From 49993695a5f7dc53486b37bfc05607f2e17cded1 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Fri, 10 Jul 2015 15:20:19 -0700 Subject: [PATCH] Made geometry refresh safe --- .../src/EntityTreeRenderer.cpp | 2 +- .../src/RenderableModelEntityItem.cpp | 6 +-- libraries/render-utils/src/Model.cpp | 47 ++++++++++++++++--- libraries/render-utils/src/Model.h | 8 ++-- 4 files changed, 49 insertions(+), 14 deletions(-) diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index 11d24c6d9d..5bad452d00 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -544,7 +544,7 @@ const FBXGeometry* EntityTreeRenderer::getCollisionGeometryForEntity(EntityItemP Model* model = modelEntityItem->getModel(this); if (model) { const QSharedPointer collisionNetworkGeometry = model->getCollisionGeometry(); - if (!collisionNetworkGeometry.isNull()) { + if (!collisionNetworkGeometry || !collisionNetworkGeometry->isLoaded()) { result = &collisionNetworkGeometry->getFBXGeometry(); } } diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index 85b7bafc78..cc4c8390c9 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -397,8 +397,8 @@ bool RenderableModelEntityItem::isReadyToComputeShape() { const QSharedPointer collisionNetworkGeometry = _model->getCollisionGeometry(); const QSharedPointer renderNetworkGeometry = _model->getGeometry(); - if ((! collisionNetworkGeometry.isNull() && collisionNetworkGeometry->isLoadedWithTextures()) && - (! renderNetworkGeometry.isNull() && renderNetworkGeometry->isLoadedWithTextures())) { + if ((!collisionNetworkGeometry && collisionNetworkGeometry->isLoadedWithTextures()) && + (!renderNetworkGeometry && renderNetworkGeometry->isLoadedWithTextures())) { // we have both URLs AND both geometries AND they are both fully loaded. return true; } @@ -419,7 +419,7 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& info) { // should never fall in here when collision model not fully loaded // hence we assert collisionNetworkGeometry is not NULL - assert(!collisionNetworkGeometry.isNull()); + assert(!collisionNetworkGeometry); const FBXGeometry& collisionGeometry = collisionNetworkGeometry->getFBXGeometry(); const QSharedPointer renderNetworkGeometry = _model->getGeometry(); diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index 03140c4dfb..2820fe74a9 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -457,7 +457,8 @@ bool Model::updateGeometry() { } deleteGeometry(); _dilatedTextures.clear(); - _geometry = geometry; + setGeometry(geometry); + _meshGroupsKnown = false; _readyWhenAdded = false; // in case any of our users are using scenes invalidCalculatedMeshBoxes(); // if we have to reload, we need to assume our mesh boxes are all invalid @@ -1142,13 +1143,32 @@ void Model::setURL(const QUrl& url, const QUrl& fallback, bool retainCurrent, bo onInvalidate(); // if so instructed, keep the current geometry until the new one is loaded - _nextBaseGeometry = _nextGeometry = DependencyManager::get()->getGeometry(url, fallback, delayLoad); + _nextGeometry = DependencyManager::get()->getGeometry(url, fallback, delayLoad); _nextLODHysteresis = NetworkGeometry::NO_HYSTERESIS; if (!retainCurrent || !isActive() || (_nextGeometry && _nextGeometry->isLoaded())) { applyNextGeometry(); } } +void Model::geometryRefreshed() { + QObject* sender = QObject::sender(); + + if (sender == _geometry) { + _readyWhenAdded = false; // reset out render items. + _needsReload = true; + invalidCalculatedMeshBoxes(); + + onInvalidate(); + + // if so instructed, keep the current geometry until the new one is loaded + _nextGeometry = DependencyManager::get()->getGeometry(_url); + _nextLODHysteresis = NetworkGeometry::NO_HYSTERESIS; + applyNextGeometry(); + } else { + sender->disconnect(this, SLOT(geometryRefreshed())); + } +} + const QSharedPointer Model::getCollisionGeometry(bool delayLoad) { @@ -1156,7 +1176,11 @@ const QSharedPointer Model::getCollisionGeometry(bool delayLoad _collisionGeometry = DependencyManager::get()->getGeometry(_collisionUrl, QUrl(), delayLoad); } - return _collisionGeometry; + if (_collisionGeometry && _collisionGeometry->isLoaded()) { + return _collisionGeometry; + } + + return QSharedPointer(); } void Model::setCollisionModelURL(const QUrl& url) { @@ -1776,6 +1800,18 @@ void Model::setBlendedVertices(int blendNumber, const QWeakPointer& newGeometry) { + if (_geometry == newGeometry) { + return; + } + + if (_geometry) { + _geometry->disconnect(_geometry.data(), &Resource::onRefresh, this, &Model::geometryRefreshed); + } + _geometry = newGeometry; + QObject::connect(_geometry.data(), &Resource::onRefresh, this, &Model::geometryRefreshed); +} + void Model::applyNextGeometry() { // delete our local geometry and custom textures deleteGeometry(); @@ -1783,13 +1819,12 @@ void Model::applyNextGeometry() { _lodHysteresis = _nextLODHysteresis; // we retain a reference to the base geometry so that its reference count doesn't fall to zero - _baseGeometry = _nextBaseGeometry; - _geometry = _nextGeometry; + setGeometry(_nextGeometry); + _meshGroupsKnown = false; _readyWhenAdded = false; // in case any of our users are using scenes _needsReload = false; // we are loaded now! invalidCalculatedMeshBoxes(); - _nextBaseGeometry.reset(); _nextGeometry.reset(); } diff --git a/libraries/render-utils/src/Model.h b/libraries/render-utils/src/Model.h index a6ce566a36..60e4d1dbaa 100644 --- a/libraries/render-utils/src/Model.h +++ b/libraries/render-utils/src/Model.h @@ -245,6 +245,7 @@ public: protected: QSharedPointer _geometry; + void setGeometry(const QSharedPointer& newGeometry); glm::vec3 _scale; glm::vec3 _offset; @@ -321,6 +322,9 @@ protected: // hook for derived classes to be notified when setUrl invalidates the current model. virtual void onInvalidate() {}; +protected slots: + void geometryRefreshed(); + private: friend class AnimationHandle; @@ -330,15 +334,12 @@ private: QVector createJointStates(const FBXGeometry& geometry); void initJointTransforms(); - QSharedPointer _baseGeometry; ///< reference required to prevent collection of base - QSharedPointer _nextBaseGeometry; QSharedPointer _nextGeometry; float _lodDistance; float _lodHysteresis; float _nextLODHysteresis; QSharedPointer _collisionGeometry; - QSharedPointer _saveNonCollisionGeometry; float _pupilDilation; QVector _blendshapeCoefficients; @@ -524,7 +525,6 @@ private: QMap _renderItems; bool _readyWhenAdded = false; bool _needsReload = true; - }; Q_DECLARE_METATYPE(QPointer)