From 143a315f1d1ee4a8bc5ded4add1c89744d8745e7 Mon Sep 17 00:00:00 2001 From: Olivier Prat Date: Tue, 20 Mar 2018 15:29:50 -0700 Subject: [PATCH 1/9] Fade edited objects are now selected with ray picking --- .../scripting/SelectionScriptingInterface.cpp | 22 ++++- .../scripting/SelectionScriptingInterface.h | 27 ++++- libraries/render-utils/src/FadeEffectJobs.cpp | 99 ++++++++----------- libraries/render-utils/src/FadeEffectJobs.h | 1 - .../utilities/render/debugTransition.js | 50 +++++++++- 5 files changed, 137 insertions(+), 62 deletions(-) diff --git a/interface/src/scripting/SelectionScriptingInterface.cpp b/interface/src/scripting/SelectionScriptingInterface.cpp index 233e61c8ae..f8a62e848c 100644 --- a/interface/src/scripting/SelectionScriptingInterface.cpp +++ b/interface/src/scripting/SelectionScriptingInterface.cpp @@ -110,7 +110,6 @@ bool SelectionScriptingInterface::enableListHighlight(const QString& listName, c } if (!(*highlightStyle).isBoundToList()) { - setupHandler(listName); (*highlightStyle).setBoundToList(true); } @@ -172,6 +171,18 @@ render::HighlightStyle SelectionScriptingInterface::getHighlightStyle(const QStr } } +bool SelectionScriptingInterface::enableListToScene(const QString& listName) { + setupHandler(listName); + + return true; +} + +bool SelectionScriptingInterface::disableListToScene(const QString& listName) { + removeHandler(listName); + + return true; +} + template bool SelectionScriptingInterface::addToGameplayObjects(const QString& listName, T idToAdd) { { QWriteLocker lock(&_selectionListsLock); @@ -303,6 +314,15 @@ void SelectionScriptingInterface::setupHandler(const QString& selectionName) { (*handler)->initialize(selectionName); } +void SelectionScriptingInterface::removeHandler(const QString& selectionName) { + QWriteLocker lock(&_selectionHandlersLock); + auto handler = _handlerMap.find(selectionName); + if (handler != _handlerMap.end()) { + delete handler.value(); + _handlerMap.erase(handler); + } +} + void SelectionScriptingInterface::onSelectedItemsListChanged(const QString& listName) { { QWriteLocker lock(&_selectionHandlersLock); diff --git a/interface/src/scripting/SelectionScriptingInterface.h b/interface/src/scripting/SelectionScriptingInterface.h index 8295375870..3046ac371e 100644 --- a/interface/src/scripting/SelectionScriptingInterface.h +++ b/interface/src/scripting/SelectionScriptingInterface.h @@ -160,13 +160,14 @@ public: * If the Selection doesn't exist, it will be created. * All objects in the list will be displayed with the highlight effect as specified from the highlightStyle. * The function can be called several times with different values in the style to modify it. - * + * * @function Selection.enableListHighlight * @param listName {string} name of the selection * @param highlightStyle {jsObject} highlight style fields (see Selection.getListHighlightStyle for a detailed description of the highlightStyle). * @returns {bool} true if the selection was successfully enabled for highlight. */ Q_INVOKABLE bool enableListHighlight(const QString& listName, const QVariantMap& highlightStyle); + /**jsdoc * Disable highlighting for the named selection. * If the Selection doesn't exist or wasn't enabled for highliting then nothing happens simply returning false. @@ -175,7 +176,27 @@ public: * @param listName {string} name of the selection * @returns {bool} true if the selection was successfully disabled for highlight, false otherwise. */ - Q_INVOKABLE bool disableListHighlight(const QString& listName); + Q_INVOKABLE bool disableListHighlight(const QString& listName); + /**jsdoc + * Enable scene selection for the named selection. + * If the Selection doesn't exist, it will be created. + * All objects in the list will be sent to a scene selection. + * + * @function Selection.enableListToScene + * @param listName {string} name of the selection + * @returns {bool} true if the selection was successfully enabled on the scene. + */ + Q_INVOKABLE bool enableListToScene(const QString& listName); + /**jsdoc + * Disable scene selection for the named selection. + * If the Selection doesn't exist or wasn't enabled on the scene then nothing happens simply returning false. + * + * @function Selection.disableListToScene + * @param listName {string} name of the selection + * @returns {bool} true if the selection was successfully disabled on the scene, false otherwise. + */ + Q_INVOKABLE bool disableListToScene(const QString& listName); + /**jsdoc * Query the highlight style values for the named selection. * If the Selection doesn't exist or hasn't been highlight enabled yet, it will return an empty object. @@ -223,7 +244,7 @@ private: template bool removeFromGameplayObjects(const QString& listName, T idToRemove); void setupHandler(const QString& selectionName); - + void removeHandler(const QString& selectionName); }; diff --git a/libraries/render-utils/src/FadeEffectJobs.cpp b/libraries/render-utils/src/FadeEffectJobs.cpp index da3f8dddc0..e6de306c6d 100644 --- a/libraries/render-utils/src/FadeEffectJobs.cpp +++ b/libraries/render-utils/src/FadeEffectJobs.cpp @@ -39,43 +39,52 @@ void FadeEditJob::run(const render::RenderContextPointer& renderContext, const F auto scene = renderContext->_scene; if (_isEditEnabled) { - float minIsectDistance = std::numeric_limits::max(); - auto& itemBounds = inputs.get0(); - auto editedItem = findNearestItem(renderContext, itemBounds, minIsectDistance); - render::Transaction transaction; - bool hasTransaction{ false }; + static const std::string selectionName("TransitionEdit"); + auto scene = renderContext->_scene; + if (!scene->isSelectionEmpty(selectionName)) { + auto selection = scene->getSelection(selectionName); + auto editedItem = selection.getItems().front(); + render::Transaction transaction; + bool hasTransaction{ false }; - if (editedItem != _editedItem && render::Item::isValidID(_editedItem)) { - // Remove transition from previously edited item as we've changed edited item - hasTransaction = true; + if (editedItem != _editedItem && render::Item::isValidID(_editedItem)) { + // Remove transition from previously edited item as we've changed edited item + hasTransaction = true; + transaction.removeTransitionFromItem(_editedItem); + } + _editedItem = editedItem; + + if (render::Item::isValidID(_editedItem)) { + static const render::Transition::Type categoryToTransition[FADE_CATEGORY_COUNT] = { + render::Transition::ELEMENT_ENTER_DOMAIN, + render::Transition::BUBBLE_ISECT_OWNER, + render::Transition::BUBBLE_ISECT_TRESPASSER, + render::Transition::USER_ENTER_DOMAIN, + render::Transition::AVATAR_CHANGE + }; + + auto transitionType = categoryToTransition[inputs.get1()]; + + transaction.queryTransitionOnItem(_editedItem, [transitionType, scene](render::ItemID id, const render::Transition* transition) { + if (transition == nullptr || transition->isFinished || transition->eventType != transitionType) { + // Relaunch transition + render::Transaction transaction; + transaction.addTransitionToItem(id, transitionType); + scene->enqueueTransaction(transaction); + } + }); + hasTransaction = true; + } + + if (hasTransaction) { + scene->enqueueTransaction(transaction); + } + } else if (render::Item::isValidID(_editedItem)) { + // Remove transition from previously edited item as we've disabled fade edition + render::Transaction transaction; transaction.removeTransitionFromItem(_editedItem); - } - _editedItem = editedItem; - - if (render::Item::isValidID(_editedItem)) { - static const render::Transition::Type categoryToTransition[FADE_CATEGORY_COUNT] = { - render::Transition::ELEMENT_ENTER_DOMAIN, - render::Transition::BUBBLE_ISECT_OWNER, - render::Transition::BUBBLE_ISECT_TRESPASSER, - render::Transition::USER_ENTER_DOMAIN, - render::Transition::AVATAR_CHANGE - }; - - auto transitionType = categoryToTransition[inputs.get1()]; - - transaction.queryTransitionOnItem(_editedItem, [transitionType, scene](render::ItemID id, const render::Transition* transition) { - if (transition == nullptr || transition->isFinished || transition->eventType!=transitionType) { - // Relaunch transition - render::Transaction transaction; - transaction.addTransitionToItem(id, transitionType); - scene->enqueueTransaction(transaction); - } - }); - hasTransaction = true; - } - - if (hasTransaction) { scene->enqueueTransaction(transaction); + _editedItem = render::Item::INVALID_ITEM_ID; } } else if (render::Item::isValidID(_editedItem)) { @@ -87,28 +96,6 @@ void FadeEditJob::run(const render::RenderContextPointer& renderContext, const F } } -render::ItemID FadeEditJob::findNearestItem(const render::RenderContextPointer& renderContext, const render::ItemBounds& inputs, float& minIsectDistance) const { - const glm::vec3 rayOrigin = renderContext->args->getViewFrustum().getPosition(); - const glm::vec3 rayDirection = renderContext->args->getViewFrustum().getDirection(); - BoxFace face; - glm::vec3 normal; - float isectDistance; - render::ItemID nearestItem = render::Item::INVALID_ITEM_ID; - const float minDistance = 1.f; - const float maxDistance = 50.f; - - for (const auto& itemBound : inputs) { - if (!itemBound.bound.contains(rayOrigin) && itemBound.bound.findRayIntersection(rayOrigin, rayDirection, isectDistance, face, normal)) { - auto& item = renderContext->_scene->getItem(itemBound.id); - if (item.getKey().isWorldSpace() && isectDistance>minDistance && isectDistance < minIsectDistance && isectDistance Date: Tue, 20 Mar 2018 17:48:41 -0700 Subject: [PATCH 2/9] Proposal to improve fade editing with some extra visual cues --- libraries/render-utils/src/FadeEffectJobs.cpp | 2 +- .../utilities/render/debugTransition.js | 80 ++++++++++++++++++- .../developer/utilities/render/transition.qml | 5 +- 3 files changed, 83 insertions(+), 4 deletions(-) diff --git a/libraries/render-utils/src/FadeEffectJobs.cpp b/libraries/render-utils/src/FadeEffectJobs.cpp index e6de306c6d..a55fb304dd 100644 --- a/libraries/render-utils/src/FadeEffectJobs.cpp +++ b/libraries/render-utils/src/FadeEffectJobs.cpp @@ -581,7 +581,7 @@ void FadeJob::run(const render::RenderContextPointer& renderContext, FadeJob::Ou if (update(*jobConfig, scene, transaction, state, deltaTime)) { hasTransaction = true; } - if (isFirstItem && jobConfig->manualFade && (state.threshold != jobConfig->threshold)) { + if (isFirstItem && (state.threshold != jobConfig->threshold)) { jobConfig->setProperty("threshold", state.threshold); isFirstItem = false; } diff --git a/scripts/developer/utilities/render/debugTransition.js b/scripts/developer/utilities/render/debugTransition.js index 2cb48b7e2a..cef6e84268 100644 --- a/scripts/developer/utilities/render/debugTransition.js +++ b/scripts/developer/utilities/render/debugTransition.js @@ -66,7 +66,81 @@ wireEventBridge(onScreen); } + var isEditEnabled = false + var noiseSphere + var gradientSphere + var selectedEntity + var editedCategory + + var FADE_MIN_SCALE = 0.001 + var FADE_MAX_SCALE = 10000.0 + + function parameterToValuePow(parameter, minValue, maxOverMinValue) { + return minValue * Math.pow(maxOverMinValue, parameter); + //return parameter + } + + function update(dt) { + var gradientProperties = Entities.getEntityProperties(selectedEntity, ["position", "dimensions"]); + if (gradientProperties!=undefined) { + var pos = gradientProperties.position + if (pos!=undefined) { + var config = Render.getConfig("RenderMainView.Fade") + //print("Center at "+pos.x+" "+pos.y+" "+pos.z) + var dim = {x:config.baseSizeX, y:config.baseSizeY, z:config.baseSizeZ} + dim.x = parameterToValuePow(dim.x, FADE_MIN_SCALE, FADE_MAX_SCALE/ FADE_MIN_SCALE) + dim.y = parameterToValuePow(dim.y, FADE_MIN_SCALE, FADE_MAX_SCALE/ FADE_MIN_SCALE) + dim.z = parameterToValuePow(dim.z, FADE_MIN_SCALE, FADE_MAX_SCALE/ FADE_MIN_SCALE) + if (editedCategory==4 || editedCategory==5) { + dim.y = gradientProperties.dimensions.y + pos.y = pos.y - gradientProperties.dimensions.y/2 + } + Overlays.editOverlay(gradientSphere, { position: pos, dimensions: dim, alpha: config.baseLevel }) + dim.x = parameterToValuePow(config.noiseSizeX, FADE_MIN_SCALE, FADE_MAX_SCALE/ FADE_MIN_SCALE) + dim.y = parameterToValuePow(config.noiseSizeY, FADE_MIN_SCALE, FADE_MAX_SCALE/ FADE_MIN_SCALE) + dim.z = parameterToValuePow(config.noiseSizeZ, FADE_MIN_SCALE, FADE_MAX_SCALE/ FADE_MIN_SCALE) + Overlays.editOverlay(noiseSphere, { position: pos, dimensions: dim, alpha: config.noiseLevel }) + } + } + } + + Script.update.connect(update); + function fromQml(message) { + tokens = message.split(' ') + print("Received '"+message+"' from transition.qml") + if (tokens[0]=="edit") { + isEditEnabled = (tokens[1]=="true") + if (isEditEnabled) { + if (gradientSphere==undefined) { + gradientSphere = Overlays.addOverlay("sphere", { + position: MyAvatar.position, + rotation: Quat.fromPitchYawRollDegrees(0.0, 0.0, 0.0), + dimensions: { x: 1.0, y: 1.0, z: 1.0 }, + color: { red: 100, green: 150, blue: 255}, + alpha: 0.2, + solid: false + }); + } + if (noiseSphere==undefined) { + noiseSphere = Overlays.addOverlay("sphere", { + position: MyAvatar.position, + rotation: Quat.fromPitchYawRollDegrees(0.0, 0.0, 0.0), + dimensions: { x: 1.0, y: 1.0, z: 1.0 }, + color: { red: 255, green: 150, blue: 100}, + alpha: 0.2, + solid: false + }); + } + } else if (!isEditEnabled) { + Overlays.deleteOverlay(noiseSphere); + Overlays.deleteOverlay(gradientSphere); + noiseSphere = undefined + gradientSphere = undefined + } + } else if (tokens[0]=="category") { + editedCategory = parseInt(tokens[1]) + } } button.clicked.connect(onClicked); @@ -109,7 +183,6 @@ var currentSelectionName = "" var SelectionList = "TransitionEdit" - var selectedEntity = null Pointers.enablePointer(laser) Selection.enableListToScene(SelectionList) Selection.clearSelectedItemsList(SelectionList) @@ -120,6 +193,7 @@ } selectedEntity = id Selection.addToSelectedItemsList(SelectionList, "entity", selectedEntity) + update() }) function cleanup() { @@ -127,6 +201,8 @@ Pointers.removePointer(ray); Selection.removeListFromMap(SelectionList) Selection.disableListToScene(SelectionList); + Overlays.deleteOverlay(noiseSphere); + Overlays.deleteOverlay(gradientSphere); } - + Script.scriptEnding.connect(cleanup); }()); \ No newline at end of file diff --git a/scripts/developer/utilities/render/transition.qml b/scripts/developer/utilities/render/transition.qml index e83a85f8ed..a8737dfa6b 100644 --- a/scripts/developer/utilities/render/transition.qml +++ b/scripts/developer/utilities/render/transition.qml @@ -22,6 +22,8 @@ Rectangle { id: root anchors.margins: hifi.dimensions.contentMargin.x + signal sendToScript(var message); + color: hifi.colors.baseGray; property var config: Render.getConfig("RenderMainView.Fade"); @@ -48,7 +50,7 @@ Rectangle { checked: root.configEdit["editFade"] onCheckedChanged: { root.configEdit["editFade"] = checked; - Render.getConfig("RenderMainView.DrawFadedOpaqueBounds").enabled = checked; + root.sendToScript("edit "+checked); } } HifiControls.ComboBox { @@ -70,6 +72,7 @@ Rectangle { paramWidgetLoader.sourceComponent = undefined; postpone.interval = 100 postpone.start() + root.sendToScript("category "+currentIndex) } } } From e4416db06fff64863614792d5cf5d4537f46596b Mon Sep 17 00:00:00 2001 From: Olivier Prat Date: Wed, 28 Mar 2018 16:54:53 -0400 Subject: [PATCH 3/9] Added save/file dialog for transition configurations in transition editor --- libraries/render-utils/src/FadeEffectJobs.cpp | 7 +-- libraries/render-utils/src/FadeEffectJobs.h | 4 +- .../utilities/render/debugTransition.js | 48 ++++++++++++++++--- .../developer/utilities/render/transition.qml | 36 ++++++++++---- 4 files changed, 72 insertions(+), 23 deletions(-) diff --git a/libraries/render-utils/src/FadeEffectJobs.cpp b/libraries/render-utils/src/FadeEffectJobs.cpp index a55fb304dd..1e2ea2bc15 100644 --- a/libraries/render-utils/src/FadeEffectJobs.cpp +++ b/libraries/render-utils/src/FadeEffectJobs.cpp @@ -340,11 +340,9 @@ QString FadeConfig::eventNames[FADE_CATEGORY_COUNT] = { "avatar_change", }; -void FadeConfig::save() const { - // Save will only work if the HIFI_USE_SOURCE_TREE_RESOURCES environment variable is set +void FadeConfig::save(const QString& configFilePath) const { assert(editedCategory < FADE_CATEGORY_COUNT); QJsonObject lProperties; - const QString configFilePath = PathUtils::resourcesPath() + "config/" + eventNames[editedCategory] + ".json"; QFile file(configFilePath); if (!file.open(QFile::WriteOnly | QFile::Text)) { qWarning() << "Fade event configuration file " << configFilePath << " cannot be opened"; @@ -369,8 +367,7 @@ void FadeConfig::save() const { } } -void FadeConfig::load() { - const QString configFilePath = PathUtils::resourcesPath() + "config/" + eventNames[editedCategory] + ".json"; +void FadeConfig::load(const QString& configFilePath) { QFile file(configFilePath); if (!file.exists()) { qWarning() << "Fade event configuration file " << configFilePath << " does not exist"; diff --git a/libraries/render-utils/src/FadeEffectJobs.h b/libraries/render-utils/src/FadeEffectJobs.h index f1026b6c2e..449995dba5 100644 --- a/libraries/render-utils/src/FadeEffectJobs.h +++ b/libraries/render-utils/src/FadeEffectJobs.h @@ -160,8 +160,8 @@ public: float manualThreshold{ 0.f }; bool manualFade{ false }; - Q_INVOKABLE void save() const; - Q_INVOKABLE void load(); + Q_INVOKABLE void save(const QString& filePath) const; + Q_INVOKABLE void load(const QString& filePath); static QString eventNames[FADE_CATEGORY_COUNT]; diff --git a/scripts/developer/utilities/render/debugTransition.js b/scripts/developer/utilities/render/debugTransition.js index cef6e84268..27b04bd32b 100644 --- a/scripts/developer/utilities/render/debugTransition.js +++ b/scripts/developer/utilities/render/debugTransition.js @@ -1,5 +1,3 @@ -"use strict"; - // // debugTransition.js // developer/utilities/render @@ -12,12 +10,17 @@ // (function() { + "use strict"; + var TABLET_BUTTON_NAME = "Transition"; var QMLAPP_URL = Script.resolvePath("./transition.qml"); var ICON_URL = Script.resolvePath("../../../system/assets/images/transition-i.svg"); var ACTIVE_ICON_URL = Script.resolvePath("../../../system/assets/images/transition-a.svg"); - + Script.include([ + Script.resolvePath("../../../system/libraries/stringHelpers.js"), + ]); + var onScreen = false; function onClicked() { @@ -106,10 +109,21 @@ Script.update.connect(update); + function loadConfiguration(fileUrl) { + var config = Render.getConfig("RenderMainView.Fade") + config.load(fileUrl) + } + + function saveConfiguration(fileUrl) { + var config = Render.getConfig("RenderMainView.Fade") + config.save(fileUrl) + } + function fromQml(message) { - tokens = message.split(' ') + tokens = message.split('*') print("Received '"+message+"' from transition.qml") - if (tokens[0]=="edit") { + command = tokens[0].toLowerCase() + if (command=="edit") { isEditEnabled = (tokens[1]=="true") if (isEditEnabled) { if (gradientSphere==undefined) { @@ -138,9 +152,28 @@ noiseSphere = undefined gradientSphere = undefined } - } else if (tokens[0]=="category") { + } else if (command=="category") { editedCategory = parseInt(tokens[1]) - } + } else if (command=="save") { + var filePath = tokens[1] + print("Raw token = "+filePath) + if (filePath.startsWith("file:///")) { + filePath = filePath.substr(8) + print("Saving configuration to "+filePath) + saveConfiguration(filePath) + } else { + print("Configurations can only be saved to local files") + } + } else if (command=="load") { + var filePath = tokens[1] + if (filePath.startsWith("file:///")) { + filePath = filePath.substr(8) + print("Loading configuration from "+filePath) + loadConfiguration(filePath) + } else { + print("Configurations can only be loaded from local files") + } + } } button.clicked.connect(onClicked); @@ -172,6 +205,7 @@ color: COLOR2, ignoreRayIntersection: true } + var laser = Pointers.createPointer(PickType.Ray, { joint: "Mouse", filter: Picks.PICK_ENTITIES, diff --git a/scripts/developer/utilities/render/transition.qml b/scripts/developer/utilities/render/transition.qml index a8737dfa6b..564090e2d6 100644 --- a/scripts/developer/utilities/render/transition.qml +++ b/scripts/developer/utilities/render/transition.qml @@ -11,6 +11,7 @@ import QtQuick 2.7 import QtQuick.Controls 1.4 import QtQuick.Layouts 1.3 +import QtQuick.Dialogs 1.0 import "qrc:///qml/styles-uit" import "qrc:///qml/controls-uit" as HifiControls @@ -29,6 +30,24 @@ Rectangle { property var config: Render.getConfig("RenderMainView.Fade"); property var configEdit: Render.getConfig("RenderMainView.FadeEdit"); + FileDialog { + id: fileDialog + title: "Please choose a file" + folder: shortcuts.documents + nameFilters: [ "JSON files (*.json)", "All files (*)" ] + onAccepted: { + root.sendToScript(title.split(" ")[0]+"*"+fileUrl.toString()) + // This is a hack to be sure the widgets below properly reflect the change of category: delete the Component + // by setting the loader source to Null and then recreate it 500ms later + paramWidgetLoader.sourceComponent = undefined; + postpone.interval = 500 + postpone.start() + } + onRejected: { + } + Component.onCompleted: visible = false + } + ColumnLayout { spacing: 3 anchors.left: parent.left @@ -50,7 +69,7 @@ Rectangle { checked: root.configEdit["editFade"] onCheckedChanged: { root.configEdit["editFade"] = checked; - root.sendToScript("edit "+checked); + root.sendToScript("edit*"+checked); } } HifiControls.ComboBox { @@ -72,7 +91,7 @@ Rectangle { paramWidgetLoader.sourceComponent = undefined; postpone.interval = 100 postpone.start() - root.sendToScript("category "+currentIndex) + root.sendToScript("category*"+currentIndex) } } } @@ -107,19 +126,18 @@ Rectangle { id: saveAction text: "Save" onTriggered: { - root.config.save() + fileDialog.title = "Save configuration..." + fileDialog.selectExisting = false + fileDialog.open() } } Action { id: loadAction text: "Load" onTriggered: { - root.config.load() - // This is a hack to be sure the widgets below properly reflect the change of category: delete the Component - // by setting the loader source to Null and then recreate it 500ms later - paramWidgetLoader.sourceComponent = undefined; - postpone.interval = 500 - postpone.start() + fileDialog.title = "Load configuration..." + fileDialog.selectExisting = true + fileDialog.open() } } From 6639a245df244435f87c0093d964646227842ac4 Mon Sep 17 00:00:00 2001 From: Olivier Prat Date: Wed, 28 Mar 2018 18:20:10 -0400 Subject: [PATCH 4/9] Object picking / edition for transitions are activate / deactivated when transition editor window is shown / hidden --- .../utilities/render/debugTransition.js | 133 ++++++++++-------- .../developer/utilities/render/transition.qml | 10 -- 2 files changed, 73 insertions(+), 70 deletions(-) diff --git a/scripts/developer/utilities/render/debugTransition.js b/scripts/developer/utilities/render/debugTransition.js index 27b04bd32b..450b2e3ac9 100644 --- a/scripts/developer/utilities/render/debugTransition.js +++ b/scripts/developer/utilities/render/debugTransition.js @@ -40,6 +40,71 @@ var hasEventBridge = false; + function enableSphereVisualization() { + if (gradientSphere==undefined) { + gradientSphere = Overlays.addOverlay("sphere", { + position: MyAvatar.position, + rotation: Quat.fromPitchYawRollDegrees(0.0, 0.0, 0.0), + dimensions: { x: 1.0, y: 1.0, z: 1.0 }, + color: { red: 100, green: 150, blue: 255}, + alpha: 0.2, + solid: false + }); + } + if (noiseSphere==undefined) { + noiseSphere = Overlays.addOverlay("sphere", { + position: MyAvatar.position, + rotation: Quat.fromPitchYawRollDegrees(0.0, 0.0, 0.0), + dimensions: { x: 1.0, y: 1.0, z: 1.0 }, + color: { red: 255, green: 150, blue: 100}, + alpha: 0.2, + solid: false + }); + } + } + + function disableSphereVisualization() { + Overlays.deleteOverlay(noiseSphere); + Overlays.deleteOverlay(gradientSphere); + noiseSphere = undefined + gradientSphere = undefined + } + + // Create a Laser pointer used to pick and add objects to selections + var END_DIMENSIONS = { x: 0.05, y: 0.05, z: 0.05 }; + var COLOR1 = {red: 255, green: 0, blue: 0}; + var COLOR2 = {red: 0, green: 255, blue: 0}; + var end1 = { + type: "sphere", + dimensions: END_DIMENSIONS, + color: COLOR1, + ignoreRayIntersection: true + } + var end2 = { + type: "sphere", + dimensions: END_DIMENSIONS, + color: COLOR2, + ignoreRayIntersection: true + } + var laser + + function enablePointer() { + laser = Pointers.createPointer(PickType.Ray, { + joint: "Mouse", + filter: Picks.PICK_ENTITIES, + renderStates: [{name: "one", end: end1}], + defaultRenderStates: [{name: "one", end: end2, distance: 2.0}], + enabled: true + }); + Pointers.setRenderState(laser, "one"); + Pointers.enablePointer(laser) + } + + function disablePointer() { + Pointers.disablePointer(laser) + Pointers.removePointer(laser); + } + function wireEventBridge(on) { if (!tablet) { print("Warning in wireEventBridge(): 'tablet' undefined!"); @@ -49,11 +114,15 @@ if (!hasEventBridge) { tablet.fromQml.connect(fromQml); hasEventBridge = true; + enablePointer(); + Render.getConfig("RenderMainView.FadeEdit")["editFade"] = true } } else { if (hasEventBridge) { tablet.fromQml.disconnect(fromQml); hasEventBridge = false; + disablePointer(); + Render.getConfig("RenderMainView.FadeEdit")["editFade"] = false } } } @@ -121,38 +190,9 @@ function fromQml(message) { tokens = message.split('*') - print("Received '"+message+"' from transition.qml") + //print("Received '"+message+"' from transition.qml") command = tokens[0].toLowerCase() - if (command=="edit") { - isEditEnabled = (tokens[1]=="true") - if (isEditEnabled) { - if (gradientSphere==undefined) { - gradientSphere = Overlays.addOverlay("sphere", { - position: MyAvatar.position, - rotation: Quat.fromPitchYawRollDegrees(0.0, 0.0, 0.0), - dimensions: { x: 1.0, y: 1.0, z: 1.0 }, - color: { red: 100, green: 150, blue: 255}, - alpha: 0.2, - solid: false - }); - } - if (noiseSphere==undefined) { - noiseSphere = Overlays.addOverlay("sphere", { - position: MyAvatar.position, - rotation: Quat.fromPitchYawRollDegrees(0.0, 0.0, 0.0), - dimensions: { x: 1.0, y: 1.0, z: 1.0 }, - color: { red: 255, green: 150, blue: 100}, - alpha: 0.2, - solid: false - }); - } - } else if (!isEditEnabled) { - Overlays.deleteOverlay(noiseSphere); - Overlays.deleteOverlay(gradientSphere); - noiseSphere = undefined - gradientSphere = undefined - } - } else if (command=="category") { + if (command=="category") { editedCategory = parseInt(tokens[1]) } else if (command=="save") { var filePath = tokens[1] @@ -189,35 +229,9 @@ }); - // Create a Laser pointer used to pick and add objects to selections - var END_DIMENSIONS = { x: 0.05, y: 0.05, z: 0.05 }; - var COLOR1 = {red: 255, green: 0, blue: 0}; - var COLOR2 = {red: 0, green: 255, blue: 0}; - var end1 = { - type: "sphere", - dimensions: END_DIMENSIONS, - color: COLOR1, - ignoreRayIntersection: true - } - var end2 = { - type: "sphere", - dimensions: END_DIMENSIONS, - color: COLOR2, - ignoreRayIntersection: true - } - - var laser = Pointers.createPointer(PickType.Ray, { - joint: "Mouse", - filter: Picks.PICK_ENTITIES, - renderStates: [{name: "one", end: end1}], - defaultRenderStates: [{name: "one", end: end2, distance: 2.0}], - enabled: true - }); - Pointers.setRenderState(laser, "one"); - var currentSelectionName = "" var SelectionList = "TransitionEdit" - Pointers.enablePointer(laser) + Selection.enableListToScene(SelectionList) Selection.clearSelectedItemsList(SelectionList) @@ -231,8 +245,7 @@ }) function cleanup() { - Pointers.disablePointer(laser) - Pointers.removePointer(ray); + disablePointer(); Selection.removeListFromMap(SelectionList) Selection.disableListToScene(SelectionList); Overlays.deleteOverlay(noiseSphere); diff --git a/scripts/developer/utilities/render/transition.qml b/scripts/developer/utilities/render/transition.qml index 564090e2d6..342b2b533e 100644 --- a/scripts/developer/utilities/render/transition.qml +++ b/scripts/developer/utilities/render/transition.qml @@ -62,16 +62,6 @@ Rectangle { Layout.fillWidth: true id: root_col - HifiControls.CheckBox { - anchors.verticalCenter: parent.verticalCenter - boxSize: 20 - text: "Edit" - checked: root.configEdit["editFade"] - onCheckedChanged: { - root.configEdit["editFade"] = checked; - root.sendToScript("edit*"+checked); - } - } HifiControls.ComboBox { anchors.verticalCenter: parent.verticalCenter Layout.fillWidth: true From 9a7f88cd783315a01c78fc462d93331cacd00c0e Mon Sep 17 00:00:00 2001 From: Olivier Prat Date: Wed, 28 Mar 2018 19:23:09 -0400 Subject: [PATCH 5/9] Moved save / load buttons to top --- .../developer/utilities/render/transition.qml | 28 +++++++++---------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/scripts/developer/utilities/render/transition.qml b/scripts/developer/utilities/render/transition.qml index 342b2b533e..b002de30aa 100644 --- a/scripts/developer/utilities/render/transition.qml +++ b/scripts/developer/utilities/render/transition.qml @@ -58,7 +58,7 @@ Rectangle { } RowLayout { - spacing: 20 + spacing: 8 Layout.fillWidth: true id: root_col @@ -84,6 +84,18 @@ Rectangle { root.sendToScript("category*"+currentIndex) } } + HifiControls.Button { + action: saveAction + Layout.fillWidth: true + anchors.top: parent.top + anchors.bottom: parent.bottom + } + HifiControls.Button { + action: loadAction + Layout.fillWidth: true + anchors.top: parent.top + anchors.bottom: parent.bottom + } } RowLayout { @@ -375,20 +387,6 @@ Rectangle { id: paramWidgetLoader sourceComponent: paramWidgets } - - Row { - anchors.left: parent.left - anchors.right: parent.right - - Button { - action: saveAction - } - Button { - action: loadAction - } - } - - } } \ No newline at end of file From 07cb1c1f9e9d13a2f04dfd17fb8a01433eedd945 Mon Sep 17 00:00:00 2001 From: Olivier Prat Date: Thu, 29 Mar 2018 10:19:24 -0400 Subject: [PATCH 6/9] Moved gradient invert checkbox --- .../developer/utilities/render/transition.qml | 39 ++++++++++++------- 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/scripts/developer/utilities/render/transition.qml b/scripts/developer/utilities/render/transition.qml index b002de30aa..a996c3a198 100644 --- a/scripts/developer/utilities/render/transition.qml +++ b/scripts/developer/utilities/render/transition.qml @@ -152,12 +152,7 @@ Rectangle { spacing: 3 width: root_col.width - HifiControls.CheckBox { - text: "Invert" - boxSize: 20 - checked: root.config["isInverted"] - onCheckedChanged: { root.config["isInverted"] = checked } - } + RowLayout { Layout.fillWidth: true @@ -219,16 +214,32 @@ Rectangle { } } - - ConfigSlider { + RowLayout { + spacing: 20 height: 36 - label: "Edge Width" - integral: false - config: root.config - property: "edgeWidth" - max: 1.0 - min: 0.0 + + HifiControls.CheckBox { + text: "Invert gradient" + anchors.verticalCenter: parent.verticalCenter + boxSize: 20 + checked: root.config["isInverted"] + onCheckedChanged: { root.config["isInverted"] = checked } + } + ConfigSlider { + anchors.left: undefined + anchors.verticalCenter: parent.verticalCenter + height: 36 + width: 300 + label: "Edge Width" + integral: false + config: root.config + property: "edgeWidth" + max: 1.0 + min: 0.0 + } } + + RowLayout { Layout.fillWidth: true From 648e6a6c9b524c6eed330599af2e7e94cfc69bc6 Mon Sep 17 00:00:00 2001 From: Olivier Prat Date: Thu, 29 Mar 2018 10:47:18 -0400 Subject: [PATCH 7/9] Added description for each event --- scripts/developer/utilities/render/transition.qml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/scripts/developer/utilities/render/transition.qml b/scripts/developer/utilities/render/transition.qml index a996c3a198..8811a15e82 100644 --- a/scripts/developer/utilities/render/transition.qml +++ b/scripts/developer/utilities/render/transition.qml @@ -75,6 +75,14 @@ Rectangle { } } onCurrentIndexChanged: { + var descriptions = [ + "Time based threshold, gradients centered on object", + "Fixed threshold, gradients centered on owner avatar", + "Position based threshold (increases when trespasser moves closer to avatar), gradients centered on trespasser avatar", + "Time based threshold, gradients centered on bottom of object", + "UNSUPPORTED" + ] + description.text = descriptions[currentIndex] root.config["editedCategory"] = currentIndex; // This is a hack to be sure the widgets below properly reflect the change of category: delete the Component // by setting the loader source to Null and then recreate it 100ms later @@ -98,6 +106,13 @@ Rectangle { } } + HifiControls.Label { + id: description + text: "..." + Layout.fillWidth: true + wrapMode: Text.WordWrap + } + RowLayout { spacing: 20 height: 36 From ef63651b2bba29ed901883d23b6503e7100b6630 Mon Sep 17 00:00:00 2001 From: Olivier Prat Date: Thu, 29 Mar 2018 12:07:56 -0400 Subject: [PATCH 8/9] Duration and timing controls are disabled when event is not time based --- scripts/developer/utilities/render/transition.qml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/scripts/developer/utilities/render/transition.qml b/scripts/developer/utilities/render/transition.qml index 8811a15e82..65f4f4354a 100644 --- a/scripts/developer/utilities/render/transition.qml +++ b/scripts/developer/utilities/render/transition.qml @@ -72,6 +72,8 @@ Rectangle { interval: 100; running: false; repeat: false onTriggered: { paramWidgetLoader.sourceComponent = paramWidgets + var isTimeBased = categoryBox.currentIndex==0 || categoryBox.currentIndex==3 + paramWidgetLoader.item.isTimeBased = isTimeBased } } onCurrentIndexChanged: { @@ -82,6 +84,7 @@ Rectangle { "Time based threshold, gradients centered on bottom of object", "UNSUPPORTED" ] + description.text = descriptions[currentIndex] root.config["editedCategory"] = currentIndex; // This is a hack to be sure the widgets below properly reflect the change of category: delete the Component @@ -166,7 +169,7 @@ Rectangle { ColumnLayout { spacing: 3 width: root_col.width - + property bool isTimeBased RowLayout { Layout.fillWidth: true @@ -327,6 +330,8 @@ Rectangle { Layout.fillWidth: true ConfigSlider { + enabled: isTimeBased + opacity: isTimeBased ? 1.0 : 0.0 anchors.left: undefined anchors.right: undefined Layout.fillWidth: true @@ -339,6 +344,8 @@ Rectangle { min: 0.1 } HifiControls.ComboBox { + enabled: isTimeBased + opacity: isTimeBased ? 1.0 : 0.0 Layout.fillWidth: true model: ["Linear", "Ease In", "Ease Out", "Ease In / Out"] currentIndex: root.config["timing"] From 0c2c09e77b83cfa1b98cf2dbef2e47032a1e5253 Mon Sep 17 00:00:00 2001 From: Olivier Prat Date: Fri, 30 Mar 2018 15:22:48 -0400 Subject: [PATCH 9/9] Fixed layout in HMD --- scripts/developer/utilities/render/transition.qml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/developer/utilities/render/transition.qml b/scripts/developer/utilities/render/transition.qml index 65f4f4354a..f74468a273 100644 --- a/scripts/developer/utilities/render/transition.qml +++ b/scripts/developer/utilities/render/transition.qml @@ -64,7 +64,8 @@ Rectangle { HifiControls.ComboBox { anchors.verticalCenter: parent.verticalCenter - Layout.fillWidth: true + anchors.left : parent.left + width: 300 id: categoryBox model: ["Elements enter/leave domain", "Bubble isect. - Owner POV", "Bubble isect. - Trespasser POV", "Another user leaves/arrives", "Changing an avatar"] Timer {