C++ – Converting glm::lookat matrix to quaternion and back

cglm-mathopenglquaternions

I am using glm to create a camera class, and I am running into some problems with a lookat function. I am using a quaternion to represent rotation, but I want to use glm's prewritten lookat function to avoid duplicating code. This is my lookat function right now:

void Camera::LookAt(float x, float y, float z) {
    glm::mat4 lookMat = glm::lookAt(position, glm::vec3(x, y, z), glm::vec3(0, 1, 0));
    rotation = glm::toQuat(lookMat);
}

However when I call LookAt(0.0f,0.0f,0.0f), my camera is not rotated to that point. When I call glm::eulerangles(rotation) after the lookat call, I get a vec3 with the following values: (180.0f, 0.0f, 180.0f). position is (0.0f,0.0f,-10.0f), so I should not have any rotation at all to look at 0,0,0. This is the function which builds the view matrix:

glm::mat4 Camera::GetView() {
    view = glm::toMat4(rotation) * glm::translate(glm::mat4(), position);
    return view;
}

Why am I not getting the correct quaternion, and how can I fix my code?

Best Answer

Solution:

You have to invert the rotation of the quaternion by conjugating it:

using namespace glm;

quat orientation = conjugate(toQuat(lookAt(vecA, vecB, up)));


Explanation:

The lookAt function is a replacement for gluLookAt, which is used to construct a view matrix.

The view matrix is used to rotate the world around the viewer, and is therefore the inverse of the cameras transform.

By taking the inverse of the inverse, you can get the actual transform.

Related Topic