Hi seagullrace,
the following code works for me, to check if there is a penetration.
First solution: btGjkPairDetector
Code: Select all
// objectA and objectB are of type btCollisionObject
// objectBodyA and objectBodyB are of type btRigidBody
btVoronoiSimplexSolver sGjkSimplexSolver;
btGjkEpaPenetrationDepthSolver epaSolver;
btPointCollector gjkOutput;
{
btGjkPairDetector convexConvex((btConvexShape*)objectA->getCollisionShape(), (btConvexShape*)objectB->getCollisionShape(),&sGjkSimplexSolver,&epaSolver);
btGjkPairDetector::ClosestPointInput input;
input.m_transformA = objectBodyA->getWorldTransform();
input.m_transformB = objectBodyB->getWorldTransform();
convexConvex.getClosestPoints(input, gjkOutput, 0);
}
if (gjkOutput.m_hasResult && gjkOutput.m_distance<0)
{
cout << "penetration depth = " << gjkOutput.m_distance << endl;
btVector3 contactPoint = gjkOutput.m_pointInWorld;
btScalar distance = gjkOutput.m_distance;
btVector3 normal = gjkOutput.m_normalOnBInWorld;
}
Second solution: contactPairTest with collision callback
Code: Select all
// perform collision test
btDrawingResult renderCallback;
dyn_world->contactPairTest(objectA,objectB, renderCallback);
// declaration of callback
struct btDrawingResult : public btCollisionWorld::ContactResultCallback
{
virtual btScalar addSingleResult(btManifoldPoint& cp, const btCollisionObject* colObj0,int partId0,int index0,const btCollisionObject* colObj1,int partId1,int index1)
{
std::cout << "contact!" << std::endl;
btVector3 ptA = cp.getPositionWorldOnA();
btVector3 ptB = cp.getPositionWorldOnB();
btVector3 norm = cp.m_normalWorldOnB;
return 0;
}
};
Third solution: process collision (nearly the same as in the second solution), iterate over manifolds afterwards
Code: Select all
btCollisionAlgorithm* algo = dyn_world->getDispatcher()->findAlgorithm(objectA,objectB);
btManifoldResult contactPointResult(objectA,objectB);
algo->processCollision(objectA,objectB,dyn_world->getDispatchInfo(),&contactPointResult);
btManifoldArray manifoldArray;
algo->getAllContactManifolds(manifoldArray);
int numManifolds = manifoldArray.size();
for (int i=0;i<numManifolds;i++)
{
btPersistentManifold* contactManifold = manifoldArray[i];
btCollisionObject* obA = static_cast<btCollisionObject*>(contactManifold->getBody0());
btCollisionObject* obB = static_cast<btCollisionObject*>(contactManifold->getBody1());
int numContacts = contactManifold->getNumContacts();
for (int j=0;j<numContacts;j++)
{
std::cout << "contact!" << std::endl;
btManifoldPoint& pt = contactManifold->getContactPoint(j);
btVector3 ptA = pt.getPositionWorldOnA();
btVector3 ptB = pt.getPositionWorldOnB();
}
}
The third solution also performs the collision response. This has to be avoided, if you only need collision detection.
But: I don't know how accurate or robust the collision detection of the Bullet GJK algorithm is. I have the feeling that contact pairs are missed from time to time. Lets say there is a contact pair in frame 1 and 3. It happends that in frame 2 this contact pair is not calculated even if it should be. You can see this on the screenshots in thread
http://bulletphysics.org/Bullet/phpBB3/ ... f=9&t=5365.
I know that they are heuristics in the Bullet implementation to reduce the number of contact pairs to the "most important" ones. But i do not know details about this fact. It would be interesting, if one could deactivate this feature without great efforts.
Maybe one of the pros of the Bullet board could give his thoughts about it to clarify this issue ? I think there are many peoples who would be interested in this fact.
Michael