Fix: NLA Track Solo flag handling, in depsgraph and F-Curve iteration

This fixes the (unreported) issue where solo'ing an NLA track would only
play back animation when _any_ of the tracks were unmuted.

Some code considered a track to be muted when its `NLATRACK_MUTED` flag
was set regardless of the `NLATRACK_SOLO` flag, whereas other code did
consider the `NLATRACK_SOLO` flag.

Now all the code is consistent with what actual animation evaluation is
doing.

Pull Request: https://projects.blender.org/blender/blender/pulls/134500
This commit is contained in:
Sybren A. Stüvel
2025-02-14 13:55:44 +01:00
parent 79627e353d
commit 62c21a0800
6 changed files with 25 additions and 32 deletions

View File

@@ -141,6 +141,14 @@ void BKE_nlatrack_remove(ListBase *tracks, NlaTrack *nlt);
*/
void BKE_nlatrack_remove_and_free(ListBase *tracks, NlaTrack *nlt, bool do_id_user);
/**
* Return whether this NLA track is enabled.
*
* If any track is solo'ed: returns true when this is the solo'ed one.
* If no track is solo'ed: returns true when this track is not muted.
*/
bool BKE_nlatrack_is_enabled(const AnimData &adt, const NlaTrack &nlt);
/**
* Compute the length of the passed strip's clip, unless the clip length
* is zero in which case a non-zero value is returned.

View File

@@ -1272,7 +1272,7 @@ static void adt_apply_all_fcurves_cb(ID *id,
/* NLA Data - Animation Data for Strips */
LISTBASE_FOREACH (NlaTrack *, nlt, &adt->nla_tracks) {
if (nlt->flag & NLATRACK_MUTED) {
if (!BKE_nlatrack_is_enabled(*adt, *nlt)) {
continue;
}
nlastrips_apply_all_curves_cb(id, &nlt->strips, func);

View File

@@ -3200,21 +3200,9 @@ static void animsys_evaluate_nla_domain(PointerRNA *ptr, NlaEvalData *channels,
/* NLA Data - Animation Data for Strips */
LISTBASE_FOREACH (NlaTrack *, nlt, &adt->nla_tracks) {
/* solo and muting are mutually exclusive... */
if (adt->flag & ADT_NLA_SOLO_TRACK) {
/* skip if there is a solo track, but this isn't it */
if ((nlt->flag & NLATRACK_SOLO) == 0) {
continue;
}
/* else - mute doesn't matter */
if (!BKE_nlatrack_is_enabled(*adt, *nlt)) {
continue;
}
else {
/* no solo tracks - skip track if muted */
if (nlt->flag & NLATRACK_MUTED) {
continue;
}
}
nla_eval_domain_strips(ptr, channels, &nlt->strips, touched_actions);
}
@@ -3325,21 +3313,7 @@ static bool is_nlatrack_evaluatable(const AnimData *adt, const NlaTrack *nlt)
return false;
}
/* Solo and muting are mutually exclusive. */
if (adt->flag & ADT_NLA_SOLO_TRACK) {
/* Skip if there is a solo track, but this isn't it. */
if ((nlt->flag & NLATRACK_SOLO) == 0) {
return false;
}
}
else {
/* Skip track if muted. */
if (nlt->flag & NLATRACK_MUTED) {
return false;
}
}
return true;
return BKE_nlatrack_is_enabled(*adt, *nlt);
}
/**

View File

@@ -667,6 +667,15 @@ void BKE_nlatrack_remove_and_free(ListBase *tracks, NlaTrack *nlt, bool do_id_us
BKE_nlatrack_free(nlt, do_id_user);
}
bool BKE_nlatrack_is_enabled(const AnimData &adt, const NlaTrack &nlt)
{
if (adt.flag & ADT_NLA_SOLO_TRACK) {
return (nlt.flag & NLATRACK_SOLO);
}
return !(nlt.flag & NLATRACK_MUTED);
}
/* *************************************************** */
/* NLA Evaluation <-> Editing Stuff */

View File

@@ -77,6 +77,7 @@
#include "BKE_mesh.hh"
#include "BKE_modifier.hh"
#include "BKE_movieclip.h"
#include "BKE_nla.hh"
#include "BKE_node.hh"
#include "BKE_node_runtime.hh"
#include "BKE_object.hh"
@@ -1253,7 +1254,7 @@ void DepsgraphNodeBuilder::build_animdata(ID *id)
}
/* NLA strips contain actions. */
LISTBASE_FOREACH (NlaTrack *, nlt, &adt->nla_tracks) {
if (nlt->flag & NLATRACK_MUTED) {
if (!BKE_nlatrack_is_enabled(*adt, *nlt)) {
continue;
}
build_animdata_nlastrip_targets(&nlt->strips);

View File

@@ -75,6 +75,7 @@
#include "BKE_material.hh"
#include "BKE_mball.hh"
#include "BKE_modifier.hh"
#include "BKE_nla.hh"
#include "BKE_node.hh"
#include "BKE_node_runtime.hh"
#include "BKE_object.hh"
@@ -1616,7 +1617,7 @@ void DepsgraphRelationBuilder::build_animdata_curves(ID *id)
build_animdata_action_targets(id, adt->slot_handle, adt_key, operation_from, adt->action);
}
LISTBASE_FOREACH (NlaTrack *, nlt, &adt->nla_tracks) {
if (nlt->flag & NLATRACK_MUTED) {
if (!BKE_nlatrack_is_enabled(*adt, *nlt)) {
continue;
}
build_animdata_nlastrip_targets(id, adt_key, operation_from, &nlt->strips);