About rotation of a camera

Hi!
I’m sorry the question is an old topic.But i can’t find the answer.

I want to implement rotation of a camera in an OpenGL apllication. Assume x-axis, y-axis and z-axis angles are a, b and c.
My code is :

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(x,y,z);               
glRotatef(a, 1.0f, 0.0f, 0.0f); 
glRotatef(b, 0.0f, 1.0f, 0.0f); 
glRotatef(c, 0.0f, 0.0f, 1.0f); 

glBegin();

             ....  //draw scene

glEnd(); 

The results are different when I switch the order of the rotate functions because of different orders of matrix multiplication.

But how to implement it correctly?

Thanks for your help!

The correct way is the way you want it to behave.

There’s no “correct” way in the general case. One order might be correct for me, cause that’s the way I want it, but it might not be correct for you.

Hi Bob!
I try to implement a camera just like cameras in some high-level APIs(e.g. Performer).
In those APIs, users give a camera position vector and a camera direction vector. Then APIs caculate the OpenGL modelview matrix from these two vectors.
I just want to implement the function in my OpenGL application. But i don’t know the right way to implement it.
Thanks for your help !

Have a nice day.

In this case, you do not care about angles.

What you want to do is basically why gluLookAt was created for, but suposing you want to do it by hand :

Lets call D the direction (capitals are for vectors) :
X,Y,Z are the camera’s axis.

Z = - D;
normilize(Z); // you got Z
Y = (0,1,0); // if you want a vertical Y axis for the camera (in case of Z is also (0,1,0), you got a problem.
s = Y.Z;
Y -= sZ;
normilize(Y); // you got Y
X = Y*Z; // (cross product)
you are done.

try to follow these steps geometrically, its simple.
Then of course add the position of you camera (“transposed”, ie not the camera’s position in respect to the center of the scene, but the position of the center of the scene in respect to the camera), and you got your camera matrices to push at first onto your model view matrix :

GLfloat cam_pos_transp = {
Xx, Yx, Zx, 0,
Xy, Yy, Zy, 0,
Xz, Yz, Zz, 0,
Tx, Ty, Tz, 1
};

where Xx is the x coordinate of the X axis, etc, and T is the position of center in respect to camera’s position, that is, if you have the position of camera in respect to center (let’s call it t) :

[Tx,Ty,Tz] = - [ [Xx,Yx,Zx] [Xy,Yy,Zy] [Xz,Yz,Zz] ] * [tx,ty,tz]

(in standard matricial notations).

got it ? :slight_smile:
(sorry but im not used to do maths in english - Im preparing an article about this kind of calculus but in french)

[This message has been edited by rixed (edited 12-13-2001).]

Hi Rixed!

Sorry, there is an error in my description.The parameters given by users are a camera position vector and three rotation angles(not a camera dircetion vector).

I’ve gotten model-view matrices from both Performer and OpenGVS . I find that rotation orders in these high-level APIs are different.

I think perhaps the rotation order depends on the origin dircetion of a camera. Is it right?

Thank your very much Rixed. I really appreciate it.

Like Bob said, there is no “correct” rotation order, any way is fine. If you want to use the same order Performer uses, just look up what it uses and do your rotations in that order. Or use the order you use currently, and specify that rotation order in the docs. However Euler angles (specifying orientation as three angles) has some other problems so it might be wise to include something like gluLookAt also.

If you want the user input to be 3 angles, then you have plenty of way to use these angles to rotate the camera, that’s why its not a very friendly way to set up a camera.

You can multiply the matrices representing the 3 rotation in any order, what I would call ‘rotation around fixed axis’ because it looks like tho object rotate around X, then the original Y, then the original Z.

You can also compute the rotation of the object around, say, X, then the rotation of the object around the new Y axis (rotated around X), then the rotation around the newest Z (rotated around X then Y), which is what i would call ‘rotation around rotating axis’, which require more computing but give more predictible results.
Everything is once again order dependant.
So the possibilities are vast.
So I do not like angles

OK! I know how to use these angles to rotate the camera now.

Thank you very much Rixed, Harsman and Bob!

But there is an other problem about rotaion of the camera. If i use a camera direction vector to specify rotation. I find that only a camera dircetion vector can not describe the rotation around camera dircetion .

E.g. the camera origin dircetion vector is (0,0,-1). When the camera is rotated around z axis, the dircetion vector does not change.

In this case, how to do? Thanks!

If you specify a point of view, and a direction of the camera, you have some problem, as you say. What you have is an equation system with two equations and three unknown. I.e. there’s an infinite amount of solutions.

The effect can be described like this (in real life that is). Stand in the middle of the room, and look towards something. You now have a viewpoint, and a viewing direction. Tilt your head to the left. You are still standing at the same spot, looking at the same point (i.e., same viewpoint and same direction), but the rotation about the directon vector is different. Tilt your head to thr right, and you haev yet another solution to the same viewpoint and direction.

What you need to solve this problem is a so called up-vector. An up-vector is a vector describing what is up for the camera. If you take my example above, and say that the up-vector is to the right, you must tilt your head to the right, and only to the right, to satisfy all three requirements: viewpoint, view direction and where the camera’s up is supposed to point.

Three equations and three unknown -> solvable with one, and only one, unique solution (unless the system is unsovable )

Take a look at the function gluLookAt to better understand what it’s all about.