mirror of
https://github.com/overte-org/overte.git
synced 2025-08-08 00:10:52 +02:00
Added setSolutionSource to AnimInverseKinematics node.
This commit is contained in:
parent
712fcbe27a
commit
2166d8c159
2 changed files with 52 additions and 19 deletions
|
@ -414,25 +414,7 @@ const AnimPoseVec& AnimInverseKinematics::overlay(const AnimVariantMap& animVars
|
||||||
|
|
||||||
PROFILE_RANGE_EX(simulation_animation, "ik/relax", 0xffff00ff, 0);
|
PROFILE_RANGE_EX(simulation_animation, "ik/relax", 0xffff00ff, 0);
|
||||||
|
|
||||||
// relax toward underPoses
|
initRelativePosesFromSolutionSource(underPoses);
|
||||||
// HACK: this relaxation needs to be constant per-frame rather than per-realtime
|
|
||||||
// in order to prevent IK "flutter" for bad FPS. The bad news is that the good parts
|
|
||||||
// of this relaxation will be FPS dependent (low FPS will make the limbs align slower
|
|
||||||
// in real-time), however most people will not notice this and this problem is less
|
|
||||||
// annoying than the flutter.
|
|
||||||
const float blend = (1.0f / 60.0f) / (0.25f); // effectively: dt / RELAXATION_TIMESCALE
|
|
||||||
int numJoints = (int)_relativePoses.size();
|
|
||||||
for (int i = 0; i < numJoints; ++i) {
|
|
||||||
float dotSign = copysignf(1.0f, glm::dot(_relativePoses[i].rot(), underPoses[i].rot()));
|
|
||||||
if (_accumulators[i].isDirty()) {
|
|
||||||
// this joint is affected by IK --> blend toward underPose rotation
|
|
||||||
_relativePoses[i].rot() = glm::normalize(glm::lerp(_relativePoses[i].rot(), dotSign * underPoses[i].rot(), blend));
|
|
||||||
} else {
|
|
||||||
// this joint is NOT affected by IK --> slam to underPose rotation
|
|
||||||
_relativePoses[i].rot() = underPoses[i].rot();
|
|
||||||
}
|
|
||||||
_relativePoses[i].trans() = underPoses[i].trans();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!underPoses.empty()) {
|
if (!underPoses.empty()) {
|
||||||
// Sometimes the underpose itself can violate the constraints. Rather than
|
// Sometimes the underpose itself can violate the constraints. Rather than
|
||||||
|
@ -1135,3 +1117,41 @@ void AnimInverseKinematics::debugDrawConstraints(const AnimContext& context) con
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AnimInverseKinematics::relaxToPoses(const AnimPoseVec& poses) {
|
||||||
|
// relax toward poses
|
||||||
|
const float blend = (1.0f / 60.0f) / (0.25f);
|
||||||
|
int numJoints = (int)_relativePoses.size();
|
||||||
|
for (int i = 0; i < numJoints; ++i) {
|
||||||
|
float dotSign = copysignf(1.0f, glm::dot(_relativePoses[i].rot(), poses[i].rot()));
|
||||||
|
if (_accumulators[i].isDirty()) {
|
||||||
|
// this joint is affected by IK --> blend toward each pose rotation
|
||||||
|
_relativePoses[i].rot() = glm::normalize(glm::lerp(_relativePoses[i].rot(), dotSign * poses[i].rot(), blend));
|
||||||
|
} else {
|
||||||
|
// this joint is NOT affected by IK --> slam to underPose rotation
|
||||||
|
_relativePoses[i].rot() = poses[i].rot();
|
||||||
|
}
|
||||||
|
_relativePoses[i].trans() = poses[i].trans();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AnimInverseKinematics::initRelativePosesFromSolutionSource(const AnimPoseVec& underPoses) {
|
||||||
|
switch (_solutionSource) {
|
||||||
|
default:
|
||||||
|
case SolutionSource::RelaxToUnderPoses:
|
||||||
|
relaxToPoses(underPoses);
|
||||||
|
break;
|
||||||
|
case SolutionSource::RelaxToLimitCenterPoses:
|
||||||
|
relaxToPoses(_limitCenterPoses);
|
||||||
|
break;
|
||||||
|
case SolutionSource::PreviousSolution:
|
||||||
|
// do nothing... _relativePoses is already the previous solution
|
||||||
|
break;
|
||||||
|
case SolutionSource::UnderPoses:
|
||||||
|
_relativePoses = underPoses;
|
||||||
|
break;
|
||||||
|
case SolutionSource::LimitCenterPoses:
|
||||||
|
_relativePoses = _limitCenterPoses;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -43,12 +43,24 @@ public:
|
||||||
|
|
||||||
float getMaxErrorOnLastSolve() { return _maxErrorOnLastSolve; }
|
float getMaxErrorOnLastSolve() { return _maxErrorOnLastSolve; }
|
||||||
|
|
||||||
|
enum class SolutionSource {
|
||||||
|
RelaxToUnderPoses = 0,
|
||||||
|
RelaxToLimitCenterPoses,
|
||||||
|
PreviousSolution,
|
||||||
|
UnderPoses,
|
||||||
|
LimitCenterPoses
|
||||||
|
};
|
||||||
|
|
||||||
|
void setSolutionSource(SolutionSource solutionSource) { _solutionSource = solutionSource; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void computeTargets(const AnimVariantMap& animVars, std::vector<IKTarget>& targets, const AnimPoseVec& underPoses);
|
void computeTargets(const AnimVariantMap& animVars, std::vector<IKTarget>& targets, const AnimPoseVec& underPoses);
|
||||||
void solveWithCyclicCoordinateDescent(const std::vector<IKTarget>& targets);
|
void solveWithCyclicCoordinateDescent(const std::vector<IKTarget>& targets);
|
||||||
int solveTargetWithCCD(const IKTarget& target, AnimPoseVec& absolutePoses);
|
int solveTargetWithCCD(const IKTarget& target, AnimPoseVec& absolutePoses);
|
||||||
virtual void setSkeletonInternal(AnimSkeleton::ConstPointer skeleton) override;
|
virtual void setSkeletonInternal(AnimSkeleton::ConstPointer skeleton) override;
|
||||||
void debugDrawConstraints(const AnimContext& context) const;
|
void debugDrawConstraints(const AnimContext& context) const;
|
||||||
|
void initRelativePosesFromSolutionSource(const AnimPoseVec& underPose);
|
||||||
|
void relaxToPoses(const AnimPoseVec& poses);
|
||||||
|
|
||||||
// for AnimDebugDraw rendering
|
// for AnimDebugDraw rendering
|
||||||
virtual const AnimPoseVec& getPosesInternal() const override { return _relativePoses; }
|
virtual const AnimPoseVec& getPosesInternal() const override { return _relativePoses; }
|
||||||
|
@ -103,6 +115,7 @@ protected:
|
||||||
|
|
||||||
float _maxErrorOnLastSolve { FLT_MAX };
|
float _maxErrorOnLastSolve { FLT_MAX };
|
||||||
bool _previousEnableDebugIKTargets { false };
|
bool _previousEnableDebugIKTargets { false };
|
||||||
|
SolutionSource _solutionSource { SolutionSource::RelaxToUnderPoses };
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_AnimInverseKinematics_h
|
#endif // hifi_AnimInverseKinematics_h
|
||||||
|
|
Loading…
Reference in a new issue