Camera orbiting around object

Started by
5 comments, last by alejandro 13 years, 1 month ago
Hi,

I'm trying to achieve an orbiting camera using gluLookAt and spherical coordinates but I just can't get it right



#define PI 3.14159265


struct Camera{
float x, y, z; // Camera position
float atX, atY, atZ; // Where is it looking
float uX, uY, uZ; // Where is up
Camera(){}
};

Camera c;
float rho = 5.;
float phi = 0.;
float theta = 0.;

float toRadians(float degrees)
{
return degrees * (PI / 180.);
}

void draw()
{
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// To Carthesian Coordinates
c.x = rho * sin(toRadians(phi)) * cos(toRadians(theta));
c.y = rho * sin(toRadians(phi)) * sin(toRadians(theta));
c.z = rho * cos(toRadians(phi));
// Where the camera is looking
c.atX = 0.;
c.atY = 0.;
c.atZ = 0.;
// What the hell is this for? Can't remember :( where I took this from
c.uX = cos(toRadians(theta));
c.uY = sin(toRadians(theta));
c.uZ = 1;

gluLookAt(c.x, c.y, c.z, c.atX, c.atY, c.atZ, c.uX, c.uY, c.uZ);

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glutWireCube(1);
glutSwapBuffers();
}



rho++ gets me a zoom in
rho-- gets me a zoom out
phi++ the camera goes 'up' but at a certain point it messes and it starts going down
phi-- the camera goes 'down' but at a certain point it messes and it starts going down
theta++ the camera rotates on z
theta-- the camera rotates on z

The main problem is when I modify phi :( I think that the problem is on UP vertex

Thanks for your help
Advertisement
Maybe I could help:

CVector vOffset;
vOffset.x = sin(xzrot) * sin(yrot) * distance;
vOffset.y = cos(yrot) * distance;
vOffset.z = cos(xzrot)*sin(yrot)*distance;

CVector vCamFocus = object.pos;
CVector vCamPos = vCamFocus + vOffset;

xzrot is rotation in xzplane, yrot is in yplane..

c.x = rho * sin(toRadians(phi)) * cos(toRadians(theta));
c.y = rho * sin(toRadians(phi)) * sin(toRadians(theta));
c.z = rho * cos(toRadians(phi));
[/quote]

To help you think the problem through, what do you expect to happen when phi > 180 degrees?

[spoiler]
sin(179) ~ 0.0175
sin(181) ~ -0.0175

It will start moving down the axis again.
[/spoiler]

To help you think the problem through, what do you expect to happen when phi > 180 degrees?



Ok, so Phi has to go from 0 - 180... Will try it later :D

Thank you

Bow_vernon: Haven't checked your solution, also will try it later :D



Hello,

Orbiting the camera is equivalent to rotating the camera location around the target position. There is a transformation matrix that allows you to rotate a point about an angle around an arbitrary axis.

Let's call this matrix R, you camera position c and you target position t. Orbiting the camera is done as follow:

c' = translate(t)*R*translate(-t)*c

Where c' is the new position of your camera after orbiting and translate( . ) is a translation matrix.

You still have to choose around which axis you want to orbit.
The code snippet in the OP does the following:

It computes a unit length vector that points from the origin towards the location where the camera is placed.


sin(toRadians(phi)) * cos(toRadians(theta));
sin(toRadians(phi)) * sin(toRadians(theta));
rho * cos(toRadians(phi));

and scales the vector by the camera distance rho, yielding in the position of the camera:


c.x = rho * sin(toRadians(phi)) * cos(toRadians(theta));
c.y = rho * sin(toRadians(phi)) * sin(toRadians(theta));
c.z = rho * cos(toRadians(phi));

Hence rho isn't a zoom factor, and changing rho doesn't zoom in/out. Instead, it moves the camera towards the origin (rho++) or away from it (rho--).

BTW: The formula used above is the conversion from spherical to cartesian co-ordinates, as can be read e.g. here on wikipedia. You can find the condition mentioned by Seriphis (and the other conditions) there.

Next, the ( c.atX, c.atY, c.atZ ) is set to the point where the camera should look at.

Now, a (not 0) vector in 3D space defines a direction but not an orientation. For an orientation you need a 2nd direction vector that is not co-linear to the 1st one. For this purpose typically the so-called up vector is used. In your case it is ( c.uX, c.uY, c.uZ ).

All this is pushed into gluLookAt (read about its parameters e.g. here).
Thanks Haegarr for your explanation also eribeg.

I was debugging today and I noticed that when phi reaches 45º -> 0.785398 radians, the object that I'm looking (0, 0, 0) dissapears, after that in 46º, it appears to going down... also in -135º

Will try to find the answers in the documentation provided.

Thanks for your answers

This topic is closed to new replies.

Advertisement