diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 99b634dec1..88f8a64830 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -1221,7 +1221,7 @@ void MyAvatar::preRender(RenderArgs* renderArgs) { joints.push_back(joint); } auto skeleton = make_shared(joints); - AnimPose xform(glm::vec3(1.0f), glm::quat(), glm::vec3(0.0)); + AnimPose xform(_skeletonModel.getScale(), glm::quat(), _skeletonModel.getOffset()); AnimDebugDraw::getInstance().addSkeleton("my-avatar", skeleton, xform); _animNode = make_shared("clip", "https://hifi-public.s3.amazonaws.com/ozan/support/FightClubBotTest1/Animations/standard_idle.fbx", 0.0f, 90.0f, 1.0f, true); diff --git a/libraries/animation/src/AnimClip.cpp b/libraries/animation/src/AnimClip.cpp index dbb241d484..9f97602ed1 100644 --- a/libraries/animation/src/AnimClip.cpp +++ b/libraries/animation/src/AnimClip.cpp @@ -138,10 +138,10 @@ void AnimClip::copyFromNetworkAnim() { _anim.resize(frameCount); for (int i = 0; i < frameCount; i++) { - // init all joints in animation to identity + // init all joints in animation to bind pose _anim[i].reserve(skeletonJointCount); for (int j = 0; j < skeletonJointCount; j++) { - _anim[i].push_back(AnimPose::identity); + _anim[i].push_back(_skeleton->getRelativeBindPose(j)); } // 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 = geom.animationFrames[i].rotations[j]; + _anim[i][k].rot = _skeleton->getRelativeBindPose(j).rot * geom.animationFrames[i].rotations[j]; } } } diff --git a/libraries/animation/src/AnimSkeleton.cpp b/libraries/animation/src/AnimSkeleton.cpp index feaa1828ce..27556c6930 100644 --- a/libraries/animation/src/AnimSkeleton.cpp +++ b/libraries/animation/src/AnimSkeleton.cpp @@ -10,6 +10,8 @@ #include "AnimSkeleton.h" #include "AnimationLogging.h" #include "glmHelpers.h" +#include +#include const AnimPose AnimPose::identity = AnimPose(glm::vec3(1.0f), glm::quat(), @@ -17,7 +19,7 @@ const AnimPose AnimPose::identity = AnimPose(glm::vec3(1.0f), AnimPose::AnimPose(const glm::mat4& mat) { scale = extractScale(mat); - rot = glm::normalize(glm::quat_cast(mat)); + rot = extractRotation(mat); trans = extractTranslation(mat); } @@ -41,6 +43,7 @@ AnimPose::operator glm::mat4() const { glm::vec4(zAxis, 0.0f), glm::vec4(trans, 1.0f)); } +//#define TRUST_BIND_TRANSFORM AnimSkeleton::AnimSkeleton(const std::vector& joints) { _joints = joints; @@ -50,9 +53,31 @@ AnimSkeleton::AnimSkeleton(const std::vector& joints) { _relativeBindPoses.reserve(joints.size()); for (size_t i = 0; i < joints.size(); i++) { + /* + // AJT: dump the skeleton, because wtf. + qCDebug(animation) << getJointName(i); + qCDebug(animation) << " isFree =" << _joints[i].isFree; + qCDebug(animation) << " freeLineage =" << _joints[i].freeLineage; + qCDebug(animation) << " parentIndex =" << _joints[i].parentIndex; + qCDebug(animation) << " boneRadius =" << _joints[i].boneRadius; + qCDebug(animation) << " translation =" << _joints[i].translation; + qCDebug(animation) << " preTransform =" << _joints[i].preTransform; + qCDebug(animation) << " preRotation =" << _joints[i].preRotation; + qCDebug(animation) << " rotation =" << _joints[i].rotation; + qCDebug(animation) << " postRotation =" << _joints[i].postRotation; + qCDebug(animation) << " postTransform =" << _joints[i].postTransform; + qCDebug(animation) << " transform =" << _joints[i].transform; + qCDebug(animation) << " rotationMin =" << _joints[i].rotationMin << ", rotationMax =" << _joints[i].rotationMax; + qCDebug(animation) << " inverseDefaultRotation" << _joints[i].inverseDefaultRotation; + qCDebug(animation) << " inverseBindRotation" << _joints[i].inverseBindRotation; + qCDebug(animation) << " bindTransform" << _joints[i].bindTransform; + qCDebug(animation) << " isSkeletonJoint" << _joints[i].isSkeletonJoint; + */ + +#ifdef TRUST_BIND_TRANSFORM + // trust FBXJoint::bindTransform (which is wrong for joints NOT bound to anything) AnimPose absoluteBindPose(_joints[i].bindTransform); _absoluteBindPoses.push_back(absoluteBindPose); - int parentIndex = getParentIndex(i); if (parentIndex >= 0) { AnimPose inverseParentAbsoluteBindPose = _absoluteBindPoses[parentIndex].inverse(); @@ -60,24 +85,24 @@ AnimSkeleton::AnimSkeleton(const std::vector& joints) { } else { _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); +#else + // trust FBXJoint's local transforms (which is not really the bind pose, but the default pose in the fbx) + glm::mat4 rotTransform = glm::mat4_cast(_joints[i].preRotation * _joints[i].rotation * _joints[i].postRotation); + glm::mat4 relBindMat = glm::translate(_joints[i].translation) * _joints[i].preTransform * rotTransform * _joints[i].postTransform; + AnimPose relBindPose(relBindMat); _relativeBindPoses.push_back(relBindPose); int parentIndex = getParentIndex(i); if (parentIndex >= 0) { - AnimPose parentAbsBindPose = _absoluteBindPoses[parentIndex]; - _absoluteBindPoses.push_back(parentAbsBindPose * relBindPose); + _absoluteBindPoses.push_back(_absoluteBindPoses[parentIndex] * relBindPose); } else { _absoluteBindPoses.push_back(relBindPose); } - */ +#endif } } + int AnimSkeleton::nameToJointIndex(const QString& jointName) const { for (size_t i = 0; i < _joints.size(); i++) { if (_joints[i].name == jointName) { diff --git a/libraries/render-utils/src/AnimDebugDraw.cpp b/libraries/render-utils/src/AnimDebugDraw.cpp index 8a9877ca12..7bfe7be98d 100644 --- a/libraries/render-utils/src/AnimDebugDraw.cpp +++ b/libraries/render-utils/src/AnimDebugDraw.cpp @@ -167,27 +167,29 @@ static const uint32_t cyan = toRGBA(0, 128, 128, 255); static void addWireframeSphereWithAxes(const AnimPose& rootPose, const AnimPose& pose, float radius, Vertex*& v) { + glm::vec3 base = rootPose * pose.trans; + // x-axis - v->pos = rootPose * pose.trans; + v->pos = base; v->rgba = red; v++; - v->pos = rootPose * (pose.trans + pose.rot * glm::vec3(radius * 2.0f, 0.0f, 0.0f)); + v->pos = rootPose * (pose.trans + pose.rot * glm::vec3(radius, 0.0f, 0.0f)); v->rgba = red; v++; // y-axis - v->pos = rootPose * pose.trans; + v->pos = base; v->rgba = green; v++; - v->pos = rootPose * (pose.trans + pose.rot * glm::vec3(0.0f, radius * 2.0f, 0.0f)); + v->pos = rootPose * (pose.trans + pose.rot * glm::vec3(0.0f, radius, 0.0f)); v->rgba = green; v++; // z-axis - v->pos = rootPose * pose.trans; + v->pos = base; v->rgba = blue; v++; - v->pos = rootPose * (pose.trans + pose.rot * glm::vec3(0.0f, 0.0f, radius * 2.0f)); + v->pos = rootPose * (pose.trans + pose.rot * glm::vec3(0.0f, 0.0f, radius)); v->rgba = blue; v++; } @@ -250,16 +252,12 @@ void AnimDebugDraw::update() { AnimPose pose = skeleton->getAbsoluteBindPose(i); // draw axes - const float radius = 0.01f; + const float radius = 0.1f; addWireframeSphereWithAxes(rootPose, pose, radius, v); // line to parent. 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); @@ -287,7 +285,7 @@ void AnimDebugDraw::update() { } // draw axes - const float radius = 0.01f; + const float radius = 0.1f; addWireframeSphereWithAxes(rootPose, absAnimPose[i], radius, v); if (parentIndex >= 0) {