9
$\begingroup$

I've been going over some OpenGL learning resources and one of them is this article: Modern OpenGL 04 - Cameras, Vectors & Input in which the author presents an approach to building a Camera class that can be used to derive the view and projection matrices.

In the accompanying source code there is a function that returns the orientation of the camera as a transform matrix (permalink to source code) which is implemented like this:

glm::mat4 Camera::orientation() const {
    glm::mat4 orientation;
    orientation = glm::rotate(orientation, glm::radians(_verticalAngle), glm::vec3(1,0,0));
    orientation = glm::rotate(orientation, glm::radians(_horizontalAngle), glm::vec3(0,1,0));
    return orientation;
}

If I'd like to translate the camera relative to the direction it is facing then I would assume that I could multiply the orientation matrix by the translation vector to get a new vector that does the translation in the direction the camera is facing.

However, this does not yield the result I was expecting. After looking at how the forward, up and right axis are derived (permalink to source code):

glm::vec3 Camera::forward() const {
    glm::vec4 forward = glm::inverse(orientation()) * glm::vec4(0,0,-1,1);
    return glm::vec3(forward);
}

glm::vec3 Camera::right() const {
    glm::vec4 right = glm::inverse(orientation()) * glm::vec4(1,0,0,1);
    return glm::vec3(right);
}

glm::vec3 Camera::up() const {
    glm::vec4 up = glm::inverse(orientation()) * glm::vec4(0,1,0,1);
    return glm::vec3(up);
}

I can see that I need to multiply the translation vector with the inverse of the orientation matrix to get the expected result but I don't understand why. Isn't the orientation (as used in this article) a rotation matrix? If that's the case then why do I need to inverse it?

$\endgroup$
1
  • 2
    $\begingroup$ I guess the author actually computes inverse orientation in orientation because he calls this orientation in Camera::view and then Camera::matrix without transpose or inversion of it. And because glfwGetCursorPos will give you flipped Y coordinates, the orientation does compute the inverse of orientation coincidentally. However X coordinates are not flipped, which should cause problem but I cannot explain why it does not. $\endgroup$ Commented Sep 5, 2017 at 17:02

2 Answers 2

8
$\begingroup$

People always forget that there is no "camera" in OpenGL. In order to simulate a camera you have to move the whole world inversely. So if you want ur camera looking 30 degrees downward, you move the whole world 30 degrees upwards. If you want your camera moved to the left, you move the whole world right. That's why you will notice the "-" sign in the translation vector where he used the variable position.

Hence the reason there is no separate "view" matrix in openGL, it's modelview matrix combined. That's the reason for taking the inverse. Since a view matrix represent's the camera's forward, up and side, you have to take the inverse since the orientation is defined for the world not the camera.

$\endgroup$
1
  • 2
    $\begingroup$ The code make a lot of sense now that I've read your answer. I had a hunch that this is it but couldn't quite figure it out. Thank you! While looking into the issue I have also stumbled across this article that explains in greater detail what you wrote: 3dgep.com/understanding-the-view-matrix. Maybe someone else will find it useful as well. $\endgroup$ Commented Sep 6, 2017 at 16:02
0
$\begingroup$

First of all, you talk about inverse orientation of points in matrix, this is needed because the subtraction logic in world transformations are directly relationed with screen rotation, instead it that the camera moviments (translation you mentioned) no are directly relationed of the screen position around center of projection.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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