diff --git a/Application/Chunk.cpp b/Application/Chunk.cpp index 42e266c..63aac5f 100644 --- a/Application/Chunk.cpp +++ b/Application/Chunk.cpp @@ -16,7 +16,7 @@ constexpr std::array, BlocksCount> BLOCKS_TO_ATLAS = std::array{ Scop::Vec2ui{ 2, 0 }, Scop::Vec2ui{ 0, 0 }, Scop::Vec2ui{ 3, 0 } }, // Grass std::array{ Scop::Vec2ui{ 0, 1 }, Scop::Vec2ui{ 0, 1 }, Scop::Vec2ui{ 0, 1 } }, // Sand std::array{ Scop::Vec2ui{ 2, 1 }, Scop::Vec2ui{ 2, 1 }, Scop::Vec2ui{ 2, 1 } }, // Snow - std::array{ Scop::Vec2ui{ 3, 1 }, Scop::Vec2ui{ 3, 1 }, Scop::Vec2ui{ 3, 1 } }, // SnowyGrass + std::array{ Scop::Vec2ui{ 2, 1 }, Scop::Vec2ui{ 0, 0 }, Scop::Vec2ui{ 3, 1 } }, // SnowyGrass std::array{ Scop::Vec2ui{ 0, 2 }, Scop::Vec2ui{ 0, 2 }, Scop::Vec2ui{ 0, 2 } }, // Cactus }; diff --git a/Application/Noise.cpp b/Application/Noise.cpp index 99b525f..7e9d077 100644 --- a/Application/Noise.cpp +++ b/Application/Noise.cpp @@ -166,32 +166,3 @@ const int Noise::ApplyPerlin2DParameters(float x, float y) noexcept // Wrapper t return static_cast(normalized * HEIGHT_COEFF); } -[[nodiscard]] std::array Noise::GetHeight(Scop::Vec2i pos) -{ - std::array data; - std::memset(data.data(), static_cast(BlockType::Air), data.size() * sizeof(std::uint32_t)); - - const std::uint32_t height = Perlin2D(pos.x, pos.y); - - 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) - data[y] = static_cast(BlockType::Sand); - else if(height < 140) - data[y] = static_cast(BlockType::Grass); - else - data[y] = static_cast(BlockType::Snow); - } - else - data[y] = static_cast(BlockType::Stone); - } - 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/Noise.h b/Application/Noise.h index 7f4e84c..3ffd34e 100644 --- a/Application/Noise.h +++ b/Application/Noise.h @@ -9,14 +9,12 @@ constexpr float HEIGHT_COEFF = 255.0f; constexpr std::uint32_t NOISE_SIZE = 512; -constexpr std::uint32_t WATER_LEVEL = 20; class Noise { public: Noise(const std::uint32_t seed, float frequency, float amplitude, int octaves, float lacunarity, float persistance, int redistribution, float compensatory_factor); - [[nodiscard]] std::array GetHeight(Scop::Vec2i pos); [[nodiscard]] const int Perlin2D(int x, int y) noexcept; [[nodiscard]] const int Perlin3D(int x, int y, int z) noexcept; diff --git a/Application/NoiseCollection.cpp b/Application/NoiseCollection.cpp index 6b9f2ac..53c6768 100644 --- a/Application/NoiseCollection.cpp +++ b/Application/NoiseCollection.cpp @@ -1,4 +1,6 @@ +#include "Block.h" #include "Chunk.h" +#include "Maths/Constants.h" #include "Maths/Vec2.h" #include #include @@ -16,5 +18,46 @@ Noise* NoiseCollection::GetNoise(const std::string& key) const const std::array NoiseCollection::GetBlocks(Scop::Vec2i pos) { - return m_collection["terrain"]->GetHeight(pos); + 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)); + + 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); + } + return data; } diff --git a/Application/NoiseCollection.h b/Application/NoiseCollection.h index 826c6bd..0b94b71 100644 --- a/Application/NoiseCollection.h +++ b/Application/NoiseCollection.h @@ -6,6 +6,10 @@ #include #include +constexpr std::uint32_t ARTIFICIAL_ELEVATION = 40; + +constexpr std::uint32_t WATER_LEVEL = 20; + class NoiseCollection { public: @@ -20,13 +24,20 @@ class NoiseCollection 4, 1.2f )); - //m_collection.emplace("caves", std::make_unique(seed)); // TODO !!!!!! + m_collection.emplace("caves", std::make_unique(seed, + 0.02f, + 1.0f, + 5, + 2.0f, + 0.5f, + 3, + 1.0f + )); // TODO !!!!!! } Noise* GetNoise(const std::string& key) const; inline void AddNoise(std::string key, std::unique_ptr noise) { m_collection.emplace(std::move(key), std::move(noise)); } - [[nodiscard]] inline std::array GetBlocks(Scop::Vec2i pos) const { return m_collection.at("terrain")->GetHeight(pos); } const std::array GetBlocks(Scop::Vec2i pos); ~NoiseCollection() = default;