History

Merge branch 'master' into M18586

# Conflicts: # interface/src/raypick/PointerScriptingInterface.cpp # interface/src/raypick/PointerScriptingInterface.h # interface/src/raypick/StylusPointer.h # libraries/pointers/src/Pointer.h # scripts/system/controllers/controllerModules/teleport.js

David Rowe committed 8 years ago

Commit e29b4032 parents c41d746 ea7bc26375 files · +10588 −5704Browse files

Showing the changes to scripts/system/controllers/controllerModules (9 of 375 files). Show all

Unified · Split

9 files
  1. scripts/system/controllers/controllerModules/highlightNearbyEntities.js +1 −1
  2. scripts/system/controllers/controllerModules/inEditMode.js +1 −1
  3. scripts/system/controllers/controllerModules/inVREditMode.js +1 −1
  4. scripts/system/controllers/controllerModules/nearActionGrabEntity.js +1 −1
  5. scripts/system/controllers/controllerModules/nearGrabHyperLinkEntity.js +1 −1
  6. scripts/system/controllers/controllerModules/nearParentGrabEntity.js +4 −1
  7. scripts/system/controllers/controllerModules/nearTrigger.js +1 −1
  8. scripts/system/controllers/controllerModules/teleport.js +247 −122
  9. scripts/system/controllers/controllerModules/webSurfaceLaserInput.js +45 −13
scripts/system/controllers/controllerModules/highlightNearbyEntities.js+1−1
@@ -37,7 +37,7 @@ · 36 unmodified lines
3737 this.highlightedEntities = [];
3838
3939 this.parameters = dispatcherUtils.makeDispatcherModuleParameters(
40− 480,
40+ 120,
4141 this.hand === dispatcherUtils.RIGHT_HAND ? ["rightHand"] : ["leftHand"],
4242 [],
4343 100);
scripts/system/controllers/controllerModules/inEditMode.js+1−1
@@ -29,7 +29,7 @@ Script.include("/~/system/libraries/utils.js"); · 28 unmodified lines
2929 this.reticleMaxY;
3030
3131 this.parameters = makeDispatcherModuleParameters(
32− 160,
32+ 200,
3333 this.hand === RIGHT_HAND ? ["rightHand", "rightHandEquip", "rightHandTrigger"] : ["leftHand", "leftHandEquip", "leftHandTrigger"],
3434 [],
3535 100,
scripts/system/controllers/controllerModules/inVREditMode.js+1−1
@@ -21,7 +21,7 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js"); · 20 unmodified lines
2121 this.disableModules = false;
2222 var NO_HAND_LASER = -1; // Invalid hand parameter so that default laser is not displayed.
2323 this.parameters = makeDispatcherModuleParameters(
24− 200, // Not too high otherwise the tablet laser doesn't work.
24+ 240, // Not too high otherwise the tablet laser doesn't work.
2525 this.hand === RIGHT_HAND
2626 ? ["rightHand", "rightHandEquip", "rightHandTrigger"]
2727 : ["leftHand", "leftHandEquip", "leftHandTrigger"],
scripts/system/controllers/controllerModules/nearActionGrabEntity.js+1−1
@@ -26,7 +26,7 @@ Script.include("/~/system/libraries/cloneEntityUtils.js"); · 25 unmodified lines
2626 this.hapticTargetID = null;
2727
2828 this.parameters = makeDispatcherModuleParameters(
29− 500,
29+ 140,
3030 this.hand === RIGHT_HAND ? ["rightHand"] : ["leftHand"],
3131 [],
3232 100);
scripts/system/controllers/controllerModules/nearGrabHyperLinkEntity.js+1−1
@@ -21,7 +21,7 @@ · 20 unmodified lines
2121 this.hyperlink = "";
2222
2323 this.parameters = makeDispatcherModuleParameters(
24− 485,
24+ 125,
2525 this.hand === RIGHT_HAND ? ["rightHand"] : ["leftHand"],
2626 [],
2727 100);
scripts/system/controllers/controllerModules/nearParentGrabEntity.js+4−1
@@ -24,6 +24,9 @@ Script.include("/~/system/libraries/controllers.js"); · 23 unmodified lines
2424 // XXX this.ignoreIK = (grabbableData.ignoreIK !== undefined) ? grabbableData.ignoreIK : true;
2525 // XXX this.kinematicGrab = (grabbableData.kinematic !== undefined) ? grabbableData.kinematic : NEAR_GRABBING_KINEMATIC;
2626
27+ // this offset needs to match the one in libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp:378
28+ var GRAB_POINT_SPHERE_OFFSET = { x: 0.04, y: 0.13, z: 0.039 }; // x = upward, y = forward, z = lateral
29+
2730 function getGrabOffset(handController) {
2831 var offset = GRAB_POINT_SPHERE_OFFSET;
2932 if (handController === Controller.Standard.LeftHand) {
@@ -54,7 +57,7 @@ Script.include("/~/system/libraries/controllers.js"); · 24 unmodified lines
5457 this.cloneAllowed = true;
5558
5659 this.parameters = makeDispatcherModuleParameters(
57− 500,
60+ 140,
5861 this.hand === RIGHT_HAND ? ["rightHand"] : ["leftHand"],
5962 [],
6063 100);
scripts/system/controllers/controllerModules/nearTrigger.js+1−1
@@ -29,7 +29,7 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js"); · 28 unmodified lines
2929 this.startSent = false;
3030
3131 this.parameters = makeDispatcherModuleParameters(
32− 480,
32+ 120,
3333 this.hand === RIGHT_HAND ? ["rightHandTrigger", "rightHand"] : ["leftHandTrigger", "leftHand"],
3434 [],
3535 100);
scripts/system/controllers/controllerModules/teleport.js+247−122
@@ -59,42 +59,53 @@ Script.include("/~/system/libraries/controllers.js"); · 58 unmodified lines
5959 width: 0.025,
6060 drawInFront: true
6161 };
62+
6263 var teleportPath = {
6364 color: COLORS_TELEPORT_CAN_TELEPORT,
6465 alpha: 1,
6566 width: 0.025,
6667 drawInFront: true
6768 };
69+
6870 var seatPath = {
6971 color: COLORS_TELEPORT_SEAT,
7072 alpha: 1,
7173 width: 0.025,
7274 drawInFront: true
7375 };
76+
7477 var teleportEnd = {
7578 type: "model",
7679 url: TARGET_MODEL_URL,
7780 dimensions: TARGET_MODEL_DIMENSIONS,
7881 ignorePickIntersection: true
7982 };
83+
8084 var seatEnd = {
8185 type: "model",
8286 url: SEAT_MODEL_URL,
8387 dimensions: TARGET_MODEL_DIMENSIONS,
8488 ignorePickIntersection: true
8589 };
86−
87−
90+
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+
8899 var teleportRenderStates = [{name: "cancel", path: cancelPath},
89100 {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}];
91103
92104 var DEFAULT_DISTANCE = 8.0;
93105 var teleportDefaultRenderStates = [{name: "cancel", distance: DEFAULT_DISTANCE, path: cancelPath}];
94106
95107 var ignoredEntities = [];
96108
97−
98109 var TELEPORTER_STATES = {
99110 IDLE: 'idle',
100111 TARGETTING: 'targetting',
@@ -103,8 +114,9 @@ Script.include("/~/system/libraries/controllers.js"); · 2 unmodified lines
103114
104115 var TARGET = {
105116 NONE: 'none', // Not currently targetting anything
106− INVISIBLE: 'invisible', // The current target is an invvsible surface
107117 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
108120 SURFACE: 'surface', // The current target is a valid surface
109121 SEAT: 'seat' // The current target is a seat
110122 };
@@ -114,6 +126,7 @@ Script.include("/~/system/libraries/controllers.js"); · 3 unmodified lines
114126
115127 function Teleporter(hand) {
116128 var _this = this;
129+ this.init = false;
117130 this.hand = hand;
118131 this.buttonValue = 0;
119132 this.disabled = false; // used by the 'Hifi-Teleport-Disabler' message handler
@@ -121,12 +134,147 @@ Script.include("/~/system/libraries/controllers.js"); · 1 unmodified line
121134 this.state = TELEPORTER_STATES.IDLE;
122135 this.currentTarget = TARGET.INVALID;
123136 this.currentResult = null;
137+ this.capsuleThreshold = 0.05;
138+ this.pickHeightOffset = 0.05;
124139
125140 this.getOtherModule = function() {
126141 var otherModule = this.hand === RIGHT_HAND ? leftTeleporter : rightTeleporter;
127142 return otherModule;
128143 };
129144
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+
130278
131279 this.teleporterSelectionName = "teleporterSelection" + hand.toString();
132280 this.TELEPORTER_SELECTION_STYLE = {
@@ -142,62 +290,6 @@ Script.include("/~/system/libraries/controllers.js"); · 9 unmodified lines
142290 isOutlineSmooth: false
143291 };
144292
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−
201293 this.addToSelectedItemsList = function (overlays) {
202294 for (var i = 0, length = overlays.length; i < length; i++) {
203295 Selection.addToSelectedItemsList(this.teleporterSelectionName, "overlay", overlays[i]);
@@ -525,19 +617,6 @@ Script.include("/~/system/libraries/controllers.js"); · 321 unmodified lines
525617 };
526618
527619
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−
541620 this.axisButtonStateX = 0; // Left/right axis button pressed.
542621 this.axisButtonStateY = 0; // Up/down axis button pressed.
543622 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
602681 var pose = Controller.getPoseValue(handInfo[(_this.hand === RIGHT_HAND) ? 'right' : 'left'].controllerInput);
603682 var mode = pose.valid ? _this.hand : 'head';
604683 if (!pose.valid) {
605− Pointers.disablePointer(_this.teleportParabolaHandVisible);
606− Pointers.disablePointer(_this.teleportParabolaHandInvisible);
607− Pointers.enablePointer(_this.teleportParabolaHeadVisible);
608− Pointers.enablePointer(_this.teleportParabolaHeadInvisible);
684+ Pointers.disablePointer(_this.teleportParabolaHandVisuals);
685+ Pointers.disablePointer(_this.teleportParabolaHandCollisions);
686+ Picks.disablePick(_this.teleportHandCollisionPick);
687+ Pointers.enablePointer(_this.teleportParabolaHeadVisuals);
688+ Pointers.enablePointer(_this.teleportParabolaHeadCollisions);
689+ Picks.enablePick(_this.teleportHeadCollisionPick);
609690 } else {
610− Pointers.enablePointer(_this.teleportParabolaHandVisible);
611− Pointers.enablePointer(_this.teleportParabolaHandInvisible);
612− Pointers.disablePointer(_this.teleportParabolaHeadVisible);
613− Pointers.disablePointer(_this.teleportParabolaHeadInvisible);
691+ Pointers.enablePointer(_this.teleportParabolaHandVisuals);
692+ Pointers.enablePointer(_this.teleportParabolaHandCollisions);
693+ Picks.enablePick(_this.teleportHandCollisionPick);
694+ Pointers.disablePointer(_this.teleportParabolaHeadVisuals);
695+ Pointers.disablePointer(_this.teleportParabolaHeadCollisions);
696+ Picks.disablePick(_this.teleportHeadCollisionPick);
614697 }
615698
616699 // We do up to 2 picks to find a teleport location.
617700 // 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+ //
619705 // 2. A seat. The seat can be visible or invisible.
620706 //
621− // * In the first pass we pick against visible and invisible entities so that we can find invisible seats.
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.
707+ // The Collision Pick is currently parented to the end overlay on teleportParabolaXXXXCollisions
624708 //
625− var result;
709+ // TODO
710+ // Parent the collision Pick directly to the teleportParabolaXXXXVisuals and get rid of teleportParabolaXXXXCollisions
711+ //
712+ var result, collisionResult;
626713 if (mode === 'head') {
627− result = Pointers.getPrevPickResult(_this.teleportParabolaHeadInvisible);
714+ result = Pointers.getPrevPickResult(_this.teleportParabolaHeadCollisions);
715+ collisionResult = Picks.getPrevPickResult(_this.teleportHeadCollisionPick);
628716 } else {
629− result = Pointers.getPrevPickResult(_this.teleportParabolaHandInvisible);
630− }
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);
717+ result = Pointers.getPrevPickResult(_this.teleportParabolaHandCollisions);
718+ collisionResult = Picks.getPrevPickResult(_this.teleportHandCollisionPick);
640719 }
720+
721+ var teleportLocationType = getTeleportTargetType(result, collisionResult);
641722
642723 if (teleportLocationType === TARGET.NONE) {
643724 // Use the cancel default state
644725 this.setTeleportState(mode, "cancel", "");
645− } else if (teleportLocationType === TARGET.INVALID || teleportLocationType === TARGET.INVISIBLE) {
726+ } else if (teleportLocationType === TARGET.INVALID) {
646727 this.setTeleportState(mode, "", "cancel");
647− } else if (teleportLocationType === TARGET.SURFACE) {
648− this.setTeleportState(mode, "teleport", "");
728+ } else if (teleportLocationType === TARGET.COLLIDES) {
729+ this.setTeleportState(mode, "cancel", "collision");
730+ } else if (teleportLocationType === TARGET.SURFACE || teleportLocationType === TARGET.DISCREPANCY) {
731+ this.setTeleportState(mode, "teleport", "collision");
649732 this.updatePlayArea(result.intersection);
650733 } else if (teleportLocationType === TARGET.SEAT) {
651− this.setTeleportState(mode, "", "seat");
734+ this.setTeleportState(mode, "collision", "seat");
652735 }
653736 return this.teleport(result, teleportLocationType);
654737 };
@@ -664,10 +747,11 @@ Script.include("/~/system/libraries/controllers.js"); · 9 unmodified lines
664747 // Do nothing
665748 } else if (target === TARGET.SEAT) {
666749 Entities.callEntityMethod(result.objectID, 'sit');
667− } else if (target === TARGET.SURFACE) {
750+ } else if (target === TARGET.SURFACE || target === TARGET.DISCREPANCY) {
668751 var offset = getAvatarFootOffset();
669752 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);
671755 HMD.centerUI();
672756 MyAvatar.centerBody();
673757 }
@@ -680,10 +764,12 @@ Script.include("/~/system/libraries/controllers.js"); · 6 unmodified lines
680764 this.disableLasers = function() {
681765 this.setPlayAreaVisible(false);
682766 Selection.disableListHighlight(this.teleporterSelectionName);
683− Pointers.disablePointer(_this.teleportParabolaHandVisible);
684− Pointers.disablePointer(_this.teleportParabolaHandInvisible);
685− Pointers.disablePointer(_this.teleportParabolaHeadVisible);
686− Pointers.disablePointer(_this.teleportParabolaHeadInvisible);
767+ Pointers.disablePointer(_this.teleportParabolaHandVisuals);
768+ Pointers.disablePointer(_this.teleportParabolaHandCollisions);
769+ Pointers.disablePointer(_this.teleportParabolaHeadVisuals);
770+ Pointers.disablePointer(_this.teleportParabolaHeadCollisions);
771+ Picks.disablePick(_this.teleportHeadCollisionPick);
772+ Picks.disablePick(_this.teleportHandCollisionPick);
687773 };
688774
689775 this.setTeleportState = function (mode, visibleState, invisibleState) {
@@ -695,12 +781,12 @@ Script.include("/~/system/libraries/controllers.js"); · 5 unmodified lines
695781 }
696782 var pointerID;
697783 if (mode === 'head') {
698− Pointers.setRenderState(_this.teleportParabolaHeadVisible, visibleState);
699− Pointers.setRenderState(_this.teleportParabolaHeadInvisible, invisibleState);
784+ Pointers.setRenderState(_this.teleportParabolaHeadVisuals, visibleState);
785+ Pointers.setRenderState(_this.teleportParabolaHeadCollisions, invisibleState);
700786 pointerID = _this.teleportParabolaHeadVisible;
701787 } else {
702− Pointers.setRenderState(_this.teleportParabolaHandVisible, visibleState);
703− Pointers.setRenderState(_this.teleportParabolaHandInvisible, invisibleState);
788+ Pointers.setRenderState(_this.teleportParabolaHandVisuals, visibleState);
789+ Pointers.setRenderState(_this.teleportParabolaHandCollisions, invisibleState);
704790 pointerID = _this.teleportParabolaHandVisible;
705791 }
706792 this.setPlayAreaVisible(visible, Pointers.getEndOverlayID(pointerID, "teleport"), true);
@@ -708,16 +794,19 @@ Script.include("/~/system/libraries/controllers.js"); · 1 unmodified line
708794 };
709795
710796 this.setIgnoreEntities = function(entitiesToIgnore) {
711− Pointers.setIgnoreItems(this.teleportParabolaHandVisible, entitiesToIgnore);
712− Pointers.setIgnoreItems(this.teleportParabolaHandInvisible, entitiesToIgnore);
713− Pointers.setIgnoreItems(this.teleportParabolaHeadVisible, entitiesToIgnore);
714− Pointers.setIgnoreItems(this.teleportParabolaHeadInvisible, entitiesToIgnore);
797+ Pointers.setIgnoreItems(this.teleportParabolaHandVisuals, entitiesToIgnore);
798+ Pointers.setIgnoreItems(this.teleportParabolaHandCollisions, entitiesToIgnore);
799+ Pointers.setIgnoreItems(this.teleportParabolaHeadVisuals, entitiesToIgnore);
800+ Pointers.setIgnoreItems(this.teleportParabolaHeadCollisions, entitiesToIgnore);
801+ Picks.setIgnoreItems(_this.teleportHeadCollisionPick, entitiesToIgnore);
802+ Picks.setIgnoreItems(_this.teleportHandCollisionPick, entitiesToIgnore);
715803 };
716804 }
717805
718806 // related to repositioning the avatar after you teleport
719807 var FOOT_JOINT_NAMES = ["RightToe_End", "RightToeBase", "RightFoot"];
720808 var DEFAULT_ROOT_TO_FOOT_OFFSET = 0.5;
809+
721810 function getAvatarFootOffset() {
722811
723812 // find a valid foot jointIndex
@@ -758,7 +847,29 @@ Script.include("/~/system/libraries/controllers.js"); · 34 unmodified lines
758847 // than MAX_ANGLE_FROM_UP_TO_TELEPORT degrees from your avatar's up, then
759848 // you can't teleport there.
760849 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) {
762873 if (result.type === Picks.INTERSECTED_NONE) {
763874 return TARGET.NONE;
764875 }
@@ -773,9 +884,14 @@ Script.include("/~/system/libraries/controllers.js"); · 8 unmodified lines
773884 return TARGET.INVALID;
774885 }
775886 }
776−
777− if (!props.visible) {
778− return TARGET.INVISIBLE;
887+ var isDiscrepancy = false;
888+ if (collisionResult.collisionRegion != undefined) {
889+ if (collisionResult.intersects) {
890+ isDiscrepancy = checkForMeshDiscrepancy(result, collisionResult);
891+ if (!isDiscrepancy) {
892+ return TARGET.COLLIDES;
893+ }
894+ }
779895 }
780896
781897 var surfaceNormal = result.surfaceNormal;
@@ -783,6 +899,8 @@ Script.include("/~/system/libraries/controllers.js"); · 1 unmodified line
783899
784900 if (angle > MAX_ANGLE_FROM_UP_TO_TELEPORT) {
785901 return TARGET.INVALID;
902+ } else if (isDiscrepancy) {
903+ return TARGET.DISCREPANCY;
786904 } else {
787905 return TARGET.SURFACE;
788906 }
@@ -876,7 +994,14 @@ Script.include("/~/system/libraries/controllers.js"); · 87 unmodified lines
876994 }
877995 }
878996 };
879−
997+
998+ MyAvatar.onLoadComplete.connect(function () {
999+ Script.setTimeout(function () {
1000+ leftTeleporter.initPointers();
1001+ rightTeleporter.initPointers();
1002+ }, 500);
1003+ });
1004+
8801005 Messages.subscribe('Hifi-Teleport-Disabler');
8811006 Messages.subscribe('Hifi-Teleport-Ignore-Add');
8821007 Messages.subscribe('Hifi-Teleport-Ignore-Remove');
scripts/system/controllers/controllerModules/webSurfaceLaserInput.js+45−13
@@ -22,14 +22,14 @@ Script.include("/~/system/libraries/controllers.js"); · 21 unmodified lines
2222 this.running = false;
2323
2424 this.parameters = makeDispatcherModuleParameters(
25− 120,
25+ 160,
2626 this.hand === RIGHT_HAND ? ["rightHand"] : ["leftHand"],
2727 [],
2828 100,
2929 makeLaserParams(hand, true));
3030
3131 this.grabModuleWantsNearbyOverlay = function(controllerData) {
32− if (controllerData.triggerValues[this.hand] > TRIGGER_ON_VALUE) {
32+ if (controllerData.triggerValues[this.hand] > TRIGGER_ON_VALUE || controllerData.secondaryValues[this.hand] > BUMPER_ON_VALUE) {
3333 var nearGrabName = this.hand === RIGHT_HAND ? "RightNearParentingGrabOverlay" : "LeftNearParentingGrabOverlay";
3434 var nearGrabModule = getEnabledModuleByName(nearGrabName);
3535 if (nearGrabModule) {
@@ -42,6 +42,23 @@ Script.include("/~/system/libraries/controllers.js"); · 6 unmodified lines
4242 return true;
4343 }
4444 }
45+ nearGrabName = this.hand === RIGHT_HAND ? "RightNearParentingGrabEntity" : "LeftNearParentingGrabEntity";
46+ nearGrabModule = getEnabledModuleByName(nearGrabName);
47+ if (nearGrabModule && nearGrabModule.isReady(controllerData)) {
48+ // check for if near parent module is active.
49+ var isNearGrabModuleActive = nearGrabModule.isReady(controllerData).active;
50+ if (isNearGrabModuleActive) {
51+ // if true, return true.
52+ return isNearGrabModuleActive;
53+ } else {
54+ // check near action grab entity as a second pass.
55+ nearGrabName = this.hand === RIGHT_HAND ? "RightNearActionGrabEntity" : "LeftNearActionGrabEntity";
56+ nearGrabModule = getEnabledModuleByName(nearGrabName);
57+ if (nearGrabModule && nearGrabModule.isReady(controllerData)) {
58+ return nearGrabModule.isReady(controllerData).active;
59+ }
60+ }
61+ }
4562 }
4663 return false;
4764 };
@@ -50,14 +67,14 @@ Script.include("/~/system/libraries/controllers.js"); · 2 unmodified lines
5067 return this.hand === RIGHT_HAND ? leftOverlayLaserInput : rightOverlayLaserInput;
5168 };
5269
53− this.isPointingAtTriggerable = function(controllerData, triggerPressed) {
70+ this.isPointingAtTriggerable = function(controllerData, triggerPressed, checkEntitiesOnly) {
5471 // allow pointing at tablet, unlocked web entities, or web overlays automatically without pressing trigger,
5572 // but for pointing at locked web entities or non-web overlays user must be pressing trigger
5673 var intersection = controllerData.rayPicks[this.hand];
57− if (intersection.type === Picks.INTERSECTED_OVERLAY) {
58− var objectID = intersection.objectID;
74+ var objectID = intersection.objectID;
75+ if (intersection.type === Picks.INTERSECTED_OVERLAY && !checkEntitiesOnly) {
5976 if ((HMD.tabletID && objectID === HMD.tabletID) ||
60− (HMD.tabletScreenID && objectID === HMD.tabletScreenID) ||
77+ (HMD.tabletScreenID && objectID === HMD.tabletScreenID) ||
6178 (HMD.homeButtonID && objectID === HMD.homeButtonID)) {
6279 return true;
6380 } else {
@@ -65,9 +82,9 @@ Script.include("/~/system/libraries/controllers.js"); · 1 unmodified line
6582 return overlayType === "web3d" || triggerPressed;
6683 }
6784 } else if (intersection.type === Picks.INTERSECTED_ENTITY) {
68− var entityProperty = Entities.getEntityProperties(intersection.objectID);
69− var entityType = entityProperty.type;
70− var isLocked = entityProperty.locked;
85+ var entityProperties = Entities.getEntityProperties(objectID);
86+ var entityType = entityProperties.type;
87+ var isLocked = entityProperties.locked;
7188 return entityType === "Web" && (!isLocked || triggerPressed);
7289 }
7390 return false;
@@ -103,7 +120,8 @@ Script.include("/~/system/libraries/controllers.js"); · 29 unmodified lines
103120 var isTriggerPressed = controllerData.triggerValues[this.hand] > TRIGGER_OFF_VALUE &&
104121 controllerData.triggerValues[this.otherHand] <= TRIGGER_OFF_VALUE;
105122 var allowThisModule = !otherModuleRunning || isTriggerPressed;
106− if (allowThisModule && this.isPointingAtTriggerable(controllerData, isTriggerPressed)) {
123+
124+ if (allowThisModule && this.isPointingAtTriggerable(controllerData, isTriggerPressed, false)) {
107125 this.updateAllwaysOn();
108126 if (isTriggerPressed) {
109127 this.dominantHandOverride = true; // Override dominant hand.
@@ -121,13 +139,27 @@ Script.include("/~/system/libraries/controllers.js"); · 11 unmodified lines
121139 otherModuleRunning = otherModuleRunning && this.getDominantHand() !== this.hand; // Auto-swap to dominant hand.
122140 otherModuleRunning = otherModuleRunning || this.getOtherModule().dominantHandOverride; // Override dominant hand.
123141 var grabModuleNeedsToRun = this.grabModuleWantsNearbyOverlay(controllerData);
142+ // only allow for non-near grab
124143 var allowThisModule = !otherModuleRunning && !grabModuleNeedsToRun;
125144 var isTriggerPressed = controllerData.triggerValues[this.hand] > TRIGGER_OFF_VALUE;
126145 var laserOn = isTriggerPressed || this.parameters.handLaser.allwaysOn;
127− if (allowThisModule && (laserOn && this.isPointingAtTriggerable(controllerData, isTriggerPressed))) {
128− this.running = true;
129− return makeRunningValues(true, [], []);
146+ if (allowThisModule) {
147+ if (isTriggerPressed && !this.isPointingAtTriggerable(controllerData, isTriggerPressed, true)) {
148+ // if trigger is down + not pointing at a web entity, keep running web surface laser
149+ this.running = true;
150+ return makeRunningValues(true, [], []);
151+ } else if (laserOn && this.isPointingAtTriggerable(controllerData, isTriggerPressed, false)) {
152+ // if trigger is down + pointing at a web entity/overlay, keep running web surface laser
153+ this.running = true;
154+ return makeRunningValues(true, [], []);
155+ } else {
156+ this.deleteContextOverlay();
157+ this.running = false;
158+ this.dominantHandOverride = false;
159+ return makeRunningValues(false, [], []);
160+ }
130161 }
162+ // if module needs to stop from near grabs or other modules are running, stop it.
131163 this.deleteContextOverlay();
132164 this.running = false;
133165 this.dominantHandOverride = false;