From 7cf27c18d3450b83908ca0fe0c140031bbb6419f Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Thu, 31 Aug 2017 18:06:55 -0700 Subject: [PATCH] code cleanup and fix broken features --- .eslintrc.js | 5 +- .../controllers/controllerDispatcher.js | 51 +++++- .../controllerModules/cloneEntity.js | 159 ------------------ .../controllerModules/equipEntity.js | 98 ++++++++--- .../controllerModules/farActionGrabEntity.js | 106 ++++++------ .../controllerModules/inEditMode.js | 71 ++++---- .../nearParentGrabOverlay.js | 2 +- .../controllerModules/overlayLaserInput.js | 63 +++---- .../controllerModules/tabletStylusInput.js | 44 ++--- .../controllerModules/webEntityLaserInput.js | 68 ++++---- 10 files changed, 316 insertions(+), 351 deletions(-) delete mode 100644 scripts/system/controllers/controllerModules/cloneEntity.js diff --git a/.eslintrc.js b/.eslintrc.js index b4d88777f2..83fda730e5 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -54,7 +54,10 @@ module.exports = { "Window": false, "XMLHttpRequest": false, "location": false, - "print": false + "print": false, + "RayPick": false, + "LaserPointers": false, + "ContextOverlay": false }, "rules": { "brace-style": ["error", "1tbs", { "allowSingleLine": false }], diff --git a/scripts/system/controllers/controllerDispatcher.js b/scripts/system/controllers/controllerDispatcher.js index 18b4c287c0..9469b59a95 100644 --- a/scripts/system/controllers/controllerDispatcher.js +++ b/scripts/system/controllers/controllerDispatcher.js @@ -34,6 +34,7 @@ Script.include("/~/system/controllers/controllerDispatcherUtils.js"); var highVarianceCount = 0; var veryhighVarianceCount = 0; this.tabletID = null; + this.blacklist = []; // a module can occupy one or more "activity" slots while it's running. If all the required slots for a module are // not set to false (not in use), a module cannot start. When a module is using a slot, that module's name @@ -293,6 +294,12 @@ Script.include("/~/system/controllers/controllerDispatcherUtils.js"); } }; + this.setBlacklist = function() { + RayPick.setIgnoreEntities(_this.leftControllerRayPick, this.blacklist); + RayPick.setIgnoreEntities(_this.rightControllerRayPick, this.blacklist); + + }; + var MAPPING_NAME = "com.highfidelity.controllerDispatcher"; var mapping = Controller.newMapping(MAPPING_NAME); mapping.from([Controller.Standard.RT]).peek().to(_this.rightTriggerPress); @@ -324,27 +331,60 @@ Script.include("/~/system/controllers/controllerDispatcherUtils.js"); joint: "_CONTROLLER_LEFTHAND", filter: RayPick.PICK_ENTITIES | RayPick.PICK_OVERLAYS, enabled: true, - maxDistance: DEFAULT_SEARCH_SPHERE_DISTANCE + maxDistance: DEFAULT_SEARCH_SPHERE_DISTANCE, + posOffset: getGrabPointSphereOffset(Controller.Standard.LeftHand) }); this.leftControllerHudRayPick = RayPick.createRayPick({ joint: "_CONTROLLER_LEFTHAND", filter: RayPick.PICK_HUD, enabled: true, - maxDistance: DEFAULT_SEARCH_SPHERE_DISTANCE + maxDistance: DEFAULT_SEARCH_SPHERE_DISTANCE, + posOffset: getGrabPointSphereOffset(Controller.Standard.LeftHand) }); this.rightControllerRayPick = RayPick.createRayPick({ joint: "_CONTROLLER_RIGHTHAND", filter: RayPick.PICK_ENTITIES | RayPick.PICK_OVERLAYS, enabled: true, - maxDistance: DEFAULT_SEARCH_SPHERE_DISTANCE + maxDistance: DEFAULT_SEARCH_SPHERE_DISTANCE, + posOffset: getGrabPointSphereOffset(Controller.Standard.RightHand) }); this.rightControllerHudRayPick = RayPick.createRayPick({ joint: "_CONTROLLER_RIGHTHAND", filter: RayPick.PICK_HUD, enabled: true, - maxDistance: DEFAULT_SEARCH_SPHERE_DISTANCE + maxDistance: DEFAULT_SEARCH_SPHERE_DISTANCE, + posOffset: getGrabPointSphereOffset(Controller.Standard.RightHand) }); + this.handleHandMessage = function(channel, message, sender) { + var data + if (sender === MyAvatar.sessionUUID) { + try { + if (channel === 'Hifi-Hand-RayPick-Blacklist') { + data = JSON.parse(message); + var action = data.action; + var id = data.id; + var index = this.blacklis.indexOf(id); + + if (action === 'add' && index === -1) { + this.blacklist.push(id); + //this.setBlacklist(); + } + + if (action === 'remove') { + if (index > -1) { + blacklist.splice(index, 1); + //this.setBlacklist(); + } + } + } + + } catch (e) { + print("WARNING: handControllerGrab.js -- error parsing Hifi-Hand-RayPick-Blacklist message: " + message); + } + } + }; + @@ -357,7 +397,8 @@ Script.include("/~/system/controllers/controllerDispatcherUtils.js"); RayPick.removeRayPick(_this.rightControllerHudRayPick); RayPick.removeRayPick(_this.leftControllerHudRayPick); }; - + Messages.subscribe('Hifi-Hand-RayPick-Blacklist'); + Messages.messageReceived.connect(this.handleHandMessage); Script.scriptEnding.connect(this.cleanup); Script.update.connect(this.update); }()); diff --git a/scripts/system/controllers/controllerModules/cloneEntity.js b/scripts/system/controllers/controllerModules/cloneEntity.js deleted file mode 100644 index cfe9cb56da..0000000000 --- a/scripts/system/controllers/controllerModules/cloneEntity.js +++ /dev/null @@ -1,159 +0,0 @@ -"use strict"; - -// cloneEntity.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, RIGHT_HAND, LEFT_HAND, - enableDispatcherModule, disableDispatcherModule, getGrabbableData, Vec3, - TRIGGER_ON_VALUE, TRIGGER_OFF_VALUE, makeDispatcherModuleParameters, makeRunningValues, NEAR_GRAB_RADIUS -*/ - -Script.include("/~/system/controllers/controllerDispatcherUtils.js"); - -// Object assign polyfill -if (typeof Object.assign != 'function') { - Object.assign = function(target, varArgs) { - if (target === null) { - throw new TypeError('Cannot convert undefined or null to object'); - } - var to = Object(target); - for (var index = 1; index < arguments.length; index++) { - var nextSource = arguments[index]; - if (nextSource !== null) { - for (var nextKey in nextSource) { - if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) { - to[nextKey] = nextSource[nextKey]; - } - } - } - } - return to; - }; -} - -(function() { - - function entityIsCloneable(props) { - var grabbableData = getGrabbableData(props); - return grabbableData.cloneable; - } - - function CloneEntity(hand) { - this.hand = hand; - this.grabbing = false; - this.previousParentID = {}; - this.previousParentJointIndex = {}; - this.previouslyUnhooked = {}; - - this.parameters = makeDispatcherModuleParameters( - 300, - this.hand === RIGHT_HAND ? ["rightHand"] : ["leftHand"], - [], - 100); - - this.getTargetProps = function (controllerData) { - // nearbyEntityProperties is already sorted by length from controller - var nearbyEntityProperties = controllerData.nearbyEntityProperties[this.hand]; - for (var i = 0; i < nearbyEntityProperties.length; i++) { - var props = nearbyEntityProperties[i]; - var handPosition = controllerData.controllerLocations[this.hand].position; - var distance = Vec3.distance(props.position, handPosition); - if (distance > NEAR_GRAB_RADIUS) { - break; - } - if (entityIsCloneable(props)) { - return props; - } - } - return null; - }; - - this.isReady = function (controllerData) { - if (controllerData.triggerValues[this.hand] < TRIGGER_OFF_VALUE) { - this.waiting = false; - return makeRunningValues(false, [], []); - } - - if (controllerData.triggerValues[this.hand] > TRIGGER_ON_VALUE) { - if (!this.waiting) { - this.waiting = true; - return makeRunningValues(true, [], []); - } - } - return makeRunningValues(false, [], []); - }; - - this.run = function (controllerData, deltaTime) { - var cloneableProps = this.getTargetProps(controllerData); - if (!cloneableProps) { - return makeRunningValues(false, [], []); - } - - // we need all the properties, for this - cloneableProps = Entities.getEntityProperties(cloneableProps.id); - - var worldEntityProps = controllerData.nearbyEntityProperties[this.hand]; - var count = 0; - worldEntityProps.forEach(function(itemWE) { - if (itemWE.name.indexOf('-clone-' + cloneableProps.id) !== -1) { - count++; - } - }); - - var grabInfo = getGrabbableData(cloneableProps); - - var limit = grabInfo.cloneLimit ? grabInfo.cloneLimit : 0; - if (count >= limit && limit !== 0) { - return makeRunningValues(false, [], []); - } - - cloneableProps.name = cloneableProps.name + '-clone-' + cloneableProps.id; - var lifetime = grabInfo.cloneLifetime ? grabInfo.cloneLifetime : 300; - var dynamic = grabInfo.cloneDynamic ? grabInfo.cloneDynamic : false; - var cUserData = Object.assign({}, cloneableProps.userData); - var cProperties = Object.assign({}, cloneableProps); - - try { - delete cUserData.grabbableKey.cloneLifetime; - delete cUserData.grabbableKey.cloneable; - delete cUserData.grabbableKey.cloneDynamic; - delete cUserData.grabbableKey.cloneLimit; - delete cProperties.id; - } catch(e) { - } - - cProperties.dynamic = dynamic; - cProperties.locked = false; - if (!cUserData.grabbableKey) { - cUserData.grabbableKey = {}; - } - cUserData.grabbableKey.triggerable = true; - cUserData.grabbableKey.grabbable = true; - cProperties.lifetime = lifetime; - cProperties.userData = JSON.stringify(cUserData); - // var cloneID = - Entities.addEntity(cProperties); - return makeRunningValues(false, [], []); - }; - - this.cleanup = function () { - }; - } - - var leftCloneEntity = new CloneEntity(LEFT_HAND); - var rightCloneEntity = new CloneEntity(RIGHT_HAND); - - enableDispatcherModule("LeftCloneEntity", leftCloneEntity); - enableDispatcherModule("RightCloneEntity", rightCloneEntity); - - this.cleanup = function () { - leftNearParentingGrabEntity.cleanup(); - rightNearParentingGrabEntity.cleanup(); - disableDispatcherModule("LeftNearParentingGrabEntity"); - disableDispatcherModule("RightNearParentingGrabEntity"); - }; - Script.scriptEnding.connect(this.cleanup); -}()); diff --git a/scripts/system/controllers/controllerModules/equipEntity.js b/scripts/system/controllers/controllerModules/equipEntity.js index 08e4113c5d..5ad7fc9e16 100644 --- a/scripts/system/controllers/controllerModules/equipEntity.js +++ b/scripts/system/controllers/controllerModules/equipEntity.js @@ -9,7 +9,8 @@ /* global Script, Entities, MyAvatar, Controller, RIGHT_HAND, LEFT_HAND, AVATAR_SELF_ID, getControllerJointIndex, NULL_UUID, enableDispatcherModule, disableDispatcherModule, Messages, makeDispatcherModuleParameters, makeRunningValues, Settings, entityHasActions, - Vec3, Overlays, flatten, Xform, getControllerWorldLocation, ensureDynamic + Vec3, Overlays, flatten, Xform, getControllerWorldLocation, ensureDynamic, entityIsCloneable, + cloneEntity */ Script.include("/~/system/libraries/Xform.js"); @@ -105,14 +106,14 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa var overlayInfoSet = this.map[keys[i]]; // this overlayInfo is highlighted. - if (this.highlightedHotspots.indexOf(keys[i]) != -1) { + if (this.highlightedHotspots.indexOf(keys[i]) !== -1) { overlayInfoSet.targetSize = HIGHLIGHT_SIZE; } else { overlayInfoSet.targetSize = NORMAL_SIZE; } // start to fade out this hotspot. - if (overlayInfoSet.timestamp != timestamp) { + if (overlayInfoSet.timestamp !== timestamp) { overlayInfoSet.targetSize = 0; } @@ -124,7 +125,7 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa } overlayInfoSet.currentSize += (overlayInfoSet.targetSize - overlayInfoSet.currentSize) * tau; - if (overlayInfoSet.timestamp != timestamp && overlayInfoSet.currentSize <= 0.05) { + if (overlayInfoSet.timestamp !== timestamp && overlayInfoSet.currentSize <= 0.05) { // this is an old overlay, that has finished fading out, delete it! overlayInfoSet.overlays.forEach(Overlays.deleteOverlay); delete this.map[keys[i]]; @@ -136,7 +137,7 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa var position = entityXform.xformPoint(overlayInfoSet.localPosition); var dimensions; - if (overlayInfoSet.type == "sphere") { + if (overlayInfoSet.type === "sphere") { dimensions = overlayInfoSet.hotspot.radius * 2 * overlayInfoSet.currentSize * EQUIP_SPHERE_SCALE_FACTOR; } else { dimensions = overlayInfoSet.hotspot.radius * 2 * overlayInfoSet.currentSize; @@ -157,8 +158,6 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa } }; - - (function() { var ATTACH_POINT_SETTINGS = "io.highfidelity.attachPoints"; @@ -185,6 +184,7 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa if (!props.userDataParsed) { props.userDataParsed = JSON.parse(props.userData); } + wearable = props.userDataParsed.wearable ? props.userDataParsed.wearable : {}; } catch (err) { } @@ -196,6 +196,7 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa if (!props.userDataParsed) { props.userDataParsed = JSON.parse(props.userData); } + equipHotspots = props.userDataParsed.equipHotspots ? props.userDataParsed.equipHotspots : []; } catch (err) { } @@ -249,6 +250,8 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa this.targetEntityID = null; this.prevHandIsUpsideDown = false; this.triggerValue = 0; + this.messageGrabEntity = false; + this.grabEntityProps = null; this.parameters = makeDispatcherModuleParameters( 300, @@ -258,6 +261,13 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa var equipHotspotBuddy = new EquipHotspotBuddy(); + this.setMessageGrabData = function(entityProperties) { + if (entityProperties) { + this.messageGrabEntity = true; + this.grabEntityProps = entityProperties; + } + }; + // returns a list of all equip-hotspots assosiated with this entity. // @param {UUID} entityID // @returns {Object[]} array of objects with the following fields. @@ -322,7 +332,7 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa if (props.parentID === NULL_UUID) { hasParent = false; } - + if (hasParent || entityHasActions(hotspot.entityID)) { return false; } @@ -376,7 +386,7 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa if (entityIsCloneable(props)) { var worldEntityProps = controllerData.nearbyEntityProperties[this.hand]; var cloneID = cloneEntity(props, worldEntityProps); - return cloneID + return cloneID; } return null; @@ -420,7 +430,7 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa handIsUpsideDown = true; } - if (handIsUpsideDown != this.prevHandIsUpsideDown) { + if (handIsUpsideDown !== this.prevHandIsUpsideDown) { this.prevHandIsUpsideDown = handIsUpsideDown; Controller.triggerHapticPulse(HAPTIC_DEQUIP_STRENGTH, HAPTIC_DEQUIP_DURATION, this.hand); } @@ -486,7 +496,7 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa this.targetEntityID = cloneID; Entities.editEntity(this.targetEntityID, reparentProps); isClone = true; - } else if (!grabbedProperties.locked) { + } else if (!grabbedProperties.locked) { Entities.editEntity(this.targetEntityID, reparentProps); } else { this.grabbedHotspot = null; @@ -508,12 +518,12 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa var args = [_this.hand === RIGHT_HAND ? "right" : "left", MyAvatar.sessionUUID]; Entities.callEntityMethod(_this.targetEntityID, "startEquip", args); }; - + if (isClone) { // 100 ms seems to be sufficient time to force the check even occur after the object has been initialized. Script.setTimeout(grabEquipCheck, 100); - } - + } + }; this.endEquipEntity = function () { @@ -546,8 +556,18 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa var controllerLocation = getControllerWorldLocation(this.handToController(), true); var worldHandPosition = controllerLocation.position; var candidateEntityProps = controllerData.nearbyEntityProperties[this.hand]; - - var potentialEquipHotspot = this.chooseBestEquipHotspot(candidateEntityProps, controllerData); + + + var potentialEquipHotspot = null; + if (this.messageGrabEntity) { + var hotspots = this.collectEquipHotspots(this.grabEntityProps); + if (hotspots.length > -1) { + potentialEquipHotspot = hotspots[0]; + } + } else { + potentialEquipHotspot = this.chooseBestEquipHotspot(candidateEntityProps, controllerData); + } + if (!this.waitForTriggerRelease) { this.updateEquipHaptics(potentialEquipHotspot, worldHandPosition); } @@ -560,17 +580,19 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa equipHotspotBuddy.update(deltaTime, timestamp, controllerData); - //if the potentialHotspot is cloneable, clone it and return it + // if the potentialHotspot is cloneable, clone it and return it // if the potentialHotspot os not cloneable and locked return null - + if (potentialEquipHotspot) { - if (this.triggerSmoothedSqueezed() && !this.waitForTriggerRelease) { + if ((this.triggerSmoothedSqueezed() && !this.waitForTriggerRelease) || this.messageGrabEntity) { this.grabbedHotspot = potentialEquipHotspot; this.targetEntityID = this.grabbedHotspot.entityID; this.startEquipEntity(controllerData); + this.messageGrabEnity = false; } return makeRunningValues(true, [potentialEquipHotspot.entityID], []); } else { + this.messageGrabEnity = false; return makeRunningValues(false, [], []); } }; @@ -610,7 +632,7 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa this.waitForTriggerRelease = false; } - if (dropDetected && this.prevDropDetected != dropDetected) { + if (dropDetected && this.prevDropDetected !== dropDetected) { this.waitForTriggerRelease = true; } @@ -627,7 +649,7 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa var prefprops = Entities.getEntityProperties(this.targetEntityID, ["localPosition", "localRotation"]); if (prefprops && prefprops.localPosition && prefprops.localRotation) { storeAttachPointForHotspotInSettings(this.grabbedHotspot, this.hand, - prefprops.localPosition, prefprops.localRotation); + prefprops.localPosition, prefprops.localRotation); } } @@ -651,6 +673,40 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa }; } + var handleMessage = function(channel, message, sender) { + var data; + print(channel); + if (sender === MyAvatar.sessionUUID) { + if (channel === 'Hifi-Hand-Grab') { + try { + data = JSON.parse(message); + var equipModule = (data.hand === 'left') ? leftEquipEntity : rightEquipEntity; + var entityProperties = Entities.getEntityProperties(data.entityID, DISPATCHER_PROPERTIES); + entityProperties.id = data.entityID; + equipModule.setMessageGrabData(entityProperties); + + } catch (e) { + print("WARNING: equipEntity.js -- error parsing Hifi-Hand-Grab message: " + message); + } + } + } else if (channel === 'Hifi-Hand-Drop') { + data = JSON.parse(message); + if (data.hand === 'left') { + leftEquipEntity.endEquipEntity(); + } else if (data.hand === 'right') { + rightEquipEntity.endEquipEntity(); + } else if (data.hand === 'both') { + leftEquipEntity.endEquipEntity(); + rightEquipEntity.endEquipEntity(); + } + } + + }; + + Messages.subscribe('Hifi-Hand-Grab'); + Messages.subscribe('Hifi-Hand-Drop'); + Messages.messageReceived.connect(handleMessage); + var leftEquipEntity = new EquipEntity(LEFT_HAND); var rightEquipEntity = new EquipEntity(RIGHT_HAND); diff --git a/scripts/system/controllers/controllerModules/farActionGrabEntity.js b/scripts/system/controllers/controllerModules/farActionGrabEntity.js index 8c5a6bf5a3..2b748e60d6 100644 --- a/scripts/system/controllers/controllerModules/farActionGrabEntity.js +++ b/scripts/system/controllers/controllerModules/farActionGrabEntity.js @@ -5,14 +5,15 @@ // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -/*jslint bitwise: true */ +/* jslint bitwise: true */ /* global Script, Controller, LaserPointers, RayPick, RIGHT_HAND, LEFT_HAND, Mat4, MyAvatar, Vec3, Camera, Quat, getGrabPointSphereOffset, getEnabledModuleByName, makeRunningValues, Entities, NULL_UUID, enableDispatcherModule, disableDispatcherModule, entityIsDistanceGrabbable, makeDispatcherModuleParameters, MSECS_PER_SEC, HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION, PICK_MAX_DISTANCE, COLORS_GRAB_SEARCHING_HALF_SQUEEZE, COLORS_GRAB_SEARCHING_FULL_SQUEEZE, COLORS_GRAB_DISTANCE_HOLD, - AVATAR_SELF_ID, DEFAULT_SEARCH_SPHERE_DISTANCE, TRIGGER_OFF_VALUE, TRIGGER_ON_VALUE, + AVATAR_SELF_ID, DEFAULT_SEARCH_SPHERE_DISTANCE, TRIGGER_OFF_VALUE, TRIGGER_ON_VALUE, ZERO_VEC, ensureDynamic, + getControllerWorldLocation, projectOntoEntityXYPlane */ @@ -77,14 +78,18 @@ Script.include("/~/system/libraries/controllers.js"); drawInFront: true, // Even when burried inside of something, show it. parentID: AVATAR_SELF_ID }; - - var renderStates = [{name: "half", path: halfPath, end: halfEnd}, - {name: "full", path: fullPath, end: fullEnd}, - {name: "hold", path: holdPath}]; - var defaultRenderStates = [{name: "half", distance: DEFAULT_SEARCH_SPHERE_DISTANCE, path: halfPath}, - {name: "full", distance: DEFAULT_SEARCH_SPHERE_DISTANCE, path: fullPath}, - {name: "hold", distance: DEFAULT_SEARCH_SPHERE_DISTANCE, path: holdPath}]; + var renderStates = [ + {name: "half", path: halfPath, end: halfEnd}, + {name: "full", path: fullPath, end: fullEnd}, + {name: "hold", path: holdPath} + ]; + + var defaultRenderStates = [ + {name: "half", distance: DEFAULT_SEARCH_SPHERE_DISTANCE, path: halfPath}, + {name: "full", distance: DEFAULT_SEARCH_SPHERE_DISTANCE, path: fullPath}, + {name: "hold", distance: DEFAULT_SEARCH_SPHERE_DISTANCE, path: holdPath} + ]; var GRABBABLE_PROPERTIES = [ "position", @@ -132,10 +137,7 @@ Script.include("/~/system/libraries/controllers.js"); var dim = {x: radius, y: radius, z: radius}; var mode = "hold"; if (!this.distanceHolding && !this.distanceRotating) { - // mode = (this.triggerSmoothedGrab() || this.secondarySqueezed()) ? "full" : "half"; - if (controllerData.triggerClicks[this.hand] - // || this.secondarySqueezed() // XXX - ) { + if (controllerData.triggerClicks[this.hand]) { mode = "full"; } else { mode = "half"; @@ -339,44 +341,44 @@ Script.include("/~/system/libraries/controllers.js"); this.notPointingAtEntity = function(controllerData) { var intersection = controllerData.rayPicks[this.hand]; - var entityProperty = Entities.getEntityProperties(intersection.objectID); + var entityProperty = Entities.getEntityProperties(intersection.objectID); var entityType = entityProperty.type; - if ((intersection.type === RayPick.INTERSECTED_ENTITY && entityType === "Web") || intersection.type === RayPick.INTERSECTED_OVERLAY) { + if ((intersection.type === RayPick.INTERSECTED_ENTITY && entityType === "Web") || intersection.type === RayPick.INTERSECTED_OVERLAY) { return true; } - return false + return false; }; this.distanceRotate = function(otherFarGrabModule) { - this.distanceRotating = true; + this.distanceRotating = true; this.distanceHolding = false; var worldControllerRotation = getControllerWorldLocation(this.handToController(), true).orientation; var controllerRotationDelta = Quat.multiply(worldControllerRotation, Quat.inverse(this.previousWorldControllerRotation)); // Rotate entity by twice the delta rotation. controllerRotationDelta = Quat.multiply(controllerRotationDelta, controllerRotationDelta); - + // Perform the rotation in the translation controller's action update. otherFarGrabModule.currentObjectRotation = Quat.multiply(controllerRotationDelta, - otherFarGrabModule.currentObjectRotation); - + otherFarGrabModule.currentObjectRotation); + // Rotate about the translation controller's target position. this.offsetPosition = Vec3.multiplyQbyV(controllerRotationDelta, this.offsetPosition); otherFarGrabModule.offsetPosition = Vec3.multiplyQbyV(controllerRotationDelta, - otherFarGrabModule.offsetPosition); - + otherFarGrabModule.offsetPosition); + this.updateLaserPointer(); - + this.previousWorldControllerRotation = worldControllerRotation; }; this.prepareDistanceRotatingData = function(controllerData) { var intersection = controllerData.rayPicks[this.hand]; - + var controllerLocation = getControllerWorldLocation(this.handToController(), true); var worldControllerPosition = controllerLocation.position; var worldControllerRotation = controllerLocation.orientation; - + var grabbedProperties = Entities.getEntityProperties(intersection.objectID, GRABBABLE_PROPERTIES); this.currentObjectPosition = grabbedProperties.position; this.grabRadius = intersection.distance; @@ -385,7 +387,7 @@ Script.include("/~/system/libraries/controllers.js"); var targetPosition = Vec3.multiply(this.grabRadius, Quat.getUp(worldControllerRotation)); targetPosition = Vec3.sum(targetPosition, worldControllerPosition); this.offsetPosition = Vec3.subtract(this.currentObjectPosition, targetPosition); - + // Initial controller rotation. this.previousWorldControllerRotation = worldControllerRotation; }; @@ -395,13 +397,13 @@ Script.include("/~/system/libraries/controllers.js"); ContextOverlay.destroyContextOverlay(this.entityWithContextOverlay); this.entityWithContextOverlay = false; } - } + }; this.isReady = function (controllerData) { if (this.notPointingAtEntity(controllerData)) { return makeRunningValues(false, [], []); } - + this.distanceHolding = false; this.distanceRotating = false; @@ -418,10 +420,15 @@ Script.include("/~/system/libraries/controllers.js"); this.isPointingAtUI = function(controllerData) { var hudRayPickInfo = controllerData.hudRayPicks[this.hand]; var hudPoint2d = HMD.overlayFromWorldPoint(hudRayPickInfo.intersection); - } + if (Reticle.pointingAtSystemOverlay || Overlays.getOverlayAtPoint(hudPoint2d || Reticle.position)) { + return true; + } + + return false; + }; this.run = function (controllerData) { - if (controllerData.triggerValues[this.hand] < TRIGGER_OFF_VALUE || this.notPointingAtEntity(controllerData)) { + if (controllerData.triggerValues[this.hand] < TRIGGER_OFF_VALUE || this.notPointingAtEntity(controllerData) || this.isPointingAtUI(controllerData)) { this.endNearGrabAction(); this.laserPointerOff(); return makeRunningValues(false, [], []); @@ -432,12 +439,16 @@ Script.include("/~/system/libraries/controllers.js"); this.destroyContextOverlay(); } + var otherModuleName =this.hand === RIGHT_HAND ? "LeftFarActionGrabEntity" : "RightFarActionGrabEntity"; + var otherFarGrabModule = getEnabledModuleByName(otherModuleName); + // gather up the readiness of the near-grab modules var nearGrabNames = [ this.hand === RIGHT_HAND ? "RightNearActionGrabEntity" : "LeftNearActionGrabEntity", this.hand === RIGHT_HAND ? "RightNearParentingGrabEntity" : "LeftNearParentingGrabEntity", this.hand === RIGHT_HAND ? "RightNearParentingGrabOverlay" : "LeftNearParentingGrabOverlay" ]; + var nearGrabReadiness = []; for (var i = 0; i < nearGrabNames.length; i++) { var nearGrabModule = getEnabledModuleByName(nearGrabNames[i]); @@ -449,19 +460,14 @@ Script.include("/~/system/libraries/controllers.js"); // if we are doing a distance grab and the object gets close enough to the controller, // stop the far-grab so the near-grab or equip can take over. for (var k = 0; k < nearGrabReadiness.length; k++) { - if (nearGrabReadiness[k].active && nearGrabReadiness[k].targets[0] == this.grabbedThingID) { + if (nearGrabReadiness[k].active && nearGrabReadiness[k].targets[0] === this.grabbedThingID) { this.laserPointerOff(); this.endNearGrabAction(); return makeRunningValues(false, [], []); } } - this.continueDistanceHolding(controllerData); - // this.updateLaserPointer(controllerData, false, false); - - // var args = [this.hand === RIGHT_HAND ? "right" : "left", MyAvatar.sessionUUID]; - // Entities.callEntityMethod(this.grabbedThingID, "continueFarGrab", args); } else { // if we are doing a distance search and this controller moves into a position // where it could near-grab something, stop searching. @@ -473,23 +479,22 @@ Script.include("/~/system/libraries/controllers.js"); } var rayPickInfo = controllerData.rayPicks[this.hand]; - var hudRayPickInfo = controllerData.hudRayPicks[this.hand]; - var hudPoint2d = HMD.overlayFromWorldPoint(hudRayPickInfo.intersection); - if (rayPickInfo.type == RayPick.INTERSECTED_ENTITY) { + if (rayPickInfo.type === RayPick.INTERSECTED_ENTITY) { if (controllerData.triggerClicks[this.hand]) { var entityID = rayPickInfo.objectID; - var targetProps = Entities.getEntityProperties(entityID, ["dynamic", "shapeType", "position", - "rotation", "dimensions", "density", - "userData", "locked", "type"]); + 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) { + + if (otherFarGrabModule.grabbedThingID === this.grabbedThingID && otherFarGrabModule.distanceHolding) { this.distanceRotate(otherFarGrabModule); } else { this.distanceHolding = true; @@ -519,14 +524,7 @@ Script.include("/~/system/libraries/controllers.js"); }, 500); } } else if (this.distanceRotating) { - var otherModuleName = - this.hand == RIGHT_HAND ? "LeftFarActionGrabEntity" : "RightFarActionGrabEntity"; - var otherFarGrabModule = getEnabledModuleByName(otherModuleName); this.distanceRotate(otherFarGrabModule); - } else if (Reticle.pointingAtSystemOverlay || Overlays.getOverlayAtPoint(hudPoint2d || Reticle.position)) { - this.endNearGrabAction(); - this.laserPointerOff(); - return makeRunningValues(false, [], []); } } return makeRunningValues(true, [], []); @@ -540,7 +538,7 @@ Script.include("/~/system/libraries/controllers.js"); this.halfEnd = halfEnd; this.fullEnd = fullEnd; this.laserPointer = LaserPointers.createLaserPointer({ - joint: (this.hand == RIGHT_HAND) ? "_CAMERA_RELATIVE_CONTROLLER_RIGHTHAND" : "_CAMERA_RELATIVE_CONTROLLER_LEFTHAND", + joint: (this.hand === RIGHT_HAND) ? "_CAMERA_RELATIVE_CONTROLLER_RIGHTHAND" : "_CAMERA_RELATIVE_CONTROLLER_LEFTHAND", filter: RayPick.PICK_ENTITIES | RayPick.PICK_OVERLAYS, maxDistance: PICK_MAX_DISTANCE, posOffset: getGrabPointSphereOffset(this.handToController()), diff --git a/scripts/system/controllers/controllerModules/inEditMode.js b/scripts/system/controllers/controllerModules/inEditMode.js index 782fb5dbc2..fc7e0b526e 100644 --- a/scripts/system/controllers/controllerModules/inEditMode.js +++ b/scripts/system/controllers/controllerModules/inEditMode.js @@ -1,4 +1,4 @@ -"use strict" +"use strict"; // inEditMode.js // @@ -8,7 +8,10 @@ /* 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 + AVATAR_SELF_ID, HMD, INCHES_TO_METERS, DEFAULT_REGISTRATION_POINT, Settings, getGrabPointSphereOffset, + COLORS_GRAB_SEARCHING_HALF_SQUEEZE, COLORS_GRAB_SEARCHING_FULL_SQUEEZE, COLORS_GRAB_DISTANCE_HOLD, + DEFAULT_SEARCH_SPHERE_DISTANCE, TRIGGER_ON_VALUE, TRIGGER_OFF_VALUE, getEnabledModuleByName, PICK_MAX_DISTANCE, + isInEditMode */ Script.include("/~/system/controllers/controllerDispatcherUtils.js"); @@ -71,13 +74,17 @@ Script.include("/~/system/libraries/utils.js"); parentID: AVATAR_SELF_ID }; - var renderStates = [{name: "half", path: halfPath, end: halfEnd}, - {name: "full", path: fullPath, end: fullEnd}, - {name: "hold", path: holdPath}]; - - var defaultRenderStates = [{name: "half", distance: DEFAULT_SEARCH_SPHERE_DISTANCE, path: halfPath}, - {name: "full", distance: DEFAULT_SEARCH_SPHERE_DISTANCE, path: fullPath}, - {name: "hold", distance: DEFAULT_SEARCH_SPHERE_DISTANCE, path: holdPath}]; + var renderStates = [ + {name: "half", path: halfPath, end: halfEnd}, + {name: "full", path: fullPath, end: fullEnd}, + {name: "hold", path: holdPath} + ]; + + var defaultRenderStates = [ + {name: "half", distance: DEFAULT_SEARCH_SPHERE_DISTANCE, path: halfPath}, + {name: "full", distance: DEFAULT_SEARCH_SPHERE_DISTANCE, path: fullPath}, + {name: "hold", distance: DEFAULT_SEARCH_SPHERE_DISTANCE, path: holdPath} + ]; function InEditMode(hand) { this.hand = hand; @@ -97,7 +104,7 @@ Script.include("/~/system/libraries/utils.js"); } return false; }; - + this.handToController = function() { return (this.hand === RIGHT_HAND) ? Controller.Standard.RightHand : Controller.Standard.LeftHand; }; @@ -116,7 +123,7 @@ Script.include("/~/system/libraries/utils.js"); this.updateLaserPointer = function(controllerData) { var RADIUS = 0.005; var dim = { x: RADIUS, y: RADIUS, z: RADIUS }; - + if (this.mode === "full") { this.fullEnd.dimensions = dim; LaserPointers.editRenderState(this.laserPointer, this.mode, {path: fullPath, end: this.fullEnd}); @@ -124,11 +131,11 @@ Script.include("/~/system/libraries/utils.js"); this.halfEnd.dimensions = dim; LaserPointers.editRenderState(this.laserPointer, this.mode, {path: halfPath, end: this.halfEnd}); } - + LaserPointers.enableLaserPointer(this.laserPointer); LaserPointers.setRenderState(this.laserPointer, this.mode); }; - + this.pointingAtTablet = function(objectID) { if (objectID === HMD.tabletScreenID || objectID === HMD.tabletButtonID) { return true; @@ -157,16 +164,21 @@ Script.include("/~/system/libraries/utils.js"); } }; - this.isReady = function(controllerData) { - var overlays = controllerData.nearbyOverlayIDs[this.hand]; - var objectID = controllerData.rayPicks[this.hand].objectID; + this.exitModule = function() { + this.disableLasers(); + return makeRunningValues(false, [], []); + }; + this.disableLasers = function() { + LaserPointers.disableLaserPointer(this.laserPointer); + }; + + this.isReady = function(controllerData) { if (isInEditMode()) { this.triggerClicked = false; return makeRunningValues(true, [], []); } - - return makeRunningValues(false, [], []); + return this.exitModule(); }; this.run = function(controllerData) { @@ -175,44 +187,44 @@ Script.include("/~/system/libraries/utils.js"); var tabletReady = tabletStylusInput.isReady(controllerData); if (tabletReady.active) { - return makeRunningValues(false, [], []); + return this.exitModule(); } } - var overlayLaser = getEnabledModuleByName(this.hand === RIGHT_HAND ? "RightOverlayLaserInput" : "LeftOverlayLaserInput"); + 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, [], []); + return this.exitModule(); } } - var nearOverlay = getEnabledModuleByName(this.hand === RIGHT_HAND ? "RightNearParentingGrabOverlay" : "LeftNearParentingGrabOverlay"); + 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.exitModule(); } } this.processControllerTriggers(controllerData); this.updateLaserPointer(controllerData); this.sendPickData(controllerData); - + return this.isReady(controllerData); }; - this.cleanup = function() { + this.cleanup = function() { LaserPointers.disableLaserPointer(this.laserPointer); LaserPointers.removeLaserPointer(this.laserPointer); - } + }; this.halfEnd = halfEnd; this.fullEnd = fullEnd; - + this.laserPointer = LaserPointers.createLaserPointer({ joint: (this.hand === RIGHT_HAND) ? "_CONTROLLER_RIGHTHAND" : "_CONTROLLER_LEFTHAND", filter: RayPick.PICK_ENTITIES | RayPick.PICK_OVERLAYS, @@ -222,10 +234,9 @@ Script.include("/~/system/libraries/utils.js"); faceAvatar: true, defaultRenderStates: defaultRenderStates }); - - LaserPointers.setIgnoreOverlays(this.laserPointer, [HMD.tabletID, HMD.tabletButtonID, HMD.tabletScreenID]); - }; + LaserPointers.setIgnoreOverlays(this.laserPointer, [HMD.tabletID, HMD.tabletButtonID, HMD.tabletScreenID]); + } var leftHandInEditMode = new InEditMode(LEFT_HAND); var rightHandInEditMode = new InEditMode(RIGHT_HAND); diff --git a/scripts/system/controllers/controllerModules/nearParentGrabOverlay.js b/scripts/system/controllers/controllerModules/nearParentGrabOverlay.js index 2cea81ce18..f0a5b9f07d 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( - 140, + 90, this.hand === RIGHT_HAND ? ["rightHand"] : ["leftHand"], [], 100); diff --git a/scripts/system/controllers/controllerModules/overlayLaserInput.js b/scripts/system/controllers/controllerModules/overlayLaserInput.js index 8a14fc49ae..ec2aa7750a 100644 --- a/scripts/system/controllers/controllerModules/overlayLaserInput.js +++ b/scripts/system/controllers/controllerModules/overlayLaserInput.js @@ -1,4 +1,4 @@ -"use strict" +"use strict"; // overlayLaserInput.js // @@ -8,16 +8,16 @@ /* 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 + AVATAR_SELF_ID, HMD, INCHES_TO_METERS, DEFAULT_REGISTRATION_POINT, Settings, getGrabPointSphereOffset, + COLORS_GRAB_SEARCHING_HALF_SQUEEZE, COLORS_GRAB_SEARCHING_FULL_SQUEEZE, COLORS_GRAB_DISTANCE_HOLD, + DEFAULT_SEARCH_SPHERE_DISTANCE, TRIGGER_ON_VALUE, TRIGGER_OFF_VALUE, getEnabledModuleByName, PICK_MAX_DISTANCE */ - - Script.include("/~/system/controllers/controllerDispatcherUtils.js"); Script.include("/~/system/libraries/controllers.js"); (function() { - var halfPath = { + var halfPath = { type: "line3d", color: COLORS_GRAB_SEARCHING_HALF_SQUEEZE, visible: true, @@ -72,13 +72,17 @@ Script.include("/~/system/libraries/controllers.js"); parentID: AVATAR_SELF_ID }; - var renderStates = [{name: "half", path: halfPath, end: halfEnd}, - {name: "full", path: fullPath, end: fullEnd}, - {name: "hold", path: holdPath}]; + var renderStates = [ + {name: "half", path: halfPath, end: halfEnd}, + {name: "full", path: fullPath, end: fullEnd}, + {name: "hold", path: holdPath} + ]; - var defaultRenderStates = [{name: "half", distance: DEFAULT_SEARCH_SPHERE_DISTANCE, path: halfPath}, - {name: "full", distance: DEFAULT_SEARCH_SPHERE_DISTANCE, path: fullPath}, - {name: "hold", distance: DEFAULT_SEARCH_SPHERE_DISTANCE, path: holdPath}]; + var defaultRenderStates = [ + {name: "half", distance: DEFAULT_SEARCH_SPHERE_DISTANCE, path: halfPath}, + {name: "full", distance: DEFAULT_SEARCH_SPHERE_DISTANCE, path: fullPath}, + {name: "hold", distance: DEFAULT_SEARCH_SPHERE_DISTANCE, path: holdPath} + ]; // triggered when stylus presses a web overlay/entity @@ -200,7 +204,7 @@ Script.include("/~/system/libraries/controllers.js"); } // will return undefined if overlayID does not exist. - function calculateLaserTargetFromOverlay(laserTip, overlayID) { + function calculateLaserTargetFromOverlay(worldPos, overlayID) { var overlayPosition = Overlays.getProperty(overlayID, "position"); if (overlayPosition === undefined) { return null; @@ -212,12 +216,11 @@ Script.include("/~/system/libraries/controllers.js"); return null; } var normal = Vec3.multiplyQbyV(overlayRotation, {x: 0, y: 0, z: 1}); - var distance = Vec3.dot(Vec3.subtract(laserTip, overlayPosition), normal); - var position = Vec3.subtract(laserTip, Vec3.multiply(normal, distance)); + var distance = Vec3.dot(Vec3.subtract(worldPos, overlayPosition), normal); // calclulate normalized position var invRot = Quat.inverse(overlayRotation); - var localPos = Vec3.multiplyQbyV(invRot, Vec3.subtract(position, overlayPosition)); + var localPos = Vec3.multiplyQbyV(invRot, Vec3.subtract(worldPos, overlayPosition)); var dpi = Overlays.getProperty(overlayID, "dpi"); var dimensions; @@ -228,12 +231,12 @@ Script.include("/~/system/libraries/controllers.js"); if (resolution === undefined) { return null; } - resolution.z = 1; // Circumvent divide-by-zero. + resolution.z = 1;// Circumvent divide-by-zero. var scale = Overlays.getProperty(overlayID, "dimensions"); if (scale === undefined) { return null; } - scale.z = 0.01; // overlay dimensions are 2D, not 3D. + scale.z = 0.01;// overlay dimensions are 2D, not 3D. dimensions = Vec3.multiplyVbyV(Vec3.multiply(resolution, INCHES_TO_METERS / dpi), scale); } else { dimensions = Overlays.getProperty(overlayID, "dimensions"); @@ -241,21 +244,23 @@ Script.include("/~/system/libraries/controllers.js"); return null; } if (!dimensions.z) { - dimensions.z = 0.01; // sometimes overlay dimensions are 2D, not 3D. + dimensions.z = 0.01;// sometimes overlay dimensions are 2D, not 3D. } } var invDimensions = { x: 1 / dimensions.x, y: 1 / dimensions.y, z: 1 / dimensions.z }; var normalizedPosition = Vec3.sum(Vec3.multiplyVbyV(localPos, invDimensions), DEFAULT_REGISTRATION_POINT); // 2D position on overlay plane in meters, relative to the bounding box upper-left hand corner. - var position2D = { x: normalizedPosition.x * dimensions.x, - y: (1 - normalizedPosition.y) * dimensions.y }; // flip y-axis + var position2D = { + x: normalizedPosition.x * dimensions.x, + y: (1 - normalizedPosition.y) * dimensions.y // flip y-axis + }; return { entityID: null, overlayID: overlayID, distance: distance, - position: position, + position: worldPos, position2D: position2D, normal: normal, normalizedPosition: normalizedPosition, @@ -400,8 +405,8 @@ Script.include("/~/system/libraries/controllers.js"); if (this.laserTarget) { var POINTER_PRESS_TO_MOVE_DELAY = 0.33; // seconds if (this.deadspotExpired || this.touchingEnterTimer > POINTER_PRESS_TO_MOVE_DELAY || - distance2D(this.laserTarget.position2D, - this.pressEnterLaserTarget.position2D) > this.deadspotRadius) { + distance2D( this.laserTarget.position2D, + this.pressEnterLaserTarget.position2D) > this.deadspotRadius) { sendTouchMoveEventToLaserTarget(this.hand, this.laserTarget); this.deadspotExpired = true; } @@ -412,7 +417,7 @@ Script.include("/~/system/libraries/controllers.js"); this.releaseTouchEvent = function() { sendTouchEndEventToLaserTarget(this.hand, this.pressEnterLaserTarget); - } + }; this.updateLaserTargets = function(controllerData) { @@ -423,9 +428,9 @@ Script.include("/~/system/libraries/controllers.js"); this.shouldExit = function(controllerData) { var intersection = controllerData.rayPicks[this.hand]; - var offOverlay = (intersection.type !== RayPick.INTERSECTED_OVERLAY) + var offOverlay = (intersection.type !== RayPick.INTERSECTED_OVERLAY); return offOverlay; - } + }; this.exitModule = function() { this.releaseTouchEvent(); @@ -433,7 +438,7 @@ Script.include("/~/system/libraries/controllers.js"); this.reset(); this.updateLaserPointer(); LaserPointers.disableLaserPointer(this.laserPointer); - } + }; this.reset = function() { this.hover = false; @@ -515,7 +520,7 @@ Script.include("/~/system/libraries/controllers.js"); this.halfEnd = halfEnd; this.fullEnd = fullEnd; this.laserPointer = LaserPointers.createLaserPointer({ - joint: (this.hand == RIGHT_HAND) ? "_CONTROLLER_RIGHTHAND" : "_CONTROLLER_LEFTHAND", + joint: (this.hand === RIGHT_HAND) ? "_CONTROLLER_RIGHTHAND" : "_CONTROLLER_LEFTHAND", filter: RayPick.PICK_OVERLAYS, maxDistance: PICK_MAX_DISTANCE, posOffset: getGrabPointSphereOffset(this.handToController()), @@ -525,7 +530,7 @@ Script.include("/~/system/libraries/controllers.js"); }); LaserPointers.setIgnoreOverlays(this.laserPointer, [HMD.tabletID]); - }; + } var leftOverlayLaserInput = new OverlayLaserInput(LEFT_HAND); var rightOverlayLaserInput = new OverlayLaserInput(RIGHT_HAND); diff --git a/scripts/system/controllers/controllerModules/tabletStylusInput.js b/scripts/system/controllers/controllerModules/tabletStylusInput.js index bbe8f935ae..9720bc8022 100644 --- a/scripts/system/controllers/controllerModules/tabletStylusInput.js +++ b/scripts/system/controllers/controllerModules/tabletStylusInput.js @@ -171,12 +171,12 @@ Script.include("/~/system/libraries/controllers.js"); if (resolution === undefined) { return; } - resolution.z = 1; // Circumvent divide-by-zero. + resolution.z = 1; // Circumvent divide-by-zero. var scale = Overlays.getProperty(overlayID, "dimensions"); if (scale === undefined) { return; } - scale.z = 0.01; // overlay dimensions are 2D, not 3D. + scale.z = 0.01; // overlay dimensions are 2D, not 3D. dimensions = Vec3.multiplyVbyV(Vec3.multiply(resolution, INCHES_TO_METERS / dpi), scale); } else { dimensions = Overlays.getProperty(overlayID, "dimensions"); @@ -184,15 +184,17 @@ Script.include("/~/system/libraries/controllers.js"); return; } if (!dimensions.z) { - dimensions.z = 0.01; // sometimes overlay dimensions are 2D, not 3D. + dimensions.z = 0.01; // sometimes overlay dimensions are 2D, not 3D. } } var invDimensions = { x: 1 / dimensions.x, y: 1 / dimensions.y, z: 1 / dimensions.z }; var normalizedPosition = Vec3.sum(Vec3.multiplyVbyV(localPos, invDimensions), DEFAULT_REGISTRATION_POINT); // 2D position on overlay plane in meters, relative to the bounding box upper-left hand corner. - var position2D = { x: normalizedPosition.x * dimensions.x, - y: (1 - normalizedPosition.y) * dimensions.y }; // flip y-axis + var position2D = { + x: normalizedPosition.x * dimensions.x, + y: (1 - normalizedPosition.y) * dimensions.y // flip y-axis + }; return { entityID: null, @@ -227,8 +229,10 @@ Script.include("/~/system/libraries/controllers.js"); var normalizedPosition = Vec3.sum(Vec3.multiplyVbyV(localPos, invDimensions), props.registrationPoint); // 2D position on entity plane in meters, relative to the bounding box upper-left hand corner. - var position2D = { x: normalizedPosition.x * props.dimensions.x, - y: (1 - normalizedPosition.y) * props.dimensions.y }; // flip y-axis + var position2D = { + x: normalizedPosition.x * props.dimensions.x, + y: (1 - normalizedPosition.y) * props.dimensions.y // flip y-axis + }; return { entityID: props.id, @@ -354,7 +358,7 @@ Script.include("/~/system/libraries/controllers.js"); // translate tip forward according to constant. var TIP_OFFSET = {x: 0, y: WEB_STYLUS_LENGTH - WEB_TOUCH_Y_OFFSET, z: 0}; this.stylusTip.position = Vec3.sum(this.stylusTip.position, - Vec3.multiplyQbyV(this.stylusTip.orientation, TIP_OFFSET)); + Vec3.multiplyQbyV(this.stylusTip.orientation, TIP_OFFSET)); } // compute tip velocity from hand controller motion, it is more accurate than computing it from previous positions. @@ -363,9 +367,8 @@ Script.include("/~/system/libraries/controllers.js"); var worldControllerPos = Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(MyAvatar.orientation, pose.translation)); var worldControllerLinearVel = Vec3.multiplyQbyV(MyAvatar.orientation, pose.velocity); var worldControllerAngularVel = Vec3.multiplyQbyV(MyAvatar.orientation, pose.angularVelocity); - var tipVelocity = Vec3.sum(worldControllerLinearVel, - Vec3.cross(worldControllerAngularVel, - Vec3.subtract(this.stylusTip.position, worldControllerPos))); + var tipVelocity = Vec3.sum(worldControllerLinearVel, Vec3.cross(worldControllerAngularVel, + Vec3.subtract(this.stylusTip.position, worldControllerPos))); this.stylusTip.velocity = tipVelocity; } else { this.stylusTip.velocity = {x: 0, y: 0, z: 0}; @@ -381,10 +384,11 @@ Script.include("/~/system/libraries/controllers.js"); name: "stylus", url: Script.resourcesPath() + "meshes/tablet-stylus-fat.fbx", loadPriority: 10.0, - localPosition: Vec3.sum({ x: 0.0, - y: WEB_TOUCH_Y_OFFSET, - z: 0.0 }, - getGrabPointSphereOffset(this.handToController())), + localPosition: Vec3.sum({ + x: 0.0, + y: WEB_TOUCH_Y_OFFSET, + z: 0.0 + }, getGrabPointSphereOffset(this.handToController())), localRotation: Quat.fromVec3Degrees({ x: -90, y: 0, z: 0 }), dimensions: { x: 0.01, y: 0.01, z: WEB_STYLUS_LENGTH }, solid: true, @@ -393,8 +397,8 @@ Script.include("/~/system/libraries/controllers.js"); drawInFront: false, parentID: AVATAR_SELF_ID, parentJointIndex: MyAvatar.getJointIndex(this.hand === RIGHT_HAND ? - "_CAMERA_RELATIVE_CONTROLLER_RIGHTHAND" : - "_CAMERA_RELATIVE_CONTROLLER_LEFTHAND") + "_CAMERA_RELATIVE_CONTROLLER_RIGHTHAND" : + "_CAMERA_RELATIVE_CONTROLLER_LEFTHAND") }; this.stylus = Overlays.addOverlay("model", stylusProperties); }; @@ -524,8 +528,8 @@ Script.include("/~/system/libraries/controllers.js"); } this.isNearStylusTarget = isNearStylusTarget(stylusTargets, EDGE_BORDER + hysteresisOffset, - TABLET_MIN_TOUCH_DISTANCE - hysteresisOffset, - WEB_DISPLAY_STYLUS_DISTANCE + hysteresisOffset); + TABLET_MIN_TOUCH_DISTANCE - hysteresisOffset, + WEB_DISPLAY_STYLUS_DISTANCE + hysteresisOffset); if (this.isNearStylusTarget) { if (!this.useFingerInsteadOfStylus) { @@ -630,7 +634,7 @@ Script.include("/~/system/libraries/controllers.js"); var POINTER_PRESS_TO_MOVE_DELAY = 0.33; // seconds if (this.deadspotExpired || this.touchingEnterTimer > POINTER_PRESS_TO_MOVE_DELAY || distance2D(this.stylusTarget.position2D, - this.touchingEnterStylusTarget.position2D) > this.deadspotRadius) { + this.touchingEnterStylusTarget.position2D) > this.deadspotRadius) { sendTouchMoveEventToStylusTarget(this.hand, this.stylusTarget); this.deadspotExpired = true; } diff --git a/scripts/system/controllers/controllerModules/webEntityLaserInput.js b/scripts/system/controllers/controllerModules/webEntityLaserInput.js index e88e75684c..747e1bae44 100644 --- a/scripts/system/controllers/controllerModules/webEntityLaserInput.js +++ b/scripts/system/controllers/controllerModules/webEntityLaserInput.js @@ -5,14 +5,14 @@ // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -/*jslint bitwise: true */ +/* jslint bitwise: true */ /* global Script, Controller, LaserPointers, RayPick, RIGHT_HAND, LEFT_HAND, Mat4, MyAvatar, Vec3, Camera, Quat, getGrabPointSphereOffset, getEnabledModuleByName, makeRunningValues, Entities, NULL_UUID, enableDispatcherModule, disableDispatcherModule, entityIsDistanceGrabbable, makeDispatcherModuleParameters, MSECS_PER_SEC, HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION, PICK_MAX_DISTANCE, COLORS_GRAB_SEARCHING_HALF_SQUEEZE, COLORS_GRAB_SEARCHING_FULL_SQUEEZE, COLORS_GRAB_DISTANCE_HOLD, - AVATAR_SELF_ID, DEFAULT_SEARCH_SPHERE_DISTANCE, TRIGGER_OFF_VALUE, TRIGGER_ON_VALUE, + AVATAR_SELF_ID, DEFAULT_SEARCH_SPHERE_DISTANCE, TRIGGER_OFF_VALUE, TRIGGER_ON_VALUE, ZERO_VEC */ @@ -20,7 +20,7 @@ Script.include("/~/system/controllers/controllerDispatcherUtils.js"); Script.include("/~/system/libraries/controllers.js"); (function() { - var halfPath = { + var halfPath = { type: "line3d", color: COLORS_GRAB_SEARCHING_HALF_SQUEEZE, visible: true, @@ -75,13 +75,17 @@ Script.include("/~/system/libraries/controllers.js"); parentID: AVATAR_SELF_ID }; - var renderStates = [{name: "half", path: halfPath, end: halfEnd}, - {name: "full", path: fullPath, end: fullEnd}, - {name: "hold", path: holdPath}]; + var renderStates = [ + {name: "half", path: halfPath, end: halfEnd}, + {name: "full", path: fullPath, end: fullEnd}, + {name: "hold", path: holdPath} + ]; - var defaultRenderStates = [{name: "half", distance: DEFAULT_SEARCH_SPHERE_DISTANCE, path: halfPath}, - {name: "full", distance: DEFAULT_SEARCH_SPHERE_DISTANCE, path: fullPath}, - {name: "hold", distance: DEFAULT_SEARCH_SPHERE_DISTANCE, path: holdPath}]; + var defaultRenderStates = [ + {name: "half", distance: DEFAULT_SEARCH_SPHERE_DISTANCE, path: halfPath}, + {name: "full", distance: DEFAULT_SEARCH_SPHERE_DISTANCE, path: fullPath}, + {name: "hold", distance: DEFAULT_SEARCH_SPHERE_DISTANCE, path: holdPath} + ]; // triggered when stylus presses a web overlay/entity @@ -143,7 +147,7 @@ Script.include("/~/system/libraries/controllers.js"); } - function sendTouchStartEventToLaserTarget(hand, laserTarget) { + function sendTouchStartEventToLaserTarget(hand, laserTarget) { var pointerEvent = { type: "Press", id: hand + 1, // 0 is reserved for hardware mouse @@ -208,16 +212,18 @@ Script.include("/~/system/libraries/controllers.js"); Vec3.multiplyQbyV(props.rotation, {x: 0, y: 1, z: 0}); var distance = Vec3.dot(Vec3.subtract(intersection, props.position), normal); var position = Vec3.subtract(intersection, Vec3.multiply(normal, distance)); - + // generate normalized coordinates var invRot = Quat.inverse(props.rotation); var localPos = Vec3.multiplyQbyV(invRot, Vec3.subtract(position, props.position)); var invDimensions = { x: 1 / props.dimensions.x, y: 1 / props.dimensions.y, z: 1 / props.dimensions.z }; var normalizedPosition = Vec3.sum(Vec3.multiplyVbyV(localPos, invDimensions), props.registrationPoint); - + // 2D position on entity plane in meters, relative to the bounding box upper-left hand corner. - var position2D = { x: normalizedPosition.x * props.dimensions.x, - y: (1 - normalizedPosition.y) * props.dimensions.y }; // flip y-axis + var position2D = { + x: normalizedPosition.x * props.dimensions.x, + y: (1 - normalizedPosition.y) * props.dimensions.y // flip y-axis + }; return { entityID: props.id, @@ -258,7 +264,7 @@ Script.include("/~/system/libraries/controllers.js"); this.getOtherModule = function() { return (this.hand === RIGHT_HAND) ? leftWebEntityLaserInput : rightWebEntityLaserInput; }; - + this.parameters = makeDispatcherModuleParameters( 550, this.hand === RIGHT_HAND ? ["rightHand"] : ["leftHand"], @@ -288,7 +294,7 @@ Script.include("/~/system/libraries/controllers.js"); }; this.processControllerTriggers = function(controllerData) { - if (controllerData.triggerClicks[this.hand]) { + if (controllerData.triggerClicks[this.hand]) { this.mode = "full"; this.laserPressingTarget = true; this.hover = false; @@ -316,7 +322,7 @@ Script.include("/~/system/libraries/controllers.js"); this.laserPressEnter = function () { sendTouchStartEventToLaserTarget(this.hand, this.laserTarget); Controller.triggerHapticPulse(HAPTIC_STYLUS_STRENGTH, HAPTIC_STYLUS_DURATION, this.hand); - + this.touchingEnterTimer = 0; this.pressEnterLaserTarget = this.laserTarget; this.deadspotExpired = false; @@ -340,12 +346,12 @@ Script.include("/~/system/libraries/controllers.js"); this.laserPressing = function (controllerData, dt) { this.touchingEnterTimer += dt; - + if (this.laserTarget) { var POINTER_PRESS_TO_MOVE_DELAY = 0.33; // seconds if (this.deadspotExpired || this.touchingEnterTimer > POINTER_PRESS_TO_MOVE_DELAY || distance2D(this.laserTarget.position2D, - this.pressEnterLaserTarget.position2D) > this.deadspotRadius) { + this.pressEnterLaserTarget.position2D) > this.deadspotRadius) { sendTouchMoveEventToLaserTarget(this.hand, this.laserTarget); this.deadspotExpired = true; } @@ -353,19 +359,19 @@ Script.include("/~/system/libraries/controllers.js"); this.laserPressingTarget = false; } }; - + this.releaseTouchEvent = function() { if (this.pressEnterLaserTarget === null) { return; } sendTouchEndEventToLaserTarget(this.hand, this.pressEnterLaserTarget); - } + }; this.updateLaserPointer = function(controllerData) { var RADIUS = 0.005; var dim = { x: RADIUS, y: RADIUS, z: RADIUS }; - + if (this.mode === "full") { fullEnd.dimensions = dim; LaserPointers.editRenderState(this.laserPointer, this.mode, {path: fullPath, end: fullEnd}); @@ -373,7 +379,7 @@ Script.include("/~/system/libraries/controllers.js"); halfEnd.dimensions = dim; LaserPointers.editRenderState(this.laserPointer, this.mode, {path: halfPath, end: halfEnd}); } - + LaserPointers.enableLaserPointer(this.laserPointer); LaserPointers.setRenderState(this.laserPointer, this.mode); }; @@ -386,7 +392,7 @@ Script.include("/~/system/libraries/controllers.js"); if ((intersection.type === RayPick.INTERSECTED_ENTITY && entityType === "Web")) { return true; } - return false + return false; }; this.exitModule = function() { @@ -396,7 +402,7 @@ Script.include("/~/system/libraries/controllers.js"); this.updateLaserPointer(); LaserPointers.disableLaserPointer(this.laserPointer); }; - + this.reset = function() { this.pressEnterLaserTarget = null; this.laserTarget = null; @@ -412,7 +418,7 @@ Script.include("/~/system/libraries/controllers.js"); if (this.isPointingAtWebEntity(controllerData) && !otherModule.active) { return makeRunningValues(true, [], []); } - + return makeRunningValues(false, [], []); }; @@ -433,7 +439,7 @@ Script.include("/~/system/libraries/controllers.js"); this.laserPressExit(); } this.previousLaserClickedTarget = this.laserPressingTarget; - + if (this.laserPressingTarget) { this.laserPressing(controllerData, deltaTime); } @@ -447,7 +453,7 @@ Script.include("/~/system/libraries/controllers.js"); this.cleanup = function() { LaserPointers.disableLaserPointer(this.laserPointer); LaserPointers.removeLaserPointer(this.laserPointer); - } + }; this.laserPointer = LaserPointers.createLaserPointer({ joint: (this.hand === RIGHT_HAND) ? "_CONTROLLER_RIGHTHAND" : "_CONTROLLER_LEFTHAND", @@ -458,13 +464,13 @@ Script.include("/~/system/libraries/controllers.js"); faceAvatar: true, defaultRenderStates: defaultRenderStates }); - }; + } var leftWebEntityLaserInput = new WebEntityLaserInput(LEFT_HAND); var rightWebEntityLaserInput = new WebEntityLaserInput(RIGHT_HAND); - enableDispatcherModule("LeftWebEntityLaserInput", leftWebEntityLaserInput); + enableDispatcherModule("LeftWebEntityLaserInput", leftWebEntityLaserInput); enableDispatcherModule("RightWebEntityLaserInput", rightWebEntityLaserInput); this.cleanup = function() { @@ -474,5 +480,5 @@ Script.include("/~/system/libraries/controllers.js"); disableDispatcherModule("RightWebEntityLaserInput"); }; Script.scriptEnding.connect(this.cleanup); - + }());