Skip to main content
NxOgre   This page is related to a deprecated version of NxOgre, called BloodyMess. Some code from here may be adopted to newer versions with sufficient care and knowledge.   NxOgre


Disclaimer: This is not an official NxOgre tutorial. However, it has been revised and edited by the creator of NxOgre and BloodyMess, betajaen.

help Help: For any problems you encounter while working on these tutorials, as well as for detailed questions and propositions, please visit the NxOgre OgreAddons-Forum.

Image You can find the complete code for this tutorial here.

NxOgreCube.png Introduction

In the third tutorial, you learned about the Visual Debugger, a tool that can visually show all physics objects in a scene, even those that are invisible. In this tutorial we will get to know one kind of these invisible element: Volumes/Trigger. Once you have completed this tutorial it would be a good idea to go back and integrate the visual debugger so that you can see this object within our scene.

NxOgreCube.png What is a Volume?

A volume is an invisible physics object of an arbitrary shape. It doesn't move, nor can it be seen. So what is the value of it? It is used as a trigger. As soon as a physics object enters it, is fully within it, or leaves it, a special event is fired that can be used to start a defined action within your program.

One example for a trigger could be the finish area in a racing game. From the finish line up to a distance beyond it, a trigger volume is placed and as soon as the player enters this volume, an event is fired and the game can, for example, react by showing a message, playing a sound or doing whatever the programmer wanted it to do.

NxOgreCube.png The Initial Code

Start a new Ogre and NxOgre project in your IDE. We will create the necessary code to make Ogre run using the ExampleApplication and ExampleFrameListener classes provided by the Ogre Samples.

Note: If you're fairly new with Ogre, it may be worth it modifying the Ogre SkyBox sample instead of creating your own Ogre project.


The following code will serve as the basis for this tutorial. It should compile and run without errors.

Copy to clipboard
#include "ExampleApplication.h" #include <NxOgre.h> #include <NxOgreOGRE3D.h> class BloodyMessTutorial4Listener : public ExampleFrameListener { public: BloodyMessTutorial4Listener(RenderWindow *win, Camera *cam) : ExampleFrameListener(win, cam) { mTimeController = NxOgre::TimeController::getSingleton(); } bool frameStarted(const FrameEvent& evt) { mTimeController->advance(evt.timeSinceLastFrame); return ExampleFrameListener::frameStarted(evt); } protected: NxOgre::TimeController* mTimeController; }; class BloodyMessTutorial4 : public ExampleApplication { protected: NxOgre::World* mWorld; NxOgre::Scene* mScene; NxOgre::TimeController* mTimeController; OGRE3DRenderSystem* mRenderSystem; OGRE3DBody* mCube; void createScene() { // Set ambient light mSceneMgr->setAmbientLight(ColourValue(0.5f, 0.5f, 0.5f)); // Create a light Light* l = mSceneMgr->createLight("MainLight"); l->setPosition(20, 80, 50); // Position the camera mCamera->setPosition(0, 20, 80); mCamera->lookAt(0, 20, 0); // Create the world mWorld = NxOgre::World::createWorld(); // Create scene description NxOgre::SceneDescription sceneDesc; sceneDesc.mGravity = NxOgre::Vec3(0, -9.81f, 0); sceneDesc.mName = "DemoScene"; // Create scene mScene = mWorld->createScene(sceneDesc); // Set some physical scene values mScene->getMaterial(0)->setStaticFriction(0.5); mScene->getMaterial(0)->setDynamicFriction(0.5); mScene->getMaterial(0)->setRestitution(0.1); // Create render system mRenderSystem = new OGRE3DRenderSystem(mScene); //Create time controller mTimeController = NxOgre::TimeController::getSingleton(); // Add objects mCube = mRenderSystem->createBody(new NxOgre::Box(1, 1, 1), NxOgre::Vec3(0, 40, 0), "cube.1m.mesh"); // Create floor plane (Ogre) MovablePlane *plane = new MovablePlane("Plane"); plane->d = 0; plane->normal = Vector3::UNIT_Y; Ogre::MeshManager::getSingleton().createPlane("PlaneMesh", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, *plane, 120, 120, 1, 1, true, 1, 3, 3, Vector3::UNIT_Z); Entity *planeEnt = mSceneMgr->createEntity("PlaneEntity", "PlaneMesh"); planeEnt->setMaterialName("Examples/GrassFloor"); Ogre::SceneNode* mPlaneNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(); mPlaneNode->attachObject(planeEnt); } // Create a new frame listener void createFrameListener() { mFrameListener = new BloodyMessTutorial4Listener(mWindow, mCamera); mRoot->addFrameListener(mFrameListener); } }; #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 #define WIN32_LEAN_AND_MEAN #include "windows.h" #endif #ifdef __cplusplus extern "C" { #endif #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 INT WINAPI WinMain(HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT) #else int main(int argc, char **argv) #endif { // Create application object BloodyMessTutorial4 app; try { app.go(); } catch(Exception& e) { #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 MessageBoxA(NULL, e.getFullDescription().c_str(), "An exception has occurred!", MB_OK | MB_ICONERROR | MB_TASKMODAL); #else std::cerr << "An exception has occurred: " << e.getFullDescription(); #endif } return 0; } #ifdef __cplusplus } #endif

NxOgreCube.png Initialize the Volume

First of all, we need to make two changes to our tutorial class. We have to declare a new member variable:

Copy to clipboard
NxOgre::Volume* mVolume;


We also have to make our tutorial class inherit NxOgre::Callback in order for it to be able to deal with the events that a volume will fire when, in this case, an NxOgre::Actor enters.

As such, ensure that our class declaration looks like this:

Copy to clipboard
class BloodyMessTutorial4 : public ExampleApplication, public NxOgre::Callback


Next, at the bottom of our createScene() function, we need to create a volume that has these parameters:

  • the shape of the volume, in this case a 5x5x5 metre box
  • the position of the volume, which is the center of our scene
  • the callback class for the volume, which is this class which we previously had inherit from NxOgre::Callback
  • the callback behavior (for which events the onVolumeEvent() should be called), which will react to an Actor entering, existing within, or exiting the volume

Copy to clipboard
mVolume = mScene->createVolume(new NxOgre::Box(5), NxOgre::Matrix44(NxOgre::Vec3(0, 0, 0)), this, NxOgre::Enums::VolumeCollisionType_All);

NxOgreCube.png The Callback Function

The final thing we have to do is create the function which will be called when an Actor triggers our callback. Place this function at the bottom of our tutorial class:

Copy to clipboard
void onVolumeEvent(NxOgre::Volume* volume, NxOgre::Shape* volumeShape, NxOgre::RigidBody* rigidBody, NxOgre::Shape* rigidBodyShape, unsigned int collisionEvent) { if(collisionEvent == NxOgre::Enums::VolumeCollisionType_OnEnter) { NxOgre::Actor* actor = static_cast<NxOgre::Actor*>(rigidBody); float y = (9.81 * actor->getMass()) // counteract gravity + (-actor->getLinearVelocity().y * actor->getMass()) // counteract vertical velocity + (10 - actor->getGlobalPosition().y * actor->getMass()); // add some force to move it to the top actor->addForce(NxOgre::Vec3(0, y, 0), NxOgre::Enums::ForceMode_Impulse); } }


This bit of code checks what type of collisionEvent occurred, which in this case we only want when an actor enters our volume. We then apply a force to our actor which will send it flying back up vertically along the Y axis.

NxOgreCube.png Conclusion

That's it! When you run the application now, you should see our cube falling straight down till it reaches our volume where it will then reverse direction and go flying back in to the air until gravity begins to pull it back down once more, so on and so fourth. Onward, for in the next tutorial we will cover Kinematics!