Sign in to follow this  
alejandro

Camera orbiting around object

Recommended Posts

Hi,

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

[code]

#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();
}
[/code]


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

Share this post


Link to post
Share on other sites
Maybe I could help:
[code]
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;
[/code]
xzrot is rotation in xzplane, yrot is in yplane..

Share this post


Link to post
Share on other sites
[quote]
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]

Share this post


Link to post
Share on other sites
[quote name='Seriphis' timestamp='1299471135' post='4782678']
To help you think the problem through, what do you expect to happen when phi > 180 degrees?
[/quote]


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



Share this post


Link to post
Share on other sites
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 [b]R[/b], you camera position [i]c[/i] and you target position [i]t[/i]. Orbiting the camera is done as follow:

[i]c[/i]' = translate([i]t[/i])*[b]R[/b]*translate(-[i]t[/i])*c

Where [i]c[/i]' 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.

Share this post


Link to post
Share on other sites
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.

[code]
sin(toRadians(phi)) * cos(toRadians(theta));
sin(toRadians(phi)) * sin(toRadians(theta));
rho * cos(toRadians(phi));
[/code]
and scales the vector by the camera distance rho, yielding in the position of the camera:

[code]
c.x = rho * sin(toRadians(phi)) * cos(toRadians(theta));
c.y = rho * sin(toRadians(phi)) * sin(toRadians(theta));
c.z = rho * cos(toRadians(phi));
[/code]
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. [url="http://en.wikipedia.org/wiki/Spherical_coordinate_system"]here on wikipedia[/url]. 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 [b]0[/b]) 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 [i]up vector[/i] 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. [url="http://www.opengl.org/sdk/docs/man/xhtml/gluLookAt.xml"]here[/url]).

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this