juztcode
juztcode

Reputation: 1355

understanding camera translation in GLM- openGL

The GLM maths library for openGL gives this implementation for the construction of lookAt matrix.

template<typename T, qualifier Q>
    GLM_FUNC_QUALIFIER mat<4, 4, T, Q> lookAtLH(vec<3, T, Q> const& eye, vec<3, T, Q> const& center, vec<3, T, Q> const& up)
    {
        vec<3, T, Q> const f(normalize(center - eye));
        vec<3, T, Q> const s(normalize(cross(up, f)));
        vec<3, T, Q> const u(cross(f, s));

        mat<4, 4, T, Q> Result(1);
        Result[0][0] = s.x;
        Result[1][0] = s.y;
        Result[2][0] = s.z;
        Result[0][1] = u.x;
        Result[1][1] = u.y;
        Result[2][1] = u.z;
        Result[0][2] = f.x;
        Result[1][2] = f.y;
        Result[2][2] = f.z;
        Result[3][0] = -dot(s, eye);  //#this
        Result[3][1] = -dot(u, eye);  //#this
        Result[3][2] = -dot(f, eye);  //#this
        return Result;
    }

Everything is fine and okay except for the translation factors that is done in the last three lines I've marked with //#this. The translation had to be done for the camera's world position x, y and z but instead it's done for the dot product of the camera's local coordinate and the direction vector, which can't possibly be equal.

Consider one case where the vector 2*eye(eye being the camera's position) is passed as the vector center(center being the target position) then the camera's local z-axis would coincide with the direction vector giving us the translation factor for the camera as [0,0,1], so we'd basically be moving along the world along only the z-axis(since we don't move the camera we'd be moving the world along just z axis in the negative direction) which is something we wouldn't want. Where am I missing the point or why is this being done for the translation?

Upvotes: 3

Views: 1037

Answers (2)

Rabbid76
Rabbid76

Reputation: 211230

glm::lookAt defines the view matrix. The view matrix transforms vertex coordinates from world space to view space.
eye, center and up are positions respectively vectors in world space, which define the the position and orientation of the camera in world space. eye, center and up define the view space. If you would setup a matrix by this vectors, then the matrix would transform from view space to world space.
Since the view matrix has to do the opposite (world space -> view space), the view matrix is the inverse matrix of that matrix which is defined by eye, center and up. glm::lookAt is a optimized algorithm for computing an inverse matrix in this spacial case.
Note s, u, f are transposed when they are assigned to the matrix.

The translation of the inverse matrix is not the negative translation of the matrix. The translation of the inverse matrix has to consider the orientation (rotation). Because of that the translation vector has to be rotated. The rotation of a (3d) vector by a 3x3 Rotation matrix can be computed by (is the same as) the 3 Dot products of the axis vectors and the direction vector. (s, u, f) define a 3x3 rotation matrix and eye is transformed by this matrix.

What the code actually dose is to concatenate a rotation by transposed (s, u, f) and a translation by -eye (very simplified pseudo code):

viewmatrix = transpose(rotation(s, u, f)) * translation(-eye)

Upvotes: 4

koko
koko

Reputation: 198

The dot product of one vector, a, with another normalized vector, n, can be thought of as the projection of a onto n. So, all that's happening here is that the eye vector is being projected onto f, s, and u, which are the basis vectors of the rotated coordinate frame. With these projections, we can learn the x, y, and z coordinates of eye in the f-s-u coordinate frame.

Upvotes: 1

Related Questions