refactor: chunk generation logic

This commit is contained in:
2026-04-23 15:19:34 +08:00
parent c7a0aff0c1
commit e90b0ce2f4
7 changed files with 399 additions and 45 deletions

View File

@@ -1,4 +1,5 @@
#pragma once
#include <array>
namespace Cubed {
@@ -13,7 +14,7 @@ constexpr int MAX_CHARACTER = 128;
constexpr float NORMAL_FOV = 70.0f;
constexpr int MAX_BIOME_SUM = 4;
using HeightMapArray = std::array<std::array<float, CHUCK_SIZE>, CHUCK_SIZE>;
constexpr float VERTICES_POS[6][6][3] = {
// ===== front (z = +1) =====
0.0f, 0.0f, 1.0f, // bottom left

View File

@@ -1,6 +1,7 @@
#pragma once
#include <array>
#include <string>
#include <vector>
namespace Cubed {
@@ -15,7 +16,8 @@ enum class Biome {
PLAIN = 0,
FOREST,
DESERT,
MOUNTAIN
MOUNTAIN,
NONE
};
struct BiomeHeightRange {
@@ -23,11 +25,16 @@ struct BiomeHeightRange {
int amplitude;
};
struct BiomeNonAdjacent {
Biome first;
std::vector<Biome> second;
Biome replace;
};
std::string get_biome_str(Biome biome);
Biome get_biome_from_noise(float temp, float humid);
std::array<float, 3> get_noise_frequencies_for_biome(Biome biome);
BiomeHeightRange get_biome_height_range(Biome biome);
Biome safe_int_to_biome(int x);
int get_interpolated_height(float world_x, float world_z, float temp, float humid);
}

View File

@@ -15,18 +15,28 @@ class World;
// if want to use, do init_chunk(), gen_vertex_data() and
class Chunk {
private:
static constexpr int SIZE_X = CHUCK_SIZE;
static constexpr int SIZE_Y = WORLD_SIZE_Y;
static constexpr int SIZE_Z = CHUCK_SIZE;
static inline const std::vector<BiomeNonAdjacent> NON_ADJACENT {{
{Biome::PLAIN, {Biome::NONE}, Biome::PLAIN},
{Biome::FOREST, {Biome::DESERT}, Biome::PLAIN},
{Biome::DESERT, {Biome::MOUNTAIN, Biome::FOREST}, Biome::PLAIN},
{Biome::MOUNTAIN, {Biome::DESERT}, Biome::PLAIN}
}
};
using HeightMapArray = std::array<std::array<float, SIZE_Z>, SIZE_X>;
std::atomic<bool> m_dirty {false};
std::atomic<bool> m_need_upload{true};
std::atomic<bool> m_is_on_gen_vertex_data {false};
std::atomic<size_t> m_vertex_sum = 0;
std::mutex m_vertexs_data_mutex;
static constexpr int SIZE_X = CHUCK_SIZE;
static constexpr int SIZE_Y = WORLD_SIZE_Y;
static constexpr int SIZE_Z = CHUCK_SIZE;
Biome m_biome = Biome::PLAIN;
std::atomic<Biome> m_biome = Biome::PLAIN;
ChunkPos m_chunk_pos;
World& m_world;
HeightMapArray m_heightmap;
// the index is a array of block id
std::vector<uint8_t> m_blocks;
GLuint m_vbo = 0;
@@ -51,10 +61,22 @@ public:
Biome get_biome() const;
const std::vector<uint8_t>& get_chunk_blocks() const;
HeightMapArray get_heightmap() const;
static int get_index(int x, int y, int z);
static int get_index(const glm::vec3& pos);
void init_chunk();
// Generate Biome
void gen_phase_one();
// Adjust Biome
void gen_phase_two(const std::array<const Chunk*, 4>& adj_chunks);
// Generate Heightmap
void gen_phase_three();
// Adjust Height
void gen_phase_four(const std::array<std::optional<HeightMapArray>, 4>& neighbor_heightmap);
// Generate Block
void gen_phase_five();
// Generate Structure
void gen_phase_six();
//void gen_vertex_data();
// 0 : (1, 0)
// 1 : (-1, 0)

View File

@@ -26,7 +26,10 @@ private:
using ChunkPtrUpdateList = std::vector<std::pair<ChunkPos, Chunk*>>;
using ChunkUpdateList = std::vector<std::pair<ChunkPos, Chunk>>;
using ConstChunkMap = std::unordered_map<ChunkPos, const Chunk*, ChunkPos::Hash>;
using ChunkPosSet = std::unordered_set<ChunkPos, ChunkPos::Hash>;
using ChunkPosSet = std::unordered_set<ChunkPos, ChunkPos::Hash>;
bool m_could_gen = true;
glm::vec3 m_gen_player_pos{0.0f, 0.0f, 0.0f};
std::unordered_map<ChunkPos , Chunk, ChunkPos::Hash> m_chunks;
std::unordered_map<std::size_t, Player> m_players;
@@ -48,6 +51,8 @@ private:
std::vector<std::pair<ChunkPos, Chunk>> m_new_chunk;
std::vector<std::pair<ChunkPos, Chunk>> m_new_chunk_queue;
void init_chunks();
void gen_chunks_internal();
void sync_player_pos(glm::vec3& player_pos);
void compute_required_chunks(ChunkPosSet& required_chunks);