[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [32380] trunk/blender/source/blender/ blenkernel/intern/fmodifier.c: Fix for [#24092] F-Curve Cycle doesn' t behave properly at end of Cycles (also: possible problem with how the cycle range is determined)

Janne Karhu jhkarh at gmail.com
Fri Oct 8 15:08:13 CEST 2010


Revision: 32380
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=32380
Author:   jhk
Date:     2010-10-08 15:08:13 +0200 (Fri, 08 Oct 2010)

Log Message:
-----------
Fix for [#24092] F-Curve Cycle doesn't behave properly at end of Cycles (also: possible problem with how the cycle range is determined)
* Cycle code had difficulties handling the transitions from one cycle iteration to the next one.
* Now the transition frames are handled manually so that:
    - cycles before the actual fcurve data respect the first datapoint
    - cycles after the fcurve data respect the last datapoint
* Also fixes a bug where the count of "before" cycles was off by one from the given value.

Modified Paths:
--------------
    trunk/blender/source/blender/blenkernel/intern/fmodifier.c

Modified: trunk/blender/source/blender/blenkernel/intern/fmodifier.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/fmodifier.c	2010-10-08 12:16:03 UTC (rev 32379)
+++ trunk/blender/source/blender/blenkernel/intern/fmodifier.c	2010-10-08 13:08:13 UTC (rev 32380)
@@ -529,7 +529,7 @@
 	FMod_Cycles *data= (FMod_Cycles *)fcm->data;
 	float prevkey[2], lastkey[2], cycyofs=0.0f;
 	short side=0, mode=0;
-	int cycles=0;
+	int cycles=0, ofs=0;
 	
 	/* check if modifier is first in stack, otherwise disable ourself... */
 	// FIXME...
@@ -571,6 +571,7 @@
 			side= -1;
 			mode= data->before_mode;
 			cycles= data->before_cycles;
+			ofs= prevkey[0];
 		}
 	}
 	else if (evaltime > lastkey[0]) {
@@ -578,6 +579,7 @@
 			side= 1;
 			mode= data->after_mode;
 			cycles= data->after_cycles;
+			ofs= lastkey[0];
 		}
 	}
 	if ELEM(0, side, mode)
@@ -585,12 +587,9 @@
 		
 	/* find relative place within a cycle */
 	{
-		float cycdx=0, cycdy=0, ofs=0;
-		float cycle= 0;
+		float cycdx=0, cycdy=0;
+		float cycle= 0, cyct=0;
 		
-		/* ofs is start frame of cycle */
-		ofs= prevkey[0];
-		
 		/* calculate period and amplitude (total height) of a cycle */
 		cycdx= lastkey[0] - prevkey[0];
 		cycdy= lastkey[1] - prevkey[1];
@@ -601,6 +600,9 @@
 			
 		/* 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) {
@@ -608,7 +610,7 @@
 			 * as this indicates infinite cycles...
 			 */
 		}
-		else if (cycle > (cycles+1)) {
+		else if (cycle > cycles) {
 			/* we are too far away from range to evaluate
 			 * TODO: but we should still hold last value... 
 			 */
@@ -617,26 +619,36 @@
 		
 		/* check if 'cyclic extrapolation', and thus calculate y-offset for this cycle */
 		if (mode == FCM_EXTRAPOLATE_CYCLIC_OFFSET) {
-			cycyofs = (float)floor((evaltime - ofs) / cycdx);
+			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) */
-		if ((mode == FCM_EXTRAPOLATE_MIRROR) && ((int)(cycle) % 2)) {
+		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= (float)(prevkey[0] - fmod(evaltime-ofs, cycdx));
+				evaltime= prevkey[0] - cyct;
 			else
-				evaltime= (float)(lastkey[0] - fmod(evaltime-ofs, cycdx));
+				evaltime= lastkey[0] - cyct;
 		}
 		else {
 			/* the cycle is played normally... */
-			evaltime= (float)(fmod(evaltime-ofs, cycdx) + ofs);
+			evaltime= prevkey[0] + cyct;
 		}
-		if (evaltime < ofs) evaltime += cycdx;
+		if (evaltime < prevkey[0]) evaltime += cycdx;
 	}
 	
 	/* store temp data if needed */





More information about the Bf-blender-cvs mailing list