From 5e589152829738a7f0d08d33115bc97c02fb0906 Mon Sep 17 00:00:00 2001 From: brunoherbelin Date: Thu, 23 Apr 2020 00:36:32 +0200 Subject: [PATCH] Picking Nodes in Mixing view and grabbing associated source to modify alpha --- CMakeLists.txt | 1 + Mixer.cpp | 18 ++++++-- Mixer.h | 5 ++- PickingVisitor.cpp | 7 ++- SearchVisitor.cpp | 41 +++++++++++++++++ SearchVisitor.h | 42 ++++++++++++++++++ Source.cpp | 33 ++++++++++++++ Source.h | 17 +++++-- UserInterfaceManager.cpp | 96 ++++++++++++++++++++++------------------ View.cpp | 19 +++++--- View.h | 5 ++- main.cpp | 29 +++++++----- 12 files changed, 240 insertions(+), 73 deletions(-) create mode 100644 SearchVisitor.cpp create mode 100644 SearchVisitor.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 9a0b3c9..455d1d3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -218,6 +218,7 @@ set(VMIX_SRCS RenderingManager.cpp UserInterfaceManager.cpp PickingVisitor.cpp + SearchVisitor.cpp ImGuiToolkit.cpp ImGuiVisitor.cpp GstToolkit.cpp diff --git a/Mixer.cpp b/Mixer.cpp index e51c56e..12a6219 100644 --- a/Mixer.cpp +++ b/Mixer.cpp @@ -64,14 +64,24 @@ void Mixer::createSourceMedia(std::string uri) current_source_ = Source::begin(); } -void Mixer::setCurrentSource(std::string namesource) +void Mixer::setCurrentSource(Node *node) { - current_source_ = std::find_if(Source::begin(), Source::end(), hasName(namesource)) ; + current_source_ = Source::find(node); } -void Mixer::setcurrentSource(Source *s) +void Mixer::setCurrentSource(std::string namesource) { -// current_source_ = Source:: + current_source_ = Source::find(namesource); +} + +void Mixer::setCurrentSource(Source *s) +{ + current_source_ = Source::find(s); +} + +void Mixer::unsetCurrentSource() +{ + current_source_ = Source::end(); } Source *Mixer::currentSource() diff --git a/Mixer.h b/Mixer.h index e2119a9..15e5884 100644 --- a/Mixer.h +++ b/Mixer.h @@ -36,7 +36,10 @@ public: void createSourceMedia(std::string uri); void setCurrentSource(std::string namesource); - void setcurrentSource(Source *s); + void setCurrentSource(Node *node); + void setCurrentSource(Source *s); + void unsetCurrentSource(); + Source *currentSource(); // management of view diff --git a/PickingVisitor.cpp b/PickingVisitor.cpp index 5e58ae1..8c72454 100644 --- a/PickingVisitor.cpp +++ b/PickingVisitor.cpp @@ -17,7 +17,9 @@ PickingVisitor::PickingVisitor(glm::vec2 coordinates) : Visitor(), point_(coordi void PickingVisitor::visit(Node &n) { - modelview_ *= n.transform_; + + modelview_ *= n.transform_; +// modelview_ = modelview_ * transform(n.translation_, n.rotation_, n.scale_); // Log::Info("Node %d", n.id()); // Log::Info("%s", glm::to_string(modelview_).c_str()); } @@ -25,7 +27,7 @@ void PickingVisitor::visit(Node &n) void PickingVisitor::visit(Group &n) { glm::mat4 mv = modelview_; - +//Log::Info("Group %d", n.id()); for (NodeSet::iterator node = n.begin(); node != n.end(); node++) { (*node)->accept(*this); modelview_ = mv; @@ -51,6 +53,7 @@ void PickingVisitor::visit(Primitive &n) void PickingVisitor::visit(Surface &n) { +// Log::Info("Surface %d", n.id()); // apply inverse transform to the point of interest glm::vec4 P = glm::inverse(modelview_) * glm::vec4( point_, 0.f, 1.f ); diff --git a/SearchVisitor.cpp b/SearchVisitor.cpp new file mode 100644 index 0000000..7ee1fe5 --- /dev/null +++ b/SearchVisitor.cpp @@ -0,0 +1,41 @@ +#include "SearchVisitor.h" + +#include "Scene.h" + +SearchVisitor::SearchVisitor(Node *node) : Visitor(), node_(node), id_(0), found_(false) +{ + id_ = node->id(); +} + +SearchVisitor::SearchVisitor(int id) : Visitor(), node_(nullptr), id_(id), found_(false) +{ + +} + +void SearchVisitor::visit(Node &n) +{ + if ( n.id() == id_ ){ + found_ = true; + node_ = &n; + } +} + +void SearchVisitor::visit(Group &n) +{ + for (NodeSet::iterator node = n.begin(); node != n.end(); node++) { + (*node)->accept(*this); + if (found_) + break; + } +} + +void SearchVisitor::visit(Switch &n) +{ + (*n.activeChild())->accept(*this); +} + + +void SearchVisitor::visit(Scene &n) +{ + n.root()->accept(*this); +} diff --git a/SearchVisitor.h b/SearchVisitor.h new file mode 100644 index 0000000..21e84fb --- /dev/null +++ b/SearchVisitor.h @@ -0,0 +1,42 @@ +#ifndef SEARCHVISITOR_H +#define SEARCHVISITOR_H + +#include "Visitor.h" + +class SearchVisitor: public Visitor +{ + Node *node_; + int id_; + bool found_; + +public: + SearchVisitor(Node *node); + SearchVisitor(int id); + inline bool found() const { return found_; } + inline Node *node() const { return found_ ? node_ : nullptr; } + + // Elements of Scene + void visit(Scene& n); + void visit(Node& n); + void visit(Group& n); + void visit(Switch& n); + + // already a Node or a Group + void visit(Animation&) {} + void visit(Primitive&) {} + void visit(Surface&) {} + void visit(ImageSurface&) {} + void visit(MediaSurface&) {} + void visit(FrameBufferSurface&) {} + void visit(LineStrip&) {} + void visit(LineSquare&) {} + void visit(LineCircle&) {} + void visit(Mesh&) {} + + // not nodes + void visit(MediaPlayer&) {} + void visit(Shader&) {} + void visit(ImageShader&) {} +}; + +#endif // SEARCHVISITOR_H diff --git a/Source.cpp b/Source.cpp index 055a193..b0f8ee5 100644 --- a/Source.cpp +++ b/Source.cpp @@ -8,6 +8,7 @@ #include "Primitives.h" #include "Mesh.h" #include "MediaPlayer.h" +#include "SearchVisitor.h" // gobal static list of all sources @@ -46,6 +47,21 @@ Source::~Source() sources_.remove(this); } +bool hasNode::operator()(const Source* elem) const +{ + if (elem) + { + SearchVisitor sv(_n); + elem->group(View::MIXING)->accept(sv); + if (sv.found()) + return true; + elem->group(View::RENDERING)->accept(sv); + return sv.found(); + } + + return false; +} + std::string Source::rename (std::string newname) { // tentative new name @@ -81,6 +97,21 @@ SourceList::iterator Source::end() return sources_.end(); } +SourceList::iterator Source::find(Source *s) +{ + return std::find(sources_.begin(), sources_.end(), s); +} + +SourceList::iterator Source::find(std::string namesource) +{ + return std::find_if(Source::begin(), Source::end(), hasName(namesource)); +} + +SourceList::iterator Source::find(Node *node) +{ + return std::find_if(Source::begin(), Source::end(), hasNode(node)); +} + uint Source::numSource() { return sources_.size(); @@ -127,5 +158,7 @@ void MediaSource::render() } // read position of the mixing node and interpret this as transparency change + float alpha = 1.0 - ABS( groups_[View::MIXING]->translation_.x ); + surface_->shader()->color.a = alpha; } diff --git a/Source.h b/Source.h index 7c47ed6..bd6335d 100644 --- a/Source.h +++ b/Source.h @@ -31,7 +31,7 @@ public: std::string rename (std::string newname); // get handle on the node used to manipulate the source in a view - inline Group *group(View::Mode m) { return groups_[m]; } + inline Group *group(View::Mode m) const { return groups_.at(m); } // every Source have a shader to control visual effects virtual Shader *shader() const = 0; @@ -42,6 +42,9 @@ public: // global management of list of sources static SourceList::iterator begin(); static SourceList::iterator end(); + static SourceList::iterator find(Source *s); + static SourceList::iterator find(std::string name); + static SourceList::iterator find(Node *node); static uint numSource(); protected: @@ -58,16 +61,22 @@ protected: struct hasName: public std::unary_function { - inline bool operator()(const Source* elem) const - { + inline bool operator()(const Source* elem) const { return (elem && elem->name() == _n); } - hasName(std::string n) : _n(n) { } private: std::string _n; +}; +struct hasNode: public std::unary_function +{ + bool operator()(const Source* elem) const; + hasNode(Node *n) : _n(n) { } + +private: + Node *_n; }; class MediaSource : public Source diff --git a/UserInterfaceManager.cpp b/UserInterfaceManager.cpp index 5344a39..43030ad 100644 --- a/UserInterfaceManager.cpp +++ b/UserInterfaceManager.cpp @@ -174,16 +174,6 @@ void UserInterface::handleMouse() // // RIGHT Mouse button // - if ( ImGui::IsMouseDown(ImGuiMouseButton_Right)) { - - Log::Info("Right Mouse press (%.1f,%.1f)", io.MousePos.x, io.MousePos.y); - - glm::vec3 point = Rendering::manager().unProject(glm::vec2(io.MousePos.x, io.MousePos.y), - Mixer::manager().currentView()->scene.root()->transform_ ); - - Log::Info(" (%.1f,%.1f)", point.x, point.y); - - } if ( ImGui::IsMouseDragging(ImGuiMouseButton_Right, 10.0f) ) { @@ -192,61 +182,79 @@ void UserInterface::handleMouse() ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeAll); } - else + else { ImGui::SetMouseCursor(ImGuiMouseCursor_Arrow); + if ( ImGui::IsMouseDown(ImGuiMouseButton_Right)) { + + // TODO CONTEXT MENU + // Log::Info("Right Mouse press (%.1f,%.1f)", io.MousePos.x, io.MousePos.y); + + glm::vec3 point = Rendering::manager().unProject(glm::vec2(io.MousePos.x, io.MousePos.y), + Mixer::manager().currentView()->scene.root()->transform_ ); + + Log::Info(" (%.1f,%.1f)", point.x, point.y); + + + } + } + // // LEFT Mouse button // - static Node *current = nullptr; - - if ( ImGui::IsMouseDown(ImGuiMouseButton_Left)) { - -// Log::Info("Mouse press (%.1f,%.1f)", io.MousePos.x, io.MousePos.y); - - glm::vec3 point = Rendering::manager().unProject(glm::vec2(io.MousePos.x, io.MousePos.y), - Mixer::manager().currentView()->scene.root()->transform_ ); - -// Log::Info(" (%.1f,%.1f)", point.x, point.y); - PickingVisitor pv(point); - Mixer::manager().currentView()->scene.accept(pv); - - if (pv.picked().empty()) - current = nullptr; - else { - current = pv.picked().back(); - } - - Log::Info(" %d picked", pv.picked().size()); - - } - if ( ImGui::IsMouseDragging(ImGuiMouseButton_Left, 10.0f) ) { + Source *current = Mixer::manager().currentSource(); if (current) { -// // drag current -// Log::Info("Dragging %d", current->id()); -// current->translation_.x += io.MouseDelta.x * 0.1f; -Mixer::manager().currentView()->grab( glm::vec2(io.MouseClickedPos[ImGuiMouseButton_Left].x, io.MouseClickedPos[ImGuiMouseButton_Left].y), glm::vec2(io.MousePos.x, io.MousePos.y), current); - + // drag current source + Mixer::manager().currentView()->grab( glm::vec2(io.MouseClickedPos[ImGuiMouseButton_Left].x, io.MouseClickedPos[ImGuiMouseButton_Left].y), glm::vec2(io.MousePos.x, io.MousePos.y), current); } else { // Log::Info("Mouse drag (%.1f,%.1f)(%.1f,%.1f)", io.MouseClickedPos[0].x, io.MouseClickedPos[0].y, io.MousePos.x, io.MousePos.y); // Selection area - ImGui::GetBackgroundDrawList()->AddRect(io.MouseClickedPos[0], io.MousePos, + ImGui::GetBackgroundDrawList()->AddRect(io.MouseClickedPos[ImGuiMouseButton_Left], io.MousePos, ImGui::GetColorU32(ImGuiCol_ResizeGripHovered)); - ImGui::GetBackgroundDrawList()->AddRectFilled(io.MouseClickedPos[0], io.MousePos, + ImGui::GetBackgroundDrawList()->AddRectFilled(io.MouseClickedPos[ImGuiMouseButton_Left], io.MousePos, ImGui::GetColorU32(ImGuiCol_ResizeGripHovered, 0.3f)); } } + else if ( ImGui::IsMouseDown(ImGuiMouseButton_Left)) { + + // get coordinate in world view of mouse cursor + glm::vec3 point = Rendering::manager().unProject(glm::vec2(io.MousePos.x, io.MousePos.y)); + + // picking visitor traverses the scene + PickingVisitor pv(point); + Mixer::manager().currentView()->scene.accept(pv); + + // picking visitor found nodes? + if (pv.picked().empty()) + Mixer::manager().unsetCurrentSource(); + else + Mixer::manager().setCurrentSource(pv.picked().back()); - if ( ImGui::IsMouseReleased(ImGuiMouseButton_Left) ) - { - current = nullptr; } + else if ( ImGui::IsMouseReleased(ImGuiMouseButton_Left) ) + { + // Log::Info("Mouse press (%.1f,%.1f)", io.MousePos.x, io.MousePos.y); +// glm::vec3 point = Rendering::manager().unProject(glm::vec2(io.MousePos.x, io.MousePos.y)); +// // Log::Info(" (%.1f,%.1f)", point.x, point.y); +// PickingVisitor pv(point); +// Mixer::manager().currentView()->scene.accept(pv); + +// if (pv.picked().empty()) +// Mixer::manager().unsetCurrentSource(); +// else +// Mixer::manager().setCurrentSource(pv.picked().back()); + +// // Log::Info(" %d picked", pv.picked().size()); + + } + + } } diff --git a/View.cpp b/View.cpp index a4738a4..1178e9d 100644 --- a/View.cpp +++ b/View.cpp @@ -5,6 +5,7 @@ #include "defines.h" #include "View.h" +#include "Source.h" #include "Primitives.h" #include "Mesh.h" #include "FrameBuffer.h" @@ -75,23 +76,31 @@ void MixingView::drag (glm::vec2 from, glm::vec2 to) } -void MixingView::grab (glm::vec2 from, glm::vec2 to, Node *node) +void MixingView::grab (glm::vec2 from, glm::vec2 to, Source *s) { + if (!s) + return; + + Group *sourceNode = s->group(View::MIXING); + static glm::vec3 start_translation = glm::vec3(0.f); static glm::vec2 start_position = glm::vec2(0.f); if ( start_position != from ) { start_position = from; - start_translation = node->translation_; + start_translation = sourceNode->translation_; } // unproject - glm::vec3 gl_Position_from = Rendering::manager().unProject(from, node->transform_); - glm::vec3 gl_Position_to = Rendering::manager().unProject(to, node->transform_); +// glm::vec3 gl_Position_from = Rendering::manager().unProject(from, sourceNode->transform_); +// glm::vec3 gl_Position_to = Rendering::manager().unProject(to, sourceNode->transform_); + glm::vec3 gl_Position_from = Rendering::manager().unProject(from, sourceNode->parent_->transform_); + glm::vec3 gl_Position_to = Rendering::manager().unProject(to, sourceNode->parent_->transform_); // compute delta translation - node->translation_ = start_translation + gl_Position_to - gl_Position_from; + // node->translation_ = start_translation + gl_Position_to - gl_Position_from; + sourceNode->translation_ = start_translation + gl_Position_to - gl_Position_from; } diff --git a/View.h b/View.h index 94d8357..cbd1077 100644 --- a/View.h +++ b/View.h @@ -5,6 +5,7 @@ #include "Scene.h" class FrameBuffer; +class Source; class View { @@ -17,7 +18,7 @@ public: virtual void draw () = 0; virtual void zoom (float) {} virtual void drag (glm::vec2, glm::vec2) {} - virtual void grab (glm::vec2, glm::vec2, Node*) {} + virtual void grab (glm::vec2, glm::vec2, Source*) {} Scene scene; @@ -35,7 +36,7 @@ public: void draw () override; void zoom (float factor); void drag (glm::vec2 from, glm::vec2 to); - void grab (glm::vec2 from, glm::vec2 to, Node *node); + void grab (glm::vec2 from, glm::vec2 to, Source *s); }; diff --git a/main.cpp b/main.cpp index c9aa218..9565d0f 100644 --- a/main.cpp +++ b/main.cpp @@ -59,23 +59,30 @@ void drawMediaPlayer() { + static bool opened = true; static GstClockTime begin = GST_CLOCK_TIME_NONE; static GstClockTime end = GST_CLOCK_TIME_NONE; - if ( !Mixer::manager().currentSource()) - return; - - MediaSource *s = static_cast(Mixer::manager().currentSource()); - if ( !s ) - return; - - MediaPlayer *mp = s->mediaplayer(); - if ( !mp || !mp->isOpen() ) - return; + bool show = false; + MediaPlayer *mp = nullptr; + if ( Mixer::manager().currentSource()) { + MediaSource *s = static_cast(Mixer::manager().currentSource()); + if (s) { + mp = s->mediaplayer(); + if (mp && mp->isOpen()) + show = true; + } + } ImGui::SetNextWindowPos(ImVec2(200, 200), ImGuiCond_FirstUseEver); ImGui::SetNextWindowSize(ImVec2(300, 300), ImGuiCond_FirstUseEver); - ImGui::Begin(IMGUI_TITLE_MEDIAPLAYER); + + if ( !ImGui::Begin(IMGUI_TITLE_MEDIAPLAYER, &opened) || !show) + { + ImGui::End(); + return; + } + float width = ImGui::GetContentRegionAvail().x; float spacing = ImGui::GetStyle().ItemInnerSpacing.x;