]> git.tdb.fi Git - libs/gl.git/commitdiff
Fix matrix interpolation parameter calculation
authorMikko Rasa <tdb@tdb.fi>
Sat, 16 Jun 2018 12:23:01 +0000 (15:23 +0300)
committerMikko Rasa <tdb@tdb.fi>
Sat, 16 Jun 2018 12:23:01 +0000 (15:23 +0300)
With an x87 FPU and compiler optimizations enabled, the code could end up
taking arccos of a value very slightly larger than one.  This would result
in a NaN and destroy the matrix contents.

source/animation.cpp

index e633aae502dfc0fa59f938b3add23e5ef5357604..c7e23b8e3b26f8bda1332cafcf3efb3d3680845b 100644 (file)
@@ -116,18 +116,19 @@ Animation::AxisInterpolation::AxisInterpolation():
 Animation::AxisInterpolation::AxisInterpolation(const float *axis1, const float *axis2)
 {
        // Compute a normalized vector halfway between the two endpoints
-       float half[3];
        float a1_len = 0;
        float h_len = 0;
+       float cos_half = 0;
        for(unsigned i=0; i<3; ++i)
        {
-               half[i] = (axis1[i]+axis2[i])/2;
+               float half_i = (axis1[i]+axis2[i])/2;
+               cos_half += axis1[i]*half_i;
                a1_len += axis1[i]*axis1[i];
-               h_len += half[i]*half[i];
+               h_len += half_i*half_i;
        }
 
        // Compute correction factors for smooth interpolation
-       float cos_half = (axis1[0]*half[0]+axis1[1]*half[1]+axis1[2]*half[2])/sqrt(a1_len*h_len);
+       cos_half = min(max(cos_half/sqrt(a1_len*h_len), -1.0f), 1.0f);
        float angle = acos(cos_half);
        slope = (angle ? angle/tan(angle) : 1);
        scale = cos_half;