From 17b9accd0c922738d91d839bdb166871c9e9ae19 Mon Sep 17 00:00:00 2001 From: Marc Gilleron Date: Mon, 20 Nov 2017 20:54:26 +0100 Subject: [PATCH] Implement per-instance custom bounding box # Conflicts: # servers/visual/visual_server_scene.h --- servers/visual/visual_server_raster.h | 2 + servers/visual/visual_server_scene.cpp | 51 ++++++++++++++++++++++++-- servers/visual/visual_server_scene.h | 7 ++++ servers/visual/visual_server_wrap_mt.h | 1 + servers/visual_server.h | 2 + 5 files changed, 59 insertions(+), 4 deletions(-) diff --git a/servers/visual/visual_server_raster.h b/servers/visual/visual_server_raster.h index 08a0cfa269..7551485919 100644 --- a/servers/visual/visual_server_raster.h +++ b/servers/visual/visual_server_raster.h @@ -504,6 +504,8 @@ public: BIND3(instance_set_surface_material, RID, int, RID) BIND2(instance_set_visible, RID, bool) + BIND2(instance_set_custom_aabb, RID, AABB) + BIND2(instance_attach_skeleton, RID, RID) BIND2(instance_set_exterior, RID, bool) diff --git a/servers/visual/visual_server_scene.cpp b/servers/visual/visual_server_scene.cpp index 4febd1a61b..5b1eb8357d 100644 --- a/servers/visual/visual_server_scene.cpp +++ b/servers/visual/visual_server_scene.cpp @@ -587,6 +587,36 @@ void VisualServerScene::instance_set_visible(RID p_instance, bool p_visible) { } } +inline bool is_geometry_instance(VisualServer::InstanceType p_type) { + return p_type == VS::INSTANCE_MESH || p_type == VS::INSTANCE_MULTIMESH || p_type == VS::INSTANCE_PARTICLES || p_type == VS::INSTANCE_IMMEDIATE; +} + +void VisualServerScene::instance_set_custom_aabb(RID p_instance, AABB p_aabb) { + + Instance *instance = instance_owner.get(p_instance); + ERR_FAIL_COND(!instance); + ERR_FAIL_COND(!is_geometry_instance(instance->base_type)); + + if(p_aabb != AABB()) { + + // Set custom AABB + if (instance->custom_aabb == NULL) + instance->custom_aabb = memnew(AABB); + *instance->custom_aabb = p_aabb; + + } else { + + // Clear custom AABB + if (instance->custom_aabb != NULL) { + memdelete(instance->custom_aabb); + instance->custom_aabb = NULL; + } + } + + if (instance->scenario) + _instance_queue_update(instance, true, false); +} + void VisualServerScene::instance_attach_skeleton(RID p_instance, RID p_skeleton) { Instance *instance = instance_owner.get(p_instance); @@ -828,23 +858,35 @@ void VisualServerScene::_update_instance_aabb(Instance *p_instance) { } break; case VisualServer::INSTANCE_MESH: { - new_aabb = VSG::storage->mesh_get_aabb(p_instance->base, p_instance->skeleton); + if (p_instance->custom_aabb) + new_aabb = *p_instance->custom_aabb; + else + new_aabb = VSG::storage->mesh_get_aabb(p_instance->base, p_instance->skeleton); } break; case VisualServer::INSTANCE_MULTIMESH: { - new_aabb = VSG::storage->multimesh_get_aabb(p_instance->base); + if (p_instance->custom_aabb) + new_aabb = *p_instance->custom_aabb; + else + new_aabb = VSG::storage->multimesh_get_aabb(p_instance->base); } break; case VisualServer::INSTANCE_IMMEDIATE: { - new_aabb = VSG::storage->immediate_get_aabb(p_instance->base); + if (p_instance->custom_aabb) + new_aabb = *p_instance->custom_aabb; + else + new_aabb = VSG::storage->immediate_get_aabb(p_instance->base); } break; case VisualServer::INSTANCE_PARTICLES: { - new_aabb = VSG::storage->particles_get_aabb(p_instance->base); + if (p_instance->custom_aabb) + new_aabb = *p_instance->custom_aabb; + else + new_aabb = VSG::storage->particles_get_aabb(p_instance->base); } break; case VisualServer::INSTANCE_LIGHT: { @@ -866,6 +908,7 @@ void VisualServerScene::_update_instance_aabb(Instance *p_instance) { default: {} } + // This is why I didn't re-use Instance::aabb to implement custom AABBs if (p_instance->extra_margin) new_aabb.grow_by(p_instance->extra_margin); diff --git a/servers/visual/visual_server_scene.h b/servers/visual/visual_server_scene.h index 2738fa058d..d075be76ca 100644 --- a/servers/visual/visual_server_scene.h +++ b/servers/visual/visual_server_scene.h @@ -197,6 +197,7 @@ public: AABB aabb; AABB transformed_aabb; + AABB *custom_aabb; // would using aabb directly with a bool be better? float extra_margin; uint32_t object_ID; @@ -251,12 +252,16 @@ public: last_frame_pass = 0; version = 1; base_data = NULL; + + custom_aabb = NULL; } ~Instance() { if (base_data) memdelete(base_data); + if (custom_aabb) + memdelete(custom_aabb); } }; @@ -460,6 +465,8 @@ public: virtual void instance_set_surface_material(RID p_instance, int p_surface, RID p_material); virtual void instance_set_visible(RID p_instance, bool p_visible); + virtual void instance_set_custom_aabb(RID p_insatnce, AABB aabb); + virtual void instance_attach_skeleton(RID p_instance, RID p_skeleton); virtual void instance_set_exterior(RID p_instance, bool p_enabled); diff --git a/servers/visual/visual_server_wrap_mt.h b/servers/visual/visual_server_wrap_mt.h index 509b77cf9c..e120eb5ad3 100644 --- a/servers/visual/visual_server_wrap_mt.h +++ b/servers/visual/visual_server_wrap_mt.h @@ -424,6 +424,7 @@ public: FUNC3(instance_set_blend_shape_weight, RID, int, float) FUNC3(instance_set_surface_material, RID, int, RID) FUNC2(instance_set_visible, RID, bool) + FUNC2(instance_set_custom_aabb, RID, AABB) FUNC2(instance_attach_skeleton, RID, RID) FUNC2(instance_set_exterior, RID, bool) diff --git a/servers/visual_server.h b/servers/visual_server.h index 3edde7ec85..c4b1583009 100644 --- a/servers/visual_server.h +++ b/servers/visual_server.h @@ -753,6 +753,8 @@ public: virtual void instance_set_surface_material(RID p_instance, int p_surface, RID p_material) = 0; virtual void instance_set_visible(RID p_instance, bool p_visible) = 0; + virtual void instance_set_custom_aabb(RID p_instance, AABB aabb) = 0; + virtual void instance_attach_skeleton(RID p_instance, RID p_skeleton) = 0; virtual void instance_set_exterior(RID p_instance, bool p_enabled) = 0;