[Bf-blender-cvs] [3bdb65f5ed1] fracture_modifier: performance regression fix which reduces some static-static collision checking

Martin Felke noreply at git.blender.org
Thu Aug 10 18:55:27 CEST 2017


Commit: 3bdb65f5ed1a51ed7838ec897a707a990e0687d4
Author: Martin Felke
Date:   Thu Aug 10 18:55:07 2017 +0200
Branches: fracture_modifier
https://developer.blender.org/rB3bdb65f5ed1a51ed7838ec897a707a990e0687d4

performance regression fix which reduces some static-static collision checking

===================================================================

M	intern/rigidbody/RBI_api.h
M	intern/rigidbody/rb_bullet_api.cpp
M	source/blender/blenkernel/intern/rigidbody.c

===================================================================

diff --git a/intern/rigidbody/RBI_api.h b/intern/rigidbody/RBI_api.h
index 02447f8d1b8..da997a38f24 100644
--- a/intern/rigidbody/RBI_api.h
+++ b/intern/rigidbody/RBI_api.h
@@ -89,7 +89,7 @@ void RB_dworld_init_compounds(rbDynamicsWorld *world);
 
 /* Create a new dynamics world instance */
 // TODO: add args to set the type of constraint solvers, etc.
-rbDynamicsWorld *RB_dworld_new(const float gravity[3], void* blenderWorld, void *blenderScene, int (*callback)(void*, void*, void*, void*, void*),
+rbDynamicsWorld *RB_dworld_new(const float gravity[3], void* blenderWorld, void *blenderScene, int (*callback)(void*, void*, void*, void*, void*, bool),
 								void (*contactCallback)(rbContactPoint*, void *), void (*idCallbackOut)(void*, void*, int*, int*),
 								void (*tickCallback)(float, void *));
 
diff --git a/intern/rigidbody/rb_bullet_api.cpp b/intern/rigidbody/rb_bullet_api.cpp
index ef6941bd5a5..e67a88c7631 100644
--- a/intern/rigidbody/rb_bullet_api.cpp
+++ b/intern/rigidbody/rb_bullet_api.cpp
@@ -717,13 +717,13 @@ struct myResultCallback : public btCollisionWorld::ClosestRayResultCallback
 
 struct rbFilterCallback : public btOverlapFilterCallback
 {
-	int (*callback)(void* world, void* island1, void* island2, void* blenderOb1, void* blenderOb2);
+	int (*callback)(void* world, void* island1, void* island2, void* blenderOb1, void* blenderOb2, bool activate);
 
-	rbFilterCallback(int (*callback)(void* world, void* island1, void* island2, void* blenderOb1, void* blenderOb2)) {
+	rbFilterCallback(int (*callback)(void* world, void* island1, void* island2, void* blenderOb1, void* blenderOb2, bool activate)) {
 		this->callback = callback;
 	}
 
-	bool check_collision(rbRigidBody* rb0, rbRigidBody* rb1, bool collides) const
+	bool check_collision(rbRigidBody* rb0, rbRigidBody* rb1, bool activate, bool collides) const
 	{
 		if (!rb0 || !rb1)
 			return collides;
@@ -802,7 +802,7 @@ struct rbFilterCallback : public btOverlapFilterCallback
 
 			collides = collides && (bool)result;
 #endif
-			result = this->callback(rb0->world->blenderWorld, rb0->meshIsland, rb1->meshIsland, rb0->blenderOb, rb1->blenderOb);
+			result = this->callback(rb0->world->blenderWorld, rb0->meshIsland, rb1->meshIsland, rb0->blenderOb, rb1->blenderOb, activate);
 			collides = collides && (bool)result;
 		}
 
@@ -811,8 +811,8 @@ struct rbFilterCallback : public btOverlapFilterCallback
 
 	virtual bool needBroadphaseCollision(btBroadphaseProxy *proxy0, btBroadphaseProxy *proxy1) const
 	{
-		//rbRigidBody *rb0 = (rbRigidBody *)((btFractureBody *)proxy0->m_clientObject)->getUserPointer();
-		//rbRigidBody *rb1 = (rbRigidBody *)((btFractureBody *)proxy1->m_clientObject)->getUserPointer();
+		rbRigidBody *rb0 = (rbRigidBody *)((btFractureBody *)proxy0->m_clientObject)->getUserPointer();
+		rbRigidBody *rb1 = (rbRigidBody *)((btFractureBody *)proxy1->m_clientObject)->getUserPointer();
 		
 		bool collides;
 		collides = (proxy0->m_collisionFilterGroup &
@@ -822,7 +822,8 @@ struct rbFilterCallback : public btOverlapFilterCallback
 		           (proxy0->m_collisionFilterMask | btBroadphaseProxy::StaticFilter |
 		            btBroadphaseProxy::KinematicFilter));
 
-		return collides; //this->check_collision(rb0, rb1, collides);
+		//only apply to trigger and triggered, to improve performance, but do not actually activate
+		return this->check_collision(rb0, rb1, false, collides);
 	}
 };
 
@@ -927,14 +928,14 @@ bool CollisionFilterDispatcher::needsCollision(const btCollisionObject *body0, c
 
 	if (this->filterCallback)
 	{
-		return this->filterCallback->check_collision(rb0, rb1, true);
+		return this->filterCallback->check_collision(rb0, rb1, true, true);
 	}
 
 	return true;
 }
 
 //yuck, but need a handle for the world somewhere for collision callback...
-rbDynamicsWorld *RB_dworld_new(const float gravity[3], void* blenderWorld, void* blenderScene, int (*callback)(void *, void *, void *, void *, void *),
+rbDynamicsWorld *RB_dworld_new(const float gravity[3], void* blenderWorld, void* blenderScene, int (*callback)(void *, void *, void *, void *, void *, bool),
 							   void (*contactCallback)(rbContactPoint* cp, void *bworld), void (*idCallbackOut)(void*, void*, int*, int*),
 							   void (*tickCallback)(float timestep, void *bworld))
 {
diff --git a/source/blender/blenkernel/intern/rigidbody.c b/source/blender/blenkernel/intern/rigidbody.c
index a6f010b824e..33c0c09314a 100644
--- a/source/blender/blenkernel/intern/rigidbody.c
+++ b/source/blender/blenkernel/intern/rigidbody.c
@@ -2073,11 +2073,12 @@ static bool colgroup_check(int group1, int group2)
 	return false;
 }
 
-static void do_activate(Object* ob, Object *ob2, MeshIsland *mi_compare, RigidBodyWorld *rbw, MeshIsland *mi_trigger)
+static bool do_activate(Object* ob, Object *ob2, MeshIsland *mi_compare, RigidBodyWorld *rbw, MeshIsland *mi_trigger, bool activate)
 {
 	FractureModifierData *fmd;
 	bool valid = true;
 	bool antiValid = ob2->rigidbody_object->flag & RBO_FLAG_ANTI_TRIGGER;
+	bool wouldActivate = false;
 	MeshIsland *mi;
 
 	fmd = (FractureModifierData*)modifiers_findByType(ob, eModifierType_Fracture);
@@ -2103,12 +2104,14 @@ static void do_activate(Object* ob, Object *ob2, MeshIsland *mi_compare, RigidBo
 			if ((((rbo->flag & RBO_FLAG_KINEMATIC) || different_cluster) &&
 			     ((mi_compare == mi) || (same_cluster && !dissolve))) && valid)
 			{
-				if (rbo->physics_object) {
+				if (rbo->physics_object && activate) {
 					activateRigidbody(rbo, rbw, mi, ob);
 				}
+
+				wouldActivate = true;
 			}
 
-			if ((mi_compare == mi) && antiValid)
+			if ((mi_compare == mi) && antiValid && activate)
 			{
 				if (rbo->physics_object) {
 					BKE_deactivateRigidbody(rbo);
@@ -2122,16 +2125,19 @@ static void do_activate(Object* ob, Object *ob2, MeshIsland *mi_compare, RigidBo
 		bool antiValid = ob2->rigidbody_object->flag & RBO_FLAG_ANTI_TRIGGER;
 		RigidBodyOb* rbo = ob->rigidbody_object;
 
-		if (rbo && valid)
+		if (rbo && valid && activate)
 		{
 			activateRigidbody(rbo, rbw, NULL, ob);
+			wouldActivate = true;
 		}
 
-		if (rbo && antiValid)
+		if (rbo && antiValid && activate)
 		{
 			BKE_deactivateRigidbody(rbo);
 		}
 	}
+
+	return wouldActivate;
 }
 
 static int check_colgroup_ghost(Object* ob1, Object *ob2)
@@ -2185,12 +2191,12 @@ static bool check_constraint_island(FractureModifierData* fmd, MeshIsland *mi1,
 }
 
 /* this allows partial object activation, only some shards will be activated, called from bullet(!) */
-static int filterCallback(void* world, void* island1, void* island2, void *blenderOb1, void* blenderOb2) {
+static int filterCallback(void* world, void* island1, void* island2, void *blenderOb1, void* blenderOb2, bool activate) {
 	MeshIsland* mi1, *mi2;
 	RigidBodyWorld *rbw = (RigidBodyWorld*)world;
 	Object* ob1, *ob2;
 	int ob_index1 = -1, ob_index2 = -1;
-	bool validOb = true;
+	bool validOb = true, check_activate = false;
 
 	mi1 = (MeshIsland*)island1;
 	mi2 = (MeshIsland*)island2;
@@ -2271,12 +2277,12 @@ static int filterCallback(void* world, void* island1, void* island2, void *blend
 	{
 		if (ob1->rigidbody_object->flag & RBO_FLAG_USE_KINEMATIC_DEACTIVATION)
 		{
-			do_activate(ob1, ob2, mi1, rbw, mi2);
+			check_activate = do_activate(ob1, ob2, mi1, rbw, mi2, activate);
 		}
 
 		if (ob2->rigidbody_object->flag & RBO_FLAG_USE_KINEMATIC_DEACTIVATION)
 		{
-			do_activate(ob2, ob1, mi2, rbw, mi1);
+			check_activate = do_activate(ob2, ob1, mi2, rbw, mi1, activate);
 		}
 	}
 
@@ -2284,7 +2290,18 @@ static int filterCallback(void* world, void* island1, void* island2, void *blend
 	fake_dynamic_collide(ob1, ob2, mi1, mi2, rbw);
 	fake_dynamic_collide(ob2, ob1, mi2, mi1, rbw);
 
-	return check_colgroup_ghost(ob1, ob2) && ((check_constraint_island(fmd1, mi1, mi2) && check_constraint_island(fmd2, mi2, mi1)) || (ob1 != ob2));
+	validOb = ((ob1->rigidbody_object->flag & RBO_FLAG_KINEMATIC) == 0) || ((ob2->rigidbody_object->flag & RBO_FLAG_KINEMATIC) == 0);
+	validOb = validOb || ((ob1->rigidbody_object->flag & RBO_FLAG_KINEMATIC) == 0) || ((mi2 && mi2->rigidbody->flag & RBO_FLAG_KINEMATIC) == 0);
+	validOb = validOb || ((mi1 && (mi1->rigidbody->flag & RBO_FLAG_KINEMATIC) == 0)) || ((ob2->rigidbody_object->flag & RBO_FLAG_KINEMATIC) == 0);
+	validOb = validOb || ((mi1 && (mi1->rigidbody->flag & RBO_FLAG_KINEMATIC) == 0)) || ((mi2 && mi2->rigidbody->flag & RBO_FLAG_KINEMATIC) == 0);
+
+	if (validOb)
+	{
+		//always allow when atleast one object is not kinematic
+		check_activate = true;
+	}
+
+	return check_activate && check_colgroup_ghost(ob1, ob2) && ((check_constraint_island(fmd1, mi1, mi2) && check_constraint_island(fmd2, mi2, mi1)) || (ob1 != ob2));
 }
 
 static bool can_break(Object* collider, Object* ob, bool limit)
@@ -4696,7 +4713,7 @@ void BKE_rigidbody_sync_transforms(RigidBodyWorld *rbw, Object *ob, float ctime)
 		rbo = ob->rigidbody_object;
 
 		/* keep original transform for kinematic and passive objects */
-		if (ELEM(NULL, rbw, rbo) || rbo->flag & RBO_FLAG_KINEMATIC || rbo->type == RBO_TYPE_PASSIVE)
+		if (ELEM(NULL, rbw, rbo) || (((rbo->flag & RBO_FLAG_KINEMATIC) && ((rbo->flag & RBO_FLAG_KINEMATIC_REBUILD) == 0)) || rbo->type == RBO_TYPE_PASSIVE))
 			return;
 
 		/* use rigid body transform after cache start frame if objects is not being transformed */




More information about the Bf-blender-cvs mailing list