mirror of
https://github.com/lubosz/overte.git
synced 2025-04-14 04:26:18 +02:00
This pr addresses two issues related to avatars that have parents joints
above their hip joints. First on the IK side this prevents parent joints from being included in the accumulators in AnimInverseKinematics. Second in AnimClip the boneLengthScale now takes into account translation and scale on these extra parent joints.
This commit is contained in:
parent
72f198fe00
commit
217145f4c5
4 changed files with 46 additions and 6 deletions
|
@ -151,12 +151,49 @@ void AnimClip::copyFromNetworkAnim() {
|
|||
const glm::vec3& animZeroTrans = animModel.animationFrames[0].translations[animJointIndex];
|
||||
float boneLengthScale = 1.0f;
|
||||
const float EPSILON = 0.0001f;
|
||||
if (fabsf(glm::length(animZeroTrans)) > EPSILON) {
|
||||
boneLengthScale = glm::length(avatarDefaultPose.trans()) / glm::length(animZeroTrans);
|
||||
|
||||
const int avatarHipsParentIndex = avatarSkeleton->getParentIndex(avatarSkeleton->nameToJointIndex("Hips"));
|
||||
if (avatarJointIndex == avatarSkeleton->nameToJointIndex("Hips") && (avatarHipsParentIndex >= 0)) {
|
||||
|
||||
const AnimPose& animHipsAbsoluteDefaultPose = animSkeleton.getAbsoluteDefaultPose(animSkeleton.nameToJointIndex("Hips"));
|
||||
const AnimPose& avatarHipsAbsoluteDefaultPose = avatarSkeleton->getAbsoluteDefaultPose(avatarSkeleton->nameToJointIndex("Hips"));
|
||||
const AnimPose& avatarHipsParentAbsoluteDefaultPose = avatarSkeleton->getAbsoluteDefaultPose(avatarHipsParentIndex);
|
||||
|
||||
// the get the units and the heights for the animation and the avatar
|
||||
const float animationUnitScale = extractScale(animModel.offset).y;
|
||||
const float avatarUnitScale = extractScale(avatarSkeleton->getGeometryOffset()).y;
|
||||
const float avatarHeightInMeters = avatarUnitScale * avatarHipsAbsoluteDefaultPose.trans().y;
|
||||
const float animHeightInMeters = animationUnitScale * animHipsAbsoluteDefaultPose.trans().y;
|
||||
|
||||
// get the parent scales for the avatar and the animation
|
||||
const float avatarHipsParentScale = avatarHipsParentAbsoluteDefaultPose.scale().y;
|
||||
float animHipsParentScale = 1.0f;
|
||||
const int animHipsParentIndex = animSkeleton.getParentIndex(animSkeleton.nameToJointIndex("Hips"));
|
||||
// also, check to see if the animation hips have a scaled parent.
|
||||
if (animHipsParentIndex >= 0) {
|
||||
const AnimPose& animationHipsParentAbsoluteDefaultPose = animSkeleton.getAbsoluteDefaultPose(animHipsParentIndex);
|
||||
animHipsParentScale = animationHipsParentAbsoluteDefaultPose.scale().y;
|
||||
}
|
||||
|
||||
// compute the ratios for the units, the heights in meters, and the parent scales
|
||||
if ((fabsf(animHeightInMeters) > EPSILON) && (animationUnitScale > EPSILON) && (animHipsParentScale > EPSILON)) {
|
||||
const float avatarToAnimationHeightRatio = avatarHeightInMeters / animHeightInMeters;
|
||||
const float unitsRatio = 1.0f / (avatarUnitScale / animationUnitScale);
|
||||
const float parentScaleRatio = 1.0f / (avatarHipsParentScale / animHipsParentScale);
|
||||
|
||||
boneLengthScale = avatarToAnimationHeightRatio * unitsRatio * parentScaleRatio;
|
||||
}
|
||||
} else {
|
||||
|
||||
if (fabsf(glm::length(animZeroTrans)) > EPSILON) {
|
||||
boneLengthScale = glm::length(avatarDefaultPose.trans()) / glm::length(animZeroTrans);
|
||||
}
|
||||
}
|
||||
|
||||
AnimPose animTransPose = AnimPose(glm::vec3(1.0f), glm::quat(), avatarDefaultPose.trans() + boneLengthScale * (animTrans - animZeroTrans));
|
||||
|
||||
_anim[frame][avatarJointIndex] = animTransPose * animPreRotPose * animRotPose * animPostRotPose;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -298,10 +298,8 @@ void AnimInverseKinematics::solve(const AnimContext& context, const std::vector<
|
|||
}
|
||||
|
||||
// harvest accumulated rotations and apply the average
|
||||
for (int i = 0; i < (int)_relativePoses.size(); ++i) {
|
||||
if (i == _hipsIndex) {
|
||||
continue; // don't apply accumulators to hips
|
||||
}
|
||||
// don't apply accumulators to hips, or parents of hips
|
||||
for (int i = (_hipsIndex+1); i < (int)_relativePoses.size(); ++i) {
|
||||
if (_rotationAccumulators[i].size() > 0) {
|
||||
_relativePoses[i].rot() = _rotationAccumulators[i].getAverage();
|
||||
_rotationAccumulators[i].clear();
|
||||
|
|
|
@ -17,6 +17,9 @@
|
|||
#include "AnimationLogging.h"
|
||||
|
||||
AnimSkeleton::AnimSkeleton(const HFMModel& hfmModel) {
|
||||
|
||||
_geometryOffset = hfmModel.offset;
|
||||
|
||||
// convert to std::vector of joints
|
||||
std::vector<HFMJoint> joints;
|
||||
joints.reserve(hfmModel.joints.size());
|
||||
|
|
|
@ -36,6 +36,7 @@ public:
|
|||
const AnimPoseVec& getRelativeDefaultPoses() const { return _relativeDefaultPoses; }
|
||||
const AnimPose& getAbsoluteDefaultPose(int jointIndex) const;
|
||||
const AnimPoseVec& getAbsoluteDefaultPoses() const { return _absoluteDefaultPoses; }
|
||||
const glm::mat4& getGeometryOffset() const { return _geometryOffset; }
|
||||
|
||||
// get pre transform which should include FBX pre potations
|
||||
const AnimPose& getPreRotationPose(int jointIndex) const;
|
||||
|
@ -83,6 +84,7 @@ protected:
|
|||
std::vector<int> _mirrorMap;
|
||||
QHash<QString, int> _jointIndicesByName;
|
||||
std::vector<std::vector<HFMCluster>> _clusterBindMatrixOriginalValues;
|
||||
glm::mat4 _geometryOffset;
|
||||
|
||||
// no copies
|
||||
AnimSkeleton(const AnimSkeleton&) = delete;
|
||||
|
|
Loading…
Reference in a new issue