diff options
Diffstat (limited to 'src/World/Generator.cpp')
| -rw-r--r-- | src/World/Generator.cpp | 184 |
1 files changed, 12 insertions, 172 deletions
diff --git a/src/World/Generator.cpp b/src/World/Generator.cpp index 875a79b..e8b3bbd 100644 --- a/src/World/Generator.cpp +++ b/src/World/Generator.cpp @@ -1,190 +1,30 @@ #include "Generator.hpp" -#include "../Math/Noise.hpp" +#include "../Math/Perlin.hpp" namespace MC::World { Chunk Generator::generate(int64_t chunk_x, int64_t chunk_y) { Chunk chunk(chunk_x, chunk_y); - auto ocean_weights = ocean_weights_pass(chunk_x, chunk_y); - auto biome_weights = biome_weights_pass(chunk_x, chunk_y, ocean_weights); - auto heights = height_pass(chunk_x, chunk_y, biome_weights); - auto biomes = flat_biome_pass(biome_weights); + Math::Perlin::Noise<3> noise{.scale=20.0f, .octaves=2}; - float extent = 60.0f; - float base = 4.0f; - - for (int x = 0; x < Chunk::Width; x++) { - for (int z = 0; z < Chunk::Width; z++) { - uint32_t height = std::round(heights(x, z) * extent + base); - - auto biome = biomes(x, z); - - BlockType top_block{}; - BlockType fill_block{}; - switch (biome) { - case BiomeType::Forest: - case BiomeType::Plains: - top_block = BlockType::Grass; - fill_block = BlockType::Dirt; - break; - case BiomeType::Desert: - top_block = BlockType::Sand; - fill_block = BlockType::Sand; - break; - case BiomeType::Ocean: - top_block = BlockType::Water; - fill_block = BlockType::Dirt; - break; - } - - for (int y = 0; y < Chunk::Height; y++) { - BlockType type = BlockType::Air; - if (y < (int32_t)height - 10) { - type = BlockType::Stone; - } else if (y < height) { - type = fill_block; - } else if (y == height) { - type = top_block; - } - - chunk.set(x, y, z, type); - } - } - } - - return chunk; -} - -Matrix<Chunk::Width, Chunk::Width> Generator::ocean_weights_pass(int64_t chunk_x, int64_t chunk_y) { - auto ocean_offset = 1125.0f; - auto ocean_scale = 0.05f; - - Matrix<Chunk::Width, Chunk::Width> ocean_weights{}; - for (int x = 0; x < Chunk::Width; x++) { - for (int y = 0; y < Chunk::Width; y++) { - float ocean_weight = Math::noise2d({ - (chunk_x * Chunk::Width + x) * ocean_scale + ocean_offset, - (chunk_y * Chunk::Width + y) * ocean_scale + ocean_offset - }); - - ocean_weights(x, y) = ocean_weight; - } - } - - return ocean_weights; -} - -Matrix<Chunk::Width, Chunk::Width, Vector<BiomeType::Size>> Generator::biome_weights_pass( - int64_t chunk_x, - int64_t chunk_y, - Matrix<Chunk::Width, Chunk::Width, float> ocean_weights -) { - auto ocean_threshold = 0.4f; - - std::vector<float> biome_offsets = {110.0f, 2450.0f, 5042.0f}; - auto biome_scale = 0.15f; - - Matrix<Chunk::Width, Chunk::Width, Vector<BiomeType::Size>> biome_weights{}; - for (int x = 0; x < Chunk::Width; x++) { - for (int y = 0; y < Chunk::Width; y++) { - Vector<BiomeType::Size> weights{}; - for (auto biome : MC::World::BiomeType::all_ground()) { - float biome_noise = Math::noise2d({ - (chunk_x * Chunk::Width + x) * biome_scale + biome_offsets[biome], - (chunk_y * Chunk::Width + y) * biome_scale + biome_offsets[biome] + for (uint x = 0; x < Chunk::Width; x++) { + for (uint z = 0; z < Chunk::Width; z++) { + for (uint y = 0; y < Chunk::Height; y++) { + auto value = noise.at({ + (float)(chunk_x * Chunk::Width + x), + (float)y, + (float)(chunk_y * Chunk::Width + z), }); - weights[biome] = biome_noise; - } - - bool ocean_weight = ocean_weights(x, y) < ocean_threshold; - weights[MC::World::BiomeType::Ocean] = ocean_weight; - - biome_weights(x,y) = weights; - } - } - - return biome_weights; -} - -Matrix<Chunk::Width, Chunk::Width> Generator::height_pass( - int64_t chunk_x, - int64_t chunk_y, - Matrix<Chunk::Width, Chunk::Width, Vector<BiomeType::Size>> biome_weights -) { - auto height_offset = 6050.0f; - auto height_scale = 0.7f; - - Matrix<Chunk::Width, Chunk::Width> heights{}; - for (int x = 0; x < Chunk::Width; x++) { - for (int y = 0; y < Chunk::Width; y++) { - auto weights = biome_weights(x, y); - - auto total_weight = 0.0f; - for (auto biome : MC::World::BiomeType::all()) { - total_weight += weights[biome]; - } - - std::pair<float, float> total_effect{}; - for (auto biome : MC::World::BiomeType::all()) { - auto weight = weights[biome]; - - std::pair<float, float> effect{}; - switch (biome) { - case MC::World::BiomeType::Forest: - effect = {0.5f, 0.45f}; - break; - case MC::World::BiomeType::Plains: - effect = {0.4f, 0.4f}; - break; - case MC::World::BiomeType::Desert: - effect = {0.6f, 0.35f}; - break; - case MC::World::BiomeType::Ocean: - effect = {0.0f, 0.0f}; - break; - } - - total_effect = { - total_effect.first + effect.first * (weight / total_weight), - total_effect.second + effect.second * (weight / total_weight), - }; - } - - float height = Math::noise2d({ - (chunk_x * Chunk::Width + x) * height_scale + height_offset, - (chunk_y * Chunk::Width + y) * height_scale + height_offset - }) * total_effect.first + total_effect.second; - - heights(x, y) = height; - } - } - - return heights; -} - -Matrix<Chunk::Width, Chunk::Width, BiomeType> Generator::flat_biome_pass( - Matrix<Chunk::Width, Chunk::Width, Vector<BiomeType::Size>> biome_weights -) { - Matrix<Chunk::Width, Chunk::Width, BiomeType> biomes{}; - for (int x = 0; x < Chunk::Width; x++) { - for (int y = 0; y < Chunk::Width; y++) { - auto weights = biome_weights(x, y); - - std::pair<MC::World::BiomeType, float> max_biome{MC::World::BiomeType::Plains, 0.0f}; - for (auto biome : MC::World::BiomeType::all()) { - auto weight = weights[biome]; - if (weight > max_biome.second) { - max_biome = {biome, weight}; + if (value > 0.6f && value < 0.7f) { + chunk.set(x, y, z, {BlockType::Stone}); } } - - biomes(x, y) = max_biome.first; } } - return biomes; + return chunk; } } \ No newline at end of file |
