From 37f92d2319b3a09148706ffb1987c3f4715a0c48 Mon Sep 17 00:00:00 2001 From: amantley Date: Thu, 24 Jan 2019 17:02:30 -0800 Subject: [PATCH] added code to read tip and base var info from the json --- .../avatar/avatar-animation_withIKNode.json | 7 + .../animation/src/AnimInverseKinematics.cpp | 15 +- libraries/animation/src/AnimNodeLoader.cpp | 12 +- libraries/animation/src/AnimSplineIK.cpp | 208 ++++++++++++------ libraries/animation/src/AnimSplineIK.h | 20 +- libraries/animation/src/Rig.cpp | 14 +- 6 files changed, 194 insertions(+), 82 deletions(-) diff --git a/interface/resources/avatar/avatar-animation_withIKNode.json b/interface/resources/avatar/avatar-animation_withIKNode.json index 44b2b9c25f..04ed593755 100644 --- a/interface/resources/avatar/avatar-animation_withIKNode.json +++ b/interface/resources/avatar/avatar-animation_withIKNode.json @@ -183,6 +183,13 @@ "interpDuration": 15, "baseJointName": "Hips", "tipJointName": "Head", + "secondaryTargetJointName": "Spine2", + "basePositionVar": "hipsPosition", + "baseRotationVar": "hipsRotation", + "tipPositionVar": "headPosition", + "tipRotationVar": "headRotation", + "secondaryTargetPositionVar": "spine2Position", + "secondaryTargetRotationVar": "spine2Rotation", "alphaVar": "splineIKAlpha", "enabledVar": "splineIKEnabled", "endEffectorRotationVarVar": "splineIKRotationVar", diff --git a/libraries/animation/src/AnimInverseKinematics.cpp b/libraries/animation/src/AnimInverseKinematics.cpp index 8c365d2561..f95fe3333f 100644 --- a/libraries/animation/src/AnimInverseKinematics.cpp +++ b/libraries/animation/src/AnimInverseKinematics.cpp @@ -243,13 +243,6 @@ void AnimInverseKinematics::solve(const AnimContext& context, const std::vector< break; case IKTarget::Type::Spline: solveTargetWithSpline(context, targets[i], absolutePoses, debug, jointChainInfoVec[i]); - //if (jointChainInfoVec[i].target.getIndex() == _skeleton->nameToJointIndex("Head")) { - // qCDebug(animation) << "AnimIK spline index is " << targets[i].getIndex() << " and chain info size is " << jointChainInfoVec[i].jointInfoVec.size(); - for (int w = 0; w < jointChainInfoVec[i].jointInfoVec.size(); w++) { - // qCDebug(animation) << "joint " << jointChainInfoVec[i].jointInfoVec[w].jointIndex << " rotation is " << jointChainInfoVec[i].jointInfoVec[w].rot; - // qCDebug(animation) << "joint " << jointChainInfoVec[i].jointInfoVec[w].jointIndex << " translation is " << jointChainInfoVec[i].jointInfoVec[w].trans; - } - //} break; default: solveTargetWithCCD(context, targets[i], absolutePoses, debug, jointChainInfoVec[i]); @@ -329,6 +322,10 @@ void AnimInverseKinematics::solve(const AnimContext& context, const std::vector< } } + //qCDebug(animation) << "joint chain pose for head animIK " << jointChainInfoVec[4].jointInfoVec[w].trans << " " << jointChainInfoVec[4].jointInfoVec[w].rot; + qCDebug(animation) << "absolute pose for head animIK " << absolutePoses[_skeleton->nameToJointIndex("Head")]; + qCDebug(animation) << "target pose for head animIK " << targets[4].getTranslation() << " " << targets[4].getRotation(); + // compute maxError maxError = 0.0f; for (size_t i = 0; i < targets.size(); i++) { @@ -833,7 +830,9 @@ void AnimInverseKinematics::solveTargetWithSpline(const AnimContext& context, co AnimPose relPose = parentAbsPose.inverse() * flexedAbsPose; + bool constrained = false; + /* if (splineJointInfo.jointIndex != _hipsIndex) { // constrain the amount the spine can stretch or compress float length = glm::length(relPose.trans()); @@ -854,7 +853,7 @@ void AnimInverseKinematics::solveTargetWithSpline(const AnimContext& context, co relPose.trans() = glm::vec3(0.0f); } } - + */ jointChainInfoOut.jointInfoVec[i] = { relPose.rot(), relPose.trans(), splineJointInfo.jointIndex, constrained }; parentAbsPose = flexedAbsPose; diff --git a/libraries/animation/src/AnimNodeLoader.cpp b/libraries/animation/src/AnimNodeLoader.cpp index ec9099df8b..ebe9dbe3ba 100644 --- a/libraries/animation/src/AnimNodeLoader.cpp +++ b/libraries/animation/src/AnimNodeLoader.cpp @@ -585,6 +585,13 @@ static AnimNode::Pointer loadSplineIKNode(const QJsonObject& jsonObj, const QStr READ_FLOAT(interpDuration, jsonObj, id, jsonUrl, nullptr); READ_STRING(baseJointName, 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(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); @@ -592,8 +599,9 @@ static AnimNode::Pointer loadSplineIKNode(const QJsonObject& jsonObj, const QStr auto node = std::make_shared(id, alpha, enabled, interpDuration, baseJointName, tipJointName, - alphaVar, enabledVar, - endEffectorRotationVarVar, endEffectorPositionVarVar); + alphaVar, enabledVar, endEffectorRotationVarVar, endEffectorPositionVarVar, + basePositionVar, baseRotationVar, + tipPositionVar, tipRotationVar, secondaryTargetJointName, secondaryTargetPositionVar, secondaryTargetRotationVar); return node; } diff --git a/libraries/animation/src/AnimSplineIK.cpp b/libraries/animation/src/AnimSplineIK.cpp index 39f8767465..afe9f6dfcb 100644 --- a/libraries/animation/src/AnimSplineIK.cpp +++ b/libraries/animation/src/AnimSplineIK.cpp @@ -20,7 +20,14 @@ AnimSplineIK::AnimSplineIK(const QString& id, float alpha, bool enabled, float i const QString& baseJointName, const QString& tipJointName, const QString& alphaVar, const QString& enabledVar, - const QString& endEffectorRotationVarVar, const QString& endEffectorPositionVarVar) : + const QString& endEffectorRotationVarVar, const QString& endEffectorPositionVarVar, + const QString& basePositionVar, + const QString& baseRotationVar, + const QString& tipPositionVar, + const QString& tipRotationVar, + const QString& secondaryTargetJointName, + const QString& secondaryTargetPositionVar, + const QString& secondaryTargetRotationVar) : AnimNode(AnimNode::Type::SplineIK, id), _alpha(alpha), _enabled(enabled), @@ -32,7 +39,15 @@ AnimSplineIK::AnimSplineIK(const QString& id, float alpha, bool enabled, float i _endEffectorRotationVarVar(endEffectorRotationVarVar), _endEffectorPositionVarVar(endEffectorPositionVarVar), _prevEndEffectorRotationVar(), - _prevEndEffectorPositionVar() { + _prevEndEffectorPositionVar(), + _basePositionVar(basePositionVar), + _baseRotationVar(baseRotationVar), + _tipPositionVar(tipPositionVar), + _tipRotationVar(tipRotationVar), + _secondaryTargetJointName(secondaryTargetJointName), + _secondaryTargetPositionVar(secondaryTargetPositionVar), + _secondaryTargetRotationVar(secondaryTargetRotationVar) +{ } @@ -51,16 +66,19 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const if (_children.size() != 1) { return _poses; } - // evalute underPoses + // evaluate underPoses AnimPoseVec underPoses = _children[0]->evaluate(animVars, context, dt, triggersOut); _poses = underPoses; - // now we override the hips relative pose based on the hips target that has been set. + glm::quat hipsTargetRotation; + glm::vec3 hipsTargetTranslation; + + // now we override the hips with the hips target pose. //////////////////////////////////////////////////// if (_poses.size() > 0) { AnimPose hipsUnderPose = _skeleton->getAbsolutePose(_hipsIndex, _poses); - glm::quat hipsTargetRotation = animVars.lookupRigToGeometry("hipsRotation", hipsUnderPose.rot()); - glm::vec3 hipsTargetTranslation = animVars.lookupRigToGeometry("hipsPosition", hipsUnderPose.trans()); + hipsTargetRotation = animVars.lookupRigToGeometry("hipsRotation", hipsUnderPose.rot()); + hipsTargetTranslation = animVars.lookupRigToGeometry("hipsPosition", hipsUnderPose.trans()); AnimPose absHipsTargetPose(hipsTargetRotation, hipsTargetTranslation); int hipsParentIndex = _skeleton->getParentIndex(_hipsIndex); @@ -76,23 +94,22 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const computeAbsolutePoses(absolutePoses); IKTarget target; - if (_headIndex != -1) { - target.setType(animVars.lookup("headType", (int)IKTarget::Type::RotationAndPosition)); - target.setIndex(_headIndex); - AnimPose absPose = _skeleton->getAbsolutePose(_headIndex, _poses); - glm::quat rotation = animVars.lookupRigToGeometry("headRotation", absPose.rot()); - glm::vec3 translation = animVars.lookupRigToGeometry("headPosition", absPose.trans()); - float weight = animVars.lookup("headWeight", "4.0"); + if (_tipJointIndex != -1) { + target.setType((int)IKTarget::Type::Spline); + target.setIndex(_tipJointIndex); + AnimPose absPose = _skeleton->getAbsolutePose(_tipJointIndex, _poses); + glm::quat rotation = animVars.lookupRigToGeometry(_tipRotationVar, absPose.rot()); + glm::vec3 translation = animVars.lookupRigToGeometry(_tipPositionVar, absPose.trans()); + float weight = 1.0f; target.setPose(rotation, translation); target.setWeight(weight); - const float* flexCoefficients = new float[5]{ 1.0f, 1.0f, 1.0f, 1.0f, 1.0f }; - //const float* flexCoefficients = new float[2]{ 0.0f, 1.0f }; + const float* flexCoefficients = new float[5]{ 1.0f, 0.5f, 0.25f, 0.2f, 0.1f }; target.setFlexCoefficients(5, flexCoefficients); } AnimChain jointChain; - AnimPose targetSpine2; + AnimPose updatedSecondaryTarget; AnimPoseVec absolutePoses2; absolutePoses2.resize(_poses.size()); if (_poses.size() > 0) { @@ -100,43 +117,47 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const //_snapshotChain.buildFromRelativePoses(_skeleton, _poses, target.getIndex()); jointChain.buildFromRelativePoses(_skeleton, _poses, target.getIndex()); solveTargetWithSpline(context, target, absolutePoses, false, jointChain); + jointChain.buildDirtyAbsolutePoses(); + qCDebug(animation) << "the jointChain Result for head " << jointChain.getAbsolutePoseFromJointIndex(_tipJointIndex); + qCDebug(animation) << "the orig target pose for head " << target.getPose(); jointChain.outputRelativePoses(_poses); - AnimPose afterSolveSpine2 = _skeleton->getAbsolutePose(_spine2Index, _poses); - glm::quat spine2RotationTarget = animVars.lookupRigToGeometry("spine2Rotation", afterSolveSpine2.rot()); + AnimPose afterSolveSecondaryTarget = _skeleton->getAbsolutePose(_secondaryTargetIndex, _poses); + glm::quat secondaryTargetRotation = animVars.lookupRigToGeometry(_secondaryTargetRotationVar, afterSolveSecondaryTarget.rot()); - targetSpine2 = AnimPose(spine2RotationTarget, afterSolveSpine2.trans()); + // updatedSecondaryTarget = AnimPose(secondaryTargetRotation, afterSolveSpine2.trans()); + updatedSecondaryTarget = AnimPose(afterSolveSecondaryTarget.rot(), afterSolveSecondaryTarget.trans()); } - /* - IKTarget target2; + + IKTarget secondaryTarget; computeAbsolutePoses(absolutePoses2); - if (_spine2Index != -1) { - target2.setType(animVars.lookup("spine2Type", (int)IKTarget::Type::RotationAndPosition)); - target2.setIndex(_spine2Index); + if (_secondaryTargetIndex != -1) { + secondaryTarget.setType((int)IKTarget::Type::Spline); + secondaryTarget.setIndex(_secondaryTargetIndex); - float weight2 = animVars.lookup("spine2Weight", "2.0"); + float weight2 = 1.0f; - target2.setPose(targetSpine2.rot(), targetSpine2.trans()); - target2.setWeight(weight2); + secondaryTarget.setPose(updatedSecondaryTarget.rot(), updatedSecondaryTarget.trans()); + secondaryTarget.setWeight(weight2); const float* flexCoefficients2 = new float[3]{ 1.0f, 1.0f, 1.0f }; - target2.setFlexCoefficients(3, flexCoefficients2); + secondaryTarget.setFlexCoefficients(3, flexCoefficients2); } - - AnimChain jointChain2; + /* + AnimChain secondaryJointChain; AnimPose beforeSolveChestNeck; if (_poses.size() > 0) { beforeSolveChestNeck = _skeleton->getAbsolutePose(_skeleton->nameToJointIndex("Neck"), _poses); - jointChain2.buildFromRelativePoses(_skeleton, _poses, target2.getIndex()); - solveTargetWithSpline(context, target2, absolutePoses2, false, jointChain2); - jointChain2.outputRelativePoses(_poses); + secondaryJointChain.buildFromRelativePoses(_skeleton, _poses, secondaryTarget.getIndex()); + solveTargetWithSpline(context, secondaryTarget, absolutePoses2, false, secondaryJointChain); + secondaryJointChain.outputRelativePoses(_poses); } - */ + */ const float FRAMES_PER_SECOND = 30.0f; _interpAlphaVel = FRAMES_PER_SECOND / _interpDuration; @@ -149,23 +170,59 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const // update the relative poses and then we are done // set the tip/head rotation to match the absolute rotation of the target. - int headParent = _skeleton->getParentIndex(_headIndex); - int spine2Parent = _skeleton->getParentIndex(_spine2Index); - if ((spine2Parent != -1) && (headParent != -1) && (_poses.size() > 0)) { + int tipParent = _skeleton->getParentIndex(_tipJointIndex); + int secondaryTargetParent = _skeleton->getParentIndex(_secondaryTargetIndex); + if ((secondaryTargetParent != -1) && (tipParent != -1) && (_poses.size() > 0)) { /* - AnimPose spine2Target(target2.getRotation(), target2.getTranslation()); - AnimPose finalSpine2RelativePose = _skeleton->getAbsolutePose(spine2Parent, _poses).inverse() * spine2Target; - _poses[_spine2Index] = finalSpine2RelativePose; + AnimPose secondaryTargetPose(target2.getRotation(), target2.getTranslation()); + AnimPose secondaryTargetRelativePose = _skeleton->getAbsolutePose(secondaryTargetParent, _poses).inverse() * secondaryTargetPose; + _poses[_secondaryTargetIndex] = secondaryTargetRelativePose; - AnimPose neckAbsolute = _skeleton->getAbsolutePose(headParent, _poses); + AnimPose neckAbsolute = _skeleton->getAbsolutePose(tipParent, _poses); AnimPose finalNeckAbsolute = AnimPose(safeLerp(target2.getRotation(), target.getRotation(), 1.0f),neckAbsolute.trans()); _poses[headParent] = spine2Target.inverse() * beforeSolveChestNeck; */ - AnimPose headTarget(target.getRotation(),target.getTranslation()); - AnimPose finalHeadRelativePose = _skeleton->getAbsolutePose(headParent,_poses).inverse() * headTarget; - _poses[_headIndex] = finalHeadRelativePose; + //AnimPose tipTarget(target.getRotation(),target.getTranslation()); + //AnimPose tipRelativePose = _skeleton->getAbsolutePose(tipParent,_poses).inverse() * headTarget; + //_poses[_tipJointIndex] = tipHeadRelativePose; } + + // debug render ik targets + if (context.getEnableDebugDrawIKTargets()) { + const vec4 WHITE(1.0f); + const vec4 GREEN(0.0f, 1.0f, 0.0f, 1.0f); + glm::mat4 rigToAvatarMat = createMatFromQuatAndPos(Quaternions::Y_180, glm::vec3()); + + glm::mat4 geomTargetMat = createMatFromQuatAndPos(target.getRotation(), target.getTranslation()); + glm::mat4 avatarTargetMat = rigToAvatarMat * context.getGeometryToRigMatrix() * geomTargetMat; + QString name = QString("ikTargetHead"); + DebugDraw::getInstance().addMyAvatarMarker(name, glmExtractRotation(avatarTargetMat), extractTranslation(avatarTargetMat), WHITE); + + glm::mat4 geomTargetMat2 = createMatFromQuatAndPos(secondaryTarget.getRotation(), secondaryTarget.getTranslation()); + glm::mat4 avatarTargetMat2 = rigToAvatarMat * context.getGeometryToRigMatrix() * geomTargetMat2; + QString name2 = QString("ikTargetSpine2"); + DebugDraw::getInstance().addMyAvatarMarker(name2, glmExtractRotation(avatarTargetMat2), extractTranslation(avatarTargetMat2), WHITE); + + + glm::mat4 geomTargetMat3 = createMatFromQuatAndPos(hipsTargetRotation, hipsTargetTranslation); + glm::mat4 avatarTargetMat3 = rigToAvatarMat * context.getGeometryToRigMatrix() * geomTargetMat3; + QString name3 = QString("ikTargetHips"); + DebugDraw::getInstance().addMyAvatarMarker(name3, glmExtractRotation(avatarTargetMat3), extractTranslation(avatarTargetMat3), WHITE); + + + } else if (context.getEnableDebugDrawIKTargets() != _previousEnableDebugIKTargets) { + // remove markers if they were added last frame. + + QString name = QString("ikTargetHead"); + DebugDraw::getInstance().removeMyAvatarMarker(name); + QString name2 = QString("ikTargetSpine2"); + DebugDraw::getInstance().removeMyAvatarMarker(name2); + QString name3 = QString("ikTargetHips"); + DebugDraw::getInstance().removeMyAvatarMarker(name3); + + } + _previousEnableDebugIKTargets = context.getEnableDebugDrawIKTargets(); return _poses; } @@ -174,11 +231,12 @@ void AnimSplineIK::lookUpIndices() { assert(_skeleton); // look up bone indices by name - std::vector indices = _skeleton->lookUpJointIndices({ _baseJointName, _tipJointName }); + std::vector indices = _skeleton->lookUpJointIndices({ _baseJointName, _tipJointName, _secondaryTargetJointName }); // cache the results _baseJointIndex = indices[0]; _tipJointIndex = indices[1]; + _secondaryTargetIndex = indices[2]; if (_baseJointIndex != -1) { _baseParentJointIndex = _skeleton->getParentIndex(_baseJointIndex); @@ -206,9 +264,8 @@ const AnimPoseVec& AnimSplineIK::getPosesInternal() const { void AnimSplineIK::setSkeletonInternal(AnimSkeleton::ConstPointer skeleton) { AnimNode::setSkeletonInternal(skeleton); - _headIndex = _skeleton->nameToJointIndex("Head"); + //_headIndex = _skeleton->nameToJointIndex("Head"); _hipsIndex = _skeleton->nameToJointIndex("Hips"); - _spine2Index = _skeleton->nameToJointIndex("Spine2"); lookUpIndices(); } @@ -224,20 +281,20 @@ static CubicHermiteSplineFunctorWithArcLength computeSplineFromTipAndBase(const void AnimSplineIK::solveTargetWithSpline(const AnimContext& context, const IKTarget& target, const AnimPoseVec& absolutePoses, bool debug, AnimChain& chainInfoOut) const { - const int baseIndex = _hipsIndex; - const int headBaseIndex = _spine2Index; + const int baseIndex = _baseJointIndex; + const int tipBaseIndex = _secondaryTargetIndex; // build spline from tip to base AnimPose tipPose = AnimPose(glm::vec3(1.0f), target.getRotation(), target.getTranslation()); AnimPose basePose; - //if (target.getIndex() == _headIndex) { - // basePose = absolutePoses[headBaseIndex]; + //if (target.getIndex() == _tipJointIndex) { + // basePose = absolutePoses[tipBaseIndex]; //} else { basePose = absolutePoses[baseIndex]; //} CubicHermiteSplineFunctorWithArcLength spline; - if (target.getIndex() == _headIndex) { + if (target.getIndex() == _tipJointIndex) { // set gain factors so that more curvature occurs near the tip of the spline. const float HIPS_GAIN = 0.5f; const float HEAD_GAIN = 1.0f; @@ -268,7 +325,7 @@ void AnimSplineIK::solveTargetWithSpline(const AnimContext& context, const IKTar // for head splines, preform most twist toward the tip by using ease in function. t^2 float rotT = t; - if (target.getIndex() == _headIndex) { + if (target.getIndex() == _tipJointIndex) { rotT = t * t; } glm::quat twistRot = safeLerp(basePose.rot(), tipPose.rot(), rotT); @@ -290,7 +347,7 @@ void AnimSplineIK::solveTargetWithSpline(const AnimContext& context, const IKTar AnimPose relPose = parentAbsPose.inverse() * flexedAbsPose; bool constrained = false; - if (splineJointInfo.jointIndex != _hipsIndex) { + if (splineJointInfo.jointIndex != _baseJointIndex) { // constrain the amount the spine can stretch or compress float length = glm::length(relPose.trans()); const float EPSILON = 0.0001f; @@ -350,15 +407,15 @@ void AnimSplineIK::computeAndCacheSplineJointInfosForIKTarget(const AnimContext& // build spline between the default poses. AnimPose tipPose = _skeleton->getAbsoluteDefaultPose(target.getIndex()); AnimPose basePose; - if (target.getIndex() == _headIndex) { - basePose = _skeleton->getAbsoluteDefaultPose(_hipsIndex); - //basePose = _skeleton->getAbsoluteDefaultPose(_spine2Index); + if (target.getIndex() == _tipJointIndex) { + basePose = _skeleton->getAbsoluteDefaultPose(_baseJointIndex); + //basePose = _skeleton->getAbsoluteDefaultPose(_secondaryTargetIndex); } else { - basePose = _skeleton->getAbsoluteDefaultPose(_hipsIndex); + basePose = _skeleton->getAbsoluteDefaultPose(_baseJointIndex); } CubicHermiteSplineFunctorWithArcLength spline; - if (target.getIndex() == _headIndex) { + if (target.getIndex() == _tipJointIndex) { // set gain factors so that more curvature occurs near the tip of the spline. const float HIPS_GAIN = 0.5f; const float HEAD_GAIN = 1.0f; @@ -377,11 +434,11 @@ void AnimSplineIK::computeAndCacheSplineJointInfosForIKTarget(const AnimContext& int index = target.getIndex(); int endIndex; - if (target.getIndex() == _headIndex) { - endIndex = _skeleton->getParentIndex(_spine2Index); - // endIndex = _skeleton->getParentIndex(_hipsIndex); + if (target.getIndex() == _tipJointIndex) { + //endIndex = _skeleton->getParentIndex(_secondaryTargetIndex); + endIndex = _skeleton->getParentIndex(_baseJointIndex); } else { - endIndex = _skeleton->getParentIndex(_hipsIndex); + endIndex = _skeleton->getParentIndex(_baseJointIndex); } while (index != endIndex) { AnimPose defaultPose = _skeleton->getAbsoluteDefaultPose(index); @@ -410,11 +467,34 @@ void AnimSplineIK::computeAndCacheSplineJointInfosForIKTarget(const AnimContext& _splineJointInfoMap[target.getIndex()] = splineJointInfoVec; } -void AnimSplineIK ::loadPoses(const AnimPoseVec& poses) { +void AnimSplineIK::loadPoses(const AnimPoseVec& poses) { assert(_skeleton && ((poses.size() == 0) || (_skeleton->getNumJoints() == (int)poses.size()))); if (_skeleton->getNumJoints() == (int)poses.size()) { _poses = poses; } else { _poses.clear(); } +} + + +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); + } + */ } \ No newline at end of file diff --git a/libraries/animation/src/AnimSplineIK.h b/libraries/animation/src/AnimSplineIK.h index 12f43fa680..4c51a0b9e1 100644 --- a/libraries/animation/src/AnimSplineIK.h +++ b/libraries/animation/src/AnimSplineIK.h @@ -21,7 +21,12 @@ public: AnimSplineIK(const QString& id, float alpha, bool enabled, float interpDuration, const QString& baseJointName, const QString& tipJointName, const QString& alphaVar, const QString& enabledVar, - const QString& endEffectorRotationVarVar, const QString& endEffectorPositionVarVar); + const QString& endEffectorRotationVarVar, const QString& endEffectorPositionVarVar, + const QString& basePositionVar, const QString& baseRotationVar, + const QString& tipPositionVar, const QString& tipRotationVar, + const QString& secondaryTargetJointName, + const QString& secondaryTargetPositionVar, + const QString& secondaryTargetRotationVar); virtual ~AnimSplineIK() override; virtual const AnimPoseVec& evaluate(const AnimVariantMap& animVars, const AnimContext& context, float dt, AnimVariantMap& triggersOut) override; @@ -52,9 +57,17 @@ protected: float _interpDuration; QString _baseJointName; QString _tipJointName; + QString _secondaryTargetJointName; + QString _basePositionVar; + QString _baseRotationVar; + QString _tipPositionVar; + QString _tipRotationVar; + QString _secondaryTargetPositionVar; + QString _secondaryTargetRotationVar; int _baseParentJointIndex { -1 }; int _baseJointIndex { -1 }; + int _secondaryTargetIndex { -1 }; int _tipJointIndex { -1 }; int _headIndex { -1 }; int _hipsIndex { -1 }; @@ -69,6 +82,8 @@ protected: QString _prevEndEffectorRotationVar; QString _prevEndEffectorPositionVar; + bool _previousEnableDebugIKTargets { false }; + InterpType _interpType{ InterpType::None }; float _interpAlphaVel{ 0.0f }; float _interpAlpha{ 0.0f }; @@ -84,6 +99,9 @@ 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; diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index 70f1f9a1f7..b92e095b4f 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -1857,14 +1857,14 @@ void Rig::updateFromControllerParameters(const ControllerParameters& params, flo updateHead(_headEnabled, hipsEnabled, params.primaryControllerPoses[PrimaryControllerType_Head]); - updateHands(leftHandEnabled, rightHandEnabled, hipsEnabled, hipsEstimated, leftArmEnabled, rightArmEnabled, _headEnabled, dt, - params.primaryControllerPoses[PrimaryControllerType_LeftHand], params.primaryControllerPoses[PrimaryControllerType_RightHand], - params.hipsShapeInfo, params.spineShapeInfo, params.spine1ShapeInfo, params.spine2ShapeInfo, - params.rigToSensorMatrix, sensorToRigMatrix); + //updateHands(leftHandEnabled, rightHandEnabled, hipsEnabled, hipsEstimated, leftArmEnabled, rightArmEnabled, _headEnabled, dt, + // params.primaryControllerPoses[PrimaryControllerType_LeftHand], params.primaryControllerPoses[PrimaryControllerType_RightHand], + // params.hipsShapeInfo, params.spineShapeInfo, params.spine1ShapeInfo, params.spine2ShapeInfo, + // params.rigToSensorMatrix, sensorToRigMatrix); - //updateHands2(leftHandEnabled, rightHandEnabled, _headEnabled, - // params.primaryControllerPoses[PrimaryControllerType_LeftHand], params.primaryControllerPoses[PrimaryControllerType_RightHand], - // params.rigToSensorMatrix, sensorToRigMatrix); + updateHands2(leftHandEnabled, rightHandEnabled, _headEnabled, + params.primaryControllerPoses[PrimaryControllerType_LeftHand], params.primaryControllerPoses[PrimaryControllerType_RightHand], + params.rigToSensorMatrix, sensorToRigMatrix); updateFeet(leftFootEnabled, rightFootEnabled, _headEnabled, params.primaryControllerPoses[PrimaryControllerType_LeftFoot], params.primaryControllerPoses[PrimaryControllerType_RightFoot],