C++ – Bullet Physics Simplest Collision Example

bulletphysicscgame-physics

I'm trying to use Bullet Physics for collision detection only. I don't need it to move any objects for me or handle rendering with callbacks. I just want to update object locations every frame and use it to tell me when I have collisions. To get the simplest example going, I'm trying to find collisions between objects with btBoxShape as their shape. Everything runs fine without crashes or apparent memory leaks, but I get no collisions so I must be making some mistakes somewhere. I'll try to keep this as brief as I can without leaving anything important out.

Here's my world setup function:

collisionConfig      = new btDefaultCollisionConfiguration();
dispatcher           = new btCollisionDispatcher(collisionConfig);
overlappingPairCache = new btDbvtBroadphase();
solver               = new btSequentialImpulseConstraintSolver;
dynamicsWorld        = new btDiscreteDynamicsWorld(dispatcher, 
overlappingPairCache, solver, collisionConfig);         

dynamicsWorld->setGravity(btVector3(0.0f, -9.8f, 0.0f));

Right now I have player and enemy objects of the type btCollisionObject*. I'm setting them up like this:

mPlayerBox = new btBoxShape(btVector3(1,3,1));
mPlayerObject = new btCollisionObject();
mPlayerObject->setCollisionShape(mPlayerBox);
btTransform playerWorld;
playerWorld.setIdentity();
//playerPos is a D3DXVECTOR3 that holds the camera position.
playerWorld.setOrigin(btVector3(playerPos.x, playerPos.y, playerPos.z));
mPlayerObject->setWorldTransform(playerWorld);
mPlayerObject->forceActivationState(DISABLE_DEACTIVATION);//maybe not needed
dynamicsWorld->addCollisionObject(mPlayerObject);

I do essentially the same thing with my enemy objects.

Then every frame I update all my objects with something like this:

btTransform updatedWorld;
updatedWorld.setIdentity();
updatedWorld.setOrigin(btVector3(position.x, position.y, position.z));
mPlayerObject->setWorldTransform(updatedWorld);

//do the same for my enemies, and then...

dynamicsWorld->performDiscreteCollisionDetection();
//Also tried doing this with stepSimulation(deltaTime, 7), but nothing changed.
//stepSimulation seems to only be for letting Bullet set world Transforms?

//check collisions with player
dynamicsWorld->contactTest(mPlayerObject, resultCallback);
int numManifolds = dynamicsWorld->getDispatcher()->getNumManifolds();
if(numManifolds > 0)
{
   //there's a collision, execute blah blah blah
}

And finally, here's the structure that defines my result callback:

struct rCallBack : public btCollisionWorld::ContactResultCallback
{
 btScalar rCallback::addSingleResult(btManifoldPoint& cp, const btCollisionObject*
 colObj0, int partId0, int index0, const btCollisionObject* colObj1, int partId1,
 int index1)
 {
   btVector3 ptA = cp.getPositionWorldOnA();
   btVector3 ptB = cp.getPositionWorldOnB();
   return 0;
 }
}

I've looked at a lot of the demos, but they seem to mostly be leaving the movement up to Bullet, and since I'm moving characters at a set speed without any special physics when they collide, I had trouble adapting the examples into my application. The result callback actually came from this post on the forums:
http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=6816
It's about using triangle meshes, but it seemed closest to what I was trying to implement.

Anyway, if you read this far, thank you!! Any advice or links you could spare would be very much appreciated.

Best Answer

I am writing an IOS app with flighter shooting each other on 3D scene. I use bullet physics for collision detection I set the flighter as kinematic object, my logic move the flighter and then update the btMotionState worldTransform of the kinematic object. I also don't get any collision detections until i change the following two statements (set the masking and group to the same for both player and enemy)

dynamicsWorld->addRigidBody(mPlayerObject,1,1);
dynamicsWorld->addRigidBody(mEnemyObject,1,1);
...
dynamicsWorld->setInternalTickCallback(myTickCallback);

then i can see the

void myTickCallback(btDynamicsWorld *world, btScalar timeStep) {
    int numManifolds = world->getDispatcher()->getNumManifolds();
    printf("numManifolds = %d\n",numManifolds);
}

numManifolds value become 1 when object collides.

Related Topic