From baa6ddb401c343d1cd607abc6257c596a5620761 Mon Sep 17 00:00:00 2001 From: Bruno Herbelin Date: Wed, 8 Dec 2021 23:55:27 +0100 Subject: [PATCH] Implementation of user defined mixing deactivation limit Mixing view handles to grab and scale limbo area. Saving of user defined limit in Session (and snapshot). Testing for source activation outside of update during session update loop. --- ActionManager.cpp | 3 + CMakeLists.txt | 1 + Mixer.cpp | 1 - MixingView.cpp | 79 ++++++++++++++++---- MixingView.h | 7 +- Session.cpp | 4 +- Session.h | 5 ++ SessionCreator.cpp | 12 ++- SessionVisitor.cpp | 3 + Source.cpp | 20 +++-- Source.h | 1 + defines.h | 5 +- rsc/mesh/triangle_point.ply | 143 ++++++++++++++++++++++++++++++++++++ 13 files changed, 257 insertions(+), 27 deletions(-) create mode 100644 rsc/mesh/triangle_point.ply diff --git a/ActionManager.cpp b/ActionManager.cpp index b53283e..3fb5342 100644 --- a/ActionManager.cpp +++ b/ActionManager.cpp @@ -69,6 +69,9 @@ void captureMixerSession(tinyxml2::XMLDocument *doc, std::string node, std::stri delete thumbnail; } + // save session attributes + sessionNode->SetAttribute("activationThreshold", se->activationThreshold()); + // save all sources using source visitor SessionVisitor sv(doc, sessionNode); for (auto iter = se->begin(); iter != se->end(); ++iter, sv.setRoot(sessionNode) ) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9b85f73..0ed142d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -413,6 +413,7 @@ set(VMIX_RSC_FILES ./rsc/mesh/shadow_perspective.ply ./rsc/mesh/point.ply ./rsc/mesh/square_point.ply + ./rsc/mesh/triangle_point.ply ./rsc/mesh/icon_video.ply ./rsc/mesh/icon_image.ply ./rsc/mesh/icon_render.ply diff --git a/Mixer.cpp b/Mixer.cpp index 660cd35..6477e3b 100644 --- a/Mixer.cpp +++ b/Mixer.cpp @@ -1334,7 +1334,6 @@ void Mixer::restore(tinyxml2::XMLElement *sessionNode) // // source lists // - // sessionsources contains list of ids of all sources currently in the session (before loading) SourceIdList session_sources = session_->getIdList(); // for( auto it = sessionsources.begin(); it != sessionsources.end(); it++) diff --git a/MixingView.cpp b/MixingView.cpp index e4be714..19a5c68 100644 --- a/MixingView.cpp +++ b/MixingView.cpp @@ -48,7 +48,7 @@ uint textureMixingQuadratic(); -MixingView::MixingView() : View(MIXING), limbo_scale_(MIXING_LIMBO_SCALE) +MixingView::MixingView() : View(MIXING), limbo_scale_(MIXING_MIN_THRESHOLD) { scene.root()->scale_ = glm::vec3(MIXING_DEFAULT_SCALE, MIXING_DEFAULT_SCALE, 1.0f); scene.root()->translation_ = glm::vec3(0.0f, 0.0f, 0.0f); @@ -62,10 +62,30 @@ MixingView::MixingView() : View(MIXING), limbo_scale_(MIXING_LIMBO_SCALE) restoreSettings(); // Mixing scene background - Mesh *tmp = new Mesh("mesh/disk.ply"); - tmp->scale_ = glm::vec3(limbo_scale_, limbo_scale_, 1.f); - tmp->shader()->color = glm::vec4( COLOR_LIMBO_CIRCLE, 0.6f ); - scene.bg()->attach(tmp); + limbo_ = new Mesh("mesh/disk.ply"); + limbo_->scale_ = glm::vec3(limbo_scale_, limbo_scale_, 1.f); + limbo_->shader()->color = glm::vec4( COLOR_LIMBO_CIRCLE, 1.f ); + scene.bg()->attach(limbo_); + + // interactive limbo scaling slider + limbo_slider_root_ = new Group; + limbo_slider_root_->translation_ = glm::vec3(0.0f, limbo_scale_, 0.f); + scene.bg()->attach(limbo_slider_root_); + limbo_slider_ = new Disk(); + limbo_slider_->translation_ = glm::vec3(0.f, -0.01f, 0.f); + limbo_slider_->scale_ = glm::vec3(0.1f, 0.1f, 1.f); + limbo_slider_->color = glm::vec4( COLOR_LIMBO_CIRCLE, 1.f ); + limbo_slider_root_->attach(limbo_slider_); + limbo_up_ = new Mesh("mesh/triangle_point.ply"); + limbo_up_->scale_ = glm::vec3(0.8f, 0.8f, 1.f); + limbo_up_->shader()->color = glm::vec4( COLOR_CIRCLE_OVER, 0.01f ); + limbo_slider_root_->attach(limbo_up_); + limbo_down_ = new Mesh("mesh/triangle_point.ply"); + limbo_down_->translation_ = glm::vec3(0.f, -0.02f, 0.f); + limbo_down_->scale_ = glm::vec3(0.8f, 0.8f, 1.f); + limbo_down_->rotation_ = glm::vec3(0.f, 0.f, M_PI); + limbo_down_->shader()->color = glm::vec4( COLOR_CIRCLE_OVER, 0.01f ); + limbo_slider_root_->attach(limbo_down_); mixingCircle_ = new Mesh("mesh/disk.ply"); mixingCircle_->shader()->color = glm::vec4( 1.f, 1.f, 1.f, 1.f ); @@ -77,8 +97,8 @@ MixingView::MixingView() : View(MIXING), limbo_scale_(MIXING_LIMBO_SCALE) // Mixing scene foreground - // button frame - tmp = new Mesh("mesh/disk.ply"); + // button frame (non interactive; no picking detected on Mesh) + Mesh *tmp = new Mesh("mesh/disk.ply"); tmp->scale_ = glm::vec3(0.033f, 0.033f, 1.f); tmp->translation_ = glm::vec3(0.f, 1.f, 0.f); tmp->shader()->color = glm::vec4( COLOR_CIRCLE, 0.9f ); @@ -118,10 +138,10 @@ MixingView::MixingView() : View(MIXING), limbo_scale_(MIXING_LIMBO_SCALE) slider_root_->attach(tmp); - stashCircle_ = new Disk(); - stashCircle_->scale_ = glm::vec3(0.5f, 0.5f, 1.f); - stashCircle_->translation_ = glm::vec3(2.f, -1.0f, 0.f); - stashCircle_->color = glm::vec4( COLOR_STASH_CIRCLE, 0.6f ); +// stashCircle_ = new Disk(); +// stashCircle_->scale_ = glm::vec3(0.5f, 0.5f, 1.f); +// stashCircle_->translation_ = glm::vec3(2.f, -1.0f, 0.f); +// stashCircle_->color = glm::vec4( COLOR_STASH_CIRCLE, 0.6f ); // scene.bg()->attach(stashCircle_); } @@ -293,6 +313,13 @@ void MixingView::update(float dt) // for mixing, this means restore position of the fading slider if (View::need_deep_update_ > 0) { + // + // Set limbo scale according to session + // + const float p = CLAMP(Mixer::manager().session()->activationThreshold(), MIXING_MIN_THRESHOLD, MIXING_MAX_THRESHOLD); + limbo_slider_root_->translation_.y = p; + limbo_->scale_ = glm::vec3(p, p, 1.f); + // // Set slider to match the actual fading of the session // @@ -312,8 +339,8 @@ void MixingView::update(float dt) } // the current view is the mixing view - if (Mixer::manager().view() == this ) - { + if (Mixer::manager().view() == this ){ + // // Set session fading to match the slider angle (during animation) // @@ -449,6 +476,22 @@ View::Cursor MixingView::grab (Source *s, glm::vec2 from, glm::vec2 to, std::pai info << "Global opacity " << 100 - int(Mixer::manager().session()->fading() * 100.0) << " %"; return Cursor(Cursor_Hand, info.str() ); } + else if (pick.first == limbo_slider_) { + + // move slider scaling limbo area + const float p = CLAMP(gl_Position_to.y, MIXING_MIN_THRESHOLD, MIXING_MAX_THRESHOLD); + limbo_slider_root_->translation_.y = p; + limbo_->scale_ = glm::vec3(p, p, 1.f); + Mixer::manager().session()->setActivationThreshold(p); + + // color change of arrow indicators + limbo_up_->shader()->color = glm::vec4( COLOR_CIRCLE_OVER, p < MIXING_MAX_THRESHOLD ? 0.15f : 0.01f ); + limbo_down_->shader()->color = glm::vec4( COLOR_CIRCLE_OVER, p > MIXING_MIN_THRESHOLD ? 0.15f : 0.01f ); + + std::ostringstream info; + info << ICON_FA_SNOWFLAKE " Deactivation limit"; + return Cursor(Cursor_Hand, info.str() ); + } // nothing to do return Cursor(); @@ -532,6 +575,16 @@ View::Cursor MixingView::over (glm::vec2 pos) else slider_->color = glm::vec4( COLOR_CIRCLE, 0.9f ); + if ( pick.first == limbo_slider_ ) { + limbo_up_->shader()->color = glm::vec4( COLOR_CIRCLE_OVER, limbo_slider_root_->translation_.y < MIXING_MAX_THRESHOLD ? 0.1f : 0.01f ); + limbo_down_->shader()->color = glm::vec4( COLOR_CIRCLE_OVER, limbo_slider_root_->translation_.y > MIXING_MIN_THRESHOLD ? 0.1f : 0.01f ); + ret.type = Cursor_Hand; + } + else { + limbo_up_->shader()->color = glm::vec4( COLOR_CIRCLE_OVER, 0.01f ); + limbo_down_->shader()->color = glm::vec4( COLOR_CIRCLE_OVER, 0.01f ); + } + return ret; } diff --git a/MixingView.h b/MixingView.h index 74ba8c3..55687aa 100644 --- a/MixingView.h +++ b/MixingView.h @@ -26,7 +26,6 @@ public: void arrow (glm::vec2) override; void setAlpha (Source *s); - inline float limboScale() { return limbo_scale_; } private: void updateSelectionOverlay() override; @@ -37,9 +36,13 @@ private: Disk *slider_; Disk *button_white_; Disk *button_black_; - Disk *stashCircle_; +// Disk *stashCircle_; Mesh *mixingCircle_; Mesh *circle_; + Mesh *limbo_; + Group *limbo_slider_root_; + Mesh *limbo_up_, *limbo_down_; + Disk *limbo_slider_; }; diff --git a/Session.cpp b/Session.cpp index 58ad33e..40b501a 100644 --- a/Session.cpp +++ b/Session.cpp @@ -37,7 +37,8 @@ SessionNote::SessionNote(const std::string &t, bool l, int s): label(std::to_str { } -Session::Session() : active_(true), filename_(""), failedSource_(nullptr), fading_target_(0.f), thumbnail_(nullptr) +Session::Session() : active_(true), activation_threshold_(MIXING_MIN_THRESHOLD), + filename_(""), failedSource_(nullptr), fading_target_(0.f), thumbnail_(nullptr) { config_[View::RENDERING] = new Group; config_[View::RENDERING]->scale_ = glm::vec3(0.f); @@ -131,6 +132,7 @@ void Session::update(float dt) // render the source (*it)->render(); // update the source + (*it)->setActive( (*it)->mix_distance() < activation_threshold_); (*it)->update(dt); } } diff --git a/Session.h b/Session.h index 4c2ca47..93c18fc 100644 --- a/Session.h +++ b/Session.h @@ -101,6 +101,10 @@ public: void setFading (float f, bool forcenow = false); inline float fading () const { return fading_target_; } + // activation threshold for source (mixing distance) + inline void setActivationThreshold(float t) { activation_threshold_ = t; } + inline float activationThreshold() const { return activation_threshold_;} + // configuration for group nodes of views inline Group *config (View::Mode m) const { return config_.at(m); } @@ -147,6 +151,7 @@ public: protected: bool active_; + float activation_threshold_; RenderView render_; std::string filename_; Source *failedSource_; diff --git a/SessionCreator.cpp b/SessionCreator.cpp index 71f8ec6..7f62f14 100644 --- a/SessionCreator.cpp +++ b/SessionCreator.cpp @@ -291,8 +291,18 @@ void SessionLoader::load(XMLElement *sessionNode) return; } - if (sessionNode != nullptr && session_ != nullptr) { + if (sessionNode != nullptr && session_ != nullptr) + { + // + // session attributes + // + float t = MIXING_MIN_THRESHOLD; + sessionNode->QueryFloatAttribute("activationThreshold", &t); + session_->setActivationThreshold(t); + // + // source lists + // XMLElement* sourceNode = sessionNode->FirstChildElement("Source"); for( ; sourceNode ; sourceNode = sourceNode->NextSiblingElement()) { diff --git a/SessionVisitor.cpp b/SessionVisitor.cpp index 044d175..213e44f 100644 --- a/SessionVisitor.cpp +++ b/SessionVisitor.cpp @@ -70,6 +70,9 @@ bool SessionVisitor::saveSession(const std::string& filename, Session *session) // source visitor (*iter)->accept(sv); + // save session attributes + sessionNode->SetAttribute("activationThreshold", session->activationThreshold()); + // save the thumbnail FrameBufferImage *thumbnail = session->thumbnail(); if (thumbnail != nullptr && thumbnail->width > 0 && thumbnail->height > 0) { diff --git a/Source.cpp b/Source.cpp index 644a5dd..d6da88d 100644 --- a/Source.cpp +++ b/Source.cpp @@ -519,6 +519,10 @@ void Source::attach(FrameBuffer *renderbuffer) void Source::setActive (bool on) { + // request update + need_update_ |= active_ != on; + + // activate active_ = on; // do not disactivate if a clone depends on it @@ -571,6 +575,11 @@ void Source::setDepth(float d) touch(); } +float Source::mix_distance() +{ + return glm::length( glm::vec2(groups_[View::MIXING]->translation_) ); +} + float Source::alpha() const { return blendingShader()->color.a; @@ -578,6 +587,7 @@ float Source::alpha() const void Source::setAlpha(float a) { + a = CLAMP(a, 0.f, 1.f); glm::vec2 dist = glm::vec2(groups_[View::MIXING]->translation_); glm::vec2 step = glm::normalize(glm::vec2(1.f, 1.f));// step in diagonal by default @@ -587,10 +597,10 @@ void Source::setAlpha(float a) // converge to reduce the difference of alpha // using dichotomic algorithm - float delta = sin_quad_(dist.x, dist.y) - CLAMP(a, 0.f, 1.f); + float delta = sin_quad_(dist.x, dist.y) - a; while ( glm::abs(delta) > DELTA_ALPHA ){ dist += step * (delta / 2.f); - delta = sin_quad_(dist.x, dist.y) - CLAMP(a, 0.f, 1.f); + delta = sin_quad_(dist.x, dist.y) - a; } // apply new mixing coordinates @@ -613,12 +623,8 @@ void Source::update(float dt) // use the sinusoidal transfer function blendingshader_->color = glm::vec4(1.f, 1.f, 1.f, sin_quad_( dist.x, dist.y )); mixingshader_->color = blendingshader_->color; - - // CHANGE update status based on limbo - bool a = glm::length(dist) < MIXING_LIMBO_SCALE; - setActive( a ); // adjust scale of mixing icon : smaller if not active - groups_[View::MIXING]->scale_ = glm::vec3(MIXING_ICON_SCALE) - ( a ? glm::vec3(0.f, 0.f, 0.f) : glm::vec3(0.03f, 0.03f, 0.f) ); + groups_[View::MIXING]->scale_ = glm::vec3(MIXING_ICON_SCALE) - ( active_ ? glm::vec3(0.f, 0.f, 0.f) : glm::vec3(0.03f, 0.03f, 0.f) ); // MODIFY geometry based on GEOMETRY node groups_[View::RENDERING]->translation_ = groups_[View::GEOMETRY]->translation_; diff --git a/Source.h b/Source.h index 1fb1a03..f257e20 100644 --- a/Source.h +++ b/Source.h @@ -170,6 +170,7 @@ public: void setDepth (float d); // operations on alpha + float mix_distance (); float alpha () const; void setAlpha (float a); diff --git a/defines.h b/defines.h index d73c8af..bf8e554 100644 --- a/defines.h +++ b/defines.h @@ -34,7 +34,8 @@ #define MIXING_DEFAULT_SCALE 2.4f #define MIXING_MIN_SCALE 0.8f #define MIXING_MAX_SCALE 7.0f -#define MIXING_LIMBO_SCALE 1.3f +#define MIXING_MIN_THRESHOLD 1.3f +#define MIXING_MAX_THRESHOLD 1.9f #define MIXING_ICON_SCALE 0.15f, 0.15f, 1.f #define GEOMETRY_DEFAULT_SCALE 1.4f #define GEOMETRY_MIN_SCALE 0.4f @@ -102,7 +103,7 @@ #define COLOR_CIRCLE 0.75f, 0.2f, 0.75f #define COLOR_CIRCLE_OVER 0.8f, 0.8f, 0.8f #define COLOR_MIXING_GROUP 0.f, 0.95f, 0.2f -#define COLOR_LIMBO_CIRCLE 0.16f, 0.16f, 0.16f +#define COLOR_LIMBO_CIRCLE 0.173f, 0.173f, 0.173f #define COLOR_SLIDER_CIRCLE 0.11f, 0.11f, 0.11f #define COLOR_STASH_CIRCLE 0.06f, 0.06f, 0.06f diff --git a/rsc/mesh/triangle_point.ply b/rsc/mesh/triangle_point.ply new file mode 100644 index 0000000..48b78cf --- /dev/null +++ b/rsc/mesh/triangle_point.ply @@ -0,0 +1,143 @@ +ply +format ascii 1.0 +comment Created by Blender 2.93.3 - www.blender.org +element vertex 54 +property float x +property float y +property float z +property float nx +property float ny +property float nz +element face 76 +property list uchar uint vertex_indices +end_header +0.057448 0.004658 0.000000 0.000000 0.000000 1.000000 +0.057742 0.002329 0.000000 0.000000 0.000000 1.000000 +0.058884 0.002939 0.000000 0.000000 0.000000 1.000000 +-0.004658 0.057448 0.000000 0.000000 0.000000 1.000000 +-0.002329 0.057742 0.000000 0.000000 0.000000 1.000000 +-0.003079 0.058745 0.000000 0.000000 0.000000 1.000000 +0.000139 -0.000883 0.000000 -0.000000 -0.000000 1.000000 +-0.028728 0.002329 0.000000 -0.000000 -0.000000 1.000000 +-0.028724 -0.002329 0.000000 -0.000000 -0.000000 1.000000 +0.002329 0.028729 0.000000 -0.000000 0.000000 1.000000 +-0.002329 0.028729 0.000000 -0.000000 0.000000 1.000000 +0.028724 -0.002329 0.000000 0.000000 0.000000 1.000000 +0.028728 0.002329 0.000000 0.000000 0.000000 1.000000 +-0.059486 0.001456 0.000000 0.000000 0.000000 1.000000 +-0.058759 0.000728 0.000000 0.000000 0.000000 1.000000 +-0.058884 0.002939 0.000000 0.000000 0.000000 1.000000 +-0.059486 -0.000000 0.000000 0.000000 0.000000 1.000000 +-0.059486 -0.001456 0.000000 0.000000 0.000000 1.000000 +-0.058884 -0.003218 0.000000 0.000000 0.000000 1.000000 +-0.058759 -0.000728 0.000000 0.000000 0.000000 1.000000 +-0.001456 0.059486 0.000000 0.000000 0.000000 1.000000 +-0.000728 0.058759 0.000000 0.000000 0.000000 1.000000 +-0.000000 0.059486 0.000000 0.000000 0.000000 1.000000 +-0.000000 0.058032 0.000000 0.000000 0.000000 1.000000 +0.002329 0.057742 0.000000 0.000000 0.000000 1.000000 +0.000728 0.058759 0.000000 0.000000 0.000000 1.000000 +0.059486 0.001456 0.000000 0.000000 -0.000000 1.000000 +0.058759 0.000728 0.000000 0.000000 -0.000000 1.000000 +0.059486 0.000000 0.000000 0.000000 -0.000000 1.000000 +0.058032 0.000000 0.000000 0.000000 -0.000000 1.000000 +0.057742 -0.002329 0.000000 0.000000 -0.000000 1.000000 +0.058759 -0.000728 0.000000 0.000000 -0.000000 1.000000 +-0.058032 0.000000 0.000000 0.000000 0.000000 1.000000 +-0.057742 -0.002329 0.000000 0.000000 0.000000 1.000000 +-0.057742 0.002329 0.000000 0.000000 0.000000 1.000000 +-0.015529 0.015529 0.000000 -0.000000 0.000000 1.000000 +-0.017855 0.044250 0.000000 0.000000 -0.000000 1.000000 +0.015529 0.015529 0.000000 0.000000 0.000000 1.000000 +0.004658 0.057448 0.000000 -0.000000 0.000000 1.000000 +-0.000000 0.057453 0.000000 -0.000000 0.000000 1.000000 +0.031053 0.031053 0.000000 0.000000 -0.000000 1.000000 +0.044250 0.017855 0.000000 0.000000 -0.000000 1.000000 +0.057453 0.000000 0.000000 0.000000 0.000000 1.000000 +0.057448 -0.004658 0.000000 0.000000 -0.000000 1.000000 +0.017855 0.044250 0.000000 0.000000 0.000000 1.000000 +-0.031053 0.031053 0.000000 0.000000 -0.000000 1.000000 +-0.044250 0.017855 0.000000 -0.000000 0.000000 1.000000 +-0.057448 0.004658 0.000000 -0.000000 0.000000 1.000000 +-0.057453 0.000000 0.000000 0.000000 0.000000 1.000000 +-0.057448 -0.004658 0.000000 0.000000 0.000000 1.000000 +0.058884 -0.003218 0.000000 0.000000 0.000000 1.000000 +0.059486 -0.001456 0.000000 0.000000 0.000000 1.000000 +0.003079 0.058745 0.000000 0.000000 0.000000 1.000000 +0.001456 0.059486 0.000000 0.000000 0.000000 1.000000 +3 0 1 2 +3 3 4 5 +3 6 7 8 +3 6 9 10 +3 6 11 12 +3 13 14 15 +3 13 16 14 +3 17 18 19 +3 20 21 22 +3 23 24 25 +3 26 27 28 +3 29 30 31 +3 32 33 34 +3 6 35 7 +3 3 36 10 +3 6 37 9 +3 38 24 39 +3 40 37 41 +3 0 42 1 +3 1 30 29 +3 1 42 30 +3 42 43 30 +3 41 12 0 +3 41 37 12 +3 37 6 12 +3 39 4 3 +3 39 24 4 +3 24 23 4 +3 9 44 38 +3 9 37 44 +3 37 40 44 +3 10 35 6 +3 10 36 35 +3 36 45 35 +3 7 46 47 +3 7 35 46 +3 35 45 46 +3 34 48 47 +3 34 33 48 +3 33 49 48 +3 31 50 51 +3 31 30 50 +3 30 43 50 +3 28 31 51 +3 28 27 31 +3 27 29 31 +3 25 52 53 +3 25 24 52 +3 24 38 52 +3 22 25 53 +3 22 21 25 +3 21 23 25 +3 19 33 32 +3 19 18 33 +3 18 49 33 +3 14 19 32 +3 14 16 19 +3 16 17 19 +3 15 34 47 +3 15 14 34 +3 14 32 34 +3 12 42 0 +3 12 11 42 +3 11 43 42 +3 10 39 3 +3 10 9 39 +3 9 38 39 +3 8 48 49 +3 8 7 48 +3 7 47 48 +3 5 21 20 +3 5 4 21 +3 4 23 21 +3 2 27 26 +3 2 1 27 +3 1 29 27