Search code examples
javaopenglmatrixlwjgl

LWJGL Matrix lookAt method


I need help with calculating the lookAt method Here is my method

    public void lookAt(Vector3f position, Vector3f direction, Vector3f up) {
    Vector3f f = new Vector3f();
    Vector3f u = new Vector3f();
    Vector3f s = new Vector3f();
    Vector3f.sub(direction, position, f);
    f.normalise(f);
    up.normalise(u);
    Vector3f.cross(f, u, s);
    s.normalise(s);
    Vector3f.cross(s, f, u);

    this.setIdentity();
    this.m00 = s.x;
    this.m10 = s.y;
    this.m20 = s.z;
    this.m01 = u.x;
    this.m11 = u.y;
    this.m21 = u.z;
    this.m02 = -f.x;
    this.m12 = -f.y;
    this.m22 = -f.z;
    this.m30 = -Vector3f.dot(s, position);
    this.m31 = -Vector3f.dot(u, position);
    this.m32 = Vector3f.dot(f, position);
}

but when I test it like this camera.lookAt(position, new Vector3f(1, 0 ,0), new Vector3f(0, -1, 0)); my camera is looking down, end if only i do this camera.lookAt(position, new Vector3f(10000, 0 ,0), new Vector3f(0, -1, 0));, camera is looking forward. Can you help please ?

P.S. sorry for my english


Solution

  • The second parameter of a lookAt function is usually not the direction in which you want to look but the point which you want to look at. As far as I can see, the calculation of your method also expects a second point and not a direction (which is calculated from the two point and stored in f).

    In conclusion, the results you get look correct to me, except that you passed the wrong parameters to the function.

    How to create a function that creates a matrix from a point and a direction

    The rotation required is one that maps the minus z-direction onto the view vector. Additionally, we want the x-vector to be mapped such that it is perpendicular to the plane spanned by view and up vector. This can relatively easy be achieved by writing -view in the third row of the 3x3 matrix. The other two vectors can then be computed as the cross products of view and up vector which results in a right-vector onto which the x-axis should be mapped. The last vector (the target mapping for the y-axis) is then computed by the cross product of view and right vector. The cross products for the last vector is used, since we know that all rotation matrices have base vectors that are perpendicular:

    viewv = normalize(-view)
    rightv = normalize(cross(view, up))
    upv = normalize(cross(view, up))
    
                          -- rightv --
    rotation_matrix = [   --   upv  -- ]
                          --  viewv --
    

    When the camera is located in the origin, then we are done now. But since this is in general not the case, we have to add a translation part that transforms the scene such that the camera is the origin. Thus t = -camera.

    The final matrix is now composed by first translating the space and then rotating it according to our calculated matrix:

    lookat_matrix = rotation_matrix * translate(-camera)
    

    Since it is fairly late here and depending on the notation you use it might be that the rotation matrix has to be transposed and that some signs have to be adjusted.