From fd3a162126e4b490950543f7196fc12653158a34 Mon Sep 17 00:00:00 2001 From: Relintai Date: Thu, 10 Oct 2019 23:51:05 +0200 Subject: [PATCH] Reworked the way chung handles props, and made chunk building fully scriptable. --- SCsub | 1 + props/voxelman_prop.cpp | 24 +++ props/voxelman_prop.h | 9 + props/voxelman_prop_mesh.cpp | 24 +++ props/voxelman_prop_mesh.h | 9 + props/voxelman_prop_scene.cpp | 24 +++ props/voxelman_prop_scene.h | 9 + register_types.cpp | 2 + world/voxel_chunk.cpp | 315 ++++++++++++++++++-------------- world/voxel_chunk.h | 67 ++++--- world/voxel_chunk_prop_data.cpp | 138 ++++++++++++++ world/voxel_chunk_prop_data.h | 71 +++++++ 12 files changed, 531 insertions(+), 162 deletions(-) create mode 100644 world/voxel_chunk_prop_data.cpp create mode 100644 world/voxel_chunk_prop_data.h diff --git a/SCsub b/SCsub index b36f884..841e400 100644 --- a/SCsub +++ b/SCsub @@ -20,6 +20,7 @@ env.add_source_files(env.modules_sources,"world/voxel_world.cpp") env.add_source_files(env.modules_sources,"world/voxel_chunk.cpp") env.add_source_files(env.modules_sources,"world/voxel_structure.cpp") env.add_source_files(env.modules_sources,"world/environment_data.cpp") +env.add_source_files(env.modules_sources,"world/voxel_chunk_prop_data.cpp") env.add_source_files(env.modules_sources,"meshers/cubic_mesher/voxel_mesher_cubic.cpp") diff --git a/props/voxelman_prop.cpp b/props/voxelman_prop.cpp index a290282..7234011 100644 --- a/props/voxelman_prop.cpp +++ b/props/voxelman_prop.cpp @@ -1,5 +1,19 @@ #include "voxelman_prop.h" +bool VoxelmanProp::get_snap_to_mesh() { + return _snap_to_mesh; +} +void VoxelmanProp::set_snap_to_mesh(bool value) { + _snap_to_mesh = value; +} + +Vector3 VoxelmanProp::get_snap_axis() { + return _snap_axis; +} +void VoxelmanProp::set_snap_axis(Vector3 value) { + _snap_axis = value; +} + Ref VoxelmanProp::get_prop(const int index) const { ERR_FAIL_INDEX_V(index, _props.size(), Ref()); @@ -40,12 +54,22 @@ void VoxelmanProp::set_props(const Vector &props) { } VoxelmanProp::VoxelmanProp() { + _snap_to_mesh = true; + _snap_axis = Vector3(0, 1, 0); } VoxelmanProp::~VoxelmanProp() { _props.clear(); } void VoxelmanProp::_bind_methods() { + ClassDB::bind_method(D_METHOD("get_snap_to_mesh"), &VoxelmanProp::get_snap_to_mesh); + ClassDB::bind_method(D_METHOD("set_snap_to_mesh", "value"), &VoxelmanProp::set_snap_to_mesh); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "snap_to_mesh"), "set_snap_to_mesh", "get_snap_to_mesh"); + + ClassDB::bind_method(D_METHOD("get_snap_axis"), &VoxelmanProp::get_snap_axis); + ClassDB::bind_method(D_METHOD("set_snap_axis", "value"), &VoxelmanProp::set_snap_axis); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "snap_axis"), "set_snap_axis", "get_snap_axis"); + ClassDB::bind_method(D_METHOD("get_prop", "index"), &VoxelmanProp::get_prop); ClassDB::bind_method(D_METHOD("set_prop", "index", "spell"), &VoxelmanProp::set_prop); ClassDB::bind_method(D_METHOD("add_prop", "prop"), &VoxelmanProp::add_prop); diff --git a/props/voxelman_prop.h b/props/voxelman_prop.h index 8c11b94..2d5bf05 100644 --- a/props/voxelman_prop.h +++ b/props/voxelman_prop.h @@ -10,6 +10,12 @@ class VoxelmanProp : public Resource { GDCLASS(VoxelmanProp, Resource); public: + bool get_snap_to_mesh(); + void set_snap_to_mesh(bool value); + + Vector3 get_snap_axis(); + void set_snap_axis(Vector3 value); + Ref get_prop(const int index) const; void set_prop(const int index, const Ref prop); void add_prop(const Ref prop); @@ -27,6 +33,9 @@ protected: static void _bind_methods(); private: + bool _snap_to_mesh; + Vector3 _snap_axis; + Vector > _props; }; diff --git a/props/voxelman_prop_mesh.cpp b/props/voxelman_prop_mesh.cpp index 039c5df..97fab63 100644 --- a/props/voxelman_prop_mesh.cpp +++ b/props/voxelman_prop_mesh.cpp @@ -7,7 +7,23 @@ void VoxelmanPropMesh::set_mesh(const Ref mesh) { _mesh = mesh; } +bool VoxelmanPropMesh::get_snap_to_mesh() { + return _snap_to_mesh; +} +void VoxelmanPropMesh::set_snap_to_mesh(bool value) { + _snap_to_mesh = value; +} + +Vector3 VoxelmanPropMesh::get_snap_axis() { + return _snap_axis; +} +void VoxelmanPropMesh::set_snap_axis(Vector3 value) { + _snap_axis = value; +} + VoxelmanPropMesh::VoxelmanPropMesh() { + _snap_to_mesh = true; + _snap_axis = Vector3(0, 1, 0); } VoxelmanPropMesh::~VoxelmanPropMesh() { if (_mesh.is_valid()) @@ -18,4 +34,12 @@ void VoxelmanPropMesh::_bind_methods() { ClassDB::bind_method(D_METHOD("get_mesh"), &VoxelmanPropMesh::get_mesh); ClassDB::bind_method(D_METHOD("set_mesh", "value"), &VoxelmanPropMesh::set_mesh); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "mesh", PROPERTY_HINT_RESOURCE_TYPE, "MeshDataResource"), "set_mesh", "get_mesh"); + + ClassDB::bind_method(D_METHOD("get_snap_to_mesh"), &VoxelmanPropMesh::get_snap_to_mesh); + ClassDB::bind_method(D_METHOD("set_snap_to_mesh", "value"), &VoxelmanPropMesh::set_snap_to_mesh); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "snap_to_mesh"), "set_snap_to_mesh", "get_snap_to_mesh"); + + ClassDB::bind_method(D_METHOD("get_snap_axis"), &VoxelmanPropMesh::get_snap_axis); + ClassDB::bind_method(D_METHOD("set_snap_axis", "value"), &VoxelmanPropMesh::set_snap_axis); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "snap_axis"), "set_snap_axis", "get_snap_axis"); } diff --git a/props/voxelman_prop_mesh.h b/props/voxelman_prop_mesh.h index e99df3d..4d02d26 100644 --- a/props/voxelman_prop_mesh.h +++ b/props/voxelman_prop_mesh.h @@ -2,6 +2,7 @@ #define VOXELMAN_PROP_MESH_H #include "voxelman_prop_entry.h" +#include "core/math/vector3.h" #include "../../entity_spell_system/meshes/mesh_data_resource.h" @@ -12,6 +13,12 @@ public: Ref get_mesh() const; void set_mesh(const Ref mesh); + bool get_snap_to_mesh(); + void set_snap_to_mesh(bool value); + + Vector3 get_snap_axis(); + void set_snap_axis(Vector3 value); + VoxelmanPropMesh(); ~VoxelmanPropMesh(); @@ -19,6 +26,8 @@ protected: static void _bind_methods(); private: + bool _snap_to_mesh; + Vector3 _snap_axis; Ref _mesh; }; diff --git a/props/voxelman_prop_scene.cpp b/props/voxelman_prop_scene.cpp index 53efdfe..9c6416a 100644 --- a/props/voxelman_prop_scene.cpp +++ b/props/voxelman_prop_scene.cpp @@ -7,7 +7,23 @@ void VoxelmanPropScene::set_scene(const Ref value) { _scene = value; } +bool VoxelmanPropScene::get_snap_to_mesh() { + return _snap_to_mesh; +} +void VoxelmanPropScene::set_snap_to_mesh(bool value) { + _snap_to_mesh = value; +} + +Vector3 VoxelmanPropScene::get_snap_axis() { + return _snap_axis; +} +void VoxelmanPropScene::set_snap_axis(Vector3 value) { + _snap_axis = value; +} + VoxelmanPropScene::VoxelmanPropScene() { + _snap_to_mesh = true; + _snap_axis = Vector3(0, 1, 0); } VoxelmanPropScene::~VoxelmanPropScene() { if (_scene.is_valid()) @@ -18,4 +34,12 @@ void VoxelmanPropScene::_bind_methods() { ClassDB::bind_method(D_METHOD("get_scene"), &VoxelmanPropScene::get_scene); ClassDB::bind_method(D_METHOD("set_scene", "value"), &VoxelmanPropScene::set_scene); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "scene", PROPERTY_HINT_RESOURCE_TYPE, "PackedScene"), "set_scene", "get_scene"); + + ClassDB::bind_method(D_METHOD("get_snap_to_mesh"), &VoxelmanPropScene::get_snap_to_mesh); + ClassDB::bind_method(D_METHOD("set_snap_to_mesh", "value"), &VoxelmanPropScene::set_snap_to_mesh); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "snap_to_mesh"), "set_snap_to_mesh", "get_snap_to_mesh"); + + ClassDB::bind_method(D_METHOD("get_snap_axis"), &VoxelmanPropScene::get_snap_axis); + ClassDB::bind_method(D_METHOD("set_snap_axis", "value"), &VoxelmanPropScene::set_snap_axis); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "snap_axis"), "set_snap_axis", "get_snap_axis"); } diff --git a/props/voxelman_prop_scene.h b/props/voxelman_prop_scene.h index b4e1c1b..4b96504 100644 --- a/props/voxelman_prop_scene.h +++ b/props/voxelman_prop_scene.h @@ -2,6 +2,7 @@ #define VOXELMAN_PROP_SCENE_H #include "voxelman_prop_entry.h" +#include "core/math/vector3.h" #include "scene/resources/packed_scene.h" @@ -12,6 +13,12 @@ public: Ref get_scene() const; void set_scene(const Ref value); + bool get_snap_to_mesh(); + void set_snap_to_mesh(bool value); + + Vector3 get_snap_axis(); + void set_snap_axis(Vector3 value); + VoxelmanPropScene(); ~VoxelmanPropScene(); @@ -19,6 +26,8 @@ protected: static void _bind_methods(); private: + bool _snap_to_mesh; + Vector3 _snap_axis; Ref _scene; }; diff --git a/register_types.cpp b/register_types.cpp index ac95b80..f11c161 100644 --- a/register_types.cpp +++ b/register_types.cpp @@ -14,6 +14,7 @@ #include "world/voxel_chunk.h" #include "world/voxel_structure.h" #include "world/environment_data.h" +#include "world/voxel_chunk_prop_data.h" #include "meshers/cubic_mesher/voxel_mesher_cubic.h" #include "meshers/cubic_mesher/voxel_cube_points.h" @@ -42,6 +43,7 @@ void register_voxelman_types() { ClassDB::register_class(); ClassDB::register_class(); ClassDB::register_class(); + ClassDB::register_class(); ClassDB::register_class(); ClassDB::register_class(); diff --git a/world/voxel_chunk.cpp b/world/voxel_chunk.cpp index 0924df7..22bccf8 100644 --- a/world/voxel_chunk.cpp +++ b/world/voxel_chunk.cpp @@ -91,6 +91,13 @@ void VoxelChunk::set_voxel_scale(float value) { } } +int VoxelChunk::get_current_build_phase() { + return _current_build_phase; +} +void VoxelChunk::set_current_build_phase(int value) { + _current_build_phase = value; +} + Ref VoxelChunk::get_mesher() const { return _mesher; } @@ -131,6 +138,32 @@ Ref VoxelChunk::get_buffer() const { return _buffer; } +RID VoxelChunk::get_mesh_rid() { + return _mesh_rid; +} +RID VoxelChunk::get_mesh_instance_rid() { + return _mesh_instance_rid; +} +RID VoxelChunk::get_shape_rid() { + return _shape_rid; +} +RID VoxelChunk::get_body_rid() { + return _body_rid; +} + +RID VoxelChunk::get_prop_mesh_rid() { + return _prop_mesh_rid; +} +RID VoxelChunk::get_prop_mesh_instance_rid() { + return _prop_mesh_instance_rid; +} +RID VoxelChunk::get_prop_shape_rid() { + return _prop_shape_rid; +} +RID VoxelChunk::get_prop_body_rid() { + return _prop_body_rid; +} + void VoxelChunk::create_mesher() { call("_create_mesher"); @@ -155,40 +188,102 @@ void VoxelChunk::finalize_mesh() { } void VoxelChunk::build() { + if (_current_build_phase == BUILD_PHASE_DONE) { + next_phase(); + } +} + +void VoxelChunk::build_phase(int phase) { + call("_build_phase", phase); +} + +void VoxelChunk::_build_phase(int phase) { ERR_FAIL_COND(!_library.is_valid()); - if (!_mesher.is_valid()) { - create_mesher(); - } + switch (phase) { + case BUILD_PHASE_DONE: + return; + case BUILD_PHASE_SETUP: { + if (!_mesher.is_valid()) { + create_mesher(); + } - _mesher->set_library(_library); + _mesher->set_library(_library); - _mesher->reset(); + _mesher->reset(); - if (has_method("_create_mesh")) { - call("_create_mesh"); - } else { - _mesher->add_buffer(_buffer); - } + next_phase(); - finalize_mesh(); + return; + } + case BUILD_PHASE_TERRARIN_MESH: { - if (get_create_collider()) { - build_collider(); - } + if (has_method("_create_mesh")) { + call("_create_mesh"); + } else { + _mesher->add_buffer(_buffer); + } - _mesher->reset(); + finalize_mesh(); - if (_props.size() > 0) { - process_props(); - build_prop_meshes(); + next_phase(); - if (get_create_collider()) { - build_prop_collider(); + return; + } + case BUILD_PHASE_TERRARIN_MESH_COLLIDER: { + + if (get_create_collider()) { + build_collider(); + } + + next_phase(); + + return; + } + case BUILD_PHASE_PROP_MESH: { + + _mesher->reset(); + + if (_props.size() > 0) { + process_props(); + build_prop_meshes(); + } + + next_phase(); + + return; + } + case BUILD_PHASE_PROP_COLLIDER: { + + if (_props.size() > 0) { + if (get_create_collider()) { + build_prop_collider(); + } + } + + _mesher->reset(); + + next_phase(); + + return; } } - _mesher->reset(); + next_phase(); +} + +void VoxelChunk::next_phase() { + ++_current_build_phase; + + if (_current_build_phase >= BUILD_PHASE_MAX) { + _current_build_phase = BUILD_PHASE_DONE; + + emit_signal("mesh_generation_finished", Ref(this)); + + return; + } + + build_phase(_current_build_phase); } void VoxelChunk::clear() { @@ -332,36 +427,18 @@ void VoxelChunk::clear_baked_lights() { _buffer->clear_lights(); } -void VoxelChunk::add_prop_mesh(const Ref mesh, const Vector3 position, const Vector3 rotation, const Vector3 scale) { - VCPropData data; - - data.transform = Transform(Basis(rotation).scaled(scale), position); - - data.mesh = mesh; - - _props.push_back(data); +void VoxelChunk::add_prop(Ref prop) { + _props.push_back(prop); } - -void VoxelChunk::add_prop_spawned(const Ref scene, const Vector3 position, const Vector3 rotation, const Vector3 scale) { - VCPropData data; - - data.transform = Transform(Basis(rotation).scaled(scale), position); - - data.scene = scene; - - _props.push_back(data); +Ref VoxelChunk::get_prop(int index) { + return _props.get(index); } - -void VoxelChunk::add_prop(const Ref prop, const Vector3 position, const Vector3 rotation, const Vector3 scale) { - VCPropData data; - - data.transform = Transform(Basis(rotation).scaled(scale), position); - - data.mesh = prop; - - _props.push_back(data); +int VoxelChunk::get_prop_count() { + return _props.size(); +} +void VoxelChunk::remove_prop(int index) { + return _props.remove(index); } - void VoxelChunk::clear_props() { _props.clear(); } @@ -387,94 +464,20 @@ void VoxelChunk::allocate_prop_mesh() { VS::get_singleton()->instance_set_transform(_prop_mesh_instance_rid, Transform(Basis(), Vector3(_chunk_position.x * _chunk_size.x * _voxel_scale, _chunk_position.y * _chunk_size.y * _voxel_scale, _chunk_position.z * _chunk_size.z * _voxel_scale))); } -void VoxelChunk::process_prop_lights() { - Transform transform(Basis().scaled(Vector3(_voxel_scale, _voxel_scale, _voxel_scale)), Vector3(_chunk_position.x * _chunk_size.x, _chunk_position.y * _chunk_size.y, _chunk_position.z * _chunk_size.z)); - - for (int i = 0; i < _props.size(); ++i) { - VCPropData prop = _props[i]; - - if (prop.prop.is_valid()) { - process_prop_light(prop.prop, transform); - } - } -} - void VoxelChunk::process_props() { + ERR_FAIL_COND(!has_method("_process_props")); + if (_prop_mesh_rid == RID()) { allocate_prop_mesh(); } - for (int i = 0; i < _props.size(); ++i) { - VCPropData prop = _props[i]; - - process_prop(prop.prop, prop.transform); - } + call("_process_props"); _mesher->bake_colors(_buffer); _mesher->build_mesh(_prop_mesh_rid); } -void VoxelChunk::process_prop_light(Ref prop, const Transform transform) { - ERR_FAIL_COND(!prop.is_valid()); - - Transform pt = prop->get_transform(); - - pt = transform * pt; - - Vector3 lp = pt.xform_inv(Vector3()); - - create_voxel_light(prop->get_light_color(), prop->get_light_size(), (int)lp.x, (int)lp.y, (int)lp.z); -} - -void VoxelChunk::process_prop(Ref prop, const Transform transform) { - ERR_FAIL_COND(!prop.is_valid()); - - for (int i = 0; i < prop->get_prop_count(); ++i) { - Ref data = prop->get_prop(i); - - if (!data.is_valid()) - continue; - - Transform pt = data->get_transform(); - - Ref mesh = data; - if (mesh.is_valid()) { - _mesher->add_mesh_data_resource_transform(mesh->get_mesh(), pt); - } - - Ref scene = data; - if (scene.is_valid()) { - spawn_prop(scene->get_scene(), pt); - } - - Ref light = data; - if (light.is_valid()) { - process_prop_light(data, transform); - } - } -} - -void VoxelChunk::spawn_prop(const Ref scene, const Transform transform) { - ERR_FAIL_COND(!scene.is_valid()); - ERR_FAIL_COND(get_voxel_world() == NULL); - - Node *n = scene->instance(); - - ERR_FAIL_COND(n == NULL); - - get_voxel_world()->add_child(n); - n->set_owner(get_voxel_world()); - - _spawned_props.push_back(n); - - Spatial *spatial = Object::cast_to(n); - - ERR_FAIL_COND(spatial == NULL); - - spatial->set_transform(transform); -} - void VoxelChunk::build_prop_meshes() { if (_prop_mesh_rid == RID()) { allocate_prop_mesh(); @@ -586,15 +589,6 @@ void VoxelChunk::free_debug_immediate_geometry() { } } -void VoxelChunk::free_chunk() { - free_debug_immediate_geometry(); - free_main_mesh(); - remove_colliders(); - free_prop_mesh(); - free_prop_colliders(); - free_spawn_props(); -} - void VoxelChunk::draw_cross_voxels(Vector3 pos) { pos *= _voxel_scale; @@ -685,10 +679,20 @@ void VoxelChunk::draw_debug_voxel_lights() { _debug_drawer->end(); } +void VoxelChunk::free_chunk() { + free_debug_immediate_geometry(); + free_main_mesh(); + remove_colliders(); + free_prop_mesh(); + free_prop_colliders(); + free_spawn_props(); +} + VoxelChunk::VoxelChunk() { _build_mesh = true; _create_collider = true; _bake_lights = true; + _current_build_phase = BUILD_PHASE_DONE; _voxel_scale = 1; _lod_size = 1; @@ -717,9 +721,13 @@ VoxelChunk::~VoxelChunk() { if (_library.is_valid()) { _library.unref(); } + + _props.clear(); } void VoxelChunk::_bind_methods() { + ADD_SIGNAL(MethodInfo("mesh_generation_finished", PropertyInfo(Variant::OBJECT, "chunk", PROPERTY_HINT_RESOURCE_TYPE, "VoxelChunk"))); + BIND_VMETHOD(MethodInfo("_create_mesh")); BIND_VMETHOD(MethodInfo("_create_mesher")); @@ -765,6 +773,10 @@ void VoxelChunk::_bind_methods() { ClassDB::bind_method(D_METHOD("set_voxel_scale", "value"), &VoxelChunk::set_voxel_scale); ADD_PROPERTY(PropertyInfo(Variant::REAL, "voxel_scale"), "set_voxel_scale", "get_voxel_scale"); + ClassDB::bind_method(D_METHOD("get_current_build_phase"), &VoxelChunk::get_current_build_phase); + ClassDB::bind_method(D_METHOD("set_current_build_phase", "value"), &VoxelChunk::set_current_build_phase); + ADD_PROPERTY(PropertyInfo(Variant::INT, "current_build_phase"), "set_current_build_phase", "get_current_build_phase"); + ClassDB::bind_method(D_METHOD("get_buffer"), &VoxelChunk::get_buffer); ADD_GROUP("Meshing", "meshing"); @@ -787,9 +799,24 @@ void VoxelChunk::_bind_methods() { ClassDB::bind_method(D_METHOD("set_voxel_world", "world"), &VoxelChunk::set_voxel_world_bind); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "voxel_world", PROPERTY_HINT_RESOURCE_TYPE, "VoxelWorld"), "set_voxel_world", "get_voxel_world"); + ClassDB::bind_method(D_METHOD("get_mesh_rid"), &VoxelChunk::get_mesh_rid); + ClassDB::bind_method(D_METHOD("get_mesh_instance_rid"), &VoxelChunk::get_mesh_instance_rid); + ClassDB::bind_method(D_METHOD("get_shape_rid"), &VoxelChunk::get_shape_rid); + ClassDB::bind_method(D_METHOD("get_body_rid"), &VoxelChunk::get_body_rid); + + ClassDB::bind_method(D_METHOD("get_prop_mesh_rid"), &VoxelChunk::get_prop_mesh_rid); + ClassDB::bind_method(D_METHOD("get_prop_mesh_instance_rid"), &VoxelChunk::get_prop_mesh_instance_rid); + ClassDB::bind_method(D_METHOD("get_prop_shape_rid"), &VoxelChunk::get_prop_shape_rid); + ClassDB::bind_method(D_METHOD("get_prop_body_rid"), &VoxelChunk::get_prop_body_rid); + ClassDB::bind_method(D_METHOD("finalize_mesh"), &VoxelChunk::finalize_mesh); + 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", "phase"), &VoxelChunk::_build_phase); + ClassDB::bind_method(D_METHOD("next_phase"), &VoxelChunk::next_phase); ClassDB::bind_method(D_METHOD("clear"), &VoxelChunk::clear); ClassDB::bind_method(D_METHOD("create_colliders"), &VoxelChunk::create_colliders); @@ -810,16 +837,14 @@ void VoxelChunk::_bind_methods() { ClassDB::bind_method(D_METHOD("bake_light", "light"), &VoxelChunk::bake_light); ClassDB::bind_method(D_METHOD("clear_baked_lights"), &VoxelChunk::clear_baked_lights); - ClassDB::bind_method(D_METHOD("add_prop_mesh", "mesh", "position", "rotation", "scale"), &VoxelChunk::add_prop_mesh, DEFVAL(Vector3()), DEFVAL(Vector3()), DEFVAL(Vector3(1.0, 1.0, 1.0))); - ClassDB::bind_method(D_METHOD("add_prop_spawned", "scene", "position", "rotation", "scale"), &VoxelChunk::add_prop_spawned, DEFVAL(Vector3()), DEFVAL(Vector3()), DEFVAL(Vector3(1.0, 1.0, 1.0))); - ClassDB::bind_method(D_METHOD("add_prop", "prop", "position", "rotation", "scale"), &VoxelChunk::add_prop, DEFVAL(Vector3()), DEFVAL(Vector3()), DEFVAL(Vector3(1.0, 1.0, 1.0))); + ClassDB::bind_method(D_METHOD("add_prop", "prop"), &VoxelChunk::add_prop); + ClassDB::bind_method(D_METHOD("get_prop", "index"), &VoxelChunk::get_prop); + ClassDB::bind_method(D_METHOD("get_prop_count"), &VoxelChunk::get_prop_count); + ClassDB::bind_method(D_METHOD("remove_prop", "index"), &VoxelChunk::remove_prop); ClassDB::bind_method(D_METHOD("clear_props"), &VoxelChunk::clear_props); - ClassDB::bind_method(D_METHOD("process_prop_lights"), &VoxelChunk::process_prop_lights); + BIND_VMETHOD(MethodInfo("_process_props")); ClassDB::bind_method(D_METHOD("process_props"), &VoxelChunk::process_props); - ClassDB::bind_method(D_METHOD("process_prop", "prop", "transform"), &VoxelChunk::process_prop, DEFVAL(Transform())); - ClassDB::bind_method(D_METHOD("process_prop_light", "prop", "transform"), &VoxelChunk::process_prop_light, DEFVAL(Transform())); - ClassDB::bind_method(D_METHOD("spawn_prop", "transform"), &VoxelChunk::spawn_prop, DEFVAL(Transform())); ClassDB::bind_method(D_METHOD("build_prop_meshes"), &VoxelChunk::build_prop_meshes); ClassDB::bind_method(D_METHOD("build_prop_collider"), &VoxelChunk::build_prop_collider); @@ -846,4 +871,12 @@ void VoxelChunk::_bind_methods() { ClassDB::bind_method(D_METHOD("draw_debug_voxels", "pos", "color"), &VoxelChunk::draw_debug_voxels, DEFVAL(Color(1, 1, 1))); ClassDB::bind_method(D_METHOD("draw_debug_voxel_lights"), &VoxelChunk::draw_debug_voxel_lights); + + BIND_CONSTANT(BUILD_PHASE_DONE); + BIND_CONSTANT(BUILD_PHASE_SETUP); + BIND_CONSTANT(BUILD_PHASE_TERRARIN_MESH); + BIND_CONSTANT(BUILD_PHASE_TERRARIN_MESH_COLLIDER); + BIND_CONSTANT(BUILD_PHASE_PROP_MESH); + BIND_CONSTANT(BUILD_PHASE_PROP_COLLIDER); + BIND_CONSTANT(BUILD_PHASE_MAX); } diff --git a/world/voxel_chunk.h b/world/voxel_chunk.h index 1d57bab..cce8d52 100644 --- a/world/voxel_chunk.h +++ b/world/voxel_chunk.h @@ -31,6 +31,7 @@ #include "../props/voxelman_prop_scene.h" #include "../props/voxelman_prop_mesh.h" #include "../props/voxelman_prop_light.h" +#include "voxel_chunk_prop_data.h" class VoxelWorld; @@ -38,6 +39,7 @@ class VoxelChunk : public Reference { GDCLASS(VoxelChunk, Reference); public: + //Properties int get_chunk_position_x(); void set_chunk_position_x(int value); int get_chunk_position_y(); @@ -67,6 +69,9 @@ public: float get_voxel_scale() const; void set_voxel_scale(float value); + int get_current_build_phase(); + void set_current_build_phase(int value); + Ref get_mesher() const; void set_mesher(Ref mesher); @@ -82,18 +87,35 @@ public: Ref get_buffer() const; + RID get_mesh_rid(); + RID get_mesh_instance_rid(); + RID get_shape_rid(); + RID get_body_rid(); + + RID get_prop_mesh_rid(); + RID get_prop_mesh_instance_rid(); + RID get_prop_shape_rid(); + RID get_prop_body_rid(); + + //Meshing void create_mesher(); void _create_mesher(); void finalize_mesh(); void build(); + void build_phase(int phase); + void _build_phase(int phase); + void next_phase(); + void clear(); + //Colliders void create_colliders(); void build_collider(); void remove_colliders(); + //lights void add_lights(Array lights); void add_voxel_light(Ref light); void create_voxel_light(const Color color, const int size, const int x, const int y, const int z); @@ -107,22 +129,21 @@ public: void bake_lights(); void bake_light(Ref light); void clear_baked_lights(); - - void add_prop_mesh(const Ref mesh, const Vector3 position = Vector3(), const Vector3 rotation = Vector3(), const Vector3 scale = Vector3(1.0, 1.0, 1.0)); - void add_prop_spawned(const Ref scene, const Vector3 position = Vector3(), const Vector3 rotation = Vector3(), const Vector3 scale = Vector3(1.0, 1.0, 1.0)); - void add_prop(const Ref prop, const Vector3 position = Vector3(), const Vector3 rotation = Vector3(), const Vector3 scale = Vector3(1.0, 1.0, 1.0)); + + //props + void add_prop(Ref prop); + Ref get_prop(int index); + int get_prop_count(); + void remove_prop(int index); void clear_props(); - void process_prop_lights(); void process_props(); - void process_prop(Ref prop, const Transform transform = Transform()); - void process_prop_light(Ref prop, const Transform transform = Transform()); - void spawn_prop(const Ref scene, const Transform transform = Transform()); void build_prop_meshes(); void build_prop_collider(); void free_spawn_props(); + //Meshes void allocate_main_mesh(); void free_main_mesh(); @@ -131,32 +152,36 @@ public: void allocate_prop_colliders(); void free_prop_colliders(); - + + //Debug void create_debug_immediate_geometry(); void free_debug_immediate_geometry(); - void free_chunk(); - void draw_cross_voxels(Vector3 pos); void draw_cross_voxels_fill(Vector3 pos, float fill); void draw_debug_voxels(int max, Color color = Color(1, 1, 1)); void draw_debug_voxel_lights(); + //free + void free_chunk(); + VoxelChunk(); ~VoxelChunk(); -protected: - struct VCPropData { - Transform transform; - - Ref mesh; - Ref prop; - Ref scene; +public: + enum { + BUILD_PHASE_DONE = 0, + BUILD_PHASE_SETUP = 1, + BUILD_PHASE_TERRARIN_MESH = 2, + BUILD_PHASE_TERRARIN_MESH_COLLIDER = 3, + BUILD_PHASE_PROP_MESH = 4, + BUILD_PHASE_PROP_COLLIDER = 5, + BUILD_PHASE_MAX = 6 }; - + protected: static void _bind_methods(); - + int _current_build_phase; bool _enabled; VoxelWorld *_voxel_world; @@ -183,7 +208,7 @@ protected: Ref _mesher; //mergeable props - Vector _props; + Vector > _props; RID _prop_mesh_rid; RID _prop_mesh_instance_rid; diff --git a/world/voxel_chunk_prop_data.cpp b/world/voxel_chunk_prop_data.cpp new file mode 100644 index 0000000..db2374b --- /dev/null +++ b/world/voxel_chunk_prop_data.cpp @@ -0,0 +1,138 @@ +#include "voxel_chunk_prop_data.h" + +int VoxelChunkPropData::get_x() { + return _x; +} +void VoxelChunkPropData::set_x(int value) { + _x = value; +} + +int VoxelChunkPropData::get_y() { + return _y; +} +void VoxelChunkPropData::set_y(int value) { + _y = value; +} + +int VoxelChunkPropData::get_z() { + return _z; +} +void VoxelChunkPropData::set_z(int value) { + _z = value; +} + +Vector3 VoxelChunkPropData::get_rotation() { + return _rotation; +} +void VoxelChunkPropData::set_rotation(Vector3 value) { + _rotation = value; +} + +Vector3 VoxelChunkPropData::get_scale() { + return _scale; +} +void VoxelChunkPropData::set_scale(Vector3 value) { + _scale = value; +} + +bool VoxelChunkPropData::get_snap_to_mesh() { + return _snap_to_mesh; +} +void VoxelChunkPropData::set_snap_to_mesh(bool value) { + _snap_to_mesh = value; +} + +Vector3 VoxelChunkPropData::get_snap_axis() { + return _snap_axis; +} +void VoxelChunkPropData::set_snap_axis(Vector3 value) { + _snap_axis = value; +} + +Ref VoxelChunkPropData::get_mesh() const { + return _mesh; +} +void VoxelChunkPropData::set_mesh(const Ref value) { + _mesh = value; +} + +Ref VoxelChunkPropData::get_light() const { + return _light; +} +void VoxelChunkPropData::set_light(const Ref value) { + _light = value; +} + +Ref VoxelChunkPropData::get_prop() const { + return _prop; +} +void VoxelChunkPropData::set_prop(const Ref value) { + _prop = value; +} + +Ref VoxelChunkPropData::get_scene() const { + return _scene; +} +void VoxelChunkPropData::set_scene(const Ref value) { + _scene = value; +} + +VoxelChunkPropData::VoxelChunkPropData() { + _x = 0; + _y = 0; + _z = 0; + _scale = Vector3(1, 1, 1); + _snap_to_mesh = false; +} +VoxelChunkPropData::~VoxelChunkPropData() { + _mesh.unref(); + _light.unref(); + _prop.unref(); + _scene.unref(); +} + +void VoxelChunkPropData::_bind_methods() { + ClassDB::bind_method(D_METHOD("get_x"), &VoxelChunkPropData::get_x); + ClassDB::bind_method(D_METHOD("set_x", "value"), &VoxelChunkPropData::set_x); + ADD_PROPERTY(PropertyInfo(Variant::INT, "x"), "set_x", "get_x"); + + ClassDB::bind_method(D_METHOD("get_y"), &VoxelChunkPropData::get_y); + ClassDB::bind_method(D_METHOD("set_y", "value"), &VoxelChunkPropData::set_y); + ADD_PROPERTY(PropertyInfo(Variant::INT, "y"), "set_y", "get_y"); + + ClassDB::bind_method(D_METHOD("get_z"), &VoxelChunkPropData::get_z); + ClassDB::bind_method(D_METHOD("set_z", "value"), &VoxelChunkPropData::set_z); + ADD_PROPERTY(PropertyInfo(Variant::INT, "z"), "set_z", "get_z"); + + ClassDB::bind_method(D_METHOD("get_rotation"), &VoxelChunkPropData::get_rotation); + ClassDB::bind_method(D_METHOD("set_rotation", "value"), &VoxelChunkPropData::set_rotation); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "rotation"), "set_rotation", "get_rotation"); + + ClassDB::bind_method(D_METHOD("get_scale"), &VoxelChunkPropData::get_scale); + ClassDB::bind_method(D_METHOD("set_scale", "value"), &VoxelChunkPropData::set_scale); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "scale"), "set_scale", "get_scale"); + + ClassDB::bind_method(D_METHOD("get_snap_to_mesh"), &VoxelChunkPropData::get_snap_to_mesh); + ClassDB::bind_method(D_METHOD("set_snap_to_mesh", "value"), &VoxelChunkPropData::set_snap_to_mesh); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "snap_to_mesh"), "set_snap_to_mesh", "get_snap_to_mesh"); + + ClassDB::bind_method(D_METHOD("get_snap_axis"), &VoxelChunkPropData::get_snap_axis); + ClassDB::bind_method(D_METHOD("set_snap_axis", "value"), &VoxelChunkPropData::set_snap_axis); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "snap_axis"), "set_snap_axis", "get_snap_axis"); + + ClassDB::bind_method(D_METHOD("get_mesh"), &VoxelChunkPropData::get_mesh); + ClassDB::bind_method(D_METHOD("set_mesh", "value"), &VoxelChunkPropData::set_scene); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "mesh", PROPERTY_HINT_RESOURCE_TYPE, "MeshDataResource"), "set_mesh", "get_mesh"); + + ClassDB::bind_method(D_METHOD("get_light"), &VoxelChunkPropData::get_light); + ClassDB::bind_method(D_METHOD("set_light", "value"), &VoxelChunkPropData::set_scene); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "light", PROPERTY_HINT_RESOURCE_TYPE, "VoxelmanPropLight"), "set_light", "get_light"); + + ClassDB::bind_method(D_METHOD("get_prop"), &VoxelChunkPropData::get_prop); + ClassDB::bind_method(D_METHOD("set_prop", "value"), &VoxelChunkPropData::set_prop); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "prop", PROPERTY_HINT_RESOURCE_TYPE, "VoxelmanProp"), "set_prop", "get_prop"); + + ClassDB::bind_method(D_METHOD("get_scene"), &VoxelChunkPropData::get_scene); + ClassDB::bind_method(D_METHOD("set_scene", "value"), &VoxelChunkPropData::set_scene); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "scene", PROPERTY_HINT_RESOURCE_TYPE, "PackedScene"), "set_scene", "get_scene"); +} diff --git a/world/voxel_chunk_prop_data.h b/world/voxel_chunk_prop_data.h new file mode 100644 index 0000000..0f0d1ff --- /dev/null +++ b/world/voxel_chunk_prop_data.h @@ -0,0 +1,71 @@ +#ifndef VOXEL_CHUNK_PROP_DATA_H +#define VOXEL_CHUNK_PROP_DATA_H + +#include "core/reference.h" +#include "core/math/vector3.h" + +#include "scene/resources/packed_scene.h" +#include "../props/voxelman_prop.h" +#include "../props/voxelman_prop_light.h" +#include "../../entity_spell_system/meshes/mesh_data_resource.h" + +class VoxelChunkPropData : public Reference { + GDCLASS(VoxelChunkPropData, Reference); + +public: + int get_x(); + void set_x(int value); + + int get_y(); + void set_y(int value); + + int get_z(); + void set_z(int value); + + Vector3 get_rotation(); + void set_rotation(Vector3 value); + + Vector3 get_scale(); + void set_scale(Vector3 value); + + bool get_snap_to_mesh(); + void set_snap_to_mesh(bool value); + + Vector3 get_snap_axis(); + void set_snap_axis(Vector3 value); + + Ref get_mesh() const; + void set_mesh(const Ref value); + + Ref get_light() const; + void set_light(const Ref value); + + Ref get_prop() const; + void set_prop(const Ref value); + + Ref get_scene() const; + void set_scene(const Ref value); + + VoxelChunkPropData(); + ~VoxelChunkPropData(); + +protected: + static void _bind_methods(); + +private: + int _x; + int _y; + int _z; + Vector3 _rotation; + Vector3 _scale; + + bool _snap_to_mesh; + Vector3 _snap_axis; + + Ref _mesh; + Ref _light; + Ref _prop; + Ref _scene; +}; + +#endif