From 03031c4c0438d43338ec0b4806adbfd3d2bcf39e Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Mon, 28 Jul 2014 16:36:12 -0700 Subject: [PATCH 1/7] Outdated link --- libraries/shared/src/SharedUtil.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/libraries/shared/src/SharedUtil.cpp b/libraries/shared/src/SharedUtil.cpp index e795ea746c..57d1d7faac 100644 --- a/libraries/shared/src/SharedUtil.cpp +++ b/libraries/shared/src/SharedUtil.cpp @@ -757,8 +757,7 @@ void setTranslation(glm::mat4& matrix, const glm::vec3& translation) { glm::quat extractRotation(const glm::mat4& matrix, bool assumeOrthogonal) { // uses the iterative polar decomposition algorithm described by Ken Shoemake at // http://www.cs.wisc.edu/graphics/Courses/838-s2002/Papers/polar-decomp.pdf - // code adapted from Clyde, https://github.com/threerings/clyde/blob/master/src/main/java/com/threerings/math/Matrix4f.java - + // code adapted from Clyde, https://github.com/threerings/clyde/blob/master/core/src/main/java/com/threerings/math/Matrix4f.java // start with the contents of the upper 3x3 portion of the matrix glm::mat3 upper = glm::mat3(matrix); if (!assumeOrthogonal) { From fb670275c2731d710d55634bb145e750b3d45e41 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Mon, 28 Jul 2014 16:42:16 -0700 Subject: [PATCH 2/7] Don't recompute unchaged transform --- interface/src/avatar/SkeletonModel.cpp | 3 ++- interface/src/renderer/JointState.cpp | 28 +++++++++++++++++++++----- interface/src/renderer/JointState.h | 5 ++++- interface/src/renderer/Model.cpp | 9 ++++++--- 4 files changed, 35 insertions(+), 10 deletions(-) diff --git a/interface/src/avatar/SkeletonModel.cpp b/interface/src/avatar/SkeletonModel.cpp index 3caaad1391..dc6a309e70 100644 --- a/interface/src/avatar/SkeletonModel.cpp +++ b/interface/src/avatar/SkeletonModel.cpp @@ -52,7 +52,8 @@ const float PALM_PRIORITY = 3.0f; void SkeletonModel::simulate(float deltaTime, bool fullUpdate) { setTranslation(_owningAvatar->getPosition()); - setRotation(_owningAvatar->getOrientation() * glm::angleAxis(PI, glm::vec3(0.0f, 1.0f, 0.0f))); + static const glm::quat refOrientation = glm::angleAxis(PI, glm::vec3(0.0f, 1.0f, 0.0f)); + setRotation(_owningAvatar->getOrientation() * refOrientation); const float MODEL_SCALE = 0.0006f; setScale(glm::vec3(1.0f, 1.0f, 1.0f) * _owningAvatar->getScale() * MODEL_SCALE); diff --git a/interface/src/renderer/JointState.cpp b/interface/src/renderer/JointState.cpp index 2a4372401e..0c27db3942 100644 --- a/interface/src/renderer/JointState.cpp +++ b/interface/src/renderer/JointState.cpp @@ -19,6 +19,7 @@ JointState::JointState() : _animationPriority(0.0f), + _transformChanged(true), _positionInParentFrame(0.0f), _distanceToParent(0.0f), _fbxJoint(NULL), @@ -26,6 +27,7 @@ JointState::JointState() : } JointState::JointState(const JointState& other) : _constraint(NULL) { + _transformChanged = true; _transform = other._transform; _rotation = other._rotation; _rotationInConstrainedFrame = other._rotationInConstrainedFrame; @@ -47,7 +49,10 @@ JointState::~JointState() { void JointState::setFBXJoint(const FBXJoint* joint) { assert(joint != NULL); - _rotationInConstrainedFrame = joint->rotation; + if (joint->rotation != _rotationInConstrainedFrame) { + _rotationInConstrainedFrame = joint->rotation; + _transformChanged = true; + } // NOTE: JointState does not own the FBXJoint to which it points. _fbxJoint = joint; if (_constraint) { @@ -71,6 +76,7 @@ void JointState::updateConstraint() { void JointState::copyState(const JointState& state) { _animationPriority = state._animationPriority; _transform = state._transform; + _transformChanged = true; _rotation = extractRotation(_transform); _rotationInConstrainedFrame = state._rotationInConstrainedFrame; _positionInParentFrame = state._positionInParentFrame; @@ -88,11 +94,20 @@ void JointState::initTransform(const glm::mat4& parentTransform) { _distanceToParent = glm::length(_positionInParentFrame); } -void JointState::computeTransform(const glm::mat4& parentTransform) { +void JointState::computeTransform(const glm::mat4& parentTransform, bool parentTransformChanged) { + if (!parentTransformChanged && !_transformChanged) { + return; + } + glm::quat rotationInParentFrame = _fbxJoint->preRotation * _rotationInConstrainedFrame * _fbxJoint->postRotation; glm::mat4 transformInParentFrame = _fbxJoint->preTransform * glm::mat4_cast(rotationInParentFrame) * _fbxJoint->postTransform; - _transform = parentTransform * glm::translate(_fbxJoint->translation) * transformInParentFrame; - _rotation = extractRotation(_transform); + glm::mat4 newTransform = parentTransform * glm::translate(_fbxJoint->translation) * transformInParentFrame; + _transformChanged = true; + + if (newTransform != _transform) { + _transform = newTransform; + _rotation = extractRotation(_transform); + } } void JointState::computeVisibleTransform(const glm::mat4& parentTransform) { @@ -139,6 +154,7 @@ void JointState::clearTransformTranslation() { _transform[3][0] = 0.0f; _transform[3][1] = 0.0f; _transform[3][2] = 0.0f; + _transformChanged = true; _visibleTransform[3][0] = 0.0f; _visibleTransform[3][1] = 0.0f; _visibleTransform[3][2] = 0.0f; @@ -151,13 +167,15 @@ void JointState::setRotation(const glm::quat& rotation, bool constrain, float pr void JointState::applyRotationDelta(const glm::quat& delta, bool constrain, float priority) { // NOTE: delta is in model-frame assert(_fbxJoint != NULL); - if (priority < _animationPriority) { + if (priority < _animationPriority || delta.null) { return; } _animationPriority = priority; if (!constrain || _constraint == NULL) { // no constraints _rotationInConstrainedFrame = _rotationInConstrainedFrame * glm::inverse(_rotation) * delta * _rotation; + _transformChanged = true; + _rotation = delta * _rotation; return; } diff --git a/interface/src/renderer/JointState.h b/interface/src/renderer/JointState.h index 94811fe13c..ea506a5db9 100644 --- a/interface/src/renderer/JointState.h +++ b/interface/src/renderer/JointState.h @@ -33,7 +33,7 @@ public: void copyState(const JointState& state); void initTransform(const glm::mat4& parentTransform); - void computeTransform(const glm::mat4& parentTransform); + void computeTransform(const glm::mat4& parentTransform, bool parentTransformChanged = true); void computeVisibleTransform(const glm::mat4& parentTransform); const glm::mat4& getVisibleTransform() const { return _visibleTransform; } @@ -41,6 +41,8 @@ public: glm::vec3 getVisiblePosition() const { return extractTranslation(_visibleTransform); } const glm::mat4& getTransform() const { return _transform; } + void resetTransformChanged() { _transformChanged = false; } + bool getTransformChanged() const { return _transformChanged; } glm::quat getRotation() const { return _rotation; } glm::vec3 getPosition() const { return extractTranslation(_transform); } @@ -104,6 +106,7 @@ private: /// debug helper function void loadBindRotation(); + bool _transformChanged; glm::mat4 _transform; // joint- to model-frame glm::quat _rotation; // joint- to model-frame glm::quat _rotationInConstrainedFrame; // rotation in frame where angular constraints would be applied diff --git a/interface/src/renderer/Model.cpp b/interface/src/renderer/Model.cpp index 8c19c11ed3..63a94772a7 100644 --- a/interface/src/renderer/Model.cpp +++ b/interface/src/renderer/Model.cpp @@ -922,7 +922,7 @@ void Model::simulate(float deltaTime, bool fullUpdate) { void Model::simulateInternal(float deltaTime) { // NOTE: this is a recursive call that walks all attachments, and their attachments // update the world space transforms for all joints - + // update animations foreach (const AnimationHandlePointer& handle, _runningAnimations) { handle->simulate(deltaTime); @@ -931,8 +931,11 @@ void Model::simulateInternal(float deltaTime) { for (int i = 0; i < _jointStates.size(); i++) { updateJointState(i); } + for (int i = 0; i < _jointStates.size(); i++) { + _jointStates[i].resetTransformChanged(); + } - _shapesAreDirty = ! _shapes.isEmpty(); + _shapesAreDirty = !_shapes.isEmpty(); // update the attachment transforms and simulate them const FBXGeometry& geometry = _geometry->getFBXGeometry(); @@ -994,7 +997,7 @@ void Model::updateJointState(int index) { state.computeTransform(parentTransform); } else { const JointState& parentState = _jointStates.at(parentIndex); - state.computeTransform(parentState.getTransform()); + state.computeTransform(parentState.getTransform(), parentState.getTransformChanged()); } } From 8354763e36e423c9ef0b15420e1926ff57342153 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Tue, 29 Jul 2014 13:35:13 -0700 Subject: [PATCH 3/7] CR --- interface/src/renderer/JointState.cpp | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/interface/src/renderer/JointState.cpp b/interface/src/renderer/JointState.cpp index 0c27db3942..bf28852d36 100644 --- a/interface/src/renderer/JointState.cpp +++ b/interface/src/renderer/JointState.cpp @@ -27,7 +27,7 @@ JointState::JointState() : } JointState::JointState(const JointState& other) : _constraint(NULL) { - _transformChanged = true; + _transformChanged = other._transformChanged; _transform = other._transform; _rotation = other._rotation; _rotationInConstrainedFrame = other._rotationInConstrainedFrame; @@ -49,10 +49,9 @@ JointState::~JointState() { void JointState::setFBXJoint(const FBXJoint* joint) { assert(joint != NULL); - if (joint->rotation != _rotationInConstrainedFrame) { - _rotationInConstrainedFrame = joint->rotation; - _transformChanged = true; - } + _rotationInConstrainedFrame = joint->rotation; + _transformChanged = true; + // NOTE: JointState does not own the FBXJoint to which it points. _fbxJoint = joint; if (_constraint) { @@ -76,7 +75,7 @@ void JointState::updateConstraint() { void JointState::copyState(const JointState& state) { _animationPriority = state._animationPriority; _transform = state._transform; - _transformChanged = true; + _transformChanged = state._transformChanged; _rotation = extractRotation(_transform); _rotationInConstrainedFrame = state._rotationInConstrainedFrame; _positionInParentFrame = state._positionInParentFrame; @@ -102,11 +101,11 @@ void JointState::computeTransform(const glm::mat4& parentTransform, bool parentT glm::quat rotationInParentFrame = _fbxJoint->preRotation * _rotationInConstrainedFrame * _fbxJoint->postRotation; glm::mat4 transformInParentFrame = _fbxJoint->preTransform * glm::mat4_cast(rotationInParentFrame) * _fbxJoint->postTransform; glm::mat4 newTransform = parentTransform * glm::translate(_fbxJoint->translation) * transformInParentFrame; - _transformChanged = true; if (newTransform != _transform) { _transform = newTransform; _rotation = extractRotation(_transform); + _transformChanged = true; } } @@ -171,15 +170,14 @@ void JointState::applyRotationDelta(const glm::quat& delta, bool constrain, floa return; } _animationPriority = priority; + glm::quat targetRotation = _rotationInConstrainedFrame * glm::inverse(_rotation) * delta * _rotation; if (!constrain || _constraint == NULL) { // no constraints - _rotationInConstrainedFrame = _rotationInConstrainedFrame * glm::inverse(_rotation) * delta * _rotation; - _transformChanged = true; + _rotationInConstrainedFrame = targetRotation; _rotation = delta * _rotation; return; } - glm::quat targetRotation = _rotationInConstrainedFrame * glm::inverse(_rotation) * delta * _rotation; setRotationInConstrainedFrame(targetRotation); } @@ -226,6 +224,7 @@ glm::quat JointState::computeVisibleParentRotation() const { void JointState::setRotationInConstrainedFrame(const glm::quat& targetRotation) { glm::quat parentRotation = computeParentRotation(); _rotationInConstrainedFrame = targetRotation; + _transformChanged = true; // R' = Rp * Rpre * r' * Rpost _rotation = parentRotation * _fbxJoint->preRotation * _rotationInConstrainedFrame * _fbxJoint->postRotation; } From 7800ffbf2eb6263923064bbe0bf700198e06b743 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Tue, 29 Jul 2014 15:55:47 -0700 Subject: [PATCH 4/7] Make _rotation extraction asynchronous by default in computeTransform --- interface/src/renderer/JointState.cpp | 32 ++++++++++++++++++++++++--- interface/src/renderer/JointState.h | 4 +++- 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/interface/src/renderer/JointState.cpp b/interface/src/renderer/JointState.cpp index bf28852d36..d4a589b657 100644 --- a/interface/src/renderer/JointState.cpp +++ b/interface/src/renderer/JointState.cpp @@ -11,8 +11,9 @@ #include +#include + #include -//#include #include #include "JointState.h" @@ -93,7 +94,7 @@ void JointState::initTransform(const glm::mat4& parentTransform) { _distanceToParent = glm::length(_positionInParentFrame); } -void JointState::computeTransform(const glm::mat4& parentTransform, bool parentTransformChanged) { +void JointState::computeTransform(const glm::mat4& parentTransform, bool parentTransformChanged, bool synchronousRotationCompute) { if (!parentTransformChanged && !_transformChanged) { return; } @@ -104,7 +105,11 @@ void JointState::computeTransform(const glm::mat4& parentTransform, bool parentT if (newTransform != _transform) { _transform = newTransform; - _rotation = extractRotation(_transform); + if (synchronousRotationCompute) { + _rotation = extractRotation(_transform); + } else { + QThreadPool::globalInstance()->start(new RotationExtractor(_transform, _rotation)); + } _transformChanged = true; } } @@ -253,3 +258,24 @@ void JointState::slaveVisibleTransform() { _visibleRotation = _rotation; _visibleRotationInConstrainedFrame = _rotationInConstrainedFrame; } + +class RotationExtractor : public QRunnable { +public: + + RotationExtractor(glm::mat4 transform, glm::quat& rotation); + + virtual void run(); + +private: + glm::mat4 _transform; + glm::quat _rotation; +}; + +RotationExtractor::RotationExtractor(glm::mat4 transform, glm::quat& rotation) { + _transform = transform; + _rotation = rotation; +} + +void RotationExtractor::run() { + _rotation = extractRotation(_transform); +} \ No newline at end of file diff --git a/interface/src/renderer/JointState.h b/interface/src/renderer/JointState.h index ea506a5db9..25333d730b 100644 --- a/interface/src/renderer/JointState.h +++ b/interface/src/renderer/JointState.h @@ -33,7 +33,9 @@ public: void copyState(const JointState& state); void initTransform(const glm::mat4& parentTransform); - void computeTransform(const glm::mat4& parentTransform, bool parentTransformChanged = true); + // if synchronousRotationCompute is true, then _transform is still computed synchronously, + // but _rotation will be asynchronously extracted + void computeTransform(const glm::mat4& parentTransform, bool parentTransformChanged = true, bool synchronousRotationCompute = false); void computeVisibleTransform(const glm::mat4& parentTransform); const glm::mat4& getVisibleTransform() const { return _visibleTransform; } From 42ba3ea33813813e5a86c586abbe0ae2fd68255e Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Tue, 29 Jul 2014 15:59:53 -0700 Subject: [PATCH 5/7] CR lost _transformChanged --- interface/src/renderer/JointState.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/interface/src/renderer/JointState.cpp b/interface/src/renderer/JointState.cpp index d4a589b657..b74cb83ad7 100644 --- a/interface/src/renderer/JointState.cpp +++ b/interface/src/renderer/JointState.cpp @@ -179,6 +179,7 @@ void JointState::applyRotationDelta(const glm::quat& delta, bool constrain, floa if (!constrain || _constraint == NULL) { // no constraints _rotationInConstrainedFrame = targetRotation; + _transformChanged = true; _rotation = delta * _rotation; return; From 8cd59ab5de876934c0c3de0cb36acdd4de6a1dad Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Tue, 29 Jul 2014 16:08:15 -0700 Subject: [PATCH 6/7] Forward declaration of RotationExtractor --- interface/src/renderer/JointState.cpp | 43 ++++++++++++++------------- 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/interface/src/renderer/JointState.cpp b/interface/src/renderer/JointState.cpp index b74cb83ad7..abaa9df7c8 100644 --- a/interface/src/renderer/JointState.cpp +++ b/interface/src/renderer/JointState.cpp @@ -18,6 +18,28 @@ #include "JointState.h" + +class RotationExtractor : public QRunnable { +public: + + RotationExtractor(glm::mat4 transform, glm::quat& rotation); + + virtual void run(); + +private: + glm::mat4 _transform; + glm::quat _rotation; +}; + +RotationExtractor::RotationExtractor(glm::mat4 transform, glm::quat& rotation) { + _transform = transform; + _rotation = rotation; +} + +void RotationExtractor::run() { + _rotation = extractRotation(_transform); +} + JointState::JointState() : _animationPriority(0.0f), _transformChanged(true), @@ -258,25 +280,4 @@ void JointState::slaveVisibleTransform() { _visibleTransform = _transform; _visibleRotation = _rotation; _visibleRotationInConstrainedFrame = _rotationInConstrainedFrame; -} - -class RotationExtractor : public QRunnable { -public: - - RotationExtractor(glm::mat4 transform, glm::quat& rotation); - - virtual void run(); - -private: - glm::mat4 _transform; - glm::quat _rotation; -}; - -RotationExtractor::RotationExtractor(glm::mat4 transform, glm::quat& rotation) { - _transform = transform; - _rotation = rotation; -} - -void RotationExtractor::run() { - _rotation = extractRotation(_transform); } \ No newline at end of file From 9b3cdacf08cd438261cea8e42c1bc84000aa55ed Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Tue, 29 Jul 2014 18:28:33 -0700 Subject: [PATCH 7/7] Removed microthreading in favor of lazy computation --- interface/src/renderer/JointState.cpp | 61 +++++++++++---------------- interface/src/renderer/JointState.h | 3 +- 2 files changed, 26 insertions(+), 38 deletions(-) diff --git a/interface/src/renderer/JointState.cpp b/interface/src/renderer/JointState.cpp index abaa9df7c8..316dfeb9ca 100644 --- a/interface/src/renderer/JointState.cpp +++ b/interface/src/renderer/JointState.cpp @@ -18,31 +18,10 @@ #include "JointState.h" - -class RotationExtractor : public QRunnable { -public: - - RotationExtractor(glm::mat4 transform, glm::quat& rotation); - - virtual void run(); - -private: - glm::mat4 _transform; - glm::quat _rotation; -}; - -RotationExtractor::RotationExtractor(glm::mat4 transform, glm::quat& rotation) { - _transform = transform; - _rotation = rotation; -} - -void RotationExtractor::run() { - _rotation = extractRotation(_transform); -} - JointState::JointState() : _animationPriority(0.0f), _transformChanged(true), + _rotationIsValid(false), _positionInParentFrame(0.0f), _distanceToParent(0.0f), _fbxJoint(NULL), @@ -52,6 +31,7 @@ JointState::JointState() : JointState::JointState(const JointState& other) : _constraint(NULL) { _transformChanged = other._transformChanged; _transform = other._transform; + _rotationIsValid = other._rotationIsValid; _rotation = other._rotation; _rotationInConstrainedFrame = other._rotationInConstrainedFrame; _positionInParentFrame = other._positionInParentFrame; @@ -70,10 +50,20 @@ JointState::~JointState() { } } +glm::quat JointState::getRotation() const { + if (!_rotationIsValid) { + const_cast(this)->_rotation = extractRotation(_transform); + const_cast(this)->_rotationIsValid = true; + } + + return _rotation; +} + void JointState::setFBXJoint(const FBXJoint* joint) { assert(joint != NULL); _rotationInConstrainedFrame = joint->rotation; _transformChanged = true; + _rotationIsValid = false; // NOTE: JointState does not own the FBXJoint to which it points. _fbxJoint = joint; @@ -97,9 +87,10 @@ void JointState::updateConstraint() { void JointState::copyState(const JointState& state) { _animationPriority = state._animationPriority; - _transform = state._transform; _transformChanged = state._transformChanged; - _rotation = extractRotation(_transform); + _transform = state._transform; + _rotationIsValid = state._rotationIsValid; + _rotation = state._rotation; _rotationInConstrainedFrame = state._rotationInConstrainedFrame; _positionInParentFrame = state._positionInParentFrame; _distanceToParent = state._distanceToParent; @@ -127,12 +118,8 @@ void JointState::computeTransform(const glm::mat4& parentTransform, bool parentT if (newTransform != _transform) { _transform = newTransform; - if (synchronousRotationCompute) { - _rotation = extractRotation(_transform); - } else { - QThreadPool::globalInstance()->start(new RotationExtractor(_transform, _rotation)); - } _transformChanged = true; + _rotationIsValid = false; } } @@ -144,7 +131,7 @@ void JointState::computeVisibleTransform(const glm::mat4& parentTransform) { } glm::quat JointState::getRotationInBindFrame() const { - return _rotation * _fbxJoint->inverseBindRotation; + return getRotation() * _fbxJoint->inverseBindRotation; } glm::quat JointState::getRotationInParentFrame() const { @@ -167,7 +154,7 @@ void JointState::setRotationInBindFrame(const glm::quat& rotation, float priorit // rotation is from bind- to model-frame assert(_fbxJoint != NULL); if (priority >= _animationPriority) { - glm::quat targetRotation = _rotationInConstrainedFrame * glm::inverse(_rotation) * rotation * glm::inverse(_fbxJoint->inverseBindRotation); + glm::quat targetRotation = _rotationInConstrainedFrame * glm::inverse(getRotation()) * rotation * glm::inverse(_fbxJoint->inverseBindRotation); if (constrain && _constraint) { _constraint->softClamp(targetRotation, _rotationInConstrainedFrame, 0.5f); } @@ -187,7 +174,7 @@ void JointState::clearTransformTranslation() { } void JointState::setRotation(const glm::quat& rotation, bool constrain, float priority) { - applyRotationDelta(rotation * glm::inverse(_rotation), true, priority); + applyRotationDelta(rotation * glm::inverse(getRotation()), true, priority); } void JointState::applyRotationDelta(const glm::quat& delta, bool constrain, float priority) { @@ -197,13 +184,13 @@ void JointState::applyRotationDelta(const glm::quat& delta, bool constrain, floa return; } _animationPriority = priority; - glm::quat targetRotation = _rotationInConstrainedFrame * glm::inverse(_rotation) * delta * _rotation; + glm::quat targetRotation = _rotationInConstrainedFrame * glm::inverse(getRotation()) * delta * getRotation(); if (!constrain || _constraint == NULL) { // no constraints _rotationInConstrainedFrame = targetRotation; _transformChanged = true; - _rotation = delta * _rotation; + _rotation = delta * getRotation(); return; } setRotationInConstrainedFrame(targetRotation); @@ -218,7 +205,7 @@ void JointState::mixRotationDelta(const glm::quat& delta, float mixFactor, float return; } _animationPriority = priority; - glm::quat targetRotation = _rotationInConstrainedFrame * glm::inverse(_rotation) * delta * _rotation; + glm::quat targetRotation = _rotationInConstrainedFrame * glm::inverse(getRotation()) * delta * getRotation(); if (mixFactor > 0.0f && mixFactor <= 1.0f) { targetRotation = safeMix(targetRotation, _fbxJoint->rotation, mixFactor); } @@ -242,7 +229,7 @@ void JointState::mixVisibleRotationDelta(const glm::quat& delta, float mixFactor glm::quat JointState::computeParentRotation() const { // R = Rp * Rpre * r * Rpost // Rp = R * (Rpre * r * Rpost)^ - return _rotation * glm::inverse(_fbxJoint->preRotation * _rotationInConstrainedFrame * _fbxJoint->postRotation); + return getRotation() * glm::inverse(_fbxJoint->preRotation * _rotationInConstrainedFrame * _fbxJoint->postRotation); } glm::quat JointState::computeVisibleParentRotation() const { @@ -278,6 +265,6 @@ const glm::vec3& JointState::getDefaultTranslationInConstrainedFrame() const { void JointState::slaveVisibleTransform() { _visibleTransform = _transform; - _visibleRotation = _rotation; + _visibleRotation = getRotation(); _visibleRotationInConstrainedFrame = _rotationInConstrainedFrame; } \ No newline at end of file diff --git a/interface/src/renderer/JointState.h b/interface/src/renderer/JointState.h index 25333d730b..81591e816b 100644 --- a/interface/src/renderer/JointState.h +++ b/interface/src/renderer/JointState.h @@ -46,7 +46,7 @@ public: void resetTransformChanged() { _transformChanged = false; } bool getTransformChanged() const { return _transformChanged; } - glm::quat getRotation() const { return _rotation; } + glm::quat getRotation() const; glm::vec3 getPosition() const { return extractTranslation(_transform); } /// \return rotation from bind to model frame @@ -110,6 +110,7 @@ private: bool _transformChanged; glm::mat4 _transform; // joint- to model-frame + bool _rotationIsValid; glm::quat _rotation; // joint- to model-frame glm::quat _rotationInConstrainedFrame; // rotation in frame where angular constraints would be applied glm::vec3 _positionInParentFrame; // only changes when the Model is scaled