Third person camera

You are an experienced programmer and have a problem with the engine, shaders, or advanced effects? Here you'll get answers.
No questions about C++ programming or topics which are answered in the tutorials!
Post Reply
the_viking
Posts: 23
Joined: Fri Aug 06, 2004 12:28 pm

Third person camera

Post by the_viking »

Hi,

I am aiming to build a 3rd Person camera that can be attached to scenenodes, and that is always staying behind the node, it always rotates like this node and so on.. so that you're always behind the node, at the same position relatively to the node. But all my experiments with Irrlicht failed to get this to work. The camera does not rotate properly, also the attaching to scenenodes seems not to work properly.

Can anyone help me? Someone of you surely managed to get such a camera ;)
puh
Posts: 356
Joined: Tue Aug 26, 2003 3:53 pm

Post by puh »

Did you read FAQ?
Third Person Camera | Set up a Third Person Camera | http://irrlicht.sourceforge.net/phpBB2/ ... php?t=1140
the_viking
Posts: 23
Joined: Fri Aug 06, 2004 12:28 pm

Post by the_viking »

that does not work... anyhow... dunno why

\E:

It's because it does not applicate the up vector... if i'd use that camera the scenenodes would rotate from the view of the Player... that's not what i want, i want a static camera, having the scenenode always at the same position and rotatation on the screen
the_viking
Posts: 23
Joined: Fri Aug 06, 2004 12:28 pm

Post by the_viking »

I applicated the code from here now, but the camera seems not to accept the position by the fakenode ( im using billboards instead)... it stays on a point, and I see the Dir and Pos nodes around my scenenode.. :(
the_viking
Posts: 23
Joined: Fri Aug 06, 2004 12:28 pm

Post by the_viking »

Ok, i got i fixed now... it's working then...
nitroman

Post by nitroman »

I read that thread in the faq and compiled the code... but how can you fix the "jitteryness" ?

Because it is so jittery that it can't be used seriously in a game (unlike the official fpscamera that work very good)
so for me this code is useless. :(
the_viking
Posts: 23
Joined: Fri Aug 06, 2004 12:28 pm

Post by the_viking »

Ok, i recoded 99% of the class so i have a nice working flying.behind-the-node-3rd-person-cam ;)

I'll share the code with you, so you can use it on you own:

camera.h:

Code: Select all

#ifndef CAMERA_H
#define CAMERA_H

#include <irrlicht.h>

/*
    Custom 3rd person following camera for irrlicht
    Made by the_viking in 2004 
*/

class cFollowingCamera 
{ 
    irr::scene::ISceneNode* m_pTargetNode; 
    irr::scene::ICameraSceneNode* m_cam; 
	irr::scene::IBillboardSceneNode* pCamPosNode,*pCamDirNode;

    irr::core::vector3df currentCameraPos; 
	irr::core::vector3df currentTargetPos;
	irr::f32 fSpeed;
    
   public: 
      // class constructor 
      cFollowingCamera(irr::scene::ISceneNode* targetNode, irr::scene::ISceneManager* smgr, 
										  irr::core::vector3df& vRelativePos = irr::core::vector3df(0,200,-200), irr::f32 speed = 15.f );
      // class destructor 
      ~cFollowingCamera(); 
       
      irr::scene::ICameraSceneNode* getCam() {  return m_cam; } 
       
	  // fDT = delta time in seconds.
      void Update(f32 fDT); 
}; 

// class constructor 
inline cFollowingCamera::cFollowingCamera(irr::scene::ISceneNode* targetNode, irr::scene::ISceneManager* smgr, 
										  irr::core::vector3df& vRelativePos, irr::f32 speed) 
{ 
	// how fast the camera moves
	fSpeed = speed;

	//create a camera 
	m_cam = smgr->addCameraSceneNode(0); // = new cFloatingCamera(targetNode,smgr,-1);

	smgr->setActiveCamera(m_cam);
	m_pTargetNode = targetNode; 

	m_pTargetNode->grab(); //make sure the node wont dissappear on us 

	// I am using billboard scenen nodes with a zero size, 
	// maybe you want to use the fake translation node
	pCamPosNode = smgr->addBillboardSceneNode(targetNode);
	pCamDirNode = smgr->addBillboardSceneNode(targetNode);

	pCamPosNode->setSize(core::dimension2d<f32>(0,0));
	pCamDirNode->setSize(core::dimension2d<f32>(0,0));
	
	pCamPosNode->setPosition(vRelativePos);
	pCamDirNode->setPosition(irr::core::vector3df(0,100.f,0));

	// Update absolute positions... these calls are
	// removing most of the "jitteryness" 
	m_pTargetNode->updateAbsolutePosition();
	pCamPosNode->updateAbsolutePosition();
	pCamDirNode->updateAbsolutePosition();

	// get first position for interpolation
	currentTargetPos = pCamDirNode->getAbsolutePosition();
	currentCameraPos = pCamPosNode->getAbsolutePosition();

	// you can change this, default value is 2000.f
	m_cam->setFarValue(15000.f);
} 

// class destructor 
inline cFollowingCamera::~cFollowingCamera() 
{ 
	m_pTargetNode->drop(); //make sure we let go of the node resource 
	pCamDirNode->drop();
	pCamPosNode->drop();
} 

inline void cFollowingCamera::Update(f32 fDT) { 
    if(!m_cam || !m_pTargetNode) return; 

	m_pTargetNode->updateAbsolutePosition();
	pCamPosNode->updateAbsolutePosition();
	pCamDirNode->updateAbsolutePosition();

    irr::core::vector3df currTargetPos = pCamPosNode->getAbsolutePosition();
	irr::core::vector3df currDirPos = pCamDirNode->getAbsolutePosition();
	irr::core::vector3df currTargetRot = m_pTargetNode->getRotation();
	irr::core::vector3df targetMoveRate = currTargetPos - currentCameraPos;
	irr::core::vector3df directionMoveRate = currDirPos - currentTargetPos;

	// Build matrix
	irr::core::matrix4 rotMatrix;
	rotMatrix.setRotationDegrees( currTargetRot );

	// Calculate new direction
	irr::core::vector3df Target(0,0,1);	
	irr::core::vector3df vUpVec(0,1,0);	

	rotMatrix.transformVect(Target);
	rotMatrix.transformVect(vUpVec);
	
	
	currentCameraPos += targetMoveRate * MIN(1.f,fDT * fSpeed);
	currentTargetPos += directionMoveRate * MIN(1.f,fDT * fSpeed);
	
	//Update camera
	
	m_cam->setPosition(currentCameraPos); 
	m_cam->setUpVector(vUpVec);
	m_cam->setTarget(currentTargetPos);
	
	m_cam->updateAbsolutePosition();    
} 

#endif
It's not very well commented, but for example, you can use it like this (i expect there is a scenenode pPlayerNode that represents your player and a pointer to a cFollowingCamera as a member in a class, pSMGR is the scenemanager):

Code: Select all

mpCam = new cFollowingCamera( pPlayerNode, pSMGR, irr::core::vector3df(0, 10,-30, 10.f );
In your update function you then write:

Code: Select all

mpCam->update( fDeltaTime );
That's all, then it should work fine. Don't forget to release your instances by delete ;)

\edit:
Maybe you have to define the MIN() macro or you have to place your own min() function there.. my macros look like these:

Code: Select all

#define MIN(a,b) ( (a) < (b) ? (a) : (b))
#define MAX(a,b) ( (a) > (b) ? (a) : (b))
I dont't know if irrlicht has it's own min,max routines, and i'm too lazy to check ;)

\edit2:
If you use this in your game, or anyone uses this in his game, it would be really nice from you if you tell me :) In my space shooter this camera works pretty well, so tell me if it doesn't work in your games
eeheeehe
Posts: 22
Joined: Tue Sep 28, 2004 3:33 am

Post by eeheeehe »

I have been trying to figure out how to use this camera, but my compiler (DevC++) keeps throwing me the following error message:

Code: Select all

C:/Programming/irrlicht-0.7/include/camera.h:31: error: `f32' was not declared 
   in this scope
C:/Programming/irrlicht-0.7/include/camera.h:31: error: syntax error before `)' 
   token
C:/Programming/irrlicht-0.7/include/camera.h:24: error: invalid type `
   irr::core::vector3df' for default argument to `irr::core::vector3df&'

C:/Programming/irrlicht-0.7/include/camera.h: In constructor `

   cFollowingCamera::cFollowingCamera(irr::scene::ISceneNode*, 
   irr::scene::ISceneManager*, irr::core::vector3df&, float)':
C:/Programming/irrlicht-0.7/include/camera.h:54: error: `core' undeclared 
   (first use this function)
C:/Programming/irrlicht-0.7/include/camera.h:54: error: (Each undeclared 
   identifier is reported only once for each function it appears in.)
C:/Programming/irrlicht-0.7/include/camera.h:54: error: syntax error before `::
   ' token
C:/Programming/irrlicht-0.7/include/camera.h:55: error: syntax error before `::
   ' token

C:/Programming/irrlicht-0.7/include/camera.h: At global scope:

C:/Programming/irrlicht-0.7/include/camera.h:82: error: `f32' was not declared 
   in this scope
C:/Programming/irrlicht-0.7/include/camera.h:82: error: syntax error before `)' 
   token
C:/Programming/irrlicht-0.7/include/camera.h: In member function `void 
   cFollowingCamera::Update(...)':
C:/Programming/irrlicht-0.7/include/camera.h:107: error: `fDT' undeclared 
   (first use this function)
C:/Programming/irrlicht-0.7/include/camera.h:107: error: `MIN' undeclared 
   (first use this function)
Post Reply