feat: add WorldGenerator filling vertical chunk stacks

This commit is contained in:
MDietermann
2026-05-31 22:08:41 +02:00
parent 6196b38cc8
commit 03cf0ceb07
2 changed files with 131 additions and 0 deletions

View File

@@ -0,0 +1,61 @@
using OpenTK.Mathematics;
using VoxelEngine.World.Blocks;
using VoxelChunk = VoxelEngine.World.Chunk.Chunk;
namespace VoxelEngine.World.WorldGen;
public sealed class WorldGenerator
{
private const int FillerDepth = 3;
private const float CellSize = 96f;
private readonly BlockRegistry _blocks;
private readonly BiomeMap _biomeMap;
private readonly TerrainSampler _terrain;
public WorldGenerator(int seed, BlockRegistry blocks)
{
this._blocks = blocks;
NoiseSource noise = new(seed);
VoronoiCells cells = new(seed, WorldGenerator.CellSize);
BiomeRegistry biomes = new(seed, blocks);
this._biomeMap = new BiomeMap(noise, cells, biomes);
this._terrain = new TerrainSampler(noise, this._biomeMap);
}
public VoxelChunk Generate(Vector3i chunkPos)
{
VoxelChunk chunk = new();
int baseX = chunkPos.X * VoxelChunk.Size;
int baseY = chunkPos.Y * VoxelChunk.Size;
int baseZ = chunkPos.Z * VoxelChunk.Size;
for (int x = 0; x < VoxelChunk.Size; x++)
for (int z = 0; z < VoxelChunk.Size; z++)
{
int worldX = baseX + x;
int worldZ = baseZ + z;
int height = this._terrain.HeightAt(worldX, worldZ);
IBiome biome = this._biomeMap.BiomeAt(worldX, worldZ);
for (int y = 0; y < VoxelChunk.Size; y++)
{
int worldY = baseY + y;
chunk[x, y, z] = WorldGenerator.BlockAt(worldY, height, biome, this._blocks);
}
}
return chunk;
}
// Pure column fill rule, extracted for testability.
public static ushort BlockAt(int worldY, int surfaceHeight, IBiome biome, BlockRegistry blocks)
{
if (worldY > surfaceHeight)
return worldY <= WorldConstants.SeaLevel ? blocks.Water.Id : blocks.Air.Id;
if (worldY == surfaceHeight)
return biome.TopBlock(worldY).Id;
if (worldY >= surfaceHeight - WorldGenerator.FillerDepth)
return biome.Surface.Filler.Id;
return biome.Surface.Under.Id;
}
}