work in progress - implementation of multiple sources selection and

manipulation
This commit is contained in:
brunoherbelin
2020-06-18 20:50:49 +02:00
parent da7ce52e2c
commit 21b28174e9
10 changed files with 211 additions and 162 deletions

View File

@@ -11,7 +11,7 @@
#include "Log.h" #include "Log.h"
Frame::Frame(Type type) : Node(), type_(type), side_(nullptr), top_(nullptr), shadow_(nullptr), square_(nullptr) Frame::Frame(CornerType corner, BorderType border, ShadowType shadow) : Node(), side_(nullptr), top_(nullptr), shadow_(nullptr), square_(nullptr)
{ {
static Mesh *shadows[3] = {nullptr}; static Mesh *shadows[3] = {nullptr};
if (shadows[0] == nullptr) { if (shadows[0] == nullptr) {
@@ -26,35 +26,69 @@ Frame::Frame(Type type) : Node(), type_(type), side_(nullptr), top_(nullptr), sh
frames[2] = new Mesh("mesh/border_large_round.ply"); frames[2] = new Mesh("mesh/border_large_round.ply");
frames[3] = new Mesh("mesh/border_large_top.ply"); frames[3] = new Mesh("mesh/border_large_top.ply");
} }
static LineSquare *sharpframe = new LineSquare( 3 ); static LineSquare *sharpframethin = new LineSquare( 3 );
static LineSquare *sharpframelarge = new LineSquare( 5 );
color = glm::vec4( 1.f, 1.f, 1.f, 1.f); if (corner == SHARP) {
switch (type) { if (border == LARGE)
case SHARP_LARGE: square_ = sharpframelarge;
square_ = sharpframe; else
square_ = sharpframethin;
}
else {
// Round corners
if (border == THIN) {
side_ = frames[0];
top_ = frames[1];
}
else{
side_ = frames[2];
top_ = frames[3];
}
}
switch (shadow) {
default:
case NONE:
break;
case GLOW:
shadow_ = shadows[0]; shadow_ = shadows[0];
break; break;
case SHARP_THIN: case DROP:
square_ = sharpframe;
break;
case ROUND_LARGE:
side_ = frames[2];
top_ = frames[3];
shadow_ = shadows[1]; shadow_ = shadows[1];
break; break;
default: case PERSPECTIVE:
case ROUND_THIN:
side_ = frames[0];
top_ = frames[1];
shadow_ = shadows[1];
break;
case ROUND_SHADOW:
side_ = frames[0];
top_ = frames[1];
shadow_ = shadows[2]; shadow_ = shadows[2];
break; break;
} }
// switch (type) {
// case SHARP_LARGE:
// square_ = sharpframe;
// shadow_ = shadows[0];
// break;
// case SHARP_THIN:
// square_ = sharpframe;
// break;
// case ROUND_LARGE:
// side_ = frames[2];
// top_ = frames[3];
// shadow_ = shadows[1];
// break;
// default:
// case ROUND_THIN:
// side_ = frames[0];
// top_ = frames[1];
// shadow_ = shadows[1];
// break;
// case ROUND_THIN_PERSPECTIVE:
// side_ = frames[0];
// top_ = frames[1];
// shadow_ = shadows[2];
// break;
// }
color = glm::vec4( 1.f, 1.f, 1.f, 1.f);
} }
Frame::~Frame() Frame::~Frame()
@@ -323,7 +357,7 @@ void Icon::accept(Visitor& v)
} }
Box::Box() SelectionBox::SelectionBox()
{ {
// color = glm::vec4( 1.f, 1.f, 1.f, 1.f); // color = glm::vec4( 1.f, 1.f, 1.f, 1.f);
color = glm::vec4( 1.f, 0.f, 0.f, 1.f); color = glm::vec4( 1.f, 0.f, 0.f, 1.f);
@@ -331,7 +365,7 @@ Box::Box()
} }
void Box::draw (glm::mat4 modelview, glm::mat4 projection) void SelectionBox::draw (glm::mat4 modelview, glm::mat4 projection)
{ {
if ( !initialized() ) { if ( !initialized() ) {
square_->init(); square_->init();

View File

@@ -12,20 +12,21 @@ class Frame : public Node
{ {
public: public:
typedef enum { ROUND_THIN = 0, ROUND_LARGE, SHARP_THIN, SHARP_LARGE, ROUND_SHADOW } Type; typedef enum { ROUND = 0, SHARP } CornerType;
Frame(Type type); typedef enum { THIN = 0, LARGE } BorderType;
typedef enum { NONE = 0, GLOW, DROP, PERSPECTIVE } ShadowType;
Frame(CornerType corner, BorderType border, ShadowType shadow);
~Frame(); ~Frame();
void update (float dt) override; void update (float dt) override;
void draw (glm::mat4 modelview, glm::mat4 projection) override; void draw (glm::mat4 modelview, glm::mat4 projection) override;
void accept (Visitor& v) override; void accept (Visitor& v) override;
Type type() const { return type_; }
Mesh *border() const { return side_; } Mesh *border() const { return side_; }
glm::vec4 color; glm::vec4 color;
protected: protected:
Type type_;
Mesh *side_; Mesh *side_;
Mesh *top_; Mesh *top_;
Mesh *shadow_; Mesh *shadow_;
@@ -71,10 +72,10 @@ protected:
Type type_; Type type_;
}; };
class Box : public Group class SelectionBox : public Group
{ {
public: public:
Box(); SelectionBox();
void draw (glm::mat4 modelview, glm::mat4 projection) override; void draw (glm::mat4 modelview, glm::mat4 projection) override;

View File

@@ -388,8 +388,9 @@ void Mixer::setCurrentSource(SourceList::iterator it)
if ( it != session_->end() ) { if ( it != session_->end() ) {
current_source_ = it; current_source_ = it;
current_source_index_ = session_->index(it); current_source_index_ = session_->index(it);
// add to selection // set selection if not already selected
selection().add(*it); if (!selection().contains(*it))
selection().set(*it);
// show status as current // show status as current
(*current_source_)->setMode(Source::CURRENT); (*current_source_)->setMode(Source::CURRENT);
} }
@@ -440,10 +441,17 @@ void Mixer::unsetCurrentSource()
{ {
// discard overlay for previously current source // discard overlay for previously current source
if ( current_source_ != session_->end() ) { if ( current_source_ != session_->end() ) {
// remove from selection // if (selection().size() > 1) {
selection().remove( *current_source_ );
// show status as normal // }
(*current_source_)->setMode(Source::NORMAL); // // current source is the sole selected source : unselect and
// else
{
// remove from selection
// selection().remove( *current_source_ );
// show status as normal
(*current_source_)->setMode(Source::ACTIVE);
}
} }
// deselect current source // deselect current source

View File

@@ -14,6 +14,31 @@ void Selection::add(Source *s)
s->setMode(Source::ACTIVE); s->setMode(Source::ACTIVE);
} }
void Selection::remove(Source *s)
{
SourceList::iterator it = find(s);
if (it != selection_.end()) {
selection_.erase(it);
s->setMode(Source::NORMAL);
}
}
void Selection::toggle(Source *s)
{
if (contains(s))
remove(s);
else
add(s);
}
void Selection::set(Source *s)
{
clear();
selection_.push_back(s);
s->setMode(Source::ACTIVE);
}
void Selection::set(SourceList l) void Selection::set(SourceList l)
{ {
clear(); clear();
@@ -41,15 +66,6 @@ void Selection::add(SourceList l)
selection_ = SourceList(result); selection_ = SourceList(result);
} }
void Selection::remove(Source *s)
{
SourceList::iterator it = find(s);
if (it != selection_.end()) {
selection_.erase(it);
s->setMode(Source::NORMAL);
}
}
void Selection::remove(SourceList l) void Selection::remove(SourceList l)
{ {
for(auto it = l.begin(); it != l.end(); it++) for(auto it = l.begin(); it != l.end(); it++)

View File

@@ -10,17 +10,19 @@ public:
Selection(); Selection();
void add (Source *s); void add (Source *s);
void add (SourceList l);
void remove (Source *s); void remove (Source *s);
void remove (SourceList l); void set (Source *s);
void toggle (Source *s);
void add (SourceList l);
void remove (SourceList l);
void set (SourceList l); void set (SourceList l);
void clear (); void clear ();
uint size ();
SourceList::iterator begin (); SourceList::iterator begin ();
SourceList::iterator end (); SourceList::iterator end ();
bool contains (Source *s); bool contains (Source *s);
uint size ();
protected: protected:
SourceList::iterator find (Source *s); SourceList::iterator find (Source *s);

View File

@@ -35,11 +35,11 @@ Source::Source() : initialized_(false), need_update_(true)
groups_[View::MIXING]->translation_ = glm::vec3(-1.f, 1.f, 0.f); groups_[View::MIXING]->translation_ = glm::vec3(-1.f, 1.f, 0.f);
frames_[View::MIXING] = new Switch; frames_[View::MIXING] = new Switch;
Frame *frame = new Frame(Frame::ROUND_THIN); Frame *frame = new Frame(Frame::ROUND, Frame::THIN, Frame::DROP);
frame->translation_.z = 0.1; frame->translation_.z = 0.1;
frame->color = glm::vec4( COLOR_DEFAULT_SOURCE, 0.9f); frame->color = glm::vec4( COLOR_DEFAULT_SOURCE, 0.9f);
frames_[View::MIXING]->attach(frame); frames_[View::MIXING]->attach(frame);
frame = new Frame(Frame::ROUND_LARGE); frame = new Frame(Frame::ROUND, Frame::LARGE, Frame::DROP);
frame->translation_.z = 0.01; frame->translation_.z = 0.01;
frame->color = glm::vec4( COLOR_HIGHLIGHT_SOURCE, 1.f); frame->color = glm::vec4( COLOR_HIGHLIGHT_SOURCE, 1.f);
frames_[View::MIXING]->attach(frame); frames_[View::MIXING]->attach(frame);
@@ -57,11 +57,11 @@ Source::Source() : initialized_(false), need_update_(true)
groups_[View::GEOMETRY]->visible_ = false; groups_[View::GEOMETRY]->visible_ = false;
frames_[View::GEOMETRY] = new Switch; frames_[View::GEOMETRY] = new Switch;
frame = new Frame(Frame::SHARP_THIN); frame = new Frame(Frame::SHARP, Frame::THIN, Frame::NONE);
frame->translation_.z = 0.1; frame->translation_.z = 0.1;
frame->color = glm::vec4( COLOR_DEFAULT_SOURCE, 0.7f); frame->color = glm::vec4( COLOR_DEFAULT_SOURCE, 0.7f);
frames_[View::GEOMETRY]->attach(frame); frames_[View::GEOMETRY]->attach(frame);
frame = new Frame(Frame::SHARP_LARGE); frame = new Frame(Frame::SHARP, Frame::LARGE, Frame::GLOW);
frame->translation_.z = 0.1; frame->translation_.z = 0.1;
frame->color = glm::vec4( COLOR_HIGHLIGHT_SOURCE, 1.f); frame->color = glm::vec4( COLOR_HIGHLIGHT_SOURCE, 1.f);
frames_[View::GEOMETRY]->attach(frame); frames_[View::GEOMETRY]->attach(frame);
@@ -70,22 +70,22 @@ Source::Source() : initialized_(false), need_update_(true)
overlays_[View::GEOMETRY] = new Group; overlays_[View::GEOMETRY] = new Group;
overlays_[View::GEOMETRY]->translation_.z = 0.15; overlays_[View::GEOMETRY]->translation_.z = 0.15;
overlays_[View::GEOMETRY]->visible_ = false; overlays_[View::GEOMETRY]->visible_ = false;
resize_handle_ = new Handles(Handles::RESIZE); handle_[Handles::RESIZE] = new Handles(Handles::RESIZE);
resize_handle_->color = glm::vec4( COLOR_HIGHLIGHT_SOURCE, 1.f); handle_[Handles::RESIZE]->color = glm::vec4( COLOR_HIGHLIGHT_SOURCE, 1.f);
resize_handle_->translation_.z = 0.1; handle_[Handles::RESIZE]->translation_.z = 0.1;
overlays_[View::GEOMETRY]->attach(resize_handle_); overlays_[View::GEOMETRY]->attach(handle_[Handles::RESIZE]);
resize_H_handle_ = new Handles(Handles::RESIZE_H); handle_[Handles::RESIZE_H] = new Handles(Handles::RESIZE_H);
resize_H_handle_->color = glm::vec4( COLOR_HIGHLIGHT_SOURCE, 1.f); handle_[Handles::RESIZE_H]->color = glm::vec4( COLOR_HIGHLIGHT_SOURCE, 1.f);
resize_H_handle_->translation_.z = 0.1; handle_[Handles::RESIZE_H]->translation_.z = 0.1;
overlays_[View::GEOMETRY]->attach(resize_H_handle_); overlays_[View::GEOMETRY]->attach(handle_[Handles::RESIZE_H]);
resize_V_handle_ = new Handles(Handles::RESIZE_V); handle_[Handles::RESIZE_V] = new Handles(Handles::RESIZE_V);
resize_V_handle_->color = glm::vec4( COLOR_HIGHLIGHT_SOURCE, 1.f); handle_[Handles::RESIZE_V]->color = glm::vec4( COLOR_HIGHLIGHT_SOURCE, 1.f);
resize_V_handle_->translation_.z = 0.1; handle_[Handles::RESIZE_V]->translation_.z = 0.1;
overlays_[View::GEOMETRY]->attach(resize_V_handle_); overlays_[View::GEOMETRY]->attach(handle_[Handles::RESIZE_V]);
rotate_handle_ = new Handles(Handles::ROTATE); handle_[Handles::ROTATE] = new Handles(Handles::ROTATE);
rotate_handle_->color = glm::vec4( COLOR_HIGHLIGHT_SOURCE, 1.f); handle_[Handles::ROTATE]->color = glm::vec4( COLOR_HIGHLIGHT_SOURCE, 1.f);
rotate_handle_->translation_.z = 0.1; handle_[Handles::ROTATE]->translation_.z = 0.1;
overlays_[View::GEOMETRY]->attach(rotate_handle_); overlays_[View::GEOMETRY]->attach(handle_[Handles::ROTATE]);
groups_[View::GEOMETRY]->attach(overlays_[View::GEOMETRY]); groups_[View::GEOMETRY]->attach(overlays_[View::GEOMETRY]);
// default layer nodes // default layer nodes
@@ -93,11 +93,11 @@ Source::Source() : initialized_(false), need_update_(true)
groups_[View::LAYER]->visible_ = false; groups_[View::LAYER]->visible_ = false;
frames_[View::LAYER] = new Switch; frames_[View::LAYER] = new Switch;
frame = new Frame(Frame::ROUND_SHADOW); frame = new Frame(Frame::ROUND, Frame::THIN, Frame::PERSPECTIVE);
frame->translation_.z = 0.1; frame->translation_.z = 0.1;
frame->color = glm::vec4( COLOR_DEFAULT_SOURCE, 0.8f); frame->color = glm::vec4( COLOR_DEFAULT_SOURCE, 0.8f);
frames_[View::LAYER]->attach(frame); frames_[View::LAYER]->attach(frame);
frame = new Frame(Frame::ROUND_LARGE); frame = new Frame(Frame::ROUND, Frame::LARGE, Frame::PERSPECTIVE);
frame->translation_.z = 0.1; frame->translation_.z = 0.1;
frame->color = glm::vec4( COLOR_HIGHLIGHT_SOURCE, 1.f); frame->color = glm::vec4( COLOR_HIGHLIGHT_SOURCE, 1.f);
frames_[View::LAYER]->attach(frame); frames_[View::LAYER]->attach(frame);
@@ -108,17 +108,21 @@ Source::Source() : initialized_(false), need_update_(true)
overlays_[View::LAYER]->visible_ = false; overlays_[View::LAYER]->visible_ = false;
groups_[View::LAYER]->attach(overlays_[View::LAYER]); groups_[View::LAYER]->attach(overlays_[View::LAYER]);
// will be associated to nodes later // create objects
stored_status_ = new Group;
// those will be associated to nodes later
blendingshader_ = new ImageShader; blendingshader_ = new ImageShader;
rendershader_ = new ImageProcessingShader; rendershader_ = new ImageProcessingShader;
renderbuffer_ = nullptr; renderbuffer_ = nullptr;
rendersurface_ = nullptr; rendersurface_ = nullptr;
} }
Source::~Source() Source::~Source()
{ {
// delete render objects // delete objects
delete stored_status_;
if (renderbuffer_) if (renderbuffer_)
delete renderbuffer_; delete renderbuffer_;
@@ -133,8 +137,10 @@ Source::~Source()
frames_.clear(); frames_.clear();
overlays_.clear(); overlays_.clear();
// inform clones that they lost their origin
for (auto it = clones_.begin(); it != clones_.end(); it++) for (auto it = clones_.begin(); it != clones_.end(); it++)
(*it)->origin_ = nullptr; (*it)->origin_ = nullptr;
} }
void Source::setName (const std::string &name) void Source::setName (const std::string &name)

View File

@@ -25,7 +25,9 @@ typedef std::list<CloneSource *> CloneList;
class Source class Source
{ {
friend class View; friend class View;
friend class MixingView;
friend class GeometryView; friend class GeometryView;
friend class LayerView;
public: public:
// create a source and add it to the list // create a source and add it to the list
@@ -104,6 +106,7 @@ public:
std::string _n; std::string _n;
}; };
protected: protected:
// name // name
std::string name_; std::string name_;
@@ -137,11 +140,12 @@ protected:
// overlays and frames to be displayed on top of source // overlays and frames to be displayed on top of source
std::map<View::Mode, Group*> overlays_; std::map<View::Mode, Group*> overlays_;
std::map<View::Mode, Switch*> frames_; std::map<View::Mode, Switch*> frames_;
Handles *resize_handle_, *resize_H_handle_, *resize_V_handle_, *rotate_handle_; Handles *handle_[4];
// update // update
bool need_update_; bool need_update_;
float dt_; float dt_;
Group *stored_status_;
// clones // clones
CloneList clones_; CloneList clones_;

View File

@@ -385,33 +385,28 @@ void UserInterface::handleMouse()
{ {
// grab current source // grab current source
View::Cursor c = Mixer::manager().currentView()->grab( mouseclic[ImGuiMouseButton_Left], mousepos, current, picked); // View::Cursor c = Mixer::manager().currentView()->grab(current, mouseclic[ImGuiMouseButton_Left], mousepos, picked);
// setMouseCursor(c);
// grab selected sources (current is also selected by default)
View::Cursor c = View::Cursor_Arrow;
for (auto it = Mixer::selection().begin(); it != Mixer::selection().end(); it++)
c = Mixer::manager().currentView()->grab(*it, mouseclic[ImGuiMouseButton_Left], mousepos, picked);
setMouseCursor(c); setMouseCursor(c);
// if ( Mixer::selection().contains(current)) {
// for (auto it = Mixer::selection().begin(); it != Mixer::selection().end(); it++)
// c = Mixer::manager().currentView()->grab( mouseclic[ImGuiMouseButton_Left], mousepos, *it, picked);
// }
} }
else { 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 // Selection area
ImGui::GetBackgroundDrawList()->AddRect(io.MouseClickedPos[ImGuiMouseButton_Left], io.MousePos, ImGui::GetBackgroundDrawList()->AddRect(io.MouseClickedPos[ImGuiMouseButton_Left], io.MousePos,
ImGui::GetColorU32(ImGuiCol_ResizeGripHovered)); ImGui::GetColorU32(ImGuiCol_ResizeGripHovered));
ImGui::GetBackgroundDrawList()->AddRectFilled(io.MouseClickedPos[ImGuiMouseButton_Left], io.MousePos, ImGui::GetBackgroundDrawList()->AddRectFilled(io.MouseClickedPos[ImGuiMouseButton_Left], io.MousePos,
ImGui::GetColorU32(ImGuiCol_ResizeGripHovered, 0.3f)); ImGui::GetColorU32(ImGuiCol_ResizeGripHovered, 0.3f));
// TODO Multiple sources selection // Bounding box multiple sources selection
Mixer::manager().currentView()->select(mouseclic[ImGuiMouseButton_Left], mousepos); Mixer::manager().currentView()->select(mouseclic[ImGuiMouseButton_Left], mousepos);
} }
} }
else if ( ImGui::IsMouseDown(ImGuiMouseButton_Left) ) { else if ( ImGui::IsMouseClicked(ImGuiMouseButton_Left) ) {
// get coordinate in world coordinate of mouse cursor
// glm::vec3 point = Rendering::manager().unProject(mousepos);
// ask the view what was picked // ask the view what was picked
picked = Mixer::manager().currentView()->pick(mousepos); picked = Mixer::manager().currentView()->pick(mousepos);
@@ -427,22 +422,24 @@ void UserInterface::handleMouse()
else { else {
// get if a source was picked // get if a source was picked
Source *s = Mixer::manager().findSource(picked.first); Source *s = Mixer::manager().findSource(picked.first);
if (s != nullptr) {
if (keyboard_modifier_active) { if (keyboard_modifier_active) {
// selection // selection
Mixer::selection().add( s ); Mixer::selection().toggle( s ); // TODO toggle selection
} }
// make current // make current
else { else {
Mixer::manager().setCurrentSource( picked.first ); Mixer::manager().setCurrentSource( s );
if (navigator.pannelVisible()) if (navigator.pannelVisible())
navigator.showPannelSource( Mixer::manager().indexCurrentSource() ); navigator.showPannelSource( Mixer::manager().indexCurrentSource() );
}
// indicate to view that an action can be initiated (e.g. grab)
Mixer::manager().currentView()->initiate();
} }
} }
// TODO deselect if current source is not in selection
// Mixer::manager().currentView()->deselect();
} }
else if ( ImGui::IsMouseReleased(ImGuiMouseButton_Left) ) else if ( ImGui::IsMouseReleased(ImGuiMouseButton_Left) )
{ {

View File

@@ -104,6 +104,15 @@ std::pair<Node *, glm::vec2> View::pick(glm::vec2 P)
return pick; return pick;
} }
void View::initiate()
{
for (auto sit = Mixer::manager().session()->begin();
sit != Mixer::manager().session()->end(); sit++){
(*sit)->stored_status_->copyTransform((*sit)->group(mode_));
}
}
void View::select(glm::vec2 A, glm::vec2 B) void View::select(glm::vec2 A, glm::vec2 B)
{ {
// unproject mouse coordinate into scene coordinates // unproject mouse coordinate into scene coordinates
@@ -180,27 +189,17 @@ void MixingView::centerSource(Source *s)
} }
View::Cursor MixingView::grab (glm::vec2 from, glm::vec2 to, Source *s, std::pair<Node *, glm::vec2>) View::Cursor MixingView::grab (Source *s, glm::vec2 from, glm::vec2 to, std::pair<Node *, glm::vec2>)
{ {
if (!s) if (!s)
return Cursor(); return Cursor();
Group *sourceNode = s->group(mode_);
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 = sourceNode->translation_;
}
// unproject // unproject
glm::vec3 gl_Position_from = Rendering::manager().unProject(from, scene.root()->transform_); glm::vec3 gl_Position_from = Rendering::manager().unProject(from, scene.root()->transform_);
glm::vec3 gl_Position_to = Rendering::manager().unProject(to, scene.root()->transform_); glm::vec3 gl_Position_to = Rendering::manager().unProject(to, scene.root()->transform_);
// compute delta translation // compute delta translation
sourceNode->translation_ = start_translation + gl_Position_to - gl_Position_from; s->group(mode_)->translation_ = s->stored_status_->translation_ + gl_Position_to - gl_Position_from;
// request update // request update
s->touch(); s->touch();
@@ -330,7 +329,7 @@ GeometryView::GeometryView() : View(GEOMETRY)
Surface *rect = new Surface; Surface *rect = new Surface;
scene.bg()->attach(rect); scene.bg()->attach(rect);
Frame *border = new Frame(Frame::SHARP_THIN); Frame *border = new Frame(Frame::SHARP, Frame::THIN, Frame::NONE);
border->color = glm::vec4( COLOR_FRAME, 1.f ); border->color = glm::vec4( COLOR_FRAME, 1.f );
scene.fg()->attach(border); scene.fg()->attach(border);
@@ -425,7 +424,7 @@ std::pair<Node *, glm::vec2> GeometryView::pick(glm::vec2 P)
return pick; return pick;
} }
View::Cursor GeometryView::grab (glm::vec2 from, glm::vec2 to, Source *s, std::pair<Node *, glm::vec2> pick) View::Cursor GeometryView::grab (Source *s, glm::vec2 from, glm::vec2 to, std::pair<Node *, glm::vec2> pick)
{ {
View::Cursor ret = Cursor(); View::Cursor ret = Cursor();
@@ -436,18 +435,6 @@ View::Cursor GeometryView::grab (glm::vec2 from, glm::vec2 to, Source *s, std::p
return ret; return ret;
Group *sourceNode = s->group(mode_); Group *sourceNode = s->group(mode_);
// remember source transform at moment of clic at position 'from'
static glm::vec2 start_clic_position = glm::vec2(0.f);
static glm::vec3 start_translation = glm::vec3(0.f);
static glm::vec3 start_scale = glm::vec3(1.f);
static glm::vec3 start_rotation = glm::vec3(0.f);
if ( start_clic_position != from ) {
start_clic_position = from;
start_translation = sourceNode->translation_;
start_scale = sourceNode->scale_;
start_rotation = sourceNode->rotation_;
}
// grab coordinates in scene-View reference frame // grab coordinates in scene-View reference frame
glm::vec3 gl_Position_from = Rendering::manager().unProject(from, scene.root()->transform_); glm::vec3 gl_Position_from = Rendering::manager().unProject(from, scene.root()->transform_);
glm::vec3 gl_Position_to = Rendering::manager().unProject(to, scene.root()->transform_); glm::vec3 gl_Position_to = Rendering::manager().unProject(to, scene.root()->transform_);
@@ -465,10 +452,10 @@ View::Cursor GeometryView::grab (glm::vec2 from, glm::vec2 to, Source *s, std::p
// which manipulation to perform? // which manipulation to perform?
if (pick.first) { if (pick.first) {
// picking on the resizing handles in the corners // picking on the resizing handles in the corners
if ( pick.first == s->resize_handle_ ) { if ( pick.first == s->handle_[Handles::RESIZE] ) {
if (UserInterface::manager().keyboardModifier()) if (UserInterface::manager().keyboardModifier())
S_resize.y = S_resize.x; S_resize.y = S_resize.x;
sourceNode->scale_ = start_scale * S_resize; sourceNode->scale_ = s->stored_status_->scale_ * S_resize;
// Log::Info(" resize ( %.1f, %.1f ) ", S_resize.x, S_resize.y); // Log::Info(" resize ( %.1f, %.1f ) ", S_resize.x, S_resize.y);
// glm::vec3 factor = S_resize * glm::vec3(0.5f, 0.5f, 1.f); // glm::vec3 factor = S_resize * glm::vec3(0.5f, 0.5f, 1.f);
@@ -486,8 +473,8 @@ View::Cursor GeometryView::grab (glm::vec2 from, glm::vec2 to, Source *s, std::p
info << " x " << sourceNode->scale_.y; info << " x " << sourceNode->scale_.y;
} }
// picking on the resizing handles left or right // picking on the resizing handles left or right
else if ( pick.first == s->resize_H_handle_ ) { else if ( pick.first == s->handle_[Handles::RESIZE_H] ) {
sourceNode->scale_ = start_scale * glm::vec3(S_resize.x, 1.f, 1.f); sourceNode->scale_ = s->stored_status_->scale_ * glm::vec3(S_resize.x, 1.f, 1.f);
if (UserInterface::manager().keyboardModifier()) if (UserInterface::manager().keyboardModifier())
sourceNode->scale_.x = float( int( sourceNode->scale_.x * 10.f ) ) / 10.f; sourceNode->scale_.x = float( int( sourceNode->scale_.x * 10.f ) ) / 10.f;
@@ -496,8 +483,8 @@ View::Cursor GeometryView::grab (glm::vec2 from, glm::vec2 to, Source *s, std::p
info << " x " << sourceNode->scale_.y; info << " x " << sourceNode->scale_.y;
} }
// picking on the resizing handles top or bottom // picking on the resizing handles top or bottom
else if ( pick.first == s->resize_V_handle_ ) { else if ( pick.first == s->handle_[Handles::RESIZE_V] ) {
sourceNode->scale_ = start_scale * glm::vec3(1.f, S_resize.y, 1.f); sourceNode->scale_ = s->stored_status_->scale_ * glm::vec3(1.f, S_resize.y, 1.f);
if (UserInterface::manager().keyboardModifier()) if (UserInterface::manager().keyboardModifier())
sourceNode->scale_.y = float( int( sourceNode->scale_.y * 10.f ) ) / 10.f; sourceNode->scale_.y = float( int( sourceNode->scale_.y * 10.f ) ) / 10.f;
@@ -506,15 +493,15 @@ View::Cursor GeometryView::grab (glm::vec2 from, glm::vec2 to, Source *s, std::p
info << " x " << sourceNode->scale_.y; info << " x " << sourceNode->scale_.y;
} }
// picking on the rotating handle // picking on the rotating handle
else if ( pick.first == s->rotate_handle_ ) { else if ( pick.first == s->handle_[Handles::ROTATE] ) {
// rotation center to center of source // rotation center to center of source
glm::mat4 T = glm::translate(glm::identity<glm::mat4>(), start_translation); glm::mat4 T = glm::translate(glm::identity<glm::mat4>(), s->stored_status_->translation_);
S_from = glm::inverse(T) * glm::vec4( gl_Position_from, 1.f ); S_from = glm::inverse(T) * glm::vec4( gl_Position_from, 1.f );
S_to = glm::inverse(T) * glm::vec4( gl_Position_to, 1.f ); S_to = glm::inverse(T) * glm::vec4( gl_Position_to, 1.f );
// angle // angle
float angle = glm::orientedAngle( glm::normalize(glm::vec2(S_from)), glm::normalize(glm::vec2(S_to))); float angle = glm::orientedAngle( glm::normalize(glm::vec2(S_from)), glm::normalize(glm::vec2(S_to)));
// apply rotation on Z axis // apply rotation on Z axis
sourceNode->rotation_ = start_rotation + glm::vec3(0.f, 0.f, angle); sourceNode->rotation_ = s->stored_status_->rotation_ + glm::vec3(0.f, 0.f, angle);
int degrees = int( glm::degrees(sourceNode->rotation_.z) ); int degrees = int( glm::degrees(sourceNode->rotation_.z) );
if (UserInterface::manager().keyboardModifier()) { if (UserInterface::manager().keyboardModifier()) {
@@ -527,7 +514,7 @@ View::Cursor GeometryView::grab (glm::vec2 from, glm::vec2 to, Source *s, std::p
} }
// picking anywhere but on a handle: user wants to move the source // picking anywhere but on a handle: user wants to move the source
else { else {
sourceNode->translation_ = start_translation + gl_Position_to - gl_Position_from; sourceNode->translation_ = s->stored_status_->translation_ + gl_Position_to - gl_Position_from;
if (UserInterface::manager().keyboardModifier()) { if (UserInterface::manager().keyboardModifier()) {
sourceNode->translation_.x = float( int( sourceNode->translation_.x * 10.f ) ) / 10.f; sourceNode->translation_.x = float( int( sourceNode->translation_.x * 10.f ) ) / 10.f;
@@ -539,13 +526,13 @@ View::Cursor GeometryView::grab (glm::vec2 from, glm::vec2 to, Source *s, std::p
info << ", " << sourceNode->translation_.y << ")"; info << ", " << sourceNode->translation_.y << ")";
} }
} }
// don't have a handle, we can only move the source // // don't have a handle, we can only move the source
else { // else {
sourceNode->translation_ = start_translation + gl_Position_to - gl_Position_from; // sourceNode->translation_ = start_translation + gl_Position_to - gl_Position_from;
ret.type = Cursor_ResizeAll; // ret.type = Cursor_ResizeAll;
info << "Position (" << std::fixed << std::setprecision(3) << sourceNode->translation_.x; // info << "Position (" << std::fixed << std::setprecision(3) << sourceNode->translation_.x;
info << ", " << sourceNode->translation_.y << ")"; // info << ", " << sourceNode->translation_.y << ")";
} // }
// request update // request update
s->touch(); s->touch();
@@ -554,7 +541,7 @@ View::Cursor GeometryView::grab (glm::vec2 from, glm::vec2 to, Source *s, std::p
return ret; return ret;
} }
View::Cursor GeometryView::over (glm::vec2, Source*, std::pair<Node *, glm::vec2>) View::Cursor GeometryView::over (Source*, glm::vec2, std::pair<Node *, glm::vec2>)
{ {
View::Cursor ret = Cursor_Arrow; View::Cursor ret = Cursor_Arrow;
@@ -581,7 +568,7 @@ LayerView::LayerView() : View(LAYER), aspect_ratio(1.f)
persp->translation_.z = -0.1f; persp->translation_.z = -0.1f;
scene.bg()->attach(persp); scene.bg()->attach(persp);
Frame *border = new Frame(Frame::ROUND_SHADOW); Frame *border = new Frame(Frame::ROUND, Frame::THIN, Frame::PERSPECTIVE);
border->color = glm::vec4( COLOR_FRAME, 0.7f ); border->color = glm::vec4( COLOR_FRAME, 0.7f );
scene.bg()->attach(border); scene.bg()->attach(border);
} }
@@ -652,25 +639,17 @@ float LayerView::setDepth(Source *s, float d)
} }
View::Cursor LayerView::grab (glm::vec2 from, glm::vec2 to, Source *s, std::pair<Node *, glm::vec2> pick) View::Cursor LayerView::grab (Source *s, glm::vec2 from, glm::vec2 to, std::pair<Node *, glm::vec2> pick)
{ {
if (!s) if (!s)
return Cursor(); return Cursor();
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 = s->group(mode_)->translation_;
}
// unproject // unproject
glm::vec3 gl_Position_from = Rendering::manager().unProject(from, scene.root()->transform_); glm::vec3 gl_Position_from = Rendering::manager().unProject(from, scene.root()->transform_);
glm::vec3 gl_Position_to = Rendering::manager().unProject(to, scene.root()->transform_); glm::vec3 gl_Position_to = Rendering::manager().unProject(to, scene.root()->transform_);
// compute delta translation // compute delta translation
glm::vec3 dest_translation = start_translation + gl_Position_to - gl_Position_from; glm::vec3 dest_translation = s->stored_status_->translation_ + gl_Position_to - gl_Position_from;
// apply change // apply change
float d = setDepth( s, MAX( -dest_translation.x, 0.f) ); float d = setDepth( s, MAX( -dest_translation.x, 0.f) );

14
View.h
View File

@@ -53,15 +53,17 @@ public:
virtual Cursor drag (glm::vec2, glm::vec2); virtual Cursor drag (glm::vec2, glm::vec2);
// grab a source provided a start and an end point in screen coordinates and the picking point // grab a source provided a start and an end point in screen coordinates and the picking point
virtual Cursor grab (glm::vec2, glm::vec2, Source*, std::pair<Node *, glm::vec2>) { virtual Cursor grab (Source*, glm::vec2, glm::vec2, std::pair<Node *, glm::vec2>) {
return Cursor(); return Cursor();
} }
// test mouse over provided a point in screen coordinates and the picking point // test mouse over provided a point in screen coordinates and the picking point
virtual Cursor over (glm::vec2, Source*, std::pair<Node *, glm::vec2>) { virtual Cursor over (Source*, glm::vec2, std::pair<Node *, glm::vec2>) {
return Cursor(); return Cursor();
} }
virtual void initiate();
virtual void restoreSettings(); virtual void restoreSettings();
virtual void saveSettings(); virtual void saveSettings();
@@ -84,7 +86,7 @@ public:
void zoom (float factor) override; void zoom (float factor) override;
void centerSource(Source *) override; void centerSource(Source *) override;
Cursor grab (glm::vec2 from, glm::vec2 to, Source *s, std::pair<Node *, glm::vec2>) override; Cursor grab (Source *s, glm::vec2 from, glm::vec2 to, std::pair<Node *, glm::vec2>) override;
void setAlpha (Source *s); void setAlpha (Source *s);
@@ -117,8 +119,8 @@ public:
void update (float dt) override; void update (float dt) override;
void zoom (float factor) override; void zoom (float factor) override;
std::pair<Node *, glm::vec2> pick(glm::vec2 P) override; std::pair<Node *, glm::vec2> pick(glm::vec2 P) override;
Cursor grab (glm::vec2 from, glm::vec2 to, Source *s, std::pair<Node *, glm::vec2> pick) override; Cursor grab (Source *s, glm::vec2 from, glm::vec2 to, std::pair<Node *, glm::vec2> pick) override;
Cursor over (glm::vec2, Source*, std::pair<Node *, glm::vec2>) override; Cursor over (Source *s, glm::vec2 pos, std::pair<Node *, glm::vec2> pick) override;
// void select(glm::vec2, glm::vec2) override; // void select(glm::vec2, glm::vec2) override;
// class Box *selection_box_; // class Box *selection_box_;
@@ -131,7 +133,7 @@ public:
void update (float dt) override; void update (float dt) override;
void zoom (float factor) override; void zoom (float factor) override;
Cursor grab (glm::vec2 from, glm::vec2 to, Source *s, std::pair<Node *, glm::vec2> pick) override; Cursor grab (Source *s, glm::vec2 from, glm::vec2 to, std::pair<Node *, glm::vec2> pick) override;
float setDepth (Source *, float d = -1.f); float setDepth (Source *, float d = -1.f);