From 9d831a2ab50b8febee6bb8c785152ba09cbaa032 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Mon, 13 Jan 2014 14:43:59 -0800 Subject: [PATCH 1/3] Orbit around voxel center, limit hover distance. --- interface/src/Application.cpp | 13 +++++++------ interface/src/Application.h | 2 +- libraries/voxels/src/VoxelTreeElement.h | 2 +- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 6e888d7918..8d758974dd 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1121,7 +1121,7 @@ void Application::mouseMoveEvent(QMouseEvent* event) { return; } if (_isHoverVoxel) { - _myAvatar.orbit(glm::vec3(_hoverVoxel.x, _hoverVoxel.y, _hoverVoxel.z) * (float)TREE_SCALE, deltaX, deltaY); + _myAvatar.orbit(getMouseVoxelWorldCoordinates(_hoverVoxel), deltaX, deltaY); return; } } @@ -1618,10 +1618,9 @@ void Application::makeVoxel(glm::vec3 position, isDestructive); } -const glm::vec3 Application::getMouseVoxelWorldCoordinates(const VoxelDetail _mouseVoxel) { - return glm::vec3((_mouseVoxel.x + _mouseVoxel.s / 2.f) * TREE_SCALE, - (_mouseVoxel.y + _mouseVoxel.s / 2.f) * TREE_SCALE, - (_mouseVoxel.z + _mouseVoxel.s / 2.f) * TREE_SCALE); +glm::vec3 Application::getMouseVoxelWorldCoordinates(const VoxelDetail& mouseVoxel) { + return glm::vec3((mouseVoxel.x + mouseVoxel.s / 2.f) * TREE_SCALE, (mouseVoxel.y + mouseVoxel.s / 2.f) * TREE_SCALE, + (mouseVoxel.z + mouseVoxel.s / 2.f) * TREE_SCALE); } const float NUDGE_PRECISION_MIN = 1 / pow(2.0, 12.0); @@ -2245,7 +2244,9 @@ void Application::updateHoverVoxels(float deltaTime, glm::vec3& mouseRayOrigin, if (!(_voxels.treeIsBusy() || _mousePressed)) { { PerformanceWarning warn(showWarnings, "Application::updateHoverVoxels() _voxels.findRayIntersection()"); - _isHoverVoxel = _voxels.findRayIntersection(mouseRayOrigin, mouseRayDirection, _hoverVoxel, distance, face); + const float MAX_HOVER_DISTANCE = 100.0f; + _isHoverVoxel = _voxels.findRayIntersection(mouseRayOrigin, mouseRayDirection, _hoverVoxel, distance, face) && + glm::distance(getMouseVoxelWorldCoordinates(_hoverVoxel), mouseRayOrigin) < MAX_HOVER_DISTANCE; } if (MAKE_SOUND_ON_VOXEL_HOVER && _isHoverVoxel && glm::vec4(_hoverVoxel.x, _hoverVoxel.y, _hoverVoxel.z, _hoverVoxel.s) != oldVoxel) { diff --git a/interface/src/Application.h b/interface/src/Application.h index 92831ff9ce..1da7de0224 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -142,7 +142,7 @@ public: void removeVoxel(glm::vec3 position, float scale); - const glm::vec3 getMouseVoxelWorldCoordinates(const VoxelDetail _mouseVoxel); + glm::vec3 getMouseVoxelWorldCoordinates(const VoxelDetail& mouseVoxel); QGLWidget* getGLWidget() { return _glWidget; } MyAvatar* getAvatar() { return &_myAvatar; } diff --git a/libraries/voxels/src/VoxelTreeElement.h b/libraries/voxels/src/VoxelTreeElement.h index 1eee7e4a5b..d30007aca1 100644 --- a/libraries/voxels/src/VoxelTreeElement.h +++ b/libraries/voxels/src/VoxelTreeElement.h @@ -92,4 +92,4 @@ protected: }; -#endif /* defined(__hifi__VoxelTreeElement__) */ \ No newline at end of file +#endif /* defined(__hifi__VoxelTreeElement__) */ From f21436a29e7298468408656ee39b2e4a6d933d07 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Mon, 13 Jan 2014 15:02:46 -0800 Subject: [PATCH 2/3] Fix (hopefully) for warning on Windows build. --- interface/src/Application.cpp | 4 +--- libraries/metavoxels/src/MetavoxelData.cpp | 4 ++-- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 8d758974dd..5a6aec5fe8 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2244,9 +2244,7 @@ void Application::updateHoverVoxels(float deltaTime, glm::vec3& mouseRayOrigin, if (!(_voxels.treeIsBusy() || _mousePressed)) { { PerformanceWarning warn(showWarnings, "Application::updateHoverVoxels() _voxels.findRayIntersection()"); - const float MAX_HOVER_DISTANCE = 100.0f; - _isHoverVoxel = _voxels.findRayIntersection(mouseRayOrigin, mouseRayDirection, _hoverVoxel, distance, face) && - glm::distance(getMouseVoxelWorldCoordinates(_hoverVoxel), mouseRayOrigin) < MAX_HOVER_DISTANCE; + _isHoverVoxel = _voxels.findRayIntersection(mouseRayOrigin, mouseRayDirection, _hoverVoxel, distance, face); } if (MAKE_SOUND_ON_VOXEL_HOVER && _isHoverVoxel && glm::vec4(_hoverVoxel.x, _hoverVoxel.y, _hoverVoxel.z, _hoverVoxel.s) != oldVoxel) { diff --git a/libraries/metavoxels/src/MetavoxelData.cpp b/libraries/metavoxels/src/MetavoxelData.cpp index 849d85960e..c04ee9f297 100644 --- a/libraries/metavoxels/src/MetavoxelData.cpp +++ b/libraries/metavoxels/src/MetavoxelData.cpp @@ -301,8 +301,8 @@ void MetavoxelNode::clearChildren(const AttributePointer& attribute) { } int MetavoxelPath::operator[](int index) const { - return _array.at(index * BITS_PER_ELEMENT) | (_array.at(index * BITS_PER_ELEMENT + 1) << 1) | - (_array.at(index * BITS_PER_ELEMENT + 2) << 2); + return (int)_array.at(index * BITS_PER_ELEMENT) | ((int)_array.at(index * BITS_PER_ELEMENT + 1) << 1) | + ((int)_array.at(index * BITS_PER_ELEMENT + 2) << 2); } MetavoxelPath& MetavoxelPath::operator+=(int element) { From 0694a7d4a5ebcde09793ec4be013361ebf788bfd Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Mon, 13 Jan 2014 16:09:36 -0800 Subject: [PATCH 3/3] When we fail to download textures or geometry, retry after steadily increasing delays. Closes #1471. --- interface/src/renderer/GeometryCache.cpp | 32 ++++++++++++++++------ interface/src/renderer/GeometryCache.h | 4 +++ interface/src/renderer/TextureCache.cpp | 35 ++++++++++++++++++------ interface/src/renderer/TextureCache.h | 8 ++++-- 4 files changed, 61 insertions(+), 18 deletions(-) diff --git a/interface/src/renderer/GeometryCache.cpp b/interface/src/renderer/GeometryCache.cpp index 1a32a70c71..7ec61a8942 100644 --- a/interface/src/renderer/GeometryCache.cpp +++ b/interface/src/renderer/GeometryCache.cpp @@ -251,18 +251,16 @@ QSharedPointer GeometryCache::getGeometry(const QUrl& url) { } NetworkGeometry::NetworkGeometry(const QUrl& url) : + _modelRequest(url), _modelReply(NULL), - _mappingReply(NULL) + _mappingReply(NULL), + _attempts(0) { if (!url.isValid()) { return; } - QNetworkRequest modelRequest(url); - modelRequest.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferCache); - _modelReply = Application::getInstance()->getNetworkAccessManager()->get(modelRequest); - - connect(_modelReply, SIGNAL(downloadProgress(qint64,qint64)), SLOT(maybeReadModelWithMapping())); - connect(_modelReply, SIGNAL(error(QNetworkReply::NetworkError)), SLOT(handleModelReplyError())); + _modelRequest.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferCache); + makeModelRequest(); QUrl mappingURL = url; QString path = url.path(); @@ -312,12 +310,30 @@ glm::vec4 NetworkGeometry::computeAverageColor() const { return (totalTriangles == 0) ? glm::vec4(1.0f, 1.0f, 1.0f, 1.0f) : totalColor / totalTriangles; } +void NetworkGeometry::makeModelRequest() { + _modelReply = Application::getInstance()->getNetworkAccessManager()->get(_modelRequest); + + connect(_modelReply, SIGNAL(downloadProgress(qint64,qint64)), SLOT(maybeReadModelWithMapping())); + connect(_modelReply, SIGNAL(error(QNetworkReply::NetworkError)), SLOT(handleModelReplyError())); +} + void NetworkGeometry::handleModelReplyError() { - qDebug() << _modelReply->errorString() << "\n"; + QDebug debug = qDebug() << _modelReply->errorString(); _modelReply->disconnect(this); _modelReply->deleteLater(); _modelReply = NULL; + + // retry with increasing delays + const int MAX_ATTEMPTS = 8; + const int BASE_DELAY_MS = 1000; + if (++_attempts < MAX_ATTEMPTS) { + QTimer::singleShot(BASE_DELAY_MS * (int)pow(2.0, _attempts), this, SLOT(makeModelRequest())); + debug << " -- retrying...\n"; + + } else { + debug << "\n"; + } } void NetworkGeometry::handleMappingReplyError() { diff --git a/interface/src/renderer/GeometryCache.h b/interface/src/renderer/GeometryCache.h index d880d25855..8a68917ba5 100644 --- a/interface/src/renderer/GeometryCache.h +++ b/interface/src/renderer/GeometryCache.h @@ -10,6 +10,7 @@ #define __interface__GeometryCache__ #include +#include #include #include #include @@ -67,15 +68,18 @@ public: private slots: + void makeModelRequest(); void handleModelReplyError(); void handleMappingReplyError(); void maybeReadModelWithMapping(); private: + QNetworkRequest _modelRequest; QNetworkReply* _modelReply; QNetworkReply* _mappingReply; + int _attempts; FBXGeometry _geometry; QVector _meshes; }; diff --git a/interface/src/renderer/TextureCache.cpp b/interface/src/renderer/TextureCache.cpp index 778fb8fb12..6a7d64da5f 100644 --- a/interface/src/renderer/TextureCache.cpp +++ b/interface/src/renderer/TextureCache.cpp @@ -252,16 +252,17 @@ Texture::~Texture() { glDeleteTextures(1, &_id); } -NetworkTexture::NetworkTexture(const QUrl& url, bool normalMap) : _reply(NULL), _averageColor(1.0f, 1.0f, 1.0f, 1.0f) { +NetworkTexture::NetworkTexture(const QUrl& url, bool normalMap) : + _request(url), + _reply(NULL), + _attempts(0), + _averageColor(1.0f, 1.0f, 1.0f, 1.0f) { + if (!url.isValid()) { return; } - QNetworkRequest request(url); - request.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferCache); - _reply = Application::getInstance()->getNetworkAccessManager()->get(request); - - connect(_reply, SIGNAL(downloadProgress(qint64,qint64)), SLOT(handleDownloadProgress(qint64,qint64))); - connect(_reply, SIGNAL(error(QNetworkReply::NetworkError)), SLOT(handleReplyError())); + _request.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferCache); + makeRequest(); // default to white/blue glBindTexture(GL_TEXTURE_2D, getID()); @@ -279,6 +280,13 @@ void NetworkTexture::imageLoaded(const QImage& image) { // nothing by default } +void NetworkTexture::makeRequest() { + _reply = Application::getInstance()->getNetworkAccessManager()->get(_request); + + connect(_reply, SIGNAL(downloadProgress(qint64,qint64)), SLOT(handleDownloadProgress(qint64,qint64))); + connect(_reply, SIGNAL(error(QNetworkReply::NetworkError)), SLOT(handleReplyError())); +} + void NetworkTexture::handleDownloadProgress(qint64 bytesReceived, qint64 bytesTotal) { if (bytesReceived < bytesTotal && !_reply->isFinished()) { return; @@ -314,11 +322,22 @@ void NetworkTexture::handleDownloadProgress(qint64 bytesReceived, qint64 bytesTo } void NetworkTexture::handleReplyError() { - qDebug() << _reply->errorString() << "\n"; + QDebug debug = qDebug() << _reply->errorString(); _reply->disconnect(this); _reply->deleteLater(); _reply = NULL; + + // retry with increasing delays + const int MAX_ATTEMPTS = 8; + const int BASE_DELAY_MS = 1000; + if (++_attempts < MAX_ATTEMPTS) { + QTimer::singleShot(BASE_DELAY_MS * (int)pow(2.0, _attempts), this, SLOT(makeRequest())); + debug << " -- retrying...\n"; + + } else { + debug << "\n"; + } } DilatableNetworkTexture::DilatableNetworkTexture(const QUrl& url, bool normalMap) : diff --git a/interface/src/renderer/TextureCache.h b/interface/src/renderer/TextureCache.h index 40f2bc5ac3..d3f138254f 100644 --- a/interface/src/renderer/TextureCache.h +++ b/interface/src/renderer/TextureCache.h @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -126,12 +127,15 @@ protected: private slots: + void makeRequest(); void handleDownloadProgress(qint64 bytesReceived, qint64 bytesTotal); void handleReplyError(); - + private: - + + QNetworkRequest _request; QNetworkReply* _reply; + int _attempts; glm::vec4 _averageColor; };