mirror of
https://github.com/overte-org/overte.git
synced 2025-08-08 21:57:00 +02:00
added code to read tip and base var info from the json
This commit is contained in:
parent
cdd03646c2
commit
37f92d2319
6 changed files with 194 additions and 82 deletions
|
@ -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",
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
|
@ -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;
|
||||||
|
|
|
@ -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],
|
||||||
|
|
Loading…
Reference in a new issue