Results 1 to 8 of 8

Thread: OpenGL: Look at matrix

  1. #1

    OpenGL: Look at matrix

    Still working on my game engine and I have yet another stupid math problem.

    Here's what I want to do: I have a space station which has several turrets and I want these turrets to rotate to face the player. How can I do this?

    Here's some code that I've tried to use, but it doesn't work properly, I have no idea where this code came from, it's probably cut & paste with some trial and error from several different sources... :roll:

    [pascal]
    function MatrixLookAt(const v1: TVector3f; const v2: TVector3f; const Up: TVector3f): TGLMatrix4f;
    var
    xAxis, yAxis, zAxis: TVector3f;
    begin
    zAxis := VectorSubtract(v1, v2);
    VectorNormalize(zAxis);

    xAxis := VectorCross(Up, zAxis);
    VectorNormalize(xAxis);

    yAxis := VectorCross(zAxis, xAxis);
    VectorNormalize(yAxis);
    VectorNormalize(xAxis);

    Result := _GLMatrix4f;

    Result[0][0] := xAxis.x;
    Result[1][0] := xAxis.y;
    Result[2][0] := xAxis.z;
    Result[3][0] := -VectorDot(xAxis, v1);

    Result[0][1] := yAxis.x;
    Result[1][1] := yAxis.y;
    Result[2][1] := yAxis.z;
    Result[3][1] := -VectorDot(yAxis, v1);

    Result[0][2] := zAxis.x;
    Result[1][2] := zAxis.y;
    Result[2][2] := zAxis.z;
    Result[3][2] := -VectorDot(zAxis, v1);
    end;
    [/pascal]

    So, I put the location of the turret to the first parameter and the location of the player's ship to the second parameter, but what should I put on the third parameter? I've tried 0,1,0 and it seem to work on some cases (sort of), but usually I just get -NAN values in my matrices...

    Should I check for example if the two vectors are 0,0,0 and 0,2,0, in this case the Up vector obviously can't be 0,1,0...

    Is there a way to easily calculate the correct Up vector? Or is my cut & paste LookAt routine just completely wrong?
    If you develop an idiot proof system, the nature develops better idiots.

  2. #2

    OpenGL: Look at matrix

    My matrix lib uses this code:
    [pascal]
    function lookat(cameraPosition, cameraTarget, up: tvector4f): tmatrix4x4;
    var zaxis, xaxis, yaxis: tvector4f;
    begin
    zaxis := normalize(sub(cameraTarget, cameraPosition));
    xaxis := normalize(cross(up, zaxis));
    yaxis := cross(zaxis, xaxis);

    lookat := matrix4x4(xaxis.x, yaxis.x, zaxis.x, 0,
    xaxis.y, yaxis.y, zaxis.y, 0,
    xaxis.z, yaxis.z, zaxis.z, 0,
    -dot(xaxis, cameraPosition), -dot(yaxis, cameraPosition), -dot(zaxis, cameraPosition), 1);

    end;
    [/pascal]

    Edit: In your example your up vector should be 0,1,0. The up vector is just indicating what direction the top of the camera should be pointing.

    You would normally just use 0,1,0 unless you want your camera rotated about the local z axis(if you use a opengl like matrix order)

    Edit2: I see now that the code is formulated exactly the same way... Could it be your vector functions acting wrong?
    Peregrinus, expectavi pedes meos in cymbalis
    Nullus norvegicorum sole urinat

  3. #3

    OpenGL: Look at matrix

    I got it working, as long as the direction is not 0,(-)1,0, this case screwes up the matrix and it gets filled with -NAN values.

    Here's what happens:

    [pascal]
    v1 := _Vector3f(0, 0, 0);
    v2 := _Vector3f(0, 10, 0);
    Up := _Vector3f(0, 1, 0);

    zAxis := VectorSubtract(v1, v2);
    VectorNormalize(zAxis);
    // zAxis = 0, -1, 0
    // Up = 0, 1, 0

    xAxis := VectorCross(Up, zAxis);
    // xAxis = 0, 0, -0
    VectorNormalize(xAxis);
    // xAxis = -NAN, -NAN, -NAN
    [/pascal]

    Because the result of VectorCross(Up, zAxis) is 0,0,-0 and I try to normalize it I get -NAN,-NAN,-NAN as the end result for xAxis.

    How to prevent this?
    If you develop an idiot proof system, the nature develops better idiots.

  4. #4

    OpenGL: Look at matrix

    Could you put a simple check on it? e.g.

    Code:
    If xAxis[2] = -0 Then xAxis[2] := 0;
    M109uk
    <br />--------------------------------------------------------
    <br />www.pulse-soft.oneuk.com

  5. #5

    OpenGL: Look at matrix

    Unfortunately it's not that simple, that way I get values like 0,0,0 for xAxis and it's not any different from 0,0,-0.

    Maybe I need to check for the direction vector (zAxis) and change the Up vector accordingly...
    If you develop an idiot proof system, the nature develops better idiots.

  6. #6

    OpenGL: Look at matrix

    Your vector normalization needs to check if the length of the vectors is zero. If it is it must return 0,0,0 instead of NaN.

    NaN will bugger up all the following equations
    Peregrinus, expectavi pedes meos in cymbalis
    Nullus norvegicorum sole urinat

  7. #7

    OpenGL: Look at matrix

    I fixed that, but it still doesn't work if the position and target are along y-axis...
    If you develop an idiot proof system, the nature develops better idiots.

  8. #8

    OpenGL: Look at matrix

    In that case i would implement a check to see if the length of xAxis is either zero or very close to zero after crossing zAxis and up.

    If it is too close to zero you could just set it to a default of 1,0,0.
    Peregrinus, expectavi pedes meos in cymbalis
    Nullus norvegicorum sole urinat

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •