Welcome to the first tutorial for IrrODE. IrrODE is a wrapper for the ODE physics library and Irrlicht. In this tutorial I'll show you how to set up the Code::Blocks IDE for the MinGW gcc compiler and how to create a simple IrrODE program. I assume you have downloaded Irrlicht and ODE and compiled an ODE library. In this tutorial we will develop a "helloIrrOdeWorld" example application.

Step 1: setting up the project
Use the Code::Blocks project creation wizard and create an Irrlicht project.
the Code::Blocks project creation wizard
Set the execution working dir to your working dir in the project/target options dialog, tab "build targets"
project properties
After this go to the "Linker" tab of the "Project Build Options" dialog and add ">irrOdeDirectory</bin/gcc-win32/libIrrOde.a" and the ODE lib you have created, e.g. "libode_single.a". Make sure "libIrrOde.a" is the first lib in the list.
add ODE lib
Now go to the "Search Directories" tab of the "Project Build Options" dialog and add the "<IrrOde directory>/include/irrOde" and the "<ODE directory>/include" directory.
add include directories

After adding the file "IrrODE.h" to the includes in your main.cpp file and cleaning the comments from the file created by the Wizard your file should look like this:
#include <irrlicht.h>
#include <IrrODE.h>

using namespace irr;

using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;
using namespace ode;  //This is the namespace of all IrrODE stuff

int main(int argc, char** argv) {
  IrrlichtDevice *device=createDevice(EDT_DIRECT3D9,dimension2d(640,480),
                                      16,false,false,false,0);

  device->setWindowCaption(L"HelloOdeWorld");

  IVideoDriver* driver = device->getVideoDriver();
  ISceneManager* smgr = device->getSceneManager();
  IGUIEnvironment* guienv = device->getGUIEnvironment();

  while(device->run()) {
    driver->beginScene(true, true, SColor(0,200,200,200));

    smgr->drawAll();
    guienv->drawAll();

    driver->endScene();
  }

  device->drop();
  return 0;
}
Your project should now compile and run. You'll get an impressive gray screen.

Step 2: initialize IrrOde:
The first thing to do for initializing IrrODE is to register an instance of the CIrrOdeSceneNodeFactory.
  CIrrOdeSceneNodeFactory cFactory(smgr);
  smgr->registerSceneNodeFactory(&cFactory);
With this scene node factory you can add all IrrOde scenenodes using the scenemanager. We'll see that later on.
Next we init ODE using the singleton instance of the CIrrOdeMananger and install it. With that installation IrrOde gets the timer and the scene manager it needs.
  //install the ODE
  CIrrOdeManager::getSharedInstance()->install(device);
	
Step 3: create an IrrODE scene
Now for the ODE specific scenenodes: the first scene node to add is a CIrrOdeWorld. This is the IrrODE version of ODE's dWorld. All nodes of the dynamic world need to be children of this world node. Don't be confused by the "nodeNameToC8" method. I used widestrings to store the scene node names, mainly to display them in the IrrOdePlayground application, but as the scenemanager needs the names as c8-strings I convert them using a method in the CIrrOdeSceneNode base class.
  ISceneNode *pNode=smgr->addSceneNode(
                    CIrrOdeSceneNode::nodeNameToC8(IRR_ODE_WORLD_NAME),
                    smgr->getRootSceneNode());
  CIrrOdeWorld *worldNode=reinterpret_cast<CIrrOdeWorld *>(pNode);
As we want a sphere bouncing off a box in this demo we need to add gravity to the world node
  worldNode->setGravity(vector3df(0,-10,0));
Now let's add the node for the box where the sphere will bounce off when the program is finished. Please note that the AnimatedMeshSceneNode is a child of the worldNode.
  IAnimatedMesh *Mesh=smgr->getMesh("data/box.3ds");
  IAnimatedMeshSceneNode *Node=smgr->addAnimatedMeshSceneNode(Mesh,worldNode);
  Node->setMaterialTexture(0,driver->getTexture("data/box0.jpg"));
  Node->setScale(vector3df(15.0f,1.5f,15.0f));
  Node->setMaterialFlag(EMF_LIGHTING,false);
Now for the node that makes the box a static object. We use the Irrlicht scenemanager to add a CIrrOdeGeomBox scene node as child of the previously added box. Next we set some surface parameters, we want the surface to be bouncy.
  CIrrOdeGeomBox *bx=reinterpret_cast<CIrrOdeGeomBox *>(smgr->addSceneNode(
                     CIrrOdeSceneNode::nodeNameToC8(IRR_ODE_GEOM_BOX_NAME),
                     Node));
  bx->getSurfaceParameters(0)->setBounce(1.0f);
  bx->getSurfaceParameters(0)->setModeBounce(true);
  bx->drop();
The next object we add is the sphere that drops on the box. As this should not be a static object we add a CIrrOdeBody object first, then the AnimatedMeshSceneNode as child of the body and (last but not least) a CIrrOdeGeomSphere object as child of the child of the body. The surface parameters of the geom will (again) be set to bouncy.
  //first add a body as child of the worldNode
  CIrrOdeBody *pBody=reinterpret_cast<CIrrOdeBody *>(
                     smgr->addSceneNode(CIrrOdeSceneNode::nodeNameToC8(
                     IRR_ODE_BODY_NAME),worldNode));
  pBody->setPosition(vector3df(0.0f,15.0f,0.0f));

  //next load a mesh and add an AnimatedMeshSceneNode
  //as child of the body
  Mesh=smgr->getMesh("data/sphere.3ds");
  Node=smgr->addAnimatedMeshSceneNode(Mesh,pBody);
  Node->setMaterialTexture(0,driver->getTexture("data/sphere0.jpg"));
  Node->setMaterialFlag(EMF_LIGHTING,false);

  //as the last part we add a sphere geom as child of the 
  //AnimatedMeshSceneNode
  CIrrOdeGeomSphere *pSphere=reinterpret_cast<CIrrOdeGeomSphere *>
                     (smgr->addSceneNode(CIrrOdeSceneNode::nodeNameToC8(
                      IRR_ODE_GEOM_SPHERE_NAME),Node));
  pSphere->setMassTotal(0.5f);
  pSphere->getSurfaceParameters(0)->setBounce(1.0f);
  pSphere->getSurfaceParameters(0)->setModeBounce(true);
  pSphere->drop();
Before adding objects to the system we init ODE.
  CIrrOdeManager::getSharedInstance()->initODE();
In order to make IrrOde initialize the physics entities of the objects we have added until now we tell the worldNode to do so.
  worldNode->initPhysics();
Note that when adding objects to the world during runtime you do also have to call the "initPhysics" method of the object. If you do e.g. call the method of a CIrrOdeBody object it will also init the physics of all it's children so there is not need to manually call all these methods.

Before we can see anything we need to add a camera to the scene, set it to an apropriate position and make it face the scene.
  ICameraSceneNode *cam=smgr->addCameraSceneNode();
  cam->setPosition(vector3df(-20.0f, 15.0f, -20.0f));
  cam->setTarget(vector3df(0.0f,0.0f,0.0f));
  
  
The final thing to do is to adjust the main loop of the program so that our world get steped in each frame. Please note that the default IrrODE rate is 60fps (0.016s/step), so that even if your computer makes a higher framerate IrrODE will automatically get the physic's rate down to that value. Please read the ODE wiki on their homepage on why it is important to have a constant time step value and all other information you may want to have.
  while(device->run()) {
    CIrrOdeManager::getSharedInstance()->step();
    driver->beginScene(true, true, SColor(0,200,200,200));

    smgr->drawAll();
    guienv->drawAll();

    driver->endScene();
  }
After all this hard and dirty work you can finally compile and run your first IrrODE application.
helloIrrOdeWorld screenshot