OGRE Wiki
Support and community documentation for Ogre3D
Ogre Forums
ogre3d.org
Log in
Username:
Password:
CapsLock is on.
Remember me (for 1 year)
Log in
Home
Tutorials
Tutorials Home
Basic Tutorials
Intermediate Tutorials
Mad Marx Tutorials
In Depth Tutorials
Older Tutorials
External Tutorials
Cookbook
Cookbook Home
CodeBank
Snippets
Experiences
Ogre Articles
Libraries
Libraries Home
Alternative Languages
Assembling A Toolset
Development Tools
OGRE Libraries
List of Libraries
Tools
Tools Home
DCC Tools
DCC Tutorials
DCC Articles
DCC Resources
Assembling a production pipeline
Development
Development Home
Roadmap
Building Ogre
Installing the Ogre SDK
Setting Up An Application
Ogre Wiki Tutorial Framework
Frequently Asked Questions
Google Summer Of Code
Help Requested
Ogre Core Articles
Community
Community Home
Projects Using Ogre
Recommended Reading
Contractors
Wiki
Immediate Wiki Tasklist
Wiki Ideas
Wiki Guidelines
Article Writing Guidelines
Wiki Styles
Wiki Page Tracker
Ogre Wiki Help
Ogre Wiki Help Overview
Help - Basic Syntax
Help - Images
Help - Pages and Structures
Help - Wiki Plugins
Toolbox
Freetags
Categories
List Pages
Structures
Trackers
Statistics
Rankings
List Galleries
Ogre Lexicon
Comments
History: BloodyMess Tutorial 4
View page
Source of version: 2
(current)
{INCLUDE(page="BloodyMess tpl")}{INCLUDE} __Disclaimer:__ This is not an official NxOgre tutorial. However, it has been revised and edited by the creator of NxOgre and BloodyMess, ((User:betajaen|betajaen)). %help%~hs~__Help:__ For any problems you encounter while working on these tutorials, as well as for detailed questions and propositions, please visit the [http://www.ogre3d.org/addonforums/viewforum.php?f=6|NxOgre OgreAddons-Forum]. {maketoc} {DIV(class="Bloody_box1")}{img src="img/wiki_up/CPP_small.png" alt="" width="22"}You can find the complete code for this tutorial ((BloodyMess Tutorial 4 Source|here)).{DIV} !!{img src="img/wiki_up/NxOgreCube.png" alt="NxOgreCube.png"} Introduction In the ((BloodyMess Tutorial 3|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. !!{img src="img/wiki_up/NxOgreCube.png" alt="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. !!{img src="img/wiki_up/NxOgreCube.png" alt="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. {DIV(class="Bloody_box2")}__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.{DIV} The following code will serve as the basis for this tutorial. It should compile and run without errors. {CODE(wrap="1", colors="c++")}#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{CODE} !!{img src="img/wiki_up/NxOgreCube.png" alt="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: {CODE(wrap="1", colors="c++")}NxOgre::Volume* mVolume;{CODE} 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: {CODE(wrap="1", colors="c++")}class BloodyMessTutorial4 : public ExampleApplication, public NxOgre::Callback{CODE} 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 {CODE(wrap="1", colors="c++")}mVolume = mScene->createVolume(new NxOgre::Box(5), NxOgre::Matrix44(NxOgre::Vec3(0, 0, 0)), this, NxOgre::Enums::VolumeCollisionType_All);{CODE} !!{img src="img/wiki_up/NxOgreCube.png" alt="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: {CODE(wrap="1", colors="c++")}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); } }{CODE} 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. !!{img src="img/wiki_up/NxOgreCube.png" alt="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! {INCLUDE(page="NxOgre tpl")}{INCLUDE}
Search by Tags
Search Wiki by Freetags
Latest Changes
FMOD SoundManager
HDRlib
Building Ogre V2 with CMake
Ogre 2.1 FAQ
Minimal Ogre Collision
Artifex Terra
OpenMB
Advanced Mogre Framework
MogreSocks
Critter AI
...more
Search
Find
Advanced
Search Help
Online Users
27 online users