From 2679a3a30d554805914ae974907a359d03d53748 Mon Sep 17 00:00:00 2001 From: Angus Antley Date: Sun, 27 Jan 2019 16:30:13 -0800 Subject: [PATCH] changed the naming of the middle joint from secondary target to midJoint, also generalized the handling of the neck head rotation after the middle spline is updated --- .../avatar-animation_withSplineIKNode.json | 6 +- libraries/animation/src/AnimNodeLoader.cpp | 13 ++-- libraries/animation/src/AnimSplineIK.cpp | 77 ++++++++----------- libraries/animation/src/AnimSplineIK.h | 13 +--- 4 files changed, 46 insertions(+), 63 deletions(-) diff --git a/interface/resources/avatar/avatar-animation_withSplineIKNode.json b/interface/resources/avatar/avatar-animation_withSplineIKNode.json index bd0baf473e..40572f698b 100644 --- a/interface/resources/avatar/avatar-animation_withSplineIKNode.json +++ b/interface/resources/avatar/avatar-animation_withSplineIKNode.json @@ -182,14 +182,14 @@ "enabled": false, "interpDuration": 15, "baseJointName": "Hips", + "midJointName": "Spine2", "tipJointName": "Head", - "secondaryTargetJointName": "Spine2", "basePositionVar": "hipsPosition", "baseRotationVar": "hipsRotation", + "midPositionVar": "spine2Position", + "midRotationVar": "spine2Rotation", "tipPositionVar": "headPosition", "tipRotationVar": "headRotation", - "secondaryTargetPositionVar": "spine2Position", - "secondaryTargetRotationVar": "spine2Rotation", "alphaVar": "splineIKAlpha", "enabledVar": "splineIKEnabled", "endEffectorRotationVarVar": "splineIKRotationVar", diff --git a/libraries/animation/src/AnimNodeLoader.cpp b/libraries/animation/src/AnimNodeLoader.cpp index bce242b50d..8a19b763bb 100644 --- a/libraries/animation/src/AnimNodeLoader.cpp +++ b/libraries/animation/src/AnimNodeLoader.cpp @@ -584,14 +584,14 @@ static AnimNode::Pointer loadSplineIKNode(const QJsonObject& jsonObj, const QStr READ_BOOL(enabled, jsonObj, id, jsonUrl, nullptr); READ_FLOAT(interpDuration, jsonObj, id, jsonUrl, nullptr); READ_STRING(baseJointName, jsonObj, id, jsonUrl, nullptr); + READ_STRING(midJointName, jsonObj, id, jsonUrl, nullptr); READ_STRING(tipJointName, jsonObj, id, jsonUrl, nullptr); - READ_STRING(secondaryTargetJointName, jsonObj, id, jsonUrl, nullptr); READ_STRING(basePositionVar, jsonObj, id, jsonUrl, nullptr); READ_STRING(baseRotationVar, jsonObj, id, jsonUrl, nullptr); + READ_STRING(midPositionVar, jsonObj, id, jsonUrl, nullptr); + READ_STRING(midRotationVar, jsonObj, id, jsonUrl, nullptr); READ_STRING(tipPositionVar, jsonObj, id, jsonUrl, nullptr); READ_STRING(tipRotationVar, jsonObj, id, jsonUrl, nullptr); - READ_STRING(secondaryTargetPositionVar, jsonObj, id, jsonUrl, nullptr); - READ_STRING(secondaryTargetRotationVar, jsonObj, id, jsonUrl, nullptr); READ_STRING(alphaVar, jsonObj, id, jsonUrl, nullptr); READ_STRING(enabledVar, jsonObj, id, jsonUrl, nullptr); READ_STRING(endEffectorRotationVarVar, jsonObj, id, jsonUrl, nullptr); @@ -600,11 +600,10 @@ static AnimNode::Pointer loadSplineIKNode(const QJsonObject& jsonObj, const QStr READ_STRING(secondaryFlexCoefficients, jsonObj, id, jsonUrl, nullptr); auto node = std::make_shared(id, alpha, enabled, interpDuration, - baseJointName, tipJointName, + baseJointName, midJointName, tipJointName, alphaVar, enabledVar, endEffectorRotationVarVar, endEffectorPositionVarVar, - basePositionVar, baseRotationVar, - tipPositionVar, tipRotationVar, secondaryTargetJointName, secondaryTargetPositionVar, - secondaryTargetRotationVar, primaryFlexCoefficients, secondaryFlexCoefficients); + basePositionVar, baseRotationVar, midPositionVar, midRotationVar, + tipPositionVar, tipRotationVar, primaryFlexCoefficients, secondaryFlexCoefficients); return node; } diff --git a/libraries/animation/src/AnimSplineIK.cpp b/libraries/animation/src/AnimSplineIK.cpp index b38850773d..27e295ffb0 100644 --- a/libraries/animation/src/AnimSplineIK.cpp +++ b/libraries/animation/src/AnimSplineIK.cpp @@ -19,16 +19,16 @@ static const float FRAMES_PER_SECOND = 30.0f; AnimSplineIK::AnimSplineIK(const QString& id, float alpha, bool enabled, float interpDuration, const QString& baseJointName, + const QString& midJointName, const QString& tipJointName, const QString& alphaVar, const QString& enabledVar, const QString& endEffectorRotationVarVar, const QString& endEffectorPositionVarVar, const QString& basePositionVar, const QString& baseRotationVar, + const QString& midPositionVar, + const QString& midRotationVar, const QString& tipPositionVar, const QString& tipRotationVar, - const QString& secondaryTargetJointName, - const QString& secondaryTargetPositionVar, - const QString& secondaryTargetRotationVar, const QString& primaryFlexCoefficients, const QString& secondaryFlexCoefficients) : AnimNode(AnimNode::Type::SplineIK, id), @@ -36,6 +36,7 @@ AnimSplineIK::AnimSplineIK(const QString& id, float alpha, bool enabled, float i _enabled(enabled), _interpDuration(interpDuration), _baseJointName(baseJointName), + _midJointName(midJointName), _tipJointName(tipJointName), _alphaVar(alphaVar), _enabledVar(enabledVar), @@ -45,11 +46,10 @@ AnimSplineIK::AnimSplineIK(const QString& id, float alpha, bool enabled, float i _prevEndEffectorPositionVar(), _basePositionVar(basePositionVar), _baseRotationVar(baseRotationVar), + _midPositionVar(midPositionVar), + _midRotationVar(midRotationVar), _tipPositionVar(tipPositionVar), - _tipRotationVar(tipRotationVar), - _secondaryTargetJointName(secondaryTargetJointName), - _secondaryTargetPositionVar(secondaryTargetPositionVar), - _secondaryTargetRotationVar(secondaryTargetRotationVar) + _tipRotationVar(tipRotationVar) { QStringList flexCoefficientsValues = primaryFlexCoefficients.split(',', QString::SkipEmptyParts); @@ -182,17 +182,17 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const qCDebug(animation) << "the orig target pose for head " << target.getPose(); jointChain.outputRelativePoses(_poses); - AnimPose afterSolveSecondaryTarget = _skeleton->getAbsolutePose(_secondaryTargetIndex, _poses); - glm::quat secondaryTargetRotation = animVars.lookupRigToGeometry(_secondaryTargetRotationVar, afterSolveSecondaryTarget.rot()); + AnimPose afterSolveSecondaryTarget = _skeleton->getAbsolutePose(_midJointIndex, _poses); + glm::quat secondaryTargetRotation = animVars.lookupRigToGeometry(_midRotationVar, afterSolveSecondaryTarget.rot()); updatedSecondaryTarget = AnimPose(secondaryTargetRotation, afterSolveSecondaryTarget.trans()); //updatedSecondaryTarget = AnimPose(afterSolveSecondaryTarget.rot(), afterSolveSecondaryTarget.trans()); } IKTarget secondaryTarget; computeAbsolutePoses(absolutePoses2); - if (_secondaryTargetIndex != -1) { + if (_midJointIndex != -1) { secondaryTarget.setType((int)IKTarget::Type::Spline); - secondaryTarget.setIndex(_secondaryTargetIndex); + secondaryTarget.setIndex(_midJointIndex); float weight2 = 1.0f; secondaryTarget.setPose(updatedSecondaryTarget.rot(), updatedSecondaryTarget.trans()); @@ -204,8 +204,17 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const AnimChain secondaryJointChain; AnimPose beforeSolveChestNeck; + int startJoint; + AnimPose correctJoint; if (_poses.size() > 0) { + // start at the tip + + for (startJoint = _tipJointIndex; _skeleton->getParentIndex(startJoint) != _midJointIndex; startJoint = _skeleton->getParentIndex(startJoint)) { + // find the child of the midJoint + } + correctJoint = _skeleton->getAbsolutePose(startJoint, _poses); + // fix this to deal with no neck AA beforeSolveChestNeck = _skeleton->getAbsolutePose(_skeleton->nameToJointIndex("Neck"), _poses); @@ -216,16 +225,19 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const // set the tip/head rotation to match the absolute rotation of the target. int tipParent = _skeleton->getParentIndex(_tipJointIndex); - int secondaryTargetParent = _skeleton->getParentIndex(_secondaryTargetIndex); + int secondaryTargetParent = _skeleton->getParentIndex(_midJointIndex); if ((secondaryTargetParent != -1) && (tipParent != -1) && (_poses.size() > 0)) { - AnimPose secondaryTargetPose(secondaryTarget.getRotation(), secondaryTarget.getTranslation()); - AnimPose neckAbsolute = _skeleton->getAbsolutePose(tipParent, _poses); - _poses[tipParent] = secondaryTargetPose.inverse() * beforeSolveChestNeck; + - AnimPose tipTarget(target.getRotation(),target.getTranslation()); - AnimPose tipRelativePose = _skeleton->getAbsolutePose(tipParent,_poses).inverse() * tipTarget; - _poses[_tipJointIndex] = tipRelativePose; + AnimPose secondaryTargetPose(secondaryTarget.getRotation(), secondaryTarget.getTranslation()); + //AnimPose neckAbsolute = _skeleton->getAbsolutePose(tipParent, _poses); + //_poses[tipParent] = secondaryTargetPose.inverse() * beforeSolveChestNeck; + _poses[startJoint] = secondaryTargetPose.inverse() * correctJoint; + + //AnimPose tipTarget(target.getRotation(),target.getTranslation()); + //AnimPose tipRelativePose = _skeleton->getAbsolutePose(tipParent,_poses).inverse() * tipTarget; + //_poses[_tipJointIndex] = tipRelativePose; } // compute chain @@ -311,12 +323,12 @@ void AnimSplineIK::lookUpIndices() { assert(_skeleton); // look up bone indices by name - std::vector indices = _skeleton->lookUpJointIndices({ _baseJointName, _tipJointName, _secondaryTargetJointName }); + std::vector indices = _skeleton->lookUpJointIndices({ _baseJointName, _tipJointName, _midJointName }); // cache the results _baseJointIndex = indices[0]; _tipJointIndex = indices[1]; - _secondaryTargetIndex = indices[2]; + _midJointIndex = indices[2]; if (_baseJointIndex != -1) { _baseParentJointIndex = _skeleton->getParentIndex(_baseJointIndex); @@ -362,7 +374,7 @@ static CubicHermiteSplineFunctorWithArcLength computeSplineFromTipAndBase(const void AnimSplineIK::solveTargetWithSpline(const AnimContext& context, const IKTarget& target, const AnimPoseVec& absolutePoses, bool debug, AnimChain& chainInfoOut) const { const int baseIndex = _baseJointIndex; - const int tipBaseIndex = _secondaryTargetIndex; + const int tipBaseIndex = _midJointIndex; // build spline from tip to base AnimPose tipPose = AnimPose(glm::vec3(1.0f), target.getRotation(), target.getTranslation()); @@ -556,29 +568,6 @@ void AnimSplineIK::loadPoses(const AnimPoseVec& poses) { } } - -void AnimSplineIK::setTargetVars(const QString& jointName, const QString& positionVar, const QString& rotationVar, - const QString& typeVar, const QString& weightVar, float weight, const std::vector& flexCoefficients, - const QString& poleVectorEnabledVar, const QString& poleReferenceVectorVar, const QString& poleVectorVar) { - /* - IKTargetVar targetVar(jointName, positionVar, rotationVar, typeVar, weightVar, weight, flexCoefficients, poleVectorEnabledVar, poleReferenceVectorVar, poleVectorVar); - - // if there are dups, last one wins. - bool found = false; - for (auto& targetVarIter : _targetVarVec) { - if (targetVarIter.jointName == jointName) { - targetVarIter = targetVar; - found = true; - break; - } - } - if (!found) { - // create a new entry - _targetVarVec.push_back(targetVar); - } - */ -} - void AnimSplineIK::beginInterp(InterpType interpType, const AnimChain& chain) { // capture the current poses in a snapshot. _snapshotChain = chain; diff --git a/libraries/animation/src/AnimSplineIK.h b/libraries/animation/src/AnimSplineIK.h index c6d435fd6b..b05c5f4849 100644 --- a/libraries/animation/src/AnimSplineIK.h +++ b/libraries/animation/src/AnimSplineIK.h @@ -60,15 +60,13 @@ protected: float _interpDuration; QString _baseJointName; QString _tipJointName; - QString _secondaryTargetJointName; + QString _midJointName; QString _basePositionVar; QString _baseRotationVar; + QString _midPositionVar; + QString _midRotationVar; QString _tipPositionVar; QString _tipRotationVar; - QString _secondaryTargetPositionVar; - QString _secondaryTargetRotationVar; - //QString _primaryFlexCoefficients; - //QString _secondaryFlexCoefficients; static const int MAX_NUMBER_FLEX_VARIABLES = 10; float _primaryFlexCoefficients[MAX_NUMBER_FLEX_VARIABLES]; @@ -78,7 +76,7 @@ protected: int _baseParentJointIndex { -1 }; int _baseJointIndex { -1 }; - int _secondaryTargetIndex { -1 }; + int _midJointIndex { -1 }; int _tipJointIndex { -1 }; int _headIndex { -1 }; int _hipsIndex { -1 }; @@ -110,9 +108,6 @@ protected: bool _lastEnableDebugDrawIKTargets{ false }; void AnimSplineIK::solveTargetWithSpline(const AnimContext& context, const IKTarget& target, const AnimPoseVec& absolutePoses, bool debug, AnimChain& chainInfoOut) const; - void AnimSplineIK::setTargetVars(const QString& jointName, const QString& positionVar, const QString& rotationVar, - const QString& typeVar, const QString& weightVar, float weight, const std::vector& flexCoefficients, - const QString& poleVectorEnabledVar, const QString& poleReferenceVectorVar, const QString& poleVectorVar); void computeAndCacheSplineJointInfosForIKTarget(const AnimContext& context, const IKTarget& target) const; const std::vector* findOrCreateSplineJointInfo(const AnimContext& context, const IKTarget& target) const; mutable std::map> _splineJointInfoMap;