From 3a140145ae607cf944c69d862ec03845eb101dba Mon Sep 17 00:00:00 2001 From: Clement Date: Tue, 31 Jul 2018 13:09:37 -0700 Subject: [PATCH 1/2] Fix angleBetween potential NaN return value --- libraries/shared/src/GLMHelpers.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/libraries/shared/src/GLMHelpers.cpp b/libraries/shared/src/GLMHelpers.cpp index 4be8ad0e41..b1780b3652 100644 --- a/libraries/shared/src/GLMHelpers.cpp +++ b/libraries/shared/src/GLMHelpers.cpp @@ -294,7 +294,13 @@ glm::vec3 safeEulerAngles(const glm::quat& q) { // Helper function returns the positive angle (in radians) between two 3D vectors float angleBetween(const glm::vec3& v1, const glm::vec3& v2) { - return acosf((glm::dot(v1, v2)) / (glm::length(v1) * glm::length(v2))); + float cosAngle = glm::dot(v1, v2) / (glm::length(v1) * glm::length(v2)); + // If v1 and v2 are colinear, then floating point rounding errors might cause + // cosAngle to be slightly higher than 1 or slightly lower than -1 + // which is are values for which acos is not defined and result in a NaN + // So we clamp the value to insure the value is in the correct range + cosAngle = glm::clamp(cosAngle, -1.0f, 1.0f); + return acosf(cosAngle); } // Helper function return the rotation from the first vector onto the second From 2dd70f1fcdea4481f295bf099d702f2ba8285d7d Mon Sep 17 00:00:00 2001 From: Clement Date: Wed, 1 Aug 2018 11:39:14 -0700 Subject: [PATCH 2/2] Warn against zero-length vectors --- libraries/shared/src/GLMHelpers.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/libraries/shared/src/GLMHelpers.cpp b/libraries/shared/src/GLMHelpers.cpp index b1780b3652..d324e5af10 100644 --- a/libraries/shared/src/GLMHelpers.cpp +++ b/libraries/shared/src/GLMHelpers.cpp @@ -294,7 +294,13 @@ glm::vec3 safeEulerAngles(const glm::quat& q) { // Helper function returns the positive angle (in radians) between two 3D vectors float angleBetween(const glm::vec3& v1, const glm::vec3& v2) { - float cosAngle = glm::dot(v1, v2) / (glm::length(v1) * glm::length(v2)); + float lengthFactor = glm::length(v1) * glm::length(v2); + + if (lengthFactor < EPSILON) { + qWarning() << "DANGER: don't supply zero-length vec3's as arguments"; + } + + float cosAngle = glm::dot(v1, v2) / lengthFactor; // If v1 and v2 are colinear, then floating point rounding errors might cause // cosAngle to be slightly higher than 1 or slightly lower than -1 // which is are values for which acos is not defined and result in a NaN