mirror of
https://github.com/brunoherbelin/vimix.git
synced 2025-12-05 15:30:00 +01:00
Work-in-progress: Interpolation of snapshot in Action manager
This commit is contained in:
@@ -6,11 +6,13 @@
|
||||
#include "Mixer.h"
|
||||
#include "MixingGroup.h"
|
||||
#include "tinyxml2Toolkit.h"
|
||||
#include "SessionSource.h"
|
||||
//#include "SessionSource.h"
|
||||
#include "ImageProcessingShader.h"
|
||||
#include "SessionVisitor.h"
|
||||
#include "SessionCreator.h"
|
||||
#include "Settings.h"
|
||||
#include "GlmToolkit.h"
|
||||
#include "Interpolator.h"
|
||||
|
||||
#include "ActionManager.h"
|
||||
|
||||
@@ -23,8 +25,10 @@
|
||||
|
||||
using namespace tinyxml2;
|
||||
|
||||
Action::Action(): history_step_(0), history_max_step_(0)
|
||||
Action::Action(): history_step_(0), history_max_step_(0), locked_(false),
|
||||
snapshot_id_(0), snapshot_node_(nullptr), interpolator_(nullptr), interpolator_node_(nullptr)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Action::init()
|
||||
@@ -33,7 +37,11 @@ void Action::init()
|
||||
history_doc_.Clear();
|
||||
history_step_ = 0;
|
||||
history_max_step_ = 0;
|
||||
// start fresh
|
||||
|
||||
// reset snapshot
|
||||
snapshot_id_ = 0;
|
||||
snapshot_node_ = nullptr;
|
||||
|
||||
store("Session start");
|
||||
}
|
||||
|
||||
@@ -177,41 +185,61 @@ void Action::snapshot(const std::string &label)
|
||||
#endif
|
||||
}
|
||||
|
||||
void Action::open(uint64_t snapshotid)
|
||||
{
|
||||
if ( snapshot_id_ != snapshotid )
|
||||
{
|
||||
// get snapshot node of target in current session
|
||||
Session *se = Mixer::manager().session();
|
||||
snapshot_node_ = se->snapshots()->xmlDoc_->FirstChildElement( SNAPSHOT_NODE(snapshotid) );
|
||||
|
||||
if (snapshot_node_)
|
||||
snapshot_id_ = snapshotid;
|
||||
else
|
||||
snapshot_id_ = 0;
|
||||
|
||||
interpolator_node_ = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void Action::replace(uint64_t snapshotid)
|
||||
{
|
||||
// ignore if locked or if no label is given
|
||||
if (locked_)
|
||||
return;
|
||||
|
||||
// get snapshot node of target in current session
|
||||
Session *se = Mixer::manager().session();
|
||||
XMLElement *sessionNode = se->snapshots()->xmlDoc_->FirstChildElement( SNAPSHOT_NODE(snapshotid) );
|
||||
if (snapshotid > 0)
|
||||
open(snapshotid);
|
||||
|
||||
if (sessionNode) {
|
||||
std::string l = sessionNode->Attribute("label");
|
||||
if (snapshot_node_) {
|
||||
// remember label
|
||||
std::string label = snapshot_node_->Attribute("label");
|
||||
|
||||
se->snapshots()->xmlDoc_->DeleteChild( sessionNode );
|
||||
// remove previous node
|
||||
Session *se = Mixer::manager().session();
|
||||
se->snapshots()->xmlDoc_->DeleteChild( snapshot_node_ );
|
||||
|
||||
// create snapshot node
|
||||
sessionNode = se->snapshots()->xmlDoc_->NewElement( SNAPSHOT_NODE(snapshotid) );
|
||||
se->snapshots()->xmlDoc_->InsertEndChild(sessionNode);
|
||||
|
||||
// label describes the snapshot
|
||||
sessionNode->SetAttribute("label", l.c_str());
|
||||
snapshot_node_ = se->snapshots()->xmlDoc_->NewElement( SNAPSHOT_NODE(snapshot_id_) );
|
||||
se->snapshots()->xmlDoc_->InsertEndChild(snapshot_node_);
|
||||
|
||||
// save all sources using source visitor
|
||||
SessionVisitor sv(se->snapshots()->xmlDoc_, sessionNode);
|
||||
for (auto iter = se->begin(); iter != se->end(); ++iter, sv.setRoot(sessionNode) )
|
||||
SessionVisitor sv(se->snapshots()->xmlDoc_, snapshot_node_);
|
||||
for (auto iter = se->begin(); iter != se->end(); ++iter, sv.setRoot(snapshot_node_) )
|
||||
(*iter)->accept(sv);
|
||||
|
||||
// restore label
|
||||
snapshot_node_->SetAttribute("label", label.c_str());
|
||||
|
||||
// debug
|
||||
#ifdef ACTION_DEBUG
|
||||
Log::Info("Snapshot replaced %d '%s'", id, label.c_str());
|
||||
Log::Info("Snapshot replaced %d '%s'", snapshot_id_, label.c_str());
|
||||
#endif
|
||||
}
|
||||
else
|
||||
snapshot_id_ = 0;
|
||||
}
|
||||
|
||||
|
||||
std::list<uint64_t> Action::snapshots() const
|
||||
{
|
||||
Session *se = Mixer::manager().session();
|
||||
@@ -220,39 +248,40 @@ std::list<uint64_t> Action::snapshots() const
|
||||
|
||||
std::string Action::label(uint64_t snapshotid) const
|
||||
{
|
||||
std::string l = "";
|
||||
std::string label = "";
|
||||
|
||||
// get snapshot node of target in current session
|
||||
Session *se = Mixer::manager().session();
|
||||
const XMLElement *sessionNode = se->snapshots()->xmlDoc_->FirstChildElement( SNAPSHOT_NODE(snapshotid) );
|
||||
const XMLElement *snap = se->snapshots()->xmlDoc_->FirstChildElement( SNAPSHOT_NODE(snapshotid) );
|
||||
|
||||
if (sessionNode) {
|
||||
l = sessionNode->Attribute("label");
|
||||
}
|
||||
return l;
|
||||
if (snap)
|
||||
label = snap->Attribute("label");
|
||||
|
||||
return label;
|
||||
}
|
||||
|
||||
void Action::setLabel (uint64_t snapshotid, const std::string &label)
|
||||
{
|
||||
// get snapshot node of target in current session
|
||||
Session *se = Mixer::manager().session();
|
||||
XMLElement *sessionNode = se->snapshots()->xmlDoc_->FirstChildElement( SNAPSHOT_NODE(snapshotid) );
|
||||
open(snapshotid);
|
||||
|
||||
if (sessionNode) {
|
||||
sessionNode->SetAttribute("label", label.c_str());
|
||||
}
|
||||
if (snapshot_node_)
|
||||
snapshot_node_->SetAttribute("label", label.c_str());
|
||||
}
|
||||
|
||||
void Action::remove(uint64_t snapshotid)
|
||||
{
|
||||
// get snapshot node of target in current session
|
||||
Session *se = Mixer::manager().session();
|
||||
XMLElement *sessionNode = se->snapshots()->xmlDoc_->FirstChildElement( SNAPSHOT_NODE(snapshotid) );
|
||||
if (snapshotid > 0)
|
||||
open(snapshotid);
|
||||
|
||||
if (sessionNode) {
|
||||
se->snapshots()->xmlDoc_->DeleteChild( sessionNode );
|
||||
se->snapshots()->keys_.remove(snapshotid);
|
||||
if (snapshot_node_) {
|
||||
// remove
|
||||
Session *se = Mixer::manager().session();
|
||||
se->snapshots()->xmlDoc_->DeleteChild( snapshot_node_ );
|
||||
se->snapshots()->keys_.remove( snapshot_id_ );
|
||||
}
|
||||
|
||||
snapshot_node_ = nullptr;
|
||||
snapshot_id_ = 0;
|
||||
}
|
||||
|
||||
void Action::restore(uint64_t snapshotid)
|
||||
@@ -260,23 +289,75 @@ void Action::restore(uint64_t snapshotid)
|
||||
// lock
|
||||
locked_ = true;
|
||||
|
||||
// get snapshot node of target in current session
|
||||
Session *se = Mixer::manager().session();
|
||||
XMLElement *sessionNode = se->snapshots()->xmlDoc_->FirstChildElement( SNAPSHOT_NODE(snapshotid) );
|
||||
if (snapshotid > 0)
|
||||
open(snapshotid);
|
||||
|
||||
if (sessionNode) {
|
||||
if (snapshot_node_)
|
||||
// actually restore
|
||||
Mixer::manager().restore(sessionNode);
|
||||
}
|
||||
Mixer::manager().restore(snapshot_node_);
|
||||
|
||||
// free
|
||||
locked_ = false;
|
||||
|
||||
store("Snapshot " + label(snapshotid));
|
||||
store("Snapshot " + label(snapshot_id_));
|
||||
}
|
||||
|
||||
|
||||
void Action::interpolate(uint64_t snapshotid, float val)
|
||||
float Action::interpolation()
|
||||
{
|
||||
float ret = 0.f;
|
||||
if ( interpolator_node_ == snapshot_node_ && interpolator_)
|
||||
ret = interpolator_->current();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void Action::interpolate(float val, uint64_t snapshotid)
|
||||
{
|
||||
if (snapshotid > 0)
|
||||
open(snapshotid);
|
||||
|
||||
if (snapshot_node_) {
|
||||
|
||||
if ( interpolator_node_ != snapshot_node_ ) {
|
||||
|
||||
// change interpolator
|
||||
if (interpolator_)
|
||||
delete interpolator_;
|
||||
|
||||
// create new interpolator
|
||||
interpolator_ = new Interpolator;
|
||||
|
||||
// current session
|
||||
Session *se = Mixer::manager().session();
|
||||
|
||||
XMLElement* N = snapshot_node_->FirstChildElement("Source");
|
||||
for( ; N ; N = N->NextSiblingElement()) {
|
||||
|
||||
// check if a source with the given id exists in the session
|
||||
uint64_t id_xml_ = 0;
|
||||
N->QueryUnsigned64Attribute("id", &id_xml_);
|
||||
SourceList::iterator sit = se->find(id_xml_);
|
||||
|
||||
// a source with this id exists
|
||||
if ( sit != se->end() ) {
|
||||
// read target in the snapshot xml
|
||||
SourceCore target;
|
||||
SessionLoader::XMLToSourcecore(N, target);
|
||||
|
||||
// add an interpolator for this source
|
||||
interpolator_->add(*sit, target);
|
||||
}
|
||||
}
|
||||
|
||||
// operate interpolation on opened snapshot
|
||||
interpolator_node_ = snapshot_node_;
|
||||
}
|
||||
|
||||
if (interpolator_) {
|
||||
// Log::Info("Action::interpolate %f", val);
|
||||
interpolator_->apply( val );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
#include <tinyxml2.h>
|
||||
|
||||
|
||||
class Interpolator;
|
||||
|
||||
class Action
|
||||
{
|
||||
@@ -17,36 +17,41 @@ class Action
|
||||
|
||||
public:
|
||||
|
||||
static Action& manager()
|
||||
static Action& manager ()
|
||||
{
|
||||
// The only instance
|
||||
static Action _instance;
|
||||
return _instance;
|
||||
}
|
||||
void init();
|
||||
void init ();
|
||||
|
||||
// UNDO History
|
||||
void store(const std::string &label);
|
||||
void undo();
|
||||
void redo();
|
||||
void stepTo(uint target);
|
||||
void store (const std::string &label);
|
||||
void undo ();
|
||||
void redo ();
|
||||
void stepTo (uint target);
|
||||
|
||||
inline uint current() const { return history_step_; }
|
||||
inline uint max() const { return history_max_step_; }
|
||||
std::string label(uint s) const;
|
||||
inline uint current () const { return history_step_; }
|
||||
inline uint max () const { return history_max_step_; }
|
||||
std::string label (uint s) const;
|
||||
|
||||
// Snapshots
|
||||
void snapshot(const std::string &label);
|
||||
void snapshot (const std::string &label);
|
||||
|
||||
std::list<uint64_t> snapshots() const;
|
||||
void replace(uint64_t snapshotid);
|
||||
void restore(uint64_t snapshotid);
|
||||
void interpolate(uint64_t snapshotid, float val);
|
||||
void remove (uint64_t snapshotid);
|
||||
std::list<uint64_t> snapshots () const;
|
||||
uint64_t currentSnapshot () const { return snapshot_id_; }
|
||||
|
||||
std::string label(uint64_t snapshotid) const;
|
||||
void open (uint64_t snapshotid);
|
||||
void replace (uint64_t snapshotid = 0);
|
||||
void restore (uint64_t snapshotid = 0);
|
||||
void remove (uint64_t snapshotid = 0);
|
||||
|
||||
std::string label (uint64_t snapshotid) const;
|
||||
void setLabel (uint64_t snapshotid, const std::string &label);
|
||||
|
||||
float interpolation ();
|
||||
void interpolate (float val, uint64_t snapshotid = 0);
|
||||
|
||||
private:
|
||||
|
||||
tinyxml2::XMLDocument history_doc_;
|
||||
@@ -55,6 +60,11 @@ private:
|
||||
std::atomic<bool> locked_;
|
||||
void restore(uint target);
|
||||
|
||||
uint64_t snapshot_id_;
|
||||
tinyxml2::XMLElement *snapshot_node_;
|
||||
|
||||
Interpolator *interpolator_;
|
||||
tinyxml2::XMLElement *interpolator_node_;
|
||||
};
|
||||
|
||||
|
||||
|
||||
159
Interpolator.cpp
159
Interpolator.cpp
@@ -4,32 +4,163 @@
|
||||
|
||||
#include "defines.h"
|
||||
#include "Log.h"
|
||||
#include "Source.h"
|
||||
#include "ImageProcessingShader.h"
|
||||
#include "UpdateCallback.h"
|
||||
|
||||
#include "Interpolator.h"
|
||||
|
||||
|
||||
Interpolator::Interpolator(Source *subject, const SourceCore &target) :
|
||||
subject_(subject), from_(static_cast<SourceCore> (*subject)), to_(target), cursor_(0.f)
|
||||
SourceInterpolator::SourceInterpolator(Source *subject, const SourceCore &target) :
|
||||
subject_(subject), from_(static_cast<SourceCore>(*subject)), to_(target), current_cursor_(0.f)
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
void SourceInterpolator::interpolateGroup(View::Mode m)
|
||||
{
|
||||
current_state_.group(m)->translation_ =
|
||||
(1.f - current_cursor_) * from_.group(m)->translation_
|
||||
+ current_cursor_ * to_.group(m)->translation_;
|
||||
current_state_.group(m)->scale_ =
|
||||
(1.f - current_cursor_) * from_.group(m)->scale_
|
||||
+ current_cursor_ * to_.group(m)->scale_;
|
||||
current_state_.group(m)->rotation_ =
|
||||
(1.f - current_cursor_) * from_.group(m)->rotation_
|
||||
+ current_cursor_ * to_.group(m)->rotation_;
|
||||
current_state_.group(m)->crop_ =
|
||||
(1.f - current_cursor_) * from_.group(m)->crop_
|
||||
+ current_cursor_ * to_.group(m)->crop_;
|
||||
|
||||
CopyCallback *anim = new CopyCallback( current_state_.group(m) );
|
||||
subject_->group(m)->update_callbacks_.clear();
|
||||
subject_->group(m)->update_callbacks_.push_back(anim);
|
||||
}
|
||||
|
||||
void SourceInterpolator::interpolateImageProcessing()
|
||||
{
|
||||
current_state_.processingShader()->brightness =
|
||||
(1.f - current_cursor_) * from_.processingShader()->brightness
|
||||
+ current_cursor_ * to_.processingShader()->brightness;
|
||||
|
||||
current_state_.processingShader()->contrast =
|
||||
(1.f - current_cursor_) * from_.processingShader()->contrast
|
||||
+ current_cursor_ * to_.processingShader()->contrast;
|
||||
|
||||
current_state_.processingShader()->saturation =
|
||||
(1.f - current_cursor_) * from_.processingShader()->saturation
|
||||
+ current_cursor_ * to_.processingShader()->saturation;
|
||||
|
||||
current_state_.processingShader()->hueshift =
|
||||
(1.f - current_cursor_) * from_.processingShader()->hueshift
|
||||
+ current_cursor_ * to_.processingShader()->hueshift;
|
||||
|
||||
current_state_.processingShader()->threshold =
|
||||
(1.f - current_cursor_) * from_.processingShader()->threshold
|
||||
+ current_cursor_ * to_.processingShader()->threshold;
|
||||
|
||||
current_state_.processingShader()->lumakey =
|
||||
(1.f - current_cursor_) * from_.processingShader()->lumakey
|
||||
+ current_cursor_ * to_.processingShader()->lumakey;
|
||||
|
||||
current_state_.processingShader()->nbColors =
|
||||
(1.f - current_cursor_) * from_.processingShader()->nbColors
|
||||
+ current_cursor_ * to_.processingShader()->nbColors;
|
||||
|
||||
current_state_.processingShader()->gamma =
|
||||
(1.f - current_cursor_) * from_.processingShader()->gamma
|
||||
+ current_cursor_ * to_.processingShader()->gamma;
|
||||
|
||||
current_state_.processingShader()->levels =
|
||||
(1.f - current_cursor_) * from_.processingShader()->levels
|
||||
+ current_cursor_ * to_.processingShader()->levels;
|
||||
|
||||
current_state_.processingShader()->chromakey =
|
||||
(1.f - current_cursor_) * from_.processingShader()->chromakey
|
||||
+ current_cursor_ * to_.processingShader()->chromakey;
|
||||
|
||||
current_state_.processingShader()->chromadelta =
|
||||
(1.f - current_cursor_) * from_.processingShader()->chromadelta
|
||||
+ current_cursor_ * to_.processingShader()->chromadelta;
|
||||
|
||||
subject_->processingShader()->copy( *current_state_.processingShader() );
|
||||
|
||||
// not interpolated : invert , filterid
|
||||
}
|
||||
|
||||
float SourceInterpolator::current() const
|
||||
{
|
||||
return current_cursor_;
|
||||
}
|
||||
|
||||
void SourceInterpolator::apply(float percent)
|
||||
{
|
||||
percent = CLAMP( percent, 0.f, 1.f);
|
||||
|
||||
if ( subject_ && ABS_DIFF(current_cursor_, percent) > EPSILON)
|
||||
{
|
||||
current_cursor_ = percent;
|
||||
|
||||
if (current_cursor_ < EPSILON) {
|
||||
current_cursor_ = 0.f;
|
||||
current_state_ = from_;
|
||||
subject_->copy(current_state_);
|
||||
}
|
||||
else if (current_cursor_ > 1.f - EPSILON) {
|
||||
current_cursor_ = 1.f;
|
||||
current_state_ = to_;
|
||||
subject_->copy(current_state_);
|
||||
}
|
||||
else {
|
||||
interpolateGroup(View::MIXING);
|
||||
interpolateGroup(View::GEOMETRY);
|
||||
interpolateGroup(View::LAYER);
|
||||
interpolateGroup(View::TEXTURE);
|
||||
interpolateImageProcessing();
|
||||
// Log::Info("SourceInterpolator::update %f", cursor);
|
||||
}
|
||||
|
||||
subject_->touch();
|
||||
}
|
||||
}
|
||||
|
||||
Interpolator::Interpolator()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Interpolator::~Interpolator()
|
||||
{
|
||||
for (auto i = interpolators_.begin(); i != interpolators_.end(); ) {
|
||||
delete *i;
|
||||
i = interpolators_.erase(i);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Interpolator::add (Source *s, const SourceCore &target)
|
||||
{
|
||||
SourceInterpolator *i = new SourceInterpolator(s, target);
|
||||
interpolators_.push_back(i);
|
||||
}
|
||||
|
||||
|
||||
float Interpolator::current() const
|
||||
{
|
||||
float ret = 0.f;
|
||||
if (interpolators_.size() > 0)
|
||||
ret = interpolators_.front()->current();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void Interpolator::apply(float percent)
|
||||
{
|
||||
cursor_ = CLAMP( percent, 0.f, 1.f);
|
||||
|
||||
|
||||
if (cursor_ < EPSILON)
|
||||
current_ = from_;
|
||||
else if (cursor_ > 1.f - EPSILON)
|
||||
current_ = to_;
|
||||
else {
|
||||
// current_ =
|
||||
}
|
||||
|
||||
subject_->copy(current_);
|
||||
for (auto i = interpolators_.begin(); i != interpolators_.end(); ++i)
|
||||
(*i)->apply( percent );
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -2,21 +2,41 @@
|
||||
#define INTERPOLATOR_H
|
||||
|
||||
#include "Source.h"
|
||||
#include "SourceList.h"
|
||||
|
||||
class Interpolator
|
||||
class SourceInterpolator
|
||||
{
|
||||
public:
|
||||
Interpolator(Source *subject, const SourceCore &target);
|
||||
SourceInterpolator(Source *subject, const SourceCore &target);
|
||||
|
||||
void apply (float percent);
|
||||
float current() const;
|
||||
|
||||
protected:
|
||||
Source *subject_;
|
||||
|
||||
SourceCore from_;
|
||||
SourceCore to_;
|
||||
SourceCore current_;
|
||||
SourceCore current_state_;
|
||||
float current_cursor_;
|
||||
|
||||
float cursor_;
|
||||
void interpolateGroup (View::Mode m);
|
||||
void interpolateImageProcessing ();
|
||||
};
|
||||
|
||||
void apply(float percent);
|
||||
class Interpolator
|
||||
{
|
||||
public:
|
||||
Interpolator();
|
||||
~Interpolator();
|
||||
|
||||
void add (Source *s, const SourceCore &target );
|
||||
|
||||
void apply (float percent);
|
||||
float current() const;
|
||||
|
||||
protected:
|
||||
std::list<SourceInterpolator *> interpolators_;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ void Node::copyTransform(const Node *other)
|
||||
{
|
||||
if (!other)
|
||||
return;
|
||||
transform_ = other->transform_;
|
||||
// transform_ = other->transform_;
|
||||
scale_ = other->scale_;
|
||||
rotation_ = other->rotation_;
|
||||
translation_ = other->translation_;
|
||||
|
||||
@@ -530,6 +530,20 @@ void SessionLoader::XMLToNode(tinyxml2::XMLElement *xml, Node &n)
|
||||
}
|
||||
}
|
||||
|
||||
void SessionLoader::XMLToSourcecore( tinyxml2::XMLElement *xml, SourceCore &s)
|
||||
{
|
||||
SessionLoader::XMLToNode(xml->FirstChildElement("Mixing"), *s.group(View::MIXING) );
|
||||
SessionLoader::XMLToNode(xml->FirstChildElement("Geometry"),*s.group(View::GEOMETRY) );
|
||||
SessionLoader::XMLToNode(xml->FirstChildElement("Layer"), *s.group(View::LAYER) );
|
||||
SessionLoader::XMLToNode(xml->FirstChildElement("Texture"), *s.group(View::TEXTURE) );
|
||||
|
||||
SessionLoader v(nullptr);
|
||||
v.xmlCurrent_ = xml->FirstChildElement("ImageProcessing");
|
||||
if (v.xmlCurrent_)
|
||||
s.processingShader()->accept(v);
|
||||
|
||||
}
|
||||
|
||||
void SessionLoader::visit(Node &n)
|
||||
{
|
||||
XMLToNode(xmlCurrent_, n);
|
||||
|
||||
@@ -58,6 +58,9 @@ public:
|
||||
void visit (DeviceSource& s) override;
|
||||
void visit (NetworkSource& s) override;
|
||||
|
||||
static void XMLToNode(tinyxml2::XMLElement *xml, Node &n);
|
||||
static void XMLToSourcecore( tinyxml2::XMLElement *xml, SourceCore &s);
|
||||
|
||||
protected:
|
||||
// result created session
|
||||
Session *session_;
|
||||
@@ -70,7 +73,6 @@ protected:
|
||||
// list of groups (lists of xml source id)
|
||||
std::list< SourceIdList > groups_sources_id_;
|
||||
|
||||
static void XMLToNode(tinyxml2::XMLElement *xml, Node &n);
|
||||
};
|
||||
|
||||
class SessionCreator : public SessionLoader {
|
||||
|
||||
@@ -64,6 +64,7 @@ void Settings::Save()
|
||||
applicationNode->SetAttribute("scale", application.scale);
|
||||
applicationNode->SetAttribute("accent_color", application.accent_color);
|
||||
applicationNode->SetAttribute("smooth_transition", application.smooth_transition);
|
||||
applicationNode->SetAttribute("smooth_snapshot", application.smooth_snapshot);
|
||||
applicationNode->SetAttribute("smooth_cursor", application.smooth_cursor);
|
||||
applicationNode->SetAttribute("action_history_follow_view", application.action_history_follow_view);
|
||||
applicationNode->SetAttribute("accept_connections", application.accept_connections);
|
||||
@@ -255,6 +256,7 @@ void Settings::Load()
|
||||
applicationNode->QueryFloatAttribute("scale", &application.scale);
|
||||
applicationNode->QueryIntAttribute("accent_color", &application.accent_color);
|
||||
applicationNode->QueryBoolAttribute("smooth_transition", &application.smooth_transition);
|
||||
applicationNode->QueryBoolAttribute("smooth_snapshot", &application.smooth_snapshot);
|
||||
applicationNode->QueryBoolAttribute("smooth_cursor", &application.smooth_cursor);
|
||||
applicationNode->QueryBoolAttribute("action_history_follow_view", &application.action_history_follow_view);
|
||||
applicationNode->QueryBoolAttribute("accept_connections", &application.accept_connections);
|
||||
|
||||
@@ -178,6 +178,7 @@ struct Application
|
||||
// Global settings Application interface
|
||||
float scale;
|
||||
int accent_color;
|
||||
bool smooth_snapshot;
|
||||
bool smooth_transition;
|
||||
bool smooth_cursor;
|
||||
bool action_history_follow_view;
|
||||
@@ -221,7 +222,8 @@ struct Application
|
||||
Application() : fresh_start(false), instance_id(0), name(APP_NAME), executable(APP_NAME) {
|
||||
scale = 1.f;
|
||||
accent_color = 0;
|
||||
smooth_transition = true;
|
||||
smooth_transition = false;
|
||||
smooth_snapshot = false;
|
||||
smooth_cursor = false;
|
||||
action_history_follow_view = false;
|
||||
accept_connections = false;
|
||||
|
||||
@@ -69,7 +69,7 @@ SourceCore::~SourceCore()
|
||||
void SourceCore::copy(SourceCore const& other)
|
||||
{
|
||||
// copy groups properties
|
||||
groups_[View::RENDERING]->copyTransform( other.group(View::RENDERING) );
|
||||
// groups_[View::RENDERING]->copyTransform( other.group(View::RENDERING) );
|
||||
groups_[View::MIXING]->copyTransform( other.group(View::MIXING) );
|
||||
groups_[View::GEOMETRY]->copyTransform( other.group(View::GEOMETRY) );
|
||||
groups_[View::LAYER]->copyTransform( other.group(View::LAYER) );
|
||||
@@ -84,14 +84,13 @@ void SourceCore::copy(SourceCore const& other)
|
||||
|
||||
void SourceCore::store (View::Mode m)
|
||||
{
|
||||
stored_status_->copyTransform(groups_[m]);
|
||||
stored_status_->copyTransform(groups_[m]);
|
||||
}
|
||||
|
||||
SourceCore& SourceCore::operator= (SourceCore const& other)
|
||||
{
|
||||
if (this != &other) { // no self assignment
|
||||
if (this != &other) // no self assignment
|
||||
copy(other);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,9 +5,11 @@
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
class Source;
|
||||
class SourceCore;
|
||||
class Session;
|
||||
|
||||
typedef std::list<Source *> SourceList;
|
||||
typedef std::list<SourceCore *> SourceCoreList;
|
||||
|
||||
SourceList depth_sorted (const SourceList &list);
|
||||
SourceList mixing_sorted (const SourceList &list, glm::vec2 center = glm::vec2(0.f, 0.f));
|
||||
|
||||
@@ -11,6 +11,18 @@ UpdateCallback::UpdateCallback() : enabled_(true), finished_(false)
|
||||
|
||||
}
|
||||
|
||||
CopyCallback::CopyCallback(Node *target) : UpdateCallback(), target_(target)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void CopyCallback::update(Node *n, float dt)
|
||||
{
|
||||
n->copyTransform(target_);
|
||||
finished_ = true;
|
||||
}
|
||||
|
||||
|
||||
MoveToCallback::MoveToCallback(glm::vec3 target, float duration) : UpdateCallback(),
|
||||
duration_(duration), progress_(0.f), initialized_(false), target_(target)
|
||||
{
|
||||
|
||||
@@ -22,6 +22,15 @@ protected:
|
||||
bool finished_;
|
||||
};
|
||||
|
||||
class CopyCallback : public UpdateCallback
|
||||
{
|
||||
Node *target_;
|
||||
|
||||
public:
|
||||
CopyCallback(Node *target);
|
||||
void update(Node *n, float dt);
|
||||
};
|
||||
|
||||
class MoveToCallback : public UpdateCallback
|
||||
{
|
||||
float duration_;
|
||||
|
||||
@@ -3129,14 +3129,14 @@ void Navigator::RenderMainPannelVimix()
|
||||
ImGui::TextDisabled( ICON_FA_REDO );
|
||||
|
||||
ImGui::SetCursorPos( ImVec2( pannel_width_ IMGUI_RIGHT_ALIGN, pos_bot.y - ImGui::GetFrameHeightWithSpacing()) );
|
||||
ImGuiToolkit::ButtonToggle(ICON_FA_ELLIPSIS_H, &Settings::application.action_history_follow_view);
|
||||
ImGuiToolkit::ButtonToggle(ICON_FA_LOCATION_ARROW, &Settings::application.action_history_follow_view);
|
||||
if (ImGui::IsItemHovered())
|
||||
ImGuiToolkit::ToolTip("Go to view of action");
|
||||
ImGuiToolkit::ToolTip("Show in view");
|
||||
}
|
||||
else {
|
||||
|
||||
std::list<uint64_t> snapshots = Action::manager().snapshots();
|
||||
static uint64_t current_snapshot = 0;
|
||||
// static uint64_t current_snapshot = Action::manager().currentSnapshot();
|
||||
|
||||
pos_top = ImGui::GetCursorPos();
|
||||
ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN);
|
||||
@@ -3147,20 +3147,20 @@ void Navigator::RenderMainPannelVimix()
|
||||
{
|
||||
// size of items
|
||||
ImVec2 s = size;
|
||||
if ( current_snapshot == *snapit )
|
||||
bool selected = ( *snapit == Action::manager().currentSnapshot() );
|
||||
if ( selected )
|
||||
s.x -= ImGui::GetTextLineHeightWithSpacing();
|
||||
// entry
|
||||
if (ImGui::Selectable( Action::manager().label(*snapit).c_str(), current_snapshot == *snapit, ImGuiSelectableFlags_AllowDoubleClick, s )) {
|
||||
if (ImGui::Selectable( Action::manager().label(*snapit).c_str(), selected, ImGuiSelectableFlags_AllowDoubleClick, s )) {
|
||||
// current list item
|
||||
current_snapshot = *snapit;
|
||||
if (ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left)) {
|
||||
// trigger snapshot
|
||||
Action::manager().restore(current_snapshot);
|
||||
current_snapshot = 0;
|
||||
}
|
||||
Action::manager().open(*snapit);
|
||||
|
||||
// trigger snapshot
|
||||
if (ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left))
|
||||
Action::manager().restore();
|
||||
}
|
||||
// context menu
|
||||
if ( current_snapshot == *snapit ) {
|
||||
if ( selected ) {
|
||||
ImGui::SameLine();
|
||||
if ( ImGuiToolkit::IconButton( ICON_FA_CHEVRON_DOWN ) )
|
||||
ImGui::OpenPopup( "MenuSnapshot" );
|
||||
@@ -3170,25 +3170,19 @@ void Navigator::RenderMainPannelVimix()
|
||||
// context menu
|
||||
if (ImGui::BeginPopup( "MenuSnapshot" ))
|
||||
{
|
||||
if (ImGui::Selectable( " " ICON_FA_ANGLE_DOUBLE_RIGHT " Apply", false, 0, size )) {
|
||||
Action::manager().restore(current_snapshot);
|
||||
current_snapshot = 0;
|
||||
}
|
||||
if (ImGui::Selectable( ICON_FA_STAR "_ Remove", false, 0, size )) {
|
||||
Action::manager().remove(current_snapshot);
|
||||
current_snapshot = 0;
|
||||
}
|
||||
if (ImGui::Selectable( ICON_FA_STAR "= Replace", false, 0, size )) {
|
||||
Action::manager().replace(current_snapshot);
|
||||
current_snapshot = 0;
|
||||
}
|
||||
if (ImGui::Selectable( " " ICON_FA_ANGLE_DOUBLE_RIGHT " Apply", false, 0, size ))
|
||||
Action::manager().restore();
|
||||
if (ImGui::Selectable( ICON_FA_STAR "_ Remove", false, 0, size ))
|
||||
Action::manager().remove();
|
||||
if (ImGui::Selectable( ICON_FA_STAR "= Replace", false, 0, size ))
|
||||
Action::manager().replace();
|
||||
ImGui::TextDisabled("Rename");
|
||||
ImGui::SetNextItemWidth(size.x);
|
||||
if ( current_snapshot > 0 ) {
|
||||
if ( Action::manager().currentSnapshot() > 0 ) {
|
||||
static std::string label;
|
||||
label = Action::manager().label(current_snapshot);
|
||||
label = Action::manager().label( Action::manager().currentSnapshot() );
|
||||
if ( ImGuiToolkit::InputText("##Rename", &label ) )
|
||||
Action::manager().setLabel(current_snapshot, label);
|
||||
Action::manager().setLabel( Action::manager().currentSnapshot(), label);
|
||||
}
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
@@ -3199,13 +3193,18 @@ void Navigator::RenderMainPannelVimix()
|
||||
|
||||
// right buttons
|
||||
ImGui::SetCursorPos( ImVec2( pannel_width_ IMGUI_RIGHT_ALIGN, pos_top.y ));
|
||||
if ( ImGuiToolkit::IconButton( ICON_FA_STAR "+")) {
|
||||
if ( ImGuiToolkit::IconButton( ICON_FA_STAR "+"))
|
||||
Action::manager().snapshot( SystemToolkit::date_time_string() );
|
||||
current_snapshot = 0;
|
||||
}
|
||||
if (ImGui::IsItemHovered())
|
||||
ImGuiToolkit::ToolTip("Take Snapshot ", CTRL_MOD "Y");
|
||||
|
||||
// toggle button for smooth transition
|
||||
ImGui::SetCursorPos( ImVec2( pannel_width_ IMGUI_RIGHT_ALIGN, pos_bot.y - ImGui::GetFrameHeightWithSpacing()) );
|
||||
ImGuiToolkit::ButtonToggle(ICON_FA_ROUTE, &Settings::application.smooth_snapshot);
|
||||
if (ImGui::IsItemHovered())
|
||||
ImGuiToolkit::ToolTip("Interpolation");
|
||||
|
||||
|
||||
// // active list element : delete snapshot button
|
||||
// ImGui::SetCursorPos( ImVec2( pannel_width_ IMGUI_RIGHT_ALIGN, pos_bot.y - ImGui::GetFrameHeightWithSpacing()));
|
||||
// if (current_snapshot != snapshots.end()) {
|
||||
@@ -3218,13 +3217,13 @@ void Navigator::RenderMainPannelVimix()
|
||||
// else
|
||||
// ImGui::TextDisabled( ICON_FA_STAR "_" );
|
||||
|
||||
if (current_snapshot > 0) {
|
||||
if (Action::manager().currentSnapshot() > 0) {
|
||||
ImGui::SetCursorPos( pos_bot );
|
||||
static float interpolation = 0.f;
|
||||
int interpolation = static_cast<int> (Action::manager().interpolation() * 100.f);
|
||||
ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN);
|
||||
if ( ImGui::SliderFloat("Animate", &interpolation, 0.f, 1.f) ) {
|
||||
if ( ImGui::SliderInt("Animate", &interpolation, 0, 100, "%d %%") )
|
||||
Action::manager().interpolate( static_cast<float> ( interpolation ) * 0.01f );
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user