From ff01470850a3f2b0c19d13358ce6208f4b2a4962 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Thu, 13 Feb 2014 14:25:01 -0800 Subject: [PATCH] Wait until each LOD level is actually requested before we start loading; before a level is loaded, try to use the closest already-loaded level. --- interface/src/renderer/GeometryCache.cpp | 37 ++++++++++++++++++++++-- interface/src/renderer/GeometryCache.h | 2 ++ 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/interface/src/renderer/GeometryCache.cpp b/interface/src/renderer/GeometryCache.cpp index 0688166ca3..28280395e4 100644 --- a/interface/src/renderer/GeometryCache.cpp +++ b/interface/src/renderer/GeometryCache.cpp @@ -308,13 +308,18 @@ NetworkGeometry::NetworkGeometry(const QUrl& url, const QSharedPointer NetworkGeometry::getLODOrFallback(float distance return _fallback; } QMap >::const_iterator it = _lods.upperBound(distance); - return (it == _lods.constBegin()) ? _lodParent.toStrongRef() : *(it - 1); + QSharedPointer lod = (it == _lods.constBegin()) ? _lodParent.toStrongRef() : *(it - 1); + if (lod->isLoaded()) { + return lod; + } + // if the ideal LOD isn't loaded, we need to make sure it's started to load, and possibly return the closest loaded one + if (!lod->_startedLoading) { + lod->makeRequest(); + } + float closestDistance = FLT_MAX; + if (isLoaded()) { + lod = _lodParent; + closestDistance = distance; + } + for (it = _lods.constBegin(); it != _lods.constEnd(); it++) { + float distanceToLOD = glm::abs(distance - it.key()); + if (it.value()->isLoaded() && distanceToLOD < closestDistance) { + lod = it.value(); + closestDistance = distanceToLOD; + } + } + return lod; } glm::vec4 NetworkGeometry::computeAverageColor() const { @@ -359,6 +384,7 @@ glm::vec4 NetworkGeometry::computeAverageColor() const { } void NetworkGeometry::makeRequest() { + _startedLoading = true; _reply = Application::getInstance()->getNetworkAccessManager()->get(_request); connect(_reply, SIGNAL(downloadProgress(qint64,qint64)), SLOT(handleDownloadProgress(qint64,qint64))); @@ -400,7 +426,12 @@ void NetworkGeometry::handleDownloadProgress(qint64 bytesReceived, qint64 bytesT _lods.insert(it.value().toFloat(), geometry); } _request.setUrl(url.resolved(filename)); - makeRequest(); + + // make the request immediately only if we have no LODs to switch between + _startedLoading = false; + if (_lods.isEmpty()) { + makeRequest(); + } } return; } diff --git a/interface/src/renderer/GeometryCache.h b/interface/src/renderer/GeometryCache.h index a3f9c93ca6..cd1972f413 100644 --- a/interface/src/renderer/GeometryCache.h +++ b/interface/src/renderer/GeometryCache.h @@ -66,6 +66,7 @@ public: const QVariantHash& mapping = QVariantHash(), const QUrl& textureBase = QUrl()); ~NetworkGeometry(); + /// Checks whether the geometry is fulled loaded. bool isLoaded() const { return !_geometry.joints.isEmpty(); } /// Returns a pointer to the geometry appropriate for the specified distance. @@ -94,6 +95,7 @@ private: QVariantHash _mapping; QUrl _textureBase; QSharedPointer _fallback; + bool _startedLoading; bool _failedToLoad; int _attempts;