1
\$\begingroup\$

Given a quaternion

float x, y, z, w;

How does one the forward, up and right vector from a single quaternion?

vec3 up;
vec3 forward;
vec3 right;

quat_get_all_axis(&quat, &up, &forward, &right);

This seems useful to accomplish things like move forward/back, strafe and jump.

\$\endgroup\$
3
\$\begingroup\$

You can simply apply the quaternion to the (0,1,0) (0,0,-1) and (1,0,0) vectors for up forward and right resp.

\$\endgroup\$
  • \$\begingroup\$ Can you elaborate on "apply"? It's not as simple as multipling a vector right? \$\endgroup\$ – 010110110101 Feb 1 '15 at 0:51
  • \$\begingroup\$ Most quaternion libraries will allow you to rotate a vector by the rotation defined by the quaternion, that's what I meant by applying \$\endgroup\$ – ratchet freak Feb 1 '15 at 0:52
  • \$\begingroup\$ I had to use the inverse of the quaternion and camera controls worked...maybe similar to how lookAt matrices are inverted. \$\endgroup\$ – jackw11111 Aug 7 '19 at 9:04
1
\$\begingroup\$

What I believe @ratchet freak means when he says "apply" is to rotate each of the original front, right and up vectors around the orientation quaternion. I'll just leave this implementation based off this OpenGL FPS Camera Quaternion tutorial here for future reference. (I had to invert the quaternion to get working camera controls, others may not need to).

glm::mat4 Camera::GetViewMatrix()
{
    glm::quat qPitch = glm::angleAxis(glm::radians(-Pitch), glm::vec3(1,0,0));
    glm::quat qYaw = glm::angleAxis(glm::radians(Yaw), glm::vec3(0,1,0));
    // omit roll
    orientation = qPitch * qYaw;
    orientation = glm::normalize(orientation);
    glm::mat4 rotate = glm::mat4_cast(orientation);
    glm::mat4 translate = glm::mat4(1.0f);
    translate = glm::translate(translate, -Position);

    return rotate * translate;
}

void Camera::updateCameraVectors()
{
    Front = glm::rotate(glm::inverse(orientation), glm::vec3(0.0, 0.0, -1.0));
    Right = glm::rotate(glm::inverse(orientation), glm::vec3(1.0, 0.0, 0.0));
    Up = glm::vec3(0.0, 1.0, 0.0);
}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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