__Initialising__

// Init newton
nWorld = NewtonCreate(NULL, NULL);
// Set up default material properties for newton
int i = NewtonMaterialGetDefaultGroupID(nWorld);
NewtonMaterialSetDefaultFriction (nWorld, i, i, 0.8f, 0.4f);
NewtonMaterialSetDefaultElasticity (nWorld, i, i, 0.3f);
NewtonMaterialSetDefaultSoftness (nWorld, i, i, 0.05f);
NewtonMaterialSetCollisionCallback (nWorld, i, i, NULL, NULL, NULL, NULL);

To start off, we create the newton object with NewtonCreate().

Next, we set the default properties for materials. Materials
define how objects interact when they collide and you can
use different materials to simulate ice, wood, sand, etc.
In this example we will just create all our objects with the
default material.

__Newton Callbacks__

Newton will call back to staticly definied functions in your
code to tell you information such as when an

object is moving. I will show how to assign the events to bodies
further down the page.

void _cdecl CGame::SetMeshTransformEvent(const NewtonBody* body, const float* matrix)
{
// copy the matrix into an irrlicht matrix4
matrix4 mat;
memcpy(mat.M, matrix, sizeof(float)*16);
// Retreive the user data attached to the newton body
ISceneNode *tmp = (ISceneNode *)NewtonBodyGetUserData(body);
if (tmp)
{
// Position the node
tmp->setPosition(mat.getTranslation()); // set position
tmp->setRotation(mat.getRotationDegrees()); // and rotation
}
}

This function will be called by newton bodies when they move.
By storing an ISceneNode pointer in the userData

of the body, we can position the corresponding scenenode easily.

void _cdecl CGame::ApplyForceAndTorqueEvent (const NewtonBody* body)
{
float mass;
float Ixx;
float Iyy;
float Izz;
float force[3];
float torque[3];
NewtonBodyGetMassMatrix (body, &mass, &Ixx, &Iyy, &Izz);
force[0] = 0.0f;
force[1] = NEWTON_GRAVITY * mass;
force[2] = 0.0f;
torque[0] = 0.0f;
torque[1] = 0.0f;
torque[2] = 0.0f;
NewtonBodyAddForce (body, force);
NewtonBodyAddTorque (body, torque);
}

This function is called by the Newton Engine every time an
active body is going to be simulated. We add gravity

to our bodies by means of a downwards force.

__Setting up the scene__

g_newtonmap = NewtonCreateTreeCollision(nWorld, NULL);
NewtonTreeCollisionBeginBuild(g_newtonmap);
int cMeshBuffer, j;
int v1i, v2i, v3i;
IMeshBuffer *mb;
float vArray[9]; // vertex array (3*3 floats)
int tmpCount = 0;
for (cMeshBuffer=0; cMeshBuffergetMesh(0)->getMeshBufferCount(); cMeshBuffer++)
{
mb = g_map->getMesh(0)->getMeshBuffer(cMeshBuffer);
video::S3DVertex2TCoords* mb_vertices = (irr::video::S3DVertex2TCoords*)mb->getVertices();
u16* mb_indices = mb->getIndices();
// add each triangle from the mesh
for (j=0; jgetIndexCount(); j+=3)
{
v1i = mb_indices[j];
v2i = mb_indices[j+1];
v3i = mb_indices[j+2];
vArray[0] = mb_vertices[v1i].Pos.X;
vArray[1] = mb_vertices[v1i].Pos.Y;
vArray[2] = mb_vertices[v1i].Pos.Z;
vArray[3] = mb_vertices[v2i].Pos.X;
vArray[4] = mb_vertices[v2i].Pos.Y;
vArray[5] = mb_vertices[v2i].Pos.Z;
vArray[6] = mb_vertices[v3i].Pos.X;
vArray[7] = mb_vertices[v3i].Pos.Y;
vArray[8] = mb_vertices[v3i].Pos.Z;
NewtonTreeCollisionAddFace(g_newtonmap, 3, (float*)vArray, 12, 1);
}
}
NewtonTreeCollisionEndBuild(g_newtonmap, 0);
g_newtonmapbody = NewtonCreateBody(nWorld, g_newtonmap);

After loading the bsp mesh in irrlicht we must create a newton
collision tree consisting of all the triangles

in the bsp mesh. To do this we loop through the indices list
and add vertices 3 at a time into newton. I should

mention here that I was lazy when writing this and just used
a straight cast to video::S3DVertex2TCoords - this is because

bsp meshes have lightmap textures on them. If you are using
a mesh with only 1 set of texture co-ordinates (like

a landscape or .x level) then use (video::S3DVertex).

Newton requires 2 pointers for every object - a NewtonBody*
for the rigid body, and a NewtonCollision* that

describes the objects geometry. After creating the tree collision
geometry, we create a body for the map and

assign it to the collision. Bodys which have a tree collision
for their geometry are static and their mass

will be ignored by newton - so you can only use meshes for your
scenery!

// set the newton world size based on the bsp size
float boxP0[3];
float boxP1[3];
float matrix[4][4];
NewtonBodyGetMatrix (g_newtonmapbody, &matrix[0][0]);
NewtonCollisionCalculateAABB (g_newtonmap, &matrix[0][0], &boxP0[0], &boxP1[0]);
// you can pad the box here if you wish
//boxP0.y -= somevalue;
//boxP1.y += somevaluef;
NewtonSetWorldSize (nWorld, (float*)boxP0, (float*)boxP1);

After loading the map, we can calculate the bounding box
surrounding it and set the newton world size to

match. Newton should automatically disable anything which
falls out of the map this way.

__Creating Cubes__

// Create a box primitive.
tmp->collision = NewtonCreateBox(nWorld, 38, 38, 38, NULL);
tmp->body = NewtonCreateBody(nWorld, tmp->collision);
// Set user data pointer to the scene node
NewtonBodySetUserData(tmp->body, tmp->node);
// Set body mass & inertia matrix
NewtonBodySetMassMatrix (tmp->body, 10.0f, 150.0f, 150.0f, 150.0f);
// Set the freeze threshhold to 1 unit (default is 0.01 but irrlight uses a large unit scale)
NewtonBodySetFreezeTreshold(tmp->body, 1.0, 1.0, 1.0, 1.0);
// Set callback functions for the body
NewtonBodySetTransformCallback(tmp->body, SetMeshTransformEvent);
NewtonBodySetForceAndTorqueCallback(tmp->body, ApplyForceAndTorqueEvent);
// Set the position of the body
matrix4 mat;
mat.setTranslation(loc);
NewtonBodySetMatrix(tmp->body, &mat.M[0]);

To start with we create a box primitive. Note that 38 is just
a value I used to match the cube model

in the examples size.

We set the cubes userData pointer to the ISceneNode related
to this cube - this is so that we can move the

scene node when newton tells us the body is moving.

Next, we set the mass. The moment of inertia for a box is given
by the expression

Ixx = M * (z * z + y * y) / 12

I have used a hard value of 150.0 for the inertia matrix,
but you could write some better code

here to automatically calculate the inertia matrix based on
box size, mass and how you want the weight

to be distributed inside the box.

Finally, set the transform and force callbacks of the newton
body to our callback functions, and set

the initial position of the body.

__Making everything move__

OK so we have our scene all set up - but we need to make everything
move!

A simple call to newtonUpdate() will do the trick :)

NewtonUpdate(nWorld, 0.01f);

In the example I call NewtonUpdate 100 times a second, with
a 0.01 second timestep to match.

You can update less often with a larger timestep but be aware
that the larger your timestep is, the less

accurate the collisions will become. I would recommend updating
between 50 to 100 times a second for a game.

__Cleaning Up__

// release the collision tree
NewtonReleaseCollision(nWorld, g_newtonmap);
// release the box primitives
for (int i=0; i<currentCube; i++)
NewtonReleaseCollision(nWorld, cubes[i]->collision);
// destory the newton world object
NewtonDestroy(nWorld);

I think the comments explain well enough ;)

Well thats it! I hope you've found this tutorial helpful. If
you didnt see the link at the top, you can download

the example source code & binary for this tutorial

HERE.

-Mercior