Fix bug #2006:
authorKester Maddock <Christopher.Maddock.1@uni.massey.ac.nz>
Sun, 9 Jan 2005 00:06:45 +0000 (00:06 +0000)
committerKester Maddock <Christopher.Maddock.1@uni.massey.ac.nz>
Sun, 9 Jan 2005 00:06:45 +0000 (00:06 +0000)
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
intern/moto/include/MT_Scalar.h

index 8b4fbc93c41dae9ae62ee74ba09b4ad5571e1477..ecfd6699f67eafc23d34f3b23bdebce851116f9a 100644 (file)
@@ -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);
index 0a72a52c20edb7401192b176c980c8c4e55a5ad9..6ee0948f24408ac855609406f885ed26345ed600 100755 (executable)
@@ -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