I was able to implement this kind of camera by tracking polar cooridinates and converting to carteasian when I place the camera.
If you can track the distance from the origin, the rotation around the Z axis (assuming Z is up), and elevation from the XY plane, you’ve got the 3 polar coordinates; Rho, Theta, Phi.
I used a sets of 3 floats for all the necessary coordinates.
polar.x, y and z equate to Rho Theta and Phi and are tied directly to the mouse.
anchor.x, y, and z hold the origin of the polar coordinate system (or the object the camera is rotating around).
position.x, y, and z hold the resulting global coordinates of the position of the camera.
Using gluLookAt, the ‘position’ is the location of the camera, and ‘anchor’ is what it’s looking at. Then all you need is a global up vector of (0, 0, 1).
This is my most recent implementation of the camera.think method. It was written in Java using lwjgl. I have no idea if it’s as fast as it could be, but the effect is visually very pleasing. The result is a camera like that of the game Homeworld.
// set the rotational limits
if( polar.x < 1.5 ) polar.x = 1.50f;
if( polar.x > 100.0 ) polar.x = 100.00f;
if( polar.y < 0.0 ) polar.y += 360.00f;
if( polar.y > 360.0 ) polar.y -= 360.00f;
if( polar.z < -89.99 ) polar.z = -89.99f;
if( polar.z > 89.99 ) polar.z = 89.99f;
// convert to radians
double tempTheta = polar.y * (float) Math.PI/180;
double tempPhi = polar.z * (float) Math.PI/180;
// convert polar to cartesian coordinates
position.x = anchor.x + polar.x * (float) Math.cos( tempPhi ) * (float) Math.cos( tempTheta );
position.y = anchor.y + polar.x * (float) Math.cos( tempPhi ) * (float) Math.sin( tempTheta );
position.z = anchor.z + polar.x * (float) Math.sin( tempPhi );
//calculate the direction the camera is looking
Vector3f.sub( position, anchor, forward );
forward.normalize();
//calculate the ‘right’ vector for billboards by pretending we know where up is
Vector3f.cross( globeUp, forward, bbRight );
bbRight.normalize();
//calculate the ‘up’ vector for billboards using the right we just got
Vector3f.cross( forward, bbRight, bbUp );
bbUp.normalize();
[This message has been edited by Clockwork (edited 12-18-2003).]