Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I am trying to write code with rotates an object.

I implemented it as:

Rotation about X-axis is given by the amount of change in y coordinates of a mouse and Rotation about Y-axis is given by the amount of change in x coordinates of a mouse.

This method is simple and work fine until on the the axis coincides with Z-axis, in short a gimble lock occurs.

How can I utilize the rotation arount Z-axis to avoid gimbal lock.

share|improve this question
    
Short answer: use quaternions –  Robert Rouhani Mar 20 '13 at 17:16
2  
Quaternions are still prone to gimbal lock if you use them wrong - it's not what you use to represent your rotations, it's concatenating multiple rotations that causes it. So don't concatenate rotations. –  Jimmy Shelter Mar 20 '13 at 17:27
    
Regarding my previous comment, see the comment from Maik Semder at gamedev.stackexchange.com/questions/23540/… –  Jimmy Shelter Mar 20 '13 at 17:39
    
I was about to write the same comment again, thanks for finding it @mh01 :) –  Maik Semder Mar 20 '13 at 17:53
add comment

2 Answers

up vote 6 down vote accepted

The simple solution is not to store the orientation of the object as angles around axes (X-, Y-, Z-axis), as for instance in euler angles.

Store the orientation of the object as a matrix or a quaternion.

This can cause gimbal lock, using euler angles:

class Object
{
    float m_angleAxisX;
    float m_angleAxisY;
    float m_angleAxisZ;
};

No gimbal lock:

class Object
{
    matrix m_orientation;   
};

No gimbal lock either:

class Object
{
    quaternion m_orientation;   
};

Now whenever the mouse is changed, multiply m_orientation with the orientation change coming from the mouse movement each frame.

share|improve this answer
add comment

This book (real-time rendering) helped me alot! See on page 66 and 70. It has very good graphics and explenation. Quaternions are on page 72 aswell! :)

Rotation about an Arbitrary Axis

This renders the camera with the rotation done by mouse input:

void Camera::getVectors(D3DXVECTOR3& up, D3DXVECTOR3& lookAt)
{
    float yaw, pitch, roll;
    D3DXMATRIX rotationMatrix;

    // Setup the vector that points upwards.
    up.x = 0.0f;
    up.y = 1.0f;
    up.z = 0.0f;

    // Setup where the camera is looking by default.
    lookAt.x = 0.0f;
    lookAt.y = 0.0f;
    lookAt.z = 1.0f;

    // Set the yaw (Y axis), pitch (X axis), and roll (Z axis) rotations in radians.
    pitch = m_rotation.x * 0.0174532925f;
    yaw   = m_rotation.y * 0.0174532925f;
    roll  = m_rotation.z * 0.0174532925f;

    // Create the rotation matrix from the yaw, pitch, and roll values.
    D3DXMatrixRotationYawPitchRoll(&rotationMatrix, yaw, pitch, roll);

    // Transform the lookAt and up vector by the rotation matrix so the view is correctly rotated at the origin.
    D3DXVec3TransformCoord(&lookAt, &lookAt, &rotationMatrix);
    D3DXVec3TransformCoord(&up, &up, &rotationMatrix);
}

// The Render function uses the position and rotation of the camera to build and update the view matrix
void Camera::render()
{
    D3DXVECTOR3 up, position, lookAt;

    // Setup the position of the camera in the world.
    position = (D3DXVECTOR3)m_position;

    getVectors(up, lookAt);

    // Translate the rotated camera position to the location of the viewer.
    lookAt = position + lookAt;

    // Finally create the view matrix from the three updated vectors.
    D3DXMatrixLookAtLH(&m_viewMatrix, &position, &lookAt, &up);

    return;
}

With the mouse input you modify yaw(head), pitch and roll.

share|improve this answer
    
-1 This does not solve the gimbal lock as it uses euler angles (m_rotation) for the internal orientation storage. This wiki explains why. –  Maik Semder Mar 20 '13 at 20:29
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.