55 lines
2.6 KiB
C#
55 lines
2.6 KiB
C#
using Unity.Mathematics;
|
|
|
|
namespace ProjectM.Simulation
|
|
{
|
|
/// <summary>
|
|
/// Deterministic, side-effect-free math for the home-base build grid. Pure (no RNG, no wall-clock)
|
|
/// so server and predicting client agree on cell occupancy. Convention: <see cref="BaseAnchor.GridOrigin"/>
|
|
/// is the min-XZ CORNER of cell (0,0); <see cref="CellToWorld"/> returns cell CENTERS; cell bounds are
|
|
/// half-open so a point on a cell's lower edge belongs to that cell and the far plot edge is out of plot.
|
|
/// World->cell uses math.floor (not truncation) so negative coordinates snap correctly. Unit-tested in
|
|
/// EditMode (no netcode world required); M6's server placement handler calls these directly.
|
|
/// </summary>
|
|
public static class BaseGridMath
|
|
{
|
|
/// <summary>Planar (XZ) world position -> integer grid cell. Uses floor, so values below GridOrigin go negative (out of plot).</summary>
|
|
public static int2 WorldToCell(in BaseAnchor a, float3 worldPos)
|
|
{
|
|
float2 local = (worldPos.xz - a.GridOrigin.xz) / a.CellSize;
|
|
return (int2)math.floor(local);
|
|
}
|
|
|
|
/// <summary>Grid cell -> world position of the cell CENTER, on the base plane (Y = GridOrigin.y).</summary>
|
|
public static float3 CellToWorld(in BaseAnchor a, int2 cell)
|
|
{
|
|
float2 centerXZ = a.GridOrigin.xz + ((float2)cell + 0.5f) * a.CellSize;
|
|
return new float3(centerXZ.x, a.GridOrigin.y, centerXZ.y);
|
|
}
|
|
|
|
/// <summary>True when the cell is inside the plot. Half-open: [0, GridDims), so the far edge is out.</summary>
|
|
public static bool IsCellInPlot(in BaseAnchor a, int2 cell)
|
|
{
|
|
return math.all(cell >= 0) && math.all(cell < a.GridDims);
|
|
}
|
|
|
|
/// <summary>True when the world point falls inside the plot (its cell is in-plot).</summary>
|
|
public static bool IsPointInPlot(in BaseAnchor a, float3 worldPos)
|
|
{
|
|
return IsCellInPlot(a, WorldToCell(a, worldPos));
|
|
}
|
|
|
|
/// <summary>Clamp a cell into the valid [0, GridDims-1] range.</summary>
|
|
public static int2 ClampCell(in BaseAnchor a, int2 cell)
|
|
{
|
|
return math.clamp(cell, new int2(0, 0), a.GridDims - 1);
|
|
}
|
|
|
|
/// <summary>World-space center of the whole plot (== AnchorPos when baked correctly).</summary>
|
|
public static float3 PlotCenter(in BaseAnchor a)
|
|
{
|
|
float2 centerXZ = a.GridOrigin.xz + (float2)a.GridDims * a.CellSize * 0.5f;
|
|
return new float3(centerXZ.x, a.GridOrigin.y, centerXZ.y);
|
|
}
|
|
}
|
|
}
|