I'm making my own camera in Irrlicht, but the camera is very glitchy and jumpy. And at the start, when the camera has not yet moved, it jerks around so much when you try to rotate that it's almost impossible to do something sane!
Anyway, please scan through the provided source if you have time
Code: Select all
#include "../include/cCamera.h"
cCamera::cCamera()
{
cameraStyle = CS_NONE;
doMouseMovement = true;
firstUpdate = true;
angleY = 0.0f;
angleZ = 0.0f;
minAngle = -45.0f;
maxAngle = 89.0f;
zoomIn = false;
zoomOut = false;
minDist = 1;
maxDist = 100;
boxSize = 0;
zoomSpeed = 10;
targetOffset = vector3df(0, 0, 0);
invertX = false;
invertY = true;
invertZ = true;
forwardIndex = 0;
sidewardIndex = 0;
}
cCamera::~cCamera()
{
}
bool cCamera::createCamera(ISceneManager* Smgr, ICursorControl* cursorcontrol, cEvent* event, f32 rotatespeed, f32 movespeed)
{
if(camera)
delete camera;
if((camera = Smgr->addCameraSceneNode()) == NULL)
return false;
Smgr->setActiveCamera(camera);
eventManager = event;
rotateSpeed = rotatespeed;
moveSpeed = movespeed;
smgr = Smgr;
cursorControl = cursorcontrol;
moveSpeed /= 1000.0f;
return true;
}
void cCamera::moveForward(long distance)
{
// camera->setTarget(vector3df(0.0f, 0.0f, 1.0f));
vector3df pos = camera->getPosition();
vector3df movedir = camera->getTarget();
movedir.normalize();
pos += movedir * (f32)distance;
camera->setPosition(pos);
camera->setTarget(pos + movedir);
camera->updateAbsolutePosition();
}
void cCamera::moveSideward(long distance)
{
camera->setTarget(vector3df(0.0f, 0.0f, 1.0f));
vector3df pos = camera->getPosition();
vector3df strafevect = camera->getTarget();
strafevect = strafevect.crossProduct(camera->getUpVector());
strafevect.normalize();
pos += strafevect * (f32)-distance;
camera->setPosition(pos);
camera->setTarget(pos + camera->getTarget());
camera->updateAbsolutePosition();
}
void cCamera::update()
{
if(smgr->getActiveCamera() != camera)
return;
if(cameraStyle <= CS_NONE || cameraStyle >= CS_LAST)
return;
if(firstUpdate)
{
if(cursorControl)
cursorControl->setPosition(0.5f, 0.5f);
lastTime = GetTickCount();
firstUpdate = false;
return;
}
if(eventManager->keys[ZOOMIN])
zoomIn = true;
else
zoomIn = false;
if(eventManager->keys[ZOOMOUT])
zoomOut = true;
else
zoomOut = false;
switch(cameraStyle)
{
case CS_1ST:
update1ST();
break;
case CS_3RD:
update3RD();
break;
case CS_RTS:
break;
}
}
void cCamera::updateMousePos()
{
position2d<irr::f32> pos = cursorControl->getRelativePosition();
if(pos.X < (0.5f)) pos.X = (0.5f);
if(pos.X > (0.5f)) pos.X = (0.5f);
if(pos.Y < (0.5f)) pos.Y = (0.5f);
if(pos.Y > (0.5f)) pos.Y = (0.5f);
cursorControl->setPosition(pos);
}
void cCamera::update1ST()
{
s32 now = GetTickCount();
s32 timeDiff = now - lastTime;
lastTime = now;
camera->setTarget(vector3df(0.0f, 0.0f, 1.0f));
if(!cursorControl)
return;
if(doMouseMovement)
{
position2d<f32> pos = cursorControl->getRelativePosition();
if(pos.X < 0.5f-EPSILON)
angleY += (pos.X-(0.5f))*rotateSpeed;
if(pos.X > 0.5f+EPSILON)
angleY += (pos.X-(0.5f))*rotateSpeed;
if(angleY > 360.0f)
angleY -= 360.0f;
if(angleY < 0.0f)
angleY += 360.0f;
if(pos.Y < 0.5f-EPSILON)
angleZ += (pos.Y-(0.5f))*rotateSpeed;
if(pos.Y > 0.5f+EPSILON)
angleZ += (pos.Y-(0.5f))*rotateSpeed;
if(angleZ < minAngle) angleZ = minAngle;
else if(angleZ > maxAngle) angleZ = maxAngle;
updateMousePos();
}
// Create translation vector - is this correct?
vector3df dist = camera->getTarget() - camera->getPosition();
vector3df translation((f32)dist.getLength(), 0, 0);
translation.rotateXYBy(-angleZ, vector3df(0,0,0));
translation.rotateXZBy(-angleY, vector3df(0,0,0));
// update position
vector3df pos = camera->getPosition();
vector3df movedir = camera->getTarget() + translation;
movedir.normalize();
if(forwardIndex != 0)
{
pos += movedir * (f32)/*timeDiff */forwardIndex * moveSpeed;
forwardIndex = 0;
}
if(sidewardIndex != 0)
{
vector3df strafevect = camera->getTarget() + translation;
strafevect = strafevect.crossProduct(camera->getUpVector());
strafevect.normalize();
pos -= strafevect * (f32)/*timeDiff */sidewardIndex * moveSpeed;
sidewardIndex = 0;
}
// write translation
camera->setPosition(pos);
// write right target
targetVector = camera->getTarget();
camera->setTarget(pos + translation + targetVector);
camera->updateAbsolutePosition();
}