for my recent project i build a flying 3rd Person camera. It supports interpolation between positions, so this will be a very smooth cam
It bases on some code i found in the forum, but that was very buggy and that cam wasn't too beautyful to fit my high expectation
So this camera would be always behind or in front of or wherever you want it of a scene node you can it attach to. So here is the code:
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
Code: Select all
mpCam = new cFollowingCamera( pPlayerNode, pSMGR, irr::core::vector3df(10,-30, 10.f );
Code: Select all
mpCam->Update( fDeltaTime );
Write this to you cleanupGame() function or whatever you name it:
Code: Select all
delete mpCam;
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 testet this class well with my Project ( a Spaceshooter ), but if you can catch some bugs, just report
Well then, i would show you a screenshot, but my project is commercial and i am not allowed to give you any media. Maybe i will make a example app when i have some free time here But you're free to do