Bullet Physics & Rendering

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
Post Reply
GameDude
Posts: 498
Joined: Thu May 24, 2007 12:24 am

Bullet Physics & Rendering

Post by GameDude »

Hello,

I am working on a small project to improve my physics programming. I am using bullet physics and Irrlicht to render, of course. However I am having a bit of a problem. I'm not sure how would I would render the Irrlicht shapes and have them correspond with the bullet physics shapes. Also, my FPS is low (16). I'll post my code.

Code: Select all

//physics.h
class Physics
{
public:
	Physics();
	~Physics();

private:
	btBroadphaseInterface* broadphase;

	btDefaultCollisionConfiguration* collisionConfiguration;
	btCollisionDispatcher* dispatcher;

	btSequentialImpulseConstraintSolver* solver;

	btDiscreteDynamicsWorld* dynamicsWorld;

	btCollisionShape* flatGroundShape;
	btCollisionShape* ballShape;

	btDefaultMotionState* groundMotionState;
	btDefaultMotionState* ballMotionState;
};

Code: Select all

//physics.cpp
#include "main.h"
#include "physics.h"

Physics::Physics()
{
	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));

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

	ballShape = new btSphereShape(1);

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

	dynamicsWorld->addRigidBody(groundRigidBody);

	ballMotionState = new btDefaultMotionState(btTransform(btQuaternion(0,0,0,1),btVector3(0,50,0)));
	btScalar mass = 1;
	btVector3 fallInertia(0,0,0);
	ballShape->calculateLocalInertia(mass,fallInertia);

	btRigidBody::btRigidBodyConstructionInfo ballRigidBodyCI(mass,ballMotionState,ballShape,fallInertia);
	btRigidBody* ballRigidBody = new btRigidBody(ballRigidBodyCI);

	dynamicsWorld->addRigidBody(ballRigidBody);

	for(int i = 0; i < 300; i++)
	{
		dynamicsWorld->stepSimulation(1/60.f, 10);

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

		//std::cout << "ball height: " << trans.getOrigin().getY() << std::endl;
	}

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

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

}

Physics::~Physics()
{
	delete broadphase;
	delete collisionConfiguration;
	delete solver;
	delete dynamicsWorld;
	delete dispatcher;

	delete flatGroundShape;
	delete ballShape;
}

Code: Select all

//game.h
class Game
{
public:
	Game();
	~Game();

private:
	IrrlichtDevice* Device;
	IVideoDriver* Driver;
	ISceneManager* Smgr;
	IGUIEnvironment* Env;

	int iWidth,iHeight,iBits;

	ISceneNode* groundMesh;
	ISceneNode* ballMesh;

	ICameraSceneNode* Cam;
};

Code: Select all

//game.cpp
#include "main.h"
#include "game.h"
#include "event.h"
#include "physics.h"

Game::Game()
{
	MainEvent receiver;

	iWidth = 800;
	iHeight = 600;
	iBits = 32;

	Device = createDevice(EDT_DIRECT3D9, dimension2d<u32>(iWidth,iHeight),
				iBits, false, false, false, &receiver);

	Driver = Device->getVideoDriver();
	Smgr = Device->getSceneManager();
	Env = Device->getGUIEnvironment();

	ballMesh = Smgr->addSphereSceneNode();

	if(ballMesh)
	{
		ballMesh->setPosition(vector3df(0,0,30));
		ballMesh->setMaterialFlag(EMF_LIGHTING, true);
	}

	Cam = Smgr->addCameraSceneNodeFPS();

	int lastFPS = -1;

	while(Device->run())
	{
		if(receiver.IsKeyDown(irr::KEY_ESCAPE))
		{
			Device->closeDevice();
		}

		Driver->beginScene(true, true, SColor(255,113,113,133));
		Smgr->drawAll();
		Env->drawAll();

		Driver->endScene();

		int fps = Driver->getFPS();

		if(lastFPS != fps)
		{
			stringw tmp(L"Physics Fun [");
			tmp += Driver->getName();
			tmp += L"] FPS:";
			tmp += fps;

			Device->setWindowCaption(tmp.c_str());
			lastFPS = fps;
		}
	}

	Device->drop();
}

Game::~Game()
{
	delete Device;
	delete Driver;
	delete Smgr;
	delete Env;
	delete ballMesh;
	delete groundMesh;
}

Code: Select all

//main.cpp
#include "main.h"
#include "game.h"

int main(int argc, char* argv[])
{
	Game* gGame = new Game();

	return 0;
}

Iyad
Posts: 140
Joined: Sat Mar 07, 2009 1:18 am
Location: Montreal, Canada

Post by Iyad »

1.

Code: Select all

for(int i = 0; i < 300; i++) 
   { 
      dynamicsWorld->stepSimulation(1/60.f, 10); 

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

      //std::cout << "ball height: " << trans.getOrigin().getY() << std::endl; 
   } 
What is that? This is in your constructor and should not be there. A step simulation should be called once per frame. You are calling it 300 times and only in the instance of your physic class. What i suggest : Remove this piece of code, add a function which could be called from you physic class each frame, and call stepSimulation from it. Also this is incorrect :

Code: Select all

dynamicsWorld->stepSimulation(1/60.f, 10); 
because each step simulation of your physic world evolve at a rythm of 1/60 seconds, so if your computer renders 1000 FPS, there is almost 17 seconds in your world that passed insted of 1. Replace 1/60.f by a Timefactor, which is the difference of time elapsed between 2 frames.

2.
Irrlicht shapes and have them correspond with the bullet physics shapes
When you create shapes, it have to correspond to the mesh you are loading, ex: For a box shape, i should use btBoxShape and its constructor is using the box halfextents. So when adding a cube in your scenemanager, get its halfextents and create a box shape. Then you create your rigid body using the shape and adding it to the Rigid body world. You have to know that Bullet manage its rigid bodys independently form irrlicht. So each frame, you have to get the position and rotation from your rigid body and apply it to your scenenode.

Hope this helps. Also, look trought the forum, there are many examples that uses bullet with irrlicht.
#include <Iyad.h>
serengeor
Posts: 1712
Joined: Tue Jan 13, 2009 7:34 pm
Location: Lithuania

Post by serengeor »

Physics updates should be in the main loop with rendering functions.
For loop is bad to useif you need your game to run for a long time instead use while loop like it is shown in irrlicht examples(unless you really feel a need to use it) .
You should check out a irrbullet wrapper and see how its done there :wink:
Or you could look here:http://irrlicht.sourceforge.net/phpBB2/ ... hp?t=39007
Working on game: Marrbles (Currently stopped).
GameDude
Posts: 498
Joined: Thu May 24, 2007 12:24 am

Post by GameDude »

Alright, thanks, I figured I was going about it wrong.
Post Reply