fixed merge conflicsts

This commit is contained in:
ericrius1 2016-03-15 15:10:22 -07:00
commit 360407dd83
22 changed files with 2769 additions and 889 deletions

View file

@ -0,0 +1,36 @@
//v1.0
var center = Vec3.sum(Vec3.sum(MyAvatar.position, {
x: 0,
y: 0.5,
z: 0
}), Vec3.multiply(2, Quat.getFront(Camera.getOrientation())));
var SCRIPT_URL = Script.resolvePath('reset.js?' + Math.random());
function createTidyGuy() {
var properties = {
type: 'Model',
modelURL: 'http://hifi-content.s3.amazonaws.com/DomainContent/Home/tidyGuy/Tidyguy-6.fbx',
dimensions: {
x: 0.32,
y: 0.96,
z: 0.6844
},
position: center,
script: SCRIPT_URL,
dynamic:false,
userData:JSON.stringify({
grabbableKey:{
wantsTrigger:true
}
})
}
return Entities.addEntity(properties);
}
var tidyGuy = createTidyGuy();
Script.scriptEnding.connect(function() {
Entities.deleteEntity(tidyGuy);
})

View file

@ -1,470 +0,0 @@
//
// createTank.js
//
//
// created by James b. Pollack @imgntn on 3/9/2016
// Copyright 2016 High Fidelity, Inc.
//
// Adds a fish tank and base, decorations, particle bubble systems, and a bubble sound. Attaches a script that does fish swimming.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
var fishTank, tankBase, bubbleSystem, secondBubbleSystem, thirdBubbleSystem, innerContainer, bubbleInjector, lowerCorner, upperCorner, anemone, treasure, rocks;
var CLEANUP = true;
var TANK_DIMENSIONS = {
x: 0.8212,
y: 0.8116,
z: 2.1404
};
var INNER_TANK_SCALE = 0.7;
var INNER_TANK_DIMENSIONS = Vec3.multiply(INNER_TANK_SCALE, TANK_DIMENSIONS);
INNER_TANK_DIMENSIONS.y = INNER_TANK_DIMENSIONS.y - 0.4;
var TANK_WIDTH = TANK_DIMENSIONS.z;
var TANK_HEIGHT = TANK_DIMENSIONS.y;
var DEBUG_COLOR = {
red: 255,
green: 0,
blue: 255
}
var centerVertical = {
x: 0,
y: 1,
z: 0
}
var upCenter = Vec3.sum(centerVertical, MyAvatar.position);
var center = Vec3.sum(upCenter, Vec3.multiply(Quat.getFront(MyAvatar.orientation), 2));
var TANK_POSITION = center;
var TANK_SCRIPT = Script.resolvePath('tank.js?' + Math.random())
var TANK_MODEL_URL = "http://hifi-content.s3.amazonaws.com/DomainContent/Home/fishTank/aquariumTank.fbx";
var TANK_BASE_MODEL_URL = 'http://hifi-content.s3.amazonaws.com/DomainContent/Home/fishTank/aquariumBase.fbx';
var TANK_BASE_COLLISION_HULL = 'http://hifi-content.s3.amazonaws.com/DomainContent/Home/fishTank/aquariumBase.obj'
var TANK_BASE_DIMENSIONS = {
x: 0.8599,
y: 1.8450,
z: 2.1936
};
var BASE_VERTICAL_OFFSET = 0.47;
var BUBBLE_SYSTEM_FORWARD_OFFSET = TANK_DIMENSIONS.x + 0.06;
var BUBBLE_SYSTEM_LATERAL_OFFSET = 0.025;
var BUBBLE_SYSTEM_VERTICAL_OFFSET = -0.30;
var BUBBLE_SYSTEM_DIMENSIONS = {
x: TANK_DIMENSIONS.x / 8,
y: TANK_DIMENSIONS.y,
z: TANK_DIMENSIONS.z / 8
}
var BUBBLE_SOUND_URL = "http://hifi-content.s3.amazonaws.com/DomainContent/Home/Sounds/aquarium_small.L.wav";
var bubbleSound = SoundCache.getSound(BUBBLE_SOUND_URL);
var ANEMONE_FORWARD_OFFSET = TANK_DIMENSIONS.x - 0.35;
var ANEMONE_LATERAL_OFFSET = -0.05;
var ANEMONE_VERTICAL_OFFSET = -0.12;
var ANEMONE_MODEL_URL = 'http://hifi-content.s3.amazonaws.com/DomainContent/Home/fishTank/anemone.fbx';
var ANEMONE_ANIMATION_URL = 'http://hifi-content.s3.amazonaws.com/DomainContent/Home/fishTank/anemone.fbx';
var ANEMONE_DIMENSIONS = {
x: 0.4,
y: 0.4,
z: 0.4
}
var ROCKS_FORWARD_OFFSET = 0;
var ROCKS_LATERAL_OFFSET = 0.0;
var ROCKS_VERTICAL_OFFSET = (-TANK_DIMENSIONS.y / 2) + 0.25;
var ROCK_MODEL_URL = 'http://hifi-content.s3.amazonaws.com/DomainContent/Home/fishTank/Aquarium-Rocks-2.fbx';
var ROCK_DIMENSIONS = {
x: 0.707,
y: 0.33,
z: 1.64
}
var TREASURE_FORWARD_OFFSET = -TANK_DIMENSIONS.x;
var TREASURE_LATERAL_OFFSET = -0.15;
var TREASURE_VERTICAL_OFFSET = -0.23;
var TREASURE_MODEL_URL = 'http://hifi-content.s3.amazonaws.com/DomainContent/Home/fishTank/Treasure-Chest2-SM.fbx';
var TREASURE_DIMENSIONS = {
x: 0.1199,
y: 0.1105,
z: 0.1020
}
function createFishTank() {
var tankProperties = {
name: 'hifi-home-fishtank',
type: 'Model',
modelURL: TANK_MODEL_URL,
dimensions: TANK_DIMENSIONS,
position: TANK_POSITION,
color: DEBUG_COLOR,
collisionless: true,
script: TANK_SCRIPT,
visible: true
}
fishTank = Entities.addEntity(tankProperties);
}
function createBubbleSystems() {
var tankProperties = Entities.getEntityProperties(fishTank);
var bubbleProperties = {
"name": 'hifi-home-fishtank-bubbles',
"isEmitting": 1,
"maxParticles": 1880,
"lifespan": 1.6,
"emitRate": 10,
"emitSpeed": 0.025,
"speedSpread": 0.025,
"emitOrientation": {
"x": 0,
"y": 0.5,
"z": 0.5,
"w": 0
},
"emitDimensions": {
"x": -0.2,
"y": TANK_DIMENSIONS.y,
"z": 0
},
"polarStart": 0,
"polarFinish": 0,
"azimuthStart": 0.2,
"azimuthFinish": 0.1,
"emitAcceleration": {
"x": 0,
"y": 0.3,
"z": 0
},
"accelerationSpread": {
"x": 0.01,
"y": 0.01,
"z": 0.01
},
"particleRadius": 0.005,
"radiusSpread": 0,
"radiusStart": 0.01,
"radiusFinish": 0.01,
"alpha": 0.2,
"alphaSpread": 0,
"alphaStart": 0.3,
"alphaFinish": 0,
"emitterShouldTrail": 0,
"textures": "http://hifi-content.s3.amazonaws.com/DomainContent/Home/fishTank/bubble-white.png"
};
bubbleProperties.type = "ParticleEffect";
bubbleProperties.parentID = fishTank;
bubbleProperties.dimensions = BUBBLE_SYSTEM_DIMENSIONS;
var finalOffset = getOffsetFromTankCenter(BUBBLE_SYSTEM_VERTICAL_OFFSET, BUBBLE_SYSTEM_FORWARD_OFFSET, BUBBLE_SYSTEM_LATERAL_OFFSET);
bubbleProperties.position = finalOffset;
bubbleSystem = Entities.addEntity(bubbleProperties);
bubbleProperties.position.x += -0.076;
secondBubbleSystem = Entities.addEntity(bubbleProperties)
bubbleProperties.position.x += -0.076;
thirdBubbleSystem = Entities.addEntity(bubbleProperties)
createBubbleSound(finalOffset);
}
function getOffsetFromTankCenter(VERTICAL_OFFSET, FORWARD_OFFSET, LATERAL_OFFSET) {
var tankProperties = Entities.getEntityProperties(fishTank);
var upVector = Quat.getUp(tankProperties.rotation);
var frontVector = Quat.getFront(tankProperties.rotation);
var rightVector = Quat.getRight(tankProperties.rotation);
var upOffset = Vec3.multiply(upVector, VERTICAL_OFFSET);
var frontOffset = Vec3.multiply(frontVector, FORWARD_OFFSET);
var rightOffset = Vec3.multiply(rightVector, LATERAL_OFFSET);
var finalOffset = Vec3.sum(tankProperties.position, upOffset);
finalOffset = Vec3.sum(finalOffset, frontOffset);
finalOffset = Vec3.sum(finalOffset, rightOffset);
return finalOffset
}
function createBubbleSound(position) {
var audioProperties = {
volume: 0.05,
position: position,
loop: true
};
bubbleInjector = Audio.playSound(bubbleSound, audioProperties);
}
function createInnerContainer(position) {
var tankProperties = Entities.getEntityProperties(fishTank);
var containerProps = {
name: "hifi-home-fishtank-inner-container",
type: 'Box',
color: {
red: 0,
green: 0,
blue: 255
},
parentID: fishTank,
dimensions: INNER_TANK_DIMENSIONS,
position: tankProperties.position,
visible: false,
collisionless: true,
dynamic: false
};
innerContainer = Entities.addEntity(containerProps);
}
function createEntitiesAtCorners() {
var bounds = Entities.getEntityProperties(innerContainer, "boundingBox").boundingBox;
var lowerProps = {
name: 'hifi-home-fishtank-lower-corner',
type: "Box",
parentID: fishTank,
dimensions: {
x: 0.2,
y: 0.2,
z: 0.2
},
color: {
red: 255,
green: 0,
blue: 0
},
collisionless: true,
position: bounds.brn,
visible: false
}
var upperProps = {
name: 'hifi-home-fishtank-upper-corner',
type: "Box",
parentID: fishTank,
dimensions: {
x: 0.2,
y: 0.2,
z: 0.2
},
color: {
red: 0,
green: 255,
blue: 0
},
collisionless: true,
position: bounds.tfl,
visible: false
}
lowerCorner = Entities.addEntity(lowerProps);
upperCorner = Entities.addEntity(upperProps);
}
function createRocks() {
var finalPosition = getOffsetFromTankCenter(ROCKS_VERTICAL_OFFSET, ROCKS_FORWARD_OFFSET, ROCKS_LATERAL_OFFSET);
var properties = {
name: 'hifi-home-fishtank-rock',
type: 'Model',
parentID: fishTank,
modelURL: ROCK_MODEL_URL,
position: finalPosition,
dimensions: ROCK_DIMENSIONS
}
rocks = Entities.addEntity(properties);
}
function createUrchin() {
var finalPosition = getOffsetFromTankCenter(ANEMONE_VERTICAL_OFFSET, ANEMONE_FORWARD_OFFSET, ANEMONE_LATERAL_OFFSET);
var properties = {
name: 'hifi-home-fishtank-anemone',
type: 'Model',
animationURL: ANEMONE_ANIMATION_URL,
animationIsPlaying: true,
animationFPS: 15,
animationSettings: JSON.stringify({
hold: false,
loop: true,
running: true,
startAutomatically: true
}),
parentID: fishTank,
modelURL: ANEMONE_MODEL_URL,
position: finalPosition,
shapeType: 'Sphere',
rotation: Quat.fromPitchYawRollDegrees(0, 90, 0),
dimensions: ANEMONE_DIMENSIONS
}
anemone = Entities.addEntity(properties);
}
function createTreasureChest() {
var finalPosition = getOffsetFromTankCenter(TREASURE_VERTICAL_OFFSET, TREASURE_FORWARD_OFFSET, TREASURE_LATERAL_OFFSET);
var properties = {
name: 'hifi-home-fishtank-treasure-chest',
type: 'Model',
parentID: fishTank,
modelURL: TREASURE_MODEL_URL,
position: finalPosition,
dimensions: TREASURE_DIMENSIONS,
rotation: Quat.fromPitchYawRollDegrees(10, -45, 10)
}
treasure = Entities.addEntity(properties);
}
function createTankBase() {
var properties = {
name: 'hifi-home-fishtank-base',
type: 'Model',
modelURL: TANK_BASE_MODEL_URL,
parentID: fishTank,
shapeType: 'compound',
compoundShapeURL: TANK_BASE_COLLISION_HULL,
position: {
x: TANK_POSITION.x,
y: TANK_POSITION.y - BASE_VERTICAL_OFFSET,
z: TANK_POSITION.z
},
dimensions: TANK_BASE_DIMENSIONS
}
tankBase = Entities.addEntity(properties);
}
createFishTank();
createInnerContainer();
createBubbleSystems();
createEntitiesAtCorners();
createUrchin();
createRocks();
createTankBase();
createTreasureChest();
var customKey = 'hifi-home-fishtank';
var data = {
fishLoaded: false,
bubbleSystem: bubbleSystem,
bubbleSound: bubbleSound,
corners: {
brn: lowerCorner,
tfl: upperCorner
},
innerContainer: innerContainer,
}
Script.setTimeout(function() {
setEntityCustomData(customKey, fishTank, data);
}, 2000)
function cleanup() {
Entities.deleteEntity(fishTank);
Entities.deleteEntity(tankBase);
Entities.deleteEntity(bubbleSystem);
Entities.deleteEntity(secondBubbleSystem);
Entities.deleteEntity(thirdBubbleSystem);
Entities.deleteEntity(innerContainer);
Entities.deleteEntity(lowerCorner);
Entities.deleteEntity(upperCorner);
Entities.deleteEntity(anemone);
Entities.deleteEntity(rocks);
bubbleInjector.stop();
bubbleInjector = null;
}
if (CLEANUP === true) {
Script.scriptEnding.connect(cleanup);
}
function setEntityUserData(id, data) {
var json = JSON.stringify(data)
Entities.editEntity(id, {
userData: json
});
}
function getEntityUserData(id) {
var results = null;
var properties = Entities.getEntityProperties(id, "userData");
if (properties.userData) {
try {
results = JSON.parse(properties.userData);
} catch (err) {
// print('error parsing json');
// print('properties are:'+ properties.userData);
}
}
return results ? results : {};
}
// Non-destructively modify the user data of an entity.
function setEntityCustomData(customKey, id, data) {
var userData = getEntityUserData(id);
if (data == null) {
delete userData[customKey];
} else {
userData[customKey] = data;
}
setEntityUserData(id, userData);
}
function getEntityCustomData(customKey, id, defaultValue) {
var userData = getEntityUserData(id);
if (undefined != userData[customKey]) {
return userData[customKey];
} else {
return defaultValue;
}
}

View file

@ -0,0 +1,457 @@
//
// createTank.js
//
//
// created by James b. Pollack @imgntn on 3/9/2016
// Copyright 2016 High Fidelity, Inc.
//
// Adds a fish tank and base, decorations, particle bubble systems, and a bubble sound. Attaches a script that does fish swimming.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
var TANK_SCRIPT = Script.resolvePath('tank.js?' + Math.random());
FishTank = function(spawnPosition, spawnRotation) {
var fishTank, tankBase, bubbleSystem, secondBubbleSystem, thirdBubbleSystem, innerContainer, bubbleInjector, lowerCorner, upperCorner, urchin, treasure, rocks;
var CLEANUP = true;
var TANK_DIMENSIONS = {
x: 0.8212,
y: 0.8116,
z: 2.1404
};
var INNER_TANK_SCALE = 0.7;
var INNER_TANK_DIMENSIONS = Vec3.multiply(INNER_TANK_SCALE, TANK_DIMENSIONS);
INNER_TANK_DIMENSIONS.y = INNER_TANK_DIMENSIONS.y - 0.4;
var TANK_WIDTH = TANK_DIMENSIONS.z;
var TANK_HEIGHT = TANK_DIMENSIONS.y;
var DEBUG_COLOR = {
red: 255,
green: 0,
blue: 255
}
var TANK_POSITION = spawnPosition;
var TANK_MODEL_URL = "http://hifi-content.s3.amazonaws.com/DomainContent/Home/fishTank/aquariumTank.fbx";
var TANK_BASE_MODEL_URL = 'http://hifi-content.s3.amazonaws.com/DomainContent/Home/fishTank/aquariumBase.fbx';
var TANK_BASE_COLLISION_HULL = 'http://hifi-content.s3.amazonaws.com/DomainContent/Home/fishTank/aquariumBase.obj'
var TANK_BASE_DIMENSIONS = {
x: 0.8599,
y: 1.8450,
z: 2.1936
};
var BASE_VERTICAL_OFFSET = 0.42;
var BUBBLE_SYSTEM_FORWARD_OFFSET = TANK_DIMENSIONS.x + 0.06;
var BUBBLE_SYSTEM_LATERAL_OFFSET = 0.025;
var BUBBLE_SYSTEM_VERTICAL_OFFSET = -0.30;
var BUBBLE_SYSTEM_DIMENSIONS = {
x: TANK_DIMENSIONS.x / 8,
y: TANK_DIMENSIONS.y,
z: TANK_DIMENSIONS.z / 8
}
var BUBBLE_SOUND_URL = "http://hifi-content.s3.amazonaws.com/DomainContent/Home/Sounds/aquarium_small.L.wav";
var bubbleSound = SoundCache.getSound(BUBBLE_SOUND_URL);
var URCHIN_FORWARD_OFFSET = TANK_DIMENSIONS.x - 0.35;
var URCHIN_LATERAL_OFFSET = -0.05;
var URCHIN_VERTICAL_OFFSET = -0.12;
var URCHIN_MODEL_URL = 'http://hifi-content.s3.amazonaws.com/DomainContent/Home/fishTank/Urchin.fbx';
var URCHIN_DIMENSIONS = {
x: 0.4,
y: 0.4,
z: 0.4
}
var ROCKS_FORWARD_OFFSET = 0;
var ROCKS_LATERAL_OFFSET = 0.0;
var ROCKS_VERTICAL_OFFSET = (-TANK_DIMENSIONS.y / 2) + 0.25;
var ROCK_MODEL_URL = 'http://hifi-content.s3.amazonaws.com/DomainContent/Home/fishTank/Aquarium-Rocks-2.fbx';
var ROCK_DIMENSIONS = {
x: 0.707,
y: 0.33,
z: 1.64
}
var TREASURE_FORWARD_OFFSET = -TANK_DIMENSIONS.x;
var TREASURE_LATERAL_OFFSET = -0.15;
var TREASURE_VERTICAL_OFFSET = -0.23;
var TREASURE_MODEL_URL = 'http://hifi-content.s3.amazonaws.com/DomainContent/Home/fishTank/Treasure-Chest2-SM.fbx';
var TREASURE_DIMENSIONS = {
x: 0.1199,
y: 0.1105,
z: 0.1020
}
function createFishTank() {
var tankProperties = {
name: 'hifi-home-fishtank',
type: 'Model',
modelURL: TANK_MODEL_URL,
dimensions: TANK_DIMENSIONS,
position: TANK_POSITION,
color: DEBUG_COLOR,
collisionless: true,
script: TANK_SCRIPT,
visible: true
}
if (spawnRotation !== undefined) {
tankProperties.rotation = spawnRotation
}
fishTank = Entities.addEntity(tankProperties);
}
function createBubbleSystems() {
var tankProperties = Entities.getEntityProperties(fishTank);
var bubbleProperties = {
"name": 'hifi-home-fishtank-bubbles',
"isEmitting": 1,
"maxParticles": 1880,
"lifespan": 1.6,
"emitRate": 10,
"emitSpeed": 0.025,
"speedSpread": 0.025,
"emitOrientation": {
"x": 0,
"y": 0.5,
"z": 0.5,
"w": 0
},
"emitDimensions": {
"x": -0.2,
"y": TANK_DIMENSIONS.y,
"z": 0
},
"polarStart": 0,
"polarFinish": 0,
"azimuthStart": 0.2,
"azimuthFinish": 0.1,
"emitAcceleration": {
"x": 0,
"y": 0.3,
"z": 0
},
"accelerationSpread": {
"x": 0.01,
"y": 0.01,
"z": 0.01
},
"particleRadius": 0.005,
"radiusSpread": 0,
"radiusStart": 0.01,
"radiusFinish": 0.01,
"alpha": 0.2,
"alphaSpread": 0,
"alphaStart": 0.3,
"alphaFinish": 0,
"emitterShouldTrail": 0,
"textures": "http://hifi-content.s3.amazonaws.com/DomainContent/Home/fishTank/bubble-white.png"
};
bubbleProperties.type = "ParticleEffect";
bubbleProperties.parentID = fishTank;
bubbleProperties.dimensions = BUBBLE_SYSTEM_DIMENSIONS;
var finalOffset = getOffsetFromTankCenter(BUBBLE_SYSTEM_VERTICAL_OFFSET, BUBBLE_SYSTEM_FORWARD_OFFSET, BUBBLE_SYSTEM_LATERAL_OFFSET);
bubbleProperties.position = finalOffset;
bubbleSystem = Entities.addEntity(bubbleProperties);
bubbleProperties.position.x += -0.076;
secondBubbleSystem = Entities.addEntity(bubbleProperties)
bubbleProperties.position.x += -0.076;
thirdBubbleSystem = Entities.addEntity(bubbleProperties)
createBubbleSound(finalOffset);
}
function getOffsetFromTankCenter(VERTICAL_OFFSET, FORWARD_OFFSET, LATERAL_OFFSET) {
var tankProperties = Entities.getEntityProperties(fishTank);
var upVector = Quat.getUp(tankProperties.rotation);
var frontVector = Quat.getFront(tankProperties.rotation);
var rightVector = Quat.getRight(tankProperties.rotation);
var upOffset = Vec3.multiply(upVector, VERTICAL_OFFSET);
var frontOffset = Vec3.multiply(frontVector, FORWARD_OFFSET);
var rightOffset = Vec3.multiply(rightVector, LATERAL_OFFSET);
var finalOffset = Vec3.sum(tankProperties.position, upOffset);
finalOffset = Vec3.sum(finalOffset, frontOffset);
finalOffset = Vec3.sum(finalOffset, rightOffset);
return finalOffset
}
function createBubbleSound(position) {
var audioProperties = {
volume: 0.05,
position: position,
loop: true
};
bubbleInjector = Audio.playSound(bubbleSound, audioProperties);
}
function createInnerContainer(position) {
var tankProperties = Entities.getEntityProperties(fishTank);
var containerProps = {
name: "hifi-home-fishtank-inner-container",
type: 'Box',
color: {
red: 0,
green: 0,
blue: 255
},
parentID: fishTank,
dimensions: INNER_TANK_DIMENSIONS,
position: tankProperties.position,
visible: false,
collisionless: true,
dynamic: false
};
innerContainer = Entities.addEntity(containerProps);
}
function createEntitiesAtCorners() {
var bounds = Entities.getEntityProperties(innerContainer, "boundingBox").boundingBox;
var lowerProps = {
name: 'hifi-home-fishtank-lower-corner',
type: "Box",
parentID: fishTank,
dimensions: {
x: 0.2,
y: 0.2,
z: 0.2
},
color: {
red: 255,
green: 0,
blue: 0
},
collisionless: true,
position: bounds.brn,
visible: false
}
var upperProps = {
name: 'hifi-home-fishtank-upper-corner',
type: "Box",
parentID: fishTank,
dimensions: {
x: 0.2,
y: 0.2,
z: 0.2
},
color: {
red: 0,
green: 255,
blue: 0
},
collisionless: true,
position: bounds.tfl,
visible: false
}
lowerCorner = Entities.addEntity(lowerProps);
upperCorner = Entities.addEntity(upperProps);
}
function createRocks() {
var finalPosition = getOffsetFromTankCenter(ROCKS_VERTICAL_OFFSET, ROCKS_FORWARD_OFFSET, ROCKS_LATERAL_OFFSET);
var properties = {
name: 'hifi-home-fishtank-rock',
type: 'Model',
parentID: fishTank,
modelURL: ROCK_MODEL_URL,
position: finalPosition,
dimensions: ROCK_DIMENSIONS
}
rocks = Entities.addEntity(properties);
}
function createUrchin() {
var finalPosition = getOffsetFromTankCenter(URCHIN_VERTICAL_OFFSET, URCHIN_FORWARD_OFFSET, URCHIN_LATERAL_OFFSET);
var properties = {
name: 'hifi-home-fishtank-urchin',
type: 'Model',
parentID: fishTank,
modelURL: URCHIN_MODEL_URL,
position: finalPosition,
shapeType: 'Sphere',
dimensions: URCHIN_DIMENSIONS
}
urchin = Entities.addEntity(properties);
}
function createTreasureChest() {
var finalPosition = getOffsetFromTankCenter(TREASURE_VERTICAL_OFFSET, TREASURE_FORWARD_OFFSET, TREASURE_LATERAL_OFFSET);
var properties = {
name: 'hifi-home-fishtank-treasure-chest',
type: 'Model',
parentID: fishTank,
modelURL: TREASURE_MODEL_URL,
position: finalPosition,
dimensions: TREASURE_DIMENSIONS,
rotation: Quat.fromPitchYawRollDegrees(10, -45, 10)
}
treasure = Entities.addEntity(properties);
}
function createTankBase() {
var properties = {
name: 'hifi-home-fishtank-base',
type: 'Model',
modelURL: TANK_BASE_MODEL_URL,
parentID: fishTank,
shapeType: 'compound',
compoundShapeURL: TANK_BASE_COLLISION_HULL,
position: {
x: TANK_POSITION.x,
y: TANK_POSITION.y - BASE_VERTICAL_OFFSET,
z: TANK_POSITION.z
},
dimensions: TANK_BASE_DIMENSIONS
}
tankBase = Entities.addEntity(properties);
}
createFishTank();
createInnerContainer();
createBubbleSystems();
createEntitiesAtCorners();
createUrchin();
createRocks();
createTankBase();
createTreasureChest();
var customKey = 'hifi-home-fishtank';
var data = {
fishLoaded: false,
bubbleSystem: bubbleSystem,
bubbleSound: bubbleSound,
corners: {
brn: lowerCorner,
tfl: upperCorner
},
innerContainer: innerContainer,
}
Script.setTimeout(function() {
setEntityCustomData(customKey, fishTank, data);
}, 2000)
function cleanup() {
Entities.deleteEntity(fishTank);
Entities.deleteEntity(tankBase);
Entities.deleteEntity(bubbleSystem);
Entities.deleteEntity(secondBubbleSystem);
Entities.deleteEntity(thirdBubbleSystem);
Entities.deleteEntity(innerContainer);
Entities.deleteEntity(lowerCorner);
Entities.deleteEntity(upperCorner);
Entities.deleteEntity(urchin);
Entities.deleteEntity(rocks);
bubbleInjector.stop();
bubbleInjector = null;
}
function setEntityUserData(id, data) {
var json = JSON.stringify(data)
Entities.editEntity(id, {
userData: json
});
}
function getEntityUserData(id) {
var results = null;
var properties = Entities.getEntityProperties(id, "userData");
if (properties.userData) {
try {
results = JSON.parse(properties.userData);
} catch (err) {
// print('error parsing json');
// print('properties are:'+ properties.userData);
}
}
return results ? results : {};
}
// Non-destructively modify the user data of an entity.
function setEntityCustomData(customKey, id, data) {
var userData = getEntityUserData(id);
if (data == null) {
delete userData[customKey];
} else {
userData[customKey] = data;
}
setEntityUserData(id, userData);
}
function getEntityCustomData(customKey, id, defaultValue) {
var userData = getEntityUserData(id);
if (undefined != userData[customKey]) {
return userData[customKey];
} else {
return defaultValue;
}
}
this.cleanup = cleanup;
return this;
}

View file

@ -15,7 +15,8 @@
Script.include('../../../../libraries/utils.js');
var _this;
GrowingPlant = function() {
function GrowingPlant() {
_this = this;
_this.flowers = [];
// _this.STARTING_FLOWER_DIMENSIONS = {x: 0.1, y: 0.001, z: 0.1}
@ -49,8 +50,6 @@
};
GrowingPlant.prototype = {
continueWatering: function(entityID, data) {
// we're being watered- every now and then spawn a new flower to add to our growing list
// If we don't have any flowers yet, immediately grow one
@ -78,8 +77,12 @@
return;
}
var xzGrowthRate = randFloat(0.00006, 0.00016);
var growthRate = {x: xzGrowthRate, y: randFloat(0.001, 0.003), z: xzGrowthRate};
var growthRate = {
x: xzGrowthRate,
y: randFloat(0.001, 0.003),
z: xzGrowthRate
};
var flower = {
dimensions: {
x: _this.STARTING_FLOWER_DIMENSIONS.x,
@ -99,7 +102,7 @@
// saturation: 0.92,
// light: 0.41
// },
hslColor: Math.random() < 0.5 ? _this.flowerHSLColors[0] : _this.flowerHSLColors[1],
hslColor: Math.random() < 0.5 ? _this.flowerHSLColors[0] : _this.flowerHSLColors[1],
growthRate: growthRate
};
flower.userData = {

View file

@ -15,7 +15,7 @@
Script.include('../../../../libraries/utils.js');
var _this;
WaterSpout = function() {
function WaterSpout() {
_this = this;
_this.waterSound = SoundCache.getSound("https://s3-us-west-1.amazonaws.com/hifi-content/eric/Sounds/shower.wav");
_this.POUR_ANGLE_THRESHOLD = 0;

View file

@ -0,0 +1,143 @@
//
// growingPlantSpawner.js
// examples/homeContent/plant
//
// Created by Eric Levin on 2/10/16.
// Copyright 2016 High Fidelity, Inc.
//
// This entity script handles the logic for growing a plant when it has water poured on it
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
var PLANT_SCRIPT_URL = Script.resolvePath("growingPlantEntityScript.js?v1" + Math.random().toFixed(2));
var WATER_CAN_SCRIPT_URL = Script.resolvePath("waterCanEntityScript.js?v2" + Math.random().toFixed());
Plant = function(spawnPosition, spawnRotation) {
var orientation = Camera.getOrientation();
orientation = Quat.safeEulerAngles(orientation);
orientation.x = 0;
orientation = Quat.fromVec3Degrees(orientation);
if (spawnRotation !== undefined) {
orientation = spawnRotation;
}
var bowlPosition = spawnPosition;
var BOWL_MODEL_URL = "http://hifi-content.s3.amazonaws.com/alan/dev/Flowers--Bowl.fbx";
var bowlDimensions = {
x: 0.518,
y: 0.1938,
z: 0.5518
};
var bowl = Entities.addEntity({
type: "Model",
modelURL: BOWL_MODEL_URL,
dimensions: bowlDimensions,
name: "plant bowl",
position: bowlPosition
});
var PLANT_MODEL_URL = "http://hifi-content.s3.amazonaws.com/alan/dev/Flowers--Moss-Rock.fbx";
var plantDimensions = {
x: 0.52,
y: 0.2600,
z: 0.52
};
var plantPosition = Vec3.sum(bowlPosition, {
x: 0,
y: plantDimensions.y / 2,
z: 0
});
var plant = Entities.addEntity({
type: "Model",
modelURL: PLANT_MODEL_URL,
name: "hifi-growable-plant",
dimensions: plantDimensions,
position: plantPosition,
script: PLANT_SCRIPT_URL,
parentID: bowl
});
var WATER_CAN_MODEL_URL = "https://s3-us-west-1.amazonaws.com/hifi-content/eric/models/waterCan.fbx?v1" + Math.random();
var waterCanPosition = Vec3.sum(plantPosition, Vec3.multiply(0.6, Quat.getRight(orientation)));
var waterCanRotation = orientation;
var waterCan = Entities.addEntity({
type: "Model",
shapeType: 'box',
name: "hifi-water-can",
modelURL: WATER_CAN_MODEL_URL,
script: WATER_CAN_SCRIPT_URL,
dimensions: {
x: 0.1859,
y: 0.2762,
z: 0.4115
},
position: waterCanPosition,
angularDamping: 1,
dynamic: true,
gravity: {
x: 0.0,
y: -2.0,
z: 0
},
rotation: waterCanRotation,
userData: JSON.stringify({
wearable: {
joints: {
RightHand: [{
x: 0.024,
y: 0.173,
z: 0.152
}, {
x: 0.374,
y: 0.636,
z: -0.638,
w: -0.215
}],
LeftHand: [{
x: -0.0348,
y: 0.201,
z: 0.166
}, {
x: 0.4095,
y: -0.625,
z: 0.616,
w: -0.247
}]
}
}
})
});
var waterSpoutPosition = Vec3.sum(waterCanPosition, Vec3.multiply(0.2, Quat.getFront(orientation)))
var waterSpoutRotation = Quat.multiply(waterCanRotation, Quat.fromPitchYawRollDegrees(10, 0, 0));
var waterSpout = Entities.addEntity({
type: "Box",
name: "hifi-water-spout",
dimensions: {
x: 0.02,
y: 0.02,
z: 0.07
},
color: {
red: 200,
green: 10,
blue: 200
},
position: waterSpoutPosition,
rotation: waterSpoutRotation,
parentID: waterCan,
visible: false
});
function cleanup() {
Entities.deleteEntity(plant);
Entities.deleteEntity(bowl);
Entities.deleteEntity(waterCan);
Entities.deleteEntity(waterSpout);
}
this.cleanup = cleanup;
}

View file

@ -1,139 +0,0 @@
//
// growingPlantSpawner.js
// examples/homeContent/plant
//
// Created by Eric Levin on 2/10/16.
// Copyright 2016 High Fidelity, Inc.
//
// This entity script handles the logic for growing a plant when it has water poured on it
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
var orientation = Camera.getOrientation();
orientation = Quat.safeEulerAngles(orientation);
orientation.x = 0;
orientation = Quat.fromVec3Degrees(orientation);
var bowlPosition = Vec3.sum(MyAvatar.position, Vec3.multiply(2, Quat.getFront(orientation)));
var BOWL_MODEL_URL = "http://hifi-content.s3.amazonaws.com/alan/dev/Flowers--Bowl.fbx";
var bowlDimensions = {
x: 0.518,
y: 0.1938,
z: 0.5518
};
var bowl = Entities.addEntity({
type: "Model",
modelURL: BOWL_MODEL_URL,
dimensions: bowlDimensions,
name: "plant bowl",
position: bowlPosition
});
var PLANT_MODEL_URL = "http://hifi-content.s3.amazonaws.com/alan/dev/Flowers--Moss-Rock.fbx";
var PLANT_SCRIPT_URL = Script.resolvePath("growingPlantEntityScript.js?v1" + Math.random().toFixed(2));
var plantDimensions = {
x: 0.52,
y: 0.2600,
z: 0.52
};
var plantPosition = Vec3.sum(bowlPosition, {
x: 0,
y: plantDimensions.y / 2,
z: 0
});
var plant = Entities.addEntity({
type: "Model",
modelURL: PLANT_MODEL_URL,
name: "hifi-growable-plant",
dimensions: plantDimensions,
position: plantPosition,
script: PLANT_SCRIPT_URL,
parentID: bowl
});
var WATER_CAN_MODEL_URL = "https://s3-us-west-1.amazonaws.com/hifi-content/eric/models/waterCan.fbx?v1" + Math.random();
var WATER_CAN_SCRIPT_URL = Script.resolvePath("waterCanEntityScript.js?v2" + Math.random().toFixed());
var waterCanPosition = Vec3.sum(plantPosition, Vec3.multiply(0.6, Quat.getRight(orientation)));
var waterCanRotation = orientation;
var waterCan = Entities.addEntity({
type: "Model",
shapeType: 'box',
name: "hifi-water-can",
modelURL: WATER_CAN_MODEL_URL,
script: WATER_CAN_SCRIPT_URL,
dimensions: {
x: 0.1859,
y: 0.2762,
z: 0.4115
},
position: waterCanPosition,
angularDamping: 1,
dynamic: true,
gravity: {
x: 0.0,
y: -2.0,
z: 0
},
rotation: waterCanRotation,
userData: JSON.stringify({
wearable: {
joints: {
RightHand: [{
x: 0.024,
y: 0.173,
z: 0.152
}, {
x: 0.374,
y: 0.636,
z: -0.638,
w: -0.215
}],
LeftHand: [{
x: -0.0348,
y: 0.201,
z: 0.166
}, {
x: 0.4095,
y: -0.625,
z: 0.616,
w: -0.247
}]
}
}
})
});
var waterSpoutPosition = Vec3.sum(waterCanPosition, Vec3.multiply(0.2, Quat.getFront(orientation)))
var waterSpoutRotation = Quat.multiply(waterCanRotation, Quat.fromPitchYawRollDegrees(10, 0, 0));
var waterSpout = Entities.addEntity({
type: "Box",
name: "hifi-water-spout",
dimensions: {
x: 0.02,
y: 0.02,
z: 0.07
},
color: {
red: 200,
green: 10,
blue: 200
},
position: waterSpoutPosition,
rotation: waterSpoutRotation,
parentID: waterCan,
visible: false
});
function cleanup() {
// Entities.deleteEntity(plant);
// Entities.deleteEntity(bowl);
// Entities.deleteEntity(waterCan);
// Entities.deleteEntity(waterSpout);
}
Script.scriptEnding.connect(cleanup);

View file

@ -0,0 +1,129 @@
//
// reset.js
//
// Created by James B. Pollack @imgntn on 3/14/2016
// Copyright 2016 High Fidelity, Inc.
//
// This cleanups up and creates content for the home.
//
//
// 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;
var dynamicEntities = [];
function Reset() {
_this = this;
};
var utilsPath = Script.resolvePath('utils.js');
var fishTankPath = Script.resolvePath('fishTank/wrapper.js?' + Math.random());
var tiltMazePath = Script.resolvePath("tiltMaze/wrapper.js?" + Math.random())
var whiteboardPath = Script.resolvePath("whiteboard/wrapper.js?" + Math.random());
var plantPath = Script.resolvePath("growingPlant/wrapper.js?" + Math.random());
Reset.prototype = {
preload: function(entityID) {
_this.entityID = entityID;
},
unload: function() {
this.cleanupDynamicEntities();
},
tidying: false,
showTidyingButton: function() {
var textureString =
'Texture.001:"http://hifi-content.s3.amazonaws.com/DomainContent/Home/tidyGuy/Tidyguy-6.fbx/Tidyguy-6.fbm/Head-Housing-Texture.png",\ntex.face.screen.emit:"http://hifi-content.s3.amazonaws.com/DomainContent/Home/tidyGuy/Tidyguy-6.fbx/Tidyguy-6.fbm/tidy-guy-face-Emit.png",\ntex.face.sceen:"http://hifi-content.s3.amazonaws.com/DomainContent/Home/tidyGuy/Tidyguy-6.fbx/Tidyguy-6.fbm/tidy-guy-face.png",\ntex.button.blanks:"http://hifi-content.s3.amazonaws.com/DomainContent/Home/tidyGuy/Tidyguy-6.fbx/Tidyguy-6.fbm/Button-Blanks.png",\ntex.button.blanks.normal:"http://hifi-content.s3.amazonaws.com/DomainContent/Home/tidyGuy/Tidyguy-6.fbx/Tidyguy-6.fbm/Button-Blanks-Normal.png",\nbutton.tidy.emit:"http://hifi-content.s3.amazonaws.com/DomainContent/Home/tidyGuy/Tidy-Up-Button-Orange-Emit.png",\nbutton.tidy:"http://hifi-content.s3.amazonaws.com/DomainContent/Home/tidyGuy/Tidy-Up-Button-Orange.png"'
Entities.editEntity(_this.entityID, {
textures: textureString
});
},
showTidyButton: function() {
var textureString =
'Texture.001:"http://hifi-content.s3.amazonaws.com/DomainContent/Home/tidyGuy/Tidyguy-6.fbx/Tidyguy-6.fbm/Head-Housing-Texture.png",\ntex.face.screen.emit:"http://hifi-content.s3.amazonaws.com/DomainContent/Home/tidyGuy/Tidyguy-6.fbx/Tidyguy-6.fbm/tidy-guy-face-Emit.png",\ntex.face.sceen:"http://hifi-content.s3.amazonaws.com/DomainContent/Home/tidyGuy/Tidyguy-6.fbx/Tidyguy-6.fbm/tidy-guy-face.png",\ntex.button.blanks:"http://hifi-content.s3.amazonaws.com/DomainContent/Home/tidyGuy/Tidyguy-6.fbx/Tidyguy-6.fbm/Button-Blanks.png",\ntex.button.blanks.normal:"http://hifi-content.s3.amazonaws.com/DomainContent/Home/tidyGuy/Tidyguy-6.fbx/Tidyguy-6.fbm/Button-Blanks-Normal.png",\nbutton.tidy.emit:"http://hifi-content.s3.amazonaws.com/DomainContent/Home/tidyGuy/Tidyguy-6.fbx/Tidyguy-6.fbm/Tidy-Up-Button-Green-Emit.png",\nbutton.tidy:"http://hifi-content.s3.amazonaws.com/DomainContent/Home/tidyGuy/Tidyguy-6.fbx/Tidyguy-6.fbm/Tidy-Up-Button-Green.png"'
Entities.editEntity(_this.entityID, {
textures: textureString
});
},
playTidyingSound: function() {
},
toggleButton: function() {
if (_this.tidying === true) {
return;
} else {
_this.tidying = true;
_this.showTidyingButton();
_this.playTidyingSound();
Script.setTimeout(function() {
_this.showTidyButton();
_this.tidying = false;
}, 2500);
_this.cleanupDynamicEntities();
_this.createDynamicEntities();
}
},
clickReleaseOnEntity: function(entityID, mouseEvent) {
if (!mouseEvent.isLeftButton) {
return;
}
_this.toggleButton();
},
startNearTrigger: function() {
_this.toggleButton();
},
createDynamicEntities: function() {
var center = Vec3.sum(Vec3.sum(MyAvatar.position, {
x: 0,
y: 0.5,
z: 0
}), Vec3.multiply(1, Quat.getFront(Camera.getOrientation())));
Script.include(utilsPath);
Script.include(fishTankPath);
Script.include(tiltMazePath);
Script.include(whiteboardPath);
Script.include(plantPath);
// var fishTank = new FishTank(center);
// var tiltMaze = new TiltMaze(center);
// var whiteboard = new Whiteboard(center);
var myPlant = new Plant(center);
// dynamicEntities.push(fishTank);
// dynamicEntities.push(tiltMaze);
// dynamicEntities.push(whiteboard);
dynamicEntities.push(myPlant);
//v2.0
// var musicBox = new MusicBox();
// var cuckooClock = new CuckooClock();
// var doppelganger = new Doppelganger();
},
cleanupDynamicEntities: function() {
if (dynamicEntities.length === 0) {
return;
}
dynamicEntities.forEach(function(dynamicEntity) {
dynamicEntity.cleanup();
})
},
}
return new Reset();
});

View file

@ -0,0 +1,180 @@
(function() {
var SEARCH_RADIUS = 100;
var EMISSIVE_TEXTURE_URL = "http://hifi-content.s3.amazonaws.com/highfidelitysign_white_emissive.png";
var DIFFUSE_TEXTURE_URL = "http://hifi-content.s3.amazonaws.com/highfidelity_diffusebaked.png";
var _this;
var utilitiesScript = Script.resolvePath('../../../../libraries/utils.js');
Script.include(utilitiesScript);
Switch = function() {
_this = this;
this.switchSound = SoundCache.getSound("https://hifi-public.s3.amazonaws.com/sounds/Switches%20and%20sliders/lamp_switch_2.wav");
};
Switch.prototype = {
prefix: 'hifi-home-dressing-room-disc-light',
clickReleaseOnEntity: function(entityID, mouseEvent) {
if (!mouseEvent.isLeftButton) {
return;
}
this.toggleLights();
},
startNearTrigger: function() {
this.toggleLights();
},
modelEmitOn: function(discModel) {
Entities.editEntity(glowDisc, {
textures: 'emissive:' + EMISSIVE_TEXTURE_URL ',\ndiffuse:"' + DIFFUSE_TEXTURE_URL + '"'
})
},
modelEmitOff: function(discModel) {
Entities.editEntity(glowDisc, {
textures: 'emissive:"",\ndiffuse:"' + DIFFUSE_TEXTURE_URL + '"'
})
},
masterLightOn: function(masterLight) {
Entities.editEntity(masterLight, {
visible: true
});
},
masterLightOff: function() {
Entities.editEntity(masterLight, {
visible: false
});
},
glowLightOn: function(glowLight) {
Entities.editEntity(glowLight, {
visible: true
});
},
glowLightOff: function(glowLight) {
Entities.editEntity(glowLight, {
visible: false
});
},
findGlowLights: function() {
var found = [];
var results = Entities.findEntities(this.position, SEARCH_RADIUS);
results.forEach(function(result) {
var properties = Entities.getEntityProperties(result);
if (properties.name === _this.prefix + "light-glow") {
found.push(result);
}
});
return found;
},
findMasterLights: function() {
var found = [];
var results = Entities.findEntities(this.position, SEARCH_RADIUS);
results.forEach(function(result) {
var properties = Entities.getEntityProperties(result);
if (properties.name === _this.prefix + "light-master") {
found.push(result);
}
});
return found;
},
findEmitModels: function() {
var found = [];
var results = Entities.findEntities(this.position, SEARCH_RADIUS);
results.forEach(function(result) {
var properties = Entities.getEntityProperties(result);
if (properties.name === _this.prefix + "light-model") {
found.push(result);
}
});
return found;
},
toggleLights: function() {
this.switch = getEntityCustomData('home-switch', this.entityID, {
state: 'off'
});
var glowLights = this.findGlowLights();
var masterLights = this.findMasterLights();
var emitModels = this.findEmitModels();
if (this.switch.state === 'off') {
glowLights.forEach(function(glowLight) {
_this.glowLightOn(glowLight);
});
masterLights.forEach(function(masterLight) {
_this.masterLightOn(masterLight);
});
emitModels.forEach(function(emitModel) {
_this.modelEmitOn(emitModel);
});
setEntityCustomData('home-switch', this.entityID, {
state: 'on'
});
} else {
glowLights.forEach(function(glowLight) {
_this.glowLightOff(glowLight);
});
masterLights.forEach(function(masterLight) {
_this.masterLightOff(masterLight);
});
emitModels.forEach(function(emitModel) {
_this.modelEmitOff(emitModel);
});
setEntityCustomData('home-switch', this.entityID, {
state: 'off'
});
}
this.flipSwitch();
Audio.playSound(this.switchSound, {
volume: 0.5,
position: this.position
});
},
flipSwitch: function() {
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;
setEntityCustomData('grabbableKey', this.entityID, {
wantsTrigger: true
});
var properties = Entities.getEntityProperties(this.entityID);
//The light switch is static, so just cache its position once
this.position = Entities.getEntityProperties(this.entityID, "position").position;
}
};
// entity scripts always need to return a newly constructed object of our type
return new Switch();
});

View file

@ -0,0 +1,150 @@
(function() {
var SEARCH_RADIUS = 10;
var EMISSIVE_TEXTURE_URL = "http://hifi-content.s3.amazonaws.com/highfidelitysign_white_emissive.png";
var DIFFUSE_TEXTURE_URL = "http://hifi-content.s3.amazonaws.com/highfidelity_diffusebaked.png";
var _this;
var utilitiesScript = Script.resolvePath('../../../../libraries/utils.js');
Script.include(utilitiesScript);
Switch = function() {
_this = this;
this.switchSound = SoundCache.getSound("https://hifi-public.s3.amazonaws.com/sounds/Switches%20and%20sliders/lamp_switch_2.wav");
};
Switch.prototype = {
prefix: 'hifi-home-lab-desk-lamp',
clickReleaseOnEntity: function(entityID, mouseEvent) {
if (!mouseEvent.isLeftButton) {
return;
}
this.toggleLights();
},
startNearTrigger: function() {
this.toggleLights();
},
modelEmitOn: function(discModel) {
Entities.editEntity(glowDisc, {
textures: 'emissive:' + EMISSIVE_TEXTURE_URL ',\ndiffuse:"' + DIFFUSE_TEXTURE_URL + '"'
})
},
modelEmitOff: function(discModel) {
Entities.editEntity(glowDisc, {
textures: 'emissive:"",\ndiffuse:"' + DIFFUSE_TEXTURE_URL + '"'
})
},
masterLightOn: function(masterLight) {
Entities.editEntity(masterLight, {
visible: true
});
},
masterLightOff: function() {
Entities.editEntity(masterLight, {
visible: false
});
},
findMasterLights: function() {
var found = [];
var results = Entities.findEntities(this.position, SEARCH_RADIUS);
results.forEach(function(result) {
var properties = Entities.getEntityProperties(result);
if (properties.name === _this.prefix + "spotlight") {
found.push(result);
}
});
return found;
},
findEmitModels: function() {
var found = [];
var results = Entities.findEntities(this.position, SEARCH_RADIUS);
results.forEach(function(result) {
var properties = Entities.getEntityProperties(result);
if (properties.name === _this.prefix + "model") {
found.push(result);
}
});
return found;
},
toggleLights: function() {
this.switch = getEntityCustomData('home-switch', this.entityID, {
state: 'off'
});
var masterLights = this.findMasterLights();
var emitModels = this.findEmitModels();
if (this.switch.state === 'off') {
masterLights.forEach(function(masterLight) {
_this.masterLightOn(masterLight);
});
emitModels.forEach(function(emitModel) {
_this.modelEmitOn(emitModel);
});
setEntityCustomData('home-switch', this.entityID, {
state: 'on'
});
} else {
masterLights.forEach(function(masterLight) {
_this.masterLightOff(masterLight);
});
emitModels.forEach(function(emitModel) {
_this.modelEmitOff(emitModel);
});
setEntityCustomData('home-switch', this.entityID, {
state: 'off'
});
}
this.flipSwitch();
Audio.playSound(this.switchSound, {
volume: 0.5,
position: this.position
});
},
flipSwitch: function() {
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;
setEntityCustomData('grabbableKey', this.entityID, {
wantsTrigger: true
});
var properties = Entities.getEntityProperties(this.entityID);
//The light switch is static, so just cache its position once
this.position = Entities.getEntityProperties(this.entityID, "position").position;
}
};
// entity scripts always need to return a newly constructed object of our type
return new Switch();
});

View file

@ -0,0 +1,17 @@
hifi-home-living-room-disc-light-model
hifi-home-living-room-disc-light-glow
hifi-home-living-room-disc-light-master
hifi-home-living-room-ceiling-fan
hifi-home-living-room-ceiling-fan-sound
hifi-home-living-room-vent-sound
hifi-home-living-room-desk-lamp-trigger
hifi-home-living-room-desk-lamp-spotlight
hifi-home-lab-desk-lamp-trigger
hifi-home-lab-desk-lamp-spotlight
hifi-home-dressing-room-disc-light-model
hifi-home-dressing-room-disc-light-glow
hifi-home-dressing-room-disc-light-master

View file

@ -0,0 +1,151 @@
(function() {
var SEARCH_RADIUS = 10;
var EMISSIVE_TEXTURE_URL = "http://hifi-content.s3.amazonaws.com/highfidelitysign_white_emissive.png";
var DIFFUSE_TEXTURE_URL = "http://hifi-content.s3.amazonaws.com/highfidelity_diffusebaked.png";
var _this;
var utilitiesScript = Script.resolvePath('../../../../libraries/utils.js');
Script.include(utilitiesScript);
Switch = function() {
_this = this;
this.switchSound = SoundCache.getSound("https://hifi-public.s3.amazonaws.com/sounds/Switches%20and%20sliders/lamp_switch_2.wav");
};
Switch.prototype = {
prefix: 'hifi-home-living-room-desk-lamp',
clickReleaseOnEntity: function(entityID, mouseEvent) {
if (!mouseEvent.isLeftButton) {
return;
}
this.toggleLights();
},
startNearTrigger: function() {
this.toggleLights();
},
modelEmitOn: function(discModel) {
Entities.editEntity(glowDisc, {
textures: 'emissive:' + EMISSIVE_TEXTURE_URL ',\ndiffuse:"' + DIFFUSE_TEXTURE_URL + '"'
})
},
modelEmitOff: function(discModel) {
Entities.editEntity(glowDisc, {
textures: 'emissive:"",\ndiffuse:"' + DIFFUSE_TEXTURE_URL + '"'
})
},
masterLightOn: function(masterLight) {
Entities.editEntity(masterLight, {
visible: true
});
},
masterLightOff: function() {
Entities.editEntity(masterLight, {
visible: false
});
},
findMasterLights: function() {
var found = [];
var results = Entities.findEntities(this.position, SEARCH_RADIUS);
results.forEach(function(result) {
var properties = Entities.getEntityProperties(result);
if (properties.name === _this.prefix + "spotlight") {
found.push(result);
}
});
return found;
},
findEmitModels: function() {
var found = [];
var results = Entities.findEntities(this.position, SEARCH_RADIUS);
results.forEach(function(result) {
var properties = Entities.getEntityProperties(result);
if (properties.name === _this.prefix + "model") {
found.push(result);
}
});
return found;
},
toggleLights: function() {
this.switch = getEntityCustomData('home-switch', this.entityID, {
state: 'off'
});
var masterLights = this.findMasterLights();
var emitModels = this.findEmitModels();
if (this.switch.state === 'off') {
masterLights.forEach(function(masterLight) {
_this.masterLightOn(masterLight);
});
emitModels.forEach(function(emitModel) {
_this.modelEmitOn(emitModel);
});
setEntityCustomData('home-switch', this.entityID, {
state: 'on'
});
} else {
masterLights.forEach(function(masterLight) {
_this.masterLightOff(masterLight);
});
emitModels.forEach(function(emitModel) {
_this.modelEmitOff(emitModel);
});
setEntityCustomData('home-switch', this.entityID, {
state: 'off'
});
}
this.flipSwitch();
Audio.playSound(this.switchSound, {
volume: 0.5,
position: this.position
});
},
flipSwitch: function() {
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;
setEntityCustomData('grabbableKey', this.entityID, {
wantsTrigger: true
});
var properties = Entities.getEntityProperties(this.entityID);
//The light switch is static, so just cache its position once
this.position = Entities.getEntityProperties(this.entityID, "position").position;
}
};
// entity scripts always need to return a newly constructed object of our type
return new Switch();
});

View file

@ -0,0 +1,180 @@
(function() {
var SEARCH_RADIUS = 100;
var EMISSIVE_TEXTURE_URL = "http://hifi-content.s3.amazonaws.com/highfidelitysign_white_emissive.png";
var DIFFUSE_TEXTURE_URL = "http://hifi-content.s3.amazonaws.com/highfidelity_diffusebaked.png";
var _this;
var utilitiesScript = Script.resolvePath('../../../../libraries/utils.js');
Script.include(utilitiesScript);
Switch = function() {
_this = this;
this.switchSound = SoundCache.getSound("https://hifi-public.s3.amazonaws.com/sounds/Switches%20and%20sliders/lamp_switch_2.wav");
};
Switch.prototype = {
prefix: 'hifi-home-living-room-disc-light',
clickReleaseOnEntity: function(entityID, mouseEvent) {
if (!mouseEvent.isLeftButton) {
return;
}
this.toggleLights();
},
startNearTrigger: function() {
this.toggleLights();
},
modelEmitOn: function(discModel) {
Entities.editEntity(glowDisc, {
textures: 'emissive:' + EMISSIVE_TEXTURE_URL ',\ndiffuse:"' + DIFFUSE_TEXTURE_URL + '"'
})
},
modelEmitOff: function(discModel) {
Entities.editEntity(glowDisc, {
textures: 'emissive:"",\ndiffuse:"' + DIFFUSE_TEXTURE_URL + '"'
})
},
masterLightOn: function(masterLight) {
Entities.editEntity(masterLight, {
visible: true
});
},
masterLightOff: function() {
Entities.editEntity(masterLight, {
visible: false
});
},
glowLightOn: function(glowLight) {
Entities.editEntity(glowLight, {
visible: true
});
},
glowLightOff: function(glowLight) {
Entities.editEntity(glowLight, {
visible: false
});
},
findGlowLights: function() {
var found = [];
var results = Entities.findEntities(this.position, SEARCH_RADIUS);
results.forEach(function(result) {
var properties = Entities.getEntityProperties(result);
if (properties.name === _this.prefix + "light-glow") {
found.push(result);
}
});
return found;
},
findMasterLights: function() {
var found = [];
var results = Entities.findEntities(this.position, SEARCH_RADIUS);
results.forEach(function(result) {
var properties = Entities.getEntityProperties(result);
if (properties.name === _this.prefix + "light-master") {
found.push(result);
}
});
return found;
},
findEmitModels: function() {
var found = [];
var results = Entities.findEntities(this.position, SEARCH_RADIUS);
results.forEach(function(result) {
var properties = Entities.getEntityProperties(result);
if (properties.name === _this.prefix + "light-model") {
found.push(result);
}
});
return found;
},
toggleLights: function() {
this.switch = getEntityCustomData('home-switch', this.entityID, {
state: 'off'
});
var glowLights = this.findGlowLights();
var masterLights = this.findMasterLights();
var emitModels = this.findEmitModels();
if (this.switch.state === 'off') {
glowLights.forEach(function(glowLight) {
_this.glowLightOn(glowLight);
});
masterLights.forEach(function(masterLight) {
_this.masterLightOn(masterLight);
});
emitModels.forEach(function(emitModel) {
_this.modelEmitOn(emitModel);
});
setEntityCustomData('home-switch', this.entityID, {
state: 'on'
});
} else {
glowLights.forEach(function(glowLight) {
_this.glowLightOff(glowLight);
});
masterLights.forEach(function(masterLight) {
_this.masterLightOff(masterLight);
});
emitModels.forEach(function(emitModel) {
_this.modelEmitOff(emitModel);
});
setEntityCustomData('home-switch', this.entityID, {
state: 'off'
});
}
this.flipSwitch();
Audio.playSound(this.switchSound, {
volume: 0.5,
position: this.position
});
},
flipSwitch: function() {
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;
setEntityCustomData('grabbableKey', this.entityID, {
wantsTrigger: true
});
var properties = Entities.getEntityProperties(this.entityID);
//The light switch is static, so just cache its position once
this.position = Entities.getEntityProperties(this.entityID, "position").position;
}
};
// entity scripts always need to return a newly constructed object of our type
return new Switch();
});

View file

@ -0,0 +1,136 @@
(function() {
var SEARCH_RADIUS = 100;
var _this;
var utilitiesScript = Script.resolvePath('../../../../libraries/utils.js');
Script.include(utilitiesScript);
Switch = function() {
_this = this;
this.switchSound = SoundCache.getSound("https://hifi-public.s3.amazonaws.com/sounds/Switches%20and%20sliders/lamp_switch_2.wav");
};
Switch.prototype = {
prefix: 'hifi-home-living-room-fan',
clickReleaseOnEntity: function(entityID, mouseEvent) {
if (!mouseEvent.isLeftButton) {
return;
}
this.toggle();
},
startNearTrigger: function() {
this.toggle();
},
fanRotationOn: function() {
Entities.editEntity(this.fan, {
damping: 0,
angularVelocity: {
x: 0,
y: 0.25,
z: 0
}
})
},
fanRotationOff: function() {
Entities.editEntity(this.fan, {
damping: 1.0,
// angularVelocity:{
// x:0,
// y:0,
// z:0
// }
})
},
fanSoundOn: function() {
},
fanSoundOff: function() {
},
ventSoundOn: function() {
},
ventSoundOff: function() {
},
findFan: function() {
var found = [];
var results = Entities.findEntities(this.position, SEARCH_RADIUS);
results.forEach(function(result) {
var properties = Entities.getEntityProperties(result);
if (properties.name === _this.prefix) {
found.push(result);
}
});
return found;
},
toggle: function() {
this.fan = this.findFan();
this.switch = getEntityCustomData('home-switch', this.entityID, {
state: 'off'
});
if (this.switch.state === 'off') {
this.fanRotationOn();
this.fanSoundOn();
this.ventSoundOn();
setEntityCustomData('home-switch', this.entityID, {
state: 'on'
});
} else {
this.fanRotationOff();
this.fanSoundOff();
this.ventSoundOff();
setEntityCustomData('home-switch', this.entityID, {
state: 'off'
});
}
this.flipSwitch();
Audio.playSound(this.switchSound, {
volume: 0.5,
position: this.position
});
},
flipSwitch: function() {
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;
setEntityCustomData('grabbableKey', this.entityID, {
wantsTrigger: true
});
var properties = Entities.getEntityProperties(this.entityID);
//The light switch is static, so just cache its position once
this.position = Entities.getEntityProperties(this.entityID, "position").position;
}
};
// entity scripts always need to return a newly constructed object of our type
return new Switch();
});

View file

@ -1,272 +0,0 @@
//
// createTiltMaze.js
//
// Created by James B. Pollack @imgntn on 2/15/2016
// Copyright 2016 High Fidelity, Inc.
//
// This script creates a maze with a ball that you can tilt to try to get to the end.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
var ball, ballSpawningAnchor, ballDetector, tiltMaze, lightAtTheEnd;
var MAZE_MODEL_URL = "http://hifi-content.s3.amazonaws.com/DomainContent/Home/tiltMaze/newmaze_tex-4.fbx";
var MAZE_COLLISION_HULL = "http://hifi-content.s3.amazonaws.com/DomainContent/Home/tiltMaze/newmaze_tex-3.obj";
var MAZE_SCRIPT = Script.resolvePath('maze.js?' + Math.random());
var SCALE = 0.5;
var MAZE_DIMENSIONS = Vec3.multiply(SCALE, {
x: 1,
y: 0.15,
z: 1
});
var BALL_DIMENSIONS = Vec3.multiply(SCALE, {
x: 0.035,
y: 0.035,
z: 0.035
});
var BALL_SPAWNER_DIMENSIONS = Vec3.multiply(SCALE, {
x: 0.05,
y: 0.05,
z: 0.05
});
var BALL_DETECTOR_DIMENSIONS = Vec3.multiply(SCALE, {
x: 0.1,
y: 0.1,
z: 0.1
});
var BALL_COLOR = {
red: 255,
green: 0,
blue: 0
};
var DEBUG_COLOR = {
red: 0,
green: 255,
blue: 0
};
var center = Vec3.sum(Vec3.sum(MyAvatar.position, {
x: 0,
y: 0.5,
z: 0
}), Vec3.multiply(1.5, Quat.getFront(Camera.getOrientation())));
var CLEANUP = true;
var BALL_FORWARD_OFFSET = -0.2 * SCALE;
var BALL_RIGHT_OFFSET = -0.4 * SCALE;
var BALL_VERTICAL_OFFSET = 0.02 * SCALE;
var BALL_FRICTION = 0.7;
var BALL_RESTITUTION = 0.1;
var BALL_DAMPING = 0.6;
var BALL_ANGULAR_DAMPING = 0.2;
var BALL_DENSITY = 1000;
var BALL_GRAVITY = {
x: 0,
y: -9.8,
z: 0
};
var MAZE_DENSITY = 1000;
var MAZE_RESTITUTION = 0.1;
var MAZE_DAMPING = 0.6;
var MAZE_ANGULAR_DAMPING = 0.6;
var DETECTOR_VERTICAL_OFFSET = 0.0 * SCALE;
var DETECTOR_FORWARD_OFFSET = 0.35 * SCALE;
var DETECTOR_RIGHT_OFFSET = 0.35 * SCALE;
var END_LIGHT_COLOR = {
red: 255,
green: 0,
blue: 0
};
var END_LIGHT_DIMENSIONS = {
x: 0.2,
y: 0.2,
z: 0.8
};
var END_LIGHT_INTENSITY = 0.035;
var END_LIGHT_CUTOFF = 30;
var END_LIGHT_EXPONENT = 1;
var getBallStartLocation = function() {
var mazeProps = Entities.getEntityProperties(tiltMaze);
var right = Quat.getRight(mazeProps.rotation);
var front = Quat.getFront(mazeProps.rotation);
var vertical = {
x: 0,
y: BALL_VERTICAL_OFFSET,
z: 0
};
var finalOffset = Vec3.sum(vertical, Vec3.multiply(right, BALL_RIGHT_OFFSET));
finalOffset = Vec3.sum(finalOffset, Vec3.multiply(front, BALL_FORWARD_OFFSET));
var location = Vec3.sum(mazeProps.position, finalOffset);
return location;
};
var getBallFinishLocation = function() {
var mazeProps = Entities.getEntityProperties(tiltMaze);
var right = Quat.getRight(mazeProps.rotation);
var forward = Quat.getFront(mazeProps.rotation);
var up = Quat.getUp(mazeProps.rotation);
var position = Vec3.sum(mazeProps.position, Vec3.multiply(up, DETECTOR_VERTICAL_OFFSET));
position = Vec3.sum(position, Vec3.multiply(right, DETECTOR_RIGHT_OFFSET));
position = Vec3.sum(position, Vec3.multiply(forward, DETECTOR_FORWARD_OFFSET));
return position;
};
var createBall = function(position) {
var properties = {
name: 'Hifi Tilt Maze Ball',
type: 'Sphere',
position: getBallStartLocation(),
dynamic: true,
collisionless: false,
friction: BALL_FRICTION,
restitution: BALL_RESTITUTION,
angularDamping: BALL_ANGULAR_DAMPING,
damping: BALL_DAMPING,
gravity: BALL_GRAVITY,
density: BALL_DENSITY,
color: BALL_COLOR,
dimensions: BALL_DIMENSIONS,
userData: JSON.stringify({
grabbableKey: {
grabbable: false
}
})
};
ball = Entities.addEntity(properties);
};
var createBallSpawningAnchor = function() {
var properties = {
name: 'Hifi Tilt Maze Ball Detector',
parentID: tiltMaze,
type: 'Box',
color: DEBUG_COLOR,
dimensions: BALL_SPAWNER_DIMENSIONS,
position: getBallStartLocation(),
collisionless: true,
visible: false,
};
ballSpawningAnchor = Entities.addEntity(properties);
};
var createBallDetector = function() {
var properties = {
name: 'Hifi Tilt Maze Ball Detector',
parentID: tiltMaze,
type: 'Box',
color: DEBUG_COLOR,
shapeType: 'none',
dimensions: BALL_DETECTOR_DIMENSIONS,
position: getBallFinishLocation(),
collisionless: true,
dynamic: false,
visible: false,
};
ballDetector = Entities.addEntity(properties);
};
var createTiltMaze = function(position) {
var properties = {
name: 'Hifi Tilt Maze',
type: 'Model',
modelURL: MAZE_MODEL_URL,
compoundShapeURL: MAZE_COLLISION_HULL,
dimensions: MAZE_DIMENSIONS,
position: position,
restitution: MAZE_RESTITUTION,
damping: MAZE_DAMPING,
angularDamping: MAZE_ANGULAR_DAMPING,
dynamic: true,
density: MAZE_DENSITY,
script: MAZE_SCRIPT
}
tiltMaze = Entities.addEntity(properties);
};
var createLightAtTheEnd = function() {
var mazeProps = Entities.getEntityProperties(tiltMaze, 'position');
var up = Quat.getUp(mazeProps.rotation);
var down = Vec3.multiply(-1, up);
var emitOrientation = Quat.rotationBetween(Vec3.UNIT_NEG_Z, down);
var position = getBallFinishLocation();
var lightProperties = {
parentID: tiltMaze,
name: 'Hifi Tilt Maze End Light',
type: "Light",
isSpotlight: true,
dimensions: END_LIGHT_DIMENSIONS,
color: END_LIGHT_COLOR,
intensity: END_LIGHT_INTENSITY,
exponent: END_LIGHT_EXPONENT,
cutoff: END_LIGHT_CUTOFF,
lifetime: -1,
position: position,
rotation: emitOrientation
};
lightAtTheEnd = Entities.addEntity(lightProperties);
};
var createAll = function() {
createTiltMaze(center);
createBallSpawningAnchor();
createBallDetector(center);
createBall(center);
createLightAtTheEnd();
Entities.editEntity(tiltMaze, {
userData: JSON.stringify({
tiltMaze: {
firstBall: ball,
ballSpawner: ballSpawningAnchor,
detector: ballDetector,
lightAtTheEnd: lightAtTheEnd
}
})
});
};
createAll();
if (CLEANUP === true) {
Script.scriptEnding.connect(function() {
Entities.deleteEntity(tiltMaze);
Entities.deleteEntity(ball);
Entities.deleteEntity(ballSpawningAnchor);
Entities.deleteEntity(lightAtTheEnd);
});
};

View file

@ -13,7 +13,7 @@
(function() {
Script.include('../../../../libraries/utils.js');
Script.include('../utils.js');
var SCALE = 0.5;
var VICTORY_SOUND;

View file

@ -0,0 +1,278 @@
//
// createTiltMaze.js
//
// Created by James B. Pollack @imgntn on 2/15/2016
// Copyright 2016 High Fidelity, Inc.
//
// This script creates a maze with a ball that you can tilt to try to get to the end.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
var MAZE_SCRIPT = Script.resolvePath('maze.js?' + Math.random());
TiltMaze = function(spawnPosition, spawnRotation) {
var ball, ballSpawningAnchor, ballDetector, tiltMaze, lightAtTheEnd;
var MAZE_MODEL_URL = "http://hifi-content.s3.amazonaws.com/DomainContent/Home/tiltMaze/newmaze_tex-4.fbx";
var MAZE_COLLISION_HULL = "http://hifi-content.s3.amazonaws.com/DomainContent/Home/tiltMaze/newmaze_tex-3.obj";
var SCALE = 0.5;
var MAZE_DIMENSIONS = Vec3.multiply(SCALE, {
x: 1,
y: 0.15,
z: 1
});
var BALL_DIMENSIONS = Vec3.multiply(SCALE, {
x: 0.035,
y: 0.035,
z: 0.035
});
var BALL_SPAWNER_DIMENSIONS = Vec3.multiply(SCALE, {
x: 0.05,
y: 0.05,
z: 0.05
});
var BALL_DETECTOR_DIMENSIONS = Vec3.multiply(SCALE, {
x: 0.1,
y: 0.1,
z: 0.1
});
var BALL_COLOR = {
red: 255,
green: 0,
blue: 0
};
var DEBUG_COLOR = {
red: 0,
green: 255,
blue: 0
};
var center = spawnPosition;
var CLEANUP = true;
var BALL_FORWARD_OFFSET = -0.2 * SCALE;
var BALL_RIGHT_OFFSET = -0.4 * SCALE;
var BALL_VERTICAL_OFFSET = 0.02 * SCALE;
var BALL_FRICTION = 0.7;
var BALL_RESTITUTION = 0.1;
var BALL_DAMPING = 0.6;
var BALL_ANGULAR_DAMPING = 0.2;
var BALL_DENSITY = 1000;
var BALL_GRAVITY = {
x: 0,
y: -9.8,
z: 0
};
var MAZE_DENSITY = 1000;
var MAZE_RESTITUTION = 0.1;
var MAZE_DAMPING = 0.6;
var MAZE_ANGULAR_DAMPING = 0.6;
var DETECTOR_VERTICAL_OFFSET = 0.0 * SCALE;
var DETECTOR_FORWARD_OFFSET = 0.35 * SCALE;
var DETECTOR_RIGHT_OFFSET = 0.35 * SCALE;
var END_LIGHT_COLOR = {
red: 255,
green: 0,
blue: 0
};
var END_LIGHT_DIMENSIONS = {
x: 0.2,
y: 0.2,
z: 0.8
};
var END_LIGHT_INTENSITY = 0.035;
var END_LIGHT_CUTOFF = 30;
var END_LIGHT_EXPONENT = 1;
var getBallStartLocation = function() {
var mazeProps = Entities.getEntityProperties(tiltMaze);
var right = Quat.getRight(mazeProps.rotation);
var front = Quat.getFront(mazeProps.rotation);
var vertical = {
x: 0,
y: BALL_VERTICAL_OFFSET,
z: 0
};
var finalOffset = Vec3.sum(vertical, Vec3.multiply(right, BALL_RIGHT_OFFSET));
finalOffset = Vec3.sum(finalOffset, Vec3.multiply(front, BALL_FORWARD_OFFSET));
var location = Vec3.sum(mazeProps.position, finalOffset);
return location;
};
var getBallFinishLocation = function() {
var mazeProps = Entities.getEntityProperties(tiltMaze);
var right = Quat.getRight(mazeProps.rotation);
var forward = Quat.getFront(mazeProps.rotation);
var up = Quat.getUp(mazeProps.rotation);
var position = Vec3.sum(mazeProps.position, Vec3.multiply(up, DETECTOR_VERTICAL_OFFSET));
position = Vec3.sum(position, Vec3.multiply(right, DETECTOR_RIGHT_OFFSET));
position = Vec3.sum(position, Vec3.multiply(forward, DETECTOR_FORWARD_OFFSET));
return position;
};
var createBall = function(position) {
var properties = {
name: 'Hifi Tilt Maze Ball',
type: 'Sphere',
position: getBallStartLocation(),
dynamic: true,
collisionless: false,
friction: BALL_FRICTION,
restitution: BALL_RESTITUTION,
angularDamping: BALL_ANGULAR_DAMPING,
damping: BALL_DAMPING,
gravity: BALL_GRAVITY,
density: BALL_DENSITY,
color: BALL_COLOR,
dimensions: BALL_DIMENSIONS,
userData: JSON.stringify({
grabbableKey: {
grabbable: false
}
})
};
ball = Entities.addEntity(properties);
};
var createBallSpawningAnchor = function() {
var properties = {
name: 'Hifi Tilt Maze Ball Detector',
parentID: tiltMaze,
type: 'Box',
color: DEBUG_COLOR,
dimensions: BALL_SPAWNER_DIMENSIONS,
position: getBallStartLocation(),
collisionless: true,
visible: false,
};
ballSpawningAnchor = Entities.addEntity(properties);
};
var createBallDetector = function() {
var properties = {
name: 'Hifi Tilt Maze Ball Detector',
parentID: tiltMaze,
type: 'Box',
color: DEBUG_COLOR,
shapeType: 'none',
dimensions: BALL_DETECTOR_DIMENSIONS,
position: getBallFinishLocation(),
collisionless: true,
dynamic: false,
visible: false,
};
ballDetector = Entities.addEntity(properties);
};
var createTiltMaze = function(position) {
var properties = {
name: 'Hifi Tilt Maze',
type: 'Model',
modelURL: MAZE_MODEL_URL,
compoundShapeURL: MAZE_COLLISION_HULL,
dimensions: MAZE_DIMENSIONS,
position: position,
restitution: MAZE_RESTITUTION,
damping: MAZE_DAMPING,
angularDamping: MAZE_ANGULAR_DAMPING,
dynamic: true,
density: MAZE_DENSITY,
script: MAZE_SCRIPT
}
if (spawnRotation !== undefined) {
properties.rotation = spawnRotation;
}
tiltMaze = Entities.addEntity(properties);
};
var createLightAtTheEnd = function() {
var mazeProps = Entities.getEntityProperties(tiltMaze, 'position');
var up = Quat.getUp(mazeProps.rotation);
var down = Vec3.multiply(-1, up);
var emitOrientation = Quat.rotationBetween(Vec3.UNIT_NEG_Z, down);
var position = getBallFinishLocation();
var lightProperties = {
parentID: tiltMaze,
name: 'Hifi Tilt Maze End Light',
type: "Light",
isSpotlight: true,
dimensions: END_LIGHT_DIMENSIONS,
color: END_LIGHT_COLOR,
intensity: END_LIGHT_INTENSITY,
exponent: END_LIGHT_EXPONENT,
cutoff: END_LIGHT_CUTOFF,
lifetime: -1,
position: position,
rotation: emitOrientation
};
lightAtTheEnd = Entities.addEntity(lightProperties);
};
var createAll = function() {
createTiltMaze(center);
createBallSpawningAnchor();
createBallDetector(center);
createBall(center);
createLightAtTheEnd();
Entities.editEntity(tiltMaze, {
userData: JSON.stringify({
tiltMaze: {
firstBall: ball,
ballSpawner: ballSpawningAnchor,
detector: ballDetector,
lightAtTheEnd: lightAtTheEnd
}
})
});
};
createAll();
function cleanup() {
Entities.deleteEntity(tiltMaze);
Entities.deleteEntity(ball);
Entities.deleteEntity(ballSpawningAnchor);
Entities.deleteEntity(lightAtTheEnd);
}
this.cleanup = cleanup;
}

View file

@ -0,0 +1,306 @@
//
// Created by Bradley Austin Davis on 2015/08/29
// 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
//
map = function(value, min1, max1, min2, max2) {
return min2 + (max2 - min2) * ((value - min1) / (max1 - min1));
}
vec3toStr = function(v, digits) {
if (!digits) { digits = 3; }
return "{ " + v.x.toFixed(digits) + ", " + v.y.toFixed(digits) + ", " + v.z.toFixed(digits)+ " }";
}
quatToStr = function(q, digits) {
if (!digits) { digits = 3; }
return "{ " + q.w.toFixed(digits) + ", " + q.x.toFixed(digits) + ", " +
q.y.toFixed(digits) + ", " + q.z.toFixed(digits)+ " }";
}
vec3equal = function(v0, v1) {
return (v0.x == v1.x) && (v0.y == v1.y) && (v0.z == v1.z);
}
colorMix = function(colorA, colorB, mix) {
var result = {};
for (var key in colorA) {
result[key] = (colorA[key] * (1 - mix)) + (colorB[key] * mix);
}
return result;
}
scaleLine = function (start, end, scale) {
var v = Vec3.subtract(end, start);
var length = Vec3.length(v);
v = Vec3.multiply(scale, v);
return Vec3.sum(start, v);
}
findAction = function(name) {
return Controller.findAction(name);
}
addLine = function(origin, vector, color) {
if (!color) {
color = COLORS.WHITE
}
return Entities.addEntity(mergeObjects(LINE_PROTOTYPE, {
position: origin,
linePoints: [
ZERO_VECTOR,
vector,
],
color: color
}));
}
// FIXME fetch from a subkey of user data to support non-destructive modifications
setEntityUserData = function(id, data) {
var json = JSON.stringify(data)
Entities.editEntity(id, { userData: json });
}
// FIXME do non-destructive modification of the existing user data
getEntityUserData = function(id) {
var results = null;
var properties = Entities.getEntityProperties(id, "userData");
if (properties.userData) {
try {
results = JSON.parse(properties.userData);
} catch(err) {
logDebug(err);
logDebug(properties.userData);
}
}
return results ? results : {};
}
// Non-destructively modify the user data of an entity.
setEntityCustomData = function(customKey, id, data) {
var userData = getEntityUserData(id);
if (data == null) {
delete userData[customKey];
} else {
userData[customKey] = data;
}
setEntityUserData(id, userData);
}
getEntityCustomData = function(customKey, id, defaultValue) {
var userData = getEntityUserData(id);
if (undefined != userData[customKey]) {
return userData[customKey];
} else {
return defaultValue;
}
}
mergeObjects = function(proto, custom) {
var result = {};
for (var attrname in proto) {
result[attrname] = proto[attrname];
}
for (var attrname in custom) {
result[attrname] = custom[attrname];
}
return result;
}
LOG_WARN = 1;
logWarn = function(str) {
if (LOG_WARN) {
print(str);
}
}
LOG_ERROR = 1;
logError = function(str) {
if (LOG_ERROR) {
print(str);
}
}
LOG_INFO = 1;
logInfo = function(str) {
if (LOG_INFO) {
print(str);
}
}
LOG_DEBUG = 0;
logDebug = function(str) {
if (LOG_DEBUG) {
print(str);
}
}
LOG_TRACE = 0;
logTrace = function(str) {
if (LOG_TRACE) {
print(str);
}
}
// Computes the penetration between a point and a sphere (centered at the origin)
// if point is inside sphere: returns true and stores the result in 'penetration'
// (the vector that would move the point outside the sphere)
// otherwise returns false
findSphereHit = function(point, sphereRadius) {
var EPSILON = 0.000001; //smallish positive number - used as margin of error for some computations
var vectorLength = Vec3.length(point);
if (vectorLength < EPSILON) {
return true;
}
var distance = vectorLength - sphereRadius;
if (distance < 0.0) {
return true;
}
return false;
}
findSpherePointHit = function(sphereCenter, sphereRadius, point) {
return findSphereHit(Vec3.subtract(point,sphereCenter), sphereRadius);
}
findSphereSphereHit = function(firstCenter, firstRadius, secondCenter, secondRadius) {
return findSpherePointHit(firstCenter, firstRadius + secondRadius, secondCenter);
}
// Given a vec3 v, return a vec3 that is the same vector relative to the avatars
// DEFAULT eye position, rotated into the avatars reference frame.
getEyeRelativePosition = function(v) {
return Vec3.sum(MyAvatar.getDefaultEyePosition(), Vec3.multiplyQbyV(MyAvatar.orientation, v));
}
getAvatarRelativeRotation = function(q) {
return Quat.multiply(MyAvatar.orientation, q);
}
pointInExtents = function(point, minPoint, maxPoint) {
return (point.x >= minPoint.x && point.x <= maxPoint.x) &&
(point.y >= minPoint.y && point.y <= maxPoint.y) &&
(point.z >= minPoint.z && point.z <= maxPoint.z);
}
/**
* Converts an HSL color value to RGB. Conversion formula
* adapted from http://en.wikipedia.org/wiki/HSL_color_space.
* Assumes h, s, and l are contained in the set [0, 1] and
* returns r, g, and b in the set [0, 255].
*
* @param Number h The hue
* @param Number s The saturation
* @param Number l The lightness
* @return Array The RGB representation
*/
hslToRgb = function(hsl) {
var r, g, b;
if (hsl.s == 0) {
r = g = b = hsl.l; // achromatic
} else {
var hue2rgb = function hue2rgb(p, q, t) {
if (t < 0) t += 1;
if (t > 1) t -= 1;
if (t < 1 / 6) return p + (q - p) * 6 * t;
if (t < 1 / 2) return q;
if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;
return p;
}
var q = hsl.l < 0.5 ? hsl.l * (1 + hsl.s) : hsl.l + hsl.s - hsl.l * hsl.s;
var p = 2 * hsl.l - q;
r = hue2rgb(p, q, hsl.h + 1 / 3);
g = hue2rgb(p, q, hsl.h);
b = hue2rgb(p, q, hsl.h - 1 / 3);
}
return {
red: Math.round(r * 255),
green: Math.round(g * 255),
blue: Math.round(b * 255)
};
}
orientationOf = function(vector) {
var Y_AXIS = {
x: 0,
y: 1,
z: 0
};
var X_AXIS = {
x: 1,
y: 0,
z: 0
};
var theta = 0.0;
var RAD_TO_DEG = 180.0 / Math.PI;
var direction, yaw, pitch;
direction = Vec3.normalize(vector);
yaw = Quat.angleAxis(Math.atan2(direction.x, direction.z) * RAD_TO_DEG, Y_AXIS);
pitch = Quat.angleAxis(Math.asin(-direction.y) * RAD_TO_DEG, X_AXIS);
return Quat.multiply(yaw, pitch);
}
randFloat = function(low, high) {
return low + Math.random() * (high - low);
}
randInt = function(low, high) {
return Math.floor(randFloat(low, high));
}
hexToRgb = function(hex) {
var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
return result ? {
red: parseInt(result[1], 16),
green: parseInt(result[2], 16),
blue: parseInt(result[3], 16)
} : null;
}
calculateHandSizeRatio = function() {
// Get the ratio of the current avatar's hand to Owen's hand
var standardCenterHandPoint = 0.11288;
var jointNames = MyAvatar.getJointNames();
//get distance from handJoint up to leftHandIndex3 as a proxy for center of hand
var wristToFingertipDistance = 0;;
for (var i = 0; i < jointNames.length; i++) {
var jointName = jointNames[i];
print(jointName)
if (jointName.indexOf("LeftHandIndex") !== -1) {
// translations are relative to parent joint, so simply add them together
// joints face down the y-axis
var translation = MyAvatar.getDefaultJointTranslation(i).y;
wristToFingertipDistance += translation;
}
}
// Right now units are in cm, so convert to meters
wristToFingertipDistance /= 100;
var centerHandPoint = wristToFingertipDistance/2;
// Compare against standard hand (Owen)
var handSizeRatio = centerHandPoint/standardCenterHandPoint;
return handSizeRatio;
}
clamp = function(val, min, max){
return Math.max(min, Math.min(max, val))
}

View file

@ -0,0 +1,109 @@
//
// eraserEntityScript.js
// examples/homeContent/eraserEntityScript
//
// Created by Eric Levin on 2/17/15.
// Copyright 2016 High Fidelity, Inc.
//
// This entity script provides logic for an object with attached script to erase nearby marker strokes
// 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('../utils.js');
var TRIGGER_CONTROLS = [
Controller.Standard.LT,
Controller.Standard.RT,
];
var _this;
Eraser = function() {
_this = this;
_this.ERASER_TRIGGER_THRESHOLD = 0.2;
_this.STROKE_NAME = "hifi-marker-stroke";
_this.ERASER_TO_STROKE_SEARCH_RADIUS = 0.7;
_this.ERASER_RESET_WAIT_TIME = 3000;
};
Eraser.prototype = {
startEquip: function(id, params) {
_this.equipped = true;
_this.hand = params[0] == "left" ? 0 : 1;
// We really only need to grab position of marker strokes once, and then just check to see if eraser comes near enough to those strokes
Overlays.editOverlay(_this.searchSphere, {
visible: true
});
},
continueEquip: function() {
_this.eraserPosition = Entities.getEntityProperties(_this.entityID, "position").position;
Overlays.editOverlay(_this.searchSphere, {
position: _this.eraserPosition
});
this.triggerValue = Controller.getValue(TRIGGER_CONTROLS[_this.hand]);
if (_this.triggerValue > _this.ERASER_TRIGGER_THRESHOLD) {
_this.continueHolding();
}
},
continueHolding: function() {
var strokeIDs = Entities.findEntities(_this.eraserPosition, _this.ERASER_TO_STROKE_SEARCH_RADIUS);
// Create a map of stroke entities and their positions
strokeIDs.forEach(function(strokeID) {
var strokeProps = Entities.getEntityProperties(strokeID, ["position", "name"]);
if (strokeProps.name === _this.STROKE_NAME && Vec3.distance(_this.eraserPosition, strokeProps.position) < _this.ERASER_TO_STROKE_SEARCH_RADIUS) {
Entities.deleteEntity(strokeID);
}
});
},
releaseEquip: function() {
Overlays.editOverlay(_this.searchSphere, {
visible: false
});
// Once user releases eraser, wait a bit then put marker back to its original position and rotation
Script.setTimeout(function() {
var userData = getEntityUserData(_this.entityID);
Entities.editEntity(_this.entityID, {
position: userData.originalPosition,
rotation: userData.originalRotation,
velocity: {
x: 0,
y: -0.01,
z: 0
}
});
}, _this.ERASER_RESET_WAIT_TIME);
},
preload: function(entityID) {
_this.entityID = entityID;
_this.searchSphere = Overlays.addOverlay('sphere', {
size: _this.ERASER_TO_STROKE_SEARCH_RADIUS,
color: {
red: 200,
green: 10,
blue: 10
},
alpha: 0.2,
solid: true,
visible: false
})
},
unload: function() {
Overlays.deleteOverlay(_this.searchSphere);
}
};
// entity scripts always need to return a newly constructed object of our type
return new Eraser();
});

View file

@ -0,0 +1,229 @@
//
// markerTipEntityScript.js
// examples/homeContent/markerTipEntityScript
//
// Created by Eric Levin on 2/17/15.
// Copyright 2016 High Fidelity, Inc.
//
// This script provides the logic for an object to draw marker strokes on its associated whiteboard
// 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('../utils.js');
var TRIGGER_CONTROLS = [
Controller.Standard.LT,
Controller.Standard.RT,
];
var MAX_POINTS_PER_STROKE = 40;
var _this;
MarkerTip = function() {
_this = this;
_this.MARKER_TEXTURE_URL = "https://s3-us-west-1.amazonaws.com/hifi-content/eric/textures/markerStroke.png";
_this.strokeForwardOffset = 0.0001;
_this.STROKE_WIDTH_RANGE = {
min: 0.002,
max: 0.01
};
_this.MAX_MARKER_TO_BOARD_DISTANCE = 1.4;
_this.MIN_DISTANCE_BETWEEN_POINTS = 0.002;
_this.MAX_DISTANCE_BETWEEN_POINTS = 0.1;
_this.strokes = [];
_this.PAINTING_TRIGGER_THRESHOLD = 0.2;
_this.STROKE_NAME = "hifi-marker-stroke";
_this.WHITEBOARD_SURFACE_NAME = "hifi-whiteboardDrawingSurface";
_this.MARKER_RESET_WAIT_TIME = 3000;
};
MarkerTip.prototype = {
startEquip: function(id, params) {
print('start equip')
_this.whiteboards = [];
_this.equipped = true;
_this.hand = params[0] == "left" ? 0 : 1;
print('before thing', id)
print('GET user data?' + typeof getEntityUserData)
_this.markerColor = getEntityUserData(_this.entityID).markerColor;
print('after thing')
// search for whiteboards
var markerPosition = Entities.getEntityProperties(_this.entityID, "position").position;
var entities = Entities.findEntities(markerPosition, 10);
print('LOOKING FOR BOARDS')
entities.forEach(function(entity) {
var entityName = Entities.getEntityProperties(entity, "name").name;
print('NAME ' + entityName)
if (entityName === _this.WHITEBOARD_SURFACE_NAME) {
print('FOUND A WHITEBOARD!!')
_this.whiteboards.push(entity);
}
});
print("intersectable entities " + JSON.stringify(_this.whiteboards))
},
releaseEquip: function() {
_this.resetStroke();
Overlays.editOverlay(_this.laserPointer, {
visible: false
});
// Once user releases marker, wait a bit then put marker back to its original position and rotation
Script.setTimeout(function() {
var userData = getEntityUserData(_this.entityID);
Entities.editEntity(_this.entityID, {
position: userData.originalPosition,
rotation: userData.originalRotation,
velocity: {
x: 0,
y: -0.01,
z: 0
}
});
}, _this.MARKER_RESET_WAIT_TIME);
},
continueEquip: function() {
// cast a ray from marker and see if it hits anything
var markerProps = Entities.getEntityProperties(_this.entityID, ["position", "rotation"]);
var pickRay = {
origin: markerProps.position,
direction: Quat.getFront(markerProps.rotation)
}
var intersection = Entities.findRayIntersectionBlocking(pickRay, true, _this.whiteboards);
if (intersection.intersects && Vec3.distance(intersection.intersection, markerProps.position) < _this.MAX_MARKER_TO_BOARD_DISTANCE) {
_this.currentWhiteboard = intersection.entityID;
var whiteboardRotation = Entities.getEntityProperties(_this.currentWhiteboard, "rotation").rotation;
_this.whiteboardNormal = Quat.getFront(whiteboardRotation);
Overlays.editOverlay(_this.laserPointer, {
visible: true,
position: intersection.intersection,
rotation: whiteboardRotation
})
_this.triggerValue = Controller.getValue(TRIGGER_CONTROLS[_this.hand]);
if (_this.triggerValue > _this.PAINTING_TRIGGER_THRESHOLD) {
_this.paint(intersection.intersection)
} else {
_this.resetStroke();
}
} else {
if (_this.currentStroke) {
_this.resetStroke();
}
Overlays.editOverlay(_this.laserPointer, {
visible: false
});
}
},
newStroke: function(position) {
_this.strokeBasePosition = position;
_this.currentStroke = Entities.addEntity({
type: "PolyLine",
name: _this.STROKE_NAME,
dimensions: {
x: 10,
y: 10,
z: 10
},
position: position,
textures: _this.MARKER_TEXTURE_URL,
color: _this.markerColor,
lifetime: 5000,
});
_this.linePoints = [];
_this.normals = [];
_this.strokes.push(_this.currentStroke);
},
paint: function(position) {
var basePosition = position;
if (!_this.currentStroke) {
if (_this.oldPosition) {
basePosition = _this.oldPosition;
}
_this.newStroke(basePosition);
}
var localPoint = Vec3.subtract(basePosition, _this.strokeBasePosition);
localPoint = Vec3.sum(localPoint, Vec3.multiply(_this.whiteboardNormal, _this.strokeForwardOffset));
if (_this.linePoints.length > 0) {
var distance = Vec3.distance(localPoint, _this.linePoints[_this.linePoints.length - 1]);
if (distance < _this.MIN_DISTANCE_BETWEEN_POINTS) {
return;
}
}
_this.linePoints.push(localPoint);
_this.normals.push(_this.whiteboardNormal);
var strokeWidths = [];
for (var i = 0; i < _this.linePoints.length; i++) {
// Create a temp array of stroke widths for calligraphy effect - start and end should be less wide
var pointsFromCenter = Math.abs(_this.linePoints.length / 2 - i);
var pointWidth = map(pointsFromCenter, 0, this.linePoints.length / 2, _this.STROKE_WIDTH_RANGE.max, this.STROKE_WIDTH_RANGE.min);
strokeWidths.push(pointWidth);
}
Entities.editEntity(_this.currentStroke, {
linePoints: _this.linePoints,
normals: _this.normals,
strokeWidths: strokeWidths
});
if (_this.linePoints.length > MAX_POINTS_PER_STROKE) {
Entities.editEntity(_this.currentStroke, {
parentID: _this.currentWhiteboard
});
_this.currentStroke = null;
_this.oldPosition = position;
}
},
resetStroke: function() {
Entities.editEntity(_this.currentStroke, {
parentID: _this.currentWhiteboard
});
_this.currentStroke = null;
_this.oldPosition = null;
},
preload: function(entityID) {
this.entityID = entityID;
_this.laserPointer = Overlays.addOverlay("circle3d", {
color: {
red: 220,
green: 35,
blue: 53
},
solid: true,
size: 0.01,
});
},
unload: function() {
Overlays.deleteOverlay(_this.laserPointer);
_this.strokes.forEach(function(stroke) {
Entities.deleteEntity(stroke);
});
}
};
// entity scripts always need to return a newly constructed object of our type
return new MarkerTip();
});

View file

@ -0,0 +1,257 @@
//
// whiteboardSpawner.js
// examples/homeContent/whiteboardV2
//
// Created by Eric Levina on 2/17/16
// Copyright 2016 High Fidelity, Inc.
//
// Run this script to spawn a whiteboard, markers, and an eraser.
// To draw on the whiteboard, equip a marker and hold down trigger with marker tip pointed at whiteboard
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
var ERASER_SCRIPT_URL = Script.resolvePath("eraserEntityScript.js?" + Math.random());
var MARKER_SCRIPT_URL = Script.resolvePath("markerEntityScript.js?" + Math.random());
Whiteboard = function(spawnPosition, spawnRotation) {
var orientation = MyAvatar.orientation;
orientation = Quat.safeEulerAngles(orientation);
var markerRotation = Quat.fromVec3Degrees({
x: orientation.x + 10,
y: orientation.y - 90,
z: orientation.z
})
orientation.x = 0;
var whiteboardRotation = Quat.fromVec3Degrees({
x: 0,
y: orientation.y,
z: 0
});
orientation = Quat.fromVec3Degrees(orientation);
var markers = [];
var whiteboardPosition = Vec3.sum(MyAvatar.position, Vec3.multiply(2, Quat.getFront(orientation)));
var WHITEBOARD_MODEL_URL = "https://s3-us-west-1.amazonaws.com/hifi-content/eric/models/Whiteboard-4.fbx";
var WHITEBOARD_COLLISION_HULL_URL = "https://s3-us-west-1.amazonaws.com/hifi-content/eric/models/whiteboardCollisionHull.obj";
var whiteboard = Entities.addEntity({
type: "Model",
name: "whiteboard",
modelURL: WHITEBOARD_MODEL_URL,
position: whiteboardPosition,
rotation: whiteboardRotation,
shapeType: 'compound',
compoundShapeURL: WHITEBOARD_COLLISION_HULL_URL,
dimensions: {
x: 1.86,
y: 2.7,
z: 0.4636
},
});
print('whiteboard:' + whiteboard)
var whiteboardSurfacePosition = Vec3.sum(whiteboardPosition, {
x: 0.0,
y: 0.45,
z: 0.0
});
whiteboardSurfacePosition = Vec3.sum(whiteboardSurfacePosition, Vec3.multiply(-0.02, Quat.getRight(whiteboardRotation)));
var moveForwardDistance = 0.02;
whiteboardFrontSurfacePosition = Vec3.sum(whiteboardSurfacePosition, Vec3.multiply(-moveForwardDistance, Quat.getFront(whiteboardRotation)));
var whiteboardSurfaceSettings = {
type: "Box",
name: "hifi-whiteboardDrawingSurface",
dimensions: {
x: 1.82,
y: 1.8,
z: 0.01
},
color: {
red: 200,
green: 10,
blue: 200
},
position: whiteboardFrontSurfacePosition,
rotation: whiteboardRotation,
visible: false,
parentID: whiteboard
}
var whiteboardFrontDrawingSurface = Entities.addEntity(whiteboardSurfaceSettings);
whiteboardBackSurfacePosition = Vec3.sum(whiteboardSurfacePosition, Vec3.multiply(moveForwardDistance, Quat.getFront(whiteboardRotation)));
whiteboardSurfaceSettings.position = whiteboardBackSurfacePosition;
var whiteboardBackDrawingSurface = Entities.addEntity(whiteboardSurfaceSettings);
var WHITEBOARD_RACK_DEPTH = 1.9;
var ERASER_MODEL_URL = "http://hifi-content.s3.amazonaws.com/alan/dev/eraser-2.fbx";
var eraserPosition = Vec3.sum(MyAvatar.position, Vec3.multiply(WHITEBOARD_RACK_DEPTH, Quat.getFront(whiteboardRotation)));
eraserPosition = Vec3.sum(eraserPosition, Vec3.multiply(-0.5, Quat.getRight(whiteboardRotation)));
var eraserRotation = markerRotation;
var eraser = Entities.addEntity({
type: "Model",
modelURL: ERASER_MODEL_URL,
position: eraserPosition,
script: ERASER_SCRIPT_URL,
shapeType: "box",
dimensions: {
x: 0.0858,
y: 0.0393,
z: 0.2083
},
rotation: eraserRotation,
dynamic: true,
gravity: {
x: 0,
y: -1,
z: 0
},
velocity: {
x: 0,
y: -0.1,
z: 0
},
userData: JSON.stringify({
originalPosition: eraserPosition,
originalRotation: eraserRotation,
wearable: {
joints: {
RightHand: [{
x: 0.020,
y: 0.120,
z: 0.049
}, {
x: 0.1004,
y: 0.6424,
z: 0.717,
w: 0.250
}],
LeftHand: [{
x: -0.005,
y: 0.1101,
z: 0.053
}, {
x: 0.723,
y: 0.289,
z: 0.142,
w: 0.610
}]
}
}
})
});
createMarkers();
function createMarkers() {
var modelURLS = [
"https://s3-us-west-1.amazonaws.com/hifi-content/eric/models/marker-blue.fbx",
"https://s3-us-west-1.amazonaws.com/hifi-content/eric/models/marker-red.fbx",
"https://s3-us-west-1.amazonaws.com/hifi-content/eric/models/marker-black.fbx",
];
var markerPosition = Vec3.sum(MyAvatar.position, Vec3.multiply(WHITEBOARD_RACK_DEPTH, Quat.getFront(orientation)));
createMarker(modelURLS[0], markerPosition, {
red: 10,
green: 10,
blue: 200
});
markerPosition = Vec3.sum(markerPosition, Vec3.multiply(-0.2, Quat.getFront(markerRotation)));
createMarker(modelURLS[1], markerPosition, {
red: 200,
green: 10,
blue: 10
});
markerPosition = Vec3.sum(markerPosition, Vec3.multiply(0.4, Quat.getFront(markerRotation)));
createMarker(modelURLS[2], markerPosition, {
red: 10,
green: 10,
blue: 10
});
}
function createMarker(modelURL, markerPosition, markerColor) {
var marker = Entities.addEntity({
type: "Model",
modelURL: modelURL,
rotation: markerRotation,
shapeType: "box",
name: "marker",
dynamic: true,
gravity: {
x: 0,
y: -1,
z: 0
},
velocity: {
x: 0,
y: -0.1,
z: 0
},
position: markerPosition,
dimensions: {
x: 0.027,
y: 0.027,
z: 0.164
},
name: "marker",
script: MARKER_SCRIPT_URL,
userData: JSON.stringify({
originalPosition: markerPosition,
originalRotation: markerRotation,
markerColor: markerColor,
wearable: {
joints: {
RightHand: [{
x: 0.001,
y: 0.139,
z: 0.050
}, {
x: -0.73,
y: -0.043,
z: -0.108,
w: -0.666
}],
LeftHand: [{
x: 0.007,
y: 0.151,
z: 0.061
}, {
x: -0.417,
y: 0.631,
z: -0.389,
w: -0.525
}]
}
}
})
});
markers.push(marker);
}
function cleanup() {
Entities.deleteEntity(whiteboard);
Entities.deleteEntity(whiteboardFrontDrawingSurface);
Entities.deleteEntity(whiteboardBackDrawingSurface);
Entities.deleteEntity(eraser);
markers.forEach(function(marker) {
Entities.deleteEntity(marker);
});
}
this.cleanup = cleanup;
}