Page 1 of 1

Third person camera

Posted: Wed Aug 11, 2004 12:54 pm
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 ;)

Posted: Wed Aug 11, 2004 1:29 pm
by puh
Did you read FAQ?
Third Person Camera | Set up a Third Person Camera | http://irrlicht.sourceforge.net/phpBB2/ ... php?t=1140

Posted: Wed Aug 11, 2004 1:44 pm
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

Posted: Wed Aug 11, 2004 2:23 pm
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.. :(

Posted: Wed Aug 11, 2004 2:36 pm
by the_viking
Ok, i got i fixed now... it's working then...

Posted: Fri Aug 13, 2004 12:05 am
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. :(

Posted: Sun Aug 15, 2004 1:34 pm
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

Posted: Sat Oct 16, 2004 3:58 am
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)