gluLookat replacement

Started by
7 comments, last by mixmaster 12 years, 3 months ago
Before I start, YES I have read lots of posts and code examples but I'm still stuck :-)

Here is my replacement code for gluLootat()


void lsMatrix4x4::LookAt( const lsVector3& eyePosition, const lsVector3& lookAt, const lsVector3& upVector )
{
lsMath math;
lsVector3 e, l, u;
lsVector3 forward, side, up;
lsMatrix4x4 matrix2, mat2;

e = eyePosition;
l = lookAt;
u = upVector;

// make sure up is normalized
up = upVector;
up.normalize();
// forward vector
forward = l - e;
forward.normalize();
// side vector
side = math.Cross( forward, up );
side.normalize();
// recalc up vector
up = math.Cross( forward, side );
up.normalize();


matrix2.matrix[0] = side.x;
matrix2.matrix[4] = side.y;
matrix2.matrix[8] = side.z;

matrix2.matrix[1] = up.x;
matrix2.matrix[5] = up.y;
matrix2.matrix[9] = up.z;

matrix2.matrix[2] = -forward.x;
matrix2.matrix[6] = -forward.y;
matrix2.matrix[10] = -forward.z;

mat2 *= matrix2;
mat2.TranslateMatrix( -e.x, -e.y, -e.z );

*this = mat2;
}


And here is the output from both OpenGL and my engine.


Camera Matrix : FPS_Camera
Matrix : OpenGL
-1 0 0 6.54721e-07
0 1 0 -1.76
0 0 -1 2.76058e-05
0 0 0 1
Matrix : vortxGE
-1 0 0 -6.54721e-07
0 -1 0 -1.76
0 0 -1 -2.76058e-05
0 0 0 1


I'm bashing my head against a wall, LOL.. It looks like a simple fix.

Any ideas anyone?

Cheers

Lee

Code is Life
C/C++, ObjC Programmer, 3D Artist, Media Production

Website : www.leestripp.com
Skype : lee.stripp@bigpond.com
Gmail : leestripp@gmail.com

Advertisement
And here's another example of a test app.


cout << endl;
cout << "*********************************************************" << endl;
cout << "** Matrix Test " << endl;
cout << "*********************************************************" << endl;

lsMatrix4x4 mat;
lsVector3 eye, look, up;
GLfloat glmat[16];
lsOpenGL *ogl = vortxge->getCdl()->getOpengl();

// Identity
// OpenGL
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
glGetFloatv( GL_MODELVIEW_MATRIX, glmat );
ogl->DisplayMatrix4( glmat, "OpenGL: Identity" );

// vortxGE Matrix
ogl->DisplayMatrix4( mat.matrix, "vortxGE: Identity" );


// LookAt
// OpenGL
glLoadIdentity();
gluLookAt( 0,0,-10.0, 0,0,0, 0,1,0 );
glGetFloatv( GL_MODELVIEW_MATRIX, glmat );
ogl->DisplayMatrix4( glmat, "OpenGL: LookAt" );

// vortxGE LookAt
mat.LoadIdentity();
eye = lsVector3( 0, 0, -10.0 );
look = lsVector3( 0, 0, 0 );
up = lsVector3( 0, 1, 0 );
mat.LookAt( eye, look, up );
ogl->DisplayMatrix4( mat.matrix, "vortxGE: LookAt" );



And the output. I took the old SGI code as an example for LookAt.. hmmmmmmm.


*********************************************************
** Matrix Test
*********************************************************
Matrix : OpenGL: Identity
1 0 0 0
0 1 0 0
0 0 1 0
0 0 0 1
Matrix : vortxGE: Identity
1 0 0 0
0 1 0 0
0 0 1 0
0 0 0 1
Matrix : OpenGL: LookAt
-1 0 0 0
0 1 0 0
0 0 -1 -10
0 0 0 1
Matrix : vortxGE: LookAt
-1 0 0 0
0 -1 0 0
0 0 -1 10
0 0 0 1

Cheers

Lee

Code is Life
C/C++, ObjC Programmer, 3D Artist, Media Production

Website : www.leestripp.com
Skype : lee.stripp@bigpond.com
Gmail : leestripp@gmail.com

Could this be because the old SGI code was Left-Handed and now OpenGL is Righ-Handed ???? Help :-)

Cheers

Lee

Code is Life
C/C++, ObjC Programmer, 3D Artist, Media Production

Website : www.leestripp.com
Skype : lee.stripp@bigpond.com
Gmail : leestripp@gmail.com

This is my LookAt function. I think I started from the Mesa implementation originally. My matrix class is row-major so that's why everything is transposed from you. I have to pass transpose=true to glUniformMatrix4fv because of this.


INLINE static void CreateLookAt(Vector3 const & position, Vector3 const & target, Vector3 const & upVector, Matrix & result)
{
Vector3 forward;
Vector3::Subtract(target, position, forward);
forward.Normalize();

Vector3 right;
Vector3::Cross(forward, upVector, right);
right.Normalize();

Vector3 up;
Vector3::Cross(right, forward, up);
up.Normalize();

result.elements[0] = right.X;
result.elements[1] = right.Y;
result.elements[2] = right.Z;

result.elements[4] = up.X;
result.elements[5] = up.Y;
result.elements[6] = up.Z;

result.elements[8] = -forward.X;
result.elements[9] = -forward.Y;
result.elements[10] = -forward.Z;

result.elements[12] = 0.0f;
result.elements[13] = 0.0f;
result.elements[14] = 0.0f;

result.elements[3] = -Vector3::Dot(right,position);
result.elements[7] = -Vector3::Dot(up,position);
result.elements[11] = Vector3::Dot(forward,position);
result.elements[15] = 1.0f;
}

This is my LookAt function. I think I started from the Mesa implementation originally. My matrix class is row-major so that's why everything is transposed from you. I have to pass transpose=true to glUniformMatrix4fv because of this.


INLINE static void CreateLookAt(Vector3 const & position, Vector3 const & target, Vector3 const & upVector, Matrix & result)
{
Vector3 forward;
Vector3::Subtract(target, position, forward);
forward.Normalize();

Vector3 right;
Vector3::Cross(forward, upVector, right);
right.Normalize();

Vector3 up;
Vector3::Cross(right, forward, up);
up.Normalize();

result.elements[0] = right.X;
result.elements[1] = right.Y;
result.elements[2] = right.Z;

result.elements[4] = up.X;
result.elements[5] = up.Y;
result.elements[6] = up.Z;

result.elements[8] = -forward.X;
result.elements[9] = -forward.Y;
result.elements[10] = -forward.Z;

result.elements[12] = 0.0f;
result.elements[13] = 0.0f;
result.elements[14] = 0.0f;

result.elements[3] = -Vector3::Dot(right,position);
result.elements[7] = -Vector3::Dot(up,position);
result.elements[11] = Vector3::Dot(forward,position);
result.elements[15] = 1.0f;
}


Thanks doesnotcompute

It might be easier using dot products then MultMatrix, thank you so much for your reply. I'll give it a try soon.

Cheers

Lee

Code is Life
C/C++, ObjC Programmer, 3D Artist, Media Production

Website : www.leestripp.com
Skype : lee.stripp@bigpond.com
Gmail : leestripp@gmail.com



// recalc up vector
up = math.Cross( forward, side );



It looks like you've reversed this cross product. forward x side will get you the down vector using the right-hand rule. Try doing side x forward and see if that fixes the issue.
WOW !! I did so many things wrong with this it would be hard to explain how I fixed everything..

In short I had matrix calcs doubling up and rotation matrix mixed into my translation matrix. I must of had a brain fade during my rewrite.

All fixed now, thanks for your responces :-) P.S. ignore the code above its wring in so many ways. LOL.

Cheers

Lee

Code is Life
C/C++, ObjC Programmer, 3D Artist, Media Production

Website : www.leestripp.com
Skype : lee.stripp@bigpond.com
Gmail : leestripp@gmail.com


[quote name='Lee Stripp' timestamp='1325219444' post='4898045']

// recalc up vector
up = math.Cross( forward, side );



It looks like you've reversed this cross product. forward x side will get you the down vector using the right-hand rule. Try doing side x forward and see if that fixes the issue.
[/quote]

Yep, I was at that point where I was trying anything. Code got messy, I didn't need to recalc the Up vector :-)

Cheers

Lee

Code is Life
C/C++, ObjC Programmer, 3D Artist, Media Production

Website : www.leestripp.com
Skype : lee.stripp@bigpond.com
Gmail : leestripp@gmail.com

Update for anyone interested.

Here's my working code

void lsMatrix4x4::LookAt( const lsVector3& eyePosition, const lsVector3& lookAt, const lsVector3& upVector )
{
lsMath math;
lsVector3 e, l, u;
lsVector3 forward, side, up;
lsMatrix4x4 rotmat, transmat;

e = eyePosition;
l = lookAt;
u = upVector;

// make sure up is normalized
up = upVector;
up.normalize();
up.debug( "up: " );
// forward vector
forward = l - e;
forward.normalize();
forward.debug( "forward: " );
// side vector
side = math.Cross( forward, up );
side.normalize();
side.debug( "side: " );

rotmat.matrix[0] = side.x;
rotmat.matrix[4] = side.y;
rotmat.matrix[8] = side.z;

rotmat.matrix[1] = up.x;
rotmat.matrix[5] = up.y;
rotmat.matrix[9] = up.z;

rotmat.matrix[2] = -forward.x;
rotmat.matrix[6] = -forward.y;
rotmat.matrix[10] = -forward.z;

transmat.TranslateMatrix( -e.x, -e.y, -e.z );

*this *= transmat * rotmat;
}


And the output it produces

Matrix : lsNode: Camera
[ 1 ] [ 0 ] [ 0 ] [ 0 ]
[ 0 ] [ 1 ] [ 0 ] [ 0 ]
[ 0 ] [ 0 ] [ 1 ] [ -10 ]
[ 0 ] [ 0 ] [ 0 ] [ 1 ]
up: Vector(0,1,0)
forward: Vector(0,0,1)
side: Vector(-1,0,0)
Matrix : Camera ViewMatrix:
[ -1 ] [ 0 ] [ 0 ] [ 0 ]
[ 0 ] [ 1 ] [ 0 ] [ 0 ]
[ 0 ] [ 0 ] [ -1 ] [ 10 ]
[ 0 ] [ 0 ] [ 0 ] [ 1 ]


I hope this will help someone avoid the pain I went through :-)

Cheers

Lee

Code is Life
C/C++, ObjC Programmer, 3D Artist, Media Production

Website : www.leestripp.com
Skype : lee.stripp@bigpond.com
Gmail : leestripp@gmail.com

This topic is closed to new replies.

Advertisement