From 3960ec7d5a31194cf565f28cae09ef62e45bfea1 Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Wed, 30 Aug 2017 15:20:03 -0700 Subject: [PATCH] finish main handControllerGrab refactoring --- .../controllerModules/farActionGrabEntity.js | 95 +++++++++++++----- .../controllerModules/inEditMode.js | 99 +++++++++++++++++++ .../nearParentGrabOverlay.js | 2 +- ...rlayLaserInput.js => overlayLaserInput.js} | 50 ++++++---- .../controllerModules/tabletStylusInput.js | 2 +- .../system/controllers/controllerScripts.js | 7 +- 6 files changed, 205 insertions(+), 50 deletions(-) create mode 100644 scripts/system/controllers/controllerModules/inEditMode.js rename scripts/system/controllers/controllerModules/{web3DOverlayLaserInput.js => overlayLaserInput.js} (92%) diff --git a/scripts/system/controllers/controllerModules/farActionGrabEntity.js b/scripts/system/controllers/controllerModules/farActionGrabEntity.js index b84ee4b822..8c5a6bf5a3 100644 --- a/scripts/system/controllers/controllerModules/farActionGrabEntity.js +++ b/scripts/system/controllers/controllerModules/farActionGrabEntity.js @@ -109,6 +109,8 @@ Script.include("/~/system/libraries/controllers.js"); this.hand = hand; this.grabbedThingID = null; this.actionID = null; // action this script created... + this.entityWithContextOverlay = false; + this.contextOverlayTimer = false; var ACTION_TTL = 15; // seconds @@ -335,11 +337,11 @@ Script.include("/~/system/libraries/controllers.js"); this.grabbedThingID = null; }; - this.pointingAtWebEntity = function(controllerData) { + this.notPointingAtEntity = function(controllerData) { var intersection = controllerData.rayPicks[this.hand]; var entityProperty = Entities.getEntityProperties(intersection.objectID); var entityType = entityProperty.type; - if ((intersection.type === RayPick.INTERSECTED_ENTITY && entityType === "Web") || intersection.objectID === HMD.tabletButtonID) { + if ((intersection.type === RayPick.INTERSECTED_ENTITY && entityType === "Web") || intersection.type === RayPick.INTERSECTED_OVERLAY) { return true; } return false @@ -388,8 +390,15 @@ Script.include("/~/system/libraries/controllers.js"); this.previousWorldControllerRotation = worldControllerRotation; }; + this.destroyContextOverlay = function(controllerData) { + if (this.entityWithContextOverlay) { + ContextOverlay.destroyContextOverlay(this.entityWithContextOverlay); + this.entityWithContextOverlay = false; + } + } + this.isReady = function (controllerData) { - if (this.pointingAtWebEntity(controllerData)) { + if (this.notPointingAtEntity(controllerData)) { return makeRunningValues(false, [], []); } @@ -401,17 +410,28 @@ Script.include("/~/system/libraries/controllers.js"); this.prepareDistanceRotatingData(controllerData); return makeRunningValues(true, [], []); } else { + this.destroyContextOverlay(); return makeRunningValues(false, [], []); } }; + this.isPointingAtUI = function(controllerData) { + var hudRayPickInfo = controllerData.hudRayPicks[this.hand]; + var hudPoint2d = HMD.overlayFromWorldPoint(hudRayPickInfo.intersection); + } + this.run = function (controllerData) { - if (controllerData.triggerValues[this.hand] < TRIGGER_OFF_VALUE || this.pointingAtWebEntity(controllerData)) { + if (controllerData.triggerValues[this.hand] < TRIGGER_OFF_VALUE || this.notPointingAtEntity(controllerData)) { this.endNearGrabAction(); this.laserPointerOff(); return makeRunningValues(false, [], []); } + var targetEntity = controllerData.rayPicks[this.hand].objectID; + if (targetEntity !== this.entityWithContextOverlay) { + this.destroyContextOverlay(); + } + // gather up the readiness of the near-grab modules var nearGrabNames = [ this.hand === RIGHT_HAND ? "RightNearActionGrabEntity" : "LeftNearActionGrabEntity", @@ -456,37 +476,58 @@ Script.include("/~/system/libraries/controllers.js"); var hudRayPickInfo = controllerData.hudRayPicks[this.hand]; var hudPoint2d = HMD.overlayFromWorldPoint(hudRayPickInfo.intersection); if (rayPickInfo.type == RayPick.INTERSECTED_ENTITY) { - var entityID = rayPickInfo.objectID; - var targetProps = Entities.getEntityProperties(entityID, ["dynamic", "shapeType", "position", - "rotation", "dimensions", "density", - "userData", "locked", "type"]); - if (entityIsDistanceGrabbable(targetProps)) { - if (!this.distanceRotating) { - this.grabbedThingID = entityID; - this.grabbedDistance = rayPickInfo.distance; - } - var otherModuleName = - this.hand == RIGHT_HAND ? "LeftFarActionGrabEntity" : "RightFarActionGrabEntity"; - var otherFarGrabModule = getEnabledModuleByName(otherModuleName); - if (otherFarGrabModule.grabbedThingID == this.grabbedThingID && otherFarGrabModule.distanceHolding) { - this.distanceRotate(otherFarGrabModule); - } else { - this.distanceHolding = true; - this.distanceRotating = false; - this.startFarGrabAction(controllerData, targetProps); + if (controllerData.triggerClicks[this.hand]) { + var entityID = rayPickInfo.objectID; + var targetProps = Entities.getEntityProperties(entityID, ["dynamic", "shapeType", "position", + "rotation", "dimensions", "density", + "userData", "locked", "type"]); + if (entityIsDistanceGrabbable(targetProps)) { + if (!this.distanceRotating) { + this.grabbedThingID = entityID; + this.grabbedDistance = rayPickInfo.distance; + } + var otherModuleName = + this.hand == RIGHT_HAND ? "LeftFarActionGrabEntity" : "RightFarActionGrabEntity"; + var otherFarGrabModule = getEnabledModuleByName(otherModuleName); + if (otherFarGrabModule.grabbedThingID == this.grabbedThingID && otherFarGrabModule.distanceHolding) { + this.distanceRotate(otherFarGrabModule); + } else { + this.distanceHolding = true; + this.distanceRotating = false; + this.startFarGrabAction(controllerData, targetProps); + } } + } else if (!this.entityWithContextOverlay && !this.contextOverlayTimer) { + var _this = this; + _this.contextOverlayTimer = Script.setTimeout(function () { + if (!_this.entityWithContextOverlay && _this.contextOverlayTimer) { + var props = Entities.getEntityProperties(rayPickInfo.objectID); + var pointerEvent = { + type: "Move", + id: this.hand + 1, // 0 is reserved for hardware mouse + pos2D: projectOntoEntityXYPlane(rayPickInfo.objectID, rayPickInfo.intersection, props), + pos3D: rayPickInfo.intersection, + normal: rayPickInfo.surfaceNormal, + direction: Vec3.subtract(ZERO_VEC, rayPickInfo.surfaceNormal), + button: "Secondary" + }; + if (ContextOverlay.createOrDestroyContextOverlay(rayPickInfo.objectID, pointerEvent)) { + _this.entityWithContextOverlay = rayPickInfo.objectID; + } + } + _this.contextOverlayTimer = false; + }, 500); } } else if (this.distanceRotating) { - var otherModuleName = - this.hand == RIGHT_HAND ? "LeftFarActionGrabEntity" : "RightFarActionGrabEntity"; + var otherModuleName = + this.hand == RIGHT_HAND ? "LeftFarActionGrabEntity" : "RightFarActionGrabEntity"; var otherFarGrabModule = getEnabledModuleByName(otherModuleName); this.distanceRotate(otherFarGrabModule); - } - /* else if (Reticle.pointingAtSystemOverlay || Overlays.getOverlayAtPoint(hudPoint2d || Reticle.position)) { + } else if (Reticle.pointingAtSystemOverlay || Overlays.getOverlayAtPoint(hudPoint2d || Reticle.position)) { this.endNearGrabAction(); this.laserPointerOff(); return makeRunningValues(false, [], []); - }*/ + } } return makeRunningValues(true, [], []); }; diff --git a/scripts/system/controllers/controllerModules/inEditMode.js b/scripts/system/controllers/controllerModules/inEditMode.js new file mode 100644 index 0000000000..67da6c18ac --- /dev/null +++ b/scripts/system/controllers/controllerModules/inEditMode.js @@ -0,0 +1,99 @@ +"use strict" + +// inEditMode.js +// +// 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, Entities, MyAvatar, Controller, RIGHT_HAND, LEFT_HAND, + NULL_UUID, enableDispatcherModule, disableDispatcherModule, makeRunningValues, + Messages, Quat, Vec3, getControllerWorldLocation, makeDispatcherModuleParameters, Overlays, ZERO_VEC, + AVATAR_SELF_ID, HMD, INCHES_TO_METERS, DEFAULT_REGISTRATION_POINT, Settings, getGrabPointSphereOffset +*/ + +Script.include("/~/system/controllers/controllerDispatcherUtils.js"); +Script.include("/~/system/libraries/controllers.js"); +Script.include("/~/system/libraries/utils.js"); + +(function () { + + function InEditMode(hand) { + this.hand = hand; + + this.parameters = makeDispatcherModuleParameters( + 160, + this.hand === RIGHT_HAND ? ["rightHand"] : ["leftHand"], + 100); + + this.nearTablet = function(overlays) { + for (var i = 0; i < overlays.length; i++) { + if (overlays[i] === HMD.tabletID) { + return true; + } + } + + return false; + }; + + this.pointingAtTablet = function(objectID) { + if (objectID === HMD.tabletScreenID || objectID === HMD.tabletButtonID) { + return true; + } + return false; + }; + + this.isReady = function(controllerData) { + var overlays = controllerData.nearbyOverlayIDs[this.hand]; + var objectID = controllerData.rayPicks[this.hand].objectID; + + if (isInEditMode()) { + return makeRunningValues(true, [], []); + } + + return makeRunningValues(false, [], []); + }; + + this.run = function(controllerData) { + var tabletStylusInput = getEnabledModuleByName(this.hand === RIGHT_HAND ? "RightTabletStylusInput" : "LeftTabletStylusInput"); + if (tabletStylusInput) { + var tabletReady = tabletStylusInput.isReady(controllerData); + + if (tabletReady.active) { + return makeRunningValues(false, [], []); + } + } + + var overlayLaser = getEnabledModuleByName(this.hand === RIGHT_HAND ? "RightOverlayLaserInput" : "LeftOverlayLaserInput"); + if (overlayLaser) { + var overlayLaserReady = overlayLaser.isReady(controllerData); + + if (overlayLaserReady.active && this.pointingAtTablet(overlayLaser.target)) { + return makeRunningValues(false, [], []); + } + } + + 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, [], []); + } + } + + return this.isReady(controllerData); + }; + }; + + + var leftHandInEditMode = new InEditMode(LEFT_HAND); + var rightHandInEditMode = new InEditMode(RIGHT_HAND); + + enableDispatcherModule("LeftHandInEditMode", leftHandInEditMode); + enableDispatcherModule("RightHandInEditMode", rightHandInEditMode); + + this.cleanup = function() { + disableDispatcherModule("LeftHandInEditMode"); + disableDispatcherModule("RightHandInEditMode"); + }; +}()); diff --git a/scripts/system/controllers/controllerModules/nearParentGrabOverlay.js b/scripts/system/controllers/controllerModules/nearParentGrabOverlay.js index 399814a0ed..2cea81ce18 100644 --- a/scripts/system/controllers/controllerModules/nearParentGrabOverlay.js +++ b/scripts/system/controllers/controllerModules/nearParentGrabOverlay.js @@ -28,7 +28,7 @@ var GRAB_RADIUS = 0.35; this.previouslyUnhooked = {}; this.parameters = makeDispatcherModuleParameters( - 500, + 140, this.hand === RIGHT_HAND ? ["rightHand"] : ["leftHand"], [], 100); diff --git a/scripts/system/controllers/controllerModules/web3DOverlayLaserInput.js b/scripts/system/controllers/controllerModules/overlayLaserInput.js similarity index 92% rename from scripts/system/controllers/controllerModules/web3DOverlayLaserInput.js rename to scripts/system/controllers/controllerModules/overlayLaserInput.js index 501c37fd35..8a14fc49ae 100644 --- a/scripts/system/controllers/controllerModules/web3DOverlayLaserInput.js +++ b/scripts/system/controllers/controllerModules/overlayLaserInput.js @@ -1,6 +1,6 @@ "use strict" -// tabletLaserInput.js +// overlayLaserInput.js // // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html @@ -270,7 +270,7 @@ Script.include("/~/system/libraries/controllers.js"); return Math.sqrt(dx * dx + dy * dy); } - function TabletLaserInput(hand) { + function OverlayLaserInput(hand) { this.hand = hand; this.active = false; this.previousLaserClikcedTarget = false; @@ -281,11 +281,12 @@ Script.include("/~/system/libraries/controllers.js"); this.laserTarget = null; this.pressEnterLaserTarget = null; this.hover = false; + this.target = null; this.lastValidTargetID = this.tabletTargetID; this.parameters = makeDispatcherModuleParameters( - 200, + 120, this.hand === RIGHT_HAND ? ["rightHand"] : ["leftHand"], [], 100); @@ -295,7 +296,7 @@ Script.include("/~/system/libraries/controllers.js"); }; this.getOtherModule = function() { - return (this.hand === RIGHT_HAND) ? leftTabletLaserInput : rightTabletLaserInput; + return (this.hand === RIGHT_HAND) ? leftOverlayLaserInput : rightOverlayLaserInput; }; this.handToController = function() { @@ -313,10 +314,6 @@ Script.include("/~/system/libraries/controllers.js"); } }; - this.hasTouchFocus = function(laserTarget) { - return (this.laserTargetID === HMD.tabletScreenID); - }; - this.relinquishTouchFocus = function() { // send hover leave event. var pointerEvent = { type: "Move", id: this.hand + 1 }; @@ -449,12 +446,28 @@ Script.include("/~/system/libraries/controllers.js"); this.active = false; }; + this.deleteContextOverlay = function() { + var farGrabModule = getEnabledModuleByName(this.hand === RIGHT_HAND ? "RightFarActionGrabEntity" : "LeftFarActionGrabEntity"); + if (farGrabModule) { + var entityWithContextOverlay = farGrabModule.entityWithContextOverlay; + + if (entityWithContextOverlay) { + ContextOverlay.destroyContextOverlay(entityWithContextOverlay); + farGrabModule.entityWithContextOverlay = false; + } + } + }; + this.isReady = function (controllerData) { + this.target = null; var intersection = controllerData.rayPicks[this.hand]; if (intersection.type === RayPick.INTERSECTED_OVERLAY) { if (controllerData.triggerValues[this.hand] > TRIGGER_ON_VALUE && !this.getOtherModule().active) { + this.target = intersection.objectID; this.active = true; return makeRunningValues(true, [], []); + } else { + this.deleteContextOverlay(); } } this.reset(); @@ -462,12 +475,15 @@ Script.include("/~/system/libraries/controllers.js"); }; this.run = function (controllerData, deltaTime) { - if (this.shouldExit(controllerData)) { this.exitModule(); return makeRunningValues(false, [], []); } + if (controllerData.triggerValues[this.hand] < TRIGGER_OFF_VALUE) { + this.deleteContextOverlay(); + } + this.updateLaserTargets(controllerData); this.processControllerTriggers(controllerData); this.updateLaserPointer(controllerData); @@ -511,17 +527,17 @@ Script.include("/~/system/libraries/controllers.js"); LaserPointers.setIgnoreOverlays(this.laserPointer, [HMD.tabletID]); }; - var leftTabletLaserInput = new TabletLaserInput(LEFT_HAND); - var rightTabletLaserInput = new TabletLaserInput(RIGHT_HAND); + var leftOverlayLaserInput = new OverlayLaserInput(LEFT_HAND); + var rightOverlayLaserInput = new OverlayLaserInput(RIGHT_HAND); - enableDispatcherModule("LeftTabletLaserInput", leftTabletLaserInput); - enableDispatcherModule("RightTabletLaserInput", rightTabletLaserInput); + enableDispatcherModule("LeftOverlayLaserInput", leftOverlayLaserInput); + enableDispatcherModule("RightOverlayLaserInput", rightOverlayLaserInput); this.cleanup = function () { - leftTabletLaserInput.cleanup(); - rightTabletLaserInput.cleanup(); - disableDispatcherModule("LeftTabletLaserInput"); - disableDispatcherModule("RightTabletLaserInput"); + leftOverlayLaserInput.cleanup(); + rightOverlayLaserInput.cleanup(); + disableDispatcherModule("LeftOverlayLaserInput"); + disableDispatcherModule("RightOverlayLaserInput"); }; Script.scriptEnding.connect(this.cleanup); }()); diff --git a/scripts/system/controllers/controllerModules/tabletStylusInput.js b/scripts/system/controllers/controllerModules/tabletStylusInput.js index 8ada1b31d7..bbe8f935ae 100644 --- a/scripts/system/controllers/controllerModules/tabletStylusInput.js +++ b/scripts/system/controllers/controllerModules/tabletStylusInput.js @@ -319,7 +319,7 @@ Script.include("/~/system/libraries/controllers.js"); this.parameters = makeDispatcherModuleParameters( - 400, + 100, this.hand === RIGHT_HAND ? ["rightHand"] : ["leftHand"], [], 100); diff --git a/scripts/system/controllers/controllerScripts.js b/scripts/system/controllers/controllerScripts.js index c9f030231a..cd572b901a 100644 --- a/scripts/system/controllers/controllerScripts.js +++ b/scripts/system/controllers/controllerScripts.js @@ -12,11 +12,9 @@ var CONTOLLER_SCRIPTS = [ "squeezeHands.js", "controllerDisplayManager.js", - // "handControllerGrab.js", "handControllerPointer.js", - // "grab.js", + "grab.js", "toggleAdvancedMovementForHandControllers.js", - "ControllerDispatcher.js", "controllerModules/nearParentGrabEntity.js", "controllerModules/nearParentGrabOverlay.js", @@ -25,8 +23,9 @@ var CONTOLLER_SCRIPTS = [ "controllerModules/tabletStylusInput.js", "controllerModules/equipEntity.js", "controllerModules/nearTrigger.js", - "controllerModules/web3DOverlayLaserInput.js", + "controllerModules/overlayLaserInput.js", "controllerModules/webEntityLaserInput.js", + "controllerModules/inEditMode.js", "teleport.js" ];