From 4f2e57a5410c13ccf63532cdc0e67a299ba2410d Mon Sep 17 00:00:00 2001 From: Kester Maddock Date: Sun, 9 Jan 2005 00:06:45 +0000 Subject: Fix bug #2006: Floating point imprecision made MT_Quaternion::angle return NaN, since acos(x) is NaN for |x| > 1. Because of the way NaN's propagate through float math, the view pos would be set to [NaN, NaN, NaN] resulting in a grey screen. --- intern/moto/include/MT_Quaternion.inl | 10 ++++++++-- intern/moto/include/MT_Scalar.h | 8 ++++++++ 2 files changed, 16 insertions(+), 2 deletions(-) (limited to 'intern/moto') diff --git a/intern/moto/include/MT_Quaternion.inl b/intern/moto/include/MT_Quaternion.inl index 8b4fbc93c41..ecfd6699f67 100644 --- a/intern/moto/include/MT_Quaternion.inl +++ b/intern/moto/include/MT_Quaternion.inl @@ -64,13 +64,19 @@ GEN_INLINE MT_Scalar MT_Quaternion::angle(const MT_Quaternion& q) const { MT_Scalar s = sqrt(length2() * q.length2()); assert(s != MT_Scalar(0.0)); - return acos(dot(q) / s); + + s = dot(q) / s; + + s = MT_clamp(s, -1.0, 1.0); + + return acos(s); } GEN_INLINE MT_Quaternion MT_Quaternion::slerp(const MT_Quaternion& q, const MT_Scalar& t) const { MT_Scalar theta = angle(q); - if (theta != MT_Scalar(0.0)) + + if (!MT_fuzzyZero(theta)) { MT_Scalar d = MT_Scalar(1.0) / sin(theta); MT_Scalar s0 = sin((MT_Scalar(1.0) - t) * theta); diff --git a/intern/moto/include/MT_Scalar.h b/intern/moto/include/MT_Scalar.h index 0a72a52c20e..6ee0948f244 100755 --- a/intern/moto/include/MT_Scalar.h +++ b/intern/moto/include/MT_Scalar.h @@ -83,5 +83,13 @@ inline MT_Scalar MT_random() { return MT_Scalar(MT_rand()) / MT_Scalar(MT_RAND_MAX); } +inline MT_Scalar MT_clamp(const MT_Scalar x, const MT_Scalar min, const MT_Scalar max) +{ + if (x < min) + return min; + else if (x > max) + return max; + return x; +} #endif -- cgit v1.2.3