mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-08-09 04:18:22 +02:00
version with spline from Spine2 to head
This commit is contained in:
parent
4a6d5e4187
commit
7115796fc4
3 changed files with 96 additions and 54 deletions
|
@ -82,6 +82,16 @@ public:
|
||||||
return foundIndex;
|
return foundIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const AnimPose& getRelativePoseAtJointIndex(int jointIndex) const {
|
||||||
|
for (int i = 0; i < _top; i++) {
|
||||||
|
if (_chain[i].jointIndex == jointIndex) {
|
||||||
|
return _chain[i].relativePose;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return AnimPose::identity;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void buildDirtyAbsolutePoses() {
|
void buildDirtyAbsolutePoses() {
|
||||||
// the relative and absolute pose is the same for the base of the chain.
|
// the relative and absolute pose is the same for the base of the chain.
|
||||||
_chain[_top - 1].absolutePose = _chain[_top - 1].relativePose;
|
_chain[_top - 1].absolutePose = _chain[_top - 1].relativePose;
|
||||||
|
|
|
@ -52,11 +52,11 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const
|
||||||
// check to see if we actually need absolute poses.
|
// check to see if we actually need absolute poses.
|
||||||
AnimPoseVec absolutePoses;
|
AnimPoseVec absolutePoses;
|
||||||
absolutePoses.resize(_poses.size());
|
absolutePoses.resize(_poses.size());
|
||||||
computeAbsolutePoses(absolutePoses);
|
//computeAbsolutePoses(absolutePoses);
|
||||||
AnimPoseVec absolutePoses2;
|
AnimPoseVec absolutePoses2;
|
||||||
absolutePoses2.resize(_poses.size());
|
absolutePoses2.resize(_poses.size());
|
||||||
// do this later
|
// do this later
|
||||||
// computeAbsolutePoses(absolutePoses2);
|
computeAbsolutePoses(absolutePoses2);
|
||||||
|
|
||||||
int jointIndex2 = _skeleton->nameToJointIndex("Spine2");
|
int jointIndex2 = _skeleton->nameToJointIndex("Spine2");
|
||||||
AnimPose origSpine2PoseAbs = _skeleton->getAbsolutePose(jointIndex2, _poses);
|
AnimPose origSpine2PoseAbs = _skeleton->getAbsolutePose(jointIndex2, _poses);
|
||||||
|
@ -67,6 +67,45 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const
|
||||||
//qCDebug(animation) << "origSpine2Pose: " << origSpine2Pose.rot();
|
//qCDebug(animation) << "origSpine2Pose: " << origSpine2Pose.rot();
|
||||||
qCDebug(animation) << "original relative spine2 " << origSpine2PoseAbs;
|
qCDebug(animation) << "original relative spine2 " << origSpine2PoseAbs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IKTarget target2;
|
||||||
|
//int jointIndex2 = _skeleton->nameToJointIndex("Spine2");
|
||||||
|
if (jointIndex2 != -1) {
|
||||||
|
target2.setType(animVars.lookup("spine2Type", (int)IKTarget::Type::RotationAndPosition));
|
||||||
|
target2.setIndex(jointIndex2);
|
||||||
|
AnimPose absPose2 = _skeleton->getAbsolutePose(jointIndex2, _poses);
|
||||||
|
glm::quat rotation2 = animVars.lookupRigToGeometry("spine2Rotation", absPose2.rot());
|
||||||
|
glm::vec3 translation2 = animVars.lookupRigToGeometry("spine2Position", absPose2.trans());
|
||||||
|
float weight2 = animVars.lookup("spine2Weight", "2.0");
|
||||||
|
qCDebug(animation) << "rig to geometry" << rotation2;
|
||||||
|
|
||||||
|
target2.setPose(rotation2, translation2);
|
||||||
|
//target2.setPose(targetSpine2.rot(), targetSpine2.trans());
|
||||||
|
target2.setWeight(weight2);
|
||||||
|
const float* flexCoefficients2 = new float[3]{ 1.0f, 0.5f, 0.25f };
|
||||||
|
target2.setFlexCoefficients(3, flexCoefficients2);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
AnimChain jointChain2;
|
||||||
|
if (_poses.size() > 0) {
|
||||||
|
|
||||||
|
// _snapshotChain.buildFromRelativePoses(_skeleton, _poses, target.getIndex());
|
||||||
|
// jointChain.buildFromRelativePoses(_skeleton, _poses, target.getIndex());
|
||||||
|
// jointChain2.buildFromRelativePoses(_skeleton, underPoses, target2.getIndex());
|
||||||
|
jointChain2.buildFromRelativePoses(_skeleton, _poses, target2.getIndex());
|
||||||
|
|
||||||
|
// for each target solve target with spline
|
||||||
|
solveTargetWithSpline(context, target2, absolutePoses2, false, jointChain2);
|
||||||
|
|
||||||
|
//jointChain.outputRelativePoses(_poses);
|
||||||
|
jointChain2.outputRelativePoses(_poses);
|
||||||
|
computeAbsolutePoses(absolutePoses);
|
||||||
|
//qCDebug(animation) << "Spine2 spline";
|
||||||
|
//jointChain2.dump();
|
||||||
|
//qCDebug(animation) << "Spine2Pose trans after spine2 spline: " << _skeleton->getAbsolutePose(jointIndex2, _poses).trans();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
IKTarget target;
|
IKTarget target;
|
||||||
int jointIndex = _skeleton->nameToJointIndex("Head");
|
int jointIndex = _skeleton->nameToJointIndex("Head");
|
||||||
|
@ -81,8 +120,9 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const
|
||||||
//qCDebug(animation) << "target 1 rotation absolute" << rotation;
|
//qCDebug(animation) << "target 1 rotation absolute" << rotation;
|
||||||
target.setPose(rotation, translation);
|
target.setPose(rotation, translation);
|
||||||
target.setWeight(weight);
|
target.setWeight(weight);
|
||||||
const float* flexCoefficients = new float[5]{ 1.0f, 0.5f, 0.25f, 0.2f, 0.1f };
|
//const float* flexCoefficients = new float[5]{ 1.0f, 0.5f, 0.25f, 0.2f, 0.1f };
|
||||||
target.setFlexCoefficients(5, flexCoefficients);
|
const float* flexCoefficients = new float[2]{ 1.0f, 0.5f };
|
||||||
|
target.setFlexCoefficients(2, flexCoefficients);
|
||||||
|
|
||||||
// record the index of the hips ik target.
|
// record the index of the hips ik target.
|
||||||
if (target.getIndex() == _hipsIndex) {
|
if (target.getIndex() == _hipsIndex) {
|
||||||
|
@ -118,52 +158,23 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const
|
||||||
AnimPose latestSpine2Relative(originalSpine2Relative.rot(), afterSolveSpine2Rel.trans());
|
AnimPose latestSpine2Relative(originalSpine2Relative.rot(), afterSolveSpine2Rel.trans());
|
||||||
//jointChain.setRelativePoseAtJointIndex(jointIndex2, finalSpine2);
|
//jointChain.setRelativePoseAtJointIndex(jointIndex2, finalSpine2);
|
||||||
jointChain.outputRelativePoses(_poses);
|
jointChain.outputRelativePoses(_poses);
|
||||||
|
_poses[_headIndex] = jointChain.getRelativePoseAtJointIndex(_headIndex);
|
||||||
|
_poses[_skeleton->nameToJointIndex("Neck")] = jointChain.getRelativePoseAtJointIndex(_skeleton->nameToJointIndex("Neck"));
|
||||||
|
_poses[_spine2Index] = jointChain.getRelativePoseAtJointIndex(_spine2Index);
|
||||||
|
|
||||||
|
//custom output code for the head. just do the head neck and spine2
|
||||||
|
|
||||||
|
|
||||||
//qCDebug(animation) << "after head spline";
|
//qCDebug(animation) << "after head spline";
|
||||||
//jointChain.dump();
|
//jointChain.dump();
|
||||||
|
|
||||||
computeAbsolutePoses(absolutePoses2);
|
//computeAbsolutePoses(absolutePoses2);
|
||||||
origAbsAfterHeadSpline = _skeleton->getAbsolutePose(jointIndex2, _poses);
|
//origAbsAfterHeadSpline = _skeleton->getAbsolutePose(jointIndex2, _poses);
|
||||||
// qCDebug(animation) << "Spine2 trans after head spline: " << origAbsAfterHeadSpline.trans();
|
// qCDebug(animation) << "Spine2 trans after head spline: " << origAbsAfterHeadSpline.trans();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
IKTarget target2;
|
|
||||||
//int jointIndex2 = _skeleton->nameToJointIndex("Spine2");
|
|
||||||
if (jointIndex2 != -1) {
|
|
||||||
target2.setType(animVars.lookup("spine2Type", (int)IKTarget::Type::RotationAndPosition));
|
|
||||||
target2.setIndex(jointIndex2);
|
|
||||||
AnimPose absPose2 = _skeleton->getAbsolutePose(jointIndex2, _poses);
|
|
||||||
glm::quat rotation2 = animVars.lookupRigToGeometry("spine2Rotation", absPose2.rot());
|
|
||||||
glm::vec3 translation2 = animVars.lookupRigToGeometry("spine2Position", absPose2.trans());
|
|
||||||
float weight2 = animVars.lookup("spine2Weight", "2.0");
|
|
||||||
qCDebug(animation) << "rig to geometry" << rotation2;
|
|
||||||
|
|
||||||
//target2.setPose(rotation2, translation2);
|
|
||||||
target2.setPose(targetSpine2.rot(), targetSpine2.trans());
|
|
||||||
target2.setWeight(weight2);
|
|
||||||
const float* flexCoefficients2 = new float[3]{ 1.0f, 0.5f, 0.25f };
|
|
||||||
target2.setFlexCoefficients(3, flexCoefficients2);
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
AnimChain jointChain2;
|
|
||||||
if (_poses.size() > 0) {
|
|
||||||
|
|
||||||
// _snapshotChain.buildFromRelativePoses(_skeleton, _poses, target.getIndex());
|
|
||||||
// jointChain.buildFromRelativePoses(_skeleton, _poses, target.getIndex());
|
|
||||||
// jointChain2.buildFromRelativePoses(_skeleton, underPoses, target2.getIndex());
|
|
||||||
jointChain2.buildFromRelativePoses(_skeleton, _poses, target2.getIndex());
|
|
||||||
|
|
||||||
// for each target solve target with spline
|
|
||||||
solveTargetWithSpline(context, target2, absolutePoses2, false, jointChain2);
|
|
||||||
|
|
||||||
//jointChain.outputRelativePoses(_poses);
|
|
||||||
jointChain2.outputRelativePoses(_poses);
|
|
||||||
//qCDebug(animation) << "Spine2 spline";
|
|
||||||
//jointChain2.dump();
|
|
||||||
//qCDebug(animation) << "Spine2Pose trans after spine2 spline: " << _skeleton->getAbsolutePose(jointIndex2, _poses).trans();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
const float FRAMES_PER_SECOND = 30.0f;
|
const float FRAMES_PER_SECOND = 30.0f;
|
||||||
_interpAlphaVel = FRAMES_PER_SECOND / _interpDuration;
|
_interpAlphaVel = FRAMES_PER_SECOND / _interpDuration;
|
||||||
|
@ -218,6 +229,7 @@ void AnimSplineIK::setSkeletonInternal(AnimSkeleton::ConstPointer skeleton) {
|
||||||
AnimNode::setSkeletonInternal(skeleton);
|
AnimNode::setSkeletonInternal(skeleton);
|
||||||
_headIndex = _skeleton->nameToJointIndex("Head");
|
_headIndex = _skeleton->nameToJointIndex("Head");
|
||||||
_hipsIndex = _skeleton->nameToJointIndex("Hips");
|
_hipsIndex = _skeleton->nameToJointIndex("Hips");
|
||||||
|
_spine2Index = _skeleton->nameToJointIndex("Spine2");
|
||||||
lookUpIndices();
|
lookUpIndices();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -234,16 +246,24 @@ static CubicHermiteSplineFunctorWithArcLength computeSplineFromTipAndBase(const
|
||||||
void AnimSplineIK::solveTargetWithSpline(const AnimContext& context, const IKTarget& target, const AnimPoseVec& absolutePoses, bool debug, AnimChain& chainInfoOut) const {
|
void AnimSplineIK::solveTargetWithSpline(const AnimContext& context, const IKTarget& target, const AnimPoseVec& absolutePoses, bool debug, AnimChain& chainInfoOut) const {
|
||||||
|
|
||||||
const int baseIndex = _hipsIndex;
|
const int baseIndex = _hipsIndex;
|
||||||
|
const int headBaseIndex = _spine2Index;
|
||||||
|
|
||||||
// build spline from tip to base
|
// build spline from tip to base
|
||||||
AnimPose tipPose = AnimPose(glm::vec3(1.0f), target.getRotation(), target.getTranslation());
|
AnimPose tipPose = AnimPose(glm::vec3(1.0f), target.getRotation(), target.getTranslation());
|
||||||
AnimPose basePose = absolutePoses[baseIndex];
|
AnimPose basePose;
|
||||||
|
if (target.getIndex() == _headIndex) {
|
||||||
|
basePose = absolutePoses[headBaseIndex];
|
||||||
|
} else {
|
||||||
|
basePose = absolutePoses[baseIndex];
|
||||||
|
}
|
||||||
|
|
||||||
CubicHermiteSplineFunctorWithArcLength spline;
|
CubicHermiteSplineFunctorWithArcLength spline;
|
||||||
if (target.getIndex() == _headIndex) {
|
if (target.getIndex() == _headIndex) {
|
||||||
// set gain factors so that more curvature occurs near the tip of the spline.
|
// set gain factors so that more curvature occurs near the tip of the spline.
|
||||||
const float HIPS_GAIN = 0.5f;
|
const float HIPS_GAIN = 0.5f;
|
||||||
const float HEAD_GAIN = 1.0f;
|
const float HEAD_GAIN = 1.0f;
|
||||||
spline = computeSplineFromTipAndBase(tipPose, basePose, HIPS_GAIN, HEAD_GAIN);
|
//spline = computeSplineFromTipAndBase(tipPose, basePose, HIPS_GAIN, HEAD_GAIN);
|
||||||
|
spline = computeSplineFromTipAndBase(tipPose, basePose);
|
||||||
} else {
|
} else {
|
||||||
spline = computeSplineFromTipAndBase(tipPose, basePose);
|
spline = computeSplineFromTipAndBase(tipPose, basePose);
|
||||||
}
|
}
|
||||||
|
@ -347,14 +367,20 @@ void AnimSplineIK::computeAndCacheSplineJointInfosForIKTarget(const AnimContext&
|
||||||
|
|
||||||
// build spline between the default poses.
|
// build spline between the default poses.
|
||||||
AnimPose tipPose = _skeleton->getAbsoluteDefaultPose(target.getIndex());
|
AnimPose tipPose = _skeleton->getAbsoluteDefaultPose(target.getIndex());
|
||||||
AnimPose basePose = _skeleton->getAbsoluteDefaultPose(_hipsIndex);
|
AnimPose basePose;
|
||||||
|
if (target.getIndex() == _headIndex) {
|
||||||
|
basePose = _skeleton->getAbsoluteDefaultPose(_spine2Index);
|
||||||
|
} else {
|
||||||
|
basePose = _skeleton->getAbsoluteDefaultPose(_hipsIndex);
|
||||||
|
}
|
||||||
|
|
||||||
CubicHermiteSplineFunctorWithArcLength spline;
|
CubicHermiteSplineFunctorWithArcLength spline;
|
||||||
if (target.getIndex() == _headIndex) {
|
if (target.getIndex() == _headIndex) {
|
||||||
// set gain factors so that more curvature occurs near the tip of the spline.
|
// set gain factors so that more curvature occurs near the tip of the spline.
|
||||||
const float HIPS_GAIN = 0.5f;
|
const float HIPS_GAIN = 0.5f;
|
||||||
const float HEAD_GAIN = 1.0f;
|
const float HEAD_GAIN = 1.0f;
|
||||||
spline = computeSplineFromTipAndBase(tipPose, basePose, HIPS_GAIN, HEAD_GAIN);
|
// spline = computeSplineFromTipAndBase(tipPose, basePose, HIPS_GAIN, HEAD_GAIN);
|
||||||
|
spline = computeSplineFromTipAndBase(tipPose, basePose);
|
||||||
} else {
|
} else {
|
||||||
spline = computeSplineFromTipAndBase(tipPose, basePose);
|
spline = computeSplineFromTipAndBase(tipPose, basePose);
|
||||||
}
|
}
|
||||||
|
@ -367,7 +393,12 @@ void AnimSplineIK::computeAndCacheSplineJointInfosForIKTarget(const AnimContext&
|
||||||
glm::vec3 baseToTipNormal = baseToTip / baseToTipLength;
|
glm::vec3 baseToTipNormal = baseToTip / baseToTipLength;
|
||||||
|
|
||||||
int index = target.getIndex();
|
int index = target.getIndex();
|
||||||
int endIndex = _skeleton->getParentIndex(_hipsIndex);
|
int endIndex;
|
||||||
|
if (target.getIndex() == _headIndex) {
|
||||||
|
endIndex = _skeleton->getParentIndex(_spine2Index);
|
||||||
|
} else {
|
||||||
|
endIndex = _skeleton->getParentIndex(_hipsIndex);
|
||||||
|
}
|
||||||
while (index != endIndex) {
|
while (index != endIndex) {
|
||||||
AnimPose defaultPose = _skeleton->getAbsoluteDefaultPose(index);
|
AnimPose defaultPose = _skeleton->getAbsoluteDefaultPose(index);
|
||||||
|
|
||||||
|
|
|
@ -51,12 +51,13 @@ protected:
|
||||||
QString _baseJointName;
|
QString _baseJointName;
|
||||||
QString _tipJointName;
|
QString _tipJointName;
|
||||||
|
|
||||||
int _baseParentJointIndex{ -1 };
|
int _baseParentJointIndex { -1 };
|
||||||
int _baseJointIndex{ -1 };
|
int _baseJointIndex { -1 };
|
||||||
int _tipJointIndex{ -1 };
|
int _tipJointIndex { -1 };
|
||||||
int _headIndex{ -1 };
|
int _headIndex { -1 };
|
||||||
int _hipsIndex{ -1 };
|
int _hipsIndex { -1 };
|
||||||
int _hipsTargetIndex{ -1 };
|
int _spine2Index { -1 };
|
||||||
|
int _hipsTargetIndex { -1 };
|
||||||
|
|
||||||
QString _alphaVar; // float - (0, 1) 0 means underPoses only, 1 means IK only.
|
QString _alphaVar; // float - (0, 1) 0 means underPoses only, 1 means IK only.
|
||||||
QString _enabledVar; // bool
|
QString _enabledVar; // bool
|
||||||
|
|
Loading…
Reference in a new issue