From 7b70562a1b68ca2fb0d858dc282bdd81f6059145 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 23 Nov 2015 15:51:43 -0800 Subject: [PATCH 1/8] update RenderableModelEntityItem::_model during simulate rather than during render --- .../src/RenderableModelEntityItem.cpp | 91 ++++++++++--------- .../src/RenderableModelEntityItem.h | 1 + libraries/entities/src/EntityItem.h | 2 +- 3 files changed, 49 insertions(+), 45 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index f1be8611e1..bbc230ec1d 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -210,6 +210,53 @@ void RenderableModelEntityItem::removeFromScene(EntityItemPointer self, std::sha } } +void RenderableModelEntityItem::simulate(const quint64& now) { + EntityItem::simulate(now); + + if (_model) { + // handle animations.. + if (hasAnimation()) { + if (!jointsMapped()) { + QStringList modelJointNames = _model->getJointNames(); + mapJoints(modelJointNames); + } + + if (jointsMapped()) { + bool newFrame; + QVector frameDataRotations; + QVector frameDataTranslations; + getAnimationFrame(newFrame, frameDataRotations, frameDataTranslations); + assert(frameDataRotations.size() == frameDataTranslations.size()); + if (newFrame) { + for (int i = 0; i < frameDataRotations.size(); i++) { + _model->setJointState(i, true, frameDataRotations[i], frameDataTranslations[i], 1.0f); + } + } + } + } + + bool movingOrAnimating = isMoving() || isAnimatingSomething(); + if ((movingOrAnimating || + _needsInitialSimulation || + _model->getTranslation() != getPosition() || + _model->getRotation() != getRotation() || + _model->getRegistrationPoint() != getRegistrationPoint()) + && _model->isActive() && _dimensionsInitialized) { + _model->setScaleToFit(true, getDimensions()); + _model->setSnapModelToRegistrationPoint(true, getRegistrationPoint()); + _model->setRotation(getRotation()); + _model->setTranslation(getPosition()); + + // make sure to simulate so everything gets set up correctly for rendering + { + PerformanceTimer perfTimer("_model->simulate"); + _model->simulate(0.0f); + } + + _needsInitialSimulation = false; + } + } +} // NOTE: this only renders the "meta" portion of the Model, namely it renders debugging items, and it handles // the per frame simulation/update that might be required if the models properties changed. @@ -259,50 +306,6 @@ void RenderableModelEntityItem::render(RenderArgs* args) { EntityTreeRenderer* renderer = static_cast(args->_renderer); getModel(renderer); } - - if (_model) { - // handle animations.. - if (hasAnimation()) { - if (!jointsMapped()) { - QStringList modelJointNames = _model->getJointNames(); - mapJoints(modelJointNames); - } - - if (jointsMapped()) { - bool newFrame; - QVector frameDataRotations; - QVector frameDataTranslations; - getAnimationFrame(newFrame, frameDataRotations, frameDataTranslations); - assert(frameDataRotations.size() == frameDataTranslations.size()); - if (newFrame) { - for (int i = 0; i < frameDataRotations.size(); i++) { - _model->setJointState(i, true, frameDataRotations[i], frameDataTranslations[i], 1.0f); - } - } - } - } - - bool movingOrAnimating = isMoving() || isAnimatingSomething(); - if ((movingOrAnimating || - _needsInitialSimulation || - _model->getTranslation() != getPosition() || - _model->getRotation() != getRotation() || - _model->getRegistrationPoint() != getRegistrationPoint()) - && _model->isActive() && _dimensionsInitialized) { - _model->setScaleToFit(true, getDimensions()); - _model->setSnapModelToRegistrationPoint(true, getRegistrationPoint()); - _model->setRotation(getRotation()); - _model->setTranslation(getPosition()); - - // make sure to simulate so everything gets set up correctly for rendering - { - PerformanceTimer perfTimer("_model->simulate"); - _model->simulate(0.0f); - } - - _needsInitialSimulation = false; - } - } } } else { static glm::vec4 greenColor(0.0f, 1.0f, 0.0f, 1.0f); diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.h b/libraries/entities-renderer/src/RenderableModelEntityItem.h index c4e36c240a..3d7ca73624 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.h +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.h @@ -47,6 +47,7 @@ public: virtual bool addToScene(EntityItemPointer self, std::shared_ptr scene, render::PendingChanges& pendingChanges); virtual void removeFromScene(EntityItemPointer self, std::shared_ptr scene, render::PendingChanges& pendingChanges); + virtual void simulate(const quint64& now); virtual void render(RenderArgs* args); virtual bool supportsDetailedRayIntersection() const { return true; } diff --git a/libraries/entities/src/EntityItem.h b/libraries/entities/src/EntityItem.h index 5ceccef4b1..6514c955e8 100644 --- a/libraries/entities/src/EntityItem.h +++ b/libraries/entities/src/EntityItem.h @@ -183,7 +183,7 @@ public: quint64 getLastUpdated() const { return _lastUpdated; } // perform linear extrapolation for SimpleEntitySimulation - void simulate(const quint64& now); + virtual void simulate(const quint64& now); void simulateKinematicMotion(float timeElapsed, bool setFlags=true); virtual bool needsToCallUpdate() const { return false; } From 89e5b11f9eea009336b5795d9978a61ec5b7b3bc Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 23 Nov 2015 16:17:22 -0800 Subject: [PATCH 2/8] do this from update rather than simulate --- .../src/RenderableModelEntityItem.cpp | 96 +++++++++---------- .../src/RenderableModelEntityItem.h | 2 - libraries/entities/src/EntityItem.h | 2 +- 3 files changed, 47 insertions(+), 53 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index bbc230ec1d..6985d1a617 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -210,54 +210,6 @@ void RenderableModelEntityItem::removeFromScene(EntityItemPointer self, std::sha } } -void RenderableModelEntityItem::simulate(const quint64& now) { - EntityItem::simulate(now); - - if (_model) { - // handle animations.. - if (hasAnimation()) { - if (!jointsMapped()) { - QStringList modelJointNames = _model->getJointNames(); - mapJoints(modelJointNames); - } - - if (jointsMapped()) { - bool newFrame; - QVector frameDataRotations; - QVector frameDataTranslations; - getAnimationFrame(newFrame, frameDataRotations, frameDataTranslations); - assert(frameDataRotations.size() == frameDataTranslations.size()); - if (newFrame) { - for (int i = 0; i < frameDataRotations.size(); i++) { - _model->setJointState(i, true, frameDataRotations[i], frameDataTranslations[i], 1.0f); - } - } - } - } - - bool movingOrAnimating = isMoving() || isAnimatingSomething(); - if ((movingOrAnimating || - _needsInitialSimulation || - _model->getTranslation() != getPosition() || - _model->getRotation() != getRotation() || - _model->getRegistrationPoint() != getRegistrationPoint()) - && _model->isActive() && _dimensionsInitialized) { - _model->setScaleToFit(true, getDimensions()); - _model->setSnapModelToRegistrationPoint(true, getRegistrationPoint()); - _model->setRotation(getRotation()); - _model->setTranslation(getPosition()); - - // make sure to simulate so everything gets set up correctly for rendering - { - PerformanceTimer perfTimer("_model->simulate"); - _model->simulate(0.0f); - } - - _needsInitialSimulation = false; - } - } -} - // NOTE: this only renders the "meta" portion of the Model, namely it renders debugging items, and it handles // the per frame simulation/update that might be required if the models properties changed. void RenderableModelEntityItem::render(RenderArgs* args) { @@ -369,14 +321,58 @@ void RenderableModelEntityItem::update(const quint64& now) { EntityItemProperties properties; auto extents = _model->getMeshExtents(); properties.setDimensions(extents.maximum - extents.minimum); - + qCDebug(entitiesrenderer) << "Autoresizing:" << (!getName().isEmpty() ? getName() : getModelURL()); QMetaObject::invokeMethod(DependencyManager::get().data(), "editEntity", Qt::QueuedConnection, Q_ARG(QUuid, getEntityItemID()), Q_ARG(EntityItemProperties, properties)); } - + + if (_model) { + // handle animations.. + if (hasAnimation()) { + if (!jointsMapped()) { + QStringList modelJointNames = _model->getJointNames(); + mapJoints(modelJointNames); + } + + if (jointsMapped()) { + bool newFrame; + QVector frameDataRotations; + QVector frameDataTranslations; + getAnimationFrame(newFrame, frameDataRotations, frameDataTranslations); + assert(frameDataRotations.size() == frameDataTranslations.size()); + if (newFrame) { + for (int i = 0; i < frameDataRotations.size(); i++) { + _model->setJointState(i, true, frameDataRotations[i], frameDataTranslations[i], 1.0f); + } + } + } + } + + bool movingOrAnimating = isMoving() || isAnimatingSomething(); + if ((movingOrAnimating || + _needsInitialSimulation || + _model->getTranslation() != getPosition() || + _model->getRotation() != getRotation() || + _model->getRegistrationPoint() != getRegistrationPoint()) + && _model->isActive() && _dimensionsInitialized) { + _model->setScaleToFit(true, getDimensions()); + _model->setSnapModelToRegistrationPoint(true, getRegistrationPoint()); + _model->setRotation(getRotation()); + _model->setTranslation(getPosition()); + + // make sure to simulate so everything gets set up correctly for rendering + { + PerformanceTimer perfTimer("_model->simulate"); + _model->simulate(0.0f); + } + + _needsInitialSimulation = false; + } + } + ModelEntityItem::update(now); } diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.h b/libraries/entities-renderer/src/RenderableModelEntityItem.h index 3d7ca73624..6c5bfc4423 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.h +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.h @@ -47,8 +47,6 @@ public: virtual bool addToScene(EntityItemPointer self, std::shared_ptr scene, render::PendingChanges& pendingChanges); virtual void removeFromScene(EntityItemPointer self, std::shared_ptr scene, render::PendingChanges& pendingChanges); - virtual void simulate(const quint64& now); - virtual void render(RenderArgs* args); virtual bool supportsDetailedRayIntersection() const { return true; } virtual bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction, diff --git a/libraries/entities/src/EntityItem.h b/libraries/entities/src/EntityItem.h index 6514c955e8..5ceccef4b1 100644 --- a/libraries/entities/src/EntityItem.h +++ b/libraries/entities/src/EntityItem.h @@ -183,7 +183,7 @@ public: quint64 getLastUpdated() const { return _lastUpdated; } // perform linear extrapolation for SimpleEntitySimulation - virtual void simulate(const quint64& now); + void simulate(const quint64& now); void simulateKinematicMotion(float timeElapsed, bool setFlags=true); virtual bool needsToCallUpdate() const { return false; } From 283ad7ffd938a858510f815bb4442e13e89ef0ff Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 23 Nov 2015 16:39:19 -0800 Subject: [PATCH 3/8] try, try again --- .../src/RenderableModelEntityItem.cpp | 22 ++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index 6985d1a617..3d9a336e83 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -313,7 +313,27 @@ Model* RenderableModelEntityItem::getModel(EntityTreeRenderer* renderer) { } bool RenderableModelEntityItem::needsToCallUpdate() const { - return !_dimensionsInitialized || _needsInitialSimulation || ModelEntityItem::needsToCallUpdate(); + if (EntityItem::needsToCallUpdate()) { + return true; + } + // these if statements match the structure of those in RenderableModelEntityItem::update + if (!_dimensionsInitialized && _model && _model->isActive()) { + return true; + } + if (_model) { + if (hasAnimation()) { + return true; + } + bool movingOrAnimating = isMoving() || isAnimatingSomething(); + if ((movingOrAnimating || + _needsInitialSimulation || + _model->getTranslation() != getPosition() || + _model->getRotation() != getRotation() || + _model->getRegistrationPoint() != getRegistrationPoint()) + && _model->isActive() && _dimensionsInitialized) { + return true; + } + } } void RenderableModelEntityItem::update(const quint64& now) { From cfcff42004cd134224bbd46ff49dcf35c07a7b63 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 23 Nov 2015 16:41:16 -0800 Subject: [PATCH 4/8] missed a line --- libraries/entities-renderer/src/RenderableModelEntityItem.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index 3d9a336e83..31d3e3ca78 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -334,6 +334,8 @@ bool RenderableModelEntityItem::needsToCallUpdate() const { return true; } } + + return false; } void RenderableModelEntityItem::update(const quint64& now) { From 5cd047da15cfdc65d4e2a23700a0f3ed99ebd5b0 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 23 Nov 2015 16:49:36 -0800 Subject: [PATCH 5/8] move some more code over --- .../src/RenderableModelEntityItem.cpp | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index 31d3e3ca78..2fedc02a2f 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -247,18 +247,7 @@ void RenderableModelEntityItem::render(RenderArgs* args) { _model->setVisibleInScene(getVisible(), scene); } - remapTextures(); - { - // float alpha = getLocalRenderAlpha(); - - if (!_model || _needsModelReload) { - // TODO: this getModel() appears to be about 3% of model render time. We should optimize - PerformanceTimer perfTimer("getModel"); - EntityTreeRenderer* renderer = static_cast(args->_renderer); - getModel(renderer); - } - } } else { static glm::vec4 greenColor(0.0f, 1.0f, 0.0f, 1.0f); gpu::Batch& batch = *args->_batch; @@ -317,6 +306,11 @@ bool RenderableModelEntityItem::needsToCallUpdate() const { return true; } // these if statements match the structure of those in RenderableModelEntityItem::update + if (hasModel() && _myRenderer) { + if (!_model || _needsModelReload) { + return true; + } + } if (!_dimensionsInitialized && _model && _model->isActive()) { return true; } @@ -351,6 +345,12 @@ void RenderableModelEntityItem::update(const quint64& now) { Q_ARG(EntityItemProperties, properties)); } + if (!_model || _needsModelReload) { + // TODO: this getModel() appears to be about 3% of model render time. We should optimize + PerformanceTimer perfTimer("getModel"); + getModel(_myRenderer); + } + if (_model) { // handle animations.. if (hasAnimation()) { From 09f14bc9a56bc7bb54c2c24a773058b9beed7ab0 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 23 Nov 2015 16:51:17 -0800 Subject: [PATCH 6/8] guard against nullptr deferenece --- libraries/entities-renderer/src/RenderableModelEntityItem.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index 2fedc02a2f..ade96901dc 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -345,7 +345,7 @@ void RenderableModelEntityItem::update(const quint64& now) { Q_ARG(EntityItemProperties, properties)); } - if (!_model || _needsModelReload) { + if (_myRenderer && (!_model || _needsModelReload)) { // TODO: this getModel() appears to be about 3% of model render time. We should optimize PerformanceTimer perfTimer("getModel"); getModel(_myRenderer); From 4ab2bfa85461d7e1fd7b298dfb08b8b10c1cbd2e Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Thu, 26 Nov 2015 08:35:28 -0800 Subject: [PATCH 7/8] clean up, minimize diff --- .../src/RenderableModelEntityItem.cpp | 23 +++++++++++-------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index e0923313c7..1221c53f24 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -210,6 +210,7 @@ void RenderableModelEntityItem::removeFromScene(EntityItemPointer self, std::sha } } + // NOTE: this only renders the "meta" portion of the Model, namely it renders debugging items, and it handles // the per frame simulation/update that might be required if the models properties changed. void RenderableModelEntityItem::render(RenderArgs* args) { @@ -249,6 +250,7 @@ void RenderableModelEntityItem::render(RenderArgs* args) { _model->setVisibleInScene(getVisible(), scene); } + remapTextures(); } else { static glm::vec4 greenColor(0.0f, 1.0f, 0.0f, 1.0f); @@ -304,22 +306,23 @@ Model* RenderableModelEntityItem::getModel(EntityTreeRenderer* renderer) { } bool RenderableModelEntityItem::needsToCallUpdate() const { - if (EntityItem::needsToCallUpdate()) { + if (!_dimensionsInitialized || _needsInitialSimulation || ModelEntityItem::needsToCallUpdate()) { return true; } - // these if statements match the structure of those in RenderableModelEntityItem::update - if (hasModel() && _myRenderer) { - if (!_model || _needsModelReload) { - return true; - } - } + if (!_dimensionsInitialized && _model && _model->isActive()) { return true; } + + if (_myRenderer && (!_model || _needsModelReload)) { + return true; + } + if (_model) { - if (hasAnimation()) { + if (hasAnimation() || jointsMapped()) { return true; } + bool movingOrAnimating = isMoving() || isAnimatingSomething(); if ((movingOrAnimating || _needsInitialSimulation || @@ -339,14 +342,14 @@ void RenderableModelEntityItem::update(const quint64& now) { EntityItemProperties properties; auto extents = _model->getMeshExtents(); properties.setDimensions(extents.maximum - extents.minimum); - + qCDebug(entitiesrenderer) << "Autoresizing:" << (!getName().isEmpty() ? getName() : getModelURL()); QMetaObject::invokeMethod(DependencyManager::get().data(), "editEntity", Qt::QueuedConnection, Q_ARG(QUuid, getEntityItemID()), Q_ARG(EntityItemProperties, properties)); } - + if (_myRenderer && (!_model || _needsModelReload)) { // TODO: this getModel() appears to be about 3% of model render time. We should optimize PerformanceTimer perfTimer("getModel"); From 4b5fec4b008731a905e87ee669d0827a2af4d5f2 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Thu, 26 Nov 2015 08:36:41 -0800 Subject: [PATCH 8/8] clean up, minimize diff --- libraries/entities-renderer/src/RenderableModelEntityItem.h | 1 + 1 file changed, 1 insertion(+) diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.h b/libraries/entities-renderer/src/RenderableModelEntityItem.h index 6c5bfc4423..c4e36c240a 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.h +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.h @@ -47,6 +47,7 @@ public: virtual bool addToScene(EntityItemPointer self, std::shared_ptr scene, render::PendingChanges& pendingChanges); virtual void removeFromScene(EntityItemPointer self, std::shared_ptr scene, render::PendingChanges& pendingChanges); + virtual void render(RenderArgs* args); virtual bool supportsDetailedRayIntersection() const { return true; } virtual bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,