From 3b92910a9174d9f39421f7770aaa885f6ecec32f Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Wed, 1 Apr 2015 12:22:35 -0700 Subject: [PATCH 1/3] Adding the cookies sciprt that provide a simple ui useful for debug and exemple, complete the interface on the scene script interface to provide the getters --- examples/example/misc/sunLightExample.js | 97 +++++++++++++++---- interface/src/Application.cpp | 5 +- libraries/model/src/model/Stage.cpp | 4 +- .../src/SceneScriptingInterface.cpp | 27 ++++++ .../src/SceneScriptingInterface.h | 9 ++ libraries/script-engine/src/ScriptEngine.cpp | 3 - 6 files changed, 118 insertions(+), 27 deletions(-) diff --git a/examples/example/misc/sunLightExample.js b/examples/example/misc/sunLightExample.js index 42837c6836..e6c06bb1ae 100644 --- a/examples/example/misc/sunLightExample.js +++ b/examples/example/misc/sunLightExample.js @@ -8,27 +8,82 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -var intensity = 1.0; -var day = 0.0; -var hour = 12.0; -var longitude = 115.0; -var latitude = 31.0; -var stageOrientation = Quat.fromPitchYawRollDegrees(0.0, 180.0, 0.0); +Script.include("../../utilities/tools/cookies.js"); -Scene.setStageDayTime(hour); -Scene.setStageOrientation(stageOrientation); -Scene.setStageLocation(longitude, latitude, 0.0); -/* -function ticktack() { - hour += 0.1; - //Scene.setSunIntensity(Math.cos(time)); - if (hour > 24.0) { - hour = 0.0; - day++; - Scene.setStageYearTime(day); +var panel = new Panel(10, 400); + +panel.newSlider("Origin Longitude", -180, 180, + function(value) { Scene.setStageLocation(value, Scene.getStageLocationLatitude(), Scene.getStageLocationAltitude()); }, + function() { return Scene.getStageLocationLongitude(); }, + function(value) { return value.toFixed(0) + " deg"; } +); + +panel.newSlider("Origin Latitude", -90, 90, + function(value) { Scene.setStageLocation(Scene.getStageLocationLongitude(), value, Scene.getStageLocationAltitude()); }, + function() { return Scene.getStageLocationLatitude(); }, + function(value) { return value.toFixed(0) + " deg"; } +); + +panel.newSlider("Origin Altitude", 0, 1000, + function(value) { Scene.setStageLocation(Scene.getStageLocationLongitude(), Scene.getStageLocationLatitude(), value); }, + function() { return Scene.getStageLocationAltitude(); }, + function(value) { return (value).toFixed(0) + " km"; } +); + +panel.newSlider("Year Time", 0, 364, + function(value) { Scene.setStageYearTime(value); }, + function() { return Scene.getStageYearTime(); }, + function(value) { + var numDaysPerMonth = 365.0 / 12.0; + var monthly = (value / numDaysPerMonth); + var month = Math.floor(monthly); + return (month + 1).toFixed(0) + "/" + Math.ceil(0.5 + (monthly - month)*Math.ceil(numDaysPerMonth)).toFixed(0); } +); + +panel.newSlider("Day Time", 0, 24, + function(value) { Scene.setStageDayTime(value); }, + function() { return Scene.getStageDayTime(); }, + function(value) { + var hour = Math.floor(value); + return (hour).toFixed(0) + ":" + ((value - hour)*60.0).toFixed(0); } - Scene.setStageDayTime(hour); -} +); -Script.setInterval(ticktack, 41); -*/ \ No newline at end of file +var tickTackPeriod = 50; +var tickTackSpeed = 0.0; +panel.newSlider("Tick tack time", -1.0, 1.0, + function(value) { tickTackSpeed = value; }, + function() { return tickTackSpeed; }, + function(value) { return (value).toFixed(2); } +); + +function runStageTime() { + if (tickTackSpeed != 0.0) { + var hour = panel.get("Day Time"); + hour += tickTackSpeed; + panel.set("Day Time", hour); + + if (hour >= 24.0) { + panel.set("Year Time", panel.get("Year Time") + 1); + } else if (hour < 0.0) { + panel.set("Year Time", panel.get("Year Time") - 1); + } + } +} +Script.setInterval(runStageTime, tickTackPeriod); + +panel.newSlider("Light Intensity", 0.0, 5, + function(value) { Scene.setSunIntensity(value); }, + function() { return Scene.getSunIntensity(); }, + function(value) { return (value).toFixed(2); } +); + +Controller.mouseMoveEvent.connect(function panelMouseMoveEvent(event) { return panel.mouseMoveEvent(event); }); +Controller.mousePressEvent.connect( function panelMousePressEvent(event) { return panel.mousePressEvent(event); }); +Controller.mouseReleaseEvent.connect(function(event) { return panel.mouseReleaseEvent(event); }); + +function scriptEnding() { + Menu.removeMenu("Developer > Scene"); + panel.destroy(); +} +Script.scriptEnding.connect(scriptEnding); diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 7bab72ff0d..8aecd34f79 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -256,7 +256,8 @@ bool setupEssentials(int& argc, char** argv) { auto speechRecognizer = DependencyManager::set(); #endif auto discoverabilityManager = DependencyManager::set(); - + auto sceneScriptingInterface = DependencyManager::set(); + return true; } @@ -3586,6 +3587,8 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEngine* scri scriptEngine->registerFunction(hmdInterface, "getHUDLookAtPosition2D", HMDScriptingInterface::getHUDLookAtPosition2D, 0); scriptEngine->registerFunction(hmdInterface, "getHUDLookAtPosition3D", HMDScriptingInterface::getHUDLookAtPosition3D, 0); + scriptEngine->registerGlobalObject("Scene", DependencyManager::get().data()); + #ifdef HAVE_RTMIDI scriptEngine->registerGlobalObject("MIDI", &MIDIManager::getInstance()); #endif diff --git a/libraries/model/src/model/Stage.cpp b/libraries/model/src/model/Stage.cpp index 1c171eee76..096ec273eb 100644 --- a/libraries/model/src/model/Stage.cpp +++ b/libraries/model/src/model/Stage.cpp @@ -92,8 +92,8 @@ void EarthSunModel::setSurfaceOrientation(const Quat& orientation) { double moduloRange(double val, double minVal, double maxVal) { double range = maxVal - minVal; double rval = (val - minVal) / range; - double intval; - return modf(rval, &intval) * range + minVal; + rval = rval - floor(rval); + return rval * range + minVal; } const float MAX_LONGITUDE = 180.0f; diff --git a/libraries/script-engine/src/SceneScriptingInterface.cpp b/libraries/script-engine/src/SceneScriptingInterface.cpp index 9cac521225..855701f536 100644 --- a/libraries/script-engine/src/SceneScriptingInterface.cpp +++ b/libraries/script-engine/src/SceneScriptingInterface.cpp @@ -20,20 +20,47 @@ void SceneScriptingInterface::setStageLocation(float longitude, float latitude, _skyStage->setOriginLocation(longitude, latitude, altitude); } +float SceneScriptingInterface::getStageLocationLongitude() const { + return _skyStage->getOriginLongitude(); +} +float SceneScriptingInterface::getStageLocationLatitude() const { + return _skyStage->getOriginLatitude(); +} +float SceneScriptingInterface::getStageLocationAltitude() const { + return _skyStage->getOriginSurfaceAltitude(); +} + void SceneScriptingInterface::setStageDayTime(float hour) { _skyStage->setDayTime(hour); } + +float SceneScriptingInterface::getStageDayTime() const { + return _skyStage->getDayTime(); +} + void SceneScriptingInterface::setStageYearTime(int day) { _skyStage->setYearTime(day); } +int SceneScriptingInterface::getStageYearTime() const { + return _skyStage->getYearTime(); +} + void SceneScriptingInterface::setSunColor(const glm::vec3& color) { _skyStage->setSunColor(color); } + +const glm::vec3& SceneScriptingInterface::getSunColor() const { + return _skyStage->getSunColor(); +} + void SceneScriptingInterface::setSunIntensity(float intensity) { _skyStage->setSunIntensity(intensity); } +float SceneScriptingInterface::getSunIntensity() const { + return _skyStage->getSunIntensity(); +} model::SunSkyStagePointer SceneScriptingInterface::getSkyStage() const { return _skyStage; diff --git a/libraries/script-engine/src/SceneScriptingInterface.h b/libraries/script-engine/src/SceneScriptingInterface.h index 8ae9424c95..0c36b303e9 100644 --- a/libraries/script-engine/src/SceneScriptingInterface.h +++ b/libraries/script-engine/src/SceneScriptingInterface.h @@ -24,12 +24,21 @@ class SceneScriptingInterface : public QObject, public Dependency { public: Q_INVOKABLE void setStageOrientation(const glm::quat& orientation); + Q_INVOKABLE void setStageLocation(float longitude, float latitude, float altitude); + Q_INVOKABLE float getStageLocationLongitude() const; + Q_INVOKABLE float getStageLocationLatitude() const; + Q_INVOKABLE float getStageLocationAltitude() const; + Q_INVOKABLE void setStageDayTime(float hour); + Q_INVOKABLE float getStageDayTime() const; Q_INVOKABLE void setStageYearTime(int day); + Q_INVOKABLE int getStageYearTime() const; Q_INVOKABLE void setSunColor(const glm::vec3& color); + Q_INVOKABLE const glm::vec3& getSunColor() const; Q_INVOKABLE void setSunIntensity(float intensity); + Q_INVOKABLE float getSunIntensity() const; model::SunSkyStagePointer getSkyStage() const; diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index c31f5be46a..390b889579 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -305,8 +305,6 @@ void ScriptEngine::init() { _isInitialized = true; - auto sceneScriptingInterface = DependencyManager::set(); - auto entityScriptingInterface = DependencyManager::get(); entityScriptingInterface->init(); @@ -350,7 +348,6 @@ void ScriptEngine::init() { registerGlobalObject("Vec3", &_vec3Library); registerGlobalObject("Uuid", &_uuidLibrary); registerGlobalObject("AnimationCache", DependencyManager::get().data()); - registerGlobalObject("Scene", DependencyManager::get().data()); // constants globalObject().setProperty("TREE_SCALE", newVariant(QVariant(TREE_SCALE))); From 695a5bcfd7551d8bd1d554e18b61eb273ad87a34 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Wed, 1 Apr 2015 12:23:31 -0700 Subject: [PATCH 2/3] Adding the cookies sciprt that provide a simple ui useful for debug and example, complete the interface on the scene script interface to provide the getters --- examples/utilities/tools/cookies.js | 278 ++++++++++++++++++++++++++++ 1 file changed, 278 insertions(+) create mode 100755 examples/utilities/tools/cookies.js diff --git a/examples/utilities/tools/cookies.js b/examples/utilities/tools/cookies.js new file mode 100755 index 0000000000..541f3b16f9 --- /dev/null +++ b/examples/utilities/tools/cookies.js @@ -0,0 +1,278 @@ +// +// cookies.js +// +// version 1.0 +// +// Created by Sam Gateau, 4/1/2015 +// A simple ui panel that present a list of porperties and the proper widget to edit it +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +// The Slider class +Slider = function(x,y,width,thumbSize) { + + this.thumb = Overlays.addOverlay("text", { + backgroundColor: { red: 255, green: 255, blue: 255 }, + x: x, + y: y, + width: thumbSize, + height: thumbSize, + alpha: 1.0, + backgroundAlpha: 1.0, + visible: true + }); + this.background = Overlays.addOverlay("text", { + backgroundColor: { red: 125, green: 125, blue: 255 }, + x: x, + y: y, + width: width, + height: thumbSize, + alpha: 1.0, + backgroundAlpha: 0.5, + visible: true + }); + + this.thumbSize = thumbSize; + this.thumbHalfSize = 0.5 * thumbSize; + + this.minThumbX = x + this.thumbHalfSize; + this.maxThumbX = x + width - this.thumbHalfSize; + this.thumbX = this.minThumbX; + + this.minValue = 0.0; + this.maxValue = 1.0; + + this.clickOffsetX = 0; + this.isMoving = false; + + this.updateThumb = function() { + thumbTruePos = this.thumbX - 0.5 * this.thumbSize; + Overlays.editOverlay(this.thumb, { x: thumbTruePos } ); + }; + + this.onMouseMoveEvent = function(event) { + if (this.isMoving) { + newThumbX = event.x - this.clickOffsetX; + if (newThumbX < this.minThumbX) { + newThumbX = this.minThumbX; + } + if (newThumbX > this.maxThumbX) { + newThumbX = this.maxThumbX; + } + this.thumbX = newThumbX; + this.updateThumb(); + this.onValueChanged(this.getValue()); + } + }; + + this.onMousePressEvent = function(event) { + this.isMoving = true; + var clickOffset = event.x - this.thumbX; + if ((clickOffset > -this.thumbHalfSize) && (clickOffset < this.thumbHalfSize)) { + this.clickOffsetX = clickOffset; + } else { + this.clickOffsetX = 0; + this.thumbX = event.x; + this.updateThumb(); + this.onValueChanged(this.getValue()); + } + + }; + + this.onMouseReleaseEvent = function(event) { + this.isMoving = false; + }; + + // Public members: + + this.setNormalizedValue = function(value) { + if (value < 0.0) { + this.thumbX = this.minThumbX; + } else if (value > 1.0) { + this.thumbX = this.maxThumbX; + } else { + this.thumbX = value * (this.maxThumbX - this.minThumbX) + this.minThumbX; + } + this.updateThumb(); + }; + this.getNormalizedValue = function() { + return (this.thumbX - this.minThumbX) / (this.maxThumbX - this.minThumbX); + }; + + this.setValue = function(value) { + var normValue = (value - this.minValue) / (this.maxValue - this.minValue); + this.setNormalizedValue(normValue); + }; + + this.getValue = function() { + return this.getNormalizedValue() * (this.maxValue - this.minValue) + this.minValue; + }; + + this.onValueChanged = function(value) {}; + + this.destroy = function() { + Overlays.deleteOverlay(this.background); + Overlays.deleteOverlay(this.thumb); + }; +} + + +var textFontSize = 16; + +function PanelItem(name, setter, getter, displayer, x, y, textWidth, valueWidth, height) { + this.name = name; + + + this.displayer = typeof displayer !== 'undefined' ? displayer : function(value) { return value.toFixed(2); }; + + var topMargin = (height - textFontSize); + this.title = Overlays.addOverlay("text", { + backgroundColor: { red: 255, green: 255, blue: 255 }, + x: x, + y: y, + width: textWidth, + height: height, + alpha: 1.0, + backgroundAlpha: 0.5, + visible: true, + text: name, + font: {size: textFontSize}, + topMargin: topMargin, + }); + + this.value = Overlays.addOverlay("text", { + backgroundColor: { red: 255, green: 255, blue: 255 }, + x: x + textWidth, + y: y, + width: valueWidth, + height: height, + alpha: 1.0, + backgroundAlpha: 0.5, + visible: true, + text: this.displayer(getter()), + font: {size: textFontSize}, + topMargin: topMargin + + }); + this.getter = getter; + + this.setter = function(value) { + setter(value); + Overlays.editOverlay(this.value, {text: this.displayer(getter())}); + if (this.widget) { + this.widget.setValue(value); + } + }; + this.setterFromWidget = function(value) { + setter(value); + Overlays.editOverlay(this.value, {text: this.displayer(getter())}); + }; + + + this.widget = null; + + this.destroy = function() { + Overlays.deleteOverlay(this.title); + Overlays.deleteOverlay(this.value); + if (this.widget != null) { + this.widget.destroy(); + } + } +} + +var textWidth = 180; +var valueWidth = 100; +var widgetWidth = 300; +var rawHeight = 20; +var rawYDelta = rawHeight * 1.5; + +Panel = function(x, y) { + + this.x = x; + this.y = y; + this.nextY = y; + + this.widgetX = x + textWidth + valueWidth; + + this.items = new Array(); + this.activeWidget = null; + + this.mouseMoveEvent = function(event) { + if (this.activeWidget) { + this.activeWidget.onMouseMoveEvent(event); + } + }; + + // we also handle click detection in our mousePressEvent() + this.mousePressEvent = function(event) { + // Make sure we quitted previous widget + if (this.activeWidget) { + this.activeWidget.onMouseReleaseEvent(event); + } + this.activeWidget = null; + + var clickedOverlay = Overlays.getOverlayAtPoint({x: event.x, y: event.y}); + + // If the user clicked any of the slider background then... + for (i in this.items) { + widget = this.items[i].widget; + + if (clickedOverlay == widget.background) { + this.activeWidget = widget; + this.activeWidget.onMousePressEvent(event); + // print("clicked... widget=" + i); + break; + } + } + }; + + this.mouseReleaseEvent = function(event) { + if (this.activeWidget) { + this.activeWidget.onMouseReleaseEvent(event); + } + this.activeWidget = null; + }; + + this.newSlider = function(name, minValue, maxValue, setValue, getValue, displayValue) { + + var sliderItem = new PanelItem(name, setValue, getValue, displayValue, this.x, this.nextY, textWidth, valueWidth, rawHeight); + + var slider = new Slider(this.widgetX, this.nextY, widgetWidth, rawHeight); + slider.minValue = minValue; + slider.maxValue = maxValue; + slider.onValueChanged = function(value) { sliderItem.setterFromWidget(value); }; + + + sliderItem.widget = slider; + sliderItem.setter(getValue()); + this.items[name] = sliderItem; + this.nextY += rawYDelta; + // print("created Item... slider=" + name); + }; + + this.destroy = function() { + for (i in this.items) { + this.items[i].destroy(); + } + } + + this.set = function(name, value) { + var item = this.items[name]; + if (item != null) { + return item.setter(value); + } + return null; + } + + this.get = function(name) { + var item = this.items[name]; + if (item != null) { + return item.getter(); + } + return null; + } +}; + + From 9918357724b887fbc11b8b52832b0fdbd19f04ab Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Wed, 1 Apr 2015 13:37:41 -0700 Subject: [PATCH 3/3] fix var declaration issues --- examples/utilities/tools/cookies.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/utilities/tools/cookies.js b/examples/utilities/tools/cookies.js index 541f3b16f9..205b19c9f9 100755 --- a/examples/utilities/tools/cookies.js +++ b/examples/utilities/tools/cookies.js @@ -216,8 +216,8 @@ Panel = function(x, y) { var clickedOverlay = Overlays.getOverlayAtPoint({x: event.x, y: event.y}); // If the user clicked any of the slider background then... - for (i in this.items) { - widget = this.items[i].widget; + for (var i in this.items) { + var widget = this.items[i].widget; if (clickedOverlay == widget.background) { this.activeWidget = widget; @@ -253,7 +253,7 @@ Panel = function(x, y) { }; this.destroy = function() { - for (i in this.items) { + for (var i in this.items) { this.items[i].destroy(); } }