# Moving camera matrix around own axis

This topic is 3989 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Hi, To rotate my camera matrix I use this piece of code:
inline void Rotate(float angle, float x, float y, float z) // x, y and z are rotations in radians
{
matrix4f rot;

vector3f rotvec(x, y, z);
rotvec.Normalize();

float c = cosf(angle);
float s = sinf(angle);
rot.m[0]  = rotvec.x * rotvec.x * (1 - c) + c;
rot.m[1]  = rotvec.y * rotvec.x * (1 - c) + rotvec.z * s;
rot.m[2]  = rotvec.x * rotvec.z * (1 - c) - rotvec.y * s;
rot.m[4]  = rotvec.x * rotvec.y * (1 - c) - rotvec.z * s;
rot.m[5]  = rotvec.y * rotvec.y * (1 - c) + c;
rot.m[6]  = rotvec.y * rotvec.z * (1 - c) + rotvec.x * s;
rot.m[8]  = rotvec.x * rotvec.z * (1 - c) + rotvec.y * s;
rot.m[9]  = rotvec.y * rotvec.z * (1 - c) - rotvec.x * s;
rot.m[10]  = rotvec.z * rotvec.z * (1 - c) + c;

Multiply(rot); // this = this * rot

}

Only, this does not do as I want to. When it rotates, it seems to rotate around the world origin (0, 0, 0) and not around the camera's own axis (which is translated from the origin). I want to have an FPS-like camera. The matrix I use is a 4*4 matrix, so it has the translation in it. What am I doing wrong?

##### Share on other sites
Your comment says that x, y, and z are 'rotations in radians', but your code says that they are the axis components of an axis-angle pair. Something is amiss :)

Can you show how you're using the function? Where do the values for x, y, and z come from?

Also, an axis can't really be 'translated from the origin', so there may be some other things that you're confused about as well.

##### Share on other sites
Oops, I commented it wrongly and I've made another mistake. I meant that the angle was in radians. x, y, z are the members of a vector that gives the direction on how to rotate with 'angle' degrees.

Furthermore, this is not the function I call. I call the very similar one:

inline void RotateWorld(float angle, float x, float y, float z) // angle is rotation in radians    {        matrix4f rot, rotfinal;		vector3f rotvec(x, y, z);		rotvec.Normalize(); // important, fixme: check if necessary        rotfinal.LoadIdentity();		rot.LoadIdentity();		float c = cosf(angle);		float s = sinf(angle);		rot.m[0]  = rotvec.x * rotvec.x * (1 - c) + c;		rot.m[1]  = rotvec.y * rotvec.x * (1 - c) + rotvec.z * s;		rot.m[2]  = rotvec.x * rotvec.z * (1 - c) - rotvec.y * s;		rot.m[4]  = rotvec.x * rotvec.y * (1 - c) - rotvec.z * s;		rot.m[5]  = rotvec.y * rotvec.y * (1 - c) + c;		rot.m[6]  = rotvec.y * rotvec.z * (1 - c) + rotvec.x * s;		rot.m[8]  = rotvec.x * rotvec.z * (1 - c) + rotvec.y * s;		rot.m[9]  = rotvec.y * rotvec.z * (1 - c) - rotvec.x * s;		rot.m[10]  = rotvec.z * rotvec.z * (1 - c) + c;		matrix4f mat;		mat.Copy(*this);        mat = rot * mat;		this->Copy(mat);    }

like this: SceneCamera.RotateWorld(MOVEANGLE, 0, 1, 0); // around y-axis

I had to use this function to use the world y-axis and not the camera y-axis.

But what happens is that now I seem to move around the world axis with my camera, so actually it is the same as the earth oribiting around the sun and not - what I want - the earth orbiting around its own axis but still using the world's (0, 1, 0) as rotation vector.

[Edited by - Revelation60 on January 4, 2008 5:36:54 AM]

##### Share on other sites
Quote:
 Original post by Revelation60Oops, I commented it wrongly and I've made another mistake. I meant that the angle was in radians. x, y, z are the members of a vector that gives the direction on how to rotate with 'angle' degrees.Furthermore, this is not the function I call. I call the very similar one:inline void RotateWorld(float angle, float x, float y, float z) // angle is rotation in radians { matrix4f rot, rotfinal; vector3f rotvec(x, y, z); rotvec.Normalize(); // important, fixme: check if necessary rotfinal.LoadIdentity(); rot.LoadIdentity(); float c = cosf(angle); float s = sinf(angle); rot.m[0] = rotvec.x * rotvec.x * (1 - c) + c; rot.m[1] = rotvec.y * rotvec.x * (1 - c) + rotvec.z * s; rot.m[2] = rotvec.x * rotvec.z * (1 - c) - rotvec.y * s; rot.m[4] = rotvec.x * rotvec.y * (1 - c) - rotvec.z * s; rot.m[5] = rotvec.y * rotvec.y * (1 - c) + c; rot.m[6] = rotvec.y * rotvec.z * (1 - c) + rotvec.x * s; rot.m[8] = rotvec.x * rotvec.z * (1 - c) + rotvec.y * s; rot.m[9] = rotvec.y * rotvec.z * (1 - c) - rotvec.x * s; rot.m[10] = rotvec.z * rotvec.z * (1 - c) + c; matrix4f mat; mat.Copy(*this); mat = rot * mat; this->Copy(mat); }like this: SceneCamera.RotateWorld(MOVEANGLE, 0, 1, 0); // around y-axisI had to use this function to use the world y-axis and not the camera y-axis.But what happens is that now I seem to move around the world axis with my camera, so actually it is the same as the earth oribiting around the sun and not - what I want - the earth orbiting around its own axis but still using the world's (0, 1, 0) as rotation vector.
It sounds like you might be applying the camera translation and rotation transforms in the wrong order.

Perhaps you could post the code where you actually assemble your camera matrix...

##### Share on other sites
Well, in my draw procedure I just call:

glMultMatrixf(SceneCamera.m);

The m is the actual array.

In the update function I take care of the input:

if (Engine.KeyDown['W'])		SceneCamera.Translate(0, 0, MOVESPEED);float MOUSEROTFACTOR = 0.04f;	float dx = Engine.MouseInfo.CurrentMouseX - Engine.MouseInfo.PreviousMouseX;	float dy = Engine.MouseInfo.CurrentMouseY - Engine.MouseInfo.PreviousMouseY;					SceneCamera.Rotate(dy * MOUSEROTFACTOR, 1, 0, 0);		SceneCamera.RotateWorld(dx * MOUSEROTFACTOR, 0, 1, 0);

the SceneCamera.Translate:

inline void Translate(float x, float y, float z)    {        matrix4f trans;	trans.LoadIdentity();        trans.m[12] = x;        trans.m[13] = y;        trans.m[14] = z;	Multiply(trans);    }

I hope this helps!

##### Share on other sites
Ok, I think I have fixed the orbit problem. The only question remaining is how to rotate the camera around the world's y axis instead of its own axis?

Changing the multiplication order Cam = Cam * Rot into Cam = Rot * Cam doesn't do the trick because then I start orbiting again.

##### Share on other sites
I guess it is: new_cam = cam * roty(angle)^-1 = cam * roty(angle)_t (transposed) = cam * roty(-angle)

in this way every point x will transform like u = new_cam * x = cam * (roty(-angle) * x) = cam * x'
x is rotated around y-world axis by (-angle)

##### Share on other sites
It still doesn't work :(

I've made a demo that shows my problem (source included). Glut needed.

##### Share on other sites
Hi,
I noticed a strange behaviour of the camera, it rotates wrong when the mouse is moved.
I noticed that inside the function processMousePassiveMotion, the matrix SceneCamera continues to accumulate rotation around x and y axis every time u move the mouse:

void processMousePassiveMotion(int x, int y) {

float MOUSEROTSPEED = 0.05;

int dx = x - prevposx;
int dy = y - prevposy;
SceneCamera.Rotate(-dy * MOUSEROTSPEED, 0, 0);
SceneCamera.Rotate(0, -dx * MOUSEROTSPEED, 0);

prevposx = x;
prevposy = y;
}

In this way, assuming to not translate your camera,
NewSceneCamera = SceneCamera * Rx1*Ry1*Rx2*Ry2*Rx3*Ry3 (whenever the mouse moves) while I guess it would be better to have
NewSceneCamera = SceneCamera * (Rx1*Rx2*Rx3..) * (Ry1*Ry2*Ry3...), it's the same as updating every time the angles of rotations (angle_x,angle_y) and multiplay your scene camera by Rx(angle_x) * Ry(angle_y)

I'm not sure if it was the original problem...

##### Share on other sites
I've tried your suggestion, but my camera still doesn't work properly :(

1. 1
2. 2
3. 3
Rutin
15
4. 4
khawk
14
5. 5
frob
12

• 9
• 11
• 11
• 23
• 12
• ### Forum Statistics

• Total Topics
633661
• Total Posts
3013220
×