Rigid body test, using the Bullet physics library (C++)

> Coding, hacking, computer graphics, game dev, and such...
User avatar
fips
Site Admin
Posts: 170
Joined: Wed Nov 12, 2008 9:49 pm
Location: Prague
Contact:

Rigid body test, using the Bullet physics library (C++)

Post by fips »

I'm currently looking for a flexible abstraction of 3D Renderer, Physics and independent Mesh representation. As a result of this effort a simple Rigid Body test came out. Note that due to the presence of a video capturer, the simulation is rather jerky.
I think I'm pretty close to the optimal abstraction. The renderer supports both immediate and retained mode, which is flexible enough for all kinds of task. Not just for a rigid engine.

Below, there’s the source of the test (it uses OpenGL for graphics and Bullet Physics Library for physics).

Code: Select all

// Rigid Body Test (c) 2009 Filip STOKLAS (FipS), http://HOLE.4FipS.com

#include "fs_e3d_rend_gl.h"
#include "fs_e3d_rend_help.h"
#include "fs_e3d_phys_blt.h"

#include <glut.h>

using namespace fs::e3d::rend;
using namespace fs::e3d::phys;
using namespace fs::math;

// renderer
typedef RendererHelper_T<gl::OpenGlRenderer_t> Renderer_t;
Renderer_t & Rend()
{
    static Renderer_t Rend(gl::OpenGlRenderer_t::Instance());
    return Rend;
}

// physics
typedef blt::BulletPhysics_t Physics_t;
Physics_t & Phys()
{
    return Physics_t::Instance();
}

// create a bunch of rigid boxes
typedef fs::e3d::phys::RigidBody_T<Physics_t> RigidBody_t;
typedef RigidBody_t::Box_t Box_t;
RigidBody_t Body1(Phys(), Box_t(), Matrix44_t::BeXyz(0.f, 0.f, 30.f));
RigidBody_t Body2(Phys(), Box_t(), Matrix44_t::BeXyz(.5f, 0.f, 40.f));
RigidBody_t Body3(Phys(), Box_t(), Matrix44_t::BeXyz(0.f, .5f, 50.f));
RigidBody_t Body4(Phys(), Box_t(), Matrix44_t::BeXyz(.5f, .5f, 60.f));
RigidBody_t Body5(Phys(), Box_t(), Matrix44_t::BeXyz(0.f, 0.f, 70.f));
RigidBody_t *Bodies[] = { &Body1, &Body2, &Body3, &Body4, &Body5 };

void OnSize(int w, int h)
{
    glViewport(0, 0, w, h);
 
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    
    const float fRatio = (float)w / (float)(h > 0 ? h : 1);
    gluPerspective(45.f, fRatio, 1.f, 1000.f);
        
    gluLookAt(
     10.f * 2, -20.f * 2, 10.f * 2, // eye
     0.f, 0.f, 0.f, // target
     0.f, 0.f, 1.f  // up
    );
    
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
}

void OnRender(void)
{
    // run the simulation step
    Phys().Simulate();

    // render the scene
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glPushMatrix();
    {
        // grid & origin
        Rend().Bare().DrawXyGrid(1.f, 60);
        Rend().Bare().DrawCoords(3.f);
        
        // rigid boxes
        for(int i = 0; i < sizeof(Bodies) / sizeof(Bodies[0]); ++i)
        {
            Rend().SetModelMatrix(Bodies[i]->GetWorldMatrix());
            Rend().Bare().DrawCoords(1.f);
            Rend().DrawBox(AxialBox_t(Vector4_t::BeZeroPoint(), 1.f));
        }
    }
    glPopMatrix();
    glutSwapBuffers();
}

int main(int argc, char **argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
    glutInitWindowPosition(100, 100);
    glutInitWindowSize(800, 600);
    glutCreateWindow("Rigid Body Test by FipS, http://HOLE.4FipS.com");
    glutDisplayFunc(OnRender);
    glutIdleFunc(OnRender);
    glutReshapeFunc(OnSize);
    glutMainLoop();

    return 0;
}