diff options
author | Joshua Leung <aligorith@gmail.com> | 2009-05-31 08:52:20 +0400 |
---|---|---|
committer | Joshua Leung <aligorith@gmail.com> | 2009-05-31 08:52:20 +0400 |
commit | c42eeddea491d6a79dbcc0b8b28386237085643d (patch) | |
tree | e50202f2c2f72a32b321c11b0db0092f21ba41e8 /source/blender | |
parent | 2e85686fe379f99c27944e3e4b5842d89e620f3b (diff) |
NLA SoC: Bugfixes + Improvements to 'Push Down' track-selection
* Trying to save no longer crashes in some cases when the NLA Editor was open with some data. The sanity check added in filesel.c might be able to be backported to 2.5? (Elubie, please check)
* NLA-track names now get drawn with the correct colours for identifying themselves as being selected or not selected.
* Now the 'push down' functionality for actions will try to add the new strip to the last NLA track, provided it has space in the range required.
* When new strips are added, they will only be allowed to extrapolate before/after if they are the first (time-wise) strip for the set of NLA data per AnimData block. This stops layered strips overriding strips that occurred in earlier tracks at earlier times.
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/blenkernel/BKE_nla.h | 3 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/nla.c | 156 | ||||
-rw-r--r-- | source/blender/editors/animation/anim_channels.c | 14 | ||||
-rw-r--r-- | source/blender/editors/space_file/filesel.c | 3 | ||||
-rw-r--r-- | source/blender/editors/space_nla/nla_draw.c | 11 |
5 files changed, 142 insertions, 45 deletions
diff --git a/source/blender/blenkernel/BKE_nla.h b/source/blender/blenkernel/BKE_nla.h index 49796250633..ededd77a92f 100644 --- a/source/blender/blenkernel/BKE_nla.h +++ b/source/blender/blenkernel/BKE_nla.h @@ -46,8 +46,9 @@ 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); +struct NlaStrip *add_nlastrip(struct bAction *act); +struct NlaStrip *add_nlastrip_to_stack(struct AnimData *adt, struct bAction *act); /* ----------------------------- */ /* API */ diff --git a/source/blender/blenkernel/intern/nla.c b/source/blender/blenkernel/intern/nla.c index 62500af85ff..3efa823f9fe 100644 --- a/source/blender/blenkernel/intern/nla.c +++ b/source/blender/blenkernel/intern/nla.c @@ -215,19 +215,45 @@ void copy_nladata (ListBase *dst, ListBase *src) /* 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) +/* Add a NLA Track to the given AnimData */ +NlaTrack *add_nlatrack (AnimData *adt) +{ + 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; +} + +/* Add a NLA Strip referencing the given Action */ +NlaStrip *add_nlastrip (bAction *act) { NlaStrip *strip; /* sanity checks */ - if ELEM(NULL, nlt, act) + if (act == NULL) 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 @@ -259,32 +285,54 @@ NlaStrip *add_nlastrip (NlaTrack *nlt, bAction *act) return strip; } -/* Add a NLA Track to the given AnimData */ -NlaTrack *add_nlatrack (AnimData *adt) +/* Add new NLA-strip to the top of the NLA stack - i.e. into the last track if space, or a new one otherwise */ +NlaStrip *add_nlastrip_to_stack (AnimData *adt, bAction *act) { + NlaStrip *strip, *ns; NlaTrack *nlt; + short not_added = 1; /* sanity checks */ - if (adt == NULL) + if ELEM(NULL, adt, act) 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); + /* create a new NLA strip */ + strip= add_nlastrip(act); + if (strip == NULL) + return NULL; - /* add track to stack, and make it the active one */ - BLI_addtail(&adt->nla_tracks, nlt); - BKE_nlatrack_set_active(&adt->nla_tracks, nlt); + /* check if the last NLA-track (if it exists) has any space for this strip: + * - if so, add this strip to that track + */ + if ( (adt->nla_tracks.last == NULL) || + (BKE_nlatrack_has_space(adt->nla_tracks.last, strip->start, strip->end)==0) ) + { + /* no space, so add to a new track... */ + nlt= add_nlatrack(adt); + } + else + { + /* there's some space, so add to this track... */ + nlt= adt->nla_tracks.last; + } - /* 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); + /* find the right place to add the strip to the nominated track */ + for (ns= nlt->strips.first; ns; ns= ns->next) { + /* if current strip occurs after the new strip, add it before */ + if (ns->start > strip->end) { + BLI_insertlinkbefore(&nlt->strips, ns, strip); + not_added= 0; + break; + } + } + if (not_added) { + /* just add to the end of the list of the strips then... */ + BLI_addtail(&nlt->strips, strip); + } - /* return the new track */ - return nlt; + + /* returns the strip added */ + return strip; } /* *************************************************** */ @@ -404,7 +452,39 @@ void BKE_nlatrack_sort_strips (NlaTrack *nlt) nlt->strips.first= tmp.first; nlt->strips.last= tmp.last; } - + +/* NLA Strips -------------------------------------- */ + +/* Is the given NLA-strip the first one to occur for the given AnimData block */ +// TODO: make this an api method if necesary, but need to add prefix first +short nlastrip_is_first (AnimData *adt, NlaStrip *strip) +{ + NlaTrack *nlt; + NlaStrip *ns; + + /* sanity checks */ + if ELEM(NULL, adt, strip) + return 0; + + /* check if strip has any strips before it */ + if (strip->prev) + return 0; + + /* check other tracks to see if they have a strip that's earlier */ + // TODO: or should we check that the strip's track is also the first? + for (nlt= adt->nla_tracks.first; nlt; nlt= nlt->next) { + /* only check the first strip, assuming that they're all in order */ + ns= nlt->strips.first; + if (ns) { + if (ns->start < strip->start) + return 0; + } + } + + /* should be first now */ + return 1; +} + /* Tools ------------------------------------------- */ /* For the given AnimData block, add the active action to the NLA @@ -415,7 +495,6 @@ void BKE_nlatrack_sort_strips (NlaTrack *nlt) // TODO: maybe we should have checks for this too... void BKE_nla_action_pushdown (AnimData *adt) { - NlaTrack *nlt; NlaStrip *strip; /* sanity checks */ @@ -431,28 +510,27 @@ void BKE_nla_action_pushdown (AnimData *adt) printf("BKE_nla_action_pushdown(): action has no data \n"); return; } - - /* 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) { - printf("BKE_nla_action_pushdown(): no NLA-track added \n"); - return; - } /* add a new NLA strip to the track, which references the active action */ - strip= add_nlastrip(nlt, adt->action); + strip= add_nlastrip_to_stack(adt, adt->action); - /* clear reference to action now that we've pushed it onto the stack */ + /* do other necessary work on strip */ if (strip) { + /* clear reference to action now that we've pushed it onto the stack */ adt->action->id.us--; adt->action= NULL; + + /* if the strip is the first one in the track it lives in, check if there + * are strips in any other tracks that may be before this, and set the extend + * mode accordingly + */ + if (nlastrip_is_first(adt, strip) == 0) { + /* not first, so extend mode can only be NLASTRIP_EXTEND_HOLD_FORWARD not NLASTRIP_EXTEND_HOLD, + * so that it doesn't override strips in previous tracks + */ + strip->extendmode= NLASTRIP_EXTEND_HOLD_FORWARD; + } } - - // TODO: set any other flags necessary here... } /* *************************************************** */ diff --git a/source/blender/editors/animation/anim_channels.c b/source/blender/editors/animation/anim_channels.c index a5f2acb591c..5d5be87801b 100644 --- a/source/blender/editors/animation/anim_channels.c +++ b/source/blender/editors/animation/anim_channels.c @@ -149,6 +149,13 @@ void ANIM_set_active_channel (void *data, short datatype, int filter, void *chan ACHANNEL_SET_FLAG(fcu, ACHANNEL_SETFLAG_CLEAR, FCURVE_ACTIVE); } break; + case ANIMTYPE_NLATRACK: + { + NlaTrack *nlt= (NlaTrack *)ale->data; + + ACHANNEL_SET_FLAG(nlt, ACHANNEL_SETFLAG_CLEAR, NLATRACK_ACTIVE); + } + break; } } @@ -167,6 +174,13 @@ void ANIM_set_active_channel (void *data, short datatype, int filter, void *chan fcu->flag |= FCURVE_ACTIVE; } break; + case ANIMTYPE_NLATRACK: + { + NlaTrack *nlt= (NlaTrack *)channel_data; + + ACHANNEL_SET_FLAG(nlt, ACHANNEL_SETFLAG_CLEAR, NLATRACK_ACTIVE); + } + break; } } diff --git a/source/blender/editors/space_file/filesel.c b/source/blender/editors/space_file/filesel.c index cbd1457e562..091319cd402 100644 --- a/source/blender/editors/space_file/filesel.c +++ b/source/blender/editors/space_file/filesel.c @@ -144,6 +144,9 @@ int ED_fileselect_layout_offset(FileLayout* layout, int x, int y) int offsetx, offsety; int active_file; + if (layout == NULL) + return NULL; + offsetx = (x)/(layout->tile_w + 2*layout->tile_border_x); offsety = (y)/(layout->tile_h + 2*layout->tile_border_y); diff --git a/source/blender/editors/space_nla/nla_draw.c b/source/blender/editors/space_nla/nla_draw.c index 28572704302..1a289d8436b 100644 --- a/source/blender/editors/space_nla/nla_draw.c +++ b/source/blender/editors/space_nla/nla_draw.c @@ -296,7 +296,7 @@ void draw_nla_channel_list (bAnimContext *ac, SpaceNla *snla, ARegion *ar) indent= 0; special= ICON_SCENE_DATA; - + /* only show expand if there are any channels */ if (EXPANDED_SCEC(sce)) expand= ICON_TRIA_UP; @@ -484,6 +484,7 @@ void draw_nla_channel_list (bAnimContext *ac, SpaceNla *snla, ARegion *ar) else protect = ICON_LOCKED; + sel = SEL_NLT(nlt); strcpy(name, nlt->name); } break; @@ -621,10 +622,10 @@ void draw_nla_channel_list (bAnimContext *ac, SpaceNla *snla, ARegion *ar) /* XXX firstly draw a little rect to help identify that it's different from the toggles */ glBegin(GL_LINE_LOOP); - glVertex2f((float)NLACHANNEL_NAMEWIDTH-offset-1, y-8); - glVertex2f((float)NLACHANNEL_NAMEWIDTH-offset-1, y+8); - glVertex2f((float)NLACHANNEL_NAMEWIDTH-1, y-8); - glVertex2f((float)NLACHANNEL_NAMEWIDTH-1, y+8); + glVertex2f((float)NLACHANNEL_NAMEWIDTH-offset-1, y-7); + glVertex2f((float)NLACHANNEL_NAMEWIDTH-offset-1, y+9); + glVertex2f((float)NLACHANNEL_NAMEWIDTH-1, y+9); + glVertex2f((float)NLACHANNEL_NAMEWIDTH-1, y-7); glEnd(); // GL_LINES /* now draw the icon */ |