mirror of
https://github.com/overte-org/overte.git
synced 2025-08-10 09:29:02 +02:00
entity script reset
This commit is contained in:
parent
169cd70a8c
commit
2c8f13b538
15 changed files with 1923 additions and 870 deletions
35
unpublishedScripts/DomainContent/Home/createTidyGuy.js
Normal file
35
unpublishedScripts/DomainContent/Home/createTidyGuy.js
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
//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-4.fbx',
|
||||||
|
dimensions: {
|
||||||
|
x: 0.32,
|
||||||
|
y: 0.96,
|
||||||
|
z: 0.6844
|
||||||
|
},
|
||||||
|
position: center,
|
||||||
|
// color:{
|
||||||
|
// red:0,
|
||||||
|
// green:255,
|
||||||
|
// blue:0
|
||||||
|
// },
|
||||||
|
script: SCRIPT_URL
|
||||||
|
}
|
||||||
|
|
||||||
|
return Entities.addEntity(properties);
|
||||||
|
}
|
||||||
|
|
||||||
|
var tidyGuy = createTidyGuy();
|
||||||
|
|
||||||
|
Script.scriptEnding.connect(function() {
|
||||||
|
Entities.deleteEntity(tidyGuy);
|
||||||
|
})
|
|
@ -1,452 +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, 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 center = Vec3.sum(MyAvatar.position, Vec3.multiply(Quat.getFront(MyAvatar.orientation), 1 * TANK_WIDTH));
|
|
||||||
|
|
||||||
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.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
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
455
unpublishedScripts/DomainContent/Home/fishTank/wrapper.js
Normal file
455
unpublishedScripts/DomainContent/Home/fishTank/wrapper.js
Normal file
|
@ -0,0 +1,455 @@
|
||||||
|
//
|
||||||
|
// 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
|
||||||
|
//
|
||||||
|
|
||||||
|
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_SCRIPT = Script.resolvePath('fishTank/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.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;
|
||||||
|
}
|
|
@ -15,7 +15,8 @@
|
||||||
Script.include('../../../../libraries/utils.js');
|
Script.include('../../../../libraries/utils.js');
|
||||||
|
|
||||||
var _this;
|
var _this;
|
||||||
GrowingPlant = function() {
|
|
||||||
|
function GrowingPlant() {
|
||||||
_this = this;
|
_this = this;
|
||||||
_this.flowers = [];
|
_this.flowers = [];
|
||||||
// _this.STARTING_FLOWER_DIMENSIONS = {x: 0.1, y: 0.001, z: 0.1}
|
// _this.STARTING_FLOWER_DIMENSIONS = {x: 0.1, y: 0.001, z: 0.1}
|
||||||
|
@ -49,8 +50,6 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
GrowingPlant.prototype = {
|
GrowingPlant.prototype = {
|
||||||
|
|
||||||
|
|
||||||
continueWatering: function(entityID, data) {
|
continueWatering: function(entityID, data) {
|
||||||
// we're being watered- every now and then spawn a new flower to add to our growing list
|
// 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
|
// If we don't have any flowers yet, immediately grow one
|
||||||
|
@ -78,8 +77,12 @@
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var xzGrowthRate = randFloat(0.00006, 0.00016);
|
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 = {
|
var flower = {
|
||||||
dimensions: {
|
dimensions: {
|
||||||
x: _this.STARTING_FLOWER_DIMENSIONS.x,
|
x: _this.STARTING_FLOWER_DIMENSIONS.x,
|
||||||
|
@ -99,7 +102,7 @@
|
||||||
// saturation: 0.92,
|
// saturation: 0.92,
|
||||||
// light: 0.41
|
// 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
|
growthRate: growthRate
|
||||||
};
|
};
|
||||||
flower.userData = {
|
flower.userData = {
|
|
@ -15,7 +15,7 @@
|
||||||
Script.include('../../../../libraries/utils.js');
|
Script.include('../../../../libraries/utils.js');
|
||||||
|
|
||||||
var _this;
|
var _this;
|
||||||
WaterSpout = function() {
|
function WaterSpout() {
|
||||||
_this = this;
|
_this = this;
|
||||||
_this.waterSound = SoundCache.getSound("https://s3-us-west-1.amazonaws.com/hifi-content/eric/Sounds/shower.wav");
|
_this.waterSound = SoundCache.getSound("https://s3-us-west-1.amazonaws.com/hifi-content/eric/Sounds/shower.wav");
|
||||||
_this.POUR_ANGLE_THRESHOLD = 0;
|
_this.POUR_ANGLE_THRESHOLD = 0;
|
142
unpublishedScripts/DomainContent/Home/growingPlant/wrapper.js
Normal file
142
unpublishedScripts/DomainContent/Home/growingPlant/wrapper.js
Normal file
|
@ -0,0 +1,142 @@
|
||||||
|
//
|
||||||
|
// 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
|
||||||
|
|
||||||
|
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 PLANT_SCRIPT_URL = Script.resolvePath("growingPlant/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("growingPlant/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);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.cleanup = cleanup;
|
||||||
|
|
||||||
|
}
|
|
@ -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);
|
|
107
unpublishedScripts/DomainContent/Home/reset.js
Normal file
107
unpublishedScripts/DomainContent/Home/reset.js
Normal file
|
@ -0,0 +1,107 @@
|
||||||
|
//
|
||||||
|
// 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() {
|
||||||
|
|
||||||
|
},
|
||||||
|
unload: function() {
|
||||||
|
|
||||||
|
},
|
||||||
|
tidying: false,
|
||||||
|
showTidyingButton: function() {
|
||||||
|
|
||||||
|
},
|
||||||
|
showTidyButton: function() {
|
||||||
|
|
||||||
|
},
|
||||||
|
toggleButton: function() {
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
clickReleaseOnEntity: function(entityID, mouseEvent) {
|
||||||
|
if (!mouseEvent.isLeftButton) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_this.prepareScene();
|
||||||
|
print('CLICK ON TIDY GUY!!!')
|
||||||
|
|
||||||
|
},
|
||||||
|
prepareScene: function() {
|
||||||
|
_this.cleanupDynamicEntities();
|
||||||
|
_this.createDynamicEntities();
|
||||||
|
},
|
||||||
|
startNearTrigger: function() {
|
||||||
|
_this.prepareScene();
|
||||||
|
},
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
print('DYNAMIC ENTITIES:: ' + JSON.stringify(dynamicEntities))
|
||||||
|
dynamicEntities.forEach(function(dynamicEntity) {
|
||||||
|
dynamicEntity.cleanup();
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
}
|
||||||
|
return new Reset();
|
||||||
|
});
|
|
@ -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);
|
|
||||||
});
|
|
||||||
};
|
|
275
unpublishedScripts/DomainContent/Home/tiltMaze/wrapper.js
Normal file
275
unpublishedScripts/DomainContent/Home/tiltMaze/wrapper.js
Normal file
|
@ -0,0 +1,275 @@
|
||||||
|
//
|
||||||
|
// 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
|
||||||
|
//
|
||||||
|
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 MAZE_SCRIPT = Script.resolvePath('tiltMaze/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 = 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;
|
||||||
|
|
||||||
|
}
|
306
unpublishedScripts/DomainContent/Home/utils.js
Normal file
306
unpublishedScripts/DomainContent/Home/utils.js
Normal 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))
|
||||||
|
}
|
||||||
|
|
|
@ -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();
|
||||||
|
});
|
|
@ -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();
|
||||||
|
});
|
255
unpublishedScripts/DomainContent/Home/whiteboard/wrapper.js
Normal file
255
unpublishedScripts/DomainContent/Home/whiteboard/wrapper.js
Normal file
|
@ -0,0 +1,255 @@
|
||||||
|
//
|
||||||
|
// 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
|
||||||
|
|
||||||
|
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 ERASER_SCRIPT_URL = Script.resolvePath("whiteboard/eraserEntityScript.js?" + Math.random());
|
||||||
|
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_SCRIPT_URL = Script.resolvePath("whiteboard/markerEntityScript.js?" + Math.random());
|
||||||
|
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;
|
||||||
|
}
|
Loading…
Reference in a new issue