Excellent contribution!

I did some tests using your code--- converting level space to view entity space and trying to get an object in each to overlap. This provides good feedback on what is happening, as you know where the object should be (versus where it is) for any given position and orientation.

I encountered two problems. One is that there are singularities (where the object flips orthogonal to where it should be at a particular values), and I found it possible to lock the tilt in such a way that the object pretty much stays flipped until the tilt is changed. You might be able to solve this by adding a gimbal lock check to ang_for_quat. (I have to check, but this may only occur when rotating about multiple axes).

The other seems to occur only when rotating about multiple axes. Getting the orientations of the entities to match between the level space and view space should look something like this: (maybe there is a conceptual error on my part?)

Quote:

//get the entity orientation
vec_set(temp_angle2,temp_entity2.pan);
quat_for_ang(quaternion2,temp_angle2);
quat_to_unit(quaternion2);
//rotate by pan
vec_set(temp_angle1,vector(-camera.pan,0,0));
quat_for_ang(quaternion1,temp_angle1);
quat_to_unit(quaternion1);
quat_multiply(quaternion2,quaternion2,quaternion1); //also tried q1 by q2
//rotate by tilt
vec_set(temp_angle1,vector(0,-camera.tilt,0));
quat_for_ang(quaternion1,temp_angle1);
quat_to_unit(quaternion1);
quat_multiply(quaternion2,quaternion2,quaternion1);
//rotate by roll
vec_set(temp_angle1,vector(0,0,-camera.roll));
quat_for_ang(quaternion1,temp_angle1);
quat_to_unit(quaternion1);
quat_multiply(quaternion2,quaternion2,quaternion1);
//update entity orientation
ang_for_quat(temp_angle1,quaternion2);
vec_set(temp_entity1.pan,temp_angle1);




The entity orientations match well when the camera angles are in the first quadrant, but they flip or become constrained by 180 degrees (oscillatory) in the other quadrants. The behavior I was trying to duplicate looks like this:

Quote:

vec_set(temp_angle1,temp_entity2.pan);
vec_set(temp_angle2,vector(-camera.pan,0,0));
ang_add(temp_angle1,temp_angle2);
vec_set(temp_angle2,vector(0,-camera.tilt,0));
ang_add(temp_angle1,temp_angle2);
vec_set(temp_angle2,vector(0,0,-camera.roll));
ang_add(temp_angle1,temp_angle2);
vec_set(temp_entity1.pan,temp_angle1);




I'd love to see SLERP implemented, by the way!