[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [21405] branches/soc-2009-aligorith/source /blender/blenkernel: NLA SoC: Recoded way that Meta-Strips are Evaluated

Joshua Leung aligorith at gmail.com
Tue Jul 7 13:37:33 CEST 2009


Revision: 21405
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=21405
Author:   aligorith
Date:     2009-07-07 13:37:33 +0200 (Tue, 07 Jul 2009)

Log Message:
-----------
NLA SoC: Recoded way that Meta-Strips are Evaluated

Previously, the quick-hack I coded for Meta-strips evaluation didn't really take into account the possibilities to use Meta-Strips as strips in their own right - i.e. reversed, muted, time-mapping-curves, influence-blending - were all unavailable. 

This commit makes the aforementioned capabilities of other strips available for Meta-Strips too. The evaluation is now kind-of recursive (as with most of the other methods which take them into account) so that each 'level' of strips get evaluated correctly within their frame-of-reference.

TODO:
* F-Modifier support for Metas...

Modified Paths:
--------------
    branches/soc-2009-aligorith/source/blender/blenkernel/intern/anim_sys.c
    branches/soc-2009-aligorith/source/blender/blenkernel/intern/nla.c
    branches/soc-2009-aligorith/source/blender/blenkernel/nla_private.h

Modified: branches/soc-2009-aligorith/source/blender/blenkernel/intern/anim_sys.c
===================================================================
--- branches/soc-2009-aligorith/source/blender/blenkernel/intern/anim_sys.c	2009-07-07 10:25:55 UTC (rev 21404)
+++ branches/soc-2009-aligorith/source/blender/blenkernel/intern/anim_sys.c	2009-07-07 11:37:33 UTC (rev 21405)
@@ -627,11 +627,12 @@
 	}
 }
 
-
-/* gets the strip active at the current time for a given list of strips */
-static NlaStrip *ctime_get_strip (ListBase *strips, short *side, float ctime)
+/* gets the strip active at the current time for a list of strips for evaluation purposes */
+NlaEvalStrip *nlastrips_ctime_get_strip (ListBase *list, ListBase *strips, short index, float ctime)
 {
 	NlaStrip *strip, *estrip=NULL;
+	NlaEvalStrip *nes;
+	short side= 0;
 	
 	/* loop over strips, checking if they fall within the range */
 	for (strip= strips->first; strip; strip= strip->next) {
@@ -651,7 +652,7 @@
 					estrip= strip;
 					
 				/* side is 'before' regardless of whether there's a useful strip */
-				*side= NES_TIME_BEFORE;
+				side= NES_TIME_BEFORE;
 			}
 			else {
 				/* before next strip - previous strip has ended, but next hasn't begun, 
@@ -663,7 +664,7 @@
 				
 				if (strip->extendmode != NLASTRIP_EXTEND_NOTHING)
 					estrip= strip;
-				*side= NES_TIME_AFTER;
+				side= NES_TIME_AFTER;
 			}
 			break;
 		}
@@ -675,7 +676,7 @@
 				if (strip->extendmode != NLASTRIP_EXTEND_NOTHING)
 					estrip= strip;
 					
-				*side= NES_TIME_AFTER;
+				side= NES_TIME_AFTER;
 				break;
 			}
 			
@@ -683,40 +684,11 @@
 		}
 	}
 	
-	/* return the matching strip found */
-	return estrip;
-}
-
-/* gets the strip active at the current time for a track for evaluation purposes */
-static void nlatrack_ctime_get_strip (ListBase *list, NlaTrack *nlt, short index, float ctime)
-{
-	ListBase *strips= &nlt->strips;
-	NlaStrip *strip, *estrip=NULL;
-	NlaEvalStrip *nes;
-	short side= 0;
-	
-	/* keep looping over hierarchy of strips until one which fits for the current time is found */
-	while (strips->first) {
-		/* try to get the strip at this frame for this strip */
-		strip= ctime_get_strip(strips, &side, ctime);
-		
-		/* if a strip was found, make this the new estrip, otherwise, stop trying */
-		if (strip) {
-			/* set new estrip */
-			estrip= strip;
-			
-			/* check children (only available if this is a meta-strip) for better match */
-			strips= &strip->strips;
-		}
-		else
-			break;
-	}
-	
 	/* check if a valid strip was found
 	 *	- must not be muted (i.e. will have contribution
 	 */
 	if ((estrip == NULL) || (estrip->flag & NLASTRIP_FLAG_MUTED)) 
-		return;
+		return NULL;
 		
 	/* if ctime was not within the boundaries of the strip, clamp! */
 	switch (side) {
@@ -734,8 +706,8 @@
 	 */
 	// TODO: this sounds a bit hacky having a few isolated F-Curves stuck on some data it operates on...
 	nlastrip_evaluate_controls(estrip, ctime);
-	if (estrip->influence <= 0.0f) // XXX is it useful to invert the strip?
-		return;
+	if (estrip->influence <= 0.0f)
+		return NULL;
 		
 	/* check if strip has valid data to evaluate,
 	 * and/or perform any additional type-specific actions
@@ -744,12 +716,12 @@
 		case NLASTRIP_TYPE_CLIP: 
 			/* clip must have some action to evaluate */
 			if (estrip->act == NULL)
-				return;
+				return NULL;
 			break;
 		case NLASTRIP_TYPE_TRANSITION:
 			/* there must be strips to transition from and to (i.e. prev and next required) */
 			if (ELEM(NULL, estrip->prev, estrip->next))
-				return;
+				return NULL;
 				
 			/* evaluate controls for the relevant extents of the bordering strips... */
 			nlastrip_evaluate_controls(estrip->prev, estrip->start);
@@ -760,13 +732,15 @@
 	/* add to list of strips we need to evaluate */
 	nes= MEM_callocN(sizeof(NlaEvalStrip), "NlaEvalStrip");
 	
-	nes->track= nlt;
 	nes->strip= estrip;
 	nes->strip_mode= side;
 	nes->track_index= index;
 	nes->strip_time= estrip->strip_time;
 	
-	BLI_addtail(list, nes);
+	if (list)
+		BLI_addtail(list, nes);
+	
+	return nes;
 }
 
 /* ---------------------- */
@@ -897,6 +871,38 @@
 	}
 }
 
+/* accumulate the results of a temporary buffer with the results of the full-buffer */
+static void nlaevalchan_buffers_accumulate (ListBase *channels, ListBase *tmp_buffer, NlaEvalStrip *nes)
+{
+	NlaEvalChannel *nec, *necn, *necd;
+	
+	/* optimise - abort if no channels */
+	if (tmp_buffer->first == NULL)
+		return;
+	
+	/* accumulate results in tmp_channels buffer to the accumulation buffer */
+	for (nec= tmp_buffer->first; nec; nec= necn) {
+		/* get pointer to next channel in case we remove the current channel from the temp-buffer */
+		necn= nec->next;
+		
+		/* try to find an existing matching channel for this setting in the accumulation buffer */
+		necd= nlaevalchan_find_match(channels, &nec->ptr, nec->prop, nec->index);
+		
+		/* if there was a matching channel already in the buffer, accumulate to it,
+		 * otherwise, add the current channel to the buffer for efficiency
+		 */
+		if (necd)
+			nlaevalchan_accumulate(necd, nes, 0, nec->value);
+		else {
+			BLI_remlink(tmp_buffer, nec);
+			BLI_addtail(channels, nec);
+		}
+	}
+	
+	/* free temp-channels that haven't been assimilated into the buffer */
+	BLI_freelistN(tmp_buffer);
+}
+
 /* ---------------------- */
 
 /* evaluate action-clip strip */
@@ -945,7 +951,6 @@
 static void nlastrip_evaluate_transition (PointerRNA *ptr, ListBase *channels, NlaEvalStrip *nes)
 {
 	ListBase tmp_channels = {NULL, NULL};
-	NlaEvalChannel *nec, *necn, *necd;
 	NlaEvalStrip tmp_nes;
 	NlaStrip *s1, *s2;
 	
@@ -986,38 +991,51 @@
 	nlastrip_evaluate_actionclip(ptr, &tmp_channels, &tmp_nes);
 	
 	
-	/* optimise - abort if no channels */
-	if (tmp_channels.first == NULL)
-		return;
+	/* assumulate temp-buffer and full-buffer, using the 'real' strip */
+	nlaevalchan_buffers_accumulate(channels, &tmp_channels, nes);
+}
+
+/* evaluate meta-strip */
+static void nlastrip_evaluate_meta (PointerRNA *ptr, ListBase *channels, NlaEvalStrip *nes)
+{
+	ListBase tmp_channels = {NULL, NULL};
+	NlaStrip *strip= nes->strip;
+	NlaEvalStrip *tmp_nes;
+	float evaltime;
 	
+	/* meta-strip was calculated normally to have some time to be evaluated at
+	 * and here we 'look inside' the meta strip, treating it as a decorated window to
+	 * it's child strips, which get evaluated as if they were some tracks on a strip 
+	 * (but with some extra modifiers to apply).
+	 *
+	 * NOTE: keep this in sync with animsys_evaluate_nla()
+	 */
 	
-	/* accumulate results in tmp_channels buffer to the accumulation buffer */
-	for (nec= tmp_channels.first; nec; nec= necn) {
-		/* get pointer to next channel in case we remove the current channel from the temp-buffer */
-		necn= nec->next;
+	/* find the child-strip to evaluate */
+	evaltime= (nes->strip_time * (strip->end - strip->start)) + strip->start;
+	tmp_nes= nlastrips_ctime_get_strip(NULL, &strip->strips, -1, evaltime);
+	if (tmp_nes == NULL)
+		return;
 		
-		/* try to find an existing matching channel for this setting in the accumulation buffer */
-		necd= nlaevalchan_find_match(channels, &nec->ptr, nec->prop, nec->index);
-		
-		/* if there was a matching channel already in the buffer, accumulate to it,
-		 * otherwise, add the current channel to the buffer for efficiency
-		 */
-		if (necd)
-			nlaevalchan_accumulate(necd, nes, 0, nec->value);
-		else {
-			BLI_remlink(&tmp_channels, nec);
-			BLI_addtail(channels, nec);
-		}
-	}
+	/* evaluate child-strip into tmp_channels buffer before accumulating 
+	 * in the accumulation buffer
+	 */
+	// TODO: need to supply overriding modifiers which will get applied over the top of these
+	nlastrip_evaluate(ptr, &tmp_channels, tmp_nes);
 	
-	/* free temp-channels that haven't been assimilated into the buffer */
-	BLI_freelistN(&tmp_channels);
+	/* assumulate temp-buffer and full-buffer, using the 'real' strip */
+	nlaevalchan_buffers_accumulate(channels, &tmp_channels, nes);
+	
+	/* free temp eval-strip */
+	MEM_freeN(tmp_nes);
 }
 
+
 /* evaluates the given evaluation strip */
-static void nlastrip_evaluate (PointerRNA *ptr, ListBase *channels, NlaEvalStrip *nes)
+void nlastrip_evaluate (PointerRNA *ptr, ListBase *channels, NlaEvalStrip *nes)
 {
 	/* actions to take depend on the type of strip */
+	// TODO: add 'modifiers' tag to chain
 	switch (nes->strip->type) {
 		case NLASTRIP_TYPE_CLIP: /* action-clip */
 			nlastrip_evaluate_actionclip(ptr, channels, nes);
@@ -1025,11 +1043,14 @@
 		case NLASTRIP_TYPE_TRANSITION: /* transition */
 			nlastrip_evaluate_transition(ptr, channels, nes);
 			break;
+		case NLASTRIP_TYPE_META: /* meta */
+			nlastrip_evaluate_meta(ptr, channels, nes);
+			break;
 	}
 }
 
 /* write the accumulated settings to */
-static void nladata_flush_channels (ListBase *channels)
+void nladata_flush_channels (ListBase *channels)
 {
 	NlaEvalChannel *nec;
 	
@@ -1104,7 +1125,8 @@
 			continue;
 			
 		/* otherwise, get strip to evaluate for this channel */
-		nlatrack_ctime_get_strip(&estrips, nlt, track_index, ctime);
+		nes= nlastrips_ctime_get_strip(&estrips, &nlt->strips, track_index, ctime);
+		if (nes) nes->track= nlt;
 	}
 	
 	/* only continue if there are strips to evaluate */

Modified: branches/soc-2009-aligorith/source/blender/blenkernel/intern/nla.c
===================================================================
--- branches/soc-2009-aligorith/source/blender/blenkernel/intern/nla.c	2009-07-07 10:25:55 UTC (rev 21404)
+++ branches/soc-2009-aligorith/source/blender/blenkernel/intern/nla.c	2009-07-07 11:37:33 UTC (rev 21405)
@@ -452,7 +452,7 @@
 float nlastrip_get_frame (NlaStrip *strip, float cframe, short mode)
 {
 	switch (strip->type) {
-		case NLASTRIP_TYPE_META: /* meta (is just a container for other strips, so shouldn't use the action-clip method) */
+		case NLASTRIP_TYPE_META: /* meta - for now, does the same as transition (is really just an empty container) */
 		case NLASTRIP_TYPE_TRANSITION: /* transition */
 			return nlastrip_get_frame_transition(strip, cframe, mode);
 		

Modified: branches/soc-2009-aligorith/source/blender/blenkernel/nla_private.h
===================================================================
--- branches/soc-2009-aligorith/source/blender/blenkernel/nla_private.h	2009-07-07 10:25:55 UTC (rev 21404)
+++ branches/soc-2009-aligorith/source/blender/blenkernel/nla_private.h	2009-07-07 11:37:33 UTC (rev 21405)
@@ -75,5 +75,11 @@
 /* convert from strip time <-> global time */

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list