From 3cde9721743da428f4dfc25aaeb34f1dde3d9e5e Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Tue, 1 Mar 2016 11:07:22 -0800 Subject: [PATCH] Rig: issue warnings for missing joints Also, Removed Rig::computeEyesInRigFrame, it was causing warnings because it was looking up Eye and Head joints for all models, not just avatars. --- interface/src/avatar/MyAvatar.cpp | 20 ----------- libraries/animation/src/Rig.cpp | 60 ++++++++++++++----------------- libraries/animation/src/Rig.h | 4 +-- 3 files changed, 29 insertions(+), 55 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 1b04fa4fa4..db4b900a3c 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -1766,25 +1766,6 @@ glm::quat MyAvatar::getWorldBodyOrientation() const { return glm::quat_cast(_sensorToWorldMatrix * _bodySensorMatrix); } -#if 0 -// derive avatar body position and orientation from the current HMD Sensor location. -// results are in sensor space -glm::mat4 MyAvatar::deriveBodyFromHMDSensor() const { - if (_rig) { - // orientation - const glm::quat hmdOrientation = getHMDSensorOrientation(); - const glm::quat yaw = cancelOutRollAndPitch(hmdOrientation); - // position - // we flip about yAxis when going from "root" to "avatar" frame - // and we must also apply "yaw" to get into HMD frame - glm::quat rotY180 = glm::angleAxis((float)M_PI, glm::vec3(0.0f, 1.0f, 0.0f)); - glm::vec3 eyesInAvatarFrame = rotY180 * yaw * _rig->getEyesInRootFrame(); - glm::vec3 bodyPos = getHMDSensorPosition() - eyesInAvatarFrame; - return createMatFromQuatAndPos(yaw, bodyPos); - } - return glm::mat4(); -} -#else // old school meat hook style glm::mat4 MyAvatar::deriveBodyFromHMDSensor() const { @@ -1825,7 +1806,6 @@ glm::mat4 MyAvatar::deriveBodyFromHMDSensor() const { return createMatFromQuatAndPos(hmdOrientationYawOnly, bodyPos); } -#endif glm::vec3 MyAvatar::getPositionForAudio() { switch (_audioListenerMode) { diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index 7bab4dfc1d..02968e3665 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -173,8 +173,6 @@ void Rig::initJointStates(const FBXGeometry& geometry, const glm::mat4& modelOff _animSkeleton = std::make_shared(geometry); - computeEyesInRootFrame(_animSkeleton->getRelativeDefaultPoses()); - _internalPoseSet._relativePoses.clear(); _internalPoseSet._relativePoses = _animSkeleton->getRelativeDefaultPoses(); @@ -201,8 +199,6 @@ void Rig::reset(const FBXGeometry& geometry) { _geometryOffset = AnimPose(geometry.offset); _animSkeleton = std::make_shared(geometry); - computeEyesInRootFrame(_animSkeleton->getRelativeDefaultPoses()); - _internalPoseSet._relativePoses.clear(); _internalPoseSet._relativePoses = _animSkeleton->getRelativeDefaultPoses(); @@ -237,10 +233,20 @@ int Rig::getJointStateCount() const { return (int)_internalPoseSet._relativePoses.size(); } +static const uint32_t MAX_JOINT_NAME_WARNING_COUNT = 100; + int Rig::indexOfJoint(const QString& jointName) const { if (_animSkeleton) { - return _animSkeleton->nameToJointIndex(jointName); + int result = _animSkeleton->nameToJointIndex(jointName); + + // This is a content error, so we should issue a warning. + if (result < 0 && _jointNameWarningCount < MAX_JOINT_NAME_WARNING_COUNT) { + qCWarning(animation) << "Rig: Missing joint" << jointName << "in avatar model"; + _jointNameWarningCount++; + } + return result; } else { + // This is normal and can happen when the avatar model has not been dowloaded/loaded yet. return -1; } } @@ -444,26 +450,6 @@ void Rig::calcAnimAlpha(float speed, const std::vector& referenceSpeeds, *alphaOut = alpha; } -void Rig::computeEyesInRootFrame(const AnimPoseVec& poses) { - // TODO: use cached eye/hips indices for these calculations - int numPoses = (int)poses.size(); - int hipsIndex = _animSkeleton->nameToJointIndex(QString("Hips")); - int headIndex = _animSkeleton->nameToJointIndex(QString("Head")); - if (hipsIndex > 0 && headIndex > 0) { - int rightEyeIndex = _animSkeleton->nameToJointIndex(QString("RightEye")); - int leftEyeIndex = _animSkeleton->nameToJointIndex(QString("LeftEye")); - if (numPoses > rightEyeIndex && numPoses > leftEyeIndex && rightEyeIndex > 0 && leftEyeIndex > 0) { - glm::vec3 rightEye = _animSkeleton->getAbsolutePose(rightEyeIndex, poses).trans; - glm::vec3 leftEye = _animSkeleton->getAbsolutePose(leftEyeIndex, poses).trans; - glm::vec3 hips = _animSkeleton->getAbsolutePose(hipsIndex, poses).trans; - _eyesInRootFrame = 0.5f * (rightEye + leftEye) - hips; - } else { - glm::vec3 hips = _animSkeleton->getAbsolutePose(hipsIndex, poses).trans; - _eyesInRootFrame = 0.5f * (DEFAULT_RIGHT_EYE_POS + DEFAULT_LEFT_EYE_POS) - hips; - } - } -} - void Rig::setEnableInverseKinematics(bool enable) { _enableInverseKinematics = enable; } @@ -893,8 +879,6 @@ void Rig::updateAnimations(float deltaTime, glm::mat4 rootTransform) { for (auto& trigger : triggersOut) { _animVars.setTrigger(trigger); } - - computeEyesInRootFrame(_internalPoseSet._relativePoses); } applyOverridePoses(); @@ -1070,7 +1054,7 @@ void Rig::updateEyeJoint(int index, const glm::vec3& modelTranslation, const glm glm::quat desiredQuat = rotationBetween(IDENTITY_FRONT, zAxis); glm::quat headQuat; - int headIndex = _animSkeleton->nameToJointIndex("Head"); + int headIndex = indexOfJoint("Head"); if (headIndex >= 0) { headQuat = _internalPoseSet._absolutePoses[headIndex].rot; } @@ -1093,7 +1077,11 @@ void Rig::updateFromHandParameters(const HandParameters& params, float dt) { const float MIN_LENGTH = 1.0e-4f; // project the hips onto the xz plane. - auto hipsTrans = _internalPoseSet._absolutePoses[_animSkeleton->nameToJointIndex("Hips")].trans; + int hipsIndex = indexOfJoint("Hips"); + glm::vec3 hipsTrans; + if (hipsIndex >= 0) { + hipsTrans = _internalPoseSet._absolutePoses[hipsIndex].trans; + } const glm::vec2 bodyCircleCenter(hipsTrans.x, hipsTrans.z); if (params.isLeftEnabled) { @@ -1278,7 +1266,11 @@ void Rig::computeAvatarBoundingCapsule( AnimPose geometryToRig = _modelOffset * _geometryOffset; - AnimPose hips = geometryToRig * _animSkeleton->getAbsoluteBindPose(_animSkeleton->nameToJointIndex("Hips")); + AnimPose hips(glm::vec3(1), glm::quat(), glm::vec3()); + int hipsIndex = indexOfJoint("Hips"); + if (hipsIndex >= 0) { + hips = geometryToRig * _animSkeleton->getAbsoluteBindPose(hipsIndex); + } AnimVariantMap animVars; glm::quat handRotation = glm::angleAxis(PI, Vectors::UNIT_X); animVars.set("leftHandPosition", hips.trans); @@ -1288,8 +1280,8 @@ void Rig::computeAvatarBoundingCapsule( animVars.set("rightHandRotation", handRotation); animVars.set("rightHandType", (int)IKTarget::Type::RotationAndPosition); - int rightFootIndex = _animSkeleton->nameToJointIndex("RightFoot"); - int leftFootIndex = _animSkeleton->nameToJointIndex("LeftFoot"); + int rightFootIndex = indexOfJoint("RightFoot"); + int leftFootIndex = indexOfJoint("LeftFoot"); if (rightFootIndex != -1 && leftFootIndex != -1) { glm::vec3 foot = Vectors::ZERO; glm::quat footRotation = glm::angleAxis(0.5f * PI, Vectors::UNIT_X); @@ -1321,7 +1313,7 @@ void Rig::computeAvatarBoundingCapsule( // HACK to reduce the radius of the bounding capsule to be tight with the torso, we only consider joints // from the head to the hips when computing the rest of the bounding capsule. - int index = _animSkeleton->nameToJointIndex(QString("Head")); + int index = indexOfJoint("Head"); while (index != -1) { const FBXJointShapeInfo& shapeInfo = geometry.joints.at(index).shapeInfo; AnimPose pose = finalPoses[index]; @@ -1344,3 +1336,5 @@ void Rig::computeAvatarBoundingCapsule( glm::vec3 rigCenter = (geometryToRig * (0.5f * (totalExtents.maximum + totalExtents.minimum))); localOffsetOut = rigCenter - (geometryToRig * rootPosition); } + + diff --git a/libraries/animation/src/Rig.h b/libraries/animation/src/Rig.h index 9c5b014d55..3d5d44b844 100644 --- a/libraries/animation/src/Rig.h +++ b/libraries/animation/src/Rig.h @@ -231,8 +231,6 @@ public: void updateEyeJoint(int index, const glm::vec3& modelTranslation, const glm::quat& modelRotation, const glm::quat& worldHeadOrientation, const glm::vec3& lookAt, const glm::vec3& saccade); void calcAnimAlpha(float speed, const std::vector& referenceSpeeds, float* alphaOut) const; - void computeEyesInRootFrame(const AnimPoseVec& poses); - AnimPose _modelOffset; // model to rig space AnimPose _geometryOffset; // geometry to model space (includes unit offset & fst offsets) @@ -305,6 +303,8 @@ public: bool _lastEnableInverseKinematics { true }; bool _enableInverseKinematics { true }; + mutable uint32_t _jointNameWarningCount { 0 }; + private: QMap _stateHandlers; int _nextStateHandlerId { 0 };