[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