Merge pull request #8371 from imgntn/teleport_cancel

Cancel mode for teleporting
This commit is contained in:
Brad Hefta-Gaub 2016-08-08 13:04:27 -07:00 committed by GitHub
commit b903c974bc
4 changed files with 137 additions and 51 deletions

Binary file not shown.

Binary file not shown.

View file

@ -1,34 +1,18 @@
// Created by james b. pollack @imgntn on 7/2/2016 // Created by james b. pollack @imgntn on 7/2/2016
// Copyright 2016 High Fidelity, Inc. // Copyright 2016 High Fidelity, Inc.
// //
// Creates a beam and target and then teleports you there. // Creates a beam and target and then teleports you there. Release when its close to you to cancel.
// //
// Distributed under the Apache License, Version 2.0. // Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
var inTeleportMode = false; var inTeleportMode = false;
// instant
// var NUMBER_OF_STEPS = 0;
// var SMOOTH_ARRIVAL_SPACING = 0;
// // slow
// var SMOOTH_ARRIVAL_SPACING = 150;
// var NUMBER_OF_STEPS = 2;
// medium-slow
// var SMOOTH_ARRIVAL_SPACING = 100;
// var NUMBER_OF_STEPS = 4;
// medium-fast
var SMOOTH_ARRIVAL_SPACING = 33; var SMOOTH_ARRIVAL_SPACING = 33;
var NUMBER_OF_STEPS = 6; var NUMBER_OF_STEPS = 6;
//fast var TARGET_MODEL_URL = Script.resolvePath("../assets/models/teleport-destination.fbx");
// var SMOOTH_ARRIVAL_SPACING = 10; var TOO_CLOSE_MODEL_URL = Script.resolvePath("../assets/models/teleport-cancel.fbx");
// var NUMBER_OF_STEPS = 20;
var TARGET_MODEL_URL = Script.resolvePath("../assets/models/teleport.fbx");
var TARGET_MODEL_DIMENSIONS = { var TARGET_MODEL_DIMENSIONS = {
x: 1.15, x: 1.15,
y: 0.5, y: 0.5,
@ -47,7 +31,13 @@ var COLORS_TELEPORT_CANNOT_TELEPORT = {
blue: 141 blue: 141
}; };
var MAX_AVATAR_SPEED = 0.25; var COLORS_TELEPORT_TOO_CLOSE = {
red: 255,
green: 184,
blue: 73
};
var TELEPORT_CANCEL_RANGE = 1.5;
function ThumbPad(hand) { function ThumbPad(hand) {
this.hand = hand; this.hand = hand;
@ -86,29 +76,17 @@ function Teleporter() {
this.rightOverlayLine = null; this.rightOverlayLine = null;
this.leftOverlayLine = null; this.leftOverlayLine = null;
this.targetOverlay = null; this.targetOverlay = null;
this.cancelOverlay = null;
this.updateConnected = null; this.updateConnected = null;
this.smoothArrivalInterval = null; this.smoothArrivalInterval = null;
this.teleportHand = null; this.teleportHand = null;
this.tooClose = false;
this.initialize = function() { this.initialize = function() {
this.createMappings(); this.createMappings();
this.disableGrab(); this.disableGrab();
}; };
this.createTargetOverlay = function() {
if (_this.targetOverlay !== null) {
return;
}
var targetOverlayProps = {
url: TARGET_MODEL_URL,
dimensions: TARGET_MODEL_DIMENSIONS,
visible: true
};
_this.targetOverlay = Overlays.addOverlay("model", targetOverlayProps);
};
this.createMappings = function() { this.createMappings = function() {
teleporter.telporterMappingInternalName = 'Hifi-Teleporter-Internal-Dev-' + Math.random(); teleporter.telporterMappingInternalName = 'Hifi-Teleporter-Internal-Dev-' + Math.random();
teleporter.teleportMappingInternal = Controller.newMapping(teleporter.telporterMappingInternalName); teleporter.teleportMappingInternal = Controller.newMapping(teleporter.telporterMappingInternalName);
@ -143,11 +121,56 @@ function Teleporter() {
this.updateConnected = true; this.updateConnected = true;
}; };
this.createTargetOverlay = function() {
if (_this.targetOverlay !== null) {
return;
}
var targetOverlayProps = {
url: TARGET_MODEL_URL,
dimensions: TARGET_MODEL_DIMENSIONS,
visible: true
};
var cancelOverlayProps = {
url: TOO_CLOSE_MODEL_URL,
dimensions: TARGET_MODEL_DIMENSIONS,
visible: true
};
_this.targetOverlay = Overlays.addOverlay("model", targetOverlayProps);
};
this.createCancelOverlay = function() {
if (_this.cancelOverlay !== null) {
return;
}
var cancelOverlayProps = {
url: TOO_CLOSE_MODEL_URL,
dimensions: TARGET_MODEL_DIMENSIONS,
visible: true
};
_this.cancelOverlay = Overlays.addOverlay("model", cancelOverlayProps);
};
this.deleteCancelOverlay = function() {
if (this.cancelOverlay === null) {
return;
}
Overlays.deleteOverlay(this.cancelOverlay);
this.cancelOverlay = null;
}
this.deleteTargetOverlay = function() { this.deleteTargetOverlay = function() {
if (this.targetOverlay === null) { if (this.targetOverlay === null) {
return; return;
} }
Overlays.deleteOverlay(this.targetOverlay); Overlays.deleteOverlay(this.targetOverlay);
this.intersection = null; this.intersection = null;
this.targetOverlay = null; this.targetOverlay = null;
@ -214,7 +237,7 @@ function Teleporter() {
var rightControllerRotation = Controller.getPoseValue(Controller.Standard.RightHand).rotation; var rightControllerRotation = Controller.getPoseValue(Controller.Standard.RightHand).rotation;
var rightRotation = Quat.multiply(MyAvatar.orientation, rightControllerRotation) var rightRotation = Quat.multiply(MyAvatar.orientation, rightControllerRotation);
var rightFinal = Quat.multiply(rightRotation, Quat.angleAxis(90, { var rightFinal = Quat.multiply(rightRotation, Quat.angleAxis(90, {
x: 1, x: 1,
@ -235,6 +258,18 @@ function Teleporter() {
var rightIntersection = Entities.findRayIntersection(teleporter.rightPickRay, true, [], [this.targetEntity]); var rightIntersection = Entities.findRayIntersection(teleporter.rightPickRay, true, [], [this.targetEntity]);
if (rightIntersection.intersects) { if (rightIntersection.intersects) {
if (this.tooClose === true) {
this.deleteTargetOverlay();
this.rightLineOn(rightPickRay.origin, rightIntersection.intersection, COLORS_TELEPORT_TOO_CLOSE);
if (this.cancelOverlay !== null) {
this.updateCancelOverlay(rightIntersection);
} else {
this.createCancelOverlay();
}
} else {
this.deleteCancelOverlay();
this.rightLineOn(rightPickRay.origin, rightIntersection.intersection, COLORS_TELEPORT_CAN_TELEPORT); this.rightLineOn(rightPickRay.origin, rightIntersection.intersection, COLORS_TELEPORT_CAN_TELEPORT);
if (this.targetOverlay !== null) { if (this.targetOverlay !== null) {
this.updateTargetOverlay(rightIntersection); this.updateTargetOverlay(rightIntersection);
@ -242,6 +277,8 @@ function Teleporter() {
this.createTargetOverlay(); this.createTargetOverlay();
} }
}
} else { } else {
this.deleteTargetOverlay(); this.deleteTargetOverlay();
@ -275,13 +312,27 @@ function Teleporter() {
if (leftIntersection.intersects) { if (leftIntersection.intersects) {
if (this.tooClose === true) {
this.deleteTargetOverlay();
this.leftLineOn(leftPickRay.origin, leftIntersection.intersection, COLORS_TELEPORT_TOO_CLOSE);
if (this.cancelOverlay !== null) {
this.updateCancelOverlay(leftIntersection);
} else {
this.createCancelOverlay();
}
} else {
this.deleteCancelOverlay();
this.leftLineOn(leftPickRay.origin, leftIntersection.intersection, COLORS_TELEPORT_CAN_TELEPORT); this.leftLineOn(leftPickRay.origin, leftIntersection.intersection, COLORS_TELEPORT_CAN_TELEPORT);
if (this.targetOverlay !== null) { if (this.targetOverlay !== null) {
this.updateTargetOverlay(leftIntersection); this.updateTargetOverlay(leftIntersection);
} else { } else {
this.createTargetOverlay(); this.createTargetOverlay();
} }
}
} else { } else {
this.deleteTargetOverlay(); this.deleteTargetOverlay();
@ -355,20 +406,44 @@ function Teleporter() {
this.updateTargetOverlay = function(intersection) { this.updateTargetOverlay = function(intersection) {
_this.intersection = intersection; _this.intersection = intersection;
var rotation = Quat.lookAt(intersection.intersection, MyAvatar.position, Vec3.UP) var rotation = Quat.lookAt(intersection.intersection, MyAvatar.position, Vec3.UP);
var euler = Quat.safeEulerAngles(rotation) var euler = Quat.safeEulerAngles(rotation);
var position = { var position = {
x: intersection.intersection.x, x: intersection.intersection.x,
y: intersection.intersection.y + TARGET_MODEL_DIMENSIONS.y / 2, y: intersection.intersection.y + TARGET_MODEL_DIMENSIONS.y / 2,
z: intersection.intersection.z z: intersection.intersection.z
} };
this.tooClose = isTooCloseToTeleport(position);
var towardUs = Quat.fromPitchYawRollDegrees(0, euler.y, 0);
Overlays.editOverlay(this.targetOverlay, { Overlays.editOverlay(this.targetOverlay, {
position: position, position: position,
rotation: Quat.fromPitchYawRollDegrees(0, euler.y, 0), rotation: towardUs
}); });
}; };
this.updateCancelOverlay = function(intersection) {
_this.intersection = intersection;
var rotation = Quat.lookAt(intersection.intersection, MyAvatar.position, Vec3.UP);
var euler = Quat.safeEulerAngles(rotation);
var position = {
x: intersection.intersection.x,
y: intersection.intersection.y + TARGET_MODEL_DIMENSIONS.y / 2,
z: intersection.intersection.z
};
this.tooClose = isTooCloseToTeleport(position);
var towardUs = Quat.fromPitchYawRollDegrees(0, euler.y, 0);
Overlays.editOverlay(this.cancelOverlay, {
position: position,
rotation: towardUs
});
};
this.disableGrab = function() { this.disableGrab = function() {
Messages.sendLocalMessage('Hifi-Hand-Disabler', this.teleportHand); Messages.sendLocalMessage('Hifi-Hand-Disabler', this.teleportHand);
}; };
@ -383,10 +458,17 @@ function Teleporter() {
}; };
this.teleport = function(value) { this.teleport = function(value) {
if (value === undefined) { if (value === undefined) {
this.exitTeleportMode(); this.exitTeleportMode();
} }
if (this.intersection !== null) { if (this.intersection !== null) {
if (this.tooClose === true) {
this.exitTeleportMode();
this.deleteCancelOverlay();
return;
}
var offset = getAvatarFootOffset(); var offset = getAvatarFootOffset();
this.intersection.intersection.y += offset; this.intersection.intersection.y += offset;
this.exitTeleportMode(); this.exitTeleportMode();
@ -394,7 +476,6 @@ function Teleporter() {
} }
}; };
this.findMidpoint = function(start, end) { this.findMidpoint = function(start, end) {
var xy = Vec3.sum(start, end); var xy = Vec3.sum(start, end);
var midpoint = Vec3.multiply(0.5, xy); var midpoint = Vec3.multiply(0.5, xy);
@ -433,13 +514,13 @@ function Teleporter() {
if (_this.arrivalPoints.length === 1 || _this.arrivalPoints.length === 0) { if (_this.arrivalPoints.length === 1 || _this.arrivalPoints.length === 0) {
_this.deleteTargetOverlay(); _this.deleteTargetOverlay();
_this.deleteCancelOverlay();
} }
}, SMOOTH_ARRIVAL_SPACING); }, SMOOTH_ARRIVAL_SPACING);
} }
} }
//related to repositioning the avatar after you teleport //related to repositioning the avatar after you teleport
function getAvatarFootOffset() { function getAvatarFootOffset() {
var data = getJointData(); var data = getJointData();
@ -505,7 +586,11 @@ function isMoving() {
} else { } else {
return false; return false;
} }
} };
function isTooCloseToTeleport(position) {
return Vec3.distance(MyAvatar.position, position) <= TELEPORT_CANCEL_RANGE;
};
function registerMappings() { function registerMappings() {
mappingName = 'Hifi-Teleporter-Dev-' + Math.random(); mappingName = 'Hifi-Teleporter-Dev-' + Math.random();
@ -559,7 +644,7 @@ function registerMappings() {
}, TELEPORT_DELAY) }, TELEPORT_DELAY)
return; return;
}); });
} };
registerMappings(); registerMappings();
@ -573,6 +658,7 @@ function cleanup() {
teleportMapping.disable(); teleportMapping.disable();
teleporter.disableMappings(); teleporter.disableMappings();
teleporter.deleteTargetOverlay(); teleporter.deleteTargetOverlay();
teleporter.deleteCancelOverlay();
teleporter.turnOffOverlayBeams(); teleporter.turnOffOverlayBeams();
if (teleporter.updateConnected !== null) { if (teleporter.updateConnected !== null) {
Script.update.disconnect(teleporter.update); Script.update.disconnect(teleporter.update);