Merge branch 'blender-v5.0-release'
This commit is contained in:
@@ -414,17 +414,17 @@ Build with external audaspace library installed on the system \
|
||||
(only enable if you know what you're doing!)"
|
||||
OFF
|
||||
)
|
||||
mark_as_advanced(WITH_AUDASPACE)
|
||||
mark_as_advanced(WITH_SYSTEM_AUDASPACE)
|
||||
|
||||
if(WITH_AUDASPACE AND NOT WITH_SYSTEM_AUDASPACE)
|
||||
option(WITH_RUBBERBAND "\
|
||||
Build with Rubber Band for audio time-stretching and pitch-scaling (used by Audaspace)"
|
||||
ON
|
||||
)
|
||||
endif()
|
||||
mark_as_advanced(WITH_AUDASPACE)
|
||||
mark_as_advanced(WITH_SYSTEM_AUDASPACE)
|
||||
mark_as_advanced(WITH_RUBBERBAND)
|
||||
|
||||
set_and_warn_dependency(WITH_AUDASPACE WITH_SYSTEM_AUDASPACE OFF)
|
||||
set_and_warn_dependency(WITH_AUDASPACE WITH_RUBBERBAND OFF)
|
||||
set_and_warn_incompatible(WITH_SYSTEM_AUDASPACE WITH_RUBBERBAND OFF)
|
||||
|
||||
if(WITH_GHOST_X11)
|
||||
option(WITH_X11_XINPUT "Enable X11 Xinput (tablet support and unicode input)" ON)
|
||||
@@ -2840,7 +2840,6 @@ if(FIRST_RUN)
|
||||
info_cfg_option(WITH_POTRACE)
|
||||
info_cfg_option(WITH_PUGIXML)
|
||||
info_cfg_option(WITH_QUADRIFLOW)
|
||||
info_cfg_option(WITH_RUBBERBAND)
|
||||
info_cfg_option(WITH_TBB)
|
||||
info_cfg_option(WITH_USD)
|
||||
info_cfg_option(WITH_MATERIALX)
|
||||
@@ -2879,6 +2878,7 @@ if(FIRST_RUN)
|
||||
|
||||
info_cfg_text("Audio:")
|
||||
info_cfg_option(WITH_AUDASPACE)
|
||||
info_cfg_option(WITH_RUBBERBAND)
|
||||
info_cfg_option(WITH_CODEC_FFMPEG)
|
||||
info_cfg_option(WITH_CODEC_SNDFILE)
|
||||
info_cfg_option(WITH_COREAUDIO)
|
||||
|
||||
@@ -615,6 +615,9 @@ static bool buttons_context_path(
|
||||
/* No pinned root, use scene as initial root. */
|
||||
else if (mainb != BCONTEXT_TOOL) {
|
||||
if (ELEM(mainb, BCONTEXT_STRIP, BCONTEXT_STRIP_MODIFIER)) {
|
||||
if (!sequencer_scene) {
|
||||
return false;
|
||||
}
|
||||
path->ptr[0] = RNA_id_pointer_create(&sequencer_scene->id);
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -23,9 +23,7 @@ struct ID;
|
||||
|
||||
namespace blender::seq {
|
||||
|
||||
struct SeqRenderState;
|
||||
struct StripScreenQuad;
|
||||
struct RenderData;
|
||||
struct ModifierApplyContext;
|
||||
|
||||
struct StripModifierTypeInfo {
|
||||
/**
|
||||
@@ -56,12 +54,7 @@ struct StripModifierTypeInfo {
|
||||
void (*copy_data)(StripModifierData *smd, StripModifierData *target);
|
||||
|
||||
/* Apply modifier on an image buffer. */
|
||||
void (*apply)(const RenderData *render_data,
|
||||
const Strip *strip,
|
||||
const float transform[3][3],
|
||||
StripModifierData *smd,
|
||||
ImBuf *ibuf,
|
||||
ImBuf *mask);
|
||||
void (*apply)(ModifierApplyContext &context, StripModifierData *smd, ImBuf *mask);
|
||||
|
||||
/** Register the panel types for the modifier's UI. */
|
||||
void (*panel_register)(ARegionType *region_type);
|
||||
|
||||
@@ -52,11 +52,8 @@ struct BrightContrastApplyOp {
|
||||
}
|
||||
};
|
||||
|
||||
static void brightcontrast_apply(const RenderData * /*render_data*/,
|
||||
const Strip * /*strip*/,
|
||||
const float transform[3][3],
|
||||
static void brightcontrast_apply(ModifierApplyContext &context,
|
||||
StripModifierData *smd,
|
||||
ImBuf *ibuf,
|
||||
ImBuf *mask)
|
||||
{
|
||||
const BrightContrastModifierData *bcmd = (BrightContrastModifierData *)smd;
|
||||
@@ -81,7 +78,7 @@ static void brightcontrast_apply(const RenderData * /*render_data*/,
|
||||
op.add = op.mul * brightness + delta;
|
||||
}
|
||||
|
||||
apply_modifier_op(op, ibuf, mask, float3x3(transform));
|
||||
apply_modifier_op(op, context.image, mask, context.transform);
|
||||
}
|
||||
|
||||
static void brightcontrast_panel_draw(const bContext *C, Panel *panel)
|
||||
|
||||
@@ -254,18 +254,13 @@ static void colorBalance_init_data(StripModifierData *smd)
|
||||
}
|
||||
}
|
||||
|
||||
static void colorBalance_apply(const RenderData * /*render_data*/,
|
||||
const Strip * /*strip*/,
|
||||
const float transform[3][3],
|
||||
StripModifierData *smd,
|
||||
ImBuf *ibuf,
|
||||
ImBuf *mask)
|
||||
static void colorBalance_apply(ModifierApplyContext &context, StripModifierData *smd, ImBuf *mask)
|
||||
{
|
||||
const ColorBalanceModifierData *cbmd = (const ColorBalanceModifierData *)smd;
|
||||
|
||||
ColorBalanceApplyOp op;
|
||||
op.init(*cbmd, ibuf->byte_buffer.data != nullptr);
|
||||
apply_modifier_op(op, ibuf, mask, float3x3(transform));
|
||||
op.init(*cbmd, context.image->byte_buffer.data != nullptr);
|
||||
apply_modifier_op(op, context.image, mask, context.transform);
|
||||
}
|
||||
|
||||
static void colorBalance_panel_draw(const bContext *C, Panel *panel)
|
||||
|
||||
@@ -44,13 +44,14 @@ class CompositorContext : public compositor::Context {
|
||||
ImBuf *image_buffer_;
|
||||
ImBuf *mask_buffer_;
|
||||
float3x3 xform_;
|
||||
float2 result_translation_ = float2(0, 0);
|
||||
|
||||
public:
|
||||
CompositorContext(const RenderData &render_data,
|
||||
const SequencerCompositorModifierData *modifier_data,
|
||||
ImBuf *image_buffer,
|
||||
ImBuf *mask_buffer,
|
||||
const Strip *strip)
|
||||
const Strip &strip)
|
||||
: compositor::Context(),
|
||||
render_data_(render_data),
|
||||
modifier_data_(modifier_data),
|
||||
@@ -61,10 +62,15 @@ class CompositorContext : public compositor::Context {
|
||||
if (mask_buffer) {
|
||||
/* Note: do not use passed transform matrix since compositor coordinate
|
||||
* space is not from the image corner, but rather centered on the image. */
|
||||
xform_ = math::invert(image_transform_matrix_get(render_data.scene, strip));
|
||||
xform_ = math::invert(image_transform_matrix_get(render_data.scene, &strip));
|
||||
}
|
||||
}
|
||||
|
||||
float2 get_result_translation() const
|
||||
{
|
||||
return result_translation_;
|
||||
}
|
||||
|
||||
const Scene &get_scene() const override
|
||||
{
|
||||
return *render_data_.scene;
|
||||
@@ -101,6 +107,7 @@ class CompositorContext : public compositor::Context {
|
||||
|
||||
compositor::Result get_output(compositor::Domain domain) override
|
||||
{
|
||||
result_translation_ = domain.transformation.location();
|
||||
compositor::Result result = this->create_result(compositor::ResultType::Color);
|
||||
if (domain.size.x != image_buffer_->x || domain.size.y != image_buffer_->y) {
|
||||
/* Output size is different (e.g. image is blurred with expanded bounds);
|
||||
@@ -119,18 +126,8 @@ class CompositorContext : public compositor::Context {
|
||||
bool /*is_data*/,
|
||||
compositor::ResultPrecision /*precision*/) override
|
||||
{
|
||||
compositor::Result result = this->create_result(compositor::ResultType::Color);
|
||||
if (domain.size.x != image_buffer_->x || domain.size.y != image_buffer_->y) {
|
||||
/* Output size is different (e.g. image is blurred with expanded bounds);
|
||||
* need to allocate appropriately sized buffer. */
|
||||
IMB_free_all_data(image_buffer_);
|
||||
image_buffer_->x = domain.size.x;
|
||||
image_buffer_->y = domain.size.y;
|
||||
IMB_alloc_float_pixels(image_buffer_, 4, false);
|
||||
}
|
||||
result.wrap_external(image_buffer_->float_buffer.data,
|
||||
int2(image_buffer_->x, image_buffer_->y));
|
||||
return result;
|
||||
/* Within compositor modifier, output and viewer output function the same. */
|
||||
return get_output(domain);
|
||||
}
|
||||
|
||||
compositor::Result get_input(StringRef name) override
|
||||
@@ -199,11 +196,8 @@ static bool ensure_linear_float_buffer(ImBuf *ibuf)
|
||||
return false;
|
||||
}
|
||||
|
||||
static void compositor_modifier_apply(const RenderData *render_data,
|
||||
const Strip *strip,
|
||||
const float /*transform*/[3][3],
|
||||
static void compositor_modifier_apply(ModifierApplyContext &context,
|
||||
StripModifierData *strip_modifier_data,
|
||||
ImBuf *image_buffer,
|
||||
ImBuf *mask)
|
||||
{
|
||||
const SequencerCompositorModifierData *modifier_data =
|
||||
@@ -218,13 +212,16 @@ static void compositor_modifier_apply(const RenderData *render_data,
|
||||
ensure_linear_float_buffer(linear_mask);
|
||||
}
|
||||
|
||||
const bool was_float_linear = ensure_linear_float_buffer(image_buffer);
|
||||
const bool was_byte = image_buffer->float_buffer.data == nullptr;
|
||||
const bool was_float_linear = ensure_linear_float_buffer(context.image);
|
||||
const bool was_byte = context.image->float_buffer.data == nullptr;
|
||||
|
||||
CompositorContext context(*render_data, modifier_data, image_buffer, linear_mask, strip);
|
||||
compositor::Evaluator evaluator(context);
|
||||
CompositorContext com_context(
|
||||
context.render_data, modifier_data, context.image, linear_mask, context.strip);
|
||||
compositor::Evaluator evaluator(com_context);
|
||||
evaluator.evaluate();
|
||||
|
||||
context.result_translation += com_context.get_result_translation();
|
||||
|
||||
if (mask != linear_mask) {
|
||||
IMB_freeImBuf(linear_mask);
|
||||
}
|
||||
@@ -234,11 +231,11 @@ static void compositor_modifier_apply(const RenderData *render_data,
|
||||
}
|
||||
|
||||
if (was_byte) {
|
||||
IMB_byte_from_float(image_buffer);
|
||||
IMB_free_float_pixels(image_buffer);
|
||||
IMB_byte_from_float(context.image);
|
||||
IMB_free_float_pixels(context.image);
|
||||
}
|
||||
else {
|
||||
seq_imbuf_to_sequencer_space(render_data->scene, image_buffer, true);
|
||||
seq_imbuf_to_sequencer_space(context.render_data.scene, context.image, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -69,12 +69,7 @@ struct CurvesApplyOp {
|
||||
}
|
||||
};
|
||||
|
||||
static void curves_apply(const RenderData * /*render_data*/,
|
||||
const Strip * /*strip*/,
|
||||
const float transform[3][3],
|
||||
StripModifierData *smd,
|
||||
ImBuf *ibuf,
|
||||
ImBuf *mask)
|
||||
static void curves_apply(ModifierApplyContext &context, StripModifierData *smd, ImBuf *mask)
|
||||
{
|
||||
CurvesModifierData *cmd = (CurvesModifierData *)smd;
|
||||
|
||||
@@ -88,7 +83,7 @@ static void curves_apply(const RenderData * /*render_data*/,
|
||||
|
||||
CurvesApplyOp op;
|
||||
op.curve_mapping = &cmd->curve_mapping;
|
||||
apply_modifier_op(op, ibuf, mask, float3x3(transform));
|
||||
apply_modifier_op(op, context.image, mask, context.transform);
|
||||
|
||||
BKE_curvemapping_premultiply(&cmd->curve_mapping, true);
|
||||
}
|
||||
|
||||
@@ -104,12 +104,7 @@ struct HueCorrectApplyOp {
|
||||
}
|
||||
};
|
||||
|
||||
static void hue_correct_apply(const RenderData * /*render_data*/,
|
||||
const Strip * /*strip*/,
|
||||
const float transform[3][3],
|
||||
StripModifierData *smd,
|
||||
ImBuf *ibuf,
|
||||
ImBuf *mask)
|
||||
static void hue_correct_apply(ModifierApplyContext &context, StripModifierData *smd, ImBuf *mask)
|
||||
{
|
||||
HueCorrectModifierData *hcmd = (HueCorrectModifierData *)smd;
|
||||
|
||||
@@ -117,7 +112,7 @@ static void hue_correct_apply(const RenderData * /*render_data*/,
|
||||
|
||||
HueCorrectApplyOp op;
|
||||
op.curve_mapping = &hcmd->curve_mapping;
|
||||
apply_modifier_op(op, ibuf, mask, float3x3(transform));
|
||||
apply_modifier_op(op, context.image, mask, context.transform);
|
||||
}
|
||||
|
||||
static void hue_correct_panel_draw(const bContext *C, Panel *panel)
|
||||
|
||||
@@ -53,11 +53,8 @@ struct MaskApplyOp {
|
||||
}
|
||||
};
|
||||
|
||||
static void maskmodifier_apply(const RenderData * /* render_data */,
|
||||
const Strip * /*strip*/,
|
||||
const float transform[3][3],
|
||||
static void maskmodifier_apply(ModifierApplyContext &context,
|
||||
StripModifierData * /*smd*/,
|
||||
ImBuf *ibuf,
|
||||
ImBuf *mask)
|
||||
{
|
||||
if (mask == nullptr || (mask->byte_buffer.data == nullptr && mask->float_buffer.data == nullptr))
|
||||
@@ -66,10 +63,10 @@ static void maskmodifier_apply(const RenderData * /* render_data */,
|
||||
}
|
||||
|
||||
MaskApplyOp op;
|
||||
apply_modifier_op(op, ibuf, mask, float3x3(transform));
|
||||
apply_modifier_op(op, context.image, mask, context.transform);
|
||||
|
||||
/* Image has gained transparency. */
|
||||
ibuf->planes = R_IMF_PLANES_RGBA;
|
||||
context.image->planes = R_IMF_PLANES_RGBA;
|
||||
}
|
||||
|
||||
static void maskmodifier_panel_draw(const bContext *C, Panel *panel)
|
||||
|
||||
@@ -281,19 +281,16 @@ static AreaLuminance tonemap_calc_input_luminance(const ImBuf *ibuf)
|
||||
return lum;
|
||||
}
|
||||
|
||||
static void tonemapmodifier_apply(const RenderData * /*render_data*/,
|
||||
const Strip * /*strip*/,
|
||||
const float transform[3][3],
|
||||
static void tonemapmodifier_apply(ModifierApplyContext &context,
|
||||
StripModifierData *smd,
|
||||
ImBuf *ibuf,
|
||||
ImBuf *mask)
|
||||
{
|
||||
const SequencerTonemapModifierData *tmmd = (const SequencerTonemapModifierData *)smd;
|
||||
|
||||
TonemapApplyOp op;
|
||||
op.type = eModTonemapType(tmmd->type);
|
||||
op.ibuf = ibuf;
|
||||
op.lum = tonemap_calc_input_luminance(ibuf);
|
||||
op.ibuf = context.image;
|
||||
op.lum = tonemap_calc_input_luminance(context.image);
|
||||
if (op.lum.pixel_count == 0) {
|
||||
return; /* Strip is zero size or off-screen. */
|
||||
}
|
||||
@@ -311,7 +308,7 @@ static void tonemapmodifier_apply(const RenderData * /*render_data*/,
|
||||
op.data.al = (al == 0.0f) ? 0.0f : (tmmd->key / al);
|
||||
op.data.igm = (tmmd->gamma == 0.0f) ? 1.0f : (1.0f / tmmd->gamma);
|
||||
|
||||
apply_modifier_op(op, ibuf, mask, float3x3(transform));
|
||||
apply_modifier_op(op, context.image, mask, context.transform);
|
||||
}
|
||||
|
||||
static void tonemapmodifier_panel_draw(const bContext *C, Panel *panel)
|
||||
|
||||
@@ -62,12 +62,7 @@ struct WhiteBalanceApplyOp {
|
||||
}
|
||||
};
|
||||
|
||||
static void whiteBalance_apply(const RenderData * /*render_data*/,
|
||||
const Strip * /*strip*/,
|
||||
const float transform[3][3],
|
||||
StripModifierData *smd,
|
||||
ImBuf *ibuf,
|
||||
ImBuf *mask)
|
||||
static void whiteBalance_apply(ModifierApplyContext &context, StripModifierData *smd, ImBuf *mask)
|
||||
{
|
||||
const WhiteBalanceModifierData *data = (const WhiteBalanceModifierData *)smd;
|
||||
|
||||
@@ -75,7 +70,7 @@ static void whiteBalance_apply(const RenderData * /*render_data*/,
|
||||
op.multiplier[0] = (data->white_value[0] != 0.0f) ? 1.0f / data->white_value[0] : FLT_MAX;
|
||||
op.multiplier[1] = (data->white_value[1] != 0.0f) ? 1.0f / data->white_value[1] : FLT_MAX;
|
||||
op.multiplier[2] = (data->white_value[2] != 0.0f) ? 1.0f / data->white_value[2] : FLT_MAX;
|
||||
apply_modifier_op(op, ibuf, mask, float3x3(transform));
|
||||
apply_modifier_op(op, context.image, mask, context.transform);
|
||||
}
|
||||
|
||||
static void whiteBalance_panel_draw(const bContext *C, Panel *panel)
|
||||
|
||||
@@ -297,8 +297,8 @@ void store_pixel_raw(float4 pix, float *ptr)
|
||||
/**
|
||||
* \a timeline_frame is offset by \a fra_offset only in case we are using a real mask.
|
||||
*/
|
||||
static ImBuf *modifier_render_mask_input(const RenderData *context,
|
||||
SeqRenderState *state,
|
||||
static ImBuf *modifier_render_mask_input(const RenderData &context,
|
||||
SeqRenderState &state,
|
||||
int mask_input_type,
|
||||
Strip *mask_strip,
|
||||
Mask *mask_id,
|
||||
@@ -309,7 +309,7 @@ static ImBuf *modifier_render_mask_input(const RenderData *context,
|
||||
|
||||
if (mask_input_type == STRIP_MASK_INPUT_STRIP) {
|
||||
if (mask_strip) {
|
||||
mask_input = seq_render_strip(context, state, mask_strip, timeline_frame);
|
||||
mask_input = seq_render_strip(&context, &state, mask_strip, timeline_frame);
|
||||
}
|
||||
}
|
||||
else if (mask_input_type == STRIP_MASK_INPUT_ID) {
|
||||
@@ -317,9 +317,9 @@ static ImBuf *modifier_render_mask_input(const RenderData *context,
|
||||
* fine, but if it is a byte image then we also just take that without
|
||||
* extra memory allocations or conversions. All modifiers are expected
|
||||
* to handle mask being either type. */
|
||||
mask_input = seq_render_mask(context->depsgraph,
|
||||
context->rectx,
|
||||
context->recty,
|
||||
mask_input = seq_render_mask(context.depsgraph,
|
||||
context.rectx,
|
||||
context.recty,
|
||||
mask_id,
|
||||
timeline_frame - fra_offset,
|
||||
false);
|
||||
@@ -464,18 +464,17 @@ static bool skip_modifier(Scene *scene, const StripModifierData *smd, int timeli
|
||||
return strip_has_ended_skip || missing_data_skip;
|
||||
}
|
||||
|
||||
void modifier_apply_stack(const RenderData *context,
|
||||
SeqRenderState *state,
|
||||
const Strip *strip,
|
||||
const float3x3 &transform,
|
||||
ImBuf *ibuf,
|
||||
int timeline_frame)
|
||||
void modifier_apply_stack(ModifierApplyContext &context, int timeline_frame)
|
||||
{
|
||||
if (strip->modifiers.first && (strip->flag & SEQ_USE_LINEAR_MODIFIERS)) {
|
||||
render_imbuf_from_sequencer_space(context->scene, ibuf);
|
||||
if (context.strip.modifiers.first == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
LISTBASE_FOREACH (StripModifierData *, smd, &strip->modifiers) {
|
||||
if (context.strip.flag & SEQ_USE_LINEAR_MODIFIERS) {
|
||||
render_imbuf_from_sequencer_space(context.render_data.scene, context.image);
|
||||
}
|
||||
|
||||
LISTBASE_FOREACH (StripModifierData *, smd, &context.strip.modifiers) {
|
||||
const StripModifierTypeInfo *smti = modifier_type_info_get(smd->type);
|
||||
|
||||
/* could happen if modifier is being removed or not exists in current version of blender */
|
||||
@@ -488,31 +487,31 @@ void modifier_apply_stack(const RenderData *context,
|
||||
continue;
|
||||
}
|
||||
|
||||
if (smti->apply && !skip_modifier(context->scene, smd, timeline_frame)) {
|
||||
if (smti->apply && !skip_modifier(context.render_data.scene, smd, timeline_frame)) {
|
||||
int frame_offset;
|
||||
if (smd->mask_time == STRIP_MASK_TIME_RELATIVE) {
|
||||
frame_offset = strip->start;
|
||||
frame_offset = context.strip.start;
|
||||
}
|
||||
else /* if (smd->mask_time == STRIP_MASK_TIME_ABSOLUTE) */ {
|
||||
frame_offset = smd->mask_id ? ((Mask *)smd->mask_id)->sfra : 0;
|
||||
}
|
||||
|
||||
ImBuf *mask = modifier_render_mask_input(context,
|
||||
state,
|
||||
ImBuf *mask = modifier_render_mask_input(context.render_data,
|
||||
context.render_state,
|
||||
smd->mask_input_type,
|
||||
smd->mask_strip,
|
||||
smd->mask_id,
|
||||
timeline_frame,
|
||||
frame_offset);
|
||||
smti->apply(context, strip, transform.ptr(), smd, ibuf, mask);
|
||||
smti->apply(context, smd, mask);
|
||||
if (mask) {
|
||||
IMB_freeImBuf(mask);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (strip->modifiers.first && (strip->flag & SEQ_USE_LINEAR_MODIFIERS)) {
|
||||
seq_imbuf_to_sequencer_space(context->scene, ibuf, false);
|
||||
if (context.strip.flag & SEQ_USE_LINEAR_MODIFIERS) {
|
||||
seq_imbuf_to_sequencer_space(context.render_data.scene, context.image, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -30,15 +30,36 @@ namespace blender::seq {
|
||||
struct RenderData;
|
||||
struct SeqRenderState;
|
||||
|
||||
/* `transform` is transformation from strip image local pixel coordinates
|
||||
* to the full render area pixel coordinates. This is used to sample
|
||||
* modifier masks (since masks are in full render area space). */
|
||||
void modifier_apply_stack(const RenderData *context,
|
||||
SeqRenderState *state,
|
||||
const Strip *strip,
|
||||
struct ModifierApplyContext {
|
||||
ModifierApplyContext(const RenderData &render_data,
|
||||
SeqRenderState &render_state,
|
||||
const Strip &strip,
|
||||
const float3x3 &transform,
|
||||
ImBuf *ibuf,
|
||||
int timeline_frame);
|
||||
ImBuf *image)
|
||||
: render_data(render_data),
|
||||
render_state(render_state),
|
||||
strip(strip),
|
||||
transform(transform),
|
||||
image(image)
|
||||
{
|
||||
}
|
||||
const RenderData &render_data;
|
||||
SeqRenderState &render_state;
|
||||
const Strip &strip;
|
||||
|
||||
/* Transformation from strip image local pixel coordinates to the
|
||||
* full render area pixel coordinates.This is used to sample
|
||||
* modifier masks (since masks are in full render area space). */
|
||||
const float3x3 transform;
|
||||
ImBuf *const image;
|
||||
|
||||
/* How much the resulting image should be translated, in pixels.
|
||||
* Compositor modifier can have some nodes that translate the output
|
||||
* image. */
|
||||
float2 result_translation = float2(0, 0);
|
||||
};
|
||||
|
||||
void modifier_apply_stack(ModifierApplyContext &context, int timeline_frame);
|
||||
|
||||
bool modifier_persistent_uids_are_valid(const Strip &strip);
|
||||
|
||||
|
||||
@@ -666,6 +666,7 @@ static ImBuf *input_preprocess(const RenderData *context,
|
||||
const bool do_scale_to_render_size = seq_need_scale_to_render_size(strip, is_proxy_image);
|
||||
const float image_scale_factor = do_scale_to_render_size ? preview_scale_factor : 1.0f;
|
||||
|
||||
float2 modifier_translation = float2(0, 0);
|
||||
if (strip->modifiers.first) {
|
||||
ibuf = IMB_makeSingleUser(ibuf);
|
||||
float3x3 matrix = calc_strip_transform_matrix(scene,
|
||||
@@ -676,11 +677,13 @@ static ImBuf *input_preprocess(const RenderData *context,
|
||||
context->recty,
|
||||
image_scale_factor,
|
||||
preview_scale_factor);
|
||||
modifier_apply_stack(context, state, strip, matrix, ibuf, timeline_frame);
|
||||
ModifierApplyContext mod_context(*context, *state, *strip, matrix, ibuf);
|
||||
modifier_apply_stack(mod_context, timeline_frame);
|
||||
modifier_translation = mod_context.result_translation;
|
||||
}
|
||||
|
||||
if (sequencer_use_crop(strip) || sequencer_use_transform(strip) || context->rectx != ibuf->x ||
|
||||
context->recty != ibuf->y)
|
||||
context->recty != ibuf->y || modifier_translation != float2(0, 0))
|
||||
{
|
||||
const int x = context->rectx;
|
||||
const int y = context->recty;
|
||||
@@ -696,6 +699,7 @@ static ImBuf *input_preprocess(const RenderData *context,
|
||||
context->recty,
|
||||
image_scale_factor,
|
||||
preview_scale_factor);
|
||||
matrix *= math::from_location<float3x3>(modifier_translation);
|
||||
matrix = math::invert(matrix);
|
||||
sequencer_preprocess_transform_crop(ibuf,
|
||||
transformed_ibuf,
|
||||
|
||||
BIN
tests/files/sequence_editing/effects/mod_comp_transform.blend
(Stored with Git LFS)
Normal file
BIN
tests/files/sequence_editing/effects/mod_comp_transform.blend
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
tests/files/sequence_editing/effects/reference/mod_comp_transform.png
(Stored with Git LFS)
Normal file
BIN
tests/files/sequence_editing/effects/reference/mod_comp_transform.png
(Stored with Git LFS)
Normal file
Binary file not shown.
Reference in New Issue
Block a user