From 8123e61e3492b965c81f1ca08daa30c74d90e5fd Mon Sep 17 00:00:00 2001 From: brunoherbelin Date: Sun, 28 Feb 2021 14:10:32 +0100 Subject: [PATCH] Cleanup depth management --- LayerView.cpp | 9 +++-- Mixer.cpp | 91 +++++++++++++++++++++++++++++++++++++-------------- Mixer.h | 1 + Selection.cpp | 15 +++------ Selection.h | 8 ++--- Session.cpp | 7 ++++ Session.h | 1 + View.cpp | 16 +++++++-- View.h | 7 ++-- 9 files changed, 105 insertions(+), 50 deletions(-) diff --git a/LayerView.cpp b/LayerView.cpp index 7800ef0..7aad360 100644 --- a/LayerView.cpp +++ b/LayerView.cpp @@ -108,7 +108,7 @@ void LayerView::draw() // manipulation of sources in Mixing view if (ImGui::Selectable( ICON_FA_ALIGN_CENTER " Distribute" )){ - SourceList dsl = Mixer::selection().depthSortedList(); + SourceList dsl = depthSorted(Mixer::selection().getCopy()); SourceList::iterator it = dsl.begin(); float depth = (*it)->depth(); float depth_inc = (dsl.back()->depth() - depth) / static_cast(Mixer::selection().size()-1); @@ -118,8 +118,8 @@ void LayerView::draw() } View::need_deep_update_++; } - if (ImGui::Selectable( ICON_FA_RULER_HORIZONTAL " Fix spacing" )){ - SourceList dsl = Mixer::selection().depthSortedList(); + if (ImGui::Selectable( ICON_FA_RULER_HORIZONTAL " Fixed space" )){ + SourceList dsl = depthSorted(Mixer::selection().getCopy()); SourceList::iterator it = dsl.begin(); float depth = (*it)->depth(); for (it++; it != dsl.end(); it++) { @@ -129,7 +129,7 @@ void LayerView::draw() View::need_deep_update_++; } if (ImGui::Selectable( ICON_FA_EXCHANGE_ALT " Inverse order" )){ - SourceList dsl = Mixer::selection().depthSortedList(); + SourceList dsl = depthSorted(Mixer::selection().getCopy()); SourceList::iterator it = dsl.begin(); SourceList::reverse_iterator rit = dsl.rbegin(); for (; it != dsl.end(); it++, rit++) { @@ -275,7 +275,6 @@ float LayerView::setDepth(Source *s, float d) return sourceNode->translation_.z; } - View::Cursor LayerView::grab (Source *s, glm::vec2 from, glm::vec2 to, std::pair pick) { if (!s) diff --git a/Mixer.cpp b/Mixer.cpp index 234e37e..6775093 100644 --- a/Mixer.cpp +++ b/Mixer.cpp @@ -764,6 +764,19 @@ Source * Mixer::findSource (uint64_t id) return nullptr; } +SourceList Mixer::findSources (float depth_from, float depth_to) +{ + SourceList found; + SourceList dsl = depthSorted( session_->getCopy() ); + SourceList::iterator it = dsl.begin(); + for (; it != dsl.end(); it++) { + if ( (*it)->depth() > depth_to ) + break; + if ( (*it)->depth() >= depth_from ) + found.push_back(*it); + } + return found; +} void Mixer::setCurrentSource(uint64_t id) { @@ -1040,41 +1053,69 @@ void Mixer::merge(SessionSource *source) // new state in history manager Action::manager().store( source->name().c_str() + std::string(" imported.")); + // detach session from SessionSource (source will fail and be deleted later) Session *session = source->detach(); - // import every sources - for ( Source *s = session->popSource(); s != nullptr; s = session->popSource()) { + // import sources of the session (if not empty) + if ( !session->empty() ) { - // avoid name duplicates - renameSource(s, s->name()); + // where to put the sources imported in depth? + float target_depth = source->depth(); - // scale alpha - s->setAlpha( s->alpha() * source->alpha() ); + // get how much space we need from there + SourceList dsl = depthSorted( session->getCopy() ); + float start_depth = dsl.front()->depth(); + float end_depth = dsl.back()->depth(); + float need_depth = MAX( end_depth - start_depth, LAYER_STEP); - // set depth at given location - s->group(View::LAYER)->translation_.z = source->depth() + (s->depth() / MAX_DEPTH); + // make room if there is not enough space + SourceList to_be_moved = findSources(target_depth, MAX_DEPTH); + if (!to_be_moved.empty()){ + float next_depth = to_be_moved.front()->depth(); + if ( next_depth < target_depth + need_depth) { + SourceList::iterator it = to_be_moved.begin(); + for (; it != to_be_moved.end(); it++) { + float scale_depth = (MAX_DEPTH-(*it)->depth()) / (MAX_DEPTH-next_depth); + (*it)->setDepth( (*it)->depth() + scale_depth ); + } + } + } - // set location - // a. transform of node to import - Group *sNode = s->group(View::GEOMETRY); - glm::mat4 sTransform = GlmToolkit::transform(sNode->translation_, sNode->rotation_, sNode->scale_); - // b. transform of session source - Group *sourceNode = source->group(View::GEOMETRY); - glm::mat4 sourceTransform = GlmToolkit::transform(sourceNode->translation_, sourceNode->rotation_, sourceNode->scale_); - // c. combined transform of source and session source - sourceTransform *= sTransform; - GlmToolkit::inverse_transform(sourceTransform, sNode->translation_, sNode->rotation_, sNode->scale_); + // import every sources + for ( Source *s = session->popSource(); s != nullptr; s = session->popSource()) { - // Add source to Session - session_->addSource(s); + // avoid name duplicates + renameSource(s, s->name()); + + // scale alpha + s->setAlpha( s->alpha() * source->alpha() ); + + // set depth (proportional to depth of s, adjusted by needed space) + s->setDepth( target_depth + ( (s->depth()-start_depth)/ need_depth) ); + + // set location + // a. transform of node to import + Group *sNode = s->group(View::GEOMETRY); + glm::mat4 sTransform = GlmToolkit::transform(sNode->translation_, sNode->rotation_, sNode->scale_); + // b. transform of session source + Group *sourceNode = source->group(View::GEOMETRY); + glm::mat4 sourceTransform = GlmToolkit::transform(sourceNode->translation_, sourceNode->rotation_, sourceNode->scale_); + // c. combined transform of source and session source + sourceTransform *= sTransform; + GlmToolkit::inverse_transform(sourceTransform, sNode->translation_, sNode->rotation_, sNode->scale_); + + // Add source to Session + session_->addSource(s); + + // Attach source to Mixer + attach(s); + } + + // needs to update ! + View::need_deep_update_++; - // Attach source to Mixer - attach(s); } - // needs to update ! - View::need_deep_update_++; - // avoid display issues current_view_->update(0.f); diff --git a/Mixer.h b/Mixer.h index 1adb637..192e0d2 100644 --- a/Mixer.h +++ b/Mixer.h @@ -79,6 +79,7 @@ public: Source * findSource (Node *node); Source * findSource (std::string name); Source * findSource (uint64_t id); + SourceList findSources (float depth_from, float depth_to); // management of view View *view (View::Mode m = View::INVALID); diff --git a/Selection.cpp b/Selection.cpp index 35a50c6..37867ae 100644 --- a/Selection.cpp +++ b/Selection.cpp @@ -104,7 +104,7 @@ void Selection::clear() selection_.clear(); } -uint Selection::size() +uint Selection::size() const { return selection_.size(); } @@ -131,7 +131,7 @@ void Selection::pop_front() selection_.pop_front(); } -bool Selection::empty() +bool Selection::empty() const { return selection_.empty(); } @@ -157,7 +157,7 @@ SourceList::iterator Selection::end() return selection_.end(); } -std::string Selection::xml() +std::string Selection::xml() const { std::string x = ""; @@ -195,16 +195,9 @@ std::string Selection::xml() return x; } -bool compare_depth (Source * first, Source * second) -{ - return ( first->depth() < second->depth() ); -} - -SourceList Selection::depthSortedList() +SourceList Selection::getCopy() const { SourceList dsl = selection_; - dsl.sort(compare_depth); - return dsl; } diff --git a/Selection.h b/Selection.h index 3946728..65755df 100644 --- a/Selection.h +++ b/Selection.h @@ -29,12 +29,12 @@ public: // properties bool contains (Source *s); - bool empty(); - uint size (); + bool empty() const; + uint size () const; // extract - std::string xml(); - SourceList depthSortedList(); + std::string xml() const; + SourceList getCopy() const; protected: SourceList::iterator find (Source *s); diff --git a/Session.cpp b/Session.cpp index aa8f955..10add59 100644 --- a/Session.cpp +++ b/Session.cpp @@ -241,6 +241,13 @@ SourceList::iterator Session::find(float depth_from, float depth_to) return std::find_if(sources_.begin(), sources_.end(), Source::hasDepth(depth_from, depth_to)); } +SourceList Session::getCopy() const +{ + SourceList list; + list = sources_; + return list; +} + uint Session::numSource() const { return sources_.size(); diff --git a/Session.h b/Session.h index 30cda9b..38b31ea 100644 --- a/Session.h +++ b/Session.h @@ -39,6 +39,7 @@ public: SourceList::iterator find (std::string name); SourceList::iterator find (Node *node); SourceList::iterator find (float depth_from, float depth_to); + SourceList getCopy() const; SourceList::iterator find (uint64_t id); std::list getIdList() const; diff --git a/View.cpp b/View.cpp index fd0c7d8..5eaa272 100644 --- a/View.cpp +++ b/View.cpp @@ -9,11 +9,10 @@ #include "imgui.h" #include "ImGuiToolkit.h" -// memmove +#include #include #include #include -#include #include "Mixer.h" #include "defines.h" @@ -285,3 +284,16 @@ void View::updateSelectionOverlay() overlay_selection_->scale_ = glm::vec3(0.f, 0.f, 1.f); } + +bool compare_depth (Source * first, Source * second) +{ + return ( first->depth() < second->depth() ); +} + +SourceList depthSorted(SourceList list) +{ + SourceList dsl = list; + dsl.sort(compare_depth); + + return dsl; +} diff --git a/View.h b/View.h index 566b255..dbb28ef 100644 --- a/View.h +++ b/View.h @@ -6,9 +6,6 @@ #include "Scene.h" #include "FrameBuffer.h" -class Source; -typedef std::list SourceList; - class Session; class SessionFileSource; class Surface; @@ -17,6 +14,10 @@ class Mesh; class Frame; class Disk; class Handles; +class Source; + +typedef std::list SourceList; +SourceList depthSorted(SourceList); class View {