Animation: Allow NLA strips to be horizontally shuffled #105532
|
@ -1953,13 +1953,13 @@ static void BKE_nlastrip_validate_autoblends(NlaTrack *nlt, NlaStrip *nls)
|
|||
}
|
||||
|
||||
/* Ensure every transition's start/end properly set.
|
||||
nrupsis marked this conversation as resolved
Outdated
|
||||
* Strip will be removed / freed if it doesn't fit.
|
||||
* Return value indicates if passed strip was freed or not. */
|
||||
* Strip will be removed / freed if it doesn't fit (invalid).
|
||||
nrupsis marked this conversation as resolved
Outdated
Sybren A. Stüvel
commented
Better name would be Better name would be `nlastrip_validate_transition_start_end`, to show that it's about transitions only.
|
||||
* Return value indicates if passed strip is valid/fixed or invalid/removed. */
|
||||
static bool nlastrip_validate_transition_start_end(NlaStrip *strip)
|
||||
nrupsis marked this conversation as resolved
Sybren A. Stüvel
commented
I feel the return value now contradicts the name of the function, as I feel the return value now contradicts the name of the function, as `true` is returned when the strip could **not** be validated. I think returning `true` when valid-or-repaired and `false` when invalid-beyond-repair is better.
|
||||
{
|
||||
|
||||
if (!(strip->type & NLASTRIP_TYPE_TRANSITION)) {
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
if (strip->prev) {
|
||||
strip->start = strip->prev->end;
|
||||
|
@ -1969,9 +1969,9 @@ static bool nlastrip_validate_transition_start_end(NlaStrip *strip)
|
|||
}
|
||||
if (strip->start >= strip->end || strip->prev == NULL || strip->next == NULL) {
|
||||
BKE_nlastrip_free(strip, true);
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void BKE_nla_validate_state(AnimData *adt)
|
||||
|
@ -1988,10 +1988,10 @@ void BKE_nla_validate_state(AnimData *adt)
|
|||
for (nlt = adt->nla_tracks.first; nlt; nlt = nlt->next) {
|
||||
LISTBASE_FOREACH_MUTABLE (NlaStrip *, strip, &nlt->strips) {
|
||||
|
||||
if (nlastrip_validate_transition_start_end(strip)) {
|
||||
if (!nlastrip_validate_transition_start_end(strip)) {
|
||||
nrupsis marked this conversation as resolved
Outdated
Sybren A. Stüvel
commented
How about making it so that `nlastrip_validate_transition_start_end()` doesn't change the `strip` pointer variable, so the `if (strip == NULL)` check doesn't check for 'if the strip was freed'.
How about making it so that `nlastrip_validate_transition_start_end()` returns a boolean that indicates whether the strip was freed or not. Alternatively you could give it a `NlaStrip **strip` parameter so that it can modify the `strip` variable itself, but I'm not really a fan of those.
Nate Rupsis
commented
Would it make more sense to have a
Would it make more sense to have a `<=` condition in the for loop, and use the same `iter_max` variable for both conditional checks? I.e
```
short iter_max = 4;
for (short iter = 0; iter <= iter_max; iter++) {
...
if ((p_exceeded && n_exceeded) || (iter == iter_max)) {
...
```
Nate Rupsis
commented
I think the boolean return type is more expressive, and arguably more readable (with an informative comment on the function) I think the boolean return type is more expressive, and arguably more readable (with an informative comment on the function)
|
||||
printf(
|
||||
nrupsis marked this conversation as resolved
Outdated
Sybren A. Stüvel
commented
This can access memory after freeing it, crashing Blender. Better to let the caller know somehow whether A similar issue occurs in the This can access memory after freeing it, crashing Blender. Better to let the caller know somehow whether `nlastrip_validate_start_end()` freed the strip.
A similar issue occurs in the `for`-loop with `strip = strip->next`. You'll probably want to replace the loop with a call to `LISTBASE_FOREACH_MUTABLE()`. That'll determine the `next` pointer before entering the loop body.
|
||||
"While moving NLA strips, a transition strip could no longer be applied to the new "
|
||||
nrupsis marked this conversation as resolved
Outdated
Sybren A. Stüvel
commented
Such a warning is a good idea. It can be more specific, though, because we know it's an transition strip, so do mention that. Maybe also turn the message more positive, like "While moving NLA strips, a transition strip could no longer be applied to the new positions and was removed." It would be better to have this as a warning in the UI though, and not just printed on the terminal. That would require some more work that's not necessarily related to this PR, though. Such a warning is a good idea. It can be more specific, though, because we know it's an transition strip, so do mention that. Maybe also turn the message more positive, like "While moving NLA strips, a transition strip could no longer be applied to the new positions and was removed."
It would be better to have this as a warning in the UI though, and not just printed on the terminal. That would require some more work that's not necessarily related to this PR, though.
|
||||
"positions and was removed. \n");
|
||||
"positions and was removed.\n");
|
||||
nrupsis marked this conversation as resolved
Outdated
Sybren A. Stüvel
commented
Remove space before newline. Remove space before newline.
|
||||
continue;
|
||||
nrupsis marked this conversation as resolved
Outdated
Sybren A. Stüvel
commented
Why return? Shouldn't the remaining strips be checked too? Why return? Shouldn't the remaining strips be checked too?
Nate Rupsis
commented
oop, nope that was a dumb mistake on my part. Should be a continue. oop, nope that was a dumb mistake on my part. Should be a continue.
|
||||
}
|
||||
|
||||
|
|
|
@ -204,7 +204,7 @@ static void nlastrip_fix_overlapping(TransInfo *t, TransDataNla *tdn, NlaStrip *
|
|||
*
|
||||
* this is done as a iterative procedure (done 5 times max for now)
|
||||
nrupsis marked this conversation as resolved
Sybren A. Stüvel
commented
Well, with the Well, with the `for`-loop as it is now, it's done 6 times.
|
||||
*/
|
||||
short iter_max = 5;
|
||||
short iter_max = 4;
|
||||
NlaStrip *prev = BKE_nlastrip_prev_in_track(strip, true);
|
||||
NlaStrip *next = BKE_nlastrip_next_in_track(strip, true);
|
||||
|
||||
|
@ -214,7 +214,7 @@ static void nlastrip_fix_overlapping(TransInfo *t, TransDataNla *tdn, NlaStrip *
|
|||
const bool p_exceeded = (prev != NULL) && (tdn->h1[0] < prev->end);
|
||||
const bool n_exceeded = (next != NULL) && (tdn->h2[0] > next->start);
|
||||
|
||||
if ((p_exceeded && n_exceeded) || (iter == 4)) {
|
||||
if ((p_exceeded && n_exceeded) || (iter == iter_max)) {
|
||||
nrupsis marked this conversation as resolved
Outdated
Sybren A. Stüvel
commented
Replace Replace `iter == 4` with `iter == iter_max`
|
||||
/* both endpoints exceeded (or iteration ping-pong'd meaning that we need a
|
||||
* compromise)
|
||||
* - Simply crop strip to fit within the bounds of the strips bounding it
|
||||
|
|
Document that this can even remove and free
strip
when it doesn't fit any more.