mirror of
https://github.com/Armored-Dragon/overte.git
synced 2025-03-11 16:13:16 +01:00
AnimClip: read in translations from fbx file and pre-process them
Do the following things to the translations 1. scale by the model offset, this should move the translations into the correct units (meters). 2. compute the ratio between the bone length in the animation and the skeleton. 3. subtract the anim translation from the first translation frame in the animation effectively turning it into a bind pose delta translation. 4. apply bone length ratio to the resulting delta. 5. set the final translation to be the skeleton rel bind pose + this scaled delta translation
This commit is contained in:
parent
8bfd38ce7c
commit
fe5ea471a1
1 changed files with 32 additions and 15 deletions
|
@ -135,29 +135,46 @@ void AnimClip::copyFromNetworkAnim() {
|
|||
const int frameCount = geom.animationFrames.size();
|
||||
const int skeletonJointCount = _skeleton->getNumJoints();
|
||||
_anim.resize(frameCount);
|
||||
for (int i = 0; i < frameCount; i++) {
|
||||
|
||||
const glm::vec3 offsetScale = extractScale(geom.offset);
|
||||
|
||||
for (int frame = 0; frame < frameCount; frame++) {
|
||||
|
||||
// init all joints in animation to bind pose
|
||||
_anim[i].reserve(skeletonJointCount);
|
||||
for (int j = 0; j < skeletonJointCount; j++) {
|
||||
_anim[i].push_back(_skeleton->getRelativeBindPose(j));
|
||||
// this will give us a resonable result for bones in the skeleton but not in the animation.
|
||||
_anim[frame].reserve(skeletonJointCount);
|
||||
for (int skeletonJoint = 0; skeletonJoint < skeletonJointCount; skeletonJoint++) {
|
||||
_anim[frame].push_back(_skeleton->getRelativeBindPose(skeletonJoint));
|
||||
}
|
||||
|
||||
// init over all joint animations
|
||||
for (int j = 0; j < animJointCount; j++) {
|
||||
int k = jointMap[j];
|
||||
if (k >= 0 && k < skeletonJointCount) {
|
||||
_anim[i][k].rot = _skeleton->getRelativeBindPose(k).rot * geom.animationFrames[i].rotations[j];
|
||||
for (int animJoint = 0; animJoint < animJointCount; animJoint++) {
|
||||
|
||||
// TODO -- why does applying all the joint translations make a mutant?
|
||||
if (animJoints[j].parentIndex == -1) {
|
||||
_anim[i][k].trans = geom.animationFrames[i].translations[j] * extractScale(geom.offset);
|
||||
} else {
|
||||
_anim[i][k].trans = _skeleton->getRelativeBindPose(k).trans;
|
||||
}
|
||||
int skeletonJoint = jointMap[animJoint];
|
||||
|
||||
// skip joints that are in the animation but not in the skeleton.
|
||||
if (skeletonJoint >= 0 && skeletonJoint < skeletonJointCount) {
|
||||
|
||||
const glm::vec3& fbxZeroTrans = geom.animationFrames[0].translations[animJoint] * offsetScale;
|
||||
const AnimPose& relBindPose = _skeleton->getRelativeBindPose(skeletonJoint);
|
||||
|
||||
// used to adjust translation offsets, so large translation animatons on the reference skeleton
|
||||
// will be adjusted when played on a skeleton with short limbs.
|
||||
float limbLengthScale = fabs(glm::length(fbxZeroTrans)) <= 0.0001f ? 1.0f : (glm::length(relBindPose.trans) / glm::length(fbxZeroTrans));
|
||||
|
||||
AnimPose& pose = _anim[frame][skeletonJoint];
|
||||
const FBXAnimationFrame& fbxAnimFrame = geom.animationFrames[frame];
|
||||
|
||||
// rotation in fbxAnimationFrame is a delta from a reference skeleton bind pose.
|
||||
pose.rot = relBindPose.rot * fbxAnimFrame.rotations[animJoint];
|
||||
|
||||
// translation in fbxAnimationFrame is not a delta.
|
||||
// convert it into a delta by subtracting from the first frame.
|
||||
const glm::vec3& fbxTrans = fbxAnimFrame.translations[animJoint] * offsetScale;
|
||||
pose.trans = relBindPose.trans + limbLengthScale * (fbxTrans - fbxZeroTrans);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_poses.resize(skeletonJointCount);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue