added code to read tip and base var info from the json

This commit is contained in:
amantley 2019-01-24 17:02:30 -08:00
parent cdd03646c2
commit 37f92d2319
6 changed files with 194 additions and 82 deletions

View file

@ -183,6 +183,13 @@
"interpDuration": 15, "interpDuration": 15,
"baseJointName": "Hips", "baseJointName": "Hips",
"tipJointName": "Head", "tipJointName": "Head",
"secondaryTargetJointName": "Spine2",
"basePositionVar": "hipsPosition",
"baseRotationVar": "hipsRotation",
"tipPositionVar": "headPosition",
"tipRotationVar": "headRotation",
"secondaryTargetPositionVar": "spine2Position",
"secondaryTargetRotationVar": "spine2Rotation",
"alphaVar": "splineIKAlpha", "alphaVar": "splineIKAlpha",
"enabledVar": "splineIKEnabled", "enabledVar": "splineIKEnabled",
"endEffectorRotationVarVar": "splineIKRotationVar", "endEffectorRotationVarVar": "splineIKRotationVar",

View file

@ -243,13 +243,6 @@ void AnimInverseKinematics::solve(const AnimContext& context, const std::vector<
break; break;
case IKTarget::Type::Spline: case IKTarget::Type::Spline:
solveTargetWithSpline(context, targets[i], absolutePoses, debug, jointChainInfoVec[i]); 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; break;
default: default:
solveTargetWithCCD(context, targets[i], absolutePoses, debug, jointChainInfoVec[i]); 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 // compute maxError
maxError = 0.0f; maxError = 0.0f;
for (size_t i = 0; i < targets.size(); i++) { 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; AnimPose relPose = parentAbsPose.inverse() * flexedAbsPose;
bool constrained = false; bool constrained = false;
/*
if (splineJointInfo.jointIndex != _hipsIndex) { if (splineJointInfo.jointIndex != _hipsIndex) {
// constrain the amount the spine can stretch or compress // constrain the amount the spine can stretch or compress
float length = glm::length(relPose.trans()); float length = glm::length(relPose.trans());
@ -854,7 +853,7 @@ void AnimInverseKinematics::solveTargetWithSpline(const AnimContext& context, co
relPose.trans() = glm::vec3(0.0f); relPose.trans() = glm::vec3(0.0f);
} }
} }
*/
jointChainInfoOut.jointInfoVec[i] = { relPose.rot(), relPose.trans(), splineJointInfo.jointIndex, constrained }; jointChainInfoOut.jointInfoVec[i] = { relPose.rot(), relPose.trans(), splineJointInfo.jointIndex, constrained };
parentAbsPose = flexedAbsPose; parentAbsPose = flexedAbsPose;

View file

@ -585,6 +585,13 @@ static AnimNode::Pointer loadSplineIKNode(const QJsonObject& jsonObj, const QStr
READ_FLOAT(interpDuration, jsonObj, id, jsonUrl, nullptr); READ_FLOAT(interpDuration, jsonObj, id, jsonUrl, nullptr);
READ_STRING(baseJointName, jsonObj, id, jsonUrl, nullptr); READ_STRING(baseJointName, jsonObj, id, jsonUrl, nullptr);
READ_STRING(tipJointName, 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(alphaVar, jsonObj, id, jsonUrl, nullptr);
READ_STRING(enabledVar, jsonObj, id, jsonUrl, nullptr); READ_STRING(enabledVar, jsonObj, id, jsonUrl, nullptr);
READ_STRING(endEffectorRotationVarVar, 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<AnimSplineIK>(id, alpha, enabled, interpDuration, auto node = std::make_shared<AnimSplineIK>(id, alpha, enabled, interpDuration,
baseJointName, tipJointName, baseJointName, tipJointName,
alphaVar, enabledVar, alphaVar, enabledVar, endEffectorRotationVarVar, endEffectorPositionVarVar,
endEffectorRotationVarVar, endEffectorPositionVarVar); basePositionVar, baseRotationVar,
tipPositionVar, tipRotationVar, secondaryTargetJointName, secondaryTargetPositionVar, secondaryTargetRotationVar);
return node; return node;
} }

View file

@ -20,7 +20,14 @@ AnimSplineIK::AnimSplineIK(const QString& id, float alpha, bool enabled, float i
const QString& baseJointName, const QString& baseJointName,
const QString& tipJointName, const QString& tipJointName,
const QString& alphaVar, const QString& enabledVar, 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), AnimNode(AnimNode::Type::SplineIK, id),
_alpha(alpha), _alpha(alpha),
_enabled(enabled), _enabled(enabled),
@ -32,7 +39,15 @@ AnimSplineIK::AnimSplineIK(const QString& id, float alpha, bool enabled, float i
_endEffectorRotationVarVar(endEffectorRotationVarVar), _endEffectorRotationVarVar(endEffectorRotationVarVar),
_endEffectorPositionVarVar(endEffectorPositionVarVar), _endEffectorPositionVarVar(endEffectorPositionVarVar),
_prevEndEffectorRotationVar(), _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) { if (_children.size() != 1) {
return _poses; return _poses;
} }
// evalute underPoses // evaluate underPoses
AnimPoseVec underPoses = _children[0]->evaluate(animVars, context, dt, triggersOut); AnimPoseVec underPoses = _children[0]->evaluate(animVars, context, dt, triggersOut);
_poses = underPoses; _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) { if (_poses.size() > 0) {
AnimPose hipsUnderPose = _skeleton->getAbsolutePose(_hipsIndex, _poses); AnimPose hipsUnderPose = _skeleton->getAbsolutePose(_hipsIndex, _poses);
glm::quat hipsTargetRotation = animVars.lookupRigToGeometry("hipsRotation", hipsUnderPose.rot()); hipsTargetRotation = animVars.lookupRigToGeometry("hipsRotation", hipsUnderPose.rot());
glm::vec3 hipsTargetTranslation = animVars.lookupRigToGeometry("hipsPosition", hipsUnderPose.trans()); hipsTargetTranslation = animVars.lookupRigToGeometry("hipsPosition", hipsUnderPose.trans());
AnimPose absHipsTargetPose(hipsTargetRotation, hipsTargetTranslation); AnimPose absHipsTargetPose(hipsTargetRotation, hipsTargetTranslation);
int hipsParentIndex = _skeleton->getParentIndex(_hipsIndex); int hipsParentIndex = _skeleton->getParentIndex(_hipsIndex);
@ -76,23 +94,22 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const
computeAbsolutePoses(absolutePoses); computeAbsolutePoses(absolutePoses);
IKTarget target; IKTarget target;
if (_headIndex != -1) { if (_tipJointIndex != -1) {
target.setType(animVars.lookup("headType", (int)IKTarget::Type::RotationAndPosition)); target.setType((int)IKTarget::Type::Spline);
target.setIndex(_headIndex); target.setIndex(_tipJointIndex);
AnimPose absPose = _skeleton->getAbsolutePose(_headIndex, _poses); AnimPose absPose = _skeleton->getAbsolutePose(_tipJointIndex, _poses);
glm::quat rotation = animVars.lookupRigToGeometry("headRotation", absPose.rot()); glm::quat rotation = animVars.lookupRigToGeometry(_tipRotationVar, absPose.rot());
glm::vec3 translation = animVars.lookupRigToGeometry("headPosition", absPose.trans()); glm::vec3 translation = animVars.lookupRigToGeometry(_tipPositionVar, absPose.trans());
float weight = animVars.lookup("headWeight", "4.0"); float weight = 1.0f;
target.setPose(rotation, translation); target.setPose(rotation, translation);
target.setWeight(weight); target.setWeight(weight);
const float* flexCoefficients = new float[5]{ 1.0f, 1.0f, 1.0f, 1.0f, 1.0f }; const float* flexCoefficients = new float[5]{ 1.0f, 0.5f, 0.25f, 0.2f, 0.1f };
//const float* flexCoefficients = new float[2]{ 0.0f, 1.0f };
target.setFlexCoefficients(5, flexCoefficients); target.setFlexCoefficients(5, flexCoefficients);
} }
AnimChain jointChain; AnimChain jointChain;
AnimPose targetSpine2; AnimPose updatedSecondaryTarget;
AnimPoseVec absolutePoses2; AnimPoseVec absolutePoses2;
absolutePoses2.resize(_poses.size()); absolutePoses2.resize(_poses.size());
if (_poses.size() > 0) { if (_poses.size() > 0) {
@ -100,43 +117,47 @@ const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const
//_snapshotChain.buildFromRelativePoses(_skeleton, _poses, target.getIndex()); //_snapshotChain.buildFromRelativePoses(_skeleton, _poses, target.getIndex());
jointChain.buildFromRelativePoses(_skeleton, _poses, target.getIndex()); jointChain.buildFromRelativePoses(_skeleton, _poses, target.getIndex());
solveTargetWithSpline(context, target, absolutePoses, false, jointChain); 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); jointChain.outputRelativePoses(_poses);
AnimPose afterSolveSpine2 = _skeleton->getAbsolutePose(_spine2Index, _poses); AnimPose afterSolveSecondaryTarget = _skeleton->getAbsolutePose(_secondaryTargetIndex, _poses);
glm::quat spine2RotationTarget = animVars.lookupRigToGeometry("spine2Rotation", afterSolveSpine2.rot()); 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); computeAbsolutePoses(absolutePoses2);
if (_spine2Index != -1) { if (_secondaryTargetIndex != -1) {
target2.setType(animVars.lookup("spine2Type", (int)IKTarget::Type::RotationAndPosition)); secondaryTarget.setType((int)IKTarget::Type::Spline);
target2.setIndex(_spine2Index); secondaryTarget.setIndex(_secondaryTargetIndex);
float weight2 = animVars.lookup("spine2Weight", "2.0"); float weight2 = 1.0f;
target2.setPose(targetSpine2.rot(), targetSpine2.trans()); secondaryTarget.setPose(updatedSecondaryTarget.rot(), updatedSecondaryTarget.trans());
target2.setWeight(weight2); secondaryTarget.setWeight(weight2);
const float* flexCoefficients2 = new float[3]{ 1.0f, 1.0f, 1.0f }; 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; AnimPose beforeSolveChestNeck;
if (_poses.size() > 0) { if (_poses.size() > 0) {
beforeSolveChestNeck = _skeleton->getAbsolutePose(_skeleton->nameToJointIndex("Neck"), _poses); beforeSolveChestNeck = _skeleton->getAbsolutePose(_skeleton->nameToJointIndex("Neck"), _poses);
jointChain2.buildFromRelativePoses(_skeleton, _poses, target2.getIndex()); secondaryJointChain.buildFromRelativePoses(_skeleton, _poses, secondaryTarget.getIndex());
solveTargetWithSpline(context, target2, absolutePoses2, false, jointChain2); solveTargetWithSpline(context, secondaryTarget, absolutePoses2, false, secondaryJointChain);
jointChain2.outputRelativePoses(_poses); secondaryJointChain.outputRelativePoses(_poses);
} }
*/
*/
const float FRAMES_PER_SECOND = 30.0f; const float FRAMES_PER_SECOND = 30.0f;
_interpAlphaVel = FRAMES_PER_SECOND / _interpDuration; _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 // update the relative poses and then we are done
// set the tip/head rotation to match the absolute rotation of the target. // set the tip/head rotation to match the absolute rotation of the target.
int headParent = _skeleton->getParentIndex(_headIndex); int tipParent = _skeleton->getParentIndex(_tipJointIndex);
int spine2Parent = _skeleton->getParentIndex(_spine2Index); int secondaryTargetParent = _skeleton->getParentIndex(_secondaryTargetIndex);
if ((spine2Parent != -1) && (headParent != -1) && (_poses.size() > 0)) { if ((secondaryTargetParent != -1) && (tipParent != -1) && (_poses.size() > 0)) {
/* /*
AnimPose spine2Target(target2.getRotation(), target2.getTranslation()); AnimPose secondaryTargetPose(target2.getRotation(), target2.getTranslation());
AnimPose finalSpine2RelativePose = _skeleton->getAbsolutePose(spine2Parent, _poses).inverse() * spine2Target; AnimPose secondaryTargetRelativePose = _skeleton->getAbsolutePose(secondaryTargetParent, _poses).inverse() * secondaryTargetPose;
_poses[_spine2Index] = finalSpine2RelativePose; _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()); AnimPose finalNeckAbsolute = AnimPose(safeLerp(target2.getRotation(), target.getRotation(), 1.0f),neckAbsolute.trans());
_poses[headParent] = spine2Target.inverse() * beforeSolveChestNeck; _poses[headParent] = spine2Target.inverse() * beforeSolveChestNeck;
*/ */
AnimPose headTarget(target.getRotation(),target.getTranslation()); //AnimPose tipTarget(target.getRotation(),target.getTranslation());
AnimPose finalHeadRelativePose = _skeleton->getAbsolutePose(headParent,_poses).inverse() * headTarget; //AnimPose tipRelativePose = _skeleton->getAbsolutePose(tipParent,_poses).inverse() * headTarget;
_poses[_headIndex] = finalHeadRelativePose; //_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; return _poses;
} }
@ -174,11 +231,12 @@ void AnimSplineIK::lookUpIndices() {
assert(_skeleton); assert(_skeleton);
// look up bone indices by name // look up bone indices by name
std::vector<int> indices = _skeleton->lookUpJointIndices({ _baseJointName, _tipJointName }); std::vector<int> indices = _skeleton->lookUpJointIndices({ _baseJointName, _tipJointName, _secondaryTargetJointName });
// cache the results // cache the results
_baseJointIndex = indices[0]; _baseJointIndex = indices[0];
_tipJointIndex = indices[1]; _tipJointIndex = indices[1];
_secondaryTargetIndex = indices[2];
if (_baseJointIndex != -1) { if (_baseJointIndex != -1) {
_baseParentJointIndex = _skeleton->getParentIndex(_baseJointIndex); _baseParentJointIndex = _skeleton->getParentIndex(_baseJointIndex);
@ -206,9 +264,8 @@ const AnimPoseVec& AnimSplineIK::getPosesInternal() const {
void AnimSplineIK::setSkeletonInternal(AnimSkeleton::ConstPointer skeleton) { 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();
} }
@ -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 { void AnimSplineIK::solveTargetWithSpline(const AnimContext& context, const IKTarget& target, const AnimPoseVec& absolutePoses, bool debug, AnimChain& chainInfoOut) const {
const int baseIndex = _hipsIndex; const int baseIndex = _baseJointIndex;
const int headBaseIndex = _spine2Index; const int tipBaseIndex = _secondaryTargetIndex;
// 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; AnimPose basePose;
//if (target.getIndex() == _headIndex) { //if (target.getIndex() == _tipJointIndex) {
// basePose = absolutePoses[headBaseIndex]; // basePose = absolutePoses[tipBaseIndex];
//} else { //} else {
basePose = absolutePoses[baseIndex]; basePose = absolutePoses[baseIndex];
//} //}
CubicHermiteSplineFunctorWithArcLength spline; CubicHermiteSplineFunctorWithArcLength spline;
if (target.getIndex() == _headIndex) { if (target.getIndex() == _tipJointIndex) {
// 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;
@ -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 // for head splines, preform most twist toward the tip by using ease in function. t^2
float rotT = t; float rotT = t;
if (target.getIndex() == _headIndex) { if (target.getIndex() == _tipJointIndex) {
rotT = t * t; rotT = t * t;
} }
glm::quat twistRot = safeLerp(basePose.rot(), tipPose.rot(), rotT); 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; AnimPose relPose = parentAbsPose.inverse() * flexedAbsPose;
bool constrained = false; bool constrained = false;
if (splineJointInfo.jointIndex != _hipsIndex) { if (splineJointInfo.jointIndex != _baseJointIndex) {
// constrain the amount the spine can stretch or compress // constrain the amount the spine can stretch or compress
float length = glm::length(relPose.trans()); float length = glm::length(relPose.trans());
const float EPSILON = 0.0001f; const float EPSILON = 0.0001f;
@ -350,15 +407,15 @@ 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; AnimPose basePose;
if (target.getIndex() == _headIndex) { if (target.getIndex() == _tipJointIndex) {
basePose = _skeleton->getAbsoluteDefaultPose(_hipsIndex); basePose = _skeleton->getAbsoluteDefaultPose(_baseJointIndex);
//basePose = _skeleton->getAbsoluteDefaultPose(_spine2Index); //basePose = _skeleton->getAbsoluteDefaultPose(_secondaryTargetIndex);
} else { } else {
basePose = _skeleton->getAbsoluteDefaultPose(_hipsIndex); basePose = _skeleton->getAbsoluteDefaultPose(_baseJointIndex);
} }
CubicHermiteSplineFunctorWithArcLength spline; CubicHermiteSplineFunctorWithArcLength spline;
if (target.getIndex() == _headIndex) { if (target.getIndex() == _tipJointIndex) {
// 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;
@ -377,11 +434,11 @@ void AnimSplineIK::computeAndCacheSplineJointInfosForIKTarget(const AnimContext&
int index = target.getIndex(); int index = target.getIndex();
int endIndex; int endIndex;
if (target.getIndex() == _headIndex) { if (target.getIndex() == _tipJointIndex) {
endIndex = _skeleton->getParentIndex(_spine2Index); //endIndex = _skeleton->getParentIndex(_secondaryTargetIndex);
// endIndex = _skeleton->getParentIndex(_hipsIndex); endIndex = _skeleton->getParentIndex(_baseJointIndex);
} else { } else {
endIndex = _skeleton->getParentIndex(_hipsIndex); endIndex = _skeleton->getParentIndex(_baseJointIndex);
} }
while (index != endIndex) { while (index != endIndex) {
AnimPose defaultPose = _skeleton->getAbsoluteDefaultPose(index); AnimPose defaultPose = _skeleton->getAbsoluteDefaultPose(index);
@ -410,11 +467,34 @@ void AnimSplineIK::computeAndCacheSplineJointInfosForIKTarget(const AnimContext&
_splineJointInfoMap[target.getIndex()] = splineJointInfoVec; _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()))); assert(_skeleton && ((poses.size() == 0) || (_skeleton->getNumJoints() == (int)poses.size())));
if (_skeleton->getNumJoints() == (int)poses.size()) { if (_skeleton->getNumJoints() == (int)poses.size()) {
_poses = poses; _poses = poses;
} else { } else {
_poses.clear(); _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<float>& 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);
}
*/
} }

View file

@ -21,7 +21,12 @@ public:
AnimSplineIK(const QString& id, float alpha, bool enabled, float interpDuration, AnimSplineIK(const QString& id, float alpha, bool enabled, float interpDuration,
const QString& baseJointName, const QString& tipJointName, const QString& baseJointName, const QString& tipJointName,
const QString& alphaVar, const QString& enabledVar, 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 ~AnimSplineIK() override;
virtual const AnimPoseVec& evaluate(const AnimVariantMap& animVars, const AnimContext& context, float dt, AnimVariantMap& triggersOut) override; virtual const AnimPoseVec& evaluate(const AnimVariantMap& animVars, const AnimContext& context, float dt, AnimVariantMap& triggersOut) override;
@ -52,9 +57,17 @@ protected:
float _interpDuration; float _interpDuration;
QString _baseJointName; QString _baseJointName;
QString _tipJointName; QString _tipJointName;
QString _secondaryTargetJointName;
QString _basePositionVar;
QString _baseRotationVar;
QString _tipPositionVar;
QString _tipRotationVar;
QString _secondaryTargetPositionVar;
QString _secondaryTargetRotationVar;
int _baseParentJointIndex { -1 }; int _baseParentJointIndex { -1 };
int _baseJointIndex { -1 }; int _baseJointIndex { -1 };
int _secondaryTargetIndex { -1 };
int _tipJointIndex { -1 }; int _tipJointIndex { -1 };
int _headIndex { -1 }; int _headIndex { -1 };
int _hipsIndex { -1 }; int _hipsIndex { -1 };
@ -69,6 +82,8 @@ protected:
QString _prevEndEffectorRotationVar; QString _prevEndEffectorRotationVar;
QString _prevEndEffectorPositionVar; QString _prevEndEffectorPositionVar;
bool _previousEnableDebugIKTargets { false };
InterpType _interpType{ InterpType::None }; InterpType _interpType{ InterpType::None };
float _interpAlphaVel{ 0.0f }; float _interpAlphaVel{ 0.0f };
float _interpAlpha{ 0.0f }; float _interpAlpha{ 0.0f };
@ -84,6 +99,9 @@ protected:
bool _lastEnableDebugDrawIKTargets{ false }; bool _lastEnableDebugDrawIKTargets{ false };
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;
void AnimSplineIK::setTargetVars(const QString& jointName, const QString& positionVar, const QString& rotationVar,
const QString& typeVar, const QString& weightVar, float weight, const std::vector<float>& flexCoefficients,
const QString& poleVectorEnabledVar, const QString& poleReferenceVectorVar, const QString& poleVectorVar);
void computeAndCacheSplineJointInfosForIKTarget(const AnimContext& context, const IKTarget& target) const; void computeAndCacheSplineJointInfosForIKTarget(const AnimContext& context, const IKTarget& target) const;
const std::vector<SplineJointInfo>* findOrCreateSplineJointInfo(const AnimContext& context, const IKTarget& target) const; const std::vector<SplineJointInfo>* findOrCreateSplineJointInfo(const AnimContext& context, const IKTarget& target) const;
mutable std::map<int, std::vector<SplineJointInfo>> _splineJointInfoMap; mutable std::map<int, std::vector<SplineJointInfo>> _splineJointInfoMap;

View file

@ -1857,14 +1857,14 @@ void Rig::updateFromControllerParameters(const ControllerParameters& params, flo
updateHead(_headEnabled, hipsEnabled, params.primaryControllerPoses[PrimaryControllerType_Head]); updateHead(_headEnabled, hipsEnabled, params.primaryControllerPoses[PrimaryControllerType_Head]);
updateHands(leftHandEnabled, rightHandEnabled, hipsEnabled, hipsEstimated, leftArmEnabled, rightArmEnabled, _headEnabled, dt, //updateHands(leftHandEnabled, rightHandEnabled, hipsEnabled, hipsEstimated, leftArmEnabled, rightArmEnabled, _headEnabled, dt,
params.primaryControllerPoses[PrimaryControllerType_LeftHand], params.primaryControllerPoses[PrimaryControllerType_RightHand], // params.primaryControllerPoses[PrimaryControllerType_LeftHand], params.primaryControllerPoses[PrimaryControllerType_RightHand],
params.hipsShapeInfo, params.spineShapeInfo, params.spine1ShapeInfo, params.spine2ShapeInfo, // params.hipsShapeInfo, params.spineShapeInfo, params.spine1ShapeInfo, params.spine2ShapeInfo,
params.rigToSensorMatrix, sensorToRigMatrix); // params.rigToSensorMatrix, sensorToRigMatrix);
//updateHands2(leftHandEnabled, rightHandEnabled, _headEnabled, updateHands2(leftHandEnabled, rightHandEnabled, _headEnabled,
// params.primaryControllerPoses[PrimaryControllerType_LeftHand], params.primaryControllerPoses[PrimaryControllerType_RightHand], params.primaryControllerPoses[PrimaryControllerType_LeftHand], params.primaryControllerPoses[PrimaryControllerType_RightHand],
// params.rigToSensorMatrix, sensorToRigMatrix); params.rigToSensorMatrix, sensorToRigMatrix);
updateFeet(leftFootEnabled, rightFootEnabled, _headEnabled, updateFeet(leftFootEnabled, rightFootEnabled, _headEnabled,
params.primaryControllerPoses[PrimaryControllerType_LeftFoot], params.primaryControllerPoses[PrimaryControllerType_RightFoot], params.primaryControllerPoses[PrimaryControllerType_LeftFoot], params.primaryControllerPoses[PrimaryControllerType_RightFoot],