[Bf-blender-cvs] [09709a7e64f] master: Nla Refactor: Split animsys_evaluate_nla()

Wayde Moss noreply at git.blender.org
Fri Jan 15 00:26:13 CET 2021


Commit: 09709a7e64ff0b225e16f97926b54c6441d94499
Author: Wayde Moss
Date:   Thu Jan 14 18:25:01 2021 -0500
Branches: master
https://developer.blender.org/rB09709a7e64ff0b225e16f97926b54c6441d94499

Nla Refactor: Split animsys_evaluate_nla()

No intended functional changes.

Refactors animsys_evaluate_nla() into 2 versions:
animsys_evaluate_nla_for_keyframing(), animsys_evaluate_nla_for_flush()
to make it clear what data is being calculated and why.

Dummy strip creation has been refactored to two separate functions,
animsys_create_tweak_strip() and animsys_create_action_track_strip().
Both are evaluated differently from other strips and eachother. There's
no need to interweave them. A future patch D8296, generally requires
both strips.

___

XXX anim_sys.c) nlatrack_find_tweaked() is a temporary work around.
If anyone has any insight into this problem, help is appreciated.

Reviewed by: sybren

Differential Revision: http://developer.blender.org/D9696

===================================================================

M	source/blender/blenkernel/BKE_animsys.h
M	source/blender/blenkernel/intern/anim_sys.c
M	source/blender/editors/animation/anim_channels_defines.c
M	source/blender/editors/animation/keyframing.c

===================================================================

diff --git a/source/blender/blenkernel/BKE_animsys.h b/source/blender/blenkernel/BKE_animsys.h
index 8d904bd6019..2fce4bfc5b8 100644
--- a/source/blender/blenkernel/BKE_animsys.h
+++ b/source/blender/blenkernel/BKE_animsys.h
@@ -212,8 +212,7 @@ struct NlaKeyframingContext *BKE_animsys_get_nla_keyframing_context(
     struct ListBase *cache,
     struct PointerRNA *ptr,
     struct AnimData *adt,
-    const struct AnimationEvalContext *anim_eval_context,
-    const bool flush_to_original);
+    const struct AnimationEvalContext *anim_eval_context);
 bool BKE_animsys_nla_remap_keyframe_values(struct NlaKeyframingContext *context,
                                            struct PointerRNA *prop_ptr,
                                            struct PropertyRNA *prop,
diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c
index 20956d6eb18..c8a4a125693 100644
--- a/source/blender/blenkernel/intern/anim_sys.c
+++ b/source/blender/blenkernel/intern/anim_sys.c
@@ -979,6 +979,19 @@ NlaEvalStrip *nlastrips_ctime_get_strip(ListBase *list,
   return nes;
 }
 
+static NlaEvalStrip *nlastrips_ctime_get_strip_single(
+    ListBase *dst_list,
+    NlaStrip *single_strip,
+    const AnimationEvalContext *anim_eval_context,
+    const bool flush_to_original)
+{
+  ListBase single_tracks_list;
+  single_tracks_list.first = single_tracks_list.last = single_strip;
+
+  return nlastrips_ctime_get_strip(
+      dst_list, &single_tracks_list, -1, anim_eval_context, flush_to_original);
+}
+
 /* ---------------------- */
 
 /* Initialize a valid mask, allocating memory if necessary. */
@@ -2212,190 +2225,344 @@ static void animsys_evaluate_nla_domain(PointerRNA *ptr, NlaEvalData *channels,
 
 /* ---------------------- */
 
+/** Tweaked strip is evaluated differently from other strips. Adjacent strips are ignored
+ * and includes a workaround for when user is not editing in place. */
+static void animsys_create_tweak_strip(const AnimData *adt,
+                                       const bool keyframing_to_strip,
+                                       NlaStrip *r_tweak_strip)
+
+{
+  /* Copy active strip so we can modify how it evaluates without affecting user data. */
+  memcpy(r_tweak_strip, adt->actstrip, sizeof(NlaStrip));
+  r_tweak_strip->next = r_tweak_strip->prev = NULL;
+
+  /* If tweaked strip is syncing action length, then evaluate using action length. */
+  if (r_tweak_strip->flag & NLASTRIP_FLAG_SYNC_LENGTH) {
+    BKE_nlastrip_recalculate_bounds_sync_action(r_tweak_strip);
+  }
+
+  /* Strips with a user-defined time curve don't get properly remapped for editing
+   * at the moment, so mapping them just for display may be confusing. */
+  const bool is_inplace_tweak = !(adt->flag & ADT_NLA_EDIT_NOMAP) &&
+                                !(adt->actstrip->flag & NLASTRIP_FLAG_USR_TIME);
+
+  if (!is_inplace_tweak) {
+    /* Use Hold due to no proper remapping yet (the note above). */
+    r_tweak_strip->extendmode = NLASTRIP_EXTEND_HOLD;
+
+    /* Disable range. */
+    r_tweak_strip->flag |= NLASTRIP_FLAG_NO_TIME_MAP;
+  }
+
+  /** Controls whether able to keyframe outside range of tweaked strip. */
+  if (keyframing_to_strip) {
+    r_tweak_strip->extendmode = (is_inplace_tweak &&
+                                 !(r_tweak_strip->flag & NLASTRIP_FLAG_SYNC_LENGTH)) ?
+                                    NLASTRIP_EXTEND_NOTHING :
+                                    NLASTRIP_EXTEND_HOLD;
+  }
+}
+
+/** Action track and strip are associated with the non-pushed action. */
+static void animsys_create_action_track_strip(const AnimData *adt,
+                                              const bool keyframing_to_strip,
+                                              NlaStrip *r_action_strip)
+{
+  memset(r_action_strip, 0, sizeof(NlaStrip));
+
+  bAction *action = adt->action;
+
+  if ((adt->flag & ADT_NLA_EDIT_ON)) {
+    action = adt->tmpact;
+  }
+
+  /* Set settings of dummy NLA strip from AnimData settings. */
+  r_action_strip->act = action;
+
+  /* Action range is calculated taking F-Modifiers into account
+   * (which making new strips doesn't do due to the troublesome nature of that). */
+  calc_action_range(r_action_strip->act, &r_action_strip->actstart, &r_action_strip->actend, 1);
+  r_action_strip->start = r_action_strip->actstart;
+  r_action_strip->end = (IS_EQF(r_action_strip->actstart, r_action_strip->actend)) ?
+                            (r_action_strip->actstart + 1.0f) :
+                            (r_action_strip->actend);
+
+  r_action_strip->blendmode = adt->act_blendmode;
+  r_action_strip->extendmode = adt->act_extendmode;
+  r_action_strip->influence = adt->act_influence;
+
+  /* NOTE: must set this, or else the default setting overrides,
+   * and this setting doesn't work. */
+  r_action_strip->flag |= NLASTRIP_FLAG_USR_INFLUENCE;
+
+  /* Unless extendmode is Nothing (might be useful for flattening NLA evaluation), disable range.
+   * Extendmode Nothing and Hold will behave as normal. Hold Forward will behave just like Hold.
+   */
+  if (r_action_strip->extendmode != NLASTRIP_EXTEND_NOTHING) {
+    r_action_strip->flag |= NLASTRIP_FLAG_NO_TIME_MAP;
+  }
+
+  const bool tweaking = (adt->flag & ADT_NLA_EDIT_ON) != 0;
+  const bool soloing = (adt->flag & ADT_NLA_SOLO_TRACK) != 0;
+  const bool actionstrip_evaluated = r_action_strip->act && !soloing && !tweaking;
+  if (!actionstrip_evaluated) {
+    r_action_strip->flag |= NLASTRIP_FLAG_MUTED;
+  }
+
+  /** If we're keyframing, then we must allow keyframing outside fcurve bounds. */
+  if (keyframing_to_strip) {
+    r_action_strip->extendmode = NLASTRIP_EXTEND_HOLD;
+  }
+}
+
+static bool is_nlatrack_evaluatable(const AnimData *adt, const NlaTrack *nlt)
+{
+  /* Skip disabled tracks unless it contains the tweaked strip. */
+  const bool contains_tweak_strip = (adt->flag & ADT_NLA_EDIT_ON) &&
+                                    (nlt->index == adt->act_track->index);
+  if ((nlt->flag & NLATRACK_DISABLED) && !contains_tweak_strip) {
+    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;
+}
+
+/** Check for special case of non-pushed action being evaluated with no NLA influence (off and no
+ * strips evaluated) nor NLA interference (ensure NLA not soloing). */
+static bool is_action_track_evaluated_without_nla(const AnimData *adt,
+                                                  const bool any_strip_evaluated)
+{
+  if (adt->action == NULL) {
+    return false;
+  }
+
+  if (any_strip_evaluated) {
+    return false;
+  }
+
+  /** NLA settings interference. */
+  if ((adt->flag & (ADT_NLA_SOLO_TRACK | ADT_NLA_EDIT_ON)) == 0) {
+    return false;
+  }
+
+  /** Allow action track to evaluate as if there isn't any NLA data. */
+  return true;
+}
+
+/** XXX Wayde Moss: BKE_nlatrack_find_tweaked() exists within nla.c, but it doesn't appear to
+ * work as expected. From animsys_evaluate_nla_for_flush(), it returns NULL in tweak mode. I'm not
+ * sure why. Preferably, it would be as simple as checking for (adt->act_Track == nlt) but that
+ * doesn't work either, neither does comparing indices.
+ *
+ *  This function is a temporary work around. The first disabled track is always the tweaked track.
+ */
+static NlaTrack *nlatrack_find_tweaked(const AnimData *adt)
+{
+  NlaTrack *nlt;
+
+  if (adt == NULL) {
+    return NULL;
+  }
+
+  /* Since the track itself gets disabled, we want the first disabled. */
+  for (nlt = adt->nla_tracks.first; nlt; nlt = nlt->next) {
+    if (nlt->flag & NLATRACK_DISABLED) {
+      return nlt;
+    }
+  }
+
+  return NULL;
+}
+
 /**
  * NLA Evaluation function - values are calculated and stored in temporary "NlaEvalChannels"
- *
  * \param[out] echannels: Evaluation channels with calculated values
- * \param[out] r_context: If not NULL,
- * data about the currently edited strip is stored here and excluded from value calculation.
- * \return false if NLA evaluation isn't actually applicable.
  */
-static bool animsys_evaluate_nla(NlaEvalData *echannels,
-                                 PointerRNA *ptr,
-                                 AnimData *adt,
-                                 const AnimationEvalContext *anim_eval_context,
-                                 const bool flush_to_original,
-                                 NlaKeyframingContext *r_context)
+static bool animsys_evaluate_nla_for_flush(NlaEvalData *echannels,
+                                           PointerRNA *ptr,
+                                           const AnimData *adt,
+                                           const AnimationEvalContext *anim_eval_context,
+                                           const bool flush_to_original)
 {
   NlaTrack *nlt;
   short track_index = 0;
   bool has_strips = false;
-
   ListBase estrips = {NULL, NULL};
   NlaEvalStrip *nes;
-  NlaStrip dummy_strip_buf;
 
-  /* dummy strip for active action */
-  NlaStrip *dummy_strip = r_context ? &r_context->strip : &dummy_strip_buf;
+  NlaStrip tweak_strip;
 
-  memset(dummy_strip, 0, sizeof(*dummy_strip));
+  NlaTrack *tweaked_track = nlatrack_find_tweaked(adt);
 
-  /* 1. get the stack of strips to evaluate at current time (influence calculated here) */
+  /* Get the stack of strips to evaluate at current time (influence calculated here). */
   for (nlt = adt->nla_tracks.first; nlt; nlt = nlt->next, track_index++) {
-    /* stop here if tweaking is on and this strip is the tweaking track
-     * (it will be the first one that's 'disabled')... */
-    if ((adt->flag & ADT_NLA_EDIT_ON) && (nlt->flag & NLATRACK_DISABLED)) {
-      break;
+
+    if (!is_nlatrack_evaluatable(adt, nlt)) {
+      continue;
     }
 
-    /* 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

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list