From e0deb2ea6611af25b08862be07985eb351772cc5 Mon Sep 17 00:00:00 2001 From: Relintai Date: Sun, 10 Nov 2019 13:42:59 +0100 Subject: [PATCH] Added liquid, and clutter mesh allocations into Chunk, also related modifications. --- clutter/ground_clutter.cpp | 41 +++++- clutter/ground_clutter.h | 13 ++ library/voxel_surface.h | 1 + library/voxelman_library.cpp | 46 ++++++- library/voxelman_library.h | 16 ++- library/voxelman_library_merger.cpp | 8 +- meshers/voxel_mesher.cpp | 76 +++++++++- meshers/voxel_mesher.h | 6 +- world/voxel_chunk.cpp | 207 ++++++++++++++++++++-------- world/voxel_chunk.h | 23 +++- 10 files changed, 362 insertions(+), 75 deletions(-) diff --git a/clutter/ground_clutter.cpp b/clutter/ground_clutter.cpp index b698e14..b99dae9 100644 --- a/clutter/ground_clutter.cpp +++ b/clutter/ground_clutter.cpp @@ -1,5 +1,38 @@ #include "ground_clutter.h" +#include "../world/voxel_chunk.h" + +bool GroundClutter::should_spawn(VoxelChunk *chunk, int x, int y, int z) { + if (has_method("_should_spawn")) + return call("_should_spawn", chunk, x, y, z); + + return false; +} +bool GroundClutter::should_spawn_bind(Node *chunk, int x, int y, int z) { + VoxelChunk *c = Object::cast_to(chunk); + + ERR_FAIL_COND_V(!ObjectDB::instance_validate(c), false); + + return should_spawn(c, x, y, z); +} + +void GroundClutter::add_meshes_to(Ref mesher, VoxelChunk *chunk, int x, int y, int z) { + if (has_method("_add_meshes_to")) + call("_add_meshes_to", mesher, chunk, x, y, z); +} +void GroundClutter::add_meshes_to_bind(Ref mesher, Node *chunk, int x, int y, int z) { + VoxelChunk *c = Object::cast_to(chunk); + + ERR_FAIL_COND(!ObjectDB::instance_validate(c)); + + add_meshes_to(mesher, c, x, y, z); +} + +void GroundClutter::add_textures_to(Ref packer) { + if (has_method("_add_textures_to")) + call("_add_textures_to", packer); +} + GroundClutter::GroundClutter() { } @@ -7,7 +40,11 @@ GroundClutter::~GroundClutter() { } void GroundClutter::_bind_methods() { - BIND_VMETHOD(MethodInfo(PropertyInfo(Variant::BOOL, "should"), "_should_spawn", PropertyInfo(Variant::OBJECT, "buffer", PROPERTY_HINT_RESOURCE_TYPE, "VoxelChunk"), PropertyInfo(Variant::INT, "x"), PropertyInfo(Variant::INT, "y"), PropertyInfo(Variant::INT, "z"))); - BIND_VMETHOD(MethodInfo("_add_meshes_to", PropertyInfo(Variant::OBJECT, "mesher", PROPERTY_HINT_RESOURCE_TYPE, "VoxelMesher"), PropertyInfo(Variant::INT, "x"), PropertyInfo(Variant::INT, "y"), PropertyInfo(Variant::INT, "z"))); + BIND_VMETHOD(MethodInfo(PropertyInfo(Variant::BOOL, "should"), "_should_spawn", PropertyInfo(Variant::OBJECT, "chunk", PROPERTY_HINT_RESOURCE_TYPE, "VoxelChunk"), PropertyInfo(Variant::INT, "x"), PropertyInfo(Variant::INT, "y"), PropertyInfo(Variant::INT, "z"))); + BIND_VMETHOD(MethodInfo("_add_meshes_to", PropertyInfo(Variant::OBJECT, "mesher", PROPERTY_HINT_RESOURCE_TYPE, "VoxelMesher"), PropertyInfo(Variant::OBJECT, "chunk", PROPERTY_HINT_RESOURCE_TYPE, "VoxelChunk"), PropertyInfo(Variant::INT, "x"), PropertyInfo(Variant::INT, "y"), PropertyInfo(Variant::INT, "z"))); BIND_VMETHOD(MethodInfo("_add_textures_to", PropertyInfo(Variant::OBJECT, "packer", PROPERTY_HINT_RESOURCE_TYPE, "TexturePacker"))); + + ClassDB::bind_method(D_METHOD("should_spawn", "chunk", "x", "y", "z"), &GroundClutter::should_spawn_bind); + ClassDB::bind_method(D_METHOD("add_meshes_to", "mesher", "chunk", "x", "y", "z"), &GroundClutter::add_meshes_to_bind); + ClassDB::bind_method(D_METHOD("add_textures_to", "packer"), &GroundClutter::add_textures_to); } diff --git a/clutter/ground_clutter.h b/clutter/ground_clutter.h index 0af0e6c..7fe3601 100644 --- a/clutter/ground_clutter.h +++ b/clutter/ground_clutter.h @@ -3,10 +3,23 @@ #include "core/resource.h" +#include "../meshers/voxel_mesher.h" +#include "../../texture_packer/texture_packer.h" + +class VoxelChunk; +class VoxelMesher; + class GroundClutter : public Resource { GDCLASS(GroundClutter, Resource); public: + bool should_spawn(VoxelChunk *chunk, int x, int y, int z); + bool should_spawn_bind(Node *chunk, int x, int y, int z); + + void add_meshes_to(Ref mesher, VoxelChunk *chunk, int x, int y, int z); + void add_meshes_to_bind(Ref mesher, Node *chunk, int x, int y, int z); + void add_textures_to(Ref packer); + GroundClutter(); ~GroundClutter(); diff --git a/library/voxel_surface.h b/library/voxel_surface.h index 5055151..5726440 100644 --- a/library/voxel_surface.h +++ b/library/voxel_surface.h @@ -12,6 +12,7 @@ #include "../clutter/ground_clutter.h" class VoxelmanLibrary; +class GroundClutter; class VoxelSurface : public Resource { GDCLASS(VoxelSurface, Resource) diff --git a/library/voxelman_library.cpp b/library/voxelman_library.cpp index 6e47984..5309b9e 100644 --- a/library/voxelman_library.cpp +++ b/library/voxelman_library.cpp @@ -1,11 +1,31 @@ #include "voxelman_library.h" -VoxelmanLibrary::VoxelmanLibrary() { +Ref VoxelmanLibrary::get_material() const { + return _material; +} +void VoxelmanLibrary::set_material(Ref mat) { + _material = mat; } -VoxelmanLibrary::~VoxelmanLibrary() { - _material.unref(); - _prop_material.unref(); +Ref VoxelmanLibrary::get_prop_material() const { + return _prop_material; +} +void VoxelmanLibrary::set_prop_material(Ref mat) { + _prop_material = mat; +} + +Ref VoxelmanLibrary::get_liquid_material() const { + return _liquid_material; +} +void VoxelmanLibrary::set_liquid_material(Ref mat) { + _liquid_material = mat; +} + +Ref VoxelmanLibrary::get_clutter_material() const { + return _clutter_material; +} +void VoxelmanLibrary::set_clutter_material(Ref mat) { + _clutter_material = mat; } //Surfaces @@ -40,6 +60,16 @@ void VoxelmanLibrary::clear_liquid_surfaces() { void VoxelmanLibrary::refresh_rects() { } +VoxelmanLibrary::VoxelmanLibrary() { +} + +VoxelmanLibrary::~VoxelmanLibrary() { + _material.unref(); + _prop_material.unref(); + _liquid_material.unref(); + _clutter_material.unref(); +} + void VoxelmanLibrary::_bind_methods() { ClassDB::bind_method(D_METHOD("get_material"), &VoxelmanLibrary::get_material); ClassDB::bind_method(D_METHOD("set_material", "value"), &VoxelmanLibrary::set_material); @@ -49,6 +79,14 @@ void VoxelmanLibrary::_bind_methods() { ClassDB::bind_method(D_METHOD("set_prop_material", "value"), &VoxelmanLibrary::set_prop_material); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "prop_material", PROPERTY_HINT_RESOURCE_TYPE, "Material"), "set_prop_material", "get_prop_material"); + ClassDB::bind_method(D_METHOD("get_liquid_material"), &VoxelmanLibrary::get_liquid_material); + ClassDB::bind_method(D_METHOD("set_liquid_material", "value"), &VoxelmanLibrary::set_liquid_material); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "liquid_material", PROPERTY_HINT_RESOURCE_TYPE, "Material"), "set_liquid_material", "get_liquid_material"); + + ClassDB::bind_method(D_METHOD("get_clutter_material"), &VoxelmanLibrary::get_clutter_material); + ClassDB::bind_method(D_METHOD("set_clutter_material", "value"), &VoxelmanLibrary::set_clutter_material); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "clutter_material", PROPERTY_HINT_RESOURCE_TYPE, "Material"), "set_clutter_material", "get_clutter_material"); + ClassDB::bind_method(D_METHOD("get_voxel_surface", "index"), &VoxelmanLibrary::get_voxel_surface); ClassDB::bind_method(D_METHOD("set_voxel_surface", "index", "surface"), &VoxelmanLibrary::set_voxel_surface); ClassDB::bind_method(D_METHOD("remove_surface", "index"), &VoxelmanLibrary::remove_surface); diff --git a/library/voxelman_library.h b/library/voxelman_library.h index 89b1195..e60d6db 100644 --- a/library/voxelman_library.h +++ b/library/voxelman_library.h @@ -14,11 +14,17 @@ class VoxelmanLibrary : public Resource { GDCLASS(VoxelmanLibrary, Resource) public: - Ref get_material() const { return _material; } - void set_material(Ref mat) { _material = mat; } + Ref get_material() const; + void set_material(Ref mat); - Ref get_prop_material() const { return _prop_material; } - void set_prop_material(Ref mat) { _prop_material = mat; } + Ref get_prop_material() const; + void set_prop_material(Ref mat); + + Ref get_liquid_material() const; + void set_liquid_material(Ref mat); + + Ref get_clutter_material() const; + void set_clutter_material(Ref mat); virtual Ref get_voxel_surface(int index) const; virtual void set_voxel_surface(int index, Ref value); @@ -43,6 +49,8 @@ protected: private: Ref _material; Ref _prop_material; + Ref _liquid_material; + Ref _clutter_material; }; #endif // VOXEL_LIBRARY_H diff --git a/library/voxelman_library_merger.cpp b/library/voxelman_library_merger.cpp index 94c1268..079c5ce 100644 --- a/library/voxelman_library_merger.cpp +++ b/library/voxelman_library_merger.cpp @@ -183,7 +183,6 @@ void VoxelmanLibraryMerger::set_liquid_voxel_surfaces(const Vector &sur } } - void VoxelmanLibraryMerger::refresh_rects() { bool texture_added = false; for (int i = 0; i < _voxel_surfaces.size(); i++) { @@ -203,6 +202,12 @@ void VoxelmanLibraryMerger::refresh_rects() { surface->set_region(static_cast(j), _packer->get_texture(tex)); } } + + Ref gc = surface->get_clutter(); + + if (gc.is_valid()) { + gc->add_textures_to(_packer); + } } } @@ -286,6 +291,7 @@ VoxelmanLibraryMerger::~VoxelmanLibraryMerger() { _liquid_surfaces.clear(); + _packer->clear(); _packer.unref(); } diff --git a/meshers/voxel_mesher.cpp b/meshers/voxel_mesher.cpp index 99a74d6..38eb37e 100644 --- a/meshers/voxel_mesher.cpp +++ b/meshers/voxel_mesher.cpp @@ -119,6 +119,12 @@ void VoxelMesher::add_buffer(Ref voxels) { call("_add_buffer", voxels); } +void VoxelMesher::add_buffer_liquid(Ref voxels) { + ERR_FAIL_COND(!has_method("_add_buffer_liquid")); + + call("_add_buffer_liquid", voxels); +} + void VoxelMesher::add_mesh_data_resource(Ref mesh, const Vector3 position, const Vector3 rotation, const Vector3 scale, const Rect2 uv_rect) { Transform transform = Transform(Basis(rotation).scaled(scale), position); @@ -252,16 +258,69 @@ void VoxelMesher::bake_colors(Ref voxels) { if (has_method("_bake_colors")) call("_bake_colors", voxels); } - void VoxelMesher::_bake_colors(Ref buffer) { Color base_light(_base_light_value, _base_light_value, _base_light_value); ERR_FAIL_COND(_vertices.size() != _normals.size()); - /* - if (_vertices.size() != _normals.size()) { - print_error("VoxelMesherCubic: Generating normals!"); - }*/ + for (int i = 0; i < _vertices.size(); ++i) { + Vector3 vert = _vertices[i]; + + if (vert.x < 0 || vert.y < 0 || vert.z < 0) { + if (_colors.size() < _vertices.size()) { + _colors.push_back(base_light); + } + + continue; + } + + unsigned int x = (unsigned int)(vert.x / _voxel_scale); + unsigned int y = (unsigned int)(vert.y / _voxel_scale); + unsigned int z = (unsigned int)(vert.z / _voxel_scale); + + if (buffer->validate_pos(x, y, z)) { + Color light = Color( + buffer->get_voxel(x, y, z, VoxelBuffer::CHANNEL_LIGHT_COLOR_R) / 255.0, + buffer->get_voxel(x, y, z, VoxelBuffer::CHANNEL_LIGHT_COLOR_G) / 255.0, + buffer->get_voxel(x, y, z, VoxelBuffer::CHANNEL_LIGHT_COLOR_B) / 255.0); + + float ao = (buffer->get_voxel(x, y, z, VoxelBuffer::CHANNEL_AO) / 255.0) * _ao_strength; + float rao = buffer->get_voxel(x, y, z, VoxelBuffer::CHANNEL_RANDOM_AO) / 255.0; + ao += rao; + + light.r += _base_light_value; + light.g += _base_light_value; + light.b += _base_light_value; + + light.r -= ao; + light.g -= ao; + light.b -= ao; + + light.r = CLAMP(light.r, 0, 1.0); + light.g = CLAMP(light.g, 0, 1.0); + light.b = CLAMP(light.b, 0, 1.0); + + if (_colors.size() < _vertices.size()) { + _colors.push_back(light); + } else { + _colors.set(i, light); + } + } else { + if (_colors.size() < _vertices.size()) { + _colors.push_back(base_light); + } + } + } +} + +void VoxelMesher::bake_liquid_colors(Ref voxels) { + if (has_method("_bake_liquid_colors")) + call("_bake_liquid_colors", voxels); +} +void VoxelMesher::_bake_liquid_colors(Ref buffer) { + Color base_light(_base_light_value, _base_light_value, _base_light_value); + + ERR_FAIL_COND(_vertices.size() != _normals.size()); for (int i = 0; i < _vertices.size(); ++i) { Vector3 vert = _vertices[i]; @@ -572,7 +631,9 @@ VoxelMesher::~VoxelMesher() { void VoxelMesher::_bind_methods() { BIND_VMETHOD(MethodInfo("_add_buffer", PropertyInfo(Variant::OBJECT, "buffer", PROPERTY_HINT_RESOURCE_TYPE, "VoxelBuffer"))); + BIND_VMETHOD(MethodInfo("_add_buffer_liquid", PropertyInfo(Variant::OBJECT, "buffer", PROPERTY_HINT_RESOURCE_TYPE, "VoxelBuffer"))); BIND_VMETHOD(MethodInfo("_bake_colors", PropertyInfo(Variant::OBJECT, "buffer", PROPERTY_HINT_RESOURCE_TYPE, "VoxelBuffer"))); + BIND_VMETHOD(MethodInfo("_bake_liquid_colors", PropertyInfo(Variant::OBJECT, "buffer", PROPERTY_HINT_RESOURCE_TYPE, "VoxelBuffer"))); ClassDB::bind_method(D_METHOD("get_library"), &VoxelMesher::get_library); ClassDB::bind_method(D_METHOD("set_library", "value"), &VoxelMesher::set_library); @@ -605,10 +666,13 @@ void VoxelMesher::_bind_methods() { ClassDB::bind_method(D_METHOD("add_buffer", "buffer"), &VoxelMesher::add_buffer); ClassDB::bind_method(D_METHOD("add_mesh_data_resource", "mesh", "position", "rotation", "scale", "uv_rect"), &VoxelMesher::add_mesh_data_resource, DEFVAL(Rect2(0, 0, 1, 1)), DEFVAL(Vector3(1.0, 1.0, 1.0)), DEFVAL(Vector3()), DEFVAL(Vector3())); ClassDB::bind_method(D_METHOD("add_mesh_data_resource_transform", "mesh", "transform", "uv_rect"), &VoxelMesher::add_mesh_data_resource_transform, DEFVAL(Rect2(0, 0, 1, 1))); - ClassDB::bind_method(D_METHOD("bake_colors", "buffer"), &VoxelMesher::bake_colors); + ClassDB::bind_method(D_METHOD("bake_colors", "buffer"), &VoxelMesher::bake_colors); ClassDB::bind_method(D_METHOD("_bake_colors", "buffer"), &VoxelMesher::_bake_colors); + ClassDB::bind_method(D_METHOD("bake_liquid_colors", "buffer"), &VoxelMesher::bake_liquid_colors); + ClassDB::bind_method(D_METHOD("_bake_liquid_colors", "buffer"), &VoxelMesher::_bake_liquid_colors); + ClassDB::bind_method(D_METHOD("get_vertex_count"), &VoxelMesher::get_vertex_count); ClassDB::bind_method(D_METHOD("get_vertex", "idx"), &VoxelMesher::get_vertex); ClassDB::bind_method(D_METHOD("remove_vertex", "idx"), &VoxelMesher::remove_vertex); diff --git a/meshers/voxel_mesher.h b/meshers/voxel_mesher.h index 405e3cd..3b747f3 100644 --- a/meshers/voxel_mesher.h +++ b/meshers/voxel_mesher.h @@ -55,12 +55,16 @@ public: void reset(); void add_buffer(Ref voxels); + void add_buffer_liquid(Ref voxels); void add_mesh_data_resource(Ref mesh, const Vector3 position = Vector3(0, 0, 0), const Vector3 rotation = Vector3(0, 0, 0), const Vector3 scale = Vector3(1.0, 1.0, 1.0), const Rect2 uv_rect = Rect2(0, 0, 1, 1)); void add_mesh_data_resource_transform(Ref mesh, const Transform transform, const Rect2 uv_rect = Rect2(0, 0, 1, 1)); - void bake_colors(Ref voxels); + void bake_colors(Ref voxels); void _bake_colors(Ref buffer); + void bake_liquid_colors(Ref voxels); + void _bake_liquid_colors(Ref buffer); + void build_collider(RID shape) const; void bake_lights(MeshInstance *node, Vector > &lights); diff --git a/world/voxel_chunk.cpp b/world/voxel_chunk.cpp index 51a6a79..61697f4 100644 --- a/world/voxel_chunk.cpp +++ b/world/voxel_chunk.cpp @@ -178,6 +178,20 @@ RID VoxelChunk::get_prop_body_rid() { return _prop_body_rid; } +RID VoxelChunk::get_liquid_mesh_rid() { + return _liquid_mesh_rid; +} +RID VoxelChunk::get_liquid_mesh_instance_rid() { + return _liquid_mesh_instance_rid; +} + +RID VoxelChunk::get_clutter_mesh_rid() { + return _clutter_mesh_rid; +} +RID VoxelChunk::get_clutter_mesh_instance_rid() { + return _clutter_mesh_instance_rid; +} + void VoxelChunk::create_mesher() { call("_create_mesher"); @@ -449,7 +463,7 @@ void VoxelChunk::clear_baked_lights() { } void VoxelChunk::add_prop_light(Ref light) { - bake_light(light); + bake_light(light); } void VoxelChunk::add_prop(Ref prop) { @@ -471,27 +485,6 @@ void VoxelChunk::clear_props() { _props.clear(); } -void VoxelChunk::allocate_prop_mesh() { - ERR_FAIL_COND(_voxel_world == NULL); - ERR_FAIL_COND(!get_library().is_valid()); - ERR_FAIL_COND(!get_library()->get_prop_material().is_valid()); - - _prop_mesh_instance_rid = VS::get_singleton()->instance_create(); - - if (get_library()->get_prop_material().is_valid()) { - VS::get_singleton()->instance_geometry_set_material_override(_prop_mesh_instance_rid, get_library()->get_prop_material()->get_rid()); - } - - if (get_voxel_world()->get_world().is_valid()) - VS::get_singleton()->instance_set_scenario(_prop_mesh_instance_rid, get_voxel_world()->get_world()->get_scenario()); - - _prop_mesh_rid = VS::get_singleton()->mesh_create(); - - VS::get_singleton()->instance_set_base(_prop_mesh_instance_rid, _prop_mesh_rid); - - 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_props() { ERR_FAIL_COND(!has_method("_process_props")); @@ -516,6 +509,60 @@ void VoxelChunk::build_prop_meshes() { _mesher->build_mesh(_prop_mesh_rid); } +void VoxelChunk::allocate_main_mesh() { + ERR_FAIL_COND(_voxel_world == NULL); + + ERR_FAIL_COND(!get_library().is_valid()); + ERR_FAIL_COND(!get_library()->get_material().is_valid()); + + _mesh_instance_rid = VS::get_singleton()->instance_create(); + + if (get_library()->get_material().is_valid()) { + VS::get_singleton()->instance_geometry_set_material_override(_mesh_instance_rid, get_library()->get_material()->get_rid()); + } + + if (get_voxel_world()->get_world().is_valid()) + VS::get_singleton()->instance_set_scenario(_mesh_instance_rid, get_voxel_world()->get_world()->get_scenario()); + + _mesh_rid = VS::get_singleton()->mesh_create(); + + VS::get_singleton()->instance_set_base(_mesh_instance_rid, _mesh_rid); + + VS::get_singleton()->instance_set_transform(_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::free_main_mesh() { + if (_mesh_instance_rid != RID()) { + VS::get_singleton()->free(_mesh_instance_rid); + VS::get_singleton()->free(_mesh_rid); + + _mesh_instance_rid = RID(); + _mesh_rid = RID(); + } +} + +void VoxelChunk::allocate_prop_mesh() { + ERR_FAIL_COND(_voxel_world == NULL); + ERR_FAIL_COND(!get_library().is_valid()); + ERR_FAIL_COND(!get_library()->get_prop_material().is_valid()); + + _prop_mesh_instance_rid = VS::get_singleton()->instance_create(); + + if (get_library()->get_prop_material().is_valid()) { + VS::get_singleton()->instance_geometry_set_material_override(_prop_mesh_instance_rid, get_library()->get_prop_material()->get_rid()); + } + + if (get_voxel_world()->get_world().is_valid()) + VS::get_singleton()->instance_set_scenario(_prop_mesh_instance_rid, get_voxel_world()->get_world()->get_scenario()); + + _prop_mesh_rid = VS::get_singleton()->mesh_create(); + + VS::get_singleton()->instance_set_base(_prop_mesh_instance_rid, _prop_mesh_rid); + + 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::free_prop_mesh() { if (_prop_mesh_instance_rid != RID()) { VS::get_singleton()->free(_prop_mesh_instance_rid); @@ -557,6 +604,72 @@ void VoxelChunk::free_prop_colliders() { } } +//Liquid mesh +void VoxelChunk::allocate_liquid_mesh() { + ERR_FAIL_COND(_voxel_world == NULL); + + ERR_FAIL_COND(!get_library().is_valid()); + ERR_FAIL_COND(!get_library()->get_liquid_material().is_valid()); + + _liquid_mesh_instance_rid = VS::get_singleton()->instance_create(); + + if (get_library()->get_liquid_material().is_valid()) { + VS::get_singleton()->instance_geometry_set_material_override(_liquid_mesh_instance_rid, get_library()->get_liquid_material()->get_rid()); + } + + if (get_voxel_world()->get_world().is_valid()) + VS::get_singleton()->instance_set_scenario(_liquid_mesh_instance_rid, get_voxel_world()->get_world()->get_scenario()); + + _liquid_mesh_rid = VS::get_singleton()->mesh_create(); + + VS::get_singleton()->instance_set_base(_liquid_mesh_instance_rid, _liquid_mesh_rid); + + VS::get_singleton()->instance_set_transform(_liquid_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::free_liquid_mesh() { + if (_liquid_mesh_instance_rid != RID()) { + VS::get_singleton()->free(_liquid_mesh_instance_rid); + VS::get_singleton()->free(_liquid_mesh_rid); + + _liquid_mesh_instance_rid = RID(); + _liquid_mesh_rid = RID(); + } +} + +//Clutter mesh +void VoxelChunk::allocate_clutter_mesh() { + ERR_FAIL_COND(_voxel_world == NULL); + + ERR_FAIL_COND(!get_library().is_valid()); + ERR_FAIL_COND(!get_library()->get_clutter_material().is_valid()); + + _clutter_mesh_instance_rid = VS::get_singleton()->instance_create(); + + if (get_library()->get_clutter_material().is_valid()) { + VS::get_singleton()->instance_geometry_set_material_override(_clutter_mesh_instance_rid, get_library()->get_clutter_material()->get_rid()); + } + + if (get_voxel_world()->get_world().is_valid()) + VS::get_singleton()->instance_set_scenario(_clutter_mesh_instance_rid, get_voxel_world()->get_world()->get_scenario()); + + _clutter_mesh_rid = VS::get_singleton()->mesh_create(); + + VS::get_singleton()->instance_set_base(_clutter_mesh_instance_rid, _clutter_mesh_rid); + + VS::get_singleton()->instance_set_transform(_clutter_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::free_clutter_mesh() { + if (_clutter_mesh_instance_rid != RID()) { + VS::get_singleton()->free(_clutter_mesh_instance_rid); + VS::get_singleton()->free(_clutter_mesh_rid); + + _clutter_mesh_instance_rid = RID(); + _clutter_mesh_rid = RID(); + } +} + void VoxelChunk::free_spawn_props() { for (int i = 0; i < _spawned_props.size(); ++i) { _spawned_props[i]->queue_delete(); @@ -565,38 +678,6 @@ void VoxelChunk::free_spawn_props() { _spawned_props.clear(); } -void VoxelChunk::allocate_main_mesh() { - ERR_FAIL_COND(_voxel_world == NULL); - - ERR_FAIL_COND(!get_library().is_valid()); - ERR_FAIL_COND(!get_library()->get_material().is_valid()); - - _mesh_instance_rid = VS::get_singleton()->instance_create(); - - if (get_library()->get_material().is_valid()) { - VS::get_singleton()->instance_geometry_set_material_override(_mesh_instance_rid, get_library()->get_material()->get_rid()); - } - - if (get_voxel_world()->get_world().is_valid()) - VS::get_singleton()->instance_set_scenario(_mesh_instance_rid, get_voxel_world()->get_world()->get_scenario()); - - _mesh_rid = VS::get_singleton()->mesh_create(); - - VS::get_singleton()->instance_set_base(_mesh_instance_rid, _mesh_rid); - - VS::get_singleton()->instance_set_transform(_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::free_main_mesh() { - if (_mesh_instance_rid != RID()) { - VS::get_singleton()->free(_mesh_instance_rid); - VS::get_singleton()->free(_mesh_rid); - - _mesh_instance_rid = RID(); - _mesh_rid = RID(); - } -} - void VoxelChunk::create_debug_immediate_geometry() { ERR_FAIL_COND(_voxel_world == NULL); ERR_FAIL_COND(_debug_drawer != NULL); @@ -719,6 +800,8 @@ void VoxelChunk::free_chunk() { free_prop_mesh(); free_prop_colliders(); free_spawn_props(); + free_liquid_mesh(); + free_clutter_mesh(); } VoxelChunk::VoxelChunk() { @@ -744,6 +827,8 @@ VoxelChunk::~VoxelChunk() { remove_colliders(); free_prop_mesh(); free_prop_colliders(); + free_liquid_mesh(); + free_clutter_mesh(); //do not call free here, the app will crash on exit, if you try to free nodes too. _voxel_lights.clear(); @@ -855,6 +940,12 @@ void VoxelChunk::_bind_methods() { 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("get_liquid_mesh_rid"), &VoxelChunk::get_liquid_mesh_rid); + ClassDB::bind_method(D_METHOD("get_liquid_mesh_instance_rid"), &VoxelChunk::get_liquid_mesh_instance_rid); + + ClassDB::bind_method(D_METHOD("get_clutter_mesh_rid"), &VoxelChunk::get_clutter_mesh_rid); + ClassDB::bind_method(D_METHOD("get_clutter_mesh_instance_rid"), &VoxelChunk::get_clutter_mesh_instance_rid); + ClassDB::bind_method(D_METHOD("finalize_mesh"), &VoxelChunk::finalize_mesh); BIND_VMETHOD(MethodInfo("_build_phase", PropertyInfo(Variant::INT, "phase"))); @@ -882,7 +973,7 @@ void VoxelChunk::_bind_methods() { ClassDB::bind_method(D_METHOD("bake_lights"), &VoxelChunk::bake_lights); 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_light", "light"), &VoxelChunk::add_prop_light); ClassDB::bind_method(D_METHOD("add_prop", "prop"), &VoxelChunk::add_prop); @@ -907,6 +998,12 @@ void VoxelChunk::_bind_methods() { ClassDB::bind_method(D_METHOD("allocate_prop_colliders"), &VoxelChunk::allocate_prop_colliders); ClassDB::bind_method(D_METHOD("free_prop_colliders"), &VoxelChunk::free_prop_colliders); + ClassDB::bind_method(D_METHOD("allocate_liquid_mesh"), &VoxelChunk::allocate_liquid_mesh); + ClassDB::bind_method(D_METHOD("free_liquid_mesh"), &VoxelChunk::free_liquid_mesh); + + ClassDB::bind_method(D_METHOD("allocate_clutter_mesh"), &VoxelChunk::allocate_clutter_mesh); + ClassDB::bind_method(D_METHOD("free_clutter_mesh"), &VoxelChunk::free_clutter_mesh); + ClassDB::bind_method(D_METHOD("create_mesher"), &VoxelChunk::create_mesher); ClassDB::bind_method(D_METHOD("create_debug_immediate_geometry"), &VoxelChunk::create_debug_immediate_geometry); diff --git a/world/voxel_chunk.h b/world/voxel_chunk.h index 67fd5ee..eead13e 100644 --- a/world/voxel_chunk.h +++ b/world/voxel_chunk.h @@ -127,6 +127,12 @@ public: RID get_prop_shape_rid(); RID get_prop_body_rid(); + RID get_liquid_mesh_rid(); + RID get_liquid_mesh_instance_rid(); + + RID get_clutter_mesh_rid(); + RID get_clutter_mesh_instance_rid(); + //Meshing void create_mesher(); void _create_mesher(); @@ -185,6 +191,12 @@ public: void allocate_prop_colliders(); void free_prop_colliders(); + void allocate_liquid_mesh(); + void free_liquid_mesh(); + + void allocate_clutter_mesh(); + void free_clutter_mesh(); + //Debug void create_debug_immediate_geometry(); void free_debug_immediate_geometry(); @@ -222,6 +234,7 @@ protected: NodePath _library_path; Ref _library; + Ref _mesher; //voxel mesh RID _mesh_rid; @@ -230,8 +243,6 @@ protected: RID _shape_rid; RID _body_rid; - Ref _mesher; - //mergeable props Vector > _props; @@ -241,6 +252,14 @@ protected: RID _prop_shape_rid; RID _prop_body_rid; + //liquids + RID _liquid_mesh_rid; + RID _liquid_mesh_instance_rid; + + //clutter + RID _clutter_mesh_rid; + RID _clutter_mesh_instance_rid; + //spawned props Vector _spawned_props;