|
|
|
@@ -28,17 +28,22 @@ TransitionBlock::TransitionBlock() :
|
|
|
|
|
connected_out_block_(nullptr),
|
|
|
|
|
connected_in_block_(nullptr)
|
|
|
|
|
{
|
|
|
|
|
out_block_input_ = new NodeInput("out_block_in", NodeParam::kBuffer);
|
|
|
|
|
out_block_input_ = new NodeInput(QStringLiteral("out_block_in"), NodeParam::kBuffer);
|
|
|
|
|
out_block_input_->set_is_keyframable(false);
|
|
|
|
|
connect(out_block_input_, &NodeParam::EdgeAdded, this, &TransitionBlock::BlockConnected);
|
|
|
|
|
connect(out_block_input_, &NodeParam::EdgeRemoved, this, &TransitionBlock::BlockDisconnected);
|
|
|
|
|
AddInput(out_block_input_);
|
|
|
|
|
|
|
|
|
|
in_block_input_ = new NodeInput("in_block_in", NodeParam::kBuffer);
|
|
|
|
|
in_block_input_ = new NodeInput(QStringLiteral("in_block_in"), NodeParam::kBuffer);
|
|
|
|
|
in_block_input_->set_is_keyframable(false);
|
|
|
|
|
connect(in_block_input_, &NodeParam::EdgeAdded, this, &TransitionBlock::BlockConnected);
|
|
|
|
|
connect(in_block_input_, &NodeParam::EdgeRemoved, this, &TransitionBlock::BlockDisconnected);
|
|
|
|
|
AddInput(in_block_input_);
|
|
|
|
|
|
|
|
|
|
curve_input_ = new NodeInput(QStringLiteral("curve_in"), NodeParam::kCombo);
|
|
|
|
|
curve_input_->set_is_keyframable(false);
|
|
|
|
|
curve_input_->set_connectable(false);
|
|
|
|
|
AddInput(curve_input_);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Block::Type TransitionBlock::type() const
|
|
|
|
@@ -62,6 +67,10 @@ void TransitionBlock::Retranslate()
|
|
|
|
|
|
|
|
|
|
out_block_input_->set_name(tr("From"));
|
|
|
|
|
in_block_input_->set_name(tr("To"));
|
|
|
|
|
curve_input_->set_name(tr("Curve"));
|
|
|
|
|
|
|
|
|
|
// These must correspond to the CurveType enum
|
|
|
|
|
curve_input_->set_combobox_strings({ tr("Linear"), tr("Exponential"), tr("Logarithmic") });
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
rational TransitionBlock::in_offset() const
|
|
|
|
@@ -106,12 +115,12 @@ Block *TransitionBlock::connected_in_block() const
|
|
|
|
|
return connected_in_block_;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
double TransitionBlock::GetTotalProgress(const rational &time) const
|
|
|
|
|
double TransitionBlock::GetTotalProgress(const double &time) const
|
|
|
|
|
{
|
|
|
|
|
return GetInternalTransitionTime(time) / length().toDouble();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
double TransitionBlock::GetOutProgress(const rational &time) const
|
|
|
|
|
double TransitionBlock::GetOutProgress(const double &time) const
|
|
|
|
|
{
|
|
|
|
|
if (out_offset() == 0) {
|
|
|
|
|
return 0;
|
|
|
|
@@ -120,7 +129,7 @@ double TransitionBlock::GetOutProgress(const rational &time) const
|
|
|
|
|
return clamp(1.0 - (GetInternalTransitionTime(time) / out_offset().toDouble()), 0.0, 1.0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
double TransitionBlock::GetInProgress(const rational &time) const
|
|
|
|
|
double TransitionBlock::GetInProgress(const double &time) const
|
|
|
|
|
{
|
|
|
|
|
if (in_offset() == 0) {
|
|
|
|
|
return 0;
|
|
|
|
@@ -133,18 +142,34 @@ void TransitionBlock::Hash(QCryptographicHash &hash, const rational &time) const
|
|
|
|
|
{
|
|
|
|
|
Node::Hash(hash, time);
|
|
|
|
|
|
|
|
|
|
double all_prog = GetTotalProgress(time);
|
|
|
|
|
double in_prog = GetInProgress(time);
|
|
|
|
|
double out_prog = GetOutProgress(time);
|
|
|
|
|
double time_dbl = time.toDouble();
|
|
|
|
|
double all_prog = GetTotalProgress(time_dbl);
|
|
|
|
|
double in_prog = GetInProgress(time_dbl);
|
|
|
|
|
double out_prog = GetOutProgress(time_dbl);
|
|
|
|
|
|
|
|
|
|
hash.addData(reinterpret_cast<const char*>(&all_prog), sizeof(double));
|
|
|
|
|
hash.addData(reinterpret_cast<const char*>(&in_prog), sizeof(double));
|
|
|
|
|
hash.addData(reinterpret_cast<const char*>(&out_prog), sizeof(double));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
double TransitionBlock::GetInternalTransitionTime(const rational &time) const
|
|
|
|
|
double TransitionBlock::GetInternalTransitionTime(const double &time) const
|
|
|
|
|
{
|
|
|
|
|
return time.toDouble() - in().toDouble();
|
|
|
|
|
return time - in().toDouble();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void TransitionBlock::InsertTransitionTimes(AcceleratedJob *job, const double &time) const
|
|
|
|
|
{
|
|
|
|
|
// Provides total transition progress from 0.0 (start) - 1.0 (end)
|
|
|
|
|
job->InsertValue(QStringLiteral("ove_tprog_all"),
|
|
|
|
|
NodeValue(NodeParam::kFloat, GetTotalProgress(time), this));
|
|
|
|
|
|
|
|
|
|
// Provides progress of out section from 1.0 (start) - 0.0 (end)
|
|
|
|
|
job->InsertValue(QStringLiteral("ove_tprog_out"),
|
|
|
|
|
NodeValue(NodeParam::kFloat, GetOutProgress(time), this));
|
|
|
|
|
|
|
|
|
|
// Provides progress of in section from 0.0 (start) - 1.0 (end)
|
|
|
|
|
job->InsertValue(QStringLiteral("ove_tprog_in"),
|
|
|
|
|
NodeValue(NodeParam::kFloat, GetInProgress(time), this));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void TransitionBlock::BlockConnected(NodeEdgePtr edge)
|
|
|
|
@@ -173,16 +198,62 @@ void TransitionBlock::BlockDisconnected(NodeEdgePtr edge)
|
|
|
|
|
|
|
|
|
|
NodeValueTable TransitionBlock::Value(NodeValueDatabase &value) const
|
|
|
|
|
{
|
|
|
|
|
ShaderJob job;
|
|
|
|
|
NodeParam::DataType data_type;
|
|
|
|
|
|
|
|
|
|
job.InsertValue(out_block_input(), value);
|
|
|
|
|
job.InsertValue(in_block_input(), value);
|
|
|
|
|
job.SetAlphaChannelRequired(true);
|
|
|
|
|
if (out_block_input()->is_connected()) {
|
|
|
|
|
data_type = value[out_block_input()].GetWithMeta(NodeParam::kBuffer).type();
|
|
|
|
|
} else if (in_block_input()->is_connected()) {
|
|
|
|
|
data_type = value[in_block_input()].GetWithMeta(NodeParam::kBuffer).type();
|
|
|
|
|
} else {
|
|
|
|
|
data_type = NodeParam::kNone;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ShaderJobEvent(value, job);
|
|
|
|
|
NodeParam::DataType job_type;
|
|
|
|
|
QVariant push_job;
|
|
|
|
|
|
|
|
|
|
if (data_type == NodeParam::kTexture) {
|
|
|
|
|
// This must be a visual transition
|
|
|
|
|
ShaderJob job;
|
|
|
|
|
|
|
|
|
|
job.InsertValue(out_block_input(), value);
|
|
|
|
|
job.InsertValue(in_block_input(), value);
|
|
|
|
|
job.InsertValue(curve_input_, value);
|
|
|
|
|
job.SetAlphaChannelRequired(true);
|
|
|
|
|
|
|
|
|
|
double time = value[QStringLiteral("global")].Get(NodeParam::kFloat, QStringLiteral("time_in")).toDouble();
|
|
|
|
|
InsertTransitionTimes(&job, time);
|
|
|
|
|
|
|
|
|
|
ShaderJobEvent(value, job);
|
|
|
|
|
|
|
|
|
|
job_type = NodeParam::kShaderJob;
|
|
|
|
|
push_job = QVariant::fromValue(job);
|
|
|
|
|
} else if (data_type == NodeParam::kSamples) {
|
|
|
|
|
// This must be an audio transition
|
|
|
|
|
SampleBufferPtr from_samples = value[out_block_input()].Take(NodeParam::kBuffer).value<SampleBufferPtr>();
|
|
|
|
|
SampleBufferPtr to_samples = value[in_block_input()].Take(NodeParam::kBuffer).value<SampleBufferPtr>();
|
|
|
|
|
|
|
|
|
|
if (from_samples || to_samples) {
|
|
|
|
|
double time_in = value[QStringLiteral("global")].Get(NodeParam::kFloat, QStringLiteral("time_in")).toDouble();
|
|
|
|
|
double time_out = value[QStringLiteral("global")].Get(NodeParam::kFloat, QStringLiteral("time_out")).toDouble();
|
|
|
|
|
|
|
|
|
|
const AudioParams& params = (from_samples) ? from_samples->audio_params() : to_samples->audio_params();
|
|
|
|
|
|
|
|
|
|
int nb_samples = params.time_to_samples(time_out - time_in);
|
|
|
|
|
|
|
|
|
|
SampleBufferPtr out_samples = SampleBuffer::CreateAllocated(params, nb_samples);
|
|
|
|
|
SampleJobEvent(from_samples, to_samples, out_samples, time_in);
|
|
|
|
|
|
|
|
|
|
job_type = NodeParam::kSamples;
|
|
|
|
|
push_job = QVariant::fromValue(out_samples);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
NodeValueTable table = value.Merge();
|
|
|
|
|
table.Push(NodeParam::kShaderJob, QVariant::fromValue(job), this);
|
|
|
|
|
|
|
|
|
|
if (!push_job.isNull()) {
|
|
|
|
|
table.Push(job_type, push_job, this);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return table;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -192,4 +263,28 @@ void TransitionBlock::ShaderJobEvent(NodeValueDatabase &value, ShaderJob &job) c
|
|
|
|
|
Q_UNUSED(job)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void TransitionBlock::SampleJobEvent(SampleBufferPtr from_samples, SampleBufferPtr to_samples, SampleBufferPtr out_samples, double time_in) const
|
|
|
|
|
{
|
|
|
|
|
Q_UNUSED(from_samples)
|
|
|
|
|
Q_UNUSED(to_samples)
|
|
|
|
|
Q_UNUSED(out_samples)
|
|
|
|
|
Q_UNUSED(time_in)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
double TransitionBlock::TransformCurve(double linear) const
|
|
|
|
|
{
|
|
|
|
|
switch (static_cast<CurveType>(curve_input_->get_standard_value().toInt())) {
|
|
|
|
|
case kLinear:
|
|
|
|
|
break;
|
|
|
|
|
case kExponential:
|
|
|
|
|
linear *= linear;
|
|
|
|
|
break;
|
|
|
|
|
case kLogarithmic:
|
|
|
|
|
linear = qSqrt(linear);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return linear;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
OLIVE_NAMESPACE_EXIT
|
|
|
|
|