Fix T101130: Scaling of NLA Strip Via S Hotkey Not Working

After switching over to using start_frame / end_frame, scaling an NLA strip didn't scale the strip, it just repeated the action.

Now withing the NLA transform code, we look for TFM_TIME_EXTEND / TFM_TIME_SCALE transform mode, and handle the update to strip scale accordingly
This commit is contained in:
Nate Rupsis 2022-12-13 08:09:08 -05:00 committed by Hans Goudey
parent 5e384860a6
commit 1965e31d17
2 changed files with 38 additions and 9 deletions

View File

@ -973,21 +973,19 @@ void BKE_nlameta_flush_transforms(NlaStrip *mstrip)
oEnd = ((NlaStrip *)mstrip->strips.last)->end;
offset = mstrip->start - oStart;
/* check if scale changed */
oLen = oEnd - oStart;
nLen = mstrip->end - mstrip->start;
scaleChanged = !IS_EQF(oLen, nLen);
/* optimization:
* don't flush if nothing changed yet
* TODO: maybe we need a flag to say always flush?
*/
if (IS_EQF(oStart, mstrip->start) && IS_EQF(oEnd, mstrip->end)) {
if (IS_EQF(oStart, mstrip->start) && IS_EQF(oEnd, mstrip->end) && !scaleChanged) {
return;
}
/* check if scale changed */
oLen = oEnd - oStart;
nLen = mstrip->end - mstrip->start;
if (IS_EQF(nLen, oLen) == 0) {
scaleChanged = 1;
}
/* for each child-strip, calculate new start/end points based on this new info */
for (strip = mstrip->strips.first; strip; strip = strip->next) {
if (scaleChanged) {
@ -1001,6 +999,12 @@ void BKE_nlameta_flush_transforms(NlaStrip *mstrip)
* then wait for second pass to flush scale properly. */
strip->start = (p1 * nLen) + mstrip->start;
strip->end = (p2 * nLen) + mstrip->start;
// Recompute the playback scale, given the new start & end frame of the strip.
const double action_len = strip->actend - strip->actstart;
const double repeated_len = action_len * strip->repeat;
const double strip_len = strip->end - strip->start;
strip->scale = strip_len / repeated_len;
}
else {
/* just apply the changes in offset to both ends of the strip */

View File

@ -76,6 +76,11 @@ static void applyTransformNLA_translation(PointerRNA *strip_rna_ptr, const Trans
RNA_float_set(strip_rna_ptr, "frame_end", transdata->h2[0]);
}
static void applyTransformNLA_timeScale(PointerRNA *strip_rna_ptr, const float value)
{
RNA_float_set(strip_rna_ptr, "scale", value);
}
/** \} */
/* -------------------------------------------------------------------- */
@ -204,6 +209,7 @@ static void createTransNlaData(bContext *C, TransInfo *t)
tdn->h1[1] = yval;
tdn->h2[0] = strip->end;
tdn->h2[1] = yval;
tdn->h1[2] = tdn->h2[2] = strip->scale;
center[0] = (float)scene->r.cfra;
center[1] = yval;
@ -333,6 +339,8 @@ static void recalcData_nla(TransInfo *t)
strip->next->start = tdn->h2[0];
}
strip->scale = tdn->h1[2];
/* flush transforms to child strips (since this should be a meta) */
BKE_nlameta_flush_transforms(strip);
@ -399,7 +407,24 @@ static void recalcData_nla(TransInfo *t)
*/
RNA_pointer_create(NULL, &RNA_NlaStrip, strip, &strip_ptr);
applyTransformNLA_translation(&strip_ptr, tdn);
switch (t->mode) {
case TFM_TIME_EXTEND:
case TFM_TIME_SCALE: {
/* The final scale is the product of the original strip scale (from before the transform
* operation started) and the current scale value of this transform operation. */
const float originalStripScale = tdn->h1[2];
const float newStripScale = originalStripScale * t->values_final[0];
applyTransformNLA_timeScale(&strip_ptr, newStripScale);
applyTransformNLA_translation(&strip_ptr, tdn);
break;
}
case TFM_TRANSLATION:
applyTransformNLA_translation(&strip_ptr, tdn);
break;
default:
printf("recalcData_nla: unsupported NLA transformation mode %d\n", t->mode);
continue;
}
/* flush transforms to child strips (since this should be a meta) */
BKE_nlameta_flush_transforms(strip);