OgreBullet RigidBOdy collision detection

739 Views Asked by At

Im having trouble with finding functions in the OgreBulletDynamics wrapper. Im trying to detect collision between 2 rigibodies using the example from the bullet wiki http://bulletphysics.org/mediawiki-1.5.8/index.php/Collision_Callbacks_and_Triggers In the Contact Information example it wants

btCollisionObject* obA = static_cast<btCollisionObject*>(contactManifold->getBody0());
btCollisionObject* obB = static_cast<btCollisionObject*>(contactManifold->getBody1());

btCollision object only works with btRigidBody and not OgreBulletDynamics::RigidBody and I cant find where btCollision in OgreBullet is.

In contactTest example, it is creating a struct derived from public btCollisionWorld::ContactResultCallback?

but I cant pass by OgreBulletDynamics RigidBody because it cant convert from OgreBulletDynamics::RigidBody to btRigidBody.

Where can I access the btCollisionWorld in OgreBulletDynamics from?

Thanks

1

There are 1 best solutions below

0
On

Though I am late in answering this question, but It may help others. For collision detection in OgreBullet you need to rely on Bullet's official APIs. I assume you have Basic Architecture of application provided by Ogre3d. There is a method bool frameRenderingQueued(const Ogre::FrameEvent &fe); this method is called every time when there is a frame queued to display. And off-course you are doing some other things in that. Just copy the below function as I took this function from Collision Callbacks and Triggers:

void MainApp::checkCollisions()
{
    btCollisionWorld *collisionWorld = mBulletWorld->getBulletCollisionWorld();
    btDynamicsWorld *dynamicWorld = mBulletWorld->getBulletDynamicsWorld();

    int numManifolds = collisionWorld->getDispatcher()->getNumManifolds();
    bool collide = false;
    for (int i=0;i<numManifolds;i++)
    {
        btPersistentManifold* contactManifold =  collisionWorld->getDispatcher()->getManifoldByIndexInternal(i);
        btCollisionObject* obA = (btCollisionObject *) contactManifold->getBody0();
        btCollisionObject* obB = (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;
                collide = true;
                std::cout << "Collision Body A: " << obA->getCollisionShape()->getName() << std::endl;
                std::cout << "Collision Body B: " << obB->getCollisionShape()->getName() << std::endl;
            }
        }
    }

    // this is label for debugging
    mInfoLabel->setCaption("Collision = " + Ogre::StringConverter::toString(collide));
}

just call this method in bool frameRenderingQueued(const Ogre::FrameEvent &fe); method at very end. Every time if there is a collision, you will have collide bool to true, otherwise false.

Moreover if you want to have some operation on the Node, this btCollisionObject is representing, you need to do something extra for that. when you create the RigidBody like:

OgreBulletDynamics::RigidBody *defaultBody = new 
OgreBulletDynamics::RigidBody("Body_Name", mBulletWorld);

then just add your created node in this defaultBody like this:

defaultBody->getBulletObject()->setUserPointer((void *) node);

then retrieve it like this:

Ogre::SceneNode *node = (Ogre::SceneNode *) obA->getUserPointer();

now you have node, you can do anything with it.

cheers :-)