From fd1ff4b4ff3cd718f4f85253f1ebc865894e5ffe Mon Sep 17 00:00:00 2001 From: Relintai Date: Mon, 10 Feb 2020 23:39:57 +0100 Subject: [PATCH] Better chunk building setup. And smaller fixes and tweaks. --- meshers/voxel_mesher.cpp | 2 +- meshers/voxel_mesher.h | 2 +- world/voxel_chunk.cpp | 112 ++++++++++++++++++++++++++++++++------- world/voxel_chunk.h | 42 ++++++++------- world/voxel_world.cpp | 2 +- 5 files changed, 119 insertions(+), 41 deletions(-) diff --git a/meshers/voxel_mesher.cpp b/meshers/voxel_mesher.cpp index 17cbed9..39c81f1 100644 --- a/meshers/voxel_mesher.cpp +++ b/meshers/voxel_mesher.cpp @@ -34,7 +34,7 @@ void VoxelMesher::set_library(Ref library) { Ref VoxelMesher::get_material() { return _material; } -void VoxelMesher::set_material(Ref material) { +void VoxelMesher::set_material(const Ref &material) { _material = material; } diff --git a/meshers/voxel_mesher.h b/meshers/voxel_mesher.h index 05f2359..b6ed937 100644 --- a/meshers/voxel_mesher.h +++ b/meshers/voxel_mesher.h @@ -56,7 +56,7 @@ public: void set_library(Ref library); Ref get_material(); - void set_material(Ref material); + void set_material(const Ref &material); float get_ao_strength() const; void set_ao_strength(float value); diff --git a/world/voxel_chunk.cpp b/world/voxel_chunk.cpp index 85dd4be..6b0125d 100644 --- a/world/voxel_chunk.cpp +++ b/world/voxel_chunk.cpp @@ -538,20 +538,64 @@ void VoxelChunk::finalize_mesh() { } } -void VoxelChunk::build() { +void VoxelChunk::build_deferred() { if (_current_build_phase == BUILD_PHASE_DONE) { + _build_prioritized = false; + + set_process_internal(true); + + if (_build_thread) { + Thread::wait_to_finish(_build_thread); + memdelete(_build_thread); + _build_thread = NULL; + } + _is_generating = true; next_phase(); } } -void VoxelChunk::_build_phase_threaded(void *_userdata) { +void VoxelChunk::build_prioritized() { + if (_current_build_phase == BUILD_PHASE_DONE) { + _build_prioritized = true; + + set_process_internal(true); + + if (_build_thread) { + Thread::wait_to_finish(_build_thread); + memdelete(_build_thread); + _build_thread = NULL; + } + + _is_generating = true; + + next_phase(); + } +} + +void VoxelChunk::_build_step() { + if (_build_prioritized) + build_phase(); + + if (_is_build_threaded) { + ERR_FAIL_COND(_build_thread != NULL); + + _build_thread = Thread::create(_build_threaded, this); + } else { + build_phase(); + } +} + +void VoxelChunk::_build_threaded(void *_userdata) { VoxelChunk *vc = (VoxelChunk *)_userdata; + vc->build_phase(); } void VoxelChunk::build_phase() { + _build_phase_done = false; + call("_build_phase", _current_build_phase); } @@ -660,6 +704,16 @@ void VoxelChunk::_build_phase(int phase) { return; } + /* + case BUILD_PHASE_LIQUID: { + next_phase(); + return; + } + case BUILD_PHASE_CLUTTER: { + next_phase(); + return; + } + */ case BUILD_PHASE_FINALIZE: { if (_mesh_instance_rid != RID()) VS::get_singleton()->instance_set_visible(_mesh_instance_rid, is_visible()); @@ -682,37 +736,32 @@ void VoxelChunk::_build_phase(int phase) { next_phase(); } +bool VoxelChunk::has_next_phase() { + if (_current_build_phase == BUILD_PHASE_DONE) + return false; + + return true; +} + void VoxelChunk::next_phase() { + _build_phase_done = true; + if (_abort_build) { _current_build_phase = BUILD_PHASE_DONE; _is_generating = false; - return; - } + set_process_internal(false); - if (_build_thread) { - Thread::wait_to_finish(_build_thread); - memdelete(_build_thread); - _build_thread = NULL; + return; } ++_current_build_phase; if (_current_build_phase >= _max_build_phases) { _current_build_phase = BUILD_PHASE_DONE; - _is_generating = false; + set_process_internal(false); emit_signal("mesh_generation_finished", this); - - return; - } - - if (_is_build_threaded) { - ERR_FAIL_COND(_build_thread != NULL); - - _build_thread = Thread::create(_build_phase_threaded, this); - } else { - build_phase(); } } @@ -1212,6 +1261,8 @@ VoxelChunk::VoxelChunk() { _margin_start = 0; _margin_end = 0; + _build_prioritized = false; + _build_phase_done = false; _build_thread = NULL; } @@ -1254,6 +1305,25 @@ void VoxelChunk::_notification(int p_what) { _build_thread = NULL; } } + case NOTIFICATION_INTERNAL_PROCESS: { + if (_build_prioritized) { + while (has_next_phase() && _build_phase_done) { + build_phase(); + } + + return; + } + + if (has_next_phase() && _build_phase_done) { + if (_build_thread) { + Thread::wait_to_finish(_build_thread); + memdelete(_build_thread); + _build_thread = NULL; + } + + build_phase(); + } + } } } @@ -1409,10 +1479,12 @@ void VoxelChunk::_bind_methods() { BIND_VMETHOD(MethodInfo("_build_phase", PropertyInfo(Variant::INT, "phase"))); - ClassDB::bind_method(D_METHOD("build"), &VoxelChunk::build); + ClassDB::bind_method(D_METHOD("build_deferred"), &VoxelChunk::build_deferred); + ClassDB::bind_method(D_METHOD("build_prioritized"), &VoxelChunk::build_prioritized); ClassDB::bind_method(D_METHOD("build_phase"), &VoxelChunk::build_phase); ClassDB::bind_method(D_METHOD("_build_phase", "phase"), &VoxelChunk::_build_phase); ClassDB::bind_method(D_METHOD("next_phase"), &VoxelChunk::next_phase); + ClassDB::bind_method(D_METHOD("has_next_phase"), &VoxelChunk::has_next_phase); ClassDB::bind_method(D_METHOD("clear"), &VoxelChunk::clear); ClassDB::bind_method(D_METHOD("create_colliders"), &VoxelChunk::create_colliders); diff --git a/world/voxel_chunk.h b/world/voxel_chunk.h index 524ea46..e73ce85 100644 --- a/world/voxel_chunk.h +++ b/world/voxel_chunk.h @@ -66,26 +66,26 @@ class VoxelChunk : public Spatial { public: enum { VOXEL_CHUNK_STATE_OK = 0, - VOXEL_CHUNK_STATE_GENERATION_QUEUED = 1, - VOXEL_CHUNK_STATE_GENERATION = 2, - VOXEL_CHUNK_STATE_MESH_GENERATION_QUEUED = 3, - VOXEL_CHUNK_STATE_MESH_GENERATION = 4, - VOXEL_CHUNK_STATE_MAX = 5, + VOXEL_CHUNK_STATE_GENERATION_QUEUED, + VOXEL_CHUNK_STATE_GENERATION, + VOXEL_CHUNK_STATE_MESH_GENERATION_QUEUED, + VOXEL_CHUNK_STATE_MESH_GENERATION, + VOXEL_CHUNK_STATE_MAX, }; enum { BUILD_PHASE_DONE = 0, - BUILD_PHASE_SETUP = 1, - BUILD_PHASE_TERRARIN_MESH_SETUP = 2, - BUILD_PHASE_TERRARIN_MESH_COLLIDER = 3, - BUILD_PHASE_LIGHTS = 4, - BUILD_PHASE_TERRARIN_MESH = 5, - BUILD_PHASE_PROP_MESH = 6, - BUILD_PHASE_PROP_COLLIDER = 7, - BUILD_PHASE_LIQUID = 8, - BUILD_PHASE_CLUTTER = 9, - BUILD_PHASE_FINALIZE = 10, - BUILD_PHASE_MAX = 11 + BUILD_PHASE_SETUP, + BUILD_PHASE_TERRARIN_MESH_SETUP, + BUILD_PHASE_TERRARIN_MESH_COLLIDER, + BUILD_PHASE_LIGHTS, + BUILD_PHASE_TERRARIN_MESH, + BUILD_PHASE_PROP_MESH, + BUILD_PHASE_PROP_COLLIDER, + //BUILD_PHASE_LIQUID, + //BUILD_PHASE_CLUTTER, + BUILD_PHASE_FINALIZE, + BUILD_PHASE_MAX }; enum DefaultChannels { @@ -218,10 +218,14 @@ public: void finalize_mesh(); - void build(); - static void _build_phase_threaded(void *_userdata); + void build_deferred(); + void build_prioritized(); + static void _build_threaded(void *_userdata); + void build_phase(); + void _build_step(); void _build_phase(int phase); + bool has_next_phase(); void next_phase(); void clear(); @@ -368,6 +372,8 @@ protected: bool _bake_lights; + bool _build_prioritized; + bool _build_phase_done; Thread *_build_thread; }; diff --git a/world/voxel_world.cpp b/world/voxel_world.cpp index 3917f74..a93e795 100644 --- a/world/voxel_world.cpp +++ b/world/voxel_world.cpp @@ -286,7 +286,7 @@ void VoxelWorld::generate_chunk(VoxelChunk *p_chunk) { call("_generate_chunk", p_chunk); - p_chunk->build(); + p_chunk->build_deferred(); } void VoxelWorld::_generate_chunk(Node *p_chunk) {