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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/blenkernel/intern/fmodifier.c')
-rw-r--r--source/blender/blenkernel/intern/fmodifier.c2179
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;
}