diff --git a/Application/Noise.cpp b/Application/Noise.cpp index 695fea3..b69f7fe 100644 --- a/Application/Noise.cpp +++ b/Application/Noise.cpp @@ -8,11 +8,11 @@ constexpr float HEIGHT_COEFF = 255.0f; constexpr std::uint32_t WATER_LEVEL = 20; -Noise::Noise(const std::uint32_t seed, float frequency, float amplitude, int octaves, float lacunarity, float persistance, int redistribution): seed(std::mt19937(seed)), frequency(frequency), amplitude(amplitude), octaves(octaves), lacunarity(lacunarity), persistance(persistance), redistribution(redistribution) +Noise::Noise(const std::uint32_t seed, float frequency, float amplitude, int octaves, float lacunarity, float persistance, int redistribution, float compensatory_factor): m_seed(std::mt19937(seed)), c_frequency(frequency), c_amplitude(amplitude), c_octaves(octaves), c_lacunarity(lacunarity), c_persistance(persistance), c_redistribution(redistribution), c_compensatory_factor(compensatory_factor) { - if(amplitude > 1.0f || amplitude < -1.0f) + if(c_amplitude > 1.0f || c_amplitude < -1.0f) Scop::FatalError("Amplitude value must be in [-1;1]"); - if(redistribution <= 0) + if(c_redistribution <= 0) Scop::FatalError("Redistribution cannot be a negative integer"); InitPermutation(); } @@ -23,7 +23,7 @@ void Noise::InitPermutation() for(int i = 0; i < 256; ++i) permutations[i] = i; - std::shuffle(permutations.begin(), permutations.end(), seed); + std::shuffle(permutations.begin(), permutations.end(), m_seed); for(int i = 0; i < 256; ++i) { this->perms[i] = permutations[i]; @@ -63,27 +63,27 @@ const float Noise::Perlin2D(float x, float y) noexcept const int Noise::ApplyPerlin2DParameters(float x, float y) noexcept // Wrapper to apply various mumbo jumbo to get a very worldlike generation { float total = 0.0f; - float tmp_freq = frequency; - float tmp_amp = amplitude; + float tmp_freq = c_frequency; + float tmp_amp = c_amplitude; float maxValue = 0.0f; - for(int i = 0; i < this->octaves; ++i) + for(int i = 0; i < this->c_octaves; ++i) { total += Perlin2D(x * tmp_freq, y * tmp_freq) * tmp_amp; maxValue += tmp_amp; - tmp_amp *= persistance; - tmp_freq *= lacunarity; + tmp_amp *= c_persistance; + tmp_freq *= c_lacunarity; } float normalized = total / maxValue; normalized = std::clamp(normalized, 0.0f, 1.0f); - normalized = std::pow(normalized, redistribution); + normalized = std::pow(normalized * c_compensatory_factor, c_redistribution); return static_cast(normalized * HEIGHT_COEFF); } [[nodiscard]] const int Noise::Perlin2D(int x, int y) noexcept { // Wrapper to unnormalise input and output - float scaledX = static_cast(x) * frequency; - float scaledY = static_cast(y) * frequency; + float scaledX = static_cast(x) * c_frequency; + float scaledY = static_cast(y) * c_frequency; return floor(ApplyPerlin2DParameters(scaledX, scaledY)); } @@ -107,17 +107,17 @@ const int Noise::ApplyPerlin2DParameters(float x, float y) noexcept // Wrapper t [[nodiscard]] const int Noise::Perlin3D(int x, int y, int z) noexcept { - float scaledX = static_cast(x) * frequency; - float scaledY = static_cast(y) * frequency; - float scaledZ = static_cast(z) * frequency; - return floor(ApplyPerlin3DParameters(scaledX, scaledY, scaledZ)); + float scaledX = static_cast(x) * c_frequency; + float scaledY = static_cast(y) * c_frequency; + float scaledZ = static_cast(z) * c_frequency; + return static_cast(ApplyPerlin3DParameters(scaledX, scaledY, scaledZ)); } [[nodiscard]] const float Noise::Perlin3D(float x, float y, float z) noexcept { - int xi = (int)floor(x) & 255; - int yi = (int)floor(y) & 255; - int zi = (int)floor(z) & 255; + int xi = static_cast(x) & 255; + int yi = static_cast(y) & 255; + int zi = static_cast(z) & 255; float xf = x - floor(x); float yf = y - floor(y); @@ -149,22 +149,22 @@ const int Noise::ApplyPerlin2DParameters(float x, float y) noexcept // Wrapper t grad(bbb, xf - 1, yf - 1, zf - 1), u); y2 = std::lerp(x1, x2, v); - return ((std::lerp(y1, y2, w) + 1.0f) / 2.0f) * amplitude; + return ((std::lerp(y1, y2, w) + 1.0f) / 2.0f) * c_amplitude; } [[nodiscard]] const int Noise::ApplyPerlin3DParameters(float x, float y, float z) noexcept { float total = 0.0f; - float tmp_freq = frequency; - float tmp_amp = amplitude; + float tmp_freq = c_frequency; + float tmp_amp = c_amplitude; float maxValue = 0.0f; - for(int i = 0; i < this->octaves; ++i) + for(int i = 0; i < this->c_octaves; ++i) { total += Perlin3D(x * tmp_freq, y * tmp_freq, z * tmp_freq) * tmp_amp; maxValue += tmp_amp; - tmp_amp *= persistance; - tmp_freq *= lacunarity; + tmp_amp *= c_persistance; + tmp_freq *= c_lacunarity; } float normalized = total / maxValue; normalized = std::clamp(normalized, 0.0f, 1.0f); diff --git a/Application/Noise.h b/Application/Noise.h index 11b495b..072d74d 100644 --- a/Application/Noise.h +++ b/Application/Noise.h @@ -11,7 +11,7 @@ class Noise { public: - Noise(const std::uint32_t seed = 42, float frequency = 0.05f, float amplitude = 0.95f, int octaves = 4, float lacunarity = 2.4f, float persistance = 0.8f, int redistribution = 3); + Noise(const std::uint32_t seed = 42, float frequency = 0.045f, float amplitude = 0.80f, int octaves = 4, float lacunarity = 2.0f, float persistance = 0.7f, int redistribution = 4, float compensatory_factor = 1.3f); [[nodiscard]] std::array GetHeight(Scop::Vec2i pos); [[nodiscard]] const int Perlin2D(int x, int y) noexcept; @@ -19,14 +19,15 @@ class Noise ~Noise() = default; private: - std::mt19937 seed; + std::mt19937 m_seed; std::array perms; - const float frequency; - const float amplitude; - const int octaves; - const float lacunarity; - const float persistance; - const int redistribution; + const float c_frequency; + const float c_amplitude; + const int c_octaves; + const float c_lacunarity; + const float c_persistance; + const int c_redistribution; + const float c_compensatory_factor; void InitPermutation(void); [[nodiscard]] const float Perlin2D(float x, float y) noexcept;