This relates to the cross product. There is a way to determine the direction of the cross product of two vectors, using the "right hand rule" - in short, to determine the direction of (A cross B), you orient your right hand such that you can sweep your fingers from A to B. Your thumb will point in the direction of the cross product. Google "cross product - right hand rule" for better pictures and explanations. But you could redefine the cross product by using your left hand - this will just reverse the direction of the resulting vector.
A gem of knowledge there. I knew that the order of the cross product is important (AxB = right | BxA = -right), but I didn't make a connection to right-handedness for lack of a better term. It does make sense to me. If this is the case, if I wanted to generate a left-handed forward vector, I'd use Up X Right, correct?
Hope that makes sense. But in short, the z vector is reversed.
That said, if I try to find the local right vector with a positive z vector, then it's a left-handed system, correct? Here's my example for a lookAt model matrix:
Vector3 lookAt; // assume this was setup ahead of time as a normalized "lookAt vector"
Vector3 forward(0.0f, 0.0f, 1.0f);
Vector3 right = Vector3::Cross(forward, lookAt);
Matrix4 trans;
// construct rotation/translation matrix
trans.m[ 0] = right.x; trans[ 4] = up.x; trans[ 8] = forward.x; trans[12] = 0.0f;
trans.m[ 1] = right.y; trans[ 5] = up.y; trans[ 9] = forward.y; trans[13] = 0.0f;
trans.m[ 2] = right.z; trans[ 6] = up.z; trans[10] = forward.z; trans[14] = 0.0f;
trans.m[ 3] = pos.x; trans[ 7] = pos.y; trans[11] = pos.z; trans[15] = 1.0f;
Given that the global forward vector is positive, and the forward vector's components aren't inserted into the matrix as negative values, this would make it left-handed, right? Also, the translation vector is along the bottom row of the matrix instead of the right-most column. I realized now that my matrix in my OpenGL code wasn't constructed correctly (although it seems to yield correct results). I took a look at the gluLookAt code, and it looks like this:
void glhLookAtf2( float *matrix, float *eyePosition3D,
float *center3D, float *upVector3D )
{
float forward[3], side[3], up[3];
float matrix2[16], resultMatrix[16];
//------------------
forward[0] = center3D[0] - eyePosition3D[0];
forward[1] = center3D[1] - eyePosition3D[1];
forward[2] = center3D[2] - eyePosition3D[2];
NormalizeVector(forward);
//------------------
//Side = forward x up
ComputeNormalOfPlane(side, forward, upVector3D);
NormalizeVector(side);
//------------------
//Recompute up as: up = side x forward
ComputeNormalOfPlane(up, side, forward);
//------------------
matrix2[0] = side[0];
matrix2[4] = side[1];
matrix2[8] = side[2];
matrix2[12] = 0.0;
//------------------
matrix2[1] = up[0];
matrix2[5] = up[1];
matrix2[9] = up[2];
matrix2[13] = 0.0;
//------------------
matrix2[2] = -forward[0];
matrix2[6] = -forward[1];
matrix2[10] = -forward[2];
matrix2[14] = 0.0;
//------------------
matrix2[3] = matrix2[7] = matrix2[11] = 0.0;
matrix2[15] = 1.0;
//------------------
MultiplyMatrices4by4OpenGL_FLOAT(resultMatrix, matrix, matrix2);
glhTranslatef2(resultMatrix,
-eyePosition3D[0], -eyePosition3D[1], -eyePosition3D[2]);
//------------------
memcpy(matrix, resultMatrix, 16*sizeof(float));
}
gluLookAt() creates a view matrix, however. My matrix is a model matrix for getting objects to face certain objects. I'm also assuming that the matrices are stored by column (every 4 elements make up a column in gluLookAt()). That said, here's how I construct my model matrix version of gluLookAt():
Matrix4 Matrix4::LookAt(Vector3 position, Vector3 target, Vector3 up)
{
Matrix4 resultMat;
Vector3 forward = target - position; // "position" would generally be called "eyePosition" for a view matrix
forward.Normalize();
Vector3 right = Vector3::Cross(forward, up);
right.Normalize();
up = Vector3::Cross(right, forward);
resultMat.Set( right.x, up.x, -forward.x, position.x,
right.y, up.y, -forward.y, position.y,
right.z, up.z, -forward.z, position.z,
0.0f, 0.0f, 0.0f, 1.0f);
return resultMat;
}
Is my model matrix setup correctly using a right-handed coordinate system? My global forward vector is <0.0f, 0.0f, -1.0f>.