From 2728290ffbeb6e95ed9db0343a80a42a69d755f8 Mon Sep 17 00:00:00 2001 From: "U-GAPOS\\andrew" Date: Tue, 26 Jan 2016 09:37:33 -0800 Subject: [PATCH] fix bug in IK and tune head/neck constraints --- .../animation/src/AnimInverseKinematics.cpp | 60 ++++++++++++------- 1 file changed, 38 insertions(+), 22 deletions(-) diff --git a/libraries/animation/src/AnimInverseKinematics.cpp b/libraries/animation/src/AnimInverseKinematics.cpp index 415ee72d7b..e47a12960e 100644 --- a/libraries/animation/src/AnimInverseKinematics.cpp +++ b/libraries/animation/src/AnimInverseKinematics.cpp @@ -153,7 +153,6 @@ void AnimInverseKinematics::solveWithCyclicCoordinateDescent(const std::vectorgetParentIndex(tipIndex); if (pivotIndex == -1 || pivotIndex == _hipsIndex) { @@ -165,12 +164,30 @@ void AnimInverseKinematics::solveWithCyclicCoordinateDescent(const std::vectorapply(tipRelativeRotation); + if (constrained) { + tipOrientation = glm::normalize(tipRelativeRotation * tipParentOrientation); + } + } + } + + // cache tip absolute position + glm::vec3 tipPosition = absolutePoses[tipIndex].trans; // descend toward root, pivoting each joint to get tip closer to target while (pivotIndex != _hipsIndex && pivotsParentIndex != -1) { @@ -201,9 +218,9 @@ void AnimInverseKinematics::solveWithCyclicCoordinateDescent(const std::vectorapply(newRot); if (constrained) { - // the constraint will modify the movement of the tip so we have to compute the modified - // model-frame deltaRotation + // the constraint will modify the local rotation of the tip so we must + // compute the corresponding model-frame deltaRotation // Q' = Qp^ * dQ * Q --> dQ = Qp * Q' * Q^ deltaRotation = absolutePoses[pivotsParentIndex].rot * - newRot * - glm::inverse(absolutePoses[pivotIndex].rot); + newRot * glm::inverse(absolutePoses[pivotIndex].rot); } } @@ -264,8 +280,8 @@ void AnimInverseKinematics::solveWithCyclicCoordinateDescent(const std::vectorgetParentIndex(pivotIndex); @@ -629,11 +645,11 @@ void AnimInverseKinematics::initConstraints() { } else if (0 == baseName.compare("Neck", Qt::CaseInsensitive)) { SwingTwistConstraint* stConstraint = new SwingTwistConstraint(); stConstraint->setReferenceRotation(_defaultRelativePoses[i].rot); - const float MAX_NECK_TWIST = PI / 4.0f; + const float MAX_NECK_TWIST = PI / 6.0f; stConstraint->setTwistLimits(-MAX_NECK_TWIST, MAX_NECK_TWIST); std::vector minDots; - const float MAX_NECK_SWING = PI / 3.0f; + const float MAX_NECK_SWING = PI / 4.0f; minDots.push_back(cosf(MAX_NECK_SWING)); stConstraint->setSwingLimits(minDots); @@ -641,11 +657,11 @@ void AnimInverseKinematics::initConstraints() { } else if (0 == baseName.compare("Head", Qt::CaseInsensitive)) { SwingTwistConstraint* stConstraint = new SwingTwistConstraint(); stConstraint->setReferenceRotation(_defaultRelativePoses[i].rot); - const float MAX_HEAD_TWIST = PI / 4.0f; + const float MAX_HEAD_TWIST = PI / 8.0f; stConstraint->setTwistLimits(-MAX_HEAD_TWIST, MAX_HEAD_TWIST); std::vector minDots; - const float MAX_HEAD_SWING = PI / 4.0f; + const float MAX_HEAD_SWING = PI / 6.0f; minDots.push_back(cosf(MAX_HEAD_SWING)); stConstraint->setSwingLimits(minDots);