hi. i’m working on a small 3d engine atm and just wrote vector, matrix and quaternion classes to calculate transformations and rotations. i’m sure these classes work correct as they are inspired by the ones of several open source engines.
in my camera class i have functions to translate and rotate the view, but it’s not working the way it should: translations work fine, but the camera is always rotated around the global axis and not its own axis. i guess it’s a simple mistake because i’m still new to this quaternion stuff, so maybe you see what’s i’m doing wrong:
using the mouse and keyboard the player calls functions to rotate (vxQuaternion Rotation) and translate (vxVector Translation) the camera
void vxCamera::Render( bool wireframe )
{
// Create a matrix from the rotation and translation and apply it
glLoadMatrixf( vxMatrix(Rotation, Translation) );
// Render world
World->Render( wireframe );
}
I think the issue may be that in order to apply a camera matrix, you need to apply the observer’s inverse transformation.
You can construct a simple matrix using unit vectors and translation to place a vertex in the world, but since the world has to be moved into the camera’s coordinate system, you need to use the inverse of the observer’s transformation matrix.
Now if that doesn’t solve the issue, I think you’ll need to post some more code.
you need to use the inverse of the observer’s transformation matrix
so how can i construct this matrix? would it simply be the inverted camera matrix? thx so far btw
I’m not too good at matrix math, I’m afraid.
I just use gluLookAt with the translation and a couple of components from my rotation matrix.
But I don’t think the inverse is the same as the transpose.
In OGL terms, the normal matrix would be constructed by means of glTranslate(pos) then 3 glRotates, the inverse would be constructed by the negative actions in the reverse order.
That bit of info might help you out.
Also, I believe the redbook has some info on matrices.
No ! the inverse of a matrix is not the transpose of this matrix.
When doing row major matrix (the maths default way), the transpose of the matrix will provide a matrix suitable for gl purpose (column major).
The invert of a matrix is the matrix that, when multiplied with the original matrix, will result in the identity matrix: M*M-1=Id.
For doing the rotation around your local camera axis, you’ll need to do some maths. The simplest way is to rotate first (when on the origin) then translate, without multiplying the matrices. And that, in fact, doesn’t require the use of matrices, which is better (less calculations to do).
For doing the rotation around your local camera axis, you’ll need to do some maths. The simplest way is to rotate first (when on the origin) then translate, without multiplying the matrices.
i tried it this way and the rotation worked fine - but then the TRANSLATION was in global space… so if i do it this way, how can i calculate the right direction to move the camera?
That’s where those nice matrix and vector classes you made come in:
When moving the camera:
calculate rotation matrix for camera’s rotation (the forward matrix) (You only need to do this when the camera rotation has changed)
multiply the camera movement by that matrix and add to the current camera position (the movement may be in three axes, but they can be combined into one vector)
When rendering:
when you set up the modelview matrix, do as you’re doing now
(Take it from me: you don’t want to store a camera position local to its own coordinate system)
uhm i’m afraid i don’t understand the 2nd step correctly… because now the camera spins insanely around^^ this is what my render routine looks like now:
void vxCamera::Render( bool wireframe )
{
// Create matrix from rotation
vxMatrix Matrix = vxMatrix(Rotation);
// Multiply translation by that matrix
Translation = vxVector( Matrix*Translation );
// Add that to the current camera position
Matrix += Translation;
// Apply matrix
glLoadMatrixf( Matrix );
// Render world
World->Render( wireframe );
}
Actually, that’s why I said “movement”, not translation.
Keep the camera position separate, and global.
When rotating the camera, keep a rotation matrix around. (It pays to keep that around because you’re probably not rotating all the time, and it’s free).
When processing a movement command (whether that is from the keyboard or the mouse or whatever), apply that rotation matrix to the movement vector (which could have “forward”, “right” and “up” components), and add the result (a vector) to the camera position.
Use the camera rotation and the camera position to setup your view.
BTW: I get the impression you’re still not taking the inverse when setting up the view.
i have written a litte camera class for navigating through a 3d-world.
it calculates the position, view-vector and the ‘up-vector’ for the gluLookAt-function : navigator.h navigator.cpp
Example use :
in the init function :
Navigator* nav = new Navigator(-4, 0, 0);
nav->setViewPos(0, 0, 0);
nav->setDelta(10.0f, 5.0f);