namespace VoxelEngine.World.WorldGen; public sealed class BiomeMap { private readonly NoiseSource _noise; private readonly VoronoiCells _cells; private readonly BiomeRegistry _biomes; public BiomeMap(NoiseSource noise, VoronoiCells cells, BiomeRegistry biomes) { this._noise = noise; this._cells = cells; this._biomes = biomes; } public int CellId(float worldX, float worldZ) => this._cells.Nearest(worldX, worldZ).Id; public IBiome BiomeAt(float worldX, float worldZ) { VoronoiCells.Cell cell = this._cells.Nearest(worldX, worldZ); // Sample climate at the cell center so the biome is constant across the cell. float temperature = this._noise.Temperature(cell.CenterX, cell.CenterZ); float elevation = this._noise.Continent(cell.CenterX, cell.CenterZ); float forest = this._noise.Forest(cell.CenterX, cell.CenterZ); return BiomeMap.Classify(temperature, elevation, forest, this._biomes); } // Pure climate -> biome lookup. Thresholds in noise units (~[-1,1]). public static IBiome Classify(float temperature, float elevation, float forest, BiomeRegistry biomes) { if (elevation > 0.25f) return biomes.Mountains; // high ground if (temperature > 0.33f) return biomes.Desert; // hot, low if (temperature > -0.33f && forest > 0f) return biomes.Forest; // temperate, wooded return biomes.Plains; // temperate/cold, low } }