content/hifi-content/Experiences/Releases/usefulUtilities/pushPreventer/2019-03-15_13-19-00/pushPreventer.js
2022-02-13 23:16:46 +01:00

122 lines
4.3 KiB
JavaScript

//
// pushPreventer.js
//
// Created by Zach Fox on 2019-03-15
// Copyright 2019 High Fidelity, Inc.
//
// See accompanying README.md for usage instructions.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
(function () {
var recordLocationInterval = false;
var RECORD_LOCATION_INTERVAL_MS = 1000;
var maxMovementAllowedM = 100;
var contentBoundaryCorners = [{"x": 0, "y": 0, "z": 0}, {"x": 0, "y": 0, "z": 0}];
// Returns true if a given location is within a given box
function isLocationInBox(location, cornerA, cornerB) {
return (location.x >= cornerA.x && location.y >= cornerA.y && location.z >= cornerA.z &&
location.x <= cornerB.x && location.y <= cornerB.y && location.z <= cornerB.z);
}
// 1. Gets the avatar's current location
// 2. If we've previously stored a location, and the avatar has moved more than they're allowed to,
// and they've moved outside the configurable boundaries, move the user back to the previously
// recorded location.
// 3. Records the current location as the previous location.
var previousLocation = false;
function recordLocation() {
var currentLocation = MyAvatar.position;
if (previousLocation) {
if (Vec3.distance(previousLocation, currentLocation) > maxMovementAllowedM &&
!isLocationInBox(currentLocation, contentBoundaryCorners[0], contentBoundaryCorners[1])) {
MyAvatar.position = previousLocation;
return;
}
}
previousLocation = currentLocation;
}
// A utility function used to ensure that all of the values in "box corner 1" are less than
// those in "box corner 2"
function maybeSwapCorners(dimension) {
var temp;
if (contentBoundaryCorners[0][dimension] > contentBoundaryCorners[1][dimension]) {
temp = contentBoundaryCorners[0][dimension];
contentBoundaryCorners[0][dimension] = contentBoundaryCorners[1][dimension];
contentBoundaryCorners[1][dimension] = temp;
}
}
// Ensures that all of the values in "box corner 1" are less than those in "box corner 2".
function fixupContentBoundaryCorners() {
maybeSwapCorners("x");
maybeSwapCorners("y");
maybeSwapCorners("z");
}
var PushPreventer = function() {};
PushPreventer.prototype = {
// Sets some configuration options based on `userData`, and ensures that data is valid and usable.
// Then, sets up the main logic interval.
preload: function (id) {
var properties = Entities.getEntityProperties(id, ["userData"]);
var userData;
try {
userData = JSON.parse(properties.userData);
} catch (e) {
console.error("Error parsing userData: ", e);
}
if (userData) {
if (userData.maxMovementAllowedM) {
maxMovementAllowedM = userData.maxMovementAllowedM;
}
if (userData.contentBoundaryCorner1) {
contentBoundaryCorners[0] = userData.contentBoundaryCorner1;
} else {
console.log("Please specify `contentBoundaryCorner1` inside this entity's `userData`!");
return;
}
if (userData.contentBoundaryCorner2) {
contentBoundaryCorners[1] = userData.contentBoundaryCorner2;
} else {
console.log("Please specify `contentBoundaryCorner2` inside this entity's `userData`!");
return;
}
} else {
console.log("Please specify this entity's `userData`! See README.md for instructions.");
return;
}
fixupContentBoundaryCorners();
recordLocationInterval = Script.setInterval(recordLocation, RECORD_LOCATION_INTERVAL_MS);
},
// Clears the main logic interval.
unload: function() {
if (recordLocationInterval) {
Script.clearInterval(recordLocationInterval);
recordLocationInterval = false;
}
}
};
return new PushPreventer();
});