From cbb2028d6417a8a811c020c7c616ce4f044bf9f3 Mon Sep 17 00:00:00 2001 From: Relintai Date: Tue, 27 Apr 2021 16:47:46 +0200 Subject: [PATCH] Split PropInstance into PropInstance and PropInstanceMerger. --- SCsub | 1 + prop_instance.cpp | 250 ------------------------ prop_instance.h | 65 +------ prop_instance_merger.cpp | 403 +++++++++++++++++++++++++++++++++++++++ prop_instance_merger.h | 128 +++++++++++++ register_types.cpp | 2 + 6 files changed, 536 insertions(+), 313 deletions(-) create mode 100644 prop_instance_merger.cpp create mode 100644 prop_instance_merger.h diff --git a/SCsub b/SCsub index ce49cf6..70bb897 100644 --- a/SCsub +++ b/SCsub @@ -34,6 +34,7 @@ sources = [ "clutter/ground_clutter_foliage.cpp", "prop_instance.cpp", + "prop_instance_merger.cpp", "prop_ess_entity.cpp", "prop_instance_job.cpp", "prop_instance_prop_job.cpp", diff --git a/prop_instance.cpp b/prop_instance.cpp index 6ca1e73..2faefdd 100644 --- a/prop_instance.cpp +++ b/prop_instance.cpp @@ -2,37 +2,8 @@ #include "../mesh_data_resource/nodes/mesh_data_instance.h" -//#include "../thread_pool/thread_pool.h" - #include "core/version.h" -#if VERSION_MAJOR > 3 -#include "core/config/engine.h" - -#define VARIANT_ARRAY_GET(arr) \ - Vector r; \ - for (int i = 0; i < arr.size(); i++) { \ - r.push_back(arr[i]); \ - } \ - return r; - -#include "servers/rendering_server.h" -typedef class RenderingServer VS; - -#else -#include "core/engine.h" - -#define VARIANT_ARRAY_GET(arr) \ - Vector r; \ - for (int i = 0; i < arr.size(); i++) { \ - r.push_back(arr[i].get_ref_ptr()); \ - } \ - return r; - -#include "servers/visual_server.h" - -#endif - #if MESH_DATA_RESOURCE_PRESENT //define PROPS_PRESENT, so things compile. That module's scsub will define this too while compiling, //but not when included from here. @@ -57,151 +28,6 @@ void PropInstance::set_prop_data(const Ref &data) { queue_build(); } -Ref PropInstance::get_job() { - return _job; -} -void PropInstance::set_job(const Ref &job) { - _job = job; -} - -#ifdef TEXTURE_PACKER_PRESENT -bool PropInstance::get_merge_textures() const { - return _merge_textures; -} - -void PropInstance::set_merge_textures(const bool value) { - _merge_textures = value; -} -#endif - -//Materials -Ref PropInstance::material_get(const int index) { - ERR_FAIL_INDEX_V(index, _materials.size(), Ref(NULL)); - - return _materials[index]; -} - -void PropInstance::material_add(const Ref &value) { - ERR_FAIL_COND(!value.is_valid()); - - _materials.push_back(value); -} - -int PropInstance::material_get_num() const { - return _materials.size(); -} - -void PropInstance::materials_clear() { - _materials.clear(); -} - -Vector PropInstance::materials_get() { - VARIANT_ARRAY_GET(_materials); -} - -void PropInstance::materials_set(const Vector &materials) { - _materials.clear(); - - for (int i = 0; i < materials.size(); i++) { - Ref material = Ref(materials[i]); - - _materials.push_back(material); - } -} - -//Meshes -RID PropInstance::mesh_get(const int index) { - ERR_FAIL_INDEX_V(index, _meshes.size(), RID()); - - return _meshes[index]; -} - -void PropInstance::mesh_add(const RID value) { - _meshes.push_back(value); -} - -int PropInstance::mesh_get_num() const { - return _meshes.size(); -} - -void PropInstance::meshs_clear() { - _meshes.clear(); -} - -Vector PropInstance::meshes_get() { - Vector r; - for (int i = 0; i < _meshes.size(); i++) { - r.push_back(_meshes[i]); - } - return r; -} - -void PropInstance::meshes_set(const Vector &meshs) { - _meshes.clear(); - - for (int i = 0; i < _meshes.size(); i++) { - RID mesh = RID(meshs[i]); - - _meshes.push_back(mesh); - } -} - -//Collider -RID PropInstance::collider_get(const int index) { - ERR_FAIL_INDEX_V(index, _colliders.size(), RID()); - - return _colliders[index]; -} - -void PropInstance::collider_add(const RID value) { - _colliders.push_back(value); -} - -int PropInstance::collider_get_num() const { - return _colliders.size(); -} - -void PropInstance::colliders_clear() { - _colliders.clear(); -} - -Vector PropInstance::colliders_get() { - Vector r; - for (int i = 0; i < _colliders.size(); i++) { - r.push_back(_colliders[i]); - } - return r; -} - -void PropInstance::colliders_set(const Vector &colliders) { - _colliders.clear(); - - for (int i = 0; i < colliders.size(); i++) { - RID collider = (colliders[i]); - - _colliders.push_back(collider); - } -} - -float PropInstance::get_first_lod_distance_squared() { - return _first_lod_distance_squared; -} -void PropInstance::set_first_lod_distance_squared(const float dist) { - _first_lod_distance_squared = dist; -} - -float PropInstance::get_lod_reduction_distance_squared() { - return _lod_reduction_distance_squared; -} -void PropInstance::set_lod_reduction_distance_squared(const float dist) { - _lod_reduction_distance_squared = dist; -} - -void PropInstance::free_meshes() { -} -void PropInstance::free_colliders() { -} - void PropInstance::init_materials() { call("_init_materials"); } @@ -227,12 +53,6 @@ void PropInstance::_build() { _building = true; _build_queued = false; - if (!_job.is_valid()) { - _job = Ref(memnew(PropInstancePropJob())); - } - - _job->set_prop_instace(this); - if (!is_inside_tree()) { return; } @@ -342,21 +162,10 @@ void PropInstance::prop_preprocess(Transform transform, const Ref &pro PropInstance::PropInstance() { _build_queued = false; _building = false; - -#ifdef TEXTURE_PACKER_PRESENT - _merge_textures = true; -#endif - - _first_lod_distance_squared = 20; - _lod_reduction_distance_squared = 10; } PropInstance::~PropInstance() { - _job.unref(); - _prop_data.unref(); - - _materials.clear(); } void PropInstance::_notification(int p_what) { @@ -367,12 +176,6 @@ void PropInstance::_notification(int p_what) { } } case NOTIFICATION_EXIT_TREE: { - if (_job.is_valid()) { - _job->set_cancelled(true); - } - - free_meshes(); - free_colliders(); } } } @@ -382,59 +185,6 @@ void PropInstance::_bind_methods() { ClassDB::bind_method(D_METHOD("set_prop_data", "value"), &PropInstance::set_prop_data); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "prop_data", PROPERTY_HINT_RESOURCE_TYPE, "PropData"), "set_prop_data", "get_prop_data"); - ClassDB::bind_method(D_METHOD("get_job"), &PropInstance::get_job); - ClassDB::bind_method(D_METHOD("set_job", "value"), &PropInstance::set_job); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "job", PROPERTY_HINT_RESOURCE_TYPE, "PropInstanceJob", 0), "set_job", "get_job"); - -#ifdef TEXTURE_PACKER_PRESENT - ClassDB::bind_method(D_METHOD("get_merge_textures"), &PropInstance::get_merge_textures); - ClassDB::bind_method(D_METHOD("set_merge_textures", "value"), &PropInstance::set_merge_textures); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "merge_textures"), "set_merge_textures", "get_merge_textures"); -#endif - - ///Materials - ClassDB::bind_method(D_METHOD("material_get", "index"), &PropInstance::material_get); - ClassDB::bind_method(D_METHOD("material_add", "value"), &PropInstance::material_add); - ClassDB::bind_method(D_METHOD("material_get_num"), &PropInstance::material_get_num); - ClassDB::bind_method(D_METHOD("materials_clear"), &PropInstance::materials_clear); - - ClassDB::bind_method(D_METHOD("materials_get"), &PropInstance::materials_get); - ClassDB::bind_method(D_METHOD("materials_set"), &PropInstance::materials_set); - ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "materials", PROPERTY_HINT_NONE, "17/17:Material", PROPERTY_USAGE_DEFAULT, "Material"), "materials_set", "materials_get"); - - //Meshes - ClassDB::bind_method(D_METHOD("mesh_get", "index"), &PropInstance::mesh_get); - ClassDB::bind_method(D_METHOD("mesh_add", "value"), &PropInstance::mesh_add); - ClassDB::bind_method(D_METHOD("mesh_get_num"), &PropInstance::mesh_get_num); - ClassDB::bind_method(D_METHOD("meshs_clear"), &PropInstance::meshs_clear); - - ClassDB::bind_method(D_METHOD("meshes_get"), &PropInstance::meshes_get); - ClassDB::bind_method(D_METHOD("meshes_set"), &PropInstance::meshes_set); - ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "meshes", PROPERTY_HINT_NONE, "", 0), "meshes_set", "meshes_get"); - - //Colliders - ClassDB::bind_method(D_METHOD("collider_get", "index"), &PropInstance::collider_get); - ClassDB::bind_method(D_METHOD("collider_add", "value"), &PropInstance::collider_add); - ClassDB::bind_method(D_METHOD("collider_get_num"), &PropInstance::collider_get_num); - ClassDB::bind_method(D_METHOD("colliders_clear"), &PropInstance::colliders_clear); - - ClassDB::bind_method(D_METHOD("colliders_get"), &PropInstance::colliders_get); - ClassDB::bind_method(D_METHOD("colliders_set"), &PropInstance::colliders_set); - ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "colliders", PROPERTY_HINT_NONE, "", 0), "colliders_set", "colliders_get"); - - //--- - ClassDB::bind_method(D_METHOD("get_first_lod_distance_squared"), &PropInstance::get_first_lod_distance_squared); - ClassDB::bind_method(D_METHOD("set_first_lod_distance_squared", "value"), &PropInstance::set_first_lod_distance_squared); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "first_lod_distance_squared"), "set_first_lod_distance_squared", "get_first_lod_distance_squared"); - - ClassDB::bind_method(D_METHOD("get_lod_reduction_distance_squared"), &PropInstance::get_lod_reduction_distance_squared); - ClassDB::bind_method(D_METHOD("set_lod_reduction_distance_squared", "value"), &PropInstance::set_lod_reduction_distance_squared); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "lod_reduction_distance_squared"), "set_lod_reduction_distance_squared", "get_lod_reduction_distance_squared"); - - //--- - ClassDB::bind_method(D_METHOD("free_meshes"), &PropInstance::free_meshes); - ClassDB::bind_method(D_METHOD("free_colliders"), &PropInstance::free_colliders); - //--- BIND_VMETHOD(MethodInfo("_init_materials")); diff --git a/prop_instance.h b/prop_instance.h index 5d778d8..20b7b0f 100644 --- a/prop_instance.h +++ b/prop_instance.h @@ -35,12 +35,8 @@ SOFTWARE. #include "core/math/vector3.h" -#include "prop_instance_prop_job.h" - #include "props/prop_data.h" -class MeshDataInstance; - class PropInstance : public Spatial { GDCLASS(PropInstance, Spatial); @@ -48,57 +44,13 @@ public: Ref get_prop_data(); void set_prop_data(const Ref &data); - Ref get_job(); - void set_job(const Ref &job); - -#ifdef TEXTURE_PACKER_PRESENT - bool get_merge_textures() const; - void set_merge_textures(const bool value); -#endif - - ///Materials - Ref material_get(const int index); - void material_add(const Ref &value); - int material_get_num() const; - void materials_clear(); - - Vector materials_get(); - void materials_set(const Vector &materials); - - //Meshes - RID mesh_get(const int index); - void mesh_add(const RID value); - int mesh_get_num() const; - void meshs_clear(); - - Vector meshes_get(); - void meshes_set(const Vector &meshes); - - //Colliders - RID collider_get(const int index); - void collider_add(const RID value); - int collider_get_num() const; - void colliders_clear(); - - Vector colliders_get(); - void colliders_set(const Vector &colliders); - - float get_first_lod_distance_squared(); - void set_first_lod_distance_squared(const float dist); - - float get_lod_reduction_distance_squared(); - void set_lod_reduction_distance_squared(const float dist); - - void free_meshes(); - void free_colliders(); - void init_materials(); virtual void _init_materials(); void build(); void queue_build(); void build_finished(); - + virtual void _build(); virtual void _build_finished(); @@ -111,24 +63,11 @@ protected: void _notification(int p_what); static void _bind_methods(); -private: +protected: Ref _prop_data; bool _build_queued; bool _building; - - Ref _job; - -#ifdef TEXTURE_PACKER_PRESENT - bool _merge_textures; -#endif - - Vector > _materials; - Vector _meshes; - Vector _colliders; - - float _first_lod_distance_squared; - float _lod_reduction_distance_squared; }; #endif diff --git a/prop_instance_merger.cpp b/prop_instance_merger.cpp new file mode 100644 index 0000000..1001d97 --- /dev/null +++ b/prop_instance_merger.cpp @@ -0,0 +1,403 @@ +#include "prop_instance_merger.h" + +#include "../mesh_data_resource/nodes/mesh_data_instance.h" + +//#include "../thread_pool/thread_pool.h" + +#include "core/version.h" + +#if VERSION_MAJOR > 3 +#include "core/config/engine.h" + +#define VARIANT_ARRAY_GET(arr) \ + Vector r; \ + for (int i = 0; i < arr.size(); i++) { \ + r.push_back(arr[i]); \ + } \ + return r; + +#include "servers/rendering_server.h" +typedef class RenderingServer VS; + +#else +#include "core/engine.h" + +#define VARIANT_ARRAY_GET(arr) \ + Vector r; \ + for (int i = 0; i < arr.size(); i++) { \ + r.push_back(arr[i].get_ref_ptr()); \ + } \ + return r; + +#include "servers/visual_server.h" + +#endif + +#if MESH_DATA_RESOURCE_PRESENT +//define PROPS_PRESENT, so things compile. That module's scsub will define this too while compiling, +//but not when included from here. +#define PROPS_PRESENT 1 +#include "../mesh_data_resource/props/prop_data_mesh_data.h" +#endif + +#include "./props/prop_data_entry.h" +#include "./props/prop_data_light.h" +#include "./props/prop_data_prop.h" +#include "./props/prop_data_scene.h" + +Ref PropInstanceMerger::get_job() { + return _job; +} +void PropInstanceMerger::set_job(const Ref &job) { + _job = job; +} + +#ifdef TEXTURE_PACKER_PRESENT +bool PropInstanceMerger::get_merge_textures() const { + return _merge_textures; +} + +void PropInstanceMerger::set_merge_textures(const bool value) { + _merge_textures = value; +} +#endif + +//Materials +Ref PropInstanceMerger::material_get(const int index) { + ERR_FAIL_INDEX_V(index, _materials.size(), Ref(NULL)); + + return _materials[index]; +} + +void PropInstanceMerger::material_add(const Ref &value) { + ERR_FAIL_COND(!value.is_valid()); + + _materials.push_back(value); +} + +int PropInstanceMerger::material_get_num() const { + return _materials.size(); +} + +void PropInstanceMerger::materials_clear() { + _materials.clear(); +} + +Vector PropInstanceMerger::materials_get() { + VARIANT_ARRAY_GET(_materials); +} + +void PropInstanceMerger::materials_set(const Vector &materials) { + _materials.clear(); + + for (int i = 0; i < materials.size(); i++) { + Ref material = Ref(materials[i]); + + _materials.push_back(material); + } +} + +//Meshes +RID PropInstanceMerger::mesh_get(const int index) { + ERR_FAIL_INDEX_V(index, _meshes.size(), RID()); + + return _meshes[index]; +} + +void PropInstanceMerger::mesh_add(const RID value) { + _meshes.push_back(value); +} + +int PropInstanceMerger::mesh_get_num() const { + return _meshes.size(); +} + +void PropInstanceMerger::meshs_clear() { + _meshes.clear(); +} + +Vector PropInstanceMerger::meshes_get() { + Vector r; + for (int i = 0; i < _meshes.size(); i++) { + r.push_back(_meshes[i]); + } + return r; +} + +void PropInstanceMerger::meshes_set(const Vector &meshs) { + _meshes.clear(); + + for (int i = 0; i < _meshes.size(); i++) { + RID mesh = RID(meshs[i]); + + _meshes.push_back(mesh); + } +} + +//Collider +RID PropInstanceMerger::collider_get(const int index) { + ERR_FAIL_INDEX_V(index, _colliders.size(), RID()); + + return _colliders[index]; +} + +void PropInstanceMerger::collider_add(const RID value) { + _colliders.push_back(value); +} + +int PropInstanceMerger::collider_get_num() const { + return _colliders.size(); +} + +void PropInstanceMerger::colliders_clear() { + _colliders.clear(); +} + +Vector PropInstanceMerger::colliders_get() { + Vector r; + for (int i = 0; i < _colliders.size(); i++) { + r.push_back(_colliders[i]); + } + return r; +} + +void PropInstanceMerger::colliders_set(const Vector &colliders) { + _colliders.clear(); + + for (int i = 0; i < colliders.size(); i++) { + RID collider = (colliders[i]); + + _colliders.push_back(collider); + } +} + +float PropInstanceMerger::get_first_lod_distance_squared() { + return _first_lod_distance_squared; +} +void PropInstanceMerger::set_first_lod_distance_squared(const float dist) { + _first_lod_distance_squared = dist; +} + +float PropInstanceMerger::get_lod_reduction_distance_squared() { + return _lod_reduction_distance_squared; +} +void PropInstanceMerger::set_lod_reduction_distance_squared(const float dist) { + _lod_reduction_distance_squared = dist; +} + +void PropInstanceMerger::free_meshes() { +} +void PropInstanceMerger::free_colliders() { +} + +void PropInstanceMerger::_init_materials() { +} + +void PropInstanceMerger::_build() { + _building = true; + _build_queued = false; + + if (!_job.is_valid()) { + _job = Ref(memnew(PropInstancePropJob())); + } + + _job->set_prop_instace(this); + + if (!is_inside_tree()) { + return; + } + + for (int i = 0; i < get_child_count(); ++i) { + Node *n = get_child(i); + + //this way we won't delete the user's nodes + if (n->get_owner() == NULL) { + n->queue_delete(); + } + } + + if (!_prop_data.is_valid()) + return; + + prop_preprocess(Transform(), _prop_data); +} + +void PropInstanceMerger::_build_finished() { +} + +void PropInstanceMerger::prop_preprocess(Transform transform, const Ref &prop) { + ERR_FAIL_COND(!prop.is_valid()); + + int count = prop->get_prop_count(); + for (int i = 0; i < count; ++i) { + Ref e = prop->get_prop(i); + + if (!e.is_valid()) + continue; + + Transform t = transform * e->get_transform(); + + Ref prop_entry_data = e; + + if (prop_entry_data.is_valid()) { + Ref p = prop_entry_data->get_prop(); + + if (!p.is_valid()) + continue; + + prop_preprocess(t, p); + + continue; + } + + Ref scene_data = e; + + if (scene_data.is_valid()) { + Ref sc = scene_data->get_scene(); + + if (!sc.is_valid()) + continue; + + Node *n = sc->instance(); + add_child(n); + n->set_owner(this); + + Spatial *sp = Object::cast_to(n); + + if (sp) { + sp->set_transform(t); + } + + continue; + } + + /* + //Will create a Terralight node, and prop + //PropDataLight could use standard godot light nodes + Ref light_data = entry; + + if (light_data.is_valid()) { + Ref light; + light.instance(); + + light->set_world_position(wp.x / get_voxel_scale(), wp.y / get_voxel_scale(), wp.z / get_voxel_scale()); + light->set_color(light_data->get_light_color()); + light->set_size(light_data->get_light_size()); + + light_add(light); + + continue; + } + */ + +#if MESH_DATA_RESOURCE_PRESENT + Ref mesh_data = e; + + if (mesh_data.is_valid()) { + Ref mdr = mesh_data->get_mesh(); + + if (!mdr.is_valid()) + continue; + + //add to job + //job could merge textures if needed + //chunk->mesh_data_resource_add(t, mdr, mesh_data->get_texture()); + + continue; + } +#endif + } +} + +PropInstanceMerger::PropInstanceMerger() { + _build_queued = false; + _building = false; + +#ifdef TEXTURE_PACKER_PRESENT + _merge_textures = true; +#endif + + _first_lod_distance_squared = 20; + _lod_reduction_distance_squared = 10; +} + +PropInstanceMerger::~PropInstanceMerger() { + _job.unref(); + + _prop_data.unref(); + + _materials.clear(); +} + +void PropInstanceMerger::_notification(int p_what) { + switch (p_what) { + case NOTIFICATION_ENTER_TREE: { + if (_prop_data.is_valid()) { + build(); + } + } + case NOTIFICATION_EXIT_TREE: { + if (_job.is_valid()) { + _job->set_cancelled(true); + } + + free_meshes(); + free_colliders(); + } + } +} + +void PropInstanceMerger::_bind_methods() { + ClassDB::bind_method(D_METHOD("get_job"), &PropInstanceMerger::get_job); + ClassDB::bind_method(D_METHOD("set_job", "value"), &PropInstanceMerger::set_job); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "job", PROPERTY_HINT_RESOURCE_TYPE, "PropInstanceJob", 0), "set_job", "get_job"); + +#ifdef TEXTURE_PACKER_PRESENT + ClassDB::bind_method(D_METHOD("get_merge_textures"), &PropInstanceMerger::get_merge_textures); + ClassDB::bind_method(D_METHOD("set_merge_textures", "value"), &PropInstanceMerger::set_merge_textures); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "merge_textures"), "set_merge_textures", "get_merge_textures"); +#endif + + ///Materials + ClassDB::bind_method(D_METHOD("material_get", "index"), &PropInstanceMerger::material_get); + ClassDB::bind_method(D_METHOD("material_add", "value"), &PropInstanceMerger::material_add); + ClassDB::bind_method(D_METHOD("material_get_num"), &PropInstanceMerger::material_get_num); + ClassDB::bind_method(D_METHOD("materials_clear"), &PropInstanceMerger::materials_clear); + + ClassDB::bind_method(D_METHOD("materials_get"), &PropInstanceMerger::materials_get); + ClassDB::bind_method(D_METHOD("materials_set"), &PropInstanceMerger::materials_set); + ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "materials", PROPERTY_HINT_NONE, "17/17:Material", PROPERTY_USAGE_DEFAULT, "Material"), "materials_set", "materials_get"); + + //Meshes + ClassDB::bind_method(D_METHOD("mesh_get", "index"), &PropInstanceMerger::mesh_get); + ClassDB::bind_method(D_METHOD("mesh_add", "value"), &PropInstanceMerger::mesh_add); + ClassDB::bind_method(D_METHOD("mesh_get_num"), &PropInstanceMerger::mesh_get_num); + ClassDB::bind_method(D_METHOD("meshs_clear"), &PropInstanceMerger::meshs_clear); + + ClassDB::bind_method(D_METHOD("meshes_get"), &PropInstanceMerger::meshes_get); + ClassDB::bind_method(D_METHOD("meshes_set"), &PropInstanceMerger::meshes_set); + ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "meshes", PROPERTY_HINT_NONE, "", 0), "meshes_set", "meshes_get"); + + //Colliders + ClassDB::bind_method(D_METHOD("collider_get", "index"), &PropInstanceMerger::collider_get); + ClassDB::bind_method(D_METHOD("collider_add", "value"), &PropInstanceMerger::collider_add); + ClassDB::bind_method(D_METHOD("collider_get_num"), &PropInstanceMerger::collider_get_num); + ClassDB::bind_method(D_METHOD("colliders_clear"), &PropInstanceMerger::colliders_clear); + + ClassDB::bind_method(D_METHOD("colliders_get"), &PropInstanceMerger::colliders_get); + ClassDB::bind_method(D_METHOD("colliders_set"), &PropInstanceMerger::colliders_set); + ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "colliders", PROPERTY_HINT_NONE, "", 0), "colliders_set", "colliders_get"); + + //--- + ClassDB::bind_method(D_METHOD("get_first_lod_distance_squared"), &PropInstanceMerger::get_first_lod_distance_squared); + ClassDB::bind_method(D_METHOD("set_first_lod_distance_squared", "value"), &PropInstanceMerger::set_first_lod_distance_squared); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "first_lod_distance_squared"), "set_first_lod_distance_squared", "get_first_lod_distance_squared"); + + ClassDB::bind_method(D_METHOD("get_lod_reduction_distance_squared"), &PropInstanceMerger::get_lod_reduction_distance_squared); + ClassDB::bind_method(D_METHOD("set_lod_reduction_distance_squared", "value"), &PropInstanceMerger::set_lod_reduction_distance_squared); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "lod_reduction_distance_squared"), "set_lod_reduction_distance_squared", "get_lod_reduction_distance_squared"); + + //--- + ClassDB::bind_method(D_METHOD("free_meshes"), &PropInstanceMerger::free_meshes); + ClassDB::bind_method(D_METHOD("free_colliders"), &PropInstanceMerger::free_colliders); +} diff --git a/prop_instance_merger.h b/prop_instance_merger.h new file mode 100644 index 0000000..2626d6b --- /dev/null +++ b/prop_instance_merger.h @@ -0,0 +1,128 @@ +/* +Copyright (c) 2020 Péter Magyar + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +#ifndef PROP_INSTANCE_MERGER_H +#define PROP_INSTANCE_MERGER_H + +#include "prop_instance.h" + +#include "core/version.h" + +#if VERSION_MAJOR < 4 +#include "scene/3d/spatial.h" +#else +#include "scene/3d/node_3d.h" + +#define Spatial Node3D +#endif + +#include "core/math/vector3.h" + +#include "prop_instance_prop_job.h" + +#include "props/prop_data.h" + +class MeshDataInstance; + +class PropInstanceMerger : public PropInstance { + GDCLASS(PropInstanceMerger, PropInstance); + +public: + Ref get_job(); + void set_job(const Ref &job); + +#ifdef TEXTURE_PACKER_PRESENT + bool get_merge_textures() const; + void set_merge_textures(const bool value); +#endif + + ///Materials + Ref material_get(const int index); + void material_add(const Ref &value); + int material_get_num() const; + void materials_clear(); + + Vector materials_get(); + void materials_set(const Vector &materials); + + //Meshes + RID mesh_get(const int index); + void mesh_add(const RID value); + int mesh_get_num() const; + void meshs_clear(); + + Vector meshes_get(); + void meshes_set(const Vector &meshes); + + //Colliders + RID collider_get(const int index); + void collider_add(const RID value); + int collider_get_num() const; + void colliders_clear(); + + Vector colliders_get(); + void colliders_set(const Vector &colliders); + + float get_first_lod_distance_squared(); + void set_first_lod_distance_squared(const float dist); + + float get_lod_reduction_distance_squared(); + void set_lod_reduction_distance_squared(const float dist); + + void free_meshes(); + void free_colliders(); + + virtual void _init_materials(); + + virtual void _build(); + virtual void _build_finished(); + + void prop_preprocess(Transform tarnsform, const Ref &prop); + + PropInstanceMerger(); + ~PropInstanceMerger(); + +protected: + void _notification(int p_what); + static void _bind_methods(); + +private: + Ref _prop_data; + + bool _build_queued; + bool _building; + + Ref _job; + +#ifdef TEXTURE_PACKER_PRESENT + bool _merge_textures; +#endif + + Vector > _materials; + Vector _meshes; + Vector _colliders; + + float _first_lod_distance_squared; + float _lod_reduction_distance_squared; +}; + +#endif diff --git a/register_types.cpp b/register_types.cpp index 94897de..072aa1a 100644 --- a/register_types.cpp +++ b/register_types.cpp @@ -41,6 +41,7 @@ SOFTWARE. #include "prop_ess_entity.h" #include "prop_instance.h" +#include "prop_instance_merger.h" #include "prop_instance_job.h" #include "prop_instance_prop_job.h" @@ -71,6 +72,7 @@ void register_props_types() { ClassDB::register_class(); ClassDB::register_class(); + ClassDB::register_class(); ClassDB::register_class();