From fe683edb66185fc1fdbbf88615d82e1cb1b7b504 Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Sat, 21 Nov 2015 10:53:24 -0800 Subject: [PATCH] Avatar Debug Draw Default Pose now works --- interface/src/avatar/MyAvatar.cpp | 20 +++--- libraries/animation/src/Rig.cpp | 65 ++++++++++++++------ libraries/animation/src/Rig.h | 7 ++- libraries/render-utils/src/AnimDebugDraw.cpp | 42 ------------- 4 files changed, 61 insertions(+), 73 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index cec110d874..46df660bc4 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -628,7 +628,7 @@ void MyAvatar::setEnableDebugDrawDefaultPose(bool isEnabled) { _enableDebugDrawDefaultPose = isEnabled; if (!isEnabled) { - AnimDebugDraw::getInstance().removeSkeleton("myAvatar"); + AnimDebugDraw::getInstance().removeAbsolutePoses("myAvatarDefaultPoses"); } } @@ -636,7 +636,7 @@ void MyAvatar::setEnableDebugDrawAnimPose(bool isEnabled) { _enableDebugDrawAnimPose = isEnabled; if (!isEnabled) { - AnimDebugDraw::getInstance().removeAbsolutePoses("myAvatar"); + AnimDebugDraw::getInstance().removeAbsolutePoses("myAvatarAnimPoses"); } } @@ -1261,27 +1261,27 @@ void MyAvatar::preRender(RenderArgs* renderArgs) { auto animSkeleton = _rig->getAnimSkeleton(); - // bones are aligned such that z is forward, not -z. - glm::quat rotY180 = glm::angleAxis((float)M_PI, glm::vec3(0.0f, 1.0f, 0.0f)); - AnimPose xform(glm::vec3(1), getOrientation() * rotY180, getPosition()); - if (_enableDebugDrawDefaultPose && animSkeleton) { + AnimPose xform(glm::vec3(1), getOrientation(), getPosition()); glm::vec4 gray(0.2f, 0.2f, 0.2f, 0.2f); - AnimDebugDraw::getInstance().addSkeleton("myAvatar", animSkeleton, xform, gray); + AnimDebugDraw::getInstance().addAbsolutePoses("myAvatarDefaultPoses", animSkeleton, _rig->getAbsoluteDefaultPoses(), xform, gray); } if (_enableDebugDrawAnimPose && animSkeleton) { glm::vec4 cyan(0.1f, 0.6f, 0.6f, 1.0f); - auto rig = _skeletonModel.getRig(); + // getJointTransforms are aligned such that z is forward, not -z. + // so they need a 180 flip + glm::quat rotY180 = glm::angleAxis((float)M_PI, glm::vec3(0.0f, 1.0f, 0.0f)); + AnimPose xform(glm::vec3(1), getOrientation() * rotY180, getPosition()); // build absolute AnimPoseVec from rig AnimPoseVec absPoses; - absPoses.reserve(rig->getJointStateCount()); + absPoses.reserve(_rig->getJointStateCount()); for (int i = 0; i < _rig->getJointStateCount(); i++) { absPoses.push_back(AnimPose(_rig->getJointTransform(i))); } - AnimDebugDraw::getInstance().addAbsolutePoses("myAvatar", animSkeleton, absPoses, xform, cyan); + AnimDebugDraw::getInstance().addAbsolutePoses("myAvatarAnimPoses", animSkeleton, absPoses, xform, cyan); } } diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index 455b447f17..e61f56ba78 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -172,8 +172,9 @@ void Rig::destroyAnimGraph() { void Rig::initJointStates(const FBXGeometry& geometry, const glm::mat4& modelOffset) { - setModelOffset(modelOffset); _geometryOffset = AnimPose(geometry.offset); + setModelOffset(modelOffset); + _animSkeleton = std::make_shared(geometry); computeEyesInRootFrame(_animSkeleton->getRelativeDefaultPoses()); @@ -181,7 +182,7 @@ void Rig::initJointStates(const FBXGeometry& geometry, const glm::mat4& modelOff _relativePoses.clear(); _relativePoses = _animSkeleton->getRelativeDefaultPoses(); - buildAbsolutePoses(); + buildAbsoluteRigPoses(_relativePoses, _absolutePoses, true); _overridePoses.clear(); _overridePoses = _animSkeleton->getRelativeDefaultPoses(); @@ -189,6 +190,8 @@ void Rig::initJointStates(const FBXGeometry& geometry, const glm::mat4& modelOff _overrideFlags.clear(); _overrideFlags.resize(_animSkeleton->getNumJoints(), false); + buildAbsoluteRigPoses(_animSkeleton->getRelativeDefaultPoses(), _absoluteDefaultPoses); + _rootJointIndex = geometry.rootJointIndex; _leftHandJointIndex = geometry.leftHandJointIndex; _leftElbowJointIndex = _leftHandJointIndex >= 0 ? geometry.joints.at(_leftHandJointIndex).parentIndex : -1; @@ -207,7 +210,7 @@ void Rig::reset(const FBXGeometry& geometry) { _relativePoses.clear(); _relativePoses = _animSkeleton->getRelativeDefaultPoses(); - buildAbsolutePoses(); + buildAbsoluteRigPoses(_relativePoses, _absolutePoses, true); _overridePoses.clear(); _overridePoses = _animSkeleton->getRelativeDefaultPoses(); @@ -215,6 +218,8 @@ void Rig::reset(const FBXGeometry& geometry) { _overrideFlags.clear(); _overrideFlags.resize(_animSkeleton->getNumJoints(), false); + buildAbsoluteRigPoses(_animSkeleton->getRelativeDefaultPoses(), _absoluteDefaultPoses); + _rootJointIndex = geometry.rootJointIndex; _leftHandJointIndex = geometry.leftHandJointIndex; _leftElbowJointIndex = _leftHandJointIndex >= 0 ? geometry.joints.at(_leftHandJointIndex).parentIndex : -1; @@ -244,13 +249,22 @@ int Rig::indexOfJoint(const QString& jointName) const { } } -void Rig::setModelOffset(const glm::mat4& modelOffset) { - _modelOffset = AnimPose(modelOffset); +void Rig::setModelOffset(const glm::mat4& modelOffsetMat) { + AnimPose newModelOffset = AnimPose(modelOffsetMat); + if (!isEqual(_modelOffset.trans, newModelOffset.trans) || + !isEqual(_modelOffset.rot, newModelOffset.rot) || + !isEqual(_modelOffset.scale, newModelOffset.scale)) { - // compute geometryToAvatarTransforms - glm::quat yFlip180 = glm::angleAxis(PI, glm::vec3(0.0f, 1.0f, 0.0f)); - _geometryToRigTransform = AnimPose(glm::vec3(1), yFlip180, glm::vec3()) * _modelOffset * _geometryOffset; - _rigToGeometryTransform = glm::inverse(_geometryToRigTransform); + _modelOffset = newModelOffset; + + // compute geometryToAvatarTransforms + glm::quat yFlip180 = glm::angleAxis(PI, glm::vec3(0.0f, 1.0f, 0.0f)); + _geometryToRigTransform = AnimPose(glm::vec3(1), yFlip180, glm::vec3()) * _modelOffset * _geometryOffset; + _rigToGeometryTransform = glm::inverse(_geometryToRigTransform); + + // rebuild cached default poses + buildAbsoluteRigPoses(_animSkeleton->getRelativeDefaultPoses(), _absoluteDefaultPoses); + } } bool Rig::getJointStateRotation(int index, glm::quat& rotation) const { @@ -430,12 +444,16 @@ void Rig::computeEyesInRootFrame(const AnimPoseVec& poses) { AnimPose Rig::getAbsoluteDefaultPose(int index) const { if (_animSkeleton && index >= 0 && index < _animSkeleton->getNumJoints()) { - return AnimPose(_geometryToRigTransform) * _animSkeleton->getAbsoluteDefaultPose(index); + return _absoluteDefaultPoses[index]; } else { return AnimPose::identity; } } +const AnimPoseVec& Rig::getAbsoluteDefaultPoses() const { + return _absoluteDefaultPoses; +} + // animation reference speeds. static const std::vector FORWARD_SPEEDS = { 0.4f, 1.4f, 4.5f }; // m/s static const std::vector BACKWARD_SPEEDS = { 0.6f, 1.45f }; // m/s @@ -719,7 +737,7 @@ void Rig::updateAnimations(float deltaTime, glm::mat4 rootTransform) { } applyOverridePoses(); - buildAbsolutePoses(); + buildAbsoluteRigPoses(_relativePoses, _absolutePoses, true); } void Rig::inverseKinematics(int endIndex, glm::vec3 targetPosition, const glm::quat& targetRotation, float priority, @@ -1005,26 +1023,35 @@ void Rig::applyOverridePoses() { } } -void Rig::buildAbsolutePoses() { +// AJT: TODO: we should ALWAYS have the 180 flip. +// However currently matrices used for rendering require it. +// we need to find were the 180 is applied down the pipe and remove it, +// cluster matrices? render parts? +void Rig::buildAbsoluteRigPoses(const AnimPoseVec& relativePoses, AnimPoseVec& absolutePosesOut, bool omitY180Flip) { if (!_animSkeleton) { return; } - ASSERT(_animSkeleton->getNumJoints() == (int)_relativePoses.size()); + ASSERT(_animSkeleton->getNumJoints() == (int)relativePoses.size()); - _absolutePoses.resize(_relativePoses.size()); - for (int i = 0; i < (int)_relativePoses.size(); i++) { + // flatten all poses out so they are absolute not relative + absolutePosesOut.resize(relativePoses.size()); + for (int i = 0; i < (int)relativePoses.size(); i++) { int parentIndex = _animSkeleton->getParentIndex(i); if (parentIndex == -1) { - _absolutePoses[i] = _relativePoses[i]; + absolutePosesOut[i] = relativePoses[i]; } else { - _absolutePoses[i] = _absolutePoses[parentIndex] * _relativePoses[i]; + absolutePosesOut[i] = absolutePosesOut[parentIndex] * relativePoses[i]; } } - AnimPose rootTransform(_modelOffset * _geometryOffset); + // transform all absolute poses into rig space. + AnimPose geometryToRigTransform(_geometryToRigTransform); + if (omitY180Flip) { + geometryToRigTransform = _modelOffset * _geometryOffset; + } for (int i = 0; i < (int)_absolutePoses.size(); i++) { - _absolutePoses[i] = rootTransform * _absolutePoses[i]; + absolutePosesOut[i] = geometryToRigTransform * absolutePosesOut[i]; } } diff --git a/libraries/animation/src/Rig.h b/libraries/animation/src/Rig.h index 9428ae2c5e..b0d2af464a 100644 --- a/libraries/animation/src/Rig.h +++ b/libraries/animation/src/Rig.h @@ -88,7 +88,7 @@ public: int getJointStateCount() const; int indexOfJoint(const QString& jointName) const; - void setModelOffset(const glm::mat4& modelOffset); + void setModelOffset(const glm::mat4& modelOffsetMat); bool getJointStateRotation(int index, glm::quat& rotation) const; bool getJointStateTranslation(int index, glm::vec3& translation) const; @@ -147,6 +147,7 @@ public: const glm::vec3& getEyesInRootFrame() const { return _eyesInRootFrame; } AnimPose getAbsoluteDefaultPose(int index) const; // avatar space + const AnimPoseVec& getAbsoluteDefaultPoses() const; // avatar space void copyJointsIntoJointData(QVector& jointDataVec) const; void copyJointsFromJointData(const QVector& jointDataVec); @@ -155,7 +156,7 @@ public: bool isValid(int index) const { return _animSkeleton && index >= 0 && index < _animSkeleton->getNumJoints(); } void updateAnimationStateHandlers(); void applyOverridePoses(); - void buildAbsolutePoses(); + void buildAbsoluteRigPoses(const AnimPoseVec& relativePoses, AnimPoseVec& absolutePosesOut, bool omitY180Flip = false); void updateLeanJoint(int index, float leanSideways, float leanForward, float torsoTwist); void updateNeckJoint(int index, const HeadParameters& params); @@ -173,6 +174,8 @@ public: AnimPoseVec _overridePoses; // geometry space relative to parent. std::vector _overrideFlags; + AnimPoseVec _absoluteDefaultPoses; // avatar space, not relative to parent. + glm::mat4 _geometryToRigTransform; glm::mat4 _rigToGeometryTransform; diff --git a/libraries/render-utils/src/AnimDebugDraw.cpp b/libraries/render-utils/src/AnimDebugDraw.cpp index 078f1ecabc..8c0af768d1 100644 --- a/libraries/render-utils/src/AnimDebugDraw.cpp +++ b/libraries/render-utils/src/AnimDebugDraw.cpp @@ -349,17 +349,6 @@ void AnimDebugDraw::update() { // AJT: FIX ME /* - for (auto& iter : _skeletons) { - AnimSkeleton::ConstPointer& skeleton = std::get<0>(iter.second); - numVerts += skeleton->getNumJoints() * VERTICES_PER_BONE; - for (int i = 0; i < skeleton->getNumJoints(); i++) { - auto parentIndex = skeleton->getParentIndex(i); - if (parentIndex >= 0) { - numVerts += VERTICES_PER_LINK; - } - } - } - for (auto& iter : _animNodes) { AnimNode::ConstPointer& animNode = std::get<0>(iter.second); auto poses = animNode->getPosesInternal(); @@ -407,37 +396,6 @@ void AnimDebugDraw::update() { Vertex* verts = (Vertex*)data._vertexBuffer->editData(); Vertex* v = verts; - // AJT: fixme - // draw skeletons - /* - for (auto& iter : _skeletons) { - AnimSkeleton::ConstPointer& skeleton = std::get<0>(iter.second); - AnimPose rootPose = std::get<1>(iter.second); - int hipsIndex = skeleton->nameToJointIndex("Hips"); - if (hipsIndex >= 0) { - rootPose.trans -= skeleton->getRelativeBindPose(hipsIndex).trans; - } - glm::vec4 color = std::get<2>(iter.second); - - for (int i = 0; i < skeleton->getNumJoints(); i++) { - AnimPose pose = skeleton->getAbsoluteBindPose(i); - - const float radius = BONE_RADIUS / (pose.scale.x * rootPose.scale.x); - - // draw bone - addBone(rootPose, pose, radius, v); - - // draw link to parent - auto parentIndex = skeleton->getParentIndex(i); - if (parentIndex >= 0) { - assert(parentIndex < skeleton->getNumJoints()); - AnimPose parentPose = skeleton->getAbsoluteBindPose(parentIndex); - addLink(rootPose, pose, parentPose, radius, color, v); - } - } - } - */ - // AJT: FIXME /* // draw animNodes