Detecting collisions with bullet

jokoon picture jokoon · Feb 2, 2012 · Viewed 8.8k times · Source

I made an app with Ogre3D, having already spawned bullet's objects, all I need for now is to detect collisions between objects.

I looked at the CollisionInterfaceDemo demo, and it doesn't really match with my needs.

What are the required steps to detect collisions between let us say 3 spheres, only to know if it collides (I don't care about the point of collision) ?

I only know that I can move an CollisionObject by setting its transform.

Answer

Kerr picture Kerr · Feb 2, 2012

If you're using Bullet there are several demos you can look at to get you going.

But basically, here's the rundown (much of this is taken from their examples):

In your header or where ever your physics system is:

btDefaultCollisionConfiguration*        mPhysicsConfig;
btCollisionDispatcher*                  mPhysicsDispatcher;
btBroadphaseInterface*                  mPhysicsCache;
btSequentialImpulseConstraintSolver*    mPhysicsSolver;
btDiscreteDynamicsWorld*                mPhysicsWorld;
btAlignedObjectArray<btCollisionShape*> mPhysicsShapes;

First (initialization):

///collision configuration contains default setup for memory, collision setup.
mPhysicsConfig = new btDefaultCollisionConfiguration();

///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded)
mPhysicsDispatcher = new    btCollisionDispatcher(mPhysicsConfig);

///btDbvtBroadphase is a good general purpose broadphase. You can also try out btAxis3Sweep.
mPhysicsCache = new btDbvtBroadphase();

///the default constraint solver. For parallel processing you can use a different solver (see Extras/BulletMultiThreaded)
mPhysicsSolver = new btSequentialImpulseConstraintSolver;
mPhysicsWorld = new btDiscreteDynamicsWorld(mPhysicsDispatcher,mPhysicsCache,mPhysicsSolver,mPhysicsConfig);
mPhysicsWorld->setGravity(btVector3(0,-9.81f,0));

Each frame (this usually goes in an Update function):

mPhysicsWorld->stepSimulation( timestep , 10 );

Add a sphere (the pointer is just returned to make access easier after creation):

btRigidBody* MyPhysicsSystem::CreateSphere(float sx, float px, float py, float pz, float mass)
{
    btCollisionShape* colShape = new btSphereShape(btScalar(sx));
    mPhysicsShapes.push_back(colShape);

    btTransform startTransform;
    startTransform.setIdentity();

    btScalar    tMass(mass);

    //rigidbody is dynamic if and only if mass is non zero, otherwise static
    bool isDynamic = (tMass != 0.f);

    btVector3 localInertia(0,0,0);
    if (isDynamic)
        colShape->calculateLocalInertia(tMass,localInertia);

    startTransform.setOrigin(btVector3(px,py,pz));

    //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
    btDefaultMotionState* myMotionState = new btDefaultMotionState(startTransform);
    btRigidBody::btRigidBodyConstructionInfo rbInfo(tMass,myMotionState,colShape,localInertia);
    btRigidBody* body = new btRigidBody(rbInfo);
    mPhysicsWorld->addRigidBody(body);
    return body;
}

And that's about it!

To reiterate:

  1. Initialize the things bullet needs for a simulation.
  2. Create an object and add it to bullet's "world".
  3. Update that world each frame by some timestep.

Bullet will take care of the collisions for you. If you need some way to have functionality done when a collision happens, I believe you can assign a custom callback as the collision behavior that will happen.

Hope this helps!