From 541abb954dd0cf93163eec014de22e8ea33659b5 Mon Sep 17 00:00:00 2001 From: Relintai Date: Sun, 29 Mar 2020 20:19:38 +0200 Subject: [PATCH] Now materials in Library are stored with vectors. This makes it possible to have different materials for every lod level for example. --- library/voxelman_library.cpp | 272 ++++++++++++++++++++++++---- library/voxelman_library.h | 52 ++++-- library/voxelman_library_merger.cpp | 78 +++++--- meshers/voxel_mesher.cpp | 2 +- props/prop_data.cpp | 12 +- props/prop_data.h | 12 +- world/voxel_chunk_default.cpp | 14 +- 7 files changed, 343 insertions(+), 99 deletions(-) diff --git a/library/voxelman_library.cpp b/library/voxelman_library.cpp index ce91c4c..a235ce7 100644 --- a/library/voxelman_library.cpp +++ b/library/voxelman_library.cpp @@ -24,32 +24,200 @@ SOFTWARE. #include "../props/prop_data.h" -Ref VoxelmanLibrary::get_material() const { - return _material; -} -void VoxelmanLibrary::set_material(Ref mat) { - _material = mat; +//Materials +Ref VoxelmanLibrary::get_material(const int index) { + ERR_FAIL_INDEX_V(index, _materials.size(), Ref(NULL)); + + return _materials[index]; } -Ref VoxelmanLibrary::get_prop_material() const { - return _prop_material; -} -void VoxelmanLibrary::set_prop_material(Ref mat) { - _prop_material = mat; +void VoxelmanLibrary::add_material(const Ref &value) { + ERR_FAIL_COND(!value.is_valid()); + + _materials.push_back(value); } -Ref VoxelmanLibrary::get_liquid_material() const { - return _liquid_material; -} -void VoxelmanLibrary::set_liquid_material(Ref mat) { - _liquid_material = mat; +void VoxelmanLibrary::set_material(const int index, const Ref &value) { + ERR_FAIL_INDEX(index, _materials.size()); + + _materials.set(index, value); } -Ref VoxelmanLibrary::get_clutter_material() const { - return _clutter_material; +void VoxelmanLibrary::remove_material(const int index) { + _materials.remove(index); } -void VoxelmanLibrary::set_clutter_material(Ref mat) { - _clutter_material = mat; + +int VoxelmanLibrary::get_num_materials() const { + return _materials.size(); +} + +void VoxelmanLibrary::clear_materials() { + _materials.clear(); +} + +Vector VoxelmanLibrary::get_materials() { + Vector r; + for (int i = 0; i < _materials.size(); i++) { + r.push_back(_materials[i].get_ref_ptr()); + } + return r; +} + +void VoxelmanLibrary::set_materials(const Vector &materials) { + _materials.clear(); + + for (int i = 0; i < materials.size(); i++) { + Ref material = Ref(materials[i]); + + _materials.push_back(material); + } +} + +//Prop Materials +Ref VoxelmanLibrary::get_prop_material(const int index) { + ERR_FAIL_INDEX_V(index, _prop_materials.size(), Ref(NULL)); + + return _prop_materials[index]; +} + +void VoxelmanLibrary::add_prop_material(const Ref &value) { + ERR_FAIL_COND(!value.is_valid()); + + _prop_materials.push_back(value); +} + +void VoxelmanLibrary::set_prop_material(const int index, const Ref &value) { + ERR_FAIL_INDEX(index, _prop_materials.size()); + + _prop_materials.set(index, value); +} + +void VoxelmanLibrary::remove_prop_material(const int index) { + _prop_materials.remove(index); +} + +int VoxelmanLibrary::get_num_prop_materials() const { + return _prop_materials.size(); +} + +void VoxelmanLibrary::clear_prop_materials() { + _prop_materials.clear(); +} + +Vector VoxelmanLibrary::get_prop_materials() { + Vector r; + for (int i = 0; i < _prop_materials.size(); i++) { + r.push_back(_prop_materials[i].get_ref_ptr()); + } + return r; +} + +void VoxelmanLibrary::set_prop_materials(const Vector &materials) { + _prop_materials.clear(); + + for (int i = 0; i < materials.size(); i++) { + Ref material = Ref(materials[i]); + + _prop_materials.push_back(material); + } +} + +//Liquid Materials +Ref VoxelmanLibrary::get_liquid_material(const int index) { + ERR_FAIL_INDEX_V(index, _liquid_materials.size(), Ref(NULL)); + + return _liquid_materials[index]; +} + +void VoxelmanLibrary::add_liquid_material(const Ref &value) { + ERR_FAIL_COND(!value.is_valid()); + + _liquid_materials.push_back(value); +} + +void VoxelmanLibrary::set_liquid_material(const int index, const Ref &value) { + ERR_FAIL_INDEX(index, _liquid_materials.size()); + + _liquid_materials.set(index, value); +} + +void VoxelmanLibrary::remove_liquid_material(const int index) { + _liquid_materials.remove(index); +} + +int VoxelmanLibrary::get_num_liquid_materials() const { + return _liquid_materials.size(); +} + +void VoxelmanLibrary::clear_liquid_materials() { + _liquid_materials.clear(); +} + +Vector VoxelmanLibrary::get_liquid_materials() { + Vector r; + for (int i = 0; i < _liquid_materials.size(); i++) { + r.push_back(_liquid_materials[i].get_ref_ptr()); + } + return r; +} + +void VoxelmanLibrary::set_liquid_materials(const Vector &materials) { + _liquid_materials.clear(); + + for (int i = 0; i < materials.size(); i++) { + Ref material = Ref(materials[i]); + + _liquid_materials.push_back(material); + } +} + +//Clutter Materials +Ref VoxelmanLibrary::get_clutter_material(const int index) { + ERR_FAIL_INDEX_V(index, _clutter_materials.size(), Ref(NULL)); + + return _clutter_materials[index]; +} + +void VoxelmanLibrary::add_clutter_material(const Ref &value) { + ERR_FAIL_COND(!value.is_valid()); + + _clutter_materials.push_back(value); +} + +void VoxelmanLibrary::set_clutter_material(const int index, const Ref &value) { + ERR_FAIL_INDEX(index, _clutter_materials.size()); + + _clutter_materials.set(index, value); +} + +void VoxelmanLibrary::remove_clutter_material(const int index) { + _clutter_materials.remove(index); +} + +int VoxelmanLibrary::get_num_clutter_materials() const { + return _clutter_materials.size(); +} + +void VoxelmanLibrary::clear_clutter_materials() { + _clutter_materials.clear(); +} + +Vector VoxelmanLibrary::get_clutter_materials() { + Vector r; + for (int i = 0; i < _clutter_materials.size(); i++) { + r.push_back(_clutter_materials[i].get_ref_ptr()); + } + return r; +} + +void VoxelmanLibrary::set_clutter_materials(const Vector &materials) { + _clutter_materials.clear(); + + for (int i = 0; i < materials.size(); i++) { + Ref material = Ref(materials[i]); + + _clutter_materials.push_back(material); + } } //Surfaces @@ -58,7 +226,7 @@ Ref VoxelmanLibrary::get_voxel_surface(const int index) { } void VoxelmanLibrary::add_voxel_surface(Ref value) { } -void VoxelmanLibrary::set_voxel_surface(const int index, Ref value) { +void VoxelmanLibrary::set_voxel_surface(int index, Ref value) { } void VoxelmanLibrary::remove_surface(const int index) { } @@ -74,7 +242,7 @@ Ref VoxelmanLibrary::get_liquid_surface(const int index) { } void VoxelmanLibrary::add_liquid_surface(Ref value) { } -void VoxelmanLibrary::set_liquid_surface(const int index, Ref value) { +void VoxelmanLibrary::set_liquid_surface(int index, Ref value) { } void VoxelmanLibrary::remove_liquid_surface(const int index) { } @@ -89,7 +257,7 @@ Ref VoxelmanLibrary::get_prop(const int id) { } void VoxelmanLibrary::add_prop(Ref value) { } -void VoxelmanLibrary::set_prop(const int id, Ref value) { +void VoxelmanLibrary::set_prop(int id, Ref value) { } void VoxelmanLibrary::remove_prop(const int id) { } @@ -112,30 +280,58 @@ VoxelmanLibrary::VoxelmanLibrary() { } VoxelmanLibrary::~VoxelmanLibrary() { - _material.unref(); - _prop_material.unref(); - _liquid_material.unref(); - _clutter_material.unref(); + _materials.clear(); + _prop_materials.clear(); + _liquid_materials.clear(); + _clutter_materials.clear(); } void VoxelmanLibrary::_bind_methods() { BIND_VMETHOD(MethodInfo("_setup_material_albedo", PropertyInfo(Variant::INT, "material_index"), PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"))); - ClassDB::bind_method(D_METHOD("get_material"), &VoxelmanLibrary::get_material); - ClassDB::bind_method(D_METHOD("set_material", "value"), &VoxelmanLibrary::set_material); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "material", PROPERTY_HINT_RESOURCE_TYPE, "Material"), "set_material", "get_material"); + ClassDB::bind_method(D_METHOD("get_material", "index"), &VoxelmanLibrary::get_material); + ClassDB::bind_method(D_METHOD("add_material", "value"), &VoxelmanLibrary::add_material); + ClassDB::bind_method(D_METHOD("set_material", "index", "value"), &VoxelmanLibrary::set_material); + ClassDB::bind_method(D_METHOD("remove_material", "index"), &VoxelmanLibrary::remove_material); + ClassDB::bind_method(D_METHOD("get_num_materials"), &VoxelmanLibrary::get_num_materials); + ClassDB::bind_method(D_METHOD("clear_materials"), &VoxelmanLibrary::clear_materials); - ClassDB::bind_method(D_METHOD("get_prop_material"), &VoxelmanLibrary::get_prop_material); - 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_materials"), &VoxelmanLibrary::get_materials); + ClassDB::bind_method(D_METHOD("set_materials"), &VoxelmanLibrary::set_materials); + ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "materials", PROPERTY_HINT_NONE, "17/17:Material", PROPERTY_USAGE_DEFAULT, "Material"), "set_materials", "get_materials"); - 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_prop_material", "index"), &VoxelmanLibrary::get_prop_material); + ClassDB::bind_method(D_METHOD("add_prop_material", "value"), &VoxelmanLibrary::add_prop_material); + ClassDB::bind_method(D_METHOD("set_prop_material", "index", "value"), &VoxelmanLibrary::set_prop_material); + ClassDB::bind_method(D_METHOD("remove_prop_material", "index"), &VoxelmanLibrary::remove_prop_material); + ClassDB::bind_method(D_METHOD("get_num_prop_materials"), &VoxelmanLibrary::get_num_prop_materials); + ClassDB::bind_method(D_METHOD("clear_prop_materials"), &VoxelmanLibrary::clear_prop_materials); - 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_prop_materials"), &VoxelmanLibrary::get_prop_materials); + ClassDB::bind_method(D_METHOD("set_prop_materials"), &VoxelmanLibrary::set_prop_materials); + ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "prop_materials", PROPERTY_HINT_NONE, "17/17:Material", PROPERTY_USAGE_DEFAULT, "Material"), "set_prop_materials", "get_prop_materials"); + + ClassDB::bind_method(D_METHOD("get_liquid_material", "index"), &VoxelmanLibrary::get_liquid_material); + ClassDB::bind_method(D_METHOD("add_liquid_material", "value"), &VoxelmanLibrary::add_liquid_material); + ClassDB::bind_method(D_METHOD("set_liquid_material", "index", "value"), &VoxelmanLibrary::set_liquid_material); + ClassDB::bind_method(D_METHOD("remove_liquid_material", "index"), &VoxelmanLibrary::remove_liquid_material); + ClassDB::bind_method(D_METHOD("get_num_liquid_materials"), &VoxelmanLibrary::get_num_liquid_materials); + ClassDB::bind_method(D_METHOD("clear_liquid_materials"), &VoxelmanLibrary::clear_liquid_materials); + + ClassDB::bind_method(D_METHOD("get_liquid_materials"), &VoxelmanLibrary::get_liquid_materials); + ClassDB::bind_method(D_METHOD("set_liquid_materials"), &VoxelmanLibrary::set_liquid_materials); + ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "liquid_materials", PROPERTY_HINT_NONE, "17/17:Material", PROPERTY_USAGE_DEFAULT, "Material"), "set_liquid_materials", "get_liquid_materials"); + + ClassDB::bind_method(D_METHOD("get_clutter_material", "index"), &VoxelmanLibrary::get_clutter_material); + ClassDB::bind_method(D_METHOD("add_clutter_material", "value"), &VoxelmanLibrary::add_clutter_material); + ClassDB::bind_method(D_METHOD("set_clutter_material", "index", "value"), &VoxelmanLibrary::set_clutter_material); + ClassDB::bind_method(D_METHOD("remove_clutter_material", "index"), &VoxelmanLibrary::remove_clutter_material); + ClassDB::bind_method(D_METHOD("get_num_clutter_materials"), &VoxelmanLibrary::get_num_clutter_materials); + ClassDB::bind_method(D_METHOD("clear_clutter_materials"), &VoxelmanLibrary::clear_clutter_materials); + + ClassDB::bind_method(D_METHOD("get_clutter_materials"), &VoxelmanLibrary::get_clutter_materials); + ClassDB::bind_method(D_METHOD("set_clutter_materials"), &VoxelmanLibrary::set_clutter_materials); + ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "clutter_materials", PROPERTY_HINT_NONE, "17/17:Material", PROPERTY_USAGE_DEFAULT, "Material"), "set_clutter_materials", "get_clutter_materials"); ClassDB::bind_method(D_METHOD("get_voxel_surface", "index"), &VoxelmanLibrary::get_voxel_surface); ClassDB::bind_method(D_METHOD("add_voxel_surface", "value"), &VoxelmanLibrary::add_voxel_surface); diff --git a/library/voxelman_library.h b/library/voxelman_library.h index e057e9a..78da526 100644 --- a/library/voxelman_library.h +++ b/library/voxelman_library.h @@ -45,17 +45,45 @@ public: }; public: - Ref get_material() const; - void set_material(Ref mat); + Ref get_material(const int index); + void add_material(const Ref &value); + void set_material(const int index, const Ref &value); + void remove_material(const int index); + int get_num_materials() const; + void clear_materials(); - Ref get_prop_material() const; - void set_prop_material(Ref mat); + Vector get_materials(); + void set_materials(const Vector &materials); - Ref get_liquid_material() const; - void set_liquid_material(Ref mat); + Ref get_prop_material(const int index); + void add_prop_material(const Ref &value); + void set_prop_material(const int index, const Ref &value); + void remove_prop_material(const int index); + int get_num_prop_materials() const; + void clear_prop_materials(); - Ref get_clutter_material() const; - void set_clutter_material(Ref mat); + Vector get_prop_materials(); + void set_prop_materials(const Vector &materials); + + Ref get_liquid_material(const int index); + void add_liquid_material(const Ref &value); + void set_liquid_material(const int index, const Ref &value); + void remove_liquid_material(const int index); + int get_num_liquid_materials() const; + void clear_liquid_materials(); + + Vector get_liquid_materials(); + void set_liquid_materials(const Vector &materials); + + Ref get_clutter_material(const int index); + void add_clutter_material(const Ref &value); + void set_clutter_material(const int index, const Ref &value); + void remove_clutter_material(const int index); + int get_num_clutter_materials() const; + void clear_clutter_materials(); + + Vector get_clutter_materials(); + void set_clutter_materials(const Vector &materials); virtual Ref get_voxel_surface(const int index); virtual void add_voxel_surface(Ref value); @@ -89,10 +117,10 @@ protected: static void _bind_methods(); private: - Ref _material; - Ref _prop_material; - Ref _liquid_material; - Ref _clutter_material; + Vector > _materials; + Vector > _prop_materials; + Vector > _liquid_materials; + Vector > _clutter_materials; }; #endif // VOXEL_LIBRARY_H diff --git a/library/voxelman_library_merger.cpp b/library/voxelman_library_merger.cpp index 12fbe76..307f44d 100644 --- a/library/voxelman_library_merger.cpp +++ b/library/voxelman_library_merger.cpp @@ -384,47 +384,67 @@ void VoxelmanLibraryMerger::refresh_rects() { void VoxelmanLibraryMerger::_setup_material_albedo(int material_index, Ref texture) { Ref mat; - switch (material_index) { - case MATERIAL_INDEX_VOXELS: - mat = get_material(); - break; - case MATERIAL_INDEX_PROP: - mat = get_prop_material(); - break; - case MATERIAL_INDEX_LIQUID: - mat = get_liquid_material(); - break; - case MATERIAL_INDEX_CLUTTER: - mat = get_clutter_material(); - break; - } - - Ref spmat; - - if (spmat.is_valid()) { - spmat->set_texture(SpatialMaterial::TEXTURE_ALBEDO, texture); - return; - } - - Ref shmat; + int count = 0; switch (material_index) { case MATERIAL_INDEX_VOXELS: - shmat = get_material(); + count = get_num_materials(); break; case MATERIAL_INDEX_PROP: - shmat = get_prop_material(); + count = get_num_prop_materials(); break; case MATERIAL_INDEX_LIQUID: - shmat = get_liquid_material(); + count = get_num_liquid_materials(); break; case MATERIAL_INDEX_CLUTTER: - shmat = get_clutter_material(); + count = get_num_clutter_materials(); break; } - if (shmat.is_valid()) { - shmat->set_shader_param("texture_albedo", texture); + for (int i = 0; i < count; ++i) { + + switch (material_index) { + case MATERIAL_INDEX_VOXELS: + mat = get_material(i); + break; + case MATERIAL_INDEX_PROP: + mat = get_prop_material(i); + break; + case MATERIAL_INDEX_LIQUID: + mat = get_liquid_material(i); + break; + case MATERIAL_INDEX_CLUTTER: + mat = get_clutter_material(i); + break; + } + + Ref spmat; + + if (spmat.is_valid()) { + spmat->set_texture(SpatialMaterial::TEXTURE_ALBEDO, texture); + return; + } + + Ref shmat; + + switch (material_index) { + case MATERIAL_INDEX_VOXELS: + shmat = get_material(i); + break; + case MATERIAL_INDEX_PROP: + shmat = get_prop_material(i); + break; + case MATERIAL_INDEX_LIQUID: + shmat = get_liquid_material(i); + break; + case MATERIAL_INDEX_CLUTTER: + shmat = get_clutter_material(i); + break; + } + + if (shmat.is_valid()) { + shmat->set_shader_param("texture_albedo", texture); + } } } diff --git a/meshers/voxel_mesher.cpp b/meshers/voxel_mesher.cpp index 2055173..fe5ec98 100644 --- a/meshers/voxel_mesher.cpp +++ b/meshers/voxel_mesher.cpp @@ -247,7 +247,7 @@ void VoxelMesher::build_mesh_into(RID mesh) { VS::get_singleton()->mesh_add_surface_from_arrays(mesh, VisualServer::PRIMITIVE_TRIANGLES, arr); if (_material.is_valid()) - VS::get_singleton()->mesh_surface_set_material(mesh, 0, _library->get_material()->get_rid()); + VS::get_singleton()->mesh_surface_set_material(mesh, 0, _library->get_material(0)->get_rid()); } void VoxelMesher::generate_normals(bool p_flip) { diff --git a/props/prop_data.cpp b/props/prop_data.cpp index c4253e5..5467583 100644 --- a/props/prop_data.cpp +++ b/props/prop_data.cpp @@ -25,24 +25,24 @@ SOFTWARE. #include "../world/voxel_chunk.h" #include "prop_data_prop.h" -int PropData::get_id() { +int PropData::get_id() const { return _id; } -void PropData::set_id(int value) { +void PropData::set_id(const int value) { _id = value; } -bool PropData::get_snap_to_mesh() { +bool PropData::get_snap_to_mesh() const { return _snap_to_mesh; } -void PropData::set_snap_to_mesh(bool value) { +void PropData::set_snap_to_mesh(const bool value) { _snap_to_mesh = value; } -Vector3 PropData::get_snap_axis() { +Vector3 PropData::get_snap_axis() const { return _snap_axis; } -void PropData::set_snap_axis(Vector3 value) { +void PropData::set_snap_axis(const Vector3 &value) { _snap_axis = value; } diff --git a/props/prop_data.h b/props/prop_data.h index 52b97ec..a65c43f 100644 --- a/props/prop_data.h +++ b/props/prop_data.h @@ -46,14 +46,14 @@ class PropData : public Resource { GDCLASS(PropData, Resource); public: - int get_id(); - void set_id(int value); + int get_id() const; + void set_id(const int value); - bool get_snap_to_mesh(); - void set_snap_to_mesh(bool value); + bool get_snap_to_mesh() const; + void set_snap_to_mesh(const bool value); - Vector3 get_snap_axis(); - void set_snap_axis(Vector3 value); + Vector3 get_snap_axis() const; + void set_snap_axis(const Vector3 &value); Ref get_prop(const int index) const; void set_prop(const int index, const Ref prop); diff --git a/world/voxel_chunk_default.cpp b/world/voxel_chunk_default.cpp index 2e40e07..10e6fd5 100644 --- a/world/voxel_chunk_default.cpp +++ b/world/voxel_chunk_default.cpp @@ -781,11 +781,11 @@ void VoxelChunkDefault::_build_phase(int phase) { if (!mesher.is_valid()) { mesher = m; - mesher->set_material(get_library()->get_material()); + mesher->set_material(get_library()->get_material(0)); continue; } - mesher->set_material(get_library()->get_material()); + mesher->set_material(get_library()->get_material(0)); mesher->add_mesher(m); } @@ -807,8 +807,8 @@ void VoxelChunkDefault::_build_phase(int phase) { VS::get_singleton()->mesh_add_surface_from_arrays(_mesh_rid, VisualServer::PRIMITIVE_TRIANGLES, temp_mesh_arr); - if (_library->get_material().is_valid()) - VS::get_singleton()->mesh_surface_set_material(_mesh_rid, 0, _library->get_material()->get_rid()); + if (_library->get_material(0).is_valid()) + VS::get_singleton()->mesh_surface_set_material(_mesh_rid, 0, _library->get_material(0)->get_rid()); next_phase(); @@ -834,7 +834,7 @@ void VoxelChunkDefault::_build_phase(int phase) { ERR_CONTINUE(!mesher.is_valid()); mesher->bake_colors(this); - mesher->set_material(get_library()->get_material()); + mesher->set_material(get_library()->get_material(0)); ERR_FAIL_COND(_prop_mesh_rid == RID()); @@ -849,8 +849,8 @@ void VoxelChunkDefault::_build_phase(int phase) { VS::get_singleton()->mesh_add_surface_from_arrays(_prop_mesh_rid, VisualServer::PRIMITIVE_TRIANGLES, arr); - if (_library->get_material().is_valid()) - VS::get_singleton()->mesh_surface_set_material(_prop_mesh_rid, 0, _library->get_material()->get_rid()); + if (_library->get_material(0).is_valid()) + VS::get_singleton()->mesh_surface_set_material(_prop_mesh_rid, 0, _library->get_material(0)->get_rid()); } }