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.
183 lines
No EOL
8.9 KiB
JavaScript
183 lines
No EOL
8.9 KiB
JavaScript
"use strict";
|
|
/*jslint vars: true, plusplus: true*/
|
|
/*global Agent, Avatar, Script, Entities, Vec3, Quat, print*/
|
|
//
|
|
// crowd-agent.js
|
|
// scripts/developer/tests/performance/
|
|
//
|
|
// Created by Howard Stearns on 9/29/16.
|
|
// Copyright 2016 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
|
|
//
|
|
// See crowd-agent.js
|
|
|
|
var version = 2;
|
|
var label = "summon";
|
|
function debug() {
|
|
print.apply(null, [].concat.apply([label, version], [].map.call(arguments, JSON.stringify)));
|
|
}
|
|
|
|
var MINIMUM_AVATARS = 2; // We will summon agents to produce this many total. (Of course, there might not be enough agents.)
|
|
var N_LISTENING = MINIMUM_AVATARS - 1;
|
|
var AVATARS_CHATTERING_AT_ONCE = 2; // How many of the agents should we request to play SOUND_DATA at once.
|
|
|
|
// If we add or remove things too quickly, we get problems (e.g., audio, fogbugz 2095).
|
|
// For now, spread them out this timing apart.
|
|
var SPREAD_TIME_MS = 500;
|
|
|
|
var DENSITY = 0.3; // square meters per person. Some say 10 sq ft is arm's length (0.9m^2), 4.5 is crowd (0.4m^2), 2.5 is mosh pit (0.2m^2).
|
|
var SOUND_DATA = {url: "https://s3.amazonaws.com/hifi-public/sounds/cocktail-party/B1.wav"};
|
|
var NEXT_SOUND_SPREAD = 500; // millisecond range of how long to wait after one sound finishes, before playing the next
|
|
var ANIMATION_DATA = {
|
|
//"url": "http://hifi-content.s3.amazonaws.com/howard/resources/avatar/animations/idle.fbx",
|
|
"url": "http://hifi-content.s3.amazonaws.com/howard/resources/avatar/animations/walk_fwd.fbx", // alternative example
|
|
"startFrame": 0.0,
|
|
"endFrame": 300.0,
|
|
"timeScale": 1.0,
|
|
"loopFlag": true
|
|
};
|
|
|
|
var spread = Math.sqrt(MINIMUM_AVATARS * DENSITY); // meters
|
|
var turnSpread = 90; // How many degrees should turn from front range over.
|
|
|
|
function coord() { return (Math.random() * spread) - (spread / 2); } // randomly distribute a coordinate zero += spread/2.
|
|
function contains(array, item) { return array.indexOf(item) >= 0; }
|
|
function without(array, itemsToRemove) { return array.filter(function (item) { return !contains(itemsToRemove, item); }); }
|
|
function nextAfter(array, id) { // Wrapping next element in array after id.
|
|
var index = array.indexOf(id) + 1;
|
|
return array[(index >= array.length) ? 0 : index];
|
|
}
|
|
|
|
function getAvatarModel(index) {
|
|
var nameArray = [
|
|
"http://mpassets.highfidelity.com/bd80a6d7-7173-489e-87c6-f7ee56e65530-v1/M_RetFut.fst",
|
|
"http://mpassets.highfidelity.com/47c8d706-d486-4c2d-afcc-70d4e1e25117-v1/M_RetSpaSuit.fst",
|
|
"http://mpassets.highfidelity.com/548d0792-0bac-4933-bbfc-57d71912d77e-v1/M_OutMer.fst",
|
|
"http://mpassets.highfidelity.com/13277c09-892f-4a5e-b9a5-8994a37d68bf-v1/F_WasWar.fst",
|
|
"http://mpassets.highfidelity.com/2d384111-0f0e-42e2-b800-66bfcab4aefb-v1/F_VooQue.fst",
|
|
"http://mpassets.highfidelity.com/57e4d1cd-9f52-4c95-9051-326f9bb114ea-v1/F_SteAvi.fst",
|
|
"http://mpassets.highfidelity.com/da2ad4cd-47d4-41da-b764-41f39ff77e30-v1/F_JerGir.fst",
|
|
"http://mpassets.highfidelity.com/96c747ab-f71b-44ee-8eb9-d19fc9593dda-v1/F_CatBur.fst",
|
|
"http://mpassets.highfidelity.com/ede82c38-c66e-4f67-9e0b-0bb0782db18f-v1/M_WesOut.fst",
|
|
"http://mpassets.highfidelity.com/8872ae86-a763-4db3-8373-d27514c1481e-v1/M_VinAvi.fst",
|
|
|
|
"http://mpassets.highfidelitydasss.com/0c2c264b-2fd2-46a4-bf80-de681881f66b-v1/F_MotRac.fst",
|
|
"http://mpassets.highfidelity.com/faf505f1-4fd1-4ed2-8909-816af246c48f-v1/M_VicGen.fst",
|
|
"http://mpassets.highfidelity.com/d807a7d2-5122-4436-a6f9-3173c94d1c49-v1/M_SuaGen.fst",
|
|
"http://mpassets.highfidelity.com/1dd41735-06f4-45a3-9ec0-d05215ace77b-v1/M_MarSen.fst",
|
|
"http://mpassets.highfidelity.com/2cad3894-8ab3-4ba5-a723-0234f93fbd6a-v1/M_BowBea.fst",
|
|
"http://mpassets.highfidelity.com/cf0eb1be-9ec7-4756-8eaf-ac8f3ec09eba-v1/F_ClaDef.fst",
|
|
"http://mpassets.highfidelity.com/0cedeca3-c1a4-4be9-9fd5-dad716afcc7e-v1/F_Cyria.fst",
|
|
"http://mpassets.highfidelity.com/dc55803b-9215-47dd-9408-eb835dac4082-v1/F_ParGir.fst",
|
|
"http://mpassets.highfidelity.com/775a8fb3-cfe7-494d-b603-a0a2d6910e55-v1/F_VinCov.fst",
|
|
"http://mpassets.highfidelity.com/eba0d8f8-aa72-4a6b-ab64-4d3fd4695b20-v1/F_VogHei.fst",
|
|
|
|
"http://mpassets.highfidelity.com/4f400c78-38f9-42af-b03b-11b5451d41b9-v1/M_MidRog.fst",
|
|
"http://mpassets.highfidelity.com/ad774d79-13f1-46e2-87c9-de49a261b264-v1/F_GunSli.fst",
|
|
"http://mpassets.highfidelity.com/5acbaefa-5455-49a2-8d40-89d12aa393ca-v1/M_KniWol.fst",
|
|
"http://mpassets.highfidelity.com/aaa1b0a8-3e1b-492a-9aee-600e5dc907db-v1/F_RetSciSuit.fst",
|
|
"http://mpassets.highfidelity.com/d8da10b6-25c1-40e2-9a66-369316c722d7-v1/F_AniSuit.fst"
|
|
|
|
];
|
|
|
|
return nameArray[ index % nameArray.length ];
|
|
}
|
|
|
|
var summonedAgents = [];
|
|
var chattering = [];
|
|
var nListening = 0;
|
|
var accumulatedDelay = 0;
|
|
var MESSAGE_CHANNEL = "io.highfidelity.summon-crowd";
|
|
function messageSend(message) {
|
|
Messages.sendMessage(MESSAGE_CHANNEL, JSON.stringify(message));
|
|
}
|
|
function messageHandler(channel, messageString, senderID) {
|
|
if (channel !== MESSAGE_CHANNEL) {
|
|
return;
|
|
}
|
|
debug('message', channel, messageString, senderID);
|
|
if (MyAvatar.sessionUUID === senderID) { // ignore my own
|
|
return;
|
|
}
|
|
var message = {}, avatarIdentifiers;
|
|
try {
|
|
message = JSON.parse(messageString);
|
|
} catch (e) {
|
|
print(e);
|
|
}
|
|
switch (message.key) {
|
|
case "hello":
|
|
Script.setTimeout(function () {
|
|
// There can be avatars we've summoned that do not yet appear in the AvatarList.
|
|
avatarIdentifiers = without(AvatarList.getAvatarIdentifiers(), summonedAgents);
|
|
debug('present', avatarIdentifiers, summonedAgents);
|
|
if ((summonedAgents.length + avatarIdentifiers.length) < MINIMUM_AVATARS ) {
|
|
var chatter = chattering.length < AVATARS_CHATTERING_AT_ONCE;
|
|
var listen = nListening < N_LISTENING;
|
|
if (chatter) {
|
|
chattering.push(senderID);
|
|
}
|
|
if (listen) {
|
|
nListening++;
|
|
}
|
|
summonedAgents.push(senderID);
|
|
var avatarModel = getAvatarModel(summonedAgents.length - 1);
|
|
messageSend({
|
|
key: 'SUMMON',
|
|
rcpt: senderID,
|
|
position: Vec3.sum(MyAvatar.position, {x: coord(), y: 0, z: coord()}),
|
|
orientation: Quat.fromPitchYawRollDegrees(0, Quat.safeEulerAngles(MyAvatar.orientation).y + (turnSpread * (Math.random() - 0.5)), 0),
|
|
soundData: chatter && SOUND_DATA,
|
|
listen: listen,
|
|
skeletonModelURL: avatarModel,
|
|
animationData: ANIMATION_DATA
|
|
});
|
|
}
|
|
}, accumulatedDelay);
|
|
accumulatedDelay += SPREAD_TIME_MS; // assume we'll get all the hello respsponses more or less together.
|
|
break;
|
|
case "finishedSound": // Give someone else a chance.
|
|
chattering = without(chattering, [senderID]);
|
|
Script.setTimeout(function () {
|
|
messageSend({
|
|
key: 'SUMMON',
|
|
rcpt: nextAfter(without(summonedAgents, chattering), senderID),
|
|
soundData: SOUND_DATA
|
|
});
|
|
}, Math.random() * NEXT_SOUND_SPREAD);
|
|
break;
|
|
case "HELO":
|
|
Window.alert("Someone else is summoning avatars.");
|
|
break;
|
|
default:
|
|
print("crowd summon.js received unrecognized message:", messageString);
|
|
}
|
|
}
|
|
Messages.subscribe(MESSAGE_CHANNEL);
|
|
Messages.messageReceived.connect(messageHandler);
|
|
Script.scriptEnding.connect(function () {
|
|
debug('stopping agents', summonedAgents);
|
|
Messages.messageReceived.disconnect(messageHandler); // don't respond to any messages during shutdown
|
|
accumulatedDelay = 0;
|
|
summonedAgents.forEach(function (id) {
|
|
messageSend({key: 'STOP', rcpt: id, delay: accumulatedDelay});
|
|
accumulatedDelay += SPREAD_TIME_MS;
|
|
});
|
|
debug('agents stopped');
|
|
Messages.unsubscribe(MESSAGE_CHANNEL);
|
|
debug('unsubscribed');
|
|
});
|
|
|
|
messageSend({key: 'HELO'}); // Ask agents to report in now.
|
|
Script.setTimeout(function () {
|
|
var total = AvatarList.getAvatarIdentifiers().length;
|
|
if (0 === summonedAgents.length) {
|
|
Window.alert("No agents reported.\n\Please run " + MINIMUM_AVATARS + " instances of\n\
|
|
http://hifi-content.s3.amazonaws.com/howard/scripts/tests/performance/crowd-agent.js\n\
|
|
on your domain server.");
|
|
} else if (total < MINIMUM_AVATARS) {
|
|
Window.alert("Only " + summonedAgents.length + " agents reported. Now missing " + (MINIMUM_AVATARS - total) + " avatars, total.");
|
|
}
|
|
}, MINIMUM_AVATARS * SPREAD_TIME_MS ) |