using System;
namespace GameCult.Geometry
{
///
/// The grid edge from sample (X, Y, Z) to (X, Y, Z) + e_Axis, where Axis 0/1/2 is X/Y/Z.
///
public readonly struct CultGeometryGridEdge : IEquatable, IComparable
{
/// Creates a grid edge.
public CultGeometryGridEdge(int x, int y, int z, byte axis)
{
X = x;
Y = y;
Z = z;
Axis = axis;
}
/// Gets the starting sample's x coordinate.
public int X { get; }
/// Gets the starting sample's y coordinate.
public int Y { get; }
/// Gets the starting sample's z coordinate.
public int Z { get; }
/// Gets the axis the edge runs along: 0 for x, 1 for y, 2 for z.
public byte Axis { get; }
/// Returns whether this edge is equal to another edge.
public bool Equals(CultGeometryGridEdge other) =>
X == other.X && Y == other.Y && Z == other.Z && Axis == other.Axis;
///
public override bool Equals(object? obj) => obj is CultGeometryGridEdge other && Equals(other);
///
public override int GetHashCode() => HashCode.Combine(X, Y, Z, Axis);
/// Compares edges by (X, Y, Z, Axis) in that order.
public int CompareTo(CultGeometryGridEdge other)
{
var byX = X.CompareTo(other.X);
if (byX != 0) return byX;
var byY = Y.CompareTo(other.Y);
if (byY != 0) return byY;
var byZ = Z.CompareTo(other.Z);
if (byZ != 0) return byZ;
return Axis.CompareTo(other.Axis);
}
///
public override string ToString() => $"({X}, {Y}, {Z})+e{Axis}";
// The relational operators (<, >, <=, >=) had no caller and no test anywhere in the repo:
// ordering goes through CompareTo (see
// Extraction_is_deterministic_and_quad_edges_are_strictly_ascending), so they were deleted
// rather than carried as untested surface. != is kept only because C# requires it whenever
// == is defined (CS0216); it is exercised directly by a test.
public static bool operator ==(CultGeometryGridEdge left, CultGeometryGridEdge right) => left.Equals(right);
public static bool operator !=(CultGeometryGridEdge left, CultGeometryGridEdge right) => !left.Equals(right);
}
///
/// An engine-neutral quad mesh with welded vertices, produced by surface nets extraction.
/// Not a CultCache document: this is an in-process algorithm result, not a persisted artifact.
///
public sealed class CultGeometryQuadMesh
{
/// Gets or sets the welded vertex positions, xyz per vertex.
public float[] Positions { get; set; } = Array.Empty();
/// Gets or sets the quad vertex indices, 4 per quad.
public uint[] Quads { get; set; } = Array.Empty();
/// Gets or sets the grid edge each quad was emitted for, one per quad, strictly ascending.
public CultGeometryGridEdge[] QuadEdges { get; set; } = Array.Empty();
/// Gets the number of quads.
public int QuadCount => Quads.Length / 4;
/// Gets the number of welded vertices.
public int VertexCount => Positions.Length / 3;
}
}