From 33c97a18337fdbf46a5713aad8a03bf7ca882c93 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Thu, 23 Jul 2015 15:14:10 -0700 Subject: [PATCH] get rid of _firstPersonSkeletonModel in MyAvatar. add flag in Rig for joints being dirty so Model knows when to recompute meshes --- interface/src/avatar/MyAvatar.cpp | 25 +----- interface/src/avatar/MyAvatar.h | 2 - interface/src/avatar/SkeletonModel.cpp | 90 ++++++++------------- interface/src/avatar/SkeletonModel.h | 7 +- libraries/animation/src/AnimationHandle.cpp | 6 +- libraries/animation/src/Rig.cpp | 89 ++++++++++++++++---- libraries/animation/src/Rig.h | 31 +++++-- libraries/render-utils/src/Model.cpp | 24 +----- libraries/render-utils/src/Model.h | 3 - 9 files changed, 137 insertions(+), 140 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 178ebc0487..d46870b479 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -103,11 +103,8 @@ MyAvatar::MyAvatar(RigPointer rig) : _realWorldFieldOfView("realWorldFieldOfView", DEFAULT_REAL_WORLD_FIELD_OF_VIEW_DEGREES), _rig(rig), - _firstPersonSkeletonModel(this, nullptr, rig), _prevShouldDrawHead(true) { - _firstPersonSkeletonModel.setIsFirstPerson(true); - ShapeCollider::initDispatchTable(); for (int i = 0; i < MAX_DRIVE_KEYS; i++) { _driveKeys[i] = 0.0f; @@ -141,7 +138,6 @@ QByteArray MyAvatar::toByteArray() { void MyAvatar::reset() { _skeletonModel.reset(); - _firstPersonSkeletonModel.reset(); getHead()->reset(); _targetVelocity = glm::vec3(0.0f); @@ -200,7 +196,6 @@ void MyAvatar::simulate(float deltaTime) { { PerformanceTimer perfTimer("skeleton"); _skeletonModel.simulate(deltaTime); - _firstPersonSkeletonModel.simulate(deltaTime); } if (!_skeletonModel.hasSkeleton()) { @@ -1028,15 +1023,8 @@ void MyAvatar::setSkeletonModelURL(const QUrl& skeletonModelURL) { if (_useFullAvatar) { _skeletonModel.setVisibleInScene(_prevShouldDrawHead, scene); - - const QUrl DEFAULT_SKELETON_MODEL_URL = QUrl::fromLocalFile(PathUtils::resourcesPath() + "meshes/defaultAvatar_body.fst"); - _firstPersonSkeletonModel.setURL(_skeletonModelURL, DEFAULT_SKELETON_MODEL_URL, true, !isMyAvatar()); - _firstPersonSkeletonModel.setVisibleInScene(!_prevShouldDrawHead, scene); } else { _skeletonModel.setVisibleInScene(true, scene); - - _firstPersonSkeletonModel.setVisibleInScene(false, scene); - _firstPersonSkeletonModel.reset(); } } @@ -1254,23 +1242,14 @@ void MyAvatar::preRender(RenderArgs* renderArgs) { const bool shouldDrawHead = shouldRenderHead(renderArgs); _skeletonModel.initWhenReady(scene); - if (_useFullAvatar) { - _firstPersonSkeletonModel.initWhenReady(scene); - } if (shouldDrawHead != _prevShouldDrawHead) { if (_useFullAvatar) { - if (shouldDrawHead) { - _skeletonModel.setVisibleInScene(true, scene); - _firstPersonSkeletonModel.setVisibleInScene(false, scene); - } else { - _skeletonModel.setVisibleInScene(false, scene); - _firstPersonSkeletonModel.setVisibleInScene(true, scene); - } + _skeletonModel.setVisibleInScene(true, scene); + _rig->setFirstPerson(!shouldDrawHead); } else { getHead()->getFaceModel().setVisibleInScene(shouldDrawHead, scene); } - } _prevShouldDrawHead = shouldDrawHead; } diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index 0c598c21be..c6cb48878f 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -287,8 +287,6 @@ private: QString _fullAvatarModelName; RigPointer _rig; - // used for rendering when in first person view or when in an HMD. - SkeletonModel _firstPersonSkeletonModel; bool _prevShouldDrawHead; }; diff --git a/interface/src/avatar/SkeletonModel.cpp b/interface/src/avatar/SkeletonModel.cpp index 2d9db1abb7..0ee3898a20 100644 --- a/interface/src/avatar/SkeletonModel.cpp +++ b/interface/src/avatar/SkeletonModel.cpp @@ -40,8 +40,7 @@ SkeletonModel::SkeletonModel(Avatar* owningAvatar, QObject* parent, RigPointer r _standingFoot(NO_FOOT), _standingOffset(0.0f), _clampedFootPosition(0.0f), - _headClipDistance(DEFAULT_NEAR_CLIP), - _isFirstPerson(false) + _headClipDistance(DEFAULT_NEAR_CLIP) { assert(_rig); assert(_owningAvatar); @@ -54,7 +53,7 @@ SkeletonModel::~SkeletonModel() { void SkeletonModel::initJointStates(QVector states) { const FBXGeometry& geometry = _geometry->getFBXGeometry(); glm::mat4 parentTransform = glm::scale(_scale) * glm::translate(_offset) * geometry.offset; - _boundingRadius = _rig->initJointStates(states, parentTransform); + _boundingRadius = _rig->initJointStates(states, parentTransform, geometry.neckJointIndex); // Determine the default eye position for avatar scale = 1.0 int headJointIndex = _geometry->getFBXGeometry().headJointIndex; @@ -98,6 +97,29 @@ void SkeletonModel::initJointStates(QVector states) { const float PALM_PRIORITY = DEFAULT_PRIORITY; const float LEAN_PRIORITY = DEFAULT_PRIORITY; + +void SkeletonModel::updateClusterMatrices() { + const FBXGeometry& geometry = _geometry->getFBXGeometry(); + glm::mat4 modelToWorld = glm::mat4_cast(_rotation); + for (int i = 0; i < _meshStates.size(); i++) { + MeshState& state = _meshStates[i]; + const FBXMesh& mesh = geometry.meshes.at(i); + if (_showTrueJointTransforms) { + for (int j = 0; j < mesh.clusters.size(); j++) { + const FBXCluster& cluster = mesh.clusters.at(j); + state.clusterMatrices[j] = + modelToWorld * _rig->getJointTransform(cluster.jointIndex) * cluster.inverseBindMatrix; + } + } else { + for (int j = 0; j < mesh.clusters.size(); j++) { + const FBXCluster& cluster = mesh.clusters.at(j); + state.clusterMatrices[j] = + modelToWorld * _rig->getJointVisibleTransform(cluster.jointIndex) * cluster.inverseBindMatrix; + } + } + } +} + void SkeletonModel::simulate(float deltaTime, bool fullUpdate) { setTranslation(_owningAvatar->getSkeletonPosition()); static const glm::quat refOrientation = glm::angleAxis(PI, glm::vec3(0.0f, 1.0f, 0.0f)); @@ -154,8 +176,11 @@ void SkeletonModel::simulate(float deltaTime, bool fullUpdate) { } } - if (_isFirstPerson) { - cauterizeHead(); + // if (_isFirstPerson) { + // cauterizeHead(); + // updateClusterMatrices(); + // } + if (_rig->getJointsAreDirty()) { updateClusterMatrices(); } @@ -764,7 +789,7 @@ void SkeletonModel::resetShapePositionsToDefaultPose() { // geometry or joints have not yet been created return; } - + const FBXGeometry& geometry = _geometry->getFBXGeometry(); if (geometry.joints.isEmpty()) { return; @@ -820,7 +845,7 @@ void SkeletonModel::renderBoundingCollisionShapes(gpu::Batch& batch, float alpha // draw a green cylinder between the two points glm::vec3 origin(0.0f); - Avatar::renderJointConnectingCone(batch, origin, axis, _boundingShape.getRadius(), _boundingShape.getRadius(), + Avatar::renderJointConnectingCone(batch, origin, axis, _boundingShape.getRadius(), _boundingShape.getRadius(), glm::vec4(0.6f, 0.8f, 0.6f, alpha)); } @@ -828,56 +853,5 @@ bool SkeletonModel::hasSkeleton() { return isActive() ? _geometry->getFBXGeometry().rootJointIndex != -1 : false; } -void SkeletonModel::initHeadBones() { - _headBones.clear(); - const FBXGeometry& fbxGeometry = _geometry->getFBXGeometry(); - const int neckJointIndex = fbxGeometry.neckJointIndex; - std::queue q; - q.push(neckJointIndex); - _headBones.push_back(neckJointIndex); - - // fbxJoints only hold links to parents not children, so we have to do a bit of extra work here. - while (q.size() > 0) { - int jointIndex = q.front(); - for (int i = 0; i < fbxGeometry.joints.size(); i++) { - const FBXJoint& fbxJoint = fbxGeometry.joints[i]; - if (jointIndex == fbxJoint.parentIndex) { - _headBones.push_back(i); - q.push(i); - } - } - q.pop(); - } -} - -void SkeletonModel::invalidateHeadBones() { - _headBones.clear(); -} - -void SkeletonModel::cauterizeHead() { - if (isActive()) { - const FBXGeometry& geometry = _geometry->getFBXGeometry(); - const int neckJointIndex = geometry.neckJointIndex; - if (neckJointIndex > 0 && neckJointIndex < _rig->getJointStateCount()) { - - // lazy init of headBones - if (_headBones.size() == 0) { - initHeadBones(); - } - - // preserve the translation for the neck - // glm::vec4 trans = _jointStates[neckJointIndex].getTransform()[3]; - glm::vec4 trans = _rig->getJointTransform(neckJointIndex)[3]; - glm::vec4 zero(0, 0, 0, 0); - for (const int &i : _headBones) { - glm::mat4 newXform(zero, zero, zero, trans); - _rig->setJointTransform(i, newXform); - _rig->setJointVisibleTransform(i, newXform); - } - } - } -} - void SkeletonModel::onInvalidate() { - invalidateHeadBones(); } diff --git a/interface/src/avatar/SkeletonModel.h b/interface/src/avatar/SkeletonModel.h index c4cd43b4df..0678ae48d4 100644 --- a/interface/src/avatar/SkeletonModel.h +++ b/interface/src/avatar/SkeletonModel.h @@ -112,9 +112,6 @@ public: float getHeadClipDistance() const { return _headClipDistance; } - void setIsFirstPerson(bool value) { _isFirstPerson = value; } - bool getIsFirstPerson() const { return _isFirstPerson; } - virtual void onInvalidate() override; signals: @@ -138,6 +135,7 @@ protected: void maybeUpdateNeckRotation(const JointState& parentState, const FBXJoint& joint, int index); void maybeUpdateEyeRotation(const JointState& parentState, const FBXJoint& joint, int index); + void updateClusterMatrices(); void cauterizeHead(); void initHeadBones(); void invalidateHeadBones(); @@ -173,9 +171,6 @@ private: glm::vec3 _clampedFootPosition; float _headClipDistance; // Near clip distance to use if no separate head model - - bool _isFirstPerson; - std::vector _headBones; }; #endif // hifi_SkeletonModel_h diff --git a/libraries/animation/src/AnimationHandle.cpp b/libraries/animation/src/AnimationHandle.cpp index d11dcacfc6..8978abd93c 100644 --- a/libraries/animation/src/AnimationHandle.cpp +++ b/libraries/animation/src/AnimationHandle.cpp @@ -176,8 +176,7 @@ void AnimationHandle::replaceMatchingPriorities(float newPriority) { for (int i = 0; i < _jointMappings.size(); i++) { int mapping = _jointMappings.at(i); if (mapping != -1) { - JointState state = _rig->getJointState(mapping); - if (_priority == state._animationPriority) { + if (_priority == _rig->getJointAnimatinoPriority(mapping)) { _rig->setJointAnimatinoPriority(mapping, newPriority); } } @@ -188,8 +187,7 @@ void AnimationHandle::restoreJoints() { for (int i = 0; i < _jointMappings.size(); i++) { int mapping = _jointMappings.at(i); if (mapping != -1) { - JointState state = _rig->getJointState(mapping); - _rig->restoreJointRotation(mapping, 1.0f, state._animationPriority); + _rig->restoreJointRotation(mapping, 1.0f, _rig->getJointAnimatinoPriority(mapping)); } } } diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index 0a889fce88..d42f65df32 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -9,6 +9,8 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +#include + #include "AnimationHandle.h" #include "Rig.h" @@ -48,9 +50,9 @@ void Rig::deleteAnimations() { } } - -float Rig::initJointStates(QVector states, glm::mat4 parentTransform) { +float Rig::initJointStates(QVector states, glm::mat4 parentTransform, int neckJointIndex) { _jointStates = states; + _neckJointIndex = neckJointIndex; initJointTransforms(parentTransform); int numStates = _jointStates.size(); @@ -66,6 +68,8 @@ float Rig::initJointStates(QVector states, glm::mat4 parentTransform _jointStates[i].slaveVisibleTransform(); } + initHeadBones(); + return radius; } @@ -106,7 +110,8 @@ JointState Rig::getJointState(int jointIndex) const { if (jointIndex == -1 || jointIndex >= _jointStates.size()) { return JointState(); } - return _jointStates[jointIndex]; + // return _jointStates[jointIndex]; + return maybeCauterizeHead(jointIndex); } bool Rig::getJointStateRotation(int index, glm::quat& rotation) const { @@ -144,6 +149,13 @@ void Rig::clearJointAnimationPriority(int index) { } } +float Rig::getJointAnimatinoPriority(int index) { + if (index != -1 && index < _jointStates.size()) { + return _jointStates[index]._animationPriority; + } + return 0.0f; +} + void Rig::setJointAnimatinoPriority(int index, float newPriority) { if (index != -1 && index < _jointStates.size()) { _jointStates[index]._animationPriority = newPriority; @@ -173,7 +185,8 @@ bool Rig::getJointPositionInWorldFrame(int jointIndex, glm::vec3& position, return false; } // position is in world-frame - position = translation + rotation * _jointStates[jointIndex].getPosition(); + // position = translation + rotation * _jointStates[jointIndex].getPosition(); + position = translation + rotation * maybeCauterizeHead(jointIndex).getPosition(); return true; } @@ -182,7 +195,7 @@ bool Rig::getJointPosition(int jointIndex, glm::vec3& position) const { return false; } // position is in model-frame - position = extractTranslation(_jointStates[jointIndex].getTransform()); + position = extractTranslation(maybeCauterizeHead(jointIndex).getTransform()); return true; } @@ -190,7 +203,7 @@ bool Rig::getJointRotationInWorldFrame(int jointIndex, glm::quat& result, const if (jointIndex == -1 || jointIndex >= _jointStates.size()) { return false; } - result = rotation * _jointStates[jointIndex].getRotation(); + result = rotation * maybeCauterizeHead(jointIndex).getRotation(); return true; } @@ -198,7 +211,7 @@ bool Rig::getJointRotation(int jointIndex, glm::quat& rotation) const { if (jointIndex == -1 || jointIndex >= _jointStates.size()) { return false; } - rotation = _jointStates[jointIndex].getRotation(); + rotation = maybeCauterizeHead(jointIndex).getRotation(); return true; } @@ -206,7 +219,7 @@ bool Rig::getJointCombinedRotation(int jointIndex, glm::quat& result, const glm: if (jointIndex == -1 || jointIndex >= _jointStates.size()) { return false; } - result = rotation * _jointStates[jointIndex].getRotation(); + result = rotation * maybeCauterizeHead(jointIndex).getRotation(); return true; } @@ -217,7 +230,7 @@ bool Rig::getVisibleJointPositionInWorldFrame(int jointIndex, glm::vec3& positio return false; } // position is in world-frame - position = translation + rotation * _jointStates[jointIndex].getVisiblePosition(); + position = translation + rotation * maybeCauterizeHead(jointIndex).getVisiblePosition(); return true; } @@ -225,7 +238,7 @@ bool Rig::getVisibleJointRotationInWorldFrame(int jointIndex, glm::quat& result, if (jointIndex == -1 || jointIndex >= _jointStates.size()) { return false; } - result = rotation * _jointStates[jointIndex].getVisibleRotation(); + result = rotation * maybeCauterizeHead(jointIndex).getVisibleRotation(); return true; } @@ -233,14 +246,14 @@ glm::mat4 Rig::getJointTransform(int jointIndex) const { if (jointIndex == -1 || jointIndex >= _jointStates.size()) { return glm::mat4(); } - return _jointStates[jointIndex].getTransform(); + return maybeCauterizeHead(jointIndex).getTransform(); } glm::mat4 Rig::getJointVisibleTransform(int jointIndex) const { if (jointIndex == -1 || jointIndex >= _jointStates.size()) { return glm::mat4(); } - return _jointStates[jointIndex].getVisibleTransform(); + return maybeCauterizeHead(jointIndex).getVisibleTransform(); } void Rig::simulateInternal(float deltaTime, glm::mat4 parentTransform) { @@ -492,7 +505,7 @@ glm::vec3 Rig::getJointDefaultTranslationInConstrainedFrame(int jointIndex) { if (jointIndex == -1 || _jointStates.isEmpty()) { return glm::vec3(); } - return _jointStates[jointIndex].getDefaultTranslationInConstrainedFrame(); + return maybeCauterizeHead(jointIndex).getDefaultTranslationInConstrainedFrame(); } glm::quat Rig::setJointRotationInConstrainedFrame(int jointIndex, glm::quat targetRotation, float priority, bool constrain) { @@ -537,5 +550,53 @@ glm::quat Rig::getJointDefaultRotationInParentFrame(int jointIndex) { if (jointIndex == -1 || _jointStates.isEmpty()) { return glm::quat(); } - return _jointStates[jointIndex].getDefaultRotationInParentFrame(); + return maybeCauterizeHead(jointIndex).getDefaultRotationInParentFrame(); +} + +void Rig::initHeadBones() { + if (_neckJointIndex == -1) { + return; + } + _headBones.clear(); + std::queue q; + q.push(_neckJointIndex); + _headBones.push_back(_neckJointIndex); + + // fbxJoints only hold links to parents not children, so we have to do a bit of extra work here. + while (q.size() > 0) { + int jointIndex = q.front(); + for (int i = 0; i < _jointStates.size(); i++) { + const FBXJoint& fbxJoint = _jointStates[i].getFBXJoint(); + if (jointIndex == fbxJoint.parentIndex) { + _headBones.push_back(i); + q.push(i); + } + } + q.pop(); + } +} + +JointState Rig::maybeCauterizeHead(int jointIndex) const { + // if (_headBones.contains(jointIndex)) { + // XXX fix this... make _headBones a hash? add a flag to JointState? + if (_neckJointIndex != -1 && + _isFirstPerson && + std::find(_headBones.begin(), _headBones.end(), jointIndex) != _headBones.end()) { + glm::vec4 trans = _jointStates[jointIndex].getTransform()[3]; + glm::vec4 zero(0, 0, 0, 0); + glm::mat4 newXform(zero, zero, zero, trans); + JointState jointStateCopy = _jointStates[jointIndex]; + jointStateCopy.setTransform(newXform); + jointStateCopy.setVisibleTransform(newXform); + return jointStateCopy; + } else { + return _jointStates[jointIndex]; + } +} + +void Rig::setFirstPerson(bool isFirstPerson) { + if (_isFirstPerson != isFirstPerson) { + _isFirstPerson = isFirstPerson; + _jointsAreDirty = true; + } } diff --git a/libraries/animation/src/Rig.h b/libraries/animation/src/Rig.h index e60116a35e..1073bd6dab 100644 --- a/libraries/animation/src/Rig.h +++ b/libraries/animation/src/Rig.h @@ -11,14 +11,18 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // /* TBD: - - What iare responsibilities of Animation/AnimationPointer/AnimationCache/AnimationDetails/AnimationObject/AnimationLoop? + - What are responsibilities of Animation/AnimationPointer/AnimationCache/AnimationDetails/AnimationObject/AnimationLoop? Is there common/copied code (e.g., ScriptableAvatar::update)? - - How do attachments interact with the physics of the attached entity? E.g., do hand joints need to reflect held object physics? - - Is there any current need (i.e., for initial campatability) to have multiple animations per role (e.g., idle) with the system choosing randomly? + - How do attachments interact with the physics of the attached entity? E.g., do hand joints need to reflect held object + physics? + - Is there any current need (i.e., for initial campatability) to have multiple animations per role (e.g., idle) with the + system choosing randomly? - Distribute some doc from here to the right files if it turns out to be correct: - - AnimationDetails is a script-useable copy of animation state, analogous to EntityItemProperties, but without anything equivalent to editEntity. - But what's the intended difference vs AnimationObjection? Maybe AnimationDetails is to Animation as AnimationObject is to AnimationPointer? + - AnimationDetails is a script-useable copy of animation state, analogous to EntityItemProperties, but without anything + equivalent to editEntity. + But what's the intended difference vs AnimationObjection? Maybe AnimationDetails is to Animation as AnimationObject + is to AnimationPointer? */ #ifndef __hifi__Rig__ @@ -51,7 +55,7 @@ public: const QList& getRunningAnimations() const { return _runningAnimations; } void deleteAnimations(); - float initJointStates(QVector states, glm::mat4 parentTransform); + float initJointStates(QVector states, glm::mat4 parentTransform, int neckJointIndex); bool jointStatesEmpty() { return _jointStates.isEmpty(); }; int getJointStateCount() const { return _jointStates.size(); } @@ -60,11 +64,12 @@ public: void reset(const QVector& fbxJoints); bool getJointStateRotation(int index, glm::quat& rotation) const; void applyJointRotationDelta(int jointIndex, const glm::quat& delta, bool constrain, float priority); - JointState getJointState(int jointIndex) const; + JointState getJointState(int jointIndex) const; // XXX bool getVisibleJointState(int index, glm::quat& rotation) const; void clearJointState(int index); void clearJointStates(); void clearJointAnimationPriority(int index); + float getJointAnimatinoPriority(int index); void setJointAnimatinoPriority(int index, float newPriority); void setJointState(int index, bool valid, const glm::quat& rotation, float priority); void restoreJointRotation(int index, float fraction, float priority); @@ -102,11 +107,23 @@ public: virtual void updateJointState(int index, glm::mat4 parentTransform) = 0; virtual void updateFaceJointState(int index, glm::mat4 parentTransform) = 0; + virtual void setFirstPerson(bool isFirstPerson); + virtual bool getIsFirstPerson() const { return _isFirstPerson; } + + bool getJointsAreDirty() { return _jointsAreDirty; } + protected: QVector _jointStates; QSet _animationHandles; QList _runningAnimations; + + JointState maybeCauterizeHead(int jointIndex) const; + void initHeadBones(); + bool _isFirstPerson = false; + std::vector _headBones; + bool _jointsAreDirty = false; + int _neckJointIndex = -1; }; #endif /* defined(__hifi__Rig__) */ diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index bd33e75207..c769f6bbe5 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -478,7 +478,7 @@ bool Model::updateGeometry() { void Model::initJointStates(QVector states) { const FBXGeometry& geometry = _geometry->getFBXGeometry(); glm::mat4 parentTransform = glm::scale(_scale) * glm::translate(_offset) * geometry.offset; - _boundingRadius = _rig->initJointStates(states, parentTransform); + _boundingRadius = _rig->initJointStates(states, parentTransform, geometry.neckJointIndex); } bool Model::findRayIntersectionAgainstSubMeshes(const glm::vec3& origin, const glm::vec3& direction, float& distance, @@ -1341,28 +1341,6 @@ void Model::simulate(float deltaTime, bool fullUpdate) { } } -void Model::updateClusterMatrices() { - const FBXGeometry& geometry = _geometry->getFBXGeometry(); - glm::mat4 modelToWorld = glm::mat4_cast(_rotation); - for (int i = 0; i < _meshStates.size(); i++) { - MeshState& state = _meshStates[i]; - const FBXMesh& mesh = geometry.meshes.at(i); - if (_showTrueJointTransforms) { - for (int j = 0; j < mesh.clusters.size(); j++) { - const FBXCluster& cluster = mesh.clusters.at(j); - state.clusterMatrices[j] = - modelToWorld * _rig->getJointTransform(cluster.jointIndex) * cluster.inverseBindMatrix; - } - } else { - for (int j = 0; j < mesh.clusters.size(); j++) { - const FBXCluster& cluster = mesh.clusters.at(j); - state.clusterMatrices[j] = - modelToWorld * _rig->getJointVisibleTransform(cluster.jointIndex) * cluster.inverseBindMatrix; - } - } - } -} - void Model::simulateInternal(float deltaTime) { // update the world space transforms for all joints diff --git a/libraries/render-utils/src/Model.h b/libraries/render-utils/src/Model.h index 30c5211990..d7178a389a 100644 --- a/libraries/render-utils/src/Model.h +++ b/libraries/render-utils/src/Model.h @@ -308,9 +308,6 @@ protected: _calculatedMeshTrianglesValid = false; } - // rebuild the clusterMatrices from the current jointStates - void updateClusterMatrices(); - // hook for derived classes to be notified when setUrl invalidates the current model. virtual void onInvalidate() {};