Irrlicht & Bullet Physics 2

Post those lines of code you feel like sharing or find what you require for your project here; or simply use them as tutorials.
Post Reply
GameDude
Posts: 498
Joined: Thu May 24, 2007 12:24 am

Irrlicht & Bullet Physics 2

Post by GameDude »

Hello,

This is another physics test using Irrlicht and Bullet. It is based off the Bullet and Irrlicht tutorial in the wiki.

Code: Select all

https://www.youtube.com/watch?v=vL0xvxHysl0&feature=plcp
I have provided a link to the video, so you can see what it looks like.

Main.h

Code: Select all

#include <stdlib.h>
#include <stdio.h>
 
#include <irrlicht.h>
 
#include <btBulletDynamicsCommon.h>
#include <btBulletCollisionCommon.h>
 
using namespace std;
 
using namespace irr;
using namespace core;
using namespace video;
using namespace scene;
using namespace io;
using namespace gui;
 
main.cpp

Code: Select all

#include "main.h"
 
static void CreateStartScene();
static void CreateBox(const btVector3 &TPosition, const vector3df &TScale, btScalar TMass);
static void CreateSphere(const btVector3 &TPosition, btScalar TRadius, btScalar TMass);
static void UpdatePhysics(u32 TDeltaTime);
static void UpdateRender(btRigidBody* TObject);
static void ClearObjects();
 
static bool Done = false;
static btDiscreteDynamicsWorld* dynamicsWorld;
static IrrlichtDevice* Device;
static IVideoDriver* Driver;
static ISceneManager* Smgr;
static IGUIEnvironment* Env;
static ITimer* Timer;
 
static list <btRigidBody*> Objects;
 
int ran = rand() % 10 + 1;
int ran2 = rand() % 5 + 3;
 
class MainEvent : public IEventReceiver
{
    public:
        virtual bool OnEvent(const SEvent& event)
        {
            if(event.EventType == EET_KEY_INPUT_EVENT && !event.KeyInput.PressedDown)
            {
                switch(event.KeyInput.Key)
                {
                    case KEY_ESCAPE:
                        Done = true;
                        break;
                        
                    case KEY_KEY_A:
                        CreateBox(btVector3(ran,ran2,ran), vector3df(0.5f,0.5f,.5f),1.0f);
                        break;
                        
                    case KEY_KEY_X:
                        CreateStartScene();
                        break;
                        
                    default:
                        return false;
                }
                
                return true;
            }
            
            return false;
        }
};
 
int main(int argc, char* argv[])
{
    MainEvent receiver;
    
    Device = createDevice(EDT_OPENGL, dimension2d<u32>(800,600),32,false,false,false,&receiver);
    Driver = Device->getVideoDriver();
    Smgr = Device->getSceneManager();
    Env = Device->getGUIEnvironment();
    Timer = Device->getTimer();
    
    btDefaultCollisionConfiguration* collisionConfiguration = new btDefaultCollisionConfiguration();
    btBroadphaseInterface* broadphase = new btAxisSweep3(btVector3(-1000,-1000,-1000), btVector3(1000,1000,1000));
    btCollisionDispatcher* dispatcher = new btCollisionDispatcher(collisionConfiguration);
    btSequentialImpulseConstraintSolver* solver = new btSequentialImpulseConstraintSolver();
    dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher,broadphase,solver,collisionConfiguration);
    
    ICameraSceneNode* Camera = Smgr->addCameraSceneNode(0,vector3df(0,0,0),vector3df(0,0,100));
    Camera->setPosition(vector3df(0,5,-10));
    Camera->setTarget(vector3df(0,0,0));
    
    Driver->getTexture("ice0.jpg");
    
    Smgr->addLightSceneNode(0,vector3df(2,5,-2),SColorf(4,4,4,1));
    CreateStartScene();
    
    u32 TimeStamp = Timer->getTime(), DeltaTime = 0;
    while(!Done)
    {
        DeltaTime = Timer->getTime() - TimeStamp;
        TimeStamp = Timer->getTime();
        
        UpdatePhysics(DeltaTime);
        
        Driver->beginScene(true, true, SColor(255,20,0,0));
        Smgr->drawAll();
        Env->drawAll();
        Driver->endScene();
        
        Device->run();
    }
    
    ClearObjects();
    delete dynamicsWorld;
    delete solver;
    delete dispatcher;
    delete broadphase;
    delete collisionConfiguration;
    
    Device->drop();
    
    return 0;
}
 
void UpdatePhysics(u32 TDeltaTime)
{
    dynamicsWorld->stepSimulation(TDeltaTime * 0.001f, 60);
    
    for(list<btRigidBody*>::Iterator Iterator = Objects.begin(); Iterator != Objects.end(); ++Iterator)
    {
        UpdateRender(*Iterator);
    }
}
 
void CreateBox(const btVector3 &TPosition, const vector3df &TScale, btScalar TMass)
{
    ISceneNode* Node = Smgr->addCubeSceneNode(1.0f);
    Node->setScale(TScale);
    Node->setMaterialFlag(EMF_LIGHTING,1);
    Node->setMaterialFlag(EMF_NORMALIZE_NORMALS, true);
    Node->setMaterialTexture(0,Driver->getTexture("ice0.jpg"));
    
    btTransform Transform;
    Transform.setIdentity();
    Transform.setOrigin(TPosition);
    
    btDefaultMotionState* MotionState = new btDefaultMotionState(Transform);
    
    btVector3 HalfExtents(TScale.X * 0.5f, TScale.Y * 0.5f, TScale.Z * 0.5f);
    btCollisionShape* Shape = new btBoxShape(HalfExtents);
    
    btVector3 LocalInertia;
    Shape->calculateLocalInertia(TMass, LocalInertia);
    
    btRigidBody* RigidBody = new btRigidBody(TMass, MotionState, Shape, LocalInertia);
    
    RigidBody->setUserPointer((void*)(Node));
    
    dynamicsWorld->addRigidBody(RigidBody);
    Objects.push_back(RigidBody);
}
 
void CreateStartScene()
{
    ClearObjects();
    CreateBox(btVector3(0.0f,0.0f,0.0f), vector3df(10.0f,0.5f,10.0f),0.0f);
}
 
void UpdateRender(btRigidBody* TObject)
{
    ISceneNode* Node = static_cast<ISceneNode*>(TObject->getUserPointer());
    
    btVector3 Point = TObject->getCenterOfMassPosition();
    Node->setPosition(vector3df((f32)Point[0],(f32)Point[1],(f32)Point[2]));
    
    vector3df Euler;
    const btQuaternion& TQuat = TObject->getOrientation();
    quaternion q(TQuat.getX(), TQuat.getY(), TQuat.getZ(), TQuat.getW());
    q.toEuler(Euler);
    Euler *= RADTODEG;
    Node->setRotation(Euler);
}
 
void ClearObjects()
{
    for(list<btRigidBody*>::Iterator Iterator = Objects.begin(); Iterator != Objects.end(); ++Iterator)
    {
        btRigidBody* Object = *Iterator;
        
        ISceneNode *Node = static_cast<ISceneNode*>(Object->getUserPointer());
        Node->remove();
        
        dynamicsWorld->removeRigidBody(Object);
        
        delete Object->getMotionState();
        delete Object->getCollisionShape();
        delete Object;
    }
    
    Objects.clear();
}
randomMesh
Posts: 1186
Joined: Fri Dec 29, 2006 12:04 am

Re: Irrlicht & Bullet Physics 2

Post by randomMesh »

The recommended way to synchronize the Irrlicht nodes with the bullet bodies are MotionStates. See my example here.
"Whoops..."
Post Reply