diff options
author | Joshua Leung <aligorith@gmail.com> | 2009-05-22 05:16:26 +0400 |
---|---|---|
committer | Joshua Leung <aligorith@gmail.com> | 2009-05-22 05:16:26 +0400 |
commit | 9b1ce6e55608e868a1fa1bc62710e053919c39de (patch) | |
tree | 1b9da9a2767f43ffbd590ce591d1edfc5e4f41be /source/blender | |
parent | cebf6cb22deb930f5ec235e81c20072bf7154a83 (diff) |
NLA SoC: Part 1 of NLA-Data Management API
In this commit:
* Added code for freeing NLA data now stored in AnimData
* Started writing some utilities for adding NLA data, especially the 'push-down' concept for Actions
* Cleanups of existing code - removal of obsolete NLA code from various places
Next commits/parts:
* File IO code for new-style NLA data
* Version patching for old data to new data
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/blenkernel/BKE_nla.h | 33 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/anim_sys.c | 7 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/nla.c | 345 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/object.c | 8 | ||||
-rw-r--r-- | source/blender/editors/space_nla/space_nla.c | 1 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_anim_types.h | 4 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_space_types.h | 2 |
7 files changed, 270 insertions, 130 deletions
diff --git a/source/blender/blenkernel/BKE_nla.h b/source/blender/blenkernel/BKE_nla.h index 230096d7ea7..0f23a5cb44d 100644 --- a/source/blender/blenkernel/BKE_nla.h +++ b/source/blender/blenkernel/BKE_nla.h @@ -17,12 +17,12 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * The Original Code is Copyright (C) 2009 Blender Foundation, Joshua Leung * All rights reserved. * * The Original Code is: all of this file. * - * Contributor(s): none yet. + * Contributor(s): Joshua Leung (full recode) * * ***** END GPL LICENSE BLOCK ***** */ @@ -30,15 +30,26 @@ #ifndef BKE_NLA_H #define BKE_NLA_H -struct bActionStrip; -struct ListBase; -struct Object; +struct AnimData; +struct NlaStrip; +struct NlaTrack; + +/* ----------------------------- */ +/* Data Management */ + +void free_nlastrip(ListBase *strips, struct NlaStrip *strip); +void free_nlatrack(ListBase *tracks, struct NlaTrack *nlt); +void free_nladata(ListBase *tracks); + +struct NlaTrack *add_nlatrack(struct AnimData *adt); + +/* ----------------------------- */ +/* API */ + +struct NlaTrack *BKE_nlatrack_find_active(ListBase *tracks); +void BKE_nlatrack_set_active(ListBase *tracks, struct NlaTrack *nlt_a); + +void BKE_nla_action_pushdown(struct AnimData *adt); -void free_actionstrip (struct bActionStrip* strip); -void free_nlastrips (struct ListBase *nlalist); -void copy_nlastrips (struct ListBase *dst, struct ListBase *src); -void copy_actionstrip (struct bActionStrip **dst, struct bActionStrip **src); -void find_stridechannel(struct Object *ob, struct bActionStrip *strip); -struct bActionStrip *convert_action_to_strip (struct Object *ob); #endif diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c index 702da23ef47..b47d734ef4f 100644 --- a/source/blender/blenkernel/intern/anim_sys.c +++ b/source/blender/blenkernel/intern/anim_sys.c @@ -17,6 +17,7 @@ #include "BKE_animsys.h" #include "BKE_action.h" #include "BKE_fcurve.h" +#include "BKE_nla.h" #include "BKE_global.h" #include "BKE_main.h" #include "BKE_utildefines.h" @@ -118,6 +119,9 @@ void BKE_free_animdata (ID *id) if (adt->action) adt->action->id.us--; + /* free nla data */ + free_nladata(&adt->nla_tracks); + /* free drivers - stored as a list of F-Curves */ free_fcurves(&adt->drivers); @@ -982,6 +986,9 @@ static void nladata_flush_channels (ListBase *channels) case PROP_ENUM: RNA_property_enum_set(ptr, prop, (int)value); break; + default: + // can't do anything with other types of property.... + break; } } } diff --git a/source/blender/blenkernel/intern/nla.c b/source/blender/blenkernel/intern/nla.c index dc2bf26759f..ac767fe86cc 100644 --- a/source/blender/blenkernel/intern/nla.c +++ b/source/blender/blenkernel/intern/nla.c @@ -17,171 +17,296 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * The Original Code is Copyright (C) 2009 Blender Foundation, Joshua Leung * All rights reserved. * * The Original Code is: all of this file. * - * Contributor(s): none yet. + * Contributor(s): Joshua Leung (full recode) * * ***** END GPL LICENSE BLOCK ***** */ #include <stdlib.h> +#include <stddef.h> +#include <stdio.h> +#include <math.h> +#include <float.h> #include "MEM_guardedalloc.h" #include "BLI_blenlib.h" -#include "DNA_space_types.h" -#include "DNA_nla_types.h" +#include "DNA_anim_types.h" #include "DNA_action_types.h" -#include "DNA_ID.h" -#include "DNA_ipo_types.h" -#include "DNA_object_types.h" -#include "BKE_nla.h" +#include "BKE_animsys.h" #include "BKE_action.h" +#include "BKE_fcurve.h" +#include "BKE_nla.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 */ -void copy_actionstrip (bActionStrip **dst, bActionStrip **src){ - bActionStrip *dstrip; - bActionStrip *sstrip = *src; +/* *************************************************** */ +/* Data Management */ - if (!*src){ - *dst=NULL; +/* Freeing ------------------------------------------- */ + +/* Remove the given NLA strip from the NLA track it occupies, free the strip's data, + * and the strip itself. + */ +// TODO: with things like transitions, should these get freed too? Maybe better as a UI tool +void free_nlastrip (ListBase *strips, NlaStrip *strip) +{ + FModifier *fcm, *fmn; + + /* sanity checks */ + if (strip == NULL) return; + + /* remove reference to action */ + if (strip->act) + strip->act->id.us--; + + /* free remapping info */ + //if (strip->remap) + // BKE_animremap_free(); + + /* free own F-Curves */ + free_fcurves(&strip->fcurves); + + /* free F-Modifiers */ + for (fcm= strip->modifiers.first; fcm; fcm= fmn) { + fmn= fcm->next; + + BLI_remlink(&strip->modifiers, fcm); + fcurve_remove_modifier(NULL, fcm); } + + /* free the strip itself */ + if (strips) + BLI_freelinkN(strips, strip); + else + MEM_freeN(strip); +} - *dst = MEM_dupallocN(sstrip); - - dstrip = *dst; - if (dstrip->act) - dstrip->act->id.us++; - - if (dstrip->ipo) - dstrip->ipo->id.us++; +/* Remove the given NLA track from the set of NLA tracks, free the track's data, + * and the track itself. + */ +void free_nlatrack (ListBase *tracks, NlaTrack *nlt) +{ + NlaStrip *strip, *stripn; - if (dstrip->modifiers.first) { - BLI_duplicatelist (&dstrip->modifiers, &sstrip->modifiers); + /* sanity checks */ + if (nlt == NULL) + return; + + /* free strips */ + for (strip= nlt->strips.first; strip; strip= stripn) { + stripn= strip->next; + free_nlastrip(&nlt->strips, strip); } + /* free NLA track itself now */ + if (tracks) + BLI_freelinkN(tracks, nlt); + else + MEM_freeN(nlt); } -void copy_nlastrips (ListBase *dst, ListBase *src) +/* Free the elements of type NLA Tracks provided in the given list, but do not free + * the list itself since that is not free-standing + */ +void free_nladata (ListBase *tracks) { - bActionStrip *strip; - - dst->first=dst->last=NULL; - - BLI_duplicatelist (dst, src); - - /* Update specific data */ - if (!dst->first) + NlaTrack *nlt, *nltn; + + /* sanity checks */ + if ELEM(NULL, tracks, tracks->first) return; - - 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; - BLI_duplicatelist (&listb, &strip->modifiers); - strip->modifiers= listb; - } + + /* free tracks one by one */ + for (nlt= tracks->first; nlt; nlt= nltn) { + nltn= nlt->next; + free_nlatrack(tracks, nlt); } + + /* clear the list's pointers to be safe */ + tracks->first= tracks->last= NULL; } -/* from editnla, for convert_action_to_strip -- no UI code so should be ok here.. */ -void find_stridechannel(Object *ob, bActionStrip *strip) +/* Copying ------------------------------------------- */ + +// TODO... + +/* Adding ------------------------------------------- */ + +/* Add a NLA Strip referencing the given Action, to the given NLA Track */ +// TODO: any extra parameters to control how this is done? +NlaStrip *add_nlastrip (NlaTrack *nlt, bAction *act) { - 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; - } + NlaStrip *strip; + + /* sanity checks */ + if ELEM(NULL, nlt, act) + return NULL; + + /* allocate new strip */ + strip= MEM_callocN(sizeof(NlaStrip), "NlaStrip"); + BLI_addtail(&nlt->strips, strip); + + /* generic settings + * - selected flag to highlight this to the user + * - auto-blends to ensure that blend in/out values are automatically + * determined by overlaps of strips + * - (XXX) synchronisation of strip-length in accordance with changes to action-length + * is not done though, since this should only really happens in editmode for strips now + * though this decision is still subject to further review... + */ + strip->flag = NLASTRIP_FLAG_SELECT|NLASTRIP_FLAG_AUTO_BLENDS; + + /* assign the action reference */ + strip->act= act; + id_us_plus(&act->id); + + /* determine initial range + * - strip length cannot be 0... ever... + */ + calc_action_range(strip->act, &strip->actstart, &strip->actend, 1); + + strip->start = strip->actstart; + strip->end = (IS_EQ(strip->actstart, strip->actend)) ? (strip->actstart + 1.0f): (strip->actend); + + /* strip should be referenced as-is */ + strip->scale= 1.0f; + strip->repeat = 1.0f; + + /* return the new strip */ + return strip; } -//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) +/* Add a NLA Track to the given AnimData */ +NlaTrack *add_nlatrack (AnimData *adt) { - 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; - - 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 */ + NlaTrack *nlt; + + /* sanity checks */ + if (adt == NULL) + return NULL; + + /* allocate new track */ + nlt= MEM_callocN(sizeof(NlaTrack), "NlaTrack"); + + /* set settings requiring the track to not be part of the stack yet */ + nlt->flag = NLATRACK_SELECTED; + nlt->index= BLI_countlist(&adt->nla_tracks); + + /* add track to stack, and make it the active one */ + BLI_addtail(&adt->nla_tracks, nlt); + BKE_nlatrack_set_active(&adt->nla_tracks, nlt); + + /* must have unique name, but we need to seed this */ + sprintf(nlt->name, "NlaTrack"); + BLI_uniquename(&adt->nla_tracks, nlt, "NlaTrack", '.', offsetof(NlaTrack, name), 64); + /* return the new track */ + return nlt; } +/* *************************************************** */ +/* Basic Utilities */ -/* not strip itself! */ -void free_actionstrip(bActionStrip* strip) -{ - if (!strip) - return; +/* States ------------------------------------------- */ - if (strip->act){ - strip->act->id.us--; - strip->act = NULL; - } - if (strip->ipo){ - strip->ipo->id.us--; - strip->ipo = NULL; - } - if (strip->modifiers.first) { - BLI_freelistN(&strip->modifiers); +/* Find the active NLA-track for the given stack */ +NlaTrack *BKE_nlatrack_find_active (ListBase *tracks) +{ + NlaTrack *nlt; + + /* sanity check */ + if ELEM(NULL, tracks, tracks->first) + return NULL; + + /* try to find the first active track */ + for (nlt= tracks->first; nlt; nlt= nlt->next) { + if (nlt->flag & NLATRACK_ACTIVE) + return nlt; } + /* none found */ + return NULL; } -void free_nlastrips (ListBase *nlalist) +/* Make the given NLA-track the active one for the given stack. If no track is provided, + * this function can be used to simply deactivate all the NLA tracks in the given stack too. + */ +void BKE_nlatrack_set_active (ListBase *tracks, NlaTrack *nlt_a) { - bActionStrip *strip; - - if (!nlalist->first) + NlaTrack *nlt; + + /* sanity check */ + if ELEM(NULL, tracks, tracks->first) return; + + /* deactive all the rest */ + for (nlt= tracks->first; nlt; nlt= nlt->next) + nlt->flag &= ~NLATRACK_ACTIVE; + + /* set the given one as the active one */ + if (nlt_a) + nlt_a->flag |= NLATRACK_ACTIVE; +} - /* Do any specific freeing */ - for (strip=nlalist->first; strip; strip=strip->next) - { - free_actionstrip (strip); - }; +/* Tools ------------------------------------------- */ - /* Free the whole list */ - BLI_freelistN(nlalist); +/* For the given AnimData block, add the active action to the NLA + * stack (i.e. 'push-down' action). The UI should only allow this + * for normal editing only (i.e. not in editmode for some strip's action), + * so no checks for this are performed. + */ +// TODO: maybe we should have checks for this too... +void BKE_nla_action_pushdown (AnimData *adt) +{ + NlaTrack *nlt; + NlaStrip *strip; + + /* sanity checks */ + // TODO: need to report the error for this + if ELEM(NULL, adt, adt->action) + return; + + /* if the action is empty, we also shouldn't try to add to stack, + * as that will cause us grief down the track + */ + // TODO: code a method for this, and report errors after... + + /* add a new NLA track to house this action + * - we could investigate trying to fit the action into an appropriately + * sized gap in the existing tracks, however, this may result in unexpected + * changes in blending behaviour... + */ + nlt= add_nlatrack(adt); + if (nlt == NULL) + return; + + /* add a new NLA strip to the track, which references the active action */ + strip= add_nlastrip(nlt, adt->action); + + /* clear reference to action now that we've pushed it onto the stack */ + if (strip) { + adt->action->id.us--; + adt->action= NULL; + } + + // TODO: set any other flags necessary here... } + +/* *************************************************** */ diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index b913651d856..b0902784687 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -1193,18 +1193,12 @@ Object *copy_object(Object *ob) armature_rebuild_pose(obn, obn->data); } copy_defgroups(&obn->defbase, &ob->defbase); -#if 0 // XXX old animation system - copy_nlastrips(&obn->nlastrips, &ob->nlastrips); -#endif // XXX old animation system copy_constraints(&obn->constraints, &ob->constraints); /* increase user numbers */ id_us_plus((ID *)obn->data); -#if 0 // XXX old animation system - id_us_plus((ID *)obn->ipo); - id_us_plus((ID *)obn->action); -#endif // XXX old animation system id_us_plus((ID *)obn->dup_group); + // FIXME: add this for animdata too... for(a=0; a<obn->totcol; a++) id_us_plus((ID *)obn->mat[a]); diff --git a/source/blender/editors/space_nla/space_nla.c b/source/blender/editors/space_nla/space_nla.c index 6e1a97dea34..188315c73fb 100644 --- a/source/blender/editors/space_nla/space_nla.c +++ b/source/blender/editors/space_nla/space_nla.c @@ -29,6 +29,7 @@ #include <string.h> #include <stdio.h> +#include "DNA_anim_types.h" #include "DNA_nla_types.h" #include "DNA_object_types.h" #include "DNA_space_types.h" diff --git a/source/blender/makesdna/DNA_anim_types.h b/source/blender/makesdna/DNA_anim_types.h index c0cdc1ab589..b20ec7ba37f 100644 --- a/source/blender/makesdna/DNA_anim_types.h +++ b/source/blender/makesdna/DNA_anim_types.h @@ -395,7 +395,7 @@ typedef struct AnimMapper { typedef struct NlaStrip { struct NlaStrip *next, *prev; - bAction *act; /* Action that is referenced by this strip */ + bAction *act; /* Action that is referenced by this strip (strip is 'user' of the action) */ AnimMapper *remap; /* Remapping info this strip (for tweaking correspondance of action with context) */ ListBase fcurves; /* F-Curves for controlling this strip's influence and timing */ // TODO: move out? @@ -458,6 +458,8 @@ enum { /* NLA strip is muted (i.e. doesn't contribute in any way) */ // TODO: this overlaps a lot with the functionality in track NLASTRIP_FLAG_MUTED = (1<<12), + /* NLA strip length is synced to the length of the referenced action */ + NLASTRIP_FLAG_SYNC_LENGTH = (1<<13), } eNlaStrip_Flag; /* NLA Strip Type */ diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index 0e19a6845da..0a4fe1c5814 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -244,7 +244,7 @@ typedef struct SpaceNla { short blockhandler[8]; - short menunr, lock; + int filterflag; /* filtering flags (similar to the ones used for Keyframe Editors) */ short autosnap; /* this uses the same settings as autosnap for Action Editor */ short flag; |