From 1f7646f72a385fd2bc806d8b22798a35b07c5418 Mon Sep 17 00:00:00 2001 From: ejcoumans Date: Thu, 2 Aug 2007 23:48:46 +0000 Subject: [PATCH] Refactoring to enable multi SAP broadphase. This was already planned, and Pierre Terdiman recent thread motivated me to decouple the paircache from the sweep and prune. http://continuousphysics.com/Bullet/phpBB2/viewtopic.php?t=1329 --- Demos/BasicDemo/BasicDemo.cpp | 2 +- Demos/BasicDemo/BasicDemo.h | 2 +- Demos/BspDemo/BspDemo.cpp | 2 +- Demos/CcdPhysicsDemo/CcdPhysicsDemo.cpp | 2 +- Demos/ColladaDemo/ColladaDemo.cpp | 2 +- Demos/ConcaveDemo/ConcavePhysicsDemo.cpp | 4 +- Demos/ConstraintDemo/ConstraintDemo.cpp | 4 +- .../ConvexDecompositionDemo.cpp | 4 +- .../MovingConcaveDemo/ConcavePhysicsDemo.cpp | 2 +- Demos/OpenGL/DemoApplication.cpp | 6 +- Demos/RagdollDemo/RagdollDemo.cpp | 2 +- .../UserCollisionAlgorithm.cpp | 2 +- Demos/VehicleDemo/VehicleDemo.cpp | 4 +- .../BroadphaseCollision/btAxisSweep3.cpp | 60 ++++++------ .../BroadphaseCollision/btAxisSweep3.h | 24 ++++- .../btBroadphaseInterface.h | 10 +- .../BroadphaseCollision/btBroadphaseProxy.h | 1 + .../btOverlappingPairCache.cpp | 3 + .../btOverlappingPairCache.h | 17 +++- .../btSimpleBroadphase.cpp | 94 +++++++++++++++++-- .../BroadphaseCollision/btSimpleBroadphase.h | 18 +++- .../CollisionDispatch/btCollisionWorld.cpp | 12 +-- .../CollisionDispatch/btCollisionWorld.h | 6 +- src/BulletDynamics/Dynamics/Bullet-C-API.cpp | 2 +- .../Dynamics/btDiscreteDynamicsWorld.cpp | 2 +- .../Dynamics/btDiscreteDynamicsWorld.h | 2 +- src/BulletDynamics/Dynamics/btDynamicsWorld.h | 4 +- .../Dynamics/btSimpleDynamicsWorld.cpp | 2 +- .../Dynamics/btSimpleDynamicsWorld.h | 2 +- 29 files changed, 212 insertions(+), 85 deletions(-) diff --git a/Demos/BasicDemo/BasicDemo.cpp b/Demos/BasicDemo/BasicDemo.cpp index e9e9addd6..4d3a5230f 100644 --- a/Demos/BasicDemo/BasicDemo.cpp +++ b/Demos/BasicDemo/BasicDemo.cpp @@ -152,7 +152,7 @@ void BasicDemo::initPhysics() m_dispatcher = new btCollisionDispatcher(true); #endif //USE_PARALLEL_DISPATCHER -//#define USE_SWEEP_AND_PRUNE 1 +#define USE_SWEEP_AND_PRUNE 1 #ifdef USE_SWEEP_AND_PRUNE #define maxProxies 8192 btVector3 worldAabbMin(-10000,-10000,-10000); diff --git a/Demos/BasicDemo/BasicDemo.h b/Demos/BasicDemo/BasicDemo.h index 21b7cba7f..4b06629d6 100644 --- a/Demos/BasicDemo/BasicDemo.h +++ b/Demos/BasicDemo/BasicDemo.h @@ -31,7 +31,7 @@ class BasicDemo : public DemoApplication //keep the collision shapes, for deletion/cleanup btAlignedObjectArray m_collisionShapes; - btOverlappingPairCache* m_overlappingPairCache; + btBroadphaseInterface* m_overlappingPairCache; btCollisionDispatcher* m_dispatcher; diff --git a/Demos/BspDemo/BspDemo.cpp b/Demos/BspDemo/BspDemo.cpp index 889b54de1..692491917 100644 --- a/Demos/BspDemo/BspDemo.cpp +++ b/Demos/BspDemo/BspDemo.cpp @@ -138,7 +138,7 @@ void BspDemo::initPhysics(char* bspfilename) btCollisionDispatcher* dispatcher = new btCollisionDispatcher(); btVector3 worldMin(-1000,-1000,-1000); btVector3 worldMax(1000,1000,1000); - btOverlappingPairCache* pairCache = new btAxisSweep3(worldMin,worldMax); + btBroadphaseInterface* pairCache = new btAxisSweep3(worldMin,worldMax); //btOverlappingPairCache* broadphase = new btSimpleBroadphase(); btConstraintSolver* constraintSolver = new btSequentialImpulseConstraintSolver(); //ConstraintSolver* solver = new OdeConstraintSolver; diff --git a/Demos/CcdPhysicsDemo/CcdPhysicsDemo.cpp b/Demos/CcdPhysicsDemo/CcdPhysicsDemo.cpp index ec4a191fe..4c874bd40 100644 --- a/Demos/CcdPhysicsDemo/CcdPhysicsDemo.cpp +++ b/Demos/CcdPhysicsDemo/CcdPhysicsDemo.cpp @@ -361,7 +361,7 @@ void CcdPhysicsDemo::initPhysics() btVector3 worldAabbMin(-1000,-1000,-1000); btVector3 worldAabbMax(1000,1000,1000); - btOverlappingPairCache* broadphase = new btAxisSweep3(worldAabbMin,worldAabbMax,maxProxies); + btBroadphaseInterface* broadphase = new btAxisSweep3(worldAabbMin,worldAabbMax,maxProxies); // btOverlappingPairCache* broadphase = new btSimpleBroadphase; #ifdef REGISTER_CUSTOM_COLLISION_ALGORITHM diff --git a/Demos/ColladaDemo/ColladaDemo.cpp b/Demos/ColladaDemo/ColladaDemo.cpp index 89a86400a..97eedd2fe 100644 --- a/Demos/ColladaDemo/ColladaDemo.cpp +++ b/Demos/ColladaDemo/ColladaDemo.cpp @@ -173,7 +173,7 @@ void ColladaDemo::initPhysics(const char* filename) btCollisionDispatcher* dispatcher = new btCollisionDispatcher(); btVector3 worldMin(-1000,-1000,-1000); btVector3 worldMax(1000,1000,1000); - btOverlappingPairCache* pairCache = new btAxisSweep3(worldMin,worldMax); + btBroadphaseInterface* pairCache = new btAxisSweep3(worldMin,worldMax); btConstraintSolver* constraintSolver = new btSequentialImpulseConstraintSolver(); m_dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher,pairCache,constraintSolver); diff --git a/Demos/ConcaveDemo/ConcavePhysicsDemo.cpp b/Demos/ConcaveDemo/ConcavePhysicsDemo.cpp index 9eb22cf8c..8337e2167 100644 --- a/Demos/ConcaveDemo/ConcavePhysicsDemo.cpp +++ b/Demos/ConcaveDemo/ConcavePhysicsDemo.cpp @@ -223,7 +223,7 @@ void ConcaveDemo::initPhysics() btVector3 worldMin(-1000,-1000,-1000); btVector3 worldMax(1000,1000,1000); - btOverlappingPairCache* pairCache = new btAxisSweep3(worldMin,worldMax); + btBroadphaseInterface* pairCache = new btAxisSweep3(worldMin,worldMax); btConstraintSolver* constraintSolver = new btSequentialImpulseConstraintSolver(); m_dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher,pairCache,constraintSolver); #ifdef USE_PARALLEL_DISPATCHER @@ -276,7 +276,7 @@ void ConcaveDemo::clientMoveAndDisplay() trimeshShape->refitTree(); //clear all contact points involving mesh proxy. Note: this is a slow/unoptimized operation. - m_dynamicsWorld->getBroadphase()->cleanProxyFromPairs(staticBody->getBroadphaseHandle()); + m_dynamicsWorld->getBroadphase()->getOverlappingPairCache()->cleanProxyFromPairs(staticBody->getBroadphaseHandle()); } m_dynamicsWorld->stepSimulation(dt); diff --git a/Demos/ConstraintDemo/ConstraintDemo.cpp b/Demos/ConstraintDemo/ConstraintDemo.cpp index cc5128023..2725b9fd7 100644 --- a/Demos/ConstraintDemo/ConstraintDemo.cpp +++ b/Demos/ConstraintDemo/ConstraintDemo.cpp @@ -79,8 +79,8 @@ void ConstraintDemo::initPhysics() btCollisionDispatcher* dispatcher = new btCollisionDispatcher(); btVector3 worldMin(-1000,-1000,-1000); btVector3 worldMax(1000,1000,1000); - btOverlappingPairCache* pairCache = new btAxisSweep3(worldMin,worldMax); - //btOverlappingPairCache* broadphase = new btSimpleBroadphase(); + btBroadphaseInterface* pairCache = new btAxisSweep3(worldMin,worldMax); + //btBroadphaseInterface* broadphase = new btSimpleBroadphase(); btConstraintSolver* constraintSolver = new btSequentialImpulseConstraintSolver(); //ConstraintSolver* solver = new OdeConstraintSolver; m_dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher,pairCache,constraintSolver); diff --git a/Demos/ConvexDecompositionDemo/ConvexDecompositionDemo.cpp b/Demos/ConvexDecompositionDemo/ConvexDecompositionDemo.cpp index 765f6cd58..82d89bf56 100644 --- a/Demos/ConvexDecompositionDemo/ConvexDecompositionDemo.cpp +++ b/Demos/ConvexDecompositionDemo/ConvexDecompositionDemo.cpp @@ -122,8 +122,8 @@ void ConvexDecompositionDemo::initPhysics(const char* filename) btVector3 worldAabbMin(-10000,-10000,-10000); btVector3 worldAabbMax(10000,10000,10000); - btOverlappingPairCache* broadphase = new btAxisSweep3(worldAabbMin,worldAabbMax); - //OverlappingPairCache* broadphase = new btSimpleBroadphase(); + btBroadphaseInterface* broadphase = new btAxisSweep3(worldAabbMin,worldAabbMax); + //btBroadphaseInterface* broadphase = new btSimpleBroadphase(); btConstraintSolver* solver = new btSequentialImpulseConstraintSolver(); m_dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher,broadphase,solver); diff --git a/Demos/MovingConcaveDemo/ConcavePhysicsDemo.cpp b/Demos/MovingConcaveDemo/ConcavePhysicsDemo.cpp index 0c335854b..4b6b4acd0 100644 --- a/Demos/MovingConcaveDemo/ConcavePhysicsDemo.cpp +++ b/Demos/MovingConcaveDemo/ConcavePhysicsDemo.cpp @@ -1648,7 +1648,7 @@ void ConcaveDemo::initPhysics() //btConstraintSolver* solver = new btSequentialImpulseConstraintSolver; btCollisionDispatcher* dispatcher = new btCollisionDispatcher(); //btOverlappingPairCache* broadphase = new btSimpleBroadphase(); - btOverlappingPairCache* broadphase = new btSimpleBroadphase(); + btBroadphaseInterface* broadphase = new btSimpleBroadphase(); btConstraintSolver* constraintSolver = new btSequentialImpulseConstraintSolver(); m_dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher,broadphase,constraintSolver); diff --git a/Demos/OpenGL/DemoApplication.cpp b/Demos/OpenGL/DemoApplication.cpp index 58d505460..1308462a4 100644 --- a/Demos/OpenGL/DemoApplication.cpp +++ b/Demos/OpenGL/DemoApplication.cpp @@ -450,12 +450,12 @@ void DemoApplication::shootBox(const btVector3& destination) startTransform.setIdentity(); btVector3 camPos = getCameraPosition(); startTransform.setOrigin(camPos); -#define TEST_UNIFORM_SCALING_SHAPE 1 +//#define TEST_UNIFORM_SCALING_SHAPE 1 #ifdef TEST_UNIFORM_SCALING_SHAPE btConvexShape* childShape = new btBoxShape(btVector3(1.f,1.f,1.f)); btUniformScalingShape* boxShape = new btUniformScalingShape(childShape,0.5f); #else - btCollisionShape* boxShape = new btSphereShape(1); + btCollisionShape* boxShape = new btBoxShape(btVector3(0.5f,0.5f,0.5f)); #endif// btRigidBody* body = this->localCreateRigidBody(mass, startTransform,boxShape); @@ -932,7 +932,7 @@ void DemoApplication::clientResetScene() colObj->activate(); } //removed cached contact points - m_dynamicsWorld->getBroadphase()->cleanProxyFromPairs(colObj->getBroadphaseHandle()); + m_dynamicsWorld->getBroadphase()->getOverlappingPairCache()->cleanProxyFromPairs(colObj->getBroadphaseHandle()); btRigidBody* body = btRigidBody::upcast(colObj); if (body && !body->isStaticObject()) diff --git a/Demos/RagdollDemo/RagdollDemo.cpp b/Demos/RagdollDemo/RagdollDemo.cpp index 54de175d0..eb10bef36 100644 --- a/Demos/RagdollDemo/RagdollDemo.cpp +++ b/Demos/RagdollDemo/RagdollDemo.cpp @@ -311,7 +311,7 @@ void RagdollDemo::initPhysics() btPoint3 worldAabbMin(-10000,-10000,-10000); btPoint3 worldAabbMax(10000,10000,10000); - btOverlappingPairCache* overlappingPairCache = new btAxisSweep3 (worldAabbMin, worldAabbMax); + btBroadphaseInterface* overlappingPairCache = new btAxisSweep3 (worldAabbMin, worldAabbMax); btConstraintSolver* solver = new btSequentialImpulseConstraintSolver; diff --git a/Demos/UserCollisionAlgorithm/UserCollisionAlgorithm.cpp b/Demos/UserCollisionAlgorithm/UserCollisionAlgorithm.cpp index 01da0965d..6ef143e0f 100644 --- a/Demos/UserCollisionAlgorithm/UserCollisionAlgorithm.cpp +++ b/Demos/UserCollisionAlgorithm/UserCollisionAlgorithm.cpp @@ -109,7 +109,7 @@ void UserCollisionAlgorithm::initPhysics() btCollisionDispatcher* dispatcher = new btCollisionDispatcher(); btVector3 maxAabb(10000,10000,10000); - btOverlappingPairCache* broadphase = new btAxisSweep3(-maxAabb,maxAabb);//SimpleBroadphase(); + btBroadphaseInterface* broadphase = new btAxisSweep3(-maxAabb,maxAabb);//SimpleBroadphase(); dispatcher->registerCollisionCreateFunc(GIMPACT_SHAPE_PROXYTYPE,GIMPACT_SHAPE_PROXYTYPE,new btSphereSphereCollisionAlgorithm::CreateFunc); btConstraintSolver* constraintSolver = new btSequentialImpulseConstraintSolver(); diff --git a/Demos/VehicleDemo/VehicleDemo.cpp b/Demos/VehicleDemo/VehicleDemo.cpp index 30a738fa2..08b97332a 100644 --- a/Demos/VehicleDemo/VehicleDemo.cpp +++ b/Demos/VehicleDemo/VehicleDemo.cpp @@ -121,7 +121,7 @@ void VehicleDemo::setupPhysics() btCollisionDispatcher* dispatcher = new btCollisionDispatcher(); btVector3 worldMin(-1000,-1000,-1000); btVector3 worldMax(1000,1000,1000); - btOverlappingPairCache* pairCache = new btAxisSweep3(worldMin,worldMax); + btBroadphaseInterface* pairCache = new btAxisSweep3(worldMin,worldMax); btConstraintSolver* constraintSolver = new btSequentialImpulseConstraintSolver(); m_dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher,pairCache,constraintSolver); #ifdef FORCE_ZAXIS_UP @@ -490,7 +490,7 @@ void VehicleDemo::clientResetScene() m_carChassis->setCenterOfMassTransform(btTransform::getIdentity()); m_carChassis->setLinearVelocity(btVector3(0,0,0)); m_carChassis->setAngularVelocity(btVector3(0,0,0)); - m_dynamicsWorld->getBroadphase()->cleanProxyFromPairs(m_carChassis->getBroadphaseHandle()); + m_dynamicsWorld->getBroadphase()->getOverlappingPairCache()->cleanProxyFromPairs(m_carChassis->getBroadphaseHandle()); if (m_vehicle) { m_vehicle->resetSuspension(); diff --git a/src/BulletCollision/BroadphaseCollision/btAxisSweep3.cpp b/src/BulletCollision/BroadphaseCollision/btAxisSweep3.cpp index be4a11506..841871a5d 100644 --- a/src/BulletCollision/BroadphaseCollision/btAxisSweep3.cpp +++ b/src/BulletCollision/BroadphaseCollision/btAxisSweep3.cpp @@ -74,9 +74,10 @@ void btAxisSweep3::setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,con btAxisSweep3::btAxisSweep3(const btPoint3& worldAabbMin,const btPoint3& worldAabbMax, int maxHandles) -:btOverlappingPairCache() +:m_invalidPair(0) { - m_invalidPair = 0; + m_pairCache = new btOverlappingPairCache(); + //assert(bounds.HasVolume()); // 1 handle is reserved as sentinel @@ -244,7 +245,7 @@ void btAxisSweep3::removeHandle(BP_FP_INT_TYPE handle) //explicitly remove the pairs containing the proxy //we could do it also in the sortMinUp (passing true) //todo: compare performance - removeOverlappingPairsContainingProxy(pHandle); + m_pairCache->removeOverlappingPairsContainingProxy(pHandle); // compute current limit of edge arrays @@ -293,27 +294,16 @@ void btAxisSweep3::removeHandle(BP_FP_INT_TYPE handle) extern int gOverlappingPairs; -void btAxisSweep3::refreshOverlappingPairs() -{ - -} -void btAxisSweep3::processAllOverlappingPairs(btOverlapCallback* callback) +void btAxisSweep3::calculateOverlappingPairs() { + + btBroadphasePairArray& overlappingPairArray = m_pairCache->getOverlappingPairArray(); //perform a sort, to find duplicates and to sort 'invalid' pairs to the end - m_overlappingPairArray.heapSort(btBroadphasePairSortPredicate()); + overlappingPairArray.heapSort(btBroadphasePairSortPredicate()); - //remove the 'invalid' ones -#ifdef USE_POPBACK_REMOVAL - while (m_invalidPair>0) - { - m_invalidPair--; - m_overlappingPairArray.pop_back(); - } -#else - m_overlappingPairArray.resize(m_overlappingPairArray.size() - m_invalidPair); + overlappingPairArray.resize(overlappingPairArray.size() - m_invalidPair); m_invalidPair = 0; -#endif int i; @@ -324,10 +314,10 @@ void btAxisSweep3::processAllOverlappingPairs(btOverlapCallback* callback) previousPair.m_algorithm = 0; - for (i=0;iprocessOverlap(pair); + needsRemoval = false;//callback->processOverlap(pair); } else { needsRemoval = true; @@ -356,7 +346,7 @@ void btAxisSweep3::processAllOverlappingPairs(btOverlapCallback* callback) if (needsRemoval) { - cleanOverlappingPair(pair); + m_pairCache->cleanOverlappingPair(pair); // m_overlappingPairArray.swap(i,m_overlappingPairArray.size()-1); // m_overlappingPairArray.pop_back(); @@ -367,10 +357,24 @@ void btAxisSweep3::processAllOverlappingPairs(btOverlapCallback* callback) } } + +///if you don't like to skip the invalid pairs in the array, execute following code: +#define CLEAN_INVALID_PAIRS 1 +#ifdef CLEAN_INVALID_PAIRS + + //perform a sort, to sort 'invalid' pairs to the end + overlappingPairArray.heapSort(btBroadphasePairSortPredicate()); + + overlappingPairArray.resize(overlappingPairArray.size() - m_invalidPair); + m_invalidPair = 0; +#endif//CLEAN_INVALID_PAIRS + + } -bool btAxisSweep3::testOverlap(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) + +bool btAxisSweep3::testAabbOverlap(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) { const Handle* pHandleA = static_cast(proxy0); const Handle* pHandleB = static_cast(proxy1); @@ -485,7 +489,7 @@ void btAxisSweep3::sortMinDown(int axis, BP_FP_INT_TYPE edge, bool updateOverlap // if previous edge is a maximum check the bounds and add an overlap if necessary if (updateOverlaps && testOverlap(axis,pHandleEdge, pHandlePrev)) { - addOverlappingPair(pHandleEdge,pHandlePrev); + m_pairCache->addOverlappingPair(pHandleEdge,pHandlePrev); //AddOverlap(pEdge->m_handle, pPrev->m_handle); @@ -636,7 +640,7 @@ void btAxisSweep3::sortMaxUp(int axis, BP_FP_INT_TYPE edge, bool updateOverlaps) { Handle* handle0 = getHandle(pEdge->m_handle); Handle* handle1 = getHandle(pNext->m_handle); - addOverlappingPair(handle0,handle1); + m_pairCache->addOverlappingPair(handle0,handle1); } // update edge reference in other handle @@ -658,3 +662,5 @@ void btAxisSweep3::sortMaxUp(int axis, BP_FP_INT_TYPE edge, bool updateOverlaps) } } + + diff --git a/src/BulletCollision/BroadphaseCollision/btAxisSweep3.h b/src/BulletCollision/BroadphaseCollision/btAxisSweep3.h index 7fa282c87..aa4f16f15 100644 --- a/src/BulletCollision/BroadphaseCollision/btAxisSweep3.h +++ b/src/BulletCollision/BroadphaseCollision/btAxisSweep3.h @@ -22,6 +22,7 @@ #include "LinearMath/btPoint3.h" #include "LinearMath/btVector3.h" #include "btOverlappingPairCache.h" +#include "btBroadphaseInterface.h" #include "btBroadphaseProxy.h" @@ -45,7 +46,7 @@ /// btAxisSweep3 is an efficient implementation of the 3d axis sweep and prune broadphase. /// It uses arrays rather then lists for storage of the 3 axis. Also it operates using integer coordinates instead of floats. /// The testOverlap check is optimized to check the array index, rather then the actual AABB coordinates/pos -class btAxisSweep3 : public btOverlappingPairCache +class btAxisSweep3 : public btBroadphaseInterface { public: @@ -77,7 +78,7 @@ public: }; // 24 bytes + 24 for Edge structures = 44 bytes total per entry -private: +protected: btPoint3 m_worldAabbMin; // overall system bounds btPoint3 m_worldAabbMax; // overall system bounds @@ -90,7 +91,9 @@ private: Edge* m_pEdges[3]; // edge arrays for the 3 axes (each array has m_maxHandles * 2 + 2 sentinel entries) - int m_invalidPair; + btOverlappingPairCache* m_pairCache; + + int m_invalidPair; // allocation/deallocation BP_FP_INT_TYPE allocHandle(); @@ -117,7 +120,7 @@ public: btAxisSweep3(const btPoint3& worldAabbMin,const btPoint3& worldAabbMax, int maxHandles = 16384); virtual ~btAxisSweep3(); - virtual void refreshOverlappingPairs(); + virtual void calculateOverlappingPairs(); BP_FP_INT_TYPE addHandle(const btPoint3& aabbMin,const btPoint3& aabbMax, void* pOwner,short int collisionFilterGroup,short int collisionFilterMask); void removeHandle(BP_FP_INT_TYPE handle); @@ -130,7 +133,18 @@ public: virtual btBroadphaseProxy* createProxy( const btVector3& min, const btVector3& max,int shapeType,void* userPtr ,short int collisionFilterGroup,short int collisionFilterMask); virtual void destroyProxy(btBroadphaseProxy* proxy); virtual void setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax); - bool testOverlap(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1); + + bool testAabbOverlap(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1); + + btOverlappingPairCache* getOverlappingPairCache() + { + return m_pairCache; + } + const btOverlappingPairCache* getOverlappingPairCache() const + { + return m_pairCache; + } + }; diff --git a/src/BulletCollision/BroadphaseCollision/btBroadphaseInterface.h b/src/BulletCollision/BroadphaseCollision/btBroadphaseInterface.h index 0c0bfe4f7..86e08924c 100644 --- a/src/BulletCollision/BroadphaseCollision/btBroadphaseInterface.h +++ b/src/BulletCollision/BroadphaseCollision/btBroadphaseInterface.h @@ -20,7 +20,9 @@ subject to the following restrictions: struct btDispatcherInfo; class btDispatcher; -struct btBroadphaseProxy; +#include "btBroadphaseProxy.h" +class btOverlappingPairCache; + #include "LinearMath/btVector3.h" ///BroadphaseInterface for aabb-overlapping object pairs @@ -32,8 +34,12 @@ public: virtual btBroadphaseProxy* createProxy( const btVector3& min, const btVector3& max,int shapeType,void* userPtr, short int collisionFilterGroup,short int collisionFilterMask) =0; virtual void destroyProxy(btBroadphaseProxy* proxy)=0; virtual void setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax)=0; - virtual void cleanProxyFromPairs(btBroadphaseProxy* proxy)=0; + ///calculateOverlappingPairs is optional: incremental algorithms (sweep and prune) might do it during the set aabb + virtual void calculateOverlappingPairs()=0; + + virtual btOverlappingPairCache* getOverlappingPairCache()=0; + virtual const btOverlappingPairCache* getOverlappingPairCache() const =0; }; diff --git a/src/BulletCollision/BroadphaseCollision/btBroadphaseProxy.h b/src/BulletCollision/BroadphaseCollision/btBroadphaseProxy.h index c00da7c21..224943c46 100644 --- a/src/BulletCollision/BroadphaseCollision/btBroadphaseProxy.h +++ b/src/BulletCollision/BroadphaseCollision/btBroadphaseProxy.h @@ -182,6 +182,7 @@ SIMD_FORCE_INLINE bool operator<(const btBroadphasePair& a, const btBroadphasePa */ + class btBroadphasePairSortPredicate { public: diff --git a/src/BulletCollision/BroadphaseCollision/btOverlappingPairCache.cpp b/src/BulletCollision/BroadphaseCollision/btOverlappingPairCache.cpp index 60f15d97e..a2813a811 100644 --- a/src/BulletCollision/BroadphaseCollision/btOverlappingPairCache.cpp +++ b/src/BulletCollision/BroadphaseCollision/btOverlappingPairCache.cpp @@ -194,3 +194,6 @@ void btOverlappingPairCache::processAllOverlappingPairs(btOverlapCallback* callb } } + + + diff --git a/src/BulletCollision/BroadphaseCollision/btOverlappingPairCache.h b/src/BulletCollision/BroadphaseCollision/btOverlappingPairCache.h index 0e9eab907..f207db9b8 100644 --- a/src/BulletCollision/BroadphaseCollision/btOverlappingPairCache.h +++ b/src/BulletCollision/BroadphaseCollision/btOverlappingPairCache.h @@ -40,19 +40,22 @@ struct btOverlapFilterCallback virtual bool needBroadphaseCollision(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) const = 0; }; +typedef btAlignedObjectArray btBroadphasePairArray; + ///btOverlappingPairCache maintains the objects with overlapping AABB ///Typically managed by the Broadphase, Axis3Sweep or btSimpleBroadphase -class btOverlappingPairCache : public btBroadphaseInterface +class btOverlappingPairCache { protected: //avoid brute-force finding all the time - btAlignedObjectArray m_overlappingPairArray; + btBroadphasePairArray m_overlappingPairArray; //during the dispatch, check that user doesn't destroy/create proxy bool m_blockedForChanges; //if set, use the callback instead of the built in filter in needBroadphaseCollision btOverlapFilterCallback* m_overlapFilterCallback; + public: btOverlappingPairCache(); @@ -84,10 +87,16 @@ class btOverlappingPairCache : public btBroadphaseInterface return collides; } - + btBroadphasePairArray& getOverlappingPairArray() + { + return m_overlappingPairArray; + } - virtual void refreshOverlappingPairs() =0; + const btBroadphasePairArray& getOverlappingPairArray() const + { + return m_overlappingPairArray; + } btBroadphasePair* getOverlappingPairArrayPtr() { diff --git a/src/BulletCollision/BroadphaseCollision/btSimpleBroadphase.cpp b/src/BulletCollision/BroadphaseCollision/btSimpleBroadphase.cpp index 30bcbe0c5..2baaffbca 100644 --- a/src/BulletCollision/BroadphaseCollision/btSimpleBroadphase.cpp +++ b/src/BulletCollision/BroadphaseCollision/btSimpleBroadphase.cpp @@ -22,6 +22,7 @@ subject to the following restrictions: #include "LinearMath/btMatrix3x3.h" #include +extern int gOverlappingPairs; void btSimpleBroadphase::validate() { @@ -36,11 +37,14 @@ void btSimpleBroadphase::validate() } btSimpleBroadphase::btSimpleBroadphase(int maxProxies) - :btOverlappingPairCache(), + : m_firstFreeProxy(0), m_numProxies(0), - m_maxProxies(maxProxies) + m_maxProxies(maxProxies), + m_invalidPair(0) { + + m_pairCache = new btOverlappingPairCache(); m_proxies = new btSimpleBroadphaseProxy[maxProxies]; m_freeProxies = new int[maxProxies]; @@ -136,7 +140,7 @@ void btSimpleBroadphase::destroyProxy(btBroadphaseProxy* proxyOrg) btAssert (index < m_maxProxies); m_freeProxies[--m_firstFreeProxy] = index; - removeOverlappingPairsContainingProxy(proxyOrg); + m_pairCache->removeOverlappingPairsContainingProxy(proxyOrg); for (i=0;ifindPair(proxy0,proxy1)) { - addOverlappingPair(proxy0,proxy1); + m_pairCache->addOverlappingPair(proxy0,proxy1); } } } } + + btBroadphasePairArray& overlappingPairArray = m_pairCache->getOverlappingPairArray(); - CheckOverlapCallback checkOverlap; + //perform a sort, to find duplicates and to sort 'invalid' pairs to the end + overlappingPairArray.heapSort(btBroadphasePairSortPredicate()); - processAllOverlappingPairs(&checkOverlap); + overlappingPairArray.resize(overlappingPairArray.size() - m_invalidPair); + m_invalidPair = 0; + btBroadphasePair previousPair; + previousPair.m_pProxy0 = 0; + previousPair.m_pProxy1 = 0; + previousPair.m_algorithm = 0; + + + for (i=0;iprocessOverlap(pair); + } else + { + needsRemoval = true; + } + } else + { + //remove duplicate + needsRemoval = true; + //should have no algorithm + btAssert(!pair.m_algorithm); + } + + if (needsRemoval) + { + m_pairCache->cleanOverlappingPair(pair); + + // m_overlappingPairArray.swap(i,m_overlappingPairArray.size()-1); + // m_overlappingPairArray.pop_back(); + pair.m_pProxy0 = 0; + pair.m_pProxy1 = 0; + m_invalidPair++; + gOverlappingPairs--; + } + + } + +///if you don't like to skip the invalid pairs in the array, execute following code: +#define CLEAN_INVALID_PAIRS 1 +#ifdef CLEAN_INVALID_PAIRS + + //perform a sort, to sort 'invalid' pairs to the end + overlappingPairArray.heapSort(btBroadphasePairSortPredicate()); + + overlappingPairArray.resize(overlappingPairArray.size() - m_invalidPair); + m_invalidPair = 0; +#endif//CLEAN_INVALID_PAIRS + } +bool btSimpleBroadphase::testAabbOverlap(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) +{ + btSimpleBroadphaseProxy* p0 = getSimpleProxyFromProxy(proxy0); + btSimpleBroadphaseProxy* p1 = getSimpleProxyFromProxy(proxy1); + return aabbOverlap(p0,p1); +} + + + diff --git a/src/BulletCollision/BroadphaseCollision/btSimpleBroadphase.h b/src/BulletCollision/BroadphaseCollision/btSimpleBroadphase.h index fb155e704..396fbdc42 100644 --- a/src/BulletCollision/BroadphaseCollision/btSimpleBroadphase.h +++ b/src/BulletCollision/BroadphaseCollision/btSimpleBroadphase.h @@ -38,7 +38,7 @@ struct btSimpleBroadphaseProxy : public btBroadphaseProxy }; ///SimpleBroadphase is a brute force aabb culling broadphase based on O(n^2) aabb checks -class btSimpleBroadphase : public btOverlappingPairCache +class btSimpleBroadphase : public btBroadphaseInterface { protected: @@ -50,7 +50,9 @@ protected: btSimpleBroadphaseProxy** m_pProxies; int m_numProxies; + btOverlappingPairCache* m_pairCache; + int m_invalidPair; int m_maxProxies; @@ -67,7 +69,8 @@ protected: protected: - virtual void refreshOverlappingPairs(); + virtual void calculateOverlappingPairs(); + public: btSimpleBroadphase(int maxProxies=16384); virtual ~btSimpleBroadphase(); @@ -82,9 +85,16 @@ public: virtual void destroyProxy(btBroadphaseProxy* proxy); virtual void setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax); - - + btOverlappingPairCache* getOverlappingPairCache() + { + return m_pairCache; + } + const btOverlappingPairCache* getOverlappingPairCache() const + { + return m_pairCache; + } + bool testAabbOverlap(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1); }; diff --git a/src/BulletCollision/CollisionDispatch/btCollisionWorld.cpp b/src/BulletCollision/CollisionDispatch/btCollisionWorld.cpp index 8cf4928d6..cf85b2367 100644 --- a/src/BulletCollision/CollisionDispatch/btCollisionWorld.cpp +++ b/src/BulletCollision/CollisionDispatch/btCollisionWorld.cpp @@ -37,7 +37,8 @@ subject to the following restrictions: #include "BulletCollision/BroadphaseCollision/btSimpleBroadphase.h" -btCollisionWorld::btCollisionWorld(btDispatcher* dispatcher,btOverlappingPairCache* pairCache, int stackSize) + +btCollisionWorld::btCollisionWorld(btDispatcher* dispatcher,btBroadphaseInterface* pairCache, int stackSize) :m_dispatcher1(dispatcher), m_broadphasePairCache(pairCache), m_ownsDispatcher(false), @@ -65,7 +66,7 @@ btCollisionWorld::~btCollisionWorld() // // only clear the cached algorithms // - getBroadphase()->cleanProxyFromPairs(bp); + getBroadphase()->getOverlappingPairCache()->cleanProxyFromPairs(bp); getBroadphase()->destroyProxy(bp); } } @@ -136,8 +137,7 @@ void btCollisionWorld::performDiscreteCollisionDetection() m_broadphasePairCache->setAabb(m_collisionObjects[i]->getBroadphaseHandle(),aabbMin,aabbMax); } - m_broadphasePairCache->refreshOverlappingPairs(); - + m_broadphasePairCache->calculateOverlappingPairs(); END_PROFILE("perform Broadphase Collision Detection"); @@ -145,7 +145,7 @@ void btCollisionWorld::performDiscreteCollisionDetection() btDispatcher* dispatcher = getDispatcher(); if (dispatcher) - dispatcher->dispatchAllCollisionPairs(m_broadphasePairCache,dispatchInfo); + dispatcher->dispatchAllCollisionPairs(m_broadphasePairCache->getOverlappingPairCache(),dispatchInfo); END_PROFILE("performDiscreteCollisionDetection"); @@ -166,7 +166,7 @@ void btCollisionWorld::removeCollisionObject(btCollisionObject* collisionObject) // // only clear the cached algorithms // - getBroadphase()->cleanProxyFromPairs(bp); + getBroadphase()->getOverlappingPairCache()->cleanProxyFromPairs(bp); getBroadphase()->destroyProxy(bp); collisionObject->setBroadphaseHandle(0); } diff --git a/src/BulletCollision/CollisionDispatch/btCollisionWorld.h b/src/BulletCollision/CollisionDispatch/btCollisionWorld.h index 1b4c3a0c1..f1aa36ee3 100644 --- a/src/BulletCollision/CollisionDispatch/btCollisionWorld.h +++ b/src/BulletCollision/CollisionDispatch/btCollisionWorld.h @@ -90,7 +90,7 @@ protected: btStackAlloc* m_stackAlloc; - btOverlappingPairCache* m_broadphasePairCache; + btBroadphaseInterface* m_broadphasePairCache; bool m_ownsDispatcher; bool m_ownsBroadphasePairCache; @@ -98,7 +98,7 @@ protected: public: //this constructor doesn't own the dispatcher and paircache/broadphase - btCollisionWorld(btDispatcher* dispatcher,btOverlappingPairCache* pairCache, int stackSize = 2*1024*1024); + btCollisionWorld(btDispatcher* dispatcher,btBroadphaseInterface* broadphasePairCache, int stackSize = 2*1024*1024); virtual ~btCollisionWorld(); @@ -110,7 +110,7 @@ public: btOverlappingPairCache* getPairCache() { - return m_broadphasePairCache; + return m_broadphasePairCache->getOverlappingPairCache(); } diff --git a/src/BulletDynamics/Dynamics/Bullet-C-API.cpp b/src/BulletDynamics/Dynamics/Bullet-C-API.cpp index a9f960db3..42c442c02 100644 --- a/src/BulletDynamics/Dynamics/Bullet-C-API.cpp +++ b/src/BulletDynamics/Dynamics/Bullet-C-API.cpp @@ -66,7 +66,7 @@ plDynamicsWorldHandle plCreateDynamicsWorld(plPhysicsSdkHandle physicsSdkHandle) { btPhysicsSdk* physicsSdk = reinterpret_cast(physicsSdkHandle); btDispatcher* dispatcher = new btCollisionDispatcher(); - btOverlappingPairCache* pairCache = new btAxisSweep3(physicsSdk->m_worldAabbMin,physicsSdk->m_worldAabbMax); + btBroadphaseInterface* pairCache = new btAxisSweep3(physicsSdk->m_worldAabbMin,physicsSdk->m_worldAabbMax); btConstraintSolver* constraintSolver = new btSequentialImpulseConstraintSolver(); return (plDynamicsWorldHandle) new btDiscreteDynamicsWorld(dispatcher,pairCache,constraintSolver); diff --git a/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp b/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp index fe0dddbb8..e4cd20764 100644 --- a/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp +++ b/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp @@ -57,7 +57,7 @@ subject to the following restrictions: -btDiscreteDynamicsWorld::btDiscreteDynamicsWorld(btDispatcher* dispatcher,btOverlappingPairCache* pairCache,btConstraintSolver* constraintSolver) +btDiscreteDynamicsWorld::btDiscreteDynamicsWorld(btDispatcher* dispatcher,btBroadphaseInterface* pairCache,btConstraintSolver* constraintSolver) :btDynamicsWorld(dispatcher,pairCache), m_constraintSolver(constraintSolver? constraintSolver: new btSequentialImpulseConstraintSolver), m_debugDrawer(0), diff --git a/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h b/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h index 733a47cbc..ca4a15b84 100644 --- a/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h +++ b/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h @@ -86,7 +86,7 @@ public: ///this btDiscreteDynamicsWorld constructor gets created objects from the user, and will not delete those - btDiscreteDynamicsWorld(btDispatcher* dispatcher,btOverlappingPairCache* pairCache,btConstraintSolver* constraintSolver); + btDiscreteDynamicsWorld(btDispatcher* dispatcher,btBroadphaseInterface* pairCache,btConstraintSolver* constraintSolver); virtual ~btDiscreteDynamicsWorld(); diff --git a/src/BulletDynamics/Dynamics/btDynamicsWorld.h b/src/BulletDynamics/Dynamics/btDynamicsWorld.h index cac0ef8e2..8d1e9b132 100644 --- a/src/BulletDynamics/Dynamics/btDynamicsWorld.h +++ b/src/BulletDynamics/Dynamics/btDynamicsWorld.h @@ -28,8 +28,8 @@ class btDynamicsWorld : public btCollisionWorld public: - btDynamicsWorld(btDispatcher* dispatcher,btOverlappingPairCache* pairCache) - :btCollisionWorld(dispatcher,pairCache) + btDynamicsWorld(btDispatcher* dispatcher,btBroadphaseInterface* broadphase) + :btCollisionWorld(dispatcher,broadphase) { } diff --git a/src/BulletDynamics/Dynamics/btSimpleDynamicsWorld.cpp b/src/BulletDynamics/Dynamics/btSimpleDynamicsWorld.cpp index af6e6b5a4..dc970bba4 100644 --- a/src/BulletDynamics/Dynamics/btSimpleDynamicsWorld.cpp +++ b/src/BulletDynamics/Dynamics/btSimpleDynamicsWorld.cpp @@ -32,7 +32,7 @@ extern "C" void btBulletDynamicsProbe () {} -btSimpleDynamicsWorld::btSimpleDynamicsWorld(btDispatcher* dispatcher,btOverlappingPairCache* pairCache,btConstraintSolver* constraintSolver) +btSimpleDynamicsWorld::btSimpleDynamicsWorld(btDispatcher* dispatcher,btBroadphaseInterface* pairCache,btConstraintSolver* constraintSolver) :btDynamicsWorld(dispatcher,pairCache), m_constraintSolver(constraintSolver), m_ownsConstraintSolver(false), diff --git a/src/BulletDynamics/Dynamics/btSimpleDynamicsWorld.h b/src/BulletDynamics/Dynamics/btSimpleDynamicsWorld.h index 5b00173de..90b6d8fc8 100644 --- a/src/BulletDynamics/Dynamics/btSimpleDynamicsWorld.h +++ b/src/BulletDynamics/Dynamics/btSimpleDynamicsWorld.h @@ -48,7 +48,7 @@ public: ///this btSimpleDynamicsWorld constructor creates dispatcher, broadphase pairCache and constraintSolver - btSimpleDynamicsWorld(btDispatcher* dispatcher,btOverlappingPairCache* pairCache,btConstraintSolver* constraintSolver); + btSimpleDynamicsWorld(btDispatcher* dispatcher,btBroadphaseInterface* pairCache,btConstraintSolver* constraintSolver); virtual ~btSimpleDynamicsWorld();