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: OgreNewt Picking
View page
Source of version: 2
(current)
{maketoc} !!Picking objects using OgreNewt For debugging and playing-around, it's handy to be able to pick things up and throwing them around using your mouse. It has been implemented in OgreNewt tutorials but not in a centralised, reusable way. I created a small class, based on the original sample code, that is easy to use and plug in where needed. !!!Usage Just setup your graphics (we need scenemanager) and physics and call this once: {CODE(wrap="1", colors="c++")} Picker::getSingletonPtr()->init(sceneManager);{CODE} As you can see from the header, you can optionally set maximum distance and force multiplier too. After you finish, call the following before destroying the scenemanager and physics: {CODE(wrap="1", colors="c++")} Picker::getSingletonPtr()->deInit(); {CODE} And every frame you wish picking would be possible, call: {CODE(wrap="1", colors="c++")} Picker::getSingletonPtr()->update(world, camera); {CODE} Thats it! !!!Code !!!!Picker.h {CODE(wrap="1", colors="c++")} #ifndef PICKER_H_INCLUDED #define PICKER_H_INCLUDED #include <Ogre.h> #include <OgreNewt.h> class Picker { public: void init(Ogre::SceneManager* sceneMgr, int maxDistance = 100, int pickForce = 10); void deInit(); void update(OgreNewt::World* world, Ogre::Camera* camera); void dragCallback(OgreNewt::Body* body, Ogre::Real timeStep, int threadIndex); static Picker* getSingletonPtr(); private: bool active; bool dragging; int maxDist; int forceMultiplier; void removeLine(); Ogre::SceneManager* sceneManager; Ogre::Camera* camera; Ogre::Vector3 dragPoint; Ogre::Real dragDist; OgreNewt::Body* dragBody; Ogre::SceneNode* dragLineNode; Ogre::ManualObject* dragLineObject; Picker(); ~Picker(); Picker(const Picker&); Picker& operator = (const Picker&); }; #endif // PICKER_H_INCLUDED {CODE} !!!!Picker.cpp {CODE(wrap="1", colors="c++")} #include "Picker.h" #include <CEGUI/CEGUI.h> #include "InputManager.h" Picker::Picker() { active = false; } Picker::~Picker() { deInit(); } void Picker::init(Ogre::SceneManager* sceneMgr, int maxDistance, int pickForce) { sceneManager = sceneMgr; maxDist = maxDistance; forceMultiplier = pickForce; dragLineNode = sceneManager->getRootSceneNode()->createChildSceneNode(); dragLineObject = new Ogre::ManualObject( "__DRAG_LINES__" ); active = true; } void Picker::deInit() { if(active) { if(dragLineNode != NULL) { dragLineNode->detachAllObjects(); if(dragLineObject != NULL) { sceneManager->destroyManualObject(dragLineObject); dragLineObject = NULL; } dragLineNode->getParentSceneNode()->removeAndDestroyChild(dragLineNode->getName()); dragLineNode = NULL; } active = false; } } void Picker::update(OgreNewt::World* world, Ogre::Camera* cam) { if(!active || sceneManager == NULL) { return; } if(!dragging) { if(InputManager::getSingletonPtr()->getMouse()->getMouseState().buttonDown(OIS::MB_Left)) { Ogre::Vector3 start, end; // Get absolute mouse position on screen [0 - resulution] and renderer for window size CEGUI::Point mouse = CEGUI::MouseCursor::getSingleton().getPosition(); CEGUI::Renderer* guiRenderer = CEGUI::System::getSingleton().getRenderer(); // Calculate normalised mouse position [0..1] Ogre::Real mx = mouse.d_x / guiRenderer->getWidth(); Ogre::Real my = mouse.d_y / guiRenderer->getHeight(); // Get a world space ray as cast from the camera through a viewport position Ogre::Ray camray = cam->getCameraToViewportRay(mx, my); // Get ray origing and end coordinates start = camray.getOrigin(); end = camray.getPoint(maxDist); // Cast a ray between these points and check for first hit OgreNewt::BasicRaycast* ray = new OgreNewt::BasicRaycast(world, start, end); OgreNewt::BasicRaycast::BasicRaycastInfo info = ray->getFirstHit(); // Found a body in the ray's path if(info.mBody) { Ogre::Vector3 bodyPos; Ogre::Quaternion bodyOrientation; // Store the body position and orientation info.mBody->getPositionOrientation(bodyPos, bodyOrientation); // Calculate hit global and local position (info.mDistance is in the range [0,1]) Ogre::Vector3 globalPos = camray.getPoint(maxDist * info.mDistance); Ogre::Vector3 localPos = bodyOrientation.Inverse() * (globalPos - bodyPos); // Change the force callback from the standard one to the one that applies the spring picking force info.mBody->setCustomForceAndTorqueCallback<Picker>(&Picker::dragCallback, this); // Store the relevant picking information dragBody = info.mBody; dragDist = (maxDist * info.mDistance); dragPoint = localPos; // We need the camera too, mark picking active camera = cam; dragging = true; } delete ray; } if(dragLineNode) { removeLine(); } } else { // Check whether user has released the mouse button if(!InputManager::getSingletonPtr()->getMouse()->getMouseState().buttonDown(OIS::MB_Left)) { // Restore body force callback (FIXME: doesnt work it it was set to anything else but the default one) dragBody->setStandardForceCallback(); // Reinitialise dragging information dragBody = NULL; dragPoint = Ogre::Vector3::ZERO; dragDist = 0.0; dragging = false; } } } void Picker::dragCallback(OgreNewt::Body* body, Ogre::Real timeStep, int threadIndex) { // Deinitialise if scenemanager has disappeared if(sceneManager == NULL) { deInit(); return; } // Again, get absolute mouse position on screen [0 - resulution] and renderer for window size CEGUI::Point mouse = CEGUI::MouseCursor::getSingleton().getPosition(); CEGUI::Renderer* guiRenderer = CEGUI::System::getSingleton().getRenderer(); // Calculate normalised mouse position [0..1] Ogre::Real mx = mouse.d_x / guiRenderer->getWidth(); Ogre::Real my = mouse.d_y / guiRenderer->getHeight(); // Get a world space ray as cast from the camera through a viewport position Ogre::Ray camray = camera->getCameraToViewportRay(mx, my); // Get the global position our cursor is at Ogre::Vector3 cursorPos = camray.getPoint(dragDist); Ogre::Quaternion bodyOrientation; Ogre::Vector3 bodyPos; // Now find the global point on the body body->getPositionOrientation(bodyPos, bodyOrientation); // Fint the handle position we are holding the body from Ogre::Vector3 dragPos = (bodyOrientation * dragPoint) + bodyPos; Ogre::Vector3 inertia; Ogre::Real mass; body->getMassMatrix(mass, inertia); // Calculate picking spring force Ogre::Vector3 dragForce = ((cursorPos - dragPos) * mass * forceMultiplier) - body->getVelocity(); // Draw a 3D line between these points for visual effect removeLine(); dragLineObject->begin("BaseWhiteNoLighting", Ogre::RenderOperation::OT_LINE_LIST); dragLineObject->position(cursorPos); dragLineObject->position(dragPos); dragLineObject->end(); dragLineNode->attachObject(dragLineObject); // Add the picking spring force at the handle body->addGlobalForce(dragForce, dragPos); // Add gravity too Ogre::Vector3 gravity = Ogre::Vector3(0,-9.8,0) * mass; body->addForce(gravity); } void Picker::removeLine() { // Clear the line between handle and cursor dragLineNode->detachAllObjects(); dragLineObject->clear(); } Picker* Picker::getSingletonPtr() { static Picker instance; return &instance; } {CODE} Hope it helps anyone :) -- kallas
Search by Tags
Search Wiki by Freetags
Latest Changes
Minimal Ogre Collision
Artifex Terra
OpenMB
Advanced Mogre Framework
MogreSocks
Critter AI
Mogre Add-ons
MOGRE
Mogre MyGUI wrapper
MOGRE Editable Terrain Manager
...more
Search
Find
Advanced
Search Help
Online Users
34 online users