diff --git a/interface/src/avatar/SkeletonModel.cpp b/interface/src/avatar/SkeletonModel.cpp index dd398f2b2b..a087693615 100644 --- a/interface/src/avatar/SkeletonModel.cpp +++ b/interface/src/avatar/SkeletonModel.cpp @@ -243,7 +243,7 @@ void SkeletonModel::updateJointState(int index) { const JointState& parentState = _jointStates.at(joint.parentIndex); const FBXGeometry& geometry = _geometry->getFBXGeometry(); if (index == geometry.leanJointIndex) { - maybeUpdateLeanRotation(parentState, joint, state); + maybeUpdateLeanRotation(parentState, state); } else if (index == geometry.neckJointIndex) { maybeUpdateNeckRotation(parentState, joint, state); @@ -260,17 +260,18 @@ void SkeletonModel::updateJointState(int index) { } } -void SkeletonModel::maybeUpdateLeanRotation(const JointState& parentState, const FBXJoint& joint, JointState& state) { +void SkeletonModel::maybeUpdateLeanRotation(const JointState& parentState, JointState& state) { if (!_owningAvatar->isMyAvatar() || Application::getInstance()->getPrioVR()->isActive()) { return; } // get the rotation axes in joint space and use them to adjust the rotation - glm::mat3 axes = glm::mat3_cast(glm::quat()); - glm::mat3 inverse = glm::mat3(glm::inverse(parentState.getTransform() * glm::translate(state.getDefaultTranslationInConstrainedFrame()) * - joint.preTransform * glm::mat4_cast(joint.preRotation * joint.rotation))); - state.setRotationInConstrainedFrame(glm::angleAxis(- RADIANS_PER_DEGREE * _owningAvatar->getHead()->getFinalLeanSideways(), - glm::normalize(inverse * axes[2])) * glm::angleAxis(- RADIANS_PER_DEGREE * _owningAvatar->getHead()->getFinalLeanForward(), - glm::normalize(inverse * axes[0])) * joint.rotation); + glm::vec3 xAxis(1.0f, 0.0f, 0.0f); + glm::vec3 zAxis(0.0f, 0.0f, 1.0f); + glm::quat inverse = glm::inverse(parentState.getRotation() * state.getDefaultRotationInParentFrame()); + state.setRotationInConstrainedFrame( + glm::angleAxis(- RADIANS_PER_DEGREE * _owningAvatar->getHead()->getFinalLeanSideways(), inverse * zAxis) + * glm::angleAxis(- RADIANS_PER_DEGREE * _owningAvatar->getHead()->getFinalLeanForward(), inverse * xAxis) + * state.getFBXJoint().rotation); } void SkeletonModel::maybeUpdateNeckRotation(const JointState& parentState, const FBXJoint& joint, JointState& state) { diff --git a/interface/src/avatar/SkeletonModel.h b/interface/src/avatar/SkeletonModel.h index b0d6ed7325..9bd8df745a 100644 --- a/interface/src/avatar/SkeletonModel.h +++ b/interface/src/avatar/SkeletonModel.h @@ -127,7 +127,7 @@ protected: /// Updates the state of the joint at the specified index. virtual void updateJointState(int index); - void maybeUpdateLeanRotation(const JointState& parentState, const FBXJoint& joint, JointState& state); + void maybeUpdateLeanRotation(const JointState& parentState, JointState& state); void maybeUpdateNeckRotation(const JointState& parentState, const FBXJoint& joint, JointState& state); void maybeUpdateEyeRotation(const JointState& parentState, const FBXJoint& joint, JointState& state); diff --git a/interface/src/renderer/JointState.cpp b/interface/src/renderer/JointState.cpp index 94b4b37a3c..9492413f54 100644 --- a/interface/src/renderer/JointState.cpp +++ b/interface/src/renderer/JointState.cpp @@ -254,6 +254,11 @@ const bool JointState::rotationIsDefault(const glm::quat& rotation, float tolera glm::abs(rotation.w - defaultRotation.w) < tolerance; } +glm::quat JointState::getDefaultRotationInParentFrame() const { + // NOTE: the result is constant and could be cached in the FBXJoint + return _fbxJoint->preRotation * _fbxJoint->rotation * _fbxJoint->postRotation; +} + const glm::vec3& JointState::getDefaultTranslationInConstrainedFrame() const { assert(_fbxJoint != NULL); return _fbxJoint->translation; diff --git a/interface/src/renderer/JointState.h b/interface/src/renderer/JointState.h index 56044125f1..bc0c6dd51f 100644 --- a/interface/src/renderer/JointState.h +++ b/interface/src/renderer/JointState.h @@ -88,6 +88,7 @@ public: const bool rotationIsDefault(const glm::quat& rotation, float tolerance = EPSILON) const; + glm::quat getDefaultRotationInParentFrame() const; const glm::vec3& getDefaultTranslationInConstrainedFrame() const;