using System; using System.Numerics; using static gaemstone.Bloxel.Constants; namespace gaemstone.Bloxel; public readonly struct ChunkPos : IEquatable { public static readonly ChunkPos ORIGIN = new(0, 0, 0); public int X { get; } public int Y { get; } public int Z { get; } public ChunkPos(int x, int y, int z) => (X, Y, Z) = (x, y, z); public void Deconstruct(out int x, out int y, out int z) => (x, y, z) = (X, Y, Z); public Vector3 GetOrigin() => new( X << ChunkBitShift, Y << ChunkBitShift, Z << ChunkBitShift); public Vector3 GetCenter() => new( (X << ChunkBitShift) + ChunkLength / 2, (Y << ChunkBitShift) + ChunkLength / 2, (Z << ChunkBitShift) + ChunkLength / 2); public ChunkPos Add(int x, int y, int z) => new(X + x, Y + y, Z + z); public ChunkPos Add(in ChunkPos other) => new(X + other.X, Y + other.Y, Z + other.Z); public ChunkPos Add(BlockFacing facing) { var (x, y, z) = facing; return Add(x, y, z); } public ChunkPos Add(Neighbor neighbor) { var (x, y, z) = neighbor; return Add(x, y, z); } public ChunkPos Subtract(int x, int y, int z) => new(X - x, Y - y, Z - z); public ChunkPos Subtract(in ChunkPos other) => new(X - other.X, Y - other.Y, Z - other.Z); public ChunkPos Subtract(BlockFacing facing) { var (x, y, z) = facing; return Subtract(x, y, z); } public ChunkPos Subtract(Neighbor neighbor) { var (x, y, z) = neighbor; return Subtract(x, y, z); } public bool Equals(ChunkPos other) => (X == other.X) && (Y == other.Y) && (Z == other.Z); public override bool Equals(object? obj) => (obj is ChunkPos pos) && Equals(pos); public override int GetHashCode() => HashCode.Combine(X, Y, Z); public override string ToString() => $"ChunkPos ({X}:{Y}:{Z})"; public string ToShortString() => $"{X}:{Y}:{Z}"; public static ChunkPos operator +(ChunkPos left, ChunkPos right) => left.Add(right); public static ChunkPos operator -(ChunkPos left, ChunkPos right) => left.Subtract(right); public static ChunkPos operator +(ChunkPos left, BlockFacing right) => left.Add(right); public static ChunkPos operator -(ChunkPos left, BlockFacing right) => left.Subtract(right); public static ChunkPos operator +(ChunkPos left, Neighbor right) => left.Add(right); public static ChunkPos operator -(ChunkPos left, Neighbor right) => left.Subtract(right); public static bool operator ==(ChunkPos left, ChunkPos right) => left.Equals(right); public static bool operator !=(ChunkPos left, ChunkPos right) => !left.Equals(right); } public static class ChunkPosExtensions { public static ChunkPos ToChunkPos(this Vector3 pos) => new( (int)MathF.Floor(pos.X) >> ChunkBitShift, (int)MathF.Floor(pos.Y) >> ChunkBitShift, (int)MathF.Floor(pos.Z) >> ChunkBitShift); public static ChunkPos ToChunkPos(this BlockPos self) => new( self.X >> ChunkBitShift, self.Y >> ChunkBitShift, self.Z >> ChunkBitShift); public static BlockPos ToChunkRelative(this BlockPos self) => new( self.X & ChunkBitMask, self.Y & ChunkBitMask, self.Z & ChunkBitMask); public static BlockPos ToChunkRelative(this BlockPos self, ChunkPos chunk) => new( self.X - (chunk.X << ChunkBitShift), self.Y - (chunk.Y << ChunkBitShift), self.Z - (chunk.Z << ChunkBitShift)); }