The little 'spins' that it does are actually kind of neat, but I'm guessing they're not intentional :) Anyway, for this type of motion I would definitely recommend accumulated relative rotations. To keep things simple, I'll skip the quaternion-specific version of the algorithm and just describe the straightforward version. In pseudocode, it looks something like this (typed directly into the post, and not tested in any way):
// Somewhere during initialization:quaternion q = whatever_you_want_the_initial_orientation_to_be();// For each update:matrix m = matrix_from_quaternion(q);vector3 forward = m.get_third_basis_vector(); // Ask if you're not sure what this meansvector3 desired_forward = normalize(velocity);vector3 axis = cross(forward, desired_forward);float length = axis.length();if (length > epsilon) { axis /= length; float angle = atan2(length, dot(forward, desired_forward)); quaternion rotation = quaternion_from_axis_angle(axis, angle); q = rotation * q; q.normalize();}
I think that's about the best advice I can offer at this point. If you have questions about the above pseudocode though, feel free to ask.