This is how it looks in client code:
Code: Select all
//set the callbacks somewhere
gCollisionStartedCallback = CollisionStarted;
gCollisionEndedCallback = CollisionEnded;
static void CollisionStarted(btPersistentManifold* manifold)
{
btCollisionObject* obA = static_cast<btCollisionObject*>(manifold->getBody0());
btCollisionObject* obB = static_cast<btCollisionObject*>(manifold->getBody1());
PhysicsComponent* phyA = (PhysicsComponent*) obA->getUserPointer();
PhysicsComponent* phyB = (PhysicsComponent*) obB->getUserPointer();
if(!phyA || !phyB)
return;
printf("Collision started between: %s, %s.\n", phyA->_parent->Name.c_str(), phyB->_parent->Name.c_str());
}
static void CollisionEnded(btPersistentManifold* manifold)
{
btCollisionObject* obA = static_cast<btCollisionObject*>(manifold->getBody0());
btCollisionObject* obB = static_cast<btCollisionObject*>(manifold->getBody1());
PhysicsComponent* phyA = (PhysicsComponent*) obA->getUserPointer();
PhysicsComponent* phyB = (PhysicsComponent*) obB->getUserPointer();
if(!phyA || !phyB)
return;
printf("Collision ended between: %s, %s.\n", phyA->_parent->Name.c_str(), phyB->_parent->Name.c_str());
}
The changes to Bullet are a mere handful of lines, and attached to this post as a patch. The logic is dead simple: If a contact is added to a manifold with zero contacts, trigger gCollisionStarted. If a contact is removed leaving a manifold with zero contacts, trigger gCollisionEnded. Personally I think this is what most people want. This may not work well if you need all of the contact points, as the collision started callback triggers as soon as a single point is available.
I'm posting this here first in case I did something incredibly stupid or unnecessary, but all of the stuff I've seen in the forums and documentation is waaaay more of a PITA than what I've put together here. If this is something useful and productive, I'll probably publish on GameDev and my blog, dunno if it's appropriate for inclusion into Bullet main-line.