2.5 - Fixes for animating enum values
Interpolation between keyframes for enum values (and booleans) can only be constant now. TODO: A way to do this for modifiers is still needed.
This commit is contained in:
@@ -164,7 +164,7 @@ FCurve *list_find_fcurve (ListBase *list, const char rna_path[], const int array
|
||||
/* check paths of curves, then array indices... */
|
||||
for (fcu= list->first; fcu; fcu= fcu->next) {
|
||||
/* simple string-compare (this assumes that they have the same root...) */
|
||||
if (strcmp(fcu->rna_path, rna_path) == 0) {
|
||||
if (fcu->rna_path && !strcmp(fcu->rna_path, rna_path)) {
|
||||
/* now check indicies */
|
||||
if (fcu->array_index == array_index)
|
||||
return fcu;
|
||||
@@ -1048,17 +1048,22 @@ static float fcurve_eval_keyframes (FCurve *fcu, BezTriple *bezts, float evaltim
|
||||
lastbezt= prevbezt + a;
|
||||
|
||||
/* evaluation time at or past endpoints? */
|
||||
if (prevbezt->vec[1][0] >= evaltime) {
|
||||
if (prevbezt->vec[1][0] >= evaltime)
|
||||
{
|
||||
/* before or on first keyframe */
|
||||
if ((fcu->extend == FCURVE_EXTRAPOLATE_LINEAR) && (prevbezt->ipo != BEZT_IPO_CONST)) {
|
||||
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) {
|
||||
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 {
|
||||
else
|
||||
{
|
||||
bezt = prevbezt+1;
|
||||
dx= prevbezt->vec[1][0] - evaltime;
|
||||
fac= bezt->vec[1][0] - prevbezt->vec[1][0];
|
||||
@@ -1072,7 +1077,8 @@ static float fcurve_eval_keyframes (FCurve *fcu, BezTriple *bezts, float evaltim
|
||||
cvalue= prevbezt->vec[1][1];
|
||||
}
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
/* Use the first handle (earlier) of first BezTriple to calculate the
|
||||
* gradient and thus the value of the curve at evaltime
|
||||
*/
|
||||
@@ -1088,24 +1094,30 @@ static float fcurve_eval_keyframes (FCurve *fcu, BezTriple *bezts, float evaltim
|
||||
cvalue= prevbezt->vec[1][1];
|
||||
}
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
/* constant (BEZT_IPO_HORIZ) extrapolation or constant interpolation,
|
||||
* so just extend first keyframe's value
|
||||
*/
|
||||
cvalue= prevbezt->vec[1][1];
|
||||
}
|
||||
}
|
||||
else if (lastbezt->vec[1][0] <= evaltime) {
|
||||
else if (lastbezt->vec[1][0] <= evaltime)
|
||||
{
|
||||
/* after or on last keyframe */
|
||||
if ((fcu->extend == FCURVE_EXTRAPOLATE_LINEAR) && (lastbezt->ipo != BEZT_IPO_CONST)) {
|
||||
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) {
|
||||
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 {
|
||||
else
|
||||
{
|
||||
prevbezt = lastbezt - 1;
|
||||
dx= evaltime - lastbezt->vec[1][0];
|
||||
fac= lastbezt->vec[1][0] - prevbezt->vec[1][0];
|
||||
@@ -1119,7 +1131,8 @@ static float fcurve_eval_keyframes (FCurve *fcu, BezTriple *bezts, float evaltim
|
||||
cvalue= lastbezt->vec[1][1];
|
||||
}
|
||||
}
|
||||
else {
|
||||
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
|
||||
*/
|
||||
@@ -1135,24 +1148,30 @@ static float fcurve_eval_keyframes (FCurve *fcu, BezTriple *bezts, float evaltim
|
||||
cvalue= lastbezt->vec[1][1];
|
||||
}
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
/* constant (BEZT_IPO_HORIZ) extrapolation or constant interpolation,
|
||||
* so just extend last keyframe's value
|
||||
*/
|
||||
cvalue= lastbezt->vec[1][1];
|
||||
}
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
/* evaltime occurs somewhere in the middle of the curve */
|
||||
for (a=0; prevbezt && bezt && (a < fcu->totvert-1); a++, prevbezt=bezt, bezt++) {
|
||||
for (a=0; prevbezt && bezt && (a < fcu->totvert-1); a++, prevbezt=bezt, bezt++)
|
||||
{
|
||||
/* evaltime occurs within the interval defined by these two keyframes */
|
||||
if ((prevbezt->vec[1][0] <= evaltime) && (bezt->vec[1][0] >= evaltime)) {
|
||||
if ((prevbezt->vec[1][0] <= evaltime) && (bezt->vec[1][0] >= evaltime))
|
||||
{
|
||||
/* value depends on interpolation mode */
|
||||
if (prevbezt->ipo == BEZT_IPO_CONST) {
|
||||
if ((prevbezt->ipo == BEZT_IPO_CONST) || (fcu->flag & FCURVE_DISCRETE_VALUES))
|
||||
{
|
||||
/* constant (evaltime not relevant, so no interpolation needed) */
|
||||
cvalue= prevbezt->vec[1][1];
|
||||
}
|
||||
else if (prevbezt->ipo == BEZT_IPO_LIN) {
|
||||
else if (prevbezt->ipo == BEZT_IPO_LIN)
|
||||
{
|
||||
/* linear - interpolate between values of the two keyframes */
|
||||
fac= bezt->vec[1][0] - prevbezt->vec[1][0];
|
||||
|
||||
@@ -1164,7 +1183,8 @@ static float fcurve_eval_keyframes (FCurve *fcu, BezTriple *bezts, float evaltim
|
||||
else
|
||||
cvalue= prevbezt->vec[1][1];
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
/* bezier interpolation */
|
||||
/* v1,v2 are the first keyframe and its 2nd handle */
|
||||
v1[0]= prevbezt->vec[1][0];
|
||||
|
||||
@@ -1169,7 +1169,7 @@ static void icu_to_fcurves (ListBase *groups, ListBase *list, IpoCurve *icu, cha
|
||||
if (G.f & G_DEBUG) printf("\tconvert bitflag ipocurve, totbits = %d \n", totbits);
|
||||
|
||||
/* add the 'only int values' flag */
|
||||
fcu->flag |= FCURVE_INT_VALUES;
|
||||
fcu->flag |= (FCURVE_INT_VALUES|FCURVE_DISCRETE_VALUES);
|
||||
|
||||
/* for each bit we have to remap + check for:
|
||||
* 1) we need to make copy the existing F-Curve data (fcu -> fcurve),
|
||||
|
||||
@@ -728,8 +728,23 @@ short insert_keyframe (ID *id, bAction *act, const char group[], const char rna_
|
||||
float curval= 0.0f;
|
||||
|
||||
/* set additional flags for the F-Curve (i.e. only integer values) */
|
||||
if (RNA_property_type(prop) != PROP_FLOAT)
|
||||
fcu->flag |= FCURVE_INT_VALUES;
|
||||
fcu->flag &= ~(FCURVE_INT_VALUES|FCURVE_DISCRETE_VALUES);
|
||||
switch (RNA_property_type(prop)) {
|
||||
case PROP_FLOAT:
|
||||
/* do nothing */
|
||||
break;
|
||||
case PROP_INT:
|
||||
/* do integer (only 'whole' numbers) interpolation between all points */
|
||||
fcu->flag |= FCURVE_INT_VALUES;
|
||||
break;
|
||||
default:
|
||||
/* do 'discrete' (i.e. enum, boolean values which cannot take any intermediate
|
||||
* values at all) interpolation between all points
|
||||
* - however, we must also ensure that evaluated values are only integers still
|
||||
*/
|
||||
fcu->flag |= (FCURVE_DISCRETE_VALUES|FCURVE_INT_VALUES);
|
||||
break;
|
||||
}
|
||||
|
||||
/* apply special time tweaking */
|
||||
// XXX check on this stuff...
|
||||
|
||||
@@ -748,7 +748,7 @@ void graph_draw_ghost_curves (bAnimContext *ac, SpaceIpo *sipo, ARegion *ar, Vie
|
||||
FCurve *fcu;
|
||||
|
||||
/* draw with thick dotted lines */
|
||||
setlinestyle(1);
|
||||
setlinestyle(10);
|
||||
glLineWidth(3.0f);
|
||||
|
||||
/* anti-aliased lines for less jagged appearance */
|
||||
|
||||
@@ -321,8 +321,10 @@ enum {
|
||||
|
||||
/* skip evaluation, as RNA-path cannot be resolved (similar to muting, but cannot be set by user) */
|
||||
FCURVE_DISABLED = (1<<10),
|
||||
/* curve can only have whole-number values (int or boolean types) */
|
||||
/* curve can only have whole-number values (integer types) */
|
||||
FCURVE_INT_VALUES = (1<<11),
|
||||
/* curve can only have certain discrete-number values (no interpolation at all, for enums/booleans) */
|
||||
FCURVE_DISCRETE_VALUES = (1<<12),
|
||||
} eFCurve_Flags;
|
||||
|
||||
/* extrapolation modes (only simple value 'extending') */
|
||||
|
||||
Reference in New Issue
Block a user