diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c index e4882d8f555..2b4a2c135eb 100644 --- a/source/blender/blenkernel/intern/anim_sys.c +++ b/source/blender/blenkernel/intern/anim_sys.c @@ -120,8 +120,15 @@ AnimData *BKE_id_add_animdata (ID *id) IdAdtTemplate *iat= (IdAdtTemplate *)id; /* check if there's already AnimData, in which case, don't add */ - if (iat->adt == NULL) - iat->adt= MEM_callocN(sizeof(AnimData), "AnimData"); + if (iat->adt == NULL) { + AnimData *adt; + + /* add animdata */ + adt= iat->adt= MEM_callocN(sizeof(AnimData), "AnimData"); + + /* set default settings */ + adt->act_influence= 1.0f; + } return iat->adt; } @@ -1190,6 +1197,9 @@ void nladata_flush_channels (ListBase *channels) */ static void animsys_evaluate_nla (PointerRNA *ptr, AnimData *adt, float ctime) { + ListBase dummy_trackslist = {NULL, NULL}; + NlaStrip dummy_strip; + NlaTrack *nlt; short track_index=0; @@ -1218,6 +1228,29 @@ static void animsys_evaluate_nla (PointerRNA *ptr, AnimData *adt, float ctime) if (nes) nes->track= nlt; } + /* add 'active' Action (may be tweaking track) as last strip to evaluate in NLA stack + * - only do this if we're not exclusively evaluating the 'solo' NLA-track + */ + if ((adt->action) && !(adt->flag & ADT_NLA_SOLO_TRACK)) { + /* make dummy NLA strip, and add that to the stack */ + memset(&dummy_strip, 0, sizeof(NlaStrip)); + dummy_trackslist.first= dummy_trackslist.last= &dummy_strip; + + dummy_strip.act= adt->action; + dummy_strip.remap= adt->remap; + + calc_action_range(dummy_strip.act, &dummy_strip.actstart, &dummy_strip.actend, 1); + dummy_strip.start = dummy_strip.actstart; + dummy_strip.end = (IS_EQ(dummy_strip.actstart, dummy_strip.actend)) ? (dummy_strip.actstart + 1.0f): (dummy_strip.actend); + + dummy_strip.blendmode= adt->act_blendmode; + dummy_strip.extendmode= adt->act_extendmode; + dummy_strip.influence= adt->act_influence; + + /* add this to our list of evaluation strips */ + nlastrips_ctime_get_strip(&estrips, &dummy_trackslist, -1, ctime); + } + /* only continue if there are strips to evaluate */ if (estrips.first == NULL) return; @@ -1316,14 +1349,10 @@ void BKE_animsys_evaluate_animdata (ID *id, AnimData *adt, float ctime, short re /* evaluate NLA data */ if ((adt->nla_tracks.first) && !(adt->flag & ADT_NLA_EVAL_OFF)) { - /* evaluate NLA-stack */ - animsys_evaluate_nla(&id_ptr, adt, ctime); - - /* evaluate 'active' Action (may be tweaking track) on top of results of NLA-evaluation - * - only do this if we're not exclusively evaluating the 'solo' NLA-track + /* evaluate NLA-stack + * - active action is evaluated as part of the NLA stack as the last item */ - if ((adt->action) && !(adt->flag & ADT_NLA_SOLO_TRACK)) - animsys_evaluate_action(&id_ptr, adt->action, adt->remap, ctime); + animsys_evaluate_nla(&id_ptr, adt, ctime); } /* evaluate Active Action only */ else if (adt->action) diff --git a/source/blender/editors/animation/keyframing.c b/source/blender/editors/animation/keyframing.c index 7bee57708ec..2da082a9b7c 100644 --- a/source/blender/editors/animation/keyframing.c +++ b/source/blender/editors/animation/keyframing.c @@ -1438,10 +1438,17 @@ int autokeyframe_cfra_can_key(Scene *scene, ID *id) /* only filter if auto-key mode requires this */ if (IS_AUTOKEY_ON(scene) == 0) return 0; - else if (IS_AUTOKEY_MODE(scene, NORMAL)) + + if (IS_AUTOKEY_MODE(scene, NORMAL)) { + /* can insert anytime we like... */ return 1; - else + } + else /* REPLACE */ { + /* for whole block - only key if there's a keyframe on that frame already + * this is a valid assumption when we're blocking + tweaking + */ return id_frame_has_keyframe(id, cfra, ANIMFILTER_KEYS_LOCAL); + } } /* ******************************************* */ diff --git a/source/blender/editors/include/ED_screen_types.h b/source/blender/editors/include/ED_screen_types.h index 3ea5dfba65c..76a2a55c29e 100644 --- a/source/blender/editors/include/ED_screen_types.h +++ b/source/blender/editors/include/ED_screen_types.h @@ -33,9 +33,18 @@ typedef struct ScreenAnimData { ARegion *ar; /* do not read from this, only for comparing if region exists */ int redraws; - int reverse; + int flag; /* flags for playback */ } ScreenAnimData; +/* for animplayer */ +enum { + /* user-setting - frame range is played backwards */ + ANIMPLAY_FLAG_REVERSE = (1<<0), + /* temporary - playback just jumped to the start/end */ + ANIMPLAY_FLAG_JUMPED = (1<<1), +}; + + typedef struct AZone { struct AZone *next, *prev; diff --git a/source/blender/editors/interface/interface_anim.c b/source/blender/editors/interface/interface_anim.c index d2e9236fcff..2993a1aba15 100644 --- a/source/blender/editors/interface/interface_anim.c +++ b/source/blender/editors/interface/interface_anim.c @@ -144,7 +144,7 @@ void ui_but_anim_autokey(uiBut *but, Scene *scene, float cfra) if(fcu && !driven) { id= but->rnapoin.id.data; - + if(autokeyframe_cfra_can_key(scene, id)) { short flag = 0; diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c index 817959aef13..926768c98ab 100644 --- a/source/blender/editors/screen/screen_edit.c +++ b/source/blender/editors/screen/screen_edit.c @@ -1477,7 +1477,7 @@ void ED_screen_animation_timer(bContext *C, int redraws, int enable) screen->animtimer= WM_event_add_window_timer(win, TIMER0, (1.0/FPS)); sad->ar= CTX_wm_region(C); sad->redraws= redraws; - sad->reverse= (enable < 0); + sad->flag= (enable < 0) ? ANIMPLAY_FLAG_REVERSE : 0; screen->animtimer->customdata= sad; } diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index 07454088604..c9e30b8c879 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -2197,39 +2197,50 @@ static int screen_animation_step(bContext *C, wmOperator *op, wmEvent *event) if(scene->audio.flag & AUDIO_SYNC) { int step = floor(wt->duration * FPS); - if (sad->reverse) // XXX does this option work with audio? + if (sad->flag & ANIMPLAY_FLAG_REVERSE) // XXX does this option work with audio? scene->r.cfra -= step; else scene->r.cfra += step; wt->duration -= ((float)step)/FPS; } else { - if (sad->reverse) + if (sad->flag & ANIMPLAY_FLAG_REVERSE) scene->r.cfra--; else scene->r.cfra++; } - if (sad->reverse) { - /* jump back to end */ + /* reset 'jumped' flag before checking if we need to jump... */ + sad->flag &= ~ANIMPLAY_FLAG_JUMPED; + + if (sad->flag & ANIMPLAY_FLAG_REVERSE) { + /* jump back to end? */ if (scene->r.psfra) { - if(scene->r.cfra < scene->r.psfra) + if (scene->r.cfra < scene->r.psfra) { scene->r.cfra= scene->r.pefra; + sad->flag |= ANIMPLAY_FLAG_JUMPED; + } } else { - if(scene->r.cfra < scene->r.sfra) + if (scene->r.cfra < scene->r.sfra) { scene->r.cfra= scene->r.efra; + sad->flag |= ANIMPLAY_FLAG_JUMPED; + } } } else { - /* jump back to start */ + /* jump back to start? */ if (scene->r.psfra) { - if(scene->r.cfra > scene->r.pefra) + if (scene->r.cfra > scene->r.pefra) { scene->r.cfra= scene->r.psfra; + sad->flag |= ANIMPLAY_FLAG_JUMPED; + } } else { - if(scene->r.cfra > scene->r.efra) + if (scene->r.cfra > scene->r.efra) { scene->r.cfra= scene->r.sfra; + sad->flag |= ANIMPLAY_FLAG_JUMPED; + } } } diff --git a/source/blender/editors/space_nla/nla_buttons.c b/source/blender/editors/space_nla/nla_buttons.c index a74037d1ace..a87ab36714c 100644 --- a/source/blender/editors/space_nla/nla_buttons.c +++ b/source/blender/editors/space_nla/nla_buttons.c @@ -100,7 +100,7 @@ static void do_nla_region_buttons(bContext *C, void *arg, int event) WM_event_add_notifier(C, NC_SCENE|NC_OBJECT|ND_TRANSFORM, NULL); } -static int nla_panel_context(const bContext *C, PointerRNA *nlt_ptr, PointerRNA *strip_ptr) +static int nla_panel_context(const bContext *C, PointerRNA *adt_ptr, PointerRNA *nlt_ptr, PointerRNA *strip_ptr) { bAnimContext ac; bAnimListElem *ale= NULL; @@ -121,8 +121,13 @@ static int nla_panel_context(const bContext *C, PointerRNA *nlt_ptr, PointerRNA for (ale= anim_data.first; ale; ale= ale->next) { if (ale->type == ANIMTYPE_NLATRACK) { NlaTrack *nlt= (NlaTrack *)ale->data; + AnimData *adt= ale->adt; /* found it, now set the pointers */ + if (adt_ptr) { + /* AnimData pointer */ + RNA_pointer_create(ale->id, &RNA_AnimData, adt, adt_ptr); + } if (nlt_ptr) { /* NLA-Track pointer */ RNA_pointer_create(ale->id, &RNA_NlaTrack, nlt, nlt_ptr); @@ -151,16 +156,22 @@ static int nla_panel_poll(const bContext *C, PanelType *pt) } #endif +static int nla_animdata_panel_poll(const bContext *C, PanelType *pt) +{ + PointerRNA ptr; + return (nla_panel_context(C, &ptr, NULL, NULL) && (ptr.data != NULL)); +} + static int nla_track_panel_poll(const bContext *C, PanelType *pt) { PointerRNA ptr; - return (nla_panel_context(C, &ptr, NULL) && (ptr.data != NULL)); + return (nla_panel_context(C, NULL, &ptr, NULL) && (ptr.data != NULL)); } static int nla_strip_panel_poll(const bContext *C, PanelType *pt) { PointerRNA ptr; - return (nla_panel_context(C, NULL, &ptr) && (ptr.data != NULL)); + return (nla_panel_context(C, NULL, NULL, &ptr) && (ptr.data != NULL)); } static int nla_strip_actclip_panel_poll(const bContext *C, PanelType *pt) @@ -168,7 +179,7 @@ static int nla_strip_actclip_panel_poll(const bContext *C, PanelType *pt) PointerRNA ptr; NlaStrip *strip; - if (!nla_panel_context(C, NULL, &ptr)) + if (!nla_panel_context(C, NULL, NULL, &ptr)) return 0; if (ptr.data == NULL) return 0; @@ -179,6 +190,42 @@ static int nla_strip_actclip_panel_poll(const bContext *C, PanelType *pt) /* -------------- */ +/* active AnimData */ +static void nla_panel_animdata (const bContext *C, Panel *pa) +{ + PointerRNA adt_ptr; + AnimData *adt; + uiLayout *layout= pa->layout; + uiLayout *row; + uiBlock *block; + + /* check context and also validity of pointer */ + if (!nla_panel_context(C, &adt_ptr, NULL, NULL)) + return; + adt= adt_ptr.data; + + block= uiLayoutGetBlock(layout); + uiBlockSetHandleFunc(block, do_nla_region_buttons, NULL); + + /* Active Action Properties ------------------------------------- */ + /* action */ + row= uiLayoutRow(layout, 1); + uiLayoutSetEnabled(row, (adt->flag & ADT_NLA_EDIT_ON)==0); + uiItemR(row, NULL, 0, &adt_ptr, "action", 0, 0, 0); + + /* extrapolation */ + row= uiLayoutRow(layout, 1); + uiItemR(row, NULL, 0, &adt_ptr, "action_extrapolation", 0, 0, 0); + + /* blending */ + row= uiLayoutRow(layout, 1); + uiItemR(row, NULL, 0, &adt_ptr, "action_blending", 0, 0, 0); + + /* influence */ + row= uiLayoutRow(layout, 1); + uiItemR(row, NULL, 0, &adt_ptr, "action_influence", 0, 0, 0); +} + /* active NLA-Track */ static void nla_panel_track (const bContext *C, Panel *pa) { @@ -188,9 +235,9 @@ static void nla_panel_track (const bContext *C, Panel *pa) uiBlock *block; /* check context and also validity of pointer */ - if (!nla_panel_context(C, &nlt_ptr, NULL)) + if (!nla_panel_context(C, NULL, &nlt_ptr, NULL)) return; - + block= uiLayoutGetBlock(layout); uiBlockSetHandleFunc(block, do_nla_region_buttons, NULL); @@ -207,7 +254,7 @@ static void nla_panel_properties(const bContext *C, Panel *pa) uiLayout *column, *row, *subcol; uiBlock *block; - if (!nla_panel_context(C, NULL, &strip_ptr)) + if (!nla_panel_context(C, NULL, NULL, &strip_ptr)) return; block= uiLayoutGetBlock(layout); @@ -263,7 +310,7 @@ static void nla_panel_actclip(const bContext *C, Panel *pa) uiBlock *block; /* check context and also validity of pointer */ - if (!nla_panel_context(C, NULL, &strip_ptr)) + if (!nla_panel_context(C, NULL, NULL, &strip_ptr)) return; block= uiLayoutGetBlock(layout); @@ -298,7 +345,7 @@ static void nla_panel_evaluation(const bContext *C, Panel *pa) uiBlock *block; /* check context and also validity of pointer */ - if (!nla_panel_context(C, NULL, &strip_ptr)) + if (!nla_panel_context(C, NULL, NULL, &strip_ptr)) return; block= uiLayoutGetBlock(layout); @@ -330,7 +377,7 @@ static void nla_panel_modifiers(const bContext *C, Panel *pa) uiBlock *block; /* check context and also validity of pointer */ - if (!nla_panel_context(C, NULL, &strip_ptr)) + if (!nla_panel_context(C, NULL, NULL, &strip_ptr)) return; strip= strip_ptr.data; @@ -362,6 +409,14 @@ void nla_buttons_register(ARegionType *art) { PanelType *pt; + pt= MEM_callocN(sizeof(PanelType), "spacetype nla panel animdata"); + strcpy(pt->idname, "NLA_PT_animdata"); + strcpy(pt->label, "Animation Data"); + pt->draw= nla_panel_animdata; + pt->poll= nla_animdata_panel_poll; + pt->flag= PNL_DEFAULT_CLOSED; + BLI_addtail(&art->paneltypes, pt); + pt= MEM_callocN(sizeof(PanelType), "spacetype nla panel track"); strcpy(pt->idname, "NLA_PT_track"); strcpy(pt->label, "Active Track"); diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c index 62b68589d98..8a7bc51c19e 100644 --- a/source/blender/editors/transform/transform_generics.c +++ b/source/blender/editors/transform/transform_generics.c @@ -92,6 +92,7 @@ #include "ED_markers.h" #include "ED_mesh.h" #include "ED_retopo.h" +#include "ED_screen_types.h" #include "ED_space_api.h" #include "ED_uvedit.h" #include "ED_view3d.h" @@ -288,6 +289,42 @@ static void animedit_refresh_id_tags (ID *id) } } +/* for the realtime animation recording feature, handle overlapping data */ +static void animrecord_check_state (Scene *scene, ID *id, wmTimer *animtimer) +{ + ScreenAnimData *sad= animtimer->customdata; + + /* if animtimer is running and we're not interested in only keying for available channels, + * check if there's a keyframe on the current frame + */ + if (IS_AUTOKEY_FLAG(INSERTAVAIL)==0) { + /* if playback has just looped around, we need to add a new NLA track+strip to allow a clean pass to occur */ + if (sad->flag & ANIMPLAY_FLAG_JUMPED) { + AnimData *adt= BKE_animdata_from_id(id); + + /* perform push-down manually with some differences + * NOTE: BKE_nla_action_pushdown() sync warning... + */ + if ((adt->action) && !(adt->flag & ADT_NLA_EDIT_ON)) { + NlaStrip *strip= add_nlastrip_to_stack(adt, adt->action); + + /* clear reference to action now that we've pushed it onto the stack */ + adt->action->id.us--; + adt->action= NULL; + + /* adjust blending + extend so that they will behave correctly */ + strip->extendmode= NLASTRIP_EXTEND_NOTHING; + strip->flag &= ~(NLASTRIP_FLAG_AUTO_BLENDS|NLASTRIP_FLAG_SELECT|NLASTRIP_FLAG_ACTIVE); + + /* also, adjust the AnimData's action extend mode to be on + * 'nothing' so that previous result still play + */ + adt->act_extendmode= NLASTRIP_EXTEND_NOTHING; + } + } + } +} + /* called for updating while transform acts, once per redraw */ void recalcData(TransInfo *t) { @@ -716,6 +753,8 @@ void recalcData(TransInfo *t) // TODO: maybe the ob->adt check isn't really needed? makes it too difficult to use... if (/*(ob->adt) && */(t->animtimer) && IS_AUTOKEY_ON(t->scene)) { short targetless_ik= (t->flag & T_AUTOIK); // XXX this currently doesn't work, since flags aren't set yet! + + animrecord_check_state(t->scene, &ob->id, t->animtimer); autokeyframe_pose_cb_func(t->scene, (View3D *)t->view, ob, t->mode, targetless_ik); } @@ -745,6 +784,7 @@ void recalcData(TransInfo *t) // TODO: autokeyframe calls need some setting to specify to add samples (FPoints) instead of keyframes? // TODO: maybe the ob->adt check isn't really needed? makes it too difficult to use... if (/*(ob->adt) && */(t->animtimer) && IS_AUTOKEY_ON(t->scene)) { + animrecord_check_state(t->scene, &ob->id, t->animtimer); autokeyframe_ob_cb_func(t->scene, (View3D *)t->view, ob, t->mode); } } diff --git a/source/blender/makesdna/DNA_anim_types.h b/source/blender/makesdna/DNA_anim_types.h index 35381e4612a..0f5129a6c25 100644 --- a/source/blender/makesdna/DNA_anim_types.h +++ b/source/blender/makesdna/DNA_anim_types.h @@ -734,8 +734,13 @@ typedef struct AnimData { ListBase overrides; /* temp storage (AnimOverride) of values for settings that are animated (but the value hasn't been keyframed) */ /* settings for animation evaluation */ - int flag; /* user-defined settings */ - int recalc; /* depsgraph recalculation flags */ + int flag; /* user-defined settings */ + int recalc; /* depsgraph recalculation flags */ + + /* settings for active action evaluation (based on NLA strip settings) */ + short act_blendmode; /* accumulation mode for active action */ + short act_extendmode; /* extrapolation mode for active action */ + float act_influence; /* influence for active action */ } AnimData; /* Animation Data settings (mostly for NLA) */ diff --git a/source/blender/makesrna/RNA_enum_types.h b/source/blender/makesrna/RNA_enum_types.h index 2592a1340ec..78e65e8fc06 100644 --- a/source/blender/makesrna/RNA_enum_types.h +++ b/source/blender/makesrna/RNA_enum_types.h @@ -41,6 +41,9 @@ extern EnumPropertyItem beztriple_interpolation_mode_items[]; extern EnumPropertyItem fmodifier_type_items[]; +extern EnumPropertyItem nla_mode_extend_items[]; +extern EnumPropertyItem nla_mode_blend_items[]; + extern EnumPropertyItem event_value_items[]; extern EnumPropertyItem event_type_items[]; diff --git a/source/blender/makesrna/intern/rna_animation.c b/source/blender/makesrna/intern/rna_animation.c index 3469d716853..76ed62f6438 100644 --- a/source/blender/makesrna/intern/rna_animation.c +++ b/source/blender/makesrna/intern/rna_animation.c @@ -26,6 +26,7 @@ #include "RNA_define.h" #include "RNA_types.h" +#include "RNA_enum_types.h" #include "rna_internal.h" @@ -187,9 +188,26 @@ void rna_def_animdata(BlenderRNA *brna) RNA_def_property_struct_type(prop, "NlaTrack"); RNA_def_property_ui_text(prop, "NLA Tracks", "NLA Tracks (i.e. Animation Layers)."); - /* Action */ + /* Active Action */ prop= RNA_def_property(srna, "action", PROP_POINTER, PROP_NONE); - RNA_def_property_ui_text(prop, "Action", "Active Action for this datablock."); + RNA_def_property_ui_text(prop, "Action", "Active Action for this datablock."); + + /* Active Action Settings */ + prop= RNA_def_property(srna, "action_extrapolation", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "act_extendmode"); + RNA_def_property_enum_items(prop, nla_mode_extend_items); + RNA_def_property_ui_text(prop, "Action Extrapolation", "Action to take for gaps past the Active Action's range (when evaluating with NLA)."); + + prop= RNA_def_property(srna, "action_blending", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "act_blendmode"); + RNA_def_property_enum_items(prop, nla_mode_blend_items); + RNA_def_property_ui_text(prop, "Action Blending", "Method used for combining Active Action's result with result of NLA stack."); + + prop= RNA_def_property(srna, "action_influence", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "act_influence"); + RNA_def_property_float_default(prop, 1.0f); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_ui_text(prop, "Action Influence", "Amount the Active Action contributes to the result of the NLA stack."); /* Drivers */ prop= RNA_def_property(srna, "drivers", PROP_COLLECTION, PROP_NONE); @@ -197,7 +215,10 @@ void rna_def_animdata(BlenderRNA *brna) RNA_def_property_struct_type(prop, "FCurve"); RNA_def_property_ui_text(prop, "Drivers", "The Drivers/Expressions for this datablock."); - /* Settings */ + /* General Settings */ + prop= RNA_def_property(srna, "nla_enabled", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", ADT_NLA_EVAL_OFF); + RNA_def_property_ui_text(prop, "NLA Evaluation Enabled", "NLA stack is evaluated when evaluating this block."); } /* --- */ diff --git a/source/blender/makesrna/intern/rna_nla.c b/source/blender/makesrna/intern/rna_nla.c index bc636af6849..3b55da046b8 100644 --- a/source/blender/makesrna/intern/rna_nla.c +++ b/source/blender/makesrna/intern/rna_nla.c @@ -243,6 +243,19 @@ static void rna_NlaStrip_animated_time_set(PointerRNA *ptr, int value) #else +/* enum defines exported for rna_animation.c */ +EnumPropertyItem nla_mode_blend_items[] = { + {NLASTRIP_MODE_REPLACE, "REPLACE", 0, "Replace", "Result strip replaces the accumulated results by amount specified by influence."}, + {NLASTRIP_MODE_ADD, "ADD", 0, "Add", "Weighted result of strip is added to the accumlated results."}, + {NLASTRIP_MODE_SUBTRACT, "SUBTRACT", 0, "Subtract", "Weighted result of strip is removed from the accumlated results."}, + {NLASTRIP_MODE_MULTIPLY, "MULITPLY", 0, "Multiply", "Weighted result of strip is multiplied with the accumlated results."}, + {0, NULL, 0, NULL, NULL}}; +EnumPropertyItem nla_mode_extend_items[] = { + {NLASTRIP_EXTEND_NOTHING, "NOTHING", 0, "Nothing", "Strip has no influence past its extents."}, + {NLASTRIP_EXTEND_HOLD, "HOLD", 0, "Hold", "Hold the first frame if no previous strips in track, and always hold last frame."}, + {NLASTRIP_EXTEND_HOLD_FORWARD, "HOLD_FORWARD", 0, "Hold Forward", "Only hold last frame."}, + {0, NULL, 0, NULL, NULL}}; + void rna_def_nlastrip(BlenderRNA *brna) { StructRNA *srna; @@ -254,17 +267,6 @@ void rna_def_nlastrip(BlenderRNA *brna) {NLASTRIP_TYPE_TRANSITION, "TRANSITION", 0, "Transition", "NLA Strip 'transitions' between adjacent strips."}, {NLASTRIP_TYPE_META, "META", 0, "Meta", "NLA Strip acts as a container for adjacent strips."}, {0, NULL, 0, NULL, NULL}}; - static EnumPropertyItem prop_mode_blend_items[] = { - {NLASTRIP_MODE_REPLACE, "REPLACE", 0, "Replace", "Result strip replaces the accumulated results by amount specified by influence."}, - {NLASTRIP_MODE_ADD, "ADD", 0, "Add", "Weighted result of strip is added to the accumlated results."}, - {NLASTRIP_MODE_SUBTRACT, "SUBTRACT", 0, "Subtract", "Weighted result of strip is removed from the accumlated results."}, - {NLASTRIP_MODE_MULTIPLY, "MULITPLY", 0, "Multiply", "Weighted result of strip is multiplied with the accumlated results."}, - {0, NULL, 0, NULL, NULL}}; - static EnumPropertyItem prop_mode_extend_items[] = { - {NLASTRIP_EXTEND_NOTHING, "NOTHING", 0, "Nothing", "Strip has no influence past its extents."}, - {NLASTRIP_EXTEND_HOLD, "HOLD", 0, "Hold", "Hold the first frame if no previous strips in track, and always hold last frame."}, - {NLASTRIP_EXTEND_HOLD_FORWARD, "HOLD_FORWARD", 0, "Hold Forward", "Only hold last frame."}, - {0, NULL, 0, NULL, NULL}}; /* struct definition */ srna= RNA_def_struct(brna, "NlaStrip", NULL); @@ -286,12 +288,12 @@ void rna_def_nlastrip(BlenderRNA *brna) prop= RNA_def_property(srna, "extrapolation", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "extendmode"); - RNA_def_property_enum_items(prop, prop_mode_extend_items); + RNA_def_property_enum_items(prop, nla_mode_extend_items); RNA_def_property_ui_text(prop, "Extrapolation", "Action to take for gaps past the strip extents."); prop= RNA_def_property(srna, "blending", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "blendmode"); - RNA_def_property_enum_items(prop, prop_mode_blend_items); + RNA_def_property_enum_items(prop, nla_mode_blend_items); RNA_def_property_ui_text(prop, "Blending", "Method used for combining strip's result with accumulated result."); /* Strip extents */