Showing the changes to scripts/system/controllers/controllerModules (5 of 7 files). Show all
Unified · Split
| @@ -8,7 +8,7 @@ · 7 unmodified lines | |||
| 8 | /*jslint bitwise: true */ | 8 | /*jslint bitwise: true */ |
| 9 | 9 | ||
| 10 | /* global Script, Controller, LaserPointers, RayPick, RIGHT_HAND, LEFT_HAND, | 10 | /* global Script, Controller, LaserPointers, RayPick, RIGHT_HAND, LEFT_HAND, |
| 11 | getGrabPointSphereOffset, entityIsGrabbable, | 11 | getGrabPointSphereOffset, getEnabledModuleByName, makeRunningValues, |
| 12 | enableDispatcherModule, disableDispatcherModule, | 12 | enableDispatcherModule, disableDispatcherModule, |
| 13 | makeDispatcherModuleParameters, | 13 | makeDispatcherModuleParameters, |
| 14 | PICK_MAX_DISTANCE, COLORS_GRAB_SEARCHING_HALF_SQUEEZE, COLORS_GRAB_SEARCHING_FULL_SQUEEZE, COLORS_GRAB_DISTANCE_HOLD, | 14 | 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"); · 120 unmodified lines | |||
| 135 | }; | 135 | }; |
| 136 | 136 | ||
| 137 | this.laserPointerOff = function() { | 137 | this.laserPointerOff = function() { |
| 138 | var laserPointerID = PICK_WITH_HAND_RAY ? this.laserPointer : this.headLaserPointer; | 138 | LaserPointers.disableLaserPointer(this.laserPointer); |
| 139 | LaserPointers.disableLaserPointer(laserPointerID); | 139 | LaserPointers.disableLaserPointer(this.headLaserPointer); |
| 140 | }; | 140 | }; |
| 141 | 141 | ||
| 142 | 142 | ||
| @@ -145,38 +145,49 @@ Script.include("/~/system/libraries/controllers.js"); · 2 unmodified lines | |||
| 145 | }; | 145 | }; |
| 146 | 146 | ||
| 147 | this.isReady = function (controllerData) { | 147 | this.isReady = function (controllerData) { |
| 148 | |||
| 148 | if (controllerData.triggerValues[this.hand] > TRIGGER_ON_VALUE) { | 149 | if (controllerData.triggerValues[this.hand] > TRIGGER_ON_VALUE) { |
| 149 | this.updateLaserPointer(controllerData, false, false); | 150 | this.updateLaserPointer(controllerData, false, false); |
| 150 | return true; | 151 | return makeRunningValues(true, [], []); |
| 151 | } else { | 152 | } else { |
| 152 | return false; | 153 | return makeRunningValues(false, [], []); |
| 153 | } | 154 | } |
| 154 | }; | 155 | }; |
| 155 | 156 | ||
| 156 | this.run = function (controllerData) { | 157 | this.run = function (controllerData) { |
| 157 | if (controllerData.triggerValues[this.hand] < TRIGGER_OFF_VALUE) { | 158 | if (controllerData.triggerValues[this.hand] < TRIGGER_OFF_VALUE) { |
| 158 | this.laserPointerOff(); | 159 | this.laserPointerOff(); |
| 159 | return false; | 160 | return makeRunningValues(false, [], []); |
| 160 | } | 161 | } |
| 161 | 162 | ||
| 163 | // gather up the readiness of the near-grab modules | ||
| 164 | var nearGrabNames = [ | ||
| 165 | this.hand === RIGHT_HAND ? "RightNearActionGrabEntity" : "LeftNearActionGrabEntity", | ||
| 166 | this.hand === RIGHT_HAND ? "RightNearParentingGrabEntity" : "LeftNearParentingGrabEntity", | ||
| 167 | this.hand === RIGHT_HAND ? "RightNearParentingGrabOverlay" : "LeftNearParentingGrabOverlay" | ||
| 168 | ]; | ||
| 169 | var nearGrabReadiness = []; | ||
| 170 | for (var i = 0; i < nearGrabNames.length; i++) { | ||
| 171 | var nearGrabModule = getEnabledModuleByName(nearGrabNames[i]); | ||
| 172 | var ready = nearGrabModule ? nearGrabModule.isReady(controllerData) : makeRunningValues(false, [], []); | ||
| 173 | nearGrabReadiness.push(ready); | ||
| 174 | } | ||
| 162 | 175 | ||
| 163 | // if we are doing a distance search and this controller moves into a position | 176 | // if we are doing a distance search and this controller moves into a position |
| 164 | // where it could near-grab something, stop searching. | 177 | // where it could near-grab something, stop searching. |
| 165 | var nearbyEntityProperties = controllerData.nearbyEntityProperties[this.hand]; | 178 | for (var j = 0; j < nearGrabReadiness.length; j++) { |
| 166 | for (var i = 0; i < nearbyEntityProperties.length; i++) { | 179 | if (nearGrabReadiness[j].active) { |
| 167 | var props = nearbyEntityProperties[i]; | ||
| 168 | if (entityIsGrabbable(props)) { | ||
| 169 | this.laserPointerOff(); | 180 | this.laserPointerOff(); |
| 170 | return false; | 181 | return makeRunningValues(false, [], []); |
| 171 | } | 182 | } |
| 172 | } | 183 | } |
| 173 | 184 | ||
| 174 | // this.updateLaserPointer(controllerData, false, false); | 185 | // this.updateLaserPointer(controllerData, false, false); |
| 175 | 186 | ||
| 176 | // var args = [this.hand === RIGHT_HAND ? "right" : "left", MyAvatar.sessionUUID]; | 187 | // var args = [this.hand === RIGHT_HAND ? "right" : "left", MyAvatar.sessionUUID]; |
| 177 | // Entities.callEntityMethod(this.grabbedThingID, "continueFarGrab", args); | 188 | // Entities.callEntityMethod(this.grabbedThingID, "continueFarGrab", args); |
| 178 | 189 | ||
| 179 | return true; | 190 | return makeRunningValues(true, [], []); |
| 180 | }; | 191 | }; |
| 181 | 192 | ||
| 182 | this.cleanup = function () { | 193 | this.cleanup = function () { |
| @@ -8,7 +8,8 @@ · 7 unmodified lines | |||
| 8 | /* global Script, Entities, MyAvatar, Controller, RIGHT_HAND, LEFT_HAND, | 8 | /* global Script, Entities, MyAvatar, Controller, RIGHT_HAND, LEFT_HAND, |
| 9 | getControllerJointIndex, getGrabbableData, NULL_UUID, enableDispatcherModule, disableDispatcherModule, | 9 | getControllerJointIndex, getGrabbableData, NULL_UUID, enableDispatcherModule, disableDispatcherModule, |
| 10 | propsArePhysical, Messages, HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION, entityIsGrabbable, | 10 | propsArePhysical, Messages, HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION, entityIsGrabbable, |
| 11 | Quat, Vec3, MSECS_PER_SEC, getControllerWorldLocation, makeDispatcherModuleParameters | 11 | Quat, Vec3, MSECS_PER_SEC, getControllerWorldLocation, makeDispatcherModuleParameters, makeRunningValues, |
| 12 | TRIGGER_OFF_VALUE | ||
| 12 | */ | 13 | */ |
| 13 | 14 | ||
| 14 | Script.include("/~/system/controllers/controllerDispatcherUtils.js"); | 15 | Script.include("/~/system/controllers/controllerDispatcherUtils.js"); |
| @@ -18,7 +19,7 @@ Script.include("/~/system/libraries/controllers.js"); · 3 unmodified lines | |||
| 18 | 19 | ||
| 19 | function NearActionGrabEntity(hand) { | 20 | function NearActionGrabEntity(hand) { |
| 20 | this.hand = hand; | 21 | this.hand = hand; |
| 21 | this.grabbedThingID = null; | 22 | this.targetEntityID = null; |
| 22 | this.actionID = null; // action this script created... | 23 | this.actionID = null; // action this script created... |
| 23 | 24 | ||
| 24 | this.parameters = makeDispatcherModuleParameters( | 25 | this.parameters = makeDispatcherModuleParameters( |
| @@ -54,10 +55,10 @@ Script.include("/~/system/libraries/controllers.js"); · 29 unmodified lines | |||
| 54 | }; | 55 | }; |
| 55 | 56 | ||
| 56 | 57 | ||
| 57 | this.startNearGrabAction = function (controllerData, grabbedProperties) { | 58 | this.startNearGrabAction = function (controllerData, targetProps) { |
| 58 | Controller.triggerHapticPulse(HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION, this.hand); | 59 | Controller.triggerHapticPulse(HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION, this.hand); |
| 59 | 60 | ||
| 60 | var grabbableData = getGrabbableData(grabbedProperties); | 61 | var grabbableData = getGrabbableData(targetProps); |
| 61 | this.ignoreIK = grabbableData.ignoreIK; | 62 | this.ignoreIK = grabbableData.ignoreIK; |
| 62 | this.kinematicGrab = grabbableData.kinematicGrab; | 63 | this.kinematicGrab = grabbableData.kinematicGrab; |
| 63 | 64 | ||
| @@ -74,10 +75,10 @@ Script.include("/~/system/libraries/controllers.js"); · 10 unmodified lines | |||
| 74 | handPosition = this.getHandPosition(); | 75 | handPosition = this.getHandPosition(); |
| 75 | } | 76 | } |
| 76 | 77 | ||
| 77 | var objectRotation = grabbedProperties.rotation; | 78 | var objectRotation = targetProps.rotation; |
| 78 | this.offsetRotation = Quat.multiply(Quat.inverse(handRotation), objectRotation); | 79 | this.offsetRotation = Quat.multiply(Quat.inverse(handRotation), objectRotation); |
| 79 | 80 | ||
| 80 | var currentObjectPosition = grabbedProperties.position; | 81 | var currentObjectPosition = targetProps.position; |
| 81 | var offset = Vec3.subtract(currentObjectPosition, handPosition); | 82 | var offset = Vec3.subtract(currentObjectPosition, handPosition); |
| 82 | this.offsetPosition = Vec3.multiplyQbyV(Quat.inverse(Quat.multiply(handRotation, this.offsetRotation)), offset); | 83 | this.offsetPosition = Vec3.multiplyQbyV(Quat.inverse(Quat.multiply(handRotation, this.offsetRotation)), offset); |
| 83 | 84 | ||
| @@ -85,9 +86,9 @@ Script.include("/~/system/libraries/controllers.js"); · 1 unmodified line | |||
| 85 | this.actionTimeout = now + (ACTION_TTL * MSECS_PER_SEC); | 86 | this.actionTimeout = now + (ACTION_TTL * MSECS_PER_SEC); |
| 86 | 87 | ||
| 87 | if (this.actionID) { | 88 | if (this.actionID) { |
| 88 | Entities.deleteAction(this.grabbedThingID, this.actionID); | 89 | Entities.deleteAction(this.targetEntityID, this.actionID); |
| 89 | } | 90 | } |
| 90 | this.actionID = Entities.addAction("hold", this.grabbedThingID, { | 91 | this.actionID = Entities.addAction("hold", this.targetEntityID, { |
| 91 | hand: this.hand === RIGHT_HAND ? "right" : "left", | 92 | hand: this.hand === RIGHT_HAND ? "right" : "left", |
| 92 | timeScale: NEAR_GRABBING_ACTION_TIMEFRAME, | 93 | timeScale: NEAR_GRABBING_ACTION_TIMEFRAME, |
| 93 | relativePosition: this.offsetPosition, | 94 | relativePosition: this.offsetPosition, |
| @@ -104,25 +105,17 @@ Script.include("/~/system/libraries/controllers.js"); · 10 unmodified lines | |||
| 104 | 105 | ||
| 105 | Messages.sendMessage('Hifi-Object-Manipulation', JSON.stringify({ | 106 | Messages.sendMessage('Hifi-Object-Manipulation', JSON.stringify({ |
| 106 | action: 'grab', | 107 | action: 'grab', |
| 107 | grabbedEntity: this.grabbedThingID, | 108 | grabbedEntity: this.targetEntityID, |
| 108 | joint: this.hand === RIGHT_HAND ? "RightHand" : "LeftHand" | 109 | joint: this.hand === RIGHT_HAND ? "RightHand" : "LeftHand" |
| 109 | })); | 110 | })); |
| 110 | }; | 111 | }; |
| 111 | 112 | ||
| 112 | // this is for when the action creation failed, before | ||
| 113 | this.restartNearGrabAction = function (controllerData) { | ||
| 114 | var props = Entities.getEntityProperties(this.grabbedThingID, ["position", "rotation", "userData"]); | ||
| 115 | if (props && entityIsGrabbable(props)) { | ||
| 116 | this.startNearGrabAction(controllerData, props); | ||
| 117 | } | ||
| 118 | }; | ||
| 119 | |||
| 120 | // this is for when the action is going to time-out | 113 | // this is for when the action is going to time-out |
| 121 | this.refreshNearGrabAction = function (controllerData) { | 114 | this.refreshNearGrabAction = function (controllerData) { |
| 122 | var now = Date.now(); | 115 | var now = Date.now(); |
| 123 | if (this.actionID && this.actionTimeout - now < ACTION_TTL_REFRESH * MSECS_PER_SEC) { | 116 | if (this.actionID && this.actionTimeout - now < ACTION_TTL_REFRESH * MSECS_PER_SEC) { |
| 124 | // if less than a 5 seconds left, refresh the actions ttl | 117 | // if less than a 5 seconds left, refresh the actions ttl |
| 125 | var success = Entities.updateAction(this.grabbedThingID, this.actionID, { | 118 | var success = Entities.updateAction(this.targetEntityID, this.actionID, { |
| 126 | hand: this.hand === RIGHT_HAND ? "right" : "left", | 119 | hand: this.hand === RIGHT_HAND ? "right" : "left", |
| 127 | timeScale: NEAR_GRABBING_ACTION_TIMEFRAME, | 120 | timeScale: NEAR_GRABBING_ACTION_TIMEFRAME, |
| 128 | relativePosition: this.offsetPosition, | 121 | relativePosition: this.offsetPosition, |
| @@ -134,74 +127,101 @@ Script.include("/~/system/libraries/controllers.js"); · 5 unmodified lines | |||
| 134 | }); | 127 | }); |
| 135 | if (success) { | 128 | if (success) { |
| 136 | this.actionTimeout = now + (ACTION_TTL * MSECS_PER_SEC); | 129 | this.actionTimeout = now + (ACTION_TTL * MSECS_PER_SEC); |
| 137 | } else { | ||
| 138 | print("continueNearGrabbing -- updateAction failed"); | ||
| 139 | this.restartNearGrabAction(controllerData); | ||
| 140 | } | 130 | } |
| 141 | } | 131 | } |
| 142 | }; | 132 | }; |
| 143 | 133 | ||
| 144 | this.endNearGrabAction = function (controllerData) { | 134 | this.endNearGrabAction = function () { |
| 145 | var args = [this.hand === RIGHT_HAND ? "right" : "left", MyAvatar.sessionUUID]; | 135 | var args = [this.hand === RIGHT_HAND ? "right" : "left", MyAvatar.sessionUUID]; |
| 146 | Entities.callEntityMethod(this.grabbedThingID, "releaseGrab", args); | 136 | Entities.callEntityMethod(this.targetEntityID, "releaseGrab", args); |
| 147 | 137 | ||
| 148 | Entities.deleteAction(this.grabbedThingID, this.actionID); | 138 | Entities.deleteAction(this.targetEntityID, this.actionID); |
| 149 | this.actionID = null; | 139 | this.actionID = null; |
| 150 | 140 | ||
| 151 | this.grabbedThingID = null; | 141 | this.targetEntityID = null; |
| 152 | }; | 142 | }; |
| 153 | 143 | ||
| 154 | this.isReady = function (controllerData) { | 144 | this.getTargetProps = function (controllerData) { |
| 155 | if (controllerData.triggerClicks[this.hand] == 0) { | 145 | // nearbyEntityProperties is already sorted by distance from controller |
| 156 | return false; | ||
| 157 | } | ||
| 158 | |||
| 159 | var grabbedProperties = null; | ||
| 160 | // nearbyEntityProperties is already sorted by length from controller | ||
| 161 | var nearbyEntityProperties = controllerData.nearbyEntityProperties[this.hand]; | 146 | var nearbyEntityProperties = controllerData.nearbyEntityProperties[this.hand]; |
| 162 | for (var i = 0; i < nearbyEntityProperties.length; i++) { | 147 | for (var i = 0; i < nearbyEntityProperties.length; i++) { |
| 163 | var props = nearbyEntityProperties[i]; | 148 | var props = nearbyEntityProperties[i]; |
| 164 | if (entityIsGrabbable(props)) { | 149 | if (entityIsGrabbable(props)) { |
| 165 | grabbedProperties = props; | 150 | return props; |
| 166 | break; | ||
| 167 | } | 151 | } |
| 168 | } | 152 | } |
| 153 | return null; | ||
| 154 | }; | ||
| 155 | |||
| 156 | this.isReady = function (controllerData) { | ||
| 157 | this.targetEntityID = null; | ||
| 169 | 158 | ||
| 170 | if (grabbedProperties) { | 159 | if (controllerData.triggerValues[this.hand] < TRIGGER_OFF_VALUE) { |
| 171 | if (!propsArePhysical(grabbedProperties)) { | 160 | makeRunningValues(false, [], []); |
| 172 | return false; // let nearParentGrabEntity handle it | 161 | } |
| 162 | |||
| 163 | var targetProps = this.getTargetProps(controllerData); | ||
| 164 | if (targetProps) { | ||
| 165 | if (!propsArePhysical(targetProps)) { | ||
| 166 | // XXX make sure no highlights are enabled from this module | ||
| 167 | return makeRunningValues(false, [], []); // let nearParentGrabEntity handle it | ||
| 168 | } else { | ||
| 169 | this.targetEntityID = targetProps.id; | ||
| 170 | // XXX highlight this.targetEntityID here | ||
| 171 | return makeRunningValues(true, [this.targetEntityID], []); | ||
| 173 | } | 172 | } |
| 174 | this.grabbedThingID = grabbedProperties.id; | ||
| 175 | this.startNearGrabAction(controllerData, grabbedProperties); | ||
| 176 | return true; | ||
| 177 | } else { | 173 | } else { |
| 178 | return false; | 174 | // XXX make sure no highlights are enabled from this module |
| 175 | return makeRunningValues(false, [], []); | ||
| 179 | } | 176 | } |
| 180 | }; | 177 | }; |
| 181 | 178 | ||
| 182 | this.run = function (controllerData) { | 179 | this.run = function (controllerData) { |
| 183 | if (controllerData.triggerClicks[this.hand] == 0) { | 180 | if (this.actionID) { |
| 184 | this.endNearGrabAction(controllerData); | 181 | if (controllerData.triggerClicks[this.hand] == 0) { |
| 185 | return false; | 182 | this.endNearGrabAction(); |
| 186 | } | 183 | return makeRunningValues(false, [], []); |
| 184 | } | ||
| 187 | 185 | ||
| 188 | if (!this.actionID) { | 186 | this.refreshNearGrabAction(controllerData); |
| 189 | this.restartNearGrabAction(controllerData); | ||
| 190 | } | ||
| 191 | 187 | ||
| 192 | this.refreshNearGrabAction(controllerData); | 188 | var args = [this.hand === RIGHT_HAND ? "right" : "left", MyAvatar.sessionUUID]; |
| 189 | Entities.callEntityMethod(this.targetEntityID, "continueNearGrab", args); | ||
| 190 | } else { | ||
| 191 | // still searching / highlighting | ||
| 192 | var readiness = this.isReady (controllerData); | ||
| 193 | if (!readiness.active) { | ||
| 194 | return readiness; | ||
| 195 | } | ||
| 196 | if (controllerData.triggerClicks[this.hand] == 1) { | ||
| 197 | // stop highlighting, switch to grabbing | ||
| 198 | // XXX stop highlight here | ||
| 199 | var targetProps = this.getTargetProps(controllerData); | ||
| 200 | if (targetProps) { | ||
| 201 | this.startNearGrabAction(controllerData, targetProps); | ||
| 202 | } | ||
| 203 | } | ||
| 204 | } | ||
| 193 | 205 | ||
| 194 | var args = [this.hand === RIGHT_HAND ? "right" : "left", MyAvatar.sessionUUID]; | 206 | return makeRunningValues(true, [this.targetEntityID], []); |
| 195 | Entities.callEntityMethod(this.grabbedThingID, "continueNearGrab", args); | 207 | }; |
| 196 | 208 | ||
| 197 | return true; | 209 | this.cleanup = function () { |
| 210 | if (this.targetEntityID) { | ||
| 211 | this.endNearGrabAction(); | ||
| 212 | } | ||
| 198 | }; | 213 | }; |
| 199 | } | 214 | } |
| 200 | 215 | ||
| 201 | enableDispatcherModule("LeftNearActionGrabEntity", new NearActionGrabEntity(LEFT_HAND)); | 216 | var leftNearActionGrabEntity = new NearActionGrabEntity(LEFT_HAND); |
| 202 | enableDispatcherModule("RightNearActionGrabEntity", new NearActionGrabEntity(RIGHT_HAND)); | 217 | var rightNearActionGrabEntity = new NearActionGrabEntity(RIGHT_HAND); |
| 218 | |||
| 219 | enableDispatcherModule("LeftNearActionGrabEntity", leftNearActionGrabEntity); | ||
| 220 | enableDispatcherModule("RightNearActionGrabEntity", rightNearActionGrabEntity); | ||
| 203 | 221 | ||
| 204 | this.cleanup = function () { | 222 | this.cleanup = function () { |
| 223 | leftNearActionGrabEntity.cleanup(); | ||
| 224 | rightNearActionGrabEntity.cleanup(); | ||
| 205 | disableDispatcherModule("LeftNearActionGrabEntity"); | 225 | disableDispatcherModule("LeftNearActionGrabEntity"); |
| 206 | disableDispatcherModule("RightNearActionGrabEntity"); | 226 | disableDispatcherModule("RightNearActionGrabEntity"); |
| 207 | }; | 227 | }; |
| @@ -8,8 +8,8 @@ · 7 unmodified lines | |||
| 8 | 8 | ||
| 9 | /* global Script, Entities, MyAvatar, Controller, RIGHT_HAND, LEFT_HAND, AVATAR_SELF_ID, | 9 | /* global Script, Entities, MyAvatar, Controller, RIGHT_HAND, LEFT_HAND, AVATAR_SELF_ID, |
| 10 | getControllerJointIndex, NULL_UUID, enableDispatcherModule, disableDispatcherModule, | 10 | getControllerJointIndex, NULL_UUID, enableDispatcherModule, disableDispatcherModule, |
| 11 | propsArePhysical, Messages, HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION, | 11 | propsArePhysical, Messages, HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION, TRIGGER_OFF_VALUE, |
| 12 | makeDispatcherModuleParameters, entityIsGrabbable | 12 | makeDispatcherModuleParameters, entityIsGrabbable, makeRunningValues |
| 13 | */ | 13 | */ |
| 14 | 14 | ||
| 15 | Script.include("/~/system/controllers/controllerDispatcherUtils.js"); | 15 | Script.include("/~/system/controllers/controllerDispatcherUtils.js"); |
| @@ -21,7 +21,8 @@ Script.include("/~/system/controllers/controllerDispatcherUtils.js"); · 5 unmodified lines | |||
| 21 | 21 | ||
| 22 | function NearParentingGrabEntity(hand) { | 22 | function NearParentingGrabEntity(hand) { |
| 23 | this.hand = hand; | 23 | this.hand = hand; |
| 24 | this.grabbedThingID = null; | 24 | this.targetEntityID = null; |
| 25 | this.grabbing = false; | ||
| 25 | this.previousParentID = {}; | 26 | this.previousParentID = {}; |
| 26 | this.previousParentJointIndex = {}; | 27 | this.previousParentJointIndex = {}; |
| 27 | this.previouslyUnhooked = {}; | 28 | this.previouslyUnhooked = {}; |
| @@ -62,7 +63,7 @@ Script.include("/~/system/controllers/controllerDispatcherUtils.js"); · 34 unmodified lines | |||
| 62 | return false; | 63 | return false; |
| 63 | }; | 64 | }; |
| 64 | 65 | ||
| 65 | this.startNearParentingGrabEntity = function (controllerData, grabbedProperties) { | 66 | this.startNearParentingGrabEntity = function (controllerData, targetProps) { |
| 66 | Controller.triggerHapticPulse(HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION, this.hand); | 67 | Controller.triggerHapticPulse(HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION, this.hand); |
| 67 | 68 | ||
| 68 | var handJointIndex; | 69 | var handJointIndex; |
| @@ -74,7 +75,7 @@ Script.include("/~/system/controllers/controllerDispatcherUtils.js"); · 5 unmodified lines | |||
| 74 | handJointIndex = this.controllerJointIndex; | 75 | handJointIndex = this.controllerJointIndex; |
| 75 | 76 | ||
| 76 | var args = [this.hand === RIGHT_HAND ? "right" : "left", MyAvatar.sessionUUID]; | 77 | var args = [this.hand === RIGHT_HAND ? "right" : "left", MyAvatar.sessionUUID]; |
| 77 | Entities.callEntityMethod(this.grabbedThingID, "startNearGrab", args); | 78 | Entities.callEntityMethod(targetProps.id, "startNearGrab", args); |
| 78 | 79 | ||
| 79 | var reparentProps = { | 80 | var reparentProps = { |
| 80 | parentID: AVATAR_SELF_ID, | 81 | parentID: AVATAR_SELF_ID, |
| @@ -83,90 +84,127 @@ Script.include("/~/system/controllers/controllerDispatcherUtils.js"); · 2 unmodified lines | |||
| 83 | angularVelocity: {x: 0, y: 0, z: 0} | 84 | angularVelocity: {x: 0, y: 0, z: 0} |
| 84 | }; | 85 | }; |
| 85 | 86 | ||
| 86 | if (this.thisHandIsParent(grabbedProperties)) { | 87 | if (this.thisHandIsParent(targetProps)) { |
| 87 | // this should never happen, but if it does, don't set previous parent to be this hand. | 88 | // this should never happen, but if it does, don't set previous parent to be this hand. |
| 88 | // this.previousParentID[this.grabbedThingID] = NULL; | 89 | // this.previousParentID[targetProps.id] = NULL; |
| 89 | // this.previousParentJointIndex[this.grabbedThingID] = -1; | 90 | // this.previousParentJointIndex[targetProps.id] = -1; |
| 90 | } else { | 91 | } else { |
| 91 | this.previousParentID[this.grabbedThingID] = grabbedProperties.parentID; | 92 | this.previousParentID[targetProps.id] = targetProps.parentID; |
| 92 | this.previousParentJointIndex[this.grabbedThingID] = grabbedProperties.parentJointIndex; | 93 | this.previousParentJointIndex[targetProps.id] = targetProps.parentJointIndex; |
| 93 | } | 94 | } |
| 94 | Entities.editEntity(this.grabbedThingID, reparentProps); | 95 | Entities.editEntity(targetProps.id, reparentProps); |
| 95 | 96 | ||
| 96 | Messages.sendMessage('Hifi-Object-Manipulation', JSON.stringify({ | 97 | Messages.sendMessage('Hifi-Object-Manipulation', JSON.stringify({ |
| 97 | action: 'grab', | 98 | action: 'grab', |
| 98 | grabbedEntity: this.grabbedThingID, | 99 | grabbedEntity: targetProps.id, |
| 99 | joint: this.hand === RIGHT_HAND ? "RightHand" : "LeftHand" | 100 | joint: this.hand === RIGHT_HAND ? "RightHand" : "LeftHand" |
| 100 | })); | 101 | })); |
| 101 | }; | 102 | }; |
| 102 | 103 | ||
| 103 | this.endNearParentingGrabEntity = function (controllerData) { | 104 | this.endNearParentingGrabEntity = function () { |
| 104 | if (this.previousParentID[this.grabbedThingID] === NULL_UUID) { | 105 | if (this.previousParentID[this.targetEntityID] === NULL_UUID) { |
| 105 | Entities.editEntity(this.grabbedThingID, { | 106 | Entities.editEntity(this.targetEntityID, { |
| 106 | parentID: this.previousParentID[this.grabbedThingID], | 107 | parentID: this.previousParentID[this.targetEntityID], |
| 107 | parentJointIndex: this.previousParentJointIndex[this.grabbedThingID] | 108 | parentJointIndex: this.previousParentJointIndex[this.targetEntityID] |
| 108 | }); | 109 | }); |
| 109 | } else { | 110 | } else { |
| 110 | // we're putting this back as a child of some other parent, so zero its velocity | 111 | // we're putting this back as a child of some other parent, so zero its velocity |
| 111 | Entities.editEntity(this.grabbedThingID, { | 112 | Entities.editEntity(this.targetEntityID, { |
| 112 | parentID: this.previousParentID[this.grabbedThingID], | 113 | parentID: this.previousParentID[this.targetEntityID], |
| 113 | parentJointIndex: this.previousParentJointIndex[this.grabbedThingID], | 114 | parentJointIndex: this.previousParentJointIndex[this.targetEntityID], |
| 114 | velocity: {x: 0, y: 0, z: 0}, | 115 | velocity: {x: 0, y: 0, z: 0}, |
| 115 | angularVelocity: {x: 0, y: 0, z: 0} | 116 | angularVelocity: {x: 0, y: 0, z: 0} |
| 116 | }); | 117 | }); |
| 117 | } | 118 | } |
| 118 | 119 | ||
| 119 | var args = [this.hand === RIGHT_HAND ? "right" : "left", MyAvatar.sessionUUID]; | 120 | var args = [this.hand === RIGHT_HAND ? "right" : "left", MyAvatar.sessionUUID]; |
| 120 | Entities.callEntityMethod(this.grabbedThingID, "releaseGrab", args); | 121 | Entities.callEntityMethod(this.targetEntityID, "releaseGrab", args); |
| 121 | 122 | ||
| 122 | this.grabbedThingID = null; | 123 | this.grabbing = false; |
| 124 | this.targetEntityID = null; | ||
| 123 | }; | 125 | }; |
| 124 | 126 | ||
| 125 | this.isReady = function (controllerData) { | 127 | this.getTargetProps = function (controllerData) { |
| 126 | if (controllerData.triggerClicks[this.hand] == 0) { | ||
| 127 | return false; | ||
| 128 | } | ||
| 129 | |||
| 130 | var grabbedProperties = null; | ||
| 131 | // nearbyEntityProperties is already sorted by length from controller | 128 | // nearbyEntityProperties is already sorted by length from controller |
| 132 | var nearbyEntityProperties = controllerData.nearbyEntityProperties[this.hand]; | 129 | var nearbyEntityProperties = controllerData.nearbyEntityProperties[this.hand]; |
| 133 | for (var i = 0; i < nearbyEntityProperties.length; i++) { | 130 | for (var i = 0; i < nearbyEntityProperties.length; i++) { |
| 134 | var props = nearbyEntityProperties[i]; | 131 | var props = nearbyEntityProperties[i]; |
| 135 | if (entityIsGrabbable(props)) { | 132 | if (entityIsGrabbable(props)) { |
| 136 | grabbedProperties = props; | 133 | return props; |
| 137 | break; | ||
| 138 | } | 134 | } |
| 139 | } | 135 | } |
| 136 | return null; | ||
| 137 | }; | ||
| 140 | 138 | ||
| 141 | if (grabbedProperties) { | 139 | this.isReady = function (controllerData) { |
| 142 | if (propsArePhysical(grabbedProperties)) { | 140 | this.targetEntityID = null; |
| 143 | return false; // let nearActionGrabEntity handle it | 141 | this.grabbing = false; |
| 142 | |||
| 143 | if (controllerData.triggerValues[this.hand] < TRIGGER_OFF_VALUE) { | ||
| 144 | makeRunningValues(false, [], []); | ||
| 145 | } | ||
| 146 | |||
| 147 | var targetProps = this.getTargetProps(controllerData); | ||
| 148 | if (targetProps) { | ||
| 149 | if (propsArePhysical(targetProps)) { | ||
| 150 | // XXX make sure no highlights are enabled from this module | ||
| 151 | return makeRunningValues(false, [], []); // let nearActionGrabEntity handle it | ||
| 152 | } else { | ||
| 153 | this.targetEntityID = targetProps.id; | ||
| 154 | // XXX highlight this.targetEntityID here | ||
| 155 | return makeRunningValues(true, [this.targetEntityID], []); | ||
| 144 | } | 156 | } |
| 145 | this.grabbedThingID = grabbedProperties.id; | ||
| 146 | this.startNearParentingGrabEntity(controllerData, grabbedProperties); | ||
| 147 | return true; | ||
| 148 | } else { | 157 | } else { |
| 149 | return false; | 158 | // XXX make sure no highlights are enabled from this module |
| 159 | return makeRunningValues(false, [], []); | ||
| 150 | } | 160 | } |
| 151 | }; | 161 | }; |
| 152 | 162 | ||
| 153 | this.run = function (controllerData) { | 163 | this.run = function (controllerData) { |
| 154 | if (controllerData.triggerClicks[this.hand] == 0) { | 164 | if (this.grabbing) { |
| 155 | this.endNearParentingGrabEntity(controllerData); | 165 | if (controllerData.triggerClicks[this.hand] == 0) { |
| 156 | return false; | 166 | this.endNearParentingGrabEntity(); |
| 167 | return makeRunningValues(false, [], []); | ||
| 168 | } | ||
| 169 | |||
| 170 | var args = [this.hand === RIGHT_HAND ? "right" : "left", MyAvatar.sessionUUID]; | ||
| 171 | Entities.callEntityMethod(this.targetEntityID, "continueNearGrab", args); | ||
| 172 | } else { | ||
| 173 | // still searching / highlighting | ||
| 174 | var readiness = this.isReady (controllerData); | ||
| 175 | if (!readiness.active) { | ||
| 176 | return readiness; | ||
| 177 | } | ||
| 178 | if (controllerData.triggerClicks[this.hand] == 1) { | ||
| 179 | // stop highlighting, switch to grabbing | ||
| 180 | // XXX stop highlight here | ||
| 181 | var targetProps = this.getTargetProps(controllerData); | ||
| 182 | if (targetProps) { | ||
| 183 | this.grabbing = true; | ||
| 184 | this.startNearParentingGrabEntity(controllerData, targetProps); | ||
| 185 | } | ||
| 186 | } | ||
| 157 | } | 187 | } |
| 158 | 188 | ||
| 159 | var args = [this.hand === RIGHT_HAND ? "right" : "left", MyAvatar.sessionUUID]; | 189 | return makeRunningValues(true, [this.targetEntityID], []); |
| 160 | Entities.callEntityMethod(this.grabbedThingID, "continueNearGrab", args); | 190 | }; |
| 161 | 191 | ||
| 162 | return true; | 192 | this.cleanup = function () { |
| 193 | if (this.targetEntityID) { | ||
| 194 | this.endNearParentingGrabEntity(); | ||
| 195 | } | ||
| 163 | }; | 196 | }; |
| 164 | } | 197 | } |
| 165 | 198 | ||
| 166 | enableDispatcherModule("LeftNearParentingGrabEntity", new NearParentingGrabEntity(LEFT_HAND)); | 199 | var leftNearParentingGrabEntity = new NearParentingGrabEntity(LEFT_HAND); |
| 167 | enableDispatcherModule("RightNearParentingGrabEntity", new NearParentingGrabEntity(RIGHT_HAND)); | 200 | var rightNearParentingGrabEntity = new NearParentingGrabEntity(RIGHT_HAND); |
| 201 | |||
| 202 | enableDispatcherModule("LeftNearParentingGrabEntity", leftNearParentingGrabEntity); | ||
| 203 | enableDispatcherModule("RightNearParentingGrabEntity", rightNearParentingGrabEntity); | ||
| 168 | 204 | ||
| 169 | this.cleanup = function () { | 205 | this.cleanup = function () { |
| 206 | leftNearParentingGrabEntity.cleanup(); | ||
| 207 | rightNearParentingGrabEntity.cleanup(); | ||
| 170 | disableDispatcherModule("LeftNearParentingGrabEntity"); | 208 | disableDispatcherModule("LeftNearParentingGrabEntity"); |
| 171 | disableDispatcherModule("RightNearParentingGrabEntity"); | 209 | disableDispatcherModule("RightNearParentingGrabEntity"); |
| 172 | }; | 210 | }; |
| @@ -9,7 +9,7 @@ · 8 unmodified lines | |||
| 9 | /* global Script, MyAvatar, Controller, RIGHT_HAND, LEFT_HAND, AVATAR_SELF_ID, | 9 | /* global Script, MyAvatar, Controller, RIGHT_HAND, LEFT_HAND, AVATAR_SELF_ID, |
| 10 | getControllerJointIndex, NULL_UUID, enableDispatcherModule, disableDispatcherModule, | 10 | getControllerJointIndex, NULL_UUID, enableDispatcherModule, disableDispatcherModule, |
| 11 | Messages, HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION, | 11 | Messages, HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION, |
| 12 | makeDispatcherModuleParameters, Overlays | 12 | makeDispatcherModuleParameters, Overlays, makeRunningValues |
| 13 | */ | 13 | */ |
| 14 | 14 | ||
| 15 | Script.include("/~/system/controllers/controllerDispatcherUtils.js"); | 15 | Script.include("/~/system/controllers/controllerDispatcherUtils.js"); |
| @@ -106,7 +106,7 @@ Script.include("/~/system/controllers/controllerDispatcherUtils.js"); · 90 unmodified lines | |||
| 106 | })); | 106 | })); |
| 107 | }; | 107 | }; |
| 108 | 108 | ||
| 109 | this.endNearParentingGrabOverlay = function (controllerData) { | 109 | this.endNearParentingGrabOverlay = function () { |
| 110 | if (this.previousParentID[this.grabbedThingID] === NULL_UUID) { | 110 | if (this.previousParentID[this.grabbedThingID] === NULL_UUID) { |
| 111 | Overlays.editOverlay(this.grabbedThingID, { | 111 | Overlays.editOverlay(this.grabbedThingID, { |
| 112 | parentID: NULL_UUID, | 112 | parentID: NULL_UUID, |
| @@ -125,7 +125,7 @@ Script.include("/~/system/controllers/controllerDispatcherUtils.js"); · 12 unmodified lines | |||
| 125 | 125 | ||
| 126 | this.isReady = function (controllerData) { | 126 | this.isReady = function (controllerData) { |
| 127 | if (controllerData.triggerClicks[this.hand] == 0) { | 127 | if (controllerData.triggerClicks[this.hand] == 0) { |
| 128 | return false; | 128 | return makeRunningValues(false, [], []); |
| 129 | } | 129 | } |
| 130 | 130 | ||
| 131 | this.grabbedThingID = null; | 131 | this.grabbedThingID = null; |
| @@ -138,26 +138,37 @@ Script.include("/~/system/controllers/controllerDispatcherUtils.js"); · 6 unmodified lines | |||
| 138 | if (grabbableOverlays.length > 0) { | 138 | if (grabbableOverlays.length > 0) { |
| 139 | this.grabbedThingID = grabbableOverlays[0]; | 139 | this.grabbedThingID = grabbableOverlays[0]; |
| 140 | this.startNearParentingGrabOverlay(controllerData); | 140 | this.startNearParentingGrabOverlay(controllerData); |
| 141 | return true; | 141 | return makeRunningValues(true, [this.grabbedThingID], []); |
| 142 | } else { | 142 | } else { |
| 143 | return false; | 143 | return makeRunningValues(false, [], []); |
| 144 | } | 144 | } |
| 145 | }; | 145 | }; |
| 146 | 146 | ||
| 147 | this.run = function (controllerData) { | 147 | this.run = function (controllerData) { |
| 148 | if (controllerData.triggerClicks[this.hand] == 0) { | 148 | if (controllerData.triggerClicks[this.hand] == 0) { |
| 149 | this.endNearParentingGrabOverlay(controllerData); | 149 | this.endNearParentingGrabOverlay(); |
| 150 | return false; | 150 | return makeRunningValues(false, [], []); |
| 151 | } else { | 151 | } else { |
| 152 | return true; | 152 | return makeRunningValues(true, [this.grabbedThingID], []); |
| 153 | } | ||
| 154 | }; | ||
| 155 | |||
| 156 | this.cleanup = function () { | ||
| 157 | if (this.grabbedThingID) { | ||
| 158 | this.endNearParentingGrabOverlay(); | ||
| 153 | } | 159 | } |
| 154 | }; | 160 | }; |
| 155 | } | 161 | } |
| 156 | 162 | ||
| 157 | enableDispatcherModule("LeftNearParentingGrabOverlay", new NearParentingGrabOverlay(LEFT_HAND)); | 163 | var leftNearParentingGrabOverlay = new NearParentingGrabOverlay(LEFT_HAND); |
| 158 | enableDispatcherModule("RightNearParentingGrabOverlay", new NearParentingGrabOverlay(RIGHT_HAND)); | 164 | var rightNearParentingGrabOverlay = new NearParentingGrabOverlay(RIGHT_HAND); |
| 165 | |||
| 166 | enableDispatcherModule("LeftNearParentingGrabOverlay", leftNearParentingGrabOverlay); | ||
| 167 | enableDispatcherModule("RightNearParentingGrabOverlay", rightNearParentingGrabOverlay); | ||
| 159 | 168 | ||
| 160 | this.cleanup = function () { | 169 | this.cleanup = function () { |
| 170 | leftNearParentingGrabOverlay.cleanup(); | ||
| 171 | rightNearParentingGrabOverlay.cleanup(); | ||
| 161 | disableDispatcherModule("LeftNearParentingGrabOverlay"); | 172 | disableDispatcherModule("LeftNearParentingGrabOverlay"); |
| 162 | disableDispatcherModule("RightNearParentingGrabOverlay"); | 173 | disableDispatcherModule("RightNearParentingGrabOverlay"); |
| 163 | }; | 174 | }; |
| @@ -6,7 +6,7 @@ · 5 unmodified lines | |||
| 6 | // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html | 6 | // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html |
| 7 | 7 | ||
| 8 | /* global Script, Entities, MyAvatar, Controller, RIGHT_HAND, LEFT_HAND, | 8 | /* global Script, Entities, MyAvatar, Controller, RIGHT_HAND, LEFT_HAND, |
| 9 | NULL_UUID, enableDispatcherModule, disableDispatcherModule, | 9 | NULL_UUID, enableDispatcherModule, disableDispatcherModule, makeRunningValues, |
| 10 | Messages, Quat, Vec3, getControllerWorldLocation, makeDispatcherModuleParameters, Overlays, ZERO_VEC, | 10 | Messages, Quat, Vec3, getControllerWorldLocation, makeDispatcherModuleParameters, Overlays, ZERO_VEC, |
| 11 | AVATAR_SELF_ID, HMD, INCHES_TO_METERS, DEFAULT_REGISTRATION_POINT, Settings, getGrabPointSphereOffset | 11 | AVATAR_SELF_ID, HMD, INCHES_TO_METERS, DEFAULT_REGISTRATION_POINT, Settings, getGrabPointSphereOffset |
| 12 | */ | 12 | */ |
| @@ -643,7 +643,11 @@ Script.include("/~/system/libraries/controllers.js"); · 630 unmodified lines | |||
| 643 | }; | 643 | }; |
| 644 | 644 | ||
| 645 | this.isReady = function (controllerData) { | 645 | this.isReady = function (controllerData) { |
| 646 | return this.processStylus(controllerData); | 646 | if (this.processStylus(controllerData)) { |
| 647 | return makeRunningValues(true, [], []); | ||
| 648 | } else { | ||
| 649 | return makeRunningValues(false, [], []); | ||
| 650 | } | ||
| 647 | }; | 651 | }; |
| 648 | 652 | ||
| 649 | this.run = function (controllerData, deltaTime) { | 653 | this.run = function (controllerData, deltaTime) { |
| @@ -660,7 +664,11 @@ Script.include("/~/system/libraries/controllers.js"); · 10 unmodified lines | |||
| 660 | if (this.stylusTouchingTarget) { | 664 | if (this.stylusTouchingTarget) { |
| 661 | this.stylusTouching(controllerData, deltaTime); | 665 | this.stylusTouching(controllerData, deltaTime); |
| 662 | } | 666 | } |
| 663 | return this.processStylus(controllerData); | 667 | if (this.processStylus(controllerData)) { |
| 668 | return makeRunningValues(true, [], []); | ||
| 669 | } else { | ||
| 670 | return makeRunningValues(false, [], []); | ||
| 671 | } | ||
| 664 | }; | 672 | }; |
| 665 | 673 | ||
| 666 | this.cleanup = function () { | 674 | this.cleanup = function () { |
| @@ -674,12 +682,11 @@ Script.include("/~/system/libraries/controllers.js"); · 7 unmodified lines | |||
| 674 | enableDispatcherModule("LeftTabletStylusInput", leftTabletStylusInput); | 682 | enableDispatcherModule("LeftTabletStylusInput", leftTabletStylusInput); |
| 675 | enableDispatcherModule("RightTabletStylusInput", rightTabletStylusInput); | 683 | enableDispatcherModule("RightTabletStylusInput", rightTabletStylusInput); |
| 676 | 684 | ||
| 677 | |||
| 678 | this.cleanup = function () { | 685 | this.cleanup = function () { |
| 679 | disableDispatcherModule("LeftTabletStylusInput"); | ||
| 680 | disableDispatcherModule("RightTabletStylusInput"); | ||
| 681 | leftTabletStylusInput.cleanup(); | 686 | leftTabletStylusInput.cleanup(); |
| 682 | rightTabletStylusInput.cleanup(); | 687 | rightTabletStylusInput.cleanup(); |
| 688 | disableDispatcherModule("LeftTabletStylusInput"); | ||
| 689 | disableDispatcherModule("RightTabletStylusInput"); | ||
| 683 | }; | 690 | }; |
| 684 | Script.scriptEnding.connect(this.cleanup); | 691 | Script.scriptEnding.connect(this.cleanup); |
| 685 | }()); | 692 | }()); |