overte-thingvellir/examples/particle_explorer/particleExplorer.js
2015-09-29 17:01:10 -07:00

239 lines
No EOL
6.7 KiB
JavaScript

//
// particleExplorer.js
//
//
// Created by James B. Pollack @imgntnon 9/26/2015
// Copyright 2014 High Fidelity, Inc.
//
// Interface side of the App.
// Quickly edit the aesthetics of a particle system. This is an example of a new, easy way to do two way bindings between dynamically created GUI and in-world entities.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
// todo: folders, color pickers, animation settings, scale gui width with window resizing
//
/*global print, WebWindow, MyAvatar, Entities, AnimationCache, SoundCache, Scene, Camera, Overlays, HMD, AvatarList, AvatarManager, Controller, UndoStack, Window, Account, GlobalServices, Script, ScriptDiscoveryService, LODManager, Menu, Vec3, Quat, AudioDevice, Paths, Clipboard, Settings, XMLHttpRequest, randFloat, randInt */
var box,
sphere,
sphereDimensions = {
x: 0.4,
y: 0.8,
z: 0.2
},
pointDimensions = {
x: 0.0,
y: 0.0,
z: 0.0
},
sphereOrientation = Quat.fromPitchYawRollDegrees(-60.0, 30.0, 0.0),
verticalOrientation = Quat.fromPitchYawRollDegrees(-90.0, 0.0, 0.0),
particles,
particleExample = -1,
PARTICLE_RADIUS = 0.04,
SLOW_EMIT_RATE = 2.0,
HALF_EMIT_RATE = 50.0,
FAST_EMIT_RATE = 100.0,
SLOW_EMIT_SPEED = 0.025,
FAST_EMIT_SPEED = 1.0,
GRAVITY_EMIT_ACCELERATON = {
x: 0.0,
y: -0.3,
z: 0.0
},
ZERO_EMIT_ACCELERATON = {
x: 0.0,
y: 0.0,
z: 0.0
},
PI = 3.141593,
DEG_TO_RAD = PI / 180.0,
NUM_PARTICLE_EXAMPLES = 18;
var particleProperties;
function setUp() {
var boxPoint,
spawnPoint,
animation = {
fps: 30,
frameIndex: 0,
running: true,
firstFrame: 0,
lastFrame: 30,
loop: true
};
boxPoint = Vec3.sum(MyAvatar.position, Vec3.multiply(4.0, Quat.getFront(Camera.getOrientation())));
boxPoint = Vec3.sum(boxPoint, {
x: 0.0,
y: -0.5,
z: 0.0
});
spawnPoint = Vec3.sum(boxPoint, {
x: 0.0,
y: 1.0,
z: 0.0
});
box = Entities.addEntity({
type: "Box",
name: "ParticlesTest Box",
position: boxPoint,
rotation: verticalOrientation,
dimensions: {
x: 0.3,
y: 0.3,
z: 0.3
},
color: {
red: 128,
green: 128,
blue: 128
},
lifetime: 3600, // 1 hour; just in case
visible: true
});
// Same size and orientation as emitter when ellipsoid.
sphere = Entities.addEntity({
type: "Sphere",
name: "ParticlesTest Sphere",
position: boxPoint,
rotation: sphereOrientation,
dimensions: sphereDimensions,
color: {
red: 128,
green: 128,
blue: 128
},
lifetime: 3600, // 1 hour; just in case
visible: false
});
// 1.0m above the box or ellipsoid.
particles = Entities.addEntity({
type: "ParticleEffect",
name: "ParticlesTest Emitter",
position: spawnPoint,
emitOrientation: verticalOrientation,
particleRadius: PARTICLE_RADIUS,
radiusSpread: 0.0,
emitRate: SLOW_EMIT_RATE,
emitSpeed: FAST_EMIT_SPEED,
speedSpread: 0.0,
emitAcceleration: GRAVITY_EMIT_ACCELERATON,
accelerationSpread: {
x: 0.0,
y: 0.0,
z: 0.0
},
textures: "https://hifi-public.s3.amazonaws.com/alan/Particles/Particle-Sprite-Smoke-1.png",
color: {
red: 255,
green: 255,
blue: 255
},
lifespan: 5.0,
visible: false,
locked: false,
animationSettings: animation,
animationIsPlaying:true,
lifetime: 3600 // 1 hour; just in case
});
}
SettingsWindow = function() {
var _this = this;
this.webWindow = null;
this.init = function() {
_this.webWindow = new WebWindow('genericProperties', Script.resolvePath('index.html'), 400, 600, true);
_this.webWindow.setVisible(true);
_this.webWindow.eventBridge.webEventReceived.connect(_this.onWebEventReceived);
Script.update.connect(waitForObjectAuthorization);
};
this.sendData = function(data) {
// print('sending data' + JSON.stringify(data));
_this.webWindow.eventBridge.emitScriptEvent(JSON.stringify(data));
};
this.onWebEventReceived = function(data) {
// print('DATA ' + data)
var _data = JSON.parse(data);
if (_data.messageType === 'page_loaded') {
print('PAGE LOADED UPDATE FROM GUI');
_this.pageLoaded = true;
sendInitialSettings(particleProperties);
}
if (_data.messageType === 'settings_update') {
print('SETTINGS UPDATE FROM GUI ' + JSON.stringify(_data.updatedSettings));
editEntity(_data.updatedSettings);
return;
}
};
};
function waitForObjectAuthorization() {
var properties = Entities.getEntityProperties(particles, "isKnownID");
var isKnownID = properties.isKnownID;
if (isKnownID === false || SettingsWindow.pageLoaded === false) {
return;
}
var currentProperties = Entities.getEntityProperties(particles);
particleProperties = currentProperties;
// Script.update.connect(sendObjectUpdates);
Script.update.disconnect(waitForObjectAuthorization);
}
function sendObjectUpdates() {
var currentProperties = Entities.getEntityProperties(particles);
sendUpdatedObject(currentProperties);
}
function sendInitialSettings(properties) {
print('SENDING INITIAL INTERFACE SETTINGS');
var settings = {
messageType: 'initial_settings',
initialSettings: properties
};
settingsWindow.sendData(settings);
}
function sendUpdatedObject(properties) {
// print('SENDING UPDATED OBJECT FROM INTERFACE');
var settings = {
messageType: 'object_update',
objectSettings: properties
};
settingsWindow.sendData(settings);
}
function editEntity(properties) {
Entities.editEntity(particles, properties);
var currentProperties = Entities.getEntityProperties(particles);
// settingsWindow.sendData({
// messageType: 'settings_update',
// updatedSettings: currentProperties
// });
}
function tearDown() {
Entities.deleteEntity(particles);
Entities.deleteEntity(box);
Entities.deleteEntity(sphere);
// Script.update.disconnect(sendObjectUpdates);
}
var settingsWindow = new SettingsWindow();
settingsWindow.init();
setUp();
Script.scriptEnding.connect(tearDown);