mirror of
https://github.com/Relintai/voxelman.git
synced 2024-11-12 10:15:12 +01:00
Chunk now supports threaded builds. Also small fixes.
This commit is contained in:
parent
a377c994e9
commit
edec04cfdc
@ -9,6 +9,13 @@ _FORCE_INLINE_ void VoxelChunk::set_is_generating(bool value) {
|
||||
_is_generating = value;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ bool VoxelChunk::get_is_build_threaded() const {
|
||||
return _is_build_threaded;
|
||||
}
|
||||
_FORCE_INLINE_ void VoxelChunk::set_is_build_threaded(bool value) {
|
||||
_is_build_threaded = value;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ bool VoxelChunk::get_dirty() const {
|
||||
return _dirty;
|
||||
}
|
||||
@ -470,8 +477,13 @@ void VoxelChunk::build() {
|
||||
}
|
||||
}
|
||||
|
||||
void VoxelChunk::build_phase(int phase) {
|
||||
call("_build_phase", phase);
|
||||
void VoxelChunk::_build_phase_threaded(void *_userdata) {
|
||||
VoxelChunk *vc = (VoxelChunk *)_userdata;
|
||||
vc->build_phase();
|
||||
}
|
||||
|
||||
void VoxelChunk::build_phase() {
|
||||
call("_build_phase", _current_build_phase);
|
||||
}
|
||||
|
||||
void VoxelChunk::_build_phase(int phase) {
|
||||
@ -574,6 +586,18 @@ void VoxelChunk::_build_phase(int phase) {
|
||||
}
|
||||
|
||||
void VoxelChunk::next_phase() {
|
||||
if (_abort_build) {
|
||||
_current_build_phase = BUILD_PHASE_DONE;
|
||||
_is_generating = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (_build_thread) {
|
||||
Thread::wait_to_finish(_build_thread);
|
||||
memdelete(_build_thread);
|
||||
_build_thread = NULL;
|
||||
}
|
||||
|
||||
++_current_build_phase;
|
||||
|
||||
if (_current_build_phase >= BUILD_PHASE_MAX) {
|
||||
@ -586,7 +610,13 @@ void VoxelChunk::next_phase() {
|
||||
return;
|
||||
}
|
||||
|
||||
build_phase(_current_build_phase);
|
||||
if (_is_build_threaded) {
|
||||
ERR_FAIL_COND(_build_thread != NULL);
|
||||
|
||||
_build_thread = Thread::create(_build_phase_threaded, this);
|
||||
} else {
|
||||
build_phase();
|
||||
}
|
||||
}
|
||||
|
||||
void VoxelChunk::clear() {
|
||||
@ -1062,6 +1092,8 @@ void VoxelChunk::free_chunk() {
|
||||
|
||||
VoxelChunk::VoxelChunk() {
|
||||
_is_generating = false;
|
||||
_is_build_threaded = false;
|
||||
_abort_build = false;
|
||||
_dirty = false;
|
||||
_state = VOXEL_CHUNK_STATE_OK;
|
||||
|
||||
@ -1078,6 +1110,8 @@ VoxelChunk::VoxelChunk() {
|
||||
|
||||
_margin_start = 0;
|
||||
_margin_end = 0;
|
||||
|
||||
_build_thread = NULL;
|
||||
}
|
||||
|
||||
VoxelChunk::~VoxelChunk() {
|
||||
@ -1110,6 +1144,20 @@ VoxelChunk::~VoxelChunk() {
|
||||
}
|
||||
}
|
||||
|
||||
void VoxelChunk::_notification(int p_what) {
|
||||
switch (p_what) {
|
||||
case NOTIFICATION_EXIT_TREE: {
|
||||
if (_build_thread) {
|
||||
_abort_build = true;
|
||||
|
||||
Thread::wait_to_finish(_build_thread);
|
||||
memdelete(_build_thread);
|
||||
_build_thread = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void VoxelChunk::_bind_methods() {
|
||||
ADD_SIGNAL(MethodInfo("mesh_generation_finished", PropertyInfo(Variant::OBJECT, "chunk", PROPERTY_HINT_RESOURCE_TYPE, "VoxelChunk")));
|
||||
|
||||
@ -1124,6 +1172,10 @@ void VoxelChunk::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("set_is_generating", "value"), &VoxelChunk::set_is_generating);
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "is_generating"), "set_is_generating", "get_is_generating");
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_is_build_threaded"), &VoxelChunk::get_is_build_threaded);
|
||||
ClassDB::bind_method(D_METHOD("set_is_build_threaded", "value"), &VoxelChunk::set_is_build_threaded);
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "is_build_threaded"), "set_is_build_threaded", "get_is_build_threaded");
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_dirty"), &VoxelChunk::get_dirty);
|
||||
ClassDB::bind_method(D_METHOD("set_dirty", "value"), &VoxelChunk::set_dirty);
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "dirty"), "set_dirty", "get_dirty");
|
||||
@ -1256,7 +1308,7 @@ 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_phase", "phase"), &VoxelChunk::build_phase);
|
||||
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("clear"), &VoxelChunk::clear);
|
||||
|
@ -5,6 +5,9 @@
|
||||
|
||||
#include "core/engine.h"
|
||||
#include "core/ustring.h"
|
||||
#include "core/os/thread.h"
|
||||
#include "core/os/thread_safe.h"
|
||||
|
||||
#include "scene/3d/mesh_instance.h"
|
||||
#include "scene/resources/packed_scene.h"
|
||||
#include "core/array.h"
|
||||
@ -36,6 +39,8 @@ class VoxelWorld;
|
||||
class VoxelChunk : public Spatial {
|
||||
GDCLASS(VoxelChunk, Spatial);
|
||||
|
||||
_THREAD_SAFE_CLASS_
|
||||
|
||||
public:
|
||||
enum {
|
||||
VOXEL_CHUNK_STATE_OK = 0,
|
||||
@ -79,6 +84,9 @@ public:
|
||||
bool get_is_generating() const;
|
||||
void set_is_generating(bool value);
|
||||
|
||||
bool get_is_build_threaded() const;
|
||||
void set_is_build_threaded(bool value);
|
||||
|
||||
bool get_dirty() const;
|
||||
void set_dirty(bool value);
|
||||
|
||||
@ -183,7 +191,8 @@ public:
|
||||
void finalize_mesh();
|
||||
|
||||
void build();
|
||||
void build_phase(int phase);
|
||||
static void _build_phase_threaded(void *_userdata);
|
||||
void build_phase();
|
||||
void _build_phase(int phase);
|
||||
void next_phase();
|
||||
|
||||
@ -255,9 +264,12 @@ public:
|
||||
~VoxelChunk();
|
||||
|
||||
protected:
|
||||
void _notification(int p_what);
|
||||
static void _bind_methods();
|
||||
|
||||
bool _is_generating;
|
||||
bool _is_build_threaded;
|
||||
bool _abort_build;
|
||||
bool _dirty;
|
||||
int _state;
|
||||
|
||||
@ -326,6 +338,8 @@ protected:
|
||||
bool _create_collider;
|
||||
|
||||
bool _bake_lights;
|
||||
|
||||
Thread *_build_thread;
|
||||
};
|
||||
|
||||
VARIANT_ENUM_CAST(VoxelChunk::DefaultChannels);
|
||||
|
@ -214,12 +214,23 @@ void VoxelWorld::clear() {
|
||||
}
|
||||
|
||||
VoxelChunk *VoxelWorld::create_chunk(int x, int y, int z) {
|
||||
Node *n = call("_create_chunk", x, y, z);
|
||||
Node *np = NULL;
|
||||
|
||||
Node *n = call("_create_chunk", x, y, z, np);
|
||||
|
||||
return(Object::cast_to<VoxelChunk>(n));
|
||||
}
|
||||
VoxelChunk *VoxelWorld::_create_chunk(int x, int y, int z) {
|
||||
VoxelChunk *chunk = memnew(VoxelChunk);
|
||||
VoxelChunk *VoxelWorld::_create_chunk(int x, int y, int z, Node *p_chunk) {
|
||||
VoxelChunk *chunk;
|
||||
|
||||
if (p_chunk != NULL) {
|
||||
chunk = Object::cast_to<VoxelChunk>(p_chunk);
|
||||
} else {
|
||||
chunk = memnew(VoxelChunk);
|
||||
}
|
||||
|
||||
ERR_FAIL_COND_V(!ObjectDB::instance_validate(chunk), NULL);
|
||||
|
||||
chunk->set_name("Chunk[" + String::num(x) + "," + String::num(y) + "," + String::num(z) + "]");
|
||||
add_child(chunk);
|
||||
|
||||
@ -227,6 +238,7 @@ VoxelChunk *VoxelWorld::_create_chunk(int x, int y, int z) {
|
||||
chunk->set_owner(get_tree()->get_edited_scene_root());
|
||||
|
||||
chunk->set_voxel_world(this);
|
||||
chunk->set_is_build_threaded(_use_threads);
|
||||
chunk->set_position(x, y, z);
|
||||
chunk->set_library(_library);
|
||||
chunk->set_voxel_scale(_voxel_scale);
|
||||
@ -235,7 +247,7 @@ VoxelChunk *VoxelWorld::_create_chunk(int x, int y, int z) {
|
||||
|
||||
add_chunk(chunk, x, y, z);
|
||||
|
||||
_generation_queue.push_back(chunk);
|
||||
add_to_generation_queue(chunk);
|
||||
|
||||
return chunk;
|
||||
}
|
||||
@ -292,7 +304,7 @@ VoxelWorld ::~VoxelWorld() {
|
||||
_player = NULL;
|
||||
|
||||
_generation_queue.clear();
|
||||
_generating.clear();;
|
||||
_generating.clear();
|
||||
}
|
||||
|
||||
void VoxelWorld::_notification(int p_what) {
|
||||
@ -340,6 +352,8 @@ void VoxelWorld::_notification(int p_what) {
|
||||
generate_chunk(chunk);
|
||||
}
|
||||
}
|
||||
case NOTIFICATION_EXIT_TREE: {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -420,12 +434,12 @@ void VoxelWorld::_bind_methods() {
|
||||
ADD_SIGNAL(MethodInfo("generation_finished"));
|
||||
BIND_VMETHOD(MethodInfo("_generation_finished"));
|
||||
|
||||
BIND_VMETHOD(MethodInfo(PropertyInfo(Variant::OBJECT, "ret", PROPERTY_HINT_RESOURCE_TYPE, "VoxelChunk"), "_create_chunk", PropertyInfo(Variant::INT, "x"), PropertyInfo(Variant::INT, "y"), PropertyInfo(Variant::INT, "z")));
|
||||
BIND_VMETHOD(MethodInfo(PropertyInfo(Variant::OBJECT, "ret", PROPERTY_HINT_RESOURCE_TYPE, "VoxelChunk"), "_create_chunk", PropertyInfo(Variant::INT, "x"), PropertyInfo(Variant::INT, "y"), PropertyInfo(Variant::INT, "z"), PropertyInfo(Variant::OBJECT, "chunk", PROPERTY_HINT_RESOURCE_TYPE, "VoxelChunk")));
|
||||
BIND_VMETHOD(MethodInfo("_prepare_chunk_for_generation", PropertyInfo(Variant::OBJECT, "chunk", PROPERTY_HINT_RESOURCE_TYPE, "VoxelChunk")));
|
||||
BIND_VMETHOD(MethodInfo("_generate_chunk", PropertyInfo(Variant::OBJECT, "chunk", PROPERTY_HINT_RESOURCE_TYPE, "VoxelChunk")));
|
||||
|
||||
ClassDB::bind_method(D_METHOD("create_chunk", "x", "y", "z"), &VoxelWorld::create_chunk);
|
||||
ClassDB::bind_method(D_METHOD("_create_chunk", "x", "y", "z"), &VoxelWorld::_create_chunk);
|
||||
ClassDB::bind_method(D_METHOD("_create_chunk", "x", "y", "z", "chunk"), &VoxelWorld::_create_chunk);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("_generate_chunk", "chunk"), &VoxelWorld::_generate_chunk);
|
||||
}
|
||||
|
@ -83,7 +83,7 @@ public:
|
||||
void clear();
|
||||
|
||||
VoxelChunk *create_chunk(int x, int y, int z);
|
||||
VoxelChunk *_create_chunk(int x, int y, int z);
|
||||
VoxelChunk *_create_chunk(int x, int y, int z, Node *p_chunk);
|
||||
|
||||
void generate_chunk_bind(Node *p_chunk);
|
||||
void generate_chunk(VoxelChunk *p_chunk);
|
||||
|
Loading…
Reference in New Issue
Block a user