From 86abd9120ebffdf1f1bd314549e55bd412572bef Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Tue, 1 Nov 2016 22:16:56 +0100 Subject: [PATCH] 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();