using System.Runtime.CompilerServices; using System.Runtime.InteropServices; [Tool] [GlobalClass] public partial class TerrainChunk : Resource { // ChunkShift of 5 results in a ChunkSize of 32. public const int Shift = 5; public const int Mask = ~(~0 << Shift); public const int Size = Mask + 1; static readonly int SizeInBytes = Size * Size * Unsafe.SizeOf(); [Export] public byte[] Data { get; set; } = new byte[SizeInBytes]; public bool IsEmpty { get { foreach (var b in Data) if (b != 0) return false; return true; } } public ref Tile this[TilePos pos] { get { var tiles = MemoryMarshal.Cast(Data); return ref tiles[GetIndex(pos)]; } } public static Vector2I ToChunkPos(TilePos pos) => new(pos.X >> Shift, pos.Z >> Shift); public static Vector2I ToTileOffset(Vector2I chunkPos) => new(chunkPos.X << Shift, chunkPos.Y << Shift); static int GetIndex(TilePos pos) => (pos.X & Mask) | ((pos.Z & Mask) << Shift); }