[Bf-blender-cvs] [2d0117ff459] temp_D10504_nla_keyframe_remap_upper_strips: NLA: Keyframe Remap Through Upper Strips

Wayde Moss noreply at git.blender.org
Mon Feb 22 22:19:01 CET 2021


Commit: 2d0117ff45945e286e833dd2332efedb999da86d
Author: Wayde Moss
Date:   Wed Feb 17 15:58:58 2021 -0500
Branches: temp_D10504_nla_keyframe_remap_upper_strips
https://developer.blender.org/rB2d0117ff45945e286e833dd2332efedb999da86d

NLA: Keyframe Remap Through Upper Strips

Differential Revision: https://developer.blender.org/D10504

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

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

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

diff --git a/source/blender/blenkernel/BKE_animsys.h b/source/blender/blenkernel/BKE_animsys.h
index 2fce4bfc5b8..3b40ec24a70 100644
--- a/source/blender/blenkernel/BKE_animsys.h
+++ b/source/blender/blenkernel/BKE_animsys.h
@@ -219,7 +219,8 @@ bool BKE_animsys_nla_remap_keyframe_values(struct NlaKeyframingContext *context,
                                            float *values,
                                            int count,
                                            int index,
-                                           bool *r_force_all);
+                                           bool *r_force_all,
+                                           const struct AnimationEvalContext *anim_eval_context);
 void BKE_animsys_free_nla_keyframing_context_cache(struct ListBase *cache);
 
 /* ************************************* */
diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c
index bdbffc2d733..5bfa5c1f828 100644
--- a/source/blender/blenkernel/intern/anim_sys.c
+++ b/source/blender/blenkernel/intern/anim_sys.c
@@ -1441,6 +1441,141 @@ static NlaEvalChannel *nlaevalchan_verify(PointerRNA *ptr, NlaEvalData *nlaeval,
 
 /* ---------------------- */
 
+/** \returns true if solution exists and output written to. */
+static bool nla_blend_get_inverted_lower_value(const int blendmode,
+                                               const float strip_value,
+                                               const float blended_value,
+                                               const float influence,
+                                               float *r_lower_value)
+{
+  if (IS_EQF(influence, 0.0f)) {
+    *r_lower_value = blended_value;
+    return true;
+  }
+
+  switch (blendmode) {
+    case NLASTRIP_MODE_ADD:
+      /* Simply subtract the scaled value on to the stack. */
+      *r_lower_value = blended_value - (strip_value * influence);
+      return true;
+
+    case NLASTRIP_MODE_SUBTRACT:
+      /* Simply add the scaled value from the stack. */
+      *r_lower_value = blended_value + (strip_value * influence);
+      return true;
+
+    case NLASTRIP_MODE_MULTIPLY:
+
+      /** Division by zero. */
+      if (IS_EQF(-strip_value * influence, 1.0f - influence)) {
+        /** Resolve 0/0 to 1. */
+        if (IS_EQF(blended_value, 0.0f)) {
+          *r_lower_value = 1;
+          return true;
+        }
+        /** Division by zero. */
+        return false;
+      }
+      /* Math:
+       *     blended_value = inf * (lower_value * strip_value) + (1 - inf) * lower_value
+       *                   = lower_value * (inf * strip_value + (1-inf))
+       *         lower_value = blended_value / (inf * strip_value + (1-inf))
+       */
+      *r_lower_value = blended_value / (influence * strip_value + (1.0f - influence));
+      return true;
+
+    case NLASTRIP_MODE_COMBINE:
+      BLI_assert(!"combine mode");
+      return false;
+
+    default:
+
+      /** No solution if lower strip has 0 influence. */
+      if (IS_EQF(influence, 1.0f)) {
+        return false;
+      }
+
+      /** Math:
+       *
+       *  blended_value = lower_value * (1.0f - inf) + (strip_value * inf)
+       *  blended_value - (strip_value * inf) = lower_value * (1.0f - inf)
+       *  blended_value - (strip_value * inf) / (1.0f - inf) = lower_value
+       *
+       *  lower_value = blended_value - (strip_value * inf) / (1.0f - inf)
+       */
+      *r_lower_value = (blended_value - (strip_value * influence)) / (1.0f - influence);
+      return true;
+  }
+}
+
+/** \returns true if solution exists and output written to. */
+static bool nla_combine_get_inverted_lower_value(const int mix_mode,
+                                                 float base_value,
+                                                 const float strip_value,
+                                                 const float blended_value,
+                                                 const float influence,
+                                                 float *r_lower_value)
+{
+  if (IS_EQF(influence, 0.0f)) {
+    *r_lower_value = blended_value;
+    return true;
+  }
+
+  /* Perform blending. */
+  switch (mix_mode) {
+    case NEC_MIX_ADD:
+    case NEC_MIX_AXIS_ANGLE:
+      *r_lower_value = blended_value - (strip_value - base_value) * influence;
+      return true;
+    case NEC_MIX_MULTIPLY:
+      /** Division by zero. */
+      if (IS_EQF(strip_value, 0.0f)) {
+        /** Resolve 0/0 to 1. */
+        if (IS_EQF(blended_value, 0.0f)) {
+          *r_lower_value = 1.0f;
+          return true;
+        }
+        return false;
+      }
+
+      if (IS_EQF(base_value, 0.0f)) {
+        base_value = 1.0f;
+      }
+
+      *r_lower_value = blended_value / powf(strip_value / base_value, influence);
+      return true;
+
+    default:
+      BLI_assert(!"invalid mix mode");
+      return false;
+  }
+}
+
+static void nla_combine_quaternion_get_inverted_lower_values(const float strip_values[4],
+                                                             const float blended_values[4],
+                                                             const float influence,
+                                                             float r_lower_value[4])
+{
+  if (IS_EQF(influence, 0.0f)) {
+    normalize_qt_qt(r_lower_value, blended_values);
+    return;
+  }
+
+  /* blended_value = lower_values @ strip_values^infl
+   * blended_value @ inv(strip_values^inf) = lower_values
+   *
+   * Returns: lower_values = blended_value @ inv(strip_values^inf) */
+  float tmp_strip_values[4], tmp_blended[4];
+
+  normalize_qt_qt(tmp_strip_values, strip_values);
+  normalize_qt_qt(tmp_blended, blended_values);
+
+  pow_qt_fl_normalized(tmp_strip_values, influence);
+  invert_qt_normalized(tmp_strip_values);
+
+  mul_qt_qtqt(r_lower_value, tmp_blended, tmp_strip_values);
+}
+
 /* Blend the lower nla stack value and upper strip value of a channel according to mode and
  * influence. */
 static float nla_blend_value(const int blendmode,
@@ -1775,7 +1910,8 @@ static void nlasnapshot_from_action(PointerRNA *ptr,
 }
 
 /* evaluate action-clip strip */
-static void nlastrip_evaluate_actionclip(PointerRNA *ptr,
+static void nlastrip_evaluate_actionclip(const int evaluation_mode,
+                                         PointerRNA *ptr,
                                          NlaEvalData *channels,
                                          ListBase *modifiers,
                                          NlaEvalStrip *nes,
@@ -1799,22 +1935,49 @@ static void nlastrip_evaluate_actionclip(PointerRNA *ptr,
   /* join this strip's modifiers to the parent's modifiers (own modifiers first) */
   nlaeval_fmodifiers_join_stacks(&tmp_modifiers, &strip->modifiers, modifiers);
 
-  NlaEvalSnapshot strip_snapshot;
-  nlaeval_snapshot_init(&strip_snapshot, channels, NULL);
+  switch (evaluation_mode) {
+    case STRIP_EVAL_BLEND: {
 
-  nlasnapshot_from_action(
-      ptr, channels, &tmp_modifiers, strip->act, strip->strip_time, &strip_snapshot);
-  nlasnapshot_blend(
-      channels, snapshot, &strip_snapshot, strip->blendmode, strip->influence, snapshot);
+      NlaEvalSnapshot strip_snapshot;
+      nlaeval_snapshot_init(&strip_snapshot, channels, NULL);
 
-  nlaeval_snapshot_free_data(&strip_snapshot);
+      nlasnapshot_from_action(
+          ptr, channels, &tmp_modifiers, strip->act, strip->strip_time, &strip_snapshot);
+      nlasnapshot_blend(
+          channels, snapshot, &strip_snapshot, strip->blendmode, strip->influence, snapshot);
+
+      nlaeval_snapshot_free_data(&strip_snapshot);
+
+      break;
+    }
+    case STRIP_EVAL_BLEND_GET_INVERTED_LOWER_SNAPSHOT: {
+
+      NlaEvalSnapshot strip_snapshot;
+      nlaeval_snapshot_init(&strip_snapshot, channels, NULL);
+
+      nlasnapshot_from_action(
+          ptr, channels, &tmp_modifiers, strip->act, strip->strip_time, &strip_snapshot);
+      nlasnapshot_blend_get_inverted_lower_snapshot(
+          channels, snapshot, &strip_snapshot, strip->blendmode, strip->influence, snapshot);
+
+      nlaeval_snapshot_free_data(&strip_snapshot);
+
+      break;
+    }
+    case STRIP_EVAL_NOBLEND: {
+      nlasnapshot_from_action(
+          ptr, channels, &tmp_modifiers, strip->act, strip->strip_time, snapshot);
+      break;
+    }
+  }
 
   /* unlink this strip's modifiers from the parent's modifiers again */
   nlaeval_fmodifiers_split_stacks(&strip->modifiers, modifiers);
 }
 
 /* evaluate transition strip */
-static void nlastrip_evaluate_transition(PointerRNA *ptr,
+static void nlastrip_evaluate_transition(const int evaluation_mode,
+                                         PointerRNA *ptr,
                                          NlaEvalData *channels,
                                          ListBase *modifiers,
                                          NlaEvalStrip *nes,
@@ -1846,49 +2009,128 @@ static void nlastrip_evaluate_transition(PointerRNA *ptr,
     s2 = nes->strip->next;
   }
 
-  /* prepare template for 'evaluation strip'
-   * - based on the transition strip's evaluation strip data
-   * - strip_mode is NES_TIME_TRANSITION_* based on which endpoint
-   * - strip_time is the 'normalized' (i.e. in-strip) time for evaluation,
-   *   which doubles up as an additional weighting factor for the strip influences
-   *   which allows us to appear to be 'interpolating' between the two extremes
-   */
-  tmp_nes = *nes;
-
-  /* evaluate these strips into a temp-buffer (tmp_channels) */
-  /* FIXME: modifier evaluation here needs some work... */
-  /* first strip */
-  tmp_nes.strip_mode = NES_TIME_TRANSITION_START;
-  tmp_nes.strip = s1;
-  tmp_nes.strip_time = s1->strip_time;
-  nlaeval_snapshot_init(&snapshot1, channels, snapshot);
-  nlastrip_evaluate(
-      ptr, channels, &tmp_modifiers, &tmp_nes, &snapshot1, anim_eval_context, flush_to_original);
+  switch (evaluation_mode) {
+    case STRIP_EVAL_BLEND: {
 
-  /* second strip */
-  tmp_nes.strip_mode = NES_TIME_TRANSITION_END;
-  tmp_nes.strip = s2;
-  tmp_nes.strip_time = s2->strip_time;
-  nlaeval_snapshot_init(&snapshot2, channels, snapshot);
-  nlastrip_evaluate(
-      ptr, channels, &tmp_modifiers, &tmp_nes, &snapshot2, anim_eval_conte

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list