Manually process and resolve collisions for Kinematic Body

Post Reply
thegeneralsolution
Posts: 16
Joined: Sun Jul 05, 2015 12:55 am

Manually process and resolve collisions for Kinematic Body

Post by thegeneralsolution »

I am building a custom character controller, using a kinematic rigid body and I need to manually handle my own collisions. Nothing super complicated, just need to get the collision contacts, contact points, normals, etc.

http://www.bulletphysics.org/mediawiki- ... d_Triggers
Looking at the documentation, I see a manual way to iterate through collision contacts is available:
//Assume world->stepSimulation or world->performDiscreteCollisionDetection has been called

int numManifolds = world->getDispatcher()->getNumManifolds();
for (int i=0;i<numManifolds;i++)
{
btPersistentManifold* contactManifold = world->getDispatcher()->getManifoldByIndexInternal(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++)
{
btManifoldPoint& pt = contactManifold->getContactPoint(j);
if (pt.getDistance()<0.f)
{
const btVector3& ptA = pt.getPositionWorldOnA();
const btVector3& ptB = pt.getPositionWorldOnB();
const btVector3& normalOnB = pt.m_normalWorldOnB;
}
}
}
My thing is I don't know if these contacts are going to be generated for a kinematic rigid body, without some special trickery. Moreover, I would have to iterate over all the contacts and find the contacts that correspond to the rigid body I want, and then handle the collisions, which seems potentially slow and inefficient.

So maybe I want a way to quickly check for all collisions against my particular object? Or maybe, since there may be several such objects in the scene, its more efficient to compute all the contacts together in one fell swoop.

Please advise!
User avatar
drleviathan
Posts: 849
Joined: Tue Sep 30, 2014 6:03 pm
Location: San Francisco

Re: Manually process and resolve collisions for Kinematic Bo

Post by drleviathan »

One way to do it is to use a btPairCachingGhostObject which is used by the btKinematicCharacterController and is mentioned in this wiki page.
thegeneralsolution
Posts: 16
Joined: Sun Jul 05, 2015 12:55 am

Re: Manually process and resolve collisions for Kinematic Bo

Post by thegeneralsolution »

Thank you for that response! I think that should work just fine for my purposes.

I guess now the question becomes, how do I process the collisions in the traditional way bullet would? Do I need to compute an impulse to separate the objects by the depth of penetration, along the direction of the contact normal?
User avatar
drleviathan
Posts: 849
Joined: Tue Sep 30, 2014 6:03 pm
Location: San Francisco

Re: Manually process and resolve collisions for Kinematic Bo

Post by drleviathan »

You can just update the kinematic btGhostObject's world transform as you see fit. Don't worry about updating other objects -- f you set the character's velocities correctly then dynamic objects that collide against it will be influenced accordingly -- the velocity doesn't actually move the kinematic object for you (you have to do that yourself, probably in CharacterController::playerStep()).

You can see how the contact points of the btGhostObject's position is updated in btKinematicCharacterController. In particular the playerStep() method calls recoverFromPenetration() several times to try to extract the capsule from any penetration prior to doing the sweep tests, since otherwise the sweeps would fail at the start. This is just one way to do it -- they moving the character by sweeping it forward... first up to see how high of a step can be taken, then forward (stopping if it hits a wall), then down to the floor.

Note: how exactly the contact details are created inside recoverFromPenetration() is a bit obfuscated but the secret is that the btCollisionDispatcher::dispatchAllCollisionPairs() call creates btBroadphasePair's, each which has a pointer to a btCollisionAlgorithm... and the details of the contact are created inside the algorithm's constructor.
Post Reply