From f9747d8a446e819bbfca457d39e6ae1e695879b3 Mon Sep 17 00:00:00 2001 From: humbletim Date: Tue, 1 Nov 2016 11:46:09 -0400 Subject: [PATCH 01/59] match requested hash key url when populating batch-loaded script contents --- libraries/script-engine/src/BatchLoader.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/libraries/script-engine/src/BatchLoader.cpp b/libraries/script-engine/src/BatchLoader.cpp index 964807894e..43cc4e8e62 100644 --- a/libraries/script-engine/src/BatchLoader.cpp +++ b/libraries/script-engine/src/BatchLoader.cpp @@ -44,7 +44,6 @@ void BatchLoader::start() { return; } - for (const auto& rawURL : _urls) { QUrl url = expandScriptUrl(normalizeScriptURL(rawURL)); @@ -57,12 +56,12 @@ void BatchLoader::start() { // anything. ScriptCacheSignalProxy* proxy = new ScriptCacheSignalProxy(scriptCache.data()); - connect(proxy, &ScriptCacheSignalProxy::contentAvailable, this, [this](const QString& url, const QString& contents, bool isURL, bool success) { + connect(proxy, &ScriptCacheSignalProxy::contentAvailable, this, [this, rawURL](const QString& url, const QString& contents, bool isURL, bool success) { if (isURL && success) { - _data.insert(url, contents); + _data.insert(rawURL, contents); qCDebug(scriptengine) << "Loaded: " << url; } else { - _data.insert(url, QString()); + _data.insert(rawURL, QString()); qCDebug(scriptengine) << "Could not load: " << url; } From 86abd9120ebffdf1f1bd314549e55bd412572bef Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Tue, 1 Nov 2016 22:16:56 +0100 Subject: [PATCH 02/59] Fixed menu out of view with HMD and Xbox controller --- .../controllers/handControllerPointer.js | 44 ++++++++++++++++++- 1 file changed, 42 insertions(+), 2 deletions(-) diff --git a/scripts/system/controllers/handControllerPointer.js b/scripts/system/controllers/handControllerPointer.js index c2deaa2fac..26a8eb5ab8 100644 --- a/scripts/system/controllers/handControllerPointer.js +++ b/scripts/system/controllers/handControllerPointer.js @@ -203,14 +203,41 @@ function overlayFromWorldPoint(point) { return { x: horizontalPixels, y: verticalPixels }; } +function activeHudPoint2dGamePad() { + if(!HMD.active){ + return; + } + var headPosition = MyAvatar.getHeadPosition(); + var headDirection = Quat.getUp(Quat.multiply(MyAvatar.headOrientation, Quat.angleAxis(-90, { x: 1, y: 0, z: 0 }))); + + var hudPoint3d = calculateRayUICollisionPoint(headPosition, headDirection); + + if (!hudPoint3d) { + if (Menu.isOptionChecked("Overlays")) { // With our hud resetting strategy, hudPoint3d should be valid here + print('Controller is parallel to HUD'); // so let us know that our assumptions are wrong. + } + return; + } + var hudPoint2d = overlayFromWorldPoint(hudPoint3d); + + // We don't know yet if we'll want to make the cursor or laser visble, but we need to move it to see if + // it's pointing at a QML tool (aka system overlay). + setReticlePosition(hudPoint2d); + + return hudPoint2d; +} + function activeHudPoint2d(activeHand) { // if controller is valid, update reticle position and answer 2d point. Otherwise falsey. var controllerPose = getControllerWorldLocation(activeHand, true); // note: this will return head pose if hand pose is invalid (third eye) if (!controllerPose.valid) { + if(gamePad){ + return activeHudPoint2dGamePad(); + } return; // Controller is cradled. } var controllerPosition = controllerPose.position; var controllerDirection = Quat.getUp(controllerPose.rotation); - + var hudPoint3d = calculateRayUICollisionPoint(controllerPosition, controllerDirection); if (!hudPoint3d) { if (Menu.isOptionChecked("Overlays")) { // With our hud resetting strategy, hudPoint3d should be valid here @@ -350,6 +377,7 @@ var leftTrigger = new Trigger('left'); var rightTrigger = new Trigger('right'); var activeTrigger = rightTrigger; var activeHand = Controller.Standard.RightHand; +var gamePad = Controller.findDevice("GamePad"); var LEFT_HUD_LASER = 1; var RIGHT_HUD_LASER = 2; var BOTH_HUD_LASERS = LEFT_HUD_LASER + RIGHT_HUD_LASER; @@ -405,7 +433,7 @@ clickMapping.from(rightTrigger.full).when(isPointingAtOverlayStartedNonFullTrigg clickMapping.from(leftTrigger.full).when(isPointingAtOverlayStartedNonFullTrigger(leftTrigger)).to(Controller.Actions.ReticleClick); // The following is essentially like Left and Right versions of // clickMapping.from(Controller.Standard.RightSecondaryThumb).peek().to(Controller.Actions.ContextMenu); -// except that we first update the reticle position from the appropriate hand position, before invoking the ContextMenu. +// except that we first update the reticle position from the appropriate hand position, before invoking the . var wantsMenu = 0; clickMapping.from(function () { return wantsMenu; }).to(Controller.Actions.ContextMenu); clickMapping.from(Controller.Standard.RightSecondaryThumb).peek().to(function (clicked) { @@ -420,6 +448,11 @@ clickMapping.from(Controller.Standard.LeftSecondaryThumb).peek().to(function (cl } wantsMenu = clicked; }); +clickMapping.from(Controller.Hardware.GamePad.Back).peek().to(function () { + Script.setTimeout(function () { + activeHudPoint2dGamePad(); + }, 0); +}); clickMapping.from(Controller.Hardware.Keyboard.RightMouseClicked).peek().to(function () { // Allow the reticle depth to be set correctly: // Wait a tick for the context menu to be displayed, and then simulate a (non-hand-controller) mouse move @@ -472,13 +505,16 @@ function update() { expireMouseCursor(); clearSystemLaser(); } + //print("In updating HandControllerPointer"); updateSeeking(true); if (!handControllerLockOut.expired(now)) { return off(); // Let them use mouse in peace. } + //print("test2"); if (!Menu.isOptionChecked("First Person")) { return off(); // What to do? menus can be behind hand! } + //print("test3"); if ((!Window.hasFocus() && !HMD.active) || !Reticle.allowMouseCapture) { // In desktop it's pretty clear when another app is on top. In that case we bail, because // hand controllers might be sputtering "valid" data and that will keep someone from deliberately @@ -487,14 +523,18 @@ function update() { // other apps anyway. So in that case, we DO keep going even though we're not on top. (Fogbugz 1831.) return off(); // Don't mess with other apps or paused mouse activity } + leftTrigger.update(); rightTrigger.update(); if (!activeTrigger.state) { return off(); // No trigger } + if (getGrabCommunications()) { return off(); } + + var hudPoint2d = activeHudPoint2d(activeHand); if (!hudPoint2d) { return off(); From e9d10b609d3e50b02ab1089577b0887e6647113d Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Wed, 2 Nov 2016 00:05:38 +0100 Subject: [PATCH 03/59] removed bad commit --- scripts/system/controllers/handControllerPointer.js | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/scripts/system/controllers/handControllerPointer.js b/scripts/system/controllers/handControllerPointer.js index 26a8eb5ab8..77cc7603e5 100644 --- a/scripts/system/controllers/handControllerPointer.js +++ b/scripts/system/controllers/handControllerPointer.js @@ -204,7 +204,7 @@ function overlayFromWorldPoint(point) { } function activeHudPoint2dGamePad() { - if(!HMD.active){ + if (!HMD.active) { return; } var headPosition = MyAvatar.getHeadPosition(); @@ -227,6 +227,7 @@ function activeHudPoint2dGamePad() { return hudPoint2d; } +var gamePad = Controller.findDevice("GamePad"); function activeHudPoint2d(activeHand) { // if controller is valid, update reticle position and answer 2d point. Otherwise falsey. var controllerPose = getControllerWorldLocation(activeHand, true); // note: this will return head pose if hand pose is invalid (third eye) if (!controllerPose.valid) { @@ -377,7 +378,6 @@ var leftTrigger = new Trigger('left'); var rightTrigger = new Trigger('right'); var activeTrigger = rightTrigger; var activeHand = Controller.Standard.RightHand; -var gamePad = Controller.findDevice("GamePad"); var LEFT_HUD_LASER = 1; var RIGHT_HUD_LASER = 2; var BOTH_HUD_LASERS = LEFT_HUD_LASER + RIGHT_HUD_LASER; @@ -449,6 +449,8 @@ clickMapping.from(Controller.Standard.LeftSecondaryThumb).peek().to(function (cl wantsMenu = clicked; }); clickMapping.from(Controller.Hardware.GamePad.Back).peek().to(function () { + // Wait a tick an allow the reticle to be correctly set to the players look at position before invoking + // ContextMenu action Script.setTimeout(function () { activeHudPoint2dGamePad(); }, 0); @@ -505,16 +507,16 @@ function update() { expireMouseCursor(); clearSystemLaser(); } - //print("In updating HandControllerPointer"); + updateSeeking(true); if (!handControllerLockOut.expired(now)) { return off(); // Let them use mouse in peace. } - //print("test2"); + if (!Menu.isOptionChecked("First Person")) { return off(); // What to do? menus can be behind hand! } - //print("test3"); + if ((!Window.hasFocus() && !HMD.active) || !Reticle.allowMouseCapture) { // In desktop it's pretty clear when another app is on top. In that case we bail, because // hand controllers might be sputtering "valid" data and that will keep someone from deliberately From d29b1c34b1cc564a0670cbe2d6035f8aa962111b Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Wed, 2 Nov 2016 00:07:58 +0100 Subject: [PATCH 04/59] fixed coding standard conflicts --- scripts/system/controllers/handControllerPointer.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/system/controllers/handControllerPointer.js b/scripts/system/controllers/handControllerPointer.js index 77cc7603e5..0ad297ccd3 100644 --- a/scripts/system/controllers/handControllerPointer.js +++ b/scripts/system/controllers/handControllerPointer.js @@ -231,7 +231,7 @@ var gamePad = Controller.findDevice("GamePad"); function activeHudPoint2d(activeHand) { // if controller is valid, update reticle position and answer 2d point. Otherwise falsey. var controllerPose = getControllerWorldLocation(activeHand, true); // note: this will return head pose if hand pose is invalid (third eye) if (!controllerPose.valid) { - if(gamePad){ + if (gamePad) { return activeHudPoint2dGamePad(); } return; // Controller is cradled. @@ -458,7 +458,7 @@ clickMapping.from(Controller.Hardware.GamePad.Back).peek().to(function () { clickMapping.from(Controller.Hardware.Keyboard.RightMouseClicked).peek().to(function () { // Allow the reticle depth to be set correctly: // Wait a tick for the context menu to be displayed, and then simulate a (non-hand-controller) mouse move - // so that the system updates qml state (Reticle.pointingAtSystemOverlay) before it gives us a mouseMove. + // so that the system updates qml state (Reticle.pointingAtSystemverlay) before it gives us a mouseMove. // We don't want the system code to always do this for us, because, e.g., we do not want to get a mouseMove // after the Left/RightSecondaryThumb gives us a context menu. Only from the mouse. Script.setTimeout(function () { From 1a83cc2c3e0dc2c4691319ec2d36c561d87a6cf7 Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Wed, 2 Nov 2016 00:12:23 +0100 Subject: [PATCH 05/59] fixed deleted comment --- scripts/system/controllers/handControllerPointer.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/system/controllers/handControllerPointer.js b/scripts/system/controllers/handControllerPointer.js index 0ad297ccd3..82344426cb 100644 --- a/scripts/system/controllers/handControllerPointer.js +++ b/scripts/system/controllers/handControllerPointer.js @@ -458,7 +458,7 @@ clickMapping.from(Controller.Hardware.GamePad.Back).peek().to(function () { clickMapping.from(Controller.Hardware.Keyboard.RightMouseClicked).peek().to(function () { // Allow the reticle depth to be set correctly: // Wait a tick for the context menu to be displayed, and then simulate a (non-hand-controller) mouse move - // so that the system updates qml state (Reticle.pointingAtSystemverlay) before it gives us a mouseMove. + // so that the system updates qml state (Reticle.pointingAtSystemOverlay) before it gives us a mouseMove. // We don't want the system code to always do this for us, because, e.g., we do not want to get a mouseMove // after the Left/RightSecondaryThumb gives us a context menu. Only from the mouse. Script.setTimeout(function () { From d749f243c669f9a3f5f1c36c42bb552b528f5975 Mon Sep 17 00:00:00 2001 From: humbletim Date: Wed, 2 Nov 2016 14:58:50 -0400 Subject: [PATCH 06/59] revert f9747d8a (rawURL) + apply alternative approach for aligning batch-loaded script URLs --- libraries/script-engine/src/BatchLoader.cpp | 7 ++++--- libraries/script-engine/src/ScriptEngine.cpp | 2 ++ 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/libraries/script-engine/src/BatchLoader.cpp b/libraries/script-engine/src/BatchLoader.cpp index 43cc4e8e62..964807894e 100644 --- a/libraries/script-engine/src/BatchLoader.cpp +++ b/libraries/script-engine/src/BatchLoader.cpp @@ -44,6 +44,7 @@ void BatchLoader::start() { return; } + for (const auto& rawURL : _urls) { QUrl url = expandScriptUrl(normalizeScriptURL(rawURL)); @@ -56,12 +57,12 @@ void BatchLoader::start() { // anything. ScriptCacheSignalProxy* proxy = new ScriptCacheSignalProxy(scriptCache.data()); - connect(proxy, &ScriptCacheSignalProxy::contentAvailable, this, [this, rawURL](const QString& url, const QString& contents, bool isURL, bool success) { + connect(proxy, &ScriptCacheSignalProxy::contentAvailable, this, [this](const QString& url, const QString& contents, bool isURL, bool success) { if (isURL && success) { - _data.insert(rawURL, contents); + _data.insert(url, contents); qCDebug(scriptengine) << "Loaded: " << url; } else { - _data.insert(rawURL, QString()); + _data.insert(url, QString()); qCDebug(scriptengine) << "Could not load: " << url; } diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index 776c7cfec6..d3b5f6576c 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -1187,6 +1187,8 @@ void ScriptEngine::include(const QStringList& includeFiles, QScriptValue callbac thisURL = resolvePath(file); } + thisURL = expandScriptUrl(normalizeScriptURL(ResourceManager::normalizeURL(thisURL))); + if (!_includedURLs.contains(thisURL)) { if (!isStandardLibrary && !currentSandboxURL.isEmpty() && (thisURL.scheme() == "file") && (currentSandboxURL.scheme() != "file" || From 620fd3713c367e6a7efcf9342744823c4aef88a6 Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Fri, 4 Nov 2016 17:09:25 -0700 Subject: [PATCH 07/59] Add color support to debug draw marker rendering --- libraries/render-utils/src/AnimDebugDraw.cpp | 29 ++++++++++---------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/libraries/render-utils/src/AnimDebugDraw.cpp b/libraries/render-utils/src/AnimDebugDraw.cpp index 80ba9cd1b2..bb0d5dbfab 100644 --- a/libraries/render-utils/src/AnimDebugDraw.cpp +++ b/libraries/render-utils/src/AnimDebugDraw.cpp @@ -121,7 +121,7 @@ AnimDebugDraw::AnimDebugDraw() : // HACK: add red, green and blue axis at (1,1,1) _animDebugDrawData->_vertexBuffer->resize(sizeof(AnimDebugDrawData::Vertex) * 6); - + static std::vector vertices({ AnimDebugDrawData::Vertex { glm::vec3(1.0, 1.0f, 1.0f), toRGBA(255, 0, 0, 255) }, AnimDebugDrawData::Vertex { glm::vec3(2.0, 1.0f, 1.0f), toRGBA(255, 0, 0, 255) }, @@ -162,9 +162,10 @@ static const uint32_t blue = toRGBA(0, 0, 255, 255); const int NUM_CIRCLE_SLICES = 24; -static void addBone(const AnimPose& rootPose, const AnimPose& pose, float radius, AnimDebugDrawData::Vertex*& v) { +static void addBone(const AnimPose& rootPose, const AnimPose& pose, float radius, glm::vec4& vecColor, AnimDebugDrawData::Vertex*& v) { const float XYZ_AXIS_LENGTH = radius * 4.0f; + const uint32_t color = toRGBA(vecColor); AnimPose finalPose = rootPose * pose; glm::vec3 base = rootPose * pose.trans; @@ -192,10 +193,10 @@ static void addBone(const AnimPose& rootPose, const AnimPose& pose, float radius // x-ring for (int i = 0; i < NUM_CIRCLE_SLICES; i++) { v->pos = xRing[i]; - v->rgba = red; + v->rgba = color; v++; v->pos = xRing[i + 1]; - v->rgba = red; + v->rgba = color; v++; } @@ -210,10 +211,10 @@ static void addBone(const AnimPose& rootPose, const AnimPose& pose, float radius // y-ring for (int i = 0; i < NUM_CIRCLE_SLICES; i++) { v->pos = yRing[i]; - v->rgba = green; + v->rgba = color; v++; v->pos = yRing[i + 1]; - v->rgba = green; + v->rgba = color; v++; } @@ -228,10 +229,10 @@ static void addBone(const AnimPose& rootPose, const AnimPose& pose, float radius // z-ring for (int i = 0; i < NUM_CIRCLE_SLICES; i++) { v->pos = zRing[i]; - v->rgba = blue; + v->rgba = color; v++; v->pos = zRing[i + 1]; - v->rgba = blue; + v->rgba = color; v++; } } @@ -367,7 +368,7 @@ void AnimDebugDraw::update() { const float radius = BONE_RADIUS / (absPoses[i].scale.x * rootPose.scale.x); // draw bone - addBone(rootPose, absPoses[i], radius, v); + addBone(rootPose, absPoses[i], radius, color, v); // draw link to parent auto parentIndex = skeleton->getParentIndex(i); @@ -382,20 +383,18 @@ void AnimDebugDraw::update() { for (auto& iter : markerMap) { glm::quat rot = std::get<0>(iter.second); glm::vec3 pos = std::get<1>(iter.second); - glm::vec4 color = std::get<2>(iter.second); // TODO: currently ignored. - Q_UNUSED(color); + glm::vec4 color = std::get<2>(iter.second); const float radius = POSE_RADIUS; - addBone(AnimPose::identity, AnimPose(glm::vec3(1), rot, pos), radius, v); + addBone(AnimPose::identity, AnimPose(glm::vec3(1), rot, pos), radius, color, v); } AnimPose myAvatarPose(glm::vec3(1), DebugDraw::getInstance().getMyAvatarRot(), DebugDraw::getInstance().getMyAvatarPos()); for (auto& iter : myAvatarMarkerMap) { glm::quat rot = std::get<0>(iter.second); glm::vec3 pos = std::get<1>(iter.second); - glm::vec4 color = std::get<2>(iter.second); // TODO: currently ignored. - Q_UNUSED(color); + glm::vec4 color = std::get<2>(iter.second); const float radius = POSE_RADIUS; - addBone(myAvatarPose, AnimPose(glm::vec3(1), rot, pos), radius, v); + addBone(myAvatarPose, AnimPose(glm::vec3(1), rot, pos), radius, color, v); } // draw rays from shared DebugDraw singleton From 28eadc149f791a7d8a2de676a874a561003a3246 Mon Sep 17 00:00:00 2001 From: humbletim Date: Sun, 6 Nov 2016 16:08:42 -0500 Subject: [PATCH 08/59] switch to apply normalizeURL only and move to top of for loop --- libraries/script-engine/src/ScriptEngine.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index d3b5f6576c..0becf6a8dd 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -1172,7 +1172,8 @@ void ScriptEngine::include(const QStringList& includeFiles, QScriptValue callbac // Guard against meaningless query and fragment parts. // Do NOT use PreferLocalFile as its behavior is unpredictable (e.g., on defaultScriptsLocation()) const auto strippingFlags = QUrl::RemoveFilename | QUrl::RemoveQuery | QUrl::RemoveFragment; - for (QString file : includeFiles) { + for (QString includeFile : includeFiles) { + QString file = ResourceManager::normalizeURL(includeFile); QUrl thisURL; bool isStandardLibrary = false; if (file.startsWith("/~/")) { @@ -1187,8 +1188,6 @@ void ScriptEngine::include(const QStringList& includeFiles, QScriptValue callbac thisURL = resolvePath(file); } - thisURL = expandScriptUrl(normalizeScriptURL(ResourceManager::normalizeURL(thisURL))); - if (!_includedURLs.contains(thisURL)) { if (!isStandardLibrary && !currentSandboxURL.isEmpty() && (thisURL.scheme() == "file") && (currentSandboxURL.scheme() != "file" || From e22c36b4b7800eae88cf7b081be0d673f1931a7c Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Mon, 7 Nov 2016 17:16:24 +0000 Subject: [PATCH 09/59] fixed menu pop up delay --- interface/resources/controllers/xbox.json | 30 +++++++++---------- .../controllers/handControllerPointer.js | 18 +++++------ 2 files changed, 23 insertions(+), 25 deletions(-) diff --git a/interface/resources/controllers/xbox.json b/interface/resources/controllers/xbox.json index b0e97b849f..36065b87a1 100644 --- a/interface/resources/controllers/xbox.json +++ b/interface/resources/controllers/xbox.json @@ -4,12 +4,12 @@ { "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.LTClick", + { "from": "GamePad.LT", "to": "Standard.LTClick", "peek": true, "filters": [ { "type": "hysteresis", "min": 0.85, "max": 0.9 } ] }, - { "from": "GamePad.LT", "to": "Standard.LT" }, - { "from": "GamePad.LB", "to": "Standard.LB" }, + { "from": "GamePad.LT", "to": "Standard.LT" }, + { "from": "GamePad.LB", "to": "Standard.LB" }, { "from": "GamePad.LS", "to": "Standard.LS" }, @@ -27,34 +27,34 @@ { "from": "GamePad.RX", "to": "Actions.Yaw" }, - { "from": "GamePad.RY", - "to": "Actions.VERTICAL_UP", - "filters": + { "from": "GamePad.RY", + "to": "Actions.VERTICAL_UP", + "filters": [ { "type": "deadZone", "min": 0.95 }, "invert" ] - }, + }, - { "from": "GamePad.RT", "to": "Standard.RTClick", + { "from": "GamePad.RT", "to": "Standard.RTClick", "peek": true, "filters": [ { "type": "hysteresis", "min": 0.85, "max": 0.9 } ] }, - { "from": "GamePad.RT", "to": "Standard.RT" }, - { "from": "GamePad.RB", "to": "Standard.RB" }, + { "from": "GamePad.RT", "to": "Standard.RT" }, + { "from": "GamePad.RB", "to": "Standard.RB" }, { "from": "GamePad.RS", "to": "Standard.RS" }, { "from": "GamePad.Start", "to": "Actions.CycleCamera" }, - { "from": "GamePad.Back", "to": "Actions.ContextMenu" }, + { "from": "GamePad.Back", "to": "Standard.Start" }, { "from": "GamePad.DU", "to": "Standard.DU" }, - { "from": "GamePad.DD", "to": "Standard.DD" }, + { "from": "GamePad.DD", "to": "Standard.DD" }, { "from": "GamePad.DL", "to": "Standard.DL" }, - { "from": "GamePad.DR", "to": "Standard.DR" }, + { "from": "GamePad.DR", "to": "Standard.DR" }, { "from": [ "GamePad.Y" ], "to": "Standard.RightPrimaryThumb", "peek": true }, - { "from": "GamePad.A", "to": "Standard.A" }, - { "from": "GamePad.B", "to": "Standard.B" }, + { "from": "GamePad.A", "to": "Standard.A" }, + { "from": "GamePad.B", "to": "Standard.B" }, { "from": "GamePad.X", "to": "Standard.X" }, { "from": "GamePad.Y", "to": "Standard.Y" } ] diff --git a/scripts/system/controllers/handControllerPointer.js b/scripts/system/controllers/handControllerPointer.js index 82344426cb..ce9b8e403f 100644 --- a/scripts/system/controllers/handControllerPointer.js +++ b/scripts/system/controllers/handControllerPointer.js @@ -203,6 +203,7 @@ function overlayFromWorldPoint(point) { return { x: horizontalPixels, y: verticalPixels }; } +var gamePad = Controller.findDevice("GamePad"); function activeHudPoint2dGamePad() { if (!HMD.active) { return; @@ -227,13 +228,10 @@ function activeHudPoint2dGamePad() { return hudPoint2d; } -var gamePad = Controller.findDevice("GamePad"); + function activeHudPoint2d(activeHand) { // if controller is valid, update reticle position and answer 2d point. Otherwise falsey. var controllerPose = getControllerWorldLocation(activeHand, true); // note: this will return head pose if hand pose is invalid (third eye) if (!controllerPose.valid) { - if (gamePad) { - return activeHudPoint2dGamePad(); - } return; // Controller is cradled. } var controllerPosition = controllerPose.position; @@ -448,12 +446,12 @@ clickMapping.from(Controller.Standard.LeftSecondaryThumb).peek().to(function (cl } wantsMenu = clicked; }); -clickMapping.from(Controller.Hardware.GamePad.Back).peek().to(function () { - // Wait a tick an allow the reticle to be correctly set to the players look at position before invoking - // ContextMenu action - Script.setTimeout(function () { - activeHudPoint2dGamePad(); - }, 0); +clickMapping.from(Controller.Standard.Start).peek().to(function (clicked) { + if (clicked) { + activeHudPoint2dGamePad(); + } + + wantsMenu = clicked; }); clickMapping.from(Controller.Hardware.Keyboard.RightMouseClicked).peek().to(function () { // Allow the reticle depth to be set correctly: From 563322d08d2aeaea69c9ee886876230ace733fa9 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 10 Nov 2016 10:02:31 -0800 Subject: [PATCH 10/59] add min and max avatar scale to domain-server settings --- .../resources/describe-settings.json | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/domain-server/resources/describe-settings.json b/domain-server/resources/describe-settings.json index e6663888b4..6c4ab9fd77 100644 --- a/domain-server/resources/describe-settings.json +++ b/domain-server/resources/describe-settings.json @@ -866,6 +866,28 @@ } ] }, + { + "name": "avatars", + "label": "Avatars", + "settings": [ + { + "name": "min_avatar_scale", + "type": "double", + "label": "Minimum Avatar Scale (meters)", + "help": "Limits the scale of avatars in your domain", + "placeholder": 0.01, + "default": 0.01 + }, + { + "name": "max_avatar_scale", + "type": "double", + "label": "Maximum Avatar Scale (meters)", + "help": "Limits the scale of avatars in your domain", + "placeholder": 4.0, + "default": 4.0 + } + ] + }, { "name": "audio_env", "label": "Audio Environment", From e2991c366529022c1a5fee098caeaf74db240b50 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Thu, 10 Nov 2016 10:35:05 -0800 Subject: [PATCH 11/59] Change minimum cores to 3 to enable OpenVR --- plugins/openvr/src/OpenVrHelpers.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/openvr/src/OpenVrHelpers.cpp b/plugins/openvr/src/OpenVrHelpers.cpp index 2803ca424e..0c3a2faed6 100644 --- a/plugins/openvr/src/OpenVrHelpers.cpp +++ b/plugins/openvr/src/OpenVrHelpers.cpp @@ -331,7 +331,7 @@ controller::Pose openVrControllerPoseToHandPose(bool isLeftHand, const mat4& mat #define FAILED_MIN_SPEC_OVERLAY_FRIENDLY_NAME "Minimum specifications for SteamVR not met" #define FAILED_MIN_SPEC_UPDATE_INTERVAL_MS 10 #define FAILED_MIN_SPEC_AUTO_QUIT_INTERVAL_MS (MSECS_PER_SECOND * 30) -#define MIN_CORES_SPEC 5 +#define MIN_CORES_SPEC 3 void showMinSpecWarning() { auto vrSystem = acquireOpenVrSystem(); From 90f55f0cd5d68060b5e81d19dc996b8a7b0442fc Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Tue, 8 Nov 2016 09:13:53 -0800 Subject: [PATCH 12/59] Add stutter tracking --- interface/resources/qml/Stats.qml | 4 ++++ interface/src/ui/Stats.cpp | 3 ++- interface/src/ui/Stats.h | 5 ++++- libraries/plugins/src/plugins/DisplayPlugin.h | 2 ++ plugins/openvr/src/OpenVrDisplayPlugin.cpp | 10 ++++++++++ plugins/openvr/src/OpenVrDisplayPlugin.h | 3 +++ 6 files changed, 25 insertions(+), 2 deletions(-) diff --git a/interface/resources/qml/Stats.qml b/interface/resources/qml/Stats.qml index 9c55b1ce2d..cb7186456f 100644 --- a/interface/resources/qml/Stats.qml +++ b/interface/resources/qml/Stats.qml @@ -69,6 +69,10 @@ Item { StatText { text: "Present Drop Rate: " + root.presentdroprate.toFixed(2); } + StatText { + text: "Stutter Rate: " + root.stutterrate.toFixed(3); + visible: root.stutterrate != -1; + } StatText { text: "Simrate: " + root.simrate } diff --git a/interface/src/ui/Stats.cpp b/interface/src/ui/Stats.cpp index edf72d9758..bad2c3c056 100644 --- a/interface/src/ui/Stats.cpp +++ b/interface/src/ui/Stats.cpp @@ -128,7 +128,8 @@ void Stats::updateStats(bool force) { STAT_UPDATE(renderrate, displayPlugin->renderRate()); STAT_UPDATE(presentrate, displayPlugin->presentRate()); STAT_UPDATE(presentnewrate, displayPlugin->newFramePresentRate()); - STAT_UPDATE(presentdroprate, qApp->getActiveDisplayPlugin()->droppedFrameRate()); + STAT_UPDATE(presentdroprate, displayPlugin->droppedFrameRate()); + STAT_UPDATE(stutterrate, displayPlugin->stutterRate()); } else { STAT_UPDATE(presentrate, -1); STAT_UPDATE(presentnewrate, -1); diff --git a/interface/src/ui/Stats.h b/interface/src/ui/Stats.h index ffa5c08bc6..5d1aac4287 100644 --- a/interface/src/ui/Stats.h +++ b/interface/src/ui/Stats.h @@ -36,7 +36,9 @@ class Stats : public QQuickItem { STATS_PROPERTY(float, renderrate, 0) // How often the display plugin is presenting to the device STATS_PROPERTY(float, presentrate, 0) - + // How often the display device reprojecting old frames + STATS_PROPERTY(float, stutterrate, 0) + STATS_PROPERTY(float, presentnewrate, 0) STATS_PROPERTY(float, presentdroprate, 0) STATS_PROPERTY(int, simrate, 0) @@ -140,6 +142,7 @@ signals: void presentrateChanged(); void presentnewrateChanged(); void presentdroprateChanged(); + void stutterrateChanged(); void simrateChanged(); void avatarSimrateChanged(); void avatarCountChanged(); diff --git a/libraries/plugins/src/plugins/DisplayPlugin.h b/libraries/plugins/src/plugins/DisplayPlugin.h index 3a9107390a..c87669c99a 100644 --- a/libraries/plugins/src/plugins/DisplayPlugin.h +++ b/libraries/plugins/src/plugins/DisplayPlugin.h @@ -188,6 +188,8 @@ public: virtual float renderRate() const { return -1.0f; } // Rate at which we present to the display device virtual float presentRate() const { return -1.0f; } + // Rate at which old frames are presented to the device display + virtual float stutterRate() const { return -1.0f; } // Rate at which new frames are being presented to the display device virtual float newFramePresentRate() const { return -1.0f; } // Rate at which rendered frames are being skipped diff --git a/plugins/openvr/src/OpenVrDisplayPlugin.cpp b/plugins/openvr/src/OpenVrDisplayPlugin.cpp index 1a4067a847..e300ad3ece 100644 --- a/plugins/openvr/src/OpenVrDisplayPlugin.cpp +++ b/plugins/openvr/src/OpenVrDisplayPlugin.cpp @@ -641,6 +641,12 @@ void OpenVrDisplayPlugin::hmdPresent() { vr::VRCompositor()->PostPresentHandoff(); _presentRate.increment(); } + + vr::Compositor_FrameTiming frameTiming; + memset(&frameTiming, 0, sizeof(vr::Compositor_FrameTiming)); + frameTiming.m_nSize = sizeof(vr::Compositor_FrameTiming); + vr::VRCompositor()->GetFrameTiming(&frameTiming); + _stutterRate.increment(frameTiming.m_nNumDroppedFrames); } void OpenVrDisplayPlugin::postPreview() { @@ -702,3 +708,7 @@ bool OpenVrDisplayPlugin::isKeyboardVisible() { int OpenVrDisplayPlugin::getRequiredThreadCount() const { return Parent::getRequiredThreadCount() + (_threadedSubmit ? 1 : 0); } + +float OpenVrDisplayPlugin::stutterRate() const { + return _stutterRate.rate(); +} diff --git a/plugins/openvr/src/OpenVrDisplayPlugin.h b/plugins/openvr/src/OpenVrDisplayPlugin.h index 3403bae27c..0f4c5a6320 100644 --- a/plugins/openvr/src/OpenVrDisplayPlugin.h +++ b/plugins/openvr/src/OpenVrDisplayPlugin.h @@ -58,6 +58,8 @@ public: // Possibly needs an additional thread for VR submission int getRequiredThreadCount() const override; + float stutterRate() const override; + protected: bool internalActivate() override; void internalDeactivate() override; @@ -77,6 +79,7 @@ private: vr::HmdMatrix34_t _lastGoodHMDPose; mat4 _sensorResetMat; bool _threadedSubmit { true }; + RateCounter<> _stutterRate; CompositeInfo::Array _compositeInfos; size_t _renderingIndex { 0 }; From c7d68aa9cf16a3e5433246858267ca5cb48ed21d Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Thu, 10 Nov 2016 12:10:01 -0800 Subject: [PATCH 13/59] Add stutter stat logging --- interface/src/Application.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index cc81396d84..089983d8ca 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1197,6 +1197,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo properties["present_rate"] = displayPlugin->presentRate(); properties["new_frame_present_rate"] = displayPlugin->newFramePresentRate(); properties["dropped_frame_rate"] = displayPlugin->droppedFrameRate(); + properties["stutter_rate"] = displayPlugin->stutterRate(); properties["sim_rate"] = getAverageSimsPerSecond(); properties["avatar_sim_rate"] = getAvatarSimrate(); properties["has_async_reprojection"] = displayPlugin->hasAsyncReprojection(); From 77ede81fc906adb51abe68a9ef77c37a36a60520 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 10 Nov 2016 13:27:13 -0800 Subject: [PATCH 14/59] limit MyAvatar scale to limits from domain settings --- .../src/avatars/ScriptableAvatar.h | 4 +- .../resources/describe-settings.json | 12 +-- interface/src/avatar/MyAvatar.cpp | 78 +++++++++++++++++-- interface/src/avatar/MyAvatar.h | 3 + libraries/avatars/src/AvatarData.cpp | 8 +- libraries/avatars/src/AvatarData.h | 6 ++ 6 files changed, 92 insertions(+), 19 deletions(-) diff --git a/assignment-client/src/avatars/ScriptableAvatar.h b/assignment-client/src/avatars/ScriptableAvatar.h index 56707de471..18d64f4ac5 100644 --- a/assignment-client/src/avatars/ScriptableAvatar.h +++ b/assignment-client/src/avatars/ScriptableAvatar.h @@ -17,7 +17,7 @@ #include #include -class ScriptableAvatar : public AvatarData, public Dependency{ +class ScriptableAvatar : public AvatarData, public Dependency { Q_OBJECT public: @@ -39,4 +39,4 @@ private: std::shared_ptr _animSkeleton; }; -#endif // hifi_ScriptableAvatar_h \ No newline at end of file +#endif // hifi_ScriptableAvatar_h diff --git a/domain-server/resources/describe-settings.json b/domain-server/resources/describe-settings.json index 6c4ab9fd77..b5c612881f 100644 --- a/domain-server/resources/describe-settings.json +++ b/domain-server/resources/describe-settings.json @@ -874,17 +874,17 @@ "name": "min_avatar_scale", "type": "double", "label": "Minimum Avatar Scale (meters)", - "help": "Limits the scale of avatars in your domain", - "placeholder": 0.01, - "default": 0.01 + "help": "Limits the scale of avatars in your domain. Must be at least than 0.005.", + "placeholder": 0.25, + "default": 0.25 }, { "name": "max_avatar_scale", "type": "double", "label": "Maximum Avatar Scale (meters)", - "help": "Limits the scale of avatars in your domain", - "placeholder": 4.0, - "default": 4.0 + "help": "Limits the scale of avatars in your domain. Cannot be greater than 1000.", + "placeholder": 3.0, + "default": 3.0 } ] }, diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 735ba05810..e1f0bd3a68 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -130,6 +130,15 @@ MyAvatar::MyAvatar(RigPointer rig) : connect(DependencyManager::get().data(), &AddressManager::locationChangeRequired, this, static_cast(&MyAvatar::goToLocation)); + // handle scale constraints imposed on us by the domain-server + auto& domainHandler = DependencyManager::get()->getDomainHandler(); + + // when we connect to a domain and retrieve its settings, we restrict our max/min scale based on those settings + connect(&domainHandler, &DomainHandler::settingsReceived, this, &MyAvatar::restrictScaleFromDomainSettings); + + // when we leave a domain we lift whatever restrictions that domain may have placed on our scale + connect(&domainHandler, &DomainHandler::disconnectedFromDomain, this, &MyAvatar::clearScaleRestriction); + _characterController.setEnabled(true); _bodySensorMatrix = deriveBodyFromHMDSensor(); @@ -1824,24 +1833,79 @@ bool findAvatarAvatarPenetration(const glm::vec3 positionA, float radiusA, float } void MyAvatar::increaseSize() { - if ((1.0f + SCALING_RATIO) * _targetScale < MAX_AVATAR_SCALE) { - _targetScale *= (1.0f + SCALING_RATIO); - qCDebug(interfaceapp, "Changed scale to %f", (double)_targetScale); + // clamp the target scale to the maximum allowable scale in the domain + + float updatedTargetScale = _targetScale * (1.0f + SCALING_RATIO); + + if (updatedTargetScale > _domainMaximumScale) { + qCDebug(interfaceapp, "Forced scale to %f since %f would be larger than allowed maximum", + _domainMaximumScale, updatedTargetScale); + + updatedTargetScale = _domainMaximumScale; } + + setTargetScale(updatedTargetScale); + qCDebug(interfaceapp, "Changed scale to %f", (double)_targetScale); } void MyAvatar::decreaseSize() { - if (MIN_AVATAR_SCALE < (1.0f - SCALING_RATIO) * _targetScale) { - _targetScale *= (1.0f - SCALING_RATIO); - qCDebug(interfaceapp, "Changed scale to %f", (double)_targetScale); + // clamp the target scale to the minimum allowable scale in the domain + float updatedTargetScale = _targetScale * (1.0f - SCALING_RATIO); + + if (updatedTargetScale < _domainMinimumScale) { + qCDebug(interfaceapp, "Forced scale to %f since %f would be smaller than allowed minimum", + _domainMinimumScale, updatedTargetScale); + + updatedTargetScale = _domainMinimumScale; } + + + setTargetScale(updatedTargetScale); + qCDebug(interfaceapp, "Changed scale to %f", (double)_targetScale); } void MyAvatar::resetSize() { - _targetScale = 1.0f; + // if the default + const float DEFAULT_AVATAR_SCALE = 1.0f; + + float allowedDefaultScale = glm::clamp(DEFAULT_AVATAR_SCALE, _domainMinimumScale, _domainMaximumScale); + + if (allowedDefaultScale != DEFAULT_AVATAR_SCALE) { + qCDebug(interfaceapp, "Forcing scale to %f since %f is not an allowed avatar scale by the domain", + allowedDefaultScale, DEFAULT_AVATAR_SCALE); + } + + setTargetScale(allowedDefaultScale); qCDebug(interfaceapp, "Reset scale to %f", (double)_targetScale); } +void MyAvatar::restrictScaleFromDomainSettings(const QJsonObject& domainSettingsObject) { + // pull out the minimum and maximum scale and set them to restrict our scale + + static const QString AVATAR_SETTINGS_KEY = "avatars"; + auto avatarsObject = domainSettingsObject[AVATAR_SETTINGS_KEY].toObject(); + + static const QString MIN_SCALE_OPTION = "min_avatar_scale"; + float settingMinScale = avatarsObject[MIN_SCALE_OPTION].toDouble(MIN_AVATAR_SCALE); + setDomainMinimumScale(settingMinScale); + + static const QString MAX_SCALE_OPTION = "max_avatar_scale"; + float settingMaxScale = avatarsObject[MAX_SCALE_OPTION].toDouble(MAX_AVATAR_SCALE); + setDomainMaximumScale(settingMaxScale); + + // debug to log if this avatar's scale in this domain will be clamped + auto clampedScale = glm::clamp(_targetScale, _domainMinimumScale, _domainMaximumScale); + + if (_targetScale != clampedScale) { + qCDebug(interfaceapp, "Avatar scale will be clamped to %f because %f is not allowed by current domain", + clampedScale, _targetScale); + } +} + +void MyAvatar::clearScaleRestriction() { + _domainMinimumScale = MIN_AVATAR_SCALE; + _domainMaximumScale = MAX_AVATAR_SCALE; +} void MyAvatar::goToLocation(const QVariant& propertiesVar) { qCDebug(interfaceapp, "MyAvatar QML goToLocation"); diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index 71f185c6ed..d9c88621d2 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -292,6 +292,9 @@ public slots: bool shouldFaceLocation = false); void goToLocation(const QVariant& properties); + void restrictScaleFromDomainSettings(const QJsonObject& domainSettingsObject); + void clearScaleRestriction(); + // Set/Get update the thrust that will move the avatar around void addThrust(glm::vec3 newThrust) { _thrust += newThrust; }; glm::vec3 getThrust() { return _thrust; }; diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index 9df23dad2c..2469d0df04 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -210,7 +210,7 @@ QByteArray AvatarData::toByteArray(bool cullSmallChanges, bool sendAll) { packFloatAngleToTwoByte((uint8_t*)(header->localOrientation + 0), bodyEulerAngles.y); packFloatAngleToTwoByte((uint8_t*)(header->localOrientation + 1), bodyEulerAngles.x); packFloatAngleToTwoByte((uint8_t*)(header->localOrientation + 2), bodyEulerAngles.z); - packFloatRatioToTwoByte((uint8_t*)(&header->scale), _targetScale); + packFloatRatioToTwoByte((uint8_t*)(&header->scale), getDomainLimitedScale()); header->lookAtPosition[0] = _headData->_lookAtPosition.x; header->lookAtPosition[1] = _headData->_lookAtPosition.y; header->lookAtPosition[2] = _headData->_lookAtPosition.z; @@ -516,7 +516,7 @@ int AvatarData::parseDataFromBuffer(const QByteArray& buffer) { } return buffer.size(); } - _targetScale = std::max(MIN_AVATAR_SCALE, std::min(MAX_AVATAR_SCALE, scale)); + setTargetScale(scale); glm::vec3 lookAt = glm::vec3(header->lookAtPosition[0], header->lookAtPosition[1], header->lookAtPosition[2]); if (isNaN(lookAt)) { @@ -1439,7 +1439,7 @@ QJsonObject AvatarData::toJson() const { if (!success) { qDebug() << "Warning -- AvatarData::toJson couldn't get avatar transform"; } - avatarTransform.setScale(getTargetScale()); + avatarTransform.setScale(getDomainLimitedScale()); if (recordingBasis) { root[JSON_AVATAR_BASIS] = Transform::toJson(*recordingBasis); // Find the relative transform @@ -1451,7 +1451,7 @@ QJsonObject AvatarData::toJson() const { root[JSON_AVATAR_RELATIVE] = Transform::toJson(avatarTransform); } - auto scale = getTargetScale(); + auto scale = getDomainLimitedScale(); if (scale != 1.0f) { root[JSON_AVATAR_SCALE] = scale; } diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index cb3ef0c40e..018833283a 100644 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -243,6 +243,10 @@ public: void setTargetScale(float targetScale); void setTargetScaleVerbose(float targetScale); + float getDomainLimitedScale() const { return glm::clamp(_targetScale, _domainMinimumScale, _domainMaximumScale); } + void setDomainMinimumScale(float domainMinimumScale) { _domainMinimumScale = std::max(domainMinimumScale, MIN_AVATAR_SCALE); } + void setDomainMaximumScale(float domainMaximumScale) { _domainMaximumScale = std::min(domainMaximumScale, MAX_AVATAR_SCALE); } + // Hand State Q_INVOKABLE void setHandState(char s) { _handState = s; } Q_INVOKABLE char getHandState() const { return _handState; } @@ -377,6 +381,8 @@ protected: // Body scale float _targetScale; + float _domainMinimumScale { MIN_AVATAR_SCALE }; + float _domainMaximumScale { MAX_AVATAR_SCALE }; // Hand state (are we grabbing something or not) char _handState; From 64d9fa0f3907a9c03d1968a8903938bb9b7538e1 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 10 Nov 2016 14:19:32 -0800 Subject: [PATCH 15/59] clamp avatar scale to domain limit in avatar mixer --- assignment-client/src/avatars/AvatarMixer.cpp | 28 ++++++++++++++++--- assignment-client/src/avatars/AvatarMixer.h | 3 ++ libraries/avatars/src/AvatarData.h | 6 ++-- 3 files changed, 31 insertions(+), 6 deletions(-) diff --git a/assignment-client/src/avatars/AvatarMixer.cpp b/assignment-client/src/avatars/AvatarMixer.cpp index d87a5f1cc9..1896e3a43f 100644 --- a/assignment-client/src/avatars/AvatarMixer.cpp +++ b/assignment-client/src/avatars/AvatarMixer.cpp @@ -512,12 +512,19 @@ void AvatarMixer::domainSettingsRequestComplete() { auto nodeList = DependencyManager::get(); nodeList->addNodeTypeToInterestSet(NodeType::Agent); - nodeList->linkedDataCreateCallback = [] (Node* node) { - node->setLinkedData(std::unique_ptr { new AvatarMixerClientData }); - }; - // parse the settings to pull out the values we need parseDomainServerSettings(nodeList->getDomainHandler().getSettingsObject()); + + float domainMinimumScale = _domainMinimumScale; + float domainMaximumScale = _domainMaximumScale; + + nodeList->linkedDataCreateCallback = [domainMinimumScale, domainMaximumScale] (Node* node) { + auto clientData = std::unique_ptr { new AvatarMixerClientData }; + clientData->getAvatar().setDomainMinimumScale(domainMinimumScale); + clientData->getAvatar().setDomainMaximumScale(domainMaximumScale); + + node->setLinkedData(std::move(clientData)); + }; // start the broadcastThread _broadcastThread.start(); @@ -549,4 +556,17 @@ void AvatarMixer::parseDomainServerSettings(const QJsonObject& domainSettings) { _maxKbpsPerNode = nodeBandwidthValue.toDouble(DEFAULT_NODE_SEND_BANDWIDTH) * KILO_PER_MEGA; qDebug() << "The maximum send bandwidth per node is" << _maxKbpsPerNode << "kbps."; + + const QString AVATARS_SETTINGS_KEY = "avatars"; + + static const QString MIN_SCALE_OPTION = "min_avatar_scale"; + float settingMinScale = domainSettings[AVATARS_SETTINGS_KEY].toObject()[MIN_SCALE_OPTION].toDouble(MIN_AVATAR_SCALE); + _domainMinimumScale = glm::clamp(settingMinScale, MIN_AVATAR_SCALE, MAX_AVATAR_SCALE); + + static const QString MAX_SCALE_OPTION = "max_avatar_scale"; + float settingMaxScale = domainSettings[AVATARS_SETTINGS_KEY].toObject()[MAX_SCALE_OPTION].toDouble(MAX_AVATAR_SCALE); + _domainMaximumScale = glm::clamp(settingMaxScale, MIN_AVATAR_SCALE, MAX_AVATAR_SCALE); + + qDebug() << "This domain requires a minimum avatar scale of" << _domainMinimumScale + << "and a maximum avatar scale of" << _domainMaximumScale; } diff --git a/assignment-client/src/avatars/AvatarMixer.h b/assignment-client/src/avatars/AvatarMixer.h index 9286cd4691..6e1d722145 100644 --- a/assignment-client/src/avatars/AvatarMixer.h +++ b/assignment-client/src/avatars/AvatarMixer.h @@ -59,6 +59,9 @@ private: float _maxKbpsPerNode = 0.0f; + float _domainMinimumScale { MIN_AVATAR_SCALE }; + float _domainMaximumScale { MAX_AVATAR_SCALE }; + QTimer* _broadcastTimer = nullptr; }; diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index 018833283a..97879700ee 100644 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -244,8 +244,10 @@ public: void setTargetScaleVerbose(float targetScale); float getDomainLimitedScale() const { return glm::clamp(_targetScale, _domainMinimumScale, _domainMaximumScale); } - void setDomainMinimumScale(float domainMinimumScale) { _domainMinimumScale = std::max(domainMinimumScale, MIN_AVATAR_SCALE); } - void setDomainMaximumScale(float domainMaximumScale) { _domainMaximumScale = std::min(domainMaximumScale, MAX_AVATAR_SCALE); } + void setDomainMinimumScale(float domainMinimumScale) + { _domainMinimumScale = glm::clamp(domainMinimumScale, MIN_AVATAR_SCALE, MAX_AVATAR_SCALE); } + void setDomainMaximumScale(float domainMaximumScale) + { _domainMaximumScale = glm::clamp(domainMaximumScale, MIN_AVATAR_SCALE, MAX_AVATAR_SCALE); } // Hand State Q_INVOKABLE void setHandState(char s) { _handState = s; } From 6f442a74b1cbc7355717ce3cc6a52ede5b8689fc Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 10 Nov 2016 14:43:15 -0800 Subject: [PATCH 16/59] request settings from agents and debug results --- .../resources/describe-settings.json | 1 + interface/src/avatar/MyAvatar.cpp | 3 ++ libraries/networking/src/DomainHandler.cpp | 32 +++++++------------ 3 files changed, 15 insertions(+), 21 deletions(-) diff --git a/domain-server/resources/describe-settings.json b/domain-server/resources/describe-settings.json index b5c612881f..77a33b4d56 100644 --- a/domain-server/resources/describe-settings.json +++ b/domain-server/resources/describe-settings.json @@ -869,6 +869,7 @@ { "name": "avatars", "label": "Avatars", + "assignment-types": [1, 2], "settings": [ { "name": "min_avatar_scale", diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index e1f0bd3a68..48b6e7c53c 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -1893,6 +1893,9 @@ void MyAvatar::restrictScaleFromDomainSettings(const QJsonObject& domainSettings float settingMaxScale = avatarsObject[MAX_SCALE_OPTION].toDouble(MAX_AVATAR_SCALE); setDomainMaximumScale(settingMaxScale); + qCDebug(interfaceapp, "This domain requires a minimum avatar scale of %f and a maximum avatar scale of %f", + _domainMinimumScale, _domainMaximumScale); + // debug to log if this avatar's scale in this domain will be clamped auto clampedScale = glm::clamp(_targetScale, _domainMinimumScale, _domainMaximumScale); diff --git a/libraries/networking/src/DomainHandler.cpp b/libraries/networking/src/DomainHandler.cpp index eecc1515f5..5d7340b2ce 100644 --- a/libraries/networking/src/DomainHandler.cpp +++ b/libraries/networking/src/DomainHandler.cpp @@ -272,27 +272,17 @@ void DomainHandler::setIsConnected(bool isConnected) { } void DomainHandler::requestDomainSettings() { - // TODO: the nodes basically lock if they don't get a response - add a timeout to this so that they at least restart - // if they can't get settings - - NodeType_t owningNodeType = DependencyManager::get()->getOwnerType(); - if (owningNodeType == NodeType::Agent) { - // for now the agent nodes don't need any domain settings - _settingsObject = QJsonObject(); - emit settingsReceived(_settingsObject); - } else { - qCDebug(networking) << "Requesting settings from domain server"; - - Assignment::Type assignmentType = Assignment::typeForNodeType(DependencyManager::get()->getOwnerType()); - - auto packet = NLPacket::create(PacketType::DomainSettingsRequest, sizeof(assignmentType), true, false); - packet->writePrimitive(assignmentType); - - auto nodeList = DependencyManager::get(); - nodeList->sendPacket(std::move(packet), _sockAddr); - - _settingsTimer.start(); - } + qCDebug(networking) << "Requesting settings from domain server"; + + Assignment::Type assignmentType = Assignment::typeForNodeType(DependencyManager::get()->getOwnerType()); + + auto packet = NLPacket::create(PacketType::DomainSettingsRequest, sizeof(assignmentType), true, false); + packet->writePrimitive(assignmentType); + + auto nodeList = DependencyManager::get(); + nodeList->sendPacket(std::move(packet), _sockAddr); + + _settingsTimer.start(); } void DomainHandler::processSettingsPacketList(QSharedPointer packetList) { From 9fdde49d141b4f70ef22d945115c0c5c96f578f4 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 10 Nov 2016 14:54:42 -0800 Subject: [PATCH 17/59] clamp target scale changes on both ends --- interface/src/avatar/MyAvatar.cpp | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 48b6e7c53c..3b2b89310b 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -1833,34 +1833,32 @@ bool findAvatarAvatarPenetration(const glm::vec3 positionA, float radiusA, float } void MyAvatar::increaseSize() { - // clamp the target scale to the maximum allowable scale in the domain - + // clamp the target scale to the allowable scale in the domain float updatedTargetScale = _targetScale * (1.0f + SCALING_RATIO); - if (updatedTargetScale > _domainMaximumScale) { - qCDebug(interfaceapp, "Forced scale to %f since %f would be larger than allowed maximum", - _domainMaximumScale, updatedTargetScale); + auto clampedTargetScale = glm::clamp(_targetScale, _domainMinimumScale, _domainMaximumScale); - updatedTargetScale = _domainMaximumScale; + if (clampedTargetScale != updatedTargetScale) { + qCDebug(interfaceapp, "Forcing scale to %f since %f is not allowed by domain", + clampedTargetScale, updatedTargetScale); } - setTargetScale(updatedTargetScale); + setTargetScale(clampedTargetScale); qCDebug(interfaceapp, "Changed scale to %f", (double)_targetScale); } void MyAvatar::decreaseSize() { - // clamp the target scale to the minimum allowable scale in the domain + // clamp the target scale to the allowable scale in the domain float updatedTargetScale = _targetScale * (1.0f - SCALING_RATIO); - if (updatedTargetScale < _domainMinimumScale) { - qCDebug(interfaceapp, "Forced scale to %f since %f would be smaller than allowed minimum", - _domainMinimumScale, updatedTargetScale); + auto clampedTargetScale = glm::clamp(_targetScale, _domainMinimumScale, _domainMaximumScale); - updatedTargetScale = _domainMinimumScale; + if (clampedTargetScale != updatedTargetScale) { + qCDebug(interfaceapp, "Forcing scale to %f since %f is not allowed by domain", + clampedTargetScale, updatedTargetScale); } - - setTargetScale(updatedTargetScale); + setTargetScale(clampedTargetScale); qCDebug(interfaceapp, "Changed scale to %f", (double)_targetScale); } From 53769f4edf030c5a4ddb7aac3cc8ef1c4f551cc3 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 10 Nov 2016 14:58:04 -0800 Subject: [PATCH 18/59] change scale for avatar if domain limited scale changes --- interface/src/avatar/Avatar.cpp | 11 ++++++----- interface/src/avatar/AvatarActionHold.cpp | 2 +- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index 872d2af04e..46ee15de08 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -165,16 +165,17 @@ AABox Avatar::getBounds() const { void Avatar::animateScaleChanges(float deltaTime) { float currentScale = getUniformScale(); - if (currentScale != _targetScale) { - // use exponential decay toward _targetScale + auto desiredScale = getDomainLimitedScale(); + if (currentScale != desiredScale) { + // use exponential decay toward the domain limit clamped scale const float SCALE_ANIMATION_TIMESCALE = 0.5f; float blendFactor = glm::clamp(deltaTime / SCALE_ANIMATION_TIMESCALE, 0.0f, 1.0f); - float animatedScale = (1.0f - blendFactor) * currentScale + blendFactor * _targetScale; + float animatedScale = (1.0f - blendFactor) * currentScale + blendFactor * desiredScale; // snap to the end when we get close enough const float MIN_RELATIVE_SCALE_ERROR = 0.03f; - if (fabsf(_targetScale - currentScale) / _targetScale < MIN_RELATIVE_SCALE_ERROR) { - animatedScale = _targetScale; + if (fabsf(desiredScale - currentScale) / desiredScale < MIN_RELATIVE_SCALE_ERROR) { + animatedScale = desiredScale; } setScale(glm::vec3(animatedScale)); // avatar scale is uniform diff --git a/interface/src/avatar/AvatarActionHold.cpp b/interface/src/avatar/AvatarActionHold.cpp index 85ff485d7a..32a3586dba 100644 --- a/interface/src/avatar/AvatarActionHold.cpp +++ b/interface/src/avatar/AvatarActionHold.cpp @@ -152,7 +152,7 @@ bool AvatarActionHold::getTarget(float deltaTimeStep, glm::quat& rotation, glm:: Transform avatarTransform; auto myAvatar = DependencyManager::get()->getMyAvatar(); avatarTransform = myAvatar->getTransform(); - palmPosition = avatarTransform.transform(pose.getTranslation() / myAvatar->getTargetScale()); + palmPosition = avatarTransform.transform(pose.getTranslation() / myAvatar->getDomainLimitedScale()); palmRotation = avatarTransform.getRotation() * pose.getRotation(); } else { glm::vec3 avatarRigidBodyPosition; From d5722c1654dd55f1ab8235ec2f5a7c09afb5887b Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 10 Nov 2016 15:03:13 -0800 Subject: [PATCH 19/59] fix clamping of scale and DRY it up --- interface/src/avatar/MyAvatar.cpp | 44 +++++++++++-------------------- interface/src/avatar/MyAvatar.h | 1 + 2 files changed, 17 insertions(+), 28 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 3b2b89310b..0fd7192f2f 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -1832,49 +1832,37 @@ bool findAvatarAvatarPenetration(const glm::vec3 positionA, float radiusA, float return false; } +void MyAvatar::clampScaleChangeToDomainLimits(float desiredScale) { + auto clampedTargetScale = glm::clamp(desiredScale, _domainMinimumScale, _domainMaximumScale); + + if (clampedTargetScale != desiredScale) { + qCDebug(interfaceapp, "Forcing scale to %f since %f is not allowed by domain", + clampedTargetScale, desiredScale); + } + + setTargetScale(clampedTargetScale); + qCDebug(interfaceapp, "Changed scale to %f", _targetScale); +} + void MyAvatar::increaseSize() { // clamp the target scale to the allowable scale in the domain float updatedTargetScale = _targetScale * (1.0f + SCALING_RATIO); - auto clampedTargetScale = glm::clamp(_targetScale, _domainMinimumScale, _domainMaximumScale); - - if (clampedTargetScale != updatedTargetScale) { - qCDebug(interfaceapp, "Forcing scale to %f since %f is not allowed by domain", - clampedTargetScale, updatedTargetScale); - } - - setTargetScale(clampedTargetScale); - qCDebug(interfaceapp, "Changed scale to %f", (double)_targetScale); + clampScaleChangeToDomainLimits(updatedTargetScale); } void MyAvatar::decreaseSize() { // clamp the target scale to the allowable scale in the domain float updatedTargetScale = _targetScale * (1.0f - SCALING_RATIO); - auto clampedTargetScale = glm::clamp(_targetScale, _domainMinimumScale, _domainMaximumScale); - - if (clampedTargetScale != updatedTargetScale) { - qCDebug(interfaceapp, "Forcing scale to %f since %f is not allowed by domain", - clampedTargetScale, updatedTargetScale); - } - - setTargetScale(clampedTargetScale); - qCDebug(interfaceapp, "Changed scale to %f", (double)_targetScale); + clampScaleChangeToDomainLimits(updatedTargetScale); } void MyAvatar::resetSize() { - // if the default + // attempt to reset avatar size to the default const float DEFAULT_AVATAR_SCALE = 1.0f; - float allowedDefaultScale = glm::clamp(DEFAULT_AVATAR_SCALE, _domainMinimumScale, _domainMaximumScale); - - if (allowedDefaultScale != DEFAULT_AVATAR_SCALE) { - qCDebug(interfaceapp, "Forcing scale to %f since %f is not an allowed avatar scale by the domain", - allowedDefaultScale, DEFAULT_AVATAR_SCALE); - } - - setTargetScale(allowedDefaultScale); - qCDebug(interfaceapp, "Reset scale to %f", (double)_targetScale); + clampScaleChangeToDomainLimits(DEFAULT_AVATAR_SCALE); } void MyAvatar::restrictScaleFromDomainSettings(const QJsonObject& domainSettingsObject) { diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index d9c88621d2..0b8db6a24d 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -372,6 +372,7 @@ private: virtual void updatePalms() override {} void lateUpdatePalms(); + void clampScaleChangeToDomainLimits(float desiredScale); float _driveKeys[MAX_DRIVE_KEYS]; bool _wasPushing; From 272d0c845e48d58db7e1089fa04c8d22dacb59e5 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 10 Nov 2016 15:25:15 -0800 Subject: [PATCH 20/59] add clarifying comments about target scale changes --- interface/src/avatar/MyAvatar.cpp | 36 ++++++++++++++++++++++++++++--- interface/src/avatar/MyAvatar.h | 1 + 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 0fd7192f2f..cdde8a00a3 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -1832,6 +1832,28 @@ bool findAvatarAvatarPenetration(const glm::vec3 positionA, float radiusA, float return false; } +// There can be a separation between the _targetScale and the actual scale of the rendered avatar in a domain. +// When the avatar enters a domain where their target scale is not allowed according to the min/max +// we do not change their saved target scale. Instead, we use getDomainLimitedScale() to render the avatar +// at a domain appropriate size. When the avatar leaves the limiting domain, we'll return them to their previous target scale. +// While connected to a domain that limits avatar scale if the user manually changes their avatar scale, we change +// target scale to match the new scale they have chosen. When they leave the domain they will not return to the scale they were +// before they entered the limiting domain. + +void MyAvatar::clampTargetScaleToDomainLimits() { + // when we're about to change the target scale because the user has asked to increase or decrease their scale, + // we first make sure that we're starting from a target scale that is allowed by the current domain + + auto clampedTargetScale = glm::clamp(_targetScale, _domainMinimumScale, _domainMaximumScale); + + if (clampedTargetScale != _targetScale) { + qCDebug(interfaceapp, "Clamped scale to %f since original target scale %f was not allowed by domain", + clampedTargetScale, _targetScale); + + setTargetScale(clampedTargetScale); + } +} + void MyAvatar::clampScaleChangeToDomainLimits(float desiredScale) { auto clampedTargetScale = glm::clamp(desiredScale, _domainMinimumScale, _domainMaximumScale); @@ -1845,21 +1867,29 @@ void MyAvatar::clampScaleChangeToDomainLimits(float desiredScale) { } void MyAvatar::increaseSize() { - // clamp the target scale to the allowable scale in the domain + // make sure we're starting from an allowable scale + clampTargetScaleToDomainLimits(); + + // calculate what our new scale should be float updatedTargetScale = _targetScale * (1.0f + SCALING_RATIO); + // attempt to change to desired scale (clamped to the domain limits) clampScaleChangeToDomainLimits(updatedTargetScale); } void MyAvatar::decreaseSize() { - // clamp the target scale to the allowable scale in the domain + // make sure we're starting from an allowable scale + clampTargetScaleToDomainLimits(); + + // calculate what our new scale should be float updatedTargetScale = _targetScale * (1.0f - SCALING_RATIO); + // attempt to change to desired scale (clamped to the domain limits) clampScaleChangeToDomainLimits(updatedTargetScale); } void MyAvatar::resetSize() { - // attempt to reset avatar size to the default + // attempt to reset avatar size to the default (clamped to domain limits) const float DEFAULT_AVATAR_SCALE = 1.0f; clampScaleChangeToDomainLimits(DEFAULT_AVATAR_SCALE); diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index 0b8db6a24d..60049bea67 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -372,6 +372,7 @@ private: virtual void updatePalms() override {} void lateUpdatePalms(); + void clampTargetScaleToDomainLimits(); void clampScaleChangeToDomainLimits(float desiredScale); float _driveKeys[MAX_DRIVE_KEYS]; From 850361f22233501f7bf0bbcd2c958be4485d4c51 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Thu, 10 Nov 2016 15:26:28 -0800 Subject: [PATCH 21/59] lastEditedBy property for entities --- libraries/entities/src/EntityItem.cpp | 9 +++++++++ libraries/entities/src/EntityItem.h | 4 ++++ libraries/entities/src/EntityItemProperties.cpp | 6 ++++++ libraries/entities/src/EntityItemProperties.h | 5 +++++ libraries/entities/src/EntityItemPropertiesDefaults.h | 2 ++ libraries/entities/src/EntityPropertyFlags.h | 2 ++ libraries/entities/src/EntityTree.cpp | 2 ++ libraries/networking/src/udt/PacketHeaders.cpp | 2 +- libraries/networking/src/udt/PacketHeaders.h | 1 + 9 files changed, 32 insertions(+), 1 deletion(-) diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index 68636415f8..babf714d9b 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -43,6 +43,7 @@ EntityItem::EntityItem(const EntityItemID& entityItemID) : _lastSimulated(0), _lastUpdated(0), _lastEdited(0), + _lastEditedBy(ENTITY_ITEM_DEFAULT_LAST_EDITED_BY), _lastEditedFromRemote(0), _lastEditedFromRemoteInRemoteTime(0), _created(UNKNOWN_CREATED_TIME), @@ -141,6 +142,8 @@ EntityPropertyFlags EntityItem::getEntityProperties(EncodeBitstreamParams& param requestedProperties += PROP_CLIENT_ONLY; requestedProperties += PROP_OWNING_AVATAR_ID; + requestedProperties += PROP_LAST_EDITED_BY; + return requestedProperties; } @@ -279,6 +282,7 @@ OctreeElement::AppendState EntityItem::appendEntityData(OctreePacketData* packet APPEND_ENTITY_PROPERTY(PROP_PARENT_ID, getParentID()); APPEND_ENTITY_PROPERTY(PROP_PARENT_JOINT_INDEX, getParentJointIndex()); APPEND_ENTITY_PROPERTY(PROP_QUERY_AA_CUBE, getQueryAACube()); + APPEND_ENTITY_PROPERTY(PROP_LAST_EDITED_BY, getLastEditedBy()); appendSubclassData(packetData, params, entityTreeElementExtraEncodeData, requestedProperties, @@ -803,6 +807,7 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef } READ_ENTITY_PROPERTY(PROP_QUERY_AA_CUBE, AACube, setQueryAACube); + READ_ENTITY_PROPERTY(PROP_LAST_EDITED_BY, QUuid, setLastEditedBy); bytesRead += readEntitySubclassDataFromBuffer(dataAt, (bytesLeftToRead - bytesRead), args, propertyFlags, overwriteLocalData, somethingChanged); @@ -1205,6 +1210,8 @@ EntityItemProperties EntityItem::getProperties(EntityPropertyFlags desiredProper COPY_ENTITY_PROPERTY_TO_PROPERTIES(clientOnly, getClientOnly); COPY_ENTITY_PROPERTY_TO_PROPERTIES(owningAvatarID, getOwningAvatarID); + COPY_ENTITY_PROPERTY_TO_PROPERTIES(lastEditedBy, getLastEditedBy); + properties._defaultSettings = false; return properties; @@ -1307,6 +1314,8 @@ bool EntityItem::setProperties(const EntityItemProperties& properties) { SET_ENTITY_PROPERTY_FROM_PROPERTIES(clientOnly, setClientOnly); SET_ENTITY_PROPERTY_FROM_PROPERTIES(owningAvatarID, setOwningAvatarID); + SET_ENTITY_PROPERTY_FROM_PROPERTIES(lastEditedBy, setLastEditedBy); + AACube saveQueryAACube = _queryAACube; checkAndAdjustQueryAACube(); if (saveQueryAACube != _queryAACube) { diff --git a/libraries/entities/src/EntityItem.h b/libraries/entities/src/EntityItem.h index a751d76b2a..999e209959 100644 --- a/libraries/entities/src/EntityItem.h +++ b/libraries/entities/src/EntityItem.h @@ -448,6 +448,9 @@ public: virtual void emitScriptEvent(const QVariant& message) {} + QUuid getLastEditedBy() const { return _lastEditedBy; } + void setLastEditedBy(QUuid value) { _lastEditedBy = value; } + protected: void setSimulated(bool simulated) { _simulated = simulated; } @@ -463,6 +466,7 @@ protected: // and physics changes quint64 _lastUpdated; // last time this entity called update(), this includes animations and non-physics changes quint64 _lastEdited; // last official local or remote edit time + QUuid _lastEditedBy; // id of last editor quint64 _lastBroadcast; // the last time we sent an edit packet about this entity quint64 _lastEditedFromRemote; // last time we received and edit from the server diff --git a/libraries/entities/src/EntityItemProperties.cpp b/libraries/entities/src/EntityItemProperties.cpp index a0142dec8f..96cd15fa85 100644 --- a/libraries/entities/src/EntityItemProperties.cpp +++ b/libraries/entities/src/EntityItemProperties.cpp @@ -36,6 +36,7 @@ EntityItemProperties::EntityItemProperties(EntityPropertyFlags desiredProperties _id(UNKNOWN_ENTITY_ID), _idSet(false), _lastEdited(0), +_lastEditedBy(QUuid()), _type(EntityTypes::Unknown), _localRenderAlpha(1.0f), @@ -227,6 +228,7 @@ void EntityItemProperties::setBackgroundModeFromString(const QString& background EntityPropertyFlags EntityItemProperties::getChangedProperties() const { EntityPropertyFlags changedProperties; + CHECK_PROPERTY_CHANGE(PROP_LAST_EDITED_BY, lastEditedBy); CHECK_PROPERTY_CHANGE(PROP_POSITION, position); CHECK_PROPERTY_CHANGE(PROP_DIMENSIONS, dimensions); CHECK_PROPERTY_CHANGE(PROP_ROTATION, rotation); @@ -368,6 +370,7 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER_NO_SKIP(ageAsText, formatSecondsElapsed(getAge())); // gettable, but not settable } + COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_LAST_EDITED_BY, lastEditedBy); COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_POSITION, position); COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_DIMENSIONS, dimensions); if (!skipDefaults) { @@ -611,6 +614,7 @@ void EntityItemProperties::copyFromScriptValue(const QScriptValue& object, bool setType(typeScriptValue.toVariant().toString()); } + COPY_PROPERTY_FROM_QSCRIPTVALUE(lastEditedBy, QUuid, setLastEditedBy); COPY_PROPERTY_FROM_QSCRIPTVALUE(position, glmVec3, setPosition); COPY_PROPERTY_FROM_QSCRIPTVALUE(dimensions, glmVec3, setDimensions); COPY_PROPERTY_FROM_QSCRIPTVALUE(rotation, glmQuat, setRotation); @@ -750,6 +754,7 @@ void EntityItemProperties::copyFromScriptValue(const QScriptValue& object, bool } void EntityItemProperties::merge(const EntityItemProperties& other) { + COPY_PROPERTY_IF_CHANGED(lastEditedBy); COPY_PROPERTY_IF_CHANGED(position); COPY_PROPERTY_IF_CHANGED(dimensions); COPY_PROPERTY_IF_CHANGED(rotation); @@ -1667,6 +1672,7 @@ bool EntityItemProperties::encodeEraseEntityMessage(const EntityItemID& entityIt } void EntityItemProperties::markAllChanged() { + _lastEditedByChanged = true; _simulationOwnerChanged = true; _positionChanged = true; _dimensionsChanged = true; diff --git a/libraries/entities/src/EntityItemProperties.h b/libraries/entities/src/EntityItemProperties.h index d5cce92f87..5a812ffe37 100644 --- a/libraries/entities/src/EntityItemProperties.h +++ b/libraries/entities/src/EntityItemProperties.h @@ -83,6 +83,7 @@ public: quint64 getLastEdited() const { return _lastEdited; } float getEditedAgo() const /// Elapsed seconds since this entity was last edited { return (float)(usecTimestampNow() - getLastEdited()) / (float)USECS_PER_SECOND; } + EntityPropertyFlags getChangedProperties() const; bool parentDependentPropertyChanged() const; // was there a changed in a property that requires parent info to interpret? @@ -218,6 +219,8 @@ public: DEFINE_PROPERTY_REF(PROP_DPI, DPI, dpi, uint16_t, ENTITY_ITEM_DEFAULT_DPI); + DEFINE_PROPERTY_REF(PROP_LAST_EDITED_BY, LastEditedBy, lastEditedBy, QUuid, ENTITY_ITEM_DEFAULT_LAST_EDITED_BY); + static QString getBackgroundModeString(BackgroundMode mode); @@ -455,6 +458,8 @@ inline QDebug operator<<(QDebug debug, const EntityItemProperties& properties) { DEBUG_PROPERTY_IF_CHANGED(debug, properties, ClientOnly, clientOnly, ""); DEBUG_PROPERTY_IF_CHANGED(debug, properties, OwningAvatarID, owningAvatarID, ""); + DEBUG_PROPERTY_IF_CHANGED(debug, properties, LastEditedBy, lastEditedBy, ""); + properties.getAnimation().debugDump(); properties.getSkybox().debugDump(); properties.getStage().debugDump(); diff --git a/libraries/entities/src/EntityItemPropertiesDefaults.h b/libraries/entities/src/EntityItemPropertiesDefaults.h index 3ab827a222..ca7ac669f3 100644 --- a/libraries/entities/src/EntityItemPropertiesDefaults.h +++ b/libraries/entities/src/EntityItemPropertiesDefaults.h @@ -75,4 +75,6 @@ const QString ENTITY_ITEM_DEFAULT_NAME = QString(""); const uint16_t ENTITY_ITEM_DEFAULT_DPI = 30; +const QUuid ENTITY_ITEM_DEFAULT_LAST_EDITED_BY = QUuid(); + #endif // hifi_EntityItemPropertiesDefaults_h diff --git a/libraries/entities/src/EntityPropertyFlags.h b/libraries/entities/src/EntityPropertyFlags.h index e09db1e867..127f3d0eea 100644 --- a/libraries/entities/src/EntityPropertyFlags.h +++ b/libraries/entities/src/EntityPropertyFlags.h @@ -181,6 +181,8 @@ enum EntityPropertyList { PROP_LOCAL_VELOCITY, // only used to convert values to and from scripts PROP_LOCAL_ANGULAR_VELOCITY, // only used to convert values to and from scripts + PROP_LAST_EDITED_BY, + //////////////////////////////////////////////////////////////////////////////////////////////////// // ATTENTION: add new properties to end of list just ABOVE this line PROP_AFTER_LAST_ITEM, diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index 5399adfa82..a03e4b8f08 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -1013,6 +1013,7 @@ int EntityTree::processEditPacketData(ReceivedMessage& message, const unsigned c endLogging = usecTimestampNow(); startUpdate = usecTimestampNow(); + properties.setLastEditedBy(senderNode->getUUID()); updateEntity(entityItemID, properties, senderNode); existingEntity->markAsChangedOnServer(); endUpdate = usecTimestampNow(); @@ -1021,6 +1022,7 @@ int EntityTree::processEditPacketData(ReceivedMessage& message, const unsigned c if (senderNode->getCanRez() || senderNode->getCanRezTmp()) { // this is a new entity... assign a new entityID properties.setCreated(properties.getLastEdited()); + properties.setLastEditedBy(senderNode->getUUID()); startCreate = usecTimestampNow(); EntityItemPointer newEntity = addEntity(entityItemID, properties); endCreate = usecTimestampNow(); diff --git a/libraries/networking/src/udt/PacketHeaders.cpp b/libraries/networking/src/udt/PacketHeaders.cpp index 6b86b7bc6e..edfe086605 100644 --- a/libraries/networking/src/udt/PacketHeaders.cpp +++ b/libraries/networking/src/udt/PacketHeaders.cpp @@ -47,7 +47,7 @@ PacketVersion versionForPacketType(PacketType packetType) { case PacketType::EntityAdd: case PacketType::EntityEdit: case PacketType::EntityData: - return VERSION_ENTITIES_ARROW_ACTION; + return VERSION_ENTITIES_LAST_EDITED_BY; case PacketType::AvatarIdentity: case PacketType::AvatarData: case PacketType::BulkAvatarData: diff --git a/libraries/networking/src/udt/PacketHeaders.h b/libraries/networking/src/udt/PacketHeaders.h index 0eca24176c..0d0f2ea618 100644 --- a/libraries/networking/src/udt/PacketHeaders.h +++ b/libraries/networking/src/udt/PacketHeaders.h @@ -188,6 +188,7 @@ const PacketVersion VERSION_MODEL_ENTITIES_SUPPORT_STATIC_MESH = 61; const PacketVersion VERSION_MODEL_ENTITIES_SUPPORT_SIMPLE_HULLS = 62; const PacketVersion VERSION_WEB_ENTITIES_SUPPORT_DPI = 63; const PacketVersion VERSION_ENTITIES_ARROW_ACTION = 64; +const PacketVersion VERSION_ENTITIES_LAST_EDITED_BY = 65; enum class AssetServerPacketVersion: PacketVersion { VegasCongestionControl = 19 From f14037979a697d6c72b7e24c98a2dbb42833f81c Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 10 Nov 2016 15:31:23 -0800 Subject: [PATCH 22/59] fix a typo in help text for minimum scale --- domain-server/resources/describe-settings.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/domain-server/resources/describe-settings.json b/domain-server/resources/describe-settings.json index 77a33b4d56..8b3b21e066 100644 --- a/domain-server/resources/describe-settings.json +++ b/domain-server/resources/describe-settings.json @@ -875,7 +875,7 @@ "name": "min_avatar_scale", "type": "double", "label": "Minimum Avatar Scale (meters)", - "help": "Limits the scale of avatars in your domain. Must be at least than 0.005.", + "help": "Limits the scale of avatars in your domain. Must be at least 0.005.", "placeholder": 0.25, "default": 0.25 }, From 88c63332de1cda9058fec5f789d33a9a733cf619 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 10 Nov 2016 16:21:48 -0800 Subject: [PATCH 23/59] protect flipped min/max scale in avatar mixer settings --- assignment-client/src/avatars/AvatarMixer.cpp | 3 +++ interface/src/avatar/MyAvatar.cpp | 3 +++ 2 files changed, 6 insertions(+) diff --git a/assignment-client/src/avatars/AvatarMixer.cpp b/assignment-client/src/avatars/AvatarMixer.cpp index 1896e3a43f..9700c544c1 100644 --- a/assignment-client/src/avatars/AvatarMixer.cpp +++ b/assignment-client/src/avatars/AvatarMixer.cpp @@ -567,6 +567,9 @@ void AvatarMixer::parseDomainServerSettings(const QJsonObject& domainSettings) { float settingMaxScale = domainSettings[AVATARS_SETTINGS_KEY].toObject()[MAX_SCALE_OPTION].toDouble(MAX_AVATAR_SCALE); _domainMaximumScale = glm::clamp(settingMaxScale, MIN_AVATAR_SCALE, MAX_AVATAR_SCALE); + // make sure that the domain owner didn't flip min and max + _domainMinimumScale = std::min(_domainMinimumScale, _domainMaximumScale); + qDebug() << "This domain requires a minimum avatar scale of" << _domainMinimumScale << "and a maximum avatar scale of" << _domainMaximumScale; } diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index cdde8a00a3..7ce0f92d72 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -1909,6 +1909,9 @@ void MyAvatar::restrictScaleFromDomainSettings(const QJsonObject& domainSettings float settingMaxScale = avatarsObject[MAX_SCALE_OPTION].toDouble(MAX_AVATAR_SCALE); setDomainMaximumScale(settingMaxScale); + // make sure that the domain owner didn't flip min and max + _domainMinimumScale = std::min(_domainMinimumScale, _domainMaximumScale); + qCDebug(interfaceapp, "This domain requires a minimum avatar scale of %f and a maximum avatar scale of %f", _domainMinimumScale, _domainMaximumScale); From 285520dff7fc29afc111a99f75b325ff750d1709 Mon Sep 17 00:00:00 2001 From: David Kelly Date: Thu, 10 Nov 2016 16:24:35 -0800 Subject: [PATCH 24/59] Initial cut No script work yet, just first stab at underpinnings --- assignment-client/src/audio/AudioMixer.cpp | 20 +++++++++++- assignment-client/src/audio/AudioMixer.h | 1 + .../src/audio/AudioMixerClientData.h | 5 +++ domain-server/src/DomainServer.cpp | 3 +- .../src/DomainServerSettingsManager.cpp | 32 +++++++++++++++++++ .../src/DomainServerSettingsManager.h | 1 + libraries/networking/src/NodeList.cpp | 23 +++++++++++++ libraries/networking/src/NodeList.h | 1 + .../networking/src/udt/PacketHeaders.cpp | 3 +- libraries/networking/src/udt/PacketHeaders.h | 3 +- .../src/UsersScriptingInterface.cpp | 5 +++ .../src/UsersScriptingInterface.h | 1 + 12 files changed, 94 insertions(+), 4 deletions(-) diff --git a/assignment-client/src/audio/AudioMixer.cpp b/assignment-client/src/audio/AudioMixer.cpp index f8077303d2..17198299b4 100644 --- a/assignment-client/src/audio/AudioMixer.cpp +++ b/assignment-client/src/audio/AudioMixer.cpp @@ -94,6 +94,7 @@ AudioMixer::AudioMixer(ReceivedMessage& message) : packetReceiver.registerListener(PacketType::MuteEnvironment, this, "handleMuteEnvironmentPacket"); packetReceiver.registerListener(PacketType::NodeIgnoreRequest, this, "handleNodeIgnoreRequestPacket"); packetReceiver.registerListener(PacketType::KillAvatar, this, "handleKillAvatarPacket"); + packetReceiver.registerListener(PacketType::NodeMuteRequest, this, "handleNodeMuteRequestPacket"); connect(nodeList.data(), &NodeList::nodeKilled, this, &AudioMixer::handleNodeKilled); } @@ -599,6 +600,19 @@ void AudioMixer::handleNodeKilled(SharedNodePointer killedNode) { }); } +void AudioMixer::handleNodeMuteRequestPacket(QSharedPointer packet, SharedNodePointer sendingNode) { + auto nodeList = DependencyManager::get(); + QUuid nodeUUID = QUuid::fromRfc4122(packet->readWithoutCopy(NUM_BYTES_RFC4122_UUID)); + + auto node = nodeList->nodeWithUUID(nodeUUID); + if (node) { + // we need to set a flag so we send them the appropriate packet to mute them + + } else { + qWarning() << "Node mute packet received for unknown node " << uuidStringWithoutCurlyBraces(nodeUUID); + } +} + void AudioMixer::handleKillAvatarPacket(QSharedPointer packet, SharedNodePointer sendingNode) { auto clientData = dynamic_cast(sendingNode->getLinkedData()); if (clientData) { @@ -814,9 +828,13 @@ void AudioMixer::broadcastMixes() { // if the stream should be muted, send mute packet if (nodeData->getAvatarAudioStream() - && shouldMute(nodeData->getAvatarAudioStream()->getQuietestFrameLoudness())) { + && (shouldMute(nodeData->getAvatarAudioStream()->getQuietestFrameLoudness()) + || nodeData->shouldMuteClient())) { auto mutePacket = NLPacket::create(PacketType::NoisyMute, 0); nodeList->sendPacket(std::move(mutePacket), *node); + + // probably now we just reset the flag, once should do it (?) + nodeData->setShouldMuteClient(false); } if (node->getType() == NodeType::Agent && node->getActiveSocket() diff --git a/assignment-client/src/audio/AudioMixer.h b/assignment-client/src/audio/AudioMixer.h index 3c68e4c6af..91eafadd9d 100644 --- a/assignment-client/src/audio/AudioMixer.h +++ b/assignment-client/src/audio/AudioMixer.h @@ -49,6 +49,7 @@ private slots: void handleNodeKilled(SharedNodePointer killedNode); void handleNodeIgnoreRequestPacket(QSharedPointer packet, SharedNodePointer sendingNode); void handleKillAvatarPacket(QSharedPointer packet, SharedNodePointer sendingNode); + void handleNodeMuteRequestPacket(QSharedPointer packet, SharedNodePointer sendingNode); void removeHRTFsForFinishedInjector(const QUuid& streamID); diff --git a/assignment-client/src/audio/AudioMixerClientData.h b/assignment-client/src/audio/AudioMixerClientData.h index 52c659c240..c74461a444 100644 --- a/assignment-client/src/audio/AudioMixerClientData.h +++ b/assignment-client/src/audio/AudioMixerClientData.h @@ -86,6 +86,9 @@ public: bool shouldFlushEncoder() { return _shouldFlushEncoder; } QString getCodecName() { return _selectedCodecName; } + + bool shouldMuteClient() { return _shouldMuteClient; } + void setShouldMuteClient(bool shouldMuteClient) { _shouldMuteClient = shouldMuteClient; } signals: void injectorStreamFinished(const QUuid& streamIdentifier); @@ -114,6 +117,8 @@ private: Decoder* _decoder{ nullptr }; // for mic stream bool _shouldFlushEncoder { false }; + + bool _shouldMuteClient { false }; }; #endif // hifi_AudioMixerClientData_h diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index d13f9b883f..b58dd0fe0e 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -498,7 +498,8 @@ void DomainServer::setupNodeListAndAssignments() { // NodeList won't be available to the settings manager when it is created, so call registerListener here packetReceiver.registerListener(PacketType::DomainSettingsRequest, &_settingsManager, "processSettingsRequestPacket"); packetReceiver.registerListener(PacketType::NodeKickRequest, &_settingsManager, "processNodeKickRequestPacket"); - + packetReceiver.registerListener(PacketType::NodeMuteRequest, &_settingsManager, "processNodeMuteRequestPacket"); + // register the gatekeeper for the packets it needs to receive packetReceiver.registerListener(PacketType::DomainConnectRequest, &_gatekeeper, "processConnectRequestPacket"); packetReceiver.registerListener(PacketType::ICEPing, &_gatekeeper, "processICEPingPacket"); diff --git a/domain-server/src/DomainServerSettingsManager.cpp b/domain-server/src/DomainServerSettingsManager.cpp index c7944bbcad..ff6c4d62c6 100644 --- a/domain-server/src/DomainServerSettingsManager.cpp +++ b/domain-server/src/DomainServerSettingsManager.cpp @@ -634,6 +634,38 @@ bool DomainServerSettingsManager::ensurePermissionsForGroupRanks() { return changed; } +void DomainServerSettingsManager::processNodeMuteRequestPacket(QSharedPointer message, SharedNodePointer sendingNode) { + if (sendingNode->getCanKick()) { + QUuid nodeUUID = QUuid::fromRfc4122(message->readWithoutCopy(NUM_BYTES_RFC4122_UUID)); + + if (!nodeUUID.isNull() && nodeUUID != sendingNode->getUUID()) { + // make sure we actually have a node with this UUID + auto limitedNodeList = DependencyManager::get(); + + auto matchingNode = limitedNodeList->nodeWithUUID(nodeUUID); + + if (matchingNode) { + // send this along to the audio mixer + auto limitedNodeList = DependencyManager::get(); + auto audioMixer = limitedNodeList->soloNodeOfType(NodeType::AudioMixer); + if (audioMixer) { + auto packet = NLPacket::create(PacketType::NodeMuteRequest, NUM_BYTES_RFC4122_UUID, true); + packet->write(nodeUUID.toRfc4122()); + limitedNodeList->sendPacket(std::move(packet), *audioMixer); + } else { + qWarning() << "Couldn't find an audio mixer, cannot process node mute request"; + } + } else { + qWarning() << "Node mute request received for unknown node. Refusing to process."; + } + } else { + qWarning() << "Node kick request received for invalid node ID or from node being kicked. Refusing to process."; + } + } else { + qWarning() << "Refusing to process a kick packet from node" << uuidStringWithoutCurlyBraces(sendingNode->getUUID()) + << "that does not have kick permissions."; + } +} void DomainServerSettingsManager::processNodeKickRequestPacket(QSharedPointer message, SharedNodePointer sendingNode) { // before we do any processing on this packet make sure it comes from a node that is allowed to kick diff --git a/domain-server/src/DomainServerSettingsManager.h b/domain-server/src/DomainServerSettingsManager.h index c067377ffc..7f874226bb 100644 --- a/domain-server/src/DomainServerSettingsManager.h +++ b/domain-server/src/DomainServerSettingsManager.h @@ -105,6 +105,7 @@ public slots: private slots: void processSettingsRequestPacket(QSharedPointer message); void processNodeKickRequestPacket(QSharedPointer message, SharedNodePointer sendingNode); + void processNodeMuteRequestPacket(QSharedPointer message, SharedNodePointer sendingNode); private: QStringList _argumentList; diff --git a/libraries/networking/src/NodeList.cpp b/libraries/networking/src/NodeList.cpp index 82bac4cc3d..782eb8da3e 100644 --- a/libraries/networking/src/NodeList.cpp +++ b/libraries/networking/src/NodeList.cpp @@ -815,3 +815,26 @@ void NodeList::kickNodeBySessionID(const QUuid& nodeID) { } } + +void NodeList::muteNodeBySessionID(const QUuid& nodeID) { + // cannot mute yourself, or nobody + if (!nodeID.isNull() && _sessionUUID != nodeID ) { + if (getThisNodeCanKick()) { + // setup the packet + auto kickPacket = NLPacket::create(PacketType::NodeMuteRequest, NUM_BYTES_RFC4122_UUID, true); + + // write the node ID to the packet + kickPacket->write(nodeID.toRfc4122()); + + qDebug() << "Sending packet to mute node" << uuidStringWithoutCurlyBraces(nodeID); + + sendPacket(std::move(kickPacket), _domainHandler.getSockAddr()); + } else { + qWarning() << "You do not have permissions to mute in this domain." + << "Request to mute node" << uuidStringWithoutCurlyBraces(nodeID) << "will not be sent"; + } + } else { + qWarning() << "NodeList::muteNodeBySessionID called with an invalid ID or an ID which matches the current session ID."; + + } +} diff --git a/libraries/networking/src/NodeList.h b/libraries/networking/src/NodeList.h index 41a4a51515..4c06a13469 100644 --- a/libraries/networking/src/NodeList.h +++ b/libraries/networking/src/NodeList.h @@ -74,6 +74,7 @@ public: bool isIgnoringNode(const QUuid& nodeID) const; void kickNodeBySessionID(const QUuid& nodeID); + void muteNodeBySessionID(const QUuid& nodeID); public slots: void reset(); diff --git a/libraries/networking/src/udt/PacketHeaders.cpp b/libraries/networking/src/udt/PacketHeaders.cpp index 6b86b7bc6e..9bbf4dc134 100644 --- a/libraries/networking/src/udt/PacketHeaders.cpp +++ b/libraries/networking/src/udt/PacketHeaders.cpp @@ -26,7 +26,8 @@ const QSet NON_VERIFIED_PACKETS = QSet() << PacketType::NodeJsonStats << PacketType::EntityQuery << PacketType::OctreeDataNack << PacketType::EntityEditNack << PacketType::DomainListRequest << PacketType::StopNode - << PacketType::DomainDisconnectRequest << PacketType::NodeKickRequest; + << PacketType::DomainDisconnectRequest << PacketType::NodeKickRequest + << PacketType::NodeMuteRequest; const QSet NON_SOURCED_PACKETS = QSet() << PacketType::StunResponse << PacketType::CreateAssignment << PacketType::RequestAssignment diff --git a/libraries/networking/src/udt/PacketHeaders.h b/libraries/networking/src/udt/PacketHeaders.h index 0eca24176c..a3a7287ad0 100644 --- a/libraries/networking/src/udt/PacketHeaders.h +++ b/libraries/networking/src/udt/PacketHeaders.h @@ -99,7 +99,8 @@ public: SelectedAudioFormat, MoreEntityShapes, NodeKickRequest, - LAST_PACKET_TYPE = NodeKickRequest + NodeMuteRequest, + LAST_PACKET_TYPE = NodeMuteRequest }; }; diff --git a/libraries/script-engine/src/UsersScriptingInterface.cpp b/libraries/script-engine/src/UsersScriptingInterface.cpp index 69ad8e04ad..702368c2b3 100644 --- a/libraries/script-engine/src/UsersScriptingInterface.cpp +++ b/libraries/script-engine/src/UsersScriptingInterface.cpp @@ -29,6 +29,11 @@ void UsersScriptingInterface::kick(const QUuid& nodeID) { DependencyManager::get()->kickNodeBySessionID(nodeID); } +void UsersScriptingInterface::mute(const QUuid& nodeID) { + // ask the NodeList to mute the user with the given session ID + DependencyManager::get()->muteNodeBySessionID(nodeID); +} + bool UsersScriptingInterface::getCanKick() { // ask the NodeList to return our ability to kick return DependencyManager::get()->getThisNodeCanKick(); diff --git a/libraries/script-engine/src/UsersScriptingInterface.h b/libraries/script-engine/src/UsersScriptingInterface.h index 712eeedeb6..3c98d0a393 100644 --- a/libraries/script-engine/src/UsersScriptingInterface.h +++ b/libraries/script-engine/src/UsersScriptingInterface.h @@ -28,6 +28,7 @@ public: public slots: void ignore(const QUuid& nodeID); void kick(const QUuid& nodeID); + void mute(const QUuid& nodeID); bool getCanKick(); From 020942c82602c98ea36bc475ffeddf492703e062 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 10 Nov 2016 16:50:36 -0800 Subject: [PATCH 25/59] better handling for a flipped min/max scale --- assignment-client/src/avatars/AvatarMixer.cpp | 4 +++- interface/src/avatar/MyAvatar.cpp | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/assignment-client/src/avatars/AvatarMixer.cpp b/assignment-client/src/avatars/AvatarMixer.cpp index 9700c544c1..041449dc57 100644 --- a/assignment-client/src/avatars/AvatarMixer.cpp +++ b/assignment-client/src/avatars/AvatarMixer.cpp @@ -568,7 +568,9 @@ void AvatarMixer::parseDomainServerSettings(const QJsonObject& domainSettings) { _domainMaximumScale = glm::clamp(settingMaxScale, MIN_AVATAR_SCALE, MAX_AVATAR_SCALE); // make sure that the domain owner didn't flip min and max - _domainMinimumScale = std::min(_domainMinimumScale, _domainMaximumScale); + if (_domainMinimumScale > _domainMaximumScale) { + std::swap(_domainMinimumScale, _domainMaximumScale); + } qDebug() << "This domain requires a minimum avatar scale of" << _domainMinimumScale << "and a maximum avatar scale of" << _domainMaximumScale; diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 7ce0f92d72..155b059f68 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -1910,7 +1910,9 @@ void MyAvatar::restrictScaleFromDomainSettings(const QJsonObject& domainSettings setDomainMaximumScale(settingMaxScale); // make sure that the domain owner didn't flip min and max - _domainMinimumScale = std::min(_domainMinimumScale, _domainMaximumScale); + if (_domainMinimumScale > _domainMaximumScale) { + std::swap(_domainMinimumScale, _domainMaximumScale); + } qCDebug(interfaceapp, "This domain requires a minimum avatar scale of %f and a maximum avatar scale of %f", _domainMinimumScale, _domainMaximumScale); From 7f46714645d3a259b369d8f89488a17dcd948050 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 10 Nov 2016 16:53:56 -0800 Subject: [PATCH 26/59] drop the incorrect scale from domain settings --- domain-server/resources/describe-settings.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/domain-server/resources/describe-settings.json b/domain-server/resources/describe-settings.json index 8b3b21e066..675c39563b 100644 --- a/domain-server/resources/describe-settings.json +++ b/domain-server/resources/describe-settings.json @@ -874,7 +874,7 @@ { "name": "min_avatar_scale", "type": "double", - "label": "Minimum Avatar Scale (meters)", + "label": "Minimum Avatar Scale", "help": "Limits the scale of avatars in your domain. Must be at least 0.005.", "placeholder": 0.25, "default": 0.25 @@ -882,7 +882,7 @@ { "name": "max_avatar_scale", "type": "double", - "label": "Maximum Avatar Scale (meters)", + "label": "Maximum Avatar Scale", "help": "Limits the scale of avatars in your domain. Cannot be greater than 1000.", "placeholder": 3.0, "default": 3.0 From 80d4033767e4822bdb34d8afb3a25831eef4f62a Mon Sep 17 00:00:00 2001 From: David Kelly Date: Thu, 10 Nov 2016 17:13:50 -0800 Subject: [PATCH 27/59] oops forgot one thing... --- assignment-client/src/audio/AudioMixer.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/assignment-client/src/audio/AudioMixer.cpp b/assignment-client/src/audio/AudioMixer.cpp index 17198299b4..7b9f08e837 100644 --- a/assignment-client/src/audio/AudioMixer.cpp +++ b/assignment-client/src/audio/AudioMixer.cpp @@ -607,6 +607,8 @@ void AudioMixer::handleNodeMuteRequestPacket(QSharedPointer pac auto node = nodeList->nodeWithUUID(nodeUUID); if (node) { // we need to set a flag so we send them the appropriate packet to mute them + AudioMixerClientData* nodeData = (AudioMixerClientData*)node->getLinkedData(); + nodeData->setShouldMuteClient(true); } else { qWarning() << "Node mute packet received for unknown node " << uuidStringWithoutCurlyBraces(nodeUUID); From 15c247fc5e1be025f6b96ba57f19b943476db27b Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Fri, 11 Nov 2016 06:37:22 -0800 Subject: [PATCH 28/59] quiet warnings --- interface/src/avatar/MyAvatar.cpp | 8 ++++---- libraries/entities/src/EntityItemProperties.cpp | 1 - 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 155b059f68..b49ee94ff6 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -1848,7 +1848,7 @@ void MyAvatar::clampTargetScaleToDomainLimits() { if (clampedTargetScale != _targetScale) { qCDebug(interfaceapp, "Clamped scale to %f since original target scale %f was not allowed by domain", - clampedTargetScale, _targetScale); + (double)clampedTargetScale, (double)_targetScale); setTargetScale(clampedTargetScale); } @@ -1863,7 +1863,7 @@ void MyAvatar::clampScaleChangeToDomainLimits(float desiredScale) { } setTargetScale(clampedTargetScale); - qCDebug(interfaceapp, "Changed scale to %f", _targetScale); + qCDebug(interfaceapp, "Changed scale to %f", (double)_targetScale); } void MyAvatar::increaseSize() { @@ -1915,14 +1915,14 @@ void MyAvatar::restrictScaleFromDomainSettings(const QJsonObject& domainSettings } qCDebug(interfaceapp, "This domain requires a minimum avatar scale of %f and a maximum avatar scale of %f", - _domainMinimumScale, _domainMaximumScale); + (double)_domainMinimumScale, (double)_domainMaximumScale); // debug to log if this avatar's scale in this domain will be clamped auto clampedScale = glm::clamp(_targetScale, _domainMinimumScale, _domainMaximumScale); if (_targetScale != clampedScale) { qCDebug(interfaceapp, "Avatar scale will be clamped to %f because %f is not allowed by current domain", - clampedScale, _targetScale); + (double)clampedScale, (double)_targetScale); } } diff --git a/libraries/entities/src/EntityItemProperties.cpp b/libraries/entities/src/EntityItemProperties.cpp index 96cd15fa85..e20bd81ab3 100644 --- a/libraries/entities/src/EntityItemProperties.cpp +++ b/libraries/entities/src/EntityItemProperties.cpp @@ -36,7 +36,6 @@ EntityItemProperties::EntityItemProperties(EntityPropertyFlags desiredProperties _id(UNKNOWN_ENTITY_ID), _idSet(false), _lastEdited(0), -_lastEditedBy(QUuid()), _type(EntityTypes::Unknown), _localRenderAlpha(1.0f), From 9c8f22e0e782f0cd5bbc57d826612e303640d766 Mon Sep 17 00:00:00 2001 From: David Kelly Date: Fri, 11 Nov 2016 09:30:58 -0800 Subject: [PATCH 29/59] straight to audio mixer since we can get the canKick there too. (doh) --- assignment-client/src/audio/AudioMixer.cpp | 20 ++++++----- domain-server/src/DomainServer.cpp | 1 - .../src/DomainServerSettingsManager.cpp | 33 ------------------- .../src/DomainServerSettingsManager.h | 1 - libraries/networking/src/NodeList.cpp | 19 +++++++---- 5 files changed, 24 insertions(+), 50 deletions(-) diff --git a/assignment-client/src/audio/AudioMixer.cpp b/assignment-client/src/audio/AudioMixer.cpp index 7b9f08e837..b0a739caba 100644 --- a/assignment-client/src/audio/AudioMixer.cpp +++ b/assignment-client/src/audio/AudioMixer.cpp @@ -95,7 +95,8 @@ AudioMixer::AudioMixer(ReceivedMessage& message) : packetReceiver.registerListener(PacketType::NodeIgnoreRequest, this, "handleNodeIgnoreRequestPacket"); packetReceiver.registerListener(PacketType::KillAvatar, this, "handleKillAvatarPacket"); packetReceiver.registerListener(PacketType::NodeMuteRequest, this, "handleNodeMuteRequestPacket"); - + + nodeList->addNodeTypeToInterestSet(NodeType::DomainServer); connect(nodeList.data(), &NodeList::nodeKilled, this, &AudioMixer::handleNodeKilled); } @@ -603,15 +604,18 @@ void AudioMixer::handleNodeKilled(SharedNodePointer killedNode) { void AudioMixer::handleNodeMuteRequestPacket(QSharedPointer packet, SharedNodePointer sendingNode) { auto nodeList = DependencyManager::get(); QUuid nodeUUID = QUuid::fromRfc4122(packet->readWithoutCopy(NUM_BYTES_RFC4122_UUID)); + if (sendingNode->getCanKick()) { + auto node = nodeList->nodeWithUUID(nodeUUID); + if (node) { + // we need to set a flag so we send them the appropriate packet to mute them + AudioMixerClientData* nodeData = (AudioMixerClientData*)node->getLinkedData(); + nodeData->setShouldMuteClient(true); - auto node = nodeList->nodeWithUUID(nodeUUID); - if (node) { - // we need to set a flag so we send them the appropriate packet to mute them - AudioMixerClientData* nodeData = (AudioMixerClientData*)node->getLinkedData(); - nodeData->setShouldMuteClient(true); - + } else { + qWarning() << "Node mute packet received for unknown node " << uuidStringWithoutCurlyBraces(nodeUUID); + } } else { - qWarning() << "Node mute packet received for unknown node " << uuidStringWithoutCurlyBraces(nodeUUID); + qWarning() << "Node mute packet received from node that cannot mute, ignoring"; } } diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index b58dd0fe0e..70ee41e934 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -498,7 +498,6 @@ void DomainServer::setupNodeListAndAssignments() { // NodeList won't be available to the settings manager when it is created, so call registerListener here packetReceiver.registerListener(PacketType::DomainSettingsRequest, &_settingsManager, "processSettingsRequestPacket"); packetReceiver.registerListener(PacketType::NodeKickRequest, &_settingsManager, "processNodeKickRequestPacket"); - packetReceiver.registerListener(PacketType::NodeMuteRequest, &_settingsManager, "processNodeMuteRequestPacket"); // register the gatekeeper for the packets it needs to receive packetReceiver.registerListener(PacketType::DomainConnectRequest, &_gatekeeper, "processConnectRequestPacket"); diff --git a/domain-server/src/DomainServerSettingsManager.cpp b/domain-server/src/DomainServerSettingsManager.cpp index ff6c4d62c6..a9db2d9b3f 100644 --- a/domain-server/src/DomainServerSettingsManager.cpp +++ b/domain-server/src/DomainServerSettingsManager.cpp @@ -634,39 +634,6 @@ bool DomainServerSettingsManager::ensurePermissionsForGroupRanks() { return changed; } -void DomainServerSettingsManager::processNodeMuteRequestPacket(QSharedPointer message, SharedNodePointer sendingNode) { - if (sendingNode->getCanKick()) { - QUuid nodeUUID = QUuid::fromRfc4122(message->readWithoutCopy(NUM_BYTES_RFC4122_UUID)); - - if (!nodeUUID.isNull() && nodeUUID != sendingNode->getUUID()) { - // make sure we actually have a node with this UUID - auto limitedNodeList = DependencyManager::get(); - - auto matchingNode = limitedNodeList->nodeWithUUID(nodeUUID); - - if (matchingNode) { - // send this along to the audio mixer - auto limitedNodeList = DependencyManager::get(); - auto audioMixer = limitedNodeList->soloNodeOfType(NodeType::AudioMixer); - if (audioMixer) { - auto packet = NLPacket::create(PacketType::NodeMuteRequest, NUM_BYTES_RFC4122_UUID, true); - packet->write(nodeUUID.toRfc4122()); - limitedNodeList->sendPacket(std::move(packet), *audioMixer); - } else { - qWarning() << "Couldn't find an audio mixer, cannot process node mute request"; - } - } else { - qWarning() << "Node mute request received for unknown node. Refusing to process."; - } - } else { - qWarning() << "Node kick request received for invalid node ID or from node being kicked. Refusing to process."; - } - } else { - qWarning() << "Refusing to process a kick packet from node" << uuidStringWithoutCurlyBraces(sendingNode->getUUID()) - << "that does not have kick permissions."; - } -} - void DomainServerSettingsManager::processNodeKickRequestPacket(QSharedPointer message, SharedNodePointer sendingNode) { // before we do any processing on this packet make sure it comes from a node that is allowed to kick if (sendingNode->getCanKick()) { diff --git a/domain-server/src/DomainServerSettingsManager.h b/domain-server/src/DomainServerSettingsManager.h index 7f874226bb..c067377ffc 100644 --- a/domain-server/src/DomainServerSettingsManager.h +++ b/domain-server/src/DomainServerSettingsManager.h @@ -105,7 +105,6 @@ public slots: private slots: void processSettingsRequestPacket(QSharedPointer message); void processNodeKickRequestPacket(QSharedPointer message, SharedNodePointer sendingNode); - void processNodeMuteRequestPacket(QSharedPointer message, SharedNodePointer sendingNode); private: QStringList _argumentList; diff --git a/libraries/networking/src/NodeList.cpp b/libraries/networking/src/NodeList.cpp index 782eb8da3e..7a778edaad 100644 --- a/libraries/networking/src/NodeList.cpp +++ b/libraries/networking/src/NodeList.cpp @@ -820,15 +820,20 @@ void NodeList::muteNodeBySessionID(const QUuid& nodeID) { // cannot mute yourself, or nobody if (!nodeID.isNull() && _sessionUUID != nodeID ) { if (getThisNodeCanKick()) { - // setup the packet - auto kickPacket = NLPacket::create(PacketType::NodeMuteRequest, NUM_BYTES_RFC4122_UUID, true); + auto audioMixer = soloNodeOfType(NodeType::AudioMixer); + if (audioMixer) { + // setup the packet + auto mutePacket = NLPacket::create(PacketType::NodeMuteRequest, NUM_BYTES_RFC4122_UUID, true); - // write the node ID to the packet - kickPacket->write(nodeID.toRfc4122()); + // write the node ID to the packet + mutePacket->write(nodeID.toRfc4122()); - qDebug() << "Sending packet to mute node" << uuidStringWithoutCurlyBraces(nodeID); - - sendPacket(std::move(kickPacket), _domainHandler.getSockAddr()); + qDebug() << "Sending packet to mute node" << uuidStringWithoutCurlyBraces(nodeID); + + sendPacket(std::move(mutePacket), *audioMixer); + } else { + qWarning() << "Couldn't find audio mixer to send node mute request"; + } } else { qWarning() << "You do not have permissions to mute in this domain." << "Request to mute node" << uuidStringWithoutCurlyBraces(nodeID) << "will not be sent"; From 162f24decd7cb736cc722c933374aebeb0ad7f7a Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Fri, 11 Nov 2016 10:12:41 -0800 Subject: [PATCH 30/59] Add stutter tracking for Oculus --- .../src/display-plugins/hmd/HmdDisplayPlugin.cpp | 4 ++++ .../src/display-plugins/hmd/HmdDisplayPlugin.h | 5 ++++- plugins/oculus/src/OculusDisplayPlugin.cpp | 10 ++++++++++ plugins/openvr/src/OpenVrDisplayPlugin.cpp | 4 ---- plugins/openvr/src/OpenVrDisplayPlugin.h | 3 --- 5 files changed, 18 insertions(+), 8 deletions(-) diff --git a/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp index 2e66659de7..c5d7ac5690 100644 --- a/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp @@ -710,3 +710,7 @@ void HmdDisplayPlugin::compositeExtra() { HmdDisplayPlugin::~HmdDisplayPlugin() { qDebug() << "Destroying HmdDisplayPlugin"; } + +float HmdDisplayPlugin::stutterRate() const { + return _stutterRate.rate(); +} diff --git a/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.h index e50183dd90..435f547899 100644 --- a/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.h @@ -44,6 +44,8 @@ public: return false; } + float stutterRate() const override; + protected: virtual void hmdPresent() = 0; virtual bool isHmdMounted() const = 0; @@ -108,8 +110,9 @@ protected: QMap _frameInfos; FrameInfo _currentPresentFrameInfo; FrameInfo _currentRenderFrameInfo; + RateCounter<> _stutterRate; - bool _disablePreview{ true }; + bool _disablePreview { true }; private: ivec4 getViewportForSourceSize(const uvec2& size) const; float getLeftCenterPixel() const; diff --git a/plugins/oculus/src/OculusDisplayPlugin.cpp b/plugins/oculus/src/OculusDisplayPlugin.cpp index 415965e948..143204be17 100644 --- a/plugins/oculus/src/OculusDisplayPlugin.cpp +++ b/plugins/oculus/src/OculusDisplayPlugin.cpp @@ -146,6 +146,16 @@ void OculusDisplayPlugin::hmdPresent() { if (!OVR_SUCCESS(result)) { logWarning("Failed to present"); } + + static int droppedFrames = 0; + ovrPerfStats perfStats; + ovr_GetPerfStats(_session, &perfStats); + for (int i = 0; i < perfStats.FrameStatsCount; ++i) { + const auto& frameStats = perfStats.FrameStats[i]; + int delta = frameStats.CompositorDroppedFrameCount - droppedFrames; + _stutterRate.increment(delta); + droppedFrames = frameStats.CompositorDroppedFrameCount; + } } _presentRate.increment(); } diff --git a/plugins/openvr/src/OpenVrDisplayPlugin.cpp b/plugins/openvr/src/OpenVrDisplayPlugin.cpp index e300ad3ece..7f0ac4d5e0 100644 --- a/plugins/openvr/src/OpenVrDisplayPlugin.cpp +++ b/plugins/openvr/src/OpenVrDisplayPlugin.cpp @@ -708,7 +708,3 @@ bool OpenVrDisplayPlugin::isKeyboardVisible() { int OpenVrDisplayPlugin::getRequiredThreadCount() const { return Parent::getRequiredThreadCount() + (_threadedSubmit ? 1 : 0); } - -float OpenVrDisplayPlugin::stutterRate() const { - return _stutterRate.rate(); -} diff --git a/plugins/openvr/src/OpenVrDisplayPlugin.h b/plugins/openvr/src/OpenVrDisplayPlugin.h index 0f4c5a6320..3403bae27c 100644 --- a/plugins/openvr/src/OpenVrDisplayPlugin.h +++ b/plugins/openvr/src/OpenVrDisplayPlugin.h @@ -58,8 +58,6 @@ public: // Possibly needs an additional thread for VR submission int getRequiredThreadCount() const override; - float stutterRate() const override; - protected: bool internalActivate() override; void internalDeactivate() override; @@ -79,7 +77,6 @@ private: vr::HmdMatrix34_t _lastGoodHMDPose; mat4 _sensorResetMat; bool _threadedSubmit { true }; - RateCounter<> _stutterRate; CompositeInfo::Array _compositeInfos; size_t _renderingIndex { 0 }; From edb8d145070a9a51b6fa00ed69ec61503a531b02 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Fri, 11 Nov 2016 10:18:16 -0800 Subject: [PATCH 31/59] Add ac address whitelist to domain server settings --- domain-server/resources/describe-settings.json | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/domain-server/resources/describe-settings.json b/domain-server/resources/describe-settings.json index e6663888b4..12e2c51a2c 100644 --- a/domain-server/resources/describe-settings.json +++ b/domain-server/resources/describe-settings.json @@ -388,6 +388,23 @@ "default": "", "advanced": false }, + { + "name": "ac_address_whitelist", + "label": "Assignment Client IP address Whitelist", + "type": "table", + "can_add_new_rows": true, + "help": "IP addresses of Assignment Clients that can connect to your domain server. Local ACs (localhost) are always permitted and do not need to be added here.", + "numbered": false, + "advanced": true, + "columns": [ + { + "name": "ip", + "label": "IP Address", + "type": "ip", + "can_set": true + } + ] + }, { "name": "standard_permissions", "type": "table", From 63cfbf55ca0478e72455b77269a2d59474d898a0 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Fri, 11 Nov 2016 10:19:03 -0800 Subject: [PATCH 32/59] Add ip address whitelist processing to domain server --- domain-server/src/DomainServer.cpp | 36 ++++++++++++++++++++++++++++++ domain-server/src/DomainServer.h | 5 +++++ 2 files changed, 41 insertions(+) diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index d13f9b883f..6766290440 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -158,6 +158,42 @@ DomainServer::DomainServer(int argc, char* argv[]) : qDebug() << "domain-server is running"; + static const SubnetMask LOCALHOST_MASK { QHostAddress("127.0.0.1"), 32 }; + + this->_acIPAddressWhitelist = { LOCALHOST_MASK }; + + _settingsManager.getWhitelistAssignmentClientAddresses(); + auto whitelist = _settingsManager.valueOrDefaultValueForKeyPath("security.ac_address_whitelist").toStringList(); + for (auto& mask : whitelist) { + auto maskParts = mask.trimmed().split("/"); + + if (maskParts.size() > 2) { + qDebug() << "Ignoring ip in whitelist, malformed: " << mask; + continue; + } + + // The default netmask is 32 if one has not been specified, which will + // match only the ip provided. + int netmask = 32; + + if (maskParts.size() == 2) { + bool ok; + netmask = maskParts[1].toInt(&ok); + if (!ok) { + qDebug() << "Ignoring ip in whitelist, bad netmask: " << mask; + continue; + } + } + + auto ip = QHostAddress(maskParts[0]); + + if (!ip.isNull()) { + qDebug() << "Adding AC whitelist IP: " << mask << " -> " << (ip.toString() + "/" + QString::number(netmask)); + _acIPAddressWhitelist.push_back({ ip , netmask }); + } else { + qDebug() << "Ignoring ip in whitelist, invalid ip: " << mask; + } + } } void DomainServer::parseCommandLine() { diff --git a/domain-server/src/DomainServer.h b/domain-server/src/DomainServer.h index c14ec5eee0..34c408b621 100644 --- a/domain-server/src/DomainServer.h +++ b/domain-server/src/DomainServer.h @@ -36,6 +36,9 @@ typedef QSharedPointer SharedAssignmentPointer; typedef QMultiHash TransactionHash; +using SubnetMask = QPair; +using SubnetMaskList = std::vector>; + class DomainServer : public QCoreApplication, public HTTPSRequestHandler { Q_OBJECT public: @@ -156,6 +159,8 @@ private: void setupGroupCacheRefresh(); + SubnetMaskList _acIPAddressWhitelist; + DomainGatekeeper _gatekeeper; HTTPManager _httpManager; From ca6a74d63d1fa02cc89921aaa00bb2630f080508 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Fri, 11 Nov 2016 10:19:46 -0800 Subject: [PATCH 33/59] Add whitelist filtering to assignment requests --- domain-server/src/DomainServer.cpp | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index 6766290440..722ffc6a74 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -1037,6 +1037,23 @@ void DomainServer::processRequestAssignmentPacket(QSharedPointergetSenderSockAddr().getAddress(); + + auto isHostAddressInSubnet = [&senderAddr](const SubnetMask& mask) -> bool { + return senderAddr.isInSubnet(mask); + }; + + auto it = find_if(_acIPAddressWhitelist.begin(), _acIPAddressWhitelist.end(), isHostAddressInSubnet); + if (it != _acIPAddressWhitelist.end()) { + auto maskString = it->first.toString() + "/" + QString::number(it->second); + qDebug() << "Received connection from whitelisted ip: " << senderAddr.toString() + << ", matches subnet mask: " << maskString; + } else { + qDebug() << "Received an assignment connect request from a disallowed ip address: " + << senderAddr; + return; + } + // Suppress these for Assignment::AgentType to once per 5 seconds static QElapsedTimer noisyMessageTimer; static bool wasNoisyTimerStarted = false; From e1466c0d47d85c071449176e2caa740675bda8c4 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Fri, 11 Nov 2016 10:21:58 -0800 Subject: [PATCH 34/59] Fix NULL -> nullptr --- libraries/shared/src/HifiConfigVariantMap.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/shared/src/HifiConfigVariantMap.cpp b/libraries/shared/src/HifiConfigVariantMap.cpp index 252079f182..a1be6db448 100644 --- a/libraries/shared/src/HifiConfigVariantMap.cpp +++ b/libraries/shared/src/HifiConfigVariantMap.cpp @@ -226,5 +226,5 @@ QVariant* valueForKeyPath(QVariantMap& variantMap, const QString& keyPath, bool shouldCreateIfMissing); } - return NULL; + return nullptr; } From d691aa3302053bce7b58efbcb37c38027c12ecc0 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Fri, 11 Nov 2016 10:32:45 -0800 Subject: [PATCH 35/59] Update naming for subnet whitelist in ds --- domain-server/src/DomainServer.cpp | 12 ++++++------ domain-server/src/DomainServer.h | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index 722ffc6a74..8e1cabe149 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -158,9 +158,9 @@ DomainServer::DomainServer(int argc, char* argv[]) : qDebug() << "domain-server is running"; - static const SubnetMask LOCALHOST_MASK { QHostAddress("127.0.0.1"), 32 }; + static const Subnet LOCALHOST { QHostAddress("127.0.0.1"), 32 }; - this->_acIPAddressWhitelist = { LOCALHOST_MASK }; + this->_acSubnetWhitelist = { LOCALHOST }; _settingsManager.getWhitelistAssignmentClientAddresses(); auto whitelist = _settingsManager.valueOrDefaultValueForKeyPath("security.ac_address_whitelist").toStringList(); @@ -189,7 +189,7 @@ DomainServer::DomainServer(int argc, char* argv[]) : if (!ip.isNull()) { qDebug() << "Adding AC whitelist IP: " << mask << " -> " << (ip.toString() + "/" + QString::number(netmask)); - _acIPAddressWhitelist.push_back({ ip , netmask }); + _acSubnetWhitelist.push_back({ ip , netmask }); } else { qDebug() << "Ignoring ip in whitelist, invalid ip: " << mask; } @@ -1039,12 +1039,12 @@ void DomainServer::processRequestAssignmentPacket(QSharedPointergetSenderSockAddr().getAddress(); - auto isHostAddressInSubnet = [&senderAddr](const SubnetMask& mask) -> bool { + auto isHostAddressInSubnet = [&senderAddr](const Subnet& mask) -> bool { return senderAddr.isInSubnet(mask); }; - auto it = find_if(_acIPAddressWhitelist.begin(), _acIPAddressWhitelist.end(), isHostAddressInSubnet); - if (it != _acIPAddressWhitelist.end()) { + auto it = find_if(_acSubnetWhitelist.begin(), _acSubnetWhitelist.end(), isHostAddressInSubnet); + if (it != _acSubnetWhitelist.end()) { auto maskString = it->first.toString() + "/" + QString::number(it->second); qDebug() << "Received connection from whitelisted ip: " << senderAddr.toString() << ", matches subnet mask: " << maskString; diff --git a/domain-server/src/DomainServer.h b/domain-server/src/DomainServer.h index 34c408b621..73135695eb 100644 --- a/domain-server/src/DomainServer.h +++ b/domain-server/src/DomainServer.h @@ -36,8 +36,8 @@ typedef QSharedPointer SharedAssignmentPointer; typedef QMultiHash TransactionHash; -using SubnetMask = QPair; -using SubnetMaskList = std::vector>; +using Subnet = QPair; +using SubnetList = std::vector; class DomainServer : public QCoreApplication, public HTTPSRequestHandler { Q_OBJECT @@ -159,7 +159,7 @@ private: void setupGroupCacheRefresh(); - SubnetMaskList _acIPAddressWhitelist; + SubnetList _acSubnetWhitelist; DomainGatekeeper _gatekeeper; From bd1bcaf1a426733c039c892fe16d60f3eb7f9ef5 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Fri, 11 Nov 2016 10:38:56 -0800 Subject: [PATCH 36/59] Clean up subnet whitelist implementation --- domain-server/src/DomainServer.cpp | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index 8e1cabe149..d8420c580c 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -158,17 +158,17 @@ DomainServer::DomainServer(int argc, char* argv[]) : qDebug() << "domain-server is running"; - static const Subnet LOCALHOST { QHostAddress("127.0.0.1"), 32 }; + static const QString AC_SUBNET_WHITELIST_SETTING_PATH = "security.ac_subnet_whitelist"; + static const Subnet LOCALHOST { QHostAddress("127.0.0.1"), 32 }; this->_acSubnetWhitelist = { LOCALHOST }; - _settingsManager.getWhitelistAssignmentClientAddresses(); - auto whitelist = _settingsManager.valueOrDefaultValueForKeyPath("security.ac_address_whitelist").toStringList(); - for (auto& mask : whitelist) { - auto maskParts = mask.trimmed().split("/"); + auto whitelist = _settingsManager.valueOrDefaultValueForKeyPath(AC_SUBNET_WHITELIST_SETTING_PATH).toStringList(); + for (auto& subnet : whitelist) { + auto netmaskParts = subnet.trimmed().split("/"); - if (maskParts.size() > 2) { - qDebug() << "Ignoring ip in whitelist, malformed: " << mask; + if (netmaskParts.size() > 2) { + qDebug() << "Ignoring subnet in whitelist, malformed: " << subnet; continue; } @@ -176,22 +176,22 @@ DomainServer::DomainServer(int argc, char* argv[]) : // match only the ip provided. int netmask = 32; - if (maskParts.size() == 2) { + if (netmaskParts.size() == 2) { bool ok; - netmask = maskParts[1].toInt(&ok); + netmask = netmaskParts[1].toInt(&ok); if (!ok) { - qDebug() << "Ignoring ip in whitelist, bad netmask: " << mask; + qDebug() << "Ignoring subnet in whitelist, bad netmask: " << subnet; continue; } } - auto ip = QHostAddress(maskParts[0]); + auto ip = QHostAddress(netmaskParts[0]); if (!ip.isNull()) { - qDebug() << "Adding AC whitelist IP: " << mask << " -> " << (ip.toString() + "/" + QString::number(netmask)); + qDebug() << "Adding AC whitelist subnet: " << subnet << " -> " << (ip.toString() + "/" + QString::number(netmask)); _acSubnetWhitelist.push_back({ ip , netmask }); } else { - qDebug() << "Ignoring ip in whitelist, invalid ip: " << mask; + qDebug() << "Ignoring subnet in whitelist, invalid ip portion: " << subnet; } } } From 969cbf4cb0160e4ee2e1b36cb8d3e513826d29df Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Fri, 11 Nov 2016 10:46:36 -0800 Subject: [PATCH 37/59] Update domain server subnet whitelist description --- domain-server/resources/describe-settings.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/domain-server/resources/describe-settings.json b/domain-server/resources/describe-settings.json index 12e2c51a2c..a2a0c56648 100644 --- a/domain-server/resources/describe-settings.json +++ b/domain-server/resources/describe-settings.json @@ -389,11 +389,11 @@ "advanced": false }, { - "name": "ac_address_whitelist", + "name": "ac_subnet_whitelist", "label": "Assignment Client IP address Whitelist", "type": "table", "can_add_new_rows": true, - "help": "IP addresses of Assignment Clients that can connect to your domain server. Local ACs (localhost) are always permitted and do not need to be added here.", + "help": "The IP addresses or subnets of ACs that can connect to this server. You can specify an IP address or a subnet in CIDR notation ('A.B.C.D/E', Example: '10.0.0.0/24'). Local ACs (localhost) are always permitted and do not need to be added here.", "numbered": false, "advanced": true, "columns": [ From 3d7e0758972f32f9b6dc1c701468c7dd294efa23 Mon Sep 17 00:00:00 2001 From: David Kelly Date: Fri, 11 Nov 2016 11:18:24 -0800 Subject: [PATCH 38/59] Added mute to mod.js script --- scripts/system/assets/images/mute-target.svg | 33 ++++++++++ scripts/system/mod.js | 66 +++++++++++++++----- 2 files changed, 83 insertions(+), 16 deletions(-) create mode 100755 scripts/system/assets/images/mute-target.svg diff --git a/scripts/system/assets/images/mute-target.svg b/scripts/system/assets/images/mute-target.svg new file mode 100755 index 0000000000..1ed642c79e --- /dev/null +++ b/scripts/system/assets/images/mute-target.svg @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/scripts/system/mod.js b/scripts/system/mod.js index ea9355e376..f94be98406 100644 --- a/scripts/system/mod.js +++ b/scripts/system/mod.js @@ -52,7 +52,9 @@ function removeOverlays() { for (var i = 0; i < modOverlayKeys.length; ++i) { var avatarID = modOverlayKeys[i]; - Overlays.deleteOverlay(modOverlays[avatarID]); + for (var j = 0; j < modOverlays[avatarID].length; ++j) { + Overlays.deleteOverlay(modOverlays[avatarID][j]); + } } modOverlays = {}; @@ -74,10 +76,14 @@ function buttonClicked(){ button.clicked.connect(buttonClicked); -function overlayURL() { +function kickOverlayURL() { return ASSETS_PATH + "/images/" + (Users.canKick ? "kick-target.svg" : "ignore-target.svg"); } +function muteOverlayURL() { + return ASSETS_PATH + "/images/" + "mute-target.svg"; +} + function updateOverlays() { if (isShowingOverlays) { @@ -101,20 +107,28 @@ function updateOverlays() { } // setup a position for the overlay that is just above this avatar's head - var overlayPosition = avatar.getJointPosition("Head"); - overlayPosition.y += 0.45; + var kickOverlayPosition = avatar.getJointPosition("Head"); + kickOverlayPosition.y += 0.45; + var muteOverlayPosition = avatar.getJointPosition("Head"); + muteOverlayPosition.y += 0.70; if (avatarID in modOverlays) { // keep the overlay above the current position of this avatar - Overlays.editOverlay(modOverlays[avatarID], { - position: overlayPosition, - url: overlayURL() + Overlays.editOverlay(modOverlays[avatarID][0], { + position: kickOverlayPosition, + url: kickOverlayURL() }); + if (Users.canKick) { + Overlays.editOverlay(modOverlays[avatarID][1], { + position: muteOverlayPosition, + url: muteOverlayURL() + }); + } } else { // add the overlay above this avatar - var newOverlay = Overlays.addOverlay("image3d", { - url: overlayURL(), - position: overlayPosition, + var newKickOverlay = Overlays.addOverlay("image3d", { + url: kickOverlayURL(), + position: kickOverlayPosition, size: 1, scale: 0.4, color: { red: 255, green: 255, blue: 255}, @@ -123,9 +137,24 @@ function updateOverlays() { isFacingAvatar: true, drawInFront: true }); - - // push this overlay to our array of overlays - modOverlays[avatarID] = newOverlay; + + modOverlays[avatarID]=[newKickOverlay]; + + if (Users.canKick) { + var newMuteOverlay = Overlays.addOverlay("image3d", { + url: muteOverlayURL(), + position: muteOverlayPosition, + size: 1, + scale: 0.4, + color: { red: 255, green: 255, blue: 255}, + alpha: 1, + solid: true, + isFacingAvatar: true, + drawInFront: true + }); + // push this overlay to our array of overlays + modOverlays[avatarID].push(newMuteOverlay); + } } } } @@ -138,7 +167,9 @@ AvatarList.avatarRemovedEvent.connect(function(avatarID){ // we are currently showing overlays and an avatar just went away // first remove the rendered overlay - Overlays.deleteOverlay(modOverlays[avatarID]); + for (var overlay in modOverlays[avatarID]) { + Overlays.deleteOverlay(overlay); + } // delete the saved ID of the overlay from our mod overlays object delete modOverlays[avatarID]; @@ -151,7 +182,8 @@ function handleSelectedOverlay(clickedOverlay) { var modOverlayKeys = Object.keys(modOverlays); for (var i = 0; i < modOverlayKeys.length; ++i) { var avatarID = modOverlayKeys[i]; - var modOverlay = modOverlays[avatarID]; + var modOverlay = modOverlays[avatarID][0]; + var muteOverlay = modOverlays[avatarID][1]; if (clickedOverlay.overlayID == modOverlay) { // matched to an overlay, ask for the matching avatar to be kicked or ignored @@ -160,8 +192,10 @@ function handleSelectedOverlay(clickedOverlay) { } else { Users.ignore(avatarID); } - // cleanup of the overlay is handled by the connection to avatarRemovedEvent + + } else if (muteOverlay && clickedOverlay.overlayID == muteOverlay) { + Users.mute(avatarID); } } } From 96f6cb7ae4d08acfde700498bb9d7ed9b299210e Mon Sep 17 00:00:00 2001 From: David Kelly Date: Fri, 11 Nov 2016 11:24:06 -0800 Subject: [PATCH 39/59] whitespace --- domain-server/src/DomainServer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index 70ee41e934..d13f9b883f 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -498,7 +498,7 @@ void DomainServer::setupNodeListAndAssignments() { // NodeList won't be available to the settings manager when it is created, so call registerListener here packetReceiver.registerListener(PacketType::DomainSettingsRequest, &_settingsManager, "processSettingsRequestPacket"); packetReceiver.registerListener(PacketType::NodeKickRequest, &_settingsManager, "processNodeKickRequestPacket"); - + // register the gatekeeper for the packets it needs to receive packetReceiver.registerListener(PacketType::DomainConnectRequest, &_gatekeeper, "processConnectRequestPacket"); packetReceiver.registerListener(PacketType::ICEPing, &_gatekeeper, "processICEPingPacket"); From d522d03bd252316a9daac6590d3b0d08d0b4f236 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Fri, 11 Nov 2016 11:29:52 -0800 Subject: [PATCH 40/59] Add repeated message suppression to request assignment packets --- domain-server/src/DomainServer.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index d8420c580c..e95379adb9 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -1045,12 +1045,16 @@ void DomainServer::processRequestAssignmentPacket(QSharedPointerfirst.toString() + "/" + QString::number(it->second); - qDebug() << "Received connection from whitelisted ip: " << senderAddr.toString() - << ", matches subnet mask: " << maskString; + qDebug() << "Received connection from whitelisted ip:" << senderAddr.toString() + << ", matches subnet mask:" << maskString; } else { - qDebug() << "Received an assignment connect request from a disallowed ip address: " - << senderAddr; + static QString repeatedMessage = LogHandler::getInstance().addRepeatedMessageRegex( + "Received an assignment connect request from a disallowed ip address: [^ ]+"); + qDebug() << "Received an assignment connect request from a disallowed ip address:" + << senderAddr.toString(); return; } From 0aec9400c705ffb71767699b56ae263769a491ff Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Fri, 11 Nov 2016 12:54:19 -0800 Subject: [PATCH 41/59] Fix buffer count in stats display --- interface/resources/qml/Stats.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/resources/qml/Stats.qml b/interface/resources/qml/Stats.qml index 9c55b1ce2d..ce3f2a56db 100644 --- a/interface/resources/qml/Stats.qml +++ b/interface/resources/qml/Stats.qml @@ -241,7 +241,7 @@ Item { text: "GPU Buffers: " } StatText { - text: " Count: " + root.gpuTextures; + text: " Count: " + root.gpuBuffers; } StatText { text: " Memory: " + root.gpuBufferMemory; From e177004d7178f7beef205f3bd3eb56e5c44d2805 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Fri, 11 Nov 2016 14:23:16 -0800 Subject: [PATCH 42/59] Fix ds not restarting when changing ac whitelist --- domain-server/src/DomainServerSettingsManager.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/domain-server/src/DomainServerSettingsManager.cpp b/domain-server/src/DomainServerSettingsManager.cpp index c7944bbcad..f460ddd115 100644 --- a/domain-server/src/DomainServerSettingsManager.cpp +++ b/domain-server/src/DomainServerSettingsManager.cpp @@ -1077,6 +1077,9 @@ QJsonObject DomainServerSettingsManager::settingDescriptionFromGroup(const QJson } bool DomainServerSettingsManager::recurseJSONObjectAndOverwriteSettings(const QJsonObject& postedObject) { + static const QString SECURITY_ROOT_KEY = "security"; + static const QString AC_SUBNET_WHITELIST_KEY = "ac_subnet_whitelist"; + auto& settingsVariant = _configMap.getConfig(); bool needRestart = false; @@ -1127,7 +1130,7 @@ bool DomainServerSettingsManager::recurseJSONObjectAndOverwriteSettings(const QJ if (!matchingDescriptionObject.isEmpty()) { updateSetting(rootKey, rootValue, *thisMap, matchingDescriptionObject); - if (rootKey != "security") { + if (rootKey != SECURITY_ROOT_KEY) { needRestart = true; } } else { @@ -1143,7 +1146,7 @@ bool DomainServerSettingsManager::recurseJSONObjectAndOverwriteSettings(const QJ if (!matchingDescriptionObject.isEmpty()) { QJsonValue settingValue = rootValue.toObject()[settingKey]; updateSetting(settingKey, settingValue, *thisMap, matchingDescriptionObject); - if (rootKey != "security") { + if (rootKey != SECURITY_ROOT_KEY || settingKey == AC_SUBNET_WHITELIST_KEY) { needRestart = true; } } else { From 6063a63f4466ed5b8fc42e2293f249908b27ced7 Mon Sep 17 00:00:00 2001 From: David Kelly Date: Fri, 11 Nov 2016 14:23:59 -0800 Subject: [PATCH 43/59] cr feedback --- assignment-client/src/audio/AudioMixer.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/assignment-client/src/audio/AudioMixer.cpp b/assignment-client/src/audio/AudioMixer.cpp index b0a739caba..90c5d32449 100644 --- a/assignment-client/src/audio/AudioMixer.cpp +++ b/assignment-client/src/audio/AudioMixer.cpp @@ -96,7 +96,6 @@ AudioMixer::AudioMixer(ReceivedMessage& message) : packetReceiver.registerListener(PacketType::KillAvatar, this, "handleKillAvatarPacket"); packetReceiver.registerListener(PacketType::NodeMuteRequest, this, "handleNodeMuteRequestPacket"); - nodeList->addNodeTypeToInterestSet(NodeType::DomainServer); connect(nodeList.data(), &NodeList::nodeKilled, this, &AudioMixer::handleNodeKilled); } @@ -610,7 +609,6 @@ void AudioMixer::handleNodeMuteRequestPacket(QSharedPointer pac // we need to set a flag so we send them the appropriate packet to mute them AudioMixerClientData* nodeData = (AudioMixerClientData*)node->getLinkedData(); nodeData->setShouldMuteClient(true); - } else { qWarning() << "Node mute packet received for unknown node " << uuidStringWithoutCurlyBraces(nodeUUID); } From fc1a7255f6d7cebbcd2074338c13d3ed8fd479d4 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Fri, 11 Nov 2016 14:24:28 -0800 Subject: [PATCH 44/59] Remove unneeded 'this->' --- domain-server/src/DomainServer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index e95379adb9..73dfc3a277 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -161,7 +161,7 @@ DomainServer::DomainServer(int argc, char* argv[]) : static const QString AC_SUBNET_WHITELIST_SETTING_PATH = "security.ac_subnet_whitelist"; static const Subnet LOCALHOST { QHostAddress("127.0.0.1"), 32 }; - this->_acSubnetWhitelist = { LOCALHOST }; + _acSubnetWhitelist = { LOCALHOST }; auto whitelist = _settingsManager.valueOrDefaultValueForKeyPath(AC_SUBNET_WHITELIST_SETTING_PATH).toStringList(); for (auto& subnet : whitelist) { From a38846aeed9467ccb3283930840fa48a1e285c14 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Fri, 11 Nov 2016 11:51:08 -0800 Subject: [PATCH 45/59] Protect against empty packet lists --- libraries/networking/src/udt/Socket.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/libraries/networking/src/udt/Socket.cpp b/libraries/networking/src/udt/Socket.cpp index 98cc62bdee..d2583dce72 100644 --- a/libraries/networking/src/udt/Socket.cpp +++ b/libraries/networking/src/udt/Socket.cpp @@ -165,6 +165,12 @@ qint64 Socket::writePacketList(std::unique_ptr packetList, const Hif // hand this packetList off to writeReliablePacketList // because Qt can't invoke with the unique_ptr we have to release it here and re-construct in writeReliablePacketList + if (packetList->getNumPackets() == 0) { + qCWarning(networking) << "Trying to send packet list with 0 packets, bailing."; + return 0; + } + + if (QThread::currentThread() != thread()) { auto ptr = packetList.release(); QMetaObject::invokeMethod(this, "writeReliablePacketList", Qt::AutoConnection, From 528b8e93f00c3a6ea5ea4b0627cbf7bdd5d4fe7d Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Fri, 11 Nov 2016 14:33:34 -0800 Subject: [PATCH 46/59] Remove extraneous logging in DomainServer for whitelist --- domain-server/src/DomainServer.cpp | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index 73dfc3a277..5208cb2326 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -1044,13 +1044,7 @@ void DomainServer::processRequestAssignmentPacket(QSharedPointerfirst.toString() + "/" + QString::number(it->second); - qDebug() << "Received connection from whitelisted ip:" << senderAddr.toString() - << ", matches subnet mask:" << maskString; - } else { + if (it == _acSubnetWhitelist.end()) { static QString repeatedMessage = LogHandler::getInstance().addRepeatedMessageRegex( "Received an assignment connect request from a disallowed ip address: [^ ]+"); qDebug() << "Received an assignment connect request from a disallowed ip address:" From 92836caf57bbdd16225748ac5a2aef504293948e Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Sat, 12 Nov 2016 10:01:29 -0800 Subject: [PATCH 47/59] when creating plugins on Linux with memory-debugging enabled, use asan flags such that the shared libraries can be loaded --- cmake/macros/MemoryDebugger.cmake | 1 + 1 file changed, 1 insertion(+) diff --git a/cmake/macros/MemoryDebugger.cmake b/cmake/macros/MemoryDebugger.cmake index 7808812493..6df41257f2 100644 --- a/cmake/macros/MemoryDebugger.cmake +++ b/cmake/macros/MemoryDebugger.cmake @@ -16,6 +16,7 @@ if (HIFI_MEMORY_DEBUGGING) if (UNIX) SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -U_FORTIFY_SOURCE -fno-stack-protector -fno-omit-frame-pointer") SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libasan -static-libstdc++ -fsanitize=address") + SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libasan -static-libstdc++ -fsanitize=address") endif (UNIX) endif () endmacro(SETUP_MEMORY_DEBUGGER) From 804f25740d2799fe3d9ffa2de3c05de881a488dc Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Sun, 13 Nov 2016 10:21:27 -0800 Subject: [PATCH 48/59] these qDebugs happen too late and cause a crash --- .../src/display-plugins/OpenGLDisplayPlugin.cpp | 2 +- libraries/gpu-gl/src/gpu/gl45/GL45BackendTexture.cpp | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp index c84f6b9954..90100d93c0 100644 --- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp @@ -758,7 +758,7 @@ void OpenGLDisplayPlugin::render(std::function f) { OpenGLDisplayPlugin::~OpenGLDisplayPlugin() { - qDebug() << "Destroying OpenGLDisplayPlugin"; + // qDebug() << "Destroying OpenGLDisplayPlugin"; } void OpenGLDisplayPlugin::updateCompositeFramebuffer() { diff --git a/libraries/gpu-gl/src/gpu/gl45/GL45BackendTexture.cpp b/libraries/gpu-gl/src/gpu/gl45/GL45BackendTexture.cpp index fca809186f..0516bc6be0 100644 --- a/libraries/gpu-gl/src/gpu/gl45/GL45BackendTexture.cpp +++ b/libraries/gpu-gl/src/gpu/gl45/GL45BackendTexture.cpp @@ -285,10 +285,10 @@ GL45Texture::GL45Texture(const std::weak_ptr& backend, const Texture& } GL45Texture::~GL45Texture() { - // External textures cycle very quickly, so don't spam the log with messages about them. - if (!_gpuObject.getUsage().isExternal()) { - qCDebug(gpugl45logging) << "Destroying texture " << _id << " from source " << _source.c_str(); - } + // // External textures cycle very quickly, so don't spam the log with messages about them. + // if (!_gpuObject.getUsage().isExternal()) { + // qCDebug(gpugl45logging) << "Destroying texture " << _id << " from source " << _source.c_str(); + // } // Remove this texture from the candidate list of derezzable textures if (_transferrable) { From 9868ddd6029d69d5846e17bc6497ecd830c59f2e Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Sun, 13 Nov 2016 10:22:14 -0800 Subject: [PATCH 49/59] global/static QStrings in plugins appear to cause crashes during shutdown --- .../Basic2DWindowOpenGLDisplayPlugin.h | 2 +- .../src/display-plugins/NullDisplayPlugin.h | 2 +- .../display-plugins/hmd/DebugHmdDisplayPlugin.h | 2 +- .../stereo/InterleavedStereoDisplayPlugin.h | 2 +- .../stereo/SideBySideStereoDisplayPlugin.h | 2 +- .../src/input-plugins/KeyboardMouseDevice.cpp | 2 +- .../src/input-plugins/KeyboardMouseDevice.h | 10 +++++----- .../src/input-plugins/TouchscreenDevice.cpp | 2 +- .../src/input-plugins/TouchscreenDevice.h | 8 ++++---- libraries/plugins/src/plugins/Plugin.cpp | 2 +- libraries/plugins/src/plugins/Plugin.h | 8 ++++---- libraries/shared/src/shared/Factory.h | 6 +++--- plugins/hifiCodec/src/HiFiCodec.cpp | 2 +- plugins/hifiCodec/src/HiFiCodec.h | 6 +++--- plugins/hifiSdl2/src/Joystick.h | 2 +- plugins/hifiSdl2/src/SDL2Manager.cpp | 2 +- plugins/hifiSdl2/src/SDL2Manager.h | 16 ++++++++-------- plugins/hifiSixense/src/SixenseManager.cpp | 16 ++++++++-------- plugins/hifiSixense/src/SixenseManager.h | 8 ++++---- plugins/pcmCodec/src/PCMCodecManager.cpp | 4 ++-- plugins/pcmCodec/src/PCMCodecManager.h | 10 +++++----- 21 files changed, 57 insertions(+), 57 deletions(-) diff --git a/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.h index 2e4e57e15a..f3dd50602c 100644 --- a/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.h @@ -18,7 +18,7 @@ class Basic2DWindowOpenGLDisplayPlugin : public OpenGLDisplayPlugin { Q_OBJECT using Parent = OpenGLDisplayPlugin; public: - virtual const QString& getName() const override { return NAME; } + virtual const QString getName() const override { return NAME; } virtual float getTargetFrameRate() const override { return _framerateTarget ? (float) _framerateTarget : TARGET_FRAMERATE_Basic2DWindowOpenGL; } diff --git a/libraries/display-plugins/src/display-plugins/NullDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/NullDisplayPlugin.h index 1852ed53ee..1da0441d8f 100644 --- a/libraries/display-plugins/src/display-plugins/NullDisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/NullDisplayPlugin.h @@ -12,7 +12,7 @@ class NullDisplayPlugin : public DisplayPlugin { public: ~NullDisplayPlugin() final {} - const QString& getName() const override { return NAME; } + const QString getName() const override { return NAME; } grouping getGrouping() const override { return DEVELOPER; } glm::uvec2 getRecommendedRenderSize() const override; diff --git a/libraries/display-plugins/src/display-plugins/hmd/DebugHmdDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/hmd/DebugHmdDisplayPlugin.h index 509e13eda7..9bb82b1836 100644 --- a/libraries/display-plugins/src/display-plugins/hmd/DebugHmdDisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/hmd/DebugHmdDisplayPlugin.h @@ -13,7 +13,7 @@ class DebugHmdDisplayPlugin : public HmdDisplayPlugin { using Parent = HmdDisplayPlugin; public: - const QString& getName() const override { return NAME; } + const QString getName() const override { return NAME; } grouping getGrouping() const override { return DEVELOPER; } bool isSupported() const override; diff --git a/libraries/display-plugins/src/display-plugins/stereo/InterleavedStereoDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/stereo/InterleavedStereoDisplayPlugin.h index 8c3ebcaa6d..debd340f24 100644 --- a/libraries/display-plugins/src/display-plugins/stereo/InterleavedStereoDisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/stereo/InterleavedStereoDisplayPlugin.h @@ -13,7 +13,7 @@ class InterleavedStereoDisplayPlugin : public StereoDisplayPlugin { Q_OBJECT using Parent = StereoDisplayPlugin; public: - const QString& getName() const override { return NAME; } + const QString getName() const override { return NAME; } grouping getGrouping() const override { return ADVANCED; } glm::uvec2 getRecommendedRenderSize() const override; diff --git a/libraries/display-plugins/src/display-plugins/stereo/SideBySideStereoDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/stereo/SideBySideStereoDisplayPlugin.h index d4d20243ea..79bf2a9ecb 100644 --- a/libraries/display-plugins/src/display-plugins/stereo/SideBySideStereoDisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/stereo/SideBySideStereoDisplayPlugin.h @@ -15,7 +15,7 @@ class SideBySideStereoDisplayPlugin : public StereoDisplayPlugin { Q_OBJECT using Parent = StereoDisplayPlugin; public: - virtual const QString& getName() const override { return NAME; } + virtual const QString getName() const override { return NAME; } virtual grouping getGrouping() const override { return ADVANCED; } virtual glm::uvec2 getRecommendedRenderSize() const override; diff --git a/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.cpp b/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.cpp index c1f764f5fa..39371cc3e3 100755 --- a/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.cpp +++ b/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.cpp @@ -18,7 +18,7 @@ #include #include -const QString KeyboardMouseDevice::NAME = "Keyboard/Mouse"; +const char* KeyboardMouseDevice::NAME = "Keyboard/Mouse"; bool KeyboardMouseDevice::_enableTouch = true; void KeyboardMouseDevice::pluginUpdate(float deltaTime, const controller::InputCalibrationData& inputCalibrationData) { diff --git a/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.h b/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.h index 8177c9bcc0..399ca4e93d 100644 --- a/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.h +++ b/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.h @@ -52,21 +52,21 @@ public: MOUSE_AXIS_WHEEL_X_POS, MOUSE_AXIS_WHEEL_X_NEG, }; - + enum TouchAxisChannel { TOUCH_AXIS_X_POS = MOUSE_AXIS_WHEEL_X_NEG + 1, TOUCH_AXIS_X_NEG, TOUCH_AXIS_Y_POS, TOUCH_AXIS_Y_NEG, }; - + enum TouchButtonChannel { TOUCH_BUTTON_PRESS = TOUCH_AXIS_Y_NEG + 1, }; // Plugin functions bool isSupported() const override { return true; } - const QString& getName() const override { return NAME; } + const QString getName() const override { return NAME; } bool isHandController() const override { return false; } @@ -88,8 +88,8 @@ public: void wheelEvent(QWheelEvent* event); static void enableTouch(bool enableTouch) { _enableTouch = enableTouch; } - - static const QString NAME; + + static const char* NAME; protected: diff --git a/libraries/input-plugins/src/input-plugins/TouchscreenDevice.cpp b/libraries/input-plugins/src/input-plugins/TouchscreenDevice.cpp index 64f02b5df3..20952df4d7 100644 --- a/libraries/input-plugins/src/input-plugins/TouchscreenDevice.cpp +++ b/libraries/input-plugins/src/input-plugins/TouchscreenDevice.cpp @@ -21,7 +21,7 @@ #include #include -const QString TouchscreenDevice::NAME = "Touchscreen"; +const char* TouchscreenDevice::NAME = "Touchscreen"; bool TouchscreenDevice::isSupported() const { for (auto touchDevice : QTouchDevice::devices()) { diff --git a/libraries/input-plugins/src/input-plugins/TouchscreenDevice.h b/libraries/input-plugins/src/input-plugins/TouchscreenDevice.h index 7bfaa23be8..65e771e8f0 100644 --- a/libraries/input-plugins/src/input-plugins/TouchscreenDevice.h +++ b/libraries/input-plugins/src/input-plugins/TouchscreenDevice.h @@ -22,7 +22,7 @@ class QGestureEvent; class TouchscreenDevice : public InputPlugin { Q_OBJECT public: - + enum TouchAxisChannel { TOUCH_AXIS_X_POS = 0, TOUCH_AXIS_X_NEG, @@ -37,7 +37,7 @@ public: // Plugin functions virtual bool isSupported() const override; - virtual const QString& getName() const override { return NAME; } + virtual const QString getName() const override { return NAME; } bool isHandController() const override { return false; } @@ -48,8 +48,8 @@ public: void touchEndEvent(const QTouchEvent* event); void touchUpdateEvent(const QTouchEvent* event); void touchGestureEvent(const QGestureEvent* event); - - static const QString NAME; + + static const char* NAME; protected: diff --git a/libraries/plugins/src/plugins/Plugin.cpp b/libraries/plugins/src/plugins/Plugin.cpp index 7c30f252c9..58c71aa97c 100644 --- a/libraries/plugins/src/plugins/Plugin.cpp +++ b/libraries/plugins/src/plugins/Plugin.cpp @@ -7,7 +7,7 @@ // #include "Plugin.h" -QString Plugin::UNKNOWN_PLUGIN_ID("unknown"); +const char* Plugin::UNKNOWN_PLUGIN_ID { "unknown" }; void Plugin::setContainer(PluginContainer* container) { _container = container; diff --git a/libraries/plugins/src/plugins/Plugin.h b/libraries/plugins/src/plugins/Plugin.h index 0452c7fbfe..15588fafa4 100644 --- a/libraries/plugins/src/plugins/Plugin.h +++ b/libraries/plugins/src/plugins/Plugin.h @@ -18,7 +18,7 @@ class Plugin : public QObject { Q_OBJECT public: /// \return human-readable name - virtual const QString& getName() const = 0; + virtual const QString getName() const = 0; typedef enum { STANDARD, ADVANCED, DEVELOPER } grouping; @@ -26,10 +26,10 @@ public: virtual grouping getGrouping() const { return STANDARD; } /// \return string ID (not necessarily human-readable) - virtual const QString& getID() const { assert(false); return UNKNOWN_PLUGIN_ID; } + virtual const QString getID() const { assert(false); return UNKNOWN_PLUGIN_ID; } virtual bool isSupported() const; - + void setContainer(PluginContainer* container); /// Called when plugin is initially loaded, typically at application start @@ -74,6 +74,6 @@ signals: protected: bool _active { false }; PluginContainer* _container { nullptr }; - static QString UNKNOWN_PLUGIN_ID; + static const char* UNKNOWN_PLUGIN_ID; }; diff --git a/libraries/shared/src/shared/Factory.h b/libraries/shared/src/shared/Factory.h index 6f1da6644b..00b7787fdb 100644 --- a/libraries/shared/src/shared/Factory.h +++ b/libraries/shared/src/shared/Factory.h @@ -23,12 +23,12 @@ namespace hifi { using Builder = std::function; using BuilderMap = std::map; - void registerBuilder(const Key& name, Builder builder) { + void registerBuilder(const Key name, Builder builder) { // FIXME don't allow name collisions _builders[name] = builder; } - Pointer create(const Key& name) const { + Pointer create(const Key name) const { const auto& entryIt = _builders.find(name); if (entryIt != _builders.end()) { return (*entryIt).second(); @@ -39,7 +39,7 @@ namespace hifi { template class Registrar { public: - Registrar(const Key& name, SimpleFactory& factory) { + Registrar(const Key name, SimpleFactory& factory) { factory.registerBuilder(name, [] { return std::make_shared(); }); } }; diff --git a/plugins/hifiCodec/src/HiFiCodec.cpp b/plugins/hifiCodec/src/HiFiCodec.cpp index 4e9336ff90..77c369dcae 100644 --- a/plugins/hifiCodec/src/HiFiCodec.cpp +++ b/plugins/hifiCodec/src/HiFiCodec.cpp @@ -18,7 +18,7 @@ #include "HiFiCodec.h" -const QString HiFiCodec::NAME = "hifiAC"; +const char* HiFiCodec::NAME { "hifiAC" }; void HiFiCodec::init() { } diff --git a/plugins/hifiCodec/src/HiFiCodec.h b/plugins/hifiCodec/src/HiFiCodec.h index eeba8d56d8..09b247ff7e 100644 --- a/plugins/hifiCodec/src/HiFiCodec.h +++ b/plugins/hifiCodec/src/HiFiCodec.h @@ -16,11 +16,11 @@ class HiFiCodec : public CodecPlugin { Q_OBJECT - + public: // Plugin functions bool isSupported() const override; - const QString& getName() const override { return NAME; } + const QString getName() const override { return NAME; } void init() override; void deinit() override; @@ -36,7 +36,7 @@ public: virtual void releaseDecoder(Decoder* decoder) override; private: - static const QString NAME; + static const char* NAME; }; #endif // hifi_HiFiCodec_h diff --git a/plugins/hifiSdl2/src/Joystick.h b/plugins/hifiSdl2/src/Joystick.h index a10e02d325..7ea17739e3 100644 --- a/plugins/hifiSdl2/src/Joystick.h +++ b/plugins/hifiSdl2/src/Joystick.h @@ -29,7 +29,7 @@ class Joystick : public QObject, public controller::InputDevice { public: using Pointer = std::shared_ptr; - const QString& getName() const { return _name; } + const QString getName() const { return _name; } SDL_GameController* getGameController() { return _sdlGameController; } diff --git a/plugins/hifiSdl2/src/SDL2Manager.cpp b/plugins/hifiSdl2/src/SDL2Manager.cpp index b6fa567aee..5ab5758412 100644 --- a/plugins/hifiSdl2/src/SDL2Manager.cpp +++ b/plugins/hifiSdl2/src/SDL2Manager.cpp @@ -41,7 +41,7 @@ static_assert( "SDL2 equvalence: Enums and values from StandardControls.h are assumed to match enums from SDL_gamecontroller.h"); -const QString SDL2Manager::NAME = "SDL2"; +const char* SDL2Manager::NAME = "SDL2"; SDL_JoystickID SDL2Manager::getInstanceId(SDL_GameController* controller) { SDL_Joystick* joystick = SDL_GameControllerGetJoystick(controller); diff --git a/plugins/hifiSdl2/src/SDL2Manager.h b/plugins/hifiSdl2/src/SDL2Manager.h index fc1654bce1..4501d0792b 100644 --- a/plugins/hifiSdl2/src/SDL2Manager.h +++ b/plugins/hifiSdl2/src/SDL2Manager.h @@ -20,11 +20,11 @@ class SDL2Manager : public InputPlugin { Q_OBJECT - + public: // Plugin functions bool isSupported() const override; - const QString& getName() const override { return NAME; } + const QString getName() const override { return NAME; } QStringList getSubdeviceNames() override; bool isHandController() const override { return false; } @@ -39,14 +39,14 @@ public: void pluginFocusOutEvent() override; void pluginUpdate(float deltaTime, const controller::InputCalibrationData& inputCalibrationData) override; - + signals: void joystickAdded(Joystick* joystick); void joystickRemoved(Joystick* joystick); - + private: SDL_JoystickID getInstanceId(SDL_GameController* controller); - + int axisInvalid() const { return SDL_CONTROLLER_AXIS_INVALID; } int axisLeftX() const { return SDL_CONTROLLER_AXIS_LEFTX; } int axisLeftY() const { return SDL_CONTROLLER_AXIS_LEFTY; } @@ -55,7 +55,7 @@ private: int axisTriggerLeft() const { return SDL_CONTROLLER_AXIS_TRIGGERLEFT; } int axisTriggerRight() const { return SDL_CONTROLLER_AXIS_TRIGGERRIGHT; } int axisMax() const { return SDL_CONTROLLER_AXIS_MAX; } - + int buttonInvalid() const { return SDL_CONTROLLER_BUTTON_INVALID; } int buttonFaceBottom() const { return SDL_CONTROLLER_BUTTON_A; } int buttonFaceRight() const { return SDL_CONTROLLER_BUTTON_B; } @@ -73,13 +73,13 @@ private: int buttonDpadLeft() const { return SDL_CONTROLLER_BUTTON_DPAD_LEFT; } int buttonDpadRight() const { return SDL_CONTROLLER_BUTTON_DPAD_RIGHT; } int buttonMax() const { return SDL_CONTROLLER_BUTTON_MAX; } - + int buttonPressed() const { return SDL_PRESSED; } int buttonRelease() const { return SDL_RELEASED; } QMap _openJoysticks; bool _isInitialized { false } ; - static const QString NAME; + static const char* NAME; QStringList _subdeviceNames; }; diff --git a/plugins/hifiSixense/src/SixenseManager.cpp b/plugins/hifiSixense/src/SixenseManager.cpp index baf13f1fae..7d443bd50d 100644 --- a/plugins/hifiSixense/src/SixenseManager.cpp +++ b/plugins/hifiSixense/src/SixenseManager.cpp @@ -55,15 +55,15 @@ bool SixenseManager::_sixenseLoaded = false; -const QString SixenseManager::NAME = "Sixense"; -const QString SixenseManager::HYDRA_ID_STRING = "Razer Hydra"; +const char* SixenseManager::NAME { "Sixense" }; +const char* SixenseManager::HYDRA_ID_STRING { "Razer Hydra" }; -const QString MENU_PARENT = "Developer"; -const QString MENU_NAME = "Sixense"; -const QString MENU_PATH = MENU_PARENT + ">" + MENU_NAME; -const QString TOGGLE_SMOOTH = "Smooth Sixense Movement"; -const QString SHOW_DEBUG_RAW = "Debug Draw Raw Data"; -const QString SHOW_DEBUG_CALIBRATED = "Debug Draw Calibrated Data"; +const char* MENU_PARENT { "Developer" }; +const char* MENU_NAME { "Sixense" }; +const char* MENU_PATH { "Developer" ">" "Sixense" }; +const char* TOGGLE_SMOOTH { "Smooth Sixense Movement" }; +const char* SHOW_DEBUG_RAW { "Debug Draw Raw Data" }; +const char* SHOW_DEBUG_CALIBRATED { "Debug Draw Calibrated Data" }; bool SixenseManager::isSupported() const { #if defined(HAVE_SIXENSE) && !defined(Q_OS_OSX) diff --git a/plugins/hifiSixense/src/SixenseManager.h b/plugins/hifiSixense/src/SixenseManager.h index c77569474e..5237dba791 100644 --- a/plugins/hifiSixense/src/SixenseManager.h +++ b/plugins/hifiSixense/src/SixenseManager.h @@ -28,8 +28,8 @@ class SixenseManager : public InputPlugin { public: // Plugin functions virtual bool isSupported() const override; - virtual const QString& getName() const override { return NAME; } - virtual const QString& getID() const override { return HYDRA_ID_STRING; } + virtual const QString getName() const override { return NAME; } + virtual const QString getID() const override { return HYDRA_ID_STRING; } // Sixense always seems to initialize even if the hydras are not present. Is there // a way we can properly detect whether the hydras are present? @@ -92,8 +92,8 @@ private: std::shared_ptr _inputDevice { std::make_shared() }; - static const QString NAME; - static const QString HYDRA_ID_STRING; + static const char* NAME; + static const char* HYDRA_ID_STRING; static bool _sixenseLoaded; }; diff --git a/plugins/pcmCodec/src/PCMCodecManager.cpp b/plugins/pcmCodec/src/PCMCodecManager.cpp index 315d0622ab..7278edaf92 100644 --- a/plugins/pcmCodec/src/PCMCodecManager.cpp +++ b/plugins/pcmCodec/src/PCMCodecManager.cpp @@ -15,7 +15,7 @@ #include "PCMCodecManager.h" -const QString PCMCodec::NAME = "pcm"; +const char* PCMCodec::NAME { "pcm" }; void PCMCodec::init() { } @@ -55,7 +55,7 @@ void PCMCodec::releaseDecoder(Decoder* decoder) { // do nothing } -const QString zLibCodec::NAME = "zlib"; +const char* zLibCodec::NAME { "zlib" }; void zLibCodec::init() { } diff --git a/plugins/pcmCodec/src/PCMCodecManager.h b/plugins/pcmCodec/src/PCMCodecManager.h index 55d7c866f1..d58a219fef 100644 --- a/plugins/pcmCodec/src/PCMCodecManager.h +++ b/plugins/pcmCodec/src/PCMCodecManager.h @@ -16,11 +16,11 @@ class PCMCodec : public CodecPlugin, public Encoder, public Decoder { Q_OBJECT - + public: // Plugin functions bool isSupported() const override; - const QString& getName() const override { return NAME; } + const QString getName() const override { return NAME; } void init() override; void deinit() override; @@ -45,7 +45,7 @@ public: virtual void trackLostFrames(int numFrames) override { } private: - static const QString NAME; + static const char* NAME; }; class zLibCodec : public CodecPlugin, public Encoder, public Decoder { @@ -54,7 +54,7 @@ class zLibCodec : public CodecPlugin, public Encoder, public Decoder { public: // Plugin functions bool isSupported() const override; - const QString& getName() const override { return NAME; } + const QString getName() const override { return NAME; } void init() override; void deinit() override; @@ -80,7 +80,7 @@ public: virtual void trackLostFrames(int numFrames) override { } private: - static const QString NAME; + static const char* NAME; }; #endif // hifi__PCMCodecManager_h From 9b4a8427e6cfa9d3d689b01c00926d537f49adae Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Sun, 13 Nov 2016 11:09:27 -0800 Subject: [PATCH 50/59] global/static QString --- plugins/hifiNeuron/src/NeuronPlugin.cpp | 4 ++-- plugins/hifiNeuron/src/NeuronPlugin.h | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/plugins/hifiNeuron/src/NeuronPlugin.cpp b/plugins/hifiNeuron/src/NeuronPlugin.cpp index e41472a8c5..aec8bf072a 100644 --- a/plugins/hifiNeuron/src/NeuronPlugin.cpp +++ b/plugins/hifiNeuron/src/NeuronPlugin.cpp @@ -27,8 +27,8 @@ Q_LOGGING_CATEGORY(inputplugins, "hifi.inputplugins") #include -const QString NeuronPlugin::NAME = "Neuron"; -const QString NeuronPlugin::NEURON_ID_STRING = "Perception Neuron"; +const char* NeuronPlugin::NAME = "Neuron"; +const char* NeuronPlugin::NEURON_ID_STRING = "Perception Neuron"; // indices of joints of the Neuron standard skeleton. // This is 'almost' the same as the High Fidelity standard skeleton. diff --git a/plugins/hifiNeuron/src/NeuronPlugin.h b/plugins/hifiNeuron/src/NeuronPlugin.h index 576deb64ae..0e4ea4e7ff 100644 --- a/plugins/hifiNeuron/src/NeuronPlugin.h +++ b/plugins/hifiNeuron/src/NeuronPlugin.h @@ -29,7 +29,7 @@ public: // Plugin functions virtual bool isSupported() const override; - virtual const QString& getName() const override { return NAME; } + virtual const char* getName() const override { return NAME; } const QString& getID() const override { return NEURON_ID_STRING; } virtual bool activate() override; @@ -65,8 +65,8 @@ protected: std::shared_ptr _inputDevice { std::make_shared() }; - static const QString NAME; - static const QString NEURON_ID_STRING; + static const char* NAME; + static const char* NEURON_ID_STRING; std::string _serverAddress; int _serverPort; From f8fb5b970928487a58b898b1556e61a6e026af60 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Sun, 13 Nov 2016 11:29:19 -0800 Subject: [PATCH 51/59] avoid some more static/global QStrings in plugins --- plugins/hifiSpacemouse/src/SpacemouseManager.h | 6 +++--- plugins/oculus/src/OculusControllerManager.cpp | 6 +++--- plugins/oculus/src/OculusControllerManager.h | 4 ++-- plugins/oculus/src/OculusDebugDisplayPlugin.cpp | 2 +- plugins/oculus/src/OculusDebugDisplayPlugin.h | 4 ++-- plugins/oculus/src/OculusDisplayPlugin.h | 4 ++-- plugins/oculusLegacy/src/OculusLegacyDisplayPlugin.h | 6 +++--- plugins/openvr/src/OpenVrDisplayPlugin.h | 4 ++-- plugins/openvr/src/ViveControllerManager.cpp | 8 ++++---- plugins/openvr/src/ViveControllerManager.h | 4 ++-- 10 files changed, 24 insertions(+), 24 deletions(-) diff --git a/plugins/hifiSpacemouse/src/SpacemouseManager.h b/plugins/hifiSpacemouse/src/SpacemouseManager.h index a9933902e5..361a1fad2d 100644 --- a/plugins/hifiSpacemouse/src/SpacemouseManager.h +++ b/plugins/hifiSpacemouse/src/SpacemouseManager.h @@ -76,8 +76,8 @@ class SpacemouseManager : public InputPlugin, public QAbstractNativeEventFilter Q_OBJECT public: bool isSupported() const override; - const QString& getName() const override { return NAME; } - const QString& getID() const override { return NAME; } + const QString getName() const override { return NAME; } + const QString getID() const override { return NAME; } bool activate() override; void deactivate() override; @@ -127,7 +127,7 @@ private: // use to calculate distance traveled since last event DWORD fLast3dmouseInputTime; - static const QString NAME; + static const char* NAME; friend class SpacemouseDevice; }; diff --git a/plugins/oculus/src/OculusControllerManager.cpp b/plugins/oculus/src/OculusControllerManager.cpp index f0edc5a465..c9c964ec9d 100644 --- a/plugins/oculus/src/OculusControllerManager.cpp +++ b/plugins/oculus/src/OculusControllerManager.cpp @@ -25,9 +25,9 @@ Q_DECLARE_LOGGING_CATEGORY(oculus) -static const QString MENU_PARENT = "Avatar"; -static const QString MENU_NAME = "Oculus Touch Controllers"; -static const QString MENU_PATH = MENU_PARENT + ">" + MENU_NAME; +static const char* MENU_PARENT = "Avatar"; +static const char* MENU_NAME = "Oculus Touch Controllers"; +static const char* MENU_PATH = MENU_PARENT + ">" + MENU_NAME; const QString OculusControllerManager::NAME = "Oculus"; diff --git a/plugins/oculus/src/OculusControllerManager.h b/plugins/oculus/src/OculusControllerManager.h index 1ca9e0f47e..98e0e3d650 100644 --- a/plugins/oculus/src/OculusControllerManager.h +++ b/plugins/oculus/src/OculusControllerManager.h @@ -24,7 +24,7 @@ class OculusControllerManager : public InputPlugin { public: // Plugin functions bool isSupported() const override; - const QString& getName() const override { return NAME; } + const QString getName() const override { return NAME; } bool isHandController() const override { return _touch != nullptr; } QStringList getSubdeviceNames() override; @@ -95,7 +95,7 @@ private: ovrInputState _inputState {}; RemoteDevice::Pointer _remote; TouchDevice::Pointer _touch; - static const QString NAME; + static const char* NAME; }; #endif // hifi__OculusControllerManager diff --git a/plugins/oculus/src/OculusDebugDisplayPlugin.cpp b/plugins/oculus/src/OculusDebugDisplayPlugin.cpp index f1d22f3ceb..429d3ecd16 100644 --- a/plugins/oculus/src/OculusDebugDisplayPlugin.cpp +++ b/plugins/oculus/src/OculusDebugDisplayPlugin.cpp @@ -8,7 +8,7 @@ #include "OculusDebugDisplayPlugin.h" #include -const QString OculusDebugDisplayPlugin::NAME("Oculus Rift (Simulator)"); +const char* OculusDebugDisplayPlugin::NAME { "Oculus Rift (Simulator)" }; static const QString DEBUG_FLAG("HIFI_DEBUG_OCULUS"); static bool enableDebugOculus = true || QProcessEnvironment::systemEnvironment().contains("HIFI_DEBUG_OCULUS"); diff --git a/plugins/oculus/src/OculusDebugDisplayPlugin.h b/plugins/oculus/src/OculusDebugDisplayPlugin.h index 983511ba01..ec05cd92e2 100644 --- a/plugins/oculus/src/OculusDebugDisplayPlugin.h +++ b/plugins/oculus/src/OculusDebugDisplayPlugin.h @@ -11,7 +11,7 @@ class OculusDebugDisplayPlugin : public OculusBaseDisplayPlugin { public: - const QString& getName() const override { return NAME; } + const QString getName() const override { return NAME; } grouping getGrouping() const override { return DEVELOPER; } bool isSupported() const override; @@ -20,6 +20,6 @@ protected: bool isHmdMounted() const override { return true; } private: - static const QString NAME; + static const char* NAME; }; diff --git a/plugins/oculus/src/OculusDisplayPlugin.h b/plugins/oculus/src/OculusDisplayPlugin.h index 0c7d57c4f4..fce8e9e6ce 100644 --- a/plugins/oculus/src/OculusDisplayPlugin.h +++ b/plugins/oculus/src/OculusDisplayPlugin.h @@ -13,7 +13,7 @@ class OculusDisplayPlugin : public OculusBaseDisplayPlugin { using Parent = OculusBaseDisplayPlugin; public: ~OculusDisplayPlugin(); - const QString& getName() const override { return NAME; } + const QString getName() const override { return NAME; } void init() override; @@ -29,7 +29,7 @@ protected: void cycleDebugOutput() override; private: - static const QString NAME; + static const char* NAME; ovrTextureSwapChain _textureSwapChain; gpu::FramebufferPointer _outputFramebuffer; bool _customized { false }; diff --git a/plugins/oculusLegacy/src/OculusLegacyDisplayPlugin.h b/plugins/oculusLegacy/src/OculusLegacyDisplayPlugin.h index 6ffc1a7f44..20345467df 100644 --- a/plugins/oculusLegacy/src/OculusLegacyDisplayPlugin.h +++ b/plugins/oculusLegacy/src/OculusLegacyDisplayPlugin.h @@ -21,7 +21,7 @@ class OculusLegacyDisplayPlugin : public HmdDisplayPlugin { public: OculusLegacyDisplayPlugin(); bool isSupported() const override; - const QString& getName() const override { return NAME; } + const QString getName() const override { return NAME; } void init() override; @@ -41,9 +41,9 @@ protected: void uncustomizeContext() override; void hmdPresent() override; bool isHmdMounted() const override { return true; } - + private: - static const QString NAME; + static const char* NAME; GLWindow* _hmdWindow{ nullptr }; ovrHmd _hmd; diff --git a/plugins/openvr/src/OpenVrDisplayPlugin.h b/plugins/openvr/src/OpenVrDisplayPlugin.h index 3403bae27c..a60c21a606 100644 --- a/plugins/openvr/src/OpenVrDisplayPlugin.h +++ b/plugins/openvr/src/OpenVrDisplayPlugin.h @@ -36,7 +36,7 @@ class OpenVrDisplayPlugin : public HmdDisplayPlugin { using Parent = HmdDisplayPlugin; public: bool isSupported() const override; - const QString& getName() const override { return NAME; } + const QString getName() const override { return NAME; } void init() override; @@ -72,7 +72,7 @@ private: vr::IVRSystem* _system { nullptr }; std::atomic _hmdActivityLevel { vr::k_EDeviceActivityLevel_Unknown }; std::atomic _keyboardSupressionCount{ 0 }; - static const QString NAME; + static const char* NAME; vr::HmdMatrix34_t _lastGoodHMDPose; mat4 _sensorResetMat; diff --git a/plugins/openvr/src/ViveControllerManager.cpp b/plugins/openvr/src/ViveControllerManager.cpp index ff8fc64474..449bf1b85e 100644 --- a/plugins/openvr/src/ViveControllerManager.cpp +++ b/plugins/openvr/src/ViveControllerManager.cpp @@ -37,10 +37,10 @@ void releaseOpenVrSystem(); static const char* CONTROLLER_MODEL_STRING = "vr_controller_05_wireless_b"; -static const QString MENU_PARENT = "Avatar"; -static const QString MENU_NAME = "Vive Controllers"; -static const QString MENU_PATH = MENU_PARENT + ">" + MENU_NAME; -static const QString RENDER_CONTROLLERS = "Render Hand Controllers"; +static const char* MENU_PARENT = "Avatar"; +static const char* MENU_NAME = "Vive Controllers"; +static const char* MENU_PATH = "Avatar" ">" "Vive Controllers"; +static const char* RENDER_CONTROLLERS = "Render Hand Controllers"; const QString ViveControllerManager::NAME = "OpenVR"; diff --git a/plugins/openvr/src/ViveControllerManager.h b/plugins/openvr/src/ViveControllerManager.h index 5f34d70ba8..3fb166c842 100644 --- a/plugins/openvr/src/ViveControllerManager.h +++ b/plugins/openvr/src/ViveControllerManager.h @@ -33,7 +33,7 @@ class ViveControllerManager : public InputPlugin { public: // Plugin functions bool isSupported() const override; - const QString& getName() const override { return NAME; } + const QString getName() const override { return NAME; } bool isHandController() const override { return true; } @@ -125,7 +125,7 @@ private: vr::IVRSystem* _system { nullptr }; std::shared_ptr _inputDevice { std::make_shared(_system) }; - static const QString NAME; + static const char* NAME; }; #endif // hifi__ViveControllerManager From 45bcf626aadc71092030e8d9c4b9ae35a1e4c9b8 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Sun, 13 Nov 2016 11:48:49 -0800 Subject: [PATCH 52/59] try, try again --- plugins/hifiNeuron/src/NeuronPlugin.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/hifiNeuron/src/NeuronPlugin.h b/plugins/hifiNeuron/src/NeuronPlugin.h index 0e4ea4e7ff..36dcf93c23 100644 --- a/plugins/hifiNeuron/src/NeuronPlugin.h +++ b/plugins/hifiNeuron/src/NeuronPlugin.h @@ -29,8 +29,8 @@ public: // Plugin functions virtual bool isSupported() const override; - virtual const char* getName() const override { return NAME; } - const QString& getID() const override { return NEURON_ID_STRING; } + virtual const QString getName() const override { return NAME; } + const QString getID() const override { return NEURON_ID_STRING; } virtual bool activate() override; virtual void deactivate() override; From 359f05426cc25b353548602fa18e1e55bc6f5026 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Sun, 13 Nov 2016 12:14:48 -0800 Subject: [PATCH 53/59] try, try again --- plugins/oculusLegacy/src/OculusLegacyDisplayPlugin.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/oculusLegacy/src/OculusLegacyDisplayPlugin.cpp b/plugins/oculusLegacy/src/OculusLegacyDisplayPlugin.cpp index b7b6ae5768..09f3e6dc8c 100644 --- a/plugins/oculusLegacy/src/OculusLegacyDisplayPlugin.cpp +++ b/plugins/oculusLegacy/src/OculusLegacyDisplayPlugin.cpp @@ -30,7 +30,7 @@ #include "OculusHelpers.h" -const QString OculusLegacyDisplayPlugin::NAME("Oculus Rift"); +const char* OculusLegacyDisplayPlugin::NAME { "Oculus Rift" }; OculusLegacyDisplayPlugin::OculusLegacyDisplayPlugin() { } From 946dc256f092bb2c520882e3485786f63e950175 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Sun, 13 Nov 2016 12:15:35 -0800 Subject: [PATCH 54/59] try, try again --- plugins/openvr/src/ViveControllerManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/openvr/src/ViveControllerManager.cpp b/plugins/openvr/src/ViveControllerManager.cpp index 449bf1b85e..2e930c0fdc 100644 --- a/plugins/openvr/src/ViveControllerManager.cpp +++ b/plugins/openvr/src/ViveControllerManager.cpp @@ -42,7 +42,7 @@ static const char* MENU_NAME = "Vive Controllers"; static const char* MENU_PATH = "Avatar" ">" "Vive Controllers"; static const char* RENDER_CONTROLLERS = "Render Hand Controllers"; -const QString ViveControllerManager::NAME = "OpenVR"; +const char* ViveControllerManager::NAME { "OpenVR" }; bool ViveControllerManager::isSupported() const { return openVrSupported(); From 212d51810946f9a12788eb37862397947ee7c070 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Sun, 13 Nov 2016 12:17:12 -0800 Subject: [PATCH 55/59] use for loop for kick and mute overlay cleanup --- scripts/system/mod.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/scripts/system/mod.js b/scripts/system/mod.js index f94be98406..7e5cc5d2a5 100644 --- a/scripts/system/mod.js +++ b/scripts/system/mod.js @@ -137,10 +137,10 @@ function updateOverlays() { isFacingAvatar: true, drawInFront: true }); - + modOverlays[avatarID]=[newKickOverlay]; - - if (Users.canKick) { + + if (Users.canKick) { var newMuteOverlay = Overlays.addOverlay("image3d", { url: muteOverlayURL(), position: muteOverlayPosition, @@ -166,11 +166,11 @@ AvatarList.avatarRemovedEvent.connect(function(avatarID){ if (isShowingOverlays) { // we are currently showing overlays and an avatar just went away - // first remove the rendered overlay - for (var overlay in modOverlays[avatarID]) { - Overlays.deleteOverlay(overlay); + // first remove the rendered overlays + for (var j = 0; j < modOverlays[avatarID].length; ++j) { + Overlays.deleteOverlay(modOverlays[avatarID][j]); } - + // delete the saved ID of the overlay from our mod overlays object delete modOverlays[avatarID]; } @@ -193,7 +193,7 @@ function handleSelectedOverlay(clickedOverlay) { Users.ignore(avatarID); } // cleanup of the overlay is handled by the connection to avatarRemovedEvent - + } else if (muteOverlay && clickedOverlay.overlayID == muteOverlay) { Users.mute(avatarID); } From da83fd9fa46683996df318cc256a4f269629f21c Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Sun, 13 Nov 2016 12:56:16 -0800 Subject: [PATCH 56/59] try, try again --- plugins/openvr/src/OpenVrDisplayPlugin.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/openvr/src/OpenVrDisplayPlugin.cpp b/plugins/openvr/src/OpenVrDisplayPlugin.cpp index 7f0ac4d5e0..eb0e58eb4a 100644 --- a/plugins/openvr/src/OpenVrDisplayPlugin.cpp +++ b/plugins/openvr/src/OpenVrDisplayPlugin.cpp @@ -33,9 +33,9 @@ Q_DECLARE_LOGGING_CATEGORY(displayplugins) -const QString OpenVrDisplayPlugin::NAME("OpenVR (Vive)"); -const QString StandingHMDSensorMode = "Standing HMD Sensor Mode"; // this probably shouldn't be hardcoded here -const QString OpenVrThreadedSubmit = "OpenVR Threaded Submit"; // this probably shouldn't be hardcoded here +const char* OpenVrDisplayPlugin::NAME { "OpenVR (Vive)" }; +const char* StandingHMDSensorMode { "Standing HMD Sensor Mode" }; // this probably shouldn't be hardcoded here +const char* OpenVrThreadedSubmit { "OpenVR Threaded Submit" }; // this probably shouldn't be hardcoded here PoseData _nextRenderPoseData; PoseData _nextSimPoseData; From 645134e4b06f2fc4f05dee5a11af3d77ca71ec89 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Sun, 13 Nov 2016 13:26:15 -0800 Subject: [PATCH 57/59] try, try again --- plugins/oculus/src/OculusControllerManager.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/oculus/src/OculusControllerManager.cpp b/plugins/oculus/src/OculusControllerManager.cpp index c9c964ec9d..f56d594919 100644 --- a/plugins/oculus/src/OculusControllerManager.cpp +++ b/plugins/oculus/src/OculusControllerManager.cpp @@ -27,9 +27,9 @@ Q_DECLARE_LOGGING_CATEGORY(oculus) static const char* MENU_PARENT = "Avatar"; static const char* MENU_NAME = "Oculus Touch Controllers"; -static const char* MENU_PATH = MENU_PARENT + ">" + MENU_NAME; +static const char* MENU_PATH = "Avatar" ">" "Oculus Touch Controllers"; -const QString OculusControllerManager::NAME = "Oculus"; +const char* OculusControllerManager::NAME = "Oculus"; bool OculusControllerManager::isSupported() const { return oculusAvailable(); From 7a160ce5e89a79bfa625c5198c247aec49675272 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Sun, 13 Nov 2016 13:39:31 -0800 Subject: [PATCH 58/59] try, try again --- plugins/oculus/src/OculusDisplayPlugin.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/oculus/src/OculusDisplayPlugin.cpp b/plugins/oculus/src/OculusDisplayPlugin.cpp index 143204be17..d7d734f6a2 100644 --- a/plugins/oculus/src/OculusDisplayPlugin.cpp +++ b/plugins/oculus/src/OculusDisplayPlugin.cpp @@ -19,7 +19,7 @@ #include "OculusHelpers.h" -const QString OculusDisplayPlugin::NAME("Oculus Rift"); +const char* OculusDisplayPlugin::NAME { "Oculus Rift" }; static ovrPerfHudMode currentDebugMode = ovrPerfHud_Off; bool OculusDisplayPlugin::internalActivate() { From 92e24e6ded96f9e35e92fb241211fe69982ce935 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Sun, 13 Nov 2016 16:09:57 -0800 Subject: [PATCH 59/59] code review --- .../display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp index 90100d93c0..63c4692a5f 100644 --- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp @@ -758,7 +758,6 @@ void OpenGLDisplayPlugin::render(std::function f) { OpenGLDisplayPlugin::~OpenGLDisplayPlugin() { - // qDebug() << "Destroying OpenGLDisplayPlugin"; } void OpenGLDisplayPlugin::updateCompositeFramebuffer() {