diff options
author | Joshua Leung <aligorith@gmail.com> | 2009-05-23 13:36:18 +0400 |
---|---|---|
committer | Joshua Leung <aligorith@gmail.com> | 2009-05-23 13:36:18 +0400 |
commit | d141aff097d17c106071f2ad966fdd97a1fb5ba4 (patch) | |
tree | ff73c044d7edd438798021d2f1c9c9f03cb52d91 | |
parent | 3b7f63a0884c6ec9db5abb938708f4191ea35274 (diff) |
NLA SoC: Adding more backend code/utilities
* Data copying
* Strip sorting
-rw-r--r-- | source/blender/blenkernel/BKE_action.h | 3 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_nla.h | 9 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/action.c | 17 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/anim_sys.c | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/nla.c | 148 |
5 files changed, 173 insertions, 6 deletions
diff --git a/source/blender/blenkernel/BKE_action.h b/source/blender/blenkernel/BKE_action.h index 67eb2ed58bf..cc10a4071a6 100644 --- a/source/blender/blenkernel/BKE_action.h +++ b/source/blender/blenkernel/BKE_action.h @@ -68,6 +68,9 @@ void make_local_action(struct bAction *act); /* Some kind of bounding box operation on the action */ void calc_action_range(const struct bAction *act, float *start, float *end, int incl_hidden); +/* Does action have any motion data at all? */ +short action_has_motion(const struct bAction *act); + /* Action Groups API ----------------- */ /* Make the given Action Group the active one */ diff --git a/source/blender/blenkernel/BKE_nla.h b/source/blender/blenkernel/BKE_nla.h index 3864d9da5f6..49796250633 100644 --- a/source/blender/blenkernel/BKE_nla.h +++ b/source/blender/blenkernel/BKE_nla.h @@ -42,6 +42,10 @@ void free_nlastrip(ListBase *strips, struct NlaStrip *strip); void free_nlatrack(ListBase *tracks, struct NlaTrack *nlt); void free_nladata(ListBase *tracks); +struct NlaStrip *copy_nlastrip(struct NlaStrip *strip); +struct NlaTrack *copy_nlatrack(struct NlaTrack *nlt); +void copy_nladata(ListBase *dst, ListBase *src); + struct NlaStrip *add_nlastrip(struct NlaTrack *nlt, struct bAction *act); struct NlaTrack *add_nlatrack(struct AnimData *adt); @@ -49,7 +53,10 @@ 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_nlatrack_set_active(ListBase *tracks, struct NlaTrack *nlt); + +short BKE_nlatrack_has_space(struct NlaTrack *nlt, float start, float end); +void BKE_nlatrack_sort_strips(struct NlaTrack *nlt); void BKE_nla_action_pushdown(struct AnimData *adt); diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c index f2e3583c87b..bb458cc7e25 100644 --- a/source/blender/blenkernel/intern/action.c +++ b/source/blender/blenkernel/intern/action.c @@ -740,7 +740,22 @@ float get_action_frame_inv(Object *ob, float cframe) } - +/* Check if the given action has any keyframes */ +short action_has_motion(const bAction *act) +{ + FCurve *fcu; + + /* return on the first F-Curve that has some keyframes/samples defined */ + if (act) { + for (fcu= act->curves.first; fcu; fcu= fcu->next) { + if (fcu->totvert) + return 1; + } + } + + /* nothing found */ + return 0; +} /* Calculate the extents of given action */ void calc_action_range(const bAction *act, float *start, float *end, int incl_hidden) diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c index b47d734ef4f..f21fed416cc 100644 --- a/source/blender/blenkernel/intern/anim_sys.c +++ b/source/blender/blenkernel/intern/anim_sys.c @@ -153,7 +153,7 @@ AnimData *BKE_copy_animdata (AnimData *adt) dadt->action= copy_action(adt->action); /* duplicate NLA data */ - // XXX todo... + copy_nladata(&dadt->nla_tracks, &adt->nla_tracks); /* duplicate drivers (F-Curves) */ copy_fcurves(&dadt->drivers, &adt->drivers); diff --git a/source/blender/blenkernel/intern/nla.c b/source/blender/blenkernel/intern/nla.c index ac767fe86cc..d062a2ab14b 100644 --- a/source/blender/blenkernel/intern/nla.c +++ b/source/blender/blenkernel/intern/nla.c @@ -145,7 +145,73 @@ void free_nladata (ListBase *tracks) /* Copying ------------------------------------------- */ -// TODO... +/* Copy NLA strip */ +NlaStrip *copy_nlastrip (NlaStrip *strip) +{ + NlaStrip *strip_d; + + /* sanity check */ + if (strip == NULL) + return NULL; + + /* make a copy */ + strip_d= MEM_dupallocN(strip); + strip_d->next= strip_d->prev= NULL; + + /* increase user-count of action */ + if (strip_d->act) + strip_d->act->id.us++; + + /* copy F-Curves and modifiers */ + copy_fcurves(&strip_d->fcurves, &strip->fcurves); + fcurve_copy_modifiers(&strip_d->modifiers, &strip->modifiers); + + /* return the strip */ + return strip_d; +} + +/* Copy NLA Track */ +NlaTrack *copy_nlatrack (NlaTrack *nlt) +{ + NlaStrip *strip, *strip_d; + NlaTrack *nlt_d; + + /* sanity check */ + if (nlt == NULL) + return NULL; + + /* make a copy */ + nlt_d= MEM_dupallocN(nlt); + nlt_d->next= nlt_d->prev= NULL; + + /* make a copy of all the strips, one at a time */ + nlt_d->strips.first= nlt_d->strips.last= NULL; + + for (strip= nlt->strips.first; strip; strip= strip->next) { + strip_d= copy_nlastrip(strip); + BLI_addtail(&nlt_d->strips, strip_d); + } + + /* return the copy */ + return nlt_d; +} + +/* Copy all NLA data */ +void copy_nladata (ListBase *dst, ListBase *src) +{ + NlaTrack *nlt, *nlt_d; + + /* sanity checks */ + if ELEM(NULL, dst, src) + return; + + /* copy each NLA-track, one at a time */ + for (nlt= src->first; nlt; nlt= nlt->next) { + /* make a copy, and add the copy to the destination list */ + nlt_d= copy_nlatrack(nlt); + BLI_addtail(dst, nlt_d); + } +} /* Adding ------------------------------------------- */ @@ -224,7 +290,7 @@ NlaTrack *add_nlatrack (AnimData *adt) /* *************************************************** */ /* Basic Utilities */ -/* States ------------------------------------------- */ +/* NLA-Tracks ---------------------------------------- */ /* Find the active NLA-track for the given stack */ NlaTrack *BKE_nlatrack_find_active (ListBase *tracks) @@ -265,6 +331,80 @@ void BKE_nlatrack_set_active (ListBase *tracks, NlaTrack *nlt_a) nlt_a->flag |= NLATRACK_ACTIVE; } +/* Check if there is any space in the last track to add the given strip */ +short BKE_nlatrack_has_space (NlaTrack *nlt, float start, float end) +{ + NlaStrip *strip; + + /* sanity checks */ + if ((nlt == NULL) || IS_EQ(start, end)) + return 0; + if (start > end) { + puts("BKE_nlatrack_has_space error... start and end arguments swapped"); + SWAP(float, start, end); + } + + /* loop over NLA strips checking for any overlaps with this area... */ + for (strip= nlt->strips.first; strip; strip= strip->next) { + /* if start frame of strip is past the target end-frame, that means that + * we've gone past the window we need to check for, so things are fine + */ + if (strip->start > end) + return 1; + + /* if the end of the strip is greater than either of the boundaries, the range + * must fall within the extents of the strip + */ + if ((strip->end > start) || (strip->end > end)) + return 0; + } + + /* if we are still here, we haven't encountered any overlapping strips */ + return 1; +} + +/* Rearrange the strips in the track so that they are always in order + * (usually only needed after a strip has been moved) + */ +void BKE_nlatrack_sort_strips (NlaTrack *nlt) +{ + ListBase tmp = {NULL, NULL}; + NlaStrip *strip, *sstrip; + + /* sanity checks */ + if ELEM(NULL, nlt, nlt->strips.first) + return; + + /* we simply perform insertion sort on this list, since it is assumed that per track, + * there are only likely to be at most 5-10 strips + */ + for (strip= nlt->strips.first; strip; strip= strip->next) { + short not_added = 1; + + /* remove this strip from the list, and add it to the new list, searching from the end of + * the list, assuming that the lists are in order + */ + BLI_remlink(&nlt->strips, strip); + + for (sstrip= tmp.last; not_added && sstrip; sstrip= sstrip->prev) { + /* check if add after */ + if (sstrip->end < strip->start) { + BLI_insertlinkafter(&tmp, sstrip, strip); + not_added= 0; + break; + } + } + + /* add before first? */ + if (not_added) + BLI_addhead(&tmp, strip); + } + + /* reassign the start and end points of the strips */ + nlt->strips.first= tmp.first; + nlt->strips.last= tmp.last; +} + /* Tools ------------------------------------------- */ /* For the given AnimData block, add the active action to the NLA @@ -286,7 +426,9 @@ void BKE_nla_action_pushdown (AnimData *adt) /* 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... + // TODO: what about modifiers? + if (action_has_motion(adt->action) == 0) + return; /* add a new NLA track to house this action * - we could investigate trying to fit the action into an appropriately |