The way I consider safe to a persons sanity is to handle the "camera" like any other object. Since scaling the camera doesn't make much sense, all you got are rotation (in the top left 3x3 "sub matrix" and translation in the last column -corresponding to the last 4 floats in the memory layout used for OpenGL-).
This means the first three columns are basically the cameras x,y,z (typically "right", "up" and "forward") axes expressed in world coordinates with the last column being it's position. It's convenient and easy to read.
To use it as view matrix, you obviously need to move everything "the opposite way", so you need the inverse of your matrix. Since you didn't scale, your matrix can be inverted in a simple way. The rotation part is transposed (which explains why it's rows, not columns) and the translation is negated along the original axes (which is better explained by showing the result.
So if your camera matrix (using r,u,f,p as right, up, forward, position instead of uvn) is:
r.x u.x f.x p.x
r.y u.y f.y p.y
r.z u.z f.z p.z
0 0 0 1Your view matrix will be (created from the camera matrix once per frame):
r.x r.y r.z -(p dot r)
u.x u.y u.z -(p dot u)
f.x f.y f.z -(p dot f)
0 0 0 1So: keep your camera matrix around, don't recalculate from scratch every frame and for heavens sake, stay as far away from Euler angles as possible (ego shooter style camera is about the only thing they can handle without a lot of head ache).
I'm not sure why Kaptein makes rotating an object around itself so complicated. If you want the camera to rotate around itself, you use camera_matrix * rotation_matrix. If you want it to rotate around the origin you use rotation_matrix * camera_matrix (or the other way around). If you are in fact feeling lazy, you can abuse OpenGL to do the matrix math. Translation and rotation are always applied in object coordinates, so objects already rotate around themselves (using their current right/up/forward axes), no matter where they are and always translate along their local axes as well.
Point is: OpenGL is not doing anything "backwards" unless you insist on thinking in world coordinates instead of object coordinates.
Examples:
-Strafe right is always glTranslate(1,0,0)
What people often do: calculating some "right" vector (instead of 1:1 extracting it from the objects transformation matrix) and then going to the trouble of translating along that vector in global coordinates by forcing things to be done "backwards".
-"Pitch around self" is always glRotate(angle, 1,0,0)
What people often do: calculate some "right" vector (again), then do stuff backwards (including translating stuff to the origin and back)
If you want to mix things, like rotate around "global up" but around your current position, you still don't need to start translating. You just need to adjust your axis by multiplying the "global" axis with the transposed rotation part of the object (basically you cancel out the existing rotations, so your objects "up" is the same as the worlds "up"):
To rotate around global (0,1,0):
axis.x = 0*r.x + 1*r.y + 0*r.z
axis.y = 0*u.x + 1*u.y + 0*u.z
axis.z = 0*f.x + 1*f.y + 0*f.zie: glRotate(angle, r.y, u.y, f.y)Bottom line: think forward and think local, it will make things much easier and more intuitive
Edited by Trienco, 12 September 2012 - 10:50 PM.