[Bf-blender-cvs] [2f0189964ad] temp-sybren-anim-cleanup: Cleanup: Animation, simplified fcurve_eval_between_keyframes() code

Sybren A. Stüvel noreply at git.blender.org
Fri Feb 7 17:52:01 CET 2020


Commit: 2f0189964ad5a4ae7cb819233c753df51a4b1508
Author: Sybren A. Stüvel
Date:   Fri Feb 7 17:29:30 2020 +0100
Branches: temp-sybren-anim-cleanup
https://developer.blender.org/rB2f0189964ad5a4ae7cb819233c753df51a4b1508

Cleanup: Animation, simplified fcurve_eval_between_keyframes() code

The function now immediately returns the evaluated value, rather than
setting a variable's value and returning that at the end of the
function. As a result, `else`-clauses and `break` statements could be
removed, simplifying and unindenting the code.

Declarations of some variables that are only used in a specific part of
the function have been moved there to clarify and limit their scope.

No functional changes.

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

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

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

diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c
index 41edba040c6..4c5644c130b 100644
--- a/source/blender/blenkernel/intern/fcurve.c
+++ b/source/blender/blenkernel/intern/fcurve.c
@@ -2786,13 +2786,9 @@ static float fcurve_eval_between_keyframes(const FCurve *fcu,
                                            BezTriple *bezts,
                                            const float evaltime)
 {
-  float cvalue = 0.0f;
-
-  const float eps = 1.e-8f;
-  float v1[2], v2[2], v3[2], v4[2], opl[32];
-  unsigned int a;
-  int b;
-  bool exact = false;
+  unsigned int bezt_index;
+  BezTriple *prevbezt;
+  BezTriple *bezt;
 
   /* Use binary search to find appropriate keyframes...
    *
@@ -2804,304 +2800,227 @@ static float fcurve_eval_between_keyframes(const FCurve *fcu,
    *   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);
-
-  BezTriple *prevbezt;
-  BezTriple *bezt;
-
+  bool exact = false;
+  bezt_index = 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;
+    bezt = bezts + bezt_index;
+    return bezt->vec[1][1];
   }
 
-  /* 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];
+  /* 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 + bezt_index;
+  prevbezt = (bezt_index > 0) ? (bezt - 1) : bezt;
+
+  /* TODO(Sybren): remove the below code, as in this case the binary search has
+   * already marked the result as an exact match. */
+  const float eps = 1.e-8f;
+  if (fabsf(bezt->vec[1][0] - evaltime) < eps) {
+    return 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];
+  /* evaltime should occur within the interval defined by these two keyframes. */
+  if (evaltime < prevbezt->vec[1][0] || bezt->vec[1][0] < evaltime) {
+    if (G.debug & G_DEBUG) {
+      printf("   ERROR: failed eval - p=%f b=%f, t=%f (%f)\n",
+             prevbezt->vec[1][0],
+             bezt->vec[1][0],
+             evaltime,
+             fabsf(bezt->vec[1][0] - evaltime));
     }
-    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 {
-              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;
+    return 0.0f;
+  }
 
-        case BEZT_IPO_LIN:
-          /* linear - simply linearly interpolate between values of the two keyframes */
-          cvalue = BLI_easing_linear_ease(time, begin, change, duration);
-          break;
+  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) */
+    return prevbezt->vec[1][1];
+  }
+
+  /* interpolation ...................................... */
+  switch (prevbezt->ipo) {
+    case BEZT_IPO_BEZ: {
+      float v1[2], v2[2], v3[2], v4[2], opl[32];
+
+      /* 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)
+         */
+        return v1[1];
+      }
 
-        /* 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);
-              break;
-            case BEZT_IPO_EASE_IN_OUT:
-              cvalue = BLI_easing_back_ease_in_out(time, begin, change, duration, prevbezt->back);
-              break;
-
-            default: /* default/auto: same as ease out */
-              cvalue = BLI_easing_back_ease_out(time, begin, change, duration, prevbezt->back);
-              break;
-          }
-          break;
+      /* 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 */
+      int b = findzero(evaltime, v1[0], v2[0], v3[0], v4[0], opl);
+      if (b == 0) {
+        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]);
+        }
+        return 0.0f;
+      }
 
-        case BEZT_IPO_BOUNCE:
-          switch (prevbezt->easing) {
-            case BEZT_IPO_EASE_IN:
-              cvalue = BLI_easing_bounce_ease_in(time, begin, change, duration);
-              break;
-            case BEZT_IPO_EASE_OUT:
-              cvalue = BLI_easing_bounce_ease_out(time, begin, change, duration);
-              break;
-            case BEZT_IPO_EASE_IN_OUT:
-              cvalue = BLI_easing_bounce_ease_in_out(time, begin, change, duration);
-              break;
-
-            default: /* default/auto: same as ease out */
-              cvalue = BLI_easing_bounce_ease_out(time, begin, change, duration);
-              break;
-          }
-          break;
+      berekeny(v1[1], v2[1], v3[1], v4[1], opl, 1);
+      return opl[0];
+    }
+    case BEZT_IPO_LIN:
+      /* linear - simply linearly interpolate between values of the two keyframes */
+      return BLI_easing_linear_ease(time, begin, change, duration);
+
+    /* easing ............................................ */
+    case BEZT_IPO_BACK:
+      switch (prevbezt->easing) {
+        case BEZT_IPO_EASE_IN:
+          return BLI_easing_back_ease_in(time, begin, change, duration, prevbezt->back);
+        case BEZT_IPO_EASE_IN_OUT:
+          return BLI_easing_back_ease_in_out(time, begin, change, duration, prevbezt->back);
+        case BEZT_IPO_EASE_OUT:
+        defa

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list