[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