As we all know rotation in Irrlichts default cameras is really jerky. There are two reasons for that:
1) small mouse position changes are not regonized
2) rotation angle may differ between frames because of aproximation (ex: if you move your mouse with a speed of 3.5 pixels per frame in one frame it will be treated as you had moved 3 pixel and in next frame as 4 pixels)
Ad.1
Quite easy to fix. Just change this lines in
CCameraFPSSceneNode::animate() (CCameraFPSSceneNode.cpp)
Code: Select all
if (cursorpos.X < 0.49f || cursorpos.X > 0.51f ||
cursorpos.Y < 0.49f || cursorpos.Y > 0.51f)
Code: Select all
if (cursorpos.X < 0.5f || cursorpos.X > 0.5f ||
cursorpos.Y < 0.5f || cursorpos.Y > 0.5f)
The way to solve this is taking average mouse posiotion change of last 3 frames instead of only last one.
First we have to add to tables to hold last two mouse positions and a variable to checkif it is the first time we make rotation. Just put this into CCameraFPSSceneNode definition (CCameraFPSSceneNode.h)
Code: Select all
f32 rotX[3];
f32 rotY[3];
bool firstRot;
Code: Select all
// Update rotation
Target.set(0,0,1);
if (!CursorControl)
return;
RelativeRotation.X *= -1.0f;
RelativeRotation.Y *= -1.0f;
if (InputReceiverEnabled)
{
core::position2d<f32> cursorpos = CursorControl->getRelativePosition();
if(firstRot) // it checks if it is the first time camera rotates and than fill tables with proper values
{
rotX[0] = rotX[1] = 0.5f - cursorpos.X;
rotY[0] = rotY[1] = 0.5f - cursorpos.Y;
firstRot=false;
}
rotX[2] = 0.5f - cursorpos.X; // puts values from this frame
rotY[2] = 0.5f - cursorpos.Y;// into table
if (cursorpos.X < 0.5 || cursorpos.X > 0.5 ||
cursorpos.Y < 0.5 || cursorpos.Y > 0.5 )
{
RelativeRotation.Y += (rotX[0]+rotX[1]+rotX[2])/3 * RotateSpeed; // here we use the average value i mentioned before
RelativeRotation.X += (rotY[0]+rotY[1]+rotY[2])/3 * RotateSpeed; // and here too ;)
CursorControl->setPosition(0.5f, 0.5f);
if (RelativeRotation.X > 89.0f) RelativeRotation.X = 89.0f;
if (RelativeRotation.X < -89.0f) RelativeRotation.X = -89.0f;
}
rotX[0] = rotX[1]; // finaly we move values to make room for a new ones
rotX[1] = rotX[2];
rotY[0] = rotY[1];
rotY[1] = rotY[2];
}
// set target
If you find some bugs or have some improvements i'll be glad to read them.
To Nico: How about adding it to SDK ? And another thing. Why default value for FOV is set to 45 degrees ? With it camera works like in alien mode form AvP Set it to 90 or something. I know it's easy to change via FOV(), but some newbies might have problems with "what's wrong with the camer" while watching techdemo or examples.