# Changeset 1807Tweet

Ignore:
Timestamp:
Aug 24, 2012, 12:51:48 PM (11 years ago)
Message:

math: improve slerp implementation.

Location:
trunk/src
Files:
2 edited

Unmodified
Added
Removed
• ## trunk/src/lol/math/vector.h

 r1799 static Quat rotate(T angle, T x, T y, T z); static Quat rotate(T angle, Vec3 const &v); static Quat slerp(Quat QuatA,Quat QuatB, float const &Scalar); /* Convert from Euler angles. The axes in fromeuler_xyx are template static inline Quat operator /(Quat x, Quat const &y) static inline Quat operator /(Quat const &x, Quat const &y) { return x * re(y); } template extern Quat slerp(Quat const &qa, Quat const &qb, T f); /*
• ## trunk/src/math/vector.cpp

 r1804 } template<> quat quat::slerp(quat QuatA, quat QuatB, float const &Scalar) { float magnitude = lol::sqrt(sqlength(QuatA) * sqlength(QuatB)); //btAssert(magnitude > btScalar(0)); float product = lol::dot(QuatA,QuatB) / magnitude; if (product > -1.0f && product < 1.0f) { // Take care of long angle case see http://en.wikipedia.org/wiki/Slerp const float sign = (product < 0.0f) ? -1.0f : 1.0f; const float theta = lol::acos(sign * product); const float s1 = lol::sin(sign * Scalar * theta); const float d = 1.0f / lol::sin(theta); const float s0 = lol::sin((1.0f - Scalar) * theta); return quat( (QuatA.w * s0 + QuatB.w * s1) * d, (QuatA.x * s0 + QuatB.x * s1) * d, (QuatA.y * s0 + QuatB.y * s1) * d, (QuatA.z * s0 + QuatB.z * s1) * d); } else { return QuatA; } template<> quat slerp(quat const &qa, quat const &qb, float f) { float const magnitude = lol::sqrt(sqlength(qa) * sqlength(qb)); float const product = lol::dot(qa, qb) / magnitude; /* If quaternions are equal or opposite, there is no need * to slerp anything, just return qa. */ if (std::abs(product) >= 1.0f) return qa; float const sign = (product < 0.0f) ? -1.0f : 1.0f; float const theta = lol::acos(sign * product); float const s1 = lol::sin(sign * f * theta); float const s0 = lol::sin((1.0f - f) * theta); /* This is the same as 1/sin(theta) */ float const d = 1.0f / lol::sqrt(1.f - product * product); return qa * (s0 * d) + qb * (s1 * d); }
Note: See TracChangeset for help on using the changeset viewer.