mirror of
https://github.com/overte-org/overte.git
synced 2025-08-08 07:37:31 +02:00
Refactor of JointChainInfo data structure
This commit is contained in:
parent
c7e4bf931b
commit
75e1a4a1e6
2 changed files with 62 additions and 61 deletions
|
@ -23,20 +23,21 @@
|
|||
#include "CubicHermiteSpline.h"
|
||||
#include "AnimUtil.h"
|
||||
|
||||
static void lookupJointChainInfo(const std::vector<AnimInverseKinematics::JointChainInfo>& jointChainInfoVec,
|
||||
static void lookupJointInfo(const AnimInverseKinematics::JointChainInfo& jointChainInfo,
|
||||
int indexA, int indexB,
|
||||
const AnimInverseKinematics::JointChainInfo** jointChainInfoA,
|
||||
const AnimInverseKinematics::JointChainInfo** jointChainInfoB) {
|
||||
*jointChainInfoA = nullptr;
|
||||
*jointChainInfoB = nullptr;
|
||||
for (size_t i = 0; i < jointChainInfoVec.size(); i++) {
|
||||
if (jointChainInfoVec[i].jointIndex == indexA) {
|
||||
*jointChainInfoA = &jointChainInfoVec[i];
|
||||
const AnimInverseKinematics::JointInfo** jointInfoA,
|
||||
const AnimInverseKinematics::JointInfo** jointInfoB) {
|
||||
*jointInfoA = nullptr;
|
||||
*jointInfoB = nullptr;
|
||||
for (size_t i = 0; i < jointChainInfo.jointInfoVec.size(); i++) {
|
||||
const AnimInverseKinematics::JointInfo* jointInfo = &jointChainInfo.jointInfoVec[i];
|
||||
if (jointInfo->jointIndex == indexA) {
|
||||
*jointInfoA = jointInfo;
|
||||
}
|
||||
if (jointChainInfoVec[i].jointIndex == indexB) {
|
||||
*jointChainInfoB = &jointChainInfoVec[i];
|
||||
if (jointInfo->jointIndex == indexB) {
|
||||
*jointInfoB = jointInfo;
|
||||
}
|
||||
if (*jointChainInfoA && *jointChainInfoB) {
|
||||
if (*jointInfoA && *jointInfoB) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -234,14 +235,15 @@ void AnimInverseKinematics::solve(const AnimContext& context, const std::vector<
|
|||
accumulator.clearAndClean();
|
||||
}
|
||||
|
||||
// initialize jointChainInfoVecVec, this holds the results for one iteration of each ik chain.
|
||||
JointChainInfo defaultJointChainInfo = { glm::quat(), glm::vec3(), 0.0f, -1, false };
|
||||
std::vector<std::vector<JointChainInfo>> jointChainInfoVecVec(targets.size());
|
||||
// initialize a new jointChainInfoVec, this will holds the results for solving each ik chain.
|
||||
JointInfo defaultJointInfo = { glm::quat(), glm::vec3(), -1, false };
|
||||
JointChainInfoVec jointChainInfoVec(targets.size());
|
||||
for (size_t i = 0; i < targets.size(); i++) {
|
||||
int chainDepth = _skeleton->getChainDepth(targets[i].getIndex());
|
||||
jointChainInfoVecVec[i].reserve(chainDepth);
|
||||
jointChainInfoVec[i].jointInfoVec.reserve(chainDepth);
|
||||
jointChainInfoVec[i].target = targets[i];
|
||||
for (size_t j = 0; j < chainDepth; j++) {
|
||||
jointChainInfoVecVec[i].push_back(defaultJointChainInfo);
|
||||
jointChainInfoVec[i].jointInfoVec.push_back(defaultJointInfo);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -257,9 +259,9 @@ void AnimInverseKinematics::solve(const AnimContext& context, const std::vector<
|
|||
// solve all targets
|
||||
for (size_t i = 0; i < targets.size(); i++) {
|
||||
if (targets[i].getType() == IKTarget::Type::Spline) {
|
||||
solveTargetWithSpline(context, targets[i], absolutePoses, debug, jointChainInfoVecVec[i]);
|
||||
solveTargetWithSpline(context, targets[i], absolutePoses, debug, jointChainInfoVec[i]);
|
||||
} else {
|
||||
solveTargetWithCCD(context, targets[i], absolutePoses, debug, jointChainInfoVecVec[i]);
|
||||
solveTargetWithCCD(context, targets[i], absolutePoses, debug, jointChainInfoVec[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -267,12 +269,13 @@ void AnimInverseKinematics::solve(const AnimContext& context, const std::vector<
|
|||
|
||||
// copy jointChainInfoVecs into accumulators
|
||||
for (size_t i = 0; i < targets.size(); i++) {
|
||||
const std::vector<JointChainInfo>& jointChainInfoVec = jointChainInfoVecVec[i];
|
||||
for (size_t j = 0; j < jointChainInfoVec.size(); j++) {
|
||||
const JointChainInfo& info = jointChainInfoVec[j];
|
||||
const std::vector<JointInfo>& jointInfoVec = jointChainInfoVec[i].jointInfoVec;
|
||||
float weight = jointChainInfoVec[i].target.getWeight();
|
||||
for (size_t j = 0; j < jointInfoVec.size(); j++) {
|
||||
const JointInfo& info = jointInfoVec[j];
|
||||
if (info.jointIndex >= 0) {
|
||||
_rotationAccumulators[info.jointIndex].add(info.relRot, info.weight);
|
||||
_translationAccumulators[info.jointIndex].add(info.relTrans, info.weight);
|
||||
_rotationAccumulators[info.jointIndex].add(info.rot, weight);
|
||||
_translationAccumulators[info.jointIndex].add(info.trans, weight);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -336,7 +339,7 @@ void AnimInverseKinematics::solve(const AnimContext& context, const std::vector<
|
|||
}
|
||||
|
||||
void AnimInverseKinematics::solveTargetWithCCD(const AnimContext& context, const IKTarget& target, const AnimPoseVec& absolutePoses,
|
||||
bool debug, std::vector<JointChainInfo>& jointChainInfoVec) const {
|
||||
bool debug, JointChainInfo& jointChainInfoOut) const {
|
||||
size_t chainDepth = 0;
|
||||
|
||||
IKTarget::Type targetType = target.getType();
|
||||
|
@ -391,7 +394,7 @@ void AnimInverseKinematics::solveTargetWithCCD(const AnimContext& context, const
|
|||
}
|
||||
|
||||
glm::vec3 tipRelativeTranslation = _relativePoses[target.getIndex()].trans();
|
||||
jointChainInfoVec[chainDepth] = { tipRelativeRotation, tipRelativeTranslation, target.getWeight(), tipIndex, constrained };
|
||||
jointChainInfoOut.jointInfoVec[chainDepth] = { tipRelativeRotation, tipRelativeTranslation, tipIndex, constrained };
|
||||
}
|
||||
|
||||
// cache tip absolute position
|
||||
|
@ -402,7 +405,7 @@ void AnimInverseKinematics::solveTargetWithCCD(const AnimContext& context, const
|
|||
// descend toward root, pivoting each joint to get tip closer to target position
|
||||
while (pivotIndex != _hipsIndex && pivotsParentIndex != -1) {
|
||||
|
||||
assert(chainDepth < jointChainInfoVec.size());
|
||||
assert(chainDepth < jointChainInfoOut.jointInfoVec.size());
|
||||
|
||||
// compute the two lines that should be aligned
|
||||
glm::vec3 jointPosition = absolutePoses[pivotIndex].trans();
|
||||
|
@ -503,7 +506,7 @@ void AnimInverseKinematics::solveTargetWithCCD(const AnimContext& context, const
|
|||
}
|
||||
|
||||
glm::vec3 newTrans = _relativePoses[pivotIndex].trans();
|
||||
jointChainInfoVec[chainDepth] = { newRot, newTrans, target.getWeight(), pivotIndex, constrained };
|
||||
jointChainInfoOut.jointInfoVec[chainDepth] = { newRot, newTrans, pivotIndex, constrained };
|
||||
|
||||
// keep track of tip's new transform as we descend towards root
|
||||
tipPosition = jointPosition + deltaRotation * (tipPosition - jointPosition);
|
||||
|
@ -530,20 +533,20 @@ void AnimInverseKinematics::solveTargetWithCCD(const AnimContext& context, const
|
|||
AnimPose accum = absolutePoses[_hipsIndex];
|
||||
AnimPose baseParentPose = absolutePoses[_hipsIndex];
|
||||
for (int i = (int)chainDepth - 1; i >= 0; i--) {
|
||||
accum = accum * AnimPose(glm::vec3(1.0f), jointChainInfoVec[i].relRot, jointChainInfoVec[i].relTrans);
|
||||
accum = accum * AnimPose(glm::vec3(1.0f), jointChainInfoOut.jointInfoVec[i].rot, jointChainInfoOut.jointInfoVec[i].trans);
|
||||
postAbsPoses[i] = accum;
|
||||
if (jointChainInfoVec[i].jointIndex == topJointIndex) {
|
||||
if (jointChainInfoOut.jointInfoVec[i].jointIndex == topJointIndex) {
|
||||
topChainIndex = i;
|
||||
topPose = accum;
|
||||
}
|
||||
if (jointChainInfoVec[i].jointIndex == midJointIndex) {
|
||||
if (jointChainInfoOut.jointInfoVec[i].jointIndex == midJointIndex) {
|
||||
midPose = accum;
|
||||
}
|
||||
if (jointChainInfoVec[i].jointIndex == baseJointIndex) {
|
||||
if (jointChainInfoOut.jointInfoVec[i].jointIndex == baseJointIndex) {
|
||||
baseChainIndex = i;
|
||||
basePose = accum;
|
||||
}
|
||||
if (jointChainInfoVec[i].jointIndex == baseParentJointIndex) {
|
||||
if (jointChainInfoOut.jointInfoVec[i].jointIndex == baseParentJointIndex) {
|
||||
baseParentPose = accum;
|
||||
}
|
||||
}
|
||||
|
@ -623,16 +626,16 @@ void AnimInverseKinematics::solveTargetWithCCD(const AnimContext& context, const
|
|||
}
|
||||
|
||||
glm::quat newBaseRelRot = glm::inverse(baseParentPose.rot()) * poleRot * basePose.rot();
|
||||
jointChainInfoVec[baseChainIndex].relRot = newBaseRelRot;
|
||||
jointChainInfoOut.jointInfoVec[baseChainIndex].rot = newBaseRelRot;
|
||||
|
||||
glm::quat newTopRelRot = glm::inverse(midPose.rot()) * glm::inverse(poleRot) * topPose.rot();
|
||||
jointChainInfoVec[topChainIndex].relRot = newTopRelRot;
|
||||
jointChainInfoOut.jointInfoVec[topChainIndex].rot = newTopRelRot;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (debug) {
|
||||
debugDrawIKChain(jointChainInfoVec, context);
|
||||
debugDrawIKChain(jointChainInfoOut, context);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -718,7 +721,7 @@ const std::vector<AnimInverseKinematics::SplineJointInfo>* AnimInverseKinematics
|
|||
|
||||
// AJT: TODO: make this const someday
|
||||
void AnimInverseKinematics::solveTargetWithSpline(const AnimContext& context, const IKTarget& target, const AnimPoseVec& absolutePoses,
|
||||
bool debug, std::vector<JointChainInfo>& jointChainInfoVec) {
|
||||
bool debug, JointChainInfo& jointChainInfoOut) {
|
||||
|
||||
const int baseIndex = _hipsIndex;
|
||||
|
||||
|
@ -801,22 +804,14 @@ void AnimInverseKinematics::solveTargetWithSpline(const AnimContext& context, co
|
|||
}
|
||||
}
|
||||
|
||||
jointChainInfoVec[i] = { relPose.rot(), relPose.trans(), target.getWeight(), splineJointInfo.jointIndex, constrained };
|
||||
jointChainInfoOut.jointInfoVec[i] = { relPose.rot(), relPose.trans(), splineJointInfo.jointIndex, constrained };
|
||||
|
||||
parentAbsPose = flexedAbsPose;
|
||||
}
|
||||
}
|
||||
|
||||
// AJT: REMOVE
|
||||
/*
|
||||
for (size_t i = 0; i < splineJointInfoVec->size(); i++) {
|
||||
_rotationAccumulators[jointChainInfos[i].jointIndex].add(jointChainInfos[i].relRot, jointChainInfos[i].weight);
|
||||
_translationAccumulators[jointChainInfos[i].jointIndex].add(jointChainInfos[i].relTrans, jointChainInfos[i].weight);
|
||||
}
|
||||
*/
|
||||
|
||||
if (debug) {
|
||||
debugDrawIKChain(jointChainInfoVec, context);
|
||||
debugDrawIKChain(jointChainInfoOut, context);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1516,14 +1511,14 @@ void AnimInverseKinematics::debugDrawRelativePoses(const AnimContext& context) c
|
|||
}
|
||||
}
|
||||
|
||||
void AnimInverseKinematics::debugDrawIKChain(const std::vector<JointChainInfo>& jointChainInfoVec, const AnimContext& context) const {
|
||||
void AnimInverseKinematics::debugDrawIKChain(const JointChainInfo& jointChainInfo, const AnimContext& context) const {
|
||||
AnimPoseVec poses = _relativePoses;
|
||||
|
||||
// copy debug joint rotations into the relative poses
|
||||
for (size_t i = 0; i < jointChainInfoVec.size(); i++) {
|
||||
const JointChainInfo& info = jointChainInfoVec[i];
|
||||
poses[info.jointIndex].rot() = info.relRot;
|
||||
poses[info.jointIndex].trans() = info.relTrans;
|
||||
for (size_t i = 0; i < jointChainInfo.jointInfoVec.size(); i++) {
|
||||
const JointInfo& info = jointChainInfo.jointInfoVec[i];
|
||||
poses[info.jointIndex].rot() = info.rot;
|
||||
poses[info.jointIndex].trans() = info.trans;
|
||||
}
|
||||
|
||||
// convert relative poses to absolute
|
||||
|
@ -1540,9 +1535,9 @@ void AnimInverseKinematics::debugDrawIKChain(const std::vector<JointChainInfo>&
|
|||
// draw each pose
|
||||
for (int i = 0; i < (int)poses.size(); i++) {
|
||||
int parentIndex = _skeleton->getParentIndex(i);
|
||||
const JointChainInfo* jointInfo = nullptr;
|
||||
const JointChainInfo* parentJointInfo = nullptr;
|
||||
lookupJointChainInfo(jointChainInfoVec, i, parentIndex, &jointInfo, &parentJointInfo);
|
||||
const JointInfo* jointInfo = nullptr;
|
||||
const JointInfo* parentJointInfo = nullptr;
|
||||
lookupJointInfo(jointChainInfo, i, parentIndex, &jointInfo, &parentJointInfo);
|
||||
if (jointInfo && parentJointInfo) {
|
||||
|
||||
// transform local axes into world space.
|
||||
|
|
|
@ -26,14 +26,20 @@ class RotationConstraint;
|
|||
class AnimInverseKinematics : public AnimNode {
|
||||
public:
|
||||
|
||||
struct JointChainInfo {
|
||||
glm::quat relRot;
|
||||
glm::vec3 relTrans;
|
||||
float weight;
|
||||
struct JointInfo {
|
||||
glm::quat rot;
|
||||
glm::vec3 trans;
|
||||
int jointIndex;
|
||||
bool constrained;
|
||||
};
|
||||
|
||||
struct JointChainInfo {
|
||||
std::vector<JointInfo> jointInfoVec;
|
||||
IKTarget target;
|
||||
};
|
||||
|
||||
using JointChainInfoVec = std::vector<JointChainInfo>;
|
||||
|
||||
explicit AnimInverseKinematics(const QString& id);
|
||||
virtual ~AnimInverseKinematics() override;
|
||||
|
||||
|
@ -74,11 +80,11 @@ protected:
|
|||
void computeTargets(const AnimVariantMap& animVars, std::vector<IKTarget>& targets, const AnimPoseVec& underPoses);
|
||||
void solve(const AnimContext& context, const std::vector<IKTarget>& targets);
|
||||
void solveTargetWithCCD(const AnimContext& context, const IKTarget& target, const AnimPoseVec& absolutePoses,
|
||||
bool debug, std::vector<JointChainInfo>& jointChainInfoVec) const;
|
||||
bool debug, JointChainInfo& jointChainInfoOut) const;
|
||||
void solveTargetWithSpline(const AnimContext& context, const IKTarget& target, const AnimPoseVec& absolutePoses,
|
||||
bool debug, std::vector<JointChainInfo>& jointChainInfoVec);
|
||||
bool debug, JointChainInfo& jointChainInfoOut);
|
||||
virtual void setSkeletonInternal(AnimSkeleton::ConstPointer skeleton) override;
|
||||
void debugDrawIKChain(const std::vector<JointChainInfo>& jointChainInfoVec, const AnimContext& context) const;
|
||||
void debugDrawIKChain(const JointChainInfo& jointChainInfo, const AnimContext& context) const;
|
||||
void debugDrawRelativePoses(const AnimContext& context) const;
|
||||
void debugDrawConstraints(const AnimContext& context) const;
|
||||
void debugDrawSpineSplines(const AnimContext& context, const std::vector<IKTarget>& targets) const;
|
||||
|
|
Loading…
Reference in a new issue