diff options
-rw-r--r-- | source/blender/blenkernel/BKE_nla.h | 8 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/anim_sys.c | 47 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/nla.c | 213 | ||||
-rw-r--r-- | source/blender/blenloader/intern/readfile.c | 75 | ||||
-rw-r--r-- | source/blender/blenloader/intern/writefile.c | 30 | ||||
-rw-r--r-- | source/blender/editors/space_nla/nla_edit.c | 120 | ||||
-rw-r--r-- | source/blender/editors/space_nla/nla_intern.h | 11 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_anim_types.h | 9 |
8 files changed, 385 insertions, 128 deletions
diff --git a/source/blender/blenkernel/BKE_nla.h b/source/blender/blenkernel/BKE_nla.h index e2b1dd89deb..efa0591bd53 100644 --- a/source/blender/blenkernel/BKE_nla.h +++ b/source/blender/blenkernel/BKE_nla.h @@ -53,6 +53,13 @@ struct NlaStrip *add_nlastrip_to_stack(struct AnimData *adt, struct bAction *act /* ----------------------------- */ /* API */ +short BKE_nlastrips_has_space(ListBase *strips, float start, float end); +void BKE_nlastrips_sort_strips(ListBase *strips); + +short BKE_nlastrips_add_strip(ListBase *strips, struct NlaStrip *strip); + +/* ............ */ + struct NlaTrack *BKE_nlatrack_find_active(ListBase *tracks); void BKE_nlatrack_set_active(ListBase *tracks, struct NlaTrack *nlt); @@ -63,6 +70,7 @@ void BKE_nlatrack_sort_strips(struct NlaTrack *nlt); short BKE_nlatrack_add_strip(struct NlaTrack *nlt, struct NlaStrip *strip); +/* ............ */ struct NlaStrip *BKE_nlastrip_find_active(struct NlaTrack *nlt); short BKE_nlastrip_within_bounds(struct NlaStrip *strip, float min, float max); diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c index 9befe9dc9cb..1d10744ac80 100644 --- a/source/blender/blenkernel/intern/anim_sys.c +++ b/source/blender/blenkernel/intern/anim_sys.c @@ -628,15 +628,13 @@ static void nlastrip_evaluate_controls (NlaStrip *strip, float ctime) } -/* gets the strip active at the current time for a track for evaluation purposes */ -static void nlatrack_ctime_get_strip (ListBase *list, NlaTrack *nlt, short index, float ctime) +/* gets the strip active at the current time for a given list of strips */ +static NlaStrip *ctime_get_strip (ListBase *strips, short *side, float ctime) { NlaStrip *strip, *estrip=NULL; - NlaEvalStrip *nes; - short side= 0; /* loop over strips, checking if they fall within the range */ - for (strip= nlt->strips.first; strip; strip= strip->next) { + for (strip= strips->first; strip; strip= strip->next) { /* check if current time occurs within this strip */ if (IN_RANGE_INCL(ctime, strip->start, strip->end)) { /* this strip is active, so try to use it */ @@ -647,13 +645,13 @@ static void nlatrack_ctime_get_strip (ListBase *list, NlaTrack *nlt, short index /* if time occurred before current strip... */ if (ctime < strip->start) { - if (strip == nlt->strips.first) { + if (strip == strips->first) { /* before first strip - only try to use it if it extends backwards in time too */ if (strip->extendmode == NLASTRIP_EXTEND_HOLD) estrip= strip; /* side is 'before' regardless of whether there's a useful strip */ - side= NES_TIME_BEFORE; + *side= NES_TIME_BEFORE; } else { /* before next strip - previous strip has ended, but next hasn't begun, @@ -665,7 +663,7 @@ static void nlatrack_ctime_get_strip (ListBase *list, NlaTrack *nlt, short index if (strip->extendmode != NLASTRIP_EXTEND_NOTHING) estrip= strip; - side= NES_TIME_AFTER; + *side= NES_TIME_AFTER; } break; } @@ -673,11 +671,11 @@ static void nlatrack_ctime_get_strip (ListBase *list, NlaTrack *nlt, short index /* if time occurred after current strip... */ if (ctime > strip->end) { /* only if this is the last strip should we do anything, and only if that is being held */ - if (strip == nlt->strips.last) { + if (strip == strips->last) { if (strip->extendmode != NLASTRIP_EXTEND_NOTHING) estrip= strip; - side= NES_TIME_AFTER; + *side= NES_TIME_AFTER; break; } @@ -685,6 +683,35 @@ static void nlatrack_ctime_get_strip (ListBase *list, NlaTrack *nlt, short index } } + /* return the matching strip found */ + return estrip; +} + +/* gets the strip active at the current time for a track for evaluation purposes */ +static void nlatrack_ctime_get_strip (ListBase *list, NlaTrack *nlt, short index, float ctime) +{ + ListBase *strips= &nlt->strips; + NlaStrip *strip, *estrip=NULL; + NlaEvalStrip *nes; + short side= 0; + + /* keep looping over hierarchy of strips until one which fits for the current time is found */ + while (strips->first) { + /* try to get the strip at this frame for this strip */ + strip= ctime_get_strip(strips, &side, ctime); + + /* if a strip was found, make this the new estrip, otherwise, stop trying */ + if (strip) { + /* set new estrip */ + estrip= strip; + + /* check children (only available if this is a meta-strip) for better match */ + strips= &strip->strips; + } + else + break; + } + /* check if a valid strip was found * - must not be muted (i.e. will have contribution */ diff --git a/source/blender/blenkernel/intern/nla.c b/source/blender/blenkernel/intern/nla.c index 1244b2900fd..d01fa2c1965 100644 --- a/source/blender/blenkernel/intern/nla.c +++ b/source/blender/blenkernel/intern/nla.c @@ -68,10 +68,18 @@ */ void free_nlastrip (ListBase *strips, NlaStrip *strip) { + NlaStrip *cs, *csn; + /* sanity checks */ if (strip == NULL) return; + /* free child-strips */ + for (cs= strip->strips.first; cs; cs= csn) { + csn= cs->next; + free_nlastrip(&strip->strips, cs); + } + /* remove reference to action */ if (strip->act) strip->act->id.us--; @@ -144,6 +152,7 @@ void free_nladata (ListBase *tracks) NlaStrip *copy_nlastrip (NlaStrip *strip) { NlaStrip *strip_d; + NlaStrip *cs, *cs_d; /* sanity check */ if (strip == NULL) @@ -161,6 +170,14 @@ NlaStrip *copy_nlastrip (NlaStrip *strip) copy_fcurves(&strip_d->fcurves, &strip->fcurves); copy_fmodifiers(&strip_d->modifiers, &strip->modifiers); + /* make a copy of all the child-strips, one at a time */ + strip_d->strips.first= strip_d->strips.last= NULL; + + for (cs= strip->strips.first; cs; cs= cs->next) { + cs_d= copy_nlastrip(cs); + BLI_addtail(&strip_d->strips, cs_d); + } + /* return the strip */ return strip_d; } @@ -435,6 +452,7 @@ static float nlastrip_get_frame_transition (NlaStrip *strip, float cframe, short float nlastrip_get_frame (NlaStrip *strip, float cframe, short mode) { switch (strip->type) { + case NLASTRIP_TYPE_META: /* meta (is just a container for other strips, so shouldn't use the action-clip method) */ case NLASTRIP_TYPE_TRANSITION: /* transition */ return nlastrip_get_frame_transition(strip, cframe, mode); @@ -487,6 +505,117 @@ float BKE_nla_tweakedit_remap (AnimData *adt, float cframe, short mode) /* *************************************************** */ /* Basic Utilities */ +/* List of Strips ------------------------------------ */ +/* (these functions are used for NLA-Tracks and also for nested/meta-strips) */ + +/* Check if there is any space in the given list to add the given strip */ +short BKE_nlastrips_has_space (ListBase *strips, float start, float end) +{ + NlaStrip *strip; + + /* sanity checks */ + if ((strips == NULL) || IS_EQ(start, end)) + return 0; + if (start > end) { + puts("BKE_nlastrips_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= 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_nlastrips_sort_strips (ListBase *strips) +{ + ListBase tmp = {NULL, NULL}; + NlaStrip *strip, *sstrip; + + /* sanity checks */ + if ELEM(NULL, strips, 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= 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(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 */ + strips->first= tmp.first; + strips->last= tmp.last; +} + +/* Add the given NLA-Strip to the given list of strips, assuming that it + * isn't currently a member of another list + */ +short BKE_nlastrips_add_strip (ListBase *strips, NlaStrip *strip) +{ + NlaStrip *ns; + short not_added = 1; + + /* sanity checks */ + if ELEM(NULL, strips, strip) + return 0; + + /* check if any space to add */ + if (BKE_nlastrips_has_space(strips, strip->start, strip->end)==0) + return 0; + + /* find the right place to add the strip to the nominated track */ + for (ns= strips->first; ns; ns= ns->next) { + /* if current strip occurs after the new strip, add it before */ + if (ns->start > strip->end) { + BLI_insertlinkbefore(strips, ns, strip); + not_added= 0; + break; + } + } + if (not_added) { + /* just add to the end of the list of the strips then... */ + BLI_addtail(strips, strip); + } + + /* added... */ + return 1; +} + /* NLA-Tracks ---------------------------------------- */ /* Find the active NLA-track for the given stack */ @@ -560,36 +689,20 @@ 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 */ + +/* Check if there is any space in the given track to add a strip of the given length */ 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"); + 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; + /* check if there's any space left in the track for a strip of the given length */ + return BKE_nlastrips_has_space(&nlt->strips, start, end); } /* Rearrange the strips in the track so that they are always in order @@ -597,41 +710,12 @@ short BKE_nlatrack_has_space (NlaTrack *nlt, float start, float end) */ 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; + /* sort the strips with a more generic function */ + BKE_nlastrips_sort_strips(&nlt->strips); } /* Add the given NLA-Strip to the given NLA-Track, assuming that it @@ -639,33 +723,12 @@ void BKE_nlatrack_sort_strips (NlaTrack *nlt) */ short BKE_nlatrack_add_strip (NlaTrack *nlt, NlaStrip *strip) { - NlaStrip *ns; - short not_added = 1; - /* sanity checks */ if ELEM(NULL, nlt, strip) return 0; - /* check if any space to add */ - if (BKE_nlatrack_has_space(nlt, strip->start, strip->end)==0) - return 0; - - /* 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); - } - - /* added... */ - return 1; + /* try to add the strip to the track using a more generic function */ + return BKE_nlastrips_add_strip(&nlt->strips, strip); } /* NLA Strips -------------------------------------- */ diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index beebf58b6c0..956c8e0042e 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -1826,18 +1826,48 @@ static void direct_link_action(FileData *fd, bAction *act) } } +static void lib_link_nladata_strips(FileData *fd, ID *id, ListBase *list) +{ + NlaStrip *strip; + + for (strip= list->first; strip; strip= strip->next) { + /* check strip's children */ + lib_link_nladata_strips(fd, id, &strip->strips); + + /* reassign the counted-reference to action */ + strip->act = newlibadr_us(fd, id->lib, strip->act); + } +} -static void lib_link_nladata (FileData *fd, ID *id, ListBase *list) +static void lib_link_nladata(FileData *fd, ID *id, ListBase *list) { NlaTrack *nlt; - NlaStrip *strip; - /* we only acare about the NLA strips inside the tracks */ + /* we only care about the NLA strips inside the tracks */ for (nlt= list->first; nlt; nlt= nlt->next) { - for (strip= nlt->strips.first; strip; strip= strip->next) { - /* reassign the counted-reference to action */ - strip->act = newlibadr_us(fd, id->lib, strip->act); - } + lib_link_nladata_strips(fd, id, &nlt->strips); + } +} + +/* This handles Animato NLA-Strips linking + * NOTE: this assumes that link_list has already been called on the list + */ +static void direct_link_nladata_strips(FileData *fd, ListBase *list) +{ + NlaStrip *strip; + + for (strip= list->first; strip; strip= strip->next) { + /* strip's child strips */ + link_list(fd, &strip->strips); + direct_link_nladata_strips(fd, &strip->strips); + + /* strip's F-Curves */ + link_list(fd, &strip->fcurves); + direct_link_fcurves(fd, &strip->fcurves); + + /* strip's F-Modifiers */ + link_list(fd, &strip->modifiers); + direct_link_fcurves(fd, &strip->modifiers); } } @@ -1845,22 +1875,13 @@ static void lib_link_nladata (FileData *fd, ID *id, ListBase *list) static void direct_link_nladata(FileData *fd, ListBase *list) { NlaTrack *nlt; - NlaStrip *strip; for (nlt= list->first; nlt; nlt= nlt->next) { /* relink list of strips */ link_list(fd, &nlt->strips); /* relink strip data */ - for (strip= nlt->strips.first; strip; strip= strip->next) { - /* strip's F-Curves */ - link_list(fd, &strip->fcurves); - direct_link_fcurves(fd, &strip->fcurves); - - /* strip's F-Modifiers */ - link_list(fd, &strip->modifiers); - direct_link_fcurves(fd, &strip->modifiers); - } + direct_link_nladata_strips(fd, &nlt->strips); } } @@ -9560,11 +9581,23 @@ static void expand_keyingsets(FileData *fd, Main *mainvar, ListBase *list) } } +static void expand_animdata_nlastrips(FileData *fd, Main *mainvar, ListBase *list) +{ + NlaStrip *strip; + + for (strip= list->first; strip; strip= strip->next) { + /* check child strips */ + expand_animdata_nlastrips(fd, mainvar, &strip->strips); + + /* relink referenced action */ + expand_doit(fd, mainvar, strip->act); + } +} + static void expand_animdata(FileData *fd, Main *mainvar, AnimData *adt) { FCurve *fcd; NlaTrack *nlt; - NlaStrip *strip; /* own action */ expand_doit(fd, mainvar, adt->action); @@ -9580,10 +9613,8 @@ static void expand_animdata(FileData *fd, Main *mainvar, AnimData *adt) } /* nla-data - referenced actions */ - for (nlt= adt->nla_tracks.first; nlt; nlt= nlt->next) { - for (strip= nlt->strips.first; strip; strip= strip->next) - expand_doit(fd, mainvar, strip->act); - } + for (nlt= adt->nla_tracks.first; nlt; nlt= nlt->next) + expand_animdata_nlastrips(fd, mainvar, &nlt->strips); } static void expand_particlesettings(FileData *fd, Main *mainvar, ParticleSettings *part) diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index 80d1d78257b..bfdd89e38b1 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -916,26 +916,34 @@ static void write_keyingsets(WriteData *wd, ListBase *list) } } +static void write_nlastrips(WriteData *wd, ListBase *strips) +{ + NlaStrip *strip; + + for (strip= strips->first; strip; strip= strip->next) { + /* write the strip first */ + writestruct(wd, DATA, "NlaStrip", 1, strip); + + /* write the strip's F-Curves and modifiers */ + write_fcurves(wd, &strip->fcurves); + write_fmodifiers(wd, &strip->modifiers); + + /* write the strip's children */ + write_nlastrips(wd, &strip->strips); + } +} + static void write_nladata(WriteData *wd, ListBase *nlabase) { NlaTrack *nlt; - NlaStrip *strip; /* write all the tracks */ for (nlt= nlabase->first; nlt; nlt= nlt->next) { /* write the track first */ writestruct(wd, DATA, "NlaTrack", 1, nlt); - for (strip= nlt->strips.first; strip; strip= strip->next) { - /* write the strip first */ - writestruct(wd, DATA, "NlaStrip", 1, strip); - - /* write the strip's F-Curves and modifiers */ - write_fcurves(wd, &strip->fcurves); - write_fmodifiers(wd, &strip->modifiers); - - // TODO write the remaps - } + /* write the track's strips */ + write_nlastrips(wd, &nlt->strips); } } diff --git a/source/blender/editors/space_nla/nla_edit.c b/source/blender/editors/space_nla/nla_edit.c index 10b25beddff..e95d0b1a50a 100644 --- a/source/blender/editors/space_nla/nla_edit.c +++ b/source/blender/editors/space_nla/nla_edit.c @@ -734,8 +734,6 @@ static int nlaedit_move_up_exec (bContext *C, wmOperator *op) bAnimListElem *ale; int filter; - BeztEditData bed; - /* get editor data */ if (ANIM_animdata_get_context(C, &ac) == 0) return OPERATOR_CANCELLED; @@ -744,9 +742,6 @@ static int nlaedit_move_up_exec (bContext *C, wmOperator *op) filter= (ANIMFILTER_VISIBLE | ANIMFILTER_NLATRACKS | ANIMFILTER_FOREDIT); ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype); - /* init the editing data */ - memset(&bed, 0, sizeof(BeztEditData)); - /* since we're potentially moving strips from lower tracks to higher tracks, we should * loop over the tracks in reverse order to avoid moving earlier strips up multiple tracks */ @@ -811,8 +806,6 @@ static int nlaedit_move_down_exec (bContext *C, wmOperator *op) bAnimListElem *ale; int filter; - BeztEditData bed; - /* get editor data */ if (ANIM_animdata_get_context(C, &ac) == 0) return OPERATOR_CANCELLED; @@ -821,9 +814,6 @@ static int nlaedit_move_down_exec (bContext *C, wmOperator *op) filter= (ANIMFILTER_VISIBLE | ANIMFILTER_NLATRACKS | ANIMFILTER_FOREDIT); ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype); - /* init the editing data */ - memset(&bed, 0, sizeof(BeztEditData)); - /* loop through the tracks in normal order, since we're pushing strips down, * strips won't get operated on twice */ @@ -1037,6 +1027,116 @@ void NLA_OT_clear_scale (wmOperatorType *ot) ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; } +/* ******************** Snap Strips Operator ************************** */ +/* Moves the start-point of the selected strips to the specified places */ + +/* defines for snap keyframes tool */ +EnumPropertyItem prop_nlaedit_snap_types[] = { + {NLAEDIT_SNAP_CFRA, "CFRA", 0, "Current frame", ""}, + {NLAEDIT_SNAP_NEAREST_FRAME, "NEAREST_FRAME", 0, "Nearest Frame", ""}, // XXX as single entry? + {NLAEDIT_SNAP_NEAREST_SECOND, "NEAREST_SECOND", 0, "Nearest Second", ""}, // XXX as single entry? + {NLAEDIT_SNAP_NEAREST_MARKER, "NEAREST_MARKER", 0, "Nearest Marker", ""}, + {0, NULL, 0, NULL, NULL} +}; + +static int nlaedit_snap_exec (bContext *C, wmOperator *op) +{ + bAnimContext ac; + + ListBase anim_data = {NULL, NULL}; + bAnimListElem *ale; + int filter; + + Scene *scene= ac.scene; + int mode = RNA_enum_get(op->ptr, "type"); + const float secf = (float)FPS; + + /* get editor data */ + if (ANIM_animdata_get_context(C, &ac) == 0) + return OPERATOR_CANCELLED; + + /* get a list of the editable tracks being shown in the NLA */ + filter= (ANIMFILTER_VISIBLE | ANIMFILTER_NLATRACKS | ANIMFILTER_FOREDIT); + ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype); + + /* since we may add tracks, perform this in reverse order */ + for (ale= anim_data.last; ale; ale= ale->prev) { + ListBase tmp_strips = {NULL, NULL}; + NlaTrack *nlt= (NlaTrack *)ale->data; + NlaStrip *strip, *stripn; + + /* first pass: move all selected strips to a separate buffer, and apply snapping to them */ + for (strip= nlt->strips.first; strip; strip= stripn) { + stripn= strip->next; + + if (strip->flag & NLASTRIP_FLAG_SELECT) { + float start, end; + + /* get the existing end-points */ + start= strip->start; + end= strip->end; + + /* calculate new start position based on snapping mode */ + switch (mode) { + case NLAEDIT_SNAP_CFRA: /* to current frame */ + strip->start= (float)CFRA; + break; + case NLAEDIT_SNAP_NEAREST_FRAME: /* to nearest frame */ + strip->start= (float)(floor(start+0.5)); + break; + case NLAEDIT_SNAP_NEAREST_SECOND: /* to nearest second */ + strip->start= ((float)floor(start/secf + 0.5f) * secf); + break; + case NLAEDIT_SNAP_NEAREST_MARKER: /* to nearest marker */ + strip->start= (float)ED_markers_find_nearest_marker_time(ac.markers, start); + break; + default: /* just in case... no snapping */ + strip->start= start; + break; + } + + /* get new endpoint based on start-point (and old length) */ + strip->end= strip->start + (end - start); + + /* remove strip from track, and add to the temp buffer */ + BLI_remlink(&nlt->strips, strip); + BLI_addtail(&tmp_strips, strip); + } + } + + // TODO: finish this... + } + + /* free temp data */ + BLI_freelistN(&anim_data); + + /* set notifier that things have changed */ + ANIM_animdata_send_notifiers(C, &ac, ANIM_CHANGED_BOTH); + WM_event_add_notifier(C, NC_SCENE, NULL); + + /* done */ + return OPERATOR_FINISHED; +} + +void NLA_OT_snap (wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Snap Strips"; + ot->idname= "NLA_OT_snap"; + ot->description= "Move start of strips to specified time."; + + /* api callbacks */ + ot->invoke= WM_menu_invoke; + ot->exec= nlaedit_snap_exec; + ot->poll= nlaop_poll_tweakmode_off; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + /* properties */ + RNA_def_enum(ot->srna, "type", prop_nlaedit_snap_types, 0, "Type", ""); +} + /* *********************************************** */ /* NLA Modifiers */ diff --git a/source/blender/editors/space_nla/nla_intern.h b/source/blender/editors/space_nla/nla_intern.h index 5921b8a75ce..422686bb424 100644 --- a/source/blender/editors/space_nla/nla_intern.h +++ b/source/blender/editors/space_nla/nla_intern.h @@ -87,6 +87,17 @@ void NLA_OT_click_select(wmOperatorType *ot); /* **************************************** */ /* nla_edit.c */ +/* defines for snap strips + */ +enum { + NLAEDIT_SNAP_CFRA = 1, + NLAEDIT_SNAP_NEAREST_FRAME, + NLAEDIT_SNAP_NEAREST_SECOND, + NLAEDIT_SNAP_NEAREST_MARKER, +} eNlaEdit_Snap_Mode; + +/* --- */ + void NLA_OT_tweakmode_enter(wmOperatorType *ot); void NLA_OT_tweakmode_exit(wmOperatorType *ot); diff --git a/source/blender/makesdna/DNA_anim_types.h b/source/blender/makesdna/DNA_anim_types.h index a90fad983c4..a8220099a11 100644 --- a/source/blender/makesdna/DNA_anim_types.h +++ b/source/blender/makesdna/DNA_anim_types.h @@ -438,11 +438,13 @@ typedef struct AnimMapper { typedef struct NlaStrip { struct NlaStrip *next, *prev; + ListBase strips; /* 'Child' strips (used for 'meta' strips) */ 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? ListBase modifiers; /* F-Curve modifiers to be applied to the entire strip's referenced F-Curves */ + float influence; /* Influence of strip */ float strip_time; /* Current 'time' within action being used (automatically evaluated, but can be overridden) */ @@ -505,6 +507,11 @@ enum { NLASTRIP_FLAG_MUTED = (1<<12), /* NLA strip length is synced to the length of the referenced action */ NLASTRIP_FLAG_SYNC_LENGTH = (1<<13), + + /* temporary editing flags */ + /* NLA-Strip is really just a temporary meta used to facilitate easier transform code */ + NLASTRIP_FLAG_TEMP_META = (1<<30), + NLASTRIP_FLAG_EDIT_TOUCHED = (1<<31), } eNlaStrip_Flag; /* NLA Strip Type */ @@ -513,6 +520,8 @@ enum { NLASTRIP_TYPE_CLIP = 0, /* 'transition' - blends between the adjacent strips */ NLASTRIP_TYPE_TRANSITION, + /* 'meta' - a strip which acts as a container for a few others */ + NLASTRIP_TYPE_META, } eNlaStrip_Type; /* NLA Tracks ------------------------------------- */ |