3
\$\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\$

2 Answers 2

4
\$\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\$
3
  • \$\begingroup\$ Can you elaborate on "apply"? It's not as simple as multipling a vector right? \$\endgroup\$
    – 101010
    Commented Feb 1, 2015 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\$ Commented Feb 1, 2015 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
    Commented Aug 7, 2019 at 9:04
2
\$\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\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .