mirror of
https://github.com/lubosz/overte.git
synced 2025-04-06 00:22:25 +02:00
415 lines
15 KiB
JavaScript
415 lines
15 KiB
JavaScript
//
|
|
// playbackMaster.js
|
|
// acScripts
|
|
//
|
|
// Created by Edgar Pironti on 11/17/15.
|
|
// Copyright 2015 High Fidelity, Inc.
|
|
//
|
|
// Distributed under the Apache License, Version 2.0.
|
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
|
//
|
|
Script.include("./AgentPoolController.js");
|
|
|
|
var masterController = new MasterController();
|
|
|
|
var input_text = null;
|
|
|
|
// Script. DO NOT MODIFY BEYOND THIS LINE.
|
|
//Script.include("../libraries/toolBars.js");
|
|
Script.include(Script.getExternalPath(Script.ExternalPaths.Assets, "scripts/libraries/toolBars.js"));
|
|
// We want small icons
|
|
Tool.IMAGE_HEIGHT /= 2;
|
|
Tool.IMAGE_WIDTH /= 2;
|
|
|
|
var PLAY = 1;
|
|
var PLAY_LOOP = 2;
|
|
var STOP = 3;
|
|
var LOAD = 6;
|
|
|
|
var windowDimensions = Controller.getViewportDimensions();
|
|
var TOOL_ICON_URL = Script.getExternalPath(Script.ExternalPaths.Assets, "images/tools/");
|
|
var ALPHA_ON = 1.0;
|
|
var ALPHA_OFF = 0.7;
|
|
var COLOR_TOOL_BAR = { red: 0, green: 0, blue: 0 };
|
|
var COLOR_MASTER = { red: 0, green: 0, blue: 0 };
|
|
var TEXT_HEIGHT = 12;
|
|
var TEXT_MARGIN = 3;
|
|
|
|
// Add new features to Actor class:
|
|
Actor.prototype.destroy = function() {
|
|
print("Actor.prototype.destroy");
|
|
print("Need to fire myself" + this.agentID);
|
|
masterController.fireAgent(this);
|
|
}
|
|
|
|
|
|
Actor.prototype.resetClip = function(clipURL, onLoadClip) {
|
|
this.clipURL = clipURL;
|
|
this.onLoadClip = onLoadClip;
|
|
if (this.isConnected()) {
|
|
this.onLoadClip(this);
|
|
}
|
|
}
|
|
|
|
|
|
Actor.prototype.onMousePressEvent = function(clickedOverlay) {
|
|
if (this.playIcon === this.toolbar.clicked(clickedOverlay, false)) {
|
|
masterController.sendCommand(this.agentID, PLAY);
|
|
} else if (this.playLoopIcon === this.toolbar.clicked(clickedOverlay, false)) {
|
|
masterController.sendCommand(this.agentID, PLAY_LOOP);
|
|
} else if (this.stopIcon === this.toolbar.clicked(clickedOverlay, false)) {
|
|
masterController.sendCommand(this.agentID, STOP);
|
|
} else if (this.nameOverlay === clickedOverlay) {
|
|
print("Actor: " + JSON.stringify(this));
|
|
} else {
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
Actor.prototype._buildUI = function() {
|
|
print("Actor.prototype._buildUI = " + JSON.stringify(this));
|
|
|
|
this.toolbar = new ToolBar(0, 0, ToolBar.HORIZONTAL);
|
|
|
|
this.toolbar.setBack(COLOR_TOOL_BAR, ALPHA_OFF);
|
|
|
|
this.playIcon = this.toolbar.addTool({
|
|
imageURL: TOOL_ICON_URL + "play.svg",
|
|
subImage: { x: 0, y: 0, width: Tool.IMAGE_WIDTH, height: Tool.IMAGE_HEIGHT },
|
|
width: Tool.IMAGE_WIDTH,
|
|
height: Tool.IMAGE_HEIGHT,
|
|
alpha: ALPHA_OFF,
|
|
visible: true
|
|
}, false);
|
|
|
|
var playLoopWidthFthis = 1.65;
|
|
this.playLoopIcon = this.toolbar.addTool({
|
|
imageURL: TOOL_ICON_URL + "play-and-loop.svg",
|
|
subImage: { x: 0, y: 0, width: playLoopWidthFthis * Tool.IMAGE_WIDTH, height: Tool.IMAGE_HEIGHT },
|
|
width: playLoopWidthFthis * Tool.IMAGE_WIDTH,
|
|
height: Tool.IMAGE_HEIGHT,
|
|
alpha: ALPHA_OFF,
|
|
visible: true
|
|
}, false);
|
|
|
|
this.stopIcon = this.toolbar.addTool({
|
|
imageURL: TOOL_ICON_URL + "recording-stop.svg",
|
|
width: Tool.IMAGE_WIDTH,
|
|
height: Tool.IMAGE_HEIGHT,
|
|
alpha: ALPHA_OFF,
|
|
visible: true
|
|
}, false);
|
|
|
|
this.nameOverlay = Overlays.addOverlay("text", {
|
|
backgroundColor: { red: 0, green: 0, blue: 0 },
|
|
font: { size: TEXT_HEIGHT },
|
|
text: "AC offline",
|
|
x: 0, y: 0,
|
|
width: this.toolbar.width + ToolBar.SPACING,
|
|
height: TEXT_HEIGHT + TEXT_MARGIN,
|
|
leftMargin: TEXT_MARGIN,
|
|
topMargin: TEXT_MARGIN,
|
|
alpha: ALPHA_OFF,
|
|
backgroundAlpha: ALPHA_OFF,
|
|
visible: true
|
|
});
|
|
}
|
|
|
|
Actor.prototype._destroyUI = function() {
|
|
this.toolbar.cleanup();
|
|
Overlays.deleteOverlay(this.nameOverlay);
|
|
}
|
|
|
|
Actor.prototype.moveUI = function(pos) {
|
|
var textSize = TEXT_HEIGHT + 2 * TEXT_MARGIN;
|
|
this.toolbar.move(pos.x, pos.y);
|
|
|
|
Overlays.editOverlay(this.nameOverlay, {
|
|
x: this.toolbar.x - ToolBar.SPACING,
|
|
y: this.toolbar.y - textSize
|
|
});
|
|
}
|
|
|
|
Director = function() {
|
|
this.actors = new Array();
|
|
this.toolbar = null;
|
|
this._buildUI();
|
|
this.requestPerformanceLoad = false;
|
|
this.performanceURL = "";
|
|
};
|
|
|
|
Director.prototype.destroy = function () {
|
|
print("Director.prototype.destroy")
|
|
this.clearActors();
|
|
this.toolbar.cleanup();
|
|
Overlays.deleteOverlay(this.nameOverlay);
|
|
}
|
|
|
|
Director.prototype.clearActors = function () {
|
|
print("Director.prototype.clearActors")
|
|
while (this.actors.length > 0) {
|
|
this.actors.pop().destroy();
|
|
}
|
|
|
|
this.actors = new Array();// Brand new actors
|
|
}
|
|
|
|
Director.prototype._buildUI = function () {
|
|
this.toolbar = new ToolBar(0, 0, ToolBar.HORIZONTAL);
|
|
|
|
this.toolbar.setBack(COLOR_MASTER, ALPHA_OFF);
|
|
|
|
this.onOffIcon = this.toolbar.addTool({
|
|
imageURL: TOOL_ICON_URL + "ac-on-off.svg",
|
|
subImage: { x: 0, y: 0, width: Tool.IMAGE_WIDTH, height: Tool.IMAGE_HEIGHT },
|
|
x: 0, y: 0,
|
|
width: Tool.IMAGE_WIDTH,
|
|
height: Tool.IMAGE_HEIGHT,
|
|
alpha: ALPHA_ON,
|
|
visible: true
|
|
}, true, true);
|
|
|
|
this.playIcon = this.toolbar.addTool({
|
|
imageURL: TOOL_ICON_URL + "play.svg",
|
|
subImage: { x: 0, y: 0, width: Tool.IMAGE_WIDTH, height: Tool.IMAGE_HEIGHT },
|
|
width: Tool.IMAGE_WIDTH,
|
|
height: Tool.IMAGE_HEIGHT,
|
|
alpha: ALPHA_OFF,
|
|
visible: true
|
|
}, false);
|
|
|
|
var playLoopWidthFthis = 1.65;
|
|
this.playLoopIcon = this.toolbar.addTool({
|
|
imageURL: TOOL_ICON_URL + "play-and-loop.svg",
|
|
subImage: { x: 0, y: 0, width: playLoopWidthFthis * Tool.IMAGE_WIDTH, height: Tool.IMAGE_HEIGHT },
|
|
width: playLoopWidthFthis * Tool.IMAGE_WIDTH,
|
|
height: Tool.IMAGE_HEIGHT,
|
|
alpha: ALPHA_OFF,
|
|
visible: true
|
|
}, false);
|
|
|
|
this.stopIcon = this.toolbar.addTool({
|
|
imageURL: TOOL_ICON_URL + "recording-stop.svg",
|
|
width: Tool.IMAGE_WIDTH,
|
|
height: Tool.IMAGE_HEIGHT,
|
|
alpha: ALPHA_OFF,
|
|
visible: true
|
|
}, false);
|
|
|
|
this.loadIcon = this.toolbar.addTool({
|
|
imageURL: TOOL_ICON_URL + "recording-upload.svg",
|
|
width: Tool.IMAGE_WIDTH,
|
|
height: Tool.IMAGE_HEIGHT,
|
|
alpha: ALPHA_OFF,
|
|
visible: true
|
|
}, false);
|
|
|
|
this.nameOverlay = Overlays.addOverlay("text", {
|
|
backgroundColor: { red: 0, green: 0, blue: 0 },
|
|
font: { size: TEXT_HEIGHT },
|
|
text: "Master",
|
|
x: 0, y: 0,
|
|
width: this.toolbar.width + ToolBar.SPACING,
|
|
height: TEXT_HEIGHT + TEXT_MARGIN,
|
|
leftMargin: TEXT_MARGIN,
|
|
topMargin: TEXT_MARGIN,
|
|
alpha: ALPHA_OFF,
|
|
backgroundAlpha: ALPHA_OFF,
|
|
visible: true
|
|
});
|
|
}
|
|
|
|
Director.prototype.onMousePressEvent = function(clickedOverlay) {
|
|
if (this.playIcon === this.toolbar.clicked(clickedOverlay, false)) {
|
|
print("master play");
|
|
masterController.sendCommand(BROADCAST_AGENTS, PLAY);
|
|
} else if (this.onOffIcon === this.toolbar.clicked(clickedOverlay, false)) {
|
|
this.clearActors();
|
|
return true;
|
|
} else if (this.playLoopIcon === this.toolbar.clicked(clickedOverlay, false)) {
|
|
masterController.sendCommand(BROADCAST_AGENTS, PLAY_LOOP);
|
|
} else if (this.stopIcon === this.toolbar.clicked(clickedOverlay, false)) {
|
|
masterController.sendCommand(BROADCAST_AGENTS, STOP);
|
|
} else if (this.loadIcon === this.toolbar.clicked(clickedOverlay, false)) {
|
|
input_text = Window.prompt("Insert the url of the clip: ","");
|
|
if (!(input_text === "" || input_text === null)) {
|
|
print("Performance file ready to be loaded url = " + input_text);
|
|
this.requestPerformanceLoad = true;
|
|
this.performanceURL = input_text;
|
|
}
|
|
} else if (this.nameOverlay === clickedOverlay) {
|
|
print("Director: " + JSON.stringify(this));
|
|
} else {
|
|
// Check individual controls
|
|
for (var i = 0; i < this.actors.length; i++) {
|
|
if (this.actors[i].onMousePressEvent(clickedOverlay)) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false; // nothing clicked from our known overlays
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
Director.prototype.moveUI = function(pos) {
|
|
var textSize = TEXT_HEIGHT + 2 * TEXT_MARGIN;
|
|
var relative = { x: pos.x, y: pos.y + (this.actors.length + 1) * (Tool.IMAGE_HEIGHT + ToolBar.SPACING + textSize) };
|
|
|
|
this.toolbar.move(relative.x, windowDimensions.y - relative.y);
|
|
Overlays.editOverlay(this.nameOverlay, {
|
|
x: this.toolbar.x - ToolBar.SPACING,
|
|
y: this.toolbar.y - textSize
|
|
});
|
|
|
|
for (var i = 0; i < this.actors.length; i++) {
|
|
this.actors[i].moveUI({x: relative.x, y: windowDimensions.y - relative.y +
|
|
(i + 1) * (Tool.IMAGE_HEIGHT + ToolBar.SPACING + textSize)});
|
|
}
|
|
}
|
|
|
|
|
|
Director.prototype.reloadPerformance = function() {
|
|
this.requestPerformanceLoad = false;
|
|
|
|
if (this.performanceURL[0] == '{') {
|
|
var jsonPerformance = JSON.parse(this.performanceURL);
|
|
this.onPerformanceLoaded(jsonPerformance);
|
|
} else {
|
|
|
|
var urlpartition = this.performanceURL.split(".");
|
|
print(urlpartition[0]);
|
|
print(urlpartition[1]);
|
|
|
|
if ((urlpartition.length > 1) && (urlpartition[urlpartition.length - 1] === "hfr")) {
|
|
print("detected a unique clip url");
|
|
var oneClipPerformance = new Object();
|
|
oneClipPerformance.avatarClips = new Array();
|
|
oneClipPerformance.avatarClips[0] = input_text;
|
|
|
|
print(JSON.stringify(oneClipPerformance));
|
|
|
|
// we make a local simple performance file with a single clip and pipe in directly
|
|
this.onPerformanceLoaded(oneClipPerformance);
|
|
return true;
|
|
} else {
|
|
// FIXME: I cannot pass directly this.onPerformanceLoaded, is that exepected ?
|
|
var localThis = this;
|
|
Assets.downloadData(input_text, function(data) { localThis.onPerformanceLoaded(JSON.parse(data)); });
|
|
}
|
|
}
|
|
}
|
|
|
|
Director.prototype.onPerformanceLoaded = function(performanceJSON) {
|
|
// First fire all the current actors
|
|
this.clearActors();
|
|
|
|
print("Director.prototype.onPerformanceLoaded = " + JSON.stringify(performanceJSON));
|
|
if (performanceJSON.avatarClips != null) {
|
|
var numClips = performanceJSON.avatarClips.length;
|
|
print("Found " + numClips + "in the performance file, and currently using " + this.actors.length + " actor(s)");
|
|
|
|
for (var i = 0; i < numClips; i++) {
|
|
this.hireActor(performanceJSON.avatarClips[i]);
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
|
|
Director.prototype.hireActor = function(clipURL) {
|
|
print("new actor = " + this.actors.length );
|
|
var newActor = new Actor();
|
|
newActor.clipURL = null;
|
|
newActor.onLoadClip = function(clip) {};
|
|
|
|
var localThis = this;
|
|
newActor.onHired = function(actor) {
|
|
print("agent hired from Director! " + actor.agentID)
|
|
Overlays.editOverlay(actor.nameOverlay, {
|
|
text: "AC " + actor.agentID,
|
|
backgroundColor: { red: 0, green: 255, blue: 0 }
|
|
});
|
|
|
|
if (actor.clipURL != null) {
|
|
print("agent hired, calling load clip for url " + actor.clipURL);
|
|
actor.onLoadClip(actor);
|
|
}
|
|
};
|
|
|
|
newActor.onFired = function(actor) {
|
|
print("agent fired from playbackMaster! " + actor.agentID);
|
|
var index = localThis.actors.indexOf(actor);
|
|
if (index >= 0) {
|
|
localThis.actors.splice(index, 1);
|
|
}
|
|
|
|
actor._destroyUI();
|
|
|
|
actor.destroy();
|
|
moveUI();
|
|
}
|
|
|
|
newActor.resetClip(clipURL, function(actor) {
|
|
print("Load clip for agent" + actor.agentID + " calling load clip for url " + actor.clipURL);
|
|
masterController.sendCommand(actor.agentID, LOAD, actor.clipURL);
|
|
});
|
|
|
|
|
|
masterController.hireAgent(newActor);
|
|
newActor._buildUI();
|
|
|
|
this.actors.push(newActor);
|
|
|
|
moveUI();
|
|
}
|
|
|
|
|
|
masterController.reset();
|
|
var director = new Director();
|
|
|
|
moveUI();
|
|
|
|
|
|
function mousePressEvent(event) {
|
|
print("mousePressEvent");
|
|
clickedOverlay = Overlays.getOverlayAtPoint({ x: event.x, y: event.y });
|
|
|
|
// Check director and actors
|
|
director.onMousePressEvent(clickedOverlay);
|
|
}
|
|
|
|
function moveUI() {
|
|
director.moveUI({ x: 70, y: 75});
|
|
|
|
}
|
|
|
|
function update(deltaTime) {
|
|
var newDimensions = Controller.getViewportDimensions();
|
|
if (windowDimensions.x != newDimensions.x ||
|
|
windowDimensions.y != newDimensions.y) {
|
|
windowDimensions = newDimensions;
|
|
moveUI();
|
|
}
|
|
|
|
if (director.requestPerformanceLoad) {
|
|
print("reloadPerformance " + director.performanceURL);
|
|
director.reloadPerformance();
|
|
}
|
|
|
|
masterController.update(deltaTime);
|
|
}
|
|
|
|
function scriptEnding() {
|
|
print("cleanup")
|
|
director.destroy();
|
|
masterController.destroy();
|
|
}
|
|
|
|
Controller.mousePressEvent.connect(mousePressEvent);
|
|
Script.update.connect(update);
|
|
Script.scriptEnding.connect(scriptEnding);
|
|
|