[Bf-blender-cvs] [7766ba2189c] temp-sybren-anim-cleanup: Cleanup: Animation, split fcurve_eval_keyframes() into separate functions

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


Commit: 7766ba2189c160686355a3eac2961f0f5253781f
Author: Sybren A. Stüvel
Date:   Fri Feb 7 14:53:05 2020 +0100
Branches: temp-sybren-anim-cleanup
https://developer.blender.org/rB7766ba2189c160686355a3eac2961f0f5253781f

Cleanup: Animation, split fcurve_eval_keyframes() into separate functions

There are three main parts of the `fcurve_eval_keyframes()` function:

- before or on the first keyframe
- after or on the last keyframe
- between those points

These are now separated into separate functions. Apart from moving the
code, there are minimal code/cleanup changes. More cleanups to follow.

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 251c6421d66..41edba040c6 100644
--- a/source/blender/blenkernel/intern/fcurve.c
+++ b/source/blender/blenkernel/intern/fcurve.c
@@ -2665,60 +2665,31 @@ static void berekeny(float f1, float f2, float f3, float f4, float *o, int b)
 
 /* -------------------------- */
 
-/* Calculate F-Curve value for 'evaltime' using BezTriple keyframes */
-static float fcurve_eval_keyframes(FCurve *fcu, BezTriple *bezts, float evaltime)
+static float fcurve_eval_before_or_on_first_keyframe(const FCurve *fcu,
+                                                     const BezTriple *prevbezt,
+                                                     const float evaltime)
 {
-  const float eps = 1.e-8f;
-  BezTriple *bezt, *prevbezt, *lastbezt;
-  float v1[2], v2[2], v3[2], v4[2], opl[32], dx, fac;
-  unsigned int a;
-  int b;
   float cvalue = 0.0f;
 
-  /* get pointers */
-  a = fcu->totvert - 1;
-  prevbezt = bezts;
-  bezt = prevbezt + 1;
-  lastbezt = prevbezt + a;
-
-  /* evaluation time at or past endpoints? */
-  if (prevbezt->vec[1][0] >= evaltime) {
-    /* before or on first keyframe */
-    if ((fcu->extend == FCURVE_EXTRAPOLATE_LINEAR) && (prevbezt->ipo != BEZT_IPO_CONST) &&
-        !(fcu->flag & FCURVE_DISCRETE_VALUES)) {
-      /* linear or bezier interpolation */
-      if (prevbezt->ipo == BEZT_IPO_LIN) {
-        /* Use the next center point instead of our own handle for
-         * linear interpolated extrapolate
-         */
-        if (fcu->totvert == 1) {
-          cvalue = prevbezt->vec[1][1];
-        }
-        else {
-          bezt = prevbezt + 1;
-          dx = prevbezt->vec[1][0] - evaltime;
-          fac = bezt->vec[1][0] - prevbezt->vec[1][0];
-
-          /* prevent division by zero */
-          if (fac) {
-            fac = (bezt->vec[1][1] - prevbezt->vec[1][1]) / fac;
-            cvalue = prevbezt->vec[1][1] - (fac * dx);
-          }
-          else {
-            cvalue = prevbezt->vec[1][1];
-          }
-        }
+  /* before or on first keyframe */
+  if ((fcu->extend == FCURVE_EXTRAPOLATE_LINEAR) && (prevbezt->ipo != BEZT_IPO_CONST) &&
+      !(fcu->flag & FCURVE_DISCRETE_VALUES)) {
+    /* linear or bezier interpolation */
+    if (prevbezt->ipo == BEZT_IPO_LIN) {
+      /* Use the next center point instead of our own handle for
+       * linear interpolated extrapolate
+       */
+      if (fcu->totvert == 1) {
+        cvalue = prevbezt->vec[1][1];
       }
       else {
-        /* Use the first handle (earlier) of first BezTriple to calculate the
-         * gradient and thus the value of the curve at evaltime
-         */
-        dx = prevbezt->vec[1][0] - evaltime;
-        fac = prevbezt->vec[1][0] - prevbezt->vec[0][0];
+        const BezTriple *bezt = prevbezt + 1;
+        float dx = prevbezt->vec[1][0] - evaltime;
+        float fac = bezt->vec[1][0] - prevbezt->vec[1][0];
 
         /* prevent division by zero */
         if (fac) {
-          fac = (prevbezt->vec[1][1] - prevbezt->vec[0][1]) / fac;
+          fac = (bezt->vec[1][1] - prevbezt->vec[1][1]) / fac;
           cvalue = prevbezt->vec[1][1] - (fac * dx);
         }
         else {
@@ -2727,49 +2698,57 @@ static float fcurve_eval_keyframes(FCurve *fcu, BezTriple *bezts, float evaltime
       }
     }
     else {
-      /* constant (BEZT_IPO_HORIZ) extrapolation or constant interpolation,
-       * so just extend first keyframe's value
+      /* Use the first handle (earlier) of first BezTriple to calculate the
+       * gradient and thus the value of the curve at evaltime
        */
-      cvalue = prevbezt->vec[1][1];
+      float dx = prevbezt->vec[1][0] - evaltime;
+      float fac = prevbezt->vec[1][0] - prevbezt->vec[0][0];
+
+      /* prevent division by zero */
+      if (fac) {
+        fac = (prevbezt->vec[1][1] - prevbezt->vec[0][1]) / fac;
+        cvalue = prevbezt->vec[1][1] - (fac * dx);
+      }
+      else {
+        cvalue = prevbezt->vec[1][1];
+      }
     }
   }
-  else if (lastbezt->vec[1][0] <= evaltime) {
-    /* after or on last keyframe */
-    if ((fcu->extend == FCURVE_EXTRAPOLATE_LINEAR) && (lastbezt->ipo != BEZT_IPO_CONST) &&
-        !(fcu->flag & FCURVE_DISCRETE_VALUES)) {
-      /* linear or bezier interpolation */
-      if (lastbezt->ipo == BEZT_IPO_LIN) {
-        /* Use the next center point instead of our own handle for
-         * linear interpolated extrapolate
-         */
-        if (fcu->totvert == 1) {
-          cvalue = lastbezt->vec[1][1];
-        }
-        else {
-          prevbezt = lastbezt - 1;
-          dx = evaltime - lastbezt->vec[1][0];
-          fac = lastbezt->vec[1][0] - prevbezt->vec[1][0];
-
-          /* prevent division by zero */
-          if (fac) {
-            fac = (lastbezt->vec[1][1] - prevbezt->vec[1][1]) / fac;
-            cvalue = lastbezt->vec[1][1] + (fac * dx);
-          }
-          else {
-            cvalue = lastbezt->vec[1][1];
-          }
-        }
+  else {
+    /* constant (BEZT_IPO_HORIZ) extrapolation or constant interpolation,
+     * so just extend first keyframe's value
+     */
+    cvalue = prevbezt->vec[1][1];
+  }
+
+  return cvalue;
+}
+
+static float fcurve_eval_after_or_on_last_keyframe(const FCurve *fcu,
+                                                   const BezTriple *lastbezt,
+                                                   const float evaltime)
+{
+  float cvalue = 0.0f;
+
+  /* after or on last keyframe */
+  if ((fcu->extend == FCURVE_EXTRAPOLATE_LINEAR) && (lastbezt->ipo != BEZT_IPO_CONST) &&
+      !(fcu->flag & FCURVE_DISCRETE_VALUES)) {
+    /* linear or bezier interpolation */
+    if (lastbezt->ipo == BEZT_IPO_LIN) {
+      /* Use the next center point instead of our own handle for
+       * linear interpolated extrapolate
+       */
+      if (fcu->totvert == 1) {
+        cvalue = lastbezt->vec[1][1];
       }
       else {
-        /* Use the gradient of the second handle (later) of last BezTriple to calculate the
-         * gradient and thus the value of the curve at evaltime
-         */
-        dx = evaltime - lastbezt->vec[1][0];
-        fac = lastbezt->vec[2][0] - lastbezt->vec[1][0];
+        const BezTriple *prevbezt = lastbezt - 1;
+        float dx = evaltime - lastbezt->vec[1][0];
+        float fac = lastbezt->vec[1][0] - prevbezt->vec[1][0];
 
         /* prevent division by zero */
         if (fac) {
-          fac = (lastbezt->vec[2][1] - lastbezt->vec[1][1]) / fac;
+          fac = (lastbezt->vec[1][1] - prevbezt->vec[1][1]) / fac;
           cvalue = lastbezt->vec[1][1] + (fac * dx);
         }
         else {
@@ -2778,326 +2757,369 @@ static float fcurve_eval_keyframes(FCurve *fcu, BezTriple *bezts, float evaltime
       }
     }
     else {
-      /* constant (BEZT_IPO_HORIZ) extrapolation or constant interpolation,
-       * so just extend last keyframe's value
+      /* Use the gradient of the second handle (later) of last BezTriple to calculate the
+       * gradient and thus the value of the curve at evaltime
        */
-      cvalue = lastbezt->vec[1][1];
+      float dx = evaltime - lastbezt->vec[1][0];
+      float fac = lastbezt->vec[2][0] - lastbezt->vec[1][0];
+
+      /* prevent division by zero */
+      if (fac) {
+        fac = (lastbezt->vec[2][1] - lastbezt->vec[1][1]) / fac;
+        cvalue = lastbezt->vec[1][1] + (fac * dx);
+      }
+      else {
+        cvalue = lastbezt->vec[1][1];
+      }
     }
   }
   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.
+    /* constant (BEZT_IPO_HORIZ) extrapolation or constant interpolation,
+     * so just extend last keyframe's value
      */
-    a = binarysearch_bezt_index_ex(bezts, evaltime, fcu->totvert, 0.0001, &exact);
+    cvalue = lastbezt->vec[1][1];
+  }
+  return cvalue;
+}
 
-    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;
-    }
+static float fcurve_eval_between_keyframes(const FCurve *fcu,
+                                           BezTriple *bezts,
+                                           const float evaltime)
+{
+  float cvalue = 0.0f;
 
-    /* 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) {
+  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;
+
+  /* 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);
+
+  BezTriple *prevbezt;
+  BezTriple *bezt;
+
+  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

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list