From df21fffa4a9b30b2311e3cfbc731e4c21947095b Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Tue, 16 Feb 2016 17:31:39 -0800 Subject: [PATCH 1/3] AnimInverseKinematics: fix for extra twist in lowerSpine joints. * When computing tipPosition, for the next iteration of the CCD, use the leverArm before it's projected onto the lowerSpine twist axis. * fix for acos() that was going outside of valid domain. (-1.0, 1.0) --- libraries/animation/src/AnimInverseKinematics.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libraries/animation/src/AnimInverseKinematics.cpp b/libraries/animation/src/AnimInverseKinematics.cpp index e3271037e0..af7fdb1fa7 100644 --- a/libraries/animation/src/AnimInverseKinematics.cpp +++ b/libraries/animation/src/AnimInverseKinematics.cpp @@ -278,8 +278,8 @@ int AnimInverseKinematics::solveTargetWithCCD(const IKTarget& target, AnimPoseVe if (axisLength > MIN_AXIS_LENGTH) { // compute angle of rotation that brings tip closer to target axis /= axisLength; - float angle = acosf(glm::dot(leverArm, targetLine) / (glm::length(leverArm) * glm::length(targetLine))); - + float cos_angle = std::min(std::max(glm::dot(leverArm, targetLine) / (glm::length(leverArm) * glm::length(targetLine)), -1.0f), 1.0f); + float angle = acosf(cos_angle); const float MIN_ADJUSTMENT_ANGLE = 1.0e-4f; if (angle > MIN_ADJUSTMENT_ANGLE) { // reduce angle by a fraction (for stability) @@ -348,7 +348,7 @@ int AnimInverseKinematics::solveTargetWithCCD(const IKTarget& target, AnimPoseVe } // keep track of tip's new transform as we descend towards root - tipPosition = jointPosition + deltaRotation * leverArm; + tipPosition = jointPosition + deltaRotation * (tipPosition - jointPosition); tipOrientation = glm::normalize(deltaRotation * tipOrientation); tipParentOrientation = glm::normalize(deltaRotation * tipParentOrientation); From b5a72225db175d8ee552322a09a77e7d6a9fd687 Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Tue, 16 Feb 2016 17:42:51 -0800 Subject: [PATCH 2/3] AnimInverseKinematics: renamed variable for extra style points --- libraries/animation/src/AnimInverseKinematics.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/animation/src/AnimInverseKinematics.cpp b/libraries/animation/src/AnimInverseKinematics.cpp index af7fdb1fa7..4402bf266a 100644 --- a/libraries/animation/src/AnimInverseKinematics.cpp +++ b/libraries/animation/src/AnimInverseKinematics.cpp @@ -278,8 +278,8 @@ int AnimInverseKinematics::solveTargetWithCCD(const IKTarget& target, AnimPoseVe if (axisLength > MIN_AXIS_LENGTH) { // compute angle of rotation that brings tip closer to target axis /= axisLength; - float cos_angle = std::min(std::max(glm::dot(leverArm, targetLine) / (glm::length(leverArm) * glm::length(targetLine)), -1.0f), 1.0f); - float angle = acosf(cos_angle); + float cosAngle = std::min(std::max(glm::dot(leverArm, targetLine) / (glm::length(leverArm) * glm::length(targetLine)), -1.0f), 1.0f); + float angle = acosf(cosAngle); const float MIN_ADJUSTMENT_ANGLE = 1.0e-4f; if (angle > MIN_ADJUSTMENT_ANGLE) { // reduce angle by a fraction (for stability) From 2d1304e0703420490210c65eebcc746a2d35881f Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Tue, 16 Feb 2016 18:00:45 -0800 Subject: [PATCH 3/3] AnimInverseKinematics: use glm::clamp for clarity. --- libraries/animation/src/AnimInverseKinematics.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/animation/src/AnimInverseKinematics.cpp b/libraries/animation/src/AnimInverseKinematics.cpp index 4402bf266a..ff1dea3d48 100644 --- a/libraries/animation/src/AnimInverseKinematics.cpp +++ b/libraries/animation/src/AnimInverseKinematics.cpp @@ -278,7 +278,7 @@ int AnimInverseKinematics::solveTargetWithCCD(const IKTarget& target, AnimPoseVe if (axisLength > MIN_AXIS_LENGTH) { // compute angle of rotation that brings tip closer to target axis /= axisLength; - float cosAngle = std::min(std::max(glm::dot(leverArm, targetLine) / (glm::length(leverArm) * glm::length(targetLine)), -1.0f), 1.0f); + float cosAngle = glm::clamp(glm::dot(leverArm, targetLine) / (glm::length(leverArm) * glm::length(targetLine)), -1.0f, 1.0f); float angle = acosf(cosAngle); const float MIN_ADJUSTMENT_ANGLE = 1.0e-4f; if (angle > MIN_ADJUSTMENT_ANGLE) {