diff --git a/libraries/animation/src/AnimClip.cpp b/libraries/animation/src/AnimClip.cpp index 6f16a8d884..dbb241d484 100644 --- a/libraries/animation/src/AnimClip.cpp +++ b/libraries/animation/src/AnimClip.cpp @@ -121,14 +121,14 @@ void AnimClip::copyFromNetworkAnim() { // build a mapping from animation joint indices to skeleton joint indices. // by matching joints with the same name. const FBXGeometry& geom = _networkAnim->getGeometry(); - const QVector& joints = geom.joints; + const QVector& animJoints = geom.joints; std::vector jointMap; - const int animJointCount = joints.count(); + const int animJointCount = animJoints.count(); jointMap.reserve(animJointCount); for (int i = 0; i < animJointCount; i++) { - int skeletonJoint = _skeleton->nameToJointIndex(joints.at(i).name); + int skeletonJoint = _skeleton->nameToJointIndex(animJoints.at(i).name); if (skeletonJoint == -1) { - qCWarning(animation) << "animation contains joint =" << joints.at(i).name << " which is not in the skeleton, url =" << _url.c_str(); + qCWarning(animation) << "animation contains joint =" << animJoints.at(i).name << " which is not in the skeleton, url =" << _url.c_str(); } jointMap.push_back(skeletonJoint); } @@ -138,10 +138,10 @@ void AnimClip::copyFromNetworkAnim() { _anim.resize(frameCount); for (int i = 0; i < frameCount; i++) { - // init all joints in animation to relative bind pose + // init all joints in animation to identity _anim[i].reserve(skeletonJointCount); for (int j = 0; j < skeletonJointCount; j++) { - _anim[i].push_back(_skeleton->getRelativeBindPose(j)); + _anim[i].push_back(AnimPose::identity); } // init over all joint animations @@ -149,7 +149,7 @@ void AnimClip::copyFromNetworkAnim() { int k = jointMap[j]; if (k >= 0 && k < skeletonJointCount) { // currently FBX animations only have rotation. - _anim[i][k].rot = _skeleton->getRelativeBindPose(k).rot * geom.animationFrames[i].rotations[j]; + _anim[i][k].rot = geom.animationFrames[i].rotations[j]; } } } diff --git a/libraries/animation/src/AnimSkeleton.cpp b/libraries/animation/src/AnimSkeleton.cpp index e966203d22..feaa1828ce 100644 --- a/libraries/animation/src/AnimSkeleton.cpp +++ b/libraries/animation/src/AnimSkeleton.cpp @@ -8,6 +8,7 @@ // #include "AnimSkeleton.h" +#include "AnimationLogging.h" #include "glmHelpers.h" const AnimPose AnimPose::identity = AnimPose(glm::vec3(1.0f), @@ -16,10 +17,22 @@ const AnimPose AnimPose::identity = AnimPose(glm::vec3(1.0f), AnimPose::AnimPose(const glm::mat4& mat) { scale = extractScale(mat); - rot = glm::quat_cast(mat); + rot = glm::normalize(glm::quat_cast(mat)); trans = extractTranslation(mat); } +glm::vec3 AnimPose::operator*(const glm::vec3& rhs) const { + return trans + (rot * (scale * rhs)); +} + +AnimPose AnimPose::operator*(const AnimPose& rhs) const { + return AnimPose(static_cast(*this) * static_cast(rhs)); +} + +AnimPose AnimPose::inverse() const { + return AnimPose(glm::inverse(static_cast(*this))); +} + AnimPose::operator glm::mat4() const { glm::vec3 xAxis = rot * glm::vec3(scale.x, 0.0f, 0.0f); glm::vec3 yAxis = rot * glm::vec3(0.0f, scale.y, 0.0f); @@ -28,6 +41,7 @@ AnimPose::operator glm::mat4() const { glm::vec4(zAxis, 0.0f), glm::vec4(trans, 1.0f)); } + AnimSkeleton::AnimSkeleton(const std::vector& joints) { _joints = joints; @@ -35,17 +49,32 @@ AnimSkeleton::AnimSkeleton(const std::vector& joints) { _absoluteBindPoses.reserve(joints.size()); _relativeBindPoses.reserve(joints.size()); for (size_t i = 0; i < joints.size(); i++) { - glm::mat4 absBindMat = _joints[i].bindTransform; - AnimPose absBindPose(_joints[i].bindTransform); - _absoluteBindPoses.push_back(absBindPose); + + AnimPose absoluteBindPose(_joints[i].bindTransform); + _absoluteBindPoses.push_back(absoluteBindPose); + int parentIndex = getParentIndex(i); if (parentIndex >= 0) { - glm::mat4 invParentAbsBindMat = glm::inverse(_joints[parentIndex].bindTransform); - glm::mat4 relBindMat = invParentAbsBindMat * absBindMat; - _relativeBindPoses.push_back(AnimPose(relBindMat)); + AnimPose inverseParentAbsoluteBindPose = _absoluteBindPoses[parentIndex].inverse(); + _relativeBindPoses.push_back(inverseParentAbsoluteBindPose * absoluteBindPose); } else { - _relativeBindPoses.push_back(absBindPose); + _relativeBindPoses.push_back(absoluteBindPose); } + + // AJT: + // Attempt to use relative bind pose.. but it's not working. + /* + AnimPose relBindPose(glm::vec3(1.0f), _joints[i].rotation, _joints[i].translation); + _relativeBindPoses.push_back(relBindPose); + + int parentIndex = getParentIndex(i); + if (parentIndex >= 0) { + AnimPose parentAbsBindPose = _absoluteBindPoses[parentIndex]; + _absoluteBindPoses.push_back(parentAbsBindPose * relBindPose); + } else { + _absoluteBindPoses.push_back(relBindPose); + } + */ } } @@ -74,4 +103,6 @@ int AnimSkeleton::getParentIndex(int jointIndex) const { return _joints[jointIndex].parentIndex; } - +const QString& AnimSkeleton::getJointName(int jointIndex) const { + return _joints[jointIndex].name; +} diff --git a/libraries/animation/src/AnimSkeleton.h b/libraries/animation/src/AnimSkeleton.h index 9019a1b356..b51daadae7 100644 --- a/libraries/animation/src/AnimSkeleton.h +++ b/libraries/animation/src/AnimSkeleton.h @@ -16,18 +16,13 @@ struct AnimPose { AnimPose() {} - AnimPose(const glm::mat4& mat); + explicit AnimPose(const glm::mat4& mat); AnimPose(const glm::vec3& scaleIn, const glm::quat& rotIn, const glm::vec3& transIn) : scale(scaleIn), rot(rotIn), trans(transIn) {} static const AnimPose identity; - glm::vec3 operator*(const glm::vec3& rhs) const { - return trans + (rot * (scale * rhs)); - } - - AnimPose operator*(const AnimPose& rhs) const { - return AnimPose(static_cast(*this) * static_cast(rhs)); - } - + glm::vec3 operator*(const glm::vec3& rhs) const; + AnimPose operator*(const AnimPose& rhs) const; + AnimPose inverse() const; operator glm::mat4() const; glm::vec3 scale; @@ -35,12 +30,18 @@ struct AnimPose { glm::vec3 trans; }; +inline QDebug operator<<(QDebug debug, const AnimPose& pose) { + debug << "AnimPose, trans = (" << pose.trans.x << pose.trans.y << pose.trans.z << "), rot = (" << pose.rot.x << pose.rot.y << pose.rot.z << pose.rot.w << "), scale = (" << pose.scale.x << pose.scale.y << pose.scale.z << ")"; + return debug; +} + class AnimSkeleton { public: typedef std::shared_ptr Pointer; AnimSkeleton(const std::vector& joints); int nameToJointIndex(const QString& jointName) const; + const QString& getJointName(int jointIndex) const; int getNumJoints() const; // absolute pose, not relative to parent diff --git a/libraries/render-utils/src/AnimDebugDraw.cpp b/libraries/render-utils/src/AnimDebugDraw.cpp index 6e3bb4bc8a..8a9877ca12 100644 --- a/libraries/render-utils/src/AnimDebugDraw.cpp +++ b/libraries/render-utils/src/AnimDebugDraw.cpp @@ -13,6 +13,7 @@ #include "AnimDebugDraw.h" #include "AbstractViewStateInterface.h" +#include "RenderUtilsLogging.h" struct Vertex { glm::vec3 pos; @@ -218,7 +219,8 @@ void AnimDebugDraw::update() { AnimSkeleton::Pointer& skeleton = iter.second.first; numVerts += skeleton->getNumJoints() * 6; for (int i = 0; i < skeleton->getNumJoints(); i++) { - if (skeleton->getParentIndex(i) >= 0) { + auto parentIndex = skeleton->getParentIndex(i); + if (parentIndex >= 0) { numVerts += 2; } } @@ -229,8 +231,9 @@ void AnimDebugDraw::update() { auto poses = animNode->getPosesInternal(); numVerts += poses.size() * 6; auto skeleton = animNode->getSkeleton(); - for (int i = 0; i < poses.size(); i++) { - if (skeleton->getParentIndex(i) >= 0) { + for (size_t i = 0; i < poses.size(); i++) { + auto parentIndex = skeleton->getParentIndex(i); + if (parentIndex >= 0) { numVerts += 2; } } @@ -251,8 +254,14 @@ void AnimDebugDraw::update() { addWireframeSphereWithAxes(rootPose, pose, radius, v); // line to parent. - if (skeleton->getParentIndex(i) >= 0) { - AnimPose parentPose = skeleton->getAbsoluteBindPose(skeleton->getParentIndex(i)); + auto parentIndex = skeleton->getParentIndex(i); + //qCDebug(renderutils) << skeleton->getJointName(i) << " index = " << i; + //qCDebug(renderutils) << " absPose =" << skeleton->getAbsoluteBindPose(i); + //qCDebug(renderutils) << " relPose =" << skeleton->getRelativeBindPose(i); + if (parentIndex >= 0) { + //qCDebug(renderutils) << " parent =" << parentIndex; + assert(parentIndex < skeleton->getNumJoints()); + AnimPose parentPose = skeleton->getAbsoluteBindPose(parentIndex); addWireframeBoneAxis(rootPose, pose, parentPose, radius, v); } } @@ -266,7 +275,7 @@ void AnimDebugDraw::update() { auto skeleton = animNode->getSkeleton(); std::vector absAnimPose; - absAnimPose.reserve(skeleton->getNumJoints()); + absAnimPose.resize(skeleton->getNumJoints()); for (size_t i = 0; i < poses.size(); i++) { @@ -282,18 +291,20 @@ void AnimDebugDraw::update() { addWireframeSphereWithAxes(rootPose, absAnimPose[i], radius, v); if (parentIndex >= 0) { + assert((size_t)parentIndex < poses.size()); // draw line to parent addWireframeBoneAxis(rootPose, absAnimPose[i], absAnimPose[parentIndex], radius, v); } } } + assert(numVerts == (v - verts)); + data._indexBuffer->resize(sizeof(uint16_t) * numVerts); uint16_t* indices = (uint16_t*)data._indexBuffer->editData(); for (int i = 0; i < numVerts; i++) { indices[i] = i; } - }); scene->enqueuePendingChanges(pendingChanges); }