Sign in to follow this  
Pet123

Why My Quaternion Slerp always rotate in same directon?

Recommended Posts

Hi there i need to rotate character's head in game, everytime rotate the head, current rotation and final destination rotation are known, this should be simple by using quaternion. to my surprise, the quaternion Slerp method always give interpolated results in same direction, even if its obvious to rotate in another direction will be much nearer. i have spent serveral hours to try to get this solved, but no luck. here is the pseudo-code i used to rotate the head, please someone points out where it is going wrong, thank you.

// rot_matrix_current and rot_matrix_dest are known
const float angle = angle_between_current_rotation_and_dest_rotation(rot_matrix_current, rot_matrix_dest);

const quaternion q_current = make_quaternion_from_matrix(rot_matrix_current);
const quaternion q_dest    = make_quaternion_from_matrix(rot_matrix_dest);

// speed is rotation speed, its known value
float t = time_elapsed_since_last_update * speed / angle;
t = clamp(t, 0, 1);

const quaternion q = slerp(t, q_current, q_dest);

rot_matrix_current = make_matrix_from_quaternion(q);

set_head_rotation(rot_matrix_current);


Share this post


Link to post
Share on other sites
hi jyk

sorry for the title maybe its misleading : the slerp() function comes along with the engine we are using.

anyway, by your reply, i guess the method im using here is correct?

ummm i'd better write some code to test the slerp() ... but i doubt its the reason.

Share this post


Link to post
Share on other sites
Quote:
Original post by Pet123
hi jyk

sorry for the title maybe its misleading : the slerp() function comes along with the engine we are using.

anyway, by your reply, i guess the method im using here is correct?

ummm i'd better write some code to test the slerp() ... but i doubt its the reason.
What about angle_between_current_rotation_and_dest_rotation()? Are you sure it's always returning the smallest angle between the two orientations, and that it's always positive?

Share this post


Link to post
Share on other sites
I do this at the quadratic interpolation stage, given four quats:

quat_previous, quat_a, quat_b, quat_next

// try to make sure that the shortest paths across the 4D hypersphere are followed...
if ( quat_a.dot(quat_b) < 0) quat_b = -quat_b;
if ( quat_a.dot(quat_previous) < 0) quat_previous = -quat_previous;
if ( quat_b.dot(quat_next) < 0) quat_next = -quat_next;

For a simple slerp you probably only need the first line. Hope that helps.

Share this post


Link to post
Share on other sites
Quote:
What about angle_between_current_rotation_and_dest_rotation()? Are you sure it's always returning the smallest angle between the two orientations, and that it's always positive?


the angle is calculated using dot product of two forward vectors extracted from the two rotation matrices, and actually only its absoulate value used here. i can confirm you that it is the shortest yesterday but now i'd think again and write code to test it. :P

Quote:

I do this at the quadratic interpolation stage, given four quats:

quat_previous, quat_a, quat_b, quat_next

// try to make sure that the shortest paths across the 4D hypersphere are followed...
if ( quat_a.dot(quat_b) < 0) quat_b = -quat_b;
if ( quat_a.dot(quat_previous) < 0) quat_previous = -quat_previous;
if ( quat_b.dot(quat_next) < 0) quat_next = -quat_next;

For a simple slerp you probably only need the first line. Hope that helps.

yeah, it does help and just like what you said only the first line needed in my case.




it works now, i just added this (like what Geocyte said in his reply)

if (q_current.dot(q_dest) < 0)
q_dest = -qdest;



thanks jyk and Geocyte.


Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this