// // particleExplorerTool.js // // Created by Eric Levin on 2/15/16 // Copyright 2016 High Fidelity, Inc. // Adds particleExplorer tool to the edit panel when a user selects a particle entity from the edit tool window // 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 // /* global ParticleExplorerTool */ var PARTICLE_EXPLORER_HTML_URL = Script.resolvePath('particleExplorer.html'); ParticleExplorerTool = function(createToolsWindow) { var that = {}; that.activeParticleEntity = 0; that.updatedActiveParticleProperties = {}; that.createWebView = function() { that.webView = Tablet.getTablet("com.highfidelity.interface.tablet.system"); that.webView.setVisible = function(value) {}; that.webView.webEventReceived.connect(that.webEventReceived); createToolsWindow.webEventReceived.addListener(this, that.webEventReceived); }; function emitScriptEvent(data) { var messageData = JSON.stringify(data); that.webView.emitScriptEvent(messageData); createToolsWindow.emitScriptEvent(messageData); } that.destroyWebView = function() { if (!that.webView) { return; } that.activeParticleEntity = 0; that.updatedActiveParticleProperties = {}; emitScriptEvent({ messageType: "particle_close" }); }; function sendParticleProperties(properties) { emitScriptEvent({ messageType: "particle_settings", currentProperties: properties }); } function sendActiveParticleProperties() { var properties = Entities.getEntityProperties(that.activeParticleEntity); if (properties.emitOrientation) { properties.emitOrientation = Quat.safeEulerAngles(properties.emitOrientation); } // Update uninitialized variables if (isNaN(properties.alphaStart)) { properties.alphaStart = properties.alpha; } if (isNaN(properties.alphaFinish)) { properties.alphaFinish = properties.alpha; } if (isNaN(properties.radiusStart)) { properties.radiusStart = properties.particleRadius; } if (isNaN(properties.radiusFinish)) { properties.radiusFinish = properties.particleRadius; } if (isNaN(properties.colorStart.red)) { properties.colorStart = properties.color; } if (isNaN(properties.colorFinish.red)) { properties.colorFinish = properties.color; } if (isNaN(properties.spinStart)) { properties.spinStart = properties.particleSpin; } if (isNaN(properties.spinFinish)) { properties.spinFinish = properties.particleSpin; } sendParticleProperties(properties); } function sendUpdatedActiveParticleProperties() { sendParticleProperties(that.updatedActiveParticleProperties); that.updatedActiveParticleProperties = {}; } that.webEventReceived = function(message) { var data = JSON.parse(message); if (data.messageType === "settings_update") { var updatedSettings = data.updatedSettings; var optionalProps = ["alphaStart", "alphaFinish", "radiusStart", "radiusFinish", "colorStart", "colorFinish", "spinStart", "spinFinish"]; var fallbackProps = ["alpha", "particleRadius", "color", "particleSpin"]; for (var i = 0; i < optionalProps.length; i++) { var fallbackProp = fallbackProps[Math.floor(i / 2)]; var optionalValue = updatedSettings[optionalProps[i]]; var fallbackValue = updatedSettings[fallbackProp]; if (optionalValue && fallbackValue) { delete updatedSettings[optionalProps[i]]; } } if (updatedSettings.emitOrientation) { updatedSettings.emitOrientation = Quat.fromVec3Degrees(updatedSettings.emitOrientation); } Entities.editEntity(that.activeParticleEntity, updatedSettings); var entityProps = Entities.getEntityProperties(that.activeParticleEntity, optionalProps); var needsUpdate = false; for (var i = 0; i < optionalProps.length; i++) { var fallbackProp = fallbackProps[Math.floor(i / 2)]; var fallbackValue = updatedSettings[fallbackProp]; if (fallbackValue) { var optionalProp = optionalProps[i]; if ((fallbackProp !== "color" && isNaN(entityProps[optionalProp])) || (fallbackProp === "color" && isNaN(entityProps[optionalProp].red))) { that.updatedActiveParticleProperties[optionalProp] = fallbackValue; needsUpdate = true; } } } if (needsUpdate) { sendUpdatedActiveParticleProperties(); } } else if (data.messageType === "page_loaded") { sendActiveParticleProperties(); } }; that.setActiveParticleEntity = function(id) { that.activeParticleEntity = id; sendActiveParticleProperties(); }; return that; };