71 lines
3.2 KiB
C#
71 lines
3.2 KiB
C#
using BlockOutReplica.Domain;
|
|
using UnityEngine;
|
|
|
|
namespace BlockOutReplica.Presentation
|
|
{
|
|
/// <summary>
|
|
/// Wall rectangles are specified by their visible bounds, not the Sprite's
|
|
/// pivot. Recovered Convex* art has a bottom-left pivot; extracted straight
|
|
/// cross-sections have a center pivot. Both must share the same grid edges.
|
|
/// </summary>
|
|
public static class BoardRimLayout
|
|
{
|
|
public const float SurfaceHeight = .1f;
|
|
|
|
public static string ProfileNameFor(DoorSide side)
|
|
{ return side == DoorSide.Right ? "ConvexRightTop" : side == DoorSide.Bottom ? "ConvexLeftBottom" : "ConvexLeftTop"; }
|
|
|
|
public static Sprite CreateStraightSprite(Sprite profile, bool horizontal)
|
|
{
|
|
Rect r = profile.textureRect;
|
|
Rect strip = horizontal ? new Rect(r.xMax - 3f, r.y, 2f, r.height)
|
|
: new Rect(r.x, r.y + 2f, r.width, 2f);
|
|
Sprite sprite = Sprite.Create(profile.texture, strip, Vector2.one * .5f,
|
|
profile.pixelsPerUnit, 0, SpriteMeshType.FullRect);
|
|
sprite.name = "Original Wall Cross Section " + profile.name;
|
|
return sprite;
|
|
}
|
|
|
|
public static Rect DoorBounds(LevelDefinition level, DoorDefinition door, Vector2 artSize)
|
|
{
|
|
if (door == null || door.Cells.Count == 0)
|
|
throw new System.ArgumentException("Door closure requires its original grid cells.", nameof(door));
|
|
bool horizontal = door.Side == DoorSide.Top || door.Side == DoorSide.Bottom;
|
|
GridPosition first = door.Cells[0];
|
|
foreach (GridPosition cell in door.Cells)
|
|
if (horizontal ? cell.X < first.X : cell.Y < first.Y) first = cell;
|
|
return WorldBounds(level, first, door.Cells.Count, artSize);
|
|
}
|
|
|
|
public static Rect WorldBounds(LevelDefinition level, GridPosition first, int length, Vector2 artSize)
|
|
{
|
|
Vector3 cell = level.GridToWorld(first);
|
|
bool left = first.X < level.MinX, right = first.X > level.MaxX;
|
|
bool bottom = first.Y < level.MinY, top = first.Y > level.MaxY;
|
|
bool corner = (left || right) && (top || bottom);
|
|
float x = cell.x, z = cell.z;
|
|
float width = corner || !(top || bottom) ? artSize.x : length;
|
|
float depth = corner || top || bottom ? artSize.y : length;
|
|
if (!corner)
|
|
{
|
|
if (top || bottom) x += (length - 1) * .5f;
|
|
else z += (length - 1) * .5f;
|
|
}
|
|
if (left) x += .5f - width * .5f;
|
|
if (right) x -= .5f - width * .5f;
|
|
if (top) z += depth * .5f - .5f;
|
|
if (bottom) z -= depth * .5f - .5f;
|
|
return new Rect(x - width * .5f, z - depth * .5f, width, depth);
|
|
}
|
|
|
|
public static Vector3 CenteredSpriteOrigin(Vector3 center, Vector2 targetSize,
|
|
Vector2 spriteSize, Vector2 spriteBoundsCenter)
|
|
{
|
|
// The XY sprite is rotated +90 degrees onto XZ by LevelViewFactory.
|
|
// Account for its local mesh center before that rotation.
|
|
return center - new Vector3(spriteBoundsCenter.x * targetSize.x / spriteSize.x,
|
|
0f, spriteBoundsCenter.y * targetSize.y / spriteSize.y);
|
|
}
|
|
}
|
|
}
|