"FPS-but-static" camera

You are an experienced programmer and have a problem with the engine, shaders, or advanced effects? Here you'll get answers.
No questions about C++ programming or topics which are answered in the tutorials!
Post Reply
SpyM
Posts: 9
Joined: Tue Jul 09, 2013 3:29 pm

"FPS-but-static" camera

Post by SpyM »

Hello Irrlicht community,

I am currently working on a visualization tool for some statistics, and I chose Irrlicht to handle it. I also decided to use Qt to move the camera precisely by entering the absolute coordinates for position and rotation.
Giving the absolute values for the position/rotation of the camera to a computer is great, but it is not very practical for humans :(
For this reason, I would like to be able to move a FPS camera precisely without using Irrlicht's keyboard-mouse input system and the game loop.

I saw there is a FPS camera in Irrlicht, but it seems to be inadequate for what I want, because I do not want to use keyboard input.
Do you know a way to get the movement vectors (forward, back, left, right) and the rotation vectors (actually angles pitch and yaw) ? Does Irrlicht provide this kind of "FPS-but-static" camera, or do I have do implement it by myself using maths ?

Here are the maths if you want them, by the way :)
aib from Stackoverflow wrote: The way I have always seen it done is using two angles, yaw and pitch. The two axes of mouse movement correspond to changes in these angles.
You can calculate the forward vector easily with a spherical-to-rectangular coordinate transformation. (pitch=latitude=φ, yaw=longitude=θ)
You can use a fixed up vector (say (0,0,1)) but this means you can't look directly upwards or downwards. (Most games solve this by allowing you to look no steeper than 89.999 degrees.)
The right vector is then the cross product of the forward and up vectors. It will always be parallel to the ground plane since the up vector is always perpendicular to the ground plane.
Left/right strafe keys then use the +/-right vector. For a forward vector parallel to the ground plane, you can take the cross product of the right and the up vectors.
As for the GL part, you can simply use gluLookAt() using the player's origin, the origin plus the forward vector and the up vector.
Oh and please, please add an "invert mouse" option.
Edit: Here's an alternative solution which gets rid of the 89.9 problem, asked in another question, which involves building the right vector first (with no pitch information) and then forward and up.
trollger
Posts: 84
Joined: Tue Jun 01, 2010 2:17 am
Location: At my computer

Re: "FPS-but-static" camera

Post by trollger »

I would like to be able to move a FPS camera precisely without using Irrlicht's keyboard-mouse input system and the game loop.
A game loop is simply a repeated call to update your games logic, input, and to draw a scene. Since a vidoe game moves very fast with a lot of changing variables this game loop is called over and over again to check for each event, but it sounds like you have a very specific program in mind. Instead of calling the next game loop right after the last one, you could redraw the scene depending on some input from QT, which I think is what you would want.
I saw there is a FPS camera in Irrlicht, but it seems to be inadequate for what I want, because I do not want to use keyboard input.
Do you know a way to get the movement vectors (forward, back, left, right) and the rotation vectors (actually angles pitch and yaw) ? Does Irrlicht provide this kind of "FPS-but-static" camera, or do I have do implement it by myself using maths ?
The FPS camera is used for a very specific tast, that being an FPS camera, and it is designed to use keyboard/mouse movement to look around. If you want you could set the movement speed to 0, I believe that will allow you to look around with the mouse without it moving with the keyboard. Otherwise you will be way better off using irr::scene::ICameraSceneNode. If you look at the APIs you would see that irr::scene::ICameraSceneNode has these methods

virtual void setPosition (const core::vector3df &newpos)
Sets the position of the node relative to its parent.

virtual void setRotation (const core::vector3df &rotation)
Sets the rotation of the node relative to its parent.

which is what I think you want.
SpyM
Posts: 9
Joined: Tue Jul 09, 2013 3:29 pm

Re: "FPS-but-static" camera

Post by SpyM »

I already implemented the static camera with position and rotation values using ICameraSceneNode. I just want to move it FPS-way. Actually, I've done exactly what you suggested : no game loop, Qt updates scene only when settings change. I'm sorry I forgot to mention it in the first place.

I know setPosition does exactly what I want if I do some maths. But I would like to avoid it by using Irrlicht's functions :)
trollger
Posts: 84
Joined: Tue Jun 01, 2010 2:17 am
Location: At my computer

Re: "FPS-but-static" camera

Post by trollger »

Irrlicht has lots of inbuilt math functions look into core::vector3d and core::CMatrix4, they should have everything you need.
SpyM
Posts: 9
Joined: Tue Jul 09, 2013 3:29 pm

Re: "FPS-but-static" camera

Post by SpyM »

I started doing the maths by using the source code of the FPS Camera. Forward (X-axis) and Up (Z-axis) vectors and orientation vectors are working well, but the left vector is not correct.

Could you help me to find my mistake in this piece of code ? "moveVector" is the move vector related to the camera view, and "staticCamera" is the camera scene node.

Thanks :)

Code: Select all

void CameraWindow::move(irr::core::vector3df moveVector) {
 
    staticCamera->updateAbsolutePosition();
    irr::core::vector3df pos = staticCamera->getPosition();
    irr::core::vector3df target = (staticCamera->getTarget() - staticCamera->getAbsolutePosition());
 
    irr::core::vector3df relativeRotation = target.getHorizontalAngle();
 
    // forward-backwards
    target.set(0,0, irr::core::max_(1.f, pos.getLength()));
    irr::core::matrix4 mat;
    mat.setRotationDegrees(irr::core::vector3df(relativeRotation.X, relativeRotation.Y, 0));
    mat.transformVect(target);
    irr::core::vector3df forwardDirection = target;
    forwardDirection.normalize();
    pos += forwardDirection * moveVector.X;
 
    // left-right
    irr::core::vector3df leftDirection = target.crossProduct(staticCamera->getUpVector());
    leftDirection.normalize();
    pos += leftDirection * moveVector.Y;
 
    // up-down
    irr::core::vector3df upDirection = staticCamera->getUpVector();
    upDirection.normalize();
    pos += upDirection * moveVector.Z;
 
    staticCamera->setPosition(pos);
 
    target += pos;
    staticCamera->setTarget(target);
}
My method is the one described in the StackOverflow post. I make the cross product of the forward vector (pointing to target) and the up vector (defined by camera) to find the left vector by using right hand's rule. However, this technique seems to be wrong :(
SpyM
Posts: 9
Joined: Tue Jul 09, 2013 3:29 pm

Re: "FPS-but-static" camera

Post by SpyM »

I found the problem.

setTarget needs an updateAbsolutePosition before being used (see camera node doc).
Post Reply