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: OgreOde Camera
View page
Source of version: 4
(current)
!!OgreOde 3rd Person Camera {maketoc} !!Introduction I spent some time to make my Camera collide correctly with the environment in OgreOde, like its known from any commercial computer game. My first thought was to give the camera a geometry and a body in OgreOde, so it collides with any object. After I made it not to move other objects but instead glide along them, I spent really a lot of time finding the right parameters for the cameras body and movement, and after all I gave it up. If anyone of you has this idea, I suggest you drop it :) The conclusion came, when I began to play World of Warcraft. We are about to implement a camera, that behaves just like this one, except some minor changes. Its pretty much of the GuildWars camera, too. As I developed this camera while I was working on a bigger project, you will not be able to adapt it completely, but I expect you to work around that on your own ;) It is developed with OgreOde, but it should be no problem to use it with ode or another physics engine. I expect you have worked with OgreOde and cameras in Ogre before, so I will focus the new elements. !!Concept Its pretty easy. {CODE(wrap="1", colors="c++")} - Take a ray, throw it from the point of the camera to the center, the players head or similiar. - Check for collisions between the ray and every object that is to move the camera -If there is a collision, move the camera along the ray to the point of collision + some distance {CODE} Additional Features: Load and save Settings, chasing if wanted, x rotation bounds !!Class Declaration Declare your cameras class and derive it from OgreOde::CollisionListener as its going to handle the collisions of the ray. You can not work with CollidingObject, because its part of my project. I use it to derive all objects that will have a collision callback by OgreOde. {CODE(wrap="1", colors="c++")} class Camera : public virtual CollidingObject, public OgreOde::CollisionListener { {CODE} We will need the following members: {CODE(wrap="1", colors="c++")} private: typedef CollidingObject inherited; protected: bool CollisionInThisFrame; Ogre::Camera* MyCamera; //the ogre camera Ogre::SceneNode* LookAtNode; //the node we are really looking at Ogre::SceneNode* RotationCenterNode; //the center of rotation, this node will be given by the user on creation Ogre::SceneNode* TargetPositionNode; //the position we want to be at, but maybe are not yet (chasing) Ogre::SceneNode* TargetLookAtNode; //the point we look at, but maybe dont yet double TightnessPos; //how fast does the camera reach target position double TightnessLook; //how fast does the camera look at the target position double MaxDistance; //how much can you zoom out double MinDistance; //how much can you zoom in double Distance; //whats the current distance between rotation center and camera double TargetDistance; //whats the target distance (chasing) double MinCamRot; //the bounds for x rotation double MaxCamRot; OgreOde::RayGeometry* Ray; //the ray we use for the collision detection ObjectManager* ObjManager; //this is part of my engine, you cant use it, more on that later Ogre::Vector3 Scale; //the scale vector of the parent node, so the camera will work same on all sizes you set for your player {CODE} and we have these functions: {CODE(wrap="1", colors="c++")} public: Camera(Ogre::SceneNode* CenterParentNode, OgreOde::Space* Space, ObjectManager* Objects); ~Camera(void); bool virtual FrameStarted(double TimePassed); bool virtual FrameEnded(double TimePassed); void virtual Zoom(const double Value); //Move the camera relative along the ray bool virtual WriteToIni(IniFile& Ini) const {return true;} //save the camera to a file bool virtual LoadFromIni(const std::basic_string<wchar_t>& ObjectID, IniFile& Ini); //load from a file bool virtual collision(OgreOde::Contact *Contact); //collision callback void RotateX(double Value); //rotate the camera along x axis, use this instead of rotating the //rotation center if you dont want the player to rotate inline Ogre::Camera* GetCamera(void) {return MyCamera;} //maybe you need the original Ogre object sometime private: bool MoveChase(const double TimePassed); bool MoveFixed(const double TimePassed); void InitBase(void); void InitNodes(Ogre::Vector3 CamCenter, Ogre::Vector3 LookAtPosition); bool InitCamera(void); bool InitViewport(void); void CollideRay(void); }; {CODE} !!Constructor Initialize your members. The constructor gets the node of the parent object, like your player, the space including the ode objects that the camera is going to collide with and a pointer to my ObjectManager class. As I said you cant use it, you need to find a way to let the camera access your objects. {CODE(wrap="1", colors="c++")} ::Camera::Camera(Ogre::SceneNode* CenterParentNode, OgreOde::Space* Space, ObjectManager* Objects) : inherited(), MyCamera(0), LookAtNode(0), TargetLookAtNode(0), TargetPositionNode(0), RotationCenterNode(0), TightnessPos(0.0), TightnessLook(0.0), MaxDistance(2.0), MinDistance(0.0), Ray(0), MinCamRot(0.0), MaxCamRot(0.0), Distance(1.0), TargetDistance(1.0), CollisionInThisFrame(false), Scale() { {CODE} Create a child of the parent center node, so it may has its own rotation that does not effect the player {CODE(wrap="1", colors="c++")} RotationCenterNode = CenterParentNode->createChildSceneNode("Camera Pos"); //Camera never rotates around the z axis: RotationCenterNode->setFixedYawAxis(true); {CODE} Our Ray. You see that I cast the camera to CollidingObject and then make it user object of the Ray. I do this with every Geometry and its parent colliding class, so you can make your own collision callback behaviour for every object. To use this camera you somehow have to identify your camera in the ray . {CODE(wrap="1", colors="c++")} Ray = new OgreOde::RayGeometry(0, HardwareManager::getSingleton().GetWorld(), Space); Ray->setUserObject(static_cast<CollidingObject*>(this)); Ray->disable(); {CODE} Save a pointer to the class that handles all the objects we are going to collide with. {CODE(wrap="1", colors="c++")} ObjManager = Objects; Scale = CenterParentNode->getScale(); } {CODE} !!Destructor Clean up a little bit: {CODE(wrap="1", colors="c++")} ::Camera::~Camera(void) { delete Ray; } {CODE} !!Create Camera and Viewport These two functions create a camera and a viewport in ogre, I expect you are familiar with that. {CODE(wrap="1", colors="c++")} bool ::Camera::InitCamera(void) { // Create the camera if (MyCamera) HardwareManager::getSingleton().GetScene()->destroyCamera(MyCamera); MyCamera = HardwareManager::getSingleton().GetScene()->createCamera("PlayerCam"); if (!MyCamera) return false; MyCamera->setNearClipDistance(5); //note: Position is Ogre::SceneNode* and comes from CollidingObject Position->attachObject(MyCamera); return true; } bool ::Camera::InitViewport(void) { // Create one viewport, entire window static Ogre::Viewport* vp = HardwareManager::getSingleton().GetWindow()->addViewport(MyCamera); if (!vp) return false; //Pink is our background color vp->setBackgroundColour(Ogre::ColourValue(255,0,255)); // Alter the camera aspect ratio to match the viewport MyCamera->setAspectRatio(Ogre::Real(vp->getActualWidth()) / Ogre::Real(vp->getActualHeight())); return true; } {CODE} !!Init the SceneNodes Now we need several scene nodes for our camera. The RotationCenterNode is what it says and is created within the constructor, so we dont need to handle it here. We will only adjust its position to the given vector, so you can set it to the players head e.g. Then we have a TargetLookAtNode and a TargetPositionNode, these are the positions where the camera should be and look at, but maybe is not yet. LookAtNode and Position are the real ones and will be updated later. You will be able to choose, if you want a static or chasing camera. {CODE(wrap="1", colors="c++")} void ::Camera::InitNodes(Ogre::Vector3 CamCenter, Ogre::Vector3 LookAtPosition) { //set position of camera rotation center: RotationCenterNode->setPosition(CamCenter); //Destroy the nodes, if they exist if (LookAtNode) HardwareManager::getSingleton().GetScene()->destroySceneNode(LookAtNode->getName()); if (TargetLookAtNode) HardwareManager::getSingleton().GetScene()->destroySceneNode(TargetLookAtNode->getName()); if (TargetPositionNode) HardwareManager::getSingleton().GetScene()->destroySceneNode(TargetPositionNode->getName()); //create LookAtNode LookAtNode = HardwareManager::getSingleton().GetScene()->getRootSceneNode()->createChildSceneNode(); //the targets are children of the center node and as such always rotated automatically to the correct positions TargetLookAtNode = RotationCenterNode->createChildSceneNode(); TargetLookAtNode->setPosition(LookAtPosition); TargetPositionNode = RotationCenterNode->createChildSceneNode(); //note: Position is Ogre::SceneNode* and comes from CollidingObject //Real PositionNode shall always look at real LookAtNode Position->setAutoTracking(true, LookAtNode); //and it should never rotate around the z axis. Position->setFixedYawAxis(true); } {CODE}
Search by Tags
Search Wiki by Freetags
Latest Changes
One Function Ogre
IDE Eclipse
FMOD SoundManager
HDRlib
Building Ogre V2 with CMake
Ogre 2.1 FAQ
Minimal Ogre Collision
Artifex Terra
OpenMB
Advanced Mogre Framework
...more
Search
Find
Advanced
Search Help
Online Users
221 online users