From e1e69c49b7727223a43cdc2deac4f1c03a3e3aba Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Sat, 16 Jun 2018 15:23:01 +0300 Subject: [PATCH] Fix matrix interpolation parameter calculation 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 | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/source/animation.cpp b/source/animation.cpp index e633aae5..c7e23b8e 100644 --- a/source/animation.cpp +++ b/source/animation.cpp @@ -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; -- 2.43.0