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
This commit is contained in:
erwin.coumans
2008-11-17 18:40:21 +00:00
parent bc131321a8
commit fe461296c6
3 changed files with 31 additions and 21 deletions

View File

@@ -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();

View File

@@ -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 (index<m_overlappingObjects.size())
{
m_overlappingObjects[index] = m_overlappingObjects[m_overlappingObjects.size()-1];
m_overlappingObjects.pop_back();
m_hashPairCache->removeOverlappingPair(getBroadphaseHandle(),otherProxy,dispatcher);
m_hashPairCache->removeOverlappingPair(actualThisProxy,otherProxy,dispatcher);
}
}

View File

@@ -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;
}