mirror of
https://github.com/overte-org/overte.git
synced 2025-08-10 22:40:27 +02:00
Added support for weights per target
This commit is contained in:
parent
67fbb15faa
commit
1e276d113c
7 changed files with 51 additions and 16 deletions
|
@ -57,6 +57,8 @@
|
||||||
"positionVar": "hipsPosition",
|
"positionVar": "hipsPosition",
|
||||||
"rotationVar": "hipsRotation",
|
"rotationVar": "hipsRotation",
|
||||||
"typeVar": "hipsType",
|
"typeVar": "hipsType",
|
||||||
|
"weightVar": "hipsWeight",
|
||||||
|
"weight": 1.0,
|
||||||
"flexCoefficients": [1]
|
"flexCoefficients": [1]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -64,20 +66,26 @@
|
||||||
"positionVar": "rightHandPosition",
|
"positionVar": "rightHandPosition",
|
||||||
"rotationVar": "rightHandRotation",
|
"rotationVar": "rightHandRotation",
|
||||||
"typeVar": "rightHandType",
|
"typeVar": "rightHandType",
|
||||||
"flexCoefficients": [1, 0.5, 0.5, 0.5, 0.25, 0.1, 0.1, 0.1, 0.1]
|
"weightVar": "rightHandWeight",
|
||||||
|
"weight": 1.0,
|
||||||
|
"flexCoefficients": [1, 0.5, 0.5, 0.25, 0.1, 0.05, 0.01, 0.0, 0.0]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"jointName": "LeftHand",
|
"jointName": "LeftHand",
|
||||||
"positionVar": "leftHandPosition",
|
"positionVar": "leftHandPosition",
|
||||||
"rotationVar": "leftHandRotation",
|
"rotationVar": "leftHandRotation",
|
||||||
"typeVar": "leftHandType",
|
"typeVar": "leftHandType",
|
||||||
"flexCoefficients": [1, 0.5, 0.5, 0.5, 0.25, 0.1, 0.1, 0.1, 0.1]
|
"weightVar": "leftHandWeight",
|
||||||
|
"weight": 1.0,
|
||||||
|
"flexCoefficients": [1, 0.5, 0.5, 0.25, 0.1, 0.05, 0.01, 0.0, 0.0]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"jointName": "RightFoot",
|
"jointName": "RightFoot",
|
||||||
"positionVar": "rightFootPosition",
|
"positionVar": "rightFootPosition",
|
||||||
"rotationVar": "rightFootRotation",
|
"rotationVar": "rightFootRotation",
|
||||||
"typeVar": "rightFootType",
|
"typeVar": "rightFootType",
|
||||||
|
"weightVar": "rightFootWeight",
|
||||||
|
"weight": 1.0,
|
||||||
"flexCoefficients": [1, 0.45, 0.45]
|
"flexCoefficients": [1, 0.45, 0.45]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -85,6 +93,8 @@
|
||||||
"positionVar": "leftFootPosition",
|
"positionVar": "leftFootPosition",
|
||||||
"rotationVar": "leftFootRotation",
|
"rotationVar": "leftFootRotation",
|
||||||
"typeVar": "leftFootType",
|
"typeVar": "leftFootType",
|
||||||
|
"weightVar": "leftFootWeight",
|
||||||
|
"weight": 1.0,
|
||||||
"flexCoefficients": [1, 0.45, 0.45]
|
"flexCoefficients": [1, 0.45, 0.45]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -92,6 +102,8 @@
|
||||||
"positionVar": "spine2Position",
|
"positionVar": "spine2Position",
|
||||||
"rotationVar": "spine2Rotation",
|
"rotationVar": "spine2Rotation",
|
||||||
"typeVar": "spine2Type",
|
"typeVar": "spine2Type",
|
||||||
|
"weightVar": "spine2Weight",
|
||||||
|
"weight": 1.0,
|
||||||
"flexCoefficients": [0.45, 0.45]
|
"flexCoefficients": [0.45, 0.45]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -99,7 +111,9 @@
|
||||||
"positionVar": "headPosition",
|
"positionVar": "headPosition",
|
||||||
"rotationVar": "headRotation",
|
"rotationVar": "headRotation",
|
||||||
"typeVar": "headType",
|
"typeVar": "headType",
|
||||||
"flexCoefficients": [1, 0.5, 0.25, 0.25, 0.25]
|
"weightVar": "headWeight",
|
||||||
|
"weight": 4.0,
|
||||||
|
"flexCoefficients": [1, 0.5, 0.5, 0.5, 0.5]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
|
@ -22,10 +22,12 @@
|
||||||
#include "AnimationLogging.h"
|
#include "AnimationLogging.h"
|
||||||
|
|
||||||
AnimInverseKinematics::IKTargetVar::IKTargetVar(const QString& jointNameIn, const QString& positionVarIn, const QString& rotationVarIn,
|
AnimInverseKinematics::IKTargetVar::IKTargetVar(const QString& jointNameIn, const QString& positionVarIn, const QString& rotationVarIn,
|
||||||
const QString& typeVarIn, const std::vector<float>& flexCoefficientsIn) :
|
const QString& typeVarIn, const QString& weightVarIn, float weightIn, const std::vector<float>& flexCoefficientsIn) :
|
||||||
positionVar(positionVarIn),
|
positionVar(positionVarIn),
|
||||||
rotationVar(rotationVarIn),
|
rotationVar(rotationVarIn),
|
||||||
typeVar(typeVarIn),
|
typeVar(typeVarIn),
|
||||||
|
weightVar(weightVarIn),
|
||||||
|
weight(weightIn),
|
||||||
jointName(jointNameIn),
|
jointName(jointNameIn),
|
||||||
numFlexCoefficients(flexCoefficientsIn.size()),
|
numFlexCoefficients(flexCoefficientsIn.size()),
|
||||||
jointIndex(-1)
|
jointIndex(-1)
|
||||||
|
@ -40,6 +42,8 @@ AnimInverseKinematics::IKTargetVar::IKTargetVar(const IKTargetVar& orig) :
|
||||||
positionVar(orig.positionVar),
|
positionVar(orig.positionVar),
|
||||||
rotationVar(orig.rotationVar),
|
rotationVar(orig.rotationVar),
|
||||||
typeVar(orig.typeVar),
|
typeVar(orig.typeVar),
|
||||||
|
weightVar(orig.weightVar),
|
||||||
|
weight(orig.weight),
|
||||||
jointName(orig.jointName),
|
jointName(orig.jointName),
|
||||||
numFlexCoefficients(orig.numFlexCoefficients),
|
numFlexCoefficients(orig.numFlexCoefficients),
|
||||||
jointIndex(orig.jointIndex)
|
jointIndex(orig.jointIndex)
|
||||||
|
@ -90,8 +94,8 @@ void AnimInverseKinematics::computeAbsolutePoses(AnimPoseVec& absolutePoses) con
|
||||||
}
|
}
|
||||||
|
|
||||||
void AnimInverseKinematics::setTargetVars(const QString& jointName, const QString& positionVar, const QString& rotationVar,
|
void AnimInverseKinematics::setTargetVars(const QString& jointName, const QString& positionVar, const QString& rotationVar,
|
||||||
const QString& typeVar, const std::vector<float>& flexCoefficients) {
|
const QString& typeVar, const QString& weightVar, float weight, const std::vector<float>& flexCoefficients) {
|
||||||
IKTargetVar targetVar(jointName, positionVar, rotationVar, typeVar, flexCoefficients);
|
IKTargetVar targetVar(jointName, positionVar, rotationVar, typeVar, weightVar, weight, flexCoefficients);
|
||||||
|
|
||||||
// if there are dups, last one wins.
|
// if there are dups, last one wins.
|
||||||
bool found = false;
|
bool found = false;
|
||||||
|
@ -132,9 +136,11 @@ void AnimInverseKinematics::computeTargets(const AnimVariantMap& animVars, std::
|
||||||
AnimPose defaultPose = _skeleton->getAbsolutePose(targetVar.jointIndex, underPoses);
|
AnimPose defaultPose = _skeleton->getAbsolutePose(targetVar.jointIndex, underPoses);
|
||||||
glm::quat rotation = animVars.lookupRigToGeometry(targetVar.rotationVar, defaultPose.rot());
|
glm::quat rotation = animVars.lookupRigToGeometry(targetVar.rotationVar, defaultPose.rot());
|
||||||
glm::vec3 translation = animVars.lookupRigToGeometry(targetVar.positionVar, defaultPose.trans());
|
glm::vec3 translation = animVars.lookupRigToGeometry(targetVar.positionVar, defaultPose.trans());
|
||||||
|
float weight = animVars.lookup(targetVar.weightVar, targetVar.weight);
|
||||||
|
|
||||||
target.setPose(rotation, translation);
|
target.setPose(rotation, translation);
|
||||||
target.setIndex(targetVar.jointIndex);
|
target.setIndex(targetVar.jointIndex);
|
||||||
|
target.setWeight(weight);
|
||||||
target.setFlexCoefficients(targetVar.numFlexCoefficients, targetVar.flexCoefficients);
|
target.setFlexCoefficients(targetVar.numFlexCoefficients, targetVar.flexCoefficients);
|
||||||
|
|
||||||
targets.push_back(target);
|
targets.push_back(target);
|
||||||
|
@ -837,7 +843,7 @@ void AnimInverseKinematics::initConstraints() {
|
||||||
stConstraint->setTwistLimits(-MAX_SHOULDER_TWIST, MAX_SHOULDER_TWIST);
|
stConstraint->setTwistLimits(-MAX_SHOULDER_TWIST, MAX_SHOULDER_TWIST);
|
||||||
|
|
||||||
std::vector<float> minDots;
|
std::vector<float> minDots;
|
||||||
const float MAX_SHOULDER_SWING = PI / 20.0f;
|
const float MAX_SHOULDER_SWING = PI / 16.0f;
|
||||||
minDots.push_back(cosf(MAX_SHOULDER_SWING));
|
minDots.push_back(cosf(MAX_SHOULDER_SWING));
|
||||||
stConstraint->setSwingLimits(minDots);
|
stConstraint->setSwingLimits(minDots);
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,7 @@ public:
|
||||||
void computeAbsolutePoses(AnimPoseVec& absolutePoses) const;
|
void computeAbsolutePoses(AnimPoseVec& absolutePoses) const;
|
||||||
|
|
||||||
void setTargetVars(const QString& jointName, const QString& positionVar, const QString& rotationVar,
|
void setTargetVars(const QString& jointName, const QString& positionVar, const QString& rotationVar,
|
||||||
const QString& typeVar, const std::vector<float>& flexCoefficients);
|
const QString& typeVar, const QString& weightVar, float weight, const std::vector<float>& flexCoefficients);
|
||||||
|
|
||||||
virtual const AnimPoseVec& evaluate(const AnimVariantMap& animVars, const AnimContext& context, float dt, AnimNode::Triggers& triggersOut) override;
|
virtual const AnimPoseVec& evaluate(const AnimVariantMap& animVars, const AnimContext& context, float dt, AnimNode::Triggers& triggersOut) override;
|
||||||
virtual const AnimPoseVec& overlay(const AnimVariantMap& animVars, const AnimContext& context, float dt, Triggers& triggersOut, const AnimPoseVec& underPoses) override;
|
virtual const AnimPoseVec& overlay(const AnimVariantMap& animVars, const AnimContext& context, float dt, Triggers& triggersOut, const AnimPoseVec& underPoses) override;
|
||||||
|
@ -81,13 +81,15 @@ protected:
|
||||||
static const size_t MAX_FLEX_COEFFICIENTS = 10;
|
static const size_t MAX_FLEX_COEFFICIENTS = 10;
|
||||||
struct IKTargetVar {
|
struct IKTargetVar {
|
||||||
IKTargetVar(const QString& jointNameIn, const QString& positionVarIn, const QString& rotationVarIn,
|
IKTargetVar(const QString& jointNameIn, const QString& positionVarIn, const QString& rotationVarIn,
|
||||||
const QString& typeVarIn, const std::vector<float>& flexCoefficientsIn);
|
const QString& typeVarIn, const QString& weightVarIn, float weightIn, const std::vector<float>& flexCoefficientsIn);
|
||||||
IKTargetVar(const IKTargetVar& orig);
|
IKTargetVar(const IKTargetVar& orig);
|
||||||
|
|
||||||
QString positionVar;
|
QString positionVar;
|
||||||
QString rotationVar;
|
QString rotationVar;
|
||||||
QString typeVar;
|
QString typeVar;
|
||||||
|
QString weightVar;
|
||||||
QString jointName;
|
QString jointName;
|
||||||
|
float weight;
|
||||||
float flexCoefficients[MAX_FLEX_COEFFICIENTS];
|
float flexCoefficients[MAX_FLEX_COEFFICIENTS];
|
||||||
size_t numFlexCoefficients;
|
size_t numFlexCoefficients;
|
||||||
int jointIndex; // cached joint index
|
int jointIndex; // cached joint index
|
||||||
|
|
|
@ -173,6 +173,13 @@ static NodeProcessFunc animNodeTypeToProcessFunc(AnimNode::Type type) {
|
||||||
} \
|
} \
|
||||||
float NAME = (float)NAME##_VAL.toDouble()
|
float NAME = (float)NAME##_VAL.toDouble()
|
||||||
|
|
||||||
|
#define READ_OPTIONAL_FLOAT(NAME, JSON_OBJ, DEFAULT) \
|
||||||
|
auto NAME##_VAL = JSON_OBJ.value(#NAME); \
|
||||||
|
float NAME = (float)DEFAULT; \
|
||||||
|
if (NAME##_VAL.isDouble()) { \
|
||||||
|
NAME = (float)NAME##_VAL.toDouble(); \
|
||||||
|
} \
|
||||||
|
do {} while (0)
|
||||||
|
|
||||||
static AnimNode::Pointer loadNode(const QJsonObject& jsonObj, const QUrl& jsonUrl) {
|
static AnimNode::Pointer loadNode(const QJsonObject& jsonObj, const QUrl& jsonUrl) {
|
||||||
auto idVal = jsonObj.value("id");
|
auto idVal = jsonObj.value("id");
|
||||||
|
@ -470,6 +477,8 @@ AnimNode::Pointer loadInverseKinematicsNode(const QJsonObject& jsonObj, const QS
|
||||||
READ_STRING(positionVar, targetObj, id, jsonUrl, nullptr);
|
READ_STRING(positionVar, targetObj, id, jsonUrl, nullptr);
|
||||||
READ_STRING(rotationVar, targetObj, id, jsonUrl, nullptr);
|
READ_STRING(rotationVar, targetObj, id, jsonUrl, nullptr);
|
||||||
READ_OPTIONAL_STRING(typeVar, targetObj);
|
READ_OPTIONAL_STRING(typeVar, targetObj);
|
||||||
|
READ_OPTIONAL_STRING(weightVar, targetObj);
|
||||||
|
READ_OPTIONAL_FLOAT(weight, targetObj, 1.0f);
|
||||||
|
|
||||||
auto flexCoefficientsValue = targetObj.value("flexCoefficients");
|
auto flexCoefficientsValue = targetObj.value("flexCoefficients");
|
||||||
if (!flexCoefficientsValue.isArray()) {
|
if (!flexCoefficientsValue.isArray()) {
|
||||||
|
@ -482,7 +491,7 @@ AnimNode::Pointer loadInverseKinematicsNode(const QJsonObject& jsonObj, const QS
|
||||||
flexCoefficients.push_back((float)value.toDouble());
|
flexCoefficients.push_back((float)value.toDouble());
|
||||||
}
|
}
|
||||||
|
|
||||||
node->setTargetVars(jointName, positionVar, rotationVar, typeVar, flexCoefficients);
|
node->setTargetVars(jointName, positionVar, rotationVar, typeVar, weightVar, weight, flexCoefficients);
|
||||||
};
|
};
|
||||||
|
|
||||||
READ_OPTIONAL_STRING(solutionSource, jsonObj);
|
READ_OPTIONAL_STRING(solutionSource, jsonObj);
|
||||||
|
|
|
@ -23,6 +23,7 @@ void IKTarget::setFlexCoefficients(size_t numFlexCoefficientsIn, const float* fl
|
||||||
|
|
||||||
float IKTarget::getFlexCoefficient(int chainDepth) const {
|
float IKTarget::getFlexCoefficient(int chainDepth) const {
|
||||||
const float DEFAULT_FLEX_COEFFICIENT = 0.5f;
|
const float DEFAULT_FLEX_COEFFICIENT = 0.5f;
|
||||||
|
|
||||||
if (chainDepth >= 0 && chainDepth < _numFlexCoefficients) {
|
if (chainDepth >= 0 && chainDepth < _numFlexCoefficients) {
|
||||||
return _flexCoefficients[chainDepth];
|
return _flexCoefficients[chainDepth];
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -38,14 +38,15 @@ public:
|
||||||
void setFlexCoefficients(size_t numFlexCoefficientsIn, const float* flexCoefficientsIn);
|
void setFlexCoefficients(size_t numFlexCoefficientsIn, const float* flexCoefficientsIn);
|
||||||
float getFlexCoefficient(int chainDepth) const;
|
float getFlexCoefficient(int chainDepth) const;
|
||||||
|
|
||||||
// HACK: give HmdHead targets more "weight" during IK algorithm
|
void setWeight(float weight) { _weight = weight; }
|
||||||
float getWeight() const { return _type == Type::HmdHead ? HACK_HMD_TARGET_WEIGHT : 1.0f; }
|
float getWeight() const { return _weight; }
|
||||||
|
|
||||||
static const size_t MAX_FLEX_COEFFICIENTS = 10;
|
static const size_t MAX_FLEX_COEFFICIENTS = 10;
|
||||||
private:
|
private:
|
||||||
AnimPose _pose;
|
AnimPose _pose;
|
||||||
int _index{-1};
|
int _index{-1};
|
||||||
Type _type{Type::RotationAndPosition};
|
Type _type{Type::RotationAndPosition};
|
||||||
|
float _weight;
|
||||||
float _flexCoefficients[MAX_FLEX_COEFFICIENTS];
|
float _flexCoefficients[MAX_FLEX_COEFFICIENTS];
|
||||||
size_t _numFlexCoefficients;
|
size_t _numFlexCoefficients;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1088,10 +1088,12 @@ void Rig::updateHeadAnimVars(const HeadParameters& params) {
|
||||||
// Since there is an explicit hips ik target, switch the head to use the more generic RotationAndPosition IK chain type.
|
// Since there is an explicit hips ik target, switch the head to use the more generic RotationAndPosition IK chain type.
|
||||||
// this will allow the spine to bend more, ensuring that it can reach the head target position.
|
// this will allow the spine to bend more, ensuring that it can reach the head target position.
|
||||||
_animVars.set("headType", (int)IKTarget::Type::RotationAndPosition);
|
_animVars.set("headType", (int)IKTarget::Type::RotationAndPosition);
|
||||||
|
_animVars.unset("headWeight"); // use the default weight for this target.
|
||||||
} else {
|
} else {
|
||||||
// When there is no hips IK target, use the HmdHead IK chain type. This will make the spine very stiff,
|
// When there is no hips IK target, use the HmdHead IK chain type. This will make the spine very stiff,
|
||||||
// but because the IK _hipsOffset is enabled, the hips will naturally follow underneath the head.
|
// but because the IK _hipsOffset is enabled, the hips will naturally follow underneath the head.
|
||||||
_animVars.set("headType", (int)IKTarget::Type::HmdHead);
|
_animVars.set("headType", (int)IKTarget::Type::HmdHead);
|
||||||
|
_animVars.set("headWeight", 8.0f);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
_animVars.unset("headPosition");
|
_animVars.unset("headPosition");
|
||||||
|
@ -1405,19 +1407,19 @@ void Rig::computeAvatarBoundingCapsule(
|
||||||
ikNode.setTargetVars("LeftHand",
|
ikNode.setTargetVars("LeftHand",
|
||||||
"leftHandPosition",
|
"leftHandPosition",
|
||||||
"leftHandRotation",
|
"leftHandRotation",
|
||||||
"leftHandType", {});
|
"leftHandType", "leftHandWeight", 1.0f, {});
|
||||||
ikNode.setTargetVars("RightHand",
|
ikNode.setTargetVars("RightHand",
|
||||||
"rightHandPosition",
|
"rightHandPosition",
|
||||||
"rightHandRotation",
|
"rightHandRotation",
|
||||||
"rightHandType", {});
|
"rightHandType", "rightHandWeight", 1.0f, {});
|
||||||
ikNode.setTargetVars("LeftFoot",
|
ikNode.setTargetVars("LeftFoot",
|
||||||
"leftFootPosition",
|
"leftFootPosition",
|
||||||
"leftFootRotation",
|
"leftFootRotation",
|
||||||
"leftFootType", {});
|
"leftFootType", "leftFootWeight", 1.0f, {});
|
||||||
ikNode.setTargetVars("RightFoot",
|
ikNode.setTargetVars("RightFoot",
|
||||||
"rightFootPosition",
|
"rightFootPosition",
|
||||||
"rightFootRotation",
|
"rightFootRotation",
|
||||||
"rightFootType", {});
|
"rightFootType", "rightFootWeight", 1.0f, {});
|
||||||
|
|
||||||
AnimPose geometryToRig = _modelOffset * _geometryOffset;
|
AnimPose geometryToRig = _modelOffset * _geometryOffset;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue