From 86abd9120ebffdf1f1bd314549e55bd412572bef Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Tue, 1 Nov 2016 22:16:56 +0100 Subject: [PATCH 1/5] 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 2/5] 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 3/5] 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 4/5] 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 e22c36b4b7800eae88cf7b081be0d673f1931a7c Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Mon, 7 Nov 2016 17:16:24 +0000 Subject: [PATCH 5/5] 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: