mirror of
https://github.com/brunoherbelin/vimix.git
synced 2025-12-12 02:40:00 +01:00
First operational version of AppearanceView. Cleanup of symbols for
sources and other bugfix.
This commit is contained in:
@@ -330,10 +330,8 @@ DeviceSource::DeviceSource() : StreamSource()
|
||||
// create stream
|
||||
stream_ = new Stream;
|
||||
|
||||
// set icons
|
||||
overlays_[View::MIXING]->attach( new Symbol(Symbol::CAMERA, glm::vec3(0.8f, 0.8f, 0.01f)) );
|
||||
overlays_[View::LAYER]->attach( new Symbol(Symbol::CAMERA, glm::vec3(0.8f, 0.8f, 0.01f)) );
|
||||
overlays_[View::APPEARANCE]->attach( new Symbol(Symbol::CAMERA, glm::vec3(1.1f, 0.9f, 0.01f)) );
|
||||
// set symbol
|
||||
symbol_ = new Symbol(Symbol::CAMERA, glm::vec3(0.8f, 0.8f, 0.01f));
|
||||
}
|
||||
|
||||
DeviceSource::~DeviceSource()
|
||||
|
||||
@@ -34,7 +34,7 @@ void GarbageVisitor::visit(Node &n)
|
||||
|
||||
// take the node out of the Tree
|
||||
if (current_)
|
||||
current_->detatch(&n);
|
||||
current_->detach(&n);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -77,21 +77,15 @@ void MediaSource::init()
|
||||
float height = float(mediaplayer_->width()) / mediaplayer_->aspectRatio();
|
||||
FrameBuffer *renderbuffer = new FrameBuffer(mediaplayer_->width(), (uint)height, true);
|
||||
|
||||
// icon in mixing view
|
||||
if (mediaplayer_->isImage())
|
||||
symbol_ = new Symbol(Symbol::IMAGE, glm::vec3(0.8f, 0.8f, 0.01f));
|
||||
else
|
||||
symbol_ = new Symbol(Symbol::VIDEO, glm::vec3(0.8f, 0.8f, 0.01f));
|
||||
|
||||
// set the renderbuffer of the source and attach rendering nodes
|
||||
attach(renderbuffer);
|
||||
|
||||
// icon in mixing view
|
||||
if (mediaplayer_->isImage()) {
|
||||
overlays_[View::MIXING]->attach( new Symbol(Symbol::IMAGE, glm::vec3(0.8f, 0.8f, 0.01f)) );
|
||||
overlays_[View::LAYER]->attach( new Symbol(Symbol::IMAGE, glm::vec3(0.8f, 0.8f, 0.01f)) );
|
||||
overlays_[View::APPEARANCE]->attach( new Symbol(Symbol::IMAGE, glm::vec3(1.1f, 0.9f, 0.01f)) );
|
||||
}
|
||||
else {
|
||||
overlays_[View::MIXING]->attach( new Symbol(Symbol::VIDEO, glm::vec3(0.8f, 0.8f, 0.01f)) );
|
||||
overlays_[View::LAYER]->attach( new Symbol(Symbol::VIDEO, glm::vec3(0.8f, 0.8f, 0.01f)) );
|
||||
overlays_[View::APPEARANCE]->attach( new Symbol(Symbol::VIDEO, glm::vec3(1.1f, 0.9f, 0.01f)) );
|
||||
}
|
||||
|
||||
// done init
|
||||
initialized_ = true;
|
||||
Log::Info("Source '%s' linked to Media %s.", name().c_str(), std::to_string(mediaplayer_->id()).c_str());
|
||||
|
||||
12
Mixer.cpp
12
Mixer.cpp
@@ -450,11 +450,11 @@ void Mixer::detach(Source *s)
|
||||
// in case it was selected..
|
||||
selection().remove(s);
|
||||
// detach from views
|
||||
mixing_.scene.ws()->detatch( s->group(View::MIXING) );
|
||||
geometry_.scene.ws()->detatch( s->group(View::GEOMETRY) );
|
||||
layer_.scene.ws()->detatch( s->group(View::LAYER) );
|
||||
appearance_.scene.ws()->detatch( s->group(View::APPEARANCE) );
|
||||
transition_.scene.ws()->detatch( s->group(View::TRANSITION) );
|
||||
mixing_.scene.ws()->detach( s->group(View::MIXING) );
|
||||
geometry_.scene.ws()->detach( s->group(View::GEOMETRY) );
|
||||
layer_.scene.ws()->detach( s->group(View::LAYER) );
|
||||
appearance_.scene.ws()->detach( s->group(View::APPEARANCE) );
|
||||
transition_.scene.ws()->detach( s->group(View::TRANSITION) );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -493,7 +493,7 @@ void Mixer::uncover(Source *s)
|
||||
if ( it != stash_.end() ) {
|
||||
stash_.erase(it);
|
||||
|
||||
mixing_.scene.bg()->detatch( s->group(View::MIXING) );
|
||||
mixing_.scene.bg()->detach( s->group(View::MIXING) );
|
||||
attach(s);
|
||||
session_->addSource(s);
|
||||
}
|
||||
|
||||
@@ -273,10 +273,9 @@ NetworkSource::NetworkSource() : StreamSource()
|
||||
// create stream
|
||||
stream_ = (Stream *) new NetworkStream;
|
||||
|
||||
// set icons
|
||||
overlays_[View::MIXING]->attach( new Symbol(Symbol::SHARE, glm::vec3(0.8f, 0.8f, 0.01f)) );
|
||||
overlays_[View::LAYER]->attach( new Symbol(Symbol::SHARE, glm::vec3(0.8f, 0.8f, 0.01f)) );
|
||||
overlays_[View::APPEARANCE]->attach( new Symbol(Symbol::SHARE, glm::vec3(1.1f, 0.9f, 0.01f)) );
|
||||
// set symbol
|
||||
symbol_ = new Symbol(Symbol::SHARE, glm::vec3(0.8f, 0.8f, 0.01f));
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -133,10 +133,8 @@ PatternSource::PatternSource() : StreamSource()
|
||||
// create stream
|
||||
stream_ = (Stream *) new Pattern;
|
||||
|
||||
// set icons
|
||||
overlays_[View::MIXING]->attach( new Symbol(Symbol::PATTERN, glm::vec3(0.8f, 0.8f, 0.01f)) );
|
||||
overlays_[View::LAYER]->attach( new Symbol(Symbol::PATTERN, glm::vec3(0.8f, 0.8f, 0.01f)) );
|
||||
overlays_[View::APPEARANCE]->attach( new Symbol(Symbol::PATTERN, glm::vec3(1.1f, 0.9f, 0.01f)) );
|
||||
// set symbol
|
||||
symbol_ = new Symbol(Symbol::PATTERN, glm::vec3(0.8f, 0.8f, 0.01f));
|
||||
}
|
||||
|
||||
void PatternSource::setPattern(uint type, glm::ivec2 resolution)
|
||||
|
||||
17
Resource.cpp
17
Resource.cpp
@@ -59,6 +59,23 @@ uint Resource::getTextureWhite()
|
||||
return tex_index_white;
|
||||
}
|
||||
|
||||
uint Resource::getTextureTransparent()
|
||||
{
|
||||
static uint tex_index_transparent = 0;
|
||||
|
||||
// generate texture (once)
|
||||
if (tex_index_transparent == 0) {
|
||||
glGenTextures(1, &tex_index_transparent);
|
||||
glBindTexture( GL_TEXTURE_2D, tex_index_transparent);
|
||||
unsigned char clearColor[4] = {0, 0, 0, 0};
|
||||
// texture with one black pixel
|
||||
glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 1, 1);
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, clearColor);
|
||||
}
|
||||
|
||||
return tex_index_transparent;
|
||||
}
|
||||
|
||||
const char *Resource::getData(const std::string& path, size_t* out_file_size){
|
||||
|
||||
auto fs = cmrc::vmix::get_filesystem();
|
||||
|
||||
@@ -22,12 +22,15 @@ namespace Resource
|
||||
// Returns the OpenGL generated Texture index
|
||||
uint getTextureImage(const std::string& path, float *aspect_ratio = nullptr);
|
||||
|
||||
// Returns the OpenGL generated Texture index for an empty 1x1 black transparent pixel texture
|
||||
// Returns the OpenGL generated Texture index for an empty 1x1 black opaque pixel texture
|
||||
uint getTextureBlack();
|
||||
|
||||
// Returns the OpenGL generated Texture index for an empty 1x1 white opaque pixel texture
|
||||
uint getTextureWhite();
|
||||
|
||||
// Returns the OpenGL generated Texture index for an empty 1x1 back transparent pixel texture
|
||||
uint getTextureTransparent();
|
||||
|
||||
// Generic access to pointer to data
|
||||
const char *getData(const std::string& path, size_t* out_file_size);
|
||||
|
||||
|
||||
@@ -228,8 +228,10 @@ void Group::clear()
|
||||
|
||||
void Group::attach(Node *child)
|
||||
{
|
||||
if (child != nullptr) {
|
||||
children_.insert(child);
|
||||
child->refcount_++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -242,8 +244,9 @@ void Group::sort()
|
||||
children_.swap(ordered_children);
|
||||
}
|
||||
|
||||
void Group::detatch(Node *child)
|
||||
void Group::detach(Node *child)
|
||||
{
|
||||
if (child != nullptr) {
|
||||
// find the node with this id, and erase it out of the list of children
|
||||
// NB: do NOT delete with remove : this takes all nodes with same depth (i.e. equal depth in set)
|
||||
NodeSet::iterator it = std::find_if(children_.begin(), children_.end(), hasId(child->id()));
|
||||
@@ -252,7 +255,7 @@ void Group::detatch(Node *child)
|
||||
children_.erase(it);
|
||||
child->refcount_--;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void Group::update( float dt )
|
||||
|
||||
2
Scene.h
2
Scene.h
@@ -173,7 +173,7 @@ public:
|
||||
// container
|
||||
void clear();
|
||||
void attach (Node *child);
|
||||
void detatch (Node *child);
|
||||
void detach (Node *child);
|
||||
inline uint numChildren () const { return children_.size(); }
|
||||
|
||||
// Group specific access to its Nodes
|
||||
|
||||
@@ -132,7 +132,7 @@ SourceList::iterator Session::deleteSource(Source *s)
|
||||
if (its != sources_.end()) {
|
||||
|
||||
// remove Node from the rendering scene
|
||||
render_.scene.ws()->detatch( s->group(View::RENDERING) );
|
||||
render_.scene.ws()->detach( s->group(View::RENDERING) );
|
||||
|
||||
// erase the source from the update list & get next element
|
||||
its = sources_.erase(its);
|
||||
@@ -160,7 +160,7 @@ void Session::removeSource(Source *s)
|
||||
if (its != sources_.end()) {
|
||||
|
||||
// remove Node from the rendering scene
|
||||
render_.scene.ws()->detatch( s->group(View::RENDERING) );
|
||||
render_.scene.ws()->detach( s->group(View::RENDERING) );
|
||||
|
||||
// erase the source from the update list & get next element
|
||||
sources_.erase(its);
|
||||
@@ -181,7 +181,7 @@ Source *Session::popSource()
|
||||
s = *its;
|
||||
|
||||
// remove Node from the rendering scene
|
||||
render_.scene.ws()->detatch( s->group(View::RENDERING) );
|
||||
render_.scene.ws()->detach( s->group(View::RENDERING) );
|
||||
|
||||
// erase the source from the update list & get next element
|
||||
sources_.erase(its);
|
||||
|
||||
@@ -248,6 +248,7 @@ void SessionLoader::load(XMLElement *sessionNode)
|
||||
session_->addSource(clone_source);
|
||||
// apply config to source
|
||||
clone_source->accept(*this);
|
||||
clone_source->touch();
|
||||
// remember
|
||||
sources_id_.push_back( clone_source->id() );
|
||||
}
|
||||
@@ -294,6 +295,9 @@ Source *SessionLoader::cloneOrCreateSource(tinyxml2::XMLElement *sourceNode)
|
||||
else if ( std::string(pType) == "DeviceSource") {
|
||||
load_source = new DeviceSource;
|
||||
}
|
||||
else if ( std::string(pType) == "NetworkSource") {
|
||||
load_source = new NetworkSource;
|
||||
}
|
||||
else if ( std::string(pType) == "CloneSource") {
|
||||
// clone from given origin
|
||||
XMLElement* originNode = xmlCurrent_->FirstChildElement("origin");
|
||||
@@ -478,6 +482,9 @@ void SessionLoader::visit (Source& s)
|
||||
xmlCurrent_ = sourceNode->FirstChildElement("Layer");
|
||||
s.groupNode(View::LAYER)->accept(*this);
|
||||
|
||||
xmlCurrent_ = sourceNode->FirstChildElement("Appearance");
|
||||
s.groupNode(View::APPEARANCE)->accept(*this);
|
||||
|
||||
xmlCurrent_ = sourceNode->FirstChildElement("Blending");
|
||||
s.blendingShader()->accept(*this);
|
||||
|
||||
|
||||
@@ -47,6 +47,9 @@ SessionSource::SessionSource() : Source(), path_("")
|
||||
overlays_[View::TRANSITION]->attach(center);
|
||||
groups_[View::TRANSITION]->attach(overlays_[View::TRANSITION]);
|
||||
|
||||
// set symbol
|
||||
symbol_ = new Symbol(Symbol::SESSION, glm::vec3(0.8f, 0.8f, 0.01f));
|
||||
|
||||
failed_ = false;
|
||||
wait_for_sources_ = false;
|
||||
session_ = nullptr;
|
||||
@@ -155,11 +158,6 @@ void SessionSource::init()
|
||||
// set the renderbuffer of the source and attach rendering nodes
|
||||
attach(renderbuffer);
|
||||
|
||||
// icon in mixing view
|
||||
overlays_[View::MIXING]->attach( new Symbol(Symbol::SESSION, glm::vec3(0.8f, 0.8f, 0.01f)) );
|
||||
overlays_[View::LAYER]->attach( new Symbol(Symbol::SESSION, glm::vec3(0.8f, 0.8f, 0.01f)) );
|
||||
overlays_[View::APPEARANCE]->attach( new Symbol(Symbol::SESSION, glm::vec3(1.1f, 0.9f, 0.01f)) );
|
||||
|
||||
// wait for all sources to init
|
||||
if (session_->numSource() > 0)
|
||||
wait_for_sources_ = true;
|
||||
@@ -173,7 +171,7 @@ void SessionSource::init()
|
||||
if (initialized_){
|
||||
// remove the loading icon
|
||||
Node *loader = overlays_[View::TRANSITION]->back();
|
||||
overlays_[View::TRANSITION]->detatch(loader);
|
||||
overlays_[View::TRANSITION]->detach(loader);
|
||||
delete loader;
|
||||
}
|
||||
}
|
||||
@@ -208,18 +206,6 @@ void SessionSource::update(float dt)
|
||||
Source::update(dt);
|
||||
}
|
||||
|
||||
void SessionSource::render()
|
||||
{
|
||||
if (!initialized_)
|
||||
init();
|
||||
else {
|
||||
// render the sesion into frame buffer
|
||||
static glm::mat4 projection = glm::ortho(-1.f, 1.f, 1.f, -1.f, -1.f, 1.f);
|
||||
renderbuffer_->begin();
|
||||
texturesurface_->draw(glm::identity<glm::mat4>(), projection);
|
||||
renderbuffer_->end();
|
||||
}
|
||||
}
|
||||
|
||||
void SessionSource::accept(Visitor& v)
|
||||
{
|
||||
@@ -231,6 +217,8 @@ void SessionSource::accept(Visitor& v)
|
||||
|
||||
RenderSource::RenderSource(Session *session) : Source(), session_(session)
|
||||
{
|
||||
// set symbol
|
||||
symbol_ = new Symbol(Symbol::RENDER, glm::vec3(0.8f, 0.8f, 0.01f));
|
||||
}
|
||||
|
||||
|
||||
@@ -262,11 +250,6 @@ void RenderSource::init()
|
||||
// set the renderbuffer of the source and attach rendering nodes
|
||||
attach(renderbuffer);
|
||||
|
||||
// icon in mixing view
|
||||
overlays_[View::MIXING]->attach( new Symbol(Symbol::RENDER, glm::vec3(0.8f, 0.8f, 0.01f)) );
|
||||
overlays_[View::LAYER]->attach( new Symbol(Symbol::RENDER, glm::vec3(0.8f, 0.8f, 0.01f)) );
|
||||
overlays_[View::APPEARANCE]->attach( new Symbol(Symbol::RENDER, glm::vec3(1.1f, 0.9f, 0.01f)) );
|
||||
|
||||
// done init
|
||||
initialized_ = true;
|
||||
|
||||
@@ -274,19 +257,6 @@ void RenderSource::init()
|
||||
}
|
||||
}
|
||||
|
||||
void RenderSource::render()
|
||||
{
|
||||
if (!initialized_)
|
||||
init();
|
||||
else {
|
||||
// render the view into frame buffer
|
||||
static glm::mat4 projection = glm::ortho(-1.f, 1.f, 1.f, -1.f, -1.f, 1.f);
|
||||
renderbuffer_->begin();
|
||||
texturesurface_->draw(glm::identity<glm::mat4>(), projection);
|
||||
renderbuffer_->end();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void RenderSource::accept(Visitor& v)
|
||||
{
|
||||
|
||||
@@ -14,7 +14,6 @@ public:
|
||||
// implementation of source API
|
||||
void update (float dt) override;
|
||||
void setActive (bool on) override;
|
||||
void render() override;
|
||||
bool failed() const override;
|
||||
uint texture() const override;
|
||||
void accept (Visitor& v) override;
|
||||
@@ -48,7 +47,6 @@ public:
|
||||
RenderSource(Session *session);
|
||||
|
||||
// implementation of source API
|
||||
void render() override;
|
||||
bool failed() const override;
|
||||
uint texture() const override;
|
||||
void accept (Visitor& v) override;
|
||||
|
||||
@@ -343,6 +343,10 @@ void SessionVisitor::visit (Source& s)
|
||||
sourceNode->InsertEndChild(xmlCurrent_);
|
||||
s.groupNode(View::LAYER)->accept(*this);
|
||||
|
||||
xmlCurrent_ = xmlDoc_->NewElement( "Appearance" );
|
||||
sourceNode->InsertEndChild(xmlCurrent_);
|
||||
s.groupNode(View::APPEARANCE)->accept(*this);
|
||||
|
||||
xmlCurrent_ = xmlDoc_->NewElement( "Blending" );
|
||||
sourceNode->InsertEndChild(xmlCurrent_);
|
||||
s.blendingShader()->accept(*this);
|
||||
|
||||
129
Source.cpp
129
Source.cpp
@@ -15,7 +15,7 @@
|
||||
#include "Log.h"
|
||||
#include "Mixer.h"
|
||||
|
||||
Source::Source() : initialized_(false), active_(true), need_update_(true)
|
||||
Source::Source() : initialized_(false), active_(true), need_update_(true), symbol_(nullptr)
|
||||
{
|
||||
// create unique id
|
||||
id_ = GlmToolkit::uniqueId();
|
||||
@@ -72,26 +72,26 @@ Source::Source() : initialized_(false), active_(true), need_update_(true)
|
||||
overlays_[View::GEOMETRY] = new Group;
|
||||
overlays_[View::GEOMETRY]->translation_.z = 0.15;
|
||||
overlays_[View::GEOMETRY]->visible_ = false;
|
||||
handle_[Handles::RESIZE] = new Handles(Handles::RESIZE);
|
||||
handle_[Handles::RESIZE]->color = glm::vec4( COLOR_HIGHLIGHT_SOURCE, 1.f);
|
||||
handle_[Handles::RESIZE]->translation_.z = 0.1;
|
||||
overlays_[View::GEOMETRY]->attach(handle_[Handles::RESIZE]);
|
||||
handle_[Handles::RESIZE_H] = new Handles(Handles::RESIZE_H);
|
||||
handle_[Handles::RESIZE_H]->color = glm::vec4( COLOR_HIGHLIGHT_SOURCE, 1.f);
|
||||
handle_[Handles::RESIZE_H]->translation_.z = 0.1;
|
||||
overlays_[View::GEOMETRY]->attach(handle_[Handles::RESIZE_H]);
|
||||
handle_[Handles::RESIZE_V] = new Handles(Handles::RESIZE_V);
|
||||
handle_[Handles::RESIZE_V]->color = glm::vec4( COLOR_HIGHLIGHT_SOURCE, 1.f);
|
||||
handle_[Handles::RESIZE_V]->translation_.z = 0.1;
|
||||
overlays_[View::GEOMETRY]->attach(handle_[Handles::RESIZE_V]);
|
||||
handle_[Handles::ROTATE] = new Handles(Handles::ROTATE);
|
||||
handle_[Handles::ROTATE]->color = glm::vec4( COLOR_HIGHLIGHT_SOURCE, 1.f);
|
||||
handle_[Handles::ROTATE]->translation_.z = 0.1;
|
||||
overlays_[View::GEOMETRY]->attach(handle_[Handles::ROTATE]);
|
||||
handle_[Handles::SCALE] = new Handles(Handles::SCALE);
|
||||
handle_[Handles::SCALE]->color = glm::vec4( COLOR_HIGHLIGHT_SOURCE, 1.f);
|
||||
handle_[Handles::SCALE]->translation_.z = 0.1;
|
||||
overlays_[View::GEOMETRY]->attach(handle_[Handles::SCALE]);
|
||||
handles_[View::GEOMETRY][Handles::RESIZE] = new Handles(Handles::RESIZE);
|
||||
handles_[View::GEOMETRY][Handles::RESIZE]->color = glm::vec4( COLOR_HIGHLIGHT_SOURCE, 1.f);
|
||||
handles_[View::GEOMETRY][Handles::RESIZE]->translation_.z = 0.1;
|
||||
overlays_[View::GEOMETRY]->attach(handles_[View::GEOMETRY][Handles::RESIZE]);
|
||||
handles_[View::GEOMETRY][Handles::RESIZE_H] = new Handles(Handles::RESIZE_H);
|
||||
handles_[View::GEOMETRY][Handles::RESIZE_H]->color = glm::vec4( COLOR_HIGHLIGHT_SOURCE, 1.f);
|
||||
handles_[View::GEOMETRY][Handles::RESIZE_H]->translation_.z = 0.1;
|
||||
overlays_[View::GEOMETRY]->attach(handles_[View::GEOMETRY][Handles::RESIZE_H]);
|
||||
handles_[View::GEOMETRY][Handles::RESIZE_V] = new Handles(Handles::RESIZE_V);
|
||||
handles_[View::GEOMETRY][Handles::RESIZE_V]->color = glm::vec4( COLOR_HIGHLIGHT_SOURCE, 1.f);
|
||||
handles_[View::GEOMETRY][Handles::RESIZE_V]->translation_.z = 0.1;
|
||||
overlays_[View::GEOMETRY]->attach(handles_[View::GEOMETRY][Handles::RESIZE_V]);
|
||||
handles_[View::GEOMETRY][Handles::ROTATE] = new Handles(Handles::ROTATE);
|
||||
handles_[View::GEOMETRY][Handles::ROTATE]->color = glm::vec4( COLOR_HIGHLIGHT_SOURCE, 1.f);
|
||||
handles_[View::GEOMETRY][Handles::ROTATE]->translation_.z = 0.1;
|
||||
overlays_[View::GEOMETRY]->attach(handles_[View::GEOMETRY][Handles::ROTATE]);
|
||||
handles_[View::GEOMETRY][Handles::SCALE] = new Handles(Handles::SCALE);
|
||||
handles_[View::GEOMETRY][Handles::SCALE]->color = glm::vec4( COLOR_HIGHLIGHT_SOURCE, 1.f);
|
||||
handles_[View::GEOMETRY][Handles::SCALE]->translation_.z = 0.1;
|
||||
overlays_[View::GEOMETRY]->attach(handles_[View::GEOMETRY][Handles::SCALE]);
|
||||
|
||||
frame = new Frame(Frame::SHARP, Frame::THIN, Frame::NONE);
|
||||
frame->translation_.z = 0.1;
|
||||
@@ -124,9 +124,36 @@ Source::Source() : initialized_(false), active_(true), need_update_(true)
|
||||
groups_[View::APPEARANCE] = new Group;
|
||||
groups_[View::APPEARANCE]->visible_ = false;
|
||||
|
||||
frames_[View::APPEARANCE] = new Switch;
|
||||
frame = new Frame(Frame::SHARP, Frame::THIN, Frame::NONE);
|
||||
frame->translation_.z = 0.1;
|
||||
frame->color = glm::vec4( COLOR_APPEARANCE_SOURCE, 0.7f);
|
||||
frames_[View::APPEARANCE]->attach(frame);
|
||||
frame = new Frame(Frame::SHARP, Frame::LARGE, Frame::NONE);
|
||||
frame->translation_.z = 0.1;
|
||||
frame->color = glm::vec4( COLOR_APPEARANCE_SOURCE, 1.f);
|
||||
frames_[View::APPEARANCE]->attach(frame);
|
||||
groups_[View::APPEARANCE]->attach(frames_[View::APPEARANCE]);
|
||||
|
||||
overlays_[View::APPEARANCE] = new Group;
|
||||
overlays_[View::APPEARANCE]->translation_.z = 0.1;
|
||||
overlays_[View::APPEARANCE]->visible_ = false;
|
||||
handles_[View::APPEARANCE][Handles::RESIZE] = new Handles(Handles::RESIZE);
|
||||
handles_[View::APPEARANCE][Handles::RESIZE]->color = glm::vec4( COLOR_APPEARANCE_SOURCE, 1.f);
|
||||
handles_[View::APPEARANCE][Handles::RESIZE]->translation_.z = 0.1;
|
||||
overlays_[View::APPEARANCE]->attach(handles_[View::APPEARANCE][Handles::RESIZE]);
|
||||
handles_[View::APPEARANCE][Handles::RESIZE_H] = new Handles(Handles::RESIZE_H);
|
||||
handles_[View::APPEARANCE][Handles::RESIZE_H]->color = glm::vec4( COLOR_APPEARANCE_SOURCE, 1.f);
|
||||
handles_[View::APPEARANCE][Handles::RESIZE_H]->translation_.z = 0.1;
|
||||
overlays_[View::APPEARANCE]->attach(handles_[View::APPEARANCE][Handles::RESIZE_H]);
|
||||
handles_[View::APPEARANCE][Handles::RESIZE_V] = new Handles(Handles::RESIZE_V);
|
||||
handles_[View::APPEARANCE][Handles::RESIZE_V]->color = glm::vec4( COLOR_APPEARANCE_SOURCE, 1.f);
|
||||
handles_[View::APPEARANCE][Handles::RESIZE_V]->translation_.z = 0.1;
|
||||
overlays_[View::APPEARANCE]->attach(handles_[View::APPEARANCE][Handles::RESIZE_V]);
|
||||
handles_[View::APPEARANCE][Handles::SCALE] = new Handles(Handles::SCALE);
|
||||
handles_[View::APPEARANCE][Handles::SCALE]->color = glm::vec4( COLOR_APPEARANCE_SOURCE, 1.f);
|
||||
handles_[View::APPEARANCE][Handles::SCALE]->translation_.z = 0.1;
|
||||
overlays_[View::APPEARANCE]->attach(handles_[View::APPEARANCE][Handles::SCALE]);
|
||||
groups_[View::APPEARANCE]->attach(overlays_[View::APPEARANCE]);
|
||||
|
||||
// empty transition node
|
||||
@@ -266,10 +293,29 @@ bool Source::imageProcessingEnabled()
|
||||
return ( renderingshader_ == processingshader_ );
|
||||
}
|
||||
|
||||
void Source::render()
|
||||
{
|
||||
if (!initialized_)
|
||||
init();
|
||||
else {
|
||||
// render the view into frame buffer
|
||||
static glm::mat4 projection = glm::ortho(-1.f, 1.f, 1.f, -1.f, -1.f, 1.f);
|
||||
renderbuffer_->begin();
|
||||
texturesurface_->draw(glm::identity<glm::mat4>(), projection);
|
||||
renderbuffer_->end();
|
||||
}
|
||||
}
|
||||
|
||||
void Source::attach(FrameBuffer *renderbuffer)
|
||||
{
|
||||
renderbuffer_ = renderbuffer;
|
||||
|
||||
// if a symbol is available, add it to icons
|
||||
if (symbol_) {
|
||||
overlays_[View::MIXING]->attach( symbol_ );
|
||||
overlays_[View::LAYER]->attach( symbol_ );
|
||||
}
|
||||
|
||||
// create the surfaces to draw the frame buffer in the views
|
||||
rendersurface_ = new FrameBufferSurface(renderbuffer_, blendingshader_);
|
||||
groups_[View::RENDERING]->attach(rendersurface_);
|
||||
@@ -285,9 +331,11 @@ void Source::attach(FrameBuffer *renderbuffer)
|
||||
groups_[View::MIXING]->attach(surfacemix);
|
||||
groups_[View::LAYER]->attach(surfacemix);
|
||||
|
||||
// for appearance view, a dedicated surface without blending
|
||||
Surface *surfacepreview = new FrameBufferSurface(renderbuffer_);
|
||||
groups_[View::APPEARANCE]->attach(surfacepreview);
|
||||
// // for appearance view, a dedicated surface without blending
|
||||
// Surface *surfacepreview = new FrameBufferSurface(renderbuffer_);
|
||||
Surface *surfacetmp = new Surface();
|
||||
surfacetmp->setTextureIndex(Resource::getTextureTransparent());
|
||||
groups_[View::APPEARANCE]->attach(surfacetmp);
|
||||
|
||||
// scale all icon nodes to match aspect ratio of the media
|
||||
NodeSet::iterator node;
|
||||
@@ -385,6 +433,19 @@ void Source::update(float dt)
|
||||
groups_[View::GEOMETRY]->translation_.z = groups_[View::LAYER]->translation_.z;
|
||||
groups_[View::RENDERING]->translation_.z = groups_[View::LAYER]->translation_.z;
|
||||
|
||||
// MODIFY texture projection based on APPEARANCE node
|
||||
texturesurface_->translation_.x = groups_[View::APPEARANCE]->translation_.x;
|
||||
if (renderbuffer_)
|
||||
texturesurface_->translation_.x /= renderbuffer_->aspectRatio();
|
||||
texturesurface_->translation_.y = groups_[View::APPEARANCE]->translation_.y;
|
||||
texturesurface_->rotation_.z = groups_[View::APPEARANCE]->rotation_.z;
|
||||
// avoid any null scale
|
||||
s = groups_[View::APPEARANCE]->scale_;
|
||||
s.x = CLAMP_SCALE(s.x);
|
||||
s.y = CLAMP_SCALE(s.y);
|
||||
s.z = 1.f;
|
||||
texturesurface_->scale_ = s;
|
||||
texturesurface_->update(dt);
|
||||
|
||||
need_update_ = false;
|
||||
}
|
||||
@@ -451,6 +512,8 @@ CloneSource *Source::clone()
|
||||
|
||||
CloneSource::CloneSource(Source *origin) : Source(), origin_(origin)
|
||||
{
|
||||
// set symbol
|
||||
symbol_ = new Symbol(Symbol::CLONE, glm::vec3(0.8f, 0.8f, 0.01f));
|
||||
}
|
||||
|
||||
CloneSource::~CloneSource()
|
||||
@@ -481,11 +544,6 @@ void CloneSource::init()
|
||||
// set the renderbuffer of the source and attach rendering nodes
|
||||
attach(renderbuffer);
|
||||
|
||||
// icon in mixing view
|
||||
overlays_[View::MIXING]->attach( new Symbol(Symbol::CLONE, glm::vec3(0.8f, 0.8f, 0.01f)) );
|
||||
overlays_[View::LAYER]->attach( new Symbol(Symbol::CLONE, glm::vec3(0.8f, 0.8f, 0.01f)) );
|
||||
overlays_[View::APPEARANCE]->attach( new Symbol(Symbol::CLONE, glm::vec3(1.1f, 0.9f, 0.01f)) );
|
||||
|
||||
// done init
|
||||
initialized_ = true;
|
||||
|
||||
@@ -514,19 +572,6 @@ uint CloneSource::texture() const
|
||||
return Resource::getTextureBlack();
|
||||
}
|
||||
|
||||
void CloneSource::render()
|
||||
{
|
||||
if (!initialized_)
|
||||
init();
|
||||
else if (origin_) {
|
||||
// render the view into frame buffer
|
||||
static glm::mat4 projection = glm::ortho(-1.f, 1.f, 1.f, -1.f, -1.f, 1.f);
|
||||
renderbuffer_->begin();
|
||||
texturesurface_->draw(glm::identity<glm::mat4>(), projection);
|
||||
renderbuffer_->end();
|
||||
}
|
||||
}
|
||||
|
||||
void CloneSource::accept(Visitor& v)
|
||||
{
|
||||
Source::accept(v);
|
||||
|
||||
8
Source.h
8
Source.h
@@ -17,6 +17,7 @@ class FrameBufferSurface;
|
||||
class Session;
|
||||
class Frame;
|
||||
class Handles;
|
||||
class Symbol;
|
||||
class CloneSource;
|
||||
|
||||
typedef std::list<CloneSource *> CloneList;
|
||||
@@ -28,6 +29,7 @@ class Source
|
||||
friend class MixingView;
|
||||
friend class GeometryView;
|
||||
friend class LayerView;
|
||||
friend class AppearanceView;
|
||||
friend class TransitionView;
|
||||
|
||||
public:
|
||||
@@ -101,7 +103,7 @@ public:
|
||||
virtual uint texture() const = 0;
|
||||
|
||||
// a Source shall define how to render into the frame buffer
|
||||
virtual void render() = 0;
|
||||
virtual void render();
|
||||
|
||||
// accept all kind of visitors
|
||||
virtual void accept (Visitor& v);
|
||||
@@ -176,7 +178,8 @@ protected:
|
||||
// overlays and frames to be displayed on top of source
|
||||
std::map<View::Mode, Group*> overlays_;
|
||||
std::map<View::Mode, Switch*> frames_;
|
||||
Handles *handle_[5];
|
||||
std::map<View::Mode, Handles*[5]> handles_;
|
||||
Symbol *symbol_;
|
||||
|
||||
// update
|
||||
bool active_;
|
||||
@@ -199,7 +202,6 @@ public:
|
||||
|
||||
// implementation of source API
|
||||
void setActive (bool on) override;
|
||||
void render() override;
|
||||
uint texture() const override;
|
||||
bool failed() const override { return origin_ == nullptr; }
|
||||
void accept (Visitor& v) override;
|
||||
|
||||
@@ -17,10 +17,8 @@ GenericStreamSource::GenericStreamSource() : StreamSource()
|
||||
// create stream
|
||||
stream_ = new Stream;
|
||||
|
||||
// icon in mixing view
|
||||
overlays_[View::MIXING]->attach( new Symbol(Symbol::EMPTY, glm::vec3(0.8f, 0.8f, 0.01f)) );
|
||||
overlays_[View::LAYER]->attach( new Symbol(Symbol::EMPTY, glm::vec3(0.8f, 0.8f, 0.01f)) );
|
||||
overlays_[View::APPEARANCE]->attach( new Symbol(Symbol::EMPTY, glm::vec3(1.1f, 0.9f, 0.01f)) );
|
||||
// set symbol
|
||||
symbol_ = new Symbol(Symbol::EMPTY, glm::vec3(0.8f, 0.8f, 0.01f));
|
||||
}
|
||||
|
||||
void GenericStreamSource::setDescription(const std::string &desc)
|
||||
@@ -115,16 +113,3 @@ void StreamSource::update(float dt)
|
||||
if (stream_)
|
||||
stream_->update();
|
||||
}
|
||||
|
||||
void StreamSource::render()
|
||||
{
|
||||
if (!initialized_)
|
||||
init();
|
||||
else {
|
||||
// render the media player into frame buffer
|
||||
static glm::mat4 projection = glm::ortho(-1.f, 1.f, 1.f, -1.f, -1.f, 1.f);
|
||||
renderbuffer_->begin();
|
||||
texturesurface_->draw(glm::identity<glm::mat4>(), projection);
|
||||
renderbuffer_->end();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,7 +30,6 @@ public:
|
||||
// implementation of source API
|
||||
void update (float dt) override;
|
||||
void setActive (bool on) override;
|
||||
void render() override;
|
||||
bool failed() const override;
|
||||
uint texture() const override;
|
||||
|
||||
|
||||
399
View.cpp
399
View.cpp
@@ -890,7 +890,7 @@ View::Cursor GeometryView::grab (Source *s, glm::vec2 from, glm::vec2 to, std::p
|
||||
// work on the given source
|
||||
if (!s)
|
||||
return ret;
|
||||
Group *sourceNode = s->group(mode_);
|
||||
Group *sourceNode = s->group(mode_); // groups_[View::GEOMETRY]
|
||||
|
||||
// grab coordinates in scene-View reference frame
|
||||
glm::vec3 scene_from = Rendering::manager().unProject(from, scene.root()->transform_);
|
||||
@@ -928,10 +928,10 @@ View::Cursor GeometryView::grab (Source *s, glm::vec2 from, glm::vec2 to, std::p
|
||||
glm::vec4 center = scene_to_corner_transform * glm::vec4( s->stored_status_->translation_, 1.f);
|
||||
|
||||
// picking on the resizing handles in the corners
|
||||
if ( pick.first == s->handle_[Handles::RESIZE] ) {
|
||||
if ( pick.first == s->handles_[mode_][Handles::RESIZE] ) {
|
||||
|
||||
// inform on which corner should be overlayed (opposite)
|
||||
s->handle_[Handles::RESIZE]->overlayActiveCorner(-corner);
|
||||
s->handles_[mode_][Handles::RESIZE]->overlayActiveCorner(-corner);
|
||||
|
||||
// overlay_scaling_grid_->visible_ = false;
|
||||
// glm::vec4 icon = corner_to_scene_transform * glm::vec4(0.f, 0.f, 0.f, 1.f);
|
||||
@@ -983,10 +983,10 @@ View::Cursor GeometryView::grab (Source *s, glm::vec2 from, glm::vec2 to, std::p
|
||||
|
||||
}
|
||||
// picking on the BORDER RESIZING handles left or right
|
||||
else if ( pick.first == s->handle_[Handles::RESIZE_H] ) {
|
||||
else if ( pick.first == s->handles_[mode_][Handles::RESIZE_H] ) {
|
||||
|
||||
// inform on which corner should be overlayed (opposite)
|
||||
s->handle_[Handles::RESIZE_H]->overlayActiveCorner(-corner);
|
||||
s->handles_[mode_][Handles::RESIZE_H]->overlayActiveCorner(-corner);
|
||||
|
||||
// SHIFT: HORIZONTAL SCALE to restore source aspect ratio
|
||||
if (UserInterface::manager().shiftModifier()) {
|
||||
@@ -1018,10 +1018,10 @@ View::Cursor GeometryView::grab (Source *s, glm::vec2 from, glm::vec2 to, std::p
|
||||
info << " x " << sourceNode->scale_.y;
|
||||
}
|
||||
// picking on the BORDER RESIZING handles top or bottom
|
||||
else if ( pick.first == s->handle_[Handles::RESIZE_V] ) {
|
||||
else if ( pick.first == s->handles_[mode_][Handles::RESIZE_V] ) {
|
||||
|
||||
// inform on which corner should be overlayed (opposite)
|
||||
s->handle_[Handles::RESIZE_V]->overlayActiveCorner(-corner);
|
||||
s->handles_[mode_][Handles::RESIZE_V]->overlayActiveCorner(-corner);
|
||||
|
||||
// SHIFT: VERTICAL SCALE to restore source aspect ratio
|
||||
if (UserInterface::manager().shiftModifier()) {
|
||||
@@ -1053,7 +1053,7 @@ View::Cursor GeometryView::grab (Source *s, glm::vec2 from, glm::vec2 to, std::p
|
||||
info << " x " << sourceNode->scale_.y;
|
||||
}
|
||||
// picking on the CENTRER SCALING handle
|
||||
else if ( pick.first == s->handle_[Handles::SCALE] ) {
|
||||
else if ( pick.first == s->handles_[mode_][Handles::SCALE] ) {
|
||||
|
||||
overlay_scaling_cross_->visible_ = false;
|
||||
overlay_scaling_grid_->visible_ = false;
|
||||
@@ -1086,7 +1086,7 @@ View::Cursor GeometryView::grab (Source *s, glm::vec2 from, glm::vec2 to, std::p
|
||||
info << " x " << sourceNode->scale_.y;
|
||||
}
|
||||
// picking on the rotating handle
|
||||
else if ( pick.first == s->handle_[Handles::ROTATE] ) {
|
||||
else if ( pick.first == s->handles_[mode_][Handles::ROTATE] ) {
|
||||
|
||||
// ROTATION on CENTER
|
||||
overlay_rotation_->visible_ = true;
|
||||
@@ -1208,9 +1208,9 @@ void GeometryView::terminate()
|
||||
for (auto sit = Mixer::manager().session()->begin();
|
||||
sit != Mixer::manager().session()->end(); sit++){
|
||||
|
||||
(*sit)->handle_[Handles::RESIZE]->overlayActiveCorner(c);
|
||||
(*sit)->handle_[Handles::RESIZE_H]->overlayActiveCorner(c);
|
||||
(*sit)->handle_[Handles::RESIZE_V]->overlayActiveCorner(c);
|
||||
(*sit)->handles_[mode_][Handles::RESIZE]->overlayActiveCorner(c);
|
||||
(*sit)->handles_[mode_][Handles::RESIZE_H]->overlayActiveCorner(c);
|
||||
(*sit)->handles_[mode_][Handles::RESIZE_V]->overlayActiveCorner(c);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1590,7 +1590,7 @@ Session *TransitionView::detach()
|
||||
|
||||
// get and detatch the group node from the view workspace
|
||||
Group *tg = transition_source_->group(View::TRANSITION);
|
||||
scene.ws()->detatch( tg );
|
||||
scene.ws()->detach( tg );
|
||||
|
||||
// test if the icon of the transition source is "Ready"
|
||||
if ( tg->translation_.x > 0.f )
|
||||
@@ -1708,31 +1708,72 @@ AppearanceView::AppearanceView() : View(APPEARANCE), index_source_(-1)
|
||||
restoreSettings();
|
||||
|
||||
// Scene background
|
||||
Surface *rect = new Surface;
|
||||
Surface *rect = new Surface; // black : TODO transparency grid
|
||||
scene.bg()->attach(rect);
|
||||
surfacepreview = new Surface; // to attach source preview
|
||||
surfacepreview->translation_.z = 0.01f;
|
||||
scene.bg()->attach(surfacepreview);
|
||||
|
||||
// Geometry Scene foreground
|
||||
Frame *border = new Frame(Frame::SHARP, Frame::THIN, Frame::NONE);
|
||||
Frame *border = new Frame(Frame::SHARP, Frame::LARGE, Frame::GLOW);
|
||||
border->color = glm::vec4( COLOR_HIGHLIGHT_SOURCE, 1.f );
|
||||
scene.fg()->attach(border);
|
||||
|
||||
}
|
||||
|
||||
void AppearanceView::update(float dt)
|
||||
{
|
||||
View::update(dt);
|
||||
|
||||
|
||||
// // a more complete update is requested (e.g. after switching to view)
|
||||
// // AND no source selected
|
||||
// if (View::need_deep_update_ && Mixer::manager().indexCurrentSource() < 0) {
|
||||
|
||||
// index_source_ = -1;
|
||||
// }
|
||||
|
||||
// User interface foreground
|
||||
//
|
||||
// point to show POSITION
|
||||
overlay_position_ = new Symbol(Symbol::SQUARE_POINT);
|
||||
overlay_position_->scale_ = glm::vec3(0.5f, 0.5f, 1.f);
|
||||
scene.fg()->attach(overlay_position_);
|
||||
overlay_position_->visible_ = false;
|
||||
// cross to show the axis for POSITION
|
||||
overlay_position_cross_ = new Symbol(Symbol::CROSS);
|
||||
overlay_position_cross_->rotation_ = glm::vec3(0.f, 0.f, M_PI_4);
|
||||
overlay_position_cross_->scale_ = glm::vec3(0.3f, 0.3f, 1.f);
|
||||
scene.fg()->attach(overlay_position_cross_);
|
||||
overlay_position_cross_->visible_ = false;
|
||||
// 'grid' : tic marks every 0.1 step for SCALING
|
||||
// with dark background
|
||||
Group *g = new Group;
|
||||
Symbol *s = new Symbol(Symbol::GRID);
|
||||
g->attach(s);
|
||||
s = new Symbol(Symbol::SQUARE_POINT);
|
||||
s->color = glm::vec4(0.f, 0.f, 0.f, 0.25f);
|
||||
s->scale_ = glm::vec3(18.f, 18.f, 1.f);
|
||||
s->translation_.z = -0.1;
|
||||
g->attach(s);
|
||||
overlay_scaling_grid_ = g;
|
||||
overlay_scaling_grid_->scale_ = glm::vec3(0.3f, 0.3f, 1.f);
|
||||
scene.fg()->attach(overlay_scaling_grid_);
|
||||
overlay_scaling_grid_->visible_ = false;
|
||||
// cross in the square for proportional SCALING
|
||||
overlay_scaling_cross_ = new Symbol(Symbol::CROSS);
|
||||
overlay_scaling_cross_->scale_ = glm::vec3(0.3f, 0.3f, 1.f);
|
||||
scene.fg()->attach(overlay_scaling_cross_);
|
||||
overlay_scaling_cross_->visible_ = false;
|
||||
// square to show the center of SCALING
|
||||
overlay_scaling_ = new Symbol(Symbol::SQUARE);
|
||||
overlay_scaling_->scale_ = glm::vec3(0.3f, 0.3f, 1.f);
|
||||
scene.fg()->attach(overlay_scaling_);
|
||||
overlay_scaling_->visible_ = false;
|
||||
|
||||
}
|
||||
|
||||
//void AppearanceView::update(float dt)
|
||||
//{
|
||||
// View::update(dt);
|
||||
|
||||
|
||||
//// // a more complete update is requested (e.g. after switching to view)
|
||||
//// // AND no source selected
|
||||
//// if (View::need_deep_update_ && Mixer::manager().indexCurrentSource() < 0) {
|
||||
|
||||
//// index_source_ = -1;
|
||||
//// }
|
||||
|
||||
|
||||
//}
|
||||
|
||||
void AppearanceView::zoom (float factor)
|
||||
{
|
||||
float z = scene.root()->scale_.x;
|
||||
@@ -1771,6 +1812,11 @@ void AppearanceView::draw()
|
||||
if (s != nullptr) {
|
||||
// update rendering frame to match current source AR
|
||||
scale = s->frame()->aspectRatio();
|
||||
|
||||
surfacepreview->setTextureIndex( s->frame()->texture() );
|
||||
}
|
||||
else {
|
||||
surfacepreview->setTextureIndex(0);
|
||||
}
|
||||
|
||||
// update aspect ratio
|
||||
@@ -1790,29 +1836,308 @@ void AppearanceView::draw()
|
||||
|
||||
View::Cursor AppearanceView::grab (Source *s, glm::vec2 from, glm::vec2 to, std::pair<Node *, glm::vec2> pick)
|
||||
{
|
||||
// View::Cursor ret = Cursor();
|
||||
// std::ostringstream info;
|
||||
|
||||
// // work on the given source
|
||||
// if (!s)
|
||||
return Cursor();
|
||||
// return ret;
|
||||
|
||||
// Group *sourceNode = s->group(mode_); // groups_[View::APPEARANCE]
|
||||
|
||||
// // grab coordinates in scene-View reference frame
|
||||
// glm::vec3 scene_from = Rendering::manager().unProject(from, scene.root()->transform_);
|
||||
// glm::vec3 scene_to = Rendering::manager().unProject(to, scene.root()->transform_);
|
||||
// glm::vec3 scene_translation = scene_to - scene_from;
|
||||
|
||||
// // make sure matrix transform of stored status is updated
|
||||
// s->stored_status_->update(0);
|
||||
|
||||
// ret.type = Cursor_ResizeAll;
|
||||
// info << "UV " ;
|
||||
|
||||
// sourceNode->translation_ = s->stored_status_->translation_ + scene_translation;
|
||||
|
||||
//// ImageShader *shader = s->blendingShader ();
|
||||
//// shader->uv.x += scene_translation.x;
|
||||
//// shader->uv.y += scene_translation.y;
|
||||
//// shader->uv.z += scene_translation.x;
|
||||
//// shader->uv.w += scene_translation.y;
|
||||
|
||||
|
||||
// // request update
|
||||
// s->touch();
|
||||
|
||||
// // update cursor
|
||||
// ret.info = info.str();
|
||||
// return ret;
|
||||
View::Cursor ret = Cursor();
|
||||
|
||||
// work on the given source
|
||||
if (!s)
|
||||
return ret;
|
||||
Group *sourceNode = s->group(mode_); // groups_[View::GEOMETRY]
|
||||
|
||||
// grab coordinates in scene-View reference frame
|
||||
glm::vec3 scene_from = Rendering::manager().unProject(from, scene.root()->transform_);
|
||||
glm::vec3 scene_to = Rendering::manager().unProject(to, scene.root()->transform_);
|
||||
glm::vec3 scene_translation = scene_to - scene_from;
|
||||
|
||||
// make sure matrix transform of stored status is updated
|
||||
s->stored_status_->update(0);
|
||||
|
||||
// grab coordinates in source-root reference frame
|
||||
glm::vec4 source_from = glm::inverse(s->stored_status_->transform_) * glm::vec4( scene_from, 1.f );
|
||||
glm::vec4 source_to = glm::inverse(s->stored_status_->transform_) * glm::vec4( scene_to, 1.f );
|
||||
glm::vec3 source_scaling = glm::vec3(source_to) / glm::vec3(source_from);
|
||||
|
||||
// which manipulation to perform?
|
||||
std::ostringstream info;
|
||||
info << "UV " ;
|
||||
if (pick.first) {
|
||||
// which corner was picked ?
|
||||
glm::vec2 corner = glm::round(pick.second);
|
||||
|
||||
ImageShader *shader = s->blendingShader ();
|
||||
shader->uv.x += scene_translation.x;
|
||||
shader->uv.y += scene_translation.y;
|
||||
shader->uv.z += scene_translation.x;
|
||||
shader->uv.w += scene_translation.y;
|
||||
// transform from source center to corner
|
||||
glm::mat4 T = GlmToolkit::transform(glm::vec3(corner.x, corner.y, 0.f), glm::vec3(0.f, 0.f, 0.f),
|
||||
glm::vec3(1.f / s->frame()->aspectRatio(), 1.f, 1.f));
|
||||
|
||||
// transformation from scene to corner:
|
||||
glm::mat4 scene_to_corner_transform = T * glm::inverse(s->stored_status_->transform_);
|
||||
glm::mat4 corner_to_scene_transform = glm::inverse(scene_to_corner_transform);
|
||||
|
||||
return Cursor(Cursor_ResizeAll, info.str() );
|
||||
// compute cursor movement in corner reference frame
|
||||
glm::vec4 corner_from = scene_to_corner_transform * glm::vec4( scene_from, 1.f );
|
||||
glm::vec4 corner_to = scene_to_corner_transform * glm::vec4( scene_to, 1.f );
|
||||
// operation of scaling in corner reference frame
|
||||
glm::vec3 corner_scaling = glm::vec3(corner_to) / glm::vec3(corner_from);
|
||||
|
||||
// convert source position in corner reference frame
|
||||
glm::vec4 center = scene_to_corner_transform * glm::vec4( s->stored_status_->translation_, 1.f);
|
||||
|
||||
// picking on the resizing handles in the corners
|
||||
if ( pick.first == s->handles_[mode_][Handles::RESIZE] ) {
|
||||
|
||||
// inform on which corner should be overlayed (opposite)
|
||||
s->handles_[mode_][Handles::RESIZE]->overlayActiveCorner(-corner);
|
||||
|
||||
// RESIZE CORNER
|
||||
// proportional SCALING with SHIFT
|
||||
if (UserInterface::manager().shiftModifier()) {
|
||||
// calculate proportional scaling factor
|
||||
float factor = glm::length( glm::vec2( corner_to ) ) / glm::length( glm::vec2( corner_from ) );
|
||||
// scale node
|
||||
sourceNode->scale_ = s->stored_status_->scale_ * glm::vec3(factor, factor, 1.f);
|
||||
// discretized scaling with ALT
|
||||
if (UserInterface::manager().altModifier()) {
|
||||
sourceNode->scale_.x = ROUND(sourceNode->scale_.x, 10.f);
|
||||
factor = sourceNode->scale_.x / s->stored_status_->scale_.x;
|
||||
sourceNode->scale_.y = s->stored_status_->scale_.y * factor;
|
||||
}
|
||||
// update corner scaling to apply to center coordinates
|
||||
corner_scaling = sourceNode->scale_ / s->stored_status_->scale_;
|
||||
}
|
||||
// non-proportional CORNER RESIZE (normal case)
|
||||
else {
|
||||
// scale node
|
||||
sourceNode->scale_ = s->stored_status_->scale_ * corner_scaling;
|
||||
// discretized scaling with ALT
|
||||
if (UserInterface::manager().altModifier()) {
|
||||
sourceNode->scale_.x = ROUND(sourceNode->scale_.x, 10.f);
|
||||
sourceNode->scale_.y = ROUND(sourceNode->scale_.y, 10.f);
|
||||
corner_scaling = sourceNode->scale_ / s->stored_status_->scale_;
|
||||
}
|
||||
}
|
||||
// transform source center (in corner reference frame)
|
||||
center = glm::scale(glm::identity<glm::mat4>(), corner_scaling) * center;
|
||||
// convert center back into scene reference frame
|
||||
center = corner_to_scene_transform * center;
|
||||
// apply to node
|
||||
sourceNode->translation_ = glm::vec3(center);
|
||||
// show cursor depending on diagonal (corner picked)
|
||||
T = glm::rotate(glm::identity<glm::mat4>(), s->stored_status_->rotation_.z, glm::vec3(0.f, 0.f, 1.f));
|
||||
T = glm::scale(T, s->stored_status_->scale_);
|
||||
corner = T * glm::vec4( corner, 0.f, 0.f );
|
||||
ret.type = corner.x * corner.y > 0.f ? Cursor_ResizeNESW : Cursor_ResizeNWSE;
|
||||
info << "Size " << std::fixed << std::setprecision(3) << sourceNode->scale_.x;
|
||||
info << " x " << sourceNode->scale_.y;
|
||||
|
||||
}
|
||||
// picking on the BORDER RESIZING handles left or right
|
||||
else if ( pick.first == s->handles_[mode_][Handles::RESIZE_H] ) {
|
||||
|
||||
// inform on which corner should be overlayed (opposite)
|
||||
s->handles_[mode_][Handles::RESIZE_H]->overlayActiveCorner(-corner);
|
||||
|
||||
// SHIFT: HORIZONTAL SCALE to restore source aspect ratio
|
||||
if (UserInterface::manager().shiftModifier()) {
|
||||
sourceNode->scale_.x = ABS(sourceNode->scale_.y) * SIGN(sourceNode->scale_.x);
|
||||
corner_scaling = sourceNode->scale_ / s->stored_status_->scale_;
|
||||
}
|
||||
// HORIZONTAL RESIZE (normal case)
|
||||
else {
|
||||
// x scale only
|
||||
corner_scaling = glm::vec3(corner_scaling.x, 1.f, 1.f);
|
||||
// scale node
|
||||
sourceNode->scale_ = s->stored_status_->scale_ * corner_scaling;
|
||||
// POST-CORRECTION ; discretized scaling with ALT
|
||||
if (UserInterface::manager().altModifier()) {
|
||||
sourceNode->scale_.x = ROUND(sourceNode->scale_.x, 10.f);
|
||||
corner_scaling = sourceNode->scale_ / s->stored_status_->scale_;
|
||||
}
|
||||
}
|
||||
// transform source center (in corner reference frame)
|
||||
center = glm::scale(glm::identity<glm::mat4>(), corner_scaling) * center;
|
||||
// convert center back into scene reference frame
|
||||
center = corner_to_scene_transform * center;
|
||||
// apply to node
|
||||
sourceNode->translation_ = glm::vec3(center);
|
||||
// show cursor depending on angle
|
||||
float c = tan(sourceNode->rotation_.z);
|
||||
ret.type = ABS(c) > 1.f ? Cursor_ResizeNS : Cursor_ResizeEW;
|
||||
info << "Size " << std::fixed << std::setprecision(3) << sourceNode->scale_.x;
|
||||
info << " x " << sourceNode->scale_.y;
|
||||
}
|
||||
// picking on the BORDER RESIZING handles top or bottom
|
||||
else if ( pick.first == s->handles_[mode_][Handles::RESIZE_V] ) {
|
||||
|
||||
// inform on which corner should be overlayed (opposite)
|
||||
s->handles_[mode_][Handles::RESIZE_V]->overlayActiveCorner(-corner);
|
||||
|
||||
// SHIFT: VERTICAL SCALE to restore source aspect ratio
|
||||
if (UserInterface::manager().shiftModifier()) {
|
||||
sourceNode->scale_.y = ABS(sourceNode->scale_.x) * SIGN(sourceNode->scale_.y);
|
||||
corner_scaling = sourceNode->scale_ / s->stored_status_->scale_;
|
||||
}
|
||||
// VERTICAL RESIZE (normal case)
|
||||
else {
|
||||
// y scale only
|
||||
corner_scaling = glm::vec3(1.f, corner_scaling.y, 1.f);
|
||||
// scale node
|
||||
sourceNode->scale_ = s->stored_status_->scale_ * corner_scaling;
|
||||
// POST-CORRECTION ; discretized scaling with ALT
|
||||
if (UserInterface::manager().altModifier()) {
|
||||
sourceNode->scale_.y = ROUND(sourceNode->scale_.y, 10.f);
|
||||
corner_scaling = sourceNode->scale_ / s->stored_status_->scale_;
|
||||
}
|
||||
}
|
||||
// transform source center (in corner reference frame)
|
||||
center = glm::scale(glm::identity<glm::mat4>(), corner_scaling) * center;
|
||||
// convert center back into scene reference frame
|
||||
center = corner_to_scene_transform * center;
|
||||
// apply to node
|
||||
sourceNode->translation_ = glm::vec3(center);
|
||||
// show cursor depending on angle
|
||||
float c = tan(sourceNode->rotation_.z);
|
||||
ret.type = ABS(c) > 1.f ? Cursor_ResizeEW : Cursor_ResizeNS;
|
||||
info << "Size " << std::fixed << std::setprecision(3) << sourceNode->scale_.x;
|
||||
info << " x " << sourceNode->scale_.y;
|
||||
}
|
||||
// picking on the CENTRER SCALING handle
|
||||
else if ( pick.first == s->handles_[mode_][Handles::SCALE] ) {
|
||||
|
||||
overlay_scaling_cross_->visible_ = false;
|
||||
overlay_scaling_grid_->visible_ = false;
|
||||
overlay_scaling_->visible_ = true;
|
||||
overlay_scaling_->translation_.x = s->stored_status_->translation_.x;
|
||||
overlay_scaling_->translation_.y = s->stored_status_->translation_.y;
|
||||
overlay_scaling_->rotation_.z = s->stored_status_->rotation_.z;
|
||||
overlay_scaling_->update(0);
|
||||
|
||||
// PROPORTIONAL ONLY
|
||||
if (UserInterface::manager().shiftModifier()) {
|
||||
float factor = glm::length( glm::vec2( source_to ) ) / glm::length( glm::vec2( source_from ) );
|
||||
source_scaling = glm::vec3(factor, factor, 1.f);
|
||||
overlay_scaling_cross_->visible_ = true;
|
||||
overlay_scaling_cross_->copyTransform(overlay_scaling_);
|
||||
}
|
||||
// apply center scaling
|
||||
sourceNode->scale_ = s->stored_status_->scale_ * source_scaling;
|
||||
// POST-CORRECTION ; discretized scaling with ALT
|
||||
if (UserInterface::manager().altModifier()) {
|
||||
sourceNode->scale_.x = ROUND(sourceNode->scale_.x, 10.f);
|
||||
sourceNode->scale_.y = ROUND(sourceNode->scale_.y, 10.f);
|
||||
overlay_scaling_grid_->visible_ = true;
|
||||
overlay_scaling_grid_->copyTransform(overlay_scaling_);
|
||||
}
|
||||
// show cursor depending on diagonal
|
||||
corner = glm::sign(sourceNode->scale_);
|
||||
ret.type = (corner.x * corner.y) > 0.f ? Cursor_ResizeNWSE : Cursor_ResizeNESW;
|
||||
info << "Size " << std::fixed << std::setprecision(3) << sourceNode->scale_.x;
|
||||
info << " x " << sourceNode->scale_.y;
|
||||
}
|
||||
// picking anywhere but on a handle: user wants to move the source
|
||||
else {
|
||||
ret.type = Cursor_ResizeAll;
|
||||
sourceNode->translation_ = s->stored_status_->translation_ + scene_translation;
|
||||
// discretized translation with ALT
|
||||
if (UserInterface::manager().altModifier()) {
|
||||
sourceNode->translation_.x = ROUND(sourceNode->translation_.x, 10.f);
|
||||
sourceNode->translation_.y = ROUND(sourceNode->translation_.y, 10.f);
|
||||
}
|
||||
// ALT: single axis movement
|
||||
overlay_position_cross_->visible_ = false;
|
||||
if (UserInterface::manager().shiftModifier()) {
|
||||
overlay_position_cross_->visible_ = true;
|
||||
overlay_position_cross_->translation_.x = s->stored_status_->translation_.x;
|
||||
overlay_position_cross_->translation_.y = s->stored_status_->translation_.y;
|
||||
overlay_position_cross_->update(0);
|
||||
|
||||
glm::vec3 dif = s->stored_status_->translation_ - sourceNode->translation_;
|
||||
if (ABS(dif.x) > ABS(dif.y) ) {
|
||||
sourceNode->translation_.y = s->stored_status_->translation_.y;
|
||||
ret.type = Cursor_ResizeEW;
|
||||
} else {
|
||||
sourceNode->translation_.x = s->stored_status_->translation_.x;
|
||||
ret.type = Cursor_ResizeNS;
|
||||
}
|
||||
}
|
||||
// Show center overlay for POSITION
|
||||
overlay_position_->visible_ = true;
|
||||
overlay_position_->translation_.x = sourceNode->translation_.x;
|
||||
overlay_position_->translation_.y = sourceNode->translation_.y;
|
||||
overlay_position_->update(0);
|
||||
// Show move cursor
|
||||
info << "Position " << std::fixed << std::setprecision(3) << sourceNode->translation_.x;
|
||||
info << ", " << sourceNode->translation_.y ;
|
||||
}
|
||||
}
|
||||
|
||||
// request update
|
||||
s->touch();
|
||||
|
||||
// store action in history
|
||||
current_action_ = s->name() + ": " + info.str();
|
||||
current_id_ = s->id();
|
||||
|
||||
// update cursor
|
||||
ret.info = info.str();
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
void AppearanceView::terminate()
|
||||
{
|
||||
View::terminate();
|
||||
|
||||
// hide all overlays
|
||||
overlay_position_->visible_ = false;
|
||||
overlay_position_cross_->visible_ = false;
|
||||
overlay_scaling_grid_->visible_ = false;
|
||||
overlay_scaling_cross_->visible_ = false;
|
||||
overlay_scaling_->visible_ = false;
|
||||
|
||||
// cancel of all handles overlays
|
||||
glm::vec2 c(0.f, 0.f);
|
||||
for (auto sit = Mixer::manager().session()->begin();
|
||||
sit != Mixer::manager().session()->end(); sit++){
|
||||
|
||||
(*sit)->handles_[mode_][Handles::RESIZE]->overlayActiveCorner(c);
|
||||
(*sit)->handles_[mode_][Handles::RESIZE_H]->overlayActiveCorner(c);
|
||||
(*sit)->handles_[mode_][Handles::RESIZE_V]->overlayActiveCorner(c);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
View::Cursor AppearanceView::drag (glm::vec2 from, glm::vec2 to)
|
||||
{
|
||||
Cursor ret = View::drag(from, to);
|
||||
|
||||
10
View.h
10
View.h
@@ -223,17 +223,25 @@ public:
|
||||
|
||||
void draw () override;
|
||||
|
||||
void update (float dt) override;
|
||||
// void update (float dt) override;
|
||||
void zoom (float factor) override;
|
||||
void resize (int) override;
|
||||
int size () 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 terminate() override;
|
||||
|
||||
private:
|
||||
|
||||
int index_source_;
|
||||
Surface *surfacepreview;
|
||||
|
||||
Node *overlay_position_;
|
||||
Node *overlay_position_cross_;
|
||||
Node *overlay_scaling_;
|
||||
Node *overlay_scaling_cross_;
|
||||
Node *overlay_scaling_grid_;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -71,6 +71,7 @@
|
||||
#define COLOR_HIGHLIGHT_SOURCE 1.f, 1.f, 1.f
|
||||
#define COLOR_TRANSITION_SOURCE 1.f, 0.5f, 1.f
|
||||
#define COLOR_TRANSITION_LINES 0.9f, 0.9f, 0.9f
|
||||
#define COLOR_APPEARANCE_SOURCE 0.0f, 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
|
||||
|
||||
Reference in New Issue
Block a user