Code: Select all
static bool physicsComputePenetration( btCollisionWorld* collisionWorld,
btBroadphasePair* collisionPair,
btCollisionObject* penetrator,
btVector3* minDepenetrationDirection,
btScalar* minDepenetrationDistance )
{
btCollisionObject* obj0 = static_cast<btCollisionObject*>(collisionPair->m_pProxy0->m_clientObject);
btCollisionObject* obj1 = static_cast<btCollisionObject*>(collisionPair->m_pProxy1->m_clientObject);
if ((obj0 && !obj0->hasContactResponse()) || (obj1 && !obj1->hasContactResponse())) {
Ogre::LogManager::getSingleton().logMessage("No contact");
return false;
}
Ogre::LogManager::getSingleton().logMessage("Contact happened");
if (!needsCollision(obj0, obj1)) {
Ogre::LogManager::getSingleton().logMessage("No collision");
return false;
}
Ogre::LogManager::getSingleton().logMessage("Collision happened");
btManifoldArray manifoldArray;
if (collisionPair->m_algorithm)
collisionPair->m_algorithm->getAllContactManifolds(manifoldArray);
Ogre::LogManager::getSingleton().logMessage("Num manifolds in collision = "
+ Ogre::StringConverter::toString(manifoldArray.size()));
btScalar maxPenetration = btScalar(0.0); // TODO: Why is this 0 ???
bool isPenetrating = false;
for (int j = 0; j < manifoldArray.size(); j++)
{
btPersistentManifold* manifold = manifoldArray[j];
btScalar directionSign = manifold->getBody0() == penetrator ? btScalar(-1.0) : btScalar(1.0);
Ogre::LogManager::getSingleton().logMessage(
"Num Contact Points in Manifold "
+ Ogre::StringConverter::toString(j)
+ " = "
+ Ogre::StringConverter::toString(manifold->getNumContacts())
);
for (int p = 0; p < manifold->getNumContacts(); p++)
{
const btManifoldPoint& pt = manifold->getContactPoint(p);
btScalar dist = pt.getDistance();
Ogre::LogManager::getSingleton().logMessage(
"Contact Point "
+ Ogre::StringConverter::toString(p) + "'s "
+ " Distance = "
+ Ogre::StringConverter::toString(dist)
);
if (dist < maxPenetration)
{
maxPenetration = dist;
*minDepenetrationDirection = pt.m_normalWorldOnB * directionSign * dist;
*minDepenetrationDistance = minDepenetrationDirection->length();
*minDepenetrationDirection = minDepenetrationDirection->normalized();
isPenetrating = true;
}
}
}
return isPenetrating;
}
I should clarify and say this would be used as a helper function for a kinematic character controller using a btPairCachingGhostObject. The function above is just a factored-out version of the inner-most block of the recoverFromPenetration function in Bullet's existing kinematic character controller example.