Compositor: Add Invert option to the movie clip stabilization node
This appears to be really common workflow when you stabilize shot to make compo easier (roto, some effects and so) and then re-introduce the motion back. Surely it's doable with some magic nodes and manual network for transforming but such workflow is too common in VFX to resist adding one small option in single node for this.
This commit is contained in:
parent
b2f57190d9
commit
ea67f55b87
|
@ -40,11 +40,13 @@ Stabilize2dNode::Stabilize2dNode(bNode *editorNode) : Node(editorNode)
|
|||
|
||||
void Stabilize2dNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const
|
||||
{
|
||||
bNode *editorNode = this->getbNode();
|
||||
NodeInput *imageInput = this->getInputSocket(0);
|
||||
MovieClip *clip = (MovieClip *)getbNode()->id;
|
||||
MovieClip *clip = (MovieClip *)editorNode->id;
|
||||
bool invert = (editorNode->custom2 & CMP_NODEFLAG_STABILIZE_INVERSE) != 0;
|
||||
|
||||
ScaleOperation *scaleOperation = new ScaleOperation();
|
||||
scaleOperation->setSampler((PixelSampler)this->getbNode()->custom1);
|
||||
scaleOperation->setSampler((PixelSampler)editorNode->custom1);
|
||||
RotateOperation *rotateOperation = new RotateOperation();
|
||||
rotateOperation->setDoDegree2RadConversion(false);
|
||||
TranslateOperation *translateOperation = new TranslateOperation();
|
||||
|
@ -53,24 +55,28 @@ void Stabilize2dNode::convertToOperations(NodeConverter &converter, const Compos
|
|||
MovieClipAttributeOperation *xAttribute = new MovieClipAttributeOperation();
|
||||
MovieClipAttributeOperation *yAttribute = new MovieClipAttributeOperation();
|
||||
SetSamplerOperation *psoperation = new SetSamplerOperation();
|
||||
psoperation->setSampler((PixelSampler)this->getbNode()->custom1);
|
||||
|
||||
psoperation->setSampler((PixelSampler)editorNode->custom1);
|
||||
|
||||
scaleAttribute->setAttribute(MCA_SCALE);
|
||||
scaleAttribute->setFramenumber(context.getFramenumber());
|
||||
scaleAttribute->setMovieClip(clip);
|
||||
|
||||
scaleAttribute->setInvert(invert);
|
||||
|
||||
angleAttribute->setAttribute(MCA_ANGLE);
|
||||
angleAttribute->setFramenumber(context.getFramenumber());
|
||||
angleAttribute->setMovieClip(clip);
|
||||
|
||||
angleAttribute->setInvert(invert);
|
||||
|
||||
xAttribute->setAttribute(MCA_X);
|
||||
xAttribute->setFramenumber(context.getFramenumber());
|
||||
xAttribute->setMovieClip(clip);
|
||||
|
||||
xAttribute->setInvert(invert);
|
||||
|
||||
yAttribute->setAttribute(MCA_Y);
|
||||
yAttribute->setFramenumber(context.getFramenumber());
|
||||
yAttribute->setMovieClip(clip);
|
||||
|
||||
yAttribute->setInvert(invert);
|
||||
|
||||
converter.addOperation(scaleAttribute);
|
||||
converter.addOperation(angleAttribute);
|
||||
converter.addOperation(xAttribute);
|
||||
|
|
|
@ -31,12 +31,14 @@ MovieClipAttributeOperation::MovieClipAttributeOperation() : NodeOperation()
|
|||
this->m_valueSet = false;
|
||||
this->m_framenumber = 0;
|
||||
this->m_attribute = MCA_X;
|
||||
this->m_invert = false;
|
||||
}
|
||||
|
||||
void MovieClipAttributeOperation::executePixelSampled(float output[4],
|
||||
float /*x*/, float /*y*/,
|
||||
PixelSampler /*sampler*/)
|
||||
{
|
||||
/* TODO(sergey): This code isn't really thread-safe. */
|
||||
if (!this->m_valueSet) {
|
||||
float loc[2], scale, angle;
|
||||
loc[0] = 0.0f;
|
||||
|
@ -61,6 +63,14 @@ void MovieClipAttributeOperation::executePixelSampled(float output[4],
|
|||
this->m_value = loc[1];
|
||||
break;
|
||||
}
|
||||
if (this->m_invert) {
|
||||
if (this->m_attribute != MCA_SCALE) {
|
||||
this->m_value = -this->m_value;
|
||||
}
|
||||
else {
|
||||
this->m_value = 1.0f / this->m_value;
|
||||
}
|
||||
}
|
||||
this->m_valueSet = true;
|
||||
}
|
||||
output[0] = this->m_value;
|
||||
|
|
|
@ -41,6 +41,7 @@ private:
|
|||
float m_value;
|
||||
bool m_valueSet;
|
||||
int m_framenumber;
|
||||
bool m_invert;
|
||||
MovieClipAttribute m_attribute;
|
||||
public:
|
||||
/**
|
||||
|
@ -57,5 +58,6 @@ public:
|
|||
void setMovieClip(MovieClip *clip) { this->m_clip = clip; }
|
||||
void setFramenumber(int framenumber) { this->m_framenumber = framenumber; }
|
||||
void setAttribute(MovieClipAttribute attribute) { this->m_attribute = attribute; }
|
||||
void setInvert(bool invert) { this->m_invert = invert; }
|
||||
};
|
||||
#endif
|
||||
|
|
|
@ -2035,6 +2035,7 @@ static void node_composit_buts_stabilize2d(uiLayout *layout, bContext *C, Pointe
|
|||
return;
|
||||
|
||||
uiItemR(layout, ptr, "filter_type", 0, "", ICON_NONE);
|
||||
uiItemR(layout, ptr, "invert", 0, NULL, ICON_NONE);
|
||||
}
|
||||
|
||||
static void node_composit_buts_translate(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
|
||||
|
|
|
@ -1110,6 +1110,11 @@ enum {
|
|||
CMP_NODEFLAG_PLANETRACKDEFORM_MOTION_BLUR = 1,
|
||||
};
|
||||
|
||||
/* Stabilization node */
|
||||
enum {
|
||||
CMP_NODEFLAG_STABILIZE_INVERSE = 1,
|
||||
};
|
||||
|
||||
#define CMP_NODE_PLANETRACKDEFORM_MBLUR_SAMPLES_MAX 64
|
||||
|
||||
/* Point Density shader node */
|
||||
|
|
|
@ -5826,6 +5826,11 @@ static void def_cmp_stabilize2d(StructRNA *srna)
|
|||
RNA_def_property_enum_items(prop, node_sampler_type_items);
|
||||
RNA_def_property_ui_text(prop, "Filter", "Method to use to filter stabilization");
|
||||
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
|
||||
|
||||
prop = RNA_def_property(srna, "invert", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "custom2", CMP_NODEFLAG_STABILIZE_INVERSE);
|
||||
RNA_def_property_ui_text(prop, "Invert", "Invert stabilization to re-introduce motion to the frame");
|
||||
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
|
||||
}
|
||||
|
||||
static void def_cmp_moviedistortion(StructRNA *srna)
|
||||
|
|
Loading…
Reference in New Issue