[Bf-blender-cvs] [5019780] fracture_modifier: fix for triggers and multiple compound objects (but compound building is slower again, due to necessary broadphase handles for triggers)

Martin Felke noreply at git.blender.org
Fri Oct 23 18:45:42 CEST 2015


Commit: 50197806641fc679372a949eff066fb1495c78aa
Author: Martin Felke
Date:   Fri Oct 23 18:45:28 2015 +0200
Branches: fracture_modifier
https://developer.blender.org/rB50197806641fc679372a949eff066fb1495c78aa

fix for triggers and multiple compound objects (but compound building is slower again, due to necessary broadphase handles for triggers)

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

M	extern/bullet2/src/BulletDynamics/Dynamics/btFractureDynamicsWorld.cpp

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

diff --git a/extern/bullet2/src/BulletDynamics/Dynamics/btFractureDynamicsWorld.cpp b/extern/bullet2/src/BulletDynamics/Dynamics/btFractureDynamicsWorld.cpp
index 10ebda7..e8789b2 100644
--- a/extern/bullet2/src/BulletDynamics/Dynamics/btFractureDynamicsWorld.cpp
+++ b/extern/bullet2/src/BulletDynamics/Dynamics/btFractureDynamicsWorld.cpp
@@ -19,6 +19,38 @@ m_addBroadPhaseHandle(false)
 btFractureDynamicsWorld::~btFractureDynamicsWorld()
 {
 	delete m_childIndexHash;
+
+	//clean up remaining objects (before inefficient collision world destructor gets run... ?)
+	int i;
+
+	// first just clear ALL pairs
+	btOverlappingPairCache *paircache = getBroadphase()->getOverlappingPairCache();
+	btBroadphasePairArray& pairs = paircache->getOverlappingPairArray();
+
+	//printf("Pair size: %d\n", pairs.size());
+	for (i=0;i<pairs.size();i++)
+	{
+		paircache->cleanOverlappingPair(pairs[i], m_dispatcher1);
+		paircache->removeOverlappingPair(pairs[i].m_pProxy0, pairs[i].m_pProxy1, m_dispatcher1);
+	}
+
+	// then all proxies, should be 2*N instead of N^2
+	for (i=0;i<m_collisionObjects.size();i++)
+	{
+		btCollisionObject* collisionObject= m_collisionObjects[i];
+
+		btBroadphaseProxy* bp = collisionObject->getBroadphaseHandle();
+		if (bp)
+		{
+			//
+			// only clear the cached algorithms
+			//
+			//getBroadphase()->getOverlappingPairCache()->cleanProxyFromPairs(bp,m_dispatcher1);
+			//printf("Destroy Proxy: %d\n", i);
+			getBroadphase()->destroyProxy(bp,m_dispatcher1);
+			collisionObject->setBroadphaseHandle(0);
+		}
+	}
 }
 
 void btFractureDynamicsWorld::updateBodies()
@@ -92,11 +124,12 @@ void btFractureDynamicsWorld::glueCallback()
 
 	///first build the islands based on axis aligned bounding box overlap
 
-	btUnionFind unionFind;
+
+	btAlignedObjectArray<int> objectIds;
+	btHashMap<btHashInt, btAlignedObjectArray<btCollisionObject*> >objectMap;
 
 	int index = 0;
 	{
-
 		int i;
 		for (i=0;i<getCollisionObjectArray().size(); i++)
 		{
@@ -104,9 +137,28 @@ void btFractureDynamicsWorld::glueCallback()
 		//	btRigidBody* body = btRigidBody::upcast(collisionObject);
 			//Adding filtering here
 #ifdef STATIC_SIMULATION_ISLAND_OPTIMIZATION
-			if (!collisionObject->isStaticOrKinematicObject())
+//			if (!collisionObject->isStaticOrKinematicObject())
+			if (collisionObject->getInternalType() & CUSTOM_FRACTURE_TYPE)
 			{
+				int objectId, shardId;
 				collisionObject->setIslandTag(index++);
+				btFractureBody *body = (btFractureBody*)collisionObject;
+				m_idCallback(body->getUserPointer(),&objectId, &shardId);
+				if (objectId > -1)
+				{
+					btAlignedObjectArray<btCollisionObject*> *objects = objectMap.find(objectId);
+					if (!objects)
+					{
+						btAlignedObjectArray<btCollisionObject*> obj;
+						obj.push_back(collisionObject);
+						objectMap.insert(objectId, obj);
+						objectIds.push_back(objectId);
+					}
+					else
+					{
+						objects->push_back(collisionObject);
+					}
+				}
 			}
 			else
 			{
@@ -119,9 +171,9 @@ void btFractureDynamicsWorld::glueCallback()
 		}
 	}
 
-	unionFind.reset(index);
+/*	unionFind.reset(index);
 
-	int numElem = unionFind.getNumElements();
+	int numElem = unionFind.getNumElements();*/
 
 #if 0
 	for (int i=0;i<numManifolds;i++)
@@ -163,22 +215,30 @@ void btFractureDynamicsWorld::glueCallback()
 		btCollisionObject* colObj1 = (btCollisionObject*)&con->getRigidBodyB();
 		int tag0 = (colObj0)->getIslandTag();
 		int tag1 = (colObj1)->getIslandTag();
-		//btRigidBody* body0 = btRigidBody::upcast(colObj0);
-		//btRigidBody* body1 = btRigidBody::upcast(colObj1);
+		btFractureBody* body0 = (btFractureBody*)colObj0;
+		btFractureBody* body1 = (btFractureBody*)colObj1;
 
+		int objectId0, shardId0, objectId1, shardId1;
+		m_idCallback(body0->getUserPointer(),&objectId0, &shardId0);
+		m_idCallback(body1->getUserPointer(),&objectId1, &shardId1);
 
-		if (!colObj0->isStaticOrKinematicObject() && !colObj1->isStaticOrKinematicObject())
+		//if (!colObj0->isStaticOrKinematicObject() && !colObj1->isStaticOrKinematicObject())
+		if (objectId0 == objectId1 && objectId0 > -1)
 		{
 			unionFind.unite(tag0, tag1);
 		}
 	}
 #endif
 
-	for (int ai=0;ai<getCollisionObjectArray().size();ai++)
+	for (int ai=0;ai<objectIds.size();ai++)
 	{
-		btCollisionObject* collisionObject= getCollisionObjectArray()[ai];
-		if (!collisionObject->isStaticOrKinematicObject())
+		btUnionFind unionFind;
+		btAlignedObjectArray<btCollisionObject*> *objects = objectMap.find(objectIds[ai]);
+		unionFind.reset(objects->size());
+
+		for (int j=0;j<objects->size();j++)
 		{
+			btCollisionObject* collisionObject = objects->at(j);
 			if (collisionObject->getInternalType() & CUSTOM_FRACTURE_TYPE)
 			{
 				//ensure 1 compound per object, so shard id 0 becomes parent always.... sure that it is first ?
@@ -186,227 +246,279 @@ void btFractureDynamicsWorld::glueCallback()
 				islandTag = collisionObject->getIslandTag();
 				btFractureBody *body = (btFractureBody*)collisionObject;
 				m_idCallback(body->getUserPointer(),&objectId, &shardId);
-				if (objectId > -1)
+				if (objectId > -1 && islandTag < objects->size())
+				{
 					unionFind.unite(objectId, islandTag);
+				}
 			}
 		}
-	}
 
-	numElem = unionFind.getNumElements();
+		int numElem = unionFind.getNumElements();
 
 
-	index=0;
-	for (int ai=0;ai<getCollisionObjectArray().size();ai++)
-	{
-		btCollisionObject* collisionObject= getCollisionObjectArray()[ai];
-		if (!collisionObject->isStaticOrKinematicObject())
+		index=0;
+		for (int ai=0;ai<objects->size();ai++)
 		{
-			int tag = unionFind.find(index);
+			btCollisionObject* collisionObject= objects->at(ai);
+			//if (!collisionObject->isStaticOrKinematicObject())
+			if (collisionObject->getInternalType() & CUSTOM_FRACTURE_TYPE)
+			{
+				int tag = unionFind.find(index);
 
-			collisionObject->setIslandTag( tag);
+				collisionObject->setIslandTag( tag);
 
-			//Set the correct object offset in Collision Object Array
+				//Set the correct object offset in Collision Object Array
 #if STATIC_SIMULATION_ISLAND_OPTIMIZATION
-			unionFind.getElement(index).m_sz = ai;
+				unionFind.getElement(index).m_sz = ai;
 #endif //STATIC_SIMULATION_ISLAND_OPTIMIZATION
 
-			index++;
+				index++;
+			}
 		}
-	}
-	unionFind.sortIslands();
+		unionFind.sortIslands();
 
 
 
-	int endIslandIndex=1;
-	int startIslandIndex;
+		int endIslandIndex=1;
+		int startIslandIndex;
 
-	btAlignedObjectArray<btCollisionObject*> removedObjects;
+		btAlignedObjectArray<btCollisionObject*> removedObjects;
+		btAlignedObjectArray<btCollisionObject*> newObjects;
 
-	///iterate over all islands
-	for ( startIslandIndex=0;startIslandIndex<numElem;startIslandIndex = endIslandIndex)
-	{
-		int islandId = unionFind.getElement(startIslandIndex).m_id;
-		for (endIslandIndex = startIslandIndex+1;(endIslandIndex<numElem) && (unionFind.getElement(endIslandIndex).m_id == islandId);endIslandIndex++)
+		///iterate over all islands
+		for ( startIslandIndex=0;startIslandIndex<numElem;startIslandIndex = endIslandIndex)
 		{
-		}
-
-		int fractureObjectIndex = -1;
-
-		int numObjects=0;
-
-		int idx;
-		for (idx=startIslandIndex;idx<endIslandIndex;idx++)
-		{
-			int i = unionFind.getElement(idx).m_sz;
-			btCollisionObject* colObj0 = getCollisionObjectArray()[i];
-			if (colObj0->getInternalType()& CUSTOM_FRACTURE_TYPE)
+			int islandId = unionFind.getElement(startIslandIndex).m_id;
+			for (endIslandIndex = startIslandIndex+1;(endIslandIndex<numElem) && (unionFind.getElement(endIslandIndex).m_id == islandId);endIslandIndex++)
 			{
-				fractureObjectIndex = i;
 			}
-			btRigidBody* otherObject = btRigidBody::upcast(colObj0);
-			if (!otherObject || !otherObject->getInvMass())
-				continue;
-			numObjects++;
-		}
-
-		///Then for each island that contains at least two objects and one fracture object
-		if (fractureObjectIndex>=0 && numObjects>1)
-		{
 
-			btFractureBody* fracObj = (btFractureBody*)getCollisionObjectArray()[fractureObjectIndex];
+			int fractureObjectIndex = -1;
 
-			///glueing objects means creating a new compound and removing the old objects
-			///delay the removal of old objects to avoid array indexing problems
-			removedObjects.push_back(fracObj);
-			//m_fractureBodies.remove(fracObj);
+			int numObjects=0;
 
-			btAlignedObjectArray<btScalar> massArray;
-
-			btAlignedObjectArray<btVector3> oldImpulses;
-			btAlignedObjectArray<btVector3> oldCenterOfMassesWS;
-
-			oldImpulses.push_back(fracObj->getLinearVelocity()/1./fracObj->getInvMass());
-			oldCenterOfMassesWS.push_back(fracObj->getCenterOfMassPosition());
+			int idx;
+			for (idx=startIslandIndex;idx<endIslandIndex;idx++)
+			{
+				int i = unionFind.getElement(idx).m_sz;
 
-			btScalar totalMass = 0.f;
+				if (i >= getCollisionObjectArray().size())
+				{
+					fractureObjectIndex = -1;
+					continue;
+				}
 
 
-			btCompoundShape* compound = new btCompoundShape(false);
-			if (fracObj->getCollisionShape()->isCompound())
-			{
-				btTransform tr;
-				tr.setIdentity();
-				btCompoundShape* oldCompound = (btCompoundShape*)fracObj->getCollisionShape();
-				for (int c=0;c<oldCompound->getNumChildShapes();c++)
+				btCollisionObject* colObj0 = getCollisionObjectArray()[i];
+				if (colObj0->getInternalType()& CUSTOM_FRACTURE_TYPE)
+				{
+					fractureObjectIndex = i;
+				}
+				else
 				{
-					compound->addChildShape(oldCompound->getChildTransform(c),oldCompound->getChildShape(c));
-					massArray.push_back(fracObj->m_masses[c]);
-					totalMass+=fracObj->m_masses[c];
+					fractureObjectIndex = -1;
+					continue;
 				}
 
-			} else
-			{
-				btTransform tr;
-				tr.setIdentity();
-				compound->addChildShape(tr,fracObj->getCollisionShape());
-				massArray.push_back(fracObj->m_masses[0]);
-				totalMass+=fracObj->m_masses[0];
+				btRigidBody* otherObject = btRigidBody::upcast(colObj0);
+				if (!otherObject || !otherObject->getInvMass())
+					continue;
+				numObjects++;
 			}
 
-			for (idx=startIslandIndex;idx<endIslandIndex;idx++)
+			///Then for each island that contains at least two objects and one fracture object
+			if (fractureObjectIndex>=0 && numObjects>1)
 			{
 
-				int i = unionFind.getElement(idx).m_sz;
+				btFractureBody* fracObj = (btFractureBody*)getCol

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list