diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index fc4ca306af..0943d0a057 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -2475,12 +2475,46 @@ glm::vec3 MyAvatar::getAbsoluteJointTranslationInObjectFrame(int index) const { } } -void MyAvatar::pintJointInWorldSpace(int index, const glm::vec3& position, const glm::quat& orientation) { +bool MyAvatar::pinJoint(int index, const glm::vec3& position, const glm::quat& orientation) { + auto hipsIndex = getJointIndex("Hips"); + if (index != hipsIndex) { + qWarning() << "Pinning is only supported for the hips joint at the moment."; + return false; + } + auto jointTranslation = getAbsoluteJointTranslationInObjectFrame(index); + auto jointRotation = getAbsoluteJointRotationInObjectFrame(index); + + Transform final(orientation, Vectors::ONE, position); + Transform joint(jointRotation, Vectors::ONE, jointTranslation); + + Transform avatarTransform(final.getMatrix() * joint.getInverseMatrix()); + setPosition(avatarTransform.getTranslation()); + setOrientation(avatarTransform.getRotation()); + + _rig->setMaxHipsOffsetLength(0.0f); + + auto it = std::find(_pinnedJoints.begin(), _pinnedJoints.end(), index); + if (it != _pinnedJoints.end()) { + _pinnedJoints.push_back(index); + } + + return true; } -void MyAvatar::clearPinOnJoint(int index) { +bool MyAvatar::clearPinOnJoint(int index) { + auto it = std::find(_pinnedJoints.begin(), _pinnedJoints.end(), index); + if (it != _pinnedJoints.end()) { + _pinnedJoints.erase(it); + auto hipsIndex = getJointIndex("Hips"); + if (index == hipsIndex) { + _rig->setMaxHipsOffsetLength(1.0f); + } + + return true; + } + return false; } // thread-safe diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index 21c40bd370..360c6918d9 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -216,8 +216,8 @@ public: virtual void clearJointData(int index) override; virtual void clearJointsData() override; - Q_INVOKABLE void pintJointInWorldSpace(int index, const glm::vec3& position, const glm::quat& orientation); - Q_INVOKABLE void clearPinOnJoint(int index); + Q_INVOKABLE bool pinJoint(int index, const glm::vec3& position, const glm::quat& orientation); + Q_INVOKABLE bool clearPinOnJoint(int index); Q_INVOKABLE void useFullAvatarURL(const QUrl& fullAvatarURL, const QString& modelName = QString()); Q_INVOKABLE QUrl getFullAvatarURLFromPreferences() const { return _fullAvatarURLFromPreferences; } @@ -530,6 +530,8 @@ private: bool didTeleport(); bool getIsAway() const { return _isAway; } void setAway(bool value); + + std::vector _pinnedJoints; }; QScriptValue audioListenModeToScriptValue(QScriptEngine* engine, const AudioListenerMode& audioListenerMode);