From fe461296c6c8ea32a65aae9a820ace73ff821709 Mon Sep 17 00:00:00 2001 From: "erwin.coumans" Date: Mon, 17 Nov 2008 18:40:21 +0000 Subject: [PATCH] Fix issue with un-initialized broadphase proxy during broadphase insert. It was an chicken-egg problem: 1) creating a broadphase proxy -> adding pairs during insertion. But during this pair insertion, the btGhostObject broadphase handle isn't set yet (it is done in step 2) 2) assign the broadphase proxy to btGhostObject Thanks to ihar3d for the report http://bulletphysics.com/Bullet/phpBB3/viewtopic.php?f=9&t=2864 --- Demos/CharacterDemo/CharacterDemo.cpp | 12 +++++------ .../CollisionDispatch/btGhostObject.cpp | 20 +++++++++++++------ .../CollisionDispatch/btGhostObject.h | 20 ++++++++++--------- 3 files changed, 31 insertions(+), 21 deletions(-) diff --git a/Demos/CharacterDemo/CharacterDemo.cpp b/Demos/CharacterDemo/CharacterDemo.cpp index 1c360403c..02e353cac 100644 --- a/Demos/CharacterDemo/CharacterDemo.cpp +++ b/Demos/CharacterDemo/CharacterDemo.cpp @@ -90,12 +90,6 @@ void CharacterDemo::initPhysics() m_character = new btKinematicCharacterController (m_ghostObject,capsule,stepHeight); #endif - - ///only collide with static for now (no interaction with dynamic objects) - m_dynamicsWorld->addCollisionObject(m_ghostObject,btBroadphaseProxy::CharacterFilter, btBroadphaseProxy::StaticFilter|btBroadphaseProxy::DefaultFilter); - - m_dynamicsWorld->addCharacter(m_character); - //////////////// /// Create some basic environment from a Quake level @@ -142,6 +136,12 @@ void CharacterDemo::initPhysics() fclose(file); } + ///only collide with static for now (no interaction with dynamic objects) + m_dynamicsWorld->addCollisionObject(m_ghostObject,btBroadphaseProxy::CharacterFilter, btBroadphaseProxy::StaticFilter|btBroadphaseProxy::DefaultFilter); + + m_dynamicsWorld->addCharacter(m_character); + + /////////////// clientResetScene(); diff --git a/src/BulletCollision/CollisionDispatch/btGhostObject.cpp b/src/BulletCollision/CollisionDispatch/btGhostObject.cpp index 06b1e6c1c..ffa788bb7 100644 --- a/src/BulletCollision/CollisionDispatch/btGhostObject.cpp +++ b/src/BulletCollision/CollisionDispatch/btGhostObject.cpp @@ -30,18 +30,20 @@ btGhostObject::~btGhostObject() } -void btGhostObject::addOverlappingObject(btBroadphaseProxy* otherProxy) +void btGhostObject::addOverlappingObjectInternal(btBroadphaseProxy* otherProxy,btBroadphaseProxy* thisProxy) { btCollisionObject* otherObject = (btCollisionObject*)otherProxy->m_clientObject; btAssert(otherObject); + ///if this linearSearch becomes too slow (too many overlapping objects) we should add a more appropriate data structure int index = m_overlappingObjects.findLinearSearch(otherObject); if (index==m_overlappingObjects.size()) { + //not found m_overlappingObjects.push_back(otherObject); } } -void btGhostObject::removeOverlappingObject(btBroadphaseProxy* otherProxy,btDispatcher* dispatcher) +void btGhostObject::removeOverlappingObjectInternal(btBroadphaseProxy* otherProxy,btDispatcher* dispatcher,btBroadphaseProxy* thisProxy) { btCollisionObject* otherObject = (btCollisionObject*)otherProxy->m_clientObject; btAssert(otherObject); @@ -64,28 +66,34 @@ btPairCachingGhostObject::~btPairCachingGhostObject() btAlignedFree( m_hashPairCache ); } -void btPairCachingGhostObject::addOverlappingObject(btBroadphaseProxy* otherProxy) +void btPairCachingGhostObject::addOverlappingObjectInternal(btBroadphaseProxy* otherProxy,btBroadphaseProxy* thisProxy) { + btBroadphaseProxy*actualThisProxy = thisProxy ? thisProxy : getBroadphaseHandle(); + btAssert(actualThisProxy); + btCollisionObject* otherObject = (btCollisionObject*)otherProxy->m_clientObject; btAssert(otherObject); int index = m_overlappingObjects.findLinearSearch(otherObject); if (index==m_overlappingObjects.size()) { m_overlappingObjects.push_back(otherObject); - m_hashPairCache->addOverlappingPair(getBroadphaseHandle(),otherProxy); + m_hashPairCache->addOverlappingPair(actualThisProxy,otherProxy); } } -void btPairCachingGhostObject::removeOverlappingObject(btBroadphaseProxy* otherProxy,btDispatcher* dispatcher) +void btPairCachingGhostObject::removeOverlappingObjectInternal(btBroadphaseProxy* otherProxy,btDispatcher* dispatcher,btBroadphaseProxy* thisProxy1) { btCollisionObject* otherObject = (btCollisionObject*)otherProxy->m_clientObject; + btBroadphaseProxy* actualThisProxy = thisProxy1 ? thisProxy1 : getBroadphaseHandle(); + btAssert(actualThisProxy); + btAssert(otherObject); int index = m_overlappingObjects.findLinearSearch(otherObject); if (indexremoveOverlappingPair(getBroadphaseHandle(),otherProxy,dispatcher); + m_hashPairCache->removeOverlappingPair(actualThisProxy,otherProxy,dispatcher); } } diff --git a/src/BulletCollision/CollisionDispatch/btGhostObject.h b/src/BulletCollision/CollisionDispatch/btGhostObject.h index 9bca9ed23..a2e57f7bd 100644 --- a/src/BulletCollision/CollisionDispatch/btGhostObject.h +++ b/src/BulletCollision/CollisionDispatch/btGhostObject.h @@ -47,9 +47,10 @@ public: void rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, btCollisionWorld::RayResultCallback& resultCallback) const; - virtual void addOverlappingObject(btBroadphaseProxy* otherProxy); - - virtual void removeOverlappingObject(btBroadphaseProxy* otherProxy,btDispatcher* dispatcher); + ///this method is mainly for expert/internal use only. + virtual void addOverlappingObjectInternal(btBroadphaseProxy* otherProxy, btBroadphaseProxy* thisProxy=0); + ///this method is mainly for expert/internal use only. + virtual void removeOverlappingObjectInternal(btBroadphaseProxy* otherProxy,btDispatcher* dispatcher,btBroadphaseProxy* thisProxy=0); int getNumOverlappingObjects() const { @@ -105,9 +106,10 @@ public: virtual ~btPairCachingGhostObject(); - virtual void addOverlappingObject(btBroadphaseProxy* otherProxy); + ///this method is mainly for expert/internal use only. + virtual void addOverlappingObjectInternal(btBroadphaseProxy* otherProxy, btBroadphaseProxy* thisProxy=0); - virtual void removeOverlappingObject(btBroadphaseProxy* otherProxy,btDispatcher* dispatcher); + virtual void removeOverlappingObjectInternal(btBroadphaseProxy* otherProxy,btDispatcher* dispatcher,btBroadphaseProxy* thisProxy=0); btHashedOverlappingPairCache* getOverlappingPairCache() { @@ -139,9 +141,9 @@ public: btGhostObject* ghost0 = btGhostObject::upcast(colObj0); btGhostObject* ghost1 = btGhostObject::upcast(colObj1); if (ghost0) - ghost0->addOverlappingObject(proxy1); + ghost0->addOverlappingObjectInternal(proxy1, proxy0); if (ghost1) - ghost1->addOverlappingObject(proxy0); + ghost1->addOverlappingObjectInternal(proxy0, proxy1); return 0; } @@ -152,9 +154,9 @@ public: btGhostObject* ghost0 = btGhostObject::upcast(colObj0); btGhostObject* ghost1 = btGhostObject::upcast(colObj1); if (ghost0) - ghost0->removeOverlappingObject(proxy1,dispatcher); + ghost0->removeOverlappingObjectInternal(proxy1,dispatcher,proxy0); if (ghost1) - ghost1->removeOverlappingObject(proxy0,dispatcher); + ghost1->removeOverlappingObjectInternal(proxy0,dispatcher,proxy1); return 0; }