Problem with gluLookAt

Started by
5 comments, last by Dexus 18 years, 8 months ago
Hi, I'm not exactly very experienced yet with OpenGL and all the projection modelview and matrix transformation stuff can go a bit over my head. Anyway the goal I have at the moment is to have a ball bouncing around a box and be able to use the mouse to 'orbit' around this ball. That means that the camera should always be a fixed distance from this ball (hopefully with the ability to adjust this in order to zoom in and out) and I should be able to use the mouse to rotate the camera around the ball. I have got the bouncing ball working ok but I haven't figured out exactly how to use gluLookAt along with glRotate to allow me to rotate around the ball. Here's what I have at the moment:

Vector3D ball1pos = sim.getBallPos(0);
gluLookAt(0.0f,0.0f,12.0f,
	(float)ball1pos.x,(float)ball1pos.y,(float)ball1pos.z,
	0.0f,1.0f,0.0f);
glRotatef(angle,0.0f,1.0f,0.0f);
This code gets the first ball's position and stores it in the Vector ball1pos. This position is used for the parameters of gluLookAt. The modelview matrix is then rotated around the y axis and the angle is calculated using the movement of the mouse. The code has two problems at the moment. First of all the camera is in a fixed position. I'd like to always be a fixed distance from the ball. Also when I rotate the camera 180 degrees, the rotation causes the ball to move away from the centre of the view. In fact when the ball moves to the right the camera moves to the left and vice versa. I can understand why the rotation of the scene causes this to happen but I can't see any way of getting it to look right. Anyone have any ideas?
Advertisement
I'll make an attempt to sketch out for you how I would do this. Can't guarantee I'll get it right, but maybe it will point you in the right direction.

float sp = sinf(cam.phi);
float cp = cosf(cam.phi);
float st = sinf(cam.theta);
float ct = cosf(cam.theta);

Vector3 offset(st*cp,sp,ct*cp);
cam.pos = ball.pos + offset * cam.distance;
gluLookAt(cam.pos.x,cam.pos.y,cam.pos.z,ball.pos.x,ball.pos.y,ball.pos.z,0,1,0);

'theta' is the angle of 'orbit' around the ball, in the range [0,360]. 'phi' is the angle of elevation, typically in the range [-90,90]. 'distance' is the distance from the camera to the ball, which you can think of as the 'zoom'. The above code finds the position of the camera using spherical coordinates, which you can google for if you'd like to learn more about them.

Again, no guarantees, but I think something like the above should work for you.
Cool thanks, that works well.

But I don't understand why this simpler method doesn't work either:

glTranslatef(-(float)ball1pos.x,-(float)ball1pos.y,-(float)ball1pos.z);GL11.glRotatef(angle,0.0f,1.0f,0.0f);GL11.glTranslatef(0.0f,0.0f,-15.0f);


The first line should centre the whole scene on the position of the ball. Then the whole scene should be rotated by angle degrees around the central point which is the ball's position. Then the last line should translate the scene 15 units into the z axis away from the camera. In my understanding this should allow you to orbit around the ball but in practice the whole scene orbits around the camera instead.

I don't understand why this is happening. If the last line translates the scene 15 untis into the z axis, shouldn't it always appear in front of the camera 15 units away?
OpenGL's transforms are stack based so they are backwards, you would do SRT (scale rotate translate) but in GL it is TRS (translate rotate scale).. but it multiplies in SRT order. It's confusing and I usually get it mixed up too.
"It's such a useful tool for living in the city!"
That's intersting and I guess it's thrown everything I thought I knew about OpenGL matrix transformations out the window. :p

Anyway it's good to find that when I reverse the order of those three transformations I'm able to get the camera to orbit the ball from a fixed distance. But I am only able to get it to work with one angle of rotation. IE I can rotate around the Y axis but as soon as I do that I can't rotate the scene up and down because the orientation of the X and Z axes has changed.

Here's an example:

glTranslatef(0.0f,0.0f,-15.0f);glRotatef(angle,0.0f,1.0f,0.0f);glRotatef(phi,1.0f,0.0f,0.0f);glTranslatef(-(float)ball1pos.x,-(float)ball1pos.y,-(float)ball1pos.z);


The rotation of angle degrees works fine but this screws up the rotation of phi degrees. I've been trying to find out how to deal with combinations of rotations and I think I may have to deal with quanternions but that may be too advanced for me at this stage. Does anyone have an idea of how I deal with these two rotations in a simple way? I could just use jyk's code above but I'd like to try to explore all possible solutions and understand which is best rather than blindly copy and paste someone else's.
There isn't a real easy way to do it that I know of. What I do is compose my rotations in a matrix and than use glMultMatrixf. I only use those commands for simple stuff anymore. I try to keep my transforms simple because you can wind up with bad matrices if you do too much.
"It's such a useful tool for living in the city!"
Actually I did figure out a way to combine those two rotations. I had to rotate the axis around which the second rotation was made by the amount that the first rotation was made. In other words:

glTranslatef(0.0f,0.0f,-15.0f);glRotatef(angle,0.0f,1.0f,0.0f);glRotatef(phi, cosf(angle * DEG_TO_RAD), 0.0f, sinf(angle * DEG_TO_RAD));glTranslatef(-(float)ball1pos.x,-(float)ball1pos.y,-(float)ball1pos.z);


And this works as well as jyk's gluLookAt code.

I am going to look further into combining these four transformations into a single matrix. It will certainly be interesting to see if that's possible.

[Edited by - Dexus on July 31, 2005 6:32:08 AM]

This topic is closed to new replies.

Advertisement