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:
authorJoshua Leung <aligorith@gmail.com>2009-03-16 04:12:37 +0300
committerJoshua Leung <aligorith@gmail.com>2009-03-16 04:12:37 +0300
commit8522b08e05c31f9fc4b5fee25c64b884593dc180 (patch)
tree0dd3b66d607ca3e3355d3a9f7311d5088ad28ce3 /source/blender/blenkernel
parent9ad4cd89c2cdee8d8086f7da9d9b35fdec12366a (diff)
F-Curve Modifiers: Generator Modifier Code
* Rewrote the Generator modifier to be more efficient and support more options * A few UI tweaks for this, but the UI for this is still not yet functional though.
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r--source/blender/blenkernel/intern/fcurve.c130
-rw-r--r--source/blender/blenkernel/intern/ipo.c50
2 files changed, 116 insertions, 64 deletions
diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c
index e73a2e158ad..3b60be396e7 100644
--- a/source/blender/blenkernel/intern/fcurve.c
+++ b/source/blender/blenkernel/intern/fcurve.c
@@ -6,6 +6,7 @@
#include <math.h>
#include <stdio.h>
#include <string.h>
+#include <float.h>
#ifdef HAVE_CONFIG_H
#include <config.h>
@@ -1119,13 +1120,24 @@ static FModifierTypeInfo FMI_MODNAME = {
/* Generator F-Curve Modifier --------------------------- */
+/* Generators available:
+ * 1) simple polynomial generator:
+ * - Exanded form - (y = C[0]*(x^(n)) + C[1]*(x^(n-1)) + ... + C[n])
+ * - Factorised form - (y = (C[0][0]*x + C[0][1]) * (C[1][0]*x + C[1][1]) * ... * (C[n][0]*x + C[n][1]))
+ * 2) simple builin 'functions':
+ * of the form (y = C[0] * fn( C[1]*x + C[2] ) + C[3])
+ * where fn() can be any one of:
+ * sin, cos, tan, ln, sqrt
+ * 3) expression...
+ */
+
static void fcm_generator_free (FModifier *fcm)
{
FMod_Generator *data= (FMod_Generator *)fcm->data;
/* free polynomial coefficients array */
- if (data->poly_coefficients)
- MEM_freeN(data->poly_coefficients);
+ if (data->coefficients)
+ MEM_freeN(data->coefficients);
}
static void fcm_generator_copy (FModifier *fcm, FModifier *src)
@@ -1133,9 +1145,9 @@ static void fcm_generator_copy (FModifier *fcm, FModifier *src)
FMod_Generator *gen= (FMod_Generator *)fcm->data;
FMod_Generator *ogen= (FMod_Generator *)src->data;
- /* copy polynomial coefficients array? */
- if (ogen->poly_coefficients)
- gen->poly_coefficients= MEM_dupallocN(ogen->poly_coefficients);
+ /* copy coefficients array? */
+ if (ogen->coefficients)
+ gen->coefficients= MEM_dupallocN(ogen->coefficients);
}
static void fcm_generator_new_data (void *mdata)
@@ -1145,7 +1157,8 @@ static void fcm_generator_new_data (void *mdata)
/* set default generator to be linear 0-1 (gradient = 1, y-offset = 0) */
data->poly_order= 1;
- cp= data->poly_coefficients= MEM_callocN(sizeof(float)*2, "FMod_Generator_Coefs");
+ data->arraysize= 2;
+ cp= data->coefficients= MEM_callocN(sizeof(float)*2, "FMod_Generator_Coefs");
cp[0] = 0; // y-offset
cp[1] = 1; // gradient
}
@@ -1155,26 +1168,113 @@ static void fcm_generator_evaluate (FCurve *fcu, FModifier *fcm, float *cvalue,
{
FMod_Generator *data= (FMod_Generator *)fcm->data;
- /* behaviour depends on mode (NOTE: we don't need to do anything...) */
+ /* behaviour depends on mode
+ * NOTE: the data in its default state is fine too
+ */
switch (data->mode) {
- // TODO: implement factorised polynomial too
- case FCM_GENERATOR_POLYNOMIAL: /* polynomial expression */
+ case FCM_GENERATOR_POLYNOMIAL: /* expanded polynomial expression */
{
/* we overwrite cvalue with the sum of the polynomial */
- float value= 0.0f, *cp = NULL;
+ 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 */
- // TODO: could this be more efficient (i.e. without need to recalc pow() everytime)
- cp= data->poly_coefficients;
- for (i=0; (i <= data->poly_order) && (cp); i++, cp++)
- value += (*cp) * (float)pow(evaltime, i);
+ for (i=0; i < data->arraysize; i++)
+ value += data->coefficients[i] * powers[i];
- /* only if something changed */
+ /* only if something changed, write *cvalue in one go */
+ if (data->poly_order)
+ *cvalue= value;
+
+ /* cleanup */
+ if (powers)
+ MEM_freeN(powers);
+ }
+ break;
+
+ case FCM_GENERATOR_POLYNOMIAL_FACTORISED: /* factorised 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 < 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)
*cvalue= value;
}
break;
+
+ case FCM_GENERATOR_FUNCTION: /* builtin function */
+ {
+ double arg= data->coefficients[1]*evaltime + data->coefficients[2];
+ 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->func_type)
+ {
+ /* simple ones */
+ case FCM_GENERATOR_FN_SIN: /* sine wave */
+ fn= sin;
+ break;
+ case FCM_GENERATOR_FN_COS: /* cosine wave */
+ fn= cos;
+ 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)
+ *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.0f)
+ fn= log;
+ else
+ *cvalue= 0.0f; /* no value possible here */
+ }
+ break;
+ case FCM_GENERATOR_FN_SQRT: /* square root */
+ {
+ /* no negative numbers */
+ if (arg > 0.0f)
+ fn= sqrt;
+ else
+ *cvalue= 0.0f; /* no vlaue possible here */
+ }
+ break;
+
+ default:
+ printf("Invalid Function-Generator for F-Modifier - %d \n", data->func_type);
+ }
+
+ /* execute function callback to set value if appropriate */
+ if (fn)
+ *cvalue= data->coefficients[0]*fn(arg) + data->coefficients[3];
+ }
+ break;
#ifndef DISABLE_PYTHON
case FCM_GENERATOR_EXPRESSION: /* py-expression */
diff --git a/source/blender/blenkernel/intern/ipo.c b/source/blender/blenkernel/intern/ipo.c
index dbb720fb0bc..b9417ccb467 100644
--- a/source/blender/blenkernel/intern/ipo.c
+++ b/source/blender/blenkernel/intern/ipo.c
@@ -1730,53 +1730,5 @@ void do_versions_ipos_to_animato(Main *main)
/* free unused drivers from actions + ipos */
free_fcurves(&drivers);
- printf("INFO: animato convert done \n"); // xxx debug
+ printf("INFO: Animato convert done \n"); // xxx debug
}
-
-
-
-#if 0 // XXX old animation system
-
-/* ***************************** IPO - DataAPI ********************************* */
-
-// !!!!!!!!!!!!!!!!!!!!!!!!!!!! FIXME - BAD CRUFT WARNING !!!!!!!!!!!!!!!!!!!!!!!
-
-/* These functions here should be replaced eventually by the Data API, as this is
- * inflexible duplication...
- */
-
-/* --------------------- Get Pointer API ----------------------------- */
-
-
-/* GS reads the memory pointed at in a specific ordering. There are,
- * however two definitions for it. I have jotted them down here, both,
- * but I think the first one is actually used. The thing is that
- * big-endian systems might read this the wrong way round. OTOH, we
- * constructed the IDs that are read out with this macro explicitly as
- * well. I expect we'll sort it out soon... */
-
-/* from blendef: */
-#define GS(a) (*((short *)(a)))
-
-/* from misc_util: flip the bytes from x */
-/* #define GS(x) (((unsigned char *)(x))[0] << 8 | ((unsigned char *)(x))[1]) */
-
-
-/* general function to get pointer to source/destination data */
-void *get_ipo_poin (ID *id, IpoCurve *icu, int *type)
-{
- void *poin= NULL;
- MTex *mtex= NULL;
-
- /* most channels will have float data, but those with other types will override this */
- *type= IPO_FLOAT;
-
- /* data is divided into 'blocktypes' based on ID-codes */
- // all adr codes put into converters!
-
- /* return pointer */
- return poin;
-}
-
-
-#endif // XXX old animation system