Added liquid, and clutter mesh allocations into Chunk, also related modifications.

This commit is contained in:
Relintai 2019-11-10 13:42:59 +01:00
parent 3cf4b3e682
commit e0deb2ea66
10 changed files with 362 additions and 75 deletions

View File

@ -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<VoxelChunk>(chunk);
ERR_FAIL_COND_V(!ObjectDB::instance_validate(c), false);
return should_spawn(c, x, y, z);
}
void GroundClutter::add_meshes_to(Ref<VoxelMesher> 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<VoxelMesher> mesher, Node *chunk, int x, int y, int z) {
VoxelChunk *c = Object::cast_to<VoxelChunk>(chunk);
ERR_FAIL_COND(!ObjectDB::instance_validate(c));
add_meshes_to(mesher, c, x, y, z);
}
void GroundClutter::add_textures_to(Ref<TexturePacker> 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);
}

View File

@ -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<VoxelMesher> mesher, VoxelChunk *chunk, int x, int y, int z);
void add_meshes_to_bind(Ref<VoxelMesher> mesher, Node *chunk, int x, int y, int z);
void add_textures_to(Ref<TexturePacker> packer);
GroundClutter();
~GroundClutter();

View File

@ -12,6 +12,7 @@
#include "../clutter/ground_clutter.h"
class VoxelmanLibrary;
class GroundClutter;
class VoxelSurface : public Resource {
GDCLASS(VoxelSurface, Resource)

View File

@ -1,11 +1,31 @@
#include "voxelman_library.h"
VoxelmanLibrary::VoxelmanLibrary() {
Ref<Material> VoxelmanLibrary::get_material() const {
return _material;
}
void VoxelmanLibrary::set_material(Ref<Material> mat) {
_material = mat;
}
VoxelmanLibrary::~VoxelmanLibrary() {
_material.unref();
_prop_material.unref();
Ref<Material> VoxelmanLibrary::get_prop_material() const {
return _prop_material;
}
void VoxelmanLibrary::set_prop_material(Ref<Material> mat) {
_prop_material = mat;
}
Ref<Material> VoxelmanLibrary::get_liquid_material() const {
return _liquid_material;
}
void VoxelmanLibrary::set_liquid_material(Ref<Material> mat) {
_liquid_material = mat;
}
Ref<Material> VoxelmanLibrary::get_clutter_material() const {
return _clutter_material;
}
void VoxelmanLibrary::set_clutter_material(Ref<Material> 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);

View File

@ -14,11 +14,17 @@ class VoxelmanLibrary : public Resource {
GDCLASS(VoxelmanLibrary, Resource)
public:
Ref<Material> get_material() const { return _material; }
void set_material(Ref<Material> mat) { _material = mat; }
Ref<Material> get_material() const;
void set_material(Ref<Material> mat);
Ref<Material> get_prop_material() const { return _prop_material; }
void set_prop_material(Ref<Material> mat) { _prop_material = mat; }
Ref<Material> get_prop_material() const;
void set_prop_material(Ref<Material> mat);
Ref<Material> get_liquid_material() const;
void set_liquid_material(Ref<Material> mat);
Ref<Material> get_clutter_material() const;
void set_clutter_material(Ref<Material> mat);
virtual Ref<VoxelSurface> get_voxel_surface(int index) const;
virtual void set_voxel_surface(int index, Ref<VoxelSurface> value);
@ -43,6 +49,8 @@ protected:
private:
Ref<Material> _material;
Ref<Material> _prop_material;
Ref<Material> _liquid_material;
Ref<Material> _clutter_material;
};
#endif // VOXEL_LIBRARY_H

View File

@ -183,7 +183,6 @@ void VoxelmanLibraryMerger::set_liquid_voxel_surfaces(const Vector<Variant> &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<VoxelSurface::VoxelSurfaceSides>(j), _packer->get_texture(tex));
}
}
Ref<GroundClutter> 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();
}

View File

@ -119,6 +119,12 @@ void VoxelMesher::add_buffer(Ref<VoxelBuffer> voxels) {
call("_add_buffer", voxels);
}
void VoxelMesher::add_buffer_liquid(Ref<VoxelBuffer> voxels) {
ERR_FAIL_COND(!has_method("_add_buffer_liquid"));
call("_add_buffer_liquid", voxels);
}
void VoxelMesher::add_mesh_data_resource(Ref<MeshDataResource> 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<VoxelBuffer> voxels) {
if (has_method("_bake_colors"))
call("_bake_colors", voxels);
}
void VoxelMesher::_bake_colors(Ref<VoxelBuffer> 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<VoxelBuffer> voxels) {
if (has_method("_bake_liquid_colors"))
call("_bake_liquid_colors", voxels);
}
void VoxelMesher::_bake_liquid_colors(Ref<VoxelBuffer> 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);

View File

@ -55,12 +55,16 @@ public:
void reset();
void add_buffer(Ref<VoxelBuffer> voxels);
void add_buffer_liquid(Ref<VoxelBuffer> voxels);
void add_mesh_data_resource(Ref<MeshDataResource> 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<MeshDataResource> mesh, const Transform transform, const Rect2 uv_rect = Rect2(0, 0, 1, 1));
void bake_colors(Ref<VoxelBuffer> voxels);
void bake_colors(Ref<VoxelBuffer> voxels);
void _bake_colors(Ref<VoxelBuffer> buffer);
void bake_liquid_colors(Ref<VoxelBuffer> voxels);
void _bake_liquid_colors(Ref<VoxelBuffer> buffer);
void build_collider(RID shape) const;
void bake_lights(MeshInstance *node, Vector<Ref<VoxelLight> > &lights);

View File

@ -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<VoxelLight> light) {
bake_light(light);
bake_light(light);
}
void VoxelChunk::add_prop(Ref<VoxelChunkPropData> 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);

View File

@ -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<VoxelmanLibrary> _library;
Ref<VoxelMesher> _mesher;
//voxel mesh
RID _mesh_rid;
@ -230,8 +243,6 @@ protected:
RID _shape_rid;
RID _body_rid;
Ref<VoxelMesher> _mesher;
//mergeable props
Vector<Ref<VoxelChunkPropData> > _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<Node *> _spawned_props;