[LWJGL] Making The Camera Look At A Point

Hello everyone! This is my first post here, So stick with me :wink:

I have been developing a 3D game in Java using lwjgl. I have a camera the orbits around the player in a circle (I think its called a Arcball camera). The problem is, I cant figure out how to make the camera look at the player while its orbiting around it :-!

I have variables for the camera pitch and yaw rotations, and of course vectors for the camera and player positions. So I just need to know how to calculate the rotations.

Any help is much appreciated. Thanks! :slight_smile:

Here is the source of gluLookAt. Hopefully you can convert it to Java, then use the resulting matrix to transform your camera.

Thanks for the link. However, I cant quite understand the code (I don’t know C/C++).

Hey, here’s my method for gluLookAt in my Matrix class.

public Mat4 gluLookAt(Vec3 eye, Vec3 center, Vec3 up) {
	Vec3 forward = center.copy().sub(eye).normalise();
	Vec3 side = forward.copy().cross(up).normalise();
	up = side.copy().cross(forward);

	identity();
	m00 = side.x;
	m01 = side.y;
	m02 = side.z;
	m10 = up.x;
	m11 = up.y;
	m12 = up.z;
	m20 = -forward.x;
	m21 = -forward.y;
	m22 = -forward.z;
	return this;
}

welcome! :slight_smile:

take a look at lwjgl glu-source :

which is pointing to

look up the [icode]gluLookAt[/icode] method.

if you use this opengl binding then you’re almost set :slight_smile:

Thanks everyone for your help! I have one more question:

Lets say I had a rotation matrix, How can I get the yaw and pitch rotations out of that? My camera is set up so that there are different floats for the yaw and pitch :slight_smile:

heres a tip.

instead of floats consider keeping your yaw pitch and roll in three separate matrix4f’s.
you merge them only when creating your view matrix. this will make situation like when you roll and now your yaw moves like a pitch much easier…

I didn’t test it but I think this should work.

forward = third column of the matrix as a vector

forward2 = forward.copy();
forward2.y = 0;
forward2.normalise();
yawn = Math.atan2(forward2.z, forward2.x);
pitch = Math.acos(forward.copy().dotProduct(forward2));

OK, I just cant get this to work :frowning: The camera turns around in the wrong direction and then turns upside down.

Here is my code:

public void lookAt(Vector3f eye, Vector3f target, Vector3f up) {
Vector3f forward = new Vector3f(0, 0, 0);
Vector3f.sub(target, eye, forward);
forward.normalise();
Vector3f side = new Vector3f(0, 0, 0);
Vector3f.cross(forward, up, side);
side.normalise();
Vector3f.cross(side, forward, up);

	  Matrix4f mat = new Matrix4f();
	  mat.setIdentity();
	  
	  mat.m00 = side.x;
	  mat.m01 = side.y;
	  mat.m02 = side.z;
	  mat.m10 = up.x;
	  mat.m11 = up.y;
	  mat.m12 = up.z;
	  mat.m20 = -forward.x;
	  mat.m21 = -forward.y;
	  mat.m22 = -forward.z;
	  
	  Vector3f forward2 = new Vector3f(forward.x, 0, forward.z);
	  forward2.normalise();
	  
	  float yawChange = (float) Math.atan2(forward2.z, forward2.x);
	  float pitchChange = (float) Math.acos(Vector3f.dot(forward, forward2));
	  
	  yaw += yawChange;
	  pitch += pitchChange;
      
   } 

For the eye parameter, I give it the camera position. For the target, I give it the player position. For up, I give it a new Vector3f(0, 1, 0).
Can you see anything wrong? Also, Sorry if this is a sort of dumb question :wink:

Thanks.

Why do you set the third column of the matrix to -forward instead of +forward?
And why do you call the third column m20, m21, m22. The index of the row is usually given first. Although I guess it doesn’t really matter.
Also the equations I gave you calculate the absolute yaw and pitch, not the change.
It’s also possible that yawn or pitch has the wrong sign and needs to be negated.

OK, First, I don’t know about the matrix stuff (Just using the code Nouht gave me, I don’t know much about matrix math :)). I changed it so the pitch and yaw where set to the absolute value of the calculations, But now the camera just looks straight ahead and does not look at the player at all. Also, Not sure what you mean about the wrong sign thing, Did a quick google search and found nothing.

Again, Thanks and sorry for the trouble.

If you are going to roll your own camera implementation straight from the matrices, then you really need to understand the maths. I find the best place to learn this stuff is here: http://www.wildbunny.co.uk/blog/vector-maths-a-primer-for-games-programmers/. It’s not too long and will give you a firm basis in vector and matrix maths as they apply to 3D graphics.

If you don’t understand this stuff then I’m afraid you are just clutching at straws and you will run into problem after problem.

You forgot to recompute the up vector.

I just cant figure this out :frowning: quew8, I took a look at that post, And I get most of the stuff on it, But that really doesn’t help me.
Can anyone just give me a bit of code that allows me to get the necessary Pitch, Yaw and Roll variables to rotate my camera to look at a point in the game world?

Thanks :slight_smile:

I figured it out! I just needed to invert the matrix :wink:

Thanks everyone for your help. Here is my final code if you are interested:

public static Matrix4f lookAt(Vector3f eye, Vector3f center, Vector3f up) {
Vector3f forward = new Vector3f(0, 0, 0);
Vector3f.sub(center, eye, forward);
forward.normalise();

      Vector3f side = new Vector3f(0, 0, 0);
      Vector3f.cross(forward, up, side);
      side.normalise();
      
      Vector3f.cross(side, forward, up);

      Matrix4f matrix = new Matrix4f();
      matrix.m00 = side.x;
      matrix.m01 = side.y;
      matrix.m02 = side.z;
      matrix.m10 = up.x;
      matrix.m11 = up.y;
      matrix.m12 = up.z;
      matrix.m20 = -forward.x;
      matrix.m21 = -forward.y;
      matrix.m22 = -forward.z;
      matrix.invert();
      
      return matrix;
   }

You have to invert the matrix because you defined it the wrong way around.
As I already mentioned, the first index is the row and the second the column.
Switching rows and columns is inverting the matrix.
That means the correct way of defining the matrix would be


         Matrix4f matrix = new Matrix4f();
         matrix.m00 = side.x;
         matrix.m10 = side.y;
         matrix.m20 = side.z;
         matrix.m01 = up.x;
         matrix.m11 = up.y;
         matrix.m21 = up.z;
         matrix.m02 = -forward.x;
         matrix.m12 = -forward.y;
         matrix.m22 = -forward.z;