NLA SoC: Adding more backend code/utilities

* Data copying
* Strip sorting
This commit is contained in:
Joshua Leung
2009-05-23 09:36:18 +00:00
parent 3b7f63a088
commit d141aff097
5 changed files with 173 additions and 6 deletions

View File

@@ -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 */

View File

@@ -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);

View File

@@ -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)

View File

@@ -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);

View File

@@ -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