Irrlicht:Physics
From GDWiki
This is a tutorial about using the Irrlicht engine with Newton Game Dynamics. This being my first tutorial and the fact that I'm relitivly new to the Irrlicht engine and C++ so this tutorial might be lacking many ways, but I hope you who find mistakes in this will feel free to edit this page.I am writing this tutorial because I don't think there are any tutorials like this one on the web.
Contents |
[edit] Physics in the Irrlicht engine
There are two main ways to implement physics in Irrlicht:
- use the basic physics that come with Irrlicht.
- integrate an existing physics engine such as Newton.
You can also use a pre-built wrapper to integrate an existing physics engine into Irrlicht. It can save you some time. A good one is IrrNewt, an Irrlicht\Newton wrapper
In this tutorial we will use Newton. First we must set up our developement enviroment,I am using Dev-Cpp, if you want to use another IDE/compiler you will have to figure out how to setup that up yourself. I could go through, step by step, how to setup Irrlicht and Newton, but why when someone already did ?
[edit] Our first Newton app
Once you have an enviroment setup we can write a small program.This basicly the same as the example that came with the Newton SDK except it uses Irrlicht for all the rendering and input thus making the coding job smaller.
To start create an empty project and call it "irrNewt" or something like that. Add a new file to the project and name it "Game.cpp". At the top put this:
#include <Irrlicht.h> #include "newton.h" #include <iostream> using namespace irr; using namespace core; using namespace scene; using namespace video; using namespace io; using namespace gui;
Now we create a pointer to a Newton "World" object :
static NewtonWorld* nWorld;
this is the main newton object. Next we add a pointer for a rigid body object :
static NewtonBody* body;
this is what the cube will be.
Then we add the pointers to the Irrlicht objects that we must have to make any Irrlicht game tick :
IVideoDriver* driver = 0; IrrlichtDevice *device = 0; ISceneManager* smgr = 0;
and finally we add the pointers for the cube sceneNode,the camera,and a variable that will help us to save time.
ISceneNode *boxNode = 0; ISceneNode *cam = 0; unsigned int lasttick;
[edit] Function InitScene
Now we are ready to get to the interesting part, we create a function called InitScene() that we prepare everything for the main game loop. In this we setup Irrlicht like usual and create a newton world.
void InitScene()
{
device = createDevice(EDT_OPENGL,
dimension2d<s32>(640,480),
false);
driver = device->getVideoDriver();
smgr = device->getSceneManager();
nWorld = NewtonCreate (NULL, NULL);
The two aurguments for NewtonCreate are function pointers for allocating and free memory by default they are malloc and free which is fine for now, so we will just put NULL and leave them along. Next we need to create a scene node for our cube and texture it
boxNode = smgr->addAnimatedMeshSceneNode(smgr->getMesh("data/smallcube.3ds"));
boxNode->setMaterialTexture(0, driver->getTexture("data/crate.jpg"));
we will then add the Newton part of the cube,we create a pointer to a collision object and the initialize it using the NewtonCreateBox function which takes four parameters the first is a pointer to the World object the next three are dimentions x,y,z ,which don't matter to use right now becuase we wont be colliding with anything, and the fourth is a pointer to a 4x4 matrix for the origin offset passing it NULL will give us the defualt which is the center
NewtonCollision *collision;
collision = NewtonCreateBox(nWorld, 0, 0, 0, NULL);
next we crate the rigid body with the data we've got with the collision object after that we can destroy the collision object,we have only one cube so it is not needed any more.
body = NewtonCreateBody (nWorld, collision); NewtonReleaseCollision (nWorld, collision);
Now we combine the Irrlicht half and the Newton half
NewtonBodySetUserData(body, boxNode);
then we set the mass an inertia which again don't really matter for this application
NewtonBodySetMassMatrix (body, 100.0f, 1.0f, 1.0f, 1.0f);
after that we set the position and volocity of the cube
matrix4 mat;
mat.setTranslation(vector3df(0,0,0));
NewtonBodySetMatrix(body, mat.pointer());
float omega[3] = {1.0f, 2.0f, 1.0f};
NewtonBodySetOmega (body, &omega[0]);
add the camera and were ready for the next step
cam = smgr->addCameraSceneNodeMaya(0,-1500.0f,200.0f,500.0f,0); cam->setPosition(vector3df(0, 300, 0)); }
[edit] DrawScene
Now we are ready for the man game loop function.this will do two things,it will keep the game running at a constant rate and update the cubes translation
void DrawScene()
{
if (device->getTimer()->getTime() > lasttick + 10) {
lasttick = device->getTimer()->getTime();
NewtonUpdate(nWorld, 0.01f);
}
newton will now run at a hunderd frames per second.Now we update the cube,first we get the matrix of its rigid body,then use memcpy toconvert the DX style matrix into a opengl style matrix,which Irrlicht uses.
float matrix[4][4];
NewtonBodyGetMatrix(body, &matrix[0][0]);
matrix4 mat;
memcpy(mat.pointer(), matrix, sizeof(float)*16);
Now we can update ou scene node some Irrlicht knows were to display it
boxNode->setPosition(mat.getTranslation());
boxNode->setRotation(mat.getRotationDegrees());
}
and that's it,now alls left is a simple main function and it will run.
[edit] Putting it all together
The main function is quit small and neat it first calls InitScene() then goes into the main game loop.
int main()
{
InitScene();
while(device->run())
{
DrawScene();
driver->beginScene(true, true, video::SColor(0,0,0,0));
smgr->drawAll();
driver->endScene();
}
NewtonDestroy(nWorld);
device->drop();
return 0;
}
Well, that wraps up this tutorial I hope to write another one covering more advance stuff until then here is the source.Special thanks to Mercior for writing his tutorial and because I stole his crate model and graphics. -Hacim

