Quaternion.cpp 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  1. #include "Quaternion.h"
  2. USING_NS_BF;
  3. Quaternion Beefy::operator* (float fScalar, const Quaternion& rkQ)
  4. {
  5. return Quaternion(fScalar*rkQ.mX, fScalar*rkQ.mY, fScalar*rkQ.mZ, fScalar*rkQ.mW);
  6. }
  7. Beefy::Quaternion Beefy::Quaternion::Slerp(float fT, const Quaternion& rkP, const Quaternion& rkQ, bool shortestPath)
  8. {
  9. float fCos = Dot(rkP, rkQ);
  10. Quaternion rkT;
  11. // Do we need to invert rotation?
  12. if (fCos < 0.0f && shortestPath)
  13. {
  14. fCos = -fCos;
  15. rkT = -rkQ;
  16. }
  17. else
  18. {
  19. rkT = rkQ;
  20. }
  21. if ((fabs(fCos) < 1.0f - BF_MS_EPSILON) && (false))
  22. {
  23. // Standard case (slerp)
  24. float fSin = sqrtf(1.0f - (fCos * fCos));
  25. float fAngle = atan2f(fSin, fCos);
  26. float fInvSin = 1.0f / fSin;
  27. float fCoeff0 = sinf((1.0f - fT) * fAngle) * fInvSin;
  28. float fCoeff1 = sinf(fT * fAngle) * fInvSin;
  29. return fCoeff0 * rkP + fCoeff1 * rkT;
  30. }
  31. else
  32. {
  33. // There are two situations:
  34. // 1. "rkP" and "rkQ" are very close (fCos ~= +1), so we can do a linear
  35. // interpolation safely.
  36. // 2. "rkP" and "rkQ" are almost inverse of each other (fCos ~= -1), there
  37. // are an infinite number of possibilities interpolation. but we haven't
  38. // have method to fix this case, so just use linear interpolation here.
  39. Quaternion t = (1.0f - fT) * rkP + fT * rkT;
  40. // taking the complement requires renormalisation
  41. t = Normalise(t);
  42. //OutputDebugStrF("%0.3f %0.3f %0.3f %0.3f\n", t.mX, t.mY, t.mZ, t.mW);
  43. return t;
  44. //return (fT < 0.5f) ? rkP : rkQ;
  45. }
  46. }