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.
372 lines
No EOL
14 KiB
JavaScript
372 lines
No EOL
14 KiB
JavaScript
//
|
|
// sitOnEntity.js
|
|
// examples/entityScripts
|
|
//
|
|
// Created by Brad Hefta-Gaub on 11/1/14.
|
|
// Copyright 2014 High Fidelity, Inc.
|
|
//
|
|
// This is an example of an entity script for sitting.
|
|
//
|
|
// Distributed under the Apache License, Version 2.0.
|
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
|
//
|
|
|
|
(function(){
|
|
|
|
this.entityID = null;
|
|
this.properties = null;
|
|
this.standUpButton = null;
|
|
this.indicatorsAdded = false;
|
|
this.indicator = new Array();
|
|
|
|
|
|
var buttonImageUrl = "https://worklist-prod.s3.amazonaws.com/attachment/0aca88e1-9bd8-5c1d.svg";
|
|
var windowDimensions = Controller.getViewportDimensions();
|
|
var buttonWidth = 37;
|
|
var buttonHeight = 46;
|
|
var buttonPadding = 50; // inside the normal toolbar position
|
|
var buttonPositionX = windowDimensions.x - buttonPadding - buttonWidth;
|
|
var buttonPositionY = (windowDimensions.y - buttonHeight) / 2 - (buttonHeight + buttonPadding);
|
|
|
|
var passedTime = 0.0;
|
|
var startPosition = null;
|
|
var startRotation = null;
|
|
var animationLenght = 2.0;
|
|
|
|
var avatarOldPosition = { x: 0, y: 0, z: 0 };
|
|
|
|
var sittingSettingsHandle = "SitJsSittingPosition";
|
|
var sitting = Settings.getValue(sittingSettingsHandle, false) == "true";
|
|
print("Original sitting status: " + sitting);
|
|
var frame = 0;
|
|
|
|
var seat = new Object();
|
|
var hiddingSeats = false;
|
|
|
|
// This is the pose we would like to end up
|
|
var pose = [
|
|
{joint:"RightUpLeg", rotation: {x:100.0, y:15.0, z:0.0}},
|
|
{joint:"RightLeg", rotation: {x:-130.0, y:15.0, z:0.0}},
|
|
{joint:"RightFoot", rotation: {x:30, y:15.0, z:0.0}},
|
|
{joint:"LeftUpLeg", rotation: {x:100.0, y:-15.0, z:0.0}},
|
|
{joint:"LeftLeg", rotation: {x:-130.0, y:-15.0, z:0.0}},
|
|
{joint:"LeftFoot", rotation: {x:30, y:15.0, z:0.0}}
|
|
];
|
|
|
|
var startPoseAndTransition = [];
|
|
|
|
function storeStartPoseAndTransition() {
|
|
for (var i = 0; i < pose.length; i++){
|
|
var startRotation = Quat.safeEulerAngles(MyAvatar.getJointRotation(pose[i].joint));
|
|
var transitionVector = Vec3.subtract( pose[i].rotation, startRotation );
|
|
startPoseAndTransition.push({joint: pose[i].joint, start: startRotation, transition: transitionVector});
|
|
}
|
|
}
|
|
|
|
function updateJoints(factor){
|
|
for (var i = 0; i < startPoseAndTransition.length; i++){
|
|
var scaledTransition = Vec3.multiply(startPoseAndTransition[i].transition, factor);
|
|
var rotation = Vec3.sum(startPoseAndTransition[i].start, scaledTransition);
|
|
MyAvatar.setJointData(startPoseAndTransition[i].joint, Quat.fromVec3Degrees( rotation ));
|
|
}
|
|
}
|
|
|
|
var sittingDownAnimation = function(deltaTime) {
|
|
|
|
passedTime += deltaTime;
|
|
var factor = passedTime/animationLenght;
|
|
|
|
if ( passedTime <= animationLenght ) {
|
|
updateJoints(factor);
|
|
|
|
var pos = { x: startPosition.x - 0.3 * factor, y: startPosition.y - 0.5 * factor, z: startPosition.z};
|
|
MyAvatar.position = pos;
|
|
} else {
|
|
Script.update.disconnect(sittingDownAnimation);
|
|
if (seat.model) {
|
|
MyAvatar.setModelReferential(seat.model.id);
|
|
}
|
|
}
|
|
}
|
|
|
|
var standingUpAnimation = function(deltaTime) {
|
|
|
|
passedTime += deltaTime;
|
|
var factor = 1 - passedTime/animationLenght;
|
|
|
|
if ( passedTime <= animationLenght ) {
|
|
|
|
updateJoints(factor);
|
|
|
|
var pos = { x: startPosition.x + 0.3 * (passedTime/animationLenght), y: startPosition.y + 0.5 * (passedTime/animationLenght), z: startPosition.z};
|
|
MyAvatar.position = pos;
|
|
} else {
|
|
Script.update.disconnect(standingUpAnimation);
|
|
|
|
}
|
|
}
|
|
|
|
var externalThis = this;
|
|
|
|
var goToSeatAnimation = function(deltaTime) {
|
|
passedTime += deltaTime;
|
|
var factor = passedTime/animationLenght;
|
|
|
|
if (passedTime <= animationLenght) {
|
|
var targetPosition = Vec3.sum(seat.position, { x: 0.3, y: 0.5, z: 0 });
|
|
MyAvatar.position = Vec3.sum(Vec3.multiply(startPosition, 1 - factor), Vec3.multiply(targetPosition, factor));
|
|
} else if (passedTime <= 2 * animationLenght) {
|
|
//Quat.print("MyAvatar: ", MyAvatar.orientation);
|
|
//Quat.print("Seat: ", seat.rotation);
|
|
MyAvatar.orientation = Quat.mix(startRotation, seat.rotation, factor - 1);
|
|
} else {
|
|
Script.update.disconnect(goToSeatAnimation);
|
|
externalThis.sitDown();
|
|
externalThis.showIndicators(false);
|
|
}
|
|
}
|
|
|
|
var globalMouseClick = function(event) {
|
|
var clickedOverlay = Overlays.getOverlayAtPoint({x: event.x, y: event.y});
|
|
if (clickedOverlay == externalThis.standUpButton) {
|
|
seat.model = null;
|
|
externalThis.standUp();
|
|
Controller.mousePressEvent.disconnect(globalMouseClick);
|
|
}
|
|
};
|
|
|
|
this.sitDown = function() {
|
|
sitting = true;
|
|
Settings.setValue(sittingSettingsHandle, sitting);
|
|
print("sitDown sitting status: " + Settings.getValue(sittingSettingsHandle, false));
|
|
passedTime = 0.0;
|
|
startPosition = MyAvatar.position;
|
|
storeStartPoseAndTransition();
|
|
try {
|
|
Script.update.disconnect(standingUpAnimation);
|
|
} catch(e){
|
|
// no need to handle. if it wasn't connected no harm done
|
|
}
|
|
Script.update.connect(sittingDownAnimation);
|
|
Overlays.editOverlay(this.standUpButton, { visible: true });
|
|
Controller.mousePressEvent.connect(globalMouseClick);
|
|
}
|
|
|
|
this.standUp = function() {
|
|
sitting = false;
|
|
Settings.setValue(sittingSettingsHandle, sitting);
|
|
print("standUp sitting status: " + Settings.getValue(sittingSettingsHandle, false));
|
|
passedTime = 0.0;
|
|
startPosition = MyAvatar.position;
|
|
MyAvatar.clearReferential();
|
|
try{
|
|
Script.update.disconnect(sittingDownAnimation);
|
|
} catch (e){}
|
|
Script.update.connect(standingUpAnimation);
|
|
Overlays.editOverlay(this.standUpButton, { visible: false });
|
|
Controller.mousePressEvent.disconnect(globalMouseClick);
|
|
}
|
|
|
|
function SeatIndicator(modelProperties, seatIndex) {
|
|
var halfDiagonal = Vec3.length(modelProperties.dimensions) / 2.0;
|
|
|
|
this.position = Vec3.sum(modelProperties.position,
|
|
Vec3.multiply(Vec3.multiplyQbyV(modelProperties.rotation, modelProperties.sittingPoints[seatIndex].position),
|
|
halfDiagonal)); // hack
|
|
|
|
this.orientation = Quat.multiply(modelProperties.rotation,
|
|
modelProperties.sittingPoints[seatIndex].rotation);
|
|
this.scale = MyAvatar.scale / 3;
|
|
|
|
this.sphere = Overlays.addOverlay("billboard", {
|
|
subImage: { x: 0, y: buttonHeight, width: buttonWidth, height: buttonHeight},
|
|
url: buttonImageUrl,
|
|
position: this.position,
|
|
scale: this.scale,
|
|
size: this.scale,
|
|
solid: true,
|
|
color: { red: 255, green: 255, blue: 255 },
|
|
alpha: 0.8,
|
|
visible: true,
|
|
isFacingAvatar: true
|
|
});
|
|
|
|
this.show = function(doShow) {
|
|
Overlays.editOverlay(this.sphere, { visible: doShow });
|
|
}
|
|
|
|
this.update = function() {
|
|
Overlays.editOverlay(this.sphere, {
|
|
position: this.position,
|
|
size: this.scale
|
|
});
|
|
}
|
|
|
|
this.cleanup = function() {
|
|
Overlays.deleteOverlay(this.sphere);
|
|
}
|
|
}
|
|
|
|
function update(deltaTime){
|
|
var newWindowDimensions = Controller.getViewportDimensions();
|
|
if( newWindowDimensions.x != windowDimensions.x || newWindowDimensions.y != windowDimensions.y ){
|
|
windowDimensions = newWindowDimensions;
|
|
var newX = windowDimensions.x - buttonPadding - buttonWidth;
|
|
var newY = (windowDimensions.y - buttonHeight) / 2 ;
|
|
Overlays.editOverlay( this.standUpButton, {x: newX, y: newY} );
|
|
}
|
|
|
|
// For a weird reason avatar joint don't update till the 10th frame
|
|
// Set the update frame to 20 to be safe
|
|
var UPDATE_FRAME = 20;
|
|
if (frame <= UPDATE_FRAME) {
|
|
if (frame == UPDATE_FRAME) {
|
|
if (sitting == true) {
|
|
print("Was seated: " + sitting);
|
|
storeStartPoseAndTransition();
|
|
updateJoints(1.0);
|
|
}
|
|
}
|
|
frame++;
|
|
}
|
|
}
|
|
|
|
this.addIndicators = function() {
|
|
if (!this.indicatorsAdded) {
|
|
if (this.properties.sittingPoints.length > 0) {
|
|
for (var i = 0; i < this.properties.sittingPoints.length; ++i) {
|
|
this.indicator[i] = new SeatIndicator(this.properties, i);
|
|
}
|
|
this.indicatorsAdded = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
this.removeIndicators = function() {
|
|
for (var i = 0; i < this.properties.sittingPoints.length; ++i) {
|
|
this.indicator[i].cleanup();
|
|
}
|
|
}
|
|
|
|
this.showIndicators = function(doShow) {
|
|
this.addIndicators();
|
|
if (this.indicatorsAdded) {
|
|
for (var i = 0; i < this.properties.sittingPoints.length; ++i) {
|
|
this.indicator[i].show(doShow);
|
|
}
|
|
}
|
|
hiddingSeats = !doShow;
|
|
}
|
|
|
|
function raySphereIntersection(origin, direction, center, radius) {
|
|
var A = origin;
|
|
var B = Vec3.normalize(direction);
|
|
var P = center;
|
|
|
|
var x = Vec3.dot(Vec3.subtract(P, A), B);
|
|
var X = Vec3.sum(A, Vec3.multiply(B, x));
|
|
var d = Vec3.length(Vec3.subtract(P, X));
|
|
|
|
return (x > 0 && d <= radius);
|
|
}
|
|
|
|
this.cleanup = function() {
|
|
this.standUp();
|
|
MyAvatar.clearReferential();
|
|
for (var i = 0; i < pose.length; i++){
|
|
MyAvatar.clearJointData(pose[i].joint);
|
|
}
|
|
Overlays.deleteOverlay(this.standUpButton);
|
|
for (var i = 0; i < this.indicator.length; ++i) {
|
|
this.indicator[i].cleanup();
|
|
}
|
|
};
|
|
|
|
|
|
this.createStandupButton = function() {
|
|
this.standUpButton = Overlays.addOverlay("image", {
|
|
x: buttonPositionX, y: buttonPositionY, width: buttonWidth, height: buttonHeight,
|
|
subImage: { x: buttonWidth, y: buttonHeight, width: buttonWidth, height: buttonHeight},
|
|
imageURL: buttonImageUrl,
|
|
visible: false,
|
|
alpha: 1.0
|
|
});
|
|
};
|
|
|
|
this.handleClickEvent = function(event) {
|
|
var clickedOverlay = Overlays.getOverlayAtPoint({x: event.x, y: event.y});
|
|
|
|
if (clickedOverlay == this.standUpButton) {
|
|
seat.model = null;
|
|
this.standUp();
|
|
} else {
|
|
this.addIndicators();
|
|
if (this.indicatorsAdded) {
|
|
var pickRay = Camera.computePickRay(event.x, event.y);
|
|
|
|
var clickedOnSeat = false;
|
|
|
|
for (var i = 0; i < this.properties.sittingPoints.length; ++i) {
|
|
if (raySphereIntersection(pickRay.origin,
|
|
pickRay.direction,
|
|
this.indicator[i].position,
|
|
this.indicator[i].scale / 2)) {
|
|
clickedOnSeat = true;
|
|
seat.model = this.entityID; // ??
|
|
seat.position = this.indicator[i].position;
|
|
seat.rotation = this.indicator[i].orientation;
|
|
}
|
|
}
|
|
|
|
if (clickedOnSeat) {
|
|
passedTime = 0.0;
|
|
startPosition = MyAvatar.position;
|
|
startRotation = MyAvatar.orientation;
|
|
try{ Script.update.disconnect(standingUpAnimation); } catch(e){}
|
|
try{ Script.update.disconnect(sittingDownAnimation); } catch(e){}
|
|
Script.update.connect(goToSeatAnimation);
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
|
|
// All callbacks start by updating the properties
|
|
this.updateProperties = function(entityID) {
|
|
if (this.entityID === null || !this.entityID.isKnownID) {
|
|
this.entityID = Entities.identifyEntity(entityID);
|
|
}
|
|
this.properties = Entities.getEntityProperties(this.entityID);
|
|
};
|
|
|
|
this.unload = function(entityID) {
|
|
this.cleanup();
|
|
Script.update.disconnect(update);
|
|
};
|
|
|
|
this.preload = function(entityID) {
|
|
this.updateProperties(entityID); // All callbacks start by updating the properties
|
|
this.createStandupButton();
|
|
Script.update.connect(update);
|
|
};
|
|
|
|
|
|
this.hoverOverEntity = function(entityID, mouseEvent) {
|
|
this.updateProperties(entityID); // All callbacks start by updating the properties
|
|
this.showIndicators(true);
|
|
};
|
|
this.hoverLeaveEntity = function(entityID, mouseEvent) {
|
|
this.updateProperties(entityID); // All callbacks start by updating the properties
|
|
this.showIndicators(false);
|
|
};
|
|
|
|
this.clickDownOnEntity = function(entityID, mouseEvent) {
|
|
this.updateProperties(entityID); // All callbacks start by updating the properties
|
|
this.handleClickEvent(mouseEvent);
|
|
};
|
|
|
|
this.clickReleaseOnEntity = function(entityID, mouseEvent) {
|
|
this.updateProperties(entityID); // All callbacks start by updating the properties
|
|
};
|
|
|
|
}) |