diff --git a/scripts/system/controllers/controllerDispatcher.js b/scripts/system/controllers/controllerDispatcher.js index 4fc8c84d5f..d79c2bd236 100644 --- a/scripts/system/controllers/controllerDispatcher.js +++ b/scripts/system/controllers/controllerDispatcher.js @@ -240,11 +240,14 @@ Script.include("/~/system/controllers/controllerDispatcherUtils.js"); var orderedPluginName = this.orderedPluginNames[pluginIndex]; var candidatePlugin = controllerDispatcherPlugins[orderedPluginName]; - if (_this.slotsAreAvailableForPlugin(candidatePlugin) && candidatePlugin.isReady(controllerData, deltaTime)) { - // this plugin will start. add it to the list of running plugins and mark the - // activity-slots which this plugin consumes as "in use" - _this.runningPluginNames[orderedPluginName] = true; - _this.markSlots(candidatePlugin, orderedPluginName); + if (_this.slotsAreAvailableForPlugin(candidatePlugin)) { + var readiness = candidatePlugin.isReady(controllerData, deltaTime); + if (readiness.active) { + // this plugin will start. add it to the list of running plugins and mark the + // activity-slots which this plugin consumes as "in use" + _this.runningPluginNames[orderedPluginName] = true; + _this.markSlots(candidatePlugin, orderedPluginName); + } } } @@ -257,11 +260,14 @@ Script.include("/~/system/controllers/controllerDispatcherUtils.js"); // them available. delete _this.runningPluginNames[runningPluginName]; _this.unmarkSlotsForPluginName(runningPluginName); - } else if (!plugin.run(controllerData, deltaTime)) { - // plugin is finished running, for now. remove it from the list - // of running plugins and mark its activity-slots as "not in use" - delete _this.runningPluginNames[runningPluginName]; - _this.markSlots(plugin, false); + } else { + var runningness = plugin.run(controllerData, deltaTime); + if (!runningness.active) { + // plugin is finished running, for now. remove it from the list + // of running plugins and mark its activity-slots as "not in use" + delete _this.runningPluginNames[runningPluginName]; + _this.markSlots(plugin, false); + } } } } diff --git a/scripts/system/controllers/controllerDispatcherUtils.js b/scripts/system/controllers/controllerDispatcherUtils.js index e2cea96a42..e52c158219 100644 --- a/scripts/system/controllers/controllerDispatcherUtils.js +++ b/scripts/system/controllers/controllerDispatcherUtils.js @@ -18,8 +18,10 @@ COLORS_GRAB_SEARCHING_FULL_SQUEEZE, COLORS_GRAB_DISTANCE_HOLD, makeDispatcherModuleParameters, + makeRunningValues, enableDispatcherModule, disableDispatcherModule, + getEnabledModuleByName, getGrabbableData, entityIsGrabbable, getControllerJointIndex, @@ -61,17 +63,24 @@ COLORS_GRAB_DISTANCE_HOLD = { red: 238, green: 75, blue: 214 }; // priority -- a lower priority means the module will be asked sooner than one with a higher priority in a given update step // activitySlots -- indicates which "slots" must not yet be in use for this module to start -// requiredDataForStart -- which "situation" parts this module looks at to decide if it will start +// requiredDataForReady -- which "situation" parts this module looks at to decide if it will start // sleepMSBetweenRuns -- how long to wait between calls to this module's "run" method -makeDispatcherModuleParameters = function (priority, activitySlots, requiredDataForStart, sleepMSBetweenRuns) { +makeDispatcherModuleParameters = function (priority, activitySlots, requiredDataForReady, sleepMSBetweenRuns) { return { priority: priority, activitySlots: activitySlots, - requiredDataForStart: requiredDataForStart, + requiredDataForReady: requiredDataForReady, sleepMSBetweenRuns: sleepMSBetweenRuns }; }; +makeRunningValues = function (active, targets, requiredDataForRun) { + return { + active: active, + targets: targets, + requiredDataForRun: requiredDataForRun + }; +}; enableDispatcherModule = function (moduleName, module, priority) { if (!controllerDispatcherPlugins) { @@ -86,6 +95,13 @@ disableDispatcherModule = function (moduleName) { controllerDispatcherPluginsNeedSort = true; }; +getEnabledModuleByName = function (moduleName) { + if (controllerDispatcherPlugins.hasOwnProperty(moduleName)) { + return controllerDispatcherPlugins[moduleName]; + } + return null; +}; + getGrabbableData = function (props) { // look in userData for a "grabbable" key, return the value or some defaults var grabbableData = {}; diff --git a/scripts/system/controllers/controllerModules/farActionGrabEntity.js b/scripts/system/controllers/controllerModules/farActionGrabEntity.js index 3d1964d639..6b54b0fe25 100644 --- a/scripts/system/controllers/controllerModules/farActionGrabEntity.js +++ b/scripts/system/controllers/controllerModules/farActionGrabEntity.js @@ -8,7 +8,7 @@ /*jslint bitwise: true */ /* global Script, Controller, LaserPointers, RayPick, RIGHT_HAND, LEFT_HAND, - getGrabPointSphereOffset, entityIsGrabbable, + getGrabPointSphereOffset, getEnabledModuleByName, makeRunningValues, enableDispatcherModule, disableDispatcherModule, makeDispatcherModuleParameters, PICK_MAX_DISTANCE, COLORS_GRAB_SEARCHING_HALF_SQUEEZE, COLORS_GRAB_SEARCHING_FULL_SQUEEZE, COLORS_GRAB_DISTANCE_HOLD, @@ -135,8 +135,8 @@ Script.include("/~/system/libraries/controllers.js"); }; this.laserPointerOff = function() { - var laserPointerID = PICK_WITH_HAND_RAY ? this.laserPointer : this.headLaserPointer; - LaserPointers.disableLaserPointer(laserPointerID); + LaserPointers.disableLaserPointer(this.laserPointer); + LaserPointers.disableLaserPointer(this.headLaserPointer); }; @@ -145,38 +145,49 @@ Script.include("/~/system/libraries/controllers.js"); }; this.isReady = function (controllerData) { + if (controllerData.triggerValues[this.hand] > TRIGGER_ON_VALUE) { this.updateLaserPointer(controllerData, false, false); - return true; + return makeRunningValues(true, [], []); } else { - return false; + return makeRunningValues(false, [], []); } }; this.run = function (controllerData) { if (controllerData.triggerValues[this.hand] < TRIGGER_OFF_VALUE) { this.laserPointerOff(); - return false; + return makeRunningValues(false, [], []); } + // 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]); + var ready = nearGrabModule ? nearGrabModule.isReady(controllerData) : makeRunningValues(false, [], []); + nearGrabReadiness.push(ready); + } // if we are doing a distance search and this controller moves into a position // where it could near-grab something, stop searching. - var nearbyEntityProperties = controllerData.nearbyEntityProperties[this.hand]; - for (var i = 0; i < nearbyEntityProperties.length; i++) { - var props = nearbyEntityProperties[i]; - if (entityIsGrabbable(props)) { + for (var j = 0; j < nearGrabReadiness.length; j++) { + if (nearGrabReadiness[j].active) { this.laserPointerOff(); - return false; + return makeRunningValues(false, [], []); } } - + // this.updateLaserPointer(controllerData, false, false); // var args = [this.hand === RIGHT_HAND ? "right" : "left", MyAvatar.sessionUUID]; // Entities.callEntityMethod(this.grabbedThingID, "continueFarGrab", args); - return true; + return makeRunningValues(true, [], []); }; this.cleanup = function () { diff --git a/scripts/system/controllers/controllerModules/nearActionGrabEntity.js b/scripts/system/controllers/controllerModules/nearActionGrabEntity.js index d6b5ffe4f7..8017f457fe 100644 --- a/scripts/system/controllers/controllerModules/nearActionGrabEntity.js +++ b/scripts/system/controllers/controllerModules/nearActionGrabEntity.js @@ -8,7 +8,8 @@ /* global Script, Entities, MyAvatar, Controller, RIGHT_HAND, LEFT_HAND, getControllerJointIndex, getGrabbableData, NULL_UUID, enableDispatcherModule, disableDispatcherModule, propsArePhysical, Messages, HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION, entityIsGrabbable, - Quat, Vec3, MSECS_PER_SEC, getControllerWorldLocation, makeDispatcherModuleParameters + Quat, Vec3, MSECS_PER_SEC, getControllerWorldLocation, makeDispatcherModuleParameters, makeRunningValues, + TRIGGER_OFF_VALUE */ Script.include("/~/system/controllers/controllerDispatcherUtils.js"); @@ -18,7 +19,7 @@ Script.include("/~/system/libraries/controllers.js"); function NearActionGrabEntity(hand) { this.hand = hand; - this.grabbedThingID = null; + this.targetEntityID = null; this.actionID = null; // action this script created... this.parameters = makeDispatcherModuleParameters( @@ -54,10 +55,10 @@ Script.include("/~/system/libraries/controllers.js"); }; - this.startNearGrabAction = function (controllerData, grabbedProperties) { + this.startNearGrabAction = function (controllerData, targetProps) { Controller.triggerHapticPulse(HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION, this.hand); - var grabbableData = getGrabbableData(grabbedProperties); + var grabbableData = getGrabbableData(targetProps); this.ignoreIK = grabbableData.ignoreIK; this.kinematicGrab = grabbableData.kinematicGrab; @@ -74,10 +75,10 @@ Script.include("/~/system/libraries/controllers.js"); handPosition = this.getHandPosition(); } - var objectRotation = grabbedProperties.rotation; + var objectRotation = targetProps.rotation; this.offsetRotation = Quat.multiply(Quat.inverse(handRotation), objectRotation); - var currentObjectPosition = grabbedProperties.position; + var currentObjectPosition = targetProps.position; var offset = Vec3.subtract(currentObjectPosition, handPosition); this.offsetPosition = Vec3.multiplyQbyV(Quat.inverse(Quat.multiply(handRotation, this.offsetRotation)), offset); @@ -85,9 +86,9 @@ Script.include("/~/system/libraries/controllers.js"); this.actionTimeout = now + (ACTION_TTL * MSECS_PER_SEC); if (this.actionID) { - Entities.deleteAction(this.grabbedThingID, this.actionID); + Entities.deleteAction(this.targetEntityID, this.actionID); } - this.actionID = Entities.addAction("hold", this.grabbedThingID, { + this.actionID = Entities.addAction("hold", this.targetEntityID, { hand: this.hand === RIGHT_HAND ? "right" : "left", timeScale: NEAR_GRABBING_ACTION_TIMEFRAME, relativePosition: this.offsetPosition, @@ -104,25 +105,17 @@ Script.include("/~/system/libraries/controllers.js"); Messages.sendMessage('Hifi-Object-Manipulation', JSON.stringify({ action: 'grab', - grabbedEntity: this.grabbedThingID, + grabbedEntity: this.targetEntityID, joint: this.hand === RIGHT_HAND ? "RightHand" : "LeftHand" })); }; - // this is for when the action creation failed, before - this.restartNearGrabAction = function (controllerData) { - var props = Entities.getEntityProperties(this.grabbedThingID, ["position", "rotation", "userData"]); - if (props && entityIsGrabbable(props)) { - this.startNearGrabAction(controllerData, props); - } - }; - // this is for when the action is going to time-out this.refreshNearGrabAction = function (controllerData) { var now = Date.now(); if (this.actionID && this.actionTimeout - now < ACTION_TTL_REFRESH * MSECS_PER_SEC) { // if less than a 5 seconds left, refresh the actions ttl - var success = Entities.updateAction(this.grabbedThingID, this.actionID, { + var success = Entities.updateAction(this.targetEntityID, this.actionID, { hand: this.hand === RIGHT_HAND ? "right" : "left", timeScale: NEAR_GRABBING_ACTION_TIMEFRAME, relativePosition: this.offsetPosition, @@ -134,74 +127,101 @@ Script.include("/~/system/libraries/controllers.js"); }); if (success) { this.actionTimeout = now + (ACTION_TTL * MSECS_PER_SEC); - } else { - print("continueNearGrabbing -- updateAction failed"); - this.restartNearGrabAction(controllerData); } } }; - this.endNearGrabAction = function (controllerData) { + this.endNearGrabAction = function () { var args = [this.hand === RIGHT_HAND ? "right" : "left", MyAvatar.sessionUUID]; - Entities.callEntityMethod(this.grabbedThingID, "releaseGrab", args); + Entities.callEntityMethod(this.targetEntityID, "releaseGrab", args); - Entities.deleteAction(this.grabbedThingID, this.actionID); + Entities.deleteAction(this.targetEntityID, this.actionID); this.actionID = null; - this.grabbedThingID = null; + this.targetEntityID = null; }; - this.isReady = function (controllerData) { - if (controllerData.triggerClicks[this.hand] == 0) { - return false; - } - - var grabbedProperties = null; - // nearbyEntityProperties is already sorted by length from controller + this.getTargetProps = function (controllerData) { + // nearbyEntityProperties is already sorted by distance from controller var nearbyEntityProperties = controllerData.nearbyEntityProperties[this.hand]; for (var i = 0; i < nearbyEntityProperties.length; i++) { var props = nearbyEntityProperties[i]; if (entityIsGrabbable(props)) { - grabbedProperties = props; - break; + return props; } } + return null; + }; - if (grabbedProperties) { - if (!propsArePhysical(grabbedProperties)) { - return false; // let nearParentGrabEntity handle it + this.isReady = function (controllerData) { + this.targetEntityID = null; + + if (controllerData.triggerValues[this.hand] < TRIGGER_OFF_VALUE) { + makeRunningValues(false, [], []); + } + + var targetProps = this.getTargetProps(controllerData); + if (targetProps) { + if (!propsArePhysical(targetProps)) { + // XXX make sure no highlights are enabled from this module + return makeRunningValues(false, [], []); // let nearParentGrabEntity handle it + } else { + this.targetEntityID = targetProps.id; + // XXX highlight this.targetEntityID here + return makeRunningValues(true, [this.targetEntityID], []); } - this.grabbedThingID = grabbedProperties.id; - this.startNearGrabAction(controllerData, grabbedProperties); - return true; } else { - return false; + // XXX make sure no highlights are enabled from this module + return makeRunningValues(false, [], []); } }; this.run = function (controllerData) { - if (controllerData.triggerClicks[this.hand] == 0) { - this.endNearGrabAction(controllerData); - return false; + if (this.actionID) { + if (controllerData.triggerClicks[this.hand] == 0) { + this.endNearGrabAction(); + return makeRunningValues(false, [], []); + } + + this.refreshNearGrabAction(controllerData); + + var args = [this.hand === RIGHT_HAND ? "right" : "left", MyAvatar.sessionUUID]; + Entities.callEntityMethod(this.targetEntityID, "continueNearGrab", args); + } else { + // still searching / highlighting + var readiness = this.isReady (controllerData); + if (!readiness.active) { + return readiness; + } + if (controllerData.triggerClicks[this.hand] == 1) { + // stop highlighting, switch to grabbing + // XXX stop highlight here + var targetProps = this.getTargetProps(controllerData); + if (targetProps) { + this.startNearGrabAction(controllerData, targetProps); + } + } } - if (!this.actionID) { - this.restartNearGrabAction(controllerData); + return makeRunningValues(true, [this.targetEntityID], []); + }; + + this.cleanup = function () { + if (this.targetEntityID) { + this.endNearGrabAction(); } - - this.refreshNearGrabAction(controllerData); - - var args = [this.hand === RIGHT_HAND ? "right" : "left", MyAvatar.sessionUUID]; - Entities.callEntityMethod(this.grabbedThingID, "continueNearGrab", args); - - return true; }; } - enableDispatcherModule("LeftNearActionGrabEntity", new NearActionGrabEntity(LEFT_HAND)); - enableDispatcherModule("RightNearActionGrabEntity", new NearActionGrabEntity(RIGHT_HAND)); + var leftNearActionGrabEntity = new NearActionGrabEntity(LEFT_HAND); + var rightNearActionGrabEntity = new NearActionGrabEntity(RIGHT_HAND); + + enableDispatcherModule("LeftNearActionGrabEntity", leftNearActionGrabEntity); + enableDispatcherModule("RightNearActionGrabEntity", rightNearActionGrabEntity); this.cleanup = function () { + leftNearActionGrabEntity.cleanup(); + rightNearActionGrabEntity.cleanup(); disableDispatcherModule("LeftNearActionGrabEntity"); disableDispatcherModule("RightNearActionGrabEntity"); }; diff --git a/scripts/system/controllers/controllerModules/nearParentGrabEntity.js b/scripts/system/controllers/controllerModules/nearParentGrabEntity.js index 58bd3d2dab..1de2fee5ea 100644 --- a/scripts/system/controllers/controllerModules/nearParentGrabEntity.js +++ b/scripts/system/controllers/controllerModules/nearParentGrabEntity.js @@ -8,8 +8,8 @@ /* global Script, Entities, MyAvatar, Controller, RIGHT_HAND, LEFT_HAND, AVATAR_SELF_ID, getControllerJointIndex, NULL_UUID, enableDispatcherModule, disableDispatcherModule, - propsArePhysical, Messages, HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION, - makeDispatcherModuleParameters, entityIsGrabbable + propsArePhysical, Messages, HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION, TRIGGER_OFF_VALUE, + makeDispatcherModuleParameters, entityIsGrabbable, makeRunningValues */ Script.include("/~/system/controllers/controllerDispatcherUtils.js"); @@ -21,7 +21,8 @@ Script.include("/~/system/controllers/controllerDispatcherUtils.js"); function NearParentingGrabEntity(hand) { this.hand = hand; - this.grabbedThingID = null; + this.targetEntityID = null; + this.grabbing = false; this.previousParentID = {}; this.previousParentJointIndex = {}; this.previouslyUnhooked = {}; @@ -62,7 +63,7 @@ Script.include("/~/system/controllers/controllerDispatcherUtils.js"); return false; }; - this.startNearParentingGrabEntity = function (controllerData, grabbedProperties) { + this.startNearParentingGrabEntity = function (controllerData, targetProps) { Controller.triggerHapticPulse(HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION, this.hand); var handJointIndex; @@ -74,7 +75,7 @@ Script.include("/~/system/controllers/controllerDispatcherUtils.js"); handJointIndex = this.controllerJointIndex; var args = [this.hand === RIGHT_HAND ? "right" : "left", MyAvatar.sessionUUID]; - Entities.callEntityMethod(this.grabbedThingID, "startNearGrab", args); + Entities.callEntityMethod(targetProps.id, "startNearGrab", args); var reparentProps = { parentID: AVATAR_SELF_ID, @@ -83,90 +84,127 @@ Script.include("/~/system/controllers/controllerDispatcherUtils.js"); angularVelocity: {x: 0, y: 0, z: 0} }; - if (this.thisHandIsParent(grabbedProperties)) { + if (this.thisHandIsParent(targetProps)) { // this should never happen, but if it does, don't set previous parent to be this hand. - // this.previousParentID[this.grabbedThingID] = NULL; - // this.previousParentJointIndex[this.grabbedThingID] = -1; + // this.previousParentID[targetProps.id] = NULL; + // this.previousParentJointIndex[targetProps.id] = -1; } else { - this.previousParentID[this.grabbedThingID] = grabbedProperties.parentID; - this.previousParentJointIndex[this.grabbedThingID] = grabbedProperties.parentJointIndex; + this.previousParentID[targetProps.id] = targetProps.parentID; + this.previousParentJointIndex[targetProps.id] = targetProps.parentJointIndex; } - Entities.editEntity(this.grabbedThingID, reparentProps); + Entities.editEntity(targetProps.id, reparentProps); Messages.sendMessage('Hifi-Object-Manipulation', JSON.stringify({ action: 'grab', - grabbedEntity: this.grabbedThingID, + grabbedEntity: targetProps.id, joint: this.hand === RIGHT_HAND ? "RightHand" : "LeftHand" })); }; - this.endNearParentingGrabEntity = function (controllerData) { - if (this.previousParentID[this.grabbedThingID] === NULL_UUID) { - Entities.editEntity(this.grabbedThingID, { - parentID: this.previousParentID[this.grabbedThingID], - parentJointIndex: this.previousParentJointIndex[this.grabbedThingID] + this.endNearParentingGrabEntity = function () { + if (this.previousParentID[this.targetEntityID] === NULL_UUID) { + Entities.editEntity(this.targetEntityID, { + parentID: this.previousParentID[this.targetEntityID], + parentJointIndex: this.previousParentJointIndex[this.targetEntityID] }); } else { // we're putting this back as a child of some other parent, so zero its velocity - Entities.editEntity(this.grabbedThingID, { - parentID: this.previousParentID[this.grabbedThingID], - parentJointIndex: this.previousParentJointIndex[this.grabbedThingID], + Entities.editEntity(this.targetEntityID, { + parentID: this.previousParentID[this.targetEntityID], + parentJointIndex: this.previousParentJointIndex[this.targetEntityID], velocity: {x: 0, y: 0, z: 0}, angularVelocity: {x: 0, y: 0, z: 0} }); } var args = [this.hand === RIGHT_HAND ? "right" : "left", MyAvatar.sessionUUID]; - Entities.callEntityMethod(this.grabbedThingID, "releaseGrab", args); + Entities.callEntityMethod(this.targetEntityID, "releaseGrab", args); - this.grabbedThingID = null; + this.grabbing = false; + this.targetEntityID = null; }; - this.isReady = function (controllerData) { - if (controllerData.triggerClicks[this.hand] == 0) { - return false; - } - - var grabbedProperties = null; + 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]; if (entityIsGrabbable(props)) { - grabbedProperties = props; - break; + return props; } } + return null; + }; - if (grabbedProperties) { - if (propsArePhysical(grabbedProperties)) { - return false; // let nearActionGrabEntity handle it + this.isReady = function (controllerData) { + this.targetEntityID = null; + this.grabbing = false; + + if (controllerData.triggerValues[this.hand] < TRIGGER_OFF_VALUE) { + makeRunningValues(false, [], []); + } + + var targetProps = this.getTargetProps(controllerData); + if (targetProps) { + if (propsArePhysical(targetProps)) { + // XXX make sure no highlights are enabled from this module + return makeRunningValues(false, [], []); // let nearActionGrabEntity handle it + } else { + this.targetEntityID = targetProps.id; + // XXX highlight this.targetEntityID here + return makeRunningValues(true, [this.targetEntityID], []); } - this.grabbedThingID = grabbedProperties.id; - this.startNearParentingGrabEntity(controllerData, grabbedProperties); - return true; } else { - return false; + // XXX make sure no highlights are enabled from this module + return makeRunningValues(false, [], []); } }; this.run = function (controllerData) { - if (controllerData.triggerClicks[this.hand] == 0) { - this.endNearParentingGrabEntity(controllerData); - return false; + if (this.grabbing) { + if (controllerData.triggerClicks[this.hand] == 0) { + this.endNearParentingGrabEntity(); + return makeRunningValues(false, [], []); + } + + var args = [this.hand === RIGHT_HAND ? "right" : "left", MyAvatar.sessionUUID]; + Entities.callEntityMethod(this.targetEntityID, "continueNearGrab", args); + } else { + // still searching / highlighting + var readiness = this.isReady (controllerData); + if (!readiness.active) { + return readiness; + } + if (controllerData.triggerClicks[this.hand] == 1) { + // stop highlighting, switch to grabbing + // XXX stop highlight here + var targetProps = this.getTargetProps(controllerData); + if (targetProps) { + this.grabbing = true; + this.startNearParentingGrabEntity(controllerData, targetProps); + } + } } - var args = [this.hand === RIGHT_HAND ? "right" : "left", MyAvatar.sessionUUID]; - Entities.callEntityMethod(this.grabbedThingID, "continueNearGrab", args); + return makeRunningValues(true, [this.targetEntityID], []); + }; - return true; + this.cleanup = function () { + if (this.targetEntityID) { + this.endNearParentingGrabEntity(); + } }; } - enableDispatcherModule("LeftNearParentingGrabEntity", new NearParentingGrabEntity(LEFT_HAND)); - enableDispatcherModule("RightNearParentingGrabEntity", new NearParentingGrabEntity(RIGHT_HAND)); + var leftNearParentingGrabEntity = new NearParentingGrabEntity(LEFT_HAND); + var rightNearParentingGrabEntity = new NearParentingGrabEntity(RIGHT_HAND); + + enableDispatcherModule("LeftNearParentingGrabEntity", leftNearParentingGrabEntity); + enableDispatcherModule("RightNearParentingGrabEntity", rightNearParentingGrabEntity); this.cleanup = function () { + leftNearParentingGrabEntity.cleanup(); + rightNearParentingGrabEntity.cleanup(); disableDispatcherModule("LeftNearParentingGrabEntity"); disableDispatcherModule("RightNearParentingGrabEntity"); }; diff --git a/scripts/system/controllers/controllerModules/nearParentGrabOverlay.js b/scripts/system/controllers/controllerModules/nearParentGrabOverlay.js index 9ce0b95abb..58b6a12090 100644 --- a/scripts/system/controllers/controllerModules/nearParentGrabOverlay.js +++ b/scripts/system/controllers/controllerModules/nearParentGrabOverlay.js @@ -9,7 +9,7 @@ /* global Script, MyAvatar, Controller, RIGHT_HAND, LEFT_HAND, AVATAR_SELF_ID, getControllerJointIndex, NULL_UUID, enableDispatcherModule, disableDispatcherModule, Messages, HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION, - makeDispatcherModuleParameters, Overlays + makeDispatcherModuleParameters, Overlays, makeRunningValues */ Script.include("/~/system/controllers/controllerDispatcherUtils.js"); @@ -106,7 +106,7 @@ Script.include("/~/system/controllers/controllerDispatcherUtils.js"); })); }; - this.endNearParentingGrabOverlay = function (controllerData) { + this.endNearParentingGrabOverlay = function () { if (this.previousParentID[this.grabbedThingID] === NULL_UUID) { Overlays.editOverlay(this.grabbedThingID, { parentID: NULL_UUID, @@ -125,7 +125,7 @@ Script.include("/~/system/controllers/controllerDispatcherUtils.js"); this.isReady = function (controllerData) { if (controllerData.triggerClicks[this.hand] == 0) { - return false; + return makeRunningValues(false, [], []); } this.grabbedThingID = null; @@ -138,26 +138,37 @@ Script.include("/~/system/controllers/controllerDispatcherUtils.js"); if (grabbableOverlays.length > 0) { this.grabbedThingID = grabbableOverlays[0]; this.startNearParentingGrabOverlay(controllerData); - return true; + return makeRunningValues(true, [this.grabbedThingID], []); } else { - return false; + return makeRunningValues(false, [], []); } }; this.run = function (controllerData) { if (controllerData.triggerClicks[this.hand] == 0) { - this.endNearParentingGrabOverlay(controllerData); - return false; + this.endNearParentingGrabOverlay(); + return makeRunningValues(false, [], []); } else { - return true; + return makeRunningValues(true, [this.grabbedThingID], []); + } + }; + + this.cleanup = function () { + if (this.grabbedThingID) { + this.endNearParentingGrabOverlay(); } }; } - enableDispatcherModule("LeftNearParentingGrabOverlay", new NearParentingGrabOverlay(LEFT_HAND)); - enableDispatcherModule("RightNearParentingGrabOverlay", new NearParentingGrabOverlay(RIGHT_HAND)); + var leftNearParentingGrabOverlay = new NearParentingGrabOverlay(LEFT_HAND); + var rightNearParentingGrabOverlay = new NearParentingGrabOverlay(RIGHT_HAND); + + enableDispatcherModule("LeftNearParentingGrabOverlay", leftNearParentingGrabOverlay); + enableDispatcherModule("RightNearParentingGrabOverlay", rightNearParentingGrabOverlay); this.cleanup = function () { + leftNearParentingGrabOverlay.cleanup(); + rightNearParentingGrabOverlay.cleanup(); disableDispatcherModule("LeftNearParentingGrabOverlay"); disableDispatcherModule("RightNearParentingGrabOverlay"); }; diff --git a/scripts/system/controllers/controllerModules/tabletStylusInput.js b/scripts/system/controllers/controllerModules/tabletStylusInput.js index 7e9f69959f..8ada1b31d7 100644 --- a/scripts/system/controllers/controllerModules/tabletStylusInput.js +++ b/scripts/system/controllers/controllerModules/tabletStylusInput.js @@ -6,7 +6,7 @@ // 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, + 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 */ @@ -643,7 +643,11 @@ Script.include("/~/system/libraries/controllers.js"); }; this.isReady = function (controllerData) { - return this.processStylus(controllerData); + if (this.processStylus(controllerData)) { + return makeRunningValues(true, [], []); + } else { + return makeRunningValues(false, [], []); + } }; this.run = function (controllerData, deltaTime) { @@ -660,7 +664,11 @@ Script.include("/~/system/libraries/controllers.js"); if (this.stylusTouchingTarget) { this.stylusTouching(controllerData, deltaTime); } - return this.processStylus(controllerData); + if (this.processStylus(controllerData)) { + return makeRunningValues(true, [], []); + } else { + return makeRunningValues(false, [], []); + } }; this.cleanup = function () { @@ -674,12 +682,11 @@ Script.include("/~/system/libraries/controllers.js"); enableDispatcherModule("LeftTabletStylusInput", leftTabletStylusInput); enableDispatcherModule("RightTabletStylusInput", rightTabletStylusInput); - this.cleanup = function () { - disableDispatcherModule("LeftTabletStylusInput"); - disableDispatcherModule("RightTabletStylusInput"); leftTabletStylusInput.cleanup(); rightTabletStylusInput.cleanup(); + disableDispatcherModule("LeftTabletStylusInput"); + disableDispatcherModule("RightTabletStylusInput"); }; Script.scriptEnding.connect(this.cleanup); }());