[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