[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [12841] branches/animsys-aligorith/source/ blender: == AnimSys Branch ==

Joshua Leung aligorith at gmail.com
Tue Dec 11 11:46:07 CET 2007


Revision: 12841
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=12841
Author:   aligorith
Date:     2007-12-11 11:46:07 +0100 (Tue, 11 Dec 2007)

Log Message:
-----------
== AnimSys Branch ==

Start of new NLA code. So far, only the groundwork has been done. 

(P.S.  test commit from new pc)

Modified Paths:
--------------
    branches/animsys-aligorith/source/blender/blenkernel/intern/action.c
    branches/animsys-aligorith/source/blender/blenkernel/intern/group.c
    branches/animsys-aligorith/source/blender/blenkernel/intern/nla.c
    branches/animsys-aligorith/source/blender/makesdna/DNA_animdata_types.h
    branches/animsys-aligorith/source/blender/makesdna/DNA_nla_types.h

Modified: branches/animsys-aligorith/source/blender/blenkernel/intern/action.c
===================================================================
--- branches/animsys-aligorith/source/blender/blenkernel/intern/action.c	2007-12-11 01:58:22 UTC (rev 12840)
+++ branches/animsys-aligorith/source/blender/blenkernel/intern/action.c	2007-12-11 10:46:07 UTC (rev 12841)
@@ -403,7 +403,7 @@
 	bActionChannel *chan;
 	
 	chan= get_action_channel(act, name);
-	if(chan==NULL) {
+	if (chan==NULL) {
 		if (!chan) {
 			chan = MEM_callocN (sizeof(bActionChannel), "actionChannel");
 			strncpy (chan->name, name, 31);

Modified: branches/animsys-aligorith/source/blender/blenkernel/intern/group.c
===================================================================
--- branches/animsys-aligorith/source/blender/blenkernel/intern/group.c	2007-12-11 01:58:22 UTC (rev 12840)
+++ branches/animsys-aligorith/source/blender/blenkernel/intern/group.c	2007-12-11 10:46:07 UTC (rev 12841)
@@ -190,6 +190,7 @@
 
 /* only replaces object strips or action when parent nla instructs it */
 /* keep checking nla.c though, in case internal structure of strip changes */
+// FIXME... the way this works needs to be looked into again!
 static void group_replaces_nla(Object *parent, Object *target, char mode)
 {
 	static ListBase nlastrips={NULL, NULL};

Modified: branches/animsys-aligorith/source/blender/blenkernel/intern/nla.c
===================================================================
--- branches/animsys-aligorith/source/blender/blenkernel/intern/nla.c	2007-12-11 01:58:22 UTC (rev 12840)
+++ branches/animsys-aligorith/source/blender/blenkernel/intern/nla.c	2007-12-11 10:46:07 UTC (rev 12841)
@@ -31,160 +31,266 @@
  */
 
 #include <stdlib.h>
+#include <string.h>
 
 #include "MEM_guardedalloc.h"
 
 #include "BLI_blenlib.h"
 
-#include "DNA_space_types.h"
-#include "DNA_nla_types.h"
+#include "DNA_listBase.h"
+#include "DNA_animdata_types.h"
 #include "DNA_action_types.h"
 #include "DNA_ID.h"
 #include "DNA_ipo_types.h"
 #include "DNA_object_types.h"
+#include "DNA_nla_types.h"
+#include "DNA_space_types.h"
 
 #include "BKE_nla.h"
 #include "BKE_action.h"
+#include "BKE_ipo.h"
 #include "BKE_blender.h"
 #include "BKE_library.h"
-#include "BKE_object.h" /* for convert_action_to_strip(ob) */
+#include "BKE_object.h"
+#include "BKE_utildefines.h"
 
-
 #ifdef HAVE_CONFIG_H
 #include <config.h>
 #endif
 
-/* NOTE: in group.c the strips get copied for group-nla override, this assumes
-   that strips are one single block, without additional data to be copied */
+/* ******************** AnimData/NLA Data-Management ********************* */
 
-void copy_actionstrip (bActionStrip **dst, bActionStrip **src){
-	bActionStrip *dstrip;
-	bActionStrip *sstrip = *src;
+/* free the given nla-strip and all it's subdata */
+void free_nlastrip (bActionStrip *strip)
+{
+	if (strip) {
+		/* unlink id-datablocks from strip */
+		if (strip->ipo) strip->ipo->id.us--;
+		if (strip->act) strip->act->id.us--;
+		
+		/* free strip modifiers */
+		BLI_freelistN(&strip->modifiers);
+		
+		/* finally, free the strip */
+		MEM_freeN(strip);
+	}
+}
 
-	if (!*src){
-		*dst=NULL;
-		return;
+/* free the given nla-track and all it's subdata */
+void free_nlatrack (bNlaTrack *nlt)
+{
+	if (nlt) {
+		bActionStrip *strip, *next;
+			
+		/* loop through strips freeing them */
+		for (strip= nlt->strips.first; strip; strip= next) {
+			next= strip->next;
+			free_nlastrip(strip);
+		}
+		
+		/* now free the track as well */
+		MEM_freeN(nlt);
 	}
+}
 
-	*dst = MEM_dupallocN(sstrip);
+/* free the given animdata block and all its subdata */
+void free_animdata (bAnimData *adt)
+{
+	if (adt) {
+		bNlaTrack *nlt, *nnlt;
+		
+		/* free nla tracks */
+		for (nlt= adt->nlatracks.first; nlt; nlt= nnlt) {
+			nnlt= nlt->next;
+			free_nlatrack(nlt);
+		}
+		
+		/* free keying sets */
+		BLI_freelistN(&adt->keyingsets);
+		
+		/* free keying types */
+		BLI_freelistN(&adt->keyabletypes);
+		
+		
+		/* unlink id-datablocks from animdata */
+		if (adt->ipo) adt->ipo->id.us--;
+		if (adt->act) adt->act->id.us--;
+	}
+}
 
-	dstrip = *dst;
-	if (dstrip->act)
-		dstrip->act->id.us++;
-
-	if (dstrip->ipo)
-		dstrip->ipo->id.us++;
+/* allocate a new animdata block, and add to stack */
+bAnimData *add_animdata (char name[], int blocktype)
+{
+	bAnimData *adt;
 	
-	if (dstrip->modifiers.first) {
-		duplicatelist (&dstrip->modifiers, &sstrip->modifiers);
-	}
+	adt= alloc_libblock(&G.main->animdata, ID_AD, name);
+	adt->blocktype= blocktype;
 	
+	return adt;
 }
 
-void copy_nlastrips (ListBase *dst, ListBase *src)
-{
-	bActionStrip *strip;
+/* ************************** Tools ************************************* */
 
-	dst->first=dst->last=NULL;
+/* ************************** NLA-Evaluation **************************** */
 
-	duplicatelist (dst, src);
+/* used for list of strips to accumulate at current time */
+typedef struct bNlaEvalStrip {
+	struct bNlaEvalStrip *next, *prev;
+	
+	bNlaTrack *track;			/* track that this strip belongs to */
+	bActionStrip *strip;		/* strip that's being used */
+	
+	short track_index;			/* the index of the track within the list */
+	short strip_mode;			/* which end of the strip are we looking at */
+} bNlaEvalStrip;
 
-	/* Update specific data */
-	if (!dst->first)
-		return;
+/* bNlaEvalStrip->strip_mode */
+enum {
+	NES_TIME_BEFORE = -1,
+	NES_TIME_WITHIN,
+	NES_TIME_AFTER,
+} eNlaEvalStrip_StripMode;
 
-	for (strip = dst->first; strip; strip=strip->next){
-		if (strip->act)
-			strip->act->id.us++;
-		if (strip->ipo)
-			strip->ipo->id.us++;
-		if (strip->modifiers.first) {
-			ListBase listb;
-			duplicatelist (&listb, &strip->modifiers);
-			strip->modifiers= listb;
-		}
-	}
-}
+/* ---------------------- */
 
-/* from editnla, for convert_action_to_strip -- no UI code so should be ok here.. */
-void find_stridechannel(Object *ob, bActionStrip *strip)
+/* evaluates the given evaluation strip */
+static void nlastrip_ctime_evaluate (bAnimData *adt, void *data, bNlaEvalStrip *nes, float ctime)
 {
-	if(ob && ob->pose) {
-		bPoseChannel *pchan;
-		for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next)
-			if(pchan->flag & POSE_STRIDE)
-				break;
-		if(pchan)
-			BLI_strncpy(strip->stridechannel, pchan->name, 32);
-		else
-			strip->stridechannel[0]= 0;
-	}
+	
 }
 
-//called by convert_nla / bpy api with an object with the action to be converted to a new strip
-bActionStrip *convert_action_to_strip (Object *ob)
+/* ---------------------- */
+
+/* gets the strip active at the current time for a track */
+static void nlatrack_ctime_get_strip (ListBase *list, bNlaTrack *nlt, short index, float ctime)
 {
-	bActionStrip *nstrip;
-
-	/* Make new actionstrip */
-	nstrip = MEM_callocN(sizeof(bActionStrip), "bActionStrip");
-			
-	/* Link the action to the nstrip */
-	nstrip->act = ob->action;
-	id_us_plus(&nstrip->act->id);
-	calc_action_range(nstrip->act, &nstrip->actstart, &nstrip->actend, 1);
-	nstrip->start = nstrip->actstart;
-	nstrip->end = nstrip->actend;
-	nstrip->flag = ACTSTRIP_SELECT|ACTSTRIP_LOCK_ACTION;
-			
-	find_stridechannel(ob, nstrip);
-	//set_active_strip(ob, nstrip); /* is in editnla as does UI calls */
-			
-	nstrip->repeat = 1.0;
-
-	if(ob->nlastrips.first == NULL)
-		ob->nlaflag |= OB_NLA_OVERRIDE;
+	bActionStrip *strip, *astrip=NULL;
+	bNlaEvalStrip *nes;
+	short side= 0;
 	
-	BLI_addtail(&ob->nlastrips, nstrip);
-	return nstrip; /* is created, malloced etc. here so is safe to just return the pointer?
-			  this is needed for setting this active in UI, and probably useful for API too */
+	/* skip if track is muted */
+	if (ELEM(NULL, list, nlt)) 
+		return;
+	if (nlt->flag & NLATRACK_MUTE) 
+		return;
 	
+	/* loop over strips, checking if they fall within the range */
+	for (strip= nlt->strips.first; strip; strip= strip->next) {
+		/* only consider if:
+		 *	- current time occurs within strip's extents
+		 *	- current time occurs before strip (if it is the first)
+		 *	- current time occurs after strip (if hold is on)
+		 */
+		if (IN_RANGE(ctime, strip->start, strip->end)) {
+			astrip= strip;
+			side= NES_TIME_WITHIN;
+			break;
+		}
+		else if (ctime < strip->start) {
+			if (strip == nlt->strips.first) {
+				astrip= strip;
+				side= NES_TIME_BEFORE;
+				break;
+			}
+			else {
+				astrip= strip->prev;
+				
+				if (astrip->flag & ACTSTRIP_HOLD) {
+					side= NES_TIME_AFTER;
+					break;
+				}
+				else 
+					return;
+			}
+		}
+	}
+	
+	/* check if strip has been found (and whether it has data worth considering) */
+	if (ELEM3(NULL, astrip, astrip->ipo, astrip->act)) 
+		return;
+	if (astrip->flag & ACTSTRIP_MUTE) 
+		return;
+	
+	
+	/* calculate/set the influence of this strip - don't consider if 0 influence */
+	calc_ipo(astrip->ipo, ctime);
+	apply_anim_ipo(astrip->ipo, astrip);
+	
+	if (astrip->influence <= 0.0f) 
+		return;
+	
+	
+	/* allocate new eval-strip for this strip + add to stack */
+	nes= MEM_callocN(sizeof(bNlaEvalStrip), "bNlaEvalStrip");
+	
+	nes->track= nlt;
+	nes->strip= astrip;
+	nes->track_index= index;
+	nes->strip_mode= side;
+	
+	BLI_addtail(list, nes);
 }
 
+/* ---------------------- */
 
-/* not strip itself! */
-void free_actionstrip(bActionStrip* strip)
+/* NLA Evaluation function (mostly for use through do_animdata) 
+ *	- this doesn't clear values before it starts anymore, as that's supposed to have
+ *	  been handled by the main animation refresh loop already...
+ */
+void do_nla (bAnimData *adt, void *data, float ctime)
 {
-	if (!strip)
+	bNlaTrack *nlt;
+	short track_index=0;
+	
+	ListBase estrips= {NULL, NULL};
+	bNlaEvalStrip *nes;
+	
+	
+	/* error checking */
+	if ((adt == NULL) || (data == NULL)) 
 		return;
-
-	if (strip->act){
-		strip->act->id.us--;
-		strip->act = NULL;
+	
+	/* 1. get the stack of strips to evaluate at current time (influence calculated here) */
+	for (nlt=adt->nlatracks.first; nlt; nlt=nlt->next, track_index++) {
+		nlatrack_ctime_get_strip(&estrips, nlt, track_index, ctime);
 	}
-	if (strip->ipo){
-		strip->ipo->id.us--;
-		strip->ipo = NULL;
+	
+	/* only continue if there are strips to evaluate */
+	if (estrips.first == NULL)
+		return;
+	
+	
+	/* 2. for each strip, evaluate! */
+	for (nes= estrips.first; nes; nes= nes->next) {
+		nlastrip_ctime_evaluate(adt, data, nes, ctime);
 	}
-	if (strip->modifiers.first) {
-		BLI_freelistN(&strip->modifiers);
-	}
 	
+	
+	/* 3. free temporary evaluation strips */
+	BLI_freelistN(&estrips);
 }
 
-void free_nlastrips (ListBase *nlalist)
+/* ************************** Main-Evaluation *************************** */
+

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list