[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [19303] branches/blender2.5/blender/source /blender: F-Curve Modifiers: Generator Modifier Code

Joshua Leung aligorith at gmail.com
Mon Mar 16 02:12:39 CET 2009


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. @@




More information about the Bf-blender-cvs mailing list