public static Quaternion Nlerp( Real fT, Quaternion rkP, Quaternion rkQ, bool shortestPath ) { Quaternion result; var fCos = rkP.Dot( rkQ ); if ( fCos < 0.0f && shortestPath ) { result = rkP + fT*( ( -rkQ ) - rkP ); } else { result = rkP + fT*( rkQ - rkP ); } result.Normalize(); return result; }
/// <summary> /// /// </summary> /// <param name="time"></param> /// <param name="quatA"></param> /// <param name="quatB"></param> /// <param name="useShortestPath"></param> /// <returns></returns> public static Quaternion Slerp( Real time, Quaternion quatA, Quaternion quatB, bool useShortestPath ) { var cos = quatA.Dot( quatB ); var angle = (Real)Utility.ACos( cos ); if ( Utility.Abs( angle ) < EPSILON ) { return quatA; } var sin = Utility.Sin( angle ); var inverseSin = 1.0f/sin; var coeff0 = Utility.Sin( ( 1.0f - time )*angle )*inverseSin; var coeff1 = Utility.Sin( time*angle )*inverseSin; Quaternion result; if ( cos < 0.0f && useShortestPath ) { coeff0 = -coeff0; // taking the complement requires renormalisation var t = coeff0*quatA + coeff1*quatB; t.Normalize(); result = t; } else { result = ( coeff0*quatA + coeff1*quatB ); } return result; }