content/hifi-public/PlanetDropBundle_v1/scripts/seatManager.js
Dale Glass 0d14e5a379 Initial data.
Needs a lot of cleanup. Data has been de-duplicated, and where identical copies existed, one of them
has been replaced with a symlink.

Some files have been excluded, such as binaries, installers and debug dumps. Some of that may still
be present.
2022-02-13 18:59:11 +01:00

349 lines
No EOL
9.5 KiB
JavaScript

//
// seatManager.js
// examples/entityScripts
//
// Created by Eric Levin on April 9, 2015
// Copyright 2015 High Fidelity, Inc.
//
// This is an example of an entity script which handles positioning and seating avatars correctly on a moving vehicle.
//
// 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 self = this;
this.preload = function(entityId) {
this.entityId = entityId;
this.buttonImageURL = "https://s3.amazonaws.com/hifi-public/images/tools/sit.svg";
this.addStandButton();
this.totalAnimationTime = 0.7;
this.targetAvatarToChairDistance = 0.5;
this.properties = Entities.getEntityProperties(this.entityId);
this.isSittingSettingHandle = "AvatarSittingState";
Settings.setValue(this.isSittingSettingHandle, false);
this.startPoseAndTransition = [];
this.forward = {
x: 0,
y: 0,
z: -1
};
this.mySeatIndex = null;
this.seatRadius = this.properties.dimensions.x * 0.4;
this.sittingAreaAngle = Math.PI;
this.numSeats = 5;
this.seatHeight = 2.0;
this.seatedPose = [{
joint: "LeftArm",
rotation: {
x: 70.0,
y: 0.0,
z: 60.0
}
}, {
joint: "LeftForeArm",
rotation: {
x: -40.0,
y: 15.0,
z: 20.0
}
}, {
joint: "RightArm",
rotation: {
x: 70.0,
y: 0.0,
z: -60.0
}
}, {
joint: "RightForeArm",
rotation: {
x: -40.0,
y: -15.0,
z: -20.0
}
}, {
joint: "RightUpLeg",
rotation: {
x: 100.0,
y: 15.0,
z: 0.0
}
}, {
joint: "RightLeg",
rotation: {
x: -120.0,
y: 80.0,
z: 0.0
}
}, {
joint: "RightFoot",
rotation: {
x: 20,
y: 5.0,
z: 0.0
}
}, {
joint: "LeftUpLeg",
rotation: {
x: 100.0,
y: -15.0,
z: 0.0
}
}, {
joint: "LeftLeg",
rotation: {
x: -150.0,
y: -70.0,
z: 0.0
}
}, {
joint: "LeftFoot",
rotation: {
x: 30,
y: 15.0,
z: 0.0
}
}];
this.storeStartPoseAndTransition();
this.getUserData();
}
this.initSeats = function() {
this.userData.seats = [];
for (var i = 0; i < this.numSeats; i++) {
this.userData.seats[i] = 0;
}
this.updateUserData();
}
//returns the index of first empty seat found in vehicle
this.assignSeat = function() {
this.getUserData();
for (var i = 0; i < this.userData.seats.length; i++) {
if (this.userData.seats[i] === 0) {
this.mySeatIndex = i;
this.userData.seats[this.mySeatIndex] = 1;
this.updateUserData();
//Now return so we don't fill up any other seat!
return;
}
}
}
this.getUserData = function() {
if (this.properties.userData) {
this.userData = JSON.parse(this.properties.userData);
} else {
this.userData = {};
}
if (!this.userData.seats) {
this.initSeats();
}
}
this.updateUserData = function() {
Entities.editEntity(this.entityId, {
userData: JSON.stringify(this.userData)
});
}
this.addStandButton = function() {
this.windowDimensions = Controller.getViewportDimensions();
this.buttonWidth = 37;
this.buttonHeight = 46;
this.buttonPadding = 10;
this.buttonPositionX = (this.windowDimensions.x - this.buttonPadding) / 2 - this.buttonWidth;
this.buttonPositionY = (this.windowDimensions.y - this.buttonHeight) - (this.buttonHeight + this.buttonPadding);
this.standUpButton = Overlays.addOverlay("image", {
x: this.buttonPositionX,
y: this.buttonPositionY,
width: this.buttonWidth,
height: this.buttonHeight,
subImage: {
x: this.buttonWidth,
y: this.buttonHeight,
width: this.buttonWidth,
height: this.buttonHeight
},
imageURL: this.buttonImageURL,
visible: false,
alpha: 1.0
});
}
this.storeStartPoseAndTransition = function() {
for (var i = 0; i < this.seatedPose.length; i++) {
var startRotation = Quat.safeEulerAngles(MyAvatar.getJointRotation(this.seatedPose[i].joint));
var transitionVector = Vec3.subtract(this.seatedPose[i].rotation, startRotation);
this.startPoseAndTransition.push({
joint: this.seatedPose[i].joint,
start: startRotation,
transition: transitionVector
});
}
}
this.clickReleaseOnEntity = function(entityId, mouseEvent) {
var isStanding = false;
if(Settings.getValue(this.isSittingSettingHandle, false) === false){
isStanding = true;
}
if (mouseEvent.isLeftButton && isStanding) {
this.initMoveToSeat();
}
}
this.initMoveToSeat = function() {
this.assignSeat();
if (this.mySeatIndex !== null) {
this.seatTheta = -this.mySeatIndex / this.numSeats * this.sittingAreaAngle;
//first we need to move avatar towards seat
this.activeUpdate = this.moveToSeat;
} else {
print("NO SEAT AVAILABLE AT THIS TIME *************************");
}
}
this.update = function(deltaTime) {
if (self.entityId) {
self.properties = Entities.getEntityProperties(self.entityId);
//need to always update seat so when user clicks on it it is in proper world space
var xPos = self.properties.position.x + (Math.cos(self.seatTheta) * self.seatRadius);
var zPos = self.properties.position.z + (Math.sin(self.seatTheta) * self.seatRadius);
self.seatPosition = {
x: xPos,
y: self.properties.position.y + self.seatHeight,
z: zPos
};
}
if (!self.activeUpdate) {
return;
}
self.activeUpdate(deltaTime);
}
this.moveToSeat = function(deltaTime) {
self.distance = Vec3.distance(MyAvatar.position, self.seatPosition);
if (self.distance > self.targetAvatarToChairDistance) {
self.sanitizedRotation = Quat.fromPitchYawRollDegrees(0, Quat.safeEulerAngles(self.properties.rotation).y, 0);
MyAvatar.orientation = Quat.mix(MyAvatar.orientation, self.sanitizedRotation, 0.02);
MyAvatar.position = Vec3.mix(MyAvatar.position, self.seatPosition, 0.05);
} else {
//otherwise we made it to chair, now sit down should be out active update function
this.elapsedTime = 0
self.activeUpdate = self.sitDown;
}
}
this.sitDown = function(deltaTime) {
self.elapsedTime += deltaTime;
self.factor = self.elapsedTime / self.totalAnimationTime;
if (self.elapsedTime < self.totalAnimationTime) {
self.updateJoints();
} else {
//We've sat, now we don't need to update any longer;
self.activeUpdate = null;
Settings.setValue(self.isSittingSettingHandle, true);
Overlays.editOverlay(self.standUpButton, {
visible: true
});
MyAvatar.setModelReferential(self.properties.id);
}
}
this.standUp = function(deltaTime) {
self.elapsedTime += deltaTime;
self.factor = 1 - self.elapsedTime / self.totalAnimationTime;
if (self.elapsedTime < self.totalAnimationTime) {
self.updateJoints();
} else {
//We're done with standing animation
self.activeUpdate = null;
Settings.setValue(this.isSittingSettingHandle, false);
//We just finished a standup after deleting the entity the avatar was sitting on
if (self.disconnectAfterStanding) {
Overlays.deleteOverlay(this.standUpButton);
Script.update.disconnect(self.update);
}
//make sure we set avatar head yaw back to 0.
MyAvatar.headYaw = 0
this.userData.seats[this.mySeatIndex] = 0;
this.mySeatIndex = null;
this.updateUserData();
//make sure we free up this seat
this.clearAvatarAnimation();
}
}
self.updateJoints = function() {
for (var i = 0; i < self.startPoseAndTransition.length; i++) {
self.scaledTransition = Vec3.multiply(self.startPoseAndTransition[i].transition, self.factor);
self.jointRotation = Vec3.sum(self.startPoseAndTransition[i].start, self.scaledTransition);
MyAvatar.setJointData(self.startPoseAndTransition[i].joint, Quat.fromVec3Degrees(self.jointRotation));
}
}
this.clearAvatarAnimation = function() {
MyAvatar.clearReferential();
for (var i = 0; i < self.seatedPose.length; i++) {
print('YAAAAAA')
MyAvatar.clearJointData(this.seatedPose[i].joint);
}
Overlays.editOverlay(this.standUpButton, {
visible: false
};);
}
this.unload = function() {
var isSitting = Settings.getValue(this.isSittingSettingHandle)
this.entityId = null;
if (isSitting === "true") {
// We need to let avatar stand before disconnecting, and then end
this.initStandUp();
this.disconnectAfterStanding = true;
this.activeUpdate = this.standUp
} else {
this.clearAvatarAnimation();
Script.update.disconnect(this.update);
}
}
this.onClick = function(event) {
var clickedOverlay = Overlays.getOverlayAtPoint({
x: event.x,
y: event.y
});
if (clickedOverlay === self.standUpButton) {
self.initStandUp();
}
}
this.initStandUp = function() {
this.elapsedTime = 0;
this.activeUpdate = this.standUp;
MyAvatar.clearReferential();
Overlays.editOverlay(self.standUpButton, {
visible: false
};);
}
function map(value, min1, max1, min2, max2) {
return min2 + (max2 - min2) * ((value - min1) / (max1 - min1));
}
Controller.mousePressEvent.connect(this.onClick);
Script.update.connect(this.update);
});