Merge pull request #5841 from ericrius1/toybox

Toybox master reset script
This commit is contained in:
Brad Hefta-Gaub 2015-10-02 11:27:43 -07:00
commit 5a0ff4b1a2
7 changed files with 1452 additions and 282 deletions

View file

@ -1,252 +0,0 @@
(function() {
// Script.include("../libraries/utils.js");
//Need absolute path for now, for testing before PR merge and s3 cloning. Will change post-merge
Script.include("../libraries/utils.js");
GRAB_FRAME_USER_DATA_KEY = "grabFrame";
this.userData = {};
var TIP_OFFSET_Z = 0.14;
var TIP_OFFSET_Y = 0.04;
var ZERO_VEC = {
x: 0,
y: 0,
z: 0
}
var MAX_POINTS_PER_LINE = 40;
var MIN_POINT_DISTANCE = 0.01;
var STROKE_WIDTH = 0.02;
var self = this;
var timeSinceLastMoved = 0;
var RESET_TIME_THRESHOLD = 5;
var DISTANCE_FROM_HOME_THRESHOLD = 0.5;
var HOME_POSITION = {
x: 549.12,
y: 495.555,
z: 503.77
};
this.getUserData = function() {
if (this.properties.userData) {
this.userData = JSON.parse(this.properties.userData);
}
}
this.updateUserData = function() {
Entities.editEntity(this.entityId, {
userData: JSON.stringify(this.userData)
});
}
this.update = function(deltaTime) {
self.getUserData();
self.properties = Entities.getEntityProperties(self.entityId);
if (Vec3.length(self.properties.velocity) < 0.1 && Vec3.distance(HOME_POSITION, self.properties.position) > DISTANCE_FROM_HOME_THRESHOLD) {
timeSinceLastMoved += deltaTime;
if (timeSinceLastMoved > RESET_TIME_THRESHOLD) {
self.reset();
timeSinceLastMoved = 0;
}
} else {
timeSinceLastMoved = 0;
}
//Only activate for the user who grabbed the object
if (self.userData.grabKey && self.userData.grabKey.activated === true && self.userData.grabKey.avatarId == MyAvatar.sessionUUID) {
if (self.activated !== true) {
//We were just grabbed, so create a particle system
self.grab();
}
//Move emitter to where entity is always when its activated
self.sprayStream();
} else if (self.userData.grabKey && self.userData.grabKey.activated === false && self.activated) {
self.letGo();
}
}
this.grab = function() {
this.activated = true;
var animationSettings = JSON.stringify({
fps: 30,
loop: true,
firstFrame: 1,
lastFrame: 10000,
running: true
});
var PI = 3.141593;
var DEG_TO_RAD = PI / 180.0;
this.paintStream = Entities.addEntity({
type: "ParticleEffect",
animationSettings: animationSettings,
position: this.properties.position,
textures: "https://raw.githubusercontent.com/ericrius1/SantasLair/santa/assets/smokeparticle.png",
emitSpeed: 0,
speedSpread: 0.02,
polarFinish: 2 * DEG_TO_RAD,
emitAcceleration: ZERO_VEC,
emitRate: 100,
particleRadius: 0.01,
color: {
red: 170,
green: 20,
blue: 150
},
lifetime: 50, //probably wont be holding longer than this straight
});
}
this.letGo = function() {
this.activated = false;
Entities.deleteEntity(this.paintStream);
this.paintStream = null;
}
this.reset = function() {
Entities.editEntity(self.entityId, {
position: HOME_POSITION,
rotation: Quat.fromPitchYawRollDegrees(0, 0, 0),
angularVelocity: ZERO_VEC,
velocity: ZERO_VEC
});
}
this.sprayStream = function() {
var forwardVec = Quat.getFront(Quat.multiply(self.properties.rotation , Quat.fromPitchYawRollDegrees(0, 90, 0)));
forwardVec = Vec3.normalize(forwardVec);
var upVec = Quat.getUp(self.properties.rotation);
var position = Vec3.sum(self.properties.position, Vec3.multiply(forwardVec, TIP_OFFSET_Z));
position = Vec3.sum(position, Vec3.multiply(upVec, TIP_OFFSET_Y))
Entities.editEntity(self.paintStream, {
position: position,
emitOrientation: forwardVec,
emitSpeed: 5
});
//Now check for an intersection with an entity
//move forward so ray doesnt intersect with gun
var origin = Vec3.sum(position, forwardVec);
var pickRay = {
origin: origin,
direction: Vec3.multiply(forwardVec, 2)
}
var intersection = Entities.findRayIntersection(pickRay, true);
if (intersection.intersects) {
var normal = Vec3.multiply(-1, Quat.getFront(intersection.properties.rotation));
this.paint(intersection.intersection, normal);
}
}
this.paint = function(position, normal) {
if (!this.painting) {
this.newStroke(position);
this.painting = true;
}
if (this.strokePoints.length > MAX_POINTS_PER_LINE) {
this.painting = false;
return;
}
var localPoint = Vec3.subtract(position, this.strokeBasePosition);
//Move stroke a bit forward along normal so it doesnt zfight with mesh its drawing on
localPoint = Vec3.sum(localPoint, Vec3.multiply(normal, .1));
if (this.strokePoints.length > 0 && Vec3.distance(localPoint, this.strokePoints[this.strokePoints.length - 1]) < MIN_POINT_DISTANCE) {
//need a minimum distance to avoid binormal NANs
return;
}
this.strokePoints.push(localPoint);
this.strokeNormals.push(normal);
this.strokeWidths.push(STROKE_WIDTH);
Entities.editEntity(this.currentStroke, {
linePoints: this.strokePoints,
normals: this.strokeNormals,
strokeWidths: this.strokeWidths
});
}
this.newStroke = function(position) {
this.strokeBasePosition = position;
this.currentStroke = Entities.addEntity({
position: position,
type: "PolyLine",
color: {
red: randInt(160, 250),
green: randInt(10, 20),
blue: randInt(190, 250)
},
dimensions: {
x: 50,
y: 50,
z: 50
},
lifetime: 100
});
this.strokePoints = [];
this.strokeNormals = [];
this.strokeWidths = [];
this.strokes.push(this.currentStroke);
}
this.preload = function(entityId) {
this.strokes = [];
this.activated = false;
this.entityId = entityId;
this.properties = Entities.getEntityProperties(self.entityId);
this.getUserData();
//Only activate for the avatar who is grabbing the can!
if (this.userData.grabKey && this.userData.grabKey.activated) {
this.activated = true;
}
if (!this.userData.grabFrame) {
var data = {
relativePosition: {
x: 0,
y: 0,
z: 0
},
relativeRotation: Quat.fromPitchYawRollDegrees(0, 0, 0)
}
setEntityCustomData(GRAB_FRAME_USER_DATA_KEY, this.entityId, data);
}
}
this.unload = function() {
Script.update.disconnect(this.update);
if(this.paintStream) {
Entities.deleteEntity(this.paintStream);
}
this.strokes.forEach(function(stroke) {
Entities.deleteEntity(stroke);
});
}
Script.update.connect(this.update);
});
function randFloat(min, max) {
return Math.random() * (max - min) + min;
}
function randInt(min, max) {
return Math.floor(Math.random() * (max - min)) + min;
}

52
examples/toys/cat.js Normal file
View file

@ -0,0 +1,52 @@
//
// cat.js
// examples/toybox/entityScripts
//
// Created by Eric Levin on 9/21/15.
// Copyright 2015 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
/*global Cat, print, MyAvatar, Entities, AnimationCache, SoundCache, Scene, Camera, Overlays, Audio, HMD, AvatarList, AvatarManager, Controller, UndoStack, Window, Account, GlobalServices, Script, ScriptDiscoveryService, LODManager, Menu, Vec3, Quat, AudioDevice, Paths, Clipboard, Settings, XMLHttpRequest, randFloat, randInt */
(function() {
var _this;
Cat = function() {
_this = this;
this.meowSound = SoundCache.getSound("https://s3.amazonaws.com/hifi-public/sounds/Animals/cat_meow.wav");
};
Cat.prototype = {
isMeowing: false,
injector: null,
startTouch: function() {
if (this.isMeowing !== true) {
this.meow();
this.isMeowing = true;
}
},
meow: function() {
this.injector = Audio.playSound(this.meowSound, {
position: this.position,
volume: 0.1
});
Script.setTimeout(function() {
_this.isMeowing = false;
}, this.soundClipTime);
},
preload: function(entityID) {
this.entityID = entityID;
this.position = Entities.getEntityProperties(this.entityID, "position").position;
this.soundClipTime = 700;
},
};
// entity scripts always need to return a newly constructed object of our type
return new Cat();
});

View file

@ -15,21 +15,14 @@
(function() {
Script.include("../../utilities.js");
Script.include("../../libraries/utils.js");
var _this;
// this is the "constructor" for the entity as a JS object we don't do much here
var Doll = function() {
_this = this;
this.screamSounds = [SoundCache.getSound("https://hifi-public.s3.amazonaws.com/sounds/KenDoll_1%2303.wav")];
};
Doll.prototype = {
startAnimationSetting: JSON.stringify({
running: true,
fps: 30,
startFrame: 0,
lastFrame: 128,
startAutomatically: true
}),
stopAnimationSetting: JSON.stringify({running: false}),
audioInjector: null,
isGrabbed: false,
setLeftHand: function() {
@ -41,26 +34,27 @@
},
startNearGrab: function() {
if (this.isGrabbed === false) {
Entities.editEntity(this.entityID, {
animationURL: "https://hifi-public.s3.amazonaws.com/models/Bboys/zombie_scream.fbx",
animationFrameIndex: 0
});
Entities.editEntity(this.entityID, {
animationURL: "https://hifi-public.s3.amazonaws.com/models/Bboys/zombie_scream.fbx",
animationSettings: this.startAnimationSetting
});
Entities.editEntity(_this.entityID, {
animationIsPlaying: true
});
var position = Entities.getEntityProperties(this.entityID, "position").position;
this.audioInjector = Audio.playSound(this.screamSounds[randInt(0, this.screamSounds.length)], {
position: position,
volume: 0.1
});
var position = Entities.getEntityProperties(this.entityID, "position").position;
this.audioInjector = Audio.playSound(this.screamSounds[randInt(0, this.screamSounds.length)], {
position: position,
volume: 0.1
});
this.isGrabbed = true;
this.initialHand = this.hand;
}
this.isGrabbed = true;
this.initialHand = this.hand;
},
continueNearGrab: function() {
var props = Entities.getEntityProperties(this.entityID, "position");
var props = Entities.getEntityProperties(this.entityID, ["position"]);
var audioOptions = {
position: props.position
};
@ -69,24 +63,23 @@
releaseGrab: function() {
if (this.isGrabbed === true && this.hand === this.initialHand) {
this.audioInjector.stop();
Entities.editEntity(this.entityID, {
animationFrameIndex: 0
});
Entities.editEntity(this.entityID, {
animationSettings: this.stopAnimationSetting,
animationURL: "http://hifi-public.s3.amazonaws.com/models/Bboys/bboy2/bboy2.fbx",
animationURL: "http://hifi-public.s3.amazonaws.com/models/Bboys/bboy2/bboy2.fbx"
});
this.isGrabbed = false;
}
},
preload: function(entityID) {
// preload() will be called when the entity has become visible (or known) to the interface
// it gives us a chance to set our local JavaScript object up. In this case it means:
// * remembering our entityID, so we can access it in cases where we're called without an entityID
this.entityID = entityID;
},
};
// entity scripts always need to return a newly constructed object of our type
return new Doll();
});
});

View file

@ -0,0 +1,202 @@
//
// lightSwitchGarage.js.js
// examples/entityScripts
//
// Created by Eric Levin on 9/21/15.
// Copyright 2015 High Fidelity, Inc.
//
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
(function() {
var _this;
// this is the "constructor" for the entity as a JS object we don't do much here, but we do want to remember
// our this object, so we can access it in cases where we're called without a this (like in the case of various global signals)
LightSwitchGarage = function() {
_this = this;
this.lightStateKey = "lightStateKey";
this.resetKey = "resetMe";
this.switchSound = SoundCache.getSound("https://hifi-public.s3.amazonaws.com/sounds/Switches%20and%20sliders/lamp_switch_2.wav");
};
LightSwitchGarage.prototype = {
clickReleaseOnEntity: function(entityID, mouseEvent) {
if (!mouseEvent.isLeftButton) {
return;
}
this.toggleLights();
},
startNearGrabNonColliding: function() {
this.toggleLights();
},
toggleLights: function() {
var defaultLightData = {
on: false
};
var lightState = getEntityCustomData(this.lightStateKey, this.entityID, defaultLightData);
if (lightState.on === true) {
this.clearLights();
} else if (lightState.on === false) {
this.createLights();
}
this.flipLights();
Audio.playSound(this.switchSound, {
volume: 0.5,
position: this.position
});
},
clearLights: function() {
var entities = Entities.findEntities(MyAvatar.position, 100);
var self = this;
entities.forEach(function(entity) {
var resetData = getEntityCustomData(self.resetKey, entity, {})
if (resetData.resetMe === true && resetData.lightType === "Sconce Light Garage") {
Entities.deleteEntity(entity);
}
});
setEntityCustomData(this.lightStateKey, this.entityID, {
on: false
});
},
createLights: function() {
var sconceLight3 = Entities.addEntity({
type: "Light",
position: {
x: 545.49468994140625,
y: 496.24026489257812,
z: 500.63516235351562
},
name: "Sconce 3 Light",
dimensions: {
x: 2.545,
y: 2.545,
z: 2.545
},
cutoff: 90,
color: {
red: 217,
green: 146,
blue: 24
}
});
setEntityCustomData(this.resetKey, sconceLight3, {
resetMe: true,
lightType: "Sconce Light Garage"
});
var sconceLight4 = Entities.addEntity({
type: "Light",
position: {
x: 550.90399169921875,
y: 496.24026489257812,
z: 507.90237426757812
},
name: "Sconce 4 Light",
dimensions: {
x: 2.545,
y: 2.545,
z: 2.545
},
cutoff: 90,
color: {
red: 217,
green: 146,
blue: 24
}
});
setEntityCustomData(this.resetKey, sconceLight4, {
resetMe: true,
lightType: "Sconce Light Garage"
});
var sconceLight5 = Entities.addEntity({
type: "Light",
position: {
x: 548.407958984375,
y: 496.24026489257812,
z: 509.5504150390625
},
name: "Sconce 5 Light",
dimensions: {
x: 2.545,
y: 2.545,
z: 2.545
},
cutoff: 90,
color: {
red: 217,
green: 146,
blue: 24
}
});
setEntityCustomData(this.resetKey, sconceLight5, {
resetMe: true,
lightType: "Sconce Light Garage"
});
setEntityCustomData(this.lightStateKey, this.entityID, {
on: true
});
},
flipLights: function() {
// flip model to give illusion of light switch being flicked
var rotation = Entities.getEntityProperties(this.entityID, "rotation").rotation;
var axis = {
x: 0,
y: 1,
z: 0
};
var dQ = Quat.angleAxis(180, axis);
rotation = Quat.multiply(rotation, dQ);
Entities.editEntity(this.entityID, {
rotation: rotation
});
},
preload: function(entityID) {
this.entityID = entityID;
//The light switch is static, so just cache its position once
this.position = Entities.getEntityProperties(this.entityID, "position").position;
var defaultLightData = {
on: false
};
var lightState = getEntityCustomData(this.lightStateKey, this.entityID, defaultLightData);
//If light is off, then we create two new lights- at the position of the sconces
if (lightState.on === false) {
this.createLights();
this.flipLights();
}
//If lights are on, do nothing!
},
};
// entity scripts always need to return a newly constructed object of our type
return new LightSwitchGarage();
})

View file

@ -0,0 +1,179 @@
//
// lightSwitchHall.js
// examples/entityScripts
//
// Created by Eric Levin on 9/21/15.
// Copyright 2015 High Fidelity, Inc.
//
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
(function() {
var _this;
// this is the "constructor" for the entity as a JS object we don't do much here, but we do want to remember
// our this object, so we can access it in cases where we're called without a this (like in the case of various global signals)
LightSwitchHall = function() {
_this = this;
this.lightStateKey = "lightStateKey";
this.resetKey = "resetMe";
this.switchSound = SoundCache.getSound("https://hifi-public.s3.amazonaws.com/sounds/Switches%20and%20sliders/lamp_switch_2.wav");
};
LightSwitchHall.prototype = {
clickReleaseOnEntity: function(entityId, mouseEvent) {
if (!mouseEvent.isLeftButton) {
return;
}
this.toggleLights();
},
startNearGrabNonColliding: function() {
this.toggleLights();
},
toggleLights: function() {
var defaultLightData = {
on: false
};
var lightState = getEntityCustomData(this.lightStateKey, this.entityID, defaultLightData);
if (lightState.on === true) {
this.clearLights();
} else if (lightState.on === false) {
this.createLights();
}
// flip model to give illusion of light switch being flicked
this.flipLights();
Audio.playSound(this.switchSound, {
volume: 0.5,
position: this.position
});
},
clearLights: function() {
var entities = Entities.findEntities(MyAvatar.position, 100);
var self = this;
entities.forEach(function(entity) {
var resetData = getEntityCustomData(self.resetKey, entity, {})
if (resetData.resetMe === true && resetData.lightType === "Sconce Light Hall") {
Entities.deleteEntity(entity);
}
});
setEntityCustomData(this.lightStateKey, this.entityID, {
on: false
});
},
createLights: function() {
var sconceLight1 = Entities.addEntity({
type: "Light",
position: {
x: 543.75,
y: 496.24,
z: 511.13
},
name: "Sconce 1 Light",
dimensions: {
x: 2.545,
y: 2.545,
z: 2.545
},
cutoff: 90,
color: {
red: 217,
green: 146,
blue: 24
}
});
setEntityCustomData(this.resetKey, sconceLight1, {
resetMe: true,
lightType: "Sconce Light Hall"
});
var sconceLight2 = Entities.addEntity({
type: "Light",
position: {
x: 540.1,
y: 496.24,
z: 505.57
},
name: "Sconce 2 Light",
dimensions: {
x: 2.545,
y: 2.545,
z: 2.545
},
cutoff: 90,
color: {
red: 217,
green: 146,
blue: 24
}
});
setEntityCustomData(this.resetKey, sconceLight2, {
resetMe: true,
lightType: "Sconce Light Hall"
});
setEntityCustomData(this.lightStateKey, this.entityID, {
on: true
});
},
flipLights: function() {
// flip model to give illusion of light switch being flicked
var rotation = Entities.getEntityProperties(this.entityID, "rotation").rotation;
var axis = {
x: 0,
y: 1,
z: 0
};
var dQ = Quat.angleAxis(180, axis);
rotation = Quat.multiply(rotation, dQ);
Entities.editEntity(this.entityID, {
rotation: rotation
});
},
// preload() will be called when the entity has become visible (or known) to the interface
// it gives us a chance to set our local JavaScript object up. In this case it means:
preload: function(entityID) {
this.entityID = entityID;
//The light switch is static, so just cache its position once
this.position = Entities.getEntityProperties(this.entityID, "position").position;
var defaultLightData = {
on: false
};
var lightState = getEntityCustomData(this.lightStateKey, this.entityID, defaultLightData);
//If light is off, then we create two new lights- at the position of the sconces
if (lightState.on === false) {
this.createLights();
this.flipLights();
}
//If lights are on, do nothing!
},
};
// entity scripts always need to return a newly constructed object of our type
return new LightSwitchHall();
})

View file

@ -0,0 +1,162 @@
//
// sprayPaintCan.js
// examples/entityScripts
//
// Created by Eric Levin on 9/21/15.
// Copyright 2015 High Fidelity, Inc.
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
(function() {
// Script.include("../libraries/utils.js");
//Need absolute path for now, for testing before PR merge and s3 cloning. Will change post-merge
Script.include("../libraries/utils.js");
this.spraySound = SoundCache.getSound("https://s3.amazonaws.com/hifi-public/sounds/sprayPaintSound.wav");
var TIP_OFFSET_Z = 0.02;
var TIP_OFFSET_Y = 0.08;
var ZERO_VEC = {
x: 0,
y: 0,
z: 0
};
// if the trigger value goes below this while held, the can will stop spraying. if it goes above, it will spray
var DISABLE_SPRAY_THRESHOLD = 0.5;
var MAX_POINTS_PER_LINE = 40;
var MIN_POINT_DISTANCE = 0.01;
var STROKE_WIDTH = 0.02;
this.setRightHand = function() {
this.hand = 'RIGHT';
}
this.setLeftHand = function() {
this.hand = 'LEFT';
}
this.startNearGrab = function() {
this.whichHand = this.hand;
}
this.toggleWithTriggerPressure = function() {
var handClickString = this.whichHand + "_HAND_CLICK";
var handClick = Controller.findAction(handClickString);
this.triggerValue = Controller.getActionValue(handClick);
if (this.triggerValue < DISABLE_SPRAY_THRESHOLD && this.spraying === true) {
this.spraying = false;
this.disableStream();
} else if (this.triggerValue >= DISABLE_SPRAY_THRESHOLD && this.spraying === false) {
this.spraying = true;
this.enableStream();
}
}
this.enableStream = function() {
var position = Entities.getEntityProperties(this.entityId, "position").position;
var animationSettings = JSON.stringify({
fps: 30,
loop: true,
firstFrame: 1,
lastFrame: 10000,
running: true
});
var PI = 3.141593;
var DEG_TO_RAD = PI / 180.0;
this.paintStream = Entities.addEntity({
type: "ParticleEffect",
name: "streamEffect",
animationSettings: animationSettings,
position: position,
textures: "https://raw.githubusercontent.com/ericrius1/SantasLair/santa/assets/smokeparticle.png",
emitSpeed: 3,
speedSpread: 0.02,
emitAcceleration: ZERO_VEC,
emitRate: 100,
particleRadius: 0.01,
radiusSpread: 0.005,
polarFinish: 0.05,
color: {
red: 170,
green: 20,
blue: 150
},
lifetime: 50, //probably wont be holding longer than this straight
});
setEntityCustomData(this.resetKey, this.paintStream, {
resetMe: true
});
this.sprayInjector = Audio.playSound(this.spraySound, {
position: position,
volume: this.sprayVolume,
loop: true
});
}
this.releaseGrab = function() {
this.disableStream();
}
this.disableStream = function() {
Entities.deleteEntity(this.paintStream);
this.paintStream = null;
this.spraying = false;
this.sprayInjector.stop();
}
this.continueNearGrab = function() {
this.toggleWithTriggerPressure();
if (this.spraying === false) {
return;
}
var props = Entities.getEntityProperties(this.entityId, ["position, rotation"]);
var forwardVec = Quat.getFront(Quat.multiply(props.rotation, Quat.fromPitchYawRollDegrees(0, 90, 0)));
forwardVec = Vec3.normalize(forwardVec);
var forwardQuat = orientationOf(forwardVec);
var upVec = Quat.getUp(props.rotation);
var position = Vec3.sum(props.position, Vec3.multiply(forwardVec, TIP_OFFSET_Z));
position = Vec3.sum(position, Vec3.multiply(upVec, TIP_OFFSET_Y))
Entities.editEntity(this.paintStream, {
position: position,
emitOrientation: forwardQuat,
});
this.sprayInjector.setOptions({
position: position,
volume: this.sprayVolume
});
}
this.preload = function(entityId) {
this.sprayVolume = 0.1;
this.spraying = false;
this.entityId = entityId;
this.resetKey = "resetMe";
}
this.unload = function() {
if (this.paintStream) {
Entities.deleteEntity(this.paintStream);
}
this.strokes.forEach(function(stroke) {
Entities.deleteEntity(stroke);
});
}
});

View file

@ -0,0 +1,834 @@
// masterReset.js
// Created by Eric Levin on 9/23/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
//
/*global print, MyAvatar, Entities, AnimationCache, SoundCache, Scene, Camera, Overlays, Audio, HMD, AvatarList, AvatarManager, Controller, UndoStack, Window, Account, GlobalServices, Script, ScriptDiscoveryService, LODManager, Menu, Vec3, Quat, AudioDevice, Paths, Clipboard, Settings, XMLHttpRequest, pointInExtents, vec3equal, setEntityCustomData, getEntityCustomData */
//per script
/*global deleteAllToys, createAllToys, createGates, createPingPongBallGun, createFire, createPottedPlant, createCombinedArmChair, createBasketballHoop, createBasketBall, createSprayCan, createDoll, createWand, createDice, createCat, deleteAllToys, createFlashlight, createBlocks, createMagballs, createLightSwitches */
var utilitiesScript = Script.resolvePath("../examples/libraries/utils.js");
Script.include(utilitiesScript);
var resetKey = "resetMe";
var GRABBABLE_DATA_KEY = "grabbableKey";
var HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/";
var shouldDeleteOnEndScript = false;
//Before creating anything, first search a radius and delete all the things that should be deleted
deleteAllToys();
createAllToys();
function createAllToys() {
createBlocks({
x: 548.3,
y: 495.55,
z: 504.4
});
createSprayCan({
x: 549.7,
y: 495.6,
z: 503.91
});
createBasketBall({
x: 547.73,
y: 495.5,
z: 505.47
});
createDoll({
x: 546.67,
y: 495.41,
z: 505.09
});
createWand({
x: 546.71,
y: 495.55,
z: 506.15
});
createDice();
createFlashlight({
x: 545.72,
y: 495.41,
z: 505.78
});
createCat({
x: 551.09,
y: 494.98,
z: 503.49
});
createCombinedArmChair({
x: 549.29,
y: 495.05,
z: 508.22
});
createPottedPlant({
x: 554.26,
y: 495.23,
z: 504.53
});
createPingPongBallGun();
createBasketballHoop();
createGates();
createFire();
// //Handles toggling of all sconce lights
createLightSwitches();
}
function deleteAllToys() {
var entities = Entities.findEntities(MyAvatar.position, 100);
entities.forEach(function (entity) {
//params: customKey, id, defaultValue
var shouldReset = getEntityCustomData(resetKey, entity, {}).resetMe;
if (shouldReset === true) {
Entities.deleteEntity(entity);
}
});
}
function createFire() {
var myOrientation = Quat.fromPitchYawRollDegrees(-90, 0, 0.0);
var animationSettings = JSON.stringify({
fps: 30,
running: true,
loop: true,
firstFrame: 1,
lastFrame: 10000
});
var fire = Entities.addEntity({
type: "ParticleEffect",
name: "fire",
animationSettings: animationSettings,
textures: "https://hifi-public.s3.amazonaws.com/alan/Particles/Particle-Sprite-Smoke-1.png",
position: {
x: 551.45,
y: 494.82,
z: 502.05
},
emitRate: 100,
colorStart: {
red: 70,
green: 70,
blue: 137
},
color: {
red: 200,
green: 99,
blue: 42
},
colorFinish: {
red: 255,
green: 99,
blue: 32
},
radiusSpread: 0.01,
radiusStart: 0.02,
radiusEnd: 0.001,
particleRadius: 0.05,
radiusFinish: 0.0,
emitOrientation: myOrientation,
emitSpeed: 0.3,
speedSpread: 0.1,
alphaStart: 0.05,
alpha: 0.1,
alphaFinish: 0.05,
emitDimensions: {
x: 1,
y: 1,
z: 0.1
},
polarFinish: 0.1,
emitAcceleration: {
x: 0.0,
y: 0.0,
z: 0.0
},
accelerationSpread: {
x: 0.1,
y: 0.01,
z: 0.1
},
lifespan: 1
});
setEntityCustomData(resetKey, fire, {
resetMe: true
});
}
function createCat(position) {
var scriptURL = Script.resolvePath("../examples/toys/cat.js");
var modelURL = "http://hifi-public.s3.amazonaws.com/ryan/Dark_Cat.fbx";
var animationURL = "http://hifi-public.s3.amazonaws.com/ryan/sleeping.fbx";
var animationSettings = JSON.stringify({
running: true,
});
var cat = Entities.addEntity({
type: "Model",
modelURL: modelURL,
name: "cat",
script: scriptURL,
animationURL: animationURL,
animationSettings: animationSettings,
position: position,
rotation: {
w: 0.35020983219146729,
x: -4.57763671875e-05,
y: 0.93664455413818359,
z: -1.52587890625e-05
},
dimensions: {
x: 0.15723302960395813,
y: 0.50762706995010376,
z: 0.90716040134429932
},
});
setEntityCustomData(resetKey, cat, {
resetMe: true
});
}
function createFlashlight(position) {
var scriptURL = Script.resolvePath('../examples/toys/flashlight/flashlight.js');
var modelURL = "https://hifi-public.s3.amazonaws.com/models/props/flashlight.fbx";
var flashlight = Entities.addEntity({
type: "Model",
modelURL: modelURL,
name: "flashlight",
script: scriptURL,
position: position,
dimensions: {
x: 0.08,
y: 0.30,
z: 0.08
},
collisionsWillMove: true,
gravity: {
x: 0,
y: -3.5,
z: 0
},
velocity: {
x: 0,
y: -0.01,
z: 0
},
shapeType: 'box',
});
setEntityCustomData(resetKey, flashlight, {
resetMe: true
});
}
function createLightSwitches() {
var modelURL = "http://hifi-public.s3.amazonaws.com/ryan/lightswitch.fbx?v1";
var scriptURL = Script.resolvePath("../examples/toys/lightSwitchHall.js");
var lightSwitchHall = Entities.addEntity({
type: "Model",
modelURL: modelURL,
name: "Light Switch Hall",
script: scriptURL,
position: {
x: 543.27764892578125,
y: 495.67999267578125,
z: 511.00564575195312
},
rotation: {
w: 0.63280689716339111,
x: 0.63280689716339111,
y: -0.31551080942153931,
z: 0.31548023223876953
},
dimensions: {
x: 0.10546875,
y: 0.032372996211051941,
z: 0.16242524981498718
}
});
setEntityCustomData(resetKey, lightSwitchHall, {
resetMe: true
});
scriptURL = Script.resolvePath("../examples/toys/lightSwitchGarage.js");
var lightSwitchGarage = Entities.addEntity({
type: "Model",
modelURL: modelURL,
name: "Light Switch Garage",
script: scriptURL,
position: {
x: 545.62,
y: 495.68,
z: 500.21
},
rotation: {
w: 0.20082402229309082,
x: 0.20082402229309082,
y: -0.67800414562225342,
z: 0.67797362804412842
},
dimensions: {
x: 0.10546875,
y: 0.032372996211051941,
z: 0.16242524981498718
}
});
setEntityCustomData(resetKey, lightSwitchGarage, {
resetMe: true
});
}
function createDice() {
var diceProps = {
type: "Model",
modelURL: "http://s3.amazonaws.com/hifi-public/models/props/Dice/goldDie.fbx",
collisionSoundURL: "http://s3.amazonaws.com/hifi-public/sounds/dice/diceCollide.wav",
name: "dice",
position: {
x: 541,
y: 494.96,
z: 509.1
},
dimensions: {
x: 0.09,
y: 0.09,
z: 0.09
},
gravity: {
x: 0,
y: -3.5,
z: 0
},
velocity: {
x: 0,
y: -0.01,
z: 0
},
shapeType: "box",
collisionsWillMove: true
};
var dice1 = Entities.addEntity(diceProps);
diceProps.position = {
x: 541.05,
y: 494.96,
z: 509.0
};
var dice2 = Entities.addEntity(diceProps);
setEntityCustomData(resetKey, dice1, {
resetMe: true
});
setEntityCustomData(resetKey, dice2, {
resetMe: true
});
}
function createGates() {
var MODEL_URL = 'http://hifi-public.s3.amazonaws.com/ryan/fence.fbx';
var rotation1 = Quat.fromPitchYawRollDegrees(0, 36, 0);
var gate1 = Entities.addEntity({
name: 'Back Door Gate',
type: 'Model',
shapeType: 'box',
modelURL: MODEL_URL,
position: {
x: 546.52,
y: 494.76,
z: 498.87
},
dimensions: {
x: 1.42,
y: 1.13,
z: 0.25
},
rotation: rotation1,
collisionsWillMove: true,
gravity: {
x: 0,
y: -50,
z: 0
},
linearDamping: 1,
angularDamping: 10,
mass: 10,
});
setEntityCustomData(resetKey, gate1, {
resetMe: true
});
setEntityCustomData(GRABBABLE_DATA_KEY, gate1, {
grabbable: false
});
var rotation2 = Quat.fromPitchYawRollDegrees(0, -16, 0);
var gate2 = Entities.addEntity({
name: 'Front Door Fence',
type: 'Model',
modelURL: MODEL_URL,
shapeType: 'box',
position: {
x: 531.15,
y: 495.11,
z: 520.20
},
dimensions: {
x: 1.42,
y: 1.13,
z: 0.2
},
rotation: rotation2,
collisionsWillMove: true,
gravity: {
x: 0,
y: -100,
z: 0
},
linearDamping: 1,
angularDamping: 10,
mass: 10,
});
setEntityCustomData(resetKey, gate2, {
resetMe: true
});
setEntityCustomData(GRABBABLE_DATA_KEY, gate2, {
grabbable: false
});
}
function createPingPongBallGun() {
var MODEL_URL = 'http://hifi-public.s3.amazonaws.com/models/ping_pong_gun/ping_pong_gun.fbx';
var COLLISION_HULL_URL = 'http://hifi-public.s3.amazonaws.com/models/ping_pong_gun/ping_pong_gun_collision_hull.obj';
var scriptURL = Script.resolvePath('../examples/toys/ping_pong_gun/pingPongGun.js');
var position = {
x: 548.6,
y: 495.4,
z: 503.39
};
var rotation = Quat.fromPitchYawRollDegrees(0, 36, 0);
var pingPongGun = Entities.addEntity({
type: "Model",
modelURL: MODEL_URL,
shapeType: 'compound',
compoundShapeURL: COLLISION_HULL_URL,
script: scriptURL,
position: position,
rotation: rotation,
gravity: {
x: 0,
y: -9.8,
z: 0
},
dimensions: {
x: 0.67,
y: 0.14,
z: 0.09
},
collisionsWillMove: true,
});
setEntityCustomData(resetKey, pingPongGun, {
resetMe: true
});
}
function createBasketballHoop() {
var position = {
x: 539.23,
y: 496.13,
z: 475.89
};
var rotation = Quat.fromPitchYawRollDegrees(0, 58.49, 0);
var hoopURL = "http://hifi-public.s3.amazonaws.com/models/basketball_hoop/basketball_hoop.fbx";
var hoopCollisionHullURL = "http://hifi-public.s3.amazonaws.com/models/basketball_hoop/basketball_hoop_collision_hull.obj";
var hoop = Entities.addEntity({
type: "Model",
modelURL: hoopURL,
position: position,
rotation: rotation,
shapeType: 'compound',
gravity: {
x: 0,
y: -9.8,
z: 0
},
dimensions: {
x: 1.89,
y: 3.99,
z: 3.79
},
compoundShapeURL: hoopCollisionHullURL
});
setEntityCustomData(resetKey, hoop, {
resetMe: true
});
setEntityCustomData(GRABBABLE_DATA_KEY, hoop, {
grabbable: false
});
}
function createWand(position) {
var WAND_MODEL = 'http://hifi-public.s3.amazonaws.com/james/bubblewand/models/wand/wand.fbx';
var WAND_COLLISION_SHAPE = 'http://hifi-public.s3.amazonaws.com/james/bubblewand/models/wand/actual_no_top_collision_hull.obj';
var scriptURL = Script.resolvePath("../examples/toys/bubblewand/wand.js");
var entity = Entities.addEntity({
name: 'Bubble Wand',
type: "Model",
modelURL: WAND_MODEL,
position: position,
gravity: {
x: 0,
y: -9.8,
z: 0
},
dimensions: {
x: 0.05,
y: 0.25,
z: 0.05
},
//must be enabled to be grabbable in the physics engine
shapeType: 'compound',
collisionsWillMove: true,
compoundShapeURL: WAND_COLLISION_SHAPE,
//Look into why bubble wand is going through table when gravity is enabled
// gravity: {x: 0, y: -3.5, z: 0},
// velocity: {x: 0, y: -0.01, z:0},
script: scriptURL
});
setEntityCustomData(resetKey, entity, {
resetMe: true
});
}
function createBasketBall(position) {
var modelURL = "http://s3.amazonaws.com/hifi-public/models/content/basketball2.fbx";
var entity = Entities.addEntity({
type: "Model",
modelURL: modelURL,
position: position,
collisionsWillMove: true,
shapeType: "sphere",
name: "basketball",
dimensions: {
x: 0.25,
y: 0.26,
z: 0.25
},
gravity: {
x: 0,
y: -7,
z: 0
},
restitution: 10,
linearDamping: 0.0,
velocity: {
x: 0,
y: -0.01,
z: 0
},
collisionSoundURL: "http://s3.amazonaws.com/hifi-public/sounds/basketball/basketball.wav"
});
setEntityCustomData(resetKey, entity, {
resetMe: true
});
}
function createDoll(position) {
var modelURL = "http://hifi-public.s3.amazonaws.com/models/Bboys/bboy2/bboy2.fbx";
var scriptURL = Script.resolvePath("../examples/toys/doll/doll.js");
var naturalDimensions = {
x: 1.63,
y: 1.67,
z: 0.26
};
var desiredDimensions = Vec3.multiply(naturalDimensions, 0.15);
var entity = Entities.addEntity({
type: "Model",
name: "doll",
modelURL: modelURL,
script: scriptURL,
position: position,
shapeType: 'box',
dimensions: desiredDimensions,
gravity: {
x: 0,
y: -5,
z: 0
},
velocity: {
x: 0,
y: -0.1,
z: 0
},
collisionsWillMove: true
});
setEntityCustomData(resetKey, entity, {
resetMe: true
});
}
function createSprayCan(position) {
var scriptURL = Script.resolvePath("../examples/toys/sprayPaintCan.js");
var modelURL = "https://hifi-public.s3.amazonaws.com/eric/models/paintcan.fbx";
var entity = Entities.addEntity({
type: "Model",
name: "spraycan",
modelURL: modelURL,
position: position,
dimensions: {
x: 0.07,
y: 0.17,
z: 0.07
},
collisionsWillMove: true,
shapeType: 'box',
script: scriptURL,
gravity: {
x: 0,
y: -0.5,
z: 0
},
velocity: {
x: 0,
y: -1,
z: 0
}
});
setEntityCustomData(resetKey, entity, {
resetMe: true
});
}
function createPottedPlant(position) {
var modelURL = "http://hifi-public.s3.amazonaws.com/models/potted_plant/potted_plant.fbx";
var entity = Entities.addEntity({
type: "Model",
name: "Potted Plant",
modelURL: modelURL,
position: position,
dimensions: {
x: 1.10,
y: 2.18,
z: 1.07
},
collisionsWillMove: true,
shapeType: 'box',
gravity: {
x: 0,
y: -9.8,
z: 0
},
velocity: {
x: 0,
y: 0,
z: 0
},
linearDamping: 0.4
});
setEntityCustomData(resetKey, entity, {
resetMe: true
});
setEntityCustomData(GRABBABLE_DATA_KEY, entity, {
grabbable: false
});
}
function createCombinedArmChair(position) {
var modelURL = "http://hifi-public.s3.amazonaws.com/models/red_arm_chair/combined_chair.fbx";
var RED_ARM_CHAIR_COLLISION_HULL = "http://hifi-public.s3.amazonaws.com/models/red_arm_chair/red_arm_chair_collision_hull.obj";
var rotation = Quat.fromPitchYawRollDegrees(0, -143, 0);
var entity = Entities.addEntity({
type: "Model",
name: "Red Arm Chair",
modelURL: modelURL,
shapeType: 'compound',
compoundShapeURL: RED_ARM_CHAIR_COLLISION_HULL,
position: position,
rotation: rotation,
dimensions: {
x: 1.26,
y: 1.56,
z: 1.35
},
collisionsWillMove: true,
gravity: {
x: 0,
y: -0.8,
z: 0
},
velocity: {
x: 0,
y: 0,
z: 0
},
linearDamping: 0.2
});
setEntityCustomData(resetKey, entity, {
resetMe: true
});
setEntityCustomData(GRABBABLE_DATA_KEY, entity, {
grabbable: false
});
}
function createBlocks(position) {
var baseURL = HIFI_PUBLIC_BUCKET + "models/content/planky/";
var collisionSoundURL = "https://hifi-public.s3.amazonaws.com/sounds/Collisions-otherorganic/ToyWoodBlock.L.wav";
var NUM_BLOCKS_PER_COLOR = 4;
var i, j;
var blockTypes = [{
url: "planky_blue.fbx",
dimensions: {
x: 0.05,
y: 0.05,
z: 0.25
}
}, {
url: "planky_green.fbx",
dimensions: {
x: 0.1,
y: 0.1,
z: 0.25
}
}, {
url: "planky_natural.fbx",
dimensions: {
x: 0.05,
y: 0.05,
z: 0.05
}
}, {
url: "planky_yellow.fbx",
dimensions: {
x: 0.03,
y: 0.05,
z: 0.25
}
}, {
url: "planky_red.fbx",
dimensions: {
x: 0.1,
y: 0.05,
z: 0.25
}
}, ];
var modelURL, entity;
for (i = 0; i < blockTypes.length; i++) {
for (j = 0; j < NUM_BLOCKS_PER_COLOR; j++) {
modelURL = baseURL + blockTypes[i].url;
entity = Entities.addEntity({
type: "Model",
modelURL: modelURL,
position: Vec3.sum(position, {
x: j / 10,
y: i / 10,
z: 0
}),
shapeType: 'box',
name: "block",
dimensions: blockTypes[i].dimensions,
collisionsWillMove: true,
collisionSoundURL: collisionSoundURL,
gravity: {
x: 0,
y: -2.5,
z: 0
},
velocity: {
x: 0,
y: -0.01,
z: 0
}
});
//customKey, id, data
setEntityCustomData(resetKey, entity, {
resetMe: true
});
}
}
}
function cleanup() {
deleteAllToys();
}
if (shouldDeleteOnEndScript) {
Script.scriptEnding.connect(cleanup);
}