diff options
-rw-r--r-- | source/blender/blenkernel/BKE_nla.h | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/nla.c | 119 | ||||
-rw-r--r-- | source/blender/editors/space_nla/nla_draw.c | 15 | ||||
-rw-r--r-- | source/blender/editors/space_nla/nla_header.c | 6 | ||||
-rw-r--r-- | source/blender/editors/transform/transform_conversions.c | 114 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_space_types.h | 1 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_space.c | 4 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_init_exit.c | 2 |
8 files changed, 182 insertions, 81 deletions
diff --git a/source/blender/blenkernel/BKE_nla.h b/source/blender/blenkernel/BKE_nla.h index bb5a2782663..241a8fd7b59 100644 --- a/source/blender/blenkernel/BKE_nla.h +++ b/source/blender/blenkernel/BKE_nla.h @@ -91,6 +91,8 @@ short BKE_nlatrack_has_animated_strips(struct NlaTrack *nlt); short BKE_nlatracks_have_animated_strips(ListBase *tracks); void BKE_nlastrip_validate_fcurves(struct NlaStrip *strip); +void BKE_nla_validate_state(struct AnimData *adt); + /* ............ */ void BKE_nla_action_pushdown(struct AnimData *adt); diff --git a/source/blender/blenkernel/intern/nla.c b/source/blender/blenkernel/intern/nla.c index 457df9be7a9..1871ec006f4 100644 --- a/source/blender/blenkernel/intern/nla.c +++ b/source/blender/blenkernel/intern/nla.c @@ -375,7 +375,7 @@ static float nlastrip_get_frame_actionclip (NlaStrip *strip, float cframe, short return strip->actend - (repeatsNum * actlength * scale) - (fmod(cframe - strip->start, actlength*scale) / scale); } - else { + else /* if (mode == NLATIME_CONVERT_EVAL) */{ if (IS_EQ(cframe, strip->end) && IS_EQ(strip->repeat, ((int)strip->repeat))) { /* this case prevents the motion snapping back to the first frame at the end of the strip * by catching the case where repeats is a whole number, which means that the end of the strip @@ -1229,13 +1229,52 @@ void BKE_nlastrip_validate_name (AnimData *adt, NlaStrip *strip) /* ---- */ +/* Get strips which overlap the given one at the start/end of its range + * - strip: strip that we're finding overlaps for + * - track: nla-track that the overlapping strips should be found from + * - start, end: frames for the offending endpoints + */ +static void nlastrip_get_endpoint_overlaps (NlaStrip *strip, NlaTrack *track, float **start, float **end) +{ + NlaStrip *nls; + + /* find strips that overlap over the start/end of the given strip, + * but which don't cover the entire length + */ + // TODO: this scheme could get quite slow for doing this on many strips... + for (nls= track->strips.first; nls; nls= nls->next) { + /* check if strip overlaps (extends over or exactly on) the entire range of the strip we're validating */ + if ((nls->start <= strip->start) && (nls->end >= strip->end)) { + *start= NULL; + *end= NULL; + return; + } + + /* check if strip doesn't even occur anywhere near... */ + if (nls->end < strip->start) + continue; /* skip checking this strip... not worthy of mention */ + if (nls->start > strip->end) + return; /* the range we're after has already passed */ + + /* if this strip is not part of an island of continuous strips, it can be used + * - this check needs to be done for each end of the strip we try and use... + */ + if ((nls->next == NULL) || IS_EQ(nls->next->start, nls->end)==0) { + if ((nls->end > strip->start) && (nls->end < strip->end)) + *start= &nls->end; + } + if ((nls->prev == NULL) || IS_EQ(nls->prev->end, nls->start)==0) { + if ((nls->start < strip->end) && (nls->start > strip->start)) + *end= &nls->start; + } + } +} + /* Determine auto-blending for the given strip */ void BKE_nlastrip_validate_autoblends (NlaTrack *nlt, NlaStrip *nls) { - NlaTrack *track; - NlaStrip *strip; - //float *ps=NULL, *pe=NULL; - //float *ns=NULL, *ne=NULL; + float *ps=NULL, *pe=NULL; + float *ns=NULL, *ne=NULL; /* sanity checks */ if ELEM(NULL, nls, nlt) @@ -1246,40 +1285,74 @@ void BKE_nlastrip_validate_autoblends (NlaTrack *nlt, NlaStrip *nls) return; /* get test ranges */ - if (nlt->prev) { - /* find strips that overlap over the start/end of the given strip, - * but which don't cover the entire length - */ - track= nlt->prev; - for (strip= track->strips.first; strip; strip= strip->next) { - - } + if (nlt->prev) + nlastrip_get_endpoint_overlaps(nls, nlt->prev, &ps, &pe); + if (nlt->next) + nlastrip_get_endpoint_overlaps(nls, nlt->next, &ns, &ne); + + /* set overlaps for this strip + * - don't use the values obtained though if the end in question + * is directly followed/preceeded by another strip, forming an + * 'island' of continuous strips + */ + if ( (ps || ns) && ((nls->prev == NULL) || IS_EQ(nls->prev->end, nls->start)==0) ) + { + /* start overlaps - pick the largest overlap */ + if ( ((ps && ns) && (*ps > *ns)) || (ps) ) + nls->blendin= *ps - nls->start; + else + nls->blendin= *ns - nls->start; } - if (nlt->next) { - /* find strips that overlap over the start/end of the given strip, - * but which don't cover the entire length - */ - track= nlt->next; - for (strip= track->strips.first; strip; strip= strip->next) { - - } + else /* no overlap allowed/needed */ + nls->blendin= 0.0f; + + if ( (pe || ne) && ((nls->next == NULL) || IS_EQ(nls->next->start, nls->end)==0) ) + { + /* end overlaps - pick the largest overlap */ + if ( ((pe && ne) && (*pe > *ne)) || (pe) ) + nls->blendout= nls->end - *pe; + else + nls->blendout= nls->end - *ne; } + else /* no overlap allowed/needed */ + nls->blendout= 0.0f; } /* Ensure that auto-blending and other settings are set correctly */ void BKE_nla_validate_state (AnimData *adt) { - NlaStrip *strip; + NlaStrip *strip, *fstrip=NULL; NlaTrack *nlt; /* sanity checks */ if ELEM(NULL, adt, adt->nla_tracks.first) return; - /* adjust blending values for auto-blending */ + /* adjust blending values for auto-blending, and also do an initial pass to find the earliest strip */ for (nlt= adt->nla_tracks.first; nlt; nlt= nlt->next) { for (strip= nlt->strips.first; strip; strip= strip->next) { + /* auto-blending first */ BKE_nlastrip_validate_autoblends(nlt, strip); + + /* extend mode - find first strip */ + if ((fstrip == NULL) || (strip->start < fstrip->start)) + fstrip= strip; + } + } + + /* second pass over the strips to adjust the extend-mode to fix any problems */ + for (nlt= adt->nla_tracks.first; nlt; nlt= nlt->next) { + for (strip= nlt->strips.first; strip; strip= strip->next) { + /* apart from 'nothing' option which user has to explicitly choose, we don't really know if + * we should be overwriting the extend setting (but assume that's what the user wanted) + */ + // TODO: 1 solution is to tie this in with auto-blending... + if (strip->extendmode != NLASTRIP_EXTEND_NOTHING) { + if (strip == fstrip) + strip->extendmode= NLASTRIP_EXTEND_HOLD; + else + strip->extendmode= NLASTRIP_EXTEND_HOLD_FORWARD; + } } } } diff --git a/source/blender/editors/space_nla/nla_draw.c b/source/blender/editors/space_nla/nla_draw.c index 9e60651081f..9aa71187334 100644 --- a/source/blender/editors/space_nla/nla_draw.c +++ b/source/blender/editors/space_nla/nla_draw.c @@ -252,10 +252,9 @@ static void nla_draw_strip_curves (NlaStrip *strip, View2D *v2d, float yminc, fl // XXX nasty hacked color for now... which looks quite bad too... glColor3f(0.7f, 0.7f, 0.7f); - /* draw with AA'd line, 2 units thick (it's either 1 or 2 px) */ + /* draw with AA'd line */ glEnable(GL_LINE_SMOOTH); glEnable(GL_BLEND); - glLineWidth(2.0f); /* influence -------------------------- */ if (strip->flag & NLASTRIP_FLAG_USR_INFLUENCE) { @@ -302,11 +301,10 @@ static void nla_draw_strip_curves (NlaStrip *strip, View2D *v2d, float yminc, fl /* turn off AA'd lines */ glDisable(GL_LINE_SMOOTH); glDisable(GL_BLEND); - glLineWidth(1.0f); } /* main call for drawing a single NLA-strip */ -static void nla_draw_strip (AnimData *adt, NlaTrack *nlt, NlaStrip *strip, View2D *v2d, float yminc, float ymaxc) +static void nla_draw_strip (SpaceNla *snla, AnimData *adt, NlaTrack *nlt, NlaStrip *strip, View2D *v2d, float yminc, float ymaxc) { float color[3]; @@ -373,8 +371,11 @@ static void nla_draw_strip (AnimData *adt, NlaTrack *nlt, NlaStrip *strip, View2 gl_round_box_shade(GL_POLYGON, strip->start, yminc, strip->end, ymaxc, 0.0, 0.5, 0.1); - /* draw strip's control 'curves' */ - nla_draw_strip_curves(strip, v2d, yminc, ymaxc); + /* draw strip's control 'curves' + * - only if user hasn't hidden them... + */ + if ((snla->flag & SNLA_NOSTRIPCURVES) == 0) + nla_draw_strip_curves(strip, v2d, yminc, ymaxc); /* draw strip outline * - color used here is to indicate active vs non-active @@ -527,7 +528,7 @@ void draw_nla_main_data (bAnimContext *ac, SpaceNla *snla, ARegion *ar) for (strip=nlt->strips.first, index=1; strip; strip=strip->next, index++) { if (BKE_nlastrip_within_bounds(strip, v2d->cur.xmin, v2d->cur.xmax)) { /* draw the visualisation of the strip */ - nla_draw_strip(adt, nlt, strip, v2d, yminc, ymaxc); + nla_draw_strip(snla, adt, nlt, strip, v2d, yminc, ymaxc); /* add the text for this strip to the cache */ nla_draw_strip_text(nlt, strip, index, v2d, yminc, ymaxc); diff --git a/source/blender/editors/space_nla/nla_header.c b/source/blender/editors/space_nla/nla_header.c index e997a096bce..f159f440759 100644 --- a/source/blender/editors/space_nla/nla_header.c +++ b/source/blender/editors/space_nla/nla_header.c @@ -21,7 +21,7 @@ * All rights reserved. * * - * Contributor(s): Blender Foundation + * Contributor(s): Blender Foundation, Joshua Leung * * ***** END GPL LICENSE BLOCK ***** */ @@ -100,7 +100,9 @@ static void nla_viewmenu(bContext *C, uiLayout *layout, void *arg_unused) uiItemO(layout, "Show Frames", 0, "ANIM_OT_time_toggle"); else uiItemO(layout, "Show Seconds", 0, "ANIM_OT_time_toggle"); - + + uiItemR(layout, NULL, 0, &spaceptr, "show_strip_curves", 0, 0, 0); + uiItemS(layout); uiItemS(layout); diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index 3d643a2dec1..4c91ca9af4a 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -4645,34 +4645,34 @@ void special_aftertrans_update(TransInfo *t) SpaceAction *saction= (SpaceAction *)t->sa->spacedata.first; Scene *scene; bAnimContext ac; - + /* initialise relevant anim-context 'context' data from TransInfo data */ /* NOTE: sync this with the code in ANIM_animdata_get_context() */ memset(&ac, 0, sizeof(bAnimContext)); - + scene= ac.scene= t->scene; ob= ac.obact= OBACT; ac.sa= t->sa; ac.ar= t->ar; ac.spacetype= (t->sa)? t->sa->spacetype : 0; ac.regiontype= (t->ar)? t->ar->regiontype : 0; - + if (ANIM_animdata_context_getdata(&ac) == 0) return; - + if (ac.datatype == ANIMCONT_DOPESHEET) { ListBase anim_data = {NULL, NULL}; bAnimListElem *ale; short filter= (ANIMFILTER_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_CURVESONLY); - + /* get channels to work on */ ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype); - + /* these should all be ipo-blocks */ for (ale= anim_data.first; ale; ale= ale->next) { AnimData *adt= ANIM_nla_mapping_get(&ac, ale); FCurve *fcu= (FCurve *)ale->key_data; - + if ( (saction->flag & SACTION_NOTRANSKEYCULL)==0 && ((cancelled == 0) || (duplicate)) ) { @@ -4685,7 +4685,7 @@ void special_aftertrans_update(TransInfo *t) posttrans_fcurve_clean(fcu); } } - + /* free temp memory */ BLI_freelistN(&anim_data); } @@ -4694,13 +4694,13 @@ void special_aftertrans_update(TransInfo *t) // fixme... some of this stuff is not good if (ob) { ob->ctime= -1234567.0f; - + if (ob->pose || ob_get_key(ob)) DAG_object_flush_update(scene, ob, OB_RECALC); else DAG_object_flush_update(scene, ob, OB_RECALC_OB); } - + /* Do curve cleanups? */ if ( (saction->flag & SACTION_NOTRANSKEYCULL)==0 && ((cancelled == 0) || (duplicate)) ) @@ -4712,7 +4712,7 @@ void special_aftertrans_update(TransInfo *t) #if 0 // XXX old animation system /* fix up the Ipocurves and redraw stuff */ Key *key= (Key *)ac.data; - + if (key->ipo) { if ( (saction->flag & SACTION_NOTRANSKEYCULL)==0 && ((cancelled == 0) || (duplicate)) ) @@ -4721,7 +4721,7 @@ void special_aftertrans_update(TransInfo *t) } } #endif // XXX old animation system - + DAG_object_flush_update(scene, OBACT, OB_RECALC_DATA); } #if 0 // XXX future of this is still not clear @@ -4731,23 +4731,23 @@ void special_aftertrans_update(TransInfo *t) { bScreen *sc= (bScreen *)ac.data; ScrArea *sa; - + /* BAD... we need to loop over all screen areas for current screen... * - sync this with actdata_filter_gpencil() in editaction.c */ for (sa= sc->areabase.first; sa; sa= sa->next) { bGPdata *gpd= gpencil_data_getactive(sa); - + if (gpd) posttrans_gpd_clean(gpd); } } } #endif // XXX future of this is still not clear - + /* make sure all F-Curves are set correctly */ ANIM_editkeyframes_refresh(&ac); - + /* clear flag that was set for time-slide drawing */ saction->flag &= ~SACTION_MOVING; } @@ -4755,35 +4755,35 @@ void special_aftertrans_update(TransInfo *t) SpaceIpo *sipo= (SpaceIpo *)t->sa->spacedata.first; Scene *scene; bAnimContext ac; - + /* initialise relevant anim-context 'context' data from TransInfo data */ /* NOTE: sync this with the code in ANIM_animdata_get_context() */ memset(&ac, 0, sizeof(bAnimContext)); - + scene= ac.scene= t->scene; ob= ac.obact= OBACT; ac.sa= t->sa; ac.ar= t->ar; ac.spacetype= (t->sa)? t->sa->spacetype : 0; ac.regiontype= (t->ar)? t->ar->regiontype : 0; - + if (ANIM_animdata_context_getdata(&ac) == 0) return; - + if (ac.datatype) { ListBase anim_data = {NULL, NULL}; bAnimListElem *ale; short filter= (ANIMFILTER_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_CURVESONLY | ANIMFILTER_CURVEVISIBLE); - + /* get channels to work on */ ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype); - + /* these should all be ipo-blocks */ for (ale= anim_data.first; ale; ale= ale->next) { AnimData *adt= ANIM_nla_mapping_get(&ac, ale); FCurve *fcu= (FCurve *)ale->key_data; - + if ( (sipo->flag & SIPO_NOTRANSKEYCULL)==0 && ((cancelled == 0) || (duplicate)) ) { @@ -4796,58 +4796,74 @@ void special_aftertrans_update(TransInfo *t) posttrans_fcurve_clean(fcu); } } - + /* free temp memory */ BLI_freelistN(&anim_data); } - + /* make sure all F-Curves are set correctly */ ANIM_editkeyframes_refresh(&ac); } else if (t->spacetype == SPACE_NLA) { Scene *scene; bAnimContext ac; - + /* initialise relevant anim-context 'context' data from TransInfo data */ /* NOTE: sync this with the code in ANIM_animdata_get_context() */ memset(&ac, 0, sizeof(bAnimContext)); - + scene= ac.scene= t->scene; ob= ac.obact= OBACT; ac.sa= t->sa; ac.ar= t->ar; ac.spacetype= (t->sa)? t->sa->spacetype : 0; ac.regiontype= (t->ar)? t->ar->regiontype : 0; - + if (ANIM_animdata_context_getdata(&ac) == 0) return; - + if (ac.datatype) { ListBase anim_data = {NULL, NULL}; bAnimListElem *ale; - short filter= (ANIMFILTER_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_NLATRACKS); - - /* get channels to work on */ - ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype); - - for (ale= anim_data.first; ale; ale= ale->next) { - NlaTrack *nlt= (NlaTrack *)ale->data; - - /* make sure strips are in order again */ - BKE_nlatrack_sort_strips(nlt); - - /* remove the temp metas */ - BKE_nlastrips_clear_metas(&nlt->strips, 0, 1); + + /* firstly, make the strips normal again */ + { + short filter= (ANIMFILTER_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_NLATRACKS); + + /* get channels to work on */ + ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype); + + for (ale= anim_data.first; ale; ale= ale->next) { + NlaTrack *nlt= (NlaTrack *)ale->data; + + /* make sure strips are in order again */ + BKE_nlatrack_sort_strips(nlt); + + /* remove the temp metas */ + BKE_nlastrips_clear_metas(&nlt->strips, 0, 1); + } + + /* free temp memory */ + BLI_freelistN(&anim_data); + } + + /* perform after-transfrom validation */ + { + short filter= (ANIMFILTER_VISIBLE | ANIMFILTER_ANIMDATA | ANIMFILTER_FOREDIT); + + /* get blocks to work on */ + ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype); + + for (ale= anim_data.first; ale; ale= ale->next) { + /* performing auto-blending, extend-mode validation, etc. */ + BKE_nla_validate_state(ale->data); + } + + /* free temp memory */ + BLI_freelistN(&anim_data); } - - /* free temp memory */ - BLI_freelistN(&anim_data); } - - // XXX check on the calls below... we need some of these sanity checks - //synchronize_action_strips(); - //ANIM_editkeyframes_refresh(&ac); } else if (t->obedit) { // TRANSFORM_FIX_ME diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index 34a5efbdf5f..4760fd00bf2 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -811,6 +811,7 @@ enum { #define SNLA_DRAWTIME (1<<2) #define SNLA_NOTRANSKEYCULL (1<<3) #define SNLA_NODRAWCFRANUM (1<<4) +#define SNLA_NOSTRIPCURVES (1<<5) /* time->flag */ /* show timing in frames instead of in seconds */ diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index cf14d18ac98..bf475d49048 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -1060,6 +1060,10 @@ static void rna_def_space_nla(BlenderRNA *brna) RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", SNLA_NODRAWCFRANUM); RNA_def_property_ui_text(prop, "Show Frame Number Indicator", "Show frame number beside the current frame indicator line."); + prop= RNA_def_property(srna, "show_strip_curves", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", SNLA_NOSTRIPCURVES); + RNA_def_property_ui_text(prop, "Show Control Curves", "Show influence curves on strips."); + /* editing */ // TODO... autosnap, dopesheet? } diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c index fd102b663d0..599844f1020 100644 --- a/source/blender/windowmanager/intern/wm_init_exit.c +++ b/source/blender/windowmanager/intern/wm_init_exit.c @@ -178,6 +178,7 @@ extern wchar_t *copybufinfo; // XXX copy/paste buffer stuff... extern void free_anim_copybuf(); +extern void free_posebuf(); /* called in creator.c even... tsk, split this! */ void WM_exit(bContext *C) @@ -231,6 +232,7 @@ void WM_exit(bContext *C) free_blender(); /* blender.c, does entire library and spacetypes */ // free_matcopybuf(); free_anim_copybuf(); + free_posebuf(); // free_vertexpaint(); // free_imagepaint(); |