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:
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