refactor: chunk interpolate (#6)

* refactor: rewrite blend_heightmap_boundaries

* refactor: init_world

* fix: unnatural biome boundary transition
This commit is contained in:
zhenyan121
2026-05-03 16:02:01 +08:00
committed by GitHub
parent a02bfad639
commit 9d200f31be
19 changed files with 553 additions and 319 deletions

View File

@@ -1,9 +1,11 @@
#pragma once
#include "Cubed/gameplay/chunk_pos.hpp"
#include <array>
namespace Cubed {
constexpr int WORLD_SIZE_Y = 256;
constexpr int CHUCK_SIZE = 16;
constexpr int CHUNK_SIZE = 16;
constexpr int SEA_LEVEL = 64;
constexpr int MAX_BLOCK_NUM = 8;
@@ -22,10 +24,13 @@ constexpr float DEFAULT_MAX_RUN_SPEED = 7.0f;
constexpr float DEFAULT_ACCELERATION = 10.0f;
constexpr float DEFAULT_DECELERATION = 15.0f;
constexpr float DEFAULT_G = 22.5f;
static constexpr int SIZE_X = CHUCK_SIZE;
static constexpr int SIZE_X = CHUNK_SIZE;
static constexpr int SIZE_Y = WORLD_SIZE_Y;
static constexpr int SIZE_Z = CHUCK_SIZE;
static constexpr int SIZE_Z = CHUNK_SIZE;
using HeightMapArray = std::array<std::array<float, CHUCK_SIZE>, CHUCK_SIZE>;
constexpr ChunkPos CHUNK_DIR[]{{1, 0}, {-1, 0}, {0, 1}, {0, -1},
{1, 1}, {-1, 1}, {1, -1}, {-1, -1}};
using HeightMapArray = std::array<std::array<int, CHUNK_SIZE>, CHUNK_SIZE>;
} // namespace Cubed

View File

@@ -42,6 +42,7 @@ private:
PlayerProfile m_player_profile;
TextEditing m_text_editing;
bool m_need_save_config = false;
bool m_gen_thread_running = true;
int m_theme = 0;
void show_about_table_bar();
void show_biome_table_bar();

View File

@@ -23,12 +23,8 @@ struct BiomeNonAdjacent {
static inline const std::vector<BiomeNonAdjacent> NON_ADJACENT{
{{BiomeType::PLAIN, {BiomeType::DESERT}, BiomeType::RIVER},
{BiomeType::FOREST, {BiomeType::DESERT}, BiomeType::RIVER},
{BiomeType::DESERT,
{BiomeType::MOUNTAIN, BiomeType::FOREST},
BiomeType::RIVER},
{BiomeType::MOUNTAIN,
{BiomeType::DESERT, BiomeType::FOREST},
BiomeType::RIVER}}};
{BiomeType::DESERT, {BiomeType::FOREST}, BiomeType::RIVER},
{BiomeType::MOUNTAIN, {BiomeType::NONE}, BiomeType::RIVER}}};
struct BaseBiomeParams {
BiomeType biome;

View File

@@ -12,5 +12,6 @@ public:
protected:
void build_bottom();
void fill_water();
};
} // namespace Cubed

View File

@@ -15,11 +15,10 @@ 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_X = CHUNK_SIZE;
static constexpr int SIZE_Y = WORLD_SIZE_Y;
static constexpr int SIZE_Z = CHUCK_SIZE;
static constexpr int SIZE_Z = CHUNK_SIZE;
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};
@@ -60,12 +59,13 @@ public:
// Determine biome from temperature and humidity noise
void gen_phase_one();
// Resolve biome adjacency conflicts with neighbor chunks
void gen_phase_two(const std::array<const Chunk*, 4>& adj_chunks);
void gen_phase_two(const std::array<const Chunk*, 8>& adj_chunks);
// Generate heightmap using biome-specific noise
void gen_phase_three();
// Blend heightmap with neighbors for smooth transitions
void gen_phase_four(
const std::array<std::optional<HeightMapArray>, 4>& neighbor_heightmap);
const std::array<std::optional<HeightMapArray>, 8>& neighbor_heightmap,
const std::array<BiomeType, 8>& neighbor_biome);
// Generate terrain blocks from heightmap and biome
void gen_phase_five();
// Blend surface blocks at chunk borders with neighbors

View File

@@ -25,12 +25,13 @@ public:
void assign_chunk_biome();
// Adjust Biome
void resolve_biome_adjacency_conflict(
const std::array<const Chunk*, 4>& adj_chunks);
const std::array<const Chunk*, 8>& adj_chunks);
// Generate Heightmap
void generate_heightmap();
// Adjust Height
void blend_heightmap_boundaries(
const std::array<std::optional<HeightMapArray>, 4>& neighbor_heightmap);
const std::array<std::optional<HeightMapArray>, 8>& neighbor_heightmap,
const std::array<BiomeType, 8>& neighbor_biome);
// Generate Block
void generate_terrain_blocks();
// Adjust Block;
@@ -39,10 +40,10 @@ public:
neighbor_block);
// Generate Structure
void generate_vegetation();
BiomeType get_biome_at(float world_x, float world_z);
Chunk& chunk();
Random& random();
bool neighbor_river() const;
const std::array<BiomeType, 8>& neighbor_biome() const;
private:
static inline std::atomic<bool> is_init{false};
@@ -50,11 +51,9 @@ private:
static inline std::atomic<bool> is_seed_change{false};
Chunk& m_chunk;
Random m_random;
std::array<BiomeType, 4> neighbor_biome{BiomeType::NONE, BiomeType::NONE,
BiomeType::NONE, BiomeType::NONE};
std::unique_ptr<BiomeBuilder> m_biome_builder{nullptr};
bool is_neighbor_river = false;
bool is_cur_chunk_ins = false;
std::array<BiomeType, 8> m_neighbor_biome;
void make_biome_builder();
};

View File

@@ -28,9 +28,9 @@ private:
using ConstChunkMap =
std::unordered_map<ChunkPos, const Chunk*, ChunkPos::Hash>;
using ChunkPosSet = std::unordered_set<ChunkPos, ChunkPos::Hash>;
using ChunkHashMap = std::unordered_map<ChunkPos, Chunk, ChunkPos::Hash>;
glm::vec3 m_gen_player_pos{0.0f, 0.0f, 0.0f};
std::unordered_map<ChunkPos, Chunk, ChunkPos::Hash> m_chunks;
ChunkHashMap m_chunks;
std::unordered_map<std::size_t, Player> m_players;
std::vector<glm::vec4> m_planes;
@@ -63,11 +63,10 @@ private:
void
build_neighbor_context_for_new_chunks(ConstChunkMap& new_chunks_neighbor,
ChunkPtrUpdateList& affected_neighbor,
const ChunkUpdateList& new_chunks);
const ChunkUpdateList& new_chunks,
ChunkHashMap& temp_neighbor);
void build_neighbor_context_for_affected_neighbors(ChunkPtrUpdateList&,
ConstChunkMap&);
void start_gen_thread();
void stop_gen_thread();
public:
World();
@@ -105,6 +104,8 @@ public:
float chunk_gen_fraction() const;
int rendering_distance() const;
void rendering_distance(int rendering_distance);
void start_gen_thread();
void stop_gen_thread();
};
} // namespace Cubed