jokoon
jokoon

Reputation: 6633

Detecting collisions with bullet

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.

Upvotes: 4

Views: 9936

Answers (2)

Kerr
Kerr

Reputation: 431

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!

Upvotes: 5

Cdaragorn
Cdaragorn

Reputation: 344

When dealing with collision detection between spheres, you need to know 2 things: each spheres radius and their position.

You then have to go through each sphere and compare it to the others. For each pair, you need to first find out the distance between them.

http://www.purplemath.com/modules/distform.htm

That's the basic 2d distance formula, to make it 3d all you need to do is add (z2 - z1)squared to the other 2 coordinates before square rooting the result.

Once you have that distance, just add the 2 spheres radii together and compare it to the distance between them. If the distance is less than or equal to the sum of the radii, the spheres have collided.

I'm not specifically familiar with Ogre3D, but if you can transform an object, you should be able to get it's position out as well.

Upvotes: 1

Related Questions