diff --git a/libraries/animation/src/AnimInverseKinematics.cpp b/libraries/animation/src/AnimInverseKinematics.cpp index 2fd52ee036..095e8333ee 100644 --- a/libraries/animation/src/AnimInverseKinematics.cpp +++ b/libraries/animation/src/AnimInverseKinematics.cpp @@ -22,6 +22,7 @@ #include "AnimationLogging.h" #include "CubicHermiteSpline.h" #include "AnimUtil.h" +#include "AnimSkeleton.h" static const int MAX_TARGET_MARKERS = 30; static const float JOINT_CHAIN_INTERP_TIME = 0.5f; @@ -66,7 +67,7 @@ AnimInverseKinematics::IKTargetVar::IKTargetVar(const QString& jointNameIn, cons poleVectorVar(poleVectorVarIn), weight(weightIn), numFlexCoefficients(flexCoefficientsIn.size()), - jointIndex(-1) + jointIndex(AnimSkeleton::INVALID_JOINT_INDEX) { numFlexCoefficients = std::min(numFlexCoefficients, (size_t)MAX_FLEX_COEFFICIENTS); for (size_t i = 0; i < numFlexCoefficients; i++) { @@ -172,14 +173,14 @@ bool debounceJointWarnings() { void AnimInverseKinematics::computeTargets(const AnimVariantMap& animVars, std::vector& targets, const AnimPoseVec& underPoses) { - _hipsTargetIndex = -1; + _hipsTargetIndex = AnimSkeleton::INVALID_JOINT_INDEX; targets.reserve(_targetVarVec.size()); for (auto& targetVar : _targetVarVec) { // update targetVar jointIndex cache - if (targetVar.jointIndex == -1) { + if (targetVar.jointIndex == AnimSkeleton::INVALID_JOINT_INDEX) { int jointIndex = _skeleton->nameToJointIndex(targetVar.jointName); if (jointIndex >= 0) { // this targetVar has a valid joint --> cache the indices @@ -190,7 +191,7 @@ void AnimInverseKinematics::computeTargets(const AnimVariantMap& animVars, std:: } IKTarget target; - if (targetVar.jointIndex != -1) { + if (targetVar.jointIndex != AnimSkeleton::INVALID_JOINT_INDEX) { target.setType(animVars.lookup(targetVar.typeVar, (int)IKTarget::Type::RotationAndPosition)); target.setIndex(targetVar.jointIndex); if (target.getType() != IKTarget::Type::Unknown) { @@ -329,7 +330,7 @@ void AnimInverseKinematics::solve(const AnimContext& context, const std::vector< // update the absolutePoses for (int i = 0; i < (int)_relativePoses.size(); ++i) { auto parentIndex = _skeleton->getParentIndex((int)i); - if (parentIndex != -1) { + if (parentIndex != AnimSkeleton::INVALID_JOINT_INDEX) { absolutePoses[i] = absolutePoses[parentIndex] * _relativePoses[i]; } } @@ -351,12 +352,12 @@ void AnimInverseKinematics::solve(const AnimContext& context, const std::vector< // finally set the relative rotation of each tip to agree with absolute target rotation for (auto& target: targets) { int tipIndex = target.getIndex(); - int parentIndex = (tipIndex >= 0) ? _skeleton->getParentIndex(tipIndex) : -1; + int parentIndex = (tipIndex >= 0) ? _skeleton->getParentIndex(tipIndex) : AnimSkeleton::INVALID_JOINT_INDEX; int chainIndex = targetToChainMap[tipIndex]; bool needsInterpolation = _prevJointChainInfoVec[chainIndex].timer > 0.0f; float alpha = needsInterpolation ? getInterpolationAlpha(_prevJointChainInfoVec[chainIndex].timer) : 0.0f; // update rotationOnly targets that don't lie on the ik chain of other ik targets. - if (parentIndex != -1 && !_rotationAccumulators[tipIndex].isDirty() && + if (parentIndex != AnimSkeleton::INVALID_JOINT_INDEX && !_rotationAccumulators[tipIndex].isDirty() && (target.getType() == IKTarget::Type::RotationOnly || target.getType() == IKTarget::Type::Unknown)) { if (target.getType() == IKTarget::Type::RotationOnly) { const glm::quat& targetRotation = target.getRotation(); @@ -434,11 +435,11 @@ void AnimInverseKinematics::solveTargetWithCCD(const AnimContext& context, const int tipIndex = target.getIndex(); int pivotIndex = _skeleton->getParentIndex(tipIndex); - if (pivotIndex == -1 || pivotIndex == _hipsIndex) { + if (pivotIndex == AnimSkeleton::INVALID_JOINT_INDEX || pivotIndex == _hipsIndex) { return; } int pivotsParentIndex = _skeleton->getParentIndex(pivotIndex); - if (pivotsParentIndex == -1) { + if (pivotsParentIndex == AnimSkeleton::INVALID_JOINT_INDEX) { // TODO?: handle case where tip's parent is root? return; } @@ -485,7 +486,7 @@ void AnimInverseKinematics::solveTargetWithCCD(const AnimContext& context, const chainDepth++; // descend toward root, pivoting each joint to get tip closer to target position - while (pivotIndex != _hipsIndex && pivotsParentIndex != -1) { + while (pivotIndex != _hipsIndex && pivotsParentIndex != AnimSkeleton::INVALID_JOINT_INDEX) { assert(chainDepth < jointChainInfoOut.jointInfoVec.size()); @@ -579,12 +580,12 @@ void AnimInverseKinematics::solveTargetWithCCD(const AnimContext& context, const if (target.getPoleVectorEnabled()) { int topJointIndex = target.getIndex(); int midJointIndex = _skeleton->getParentIndex(topJointIndex); - if (midJointIndex != -1) { + if (midJointIndex != AnimSkeleton::INVALID_JOINT_INDEX) { int baseJointIndex = _skeleton->getParentIndex(midJointIndex); - if (baseJointIndex != -1) { + if (baseJointIndex != AnimSkeleton::INVALID_JOINT_INDEX) { int baseParentJointIndex = _skeleton->getParentIndex(baseJointIndex); AnimPose topPose, midPose, basePose; - int topChainIndex = -1, baseChainIndex = -1; + int topChainIndex = AnimSkeleton::INVALID_JOINT_INDEX, baseChainIndex = AnimSkeleton::INVALID_JOINT_INDEX; const size_t MAX_CHAIN_DEPTH = 30; AnimPose postAbsPoses[MAX_CHAIN_DEPTH]; AnimPose accum = absolutePoses[_hipsIndex]; @@ -756,7 +757,7 @@ void AnimInverseKinematics::computeAndCacheSplineJointInfosForIKTarget(const Ani int index = target.getIndex(); int endIndex = _skeleton->getParentIndex(_hipsIndex); - while (index != endIndex) { + while (index != endIndex && index != AnimSkeleton::INVALID_JOINT_INDEX) { AnimPose defaultPose = _skeleton->getAbsoluteDefaultPose(index); float ratio = glm::dot(defaultPose.trans() - basePose.trans(), baseToTipNormal) / baseToTipLength; @@ -1460,7 +1461,7 @@ void AnimInverseKinematics::setSkeletonInternal(AnimSkeleton::ConstPointer skele // invalidate all targetVars for (auto& targetVar: _targetVarVec) { - targetVar.jointIndex = -1; + targetVar.jointIndex = AnimSkeleton::INVALID_JOINT_INDEX; } for (auto& accumulator: _rotationAccumulators) { @@ -1480,18 +1481,18 @@ void AnimInverseKinematics::setSkeletonInternal(AnimSkeleton::ConstPointer skele if (_hipsIndex >= 0) { _hipsParentIndex = _skeleton->getParentIndex(_hipsIndex); } else { - _hipsParentIndex = -1; + _hipsParentIndex = AnimSkeleton::INVALID_JOINT_INDEX; } _leftHandIndex = _skeleton->nameToJointIndex("LeftHand"); _rightHandIndex = _skeleton->nameToJointIndex("RightHand"); } else { clearConstraints(); - _headIndex = -1; - _hipsIndex = -1; - _hipsParentIndex = -1; - _leftHandIndex = -1; - _rightHandIndex = -1; + _headIndex = AnimSkeleton::INVALID_JOINT_INDEX; + _hipsIndex = AnimSkeleton::INVALID_JOINT_INDEX; + _hipsParentIndex = AnimSkeleton::INVALID_JOINT_INDEX; + _leftHandIndex = AnimSkeleton::INVALID_JOINT_INDEX; + _rightHandIndex = AnimSkeleton::INVALID_JOINT_INDEX; } } @@ -1531,7 +1532,7 @@ void AnimInverseKinematics::debugDrawRelativePoses(const AnimContext& context) c // draw line to parent int parentIndex = _skeleton->getParentIndex(i); - if (parentIndex != -1) { + if (parentIndex != AnimSkeleton::INVALID_JOINT_INDEX) { glm::vec3 parentPos = transformPoint(geomToWorldMatrix, poses[parentIndex].trans()); DebugDraw::getInstance().drawRay(pos, parentPos, GRAY); } @@ -1580,7 +1581,7 @@ void AnimInverseKinematics::debugDrawIKChain(const JointChainInfo& jointChainInf DebugDraw::getInstance().drawRay(pos, pos + AXIS_LENGTH * zAxis, BLUE); // draw line to parent - if (parentIndex != -1) { + if (parentIndex != AnimSkeleton::INVALID_JOINT_INDEX) { glm::vec3 parentPos = transformPoint(geomToWorldMatrix, poses[parentIndex].trans()); glm::vec4 color = GRAY; @@ -1629,13 +1630,13 @@ void AnimInverseKinematics::debugDrawConstraints(const AnimContext& context) con // draw line to parent int parentIndex = _skeleton->getParentIndex(i); - if (parentIndex != -1) { + if (parentIndex != AnimSkeleton::INVALID_JOINT_INDEX) { glm::vec3 parentPos = transformPoint(geomToWorldMatrix, poses[parentIndex].trans()); DebugDraw::getInstance().drawRay(pos, parentPos, GRAY); } glm::quat parentAbsRot; - if (parentIndex != -1) { + if (parentIndex != AnimSkeleton::INVALID_JOINT_INDEX) { parentAbsRot = poses[parentIndex].rot(); } @@ -1733,7 +1734,7 @@ void AnimInverseKinematics::preconditionRelativePosesToAvoidLimbLock(const AnimC const float MIN_AXIS_LENGTH = 1.0e-4f; for (auto& target : targets) { - if (target.getIndex() != -1 && target.getType() == IKTarget::Type::RotationAndPosition) { + if (target.getIndex() != AnimSkeleton::INVALID_JOINT_INDEX && target.getType() == IKTarget::Type::RotationAndPosition) { for (int i = 0; i < NUM_LIMBS; i++) { if (limbs[i].first == target.getIndex()) { int tipIndex = limbs[i].first; diff --git a/libraries/animation/src/AnimSkeleton.cpp b/libraries/animation/src/AnimSkeleton.cpp index b26d00d8d0..bd338aae4a 100644 --- a/libraries/animation/src/AnimSkeleton.cpp +++ b/libraries/animation/src/AnimSkeleton.cpp @@ -66,7 +66,7 @@ int AnimSkeleton::nameToJointIndex(const QString& jointName) const { if (_jointIndicesByName.end() != itr) { return itr.value(); } - return -1; + return INVALID_JOINT_INDEX; } int AnimSkeleton::getNumJoints() const { @@ -80,7 +80,7 @@ int AnimSkeleton::getChainDepth(int jointIndex) const { do { chainDepth++; index = _parentIndices[index]; - } while (index != -1); + } while (index != INVALID_JOINT_INDEX); return chainDepth; } else { return 0; @@ -108,7 +108,7 @@ const AnimPose& AnimSkeleton::getPostRotationPose(int jointIndex) const { std::vector AnimSkeleton::getChildrenOfJoint(int jointIndex) const { // Children and grandchildren, etc. std::vector result; - if (jointIndex != -1) { + if (jointIndex != INVALID_JOINT_INDEX) { for (int i = jointIndex + 1; i < (int)_parentIndices.size(); i++) { if (_parentIndices[i] == jointIndex || (std::find(result.begin(), result.end(), _parentIndices[i]) != result.end())) { result.push_back(i); @@ -135,7 +135,7 @@ void AnimSkeleton::convertRelativePosesToAbsolute(AnimPoseVec& poses) const { int lastIndex = std::min((int)poses.size(), _jointsSize); for (int i = 0; i < lastIndex; ++i) { int parentIndex = _parentIndices[i]; - if (parentIndex != -1) { + if (parentIndex != INVALID_JOINT_INDEX) { poses[i] = poses[parentIndex] * poses[i]; } } @@ -146,7 +146,7 @@ void AnimSkeleton::convertAbsolutePosesToRelative(AnimPoseVec& poses) const { int lastIndex = std::min((int)poses.size(), _jointsSize); for (int i = lastIndex - 1; i >= 0; --i) { int parentIndex = _parentIndices[i]; - if (parentIndex != -1) { + if (parentIndex != INVALID_JOINT_INDEX) { poses[i] = poses[parentIndex].inverse() * poses[i]; } } @@ -157,7 +157,7 @@ void AnimSkeleton::convertRelativeRotationsToAbsolute(std::vector& ro int lastIndex = std::min((int)rotations.size(), _jointsSize); for (int i = 0; i < lastIndex; ++i) { int parentIndex = _parentIndices[i]; - if (parentIndex != -1) { + if (parentIndex != INVALID_JOINT_INDEX) { rotations[i] = rotations[parentIndex] * rotations[i]; } } @@ -168,7 +168,7 @@ void AnimSkeleton::convertAbsoluteRotationsToRelative(std::vector& ro int lastIndex = std::min((int)rotations.size(), _jointsSize); for (int i = lastIndex - 1; i >= 0; --i) { int parentIndex = _parentIndices[i]; - if (parentIndex != -1) { + if (parentIndex != INVALID_JOINT_INDEX) { rotations[i] = glm::inverse(rotations[parentIndex]) * rotations[i]; } } @@ -280,7 +280,7 @@ void AnimSkeleton::buildSkeletonFromJoints(const std::vector& joints, // so we can restore them after a future mirror operation _nonMirroredIndices.push_back(i); } - int mirrorJointIndex = -1; + int mirrorJointIndex = INVALID_JOINT_INDEX; if (_joints[i].name.startsWith("Left")) { QString mirrorJointName = QString(_joints[i].name).replace(0, 4, "Right"); mirrorJointIndex = nameToJointIndex(mirrorJointName); @@ -350,7 +350,7 @@ std::vector AnimSkeleton::lookUpJointIndices(const std::vector& jo result.reserve(jointNames.size()); for (auto& name : jointNames) { int index = nameToJointIndex(name); - if (index == -1) { + if (index == INVALID_JOINT_INDEX) { qWarning(animation) << "AnimSkeleton::lookUpJointIndices(): could not find bone with name " << name; } result.push_back(index); diff --git a/libraries/animation/src/AnimSkeleton.h b/libraries/animation/src/AnimSkeleton.h index efc1c1599f..e36ceb4042 100644 --- a/libraries/animation/src/AnimSkeleton.h +++ b/libraries/animation/src/AnimSkeleton.h @@ -30,6 +30,8 @@ public: const QString& getJointName(int jointIndex) const; int getNumJoints() const; int getChainDepth(int jointIndex) const; + + static const int INVALID_JOINT_INDEX { -1 }; // the default poses are the orientations of the joints on frame 0. const AnimPose& getRelativeDefaultPose(int jointIndex) const;