I would appreciate any advice anyone could provide.
I have been using the following code with gluLookAt with wonderful success for a 6DOF camera:
Transformable::Transformable ( )
{ // Init W/ Standard OGL Values:
Position = Zero;
ViewDir = NegUnitZ;
Right = UnitX;
Up = UnitY;
ViewPoint = NegUnitZ;
ScaleX = 1.0f;
ScaleY = 1.0f;
ScaleZ = 1.0f;
}
void Transformable::Move ( Vector Direction )
{
Position = Position + Direction;
ViewPoint = Position + ViewDir;
}
void Transformable::MoveForward ( float Distance )
{
Position = Position + ViewDir * Distance;
ViewPoint = Position + ViewDir;
}
void Transformable::MoveRight ( float Distance ) // Strafe Right
{
Position = Position + Right * Distance;
ViewPoint = Position + ViewDir;
}
void Transformable::MoveUpward ( float Distance )
{
Position = Position + Up * Distance;
ViewPoint = Position + ViewDir;
}
void Transformable::RotateX ( float Angle )
{
ViewDir = ViewDir * cos( Deg2Rad(Angle) ) + // Rotate ViewDir Around The Right Vector:
Up * sin( Deg2Rad(Angle) );
ViewDir.Normalize ( );
Up = ViewDir.CrossProduct ( Right ) * -1; // Compute The New Up Vector
ViewPoint = Position + ViewDir;
}
void Transformable::RotateY ( float Angle )
{
ViewDir = ViewDir * cos( Deg2Rad(Angle) ) - // Rotate ViewDir Around The Up Vector:
Right * sin( Deg2Rad(Angle) );
ViewDir.Normalize ( );
Right = ViewDir.CrossProduct ( Up ); // Compute The New Right
ViewPoint = Position + ViewDir;
}
void Transformable::RotateZ ( float Angle )
{
Right = Right * cos ( Deg2Rad(Angle) ) + // Rotate ViewDir Around The Right Vector:
Up * sin ( Deg2Rad(Angle) );
Right.Normalize ( );
Up = ViewDir.CrossProduct ( Right ) * -1; // Compute The New Up
ViewPoint = Position + ViewDir;
}
To Render:
void OpenGL::Render ( Transformable &T )
{
gluLookAt( T.Position.X, // Since We Know The Up Vector, We Can Easily Use gluLookAt:
T.Position.Y,
T.Position.Z,
T.ViewPoint.X,
T.ViewPoint.Y,
T.ViewPoint.Z,
T.Up.X,
T.Up.Y,
T.Up.Z );
}
So just recently, I have been experimenting with using the exact same code to transform arbitrary meshes, with them inheriting Transformable, and rendering like so:
void OpenGLMesh::Render ( )
{
glPushMatrix();
MyTexture->Call ( );
...
gluLookAt( Position.X, // Since We Know The Up Vector, We Can Easily Use gluLookAt:
Position.Y,
Position.Z,
ViewPoint.X,
ViewPoint.Y,
ViewPoint.Z,
Up.X,
Up.Y,
Up.Z );
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glEnableClientState(GL_VERTEX_ARRAY);
glDrawArrays(GL_TRIANGLES, 0, T.size()*3); // VBO, YAY!!!
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glPopMatrix();
}
It seemed to work perfectly, until I noticed that instead of rotating about its Right vector for RotateX, like it does for my camera, it rotates only about the absolute X axis. It has the same symptom for the other two rotation types.
1. Why is only rotating about the X, Y, Z, directions, instead of about its own orthogonal basis?
2. Can I fix it to rotate about its own orthogonal bases?
3. Is this a disgusting abuse of gluLookAt? Is there a similar function that is less intended for camera viewpoints?
Thanks!
Greg