I don’t think there’s any problem with me posting the C++ snippet for Unity implementation, just don’t ask me or blame me for it, I didn’t write it
:
Quaternionf Slerp(const Quaternionf& q1, const Quaternionf& q2, float t)
{
float dot = Dot(q1, q2);
// dot = cos(theta)
// if (dot < 0), q1 and q2 are more than 90 degrees apart,
// so we can invert one to reduce spinning
Quaternionf tmpQuat;
if (dot < 0.0f)
{
dot = -dot;
tmpQuat.Set(-q2.x,
-q2.y,
-q2.z,
-q2.w);
}
else
tmpQuat = q2;
if (dot < 0.95f)
{
float angle = acos(dot);
float sinadiv, sinat, sinaomt;
sinadiv = 1.0f / sin(angle);
sinat = sin(angle * t);
sinaomt = sin(angle * (1.0f - t));
tmpQuat.Set((q1.x * sinaomt + tmpQuat.x * sinat) * sinadiv,
(q1.y * sinaomt + tmpQuat.y * sinat) * sinadiv,
(q1.z * sinaomt + tmpQuat.z * sinat) * sinadiv,
(q1.w * sinaomt + tmpQuat.w * sinat) * sinadiv);
return tmpQuat;
}
// if the angle is small, use linear interpolation
else
{
return Lerp(q1, tmpQuat, t);
}
}