I could implement it (more or less) using btManifoldPoint, but I think this only takes into consideration the broadphase, and all the normals it returns are based on cubes (so they only point in one axis (x y or z). When I rotated a btRigidBody with a btBoxShape 45 degrees, my program broke and wasn't detecting anything in that cube, only if I go to the edges, and it returns an incorrect normal.
Here is a screenshot of my game: http://i.imgur.com/3iT2EPJ.png (the blue tower and the grey platform are rotated, the rest isn't).
So far I did this (modified this from recoverFromPenetration of btKinematicCharacterController):
Code: Select all
btAlignedObjectArray<btVector3> Player::getObjectTouchingNormal()
{
btDiscreteDynamicsWorld* world = Physics::getSingleton()->getWorld();
mNormals->clear(); // mNormals is btAlignedObjectArray<btVector3>*
btVector3 minAabb, maxAabb;
mGhostObject->getCollisionShape()->getAabb(mGhostObject->getWorldTransform(), minAabb,maxAabb);
world->getBroadphase()->setAabb(mGhostObject->getBroadphaseHandle(),
minAabb,
maxAabb,
world->getDispatcher());
bool penetration = false;
world->getDispatcher()->dispatchAllCollisionPairs(mGhostObject->getOverlappingPairCache(), world->getDispatchInfo(), world->getDispatcher());
btScalar maxPen = btScalar(0.0);
mNumberOverlappingPairsLastUpdate = mGhostObject->getOverlappingPairCache()->getNumOverlappingPairs();
for (int i = 0; i < mNumberOverlappingPairsLastUpdate; i++)
{
btManifoldArray m_manifoldArray = btManifoldArray();
m_manifoldArray.resize(0);
btBroadphasePair* collisionPair = &mGhostObject->getOverlappingPairCache()->getOverlappingPairArray()[i];
if (collisionPair->m_algorithm)
collisionPair->m_algorithm->getAllContactManifolds(m_manifoldArray);
for (int j=0;j<m_manifoldArray.size();j++)
{
btPersistentManifold* manifold = m_manifoldArray[j];
btScalar directionSign = manifold->getBody0() == mGhostObject ? btScalar(-1.0) : btScalar(1.0);
for (int p=0;p<manifold->getNumContacts();p++)
{
stringstream ss;
ss << "textbox-";
ss << p + 2;
const btManifoldPoint&pt = manifold->getContactPoint(p);
mNormals->push_back(pt.m_normalWorldOnB);
}
}
}
return *mNormals;
}