Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

LookAt function: I'm going crazy

I must do a homework and I try to implement a lookAt function. I tried in many ways but the only result I got is a blue screen. The rest of my program works greatly, infact if I use glm::lookAt all is good. This is my code:

mat4 Transform::lookAt(const vec3 &eye, const vec3 &center, const vec3 &up) 
{
    vec3 w(glm::normalize(eye - center)) ;
        vec3 u(glm::normalize(glm::cross(up, w)));
        vec3 v(glm::cross(w, u)) ;
    mat4 ret = mat4 (
        vec4 (u.x,v.x,w.x,0),
            vec4 (u.y,v.y,w.y,0),
            vec4 (u.z,v.z,w.z,0),
        vec4 (-u.x*eye.x-u.y*eye.y-u.z*eye.z,
             -v.x*eye.x-v.y*eye.y-v.z*eye.z,
             -w.x*eye.x-w.y*eye.y-w.z*eye.z,
             1)
    );
  return ret;
like image 636
Domenico Maiuri Avatar asked Nov 02 '13 09:11

Domenico Maiuri


People also ask

What does the LookAt function do?

The LookAt function in OpenGL creates a view matrix that transforms vertices from world space to camera space. It takes three vectors as arguments that together describe the position and orientation of a camera.

What is Cameraupvector?

The camera up vector specifies the direction that is oriented up in the scene. camup([up_vector]) sets the up vector in the current axes to the specified value. Specify the up vector as x, y, and z components.

What is a LookAt matrix?

The lookat matrix is a matrix that positions / rotates something to point to (look at) a point in space, from another point in space.


1 Answers

I saw you use the glm library for matrix operations, so from the glm code the lookat implementation looks like this:

mat4x4 lookAt(vec3  const & eye, vec3  const & center, vec3  const & up)
{
    vec3  f = normalize(center - eye);
    vec3  u = normalize(up);
    vec3  s = normalize(cross(f, u));
    u = cross(s, f);

    mat4x4 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);
    Result[3][1] =-dot(u, eye);
    Result[3][2] = dot(f, eye);
    return Result;
}

You first normalize the vectors you will use(f is the direction you look at, u the up and s is the right vector). Then to make sure the up vector is perpendicular to the direction and right vectors you recalculate it as their cross product, because when you give an up vector you can't make sure its perpendicular to the eye-center vector(view direction), they're just form a plane which gives you the right vector.

The matrix is constructed from these. For more detail how does it works check the http://www.songho.ca/opengl/gl_transform.html page. In short:this is a matrix which creates you a new coordinate system, so the coloumns are the axises. Then at the last coloumn the translation matrix is applied.

(Look at the identity matrix:

AXIS     TRANSFORM
x  y  z  transl.
1, 0, 0, 0
0, 1, 0, 0,
0, 0, 1, 0
0, 0, 0, 1

This gives you the standard coordinate system with no translation.)

Then you multiply this with projection and model matrixes (p*v*m), the order is important. When you write your implementation make sure you use coloumn major matrixes, because of opengl, or transpose them.

I hope it helps.

like image 187
David Szalai Avatar answered Oct 21 '22 02:10

David Szalai