From 53a92c15065af578bb85ab8af50a00f896a8c73a Mon Sep 17 00:00:00 2001 From: Olivier Prat Date: Thu, 13 Jul 2017 12:31:10 +0200 Subject: [PATCH] Fade edit is working again and time based transitions are garbage collected --- libraries/render-utils/src/FadeEffect.cpp | 96 +++++++++++++-------- libraries/render-utils/src/FadeEffect.h | 13 +-- libraries/render/src/render/Scene.cpp | 4 +- libraries/render/src/render/Transition.h | 2 +- scripts/developer/utilities/render/fade.qml | 6 +- 5 files changed, 76 insertions(+), 45 deletions(-) diff --git a/libraries/render-utils/src/FadeEffect.cpp b/libraries/render-utils/src/FadeEffect.cpp index 222224ed5f..b5e0c53973 100644 --- a/libraries/render-utils/src/FadeEffect.cpp +++ b/libraries/render-utils/src/FadeEffect.cpp @@ -22,32 +22,59 @@ inline float valueToParameterPow(float value, const double minValue, const doubl return (float)(log(double(value) / minValue) / log(maxOverMinValue)); } +void FadeEditJob::configure(const Config& config) { + _isEditEnabled = config.editFade; +} + void FadeEditJob::run(const render::RenderContextPointer& renderContext, const FadeEditJob::Input& inputs) { - auto jobConfig = static_cast(renderContext->jobConfig.get()); - auto& itemBounds = inputs.get0(); + auto scene = renderContext->_scene; - if (jobConfig->editFade) { + if (_isEditEnabled) { float minIsectDistance = std::numeric_limits::max(); - auto itemId = findNearestItem(renderContext, itemBounds, minIsectDistance); + auto& itemBounds = inputs.get0(); + auto editedItem = findNearestItem(renderContext, itemBounds, minIsectDistance); + render::Transaction transaction; + bool hasTransaction{ false }; - if (itemId != render::Item::INVALID_ITEM_ID) { - const auto& item = renderContext->_scene->getItem(itemId); - - if (item.getTransitionId() == render::TransitionStage::INVALID_INDEX) { - static const render::Transition::Type categoryToTransition[FadeConfig::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 - }; - - // Relaunch transition - render::Transaction transaction; - transaction.addTransitionToItem(itemId, categoryToTransition[inputs.get1()]); - renderContext->_scene->enqueueTransaction(transaction); - } + if (editedItem != _editedItem && _editedItem != render::Item::INVALID_ITEM_ID) { + // Remove transition from previously edited item as we've changed edited item + hasTransaction = true; + transaction.removeTransitionFromItem(_editedItem); } + _editedItem = editedItem; + + if (_editedItem != render::Item::INVALID_ITEM_ID) { + static const render::Transition::Type categoryToTransition[FadeConfig::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 (_editedItem != render::Item::INVALID_ITEM_ID) { + // Remove transition from previously edited item as we've disabled fade edition + render::Transaction transaction; + transaction.removeTransitionFromItem(_editedItem); + scene->enqueueTransaction(transaction); + _editedItem = render::Item::INVALID_ITEM_ID; } } @@ -66,10 +93,10 @@ render::ItemID FadeEditJob::findNearestItem(const render::RenderContextPointer& if (isectDistance>minDistance && isectDistance < minIsectDistance) { auto& item = scene->getItem(itemBound.id); - if (item.getKey().isShape() && !item.getKey().isMeta()) { + // if (!item.getKey().isMeta()) { nearestItem = itemBound.id; minIsectDistance = isectDistance; - } + // } } } } @@ -607,7 +634,7 @@ void FadeJob::update(const Config& config, const render::ScenePointer& scene, re transition.baseInvSize.x = 1.f / dimensions.x; transition.baseInvSize.y = 1.f / dimensions.y; transition.baseInvSize.z = 1.f / dimensions.z; - transition.isFinished = transition.threshold >= 1.f; + transition.isFinished += (transition.threshold >= 1.f) & 1; if (transition.eventType == render::Transition::ELEMENT_ENTER_DOMAIN) { transition.threshold = 1.f - transition.threshold; } @@ -618,15 +645,6 @@ void FadeJob::update(const Config& config, const render::ScenePointer& scene, re { transition.threshold = 0.5f; transition.baseOffset = transition.noiseOffset; - - /* const glm::vec3 cameraPos = renderContext->args->getViewFrustum().getPosition(); - glm::vec3 delta = itemBounds.bound.calcCenter() - cameraPos; - float distance = glm::length(delta); - - delta = glm::normalize(delta) * std::max(0.f, distance - 0.5f); - - _editBaseOffset = cameraPos + delta*_editThreshold; - _editThreshold = 0.33f;*/ } break; @@ -643,7 +661,7 @@ void FadeJob::update(const Config& config, const render::ScenePointer& scene, re transition.threshold = computeElementEnterRatio(transition.time, eventConfig.duration, timing); transition.baseOffset = transition.noiseOffset - dimensions.y / 2.f; transition.baseInvSize.y = 1.f / dimensions.y; - transition.isFinished = transition.threshold >= 1.f; + transition.isFinished += (transition.threshold >= 1.f) & 1; if (transition.eventType == render::Transition::USER_LEAVE_DOMAIN) { transition.threshold = 1.f - transition.threshold; } @@ -659,9 +677,19 @@ void FadeJob::update(const Config& config, const render::ScenePointer& scene, re } transition.noiseOffset += eventConfig.noiseSpeed * (float)transition.time; + if (config.manualFade) { + transition.threshold = config.manualThreshold; + } transition.threshold = std::max(0.f, std::min(1.f, transition.threshold)); transition.threshold = (transition.threshold - 0.5f)*_thresholdScale[fadeCategory] + 0.5f; transition.time += deltaTime; + + // If the transition is finished for more than a number of frames (here 3), garbage collect it. + if (transition.isFinished > 3) { + render::Transaction transaction; + transaction.removeTransitionFromItem(transition.itemId); + scene->enqueueTransaction(transaction); + } } float FadeJob::computeElementEnterRatio(double time, const double period, FadeConfig::Timing timing) { diff --git a/libraries/render-utils/src/FadeEffect.h b/libraries/render-utils/src/FadeEffect.h index 431a069ee6..30c233ad29 100644 --- a/libraries/render-utils/src/FadeEffect.h +++ b/libraries/render-utils/src/FadeEffect.h @@ -18,15 +18,11 @@ class FadeEditConfig : public render::Job::Config { Q_OBJECT - Q_PROPERTY(bool manualFade MEMBER manualFade NOTIFY dirty) - Q_PROPERTY(float manualThreshold MEMBER manualThreshold NOTIFY dirty) Q_PROPERTY(bool editFade MEMBER editFade NOTIFY dirty) public: - float manualThreshold{ 0.f }; bool editFade{ false }; - bool manualFade{ false }; signals: @@ -60,6 +56,8 @@ class FadeConfig : public render::Job::Config { Q_PROPERTY(float noiseSpeedY READ getNoiseSpeedY WRITE setNoiseSpeedY NOTIFY dirty) Q_PROPERTY(float noiseSpeedZ READ getNoiseSpeedZ WRITE setNoiseSpeedZ NOTIFY dirty) Q_PROPERTY(float threshold MEMBER threshold NOTIFY dirty) + Q_PROPERTY(bool manualFade MEMBER manualFade NOTIFY dirty) + Q_PROPERTY(float manualThreshold MEMBER manualThreshold NOTIFY dirty) public: @@ -173,6 +171,8 @@ public: Event events[CATEGORY_COUNT]; int editedCategory{ ELEMENT_ENTER_LEAVE_DOMAIN }; float threshold{ 0.f }; + float manualThreshold{ 0.f }; + bool manualFade{ false }; Q_INVOKABLE void save() const; Q_INVOKABLE void load(); @@ -196,11 +196,14 @@ public: FadeEditJob() {} - void configure(const Config& config) {} + void configure(const Config& config); void run(const render::RenderContextPointer& renderContext, const FadeEditJob::Input& inputs); private: + bool _isEditEnabled{ false }; + render::ItemID _editedItem{ render::Item::INVALID_ITEM_ID }; + render::ItemID findNearestItem(const render::RenderContextPointer& renderContext, const render::ItemBounds& inputs, float& minIsectDistance) const; }; diff --git a/libraries/render/src/render/Scene.cpp b/libraries/render/src/render/Scene.cpp index 18aef8ff70..8bbcca0691 100644 --- a/libraries/render/src/render/Scene.cpp +++ b/libraries/render/src/render/Scene.cpp @@ -242,7 +242,7 @@ void Scene::transitionItems(const Transaction::TransitionAdds& transactions) { auto boundId = std::get<2>(add); // Remove pre-existing transition, if need be - if (TransitionStage::isIndexInvalid(item.getTransitionId())) { + if (!TransitionStage::isIndexInvalid(item.getTransitionId())) { transitionStage->removeTransition(item.getTransitionId()); } // Add a new one. @@ -266,7 +266,7 @@ void Scene::queryTransitionItems(const Transaction::TransitionQueries& transacti if (item.exist() && func != nullptr) { auto transitionId = item.getTransitionId(); - if (TransitionStage::isIndexInvalid(transitionId)) { + if (!TransitionStage::isIndexInvalid(transitionId)) { auto& transition = transitionStage->getTransition(transitionId); func(itemId, &transition); } diff --git a/libraries/render/src/render/Transition.h b/libraries/render/src/render/Transition.h index a87595e4ce..622e6f69ce 100644 --- a/libraries/render/src/render/Transition.h +++ b/libraries/render/src/render/Transition.h @@ -41,7 +41,7 @@ namespace render { glm::vec3 baseOffset{ 0.f, 0.f, 0.f }; glm::vec3 baseInvSize{ 1.f, 1.f, 1.f }; float threshold{ 0.f }; - bool isFinished{ false }; + uint8_t isFinished{ 0 }; }; typedef std::shared_ptr TransitionPointer; diff --git a/scripts/developer/utilities/render/fade.qml b/scripts/developer/utilities/render/fade.qml index cc25cdfde6..f4e4a167d9 100644 --- a/scripts/developer/utilities/render/fade.qml +++ b/scripts/developer/utilities/render/fade.qml @@ -54,15 +54,15 @@ Column { CheckBox { text: "Manual" - checked: root.configEdit["manualFade"] + checked: root.config["manualFade"] onCheckedChanged: { - root.configEdit["manualFade"] = checked; + root.config["manualFade"] = checked; } } ConfigSlider { label: "Threshold" integral: false - config: root.configEdit + config: root.config property: "manualThreshold" max: 1.0 min: 0.0