mirror of
https://github.com/zhenyan121/Cubed.git
synced 2026-06-21 18:17:03 +08:00
feat(world): add ChunkLoadStyle enum and rename chunk_pos to get_chunk_pos
This commit is contained in:
@@ -49,6 +49,7 @@ private:
|
||||
bool m_tick_frezze = false;
|
||||
int m_samples_idx = 1;
|
||||
int m_threads = 1;
|
||||
int m_chunk_style = 0;
|
||||
void show_about_table_bar();
|
||||
void show_biome_table_bar();
|
||||
void show_time_table_bar();
|
||||
|
||||
@@ -35,6 +35,8 @@ class Player;
|
||||
class TextureManager;
|
||||
class World {
|
||||
private:
|
||||
enum class ChunkLoadStyle { RANDOM, CENTER };
|
||||
|
||||
struct PendingChunk {
|
||||
Chunk chunk;
|
||||
std::future<void> future;
|
||||
@@ -85,7 +87,7 @@ private:
|
||||
std::atomic<int> m_pool_threads{1};
|
||||
std::atomic<int> m_max_threads{1};
|
||||
std::atomic<TickType> m_game_ticks{0};
|
||||
|
||||
std::atomic<ChunkLoadStyle> m_chunk_load_style{ChunkLoadStyle::RANDOM};
|
||||
std::vector<ChunkPos> m_dirty_queue;
|
||||
std::vector<ChunkRenderSnapshot> m_render_snapshots;
|
||||
std::vector<std::pair<ChunkPos, Chunk>> m_new_finished_chunk;
|
||||
@@ -124,7 +126,7 @@ public:
|
||||
bool is_solid(const glm::ivec3& block_pos) const;
|
||||
bool can_pass_block(const glm::ivec3& block_pos) const;
|
||||
BlockType get_block_tpye(const glm::ivec3& block_pos) const;
|
||||
static ChunkPos chunk_pos(int world_x, int world_z);
|
||||
static ChunkPos get_chunk_pos(int world_x, int world_z);
|
||||
|
||||
void need_gen();
|
||||
|
||||
@@ -163,6 +165,8 @@ public:
|
||||
int pool_threads() const;
|
||||
int max_threads() const;
|
||||
void change_pool_threads(int threads);
|
||||
int chunk_load_style() const;
|
||||
void set_chunk_load_style(int id);
|
||||
};
|
||||
|
||||
} // namespace Cubed
|
||||
|
||||
@@ -480,6 +480,12 @@ void DevPanel::show_world_tab_item() {
|
||||
"threads minus reserved threads), \nit may cause stuttering.");
|
||||
}
|
||||
|
||||
static const char* chunk_load_style[] = {"Random", "Center"};
|
||||
m_chunk_style = m_app.world().chunk_load_style();
|
||||
if (ImGui::Combo("ChunkLoadStyle", &m_chunk_style, chunk_load_style,
|
||||
IM_ARRAYSIZE(chunk_load_style))) {
|
||||
m_app.world().set_chunk_load_style(m_chunk_style);
|
||||
}
|
||||
if (ImGui::Button("Rebuild World")) {
|
||||
m_app.world().rebuild_world();
|
||||
}
|
||||
|
||||
@@ -299,7 +299,7 @@ void Chunk::gen_vertices(const OptionalBlockVectorArray& neighbor_block) {
|
||||
int world_nz = world_z + DIR[face].z;
|
||||
|
||||
auto [neighbor_x, neighbor_z] =
|
||||
World::chunk_pos(world_nx, world_nz);
|
||||
World::get_chunk_pos(world_nx, world_nz);
|
||||
|
||||
auto is_culled =
|
||||
[&](const std::optional<std::vector<BlockType>>&
|
||||
|
||||
@@ -247,7 +247,7 @@ void Player::update_front_vec(float offset_x, float offset_y) {
|
||||
}
|
||||
|
||||
void Player::check_player_chunk_transition() {
|
||||
ChunkPos cur_pos = m_world.chunk_pos(m_player_pos.x, m_player_pos.z);
|
||||
ChunkPos cur_pos = m_world.get_chunk_pos(m_player_pos.x, m_player_pos.z);
|
||||
if (cur_pos != m_player_chunk_pos) {
|
||||
m_world.need_gen();
|
||||
m_player_chunk_pos = cur_pos;
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <numbers>
|
||||
using namespace std::chrono;
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
namespace Cubed {
|
||||
|
||||
struct ChunkRenderData {
|
||||
@@ -115,7 +116,7 @@ void World::init_chunks() {
|
||||
}
|
||||
}
|
||||
|
||||
ChunkPos World::chunk_pos(int world_x, int world_z) {
|
||||
ChunkPos World::get_chunk_pos(int world_x, int world_z) {
|
||||
int chunk_x, chunk_z;
|
||||
if (world_x < 0) {
|
||||
chunk_x = (world_x + 1) / CHUNK_SIZE - 1;
|
||||
@@ -209,7 +210,7 @@ void World::compute_required_chunks(ChunkPosSet& required_chunks,
|
||||
|
||||
int x = std::floor(player_pos.x);
|
||||
int z = std::floor(player_pos.z);
|
||||
auto [chunk_x, chunk_z] = chunk_pos(x, z);
|
||||
auto [chunk_x, chunk_z] = get_chunk_pos(x, z);
|
||||
int radius = m_rendering_distance;
|
||||
int r2 = radius * radius;
|
||||
required_chunks.reserve(radius * radius);
|
||||
@@ -255,16 +256,49 @@ void World::sync_and_collect_missing_chunks(
|
||||
}
|
||||
|
||||
void World::submit_new_chunks() {
|
||||
using enum ChunkLoadStyle;
|
||||
std::lock_guard lock(m_new_chunk_mutex);
|
||||
auto pool_ptr = m_gen_thread_pool.load();
|
||||
if (!pool_ptr) {
|
||||
return;
|
||||
}
|
||||
for (auto& [pos, task] : new_chunks) {
|
||||
if (!task.future.valid()) {
|
||||
task.future =
|
||||
pool_ptr->enqueue([&task]() { task.chunk.gen_chunk(); });
|
||||
switch (m_chunk_load_style) {
|
||||
case RANDOM:
|
||||
for (auto& [pos, task] : new_chunks) {
|
||||
if (!task.future.valid()) {
|
||||
task.future =
|
||||
pool_ptr->enqueue([&task]() { task.chunk.gen_chunk(); });
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CENTER: {
|
||||
std::vector<std::pair<ChunkPos, PendingChunk*>> tasks;
|
||||
for (auto& [pos, task] : new_chunks) {
|
||||
if (!task.future.valid()) {
|
||||
tasks.emplace_back(pos, &task);
|
||||
}
|
||||
}
|
||||
glm::vec3 player_pos;
|
||||
sync_player_pos(player_pos);
|
||||
auto dist2 = [player_pos](ChunkPos chunk_pos) {
|
||||
ChunkPos player_chunk_pos =
|
||||
get_chunk_pos(player_pos.x, player_pos.z);
|
||||
float dx = player_chunk_pos.x - chunk_pos.x;
|
||||
float dz = player_chunk_pos.z - chunk_pos.z;
|
||||
return dx * dx + dz * dz;
|
||||
};
|
||||
|
||||
std::sort(tasks.begin(), tasks.end(),
|
||||
[&dist2](const auto& a, const auto& b) {
|
||||
return dist2(a.first) < dist2(b.first);
|
||||
});
|
||||
for (auto& [pos, task] : tasks) {
|
||||
if (!task->future.valid()) {
|
||||
task->future =
|
||||
pool_ptr->enqueue([task]() { task->chunk.gen_chunk(); });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -363,7 +397,7 @@ void World::need_gen() {
|
||||
}
|
||||
|
||||
int World::get_block(const glm::ivec3& block_pos) const {
|
||||
auto [chunk_x, chunk_z] = chunk_pos(block_pos.x, block_pos.z);
|
||||
auto [chunk_x, chunk_z] = get_chunk_pos(block_pos.x, block_pos.z);
|
||||
std::lock_guard lk(m_chunks_mutex);
|
||||
auto it = m_chunks.find(ChunkPos{chunk_x, chunk_z});
|
||||
|
||||
@@ -381,7 +415,7 @@ int World::get_block(const glm::ivec3& block_pos) const {
|
||||
}
|
||||
|
||||
bool World::is_solid(const glm::ivec3& block_pos) const {
|
||||
auto [chunk_x, chunk_z] = chunk_pos(block_pos.x, block_pos.z);
|
||||
auto [chunk_x, chunk_z] = get_chunk_pos(block_pos.x, block_pos.z);
|
||||
std::lock_guard lk(m_chunks_mutex);
|
||||
auto it = m_chunks.find(ChunkPos{chunk_x, chunk_z});
|
||||
|
||||
@@ -403,7 +437,7 @@ bool World::is_solid(const glm::ivec3& block_pos) const {
|
||||
}
|
||||
|
||||
bool World::can_pass_block(const glm::ivec3& block_pos) const {
|
||||
auto [chunk_x, chunk_z] = chunk_pos(block_pos.x, block_pos.z);
|
||||
auto [chunk_x, chunk_z] = get_chunk_pos(block_pos.x, block_pos.z);
|
||||
std::lock_guard lk(m_chunks_mutex);
|
||||
auto it = m_chunks.find(ChunkPos{chunk_x, chunk_z});
|
||||
|
||||
@@ -421,7 +455,7 @@ bool World::can_pass_block(const glm::ivec3& block_pos) const {
|
||||
}
|
||||
|
||||
BlockType World::get_block_tpye(const glm::ivec3& block_pos) const {
|
||||
auto [chunk_x, chunk_z] = chunk_pos(block_pos.x, block_pos.z);
|
||||
auto [chunk_x, chunk_z] = get_chunk_pos(block_pos.x, block_pos.z);
|
||||
std::lock_guard lk(m_chunks_mutex);
|
||||
auto it = m_chunks.find(ChunkPos{chunk_x, chunk_z});
|
||||
|
||||
@@ -448,7 +482,7 @@ void World::set_block(const glm::ivec3& block_pos, unsigned id) {
|
||||
world_y = block_pos.y;
|
||||
world_z = block_pos.z;
|
||||
|
||||
auto [chunk_x, chunk_z] = chunk_pos(world_x, world_z);
|
||||
auto [chunk_x, chunk_z] = get_chunk_pos(world_x, world_z);
|
||||
std::lock_guard lk(m_chunks_mutex);
|
||||
auto it = m_chunks.find(ChunkPos{chunk_x, chunk_z});
|
||||
|
||||
@@ -471,7 +505,7 @@ void World::set_block(const glm::ivec3& block_pos, unsigned id) {
|
||||
for (const auto& dir : NEIGHBOR_DIRS) {
|
||||
glm::ivec3 neighbor = block_pos + dir;
|
||||
|
||||
auto [cx, cz] = chunk_pos(neighbor.x, neighbor.z);
|
||||
auto [cx, cz] = get_chunk_pos(neighbor.x, neighbor.z);
|
||||
auto it = m_chunks.find({cx, cz});
|
||||
if (it != m_chunks.end()) {
|
||||
it->second.mark_dirty();
|
||||
@@ -670,4 +704,25 @@ void World::change_pool_threads(int threads) {
|
||||
m_gen_thread_pool.store(std::make_shared<ThreadPool>(used_thread));
|
||||
m_pool_threads = used_thread;
|
||||
}
|
||||
int World::chunk_load_style() const {
|
||||
return std::to_underlying(m_chunk_load_style.load());
|
||||
}
|
||||
void World::set_chunk_load_style(int id) {
|
||||
using enum ChunkLoadStyle;
|
||||
using std::to_underlying;
|
||||
switch (m_chunk_load_style.load()) {
|
||||
case RANDOM:
|
||||
if (id == to_underlying(RANDOM)) {
|
||||
m_chunk_load_style = RANDOM;
|
||||
return;
|
||||
}
|
||||
case CENTER:
|
||||
if (id == to_underlying(CENTER)) {
|
||||
m_chunk_load_style = CENTER;
|
||||
return;
|
||||
}
|
||||
}
|
||||
Logger::error("Can,t Find Chunk Load Style Id {}, Nothing Will Do", id);
|
||||
}
|
||||
|
||||
} // namespace Cubed
|
||||
Reference in New Issue
Block a user