From 3fa3cd8cfdb9be2ec3f4d1c160e000a35c9cceb8 Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Wed, 8 Aug 2018 13:44:26 -0700 Subject: [PATCH] In CCD IK chains, remove the LeftHand and RightHand constraint completely. When used in combination with the elbow pole vector, this was causing the hand to never properly reach its rotation target. It was also having side effects causing the elbow to never straighten properly to reach its position target. There is possibly a bug in how this tip constraint is enforced and I've verified that there are no ill effects in removing it. --- .../animation/src/AnimInverseKinematics.cpp | 66 +------------------ 1 file changed, 1 insertion(+), 65 deletions(-) diff --git a/libraries/animation/src/AnimInverseKinematics.cpp b/libraries/animation/src/AnimInverseKinematics.cpp index c8d36db58f..71094cc6e1 100644 --- a/libraries/animation/src/AnimInverseKinematics.cpp +++ b/libraries/animation/src/AnimInverseKinematics.cpp @@ -481,29 +481,6 @@ void AnimInverseKinematics::solveTargetWithCCD(const AnimContext& context, const // reduce angle by a flexCoefficient angle *= target.getFlexCoefficient(chainDepth); deltaRotation = glm::angleAxis(angle, axis); - - // The swing will re-orient the tip but there will tend to be be a non-zero delta between the tip's - // new orientation and its target. This is the final parent-relative orientation that the tip joint have - // make to achieve its target orientation. - glm::quat tipRelativeRotation = glm::inverse(deltaRotation * tipParentOrientation) * target.getRotation(); - - // enforce tip's constraint - RotationConstraint* constraint = getConstraint(tipIndex); - if (constraint) { - bool constrained = constraint->apply(tipRelativeRotation); - if (constrained) { - // The tip's final parent-relative rotation would violate its constraint - // so we try to pre-twist this pivot to compensate. - glm::quat constrainedTipRotation = deltaRotation * tipParentOrientation * tipRelativeRotation; - glm::quat missingRotation = target.getRotation() * glm::inverse(constrainedTipRotation); - glm::quat swingPart; - glm::quat twistPart; - glm::vec3 axis = glm::normalize(deltaRotation * leverArm); - swingTwistDecomposition(missingRotation, axis, swingPart, twistPart); - const float LIMIT_LEAK_FRACTION = 0.1f; - deltaRotation = safeLerp(glm::quat(), twistPart, LIMIT_LEAK_FRACTION); - } - } } } } else if (targetType == IKTarget::Type::HmdHead) { @@ -1255,48 +1232,7 @@ void AnimInverseKinematics::initConstraints() { constraint = static_cast(stConstraint); } else if (0 == baseName.compare("Hand", Qt::CaseSensitive)) { - SwingTwistConstraint* stConstraint = new SwingTwistConstraint(); - stConstraint->setReferenceRotation(_defaultRelativePoses[i].rot()); - stConstraint->setTwistLimits(0.0f, 0.0f); // max == min, disables twist limits - - /* KEEP THIS CODE for future experimentation -- twist limits for hands - const float MAX_HAND_TWIST = 3.0f * PI / 5.0f; - const float MIN_HAND_TWIST = -PI / 2.0f; - if (isLeft) { - stConstraint->setTwistLimits(-MAX_HAND_TWIST, -MIN_HAND_TWIST); - } else { - stConstraint->setTwistLimits(MIN_HAND_TWIST, MAX_HAND_TWIST); - } - */ - - /* KEEP THIS CODE for future experimentation -- non-symmetrical swing limits for wrist - * a more complicated wrist with asymmetric cone - // these directions are approximate swing limits in parent-frame - // NOTE: they don't need to be normalized - std::vector swungDirections; - swungDirections.push_back(glm::vec3(1.0f, 1.0f, 0.0f)); - swungDirections.push_back(glm::vec3(0.75f, 1.0f, -1.0f)); - swungDirections.push_back(glm::vec3(-0.75f, 1.0f, -1.0f)); - swungDirections.push_back(glm::vec3(-1.0f, 1.0f, 0.0f)); - swungDirections.push_back(glm::vec3(-0.75f, 1.0f, 1.0f)); - swungDirections.push_back(glm::vec3(0.75f, 1.0f, 1.0f)); - - // rotate directions into joint-frame - glm::quat invRelativeRotation = glm::inverse(_defaultRelativePoses[i].rot); - int numDirections = (int)swungDirections.size(); - for (int j = 0; j < numDirections; ++j) { - swungDirections[j] = invRelativeRotation * swungDirections[j]; - } - stConstraint->setSwingLimits(swungDirections); - */ - - // simple cone - std::vector minDots; - const float MAX_HAND_SWING = PI / 2.0f; - minDots.push_back(cosf(MAX_HAND_SWING)); - stConstraint->setSwingLimits(minDots); - - constraint = static_cast(stConstraint); + // hand/wrist constraints have been disabled. } else if (baseName.startsWith("Shoulder", Qt::CaseSensitive)) { SwingTwistConstraint* stConstraint = new SwingTwistConstraint(); stConstraint->setReferenceRotation(_defaultRelativePoses[i].rot());