mirror of
https://github.com/overte-org/overte.git
synced 2025-08-08 11:37:58 +02:00
Added USE_PRE_ROT_FROM_ANIM option to AnimClip
This will allow us in the future to pull preRotations from animations instead of the model skeleton. It is disabled by default because our current animations preRotations are not correct for the left hand.
This commit is contained in:
parent
8252bbed9b
commit
8f46b8a765
2 changed files with 20 additions and 20 deletions
|
@ -91,41 +91,48 @@ void AnimClip::copyFromNetworkAnim() {
|
||||||
// build a mapping from animation joint indices to skeleton joint indices.
|
// build a mapping from animation joint indices to skeleton joint indices.
|
||||||
// by matching joints with the same name.
|
// by matching joints with the same name.
|
||||||
const FBXGeometry& geom = _networkAnim->getGeometry();
|
const FBXGeometry& geom = _networkAnim->getGeometry();
|
||||||
const QVector<FBXJoint>& animJoints = geom.joints;
|
AnimSkeleton animSkeleton(geom);
|
||||||
|
const int animJointCount = animSkeleton.getNumJoints();
|
||||||
|
const int skeletonJointCount = _skeleton->getNumJoints();
|
||||||
std::vector<int> jointMap;
|
std::vector<int> jointMap;
|
||||||
const int animJointCount = animJoints.count();
|
|
||||||
jointMap.reserve(animJointCount);
|
jointMap.reserve(animJointCount);
|
||||||
for (int i = 0; i < animJointCount; i++) {
|
for (int i = 0; i < animJointCount; i++) {
|
||||||
int skeletonJoint = _skeleton->nameToJointIndex(animJoints.at(i).name);
|
int skeletonJoint = _skeleton->nameToJointIndex(animSkeleton.getJointName(i));
|
||||||
if (skeletonJoint == -1) {
|
if (skeletonJoint == -1) {
|
||||||
qCWarning(animation) << "animation contains joint =" << animJoints.at(i).name << " which is not in the skeleton, url =" << _url;
|
qCWarning(animation) << "animation contains joint =" << animSkeleton.getJointName(i) << " which is not in the skeleton, url =" << _url;
|
||||||
}
|
}
|
||||||
jointMap.push_back(skeletonJoint);
|
jointMap.push_back(skeletonJoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
const int frameCount = geom.animationFrames.size();
|
const int frameCount = geom.animationFrames.size();
|
||||||
const int skeletonJointCount = _skeleton->getNumJoints();
|
|
||||||
_anim.resize(frameCount);
|
_anim.resize(frameCount);
|
||||||
|
|
||||||
for (int frame = 0; frame < frameCount; frame++) {
|
for (int frame = 0; frame < frameCount; frame++) {
|
||||||
|
|
||||||
// init all joints in animation to bind pose
|
// init all joints in animation to default pose
|
||||||
// this will give us a resonable result for bones in the skeleton but not in the animation.
|
// this will give us a resonable result for bones in the model skeleton but not in the animation.
|
||||||
_anim[frame].reserve(skeletonJointCount);
|
_anim[frame].reserve(skeletonJointCount);
|
||||||
for (int skeletonJoint = 0; skeletonJoint < skeletonJointCount; skeletonJoint++) {
|
for (int skeletonJoint = 0; skeletonJoint < skeletonJointCount; skeletonJoint++) {
|
||||||
_anim[frame].push_back(_skeleton->getRelativeBindPose(skeletonJoint));
|
_anim[frame].push_back(_skeleton->getRelativeDefaultPose(skeletonJoint));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int animJoint = 0; animJoint < animJointCount; animJoint++) {
|
for (int animJoint = 0; animJoint < animJointCount; animJoint++) {
|
||||||
|
|
||||||
int skeletonJoint = jointMap[animJoint];
|
int skeletonJoint = jointMap[animJoint];
|
||||||
|
|
||||||
// skip joints that are in the animation but not in the skeleton.
|
// skip joints that are in the animation but not in the skeleton.
|
||||||
if (skeletonJoint >= 0 && skeletonJoint < skeletonJointCount) {
|
if (skeletonJoint >= 0 && skeletonJoint < skeletonJointCount) {
|
||||||
|
|
||||||
const glm::vec3& fbxZeroTrans = geom.animationFrames[0].translations[animJoint];
|
const glm::vec3& fbxZeroTrans = geom.animationFrames[0].translations[animJoint];
|
||||||
// AJT: TODO: use the actual preRotation not the bind pose here.
|
#ifdef USE_PRE_ROT_FROM_ANIM
|
||||||
const AnimPose& jointOrientPose = _skeleton->getRelativeBindPose(skeletonJoint);
|
// TODO: This is the correct way to apply the pre rotations from maya, however
|
||||||
|
// the current animation set has incorrect preRotations for the left wrist and thumb
|
||||||
|
// so it looks wrong if we enable this code.
|
||||||
|
glm::quat preRotation = animSkeleton.getPreRotation(animJoint);
|
||||||
|
#else
|
||||||
|
// TODO: This is legacy approach, this does not work when animations and models do not
|
||||||
|
// have the same set of pre rotations. For example when mixing maya models with blender animations.
|
||||||
|
glm::quat preRotation = _skeleton->getRelativeBindPose(skeletonJoint).rot;
|
||||||
|
#endif
|
||||||
const AnimPose& relDefaultPose = _skeleton->getRelativeDefaultPose(skeletonJoint);
|
const AnimPose& relDefaultPose = _skeleton->getRelativeDefaultPose(skeletonJoint);
|
||||||
|
|
||||||
// used to adjust translation offsets, so large translation animatons on the reference skeleton
|
// used to adjust translation offsets, so large translation animatons on the reference skeleton
|
||||||
|
@ -135,8 +142,8 @@ void AnimClip::copyFromNetworkAnim() {
|
||||||
AnimPose& pose = _anim[frame][skeletonJoint];
|
AnimPose& pose = _anim[frame][skeletonJoint];
|
||||||
const FBXAnimationFrame& fbxAnimFrame = geom.animationFrames[frame];
|
const FBXAnimationFrame& fbxAnimFrame = geom.animationFrames[frame];
|
||||||
|
|
||||||
// rotation in fbxAnimationFrame is a delta from its jointOrientPose (aka preRotation)
|
// rotation in fbxAnimationFrame is a delta from its preRotation.
|
||||||
pose.rot = jointOrientPose.rot * fbxAnimFrame.rotations[animJoint];
|
pose.rot = preRotation * fbxAnimFrame.rotations[animJoint];
|
||||||
|
|
||||||
// translation in fbxAnimationFrame is not a delta.
|
// translation in fbxAnimationFrame is not a delta.
|
||||||
// convert it into a delta by subtracting from the first frame.
|
// convert it into a delta by subtracting from the first frame.
|
||||||
|
|
|
@ -750,13 +750,6 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS
|
||||||
model.preRotation = glm::quat(glm::radians(preRotation));
|
model.preRotation = glm::quat(glm::radians(preRotation));
|
||||||
model.rotation = glm::quat(glm::radians(rotation));
|
model.rotation = glm::quat(glm::radians(rotation));
|
||||||
model.postRotation = glm::quat(glm::radians(postRotation));
|
model.postRotation = glm::quat(glm::radians(postRotation));
|
||||||
|
|
||||||
if (geometry.applicationName.startsWith("Blender")) {
|
|
||||||
// blender puts the jointOffset in the wrong place.
|
|
||||||
model.preRotation = model.rotation;
|
|
||||||
model.rotation = glm::quat();
|
|
||||||
}
|
|
||||||
|
|
||||||
model.postTransform = glm::translate(-rotationPivot) * glm::translate(scaleOffset) *
|
model.postTransform = glm::translate(-rotationPivot) * glm::translate(scaleOffset) *
|
||||||
glm::translate(scalePivot) * glm::scale(scale) * glm::translate(-scalePivot);
|
glm::translate(scalePivot) * glm::scale(scale) * glm::translate(-scalePivot);
|
||||||
// NOTE: angles from the FBX file are in degrees
|
// NOTE: angles from the FBX file are in degrees
|
||||||
|
|
Loading…
Reference in a new issue