diff options
Diffstat (limited to 'source/blender/blenkernel/intern/fmodifier.c')
-rw-r--r-- | source/blender/blenkernel/intern/fmodifier.c | 2179 |
1 files changed, 1107 insertions, 1072 deletions
diff --git a/source/blender/blenkernel/intern/fmodifier.c b/source/blender/blenkernel/intern/fmodifier.c index 1486455c750..d54a3bdaa37 100644 --- a/source/blender/blenkernel/intern/fmodifier.c +++ b/source/blender/blenkernel/intern/fmodifier.c @@ -79,21 +79,21 @@ void *fmodifiers_storage_get(FModifierStackStorage *storage, FModifier *fcm); */ #if 0 static FModifierTypeInfo FMI_MODNAME = { - FMODIFIER_TYPE_MODNAME, /* type */ - sizeof(FMod_ModName), /* size */ - FMI_TYPE_SOME_ACTION, /* action type */ - FMI_REQUIRES_SOME_REQUIREMENT, /* requirements */ - "Modifier Name", /* name */ - "FMod_ModName", /* struct name */ - fcm_modname_free, /* free data */ - fcm_modname_relink, /* relink data */ - fcm_modname_copy, /* copy data */ - fcm_modname_new_data, /* new data */ - fcm_modname_verify, /* verify */ - fcm_modname_time, /* evaluate time */ - fcm_modname_evaluate, /* evaluate */ - fcm_modname_time_storage, /* evaluate time with storage */ - fcm_modname_evaluate_storage, /* evaluate with storage */ + FMODIFIER_TYPE_MODNAME, /* type */ + sizeof(FMod_ModName), /* size */ + FMI_TYPE_SOME_ACTION, /* action type */ + FMI_REQUIRES_SOME_REQUIREMENT, /* requirements */ + "Modifier Name", /* name */ + "FMod_ModName", /* struct name */ + fcm_modname_free, /* free data */ + fcm_modname_relink, /* relink data */ + fcm_modname_copy, /* copy data */ + fcm_modname_new_data, /* new data */ + fcm_modname_verify, /* verify */ + fcm_modname_time, /* evaluate time */ + fcm_modname_evaluate, /* evaluate */ + fcm_modname_time_storage, /* evaluate time with storage */ + fcm_modname_evaluate_storage, /* evaluate with storage */ }; #endif @@ -107,146 +107,148 @@ static FModifierTypeInfo FMI_MODNAME = { static void fcm_generator_free(FModifier *fcm) { - FMod_Generator *data = (FMod_Generator *)fcm->data; + FMod_Generator *data = (FMod_Generator *)fcm->data; - /* free polynomial coefficients array */ - if (data->coefficients) - MEM_freeN(data->coefficients); + /* free polynomial coefficients array */ + if (data->coefficients) + MEM_freeN(data->coefficients); } static void fcm_generator_copy(FModifier *fcm, const FModifier *src) { - FMod_Generator *gen = (FMod_Generator *)fcm->data; - FMod_Generator *ogen = (FMod_Generator *)src->data; + FMod_Generator *gen = (FMod_Generator *)fcm->data; + FMod_Generator *ogen = (FMod_Generator *)src->data; - /* copy coefficients array? */ - if (ogen->coefficients) - gen->coefficients = MEM_dupallocN(ogen->coefficients); + /* copy coefficients array? */ + if (ogen->coefficients) + gen->coefficients = MEM_dupallocN(ogen->coefficients); } static void fcm_generator_new_data(void *mdata) { - FMod_Generator *data = (FMod_Generator *)mdata; - float *cp; - - /* set default generator to be linear 0-1 (gradient = 1, y-offset = 0) */ - data->poly_order = 1; - data->arraysize = 2; - cp = data->coefficients = MEM_callocN(sizeof(float) * 2, "FMod_Generator_Coefs"); - cp[0] = 0; // y-offset - cp[1] = 1; // gradient + FMod_Generator *data = (FMod_Generator *)mdata; + float *cp; + + /* set default generator to be linear 0-1 (gradient = 1, y-offset = 0) */ + data->poly_order = 1; + data->arraysize = 2; + cp = data->coefficients = MEM_callocN(sizeof(float) * 2, "FMod_Generator_Coefs"); + cp[0] = 0; // y-offset + cp[1] = 1; // gradient } static void fcm_generator_verify(FModifier *fcm) { - FMod_Generator *data = (FMod_Generator *)fcm->data; - - /* requirements depend on mode */ - switch (data->mode) { - case FCM_GENERATOR_POLYNOMIAL: /* expanded polynomial expression */ - { - const int arraysize_new = data->poly_order + 1; - /* arraysize needs to be order+1, so resize if not */ - if (data->arraysize != arraysize_new) { - data->coefficients = MEM_recallocN(data->coefficients, - sizeof(float) * arraysize_new); - data->arraysize = arraysize_new; - } - break; - } - case FCM_GENERATOR_POLYNOMIAL_FACTORISED: /* expanded polynomial expression */ - { - const int arraysize_new = data->poly_order * 2; - /* arraysize needs to be (2 * order), so resize if not */ - if (data->arraysize != arraysize_new) { - data->coefficients = MEM_recallocN(data->coefficients, - sizeof(float) * arraysize_new); - data->arraysize = arraysize_new; - } - break; - } - } + FMod_Generator *data = (FMod_Generator *)fcm->data; + + /* requirements depend on mode */ + switch (data->mode) { + case FCM_GENERATOR_POLYNOMIAL: /* expanded polynomial expression */ + { + const int arraysize_new = data->poly_order + 1; + /* arraysize needs to be order+1, so resize if not */ + if (data->arraysize != arraysize_new) { + data->coefficients = MEM_recallocN(data->coefficients, sizeof(float) * arraysize_new); + data->arraysize = arraysize_new; + } + break; + } + case FCM_GENERATOR_POLYNOMIAL_FACTORISED: /* expanded polynomial expression */ + { + const int arraysize_new = data->poly_order * 2; + /* arraysize needs to be (2 * order), so resize if not */ + if (data->arraysize != arraysize_new) { + data->coefficients = MEM_recallocN(data->coefficients, sizeof(float) * arraysize_new); + data->arraysize = arraysize_new; + } + break; + } + } } -static void fcm_generator_evaluate(FCurve *UNUSED(fcu), FModifier *fcm, float *cvalue, float evaltime) +static void fcm_generator_evaluate(FCurve *UNUSED(fcu), + FModifier *fcm, + float *cvalue, + float evaltime) { - FMod_Generator *data = (FMod_Generator *)fcm->data; - - /* behavior depends on mode - * NOTE: the data in its default state is fine too - */ - switch (data->mode) { - case FCM_GENERATOR_POLYNOMIAL: /* expanded polynomial expression */ - { - /* we overwrite cvalue with the sum of the polynomial */ - float *powers = MEM_callocN(sizeof(float) * data->arraysize, "Poly Powers"); - float value = 0.0f; - unsigned int i; - - /* for each x^n, precalculate value based on previous one first... this should be - * faster that calling pow() for each entry - */ - for (i = 0; i < data->arraysize; i++) { - /* first entry is x^0 = 1, otherwise, calculate based on previous */ - if (i) - powers[i] = powers[i - 1] * evaltime; - else - powers[0] = 1; - } - - /* for each coefficient, add to value, which we'll write to *cvalue in one go */ - for (i = 0; i < data->arraysize; i++) - value += data->coefficients[i] * powers[i]; - - /* only if something changed, write *cvalue in one go */ - if (data->poly_order) { - if (data->flag & FCM_GENERATOR_ADDITIVE) - *cvalue += value; - else - *cvalue = value; - } - - /* cleanup */ - if (powers) - MEM_freeN(powers); - break; - } - case FCM_GENERATOR_POLYNOMIAL_FACTORISED: /* Factorized polynomial */ - { - float value = 1.0f, *cp = NULL; - unsigned int i; - - /* for each coefficient pair, solve for that bracket before accumulating in value by multiplying */ - for (cp = data->coefficients, i = 0; (cp) && (i < (unsigned int)data->poly_order); cp += 2, i++) - value *= (cp[0] * evaltime + cp[1]); - - /* only if something changed, write *cvalue in one go */ - if (data->poly_order) { - if (data->flag & FCM_GENERATOR_ADDITIVE) - *cvalue += value; - else - *cvalue = value; - } - break; - } - } + FMod_Generator *data = (FMod_Generator *)fcm->data; + + /* behavior depends on mode + * NOTE: the data in its default state is fine too + */ + switch (data->mode) { + case FCM_GENERATOR_POLYNOMIAL: /* expanded polynomial expression */ + { + /* we overwrite cvalue with the sum of the polynomial */ + float *powers = MEM_callocN(sizeof(float) * data->arraysize, "Poly Powers"); + float value = 0.0f; + unsigned int i; + + /* for each x^n, precalculate value based on previous one first... this should be + * faster that calling pow() for each entry + */ + for (i = 0; i < data->arraysize; i++) { + /* first entry is x^0 = 1, otherwise, calculate based on previous */ + if (i) + powers[i] = powers[i - 1] * evaltime; + else + powers[0] = 1; + } + + /* for each coefficient, add to value, which we'll write to *cvalue in one go */ + for (i = 0; i < data->arraysize; i++) + value += data->coefficients[i] * powers[i]; + + /* only if something changed, write *cvalue in one go */ + if (data->poly_order) { + if (data->flag & FCM_GENERATOR_ADDITIVE) + *cvalue += value; + else + *cvalue = value; + } + + /* cleanup */ + if (powers) + MEM_freeN(powers); + break; + } + case FCM_GENERATOR_POLYNOMIAL_FACTORISED: /* Factorized polynomial */ + { + float value = 1.0f, *cp = NULL; + unsigned int i; + + /* for each coefficient pair, solve for that bracket before accumulating in value by multiplying */ + for (cp = data->coefficients, i = 0; (cp) && (i < (unsigned int)data->poly_order); + cp += 2, i++) + value *= (cp[0] * evaltime + cp[1]); + + /* only if something changed, write *cvalue in one go */ + if (data->poly_order) { + if (data->flag & FCM_GENERATOR_ADDITIVE) + *cvalue += value; + else + *cvalue = value; + } + break; + } + } } static FModifierTypeInfo FMI_GENERATOR = { - FMODIFIER_TYPE_GENERATOR, /* type */ - sizeof(FMod_Generator), /* size */ - FMI_TYPE_GENERATE_CURVE, /* action type */ - FMI_REQUIRES_NOTHING, /* requirements */ - N_("Generator"), /* name */ - "FMod_Generator", /* struct name */ - fcm_generator_free, /* free data */ - fcm_generator_copy, /* copy data */ - fcm_generator_new_data, /* new data */ - fcm_generator_verify, /* verify */ - NULL, /* evaluate time */ - fcm_generator_evaluate, /* evaluate */ - NULL, /* evaluate time with storage */ - NULL, /* evaluate with storage */ + FMODIFIER_TYPE_GENERATOR, /* type */ + sizeof(FMod_Generator), /* size */ + FMI_TYPE_GENERATE_CURVE, /* action type */ + FMI_REQUIRES_NOTHING, /* requirements */ + N_("Generator"), /* name */ + "FMod_Generator", /* struct name */ + fcm_generator_free, /* free data */ + fcm_generator_copy, /* copy data */ + fcm_generator_new_data, /* new data */ + fcm_generator_verify, /* verify */ + NULL, /* evaluate time */ + fcm_generator_evaluate, /* evaluate */ + NULL, /* evaluate time with storage */ + NULL, /* evaluate with storage */ }; /* Built-In Function Generator F-Curve Modifier --------------------------- */ @@ -263,11 +265,11 @@ static FModifierTypeInfo FMI_GENERATOR = { static void fcm_fn_generator_new_data(void *mdata) { - FMod_FunctionGenerator *data = (FMod_FunctionGenerator *)mdata; + FMod_FunctionGenerator *data = (FMod_FunctionGenerator *)mdata; - /* set amplitude and phase multiplier to 1.0f so that something is generated */ - data->amplitude = 1.0f; - data->phase_multiplier = 1.0f; + /* set amplitude and phase multiplier to 1.0f so that something is generated */ + data->amplitude = 1.0f; + data->phase_multiplier = 1.0f; } /* Unary 'normalized sine' function @@ -276,210 +278,216 @@ static void fcm_fn_generator_new_data(void *mdata) */ static double sinc(double x) { - if (fabs(x) < 0.0001) - return 1.0; - else - return sin(M_PI * x) / (M_PI * x); + if (fabs(x) < 0.0001) + return 1.0; + else + return sin(M_PI * x) / (M_PI * x); } -static void fcm_fn_generator_evaluate(FCurve *UNUSED(fcu), FModifier *fcm, float *cvalue, float evaltime) +static void fcm_fn_generator_evaluate(FCurve *UNUSED(fcu), + FModifier *fcm, + float *cvalue, + float evaltime) { - FMod_FunctionGenerator *data = (FMod_FunctionGenerator *)fcm->data; - double arg = data->phase_multiplier * evaltime + data->phase_offset; - double (*fn)(double v) = NULL; - - /* get function pointer to the func to use: - * WARNING: must perform special argument validation hereto guard against crashes - */ - switch (data->type) { - /* simple ones */ - case FCM_GENERATOR_FN_SIN: /* sine wave */ - fn = sin; - break; - case FCM_GENERATOR_FN_COS: /* cosine wave */ - fn = cos; - break; - case FCM_GENERATOR_FN_SINC: /* normalized sine wave */ - fn = sinc; - break; - - /* validation required */ - case FCM_GENERATOR_FN_TAN: /* tangent wave */ - { - /* check that argument is not on one of the discontinuities (i.e. 90deg, 270 deg, etc) */ - if (IS_EQ(fmod((arg - M_PI_2), M_PI), 0.0)) { - if ((data->flag & FCM_GENERATOR_ADDITIVE) == 0) - *cvalue = 0.0f; /* no value possible here */ - } - else - fn = tan; - break; - } - case FCM_GENERATOR_FN_LN: /* natural log */ - { - /* check that value is greater than 1? */ - if (arg > 1.0) { - fn = log; - } - else { - if ((data->flag & FCM_GENERATOR_ADDITIVE) == 0) - *cvalue = 0.0f; /* no value possible here */ - } - break; - } - case FCM_GENERATOR_FN_SQRT: /* square root */ - { - /* no negative numbers */ - if (arg > 0.0) { - fn = sqrt; - } - else { - if ((data->flag & FCM_GENERATOR_ADDITIVE) == 0) - *cvalue = 0.0f; /* no value possible here */ - } - break; - } - default: - CLOG_ERROR(&LOG, "Invalid Function-Generator for F-Modifier - %d", data->type); - break; - - } - - /* execute function callback to set value if appropriate */ - if (fn) { - float value = (float)(data->amplitude * (float)fn(arg) + data->value_offset); - - if (data->flag & FCM_GENERATOR_ADDITIVE) - *cvalue += value; - else - *cvalue = value; - } + FMod_FunctionGenerator *data = (FMod_FunctionGenerator *)fcm->data; + double arg = data->phase_multiplier * evaltime + data->phase_offset; + double (*fn)(double v) = NULL; + + /* get function pointer to the func to use: + * WARNING: must perform special argument validation hereto guard against crashes + */ + switch (data->type) { + /* simple ones */ + case FCM_GENERATOR_FN_SIN: /* sine wave */ + fn = sin; + break; + case FCM_GENERATOR_FN_COS: /* cosine wave */ + fn = cos; + break; + case FCM_GENERATOR_FN_SINC: /* normalized sine wave */ + fn = sinc; + break; + + /* validation required */ + case FCM_GENERATOR_FN_TAN: /* tangent wave */ + { + /* check that argument is not on one of the discontinuities (i.e. 90deg, 270 deg, etc) */ + if (IS_EQ(fmod((arg - M_PI_2), M_PI), 0.0)) { + if ((data->flag & FCM_GENERATOR_ADDITIVE) == 0) + *cvalue = 0.0f; /* no value possible here */ + } + else + fn = tan; + break; + } + case FCM_GENERATOR_FN_LN: /* natural log */ + { + /* check that value is greater than 1? */ + if (arg > 1.0) { + fn = log; + } + else { + if ((data->flag & FCM_GENERATOR_ADDITIVE) == 0) + *cvalue = 0.0f; /* no value possible here */ + } + break; + } + case FCM_GENERATOR_FN_SQRT: /* square root */ + { + /* no negative numbers */ + if (arg > 0.0) { + fn = sqrt; + } + else { + if ((data->flag & FCM_GENERATOR_ADDITIVE) == 0) + *cvalue = 0.0f; /* no value possible here */ + } + break; + } + default: + CLOG_ERROR(&LOG, "Invalid Function-Generator for F-Modifier - %d", data->type); + break; + } + + /* execute function callback to set value if appropriate */ + if (fn) { + float value = (float)(data->amplitude * (float)fn(arg) + data->value_offset); + + if (data->flag & FCM_GENERATOR_ADDITIVE) + *cvalue += value; + else + *cvalue = value; + } } static FModifierTypeInfo FMI_FN_GENERATOR = { - FMODIFIER_TYPE_FN_GENERATOR, /* type */ - sizeof(FMod_FunctionGenerator), /* size */ - FMI_TYPE_GENERATE_CURVE, /* action type */ - FMI_REQUIRES_NOTHING, /* requirements */ - N_("Built-In Function"), /* name */ - "FMod_FunctionGenerator", /* struct name */ - NULL, /* free data */ - NULL, /* copy data */ - fcm_fn_generator_new_data, /* new data */ - NULL, /* verify */ - NULL, /* evaluate time */ - fcm_fn_generator_evaluate, /* evaluate */ - NULL, /* evaluate time with storage */ - NULL, /* evaluate with storage */ + FMODIFIER_TYPE_FN_GENERATOR, /* type */ + sizeof(FMod_FunctionGenerator), /* size */ + FMI_TYPE_GENERATE_CURVE, /* action type */ + FMI_REQUIRES_NOTHING, /* requirements */ + N_("Built-In Function"), /* name */ + "FMod_FunctionGenerator", /* struct name */ + NULL, /* free data */ + NULL, /* copy data */ + fcm_fn_generator_new_data, /* new data */ + NULL, /* verify */ + NULL, /* evaluate time */ + fcm_fn_generator_evaluate, /* evaluate */ + NULL, /* evaluate time with storage */ + NULL, /* evaluate with storage */ }; /* Envelope F-Curve Modifier --------------------------- */ static void fcm_envelope_free(FModifier *fcm) { - FMod_Envelope *env = (FMod_Envelope *)fcm->data; + FMod_Envelope *env = (FMod_Envelope *)fcm->data; - /* free envelope data array */ - if (env->data) - MEM_freeN(env->data); + /* free envelope data array */ + if (env->data) + MEM_freeN(env->data); } static void fcm_envelope_copy(FModifier *fcm, const FModifier *src) { - FMod_Envelope *env = (FMod_Envelope *)fcm->data; - FMod_Envelope *oenv = (FMod_Envelope *)src->data; + FMod_Envelope *env = (FMod_Envelope *)fcm->data; + FMod_Envelope *oenv = (FMod_Envelope *)src->data; - /* copy envelope data array */ - if (oenv->data) - env->data = MEM_dupallocN(oenv->data); + /* copy envelope data array */ + if (oenv->data) + env->data = MEM_dupallocN(oenv->data); } static void fcm_envelope_new_data(void *mdata) { - FMod_Envelope *env = (FMod_Envelope *)mdata; + FMod_Envelope *env = (FMod_Envelope *)mdata; - /* set default min/max ranges */ - env->min = -1.0f; - env->max = 1.0f; + /* set default min/max ranges */ + env->min = -1.0f; + env->max = 1.0f; } static void fcm_envelope_verify(FModifier *fcm) { - FMod_Envelope *env = (FMod_Envelope *)fcm->data; + FMod_Envelope *env = (FMod_Envelope *)fcm->data; - /* if the are points, perform bubble-sort on them, as user may have changed the order */ - if (env->data) { - /* XXX todo... */ - } + /* if the are points, perform bubble-sort on them, as user may have changed the order */ + if (env->data) { + /* XXX todo... */ + } } -static void fcm_envelope_evaluate(FCurve *UNUSED(fcu), FModifier *fcm, float *cvalue, float evaltime) +static void fcm_envelope_evaluate(FCurve *UNUSED(fcu), + FModifier *fcm, + float *cvalue, + float evaltime) { - FMod_Envelope *env = (FMod_Envelope *)fcm->data; - FCM_EnvelopeData *fed, *prevfed, *lastfed; - float min = 0.0f, max = 0.0f, fac = 0.0f; - int a; - - /* get pointers */ - if (env->data == NULL) return; - prevfed = env->data; - fed = prevfed + 1; - lastfed = prevfed + (env->totvert - 1); - - /* get min/max values for envelope at evaluation time (relative to mid-value) */ - if (prevfed->time >= evaltime) { - /* before or on first sample, so just extend value */ - min = prevfed->min; - max = prevfed->max; - } - else if (lastfed->time <= evaltime) { - /* after or on last sample, so just extend value */ - min = lastfed->min; - max = lastfed->max; - } - else { - /* evaltime occurs somewhere between segments */ - /* TODO: implement binary search for this to make it faster? */ - for (a = 0; prevfed && fed && (a < env->totvert - 1); a++, prevfed = fed, fed++) { - /* evaltime occurs within the interval defined by these two envelope points */ - if ((prevfed->time <= evaltime) && (fed->time >= evaltime)) { - float afac, bfac, diff; - - diff = fed->time - prevfed->time; - afac = (evaltime - prevfed->time) / diff; - bfac = (fed->time - evaltime) / diff; - - min = bfac * prevfed->min + afac * fed->min; - max = bfac * prevfed->max + afac * fed->max; - - break; - } - } - } - - /* adjust *cvalue - * - fac is the ratio of how the current y-value corresponds to the reference range - * - thus, the new value is found by mapping the old range to the new! - */ - fac = (*cvalue - (env->midval + env->min)) / (env->max - env->min); - *cvalue = min + fac * (max - min); + FMod_Envelope *env = (FMod_Envelope *)fcm->data; + FCM_EnvelopeData *fed, *prevfed, *lastfed; + float min = 0.0f, max = 0.0f, fac = 0.0f; + int a; + + /* get pointers */ + if (env->data == NULL) + return; + prevfed = env->data; + fed = prevfed + 1; + lastfed = prevfed + (env->totvert - 1); + + /* get min/max values for envelope at evaluation time (relative to mid-value) */ + if (prevfed->time >= evaltime) { + /* before or on first sample, so just extend value */ + min = prevfed->min; + max = prevfed->max; + } + else if (lastfed->time <= evaltime) { + /* after or on last sample, so just extend value */ + min = lastfed->min; + max = lastfed->max; + } + else { + /* evaltime occurs somewhere between segments */ + /* TODO: implement binary search for this to make it faster? */ + for (a = 0; prevfed && fed && (a < env->totvert - 1); a++, prevfed = fed, fed++) { + /* evaltime occurs within the interval defined by these two envelope points */ + if ((prevfed->time <= evaltime) && (fed->time >= evaltime)) { + float afac, bfac, diff; + + diff = fed->time - prevfed->time; + afac = (evaltime - prevfed->time) / diff; + bfac = (fed->time - evaltime) / diff; + + min = bfac * prevfed->min + afac * fed->min; + max = bfac * prevfed->max + afac * fed->max; + + break; + } + } + } + + /* adjust *cvalue + * - fac is the ratio of how the current y-value corresponds to the reference range + * - thus, the new value is found by mapping the old range to the new! + */ + fac = (*cvalue - (env->midval + env->min)) / (env->max - env->min); + *cvalue = min + fac * (max - min); } static FModifierTypeInfo FMI_ENVELOPE = { - FMODIFIER_TYPE_ENVELOPE, /* type */ - sizeof(FMod_Envelope), /* size */ - FMI_TYPE_REPLACE_VALUES, /* action type */ - 0, /* requirements */ - N_("Envelope"), /* name */ - "FMod_Envelope", /* struct name */ - fcm_envelope_free, /* free data */ - fcm_envelope_copy, /* copy data */ - fcm_envelope_new_data, /* new data */ - fcm_envelope_verify, /* verify */ - NULL, /* evaluate time */ - fcm_envelope_evaluate, /* evaluate */ - NULL, /* evaluate time with storage */ - NULL, /* evaluate with storage */ + FMODIFIER_TYPE_ENVELOPE, /* type */ + sizeof(FMod_Envelope), /* size */ + FMI_TYPE_REPLACE_VALUES, /* action type */ + 0, /* requirements */ + N_("Envelope"), /* name */ + "FMod_Envelope", /* struct name */ + fcm_envelope_free, /* free data */ + fcm_envelope_copy, /* copy data */ + fcm_envelope_new_data, /* new data */ + fcm_envelope_verify, /* verify */ + NULL, /* evaluate time */ + fcm_envelope_evaluate, /* evaluate */ + NULL, /* evaluate time with storage */ + NULL, /* evaluate with storage */ }; /* exported function for finding points */ @@ -489,85 +497,92 @@ static FModifierTypeInfo FMI_ENVELOPE = { */ #define BINARYSEARCH_FRAMEEQ_THRESH 0.0001f -int BKE_fcm_envelope_find_index(FCM_EnvelopeData array[], float frame, int arraylen, bool *r_exists) +int BKE_fcm_envelope_find_index(FCM_EnvelopeData array[], + float frame, + int arraylen, + bool *r_exists) { - int start = 0, end = arraylen; - int loopbreaker = 0, maxloop = arraylen * 2; - - /* initialize exists-flag first */ - *r_exists = false; - - /* sneaky optimizations (don't go through searching process if...): - * - keyframe to be added is to be added out of current bounds - * - keyframe to be added would replace one of the existing ones on bounds - */ - if ((arraylen <= 0) || (array == NULL)) { - CLOG_WARN(&LOG, "encountered invalid array"); - return 0; - } - else { - /* check whether to add before/after/on */ - float framenum; - - /* 'First' Point (when only one point, this case is used) */ - framenum = array[0].time; - if (IS_EQT(frame, framenum, BINARYSEARCH_FRAMEEQ_THRESH)) { - *r_exists = true; - return 0; - } - else if (frame < framenum) { - return 0; - } - - /* 'Last' Point */ - framenum = array[(arraylen - 1)].time; - if (IS_EQT(frame, framenum, BINARYSEARCH_FRAMEEQ_THRESH)) { - *r_exists = true; - return (arraylen - 1); - } - else if (frame > framenum) { - return arraylen; - } - } - - - /* most of the time, this loop is just to find where to put it - * - 'loopbreaker' is just here to prevent infinite loops - */ - for (loopbreaker = 0; (start <= end) && (loopbreaker < maxloop); loopbreaker++) { - /* compute and get midpoint */ - int mid = start + ((end - start) / 2); /* we calculate the midpoint this way to avoid int overflows... */ - float midfra = array[mid].time; - - /* check if exactly equal to midpoint */ - if (IS_EQT(frame, midfra, BINARYSEARCH_FRAMEEQ_THRESH)) { - *r_exists = true; - return mid; - } - - /* repeat in upper/lower half */ - if (frame > midfra) { - start = mid + 1; - } - else if (frame < midfra) { - end = mid - 1; - } - } - - /* print error if loop-limit exceeded */ - if (loopbreaker == (maxloop - 1)) { - CLOG_ERROR(&LOG, "binary search was taking too long"); - - // include debug info - CLOG_ERROR(&LOG, "\tround = %d: start = %d, end = %d, arraylen = %d", loopbreaker, start, end, arraylen); - } - - /* not found, so return where to place it */ - return start; + int start = 0, end = arraylen; + int loopbreaker = 0, maxloop = arraylen * 2; + + /* initialize exists-flag first */ + *r_exists = false; + + /* sneaky optimizations (don't go through searching process if...): + * - keyframe to be added is to be added out of current bounds + * - keyframe to be added would replace one of the existing ones on bounds + */ + if ((arraylen <= 0) || (array == NULL)) { + CLOG_WARN(&LOG, "encountered invalid array"); + return 0; + } + else { + /* check whether to add before/after/on */ + float framenum; + + /* 'First' Point (when only one point, this case is used) */ + framenum = array[0].time; + if (IS_EQT(frame, framenum, BINARYSEARCH_FRAMEEQ_THRESH)) { + *r_exists = true; + return 0; + } + else if (frame < framenum) { + return 0; + } + + /* 'Last' Point */ + framenum = array[(arraylen - 1)].time; + if (IS_EQT(frame, framenum, BINARYSEARCH_FRAMEEQ_THRESH)) { + *r_exists = true; + return (arraylen - 1); + } + else if (frame > framenum) { + return arraylen; + } + } + + /* most of the time, this loop is just to find where to put it + * - 'loopbreaker' is just here to prevent infinite loops + */ + for (loopbreaker = 0; (start <= end) && (loopbreaker < maxloop); loopbreaker++) { + /* compute and get midpoint */ + int mid = start + ((end - start) / + 2); /* we calculate the midpoint this way to avoid int overflows... */ + float midfra = array[mid].time; + + /* check if exactly equal to midpoint */ + if (IS_EQT(frame, midfra, BINARYSEARCH_FRAMEEQ_THRESH)) { + *r_exists = true; + return mid; + } + + /* repeat in upper/lower half */ + if (frame > midfra) { + start = mid + 1; + } + else if (frame < midfra) { + end = mid - 1; + } + } + + /* print error if loop-limit exceeded */ + if (loopbreaker == (maxloop - 1)) { + CLOG_ERROR(&LOG, "binary search was taking too long"); + + // include debug info + CLOG_ERROR(&LOG, + "\tround = %d: start = %d, end = %d, arraylen = %d", + loopbreaker, + start, + end, + arraylen); + } + + /* not found, so return where to place it */ + return start; } #undef BINARYSEARCH_FRAMEEQ_THRESH - /* Cycles F-Curve Modifier --------------------------- */ /* This modifier changes evaltime to something that exists within the curve's frame-range, @@ -584,410 +599,429 @@ int BKE_fcm_envelope_find_index(FCM_EnvelopeData array[], float frame, int array /* temp data used during evaluation */ typedef struct tFCMED_Cycles { - float cycyofs; /* y-offset to apply */ + float cycyofs; /* y-offset to apply */ } tFCMED_Cycles; static void fcm_cycles_new_data(void *mdata) { - FMod_Cycles *data = (FMod_Cycles *)mdata; + FMod_Cycles *data = (FMod_Cycles *)mdata; - /* turn on cycles by default */ - data->before_mode = data->after_mode = FCM_EXTRAPOLATE_CYCLIC; + /* turn on cycles by default */ + data->before_mode = data->after_mode = FCM_EXTRAPOLATE_CYCLIC; } -static float fcm_cycles_time(FModifierStackStorage *storage, FCurve *fcu, FModifier *fcm, - float UNUSED(cvalue), float evaltime) +static float fcm_cycles_time(FModifierStackStorage *storage, + FCurve *fcu, + FModifier *fcm, + float UNUSED(cvalue), + float evaltime) { - FMod_Cycles *data = (FMod_Cycles *)fcm->data; - float prevkey[2], lastkey[2], cycyofs = 0.0f; - short side = 0, mode = 0; - int cycles = 0; - float ofs = 0; - - /* check if modifier is first in stack, otherwise disable ourself... */ - /* FIXME... */ - if (fcm->prev) { - fcm->flag |= FMODIFIER_FLAG_DISABLED; - return evaltime; - } - - /* calculate new evaltime due to cyclic interpolation */ - if (fcu && fcu->bezt) { - BezTriple *prevbezt = fcu->bezt; - BezTriple *lastbezt = prevbezt + fcu->totvert - 1; - - prevkey[0] = prevbezt->vec[1][0]; - prevkey[1] = prevbezt->vec[1][1]; - - lastkey[0] = lastbezt->vec[1][0]; - lastkey[1] = lastbezt->vec[1][1]; - } - else if (fcu && fcu->fpt) { - FPoint *prevfpt = fcu->fpt; - FPoint *lastfpt = prevfpt + fcu->totvert - 1; - - prevkey[0] = prevfpt->vec[0]; - prevkey[1] = prevfpt->vec[1]; - - lastkey[0] = lastfpt->vec[0]; - lastkey[1] = lastfpt->vec[1]; - } - else - return evaltime; - - /* check if modifier will do anything - * 1) if in data range, definitely don't do anything - * 2) if before first frame or after last frame, make sure some cycling is in use - */ - if (evaltime < prevkey[0]) { - if (data->before_mode) { - side = -1; - mode = data->before_mode; - cycles = data->before_cycles; - ofs = prevkey[0]; - } - } - else if (evaltime > lastkey[0]) { - if (data->after_mode) { - side = 1; - mode = data->after_mode; - cycles = data->after_cycles; - ofs = lastkey[0]; - } - } - if ((ELEM(0, side, mode))) - return evaltime; - - /* find relative place within a cycle */ - { - float cycdx = 0, cycdy = 0; - float cycle = 0, cyct = 0; - - /* calculate period and amplitude (total height) of a cycle */ - cycdx = lastkey[0] - prevkey[0]; - cycdy = lastkey[1] - prevkey[1]; - - /* check if cycle is infinitely small, to be point of being impossible to use */ - if (cycdx == 0) - return evaltime; - - /* calculate the 'number' of the cycle */ - cycle = ((float)side * (evaltime - ofs) / cycdx); - - /* calculate the time inside the cycle */ - cyct = fmod(evaltime - ofs, cycdx); - - /* check that cyclic is still enabled for the specified time */ - if (cycles == 0) { - /* catch this case so that we don't exit when we have (cycles = 0) - * as this indicates infinite cycles... - */ - } - else if (cycle > cycles) { - /* we are too far away from range to evaluate - * TODO: but we should still hold last value... - */ - return evaltime; - } - - /* check if 'cyclic extrapolation', and thus calculate y-offset for this cycle */ - if (mode == FCM_EXTRAPOLATE_CYCLIC_OFFSET) { - if (side < 0) - cycyofs = (float)floor((evaltime - ofs) / cycdx); - else - cycyofs = (float)ceil((evaltime - ofs) / cycdx); - cycyofs *= cycdy; - } - - /* special case for cycle start/end */ - if (cyct == 0.0f) { - evaltime = (side == 1 ? lastkey[0] : prevkey[0]); - - if ((mode == FCM_EXTRAPOLATE_MIRROR) && ((int)cycle % 2)) - evaltime = (side == 1 ? prevkey[0] : lastkey[0]); - } - /* calculate where in the cycle we are (overwrite evaltime to reflect this) */ - else if ((mode == FCM_EXTRAPOLATE_MIRROR) && ((int)(cycle + 1) % 2)) { - /* when 'mirror' option is used and cycle number is odd, this cycle is played in reverse - * - for 'before' extrapolation, we need to flip in a different way, otherwise values past - * then end of the curve get referenced (result of fmod will be negative, and with different phase) - */ - if (side < 0) - evaltime = prevkey[0] - cyct; - else - evaltime = lastkey[0] - cyct; - } - else { - /* the cycle is played normally... */ - evaltime = prevkey[0] + cyct; - } - if (evaltime < prevkey[0]) evaltime += cycdx; - } - - /* store temp data if needed */ - if (mode == FCM_EXTRAPOLATE_CYCLIC_OFFSET) { - tFCMED_Cycles *edata; - - /* for now, this is just a float, but we could get more stuff... */ - edata = MEM_callocN(sizeof(tFCMED_Cycles), "tFCMED_Cycles"); - edata->cycyofs = cycyofs; - - fmodifiers_storage_put(storage, fcm, edata); - } - - /* return the new frame to evaluate */ - return evaltime; + FMod_Cycles *data = (FMod_Cycles *)fcm->data; + float prevkey[2], lastkey[2], cycyofs = 0.0f; + short side = 0, mode = 0; + int cycles = 0; + float ofs = 0; + + /* check if modifier is first in stack, otherwise disable ourself... */ + /* FIXME... */ + if (fcm->prev) { + fcm->flag |= FMODIFIER_FLAG_DISABLED; + return evaltime; + } + + /* calculate new evaltime due to cyclic interpolation */ + if (fcu && fcu->bezt) { + BezTriple *prevbezt = fcu->bezt; + BezTriple *lastbezt = prevbezt + fcu->totvert - 1; + + prevkey[0] = prevbezt->vec[1][0]; + prevkey[1] = prevbezt->vec[1][1]; + + lastkey[0] = lastbezt->vec[1][0]; + lastkey[1] = lastbezt->vec[1][1]; + } + else if (fcu && fcu->fpt) { + FPoint *prevfpt = fcu->fpt; + FPoint *lastfpt = prevfpt + fcu->totvert - 1; + + prevkey[0] = prevfpt->vec[0]; + prevkey[1] = prevfpt->vec[1]; + + lastkey[0] = lastfpt->vec[0]; + lastkey[1] = lastfpt->vec[1]; + } + else + return evaltime; + + /* check if modifier will do anything + * 1) if in data range, definitely don't do anything + * 2) if before first frame or after last frame, make sure some cycling is in use + */ + if (evaltime < prevkey[0]) { + if (data->before_mode) { + side = -1; + mode = data->before_mode; + cycles = data->before_cycles; + ofs = prevkey[0]; + } + } + else if (evaltime > lastkey[0]) { + if (data->after_mode) { + side = 1; + mode = data->after_mode; + cycles = data->after_cycles; + ofs = lastkey[0]; + } + } + if ((ELEM(0, side, mode))) + return evaltime; + + /* find relative place within a cycle */ + { + float cycdx = 0, cycdy = 0; + float cycle = 0, cyct = 0; + + /* calculate period and amplitude (total height) of a cycle */ + cycdx = lastkey[0] - prevkey[0]; + cycdy = lastkey[1] - prevkey[1]; + + /* check if cycle is infinitely small, to be point of being impossible to use */ + if (cycdx == 0) + return evaltime; + + /* calculate the 'number' of the cycle */ + cycle = ((float)side * (evaltime - ofs) / cycdx); + + /* calculate the time inside the cycle */ + cyct = fmod(evaltime - ofs, cycdx); + + /* check that cyclic is still enabled for the specified time */ + if (cycles == 0) { + /* catch this case so that we don't exit when we have (cycles = 0) + * as this indicates infinite cycles... + */ + } + else if (cycle > cycles) { + /* we are too far away from range to evaluate + * TODO: but we should still hold last value... + */ + return evaltime; + } + + /* check if 'cyclic extrapolation', and thus calculate y-offset for this cycle */ + if (mode == FCM_EXTRAPOLATE_CYCLIC_OFFSET) { + if (side < 0) + cycyofs = (float)floor((evaltime - ofs) / cycdx); + else + cycyofs = (float)ceil((evaltime - ofs) / cycdx); + cycyofs *= cycdy; + } + + /* special case for cycle start/end */ + if (cyct == 0.0f) { + evaltime = (side == 1 ? lastkey[0] : prevkey[0]); + + if ((mode == FCM_EXTRAPOLATE_MIRROR) && ((int)cycle % 2)) + evaltime = (side == 1 ? prevkey[0] : lastkey[0]); + } + /* calculate where in the cycle we are (overwrite evaltime to reflect this) */ + else if ((mode == FCM_EXTRAPOLATE_MIRROR) && ((int)(cycle + 1) % 2)) { + /* when 'mirror' option is used and cycle number is odd, this cycle is played in reverse + * - for 'before' extrapolation, we need to flip in a different way, otherwise values past + * then end of the curve get referenced (result of fmod will be negative, and with different phase) + */ + if (side < 0) + evaltime = prevkey[0] - cyct; + else + evaltime = lastkey[0] - cyct; + } + else { + /* the cycle is played normally... */ + evaltime = prevkey[0] + cyct; + } + if (evaltime < prevkey[0]) + evaltime += cycdx; + } + + /* store temp data if needed */ + if (mode == FCM_EXTRAPOLATE_CYCLIC_OFFSET) { + tFCMED_Cycles *edata; + + /* for now, this is just a float, but we could get more stuff... */ + edata = MEM_callocN(sizeof(tFCMED_Cycles), "tFCMED_Cycles"); + edata->cycyofs = cycyofs; + + fmodifiers_storage_put(storage, fcm, edata); + } + + /* return the new frame to evaluate */ + return evaltime; } -static void fcm_cycles_evaluate(FModifierStackStorage *storage, FCurve *UNUSED(fcu), - FModifier *fcm, float *cvalue, float UNUSED(evaltime)) +static void fcm_cycles_evaluate(FModifierStackStorage *storage, + FCurve *UNUSED(fcu), + FModifier *fcm, + float *cvalue, + float UNUSED(evaltime)) { - tFCMED_Cycles *edata = fmodifiers_storage_get(storage, fcm); + tFCMED_Cycles *edata = fmodifiers_storage_get(storage, fcm); - /* use temp data */ - if (edata) { - /* add cyclic offset - no need to check for now, otherwise the data wouldn't exist! */ - *cvalue += edata->cycyofs; + /* use temp data */ + if (edata) { + /* add cyclic offset - no need to check for now, otherwise the data wouldn't exist! */ + *cvalue += edata->cycyofs; - /* free temp data */ - MEM_freeN(edata); - fmodifiers_storage_remove(storage, fcm); - } + /* free temp data */ + MEM_freeN(edata); + fmodifiers_storage_remove(storage, fcm); + } } static FModifierTypeInfo FMI_CYCLES = { - FMODIFIER_TYPE_CYCLES, /* type */ - sizeof(FMod_Cycles), /* size */ - FMI_TYPE_EXTRAPOLATION, /* action type */ - FMI_REQUIRES_ORIGINAL_DATA | FMI_REQUIRES_STORAGE, /* requirements */ - N_("Cycles"), /* name */ - "FMod_Cycles", /* struct name */ - NULL, /* free data */ - NULL, /* copy data */ - fcm_cycles_new_data, /* new data */ - NULL /*fcm_cycles_verify*/, /* verify */ - NULL, /* evaluate time */ - NULL, /* evaluate */ - fcm_cycles_time, /* evaluate time with storage */ - fcm_cycles_evaluate, /* evaluate with storage */ + FMODIFIER_TYPE_CYCLES, /* type */ + sizeof(FMod_Cycles), /* size */ + FMI_TYPE_EXTRAPOLATION, /* action type */ + FMI_REQUIRES_ORIGINAL_DATA | FMI_REQUIRES_STORAGE, /* requirements */ + N_("Cycles"), /* name */ + "FMod_Cycles", /* struct name */ + NULL, /* free data */ + NULL, /* copy data */ + fcm_cycles_new_data, /* new data */ + NULL /*fcm_cycles_verify*/, /* verify */ + NULL, /* evaluate time */ + NULL, /* evaluate */ + fcm_cycles_time, /* evaluate time with storage */ + fcm_cycles_evaluate, /* evaluate with storage */ }; /* Noise F-Curve Modifier --------------------------- */ static void fcm_noise_new_data(void *mdata) { - FMod_Noise *data = (FMod_Noise *)mdata; - - /* defaults */ - data->size = 1.0f; - data->strength = 1.0f; - data->phase = 1.0f; - data->offset = 0.0f; - data->depth = 0; - data->modification = FCM_NOISE_MODIF_REPLACE; + FMod_Noise *data = (FMod_Noise *)mdata; + + /* defaults */ + data->size = 1.0f; + data->strength = 1.0f; + data->phase = 1.0f; + data->offset = 0.0f; + data->depth = 0; + data->modification = FCM_NOISE_MODIF_REPLACE; } static void fcm_noise_evaluate(FCurve *UNUSED(fcu), FModifier *fcm, float *cvalue, float evaltime) { - FMod_Noise *data = (FMod_Noise *)fcm->data; - float noise; - - /* generate noise using good ol' Blender Noise - * - 0.1 is passed as the 'z' value, otherwise evaluation fails for size = phase = 1 - * with evaltime being an integer (which happens when evaluating on frame by frame basis) - */ - noise = BLI_turbulence(data->size, evaltime - data->offset, data->phase, 0.1f, data->depth); - - /* combine the noise with existing motion data */ - switch (data->modification) { - case FCM_NOISE_MODIF_ADD: - *cvalue = *cvalue + noise * data->strength; - break; - case FCM_NOISE_MODIF_SUBTRACT: - *cvalue = *cvalue - noise * data->strength; - break; - case FCM_NOISE_MODIF_MULTIPLY: - *cvalue = *cvalue * noise * data->strength; - break; - case FCM_NOISE_MODIF_REPLACE: - default: - *cvalue = *cvalue + (noise - 0.5f) * data->strength; - break; - } + FMod_Noise *data = (FMod_Noise *)fcm->data; + float noise; + + /* generate noise using good ol' Blender Noise + * - 0.1 is passed as the 'z' value, otherwise evaluation fails for size = phase = 1 + * with evaltime being an integer (which happens when evaluating on frame by frame basis) + */ + noise = BLI_turbulence(data->size, evaltime - data->offset, data->phase, 0.1f, data->depth); + + /* combine the noise with existing motion data */ + switch (data->modification) { + case FCM_NOISE_MODIF_ADD: + *cvalue = *cvalue + noise * data->strength; + break; + case FCM_NOISE_MODIF_SUBTRACT: + *cvalue = *cvalue - noise * data->strength; + break; + case FCM_NOISE_MODIF_MULTIPLY: + *cvalue = *cvalue * noise * data->strength; + break; + case FCM_NOISE_MODIF_REPLACE: + default: + *cvalue = *cvalue + (noise - 0.5f) * data->strength; + break; + } } static FModifierTypeInfo FMI_NOISE = { - FMODIFIER_TYPE_NOISE, /* type */ - sizeof(FMod_Noise), /* size */ - FMI_TYPE_REPLACE_VALUES, /* action type */ - 0, /* requirements */ - N_("Noise"), /* name */ - "FMod_Noise", /* struct name */ - NULL, /* free data */ - NULL, /* copy data */ - fcm_noise_new_data, /* new data */ - NULL /*fcm_noise_verify*/, /* verify */ - NULL, /* evaluate time */ - fcm_noise_evaluate, /* evaluate */ - NULL, /* evaluate time with storage */ - NULL, /* evaluate with storage */ + FMODIFIER_TYPE_NOISE, /* type */ + sizeof(FMod_Noise), /* size */ + FMI_TYPE_REPLACE_VALUES, /* action type */ + 0, /* requirements */ + N_("Noise"), /* name */ + "FMod_Noise", /* struct name */ + NULL, /* free data */ + NULL, /* copy data */ + fcm_noise_new_data, /* new data */ + NULL /*fcm_noise_verify*/, /* verify */ + NULL, /* evaluate time */ + fcm_noise_evaluate, /* evaluate */ + NULL, /* evaluate time with storage */ + NULL, /* evaluate with storage */ }; - /* Python F-Curve Modifier --------------------------- */ static void fcm_python_free(FModifier *fcm) { - FMod_Python *data = (FMod_Python *)fcm->data; + FMod_Python *data = (FMod_Python *)fcm->data; - /* id-properties */ - IDP_FreeProperty(data->prop); - MEM_freeN(data->prop); + /* id-properties */ + IDP_FreeProperty(data->prop); + MEM_freeN(data->prop); } static void fcm_python_new_data(void *mdata) { - FMod_Python *data = (FMod_Python *)mdata; + FMod_Python *data = (FMod_Python *)mdata; - /* everything should be set correctly by calloc, except for the prop->type constant.*/ - data->prop = MEM_callocN(sizeof(IDProperty), "PyFModifierProps"); - data->prop->type = IDP_GROUP; + /* everything should be set correctly by calloc, except for the prop->type constant.*/ + data->prop = MEM_callocN(sizeof(IDProperty), "PyFModifierProps"); + data->prop->type = IDP_GROUP; } static void fcm_python_copy(FModifier *fcm, const FModifier *src) { - FMod_Python *pymod = (FMod_Python *)fcm->data; - FMod_Python *opymod = (FMod_Python *)src->data; + FMod_Python *pymod = (FMod_Python *)fcm->data; + FMod_Python *opymod = (FMod_Python *)src->data; - pymod->prop = IDP_CopyProperty(opymod->prop); + pymod->prop = IDP_CopyProperty(opymod->prop); } -static void fcm_python_evaluate(FCurve *UNUSED(fcu), FModifier *UNUSED(fcm), float *UNUSED(cvalue), float UNUSED(evaltime)) +static void fcm_python_evaluate(FCurve *UNUSED(fcu), + FModifier *UNUSED(fcm), + float *UNUSED(cvalue), + float UNUSED(evaltime)) { #ifdef WITH_PYTHON - //FMod_Python *data = (FMod_Python *)fcm->data; + //FMod_Python *data = (FMod_Python *)fcm->data; - /* FIXME... need to implement this modifier... - * It will need it execute a script using the custom properties - */ + /* FIXME... need to implement this modifier... + * It will need it execute a script using the custom properties + */ #endif /* WITH_PYTHON */ } static FModifierTypeInfo FMI_PYTHON = { - FMODIFIER_TYPE_PYTHON, /* type */ - sizeof(FMod_Python), /* size */ - FMI_TYPE_GENERATE_CURVE, /* action type */ - FMI_REQUIRES_RUNTIME_CHECK, /* requirements */ - N_("Python"), /* name */ - "FMod_Python", /* struct name */ - fcm_python_free, /* free data */ - fcm_python_copy, /* copy data */ - fcm_python_new_data, /* new data */ - NULL /*fcm_python_verify*/, /* verify */ - NULL /*fcm_python_time*/, /* evaluate time */ - fcm_python_evaluate, /* evaluate */ - NULL, /* evaluate time with storage */ - NULL, /* evaluate with storage */ + FMODIFIER_TYPE_PYTHON, /* type */ + sizeof(FMod_Python), /* size */ + FMI_TYPE_GENERATE_CURVE, /* action type */ + FMI_REQUIRES_RUNTIME_CHECK, /* requirements */ + N_("Python"), /* name */ + "FMod_Python", /* struct name */ + fcm_python_free, /* free data */ + fcm_python_copy, /* copy data */ + fcm_python_new_data, /* new data */ + NULL /*fcm_python_verify*/, /* verify */ + NULL /*fcm_python_time*/, /* evaluate time */ + fcm_python_evaluate, /* evaluate */ + NULL, /* evaluate time with storage */ + NULL, /* evaluate with storage */ }; - /* Limits F-Curve Modifier --------------------------- */ -static float fcm_limits_time(FCurve *UNUSED(fcu), FModifier *fcm, float UNUSED(cvalue), float evaltime) +static float fcm_limits_time(FCurve *UNUSED(fcu), + FModifier *fcm, + float UNUSED(cvalue), + float evaltime) { - FMod_Limits *data = (FMod_Limits *)fcm->data; + FMod_Limits *data = (FMod_Limits *)fcm->data; - /* check for the time limits */ - if ((data->flag & FCM_LIMIT_XMIN) && (evaltime < data->rect.xmin)) - return data->rect.xmin; - if ((data->flag & FCM_LIMIT_XMAX) && (evaltime > data->rect.xmax)) - return data->rect.xmax; + /* check for the time limits */ + if ((data->flag & FCM_LIMIT_XMIN) && (evaltime < data->rect.xmin)) + return data->rect.xmin; + if ((data->flag & FCM_LIMIT_XMAX) && (evaltime > data->rect.xmax)) + return data->rect.xmax; - /* modifier doesn't change time */ - return evaltime; + /* modifier doesn't change time */ + return evaltime; } -static void fcm_limits_evaluate(FCurve *UNUSED(fcu), FModifier *fcm, float *cvalue, float UNUSED(evaltime)) +static void fcm_limits_evaluate(FCurve *UNUSED(fcu), + FModifier *fcm, + float *cvalue, + float UNUSED(evaltime)) { - FMod_Limits *data = (FMod_Limits *)fcm->data; + FMod_Limits *data = (FMod_Limits *)fcm->data; - /* value limits now */ - if ((data->flag & FCM_LIMIT_YMIN) && (*cvalue < data->rect.ymin)) - *cvalue = data->rect.ymin; - if ((data->flag & FCM_LIMIT_YMAX) && (*cvalue > data->rect.ymax)) - *cvalue = data->rect.ymax; + /* value limits now */ + if ((data->flag & FCM_LIMIT_YMIN) && (*cvalue < data->rect.ymin)) + *cvalue = data->rect.ymin; + if ((data->flag & FCM_LIMIT_YMAX) && (*cvalue > data->rect.ymax)) + *cvalue = data->rect.ymax; } static FModifierTypeInfo FMI_LIMITS = { - FMODIFIER_TYPE_LIMITS, /* type */ - sizeof(FMod_Limits), /* size */ - FMI_TYPE_GENERATE_CURVE, /* action type */ /* XXX... err... */ - FMI_REQUIRES_RUNTIME_CHECK, /* requirements */ - N_("Limits"), /* name */ - "FMod_Limits", /* struct name */ - NULL, /* free data */ - NULL, /* copy data */ - NULL, /* new data */ - NULL, /* verify */ - fcm_limits_time, /* evaluate time */ - fcm_limits_evaluate, /* evaluate */ - NULL, /* evaluate time with storage */ - NULL, /* evaluate with storage */ + FMODIFIER_TYPE_LIMITS, /* type */ + sizeof(FMod_Limits), /* size */ + FMI_TYPE_GENERATE_CURVE, + /* action type */ /* XXX... err... */ + FMI_REQUIRES_RUNTIME_CHECK, /* requirements */ + N_("Limits"), /* name */ + "FMod_Limits", /* struct name */ + NULL, /* free data */ + NULL, /* copy data */ + NULL, /* new data */ + NULL, /* verify */ + fcm_limits_time, /* evaluate time */ + fcm_limits_evaluate, /* evaluate */ + NULL, /* evaluate time with storage */ + NULL, /* evaluate with storage */ }; /* Stepped F-Curve Modifier --------------------------- */ static void fcm_stepped_new_data(void *mdata) { - FMod_Stepped *data = (FMod_Stepped *)mdata; + FMod_Stepped *data = (FMod_Stepped *)mdata; - /* just need to set the step-size to 2-frames by default */ - /* XXX: or would 5 be more normal? */ - data->step_size = 2.0f; + /* just need to set the step-size to 2-frames by default */ + /* XXX: or would 5 be more normal? */ + data->step_size = 2.0f; } -static float fcm_stepped_time(FCurve *UNUSED(fcu), FModifier *fcm, float UNUSED(cvalue), float evaltime) +static float fcm_stepped_time(FCurve *UNUSED(fcu), + FModifier *fcm, + float UNUSED(cvalue), + float evaltime) { - FMod_Stepped *data = (FMod_Stepped *)fcm->data; - int snapblock; - - /* check range clamping to see if we should alter the timing to achieve the desired results */ - if (data->flag & FCM_STEPPED_NO_BEFORE) { - if (evaltime < data->start_frame) - return evaltime; - } - if (data->flag & FCM_STEPPED_NO_AFTER) { - if (evaltime > data->end_frame) - return evaltime; - } - - /* we snap to the start of the previous closest block of 'step_size' frames - * after the start offset has been discarded - * - i.e. round down - */ - snapblock = (int)((evaltime - data->offset) / data->step_size); - - /* reapply the offset, and multiple the snapblock by the size of the steps to get - * the new time to evaluate at - */ - return ((float)snapblock * data->step_size) + data->offset; + FMod_Stepped *data = (FMod_Stepped *)fcm->data; + int snapblock; + + /* check range clamping to see if we should alter the timing to achieve the desired results */ + if (data->flag & FCM_STEPPED_NO_BEFORE) { + if (evaltime < data->start_frame) + return evaltime; + } + if (data->flag & FCM_STEPPED_NO_AFTER) { + if (evaltime > data->end_frame) + return evaltime; + } + + /* we snap to the start of the previous closest block of 'step_size' frames + * after the start offset has been discarded + * - i.e. round down + */ + snapblock = (int)((evaltime - data->offset) / data->step_size); + + /* reapply the offset, and multiple the snapblock by the size of the steps to get + * the new time to evaluate at + */ + return ((float)snapblock * data->step_size) + data->offset; } static FModifierTypeInfo FMI_STEPPED = { - FMODIFIER_TYPE_STEPPED, /* type */ - sizeof(FMod_Limits), /* size */ - FMI_TYPE_GENERATE_CURVE, /* action type */ /* XXX... err... */ - FMI_REQUIRES_RUNTIME_CHECK, /* requirements */ - N_("Stepped"), /* name */ - "FMod_Stepped", /* struct name */ - NULL, /* free data */ - NULL, /* copy data */ - fcm_stepped_new_data, /* new data */ - NULL, /* verify */ - fcm_stepped_time, /* evaluate time */ - NULL, /* evaluate */ - NULL, /* evaluate time with storage */ - NULL, /* evaluate with storage */ + FMODIFIER_TYPE_STEPPED, /* type */ + sizeof(FMod_Limits), /* size */ + FMI_TYPE_GENERATE_CURVE, + /* action type */ /* XXX... err... */ + FMI_REQUIRES_RUNTIME_CHECK, /* requirements */ + N_("Stepped"), /* name */ + "FMod_Stepped", /* struct name */ + NULL, /* free data */ + NULL, /* copy data */ + fcm_stepped_new_data, /* new data */ + NULL, /* verify */ + fcm_stepped_time, /* evaluate time */ + NULL, /* evaluate */ + NULL, /* evaluate time with storage */ + NULL, /* evaluate with storage */ }; /* F-Curve Modifier API --------------------------- */ @@ -1002,16 +1036,16 @@ static short FMI_INIT = 1; /* when non-zero, the list needs to be updated */ /* This function only gets called when FMI_INIT is non-zero */ static void fmods_init_typeinfo(void) { - fmodifiersTypeInfo[0] = NULL; /* 'Null' F-Curve Modifier */ - fmodifiersTypeInfo[1] = &FMI_GENERATOR; /* Generator F-Curve Modifier */ - fmodifiersTypeInfo[2] = &FMI_FN_GENERATOR; /* Built-In Function Generator F-Curve Modifier */ - fmodifiersTypeInfo[3] = &FMI_ENVELOPE; /* Envelope F-Curve Modifier */ - fmodifiersTypeInfo[4] = &FMI_CYCLES; /* Cycles F-Curve Modifier */ - fmodifiersTypeInfo[5] = &FMI_NOISE; /* Apply-Noise F-Curve Modifier */ - fmodifiersTypeInfo[6] = NULL /*&FMI_FILTER*/; /* Filter F-Curve Modifier */ // XXX unimplemented - fmodifiersTypeInfo[7] = &FMI_PYTHON; /* Custom Python F-Curve Modifier */ - fmodifiersTypeInfo[8] = &FMI_LIMITS; /* Limits F-Curve Modifier */ - fmodifiersTypeInfo[9] = &FMI_STEPPED; /* Stepped F-Curve Modifier */ + fmodifiersTypeInfo[0] = NULL; /* 'Null' F-Curve Modifier */ + fmodifiersTypeInfo[1] = &FMI_GENERATOR; /* Generator F-Curve Modifier */ + fmodifiersTypeInfo[2] = &FMI_FN_GENERATOR; /* Built-In Function Generator F-Curve Modifier */ + fmodifiersTypeInfo[3] = &FMI_ENVELOPE; /* Envelope F-Curve Modifier */ + fmodifiersTypeInfo[4] = &FMI_CYCLES; /* Cycles F-Curve Modifier */ + fmodifiersTypeInfo[5] = &FMI_NOISE; /* Apply-Noise F-Curve Modifier */ + fmodifiersTypeInfo[6] = NULL /*&FMI_FILTER*/; /* Filter F-Curve Modifier */ // XXX unimplemented + fmodifiersTypeInfo[7] = &FMI_PYTHON; /* Custom Python F-Curve Modifier */ + fmodifiersTypeInfo[8] = &FMI_LIMITS; /* Limits F-Curve Modifier */ + fmodifiersTypeInfo[9] = &FMI_STEPPED; /* Stepped F-Curve Modifier */ } /* This function should be used for getting the appropriate type-info when only @@ -1019,24 +1053,22 @@ static void fmods_init_typeinfo(void) */ const FModifierTypeInfo *get_fmodifier_typeinfo(const int type) { - /* initialize the type-info list? */ - if (FMI_INIT) { - fmods_init_typeinfo(); - FMI_INIT = 0; - } - - /* only return for valid types */ - if ((type >= FMODIFIER_TYPE_NULL) && - (type < FMODIFIER_NUM_TYPES)) - { - /* there shouldn't be any segfaults here... */ - return fmodifiersTypeInfo[type]; - } - else { - CLOG_ERROR(&LOG, "No valid F-Curve Modifier type-info data available. Type = %i", type); - } - - return NULL; + /* initialize the type-info list? */ + if (FMI_INIT) { + fmods_init_typeinfo(); + FMI_INIT = 0; + } + + /* only return for valid types */ + if ((type >= FMODIFIER_TYPE_NULL) && (type < FMODIFIER_NUM_TYPES)) { + /* there shouldn't be any segfaults here... */ + return fmodifiersTypeInfo[type]; + } + else { + CLOG_ERROR(&LOG, "No valid F-Curve Modifier type-info data available. Type = %i", type); + } + + return NULL; } /* This function should always be used to get the appropriate type-info, as it @@ -1044,11 +1076,11 @@ const FModifierTypeInfo *get_fmodifier_typeinfo(const int type) */ const FModifierTypeInfo *fmodifier_get_typeinfo(const FModifier *fcm) { - /* only return typeinfo for valid modifiers */ - if (fcm) - return get_fmodifier_typeinfo(fcm->type); - else - return NULL; + /* only return typeinfo for valid modifiers */ + if (fcm) + return get_fmodifier_typeinfo(fcm->type); + else + return NULL; } /* API --------------------------- */ @@ -1056,188 +1088,191 @@ const FModifierTypeInfo *fmodifier_get_typeinfo(const FModifier *fcm) /* Add a new F-Curve Modifier to the given F-Curve of a certain type */ FModifier *add_fmodifier(ListBase *modifiers, int type, FCurve *owner_fcu) { - const FModifierTypeInfo *fmi = get_fmodifier_typeinfo(type); - FModifier *fcm; - - /* sanity checks */ - if (ELEM(NULL, modifiers, fmi)) - return NULL; - - /* special checks for whether modifier can be added */ - if ((modifiers->first) && (type == FMODIFIER_TYPE_CYCLES)) { - /* cycles modifier must be first in stack, so for now, don't add if it can't be */ - /* TODO: perhaps there is some better way, but for now, */ - CLOG_STR_ERROR(&LOG, "Cannot add 'Cycles' modifier to F-Curve, as 'Cycles' modifier can only be first in stack."); - return NULL; - } - - /* add modifier itself */ - fcm = MEM_callocN(sizeof(FModifier), "F-Curve Modifier"); - fcm->type = type; - fcm->flag = FMODIFIER_FLAG_EXPANDED; - fcm->curve = owner_fcu; - fcm->influence = 1.0f; - BLI_addtail(modifiers, fcm); - - /* tag modifier as "active" if no other modifiers exist in the stack yet */ - if (BLI_listbase_is_single(modifiers)) - fcm->flag |= FMODIFIER_FLAG_ACTIVE; - - /* add modifier's data */ - fcm->data = MEM_callocN(fmi->size, fmi->structName); - - /* init custom settings if necessary */ - if (fmi->new_data) - fmi->new_data(fcm->data); - - /* update the fcurve if the Cycles modifier is added */ - if ((owner_fcu) && (type == FMODIFIER_TYPE_CYCLES)) - calchandles_fcurve(owner_fcu); - - /* return modifier for further editing */ - return fcm; + const FModifierTypeInfo *fmi = get_fmodifier_typeinfo(type); + FModifier *fcm; + + /* sanity checks */ + if (ELEM(NULL, modifiers, fmi)) + return NULL; + + /* special checks for whether modifier can be added */ + if ((modifiers->first) && (type == FMODIFIER_TYPE_CYCLES)) { + /* cycles modifier must be first in stack, so for now, don't add if it can't be */ + /* TODO: perhaps there is some better way, but for now, */ + CLOG_STR_ERROR(&LOG, + "Cannot add 'Cycles' modifier to F-Curve, as 'Cycles' modifier can only be " + "first in stack."); + return NULL; + } + + /* add modifier itself */ + fcm = MEM_callocN(sizeof(FModifier), "F-Curve Modifier"); + fcm->type = type; + fcm->flag = FMODIFIER_FLAG_EXPANDED; + fcm->curve = owner_fcu; + fcm->influence = 1.0f; + BLI_addtail(modifiers, fcm); + + /* tag modifier as "active" if no other modifiers exist in the stack yet */ + if (BLI_listbase_is_single(modifiers)) + fcm->flag |= FMODIFIER_FLAG_ACTIVE; + + /* add modifier's data */ + fcm->data = MEM_callocN(fmi->size, fmi->structName); + + /* init custom settings if necessary */ + if (fmi->new_data) + fmi->new_data(fcm->data); + + /* update the fcurve if the Cycles modifier is added */ + if ((owner_fcu) && (type == FMODIFIER_TYPE_CYCLES)) + calchandles_fcurve(owner_fcu); + + /* return modifier for further editing */ + return fcm; } /* Make a copy of the specified F-Modifier */ FModifier *copy_fmodifier(const FModifier *src) { - const FModifierTypeInfo *fmi = fmodifier_get_typeinfo(src); - FModifier *dst; + const FModifierTypeInfo *fmi = fmodifier_get_typeinfo(src); + FModifier *dst; - /* sanity check */ - if (src == NULL) - return NULL; + /* sanity check */ + if (src == NULL) + return NULL; - /* copy the base data, clearing the links */ - dst = MEM_dupallocN(src); - dst->next = dst->prev = NULL; - dst->curve = NULL; + /* copy the base data, clearing the links */ + dst = MEM_dupallocN(src); + dst->next = dst->prev = NULL; + dst->curve = NULL; - /* make a new copy of the F-Modifier's data */ - dst->data = MEM_dupallocN(src->data); + /* make a new copy of the F-Modifier's data */ + dst->data = MEM_dupallocN(src->data); - /* only do specific constraints if required */ - if (fmi && fmi->copy_data) - fmi->copy_data(dst, src); + /* only do specific constraints if required */ + if (fmi && fmi->copy_data) + fmi->copy_data(dst, src); - /* return the new modifier */ - return dst; + /* return the new modifier */ + return dst; } /* Duplicate all of the F-Modifiers in the Modifier stacks */ void copy_fmodifiers(ListBase *dst, const ListBase *src) { - FModifier *fcm, *srcfcm; + FModifier *fcm, *srcfcm; - if (ELEM(NULL, dst, src)) - return; + if (ELEM(NULL, dst, src)) + return; - BLI_listbase_clear(dst); - BLI_duplicatelist(dst, src); + BLI_listbase_clear(dst); + BLI_duplicatelist(dst, src); - for (fcm = dst->first, srcfcm = src->first; fcm && srcfcm; srcfcm = srcfcm->next, fcm = fcm->next) { - const FModifierTypeInfo *fmi = fmodifier_get_typeinfo(fcm); + for (fcm = dst->first, srcfcm = src->first; fcm && srcfcm; + srcfcm = srcfcm->next, fcm = fcm->next) { + const FModifierTypeInfo *fmi = fmodifier_get_typeinfo(fcm); - /* make a new copy of the F-Modifier's data */ - fcm->data = MEM_dupallocN(fcm->data); - fcm->curve = NULL; + /* make a new copy of the F-Modifier's data */ + fcm->data = MEM_dupallocN(fcm->data); + fcm->curve = NULL; - /* only do specific constraints if required */ - if (fmi && fmi->copy_data) - fmi->copy_data(fcm, srcfcm); - } + /* only do specific constraints if required */ + if (fmi && fmi->copy_data) + fmi->copy_data(fcm, srcfcm); + } } /* Remove and free the given F-Modifier from the given stack */ bool remove_fmodifier(ListBase *modifiers, FModifier *fcm) { - const FModifierTypeInfo *fmi = fmodifier_get_typeinfo(fcm); - - /* sanity check */ - if (fcm == NULL) - return false; - - /* removing the cycles modifier requires a handle update */ - FCurve *update_fcu = (fcm->type == FMODIFIER_TYPE_CYCLES) ? fcm->curve : NULL; - - /* free modifier's special data (stored inside fcm->data) */ - if (fcm->data) { - if (fmi && fmi->free_data) - fmi->free_data(fcm); - - /* free modifier's data (fcm->data) */ - MEM_freeN(fcm->data); - } - - /* remove modifier from stack */ - if (modifiers) { - BLI_freelinkN(modifiers, fcm); - - /* update the fcurve if the Cycles modifier is removed */ - if (update_fcu) - calchandles_fcurve(update_fcu); - - return true; - } - else { - /* XXX this case can probably be removed some day, as it shouldn't happen... */ - CLOG_STR_ERROR(&LOG, "no modifier stack given"); - MEM_freeN(fcm); - return false; - } + const FModifierTypeInfo *fmi = fmodifier_get_typeinfo(fcm); + + /* sanity check */ + if (fcm == NULL) + return false; + + /* removing the cycles modifier requires a handle update */ + FCurve *update_fcu = (fcm->type == FMODIFIER_TYPE_CYCLES) ? fcm->curve : NULL; + + /* free modifier's special data (stored inside fcm->data) */ + if (fcm->data) { + if (fmi && fmi->free_data) + fmi->free_data(fcm); + + /* free modifier's data (fcm->data) */ + MEM_freeN(fcm->data); + } + + /* remove modifier from stack */ + if (modifiers) { + BLI_freelinkN(modifiers, fcm); + + /* update the fcurve if the Cycles modifier is removed */ + if (update_fcu) + calchandles_fcurve(update_fcu); + + return true; + } + else { + /* XXX this case can probably be removed some day, as it shouldn't happen... */ + CLOG_STR_ERROR(&LOG, "no modifier stack given"); + MEM_freeN(fcm); + return false; + } } /* Remove all of a given F-Curve's modifiers */ void free_fmodifiers(ListBase *modifiers) { - FModifier *fcm, *fmn; + FModifier *fcm, *fmn; - /* sanity check */ - if (modifiers == NULL) - return; + /* sanity check */ + if (modifiers == NULL) + return; - /* free each modifier in order - modifier is unlinked from list and freed */ - for (fcm = modifiers->first; fcm; fcm = fmn) { - fmn = fcm->next; - remove_fmodifier(modifiers, fcm); - } + /* free each modifier in order - modifier is unlinked from list and freed */ + for (fcm = modifiers->first; fcm; fcm = fmn) { + fmn = fcm->next; + remove_fmodifier(modifiers, fcm); + } } /* Find the active F-Modifier */ FModifier *find_active_fmodifier(ListBase *modifiers) { - FModifier *fcm; + FModifier *fcm; - /* sanity checks */ - if (ELEM(NULL, modifiers, modifiers->first)) - return NULL; + /* sanity checks */ + if (ELEM(NULL, modifiers, modifiers->first)) + return NULL; - /* loop over modifiers until 'active' one is found */ - for (fcm = modifiers->first; fcm; fcm = fcm->next) { - if (fcm->flag & FMODIFIER_FLAG_ACTIVE) - return fcm; - } + /* loop over modifiers until 'active' one is found */ + for (fcm = modifiers->first; fcm; fcm = fcm->next) { + if (fcm->flag & FMODIFIER_FLAG_ACTIVE) + return fcm; + } - /* no modifier is active */ - return NULL; + /* no modifier is active */ + return NULL; } /* Set the active F-Modifier */ void set_active_fmodifier(ListBase *modifiers, FModifier *fcm) { - FModifier *fm; + FModifier *fm; - /* sanity checks */ - if (ELEM(NULL, modifiers, modifiers->first)) - return; + /* sanity checks */ + if (ELEM(NULL, modifiers, modifiers->first)) + return; - /* deactivate all, and set current one active */ - for (fm = modifiers->first; fm; fm = fm->next) - fm->flag &= ~FMODIFIER_FLAG_ACTIVE; + /* deactivate all, and set current one active */ + for (fm = modifiers->first; fm; fm = fm->next) + fm->flag &= ~FMODIFIER_FLAG_ACTIVE; - /* make given modifier active */ - if (fcm) - fcm->flag |= FMODIFIER_FLAG_ACTIVE; + /* make given modifier active */ + if (fcm) + fcm->flag |= FMODIFIER_FLAG_ACTIVE; } /* Do we have any modifiers which match certain criteria @@ -1246,131 +1281,130 @@ void set_active_fmodifier(ListBase *modifiers, FModifier *fcm) */ bool list_has_suitable_fmodifier(ListBase *modifiers, int mtype, short acttype) { - FModifier *fcm; - - /* if there are no specific filtering criteria, just skip */ - if ((mtype == 0) && (acttype == 0)) - return (modifiers && modifiers->first); - - /* sanity checks */ - if (ELEM(NULL, modifiers, modifiers->first)) - return false; - - /* find the first mdifier fitting these criteria */ - for (fcm = modifiers->first; fcm; fcm = fcm->next) { - const FModifierTypeInfo *fmi = fmodifier_get_typeinfo(fcm); - short mOk = 1, aOk = 1; /* by default 1, so that when only one test, won't fail */ - - /* check if applicable ones are fulfilled */ - if (mtype) - mOk = (fcm->type == mtype); - if (acttype > -1) - aOk = (fmi->acttype == acttype); - - /* if both are ok, we've found a hit */ - if (mOk && aOk) - return true; - } - - /* no matches */ - return false; + FModifier *fcm; + + /* if there are no specific filtering criteria, just skip */ + if ((mtype == 0) && (acttype == 0)) + return (modifiers && modifiers->first); + + /* sanity checks */ + if (ELEM(NULL, modifiers, modifiers->first)) + return false; + + /* find the first mdifier fitting these criteria */ + for (fcm = modifiers->first; fcm; fcm = fcm->next) { + const FModifierTypeInfo *fmi = fmodifier_get_typeinfo(fcm); + short mOk = 1, aOk = 1; /* by default 1, so that when only one test, won't fail */ + + /* check if applicable ones are fulfilled */ + if (mtype) + mOk = (fcm->type == mtype); + if (acttype > -1) + aOk = (fmi->acttype == acttype); + + /* if both are ok, we've found a hit */ + if (mOk && aOk) + return true; + } + + /* no matches */ + return false; } /* Evaluation API --------------------------- */ FModifierStackStorage *evaluate_fmodifiers_storage_new(ListBase *modifiers) { - FModifier *fcm; + FModifier *fcm; - /* Sanity checks. */ - if (ELEM(NULL, modifiers, modifiers->last)) { - return NULL; - } + /* Sanity checks. */ + if (ELEM(NULL, modifiers, modifiers->last)) { + return NULL; + } - for (fcm = modifiers->last; fcm; fcm = fcm->prev) { - const FModifierTypeInfo *fmi = fmodifier_get_typeinfo(fcm); + for (fcm = modifiers->last; fcm; fcm = fcm->prev) { + const FModifierTypeInfo *fmi = fmodifier_get_typeinfo(fcm); - if (fmi == NULL) { - continue; - } + if (fmi == NULL) { + continue; + } - if (fmi->requires & FMI_REQUIRES_STORAGE) { - return (FModifierStackStorage *) BLI_ghash_new(BLI_ghashutil_ptrhash, - BLI_ghashutil_ptrcmp, - "fmodifier stack temp storage"); - } - } + if (fmi->requires & FMI_REQUIRES_STORAGE) { + return (FModifierStackStorage *)BLI_ghash_new( + BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "fmodifier stack temp storage"); + } + } - return NULL; + return NULL; } void evaluate_fmodifiers_storage_free(FModifierStackStorage *storage) { - if (storage != NULL) { - BLI_ghash_free((GHash *) storage, NULL, NULL); - } + if (storage != NULL) { + BLI_ghash_free((GHash *)storage, NULL, NULL); + } } void fmodifiers_storage_put(FModifierStackStorage *storage, FModifier *fcm, void *data) { - BLI_assert(storage != NULL); + BLI_assert(storage != NULL); - BLI_ghash_insert((GHash *) storage, fcm, data); + BLI_ghash_insert((GHash *)storage, fcm, data); } void fmodifiers_storage_remove(FModifierStackStorage *storage, FModifier *fcm) { - BLI_assert(storage != NULL); + BLI_assert(storage != NULL); - BLI_ghash_remove((GHash *) storage, fcm, NULL, NULL); + BLI_ghash_remove((GHash *)storage, fcm, NULL, NULL); } void *fmodifiers_storage_get(FModifierStackStorage *storage, FModifier *fcm) { - BLI_assert(storage != NULL); + BLI_assert(storage != NULL); - return BLI_ghash_lookup((GHash *) storage, fcm); + return BLI_ghash_lookup((GHash *)storage, fcm); } /* helper function - calculate influence of FModifier */ static float eval_fmodifier_influence(FModifier *fcm, float evaltime) { - float influence; - - /* sanity check */ - if (fcm == NULL) - return 0.0f; - - /* should we use influence stored in modifier or not - * NOTE: this is really just a hack so that we don't need to version patch old files ;) - */ - if (fcm->flag & FMODIFIER_FLAG_USEINFLUENCE) - influence = fcm->influence; - else - influence = 1.0f; - - /* restricted range or full range? */ - if (fcm->flag & FMODIFIER_FLAG_RANGERESTRICT) { - if ((evaltime <= fcm->sfra) || (evaltime >= fcm->efra)) { - /* out of range */ - return 0.0f; - } - else if ((evaltime > fcm->sfra) && (evaltime < fcm->sfra + fcm->blendin)) { - /* blend in range */ - float a = fcm->sfra; - float b = fcm->sfra + fcm->blendin; - return influence * (evaltime - a) / (b - a); - } - else if ((evaltime < fcm->efra) && (evaltime > fcm->efra - fcm->blendout)) { - /* blend out range */ - float a = fcm->efra; - float b = fcm->efra - fcm->blendout; - return influence * (evaltime - a) / (b - a); - } - } - - /* just return the influence of the modifier */ - return influence; + float influence; + + /* sanity check */ + if (fcm == NULL) + return 0.0f; + + /* should we use influence stored in modifier or not + * NOTE: this is really just a hack so that we don't need to version patch old files ;) + */ + if (fcm->flag & FMODIFIER_FLAG_USEINFLUENCE) + influence = fcm->influence; + else + influence = 1.0f; + + /* restricted range or full range? */ + if (fcm->flag & FMODIFIER_FLAG_RANGERESTRICT) { + if ((evaltime <= fcm->sfra) || (evaltime >= fcm->efra)) { + /* out of range */ + return 0.0f; + } + else if ((evaltime > fcm->sfra) && (evaltime < fcm->sfra + fcm->blendin)) { + /* blend in range */ + float a = fcm->sfra; + float b = fcm->sfra + fcm->blendin; + return influence * (evaltime - a) / (b - a); + } + else if ((evaltime < fcm->efra) && (evaltime > fcm->efra - fcm->blendout)) { + /* blend out range */ + float a = fcm->efra; + float b = fcm->efra - fcm->blendout; + return influence * (evaltime - a) / (b - a); + } + } + + /* just return the influence of the modifier */ + return influence; } /* evaluate time modifications imposed by some F-Curve Modifiers @@ -1384,106 +1418,107 @@ static float eval_fmodifier_influence(FModifier *fcm, float evaltime) * * Note: *fcu might be NULL */ -float evaluate_time_fmodifiers(FModifierStackStorage *storage, ListBase *modifiers, - FCurve *fcu, float cvalue, float evaltime) +float evaluate_time_fmodifiers( + FModifierStackStorage *storage, ListBase *modifiers, FCurve *fcu, float cvalue, float evaltime) { - FModifier *fcm; - - /* sanity checks */ - if (ELEM(NULL, modifiers, modifiers->last)) - return evaltime; - - if (fcu && fcu->flag & FCURVE_MOD_OFF) - return evaltime; - - /* Starting from the end of the stack, calculate the time effects of various stacked modifiers - * on the time the F-Curve should be evaluated at. - * - * This is done in reverse order to standard evaluation, as when this is done in standard - * order, each modifier would cause jumps to other points in the curve, forcing all - * previous ones to be evaluated again for them to be correct. However, if we did in the - * reverse order as we have here, we can consider them a macro to micro type of waterfall - * effect, which should get us the desired effects when using layered time manipulations - * (such as multiple 'stepped' modifiers in sequence, causing different stepping rates) - */ - for (fcm = modifiers->last; fcm; fcm = fcm->prev) { - const FModifierTypeInfo *fmi = fmodifier_get_typeinfo(fcm); - - if (fmi == NULL) - continue; - - /* if modifier cannot be applied on this frame (whatever scale it is on, it won't affect the results) - * hence we shouldn't bother seeing what it would do given the chance - */ - if ((fcm->flag & FMODIFIER_FLAG_RANGERESTRICT) == 0 || - ((fcm->sfra <= evaltime) && (fcm->efra >= evaltime)) ) - { - /* only evaluate if there's a callback for this */ - if (fmi->evaluate_modifier_time || fmi->evaluate_modifier_time_storage) { - if ((fcm->flag & (FMODIFIER_FLAG_DISABLED | FMODIFIER_FLAG_MUTED)) == 0) { - float influence = eval_fmodifier_influence(fcm, evaltime); - float nval; - - if ((fmi->requires & FMI_REQUIRES_STORAGE) == 0) { - nval = fmi->evaluate_modifier_time(fcu, fcm, cvalue, evaltime); - } - else { - nval = fmi->evaluate_modifier_time_storage(storage, fcu, fcm, cvalue, evaltime); - } - - evaltime = interpf(nval, evaltime, influence); - } - } - } - } - - /* return the modified evaltime */ - return evaltime; + FModifier *fcm; + + /* sanity checks */ + if (ELEM(NULL, modifiers, modifiers->last)) + return evaltime; + + if (fcu && fcu->flag & FCURVE_MOD_OFF) + return evaltime; + + /* Starting from the end of the stack, calculate the time effects of various stacked modifiers + * on the time the F-Curve should be evaluated at. + * + * This is done in reverse order to standard evaluation, as when this is done in standard + * order, each modifier would cause jumps to other points in the curve, forcing all + * previous ones to be evaluated again for them to be correct. However, if we did in the + * reverse order as we have here, we can consider them a macro to micro type of waterfall + * effect, which should get us the desired effects when using layered time manipulations + * (such as multiple 'stepped' modifiers in sequence, causing different stepping rates) + */ + for (fcm = modifiers->last; fcm; fcm = fcm->prev) { + const FModifierTypeInfo *fmi = fmodifier_get_typeinfo(fcm); + + if (fmi == NULL) + continue; + + /* if modifier cannot be applied on this frame (whatever scale it is on, it won't affect the results) + * hence we shouldn't bother seeing what it would do given the chance + */ + if ((fcm->flag & FMODIFIER_FLAG_RANGERESTRICT) == 0 || + ((fcm->sfra <= evaltime) && (fcm->efra >= evaltime))) { + /* only evaluate if there's a callback for this */ + if (fmi->evaluate_modifier_time || fmi->evaluate_modifier_time_storage) { + if ((fcm->flag & (FMODIFIER_FLAG_DISABLED | FMODIFIER_FLAG_MUTED)) == 0) { + float influence = eval_fmodifier_influence(fcm, evaltime); + float nval; + + if ((fmi->requires & FMI_REQUIRES_STORAGE) == 0) { + nval = fmi->evaluate_modifier_time(fcu, fcm, cvalue, evaltime); + } + else { + nval = fmi->evaluate_modifier_time_storage(storage, fcu, fcm, cvalue, evaltime); + } + + evaltime = interpf(nval, evaltime, influence); + } + } + } + } + + /* return the modified evaltime */ + return evaltime; } /* Evaluates the given set of F-Curve Modifiers using the given data * Should only be called after evaluate_time_fmodifiers() has been called... */ -void evaluate_value_fmodifiers(FModifierStackStorage *storage, ListBase *modifiers, - FCurve *fcu, float *cvalue, float evaltime) +void evaluate_value_fmodifiers(FModifierStackStorage *storage, + ListBase *modifiers, + FCurve *fcu, + float *cvalue, + float evaltime) { - FModifier *fcm; - - /* sanity checks */ - if (ELEM(NULL, modifiers, modifiers->first)) - return; - - if (fcu->flag & FCURVE_MOD_OFF) - return; - - /* evaluate modifiers */ - for (fcm = modifiers->first; fcm; fcm = fcm->next) { - const FModifierTypeInfo *fmi = fmodifier_get_typeinfo(fcm); - - if (fmi == NULL) - continue; - - /* only evaluate if there's a callback for this, and if F-Modifier can be evaluated on this frame */ - if ((fcm->flag & FMODIFIER_FLAG_RANGERESTRICT) == 0 || - ((fcm->sfra <= evaltime) && (fcm->efra >= evaltime)) ) - { - if (fmi->evaluate_modifier || fmi->evaluate_modifier_storage) { - if ((fcm->flag & (FMODIFIER_FLAG_DISABLED | FMODIFIER_FLAG_MUTED)) == 0) { - float influence = eval_fmodifier_influence(fcm, evaltime); - float nval = *cvalue; - - if ((fmi->requires & FMI_REQUIRES_STORAGE) == 0) { - fmi->evaluate_modifier(fcu, fcm, &nval, evaltime); - } - else { - fmi->evaluate_modifier_storage(storage, fcu, fcm, &nval, evaltime); - } - - *cvalue = interpf(nval, *cvalue, influence); - } - } - } - } + FModifier *fcm; + + /* sanity checks */ + if (ELEM(NULL, modifiers, modifiers->first)) + return; + + if (fcu->flag & FCURVE_MOD_OFF) + return; + + /* evaluate modifiers */ + for (fcm = modifiers->first; fcm; fcm = fcm->next) { + const FModifierTypeInfo *fmi = fmodifier_get_typeinfo(fcm); + + if (fmi == NULL) + continue; + + /* only evaluate if there's a callback for this, and if F-Modifier can be evaluated on this frame */ + if ((fcm->flag & FMODIFIER_FLAG_RANGERESTRICT) == 0 || + ((fcm->sfra <= evaltime) && (fcm->efra >= evaltime))) { + if (fmi->evaluate_modifier || fmi->evaluate_modifier_storage) { + if ((fcm->flag & (FMODIFIER_FLAG_DISABLED | FMODIFIER_FLAG_MUTED)) == 0) { + float influence = eval_fmodifier_influence(fcm, evaltime); + float nval = *cvalue; + + if ((fmi->requires & FMI_REQUIRES_STORAGE) == 0) { + fmi->evaluate_modifier(fcu, fcm, &nval, evaltime); + } + else { + fmi->evaluate_modifier_storage(storage, fcu, fcm, &nval, evaltime); + } + + *cvalue = interpf(nval, *cvalue, influence); + } + } + } + } } /* ---------- */ @@ -1493,25 +1528,25 @@ void evaluate_value_fmodifiers(FModifierStackStorage *storage, ListBase *modifie */ void fcurve_bake_modifiers(FCurve *fcu, int start, int end) { - ChannelDriver *driver; + ChannelDriver *driver; - /* sanity checks */ - /* TODO: make these tests report errors using reports not CLOG's */ - if (ELEM(NULL, fcu, fcu->modifiers.first)) { - CLOG_ERROR(&LOG, "No F-Curve with F-Curve Modifiers to Bake"); - return; - } + /* sanity checks */ + /* TODO: make these tests report errors using reports not CLOG's */ + if (ELEM(NULL, fcu, fcu->modifiers.first)) { + CLOG_ERROR(&LOG, "No F-Curve with F-Curve Modifiers to Bake"); + return; + } - /* temporarily, disable driver while we sample, so that they don't influence the outcome */ - driver = fcu->driver; - fcu->driver = NULL; + /* temporarily, disable driver while we sample, so that they don't influence the outcome */ + driver = fcu->driver; + fcu->driver = NULL; - /* bake the modifiers, by sampling the curve at each frame */ - fcurve_store_samples(fcu, NULL, start, end, fcurve_samplingcb_evalcurve); + /* bake the modifiers, by sampling the curve at each frame */ + fcurve_store_samples(fcu, NULL, start, end, fcurve_samplingcb_evalcurve); - /* free the modifiers now */ - free_fmodifiers(&fcu->modifiers); + /* free the modifiers now */ + free_fmodifiers(&fcu->modifiers); - /* restore driver */ - fcu->driver = driver; + /* restore driver */ + fcu->driver = driver; } |