NLA: Udating Blend-in and Blend-out values to clamp on NLA strip Transform

Previously, transforming a clip (scaling, repeat, etc) wouldn't re-calculate the blend-in and blend-out values, leading to over / undershoot, and a visual clip artifact

Old:

{F14045003}

This patch adds re-calculation logic (new `BKE_nlastrip_recalculate_blend()`  method) to the blend-in/out on transformations to clamp values, and avoid over/under shoot.

The `BKE_nlastrip_recalculate_blend()`  encapsulates the existing logic for both the `rna_NlaStrip_blend_in_set()` and `rna_NlaStrip_blend_out_set()` methods into a single BKE method that we an execute as needed. The fact that blend-in is first decreased, is strictly on the order of calculation. My suspicion is that //if// the blend-in / blend-our values were working as intended, the RNA set methods would update in order, and we'd experience the same thing. In short, the choice here was to linearly combine the logic, without making any assumptions of my own.

while talking things over with @sybren  and @RiggingDojo, they are fine with how this currently works, but there a desire to update how the two values interact with each (ratio scale, etc) in the future.

New:
{F14045024}

{F14045025}

Reviewed By: sybren

Maniphest Tasks: T101369

Differential Revision: https://developer.blender.org/D16720
This commit is contained in:
Nate Rupsis 2023-01-19 13:42:23 -05:00 committed by Nate Rupsis
parent 9066f2e043
commit fa67b84c34
Notes: blender-bot 2023-05-22 12:40:41 +02:00
Referenced by issue #101369, NLA strip blend in line renders incorrectly after scaling strip
5 changed files with 81 additions and 1 deletions

View File

@ -10,6 +10,8 @@
/** Temp constant defined for these functions only. */
#define NLASTRIP_MIN_LEN_THRESH 0.1f
#include "DNA_listBase.h"
#ifdef __cplusplus
extern "C" {
#endif
@ -295,6 +297,11 @@ void BKE_nlastrip_recalculate_bounds(struct NlaStrip *strip);
*/
void BKE_nlastrip_recalculate_bounds_sync_action(struct NlaStrip *strip);
/**
* Recalculate the Blendin and Blendout values after a strip transform update.
*/
void BKE_nlastrip_recalculate_blend(struct NlaStrip *strip);
/**
* Find (and set) a unique name for a strip from the whole AnimData block
* Uses a similar method to the BLI method, but is implemented differently

View File

@ -837,6 +837,7 @@ if(WITH_GTESTS)
intern/lib_id_remapper_test.cc
intern/lib_id_test.cc
intern/lib_remap_test.cc
intern/nla_test.cc
intern/tracking_test.cc
)
set(TEST_INC
@ -847,4 +848,4 @@ if(WITH_GTESTS)
# RNA_prototypes.h
add_dependencies(bf_blenkernel_tests bf_rna)
endif()
endif()

View File

@ -1521,6 +1521,30 @@ void BKE_nlastrip_recalculate_bounds(NlaStrip *strip)
nlastrip_fix_resize_overlaps(strip);
}
void BKE_nlastrip_recalculate_blend(NlaStrip *strip)
{
/* check if values need to be re-calculated. */
if (strip->blendin == 0 && strip->blendout == 0) {
return;
}
const double strip_len = strip->end - strip->start;
double blend_in = strip->blendin;
double blend_out = strip->blendout;
double blend_in_max = strip_len - blend_out;
CLAMP_MIN(blend_in_max, 0);
/* blend-out is limited to the length of the strip. */
CLAMP(blend_in, 0, blend_in_max);
CLAMP(blend_out, 0, strip_len - blend_in);
strip->blendin = blend_in;
strip->blendout = blend_out;
}
/* Animated Strips ------------------------------------------- */
bool BKE_nlatrack_has_animated_strips(NlaTrack *nlt)
@ -1854,6 +1878,7 @@ void BKE_nla_validate_state(AnimData *adt)
for (strip = nlt->strips.first; strip; strip = strip->next) {
/* auto-blending first */
BKE_nlastrip_validate_autoblends(nlt, strip);
BKE_nlastrip_recalculate_blend(strip);
}
}
}

View File

@ -0,0 +1,45 @@
/* SPDX-License-Identifier: GPL-2.0-or-later
* Copyright 2023 Blender Foundation. All rights reserved. */
#include "BKE_nla.h"
#include "DNA_nla_types.h"
#include "DNA_anim_types.h"
#include "MEM_guardedalloc.h"
#include "testing/testing.h"
namespace blender::bke::tests {
TEST(nla_strip, BKE_nlastrip_recalculate_blend)
{
NlaStrip strip = {
.blendin = 4.0,
.blendout = 5.0,
.start = 1,
.end = 10
};
/* Scaling a strip up doesn't affect the blend in/out value */
strip.end = 20;
BKE_nlastrip_recalculate_blend(&strip);
EXPECT_FLOAT_EQ(strip.blendin, 4.0);
EXPECT_FLOAT_EQ(strip.blendout, 5.0);
/* Scaling a strip down affects the blend-in value before the blend-out value */
strip.end = 7;
BKE_nlastrip_recalculate_blend(&strip);
EXPECT_FLOAT_EQ(strip.blendin, 1.0);
EXPECT_FLOAT_EQ(strip.blendout, 5.0);
/* Scaling a strip down to nothing updates the blend in/out values accordingly */
strip.end = 1.1;
BKE_nlastrip_recalculate_blend(&strip);
EXPECT_FLOAT_EQ(strip.blendin, 0.0);
EXPECT_FLOAT_EQ(strip.blendout, 0.1);
}
} // namespace blender::bke::tests

View File

@ -157,6 +157,8 @@ static void rna_NlaStrip_transform_update(Main *bmain, Scene *scene, PointerRNA
}
}
BKE_nlastrip_recalculate_blend(strip);
rna_NlaStrip_update(bmain, scene, ptr);
}