diff --git a/hifi-content/hifi-worklist-logo.jpg b/hifi-content/hifi-worklist-logo.jpg new file mode 100644 index 000000000..aea9a6f10 --- /dev/null +++ b/hifi-content/hifi-worklist-logo.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:55e0762d0f18abcc9774c54991707b651ddde44aecb3f659bdf74ffb6b902e4e +size 57744 diff --git a/hifi-content/high-fidelity-og.jpg b/hifi-content/high-fidelity-og.jpg new file mode 100644 index 000000000..51847777a --- /dev/null +++ b/hifi-content/high-fidelity-og.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:11dea34a973c9a92a8763d60e0fa83d008c256f67666be8fabf0ff877314808f +size 249288 diff --git a/hifi-content/high-fidelity-og_load-test.jpg b/hifi-content/high-fidelity-og_load-test.jpg new file mode 100644 index 000000000..8057cf6a5 --- /dev/null +++ b/hifi-content/high-fidelity-og_load-test.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:723ed0248227f0b23c10c8f588fc52e4b99c152a11ab86da5d6e0da9fb552b65 +size 191882 diff --git a/hifi-content/howard/production/zaru-content-custom-scripts.zip b/hifi-content/howard/production/zaru-content-custom-scripts.zip new file mode 120000 index 000000000..7804ca9ad --- /dev/null +++ b/hifi-content/howard/production/zaru-content-custom-scripts.zip @@ -0,0 +1 @@ +../zaru-content-custom-scripts.zip \ No newline at end of file diff --git a/hifi-content/howard/resources/avatar/animations/idle.fbx b/hifi-content/howard/resources/avatar/animations/idle.fbx new file mode 120000 index 000000000..28932e2a2 --- /dev/null +++ b/hifi-content/howard/resources/avatar/animations/idle.fbx @@ -0,0 +1 @@ +../../../../DomainContent/AvatarStore-Backup/BodyMart/idle.fbx \ No newline at end of file diff --git a/hifi-content/howard/resources/avatar/animations/walk_fwd.fbx b/hifi-content/howard/resources/avatar/animations/walk_fwd.fbx new file mode 100644 index 000000000..c46983c2d --- /dev/null +++ b/hifi-content/howard/resources/avatar/animations/walk_fwd.fbx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:41e68ef30fcab9aca97307fa815f401477aa7550668beb2af8b35c7a1bd112e5 +size 309024 diff --git a/hifi-content/howard/resources/meshes/being_of_light/being_of_light.fbx b/hifi-content/howard/resources/meshes/being_of_light/being_of_light.fbx new file mode 120000 index 000000000..adc65df8f --- /dev/null +++ b/hifi-content/howard/resources/meshes/being_of_light/being_of_light.fbx @@ -0,0 +1 @@ +../../../../lincoln/avatars/being_of_light.fbx \ No newline at end of file diff --git a/hifi-content/howard/resources/meshes/being_of_light/textures/BaseMesh_BeingofLight_DiffuseMap.png b/hifi-content/howard/resources/meshes/being_of_light/textures/BaseMesh_BeingofLight_DiffuseMap.png new file mode 120000 index 000000000..8f6222018 --- /dev/null +++ b/hifi-content/howard/resources/meshes/being_of_light/textures/BaseMesh_BeingofLight_DiffuseMap.png @@ -0,0 +1 @@ +../../../../../Avatars/production/being_of_light/textures/BaseMesh_BeingofLight_DiffuseMap.png \ No newline at end of file diff --git a/hifi-content/howard/resources/meshes/being_of_light/textures/BaseMesh_BeingofLight_EmissiveMap.png b/hifi-content/howard/resources/meshes/being_of_light/textures/BaseMesh_BeingofLight_EmissiveMap.png new file mode 120000 index 000000000..55f17c005 --- /dev/null +++ b/hifi-content/howard/resources/meshes/being_of_light/textures/BaseMesh_BeingofLight_EmissiveMap.png @@ -0,0 +1 @@ +../../../../../Avatars/production/being_of_light/textures/BaseMesh_BeingofLight_EmissiveMap.png \ No newline at end of file diff --git a/hifi-content/howard/resources/meshes/being_of_light/textures/BaseMesh_BeingofLight_NormalMap.png b/hifi-content/howard/resources/meshes/being_of_light/textures/BaseMesh_BeingofLight_NormalMap.png new file mode 120000 index 000000000..fedb67990 --- /dev/null +++ b/hifi-content/howard/resources/meshes/being_of_light/textures/BaseMesh_BeingofLight_NormalMap.png @@ -0,0 +1 @@ +../../../../../Avatars/production/being_of_light/textures/BaseMesh_BeingofLight_NormalMap.png \ No newline at end of file diff --git a/hifi-content/howard/resources/meshes/defaultAvatar_full.fst b/hifi-content/howard/resources/meshes/defaultAvatar_full.fst new file mode 120000 index 000000000..22ea22bcf --- /dev/null +++ b/hifi-content/howard/resources/meshes/defaultAvatar_full.fst @@ -0,0 +1 @@ +../../../lincoln/avatars/being_of_light.fst \ No newline at end of file diff --git a/hifi-content/howard/scripts/dev-welcome.js b/hifi-content/howard/scripts/dev-welcome.js new file mode 100644 index 000000000..4dbcf12ad --- /dev/null +++ b/hifi-content/howard/scripts/dev-welcome.js @@ -0,0 +1,64 @@ +var typeBlacklist = ["Zone"]; /* for now, disallow all zone entities */ +var center = {x: 0, y: 0, z: 0}; /* also nothing can move within 5 meters of 0,0,0 */ +var radius = 5; +var epsilon = 0.01; +var aBitMore = 5 * (1 + epsilon); +var staticBounceSpeed = 0.5; /* If edit within radius that has no velocity. */ +var Vec3 = { + distance: function distance(a, b) { + var x = a.x - b.x, + y = a.y - b.y, + z = a.z - b.z; + return Math.sqrt((x * x) + (y * y) + (z * z)); + }, + ZERO: {x: 0, y: 0, z: 0}, + length: function length(v) { + return Vec3.distance(Vec3.ZERO, v); + }, + multiply: function multiply(s, v) { + return {x: s * v.x, y: s * v.y, z: s * v.z}; + }, + normalize: function normalize(v) { + var length = Vec3.length(v); + return Vec3.multiply(1/length, v); + } +}; + +function filter(p, filterType) { + if (p.type && (typeBlacklist.indexOf(p.type) != -1)) { + print("filtering out " + p.type + " entity!"); + return false + } + if (p.position) { + var distance = Vec3.distance(center, p.position); + var reject = distance <= radius; + var normal; + if (reject) { + print('rejecting type', filterType, 'packet near origin'); + if (filterType === Entities.ADD_FILTER_TYPE) { + return false; + } else { /* Others are Entities.EDIT_FILTER_TYPE and Entities.PHYSICS_FILTER_TYPE. */ + normal = Vec3.normalize(p.position); + p.position = Vec3.multiply(aBitMore, normal); + p.velocity = (p.velocity && Vec3.length(p.velocity) > epsilon) ? + Vec3.multiply(-1, p.velocity) : Vec3.multiply(staticBounceSpeed, normal); + p.acceleration = Vec3.ZERO; + } + } + } + if (p.dimensions && (filterType !== Entities.ADD_FILTER_TYPE)) { + if (p.dimensions.x > 11) { + p.dimensions.x = 11; + print('capping x dimension'); + } + if (p.dimensions.y > 11) { + p.dimensions.y = 11; + print('capping y dimension'); + } + if (p.dimensions.z > 11) { + p.dimensions.z = 11; + print('capping z dimension'); + } + } + return p; +} diff --git a/hifi-content/howard/scripts/tests/performance/crowd-agent.js b/hifi-content/howard/scripts/tests/performance/crowd-agent.js new file mode 100644 index 000000000..708856a82 --- /dev/null +++ b/hifi-content/howard/scripts/tests/performance/crowd-agent.js @@ -0,0 +1,166 @@ +"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 +// +// Add this to domain-settings scripts url with n instances. It will lie dormant until +// a script like summon.js calls up to n avatars to be around you. + +var MESSAGE_CHANNEL = "io.highfidelity.summon-crowd"; + +print('crowd-agent version 5'); + +/* Observations: +- File urls for AC scripts silently fail. Use a local server (e.g., python SimpleHTTPServer) for development. +- URLs are cached regardless of server headers. Must use cache-defeating query parameters. +- JSON.stringify(Avatar) silently fails (even when Agent.isAvatar) +- If you run from a dev build directory, you must link assignment-client//resources to ../../interface//resources +*/ + +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); + } + function onDownloaded() { + sound.ready.disconnect(onDownloaded); + callback(sound); + } + sound.ready.connect(onDownloaded); +} +function onFinishedPlaying() { + messageSend({key: 'finishedSound'}); +} + +var attachment; +var stopper; +function clearStopper() { + if (!stopper) { + return; + } + Script.clearTimeout(stopper); + stopper = null; +} +function stopAgent(parameters) { + function stop() { + clearStopper(); + if (attachment) { + Avatar.detachOne(attachment.modelURL, attachment.jointName); + attachment = undefined; + } + Agent.isListeningToAudioStream = false; + Agent.isAvatar = false; + print('crowd-agent stopped', JSON.stringify(parameters), JSON.stringify(Agent)); + } + // Shutting down lots of agents at once can be hard on other parts of the system. (See fogbugz 2095.) + // For now, accept a parameter to delay for the given number of milliseconds before stopping. + // (We cannot count on summoning scripts to spread out the STOP messages, because they might be doing so + // on scriptEnding, in which case they are not allowed to create new delays.) + if (parameters.delay) { + if (!stopper) { // Let the first stopper do the deed. + stopper = Script.setTimeout(stop, parameters.delay); + } + } else { + stop(); + } +} + + +var MILLISECONDS_IN_SECOND = 1000; +function startAgent(parameters) { // Can also be used to update. + print('crowd-agent starting params', JSON.stringify(parameters), JSON.stringify(Agent)); + clearStopper(); + var wasOff = !Agent.isAvatar; + Agent.isAvatar = true; + if (parameters.displayName !== undefined) { + Avatar.displayName = parameters.displayName; + } + if (parameters.position) { + Avatar.position = parameters.position; + } + if (parameters.orientation) { + Avatar.orientation = parameters.orientation; + } + if (parameters.skeletonModelURL) { + Avatar.skeletonModelURL = parameters.skeletonModelURL; + } + if (parameters.listen != undefined) { + Agent.isListeningToAudioStream = parameters.listen; // Send silence when not chattering. + } else if (wasOff) { + Agent.isListeningToAudioStream = true; + } + if (parameters.soundData) { + getSound(parameters.soundData, function (sound) { + Script.setTimeout(onFinishedPlaying, sound.duration * MILLISECONDS_IN_SECOND); + Agent.playAvatarSound(sound); + }); + } + if (parameters.animationData) { + var data = parameters.animationData; + Avatar.startAnimation(data.url, data.fps || 30, 1.0, (data.loopFlag === undefined) ? true : data.loopFlag, false, data.startFrame || 0, data.endFrame); + } + if (parameters.attachment) { + attachment = parameters.attachment; + Avatar.attach(attachment.modelURL, attachment.jointName, attachment.translation, attachment.rotation, attachment.scale, attachment.isSoft); + } else { + attachment = undefined; + } + print('crowd-agent avatars started'); +} + +function messageHandler(channel, messageString, senderID) { + if (channel !== MESSAGE_CHANNEL) { + return; + } + print('crowd-agent message', channel, messageString, senderID); + if (Agent.sessionUUID === senderID) { // ignore my own + return; + } + var message = {}; + try { + message = JSON.parse(messageString); + } catch (e) { + print(e); + } + switch (message.key) { + case "HELO": + messageSend({key: 'hello'}); // Allow the coordinator to count responses and make assignments. + break; + case 'hello': // ignore responses (e.g., from other agents) + case 'finishedSound': + break; + case "SUMMON": + if (message.rcpt === Agent.sessionUUID) { + startAgent(message); + } + break; + case "STOP": + if (message.rcpt === Agent.sessionUUID) { + stopAgent(message); + } + break; + default: + print("crowd-agent received unrecognized message:", channel, messageString, senderID); + } +} +Messages.subscribe(MESSAGE_CHANNEL); +Messages.messageReceived.connect(messageHandler); + +Script.scriptEnding.connect(function () { + print('crowd-agent shutting down'); + Messages.messageReceived.disconnect(messageHandler); + Messages.unsubscribe(MESSAGE_CHANNEL); + print('crowd-agent unsubscribed'); +}); diff --git a/hifi-content/howard/scripts/tests/performance/domain-check.js b/hifi-content/howard/scripts/tests/performance/domain-check.js new file mode 100644 index 000000000..b4bf4569c --- /dev/null +++ b/hifi-content/howard/scripts/tests/performance/domain-check.js @@ -0,0 +1,345 @@ +"use strict"; +/*jslint vars: true, plusplus: true*/ +/*globals Script, MyAvatar, Quat, Vec3, Render, ScriptDiscoveryService, Window, LODManager, Entities, Messages, AvatarList, Menu, Stats, HMD, location, print*/ +// +// loadedMachine.js +// scripts/developer/tests/ +// +// Created by Howard Stearns on 6/6/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 +// +// Confirms that the specified domain is operating within specified constraints. + +var MINIMUM_DESKTOP_FRAMERATE = 57; // frames per second +var MINIMUM_HMD_FRAMERATE = 86; +var EXPECTED_DESKTOP_FRAMERATE = 60; +var EXPECTED_HMD_FRAMERATE = 90; +var NOMINAL_LOAD_TIME = 30; // seconds +var MAXIMUM_LOAD_TIME = NOMINAL_LOAD_TIME * 2; +var MINIMUM_AVATARS = 25; // changeable by prompt + +// 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: "http://hifi-content.s3.amazonaws.com/howard/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 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 version = 4; +function debug() { + print.apply(null, [].concat.apply(['hrs fixme', version], [].map.call(arguments, JSON.stringify))); +} + +function canonicalizePlacename(name) { + var prefix = 'dev-'; + name = name.toLowerCase(); + if (name.indexOf(prefix) === 0) { + name = name.slice(prefix.length); + } + return name; +} +var cachePlaces = ['localhost', 'welcome'].map(canonicalizePlacename); // For now, list the lighter weight one first. +var defaultPlace = location.hostname; +var prompt = "domain-check.js version " + version + "\n\nWhat place should we enter?"; +debug(cachePlaces, defaultPlace, prompt); +var entryPlace = Window.prompt(prompt, defaultPlace); +var runTribbles = Window.confirm("Run tribbles?\n\n\ +At most, only one participant should say yes."); +MINIMUM_AVATARS = parseInt(Window.prompt("Total avatars (including yourself and any already present)?", MINIMUM_AVATARS.toString()) || "0", 10); +AVATARS_CHATTERING_AT_ONCE = MINIMUM_AVATARS ? parseInt(Window.prompt("Number making sound?", Math.min(MINIMUM_AVATARS - 1, AVATARS_CHATTERING_AT_ONCE).toString()) || "0", 10) : 0; + +function placesMatch(a, b) { // handling case and 'dev-' variations + return canonicalizePlacename(a) === canonicalizePlacename(b); +} +function isNowIn(place) { // true if currently in specified place + placesMatch(location.hostname, place); +} + +function go(place) { // handle (dev-)welcome in the appropriate version-specific way + debug('go', place); + if (placesMatch(place, 'welcome')) { + location.goToEntry(); + } else { + location.handleLookupString(place); + } +} + +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]; +} + +var summonedAgents = []; +var chattering = []; +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; + if (chatter) { + chattering.push(senderID); + } + summonedAgents.push(senderID); + 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: true, + skeletonModelURL: "http://hifi-content.s3.amazonaws.com/howard/resources/meshes/defaultAvatar_full.fst", + 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-agent 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'); +}); + +var fail = false, results = ""; +function addResult(label, actual, nominal, minimum, maximum) { + if ((minimum !== undefined) && (actual < minimum)) { + fail = ' FAILED: ' + label + ' below ' + minimum; + } + if ((maximum !== undefined) && (actual > maximum)) { + fail = ' FAILED: ' + label + ' above ' + maximum; + } + results += "\n" + label + ": " + actual.toFixed(0) + " (" + ((100 * actual) / nominal).toFixed(0) + "%)"; +} +function giveReport() { + Window.alert(entryPlace + (fail || " OK") + "\n" + results + "\nwith " + summonedAgents.length + " avatars added,\nand " + AVATARS_CHATTERING_AT_ONCE + " making noise."); +} + +// Tests are performed domain-wide, at full LOD +var initialLodIsAutomatic = LODManager.getAutomaticLODAdjust(); +var LOD = 32768 * 400; +LODManager.setAutomaticLODAdjust(false); +LODManager.setOctreeSizeScale(LOD); +Script.scriptEnding.connect(function () { LODManager.setAutomaticLODAdjust(initialLodIsAutomatic); }); + +function startTwirl(targetRotation, degreesPerUpdate, interval, strafeDistance, optionalCallback) { + var initialRotation = Quat.safeEulerAngles(MyAvatar.orientation).y; + var accumulatedRotation = 0; + function tick() { + MyAvatar.orientation = Quat.fromPitchYawRollDegrees(0, accumulatedRotation + initialRotation, 0); + if (strafeDistance) { + MyAvatar.position = Vec3.sum(MyAvatar.position, Vec3.multiply(strafeDistance, Quat.getRight(MyAvatar.orientation))); + } + accumulatedRotation += degreesPerUpdate; + if (accumulatedRotation >= targetRotation) { + return optionalCallback && optionalCallback(); + } + Script.setTimeout(tick, interval); + } + tick(); +} + +function doLoad(place, continuationWithLoadTime) { // Go to place and call continuationWithLoadTime(loadTimeInSeconds) + var start = Date.now(), timeout, onDownloadUpdate, finishedTwirl = false, loadTime; + // There are two ways to learn of changes: connect to change signals, or poll. + // Until we get reliable results, we'll poll. + var POLL_INTERVAL = 500, poll; + function setHandlers() { + //Stats.downloadsPendingChanged.connect(onDownloadUpdate); downloadsChanged, and physics... + poll = Script.setInterval(onDownloadUpdate, POLL_INTERVAL); + } + function clearHandlers() { + debug('clearHandlers'); + //Stats.downloadsPendingChanged.disconnect(onDownloadUpdate); downloadsChanged, and physics.. + Script.clearInterval(poll); + } + function waitForLoad(flag) { + debug('entry', place, 'initial downloads/pending', Stats.downloads, Stats.downloadsPending); + location.hostChanged.disconnect(waitForLoad); + timeout = Script.setTimeout(function () { + debug('downloads timeout', Date()); + clearHandlers(); + Window.alert("Timeout during " + place + " load. FAILED"); + Script.stop(); + }, MAXIMUM_LOAD_TIME * 1000); + startTwirl(360, 6, 90, null, function () { + finishedTwirl = true; + if (loadTime) { + continuationWithLoadTime(loadTime); + } + }); + setHandlers(); + } + function isLoading() { + // FIXME: We should also confirm that textures have loaded. + return Stats.downloads || Stats.downloadsPending || !Window.isPhysicsEnabled(); + } + onDownloadUpdate = function onDownloadUpdate() { + debug('update downloads/pending', Stats.downloads, Stats.downloadsPending); + if (isLoading()) { + return; + } + Script.clearTimeout(timeout); + clearHandlers(); + loadTime = (Date.now() - start) / 1000; + if (finishedTwirl) { + continuationWithLoadTime(loadTime); + } + }; + + location.hostChanged.connect(waitForLoad); + go(place); +} + +var config = Render.getConfig("Stats"); +function doRender(continuation) { + var start = Date.now(), frames = 0; + function onNewStats() { // Accumulates frames on signal during load test + frames++; + } + if (MINIMUM_AVATARS) { + messageSend({key: 'HELO'}); // Ask agents to report in now. + } + + config.newStats.connect(onNewStats); + startTwirl(720, 1, 20, 0.08, function () { + var end = Date.now(); + config.newStats.disconnect(onNewStats); + addResult('frame rate', 1000 * frames / (end - start), + HMD.active ? EXPECTED_HMD_FRAMERATE : EXPECTED_DESKTOP_FRAMERATE, + HMD.active ? MINIMUM_HMD_FRAMERATE : MINIMUM_DESKTOP_FRAMERATE); + var total = AvatarList.getAvatarIdentifiers().length; + if (MINIMUM_AVATARS && !fail) { + if (0 === summonedAgents.length) { + fail = "FAIL: No agents reported.\nPlease run " + MINIMUM_AVATARS + " instances of\n\ +http://hifi-content.s3.amazonaws.com/howard/scripts/tests/performance/crowd-agent.js?v=3\n\ +on your domain server."; + } else if (total < MINIMUM_AVATARS) { + fail = "FAIL: Only " + summonedAgents.length + " agents reported. Now missing " + (MINIMUM_AVATARS - total) + " avatars, total."; + } + } + continuation(); + }); +} + +var TELEPORT_PAUSE = 500; +function prepareCache(continuation) { + function loadNext() { + var place = cachePlaces.shift(); + doLoad(place, function (prepTime) { + debug(place, 'ready', prepTime); + if (cachePlaces.length) { + loadNext(); + } else { + continuation(); + } + }); + } + // remove entryPlace target from cachePlaces + var targetInCache = cachePlaces.indexOf(canonicalizePlacename(entryPlace)); + if (targetInCache !== -1) { + cachePlaces.splice(targetInCache, 1); + } + debug('cachePlaces', cachePlaces); + go(cachePlaces[1] || entryPlace); // Not quite right for entryPlace case (allows some qt pre-caching), but close enough. + Script.setTimeout(function () { + Menu.triggerOption("Reload Content (Clears all caches)"); + Script.setTimeout(loadNext, TELEPORT_PAUSE); + }, TELEPORT_PAUSE); +} + +function maybeRunTribbles(continuation) { + if (runTribbles) { + Script.load('http://cdn.highfidelity.com/davidkelly/production/scripts/tests/performance/tribbles.js'); + Script.setTimeout(continuation, 3000); + } else { + continuation(); + } +} + +if (!entryPlace) { + Window.alert("domain-check.js cancelled"); + Script.stop(); +} else { + prepareCache(function (prepTime) { + debug('cache ready', prepTime); + doLoad(entryPlace, function (loadTime) { + addResult("load time", loadTime, NOMINAL_LOAD_TIME, undefined, MAXIMUM_LOAD_TIME); + LODManager.setAutomaticLODAdjust(initialLodIsAutomatic); // after loading, restore lod. + maybeRunTribbles(function () { + doRender(function () { + giveReport(); + Script.stop(); + }); + }); + }); + }); +} + +Script.scriptEnding.connect(function () { print("domain-check completed"); }); diff --git a/hifi-content/howard/scripts/tests/performance/screamingAvatarAC.js b/hifi-content/howard/scripts/tests/performance/screamingAvatarAC.js new file mode 100644 index 000000000..40210ef02 --- /dev/null +++ b/hifi-content/howard/scripts/tests/performance/screamingAvatarAC.js @@ -0,0 +1,39 @@ +var sound = SoundCache.getSound("http://hifi-content.s3.amazonaws.com/howard/sounds/piano1.wav"); + +var ANIMATION_URL = "http://hifi-content.s3.amazonaws.com/howard/resources/avatar/animations/idle.fbx"; +var AVATAR_MODEL = "http://hifi-content.s3.amazonaws.com/howard/resources/meshes/defaultAvatar_full.fst"; +var POLL_INTERVAL = 500; // ms +var SPREAD_MAX = 2; +var SPREAD_MIN = 0; +var SOUND_PAUSE_MAX = 10000; +var SOUND_PAUSE_MIN = 2000; + +function randInterval(min, max) { + return min + Math.random()*(max-min); +} + +Agent.isAvatar = true; +Agent.isListening = true; + +Avatar.skeletonModelURL = AVATAR_MODEL; +Avatar.position = { x: randInterval(SPREAD_MIN, SPREAD_MAX), + y: randInterval(SPREAD_MIN, SPREAD_MAX), + z: randInterval(SPREAD_MIN, SPREAD_MAX) +}; + +Avatar.startAnimation(ANIMATION_URL, 30, 1.0, true, false, 0, 300); + +var soundInterval = Script.setInterval(function () { + if (sound.downloaded) { + Script.clearInterval(soundInterval); + print("sound downloaded"); + // now play it in a loop until the end of time + Script.setInterval(function() { + print("playing sound"); + Agent.playAvatarSound(sound); + }, sound.duration + randInterval(SOUND_PAUSE_MIN, SOUND_PAUSE_MAX)); + } else { + print("waiting for sound to download..."); + } +}, POLL_INTERVAL); + diff --git a/hifi-content/howard/scripts/tests/performance/summon.js b/hifi-content/howard/scripts/tests/performance/summon.js new file mode 100644 index 000000000..29b61bf2c --- /dev/null +++ b/hifi-content/howard/scripts/tests/performance/summon.js @@ -0,0 +1,157 @@ +"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 = 3; +var label = "summon"; +function debug() { + print.apply(null, [].concat.apply([label, version], [].map.call(arguments, JSON.stringify))); +} + +var MINIMUM_AVATARS = 25; // 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 = 4; // How many of the agents should we request to play SOUND_DATA at once. + +var initialBubble = Users.getIgnoreRadiusEnabled(); +debug('startup seeking:', MINIMUM_AVATARS, 'listening:', N_LISTENING, 'chattering:', AVATARS_CHATTERING_AT_ONCE, 'had bubble:', initialBubble); + +// 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: "http://hifi-content.s3.amazonaws.com/howard/sounds/piano1.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]; +} + +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 = {}; + 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. + var avatarIdentifiers = without(AvatarList.getAvatarIdentifiers(), summonedAgents); + var nSummoned = summonedAgents.length; + debug('present', avatarIdentifiers, summonedAgents); + if ((nSummoned + 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); + messageSend({ + key: 'SUMMON', + rcpt: senderID, + displayName: "crowd " + nSummoned + " " + 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: "http://hifi-content.s3.amazonaws.com/howard/resources/meshes/defaultAvatar_full.fst", + animationData: ANIMATION_DATA + }); + } + }, accumulatedDelay); + accumulatedDelay += SPREAD_TIME_MS; // assume we'll get all the hello responses 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); + Users.requestsDomainListData = false; + if (initialBubble && !Users.getIgnoreRadiusEnabled()) { Users.toggleIgnoreRadius(); } + 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'); +}); + +Users.requestsDomainListData = true; // Get avatar data for the whole domain, even if not in our view. +if (initialBubble) { Users.toggleIgnoreRadius(); } +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?v=someDate\n\ +on your domain server."); + } else if (total < MINIMUM_AVATARS) { + Window.alert("Only " + summonedAgents.length + " agents reported. Now missing " + (MINIMUM_AVATARS - total) + " avatars, total."); + } + Users.requestsDomainListData = false; +}, MINIMUM_AVATARS * SPREAD_TIME_MS ) diff --git a/hifi-content/howard/sounds/hello.wav b/hifi-content/howard/sounds/hello.wav new file mode 100644 index 000000000..a995e7d65 --- /dev/null +++ b/hifi-content/howard/sounds/hello.wav @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6bbd7c78a54c8b62d509c102301a2c4647d4450abe314b2c3f869d755bdfacf9 +size 231196 diff --git a/hifi-content/howard/sounds/piano1.wav b/hifi-content/howard/sounds/piano1.wav new file mode 100644 index 000000000..57de26dcf --- /dev/null +++ b/hifi-content/howard/sounds/piano1.wav @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f0c3614f197c953bf2abfddfd262ede87b94d195afb4d5a32aa1bcbbee5e38a0 +size 605468 diff --git a/hifi-content/howard/zaru-content-custom-scripts.zip b/hifi-content/howard/zaru-content-custom-scripts.zip new file mode 100644 index 000000000..35ccca50a --- /dev/null +++ b/hifi-content/howard/zaru-content-custom-scripts.zip @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3afc07ec2d54a3e4f8d4c63a2348c98319184bf20ab0b14eea1e6cf183b248c4 +size 57483884 diff --git a/hifi-content/howard/zaru-content-default-scripts.zip b/hifi-content/howard/zaru-content-default-scripts.zip new file mode 100644 index 000000000..d16b101b9 --- /dev/null +++ b/hifi-content/howard/zaru-content-default-scripts.zip @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:66cc1ca2df52b52db588d3a0b27d75a478648a5a4f3bbdea1905edbddef36563 +size 57483371 diff --git a/hifi-content/howell/Prototypes/Cartoony_Computer/CCTV_image-redigert.jpg b/hifi-content/howell/Prototypes/Cartoony_Computer/CCTV_image-redigert.jpg new file mode 100644 index 000000000..31cbf3738 --- /dev/null +++ b/hifi-content/howell/Prototypes/Cartoony_Computer/CCTV_image-redigert.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:90f6c2a8798894aaa28d56638ea63e0beed0baf83bc76876046cc3c1cc52179c +size 554614 diff --git a/hifi-content/howell/Prototypes/Cartoony_Computer/Cartoony_Computer.FBX b/hifi-content/howell/Prototypes/Cartoony_Computer/Cartoony_Computer.FBX new file mode 100644 index 000000000..75593922e --- /dev/null +++ b/hifi-content/howell/Prototypes/Cartoony_Computer/Cartoony_Computer.FBX @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2c975e55ed89259df4ec3ea70a6cab91d10b5dacb705c6de7f2fb60b211324fc +size 536048 diff --git a/hifi-content/howell/Prototypes/Cartoony_Computer/Cartoony_Computer.max b/hifi-content/howell/Prototypes/Cartoony_Computer/Cartoony_Computer.max new file mode 100644 index 000000000..8f8340149 --- /dev/null +++ b/hifi-content/howell/Prototypes/Cartoony_Computer/Cartoony_Computer.max @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:443d4bc32914392ae60cf9eb5dae38188b3fc3afb5fd23601d03b489520894e2 +size 1925120 diff --git a/hifi-content/howell/Prototypes/Cartoony_Computer/Cartoony_Computer.mtl b/hifi-content/howell/Prototypes/Cartoony_Computer/Cartoony_Computer.mtl new file mode 100644 index 000000000..914a843e5 --- /dev/null +++ b/hifi-content/howell/Prototypes/Cartoony_Computer/Cartoony_Computer.mtl @@ -0,0 +1,84 @@ +# 3ds Max Wavefront OBJ Exporter v0.97b - (c)2007 guruware +# File Created: 19.03.2013 20:37:19 + +newmtl Material__223 + Ns 10.0000 + Ni 1.5000 + d 1.0000 + Tr 0.0000 + Tf 1.0000 1.0000 1.0000 + illum 2 + Ka 0.5880 0.5880 0.5880 + Kd 0.7765 0.7765 0.7765 + Ks 0.0000 0.0000 0.0000 + Ke 0.0000 0.0000 0.0000 + +newmtl CCTV_screen + Ns 10.0000 + Ni 1.5000 + d 1.0000 + Tr 0.0000 + Tf 1.0000 1.0000 1.0000 + illum 2 + Ka 0.5880 0.5880 0.5880 + Kd 0.1137 0.1137 0.1137 + Ks 0.0000 0.0000 0.0000 + Ke 0.0978 0.0978 0.0978 + map_Ka F:\shared\TurboSquid\Free\Computer\maps\CCTV_image-redigert.jpg + map_Kd F:\shared\TurboSquid\Free\Computer\maps\CCTV_image-redigert.jpg + +newmtl Material__225 + Ns 10.0000 + Ni 1.5000 + d 1.0000 + Tr 0.0000 + Tf 1.0000 1.0000 1.0000 + illum 2 + Ka 0.5880 0.5880 0.5880 + Kd 0.4275 0.4275 0.4275 + Ks 0.0000 0.0000 0.0000 + Ke 0.0000 0.0000 0.0000 + +newmtl Computer_screen + Ns 10.0000 + Ni 1.5000 + d 1.0000 + Tr 0.0000 + Tf 1.0000 1.0000 1.0000 + illum 2 + Ka 0.5880 0.5880 0.5880 + Kd 0.8784 0.8549 0.8118 + Ks 0.0000 0.0000 0.0000 + Ke 0.0000 0.0000 0.0000 + +newmtl wire_154215229 + Ns 32 + d 1 + Tr 0 + Tf 1 1 1 + illum 2 + Ka 0.6039 0.8431 0.8980 + Kd 0.6039 0.8431 0.8980 + Ks 0.3500 0.3500 0.3500 + +newmtl wire_177088027 + Ns 32 + d 1 + Tr 0 + Tf 1 1 1 + illum 2 + Ka 0.6941 0.3451 0.1059 + Kd 0.6941 0.3451 0.1059 + Ks 0.3500 0.3500 0.3500 + +newmtl RedButton + Ns 10.0000 + Ni 1.5000 + d 1.0000 + Tr 0.0000 + Tf 1.0000 1.0000 1.0000 + illum 2 + Ka 0.5880 0.5880 0.5880 + Kd 1.0000 0.0000 0.0000 + Ks 0.0000 0.0000 0.0000 + Ke 0.0000 0.0000 0.0000 diff --git a/hifi-content/howell/Prototypes/Cartoony_Computer/Cartoony_Computer.obj b/hifi-content/howell/Prototypes/Cartoony_Computer/Cartoony_Computer.obj new file mode 100644 index 000000000..8ce0e9c4f --- /dev/null +++ b/hifi-content/howell/Prototypes/Cartoony_Computer/Cartoony_Computer.obj @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c62744991df8b49dfe081027be0aacbc066864f401e4d15fd0845d3026de3cbc +size 952242 diff --git a/hifi-content/howell/Prototypes/Cartoony_Computer/Cartoony_Computer[max2010].max b/hifi-content/howell/Prototypes/Cartoony_Computer/Cartoony_Computer[max2010].max new file mode 100644 index 000000000..63454eedd --- /dev/null +++ b/hifi-content/howell/Prototypes/Cartoony_Computer/Cartoony_Computer[max2010].max @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:950ac518d51b84869f080e6c7c14d62f181475b6ef7422d5520e3574a77777e5 +size 1761280 diff --git a/hifi-content/howell/Prototypes/GOT/GOT.png b/hifi-content/howell/Prototypes/GOT/GOT.png new file mode 100644 index 000000000..baf7e0353 --- /dev/null +++ b/hifi-content/howell/Prototypes/GOT/GOT.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e85deb385b86801c5c5cf0dccafa187c3cc1d9c84b3f8d515e0ca2ac588b747f +size 98997 diff --git a/hifi-content/howell/Prototypes/GOT/drogon finished with base2.obj b/hifi-content/howell/Prototypes/GOT/drogon finished with base2.obj new file mode 100644 index 000000000..8be9a77bc --- /dev/null +++ b/hifi-content/howell/Prototypes/GOT/drogon finished with base2.obj @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ceaa61bde404e2621e5ddbcbbf18224fc1a4d1207093bb5dca55b75c46e7d47d +size 30302889 diff --git a/hifi-content/howell/Prototypes/GOT/drogon-statue.fbx b/hifi-content/howell/Prototypes/GOT/drogon-statue.fbx new file mode 100644 index 000000000..8ac488408 --- /dev/null +++ b/hifi-content/howell/Prototypes/GOT/drogon-statue.fbx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:df2e239a3abb3797ece2ddfaca17e7103f0d14aeaa1969d657a474545e0f411c +size 17763132 diff --git a/hifi-content/howell/Prototypes/Idle_app/Hanging Idle.fbx b/hifi-content/howell/Prototypes/Idle_app/Hanging Idle.fbx new file mode 100644 index 000000000..7643ae8c6 --- /dev/null +++ b/hifi-content/howell/Prototypes/Idle_app/Hanging Idle.fbx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:93019adf0763112f7082d6e1475f2c4f09f7c34fc3f02fd052cd772935f6b5df +size 439568 diff --git a/hifi-content/howell/Prototypes/Idle_app/Happy.fbx b/hifi-content/howell/Prototypes/Idle_app/Happy.fbx new file mode 100644 index 000000000..e5356ea7f --- /dev/null +++ b/hifi-content/howell/Prototypes/Idle_app/Happy.fbx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b9c35753b396373d6646521a69bbca9b9bc8d4e24992925ffdc1941b07c2c9f1 +size 531520 diff --git a/hifi-content/howell/Prototypes/Idle_app/Male Laying Pose.fbx b/hifi-content/howell/Prototypes/Idle_app/Male Laying Pose.fbx new file mode 100644 index 000000000..28395a95f --- /dev/null +++ b/hifi-content/howell/Prototypes/Idle_app/Male Laying Pose.fbx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fb9e60eef42c9c5144fd419c8eb00c8c8a79be1dd18ae91ffe9e65383973d725 +size 210944 diff --git a/hifi-content/howell/Prototypes/Idle_app/Ninja Idle.fbx b/hifi-content/howell/Prototypes/Idle_app/Ninja Idle.fbx new file mode 100644 index 000000000..9d7887e20 --- /dev/null +++ b/hifi-content/howell/Prototypes/Idle_app/Ninja Idle.fbx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a580d6c309a0fa3fe1ddba1f41c60693c2573f4203026945cbe583972cad836e +size 652512 diff --git a/hifi-content/howell/Prototypes/Idle_app/Push Up.fbx b/hifi-content/howell/Prototypes/Idle_app/Push Up.fbx new file mode 100644 index 000000000..c14ddde70 --- /dev/null +++ b/hifi-content/howell/Prototypes/Idle_app/Push Up.fbx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2828190ed38048d7387a169b3f34ecf4a34a0830527c062590326dd63767bf96 +size 331072 diff --git a/hifi-content/howell/Prototypes/Idle_app/mat_laying.fbx b/hifi-content/howell/Prototypes/Idle_app/mat_laying.fbx new file mode 100644 index 000000000..f17e21e54 --- /dev/null +++ b/hifi-content/howell/Prototypes/Idle_app/mat_laying.fbx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:82be489c57ba5f8ccc90f4fde4214b980cb28e4b610888ea5ff456ed7ebc15b2 +size 210944 diff --git a/hifi-content/howell/Prototypes/JAT_test/JATScritp.js b/hifi-content/howell/Prototypes/JAT_test/JATScritp.js new file mode 100644 index 000000000..6cded211d --- /dev/null +++ b/hifi-content/howell/Prototypes/JAT_test/JATScritp.js @@ -0,0 +1,344 @@ +// +// JATAvatarScript.js +// +// Rezzes JAT's avatars as Overlays, and handle clicking on them. +// +// Created by Zach Fox on 2019-03-15 +// Copyright 2019 High Fidelity, Inc. +// +// See accompanying README.md for usage instructions. +// +// 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 BASE_RELATIVE_POSITION = {"x":20.9303035736084,"y":-11.449395179748535,"z":-50.0930061340332}; + + var config = Script.require(Script.resolvePath("config.json?" + Date.now())); + + var AVATAR_OVERLAY_PROPERTIES = [ + { + "type": "Model", + "name": config.avatars[0].name, + "position": { + "x": 0.8213138580322266, + "y": 0.022147178649902344, + "z": 0.5046806335449219 + }, + "dimensions": { + "x": 0.4687473773956299, + "y": 0.797889769077301, + "z": 0.3429218530654907 + }, + "rotation": { + "x": -0.0000457763671875, + "y": -0.2866712212562561, + "z": -0.0000152587890625, + "w": 0.9580377340316772 + }, + "url": config.avatars[0].url, + "isFacingAvatar": false + }, + { + "id": "{d8ad1d89-038e-43c2-87dc-6d38988a71a4}", + "type": "Model", + "name": config.avatars[1].name, + "position": { + "x": 2.492778778076172, + "y": 0.08696365356445312, + "z": 2.8273887634277344 + }, + "dimensions": { + "x": 0.5626906156539917, + "y": 0.9782152771949768, + "z": 0.20142969489097595 + }, + "rotation": { + "x": 0.0000152587890625, + "y": 0.5656976699829102, + "z": -0.0000457763671875, + "w": -0.8246127963066101 + }, + "url": config.avatars[1].url, + "isFacingAvatar": false + }, + { + "id": "{ac2a7754-eec7-4bb6-9550-3af9caa970c9}", + "type": "Model", + "name": config.avatars[2].name, + "position": { + "x": 1.6198616027832031, + "y": 0.17209148406982422, + "z": 1.1371917724609375 + }, + "dimensions": { + "x": 1.1117140054702759, + "y": 0.8896834254264832, + "z": 0.6230975985527039 + }, + "rotation": { + "x": -0.0000457763671875, + "y": -0.423941433429718, + "z": -0.0000457763671875, + "w": 0.9056992530822754 + }, + "url": config.avatars[2].url, + "isFacingAvatar": false + }, + { + "id": "{0b261ed8-4c78-40db-915d-951b819821f5}", + "type": "Model", + "name": config.avatars[3].name, + "position": { + "x": 0, + "y": 0.12828731536865234, + "z": 0 + }, + "dimensions": { + "x": 1.0574196577072144, + "y": 1.1382946968078613, + "z": 0.27917155623435974 + }, + "rotation": { + "x": -0.0000457763671875, + "y": -0.22655069828033447, + "z": -0.0000152587890625, + "w": 0.9739986658096313 + }, + "url": config.avatars[3].url, + "isFacingAvatar": false + }, + { + "id": "{57168289-d40e-467a-8154-c9f1c6868615}", + "type": "Model", + "name": config.avatars[4].name, + "position": { + "x": 2.1323165893554688, + "y": 0, + "z": 2.091522216796875 + }, + "dimensions": { + "x": 0.667604386806488, + "y": 0.8386905193328857, + "z": 0.1569727063179016 + }, + "rotation": { + "x": 0.0000152587890625, + "y": 0.5126268863677979, + "z": -0.0000762939453125, + "w": -0.8586099147796631 + }, + "url": config.avatars[4].url, + "isFacingAvatar": false + } + ]; + + var BUTTON_DIMENSIONS = {"x": 0.2, "y": 0.2, "z": 0.2}; + var BUTTON_ROTATION = Quat.fromPitchYawRollDegrees(180, 140, 180); + var BUTTON_ROTATION_PREV = Quat.fromPitchYawRollDegrees(180, -140, 0); + + var CONTROL_BUTTON_PROPERTIES = [ + { + "name": "play", + "url": "https://hifi-content.s3.amazonaws.com/alan/dev/playback_play-button.fbx", + "position": { + "x": 16.6961, + "y": -11.1147, + "z": -48.6680 + }, + "dimensions": BUTTON_DIMENSIONS, + "rotation": BUTTON_ROTATION + }, + { + "name": "pause", + "url": "https://hifi-content.s3.amazonaws.com/alan/dev/playback_pause-button.fbx", + "position": { + "x": 17.1057, + "y": -11.1149, + "z": -48.9547 + }, + "dimensions": BUTTON_DIMENSIONS, + "rotation": BUTTON_ROTATION + }, + { + "name": "previous", + "url": "https://hifi-content.s3.amazonaws.com/alan/dev/playback_ff-rw-button.fbx", + "position": { + "x": 17.5153, + "y": -11.1150, + "z": -49.2414 + }, + "dimensions": BUTTON_DIMENSIONS, + "rotation": BUTTON_ROTATION_PREV + }, + { + "name": "next", + "url": "https://hifi-content.s3.amazonaws.com/alan/dev/playback_ff-rw-button.fbx", + "position": { + "x": 17.9249, + "y": -11.1151, + "z": -49.5279 + }, + "dimensions": BUTTON_DIMENSIONS, + "rotation": BUTTON_ROTATION + } + ]; + + var TEXT_OVERLAY_PROPERTIES = { + "name": "text", + "lineHeight": 0.10, + "backgroundAlpha": 0.75, + "position": { + "x": 15.7621, + "y": -11.3145, + "z": -48.2583 + }, + "rotation": BUTTON_ROTATION, + "dimensions": { + "x": 1.5, + "y": 0.25, + "z": 1 + }, + "topMargin": 0, + "rightMargin": 0, + "bottomMargin": 0, + "leftMargin": 0 + }; + + var METERS_TO_INCHES = 39.3701; + var WEB_OVERLAY_PROPERTIES = { + "rotation": BUTTON_ROTATION, + "dimensions": { + "x": 1, + "y": 1, + "z": 0 + }, + "position": { + "x": 18.8594, + "y": -11.3154, + "z": -50.4261 + }, + "url": config.screenleapURL, + "dpi": 1920 / (3 * METERS_TO_INCHES), + "alpha": 0.75 + }; + + var rezzedAvatarOverlays = []; + function rezAvatarOverlays() { + for (var i = 0; i < AVATAR_OVERLAY_PROPERTIES.length; i++) { + var currentProps = AVATAR_OVERLAY_PROPERTIES[i]; + currentProps.position = Vec3.sum(currentProps.position, BASE_RELATIVE_POSITION); + console.log("Rezzing overlay with name " + + AVATAR_OVERLAY_PROPERTIES[i].name + " at " + JSON.stringify(currentProps.position)); + rezzedAvatarOverlays.push(Overlays.addOverlay("model", currentProps)); + } + } + + var rezzedControlButtonOverlays = []; + function rezVideoControlButtons() { + for (var i = 0; i < CONTROL_BUTTON_PROPERTIES.length; i++) { + var currentProps = CONTROL_BUTTON_PROPERTIES[i]; + console.log("Rezzing overlay with name " + + CONTROL_BUTTON_PROPERTIES[i].name + " at " + JSON.stringify(currentProps.position)); + rezzedControlButtonOverlays.push(Overlays.addOverlay("model", currentProps)); + } + } + + var textOverlay = false; + function rezTextOverlay() { + console.log("Rezzing overlay with name " + + TEXT_OVERLAY_PROPERTIES.name + " at " + JSON.stringify(TEXT_OVERLAY_PROPERTIES.position)); + textOverlay = Overlays.addOverlay("text3d", TEXT_OVERLAY_PROPERTIES); + } + + var webOverlay = false; + function rezWebOverlay() { + console.log("Rezzing overlay with name " + + WEB_OVERLAY_PROPERTIES.name + " at " + JSON.stringify(WEB_OVERLAY_PROPERTIES.position)); + webOverlay = Overlays.addOverlay("web3d", WEB_OVERLAY_PROPERTIES); + } + + function startup() { + console.log("Welcome to rezJATAvatars.js!"); + + rezAvatarOverlays(); + rezVideoControlButtons(); + rezTextOverlay(); + rezWebOverlay(); + } + + function onScriptEnding() { + for (var i = 0; i < rezzedAvatarOverlays.length; i++) { + console.log("Deleting local entity with ID " + rezzedAvatarOverlays[i]); + Overlays.deleteOverlay(rezzedAvatarOverlays[i]); + } + for (i = 0; i < rezzedAvatarOverlays.length; i++) { + console.log("Deleting local entity with ID " + rezzedControlButtonOverlays[i]); + Overlays.deleteOverlay(rezzedControlButtonOverlays[i]); + } + + if (textOverlay) { + Overlays.deleteOverlay(textOverlay); + } + + if (webOverlay) { + Overlays.deleteOverlay(webOverlay); + } + + Overlays.mousePressOnOverlay.disconnect(onMousePressOnOverlay); + } + + var MESSAGE_CHANNEL = config.controlsMessageChannel; + function handleControlButtonPress(id) { + var name = Overlays.getProperties(id, ["name"]).name; + + switch (name) { + case "play": + Messages.sendMessage(MESSAGE_CHANNEL, 'play'); + break; + + case "pause": + Messages.sendMessage(MESSAGE_CHANNEL, 'pause'); + break; + + case "previous": + Messages.sendMessage(MESSAGE_CHANNEL, 'previous'); + break; + + case "next": + Messages.sendMessage(MESSAGE_CHANNEL, 'next'); + break; + + default: + console.log("Unhandled button overlay pressed"); + } + } + + var STATUS_MESSAGE_CHANNEL = config.statusMessageChannel; + function onMessageReceived(channel, message) { + if (channel === STATUS_MESSAGE_CHANNEL && textOverlay){ + console.log("message", message); + Overlays.editOverlay(textOverlay, {text: message}); + } + } + + function onMousePressOnOverlay(id, event) { + if (!event.button === "Primary") { + return; + } + + if (rezzedAvatarOverlays.indexOf(id) > -1) { + var modelURL = Overlays.getProperties(id, ["url"]).url; + MyAvatar.useFullAvatarURL(modelURL); + } else if (rezzedControlButtonOverlays.indexOf(id) > -1) { + handleControlButtonPress(id); + } + } + + Overlays.mousePressOnOverlay.connect(onMousePressOnOverlay); + Script.scriptEnding.connect(onScriptEnding); + Messages.subscribe(STATUS_MESSAGE_CHANNEL); + Messages.messageReceived.connect(onMessageReceived); + startup(); +})(); diff --git a/hifi-content/howell/Prototypes/JAT_test/config.json b/hifi-content/howell/Prototypes/JAT_test/config.json new file mode 100644 index 000000000..c587d53fe --- /dev/null +++ b/hifi-content/howell/Prototypes/JAT_test/config.json @@ -0,0 +1,27 @@ +{ + "avatars": [ + { + "name": "Andy1", + "url": "https://raw.githubusercontent.com/AndySeattle/Avatar/master/office_zombie_alive/office_zombie_alive.fst" + }, + { + "name": "Vacation", + "url": "https://raw.githubusercontent.com/AndySeattle/Avatar/master/Zombie_on_vacation/zombie_on_vacation_hifi.fst" + }, + { + "name": "Ice Hero", + "url": "http://mpassets.highfidelity.com/e238153a-21f4-4eba-8ab5-c6b10a0eb967-v1/avatar.fst" + }, + { + "name": "Ice Hero2", + "url": "http://mpassets.highfidelity.com/e238153a-21f4-4eba-8ab5-c6b10a0eb967-v1/avatar.fst" + }, + { + "name": "ice hero 3", + "url": http://mpassets.highfidelity.com/e238153a-21f4-4eba-8ab5-c6b10a0eb967-v1/avatar.fst" + } + ], + "screenleapURL": "", + "controlsMessageChannel": "", + "statusMessageChannel": "" +} \ No newline at end of file diff --git a/hifi-content/howell/Prototypes/andy_bot_bingos.js b/hifi-content/howell/Prototypes/andy_bot_bingos.js new file mode 100644 index 000000000..6a435366d --- /dev/null +++ b/hifi-content/howell/Prototypes/andy_bot_bingos.js @@ -0,0 +1,125 @@ +randFloat = function(low, high) { + return low + Math.random() * (high - low); +} + +var baseURL = "https://hifi-content.s3.amazonaws.com/milad/ROLC/Organize/Projects/Testing/Flow/out/hfr/"; + +// Link to get the urls from +var GOOGLE_SHEET_URL = "https://script.googleusercontent.com/a/macros/highfidelity.io/echo?user_content_key=z30W_Z9rqfb41pGEoxCkUM9yv8ZN8mxWuMyDWUHroj3cJ65OTSWNE_Zq7wvrTybnnFtRp6azMkya2K4Hj_UvG2HA9j2tP4Hjm5_BxDlH2jW0nuo2oDemN9CCS2h10ox_nRPgeZU6HP_Ok_bZ6q4uc2IEwUGUhs3tubd_SaoYEJGc6Y4WQVrmGLClD6RzMAfZPxqtsdMQ32tpzl66ygAELl7JpluoKw78VudcD_Dja5DuJzk35EV1vQ&lib=MzB5vcFo1OT_VNOUwG7287OYoCQvnAuFY"; +var rand = 10000; +var min = 2000; +var timeoutPeriod = Math.floor(Math.random()*rand)+min; + +var sheetXHR; +Script.setTimeout(function(){ + //console.log("about to run XHR"); + sheetXHR = new XHR(GOOGLE_SHEET_URL, sheetSuccess, sheetFailure); + +}, timeoutPeriod); +var TABLE = []; +var TOTAL_TO_GRAB = 100; + +function XHR(url, successCb, failureCb, TIMEOUT) { + //print("XHR: request url = " + url); + var self = this; + this.url = url; + this.successCb = successCb; + this.failureCb = failureCb; + this.req = new XMLHttpRequest(); + this.req.open("GET", url, true); + this.req.timeout = TIMEOUT; + this.req.ontimeout = function () { + if (self.failureCb) { + self.failureCb(0, "timeout"); + } + }; + this.req.onreadystatechange = function () { + if (self.req.readyState === self.req.DONE) { + if (self.req.status === 200 || self.req.status === 203) { + if (self.successCb) { + self.successCb(self.req.responseText); + } + } else { + if (self.failureCb) { + self.failureCb(self.req.status, "done"); + } + } + } + }; + this.req.send(); +} + +function baseName(str) { + var base = new String(str).substring(str.lastIndexOf('/') + 1); + if (base.lastIndexOf(".") !== -1) { + base = base.substring(0, base.lastIndexOf(".")); + } + return base; +} + +function sheetFailure(status, reason) { + //console.log("sheetFailure status code = " + status + ", reason = " + reason); +} + +function sheetSuccess(response) { + //console.log("sheetSuccess status, = "); + TABLE = JSON.parse(response); + TABLE.shift(); // strip off the header row. + for (var i = 0; i < TOTAL_TO_GRAB; i++){ + TABLE.map(function(recording){ + return baseName(TABLE[i].avatar_HFR); + }) + } + + var randomIndex = Math.floor((Math.random() * TABLE.length) % TABLE.length); + var RECORDING_URL = TABLE[randomIndex].avatar_HFR; + + var LOCATIONS_ARRAY = [{ min_x: -88, max_x: -66, y: -21, min_z: 2.8, max_z: 10 }]; + + var LOCATION_PARAMS = LOCATIONS_ARRAY[Math.floor(Math.random() * LOCATIONS_ARRAY.length)]; + + var LOCATION = { x: randFloat(LOCATION_PARAMS.min_x, LOCATION_PARAMS.max_x), y: LOCATION_PARAMS.y, z: randFloat(LOCATION_PARAMS.min_z, LOCATION_PARAMS.max_z) }; + + //Vec3.print("RANDOM LOCATION SELECTED:", LOCATION); + + // Disable the privacy bubble + Users.disableIgnoreRadius(); + + // Set position here if playFromCurrentLocation is true + Avatar.position = LOCATION; + Avatar.orientation = Quat.fromPitchYawRollDegrees(0, randFloat(0, 360), 0); + Avatar.scale = 1.0; + Agent.isAvatar = true; + + Recording.loadRecording(RECORDING_URL, function(success) { + if (success) { + Script.update.connect(update); + } else { + // print("Failed to load recording from " + RECORDING_URL); + } + }); +} + +count = 300; // Randomly wait some period of time before starting the recording +function update(event) { + if (count > 0) { + count--; + return; + } + + if (count == 0) { + Recording.setPlayFromCurrentLocation(true); + Recording.setPlayerLoop(true); + Recording.startPlaying(); + //Vec3.print("Playing from ", Avatar.position); + count--; + } + + EntityViewer.setPosition(Avatar.position); + EntityViewer.setOrientation(Avatar.orientation); + EntityViewer.queryOctree(); + + if (!Recording.isPlaying()) { + Script.update.disconnect(update); + } +} \ No newline at end of file diff --git a/hifi-content/howell/Prototypes/andy_bots.js b/hifi-content/howell/Prototypes/andy_bots.js new file mode 100644 index 000000000..4d0200259 --- /dev/null +++ b/hifi-content/howell/Prototypes/andy_bots.js @@ -0,0 +1,125 @@ +randFloat = function(low, high) { + return low + Math.random() * (high - low); +} + +var baseURL = "https://hifi-content.s3.amazonaws.com/milad/ROLC/Organize/Projects/Testing/Flow/out/hfr/"; + +// Link to get the urls from +var GOOGLE_SHEET_URL = "https://script.googleusercontent.com/a/macros/highfidelity.io/echo?user_content_key=z30W_Z9rqfb41pGEoxCkUM9yv8ZN8mxWuMyDWUHroj3cJ65OTSWNE_Zq7wvrTybnnFtRp6azMkya2K4Hj_UvG2HA9j2tP4Hjm5_BxDlH2jW0nuo2oDemN9CCS2h10ox_nRPgeZU6HP_Ok_bZ6q4uc2IEwUGUhs3tubd_SaoYEJGc6Y4WQVrmGLClD6RzMAfZPxqtsdMQ32tpzl66ygAELl7JpluoKw78VudcD_Dja5DuJzk35EV1vQ&lib=MzB5vcFo1OT_VNOUwG7287OYoCQvnAuFY"; +var rand = 10000; +var min = 2000; +var timeoutPeriod = Math.floor(Math.random()*rand)+min; + +var sheetXHR; +Script.setTimeout(function(){ + //console.log("about to run XHR"); + sheetXHR = new XHR(GOOGLE_SHEET_URL, sheetSuccess, sheetFailure); + +}, timeoutPeriod); +var TABLE = []; +var TOTAL_TO_GRAB = 100; + +function XHR(url, successCb, failureCb, TIMEOUT) { + //print("XHR: request url = " + url); + var self = this; + this.url = url; + this.successCb = successCb; + this.failureCb = failureCb; + this.req = new XMLHttpRequest(); + this.req.open("GET", url, true); + this.req.timeout = TIMEOUT; + this.req.ontimeout = function () { + if (self.failureCb) { + self.failureCb(0, "timeout"); + } + }; + this.req.onreadystatechange = function () { + if (self.req.readyState === self.req.DONE) { + if (self.req.status === 200 || self.req.status === 203) { + if (self.successCb) { + self.successCb(self.req.responseText); + } + } else { + if (self.failureCb) { + self.failureCb(self.req.status, "done"); + } + } + } + }; + this.req.send(); +} + +function baseName(str) { + var base = new String(str).substring(str.lastIndexOf('/') + 1); + if (base.lastIndexOf(".") !== -1) { + base = base.substring(0, base.lastIndexOf(".")); + } + return base; +} + +function sheetFailure(status, reason) { + //console.log("sheetFailure status code = " + status + ", reason = " + reason); +} + +function sheetSuccess(response) { + //console.log("sheetSuccess status, = "); + TABLE = JSON.parse(response); + TABLE.shift(); // strip off the header row. + for (var i = 0; i < TOTAL_TO_GRAB; i++){ + TABLE.map(function(recording){ + return baseName(TABLE[i].avatar_HFR); + }) + } + + var randomIndex = Math.floor((Math.random() * TABLE.length) % TABLE.length); + var RECORDING_URL = TABLE[randomIndex].avatar_HFR; + + var LOCATIONS_ARRAY = [{ min_x: -6, max_x: 21, y: -12, min_z: -57, max_z: -54 }]; + + var LOCATION_PARAMS = LOCATIONS_ARRAY[Math.floor(Math.random() * LOCATIONS_ARRAY.length)]; + + var LOCATION = { x: randFloat(LOCATION_PARAMS.min_x, LOCATION_PARAMS.max_x), y: LOCATION_PARAMS.y, z: randFloat(LOCATION_PARAMS.min_z, LOCATION_PARAMS.max_z) }; + + //Vec3.print("RANDOM LOCATION SELECTED:", LOCATION); + + // Disable the privacy bubble + Users.disableIgnoreRadius(); + + // Set position here if playFromCurrentLocation is true + Avatar.position = LOCATION; + Avatar.orientation = Quat.fromPitchYawRollDegrees(0, randFloat(0, 360), 0); + Avatar.scale = 1.0; + Agent.isAvatar = true; + + Recording.loadRecording(RECORDING_URL, function(success) { + if (success) { + Script.update.connect(update); + } else { + // print("Failed to load recording from " + RECORDING_URL); + } + }); +} + +count = 300; // Randomly wait some period of time before starting the recording +function update(event) { + if (count > 0) { + count--; + return; + } + + if (count == 0) { + Recording.setPlayFromCurrentLocation(true); + Recording.setPlayerLoop(true); + Recording.startPlaying(); + //Vec3.print("Playing from ", Avatar.position); + count--; + } + + EntityViewer.setPosition(Avatar.position); + EntityViewer.setOrientation(Avatar.orientation); + EntityViewer.queryOctree(); + + if (!Recording.isPlaying()) { + Script.update.disconnect(update); + } +} \ No newline at end of file diff --git a/hifi-content/howell/Prototypes/andy_bots_futvrelands.js b/hifi-content/howell/Prototypes/andy_bots_futvrelands.js new file mode 100644 index 000000000..4fb074a09 --- /dev/null +++ b/hifi-content/howell/Prototypes/andy_bots_futvrelands.js @@ -0,0 +1,203 @@ +// +// BetterClientSimulationBotFromRecording.js +// examples +// +// Created by Brad Hefta-Gaub on 2/6/17. +// Copyright 2017 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 +// + + +var WANT_DEBUGGING = false; + +randFloat = function(low, high) { + return low + Math.random() * (high - low); +} + +var MESSAGE_CHANNEL = "TriviaChannel"; + +var AVATARS_ARRAY = [ + "http://mpassets.highfidelity.com/0c2c264b-2fd2-46a4-bf80-de681881f66b-v1/F_MotRac.fst", + "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.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", + "http://mpassets.highfidelity.com/f3fbb9f4-e159-49ed-ac32-03af9056b17e-v1/matthew.fst", + "http://mpassets.highfidelity.com/0c954ba0-4d87-4353-b65e-c45509f85658-v1/priscilla.fst", + "http://mpassets.highfidelity.com/e76946cc-c272-4adf-9bb6-02cde0a4b57d-v1/9e8c5c42a0cbd436962d6bd36f032ab3.fst", + "http://mpassets.highfidelity.com/72e083ee-194d-4113-9c61-0591d8257493-v1/skeleton_Rigged.fst", + "http://mpassets.highfidelity.com/f14bf7c9-49a1-4249-988a-0a577ed78957-v1/beingOfLight.fst", + "http://mpassets.highfidelity.com/1b7e1e7c-6c0b-4f20-9cd0-1d5ccedae620-v1/bb64e937acf86447f6829767e958073c.fst", + "http://mpassets.highfidelity.com/67d7c7aa-c300-4d03-85f4-86480130eaa5-v1/F_StarCrew.fst", + "http://mpassets.highfidelity.com/d293ef06-c659-467a-9288-c3cbaff0372a-v1/arya_avatar.fst", + "http://mpassets.highfidelity.com/faf249d5-12a8-48e2-a08e-fb0c33087011-v1/F_Ranger.fst", + "http://mpassets.highfidelity.com/b4502145-15eb-4023-b7d6-a81c5cbf6abf-v1/F_FitTra.fst", + "http://mpassets.highfidelity.com/548d0792-0bac-4933-bbfc-57d71912d77e-v1/M_OutMer.fst", + "http://mpassets.highfidelity.com/caa61e5d-5629-4165-81d8-6a7eb55e942d-v1/F_DeaSur.fst", + "http://mpassets.highfidelity.com/2cad3894-8ab3-4ba5-a723-0234f93fbd6a-v1/M_BowBea.fst", + "http://mpassets.highfidelity.com/fd4fa45a-9d2a-463e-a484-f9d1b3bba724-v1/M_BeaWar.fst", + "http://mpassets.highfidelity.com/367a5b60-8a92-4d56-a152-a00f3086f02b-v1/M_Espio.fst", + "http://mpassets.highfidelity.com/ab466729-31da-4b4c-a33c-366f7c1d38e5-v1/M_MMAFig.fst", + "http://mpassets.highfidelity.com/b0795a0c-493d-4abd-b4cc-5f32e6d6df46-v1/M_SalMer.fst", + "http://mpassets.highfidelity.com/0a1d44bf-a988-4199-b29e-a532ab85a2e8-v1/M_StaShi.fst", + "http://mpassets.highfidelity.com/d807a7d2-5122-4436-a6f9-3173c94d1c49-v1/M_SuaGen.fst", + "http://mpassets.highfidelity.com/cb20212c-36f2-4d41-bdad-132361ca6ff4-v1/M_TreTee.fst", + "http://mpassets.highfidelity.com/830988dc-619a-4e88-96e1-a19fa0aaa30f-v1/M_UrbEnf.fst", + "http://mpassets.highfidelity.com/faf505f1-4fd1-4ed2-8909-816af246c48f-v1/M_VicGen.fst", + "http://mpassets.highfidelity.com/883ac86f-dd29-4676-8bda-7dd52fb6465f-v1/M_WasWan.fst", + "http://mpassets.highfidelity.com/ede82c38-c66e-4f67-9e0b-0bb0782db18f-v1/M_WesOut.fst", + "http://mpassets.highfidelity.com/04c9a1e9-0390-4a7f-b6c6-5f135c19e3fb-v1/F_ArmTro.fst", + "http://mpassets.highfidelity.com/e863348f-a777-4f36-86e6-af6e65ffa161-v1/F_BloSam.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/da2ad4cd-47d4-41da-b764-41f39ff77e30-v1/F_JerGir.fst", + "http://mpassets.highfidelity.com/534d42f8-ec13-4145-929f-5c8facac2fb7-v1/F_LegFig.fst", + "http://mpassets.highfidelity.com/dc55803b-9215-47dd-9408-eb835dac4082-v1/F_ParGir.fst", + "http://mpassets.highfidelity.com/f823e831-d8c4-4191-a3bd-427e406e69f9-v1/F_Shinjuku.fst", + "http://mpassets.highfidelity.com/eba0d8f8-aa72-4a6b-ab64-4d3fd4695b20-v1/F_VogHei.fst", + "http://mpassets.highfidelity.com/13277c09-892f-4a5e-b9a5-8994a37d68bf-v1/F_WasWar.fst", + "http://mpassets.highfidelity.com/9b589fbb-59e4-47a9-8b3f-bf8d3a0bd1d8-v1/M_LawSur.fst", + "http://mpassets.highfidelity.com/4f400c78-38f9-42af-b03b-11b5451d41b9-v1/M_MidRog.fst", + "http://mpassets.highfidelity.com/c90d755d-0456-48fd-b98c-09c4d85cd481-v1/M_MouOff.fst", + "http://mpassets.highfidelity.com/c2ed3b9a-b3a9-4424-9fd2-8a798209f32b-v1/M_PerTra.fst", + "http://mpassets.highfidelity.com/c48928ac-7657-41f4-bbdc-9b47385736ab-v1/M_SpaMar.fst", + "http://mpassets.highfidelity.com/d029ae8d-2905-4eb7-ba46-4bd1b8cb9d73-v1/4618d52e711fbb34df442b414da767bb.fst", + "http://mpassets.highfidelity.com/c85c497d-c87b-42b1-9bbf-5405e05a0ad3-v1/M_ArmSol.fst", + "http://mpassets.highfidelity.com/1dd41735-06f4-45a3-9ec0-d05215ace77b-v1/M_MarSen.fst", + "http://mpassets.highfidelity.com/bd80a6d7-7173-489e-87c6-f7ee56e65530-v1/M_RetFut.fst", + "http://mpassets.highfidelity.com/8872ae86-a763-4db3-8373-d27514c1481e-v1/M_VinAvi.fst", + "http://mpassets.highfidelity.com/f798d926-9a9e-481a-b298-af0e45451252-v1/F_Assassin.fst", + "http://mpassets.highfidelity.com/ad774d79-13f1-46e2-87c9-de49a261b264-v1/F_GunSli.fst", + "http://mpassets.highfidelity.com/aaa1b0a8-3e1b-492a-9aee-600e5dc907db-v1/F_RetSciSuit.fst" + ]; + + +var AVATAR_URL = AVATARS_ARRAY[Math.floor(Math.random() * AVATARS_ARRAY.length)]; +print("RANDOM AVATAR SELECTED:" + AVATAR_URL); + +var RECORDINGS_ARRAY = [ + "http://hifi-content.s3.amazonaws.com/DomainContent/Event%20/NPC%27s/waiting6.hfr", + "http://hifi-content.s3.amazonaws.com/DomainContent/Event%20/NPC%27s/waiting7.hfr", + "http://hifi-content.s3.amazonaws.com/DomainContent/Event%20/NPC%27s/waiting10.hfr", + "http://hifi-content.s3.amazonaws.com/DomainContent/Event%20/NPC%27s/bot1.hfr", + "http://hifi-content.s3.amazonaws.com/DomainContent/Event%20/NPC%27s/bot2.hfr", + "http://hifi-content.s3.amazonaws.com/DomainContent/Event%20/NPC%27s/bot3.hfr", + "http://hifi-content.s3.amazonaws.com/DomainContent/Event%20/NPC%27s/bot4.hfr" + ]; + +var RECORDING_URL = RECORDINGS_ARRAY[Math.floor(Math.random() * RECORDINGS_ARRAY.length)]; +print("RANDOM RECORDING SELECTED:" + RECORDING_URL); + +// not quite what I want... +var LOCATIONS_ARRAY = [ + { min_x: -91, max_x: -40, y: -19.2, min_z: -1.8, max_z: 90 } +]; + +var LOCATION_PARAMS = LOCATIONS_ARRAY[Math.floor(Math.random() * LOCATIONS_ARRAY.length)]; + +var LOCATION = { x: randFloat(LOCATION_PARAMS.min_x, LOCATION_PARAMS.max_x), y: LOCATION_PARAMS.y, z: randFloat(LOCATION_PARAMS.min_z, LOCATION_PARAMS.max_z) }; + +Vec3.print("RANDOM LOCATION SELECTED:", LOCATION); + +var playFromCurrentLocation = true; +var loop = true; + +// Disable the privacy bubble +Users.disableIgnoreRadius(); + +// Set position here if playFromCurrentLocation is true +Avatar.position = LOCATION; +Avatar.orientation = Quat.fromPitchYawRollDegrees(1, 0, 0); +Avatar.scale = 1.0; +Agent.isAvatar = true; + +// make the agent "listen" to the audio stream to cause additional audio-mixer load, technically this isn't needed when you're playing a recording +// but if you switch to a non-recording bot, you will need this, so we can leave this. +Agent.isListeningToAudioStream = true; +Avatar.skeletonModelURL = AVATAR_URL; // FIXME - currently setting an avatar while playing a recording doesn't work it will be ignored + + +function messageLog(channel, sender, message) { + if (channel === MESSAGE_CHANNEL) { + print ("AC Bot at position: " + JSON.stringify(Avatar.position) + " received message on " + MESSAGE_CHANNEL); + } +} + +Recording.loadRecording(RECORDING_URL, function(success) { + if (success) { + Script.update.connect(update); + Messages.subscribe(MESSAGE_CHANNEL); + Messages.messageReceived.connect(messageLog); + } else { + print("Failed to load recording from " + RECORDING_URL); + } +}); + + +count = 300; // This is necessary to wait for the audio mixer to connect +function update(event) { + if (count > 0) { + count--; + return; + } + if (count == 0) { + Recording.setPlayFromCurrentLocation(playFromCurrentLocation); + Recording.setPlayerLoop(loop); + Recording.setPlayerUseDisplayName(true); + Recording.setPlayerUseAttachments(true); + Recording.setPlayerUseHeadModel(false); + Recording.setPlayerUseSkeletonModel(false); // FIXME - this would allow you to override the recording avatar, but that's not currently working + Recording.startPlaying(); + Vec3.print("Playing from ", Avatar.position); + count--; + } else if (WANT_DEBUGGING) { + count = 100; + Vec3.print("Avatar at: ", Avatar.position); + Quat.print("Avatar head orientation: ", Avatar.headOrientation); + print("outbound:" + +" GP: " + Avatar.getDataRate("globalPositionOutbound").toFixed(2) + "\n" + +" LP: " + Avatar.getDataRate("localPositionOutbound").toFixed(2) + "\n" + +" BB: " + Avatar.getDataRate("avatarBoundingBoxOutbound").toFixed(2) + "\n" + +" AO: " + Avatar.getDataRate("avatarOrientationOutbound").toFixed(2) + "\n" + +" AS: " + Avatar.getDataRate("avatarScaleOutbound").toFixed(2) + "\n" + +" LA: " + Avatar.getDataRate("lookAtPositionOutbound").toFixed(2) + "\n" + +" AL: " + Avatar.getDataRate("audioLoudnessOutbound").toFixed(2) + "\n" + +" SW: " + Avatar.getDataRate("sensorToWorkMatrixOutbound").toFixed(2) + "\n" + +" AF: " + Avatar.getDataRate("additionalFlagsOutbound").toFixed(2) + "\n" + +" PI: " + Avatar.getDataRate("parentInfoOutbound").toFixed(2) + "\n" + +" FT: " + Avatar.getDataRate("faceTrackerOutbound").toFixed(2) + "\n" + +" JD: " + Avatar.getDataRate("jointDataOutbound").toFixed(2)); + } + + if (!Recording.isPlaying()) { + Script.update.disconnect(update); + Messages.unsubscribe(MESSAGE_CHANNEL); + Messages.messageReceived.disconnect(messageLog); + } +} + +Script.scriptEnding.connect(function(){ + Messages.unsubscribe(MESSAGE_CHANNEL); +}); \ No newline at end of file diff --git a/hifi-content/howell/Prototypes/best_game.jpg b/hifi-content/howell/Prototypes/best_game.jpg new file mode 100644 index 000000000..21de3c1b5 --- /dev/null +++ b/hifi-content/howell/Prototypes/best_game.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5db32657baee0bfc6ccae71cfb87f81a5f9b40037bcb9d237543406a3fc5b517 +size 95702 diff --git a/hifi-content/howell/Prototypes/bot_player_content_v4/assignmentClientManager_andy_test.js b/hifi-content/howell/Prototypes/bot_player_content_v4/assignmentClientManager_andy_test.js new file mode 100644 index 000000000..ff04f194f --- /dev/null +++ b/hifi-content/howell/Prototypes/bot_player_content_v4/assignmentClientManager_andy_test.js @@ -0,0 +1,247 @@ +"use strict"; + +// +// Bot Player +// assignmentClientManager.js +// Created by Milad Nazeri on 2019-06-06 +// Copyright 2019 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 +// + + +(function() { + + // ************************************* + // START UTILITY FUNCTIONS + // ************************************* + // #region UTILITY FUNCTIONS + + + // Start playing sequence to fill players with bots + var AC_AVAILABILITY_CHECK_MS = 1000; + function startSequence() { + // Check to see how many bots are needed + if (botCount >= botsFound + 1) { + return; + } + + if (botCount < availableAssignmentClientPlayers.length) { + var player = availableAssignmentClientPlayers[botCount]; + player.play(); + botCount++; + + if (botCount >= botsFound + 1) { + return; + } + } + + Script.setTimeout(function() { + startSequence(); + }, AC_AVAILABILITY_CHECK_MS); + } + + + // Searching through the s3 bucket to grab which recordings are valid and stop as soon as we get an error + // Synchronous version of require + var BASE_PATH = "https://hifi-content.s3.amazonaws.com/howell/bots_new/"; + var MAX_BOTS_TO_TRY = 100; + var requestSync = Script.require("./requestSync.js").request; + var botsFound = 0; + function populateRecordingList(){ + for (var i = 1; i < MAX_BOTS_TO_TRY; i++) { + var botRecordingFound = true; + var currentBotUrl = BASE_PATH + "AVATAR_TEST" + i + ".hfr"; + requestSync(currentBotUrl, function(error){ + if (error) { + botRecordingFound = false; + } else { + botsFound++; + botList.push(currentBotUrl); + } + }); + if (!botRecordingFound) { + break; + } + } + } + + + // #endregion + // ************************************* + // END UTILITY FUNCTIONS + // ************************************* + + // ************************************* + // START CONSTS_AND_VARS + // ************************************* + // #region CONSTS_AND_VARS + + + // The Assignment Client channel + var ASSIGNMENT_MANAGER_CHANNEL = "ASSIGNMENT_MANAGER_CHANNEL"; + var ASSIGNMENT_CLIENT_MESSANGER_CHANNEL = "ASSIGNMENT_CLIENT_MESSANGER_CHANNEL"; + + // Array of the assignment client players and their assignment client player object + var availableAssignmentClientPlayers = []; + + // Current playing bot count we are at + var botCount = 0; + + // Current registered bount count + var botsRegisteredCount = 0; + + // Array of the recordings found + var botList = []; + + + // #endregion + // ************************************* + // END CONSTS_AND_VARS + // ************************************* + + // ************************************* + // START ASSIGNMENT_CLIENT_PLAYER + // ************************************* + // #region ASSIGNMENT_CLIENT_PLAYER + + + // Individual AssignmentClientPlayerObject + function AssignmentClientPlayerObject(uuid, fileToPlay, position, volume) { + this.uuid = uuid; + this.fileToPlay = fileToPlay; + } + + + // Play the current clip + function play() { + Messages.sendMessage(ASSIGNMENT_MANAGER_CHANNEL, JSON.stringify({ + action: "PLAY", + fileToPlay: this.fileToPlay, + uuid: this.uuid + })); + } + + + // Stop the current clip + function stop() { + Messages.sendMessage(ASSIGNMENT_MANAGER_CHANNEL, JSON.stringify({ + action: "STOP", + uuid: this.uuid + })); + } + + + AssignmentClientPlayerObject.prototype = { + play: play, + stop: stop + }; + + + // #endregion + // ************************************* + // END ASSIGNMENT_CLIENT_PLAYER + // ************************************* + + // ************************************* + // START MESSAGES + // ************************************* + // #region MESSAGES + + + // Handle Messages received + function onMangerChannelMessageReceived(channel, message, sender) { + if (channel !== ASSIGNMENT_MANAGER_CHANNEL || sender === Agent.sessionUUID) { + return; + } + + try { + message = JSON.parse(message); + } catch (error) { + console.log("invalid object"); + console.log("MESSAGE:", message); + return; + } + + switch (message.action) { + case "REGISTER_ME": + var fileName = botList[botsRegisteredCount]; + availableAssignmentClientPlayers.push( + new AssignmentClientPlayerObject(message.uuid, fileName)); + botsRegisteredCount++; + var messageToSend = JSON.stringify({ + action: "AC_AVAILABLE_UPDATE", + newAvailableACs: availableAssignmentClientPlayers.length + }); + Messages.sendMessage(ASSIGNMENT_CLIENT_MESSANGER_CHANNEL, messageToSend); + break; + case "ARE_YOU_THERE_MANAGER_ITS_ME_BOT": + Messages.sendMessage(ASSIGNMENT_MANAGER_CHANNEL, JSON.stringify({ + action: "REGISTER_MANAGER", + uuid: sender + })); + break; + default: + console.log("unrecognized action in assignmentClientManger.js"); + break; + } + } + + + // #endregion + // ************************************* + // END MESSAGES + // ************************************* + + // ************************************* + // START MAIN + // ************************************* + // #region MAIN + + + // Startup for the manager when it comes online + function startUp() { + Messages.subscribe(ASSIGNMENT_MANAGER_CHANNEL); + Messages.subscribe(ASSIGNMENT_CLIENT_MESSANGER_CHANNEL); + Messages.messageReceived.connect(onMangerChannelMessageReceived); + Script.scriptEnding.connect(onEnding); + populateRecordingList(); + startSequence(); + } + + startUp(); + + + // #endregion + // ************************************* + // END MAIN + // ************************************* + + // ************************************* + // START CLEANUP + // ************************************* + // #region CLEANUP + + + // Cleanup the manager and it's messages + function onEnding() { + Messages.messageReceived.disconnect(onMangerChannelMessageReceived); + var messageToSend = JSON.stringify({ + action: "GET_MANAGER_STATUS", + newAvailableACs: 0, + isPlaying: false, + closeTablet: true + }); + Messages.sendMessage(ASSIGNMENT_CLIENT_MESSANGER_CHANNEL, messageToSend); + Messages.unsubscribe(ASSIGNMENT_MANAGER_CHANNEL); + Messages.unsubscribe(ASSIGNMENT_CLIENT_MESSANGER_CHANNEL); + } + + + // #endregion + // ************************************* + // END CLEANUP + // ************************************* + +})(); diff --git a/hifi-content/howell/Prototypes/bouncer.js b/hifi-content/howell/Prototypes/bouncer.js new file mode 100644 index 000000000..ce54d5497 --- /dev/null +++ b/hifi-content/howell/Prototypes/bouncer.js @@ -0,0 +1,270 @@ +// +// ZoneScript.js +// +// This script serves as a virtual bouncer depending on username or whether or not a client can validate +// ownership of a particular specified avatar entity. Can one or all three methods: hardcoded list in APPROVED_USERNAMES, +// inside entity userData username list, and/or verifying an wearable marketplace entity through it's ID. +// +// Copyright 2017 High Fidelity, Inc. +// +// Set Up: +// 1. Add below userData object to zone entity userData +// 1. Fill in rejectTeleportLocation, example "/13.9828,-10.5277,0.0609192/0,0.460983,0,0.887409" +// 2. Optional: add marketplaceID of the item to verify +// 3. Optional: (can update while script is running): each username to add to whitelist +// 2. Add approved users to APPROVED_USERNAMES below, keep blank if not using +// 3. Add script to zone entity +// 4. Update userData at anytime to add more to usernames your whitelist +// +// Add this to the zone userData : +// { +// "whitelist" : { +// "rejectTeleportLocation" : "<>" +// "marketplaceID" : "<>", +// "usernames" : [""] +// }, +// "grabbableKey": { +// "grabbable": false +// } +// } +// +// whitelist - (required) contains variables for the zone +// rejectTeleportLocation - (required) rejected avatars are sent to these domain coordinates +// marketplaceID - (optional) marketplace item id for marketplace item verification +// usernames - (optional) array for usernames to be added while script is running +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html + +/* globals Entities, Wallet, Window, AccountServices */ + +(function () { + + // username lookup variables + var APPROVED_USERNAMES = []; // hardcoded + var whitelist = []; // stores lowercase usernames from APPROVED_USERNAMES + + // usernames inside userData + var _usernames; // userData names + + // marketplace lookup variables + var WEARABLE_SEARCH_RADIUS = 10; + var foundValidTestable = false; + var _foundEntityID = -1; + var _passMarketplaceID; + var _userDataProperties; + var _backupLocation; + + var _entityID; + var LOAD_TIME = 50; + var avatarCheckStep = 0; + var HALF = 0.5; + var DEBUG = false; + + var marketplaceItem = { + + verificationSuccess: function (entityID) { + if (DEBUG) { + print("You may enter - verification passed for entity: " + entityID); + } + Wallet.ownershipVerificationSuccess.disconnect(this.verificationSuccess); + Wallet.ownershipVerificationFailed.disconnect(this.verificationFailed); + }, + + verificationFailed: function (entityID) { + if (DEBUG) { + print("You may not enter - verification failed for entity: " + entityID); + } + utils.rejectTeleportAvatar(); + Wallet.ownershipVerificationSuccess.disconnect(this.verificationSuccess); + Wallet.ownershipVerificationFailed.disconnect(this.verificationFailed); + }, + + verifyAvatarOwnership: function (entityID) { + Wallet.proveAvatarEntityOwnershipVerification(entityID); + }, + searchForMatchingItem: function () { + Entities.findEntitiesByType('Model', MyAvatar.position, WEARABLE_SEARCH_RADIUS).forEach(function (entityID) { + var properties = Entities.getEntityProperties(entityID, ['marketplaceID', 'certificateID', 'parentID']); + if (properties.marketplaceID === _passMarketplaceID && properties.parentID === MyAvatar.sessionUUID) { + _foundEntityID = entityID; + foundValidTestable = true; + this.verifyAvatarOwnership(_foundEntityID); + Wallet.ownershipVerificationSuccess.connect(this.verificationSuccess); + Wallet.ownershipVerificationFailed.connect(this.verificationFailed); + } + }); + if (!foundValidTestable) { + utils.rejectTeleportAvatar(); + } + } + }; + + var avatarUserName = { + isOnWhitelist: function () { + var username = AccountServices.username.toLowerCase(); + if (whitelist.indexOf(username) >= 0) { + if (DEBUG) { + print("Username is on hardcoded whitelist"); + } + return true; + } else { + return false; + } + }, + isInUserData: function () { + var username = AccountServices.username.toLowerCase(); + + for (var i = 0; i < _usernames.length; i++) { + if (_usernames[i].toLowerCase() === username) { + if (DEBUG) { + print("Username is on userData whitelist"); + } + return true; + } + } + return false; + } + }; + + var utils = { + + updateUserData: function () { + try { + _userDataProperties = JSON.parse(Entities.getEntityProperties(_entityID, 'userData').userData); + } catch (err) { + console.error("Error parsing userData: ", err); + } + + _usernames = _userDataProperties.whitelist && _userDataProperties.whitelist.usernames || []; + }, + + rejectTeleportAvatar: function () { + if (DEBUG) { + print("Rejected from zone to: ", _backupLocation); + } + Window.location.handleLookupString(_backupLocation); + }, + + largestAxisVec: function (dimensions) { + var max = Math.max(dimensions.x, dimensions.y, dimensions.z); + return max; + }, + + isInEntity: function () { + var properties = Entities.getEntityProperties(_entityID, ["position", "dimensions", "rotation"]); + var position = properties.position; + var dimensions = properties.dimensions; + + var avatarPosition = MyAvatar.position; + var worldOffset = Vec3.subtract(avatarPosition, position); + + avatarPosition = Vec3.multiplyQbyV(Quat.inverse(properties.rotation), worldOffset); + + var minX = 0 - dimensions.x * HALF; + var maxX = 0 + dimensions.x * HALF; + var minY = 0 - dimensions.y * HALF; + var maxY = 0 + dimensions.y * HALF; + var minZ = 0 - dimensions.z * HALF; + var maxZ = 0 + dimensions.z * HALF; + + if (avatarPosition.x >= minX && avatarPosition.x <= maxX + && avatarPosition.y >= minY && avatarPosition.y <= maxY + && avatarPosition.z >= minZ && avatarPosition.z <= maxZ) { + + if (DEBUG) { + print("Avatar is inside zone"); + } + return true; + + } else { + + if (DEBUG) { + print("Avatar is NOT in zone"); + } + return false; + } + } + + }; + + var ProtectedZone = function () { + + }; + + ProtectedZone.prototype = { + + preload: function (entityID) { + _entityID = entityID; + var _this = this; + + + if (APPROVED_USERNAMES.length > 0) { + APPROVED_USERNAMES.forEach(function (username) { + whitelist.push(username.toLowerCase()); + }); + } + + utils.updateUserData(); + + Script.setTimeout(function () { + if (_userDataProperties.whitelist) { + + _passMarketplaceID = _userDataProperties.whitelist.marketplaceID || ""; + _backupLocation = _userDataProperties.whitelist.rejectTeleportLocation; + _usernames = _userDataProperties.whitelist.usernames || []; + + } + _this.insideEntityCheck(); + + }, LOAD_TIME); + + }, + insideEntityCheck: function () { + // ensures every avatar experiences the enterEntity method + var properties = Entities.getEntityProperties(_entityID, ["position", "dimensions"]); + var largestDimension = utils.largestAxisVec(properties.dimensions); + var avatarsInRange = AvatarList.getAvatarsInRange(properties.position, largestDimension).filter(function(id) { + return id === MyAvatar.sessionUUID; + }); + + if (avatarsInRange.length > 0) { + if (DEBUG) { + print("Found avatar near zone: ", avatarCheckStep); + } + // do isInZone check + if (utils.isInEntity()) { + this.enterEntity(); + } + } + }, + enterEntity: function () { + + utils.updateUserData(); + + Script.setTimeout(function () { + + var isInUserData = avatarUserName.isInUserData(); + + if (isInUserData || (APPROVED_USERNAMES.length > 0 && avatarUserName.isOnWhitelist())) { + // do nothing + } else { + // did not pass username tests + if (_passMarketplaceID) { + // if marketplaceID exists look for item + foundValidTestable = false; + marketplaceItem.searchForMatchingItem(); // will reject within function + } else { + // otherwise reject avatar + utils.rejectTeleportAvatar(); + } + } + + }, LOAD_TIME); + + } + }; + + return new ProtectedZone(); + +}); \ No newline at end of file diff --git a/hifi-content/howell/Prototypes/crabble.png b/hifi-content/howell/Prototypes/crabble.png new file mode 100644 index 000000000..b41fe4da9 --- /dev/null +++ b/hifi-content/howell/Prototypes/crabble.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:96d1d7254d45ddbaf8aa8dc1e07c2301a98295a74a6fb797c344b6fb69f82fb0 +size 9172 diff --git a/hifi-content/howell/Prototypes/dog_skull/dogskull.mtl b/hifi-content/howell/Prototypes/dog_skull/dogskull.mtl new file mode 100644 index 000000000..e32b28f43 --- /dev/null +++ b/hifi-content/howell/Prototypes/dog_skull/dogskull.mtl @@ -0,0 +1,14 @@ +# +# Wavefront material file +# Created in RealityCapture v1.0.3.4658 +# www.capturingreality.com +# + + +newmtl dogskull_Material_u1_v1 +Ka 1 1 1 +Kd 1 1 1 +d 1 +Ns 0 +illum 1 +map_Kd dogskull_u1_v1.jpg diff --git a/hifi-content/howell/Prototypes/dog_skull/dogskull.obj b/hifi-content/howell/Prototypes/dog_skull/dogskull.obj new file mode 100644 index 000000000..aac6fb09b --- /dev/null +++ b/hifi-content/howell/Prototypes/dog_skull/dogskull.obj @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4e32bd05e62eb3e4b428f611364117ecffcfc60beec2e139155e226730f124e0 +size 5187505 diff --git a/hifi-content/howell/Prototypes/dog_skull/dogskull_u1_v1.jpg b/hifi-content/howell/Prototypes/dog_skull/dogskull_u1_v1.jpg new file mode 100644 index 000000000..75674ebed --- /dev/null +++ b/hifi-content/howell/Prototypes/dog_skull/dogskull_u1_v1.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:be3619b68560da8c9ecb4680014ca2024c1a4815245b04a9cd9df939bba5f084 +size 566510 diff --git a/hifi-content/howell/Prototypes/glasses.jpg b/hifi-content/howell/Prototypes/glasses.jpg new file mode 100644 index 000000000..26aa3eca1 --- /dev/null +++ b/hifi-content/howell/Prototypes/glasses.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:893bbc9eb8ec5296bc168f28e9e73717fcbe5641c59fcbba3783411dad0dc7d8 +size 111129 diff --git a/hifi-content/howell/Prototypes/jat_test2/JATScritp.js b/hifi-content/howell/Prototypes/jat_test2/JATScritp.js new file mode 120000 index 000000000..4a027c37a --- /dev/null +++ b/hifi-content/howell/Prototypes/jat_test2/JATScritp.js @@ -0,0 +1 @@ +../JAT_test/JATScritp.js \ No newline at end of file diff --git a/hifi-content/howell/Prototypes/jat_test2/config.json b/hifi-content/howell/Prototypes/jat_test2/config.json new file mode 120000 index 000000000..d476b91f5 --- /dev/null +++ b/hifi-content/howell/Prototypes/jat_test2/config.json @@ -0,0 +1 @@ +../JAT_test/config.json \ No newline at end of file diff --git a/hifi-content/howell/Prototypes/jat_test3/JATScritp.js b/hifi-content/howell/Prototypes/jat_test3/JATScritp.js new file mode 120000 index 000000000..4a027c37a --- /dev/null +++ b/hifi-content/howell/Prototypes/jat_test3/JATScritp.js @@ -0,0 +1 @@ +../JAT_test/JATScritp.js \ No newline at end of file diff --git a/hifi-content/howell/Prototypes/jat_test3/config.json b/hifi-content/howell/Prototypes/jat_test3/config.json new file mode 100644 index 000000000..bab4ef25a --- /dev/null +++ b/hifi-content/howell/Prototypes/jat_test3/config.json @@ -0,0 +1,27 @@ +{ + "avatars": [ + { + "name": "Andy1", + "url": "https://raw.githubusercontent.com/AndySeattle/Avatar/master/office_zombie_alive/office_zombie_alive.fst" + }, + { + "name": "Vacation", + "url": "https://raw.githubusercontent.com/AndySeattle/Avatar/master/Zombie_on_vacation/zombie_on_vacation_hifi.fst" + }, + { + "name": "Ice Hero", + "url": "http://mpassets.highfidelity.com/e238153a-21f4-4eba-8ab5-c6b10a0eb967-v1/avatar.fst" + }, + { + "name": "Ice Hero2", + "url": "http://mpassets.highfidelity.com/e238153a-21f4-4eba-8ab5-c6b10a0eb967-v1/avatar.fst" + }, + { + "name": "ice hero 3", + "url": "http://mpassets.highfidelity.com/e238153a-21f4-4eba-8ab5-c6b10a0eb967-v1/avatar.fst" + } + ], + "screenleapURL": "", + "controlsMessageChannel": "", + "statusMessageChannel": "" +} \ No newline at end of file diff --git a/hifi-content/howell/Prototypes/neon_snowflake.jpg b/hifi-content/howell/Prototypes/neon_snowflake.jpg new file mode 100644 index 000000000..79fa686f4 --- /dev/null +++ b/hifi-content/howell/Prototypes/neon_snowflake.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3bfb883b0e50213df4c94a032ca6ec923a2a2db42f4044c64bee2391ed3bb846 +size 97273 diff --git a/hifi-content/howell/Prototypes/neonturkey.jpg b/hifi-content/howell/Prototypes/neonturkey.jpg new file mode 100644 index 000000000..09050407d --- /dev/null +++ b/hifi-content/howell/Prototypes/neonturkey.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f20e6d01aa352b271d87abc354cbd7cef04586ae1cdf4a3a096e65e22ba24a86 +size 111176 diff --git a/hifi-content/howell/Prototypes/pants.JPG b/hifi-content/howell/Prototypes/pants.JPG new file mode 100644 index 000000000..9153c3125 --- /dev/null +++ b/hifi-content/howell/Prototypes/pants.JPG @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:276cb6ffb72c6c8056293a57805083d9b7f04db9f172cf59253f301c0307d9e6 +size 57787 diff --git a/hifi-content/howell/Prototypes/pumpkins.jpg b/hifi-content/howell/Prototypes/pumpkins.jpg new file mode 100644 index 000000000..2e0032f75 --- /dev/null +++ b/hifi-content/howell/Prototypes/pumpkins.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6096a4bd8321589982b32f7d4b88ac5dea8680930d3f339f1ab414f9f68ff9a9 +size 322425 diff --git a/hifi-content/howell/Prototypes/satdium.fbx b/hifi-content/howell/Prototypes/satdium.fbx new file mode 100644 index 000000000..d0ab9de37 --- /dev/null +++ b/hifi-content/howell/Prototypes/satdium.fbx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:32b6e4ff38986bb5e00dc6308fc02df7f23e08a635929afd0798dd4ba70a2c4a +size 3316816 diff --git a/hifi-content/howell/Prototypes/shirt.jpg b/hifi-content/howell/Prototypes/shirt.jpg new file mode 100644 index 000000000..f08a2fe72 --- /dev/null +++ b/hifi-content/howell/Prototypes/shirt.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:528968504004a0c1939076b50bfaf2fb20f825d9c1b98d5f7aa96d0365f3f451 +size 78865 diff --git a/hifi-content/howell/Prototypes/snowflake.PNG b/hifi-content/howell/Prototypes/snowflake.PNG new file mode 100644 index 000000000..0d3fbb313 --- /dev/null +++ b/hifi-content/howell/Prototypes/snowflake.PNG @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1f06cad98fe7c0456945ab0701f111fca696e21e359b3468b09413afec08913a +size 348816 diff --git a/hifi-content/howell/Prototypes/space.jpg b/hifi-content/howell/Prototypes/space.jpg new file mode 100644 index 000000000..f11c98346 --- /dev/null +++ b/hifi-content/howell/Prototypes/space.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:68249cffab436921e5326a80e01e16b681689c8b8a44e350e89df9d5df27a174 +size 242924 diff --git a/hifi-content/howell/Prototypes/space2.jpg b/hifi-content/howell/Prototypes/space2.jpg new file mode 100644 index 000000000..35b375e15 --- /dev/null +++ b/hifi-content/howell/Prototypes/space2.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:915657c377ec8f664bcef5d0ed8344afecf7b86493a3a448d58f7201a73f0a20 +size 147379 diff --git a/hifi-content/howell/Prototypes/team_directory.PNG b/hifi-content/howell/Prototypes/team_directory.PNG new file mode 100644 index 000000000..4d0c5b2bd --- /dev/null +++ b/hifi-content/howell/Prototypes/team_directory.PNG @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9dcea6bdd128e75bb99aae1717a5b552ce68113a06f27693d95b4349d4e16e89 +size 29101 diff --git a/hifi-content/howell/Prototypes/turkeybleh.png b/hifi-content/howell/Prototypes/turkeybleh.png new file mode 100644 index 000000000..07622a8b9 --- /dev/null +++ b/hifi-content/howell/Prototypes/turkeybleh.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ab45cb8a0edf4459ad856c581862b52e0e2a39d9d27cc7b87a14709743414ab6 +size 147349 diff --git a/hifi-content/howell/Prototypes/ugly_sweater.jpg b/hifi-content/howell/Prototypes/ugly_sweater.jpg new file mode 100644 index 000000000..bdf549913 --- /dev/null +++ b/hifi-content/howell/Prototypes/ugly_sweater.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b5a7337f0cad399bee35ebefa412d0f8acb8cda2d5b299c6f5af5edd5f8f94fc +size 20781 diff --git a/hifi-content/howell/Prototypes/wheel_of_current_events.png b/hifi-content/howell/Prototypes/wheel_of_current_events.png new file mode 100644 index 000000000..f812cab83 --- /dev/null +++ b/hifi-content/howell/Prototypes/wheel_of_current_events.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:23e76865a807aed401b0cbb61516ac94474aa6ce1fdc8b63c4f412c08125de41 +size 90689 diff --git a/hifi-content/howell/bots/AVATAR_TEST1.hfr b/hifi-content/howell/bots/AVATAR_TEST1.hfr new file mode 100644 index 000000000..f83d11201 --- /dev/null +++ b/hifi-content/howell/bots/AVATAR_TEST1.hfr @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d1c912c52b81e0c826eebf36af923f53d712a96bb160521e477b1ab2a62937c1 +size 7974898 diff --git a/hifi-content/howell/bots/AVATAR_TEST10.hfr b/hifi-content/howell/bots/AVATAR_TEST10.hfr new file mode 100644 index 000000000..73926b371 --- /dev/null +++ b/hifi-content/howell/bots/AVATAR_TEST10.hfr @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:dc3513dcb18a9881d624589b2c9774d9bbf8624bd1cd8219628a77c4f3c1800a +size 1135949 diff --git a/hifi-content/howell/bots/AVATAR_TEST11.hfr b/hifi-content/howell/bots/AVATAR_TEST11.hfr new file mode 100644 index 000000000..bf5badf2d --- /dev/null +++ b/hifi-content/howell/bots/AVATAR_TEST11.hfr @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6bd91df2847a77d64f53f8eaadb83a1554e011686a4f632f81eadfa2f69991e8 +size 1591454 diff --git a/hifi-content/howell/bots/AVATAR_TEST12.hfr b/hifi-content/howell/bots/AVATAR_TEST12.hfr new file mode 100644 index 000000000..62b8c6127 --- /dev/null +++ b/hifi-content/howell/bots/AVATAR_TEST12.hfr @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fa2b7bdf58b049e0e33f308d72a73a142c42a12faf49121beda3c6c49fbf44f4 +size 1686480 diff --git a/hifi-content/howell/bots/AVATAR_TEST13.hfr b/hifi-content/howell/bots/AVATAR_TEST13.hfr new file mode 100644 index 000000000..c51393d15 --- /dev/null +++ b/hifi-content/howell/bots/AVATAR_TEST13.hfr @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:54cefee9dc45885ac676525e175ea723e1a838abb80c9fc32f828c59e1acf65d +size 2204124 diff --git a/hifi-content/howell/bots/AVATAR_TEST14.hfr b/hifi-content/howell/bots/AVATAR_TEST14.hfr new file mode 100644 index 000000000..6a91c1bd2 --- /dev/null +++ b/hifi-content/howell/bots/AVATAR_TEST14.hfr @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f7faa106a9808d87784860dc7461c1d9c2fc27f612ef9cc57bdfc2b5c702c008 +size 1185194 diff --git a/hifi-content/howell/bots/AVATAR_TEST15.hfr b/hifi-content/howell/bots/AVATAR_TEST15.hfr new file mode 100644 index 000000000..5b52952e3 --- /dev/null +++ b/hifi-content/howell/bots/AVATAR_TEST15.hfr @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e450bd4b3ef294984738a769da71b694bfc55940e1071a33efc8fbf9d8a58d51 +size 2887841 diff --git a/hifi-content/howell/bots/AVATAR_TEST16.hfr b/hifi-content/howell/bots/AVATAR_TEST16.hfr new file mode 100644 index 000000000..eb17e0191 --- /dev/null +++ b/hifi-content/howell/bots/AVATAR_TEST16.hfr @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1f242f9423b60c5f347fa2fb6b89c125ee921fc8fc7be6254d371ef756da02ea +size 1666494 diff --git a/hifi-content/howell/bots/AVATAR_TEST17.hfr b/hifi-content/howell/bots/AVATAR_TEST17.hfr new file mode 100644 index 000000000..4fcdb31aa --- /dev/null +++ b/hifi-content/howell/bots/AVATAR_TEST17.hfr @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:08259f6135f2bac23632d50befd5a924c23b2791123ed23e051a7a9edc60ee58 +size 1426485 diff --git a/hifi-content/howell/bots/AVATAR_TEST18.hfr b/hifi-content/howell/bots/AVATAR_TEST18.hfr new file mode 100644 index 000000000..658395473 --- /dev/null +++ b/hifi-content/howell/bots/AVATAR_TEST18.hfr @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:98f3ff1147262a21ab6cd1a91e137ac75aef2f7ea84df1933fd6629a9558c8c1 +size 1363808 diff --git a/hifi-content/howell/bots/AVATAR_TEST19.hfr b/hifi-content/howell/bots/AVATAR_TEST19.hfr new file mode 100644 index 000000000..7cc8ef467 --- /dev/null +++ b/hifi-content/howell/bots/AVATAR_TEST19.hfr @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2bf086e1b8c0ab37cde6351a9fb7e0ca363e8d8a7a49ba6f0b45d20eb3b22e8a +size 985808 diff --git a/hifi-content/howell/bots/AVATAR_TEST2.hfr b/hifi-content/howell/bots/AVATAR_TEST2.hfr new file mode 100644 index 000000000..375651531 --- /dev/null +++ b/hifi-content/howell/bots/AVATAR_TEST2.hfr @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0e3038a4e34576fe52aa9ceda70cb066fe93ddd46782d3db44827e3ecffe34d9 +size 2178570 diff --git a/hifi-content/howell/bots/AVATAR_TEST20.hfr b/hifi-content/howell/bots/AVATAR_TEST20.hfr new file mode 100644 index 000000000..8611625cd --- /dev/null +++ b/hifi-content/howell/bots/AVATAR_TEST20.hfr @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:49675f51a8981e99aa5bc079819568a96bba348519f44cd22cc4d55b5bf55932 +size 1739628 diff --git a/hifi-content/howell/bots/AVATAR_TEST3.hfr b/hifi-content/howell/bots/AVATAR_TEST3.hfr new file mode 100644 index 000000000..c405e31e4 --- /dev/null +++ b/hifi-content/howell/bots/AVATAR_TEST3.hfr @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ee10abed9d2152c503739887a5af8b9a1bb827a6f2a931db839113072f1cce0f +size 1667470 diff --git a/hifi-content/howell/bots/AVATAR_TEST4.hfr b/hifi-content/howell/bots/AVATAR_TEST4.hfr new file mode 100644 index 000000000..5cd58f9c4 --- /dev/null +++ b/hifi-content/howell/bots/AVATAR_TEST4.hfr @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4d2e20acb44e860edf402b2c8be36e3d510847b88276c9999a749ac6581f6e9a +size 3584851 diff --git a/hifi-content/howell/bots/AVATAR_TEST5.hfr b/hifi-content/howell/bots/AVATAR_TEST5.hfr new file mode 100644 index 000000000..d2902d69c --- /dev/null +++ b/hifi-content/howell/bots/AVATAR_TEST5.hfr @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9d88321eb90c0b276cd98a12b8e7b9f69ed4581588389ad2541cebd63ff4773a +size 5587202 diff --git a/hifi-content/howell/bots/AVATAR_TEST6.hfr b/hifi-content/howell/bots/AVATAR_TEST6.hfr new file mode 100644 index 000000000..138ea7ec9 --- /dev/null +++ b/hifi-content/howell/bots/AVATAR_TEST6.hfr @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0783ee0db7bac33092c443fdcdd3702db8e36fc9a8a62836371534c11a8c79cb +size 5949659 diff --git a/hifi-content/howell/bots/AVATAR_TEST7.hfr b/hifi-content/howell/bots/AVATAR_TEST7.hfr new file mode 100644 index 000000000..2bceec911 --- /dev/null +++ b/hifi-content/howell/bots/AVATAR_TEST7.hfr @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ce31d7e20ecba3ea824b7d0ca61e34a8e66e6b4cd415bfb76a658cf067f8984b +size 2389461 diff --git a/hifi-content/howell/bots/AVATAR_TEST8.hfr b/hifi-content/howell/bots/AVATAR_TEST8.hfr new file mode 100644 index 000000000..45f026812 --- /dev/null +++ b/hifi-content/howell/bots/AVATAR_TEST8.hfr @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:46c2efb60681234de3eb8b50dddc2a3fb8b800bdf1e7902e5e1daae7e332f25c +size 1879422 diff --git a/hifi-content/howell/bots/AVATAR_TEST9.hfr b/hifi-content/howell/bots/AVATAR_TEST9.hfr new file mode 100644 index 000000000..3496db33f --- /dev/null +++ b/hifi-content/howell/bots/AVATAR_TEST9.hfr @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ab03e5e3ef6660decc90396b77b5ef337ec18ca44a4e73a448cbb107bfd03cee +size 2547568 diff --git a/hifi-content/howell/bots/_AVATAR_TEST5.hfr b/hifi-content/howell/bots/_AVATAR_TEST5.hfr new file mode 120000 index 000000000..3879f6d5f --- /dev/null +++ b/hifi-content/howell/bots/_AVATAR_TEST5.hfr @@ -0,0 +1 @@ +AVATAR_TEST15.hfr \ No newline at end of file diff --git a/hifi-content/howell/bots_new/AVATAR_TEST1.hfr b/hifi-content/howell/bots_new/AVATAR_TEST1.hfr new file mode 100644 index 000000000..6d13dd4f4 --- /dev/null +++ b/hifi-content/howell/bots_new/AVATAR_TEST1.hfr @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8144f99773cda75e348020f2acc1bef6180a7577f5e48649316e26b7b177a2e6 +size 2232992 diff --git a/hifi-content/howell/usertesting/can_you_see_me.txt b/hifi-content/howell/usertesting/can_you_see_me.txt new file mode 100644 index 000000000..51ce371a0 --- /dev/null +++ b/hifi-content/howell/usertesting/can_you_see_me.txt @@ -0,0 +1 @@ +Shannon can you see this? \ No newline at end of file diff --git a/hifi-content/huffman/avatars/tubeboy/tubeboy.fst b/hifi-content/huffman/avatars/tubeboy/tubeboy.fst new file mode 100644 index 000000000..78d2321e0 --- /dev/null +++ b/hifi-content/huffman/avatars/tubeboy/tubeboy.fst @@ -0,0 +1,131 @@ +name = tubeboy +type = body+head +scale = 1 +filename = tubeboy/tubeboy.fbx +texdir = tubeboy/textures +joint = jointNeck = Neck +joint = jointRoot = Hips +joint = jointRightHand = RightHand +joint = jointLeftHand = LeftHand +joint = jointHead = HeadTop_End +joint = jointLean = Spine +freeJoint = LeftArm +freeJoint = LeftForeArm +freeJoint = RightArm +freeJoint = RightForeArm +bs = LipsLowerDown = LowerLipDown_Right = 0.69999999999999996 +bs = LipsLowerDown = LowerLipDown_Left = 0.69999999999999996 +bs = EyeOpen_L = EyesWide_Left = 1 +bs = LipsLowerOpen = LowerLipOut = 1 +bs = MouthDimple_L = Smile_Left = 0.25 +bs = BrowsU_L = BrowsUp_Left = 1 +bs = ChinLowerRaise = Jaw_Up = 1 +bs = MouthRight = Midmouth_Right = 1 +bs = JawLeft = JawRotateY_Left = 0.5 +bs = EyeOpen_R = EyesWide_Right = 1 +bs = LipsPucker = MouthNarrow_Right = 1 +bs = LipsPucker = MouthNarrow_Left = 1 +bs = EyeBlink_L = Blink_Left = 1 +bs = EyeBlink_R = Blink_Right = 1 +bs = JawOpen = MouthOpen = 0.69999999999999996 +bs = EyeSquint_L = Squint_Left = 1 +bs = BrowsU_C = BrowsUp_Right = 1 +bs = BrowsU_C = BrowsUp_Left = 1 +bs = MouthSmile_L = Smile_Left = 1 +bs = JawRight = Jaw_Right = 1 +bs = MouthFrown_R = Frown_Right = 1 +bs = Puff = CheekPuff_Right = 1 +bs = Puff = CheekPuff_Left = 1 +bs = BrowsD_R = BrowsDown_Right = 1 +bs = EyeSquint_R = Squint_Right = 1 +bs = MouthFrown_L = Frown_Left = 1 +bs = Sneer = Squint_Right = 0.5 +bs = Sneer = Squint_Left = 0.5 +bs = Sneer = NoseScrunch_Right = 0.75 +bs = Sneer = NoseScrunch_Left = 0.75 +bs = LipsUpperOpen = UpperLipOut = 1 +bs = JawFwd = JawForeward = 1 +bs = MouthLeft = Midmouth_Left = 1 +bs = MouthSmile_R = Smile_Right = 1 +bs = LipsUpperUp = UpperLipUp_Right = 0.69999999999999996 +bs = LipsUpperUp = UpperLipUp_Left = 0.69999999999999996 +bs = LipsUpperClose = UpperLipIn = 1 +bs = MouthDimple_R = Smile_Right = 0.25 +bs = LipsLowerClose = LowerLipIn = 1 +bs = LipsFunnel = TongueUp = 1 +bs = LipsFunnel = MouthWhistle_NarrowAdjust_Right = 0.5 +bs = LipsFunnel = MouthWhistle_NarrowAdjust_Left = 0.5 +bs = LipsFunnel = MouthNarrow_Right = 1 +bs = LipsFunnel = MouthNarrow_Left = 1 +bs = LipsFunnel = Jaw_Down = 0.35999999999999999 +bs = LipsFunnel = JawForeward = 0.39000000000000001 +bs = BrowsU_R = BrowsUp_Right = 1 +bs = ChinUpperRaise = UpperLipUp_Right = 0.5 +bs = ChinUpperRaise = UpperLipUp_Left = 0.5 +bs = BrowsD_L = BrowsDown_Left = 1 +jointIndex = RightArm = 16 +jointIndex = RightHandThumb1 = 35 +jointIndex = LeftUpLeg = 7 +jointIndex = Spine1 = 13 +jointIndex = LeftHandThumb2 = 60 +jointIndex = LeftToe_End = 11 +jointIndex = LeftHandPinky1 = 43 +jointIndex = LeftHandThumb4 = 62 +jointIndex = RightHandPinky1 = 19 +jointIndex = LeftLeg = 8 +jointIndex = RightHandThumb3 = 37 +jointIndex = RightHandMiddle4 = 30 +jointIndex = LeftHandPinky3 = 45 +jointIndex = RightHandMiddle1 = 27 +jointIndex = RightHandIndex3 = 33 +jointIndex = LeftHandIndex1 = 55 +jointIndex = LeftToeBase = 10 +jointIndex = LeftHandPinky4 = 46 +jointIndex = LeftHandRing4 = 50 +jointIndex = Head = 64 +jointIndex = LeftShoulder = 39 +jointIndex = RightHandRing3 = 25 +jointIndex = RightFoot = 4 +jointIndex = RightHandRing1 = 23 +jointIndex = RightHandThumb4 = 38 +jointIndex = RightHandRing4 = 26 +jointIndex = RightHandThumb2 = 36 +jointIndex = LeftHandPinky2 = 44 +jointIndex = Hips = 0 +jointIndex = RightHand = 18 +jointIndex = RightHandMiddle2 = 28 +jointIndex = LeftHandRing1 = 47 +jointIndex = RightToeBase = 5 +jointIndex = LeftHandMiddle4 = 54 +jointIndex = RightHandRing2 = 24 +jointIndex = Spine = 12 +jointIndex = HeadTop_End = 65 +jointIndex = LeftHandRing3 = 49 +jointIndex = Spine2 = 14 +jointIndex = LeftHandMiddle2 = 52 +jointIndex = LeftHandIndex3 = 57 +jointIndex = RightHandPinky4 = 22 +jointIndex = RightLeg = 3 +jointIndex = RightToe_End = 6 +jointIndex = LeftHandRing2 = 48 +jointIndex = LeftHandIndex2 = 56 +jointIndex = LeftHandThumb3 = 61 +jointIndex = RightHandIndex4 = 34 +jointIndex = LeftFoot = 9 +jointIndex = LeftForeArm = 41 +jointIndex = LeftHandMiddle3 = 53 +jointIndex = RightHandMiddle3 = 29 +jointIndex = Neck = 63 +jointIndex = RightForeArm = 17 +jointIndex = Layer_7 = 1 +jointIndex = LeftHandMiddle1 = 51 +jointIndex = RightUpLeg = 2 +jointIndex = RightHandPinky2 = 20 +jointIndex = LeftHand = 42 +jointIndex = RightHandIndex2 = 32 +jointIndex = LeftHandIndex4 = 58 +jointIndex = LeftArm = 40 +jointIndex = RightHandIndex1 = 31 +jointIndex = LeftHandThumb1 = 59 +jointIndex = RightHandPinky3 = 21 +jointIndex = RightShoulder = 15 diff --git a/hifi-content/huffman/avatars/tubeboy/tubeboy/tubeboy.fbx b/hifi-content/huffman/avatars/tubeboy/tubeboy/tubeboy.fbx new file mode 100644 index 000000000..c2bb6a750 --- /dev/null +++ b/hifi-content/huffman/avatars/tubeboy/tubeboy/tubeboy.fbx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d0fcf3223cc5affce57dfe1235611659812fa6a85b8d84449c1630cf8546a9b5 +size 4457056 diff --git a/hifi-content/huffman/ctf/Portal-Red-Blue.svo.json b/hifi-content/huffman/ctf/Portal-Red-Blue.svo.json new file mode 100644 index 000000000..50f0d3fed --- /dev/null +++ b/hifi-content/huffman/ctf/Portal-Red-Blue.svo.json @@ -0,0 +1,175 @@ +{ + "Entities": [ + { + "clientOnly": 0, + "collisionsWillMove": 1, + "compoundShapeURL": "http://hifi-production.s3.amazonaws.com/tutorials/pingPongGun/Pingpong-Gun-New.obj", + "created": "2017-02-27T19:00:27Z", + "dimensions": { + "x": 0.17742760479450226, + "y": 0.38749998807907104, + "z": 0.99309998750686646 + }, + "dynamic": 1, + "gravity": { + "x": 0, + "y": -5, + "z": 0 + }, + "id": "{891a0f4b-b8b2-4825-ace1-f566e8718782}", + "lastEdited": 1488229103067753, + "lastEditedBy": "{0f6b0911-7faf-45af-bfd0-9726a9ef0a2e}", + "modelURL": "http://hifi-content.s3.amazonaws.com/alan/dev/Pingportal-Gun-New.fbx?1", + "name": "Tutorial Ping Pong Gun", + "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", + "position": { + "x": 1.4289360046386719, + "y": 0, + "z": 1.4532890319824219 + }, + "queryAACube": { + "scale": 1.0806869268417358, + "x": 0.88859254121780396, + "y": -0.54034346342086792, + "z": 0.91294556856155396 + }, + "rotation": { + "w": 0.51259636878967285, + "x": -0.5248645544052124, + "y": 0.5236133337020874, + "z": -0.43306630849838257 + }, + "script": "http://hifi-content.s3.amazonaws.com/alan/dev/Scripts/ping-portal-lionsgate-blue.js?4", + "shapeType": "compound", + "type": "Model", + "userData": "{\"grabbableKey\":{\"invertSolidWhileHeld\":true},\"wearable\":{\"joints\":{\"RightHand\":[{\"x\":0.1177130937576294,\"y\":0.12922893464565277,\"z\":0.08307232707738876},{\"x\":0.4934672713279724,\"y\":0.3605862259864807,\"z\":0.6394805908203125,\"w\":-0.4664038419723511}],\"LeftHand\":[{\"x\":0.09151676297187805,\"y\":0.13639454543590546,\"z\":0.09354984760284424},{\"x\":-0.19628101587295532,\"y\":0.6418180465698242,\"z\":0.2830369472503662,\"w\":0.6851521730422974}]}}}" + }, + { + "clientOnly": 0, + "color": { + "blue": 255, + "green": 166, + "red": 41 + }, + "created": "2017-02-27T19:00:27Z", + "cutoff": 90, + "dimensions": { + "x": 5.0777130126953125, + "y": 5.0777130126953125, + "z": 5.0777130126953125 + }, + "falloffRadius": 2.2000000476837158, + "id": "{51782e1b-983b-477d-9a6d-5ab550c198df}", + "intensity": 5, + "lastEdited": 1488229094210296, + "lastEditedBy": "{0f6b0911-7faf-45af-bfd0-9726a9ef0a2e}", + "name": "PingPortal-Light", + "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", + "parentID": "{891a0f4b-b8b2-4825-ace1-f566e8718782}", + "position": { + "x": -0.071898072957992554, + "y": 0.1922331303358078, + "z": 0.59060537815093994 + }, + "queryAACube": { + "scale": 26.384571075439453, + "x": -21.061281204223633, + "y": -13.358207702636719, + "z": -58.344821929931641 + }, + "rotation": { + "w": -0.14616614580154419, + "x": 0.68834972381591797, + "y": -0.69469749927520752, + "z": -0.14915692806243896 + }, + "type": "Light" + }, + { + "clientOnly": 0, + "collisionsWillMove": 1, + "compoundShapeURL": "http://hifi-production.s3.amazonaws.com/tutorials/pingPongGun/Pingpong-Gun-New.obj", + "created": "2017-02-27T20:45:19Z", + "dimensions": { + "x": 0.17742760479450226, + "y": 0.38749998807907104, + "z": 0.99309998750686646 + }, + "dynamic": 1, + "gravity": { + "x": 0, + "y": -5, + "z": 0 + }, + "id": "{25c38044-7ede-485c-815b-dddbf6496bcb}", + "lastEdited": 1488229023393654, + "lastEditedBy": "{0f6b0911-7faf-45af-bfd0-9726a9ef0a2e}", + "modelURL": "http://hifi-content.s3.amazonaws.com/alan/dev/PingPortal-Gun-red.fbx", + "name": "Portal-Gun", + "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", + "position": { + "x": 0, + "y": 0.0038486719131469727, + "z": 0 + }, + "queryAACube": { + "scale": 92.106178283691406, + "x": -54.764865875244141, + "y": -2.7994985580444336, + "z": -53.593635559082031 + }, + "rotation": { + "w": 0.64834010601043701, + "x": -0.34717363119125366, + "y": 0.36466187238693237, + "z": -0.57109308242797852 + }, + "script": "http://hifi-content.s3.amazonaws.com/alan/dev/Scripts/ping-portal-lionsgate-red.js", + "shapeType": "compound", + "type": "Model", + "userData": "{\"grabbableKey\":{\"invertSolidWhileHeld\":true},\"wearable\":{\"joints\":{\"RightHand\":[{\"x\":0.1177130937576294,\"y\":0.12922893464565277,\"z\":0.08307232707738876},{\"x\":0.4934672713279724,\"y\":0.3605862259864807,\"z\":0.6394805908203125,\"w\":-0.4664038419723511}],\"LeftHand\":[{\"x\":0.09151676297187805,\"y\":0.13639454543590546,\"z\":0.09354984760284424},{\"x\":-0.19628101587295532,\"y\":0.6418180465698242,\"z\":0.2830369472503662,\"w\":0.6851521730422974}]}}}" + }, + { + "clientOnly": 0, + "color": { + "blue": 96, + "green": 23, + "red": 255 + }, + "created": "2017-02-27T20:45:19Z", + "cutoff": 90, + "dimensions": { + "x": 5.0777130126953125, + "y": 5.0777130126953125, + "z": 5.0777130126953125 + }, + "falloffRadius": 3.2000000476837158, + "id": "{e33b0529-361c-4515-b17c-534e4d1af5aa}", + "intensity": 5.4000000953674316, + "lastEdited": 1488229000832557, + "lastEditedBy": "{0f6b0911-7faf-45af-bfd0-9726a9ef0a2e}", + "name": "PingPortal-Light", + "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", + "parentID": "{25c38044-7ede-485c-815b-dddbf6496bcb}", + "position": { + "x": -0.071893095970153809, + "y": 0.1922280490398407, + "z": 0.5906517505645752 + }, + "queryAACube": { + "scale": 26.384571075439453, + "x": -18.223112106323242, + "y": -13.085569381713867, + "z": -64.876693725585938 + }, + "rotation": { + "w": -0.14616614580154419, + "x": 0.68831920623779297, + "y": -0.69469749927520752, + "z": -0.14915692806243896 + }, + "type": "Light" + } + ], + "Version": 66 +} diff --git a/hifi-content/huffman/ctf/README.md b/hifi-content/huffman/ctf/README.md new file mode 100644 index 000000000..78fd985d4 --- /dev/null +++ b/hifi-content/huffman/ctf/README.md @@ -0,0 +1,24 @@ +### ballClientEntity.js + + * Keeps track of whether it is being held locally. + * Has a message interface to release the ball. This message is sent when the + portal gun bullet/orb hits the user. + * Releases the ball when the goal is touched, and sends a message to the goal + +### goalClientEntity.js + + * Shoots fireworks when the ball is scored + * Manages a cooldown so the goal can only be triggered every 2 seconds (on the client, so technically if 2 clients + scored in a shorted period of time it would still trigger twice). + +### portalGunClientEntity.js + +Portal gun client entity script + +### portalBulletClientEntity.js + +Portal bullet client entity script. Teleports a user to the starting area when it hits a user + +### gunSpawnerClientEntity.js + +Spawns guns when it is clicked/grabbed/fargrabbed diff --git a/hifi-content/huffman/ctf/ballClientEntity.js b/hifi-content/huffman/ctf/ballClientEntity.js new file mode 100644 index 000000000..4a618ca2d --- /dev/null +++ b/hifi-content/huffman/ctf/ballClientEntity.js @@ -0,0 +1,67 @@ +(function() { + var self = this; + + var leftHeld = false; + var rightHeld = false; + + self.preload = function(entityID) { + self.entityID = entityID; + Script.addEventHandler(entityID, "collisionWithEntity", self.onCollide); + print('preload'); + }; + + self.startDistanceGrab = function(entityID, args) { + if (args[0] === 'left') { + leftHeld = true; + } else { + rightHeld = true; + } + print("startDistance", leftHeld, rightHeld); + }; + self.startNearGrab = function(entityID, args) { + if (args[0] === 'left') { + leftHeld = true; + } else { + rightHeld = true; + } + print("startNear", leftHeld, rightHeld); + }; + self.releaseGrab = function(entityID, args) { + if (args[0] === 'left') { + leftHeld = false; + } else { + rightHeld = false; + } + print("release", leftHeld, rightHeld); + }; + + self.onCollide = function(entityA, entityB, collision) { + var colliderName = Entities.getEntityProperties(entityB, 'name').name; + print("Collide", colliderName); + if (colliderName === "Portal/Goal") { + self.releaseBall(); + Entities.callEntityMethod(entityB, 'onScored'); + } + }; + + self.releaseBall = function() { + if (leftHeld || rightHeld) { + var hand; + if (leftHeld && rightHeld) { + hand = 'both'; + } else if (!leftHeld && rightHeld) { + hand = 'right'; + } else if (leftHeld && !rightHeld) { + hand = 'left'; + } + Messages.sendMessage("Hifi-Hand-Drop", hand); + } + }; + + Messages.subscribe("Portal-Game"); + Messages.messageReceived.connect(function(channel, message, sender) { + if (channel === "Portal-Game") { + self.releaseBall(); + } + }); +}); diff --git a/hifi-content/huffman/ctf/firework.js b/hifi-content/huffman/ctf/firework.js new file mode 100644 index 000000000..c723b34ed --- /dev/null +++ b/hifi-content/huffman/ctf/firework.js @@ -0,0 +1,147 @@ +// +// firework.js +// examples/baseball/ +// +// Created by Ryan Huffman on Nov 9, 2015 +// 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 +// + +/* globals randomVec3, randomInt, randomColor, getSounds, playFireworkShow:true */ + +Script.include("utils.js"); + +var emitters = []; + +var smokeTrailSettings = { + "name":"ParticlesTest Emitter", + "type": "ParticleEffect", + "color":{"red":205,"green":84.41176470588235,"blue":84.41176470588235}, + "maxParticles":1000, + "velocity": { x: 0, y: 18.0, z: 0 }, + "lifetime": 20, + "lifespan":3, + "emitRate":100, + "emitSpeed":0.5, + "speedSpread":0, + "emitOrientation":{"x":0,"y":0,"z":0,"w":1}, + "emitDimensions":{"x":0,"y":0,"z":0}, + "emitRadiusStart":0.5, + "polarStart":1, + "polarFinish":1, + "azimuthStart":0, + "azimuthFinish":0, + "emitterShouldTrail": true, + "emitAcceleration":{"x":0,"y":-0.70000001192092896,"z":0}, + "accelerationSpread":{"x":0,"y":0,"z":0}, + "particleRadius":0.03999999910593033, + "radiusSpread":0, + "radiusStart":0.13999999910593033, + "radiusFinish":0.14, + "colorSpread":{"red":0,"green":0,"blue":0}, + "colorStart":{"red":255,"green":255,"blue":255}, + "colorFinish":{"red":255,"green":255,"blue":255}, + "alpha":1, + "alphaSpread":0, + "alphaStart":1, + "alphaFinish":0, + "textures":"https://hifi-public.s3.amazonaws.com/alan/Particles/Particle-Sprite-Smoke-1.png" +}; + +var fireworkSettings = { + "name":"ParticlesTest Emitter", + "type": "ParticleEffect", + "color":{"red":205,"green":84.41176470588235,"blue":84.41176470588235}, + "maxParticles":1000, + "lifetime": 20, + "lifespan":15, + "emitRate":2000, + "emitSpeed":2.5, + "speedSpread":1.0, + "emitOrientation":{"x":-0.2,"y":0,"z":0,"w":0.7000000000000001}, + "emitDimensions":{"x":0,"y":0,"z":0}, + "emitRadiusStart":0.5, + "polarStart":0, + "polarFinish":Math.PI, + "azimuthStart":-Math.PI, + "azimuthFinish":Math.PI, + "emitAcceleration":{"x":0,"y":-1.70000001192092896,"z":0}, + "accelerationSpread":{"x":0,"y":0,"z":0}, + "particleRadius":0.02999999910593033, + "radiusSpread":0, + "radiusStart":0.13999999910593033, + "radiusFinish":0.14, + "colorSpread":{"red":0,"green":0,"blue":0}, + "colorStart":{"red":255,"green":255,"blue":255}, + "colorFinish":{"red":255,"green":255,"blue":255}, + "alpha":1, + "alphaSpread":0, + "alphaStart":1, + "alphaFinish":0, + "textures":"http://hifi-content.s3.amazonaws.com/alan/dev/Particles/Particle-Spark.png" +}; + +var popSounds = getSounds([ + "http://hifi-public.s3.amazonaws.com/birarda/baseball/fireworks/pop1.wav", + "http://hifi-public.s3.amazonaws.com/birarda/baseball/fireworks/pop2.wav", + "http://hifi-public.s3.amazonaws.com/birarda/baseball/fireworks/pop3.wav", + "http://hifi-public.s3.amazonaws.com/birarda/baseball/fireworks/pop4.wav" +]); + +var launchSounds = getSounds([ + "http://hifi-public.s3.amazonaws.com/birarda/baseball/fireworks/fire1.wav", + "http://hifi-public.s3.amazonaws.com/birarda/baseball/fireworks/fire2.wav", + "http://hifi-public.s3.amazonaws.com/birarda/baseball/fireworks/fire3.wav", + "http://hifi-public.s3.amazonaws.com/birarda/baseball/fireworks/fire4.wav" +]); + +function playRandomSound(sounds, options) { + Audio.playSound(sounds[randomInt(sounds.length)], options); +} + +function shootFirework(position, color, options) { + smokeTrailSettings.position = position; + smokeTrailSettings.velocity = randomVec3(-5, 5, 10, 20, -5, 5); + smokeTrailSettings.gravity = randomVec3(-5, 5, -9.8, -9.8, -5, 5); + + playRandomSound(launchSounds, { position: position, volume: 3.0 }); + var smokeID = Entities.addEntity(smokeTrailSettings); + + Script.setTimeout(function() { + Entities.editEntity(smokeID, { emitRate: 0 }); + var position = Entities.getEntityProperties(smokeID, ['position']).position; + fireworkSettings.position = position; + fireworkSettings.colorStart = color; + fireworkSettings.colorFinish = color; + var burstID = Entities.addEntity(fireworkSettings); + playRandomSound(popSounds, { position: position, volume: 3.0 }); + Script.setTimeout(function() { + Entities.editEntity(burstID, { emitRate: 0 }); + }, 250); + Script.setTimeout(function() { + Entities.deleteEntity(smokeID); + Entities.deleteEntity(burstID); + }, 10000); + }, 2000); +} + +playFireworkShow = function(position, numberOfFireworks, duration, offsetRange, colorBegin, colorEnd) { + for (var i = 0; i < numberOfFireworks; i++) { + var randomOffset = randomVec3(-offsetRange.x/2, offsetRange.x/2, + -offsetRange.y/2, offsetRange.y/2, + -offsetRange.z/2, offsetRange.z/2); + var randomPosition = Vec3.sum(position, randomOffset); + Script.setTimeout(function(position) { + return function() { + var color = randomColor(colorBegin.red, colorEnd.red, + colorBegin.green, colorEnd.green, + colorBegin.blue, colorEnd.blue); + shootFirework(position, color, fireworkSettings); + }; + }(randomPosition), Math.random() * duration); + } +}; +//var position = Vec3.sum(MyAvatar.position, { x: 30, y: 0, z: 0 }); +//playFireworkShow(position, 10, 2000, { x: 0, y: 0, z: 0 }, { red: 0, green: 0, blue: 200 }, { red: 0, green: 0, blue: 200 }); diff --git a/hifi-content/huffman/ctf/goalClientEntity.js b/hifi-content/huffman/ctf/goalClientEntity.js new file mode 100644 index 000000000..b16e63594 --- /dev/null +++ b/hifi-content/huffman/ctf/goalClientEntity.js @@ -0,0 +1,50 @@ +/* globals playFireworkShow */ + +(function() { + Script.include("firework.js?" + Date.now()); + + var self = this; + var teleportSound = SoundCache.getSound(Script.resolvePath("sounds/teleport.raw")); + var inCooldown = false; + + self.preload = function(entityID) { + self.entityID = entityID; + + var userData = Entities.getEntityProperties(entityID, 'userData').userData; + try { + userData = JSON.parse(userData); + if (userData.beginColor !== undefined && userData.endColor !== undefined) { + self.beginColor = userData.beginColor; + self.endColor = userData.endColor; + print("bgin:", self.beginColor.red, self.beginColor.green, self.beginColor.blue); + } else { + print("ERROR, colors not found"); + } + } catch (e) { + print("ERROR, could not find gun color"); + } + }; + + self.onScored = function() { + if (inCooldown) { + return; + } + + var position = Entities.getEntityProperties(self.entityID, 'position').position; + playFireworkShow(position, 20, 3000, + { x: 5, y: 2, z: 5 }, + self.beginColor, + self.endColor); + Audio.playSound(teleportSound, { + position: position, + volume: 0.40 + }); + inCooldown = true; + Script.setTimeout(function() { + inCooldown = false; + }, 2000); + }; +}); + + +// http://hifi-content.s3.amazonaws.com/caitlyn/production/soundEmitter/soundLoopEmitter.js diff --git a/hifi-content/huffman/ctf/gunSpawnerClientEntity.js b/hifi-content/huffman/ctf/gunSpawnerClientEntity.js new file mode 100644 index 000000000..8121cfc7a --- /dev/null +++ b/hifi-content/huffman/ctf/gunSpawnerClientEntity.js @@ -0,0 +1,124 @@ +(function() { + var GUN_RED_MODEL_URL = Script.resolvePath("models/portalgun_red.fbx"); + var GUN_BLUE_MODEL_URL = Script.resolvePath("models/portalgun_blue.fbx"); + + var gunProps = { + "collisionsWillMove": 1, + "compoundShapeURL": Script.resolvePath("models/portalgun_collider.obj"), + "dimensions": { + "x": 0.17742760479450226, + "y": 0.38749998807907104, + "z": 0.99309998750686646 + }, + "dynamic": 1, + "gravity": { + "x": 0, + "y": -5, + "z": 0 + }, + "modelURL": Script.resolvePath("models/portalgun_red.fbx"), + "name": "Portal/Gun", + "position": { + "x": 1.4289360046386719, + "y": 0, + "z": 1.4532890319824219 + }, + "rotation": { + "w": 0.51259636878967285, + "x": -0.5248645544052124, + "y": 0.5236133337020874, + "z": -0.43306630849838257 + }, + //lifetime: 100, + velocity: { + x: 0, + y: 0.1, + z: 0 + }, + "script": Script.resolvePath("portalGunClientEntity.js?" + Date.now()), + "shapeType": "compound", + "type": "Model", + "userData": "{\"grabbableKey\":{\"invertSolidWhileHeld\":true},\"wearable\":{\"joints\":{\"RightHand\":[{\"x\":0.1177130937576294,\"y\":0.12922893464565277,\"z\":0.08307232707738876},{\"x\":0.4934672713279724,\"y\":0.3605862259864807,\"z\":0.6394805908203125,\"w\":-0.4664038419723511}],\"LeftHand\":[{\"x\":0.09151676297187805,\"y\":0.13639454543590546,\"z\":0.09354984760284424},{\"x\":-0.19628101587295532,\"y\":0.6418180465698242,\"z\":0.2830369472503662,\"w\":0.6851521730422974}]}}}" + }; + + var lightProps = { + //lifetime: 100, + "color": { + "blue": 255, + "green": 166, + "red": 41 + }, + "cutoff": 90, + "dimensions": { + "x": 5.0777130126953125, + "y": 5.0777130126953125, + "z": 5.0777130126953125 + }, + "falloffRadius": 2.2000000476837158, + "intensity": 5, + "name": "Portal/GunLight", + "localPosition": { + x: 0, + y: 0.1, + z: 0.5 + }, + "type": "Light" + }; + + var gunData = { + red: { + modelURL: GUN_RED_MODEL_URL, + lightColor: { + red: 255, + green: 23, + blue: 96, + } + }, + blue: { + modelURL: GUN_BLUE_MODEL_URL, + lightColor: { + red: 41, + green: 166, + blue: 255, + } + } + }; + + var inCooldown = false; + + this.preload = function(entityID) { + this.entityID = entityID; + }; + + function spawnWeapons() { + if (inCooldown) { + return; + } + + var position = Entities.getEntityProperties(this.entityID, 'position').position; + + var userData = JSON.parse(gunProps.userData); + var colors = ['red', 'blue']; + for (var i = 0; i < colors.length; ++i) { + var color = colors[i]; + gunProps.modelURL = gunData[color].modelURL; + gunProps.position = position; + userData.color = color; + gunProps.userData = JSON.stringify(userData); + var gunID = Entities.addEntity(gunProps); + + lightProps.color = gunData[color].lightColor; + lightProps.parentID = gunID; + Entities.addEntity(lightProps); + } + + inCooldown = true; + Script.setTimeout(function() { + inCooldown = false; + }, 2000); + } + + this.startNearTrigger = spawnWeapons; + this.startFarTrigger = spawnWeapons; + this.clickDownOnEntity = spawnWeapons; +}); diff --git a/hifi-content/huffman/ctf/models/portalgun.fbx b/hifi-content/huffman/ctf/models/portalgun.fbx new file mode 120000 index 000000000..073c1557b --- /dev/null +++ b/hifi-content/huffman/ctf/models/portalgun.fbx @@ -0,0 +1 @@ +../../../alan/dev/Pingportal-Gun-New.fbx \ No newline at end of file diff --git a/hifi-content/huffman/ctf/models/portalgun_blue.fbx b/hifi-content/huffman/ctf/models/portalgun_blue.fbx new file mode 120000 index 000000000..073c1557b --- /dev/null +++ b/hifi-content/huffman/ctf/models/portalgun_blue.fbx @@ -0,0 +1 @@ +../../../alan/dev/Pingportal-Gun-New.fbx \ No newline at end of file diff --git a/hifi-content/huffman/ctf/models/portalgun_collider.obj b/hifi-content/huffman/ctf/models/portalgun_collider.obj new file mode 120000 index 000000000..8557ff2a3 --- /dev/null +++ b/hifi-content/huffman/ctf/models/portalgun_collider.obj @@ -0,0 +1 @@ +../../../alan/dev/Pingpong-Gun-New.obj \ No newline at end of file diff --git a/hifi-content/huffman/ctf/models/portalgun_red.fbx b/hifi-content/huffman/ctf/models/portalgun_red.fbx new file mode 120000 index 000000000..b02853b30 --- /dev/null +++ b/hifi-content/huffman/ctf/models/portalgun_red.fbx @@ -0,0 +1 @@ +../../../alan/dev/PingPortal-Gun-red.fbx \ No newline at end of file diff --git a/hifi-content/huffman/ctf/origina_portal_gun.js b/hifi-content/huffman/ctf/origina_portal_gun.js new file mode 100644 index 000000000..89bb5fa66 --- /dev/null +++ b/hifi-content/huffman/ctf/origina_portal_gun.js @@ -0,0 +1,210 @@ +// pingPongGun.js +// +// Script Type: Entity +// Created by James B. Pollack @imgntn on 9/21/2015 +// Copyright 2015 High Fidelity, Inc. +// +// This script shoots a ping pong ball. +// 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 _this = this; + + var SHOOTING_SOUND_URL = 'http://hifi-content.s3.amazonaws.com/DomainContent/Event%20/Sounds/Gun/GunFire02.wav'; + + function PingPongGun() { + return; + } + + //if the trigger value goes below this value, reload the gun. + var RELOAD_THRESHOLD = 0.95; + var GUN_TIP_FWD_OFFSET = -1; + var GUN_TIP_UP_OFFSET = 0.12; + var GUN_FORCE = 20; + var BALL_RESTITUTION = 0.2; + var BALL_LINEAR_DAMPING = 0.1; + var BALL_DENSITY = 10000; + var BALL_GRAVITY = { + x: 0, + y: -4.8, + z: 0 + }; + + var PING_PONG_GUN_GRAVITY = { + x: 0, + y: -10, + z: 0 + }; + + var BALL_DIMENSIONS = { + x: 2.5, + y: 2.5, + z: 2.5 + }; + + var BALL_ANGULAR_VEL = { + x: 2, + y: 3, + z: 1 + }; + + + + var TRIGGER_CONTROLS = [ + Controller.Standard.LT, + Controller.Standard.RT, + ]; + + + PingPongGun.prototype = { + hand: null, + gunTipPosition: null, + canShoot: false, + canShootTimeout: null, + + startEquip: function(entityID, args) { + this.hand = args[0] == "left" ? 0 : 1; + }, + + continueEquip: function(entityID, args) { + if (this.canShootTimeout !== null) { + Script.clearTimeout(this.canShootTimeout); + } + this.checkTriggerPressure(this.hand); + }, + + releaseEquip: function(entityID, args) { + var _this = this; + this.canShootTimeout = Script.setTimeout(function() { + _this.canShoot = false; + }, 250); + }, + + checkTriggerPressure: function(gunHand) { + this.triggerValue = Controller.getValue(TRIGGER_CONTROLS[gunHand]); + if (this.triggerValue < RELOAD_THRESHOLD) { + this.canShoot = true; + } else if (this.triggerValue >= RELOAD_THRESHOLD && this.canShoot === true) { + var gunProperties = Entities.getEntityProperties(this.entityID, ["position", "rotation"]); + this.shootBall(gunProperties); + this.canShoot = false; + } + + return; + }, + + shootBall: function(gunProperties) { + var forwardVec = Quat.getFront(Quat.multiply(gunProperties.rotation, Quat.fromPitchYawRollDegrees(0, 180, 0))); + forwardVec = Vec3.normalize(forwardVec); + forwardVec = Vec3.multiply(forwardVec, GUN_FORCE); + var gunTipPosition = this.getGunTipPosition(gunProperties); + + var projectileProperties = { + name: 'Glow-Projectile', + type: 'Model', + modelURL: "http://hifi-content.s3.amazonaws.com/alan/dev/Glow-ball-blue.fbx", + dimensions: BALL_DIMENSIONS, + damping: BALL_LINEAR_DAMPING, + gravity: BALL_GRAVITY, + restitution: BALL_RESTITUTION, + density: BALL_DENSITY, + dynamic: true, + rotation: gunProperties.rotation, + position: gunTipPosition, + gravity: PING_PONG_GUN_GRAVITY, + angularDamping: 0, + angularVelocity: BALL_ANGULAR_VEL, + velocity: forwardVec, + lifetime: 10, + collisionless: true, + visible: true, + }; + + var projectileID = Entities.addEntity(projectileProperties); + + + var portalProperties = { + name: 'Portal-Projectile', + type: 'Sphere', + dimensions: BALL_DIMENSIONS, + parentID: projectileID, + damping: BALL_LINEAR_DAMPING, + gravity: BALL_GRAVITY, + restitution: BALL_RESTITUTION, + density: BALL_DENSITY, + dynamic: false, + rotation: gunProperties.rotation, + position: gunTipPosition, + gravity: PING_PONG_GUN_GRAVITY, + angularDamping: 0, + angularVelocity: BALL_ANGULAR_VEL, + velocity: forwardVec, + lifetime: 10, + visible: false, + script: 'http://hifi-content.s3.amazonaws.com/alan/dev/Scripts/portal-lionsgate.js', + collisionless: true, + }; + + Entities.addEntity(portalProperties); + + + this.playSoundAtCurrentPosition(gunProperties.position); + }, + + playSoundAtCurrentPosition: function(position) { + var audioProperties = { + volume: 0.9, + position: position + }; + + Audio.playSound(this.SHOOTING_SOUND, audioProperties); + }, + + getGunTipPosition: function(properties) { + //the tip of the gun is going to be in a different place than the center, so we move in space relative to the model to find that position + var frontVector = Quat.getFront(properties.rotation); + var frontOffset = Vec3.multiply(frontVector, GUN_TIP_FWD_OFFSET); + var upVector = Quat.getUp(properties.rotation); + var upOffset = Vec3.multiply(upVector, GUN_TIP_UP_OFFSET); + + var gunTipPosition = Vec3.sum(properties.position, frontOffset); + gunTipPosition = Vec3.sum(gunTipPosition, upOffset); + + return gunTipPosition; + }, + + preload: function(entityID) { + this.entityID = entityID; + this.SHOOTING_SOUND = SoundCache.getSound(SHOOTING_SOUND_URL); + // this.createTipEntity(entityID); + }, + createTipEntity: function(entityID) { + //for debugging where its going to shoot from + var gunProperties = Entities.getEntityProperties(entityID, ["position", "rotation"]); + + var tipProps = { + name: 'Ping pong tip test', + dimensions: { + x: 0.1, + y: 0.1, + z: 0.1 + }, + color: { + red: 0, + green: 255, + blue: 0 + }, + type: 'Box', + parentID: entityID, + position: this.getGunTipPosition(gunProperties) + }; + var tip = Entities.addEntity(tipProps); + } + + }; + + // entity scripts should return a newly constructed object of our type + return new PingPongGun(); +}); \ No newline at end of file diff --git a/hifi-content/huffman/ctf/portalBulletClientEntity.js b/hifi-content/huffman/ctf/portalBulletClientEntity.js new file mode 100644 index 000000000..0b5e7f860 --- /dev/null +++ b/hifi-content/huffman/ctf/portalBulletClientEntity.js @@ -0,0 +1,47 @@ +(function() { + this.preload = function(entityID) { + print("Loading portal bullet script"); + + this.teleportSound = SoundCache.getSound(Script.resolvePath("sounds/teleport.raw")); + this.portalTargetLocation = undefined; + + var userData = Entities.getEntityProperties(entityID, 'userData').userData; + try { + this.portalTargetLocation = JSON.parse(userData).portalTargetLocation; + } catch (e) { + this.portalTargetLocation = undefined; + } + + if (this.portalTargetLocation === undefined) { + print("ERROR, could not find portalTargetLocation in userData"); + } else { + print("Portal target location is: ", this.portalTargetLocation); + } + }; + + this.enterEntity = function(entityID) { + print("Entered bullet entity, the destination is " + this.portalTargetLocation); + + if (this.teleportSound.downloaded) { + var position = Entities.getEntityProperties(this.entityID, 'position').position; + Audio.playSound(this.teleportSound, { + position: position, + volume: 0.40, + localOnly: true + }); + } + + if (this.portalTargetLocation !== undefined) { + print("Teleporting to " + this.portalTargetLocation); + Window.location = this.portalTargetLocation; + } + + // Notify any instances of the ball that we have been hit ensuring that + // the ball will be dropped if we are holding it. + Messages.sendLocalMessage("Portal-Game", "hit"); + }; + + this.unload = function() { + print("unloading teleport script"); + }; +}); diff --git a/hifi-content/huffman/ctf/portalGunClientEntity.js b/hifi-content/huffman/ctf/portalGunClientEntity.js new file mode 100644 index 000000000..b7c43e3ff --- /dev/null +++ b/hifi-content/huffman/ctf/portalGunClientEntity.js @@ -0,0 +1,222 @@ +// pingPongGun.js +// +// Script Type: Entity +// Created by James B. Pollack @imgntn on 9/21/2015 +// Copyright 2015 High Fidelity, Inc. +// +// This script shoots a ping pong ball. +// 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 TRIGGER_THRESHOLD = 0.3; + + var BULLET_BLUE_MODEL_URL = "http://hifi-content.s3.amazonaws.com/alan/dev/Glow-ball-blue.fbx"; + var BULLET_RED_MODEL_URL = "http://hifi-content.s3.amazonaws.com/alan/dev/Glow-ball-red.fbx"; + + var GUN_LOAD_SOUND_URL = "https://hifi-content.s3.amazonaws.com/DomainContent/Event%20/Sounds/Gun/GunLoad02.wav"; + var GUN_FIRE1_SOUND_URL = "https://hifi-content.s3.amazonaws.com/DomainContent/Event%20/Sounds/Gun/GunFire01.wav"; + var GUN_FIRE2_SOUND_URL = "https://hifi-content.s3.amazonaws.com/DomainContent/Event%20/Sounds/Gun/GunFire02.wav"; + var GUN_FIRE3_SOUND_URL = "https://hifi-content.s3.amazonaws.com/DomainContent/Event%20/Sounds/Gun/GunFire03.wav"; + + var GUN_TIP_FWD_OFFSET = -1; + var GUN_TIP_UP_OFFSET = 0.12; + var GUN_FORCE = 20; + var BALL_RESTITUTION = 0.2; + var BALL_LINEAR_DAMPING = 0.1; + var BALL_DENSITY = 10000; + + var BALL_GRAVITY = { + x: 0, + y: -10, + z: 0 + }; + + var BALL_DIMENSIONS = { + x: 2.5, + y: 2.5, + z: 2.5 + }; + + var BALL_COLLIDER_DIMENSIONS = { + x: 0.94, + y: 2.0, + z: 0.94 + }; + + var BALL_ANGULAR_VEL = { + x: 2, + y: 3, + z: 1 + }; + + var TRIGGER_CONTROLS = [ + Controller.Standard.LT, + Controller.Standard.RT + ]; + + function PortalGun() { + } + + PortalGun.prototype = { + hand: null, + gunTipPosition: null, + cooldownActive: false, + + preload: function(entityID) { + this.entityID = entityID; + this.gunFireSound = SoundCache.getSound(GUN_FIRE1_SOUND_URL); + this.gunLoadSound = SoundCache.getSound(GUN_LOAD_SOUND_URL); + + this.hasReleasedInitialTriggerPress = false; + + this.color = 'red'; + + var userData = Entities.getEntityProperties(entityID, 'userData').userData; + try { + userData = JSON.parse(userData); + if (userData.color === 'red' || userData.color === 'blue') { + this.color = userData.color; + } else { + print("ERROR, invalid color:", userData.color); + } + } catch (e) { + print("ERROR, could not find gun color"); + } + }, + startEquip: function(entityID, args) { + this.hand = args[0] === "left" ? 0 : 1; + }, + continueEquip: function(entityID, args) { + if (this.cooldownActive) { + return; + } + + var triggerValue = Controller.getValue(TRIGGER_CONTROLS[this.hand]); + if (triggerValue > TRIGGER_THRESHOLD) { + if (this.hasReleasedInitialTriggerPress) { + this.shootBall(); + } + } else { + this.hasReleasedInitialTriggerPress = true; + } + }, + releaseEquip: function(entityID, args) { + }, + shootBall: function() { + if (this.cooldownActive) { + print("Not allowing portal bullet to be shot while cooldown active"); + return; + } + Controller.triggerHapticPulse(10.0, 0.5, this.hand); + + var gunProperties = Entities.getEntityProperties(this.entityID, ["position", "rotation"]); + + var gunTipPosition = this.getGunTipPosition(gunProperties); + + var audioProperties = { + volume: 0.9, + position: gunTipPosition, + localOnly: true + }; + + Audio.playSound(this.gunFireSound, audioProperties); + + var forwardVec = Quat.getFront(Quat.multiply(gunProperties.rotation, Quat.fromPitchYawRollDegrees(0, 180, 0))); + forwardVec = Vec3.normalize(forwardVec); + forwardVec = Vec3.multiply(forwardVec, GUN_FORCE); + + var projectileProperties = { + name: 'CTF/PortalBullet', + type: 'Model', + modelURL: this.color === 'blue' ? BULLET_BLUE_MODEL_URL : BULLET_RED_MODEL_URL, + dimensions: BALL_DIMENSIONS, + damping: BALL_LINEAR_DAMPING, + gravity: BALL_GRAVITY, + restitution: BALL_RESTITUTION, + density: BALL_DENSITY, + dynamic: true, + rotation: gunProperties.rotation, + position: gunTipPosition, + angularDamping: 0, + angularVelocity: BALL_ANGULAR_VEL, + velocity: forwardVec, + lifetime: 10, + collisionless: true, + visible: true + }; + var projectileID = Entities.addEntity(projectileProperties); + + var portalProperties = { + name: 'CTF/PortalCollider', + type: 'Sphere', + localPosition: { x: 0, y: 0, z: 0 }, + dimensions: BALL_DIMENSIONS, + parentID: projectileID, + dynamic: false, + lifetime: 10, + visible: false, + script: Script.resolvePath("portalBulletClientEntity.js"), + collisionless: true, + userData: JSON.stringify({ + //portalTargetLocation: "hifi://lionsgate.highfidelity.io/-104.376,-0.496867,-8.28224/0,0.721841,0,0.692059" + portalTargetLocation: "/16.0555,-0.372284,18.5259/0,0.631228,0,0.775597" + }) + }; + Entities.addEntity(portalProperties); + + var self = this; + this.cooldownActive = true; + Script.setTimeout(function() { + var gunProperties = Entities.getEntityProperties(self.entityID, ["position", "rotation"]); + var gunTipPosition = self.getGunTipPosition(gunProperties); + var audioProperties = { + volume: 0.9, + position: gunTipPosition, + localOnly: true + }; + Audio.playSound(self.gunLoadSound, audioProperties); + self.cooldownActive = false; + }, 1000); + }, + getGunTipPosition: function(properties) { + // the tip of the gun is going to be in a different place than the center, + // so we move in space relative to the model to find that position + var frontVector = Quat.getFront(properties.rotation); + var frontOffset = Vec3.multiply(frontVector, GUN_TIP_FWD_OFFSET); + var upVector = Quat.getUp(properties.rotation); + var upOffset = Vec3.multiply(upVector, GUN_TIP_UP_OFFSET); + + var gunTipPosition = Vec3.sum(properties.position, frontOffset); + gunTipPosition = Vec3.sum(gunTipPosition, upOffset); + + return gunTipPosition; + }, + createTipEntity: function(entityID) { + // for debugging where its going to shoot from + var gunProperties = Entities.getEntityProperties(entityID, ["position", "rotation"]); + + var tipProps = { + name: 'Ping pong tip test', + dimensions: { + x: 0.1, + y: 0.1, + z: 0.1 + }, + color: { + red: 0, + green: 255, + blue: 0 + }, + type: 'Box', + parentID: entityID, + position: this.getGunTipPosition(gunProperties) + }; + Entities.addEntity(tipProps); + } + }; + + // entity scripts should return a newly varructed object of our type + return new PortalGun(); +}); diff --git a/hifi-content/huffman/ctf/portalgun.json b/hifi-content/huffman/ctf/portalgun.json new file mode 100644 index 000000000..cbd6402a4 --- /dev/null +++ b/hifi-content/huffman/ctf/portalgun.json @@ -0,0 +1,81 @@ +{ + "Entities": [ + { + "clientOnly": 0, + "collisionsWillMove": 1, + "compoundShapeURL": "http://hifi-production.s3.amazonaws.com/tutorials/pingPongGun/Pingpong-Gun-New.obj", + "created": "2016-11-04T22:25:04Z", + "dimensions": { + "x": 0.17742760479450226, + "y": 0.38749998807907104, + "z": 0.99309998750686646 + }, + "dynamic": 1, + "gravity": { + "x": 0, + "y": -5, + "z": 0 + }, + "id": "{a871719d-051d-4899-81f8-f624c04c3e3a}", + "modelURL": "http://hifi-content.s3.amazonaws.com/alan/dev/Pingportal-Gun-New.fbx?1", + "name": "Tutorial Ping Pong Gun", + "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", + "queryAACube": { + "scale": 1.0806869268417358, + "x": -0.54034346342086792, + "y": -0.54034346342086792, + "z": -0.54034346342086792 + }, + "rotation": { + "w": -0.14616614580154419, + "x": -0.68838024139404297, + "y": 0.69466698169708252, + "z": 0.14915692806243896 + }, + "script": "http://hifi-content.s3.amazonaws.com/alan/dev/Scripts/ping-portal-welcome.js?3", + "shapeType": "compound", + "type": "Model", + "userData": "{\"grabbableKey\":{\"invertSolidWhileHeld\":true},\"wearable\":{\"joints\":{\"RightHand\":[{\"x\":0.1177130937576294,\"y\":0.12922893464565277,\"z\":0.08307232707738876},{\"x\":0.4934672713279724,\"y\":0.3605862259864807,\"z\":0.6394805908203125,\"w\":-0.4664038419723511}],\"LeftHand\":[{\"x\":0.09151676297187805,\"y\":0.13639454543590546,\"z\":0.09354984760284424},{\"x\":-0.19628101587295532,\"y\":0.6418180465698242,\"z\":0.2830369472503662,\"w\":0.6851521730422974}]}}}" + }, + { + "clientOnly": 0, + "color": { + "blue": 255, + "green": 166, + "red": 41 + }, + "created": "2016-11-04T22:55:39Z", + "cutoff": 90, + "dimensions": { + "x": 5.0777130126953125, + "y": 5.0777130126953125, + "z": 5.0777130126953125 + }, + "falloffRadius": 1.7000000476837158, + "id": "{a240a5b9-8ec5-46f7-a443-fd99ee08ba33}", + "intensity": 3.2999999523162842, + "name": "PingPortal-Light", + "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", + "parentID": "{a871719d-051d-4899-81f8-f624c04c3e3a}", + "position": { + "x": -0.071898072957992554, + "y": 0.1922331303358078, + "z": 0.59060537815093994 + }, + "queryAACube": { + "scale": 8.7948570251464844, + "x": 6.5513162612915039, + "y": -4.9521479606628418, + "z": -150.72532653808594 + }, + "rotation": { + "w": -0.14616614580154419, + "x": 0.68838024139404297, + "y": -0.69466698169708252, + "z": -0.14915692806243896 + }, + "type": "Light" + } + ], + "Version": 64 +} diff --git a/hifi-content/huffman/ctf/sounds/gunFire.wav b/hifi-content/huffman/ctf/sounds/gunFire.wav new file mode 100644 index 000000000..88b11e741 --- /dev/null +++ b/hifi-content/huffman/ctf/sounds/gunFire.wav @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:99e52a695d2477a48f71da9f15f40f02ec1073768eba8e26ed0cda07c34e93cb +size 145056 diff --git a/hifi-content/huffman/ctf/sounds/pong_sound.wav b/hifi-content/huffman/ctf/sounds/pong_sound.wav new file mode 100644 index 000000000..388d1bad1 --- /dev/null +++ b/hifi-content/huffman/ctf/sounds/pong_sound.wav @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0bab5297e882dd92ca7fcb5f1e043386249d28cc5a013fc7a48c2660386c81aa +size 46926 diff --git a/hifi-content/huffman/ctf/sounds/teleport.raw b/hifi-content/huffman/ctf/sounds/teleport.raw new file mode 100644 index 000000000..7ee3b4ce4 Binary files /dev/null and b/hifi-content/huffman/ctf/sounds/teleport.raw differ diff --git a/hifi-content/huffman/ctf/spawnPortalGun.js b/hifi-content/huffman/ctf/spawnPortalGun.js new file mode 100644 index 000000000..531216a36 --- /dev/null +++ b/hifi-content/huffman/ctf/spawnPortalGun.js @@ -0,0 +1,99 @@ +var GUN_RED_MODEL_URL = Script.resolvePath("models/portalgun_red.fbx"); +var GUN_BLUE_MODEL_URL = Script.resolvePath("models/portalgun_blue.fbx"); + +var gunProps = { + "collisionsWillMove": 1, + "compoundShapeURL": Script.resolvePath("models/portalgun_collider.obj"), + "dimensions": { + "x": 0.17742760479450226, + "y": 0.38749998807907104, + "z": 0.99309998750686646 + }, + "dynamic": 1, + "gravity": { + "x": 0, + "y": -5, + "z": 0 + }, + "modelURL": Script.resolvePath("models/portalgun_red.fbx"), + "name": "Portal/Gun", + "position": { + "x": 1.4289360046386719, + "y": 0, + "z": 1.4532890319824219 + }, + "rotation": { + "w": 0.51259636878967285, + "x": -0.5248645544052124, + "y": 0.5236133337020874, + "z": -0.43306630849838257 + }, + lifetime: 100, + velocity: { + x: 0, + y: 0.5, + z: 0 + }, + "script": Script.resolvePath("portalGunClientEntity.js?" + Date.now()), + "shapeType": "compound", + "type": "Model", + "userData": "{\"grabbableKey\":{\"invertSolidWhileHeld\":true},\"wearable\":{\"joints\":{\"RightHand\":[{\"x\":0.1177130937576294,\"y\":0.12922893464565277,\"z\":0.08307232707738876},{\"x\":0.4934672713279724,\"y\":0.3605862259864807,\"z\":0.6394805908203125,\"w\":-0.4664038419723511}],\"LeftHand\":[{\"x\":0.09151676297187805,\"y\":0.13639454543590546,\"z\":0.09354984760284424},{\"x\":-0.19628101587295532,\"y\":0.6418180465698242,\"z\":0.2830369472503662,\"w\":0.6851521730422974}]}}}" +}; + +var lightProps = { + lifetime: 100, + "color": { + "blue": 255, + "green": 166, + "red": 41 + }, + "cutoff": 90, + "dimensions": { + "x": 5.0777130126953125, + "y": 5.0777130126953125, + "z": 5.0777130126953125 + }, + "falloffRadius": 2.2000000476837158, + "intensity": 5, + "name": "Portal/GunLight", + "localPosition": { + x: 0, + y: 0.1, + z: 0.5 + }, + "type": "Light" +}; + +var userData = JSON.parse(gunProps.userData); +var gunData = { + red: { + modelURL: GUN_RED_MODEL_URL, + lightColor: { + red: 255, + green: 23, + blue: 96, + } + }, + blue: { + modelURL: GUN_BLUE_MODEL_URL, + lightColor: { + red: 41, + green: 166, + blue: 255, + } + } +}; +var models = [GUN_RED_MODEL_URL, GUN_BLUE_MODEL_URL]; +var colors = ['red', 'blue']; +for (var i = 0; i < colors.length; ++i) { + var color = colors[i]; + gunProps.modelURL = gunData[color].modelURL; + gunProps.position = MyAvatar.position; + userData.color = color; + gunProps.userData = JSON.stringify(userData); + var gunID = Entities.addEntity(gunProps); + + lightProps.color = gunData[color].lightColor; + lightProps.parentID = gunID; + Entities.addEntity(lightProps); +} diff --git a/hifi-content/huffman/ctf/utils.js b/hifi-content/huffman/ctf/utils.js new file mode 100644 index 000000000..4cc179b81 --- /dev/null +++ b/hifi-content/huffman/ctf/utils.js @@ -0,0 +1,93 @@ +// +// utils.js +// examples/baseball/ +// +// Created by Ryan Huffman on Nov 9, 2015 +// 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 +// + +randomInt = function(low, high) { + print("low, high", low, high); + return Math.floor(randomFloat(low, high)); +}; + +randomFloat = function(low, high) { + if (high === undefined) { + high = low; + low = 0; + } + return low + Math.random() * (high - low); +}; + +randomColor = function(redMin, redMax, greenMin, greenMax, blueMin, blueMax) { + return { + red: Math.ceil(randomInt(redMin, redMax)), + green: Math.ceil(randomInt(greenMin, greenMax)), + blue: Math.ceil(randomInt(blueMin, blueMax)), + } +}; + +randomVec3 = function(xMin, xMax, yMin, yMax, zMin, zMax) { + return { + x: randomFloat(xMin, xMax), + y: randomFloat(yMin, yMax), + z: randomFloat(zMin, zMax), + } +}; + +getSounds = function(soundURLs) { + var sounds = []; + for (var i = 0; i < soundURLs.length; ++i) { + sounds.push(SoundCache.getSound(soundURLs[i], false)); + } + return sounds; +}; + +playRandomSound = function(sounds, options) { + if (options === undefined) { + options = { + volume: 1.0, + position: MyAvatar.position, + } + } + return Audio.playSound(sounds[randomInt(sounds.length)], options); +} + +shallowCopy = function(obj) { + var copy = {} + for (var key in obj) { + copy[key] = obj[key]; + } + return copy; +} + +findEntity = function(properties, searchRadius) { + var entities = findEntities(properties, searchRadius); + return entities.length > 0 ? entities[0] : null; +} + +// Return all entities with properties `properties` within radius `searchRadius` +findEntities = function(properties, searchRadius) { + var entities = Entities.findEntities(MyAvatar.position, searchRadius); + var matchedEntities = []; + var keys = Object.keys(properties); + for (var i = 0; i < entities.length; ++i) { + var match = true; + var candidateProperties = Entities.getEntityProperties(entities[i], keys); + for (var key in properties) { + if (candidateProperties[key] != properties[key]) { + // This isn't a match, move to next entity + match = false; + break; + } + } + if (match) { + matchedEntities.push(entities[i]); + } + } + + return matchedEntities; +} diff --git a/hifi-content/huffman/essTest.js b/hifi-content/huffman/essTest.js new file mode 100644 index 000000000..698873da6 --- /dev/null +++ b/hifi-content/huffman/essTest.js @@ -0,0 +1,9 @@ +(function() { + print("Inside ctor"); + this.preload = function() { + print("inside preload"); + } + this.unload = function() { + print("inside preload"); + } +});