Realtime Compositor: Implement Stabilize 2D node

This patch implements the Stabilize 2D node for the realtime compositor.

Pull Request: https://projects.blender.org/blender/blender/pulls/107401
This commit is contained in:
Omar Emara 2023-05-02 17:11:59 +02:00 committed by Omar Emara
parent 1a5ad33a57
commit 88d03d15c1
4 changed files with 80 additions and 13 deletions

View File

@ -21,7 +21,7 @@ void Stabilize2dNode::convert_to_operations(NodeConverter &converter,
const bNode *editor_node = this->get_bnode();
NodeInput *image_input = this->get_input_socket(0);
MovieClip *clip = (MovieClip *)editor_node->id;
bool invert = (editor_node->custom2 & CMP_NODEFLAG_STABILIZE_INVERSE) != 0;
bool invert = (editor_node->custom2 & CMP_NODE_STABILIZE_FLAG_INVERSE) != 0;
const PixelSampler sampler = (PixelSampler)editor_node->custom1;
MovieClipAttributeOperation *scale_attribute = new MovieClipAttributeOperation();

View File

@ -2096,18 +2096,24 @@ typedef enum CMPNodeGlareType {
CMP_NODE_GLARE_GHOST = 3,
} CMPNodeGlareType;
/* Stabilize 2D node. Stored in custom1. */
typedef enum CMPNodeStabilizeInterpolation {
CMP_NODE_STABILIZE_INTERPOLATION_NEAREST = 0,
CMP_NODE_STABILIZE_INTERPOLATION_BILINEAR = 1,
CMP_NODE_STABILIZE_INTERPOLATION_BICUBIC = 2,
} CMPNodeStabilizeInterpolation;
/* Stabilize 2D node. Stored in custom2. */
typedef enum CMPNodeStabilizeInverse {
CMP_NODE_STABILIZE_FLAG_INVERSE = 1,
} CMPNodeStabilizeInverse;
/* Plane track deform node. */
enum {
CMP_NODEFLAG_PLANETRACKDEFORM_MOTION_BLUR = 1,
};
/* Stabilization node. */
enum {
CMP_NODEFLAG_STABILIZE_INVERSE = 1,
};
/* Set Alpha Node. */
/** #NodeSetAlpha.mode */

View File

@ -8283,7 +8283,7 @@ static void def_cmp_stabilize2d(StructRNA *srna)
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_boolean_sdna(prop, NULL, "custom2", CMP_NODE_STABILIZE_FLAG_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");

View File

@ -5,13 +5,24 @@
* \ingroup cmpnodes
*/
#include "BLI_assert.h"
#include "BLI_math_angle_types.hh"
#include "BLI_math_matrix.hh"
#include "BLI_math_matrix_types.hh"
#include "BLI_math_vector_types.hh"
#include "BLT_translation.h"
#include "UI_interface.h"
#include "UI_resources.h"
#include "DNA_movieclip_types.h"
#include "DNA_node_types.h"
#include "BKE_context.h"
#include "BKE_lib_id.h"
#include "BKE_movieclip.h"
#include "BKE_tracking.h"
#include "COM_node_operation.hh"
@ -23,7 +34,9 @@ namespace blender::nodes::node_composite_stabilize2d_cc {
static void cmp_node_stabilize2d_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Color>(N_("Image")).default_value({0.8f, 0.8f, 0.8f, 1.0f});
b.add_input<decl::Color>(N_("Image"))
.default_value({0.8f, 0.8f, 0.8f, 1.0f})
.compositor_domain_priority(0);
b.add_output<decl::Color>(N_("Image"));
}
@ -70,8 +83,58 @@ class Stabilize2DOperation : public NodeOperation {
void execute() override
{
get_input("Image").pass_through(get_result("Image"));
context().set_info_message("Viewport compositor setup not fully supported");
Result &input_image = get_input("Image");
Result &output_image = get_result("Image");
input_image.pass_through(output_image);
MovieClip *movie_clip = get_movie_clip();
if (input_image.is_single_value() || !movie_clip) {
return;
}
const int width = input_image.domain().size.x;
const int height = input_image.domain().size.y;
const int frame_number = BKE_movieclip_remap_scene_to_clip_frame(movie_clip,
context().get_frame_number());
float2 translation;
float scale, rotation;
BKE_tracking_stabilization_data_get(
movie_clip, frame_number, width, height, translation, &scale, &rotation);
float3x3 transformation = math::from_loc_rot_scale<float3x3>(
translation, math::AngleRadian(rotation), float2(scale));
if (do_inverse_stabilization()) {
transformation = math::invert(transformation);
}
output_image.transform(transformation);
output_image.get_realization_options().interpolation = get_interpolation();
}
Interpolation get_interpolation()
{
switch (static_cast<CMPNodeStabilizeInterpolation>(bnode().custom1)) {
case CMP_NODE_STABILIZE_INTERPOLATION_NEAREST:
return Interpolation::Nearest;
case CMP_NODE_STABILIZE_INTERPOLATION_BILINEAR:
return Interpolation::Bilinear;
case CMP_NODE_STABILIZE_INTERPOLATION_BICUBIC:
return Interpolation::Bicubic;
}
BLI_assert_unreachable();
return Interpolation::Nearest;
}
bool do_inverse_stabilization()
{
return bnode().custom2 & CMP_NODE_STABILIZE_FLAG_INVERSE;
}
MovieClip *get_movie_clip()
{
return (MovieClip *)bnode().id;
}
};
@ -93,8 +156,6 @@ void register_node_type_cmp_stabilize2d()
ntype.draw_buttons = file_ns::node_composit_buts_stabilize2d;
ntype.initfunc_api = file_ns::init;
ntype.get_compositor_operation = file_ns::get_compositor_operation;
ntype.realtime_compositor_unsupported_message = N_(
"Node not supported in the Viewport compositor");
nodeRegisterType(&ntype);
}