New: implementation of fading slider in MixingView. Needed to implement

decoration Disk and to update picking visitor.
This commit is contained in:
brunoherbelin
2020-07-29 17:06:08 +02:00
parent 714f2bea3c
commit 837eb2d569
13 changed files with 284 additions and 128 deletions

View File

@@ -355,55 +355,95 @@ void Symbol::accept(Visitor& v)
v.visit(*this);
}
Mesh *Disk::disk_ = nullptr;
SelectionBox::SelectionBox()
Disk::Disk() : Node()
{
if (Disk::disk_ == nullptr)
Disk::disk_ = new Mesh("mesh/disk.ply");
color = glm::vec4( 1.f, 1.f, 1.f, 1.f);
}
Disk::~Disk()
{
// color = glm::vec4( 1.f, 1.f, 1.f, 1.f);
color = glm::vec4( 1.f, 0.f, 0.f, 1.f);
square_ = new LineSquare( 3 );
}
void SelectionBox::draw (glm::mat4 modelview, glm::mat4 projection)
void Disk::draw(glm::mat4 modelview, glm::mat4 projection)
{
if ( !initialized() ) {
square_->init();
if (!Disk::disk_->initialized())
Disk::disk_->init();
init();
}
if (visible_) {
// use a visitor bounding box to calculate extend of all selected nodes
BoundingBoxVisitor vbox;
// visit every child of the selection
for (NodeSet::iterator node = children_.begin();
node != children_.end(); node++) {
// reset the transform before
vbox.setModelview(glm::identity<glm::mat4>());
(*node)->accept(vbox);
}
// get the bounding box
bbox_ = vbox.bbox();
// Log::Info(" -------- visitor box (%f, %f)-(%f, %f)", bbox_.min().x, bbox_.min().y, bbox_.max().x, bbox_.max().y);
if ( visible_ ) {
// set color
square_->shader()->color = color;
Disk::disk_->shader()->color = color;
// compute transformation from bounding box
// glm::mat4 ctm = modelview * GlmToolkit::transform(glm::vec3(0.f), glm::vec3(0.f), glm::vec3(1.f));
glm::mat4 ctm = modelview * GlmToolkit::transform(bbox_.center(), glm::vec3(0.f), bbox_.scale());
glm::mat4 ctm = modelview * transform_;
Disk::disk_->draw( ctm, projection);
// draw bbox
// square_->draw( modelview, projection);
square_->draw( ctm, projection);
// DEBUG
// visible_=false;
}
}
void Disk::accept(Visitor& v)
{
Node::accept(v);
v.visit(*this);
}
//SelectionBox::SelectionBox()
//{
//// color = glm::vec4( 1.f, 1.f, 1.f, 1.f);
// color = glm::vec4( 1.f, 0.f, 0.f, 1.f);
// square_ = new LineSquare( 3 );
//}
//void SelectionBox::draw (glm::mat4 modelview, glm::mat4 projection)
//{
// if ( !initialized() ) {
// square_->init();
// init();
// }
// if (visible_) {
// // use a visitor bounding box to calculate extend of all selected nodes
// BoundingBoxVisitor vbox;
// // visit every child of the selection
// for (NodeSet::iterator node = children_.begin();
// node != children_.end(); node++) {
// // reset the transform before
// vbox.setModelview(glm::identity<glm::mat4>());
// (*node)->accept(vbox);
// }
// // get the bounding box
// bbox_ = vbox.bbox();
//// Log::Info(" -------- visitor box (%f, %f)-(%f, %f)", bbox_.min().x, bbox_.min().y, bbox_.max().x, bbox_.max().y);
// // set color
// square_->shader()->color = color;
// // compute transformation from bounding box
//// glm::mat4 ctm = modelview * GlmToolkit::transform(glm::vec3(0.f), glm::vec3(0.f), glm::vec3(1.f));
// glm::mat4 ctm = modelview * GlmToolkit::transform(bbox_.center(), glm::vec3(0.f), bbox_.scale());
// // draw bbox
//// square_->draw( modelview, projection);
// square_->draw( ctm, projection);
// // DEBUG
//// visible_=false;
// }
//}

View File

@@ -72,20 +72,35 @@ protected:
Type type_;
};
class SelectionBox : public Group
class Disk : public Node
{
public:
SelectionBox();
Disk();
~Disk();
void draw (glm::mat4 modelview, glm::mat4 projection) override;
void accept (Visitor& v) override;
glm::vec4 color;
protected:
LineSquare *square_;
GlmToolkit::AxisAlignedBoundingBox bbox_;
static Mesh *disk_;
};
//class SelectionBox : public Group
//{
//public:
// SelectionBox();
// void draw (glm::mat4 modelview, glm::mat4 projection) override;
// glm::vec4 color;
//protected:
// LineSquare *square_;
// GlmToolkit::AxisAlignedBoundingBox bbox_;
//};
#endif // DECORATIONS_H

2
Mesh.h
View File

@@ -26,7 +26,7 @@ public:
inline std::string meshPath() const { return mesh_resource_; }
inline std::string texturePath() const { return texture_resource_; }
//protected:
protected:
std::string mesh_resource_;
std::string texture_resource_;
uint textureindex_;

View File

@@ -231,9 +231,6 @@ void Mixer::draw()
// draw the current view in the window
current_view_->draw();
// make sure we disable fading of session rendering
if (current_view_ != &transition_)
session_->fadeIn();
}
// manangement of sources
@@ -555,6 +552,7 @@ void Mixer::setView(View::Mode m)
case View::MIXING:
default:
current_view_ = &mixing_;
mixing_.setFading( session_->fading() );
break;
}

View File

@@ -58,10 +58,9 @@ void PickingVisitor::visit(Switch &n)
modelview_ = mv;
}
void PickingVisitor::visit(Primitive &n)
void PickingVisitor::visit(Primitive &)
{
// TODO: generic visitor for primitive with random shape ?
// by default, a Primitive is not interactive
}
void PickingVisitor::visit(Surface &n)
@@ -97,10 +96,20 @@ void PickingVisitor::visit(Surface &n)
}
}
void PickingVisitor::visit(Frame &n)
void PickingVisitor::visit(Disk &n)
{
// if (n.border())
// n.border()->accept(*this);
// discard if not visible or if not exactly one point given for picking
if (!n.visible_ || points_.size() != 1)
return;
// apply inverse transform to the point of interest
glm::vec4 P = glm::inverse(modelview_) * glm::vec4( points_[0], 1.f );
// test distance for picking from a single point
if ( glm::length(glm::vec2(P)) < 1.f )
// add this surface to the nodes picked
nodes_.push_back( std::pair(&n, glm::vec2(P)) );
}
void PickingVisitor::visit(Handles &n)
@@ -147,29 +156,6 @@ void PickingVisitor::visit(Handles &n)
}
void PickingVisitor::visit(LineSquare &)
{
// // apply inverse transform to the point of interest
// glm::vec4 P = glm::inverse(modelview_) * glm::vec4( point_A_, 0.f, 1.f );
// // lower left corner
// glm::vec3 LL = glm::vec3( -1.f, -1.f, 0.f );
// // up right corner
// glm::vec3 UR = glm::vec3( 1.f, 1.f, 0.f );
// // if P is over a line [LL UR] rectangle:
// // TODO
}
void PickingVisitor::visit(LineCircle &n)
{
// // apply inverse transform to the point of interest
// glm::vec4 P = glm::inverse(modelview_) * glm::vec4( point_A_, 0.f, 1.f );
// float r = glm::length( glm::vec2(P) );
// if ( r < 1.02 && r > 0.98)
// nodes_.push_back( std::pair(&n, glm::vec2(P)) );
}
void PickingVisitor::visit(Scene &n)
{

View File

@@ -7,6 +7,15 @@
#include "Visitor.h"
/**
* @brief The PickingVisitor class is used to
* capture which objects of a scene are located at the screen
* coordinate. Typically at mouse cursor coordinates for
* user interaction.
*
* Only a subset of interactive objects (surface and Decorations)
* are interactive.
*/
class PickingVisitor: public Visitor
{
std::vector<glm::vec3> points_;
@@ -26,11 +35,21 @@ public:
void visit(Switch& n) override;
void visit(Primitive& n) override;
/**
* @brief visit Surface : picking source rendering surface
* @param n
*/
void visit(Surface& n) override;
void visit(Frame& n) override;
/**
* @brief visit Handles : picking grabbers of source in geometry view
* @param n
*/
void visit(Handles& n) override;
void visit(LineSquare&) override;
void visit(LineCircle& n) override;
/**
* @brief visit Disk : picking grabber for mixing view
* @param n
*/
void visit(Disk& n) override;
};

View File

@@ -9,7 +9,7 @@
#include "Log.h"
Session::Session() : filename_(""), failedSource_(nullptr), active_(true)
Session::Session() : filename_(""), failedSource_(nullptr), active_(true), fading_target_(0.f)
{
config_[View::RENDERING] = new Group;
config_[View::RENDERING]->scale_ = render_.resolution();
@@ -69,6 +69,12 @@ void Session::update(float dt)
}
}
// apply fading (smooth dicotomic reaching)
float f = render_.fading();
if ( ABS_DIFF(f, fading_target_) > EPSILON) {
render_.setFading( f + ( fading_target_ - f ) / 2.f);
}
// update the scene tree
render_.update(dt);
@@ -152,20 +158,22 @@ void Session::setResolution(glm::vec3 resolution)
void Session::setFading(float f)
{
render_.setFading(f);
fading_target_ = CLAMP(f, 0.f, 1.f);
}
void Session::fadeIn() {
float f = render_.fading();
if ( f > EPSILON)
render_.setFading( f / 2.f);
}
void Session::fadeOut() {
float f = render_.fading();
if ( f < 1.f - EPSILON)
render_.setFading( f * 2.f);
}
//void Session::fadeIn() {
// float f = render_.fading();
// if ( f > EPSILON)
// render_.setFading( f / 2.f);
//}
//void Session::fadeOut() {
// float f = render_.fading();
// if ( f < 1.f - EPSILON)
// render_.setFading( f * 2.f);
//}
SourceList::iterator Session::begin()
{

View File

@@ -59,8 +59,7 @@ public:
// manipulate fading of output
void setFading(float f);
void fadeIn();
void fadeOut();
inline float fading() const { return fading_target_; }
// configuration for group nodes of views
inline Group *config (View::Mode m) const { return config_.at(m); }
@@ -77,7 +76,7 @@ protected:
std::map<View::Mode, Group*> config_;
bool active_;
std::list<Recorder *> recorders_;
float fading_target_;
};
#endif // SESSION_H

View File

@@ -428,20 +428,16 @@ void UserInterface::handleMouse()
// ask the view what was picked
picked = Mixer::manager().view()->pick(mousepos);
bool clear_selection = false;
// if nothing picked,
if ( picked.first == nullptr ) {
// unset current
Mixer::manager().unsetCurrentSource();
navigator.hidePannel();
// clear selection
Mixer::selection().clear();
clear_selection = true;
}
// something was picked
else {
// get if a source was picked
Source *s = Mixer::manager().findSource(picked.first);
if (s != nullptr) {
// CTRL + clic = multiple selection
if (keyboard_modifier_active) {
if ( !Mixer::selection().contains(s) )
@@ -455,14 +451,24 @@ void UserInterface::handleMouse()
}
}
}
// making the picked source the current one
Mixer::manager().setCurrentSource( s );
if (navigator.pannelVisible())
navigator.showPannelSource( Mixer::manager().indexCurrentSource() );
// indicate to view that an action can be initiated (e.g. grab)
Mixer::manager().view()->initiate();
Mixer::manager().view()->storeStatus();
}
// no source is selected
else
clear_selection = true;
}
if (clear_selection) {
// unset current
Mixer::manager().unsetCurrentSource();
navigator.hidePannel();
// clear selection
Mixer::selection().clear();
}
}
}
@@ -497,7 +503,7 @@ void UserInterface::handleMouse()
view_drag = Mixer::manager().view();
// indicate to view that an action can be initiated (e.g. grab)
Mixer::manager().view()->initiate();
Mixer::manager().view()->storeStatus();
}
// only operate if the view didn't change
@@ -513,6 +519,11 @@ void UserInterface::handleMouse()
c = Mixer::manager().view()->grab(*it, mouseclic[ImGuiMouseButton_Left], mousepos, picked);
setMouseCursor(io.MousePos, c);
}
else if ( picked.first != nullptr )
{
View::Cursor c = Mixer::manager().view()->grab(nullptr, mouseclic[ImGuiMouseButton_Left], mousepos, picked);
setMouseCursor(io.MousePos, c);
}
// Selection area
else {
ImGui::GetBackgroundDrawList()->AddRect(io.MouseClickedPos[ImGuiMouseButton_Left], io.MousePos,
@@ -527,6 +538,11 @@ void UserInterface::handleMouse()
}
}
}
else {
// cancel all operations on view when interacting on GUI
view_drag = nullptr;
mousedown = false;
}
}

106
View.cpp
View File

@@ -105,11 +105,12 @@ std::pair<Node *, glm::vec2> View::pick(glm::vec2 P)
// select top-most Node picked
pick = pv.picked().back();
Log::Info("picked %d", pick.first->id());
}
return pick;
}
void View::initiate()
void View::storeStatus()
{
for (auto sit = Mixer::manager().session()->begin();
sit != Mixer::manager().session()->end(); sit++){
@@ -227,19 +228,40 @@ MixingView::MixingView() : View(MIXING), limbo_scale_(1.3f)
restoreSettings();
// Mixing scene background
Mesh *disk = new Mesh("mesh/disk.ply");
disk->scale_ = glm::vec3(limbo_scale_, limbo_scale_, 1.f);
disk->shader()->color = glm::vec4( COLOR_LIMBO_CIRCLE, 0.6f );
scene.bg()->attach(disk);
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);
disk = new Mesh("mesh/disk.ply");
disk->setTexture(textureMixingQuadratic());
scene.bg()->attach(disk);
mixingCircle_ = new Mesh("mesh/disk.ply");
mixingCircle_->setTexture(textureMixingQuadratic());
mixingCircle_->shader()->color = glm::vec4( 1.f, 1.f, 1.f, 1.f );
scene.bg()->attach(mixingCircle_);
Mesh *circle = new Mesh("mesh/circle.ply");
circle->shader()->color = glm::vec4( COLOR_FRAME, 0.9f );
scene.bg()->attach(circle);
Symbol *dot = new Symbol(Symbol::POINT, glm::vec3(0.f, 1.f, 0.1f));
dot->scale_ = glm::vec3( 0.33f, 0.33f, 1.f);
dot->color = glm::vec4( COLOR_FRAME, 1.f );
scene.bg()->attach(dot);
tmp = new Mesh("mesh/circle.ply");
tmp->shader()->color = glm::vec4( COLOR_FRAME, 0.9f );
scene.bg()->attach(tmp);
// Mixing scene foreground
slider_root_ = new Group;
scene.fg()->attach(slider_root_);
tmp = new Mesh("mesh/disk.ply");
tmp->scale_ = glm::vec3(0.08f, 0.08f, 1.f);
tmp->translation_ = glm::vec3(0.0f, 1.0f, 0.f);
tmp->shader()->color = glm::vec4( COLOR_FRAME, 0.9f );
slider_root_->attach(tmp);
slider_ = new Disk();
slider_->scale_ = glm::vec3(0.075f, 0.075f, 1.f);
slider_->translation_ = glm::vec3(0.0f, 1.0f, 0.f);
slider_->color = glm::vec4( COLOR_SLIDER_CIRCLE, 1.0f );
slider_root_->attach(slider_);
}
@@ -275,7 +297,6 @@ void MixingView::centerSource(Source *s)
}
void MixingView::selectAll()
{
for(auto sit = Mixer::manager().session()->begin();
@@ -284,15 +305,63 @@ void MixingView::selectAll()
}
}
View::Cursor MixingView::grab (Source *s, glm::vec2 from, glm::vec2 to, std::pair<Node *, glm::vec2>)
void MixingView::setFading(float f)
{
if (!s)
return Cursor();
// reverse calculate angle from fading
float angle = SIGN(slider_root_->rotation_.z) * asin(f) * 2.f;
// move slider
slider_root_->rotation_.z = angle;
// visual feedback on mixing circle
f = 1.f - f;
mixingCircle_->shader()->color = glm::vec4(f, f, f, 1.f);
}
View::Cursor MixingView::grab (Source *s, glm::vec2 from, glm::vec2 to, std::pair<Node *, glm::vec2> pick)
{
// unproject
glm::vec3 gl_Position_from = Rendering::manager().unProject(from, scene.root()->transform_);
glm::vec3 gl_Position_to = Rendering::manager().unProject(to, scene.root()->transform_);
// No source is given
if (!s) {
// if interaction with slider
if (pick.first == slider_) {
// apply rotation to match angle with mouse cursor
float angle = glm::orientedAngle( glm::normalize(glm::vec2(0.f, 1.0)), glm::normalize(glm::vec2(gl_Position_to)));
// snap on 0 and PI angles
if ( ABS_DIFF(angle, 0.f) < 0.05)
angle = 0.f;
else if ( ABS_DIFF(angle, M_PI) < 0.05)
angle = M_PI;
// animate slider (rotation angle on its parent)
slider_root_->rotation_.z = angle;
// calculate fading from angle
float fading = sin( ABS(angle) * 0.5f);
// apply fading to session
Mixer::manager().session()->setFading(fading);
// visual feedback on mixing circle
fading = 1.f - fading;
mixingCircle_->shader()->color = glm::vec4(fading, fading, fading, 1.f);
// cursor feedback
std::ostringstream info;
info << "Global opacity " << int(fading * 100.0) << " %";
return Cursor(Cursor_Hand, info.str() );
}
// nothing to do
return Cursor();
}
//
// Interaction with source
//
// compute delta translation
s->group(mode_)->translation_ = s->stored_status_->translation_ + gl_Position_to - gl_Position_from;
@@ -459,7 +528,6 @@ void RenderView::draw()
frame_buffer_->end();
}
GeometryView::GeometryView() : View(GEOMETRY)
{
// read default settings
@@ -585,8 +653,6 @@ View::Cursor GeometryView::grab (Source *s, glm::vec2 from, glm::vec2 to, std::p
{
View::Cursor ret = Cursor();
std::ostringstream info;
// work on the given source
if (!s)
return ret;
@@ -607,6 +673,7 @@ View::Cursor GeometryView::grab (Source *s, glm::vec2 from, glm::vec2 to, std::p
// Log::Info(" ( %.1f, %.1f, %.1f ) ", S_to.x, S_to.y, S_to.z);
// which manipulation to perform?
std::ostringstream info;
if (pick.first) {
// picking on the resizing handles in the corners
if ( pick.first == s->handle_[Handles::RESIZE] ) {
@@ -1112,14 +1179,13 @@ View::Cursor TransitionView::grab (Source *s, glm::vec2 from, glm::vec2 to, std:
if (!s)
return Cursor();
std::ostringstream info;
// unproject
glm::vec3 gl_Position_from = Rendering::manager().unProject(from, scene.root()->transform_);
glm::vec3 gl_Position_to = Rendering::manager().unProject(to, scene.root()->transform_);
// compute delta translation
float d = s->stored_status_->translation_.x + gl_Position_to.x - gl_Position_from.x;
std::ostringstream info;
if (d > 0.2) {
s->group(View::TRANSITION)->translation_.x = 0.4;
info << "Open session";

26
View.h
View File

@@ -56,6 +56,7 @@ public:
virtual Cursor drag (glm::vec2, glm::vec2);
// grab a source provided a start and an end point in screen coordinates and the picking point
virtual void storeStatus();
virtual Cursor grab (Source*, glm::vec2, glm::vec2, std::pair<Node *, glm::vec2>) {
return Cursor();
}
@@ -65,7 +66,6 @@ public:
return Cursor();
}
virtual void initiate();
virtual void recenter();
// accessible scene
@@ -91,17 +91,23 @@ public:
void draw () override;
void zoom (float factor) override;
void centerSource(Source *) override;
void selectAll() override;
Cursor grab (Source *s, glm::vec2 from, glm::vec2 to, std::pair<Node *, glm::vec2>) override;
Cursor drag (glm::vec2, glm::vec2) override;
void setAlpha (Source *s);
inline float limboScale() { return limbo_scale_; }
void setFading (float f);
private:
uint textureMixingQuadratic();
float limbo_scale_;
Group *slider_root_;
class Disk *slider_;
class Mesh *mixingCircle_;
};
class RenderView : public View
@@ -132,13 +138,12 @@ public:
void draw () override;
void update (float dt) override;
void zoom (float factor) override;
std::pair<Node *, glm::vec2> pick(glm::vec2 P) override;
Cursor grab (Source *s, glm::vec2 from, glm::vec2 to, std::pair<Node *, glm::vec2> pick) override;
Cursor over (Source *s, glm::vec2 pos, std::pair<Node *, glm::vec2> pick) override;
Cursor drag (glm::vec2, glm::vec2) override;
// void select(glm::vec2, glm::vec2) override;
// class Box *selection_box_;
};
class LayerView : public View
@@ -148,6 +153,7 @@ public:
void update (float dt) override;
void zoom (float factor) override;
Cursor grab (Source *s, glm::vec2 from, glm::vec2 to, std::pair<Node *, glm::vec2> pick) override;
Cursor drag (glm::vec2, glm::vec2) override;
@@ -162,19 +168,19 @@ class TransitionView : public View
public:
TransitionView();
void attach(SessionSource *ts);
class Session *detach();
void play(bool open);
void draw () override;
void update (float dt) override;
void zoom (float factor) override;
std::pair<Node *, glm::vec2> pick(glm::vec2 P) override;
void selectAll() override;
std::pair<Node *, glm::vec2> pick(glm::vec2 P) override;
Cursor grab (Source *s, glm::vec2 from, glm::vec2 to, std::pair<Node *, glm::vec2> pick) override;
Cursor drag (glm::vec2, glm::vec2) override;
void attach(SessionSource *ts);
class Session *detach();
void play(bool open);
private:
class Surface *output_surface_;
class Mesh *mark_100ms_, *mark_1s_;

View File

@@ -19,6 +19,7 @@ class LineCircle;
class Mesh;
class Frame;
class Handles;
class Disk;
class MediaPlayer;
class Shader;
class ImageShader;
@@ -51,6 +52,7 @@ public:
virtual void visit (Mesh&) {}
virtual void visit (Frame&) {}
virtual void visit (Handles&) {}
virtual void visit (Disk&) {}
virtual void visit (MediaPlayer&) {}
virtual void visit (Shader&) {}
virtual void visit (ImageShader&) {}

View File

@@ -64,6 +64,7 @@
#define COLOR_TRANSITION_LINES 0.9f, 0.9f, 0.9f
#define COLOR_FRAME 0.8f, 0.f, 0.8f
#define COLOR_LIMBO_CIRCLE 0.16f, 0.16f, 0.16f
#define COLOR_SLIDER_CIRCLE 0.11f, 0.11f, 0.11f
// from glmixer
#define TEXTURE_REQUIRED_MAXIMUM 2048