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,65 +1,59 @@
|
||||
#include "Cubed/gameplay/river_worm.hpp"
|
||||
|
||||
#include "Cubed/constants.hpp"
|
||||
|
||||
#include "Cubed/gameplay/river.path.hpp"
|
||||
#include "Cubed/tools/cubed_hash.hpp"
|
||||
namespace Cubed {
|
||||
RiverWorm::RiverWorm() {}
|
||||
RiverWorm::~RiverWorm() {}
|
||||
RiverWorm::RiverHashMap& RiverWorm::paths() { return m_paths; }
|
||||
|
||||
void RiverWorm::init(unsigned world_seed) {
|
||||
m_seed = world_seed;
|
||||
m_world_seed = world_seed;
|
||||
|
||||
m_random.init(m_seed);
|
||||
m_random.init(m_world_seed);
|
||||
}
|
||||
|
||||
void RiverWorm::reload(unsigned world_seed) {
|
||||
m_seed = world_seed;
|
||||
m_paths.clear();
|
||||
|
||||
m_world_seed = world_seed;
|
||||
|
||||
init(world_seed);
|
||||
}
|
||||
|
||||
void RiverWorm::add_path(const glm::vec3& pos, unsigned chunk_seed) {
|
||||
m_paths.emplace(chunk_seed, RiverPath{chunk_seed, m_seed, pos});
|
||||
bool RiverWorm::has_origin_fast(const ChunkPos& pos) const {
|
||||
unsigned h = HASH::combine_32(HASH::combine_32(pos.x, pos.z), m_world_seed);
|
||||
|
||||
return (h & 0xFFFF) < static_cast<unsigned>(m_probability * 0xFFFF);
|
||||
}
|
||||
|
||||
void RiverWorm::try_to_add_path(const ChunkPos& chunk_pos,
|
||||
unsigned chunk_seed) {
|
||||
{
|
||||
RiverHashMap::const_accessor acc;
|
||||
if (m_paths.find(acc, chunk_seed)) {
|
||||
return;
|
||||
}
|
||||
PathOrigin RiverWorm::get_origin(const ChunkPos& origin_chunk) const {
|
||||
// Quickly check if there is an origin point without constructing Random
|
||||
if (!has_origin_fast(origin_chunk)) {
|
||||
return {false, {}, 0};
|
||||
}
|
||||
|
||||
unsigned chunk_seed =
|
||||
HASH::chunk_seed_hash(origin_chunk.x, origin_chunk.z, m_world_seed);
|
||||
Random random{chunk_seed};
|
||||
if (random.random_bool(static_cast<double>(m_probability))) {
|
||||
const int CHUNK_MIN_X = chunk_pos.x * CHUNK_SIZE;
|
||||
const int CHUNK_MIN_Z = chunk_pos.z * CHUNK_SIZE;
|
||||
const int CHUNK_MAX_X = CHUNK_MIN_X + SIZE_X - 1;
|
||||
const int CHUNK_MAX_Z = CHUNK_MIN_Z + SIZE_Z - 1;
|
||||
int x = random.random_int(CHUNK_MIN_X, CHUNK_MAX_X);
|
||||
int y = SEA_LEVEL + 2;
|
||||
int z = random.random_int(CHUNK_MIN_Z, CHUNK_MAX_Z);
|
||||
add_path(glm::vec3{x, y, z}, chunk_seed);
|
||||
}
|
||||
|
||||
const int CHUNK_MIN_X = origin_chunk.x * CHUNK_SIZE;
|
||||
const int CHUNK_MIN_Z = origin_chunk.z * CHUNK_SIZE;
|
||||
const int CHUNK_MAX_X = CHUNK_MIN_X + SIZE_X - 1;
|
||||
const int CHUNK_MAX_Z = CHUNK_MIN_Z + SIZE_Z - 1;
|
||||
int x = random.random_int(CHUNK_MIN_X, CHUNK_MAX_X);
|
||||
int y = SEA_LEVEL + 2;
|
||||
int z = random.random_int(CHUNK_MIN_Z, CHUNK_MAX_Z);
|
||||
return {true, {x, y, z}, chunk_seed};
|
||||
}
|
||||
|
||||
void RiverWorm::cleanup_finished_rivers() {
|
||||
std::vector<unsigned> finished_keys;
|
||||
|
||||
for (const auto& pair : m_paths) {
|
||||
if (pair.second.is_finished()) {
|
||||
finished_keys.push_back(pair.first);
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto& key : finished_keys) {
|
||||
m_paths.erase(key);
|
||||
}
|
||||
int RiverWorm::search_radius() const {
|
||||
float max_displacement =
|
||||
3.0f * std::sqrt(static_cast<float>(RiverPath::step_max())) *
|
||||
RiverPath::step_len();
|
||||
return static_cast<int>(std::ceil(
|
||||
(max_displacement + RiverPath::radius_xz_max()) / CHUNK_SIZE));
|
||||
}
|
||||
|
||||
int RiverWorm::river_sum() const { return m_paths.size(); }
|
||||
float& RiverWorm::river_probability() { return m_probability; }
|
||||
std::shared_mutex& RiverWorm::paths_mutex() { return m_paths_mutex; }
|
||||
unsigned RiverWorm::world_seed() const { return m_world_seed; }
|
||||
float RiverWorm::river_probability() const { return m_probability; }
|
||||
|
||||
} // namespace Cubed
|
||||
Reference in New Issue
Block a user