diff --git a/quaternion.cpp b/quaternion.cpp index 743a0538..df2b9a2f 100644 --- a/quaternion.cpp +++ b/quaternion.cpp @@ -104,6 +104,49 @@ quaternion::operator- () const noexcept } +/////////////////////////////////////////////////////////////////////////////// +template +quaternion +cruft::slerp (quaternion a, quaternion b, T t) +{ + // calc cosine theta + T cosine = dot (a, b); + + // adjust signs (if necessary) + if (cosine < 0) { + cosine = -cosine; + b = -b; + } + + // Calculate coefficients + T p, q; + if (T(0.9995) > cosine) { + T omega = std::acos (cosine); // extract theta from dot product's cos theta + T sine = std::sin (omega); + + p = std::sin ((1 - t) * omega) / sine; + q = std::sin ( t * omega) / sine; + } else { + // Very close, do linear interp (because it's faster) + p = 1 - t; + q = t; + } + + return a * p + b * q; +} + + +//----------------------------------------------------------------------------- +template +quaternion +cruft::nlerp (cruft::quaternion a, cruft::quaternion b, T t) +{ + return cruft::normalised ( + cruft::mix (a, b, t) + ); +} + + /////////////////////////////////////////////////////////////////////////////// template quaternion @@ -311,6 +354,8 @@ namespace cruft::debug { /////////////////////////////////////////////////////////////////////////////// #define INSTANTIATE(T) \ template cruft::vector3 cruft::rotate (cruft::vector3, cruft::quaternion); \ +template quaternion cruft::slerp (quaternion, quaternion, T); \ +template quaternion cruft::nlerp (quaternion, quaternion, T); \ template quaternion cruft::conjugate (quaternion); \ template quaternion cruft::operator* (quaternion, quaternion); \ template quaternion& cruft::operator*= (quaternion&, quaternion); \ diff --git a/quaternion.hpp b/quaternion.hpp index 1a843007..1d89a016 100644 --- a/quaternion.hpp +++ b/quaternion.hpp @@ -141,6 +141,18 @@ namespace cruft { } + /////////////////////////////////////////////////////////////////////////// + template + quaternion + slerp (quaternion a, quaternion b, T t); + + + //------------------------------------------------------------------------- + template + quaternion + nlerp (quaternion a, quaternion b, T t); + + /////////////////////////////////////////////////////////////////////////// template quaternion