diff --git a/scripts/system/controllers/controllerModules/inVREditMode.js b/scripts/system/controllers/controllerModules/inVREditMode.js new file mode 100644 index 0000000000..c48955442b --- /dev/null +++ b/scripts/system/controllers/controllerModules/inVREditMode.js @@ -0,0 +1,111 @@ +"use strict"; + +// inVREditMode.js +// +// Created by David Rowe on 16 Sep 2017. +// Copyright 2017 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html + +/* global Script, MyAvatar, RIGHT_HAND, LEFT_HAND, enableDispatcherModule, disableDispatcherModule, + makeDispatcherModuleParameters, makeRunningValues, getEnabledModuleByName +*/ + +Script.include("/~/system/libraries/controllerDispatcherUtils.js"); + +(function () { + + function InVREditMode(hand) { + this.hand = hand; + this.disableModules = false; + this.parameters = makeDispatcherModuleParameters( + 200, // Not too high otherwise the tablet laser doesn't work. + this.hand === RIGHT_HAND + ? ["rightHand", "rightHandEquip", "rightHandTrigger"] + : ["leftHand", "leftHandEquip", "leftHandTrigger"], + [], + 100 + ); + + this.isReady = function (controllerData) { + if (this.disableModules) { + return makeRunningValues(true, [], []); + } + return makeRunningValues(false, [], []); + }; + + this.run = function (controllerData) { + // Default behavior if disabling is not enabled. + if (!this.disableModules) { + return makeRunningValues(false, [], []); + } + + // 2D overlay lasers. + // These are automatically enabled. + + // Tablet stylus. + // Includes the tablet laser. + var tabletStylusInput = getEnabledModuleByName(this.hand === RIGHT_HAND + ? "RightTabletStylusInput" + : "LeftTabletStylusInput"); + if (tabletStylusInput) { + var tabletReady = tabletStylusInput.isReady(controllerData); + if (tabletReady.active) { + return makeRunningValues(false, [], []); + } + } + + // Tablet grabbing. + var nearOverlay = getEnabledModuleByName(this.hand === RIGHT_HAND + ? "RightNearParentingGrabOverlay" + : "LeftNearParentingGrabOverlay"); + if (nearOverlay) { + var nearOverlayReady = nearOverlay.isReady(controllerData); + if (nearOverlayReady.active && nearOverlay.grabbedThingID === HMD.tabletID) { + return makeRunningValues(false, [], []); + } + } + + // Teleport. + var teleporter = getEnabledModuleByName(this.hand === RIGHT_HAND + ? "RightTeleporter" + : "LeftTeleporter"); + if (teleporter) { + var teleporterReady = teleporter.isReady(controllerData); + if (teleporterReady.active) { + return makeRunningValues(false, [], []); + } + } + + // Other behaviors are disabled. + return makeRunningValues(true, [], []); + }; + } + + var leftHandInVREditMode = new InVREditMode(LEFT_HAND); + var rightHandInVREditMode = new InVREditMode(RIGHT_HAND); + enableDispatcherModule("LeftHandInVREditMode", leftHandInVREditMode); + enableDispatcherModule("RightHandInVREditMode", rightHandInVREditMode); + + var INVREDIT_DISABLER_MESSAGE_CHANNEL = "Hifi-InVREdit-Disabler"; + this.handleMessage = function (channel, message, sender) { + if (sender === MyAvatar.sessionUUID && channel === INVREDIT_DISABLER_MESSAGE_CHANNEL) { + if (message === "both") { + leftHandInVREditMode.disableModules = true; + rightHandInVREditMode.disableModules = true; + } else if (message === "none") { + leftHandInVREditMode.disableModules = false; + rightHandInVREditMode.disableModules = false; + } + } + }; + Messages.subscribe(INVREDIT_DISABLER_MESSAGE_CHANNEL); + Messages.messageReceived.connect(this.handleMessage); + + this.cleanup = function () { + disableDispatcherModule("LeftHandInVREditMode"); + disableDispatcherModule("RightHandInVREditMode"); + }; + Script.scriptEnding.connect(this.cleanup); +}()); \ No newline at end of file diff --git a/scripts/system/controllers/controllerScripts.js b/scripts/system/controllers/controllerScripts.js index e8b07c623d..87c349523a 100644 --- a/scripts/system/controllers/controllerScripts.js +++ b/scripts/system/controllers/controllerScripts.js @@ -26,6 +26,7 @@ var CONTOLLER_SCRIPTS = [ "controllerModules/overlayLaserInput.js", "controllerModules/webEntityLaserInput.js", "controllerModules/inEditMode.js", + "controllerModules/inVREditMode.js", "controllerModules/disableOtherModule.js", "controllerModules/farTrigger.js", "controllerModules/teleport.js", diff --git a/scripts/vr-edit/modules/laser.js b/scripts/vr-edit/modules/laser.js index 9c1a6f5bb3..afd67cf364 100644 --- a/scripts/vr-edit/modules/laser.js +++ b/scripts/vr-edit/modules/laser.js @@ -169,18 +169,27 @@ Laser = function (side) { // Normal laser operation with trigger. intersection = Overlays.findRayIntersection(pickRay, PRECISION_PICKING, NO_INCLUDE_IDS, NO_EXCLUDE_IDS, VISIBLE_ONLY); - if (!intersection.intersects) { - intersection = Entities.findRayIntersection(pickRay, PRECISION_PICKING, NO_INCLUDE_IDS, NO_EXCLUDE_IDS, - VISIBLE_ONLY); - intersection.editableEntity = intersection.intersects && Entities.hasEditableRoot(intersection.entityID); - intersection.overlayID = null; + if (Reticle.pointingAtSystemOverlay || (intersection.overlayID + && [HMD.tabletID, HMD.tabletScreenID, HMD.homeButtonID].indexOf(intersection.overlayID) !== -1)) { + // No laser if pointing at HUD overlay or tablet; system provides lasers for these cases. + if (isLaserOn) { + isLaserOn = false; + hide(); + } + } else { + if (!intersection.intersects) { + intersection = Entities.findRayIntersection(pickRay, PRECISION_PICKING, NO_INCLUDE_IDS, NO_EXCLUDE_IDS, + VISIBLE_ONLY); + intersection.editableEntity = intersection.intersects && Entities.hasEditableRoot(intersection.entityID); + intersection.overlayID = null; + } + intersection.laserIntersected = intersection.intersects; + laserLength = (specifiedLaserLength !== null) + ? specifiedLaserLength + : (intersection.intersects ? intersection.distance : PICK_MAX_DISTANCE); + isLaserOn = true; + display(pickRay.origin, pickRay.direction, laserLength, true, hand.triggerClicked()); } - intersection.laserIntersected = intersection.intersects; - laserLength = (specifiedLaserLength !== null) - ? specifiedLaserLength - : (intersection.intersects ? intersection.distance : PICK_MAX_DISTANCE); - isLaserOn = true; - display(pickRay.origin, pickRay.direction, laserLength, true, hand.triggerClicked()); } else if (uiOverlayIDs.length > 0) { diff --git a/scripts/vr-edit/vr-edit.js b/scripts/vr-edit/vr-edit.js index 94801335cb..e0a54578ff 100644 --- a/scripts/vr-edit/vr-edit.js +++ b/scripts/vr-edit/vr-edit.js @@ -1399,8 +1399,7 @@ // Communicate app status to controllerDispatcher.js. var DISABLE_HANDS = "both", ENABLE_HANDS = "none"; - // TODO: Proper method to disable specific laser and grabbing functionality. - Messages.sendLocalMessage('Hifi-Hand-Disabler', isAppActive ? DISABLE_HANDS : ENABLE_HANDS); + Messages.sendLocalMessage("Hifi-InVREdit-Disabler", isAppActive ? DISABLE_HANDS : ENABLE_HANDS); } function onUICommand(command, parameter) {