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