feat: add biome parameter adjustment

This commit is contained in:
2026-04-25 22:23:24 +08:00
parent a95ad796ce
commit 9402847e89
7 changed files with 227 additions and 25 deletions

View File

@@ -8,6 +8,48 @@
namespace Cubed {
static PlainParams plain {
{
Biome::PLAIN,
{0.0f, 0.5f},
{0.0f, 0.5f},
{0.003f, 0.010f, 0.020f},
{62, 8}
}
};
static ForestParams forest {
{
Biome::FOREST,
{0.5f, 1.0f},
{0.5f, 1.0f},
{0.004f, 0.012f, 0.022f},
{64, 12}
},
0.1f
};
static DesertParams desert {
{
Biome::DESERT,
{0.5f, 1.0f},
{0.0f, 0.5f},
{0.003f, 0.010f, 0.020f},
{61, 12}
}
};
static MountainParams mountain {
{
Biome::MOUNTAIN,
{0.0f, 0.5f},
{0.5f, 1.0f},
{0.006f, 0.015f, 0.030f},
{70, 70}
}
};
std::string get_biome_str(Biome biome) {
std::string str;
using enum Biome;
@@ -51,22 +93,32 @@ Biome get_biome_from_noise(float temp, float humid) {
*/
Biome get_biome_from_noise(float temp, float humid) {
using enum Biome;
if (temp < 0.5f && humid < 0.5f) return PLAIN;
if (temp < 0.5f && humid >= 0.5f) return FOREST;
if (temp >= 0.5f && humid < 0.5f) return DESERT;
return MOUNTAIN;
if (plain.temp.first <= temp && temp <= plain.temp.second && plain.humid.first <= humid && humid <= plain.humid.second) {
return PLAIN;
}
if (forest.temp.first <= temp && temp <= forest.temp.second && forest.humid.first <= humid && humid <= forest.humid.second) {
return FOREST;
}
if (desert.temp.first <= temp && temp <= desert.temp.second && desert.humid.first <= humid && humid <= desert.humid.second) {
return DESERT;
}
if (mountain.temp.first <= temp && temp <= mountain.temp.second && mountain.humid.first <= humid && humid <= mountain.humid.second) {
return MOUNTAIN;
}
Logger::warn("Invail Temp {} or Humid {}", temp, humid);
return PLAIN;
}
std::array<float, 3> get_noise_frequencies_for_biome(Biome biome) {
using enum Biome;
switch (biome) {
case PLAIN:
return {0.003f, 0.010f, 0.020f};
return plain.frequencies;
case FOREST:
return {0.004f, 0.012f, 0.022f};
return forest.frequencies;
case DESERT:
return {0.003f, 0.010f, 0.020f};
return desert.frequencies;
case MOUNTAIN:
return {0.006f, 0.015f, 0.030f};
return mountain.frequencies;
case NONE:
ASSERT_MSG(false, "Chunk Biome is None");
throw std::invalid_argument{"Chunk Biome is None"};
@@ -79,13 +131,13 @@ BiomeHeightRange get_biome_height_range(Biome biome) {
using enum Biome;
switch (biome) {
case PLAIN:
return {62, 8};
return plain.height_range;
case FOREST:
return {64, 12};
return forest.height_range;
case DESERT:
return {61, 12};
return desert.height_range;
case MOUNTAIN:
return {70, 70};
return mountain.height_range;
case NONE:
ASSERT_MSG(false, "Chunk Biome is None");
throw std::invalid_argument{"Chunk Biome is None"};
@@ -149,5 +201,18 @@ int get_interpolated_height(float world_x, float world_z, float temp, float humi
return static_cast<int>(h);
}
PlainParams& plain_params() {
return plain;
}
ForestParams& forest_params() {
return forest;
}
DesertParams& desert_params() {
return desert;
}
MountainParams& mountain_params() {
return mountain;
}
}

View File

@@ -387,7 +387,7 @@ void Chunk::gen_phase_six() {
std::shuffle(z_arr.begin(), z_arr.end(), Cubed::Random::get().engine());
for (auto x : x_arr) {
for (auto z : z_arr) {
if (Cubed::Random::get().random_bool(0.1)) {
if (Cubed::Random::get().random_bool(forest_params().tree_frequency)) {
build_tree(*this, {x, static_cast<int>(m_heightmap[x][z]), z});
}

View File

@@ -265,7 +265,7 @@ ChunkPos World::chunk_pos(int world_x, int world_z) {
}
void World::gen_chunks_internal() {
m_chunk_gen_fraction = 0.0f;
ChunkPosSet required_chunks;
compute_required_chunks(required_chunks);
@@ -277,8 +277,10 @@ void World::gen_chunks_internal() {
Logger::info("New Gen Chunks Sum: {}", need_gen_chunks_pos.size());
if (need_gen_chunks_pos.empty()) {
m_could_gen = true;
m_chunk_gen_fraction = 1.0f;
return;
}
m_chunk_gen_fraction = 0.1f;
ChunkUpdateList new_chunks;
for (auto& pos : need_gen_chunks_pos) {
new_chunks.push_back({pos, Chunk(*this, pos)});
@@ -295,7 +297,7 @@ void World::gen_chunks_internal() {
for (auto& [pos, chunk] : new_chunks) {
chunk.gen_phase_one();
}
m_chunk_gen_fraction = 0.2f;
std::array<const Chunk*, 4> neighbor_chunks;
for (auto& [pos, chunks] : new_chunks) {
for (int i = 0; i < 4; i++) {
@@ -310,10 +312,11 @@ void World::gen_chunks_internal() {
}
chunks.gen_phase_two(neighbor_chunks);
}
m_chunk_gen_fraction = 0.3f;
for (auto& [pos, chunks] : new_chunks) {
chunks.gen_phase_three();
}
m_chunk_gen_fraction = 0.4f;
std::array<std::optional<HeightMapArray>, 4> neighbor_chunk_heightmap;
for (auto& [pos, chunks] : new_chunks) {
{
@@ -330,12 +333,12 @@ void World::gen_chunks_internal() {
}
chunks.gen_phase_four(neighbor_chunk_heightmap);
}
m_chunk_gen_fraction = 0.5f;
for (auto& [pos, chunks] : new_chunks) {
chunks.gen_phase_five();
chunks.gen_phase_six();
}
m_chunk_gen_fraction = 0.6f;
for (auto& [pos, chunk] : new_chunks) {
for (int i = 0; i < 4; i++) {
auto it = new_chunks_neighbor.find(pos + CHUNK_DIR[i]);
@@ -347,8 +350,9 @@ void World::gen_chunks_internal() {
}
chunk.gen_vertex_data(neighbor_block);
}
m_chunk_gen_fraction = 0.7f;
build_neighbor_context_for_affected_neighbors(affected_neighbor, new_chunks_neighbor);
m_chunk_gen_fraction = 0.8f;
for (auto& [pos, chunk] : affected_neighbor) {
for (int i = 0; i < 4; i++) {
auto it = new_chunks_neighbor.find(pos + CHUNK_DIR[i]);
@@ -361,7 +365,7 @@ void World::gen_chunks_internal() {
chunk->gen_vertex_data(neighbor_block);
chunk->need_upload();
}
m_chunk_gen_fraction = 0.9f;
{
std::lock_guard lk(m_new_chunk_queue_mutex);
for (auto& x : new_chunks) {
@@ -369,7 +373,7 @@ void World::gen_chunks_internal() {
}
}
m_chunk_gen_fraction = 1.0f;
}
void World::sync_player_pos(glm::vec3& player_pos) {
@@ -690,9 +694,19 @@ void World::rebuild_world() {
need_gen();
m_is_rebuilding = false;
for (auto& player : m_players) {
player.second.set_player_pos({0.0f, 255.0f, 0.0f});
}
}
float World::chunk_gen_fraction() const {
return m_chunk_gen_fraction.load();
}
int World::rendering_distance() const {
return m_rendering_distance.load();
}
void World::rendering_distance(int rendering_distance) {
m_rendering_distance = rendering_distance;
}
}