[Bf-blender-cvs] [5b6ee803516] master: Cleanup: Animation, split FCurve interpolation into separate function

Sybren A. Stüvel noreply at git.blender.org
Fri May 1 18:10:13 CEST 2020


Commit: 5b6ee803516a2ccb9f43e4d6ee0b6f77c22745cc
Author: Sybren A. Stüvel
Date:   Fri May 1 15:49:59 2020 +0200
Branches: master
https://developer.blender.org/rB5b6ee803516a2ccb9f43e4d6ee0b6f77c22745cc

Cleanup: Animation, split FCurve interpolation into separate function

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

M	source/blender/blenkernel/intern/fcurve.c

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

diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c
index 2506c937dc5..8f2726b147a 100644
--- a/source/blender/blenkernel/intern/fcurve.c
+++ b/source/blender/blenkernel/intern/fcurve.c
@@ -1462,11 +1462,10 @@ static float fcurve_eval_keyframes_extrapolate(
   return endpoint_bezt->vec[1][1] - (fac * dx);
 }
 
-/* Calculate F-Curve value for 'evaltime' using BezTriple keyframes */
-static float fcurve_eval_keyframes(FCurve *fcu, BezTriple *bezts, float evaltime)
+static float fcurve_eval_keyframes_interpolate(FCurve *fcu, BezTriple *bezts, float evaltime)
 {
   const float eps = 1.e-8f;
-  BezTriple *bezt, *prevbezt, *lastbezt;
+  BezTriple *bezt, *prevbezt;
   float v1[2], v2[2], v3[2], v4[2], opl[32];
   unsigned int a;
   int b;
@@ -1476,329 +1475,332 @@ static float fcurve_eval_keyframes(FCurve *fcu, BezTriple *bezts, float evaltime
   a = fcu->totvert - 1;
   prevbezt = bezts;
   bezt = prevbezt + 1;
-  lastbezt = prevbezt + a;
 
-  /* evaluation time at or past endpoints? */
-  if (prevbezt->vec[1][0] >= evaltime) {
-    cvalue = fcurve_eval_keyframes_extrapolate(fcu, bezts, evaltime, 0, +1);
-  }
-  else if (lastbezt->vec[1][0] <= evaltime) {
-    cvalue = fcurve_eval_keyframes_extrapolate(fcu, bezts, evaltime, fcu->totvert - 1, -1);
+  /* evaltime occurs somewhere in the middle of the curve */
+  bool exact = false;
+
+  /* Use binary search to find appropriate keyframes...
+   *
+   * The threshold here has the following constraints:
+   * - 0.001 is too coarse:
+   *   We get artifacts with 2cm driver movements at 1BU = 1m (see T40332)
+   *
+   * - 0.00001 is too fine:
+   *   Weird errors, like selecting the wrong keyframe range (see T39207), occur.
+   *   This lower bound was established in b888a32eee8147b028464336ad2404d8155c64dd.
+   */
+  a = binarysearch_bezt_index_ex(bezts, evaltime, fcu->totvert, 0.0001, &exact);
+
+  if (exact) {
+    /* index returned must be interpreted differently when it sits on top of an existing keyframe
+     * - that keyframe is the start of the segment we need (see action_bug_2.blend in T39207)
+     */
+    prevbezt = bezts + a;
+    bezt = (a < fcu->totvert - 1) ? (prevbezt + 1) : prevbezt;
   }
   else {
-    /* evaltime occurs somewhere in the middle of the curve */
-    bool exact = false;
-
-    /* Use binary search to find appropriate keyframes...
-     *
-     * The threshold here has the following constraints:
-     * - 0.001 is too coarse:
-     *   We get artifacts with 2cm driver movements at 1BU = 1m (see T40332)
-     *
-     * - 0.00001 is too fine:
-     *   Weird errors, like selecting the wrong keyframe range (see T39207), occur.
-     *   This lower bound was established in b888a32eee8147b028464336ad2404d8155c64dd.
+    /* index returned refers to the keyframe that the eval-time occurs *before*
+     * - hence, that keyframe marks the start of the segment we're dealing with
      */
-    a = binarysearch_bezt_index_ex(bezts, evaltime, fcu->totvert, 0.0001, &exact);
-
-    if (exact) {
-      /* index returned must be interpreted differently when it sits on top of an existing keyframe
-       * - that keyframe is the start of the segment we need (see action_bug_2.blend in T39207)
-       */
-      prevbezt = bezts + a;
-      bezt = (a < fcu->totvert - 1) ? (prevbezt + 1) : prevbezt;
-    }
-    else {
-      /* index returned refers to the keyframe that the eval-time occurs *before*
-       * - hence, that keyframe marks the start of the segment we're dealing with
-       */
-      bezt = bezts + a;
-      prevbezt = (a > 0) ? (bezt - 1) : bezt;
-    }
-
-    /* use if the key is directly on the frame,
-     * rare cases this is needed else we get 0.0 instead. */
-    /* XXX: consult T39207 for examples of files where failure of these checks can cause issues */
-    if (exact) {
+    bezt = bezts + a;
+    prevbezt = (a > 0) ? (bezt - 1) : bezt;
+  }
+
+  /* use if the key is directly on the frame,
+   * rare cases this is needed else we get 0.0 instead. */
+  /* XXX: consult T39207 for examples of files where failure of these checks can cause issues */
+  if (exact) {
+    cvalue = prevbezt->vec[1][1];
+  }
+  else if (fabsf(bezt->vec[1][0] - evaltime) < eps) {
+    cvalue = bezt->vec[1][1];
+  }
+  /* evaltime occurs within the interval defined by these two keyframes */
+  else if ((prevbezt->vec[1][0] <= evaltime) && (bezt->vec[1][0] >= evaltime)) {
+    const float begin = prevbezt->vec[1][1];
+    const float change = bezt->vec[1][1] - prevbezt->vec[1][1];
+    const float duration = bezt->vec[1][0] - prevbezt->vec[1][0];
+    const float time = evaltime - prevbezt->vec[1][0];
+    const float amplitude = prevbezt->amplitude;
+    const float period = prevbezt->period;
+
+    /* value depends on interpolation mode */
+    if ((prevbezt->ipo == BEZT_IPO_CONST) || (fcu->flag & FCURVE_DISCRETE_VALUES) ||
+        (duration == 0)) {
+      /* constant (evaltime not relevant, so no interpolation needed) */
       cvalue = prevbezt->vec[1][1];
     }
-    else if (fabsf(bezt->vec[1][0] - evaltime) < eps) {
-      cvalue = bezt->vec[1][1];
-    }
-    /* evaltime occurs within the interval defined by these two keyframes */
-    else if ((prevbezt->vec[1][0] <= evaltime) && (bezt->vec[1][0] >= evaltime)) {
-      const float begin = prevbezt->vec[1][1];
-      const float change = bezt->vec[1][1] - prevbezt->vec[1][1];
-      const float duration = bezt->vec[1][0] - prevbezt->vec[1][0];
-      const float time = evaltime - prevbezt->vec[1][0];
-      const float amplitude = prevbezt->amplitude;
-      const float period = prevbezt->period;
-
-      /* value depends on interpolation mode */
-      if ((prevbezt->ipo == BEZT_IPO_CONST) || (fcu->flag & FCURVE_DISCRETE_VALUES) ||
-          (duration == 0)) {
-        /* constant (evaltime not relevant, so no interpolation needed) */
-        cvalue = prevbezt->vec[1][1];
-      }
-      else {
-        switch (prevbezt->ipo) {
-          /* interpolation ...................................... */
-          case BEZT_IPO_BEZ:
-            /* bezier interpolation */
-            /* (v1, v2) are the first keyframe and its 2nd handle */
-            v1[0] = prevbezt->vec[1][0];
-            v1[1] = prevbezt->vec[1][1];
-            v2[0] = prevbezt->vec[2][0];
-            v2[1] = prevbezt->vec[2][1];
-            /* (v3, v4) are the last keyframe's 1st handle + the last keyframe */
-            v3[0] = bezt->vec[0][0];
-            v3[1] = bezt->vec[0][1];
-            v4[0] = bezt->vec[1][0];
-            v4[1] = bezt->vec[1][1];
-
-            if (fabsf(v1[1] - v4[1]) < FLT_EPSILON && fabsf(v2[1] - v3[1]) < FLT_EPSILON &&
-                fabsf(v3[1] - v4[1]) < FLT_EPSILON) {
-              /* Optimization: If all the handles are flat/at the same values,
-               * the value is simply the shared value (see T40372 -> F91346)
-               */
-              cvalue = v1[1];
+    else {
+      switch (prevbezt->ipo) {
+        /* interpolation ...................................... */
+        case BEZT_IPO_BEZ:
+          /* bezier interpolation */
+          /* (v1, v2) are the first keyframe and its 2nd handle */
+          v1[0] = prevbezt->vec[1][0];
+          v1[1] = prevbezt->vec[1][1];
+          v2[0] = prevbezt->vec[2][0];
+          v2[1] = prevbezt->vec[2][1];
+          /* (v3, v4) are the last keyframe's 1st handle + the last keyframe */
+          v3[0] = bezt->vec[0][0];
+          v3[1] = bezt->vec[0][1];
+          v4[0] = bezt->vec[1][0];
+          v4[1] = bezt->vec[1][1];
+
+          if (fabsf(v1[1] - v4[1]) < FLT_EPSILON && fabsf(v2[1] - v3[1]) < FLT_EPSILON &&
+              fabsf(v3[1] - v4[1]) < FLT_EPSILON) {
+            /* Optimization: If all the handles are flat/at the same values,
+             * the value is simply the shared value (see T40372 -> F91346)
+             */
+            cvalue = v1[1];
+          }
+          else {
+            /* adjust handles so that they don't overlap (forming a loop) */
+            correct_bezpart(v1, v2, v3, v4);
+
+            /* try to get a value for this position - if failure, try another set of points */
+            b = findzero(evaltime, v1[0], v2[0], v3[0], v4[0], opl);
+            if (b) {
+              berekeny(v1[1], v2[1], v3[1], v4[1], opl, 1);
+              cvalue = opl[0];
+              /* break; */
             }
             else {
-              /* adjust handles so that they don't overlap (forming a loop) */
-              correct_bezpart(v1, v2, v3, v4);
-
-              /* try to get a value for this position - if failure, try another set of points */
-              b = findzero(evaltime, v1[0], v2[0], v3[0], v4[0], opl);
-              if (b) {
-                berekeny(v1[1], v2[1], v3[1], v4[1], opl, 1);
-                cvalue = opl[0];
-                /* break; */
+              if (G.debug & G_DEBUG) {
+                printf("    ERROR: findzero() failed at %f with %f %f %f %f\n",
+                       evaltime,
+                       v1[0],
+                       v2[0],
+                       v3[0],
+                       v4[0]);
               }
-              else {
-                if (G.debug & G_DEBUG) {
-                  printf("    ERROR: findzero() failed at %f with %f %f %f %f\n",
-                         evaltime,
-                         v1[0],
-                         v2[0],
-                         v3[0],
-                         v4[0]);
-                }
-              }
-            }
-            break;
-
-          case BEZT_IPO_LIN:
-            /* linear - simply linearly interpolate between values of the two keyframes */
-            cvalue = BLI_easing_linear_ease(time, begin, change, duration);
-            break;
-
-          /* easing ............................................ */
-          case BEZT_IPO_BACK:
-            switch (prevbezt->easing) {
-              case BEZT_IPO_EASE_IN:
-                cvalue = BLI_easing_back_ease_in(time, begin, change, duration, prevbezt->back);
-                break;
-              case BEZT_IPO_EASE_OUT:
-                cvalue = BLI_easing_back_ease_out(time, begin, change, duration, prevbezt->back);

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list