| @@ -59,42 +59,53 @@ Script.include("/~/system/libraries/controllers.js"); · 58 unmodified lines |
| 59 | width: 0.025, | 59 | width: 0.025, |
| 60 | drawInFront: true | 60 | drawInFront: true |
| 61 | }; | 61 | }; |
| | 62 | |
| 62 | var teleportPath = { | 63 | var teleportPath = { |
| 63 | color: COLORS_TELEPORT_CAN_TELEPORT, | 64 | color: COLORS_TELEPORT_CAN_TELEPORT, |
| 64 | alpha: 1, | 65 | alpha: 1, |
| 65 | width: 0.025, | 66 | width: 0.025, |
| 66 | drawInFront: true | 67 | drawInFront: true |
| 67 | }; | 68 | }; |
| | 69 | |
| 68 | var seatPath = { | 70 | var seatPath = { |
| 69 | color: COLORS_TELEPORT_SEAT, | 71 | color: COLORS_TELEPORT_SEAT, |
| 70 | alpha: 1, | 72 | alpha: 1, |
| 71 | width: 0.025, | 73 | width: 0.025, |
| 72 | drawInFront: true | 74 | drawInFront: true |
| 73 | }; | 75 | }; |
| | 76 | |
| 74 | var teleportEnd = { | 77 | var teleportEnd = { |
| 75 | type: "model", | 78 | type: "model", |
| 76 | url: TARGET_MODEL_URL, | 79 | url: TARGET_MODEL_URL, |
| 77 | dimensions: TARGET_MODEL_DIMENSIONS, | 80 | dimensions: TARGET_MODEL_DIMENSIONS, |
| 78 | ignorePickIntersection: true | 81 | ignorePickIntersection: true |
| 79 | }; | 82 | }; |
| | 83 | |
| 80 | var seatEnd = { | 84 | var seatEnd = { |
| 81 | type: "model", | 85 | type: "model", |
| 82 | url: SEAT_MODEL_URL, | 86 | url: SEAT_MODEL_URL, |
| 83 | dimensions: TARGET_MODEL_DIMENSIONS, | 87 | dimensions: TARGET_MODEL_DIMENSIONS, |
| 84 | ignorePickIntersection: true | 88 | ignorePickIntersection: true |
| 85 | }; | 89 | }; |
| 86 | | 90 | |
| 87 | | 91 | var collisionEnd = { |
| | 92 | type: "shape", |
| | 93 | shape: "box", |
| | 94 | dimensions: { x: 1.0, y: 0.001, z: 1.0 }, |
| | 95 | alpha: 0.0, |
| | 96 | ignorePickIntersection: true |
| | 97 | }; |
| | 98 | |
| 88 | var teleportRenderStates = [{name: "cancel", path: cancelPath}, | 99 | var teleportRenderStates = [{name: "cancel", path: cancelPath}, |
| 89 | {name: "teleport", path: teleportPath, end: teleportEnd}, | 100 | {name: "teleport", path: teleportPath, end: teleportEnd}, |
| 90 | {name: "seat", path: seatPath, end: seatEnd}]; | 101 | {name: "seat", path: seatPath, end: seatEnd}, |
| | 102 | {name: "collision", end: collisionEnd}]; |
| 91 | | 103 | |
| 92 | var DEFAULT_DISTANCE = 8.0; | 104 | var DEFAULT_DISTANCE = 8.0; |
| 93 | var teleportDefaultRenderStates = [{name: "cancel", distance: DEFAULT_DISTANCE, path: cancelPath}]; | 105 | var teleportDefaultRenderStates = [{name: "cancel", distance: DEFAULT_DISTANCE, path: cancelPath}]; |
| 94 | | 106 | |
| 95 | var ignoredEntities = []; | 107 | var ignoredEntities = []; |
| 96 | | 108 | |
| 97 | | | |
| 98 | var TELEPORTER_STATES = { | 109 | var TELEPORTER_STATES = { |
| 99 | IDLE: 'idle', | 110 | IDLE: 'idle', |
| 100 | TARGETTING: 'targetting', | 111 | TARGETTING: 'targetting', |
| @@ -103,8 +114,9 @@ Script.include("/~/system/libraries/controllers.js"); · 2 unmodified lines |
| 103 | | 114 | |
| 104 | var TARGET = { | 115 | var TARGET = { |
| 105 | NONE: 'none', // Not currently targetting anything | 116 | NONE: 'none', // Not currently targetting anything |
| 106 | INVISIBLE: 'invisible', // The current target is an invvsible surface | | |
| 107 | INVALID: 'invalid', // The current target is invalid (wall, ceiling, etc.) | 117 | INVALID: 'invalid', // The current target is invalid (wall, ceiling, etc.) |
| | 118 | COLLIDES: 'collides', // Insufficient space to accommodate the avatar capsule |
| | 119 | DISCREPANCY: 'discrepancy', // We are not 100% sure the avatar will fit so we trigger safe landing |
| 108 | SURFACE: 'surface', // The current target is a valid surface | 120 | SURFACE: 'surface', // The current target is a valid surface |
| 109 | SEAT: 'seat' // The current target is a seat | 121 | SEAT: 'seat' // The current target is a seat |
| 110 | }; | 122 | }; |
| @@ -114,6 +126,7 @@ Script.include("/~/system/libraries/controllers.js"); · 3 unmodified lines |
| 114 | | 126 | |
| 115 | function Teleporter(hand) { | 127 | function Teleporter(hand) { |
| 116 | var _this = this; | 128 | var _this = this; |
| | 129 | this.init = false; |
| 117 | this.hand = hand; | 130 | this.hand = hand; |
| 118 | this.buttonValue = 0; | 131 | this.buttonValue = 0; |
| 119 | this.disabled = false; // used by the 'Hifi-Teleport-Disabler' message handler | 132 | this.disabled = false; // used by the 'Hifi-Teleport-Disabler' message handler |
| @@ -121,12 +134,147 @@ Script.include("/~/system/libraries/controllers.js"); · 1 unmodified line |
| 121 | this.state = TELEPORTER_STATES.IDLE; | 134 | this.state = TELEPORTER_STATES.IDLE; |
| 122 | this.currentTarget = TARGET.INVALID; | 135 | this.currentTarget = TARGET.INVALID; |
| 123 | this.currentResult = null; | 136 | this.currentResult = null; |
| | 137 | this.capsuleThreshold = 0.05; |
| | 138 | this.pickHeightOffset = 0.05; |
| 124 | | 139 | |
| 125 | this.getOtherModule = function() { | 140 | this.getOtherModule = function() { |
| 126 | var otherModule = this.hand === RIGHT_HAND ? leftTeleporter : rightTeleporter; | 141 | var otherModule = this.hand === RIGHT_HAND ? leftTeleporter : rightTeleporter; |
| 127 | return otherModule; | 142 | return otherModule; |
| 128 | }; | 143 | }; |
| 129 | | 144 | |
| | 145 | this.teleportHeadCollisionPick; |
| | 146 | this.teleportHandCollisionPick; |
| | 147 | this.teleportParabolaHandVisuals; |
| | 148 | this.teleportParabolaHandCollisions; |
| | 149 | this.teleportParabolaHeadVisuals; |
| | 150 | this.teleportParabolaHeadCollisions; |
| | 151 | this.teleporterSelectionName; |
| | 152 | this.teleportedTargetOverlay; |
| | 153 | this.playAreaOverlay; |
| | 154 | this.playAreaSensorPositionOverlays = []; |
| | 155 | |
| | 156 | this.cleanup = function() { |
| | 157 | Selection.removeListFromMap(_this.teleporterSelectionName); |
| | 158 | Pointers.removePointer(_this.teleportParabolaHandVisuals); |
| | 159 | Pointers.removePointer(_this.teleportParabolaHandCollisions); |
| | 160 | Pointers.removePointer(_this.teleportParabolaHeadVisuals); |
| | 161 | Pointers.removePointer(_this.teleportParabolaHeadCollisions); |
| | 162 | Picks.removePick(_this.teleportHandCollisionPick); |
| | 163 | Picks.removePick(_this.teleportHeadCollisionPick); |
| | 164 | Overlays.deleteOverlay(this.teleportedTargetOverlay); |
| | 165 | Overlays.deleteOverlay(_this.playAreaOverlay); |
| | 166 | for (var i = 0; i < _this.playAreaSensorPositionOverlays.length; i++) { |
| | 167 | Overlays.deleteOverlay(_this.playAreaSensorPositionOverlays[i]); |
| | 168 | } |
| | 169 | }; |
| | 170 | |
| | 171 | this.initPointers = function () { |
| | 172 | if (_this.init) { |
| | 173 | _this.cleanup(); |
| | 174 | } |
| | 175 | _this.teleportParabolaHandVisuals = Pointers.createPointer(PickType.Parabola, { |
| | 176 | joint: (_this.hand === RIGHT_HAND) ? "_CAMERA_RELATIVE_CONTROLLER_RIGHTHAND" : "_CAMERA_RELATIVE_CONTROLLER_LEFTHAND", |
| | 177 | dirOffset: { x: 0, y: 1, z: 0.1 }, |
| | 178 | posOffset: { x: (_this.hand === RIGHT_HAND) ? 0.03 : -0.03, y: 0.2, z: 0.02 }, |
| | 179 | filter: Picks.PICK_ENTITIES | Picks.PICK_INCLUDE_INVISIBLE, |
| | 180 | faceAvatar: true, |
| | 181 | scaleWithAvatar: true, |
| | 182 | centerEndY: false, |
| | 183 | speed: speed, |
| | 184 | accelerationAxis: accelerationAxis, |
| | 185 | rotateAccelerationWithAvatar: true, |
| | 186 | renderStates: teleportRenderStates, |
| | 187 | defaultRenderStates: teleportDefaultRenderStates, |
| | 188 | maxDistance: 8.0 |
| | 189 | }); |
| | 190 | |
| | 191 | _this.teleportParabolaHandCollisions = Pointers.createPointer(PickType.Parabola, { |
| | 192 | joint: (_this.hand === RIGHT_HAND) ? "_CAMERA_RELATIVE_CONTROLLER_RIGHTHAND" : "_CAMERA_RELATIVE_CONTROLLER_LEFTHAND", |
| | 193 | dirOffset: { x: 0, y: 1, z: 0.1 }, |
| | 194 | posOffset: { x: (_this.hand === RIGHT_HAND) ? 0.03 : -0.03, y: 0.2, z: 0.02 }, |
| | 195 | filter: Picks.PICK_ENTITIES | Picks.PICK_INCLUDE_INVISIBLE, |
| | 196 | faceAvatar: true, |
| | 197 | scaleWithAvatar: true, |
| | 198 | centerEndY: false, |
| | 199 | speed: speed, |
| | 200 | accelerationAxis: accelerationAxis, |
| | 201 | rotateAccelerationWithAvatar: true, |
| | 202 | renderStates: teleportRenderStates, |
| | 203 | maxDistance: 8.0 |
| | 204 | }); |
| | 205 | |
| | 206 | _this.teleportParabolaHeadVisuals = Pointers.createPointer(PickType.Parabola, { |
| | 207 | joint: "Avatar", |
| | 208 | filter: Picks.PICK_ENTITIES | Picks.PICK_INCLUDE_INVISIBLE, |
| | 209 | faceAvatar: true, |
| | 210 | scaleWithAvatar: true, |
| | 211 | centerEndY: false, |
| | 212 | speed: speed, |
| | 213 | accelerationAxis: accelerationAxis, |
| | 214 | rotateAccelerationWithAvatar: true, |
| | 215 | renderStates: teleportRenderStates, |
| | 216 | defaultRenderStates: teleportDefaultRenderStates, |
| | 217 | maxDistance: 8.0 |
| | 218 | }); |
| | 219 | |
| | 220 | _this.teleportParabolaHeadCollisions = Pointers.createPointer(PickType.Parabola, { |
| | 221 | joint: "Avatar", |
| | 222 | filter: Picks.PICK_ENTITIES | Picks.PICK_INCLUDE_INVISIBLE, |
| | 223 | faceAvatar: true, |
| | 224 | scaleWithAvatar: true, |
| | 225 | centerEndY: false, |
| | 226 | speed: speed, |
| | 227 | accelerationAxis: accelerationAxis, |
| | 228 | rotateAccelerationWithAvatar: true, |
| | 229 | renderStates: teleportRenderStates, |
| | 230 | maxDistance: 8.0 |
| | 231 | }); |
| | 232 | |
| | 233 | var capsuleData = MyAvatar.getCollisionCapsule(); |
| | 234 | |
| | 235 | var sensorToWorldScale = MyAvatar.getSensorToWorldScale(); |
| | 236 | |
| | 237 | var radius = capsuleData.radius / sensorToWorldScale; |
| | 238 | var height = (Vec3.distance(capsuleData.start, capsuleData.end) + (capsuleData.radius * 2.0)) / sensorToWorldScale; |
| | 239 | var capsuleRatio = 10.0 * radius / height; |
| | 240 | var offset = _this.pickHeightOffset * capsuleRatio; |
| | 241 | |
| | 242 | _this.teleportHandCollisionPick = Picks.createPick(PickType.Collision, { |
| | 243 | enabled: true, |
| | 244 | parentID: Pointers.getPointerProperties(_this.teleportParabolaHandCollisions).renderStates["collision"].end, |
| | 245 | filter: Picks.PICK_ENTITIES | Picks.PICK_AVATARS, |
| | 246 | shape: { |
| | 247 | shapeType: "capsule-y", |
| | 248 | dimensions: { |
| | 249 | x: radius * 2.0, |
| | 250 | y: height - (radius * 2.0), |
| | 251 | z: radius * 2.0 |
| | 252 | } |
| | 253 | }, |
| | 254 | position: { x: 0, y: offset + height * 0.5, z: 0 }, |
| | 255 | threshold: _this.capsuleThreshold |
| | 256 | }); |
| | 257 | |
| | 258 | _this.teleportHeadCollisionPick = Picks.createPick(PickType.Collision, { |
| | 259 | enabled: true, |
| | 260 | parentID: Pointers.getPointerProperties(_this.teleportParabolaHeadCollisions).renderStates["collision"].end, |
| | 261 | filter: Picks.PICK_ENTITIES | Picks.PICK_AVATARS, |
| | 262 | shape: { |
| | 263 | shapeType: "capsule-y", |
| | 264 | dimensions: { |
| | 265 | x: radius * 2.0, |
| | 266 | y: height - (radius * 2.0), |
| | 267 | z: radius * 2.0 |
| | 268 | } |
| | 269 | }, |
| | 270 | position: { x: 0, y: offset + height * 0.5, z: 0 }, |
| | 271 | threshold: _this.capsuleThreshold |
| | 272 | }); |
| | 273 | _this.init = true; |
| | 274 | } |
| | 275 | |
| | 276 | _this.initPointers(); |
| | 277 | |
| 130 | | 278 | |
| 131 | this.teleporterSelectionName = "teleporterSelection" + hand.toString(); | 279 | this.teleporterSelectionName = "teleporterSelection" + hand.toString(); |
| 132 | this.TELEPORTER_SELECTION_STYLE = { | 280 | this.TELEPORTER_SELECTION_STYLE = { |
| @@ -142,62 +290,6 @@ Script.include("/~/system/libraries/controllers.js"); · 9 unmodified lines |
| 142 | isOutlineSmooth: false | 290 | isOutlineSmooth: false |
| 143 | }; | 291 | }; |
| 144 | | 292 | |
| 145 | | | |
| 146 | this.teleportParabolaHandVisible = Pointers.createPointer(PickType.Parabola, { | | |
| 147 | joint: (_this.hand === RIGHT_HAND) ? "_CAMERA_RELATIVE_CONTROLLER_RIGHTHAND" : "_CAMERA_RELATIVE_CONTROLLER_LEFTHAND", | | |
| 148 | dirOffset: { x: 0, y: 1, z: 0.1 }, | | |
| 149 | posOffset: { x: (_this.hand === RIGHT_HAND) ? 0.03 : -0.03, y: 0.2, z: 0.02 }, | | |
| 150 | filter: Picks.PICK_ENTITIES, | | |
| 151 | faceAvatar: true, | | |
| 152 | scaleWithAvatar: true, | | |
| 153 | centerEndY: false, | | |
| 154 | speed: speed, | | |
| 155 | accelerationAxis: accelerationAxis, | | |
| 156 | rotateAccelerationWithAvatar: true, | | |
| 157 | renderStates: teleportRenderStates, | | |
| 158 | defaultRenderStates: teleportDefaultRenderStates, | | |
| 159 | maxDistance: 8.0 | | |
| 160 | }); | | |
| 161 | this.teleportParabolaHandInvisible = Pointers.createPointer(PickType.Parabola, { | | |
| 162 | joint: (_this.hand === RIGHT_HAND) ? "_CAMERA_RELATIVE_CONTROLLER_RIGHTHAND" : "_CAMERA_RELATIVE_CONTROLLER_LEFTHAND", | | |
| 163 | dirOffset: { x: 0, y: 1, z: 0.1 }, | | |
| 164 | posOffset: { x: (_this.hand === RIGHT_HAND) ? 0.03 : -0.03, y: 0.2, z: 0.02 }, | | |
| 165 | filter: Picks.PICK_ENTITIES | Picks.PICK_INCLUDE_INVISIBLE, | | |
| 166 | faceAvatar: true, | | |
| 167 | scaleWithAvatar: true, | | |
| 168 | centerEndY: false, | | |
| 169 | speed: speed, | | |
| 170 | accelerationAxis: accelerationAxis, | | |
| 171 | rotateAccelerationWithAvatar: true, | | |
| 172 | renderStates: teleportRenderStates, | | |
| 173 | maxDistance: 8.0 | | |
| 174 | }); | | |
| 175 | this.teleportParabolaHeadVisible = Pointers.createPointer(PickType.Parabola, { | | |
| 176 | joint: "Avatar", | | |
| 177 | filter: Picks.PICK_ENTITIES, | | |
| 178 | faceAvatar: true, | | |
| 179 | scaleWithAvatar: true, | | |
| 180 | centerEndY: false, | | |
| 181 | speed: speed, | | |
| 182 | accelerationAxis: accelerationAxis, | | |
| 183 | rotateAccelerationWithAvatar: true, | | |
| 184 | renderStates: teleportRenderStates, | | |
| 185 | defaultRenderStates: teleportDefaultRenderStates, | | |
| 186 | maxDistance: 8.0 | | |
| 187 | }); | | |
| 188 | this.teleportParabolaHeadInvisible = Pointers.createPointer(PickType.Parabola, { | | |
| 189 | joint: "Avatar", | | |
| 190 | filter: Picks.PICK_ENTITIES | Picks.PICK_INCLUDE_INVISIBLE, | | |
| 191 | faceAvatar: true, | | |
| 192 | scaleWithAvatar: true, | | |
| 193 | centerEndY: false, | | |
| 194 | speed: speed, | | |
| 195 | accelerationAxis: accelerationAxis, | | |
| 196 | rotateAccelerationWithAvatar: true, | | |
| 197 | renderStates: teleportRenderStates, | | |
| 198 | maxDistance: 8.0 | | |
| 199 | }); | | |
| 200 | | | |
| 201 | this.addToSelectedItemsList = function (overlays) { | 293 | this.addToSelectedItemsList = function (overlays) { |
| 202 | for (var i = 0, length = overlays.length; i < length; i++) { | 294 | for (var i = 0, length = overlays.length; i < length; i++) { |
| 203 | Selection.addToSelectedItemsList(this.teleporterSelectionName, "overlay", overlays[i]); | 295 | Selection.addToSelectedItemsList(this.teleporterSelectionName, "overlay", overlays[i]); |
| @@ -525,19 +617,6 @@ Script.include("/~/system/libraries/controllers.js"); · 321 unmodified lines |
| 525 | }; | 617 | }; |
| 526 | | 618 | |
| 527 | | 619 | |
| 528 | this.cleanup = function () { | | |
| 529 | Selection.removeListFromMap(this.teleporterSelectionName); | | |
| 530 | Pointers.removePointer(this.teleportParabolaHandVisible); | | |
| 531 | Pointers.removePointer(this.teleportParabolaHandInvisible); | | |
| 532 | Pointers.removePointer(this.teleportParabolaHeadVisible); | | |
| 533 | Pointers.removePointer(this.teleportParabolaHeadInvisible); | | |
| 534 | Overlays.deleteOverlay(this.teleportedTargetOverlay); | | |
| 535 | Overlays.deleteOverlay(this.playAreaOverlay); | | |
| 536 | for (var i = 0; i < this.playAreaSensorPositionOverlays.length; i++) { | | |
| 537 | Overlays.deleteOverlay(this.playAreaSensorPositionOverlays[i]); | | |
| 538 | } | | |
| 539 | }; | | |
| 540 | | | |
| 541 | this.axisButtonStateX = 0; // Left/right axis button pressed. | 620 | this.axisButtonStateX = 0; // Left/right axis button pressed. |
| 542 | this.axisButtonStateY = 0; // Up/down axis button pressed. | 621 | this.axisButtonStateY = 0; // Up/down axis button pressed. |
| 543 | this.BUTTON_TRANSITION_DELAY = 100; // Allow time for transition from direction buttons to touch-pad. | 622 | this.BUTTON_TRANSITION_DELAY = 100; // Allow time for transition from direction buttons to touch-pad. |
| @@ -602,53 +681,57 @@ Script.include("/~/system/libraries/controllers.js"); · 58 unmodified lines |
| 602 | var pose = Controller.getPoseValue(handInfo[(_this.hand === RIGHT_HAND) ? 'right' : 'left'].controllerInput); | 681 | var pose = Controller.getPoseValue(handInfo[(_this.hand === RIGHT_HAND) ? 'right' : 'left'].controllerInput); |
| 603 | var mode = pose.valid ? _this.hand : 'head'; | 682 | var mode = pose.valid ? _this.hand : 'head'; |
| 604 | if (!pose.valid) { | 683 | if (!pose.valid) { |
| 605 | Pointers.disablePointer(_this.teleportParabolaHandVisible); | 684 | Pointers.disablePointer(_this.teleportParabolaHandVisuals); |
| 606 | Pointers.disablePointer(_this.teleportParabolaHandInvisible); | 685 | Pointers.disablePointer(_this.teleportParabolaHandCollisions); |
| 607 | Pointers.enablePointer(_this.teleportParabolaHeadVisible); | 686 | Picks.disablePick(_this.teleportHandCollisionPick); |
| 608 | Pointers.enablePointer(_this.teleportParabolaHeadInvisible); | 687 | Pointers.enablePointer(_this.teleportParabolaHeadVisuals); |
| | 688 | Pointers.enablePointer(_this.teleportParabolaHeadCollisions); |
| | 689 | Picks.enablePick(_this.teleportHeadCollisionPick); |
| 609 | } else { | 690 | } else { |
| 610 | Pointers.enablePointer(_this.teleportParabolaHandVisible); | 691 | Pointers.enablePointer(_this.teleportParabolaHandVisuals); |
| 611 | Pointers.enablePointer(_this.teleportParabolaHandInvisible); | 692 | Pointers.enablePointer(_this.teleportParabolaHandCollisions); |
| 612 | Pointers.disablePointer(_this.teleportParabolaHeadVisible); | 693 | Picks.enablePick(_this.teleportHandCollisionPick); |
| 613 | Pointers.disablePointer(_this.teleportParabolaHeadInvisible); | 694 | Pointers.disablePointer(_this.teleportParabolaHeadVisuals); |
| | 695 | Pointers.disablePointer(_this.teleportParabolaHeadCollisions); |
| | 696 | Picks.disablePick(_this.teleportHeadCollisionPick); |
| 614 | } | 697 | } |
| 615 | | 698 | |
| 616 | // We do up to 2 picks to find a teleport location. | 699 | // We do up to 2 picks to find a teleport location. |
| 617 | // There are 2 types of teleport locations we are interested in: | 700 | // There are 2 types of teleport locations we are interested in: |
| 618 | // 1. A visible floor. This can be any entity surface that points within some degree of "up" | 701 | // |
| | 702 | // 1. A visible floor. This can be any entity surface that points within some degree of "up" |
| | 703 | // and where the avatar capsule can be positioned without colliding |
| | 704 | // |
| 619 | // 2. A seat. The seat can be visible or invisible. | 705 | // 2. A seat. The seat can be visible or invisible. |
| 620 | // | 706 | // |
| 621 | // * In the first pass we pick against visible and invisible entities so that we can find invisible seats. | 707 | // The Collision Pick is currently parented to the end overlay on teleportParabolaXXXXCollisions |
| 622 | // We might hit an invisible entity that is not a seat, so we need to do a second pass. | | |
| 623 | // * In the second pass we pick against visible entities only. | | |
| 624 | // | 708 | // |
| 625 | var result; | 709 | // TODO |
| | 710 | // Parent the collision Pick directly to the teleportParabolaXXXXVisuals and get rid of teleportParabolaXXXXCollisions |
| | 711 | // |
| | 712 | var result, collisionResult; |
| 626 | if (mode === 'head') { | 713 | if (mode === 'head') { |
| 627 | result = Pointers.getPrevPickResult(_this.teleportParabolaHeadInvisible); | 714 | result = Pointers.getPrevPickResult(_this.teleportParabolaHeadCollisions); |
| | 715 | collisionResult = Picks.getPrevPickResult(_this.teleportHeadCollisionPick); |
| 628 | } else { | 716 | } else { |
| 629 | result = Pointers.getPrevPickResult(_this.teleportParabolaHandInvisible); | 717 | result = Pointers.getPrevPickResult(_this.teleportParabolaHandCollisions); |
| 630 | } | 718 | collisionResult = Picks.getPrevPickResult(_this.teleportHandCollisionPick); |
| 631 | | | |
| 632 | var teleportLocationType = getTeleportTargetType(result); | | |
| 633 | if (teleportLocationType === TARGET.INVISIBLE) { | | |
| 634 | if (mode === 'head') { | | |
| 635 | result = Pointers.getPrevPickResult(_this.teleportParabolaHeadVisible); | | |
| 636 | } else { | | |
| 637 | result = Pointers.getPrevPickResult(_this.teleportParabolaHandVisible); | | |
| 638 | } | | |
| 639 | teleportLocationType = getTeleportTargetType(result); | | |
| 640 | } | 719 | } |
| | 720 | |
| | 721 | var teleportLocationType = getTeleportTargetType(result, collisionResult); |
| 641 | | 722 | |
| 642 | if (teleportLocationType === TARGET.NONE) { | 723 | if (teleportLocationType === TARGET.NONE) { |
| 643 | // Use the cancel default state | 724 | // Use the cancel default state |
| 644 | this.setTeleportState(mode, "cancel", ""); | 725 | this.setTeleportState(mode, "cancel", ""); |
| 645 | } else if (teleportLocationType === TARGET.INVALID || teleportLocationType === TARGET.INVISIBLE) { | 726 | } else if (teleportLocationType === TARGET.INVALID) { |
| 646 | this.setTeleportState(mode, "", "cancel"); | 727 | this.setTeleportState(mode, "", "cancel"); |
| 647 | } else if (teleportLocationType === TARGET.SURFACE) { | 728 | } else if (teleportLocationType === TARGET.COLLIDES) { |
| 648 | this.setTeleportState(mode, "teleport", ""); | 729 | this.setTeleportState(mode, "cancel", "collision"); |
| | 730 | } else if (teleportLocationType === TARGET.SURFACE || teleportLocationType === TARGET.DISCREPANCY) { |
| | 731 | this.setTeleportState(mode, "teleport", "collision"); |
| 649 | this.updatePlayArea(result.intersection); | 732 | this.updatePlayArea(result.intersection); |
| 650 | } else if (teleportLocationType === TARGET.SEAT) { | 733 | } else if (teleportLocationType === TARGET.SEAT) { |
| 651 | this.setTeleportState(mode, "", "seat"); | 734 | this.setTeleportState(mode, "collision", "seat"); |
| 652 | } | 735 | } |
| 653 | return this.teleport(result, teleportLocationType); | 736 | return this.teleport(result, teleportLocationType); |
| 654 | }; | 737 | }; |
| @@ -664,10 +747,11 @@ Script.include("/~/system/libraries/controllers.js"); · 9 unmodified lines |
| 664 | // Do nothing | 747 | // Do nothing |
| 665 | } else if (target === TARGET.SEAT) { | 748 | } else if (target === TARGET.SEAT) { |
| 666 | Entities.callEntityMethod(result.objectID, 'sit'); | 749 | Entities.callEntityMethod(result.objectID, 'sit'); |
| 667 | } else if (target === TARGET.SURFACE) { | 750 | } else if (target === TARGET.SURFACE || target === TARGET.DISCREPANCY) { |
| 668 | var offset = getAvatarFootOffset(); | 751 | var offset = getAvatarFootOffset(); |
| 669 | result.intersection.y += offset; | 752 | result.intersection.y += offset; |
| 670 | MyAvatar.goToLocation(result.intersection, true, HMD.orientation, false); | 753 | var shouldLandSafe = target === TARGET.DISCREPANCY; |
| | 754 | MyAvatar.goToLocation(result.intersection, true, HMD.orientation, false, shouldLandSafe); |
| 671 | HMD.centerUI(); | 755 | HMD.centerUI(); |
| 672 | MyAvatar.centerBody(); | 756 | MyAvatar.centerBody(); |
| 673 | } | 757 | } |
| @@ -680,10 +764,12 @@ Script.include("/~/system/libraries/controllers.js"); · 6 unmodified lines |
| 680 | this.disableLasers = function() { | 764 | this.disableLasers = function() { |
| 681 | this.setPlayAreaVisible(false); | 765 | this.setPlayAreaVisible(false); |
| 682 | Selection.disableListHighlight(this.teleporterSelectionName); | 766 | Selection.disableListHighlight(this.teleporterSelectionName); |
| 683 | Pointers.disablePointer(_this.teleportParabolaHandVisible); | 767 | Pointers.disablePointer(_this.teleportParabolaHandVisuals); |
| 684 | Pointers.disablePointer(_this.teleportParabolaHandInvisible); | 768 | Pointers.disablePointer(_this.teleportParabolaHandCollisions); |
| 685 | Pointers.disablePointer(_this.teleportParabolaHeadVisible); | 769 | Pointers.disablePointer(_this.teleportParabolaHeadVisuals); |
| 686 | Pointers.disablePointer(_this.teleportParabolaHeadInvisible); | 770 | Pointers.disablePointer(_this.teleportParabolaHeadCollisions); |
| | 771 | Picks.disablePick(_this.teleportHeadCollisionPick); |
| | 772 | Picks.disablePick(_this.teleportHandCollisionPick); |
| 687 | }; | 773 | }; |
| 688 | | 774 | |
| 689 | this.setTeleportState = function (mode, visibleState, invisibleState) { | 775 | this.setTeleportState = function (mode, visibleState, invisibleState) { |
| @@ -695,12 +781,12 @@ Script.include("/~/system/libraries/controllers.js"); · 5 unmodified lines |
| 695 | } | 781 | } |
| 696 | var pointerID; | 782 | var pointerID; |
| 697 | if (mode === 'head') { | 783 | if (mode === 'head') { |
| 698 | Pointers.setRenderState(_this.teleportParabolaHeadVisible, visibleState); | 784 | Pointers.setRenderState(_this.teleportParabolaHeadVisuals, visibleState); |
| 699 | Pointers.setRenderState(_this.teleportParabolaHeadInvisible, invisibleState); | 785 | Pointers.setRenderState(_this.teleportParabolaHeadCollisions, invisibleState); |
| 700 | pointerID = _this.teleportParabolaHeadVisible; | 786 | pointerID = _this.teleportParabolaHeadVisible; |
| 701 | } else { | 787 | } else { |
| 702 | Pointers.setRenderState(_this.teleportParabolaHandVisible, visibleState); | 788 | Pointers.setRenderState(_this.teleportParabolaHandVisuals, visibleState); |
| 703 | Pointers.setRenderState(_this.teleportParabolaHandInvisible, invisibleState); | 789 | Pointers.setRenderState(_this.teleportParabolaHandCollisions, invisibleState); |
| 704 | pointerID = _this.teleportParabolaHandVisible; | 790 | pointerID = _this.teleportParabolaHandVisible; |
| 705 | } | 791 | } |
| 706 | this.setPlayAreaVisible(visible, Pointers.getEndOverlayID(pointerID, "teleport"), true); | 792 | this.setPlayAreaVisible(visible, Pointers.getEndOverlayID(pointerID, "teleport"), true); |
| @@ -708,16 +794,19 @@ Script.include("/~/system/libraries/controllers.js"); · 1 unmodified line |
| 708 | }; | 794 | }; |
| 709 | | 795 | |
| 710 | this.setIgnoreEntities = function(entitiesToIgnore) { | 796 | this.setIgnoreEntities = function(entitiesToIgnore) { |
| 711 | Pointers.setIgnoreItems(this.teleportParabolaHandVisible, entitiesToIgnore); | 797 | Pointers.setIgnoreItems(this.teleportParabolaHandVisuals, entitiesToIgnore); |
| 712 | Pointers.setIgnoreItems(this.teleportParabolaHandInvisible, entitiesToIgnore); | 798 | Pointers.setIgnoreItems(this.teleportParabolaHandCollisions, entitiesToIgnore); |
| 713 | Pointers.setIgnoreItems(this.teleportParabolaHeadVisible, entitiesToIgnore); | 799 | Pointers.setIgnoreItems(this.teleportParabolaHeadVisuals, entitiesToIgnore); |
| 714 | Pointers.setIgnoreItems(this.teleportParabolaHeadInvisible, entitiesToIgnore); | 800 | Pointers.setIgnoreItems(this.teleportParabolaHeadCollisions, entitiesToIgnore); |
| | 801 | Picks.setIgnoreItems(_this.teleportHeadCollisionPick, entitiesToIgnore); |
| | 802 | Picks.setIgnoreItems(_this.teleportHandCollisionPick, entitiesToIgnore); |
| 715 | }; | 803 | }; |
| 716 | } | 804 | } |
| 717 | | 805 | |
| 718 | // related to repositioning the avatar after you teleport | 806 | // related to repositioning the avatar after you teleport |
| 719 | var FOOT_JOINT_NAMES = ["RightToe_End", "RightToeBase", "RightFoot"]; | 807 | var FOOT_JOINT_NAMES = ["RightToe_End", "RightToeBase", "RightFoot"]; |
| 720 | var DEFAULT_ROOT_TO_FOOT_OFFSET = 0.5; | 808 | var DEFAULT_ROOT_TO_FOOT_OFFSET = 0.5; |
| | 809 | |
| 721 | function getAvatarFootOffset() { | 810 | function getAvatarFootOffset() { |
| 722 | | 811 | |
| 723 | // find a valid foot jointIndex | 812 | // find a valid foot jointIndex |
| @@ -758,7 +847,29 @@ Script.include("/~/system/libraries/controllers.js"); · 34 unmodified lines |
| 758 | // than MAX_ANGLE_FROM_UP_TO_TELEPORT degrees from your avatar's up, then | 847 | // than MAX_ANGLE_FROM_UP_TO_TELEPORT degrees from your avatar's up, then |
| 759 | // you can't teleport there. | 848 | // you can't teleport there. |
| 760 | var MAX_ANGLE_FROM_UP_TO_TELEPORT = 70; | 849 | var MAX_ANGLE_FROM_UP_TO_TELEPORT = 70; |
| 761 | function getTeleportTargetType(result) { | 850 | var MAX_DISCREPANCY_DISTANCE = 1.0; |
| | 851 | var MAX_DOT_SIGN = -0.6; |
| | 852 | |
| | 853 | function checkForMeshDiscrepancy(result, collisionResult) { |
| | 854 | var intersectingObjects = collisionResult.intersectingObjects; |
| | 855 | if (intersectingObjects.length > 0 && intersectingObjects.length < 3) { |
| | 856 | for (var j = 0; j < collisionResult.intersectingObjects.length; j++) { |
| | 857 | var intersectingObject = collisionResult.intersectingObjects[j]; |
| | 858 | for (var i = 0; i < intersectingObject.collisionContacts.length; i++) { |
| | 859 | var normal = intersectingObject.collisionContacts[i].normalOnPick; |
| | 860 | var distanceToPick = Vec3.distance(intersectingObject.collisionContacts[i].pointOnPick, result.intersection); |
| | 861 | var normalSign = Vec3.dot(normal, Quat.getUp(MyAvatar.orientation)); |
| | 862 | if ((distanceToPick > MAX_DISCREPANCY_DISTANCE) || (normalSign > MAX_DOT_SIGN)) { |
| | 863 | return false; |
| | 864 | } |
| | 865 | } |
| | 866 | } |
| | 867 | return true; |
| | 868 | } |
| | 869 | return false; |
| | 870 | } |
| | 871 | |
| | 872 | function getTeleportTargetType(result, collisionResult) { |
| 762 | if (result.type === Picks.INTERSECTED_NONE) { | 873 | if (result.type === Picks.INTERSECTED_NONE) { |
| 763 | return TARGET.NONE; | 874 | return TARGET.NONE; |
| 764 | } | 875 | } |
| @@ -773,9 +884,14 @@ Script.include("/~/system/libraries/controllers.js"); · 8 unmodified lines |
| 773 | return TARGET.INVALID; | 884 | return TARGET.INVALID; |
| 774 | } | 885 | } |
| 775 | } | 886 | } |
| 776 | | 887 | var isDiscrepancy = false; |
| 777 | if (!props.visible) { | 888 | if (collisionResult.collisionRegion != undefined) { |
| 778 | return TARGET.INVISIBLE; | 889 | if (collisionResult.intersects) { |
| | 890 | isDiscrepancy = checkForMeshDiscrepancy(result, collisionResult); |
| | 891 | if (!isDiscrepancy) { |
| | 892 | return TARGET.COLLIDES; |
| | 893 | } |
| | 894 | } |
| 779 | } | 895 | } |
| 780 | | 896 | |
| 781 | var surfaceNormal = result.surfaceNormal; | 897 | var surfaceNormal = result.surfaceNormal; |
| @@ -783,6 +899,8 @@ Script.include("/~/system/libraries/controllers.js"); · 1 unmodified line |
| 783 | | 899 | |
| 784 | if (angle > MAX_ANGLE_FROM_UP_TO_TELEPORT) { | 900 | if (angle > MAX_ANGLE_FROM_UP_TO_TELEPORT) { |
| 785 | return TARGET.INVALID; | 901 | return TARGET.INVALID; |
| | 902 | } else if (isDiscrepancy) { |
| | 903 | return TARGET.DISCREPANCY; |
| 786 | } else { | 904 | } else { |
| 787 | return TARGET.SURFACE; | 905 | return TARGET.SURFACE; |
| 788 | } | 906 | } |
| @@ -876,7 +994,14 @@ Script.include("/~/system/libraries/controllers.js"); · 87 unmodified lines |
| 876 | } | 994 | } |
| 877 | } | 995 | } |
| 878 | }; | 996 | }; |
| 879 | | 997 | |
| | 998 | MyAvatar.onLoadComplete.connect(function () { |
| | 999 | Script.setTimeout(function () { |
| | 1000 | leftTeleporter.initPointers(); |
| | 1001 | rightTeleporter.initPointers(); |
| | 1002 | }, 500); |
| | 1003 | }); |
| | 1004 | |
| 880 | Messages.subscribe('Hifi-Teleport-Disabler'); | 1005 | Messages.subscribe('Hifi-Teleport-Disabler'); |
| 881 | Messages.subscribe('Hifi-Teleport-Ignore-Add'); | 1006 | Messages.subscribe('Hifi-Teleport-Ignore-Add'); |
| 882 | Messages.subscribe('Hifi-Teleport-Ignore-Remove'); | 1007 | Messages.subscribe('Hifi-Teleport-Ignore-Remove'); |