From f229e24e60aab1536a03c0f52d546d090567518b Mon Sep 17 00:00:00 2001 From: howard-stearns Date: Tue, 3 Apr 2018 13:22:47 -0700 Subject: [PATCH 01/16] fix help.js noisy log reference to undefined string#startsWith --- scripts/system/help.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/system/help.js b/scripts/system/help.js index e29fc59e59..aaeb82721c 100644 --- a/scripts/system/help.js +++ b/scripts/system/help.js @@ -40,7 +40,7 @@ } function onScreenChanged(type, url) { - onHelpScreen = type === "Web" && url.startsWith(HELP_URL); + onHelpScreen = type === "Web" && (url.indexOf(HELP_URL) === 0); button.editProperties({ isActive: onHelpScreen }); } From 01d90ea1a5c50a266d6c003343d5895e33805ff3 Mon Sep 17 00:00:00 2001 From: howard-stearns Date: Tue, 3 Apr 2018 13:34:05 -0700 Subject: [PATCH 02/16] Introduce safeLoading. --- .../qml/controls/FlickableWebViewCore.qml | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/interface/resources/qml/controls/FlickableWebViewCore.qml b/interface/resources/qml/controls/FlickableWebViewCore.qml index efc8519c1e..8e7db44b7d 100644 --- a/interface/resources/qml/controls/FlickableWebViewCore.qml +++ b/interface/resources/qml/controls/FlickableWebViewCore.qml @@ -122,9 +122,21 @@ Item { newViewRequestedCallback(request) } + // Prior to 5.10, the WebEngineView loading property is true during initial page loading and then stays false + // as in-page javascript adds more html content. However, in 5.10 there is a bug such that adding html turns + // loading true, and never turns it false again. safeLoading provides a workaround, but it should be removed + // when QT fixes this. + property bool safeLoading: false + property bool loadingLatched: false + property var loadingRequest: null onLoadingChanged: { - flick.onLoadingChanged(loadRequest) - loadingChangedCallback(loadRequest) + webViewCore.loadingRequest = loadRequest; + webViewCore.safeLoading = webViewCore.loading && !loadingLatched; + webViewCore.loadingLatched |= webViewCore.loading; + } + onSafeLoadingChanged: { + flick.onLoadingChanged(webViewCore.loadingRequest) + loadingChangedCallback(webViewCore.loadingRequest) } } @@ -133,7 +145,7 @@ Item { x: flick.width/2 - width/2 y: flick.height/2 - height/2 source: "../../icons/loader-snake-64-w.gif" - visible: webViewCore.loading && /^(http.*|)$/i.test(webViewCore.url.toString()) + visible: webViewCore.safeLoading && /^(http.*|)$/i.test(webViewCore.url.toString()) playing: visible z: 10000 } From 4b0d338e5751ef43d85184c3e1dc5cb88f82c008 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Wed, 4 Apr 2018 18:00:11 -0700 Subject: [PATCH 03/16] on first run, send user to serverless tutorial rather than checking for a local sandbox --- interface/src/Application.cpp | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 2bfd48ec2c..18ba881573 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3042,7 +3042,6 @@ void Application::handleSandboxStatus(QNetworkReply* reply) { static const QString SENT_TO_PREVIOUS_LOCATION = "previous_location"; static const QString SENT_TO_ENTRY = "entry"; - static const QString SENT_TO_SANDBOX = "sandbox"; QString sentTo; @@ -3051,15 +3050,8 @@ void Application::handleSandboxStatus(QNetworkReply* reply) { #if !defined(Q_OS_ANDROID) showHelp(); #endif - if (sandboxIsRunning) { - qCDebug(interfaceapp) << "Home sandbox appears to be running, going to Home."; - DependencyManager::get()->goToLocalSandbox(); - sentTo = SENT_TO_SANDBOX; - } else { - qCDebug(interfaceapp) << "Home sandbox does not appear to be running, going to Entry."; - DependencyManager::get()->goToEntry(); - sentTo = SENT_TO_ENTRY; - } + DependencyManager::get()->goToEntry(); + sentTo = SENT_TO_ENTRY; firstRun.set(false); } else { From 78053b8b48232548ddf82ae4d616776e8a32492d Mon Sep 17 00:00:00 2001 From: samcake Date: Wed, 4 Apr 2018 18:33:27 -0700 Subject: [PATCH 04/16] Refix the normal map case foro translucents --- libraries/render-utils/src/RenderPipelines.cpp | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/libraries/render-utils/src/RenderPipelines.cpp b/libraries/render-utils/src/RenderPipelines.cpp index aca8439547..cc27599a58 100644 --- a/libraries/render-utils/src/RenderPipelines.cpp +++ b/libraries/render-utils/src/RenderPipelines.cpp @@ -32,6 +32,7 @@ #include "model_lightmap_fade_vert.h" #include "model_lightmap_normal_map_fade_vert.h" #include "model_translucent_vert.h" +#include "model_translucent_normal_map_vert.h" #include "skin_model_fade_vert.h" #include "skin_model_normal_map_fade_vert.h" #include "skin_model_fade_dq_vert.h" @@ -68,11 +69,13 @@ #include "model_lightmap_normal_map_frag.h" #include "model_translucent_frag.h" #include "model_translucent_unlit_frag.h" +#include "model_translucent_normal_map_frag.h" #include "model_lightmap_fade_frag.h" #include "model_lightmap_normal_map_fade_frag.h" #include "model_translucent_fade_frag.h" #include "model_translucent_unlit_fade_frag.h" +#include "model_translucent_normal_map_fade_frag.h" #include "overlay3D_vert.h" #include "overlay3D_frag.h" @@ -187,6 +190,7 @@ void initDeferredPipelines(render::ShapePlumber& plumber, const render::ShapePip auto modelLightmapVertex = model_lightmap_vert::getShader(); auto modelLightmapNormalMapVertex = model_lightmap_normal_map_vert::getShader(); auto modelTranslucentVertex = model_translucent_vert::getShader(); + auto modelTranslucentNormalMapVertex = model_translucent_normal_map_vert::getShader(); auto modelShadowVertex = model_shadow_vert::getShader(); auto modelLightmapFadeVertex = model_lightmap_fade_vert::getShader(); @@ -227,6 +231,7 @@ void initDeferredPipelines(render::ShapePlumber& plumber, const render::ShapePip auto modelNormalMapPixel = model_normal_map_frag::getShader(); auto modelTranslucentPixel = model_translucent_frag::getShader(); auto modelTranslucentUnlitPixel = model_translucent_unlit_frag::getShader(); + auto modelTranslucentNormalMapPixel = model_translucent_normal_map_frag::getShader(); auto modelShadowPixel = model_shadow_frag::getShader(); auto modelLightmapPixel = model_lightmap_frag::getShader(); auto modelLightmapNormalMapPixel = model_lightmap_normal_map_frag::getShader(); @@ -239,6 +244,7 @@ void initDeferredPipelines(render::ShapePlumber& plumber, const render::ShapePip auto modelShadowFadePixel = model_shadow_fade_frag::getShader(); auto modelTranslucentFadePixel = model_translucent_fade_frag::getShader(); auto modelTranslucentUnlitFadePixel = model_translucent_unlit_fade_frag::getShader(); + auto modelTranslucentNormalMapFadePixel = model_translucent_normal_map_fade_frag::getShader(); auto simpleFadePixel = simple_textured_fade_frag::getShader(); auto simpleUnlitFadePixel = simple_textured_unlit_fade_frag::getShader(); auto simpleTranslucentFadePixel = simple_transparent_textured_fade_frag::getShader(); @@ -296,7 +302,7 @@ void initDeferredPipelines(render::ShapePlumber& plumber, const render::ShapePip simpleVertex, simpleTranslucentUnlitPixel, nullptr, nullptr); addPipeline( Key::Builder().withMaterial().withTranslucent().withTangents(), - modelTranslucentVertex, modelTranslucentPixel, nullptr, nullptr); + modelTranslucentNormalMapVertex, modelTranslucentNormalMapPixel, nullptr, nullptr); addPipeline( // FIXME: Ignore lightmap for translucents meshpart Key::Builder().withMaterial().withTranslucent().withLightmap(), @@ -316,7 +322,7 @@ void initDeferredPipelines(render::ShapePlumber& plumber, const render::ShapePip simpleFadeVertex, simpleTranslucentUnlitFadePixel, batchSetter, itemSetter); addPipeline( Key::Builder().withMaterial().withTranslucent().withTangents().withFade(), - modelNormalMapFadeVertex, modelTranslucentFadePixel, batchSetter, itemSetter); + modelTranslucentNormalMapVertex, modelTranslucentNormalMapFadePixel, batchSetter, itemSetter); addPipeline( // FIXME: Ignore lightmap for translucents meshpart Key::Builder().withMaterial().withTranslucent().withLightmap().withFade(), @@ -358,14 +364,14 @@ void initDeferredPipelines(render::ShapePlumber& plumber, const render::ShapePip skinModelTranslucentVertex, modelTranslucentPixel, nullptr, nullptr); addPipeline( Key::Builder().withMaterial().withSkinned().withTranslucent().withTangents(), - skinModelNormalMapTranslucentVertex, modelTranslucentPixel, nullptr, nullptr); + skinModelNormalMapTranslucentVertex, modelTranslucentNormalMapPixel, nullptr, nullptr); // Same thing but with Fade on addPipeline( Key::Builder().withMaterial().withSkinned().withTranslucent().withFade(), skinModelFadeVertex, modelTranslucentFadePixel, batchSetter, itemSetter); addPipeline( Key::Builder().withMaterial().withSkinned().withTranslucent().withTangents().withFade(), - skinModelNormalMapFadeVertex, modelTranslucentFadePixel, batchSetter, itemSetter); + skinModelNormalMapFadeVertex, modelTranslucentNormalMapFadePixel, batchSetter, itemSetter); // dual quaternion skinned addPipeline( @@ -388,14 +394,14 @@ void initDeferredPipelines(render::ShapePlumber& plumber, const render::ShapePip skinModelTranslucentDualQuatVertex, modelTranslucentPixel, nullptr, nullptr); addPipeline( Key::Builder().withMaterial().withSkinned().withDualQuatSkinned().withTranslucent().withTangents(), - skinModelNormalMapTranslucentDualQuatVertex, modelTranslucentPixel, nullptr, nullptr); + skinModelNormalMapTranslucentDualQuatVertex, modelTranslucentNormalMapPixel, nullptr, nullptr); // Same thing but with Fade on addPipeline( Key::Builder().withMaterial().withSkinned().withDualQuatSkinned().withTranslucent().withFade(), skinModelFadeDualQuatVertex, modelTranslucentFadePixel, batchSetter, itemSetter); addPipeline( Key::Builder().withMaterial().withSkinned().withDualQuatSkinned().withTranslucent().withTangents().withFade(), - skinModelNormalMapFadeDualQuatVertex, modelTranslucentFadePixel, batchSetter, itemSetter); + skinModelNormalMapFadeDualQuatVertex, modelTranslucentNormalMapFadePixel, batchSetter, itemSetter); // Depth-only addPipeline( From 8e46ebf83bace5fb06ae53036ba09d5cff3d2f79 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Thu, 5 Apr 2018 11:27:26 -0700 Subject: [PATCH 05/16] Prevent Interface from crashing when a Snapshot upload fails --- interface/src/ui/SnapshotUploader.cpp | 8 ++++---- scripts/system/snapshot.js | 2 -- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/interface/src/ui/SnapshotUploader.cpp b/interface/src/ui/SnapshotUploader.cpp index 3408cb8512..91e4ba1217 100644 --- a/interface/src/ui/SnapshotUploader.cpp +++ b/interface/src/ui/SnapshotUploader.cpp @@ -65,7 +65,7 @@ void SnapshotUploader::uploadSuccess(QNetworkReply& reply) { } else { emit DependencyManager::get()->snapshotShared(true, contents); - delete this; + this->deleteLater(); } } @@ -76,13 +76,13 @@ void SnapshotUploader::uploadFailure(QNetworkReply& reply) { replyString = reply.errorString(); } emit DependencyManager::get()->snapshotShared(true, replyString); // maybe someday include _inWorldLocation, _filename? - delete this; + this->deleteLater(); } void SnapshotUploader::createStorySuccess(QNetworkReply& reply) { QString replyString = reply.readAll(); emit DependencyManager::get()->snapshotShared(false, replyString); - delete this; + this->deleteLater(); } void SnapshotUploader::createStoryFailure(QNetworkReply& reply) { @@ -92,6 +92,6 @@ void SnapshotUploader::createStoryFailure(QNetworkReply& reply) { replyString = reply.errorString(); } emit DependencyManager::get()->snapshotShared(true, replyString); - delete this; + this->deleteLater(); } diff --git a/scripts/system/snapshot.js b/scripts/system/snapshot.js index ae8ef52a15..658d1c3ced 100644 --- a/scripts/system/snapshot.js +++ b/scripts/system/snapshot.js @@ -411,8 +411,6 @@ function snapshotUploaded(isError, reply) { } else { print('Ignoring snapshotUploaded() callback for stale ' + (isGif ? 'GIF' : 'Still' ) + ' snapshot. Stale story ID:', storyID); } - } else { - print(reply); } isUploadingPrintableStill = false; } From 010356709dacc31bdccf396a28e3d6d32f9f7b21 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 5 Apr 2018 11:52:31 -0700 Subject: [PATCH 06/16] Remove lock file recovery in entity server * We no longer make backups at the ES, so there is no backup to recover from if we crash during persist to disk. * When loading the most recent backup we look for files that match our backup rules. If we have no backup rules we end up grabbing everything. * Because we grab everything, we are at risk of grabbing the lock file and treating it as a backup. In the case where we crash on persist, we end up replacing the models.json.gz file with the lock file (!!). This commit makes a small change to not do the recovery on startup. In a future update we will remove the backup-related code on the ES altogether. --- libraries/octree/src/OctreePersistThread.cpp | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/libraries/octree/src/OctreePersistThread.cpp b/libraries/octree/src/OctreePersistThread.cpp index 7c5b7eb45c..e6c28f75e8 100644 --- a/libraries/octree/src/OctreePersistThread.cpp +++ b/libraries/octree/src/OctreePersistThread.cpp @@ -192,17 +192,12 @@ bool OctreePersistThread::process() { QString lockFileName = _filename + ".lock"; std::ifstream lockFile(qPrintable(lockFileName), std::ios::in | std::ios::binary | std::ios::ate); if (lockFile.is_open()) { - qCDebug(octree) << "WARNING: Octree lock file detected at startup:" << lockFileName - << "-- Attempting to restore from previous backup file."; - - // This is where we should attempt to find the most recent backup and restore from - // that file as our persist file. - restoreFromMostRecentBackup(); + qCDebug(octree) << "WARNING: Octree lock file detected at startup:" << lockFileName; lockFile.close(); - qCDebug(octree) << "Loading Octree... lock file closed:" << lockFileName; + qCDebug(octree) << "Removing lock file:" << lockFileName; remove(qPrintable(lockFileName)); - qCDebug(octree) << "Loading Octree... lock file removed:" << lockFileName; + qCDebug(octree) << "Lock file removed:" << lockFileName; } persistentFileRead = _tree->readFromFile(qPrintable(_filename.toLocal8Bit())); From 81ba875ad2e1b8c968de701232f44cf87f03b8a7 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Thu, 5 Apr 2018 12:39:49 -0700 Subject: [PATCH 07/16] currentShareableAddress wont return file: urls. copy-current-address menu item uses non-shareable version --- libraries/networking/src/AddressManager.cpp | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/libraries/networking/src/AddressManager.cpp b/libraries/networking/src/AddressManager.cpp index 7d7c2e682b..541b564317 100644 --- a/libraries/networking/src/AddressManager.cpp +++ b/libraries/networking/src/AddressManager.cpp @@ -60,6 +60,7 @@ QUrl AddressManager::currentFacingAddress() const { } QUrl AddressManager::currentShareableAddress(bool domainOnly) const { + QUrl shareableAddress; if (!_shareablePlaceName.isEmpty()) { // if we have a shareable place name use that instead of whatever the current host is QUrl hifiURL; @@ -71,10 +72,16 @@ QUrl AddressManager::currentShareableAddress(bool domainOnly) const { hifiURL.setPath(currentPath()); } - return hifiURL; + shareableAddress = hifiURL; } else { - return currentAddress(domainOnly); + shareableAddress = currentAddress(domainOnly); } + + if (shareableAddress.scheme() == URL_SCHEME_HIFI) { + return QUrl(); // file: urls aren't shareable + } + + return shareableAddress; } QUrl AddressManager::currentFacingShareableAddress() const { @@ -288,6 +295,7 @@ bool AddressManager::handleUrl(const QUrl& lookupUrl, LookupTrigger trigger) { // lookupUrl.scheme() == URL_SCHEME_HTTP || // lookupUrl.scheme() == URL_SCHEME_HTTPS || _previousLookup.clear(); + _shareablePlaceName.clear(); QUrl domainURL = PathUtils::expandToLocalDataAbsolutePath(lookupUrl); setDomainInfo(domainURL, trigger); emit lookupResultsFinished(); @@ -818,7 +826,7 @@ void AddressManager::copyAddress() { } // assume that the address is being copied because the user wants a shareable address - QGuiApplication::clipboard()->setText(currentShareableAddress().toString()); + QGuiApplication::clipboard()->setText(currentFacingAddress().toString()); } void AddressManager::copyPath() { From 1de878eb9c9b0ddfc5b0acb32645ce8caef5c737 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Thu, 5 Apr 2018 12:43:03 -0700 Subject: [PATCH 08/16] fix logic --- libraries/networking/src/AddressManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/networking/src/AddressManager.cpp b/libraries/networking/src/AddressManager.cpp index 541b564317..443626ab52 100644 --- a/libraries/networking/src/AddressManager.cpp +++ b/libraries/networking/src/AddressManager.cpp @@ -77,7 +77,7 @@ QUrl AddressManager::currentShareableAddress(bool domainOnly) const { shareableAddress = currentAddress(domainOnly); } - if (shareableAddress.scheme() == URL_SCHEME_HIFI) { + if (shareableAddress.scheme() != URL_SCHEME_HIFI) { return QUrl(); // file: urls aren't shareable } From 148007435e7aeb784823898fa322d5d478d7dded Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Thu, 5 Apr 2018 13:01:31 -0700 Subject: [PATCH 09/16] update comment --- libraries/networking/src/AddressManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/networking/src/AddressManager.cpp b/libraries/networking/src/AddressManager.cpp index 443626ab52..45e46c70ac 100644 --- a/libraries/networking/src/AddressManager.cpp +++ b/libraries/networking/src/AddressManager.cpp @@ -825,7 +825,7 @@ void AddressManager::copyAddress() { return; } - // assume that the address is being copied because the user wants a shareable address + // currentShareableAddress will be blank for serverless domains, so use currentFacingAddress here QGuiApplication::clipboard()->setText(currentFacingAddress().toString()); } From ac2721fe6a7b410a2d9682008e7ec4150e24f584 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Thu, 5 Apr 2018 13:04:09 -0700 Subject: [PATCH 10/16] Logging improvements --- interface/src/ui/SnapshotUploader.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/interface/src/ui/SnapshotUploader.cpp b/interface/src/ui/SnapshotUploader.cpp index 91e4ba1217..37505db629 100644 --- a/interface/src/ui/SnapshotUploader.cpp +++ b/interface/src/ui/SnapshotUploader.cpp @@ -75,6 +75,8 @@ void SnapshotUploader::uploadFailure(QNetworkReply& reply) { if (replyString.size() == 0) { replyString = reply.errorString(); } + replyString = replyString.left(1000); // Only print first 1000 characters of error + qDebug() << "Snapshot upload reply error (truncated):" << replyString; emit DependencyManager::get()->snapshotShared(true, replyString); // maybe someday include _inWorldLocation, _filename? this->deleteLater(); } @@ -87,10 +89,12 @@ void SnapshotUploader::createStorySuccess(QNetworkReply& reply) { void SnapshotUploader::createStoryFailure(QNetworkReply& reply) { QString replyString = reply.readAll(); - qDebug() << "Error " << reply.errorString() << " uploading snapshot " << _pathname << " from " << _inWorldLocation; + qDebug() << "Error " << reply.errorString() << " uploading snapshot story " << _pathname << " from " << _inWorldLocation; if (replyString.size() == 0) { replyString = reply.errorString(); } + replyString = replyString.left(1000); // Only print first 1000 characters of error + qDebug() << "Snapshot story upload reply error (truncated):" << replyString; emit DependencyManager::get()->snapshotShared(true, replyString); this->deleteLater(); } From 8de545acdf5907a2add6f6f12fe36c33cc2281ae Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Thu, 5 Apr 2018 13:39:51 -0700 Subject: [PATCH 11/16] add new address accessor for 'public' addresses, use it for snapshot and stream --- interface/src/DiscoverabilityManager.cpp | 2 +- interface/src/ui/Snapshot.cpp | 2 +- libraries/networking/src/AddressManager.cpp | 29 ++++++++++++++++----- libraries/networking/src/AddressManager.h | 2 ++ 4 files changed, 26 insertions(+), 9 deletions(-) diff --git a/interface/src/DiscoverabilityManager.cpp b/interface/src/DiscoverabilityManager.cpp index e2d47bf844..33cfc481d7 100644 --- a/interface/src/DiscoverabilityManager.cpp +++ b/interface/src/DiscoverabilityManager.cpp @@ -129,7 +129,7 @@ void DiscoverabilityManager::updateLocation() { // Update Steam if (auto steamClient = PluginManager::getInstance()->getSteamClientPlugin()) { - steamClient->updateLocation(domainHandler.getHostname(), addressManager->currentFacingShareableAddress()); + steamClient->updateLocation(domainHandler.getHostname(), addressManager->currentFacingPublicAddress()); } } diff --git a/interface/src/ui/Snapshot.cpp b/interface/src/ui/Snapshot.cpp index 9b3089d78d..69103a40b5 100644 --- a/interface/src/ui/Snapshot.cpp +++ b/interface/src/ui/Snapshot.cpp @@ -95,7 +95,7 @@ QTemporaryFile* Snapshot::saveTempSnapshot(QImage image) { QFile* Snapshot::savedFileForSnapshot(QImage & shot, bool isTemporary, const QString& userSelectedFilename) { // adding URL to snapshot - QUrl currentURL = DependencyManager::get()->currentShareableAddress(); + QUrl currentURL = DependencyManager::get()->currentPublicAddress(); shot.setText(URL, currentURL.toString()); QString username = DependencyManager::get()->getAccountInfo().getUsername(); diff --git a/libraries/networking/src/AddressManager.cpp b/libraries/networking/src/AddressManager.cpp index 45e46c70ac..cfe05941c0 100644 --- a/libraries/networking/src/AddressManager.cpp +++ b/libraries/networking/src/AddressManager.cpp @@ -60,7 +60,6 @@ QUrl AddressManager::currentFacingAddress() const { } QUrl AddressManager::currentShareableAddress(bool domainOnly) const { - QUrl shareableAddress; if (!_shareablePlaceName.isEmpty()) { // if we have a shareable place name use that instead of whatever the current host is QUrl hifiURL; @@ -72,18 +71,23 @@ QUrl AddressManager::currentShareableAddress(bool domainOnly) const { hifiURL.setPath(currentPath()); } - shareableAddress = hifiURL; + return hifiURL; } else { - shareableAddress = currentAddress(domainOnly); + return currentAddress(domainOnly); } +} +QUrl AddressManager::currentPublicAddress(bool domainOnly) const { + // return an address that can be used by others to visit this client's current location. If + // in a serverless domain (which can't be visited) return an empty URL. + QUrl shareableAddress = currentShareableAddress(domainOnly); if (shareableAddress.scheme() != URL_SCHEME_HIFI) { - return QUrl(); // file: urls aren't shareable + return QUrl(); // file: urls aren't public } - return shareableAddress; } + QUrl AddressManager::currentFacingShareableAddress() const { auto hifiURL = currentShareableAddress(); if (hifiURL.scheme() == URL_SCHEME_HIFI) { @@ -93,6 +97,17 @@ QUrl AddressManager::currentFacingShareableAddress() const { return hifiURL; } +QUrl AddressManager::currentFacingPublicAddress() const { + // return an address that can be used by others to visit this client's current location. If + // in a serverless domain (which can't be visited) return an empty URL. + QUrl shareableAddress = currentFacingShareableAddress(); + if (shareableAddress.scheme() != URL_SCHEME_HIFI) { + return QUrl(); // file: urls aren't public + } + return shareableAddress; +} + + void AddressManager::loadSettings(const QString& lookupString) { #if defined(USE_GLES) && defined(Q_OS_WIN) handleUrl(QUrl("hifi://127.0.0.0"), LookupTrigger::StartupFromSettings); @@ -825,8 +840,8 @@ void AddressManager::copyAddress() { return; } - // currentShareableAddress will be blank for serverless domains, so use currentFacingAddress here - QGuiApplication::clipboard()->setText(currentFacingAddress().toString()); + // assume that the address is being copied because the user wants a shareable address + QGuiApplication::clipboard()->setText(currentShareableAddress().toString()); } void AddressManager::copyPath() { diff --git a/libraries/networking/src/AddressManager.h b/libraries/networking/src/AddressManager.h index dc1046bf51..4add1e9414 100644 --- a/libraries/networking/src/AddressManager.h +++ b/libraries/networking/src/AddressManager.h @@ -150,7 +150,9 @@ public: QUrl currentAddress(bool domainOnly = false) const; QUrl currentFacingAddress() const; QUrl currentShareableAddress(bool domainOnly = false) const; + QUrl currentPublicAddress(bool domainOnly = false) const; QUrl currentFacingShareableAddress() const; + QUrl currentFacingPublicAddress() const; QString currentPath(bool withOrientation = true) const; QString currentFacingPath() const; From 2e3db99f7e56735a03941e039f44d52028bd9d77 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 5 Apr 2018 16:03:49 -0700 Subject: [PATCH 12/16] update to serverless tutorial with RC66 fixes --- cmake/externals/serverless-content/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmake/externals/serverless-content/CMakeLists.txt b/cmake/externals/serverless-content/CMakeLists.txt index 1c66fb213f..4d0773f5f5 100644 --- a/cmake/externals/serverless-content/CMakeLists.txt +++ b/cmake/externals/serverless-content/CMakeLists.txt @@ -4,8 +4,8 @@ set(EXTERNAL_NAME serverless-content) ExternalProject_Add( ${EXTERNAL_NAME} - URL http://cdn.highfidelity.com/content-sets/serverless-tutorial-RC66.zip - URL_MD5 91edfde96e06efc847ca327ab97f4c74 + URL http://cdn.highfidelity.com/content-sets/serverless-tutorial-RC66-v2.zip + URL_MD5 d76bdb3e2bf7ae5d20115bd97b0c44a8 CONFIGURE_COMMAND "" BUILD_COMMAND "" INSTALL_COMMAND "" From a5ee211dbf0cd6a12cc2eb01f97750422775ec9a Mon Sep 17 00:00:00 2001 From: samcake Date: Thu, 5 Apr 2018 18:04:35 -0700 Subject: [PATCH 13/16] Dirty attempt to capture the owner typefor a payload --- interface/src/workload/PhysicsBoundary.h | 12 ++++----- .../src/EntityTreeRenderer.cpp | 2 +- libraries/workload/src/workload/Proxy.h | 25 ++++++++++++++++--- 3 files changed, 29 insertions(+), 10 deletions(-) diff --git a/interface/src/workload/PhysicsBoundary.h b/interface/src/workload/PhysicsBoundary.h index 8f5c1a48ff..4109418e27 100644 --- a/interface/src/workload/PhysicsBoundary.h +++ b/interface/src/workload/PhysicsBoundary.h @@ -61,12 +61,12 @@ public: uint32_t numExits = (uint32_t)regionChanges[exitIndex].size(); for (uint32_t i = 0; i < numExits; ++i) { int32_t proxyID = regionChanges[exitIndex][i]; - void* owner = space->getOwner(proxyID).get(); + auto owner = space->getOwner(proxyID).get(); if (owner) { - EntityItem* entity = static_cast(owner); + //EntityItem* entity = static_cast(owner); std::cout << "adebug - " //<< owner - << " '" << entity->getName().toStdString() << "'" + << " '" << owner->getName().toStdString() << "'" << std::endl; // adebug } } @@ -75,12 +75,12 @@ public: uint32_t numEntries = (uint32_t)regionChanges[enterIndex].size(); for (uint32_t i = 0; i < numEntries; ++i) { int32_t proxyID = regionChanges[enterIndex][i]; - void* owner = space->getOwner(proxyID).get(); + auto owner = space->getOwner(proxyID).get(); if (owner) { - EntityItem* entity = static_cast(owner); + // EntityItem* entity = static_cast(owner); std::cout << "adebug + " //<< owner - << " '" << entity->getName().toStdString() << "'" + << " '" << owner->getName().toStdString() << "'" << std::endl; // adebug } } diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index ac3afb3e2b..8a8b71218c 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -284,7 +284,7 @@ void EntityTreeRenderer::addPendingEntities(const render::ScenePointer& scene, r auto spaceIndex = _space->allocateID(); workload::Sphere sphere(entity->getWorldPosition(), entity->getBoundingRadius()); workload::Transaction transaction; - transaction.reset(spaceIndex, sphere, workload::Owner(entity.get())); + transaction.reset(spaceIndex, sphere, workload::Owner(entity)); _space->enqueueTransaction(transaction); entity->setSpaceIndex(spaceIndex); connect(entity.get(), &EntityItem::spaceUpdate, this, &EntityTreeRenderer::handleSpaceUpdate, Qt::QueuedConnection); diff --git a/libraries/workload/src/workload/Proxy.h b/libraries/workload/src/workload/Proxy.h index 0c1c7363cd..d204bd8544 100644 --- a/libraries/workload/src/workload/Proxy.h +++ b/libraries/workload/src/workload/Proxy.h @@ -18,13 +18,32 @@ namespace workload { class Owner { public: Owner() = default; - Owner(void* data) : _data(data) {} Owner(const Owner& other) = default; Owner& operator=(const Owner& other) = default; + + template Owner(const T& data) : _concept(std::make_shared>(data)) {} + ~Owner() {} - void* get() const { return _data; } + + template const T get() const { return std::static_pointer_cast>(_concept)->_data; } + +protected: + class Concept { + public: + virtual ~Concept() = default; + + }; + template class Model : public Concept { + public: + using Data = T; + Data _data; + + Model(const Data& data) : _data(data) {} + virtual ~Model() = default; + }; + private: - void* _data { nullptr }; + std::shared_ptr _concept; }; class Proxy { From b96a4ed4be81e7de267f2b6c37429304abc53550 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Fri, 6 Apr 2018 07:20:53 -0700 Subject: [PATCH 14/16] add Space::getRegion(id) --- libraries/workload/src/workload/Space.cpp | 4 ++++ libraries/workload/src/workload/Space.h | 1 + 2 files changed, 5 insertions(+) diff --git a/libraries/workload/src/workload/Space.cpp b/libraries/workload/src/workload/Space.cpp index ea18385c93..e5a90503da 100644 --- a/libraries/workload/src/workload/Space.cpp +++ b/libraries/workload/src/workload/Space.cpp @@ -127,6 +127,10 @@ const Owner Space::getOwner(int32_t proxyID) const { return Owner(); } +uint8_t Space::getRegion(int32_t proxyID) const { + return _IDAllocator.checkIndex(proxyID) ? _proxies[proxyID].region : Region::INVALID; +} + void Space::clear() { std::unique_lock lock(_proxiesMutex); _IDAllocator.clear(); diff --git a/libraries/workload/src/workload/Space.h b/libraries/workload/src/workload/Space.h index d8d1659751..8ed85e15ab 100644 --- a/libraries/workload/src/workload/Space.h +++ b/libraries/workload/src/workload/Space.h @@ -49,6 +49,7 @@ public: uint32_t copyProxyValues(Proxy* proxies, uint32_t numDestProxies) const; const Owner getOwner(int32_t proxyID) const; + uint8_t getRegion(int32_t proxyID) const; void clear(); private: From ed1761945c64d16fb3a42c009c5eeb1c75b3015e Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Fri, 6 Apr 2018 07:22:05 -0700 Subject: [PATCH 15/16] add/remove entities to physics using workload output --- interface/src/Application.cpp | 1 + interface/src/workload/PhysicsBoundary.h | 56 ++++--------------- .../src/EntityTreeRenderer.h | 2 +- libraries/physics/CMakeLists.txt | 2 +- .../physics/src/PhysicalEntitySimulation.cpp | 6 +- .../physics/src/PhysicalEntitySimulation.h | 3 + libraries/physics/src/PhysicsEngine.cpp | 2 + libraries/workload/src/workload/Proxy.h | 7 --- 8 files changed, 22 insertions(+), 57 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 1b85563969..1105e7461c 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -4705,6 +4705,7 @@ void Application::init() { }, Qt::QueuedConnection); _gameWorkload.startup(getEntities()->getWorkloadSpace(), _main3DScene, _entitySimulation); + _entitySimulation->setWorkloadSpace(getEntities()->getWorkloadSpace()); } void Application::updateLOD(float deltaTime) const { diff --git a/interface/src/workload/PhysicsBoundary.h b/interface/src/workload/PhysicsBoundary.h index 4109418e27..7eb3644375 100644 --- a/interface/src/workload/PhysicsBoundary.h +++ b/interface/src/workload/PhysicsBoundary.h @@ -15,19 +15,6 @@ #include "render/Scene.h" -/* -class FooJobConfig : public workload::Job::Config { - Q_OBJECT - Q_PROPERTY(bool fubar MEMBER fubar NOTIFY dirty) -public: - bool fubar{ false }; -signals: - void dirty(); -protected: -}; -*/ - -#include // adebug #include #include #include "PhysicalEntitySimulation.h" @@ -45,43 +32,20 @@ public: } void run(const workload::WorkloadContextPointer& context, const Inputs& inputs) { - const auto& regionChanges = inputs.get1(); auto space = context->_space; if (!space) { return; } - uint32_t listSize = (uint32_t)regionChanges.size(); - uint32_t totalTransitions = 0; - for (uint32_t i = 0; i < listSize; ++i) { - totalTransitions += (uint32_t)regionChanges[i].size(); - } - // we're interested in things entering/leaving R3 - uint32_t regionIndex = workload::Region::R3; - uint32_t exitIndex = 2 * regionIndex; - uint32_t numExits = (uint32_t)regionChanges[exitIndex].size(); - for (uint32_t i = 0; i < numExits; ++i) { - int32_t proxyID = regionChanges[exitIndex][i]; - auto owner = space->getOwner(proxyID).get(); - if (owner) { - //EntityItem* entity = static_cast(owner); - std::cout << "adebug - " - //<< owner - << " '" << owner->getName().toStdString() << "'" - << std::endl; // adebug - } - } - - uint32_t enterIndex = exitIndex + 1; - uint32_t numEntries = (uint32_t)regionChanges[enterIndex].size(); - for (uint32_t i = 0; i < numEntries; ++i) { - int32_t proxyID = regionChanges[enterIndex][i]; - auto owner = space->getOwner(proxyID).get(); - if (owner) { - // EntityItem* entity = static_cast(owner); - std::cout << "adebug + " - //<< owner - << " '" << owner->getName().toStdString() << "'" - << std::endl; // adebug + GameWorkloadContext* gameContext = static_cast(context.get()); + PhysicalEntitySimulationPointer simulation = gameContext->_simulation; + const auto& regionChanges = inputs.get0(); + for (uint32_t i = 0; i < (uint32_t)regionChanges.size(); ++i) { + const workload::Space::Change& change = regionChanges[i]; + auto entity = space->getOwner(change.proxyId).get(); + if (entity) { + simulation->changeEntity(entity); + qCDebug("physics") << change.proxyId << " : " << "'" << entity->getName() << "' " + << (uint32_t)(change.prevRegion) << " --> " << (uint32_t)(change.region); } } } diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.h b/libraries/entities-renderer/src/EntityTreeRenderer.h index fa9c2ac6d2..a425ad4676 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.h +++ b/libraries/entities-renderer/src/EntityTreeRenderer.h @@ -121,7 +121,7 @@ public: static bool shouldRenderDebugHulls() { return _renderDebugHullsOperator(); } // Access the workload Space - const workload::SpacePointer getWorkloadSpace() const { return _space; } + workload::SpacePointer getWorkloadSpace() const { return _space; } signals: void enterEntity(const EntityItemID& entityItemID); diff --git a/libraries/physics/CMakeLists.txt b/libraries/physics/CMakeLists.txt index ad082c1a6e..96a55c8477 100644 --- a/libraries/physics/CMakeLists.txt +++ b/libraries/physics/CMakeLists.txt @@ -1,6 +1,6 @@ set(TARGET_NAME physics) setup_hifi_library() -link_hifi_libraries(shared fbx entities graphics) +link_hifi_libraries(shared task workload fbx entities graphics) include_hifi_library_headers(networking) include_hifi_library_headers(gpu) include_hifi_library_headers(avatars) diff --git a/libraries/physics/src/PhysicalEntitySimulation.cpp b/libraries/physics/src/PhysicalEntitySimulation.cpp index d799577fc2..f05f5a94f5 100644 --- a/libraries/physics/src/PhysicalEntitySimulation.cpp +++ b/libraries/physics/src/PhysicalEntitySimulation.cpp @@ -120,8 +120,10 @@ void PhysicalEntitySimulation::changeEntityInternal(EntityItemPointer entity) { QMutexLocker lock(&_mutex); assert(entity); EntityMotionState* motionState = static_cast(entity->getPhysicsInfo()); + uint8_t region = _space->getRegion(entity->getSpaceIndex()); + bool shouldBePhysical = region < workload::Region::R3 && entity->shouldBePhysical(); if (motionState) { - if (!entity->shouldBePhysical()) { + if (!shouldBePhysical) { // the entity should be removed from the physical simulation _incomingChanges.remove(motionState); _physicalObjects.remove(motionState); @@ -133,7 +135,7 @@ void PhysicalEntitySimulation::changeEntityInternal(EntityItemPointer entity) { } else { _incomingChanges.insert(motionState); } - } else if (entity->shouldBePhysical()) { + } else if (shouldBePhysical) { // The intent is for this object to be in the PhysicsEngine, but it has no MotionState yet. // Perhaps it's shape has changed and it can now be added? _entitiesToAddToPhysics.insert(entity); diff --git a/libraries/physics/src/PhysicalEntitySimulation.h b/libraries/physics/src/PhysicalEntitySimulation.h index 7b6fe221fb..3f04347f18 100644 --- a/libraries/physics/src/PhysicalEntitySimulation.h +++ b/libraries/physics/src/PhysicalEntitySimulation.h @@ -19,6 +19,7 @@ #include #include +#include #include "PhysicsEngine.h" #include "EntityMotionState.h" @@ -45,6 +46,7 @@ public: ~PhysicalEntitySimulation(); void init(EntityTreePointer tree, PhysicsEnginePointer engine, EntityEditPacketSender* packetSender); + void setWorkloadSpace(const workload::SpacePointer space) { _space = space; } virtual void addDynamic(EntityDynamicPointer dynamic) override; virtual void applyDynamicChanges() override; @@ -102,6 +104,7 @@ private: VectorOfEntityMotionStates _owned; VectorOfEntityMotionStates _bids; + workload::SpacePointer _space; uint64_t _nextBidExpiry; uint32_t _lastStepSendPackets { 0 }; }; diff --git a/libraries/physics/src/PhysicsEngine.cpp b/libraries/physics/src/PhysicsEngine.cpp index 1d4c385f07..945b9c86dd 100644 --- a/libraries/physics/src/PhysicsEngine.cpp +++ b/libraries/physics/src/PhysicsEngine.cpp @@ -72,6 +72,7 @@ uint32_t PhysicsEngine::getNumSubsteps() { // private void PhysicsEngine::addObjectToDynamicsWorld(ObjectMotionState* motionState) { + qCDebug(physics) << "templog addObject" << (void*)(motionState); // TODO: remove this assert(motionState); btVector3 inertia(0.0f, 0.0f, 0.0f); @@ -193,6 +194,7 @@ void PhysicsEngine::removeObjects(const VectorOfMotionStates& objects) { for (auto object : objects) { btRigidBody* body = object->getRigidBody(); if (body) { + qCDebug(physics) << "removeObject" << (void*)(body->getMotionState()); // TODO: remove this removeDynamicsForBody(body); _dynamicsWorld->removeRigidBody(body); diff --git a/libraries/workload/src/workload/Proxy.h b/libraries/workload/src/workload/Proxy.h index d204bd8544..8e0be6f6f7 100644 --- a/libraries/workload/src/workload/Proxy.h +++ b/libraries/workload/src/workload/Proxy.h @@ -20,28 +20,21 @@ public: Owner() = default; Owner(const Owner& other) = default; Owner& operator=(const Owner& other) = default; - template Owner(const T& data) : _concept(std::make_shared>(data)) {} - ~Owner() {} - template const T get() const { return std::static_pointer_cast>(_concept)->_data; } - protected: class Concept { public: virtual ~Concept() = default; - }; template class Model : public Concept { public: using Data = T; Data _data; - Model(const Data& data) : _data(data) {} virtual ~Model() = default; }; - private: std::shared_ptr _concept; }; From da48a5af20c21e41855c47cfc232ad1a4515196b Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Fri, 6 Apr 2018 11:10:23 -0700 Subject: [PATCH 16/16] fix compile errors and add PhysicsBoundary.cpp file --- interface/src/workload/PhysicsBoundary.cpp | 34 +++++++++++++++++++++ interface/src/workload/PhysicsBoundary.h | 35 ++++------------------ 2 files changed, 40 insertions(+), 29 deletions(-) create mode 100644 interface/src/workload/PhysicsBoundary.cpp diff --git a/interface/src/workload/PhysicsBoundary.cpp b/interface/src/workload/PhysicsBoundary.cpp new file mode 100644 index 0000000000..a62dfcf9f9 --- /dev/null +++ b/interface/src/workload/PhysicsBoundary.cpp @@ -0,0 +1,34 @@ +// +// PhysicsBoundary.h +// +// Created by Andrew Meadows 2018.04.05 +// Copyright 2018 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include "PhysicsBoundary.h" + +#include +#include + +#include "workload/GameWorkload.h" + +void PhysicsBoundary::run(const workload::WorkloadContextPointer& context, const Inputs& inputs) { + auto space = context->_space; + if (!space) { + return; + } + GameWorkloadContext* gameContext = static_cast(context.get()); + PhysicalEntitySimulationPointer simulation = gameContext->_simulation; + const auto& regionChanges = inputs.get0(); + for (uint32_t i = 0; i < (uint32_t)regionChanges.size(); ++i) { + const workload::Space::Change& change = regionChanges[i]; + auto entity = space->getOwner(change.proxyId).get(); + if (entity) { + simulation->changeEntity(entity); + qCDebug(physics) << change.proxyId << " : " << "'" << entity->getName() << "' " << (uint32_t)(change.prevRegion) << " --> " << (uint32_t)(change.region); + } + } +} diff --git a/interface/src/workload/PhysicsBoundary.h b/interface/src/workload/PhysicsBoundary.h index 7eb3644375..c316fa5686 100644 --- a/interface/src/workload/PhysicsBoundary.h +++ b/interface/src/workload/PhysicsBoundary.h @@ -1,7 +1,7 @@ // // PhysicsBoundary.h // -// Created by Sam Gateau on 2/16/2018. +// Created by Andrew Meadows 2018.04.05 // Copyright 2018 High Fidelity, Inc. // // Distributed under the Apache License, Version 2.0. @@ -10,13 +10,10 @@ #ifndef hifi_PhysicsGatekeeper_h #define hifi_PhysicsGatekeeper_h -#include "workload/Space.h" -#include "workload/Engine.h" - -#include "render/Scene.h" - -#include #include +#include +#include + #include "PhysicalEntitySimulation.h" class PhysicsBoundary { @@ -27,28 +24,8 @@ public: using JobModel = workload::Job::ModelI; // this doesn't work PhysicsBoundary() {} - - void configure(const Config& config) { - } - - void run(const workload::WorkloadContextPointer& context, const Inputs& inputs) { - auto space = context->_space; - if (!space) { - return; - } - GameWorkloadContext* gameContext = static_cast(context.get()); - PhysicalEntitySimulationPointer simulation = gameContext->_simulation; - const auto& regionChanges = inputs.get0(); - for (uint32_t i = 0; i < (uint32_t)regionChanges.size(); ++i) { - const workload::Space::Change& change = regionChanges[i]; - auto entity = space->getOwner(change.proxyId).get(); - if (entity) { - simulation->changeEntity(entity); - qCDebug("physics") << change.proxyId << " : " << "'" << entity->getName() << "' " - << (uint32_t)(change.prevRegion) << " --> " << (uint32_t)(change.region); - } - } - } + void configure(const Config& config) { } + void run(const workload::WorkloadContextPointer& context, const Inputs& inputs); }; #endif // hifi_PhysicsGatekeeper_h