From 84aa86b4645ed5437c970af80f6089e49459e7c1 Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Mon, 8 May 2017 18:07:45 -0700 Subject: [PATCH] Added animVar support for IK solutionSource. --- .../resources/avatar/avatar-animation.json | 2 + .../animation/src/AnimInverseKinematics.cpp | 9 +++-- .../animation/src/AnimInverseKinematics.h | 7 +++- libraries/animation/src/AnimNodeLoader.cpp | 37 +++++++++++++++++++ libraries/animation/src/Rig.cpp | 2 + 5 files changed, 52 insertions(+), 5 deletions(-) diff --git a/interface/resources/avatar/avatar-animation.json b/interface/resources/avatar/avatar-animation.json index 9efe3dd29b..eb8403634a 100644 --- a/interface/resources/avatar/avatar-animation.json +++ b/interface/resources/avatar/avatar-animation.json @@ -49,6 +49,8 @@ "id": "ik", "type": "inverseKinematics", "data": { + "solutionSource": "relaxToUnderPoses", + "solutionSourceVar": "solutionSource", "targets": [ { "jointName": "Hips", diff --git a/libraries/animation/src/AnimInverseKinematics.cpp b/libraries/animation/src/AnimInverseKinematics.cpp index bf05d9358c..513d770e64 100644 --- a/libraries/animation/src/AnimInverseKinematics.cpp +++ b/libraries/animation/src/AnimInverseKinematics.cpp @@ -399,6 +399,9 @@ const AnimPoseVec& AnimInverseKinematics::evaluate(const AnimVariantMap& animVar //virtual const AnimPoseVec& AnimInverseKinematics::overlay(const AnimVariantMap& animVars, const AnimContext& context, float dt, Triggers& triggersOut, const AnimPoseVec& underPoses) { + // allows solutionSource to be overridden by an animVar + auto solutionSource = animVars.lookup(_solutionSourceVar, (int)_solutionSource); + if (context.getEnableDebugDrawIKConstraints()) { debugDrawConstraints(context); } @@ -414,7 +417,7 @@ const AnimPoseVec& AnimInverseKinematics::overlay(const AnimVariantMap& animVars PROFILE_RANGE_EX(simulation_animation, "ik/relax", 0xffff00ff, 0); - initRelativePosesFromSolutionSource(underPoses); + initRelativePosesFromSolutionSource((SolutionSource)solutionSource, underPoses); if (!underPoses.empty()) { // Sometimes the underpose itself can violate the constraints. Rather than @@ -1135,8 +1138,8 @@ void AnimInverseKinematics::relaxToPoses(const AnimPoseVec& poses) { } } -void AnimInverseKinematics::initRelativePosesFromSolutionSource(const AnimPoseVec& underPoses) { - switch (_solutionSource) { +void AnimInverseKinematics::initRelativePosesFromSolutionSource(SolutionSource solutionSource, const AnimPoseVec& underPoses) { + switch (solutionSource) { default: case SolutionSource::RelaxToUnderPoses: relaxToPoses(underPoses); diff --git a/libraries/animation/src/AnimInverseKinematics.h b/libraries/animation/src/AnimInverseKinematics.h index 9b7c095e6b..a78662cbeb 100644 --- a/libraries/animation/src/AnimInverseKinematics.h +++ b/libraries/animation/src/AnimInverseKinematics.h @@ -48,10 +48,12 @@ public: RelaxToLimitCenterPoses, PreviousSolution, UnderPoses, - LimitCenterPoses + LimitCenterPoses, + NumSolutionSources, }; void setSolutionSource(SolutionSource solutionSource) { _solutionSource = solutionSource; } + void setSolutionSourceVar(const QString& solutionSourceVar) { _solutionSourceVar = solutionSourceVar; } protected: void computeTargets(const AnimVariantMap& animVars, std::vector& targets, const AnimPoseVec& underPoses); @@ -59,7 +61,7 @@ protected: int solveTargetWithCCD(const IKTarget& target, AnimPoseVec& absolutePoses); virtual void setSkeletonInternal(AnimSkeleton::ConstPointer skeleton) override; void debugDrawConstraints(const AnimContext& context) const; - void initRelativePosesFromSolutionSource(const AnimPoseVec& underPose); + void initRelativePosesFromSolutionSource(SolutionSource solutionSource, const AnimPoseVec& underPose); void relaxToPoses(const AnimPoseVec& poses); // for AnimDebugDraw rendering @@ -116,6 +118,7 @@ protected: float _maxErrorOnLastSolve { FLT_MAX }; bool _previousEnableDebugIKTargets { false }; SolutionSource _solutionSource { SolutionSource::RelaxToUnderPoses }; + QString _solutionSourceVar; }; #endif // hifi_AnimInverseKinematics_h diff --git a/libraries/animation/src/AnimNodeLoader.cpp b/libraries/animation/src/AnimNodeLoader.cpp index bda4541f36..592667bb72 100644 --- a/libraries/animation/src/AnimNodeLoader.cpp +++ b/libraries/animation/src/AnimNodeLoader.cpp @@ -352,6 +352,23 @@ static AnimOverlay::BoneSet stringToBoneSetEnum(const QString& str) { return AnimOverlay::NumBoneSets; } +static const char* solutionSourceStrings[AnimInverseKinematics::SolutionSource::NumSolutionSources] = { + "relaxToUnderPoses", + "relaxToLimitCenterPoses", + "previousSolution", + "underPoses", + "limitCenterPoses" +}; + +static AnimInverseKinematics::SolutionSource stringToSolutionSourceEnum(const QString& str) { + for (int i = 0; i < (int)AnimInverseKinematics::SolutionSource::NumSolutionSources; i++) { + if (str == solutionSourceStrings[i]) { + return (AnimInverseKinematics::SolutionSource)i; + } + } + return AnimInverseKinematics::SolutionSource::NumSolutionSources; +} + static AnimNode::Pointer loadOverlayNode(const QJsonObject& jsonObj, const QString& id, const QUrl& jsonUrl) { READ_STRING(boneSet, jsonObj, id, jsonUrl, nullptr); @@ -457,6 +474,26 @@ AnimNode::Pointer loadInverseKinematicsNode(const QJsonObject& jsonObj, const QS node->setTargetVars(jointName, positionVar, rotationVar, typeVar); }; + READ_OPTIONAL_STRING(solutionSource, jsonObj); + + if (!solutionSource.isEmpty()) { + qCDebug(animation) << "AJT: REMOVE solutionSource = " << solutionSource; + + AnimInverseKinematics::SolutionSource solutionSourceType = stringToSolutionSourceEnum(solutionSource); + if (solutionSourceType != AnimInverseKinematics::SolutionSource::NumSolutionSources) { + node->setSolutionSource(solutionSourceType); + } else { + qCWarning(animation) << "AnimNodeLoader, bad solutionSourceType in \"solutionSource\", id = " << id << ", url = " << jsonUrl.toDisplayString(); + } + } + + READ_OPTIONAL_STRING(solutionSourceVar, jsonObj); + + if (!solutionSourceVar.isEmpty()) { + qCDebug(animation) << "AJT: REMOVE solutionSourceVar = " << solutionSourceVar; + node->setSolutionSourceVar(solutionSourceVar); + } + return node; } diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index 2bcd71d5c3..c1ef443684 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -1031,10 +1031,12 @@ void Rig::updateFromHeadParameters(const HeadParameters& params, float dt) { _animVars.set("notIsTalking", !params.isTalking); if (params.hipsEnabled) { + _animVars.set("solutionSource", (int)AnimInverseKinematics::SolutionSource::RelaxToCenterJointLimits); _animVars.set("hipsType", (int)IKTarget::Type::RotationAndPosition); _animVars.set("hipsPosition", extractTranslation(params.hipsMatrix)); _animVars.set("hipsRotation", glmExtractRotation(params.hipsMatrix)); } else { + _animVars.set("solutionSource", (int)AnimInverseKinematics::SolutionSource::RelaxToUnderPoses); _animVars.set("hipsType", (int)IKTarget::Type::Unknown); }