Bullet physics in VR

Time to add some physics to my virtual world.

I installed Bullet Real-Time Physics Simulation, using CMake to target Visual Studio 2015 Win64 and then building the BULLET_PHYSICS.sln to spit out 64-bit libs for my app.

My app is a Microsoft Visual Studio C++ solution (with OpenGL graphics library and the Oculus SDK for Windows). I configure it to point to the Bullet src and libs. And then I drop the Bullet Hello World code into a handy class:

#include <btBulletDynamicsCommon.h>

class PhysicsClient
{

private:
    btRigidBody* fallRigidBody;
    btRigidBody* groundRigidBody;
    btCollisionShape* fallShape;
    btCollisionShape* groundShape;
    btDiscreteDynamicsWorld* dynamicsWorld;
    btSequentialImpulseConstraintSolver* solver;
    btDefaultCollisionConfiguration* collisionConfiguration;
    btCollisionDispatcher* dispatcher;
    btBroadphaseInterface* broadphase;

public:

    PhysicsClient()
    {
        broadphase = new btDbvtBroadphase();

        collisionConfiguration = new btDefaultCollisionConfiguration();
        dispatcher = new btCollisionDispatcher(collisionConfiguration);

        solver = new btSequentialImpulseConstraintSolver;

        dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher, broadphase, solver, collisionConfiguration);

        dynamicsWorld->setGravity(btVector3(0, -10, 0));

        groundShape = new btStaticPlaneShape(btVector3(0, 1, 0), 1);

        fallShape = new btSphereShape(1);

        btDefaultMotionState* groundMotionState = new btDefaultMotionState(btTransform(btQuaternion(0, 0, 0, 1), btVector3(0, -1, 0)));
        btRigidBody::btRigidBodyConstructionInfo
            groundRigidBodyCI(0, groundMotionState, groundShape, btVector3(0, 0, 0));
        groundRigidBody = new btRigidBody(groundRigidBodyCI);
        dynamicsWorld->addRigidBody(groundRigidBody);

        btDefaultMotionState* fallMotionState =
            new btDefaultMotionState(btTransform(btQuaternion(0, 0, 0, 1), btVector3(0, 50, 0)));
        btScalar mass = 1;
        btVector3 fallInertia(0, 0, 0);
        fallShape->calculateLocalInertia(mass, fallInertia);
        btRigidBody::btRigidBodyConstructionInfo fallRigidBodyCI(mass, fallMotionState, fallShape, fallInertia);
        fallRigidBody = new btRigidBody(fallRigidBodyCI);
        dynamicsWorld->addRigidBody(fallRigidBody);
    }

    ~PhysicsClient()
    {
        dynamicsWorld->removeRigidBody(fallRigidBody);
        delete fallRigidBody->getMotionState();
        delete fallRigidBody;

        dynamicsWorld->removeRigidBody(groundRigidBody);
        delete groundRigidBody->getMotionState();
        delete groundRigidBody;

        delete fallShape;

        delete groundShape;

        delete dynamicsWorld;
        delete solver;
        delete collisionConfiguration;
        delete dispatcher;
        delete broadphase;
    }

    float StepSimulation() {
        dynamicsWorld->stepSimulation(1 / 60.f, 10);

        btTransform trans;
        fallRigidBody->getMotionState()->getWorldTransform(trans);

        return trans.getOrigin().getY();
    }
};

Great.

Next, I create a simple sphere mesh in Blender (the free and open source 3D creation suite) and import it into my virtual world.

All that’s left is to update my sphere’s height in the virtual world to match the physics:

// physics only on one side of the room
if (pos.x < 5.0f) return;

// get ycoord from Bullet physics
float ycoord = physicsClient->StepSimulation();

// update ball ycoord to match physics
for (int i = 0; i < numMyModels; ++i) {
    if (MyModels[i]->MyModelName == Zoodo_Floor1_Ball) {

        for (int j = 0; j < MyModels[i]->numMyMeshes; ++j) {
            MyModels[i]->MyMeshes[j]->Pos.y = ycoord;
        }

        break;
    }
}

I put on my Oculus Rift virtual reality headset, stroll across the room, and watch the sphere fall from the night sky and crash through a table.

Here’s a video of Bullet Real-Time Physics Simulation in my virtual world:

Time to get more physical.

Ciao!

https://myspace.com/rdmilligan/music/album/bones-ep-19172460