added the const argument to the AnimSkeleton constructor that allows the offset rotations to be passed in

This commit is contained in:
amantley 2018-11-01 13:33:03 -07:00
parent f1d9ab76b4
commit 64d8fa6875
6 changed files with 36 additions and 26 deletions

View file

@ -84,7 +84,8 @@ void ScriptableAvatar::update(float deltatime) {
// Run animation // Run animation
if (_animation && _animation->isLoaded() && _animation->getFrames().size() > 0 && !_bind.isNull() && _bind->isLoaded()) { if (_animation && _animation->isLoaded() && _animation->getFrames().size() > 0 && !_bind.isNull() && _bind->isLoaded()) {
if (!_animSkeleton) { if (!_animSkeleton) {
_animSkeleton = std::make_shared<AnimSkeleton>(_bind->getGeometry()); QMap<int, glm::quat> jointRotationOffsets;
_animSkeleton = std::make_shared<AnimSkeleton>(_bind->getGeometry(), jointRotationOffsets);
} }
float currentFrame = _animationDetails.currentFrame + deltatime * _animationDetails.fps; float currentFrame = _animationDetails.currentFrame + deltatime * _animationDetails.fps;
if (_animationDetails.loop || currentFrame < _animationDetails.lastFrame) { if (_animationDetails.loop || currentFrame < _animationDetails.lastFrame) {

View file

@ -102,7 +102,8 @@ 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();
AnimSkeleton animSkeleton(geom); QMap<int, glm::quat> jointRotationOffsets;
AnimSkeleton animSkeleton(geom, jointRotationOffsets);
const auto animJointCount = animSkeleton.getNumJoints(); const auto animJointCount = animSkeleton.getNumJoints();
const auto skeletonJointCount = _skeleton->getNumJoints(); const auto skeletonJointCount = _skeleton->getNumJoints();
std::vector<int> jointMap; std::vector<int> jointMap;

View file

@ -16,21 +16,20 @@
#include "AnimationLogging.h" #include "AnimationLogging.h"
AnimSkeleton::AnimSkeleton(const FBXGeometry& fbxGeometry) { AnimSkeleton::AnimSkeleton(const FBXGeometry& fbxGeometry, const QMap<int, glm::quat> jointOffsets) {
// convert to std::vector of joints // convert to std::vector of joints
std::vector<FBXJoint> joints; std::vector<FBXJoint> joints;
joints.reserve(fbxGeometry.joints.size()); joints.reserve(fbxGeometry.joints.size());
_avatarTPoseOffsets.reserve(fbxGeometry.joints.size()); //_avatarTPoseOffsets.reserve(_jointsSize);
AnimPose identity(glm::quat(), glm::vec3());
for (auto& joint : fbxGeometry.joints) { for (auto& joint : fbxGeometry.joints) {
joints.push_back(joint); joints.push_back(joint);
_avatarTPoseOffsets.push_back(identity); //_avatarTPoseOffsets.push_back(AnimPose(glm::quat(), glm::vec3()));
} }
buildSkeletonFromJoints(joints);
/*
// add offsets for spine2 and the neck // add offsets for spine2 and the neck
_avatarTPoseOffsets[nameToJointIndex("Spine2")] = AnimPose(glm::quat(-0.707107f, 0.0f, 0.0f, 0.707107f), glm::vec3()); // _avatarTPoseOffsets[nameToJointIndex("Spine2")] = AnimPose(glm::quat(-0.707107f, 0.0f, 0.0f, 0.707107f), glm::vec3());
_avatarTPoseOffsets[nameToJointIndex("Neck")] = AnimPose(glm::quat(0.0f, 0.707107f, 0.0f, 0.707107f), glm::vec3()); // _avatarTPoseOffsets[nameToJointIndex("Neck")] = AnimPose(glm::quat(0.0f, 0.707107f, 0.0f, 0.707107f), glm::vec3());
for (int i = 0; i < (int)fbxGeometry.meshes.size(); i++) { for (int i = 0; i < (int)fbxGeometry.meshes.size(); i++) {
const FBXMesh& mesh = fbxGeometry.meshes.at(i); const FBXMesh& mesh = fbxGeometry.meshes.at(i);
@ -40,16 +39,19 @@ AnimSkeleton::AnimSkeleton(const FBXGeometry& fbxGeometry) {
// AJT: mutate bind pose! this allows us to oreint the skeleton back into the authored orientaiton before // AJT: mutate bind pose! this allows us to oreint the skeleton back into the authored orientaiton before
// rendering, with no runtime overhead. // rendering, with no runtime overhead.
// this works if clusters match joints one for one. // this works if clusters match joints one for one.
//cluster.inverseBindMatrix = (glm::mat4)_avatarTPoseOffsets[cluster.jointIndex].inverse() * cluster.inverseBindMatrix; if (jointOffsets.contains(j)) {
AnimPose localOffset(jointOffsets[j], glm::vec3());
cluster.inverseBindMatrix = (glm::mat4)localOffset.inverse() * cluster.inverseBindMatrix;
cluster.inverseBindTransform.evalFromRawMatrix(cluster.inverseBindMatrix); cluster.inverseBindTransform.evalFromRawMatrix(cluster.inverseBindMatrix);
}
}
*/
} }
AnimSkeleton::AnimSkeleton(const std::vector<FBXJoint>& joints) { }
buildSkeletonFromJoints(joints); }
buildSkeletonFromJoints(joints, jointOffsets);
}
AnimSkeleton::AnimSkeleton(const std::vector<FBXJoint>& joints, const QMap<int, glm::quat> jointOffsets) {
buildSkeletonFromJoints(joints, jointOffsets);
} }
int AnimSkeleton::nameToJointIndex(const QString& jointName) const { int AnimSkeleton::nameToJointIndex(const QString& jointName) const {
@ -188,7 +190,7 @@ void AnimSkeleton::mirrorAbsolutePoses(AnimPoseVec& poses) const {
} }
} }
void AnimSkeleton::buildSkeletonFromJoints(const std::vector<FBXJoint>& joints) { void AnimSkeleton::buildSkeletonFromJoints(const std::vector<FBXJoint>& joints, const QMap<int, glm::quat> jointOffsets) {
_joints = joints; _joints = joints;
_jointsSize = (int)joints.size(); _jointsSize = (int)joints.size();
// build a cache of bind poses // build a cache of bind poses
@ -218,9 +220,14 @@ void AnimSkeleton::buildSkeletonFromJoints(const std::vector<FBXJoint>& joints)
// remember the inverse bind pose already has the offset added into it. the total effect is offset^-1 * relDefPose * offset. // remember the inverse bind pose already has the offset added into it. the total effect is offset^-1 * relDefPose * offset.
// this gives us the correct transform for the joint that has been put in t-pose with an offset rotation. // this gives us the correct transform for the joint that has been put in t-pose with an offset rotation.
//relDefaultPose = relDefaultPose * _avatarTPoseOffsets[i]; //relDefaultPose = relDefaultPose * _avatarTPoseOffsets[i];
//if (parentIndex >= 0) { if (jointOffsets.contains(i)) {
// relDefaultPose = _avatarTPoseOffsets[parentIndex].inverse() * AnimPose(glm::quat(), relDefaultPose.trans()) * _avatarTPoseOffsets[parentIndex] * AnimPose(relDefaultPose.rot(), glm::vec3()); AnimPose localOffset(jointOffsets[i], glm::vec3());
//} relDefaultPose = relDefaultPose * localOffset;
if ((parentIndex >= 0) && jointOffsets.contains(parentIndex)) {
AnimPose localParentOffset(jointOffsets[parentIndex], glm::vec3());
relDefaultPose = localParentOffset.inverse() * AnimPose(glm::quat(), relDefaultPose.trans()) * localParentOffset * AnimPose(relDefaultPose.rot(), glm::vec3());
}
}
_relativeDefaultPoses.push_back(relDefaultPose); _relativeDefaultPoses.push_back(relDefaultPose);

View file

@ -23,8 +23,8 @@ public:
using Pointer = std::shared_ptr<AnimSkeleton>; using Pointer = std::shared_ptr<AnimSkeleton>;
using ConstPointer = std::shared_ptr<const AnimSkeleton>; using ConstPointer = std::shared_ptr<const AnimSkeleton>;
explicit AnimSkeleton(const FBXGeometry& fbxGeometry); explicit AnimSkeleton(const FBXGeometry& fbxGeometry, const QMap<int, glm::quat> jointOffsets);
explicit AnimSkeleton(const std::vector<FBXJoint>& joints); explicit AnimSkeleton(const std::vector<FBXJoint>& joints, const QMap<int, glm::quat> jointOffsets);
int nameToJointIndex(const QString& jointName) const; int nameToJointIndex(const QString& jointName) const;
const QString& getJointName(int jointIndex) const; const QString& getJointName(int jointIndex) const;
int getNumJoints() const; int getNumJoints() const;
@ -64,7 +64,7 @@ public:
std::vector<int> lookUpJointIndices(const std::vector<QString>& jointNames) const; std::vector<int> lookUpJointIndices(const std::vector<QString>& jointNames) const;
protected: protected:
void buildSkeletonFromJoints(const std::vector<FBXJoint>& joints); void buildSkeletonFromJoints(const std::vector<FBXJoint>& joints, const QMap<int, glm::quat> jointOffsets);
std::vector<FBXJoint> _joints; std::vector<FBXJoint> _joints;
AnimPoseVec _avatarTPoseOffsets; AnimPoseVec _avatarTPoseOffsets;

View file

@ -267,7 +267,7 @@ void Rig::initJointStates(const FBXGeometry& geometry, const glm::mat4& modelOff
_rigToGeometryTransform = glm::inverse(_geometryToRigTransform); _rigToGeometryTransform = glm::inverse(_geometryToRigTransform);
setModelOffset(modelOffset); setModelOffset(modelOffset);
_animSkeleton = std::make_shared<AnimSkeleton>(geometry); _animSkeleton = std::make_shared<AnimSkeleton>(geometry,_jointRotationOffsets);
_internalPoseSet._relativePoses.clear(); _internalPoseSet._relativePoses.clear();
_internalPoseSet._relativePoses = _animSkeleton->getRelativeDefaultPoses(); _internalPoseSet._relativePoses = _animSkeleton->getRelativeDefaultPoses();
@ -310,7 +310,7 @@ void Rig::initJointStates(const FBXGeometry& geometry, const glm::mat4& modelOff
void Rig::reset(const FBXGeometry& geometry) { void Rig::reset(const FBXGeometry& geometry) {
_geometryOffset = AnimPose(geometry.offset); _geometryOffset = AnimPose(geometry.offset);
_invGeometryOffset = _geometryOffset.inverse(); _invGeometryOffset = _geometryOffset.inverse();
_animSkeleton = std::make_shared<AnimSkeleton>(geometry); _animSkeleton = std::make_shared<AnimSkeleton>(geometry, _jointRotationOffsets);
_internalPoseSet._relativePoses.clear(); _internalPoseSet._relativePoses.clear();
_internalPoseSet._relativePoses = _animSkeleton->getRelativeDefaultPoses(); _internalPoseSet._relativePoses = _animSkeleton->getRelativeDefaultPoses();

View file

@ -55,7 +55,8 @@ SkeletonDumpApp::SkeletonDumpApp(int argc, char* argv[]) : QCoreApplication(argc
} }
QByteArray blob = file.readAll(); QByteArray blob = file.readAll();
std::unique_ptr<FBXGeometry> fbxGeometry(readFBX(blob, QVariantHash())); std::unique_ptr<FBXGeometry> fbxGeometry(readFBX(blob, QVariantHash()));
std::unique_ptr<AnimSkeleton> skeleton(new AnimSkeleton(*fbxGeometry)); QMap<int, glm::quat> jointRotationOffsets;
std::unique_ptr<AnimSkeleton> skeleton(new AnimSkeleton(*fbxGeometry, jointRotationOffsets));
skeleton->dump(verbose); skeleton->dump(verbose);
} }