mirror of
https://github.com/brunoherbelin/vimix.git
synced 2025-12-11 18:34:58 +01:00
Picking Nodes in Mixing view and grabbing associated source to modify
alpha
This commit is contained in:
@@ -218,6 +218,7 @@ set(VMIX_SRCS
|
||||
RenderingManager.cpp
|
||||
UserInterfaceManager.cpp
|
||||
PickingVisitor.cpp
|
||||
SearchVisitor.cpp
|
||||
ImGuiToolkit.cpp
|
||||
ImGuiVisitor.cpp
|
||||
GstToolkit.cpp
|
||||
|
||||
18
Mixer.cpp
18
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()
|
||||
|
||||
5
Mixer.h
5
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
|
||||
|
||||
@@ -17,7 +17,9 @@ PickingVisitor::PickingVisitor(glm::vec2 coordinates) : Visitor(), point_(coordi
|
||||
|
||||
void PickingVisitor::visit(Node &n)
|
||||
{
|
||||
|
||||
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 );
|
||||
|
||||
|
||||
41
SearchVisitor.cpp
Normal file
41
SearchVisitor.cpp
Normal file
@@ -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);
|
||||
}
|
||||
42
SearchVisitor.h
Normal file
42
SearchVisitor.h
Normal file
@@ -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
|
||||
33
Source.cpp
33
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;
|
||||
|
||||
}
|
||||
|
||||
17
Source.h
17
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<Source*, bool>
|
||||
{
|
||||
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<Source*, bool>
|
||||
{
|
||||
bool operator()(const Source* elem) const;
|
||||
hasNode(Node *n) : _n(n) { }
|
||||
|
||||
private:
|
||||
Node *_n;
|
||||
};
|
||||
|
||||
class MediaSource : public Source
|
||||
|
||||
@@ -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);
|
||||
|
||||
//
|
||||
// LEFT Mouse button
|
||||
//
|
||||
static Node *current = nullptr;
|
||||
if ( ImGui::IsMouseDown(ImGuiMouseButton_Right)) {
|
||||
|
||||
if ( ImGui::IsMouseDown(ImGuiMouseButton_Left)) {
|
||||
|
||||
// Log::Info("Mouse press (%.1f,%.1f)", io.MousePos.x, io.MousePos.y);
|
||||
// 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);
|
||||
PickingVisitor pv(point);
|
||||
Mixer::manager().currentView()->scene.accept(pv);
|
||||
Log::Info(" (%.1f,%.1f)", point.x, point.y);
|
||||
|
||||
if (pv.picked().empty())
|
||||
current = nullptr;
|
||||
else {
|
||||
current = pv.picked().back();
|
||||
}
|
||||
|
||||
Log::Info(" %d picked", pv.picked().size());
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// LEFT Mouse button
|
||||
//
|
||||
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;
|
||||
// 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());
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
19
View.cpp
19
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;
|
||||
|
||||
}
|
||||
|
||||
|
||||
5
View.h
5
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);
|
||||
|
||||
};
|
||||
|
||||
|
||||
27
main.cpp
27
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;
|
||||
|
||||
bool show = false;
|
||||
MediaPlayer *mp = nullptr;
|
||||
if ( Mixer::manager().currentSource()) {
|
||||
MediaSource *s = static_cast<MediaSource *>(Mixer::manager().currentSource());
|
||||
if ( !s )
|
||||
return;
|
||||
|
||||
MediaPlayer *mp = s->mediaplayer();
|
||||
if ( !mp || !mp->isOpen() )
|
||||
return;
|
||||
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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user