From 0a4d07c582487b7c212270c1da8b0e02670bea58 Mon Sep 17 00:00:00 2001 From: Relintai Date: Tue, 4 Aug 2020 14:40:40 +0200 Subject: [PATCH] The terrarin mesh setup phase can now distribute it's calculations onto multiple frames.. Also small fixes to the single threaded logic. --- .../voxel_mesher_marching_cubes.cpp | 42 ++++++++++++++++++- world/default/voxel_chunk_default.cpp | 38 ++++++++++++++++- world/default/voxel_job.cpp | 18 ++++++-- world/default/voxel_job.h | 2 - 4 files changed, 90 insertions(+), 10 deletions(-) diff --git a/meshers/marching_cubes/voxel_mesher_marching_cubes.cpp b/meshers/marching_cubes/voxel_mesher_marching_cubes.cpp index c93650e..807ea5e 100644 --- a/meshers/marching_cubes/voxel_mesher_marching_cubes.cpp +++ b/meshers/marching_cubes/voxel_mesher_marching_cubes.cpp @@ -27,6 +27,8 @@ SOFTWARE. #include "core/array.h" #include "core/dictionary.h" +#include "../../world/default/voxel_job.h" + #include "core/version.h" #if VERSION_MAJOR < 4 @@ -187,7 +189,18 @@ void VoxelMesherMarchingCubes::_add_chunk(Ref p_chunk) { ERR_FAIL_COND(!chunk.is_valid()); - chunk->generate_ao(); + Ref job = chunk->get_job(); + + if (!job->has_meta("ao_done")) { + job->set_meta("ao_done", true); + chunk->generate_ao(); + } + + job->remove_meta("ao_done"); + + if (job->should_return()) { + return; + } int type_arr[8]; @@ -197,7 +210,18 @@ void VoxelMesherMarchingCubes::_add_chunk(Ref p_chunk) { int lod_size = get_lod_size(); - for (int y = 0; y < y_size; y += lod_size) { + int start_y = 0; + + if (job->has_meta("mc_start_y")) { + start_y = job->get_meta("mc_start_y"); + } + + for (int y = start_y; y < y_size; y += lod_size) { + if (job->should_return()) { + job->set_meta("mc_start_y", y); + return; + } + for (int z = 0; z < z_size; z += lod_size) { for (int x = 0; x < x_size; x += lod_size) { @@ -437,7 +461,21 @@ void VoxelMesherMarchingCubes::_add_chunk(Ref p_chunk) { } } + job->set_meta("mc_start_y", y_size); + + if (job->should_return()) { + return; + } + remove_doubles_hashed(); + + if (job->has_meta("mc_start_y")) { + job->remove_meta("mc_start_y"); + } + + if (job->has_meta("ao_done")) { + job->remove_meta("ao_done"); + } } Vector3 VoxelMesherMarchingCubes::corner_id_to_vertex(int corner_id) const { diff --git a/world/default/voxel_chunk_default.cpp b/world/default/voxel_chunk_default.cpp index 1ee32a9..f70e912 100644 --- a/world/default/voxel_chunk_default.cpp +++ b/world/default/voxel_chunk_default.cpp @@ -188,6 +188,8 @@ void VoxelChunkDefault::build_step() { _build_step_in_progress = true; + _job->set_complete(false); + #if THREAD_POOL_PRESENT ThreadPool::get_singleton()->add_job(_job); #else @@ -1176,7 +1178,18 @@ void VoxelChunkDefault::_build_phase(int phase) { return; } case BUILD_PHASE_TERRARIN_MESH_SETUP: { - for (int i = 0; i < _meshers.size(); ++i) { + int starti = 0; + + if (_job->has_meta("tms_m")) { + starti = _job->get_meta("tms_m"); + } + + for (int i = starti; i < _meshers.size(); ++i) { + if (_job->should_return()) { + _job->set_meta("tms_m", i); + return; + } + Ref mesher = _meshers.get(i); ERR_CONTINUE(!mesher.is_valid()); @@ -1184,7 +1197,18 @@ void VoxelChunkDefault::_build_phase(int phase) { mesher->add_chunk(this); } - for (int i = 0; i < _liquid_meshers.size(); ++i) { + starti = 0; + + if (_job->has_meta("tms_lm")) { + starti = _job->get_meta("tms_lm"); + } + + for (int i = starti; i < _liquid_meshers.size(); ++i) { + if (_job->should_return()) { + _job->set_meta("tms_lm", i); + return; + } + Ref mesher = _liquid_meshers.get(i); ERR_CONTINUE(!mesher.is_valid()); @@ -1194,6 +1218,14 @@ void VoxelChunkDefault::_build_phase(int phase) { next_phase(); + if (_job->has_meta("tms_m")) { + _job->remove_meta("tms_m"); + } + + if (_job->has_meta("tms_lm")) { + _job->remove_meta("tms_lm"); + } + return; } case BUILD_PHASE_COLLIDER: { @@ -1611,6 +1643,8 @@ void VoxelChunkDefault::_build_phase(int phase) { return; } } + + next_phase(); } void VoxelChunkDefault::_build_phase_process(int phase) { diff --git a/world/default/voxel_job.cpp b/world/default/voxel_job.cpp index b332a95..13e1a68 100644 --- a/world/default/voxel_job.cpp +++ b/world/default/voxel_job.cpp @@ -43,6 +43,17 @@ void VoxelJob::chunk_exit_tree() { void VoxelJob::_execute() { ERR_FAIL_COND(!_chunk.is_valid()); + + if (!_chunk->has_next_phase()) { + //_chunk->set_build_step_in_progress(false); + + //if (!_in_tree) { + // _chunk.unref(); + //} + + set_complete(true); + } + ERR_FAIL_COND(!_chunk->has_next_phase()); //ERR_FAIL_COND(_build_step_in_progress); @@ -50,13 +61,13 @@ void VoxelJob::_execute() { while (!get_cancelled() && _in_tree && _chunk->has_next_phase() && _chunk->get_active_build_phase_type() == VoxelChunkDefault::BUILD_PHASE_TYPE_NORMAL) { - int phase = _chunk->get_current_build_phase(); + //int phase = _chunk->get_current_build_phase(); _chunk->build_phase(); - print_error(String::num(get_current_execution_time()) + " phase: " + String::num(phase)); + //print_error(String::num(get_current_execution_time()) + " phase: " + String::num(phase)); - if (should_return()) + if (_chunk->get_active_build_phase_type() == VoxelChunkDefault::BUILD_PHASE_TYPE_NORMAL && should_return()) return; if (!_chunk->get_build_phase_done()) @@ -73,7 +84,6 @@ void VoxelJob::_execute() { } VoxelJob::VoxelJob() { - _build_step_in_progress = false; _in_tree = false; #if !THREAD_POOL_PRESENT diff --git a/world/default/voxel_job.h b/world/default/voxel_job.h index 101ed03..d2e7623 100644 --- a/world/default/voxel_job.h +++ b/world/default/voxel_job.h @@ -49,8 +49,6 @@ public: VoxelJob(); ~VoxelJob(); - bool _build_step_in_progress; - protected: static void _bind_methods();