diff --git a/include/Cubed/config.hpp b/include/Cubed/config.hpp index 8459273..6cf2c12 100644 --- a/include/Cubed/config.hpp +++ b/include/Cubed/config.hpp @@ -4,13 +4,13 @@ constexpr int MAX_BLOCK_NUM = 5; constexpr int MAX_UI_NUM = 1; constexpr int CHUCK_SIZE = 16; -constexpr int DISTANCE = 16; +constexpr int DISTANCE = 24; constexpr int MAX_BLOCK_STATUS = 1; constexpr int MAX_CHARACTER = 128; constexpr float NORMAL_FOV = 70.0f; constexpr int MAX_BIOME_SUM = 4; -constexpr float BIOME_NOISE_FREQUENCY = 0.005f; +constexpr float BIOME_NOISE_FREQUENCY = 0.003f; constexpr float VERTICES_POS[6][6][3] = { // ===== front (z = +1) ===== diff --git a/include/Cubed/gameplay/chunk_status.hpp b/include/Cubed/gameplay/chunk_status.hpp index dd49606..95728bc 100644 --- a/include/Cubed/gameplay/chunk_status.hpp +++ b/include/Cubed/gameplay/chunk_status.hpp @@ -1,4 +1,5 @@ #pragma once +#include #include #include #include @@ -29,6 +30,11 @@ struct ChunkPos { }; }; +constexpr float PLAIN_FREQ = 0.5f; +constexpr float FOREST_FREQ = 1.0f; +constexpr float DESERT_FREQ = 1.0f; +constexpr float MOUNTAIN_FREQ = 2.0f; + enum class Biome { PLAIN = 0, FOREST, @@ -62,9 +68,20 @@ constexpr inline std::string get_biome_str(Biome biome) { }; inline Biome get_biome_from_noise(float temp, float humid) { - if (temp < 0.5f && humid < 0.5f) return Biome::MOUNTAIN; - if (temp < 0.5f && humid >= 0.5f) return Biome::PLAIN; - if (temp >= 0.5f && humid < 0.5f) return Biome::DESERT; + auto weight = [](float t, float h, float ct, float ch) -> float { + float dt = t - ct; + float dh = h - ch; + float dist = std::sqrt(dt*dt + dh*dh); + return std::max(0.0f, 0.5f - dist); + }; + float w_m = weight(temp, humid, 0.25f, 0.15f); + float w_p = weight(temp, humid, 0.50f, 0.40f); + float w_d = weight(temp, humid, 0.75f, 0.15f); + float w_f = weight(temp, humid, 0.75f, 0.75f); + w_m = pow(w_m, 8); w_p = pow(w_p, 8); w_d = pow(w_d, 8); w_f = pow(w_f, 8); + if (w_m >= w_p && w_m >= w_d && w_m >= w_f) return Biome::MOUNTAIN; + if (w_p >= w_m && w_p >= w_d && w_p >= w_f) return Biome::PLAIN; + if (w_d >= w_m && w_d >= w_p && w_d >= w_f) return Biome::DESERT; return Biome::FOREST; } @@ -72,13 +89,13 @@ inline std::array get_noise_frequencies_for_biome(Biome biome) { using enum Biome; switch (biome) { case PLAIN: - return {0.003f, 0.008f, 0.018f}; + return {0.003f, 0.010f, 0.020f}; case FOREST: return {0.004f, 0.012f, 0.022f}; case DESERT: - return {0.003f, 0.008f, 0.018f}; + return {0.003f, 0.010f, 0.020f}; case MOUNTAIN: - return {0.006f, 0.015f, 0.03f}; + return {0.006f, 0.015f, 0.030f}; } Logger::warn("Unknown Biome"); return {0.003f, 0.015f, 0.06f}; @@ -88,11 +105,11 @@ inline BiomeHeightRange get_biome_height_range(Biome biome) { using enum Biome; switch (biome) { case PLAIN: - return {62, 4}; + return {62, 8}; case FOREST: - return {64, 8}; + return {64, 12}; case DESERT: - return {61, 8}; + return {61, 12}; case MOUNTAIN: return {70, 70}; } diff --git a/include/Cubed/tools/math_tools.hpp b/include/Cubed/tools/math_tools.hpp index 0707f22..60416dd 100644 --- a/include/Cubed/tools/math_tools.hpp +++ b/include/Cubed/tools/math_tools.hpp @@ -2,5 +2,5 @@ #include namespace Math { void extract_frustum_planes(const glm::mat4& mvp_matrix, std::vector& planes); - int get_interpolated_height(float world_x, float world_z, float biome_noise, float temp, float humid); + int get_interpolated_height(float world_x, float world_z, float temp, float humid); } \ No newline at end of file diff --git a/src/gameplay/chunk.cpp b/src/gameplay/chunk.cpp index 1623f27..b35fbfa 100644 --- a/src/gameplay/chunk.cpp +++ b/src/gameplay/chunk.cpp @@ -280,16 +280,10 @@ void Chunk::resolve_blocks() { float world_x = static_cast(x + m_chunk_pos.x * CHUCK_SIZE); float world_z = static_cast(z + m_chunk_pos.z * CHUCK_SIZE); - - float biome_noise = PerlinNoise::noise( - world_x * BIOME_NOISE_FREQUENCY, - 0.5f, - world_z * BIOME_NOISE_FREQUENCY - ); float temp = PerlinNoise::noise(world_x * BIOME_NOISE_FREQUENCY, 0.0f, world_z * BIOME_NOISE_FREQUENCY); float humid = PerlinNoise::noise(world_x * BIOME_NOISE_FREQUENCY, 1.0f, world_z * BIOME_NOISE_FREQUENCY); - int height = Math::get_interpolated_height(world_x, world_z, biome_noise, temp, humid); + int height = Math::get_interpolated_height(world_x, world_z, temp, humid); auto biome = get_biome_from_noise(temp, humid); for (int y = 5; y < height - 5; y++) { m_blocks[get_index(x, y, z)] = 3; diff --git a/src/tools/math_tools.cpp b/src/tools/math_tools.cpp index d689868..5f14c39 100644 --- a/src/tools/math_tools.cpp +++ b/src/tools/math_tools.cpp @@ -34,9 +34,8 @@ namespace Math { } } - int get_interpolated_height(float world_x, float world_z, float biome_noise, float temp, float humid) { + int get_interpolated_height(float world_x, float world_z, float temp, float humid) { - auto weight = [](float t, float h, float ct, float ch) -> float { float dt = t - ct; float dh = h - ch; @@ -44,16 +43,16 @@ namespace Math { return std::max(0.0f, 0.5f - dist); }; - float w_mountain = weight(temp, humid, 0.25f, 0.25f); - float w_plain = weight(temp, humid, 0.25f, 0.75f); - float w_desert = weight(temp, humid, 0.75f, 0.25f); + float w_mountain = weight(temp, humid, 0.25f, 0.15f); + float w_plain = weight(temp, humid, 0.50f, 0.40f); + float w_desert = weight(temp, humid, 0.75f, 0.15f); float w_forest = weight(temp, humid, 0.75f, 0.75f); // adjust transitions between chunks float pow_n = 8.0f; // the larger n is, the purer the biome - w_mountain = std::pow(w_mountain, pow_n); - w_plain = std::pow(w_plain, pow_n); - w_desert = std::pow(w_desert, pow_n); - w_forest = std::pow(w_forest, pow_n); + w_mountain = std::pow(w_mountain, pow_n) * MOUNTAIN_FREQ; + w_plain = std::pow(w_plain, pow_n) * PLAIN_FREQ; + w_desert = std::pow(w_desert, pow_n) * DESERT_FREQ; + w_forest = std::pow(w_forest, pow_n) * FOREST_FREQ; float total = w_mountain + w_plain + w_desert + w_forest; w_mountain /= total; w_plain /= total; w_desert /= total; w_forest /= total;