# How to get rid of camera z-axis rotation

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

## Recommended Posts

Hello.

I have an issue with my quternion based camera: when I move it only on X and Y axis fast it is also begin rotate around Z axis, but it shouldnt.

I use sharpDX lib and my code is following:

public void RotateX(float _degree_angle)
{
if (cameraType == CamType.ThirdPerson)
{
_degree_angle = -_degree_angle;
}

UpdateViewMatrix();
}

public void RotateY(float _degree_angle)
{
if (cameraType == CamType.ThirdPerson)
{
_degree_angle = -_degree_angle;
}

UpdateViewMatrix();
}


private void UpdateViewMatrix()
{
qRotation = Quaternion.Normalize(qRotation);

if (CameraType == CamType.ThirdPerson)
{
ViewMatrix = Matrix.Translation(Vector3.Negate(position)) * Matrix.RotationQuaternion(qRotation);

position -= new Vector3(ViewMatrix.M13, ViewMatrix.M23, ViewMatrix.M33) * radius;

ViewMatrix = Matrix.LookAtLH(position, lookAt, new Vector3(ViewMatrix.M12, ViewMatrix.M22, ViewMatrix.M32));
}
else
{
ViewMatrix = Matrix.Translation(Vector3.Negate(position)) * Matrix.RotationQuaternion(qRotation);
}
}


I tried to change order of multiplying for x and y quaternion rotations like this:

qRotation = Quaternion.Multiply(Quaternion.RotationAxis(Vector3.UnitY, MathUtil.DegreesToRadians(_degree_angle)), qRotation);

qRotation = Quaternion.Multiply(qRotation, Quaternion.RotationAxis(Vector3.UnitX, MathUtil.DegreesToRadians(_degree_angle2))); 

This helps - after that camera no longer rotate on Z-axis during fast moving on x-y axis, but if I move it on diagonal, if begins to rotate around all 3 axis, describing virtual 8 digit.

Could someone please point me the right way working with quaternions to stop camera rotation around Z-axis when I dont need this?

This issue is driving me crazy.

##### Share on other sites

I use front, side and up vector for my camera. after each update, I will set the y component of the side vector zero, so that no rotation around z axis is possible. After that, I will normalize the vector and recompute the front and up vector.

##### Share on other sites

Could you please give the code responcible for recomputing the front and up vectors?

Or (better) the whole view matrix update.

##### Share on other sites

D3DXVECTOR3 eye; //camera position

D3DXVECTOR3 at; //where you look at

D3DXVECTOR3 up(0,1,0); //assume the up vector is always pointing up, could have problem when you look straight up

D3DXVECTOR3 front = Normalize(at - eye);

D3DXVECTOR3 side = cross(front,up); //if you look through front vector, side vector will be on your right

use D3DXMatrixLookAtLH(....) or XMMatrixLookAtLH(...) to update the view matrix

##### Share on other sites

Thanks, but side and front is not using in XMMatrixLookAtLH(...) or D3DXMatrixLookAtLH(...). Where and when I need to apply them?

Edited by BlackJoker

##### Share on other sites

D3DXVECTOR3 eye; //camera position

D3DXVECTOR3 at; //where you look at

D3DXVECTOR3 up(0,1,0); //assume the up vector is always pointing up, could have problem when you look straight up

D3DXVECTOR3 front = Normalize(at - eye);

D3DXVECTOR3 side = cross(front,up); //if you look through front vector, side vector will be on your right

use D3DXMatrixLookAtLH(....) or XMMatrixLookAtLH(...) to update the view matrix

Doesn't D3DXMatrixLookAtLH(....) or XMMatrixLookAtLH(...) take as income parameters the mentioned 'eye', 'at' and 'up' and construct 'front' and 'side' automatically?

##### Share on other sites
If you rotate around the X axis, then rotate around the Y axis, then undo the rotation around the X axis, and finally undo the rotation around the Y axis, the resulting transformation is a rotation around the Z axis. This is a feature of rotations in 3D space, and you will observe it regardless of whether you use quaternions or anything else to represent them.

Perhaps instead of rotating around the X and Y axes, you meant to control pitch and yaw. If that's the case, use those angles to build the rotation from scratch every time.

##### Share on other sites

D3DXVECTOR3 eye; //camera position

D3DXVECTOR3 at; //where you look at

D3DXVECTOR3 up(0,1,0); //assume the up vector is always pointing up, could have problem when you look straight up

D3DXVECTOR3 front = Normalize(at - eye);

D3DXVECTOR3 side = cross(front,up); //if you look through front vector, side vector will be on your right

use D3DXMatrixLookAtLH(....) or XMMatrixLookAtLH(...) to update the view matrix

Doesn't D3DXMatrixLookAtLH(....) or XMMatrixLookAtLH(...) take as income parameters the mentioned 'eye', 'at' and 'up' and construct 'front' and 'side' automatically?

After 'side = cross(front,up)', set 'side.y = 1', then normalize it, then recompute the up vector.

At this time, 'eye' and 'at' haven't changed, but 'up' has changed.

If you have rotation angle, álvaro's method would be simpler.

##### Share on other sites

If you rotate around the X axis, then rotate around the Y axis, then undo the rotation around the X axis, and finally undo the rotation around the Y axis, the resulting transformation is a rotation around the Z axis. This is a feature of rotations in 3D space, and you will observe it regardless of whether you use quaternions or anything else to represent them.

Perhaps instead of rotating around the X and Y axes, you meant to control pitch and yaw. If that's the case, use those angles to build the rotation from scratch every time.

We already tried to accum degrees, but as a result, camera moving not on orbit, but on trajectory 8  (rotating in all 3 axis at the same time).

Edited by BlackJoker

##### Share on other sites

If you're trying to do a 3rd person camera, I'll echo Álvaro and suggest you just keep track of camera yaw and position then construct the transform each frame.

Pseudo code:

class Camera
{
float m_yaw; // Should be a value between 0 and 2 PI
float m_pitch; // Value between -PI/2 and PI/2
Vector3 m_position;
Matrix  m_cameraMatrix;

void Update()
{
Vector2 deltaMousePos; // Assume this is a 2D vector that has the delta X/Y of our mouse cursor since the last frame.

m_yaw += deltaMousePos.x;
m_pitch += deltaMousePos.y;

// Construct our rotation based on our current yaw/pitch
Quaternion yRotation(Vector3::UnitY, m_yaw);
Quaternion xRotation(Vector3::UnitX, m_pitch);

m_cameraMatrix = Matrix::Identity;
m_cameraMatrix *= (xRotation * yRotation);
m_cameraMatrix.translation = m_position; // Restore our position.
}

}


1. 1
2. 2
Rutin
24
3. 3
JoeJ
19
4. 4
5. 5

• 17
• 40
• 23
• 13
• 13
• ### Forum Statistics

• Total Topics
631729
• Total Posts
3001918
×