I’ll try to explain how you can create a matrix with the functionality of the lookAt function. The top left 3x3 of the 4x4 matrix contains the rotation of the matrix. In fact it contains the 3 unit vectors (x, y, z) that are perpendicular to eachother. If they are not one unit in size then there is a scale applied to the matrix. If they are not perpendicular then the matrix is scewed. So by filling in the forward, up and side vector of the object you want to orientate, you’ve got yourself a lookAt matrix.
First take the direction you wan’t to aim and normalize. This will be the z vector in the matrix. We get the horizontal (x) part of the matrix by applying the crossproduct between the forward vector and the up vector. We don’t know the real up vector, but can use (0, 1, 0) instead. The crossproduct will be correct as long as you don’t aim up or down. That can not happen in my game so I don’t handle this special case in my source. We can’t use up (0, 1, 0) in the matrix, but we can get the perpendicular up vector by crossing the z and x vectors. Stick the x, y and z vectors along with the position into the matrix and thats it.
Here some code:
public static float[] getMatrix(Vector3f eye, Vector3f pos) {
Vector3f zAxis = new Vector3f(pos);
zAxis.sub(eye);
zAxis.normalize();
Vector3f yAxis = new Vector3f(0, 1, 0);
// Build the X axis vector based on the two existing vectors
Vector3f xAxis = new Vector3f();
xAxis.cross(yAxis, zAxis);
xAxis.normalize();
// Correct the Y reference vector
yAxis.cross(xAxis, zAxis);
yAxis.normalize();
yAxis.scale(-1);
float m[] = new float[16];
m[0] = xAxis.x; m[1] = xAxis.y; m[2] = xAxis.z; m[12] = pos.x;
m[4] = yAxis.x; m[5] = yAxis.y; m[6] = yAxis.z; m[13] = pos.y;
m[8] = zAxis.x; m[9] = zAxis.y; m[10] = zAxis.z; m[14] = pos.z;
m[15] = 1;
return m;
}
public static void applyMatrix(Vector3f eye, Vector3f pos) {
float m[] = getMatrix(eye, pos);
matBuff.rewind();
matBuff.put(m);
matBuff.flip();
GL11.glMultMatrix(matBuff);
}
I have to admit that the atan2 code looks clearer 