mirror of
https://github.com/zhenyan121/Cubed.git
synced 2026-08-09 02:07:04 +08:00
refactor: cave and river (#22)
* refactor(chunk): add ChunkInfo and switch to shared_mutex for chunk access Introduced ChunkInfo struct to expose chunk metadata (position, seed, biome). Replaced std::mutex with std::shared_mutex for chunk map to allow concurrent read access. Added World::get_chunk_info() method. Temporarily disabled cave/river cleanup and debug biome reporting. * refactor(cave,river,chunk): use ChunkPos as key for paths and track cave existence * refactor(gameplay): use deterministic origin-based cave and river generation Compute cave and river paths on-the-fly per chunk from a deterministic origin instead of storing them globally. Remove concurrent hash map storage, shared mutexes, and related cleanup methods. This simplifies concurrency and reduces memory overhead. * refactor(world): remove unused chunk generation progress tracking
This commit is contained in:
@@ -1,31 +1,25 @@
|
||||
#pragma once
|
||||
#include "Cubed/gameplay/cave_path.hpp"
|
||||
#include "Cubed/constants.hpp"
|
||||
#include "Cubed/gameplay/path.hpp"
|
||||
|
||||
#include <shared_mutex>
|
||||
#include <tbb/concurrent_hash_map.h>
|
||||
|
||||
namespace Cubed {
|
||||
class CaveCarver {
|
||||
using CaveHashMap = tbb::concurrent_hash_map<unsigned, CavePath>;
|
||||
|
||||
public:
|
||||
CaveCarver();
|
||||
CaveHashMap& paths();
|
||||
|
||||
void init(unsigned world_seed);
|
||||
void reload(unsigned world_seed);
|
||||
void add_path(const glm::vec3& pos, unsigned chunk_seed);
|
||||
void try_to_add_path(const ChunkPos& pos, unsigned chunk_seed);
|
||||
void cleanup_finished_caves();
|
||||
|
||||
int cave_sum() const;
|
||||
float& cave_probability();
|
||||
std::shared_mutex& path_mutex();
|
||||
bool has_origin_fast(const ChunkPos& pos) const;
|
||||
float cave_probability() const;
|
||||
PathOrigin get_origin(const ChunkPos& origin_chunk) const;
|
||||
int search_radius() const;
|
||||
unsigned world_seed() const;
|
||||
|
||||
private:
|
||||
CaveHashMap m_paths;
|
||||
unsigned m_seed = 0;
|
||||
Random m_random;
|
||||
float m_cave_probability = 0.035f;
|
||||
std::shared_mutex m_path_mutex;
|
||||
std::atomic<unsigned> m_world_seed{0};
|
||||
std::atomic<float> m_cave_probability{DEFAULT_CAVE_PROBABILITY};
|
||||
};
|
||||
} // namespace Cubed
|
||||
|
||||
@@ -16,8 +16,6 @@ public:
|
||||
CavePath(unsigned int chunk_seed, unsigned world_seed,
|
||||
const glm::vec3& start_pos);
|
||||
const std::vector<PathPoint>& points() const;
|
||||
void clear_chunk(const ChunkPos& pos);
|
||||
bool is_finished() const;
|
||||
|
||||
static float& radius_xz_min();
|
||||
static float& radius_xz_max();
|
||||
@@ -27,6 +25,7 @@ public:
|
||||
static float& delta_angle_max();
|
||||
static int& step_min();
|
||||
static int& step_max();
|
||||
static int step_len();
|
||||
|
||||
private:
|
||||
static inline float m_radius_xz_min = 5.0f;
|
||||
@@ -37,18 +36,16 @@ private:
|
||||
static inline float m_delta_angle_max = 5.0f;
|
||||
static inline int m_step_min = 10;
|
||||
static inline int m_step_max = 400;
|
||||
|
||||
static inline float m_step_len = 4.0f;
|
||||
unsigned int m_seed = 0;
|
||||
float m_yaw = 0.0f;
|
||||
float m_pitch = 0.0f;
|
||||
int m_step = 0;
|
||||
float m_step_len = 1.0f;
|
||||
|
||||
PathPoint m_start_path_point{{0.0f, 0.0f, 0.0f}, 0.0f, 0.0f};
|
||||
Random m_random;
|
||||
|
||||
std::vector<PathPoint> m_points;
|
||||
ChunkPosSet m_pending_chunks;
|
||||
void collect_path_points();
|
||||
void precompute_chunk_coverage();
|
||||
};
|
||||
} // namespace Cubed
|
||||
@@ -10,6 +10,15 @@
|
||||
#include <mutex>
|
||||
namespace Cubed {
|
||||
|
||||
struct ChunkInfo {
|
||||
ChunkPos pos{0, 0};
|
||||
unsigned seed{0};
|
||||
BiomeType biome{BiomeType::NONE};
|
||||
unsigned first_random{0};
|
||||
bool has_cave_start{false};
|
||||
bool has_cave{false};
|
||||
};
|
||||
|
||||
class World;
|
||||
// if want to use, do init_chunk(), gen_vertex_data() and
|
||||
class Chunk {
|
||||
@@ -26,6 +35,8 @@ private:
|
||||
std::atomic<bool> m_gening{false};
|
||||
std::atomic<bool> m_temp_chunk{false};
|
||||
|
||||
bool m_has_cave{false};
|
||||
|
||||
std::atomic<BiomeType> m_biome = BiomeType::PLAIN;
|
||||
std::mutex m_vertexs_data_mutex;
|
||||
|
||||
@@ -50,7 +61,7 @@ private:
|
||||
unsigned m_seed = 0;
|
||||
|
||||
BiomeConditions m_conditions;
|
||||
|
||||
ChunkInfo m_info;
|
||||
void clear_dirty();
|
||||
void gen_vertices(const OptionalBlockVectorArray& neighbor_block);
|
||||
void gen_cross_plane_vertices(int world_x, int world_y, int world_z,
|
||||
@@ -129,6 +140,7 @@ public:
|
||||
void set_chunk_block(int index, unsigned id);
|
||||
// ensure thread safe!
|
||||
void gen_chunk();
|
||||
|
||||
bool is_temp_chunk() const;
|
||||
ChunkPos chunk_pos() const;
|
||||
BiomeType biome() const;
|
||||
@@ -138,6 +150,8 @@ public:
|
||||
World& world();
|
||||
unsigned seed() const;
|
||||
BiomeConditions& conditions();
|
||||
ChunkInfo get_info() const;
|
||||
bool& has_cave();
|
||||
};
|
||||
|
||||
} // namespace Cubed
|
||||
@@ -4,7 +4,6 @@
|
||||
#include "Cubed/gameplay/biome.hpp"
|
||||
#include "Cubed/gameplay/block.hpp"
|
||||
#include "Cubed/gameplay/builders/biome_builder.hpp"
|
||||
#include "Cubed/gameplay/path_point.hpp"
|
||||
#include "Cubed/tools/cubed_random.hpp"
|
||||
|
||||
#include <atomic>
|
||||
@@ -62,9 +61,6 @@ private:
|
||||
unsigned m_chunk_seed = 0;
|
||||
|
||||
void make_biome_builder();
|
||||
void
|
||||
carve_worm(const std::vector<PathPoint>& points, const ChunkPos& chunk_pos,
|
||||
std::function<void(int /*x*/, int /*y*/, int /*z*/)> on_hit);
|
||||
};
|
||||
|
||||
} // namespace Cubed
|
||||
8
include/Cubed/gameplay/path.hpp
Normal file
8
include/Cubed/gameplay/path.hpp
Normal file
@@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
struct PathOrigin {
|
||||
bool exists;
|
||||
glm::vec3 pos;
|
||||
unsigned seed;
|
||||
};
|
||||
@@ -16,8 +16,6 @@ public:
|
||||
RiverPath(unsigned int chunk_seed, unsigned world_seed,
|
||||
const glm::vec3& start_pos);
|
||||
const std::vector<PathPoint>& points() const;
|
||||
void clear_chunk(const ChunkPos& pos);
|
||||
bool is_finished() const;
|
||||
|
||||
static float& radius_xz_min();
|
||||
static float& radius_xz_max();
|
||||
@@ -27,6 +25,7 @@ public:
|
||||
static float& delta_angle_max();
|
||||
static int& step_min();
|
||||
static int& step_max();
|
||||
static float step_len();
|
||||
|
||||
private:
|
||||
static inline float m_radius_xz_min = 5.0f;
|
||||
@@ -37,13 +36,12 @@ private:
|
||||
static inline float m_delta_angle_max = 3.0f;
|
||||
static inline int m_step_min = 200;
|
||||
static inline int m_step_max = 400;
|
||||
|
||||
static inline float m_step_len = 4.0f;
|
||||
unsigned int m_seed = 0;
|
||||
float m_yaw = 0.0f;
|
||||
float m_initial_yaw = 0.0f;
|
||||
float m_pitch = 0.0f;
|
||||
int m_step = 0;
|
||||
float m_step_len = 1.0f;
|
||||
PathPoint m_start_path_point{{0.0f, 0.0f, 0.0f}, 0.0f, 0.0f};
|
||||
Random m_random;
|
||||
|
||||
|
||||
@@ -1,37 +1,32 @@
|
||||
#pragma once
|
||||
#include "Cubed/gameplay/chunk_pos.hpp"
|
||||
#include "Cubed/gameplay/river.path.hpp"
|
||||
#include "Cubed/gameplay/path.hpp"
|
||||
#include "Cubed/tools/cubed_random.hpp"
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <shared_mutex>
|
||||
#include <tbb/concurrent_hash_map.h>
|
||||
|
||||
namespace Cubed {
|
||||
|
||||
class RiverWorm {
|
||||
using RiverHashMap = tbb::concurrent_hash_map<unsigned, RiverPath>;
|
||||
|
||||
public:
|
||||
RiverWorm();
|
||||
~RiverWorm();
|
||||
RiverHashMap& paths();
|
||||
|
||||
void init(unsigned world_seed);
|
||||
void reload(unsigned world_seed);
|
||||
void add_path(const glm::vec3& pos, unsigned chunk_seed);
|
||||
void try_to_add_path(const ChunkPos& pos, unsigned chunk_seed);
|
||||
void cleanup_finished_rivers();
|
||||
|
||||
int river_sum() const;
|
||||
float& river_probability();
|
||||
std::shared_mutex& paths_mutex();
|
||||
PathOrigin get_origin(const ChunkPos& origin_chunk) const;
|
||||
int search_radius() const;
|
||||
unsigned world_seed() const;
|
||||
|
||||
float river_probability() const;
|
||||
bool has_origin_fast(const ChunkPos& pos) const;
|
||||
|
||||
private:
|
||||
RiverHashMap m_paths;
|
||||
unsigned m_seed = 0;
|
||||
std::atomic<unsigned> m_world_seed{0};
|
||||
Random m_random;
|
||||
float m_probability = 0.01f;
|
||||
std::shared_mutex m_paths_mutex;
|
||||
std::atomic<float> m_probability{0.01f};
|
||||
};
|
||||
|
||||
}; // namespace Cubed
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <condition_variable>
|
||||
#include <mutex>
|
||||
#include <optional>
|
||||
#include <shared_mutex>
|
||||
#include <thread>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
@@ -67,7 +68,7 @@ private:
|
||||
|
||||
std::atomic<TickType> m_day_tick = 6000;
|
||||
|
||||
mutable std::mutex m_chunks_mutex;
|
||||
mutable std::shared_mutex m_chunks_mutex;
|
||||
std::mutex m_gen_signal_mutex;
|
||||
std::mutex m_new_chunk_mutex;
|
||||
std::mutex m_delete_vbo_mutex;
|
||||
@@ -83,7 +84,6 @@ private:
|
||||
std::atomic<bool> m_could_gen{true};
|
||||
std::atomic<bool> m_tick_running{true};
|
||||
std::atomic<int> m_rendering_distance{24};
|
||||
std::atomic<float> m_chunk_gen_fraction{0.0f};
|
||||
std::atomic<int> m_pool_threads{0};
|
||||
std::atomic<int> m_max_threads{1};
|
||||
std::atomic<TickType> m_game_ticks{0};
|
||||
@@ -100,8 +100,7 @@ private:
|
||||
|
||||
void gen_chunks_internal();
|
||||
void sync_player_pos(glm::vec3& player_pos);
|
||||
void compute_required_chunks(ChunkPosSet& required_chunks,
|
||||
ChunkPairVector& temp_neighbor);
|
||||
void compute_required_chunks(ChunkPosSet& required_chunks);
|
||||
void sync_and_collect_missing_chunks(std::vector<ChunkPos>&,
|
||||
const ChunkPosSet&);
|
||||
|
||||
@@ -118,7 +117,7 @@ public:
|
||||
|
||||
const std::optional<LookBlock>&
|
||||
get_look_block_pos(const std::string& name) const;
|
||||
const Chunk* get_chunk(const ChunkPos& pos) const;
|
||||
// const Chunk* get_chunk(const ChunkPos& pos) const;
|
||||
|
||||
Player& get_player(const std::string& name);
|
||||
void init_world();
|
||||
@@ -139,7 +138,6 @@ public:
|
||||
|
||||
void rebuild_world();
|
||||
|
||||
float chunk_gen_fraction() const;
|
||||
int rendering_distance() const;
|
||||
void rendering_distance(int rendering_distance);
|
||||
void start_gen_thread();
|
||||
@@ -169,6 +167,7 @@ public:
|
||||
void change_pool_threads(int threads);
|
||||
int chunk_load_style() const;
|
||||
void set_chunk_load_style(int id);
|
||||
ChunkInfo get_chunk_info(const glm::vec3& world_pos) const;
|
||||
};
|
||||
|
||||
} // namespace Cubed
|
||||
|
||||
Reference in New Issue
Block a user