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:
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?
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.
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):
// 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;
}
}
}
}