implemented gizmo transforming through the node graph
This commit is contained in:
@@ -79,10 +79,12 @@ void CropDistortNode::Value(const NodeValueRow &value, const NodeGlobals &global
|
||||
{
|
||||
ShaderJob job;
|
||||
job.Insert(value);
|
||||
job.Insert(QStringLiteral("resolution_in"), NodeValue(NodeValue::kVec2, globals.resolution(), this));
|
||||
job.SetAlphaChannelRequired(GenerateJob::kAlphaForceOn);
|
||||
job.SetWillChangeImageSize(false);
|
||||
|
||||
if (TexturePtr texture = job.Get(kTextureInput).toTexture()) {
|
||||
job.Insert(QStringLiteral("resolution_in"), NodeValue(NodeValue::kVec2, QVector2D(texture->params().width(), texture->params().height()), this));
|
||||
|
||||
if (job.Get(kTextureInput).toTexture()) {
|
||||
if (!qIsNull(job.Get(kLeftInput).toDouble())
|
||||
|| !qIsNull(job.Get(kRightInput).toDouble())
|
||||
|| !qIsNull(job.Get(kTopInput).toDouble())
|
||||
|
||||
@@ -84,7 +84,7 @@ void TransformDistortNode::Retranslate()
|
||||
void TransformDistortNode::Value(const NodeValueRow &value, const NodeGlobals &globals, NodeValueTable *table) const
|
||||
{
|
||||
// Generate matrix
|
||||
QMatrix4x4 generated_matrix = GenerateMatrix(value, true, false, false, false);
|
||||
QMatrix4x4 generated_matrix = GenerateMatrix(value, false, false, false);
|
||||
|
||||
// Pop texture
|
||||
NodeValue texture_meta = value[kTextureInput];
|
||||
@@ -143,7 +143,7 @@ void TransformDistortNode::Hash(QCryptographicHash &hash, const NodeGlobals &glo
|
||||
TexturePtr tex = db[kTextureInput].toTexture();
|
||||
if (tex) {
|
||||
VideoParams tex_params = tex->params();
|
||||
QMatrix4x4 matrix = GenerateMatrix(db, true, false, false, false);
|
||||
QMatrix4x4 matrix = GenerateMatrix(db, false, false, false);
|
||||
matrix = GenerateAutoScaledMatrix(matrix, db, globals, tex_params);
|
||||
|
||||
if (!matrix.isIdentity()) {
|
||||
@@ -162,7 +162,7 @@ void TransformDistortNode::GizmoDragStart(const NodeValueRow &row, double x, dou
|
||||
|
||||
if (gizmo == anchor_gizmo_) {
|
||||
|
||||
gizmo_inverted_transform_ = GenerateMatrix(row, false, true, true, false).toTransform().inverted();
|
||||
gizmo_inverted_transform_ = GenerateMatrix(row, true, true, false).toTransform().inverted();
|
||||
|
||||
} else if (IsAScaleGizmo(gizmo)) {
|
||||
|
||||
@@ -204,7 +204,7 @@ void TransformDistortNode::GizmoDragStart(const NodeValueRow &row, double x, dou
|
||||
}
|
||||
|
||||
// Store current matrix
|
||||
gizmo_inverted_transform_ = GenerateMatrix(row, false, true, true, true).toTransform().inverted();
|
||||
gizmo_inverted_transform_ = GenerateMatrix(row, true, true, true).toTransform().inverted();
|
||||
|
||||
} else if (gizmo == rotation_gizmo_) {
|
||||
|
||||
@@ -389,7 +389,7 @@ void TransformDistortNode::UpdateGizmoPositions(const NodeValueRow &row, const N
|
||||
// Fold values into a matrix for the rectangle
|
||||
QMatrix4x4 rectangle_matrix;
|
||||
rectangle_matrix.scale(sequence_half_res);
|
||||
rectangle_matrix *= AdjustMatrixByResolutions(GenerateMatrix(row, false, false, false, false),
|
||||
rectangle_matrix *= AdjustMatrixByResolutions(GenerateMatrix(row, false, false, false),
|
||||
sequence_res,
|
||||
tex_sz,
|
||||
tex_offset,
|
||||
@@ -409,7 +409,7 @@ void TransformDistortNode::UpdateGizmoPositions(const NodeValueRow &row, const N
|
||||
// Draw anchor point
|
||||
QMatrix4x4 anchor_matrix;
|
||||
anchor_matrix.scale(sequence_half_res);
|
||||
anchor_matrix *= AdjustMatrixByResolutions(GenerateMatrix(row, false, true, false, false),
|
||||
anchor_matrix *= AdjustMatrixByResolutions(GenerateMatrix(row, true, false, false),
|
||||
sequence_res,
|
||||
tex_sz,
|
||||
tex_offset,
|
||||
@@ -432,6 +432,15 @@ void TransformDistortNode::UpdateGizmoPositions(const NodeValueRow &row, const N
|
||||
SetInputProperty(kAnchorInput, QStringLiteral("offset"), tex_sz * 0.5);
|
||||
}
|
||||
|
||||
QTransform TransformDistortNode::GizmoTransformation(const NodeValueRow &row, const NodeGlobals &globals) const
|
||||
{
|
||||
if (TexturePtr texture = row[kTextureInput].toTexture()) {
|
||||
auto m = GenerateMatrix(row, false, false, false);
|
||||
return GenerateAutoScaledMatrix(m, row, globals, texture->params()).toTransform();
|
||||
}
|
||||
return super::GizmoTransformation(row, globals);
|
||||
}
|
||||
|
||||
QPointF TransformDistortNode::CreateScalePoint(double x, double y, const QPointF &half_res, const QMatrix4x4 &mat)
|
||||
{
|
||||
return mat.map(QPointF(x, y)) + half_res;
|
||||
|
||||
@@ -82,6 +82,7 @@ public:
|
||||
AutoScaleType autoscale_type = kAutoScaleNone);
|
||||
|
||||
virtual void UpdateGizmoPositions(const NodeValueRow &row, const NodeGlobals &globals) override;
|
||||
virtual QTransform GizmoTransformation(const NodeValueRow &row, const NodeGlobals &globals) const override;
|
||||
|
||||
static const QString kTextureInput;
|
||||
static const QString kAutoscaleInput;
|
||||
|
||||
@@ -90,63 +90,33 @@ void MatrixGenerator::Retranslate()
|
||||
void MatrixGenerator::Value(const NodeValueRow &value, const NodeGlobals &globals, NodeValueTable *table) const
|
||||
{
|
||||
// Push matrix output
|
||||
QMatrix4x4 mat = GenerateMatrix(value, true, false, false, false);
|
||||
QMatrix4x4 mat = GenerateMatrix(value, false, false, false);
|
||||
table->Push(NodeValue::kMatrix, mat, this);
|
||||
}
|
||||
|
||||
QMatrix4x4 MatrixGenerator::GenerateMatrix(const NodeValueRow &value, bool take, bool ignore_anchor, bool ignore_position, bool ignore_scale) const
|
||||
QMatrix4x4 MatrixGenerator::GenerateMatrix(const NodeValueRow &value, bool ignore_anchor, bool ignore_position, bool ignore_scale) const
|
||||
{
|
||||
QVector2D anchor;
|
||||
QVector2D position;
|
||||
QVector2D scale;
|
||||
|
||||
if (!ignore_anchor) {
|
||||
if (take) {
|
||||
// Take and store
|
||||
anchor = value[kAnchorInput].toVec2();
|
||||
} else {
|
||||
// Get and store
|
||||
anchor = value[kAnchorInput].toVec2();
|
||||
}
|
||||
} else if (take) {
|
||||
// Just take
|
||||
value[kAnchorInput].toVec2();
|
||||
anchor = value[kAnchorInput].toVec2();
|
||||
}
|
||||
|
||||
if (!ignore_scale) {
|
||||
if (take) {
|
||||
scale = value[kScaleInput].toVec2();
|
||||
} else {
|
||||
scale = value[kScaleInput].toVec2();
|
||||
}
|
||||
} else if (take) {
|
||||
value[kScaleInput].toVec2();
|
||||
scale = value[kScaleInput].toVec2();
|
||||
}
|
||||
|
||||
if (!ignore_position) {
|
||||
if (take) {
|
||||
position = value[kPositionInput].toVec2();
|
||||
} else {
|
||||
position = value[kPositionInput].toVec2();
|
||||
}
|
||||
} else if (take) {
|
||||
value[kPositionInput].toVec2();
|
||||
position = value[kPositionInput].toVec2();
|
||||
}
|
||||
|
||||
if (take) {
|
||||
return GenerateMatrix(position,
|
||||
value[kRotationInput].toDouble(),
|
||||
scale,
|
||||
value[kUniformScaleInput].toBool(),
|
||||
anchor);
|
||||
} else {
|
||||
return GenerateMatrix(position,
|
||||
value[kRotationInput].toDouble(),
|
||||
scale,
|
||||
value[kUniformScaleInput].toBool(),
|
||||
anchor);
|
||||
|
||||
}
|
||||
return GenerateMatrix(position,
|
||||
value[kRotationInput].toDouble(),
|
||||
scale,
|
||||
value[kUniformScaleInput].toBool(),
|
||||
anchor);
|
||||
}
|
||||
|
||||
QMatrix4x4 MatrixGenerator::GenerateMatrix(const QVector2D& pos,
|
||||
|
||||
@@ -53,7 +53,7 @@ public:
|
||||
static const QString kAnchorInput;
|
||||
|
||||
protected:
|
||||
QMatrix4x4 GenerateMatrix(const NodeValueRow &value, bool take, bool ignore_anchor, bool ignore_position, bool ignore_scale) const;
|
||||
QMatrix4x4 GenerateMatrix(const NodeValueRow &value, bool ignore_anchor, bool ignore_position, bool ignore_scale) const;
|
||||
static QMatrix4x4 GenerateMatrix(const QVector2D &pos,
|
||||
const float &rot,
|
||||
const QVector2D &scale,
|
||||
|
||||
@@ -50,7 +50,7 @@ QByteArray HashTraverser::GetHash(const Node *node, const Node::ValueHint &hint,
|
||||
//Hash(reference);
|
||||
|
||||
// Our overrides will generate a hash from this
|
||||
NodeValueTable table = GenerateTable(node, hint, range);
|
||||
NodeValueTable table = GenerateTable(node, range);
|
||||
NodeValue final_value = GenerateRowValueElement(hint, NodeValue::kTexture, &table);
|
||||
HashNodeValue(final_value);
|
||||
|
||||
|
||||
@@ -889,6 +889,8 @@ public:
|
||||
return gizmos_;
|
||||
}
|
||||
|
||||
virtual QTransform GizmoTransformation(const NodeValueRow &row, const NodeGlobals &globals) const { return QTransform(); }
|
||||
|
||||
virtual void UpdateGizmoPositions(const NodeValueRow &row, const NodeGlobals &globals){}
|
||||
|
||||
const QString& GetLabel() const;
|
||||
|
||||
@@ -381,7 +381,7 @@ rational ViewerOutput::VerifyLengthInternal(Track::Type type) const
|
||||
switch (type) {
|
||||
case Track::kVideo:
|
||||
if (IsInputConnected(kTextureInput)) {
|
||||
NodeValueTable t = traverser.GenerateTable(GetConnectedOutput(kTextureInput), GetValueHintForInput(kTextureInput), TimeRange(0, 0));
|
||||
NodeValueTable t = traverser.GenerateTable(GetConnectedOutput(kTextureInput), TimeRange(0, 0));
|
||||
rational r = t.Get(NodeValue::kRational, QStringLiteral("length")).value<rational>();
|
||||
if (!r.isNaN()) {
|
||||
return r;
|
||||
@@ -390,7 +390,7 @@ rational ViewerOutput::VerifyLengthInternal(Track::Type type) const
|
||||
break;
|
||||
case Track::kAudio:
|
||||
if (IsInputConnected(kSamplesInput)) {
|
||||
NodeValueTable t = traverser.GenerateTable(GetConnectedOutput(kSamplesInput), GetValueHintForInput(kSamplesInput), TimeRange(0, 0));
|
||||
NodeValueTable t = traverser.GenerateTable(GetConnectedOutput(kSamplesInput), TimeRange(0, 0));
|
||||
rational r = t.Get(NodeValue::kRational, QStringLiteral("length")).value<rational>();;
|
||||
if (!r.isNaN()) {
|
||||
return r;
|
||||
|
||||
+58
-7
@@ -141,6 +141,16 @@ int NodeTraverser::GenerateRowValueElementIndex(const Node *node, const QString
|
||||
return GenerateRowValueElementIndex(node->GetValueHintForInput(input, element), node->GetInputDataType(input), table);
|
||||
}
|
||||
|
||||
void NodeTraverser::Transform(QTransform *transform, const Node *start, const Node *end, const TimeRange &range)
|
||||
{
|
||||
transform_ = transform;
|
||||
transform_start_ = start;
|
||||
|
||||
GenerateTable(end, range);
|
||||
|
||||
transform_ = nullptr;
|
||||
}
|
||||
|
||||
NodeGlobals NodeTraverser::GenerateGlobals(const VideoParams ¶ms, const TimeRange &time)
|
||||
{
|
||||
return NodeGlobals(QVector2D(params.width(), params.height()), params.pixel_aspect_ratio(), time);
|
||||
@@ -179,6 +189,20 @@ int NodeTraverser::GetChannelCountFromJob(const GenerateJob &job)
|
||||
return VideoParams::kRGBAChannelCount;
|
||||
}
|
||||
|
||||
TexturePtr NodeTraverser::GetMainTextureFromJob(const GenerateJob &job)
|
||||
{
|
||||
// FIXME: Should probably take Node::GetEffectInput into account here
|
||||
for (auto it=job.GetValues().cbegin(); it!=job.GetValues().cend(); it++) {
|
||||
if (it.value().type() == NodeValue::kTexture) {
|
||||
if (TexturePtr t = it.value().toTexture()) {
|
||||
return t;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
NodeValueTable NodeTraverser::ProcessInput(const Node* node, const QString& input, const TimeRange& range)
|
||||
{
|
||||
// If input is connected, retrieve value directly
|
||||
@@ -187,7 +211,7 @@ NodeValueTable NodeTraverser::ProcessInput(const Node* node, const QString& inpu
|
||||
TimeRange adjusted_range = node->InputTimeAdjustment(input, -1, range);
|
||||
|
||||
// Value will equal something from the connected node, follow it
|
||||
return GenerateTable(node->GetConnectedOutput(input), node->GetValueHintForInput(input), adjusted_range);
|
||||
return GenerateTable(node->GetConnectedOutput(input), adjusted_range);
|
||||
|
||||
} else {
|
||||
|
||||
@@ -205,7 +229,7 @@ NodeValueTable NodeTraverser::ProcessInput(const Node* node, const QString& inpu
|
||||
TimeRange adjusted_range = node->InputTimeAdjustment(input, i, range);
|
||||
|
||||
if (node->IsInputConnected(input, i)) {
|
||||
sub_tbl = GenerateTable(node->GetConnectedOutput(input, i), node->GetValueHintForInput(input, i), adjusted_range);
|
||||
sub_tbl = GenerateTable(node->GetConnectedOutput(input, i), adjusted_range);
|
||||
} else {
|
||||
QVariant input_value = node->GetValueAtTime(input, adjusted_range.in(), i);
|
||||
sub_tbl.Push(node->GetInputDataType(input), input_value, node);
|
||||
@@ -231,11 +255,12 @@ NodeValueTable NodeTraverser::ProcessInput(const Node* node, const QString& inpu
|
||||
}
|
||||
|
||||
NodeTraverser::NodeTraverser() :
|
||||
cancel_(nullptr)
|
||||
cancel_(nullptr),
|
||||
transform_(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
NodeValueTable NodeTraverser::GenerateTable(const Node *n, const Node::ValueHint &hint, const TimeRange& range)
|
||||
NodeValueTable NodeTraverser::GenerateTable(const Node *n, const TimeRange& range)
|
||||
{
|
||||
const Track* track = dynamic_cast<const Track*>(n);
|
||||
if (track) {
|
||||
@@ -264,7 +289,24 @@ NodeValueTable NodeTraverser::GenerateTable(const Node *n, const Node::ValueHint
|
||||
NodeValueTable table = database.Merge();
|
||||
|
||||
// By this point, the node should have all the inputs it needs to render correctly
|
||||
n->Value(row, GenerateGlobals(video_params_, range), &table);
|
||||
NodeGlobals globals = GenerateGlobals(video_params_, range);
|
||||
n->Value(row, globals, &table);
|
||||
|
||||
if (transform_) {
|
||||
if (!transform_start_) {
|
||||
if (!transform_ignore_.contains(n)) {
|
||||
QTransform t = n->GizmoTransformation(row, globals);
|
||||
if (!t.isIdentity()) {
|
||||
qDebug() << "transforming" << n;
|
||||
(*transform_) *= t;
|
||||
}
|
||||
|
||||
transform_ignore_.append(n);
|
||||
}
|
||||
} else if (transform_start_ == n) {
|
||||
transform_start_ = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
return table;
|
||||
} else {
|
||||
@@ -288,7 +330,7 @@ NodeValueTable NodeTraverser::GenerateBlockTable(const Track *track, const TimeR
|
||||
NodeValueTable table;
|
||||
|
||||
if (active_block) {
|
||||
table = GenerateTable(active_block, track->GetValueHintForInput(Track::kBlockInput, track->GetArrayIndexFromBlock(active_block)), Track::TransformRangeForBlock(active_block, range));
|
||||
table = GenerateTable(active_block, Track::TransformRangeForBlock(active_block, range));
|
||||
}
|
||||
|
||||
return table;
|
||||
@@ -307,12 +349,21 @@ void NodeTraverser::ResolveJobs(NodeValue &val, const TimeRange &range)
|
||||
|
||||
ShaderJob job = val.value<ShaderJob>();
|
||||
|
||||
PreProcessRow(range, job.GetValues());
|
||||
|
||||
VideoParams tex_params = GetCacheVideoParams();
|
||||
tex_params.set_channel_count(GetChannelCountFromJob(job));
|
||||
|
||||
if (!job.GetWillChangeImageSize()) {
|
||||
if (TexturePtr texture = GetMainTextureFromJob(job)) {
|
||||
tex_params.set_width(texture->params().width());
|
||||
tex_params.set_height(texture->params().height());
|
||||
tex_params.set_divider(texture->params().divider());
|
||||
}
|
||||
}
|
||||
|
||||
TexturePtr tex = CreateTexture(tex_params);
|
||||
|
||||
PreProcessRow(range, job.GetValues());
|
||||
ProcessShader(tex, val.source(), range, job);
|
||||
|
||||
val.set_value(tex);
|
||||
|
||||
@@ -37,7 +37,7 @@ class NodeTraverser
|
||||
public:
|
||||
NodeTraverser();
|
||||
|
||||
NodeValueTable GenerateTable(const Node *n, const Node::ValueHint &hint, const TimeRange &range);
|
||||
NodeValueTable GenerateTable(const Node *n, const TimeRange &range);
|
||||
|
||||
NodeValueDatabase GenerateDatabase(const Node *node, const TimeRange &range);
|
||||
|
||||
@@ -50,6 +50,8 @@ public:
|
||||
int GenerateRowValueElementIndex(const Node::ValueHint &hint, NodeValue::Type preferred_type, const NodeValueTable *table);
|
||||
int GenerateRowValueElementIndex(const Node *node, const QString &input, int element, const NodeValueTable *table);
|
||||
|
||||
void Transform(QTransform *transform, const Node *start, const Node *end, const TimeRange &range);
|
||||
|
||||
static NodeGlobals GenerateGlobals(const VideoParams ¶ms, const TimeRange &time);
|
||||
static NodeGlobals GenerateGlobals(const VideoParams ¶ms, const rational &time)
|
||||
{
|
||||
@@ -78,6 +80,8 @@ public:
|
||||
|
||||
static int GetChannelCountFromJob(const GenerateJob& job);
|
||||
|
||||
static TexturePtr GetMainTextureFromJob(const GenerateJob& job);
|
||||
|
||||
protected:
|
||||
NodeValueTable ProcessInput(const Node *node, const QString &input, const TimeRange &range);
|
||||
|
||||
@@ -152,6 +156,10 @@ private:
|
||||
|
||||
const QAtomicInt *cancel_;
|
||||
|
||||
const Node *transform_start_;
|
||||
QTransform *transform_;
|
||||
QVector<const Node*> transform_ignore_;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -36,6 +36,7 @@ public:
|
||||
{
|
||||
iterations_ = 1;
|
||||
iterative_input_ = nullptr;
|
||||
will_change_image_size_ = true;
|
||||
}
|
||||
|
||||
const QString& GetShaderID() const
|
||||
@@ -99,6 +100,9 @@ public:
|
||||
return vertex_overrides_;
|
||||
}
|
||||
|
||||
bool GetWillChangeImageSize() const { return will_change_image_size_; }
|
||||
void SetWillChangeImageSize(bool e) { will_change_image_size_ = e; }
|
||||
|
||||
private:
|
||||
QString shader_id_;
|
||||
|
||||
@@ -110,6 +114,8 @@ private:
|
||||
|
||||
QVector<float> vertex_overrides_;
|
||||
|
||||
bool will_change_image_size_;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@ TexturePtr RenderProcessor::GenerateTexture(const rational &time, const rational
|
||||
|
||||
NodeValueTable table;
|
||||
if (Node *texture_output = viewer->GetConnectedTextureOutput()) {
|
||||
table = GenerateTable(texture_output, viewer->GetValueHintForInput(ViewerOutput::kTextureInput), range);
|
||||
table = GenerateTable(texture_output, range);
|
||||
}
|
||||
|
||||
NodeValue tex_val = table.Get(NodeValue::kTexture);
|
||||
@@ -193,7 +193,7 @@ void RenderProcessor::Run()
|
||||
|
||||
NodeValueTable table;
|
||||
if (Node *texture_output = viewer->GetConnectedSampleOutput()) {
|
||||
table = GenerateTable(texture_output, viewer->GetValueHintForInput(ViewerOutput::kSamplesInput),time);
|
||||
table = GenerateTable(texture_output, time);
|
||||
}
|
||||
|
||||
NodeValue sample_val = table.Get(NodeValue::kSamples);
|
||||
@@ -290,7 +290,7 @@ NodeValueTable RenderProcessor::GenerateBlockTable(const Track *track, const Tim
|
||||
int max_dest_sz = audio_params.time_to_samples(range_for_block.length());
|
||||
|
||||
// Destination buffer
|
||||
NodeValueTable table = GenerateTable(b, track->GetValueHintForInput(Track::kBlockInput, track->GetArrayIndexFromBlock(b)),Track::TransformRangeForBlock(b, range_for_block));
|
||||
NodeValueTable table = GenerateTable(b, Track::TransformRangeForBlock(b, range_for_block));
|
||||
SampleBuffer samples_from_this_block = table.Take(NodeValue::kSamples).toSamples();
|
||||
ClipBlock *clip_cast = dynamic_cast<ClipBlock*>(b);
|
||||
|
||||
|
||||
@@ -31,9 +31,8 @@ void NodeValueTree::SetNode(const NodeInput &input, const rational &time)
|
||||
NodeTraverser traverser;
|
||||
|
||||
Node *connected_node = input.GetConnectedOutput();
|
||||
Node::ValueHint value_hint = input.node()->GetValueHintForInput(input.input(), input.element());
|
||||
|
||||
NodeValueTable table = traverser.GenerateTable(connected_node, value_hint, TimeRange(time, time));
|
||||
NodeValueTable table = traverser.GenerateTable(connected_node, TimeRange(time, time));
|
||||
|
||||
int index = traverser.GenerateRowValueElementIndex(input.node(), input.input(), input.element(), &table);
|
||||
|
||||
|
||||
@@ -45,7 +45,6 @@
|
||||
#include "node/gizmo/point.h"
|
||||
#include "node/gizmo/polygon.h"
|
||||
#include "node/gizmo/screen.h"
|
||||
#include "node/traverser.h"
|
||||
#include "viewertexteditor.h"
|
||||
#include "window/mainwindow/mainwindow.h"
|
||||
|
||||
@@ -221,7 +220,7 @@ QPointF ViewerDisplayWidget::TransformViewerSpaceToBufferSpace(const QPointF &po
|
||||
* Inversion will only fail if the viewer has been scaled by 0 in any direction
|
||||
* which I think should never happen.
|
||||
*/
|
||||
return pos * GenerateGizmoTransform().inverted();
|
||||
return pos * GenerateDisplayTransform().inverted();
|
||||
}
|
||||
|
||||
void ViewerDisplayWidget::ResetFPSTimer()
|
||||
@@ -253,7 +252,8 @@ void ViewerDisplayWidget::mousePressEvent(QMouseEvent *event)
|
||||
add_band_->show();
|
||||
|
||||
} else if (event->button() == Qt::LeftButton && gizmos_
|
||||
&& (current_gizmo_ = TryGizmoPress(gizmo_db_, TransformViewerSpaceToBufferSpace(event->pos())))) {
|
||||
&& (gizmo_last_draw_transform_inverted_ = gizmo_last_draw_transform_.inverted(),
|
||||
current_gizmo_ = TryGizmoPress(gizmo_db_, event->pos() * gizmo_last_draw_transform_inverted_))) {
|
||||
|
||||
// Handle gizmo click
|
||||
gizmo_start_drag_ = event->pos();
|
||||
@@ -300,7 +300,7 @@ void ViewerDisplayWidget::mouseMoveEvent(QMouseEvent *event)
|
||||
// Signal movement
|
||||
if (DraggableGizmo *draggable = dynamic_cast<DraggableGizmo*>(current_gizmo_)) {
|
||||
if (!gizmo_drag_started_) {
|
||||
QPointF start = TransformViewerSpaceToBufferSpace(gizmo_start_drag_);
|
||||
QPointF start = gizmo_start_drag_ * gizmo_last_draw_transform_inverted_;
|
||||
|
||||
rational gizmo_time = GetGizmoTime();
|
||||
NodeTraverser t;
|
||||
@@ -311,17 +311,17 @@ void ViewerDisplayWidget::mouseMoveEvent(QMouseEvent *event)
|
||||
gizmo_drag_started_ = true;
|
||||
}
|
||||
|
||||
QPointF v = TransformViewerSpaceToBufferSpace(event->pos());
|
||||
QPointF v = event->pos() * gizmo_last_draw_transform_inverted_;
|
||||
switch (draggable->GetDragValueBehavior()) {
|
||||
case DraggableGizmo::kAbsolute:
|
||||
// Above value is correct
|
||||
break;
|
||||
case DraggableGizmo::kDeltaFromPrevious:
|
||||
v -= TransformViewerSpaceToBufferSpace(gizmo_last_drag_);
|
||||
v -= gizmo_last_drag_ * gizmo_last_draw_transform_inverted_;
|
||||
gizmo_last_drag_ = event->pos();
|
||||
break;
|
||||
case DraggableGizmo::kDeltaFromStart:
|
||||
v -= TransformViewerSpaceToBufferSpace(gizmo_start_drag_);
|
||||
v -= gizmo_start_drag_ * gizmo_last_draw_transform_inverted_;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -349,7 +349,7 @@ void ViewerDisplayWidget::mouseReleaseEvent(QMouseEvent *event)
|
||||
|
||||
const QRect &band_rect = add_band_->geometry();
|
||||
if (band_rect.width() > 1 && band_rect.height() > 1) {
|
||||
QRectF r = GenerateGizmoTransform().inverted().mapRect(add_band_->geometry());
|
||||
QRectF r = GenerateDisplayTransform().inverted().mapRect(add_band_->geometry());
|
||||
emit CreateAddableAt(r);
|
||||
}
|
||||
|
||||
@@ -510,7 +510,8 @@ void ViewerDisplayWidget::OnPaint()
|
||||
gizmo_db_ = gt.GenerateRow(gizmos_, range);
|
||||
|
||||
QPainter p(inner_widget());
|
||||
p.setWorldTransform(GenerateGizmoTransform());
|
||||
gizmo_last_draw_transform_ = GenerateGizmoTransform(gt, range);
|
||||
p.setWorldTransform(gizmo_last_draw_transform_);
|
||||
|
||||
gizmos_->UpdateGizmoPositions(gizmo_db_, NodeTraverser::GenerateGlobals(gizmo_params_, range));
|
||||
foreach (NodeGizmo *gizmo, gizmos_->GetGizmos()) {
|
||||
@@ -722,7 +723,7 @@ QTransform ViewerDisplayWidget::GenerateWorldTransform()
|
||||
return world;
|
||||
}
|
||||
|
||||
QTransform ViewerDisplayWidget::GenerateGizmoTransform()
|
||||
QTransform ViewerDisplayWidget::GenerateDisplayTransform()
|
||||
{
|
||||
QVector2D viewer_scale(GetTexturePosition(size()));
|
||||
QTransform gizmo_transform = GenerateWorldTransform();
|
||||
@@ -731,13 +732,37 @@ QTransform ViewerDisplayWidget::GenerateGizmoTransform()
|
||||
return gizmo_transform;
|
||||
}
|
||||
|
||||
QTransform ViewerDisplayWidget::GenerateGizmoTransform(NodeTraverser >, const TimeRange &range)
|
||||
{
|
||||
QTransform t = GenerateDisplayTransform();
|
||||
if (GetTimeTarget()) {
|
||||
t.translate(gizmo_params_.width()*0.5, gizmo_params_.height()*0.5);
|
||||
|
||||
Node *target = GetTimeTarget();
|
||||
if (ViewerOutput *v = dynamic_cast<ViewerOutput *>(target)) {
|
||||
if (Node *n = v->GetConnectedTextureOutput()) {
|
||||
target = n;
|
||||
}
|
||||
}
|
||||
|
||||
QTransform nt;
|
||||
gt.Transform(&nt, gizmos_, target, range);
|
||||
|
||||
t = nt * t;
|
||||
|
||||
t.translate(-gizmo_params_.width()*0.5, -gizmo_params_.height()*0.5);
|
||||
}
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
NodeGizmo *ViewerDisplayWidget::TryGizmoPress(const NodeValueRow &row, const QPointF &p)
|
||||
{
|
||||
for (auto it=gizmos_->GetGizmos().crbegin(); it!=gizmos_->GetGizmos().crend(); it++) {
|
||||
NodeGizmo *gizmo = *it;
|
||||
if (gizmo->IsVisible()) {
|
||||
if (PointGizmo *point = dynamic_cast<PointGizmo*>(gizmo)) {
|
||||
if (point->GetClickingRect(GenerateGizmoTransform()).contains(p)) {
|
||||
if (point->GetClickingRect(GenerateDisplayTransform()).contains(p)) {
|
||||
return point;
|
||||
}
|
||||
} else if (PolygonGizmo *poly = dynamic_cast<PolygonGizmo*>(gizmo)) {
|
||||
@@ -760,7 +785,7 @@ NodeGizmo *ViewerDisplayWidget::TryGizmoPress(const NodeValueRow &row, const QPo
|
||||
|
||||
void ViewerDisplayWidget::OpenTextGizmo(TextGizmo *text, QMouseEvent *event)
|
||||
{
|
||||
QTransform gizmo_transform = GenerateGizmoTransform();
|
||||
QTransform gizmo_transform = GenerateDisplayTransform();
|
||||
|
||||
ViewerTextEditor *text_edit = new ViewerTextEditor(gizmo_transform.m11(), this);
|
||||
Html::HtmlToDoc(text_edit->document(), text->GetHtml());
|
||||
@@ -821,7 +846,7 @@ void ViewerDisplayWidget::EmitColorAtCursor(QMouseEvent *e)
|
||||
Color reference, display;
|
||||
|
||||
if (texture_) {
|
||||
QPointF pixel_pos = GenerateGizmoTransform().inverted().map(e->pos());
|
||||
QPointF pixel_pos = GenerateDisplayTransform().inverted().map(e->pos());
|
||||
pixel_pos /= texture_->params().divider();
|
||||
|
||||
reference = renderer()->GetPixelFromTexture(texture_.get(), pixel_pos);
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include "node/gizmo/text.h"
|
||||
#include "node/node.h"
|
||||
#include "node/output/track/tracklist.h"
|
||||
#include "node/traverser.h"
|
||||
#include "render/color.h"
|
||||
#include "tool/tool.h"
|
||||
#include "viewerplaybacktimer.h"
|
||||
@@ -262,7 +263,9 @@ private:
|
||||
|
||||
QTransform GenerateWorldTransform();
|
||||
|
||||
QTransform GenerateGizmoTransform();
|
||||
QTransform GenerateDisplayTransform();
|
||||
|
||||
QTransform GenerateGizmoTransform(NodeTraverser >, const TimeRange &range);
|
||||
|
||||
TimeRange GenerateGizmoTime()
|
||||
{
|
||||
@@ -326,6 +329,8 @@ private:
|
||||
QPoint gizmo_last_drag_;
|
||||
NodeGizmo *current_gizmo_;
|
||||
bool gizmo_drag_started_;
|
||||
QTransform gizmo_last_draw_transform_;
|
||||
QTransform gizmo_last_draw_transform_inverted_;
|
||||
|
||||
bool show_subtitles_;
|
||||
Sequence *subtitle_tracks_;
|
||||
|
||||
Reference in New Issue
Block a user