//// FadeEffectJobs.cpp // Created by Olivier Prat on 07/07/2017.// Copyright 2017 High Fidelity, Inc.//// Distributed under the Apache License, Version 2.0.// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html//#include "FadeEffectJobs.h"#include "render/Logging.h"#include "render/TransitionStage.h" #include <NumericalConstants.h>#include <Interpolate.h>#include <gpu/Context.h> #include <QJsonArray> #include <PathUtils.h> #define FADE_MIN_SCALE 0.001#define FADE_MAX_SCALE 10000.0#define FADE_MAX_SPEED 50.f inline float parameterToValuePow(float parameter, const double minValue, const double maxOverMinValue) { return (float)(minValue * pow(maxOverMinValue, double(parameter)));} inline float valueToParameterPow(float value, const double minValue, const double maxOverMinValue) { 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 scene = renderContext->_scene; if (_isEditEnabled) { 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; 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); scene->enqueueTransaction(transaction); _editedItem = render::Item::INVALID_ITEM_ID; } } else if (render::Item::isValidID(_editedItem)) { // 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; }} FadeConfig::FadeConfig() { events[FADE_ELEMENT_ENTER_LEAVE_DOMAIN].noiseSize = glm::vec3{ 0.75f, 0.75f, 0.75f }; events[FADE_ELEMENT_ENTER_LEAVE_DOMAIN].noiseLevel = 1.f; events[FADE_ELEMENT_ENTER_LEAVE_DOMAIN].noiseSpeed = glm::vec3{ 0.0f, 0.0f, 0.0f }; events[FADE_ELEMENT_ENTER_LEAVE_DOMAIN].timing = FadeConfig::LINEAR; events[FADE_ELEMENT_ENTER_LEAVE_DOMAIN].baseSize = glm::vec3{ 1.0f, 1.0f, 1.0f }; events[FADE_ELEMENT_ENTER_LEAVE_DOMAIN].baseLevel = 0.f; events[FADE_ELEMENT_ENTER_LEAVE_DOMAIN].isInverted = false; events[FADE_ELEMENT_ENTER_LEAVE_DOMAIN].duration = 4.f; events[FADE_ELEMENT_ENTER_LEAVE_DOMAIN].edgeWidth = 0.1f; events[FADE_ELEMENT_ENTER_LEAVE_DOMAIN].edgeInnerColor = glm::vec4{ 78.f / 255.f, 215.f / 255.f, 255.f / 255.f, 0.0f }; events[FADE_ELEMENT_ENTER_LEAVE_DOMAIN].edgeOuterColor = glm::vec4{ 78.f / 255.f, 215.f / 255.f, 255.f / 255.f, 1.0f }; events[FADE_BUBBLE_ISECT_OWNER].noiseSize = glm::vec3{ 1.5f, 1.0f / 25.f, 0.5f }; events[FADE_BUBBLE_ISECT_OWNER].noiseLevel = 0.37f; events[FADE_BUBBLE_ISECT_OWNER].noiseSpeed = glm::vec3{ 1.0f, 0.2f, 1.0f }; events[FADE_BUBBLE_ISECT_OWNER].timing = FadeConfig::LINEAR; events[FADE_BUBBLE_ISECT_OWNER].baseSize = glm::vec3{ 2.0f, 2.0f, 2.0f }; events[FADE_BUBBLE_ISECT_OWNER].baseLevel = 1.f; events[FADE_BUBBLE_ISECT_OWNER].isInverted = false; events[FADE_BUBBLE_ISECT_OWNER].duration = 4.f; events[FADE_BUBBLE_ISECT_OWNER].edgeWidth = 0.02f; events[FADE_BUBBLE_ISECT_OWNER].edgeInnerColor = glm::vec4{ 31.f / 255.f, 198.f / 255.f, 166.f / 255.f, 1.0f }; events[FADE_BUBBLE_ISECT_OWNER].edgeOuterColor = glm::vec4{ 31.f / 255.f, 198.f / 255.f, 166.f / 255.f, 2.0f }; events[FADE_BUBBLE_ISECT_TRESPASSER].noiseSize = glm::vec3{ 0.5f, 1.0f / 25.f, 0.5f }; events[FADE_BUBBLE_ISECT_TRESPASSER].noiseLevel = 1.f; events[FADE_BUBBLE_ISECT_TRESPASSER].noiseSpeed = glm::vec3{ 1.0f, -5.f, 1.0f }; events[FADE_BUBBLE_ISECT_TRESPASSER].timing = FadeConfig::LINEAR; events[FADE_BUBBLE_ISECT_TRESPASSER].baseSize = glm::vec3{ 2.0f, 2.0f, 2.0f }; events[FADE_BUBBLE_ISECT_TRESPASSER].baseLevel = 0.f; events[FADE_BUBBLE_ISECT_TRESPASSER].isInverted = false; events[FADE_BUBBLE_ISECT_TRESPASSER].duration = 4.f; events[FADE_BUBBLE_ISECT_TRESPASSER].edgeWidth = 0.025f; events[FADE_BUBBLE_ISECT_TRESPASSER].edgeInnerColor = glm::vec4{ 31.f / 255.f, 198.f / 255.f, 166.f / 255.f, 1.0f }; events[FADE_BUBBLE_ISECT_TRESPASSER].edgeOuterColor = glm::vec4{ 31.f / 255.f, 198.f / 255.f, 166.f / 255.f, 2.0f }; events[FADE_USER_ENTER_LEAVE_DOMAIN].noiseSize = glm::vec3{ 10.f, 0.01f, 10.0f }; events[FADE_USER_ENTER_LEAVE_DOMAIN].noiseLevel = 0.3f; events[FADE_USER_ENTER_LEAVE_DOMAIN].noiseSpeed = glm::vec3{ 0.0f, -5.0f, 0.0f }; events[FADE_USER_ENTER_LEAVE_DOMAIN].timing = FadeConfig::LINEAR; events[FADE_USER_ENTER_LEAVE_DOMAIN].baseSize = glm::vec3{ 10000.f, 1.0f, 10000.0f }; events[FADE_USER_ENTER_LEAVE_DOMAIN].baseLevel = 1.f; events[FADE_USER_ENTER_LEAVE_DOMAIN].isInverted = true; events[FADE_USER_ENTER_LEAVE_DOMAIN].duration = 2.f; events[FADE_USER_ENTER_LEAVE_DOMAIN].edgeWidth = 0.229f; events[FADE_USER_ENTER_LEAVE_DOMAIN].edgeInnerColor = glm::vec4{ 1.f, 0.63f, 0.13f, 0.5f }; events[FADE_USER_ENTER_LEAVE_DOMAIN].edgeOuterColor = glm::vec4{ 1.f, 1.f, 1.f, 1.0f }; events[FADE_AVATAR_CHANGE].noiseSize = glm::vec3{ 0.4f, 0.4f, 0.4f }; events[FADE_AVATAR_CHANGE].noiseLevel = 1.f; events[FADE_AVATAR_CHANGE].noiseSpeed = glm::vec3{ 0.0f, 0.0f, 0.0f }; events[FADE_AVATAR_CHANGE].timing = FadeConfig::LINEAR; events[FADE_AVATAR_CHANGE].baseSize = glm::vec3{ 0.4f, 0.4f, 0.4f }; events[FADE_AVATAR_CHANGE].baseLevel = 1.f; events[FADE_AVATAR_CHANGE].isInverted = false; events[FADE_AVATAR_CHANGE].duration = 3.f; events[FADE_AVATAR_CHANGE].edgeWidth = 0.05f; events[FADE_AVATAR_CHANGE].edgeInnerColor = glm::vec4{ 1.0f, 1.0f, 1.0f, 1.0f }; events[FADE_AVATAR_CHANGE].edgeOuterColor = glm::vec4{ 1.0f, 1.0f, 1.0f, 1.0f };} void FadeConfig::setEditedCategory(int value) { assert(value < FADE_CATEGORY_COUNT); editedCategory = std::min<int>(FADE_CATEGORY_COUNT, value); emit dirtyCategory(); emit dirty();} void FadeConfig::setDuration(float value) { events[editedCategory].duration = value; emit dirty();} float FadeConfig::getDuration() const { return events[editedCategory].duration;} void FadeConfig::setBaseSizeX(float value) { events[editedCategory].baseSize.x = parameterToValuePow(value, FADE_MIN_SCALE, FADE_MAX_SCALE/ FADE_MIN_SCALE); emit dirty();} float FadeConfig::getBaseSizeX() const { return valueToParameterPow(events[editedCategory].baseSize.x, FADE_MIN_SCALE, FADE_MAX_SCALE / FADE_MIN_SCALE);} void FadeConfig::setBaseSizeY(float value) { events[editedCategory].baseSize.y = parameterToValuePow(value, FADE_MIN_SCALE, FADE_MAX_SCALE / FADE_MIN_SCALE); emit dirty();} float FadeConfig::getBaseSizeY() const { return valueToParameterPow(events[editedCategory].baseSize.y, FADE_MIN_SCALE, FADE_MAX_SCALE / FADE_MIN_SCALE);} void FadeConfig::setBaseSizeZ(float value) { events[editedCategory].baseSize.z = parameterToValuePow(value, FADE_MIN_SCALE, FADE_MAX_SCALE / FADE_MIN_SCALE); emit dirty();} float FadeConfig::getBaseSizeZ() const { return valueToParameterPow(events[editedCategory].baseSize.z, FADE_MIN_SCALE, FADE_MAX_SCALE / FADE_MIN_SCALE);} void FadeConfig::setBaseLevel(float value) { events[editedCategory].baseLevel = value; emit dirty();} void FadeConfig::setInverted(bool value) { events[editedCategory].isInverted = value; emit dirty();} bool FadeConfig::isInverted() const { return events[editedCategory].isInverted;} void FadeConfig::setNoiseSizeX(float value) { events[editedCategory].noiseSize.x = parameterToValuePow(value, FADE_MIN_SCALE, FADE_MAX_SCALE / FADE_MIN_SCALE); emit dirty();} float FadeConfig::getNoiseSizeX() const { return valueToParameterPow(events[editedCategory].noiseSize.x, FADE_MIN_SCALE, FADE_MAX_SCALE / FADE_MIN_SCALE);} void FadeConfig::setNoiseSizeY(float value) { events[editedCategory].noiseSize.y = parameterToValuePow(value, FADE_MIN_SCALE, FADE_MAX_SCALE / FADE_MIN_SCALE); emit dirty();} float FadeConfig::getNoiseSizeY() const { return valueToParameterPow(events[editedCategory].noiseSize.y, FADE_MIN_SCALE, FADE_MAX_SCALE / FADE_MIN_SCALE);} void FadeConfig::setNoiseSizeZ(float value) { events[editedCategory].noiseSize.z = parameterToValuePow(value, FADE_MIN_SCALE, FADE_MAX_SCALE / FADE_MIN_SCALE); emit dirty();} float FadeConfig::getNoiseSizeZ() const { return valueToParameterPow(events[editedCategory].noiseSize.z, FADE_MIN_SCALE, FADE_MAX_SCALE / FADE_MIN_SCALE);} void FadeConfig::setNoiseLevel(float value) { events[editedCategory].noiseLevel = value; emit dirty();} void FadeConfig::setNoiseSpeedX(float value) { events[editedCategory].noiseSpeed.x = powf(value, 3.f)*FADE_MAX_SPEED; emit dirty();} float FadeConfig::getNoiseSpeedX() const { return powf(events[editedCategory].noiseSpeed.x / FADE_MAX_SPEED, 1.f / 3.f);} void FadeConfig::setNoiseSpeedY(float value) { events[editedCategory].noiseSpeed.y = powf(value, 3.f)*FADE_MAX_SPEED; emit dirty();} float FadeConfig::getNoiseSpeedY() const { return powf(events[editedCategory].noiseSpeed.y / FADE_MAX_SPEED, 1.f / 3.f);} void FadeConfig::setNoiseSpeedZ(float value) { events[editedCategory].noiseSpeed.z = powf(value, 3.f)*FADE_MAX_SPEED; emit dirty();} float FadeConfig::getNoiseSpeedZ() const { return powf(events[editedCategory].noiseSpeed.z / FADE_MAX_SPEED, 1.f / 3.f);} void FadeConfig::setEdgeWidth(float value) { events[editedCategory].edgeWidth = value * value; emit dirty();} float FadeConfig::getEdgeWidth() const { return sqrtf(events[editedCategory].edgeWidth);} void FadeConfig::setEdgeInnerColor(const QColor& value) { events[editedCategory].edgeInnerColor.r = value.redF(); events[editedCategory].edgeInnerColor.g = value.greenF(); events[editedCategory].edgeInnerColor.b = value.blueF(); emit dirty();} QColor FadeConfig::getEdgeInnerColor() const { QColor color; color.setRedF(events[editedCategory].edgeInnerColor.r); color.setGreenF(events[editedCategory].edgeInnerColor.g); color.setBlueF(events[editedCategory].edgeInnerColor.b); color.setAlphaF(1.0f); return color;} void FadeConfig::setEdgeInnerIntensity(float value) { events[editedCategory].edgeInnerColor.a = value; emit dirty();} void FadeConfig::setEdgeOuterColor(const QColor& value) { events[editedCategory].edgeOuterColor.r = value.redF(); events[editedCategory].edgeOuterColor.g = value.greenF(); events[editedCategory].edgeOuterColor.b = value.blueF(); emit dirty();} QColor FadeConfig::getEdgeOuterColor() const { QColor color; color.setRedF(events[editedCategory].edgeOuterColor.r); color.setGreenF(events[editedCategory].edgeOuterColor.g); color.setBlueF(events[editedCategory].edgeOuterColor.b); color.setAlphaF(1.0f); return color;} void FadeConfig::setEdgeOuterIntensity(float value) { events[editedCategory].edgeOuterColor.a = value; emit dirty();} void FadeConfig::setTiming(int value) { assert(value < TIMING_COUNT); events[editedCategory].timing = value; emit dirty();} QString FadeConfig::eventNames[FADE_CATEGORY_COUNT] = { "element_enter_leave_domain", "bubble_isect_owner", "bubble_isect_trespasser", "user_enter_leave_domain", "avatar_change",}; void FadeConfig::save(const QString& configFilePath) const { assert(editedCategory < FADE_CATEGORY_COUNT); QJsonObject lProperties; QFile file(configFilePath); if (!file.open(QFile::WriteOnly | QFile::Text)) { qWarning() << "Fade event configuration file " << configFilePath << " cannot be opened"; } else { const auto& event = events[editedCategory]; lProperties["edgeInnerColor"] = QJsonArray{ event.edgeInnerColor.r, event.edgeInnerColor.g, event.edgeInnerColor.b, event.edgeInnerColor.a }; lProperties["edgeOuterColor"] = QJsonArray{ event.edgeOuterColor.r, event.edgeOuterColor.g, event.edgeOuterColor.b, event.edgeOuterColor.a }; lProperties["noiseSize"] = QJsonArray{ event.noiseSize.x, event.noiseSize.y, event.noiseSize.z }; lProperties["noiseSpeed"] = QJsonArray{ event.noiseSpeed.x, event.noiseSpeed.y, event.noiseSpeed.z }; lProperties["baseSize"] = QJsonArray{ event.baseSize.x, event.baseSize.y, event.baseSize.z }; lProperties["noiseLevel"] = event.noiseLevel; lProperties["baseLevel"] = event.baseLevel; lProperties["duration"] = event.duration; lProperties["edgeWidth"] = event.edgeWidth; lProperties["timing"] = event.timing; lProperties["isInverted"] = event.isInverted; file.write( QJsonDocument(lProperties).toJson() ); file.close(); }} void FadeConfig::load(const QString& configFilePath) { QFile file(configFilePath); if (!file.exists()) { qWarning() << "Fade event configuration file " << configFilePath << " does not exist"; } else if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { qWarning() << "Fade event configuration file " << configFilePath << " cannot be opened"; } else { QString fileData = file.readAll(); file.close(); QJsonParseError error; QJsonDocument doc = QJsonDocument::fromJson(fileData.toUtf8(), &error); if (error.error == error.NoError) { QJsonObject jsonObject = doc.object(); QJsonValue value; auto& event = events[editedCategory]; qCDebug(renderlogging) << "Fade event configuration file" << configFilePath << "loaded"; value = jsonObject["edgeInnerColor"]; if (value.isArray()) { QJsonArray data = value.toArray(); if (data.size() < 4) { qWarning() << "Fade event configuration file " << configFilePath << " contains an invalid 'edgeInnerColor' field. Expected array of size 4"; } else { event.edgeInnerColor.r = (float)data.at(0).toDouble(); event.edgeInnerColor.g = (float)data.at(1).toDouble(); event.edgeInnerColor.b = (float)data.at(2).toDouble(); event.edgeInnerColor.a = (float)data.at(3).toDouble(); } } else { qWarning() << "Fade event configuration file " << configFilePath << " contains an invalid 'edgeInnerColor' field. Expected array of size 4"; } value = jsonObject["edgeOuterColor"]; if (value.isArray()) { QJsonArray data = value.toArray(); if (data.size() < 4) { qWarning() << "Fade event configuration file " << configFilePath << " contains an invalid 'edgeOuterColor' field. Expected array of size 4"; } else { event.edgeOuterColor.r = (float)data.at(0).toDouble(); event.edgeOuterColor.g = (float)data.at(1).toDouble(); event.edgeOuterColor.b = (float)data.at(2).toDouble(); event.edgeOuterColor.a = (float)data.at(3).toDouble(); } } else { qWarning() << "Fade event configuration file " << configFilePath << " contains an invalid 'edgeOuterColor' field. Expected array of size 4"; } value = jsonObject["noiseSize"]; if (value.isArray()) { QJsonArray data = value.toArray(); if (data.size() < 3) { qWarning() << "Fade event configuration file " << configFilePath << " contains an invalid 'noiseSize' field. Expected array of size 3"; } else { event.noiseSize.x = (float)data.at(0).toDouble(); event.noiseSize.y = (float)data.at(1).toDouble(); event.noiseSize.z = (float)data.at(2).toDouble(); } } else { qWarning() << "Fade event configuration file " << configFilePath << " contains an invalid 'noiseSize' field. Expected array of size 3"; } value = jsonObject["noiseSpeed"]; if (value.isArray()) { QJsonArray data = value.toArray(); if (data.size() < 3) { qWarning() << "Fade event configuration file " << configFilePath << " contains an invalid 'noiseSpeed' field. Expected array of size 3"; } else { event.noiseSpeed.x = (float)data.at(0).toDouble(); event.noiseSpeed.y = (float)data.at(1).toDouble(); event.noiseSpeed.z = (float)data.at(2).toDouble(); } } else { qWarning() << "Fade event configuration file " << configFilePath << " contains an invalid 'noiseSpeed' field. Expected array of size 3"; } value = jsonObject["baseSize"]; if (value.isArray()) { QJsonArray data = value.toArray(); if (data.size() < 3) { qWarning() << "Fade event configuration file " << configFilePath << " contains an invalid 'baseSize' field. Expected array of size 3"; } else { event.baseSize.x = (float)data.at(0).toDouble(); event.baseSize.y = (float)data.at(1).toDouble(); event.baseSize.z = (float)data.at(2).toDouble(); } } else { qWarning() << "Fade event configuration file " << configFilePath << " contains an invalid 'baseSize' field. Expected array of size 3"; } value = jsonObject["noiseLevel"]; if (value.isDouble()) { event.noiseLevel = (float)value.toDouble(); } else { qWarning() << "Fade event configuration file " << configFilePath << " contains an invalid 'noiseLevel' field. Expected float value"; } value = jsonObject["baseLevel"]; if (value.isDouble()) { event.baseLevel = (float)value.toDouble(); } else { qWarning() << "Fade event configuration file " << configFilePath << " contains an invalid 'baseLevel' field. Expected float value"; } value = jsonObject["duration"]; if (value.isDouble()) { event.duration = (float)value.toDouble(); } else { qWarning() << "Fade event configuration file " << configFilePath << " contains an invalid 'duration' field. Expected float value"; } Lines 1–500 of 714. Load more
// // FadeEffectJobs.cpp // Created by Olivier Prat on 07/07/2017. // Copyright 2017 High Fidelity, Inc. // // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // #include "FadeEffectJobs.h" #include "render/Logging.h" #include "render/TransitionStage.h" #include <NumericalConstants.h> #include <Interpolate.h> #include <gpu/Context.h> #include <QJsonArray> #include <PathUtils.h> #define FADE_MIN_SCALE 0.001 #define FADE_MAX_SCALE 10000.0 #define FADE_MAX_SPEED 50.f inline float parameterToValuePow(float parameter, const double minValue, const double maxOverMinValue) { return (float)(minValue * pow(maxOverMinValue, double(parameter))); } inline float valueToParameterPow(float value, const double minValue, const double maxOverMinValue) { 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 scene = renderContext->_scene; if (_isEditEnabled) { 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; 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); scene->enqueueTransaction(transaction); _editedItem = render::Item::INVALID_ITEM_ID; } } else if (render::Item::isValidID(_editedItem)) { // 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; } } FadeConfig::FadeConfig() { events[FADE_ELEMENT_ENTER_LEAVE_DOMAIN].noiseSize = glm::vec3{ 0.75f, 0.75f, 0.75f }; events[FADE_ELEMENT_ENTER_LEAVE_DOMAIN].noiseLevel = 1.f; events[FADE_ELEMENT_ENTER_LEAVE_DOMAIN].noiseSpeed = glm::vec3{ 0.0f, 0.0f, 0.0f }; events[FADE_ELEMENT_ENTER_LEAVE_DOMAIN].timing = FadeConfig::LINEAR; events[FADE_ELEMENT_ENTER_LEAVE_DOMAIN].baseSize = glm::vec3{ 1.0f, 1.0f, 1.0f }; events[FADE_ELEMENT_ENTER_LEAVE_DOMAIN].baseLevel = 0.f; events[FADE_ELEMENT_ENTER_LEAVE_DOMAIN].isInverted = false; events[FADE_ELEMENT_ENTER_LEAVE_DOMAIN].duration = 4.f; events[FADE_ELEMENT_ENTER_LEAVE_DOMAIN].edgeWidth = 0.1f; events[FADE_ELEMENT_ENTER_LEAVE_DOMAIN].edgeInnerColor = glm::vec4{ 78.f / 255.f, 215.f / 255.f, 255.f / 255.f, 0.0f }; events[FADE_ELEMENT_ENTER_LEAVE_DOMAIN].edgeOuterColor = glm::vec4{ 78.f / 255.f, 215.f / 255.f, 255.f / 255.f, 1.0f }; events[FADE_BUBBLE_ISECT_OWNER].noiseSize = glm::vec3{ 1.5f, 1.0f / 25.f, 0.5f }; events[FADE_BUBBLE_ISECT_OWNER].noiseLevel = 0.37f; events[FADE_BUBBLE_ISECT_OWNER].noiseSpeed = glm::vec3{ 1.0f, 0.2f, 1.0f }; events[FADE_BUBBLE_ISECT_OWNER].timing = FadeConfig::LINEAR; events[FADE_BUBBLE_ISECT_OWNER].baseSize = glm::vec3{ 2.0f, 2.0f, 2.0f }; events[FADE_BUBBLE_ISECT_OWNER].baseLevel = 1.f; events[FADE_BUBBLE_ISECT_OWNER].isInverted = false; events[FADE_BUBBLE_ISECT_OWNER].duration = 4.f; events[FADE_BUBBLE_ISECT_OWNER].edgeWidth = 0.02f; events[FADE_BUBBLE_ISECT_OWNER].edgeInnerColor = glm::vec4{ 31.f / 255.f, 198.f / 255.f, 166.f / 255.f, 1.0f }; events[FADE_BUBBLE_ISECT_OWNER].edgeOuterColor = glm::vec4{ 31.f / 255.f, 198.f / 255.f, 166.f / 255.f, 2.0f }; events[FADE_BUBBLE_ISECT_TRESPASSER].noiseSize = glm::vec3{ 0.5f, 1.0f / 25.f, 0.5f }; events[FADE_BUBBLE_ISECT_TRESPASSER].noiseLevel = 1.f; events[FADE_BUBBLE_ISECT_TRESPASSER].noiseSpeed = glm::vec3{ 1.0f, -5.f, 1.0f }; events[FADE_BUBBLE_ISECT_TRESPASSER].timing = FadeConfig::LINEAR; events[FADE_BUBBLE_ISECT_TRESPASSER].baseSize = glm::vec3{ 2.0f, 2.0f, 2.0f }; events[FADE_BUBBLE_ISECT_TRESPASSER].baseLevel = 0.f; events[FADE_BUBBLE_ISECT_TRESPASSER].isInverted = false; events[FADE_BUBBLE_ISECT_TRESPASSER].duration = 4.f; events[FADE_BUBBLE_ISECT_TRESPASSER].edgeWidth = 0.025f; events[FADE_BUBBLE_ISECT_TRESPASSER].edgeInnerColor = glm::vec4{ 31.f / 255.f, 198.f / 255.f, 166.f / 255.f, 1.0f }; events[FADE_BUBBLE_ISECT_TRESPASSER].edgeOuterColor = glm::vec4{ 31.f / 255.f, 198.f / 255.f, 166.f / 255.f, 2.0f }; events[FADE_USER_ENTER_LEAVE_DOMAIN].noiseSize = glm::vec3{ 10.f, 0.01f, 10.0f }; events[FADE_USER_ENTER_LEAVE_DOMAIN].noiseLevel = 0.3f; events[FADE_USER_ENTER_LEAVE_DOMAIN].noiseSpeed = glm::vec3{ 0.0f, -5.0f, 0.0f }; events[FADE_USER_ENTER_LEAVE_DOMAIN].timing = FadeConfig::LINEAR; events[FADE_USER_ENTER_LEAVE_DOMAIN].baseSize = glm::vec3{ 10000.f, 1.0f, 10000.0f }; events[FADE_USER_ENTER_LEAVE_DOMAIN].baseLevel = 1.f; events[FADE_USER_ENTER_LEAVE_DOMAIN].isInverted = true; events[FADE_USER_ENTER_LEAVE_DOMAIN].duration = 2.f; events[FADE_USER_ENTER_LEAVE_DOMAIN].edgeWidth = 0.229f; events[FADE_USER_ENTER_LEAVE_DOMAIN].edgeInnerColor = glm::vec4{ 1.f, 0.63f, 0.13f, 0.5f }; events[FADE_USER_ENTER_LEAVE_DOMAIN].edgeOuterColor = glm::vec4{ 1.f, 1.f, 1.f, 1.0f }; events[FADE_AVATAR_CHANGE].noiseSize = glm::vec3{ 0.4f, 0.4f, 0.4f }; events[FADE_AVATAR_CHANGE].noiseLevel = 1.f; events[FADE_AVATAR_CHANGE].noiseSpeed = glm::vec3{ 0.0f, 0.0f, 0.0f }; events[FADE_AVATAR_CHANGE].timing = FadeConfig::LINEAR; events[FADE_AVATAR_CHANGE].baseSize = glm::vec3{ 0.4f, 0.4f, 0.4f }; events[FADE_AVATAR_CHANGE].baseLevel = 1.f; events[FADE_AVATAR_CHANGE].isInverted = false; events[FADE_AVATAR_CHANGE].duration = 3.f; events[FADE_AVATAR_CHANGE].edgeWidth = 0.05f; events[FADE_AVATAR_CHANGE].edgeInnerColor = glm::vec4{ 1.0f, 1.0f, 1.0f, 1.0f }; events[FADE_AVATAR_CHANGE].edgeOuterColor = glm::vec4{ 1.0f, 1.0f, 1.0f, 1.0f }; } void FadeConfig::setEditedCategory(int value) { assert(value < FADE_CATEGORY_COUNT); editedCategory = std::min<int>(FADE_CATEGORY_COUNT, value); emit dirtyCategory(); emit dirty(); } void FadeConfig::setDuration(float value) { events[editedCategory].duration = value; emit dirty(); } float FadeConfig::getDuration() const { return events[editedCategory].duration; } void FadeConfig::setBaseSizeX(float value) { events[editedCategory].baseSize.x = parameterToValuePow(value, FADE_MIN_SCALE, FADE_MAX_SCALE/ FADE_MIN_SCALE); emit dirty(); } float FadeConfig::getBaseSizeX() const { return valueToParameterPow(events[editedCategory].baseSize.x, FADE_MIN_SCALE, FADE_MAX_SCALE / FADE_MIN_SCALE); } void FadeConfig::setBaseSizeY(float value) { events[editedCategory].baseSize.y = parameterToValuePow(value, FADE_MIN_SCALE, FADE_MAX_SCALE / FADE_MIN_SCALE); emit dirty(); } float FadeConfig::getBaseSizeY() const { return valueToParameterPow(events[editedCategory].baseSize.y, FADE_MIN_SCALE, FADE_MAX_SCALE / FADE_MIN_SCALE); } void FadeConfig::setBaseSizeZ(float value) { events[editedCategory].baseSize.z = parameterToValuePow(value, FADE_MIN_SCALE, FADE_MAX_SCALE / FADE_MIN_SCALE); emit dirty(); } float FadeConfig::getBaseSizeZ() const { return valueToParameterPow(events[editedCategory].baseSize.z, FADE_MIN_SCALE, FADE_MAX_SCALE / FADE_MIN_SCALE); } void FadeConfig::setBaseLevel(float value) { events[editedCategory].baseLevel = value; emit dirty(); } void FadeConfig::setInverted(bool value) { events[editedCategory].isInverted = value; emit dirty(); } bool FadeConfig::isInverted() const { return events[editedCategory].isInverted; } void FadeConfig::setNoiseSizeX(float value) { events[editedCategory].noiseSize.x = parameterToValuePow(value, FADE_MIN_SCALE, FADE_MAX_SCALE / FADE_MIN_SCALE); emit dirty(); } float FadeConfig::getNoiseSizeX() const { return valueToParameterPow(events[editedCategory].noiseSize.x, FADE_MIN_SCALE, FADE_MAX_SCALE / FADE_MIN_SCALE); } void FadeConfig::setNoiseSizeY(float value) { events[editedCategory].noiseSize.y = parameterToValuePow(value, FADE_MIN_SCALE, FADE_MAX_SCALE / FADE_MIN_SCALE); emit dirty(); } float FadeConfig::getNoiseSizeY() const { return valueToParameterPow(events[editedCategory].noiseSize.y, FADE_MIN_SCALE, FADE_MAX_SCALE / FADE_MIN_SCALE); } void FadeConfig::setNoiseSizeZ(float value) { events[editedCategory].noiseSize.z = parameterToValuePow(value, FADE_MIN_SCALE, FADE_MAX_SCALE / FADE_MIN_SCALE); emit dirty(); } float FadeConfig::getNoiseSizeZ() const { return valueToParameterPow(events[editedCategory].noiseSize.z, FADE_MIN_SCALE, FADE_MAX_SCALE / FADE_MIN_SCALE); } void FadeConfig::setNoiseLevel(float value) { events[editedCategory].noiseLevel = value; emit dirty(); } void FadeConfig::setNoiseSpeedX(float value) { events[editedCategory].noiseSpeed.x = powf(value, 3.f)*FADE_MAX_SPEED; emit dirty(); } float FadeConfig::getNoiseSpeedX() const { return powf(events[editedCategory].noiseSpeed.x / FADE_MAX_SPEED, 1.f / 3.f); } void FadeConfig::setNoiseSpeedY(float value) { events[editedCategory].noiseSpeed.y = powf(value, 3.f)*FADE_MAX_SPEED; emit dirty(); } float FadeConfig::getNoiseSpeedY() const { return powf(events[editedCategory].noiseSpeed.y / FADE_MAX_SPEED, 1.f / 3.f); } void FadeConfig::setNoiseSpeedZ(float value) { events[editedCategory].noiseSpeed.z = powf(value, 3.f)*FADE_MAX_SPEED; emit dirty(); } float FadeConfig::getNoiseSpeedZ() const { return powf(events[editedCategory].noiseSpeed.z / FADE_MAX_SPEED, 1.f / 3.f); } void FadeConfig::setEdgeWidth(float value) { events[editedCategory].edgeWidth = value * value; emit dirty(); } float FadeConfig::getEdgeWidth() const { return sqrtf(events[editedCategory].edgeWidth); } void FadeConfig::setEdgeInnerColor(const QColor& value) { events[editedCategory].edgeInnerColor.r = value.redF(); events[editedCategory].edgeInnerColor.g = value.greenF(); events[editedCategory].edgeInnerColor.b = value.blueF(); emit dirty(); } QColor FadeConfig::getEdgeInnerColor() const { QColor color; color.setRedF(events[editedCategory].edgeInnerColor.r); color.setGreenF(events[editedCategory].edgeInnerColor.g); color.setBlueF(events[editedCategory].edgeInnerColor.b); color.setAlphaF(1.0f); return color; } void FadeConfig::setEdgeInnerIntensity(float value) { events[editedCategory].edgeInnerColor.a = value; emit dirty(); } void FadeConfig::setEdgeOuterColor(const QColor& value) { events[editedCategory].edgeOuterColor.r = value.redF(); events[editedCategory].edgeOuterColor.g = value.greenF(); events[editedCategory].edgeOuterColor.b = value.blueF(); emit dirty(); } QColor FadeConfig::getEdgeOuterColor() const { QColor color; color.setRedF(events[editedCategory].edgeOuterColor.r); color.setGreenF(events[editedCategory].edgeOuterColor.g); color.setBlueF(events[editedCategory].edgeOuterColor.b); color.setAlphaF(1.0f); return color; } void FadeConfig::setEdgeOuterIntensity(float value) { events[editedCategory].edgeOuterColor.a = value; emit dirty(); } void FadeConfig::setTiming(int value) { assert(value < TIMING_COUNT); events[editedCategory].timing = value; emit dirty(); } QString FadeConfig::eventNames[FADE_CATEGORY_COUNT] = { "element_enter_leave_domain", "bubble_isect_owner", "bubble_isect_trespasser", "user_enter_leave_domain", "avatar_change", }; void FadeConfig::save(const QString& configFilePath) const { assert(editedCategory < FADE_CATEGORY_COUNT); QJsonObject lProperties; QFile file(configFilePath); if (!file.open(QFile::WriteOnly | QFile::Text)) { qWarning() << "Fade event configuration file " << configFilePath << " cannot be opened"; } else { const auto& event = events[editedCategory]; lProperties["edgeInnerColor"] = QJsonArray{ event.edgeInnerColor.r, event.edgeInnerColor.g, event.edgeInnerColor.b, event.edgeInnerColor.a }; lProperties["edgeOuterColor"] = QJsonArray{ event.edgeOuterColor.r, event.edgeOuterColor.g, event.edgeOuterColor.b, event.edgeOuterColor.a }; lProperties["noiseSize"] = QJsonArray{ event.noiseSize.x, event.noiseSize.y, event.noiseSize.z }; lProperties["noiseSpeed"] = QJsonArray{ event.noiseSpeed.x, event.noiseSpeed.y, event.noiseSpeed.z }; lProperties["baseSize"] = QJsonArray{ event.baseSize.x, event.baseSize.y, event.baseSize.z }; lProperties["noiseLevel"] = event.noiseLevel; lProperties["baseLevel"] = event.baseLevel; lProperties["duration"] = event.duration; lProperties["edgeWidth"] = event.edgeWidth; lProperties["timing"] = event.timing; lProperties["isInverted"] = event.isInverted; file.write( QJsonDocument(lProperties).toJson() ); file.close(); } } void FadeConfig::load(const QString& configFilePath) { QFile file(configFilePath); if (!file.exists()) { qWarning() << "Fade event configuration file " << configFilePath << " does not exist"; } else if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { qWarning() << "Fade event configuration file " << configFilePath << " cannot be opened"; } else { QString fileData = file.readAll(); file.close(); QJsonParseError error; QJsonDocument doc = QJsonDocument::fromJson(fileData.toUtf8(), &error); if (error.error == error.NoError) { QJsonObject jsonObject = doc.object(); QJsonValue value; auto& event = events[editedCategory]; qCDebug(renderlogging) << "Fade event configuration file" << configFilePath << "loaded"; value = jsonObject["edgeInnerColor"]; if (value.isArray()) { QJsonArray data = value.toArray(); if (data.size() < 4) { qWarning() << "Fade event configuration file " << configFilePath << " contains an invalid 'edgeInnerColor' field. Expected array of size 4"; } else { event.edgeInnerColor.r = (float)data.at(0).toDouble(); event.edgeInnerColor.g = (float)data.at(1).toDouble(); event.edgeInnerColor.b = (float)data.at(2).toDouble(); event.edgeInnerColor.a = (float)data.at(3).toDouble(); } } else { qWarning() << "Fade event configuration file " << configFilePath << " contains an invalid 'edgeInnerColor' field. Expected array of size 4"; } value = jsonObject["edgeOuterColor"]; if (value.isArray()) { QJsonArray data = value.toArray(); if (data.size() < 4) { qWarning() << "Fade event configuration file " << configFilePath << " contains an invalid 'edgeOuterColor' field. Expected array of size 4"; } else { event.edgeOuterColor.r = (float)data.at(0).toDouble(); event.edgeOuterColor.g = (float)data.at(1).toDouble(); event.edgeOuterColor.b = (float)data.at(2).toDouble(); event.edgeOuterColor.a = (float)data.at(3).toDouble(); } } else { qWarning() << "Fade event configuration file " << configFilePath << " contains an invalid 'edgeOuterColor' field. Expected array of size 4"; } value = jsonObject["noiseSize"]; if (value.isArray()) { QJsonArray data = value.toArray(); if (data.size() < 3) { qWarning() << "Fade event configuration file " << configFilePath << " contains an invalid 'noiseSize' field. Expected array of size 3"; } else { event.noiseSize.x = (float)data.at(0).toDouble(); event.noiseSize.y = (float)data.at(1).toDouble(); event.noiseSize.z = (float)data.at(2).toDouble(); } } else { qWarning() << "Fade event configuration file " << configFilePath << " contains an invalid 'noiseSize' field. Expected array of size 3"; } value = jsonObject["noiseSpeed"]; if (value.isArray()) { QJsonArray data = value.toArray(); if (data.size() < 3) { qWarning() << "Fade event configuration file " << configFilePath << " contains an invalid 'noiseSpeed' field. Expected array of size 3"; } else { event.noiseSpeed.x = (float)data.at(0).toDouble(); event.noiseSpeed.y = (float)data.at(1).toDouble(); event.noiseSpeed.z = (float)data.at(2).toDouble(); } } else { qWarning() << "Fade event configuration file " << configFilePath << " contains an invalid 'noiseSpeed' field. Expected array of size 3"; } value = jsonObject["baseSize"]; if (value.isArray()) { QJsonArray data = value.toArray(); if (data.size() < 3) { qWarning() << "Fade event configuration file " << configFilePath << " contains an invalid 'baseSize' field. Expected array of size 3"; } else { event.baseSize.x = (float)data.at(0).toDouble(); event.baseSize.y = (float)data.at(1).toDouble(); event.baseSize.z = (float)data.at(2).toDouble(); } } else { qWarning() << "Fade event configuration file " << configFilePath << " contains an invalid 'baseSize' field. Expected array of size 3"; } value = jsonObject["noiseLevel"]; if (value.isDouble()) { event.noiseLevel = (float)value.toDouble(); } else { qWarning() << "Fade event configuration file " << configFilePath << " contains an invalid 'noiseLevel' field. Expected float value"; } value = jsonObject["baseLevel"]; if (value.isDouble()) { event.baseLevel = (float)value.toDouble(); } else { qWarning() << "Fade event configuration file " << configFilePath << " contains an invalid 'baseLevel' field. Expected float value"; } value = jsonObject["duration"]; if (value.isDouble()) { event.duration = (float)value.toDouble(); } else { qWarning() << "Fade event configuration file " << configFilePath << " contains an invalid 'duration' field. Expected float value"; }