From 4ca0048ec9605fe5df00c2d8c00ba5422126f03d Mon Sep 17 00:00:00 2001 From: David Rowe Date: Fri, 7 Oct 2016 15:21:24 +1300 Subject: [PATCH 01/20] Display minimized users list when not logged in --- scripts/system/users.js | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/scripts/system/users.js b/scripts/system/users.js index 76722bd58d..454f8811a6 100644 --- a/scripts/system/users.js +++ b/scripts/system/users.js @@ -565,28 +565,28 @@ var usersWindow = (function () { function updateOverlayVisibility() { Overlays.editOverlay(windowBorder, { - visible: isLoggedIn && isVisible && isBorderVisible + visible: isVisible && isBorderVisible }); Overlays.editOverlay(windowPane, { - visible: isLoggedIn && isVisible + visible: isVisible }); Overlays.editOverlay(windowHeading, { - visible: isLoggedIn && isVisible + visible: isVisible }); Overlays.editOverlay(minimizeButton, { visible: isLoggedIn && isVisible }); Overlays.editOverlay(scrollbarBackground, { - visible: isLoggedIn && isVisible && isUsingScrollbars && !isMinimized + visible: isVisible && isUsingScrollbars && !isMinimized }); Overlays.editOverlay(scrollbarBar, { - visible: isLoggedIn && isVisible && isUsingScrollbars && !isMinimized + visible: isVisible && isUsingScrollbars && !isMinimized }); Overlays.editOverlay(friendsButton, { - visible: isLoggedIn && isVisible && !isMinimized + visible: isVisible && !isMinimized }); - displayControl.setVisible(isLoggedIn && isVisible && !isMinimized); - visibilityControl.setVisible(isLoggedIn && isVisible && !isMinimized); + displayControl.setVisible(isVisible && !isMinimized); + visibilityControl.setVisible(isVisible && !isMinimized); } function checkLoggedIn() { @@ -594,6 +594,13 @@ var usersWindow = (function () { isLoggedIn = Account.isLoggedIn(); if (isLoggedIn !== wasLoggedIn) { + if (wasLoggedIn) { + setMinimized(true); + calculateWindowHeight(); + updateOverlayPositions(); + updateUsersDisplay(); + } + updateOverlayVisibility(); } } From c637649805edf81f794dfd944a6936c3d1fa7ff8 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Fri, 7 Oct 2016 15:25:47 +1300 Subject: [PATCH 02/20] Make users online title say to login to view --- scripts/system/users.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/system/users.js b/scripts/system/users.js index 454f8811a6..9dc451a8ed 100644 --- a/scripts/system/users.js +++ b/scripts/system/users.js @@ -559,7 +559,7 @@ var usersWindow = (function () { }); Overlays.editOverlay(windowHeading, { - text: linesOfUsers.length > 0 ? "Users online" : "No users online" + text: isLoggedIn ? (linesOfUsers.length > 0 ? "Users online" : "No users online") : "Users online - log in to view" }); } @@ -1028,7 +1028,7 @@ var usersWindow = (function () { color: WINDOW_HEADING_COLOR, alpha: WINDOW_HEADING_ALPHA, backgroundAlpha: 0.0, - text: "No users online", + text: "Users online", font: WINDOW_FONT, visible: false }); From c76bb01359f45173d7415e8f9be63b052b7ddc34 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Fri, 7 Oct 2016 15:39:46 +1300 Subject: [PATCH 03/20] Make Interface title say if user not logged in --- interface/src/Application.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 610144b2cc..c7101f7434 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -4568,11 +4568,15 @@ void Application::resetSensors(bool andReload) { void Application::updateWindowTitle() const { - QString buildVersion = " (build " + applicationVersion() + ")"; auto nodeList = DependencyManager::get(); + auto accountManager = DependencyManager::get(); - QString connectionStatus = nodeList->getDomainHandler().isConnected() ? "" : " (NOT CONNECTED) "; - QString username = DependencyManager::get()->getAccountInfo().getUsername(); + QString buildVersion = " (build " + applicationVersion() + ")"; + + QString loginStatus = accountManager->isLoggedIn() ? "" : " (NOT LOGGED IN)"; + + QString connectionStatus = nodeList->getDomainHandler().isConnected() ? "" : " (NOT CONNECTED)"; + QString username = accountManager->getAccountInfo().getUsername(); QString currentPlaceName = DependencyManager::get()->getHost(); if (currentPlaceName.isEmpty()) { @@ -4580,7 +4584,7 @@ void Application::updateWindowTitle() const { } QString title = QString() + (!username.isEmpty() ? username + " @ " : QString()) - + currentPlaceName + connectionStatus + buildVersion; + + currentPlaceName + connectionStatus + loginStatus + buildVersion; #ifndef WIN32 // crashes with vs2013/win32 From 52fbb654fae3f876a6a34d2880b9df3eb8f41b74 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Fri, 7 Oct 2016 15:43:54 +1300 Subject: [PATCH 04/20] Tweak location of users online minimize/maximize button --- scripts/system/users.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/system/users.js b/scripts/system/users.js index 9dc451a8ed..1e1a68fd9c 100644 --- a/scripts/system/users.js +++ b/scripts/system/users.js @@ -469,7 +469,7 @@ var usersWindow = (function () { Overlays.editOverlay(minimizeButton, { x: windowLeft + WINDOW_WIDTH - WINDOW_MARGIN / 2 - MIN_MAX_BUTTON_WIDTH, - y: windowTop + WINDOW_MARGIN / 2 + y: windowTop + WINDOW_MARGIN }); scrollbarBackgroundPosition.x = windowLeft + WINDOW_WIDTH - 0.5 * WINDOW_MARGIN - SCROLLBAR_BACKGROUND_WIDTH; From c5f889a34dae02670edee1d972a178c26ecfe522 Mon Sep 17 00:00:00 2001 From: howard-stearns Date: Fri, 7 Oct 2016 15:13:37 -0700 Subject: [PATCH 05/20] update for sound --- .../tests/performance/crowd-agent.js | 28 ++++++++++++-- scripts/developer/tests/performance/summon.js | 38 ++++++++++++++++--- 2 files changed, 56 insertions(+), 10 deletions(-) diff --git a/scripts/developer/tests/performance/crowd-agent.js b/scripts/developer/tests/performance/crowd-agent.js index 5df576cf99..6b73d66c4f 100644 --- a/scripts/developer/tests/performance/crowd-agent.js +++ b/scripts/developer/tests/performance/crowd-agent.js @@ -16,7 +16,7 @@ var MESSAGE_CHANNEL = "io.highfidelity.summon-crowd"; -print('crowd-agent version 1'); +print('crowd-agent version 2'); /* Observations: - File urls for AC scripts silently fail. Use a local server (e.g., python SimpleHTTPServer) for development. @@ -24,9 +24,26 @@ print('crowd-agent version 1'); - JSON.stringify(Avatar) silently fails (even when Agent.isAvatar) */ +function messageSend(message) { + Messages.sendMessage(MESSAGE_CHANNEL, JSON.stringify(message)); +} + +function getSound(data, callback) { // callback(sound) when downloaded (which may be immediate). + var sound = SoundCache.getSound(data.url); + if (sound.downloaded) { + return callback(sound); + } + sound.ready.connect(function () { callback(sound); }); +} +function onFinishedPlaying() { + messageSend({key: 'finishedSound'}); +} + +var MILLISECONDS_IN_SECOND = 1000; function startAgent(parameters) { // Can also be used to update. print('crowd-agent starting params', JSON.stringify(parameters), JSON.stringify(Agent)); Agent.isAvatar = true; + Agent.isListeningToAudioStream = true; // Send silence when not chattering. if (parameters.position) { Avatar.position = parameters.position; } @@ -36,6 +53,12 @@ function startAgent(parameters) { // Can also be used to update. if (parameters.skeletonModelURL) { Avatar.skeletonModelURL = parameters.skeletonModelURL; } + if (parameters.soundData) { + getSound(parameters.soundData, function (sound) { + Script.setTimeout(onFinishedPlaying, sound.duration * MILLISECONDS_IN_SECOND); + Agent.playAvatarSound(sound); + }); + } if (parameters.animationData) { data = parameters.animationData; Avatar.startAnimation(data.url, data.fps || 30, 1.0, (data.loopFlag === undefined) ? true : data.loopFlag, false, data.startFrame || 0, data.endFrame); @@ -47,9 +70,6 @@ function stopAgent(parameters) { print('crowd-agent stopped', JSON.stringify(parameters), JSON.stringify(Agent)); } -function messageSend(message) { - Messages.sendMessage(MESSAGE_CHANNEL, JSON.stringify(message)); -} function messageHandler(channel, messageString, senderID) { if (channel !== MESSAGE_CHANNEL) { return; diff --git a/scripts/developer/tests/performance/summon.js b/scripts/developer/tests/performance/summon.js index 2eb1fbe301..10c3af5ae5 100644 --- a/scripts/developer/tests/performance/summon.js +++ b/scripts/developer/tests/performance/summon.js @@ -18,15 +18,25 @@ var label = "summon"; function debug() { print.apply(null, [].concat.apply([label, version], [].map.call(arguments, JSON.stringify))); } -var MINIMUM_AVATARS = 25; +var MINIMUM_AVATARS = 25; // We will summon agents to produce this many total. (Of course, there might not be enough agents.) var DENSITY = 0.3; // square meters per person. Some say 10 sq ft is arm's length (0.9m^2), 4.5 is crowd (0.4m^2), 2.5 is mosh pit (0.2m^2). +var SOUND_DATA = {url: "http://howard-stearns.github.io/models/sounds/piano1.wav"}; +var AVATARS_CHATTERING_AT_ONCE = 4; // How many of the agents should we request to play SOUND at once. +var NEXT_SOUND_SPREAD = 500; // millisecond range of how long to wait after one sound finishes, before playing the next + var spread = Math.sqrt(MINIMUM_AVATARS * DENSITY); // meters var turnSpread = 90; // How many degrees should turn from front range over. function coord() { return (Math.random() * spread) - (spread / 2); } // randomly distribute a coordinate zero += spread/2. - +function contains(array, item) { return array.indexOf(item) >= 0; } +function without(array, itemsToRemove) { return array.filter(function (item) { return !contains(itemsToRemove, item); }); } +function nextAfter(array, id) { // Wrapping next element in array after id. + var index = array.indexOf(id) + 1; + return array[(index >= array.length) ? 0 : index]; +} var summonedAgents = []; +var chattering = []; var MESSAGE_CHANNEL = "io.highfidelity.summon-crowd"; function messageSend(message) { Messages.sendMessage(MESSAGE_CHANNEL, JSON.stringify(message)); @@ -48,15 +58,20 @@ function messageHandler(channel, messageString, senderID) { switch (message.key) { case "hello": // There can be avatars we've summoned that do not yet appear in the AvatarList. - avatarIdentifiers = AvatarList.getAvatarIdentifiers().filter(function (id) { return summonedAgents.indexOf(id) === -1; }); + avatarIdentifiers = without(AvatarList.getAvatarIdentifiers(), summonedAgents); debug('present', avatarIdentifiers, summonedAgents); if ((summonedAgents.length + avatarIdentifiers.length) < MINIMUM_AVATARS ) { + var chatter = chattering.length < AVATARS_CHATTERING_AT_ONCE; + if (chatter) { + chattering.push(senderID); + } summonedAgents.push(senderID); messageSend({ key: 'SUMMON', rcpt: senderID, position: Vec3.sum(MyAvatar.position, {x: coord(), y: 0, z: coord()}), - orientation: Quat.fromPitchYawRollDegrees(0, Quat.safeEulerAngles(MyAvatar.orientation).y + (turnSpread * (Math.random() - 0.5)), 0)/*, + orientation: Quat.fromPitchYawRollDegrees(0, Quat.safeEulerAngles(MyAvatar.orientation).y + (turnSpread * (Math.random() - 0.5)), 0), + soundData: chatter && SOUND_DATA/* // No need to specify skeletonModelURL //skeletonModelURL: "file:///c:/Program Files/High Fidelity Release/resources/meshes/being_of_light/being_of_light.fbx", //skeletonModelURL: "file:///c:/Program Files/High Fidelity Release/resources/meshes/defaultAvatar_full.fst"/, @@ -71,6 +86,16 @@ function messageHandler(channel, messageString, senderID) { }); } break; + case "finishedSound": // Give someone else a chance. + chattering = without(chattering, [senderID]); + Script.setTimeout(function () { + messageSend({ + key: 'SUMMON', + rcpt: nextAfter(without(summonedAgents, chattering), senderID), + soundData: SOUND_DATA + }); + }, Math.random() * NEXT_SOUND_SPREAD); + break; case "HELO": Window.alert("Someone else is summoning avatars."); break; @@ -93,11 +118,12 @@ Script.scriptEnding.connect(function () { messageSend({key: 'HELO'}); // Ask agents to report in now. Script.setTimeout(function () { + var total = AvatarList.getAvatarIdentifiers().length; if (0 === summonedAgents.length) { Window.alert("No agents reported.\n\Please run " + MINIMUM_AVATARS + " instances of\n\ http://cdn.highfidelity.com/davidkelly/production/scripts/tests/performance/crowd-agent.js\n\ on your domain server."); - } else if (summonedAgents.length < MINIMUM_AVATARS) { - Window.alert("Only " + summonedAgents.length + " of the expected " + MINIMUM_AVATARS + " agents reported in."); + } else if (total < MINIMUM_AVATARS) { + Window.alert("Only " + summonedAgents.length + " of the expected " + (MINIMUM_AVATARS - total) + " agents + reported in."); } }, 5000); From 7c5dd89372a0f420c8f46a26902ecc63400b70e6 Mon Sep 17 00:00:00 2001 From: howard-stearns Date: Fri, 7 Oct 2016 15:27:58 -0700 Subject: [PATCH 06/20] typo --- scripts/developer/tests/performance/summon.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/developer/tests/performance/summon.js b/scripts/developer/tests/performance/summon.js index 10c3af5ae5..8118f553f1 100644 --- a/scripts/developer/tests/performance/summon.js +++ b/scripts/developer/tests/performance/summon.js @@ -124,6 +124,6 @@ Script.setTimeout(function () { http://cdn.highfidelity.com/davidkelly/production/scripts/tests/performance/crowd-agent.js\n\ on your domain server."); } else if (total < MINIMUM_AVATARS) { - Window.alert("Only " + summonedAgents.length + " of the expected " + (MINIMUM_AVATARS - total) + " agents + reported in."); + Window.alert("Only " + summonedAgents.length + " of the expected " + (MINIMUM_AVATARS - total) + " agents reported in."); } }, 5000); From 9712301172a515c196a0eca9c6e0098fdf4c0160 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 10 Oct 2016 11:54:33 -0700 Subject: [PATCH 07/20] avoid a race that can cause metaverse to not have correct ice-server information about a domain --- domain-server/src/DomainServer.cpp | 21 +++++++++++++++++++++ domain-server/src/DomainServer.h | 4 ++++ 2 files changed, 25 insertions(+) diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index d7bcaa838e..c6425f5016 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -1278,6 +1278,13 @@ void DomainServer::handleMetaverseHeartbeatError(QNetworkReply& requestReply) { } void DomainServer::sendICEServerAddressToMetaverseAPI() { + if (_sendICEServerAddressToMetaverseAPIInProgress) { + // don't have more than one of these in-flight at a time. set a flag to indicate that once the current one + // is done, we need to do update metaverse again. + _sendICEServerAddressToMetaverseAPIRedo = true; + return; + } + _sendICEServerAddressToMetaverseAPIInProgress = true; const QString ICE_SERVER_ADDRESS = "ice_server_address"; QJsonObject domainObject; @@ -1302,6 +1309,8 @@ void DomainServer::sendICEServerAddressToMetaverseAPI() { JSONCallbackParameters callbackParameters; callbackParameters.errorCallbackReceiver = this; callbackParameters.errorCallbackMethod = "handleFailedICEServerAddressUpdate"; + callbackParameters.jsonCallbackReceiver = this; + callbackParameters.jsonCallbackMethod = "handleSuccessfulICEServerAddressUpdate"; static QString repeatedMessage = LogHandler::getInstance().addOnlyOnceMessageRegex ("Updating ice-server address in High Fidelity Metaverse API to [^ \n]+"); @@ -1317,7 +1326,19 @@ void DomainServer::sendICEServerAddressToMetaverseAPI() { domainUpdateJSON.toUtf8()); } +void DomainServer::handleSuccessfulICEServerAddressUpdate(QNetworkReply& requestReply) { + _sendICEServerAddressToMetaverseAPIInProgress = false; + if (_sendICEServerAddressToMetaverseAPIRedo) { + qDebug() << "ice-server address updated with metaverse, but has since changed. redoing update..."; + _sendICEServerAddressToMetaverseAPIRedo = false; + sendICEServerAddressToMetaverseAPI(); + } else { + qDebug() << "ice-server address updated with metaverse."; + } +} + void DomainServer::handleFailedICEServerAddressUpdate(QNetworkReply& requestReply) { + _sendICEServerAddressToMetaverseAPIInProgress = false; const int ICE_SERVER_UPDATE_RETRY_MS = 2 * 1000; qWarning() << "Failed to update ice-server address with High Fidelity Metaverse - error was" << requestReply.errorString(); diff --git a/domain-server/src/DomainServer.h b/domain-server/src/DomainServer.h index 066f2be0d1..6330cf51a5 100644 --- a/domain-server/src/DomainServer.h +++ b/domain-server/src/DomainServer.h @@ -96,6 +96,7 @@ private slots: void handleICEHostInfo(const QHostInfo& hostInfo); void sendICEServerAddressToMetaverseAPI(); + void handleSuccessfulICEServerAddressUpdate(QNetworkReply& requestReply); void handleFailedICEServerAddressUpdate(QNetworkReply& requestReply); signals: @@ -211,6 +212,9 @@ private: int _iceServerPort; bool _overrideDomainID { false }; // should we override the domain-id from settings? QUuid _overridingDomainID { QUuid() }; // what should we override it with? + + bool _sendICEServerAddressToMetaverseAPIInProgress { false }; + bool _sendICEServerAddressToMetaverseAPIRedo { false }; }; From e9961110e92dba4c1b217aafed5a9688c9351954 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 10 Oct 2016 15:40:59 -0700 Subject: [PATCH 08/20] if we have new ice-server information, retry right away, even if the previous attempt failed --- domain-server/src/DomainServer.cpp | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index c6425f5016..26c37f1918 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -1339,12 +1339,19 @@ void DomainServer::handleSuccessfulICEServerAddressUpdate(QNetworkReply& request void DomainServer::handleFailedICEServerAddressUpdate(QNetworkReply& requestReply) { _sendICEServerAddressToMetaverseAPIInProgress = false; - const int ICE_SERVER_UPDATE_RETRY_MS = 2 * 1000; + if (_sendICEServerAddressToMetaverseAPIRedo) { + // if we have new data, retry right away, even though the previous attempt didn't go well. + _sendICEServerAddressToMetaverseAPIRedo = false; + sendICEServerAddressToMetaverseAPI(); + } else { + const int ICE_SERVER_UPDATE_RETRY_MS = 2 * 1000; - qWarning() << "Failed to update ice-server address with High Fidelity Metaverse - error was" << requestReply.errorString(); - qWarning() << "\tRe-attempting in" << ICE_SERVER_UPDATE_RETRY_MS / 1000 << "seconds"; + qWarning() << "Failed to update ice-server address with High Fidelity Metaverse - error was" + << requestReply.errorString(); + qWarning() << "\tRe-attempting in" << ICE_SERVER_UPDATE_RETRY_MS / 1000 << "seconds"; - QTimer::singleShot(ICE_SERVER_UPDATE_RETRY_MS, this, SLOT(sendICEServerAddressToMetaverseAPI())); + QTimer::singleShot(ICE_SERVER_UPDATE_RETRY_MS, this, SLOT(sendICEServerAddressToMetaverseAPI())); + } } void DomainServer::sendHeartbeatToIceServer() { From 7ab76984ad8f08900fd27c63f20f0c3e60dbca84 Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Mon, 10 Oct 2016 16:54:08 -0700 Subject: [PATCH 09/20] Fix crash when switching to desktop mode from oculus HMD mode Removed internalPresent in oculus uncustomizeContext. It had no ill effects. --- plugins/oculus/src/OculusBaseDisplayPlugin.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/plugins/oculus/src/OculusBaseDisplayPlugin.cpp b/plugins/oculus/src/OculusBaseDisplayPlugin.cpp index 83da154b1f..377050064a 100644 --- a/plugins/oculus/src/OculusBaseDisplayPlugin.cpp +++ b/plugins/oculus/src/OculusBaseDisplayPlugin.cpp @@ -63,7 +63,6 @@ void OculusBaseDisplayPlugin::customizeContext() { void OculusBaseDisplayPlugin::uncustomizeContext() { Parent::uncustomizeContext(); - internalPresent(); } bool OculusBaseDisplayPlugin::internalActivate() { From 0951ca6bbe07e301b575389412a4dd0d4ca99c87 Mon Sep 17 00:00:00 2001 From: samcake Date: Mon, 10 Oct 2016 18:43:24 -0700 Subject: [PATCH 10/20] Add check for bad texture resource slot --- libraries/gpu-gl/src/gpu/gl/GLBackendPipeline.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libraries/gpu-gl/src/gpu/gl/GLBackendPipeline.cpp b/libraries/gpu-gl/src/gpu/gl/GLBackendPipeline.cpp index f18962976c..ed0b9607e6 100644 --- a/libraries/gpu-gl/src/gpu/gl/GLBackendPipeline.cpp +++ b/libraries/gpu-gl/src/gpu/gl/GLBackendPipeline.cpp @@ -192,6 +192,11 @@ void GLBackend::resetResourceStage() { void GLBackend::do_setResourceTexture(const Batch& batch, size_t paramOffset) { GLuint slot = batch._params[paramOffset + 1]._uint; + if (slot >= (GLuint) MAX_NUM_RESOURCE_TEXTURES) { + // "GLBackend::do_setResourceTexture: Trying to set a resource Texture at slot #" + slot + " which doesn't exist. MaxNumResourceTextures = " + getMaxNumResourceTextures()); + return; + } + TexturePointer resourceTexture = batch._textures.get(batch._params[paramOffset + 0]._uint); if (!resourceTexture) { From ec5850b82bce689d482b3cacd956b512e2d6206e Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 10 Oct 2016 17:59:01 -0700 Subject: [PATCH 11/20] emit ReceivedMessage progress signals more frequently for new timeout --- libraries/networking/src/ReceivedMessage.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/networking/src/ReceivedMessage.cpp b/libraries/networking/src/ReceivedMessage.cpp index cd3eb03473..e860fa0829 100644 --- a/libraries/networking/src/ReceivedMessage.cpp +++ b/libraries/networking/src/ReceivedMessage.cpp @@ -54,7 +54,7 @@ void ReceivedMessage::appendPacket(NLPacket& packet) { "We should not be appending to a complete message"); // Limit progress signal to every X packets - const int EMIT_PROGRESS_EVERY_X_PACKETS = 100; + const int EMIT_PROGRESS_EVERY_X_PACKETS = 5; ++_numPackets; From 826c2f1a9febf132c8dabcced0c67ce81e2ac860 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 11 Oct 2016 09:53:02 -0700 Subject: [PATCH 12/20] push the AssetResourceRequest timeout to 15s --- libraries/networking/src/AssetResourceRequest.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/networking/src/AssetResourceRequest.cpp b/libraries/networking/src/AssetResourceRequest.cpp index f320f00dbb..3c53288dfb 100644 --- a/libraries/networking/src/AssetResourceRequest.cpp +++ b/libraries/networking/src/AssetResourceRequest.cpp @@ -39,7 +39,7 @@ bool AssetResourceRequest::urlIsAssetHash() const { void AssetResourceRequest::setupTimer() { Q_ASSERT(!_sendTimer); - static const int TIMEOUT_MS = 2000; + static const int TIMEOUT_MS = 15000; _sendTimer = new QTimer(this); connect(_sendTimer, &QTimer::timeout, this, &AssetResourceRequest::onTimeout); From 350977f03e77ca73043e24159d20893acd53de60 Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Tue, 11 Oct 2016 10:49:43 -0700 Subject: [PATCH 13/20] Speculative fix for crash in AudioClient --- libraries/audio-client/src/AudioClient.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libraries/audio-client/src/AudioClient.cpp b/libraries/audio-client/src/AudioClient.cpp index 6fbd93e386..5fced85d2d 100644 --- a/libraries/audio-client/src/AudioClient.cpp +++ b/libraries/audio-client/src/AudioClient.cpp @@ -867,6 +867,10 @@ void AudioClient::handleLocalEchoAndReverb(QByteArray& inputByteArray) { void AudioClient::handleAudioInput() { + if (!_inputDevice) { + return; + } + // input samples required to produce exactly NETWORK_FRAME_SAMPLES of output const int inputSamplesRequired = (_inputToNetworkResampler ? _inputToNetworkResampler->getMinInput(AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL) : From a0c27e2130e788f417013136a44c251c7c893da5 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 11 Oct 2016 13:17:57 -0700 Subject: [PATCH 14/20] remove timer forced timeouts in ARR, occasionally ouput DL progress --- .../networking/src/AssetResourceRequest.cpp | 72 ++++++------------- .../networking/src/AssetResourceRequest.h | 10 ++- libraries/networking/src/ReceivedMessage.cpp | 2 +- 3 files changed, 26 insertions(+), 58 deletions(-) diff --git a/libraries/networking/src/AssetResourceRequest.cpp b/libraries/networking/src/AssetResourceRequest.cpp index 3c53288dfb..2be4145cd0 100644 --- a/libraries/networking/src/AssetResourceRequest.cpp +++ b/libraries/networking/src/AssetResourceRequest.cpp @@ -11,10 +11,12 @@ #include "AssetResourceRequest.h" +#include + #include "AssetClient.h" #include "AssetUtils.h" #include "MappingRequest.h" -#include +#include "NetworkLogging.h" AssetResourceRequest::~AssetResourceRequest() { if (_assetMappingRequest) { @@ -24,10 +26,6 @@ AssetResourceRequest::~AssetResourceRequest() { if (_assetRequest) { _assetRequest->deleteLater(); } - - if (_sendTimer) { - cleanupTimer(); - } } bool AssetResourceRequest::urlIsAssetHash() const { @@ -37,24 +35,6 @@ bool AssetResourceRequest::urlIsAssetHash() const { return hashRegex.exactMatch(_url.toString()); } -void AssetResourceRequest::setupTimer() { - Q_ASSERT(!_sendTimer); - static const int TIMEOUT_MS = 15000; - - _sendTimer = new QTimer(this); - connect(_sendTimer, &QTimer::timeout, this, &AssetResourceRequest::onTimeout); - - _sendTimer->setSingleShot(true); - _sendTimer->start(TIMEOUT_MS); -} - -void AssetResourceRequest::cleanupTimer() { - Q_ASSERT(_sendTimer); - disconnect(_sendTimer, 0, this, 0); - _sendTimer->deleteLater(); - _sendTimer = nullptr; -} - void AssetResourceRequest::doSend() { // We'll either have a hash or an ATP path to a file (that maps to a hash) if (urlIsAssetHash()) { @@ -81,8 +61,6 @@ void AssetResourceRequest::requestMappingForPath(const AssetPath& path) { Q_ASSERT(_state == InProgress); Q_ASSERT(request == _assetMappingRequest); - cleanupTimer(); - switch (request->getError()) { case MappingRequest::NoError: // we have no error, we should have a resulting hash - use that to send of a request for that asset @@ -118,7 +96,6 @@ void AssetResourceRequest::requestMappingForPath(const AssetPath& path) { _assetMappingRequest = nullptr; }); - setupTimer(); _assetMappingRequest->start(); } @@ -133,8 +110,6 @@ void AssetResourceRequest::requestHash(const AssetHash& hash) { Q_ASSERT(_state == InProgress); Q_ASSERT(req == _assetRequest); Q_ASSERT(req->getState() == AssetRequest::Finished); - - cleanupTimer(); switch (req->getError()) { case AssetRequest::Error::NoError: @@ -162,35 +137,30 @@ void AssetResourceRequest::requestHash(const AssetHash& hash) { _assetRequest = nullptr; }); - setupTimer(); _assetRequest->start(); } void AssetResourceRequest::onDownloadProgress(qint64 bytesReceived, qint64 bytesTotal) { Q_ASSERT(_state == InProgress); - // We've received data, so reset the timer - _sendTimer->start(); - emit progress(bytesReceived, bytesTotal); + + static const int DOWNLOAD_PROGRESS_LOG_INTERVAL_SECONDS = 5; + auto now = p_high_resolution_clock::now(); + + // if we haven't received the full asset check if it is time to output progress to log + // we do so every X seconds to assist with ATP download tracking + + if (bytesReceived != bytesTotal + && now - _lastProgressDebug > std::chrono::seconds(DOWNLOAD_PROGRESS_LOG_INTERVAL_SECONDS)) { + + int percentage = roundf((float) bytesReceived / (float) bytesTotal * 100.0f); + + qCDebug(networking).nospace() << "Progress for " << _url.path() << " - " + << bytesReceived << " bytes of " << bytesTotal << " - " << percentage << "%"; + + _lastProgressDebug = now; + } + } -void AssetResourceRequest::onTimeout() { - if (_state == InProgress) { - qWarning() << "Asset request timed out: " << _url; - if (_assetRequest) { - disconnect(_assetRequest, 0, this, 0); - _assetRequest->deleteLater(); - _assetRequest = nullptr; - } - if (_assetMappingRequest) { - disconnect(_assetMappingRequest, 0, this, 0); - _assetMappingRequest->deleteLater(); - _assetMappingRequest = nullptr; - } - _result = Timeout; - _state = Finished; - emit finished(); - } - cleanupTimer(); -} diff --git a/libraries/networking/src/AssetResourceRequest.h b/libraries/networking/src/AssetResourceRequest.h index c462fbc3f8..93f76cb154 100644 --- a/libraries/networking/src/AssetResourceRequest.h +++ b/libraries/networking/src/AssetResourceRequest.h @@ -14,6 +14,8 @@ #include +#include + #include "AssetRequest.h" #include "ResourceRequest.h" @@ -28,21 +30,17 @@ protected: private slots: void onDownloadProgress(qint64 bytesReceived, qint64 bytesTotal); - void onTimeout(); private: - void setupTimer(); - void cleanupTimer(); - bool urlIsAssetHash() const; void requestMappingForPath(const AssetPath& path); void requestHash(const AssetHash& hash); - QTimer* _sendTimer { nullptr }; - GetMappingRequest* _assetMappingRequest { nullptr }; AssetRequest* _assetRequest { nullptr }; + + p_high_resolution_clock::time_point _lastProgressDebug; }; #endif diff --git a/libraries/networking/src/ReceivedMessage.cpp b/libraries/networking/src/ReceivedMessage.cpp index e860fa0829..150ae5c91b 100644 --- a/libraries/networking/src/ReceivedMessage.cpp +++ b/libraries/networking/src/ReceivedMessage.cpp @@ -54,7 +54,7 @@ void ReceivedMessage::appendPacket(NLPacket& packet) { "We should not be appending to a complete message"); // Limit progress signal to every X packets - const int EMIT_PROGRESS_EVERY_X_PACKETS = 5; + const int EMIT_PROGRESS_EVERY_X_PACKETS = 50; ++_numPackets; From 7af3aa53acd75f5668fc146db1a4644df51bf1b6 Mon Sep 17 00:00:00 2001 From: samcake Date: Tue, 11 Oct 2016 13:20:32 -0700 Subject: [PATCH 15/20] Fixing the key light pass with ambient map --- libraries/render-utils/src/DeferredLightingEffect.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp index 808d765dd7..574f67eed3 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.cpp +++ b/libraries/render-utils/src/DeferredLightingEffect.cpp @@ -487,10 +487,8 @@ void RenderDeferredSetup::run(const render::SceneContextPointer& sceneContext, c } } else { if (keyLight->getAmbientMap()) { - program = deferredLightingEffect->_directionalAmbientSphereLight; - locations = deferredLightingEffect->_directionalAmbientSphereLightLocations; - //program = deferredLightingEffect->_directionalSkyboxLight; - //locations = deferredLightingEffect->_directionalSkyboxLightLocations; + program = deferredLightingEffect->_directionalSkyboxLight; + locations = deferredLightingEffect->_directionalSkyboxLightLocations; } else { program = deferredLightingEffect->_directionalAmbientSphereLight; locations = deferredLightingEffect->_directionalAmbientSphereLightLocations; From 07d0a038a56450188077874160cba46a163aae90 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 11 Oct 2016 13:21:15 -0700 Subject: [PATCH 16/20] set the initial last progress debug 5s back --- libraries/networking/src/AssetResourceRequest.cpp | 9 ++++++++- libraries/networking/src/AssetResourceRequest.h | 2 +- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/libraries/networking/src/AssetResourceRequest.cpp b/libraries/networking/src/AssetResourceRequest.cpp index 2be4145cd0..f3e5f33507 100644 --- a/libraries/networking/src/AssetResourceRequest.cpp +++ b/libraries/networking/src/AssetResourceRequest.cpp @@ -18,6 +18,14 @@ #include "MappingRequest.h" #include "NetworkLogging.h" +static const int DOWNLOAD_PROGRESS_LOG_INTERVAL_SECONDS = 5; + +AssetResourceRequest::AssetResourceRequest(const QUrl& url) : + ResourceRequest(url) +{ + _lastProgressDebug = p_high_resolution_clock::now() - std::chrono::seconds(DOWNLOAD_PROGRESS_LOG_INTERVAL_SECONDS); +} + AssetResourceRequest::~AssetResourceRequest() { if (_assetMappingRequest) { _assetMappingRequest->deleteLater(); @@ -145,7 +153,6 @@ void AssetResourceRequest::onDownloadProgress(qint64 bytesReceived, qint64 bytes emit progress(bytesReceived, bytesTotal); - static const int DOWNLOAD_PROGRESS_LOG_INTERVAL_SECONDS = 5; auto now = p_high_resolution_clock::now(); // if we haven't received the full asset check if it is time to output progress to log diff --git a/libraries/networking/src/AssetResourceRequest.h b/libraries/networking/src/AssetResourceRequest.h index 93f76cb154..3f110fae17 100644 --- a/libraries/networking/src/AssetResourceRequest.h +++ b/libraries/networking/src/AssetResourceRequest.h @@ -22,7 +22,7 @@ class AssetResourceRequest : public ResourceRequest { Q_OBJECT public: - AssetResourceRequest(const QUrl& url) : ResourceRequest(url) { } + AssetResourceRequest(const QUrl& url); virtual ~AssetResourceRequest() override; protected: From 20ea7e6c987b7466e7d9ce275303b09e22c0eee3 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 11 Oct 2016 13:21:53 -0700 Subject: [PATCH 17/20] change QLoggingCategory include casing --- libraries/networking/src/AssetResourceRequest.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/networking/src/AssetResourceRequest.cpp b/libraries/networking/src/AssetResourceRequest.cpp index f3e5f33507..731803abcd 100644 --- a/libraries/networking/src/AssetResourceRequest.cpp +++ b/libraries/networking/src/AssetResourceRequest.cpp @@ -11,7 +11,7 @@ #include "AssetResourceRequest.h" -#include +#include #include "AssetClient.h" #include "AssetUtils.h" From 504e92607a71736f36edf48b3c3825eb727fbf85 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 11 Oct 2016 13:23:52 -0700 Subject: [PATCH 18/20] change format of debug message --- libraries/networking/src/AssetResourceRequest.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/networking/src/AssetResourceRequest.cpp b/libraries/networking/src/AssetResourceRequest.cpp index 731803abcd..11ced60ec4 100644 --- a/libraries/networking/src/AssetResourceRequest.cpp +++ b/libraries/networking/src/AssetResourceRequest.cpp @@ -164,7 +164,7 @@ void AssetResourceRequest::onDownloadProgress(qint64 bytesReceived, qint64 bytes int percentage = roundf((float) bytesReceived / (float) bytesTotal * 100.0f); qCDebug(networking).nospace() << "Progress for " << _url.path() << " - " - << bytesReceived << " bytes of " << bytesTotal << " - " << percentage << "%"; + << bytesReceived << " of " << bytesTotal << " bytes - " << percentage << "%"; _lastProgressDebug = now; } From f532affdf386e9ecc2f2c2987e300181652560fc Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Tue, 11 Oct 2016 14:39:45 -0700 Subject: [PATCH 19/20] hardwire xbox to match help --- interface/resources/controllers/xbox.json | 37 ++++++++++++++++++----- 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/interface/resources/controllers/xbox.json b/interface/resources/controllers/xbox.json index 1234372a7e..c4b9da9ae2 100644 --- a/interface/resources/controllers/xbox.json +++ b/interface/resources/controllers/xbox.json @@ -1,28 +1,49 @@ { "name": "XBox to Standard", "channels": [ - { "from": "GamePad.LY", "filters": { "type": "deadZone", "min": 0.05 }, "to": "Standard.LY" }, - { "from": "GamePad.LX", "filters": { "type": "deadZone", "min": 0.05 }, "to": "Standard.LX" }, + { "from": "GamePad.LY", "filters": { "type": "deadZone", "min": 0.05 }, "to": "Actions.TranslateZ" }, + { "from": "GamePad.LX", "filters": { "type": "deadZone", "min": 0.05 }, "to": "Actions.TranslateX" }, { "from": "GamePad.LT", "to": "Standard.LT" }, { "from": "GamePad.LB", "to": "Standard.LB" }, { "from": "GamePad.LS", "to": "Standard.LS" }, - { "from": "GamePad.RY", "filters": { "type": "deadZone", "min": 0.05 }, "to": "Standard.RY" }, - { "from": "GamePad.RX", "filters": { "type": "deadZone", "min": 0.05 }, "to": "Standard.RX" }, + + { "from": "GamePad.RX", + "when": [ "Application.InHMD", "Application.SnapTurn" ], + "to": "Actions.StepYaw", + "filters": + [ + { "type": "deadZone", "min": 0.15 }, + "constrainToInteger", + { "type": "pulse", "interval": 0.25 }, + { "type": "scale", "scale": 22.5 } + ] + }, + + { "from": "GamePad.RX", "to": "Actions.Yaw" }, + + { "from": "GamePad.RY", + "to": "Actions.VERTICAL_UP", + "filters": + [ + { "type": "deadZone", "min": 0.95 }, + "invert" + ] + }, + { "from": "GamePad.RT", "to": "Standard.RT" }, { "from": "GamePad.RB", "to": "Standard.RB" }, { "from": "GamePad.RS", "to": "Standard.RS" }, - { "from": "GamePad.Back", "to": "Standard.Back" }, - { "from": "GamePad.Start", "to": "Standard.Start" }, + { "from": "GamePad.Start", "to": "Actions.CycleCamera" }, + { "from": "GamePad.Back", "to": "Actions.ContextMenu" }, - { "from": [ "GamePad.DU", "GamePad.DL", "GamePad.DR", "GamePad.DD" ], "to": "Standard.LeftPrimaryThumb", "peek": true }, { "from": "GamePad.DU", "to": "Standard.DU" }, { "from": "GamePad.DD", "to": "Standard.DD" }, { "from": "GamePad.DL", "to": "Standard.DL" }, { "from": "GamePad.DR", "to": "Standard.DR" }, - { "from": [ "GamePad.A", "GamePad.B", "GamePad.X", "GamePad.Y" ], "to": "Standard.RightPrimaryThumb", "peek": true }, + { "from": [ "GamePad.Y" ], "to": "Standard.RightPrimaryThumb", "peek": true }, { "from": "GamePad.A", "to": "Standard.A" }, { "from": "GamePad.B", "to": "Standard.B" }, { "from": "GamePad.X", "to": "Standard.X" }, From 7ea790aa4fd06237fa0ce09785328dfb2b7f7aa4 Mon Sep 17 00:00:00 2001 From: samcake Date: Tue, 11 Oct 2016 14:43:41 -0700 Subject: [PATCH 20/20] adding a comment to explain what we are doing --- libraries/render-utils/src/DeferredLightingEffect.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp index 574f67eed3..2e169e5cc3 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.cpp +++ b/libraries/render-utils/src/DeferredLightingEffect.cpp @@ -478,6 +478,8 @@ void RenderDeferredSetup::run(const render::SceneContextPointer& sceneContext, c // Setup the global directional pass pipeline { if (deferredLightingEffect->_shadowMapEnabled) { + // If the keylight has an ambient Map then use the Skybox version of the pass + // otherwise use the ambient sphere version if (keyLight->getAmbientMap()) { program = deferredLightingEffect->_directionalSkyboxLightShadow; locations = deferredLightingEffect->_directionalSkyboxLightShadowLocations; @@ -486,6 +488,8 @@ void RenderDeferredSetup::run(const render::SceneContextPointer& sceneContext, c locations = deferredLightingEffect->_directionalAmbientSphereLightShadowLocations; } } else { + // If the keylight has an ambient Map then use the Skybox version of the pass + // otherwise use the ambient sphere version if (keyLight->getAmbientMap()) { program = deferredLightingEffect->_directionalSkyboxLight; locations = deferredLightingEffect->_directionalSkyboxLightLocations;