[Bf-blender-cvs] [f651548c2e1] master: Cleanup: Animation, refactored FCurve extrapolation

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


Commit: f651548c2e15f0e7f0ec9a7ab6b94c7e3cd08d1c
Author: Sybren A. Stüvel
Date:   Fri May 1 14:44:16 2020 +0200
Branches: master
https://developer.blender.org/rBf651548c2e15f0e7f0ec9a7ab6b94c7e3cd08d1c

Cleanup: Animation, refactored FCurve extrapolation

Variables have been renamed so that they refer to the endpoint and its
neighbor (rather than `bezt`, `prevbezt`, or `lastbezt`), and
unnecessary variables have been removed. By returning early the code
flow is also easier to understand.

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 0ce5cce27dc..f49d1adb8cd 100644
--- a/source/blender/blenkernel/intern/fcurve.c
+++ b/source/blender/blenkernel/intern/fcurve.c
@@ -1417,130 +1417,90 @@ static void berekeny(float f1, float f2, float f3, float f4, float *o, int b)
 
 static float fcurve_eval_keyframes_before_first(FCurve *fcu, BezTriple *bezts, float evaltime)
 {
-  BezTriple *bezt, *prevbezt;
-  float dx, fac;
-  float cvalue = 0.0f;
+  BezTriple *endpoint_bezt = bezts;             /* The first keyframe. */
+  BezTriple *neighbor_bezt = endpoint_bezt + 1; /* The second keyframe. */
 
-  /* get pointers */
-  prevbezt = bezts;
-  bezt = prevbezt + 1;
+  if (endpoint_bezt->ipo == BEZT_IPO_CONST || fcu->extend == FCURVE_EXTRAPOLATE_CONSTANT ||
+      (fcu->flag & FCURVE_DISCRETE_VALUES) != 0) {
+    /* Constant (BEZT_IPO_HORIZ) extrapolation or constant interpolation, so just extend first
+     * keyframe's value. */
+    return endpoint_bezt->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 {
-        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];
-        }
-      }
+  if (endpoint_bezt->ipo == BEZT_IPO_LIN) {
+    /* Use the next center point instead of our own handle for linear interpolated extrapolate. */
+    if (fcu->totvert == 1) {
+      return endpoint_bezt->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];
 
-      /* 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];
-      }
+    float dx = endpoint_bezt->vec[1][0] - evaltime;
+    float fac = neighbor_bezt->vec[1][0] - endpoint_bezt->vec[1][0];
+
+    /* Prevent division by zero. */
+    if (fac == 0.0f) {
+      return endpoint_bezt->vec[1][1];
     }
+
+    fac = (neighbor_bezt->vec[1][1] - endpoint_bezt->vec[1][1]) / fac;
+    return endpoint_bezt->vec[1][1] - (fac * dx);
   }
-  else {
-    /* constant (BEZT_IPO_HORIZ) extrapolation or constant interpolation,
-     * so just extend first keyframe's value
-     */
-    cvalue = prevbezt->vec[1][1];
+
+  /* Use the first handle (earlier) of first BezTriple to calculate the gradient and thus the value
+   * of the curve at evaltime. */
+  float dx = endpoint_bezt->vec[1][0] - evaltime;
+  float fac = endpoint_bezt->vec[1][0] - endpoint_bezt->vec[0][0];
+
+  /* Prevent division by zero. */
+  if (fac == 0.0f) {
+    return endpoint_bezt->vec[1][1];
   }
 
-  return cvalue;
+  fac = (endpoint_bezt->vec[1][1] - endpoint_bezt->vec[0][1]) / fac;
+  return endpoint_bezt->vec[1][1] - (fac * dx);
 }
 
 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;
+  BezTriple *endpoint_bezt = bezts + fcu->totvert - 1; /* The last keyframe. */
+  BezTriple *neighbor_bezt = endpoint_bezt - 1;        /* The second to last keyframe. */
 
-  /* get pointers */
-  a = fcu->totvert - 1;
-  prevbezt = bezts;
-  lastbezt = prevbezt + a;
+  if (endpoint_bezt->ipo == BEZT_IPO_CONST || fcu->extend == FCURVE_EXTRAPOLATE_CONSTANT ||
+      (fcu->flag & FCURVE_DISCRETE_VALUES) != 0) {
+    /* Constant (BEZT_IPO_HORIZ) extrapolation or constant interpolation, so just extend last
+     * keyframe's value. */
+    return endpoint_bezt->vec[1][1];
+  }
 
-  /* 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];
-        }
-      }
+  if (endpoint_bezt->ipo == BEZT_IPO_LIN) {
+    /* Use the next center point instead of our own handle for linear interpolated extrapolate. */
+    if (fcu->totvert == 1) {
+      return endpoint_bezt->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];
 
-      /* 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];
-      }
+    float dx = evaltime - endpoint_bezt->vec[1][0];
+    float fac = endpoint_bezt->vec[1][0] - neighbor_bezt->vec[1][0];
+
+    /* Prevent division by zero. */
+    if (fac == 0.0f) {
+      return endpoint_bezt->vec[1][1];
     }
+
+    fac = (endpoint_bezt->vec[1][1] - neighbor_bezt->vec[1][1]) / fac;
+    return endpoint_bezt->vec[1][1] + (fac * dx);
   }
-  else {
-    /* constant (BEZT_IPO_HORIZ) extrapolation or constant interpolation,
-     * so just extend last keyframe's value
-     */
-    cvalue = lastbezt->vec[1][1];
+
+  /* Use the gradient of the second handle (later) of last BezTriple to calculate the gradient and
+   * thus the value of the curve at evaltime */
+  float dx = evaltime - endpoint_bezt->vec[1][0];
+  float fac = endpoint_bezt->vec[2][0] - endpoint_bezt->vec[1][0];
+
+  /* Prevent division by zero. */
+  if (fac == 0.0f) {
+    return endpoint_bezt->vec[1][1];
   }
 
-  return cvalue;
+  fac = (endpoint_bezt->vec[2][1] - endpoint_bezt->vec[1][1]) / fac;
+  return endpoint_bezt->vec[1][1] + (fac * dx);
 }
 
 /* Calculate F-Curve value for 'evaltime' using BezTriple keyframes */



More information about the Bf-blender-cvs mailing list