diff --git a/src/Mixer.cpp b/src/Mixer.cpp index 91bccf9..bd7b9dd 100644 --- a/src/Mixer.cpp +++ b/src/Mixer.cpp @@ -18,6 +18,8 @@ **/ #include +#include +#include #include #include #include @@ -30,19 +32,17 @@ #include #include "ImageShader.h" -#include "Source/TextSource.h" #include "defines.h" #include "Settings.h" #include "Log.h" #include "View/View.h" #include "Toolkit/BaseToolkit.h" #include "Toolkit/SystemToolkit.h" -#include "SessionCreator.h" #include "Visitor/SessionVisitor.h" +#include "Source/TextSource.h" #include "Source/SessionSource.h" #include "Source/CloneSource.h" #include "Source/RenderSource.h" -#include "MediaPlayer.h" #include "Source/MediaSource.h" #include "Source/PatternSource.h" #include "Source/DeviceSource.h" @@ -54,9 +54,12 @@ #include "Source/SrtReceiverSource.h" #include "Source/SourceCallback.h" +#include "SessionCreator.h" +#include "MediaPlayer.h" #include "ActionManager.h" #include "MixingGroup.h" #include "FrameGrabber.h" +#include "Visitor/BoundingBoxVisitor.h" #include "Mixer.h" @@ -808,8 +811,12 @@ void Mixer::group(SourceList sourcelist) // create session group where to transfer sources into SessionGroupSource *sessiongroup = new SessionGroupSource; - sessiongroup->setResolution( session_->frame()->resolution() ); + // compute dimensions to cover all sources + GlmToolkit::AxisAlignedBoundingBox selection_box = BoundingBoxVisitor::AABB(sourcelist, &geometry_); + sessiongroup->setDimensions( selection_box.scale(), selection_box.center(), + session_->frame()->resolution().y ); + // prepare for new session group name std::string name; // prepare for depth to place the group source @@ -851,6 +858,12 @@ void Mixer::group(SourceList sourcelist) sessiongroup->group(View::MIXING)->translation_.x = 0.f; sessiongroup->group(View::MIXING)->translation_.y = 0.f; + // set geometry + sessiongroup->group(View::GEOMETRY)->translation_ = sessiongroup->center(); + sessiongroup->group(View::GEOMETRY)->scale_ = sessiongroup->scale(); + // correct for aspect ratio done by SessionGroupSource resolution + sessiongroup->group(View::GEOMETRY)->scale_.x = sessiongroup->group(View::GEOMETRY)->scale_.y; + // Add source to Session session_->addSource(sessiongroup); diff --git a/src/SessionCreator.cpp b/src/SessionCreator.cpp index 442c348..6c934ac 100644 --- a/src/SessionCreator.cpp +++ b/src/SessionCreator.cpp @@ -17,6 +17,8 @@ * along with this program. If not, see . **/ +#include +#include #include #include @@ -1225,8 +1227,23 @@ void SessionLoader::visit (SessionFileSource& s) void SessionLoader::visit (SessionGroupSource& s) { - // set resolution from host session - s.setResolution( session_->config(View::RENDERING)->scale_ ); + float height = 0.f; + xmlCurrent_->QueryFloatAttribute("height", &height); + if (height > 0.f) { + // load dimensions + glm::vec3 scale(1.f), center(0.f); + const XMLElement *scaleNode = xmlCurrent_->FirstChildElement("scale"); + if (scaleNode) + tinyxml2::XMLElementToGLM( scaleNode->FirstChildElement("vec3"), scale); + const XMLElement *centerNode = xmlCurrent_->FirstChildElement("center"); + if (centerNode) + tinyxml2::XMLElementToGLM( centerNode->FirstChildElement("vec3"), center); + s.setDimensions(scale, center, height); + } + else { + // set resolution from host session + s.setResolution( session_->config(View::RENDERING)->scale_ ); + } // get the inside session XMLElement* sessionGroupNode = xmlCurrent_->FirstChildElement("Session"); diff --git a/src/Source/SessionSource.cpp b/src/Source/SessionSource.cpp index 4656632..8c559ca 100644 --- a/src/Source/SessionSource.cpp +++ b/src/Source/SessionSource.cpp @@ -19,6 +19,8 @@ #include +#include +#include #include #include "defines.h" @@ -424,7 +426,10 @@ std::string SessionFileSource::info() const } -SessionGroupSource::SessionGroupSource(uint64_t id) : SessionSource(id), resolution_(glm::vec3(0.f)) +SessionGroupSource::SessionGroupSource(uint64_t id) : SessionSource(id), + resolution_(glm::vec3(0.f)), + dimension_scale_(glm::vec3(1.f)), + dimension_center_(glm::vec3(0.f)) { // set symbol symbol_ = new Symbol(Symbol::GROUP, glm::vec3(0.75f, 0.75f, 0.01f)); @@ -479,9 +484,23 @@ void SessionGroupSource::setSession (Session *s) delete session_; session_ = s; resolution_ = s->frame()->resolution(); + dimension_scale_ = glm::vec3(1.f); + dimension_center_ = glm::vec3(0.f); } } +void SessionGroupSource::setDimensions(glm::vec3 scale, glm::vec3 center, float height) +{ + // compute resolution from height if given + if ( height > 0.f ) { + float H = height * scale.y; + resolution_ = glm::vec3( H * (scale.x / scale.y), H, 0.f ); + } + + dimension_scale_ = scale; + dimension_center_ = center; +} + bool SessionGroupSource::import(Source *source) { bool ret = false; @@ -489,8 +508,17 @@ bool SessionGroupSource::import(Source *source) if ( session_ ) { SourceList::iterator its = session_->addSource(source); - if (its != session_->end()) + if (its != session_->end()) { ret = true; + // update geometry to match scale and center of the SessionGroupSource + glm::vec3 scaling = dimension_scale_; + scaling.x = scaling.y ; + (*its)->group(View::RENDERING)->scale_ = source->group(View::RENDERING)->scale_ / scaling; + (*its)->group(View::RENDERING)->translation_ = (source->group(View::RENDERING)->translation_ - dimension_center_) / scaling ; + // keep geometry in GEOMETRY view in sync + (*its)->group(View::GEOMETRY)->scale_ = source->group(View::RENDERING)->scale_; + (*its)->group(View::GEOMETRY)->translation_ = source->group(View::RENDERING)->translation_; + } } return ret; diff --git a/src/Source/SessionSource.h b/src/Source/SessionSource.h index 2aa55cb..c9e6d53 100644 --- a/src/Source/SessionSource.h +++ b/src/Source/SessionSource.h @@ -72,6 +72,10 @@ public: // SessionGroup Source specific interface void setSession (Session *s); inline void setResolution (glm::vec3 v) { resolution_ = v; } + inline glm::vec3 resolution() const { return resolution_; } + void setDimensions( glm::vec3 scale, glm::vec3 center, float height); + inline glm::vec3 scale() const { return dimension_scale_; } + inline glm::vec3 center() const { return dimension_center_; } // import a source bool import(Source *source); @@ -83,6 +87,7 @@ protected: void init() override; glm::vec3 resolution_; + glm::vec3 dimension_scale_, dimension_center_; }; #endif // SESSIONSOURCE_H diff --git a/src/Visitor/SessionVisitor.cpp b/src/Visitor/SessionVisitor.cpp index c7ab53c..6f4057e 100644 --- a/src/Visitor/SessionVisitor.cpp +++ b/src/Visitor/SessionVisitor.cpp @@ -722,6 +722,14 @@ void SessionVisitor::visit (SessionFileSource& s) void SessionVisitor::visit (SessionGroupSource& s) { xmlCurrent_->SetAttribute("type", "GroupSource"); + xmlCurrent_->SetAttribute("height", (float) s.frame()->height()); + + XMLElement *center = xmlDoc_->NewElement("center"); + center->InsertEndChild( XMLElementFromGLM(xmlDoc_, s.center()) ); + xmlCurrent_->InsertEndChild(center); + XMLElement *scale = xmlDoc_->NewElement("scale"); + scale->InsertEndChild( XMLElementFromGLM(xmlDoc_, s.scale()) ); + xmlCurrent_->InsertEndChild(scale); Session *se = s.session(); if (se) {