diff --git a/Application/Biome.cpp b/Application/Biome.cpp index bf4b613..cb3e575 100644 --- a/Application/Biome.cpp +++ b/Application/Biome.cpp @@ -2,6 +2,7 @@ #include "Biome.h" #include "Block.h" #include "Chunk.h" +#include "NoiseCollection.h" #include Biome::Biome(std::uint32_t filler, std::uint32_t water_level, std::map>> blocks): filler(filler), water_level(water_level), c_blockmap(blocks) @@ -18,11 +19,14 @@ const std::array Biome::GetBiomeBlocks(const std::u { std::array data; - auto it = c_blockmap.lower_bound(height); + std::memset(data.data(), static_cast(BlockType::Air), data.size() * sizeof(std::uint32_t)); + std::fill(data.begin(), data.begin() + ARTIFICIAL_ELEVATION, filler); + std::fill(data.begin() + ARTIFICIAL_ELEVATION, data.begin() + ARTIFICIAL_ELEVATION + water_level, static_cast(BlockType::Water)); + auto it = c_blockmap.lower_bound(height - ARTIFICIAL_ELEVATION); if (it == c_blockmap.end()) Scop::FatalError("Biome declaration does not have a value for a certain generated height"); - for(std::uint32_t y = 0; y < std::min(height, CHUNK_SIZE.y); y++) + for(std::uint32_t y = ARTIFICIAL_ELEVATION; y < std::min(height, CHUNK_SIZE.y); y++) { if(y > std::min(height, CHUNK_SIZE.y) - 2) { @@ -31,7 +35,7 @@ const std::array Biome::GetBiomeBlocks(const std::u { case(static_cast(BlockPlacementType::Simple)): { - data[y] = static_cast(blockTypes.front()); + data[y] = static_cast(blockTypes.at(0)); break; } case(static_cast(BlockPlacementType::PseudoRandom)): @@ -44,7 +48,7 @@ const std::array Biome::GetBiomeBlocks(const std::u break; } default: - data[y] = static_cast(BlockType::Stone); + data[y] = static_cast(BlockType::Stone); // fallback } } else @@ -52,10 +56,5 @@ const std::array Biome::GetBiomeBlocks(const std::u data[y] = filler; } } - for(std::uint32_t y = 0; y < water_level; y++) - { - if(data[y] == static_cast(BlockType::Air)) - data[y] = static_cast(BlockType::Water); - } return data; } diff --git a/Application/BiomeCollection.h b/Application/BiomeCollection.h index 85960d0..402171a 100644 --- a/Application/BiomeCollection.h +++ b/Application/BiomeCollection.h @@ -6,6 +6,7 @@ #include #include #include "Biome.h" +#include "Block.h" #include "Chunk.h" #include "Maths/Vec2.h" @@ -15,13 +16,33 @@ class BiomeCollection inline BiomeCollection() { m_collection.emplace("grassland", std::make_unique( - static_cast(BlockType::Stone), - 0, - { - {20, {BlockPlacementType::Simple, {BlockType::Sand}}}, - {255, {BlockPlacementType::Simple, {BlockType::Snow}}} - } - )); + static_cast(BlockType::Stone), + 20, + std::map>>{ + {23, std::pair>{BlockPlacementType::Simple, std::vector{BlockType::Sand}}}, + {125, std::pair>{BlockPlacementType::Simple, std::vector{BlockType::Grass}}}, + {132, std::pair>{BlockPlacementType::PseudoRandom, std::vector{BlockType::SnowyGrass, BlockType::Grass}}}, + {140, std::pair>{BlockPlacementType::PseudoRandom, std::vector{BlockType::Snow, BlockType::SnowyGrass}}}, + {255, std::pair>{BlockPlacementType::Simple, std::vector{BlockType::Snow}}} + } + )); + m_collection.emplace("tundra", std::make_unique( + static_cast(BlockType::Stone), + 20, + std::map>>{ + {23, std::pair>{BlockPlacementType::Simple, std::vector{BlockType::Snow}}}, + {120, std::pair>{BlockPlacementType::Simple, std::vector{BlockType::SnowyGrass}}}, + {140, std::pair>{BlockPlacementType::PseudoRandom, std::vector{BlockType::Snow, BlockType::SnowyGrass}}}, + {255, std::pair>{BlockPlacementType::Simple, std::vector{BlockType::Snow}}} + } + )); + m_collection.emplace("desert", std::make_unique( + static_cast(BlockType::Stone), + 20, + std::map>>{ + {255, std::pair>{BlockPlacementType::Simple, std::vector{BlockType::Sand}}} + } + )); }; const std::array GetBiomeBlocks(std::string biome, std::uint32_t height, Scop::Vec2i pos) const; ~BiomeCollection() = default; diff --git a/Application/NoiseCollection.cpp b/Application/NoiseCollection.cpp index 1033a73..0c65324 100644 --- a/Application/NoiseCollection.cpp +++ b/Application/NoiseCollection.cpp @@ -20,50 +20,14 @@ const std::array NoiseCollection::GetBlocks(Scop::V { const std::uint32_t height = m_collection["terrain"]->Perlin2D(pos.x, pos.y) + ARTIFICIAL_ELEVATION; std::array data; - - std::memset(data.data(), static_cast(BlockType::Air), data.size() * sizeof(std::uint32_t)); - - data = c_biomecollection.GetBiomeBlocks("grassland", height, pos); - return data; - for(std::uint32_t y = 0; y < std::min(height, CHUNK_SIZE.y); y++) - { - // const std::uint32_t value = Perlin3D(pos.x, y, pos.y); - if(y > std::min(height, CHUNK_SIZE.y) - 2) - { - if(height <= 23 + ARTIFICIAL_ELEVATION) - data[y] = static_cast(BlockType::Sand); - else if(height < 125 + ARTIFICIAL_ELEVATION) - data[y] = static_cast(BlockType::Grass); - else if (height < 132 + ARTIFICIAL_ELEVATION) - { - float weight = sin(2 * (pos.x * pos.y)) + sin(Scop::Pi() * (pos.x * pos.y)); - if (weight > 0.0f) - data[y] = static_cast(BlockType::Grass); - else - data[y] = static_cast(BlockType::SnowyGrass); - } - else if (height < 140 + ARTIFICIAL_ELEVATION) - { - float weight = sin(2 * (pos.x * pos.y)) + sin(Scop::Pi() * (pos.x * pos.y)); - if (weight > 0.0f) - data[y] = static_cast(BlockType::Snow); - else - data[y] = static_cast(BlockType::SnowyGrass); - } - else - data[y] = static_cast(BlockType::Snow); - } - else - data[y] = static_cast(BlockType::Stone); - } - for(std::uint32_t y = 0; y < ARTIFICIAL_ELEVATION + WATER_LEVEL; y++) - { - if(data[y] == static_cast(BlockType::Air)) - data[y] = static_cast(BlockType::Water); - } const std::uint32_t biome_value = m_collection["biomes"]->Perlin2D(pos.x, pos.y); - - if (biome_value > 20) - data[240] = static_cast(BlockType::Stone); - return data; + const std::uint32_t temperature = m_collection["temperature"]->Perlin2D(pos.x, pos.y); + const std::uint32_t humidity = m_collection["humidity"]->Perlin2D(pos.x, pos.y); + if (temperature < 85 && humidity <= 110) + return c_biomecollection.GetBiomeBlocks("tundra", height, pos); + if (temperature >= 85 && temperature <= 145 && humidity >= 85) + return c_biomecollection.GetBiomeBlocks("grassland", height, pos); + if (temperature >= 145) + return c_biomecollection.GetBiomeBlocks("desert", height, pos); + return c_biomecollection.GetBiomeBlocks("grassland", height, pos); } diff --git a/Application/NoiseCollection.h b/Application/NoiseCollection.h index 7bcdef6..804c726 100644 --- a/Application/NoiseCollection.h +++ b/Application/NoiseCollection.h @@ -25,6 +25,15 @@ class NoiseCollection 4, 1.2f )); + m_collection.emplace("humidity", std::make_unique(seed, // seed + 0.02f, + 0.3f, + 1, + 2.0f, + 0.6f, + 2, + 1.0f + )); m_collection.emplace("caves", std::make_unique(seed, 0.02f, 1.0f, @@ -34,15 +43,24 @@ class NoiseCollection 3, 1.0f )); // TODO !!!!!! - m_collection.emplace("biomes", std::make_unique(seed, + m_collection.emplace("biomes", std::make_unique(seed + 1, 0.05f, - 1.0f, + 0.1f, 1, 2.0f, 0.5f, 1, 1.0f )); + m_collection.emplace("temperature", std::make_unique(seed + 1, + 0.02f, + 0.3f, + 2, + 2.0f, + 0.55f, + 2, + 1.05f + )); } Noise* GetNoise(const std::string& key) const;