Changeset 1807
- Timestamp:
- Aug 24, 2012, 12:51:48 PM (11 years ago)
- Location:
- trunk/src
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/lol/math/vector.h
r1799 r1807 935 935 static Quat<T> rotate(T angle, T x, T y, T z); 936 936 static Quat<T> rotate(T angle, Vec3<T> const &v); 937 static Quat<T> slerp(Quat<T> QuatA,Quat<T> QuatB, float const &Scalar);938 937 939 938 /* Convert from Euler angles. The axes in fromeuler_xyx are … … 1020 1019 1021 1020 template<typename T> 1022 static inline Quat<T> operator /(Quat<T> x, Quat<T> const &y)1021 static inline Quat<T> operator /(Quat<T> const &x, Quat<T> const &y) 1023 1022 { 1024 1023 return x * re(y); 1025 1024 } 1025 1026 template<typename T> 1027 extern Quat<T> slerp(Quat<T> const &qa, Quat<T> const &qb, T f); 1026 1028 1027 1029 /* -
trunk/src/math/vector.cpp
r1804 r1807 487 487 } 488 488 489 template<> quat quat::slerp(quat QuatA, quat QuatB, float const &Scalar) 490 { 491 float magnitude = lol::sqrt(sqlength(QuatA) * sqlength(QuatB)); 492 //btAssert(magnitude > btScalar(0)); 493 494 float product = lol::dot(QuatA,QuatB) / magnitude; 495 if (product > -1.0f && product < 1.0f) 496 { 497 // Take care of long angle case see http://en.wikipedia.org/wiki/Slerp 498 const float sign = (product < 0.0f) ? -1.0f : 1.0f; 499 500 const float theta = lol::acos(sign * product); 501 const float s1 = lol::sin(sign * Scalar * theta); 502 const float d = 1.0f / lol::sin(theta); 503 const float s0 = lol::sin((1.0f - Scalar) * theta); 504 505 return quat( 506 (QuatA.w * s0 + QuatB.w * s1) * d, 507 (QuatA.x * s0 + QuatB.x * s1) * d, 508 (QuatA.y * s0 + QuatB.y * s1) * d, 509 (QuatA.z * s0 + QuatB.z * s1) * d); 510 } 511 else 512 { 513 return QuatA; 514 } 489 template<> quat slerp(quat const &qa, quat const &qb, float f) 490 { 491 float const magnitude = lol::sqrt(sqlength(qa) * sqlength(qb)); 492 float const product = lol::dot(qa, qb) / magnitude; 493 494 /* If quaternions are equal or opposite, there is no need 495 * to slerp anything, just return qa. */ 496 if (std::abs(product) >= 1.0f) 497 return qa; 498 499 float const sign = (product < 0.0f) ? -1.0f : 1.0f; 500 float const theta = lol::acos(sign * product); 501 float const s1 = lol::sin(sign * f * theta); 502 float const s0 = lol::sin((1.0f - f) * theta); 503 504 /* This is the same as 1/sin(theta) */ 505 float const d = 1.0f / lol::sqrt(1.f - product * product); 506 507 return qa * (s0 * d) + qb * (s1 * d); 515 508 } 516 509
Note: See TracChangeset
for help on using the changeset viewer.