From 7ccdbd474c95d439f3891a4c88b26f8c0a9623fd Mon Sep 17 00:00:00 2001 From: Relintai Date: Wed, 25 Aug 2021 20:37:37 +0200 Subject: [PATCH] Fixed collision shape positions in PropInstanceMerger. Also improved it's collision shape / physics body handling. --- prop_instance_merger.cpp | 32 +++++++++++++++++++++++--------- prop_instance_merger.h | 7 ++++++- prop_instance_prop_job.cpp | 18 ++++++++++-------- prop_instance_prop_job.h | 7 ++++++- 4 files changed, 45 insertions(+), 19 deletions(-) diff --git a/prop_instance_merger.cpp b/prop_instance_merger.cpp index 03a1aea..56587cf 100644 --- a/prop_instance_merger.cpp +++ b/prop_instance_merger.cpp @@ -271,7 +271,7 @@ RID PropInstanceMerger::collider_shape_rid_get(const int index) { return _colliders[index].shape_rid; } -int PropInstanceMerger::collider_add(const Transform &local_transform, const Ref &shape, const RID &shape_rid, const RID &body) { +int PropInstanceMerger::collider_add(const Transform &local_transform, const Ref &shape, const RID &shape_rid, const RID &body, const bool owns_shape) { ERR_FAIL_COND_V(!shape.is_valid() && shape_rid == RID(), 0); int index = _colliders.size(); @@ -281,6 +281,7 @@ int PropInstanceMerger::collider_add(const Transform &local_transform, const Ref e.body = body; e.shape = shape; e.shape_rid = shape_rid; + e.owns_shape = owns_shape; _colliders.push_back(e); @@ -449,8 +450,9 @@ void PropInstanceMerger::draw_debug_mdr_colliders() { for (int i = 0; i < collider_get_num(); ++i) { Ref shape = collider_shape_get(i); - if (!shape.is_valid()) + if (!shape.is_valid()) { continue; + } Transform t = collider_local_transform_get(i); @@ -481,9 +483,16 @@ void PropInstanceMerger::free_meshes() { void PropInstanceMerger::free_colliders() { for (int i = 0; i < _colliders.size(); ++i) { - PhysicsServer::get_singleton()->free(_colliders[i].body); + ColliderBody &e = _colliders.write[i]; - _colliders.write[i].body = RID(); + PhysicsServer::get_singleton()->free(e.body); + + e.body = RID(); + + if (e.owns_shape) { + e.shape.unref(); + e.shape_rid = RID(); + } } } @@ -570,6 +579,8 @@ void PropInstanceMerger::_build_finished() { apply_lod_level(); check_auto_lod(); + notification(NOTIFICATION_TRANSFORM_CHANGED); + if (_build_queued) { call_deferred("build"); } @@ -618,7 +629,7 @@ void PropInstanceMerger::_prop_preprocess(Transform transform, const Refadd_collision_shape(tws, tt); + _job->add_collision_shape(tws, tt, true); } continue; @@ -840,9 +851,10 @@ void PropInstanceMerger::_notification(int p_what) { case NOTIFICATION_TRANSFORM_CHANGED: { Transform new_transform = get_global_transform(); - if (new_transform == _last_transform) { - break; - } + //Don't do this check, so this can be used to setmesh positions after a build + //if (new_transform == _last_transform) { + // break; + //} _last_transform = new_transform; @@ -863,7 +875,9 @@ void PropInstanceMerger::_notification(int p_what) { for (int i = 0; i < _colliders.size(); ++i) { const ColliderBody &c = _colliders[i]; - PhysicsServer::get_singleton()->body_set_shape_transform(c.body, 0, new_transform * c.transform); + if (c.body != RID()) { + PhysicsServer::get_singleton()->body_set_shape_transform(c.body, 0, new_transform * c.transform); + } } break; diff --git a/prop_instance_merger.h b/prop_instance_merger.h index 17e2ff5..8ddb7c1 100644 --- a/prop_instance_merger.h +++ b/prop_instance_merger.h @@ -92,7 +92,7 @@ public: RID collider_body_get(const int index); Ref collider_shape_get(const int index); RID collider_shape_rid_get(const int index); - int collider_add(const Transform &local_transform, const Ref &shape, const RID &shape_rid, const RID &body); + int collider_add(const Transform &local_transform, const Ref &shape, const RID &shape_rid, const RID &body, const bool owns_shape = false); int collider_get_num() const; void colliders_clear(); @@ -135,6 +135,11 @@ protected: RID body; Ref shape; RID shape_rid; + bool owns_shape; + + ColliderBody() { + owns_shape = false; + } }; struct MeshEntry { diff --git a/prop_instance_prop_job.cpp b/prop_instance_prop_job.cpp index 9ab9512..d0a596b 100644 --- a/prop_instance_prop_job.cpp +++ b/prop_instance_prop_job.cpp @@ -91,11 +91,12 @@ int PropInstancePropJob::get_jobs_step_count() const { return _job_steps.size(); } -void PropInstancePropJob::add_collision_shape(const Ref &shape, const Transform &transform) { +void PropInstancePropJob::add_collision_shape(const Ref &shape, const Transform &transform, const bool owns_shape) { CollisionShapeEntry e; e.shape = shape; e.transform = transform; + e.owns_shape = owns_shape; _collision_shapes.push_back(e); } @@ -214,10 +215,11 @@ void PropInstancePropJob::_reset() { void PropInstancePropJob::phase_physics_process() { //TODO this should only update the differences - for (int i = 0; i < _prop_instace->collider_get_num(); ++i) { - PhysicsServer::get_singleton()->free(_prop_instace->collider_body_get(i)); - } + //for (int i = 0; i < _prop_instace->collider_get_num(); ++i) { + // PhysicsServer::get_singleton()->free(_prop_instace->collider_body_get(i)); + //} + _prop_instace->free_colliders(); _prop_instace->colliders_clear(); for (int i = 0; i < _collision_shapes.size(); ++i) { @@ -233,7 +235,6 @@ void PropInstancePropJob::phase_physics_process() { //TODO store the layer mask somewhere PhysicsServer::get_singleton()->body_set_collision_layer(body, 1); - PhysicsServer::get_singleton()->body_set_collision_mask(body, 1); if (_prop_instace->is_inside_tree() && _prop_instace->is_inside_world()) { @@ -244,9 +245,9 @@ void PropInstancePropJob::phase_physics_process() { } } - PhysicsServer::get_singleton()->body_set_state(body, PhysicsServer::BODY_STATE_TRANSFORM, e.transform); + //PhysicsServer::get_singleton()->body_set_state(body, PhysicsServer::BODY_STATE_TRANSFORM, e.transform); - _prop_instace->collider_add(e.transform, e.shape, e.shape->get_rid(), body); + _prop_instace->collider_add(e.transform, e.shape, e.shape->get_rid(), body, e.owns_shape); } #if TOOLS_ENABLED @@ -322,7 +323,8 @@ void PropInstancePropJob::phase_prop() { PTWEntry &e = _prop_tiled_wall_datas.write[i]; Ref pdtw = e.data; - Transform t = pdtw->get_transform(); + //Transform t = pdtw->get_transform(); + Transform t = e.base_transform; _prop_mesher->add_tiled_wall_simple(pdtw->get_width(), pdtw->get_heigth(), t, pdtw->get_data(), _material_cache); } diff --git a/prop_instance_prop_job.h b/prop_instance_prop_job.h index 8cd67c0..d67191d 100644 --- a/prop_instance_prop_job.h +++ b/prop_instance_prop_job.h @@ -51,7 +51,7 @@ public: void add_jobs_step(const Ref &step); int get_jobs_step_count() const; - void add_collision_shape(const Ref &shape, const Transform &transform); + void add_collision_shape(const Ref &shape, const Transform &transform, const bool owns_shape = false); void clear_collision_shapes(); PropInstanceMerger *get_prop_instace(); @@ -115,6 +115,11 @@ protected: struct CollisionShapeEntry { Ref shape; Transform transform; + bool owns_shape; + + CollisionShapeEntry() { + owns_shape = false; + } }; Ref _material_cache;