New interface for PropInstance.

This commit is contained in:
Relintai 2021-04-26 18:04:52 +02:00
parent 669ab8e193
commit a429f71cb0
2 changed files with 326 additions and 75 deletions

View File

@ -8,8 +8,29 @@
#if VERSION_MAJOR > 3 #if VERSION_MAJOR > 3
#include "core/config/engine.h" #include "core/config/engine.h"
#define VARIANT_ARRAY_GET(arr) \
Vector<Variant> 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 #else
#include "core/engine.h" #include "core/engine.h"
#define VARIANT_ARRAY_GET(arr) \
Vector<Variant> 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 #endif
Ref<PropData> PropInstance::get_prop_data() { Ref<PropData> PropInstance::get_prop_data() {
@ -21,61 +42,170 @@ void PropInstance::set_prop_data(const Ref<PropData> &data) {
_prop_data = data; _prop_data = data;
build(); queue_build();
} }
bool PropInstance::get_auto_bake() const { Ref<PropInstanceJob> PropInstance::get_job() {
return _auto_bake; return _job;
} }
void PropInstance::set_auto_bake(const bool value) { void PropInstance::set_job(const Ref<PropInstanceJob> &job) {
_auto_bake = value; _job = job;
} }
bool PropInstance::get_snap_to_mesh() const { #ifdef TEXTURE_PACKER_PRESENT
return _snap_to_mesh; bool PropInstance::get_merge_textures() const {
} return _merge_textures;
void PropInstance::set_snap_to_mesh(const bool value) {
_snap_to_mesh = value;
} }
Vector3 PropInstance::get_snap_axis() const { void PropInstance::set_merge_textures(const bool value) {
return _snap_axis; _merge_textures = value;
} }
void PropInstance::set_snap_axis(const Vector3 &value) { #endif
_snap_axis = value;
//Materials
Ref<Material> PropInstance::material_get(const int index) {
ERR_FAIL_INDEX_V(index, _materials.size(), Ref<Material>(NULL));
return _materials[index];
} }
void PropInstance::bake() { void PropInstance::material_add(const Ref<Material> &value) {
_baking = true; ERR_FAIL_COND(!value.is_valid());
_bake_queued = false;
_materials.push_back(value);
}
int PropInstance::material_get_num() const {
return _materials.size();
}
void PropInstance::materials_clear() {
_materials.clear();
}
Vector<Variant> PropInstance::materials_get() {
VARIANT_ARRAY_GET(_materials);
}
void PropInstance::materials_set(const Vector<Variant> &materials) {
_materials.clear();
for (int i = 0; i < materials.size(); i++) {
Ref<Material> material = Ref<Material>(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<Variant> PropInstance::meshes_get() {
Vector<Variant> r;
for (int i = 0; i < _meshes.size(); i++) {
r.push_back(_meshes[i]);
}
return r;
}
void PropInstance::meshes_set(const Vector<Variant> &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<Variant> PropInstance::colliders_get() {
Vector<Variant> r;
for (int i = 0; i < _colliders.size(); i++) {
r.push_back(_colliders[i]);
}
return r;
}
void PropInstance::colliders_set(const Vector<Variant> &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");
}
void PropInstance::_init_materials() {
}
void PropInstance::build() {
_building = true;
_build_queued = false;
if (!_job.is_valid()) { if (!_job.is_valid()) {
_job.instance(); _job = Ref<PropInstanceJob>(memnew(PropInstancePropJob()));
} }
_job->set_prop_instace(this); _job->set_prop_instace(this);
}
void PropInstance::bake_finished() {
_baking = false;
if (_bake_queued) {
call_deferred("bake");
}
}
void PropInstance::queue_bake() {
if (!_bake_queued) {
_bake_queued = true;
if (!_baking) {
call_deferred("bake");
}
}
}
void PropInstance::build() {
if (!is_inside_tree()) { if (!is_inside_tree()) {
return; return;
} }
@ -107,20 +237,40 @@ void PropInstance::build() {
// n->set_owner(get_tree()->get_edited_scene_root()); // n->set_owner(get_tree()->get_edited_scene_root());
} }
} }
}
void PropInstance::queue_build() {
}
void PropInstance::build_finished() {
_building = false;
if (_build_queued) {
call_deferred("build");
}
}
void PropInstance::_build_finished() {
} }
PropInstance::PropInstance() { PropInstance::PropInstance() {
_baking = false; _build_queued = false;
_bake_queued = false; _building = false;
_snap_to_mesh = false;
_snap_axis = Vector3(0, -1, 0); #ifdef TEXTURE_PACKER_PRESENT
//_job.instance(); _merge_textures = true;
//_job->connect("completed", this, "bake_finished", Vector<Variant>(), Object::CONNECT_DEFERRED); #endif
_first_lod_distance_squared = 20;
_lod_reduction_distance_squared = 10;
} }
PropInstance::~PropInstance() { PropInstance::~PropInstance() {
//_job.unref(); _job.unref();
_prop_data.unref(); _prop_data.unref();
_materials.clear();
} }
void PropInstance::_notification(int p_what) { void PropInstance::_notification(int p_what) {
@ -130,6 +280,14 @@ void PropInstance::_notification(int p_what) {
build(); build();
} }
} }
case NOTIFICATION_EXIT_TREE: {
if (_job.is_valid()) {
_job->set_cancelled(true);
}
free_meshes();
free_colliders();
}
} }
} }
@ -138,19 +296,71 @@ void PropInstance::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_prop_data", "value"), &PropInstance::set_prop_data); 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"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "prop_data", PROPERTY_HINT_RESOURCE_TYPE, "PropData"), "set_prop_data", "get_prop_data");
ClassDB::bind_method(D_METHOD("get_auto_bake"), &PropInstance::get_auto_bake); ClassDB::bind_method(D_METHOD("get_job"), &PropInstance::get_job);
ClassDB::bind_method(D_METHOD("set_auto_bake", "value"), &PropInstance::set_auto_bake); ClassDB::bind_method(D_METHOD("set_job", "value"), &PropInstance::set_job);
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "auto_bake"), "set_auto_bake", "get_auto_bake"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "job", PROPERTY_HINT_RESOURCE_TYPE, "PropInstanceJob", 0), "set_job", "get_job");
ClassDB::bind_method(D_METHOD("get_snap_to_mesh"), &PropInstance::get_snap_to_mesh); #ifdef TEXTURE_PACKER_PRESENT
ClassDB::bind_method(D_METHOD("set_snap_to_mesh", "value"), &PropInstance::set_snap_to_mesh); ClassDB::bind_method(D_METHOD("get_merge_textures"), &PropInstance::get_merge_textures);
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "snap_to_mesh"), "set_snap_to_mesh", "get_snap_to_mesh"); 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
ClassDB::bind_method(D_METHOD("get_snap_axis"), &PropInstance::get_snap_axis); ///Materials
ClassDB::bind_method(D_METHOD("set_snap_axis", "value"), &PropInstance::set_snap_axis); ClassDB::bind_method(D_METHOD("material_get", "index"), &PropInstance::material_get);
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "snap_axis"), "set_snap_axis", "get_snap_axis"); 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("bake"), &PropInstance::bake); ClassDB::bind_method(D_METHOD("materials_get"), &PropInstance::materials_get);
ClassDB::bind_method(D_METHOD("queue_bake"), &PropInstance::queue_bake); ClassDB::bind_method(D_METHOD("materials_set"), &PropInstance::materials_set);
ClassDB::bind_method(D_METHOD("bake_finished"), &PropInstance::bake_finished); 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"));
ClassDB::bind_method(D_METHOD("init_materials"), &PropInstance::init_materials);
ClassDB::bind_method(D_METHOD("_init_materials"), &PropInstance::_init_materials);
//---
ClassDB::bind_method(D_METHOD("build"), &PropInstance::build);
ClassDB::bind_method(D_METHOD("queue_build"), &PropInstance::queue_build);
ClassDB::bind_method(D_METHOD("build_finished"), &PropInstance::build_finished);
BIND_VMETHOD(MethodInfo("_build_finished"));
ClassDB::bind_method(D_METHOD("_build_finished"), &PropInstance::_build_finished);
} }

View File

@ -48,20 +48,57 @@ public:
Ref<PropData> get_prop_data(); Ref<PropData> get_prop_data();
void set_prop_data(const Ref<PropData> &data); void set_prop_data(const Ref<PropData> &data);
bool get_auto_bake() const; Ref<PropInstanceJob> get_job();
void set_auto_bake(const bool value); void set_job(const Ref<PropInstanceJob> &job);
bool get_snap_to_mesh() const; #ifdef TEXTURE_PACKER_PRESENT
void set_snap_to_mesh(const bool value); bool get_merge_textures() const;
void set_merge_textures(const bool value);
#endif
Vector3 get_snap_axis() const; ///Materials
void set_snap_axis(const Vector3 &value); Ref<Material> material_get(const int index);
void material_add(const Ref<Material> &value);
int material_get_num() const;
void materials_clear();
void bake(); Vector<Variant> materials_get();
void queue_bake(); void materials_set(const Vector<Variant> &materials);
void bake_finished();
//Meshes
RID mesh_get(const int index);
void mesh_add(const RID value);
int mesh_get_num() const;
void meshs_clear();
Vector<Variant> meshes_get();
void meshes_set(const Vector<Variant> &meshes);
//Colliders
RID collider_get(const int index);
void collider_add(const RID value);
int collider_get_num() const;
void colliders_clear();
Vector<Variant> colliders_get();
void colliders_set(const Vector<Variant> &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 build();
void queue_build();
void build_finished();
virtual void _build_finished();
PropInstance(); PropInstance();
~PropInstance(); ~PropInstance();
@ -72,18 +109,22 @@ protected:
private: private:
Ref<PropData> _prop_data; Ref<PropData> _prop_data;
bool _auto_bake;
bool _bake_queued; bool _build_queued;
bool _baking; bool _building;
bool _snap_to_mesh;
Vector3 _snap_axis;
Ref<PropInstancePropJob> _job; Ref<PropInstancePropJob> _job;
bool _merge_extures; #ifdef TEXTURE_PACKER_PRESENT
Vector<Ref<Material> > _original_materials;//if !_merge_extures, just use this ? bool _merge_textures;
#endif
static HashMap<Ref<PropData>, Ref<Material> > _material_map; Vector<Ref<Material> > _materials;
Vector<RID> _meshes;
Vector<RID> _colliders;
float _first_lod_distance_squared;
float _lod_reduction_distance_squared;
}; };
#endif #endif