diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index ec8539954a..899514d1c1 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -118,26 +118,21 @@ void Avatar::simulate(float deltaTime) { _skeletonModel.setLODDistance(getLODDistance()); if (!_shouldRenderBillboard && inViewFrustum) { - glm::vec3 headPosition = _position; - - _skeletonModel.updateGeometry(); - if (_skeletonModel.isActive()) { - // copy joint data to skeleton - if (_hasNewJointRotations) { - for (int i = 0; i < _jointData.size(); i++) { - const JointData& data = _jointData.at(i); - _skeletonModel.setJointState(i, data.valid, data.rotation); - } - _skeletonModel.simulate(deltaTime); - _hasNewJointRotations = false; + if (_hasNewJointRotations) { + for (int i = 0; i < _jointData.size(); i++) { + const JointData& data = _jointData.at(i); + _skeletonModel.setJointState(i, data.valid, data.rotation); } - _skeletonModel.getHeadPosition(headPosition); + _skeletonModel.simulate(deltaTime); } + _skeletonModel.simulate(deltaTime, _hasNewJointRotations); + _hasNewJointRotations = false; + glm::vec3 headPosition = _position; + _skeletonModel.getHeadPosition(headPosition); Head* head = getHead(); head->setPosition(headPosition); head->setScale(_scale); - head->getFaceModel().updateGeometry(); head->simulate(deltaTime, false, _shouldRenderBillboard); } diff --git a/interface/src/avatar/FaceModel.cpp b/interface/src/avatar/FaceModel.cpp index 5d9b71f11d..2934a022af 100644 --- a/interface/src/avatar/FaceModel.cpp +++ b/interface/src/avatar/FaceModel.cpp @@ -19,9 +19,7 @@ FaceModel::FaceModel(Head* owningHead) : } void FaceModel::simulate(float deltaTime) { - if (!isActive()) { - return; - } + updateGeometry(); Avatar* owningAvatar = static_cast(_owningHead->_owningAvatar); glm::vec3 neckPosition; if (!owningAvatar->getSkeletonModel().getNeckPosition(neckPosition)) { @@ -36,12 +34,14 @@ void FaceModel::simulate(float deltaTime) { const float MODEL_SCALE = 0.0006f; setScale(glm::vec3(1.0f, 1.0f, 1.0f) * _owningHead->getScale() * MODEL_SCALE); - setOffset(-_geometry->getFBXGeometry().neckPivot); + if (isActive()) { + setOffset(-_geometry->getFBXGeometry().neckPivot); + } setPupilDilation(_owningHead->getPupilDilation()); setBlendshapeCoefficients(_owningHead->getBlendshapeCoefficients()); - Model::simulate(deltaTime); + Model::simulateInternal(deltaTime); } void FaceModel::maybeUpdateNeckRotation(const JointState& parentState, const FBXJoint& joint, JointState& state) { diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 0b220a532c..9dcfaa09ba 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -289,7 +289,6 @@ void MyAvatar::simulate(float deltaTime) { getHand()->collideAgainstOurself(); getHand()->simulate(deltaTime, true); - _skeletonModel.updateGeometry(); _skeletonModel.simulate(deltaTime); // copy out the skeleton joints from the model @@ -306,7 +305,6 @@ void MyAvatar::simulate(float deltaTime) { } head->setPosition(headPosition); head->setScale(_scale); - head->getFaceModel().updateGeometry(); head->simulate(deltaTime, true); // Zero thrust out now that we've added it to velocity in this frame diff --git a/interface/src/avatar/SkeletonModel.cpp b/interface/src/avatar/SkeletonModel.cpp index 0ce97f4ef9..69229d9e8d 100644 --- a/interface/src/avatar/SkeletonModel.cpp +++ b/interface/src/avatar/SkeletonModel.cpp @@ -18,16 +18,13 @@ SkeletonModel::SkeletonModel(Avatar* owningAvatar) : _owningAvatar(owningAvatar) { } -void SkeletonModel::simulate(float deltaTime) { - if (!isActive()) { - return; - } +void SkeletonModel::simulate(float deltaTime, bool fullUpdate) { setTranslation(_owningAvatar->getPosition()); setRotation(_owningAvatar->getOrientation() * glm::angleAxis(PI, glm::vec3(0.0f, 1.0f, 0.0f))); const float MODEL_SCALE = 0.0006f; setScale(glm::vec3(1.0f, 1.0f, 1.0f) * _owningAvatar->getScale() * MODEL_SCALE); - Model::simulate(deltaTime); + Model::simulate(deltaTime, fullUpdate); if (!(isActive() && _owningAvatar->isMyAvatar())) { return; // only simulate for own avatar diff --git a/interface/src/avatar/SkeletonModel.h b/interface/src/avatar/SkeletonModel.h index 60b12eb8f5..31867dec5c 100644 --- a/interface/src/avatar/SkeletonModel.h +++ b/interface/src/avatar/SkeletonModel.h @@ -21,7 +21,7 @@ public: SkeletonModel(Avatar* owningAvatar); - void simulate(float deltaTime); + void simulate(float deltaTime, bool fullUpdate = true); /// \param jointIndex index of hand joint /// \param shapes[out] list in which is stored pointers to hand shapes diff --git a/interface/src/renderer/Model.cpp b/interface/src/renderer/Model.cpp index 000a41b7d5..9d2a031a6e 100644 --- a/interface/src/renderer/Model.cpp +++ b/interface/src/renderer/Model.cpp @@ -190,11 +190,14 @@ void Model::reset() { } } -void Model::updateGeometry() { +bool Model::updateGeometry() { // NOTE: this is a recursive call that walks all attachments, and their attachments + bool needFullUpdate = false; for (int i = 0; i < _attachments.size(); i++) { Model* model = _attachments.at(i); - model->updateGeometry(); + if (model->updateGeometry()) { + needFullUpdate = true; + } } bool needToRebuild = false; @@ -209,7 +212,7 @@ void Model::updateGeometry() { } if (!_geometry) { // geometry is not ready - return; + return false; } QSharedPointer geometry = _geometry->getLODOrFallback(_lodDistance, _lodHysteresis); @@ -273,8 +276,9 @@ void Model::updateGeometry() { _attachments.append(model); } rebuildShapes(); + needFullUpdate = true; } - return; + return needFullUpdate; } bool Model::render(float alpha, bool forShadowMap) { @@ -682,11 +686,15 @@ void Blender::run() { Q_ARG(const QVector&, vertices), Q_ARG(const QVector&, normals)); } -void Model::simulate(float deltaTime) { - // NOTE: this is a recursive call that walks all attachments, and their attachments - if (!isActive()) { - return; +void Model::simulate(float deltaTime, bool fullUpdate) { + fullUpdate = updateGeometry() || fullUpdate; + if (isActive() && fullUpdate) { + simulateInternal(deltaTime); } +} + +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 for (int i = 0; i < _jointStates.size(); i++) { updateJointState(i); @@ -709,7 +717,9 @@ void Model::simulate(float deltaTime) { model->setRotation(jointRotation * attachment.rotation); model->setScale(_scale * attachment.scale); - model->simulate(deltaTime); + if (model->isActive()) { + model->simulateInternal(deltaTime); + } } for (int i = 0; i < _meshStates.size(); i++) { diff --git a/interface/src/renderer/Model.h b/interface/src/renderer/Model.h index 0c05b18429..11374a6369 100644 --- a/interface/src/renderer/Model.h +++ b/interface/src/renderer/Model.h @@ -56,7 +56,7 @@ public: void init(); void reset(); - virtual void simulate(float deltaTime); + virtual void simulate(float deltaTime, bool fullUpdate = true); bool render(float alpha = 1.0f, bool forShadowMap = false); /// Sets the URL of the model to render. @@ -185,8 +185,6 @@ public: /// Sets blended vertices computed in a separate thread. void setBlendedVertices(const QVector& vertices, const QVector& normals); - void updateGeometry(); - protected: QSharedPointer _geometry; @@ -219,6 +217,11 @@ protected: QVector _meshStates; + // returns 'true' if needs fullUpdate after geometry change + bool updateGeometry(); + + void simulateInternal(float deltaTime); + /// Updates the state of the joint at the specified index. virtual void updateJointState(int index);