I tried a bunch of different ways to set the camera, but it always ended up wonky in some way, whether jumping around at the top and bottom of the rotation arc, or by not allowing going upside-down.
This code will follow an object around at a certain offset. If your character goes up side down, so will the camera(hence, I call it 'rigid'). This might be fun to attach as a 3rd person car camera, or for a jet plane or a spaceship.
The easiest way to make this work is to call something similar to this pseudo code:
SetCustomCam(mychar.matrix(), mychar.....getPoint("camera_slot").pos, mychar.....getPoint("camera_slot").dir, false);
Now you can do a barrel roll!
Alternatively,
SetCustomCam(mychar.matrix(), Vec(0, 5, 0), interestingObjectPos);
A periscope feel!
If you want to move the camera around, you can modify offset.
Code:
void SetCustomCam( C Matrix &mat, // Matrix that belongs to the object for the cam to follow
C Vec &offset, // The offset in local coords
C Vec &facing, // The direction to face
bool facingIsLocation = true ) // Whether the direction is a point in the world to face or a normalized direction
{
Vec pos = offset; // The offset to move the camera by
pos.mul( mat.orn( ) ); // Transform the local vector by the rotation
pos += mat.pos; // Apply to world coords
Vec up( 0, 1, 0 ); // Create the up vector
up .mul(mat.orn( ) ); // Rotate the up vector so the camera up is relative to the object up
Vec dir = facingIsLocation ?
!( facing - pos ) : // Set the direction towards a point
dir = facing ; // Set the direction the same as passed in
Cam.setPosDir( pos, dir, up ); // Apply the transforms to the camera
Cam.updateVelocities( ).set( ); // Update Velocities for effects and set the camera active
}
Hopefully, this will save someone a lot of the time it took me to experiment.