feat: add multi-chunk world with cross-chunk face culling
Add a World that stores chunks in a Dictionary keyed by chunk coordinate, with floor-division world<->chunk coordinate mapping (correct for negative coords). The mesher takes an optional neighbor sampler so faces at chunk borders are culled against adjacent chunks instead of always meshing the shell. Render one ChunkRenderer per chunk, placed via the model matrix. Reorganize the World layer into Blocks/ and Chunk/ sub-namespaces.
This commit is contained in:
11
World/Blocks/BlockFace.cs
Normal file
11
World/Blocks/BlockFace.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
namespace VoxelEngine.World.Blocks;
|
||||
|
||||
public enum BlockFace
|
||||
{
|
||||
Top, // +Y
|
||||
Bottom, // -Y
|
||||
North, // -Z
|
||||
South, // +Z
|
||||
East, // +X
|
||||
West // -X
|
||||
}
|
||||
24
World/Blocks/BlockRegistry.cs
Normal file
24
World/Blocks/BlockRegistry.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
namespace VoxelEngine.World.Blocks;
|
||||
|
||||
public sealed class BlockRegistry
|
||||
{
|
||||
private readonly IBlock[] _byId;
|
||||
|
||||
public AirBlock Air { get; } = new();
|
||||
public StoneBlock Stone { get; } = new();
|
||||
public DirtBlock Dirt { get; } = new();
|
||||
public GrassBlock Grass { get; } = new();
|
||||
|
||||
public BlockRegistry()
|
||||
{
|
||||
// Index by id. Order does not matter; slot = block.Id.
|
||||
IBlock[] blocks = new IBlock[] { this.Air, this.Stone, this.Dirt, this.Grass };
|
||||
this._byId = new IBlock[blocks.Length];
|
||||
foreach (IBlock block in blocks)
|
||||
{
|
||||
this._byId[block.Id] = block;
|
||||
}
|
||||
}
|
||||
|
||||
public IBlock Get(ushort id) => this._byId[id];
|
||||
}
|
||||
21
World/Blocks/IBlock.cs
Normal file
21
World/Blocks/IBlock.cs
Normal file
@@ -0,0 +1,21 @@
|
||||
namespace VoxelEngine.World.Blocks;
|
||||
|
||||
public interface IBlock
|
||||
{
|
||||
ushort Id { get; }
|
||||
string Name { get; }
|
||||
|
||||
// Drives face culling: a face is emitted only if its neighbor is not opaque.
|
||||
bool IsOpaque { get; }
|
||||
|
||||
// Reserved for future collision (not used in the baseline).
|
||||
bool IsSolid { get; }
|
||||
|
||||
// Atlas tile index for the given face.
|
||||
int GetTextureIndex(BlockFace face);
|
||||
|
||||
// Interaction hooks — capability present now, system built post-baseline.
|
||||
void OnInteract() { }
|
||||
void OnPlaced() { }
|
||||
void OnBroken() { }
|
||||
}
|
||||
Reference in New Issue
Block a user