diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index 67dfbec24a..378bd55667 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -165,6 +165,7 @@ void Rig::destroyAnimGraph() { void Rig::initJointStates(const FBXGeometry& geometry, const glm::mat4& modelOffset) { _geometryOffset = AnimPose(geometry.offset); + _invGeometryOffset = _geometryOffset.inverse(); setModelOffset(modelOffset); _animSkeleton = std::make_shared(geometry); @@ -193,6 +194,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); _internalPoseSet._relativePoses.clear(); @@ -272,24 +274,6 @@ void Rig::setModelOffset(const glm::mat4& modelOffsetMat) { } } -bool Rig::getJointStateRotation(int index, glm::quat& rotation) const { - if (isIndexValid(index)) { - rotation = _internalPoseSet._relativePoses[index].rot; - return !isEqual(rotation, _animSkeleton->getRelativeDefaultPose(index).rot); - } else { - return false; - } -} - -bool Rig::getJointStateTranslation(int index, glm::vec3& translation) const { - if (isIndexValid(index)) { - translation = _internalPoseSet._relativePoses[index].trans; - return !isEqual(translation, _animSkeleton->getRelativeDefaultPose(index).trans); - } else { - return false; - } -} - void Rig::clearJointState(int index) { if (isIndexValid(index)) { _internalPoseSet._overrideFlags[index] = false; @@ -446,6 +430,23 @@ void Rig::calcAnimAlpha(float speed, const std::vector& referenceSpeeds, *alphaOut = alpha; } +bool Rig::getJointData(int index, JointData& jointDataOut) const { + if (isIndexValid(index)) { + jointDataOut.rotation = _internalPoseSet._absolutePoses[index].rot; + jointDataOut.rotationSet = !isEqual(jointDataOut.rotation, _animSkeleton->getAbsoluteDefaultPose(index).rot); + + // geometry offset is used here so that translations are in meters, this is what the avatar mixer expects + jointDataOut.translation = _geometryOffset * _internalPoseSet._absolutePoses[index].trans; + jointDataOut.translationSet = !isEqual(jointDataOut.translation, _animSkeleton->getAbsoluteDefaultPose(index).trans); + return true; + } else { + jointDataOut.translationSet = false; + jointDataOut.rotationSet = false; + return false; + } +} + + void Rig::setEnableInverseKinematics(bool enable) { _enableInverseKinematics = enable; } @@ -1232,21 +1233,44 @@ void Rig::copyJointsIntoJointData(QVector& jointDataVec) const { jointDataVec.resize((int)getJointStateCount()); for (auto i = 0; i < jointDataVec.size(); i++) { JointData& data = jointDataVec[i]; - data.rotationSet |= getJointStateRotation(i, data.rotation); - // geometry offset is used here so that translations are in meters. - // this is what the avatar mixer expects - data.translationSet |= getJointStateTranslation(i, data.translation); - data.translation = _geometryOffset * data.translation; + getJointData(i, data); } } void Rig::copyJointsFromJointData(const QVector& jointDataVec) { - AnimPose invGeometryOffset = _geometryOffset.inverse(); - for (int i = 0; i < jointDataVec.size(); i++) { - const JointData& data = jointDataVec.at(i); - setJointRotation(i, data.rotationSet, data.rotation, 1.0f); - // geometry offset is used here to undo the fact that avatar mixer translations are in meters. - setJointTranslation(i, data.translationSet, invGeometryOffset * data.translation, 1.0f); + + if (_animSkeleton) { + + std::vector overrideFlags(_internalPoseSet._overridePoses.size(), false); + AnimPoseVec overridePoses = _animSkeleton->getAbsoluteDefaultPoses(); // start with the default poses. + + ASSERT(overrideFlags.size() == absoluteOverridePoses.size()); + + for (int i = 0; i < jointDataVec.size(); i++) { + if (isIndexValid(i)) { + const JointData& data = jointDataVec.at(i); + if (data.rotationSet) { + overrideFlags[i] = true; + overridePoses[i].rot = data.rotation; + } + if (data.translationSet) { + overrideFlags[i] = true; + // convert from meters back into geometry units. + overridePoses[i].trans = _invGeometryOffset * data.translation; + } + } + } + + ASSERT(_internalPoseSet._overrideFlags.size() == _internalPoseSet._overridePoses.size()); + + _animSkeleton->convertAbsolutePosesToRelative(overridePoses); + + for (int i = 0; i < jointDataVec.size(); i++) { + if (overrideFlags[i]) { + _internalPoseSet._overrideFlags[i] = true; + _internalPoseSet._overridePoses[i] = overridePoses[i]; + } + } } } diff --git a/libraries/animation/src/Rig.h b/libraries/animation/src/Rig.h index 363006d48c..7446fddc47 100644 --- a/libraries/animation/src/Rig.h +++ b/libraries/animation/src/Rig.h @@ -104,12 +104,6 @@ public: void setModelOffset(const glm::mat4& modelOffsetMat); - // geometry space - bool getJointStateRotation(int index, glm::quat& rotation) const; - - // geometry space - bool getJointStateTranslation(int index, glm::vec3& translation) const; - void clearJointState(int index); void clearJointStates(); void clearJointAnimationPriority(int index); @@ -119,8 +113,6 @@ public: // geometry space void setJointTranslation(int index, bool valid, const glm::vec3& translation, float priority); - - // geometry space void setJointRotation(int index, bool valid, const glm::quat& rotation, float priority); // legacy @@ -237,8 +229,12 @@ protected: 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; + // geometry space + bool getJointData(int index, JointData& jointDataOut) const; + AnimPose _modelOffset; // model to rig space AnimPose _geometryOffset; // geometry to model space (includes unit offset & fst offsets) + AnimPose _invGeometryOffset; struct PoseSet { AnimPoseVec _relativePoses; // geometry space relative to parent. diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index 9c556dc42b..784044da2e 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -121,6 +121,8 @@ void AvatarData::setHandPosition(const glm::vec3& handPosition) { _handPosition = glm::inverse(getOrientation()) * (handPosition - getPosition()); } +#define WANT_DEBUG + QByteArray AvatarData::toByteArray(bool cullSmallChanges, bool sendAll) { // TODO: DRY this up to a shared method // that can pack any type given the number of bytes @@ -329,7 +331,7 @@ QByteArray AvatarData::toByteArray(bool cullSmallChanges, bool sendAll) { } #ifdef WANT_DEBUG - if (sendAll) { + //if (sendAll) { qDebug() << "AvatarData::toByteArray" << cullSmallChanges << sendAll << "rotations:" << rotationSentCount << "translations:" << translationSentCount << "largest:" << maxTranslationDimension @@ -339,7 +341,7 @@ QByteArray AvatarData::toByteArray(bool cullSmallChanges, bool sendAll) { << (beforeTranslations - beforeRotations) << "+" << (destinationBuffer - beforeTranslations) << "=" << (destinationBuffer - startPosition); - } + //} #endif return avatarDataByteArray.left(destinationBuffer - startPosition); diff --git a/libraries/networking/src/udt/PacketHeaders.h b/libraries/networking/src/udt/PacketHeaders.h index b98a87e439..e0d854ab71 100644 --- a/libraries/networking/src/udt/PacketHeaders.h +++ b/libraries/networking/src/udt/PacketHeaders.h @@ -174,7 +174,8 @@ const PacketVersion VERSION_LIGHT_HAS_FALLOFF_RADIUS = 57; enum class AvatarMixerPacketVersion : PacketVersion { TranslationSupport = 17, - SoftAttachmentSupport + SoftAttachmentSupport, + AbsoluteFortyEightBitRotations }; #endif // hifi_PacketHeaders_h diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index 2fe4427333..e4c414d30b 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -726,10 +726,6 @@ glm::vec3 Model::calculateScaledOffsetPoint(const glm::vec3& point) const { return translatedPoint; } -bool Model::getJointState(int index, glm::quat& rotation) const { - return _rig->getJointStateRotation(index, rotation); -} - void Model::clearJointState(int index) { _rig->clearJointState(index); } diff --git a/libraries/render-utils/src/Model.h b/libraries/render-utils/src/Model.h index 581184918d..6a7c9ec560 100644 --- a/libraries/render-utils/src/Model.h +++ b/libraries/render-utils/src/Model.h @@ -252,10 +252,6 @@ protected: /// Returns the scaled equivalent of a point in model space. glm::vec3 calculateScaledOffsetPoint(const glm::vec3& point) const; - /// Fetches the joint state at the specified index. - /// \return whether or not the joint state is "valid" (that is, non-default) - bool getJointState(int index, glm::quat& rotation) const; - /// Clear the joint states void clearJointState(int index);