Using btGhostObject

conormcc
Posts: 6
Joined: Thu Apr 09, 2009 9:25 am

Using btGhostObject

Post by conormcc »

Hi all,

I am trying to use a ghost object to determine whether or not I can move a dynamic rigid body to the chosen location without coming into contact with other dynamic rigid bodies. I have done the following:

Code: Select all

ghostObject = new btGhostObject();
ghostObject->setCollisionShape(boxShape);
ghostObject->setCollisionFlags(btCollisionObject::CF_NO_CONTACT_RESPONSE);
sDynamicsWorld->addCollisionObject(ghostObject,btBroadphaseProxy::SensorTrigger,btBroadphaseProxy::AllFilter & ~btBroadphaseProxy::SensorTrigger);
        
// set the new location
ghostObject->setWorldTransform(transform);
int num = ghostObject->getNumOverlappingObjects();
Unfortunately, num is always 0. What am I doing wrong?

Also, I would like to use btPairCachingGhostObject for real object collision rather than AABBs. Do these only get calculated after stepSimulation? I'd like to move the ghost object and look for collisions without any physics steps. Is this possible?

Thanks
Flix
Posts: 456
Joined: Tue Dec 25, 2007 1:06 pm

Re: Using btGhostObject

Post by Flix »

I don't have a final solution, but:

It may be that the transform is wrong (many people just write: btTransform T;T.setOrigin(...); and think that the code is correct) or that the other objects in the world still needs to be created or that maybe some physic steps must already been performed before the code you posted can be used. I suggest you monitor ghostObject->getNumOverlappingObjects() each step.
Flix
Posts: 456
Joined: Tue Dec 25, 2007 1:06 pm

Re: Using btGhostObject

Post by Flix »

I forget the last question:
Also, I would like to use btPairCachingGhostObject for real object collision rather than AABBs. Do these only get calculated after stepSimulation? I'd like to move the ghost object and look for collisions without any physics steps. Is this possible?
I use this code for narrowphase collision detection using ghost objects: it just detect the objects inside it whenever you call it (no steps needed):

Code: Select all

// Main method: fills a m_objectsInFrustum aligned vector.
void GlutDemoApplicationEx::performGhostObjectNarrowphaseDetection()	{
	m_objectsInFrustum.resize(0);	// clear() is probably slower
	if (!m_ghostObject  || !m_dynamicsWorld) return;
	
	//======================================================================================================
// This is the expensive operation to trigger the narrowphase detection:	m_dynamicsWorld->getDispatcher()->dispatchAllCollisionPairs(m_ghostObject->getOverlappingPairCache(), m_dynamicsWorld->getDispatchInfo(), m_dynamicsWorld->getDispatcher());
//======================================================================================================
	
	btBroadphasePairArray& collisionPairs = m_ghostObject->getOverlappingPairCache()->getOverlappingPairArray();	//New
  	const int	numObjects=collisionPairs.size();	
	static btManifoldArray	m_manifoldArray;
	bool added;
	for(int i=0;i<numObjects;i++)	{
    	const btBroadphasePair& collisionPair = collisionPairs[i];
		m_manifoldArray.resize(0);
		if (collisionPair.m_algorithm) collisionPair.m_algorithm->getAllContactManifolds(m_manifoldArray);
		else printf("No collisionPair.m_algorithm - probably m_dynamicsWorld->getDispatcher()->dispatchAllCollisionPairs(...) must be missing.\n");
		added = false;
		for (int j=0;j<m_manifoldArray.size();j++)	{
			btPersistentManifold* manifold = m_manifoldArray[j];
			// Here we are in the narrowphase, but can happen that manifold->getNumContacts()==0:
			if (m_processOnlyObjectsWithNegativePenetrationDistance)	{
				for (int p=0;p<manifold->getNumContacts();p++)			{
					const btManifoldPoint&pt = manifold->getContactPoint(p);
					if (pt.getDistance() < 0.0) 	{
						// How can I be sure that the colObjs are all distinct ? I use the "added" flag.
						m_objectsInFrustum.push_back((btCollisionObject*) (manifold->getBody0() == m_ghostObject ? manifold->getBody1() : manifold->getBody0()));
						added = true;
						break;
					}	
				}
			if (added) break;
			}
			else if (manifold->getNumContacts()>0) {
				m_objectsInFrustum.push_back((btCollisionObject*) (manifold->getBody0() == m_ghostObject ? manifold->getBody1() : manifold->getBody0()));
				break;
			}
		}
	}	
}
Hope you like it :) .
conormcc
Posts: 6
Joined: Thu Apr 09, 2009 9:25 am

Re: Using btGhostObject

Post by conormcc »

Thanks for your help Flix. Looks like I was also missing this call at setup:

Code: Select all

sBroadphase->getOverlappingPairCache()->setInternalGhostPairCallback(new btGhostPairCallback());
Conor