# matrix camera

For a camera implementation I’ve decided to do the following:

Store the camera’s pos, right, up, and forward vectors.

When rotating left/right I’d multiply the orientation vectors [r|u|f] by a the standard y axis rotation matrix

cos 0 sin
0 1 0
-sin 0 cos

When rotating up/down I’d rotate by the camera’s right vector, not the x, since if the camera is rotated the x axis wouldn’t be at a right angle to the forward vector.

I build the matrix like with I + sin(angle)*S + (1-cos(angle))*S^2 where I = identity,

S = {0, -u.z, u.y}
{u.z 0 -u.x
{-u.y u.x 0}

Doing that gets me awkward rotations, I get rolls when I should be getting a yaw.

If anyone’s interested I’ve tried getting an answer on this thread: http://www.gamedev.net/community/forums/topic.asp?topic_id=78749

[This message has been edited by outRider (edited 02-06-2002).]

The problem is that you are doing rotation around i,j,k. So you are essentially rotating your whole coordinate system around i, j or k. You have to visualise your three vectors and the basic coordinate system at the same time.

Ex. At the beginning, forward = 0,0,1 left = 1,0,0 up = 0,1,0.

You do a rotation of 90 degrees around k( a roll ). So what you get is

forwatd = 0,0,1 left = 0,-1,0 up = 1,0,0

But now, you want to turn your to the left, so you think I will rotate 90 around j. Incorrect, because by doing, your coordinates is actually rotating around your left axis because it is the one aligned with j. And so you end up with

forward = -1,0,0 left 0, -1, 0 up = 0,0,1

Ok. So the solution : rotate around your coordinate system.

So if you want to roll, you use your forward vector has the axis, if you want to yaw use the Up vector and if you want to pitch use your left vector.

If you look on the web, you will be able to find the calculations to build a matrix from any axis and an angle.

But, if you are simulating a human head movement, you will need to restrict the angle at which you rotate.

[This message has been edited by Gorg (edited 02-06-2002).]

That’s what I first tried, rotating around the camera’s orientation vectors and not the x/y/z axes, but that doesn’t work. If I turn left 90 then rotate up 90 I get a roll directly infront of me, the rotation up happens in the direction I just turned away from.

Like I said, for human head movement I’d yaw around the left vector, and pitch around the y axis, since if you look up 45 degrees then turn left your line of site doesn’t drop down, but stays at a constant height and moves across.

Yeah. That is also fine.

But if you ever wanted to do a plane, or underwated movement or space movement when you can move in any direction, you would need to rotate around your up,left and up vector

The point is it doesn’t work, I get a roll when I should get a pitch, when using either the y or up axes.

Then you have a bug in your software or your are misinterpreting what you are seing on screen.

Have you checked the actual values of vectors after the rotation? Are they correct? If yes, than you are misinterpreting what you see, if not then you have a bug.

*Update * : I just went to have a look at your stuff on gamedev, and you should not be using straight equations like that. They are error prone, hard to read and hard to debug.
What you should be doing is creating a matrix from the axis and the rotation angle and multipling it with the vectors of your base.

[This message has been edited by Gorg (edited 02-07-2002).]

That’s exactly what I’m doing…

Anyhow, I did what you said and as far as the rotation goes it seems to do as intended, first a 90deg yaw gets me from

L=1, 0, 0
U=0, 1, 0
F=0, 0, 1

to

L=0, 0, -1
U=0, 1, 0
F=1, 0, 0

then rotating that vertically gets

L=0, 0, -1
U=1, 0, 0
F=0, -1, 0

So i figure it must be how I’m building the final view matrix and passing it to GL. So here’s that, more or less.

CMatrix CamMatrix(Right.GetX(), Up.GetX(), Forward.GetX(),
Right.GetY(), Up.GetY(), Forward.GetY(),
Right.GetZ(), Up.GetZ(), Forward.GetZ());

``````CamMatrix.Transpose();

CVector3D	Result = CamMatrix.Mul(Position);

Result.Flip();

float	Matrix[16];

Matrix[0] = CamMatrix.Get(0, 0);
Matrix[1] = CamMatrix.Get(0, 1);
Matrix[2] = CamMatrix.Get(0, 2);
Matrix[3] = Result.GetX();

Matrix[4] = CamMatrix.Get(1, 0);
Matrix[5] = CamMatrix.Get(1, 1);
Matrix[6] = CamMatrix.Get(1, 2);
Matrix[7] = Result.GetY();

Matrix[8] = CamMatrix.Get(2, 0);
Matrix[9] = CamMatrix.Get(2, 1);
Matrix[10] = CamMatrix.Get(2, 2);
Matrix[11] = Result.GetZ();

Matrix[12] = 0;
Matrix[13] = 0;
Matrix[14] = 0;
Matrix[15] = 1;

//glMultMatrixf(Matrix);
``````

[This message has been edited by outRider (edited 02-07-2002).]

Ignore the fact that one of the vectors is named Right and that I keep reffering to it as left, it should be Left but its 6am…

If anyone wants to see what I see http://www.geocities.com/y_mohamoud has the basic exe, texture, and camera source. If you run that and hit left the cam rotates left, so rotate 90 to the left, then hit up, you’ll see what I mean.

I appreciate the help Gorg, and anyone else who has time to kill.

[This message has been edited by outRider (edited 02-07-2002).]

[This message has been edited by outRider (edited 02-07-2002).]

If anyone wants to see what I see http://www.geocities.com/y_mohamoud has the basic exe, texture, and camera source. If you run that and hit left the cam rotates left, so rotate 90 to the left, then hit up, you’ll see what I mean.

Could this be a case of gimbal lock? Anytime I see a angle at 90, that is the first thing that comes to mind.

Well, I’m not sure, but what I’m doing is for each transformation on the camera I apply the rotation to the u/v/n vectors and one per frame build the view matrix. It seems that not all the rotations are represented in that matrix. when changing the view matrix, do i create a new one for each transformation of the camera and concatrate with the old view matrix? or just build a view matrix after all the camera transformations are complete?