mirror of
https://github.com/lubosz/overte.git
synced 2025-04-25 14:13:05 +02:00
Merge pull request #8759 from howard-stearns/crowd-update
update for sound
This commit is contained in:
commit
c664c7192e
2 changed files with 56 additions and 10 deletions
|
@ -16,7 +16,7 @@
|
||||||
|
|
||||||
var MESSAGE_CHANNEL = "io.highfidelity.summon-crowd";
|
var MESSAGE_CHANNEL = "io.highfidelity.summon-crowd";
|
||||||
|
|
||||||
print('crowd-agent version 1');
|
print('crowd-agent version 2');
|
||||||
|
|
||||||
/* Observations:
|
/* Observations:
|
||||||
- File urls for AC scripts silently fail. Use a local server (e.g., python SimpleHTTPServer) for development.
|
- File urls for AC scripts silently fail. Use a local server (e.g., python SimpleHTTPServer) for development.
|
||||||
|
@ -24,9 +24,26 @@ print('crowd-agent version 1');
|
||||||
- JSON.stringify(Avatar) silently fails (even when Agent.isAvatar)
|
- JSON.stringify(Avatar) silently fails (even when Agent.isAvatar)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
function messageSend(message) {
|
||||||
|
Messages.sendMessage(MESSAGE_CHANNEL, JSON.stringify(message));
|
||||||
|
}
|
||||||
|
|
||||||
|
function getSound(data, callback) { // callback(sound) when downloaded (which may be immediate).
|
||||||
|
var sound = SoundCache.getSound(data.url);
|
||||||
|
if (sound.downloaded) {
|
||||||
|
return callback(sound);
|
||||||
|
}
|
||||||
|
sound.ready.connect(function () { callback(sound); });
|
||||||
|
}
|
||||||
|
function onFinishedPlaying() {
|
||||||
|
messageSend({key: 'finishedSound'});
|
||||||
|
}
|
||||||
|
|
||||||
|
var MILLISECONDS_IN_SECOND = 1000;
|
||||||
function startAgent(parameters) { // Can also be used to update.
|
function startAgent(parameters) { // Can also be used to update.
|
||||||
print('crowd-agent starting params', JSON.stringify(parameters), JSON.stringify(Agent));
|
print('crowd-agent starting params', JSON.stringify(parameters), JSON.stringify(Agent));
|
||||||
Agent.isAvatar = true;
|
Agent.isAvatar = true;
|
||||||
|
Agent.isListeningToAudioStream = true; // Send silence when not chattering.
|
||||||
if (parameters.position) {
|
if (parameters.position) {
|
||||||
Avatar.position = parameters.position;
|
Avatar.position = parameters.position;
|
||||||
}
|
}
|
||||||
|
@ -36,6 +53,12 @@ function startAgent(parameters) { // Can also be used to update.
|
||||||
if (parameters.skeletonModelURL) {
|
if (parameters.skeletonModelURL) {
|
||||||
Avatar.skeletonModelURL = parameters.skeletonModelURL;
|
Avatar.skeletonModelURL = parameters.skeletonModelURL;
|
||||||
}
|
}
|
||||||
|
if (parameters.soundData) {
|
||||||
|
getSound(parameters.soundData, function (sound) {
|
||||||
|
Script.setTimeout(onFinishedPlaying, sound.duration * MILLISECONDS_IN_SECOND);
|
||||||
|
Agent.playAvatarSound(sound);
|
||||||
|
});
|
||||||
|
}
|
||||||
if (parameters.animationData) {
|
if (parameters.animationData) {
|
||||||
data = parameters.animationData;
|
data = parameters.animationData;
|
||||||
Avatar.startAnimation(data.url, data.fps || 30, 1.0, (data.loopFlag === undefined) ? true : data.loopFlag, false, data.startFrame || 0, data.endFrame);
|
Avatar.startAnimation(data.url, data.fps || 30, 1.0, (data.loopFlag === undefined) ? true : data.loopFlag, false, data.startFrame || 0, data.endFrame);
|
||||||
|
@ -47,9 +70,6 @@ function stopAgent(parameters) {
|
||||||
print('crowd-agent stopped', JSON.stringify(parameters), JSON.stringify(Agent));
|
print('crowd-agent stopped', JSON.stringify(parameters), JSON.stringify(Agent));
|
||||||
}
|
}
|
||||||
|
|
||||||
function messageSend(message) {
|
|
||||||
Messages.sendMessage(MESSAGE_CHANNEL, JSON.stringify(message));
|
|
||||||
}
|
|
||||||
function messageHandler(channel, messageString, senderID) {
|
function messageHandler(channel, messageString, senderID) {
|
||||||
if (channel !== MESSAGE_CHANNEL) {
|
if (channel !== MESSAGE_CHANNEL) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -18,15 +18,25 @@ var label = "summon";
|
||||||
function debug() {
|
function debug() {
|
||||||
print.apply(null, [].concat.apply([label, version], [].map.call(arguments, JSON.stringify)));
|
print.apply(null, [].concat.apply([label, version], [].map.call(arguments, JSON.stringify)));
|
||||||
}
|
}
|
||||||
var MINIMUM_AVATARS = 25;
|
var MINIMUM_AVATARS = 25; // We will summon agents to produce this many total. (Of course, there might not be enough agents.)
|
||||||
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 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: "http://howard-stearns.github.io/models/sounds/piano1.wav"};
|
||||||
|
var AVATARS_CHATTERING_AT_ONCE = 4; // How many of the agents should we request to play SOUND at once.
|
||||||
|
var NEXT_SOUND_SPREAD = 500; // millisecond range of how long to wait after one sound finishes, before playing the next
|
||||||
|
|
||||||
var spread = Math.sqrt(MINIMUM_AVATARS * DENSITY); // meters
|
var spread = Math.sqrt(MINIMUM_AVATARS * DENSITY); // meters
|
||||||
var turnSpread = 90; // How many degrees should turn from front range over.
|
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 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];
|
||||||
|
}
|
||||||
|
|
||||||
var summonedAgents = [];
|
var summonedAgents = [];
|
||||||
|
var chattering = [];
|
||||||
var MESSAGE_CHANNEL = "io.highfidelity.summon-crowd";
|
var MESSAGE_CHANNEL = "io.highfidelity.summon-crowd";
|
||||||
function messageSend(message) {
|
function messageSend(message) {
|
||||||
Messages.sendMessage(MESSAGE_CHANNEL, JSON.stringify(message));
|
Messages.sendMessage(MESSAGE_CHANNEL, JSON.stringify(message));
|
||||||
|
@ -48,15 +58,20 @@ function messageHandler(channel, messageString, senderID) {
|
||||||
switch (message.key) {
|
switch (message.key) {
|
||||||
case "hello":
|
case "hello":
|
||||||
// There can be avatars we've summoned that do not yet appear in the AvatarList.
|
// There can be avatars we've summoned that do not yet appear in the AvatarList.
|
||||||
avatarIdentifiers = AvatarList.getAvatarIdentifiers().filter(function (id) { return summonedAgents.indexOf(id) === -1; });
|
avatarIdentifiers = without(AvatarList.getAvatarIdentifiers(), summonedAgents);
|
||||||
debug('present', avatarIdentifiers, summonedAgents);
|
debug('present', avatarIdentifiers, summonedAgents);
|
||||||
if ((summonedAgents.length + avatarIdentifiers.length) < MINIMUM_AVATARS ) {
|
if ((summonedAgents.length + avatarIdentifiers.length) < MINIMUM_AVATARS ) {
|
||||||
|
var chatter = chattering.length < AVATARS_CHATTERING_AT_ONCE;
|
||||||
|
if (chatter) {
|
||||||
|
chattering.push(senderID);
|
||||||
|
}
|
||||||
summonedAgents.push(senderID);
|
summonedAgents.push(senderID);
|
||||||
messageSend({
|
messageSend({
|
||||||
key: 'SUMMON',
|
key: 'SUMMON',
|
||||||
rcpt: senderID,
|
rcpt: senderID,
|
||||||
position: Vec3.sum(MyAvatar.position, {x: coord(), y: 0, z: coord()}),
|
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)/*,
|
orientation: Quat.fromPitchYawRollDegrees(0, Quat.safeEulerAngles(MyAvatar.orientation).y + (turnSpread * (Math.random() - 0.5)), 0),
|
||||||
|
soundData: chatter && SOUND_DATA/*
|
||||||
// No need to specify skeletonModelURL
|
// No need to specify skeletonModelURL
|
||||||
//skeletonModelURL: "file:///c:/Program Files/High Fidelity Release/resources/meshes/being_of_light/being_of_light.fbx",
|
//skeletonModelURL: "file:///c:/Program Files/High Fidelity Release/resources/meshes/being_of_light/being_of_light.fbx",
|
||||||
//skeletonModelURL: "file:///c:/Program Files/High Fidelity Release/resources/meshes/defaultAvatar_full.fst"/,
|
//skeletonModelURL: "file:///c:/Program Files/High Fidelity Release/resources/meshes/defaultAvatar_full.fst"/,
|
||||||
|
@ -71,6 +86,16 @@ function messageHandler(channel, messageString, senderID) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
break;
|
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":
|
case "HELO":
|
||||||
Window.alert("Someone else is summoning avatars.");
|
Window.alert("Someone else is summoning avatars.");
|
||||||
break;
|
break;
|
||||||
|
@ -93,11 +118,12 @@ Script.scriptEnding.connect(function () {
|
||||||
|
|
||||||
messageSend({key: 'HELO'}); // Ask agents to report in now.
|
messageSend({key: 'HELO'}); // Ask agents to report in now.
|
||||||
Script.setTimeout(function () {
|
Script.setTimeout(function () {
|
||||||
|
var total = AvatarList.getAvatarIdentifiers().length;
|
||||||
if (0 === summonedAgents.length) {
|
if (0 === summonedAgents.length) {
|
||||||
Window.alert("No agents reported.\n\Please run " + MINIMUM_AVATARS + " instances of\n\
|
Window.alert("No agents reported.\n\Please run " + MINIMUM_AVATARS + " instances of\n\
|
||||||
http://cdn.highfidelity.com/davidkelly/production/scripts/tests/performance/crowd-agent.js\n\
|
http://cdn.highfidelity.com/davidkelly/production/scripts/tests/performance/crowd-agent.js\n\
|
||||||
on your domain server.");
|
on your domain server.");
|
||||||
} else if (summonedAgents.length < MINIMUM_AVATARS) {
|
} else if (total < MINIMUM_AVATARS) {
|
||||||
Window.alert("Only " + summonedAgents.length + " of the expected " + MINIMUM_AVATARS + " agents reported in.");
|
Window.alert("Only " + summonedAgents.length + " of the expected " + (MINIMUM_AVATARS - total) + " agents reported in.");
|
||||||
}
|
}
|
||||||
}, 5000);
|
}, 5000);
|
||||||
|
|
Loading…
Reference in a new issue