10 #ifndef hifi_AnimInverseKinematics_h
11 #define hifi_AnimInverseKinematics_h
21 #include "RotationAccumulator.h"
22 #include "TranslationAccumulator.h"
24 class RotationConstraint;
26 class AnimInverseKinematics :
public AnimNode {
36 struct JointChainInfo {
37 std::vector<JointInfo> jointInfoVec;
42 using JointChainInfoVec = std::vector<JointChainInfo>;
44 explicit AnimInverseKinematics(
const QString&
id);
45 virtual ~AnimInverseKinematics()
override;
47 void loadDefaultPoses(
const AnimPoseVec& poses);
48 void loadPoses(
const AnimPoseVec& poses);
49 void computeAbsolutePoses(AnimPoseVec& absolutePoses)
const;
51 void setTargetVars(
const QString& jointName,
const QString& positionVar,
const QString& rotationVar,
52 const QString& typeVar,
const QString& weightVar,
float weight,
const std::vector<float>& flexCoefficients,
53 const QString& poleVectorEnabledVar,
const QString& poleReferenceVectorVar,
const QString& poleVectorVar);
55 virtual const AnimPoseVec& evaluate(
const AnimVariantMap& animVars,
const AnimContext& context,
float dt, AnimVariantMap& triggersOut)
override;
56 virtual const AnimPoseVec& overlay(
const AnimVariantMap& animVars,
const AnimContext& context,
float dt, AnimVariantMap& triggersOut,
const AnimPoseVec& underPoses)
override;
58 void clearIKJointLimitHistory();
60 float getMaxErrorOnLastSolve() {
return _maxErrorOnLastSolve; }
104 enum class SolutionSource {
105 RelaxToUnderPoses = 0,
106 RelaxToLimitCenterPoses,
113 void setSecondaryTargetInRigFrame(
int jointIndex,
const AnimPose& pose);
114 void clearSecondaryTarget(
int jointIndex);
116 void setSolutionSource(SolutionSource solutionSource) { _solutionSource = solutionSource; }
117 void setSolutionSourceVar(
const QString& solutionSourceVar) { _solutionSourceVar = solutionSourceVar; }
120 void computeTargets(
const AnimVariantMap& animVars, std::vector<IKTarget>& targets,
const AnimPoseVec& underPoses);
121 void solve(
const AnimContext& context,
const std::vector<IKTarget>& targets,
float dt, JointChainInfoVec& jointChainInfoVec);
122 void solveTargetWithCCD(
const AnimContext& context,
const IKTarget& target,
const AnimPoseVec& absolutePoses,
123 bool debug, JointChainInfo& jointChainInfoOut)
const;
124 void solveTargetWithSpline(
const AnimContext& context,
const IKTarget& target,
const AnimPoseVec& absolutePoses,
125 bool debug, JointChainInfo& jointChainInfoOut)
const;
126 virtual void setSkeletonInternal(AnimSkeleton::ConstPointer skeleton)
override;
127 void debugDrawIKChain(
const JointChainInfo& jointChainInfo,
const AnimContext& context)
const;
128 void debugDrawRelativePoses(
const AnimContext& context)
const;
129 void debugDrawConstraints(
const AnimContext& context)
const;
130 void debugDrawSpineSplines(
const AnimContext& context,
const std::vector<IKTarget>& targets)
const;
131 void initRelativePosesFromSolutionSource(SolutionSource solutionSource,
const AnimPoseVec& underPose);
132 void blendToPoses(
const AnimPoseVec& targetPoses,
const AnimPoseVec& underPose,
float blendFactor);
133 void preconditionRelativePosesToAvoidLimbLock(
const AnimContext& context,
const std::vector<IKTarget>& targets);
134 void setSecondaryTargets(
const AnimContext& context);
137 struct SplineJointInfo {
143 void computeAndCacheSplineJointInfosForIKTarget(
const AnimContext& context,
const IKTarget& target)
const;
144 const std::vector<SplineJointInfo>* findOrCreateSplineJointInfo(
const AnimContext& context,
const IKTarget& target)
const;
147 virtual const AnimPoseVec& getPosesInternal()
const override {
return _relativePoses; }
149 RotationConstraint* getConstraint(
int index)
const;
150 void clearConstraints();
151 void initConstraints();
152 void initLimitCenterPoses();
153 float getInterpolationAlpha(
float timer);
156 AnimInverseKinematics(
const AnimInverseKinematics&) =
delete;
157 AnimInverseKinematics& operator=(
const AnimInverseKinematics&) =
delete;
159 enum FlexCoefficients { MAX_FLEX_COEFFICIENTS = 10 };
161 IKTargetVar(
const QString& jointNameIn,
const QString& positionVarIn,
const QString& rotationVarIn,
162 const QString& typeVarIn,
const QString& weightVarIn,
float weightIn,
const std::vector<float>& flexCoefficientsIn,
163 const QString& poleVectorEnabledVar,
const QString& poleReferenceVectorVar,
const QString& poleVectorVar);
164 IKTargetVar(
const IKTargetVar& orig);
165 AnimInverseKinematics::IKTargetVar& operator=(
const AnimInverseKinematics::IKTargetVar&) =
default;
172 QString poleVectorEnabledVar;
173 QString poleReferenceVectorVar;
174 QString poleVectorVar;
176 float flexCoefficients[MAX_FLEX_COEFFICIENTS];
177 size_t numFlexCoefficients;
181 std::map<int, RotationConstraint*> _constraints;
182 std::vector<RotationAccumulator> _rotationAccumulators;
183 std::vector<TranslationAccumulator> _translationAccumulators;
184 std::vector<IKTargetVar> _targetVarVec;
185 AnimPoseVec _defaultRelativePoses;
186 AnimPoseVec _relativePoses;
187 AnimPoseVec _limitCenterPoses;
188 std::map<int, glm::quat> _rotationOnlyIKRotations;
190 std::map<int, AnimPose> _secondaryTargetsInRigFrame;
192 mutable std::map<int, std::vector<SplineJointInfo>> _splineJointInfoMap;
194 int _headIndex { -1 };
195 int _hipsIndex { -1 };
196 int _hipsParentIndex { -1 };
197 int _hipsTargetIndex { -1 };
198 int _leftHandIndex { -1 };
199 int _rightHandIndex { -1 };
201 float _maxErrorOnLastSolve { FLT_MAX };
202 bool _previousEnableDebugIKTargets {
false };
203 SolutionSource _solutionSource { SolutionSource::RelaxToUnderPoses };
204 QString _solutionSourceVar;
206 JointChainInfoVec _prevJointChainInfoVec;