Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSybren A. Stüvel <sybren@blender.org>2020-05-01 15:29:50 +0300
committerSybren A. Stüvel <sybren@blender.org>2020-05-01 16:38:45 +0300
commit75370684fa89103c097487d5cda8390ffb6cbc8e (patch)
treefddc6fc5cb821c7a66ad57e7ca0bdd46e71eaa95 /source/blender/blenkernel/intern/fcurve.c
parentb523911e860e6602cf4dc3df67a405b469f22b74 (diff)
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.
Diffstat (limited to 'source/blender/blenkernel/intern/fcurve.c')
-rw-r--r--source/blender/blenkernel/intern/fcurve.c188
1 files changed, 110 insertions, 78 deletions
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,13 +1517,56 @@ 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;