Browse Source

Merge pull request #12645 from Zylann/custom_aabb

Implement per-instance custom bounding box
Rémi Verschelde 7 years ago
parent
commit
0442bd6e18

+ 2 - 0
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)
 

+ 47 - 4
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: {}
 	}
 
+	// <Zylann> 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);
 

+ 7 - 0
servers/visual/visual_server_scene.h

@@ -197,6 +197,7 @@ public:
 
 		AABB aabb;
 		AABB transformed_aabb;
+		AABB *custom_aabb; // <Zylann> 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);
 

+ 1 - 0
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)

+ 2 - 0
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;