mirror of
https://github.com/brunoherbelin/vimix.git
synced 2025-12-07 16:30:00 +01:00
BugFix Set Clone filter Uniform using callback for OSC
Async call to setProgramParameter is unsave (Issue #149).
This commit is contained in:
@@ -961,7 +961,7 @@ bool Control::receiveSourceAttribute(Source *target, const std::string &attribut
|
||||
}
|
||||
/// e.g. '/vimix/current/contents s text'
|
||||
else if (attribute.compare(OSC_SOURCE_CONTENTS) == 0) {
|
||||
// try by client name if given: remove all streams with that name
|
||||
// get text
|
||||
const char *label = nullptr;
|
||||
arguments >> label >> osc::EndMessage;
|
||||
TextSource *textsrc = dynamic_cast<TextSource *>(target);
|
||||
@@ -971,27 +971,17 @@ bool Control::receiveSourceAttribute(Source *target, const std::string &attribut
|
||||
}
|
||||
/// e.g. '/vimix/current/uniform sf var 0.5'
|
||||
else if (attribute.compare(OSC_SOURCE_UNIFORM) == 0) {
|
||||
std::string uniform_name;
|
||||
float t = 0.f;
|
||||
// get uniform name and value
|
||||
float uniform_value = NAN;
|
||||
|
||||
// get uniform name
|
||||
const char *str = nullptr;
|
||||
arguments >> str;
|
||||
if (str)
|
||||
{
|
||||
uniform_name = std::string(str);
|
||||
|
||||
// get uniform value
|
||||
arguments >> uniform_value >> osc::EndMessage;
|
||||
|
||||
// apply to ImageFilter source only
|
||||
CloneSource *clonesrc = dynamic_cast<CloneSource *>(target);
|
||||
if (clonesrc) {
|
||||
ImageFilter *f = dynamic_cast<ImageFilter *>(clonesrc->filter());
|
||||
if (f) {
|
||||
f->setProgramParameter(uniform_name, uniform_value);
|
||||
}
|
||||
}
|
||||
arguments >> str >> uniform_value;
|
||||
if (arguments.Eos())
|
||||
arguments >> osc::EndMessage;
|
||||
else
|
||||
arguments >> t >> osc::EndMessage;
|
||||
if (str && uniform_value != NAN) {
|
||||
target->call(new SetFilterUniform(std::string(str), uniform_value, t), true);
|
||||
}
|
||||
}
|
||||
/// e.g. '/vimix/current/filter sf blur 0.5'
|
||||
|
||||
@@ -1334,3 +1334,83 @@ void SetFilter::accept(Visitor& v)
|
||||
v.visit(*this);
|
||||
}
|
||||
|
||||
SetFilterUniform::SetFilterUniform(const std::string &uniform, float value, float ms)
|
||||
: SourceCallback()
|
||||
, uniform_(uniform)
|
||||
, target_(value)
|
||||
, start_(0.f)
|
||||
, duration_(ms)
|
||||
{
|
||||
imagefilter = nullptr;
|
||||
}
|
||||
|
||||
void SetFilterUniform::update(Source *s, float dt)
|
||||
{
|
||||
SourceCallback::update(s, dt);
|
||||
CloneSource *clonesrc = dynamic_cast<CloneSource *>(s);
|
||||
|
||||
if (s->locked() || !clonesrc)
|
||||
status_ = FINISHED;
|
||||
|
||||
|
||||
// set start on first time it is ready
|
||||
if (status_ == READY) {
|
||||
// by default it will finish if all tests below fail
|
||||
status_ = FINISHED;
|
||||
// if there is an image filter in the clone source
|
||||
imagefilter = dynamic_cast<ImageFilter *>(clonesrc->filter());
|
||||
if (imagefilter) {
|
||||
// get the list of parameters
|
||||
std::map<std::string, float> params = imagefilter->program().parameters();
|
||||
// if there is a parameter named as given
|
||||
auto p = params.find(uniform_);
|
||||
if (p != params.end()) {
|
||||
// set start value to the current value
|
||||
start_ = p->second;
|
||||
// if a valid target value is given
|
||||
if (!std::isnan(target_))
|
||||
// then activate for value update
|
||||
status_ = ACTIVE;
|
||||
}
|
||||
else
|
||||
Log::Info("Filter : unknown uniform '%s'", uniform_.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
// set value
|
||||
if (status_ == ACTIVE && imagefilter) {
|
||||
|
||||
// time passed since start
|
||||
float progress = elapsed_ - delay_;
|
||||
|
||||
// time-out or instantaneous
|
||||
if (!(ABS(duration_) > 0.f) || progress > duration_) {
|
||||
// apply target value
|
||||
imagefilter->setProgramParameter(uniform_, target_);
|
||||
// done
|
||||
status_ = FINISHED;
|
||||
}
|
||||
else {
|
||||
// apply calculated intermediate value
|
||||
imagefilter->setProgramParameter(uniform_,
|
||||
glm::mix(start_, target_, progress / duration_));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void SetFilterUniform::multiply (float factor)
|
||||
{
|
||||
target_ *= factor;
|
||||
}
|
||||
|
||||
SourceCallback *SetFilterUniform::clone() const
|
||||
{
|
||||
return new SetFilterUniform(uniform_, target_, duration_);
|
||||
}
|
||||
|
||||
void SetFilterUniform::accept(Visitor& v)
|
||||
{
|
||||
SourceCallback::accept(v);
|
||||
v.visit(*this);
|
||||
}
|
||||
|
||||
@@ -51,7 +51,8 @@ public:
|
||||
CALLBACK_THRESHOLD,
|
||||
CALLBACK_INVERT,
|
||||
CALLBACK_POSTERIZE,
|
||||
CALLBACK_FILTER
|
||||
CALLBACK_FILTER,
|
||||
CALLBACK_FILTER_UNIFORM
|
||||
} CallbackType;
|
||||
|
||||
static SourceCallback *create(CallbackType type);
|
||||
@@ -507,4 +508,28 @@ public:
|
||||
void accept (Visitor& v) override;
|
||||
};
|
||||
|
||||
class SetFilterUniform : public SourceCallback
|
||||
{
|
||||
std::string uniform_;
|
||||
float target_;
|
||||
float start_;
|
||||
float duration_;
|
||||
class ImageFilter *imagefilter;
|
||||
|
||||
public:
|
||||
SetFilterUniform (const std::string &uniform = std::string(),
|
||||
float value = NAN, float ms = 0.f);
|
||||
|
||||
float value () const { return target_; }
|
||||
void setValue (float g) { target_ = g; }
|
||||
float duration () const { return duration_; }
|
||||
void setDuration (float ms) { duration_ = ms; }
|
||||
|
||||
void update (Source *s, float) override;
|
||||
void multiply (float factor) override;
|
||||
SourceCallback *clone () const override;
|
||||
CallbackType type () const override { return CALLBACK_FILTER_UNIFORM; }
|
||||
void accept (Visitor& v) override;
|
||||
};
|
||||
|
||||
#endif // SOURCECALLBACK_H
|
||||
|
||||
Reference in New Issue
Block a user