From 3158439cba430f8662cf45652afbec1b6ed25082 Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Thu, 6 Oct 2016 15:44:24 -0700 Subject: [PATCH 01/20] Prevent deadlock when rapidly switching between openvr and desktop mode --- .../src/display-plugins/hmd/HmdDisplayPlugin.cpp | 1 - libraries/shared/src/LogHandler.h | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp index 86322edded..70535e7a0a 100644 --- a/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp @@ -124,7 +124,6 @@ void HmdDisplayPlugin::uncustomizeContext() { batch.setFramebuffer(_compositeFramebuffer); batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, vec4(0)); }); - internalPresent(); _overlayRenderer = OverlayRenderer(); Parent::uncustomizeContext(); } diff --git a/libraries/shared/src/LogHandler.h b/libraries/shared/src/LogHandler.h index d346913dd3..5eae57c3b6 100644 --- a/libraries/shared/src/LogHandler.h +++ b/libraries/shared/src/LogHandler.h @@ -59,7 +59,7 @@ private: QString _targetName; bool _shouldOutputProcessID { false }; - bool _shouldOutputThreadID { false }; + bool _shouldOutputThreadID { true }; bool _shouldDisplayMilliseconds { false }; QSet _repeatedMessageRegexes; QHash _repeatMessageCountHash; From 4ca0048ec9605fe5df00c2d8c00ba5422126f03d Mon Sep 17 00:00:00 2001 From: David Rowe Date: Fri, 7 Oct 2016 15:21:24 +1300 Subject: [PATCH 02/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 03/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 04/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 05/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 17d00ee3f9c8c7ada3a998b4eb01758248cbf03e Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Fri, 7 Oct 2016 11:41:58 -0700 Subject: [PATCH 06/20] Workaround openvr crash by calling Submit before VR_Shutdown --- plugins/openvr/src/OpenVrHelpers.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/plugins/openvr/src/OpenVrHelpers.cpp b/plugins/openvr/src/OpenVrHelpers.cpp index 820476191a..64bad19e3c 100644 --- a/plugins/openvr/src/OpenVrHelpers.cpp +++ b/plugins/openvr/src/OpenVrHelpers.cpp @@ -103,6 +103,15 @@ void releaseOpenVrSystem() { #if DEV_BUILD qCDebug(displayplugins) << "OpenVR: zero refcount, deallocate VR system"; #endif + + // HACK: workaround openvr crash, call submit right before VR_Shutdown. + const GLuint NON_ZERO_GL_TEXTURE_HANDLE = 1; + vr::Texture_t vrTexture{ (void*)NON_ZERO_GL_TEXTURE_HANDLE, vr::API_OpenGL, vr::ColorSpace_Auto }; + static vr::VRTextureBounds_t OPENVR_TEXTURE_BOUNDS_LEFT{ 0, 0, 0.5f, 1 }; + static vr::VRTextureBounds_t OPENVR_TEXTURE_BOUNDS_RIGHT{ 0.5f, 0, 1, 1 }; + vr::VRCompositor()->Submit(vr::Eye_Left, &vrTexture, &OPENVR_TEXTURE_BOUNDS_LEFT); + vr::VRCompositor()->Submit(vr::Eye_Right, &vrTexture, &OPENVR_TEXTURE_BOUNDS_RIGHT); + vr::VR_Shutdown(); _openVrQuitRequested = false; activeHmd = nullptr; From a4c7e832b5d5fc5d46ddc0d39bd6af31ccdaff5d Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Fri, 7 Oct 2016 11:42:34 -0700 Subject: [PATCH 07/20] Reset threadID logging to false --- libraries/shared/src/LogHandler.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/shared/src/LogHandler.h b/libraries/shared/src/LogHandler.h index 5eae57c3b6..d346913dd3 100644 --- a/libraries/shared/src/LogHandler.h +++ b/libraries/shared/src/LogHandler.h @@ -59,7 +59,7 @@ private: QString _targetName; bool _shouldOutputProcessID { false }; - bool _shouldOutputThreadID { true }; + bool _shouldOutputThreadID { false }; bool _shouldDisplayMilliseconds { false }; QSet _repeatedMessageRegexes; QHash _repeatMessageCountHash; From 8526ac74a51076adda3b4793d39a321bc0e5042d Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Fri, 7 Oct 2016 13:36:49 -0700 Subject: [PATCH 08/20] Turn on forced reprojection on i5 systems --- plugins/openvr/src/OpenVrDisplayPlugin.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/plugins/openvr/src/OpenVrDisplayPlugin.cpp b/plugins/openvr/src/OpenVrDisplayPlugin.cpp index 9247ebea0b..68bb23a84d 100644 --- a/plugins/openvr/src/OpenVrDisplayPlugin.cpp +++ b/plugins/openvr/src/OpenVrDisplayPlugin.cpp @@ -39,6 +39,10 @@ const QString StandingHMDSensorMode = "Standing HMD Sensor Mode"; // this probab PoseData _nextRenderPoseData; PoseData _nextSimPoseData; +#define MIN_CORES_FOR_NORMAL_RENDER 5 +bool forceInterleavedReprojection = (QThread::idealThreadCount() < MIN_CORES_FOR_NORMAL_RENDER); + + static std::array VR_EYES { { vr::Eye_Left, vr::Eye_Right } }; bool _openVrDisplayActive { false }; // Flip y-axis since GL UV coords are backwards. @@ -399,7 +403,10 @@ bool OpenVrDisplayPlugin::internalActivate() { }); // enable async time warp - //vr::VRCompositor()->ForceInterleavedReprojectionOn(true); + if (forceInterleavedReprojection) { + vr::VRCompositor()->ForceInterleavedReprojectionOn(true); + } + // set up default sensor space such that the UI overlay will align with the front of the room. auto chaperone = vr::VRChaperone(); From c5f889a34dae02670edee1d972a178c26ecfe522 Mon Sep 17 00:00:00 2001 From: howard-stearns Date: Fri, 7 Oct 2016 15:13:37 -0700 Subject: [PATCH 09/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 10/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 a934f59c2ab603b9905f7b62314579063876a929 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Sat, 8 Oct 2016 13:37:31 +1300 Subject: [PATCH 11/20] Fix virtual keyboard in login dialog --- .../qml/LoginDialog/LinkAccountBody.qml | 47 +++++++++++++++---- 1 file changed, 39 insertions(+), 8 deletions(-) diff --git a/interface/resources/qml/LoginDialog/LinkAccountBody.qml b/interface/resources/qml/LoginDialog/LinkAccountBody.qml index 137556964f..debd40a67b 100644 --- a/interface/resources/qml/LoginDialog/LinkAccountBody.qml +++ b/interface/resources/qml/LoginDialog/LinkAccountBody.qml @@ -27,6 +27,11 @@ Item { loginDialog.login(usernameField.text, passwordField.text) } + property bool keyboardRaised: false + property bool punctuationMode: false + + onKeyboardRaisedChanged: d.resize(); + QtObject { id: d readonly property int minWidth: 480 @@ -35,13 +40,13 @@ Item { readonly property int maxHeight: 720 function resize() { - var targetWidth = Math.max(titleWidth, form.contentWidth) - var targetHeight = hifi.dimensions.contentSpacing.y + mainTextContainer.height + - 4 * hifi.dimensions.contentSpacing.y + form.height + - 4 * hifi.dimensions.contentSpacing.y + buttons.height + var targetWidth = Math.max(titleWidth, form.contentWidth); + var targetHeight = hifi.dimensions.contentSpacing.y + mainTextContainer.height + + 4 * hifi.dimensions.contentSpacing.y + form.height + hifi.dimensions.contentSpacing.y + buttons.height; - root.width = Math.max(d.minWidth, Math.min(d.maxWidth, targetWidth)) + root.width = Math.max(d.minWidth, Math.min(d.maxWidth, targetWidth)); root.height = Math.max(d.minHeight, Math.min(d.maxHeight, targetHeight)) + + (linkAccountBody.keyboardRaised ? (200 + 2 * hifi.dimensions.contentSpacing.y) : hifi.dimensions.contentSpacing.y); } } @@ -130,13 +135,39 @@ Item { } + // Override ScrollingWindow's keyboard that would be at very bottom of dialog. + Keyboard { + y: parent.keyboardRaised ? parent.height : 0 + height: parent.keyboardRaised ? 200 : 0 + visible: parent.keyboardRaised && !parent.punctuationMode + enabled: parent.keyboardRaised && !parent.punctuationMode + anchors { + left: parent.left + right: parent.right + bottom: buttons.top + bottomMargin: parent.keyboardRaised ? 2 * hifi.dimensions.contentSpacing.y : 0 + } + } + + KeyboardPunctuation { + y: parent.keyboardRaised ? parent.height : 0 + height: parent.keyboardRaised ? 200 : 0 + visible: parent.keyboardRaised && parent.punctuationMode + enabled: parent.keyboardRaised && parent.punctuationMode + anchors { + left: parent.left + right: parent.right + bottom: buttons.top + bottomMargin: parent.keyboardRaised ? 2 * hifi.dimensions.contentSpacing.y : 0 + } + } + Row { id: buttons anchors { - top: form.bottom right: parent.right - margins: 0 - topMargin: 3 * hifi.dimensions.contentSpacing.y + bottom: parent.bottom + bottomMargin: hifi.dimensions.contentSpacing.y } spacing: hifi.dimensions.contentSpacing.x onHeightChanged: d.resize(); onWidthChanged: d.resize(); From ec801cb9d8ba7b692ba00a30ade5e4051f4d2076 Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Fri, 7 Oct 2016 17:46:46 -0700 Subject: [PATCH 12/20] Addressed feedback from code review. --- .../model-networking/src/model-networking/TextureCache.cpp | 4 ++-- plugins/oculus/src/OculusBaseDisplayPlugin.cpp | 5 +++++ plugins/oculus/src/OculusBaseDisplayPlugin.h | 1 + plugins/openvr/src/OpenVrHelpers.cpp | 6 +++--- 4 files changed, 11 insertions(+), 5 deletions(-) diff --git a/libraries/model-networking/src/model-networking/TextureCache.cpp b/libraries/model-networking/src/model-networking/TextureCache.cpp index b4803a7bcd..215263661d 100644 --- a/libraries/model-networking/src/model-networking/TextureCache.cpp +++ b/libraries/model-networking/src/model-networking/TextureCache.cpp @@ -127,7 +127,7 @@ const gpu::TexturePointer& TextureCache::getGrayTexture() { if (!_grayTexture) { _grayTexture = gpu::TexturePointer(gpu::Texture::create2D(gpu::Element::COLOR_RGBA_32, 1, 1)); _grayTexture->setSource("TextureCache::_grayTexture"); - _grayTexture->assignStoredMip(0, _whiteTexture->getTexelFormat(), sizeof(OPAQUE_WHITE), OPAQUE_GRAY); + _grayTexture->assignStoredMip(0, _grayTexture->getTexelFormat(), sizeof(OPAQUE_GRAY), OPAQUE_GRAY); } return _grayTexture; } @@ -145,7 +145,7 @@ const gpu::TexturePointer& TextureCache::getBlackTexture() { if (!_blackTexture) { _blackTexture = gpu::TexturePointer(gpu::Texture::create2D(gpu::Element::COLOR_RGBA_32, 1, 1)); _blackTexture->setSource("TextureCache::_blackTexture"); - _blackTexture->assignStoredMip(0, _whiteTexture->getTexelFormat(), sizeof(OPAQUE_BLACK), OPAQUE_BLACK); + _blackTexture->assignStoredMip(0, _blackTexture->getTexelFormat(), sizeof(OPAQUE_BLACK), OPAQUE_BLACK); } return _blackTexture; } diff --git a/plugins/oculus/src/OculusBaseDisplayPlugin.cpp b/plugins/oculus/src/OculusBaseDisplayPlugin.cpp index 7690736a84..83da154b1f 100644 --- a/plugins/oculus/src/OculusBaseDisplayPlugin.cpp +++ b/plugins/oculus/src/OculusBaseDisplayPlugin.cpp @@ -61,6 +61,11 @@ void OculusBaseDisplayPlugin::customizeContext() { Parent::customizeContext(); } +void OculusBaseDisplayPlugin::uncustomizeContext() { + Parent::uncustomizeContext(); + internalPresent(); +} + bool OculusBaseDisplayPlugin::internalActivate() { _session = acquireOculusSession(); if (!_session) { diff --git a/plugins/oculus/src/OculusBaseDisplayPlugin.h b/plugins/oculus/src/OculusBaseDisplayPlugin.h index 503d8f0b90..25629f004a 100644 --- a/plugins/oculus/src/OculusBaseDisplayPlugin.h +++ b/plugins/oculus/src/OculusBaseDisplayPlugin.h @@ -26,6 +26,7 @@ public: protected: void customizeContext() override; + void uncustomizeContext() override; bool internalActivate() override; void internalDeactivate() override; void updatePresentPose() override; diff --git a/plugins/openvr/src/OpenVrHelpers.cpp b/plugins/openvr/src/OpenVrHelpers.cpp index 64bad19e3c..d22562a659 100644 --- a/plugins/openvr/src/OpenVrHelpers.cpp +++ b/plugins/openvr/src/OpenVrHelpers.cpp @@ -104,9 +104,9 @@ void releaseOpenVrSystem() { qCDebug(displayplugins) << "OpenVR: zero refcount, deallocate VR system"; #endif - // HACK: workaround openvr crash, call submit right before VR_Shutdown. - const GLuint NON_ZERO_GL_TEXTURE_HANDLE = 1; - vr::Texture_t vrTexture{ (void*)NON_ZERO_GL_TEXTURE_HANDLE, vr::API_OpenGL, vr::ColorSpace_Auto }; + // HACK: workaround openvr crash, call submit with an invalid texture, right before VR_Shutdown. + const GLuint INVALID_GL_TEXTURE_HANDLE = -1; + vr::Texture_t vrTexture{ (void*)INVALID_GL_TEXTURE_HANDLE, vr::API_OpenGL, vr::ColorSpace_Auto }; static vr::VRTextureBounds_t OPENVR_TEXTURE_BOUNDS_LEFT{ 0, 0, 0.5f, 1 }; static vr::VRTextureBounds_t OPENVR_TEXTURE_BOUNDS_RIGHT{ 0.5f, 0, 1, 1 }; vr::VRCompositor()->Submit(vr::Eye_Left, &vrTexture, &OPENVR_TEXTURE_BOUNDS_LEFT); From 12f4b2854d10112fe4db48e3e800e6139a130e9b Mon Sep 17 00:00:00 2001 From: David Rowe Date: Sat, 8 Oct 2016 19:38:57 +1300 Subject: [PATCH 13/20] Fix address bar not being able to regain focus --- interface/resources/qml/AddressBarDialog.qml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/interface/resources/qml/AddressBarDialog.qml b/interface/resources/qml/AddressBarDialog.qml index bb44e2c56e..7ed91a2940 100644 --- a/interface/resources/qml/AddressBarDialog.qml +++ b/interface/resources/qml/AddressBarDialog.qml @@ -221,7 +221,7 @@ Window { } } onActiveFocusChanged: { - cursorVisible = isCursorVisible; + cursorVisible = isCursorVisible && focus; } MouseArea { // If user clicks in address bar show cursor to indicate ability to enter address. @@ -229,6 +229,7 @@ Window { onClicked: { isCursorVisible = true; parent.cursorVisible = true; + parent.forceActiveFocus(); } } } From 4ec9299930c18495108da1125d66cdb89ec654ab Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Sat, 8 Oct 2016 14:31:30 -0700 Subject: [PATCH 14/20] fix reticle depth when not moving mouse, but moving head relative to HUD --- scripts/system/controllers/handControllerPointer.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/scripts/system/controllers/handControllerPointer.js b/scripts/system/controllers/handControllerPointer.js index f96e117d26..5bb8ea8a90 100644 --- a/scripts/system/controllers/handControllerPointer.js +++ b/scripts/system/controllers/handControllerPointer.js @@ -308,6 +308,17 @@ function hudReticleDistance() { // 3d distance from camera to the reticle positi var reticlePositionOnHUD = HMD.worldPointFromOverlay(Reticle.position); return Vec3.distance(reticlePositionOnHUD, HMD.position); } + +function maybeAdjustReticleDepth() { + if (HMD.active) { // set depth + if (isPointingAtOverlay()) { + Reticle.depth = hudReticleDistance(); + } + } +} +var ADJUST_RETICLE_DEPTH_INTERVAL = 50; // 20hz +Script.setInterval(maybeAdjustReticleDepth,ADJUST_RETICLE_DEPTH_INTERVAL); + function onMouseMove() { // Display cursor at correct depth (as in depthReticle.js), and updateMouseActivity. if (ignoreMouseActivity()) { From db5edb530a20b5bfb4787d2afd663b1f633a4e1d Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Sun, 9 Oct 2016 15:22:35 -0700 Subject: [PATCH 15/20] fix skybox changing when going between zones --- libraries/entities-renderer/src/EntityTreeRenderer.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index 2ef2beb274..e0fc03897a 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -478,7 +478,8 @@ bool EntityTreeRenderer::applySkyboxAndHasAmbient() { } } - if (_pendingSkyboxTexture && !_skyboxTexture) { + if (_pendingSkyboxTexture && + (!_skyboxTexture || (_skyboxTexture->getURL() != _skyboxTextureURL))) { _skyboxTexture = textureCache->getTexture(_skyboxTextureURL, NetworkTexture::CUBE_TEXTURE); } if (_skyboxTexture && _skyboxTexture->isLoaded()) { From 9712301172a515c196a0eca9c6e0098fdf4c0160 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 10 Oct 2016 11:54:33 -0700 Subject: [PATCH 16/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 1051c068e145272d1612aabd4680d40ff124a96a Mon Sep 17 00:00:00 2001 From: howard-stearns Date: Mon, 10 Oct 2016 13:47:08 -0700 Subject: [PATCH 17/20] kick by hand controller --- scripts/system/mod.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/system/mod.js b/scripts/system/mod.js index 1a7b3b401e..ea9355e376 100644 --- a/scripts/system/mod.js +++ b/scripts/system/mod.js @@ -193,7 +193,7 @@ var triggerMapping = Controller.newMapping(Script.resolvePath('') + '-click'); function controllerComputePickRay(hand) { var controllerPose = getControllerWorldLocation(hand, true); if (controllerPose.valid) { - return { origin: controllerPose.position, direction: controllerPose.orientation }; + return { origin: controllerPose.position, direction: Quat.getUp(controllerPose.orientation) }; } } From e76a7fc577a0478d30cef5feb86464cca2b9aa51 Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Mon, 10 Oct 2016 13:57:54 -0700 Subject: [PATCH 18/20] Crash fix for RenderableWebEntityItem::buildWebSurface Gracefully handle the absence of a gl context. We will continue to retry every render call. --- libraries/entities-renderer/src/RenderableWebEntityItem.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libraries/entities-renderer/src/RenderableWebEntityItem.cpp b/libraries/entities-renderer/src/RenderableWebEntityItem.cpp index 0b36e9db8b..021edde2c2 100644 --- a/libraries/entities-renderer/src/RenderableWebEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableWebEntityItem.cpp @@ -83,6 +83,9 @@ bool RenderableWebEntityItem::buildWebSurface(EntityTreeRenderer* renderer) { ++_currentWebCount; // Save the original GL context, because creating a QML surface will create a new context QOpenGLContext * currentContext = QOpenGLContext::currentContext(); + if (!currentContext) { + return false; + } QSurface * currentSurface = currentContext->surface(); auto deleter = [](OffscreenQmlSurface* webSurface) { From 333ec388a86fe8c6703cd73816ac6c9f657ca919 Mon Sep 17 00:00:00 2001 From: howard-stearns Date: Mon, 10 Oct 2016 14:30:47 -0700 Subject: [PATCH 19/20] make marketplace button state match whether tablet being shown --- scripts/system/marketplaces/marketplace.js | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/scripts/system/marketplaces/marketplace.js b/scripts/system/marketplaces/marketplace.js index 349c3f70e1..563a5289fc 100644 --- a/scripts/system/marketplaces/marketplace.js +++ b/scripts/system/marketplaces/marketplace.js @@ -39,6 +39,7 @@ function shouldShowWebTablet() { function showMarketplace(marketplaceID) { if (shouldShowWebTablet()) { + updateButtonState(true); marketplaceWebTablet = new WebTablet("https://metaverse.highfidelity.com/marketplace"); } else { var url = MARKETPLACE_URL; @@ -58,6 +59,7 @@ function hideMarketplace() { marketplaceWindow.setVisible(false); marketplaceWindow.setURL("about:blank"); } else if (marketplaceWebTablet) { + updateButtonState(false); marketplaceWebTablet.destroy(); marketplaceWebTablet = null; } @@ -83,10 +85,13 @@ var browseExamplesButton = toolBar.addButton({ alpha: 0.9 }); +function updateButtonState(visible) { + browseExamplesButton.writeProperty('buttonState', visible ? 0 : 1); + browseExamplesButton.writeProperty('defaultState', visible ? 0 : 1); + browseExamplesButton.writeProperty('hoverState', visible ? 2 : 3); +} function onMarketplaceWindowVisibilityChanged() { - browseExamplesButton.writeProperty('buttonState', marketplaceWindow.visible ? 0 : 1); - browseExamplesButton.writeProperty('defaultState', marketplaceWindow.visible ? 0 : 1); - browseExamplesButton.writeProperty('hoverState', marketplaceWindow.visible ? 2 : 3); + updateButtonState(marketplaceWindow.visible); marketplaceVisible = marketplaceWindow.visible; } From e9961110e92dba4c1b217aafed5a9688c9351954 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 10 Oct 2016 15:40:59 -0700 Subject: [PATCH 20/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() {