diff --git a/examples/tPose.js b/examples/tPose.js new file mode 100644 index 0000000000..e6ead08420 --- /dev/null +++ b/examples/tPose.js @@ -0,0 +1,84 @@ +// +// tPose.js +// examples +// +// Created by Anthony Thibault on 11/9/2015 +// Copyright 2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// +// Example of how to put the avatar into it's default tpose. +// + +// TODO: CHANGE +var buttonImageUrl = "https://s3.amazonaws.com/hifi-public/images/tools/tpose.svg"; +var windowDimensions = Controller.getViewportDimensions(); + +var buttonWidth = 37; +var buttonHeight = 46; +var buttonPadding = 10; + +var buttonPositionX = windowDimensions.x - buttonPadding - buttonWidth; +var buttonPositionY = (windowDimensions.y - buttonHeight) / 2 - (buttonHeight + buttonPadding); + +var tPoseEnterImageOverlay = { + x: buttonPositionX, + y: buttonPositionY, + width: buttonWidth, + height: buttonHeight, + subImage: { x: 0, y: buttonHeight, width: buttonWidth, height: buttonHeight }, + imageURL: buttonImageUrl, + visible: true, + alpha: 1.0 +}; + +var tPoseExitImageOverlay = { + x: buttonPositionX, + y: buttonPositionY, + width: buttonWidth, + height: buttonHeight, + subImage: { x: buttonWidth, y: buttonHeight, width: buttonWidth, height: buttonHeight }, + imageURL: buttonImageUrl, + visible: false, + alpha: 1.0 +}; + +var tPoseEnterButton = Overlays.addOverlay("image", tPoseEnterImageOverlay); +var tPoseExitButton = Overlays.addOverlay("image", tPoseExitImageOverlay); +var tPose = false; + +function enterDefaultPose() { + tPose = true; + var i, l = MyAvatar.getJointNames().length; + var rot, trans; + for (i = 0; i < l; i++) { + rot = MyAvatar.getDefaultJointRotation(i); + trans = MyAvatar.getDefaultJointTranslation(i); + MyAvatar.setJointData(i, rot, trans); + } + Overlays.editOverlay(tPoseEnterButton, { visible: false }); + Overlays.editOverlay(tPoseExitButton, { visible: true }); +} + +function exitDefaultPose() { + tPose = false; + MyAvatar.clearJointsData(); + Overlays.editOverlay(tPoseEnterButton, { visible: true }); + Overlays.editOverlay(tPoseExitButton, { visible: false }); +} + +Controller.mousePressEvent.connect(function (event) { + var clickedOverlay = Overlays.getOverlayAtPoint({ x: event.x, y: event.y }); + if (clickedOverlay == tPoseEnterButton) { + enterDefaultPose(); + } else if (clickedOverlay == tPoseExitButton) { + exitDefaultPose(); + } +}); + +Script.scriptEnding.connect(function() { + Overlays.deleteOverlay(tPoseEnterButton); + Overlays.deleteOverlay(tPoseExitButton); +}); + diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index e2b92cc06f..8f8746dc27 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -869,6 +869,18 @@ glm::vec3 Avatar::getJointTranslation(int index) const { return translation; } +glm::quat Avatar::getDefaultJointRotation(int index) const { + glm::quat rotation; + _skeletonModel.getRelativeDefaultJointRotation(index, rotation); + return rotation; +} + +glm::vec3 Avatar::getDefaultJointTranslation(int index) const { + glm::vec3 translation; + _skeletonModel.getRelativeDefaultJointTranslation(index, translation); + return translation; +} + glm::quat Avatar::getAbsoluteJointRotationInObjectFrame(int index) const { glm::quat rotation; _skeletonModel.getAbsoluteJointRotationInRigFrame(index, rotation); diff --git a/interface/src/avatar/Avatar.h b/interface/src/avatar/Avatar.h index 99a4fc52a9..b161b46634 100644 --- a/interface/src/avatar/Avatar.h +++ b/interface/src/avatar/Avatar.h @@ -105,6 +105,10 @@ public: virtual QVector getJointRotations() const; virtual glm::quat getJointRotation(int index) const; virtual glm::vec3 getJointTranslation(int index) const; + + Q_INVOKABLE virtual glm::quat getDefaultJointRotation(int index) const; + Q_INVOKABLE virtual glm::vec3 getDefaultJointTranslation(int index) const; + virtual int getJointIndex(const QString& name) const; virtual QStringList getJointNames() const; diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 34821e6737..7cb6d37184 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -971,7 +971,11 @@ void MyAvatar::clearJointData(int index) { } void MyAvatar::clearJointsData() { - //clearJointAnimationPriorities(); + if (QThread::currentThread() != thread()) { + QMetaObject::invokeMethod(this, "clearJointsData"); + return; + } + _rig->clearJointStates(); } void MyAvatar::setFaceModelURL(const QUrl& faceModelURL) { diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index a80ef5d2eb..cd34303753 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -283,12 +283,14 @@ bool Rig::getJointStateTranslation(int index, glm::vec3& translation) const { void Rig::clearJointState(int index) { if (isIndexValid(index)) { _internalPoseSet._overrideFlags[index] = false; + _internalPoseSet._overridePoses[index] = _animSkeleton->getRelativeDefaultPose(index); } } void Rig::clearJointStates() { _internalPoseSet._overrideFlags.clear(); _internalPoseSet._overrideFlags.resize(_animSkeleton->getNumJoints()); + _internalPoseSet._overridePoses = _animSkeleton->getRelativeDefaultPoses(); } void Rig::clearJointAnimationPriority(int index) { @@ -464,6 +466,25 @@ const AnimPoseVec& Rig::getAbsoluteDefaultPoses() const { return _absoluteDefaultPoses; } + +bool Rig::getRelativeDefaultJointRotation(int index, glm::quat& rotationOut) const { + if (_animSkeleton && index >= 0 && index < _animSkeleton->getNumJoints()) { + rotationOut = _animSkeleton->getRelativeDefaultPose(index).rot; + return true; + } else { + return false; + } +} + +bool Rig::getRelativeDefaultJointTranslation(int index, glm::vec3& translationOut) const { + if (_animSkeleton && index >= 0 && index < _animSkeleton->getNumJoints()) { + translationOut = _animSkeleton->getRelativeDefaultPose(index).trans; + return true; + } else { + return false; + } +} + // animation reference speeds. static const std::vector FORWARD_SPEEDS = { 0.4f, 1.4f, 4.5f }; // m/s static const std::vector BACKWARD_SPEEDS = { 0.6f, 1.45f }; // m/s diff --git a/libraries/animation/src/Rig.h b/libraries/animation/src/Rig.h index e3ec5d18cf..9faf93e40b 100644 --- a/libraries/animation/src/Rig.h +++ b/libraries/animation/src/Rig.h @@ -200,6 +200,10 @@ public: // rig space const AnimPoseVec& getAbsoluteDefaultPoses() const; + // geometry space + bool getRelativeDefaultJointRotation(int index, glm::quat& rotationOut) const; + bool getRelativeDefaultJointTranslation(int index, glm::vec3& translationOut) const; + void copyJointsIntoJointData(QVector& jointDataVec) const; void copyJointsFromJointData(const QVector& jointDataVec); diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index b367d299e5..3a26a15855 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -766,12 +766,20 @@ bool Model::getJointTranslation(int jointIndex, glm::vec3& translation) const { return _rig->getJointTranslation(jointIndex, translation); } -bool Model::getAbsoluteJointRotationInRigFrame(int jointIndex, glm::quat& rotation) const { - return _rig->getAbsoluteJointRotationInRigFrame(jointIndex, rotation); +bool Model::getAbsoluteJointRotationInRigFrame(int jointIndex, glm::quat& rotationOut) const { + return _rig->getAbsoluteJointRotationInRigFrame(jointIndex, rotationOut); } -bool Model::getAbsoluteJointTranslationInRigFrame(int jointIndex, glm::vec3& translation) const { - return _rig->getAbsoluteJointTranslationInRigFrame(jointIndex, translation); +bool Model::getAbsoluteJointTranslationInRigFrame(int jointIndex, glm::vec3& translationOut) const { + return _rig->getAbsoluteJointTranslationInRigFrame(jointIndex, translationOut); +} + +bool Model::getRelativeDefaultJointRotation(int jointIndex, glm::quat& rotationOut) const { + return _rig->getRelativeDefaultJointRotation(jointIndex, rotationOut); +} + +bool Model::getRelativeDefaultJointTranslation(int jointIndex, glm::vec3& translationOut) const { + return _rig->getRelativeDefaultJointTranslation(jointIndex, translationOut); } bool Model::getJointCombinedRotation(int jointIndex, glm::quat& rotation) const { diff --git a/libraries/render-utils/src/Model.h b/libraries/render-utils/src/Model.h index d77cf830bd..001ae61c92 100644 --- a/libraries/render-utils/src/Model.h +++ b/libraries/render-utils/src/Model.h @@ -167,8 +167,11 @@ public: bool getJointTranslation(int jointIndex, glm::vec3& translation) const; // model frame - bool getAbsoluteJointRotationInRigFrame(int jointIndex, glm::quat& rotation) const; - bool getAbsoluteJointTranslationInRigFrame(int jointIndex, glm::vec3& translation) const; + bool getAbsoluteJointRotationInRigFrame(int jointIndex, glm::quat& rotationOut) const; + bool getAbsoluteJointTranslationInRigFrame(int jointIndex, glm::vec3& translationOut) const; + + bool getRelativeDefaultJointRotation(int jointIndex, glm::quat& rotationOut) const; + bool getRelativeDefaultJointTranslation(int jointIndex, glm::vec3& translationOut) const; /// Returns the index of the parent of the indexed joint, or -1 if not found. int getParentJointIndex(int jointIndex) const;