[Bf-blender-cvs] [75370684fa8] master: Cleanup: Animation, split FCurve extrapolation into separate functions

Sybren A. Stüvel noreply at git.blender.org
Fri May 1 15:40:35 CEST 2020


Commit: 75370684fa89103c097487d5cda8390ffb6cbc8e
Author: Sybren A. Stüvel
Date:   Fri May 1 14:29:50 2020 +0200
Branches: master
https://developer.blender.org/rB75370684fa89103c097487d5cda8390ffb6cbc8e

Cleanup: Animation, split FCurve extrapolation into separate functions

The `fcurve_eval_keyframes` consists of three parts:
- Before the first keyframe
- After the last keyframe
- Between the keyframes

This commit splits the first two parts into separate functions. This is
the first of a series of refactors, which will be committed into smaller
parts so that each is easier to follow & validate.

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 b07bf8c89b1..0ce5cce27dc 100644
--- a/source/blender/blenkernel/intern/fcurve.c
+++ b/source/blender/blenkernel/intern/fcurve.c
@@ -1415,60 +1415,35 @@ 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_keyframes_before_first(FCurve *fcu, BezTriple *bezts, 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;
+  BezTriple *bezt, *prevbezt;
+  float dx, fac;
   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
-         */
+        bezt = prevbezt + 1;
         dx = prevbezt->vec[1][0] - evaltime;
-        fac = prevbezt->vec[1][0] - prevbezt->vec[0][0];
+        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 {
@@ -1477,49 +1452,63 @@ 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];
+      dx = prevbezt->vec[1][0] - evaltime;
+      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_keyframes_after_last(FCurve *fcu, BezTriple *bezts, float evaltime)
+{
+  BezTriple *prevbezt, *lastbezt;
+  float dx, fac;
+  unsigned int a;
+  float cvalue = 0.0f;
+
+  /* get pointers */
+  a = fcu->totvert - 1;
+  prevbezt = bezts;
+  lastbezt = prevbezt + a;
+
+  /* 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
-         */
+        prevbezt = lastbezt - 1;
         dx = evaltime - lastbezt->vec[1][0];
-        fac = lastbezt->vec[2][0] - lastbezt->vec[1][0];
+        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 {
@@ -1528,12 +1517,55 @@ 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];
+      dx = evaltime - lastbezt->vec[1][0];
+      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 {
+    /* constant (BEZT_IPO_HORIZ) extrapolation or constant interpolation,
+     * so just extend last keyframe's value
+     */
+    cvalue = lastbezt->vec[1][1];
+  }
+
+  return cvalue;
+}
+
+/* Calculate F-Curve value for 'evaltime' using BezTriple keyframes */
+static float fcurve_eval_keyframes(FCurve *fcu, BezTriple *bezts, float evaltime)
+{
+  const float eps = 1.e-8f;
+  BezTriple *bezt, *prevbezt, *lastbezt;
+  float v1[2], v2[2], v3[2], v4[2], opl[32];
+  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) {
+    cvalue = fcurve_eval_keyframes_before_first(fcu, bezts, evaltime);
+  }
+  else if (lastbezt->vec[1][0] <= evaltime) {
+    cvalue = fcurve_eval_keyframes_after_last(fcu, bezts, evaltime);
+  }
   else {
     /* evaltime occurs somewhere in the middle of the curve */
     bool exact = false;



More information about the Bf-blender-cvs mailing list