node: implemented convenience functions for transforming time
Implements a function that calculates the time transformation(s) only between one node and another.
This commit is contained in:
@@ -89,6 +89,15 @@ TimeRange ClipBlock::InputTimeAdjustment(NodeInput *input, const TimeRange &inpu
|
||||
return Block::InputTimeAdjustment(input, input_time);
|
||||
}
|
||||
|
||||
TimeRange ClipBlock::OutputTimeAdjustment(NodeInput *input, const TimeRange &input_time) const
|
||||
{
|
||||
if (input == texture_input_) {
|
||||
return TimeRange(MediaToSequenceTime(input_time.in()), MediaToSequenceTime(input_time.out()));
|
||||
}
|
||||
|
||||
return Block::InputTimeAdjustment(input, input_time);
|
||||
}
|
||||
|
||||
NodeValueTable ClipBlock::Value(const NodeValueDatabase &value) const
|
||||
{
|
||||
// We discard most values here except for the buffer we received
|
||||
|
||||
@@ -46,6 +46,8 @@ public:
|
||||
|
||||
virtual TimeRange InputTimeAdjustment(NodeInput* input, const TimeRange& input_time) const override;
|
||||
|
||||
virtual TimeRange OutputTimeAdjustment(NodeInput* input, const TimeRange& input_time) const override;
|
||||
|
||||
virtual NodeValueTable Value(const NodeValueDatabase& value) const override;
|
||||
|
||||
virtual void Retranslate() override;
|
||||
|
||||
+92
-2
@@ -167,10 +167,15 @@ void Node::InvalidateVisible(NodeInput *from)
|
||||
}
|
||||
}
|
||||
|
||||
TimeRange Node::InputTimeAdjustment(NodeInput *input, const TimeRange &input_time) const
|
||||
TimeRange Node::InputTimeAdjustment(NodeInput *, const TimeRange &input_time) const
|
||||
{
|
||||
// Default behavior is no time adjustment at all
|
||||
return input_time;
|
||||
}
|
||||
|
||||
TimeRange Node::OutputTimeAdjustment(NodeInput *, const TimeRange &input_time) const
|
||||
{
|
||||
// Default behavior is no time adjustment at all
|
||||
Q_UNUSED(input)
|
||||
return input_time;
|
||||
}
|
||||
|
||||
@@ -224,6 +229,42 @@ QString Node::ReadFileAsString(const QString &filename)
|
||||
return file_data;
|
||||
}
|
||||
|
||||
void GetInputsIncludingArraysInternal(NodeInputArray* array, QList<NodeInput *>& list)
|
||||
{
|
||||
foreach (NodeInput* input, array->sub_params()) {
|
||||
list.append(input);
|
||||
|
||||
if (input->IsArray()) {
|
||||
GetInputsIncludingArraysInternal(static_cast<NodeInputArray*>(input), list);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QList<NodeInput *> Node::GetInputsIncludingArrays() const
|
||||
{
|
||||
QList<NodeInput *> inputs;
|
||||
|
||||
foreach (NodeParam* param, params_) {
|
||||
if (param->type() == NodeParam::kInput) {
|
||||
NodeInput* input = static_cast<NodeInput*>(param);
|
||||
|
||||
inputs.append(input);
|
||||
|
||||
if (input->IsArray()) {
|
||||
GetInputsIncludingArraysInternal(static_cast<NodeInputArray*>(input), inputs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return inputs;
|
||||
}
|
||||
|
||||
QList<NodeOutput *> Node::GetOutputs() const
|
||||
{
|
||||
// The current design only uses one output per node. This function returns a list just in case that changes.
|
||||
return {output_};
|
||||
}
|
||||
|
||||
void Node::CopyInputs(Node *source, Node *destination, bool include_connections)
|
||||
{
|
||||
Q_ASSERT(source->id() == destination->id());
|
||||
@@ -487,6 +528,55 @@ void Node::DisconnectAll()
|
||||
}
|
||||
}
|
||||
|
||||
QList<TimeRange> Node::TransformTimeTo(const TimeRange &time, Node *target, NodeParam::Type direction)
|
||||
{
|
||||
QList<TimeRange> paths_found;
|
||||
|
||||
if (direction == NodeParam::kInput) {
|
||||
// Get list of all inputs
|
||||
QList<NodeInput *> inputs = GetInputsIncludingArrays();
|
||||
|
||||
// If this input is connected, traverse it to see if we stumble across the specified `node`
|
||||
foreach (NodeInput* input, inputs) {
|
||||
if (input->IsConnected()) {
|
||||
TimeRange input_adjustment = InputTimeAdjustment(input, time);
|
||||
|
||||
if (input->get_connected_node() == target) {
|
||||
// We found the target, no need to keep traversing
|
||||
if (!paths_found.contains(input_adjustment)) {
|
||||
paths_found.append(input_adjustment);
|
||||
}
|
||||
} else {
|
||||
// We did NOT find the target, traverse this
|
||||
paths_found.append(TransformTimeTo(input_adjustment, target, direction));
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Get list of all outputs
|
||||
QList<NodeOutput*> outputs = GetOutputs();
|
||||
|
||||
// If this input is connected, traverse it to see if we stumble across the specified `node`
|
||||
foreach (NodeOutput* output, outputs) {
|
||||
if (output->IsConnected()) {
|
||||
foreach (NodeEdgePtr edge, output->edges()) {
|
||||
Node* input_node = edge->input()->parentNode();
|
||||
|
||||
TimeRange output_adjustment = input_node->OutputTimeAdjustment(edge->input(), time);
|
||||
|
||||
if (input_node == target) {
|
||||
paths_found.append(output_adjustment);
|
||||
} else {
|
||||
paths_found.append(TransformTimeTo(output_adjustment, target, direction));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return paths_found;
|
||||
}
|
||||
|
||||
QVariant Node::PtrToValue(void *ptr)
|
||||
{
|
||||
return reinterpret_cast<quintptr>(ptr);
|
||||
|
||||
@@ -212,6 +212,11 @@ public:
|
||||
*/
|
||||
void DisconnectAll();
|
||||
|
||||
/**
|
||||
* @brief Transforms time from this node through the connections it takes to get to the specified node
|
||||
*/
|
||||
QList<TimeRange> TransformTimeTo(const TimeRange& time, Node* target, NodeParam::Type direction);
|
||||
|
||||
template<class T>
|
||||
/**
|
||||
* @brief Find a node of a certain type that this Node outputs to
|
||||
@@ -245,8 +250,19 @@ public:
|
||||
*/
|
||||
virtual void InvalidateVisible(NodeInput *from);
|
||||
|
||||
/**
|
||||
* @brief Adjusts time that should be sent to nodes connected to certain inputs.
|
||||
*
|
||||
* If this node modifies the `time` (i.e. a clip converting sequence time to media time), this function should be
|
||||
* overridden to do so. Also make sure to override OutputTimeAdjustment() to provide the inverse function.
|
||||
*/
|
||||
virtual TimeRange InputTimeAdjustment(NodeInput* input, const TimeRange& input_time) const;
|
||||
|
||||
/**
|
||||
* @brief The inverse of InputTimeAdjustment()
|
||||
*/
|
||||
virtual TimeRange OutputTimeAdjustment(NodeInput* input, const TimeRange& input_time) const;
|
||||
|
||||
/**
|
||||
* @brief Copies inputs from from Node to another including connections
|
||||
*
|
||||
@@ -315,6 +331,10 @@ public:
|
||||
|
||||
static QString ReadFileAsString(const QString& filename);
|
||||
|
||||
QList<NodeInput*> GetInputsIncludingArrays() const;
|
||||
|
||||
QList<NodeOutput*> GetOutputs() const;
|
||||
|
||||
protected:
|
||||
void AddInput(NodeInput* input);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user