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.
This commit is contained in:
@@ -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)
|
static float fcurve_eval_keyframes_before_first(FCurve *fcu, BezTriple *bezts, float evaltime)
|
||||||
{
|
{
|
||||||
BezTriple *bezt, *prevbezt;
|
BezTriple *endpoint_bezt = bezts; /* The first keyframe. */
|
||||||
float dx, fac;
|
BezTriple *neighbor_bezt = endpoint_bezt + 1; /* The second keyframe. */
|
||||||
float cvalue = 0.0f;
|
|
||||||
|
|
||||||
/* get pointers */
|
if (endpoint_bezt->ipo == BEZT_IPO_CONST || fcu->extend == FCURVE_EXTRAPOLATE_CONSTANT ||
|
||||||
prevbezt = bezts;
|
(fcu->flag & FCURVE_DISCRETE_VALUES) != 0) {
|
||||||
bezt = prevbezt + 1;
|
/* Constant (BEZT_IPO_HORIZ) extrapolation or constant interpolation, so just extend first
|
||||||
|
* keyframe's value. */
|
||||||
/* before or on first keyframe */
|
return endpoint_bezt->vec[1][1];
|
||||||
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];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
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];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
/* constant (BEZT_IPO_HORIZ) extrapolation or constant interpolation,
|
|
||||||
* so just extend first keyframe's value
|
|
||||||
*/
|
|
||||||
cvalue = prevbezt->vec[1][1];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return cvalue;
|
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];
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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];
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
static float fcurve_eval_keyframes_after_last(FCurve *fcu, BezTriple *bezts, float evaltime)
|
||||||
{
|
{
|
||||||
BezTriple *prevbezt, *lastbezt;
|
BezTriple *endpoint_bezt = bezts + fcu->totvert - 1; /* The last keyframe. */
|
||||||
float dx, fac;
|
BezTriple *neighbor_bezt = endpoint_bezt - 1; /* The second to last keyframe. */
|
||||||
unsigned int a;
|
|
||||||
float cvalue = 0.0f;
|
|
||||||
|
|
||||||
/* get pointers */
|
if (endpoint_bezt->ipo == BEZT_IPO_CONST || fcu->extend == FCURVE_EXTRAPOLATE_CONSTANT ||
|
||||||
a = fcu->totvert - 1;
|
(fcu->flag & FCURVE_DISCRETE_VALUES) != 0) {
|
||||||
prevbezt = bezts;
|
/* Constant (BEZT_IPO_HORIZ) extrapolation or constant interpolation, so just extend last
|
||||||
lastbezt = prevbezt + a;
|
* 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];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
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];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
/* constant (BEZT_IPO_HORIZ) extrapolation or constant interpolation,
|
|
||||||
* so just extend last keyframe's value
|
|
||||||
*/
|
|
||||||
cvalue = lastbezt->vec[1][1];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return cvalue;
|
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];
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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];
|
||||||
|
}
|
||||||
|
|
||||||
|
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 */
|
/* Calculate F-Curve value for 'evaltime' using BezTriple keyframes */
|
||||||
|
|||||||
Reference in New Issue
Block a user