Revision: 19303
          
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=19303
Author:   aligorith
Date:     2009-03-16 02:12:37 +0100 (Mon, 16 Mar 2009)

Log Message:
-----------
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.

Modified Paths:
--------------
    branches/blender2.5/blender/source/blender/blenkernel/intern/fcurve.c
    branches/blender2.5/blender/source/blender/blenkernel/intern/ipo.c
    branches/blender2.5/blender/source/blender/blenloader/intern/readfile.c
    branches/blender2.5/blender/source/blender/blenloader/intern/writefile.c
    
branches/blender2.5/blender/source/blender/editors/space_graph/graph_buttons.c
    branches/blender2.5/blender/source/blender/editors/space_graph/space_graph.c
    branches/blender2.5/blender/source/blender/makesdna/DNA_anim_types.h

Modified: branches/blender2.5/blender/source/blender/blenkernel/intern/fcurve.c
===================================================================
--- branches/blender2.5/blender/source/blender/blenkernel/intern/fcurve.c       
2009-03-15 23:40:59 UTC (rev 19302)
+++ branches/blender2.5/blender/source/blender/blenkernel/intern/fcurve.c       
2009-03-16 01:12:37 UTC (rev 19303)
@@ -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 @@
 
 /* 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 @@
        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 @@
        
        /* 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 @@
 {
        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 */

Modified: branches/blender2.5/blender/source/blender/blenkernel/intern/ipo.c
===================================================================
--- branches/blender2.5/blender/source/blender/blenkernel/intern/ipo.c  
2009-03-15 23:40:59 UTC (rev 19302)
+++ branches/blender2.5/blender/source/blender/blenkernel/intern/ipo.c  
2009-03-16 01:12:37 UTC (rev 19303)
@@ -1730,53 +1730,5 @@
        /* 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

Modified: 
branches/blender2.5/blender/source/blender/blenloader/intern/readfile.c
===================================================================
--- branches/blender2.5/blender/source/blender/blenloader/intern/readfile.c     
2009-03-15 23:40:59 UTC (rev 19302)
+++ branches/blender2.5/blender/source/blender/blenloader/intern/readfile.c     
2009-03-16 01:12:37 UTC (rev 19303)
@@ -1725,7 +1725,7 @@
                                {
                                        FMod_Generator *data= (FMod_Generator 
*)fcm->data;
                                        
-                                       data->poly_coefficients= newdataadr(fd, 
data->poly_coefficients);
+                                       data->coefficients= newdataadr(fd, 
data->coefficients);
                                }
                                        break;
                                case FMODIFIER_TYPE_PYTHON:

Modified: 
branches/blender2.5/blender/source/blender/blenloader/intern/writefile.c
===================================================================
--- branches/blender2.5/blender/source/blender/blenloader/intern/writefile.c    
2009-03-15 23:40:59 UTC (rev 19302)
+++ branches/blender2.5/blender/source/blender/blenloader/intern/writefile.c    
2009-03-16 01:12:37 UTC (rev 19303)
@@ -805,9 +805,9 @@
                                        {
                                                FMod_Generator *data= 
(FMod_Generator *)fcm->data;
                                                
-                                               /* write polynomial 
coefficients array */
-                                               if (data->poly_coefficients)
-                                                       writedata(wd, DATA, 
sizeof(float)*(data->poly_order+1), data->poly_coefficients);
+                                               /* write coefficients array */
+                                               if (data->coefficients)
+                                                       writedata(wd, DATA, 
sizeof(float)*(data->arraysize), data->coefficients);
                                        }
                                                break;
                                        case FMODIFIER_TYPE_PYTHON:

Modified: 
branches/blender2.5/blender/source/blender/editors/space_graph/graph_buttons.c
===================================================================
--- 
branches/blender2.5/blender/source/blender/editors/space_graph/graph_buttons.c  
    2009-03-15 23:40:59 UTC (rev 19302)
+++ 
branches/blender2.5/blender/source/blender/editors/space_graph/graph_buttons.c  
    2009-03-16 01:12:37 UTC (rev 19303)
@@ -231,8 +231,47 @@
        }
 }
 
+/* macro for use here to draw background box and set height */
+#define DRAW_BACKDROP(height, h) \
+       { \
+               height= h; \
+               if (active) uiBlockSetCol(block, TH_BUT_ACTION); \
+                       uiDefBut(block, ROUNDBOX, B_REDR, "", 10-8, 
*yco-height, width, height-1, NULL, 5.0, 0.0, 12.0, (float)rb_col, ""); \
+               if (active) uiBlockSetCol(block, TH_AUTO); \
+       }
 
-/* for now, just print name of modifier */
+/* draw settings for generator modifier */

@@ Diff output truncated at 10240 characters. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to