No problem. I wasn't really able to find a useful formula online to use rotations to accomplish the same effect. I did, however, come up with my own formula. I am no math wiz, so the main difficulty I was having was the fact that the camera's rotate methods are all relative to its current orientation (compounded by my lack of experience with 3D geometry). I believe I have finally solved the problem, though.

Here are the two methods for setting camera look-at and up directions using normalized vectors. Note: I've only run some very basic tests on the setUpDirection() method, but it seems to work. I'll write another post here after I've had a chance to use the method more extensively to see if there is an error in my formula.

`/**`

* Sets the specified Camera's look-at direction.

* @param c Camera to use.

* @param v Normalized vector indicating the look-at direction.

*/

public void setLookDirection( Camera c, SimpleVector v )

{

SimpleVector l = new SimpleVector( v );

l.add( c.getPosition() );

c.lookAt( l );

}

/**

* Sets the specified Camera's up direction.

* @param c Camera to use.

* @param v Normalized vector indicating the up direction.

*/

public void setUpDirection( Camera c, SimpleVector v )

{

SimpleVector previousUp = new SimpleVector( c.getUpVector() );

// TODO: Remove this hack after the next release of jPCT!

previousUp.y = -previousUp.y;

float distance = previousUp.calcSub( v ).length();

float angle = (float) Math.acos( ( 2.0d - (distance * distance) )

/ 2.0d );

if( previousUp.x == -v.x && previousUp.y == -v.y &&

previousUp.z == -v.z )

c.rotateAxis( c.getDirection(), angle );

else

c.rotateAxis( previousUp.calcCross( v ).normalize(), angle );

}

In case you are wondering about that if statement, I put it there to handle the case where the new up-direction is exactly opposite to the previous up-direction (for example, if previous up is -y and new up is y). In such a case, a cross-vector can not be calculated to indicate which axis to rotate around. Also, you may be wondering why I didn't always use c.getDirection() as the axis to rotate around. That is because I am using the law of cosines, which was designed to calculate the angle of a triangle given its sides, so it is limited to angles between 0 and pi. In order to get a full 2 pi of rotation, I calculate the cross-vector, which reverses when the angle becomes greater than pi.