This is fairly easy to do with Quaternions -- though I can definitely understand your trouble trying to deal with this in Euler angles. In fact this is the type of situation where it's particularly useful to have Quaternions, but perhaps you don't want to convert to Quaternions just for this. That's okay, because the latest update (A7.80) adds ang_for_axis, which will be very helpful.

Here's how I've done it with Quaternions (should work without, and I've briefly outlined how to do it without Quaternions too) :

1. The player has a vector (just a local VECTOR) that always has its relative up vector (simple vec_rotate(up, my.pan) where "up" is (0, 0, 1)).

2. c_trace to get the normal (as you've done).

3. Find the angle between my "up" and the normal -- acos(vec_dot(up, normal)) -- we don't have to divide by the length of either vector since they are both unit vectors. This angle is how much we want to rotate our model.

4. Find the axis we want to rotate around by getting vec_cross(up, normal) (since the axis has to be perpindicular to both our starting vector and the vector we want to line it up with).

5. Lastly, to line the model up with the normal, we want to line the player up with the normal beneath it by rotating it by the angle we found in "3." around the axis we found in "4.". I did this with Quaternions (very easy that way), but if you want to do it without and you have the latest update, you can probably use "ang_for_axis(ANGLE* result, axis, angle);" to find the Euler version of the rotation, and then use ang_add to rotate your model by that amount.

I hope this is helpful. Let me know if you need a little more, and I'll be happy to help more, but as the shader contest deadline approaches Friday night I won't be able to help until Saturday.

On a side-note, a threw in a couple of small snippets from my Quaternion code into my contest entry, and have found ang_for_axis very useful for a very clean conversion back to Euler angles laugh

Jibb

EDIT: In step 1 I actually used my own Quaternion version of vec_rotate, because it would be inconsistent and slightly less stable to alternate between using the entity's Euler orientation and its Quaternion rotation. That won't change how you do it, though laugh

Last edited by JulzMighty; 08/13/09 14:00.

Formerly known as JulzMighty.
I made KarBOOM!