From 339ecb1faa3897de1a9e0e5e1011fcb43ffdfdab Mon Sep 17 00:00:00 2001 From: amantley Date: Tue, 30 Oct 2018 16:54:34 -0700 Subject: [PATCH 01/32] adding the offsets to the AnimSkeleton.cpp --- libraries/animation/src/AnimSkeleton.cpp | 34 ++++++++++++++++++++++-- libraries/animation/src/AnimSkeleton.h | 1 + 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/libraries/animation/src/AnimSkeleton.cpp b/libraries/animation/src/AnimSkeleton.cpp index bed9c590be..0a4303baf3 100644 --- a/libraries/animation/src/AnimSkeleton.cpp +++ b/libraries/animation/src/AnimSkeleton.cpp @@ -20,11 +20,30 @@ AnimSkeleton::AnimSkeleton(const FBXGeometry& fbxGeometry) { // convert to std::vector of joints std::vector joints; joints.reserve(fbxGeometry.joints.size()); + AnimPose identity; for (auto& joint : fbxGeometry.joints) { joints.push_back(joint); + _avatarTPoseOffsets.push_back(identity); } buildSkeletonFromJoints(joints); -} + //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("Neck")] = AnimPose(glm::quat(0.0f, 0.707107f, 0.0f, 0.707107f), glm::vec3()); + + for (int i = 0; i < (int)fbxGeometry.meshes.size(); i++) { + const FBXMesh& mesh = fbxGeometry.meshes.at(i); + for (int j = 0; j < mesh.clusters.size(); j++) { + // cast into a non-const reference, so we can mutate the FBXCluster + FBXCluster& cluster = const_cast(mesh.clusters.at(j)); + // AJT: mutate bind pose! this allows us to oreint the skeleton back into the authored orientaiton before + // rendering, with no runtime overhead. + // this works if clusters match joints one for one. + //cluster.inverseBindMatrix = (glm::mat4)_avatarTPoseOffsets[cluster.jointIndex].inverse() * cluster.inverseBindMatrix; + cluster.inverseBindTransform.evalFromRawMatrix(cluster.inverseBindMatrix); + + } + } +} AnimSkeleton::AnimSkeleton(const std::vector& joints) { buildSkeletonFromJoints(joints); @@ -189,8 +208,19 @@ void AnimSkeleton::buildSkeletonFromJoints(const std::vector& joints) // build relative and absolute default poses glm::mat4 relDefaultMat = glm::translate(_joints[i].translation) * preRotationTransform * glm::mat4_cast(_joints[i].rotation) * postRotationTransform; AnimPose relDefaultPose(relDefaultMat); - _relativeDefaultPoses.push_back(relDefaultPose); + int parentIndex = getParentIndex(i); + + // putting the pipeline code is + // 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. + //relDefaultPose = relDefaultPose * _avatarTPoseOffsets[i]; + //if (parentIndex >= 0) { + // relDefaultPose = _avatarTPoseOffsets[parentIndex].inverse() * AnimPose(glm::quat(), relDefaultPose.trans()) * _avatarTPoseOffsets[parentIndex] * AnimPose(relDefaultPose.rot(), glm::vec3()); + //} + + _relativeDefaultPoses.push_back(relDefaultPose); + if (parentIndex >= 0) { _absoluteDefaultPoses.push_back(_absoluteDefaultPoses[parentIndex] * relDefaultPose); } else { diff --git a/libraries/animation/src/AnimSkeleton.h b/libraries/animation/src/AnimSkeleton.h index 2ebf3f4f5d..ad1120fcbf 100644 --- a/libraries/animation/src/AnimSkeleton.h +++ b/libraries/animation/src/AnimSkeleton.h @@ -67,6 +67,7 @@ protected: void buildSkeletonFromJoints(const std::vector& joints); std::vector _joints; + AnimPoseVec _avatarTPoseOffsets; int _jointsSize { 0 }; AnimPoseVec _relativeDefaultPoses; AnimPoseVec _absoluteDefaultPoses; From e24f10a125e9a6ffba69b7c959b4ec665653e4c7 Mon Sep 17 00:00:00 2001 From: amantley Date: Tue, 30 Oct 2018 17:33:28 -0700 Subject: [PATCH 02/32] debugging offset vector --- libraries/animation/src/AnimSkeleton.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libraries/animation/src/AnimSkeleton.cpp b/libraries/animation/src/AnimSkeleton.cpp index 0a4303baf3..bd8d62bdb4 100644 --- a/libraries/animation/src/AnimSkeleton.cpp +++ b/libraries/animation/src/AnimSkeleton.cpp @@ -20,12 +20,14 @@ AnimSkeleton::AnimSkeleton(const FBXGeometry& fbxGeometry) { // convert to std::vector of joints std::vector joints; joints.reserve(fbxGeometry.joints.size()); - AnimPose identity; + _avatarTPoseOffsets.reserve(fbxGeometry.joints.size()); + AnimPose identity(glm::quat(), glm::vec3()); for (auto& joint : fbxGeometry.joints) { joints.push_back(joint); _avatarTPoseOffsets.push_back(identity); } buildSkeletonFromJoints(joints); + /* //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("Neck")] = AnimPose(glm::quat(0.0f, 0.707107f, 0.0f, 0.707107f), glm::vec3()); @@ -43,6 +45,7 @@ AnimSkeleton::AnimSkeleton(const FBXGeometry& fbxGeometry) { } } + */ } AnimSkeleton::AnimSkeleton(const std::vector& joints) { From c070bce2ec6cb257cc0f400fc7cea909b3663cd3 Mon Sep 17 00:00:00 2001 From: luiscuenca Date: Wed, 31 Oct 2018 08:39:35 -0700 Subject: [PATCH 03/32] Read joint rotation offsets from .fst --- libraries/animation/src/Rig.cpp | 13 ++++++++++ libraries/animation/src/Rig.h | 4 ++++ .../src/avatars-renderer/SkeletonModel.cpp | 3 ++- libraries/fbx/src/FSTReader.cpp | 24 +++++++++++++++++++ libraries/fbx/src/FSTReader.h | 3 +++ 5 files changed, 46 insertions(+), 1 deletion(-) diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index 33b9569758..c58a96aa84 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -2062,3 +2062,16 @@ void Rig::computeAvatarBoundingCapsule( glm::vec3 capsuleCenter = transformPoint(_geometryToRigTransform, (0.5f * (totalExtents.maximum + totalExtents.minimum))); localOffsetOut = capsuleCenter - hipsPosition; } + +void Rig::setJointRotationOffsets(const QMap& offsets) { + _jointRotationOffsets.clear(); + for (auto itr = offsets.begin(); itr != offsets.end(); itr++) { + QString jointName = itr.key(); + glm::quat rotationOffset = itr.value(); + int jointIndex = indexOfJoint(jointName); + if (jointIndex != -1) { + _jointRotationOffsets.insert(jointIndex, rotationOffset); + } + qDebug() << "Joint Rotation Offset added to Rig._jointRotationOffsets : " << " jointName: " << jointName << " jointIndex: " << jointIndex << " rotation offset: " << rotationOffset; + } +} \ No newline at end of file diff --git a/libraries/animation/src/Rig.h b/libraries/animation/src/Rig.h index 7a090bd7bd..9928810026 100644 --- a/libraries/animation/src/Rig.h +++ b/libraries/animation/src/Rig.h @@ -231,6 +231,8 @@ public: const AnimContext::DebugAlphaMap& getDebugAlphaMap() const { return _lastContext.getDebugAlphaMap(); } const AnimVariantMap& getAnimVars() const { return _lastAnimVars; } const AnimContext::DebugStateMachineMap& getStateMachineMap() const { return _lastContext.getStateMachineMap(); } + + void setJointRotationOffsets(const QMap& offsets); signals: void onLoadComplete(); @@ -300,6 +302,8 @@ protected: int _rightElbowJointIndex { -1 }; int _rightShoulderJointIndex { -1 }; + QMap _jointRotationOffsets; + glm::vec3 _lastForward; glm::vec3 _lastPosition; glm::vec3 _lastVelocity; diff --git a/libraries/avatars-renderer/src/avatars-renderer/SkeletonModel.cpp b/libraries/avatars-renderer/src/avatars-renderer/SkeletonModel.cpp index 1ec58fd704..816e078886 100644 --- a/libraries/avatars-renderer/src/avatars-renderer/SkeletonModel.cpp +++ b/libraries/avatars-renderer/src/avatars-renderer/SkeletonModel.cpp @@ -18,6 +18,7 @@ #include #include #include +#include #include "Avatar.h" #include "Logging.h" @@ -82,7 +83,7 @@ void SkeletonModel::initJointStates() { // Skeleton may have already been scaled so unscale it _defaultEyeModelPosition = _defaultEyeModelPosition / _scale; - + _rig.setJointRotationOffsets(FSTReader::getJointRotationOffsets(getGeometry()->getMapping())); computeBoundingShape(); Extents meshExtents = getMeshExtents(); diff --git a/libraries/fbx/src/FSTReader.cpp b/libraries/fbx/src/FSTReader.cpp index 75596862d2..10ea9dc964 100644 --- a/libraries/fbx/src/FSTReader.cpp +++ b/libraries/fbx/src/FSTReader.cpp @@ -207,6 +207,30 @@ QVector FSTReader::getScripts(const QUrl& url, const QVariantHash& mapp return scriptPaths; } +QMap FSTReader::getJointRotationOffsets(const QVariantHash& mapping) { + QMap jointRotationOffsets; + if (!mapping.isEmpty() && mapping.contains(JOINT_ROTATION_OFFSET_FIELD) && mapping[JOINT_ROTATION_OFFSET_FIELD].type() == QVariant::Hash) { + auto offsets = mapping[JOINT_ROTATION_OFFSET_FIELD].toHash(); + for (auto itr = offsets.begin(); itr != offsets.end(); itr++) { + QString jointName = itr.key(); + QString line = itr.value().toString(); + auto eulerAngles = line.split(','); + if (eulerAngles.size() == 3) { + float eulerX = eulerAngles[0].mid(1).toFloat(); + float eulerY = eulerAngles[1].toFloat(); + float eulerZ = eulerAngles[2].mid(0, eulerAngles[2].size() - 1).toFloat(); + if (!isNaN(eulerX) && !isNaN(eulerY) && !isNaN(eulerZ)) { + glm::quat rotationOffset = (glm::angleAxis(eulerX * RADIANS_PER_DEGREE, Vectors::UNIT_Y) * + glm::angleAxis(eulerY * RADIANS_PER_DEGREE, Vectors::UNIT_X) * + glm::angleAxis(eulerZ * RADIANS_PER_DEGREE, Vectors::UNIT_Z)); + jointRotationOffsets.insert(jointName, rotationOffset); + } + } + } + } + return jointRotationOffsets; +} + QVariantHash FSTReader::downloadMapping(const QString& url) { QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance(); QNetworkRequest networkRequest = QNetworkRequest(url); diff --git a/libraries/fbx/src/FSTReader.h b/libraries/fbx/src/FSTReader.h index 4a8574f0cf..ef649eb4d8 100644 --- a/libraries/fbx/src/FSTReader.h +++ b/libraries/fbx/src/FSTReader.h @@ -14,6 +14,7 @@ #include #include +#include static const QString NAME_FIELD = "name"; static const QString TYPE_FIELD = "type"; @@ -29,6 +30,7 @@ static const QString JOINT_FIELD = "joint"; static const QString FREE_JOINT_FIELD = "freeJoint"; static const QString BLENDSHAPE_FIELD = "bs"; static const QString SCRIPT_FIELD = "script"; +static const QString JOINT_ROTATION_OFFSET_FIELD = "jointRotationOffset"; class FSTReader { public: @@ -51,6 +53,7 @@ public: static ModelType predictModelType(const QVariantHash& mapping); static QVector getScripts(const QUrl& fstUrl, const QVariantHash& mapping = QVariantHash()); + static QMap getJointRotationOffsets(const QVariantHash& mapping); static QString getNameFromType(ModelType modelType); static FSTReader::ModelType getTypeFromName(const QString& name); From 914491ae27e27ee0998a49967352bc3a776aa3c1 Mon Sep 17 00:00:00 2001 From: luiscuenca Date: Wed, 31 Oct 2018 11:48:55 -0700 Subject: [PATCH 04/32] fix YX coord swamp --- libraries/fbx/src/FSTReader.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/fbx/src/FSTReader.cpp b/libraries/fbx/src/FSTReader.cpp index 10ea9dc964..05690f5740 100644 --- a/libraries/fbx/src/FSTReader.cpp +++ b/libraries/fbx/src/FSTReader.cpp @@ -220,8 +220,8 @@ QMap FSTReader::getJointRotationOffsets(const QVariantHash& float eulerY = eulerAngles[1].toFloat(); float eulerZ = eulerAngles[2].mid(0, eulerAngles[2].size() - 1).toFloat(); if (!isNaN(eulerX) && !isNaN(eulerY) && !isNaN(eulerZ)) { - glm::quat rotationOffset = (glm::angleAxis(eulerX * RADIANS_PER_DEGREE, Vectors::UNIT_Y) * - glm::angleAxis(eulerY * RADIANS_PER_DEGREE, Vectors::UNIT_X) * + glm::quat rotationOffset = (glm::angleAxis(eulerX * RADIANS_PER_DEGREE, Vectors::UNIT_X) * + glm::angleAxis(eulerY * RADIANS_PER_DEGREE, Vectors::UNIT_Y) * glm::angleAxis(eulerZ * RADIANS_PER_DEGREE, Vectors::UNIT_Z)); jointRotationOffsets.insert(jointName, rotationOffset); } From 64d8fa6875ff402bc6a8a7bf8da62680e6d75b79 Mon Sep 17 00:00:00 2001 From: amantley Date: Thu, 1 Nov 2018 13:33:03 -0700 Subject: [PATCH 05/32] added the const argument to the AnimSkeleton constructor that allows the offset rotations to be passed in --- .../src/avatars/ScriptableAvatar.cpp | 3 +- libraries/animation/src/AnimClip.cpp | 3 +- libraries/animation/src/AnimSkeleton.cpp | 43 +++++++++++-------- libraries/animation/src/AnimSkeleton.h | 6 +-- libraries/animation/src/Rig.cpp | 4 +- tools/skeleton-dump/src/SkeletonDumpApp.cpp | 3 +- 6 files changed, 36 insertions(+), 26 deletions(-) diff --git a/assignment-client/src/avatars/ScriptableAvatar.cpp b/assignment-client/src/avatars/ScriptableAvatar.cpp index 7d2b267a05..da151c7a35 100644 --- a/assignment-client/src/avatars/ScriptableAvatar.cpp +++ b/assignment-client/src/avatars/ScriptableAvatar.cpp @@ -84,7 +84,8 @@ void ScriptableAvatar::update(float deltatime) { // Run animation if (_animation && _animation->isLoaded() && _animation->getFrames().size() > 0 && !_bind.isNull() && _bind->isLoaded()) { if (!_animSkeleton) { - _animSkeleton = std::make_shared(_bind->getGeometry()); + QMap jointRotationOffsets; + _animSkeleton = std::make_shared(_bind->getGeometry(), jointRotationOffsets); } float currentFrame = _animationDetails.currentFrame + deltatime * _animationDetails.fps; if (_animationDetails.loop || currentFrame < _animationDetails.lastFrame) { diff --git a/libraries/animation/src/AnimClip.cpp b/libraries/animation/src/AnimClip.cpp index f9195a608b..ffbbf1b0f4 100644 --- a/libraries/animation/src/AnimClip.cpp +++ b/libraries/animation/src/AnimClip.cpp @@ -102,7 +102,8 @@ 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(); - AnimSkeleton animSkeleton(geom); + QMap jointRotationOffsets; + AnimSkeleton animSkeleton(geom, jointRotationOffsets); const auto animJointCount = animSkeleton.getNumJoints(); const auto skeletonJointCount = _skeleton->getNumJoints(); std::vector jointMap; diff --git a/libraries/animation/src/AnimSkeleton.cpp b/libraries/animation/src/AnimSkeleton.cpp index bd8d62bdb4..23e4b7a9d6 100644 --- a/libraries/animation/src/AnimSkeleton.cpp +++ b/libraries/animation/src/AnimSkeleton.cpp @@ -16,21 +16,20 @@ #include "AnimationLogging.h" -AnimSkeleton::AnimSkeleton(const FBXGeometry& fbxGeometry) { +AnimSkeleton::AnimSkeleton(const FBXGeometry& fbxGeometry, const QMap jointOffsets) { // convert to std::vector of joints std::vector joints; joints.reserve(fbxGeometry.joints.size()); - _avatarTPoseOffsets.reserve(fbxGeometry.joints.size()); - AnimPose identity(glm::quat(), glm::vec3()); + //_avatarTPoseOffsets.reserve(_jointsSize); for (auto& joint : fbxGeometry.joints) { 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 - _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()); + + + // 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("Neck")] = AnimPose(glm::quat(0.0f, 0.707107f, 0.0f, 0.707107f), glm::vec3()); for (int i = 0; i < (int)fbxGeometry.meshes.size(); 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 // rendering, with no runtime overhead. // this works if clusters match joints one for one. - //cluster.inverseBindMatrix = (glm::mat4)_avatarTPoseOffsets[cluster.jointIndex].inverse() * cluster.inverseBindMatrix; - cluster.inverseBindTransform.evalFromRawMatrix(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); + } } } - */ + buildSkeletonFromJoints(joints, jointOffsets); } -AnimSkeleton::AnimSkeleton(const std::vector& joints) { - buildSkeletonFromJoints(joints); +AnimSkeleton::AnimSkeleton(const std::vector& joints, const QMap jointOffsets) { + buildSkeletonFromJoints(joints, jointOffsets); } int AnimSkeleton::nameToJointIndex(const QString& jointName) const { @@ -188,7 +190,7 @@ void AnimSkeleton::mirrorAbsolutePoses(AnimPoseVec& poses) const { } } -void AnimSkeleton::buildSkeletonFromJoints(const std::vector& joints) { +void AnimSkeleton::buildSkeletonFromJoints(const std::vector& joints, const QMap jointOffsets) { _joints = joints; _jointsSize = (int)joints.size(); // build a cache of bind poses @@ -218,9 +220,14 @@ void AnimSkeleton::buildSkeletonFromJoints(const std::vector& joints) // 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. //relDefaultPose = relDefaultPose * _avatarTPoseOffsets[i]; - //if (parentIndex >= 0) { - // relDefaultPose = _avatarTPoseOffsets[parentIndex].inverse() * AnimPose(glm::quat(), relDefaultPose.trans()) * _avatarTPoseOffsets[parentIndex] * AnimPose(relDefaultPose.rot(), glm::vec3()); - //} + if (jointOffsets.contains(i)) { + 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); diff --git a/libraries/animation/src/AnimSkeleton.h b/libraries/animation/src/AnimSkeleton.h index ad1120fcbf..0a5b177b63 100644 --- a/libraries/animation/src/AnimSkeleton.h +++ b/libraries/animation/src/AnimSkeleton.h @@ -23,8 +23,8 @@ public: using Pointer = std::shared_ptr; using ConstPointer = std::shared_ptr; - explicit AnimSkeleton(const FBXGeometry& fbxGeometry); - explicit AnimSkeleton(const std::vector& joints); + explicit AnimSkeleton(const FBXGeometry& fbxGeometry, const QMap jointOffsets); + explicit AnimSkeleton(const std::vector& joints, const QMap jointOffsets); int nameToJointIndex(const QString& jointName) const; const QString& getJointName(int jointIndex) const; int getNumJoints() const; @@ -64,7 +64,7 @@ public: std::vector lookUpJointIndices(const std::vector& jointNames) const; protected: - void buildSkeletonFromJoints(const std::vector& joints); + void buildSkeletonFromJoints(const std::vector& joints, const QMap jointOffsets); std::vector _joints; AnimPoseVec _avatarTPoseOffsets; diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index c58a96aa84..c7e5226c7b 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -267,7 +267,7 @@ void Rig::initJointStates(const FBXGeometry& geometry, const glm::mat4& modelOff _rigToGeometryTransform = glm::inverse(_geometryToRigTransform); setModelOffset(modelOffset); - _animSkeleton = std::make_shared(geometry); + _animSkeleton = std::make_shared(geometry,_jointRotationOffsets); _internalPoseSet._relativePoses.clear(); _internalPoseSet._relativePoses = _animSkeleton->getRelativeDefaultPoses(); @@ -310,7 +310,7 @@ void Rig::initJointStates(const FBXGeometry& geometry, const glm::mat4& modelOff void Rig::reset(const FBXGeometry& geometry) { _geometryOffset = AnimPose(geometry.offset); _invGeometryOffset = _geometryOffset.inverse(); - _animSkeleton = std::make_shared(geometry); + _animSkeleton = std::make_shared(geometry, _jointRotationOffsets); _internalPoseSet._relativePoses.clear(); _internalPoseSet._relativePoses = _animSkeleton->getRelativeDefaultPoses(); diff --git a/tools/skeleton-dump/src/SkeletonDumpApp.cpp b/tools/skeleton-dump/src/SkeletonDumpApp.cpp index e9d8243e38..cb623fd53e 100644 --- a/tools/skeleton-dump/src/SkeletonDumpApp.cpp +++ b/tools/skeleton-dump/src/SkeletonDumpApp.cpp @@ -55,7 +55,8 @@ SkeletonDumpApp::SkeletonDumpApp(int argc, char* argv[]) : QCoreApplication(argc } QByteArray blob = file.readAll(); std::unique_ptr fbxGeometry(readFBX(blob, QVariantHash())); - std::unique_ptr skeleton(new AnimSkeleton(*fbxGeometry)); + QMap jointRotationOffsets; + std::unique_ptr skeleton(new AnimSkeleton(*fbxGeometry, jointRotationOffsets)); skeleton->dump(verbose); } From 5392d21b1c9def68a0de2f52029276e8239b3b1b Mon Sep 17 00:00:00 2001 From: amantley Date: Fri, 2 Nov 2018 17:59:18 -0700 Subject: [PATCH 06/32] loading test file to check rotation offsets --- libraries/animation/src/AnimSkeleton.cpp | 7 +++++++ libraries/animation/src/Rig.cpp | 9 +++++++++ 2 files changed, 16 insertions(+) diff --git a/libraries/animation/src/AnimSkeleton.cpp b/libraries/animation/src/AnimSkeleton.cpp index 23e4b7a9d6..ab914b1da3 100644 --- a/libraries/animation/src/AnimSkeleton.cpp +++ b/libraries/animation/src/AnimSkeleton.cpp @@ -17,6 +17,8 @@ #include "AnimationLogging.h" AnimSkeleton::AnimSkeleton(const FBXGeometry& fbxGeometry, const QMap jointOffsets) { + + qCDebug(animation) << "in the animSkeleton"; // convert to std::vector of joints std::vector joints; joints.reserve(fbxGeometry.joints.size()); @@ -34,12 +36,17 @@ AnimSkeleton::AnimSkeleton(const FBXGeometry& fbxGeometry, const QMap(mesh.clusters.at(j)); + if ((cluster.jointIndex == nameToJointIndex("Neck")) || (cluster.jointIndex == nameToJointIndex("Spine2"))) { + qCDebug(animation) << "found a joint offset to add " << cluster.jointIndex << " " << jointOffsets[j]; + } // AJT: mutate bind pose! this allows us to oreint the skeleton back into the authored orientaiton before // rendering, with no runtime overhead. // this works if clusters match joints one for one. if (jointOffsets.contains(j)) { + qCDebug(animation) << "found a joint offset to add " << j << " " << jointOffsets[j]; AnimPose localOffset(jointOffsets[j], glm::vec3()); cluster.inverseBindMatrix = (glm::mat4)localOffset.inverse() * cluster.inverseBindMatrix; cluster.inverseBindTransform.evalFromRawMatrix(cluster.inverseBindMatrix); diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index c7e5226c7b..f1cb94a99c 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -2074,4 +2074,13 @@ void Rig::setJointRotationOffsets(const QMap& offsets) { } qDebug() << "Joint Rotation Offset added to Rig._jointRotationOffsets : " << " jointName: " << jointName << " jointIndex: " << jointIndex << " rotation offset: " << rotationOffset; } + int neckIndex = indexOfJoint("Neck"); + int spine2Index = indexOfJoint("Spine2"); + if (neckIndex != -1) { + _jointRotationOffsets.insert(neckIndex, glm::quat(0.7071f, 0.0f, 0.7071f, 0.0f)); + } + if (spine2Index != -1) { + _jointRotationOffsets.insert(spine2Index, glm::quat(0.7071f, -0.7071f, 0.0f, 0.0f)); + } + qCDebug(animation) << "set the neck and spine2 offsets"; } \ No newline at end of file From d231a35dfacfccbdcf25cb8050685c7df6064ee6 Mon Sep 17 00:00:00 2001 From: amantley Date: Mon, 5 Nov 2018 08:35:01 -0800 Subject: [PATCH 07/32] changes to get spine2 and neck to work almost there --- libraries/animation/src/AnimSkeleton.cpp | 38 +++++++++++++++---- libraries/animation/src/Rig.cpp | 14 +++---- .../src/avatars-renderer/SkeletonModel.cpp | 3 +- 3 files changed, 40 insertions(+), 15 deletions(-) diff --git a/libraries/animation/src/AnimSkeleton.cpp b/libraries/animation/src/AnimSkeleton.cpp index ab914b1da3..cc4a66027d 100644 --- a/libraries/animation/src/AnimSkeleton.cpp +++ b/libraries/animation/src/AnimSkeleton.cpp @@ -37,17 +37,30 @@ AnimSkeleton::AnimSkeleton(const FBXGeometry& fbxGeometry, const QMap(mesh.clusters.at(j)); - if ((cluster.jointIndex == nameToJointIndex("Neck")) || (cluster.jointIndex == nameToJointIndex("Spine2"))) { - qCDebug(animation) << "found a joint offset to add " << cluster.jointIndex << " " << jointOffsets[j]; + if (jointOffsets.contains(cluster.jointIndex)) { + qCDebug(animation) << "cluster joint equals index " << cluster.jointIndex; + } + + if ((cluster.jointIndex == 62) || (cluster.jointIndex == 13)) { + qCDebug(animation) << "cluster joint equals index " << cluster.jointIndex; } // AJT: mutate bind pose! this allows us to oreint the skeleton back into the authored orientaiton before // rendering, with no runtime overhead. // this works if clusters match joints one for one. - if (jointOffsets.contains(j)) { - qCDebug(animation) << "found a joint offset to add " << j << " " << jointOffsets[j]; - AnimPose localOffset(jointOffsets[j], glm::vec3()); + if (cluster.jointIndex == 62) { + qCDebug(animation) << "Neck"; + qCDebug(animation) << "found a joint offset to add " << cluster.jointIndex << " " << jointOffsets[cluster.jointIndex] << " cluster " << cluster.jointIndex; + AnimPose localOffset(jointOffsets[cluster.jointIndex], glm::vec3()); + cluster.inverseBindMatrix = (glm::mat4)localOffset.inverse() * cluster.inverseBindMatrix; + cluster.inverseBindTransform.evalFromRawMatrix(cluster.inverseBindMatrix); + } + if (cluster.jointIndex == 13) { + qCDebug(animation) << "Spine2"; + qCDebug(animation) << "found a joint offset to add " << cluster.jointIndex << " " << jointOffsets[cluster.jointIndex] << " cluster " << cluster.jointIndex; + AnimPose localOffset(jointOffsets[cluster.jointIndex], glm::vec3()); cluster.inverseBindMatrix = (glm::mat4)localOffset.inverse() * cluster.inverseBindMatrix; cluster.inverseBindTransform.evalFromRawMatrix(cluster.inverseBindMatrix); } @@ -227,14 +240,25 @@ void AnimSkeleton::buildSkeletonFromJoints(const std::vector& joints, // 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. //relDefaultPose = relDefaultPose * _avatarTPoseOffsets[i]; + + QString jointName = getJointName(i); if (jointOffsets.contains(i)) { + //QString parentIndex = getJointName(parentIndex); 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()); + // AnimPose localParentOffset(jointOffsets[parentIndex], glm::vec3()); + // relDefaultPose = localParentOffset.inverse() * AnimPose(glm::quat(), relDefaultPose.trans()) * localParentOffset * AnimPose(relDefaultPose.rot(), glm::vec3()); } } + if ((parentIndex == 13) && jointOffsets.contains(13)) { + AnimPose localParentOffset(jointOffsets[parentIndex], glm::vec3()); + relDefaultPose = localParentOffset.inverse() * AnimPose(glm::quat(), relDefaultPose.trans()) * localParentOffset * AnimPose(relDefaultPose.rot(), glm::vec3()); + } + if ((parentIndex == 62) && jointOffsets.contains(62)) { + AnimPose localParentOffset(glm::quat(0.7071f, 0.0f, -0.7071f, 0.0f), glm::vec3()); + relDefaultPose = localParentOffset.inverse() * AnimPose(glm::quat(), relDefaultPose.trans()) * localParentOffset * AnimPose(relDefaultPose.rot(), glm::vec3()); + } _relativeDefaultPoses.push_back(relDefaultPose); diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index f1cb94a99c..ff9d19c8a2 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -2074,13 +2074,13 @@ void Rig::setJointRotationOffsets(const QMap& offsets) { } qDebug() << "Joint Rotation Offset added to Rig._jointRotationOffsets : " << " jointName: " << jointName << " jointIndex: " << jointIndex << " rotation offset: " << rotationOffset; } - int neckIndex = indexOfJoint("Neck"); - int spine2Index = indexOfJoint("Spine2"); - if (neckIndex != -1) { - _jointRotationOffsets.insert(neckIndex, glm::quat(0.7071f, 0.0f, 0.7071f, 0.0f)); + int neckId = 62; + int spine2Id = 13; + if (true){ //neckIndex != -1) { + _jointRotationOffsets.insert(neckId, glm::quat(0.0f, 0.7071f, 0.7071f, 0.0f)); } - if (spine2Index != -1) { - _jointRotationOffsets.insert(spine2Index, glm::quat(0.7071f, -0.7071f, 0.0f, 0.0f)); + if (true){ //spine2Index != -1) { + _jointRotationOffsets.insert(spine2Id, glm::quat(0.5f, 0.5f, 0.5f, -0.5f)); } - qCDebug(animation) << "set the neck and spine2 offsets"; + qCDebug(animation) << "set the neck and spine2 offsets " << spine2Id << " " << neckId; } \ No newline at end of file diff --git a/libraries/avatars-renderer/src/avatars-renderer/SkeletonModel.cpp b/libraries/avatars-renderer/src/avatars-renderer/SkeletonModel.cpp index 816e078886..c6123ef003 100644 --- a/libraries/avatars-renderer/src/avatars-renderer/SkeletonModel.cpp +++ b/libraries/avatars-renderer/src/avatars-renderer/SkeletonModel.cpp @@ -57,6 +57,7 @@ void SkeletonModel::setTextures(const QVariantMap& textures) { void SkeletonModel::initJointStates() { const FBXGeometry& geometry = getFBXGeometry(); glm::mat4 modelOffset = glm::scale(_scale) * glm::translate(_offset); + _rig.setJointRotationOffsets(FSTReader::getJointRotationOffsets(getGeometry()->getMapping())); _rig.initJointStates(geometry, modelOffset); { @@ -83,7 +84,7 @@ void SkeletonModel::initJointStates() { // Skeleton may have already been scaled so unscale it _defaultEyeModelPosition = _defaultEyeModelPosition / _scale; - _rig.setJointRotationOffsets(FSTReader::getJointRotationOffsets(getGeometry()->getMapping())); + //_rig.setJointRotationOffsets(FSTReader::getJointRotationOffsets(getGeometry()->getMapping())); computeBoundingShape(); Extents meshExtents = getMeshExtents(); From bcde01621d13417baab6a2a173c8977a5b1aef6d Mon Sep 17 00:00:00 2001 From: luiscuenca Date: Mon, 5 Nov 2018 14:25:52 -0700 Subject: [PATCH 08/32] set offsets on FBXGeometry --- libraries/animation/src/Rig.cpp | 13 ------- libraries/animation/src/Rig.h | 4 -- .../src/avatars-renderer/SkeletonModel.cpp | 1 - libraries/fbx/src/FBX.h | 2 + libraries/fbx/src/FBXReader.cpp | 38 +++++++++++++++++++ libraries/fbx/src/FSTReader.cpp | 24 ------------ libraries/fbx/src/FSTReader.h | 2 - 7 files changed, 40 insertions(+), 44 deletions(-) diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index c58a96aa84..33b9569758 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -2062,16 +2062,3 @@ void Rig::computeAvatarBoundingCapsule( glm::vec3 capsuleCenter = transformPoint(_geometryToRigTransform, (0.5f * (totalExtents.maximum + totalExtents.minimum))); localOffsetOut = capsuleCenter - hipsPosition; } - -void Rig::setJointRotationOffsets(const QMap& offsets) { - _jointRotationOffsets.clear(); - for (auto itr = offsets.begin(); itr != offsets.end(); itr++) { - QString jointName = itr.key(); - glm::quat rotationOffset = itr.value(); - int jointIndex = indexOfJoint(jointName); - if (jointIndex != -1) { - _jointRotationOffsets.insert(jointIndex, rotationOffset); - } - qDebug() << "Joint Rotation Offset added to Rig._jointRotationOffsets : " << " jointName: " << jointName << " jointIndex: " << jointIndex << " rotation offset: " << rotationOffset; - } -} \ No newline at end of file diff --git a/libraries/animation/src/Rig.h b/libraries/animation/src/Rig.h index 9928810026..7a090bd7bd 100644 --- a/libraries/animation/src/Rig.h +++ b/libraries/animation/src/Rig.h @@ -231,8 +231,6 @@ public: const AnimContext::DebugAlphaMap& getDebugAlphaMap() const { return _lastContext.getDebugAlphaMap(); } const AnimVariantMap& getAnimVars() const { return _lastAnimVars; } const AnimContext::DebugStateMachineMap& getStateMachineMap() const { return _lastContext.getStateMachineMap(); } - - void setJointRotationOffsets(const QMap& offsets); signals: void onLoadComplete(); @@ -302,8 +300,6 @@ protected: int _rightElbowJointIndex { -1 }; int _rightShoulderJointIndex { -1 }; - QMap _jointRotationOffsets; - glm::vec3 _lastForward; glm::vec3 _lastPosition; glm::vec3 _lastVelocity; diff --git a/libraries/avatars-renderer/src/avatars-renderer/SkeletonModel.cpp b/libraries/avatars-renderer/src/avatars-renderer/SkeletonModel.cpp index 816e078886..bf6af763a3 100644 --- a/libraries/avatars-renderer/src/avatars-renderer/SkeletonModel.cpp +++ b/libraries/avatars-renderer/src/avatars-renderer/SkeletonModel.cpp @@ -83,7 +83,6 @@ void SkeletonModel::initJointStates() { // Skeleton may have already been scaled so unscale it _defaultEyeModelPosition = _defaultEyeModelPosition / _scale; - _rig.setJointRotationOffsets(FSTReader::getJointRotationOffsets(getGeometry()->getMapping())); computeBoundingShape(); Extents meshExtents = getMeshExtents(); diff --git a/libraries/fbx/src/FBX.h b/libraries/fbx/src/FBX.h index fdebb16bc8..ec3a29e7f5 100644 --- a/libraries/fbx/src/FBX.h +++ b/libraries/fbx/src/FBX.h @@ -366,6 +366,8 @@ public: QString getModelNameOfMesh(int meshIndex) const; QList blendshapeChannelNames; + + QMap jointRotationOffsets; }; Q_DECLARE_METATYPE(FBXGeometry) diff --git a/libraries/fbx/src/FBXReader.cpp b/libraries/fbx/src/FBXReader.cpp index dd766f002c..44976adfa8 100644 --- a/libraries/fbx/src/FBXReader.cpp +++ b/libraries/fbx/src/FBXReader.cpp @@ -615,6 +615,31 @@ QByteArray fileOnUrl(const QByteArray& filepath, const QString& url) { return filepath.mid(filepath.lastIndexOf('/') + 1); } +QMap getJointRotationOffsets(const QVariantHash& mapping) { + QMap jointRotationOffsets; + static const QString JOINT_ROTATION_OFFSET_FIELD = "jointRotationOffset"; + if (!mapping.isEmpty() && mapping.contains(JOINT_ROTATION_OFFSET_FIELD) && mapping[JOINT_ROTATION_OFFSET_FIELD].type() == QVariant::Hash) { + auto offsets = mapping[JOINT_ROTATION_OFFSET_FIELD].toHash(); + for (auto itr = offsets.begin(); itr != offsets.end(); itr++) { + QString jointName = itr.key(); + QString line = itr.value().toString(); + auto eulerAngles = line.split(','); + if (eulerAngles.size() == 3) { + float eulerX = eulerAngles[0].mid(1).toFloat(); + float eulerY = eulerAngles[1].toFloat(); + float eulerZ = eulerAngles[2].mid(0, eulerAngles[2].size() - 1).toFloat(); + if (!isNaN(eulerX) && !isNaN(eulerY) && !isNaN(eulerZ)) { + glm::quat rotationOffset = (glm::angleAxis(eulerX * RADIANS_PER_DEGREE, Vectors::UNIT_X) * + glm::angleAxis(eulerY * RADIANS_PER_DEGREE, Vectors::UNIT_Y) * + glm::angleAxis(eulerZ * RADIANS_PER_DEGREE, Vectors::UNIT_Z)); + jointRotationOffsets.insert(jointName, rotationOffset); + } + } + } + } + return jointRotationOffsets; +} + FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QString& url) { const FBXNode& node = _rootNode; QMap meshes; @@ -1991,6 +2016,19 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS } } } + + auto offsets = getJointRotationOffsets(mapping); + geometry.jointRotationOffsets.clear(); + for (auto itr = offsets.begin(); itr != offsets.end(); itr++) { + QString jointName = itr.key(); + glm::quat rotationOffset = itr.value(); + int jointIndex = geometry.getJointIndex(jointName); + if (jointIndex != -1) { + geometry.jointRotationOffsets.insert(jointIndex, rotationOffset); + } + qCDebug(modelformat) << "Joint Rotation Offset added to Rig._jointRotationOffsets : " << " jointName: " << jointName << " jointIndex: " << jointIndex << " rotation offset: " << rotationOffset; + } + return geometryPtr; } diff --git a/libraries/fbx/src/FSTReader.cpp b/libraries/fbx/src/FSTReader.cpp index 05690f5740..75596862d2 100644 --- a/libraries/fbx/src/FSTReader.cpp +++ b/libraries/fbx/src/FSTReader.cpp @@ -207,30 +207,6 @@ QVector FSTReader::getScripts(const QUrl& url, const QVariantHash& mapp return scriptPaths; } -QMap FSTReader::getJointRotationOffsets(const QVariantHash& mapping) { - QMap jointRotationOffsets; - if (!mapping.isEmpty() && mapping.contains(JOINT_ROTATION_OFFSET_FIELD) && mapping[JOINT_ROTATION_OFFSET_FIELD].type() == QVariant::Hash) { - auto offsets = mapping[JOINT_ROTATION_OFFSET_FIELD].toHash(); - for (auto itr = offsets.begin(); itr != offsets.end(); itr++) { - QString jointName = itr.key(); - QString line = itr.value().toString(); - auto eulerAngles = line.split(','); - if (eulerAngles.size() == 3) { - float eulerX = eulerAngles[0].mid(1).toFloat(); - float eulerY = eulerAngles[1].toFloat(); - float eulerZ = eulerAngles[2].mid(0, eulerAngles[2].size() - 1).toFloat(); - if (!isNaN(eulerX) && !isNaN(eulerY) && !isNaN(eulerZ)) { - glm::quat rotationOffset = (glm::angleAxis(eulerX * RADIANS_PER_DEGREE, Vectors::UNIT_X) * - glm::angleAxis(eulerY * RADIANS_PER_DEGREE, Vectors::UNIT_Y) * - glm::angleAxis(eulerZ * RADIANS_PER_DEGREE, Vectors::UNIT_Z)); - jointRotationOffsets.insert(jointName, rotationOffset); - } - } - } - } - return jointRotationOffsets; -} - QVariantHash FSTReader::downloadMapping(const QString& url) { QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance(); QNetworkRequest networkRequest = QNetworkRequest(url); diff --git a/libraries/fbx/src/FSTReader.h b/libraries/fbx/src/FSTReader.h index ef649eb4d8..3729cbaf16 100644 --- a/libraries/fbx/src/FSTReader.h +++ b/libraries/fbx/src/FSTReader.h @@ -30,7 +30,6 @@ static const QString JOINT_FIELD = "joint"; static const QString FREE_JOINT_FIELD = "freeJoint"; static const QString BLENDSHAPE_FIELD = "bs"; static const QString SCRIPT_FIELD = "script"; -static const QString JOINT_ROTATION_OFFSET_FIELD = "jointRotationOffset"; class FSTReader { public: @@ -53,7 +52,6 @@ public: static ModelType predictModelType(const QVariantHash& mapping); static QVector getScripts(const QUrl& fstUrl, const QVariantHash& mapping = QVariantHash()); - static QMap getJointRotationOffsets(const QVariantHash& mapping); static QString getNameFromType(ModelType modelType); static FSTReader::ModelType getTypeFromName(const QString& name); From 8310dd0cbac7203e15e39af8888b3dcc3f03fb0c Mon Sep 17 00:00:00 2001 From: luiscuenca Date: Mon, 5 Nov 2018 15:10:09 -0700 Subject: [PATCH 09/32] Delete leftovers --- .../avatars-renderer/src/avatars-renderer/SkeletonModel.cpp | 2 +- libraries/fbx/src/FSTReader.h | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/libraries/avatars-renderer/src/avatars-renderer/SkeletonModel.cpp b/libraries/avatars-renderer/src/avatars-renderer/SkeletonModel.cpp index bf6af763a3..fce33d38c1 100644 --- a/libraries/avatars-renderer/src/avatars-renderer/SkeletonModel.cpp +++ b/libraries/avatars-renderer/src/avatars-renderer/SkeletonModel.cpp @@ -18,7 +18,6 @@ #include #include #include -#include #include "Avatar.h" #include "Logging.h" @@ -83,6 +82,7 @@ void SkeletonModel::initJointStates() { // Skeleton may have already been scaled so unscale it _defaultEyeModelPosition = _defaultEyeModelPosition / _scale; + computeBoundingShape(); Extents meshExtents = getMeshExtents(); diff --git a/libraries/fbx/src/FSTReader.h b/libraries/fbx/src/FSTReader.h index 3729cbaf16..4a8574f0cf 100644 --- a/libraries/fbx/src/FSTReader.h +++ b/libraries/fbx/src/FSTReader.h @@ -14,7 +14,6 @@ #include #include -#include static const QString NAME_FIELD = "name"; static const QString TYPE_FIELD = "type"; From 484eb8ba09f2c42035623f012f5c1051f97a56d2 Mon Sep 17 00:00:00 2001 From: amantley Date: Mon, 5 Nov 2018 14:56:58 -0800 Subject: [PATCH 10/32] debugging unity offsets --- libraries/animation/src/AnimSkeleton.cpp | 32 ++++++++++++++++++------ 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/libraries/animation/src/AnimSkeleton.cpp b/libraries/animation/src/AnimSkeleton.cpp index cc4a66027d..39ab5a178e 100644 --- a/libraries/animation/src/AnimSkeleton.cpp +++ b/libraries/animation/src/AnimSkeleton.cpp @@ -28,11 +28,11 @@ AnimSkeleton::AnimSkeleton(const FBXGeometry& fbxGeometry, const QMap& joints, const QMap jointOffsets) { @@ -240,7 +248,7 @@ void AnimSkeleton::buildSkeletonFromJoints(const std::vector& joints, // 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. //relDefaultPose = relDefaultPose * _avatarTPoseOffsets[i]; - + /* QString jointName = getJointName(i); if (jointOffsets.contains(i)) { //QString parentIndex = getJointName(parentIndex); @@ -252,13 +260,23 @@ void AnimSkeleton::buildSkeletonFromJoints(const std::vector& joints, } } if ((parentIndex == 13) && jointOffsets.contains(13)) { + if (i == 62) { + qCDebug(animation) << "the neck translation is " << relDefaultPose.trans(); + } AnimPose localParentOffset(jointOffsets[parentIndex], glm::vec3()); - relDefaultPose = localParentOffset.inverse() * AnimPose(glm::quat(), relDefaultPose.trans()) * localParentOffset * AnimPose(relDefaultPose.rot(), glm::vec3()); + //relDefaultPose = localParentOffset.inverse() * AnimPose(glm::quat(), relDefaultPose.trans()) * localParentOffset * AnimPose(relDefaultPose.rot(), glm::vec3()); + if (i == 62) { + qCDebug(animation) << "the neck translation redo is " << relDefaultPose.trans(); + } } if ((parentIndex == 62) && jointOffsets.contains(62)) { - AnimPose localParentOffset(glm::quat(0.7071f, 0.0f, -0.7071f, 0.0f), glm::vec3()); - relDefaultPose = localParentOffset.inverse() * AnimPose(glm::quat(), relDefaultPose.trans()) * localParentOffset * AnimPose(relDefaultPose.rot(), glm::vec3()); + qCDebug(animation) << "the head translation is " << relDefaultPose.trans(); + //AnimPose localOffset(glm::quat(0.7071f, 0.0f, 0.7071f, 0.0f), glm::vec3()); + //relDefaultPose = relDefaultPose * localOffset; + //AnimPose localParentOffset(glm::quat(0.7071f, 0.0f, -0.7071f, 0.0f), glm::vec3()); + //relDefaultPose = localParentOffset.inverse() * AnimPose(glm::quat(), relDefaultPose.trans()) * localParentOffset * AnimPose(relDefaultPose.rot(), glm::vec3()); } + */ _relativeDefaultPoses.push_back(relDefaultPose); From f0c02bb49bbdb44b04f4c27226deb56147280829 Mon Sep 17 00:00:00 2001 From: amantley Date: Mon, 5 Nov 2018 17:36:54 -0800 Subject: [PATCH 11/32] more debug --- libraries/animation/src/AnimSkeleton.cpp | 25 ++++++++++++------------ libraries/animation/src/Rig.cpp | 2 +- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/libraries/animation/src/AnimSkeleton.cpp b/libraries/animation/src/AnimSkeleton.cpp index 39ab5a178e..49ffe75ba0 100644 --- a/libraries/animation/src/AnimSkeleton.cpp +++ b/libraries/animation/src/AnimSkeleton.cpp @@ -32,7 +32,7 @@ AnimSkeleton::AnimSkeleton(const FBXGeometry& fbxGeometry, const QMap(mesh.clusters.at(j)); - if (jointOffsets.contains(cluster.jointIndex)) { - qCDebug(animation) << "cluster joint equals index " << cluster.jointIndex; - } if ((cluster.jointIndex == 62) || (cluster.jointIndex == 13)) { qCDebug(animation) << "cluster joint equals index " << cluster.jointIndex; @@ -51,8 +48,8 @@ AnimSkeleton::AnimSkeleton(const FBXGeometry& fbxGeometry, const QMap& joints, // build relative and absolute default poses glm::mat4 relDefaultMat = glm::translate(_joints[i].translation) * preRotationTransform * glm::mat4_cast(_joints[i].rotation) * postRotationTransform; AnimPose relDefaultPose(relDefaultMat); + qCDebug(animation) << "relative default pose for joint " << i << " " << relDefaultPose.trans() << " " << relDefaultPose.rot(); int parentIndex = getParentIndex(i); @@ -248,7 +246,7 @@ void AnimSkeleton::buildSkeletonFromJoints(const std::vector& joints, // 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. //relDefaultPose = relDefaultPose * _avatarTPoseOffsets[i]; - /* + QString jointName = getJointName(i); if (jointOffsets.contains(i)) { //QString parentIndex = getJointName(parentIndex); @@ -264,19 +262,20 @@ void AnimSkeleton::buildSkeletonFromJoints(const std::vector& joints, qCDebug(animation) << "the neck translation is " << relDefaultPose.trans(); } AnimPose localParentOffset(jointOffsets[parentIndex], glm::vec3()); - //relDefaultPose = localParentOffset.inverse() * AnimPose(glm::quat(), relDefaultPose.trans()) * localParentOffset * AnimPose(relDefaultPose.rot(), glm::vec3()); + relDefaultPose = localParentOffset.inverse() * AnimPose(glm::quat(), relDefaultPose.trans()) * localParentOffset * AnimPose(relDefaultPose.rot(), glm::vec3()); if (i == 62) { qCDebug(animation) << "the neck translation redo is " << relDefaultPose.trans(); } } if ((parentIndex == 62) && jointOffsets.contains(62)) { - qCDebug(animation) << "the head translation is " << relDefaultPose.trans(); + //AnimPose localOffset(glm::quat(0.7071f, 0.0f, 0.7071f, 0.0f), glm::vec3()); //relDefaultPose = relDefaultPose * localOffset; - //AnimPose localParentOffset(glm::quat(0.7071f, 0.0f, -0.7071f, 0.0f), glm::vec3()); - //relDefaultPose = localParentOffset.inverse() * AnimPose(glm::quat(), relDefaultPose.trans()) * localParentOffset * AnimPose(relDefaultPose.rot(), glm::vec3()); + AnimPose localParentOffset(glm::quat(0.7071f, 0.0f, -0.7071f, 0.0f), glm::vec3()); + relDefaultPose = localParentOffset.inverse() * AnimPose(glm::quat(), relDefaultPose.trans()) * localParentOffset * AnimPose(relDefaultPose.rot(), glm::vec3()); + qCDebug(animation) << "the head translation is " << relDefaultPose.trans(); } - */ + _relativeDefaultPoses.push_back(relDefaultPose); diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index ff9d19c8a2..3302760f6b 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -2077,7 +2077,7 @@ void Rig::setJointRotationOffsets(const QMap& offsets) { int neckId = 62; int spine2Id = 13; if (true){ //neckIndex != -1) { - _jointRotationOffsets.insert(neckId, glm::quat(0.0f, 0.7071f, 0.7071f, 0.0f)); + _jointRotationOffsets.insert(neckId, glm::quat(0.7071f, 0.0f, -0.7071f, 0.0f)); } if (true){ //spine2Index != -1) { _jointRotationOffsets.insert(spine2Id, glm::quat(0.5f, 0.5f, 0.5f, -0.5f)); From 599b7761b2a7d44b848215a0bb001ac4d21e08bd Mon Sep 17 00:00:00 2001 From: luiscuenca Date: Tue, 6 Nov 2018 11:09:56 -0700 Subject: [PATCH 12/32] Read quats from fst --- libraries/fbx/src/FBXReader.cpp | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/libraries/fbx/src/FBXReader.cpp b/libraries/fbx/src/FBXReader.cpp index 44976adfa8..c8dc78bd91 100644 --- a/libraries/fbx/src/FBXReader.cpp +++ b/libraries/fbx/src/FBXReader.cpp @@ -623,15 +623,14 @@ QMap getJointRotationOffsets(const QVariantHash& mapping) { for (auto itr = offsets.begin(); itr != offsets.end(); itr++) { QString jointName = itr.key(); QString line = itr.value().toString(); - auto eulerAngles = line.split(','); - if (eulerAngles.size() == 3) { - float eulerX = eulerAngles[0].mid(1).toFloat(); - float eulerY = eulerAngles[1].toFloat(); - float eulerZ = eulerAngles[2].mid(0, eulerAngles[2].size() - 1).toFloat(); - if (!isNaN(eulerX) && !isNaN(eulerY) && !isNaN(eulerZ)) { - glm::quat rotationOffset = (glm::angleAxis(eulerX * RADIANS_PER_DEGREE, Vectors::UNIT_X) * - glm::angleAxis(eulerY * RADIANS_PER_DEGREE, Vectors::UNIT_Y) * - glm::angleAxis(eulerZ * RADIANS_PER_DEGREE, Vectors::UNIT_Z)); + auto quatCoords = line.split(','); + if (quatCoords.size() == 4) { + float quatX = quatCoords[0].mid(1).toFloat(); + float quatY = quatCoords[1].toFloat(); + float quatZ = quatCoords[2].toFloat(); + float quatW = quatCoords[3].mid(0, quatCoords[3].size() - 1).toFloat(); + if (!isNaN(quatX) && !isNaN(quatY) && !isNaN(quatZ) && !isNaN(quatW)) { + glm::quat rotationOffset = glm::quat(quatW, quatX, quatY, quatZ); jointRotationOffsets.insert(jointName, rotationOffset); } } @@ -2026,7 +2025,7 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS if (jointIndex != -1) { geometry.jointRotationOffsets.insert(jointIndex, rotationOffset); } - qCDebug(modelformat) << "Joint Rotation Offset added to Rig._jointRotationOffsets : " << " jointName: " << jointName << " jointIndex: " << jointIndex << " rotation offset: " << rotationOffset; + qDebug() << "Joint Rotation Offset added to Rig._jointRotationOffsets : " << " jointName: " << jointName << " jointIndex: " << jointIndex << " rotation offset: " << rotationOffset; } return geometryPtr; From e0d1ef3be3128a9433787bb76bc27881c5f4d07f Mon Sep 17 00:00:00 2001 From: luiscuenca Date: Tue, 6 Nov 2018 11:11:16 -0700 Subject: [PATCH 13/32] Fix debug output --- libraries/fbx/src/FBXReader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/fbx/src/FBXReader.cpp b/libraries/fbx/src/FBXReader.cpp index c8dc78bd91..c357d0f430 100644 --- a/libraries/fbx/src/FBXReader.cpp +++ b/libraries/fbx/src/FBXReader.cpp @@ -2025,7 +2025,7 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS if (jointIndex != -1) { geometry.jointRotationOffsets.insert(jointIndex, rotationOffset); } - qDebug() << "Joint Rotation Offset added to Rig._jointRotationOffsets : " << " jointName: " << jointName << " jointIndex: " << jointIndex << " rotation offset: " << rotationOffset; + qCDebug(modelformat) << "Joint Rotation Offset added to Rig._jointRotationOffsets : " << " jointName: " << jointName << " jointIndex: " << jointIndex << " rotation offset: " << rotationOffset; } return geometryPtr; From e52f2ab7d6210ca8be1fdfe65dfb2aa74b5d9128 Mon Sep 17 00:00:00 2001 From: amantley Date: Tue, 6 Nov 2018 14:14:57 -0800 Subject: [PATCH 14/32] works for two joints now --- libraries/animation/src/AnimSkeleton.cpp | 21 +-------------------- libraries/animation/src/Rig.cpp | 3 ++- 2 files changed, 3 insertions(+), 21 deletions(-) diff --git a/libraries/animation/src/AnimSkeleton.cpp b/libraries/animation/src/AnimSkeleton.cpp index 49ffe75ba0..2dfcdee4b0 100644 --- a/libraries/animation/src/AnimSkeleton.cpp +++ b/libraries/animation/src/AnimSkeleton.cpp @@ -252,30 +252,11 @@ void AnimSkeleton::buildSkeletonFromJoints(const std::vector& joints, //QString parentIndex = getJointName(parentIndex); 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()); - } } - if ((parentIndex == 13) && jointOffsets.contains(13)) { - if (i == 62) { - qCDebug(animation) << "the neck translation is " << relDefaultPose.trans(); - } + 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()); - if (i == 62) { - qCDebug(animation) << "the neck translation redo is " << relDefaultPose.trans(); - } } - if ((parentIndex == 62) && jointOffsets.contains(62)) { - - //AnimPose localOffset(glm::quat(0.7071f, 0.0f, 0.7071f, 0.0f), glm::vec3()); - //relDefaultPose = relDefaultPose * localOffset; - AnimPose localParentOffset(glm::quat(0.7071f, 0.0f, -0.7071f, 0.0f), glm::vec3()); - relDefaultPose = localParentOffset.inverse() * AnimPose(glm::quat(), relDefaultPose.trans()) * localParentOffset * AnimPose(relDefaultPose.rot(), glm::vec3()); - qCDebug(animation) << "the head translation is " << relDefaultPose.trans(); - } - _relativeDefaultPoses.push_back(relDefaultPose); diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index 3302760f6b..02648d5771 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -2077,7 +2077,8 @@ void Rig::setJointRotationOffsets(const QMap& offsets) { int neckId = 62; int spine2Id = 13; if (true){ //neckIndex != -1) { - _jointRotationOffsets.insert(neckId, glm::quat(0.7071f, 0.0f, -0.7071f, 0.0f)); + _jointRotationOffsets.insert(neckId, glm::quat(0.0f, 0.7071f, 0.7071f, 0.0f) * glm::quat(0.5f, 0.5f, 0.5f, -0.5f) ); //glm::quat(0.7071f, 0.0f, -0.7071f, 0.0f) + qCDebug(animation) << "multiplied quats are " << glm::quat(0.0f, 0.7071f, 0.7071f, 0.0f) * glm::quat(0.5f, 0.5f, 0.5f, -0.5f); } if (true){ //spine2Index != -1) { _jointRotationOffsets.insert(spine2Id, glm::quat(0.5f, 0.5f, 0.5f, -0.5f)); From 1dbccc814b9471a554573d31ce85332b586039b3 Mon Sep 17 00:00:00 2001 From: amantley Date: Tue, 6 Nov 2018 17:35:53 -0800 Subject: [PATCH 15/32] working on the ik dislocation caused by the offsets, head is what I am working on --- interface/src/avatar/MyAvatar.cpp | 2 +- interface/src/avatar/MySkeletonModel.cpp | 8 ++++++-- libraries/animation/src/AnimSkeleton.cpp | 15 +++------------ libraries/animation/src/Rig.cpp | 6 +++++- libraries/animation/src/Rig.h | 2 ++ 5 files changed, 17 insertions(+), 16 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 3299bd10e7..0f9d3f2f81 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -431,7 +431,7 @@ void MyAvatar::reset(bool andRecenter, bool andReload, bool andHead) { _wasPushing = _isPushing = _isBraking = false; _follow.deactivate(); if (andReload) { - _skeletonModel->reset(); + //_skeletonModel->reset(); } if (andHead) { // which drives camera in desktop getHead()->reset(); diff --git a/interface/src/avatar/MySkeletonModel.cpp b/interface/src/avatar/MySkeletonModel.cpp index c6aae6124a..858cba69dd 100644 --- a/interface/src/avatar/MySkeletonModel.cpp +++ b/interface/src/avatar/MySkeletonModel.cpp @@ -91,6 +91,7 @@ static AnimPose computeHipsInSensorFrame(MyAvatar* myAvatar, bool isFlying) { // Called within Model::simulate call, below. void MySkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) { const FBXGeometry& geometry = getFBXGeometry(); + const QMap jointOffsetMap = _rig.getJointRotationOffsets(); Head* head = _owningAvatar->getHead(); @@ -118,8 +119,10 @@ void MySkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) { // input action is the highest priority source for head orientation. auto avatarHeadPose = myAvatar->getControllerPoseInAvatarFrame(controller::Action::HEAD); if (avatarHeadPose.isValid()) { + qCDebug(interfaceapp) << "neck joint offset " << jointOffsetMap[62]; + AnimPose jointOffset(jointOffsetMap[62], glm::vec3()); AnimPose pose(avatarHeadPose.getRotation(), avatarHeadPose.getTranslation()); - params.primaryControllerPoses[Rig::PrimaryControllerType_Head] = avatarToRigPose * pose; + params.primaryControllerPoses[Rig::PrimaryControllerType_Head] = jointOffset.inverse() * (avatarToRigPose * pose) * jointOffset; params.primaryControllerFlags[Rig::PrimaryControllerType_Head] = (uint8_t)Rig::ControllerFlags::Enabled; } else { // even though full head IK is disabled, the rig still needs the head orientation to rotate the head up and @@ -229,7 +232,8 @@ void MySkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) { params.primaryControllerFlags[Rig::PrimaryControllerType_Hips] = (uint8_t)Rig::ControllerFlags::Enabled | (uint8_t)Rig::ControllerFlags::Estimated; // set spine2 if we have hand controllers - if (myAvatar->getControllerPoseInAvatarFrame(controller::Action::RIGHT_HAND).isValid() && + qCDebug(interfaceapp) << "spine 2 joint offset " << jointOffsetMap[13]; + if (false && myAvatar->getControllerPoseInAvatarFrame(controller::Action::RIGHT_HAND).isValid() && myAvatar->getControllerPoseInAvatarFrame(controller::Action::LEFT_HAND).isValid() && !(params.primaryControllerFlags[Rig::PrimaryControllerType_Spine2] & (uint8_t)Rig::ControllerFlags::Enabled)) { diff --git a/libraries/animation/src/AnimSkeleton.cpp b/libraries/animation/src/AnimSkeleton.cpp index 2dfcdee4b0..05953e2803 100644 --- a/libraries/animation/src/AnimSkeleton.cpp +++ b/libraries/animation/src/AnimSkeleton.cpp @@ -41,19 +41,10 @@ AnimSkeleton::AnimSkeleton(const FBXGeometry& fbxGeometry, const QMap(mesh.clusters.at(j)); - if ((cluster.jointIndex == 62) || (cluster.jointIndex == 13)) { - qCDebug(animation) << "cluster joint equals index " << cluster.jointIndex; - } // AJT: mutate bind pose! this allows us to oreint the skeleton back into the authored orientaiton before // rendering, with no runtime overhead. // this works if clusters match joints one for one. - if (cluster.jointIndex == 63) { - //qCDebug(animation) << "Head"; - //qCDebug(animation) << "found a joint offset to add " << cluster.jointIndex << " " << jointOffsets[cluster.jointIndex] << " cluster " << cluster.jointIndex; - //AnimPose localOffset(glm::quat(.7071f, 0.0f, .7071f, 0.0f), glm::vec3()); - //cluster.inverseBindMatrix = (glm::mat4)localOffset.inverse() * cluster.inverseBindMatrix; - //cluster.inverseBindTransform.evalFromRawMatrix(cluster.inverseBindMatrix); - } + if (cluster.jointIndex == 62) { qCDebug(animation) << "Neck"; qCDebug(animation) << "found a joint offset to add " << cluster.jointIndex << " " << jointOffsets[cluster.jointIndex] << " cluster " << cluster.jointIndex; @@ -246,11 +237,11 @@ void AnimSkeleton::buildSkeletonFromJoints(const std::vector& joints, // 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. //relDefaultPose = relDefaultPose * _avatarTPoseOffsets[i]; - + QString jointName = getJointName(i); if (jointOffsets.contains(i)) { //QString parentIndex = getJointName(parentIndex); - AnimPose localOffset(jointOffsets[i], glm::vec3()); + AnimPose localOffset(jointOffsets[i], glm::vec3()); relDefaultPose = relDefaultPose * localOffset; } if ((parentIndex >= 0) && jointOffsets.contains(parentIndex)) { diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index 02648d5771..1e20ec9a7d 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -267,7 +267,7 @@ void Rig::initJointStates(const FBXGeometry& geometry, const glm::mat4& modelOff _rigToGeometryTransform = glm::inverse(_geometryToRigTransform); setModelOffset(modelOffset); - _animSkeleton = std::make_shared(geometry,_jointRotationOffsets); + _animSkeleton = std::make_shared(geometry, _jointRotationOffsets); _internalPoseSet._relativePoses.clear(); _internalPoseSet._relativePoses = _animSkeleton->getRelativeDefaultPoses(); @@ -2084,4 +2084,8 @@ void Rig::setJointRotationOffsets(const QMap& offsets) { _jointRotationOffsets.insert(spine2Id, glm::quat(0.5f, 0.5f, 0.5f, -0.5f)); } qCDebug(animation) << "set the neck and spine2 offsets " << spine2Id << " " << neckId; +} + +const QMap& Rig::getJointRotationOffsets() const { + return _jointRotationOffsets; } \ No newline at end of file diff --git a/libraries/animation/src/Rig.h b/libraries/animation/src/Rig.h index 9928810026..dd7e766a49 100644 --- a/libraries/animation/src/Rig.h +++ b/libraries/animation/src/Rig.h @@ -128,6 +128,7 @@ public: int getJointStateCount() const; int indexOfJoint(const QString& jointName) const; QString nameOfJoint(int jointIndex) const; + const QMap& getJointRotationOffsets() const; void setModelOffset(const glm::mat4& modelOffsetMat); @@ -422,6 +423,7 @@ protected: SnapshotBlendPoseHelper _hipsBlendHelper; ControllerParameters _previousControllerParameters; + bool _alreadyInitialized { false }; }; #endif /* defined(__hifi__Rig__) */ From dfd0ce69cbade0f1ead879c597ce17f451452799 Mon Sep 17 00:00:00 2001 From: amantley Date: Tue, 6 Nov 2018 17:36:05 -0800 Subject: [PATCH 16/32] more head ik --- interface/src/avatar/MySkeletonModel.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/interface/src/avatar/MySkeletonModel.cpp b/interface/src/avatar/MySkeletonModel.cpp index 858cba69dd..6aa4d1402f 100644 --- a/interface/src/avatar/MySkeletonModel.cpp +++ b/interface/src/avatar/MySkeletonModel.cpp @@ -120,9 +120,10 @@ void MySkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) { auto avatarHeadPose = myAvatar->getControllerPoseInAvatarFrame(controller::Action::HEAD); if (avatarHeadPose.isValid()) { qCDebug(interfaceapp) << "neck joint offset " << jointOffsetMap[62]; - AnimPose jointOffset(jointOffsetMap[62], glm::vec3()); + AnimPose jointOffsetNeck(jointOffsetMap[62], glm::vec3()); + AnimPose jointOffsetSpine2(jointOffsetMap[13], glm::vec3()); AnimPose pose(avatarHeadPose.getRotation(), avatarHeadPose.getTranslation()); - params.primaryControllerPoses[Rig::PrimaryControllerType_Head] = jointOffset.inverse() * (avatarToRigPose * pose) * jointOffset; + params.primaryControllerPoses[Rig::PrimaryControllerType_Head] = jointOffsetSpine2.inverse() * jointOffsetNeck.inverse() * (avatarToRigPose * pose) * jointOffsetNeck * jointOffsetSpine2; params.primaryControllerFlags[Rig::PrimaryControllerType_Head] = (uint8_t)Rig::ControllerFlags::Enabled; } else { // even though full head IK is disabled, the rig still needs the head orientation to rotate the head up and From 6b4620b4a14d5254925bd5e54ada3caf61d54edb Mon Sep 17 00:00:00 2001 From: amantley Date: Wed, 7 Nov 2018 17:32:23 -0800 Subject: [PATCH 17/32] working on the input mapper problem for the offset rotations --- interface/src/avatar/MyAvatar.cpp | 5 ++++- interface/src/avatar/MySkeletonModel.cpp | 15 +++++++++++++-- libraries/animation/src/Rig.cpp | 2 +- 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 0f9d3f2f81..39e6a56b02 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -431,7 +431,7 @@ void MyAvatar::reset(bool andRecenter, bool andReload, bool andHead) { _wasPushing = _isPushing = _isBraking = false; _follow.deactivate(); if (andReload) { - //_skeletonModel->reset(); + _skeletonModel->reset(); } if (andHead) { // which drives camera in desktop getHead()->reset(); @@ -2037,7 +2037,9 @@ controller::Pose MyAvatar::getControllerPoseInSensorFrame(controller::Action act controller::Pose MyAvatar::getControllerPoseInWorldFrame(controller::Action action) const { auto pose = getControllerPoseInSensorFrame(action); + qCDebug(interfaceapp) << "avatar sensor orientation " << pose.getRotation(); if (pose.valid) { + qCDebug(interfaceapp) << "sensor to world matrix orientation " << extractRotation(getSensorToWorldMatrix()); return pose.transform(getSensorToWorldMatrix()); } else { return controller::Pose(); // invalid pose @@ -2047,6 +2049,7 @@ controller::Pose MyAvatar::getControllerPoseInWorldFrame(controller::Action acti controller::Pose MyAvatar::getControllerPoseInAvatarFrame(controller::Action action) const { auto pose = getControllerPoseInWorldFrame(action); if (pose.valid) { + qCDebug(interfaceapp) << "avatar world orientation " << getWorldOrientation(); glm::mat4 invAvatarMatrix = glm::inverse(createMatFromQuatAndPos(getWorldOrientation(), getWorldPosition())); return pose.transform(invAvatarMatrix); } else { diff --git a/interface/src/avatar/MySkeletonModel.cpp b/interface/src/avatar/MySkeletonModel.cpp index 6aa4d1402f..d389d99e26 100644 --- a/interface/src/avatar/MySkeletonModel.cpp +++ b/interface/src/avatar/MySkeletonModel.cpp @@ -119,11 +119,22 @@ void MySkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) { // input action is the highest priority source for head orientation. auto avatarHeadPose = myAvatar->getControllerPoseInAvatarFrame(controller::Action::HEAD); if (avatarHeadPose.isValid()) { + AnimPose previousHeadPose; + bool headUnfuckedWith = _rig.getAbsoluteJointPoseInRigFrame(_rig.indexOfJoint("Head"), previousHeadPose); + if (headUnfuckedWith) { + qCDebug(interfaceapp) << "unset head position " << previousHeadPose.trans(); + qCDebug(interfaceapp) << "unset head rotation " << previousHeadPose.rot(); + } qCDebug(interfaceapp) << "neck joint offset " << jointOffsetMap[62]; + qCDebug(interfaceapp) << "head joint avatar frame " << avatarHeadPose.getRotation(); AnimPose jointOffsetNeck(jointOffsetMap[62], glm::vec3()); AnimPose jointOffsetSpine2(jointOffsetMap[13], glm::vec3()); + AnimPose testPose(glm::quat(0.7071f, 0.0f, 0.0f, 0.7071f), glm::vec3()); AnimPose pose(avatarHeadPose.getRotation(), avatarHeadPose.getTranslation()); - params.primaryControllerPoses[Rig::PrimaryControllerType_Head] = jointOffsetSpine2.inverse() * jointOffsetNeck.inverse() * (avatarToRigPose * pose) * jointOffsetNeck * jointOffsetSpine2; + AnimPose newHeadRot = (avatarToRigPose * pose) * testPose; + AnimPose newHeadRot2(newHeadRot.rot(), avatarHeadPose.getTranslation()); + AnimPose identityPose(glm::quat(1.0f,0.0f,0.0f,0.0f), glm::vec3(0.0f,0.57f,0.0f)); + params.primaryControllerPoses[Rig::PrimaryControllerType_Head] = avatarToRigPose * pose; params.primaryControllerFlags[Rig::PrimaryControllerType_Head] = (uint8_t)Rig::ControllerFlags::Enabled; } else { // even though full head IK is disabled, the rig still needs the head orientation to rotate the head up and @@ -234,7 +245,7 @@ void MySkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) { // set spine2 if we have hand controllers qCDebug(interfaceapp) << "spine 2 joint offset " << jointOffsetMap[13]; - if (false && myAvatar->getControllerPoseInAvatarFrame(controller::Action::RIGHT_HAND).isValid() && + if (myAvatar->getControllerPoseInAvatarFrame(controller::Action::RIGHT_HAND).isValid() && myAvatar->getControllerPoseInAvatarFrame(controller::Action::LEFT_HAND).isValid() && !(params.primaryControllerFlags[Rig::PrimaryControllerType_Spine2] & (uint8_t)Rig::ControllerFlags::Enabled)) { diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index 1e20ec9a7d..a73c945124 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -2078,7 +2078,7 @@ void Rig::setJointRotationOffsets(const QMap& offsets) { int spine2Id = 13; if (true){ //neckIndex != -1) { _jointRotationOffsets.insert(neckId, glm::quat(0.0f, 0.7071f, 0.7071f, 0.0f) * glm::quat(0.5f, 0.5f, 0.5f, -0.5f) ); //glm::quat(0.7071f, 0.0f, -0.7071f, 0.0f) - qCDebug(animation) << "multiplied quats are " << glm::quat(0.0f, 0.7071f, 0.7071f, 0.0f) * glm::quat(0.5f, 0.5f, 0.5f, -0.5f); + qCDebug(animation) << "multiplied quats are " << glm::quat(0.7071f, 0.0f, -0.7071f, 0.0f) * glm::quat(0.5f, 0.5f, 0.5f, -0.5f); } if (true){ //spine2Index != -1) { _jointRotationOffsets.insert(spine2Id, glm::quat(0.5f, 0.5f, 0.5f, -0.5f)); From 8735b409ab110e4cc7b9d67b18932a6f37711782 Mon Sep 17 00:00:00 2001 From: amantley Date: Thu, 8 Nov 2018 17:12:10 -0800 Subject: [PATCH 18/32] in the process of changing the rotation application to being absolute joints not local --- interface/src/avatar/MyAvatar.cpp | 3 - interface/src/avatar/MySkeletonModel.cpp | 17 +---- libraries/animation/src/AnimSkeleton.cpp | 82 +++++++++++++----------- libraries/animation/src/Rig.cpp | 2 + 4 files changed, 48 insertions(+), 56 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 39e6a56b02..3299bd10e7 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -2037,9 +2037,7 @@ controller::Pose MyAvatar::getControllerPoseInSensorFrame(controller::Action act controller::Pose MyAvatar::getControllerPoseInWorldFrame(controller::Action action) const { auto pose = getControllerPoseInSensorFrame(action); - qCDebug(interfaceapp) << "avatar sensor orientation " << pose.getRotation(); if (pose.valid) { - qCDebug(interfaceapp) << "sensor to world matrix orientation " << extractRotation(getSensorToWorldMatrix()); return pose.transform(getSensorToWorldMatrix()); } else { return controller::Pose(); // invalid pose @@ -2049,7 +2047,6 @@ controller::Pose MyAvatar::getControllerPoseInWorldFrame(controller::Action acti controller::Pose MyAvatar::getControllerPoseInAvatarFrame(controller::Action action) const { auto pose = getControllerPoseInWorldFrame(action); if (pose.valid) { - qCDebug(interfaceapp) << "avatar world orientation " << getWorldOrientation(); glm::mat4 invAvatarMatrix = glm::inverse(createMatFromQuatAndPos(getWorldOrientation(), getWorldPosition())); return pose.transform(invAvatarMatrix); } else { diff --git a/interface/src/avatar/MySkeletonModel.cpp b/interface/src/avatar/MySkeletonModel.cpp index d389d99e26..6026794cda 100644 --- a/interface/src/avatar/MySkeletonModel.cpp +++ b/interface/src/avatar/MySkeletonModel.cpp @@ -119,21 +119,7 @@ void MySkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) { // input action is the highest priority source for head orientation. auto avatarHeadPose = myAvatar->getControllerPoseInAvatarFrame(controller::Action::HEAD); if (avatarHeadPose.isValid()) { - AnimPose previousHeadPose; - bool headUnfuckedWith = _rig.getAbsoluteJointPoseInRigFrame(_rig.indexOfJoint("Head"), previousHeadPose); - if (headUnfuckedWith) { - qCDebug(interfaceapp) << "unset head position " << previousHeadPose.trans(); - qCDebug(interfaceapp) << "unset head rotation " << previousHeadPose.rot(); - } - qCDebug(interfaceapp) << "neck joint offset " << jointOffsetMap[62]; - qCDebug(interfaceapp) << "head joint avatar frame " << avatarHeadPose.getRotation(); - AnimPose jointOffsetNeck(jointOffsetMap[62], glm::vec3()); - AnimPose jointOffsetSpine2(jointOffsetMap[13], glm::vec3()); - AnimPose testPose(glm::quat(0.7071f, 0.0f, 0.0f, 0.7071f), glm::vec3()); AnimPose pose(avatarHeadPose.getRotation(), avatarHeadPose.getTranslation()); - AnimPose newHeadRot = (avatarToRigPose * pose) * testPose; - AnimPose newHeadRot2(newHeadRot.rot(), avatarHeadPose.getTranslation()); - AnimPose identityPose(glm::quat(1.0f,0.0f,0.0f,0.0f), glm::vec3(0.0f,0.57f,0.0f)); params.primaryControllerPoses[Rig::PrimaryControllerType_Head] = avatarToRigPose * pose; params.primaryControllerFlags[Rig::PrimaryControllerType_Head] = (uint8_t)Rig::ControllerFlags::Enabled; } else { @@ -244,7 +230,7 @@ void MySkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) { params.primaryControllerFlags[Rig::PrimaryControllerType_Hips] = (uint8_t)Rig::ControllerFlags::Enabled | (uint8_t)Rig::ControllerFlags::Estimated; // set spine2 if we have hand controllers - qCDebug(interfaceapp) << "spine 2 joint offset " << jointOffsetMap[13]; + //qCDebug(interfaceapp) << "spine 2 joint offset " << jointOffsetMap[13]; if (myAvatar->getControllerPoseInAvatarFrame(controller::Action::RIGHT_HAND).isValid() && myAvatar->getControllerPoseInAvatarFrame(controller::Action::LEFT_HAND).isValid() && !(params.primaryControllerFlags[Rig::PrimaryControllerType_Spine2] & (uint8_t)Rig::ControllerFlags::Enabled)) { @@ -255,6 +241,7 @@ void MySkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) { bool spine2Exists = _rig.getAbsoluteJointPoseInRigFrame(_rig.indexOfJoint("Spine2"), currentSpine2Pose); bool headExists = _rig.getAbsoluteJointPoseInRigFrame(_rig.indexOfJoint("Head"), currentHeadPose); bool hipsExists = _rig.getAbsoluteJointPoseInRigFrame(_rig.indexOfJoint("Hips"), currentHipsPose); + if (spine2Exists && headExists && hipsExists) { AnimPose rigSpaceYaw(myAvatar->getSpine2RotationRigSpace()); diff --git a/libraries/animation/src/AnimSkeleton.cpp b/libraries/animation/src/AnimSkeleton.cpp index 05953e2803..d2bed40a06 100644 --- a/libraries/animation/src/AnimSkeleton.cpp +++ b/libraries/animation/src/AnimSkeleton.cpp @@ -15,6 +15,7 @@ #include #include "AnimationLogging.h" +static bool notBound = true; AnimSkeleton::AnimSkeleton(const FBXGeometry& fbxGeometry, const QMap jointOffsets) { @@ -22,48 +23,46 @@ AnimSkeleton::AnimSkeleton(const FBXGeometry& fbxGeometry, const QMap joints; joints.reserve(fbxGeometry.joints.size()); - //_avatarTPoseOffsets.reserve(_jointsSize); for (auto& joint : fbxGeometry.joints) { joints.push_back(joint); - //_avatarTPoseOffsets.push_back(AnimPose(glm::quat(), glm::vec3())); } buildSkeletonFromJoints(joints, jointOffsets); // 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("Neck")] = AnimPose(glm::quat(0.0f, 0.707107f, 0.0f, 0.707107f), glm::vec3()); - - for (int i = 0; i < (int)fbxGeometry.meshes.size(); i++) { - const FBXMesh& mesh = fbxGeometry.meshes.at(i); - for (int j = 0; j < mesh.clusters.size(); j++) { - - - // cast into a non-const reference, so we can mutate the FBXCluster - FBXCluster& cluster = const_cast(mesh.clusters.at(j)); + if (notBound) { + notBound = false; + for (int i = 0; i < (int)fbxGeometry.meshes.size(); i++) { + const FBXMesh& mesh = fbxGeometry.meshes.at(i); + for (int j = 0; j < mesh.clusters.size(); j++) { - // AJT: mutate bind pose! this allows us to oreint the skeleton back into the authored orientaiton before - // rendering, with no runtime overhead. - // this works if clusters match joints one for one. - - if (cluster.jointIndex == 62) { - qCDebug(animation) << "Neck"; - qCDebug(animation) << "found a joint offset to add " << cluster.jointIndex << " " << jointOffsets[cluster.jointIndex] << " cluster " << cluster.jointIndex; - AnimPose localOffset(jointOffsets[cluster.jointIndex], glm::vec3()); - cluster.inverseBindMatrix = (glm::mat4)localOffset.inverse() * cluster.inverseBindMatrix; - cluster.inverseBindTransform.evalFromRawMatrix(cluster.inverseBindMatrix); - } - if (cluster.jointIndex == 13) { - qCDebug(animation) << "Spine2"; - qCDebug(animation) << "found a joint offset to add " << cluster.jointIndex << " " << jointOffsets[cluster.jointIndex] << " cluster " << cluster.jointIndex; - AnimPose localOffset(jointOffsets[cluster.jointIndex], glm::vec3()); - cluster.inverseBindMatrix = (glm::mat4)localOffset.inverse() * cluster.inverseBindMatrix; - cluster.inverseBindTransform.evalFromRawMatrix(cluster.inverseBindMatrix); - } + // cast into a non-const reference, so we can mutate the FBXCluster + FBXCluster& cluster = const_cast(mesh.clusters.at(j)); + + // AJT: mutate bind pose! this allows us to oreint the skeleton back into the authored orientaiton before + // rendering, with no runtime overhead. + // this works if clusters match joints one for one. + + if (cluster.jointIndex == 62) { + qCDebug(animation) << "Neck"; + qCDebug(animation) << "found a joint offset to add " << cluster.jointIndex << " " << jointOffsets[cluster.jointIndex] << " cluster " << cluster.jointIndex; + AnimPose localOffset(jointOffsets[cluster.jointIndex], glm::vec3()); + cluster.inverseBindMatrix = (glm::mat4)localOffset.inverse() * cluster.inverseBindMatrix; + cluster.inverseBindTransform.evalFromRawMatrix(cluster.inverseBindMatrix); + } + if (cluster.jointIndex == 13) { + qCDebug(animation) << "Spine2"; + qCDebug(animation) << "found a joint offset to add " << cluster.jointIndex << " " << jointOffsets[cluster.jointIndex] << " cluster " << cluster.jointIndex; + AnimPose localOffset(jointOffsets[cluster.jointIndex], glm::vec3()); + cluster.inverseBindMatrix = (glm::mat4)localOffset.inverse() * cluster.inverseBindMatrix; + cluster.inverseBindTransform.evalFromRawMatrix(cluster.inverseBindMatrix); + } + + } } + } - } AnimSkeleton::AnimSkeleton(const std::vector& joints, const QMap jointOffsets) { @@ -232,6 +231,12 @@ void AnimSkeleton::buildSkeletonFromJoints(const std::vector& joints, qCDebug(animation) << "relative default pose for joint " << i << " " << relDefaultPose.trans() << " " << relDefaultPose.rot(); int parentIndex = getParentIndex(i); + AnimPose newAbsPose; + if (parentIndex >= 0) { + newAbsPose = _absoluteDefaultPoses[parentIndex] * AnimPose(relDefaultPose.rot(),glm::vec3()); + } else { + newAbsPose = relDefaultPose; + } // putting the pipeline code is // remember the inverse bind pose already has the offset added into it. the total effect is offset^-1 * relDefPose * offset. @@ -242,20 +247,21 @@ void AnimSkeleton::buildSkeletonFromJoints(const std::vector& joints, if (jointOffsets.contains(i)) { //QString parentIndex = getJointName(parentIndex); AnimPose localOffset(jointOffsets[i], glm::vec3()); - relDefaultPose = relDefaultPose * localOffset; + newAbsPose = newAbsPose * 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()); + newAbsPose = localParentOffset.inverse() * AnimPose(glm::quat(), relDefaultPose.trans()) * localParentOffset * AnimPose(newAbsPose.rot(), glm::vec3()); } - _relativeDefaultPoses.push_back(relDefaultPose); - if (parentIndex >= 0) { - _absoluteDefaultPoses.push_back(_absoluteDefaultPoses[parentIndex] * relDefaultPose); - } else { - _absoluteDefaultPoses.push_back(relDefaultPose); + relDefaultPose = _absoluteDefaultPoses[parentIndex].inverse() * newAbsPose; } + _relativeDefaultPoses.push_back(relDefaultPose); + + + _absoluteDefaultPoses.push_back(newAbsPose); + } for (int i = 0; i < _jointsSize; i++) { diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index a73c945124..bdbbd02706 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -2084,6 +2084,8 @@ void Rig::setJointRotationOffsets(const QMap& offsets) { _jointRotationOffsets.insert(spine2Id, glm::quat(0.5f, 0.5f, 0.5f, -0.5f)); } qCDebug(animation) << "set the neck and spine2 offsets " << spine2Id << " " << neckId; + glm::quat testRot(glm::vec3(0.000018095f, -4.74360667058f, -89.9994155926f)); + qCDebug(animation) << "test rot from euler" << testRot; } const QMap& Rig::getJointRotationOffsets() const { From 244b768b9ae279e978e14768bb8963e60dc1513d Mon Sep 17 00:00:00 2001 From: Angus Antley Date: Thu, 8 Nov 2018 23:42:50 -0800 Subject: [PATCH 19/32] fixed the absolute default joint poses so they work for the 2 joint avatar --- interface/src/avatar/MyAvatar.cpp | 2 +- libraries/animation/src/AnimSkeleton.cpp | 38 ++++++++-- libraries/animation/src/Rig.cpp | 79 ++++++++++++++++++--- tools/skeleton-dump/src/SkeletonDumpApp.cpp | 11 ++- 4 files changed, 109 insertions(+), 21 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 8d47591d40..502be9d57c 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -431,7 +431,7 @@ void MyAvatar::reset(bool andRecenter, bool andReload, bool andHead) { _wasPushing = _isPushing = _isBraking = false; _follow.deactivate(); if (andReload) { - _skeletonModel->reset(); + //_skeletonModel->reset(); } if (andHead) { // which drives camera in desktop getHead()->reset(); diff --git a/libraries/animation/src/AnimSkeleton.cpp b/libraries/animation/src/AnimSkeleton.cpp index 03eac7de49..af0ec0d5b0 100644 --- a/libraries/animation/src/AnimSkeleton.cpp +++ b/libraries/animation/src/AnimSkeleton.cpp @@ -28,8 +28,8 @@ AnimSkeleton::AnimSkeleton(const HFMModel& hfmModel, const QMap buildSkeletonFromJoints(joints, jointOffsets); // add offsets for spine2 and the neck - if (notBound) { - notBound = false; + + for (int i = 0; i < (int)hfmModel.meshes.size(); i++) { const HFMMesh& mesh = hfmModel.meshes.at(i); for (int j = 0; j < mesh.clusters.size(); j++) { @@ -59,7 +59,7 @@ AnimSkeleton::AnimSkeleton(const HFMModel& hfmModel, const QMap } } - } + } @@ -230,6 +230,34 @@ void AnimSkeleton::mirrorAbsolutePoses(AnimPoseVec& poses) const { qCDebug(animation) << "relative default pose for joint " << i << " " << relDefaultPose.trans() << " " << relDefaultPose.rot(); int parentIndex = getParentIndex(i); + + AnimPose newAbsPose; + if (parentIndex >= 0) { + newAbsPose = _absoluteDefaultPoses[parentIndex] * relDefaultPose; + + _absoluteDefaultPoses.push_back(newAbsPose); + } else { + + _absoluteDefaultPoses.push_back(relDefaultPose); + } + + } + for (int k = 0; k < _jointsSize; k++) { + int parentIndex2 = getParentIndex(k); + if (jointOffsets.contains(k)) { + AnimPose localOffset(jointOffsets[k], glm::vec3()); + _absoluteDefaultPoses[k] = _absoluteDefaultPoses[k] * localOffset; + } + if (parentIndex2 >= 0) { + + _relativeDefaultPoses.push_back(_absoluteDefaultPoses[parentIndex2].inverse() * _absoluteDefaultPoses[k]); + } else { + + _relativeDefaultPoses.push_back(_absoluteDefaultPoses[k]); + } + } + + /* AnimPose newAbsPose; if (parentIndex >= 0) { newAbsPose = _absoluteDefaultPoses[parentIndex] * AnimPose(relDefaultPose.rot(),glm::vec3()); @@ -260,9 +288,9 @@ void AnimSkeleton::mirrorAbsolutePoses(AnimPoseVec& poses) const { _absoluteDefaultPoses.push_back(newAbsPose); - + } - + */ for (int i = 0; i < _jointsSize; i++) { _jointIndicesByName[_joints[i].name] = i; } diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index 6f1e37d9ff..28ef0aef5c 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -310,11 +310,9 @@ void Rig::initJointStates(const HFMModel& hfmModel, const glm::mat4& modelOffset void Rig::reset(const HFMModel& hfmModel) { _geometryOffset = AnimPose(hfmModel.offset); _invGeometryOffset = _geometryOffset.inverse(); -<<<<<<< HEAD - _animSkeleton = std::make_shared(geometry, _jointRotationOffsets); -======= - _animSkeleton = std::make_shared(hfmModel); ->>>>>>> upstream/master + + _animSkeleton = std::make_shared(hfmModel, _jointRotationOffsets); + _internalPoseSet._relativePoses.clear(); _internalPoseSet._relativePoses = _animSkeleton->getRelativeDefaultPoses(); @@ -2087,9 +2085,74 @@ void Rig::setJointRotationOffsets(const QMap& offsets) { if (true){ //spine2Index != -1) { _jointRotationOffsets.insert(spine2Id, glm::quat(0.5f, 0.5f, 0.5f, -0.5f)); } - qCDebug(animation) << "set the neck and spine2 offsets " << spine2Id << " " << neckId; - glm::quat testRot(glm::vec3(0.000018095f, -4.74360667058f, -89.9994155926f)); - qCDebug(animation) << "test rot from euler" << testRot; + + std::vector eulersFromEngineer; + eulersFromEngineer.push_back(glm::vec3(-81.1050620752f, -20.1443891394f, 100.309499473f)); + eulersFromEngineer.push_back(glm::vec3(260.889773298f, -20.143735467f, 79.7184972987f)); + eulersFromEngineer.push_back(glm::vec3(-196.885439853f, -15.4618394328f, 107.273377257f)); + eulersFromEngineer.push_back(glm::vec3(185.169288353f, -14.3865564204f, 73.5514142013f)); + eulersFromEngineer.push_back(glm::vec3(85.0436206363f, -0.405424354654f, 279.126747746f)); + eulersFromEngineer.push_back(glm::vec3(265.040827938f, -24.8809133357f, 80.8874530433f)); + eulersFromEngineer.push_back(glm::vec3(0.0000012746f, -9.5408567955f, 89.9999827841f)); + eulersFromEngineer.push_back(glm::vec3(-304.676178613f, -1.77806457464f, 94.6267844984f)); + eulersFromEngineer.push_back(glm::vec3(299.239708621f, -1.75410019523f, 85.3712190608f)); + eulersFromEngineer.push_back(glm::vec3(-70.5442845855f, 180.00795643f, -73.899282669f)); + eulersFromEngineer.push_back(glm::vec3(-5.65981473995f, -0.554837824572f, 90.3818083467f)); + eulersFromEngineer.push_back(glm::vec3(282.516400893f, -2.86457680169f, 106.966109268f)); + eulersFromEngineer.push_back(glm::vec3(-5.74446362761f, -3.69252247483f, 89.4088276443f)); + eulersFromEngineer.push_back(glm::vec3(175.098015269f, 11.7273076323f, 282.707060357f)); + eulersFromEngineer.push_back(glm::vec3(-5.86440719705f, -11.5976507143f, 93.7305032918f)); + eulersFromEngineer.push_back(glm::vec3(212.162310762f, 11.1889030401f, 90.489887929f)); + eulersFromEngineer.push_back(glm::vec3(-183.528298852f, 11.1630787238f, 89.5119846423f)); + eulersFromEngineer.push_back(glm::vec3(-21.5907187136f, -1.16096242449f, 93.4017341288f)); + eulersFromEngineer.push_back(glm::vec3(-230.174545226f, -1.16165879865f, 86.5984269351f)); + eulersFromEngineer.push_back(glm::vec3(-71.3250132734f, 179.345867731f, -73.9245897857f)); + eulersFromEngineer.push_back(glm::vec3(4.4183033408f, 0.0214780500113f, 89.6156394563f)); + eulersFromEngineer.push_back(glm::vec3(-71.3557521294f, -1.96233777224f, 101.311991763f)); + eulersFromEngineer.push_back(glm::vec3(4.52300317986f, -3.2744480538f, 93.9297689938f)); + eulersFromEngineer.push_back(glm::vec3(183.372659045f, 18.4240672177f, 289.089833888f)); + eulersFromEngineer.push_back(glm::vec3(4.69575782766f, -18.4271517191f, 85.8795582505f)); + eulersFromEngineer.push_back(glm::vec3(180.000000381f, 184.227605816f, -90.0000102753f)); + eulersFromEngineer.push_back(glm::vec3(180.000018095f, -4.74360667058f, -89.9994155926f)); + eulersFromEngineer.push_back(glm::vec3(-6.65059725988f, 179.738939306f, -74.3826161322f)); + eulersFromEngineer.push_back(glm::vec3(1.39276173327f, 0.376166992987f, 92.9332563713f)); + eulersFromEngineer.push_back(glm::vec3(290.266370725f, -2.98535083963f, 105.944099833f)); + eulersFromEngineer.push_back(glm::vec3(1.43200712942f, -2.97286285904f, 93.1492284976f)); + eulersFromEngineer.push_back(glm::vec3(194.564263389f, 20.3832505773f, 294.645037769f)); + eulersFromEngineer.push_back(glm::vec3(1.63629620002f, -20.9266621269f, 88.1506158063f)); + eulersFromEngineer.push_back(glm::vec3(-0.0431167069757f, 179.97446471f, -73.261703364f)); + eulersFromEngineer.push_back(glm::vec3(7.60338271732f, -0.342204658844f, 91.3116554499f)); + eulersFromEngineer.push_back(glm::vec3(279.206234833f, -3.4007859075f, 106.246009192f)); + eulersFromEngineer.push_back(glm::vec3(7.72548545025f, -3.33436960581f, 92.0998444782f)); + eulersFromEngineer.push_back(glm::vec3(197.45405684f, 22.6995116972f, 295.695981195f)); + eulersFromEngineer.push_back(glm::vec3(8.21527813645f, -19.794697098f, 86.2545417524f)); + eulersFromEngineer.push_back(glm::vec3(180.000036925f, 168.400465599f, -90.0003196145f)); + eulersFromEngineer.push_back(glm::vec3(7.86635710548e-05f, -2.45210839758f, 89.9992192762f)); + eulersFromEngineer.push_back(glm::vec3(179.999920323f, 4.95709895474f, 269.999215822f)); + eulersFromEngineer.push_back(glm::vec3(241.077352225f, -184.455008741f, -426.541304554f)); + eulersFromEngineer.push_back(glm::vec3(-70.6642196779f, 6.88023375774f, 85.5052784744f)); + eulersFromEngineer.push_back(glm::vec3(51.5850104459f, 4.10357301154f, 96.1370118091f)); + eulersFromEngineer.push_back(glm::vec3(-70.3665845407f, 5.50499763056f, 102.700969646f)); + eulersFromEngineer.push_back(glm::vec3(94.1058470618f, -4.50566341059f, -63.663409373f)); + eulersFromEngineer.push_back(glm::vec3(-70.8795528982f, 7.23642133863f, 82.4215992116f)); + eulersFromEngineer.push_back(glm::vec3(354.986036508f, -0.167802950666f, -73.0700479208f)); + eulersFromEngineer.push_back(glm::vec3(174.972844269f, 0.163203627576f, 73.0320316709f)); + eulersFromEngineer.push_back(glm::vec3(-156.40949683f, -2.25584901219f, 89.478726037f)); + eulersFromEngineer.push_back(glm::vec3(-147.791270237f, -2.25609369727f, 90.5216948763f)); + + qCDebug(animation) << "list of joint quats for engineer"; + for (glm::vec3 bone : eulersFromEngineer) { + glm::quat boneQuat(glm::vec3((bone.x / 180.0f)*PI, (bone.y / 180.0f)*PI, (bone.z / 180.0f)*PI)); + qCDebug(animation) << boneQuat; + } + + + + //qCDebug(animation) << "set the neck and spine2 offsets " << spine2Id << " " << neckId; + //glm::quat leftShoulder(glm::vec3((-81.1050620752f / 180.0f)*PI, (-20.1443891394f / 180.0f)*PI, (100.309499473f / 180.0f)*PI)); + //qCDebug(animation) << "jointRotationOffset = LeftShoulder = (" << leftShoulder << ")"; + //glm::quat testRot2(glm::vec3(PI / 2.0f, 0.0f, PI / 2.0f)); + //qCDebug(animation) << "test rot2 from euler" << testRot2; } const QMap& Rig::getJointRotationOffsets() const { diff --git a/tools/skeleton-dump/src/SkeletonDumpApp.cpp b/tools/skeleton-dump/src/SkeletonDumpApp.cpp index b818ae5da1..d1520d81f9 100644 --- a/tools/skeleton-dump/src/SkeletonDumpApp.cpp +++ b/tools/skeleton-dump/src/SkeletonDumpApp.cpp @@ -54,14 +54,11 @@ SkeletonDumpApp::SkeletonDumpApp(int argc, char* argv[]) : QCoreApplication(argc return; } QByteArray blob = file.readAll(); -<<<<<<< HEAD - std::unique_ptr fbxGeometry(readFBX(blob, QVariantHash())); - QMap jointRotationOffsets; - std::unique_ptr skeleton(new AnimSkeleton(*fbxGeometry, jointRotationOffsets)); -======= + std::unique_ptr geometry(readFBX(blob, QVariantHash())); - std::unique_ptr skeleton(new AnimSkeleton(*geometry)); ->>>>>>> upstream/master + QMap jointRotationOffsets; + std::unique_ptr skeleton(new AnimSkeleton(*geometry, jointRotationOffsets)); + skeleton->dump(verbose); } From e36ab9efd682bc2baf3557ebfb24f0303b09fd4d Mon Sep 17 00:00:00 2001 From: Angus Antley Date: Fri, 9 Nov 2018 00:44:52 -0800 Subject: [PATCH 20/32] cleaned up for merge with luis --- .../src/avatars/ScriptableAvatar.cpp | 3 +- interface/src/avatar/MySkeletonModel.cpp | 1 - libraries/animation/src/AnimClip.cpp | 3 +- libraries/animation/src/AnimSkeleton.cpp | 6 +- libraries/animation/src/Rig.cpp | 98 +------------------ libraries/animation/src/Rig.h | 6 -- .../src/avatars-renderer/SkeletonModel.cpp | 3 - libraries/fbx/src/FSTReader.cpp | 24 ----- libraries/fbx/src/FSTReader.h | 3 - tools/skeleton-dump/src/SkeletonDumpApp.cpp | 3 +- 10 files changed, 8 insertions(+), 142 deletions(-) diff --git a/assignment-client/src/avatars/ScriptableAvatar.cpp b/assignment-client/src/avatars/ScriptableAvatar.cpp index a211fe1bbe..51038a782f 100644 --- a/assignment-client/src/avatars/ScriptableAvatar.cpp +++ b/assignment-client/src/avatars/ScriptableAvatar.cpp @@ -84,8 +84,7 @@ void ScriptableAvatar::update(float deltatime) { // Run animation if (_animation && _animation->isLoaded() && _animation->getFrames().size() > 0 && !_bind.isNull() && _bind->isLoaded()) { if (!_animSkeleton) { - QMap jointRotationOffsets; - _animSkeleton = std::make_shared(_bind->getHFMModel(), jointRotationOffsets); + _animSkeleton = std::make_shared(_bind->getHFMModel()); } float currentFrame = _animationDetails.currentFrame + deltatime * _animationDetails.fps; if (_animationDetails.loop || currentFrame < _animationDetails.lastFrame) { diff --git a/interface/src/avatar/MySkeletonModel.cpp b/interface/src/avatar/MySkeletonModel.cpp index a5089dc0ea..720bbd1066 100644 --- a/interface/src/avatar/MySkeletonModel.cpp +++ b/interface/src/avatar/MySkeletonModel.cpp @@ -92,7 +92,6 @@ static AnimPose computeHipsInSensorFrame(MyAvatar* myAvatar, bool isFlying) { void MySkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) { const HFMModel& hfmModel = getHFMModel(); - const QMap jointOffsetMap = _rig.getJointRotationOffsets(); Head* head = _owningAvatar->getHead(); diff --git a/libraries/animation/src/AnimClip.cpp b/libraries/animation/src/AnimClip.cpp index 4900f414b7..a3d55726d6 100644 --- a/libraries/animation/src/AnimClip.cpp +++ b/libraries/animation/src/AnimClip.cpp @@ -103,8 +103,7 @@ void AnimClip::copyFromNetworkAnim() { // by matching joints with the same name. const HFMModel& hfmModel = _networkAnim->getHFMModel(); - QMap jointRotationOffsets; - AnimSkeleton animSkeleton(hfmModel, jointRotationOffsets); + AnimSkeleton animSkeleton(hfmModel); const auto animJointCount = animSkeleton.getNumJoints(); const auto skeletonJointCount = _skeleton->getNumJoints(); diff --git a/libraries/animation/src/AnimSkeleton.cpp b/libraries/animation/src/AnimSkeleton.cpp index af0ec0d5b0..f0219eb946 100644 --- a/libraries/animation/src/AnimSkeleton.cpp +++ b/libraries/animation/src/AnimSkeleton.cpp @@ -17,7 +17,7 @@ #include "AnimationLogging.h" static bool notBound = true; -AnimSkeleton::AnimSkeleton(const HFMModel& hfmModel, const QMap jointOffsets) { +AnimSkeleton::AnimSkeleton(const HFMModel& hfmModel) { qCDebug(animation) << "in the animSkeleton"; // convert to std::vector of joints std::vector joints; @@ -26,7 +26,7 @@ AnimSkeleton::AnimSkeleton(const HFMModel& hfmModel, const QMap joints.push_back(joint); } - buildSkeletonFromJoints(joints, jointOffsets); + buildSkeletonFromJoints(joints, hfmModel.jointOffsets); // add offsets for spine2 and the neck @@ -203,7 +203,7 @@ void AnimSkeleton::mirrorAbsolutePoses(AnimPoseVec& poses) const { } } - void AnimSkeleton::buildSkeletonFromJoints(const std::vector& joints, const QMap jointOffsets) { +void AnimSkeleton::buildSkeletonFromJoints(const std::vector& joints, const QMap jointOffsets) { _joints = joints; _jointsSize = (int)joints.size(); diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index 28ef0aef5c..85a19f6cfe 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -267,7 +267,7 @@ void Rig::initJointStates(const HFMModel& hfmModel, const glm::mat4& modelOffset _rigToGeometryTransform = glm::inverse(_geometryToRigTransform); setModelOffset(modelOffset); - _animSkeleton = std::make_shared(hfmModel, _jointRotationOffsets); + _animSkeleton = std::make_shared(hfmModel); _internalPoseSet._relativePoses.clear(); _internalPoseSet._relativePoses = _animSkeleton->getRelativeDefaultPoses(); @@ -311,7 +311,7 @@ void Rig::reset(const HFMModel& hfmModel) { _geometryOffset = AnimPose(hfmModel.offset); _invGeometryOffset = _geometryOffset.inverse(); - _animSkeleton = std::make_shared(hfmModel, _jointRotationOffsets); + _animSkeleton = std::make_shared(hfmModel); _internalPoseSet._relativePoses.clear(); @@ -2064,97 +2064,3 @@ void Rig::computeAvatarBoundingCapsule( glm::vec3 capsuleCenter = transformPoint(_geometryToRigTransform, (0.5f * (totalExtents.maximum + totalExtents.minimum))); localOffsetOut = capsuleCenter - hipsPosition; } - -void Rig::setJointRotationOffsets(const QMap& offsets) { - _jointRotationOffsets.clear(); - for (auto itr = offsets.begin(); itr != offsets.end(); itr++) { - QString jointName = itr.key(); - glm::quat rotationOffset = itr.value(); - int jointIndex = indexOfJoint(jointName); - if (jointIndex != -1) { - _jointRotationOffsets.insert(jointIndex, rotationOffset); - } - qDebug() << "Joint Rotation Offset added to Rig._jointRotationOffsets : " << " jointName: " << jointName << " jointIndex: " << jointIndex << " rotation offset: " << rotationOffset; - } - int neckId = 62; - int spine2Id = 13; - if (true){ //neckIndex != -1) { - _jointRotationOffsets.insert(neckId, glm::quat(0.0f, 0.7071f, 0.7071f, 0.0f) * glm::quat(0.5f, 0.5f, 0.5f, -0.5f) ); //glm::quat(0.7071f, 0.0f, -0.7071f, 0.0f) - qCDebug(animation) << "multiplied quats are " << glm::quat(0.7071f, 0.0f, -0.7071f, 0.0f) * glm::quat(0.5f, 0.5f, 0.5f, -0.5f); - } - if (true){ //spine2Index != -1) { - _jointRotationOffsets.insert(spine2Id, glm::quat(0.5f, 0.5f, 0.5f, -0.5f)); - } - - std::vector eulersFromEngineer; - eulersFromEngineer.push_back(glm::vec3(-81.1050620752f, -20.1443891394f, 100.309499473f)); - eulersFromEngineer.push_back(glm::vec3(260.889773298f, -20.143735467f, 79.7184972987f)); - eulersFromEngineer.push_back(glm::vec3(-196.885439853f, -15.4618394328f, 107.273377257f)); - eulersFromEngineer.push_back(glm::vec3(185.169288353f, -14.3865564204f, 73.5514142013f)); - eulersFromEngineer.push_back(glm::vec3(85.0436206363f, -0.405424354654f, 279.126747746f)); - eulersFromEngineer.push_back(glm::vec3(265.040827938f, -24.8809133357f, 80.8874530433f)); - eulersFromEngineer.push_back(glm::vec3(0.0000012746f, -9.5408567955f, 89.9999827841f)); - eulersFromEngineer.push_back(glm::vec3(-304.676178613f, -1.77806457464f, 94.6267844984f)); - eulersFromEngineer.push_back(glm::vec3(299.239708621f, -1.75410019523f, 85.3712190608f)); - eulersFromEngineer.push_back(glm::vec3(-70.5442845855f, 180.00795643f, -73.899282669f)); - eulersFromEngineer.push_back(glm::vec3(-5.65981473995f, -0.554837824572f, 90.3818083467f)); - eulersFromEngineer.push_back(glm::vec3(282.516400893f, -2.86457680169f, 106.966109268f)); - eulersFromEngineer.push_back(glm::vec3(-5.74446362761f, -3.69252247483f, 89.4088276443f)); - eulersFromEngineer.push_back(glm::vec3(175.098015269f, 11.7273076323f, 282.707060357f)); - eulersFromEngineer.push_back(glm::vec3(-5.86440719705f, -11.5976507143f, 93.7305032918f)); - eulersFromEngineer.push_back(glm::vec3(212.162310762f, 11.1889030401f, 90.489887929f)); - eulersFromEngineer.push_back(glm::vec3(-183.528298852f, 11.1630787238f, 89.5119846423f)); - eulersFromEngineer.push_back(glm::vec3(-21.5907187136f, -1.16096242449f, 93.4017341288f)); - eulersFromEngineer.push_back(glm::vec3(-230.174545226f, -1.16165879865f, 86.5984269351f)); - eulersFromEngineer.push_back(glm::vec3(-71.3250132734f, 179.345867731f, -73.9245897857f)); - eulersFromEngineer.push_back(glm::vec3(4.4183033408f, 0.0214780500113f, 89.6156394563f)); - eulersFromEngineer.push_back(glm::vec3(-71.3557521294f, -1.96233777224f, 101.311991763f)); - eulersFromEngineer.push_back(glm::vec3(4.52300317986f, -3.2744480538f, 93.9297689938f)); - eulersFromEngineer.push_back(glm::vec3(183.372659045f, 18.4240672177f, 289.089833888f)); - eulersFromEngineer.push_back(glm::vec3(4.69575782766f, -18.4271517191f, 85.8795582505f)); - eulersFromEngineer.push_back(glm::vec3(180.000000381f, 184.227605816f, -90.0000102753f)); - eulersFromEngineer.push_back(glm::vec3(180.000018095f, -4.74360667058f, -89.9994155926f)); - eulersFromEngineer.push_back(glm::vec3(-6.65059725988f, 179.738939306f, -74.3826161322f)); - eulersFromEngineer.push_back(glm::vec3(1.39276173327f, 0.376166992987f, 92.9332563713f)); - eulersFromEngineer.push_back(glm::vec3(290.266370725f, -2.98535083963f, 105.944099833f)); - eulersFromEngineer.push_back(glm::vec3(1.43200712942f, -2.97286285904f, 93.1492284976f)); - eulersFromEngineer.push_back(glm::vec3(194.564263389f, 20.3832505773f, 294.645037769f)); - eulersFromEngineer.push_back(glm::vec3(1.63629620002f, -20.9266621269f, 88.1506158063f)); - eulersFromEngineer.push_back(glm::vec3(-0.0431167069757f, 179.97446471f, -73.261703364f)); - eulersFromEngineer.push_back(glm::vec3(7.60338271732f, -0.342204658844f, 91.3116554499f)); - eulersFromEngineer.push_back(glm::vec3(279.206234833f, -3.4007859075f, 106.246009192f)); - eulersFromEngineer.push_back(glm::vec3(7.72548545025f, -3.33436960581f, 92.0998444782f)); - eulersFromEngineer.push_back(glm::vec3(197.45405684f, 22.6995116972f, 295.695981195f)); - eulersFromEngineer.push_back(glm::vec3(8.21527813645f, -19.794697098f, 86.2545417524f)); - eulersFromEngineer.push_back(glm::vec3(180.000036925f, 168.400465599f, -90.0003196145f)); - eulersFromEngineer.push_back(glm::vec3(7.86635710548e-05f, -2.45210839758f, 89.9992192762f)); - eulersFromEngineer.push_back(glm::vec3(179.999920323f, 4.95709895474f, 269.999215822f)); - eulersFromEngineer.push_back(glm::vec3(241.077352225f, -184.455008741f, -426.541304554f)); - eulersFromEngineer.push_back(glm::vec3(-70.6642196779f, 6.88023375774f, 85.5052784744f)); - eulersFromEngineer.push_back(glm::vec3(51.5850104459f, 4.10357301154f, 96.1370118091f)); - eulersFromEngineer.push_back(glm::vec3(-70.3665845407f, 5.50499763056f, 102.700969646f)); - eulersFromEngineer.push_back(glm::vec3(94.1058470618f, -4.50566341059f, -63.663409373f)); - eulersFromEngineer.push_back(glm::vec3(-70.8795528982f, 7.23642133863f, 82.4215992116f)); - eulersFromEngineer.push_back(glm::vec3(354.986036508f, -0.167802950666f, -73.0700479208f)); - eulersFromEngineer.push_back(glm::vec3(174.972844269f, 0.163203627576f, 73.0320316709f)); - eulersFromEngineer.push_back(glm::vec3(-156.40949683f, -2.25584901219f, 89.478726037f)); - eulersFromEngineer.push_back(glm::vec3(-147.791270237f, -2.25609369727f, 90.5216948763f)); - - qCDebug(animation) << "list of joint quats for engineer"; - for (glm::vec3 bone : eulersFromEngineer) { - glm::quat boneQuat(glm::vec3((bone.x / 180.0f)*PI, (bone.y / 180.0f)*PI, (bone.z / 180.0f)*PI)); - qCDebug(animation) << boneQuat; - } - - - - //qCDebug(animation) << "set the neck and spine2 offsets " << spine2Id << " " << neckId; - //glm::quat leftShoulder(glm::vec3((-81.1050620752f / 180.0f)*PI, (-20.1443891394f / 180.0f)*PI, (100.309499473f / 180.0f)*PI)); - //qCDebug(animation) << "jointRotationOffset = LeftShoulder = (" << leftShoulder << ")"; - //glm::quat testRot2(glm::vec3(PI / 2.0f, 0.0f, PI / 2.0f)); - //qCDebug(animation) << "test rot2 from euler" << testRot2; -} - -const QMap& Rig::getJointRotationOffsets() const { - return _jointRotationOffsets; -} \ No newline at end of file diff --git a/libraries/animation/src/Rig.h b/libraries/animation/src/Rig.h index 1b5826a757..345f335f88 100644 --- a/libraries/animation/src/Rig.h +++ b/libraries/animation/src/Rig.h @@ -128,7 +128,6 @@ public: int getJointStateCount() const; int indexOfJoint(const QString& jointName) const; QString nameOfJoint(int jointIndex) const; - const QMap& getJointRotationOffsets() const; void setModelOffset(const glm::mat4& modelOffsetMat); @@ -232,8 +231,6 @@ public: const AnimContext::DebugAlphaMap& getDebugAlphaMap() const { return _lastContext.getDebugAlphaMap(); } const AnimVariantMap& getAnimVars() const { return _lastAnimVars; } const AnimContext::DebugStateMachineMap& getStateMachineMap() const { return _lastContext.getStateMachineMap(); } - - void setJointRotationOffsets(const QMap& offsets); signals: void onLoadComplete(); @@ -303,8 +300,6 @@ protected: int _rightElbowJointIndex { -1 }; int _rightShoulderJointIndex { -1 }; - QMap _jointRotationOffsets; - glm::vec3 _lastForward; glm::vec3 _lastPosition; glm::vec3 _lastVelocity; @@ -423,7 +418,6 @@ protected: SnapshotBlendPoseHelper _hipsBlendHelper; ControllerParameters _previousControllerParameters; - bool _alreadyInitialized { false }; }; #endif /* defined(__hifi__Rig__) */ diff --git a/libraries/avatars-renderer/src/avatars-renderer/SkeletonModel.cpp b/libraries/avatars-renderer/src/avatars-renderer/SkeletonModel.cpp index 0f18d254c3..3b9e874fba 100644 --- a/libraries/avatars-renderer/src/avatars-renderer/SkeletonModel.cpp +++ b/libraries/avatars-renderer/src/avatars-renderer/SkeletonModel.cpp @@ -18,7 +18,6 @@ #include #include #include -#include #include "Avatar.h" #include "Logging.h" @@ -58,7 +57,6 @@ void SkeletonModel::initJointStates() { const HFMModel& hfmModel = getHFMModel(); glm::mat4 modelOffset = glm::scale(_scale) * glm::translate(_offset); - _rig.setJointRotationOffsets(FSTReader::getJointRotationOffsets(getGeometry()->getMapping())); _rig.initJointStates(hfmModel, modelOffset); { @@ -85,7 +83,6 @@ void SkeletonModel::initJointStates() { // Skeleton may have already been scaled so unscale it _defaultEyeModelPosition = _defaultEyeModelPosition / _scale; - //_rig.setJointRotationOffsets(FSTReader::getJointRotationOffsets(getGeometry()->getMapping())); computeBoundingShape(); Extents meshExtents = getMeshExtents(); diff --git a/libraries/fbx/src/FSTReader.cpp b/libraries/fbx/src/FSTReader.cpp index 10ea9dc964..75596862d2 100644 --- a/libraries/fbx/src/FSTReader.cpp +++ b/libraries/fbx/src/FSTReader.cpp @@ -207,30 +207,6 @@ QVector FSTReader::getScripts(const QUrl& url, const QVariantHash& mapp return scriptPaths; } -QMap FSTReader::getJointRotationOffsets(const QVariantHash& mapping) { - QMap jointRotationOffsets; - if (!mapping.isEmpty() && mapping.contains(JOINT_ROTATION_OFFSET_FIELD) && mapping[JOINT_ROTATION_OFFSET_FIELD].type() == QVariant::Hash) { - auto offsets = mapping[JOINT_ROTATION_OFFSET_FIELD].toHash(); - for (auto itr = offsets.begin(); itr != offsets.end(); itr++) { - QString jointName = itr.key(); - QString line = itr.value().toString(); - auto eulerAngles = line.split(','); - if (eulerAngles.size() == 3) { - float eulerX = eulerAngles[0].mid(1).toFloat(); - float eulerY = eulerAngles[1].toFloat(); - float eulerZ = eulerAngles[2].mid(0, eulerAngles[2].size() - 1).toFloat(); - if (!isNaN(eulerX) && !isNaN(eulerY) && !isNaN(eulerZ)) { - glm::quat rotationOffset = (glm::angleAxis(eulerX * RADIANS_PER_DEGREE, Vectors::UNIT_Y) * - glm::angleAxis(eulerY * RADIANS_PER_DEGREE, Vectors::UNIT_X) * - glm::angleAxis(eulerZ * RADIANS_PER_DEGREE, Vectors::UNIT_Z)); - jointRotationOffsets.insert(jointName, rotationOffset); - } - } - } - } - return jointRotationOffsets; -} - QVariantHash FSTReader::downloadMapping(const QString& url) { QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance(); QNetworkRequest networkRequest = QNetworkRequest(url); diff --git a/libraries/fbx/src/FSTReader.h b/libraries/fbx/src/FSTReader.h index ef649eb4d8..4a8574f0cf 100644 --- a/libraries/fbx/src/FSTReader.h +++ b/libraries/fbx/src/FSTReader.h @@ -14,7 +14,6 @@ #include #include -#include static const QString NAME_FIELD = "name"; static const QString TYPE_FIELD = "type"; @@ -30,7 +29,6 @@ static const QString JOINT_FIELD = "joint"; static const QString FREE_JOINT_FIELD = "freeJoint"; static const QString BLENDSHAPE_FIELD = "bs"; static const QString SCRIPT_FIELD = "script"; -static const QString JOINT_ROTATION_OFFSET_FIELD = "jointRotationOffset"; class FSTReader { public: @@ -53,7 +51,6 @@ public: static ModelType predictModelType(const QVariantHash& mapping); static QVector getScripts(const QUrl& fstUrl, const QVariantHash& mapping = QVariantHash()); - static QMap getJointRotationOffsets(const QVariantHash& mapping); static QString getNameFromType(ModelType modelType); static FSTReader::ModelType getTypeFromName(const QString& name); diff --git a/tools/skeleton-dump/src/SkeletonDumpApp.cpp b/tools/skeleton-dump/src/SkeletonDumpApp.cpp index d1520d81f9..2bb5c758ce 100644 --- a/tools/skeleton-dump/src/SkeletonDumpApp.cpp +++ b/tools/skeleton-dump/src/SkeletonDumpApp.cpp @@ -56,8 +56,7 @@ SkeletonDumpApp::SkeletonDumpApp(int argc, char* argv[]) : QCoreApplication(argc QByteArray blob = file.readAll(); std::unique_ptr geometry(readFBX(blob, QVariantHash())); - QMap jointRotationOffsets; - std::unique_ptr skeleton(new AnimSkeleton(*geometry, jointRotationOffsets)); + std::unique_ptr skeleton(new AnimSkeleton(*geometry)); skeleton->dump(verbose); } From dce040978cda9ef13794d48b8053fc1f1e3a8f4d Mon Sep 17 00:00:00 2001 From: Angus Antley Date: Fri, 9 Nov 2018 01:31:27 -0800 Subject: [PATCH 21/32] works two joint avatar with luis's new code. remains to do the engineer --- libraries/animation/src/AnimSkeleton.cpp | 50 ++++++------------------ libraries/animation/src/AnimSkeleton.h | 2 +- libraries/fbx/src/FBXReader.cpp | 2 + 3 files changed, 14 insertions(+), 40 deletions(-) diff --git a/libraries/animation/src/AnimSkeleton.cpp b/libraries/animation/src/AnimSkeleton.cpp index f0219eb946..a285c100fe 100644 --- a/libraries/animation/src/AnimSkeleton.cpp +++ b/libraries/animation/src/AnimSkeleton.cpp @@ -26,7 +26,10 @@ AnimSkeleton::AnimSkeleton(const HFMModel& hfmModel) { joints.push_back(joint); } - buildSkeletonFromJoints(joints, hfmModel.jointOffsets); + glm::quat offset1(0.5f, 0.5f, 0.5f, -0.5f); + glm::quat offset2(0.7071f, 0.0f, 0.7071f, 0.0f); + + buildSkeletonFromJoints(joints, hfmModel.jointRotationOffsets); // add offsets for spine2 and the neck @@ -44,15 +47,17 @@ AnimSkeleton::AnimSkeleton(const HFMModel& hfmModel) { if (cluster.jointIndex == 62) { qCDebug(animation) << "Neck"; - qCDebug(animation) << "found a joint offset to add " << cluster.jointIndex << " " << jointOffsets[cluster.jointIndex] << " cluster " << cluster.jointIndex; - AnimPose localOffset(jointOffsets[cluster.jointIndex], glm::vec3()); + qCDebug(animation) << "found a joint offset to add " << cluster.jointIndex << " " << offset2 << " cluster " << cluster.jointIndex; + AnimPose localOffset(hfmModel.jointRotationOffsets[cluster.jointIndex], glm::vec3()); + //AnimPose localOffset(offset2, glm::vec3()); cluster.inverseBindMatrix = (glm::mat4)localOffset.inverse() * cluster.inverseBindMatrix; cluster.inverseBindTransform.evalFromRawMatrix(cluster.inverseBindMatrix); } if (cluster.jointIndex == 13) { qCDebug(animation) << "Spine2"; - qCDebug(animation) << "found a joint offset to add " << cluster.jointIndex << " " << jointOffsets[cluster.jointIndex] << " cluster " << cluster.jointIndex; - AnimPose localOffset(jointOffsets[cluster.jointIndex], glm::vec3()); + qCDebug(animation) << "found a joint offset to add " << cluster.jointIndex << " " << offset1<< " cluster " << cluster.jointIndex; + AnimPose localOffset(hfmModel.jointRotationOffsets[cluster.jointIndex], glm::vec3()); + //AnimPose localOffset(offset1, glm::vec3()); cluster.inverseBindMatrix = (glm::mat4)localOffset.inverse() * cluster.inverseBindMatrix; cluster.inverseBindTransform.evalFromRawMatrix(cluster.inverseBindMatrix); } @@ -257,40 +262,7 @@ void AnimSkeleton::buildSkeletonFromJoints(const std::vector& joints, } } - /* - AnimPose newAbsPose; - if (parentIndex >= 0) { - newAbsPose = _absoluteDefaultPoses[parentIndex] * AnimPose(relDefaultPose.rot(),glm::vec3()); - } else { - newAbsPose = relDefaultPose; - } - - // putting the pipeline code is - // 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. - //relDefaultPose = relDefaultPose * _avatarTPoseOffsets[i]; - - QString jointName = getJointName(i); - if (jointOffsets.contains(i)) { - //QString parentIndex = getJointName(parentIndex); - AnimPose localOffset(jointOffsets[i], glm::vec3()); - newAbsPose = newAbsPose * localOffset; - } - if ((parentIndex >= 0) && jointOffsets.contains(parentIndex)) { - AnimPose localParentOffset(jointOffsets[parentIndex], glm::vec3()); - newAbsPose = localParentOffset.inverse() * AnimPose(glm::quat(), relDefaultPose.trans()) * localParentOffset * AnimPose(newAbsPose.rot(), glm::vec3()); - } - - if (parentIndex >= 0) { - relDefaultPose = _absoluteDefaultPoses[parentIndex].inverse() * newAbsPose; - } - _relativeDefaultPoses.push_back(relDefaultPose); - - - _absoluteDefaultPoses.push_back(newAbsPose); - - } - */ + for (int i = 0; i < _jointsSize; i++) { _jointIndicesByName[_joints[i].name] = i; } diff --git a/libraries/animation/src/AnimSkeleton.h b/libraries/animation/src/AnimSkeleton.h index a08276d2cb..f06813e51f 100644 --- a/libraries/animation/src/AnimSkeleton.h +++ b/libraries/animation/src/AnimSkeleton.h @@ -23,7 +23,7 @@ public: using Pointer = std::shared_ptr; using ConstPointer = std::shared_ptr; - explicit AnimSkeleton(const HFMModel& hfmModel, const QMap jointOffsets); + explicit AnimSkeleton(const HFMModel& hfmModel); explicit AnimSkeleton(const std::vector& joints, const QMap jointOffsets); int nameToJointIndex(const QString& jointName) const; diff --git a/libraries/fbx/src/FBXReader.cpp b/libraries/fbx/src/FBXReader.cpp index 6ec7e0e73c..281759a9e9 100644 --- a/libraries/fbx/src/FBXReader.cpp +++ b/libraries/fbx/src/FBXReader.cpp @@ -2027,6 +2027,8 @@ HFMModel* FBXReader::extractHFMModel(const QVariantHash& mapping, const QString& } qCDebug(modelformat) << "Joint Rotation Offset added to Rig._jointRotationOffsets : " << " jointName: " << jointName << " jointIndex: " << jointIndex << " rotation offset: " << rotationOffset; } + hfmModel.jointRotationOffsets.insert(13, glm::quat(0.5f, 0.5f, 0.5f, -0.5f)); + hfmModel.jointRotationOffsets.insert(62, glm::quat(0.7071f, 0.0f, -0.7071f, 0.0f)); return hfmModelPtr; } From fd365b5509e3e3b6cfa37bf4bffba95411dd8e5a Mon Sep 17 00:00:00 2001 From: Angus Antley Date: Fri, 9 Nov 2018 07:22:36 -0800 Subject: [PATCH 22/32] added debug print to fbx reader to see if the fst is being read correctly --- libraries/animation/src/AnimSkeleton.cpp | 2 +- libraries/fbx/src/FBXReader.cpp | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/libraries/animation/src/AnimSkeleton.cpp b/libraries/animation/src/AnimSkeleton.cpp index a285c100fe..1d4d662928 100644 --- a/libraries/animation/src/AnimSkeleton.cpp +++ b/libraries/animation/src/AnimSkeleton.cpp @@ -27,7 +27,7 @@ AnimSkeleton::AnimSkeleton(const HFMModel& hfmModel) { } glm::quat offset1(0.5f, 0.5f, 0.5f, -0.5f); - glm::quat offset2(0.7071f, 0.0f, 0.7071f, 0.0f); + glm::quat offset2(0.7071f, 0.0f, -0.7071f, 0.0f); buildSkeletonFromJoints(joints, hfmModel.jointRotationOffsets); // add offsets for spine2 and the neck diff --git a/libraries/fbx/src/FBXReader.cpp b/libraries/fbx/src/FBXReader.cpp index 281759a9e9..6ae2b69e60 100644 --- a/libraries/fbx/src/FBXReader.cpp +++ b/libraries/fbx/src/FBXReader.cpp @@ -632,10 +632,14 @@ QMap getJointRotationOffsets(const QVariantHash& mapping) { if (!isNaN(quatX) && !isNaN(quatY) && !isNaN(quatZ) && !isNaN(quatW)) { glm::quat rotationOffset = glm::quat(quatW, quatX, quatY, quatZ); jointRotationOffsets.insert(jointName, rotationOffset); + } } + qCDebug(modelformat) << "found an offset in fst"; } + qCDebug(modelformat) << "found an offset in fst 2"; } + qCDebug(modelformat) << "found an offset in fst 3"; return jointRotationOffsets; } From 5bb2378cd90a44e921e4b24cde6613a6e9510d77 Mon Sep 17 00:00:00 2001 From: amantley Date: Fri, 9 Nov 2018 15:10:14 -0800 Subject: [PATCH 23/32] changes to get the engineer working --- .../qml/hifi/tablet/OpenVrConfiguration.qml | 4 +-- interface/src/avatar/MyAvatar.cpp | 2 +- libraries/animation/src/AnimSkeleton.cpp | 25 ++++++++++++++++--- libraries/fbx/src/FBXReader.cpp | 4 +-- 4 files changed, 27 insertions(+), 8 deletions(-) diff --git a/interface/resources/qml/hifi/tablet/OpenVrConfiguration.qml b/interface/resources/qml/hifi/tablet/OpenVrConfiguration.qml index 2fc5cc4196..f91642105f 100644 --- a/interface/resources/qml/hifi/tablet/OpenVrConfiguration.qml +++ b/interface/resources/qml/hifi/tablet/OpenVrConfiguration.qml @@ -9,9 +9,9 @@ import QtQuick 2.5 import QtGraphicalEffects 1.0 -import stylesUit 1.0 +import "../../styles-uit" import "../../controls" -import controlsUit 1.0 as HifiControls +import "../../controls-uit" as HifiControls import "." diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 502be9d57c..8d47591d40 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -431,7 +431,7 @@ void MyAvatar::reset(bool andRecenter, bool andReload, bool andHead) { _wasPushing = _isPushing = _isBraking = false; _follow.deactivate(); if (andReload) { - //_skeletonModel->reset(); + _skeletonModel->reset(); } if (andHead) { // which drives camera in desktop getHead()->reset(); diff --git a/libraries/animation/src/AnimSkeleton.cpp b/libraries/animation/src/AnimSkeleton.cpp index 1d4d662928..aec969af69 100644 --- a/libraries/animation/src/AnimSkeleton.cpp +++ b/libraries/animation/src/AnimSkeleton.cpp @@ -31,8 +31,11 @@ AnimSkeleton::AnimSkeleton(const HFMModel& hfmModel) { buildSkeletonFromJoints(joints, hfmModel.jointRotationOffsets); // add offsets for spine2 and the neck - - + static bool once = true; + qCDebug(animation) << "the hfm model path is " << hfmModel.originalURL; + if (once && hfmModel.originalURL == "/angus/avatars/engineer_hifinames/engineer_hifinames/engineer_hifinames.fbx") { + //if (once && hfmModel.originalURL == "/angus/avatars/pei_z_neckNexX_spine2NegY_fwd/pei_z_neckNexX_spine2NegY_fwd/pei_z_neckNexX_spine2NegY_fwd.fbx") { + once = false; for (int i = 0; i < (int)hfmModel.meshes.size(); i++) { const HFMMesh& mesh = hfmModel.meshes.at(i); for (int j = 0; j < mesh.clusters.size(); j++) { @@ -44,6 +47,15 @@ AnimSkeleton::AnimSkeleton(const HFMModel& hfmModel) { // AJT: mutate bind pose! this allows us to oreint the skeleton back into the authored orientaiton before // rendering, with no runtime overhead. // this works if clusters match joints one for one. + if (hfmModel.jointRotationOffsets.contains(cluster.jointIndex)) { + qCDebug(animation) << "found a joint offset to add " << cluster.jointIndex << " " << offset2 << " cluster " << cluster.jointIndex; + AnimPose localOffset(hfmModel.jointRotationOffsets[cluster.jointIndex], glm::vec3()); + //AnimPose localOffset(offset2, glm::vec3()); + cluster.inverseBindMatrix = (glm::mat4)localOffset.inverse() * cluster.inverseBindMatrix; + cluster.inverseBindTransform.evalFromRawMatrix(cluster.inverseBindMatrix); + } + + /* if (cluster.jointIndex == 62) { qCDebug(animation) << "Neck"; @@ -55,14 +67,16 @@ AnimSkeleton::AnimSkeleton(const HFMModel& hfmModel) { } if (cluster.jointIndex == 13) { qCDebug(animation) << "Spine2"; - qCDebug(animation) << "found a joint offset to add " << cluster.jointIndex << " " << offset1<< " cluster " << cluster.jointIndex; + qCDebug(animation) << "found a joint offset to add " << cluster.jointIndex << " " << offset1 << " cluster " << cluster.jointIndex; AnimPose localOffset(hfmModel.jointRotationOffsets[cluster.jointIndex], glm::vec3()); //AnimPose localOffset(offset1, glm::vec3()); cluster.inverseBindMatrix = (glm::mat4)localOffset.inverse() * cluster.inverseBindMatrix; cluster.inverseBindTransform.evalFromRawMatrix(cluster.inverseBindMatrix); } + */ } } + } @@ -247,6 +261,7 @@ void AnimSkeleton::buildSkeletonFromJoints(const std::vector& joints, } } + for (int k = 0; k < _jointsSize; k++) { int parentIndex2 = getParentIndex(k); if (jointOffsets.contains(k)) { @@ -261,6 +276,10 @@ void AnimSkeleton::buildSkeletonFromJoints(const std::vector& joints, _relativeDefaultPoses.push_back(_absoluteDefaultPoses[k]); } } + + // re-compute relative poses + //_relativeDefaultPoses = _absoluteDefaultPoses; + //convertAbsolutePosesToRelative(_relativeDefaultPoses); for (int i = 0; i < _jointsSize; i++) { diff --git a/libraries/fbx/src/FBXReader.cpp b/libraries/fbx/src/FBXReader.cpp index 6ae2b69e60..6213cc458b 100644 --- a/libraries/fbx/src/FBXReader.cpp +++ b/libraries/fbx/src/FBXReader.cpp @@ -2031,8 +2031,8 @@ HFMModel* FBXReader::extractHFMModel(const QVariantHash& mapping, const QString& } qCDebug(modelformat) << "Joint Rotation Offset added to Rig._jointRotationOffsets : " << " jointName: " << jointName << " jointIndex: " << jointIndex << " rotation offset: " << rotationOffset; } - hfmModel.jointRotationOffsets.insert(13, glm::quat(0.5f, 0.5f, 0.5f, -0.5f)); - hfmModel.jointRotationOffsets.insert(62, glm::quat(0.7071f, 0.0f, -0.7071f, 0.0f)); + //hfmModel.jointRotationOffsets.insert(13, glm::quat(0.5f, 0.5f, 0.5f, -0.5f)); + //hfmModel.jointRotationOffsets.insert(62, glm::quat(0.7071f, 0.0f, -0.7071f, 0.0f)); return hfmModelPtr; } From 92befbc5bf7371ac775f468e6969af1fd8d6745f Mon Sep 17 00:00:00 2001 From: amantley Date: Mon, 12 Nov 2018 11:12:56 -0800 Subject: [PATCH 24/32] implementing backup of cluster matrices --- libraries/fbx/src/FBX.h | 1 + libraries/fbx/src/FBXReader.cpp | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/libraries/fbx/src/FBX.h b/libraries/fbx/src/FBX.h index d4072f03d7..943db4b7fe 100644 --- a/libraries/fbx/src/FBX.h +++ b/libraries/fbx/src/FBX.h @@ -349,6 +349,7 @@ public: Extents meshExtents; QVector animationFrames; + std::vector> clusterBindMatrixOriginalValues; int getJointIndex(const QString& name) const { return jointIndices.value(name) - 1; } QStringList getJointNames() const; diff --git a/libraries/fbx/src/FBXReader.cpp b/libraries/fbx/src/FBXReader.cpp index 6213cc458b..a8cbcdcf25 100644 --- a/libraries/fbx/src/FBXReader.cpp +++ b/libraries/fbx/src/FBXReader.cpp @@ -2034,6 +2034,14 @@ HFMModel* FBXReader::extractHFMModel(const QVariantHash& mapping, const QString& //hfmModel.jointRotationOffsets.insert(13, glm::quat(0.5f, 0.5f, 0.5f, -0.5f)); //hfmModel.jointRotationOffsets.insert(62, glm::quat(0.7071f, 0.0f, -0.7071f, 0.0f)); + for (int i = 0; i < (int)hfmModel.meshes.size(); i++) { + const HFMMesh& mesh = hfmModel.meshes.at(i); + for (int j = 0; j < mesh.clusters.size(); j++) { + const HFMCluster& cluster = mesh.clusters.at(j); + hfmModel.clusterBindMatrixOriginalValues[i][cluster.jointIndex] = cluster.inverseBindMatrix; + } + } + return hfmModelPtr; } From bcd651a65dc5cbf690b1f12e4ded566fc53988a7 Mon Sep 17 00:00:00 2001 From: amantley Date: Mon, 12 Nov 2018 14:39:48 -0800 Subject: [PATCH 25/32] adding the member variable to keep track of the orig bind matrices to fbx.h --- libraries/animation/src/AnimSkeleton.cpp | 4 ++++ libraries/fbx/src/FBX.h | 2 +- libraries/fbx/src/FBXReader.cpp | 11 ++++++++--- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/libraries/animation/src/AnimSkeleton.cpp b/libraries/animation/src/AnimSkeleton.cpp index aec969af69..aec4ae6dda 100644 --- a/libraries/animation/src/AnimSkeleton.cpp +++ b/libraries/animation/src/AnimSkeleton.cpp @@ -52,6 +52,10 @@ AnimSkeleton::AnimSkeleton(const HFMModel& hfmModel) { AnimPose localOffset(hfmModel.jointRotationOffsets[cluster.jointIndex], glm::vec3()); //AnimPose localOffset(offset2, glm::vec3()); cluster.inverseBindMatrix = (glm::mat4)localOffset.inverse() * cluster.inverseBindMatrix; + qCDebug(animation) << "the new bind matrix num: " << cluster.jointIndex << cluster.inverseBindMatrix; + //if ((hfmModel.clusterBindMatrixOriginalValues.size() > i) && (hfmModel.clusterBindMatrixOriginalValues[i].contains(cluster.jointIndex))) { + // qCDebug(animation) << "the saved orig matrix num: " << cluster.jointIndex << hfmModel.clusterBindMatrixOriginalValues[i][cluster.jointIndex]; + //} cluster.inverseBindTransform.evalFromRawMatrix(cluster.inverseBindMatrix); } diff --git a/libraries/fbx/src/FBX.h b/libraries/fbx/src/FBX.h index 943db4b7fe..342f3c456a 100644 --- a/libraries/fbx/src/FBX.h +++ b/libraries/fbx/src/FBX.h @@ -349,7 +349,7 @@ public: Extents meshExtents; QVector animationFrames; - std::vector> clusterBindMatrixOriginalValues; + std::vector> clusterBindMatrixOriginalValues; int getJointIndex(const QString& name) const { return jointIndices.value(name) - 1; } QStringList getJointNames() const; diff --git a/libraries/fbx/src/FBXReader.cpp b/libraries/fbx/src/FBXReader.cpp index a8cbcdcf25..ed5e349957 100644 --- a/libraries/fbx/src/FBXReader.cpp +++ b/libraries/fbx/src/FBXReader.cpp @@ -2033,15 +2033,20 @@ HFMModel* FBXReader::extractHFMModel(const QVariantHash& mapping, const QString& } //hfmModel.jointRotationOffsets.insert(13, glm::quat(0.5f, 0.5f, 0.5f, -0.5f)); //hfmModel.jointRotationOffsets.insert(62, glm::quat(0.7071f, 0.0f, -0.7071f, 0.0f)); - + /* for (int i = 0; i < (int)hfmModel.meshes.size(); i++) { const HFMMesh& mesh = hfmModel.meshes.at(i); + QMap tempBindMat; for (int j = 0; j < mesh.clusters.size(); j++) { const HFMCluster& cluster = mesh.clusters.at(j); - hfmModel.clusterBindMatrixOriginalValues[i][cluster.jointIndex] = cluster.inverseBindMatrix; + tempBindMat.insert(cluster.jointIndex, cluster.inverseBindMatrix); + //if(hfmModel.clusterBindMatrixOriginalValues[i]) + //hfmModel.clusterBindMatrixOriginalValues[i].insert(cluster.jointIndex,Matrices::IDENTITY);// cluster.inverseBindMatrix; + //glm::mat4 testMat = cluster.inverseBindMatrix; } + hfmModel.clusterBindMatrixOriginalValues.push_back(tempBindMat); } - + */ return hfmModelPtr; } From f83edf4b7ffa373c8bac88214eb1b0771ca26194 Mon Sep 17 00:00:00 2001 From: amantley Date: Tue, 13 Nov 2018 11:29:01 -0800 Subject: [PATCH 26/32] joint offsets working. reset working. to do: handling extra joints --- libraries/animation/src/AnimSkeleton.cpp | 12 ++++++------ libraries/fbx/src/FBX.h | 2 +- libraries/fbx/src/FBXReader.cpp | 7 +++---- 3 files changed, 10 insertions(+), 11 deletions(-) diff --git a/libraries/animation/src/AnimSkeleton.cpp b/libraries/animation/src/AnimSkeleton.cpp index aec4ae6dda..790c898674 100644 --- a/libraries/animation/src/AnimSkeleton.cpp +++ b/libraries/animation/src/AnimSkeleton.cpp @@ -33,7 +33,7 @@ AnimSkeleton::AnimSkeleton(const HFMModel& hfmModel) { // add offsets for spine2 and the neck static bool once = true; qCDebug(animation) << "the hfm model path is " << hfmModel.originalURL; - if (once && hfmModel.originalURL == "/angus/avatars/engineer_hifinames/engineer_hifinames/engineer_hifinames.fbx") { + //if (once && hfmModel.originalURL == "/angus/avatars/engineer_hifinames/engineer_hifinames/engineer_hifinames.fbx") { //if (once && hfmModel.originalURL == "/angus/avatars/pei_z_neckNexX_spine2NegY_fwd/pei_z_neckNexX_spine2NegY_fwd/pei_z_neckNexX_spine2NegY_fwd.fbx") { once = false; for (int i = 0; i < (int)hfmModel.meshes.size(); i++) { @@ -51,11 +51,11 @@ AnimSkeleton::AnimSkeleton(const HFMModel& hfmModel) { qCDebug(animation) << "found a joint offset to add " << cluster.jointIndex << " " << offset2 << " cluster " << cluster.jointIndex; AnimPose localOffset(hfmModel.jointRotationOffsets[cluster.jointIndex], glm::vec3()); //AnimPose localOffset(offset2, glm::vec3()); - cluster.inverseBindMatrix = (glm::mat4)localOffset.inverse() * cluster.inverseBindMatrix; + cluster.inverseBindMatrix = (glm::mat4)localOffset.inverse() * hfmModel.clusterBindMatrixOriginalValues[i][j]; qCDebug(animation) << "the new bind matrix num: " << cluster.jointIndex << cluster.inverseBindMatrix; - //if ((hfmModel.clusterBindMatrixOriginalValues.size() > i) && (hfmModel.clusterBindMatrixOriginalValues[i].contains(cluster.jointIndex))) { - // qCDebug(animation) << "the saved orig matrix num: " << cluster.jointIndex << hfmModel.clusterBindMatrixOriginalValues[i][cluster.jointIndex]; - //} + if ((hfmModel.clusterBindMatrixOriginalValues.size() > i) && (hfmModel.clusterBindMatrixOriginalValues[i].size() > cluster.jointIndex)) { + qCDebug(animation) << "the saved orig matrix num: " << cluster.jointIndex << hfmModel.clusterBindMatrixOriginalValues[i][j]; + } cluster.inverseBindTransform.evalFromRawMatrix(cluster.inverseBindMatrix); } @@ -80,7 +80,7 @@ AnimSkeleton::AnimSkeleton(const HFMModel& hfmModel) { */ } } - } + //} diff --git a/libraries/fbx/src/FBX.h b/libraries/fbx/src/FBX.h index 342f3c456a..943db4b7fe 100644 --- a/libraries/fbx/src/FBX.h +++ b/libraries/fbx/src/FBX.h @@ -349,7 +349,7 @@ public: Extents meshExtents; QVector animationFrames; - std::vector> clusterBindMatrixOriginalValues; + std::vector> clusterBindMatrixOriginalValues; int getJointIndex(const QString& name) const { return jointIndices.value(name) - 1; } QStringList getJointNames() const; diff --git a/libraries/fbx/src/FBXReader.cpp b/libraries/fbx/src/FBXReader.cpp index ed5e349957..7a49874abb 100644 --- a/libraries/fbx/src/FBXReader.cpp +++ b/libraries/fbx/src/FBXReader.cpp @@ -2033,20 +2033,19 @@ HFMModel* FBXReader::extractHFMModel(const QVariantHash& mapping, const QString& } //hfmModel.jointRotationOffsets.insert(13, glm::quat(0.5f, 0.5f, 0.5f, -0.5f)); //hfmModel.jointRotationOffsets.insert(62, glm::quat(0.7071f, 0.0f, -0.7071f, 0.0f)); - /* + for (int i = 0; i < (int)hfmModel.meshes.size(); i++) { const HFMMesh& mesh = hfmModel.meshes.at(i); - QMap tempBindMat; + vector tempBindMat; for (int j = 0; j < mesh.clusters.size(); j++) { const HFMCluster& cluster = mesh.clusters.at(j); - tempBindMat.insert(cluster.jointIndex, cluster.inverseBindMatrix); + tempBindMat.push_back(cluster.inverseBindMatrix); //if(hfmModel.clusterBindMatrixOriginalValues[i]) //hfmModel.clusterBindMatrixOriginalValues[i].insert(cluster.jointIndex,Matrices::IDENTITY);// cluster.inverseBindMatrix; //glm::mat4 testMat = cluster.inverseBindMatrix; } hfmModel.clusterBindMatrixOriginalValues.push_back(tempBindMat); } - */ return hfmModelPtr; } From c80ade98ecfcea0d1a8eeb712647a033e78cd660 Mon Sep 17 00:00:00 2001 From: amantley Date: Tue, 13 Nov 2018 12:10:10 -0800 Subject: [PATCH 27/32] cleaned up white space --- .../qml/hifi/tablet/OpenVrConfiguration.qml | 4 +- interface/src/avatar/MySkeletonModel.cpp | 3 - libraries/animation/src/AnimClip.cpp | 2 - libraries/animation/src/AnimSkeleton.cpp | 84 +++++-------------- libraries/fbx/src/FBXReader.cpp | 13 +-- tools/skeleton-dump/src/SkeletonDumpApp.cpp | 2 - 6 files changed, 24 insertions(+), 84 deletions(-) diff --git a/interface/resources/qml/hifi/tablet/OpenVrConfiguration.qml b/interface/resources/qml/hifi/tablet/OpenVrConfiguration.qml index f91642105f..2fc5cc4196 100644 --- a/interface/resources/qml/hifi/tablet/OpenVrConfiguration.qml +++ b/interface/resources/qml/hifi/tablet/OpenVrConfiguration.qml @@ -9,9 +9,9 @@ import QtQuick 2.5 import QtGraphicalEffects 1.0 -import "../../styles-uit" +import stylesUit 1.0 import "../../controls" -import "../../controls-uit" as HifiControls +import controlsUit 1.0 as HifiControls import "." diff --git a/interface/src/avatar/MySkeletonModel.cpp b/interface/src/avatar/MySkeletonModel.cpp index 720bbd1066..2a21f78b21 100644 --- a/interface/src/avatar/MySkeletonModel.cpp +++ b/interface/src/avatar/MySkeletonModel.cpp @@ -90,7 +90,6 @@ static AnimPose computeHipsInSensorFrame(MyAvatar* myAvatar, bool isFlying) { // Called within Model::simulate call, below. void MySkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) { - const HFMModel& hfmModel = getHFMModel(); Head* head = _owningAvatar->getHead(); @@ -230,7 +229,6 @@ void MySkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) { params.primaryControllerFlags[Rig::PrimaryControllerType_Hips] = (uint8_t)Rig::ControllerFlags::Enabled | (uint8_t)Rig::ControllerFlags::Estimated; // set spine2 if we have hand controllers - //qCDebug(interfaceapp) << "spine 2 joint offset " << jointOffsetMap[13]; if (myAvatar->getControllerPoseInAvatarFrame(controller::Action::RIGHT_HAND).isValid() && myAvatar->getControllerPoseInAvatarFrame(controller::Action::LEFT_HAND).isValid() && !(params.primaryControllerFlags[Rig::PrimaryControllerType_Spine2] & (uint8_t)Rig::ControllerFlags::Enabled)) { @@ -241,7 +239,6 @@ void MySkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) { bool spine2Exists = _rig.getAbsoluteJointPoseInRigFrame(_rig.indexOfJoint("Spine2"), currentSpine2Pose); bool headExists = _rig.getAbsoluteJointPoseInRigFrame(_rig.indexOfJoint("Head"), currentHeadPose); bool hipsExists = _rig.getAbsoluteJointPoseInRigFrame(_rig.indexOfJoint("Hips"), currentHipsPose); - if (spine2Exists && headExists && hipsExists) { AnimPose rigSpaceYaw(myAvatar->getSpine2RotationRigSpace()); diff --git a/libraries/animation/src/AnimClip.cpp b/libraries/animation/src/AnimClip.cpp index a3d55726d6..eeac8fadce 100644 --- a/libraries/animation/src/AnimClip.cpp +++ b/libraries/animation/src/AnimClip.cpp @@ -101,10 +101,8 @@ void AnimClip::copyFromNetworkAnim() { // build a mapping from animation joint indices to skeleton joint indices. // by matching joints with the same name. - const HFMModel& hfmModel = _networkAnim->getHFMModel(); AnimSkeleton animSkeleton(hfmModel); - const auto animJointCount = animSkeleton.getNumJoints(); const auto skeletonJointCount = _skeleton->getNumJoints(); std::vector jointMap; diff --git a/libraries/animation/src/AnimSkeleton.cpp b/libraries/animation/src/AnimSkeleton.cpp index 790c898674..85c9999788 100644 --- a/libraries/animation/src/AnimSkeleton.cpp +++ b/libraries/animation/src/AnimSkeleton.cpp @@ -15,76 +15,38 @@ #include #include "AnimationLogging.h" -static bool notBound = true; AnimSkeleton::AnimSkeleton(const HFMModel& hfmModel) { - qCDebug(animation) << "in the animSkeleton"; // convert to std::vector of joints std::vector joints; joints.reserve(hfmModel.joints.size()); for (auto& joint : hfmModel.joints) { joints.push_back(joint); } - - glm::quat offset1(0.5f, 0.5f, 0.5f, -0.5f); - glm::quat offset2(0.7071f, 0.0f, -0.7071f, 0.0f); - buildSkeletonFromJoints(joints, hfmModel.jointRotationOffsets); - // add offsets for spine2 and the neck - static bool once = true; - qCDebug(animation) << "the hfm model path is " << hfmModel.originalURL; - //if (once && hfmModel.originalURL == "/angus/avatars/engineer_hifinames/engineer_hifinames/engineer_hifinames.fbx") { - //if (once && hfmModel.originalURL == "/angus/avatars/pei_z_neckNexX_spine2NegY_fwd/pei_z_neckNexX_spine2NegY_fwd/pei_z_neckNexX_spine2NegY_fwd.fbx") { - once = false; - for (int i = 0; i < (int)hfmModel.meshes.size(); i++) { - const HFMMesh& mesh = hfmModel.meshes.at(i); - for (int j = 0; j < mesh.clusters.size(); j++) { + for (int i = 0; i < (int)hfmModel.meshes.size(); i++) { + const HFMMesh& mesh = hfmModel.meshes.at(i); + for (int j = 0; j < mesh.clusters.size(); j++) { - // cast into a non-const reference, so we can mutate the FBXCluster - HFMCluster& cluster = const_cast(mesh.clusters.at(j)); + // cast into a non-const reference, so we can mutate the FBXCluster + HFMCluster& cluster = const_cast(mesh.clusters.at(j)); - // AJT: mutate bind pose! this allows us to oreint the skeleton back into the authored orientaiton before - // rendering, with no runtime overhead. - // this works if clusters match joints one for one. - if (hfmModel.jointRotationOffsets.contains(cluster.jointIndex)) { - qCDebug(animation) << "found a joint offset to add " << cluster.jointIndex << " " << offset2 << " cluster " << cluster.jointIndex; - AnimPose localOffset(hfmModel.jointRotationOffsets[cluster.jointIndex], glm::vec3()); - //AnimPose localOffset(offset2, glm::vec3()); - cluster.inverseBindMatrix = (glm::mat4)localOffset.inverse() * hfmModel.clusterBindMatrixOriginalValues[i][j]; - qCDebug(animation) << "the new bind matrix num: " << cluster.jointIndex << cluster.inverseBindMatrix; - if ((hfmModel.clusterBindMatrixOriginalValues.size() > i) && (hfmModel.clusterBindMatrixOriginalValues[i].size() > cluster.jointIndex)) { - qCDebug(animation) << "the saved orig matrix num: " << cluster.jointIndex << hfmModel.clusterBindMatrixOriginalValues[i][j]; - } - cluster.inverseBindTransform.evalFromRawMatrix(cluster.inverseBindMatrix); + // AJT: mutate bind pose! this allows us to oreint the skeleton back into the authored orientaiton before + // rendering, with no runtime overhead. + if (hfmModel.jointRotationOffsets.contains(cluster.jointIndex)) { + qCDebug(animation) << "found a cluster " << cluster.jointIndex; + AnimPose localOffset(hfmModel.jointRotationOffsets[cluster.jointIndex], glm::vec3()); + cluster.inverseBindMatrix = (glm::mat4)localOffset.inverse() * hfmModel.clusterBindMatrixOriginalValues[i][j]; + qCDebug(animation) << "the new bind matrix num: " << cluster.jointIndex << cluster.inverseBindMatrix; + if ((hfmModel.clusterBindMatrixOriginalValues.size() > i) && (hfmModel.clusterBindMatrixOriginalValues[i].size() > cluster.jointIndex)) { + qCDebug(animation) << "the saved orig matrix num: " << cluster.jointIndex << hfmModel.clusterBindMatrixOriginalValues[i][j]; } - - /* - - if (cluster.jointIndex == 62) { - qCDebug(animation) << "Neck"; - qCDebug(animation) << "found a joint offset to add " << cluster.jointIndex << " " << offset2 << " cluster " << cluster.jointIndex; - AnimPose localOffset(hfmModel.jointRotationOffsets[cluster.jointIndex], glm::vec3()); - //AnimPose localOffset(offset2, glm::vec3()); - cluster.inverseBindMatrix = (glm::mat4)localOffset.inverse() * cluster.inverseBindMatrix; - cluster.inverseBindTransform.evalFromRawMatrix(cluster.inverseBindMatrix); - } - if (cluster.jointIndex == 13) { - qCDebug(animation) << "Spine2"; - qCDebug(animation) << "found a joint offset to add " << cluster.jointIndex << " " << offset1 << " cluster " << cluster.jointIndex; - AnimPose localOffset(hfmModel.jointRotationOffsets[cluster.jointIndex], glm::vec3()); - //AnimPose localOffset(offset1, 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& joints, const QMap jointOffsets) { buildSkeletonFromJoints(joints, jointOffsets); @@ -253,19 +215,15 @@ void AnimSkeleton::buildSkeletonFromJoints(const std::vector& joints, qCDebug(animation) << "relative default pose for joint " << i << " " << relDefaultPose.trans() << " " << relDefaultPose.rot(); int parentIndex = getParentIndex(i); - AnimPose newAbsPose; if (parentIndex >= 0) { newAbsPose = _absoluteDefaultPoses[parentIndex] * relDefaultPose; - _absoluteDefaultPoses.push_back(newAbsPose); } else { - _absoluteDefaultPoses.push_back(relDefaultPose); } - } - + for (int k = 0; k < _jointsSize; k++) { int parentIndex2 = getParentIndex(k); if (jointOffsets.contains(k)) { @@ -273,19 +231,15 @@ void AnimSkeleton::buildSkeletonFromJoints(const std::vector& joints, _absoluteDefaultPoses[k] = _absoluteDefaultPoses[k] * localOffset; } if (parentIndex2 >= 0) { - _relativeDefaultPoses.push_back(_absoluteDefaultPoses[parentIndex2].inverse() * _absoluteDefaultPoses[k]); } else { - _relativeDefaultPoses.push_back(_absoluteDefaultPoses[k]); } } - - // re-compute relative poses + // re-compute relative poses //_relativeDefaultPoses = _absoluteDefaultPoses; //convertAbsolutePosesToRelative(_relativeDefaultPoses); - for (int i = 0; i < _jointsSize; i++) { _jointIndicesByName[_joints[i].name] = i; } diff --git a/libraries/fbx/src/FBXReader.cpp b/libraries/fbx/src/FBXReader.cpp index 7a49874abb..da0fe4fe01 100644 --- a/libraries/fbx/src/FBXReader.cpp +++ b/libraries/fbx/src/FBXReader.cpp @@ -632,14 +632,10 @@ QMap getJointRotationOffsets(const QVariantHash& mapping) { if (!isNaN(quatX) && !isNaN(quatY) && !isNaN(quatZ) && !isNaN(quatW)) { glm::quat rotationOffset = glm::quat(quatW, quatX, quatY, quatZ); jointRotationOffsets.insert(jointName, rotationOffset); - } } - qCDebug(modelformat) << "found an offset in fst"; } - qCDebug(modelformat) << "found an offset in fst 2"; } - qCDebug(modelformat) << "found an offset in fst 3"; return jointRotationOffsets; } @@ -2031,18 +2027,15 @@ HFMModel* FBXReader::extractHFMModel(const QVariantHash& mapping, const QString& } qCDebug(modelformat) << "Joint Rotation Offset added to Rig._jointRotationOffsets : " << " jointName: " << jointName << " jointIndex: " << jointIndex << " rotation offset: " << rotationOffset; } - //hfmModel.jointRotationOffsets.insert(13, glm::quat(0.5f, 0.5f, 0.5f, -0.5f)); - //hfmModel.jointRotationOffsets.insert(62, glm::quat(0.7071f, 0.0f, -0.7071f, 0.0f)); - + + // create a backup copy of the bindposes, + // these are needed when we recompute the bindpose offsets on reset. for (int i = 0; i < (int)hfmModel.meshes.size(); i++) { const HFMMesh& mesh = hfmModel.meshes.at(i); vector tempBindMat; for (int j = 0; j < mesh.clusters.size(); j++) { const HFMCluster& cluster = mesh.clusters.at(j); tempBindMat.push_back(cluster.inverseBindMatrix); - //if(hfmModel.clusterBindMatrixOriginalValues[i]) - //hfmModel.clusterBindMatrixOriginalValues[i].insert(cluster.jointIndex,Matrices::IDENTITY);// cluster.inverseBindMatrix; - //glm::mat4 testMat = cluster.inverseBindMatrix; } hfmModel.clusterBindMatrixOriginalValues.push_back(tempBindMat); } diff --git a/tools/skeleton-dump/src/SkeletonDumpApp.cpp b/tools/skeleton-dump/src/SkeletonDumpApp.cpp index 2bb5c758ce..10b13aef36 100644 --- a/tools/skeleton-dump/src/SkeletonDumpApp.cpp +++ b/tools/skeleton-dump/src/SkeletonDumpApp.cpp @@ -54,10 +54,8 @@ SkeletonDumpApp::SkeletonDumpApp(int argc, char* argv[]) : QCoreApplication(argc return; } QByteArray blob = file.readAll(); - std::unique_ptr geometry(readFBX(blob, QVariantHash())); std::unique_ptr skeleton(new AnimSkeleton(*geometry)); - skeleton->dump(verbose); } From a8d7b0503d10f6d0e7b2104f1f7e921e2558a8f1 Mon Sep 17 00:00:00 2001 From: amantley Date: Tue, 13 Nov 2018 14:24:18 -0800 Subject: [PATCH 28/32] removed more cruft --- libraries/animation/src/AnimSkeleton.cpp | 21 +++++---------------- libraries/fbx/src/FBXReader.cpp | 6 +++--- 2 files changed, 8 insertions(+), 19 deletions(-) diff --git a/libraries/animation/src/AnimSkeleton.cpp b/libraries/animation/src/AnimSkeleton.cpp index 85c9999788..a9dab701ed 100644 --- a/libraries/animation/src/AnimSkeleton.cpp +++ b/libraries/animation/src/AnimSkeleton.cpp @@ -35,12 +35,9 @@ AnimSkeleton::AnimSkeleton(const HFMModel& hfmModel) { // AJT: mutate bind pose! this allows us to oreint the skeleton back into the authored orientaiton before // rendering, with no runtime overhead. if (hfmModel.jointRotationOffsets.contains(cluster.jointIndex)) { - qCDebug(animation) << "found a cluster " << cluster.jointIndex; AnimPose localOffset(hfmModel.jointRotationOffsets[cluster.jointIndex], glm::vec3()); - cluster.inverseBindMatrix = (glm::mat4)localOffset.inverse() * hfmModel.clusterBindMatrixOriginalValues[i][j]; - qCDebug(animation) << "the new bind matrix num: " << cluster.jointIndex << cluster.inverseBindMatrix; - if ((hfmModel.clusterBindMatrixOriginalValues.size() > i) && (hfmModel.clusterBindMatrixOriginalValues[i].size() > cluster.jointIndex)) { - qCDebug(animation) << "the saved orig matrix num: " << cluster.jointIndex << hfmModel.clusterBindMatrixOriginalValues[i][j]; + if ((hfmModel.clusterBindMatrixOriginalValues.size() > i) && (hfmModel.clusterBindMatrixOriginalValues[i].size() > j)) { + cluster.inverseBindMatrix = (glm::mat4)localOffset.inverse() * hfmModel.clusterBindMatrixOriginalValues[i][j]; } cluster.inverseBindTransform.evalFromRawMatrix(cluster.inverseBindMatrix); } @@ -215,30 +212,22 @@ void AnimSkeleton::buildSkeletonFromJoints(const std::vector& joints, qCDebug(animation) << "relative default pose for joint " << i << " " << relDefaultPose.trans() << " " << relDefaultPose.rot(); int parentIndex = getParentIndex(i); - AnimPose newAbsPose; if (parentIndex >= 0) { - newAbsPose = _absoluteDefaultPoses[parentIndex] * relDefaultPose; - _absoluteDefaultPoses.push_back(newAbsPose); + _absoluteDefaultPoses.push_back(_absoluteDefaultPoses[parentIndex] * relDefaultPose); } else { _absoluteDefaultPoses.push_back(relDefaultPose); } } for (int k = 0; k < _jointsSize; k++) { - int parentIndex2 = getParentIndex(k); if (jointOffsets.contains(k)) { AnimPose localOffset(jointOffsets[k], glm::vec3()); _absoluteDefaultPoses[k] = _absoluteDefaultPoses[k] * localOffset; } - if (parentIndex2 >= 0) { - _relativeDefaultPoses.push_back(_absoluteDefaultPoses[parentIndex2].inverse() * _absoluteDefaultPoses[k]); - } else { - _relativeDefaultPoses.push_back(_absoluteDefaultPoses[k]); - } } // re-compute relative poses - //_relativeDefaultPoses = _absoluteDefaultPoses; - //convertAbsolutePosesToRelative(_relativeDefaultPoses); + _relativeDefaultPoses = _absoluteDefaultPoses; + convertAbsolutePosesToRelative(_relativeDefaultPoses); for (int i = 0; i < _jointsSize; i++) { _jointIndicesByName[_joints[i].name] = i; diff --git a/libraries/fbx/src/FBXReader.cpp b/libraries/fbx/src/FBXReader.cpp index da0fe4fe01..2e4f98ee4c 100644 --- a/libraries/fbx/src/FBXReader.cpp +++ b/libraries/fbx/src/FBXReader.cpp @@ -2032,12 +2032,12 @@ HFMModel* FBXReader::extractHFMModel(const QVariantHash& mapping, const QString& // these are needed when we recompute the bindpose offsets on reset. for (int i = 0; i < (int)hfmModel.meshes.size(); i++) { const HFMMesh& mesh = hfmModel.meshes.at(i); - vector tempBindMat; + vector meshBindMatrices; for (int j = 0; j < mesh.clusters.size(); j++) { const HFMCluster& cluster = mesh.clusters.at(j); - tempBindMat.push_back(cluster.inverseBindMatrix); + meshBindMatrices.push_back(cluster.inverseBindMatrix); } - hfmModel.clusterBindMatrixOriginalValues.push_back(tempBindMat); + hfmModel.clusterBindMatrixOriginalValues.push_back(meshBindMatrices); } return hfmModelPtr; } From 8256c652fc7dd2d919f3e957659970fce41df23e Mon Sep 17 00:00:00 2001 From: amantley Date: Wed, 14 Nov 2018 17:02:25 -0800 Subject: [PATCH 29/32] added the hook to put the copy of the mutated bind poses into tthe skeleton --- libraries/animation/src/AnimSkeleton.cpp | 19 +++++++++++++---- libraries/animation/src/AnimSkeleton.h | 2 ++ libraries/fbx/src/FBXReader.cpp | 2 +- .../render-utils/src/CauterizedModel.cpp | 21 +++++++++++++++---- libraries/render-utils/src/Model.cpp | 10 +++++++-- .../render-utils/src/SoftAttachmentModel.cpp | 7 ++++--- 6 files changed, 47 insertions(+), 14 deletions(-) diff --git a/libraries/animation/src/AnimSkeleton.cpp b/libraries/animation/src/AnimSkeleton.cpp index a9dab701ed..d9c90a58cc 100644 --- a/libraries/animation/src/AnimSkeleton.cpp +++ b/libraries/animation/src/AnimSkeleton.cpp @@ -27,21 +27,32 @@ AnimSkeleton::AnimSkeleton(const HFMModel& hfmModel) { for (int i = 0; i < (int)hfmModel.meshes.size(); i++) { const HFMMesh& mesh = hfmModel.meshes.at(i); - for (int j = 0; j < mesh.clusters.size(); j++) { + std::vector dummyClustersList; + for (int j = 0; j < mesh.clusters.size(); j++) { + std::vector bindMatrices; // cast into a non-const reference, so we can mutate the FBXCluster HFMCluster& cluster = const_cast(mesh.clusters.at(j)); - + + HFMCluster localCluster; + localCluster.jointIndex = cluster.jointIndex; + localCluster.inverseBindMatrix = cluster.inverseBindMatrix; + localCluster.inverseBindTransform.evalFromRawMatrix(localCluster.inverseBindMatrix); + //dummyClustersList.push_back(localCluster); // AJT: mutate bind pose! this allows us to oreint the skeleton back into the authored orientaiton before // rendering, with no runtime overhead. if (hfmModel.jointRotationOffsets.contains(cluster.jointIndex)) { AnimPose localOffset(hfmModel.jointRotationOffsets[cluster.jointIndex], glm::vec3()); if ((hfmModel.clusterBindMatrixOriginalValues.size() > i) && (hfmModel.clusterBindMatrixOriginalValues[i].size() > j)) { - cluster.inverseBindMatrix = (glm::mat4)localOffset.inverse() * hfmModel.clusterBindMatrixOriginalValues[i][j]; + localCluster.inverseBindMatrix = (glm::mat4)localOffset.inverse() * hfmModel.clusterBindMatrixOriginalValues[i][j]; + //cluster.inverseBindMatrix = (glm::mat4)localOffset.inverse() * hfmModel.clusterBindMatrixOriginalValues[i][j]; } - cluster.inverseBindTransform.evalFromRawMatrix(cluster.inverseBindMatrix); + //cluster.inverseBindTransform.evalFromRawMatrix(cluster.inverseBindMatrix); + localCluster.inverseBindTransform.evalFromRawMatrix(localCluster.inverseBindMatrix); } + dummyClustersList.push_back(localCluster); } + _clusterBindMatrixOriginalValues.push_back(dummyClustersList); } } diff --git a/libraries/animation/src/AnimSkeleton.h b/libraries/animation/src/AnimSkeleton.h index f06813e51f..552b40b135 100644 --- a/libraries/animation/src/AnimSkeleton.h +++ b/libraries/animation/src/AnimSkeleton.h @@ -63,6 +63,7 @@ public: void dump(const AnimPoseVec& poses) const; std::vector lookUpJointIndices(const std::vector& jointNames) const; + std::vector> _clusterBindMatrixOriginalValues; protected: void buildSkeletonFromJoints(const std::vector& joints, const QMap jointOffsets); @@ -77,6 +78,7 @@ protected: std::vector _nonMirroredIndices; std::vector _mirrorMap; QHash _jointIndicesByName; + // std::vector> _clusterBindMatrixOriginalValues; // no copies AnimSkeleton(const AnimSkeleton&) = delete; diff --git a/libraries/fbx/src/FBXReader.cpp b/libraries/fbx/src/FBXReader.cpp index 2e4f98ee4c..5ac87e3004 100644 --- a/libraries/fbx/src/FBXReader.cpp +++ b/libraries/fbx/src/FBXReader.cpp @@ -2029,7 +2029,7 @@ HFMModel* FBXReader::extractHFMModel(const QVariantHash& mapping, const QString& } // create a backup copy of the bindposes, - // these are needed when we recompute the bindpose offsets on reset. + // these are needed when we recompute the bindpose offsets in the AnimSkeleton constructor on mySkeleton->reset() for (int i = 0; i < (int)hfmModel.meshes.size(); i++) { const HFMMesh& mesh = hfmModel.meshes.at(i); vector meshBindMatrices; diff --git a/libraries/render-utils/src/CauterizedModel.cpp b/libraries/render-utils/src/CauterizedModel.cpp index c31345bc55..eed5c16445 100644 --- a/libraries/render-utils/src/CauterizedModel.cpp +++ b/libraries/render-utils/src/CauterizedModel.cpp @@ -112,6 +112,7 @@ void CauterizedModel::updateClusterMatrices() { const HFMModel& hfmModel = getHFMModel(); for (int i = 0; i < (int)_meshStates.size(); i++) { + qCDebug(renderutils) << "mesh states size " << _meshStates.size() << " mesh size " << hfmModel.meshes.size(); Model::MeshState& state = _meshStates[i]; const HFMMesh& mesh = hfmModel.meshes.at(i); for (int j = 0; j < mesh.clusters.size(); j++) { @@ -120,12 +121,20 @@ void CauterizedModel::updateClusterMatrices() { auto jointPose = _rig.getJointPose(cluster.jointIndex); Transform jointTransform(jointPose.rot(), jointPose.scale(), jointPose.trans()); Transform clusterTransform; - Transform::mult(clusterTransform, jointTransform, cluster.inverseBindTransform); + Transform clusterTransform2; + //Transform::mult(clusterTransform, jointTransform, cluster.inverseBindTransform); + Transform::mult(clusterTransform, jointTransform, _rig.getAnimSkeleton()->_clusterBindMatrixOriginalValues[i][j].inverseBindTransform); + Transform::mult(clusterTransform2, jointTransform, cluster.inverseBindTransform); + //qCDebug(renderutils) << "the animskel matrix i " << i << " j " << j << _rig.getAnimSkeleton()->_clusterBindMatrixOriginalValues[i][j].inverseBindTransform; + qCDebug(renderutils) << "the mesh state cluster matrix " << state.clusterMatrices[j]; + //qCDebug(renderutils) << "cluster transform old way " << clusterTransform2; + //qCDebug(renderutils) << "cluster transform new way " << clusterTransform; state.clusterDualQuaternions[j] = Model::TransformDualQuaternion(clusterTransform); state.clusterDualQuaternions[j].setCauterizationParameters(0.0f, jointPose.trans()); } else { auto jointMatrix = _rig.getJointTransform(cluster.jointIndex); - glm_mat4u_mul(jointMatrix, cluster.inverseBindMatrix, state.clusterMatrices[j]); + //glm_mat4u_mul(jointMatrix, cluster.inverseBindMatrix, state.clusterMatrices[j]); + glm_mat4u_mul(jointMatrix, _rig.getAnimSkeleton()->_clusterBindMatrixOriginalValues[i][j].inverseBindMatrix, state.clusterMatrices[j]); } } } @@ -157,7 +166,8 @@ void CauterizedModel::updateClusterMatrices() { } else { Transform jointTransform(cauterizePose.rot(), cauterizePose.scale(), cauterizePose.trans()); Transform clusterTransform; - Transform::mult(clusterTransform, jointTransform, cluster.inverseBindTransform); + //Transform::mult(clusterTransform, jointTransform, cluster.inverseBindTransform); + Transform::mult(clusterTransform, jointTransform, _rig.getAnimSkeleton()->_clusterBindMatrixOriginalValues[i][j].inverseBindTransform); state.clusterDualQuaternions[j] = Model::TransformDualQuaternion(clusterTransform); state.clusterDualQuaternions[j].setCauterizationParameters(1.0f, cauterizePose.trans()); } @@ -166,7 +176,8 @@ void CauterizedModel::updateClusterMatrices() { // not cauterized so just copy the value from the non-cauterized version. state.clusterMatrices[j] = _meshStates[i].clusterMatrices[j]; } else { - glm_mat4u_mul(cauterizeMatrix, cluster.inverseBindMatrix, state.clusterMatrices[j]); + // glm_mat4u_mul(cauterizeMatrix, cluster.inverseBindMatrix, state.clusterMatrices[j]); + glm_mat4u_mul(cauterizeMatrix, _rig.getAnimSkeleton()->_clusterBindMatrixOriginalValues[i][j].inverseBindMatrix, state.clusterMatrices[j]); } } } @@ -231,6 +242,8 @@ void CauterizedModel::updateRenderItems() { if (useDualQuaternionSkinning) { data.updateClusterBuffer(meshState.clusterDualQuaternions, cauterizedMeshState.clusterDualQuaternions); + //qCDebug(renderutils) << "mesh cluster transform " << meshState.clusterDualQuaternions[0]; + //qCDebug(renderutils) << "cauterized mesh cluster transform " << cauterizedMeshState.clusterDualQuaternions[0]; } else { data.updateClusterBuffer(meshState.clusterMatrices, cauterizedMeshState.clusterMatrices); diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index 7da7a45e83..25dba9c1de 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -237,6 +237,10 @@ void Model::updateRenderItems() { bool invalidatePayloadShapeKey = self->shouldInvalidatePayloadShapeKey(meshIndex); bool useDualQuaternionSkinning = self->getUseDualQuaternionSkinning(); + if (useDualQuaternionSkinning) { + qCDebug(renderutils) << "use dual quats value " << useDualQuaternionSkinning; + } + transaction.updateItem(itemID, [modelTransform, meshState, useDualQuaternionSkinning, invalidatePayloadShapeKey, isWireframe, renderItemKeyGlobalFlags](ModelMeshPartPayload& data) { if (useDualQuaternionSkinning) { @@ -1425,11 +1429,13 @@ void Model::updateClusterMatrices() { auto jointPose = _rig.getJointPose(cluster.jointIndex); Transform jointTransform(jointPose.rot(), jointPose.scale(), jointPose.trans()); Transform clusterTransform; - Transform::mult(clusterTransform, jointTransform, cluster.inverseBindTransform); + Transform::mult(clusterTransform, jointTransform, _rig.getAnimSkeleton()->_clusterBindMatrixOriginalValues[i][j].inverseBindTransform); + //Transform::mult(clusterTransform, jointTransform, cluster.inverseBindTransform); state.clusterDualQuaternions[j] = Model::TransformDualQuaternion(clusterTransform); } else { auto jointMatrix = _rig.getJointTransform(cluster.jointIndex); - glm_mat4u_mul(jointMatrix, cluster.inverseBindMatrix, state.clusterMatrices[j]); + glm_mat4u_mul(jointMatrix, _rig.getAnimSkeleton()->_clusterBindMatrixOriginalValues[i][j].inverseBindMatrix, state.clusterMatrices[j]); + // glm_mat4u_mul(jointMatrix, cluster.inverseBindMatrix, state.clusterMatrices[j]); } } } diff --git a/libraries/render-utils/src/SoftAttachmentModel.cpp b/libraries/render-utils/src/SoftAttachmentModel.cpp index f26bad86b0..58b0989403 100644 --- a/libraries/render-utils/src/SoftAttachmentModel.cpp +++ b/libraries/render-utils/src/SoftAttachmentModel.cpp @@ -61,7 +61,8 @@ void SoftAttachmentModel::updateClusterMatrices() { } glm::mat4 m; - glm_mat4u_mul(jointMatrix, cluster.inverseBindMatrix, m); + //glm_mat4u_mul(jointMatrix, cluster.inverseBindMatrix, m); + glm_mat4u_mul(jointMatrix, _rig.getAnimSkeleton()->_clusterBindMatrixOriginalValues[i][j].inverseBindMatrix, m); state.clusterDualQuaternions[j] = Model::TransformDualQuaternion(m); } else { glm::mat4 jointMatrix; @@ -70,8 +71,8 @@ void SoftAttachmentModel::updateClusterMatrices() { } else { jointMatrix = _rig.getJointTransform(cluster.jointIndex); } - - glm_mat4u_mul(jointMatrix, cluster.inverseBindMatrix, state.clusterMatrices[j]); + //glm_mat4u_mul(jointMatrix, cluster.inverseBindMatrix, state.clusterMatrices[j]); + glm_mat4u_mul(jointMatrix, _rig.getAnimSkeleton()->_clusterBindMatrixOriginalValues[i][j].inverseBindMatrix, state.clusterMatrices[j]); } } } From 80ebde10369f576359834c073355c5de13524fcb Mon Sep 17 00:00:00 2001 From: amantley Date: Wed, 14 Nov 2018 17:27:45 -0800 Subject: [PATCH 30/32] started cleanup of pr --- libraries/animation/src/AnimSkeleton.cpp | 10 +++------- libraries/animation/src/AnimSkeleton.h | 1 - .../src/avatars-renderer/SkeletonModel.cpp | 1 - libraries/fbx/src/FBXReader.cpp | 11 ----------- libraries/render-utils/src/CauterizedModel.cpp | 13 ------------- libraries/render-utils/src/Model.cpp | 4 ---- libraries/render-utils/src/SoftAttachmentModel.cpp | 2 -- 7 files changed, 3 insertions(+), 39 deletions(-) diff --git a/libraries/animation/src/AnimSkeleton.cpp b/libraries/animation/src/AnimSkeleton.cpp index d9c90a58cc..435eaf9184 100644 --- a/libraries/animation/src/AnimSkeleton.cpp +++ b/libraries/animation/src/AnimSkeleton.cpp @@ -33,21 +33,18 @@ AnimSkeleton::AnimSkeleton(const HFMModel& hfmModel) { std::vector bindMatrices; // cast into a non-const reference, so we can mutate the FBXCluster HFMCluster& cluster = const_cast(mesh.clusters.at(j)); - + HFMCluster localCluster; localCluster.jointIndex = cluster.jointIndex; localCluster.inverseBindMatrix = cluster.inverseBindMatrix; localCluster.inverseBindTransform.evalFromRawMatrix(localCluster.inverseBindMatrix); - //dummyClustersList.push_back(localCluster); - // AJT: mutate bind pose! this allows us to oreint the skeleton back into the authored orientaiton before - // rendering, with no runtime overhead. + + // we make a copy of the inversebindMatrices in order to prevent mutating the model bind pose if (hfmModel.jointRotationOffsets.contains(cluster.jointIndex)) { AnimPose localOffset(hfmModel.jointRotationOffsets[cluster.jointIndex], glm::vec3()); if ((hfmModel.clusterBindMatrixOriginalValues.size() > i) && (hfmModel.clusterBindMatrixOriginalValues[i].size() > j)) { localCluster.inverseBindMatrix = (glm::mat4)localOffset.inverse() * hfmModel.clusterBindMatrixOriginalValues[i][j]; - //cluster.inverseBindMatrix = (glm::mat4)localOffset.inverse() * hfmModel.clusterBindMatrixOriginalValues[i][j]; } - //cluster.inverseBindTransform.evalFromRawMatrix(cluster.inverseBindMatrix); localCluster.inverseBindTransform.evalFromRawMatrix(localCluster.inverseBindMatrix); } dummyClustersList.push_back(localCluster); @@ -220,7 +217,6 @@ void AnimSkeleton::buildSkeletonFromJoints(const std::vector& joints, // build relative and absolute default poses glm::mat4 relDefaultMat = glm::translate(_joints[i].translation) * preRotationTransform * glm::mat4_cast(_joints[i].rotation) * postRotationTransform; AnimPose relDefaultPose(relDefaultMat); - qCDebug(animation) << "relative default pose for joint " << i << " " << relDefaultPose.trans() << " " << relDefaultPose.rot(); int parentIndex = getParentIndex(i); if (parentIndex >= 0) { diff --git a/libraries/animation/src/AnimSkeleton.h b/libraries/animation/src/AnimSkeleton.h index 552b40b135..7436609ee1 100644 --- a/libraries/animation/src/AnimSkeleton.h +++ b/libraries/animation/src/AnimSkeleton.h @@ -78,7 +78,6 @@ protected: std::vector _nonMirroredIndices; std::vector _mirrorMap; QHash _jointIndicesByName; - // std::vector> _clusterBindMatrixOriginalValues; // no copies AnimSkeleton(const AnimSkeleton&) = delete; diff --git a/libraries/avatars-renderer/src/avatars-renderer/SkeletonModel.cpp b/libraries/avatars-renderer/src/avatars-renderer/SkeletonModel.cpp index 32c95b8c4c..36e37dd3d4 100644 --- a/libraries/avatars-renderer/src/avatars-renderer/SkeletonModel.cpp +++ b/libraries/avatars-renderer/src/avatars-renderer/SkeletonModel.cpp @@ -56,7 +56,6 @@ void SkeletonModel::setTextures(const QVariantMap& textures) { void SkeletonModel::initJointStates() { const HFMModel& hfmModel = getHFMModel(); glm::mat4 modelOffset = glm::scale(_scale) * glm::translate(_offset); - _rig.initJointStates(hfmModel, modelOffset); { diff --git a/libraries/fbx/src/FBXReader.cpp b/libraries/fbx/src/FBXReader.cpp index 5ac87e3004..6ec7e0e73c 100644 --- a/libraries/fbx/src/FBXReader.cpp +++ b/libraries/fbx/src/FBXReader.cpp @@ -2028,17 +2028,6 @@ HFMModel* FBXReader::extractHFMModel(const QVariantHash& mapping, const QString& qCDebug(modelformat) << "Joint Rotation Offset added to Rig._jointRotationOffsets : " << " jointName: " << jointName << " jointIndex: " << jointIndex << " rotation offset: " << rotationOffset; } - // create a backup copy of the bindposes, - // these are needed when we recompute the bindpose offsets in the AnimSkeleton constructor on mySkeleton->reset() - for (int i = 0; i < (int)hfmModel.meshes.size(); i++) { - const HFMMesh& mesh = hfmModel.meshes.at(i); - vector meshBindMatrices; - for (int j = 0; j < mesh.clusters.size(); j++) { - const HFMCluster& cluster = mesh.clusters.at(j); - meshBindMatrices.push_back(cluster.inverseBindMatrix); - } - hfmModel.clusterBindMatrixOriginalValues.push_back(meshBindMatrices); - } return hfmModelPtr; } diff --git a/libraries/render-utils/src/CauterizedModel.cpp b/libraries/render-utils/src/CauterizedModel.cpp index eed5c16445..e00a82d71f 100644 --- a/libraries/render-utils/src/CauterizedModel.cpp +++ b/libraries/render-utils/src/CauterizedModel.cpp @@ -112,7 +112,6 @@ void CauterizedModel::updateClusterMatrices() { const HFMModel& hfmModel = getHFMModel(); for (int i = 0; i < (int)_meshStates.size(); i++) { - qCDebug(renderutils) << "mesh states size " << _meshStates.size() << " mesh size " << hfmModel.meshes.size(); Model::MeshState& state = _meshStates[i]; const HFMMesh& mesh = hfmModel.meshes.at(i); for (int j = 0; j < mesh.clusters.size(); j++) { @@ -121,19 +120,11 @@ void CauterizedModel::updateClusterMatrices() { auto jointPose = _rig.getJointPose(cluster.jointIndex); Transform jointTransform(jointPose.rot(), jointPose.scale(), jointPose.trans()); Transform clusterTransform; - Transform clusterTransform2; - //Transform::mult(clusterTransform, jointTransform, cluster.inverseBindTransform); Transform::mult(clusterTransform, jointTransform, _rig.getAnimSkeleton()->_clusterBindMatrixOriginalValues[i][j].inverseBindTransform); - Transform::mult(clusterTransform2, jointTransform, cluster.inverseBindTransform); - //qCDebug(renderutils) << "the animskel matrix i " << i << " j " << j << _rig.getAnimSkeleton()->_clusterBindMatrixOriginalValues[i][j].inverseBindTransform; - qCDebug(renderutils) << "the mesh state cluster matrix " << state.clusterMatrices[j]; - //qCDebug(renderutils) << "cluster transform old way " << clusterTransform2; - //qCDebug(renderutils) << "cluster transform new way " << clusterTransform; state.clusterDualQuaternions[j] = Model::TransformDualQuaternion(clusterTransform); state.clusterDualQuaternions[j].setCauterizationParameters(0.0f, jointPose.trans()); } else { auto jointMatrix = _rig.getJointTransform(cluster.jointIndex); - //glm_mat4u_mul(jointMatrix, cluster.inverseBindMatrix, state.clusterMatrices[j]); glm_mat4u_mul(jointMatrix, _rig.getAnimSkeleton()->_clusterBindMatrixOriginalValues[i][j].inverseBindMatrix, state.clusterMatrices[j]); } } @@ -166,7 +157,6 @@ void CauterizedModel::updateClusterMatrices() { } else { Transform jointTransform(cauterizePose.rot(), cauterizePose.scale(), cauterizePose.trans()); Transform clusterTransform; - //Transform::mult(clusterTransform, jointTransform, cluster.inverseBindTransform); Transform::mult(clusterTransform, jointTransform, _rig.getAnimSkeleton()->_clusterBindMatrixOriginalValues[i][j].inverseBindTransform); state.clusterDualQuaternions[j] = Model::TransformDualQuaternion(clusterTransform); state.clusterDualQuaternions[j].setCauterizationParameters(1.0f, cauterizePose.trans()); @@ -176,7 +166,6 @@ void CauterizedModel::updateClusterMatrices() { // not cauterized so just copy the value from the non-cauterized version. state.clusterMatrices[j] = _meshStates[i].clusterMatrices[j]; } else { - // glm_mat4u_mul(cauterizeMatrix, cluster.inverseBindMatrix, state.clusterMatrices[j]); glm_mat4u_mul(cauterizeMatrix, _rig.getAnimSkeleton()->_clusterBindMatrixOriginalValues[i][j].inverseBindMatrix, state.clusterMatrices[j]); } } @@ -242,8 +231,6 @@ void CauterizedModel::updateRenderItems() { if (useDualQuaternionSkinning) { data.updateClusterBuffer(meshState.clusterDualQuaternions, cauterizedMeshState.clusterDualQuaternions); - //qCDebug(renderutils) << "mesh cluster transform " << meshState.clusterDualQuaternions[0]; - //qCDebug(renderutils) << "cauterized mesh cluster transform " << cauterizedMeshState.clusterDualQuaternions[0]; } else { data.updateClusterBuffer(meshState.clusterMatrices, cauterizedMeshState.clusterMatrices); diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index 25dba9c1de..a5565d0646 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -237,10 +237,6 @@ void Model::updateRenderItems() { bool invalidatePayloadShapeKey = self->shouldInvalidatePayloadShapeKey(meshIndex); bool useDualQuaternionSkinning = self->getUseDualQuaternionSkinning(); - if (useDualQuaternionSkinning) { - qCDebug(renderutils) << "use dual quats value " << useDualQuaternionSkinning; - } - transaction.updateItem(itemID, [modelTransform, meshState, useDualQuaternionSkinning, invalidatePayloadShapeKey, isWireframe, renderItemKeyGlobalFlags](ModelMeshPartPayload& data) { if (useDualQuaternionSkinning) { diff --git a/libraries/render-utils/src/SoftAttachmentModel.cpp b/libraries/render-utils/src/SoftAttachmentModel.cpp index 58b0989403..e45141a838 100644 --- a/libraries/render-utils/src/SoftAttachmentModel.cpp +++ b/libraries/render-utils/src/SoftAttachmentModel.cpp @@ -61,7 +61,6 @@ void SoftAttachmentModel::updateClusterMatrices() { } glm::mat4 m; - //glm_mat4u_mul(jointMatrix, cluster.inverseBindMatrix, m); glm_mat4u_mul(jointMatrix, _rig.getAnimSkeleton()->_clusterBindMatrixOriginalValues[i][j].inverseBindMatrix, m); state.clusterDualQuaternions[j] = Model::TransformDualQuaternion(m); } else { @@ -71,7 +70,6 @@ void SoftAttachmentModel::updateClusterMatrices() { } else { jointMatrix = _rig.getJointTransform(cluster.jointIndex); } - //glm_mat4u_mul(jointMatrix, cluster.inverseBindMatrix, state.clusterMatrices[j]); glm_mat4u_mul(jointMatrix, _rig.getAnimSkeleton()->_clusterBindMatrixOriginalValues[i][j].inverseBindMatrix, state.clusterMatrices[j]); } } From c8cd65c3bd46d17668f4c94042fed45b2b0fa199 Mon Sep 17 00:00:00 2001 From: amantley Date: Thu, 15 Nov 2018 09:57:09 -0800 Subject: [PATCH 31/32] added getter for the orginal cluster bind matrix values in AnimSkeleton --- libraries/animation/src/AnimSkeleton.cpp | 9 ++++--- libraries/animation/src/AnimSkeleton.h | 3 ++- libraries/fbx/src/FBX.h | 1 - .../render-utils/src/CauterizedModel.cpp | 14 +++++++--- libraries/render-utils/src/Model.cpp | 9 ++++--- .../render-utils/src/SoftAttachmentModel.cpp | 26 +++++++------------ 6 files changed, 32 insertions(+), 30 deletions(-) diff --git a/libraries/animation/src/AnimSkeleton.cpp b/libraries/animation/src/AnimSkeleton.cpp index 435eaf9184..91ca2359b4 100644 --- a/libraries/animation/src/AnimSkeleton.cpp +++ b/libraries/animation/src/AnimSkeleton.cpp @@ -25,6 +25,8 @@ AnimSkeleton::AnimSkeleton(const HFMModel& hfmModel) { } buildSkeletonFromJoints(joints, hfmModel.jointRotationOffsets); + // we make a copy of the inverseBindMatrices in order to prevent mutating the model bind pose + // when we are dealing with a joint offset in the model for (int i = 0; i < (int)hfmModel.meshes.size(); i++) { const HFMMesh& mesh = hfmModel.meshes.at(i); std::vector dummyClustersList; @@ -39,12 +41,11 @@ AnimSkeleton::AnimSkeleton(const HFMModel& hfmModel) { localCluster.inverseBindMatrix = cluster.inverseBindMatrix; localCluster.inverseBindTransform.evalFromRawMatrix(localCluster.inverseBindMatrix); - // we make a copy of the inversebindMatrices in order to prevent mutating the model bind pose + // if we have a joint offset in the fst file then multiply its inverse by the + // model cluster inverse bind matrix if (hfmModel.jointRotationOffsets.contains(cluster.jointIndex)) { AnimPose localOffset(hfmModel.jointRotationOffsets[cluster.jointIndex], glm::vec3()); - if ((hfmModel.clusterBindMatrixOriginalValues.size() > i) && (hfmModel.clusterBindMatrixOriginalValues[i].size() > j)) { - localCluster.inverseBindMatrix = (glm::mat4)localOffset.inverse() * hfmModel.clusterBindMatrixOriginalValues[i][j]; - } + localCluster.inverseBindMatrix = (glm::mat4)localOffset.inverse() * cluster.inverseBindMatrix; localCluster.inverseBindTransform.evalFromRawMatrix(localCluster.inverseBindMatrix); } dummyClustersList.push_back(localCluster); diff --git a/libraries/animation/src/AnimSkeleton.h b/libraries/animation/src/AnimSkeleton.h index 7436609ee1..ab89eb643d 100644 --- a/libraries/animation/src/AnimSkeleton.h +++ b/libraries/animation/src/AnimSkeleton.h @@ -63,7 +63,7 @@ public: void dump(const AnimPoseVec& poses) const; std::vector lookUpJointIndices(const std::vector& jointNames) const; - std::vector> _clusterBindMatrixOriginalValues; + const HFMCluster getClusterBindMatricesOriginalValues(const int meshIndex, const int clusterIndex) const { return _clusterBindMatrixOriginalValues[meshIndex][clusterIndex]; } protected: void buildSkeletonFromJoints(const std::vector& joints, const QMap jointOffsets); @@ -78,6 +78,7 @@ protected: std::vector _nonMirroredIndices; std::vector _mirrorMap; QHash _jointIndicesByName; + std::vector> _clusterBindMatrixOriginalValues; // no copies AnimSkeleton(const AnimSkeleton&) = delete; diff --git a/libraries/fbx/src/FBX.h b/libraries/fbx/src/FBX.h index 943db4b7fe..d4072f03d7 100644 --- a/libraries/fbx/src/FBX.h +++ b/libraries/fbx/src/FBX.h @@ -349,7 +349,6 @@ public: Extents meshExtents; QVector animationFrames; - std::vector> clusterBindMatrixOriginalValues; int getJointIndex(const QString& name) const { return jointIndices.value(name) - 1; } QStringList getJointNames() const; diff --git a/libraries/render-utils/src/CauterizedModel.cpp b/libraries/render-utils/src/CauterizedModel.cpp index e00a82d71f..86d4793aa5 100644 --- a/libraries/render-utils/src/CauterizedModel.cpp +++ b/libraries/render-utils/src/CauterizedModel.cpp @@ -114,18 +114,22 @@ void CauterizedModel::updateClusterMatrices() { for (int i = 0; i < (int)_meshStates.size(); i++) { Model::MeshState& state = _meshStates[i]; const HFMMesh& mesh = hfmModel.meshes.at(i); + int meshIndex = i; + for (int j = 0; j < mesh.clusters.size(); j++) { const HFMCluster& cluster = mesh.clusters.at(j); + int clusterIndex = j; + if (_useDualQuaternionSkinning) { auto jointPose = _rig.getJointPose(cluster.jointIndex); Transform jointTransform(jointPose.rot(), jointPose.scale(), jointPose.trans()); Transform clusterTransform; - Transform::mult(clusterTransform, jointTransform, _rig.getAnimSkeleton()->_clusterBindMatrixOriginalValues[i][j].inverseBindTransform); + Transform::mult(clusterTransform, jointTransform, _rig.getAnimSkeleton()->getClusterBindMatricesOriginalValues(meshIndex, clusterIndex).inverseBindTransform); state.clusterDualQuaternions[j] = Model::TransformDualQuaternion(clusterTransform); state.clusterDualQuaternions[j].setCauterizationParameters(0.0f, jointPose.trans()); } else { auto jointMatrix = _rig.getJointTransform(cluster.jointIndex); - glm_mat4u_mul(jointMatrix, _rig.getAnimSkeleton()->_clusterBindMatrixOriginalValues[i][j].inverseBindMatrix, state.clusterMatrices[j]); + glm_mat4u_mul(jointMatrix, _rig.getAnimSkeleton()->getClusterBindMatricesOriginalValues(meshIndex, clusterIndex).inverseBindMatrix, state.clusterMatrices[j]); } } } @@ -146,9 +150,11 @@ void CauterizedModel::updateClusterMatrices() { for (int i = 0; i < _cauterizeMeshStates.size(); i++) { Model::MeshState& state = _cauterizeMeshStates[i]; const HFMMesh& mesh = hfmModel.meshes.at(i); + int meshIndex = i; for (int j = 0; j < mesh.clusters.size(); j++) { const HFMCluster& cluster = mesh.clusters.at(j); + int clusterIndex = j; if (_useDualQuaternionSkinning) { if (_cauterizeBoneSet.find(cluster.jointIndex) == _cauterizeBoneSet.end()) { @@ -157,7 +163,7 @@ void CauterizedModel::updateClusterMatrices() { } else { Transform jointTransform(cauterizePose.rot(), cauterizePose.scale(), cauterizePose.trans()); Transform clusterTransform; - Transform::mult(clusterTransform, jointTransform, _rig.getAnimSkeleton()->_clusterBindMatrixOriginalValues[i][j].inverseBindTransform); + Transform::mult(clusterTransform, jointTransform, _rig.getAnimSkeleton()->getClusterBindMatricesOriginalValues(meshIndex, clusterIndex).inverseBindTransform); state.clusterDualQuaternions[j] = Model::TransformDualQuaternion(clusterTransform); state.clusterDualQuaternions[j].setCauterizationParameters(1.0f, cauterizePose.trans()); } @@ -166,7 +172,7 @@ void CauterizedModel::updateClusterMatrices() { // not cauterized so just copy the value from the non-cauterized version. state.clusterMatrices[j] = _meshStates[i].clusterMatrices[j]; } else { - glm_mat4u_mul(cauterizeMatrix, _rig.getAnimSkeleton()->_clusterBindMatrixOriginalValues[i][j].inverseBindMatrix, state.clusterMatrices[j]); + glm_mat4u_mul(cauterizeMatrix, _rig.getAnimSkeleton()->getClusterBindMatricesOriginalValues(meshIndex, clusterIndex).inverseBindMatrix, state.clusterMatrices[j]); } } } diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index a5565d0646..9cefbf65a8 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -1418,20 +1418,21 @@ void Model::updateClusterMatrices() { const HFMModel& hfmModel = getHFMModel(); for (int i = 0; i < (int) _meshStates.size(); i++) { MeshState& state = _meshStates[i]; + int meshIndex = i; const HFMMesh& mesh = hfmModel.meshes.at(i); for (int j = 0; j < mesh.clusters.size(); j++) { const HFMCluster& cluster = mesh.clusters.at(j); + int clusterIndex = j; + if (_useDualQuaternionSkinning) { auto jointPose = _rig.getJointPose(cluster.jointIndex); Transform jointTransform(jointPose.rot(), jointPose.scale(), jointPose.trans()); Transform clusterTransform; - Transform::mult(clusterTransform, jointTransform, _rig.getAnimSkeleton()->_clusterBindMatrixOriginalValues[i][j].inverseBindTransform); - //Transform::mult(clusterTransform, jointTransform, cluster.inverseBindTransform); + Transform::mult(clusterTransform, jointTransform, _rig.getAnimSkeleton()->getClusterBindMatricesOriginalValues(meshIndex, clusterIndex).inverseBindTransform); state.clusterDualQuaternions[j] = Model::TransformDualQuaternion(clusterTransform); } else { auto jointMatrix = _rig.getJointTransform(cluster.jointIndex); - glm_mat4u_mul(jointMatrix, _rig.getAnimSkeleton()->_clusterBindMatrixOriginalValues[i][j].inverseBindMatrix, state.clusterMatrices[j]); - // glm_mat4u_mul(jointMatrix, cluster.inverseBindMatrix, state.clusterMatrices[j]); + glm_mat4u_mul(jointMatrix, _rig.getAnimSkeleton()->getClusterBindMatricesOriginalValues(meshIndex, clusterIndex).inverseBindMatrix, state.clusterMatrices[j]); } } } diff --git a/libraries/render-utils/src/SoftAttachmentModel.cpp b/libraries/render-utils/src/SoftAttachmentModel.cpp index e45141a838..a6f82e1417 100644 --- a/libraries/render-utils/src/SoftAttachmentModel.cpp +++ b/libraries/render-utils/src/SoftAttachmentModel.cpp @@ -46,31 +46,25 @@ void SoftAttachmentModel::updateClusterMatrices() { for (int i = 0; i < (int) _meshStates.size(); i++) { MeshState& state = _meshStates[i]; const HFMMesh& mesh = hfmModel.meshes.at(i); - + int meshIndex = i; for (int j = 0; j < mesh.clusters.size(); j++) { const HFMCluster& cluster = mesh.clusters.at(j); + int clusterIndex = j; // TODO: cache these look-ups as an optimization int jointIndexOverride = getJointIndexOverride(cluster.jointIndex); + glm::mat4 jointMatrix; + if (jointIndexOverride >= 0 && jointIndexOverride < _rigOverride.getJointStateCount()) { + jointMatrix = _rigOverride.getJointTransform(jointIndexOverride); + } else { + jointMatrix = _rig.getJointTransform(cluster.jointIndex); + } if (_useDualQuaternionSkinning) { - glm::mat4 jointMatrix; - if (jointIndexOverride >= 0 && jointIndexOverride < _rigOverride.getJointStateCount()) { - jointMatrix = _rigOverride.getJointTransform(jointIndexOverride); - } else { - jointMatrix = _rig.getJointTransform(cluster.jointIndex); - } - glm::mat4 m; - glm_mat4u_mul(jointMatrix, _rig.getAnimSkeleton()->_clusterBindMatrixOriginalValues[i][j].inverseBindMatrix, m); + glm_mat4u_mul(jointMatrix, _rig.getAnimSkeleton()->getClusterBindMatricesOriginalValues(meshIndex, clusterIndex).inverseBindMatrix, m); state.clusterDualQuaternions[j] = Model::TransformDualQuaternion(m); } else { - glm::mat4 jointMatrix; - if (jointIndexOverride >= 0 && jointIndexOverride < _rigOverride.getJointStateCount()) { - jointMatrix = _rigOverride.getJointTransform(jointIndexOverride); - } else { - jointMatrix = _rig.getJointTransform(cluster.jointIndex); - } - glm_mat4u_mul(jointMatrix, _rig.getAnimSkeleton()->_clusterBindMatrixOriginalValues[i][j].inverseBindMatrix, state.clusterMatrices[j]); + glm_mat4u_mul(jointMatrix, _rig.getAnimSkeleton()->getClusterBindMatricesOriginalValues(meshIndex, clusterIndex).inverseBindMatrix, state.clusterMatrices[j]); } } } From 3bf4a7844d6d17b93e54f12f072b55d7796c6380 Mon Sep 17 00:00:00 2001 From: amantley Date: Thu, 15 Nov 2018 10:56:17 -0800 Subject: [PATCH 32/32] moved the jointrotationoffsets to hfmModel.h from fbx.h --- libraries/hfm/src/hfm/HFM.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libraries/hfm/src/hfm/HFM.h b/libraries/hfm/src/hfm/HFM.h index 7d4479e681..05e48b6534 100644 --- a/libraries/hfm/src/hfm/HFM.h +++ b/libraries/hfm/src/hfm/HFM.h @@ -311,6 +311,8 @@ public: QString getModelNameOfMesh(int meshIndex) const; QList blendshapeChannelNames; + + QMap jointRotationOffsets; }; };