diff options
Diffstat (limited to 'source/blender/editors')
-rw-r--r-- | source/blender/editors/animation/anim_draw.c | 4 | ||||
-rw-r--r-- | source/blender/editors/animation/keyframes_draw.c | 296 | ||||
-rw-r--r-- | source/blender/editors/armature/pose_lib.c | 2 | ||||
-rw-r--r-- | source/blender/editors/armature/pose_slide.c | 4 | ||||
-rw-r--r-- | source/blender/editors/include/ED_keyframes_draw.h | 66 | ||||
-rw-r--r-- | source/blender/editors/include/UI_icons.h | 6 | ||||
-rw-r--r-- | source/blender/editors/include/UI_resources.h | 1 | ||||
-rw-r--r-- | source/blender/editors/interface/interface_icons.c | 60 | ||||
-rw-r--r-- | source/blender/editors/interface/resources.c | 3 | ||||
-rw-r--r-- | source/blender/editors/screen/screen_ops.c | 4 | ||||
-rw-r--r-- | source/blender/editors/space_action/action_draw.c | 16 | ||||
-rw-r--r-- | source/blender/editors/space_action/action_select.c | 12 | ||||
-rw-r--r-- | source/blender/editors/space_clip/clip_dopesheet_draw.c | 3 | ||||
-rw-r--r-- | source/blender/editors/space_nla/nla_draw.c | 11 |
14 files changed, 380 insertions, 108 deletions
diff --git a/source/blender/editors/animation/anim_draw.c b/source/blender/editors/animation/anim_draw.c index 48dd310e2b4..a2046985a36 100644 --- a/source/blender/editors/animation/anim_draw.c +++ b/source/blender/editors/animation/anim_draw.c @@ -551,11 +551,11 @@ static bool find_prev_next_keyframes(struct bContext *C, int *nextfra, int *prev } /* populate tree with keyframe nodes */ - scene_to_keylist(&ads, scene, &keys); + scene_to_keylist(&ads, scene, &keys, 0); gpencil_to_keylist(&ads, scene->gpd, &keys, false); if (ob) { - ob_to_keylist(&ads, ob, &keys); + ob_to_keylist(&ads, ob, &keys, 0); gpencil_to_keylist(&ads, ob->data, &keys, false); } diff --git a/source/blender/editors/animation/keyframes_draw.c b/source/blender/editors/animation/keyframes_draw.c index 33e2a11f4c5..008160e2459 100644 --- a/source/blender/editors/animation/keyframes_draw.c +++ b/source/blender/editors/animation/keyframes_draw.c @@ -42,6 +42,7 @@ #include "BLI_dlrbTree.h" #include "BLI_math.h" #include "BLI_utildefines.h" +#include "BLI_rect.h" #include "DNA_anim_types.h" #include "DNA_cachefile_types.h" @@ -96,24 +97,108 @@ short compare_ak_cfraPtr(void *node, void *data) /* --------------- */ -/* Comparator callback used for ActKeyColumns and BezTriple */ +/* Set of references to three logically adjacent keys. */ +typedef struct BezTripleChain { + /* Current keyframe. */ + BezTriple *cur; + + /* Logical neighbors. May be NULL. */ + BezTriple *prev, *next; +} BezTripleChain; + +/* Categorize the interpolation & handle type of the keyframe. */ +static eKeyframeHandleDrawOpts bezt_handle_type(BezTriple *bezt) +{ + if (bezt->h1 == HD_AUTO_ANIM && bezt->h2 == HD_AUTO_ANIM) { + return KEYFRAME_HANDLE_AUTO_CLAMP; + } + else if (ELEM(bezt->h1, HD_AUTO_ANIM, HD_AUTO) && ELEM(bezt->h2, HD_AUTO_ANIM, HD_AUTO)) { + return KEYFRAME_HANDLE_AUTO; + } + else if (bezt->h1 == HD_VECT && bezt->h2 == HD_VECT) { + return KEYFRAME_HANDLE_VECTOR; + } + else if (ELEM(HD_FREE, bezt->h1, bezt->h2)) { + return KEYFRAME_HANDLE_FREE; + } + else { + return KEYFRAME_HANDLE_ALIGNED; + } +} + +/* Determine if the keyframe is an extreme by comparing with neighbors. + * Ends of fixed-value sections and of the whole curve are also marked. + */ +static eKeyframeExtremeDrawOpts bezt_extreme_type(BezTripleChain *chain) +{ + if (chain->prev == NULL && chain->next == NULL) { + return KEYFRAME_EXTREME_NONE; + } + + /* Keyframe values for the current one and neighbors. */ + float cur_y = chain->cur->vec[1][1]; + float prev_y = cur_y, next_y = cur_y; + + if (chain->prev && !IS_EQF(cur_y, chain->prev->vec[1][1])) { + prev_y = chain->prev->vec[1][1]; + } + if (chain->next && !IS_EQF(cur_y, chain->next->vec[1][1])) { + next_y = chain->next->vec[1][1]; + } + + /* Static hold. */ + if (prev_y == cur_y && next_y == cur_y) { + return KEYFRAME_EXTREME_FLAT; + } + + /* Middle of an incline. */ + if ((prev_y < cur_y && next_y > cur_y) || (prev_y > cur_y && next_y < cur_y)) { + return KEYFRAME_EXTREME_NONE; + } + + /* Bezier handle values for the overshoot check. */ + bool l_bezier = chain->prev && chain->prev->ipo == BEZT_IPO_BEZ; + bool r_bezier = chain->next && chain->cur->ipo == BEZT_IPO_BEZ; + float handle_l = l_bezier ? chain->cur->vec[0][1] : cur_y; + float handle_r = r_bezier ? chain->cur->vec[2][1] : cur_y; + + /* Detect extremes. One of the neighbors is allowed to be equal to current. */ + if (prev_y < cur_y || next_y < cur_y) { + bool is_overshoot = (handle_l > cur_y || handle_r > cur_y); + + return KEYFRAME_EXTREME_MAX | (is_overshoot ? KEYFRAME_EXTREME_MIXED : 0); + } + + if (prev_y > cur_y || next_y > cur_y) { + bool is_overshoot = (handle_l < cur_y || handle_r < cur_y); + + return KEYFRAME_EXTREME_MIN | (is_overshoot ? KEYFRAME_EXTREME_MIXED : 0); + } + + return KEYFRAME_EXTREME_NONE; +} + +/* Comparator callback used for ActKeyColumns and BezTripleChain */ static short compare_ak_bezt(void *node, void *data) { - BezTriple *bezt = (BezTriple *)data; + BezTripleChain *chain = (BezTripleChain*)data; - return compare_ak_cfraPtr(node, &bezt->vec[1][0]); + return compare_ak_cfraPtr(node, &chain->cur->vec[1][0]); } -/* New node callback used for building ActKeyColumns from BezTriples */ +/* New node callback used for building ActKeyColumns from BezTripleChain */ static DLRBT_Node *nalloc_ak_bezt(void *data) { ActKeyColumn *ak = MEM_callocN(sizeof(ActKeyColumn), "ActKeyColumn"); - BezTriple *bezt = (BezTriple *)data; + BezTripleChain *chain = (BezTripleChain*)data; + BezTriple *bezt = chain->cur; /* store settings based on state of BezTriple */ ak->cfra = bezt->vec[1][0]; ak->sel = BEZT_ISSEL_ANY(bezt) ? SELECT : 0; ak->key_type = BEZKEYTYPE(bezt); + ak->handle_type = bezt_handle_type(bezt); + ak->extreme_type = bezt_extreme_type(chain); /* count keyframes in this column */ ak->totkey = 1; @@ -121,11 +206,12 @@ static DLRBT_Node *nalloc_ak_bezt(void *data) return (DLRBT_Node *)ak; } -/* Node updater callback used for building ActKeyColumns from BezTriples */ +/* Node updater callback used for building ActKeyColumns from BezTripleChain */ static void nupdate_ak_bezt(void *node, void *data) { ActKeyColumn *ak = (ActKeyColumn *)node; - BezTriple *bezt = (BezTriple *)data; + BezTripleChain *chain = (BezTripleChain*)data; + BezTriple *bezt = chain->cur; /* set selection status and 'touched' status */ if (BEZT_ISSEL_ANY(bezt)) ak->sel = SELECT; @@ -136,6 +222,22 @@ static void nupdate_ak_bezt(void *node, void *data) /* for keyframe type, 'proper' keyframes have priority over breakdowns (and other types for now) */ if (BEZKEYTYPE(bezt) == BEZT_KEYTYPE_KEYFRAME) ak->key_type = BEZT_KEYTYPE_KEYFRAME; + + /* For interpolation type, select the highest value (enum is sorted). */ + ak->handle_type = MAX2(ak->handle_type, bezt_handle_type(bezt)); + + /* For extremes, detect when combining different states. */ + char new_extreme = bezt_extreme_type(chain); + + if (new_extreme != ak->extreme_type) { + /* Replace the flat status without adding mixed. */ + if (ak->extreme_type == KEYFRAME_EXTREME_FLAT) { + ak->extreme_type = new_extreme; + } + else if (new_extreme != KEYFRAME_EXTREME_FLAT) { + ak->extreme_type |= (new_extreme | KEYFRAME_EXTREME_MIXED); + } + } } /* ......... */ @@ -225,7 +327,7 @@ static void nupdate_ak_masklayshape(void *node, void *data) /* --------------- */ /* Add the given BezTriple to the given 'list' of Keyframes */ -static void add_bezt_to_keycolumns_list(DLRBT_Tree *keys, BezTriple *bezt) +static void add_bezt_to_keycolumns_list(DLRBT_Tree *keys, BezTripleChain *bezt) { if (ELEM(NULL, keys, bezt)) return; @@ -291,6 +393,11 @@ static void compute_keyblock_data(ActKeyBlockInfo *info, BezTriple *prev, BezTri } } + /* Remember non-bezier interpolation info. */ + if (prev->ipo != BEZT_IPO_BEZ) { + info->flag |= ACTKEYBLOCK_FLAG_NON_BEZIER; + } + info->sel = BEZT_ISSEL_ANY(prev) || BEZT_ISSEL_ANY(beztn); } @@ -410,11 +517,16 @@ static void update_keyblocks(DLRBT_Tree *keys, BezTriple *bezt, int bezt_len) /* --------- */ +bool actkeyblock_is_valid(ActKeyColumn *ac) +{ + return ac != NULL && ac->next != NULL && ac->totblock > 0; +} + /* Checks if ActKeyBlock should exist... */ int actkeyblock_get_valid_hold(ActKeyColumn *ac) { /* check that block is valid */ - if (ac == NULL || ac->next == NULL || ac->totblock == 0) + if (!actkeyblock_is_valid(ac)) return 0; const int hold_mask = (ACTKEYBLOCK_FLAG_ANY_HOLD | ACTKEYBLOCK_FLAG_STATIC_HOLD | ACTKEYBLOCK_FLAG_ANY_HOLD); @@ -424,7 +536,8 @@ int actkeyblock_get_valid_hold(ActKeyColumn *ac) /* *************************** Keyframe Drawing *************************** */ void draw_keyframe_shape(float x, float y, float size, bool sel, short key_type, short mode, float alpha, - unsigned int pos_id, unsigned int size_id, unsigned int color_id, unsigned int outline_color_id) + unsigned int pos_id, unsigned int size_id, unsigned int color_id, unsigned int outline_color_id, + unsigned int flags_id, short handle_type, short extreme_type) { bool draw_fill = ELEM(mode, KEYFRAME_SHAPE_INSIDE, KEYFRAME_SHAPE_BOTH); bool draw_outline = ELEM(mode, KEYFRAME_SHAPE_FRAME, KEYFRAME_SHAPE_BOTH); @@ -456,6 +569,7 @@ void draw_keyframe_shape(float x, float y, float size, bool sel, short key_type, unsigned char fill_col[4]; unsigned char outline_col[4]; + unsigned int flags = 0; /* draw! */ if (draw_fill) { @@ -504,19 +618,44 @@ void draw_keyframe_shape(float x, float y, float size, bool sel, short key_type, fill_col[2] = outline_col[2]; fill_col[3] = 0; } + + /* Handle type to outline shape. */ + switch (handle_type) { + case KEYFRAME_HANDLE_AUTO_CLAMP: flags = 0x2; break; /* circle */ + case KEYFRAME_HANDLE_AUTO: flags = 0x12; break; /* circle with dot */ + case KEYFRAME_HANDLE_VECTOR: flags = 0xC; break; /* square */ + case KEYFRAME_HANDLE_ALIGNED: flags = 0x5; break; /* clipped diamond */ + + case KEYFRAME_HANDLE_FREE: + default: + flags = 1; /* diamond */ + } + + /* Extreme type to arrow-like shading. */ + if (extreme_type & KEYFRAME_EXTREME_MAX) { + flags |= 0x100; + } + if (extreme_type & KEYFRAME_EXTREME_MIN) { + flags |= 0x200; + } + if (extreme_type & KEYFRAME_EXTREME_MIXED) { + flags |= 0x400; + } } immAttr1f(size_id, size); immAttr4ubv(color_id, fill_col); immAttr4ubv(outline_color_id, outline_col); + immAttr1u(flags_id, flags); immVertex2f(pos_id, x, y); } -static void draw_keylist(View2D *v2d, DLRBT_Tree *keys, float ypos, float yscale_fac, bool channelLocked) +static void draw_keylist(View2D *v2d, DLRBT_Tree *keys, float ypos, float yscale_fac, bool channelLocked, int saction_flag) { const float icon_sz = U.widget_unit * 0.5f * yscale_fac; const float half_icon_sz = 0.5f * icon_sz; const float smaller_sz = 0.35f * icon_sz; + const float ipo_sz = 0.1f * icon_sz; GPU_blend(true); @@ -524,28 +663,39 @@ static void draw_keylist(View2D *v2d, DLRBT_Tree *keys, float ypos, float yscale /* TODO: allow this opacity factor to be themed? */ float alpha = channelLocked ? 0.25f : 1.0f; + /* Show interpolation and handle type? */ + bool show_ipo = (saction_flag & SACTION_SHOW_INTERPOLATION) != 0; + /* draw keyblocks */ if (keys) { float sel_color[4], unsel_color[4]; float sel_mhcol[4], unsel_mhcol[4]; + float ipo_color[4], ipo_color_mix[4]; /* cache colours first */ UI_GetThemeColor4fv(TH_STRIP_SELECT, sel_color); UI_GetThemeColor4fv(TH_STRIP, unsel_color); + UI_GetThemeColor4fv(TH_DOPESHEET_IPOLINE, ipo_color); sel_color[3] *= alpha; unsel_color[3] *= alpha; + ipo_color[3] *= alpha; copy_v4_v4(sel_mhcol, sel_color); sel_mhcol[3] *= 0.8f; copy_v4_v4(unsel_mhcol, unsel_color); unsel_mhcol[3] *= 0.8f; + copy_v4_v4(ipo_color_mix, ipo_color); + ipo_color_mix[3] *= 0.5f; uint block_len = 0; for (ActKeyColumn *ab = keys->first; ab; ab = ab->next) { if (actkeyblock_get_valid_hold(ab)) { block_len++; } + if (show_ipo && actkeyblock_is_valid(ab) && (ab->block.flag & ACTKEYBLOCK_FLAG_NON_BEZIER)) { + block_len++; + } } if (block_len > 0) { @@ -571,6 +721,12 @@ static void draw_keylist(View2D *v2d, DLRBT_Tree *keys, float ypos, float yscale (ab->block.sel) ? sel_color : unsel_color); } } + if (show_ipo && actkeyblock_is_valid(ab) && (ab->block.flag & ACTKEYBLOCK_FLAG_NON_BEZIER)) { + /* draw an interpolation line */ + immRectf_fast_with_color(pos_id, color_id, + ab->cfra, ypos - ipo_sz, ab->next->cfra, ypos + ipo_sz, + (ab->block.conflict & ACTKEYBLOCK_FLAG_NON_BEZIER) ? ipo_color_mix : ipo_color); + } } immEnd(); immUnbindProgram(); @@ -595,14 +751,25 @@ static void draw_keylist(View2D *v2d, DLRBT_Tree *keys, float ypos, float yscale uint size_id = GPU_vertformat_attr_add(format, "size", GPU_COMP_F32, 1, GPU_FETCH_FLOAT); uint color_id = GPU_vertformat_attr_add(format, "color", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT); uint outline_color_id = GPU_vertformat_attr_add(format, "outlineColor", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT); + uint flags_id = GPU_vertformat_attr_add(format, "flags", GPU_COMP_U32, 1, GPU_FETCH_INT); immBindBuiltinProgram(GPU_SHADER_KEYFRAME_DIAMOND); GPU_enable_program_point_size(); + immUniform2f("ViewportSize", BLI_rcti_size_x(&v2d->mask) + 1, BLI_rcti_size_y(&v2d->mask) + 1); immBegin(GPU_PRIM_POINTS, key_len); + short handle_type = KEYFRAME_HANDLE_NONE, extreme_type = KEYFRAME_EXTREME_NONE; + for (ActKeyColumn *ak = keys->first; ak; ak = ak->next) { if (IN_RANGE_INCL(ak->cfra, v2d->cur.xmin, v2d->cur.xmax)) { + if (show_ipo) { + handle_type = ak->handle_type; + } + if (saction_flag & SACTION_SHOW_EXTREMES) { + extreme_type = ak->extreme_type; + } + draw_keyframe_shape(ak->cfra, ypos, icon_sz, (ak->sel & SELECT), ak->key_type, KEYFRAME_SHAPE_BOTH, alpha, - pos_id, size_id, color_id, outline_color_id); + pos_id, size_id, color_id, outline_color_id, flags_id, handle_type, extreme_type); } } @@ -617,46 +784,52 @@ static void draw_keylist(View2D *v2d, DLRBT_Tree *keys, float ypos, float yscale /* *************************** Channel Drawing Funcs *************************** */ -void draw_summary_channel(View2D *v2d, bAnimContext *ac, float ypos, float yscale_fac) +void draw_summary_channel(View2D *v2d, bAnimContext *ac, float ypos, float yscale_fac, int saction_flag) { DLRBT_Tree keys; + saction_flag &= ~SACTION_SHOW_EXTREMES; + BLI_dlrbTree_init(&keys); - summary_to_keylist(ac, &keys); + summary_to_keylist(ac, &keys, saction_flag); - draw_keylist(v2d, &keys, ypos, yscale_fac, false); + draw_keylist(v2d, &keys, ypos, yscale_fac, false, saction_flag); BLI_dlrbTree_free(&keys); } -void draw_scene_channel(View2D *v2d, bDopeSheet *ads, Scene *sce, float ypos, float yscale_fac) +void draw_scene_channel(View2D *v2d, bDopeSheet *ads, Scene *sce, float ypos, float yscale_fac, int saction_flag) { DLRBT_Tree keys; + saction_flag &= ~SACTION_SHOW_EXTREMES; + BLI_dlrbTree_init(&keys); - scene_to_keylist(ads, sce, &keys); + scene_to_keylist(ads, sce, &keys, saction_flag); - draw_keylist(v2d, &keys, ypos, yscale_fac, false); + draw_keylist(v2d, &keys, ypos, yscale_fac, false, saction_flag); BLI_dlrbTree_free(&keys); } -void draw_object_channel(View2D *v2d, bDopeSheet *ads, Object *ob, float ypos, float yscale_fac) +void draw_object_channel(View2D *v2d, bDopeSheet *ads, Object *ob, float ypos, float yscale_fac, int saction_flag) { DLRBT_Tree keys; + saction_flag &= ~SACTION_SHOW_EXTREMES; + BLI_dlrbTree_init(&keys); - ob_to_keylist(ads, ob, &keys); + ob_to_keylist(ads, ob, &keys, saction_flag); - draw_keylist(v2d, &keys, ypos, yscale_fac, false); + draw_keylist(v2d, &keys, ypos, yscale_fac, false, saction_flag); BLI_dlrbTree_free(&keys); } -void draw_fcurve_channel(View2D *v2d, AnimData *adt, FCurve *fcu, float ypos, float yscale_fac) +void draw_fcurve_channel(View2D *v2d, AnimData *adt, FCurve *fcu, float ypos, float yscale_fac, int saction_flag) { DLRBT_Tree keys; @@ -666,14 +839,14 @@ void draw_fcurve_channel(View2D *v2d, AnimData *adt, FCurve *fcu, float ypos, fl BLI_dlrbTree_init(&keys); - fcurve_to_keylist(adt, fcu, &keys); + fcurve_to_keylist(adt, fcu, &keys, saction_flag); - draw_keylist(v2d, &keys, ypos, yscale_fac, locked); + draw_keylist(v2d, &keys, ypos, yscale_fac, locked, saction_flag); BLI_dlrbTree_free(&keys); } -void draw_agroup_channel(View2D *v2d, AnimData *adt, bActionGroup *agrp, float ypos, float yscale_fac) +void draw_agroup_channel(View2D *v2d, AnimData *adt, bActionGroup *agrp, float ypos, float yscale_fac, int saction_flag) { DLRBT_Tree keys; @@ -682,42 +855,46 @@ void draw_agroup_channel(View2D *v2d, AnimData *adt, bActionGroup *agrp, float y BLI_dlrbTree_init(&keys); - agroup_to_keylist(adt, agrp, &keys); + agroup_to_keylist(adt, agrp, &keys, saction_flag); - draw_keylist(v2d, &keys, ypos, yscale_fac, locked); + draw_keylist(v2d, &keys, ypos, yscale_fac, locked, saction_flag); BLI_dlrbTree_free(&keys); } -void draw_action_channel(View2D *v2d, AnimData *adt, bAction *act, float ypos, float yscale_fac) +void draw_action_channel(View2D *v2d, AnimData *adt, bAction *act, float ypos, float yscale_fac, int saction_flag) { DLRBT_Tree keys; bool locked = (act && ID_IS_LINKED(act)); + saction_flag &= ~SACTION_SHOW_EXTREMES; + BLI_dlrbTree_init(&keys); - action_to_keylist(adt, act, &keys); + action_to_keylist(adt, act, &keys, saction_flag); - draw_keylist(v2d, &keys, ypos, yscale_fac, locked); + draw_keylist(v2d, &keys, ypos, yscale_fac, locked, saction_flag); BLI_dlrbTree_free(&keys); } -void draw_gpencil_channel(View2D *v2d, bDopeSheet *ads, bGPdata *gpd, float ypos, float yscale_fac) +void draw_gpencil_channel(View2D *v2d, bDopeSheet *ads, bGPdata *gpd, float ypos, float yscale_fac, int saction_flag) { DLRBT_Tree keys; + saction_flag &= ~SACTION_SHOW_EXTREMES; + BLI_dlrbTree_init(&keys); gpencil_to_keylist(ads, gpd, &keys, false); - draw_keylist(v2d, &keys, ypos, yscale_fac, false); + draw_keylist(v2d, &keys, ypos, yscale_fac, false, saction_flag); BLI_dlrbTree_free(&keys); } -void draw_gpl_channel(View2D *v2d, bDopeSheet *ads, bGPDlayer *gpl, float ypos, float yscale_fac) +void draw_gpl_channel(View2D *v2d, bDopeSheet *ads, bGPDlayer *gpl, float ypos, float yscale_fac, int saction_flag) { DLRBT_Tree keys; @@ -727,12 +904,12 @@ void draw_gpl_channel(View2D *v2d, bDopeSheet *ads, bGPDlayer *gpl, float ypos, gpl_to_keylist(ads, gpl, &keys); - draw_keylist(v2d, &keys, ypos, yscale_fac, locked); + draw_keylist(v2d, &keys, ypos, yscale_fac, locked, saction_flag); BLI_dlrbTree_free(&keys); } -void draw_masklay_channel(View2D *v2d, bDopeSheet *ads, MaskLayer *masklay, float ypos, float yscale_fac) +void draw_masklay_channel(View2D *v2d, bDopeSheet *ads, MaskLayer *masklay, float ypos, float yscale_fac, int saction_flag) { DLRBT_Tree keys; @@ -742,14 +919,14 @@ void draw_masklay_channel(View2D *v2d, bDopeSheet *ads, MaskLayer *masklay, floa mask_to_keylist(ads, masklay, &keys); - draw_keylist(v2d, &keys, ypos, yscale_fac, locked); + draw_keylist(v2d, &keys, ypos, yscale_fac, locked, saction_flag); BLI_dlrbTree_free(&keys); } /* *************************** Keyframe List Conversions *************************** */ -void summary_to_keylist(bAnimContext *ac, DLRBT_Tree *keys) +void summary_to_keylist(bAnimContext *ac, DLRBT_Tree *keys, int saction_flag) { if (ac) { ListBase anim_data = {NULL, NULL}; @@ -769,7 +946,7 @@ void summary_to_keylist(bAnimContext *ac, DLRBT_Tree *keys) switch (ale->datatype) { case ALE_FCURVE: - fcurve_to_keylist(ale->adt, ale->data, keys); + fcurve_to_keylist(ale->adt, ale->data, keys, saction_flag); break; case ALE_MASKLAY: mask_to_keylist(ac->ads, ale->data, keys); @@ -787,7 +964,7 @@ void summary_to_keylist(bAnimContext *ac, DLRBT_Tree *keys) } } -void scene_to_keylist(bDopeSheet *ads, Scene *sce, DLRBT_Tree *keys) +void scene_to_keylist(bDopeSheet *ads, Scene *sce, DLRBT_Tree *keys, int saction_flag) { bAnimContext ac = {NULL}; ListBase anim_data = {NULL, NULL}; @@ -815,12 +992,12 @@ void scene_to_keylist(bDopeSheet *ads, Scene *sce, DLRBT_Tree *keys) /* loop through each F-Curve, grabbing the keyframes */ for (ale = anim_data.first; ale; ale = ale->next) - fcurve_to_keylist(ale->adt, ale->data, keys); + fcurve_to_keylist(ale->adt, ale->data, keys, saction_flag); ANIM_animdata_freelist(&anim_data); } -void ob_to_keylist(bDopeSheet *ads, Object *ob, DLRBT_Tree *keys) +void ob_to_keylist(bDopeSheet *ads, Object *ob, DLRBT_Tree *keys, int saction_flag) { bAnimContext ac = {NULL}; ListBase anim_data = {NULL, NULL}; @@ -851,12 +1028,12 @@ void ob_to_keylist(bDopeSheet *ads, Object *ob, DLRBT_Tree *keys) /* loop through each F-Curve, grabbing the keyframes */ for (ale = anim_data.first; ale; ale = ale->next) - fcurve_to_keylist(ale->adt, ale->data, keys); + fcurve_to_keylist(ale->adt, ale->data, keys, saction_flag); ANIM_animdata_freelist(&anim_data); } -void cachefile_to_keylist(bDopeSheet *ads, CacheFile *cache_file, DLRBT_Tree *keys) +void cachefile_to_keylist(bDopeSheet *ads, CacheFile *cache_file, DLRBT_Tree *keys, int saction_flag) { if (cache_file == NULL) { return; @@ -881,25 +1058,36 @@ void cachefile_to_keylist(bDopeSheet *ads, CacheFile *cache_file, DLRBT_Tree *ke /* loop through each F-Curve, grabbing the keyframes */ for (bAnimListElem *ale = anim_data.first; ale; ale = ale->next) { - fcurve_to_keylist(ale->adt, ale->data, keys); + fcurve_to_keylist(ale->adt, ale->data, keys, saction_flag); } ANIM_animdata_freelist(&anim_data); } -void fcurve_to_keylist(AnimData *adt, FCurve *fcu, DLRBT_Tree *keys) +void fcurve_to_keylist(AnimData *adt, FCurve *fcu, DLRBT_Tree *keys, int saction_flag) { - BezTriple *bezt; - unsigned int v; - if (fcu && fcu->totvert && fcu->bezt) { /* apply NLA-mapping (if applicable) */ if (adt) ANIM_nla_mapping_apply_fcurve(adt, fcu, 0, 0); + /* Check if the curve is cyclic. */ + bool is_cyclic = BKE_fcurve_is_cyclic(fcu) && (fcu->totvert >= 2); + bool do_extremes = (saction_flag & SACTION_SHOW_EXTREMES) != 0; + /* loop through beztriples, making ActKeysColumns */ - for (v = 0, bezt = fcu->bezt; v < fcu->totvert; v++, bezt++) { - add_bezt_to_keycolumns_list(keys, bezt); + BezTripleChain chain = { 0 }; + + for (int v = 0; v < fcu->totvert; v++) { + chain.cur = &fcu->bezt[v]; + + /* Neighbor keys, accounting for being cyclic. */ + if (do_extremes) { + chain.prev = (v > 0) ? &fcu->bezt[v - 1] : is_cyclic ? &fcu->bezt[fcu->totvert - 2] : NULL; + chain.next = (v + 1 < fcu->totvert) ? &fcu->bezt[v + 1] : is_cyclic ? &fcu->bezt[1] : NULL; + } + + add_bezt_to_keycolumns_list(keys, &chain); } /* Update keyblocks. */ @@ -911,26 +1099,26 @@ void fcurve_to_keylist(AnimData *adt, FCurve *fcu, DLRBT_Tree *keys) } } -void agroup_to_keylist(AnimData *adt, bActionGroup *agrp, DLRBT_Tree *keys) +void agroup_to_keylist(AnimData *adt, bActionGroup *agrp, DLRBT_Tree *keys, int saction_flag) { FCurve *fcu; if (agrp) { /* loop through F-Curves */ for (fcu = agrp->channels.first; fcu && fcu->grp == agrp; fcu = fcu->next) { - fcurve_to_keylist(adt, fcu, keys); + fcurve_to_keylist(adt, fcu, keys, saction_flag); } } } -void action_to_keylist(AnimData *adt, bAction *act, DLRBT_Tree *keys) +void action_to_keylist(AnimData *adt, bAction *act, DLRBT_Tree *keys, int saction_flag) { FCurve *fcu; if (act) { /* loop through F-Curves */ for (fcu = act->curves.first; fcu; fcu = fcu->next) { - fcurve_to_keylist(adt, fcu, keys); + fcurve_to_keylist(adt, fcu, keys, saction_flag); } } } diff --git a/source/blender/editors/armature/pose_lib.c b/source/blender/editors/armature/pose_lib.c index 673ca587811..280aa73b1c8 100644 --- a/source/blender/editors/armature/pose_lib.c +++ b/source/blender/editors/armature/pose_lib.c @@ -312,7 +312,7 @@ static int poselib_sanitize_exec(bContext *C, wmOperator *op) /* determine which frames have keys */ BLI_dlrbTree_init(&keys); - action_to_keylist(NULL, act, &keys); + action_to_keylist(NULL, act, &keys, 0); /* for each key, make sure there is a corresponding pose */ for (ak = keys.first; ak; ak = ak->next) { diff --git a/source/blender/editors/armature/pose_slide.c b/source/blender/editors/armature/pose_slide.c index bae794e84c4..be3914b2054 100644 --- a/source/blender/editors/armature/pose_slide.c +++ b/source/blender/editors/armature/pose_slide.c @@ -789,7 +789,7 @@ static int pose_slide_invoke_common(bContext *C, wmOperator *op, tPoseSlideOp *p /* do this for each F-Curve */ for (ld = pfl->fcurves.first; ld; ld = ld->next) { FCurve *fcu = (FCurve *)ld->data; - fcurve_to_keylist(pfl->ob->adt, fcu, &pso->keys); + fcurve_to_keylist(pfl->ob->adt, fcu, &pso->keys, 0); } } @@ -1350,7 +1350,7 @@ static float pose_propagate_get_boneHoldEndFrame(tPChanFCurveLink *pfl, float st for (ld = pfl->fcurves.first; ld; ld = ld->next) { FCurve *fcu = (FCurve *)ld->data; - fcurve_to_keylist(adt, fcu, &keys); + fcurve_to_keylist(adt, fcu, &keys, 0); } /* find the long keyframe (i.e. hold), and hence obtain the endFrame value diff --git a/source/blender/editors/include/ED_keyframes_draw.h b/source/blender/editors/include/ED_keyframes_draw.h index 93fd8238fdd..6421c5817b0 100644 --- a/source/blender/editors/include/ED_keyframes_draw.h +++ b/source/blender/editors/include/ED_keyframes_draw.h @@ -73,6 +73,8 @@ typedef struct ActKeyColumn { /* keyframe info */ char key_type; /* eBezTripe_KeyframeType */ + char handle_type; /* eKeyframeHandleDrawOpts */ + char extreme_type; /* eKeyframeExtremeDrawOpts */ short sel; float cfra; @@ -91,6 +93,8 @@ typedef enum eActKeyBlock_Hold { ACTKEYBLOCK_FLAG_STATIC_HOLD = (1 << 1), /* Key block represents any kind of hold */ ACTKEYBLOCK_FLAG_ANY_HOLD = (1 << 2), + /* The curve segment uses non-bezier interpolation */ + ACTKEYBLOCK_FLAG_NON_BEZIER = (1 << 3), } eActKeyBlock_Flag; /* *********************** Keyframe Drawing ****************************** */ @@ -105,48 +109,73 @@ typedef enum eKeyframeShapeDrawOpts { KEYFRAME_SHAPE_BOTH } eKeyframeShapeDrawOpts; +/* Handle type. */ +typedef enum eKeyframeHandleDrawOpts { + /* Don't draw */ + KEYFRAME_HANDLE_NONE = 0, + /* Various marks in order of increasing display priority. */ + KEYFRAME_HANDLE_AUTO_CLAMP, + KEYFRAME_HANDLE_AUTO, + KEYFRAME_HANDLE_VECTOR, + KEYFRAME_HANDLE_ALIGNED, + KEYFRAME_HANDLE_FREE, +} eKeyframeHandleDrawOpts; + +/* Extreme type. */ +typedef enum eKeyframeExtremeDrawOpts { + KEYFRAME_EXTREME_NONE = 0, + /* Minimum/maximum present. */ + KEYFRAME_EXTREME_MIN = (1 << 0), + KEYFRAME_EXTREME_MAX = (1 << 1), + /* Grouped keys have different states. */ + KEYFRAME_EXTREME_MIXED = (1 << 2), + /* Both neigbors are equal to this key. */ + KEYFRAME_EXTREME_FLAT = (1 << 3), +} eKeyframeExtremeDrawOpts; + /* draw simple diamond-shape keyframe */ /* caller should set up vertex format, bind GPU_SHADER_KEYFRAME_DIAMOND, immBegin(GPU_PRIM_POINTS, n), then call this n times */ void draw_keyframe_shape(float x, float y, float size, bool sel, short key_type, short mode, float alpha, - unsigned int pos_id, unsigned int size_id, unsigned int color_id, unsigned int outline_color_id); + unsigned int pos_id, unsigned int size_id, unsigned int color_id, unsigned int outline_color_id, + unsigned int linemask_id, short ipo_type, short extreme_type); /* ******************************* Methods ****************************** */ /* Channel Drawing ------------------ */ /* F-Curve */ -void draw_fcurve_channel(struct View2D *v2d, struct AnimData *adt, struct FCurve *fcu, float ypos, float yscale_fac); +void draw_fcurve_channel(struct View2D *v2d, struct AnimData *adt, struct FCurve *fcu, float ypos, float yscale_fac, int saction_flag); /* Action Group Summary */ -void draw_agroup_channel(struct View2D *v2d, struct AnimData *adt, struct bActionGroup *agrp, float ypos, float yscale_fac); +void draw_agroup_channel(struct View2D *v2d, struct AnimData *adt, struct bActionGroup *agrp, float ypos, float yscale_fac, int saction_flag); /* Action Summary */ -void draw_action_channel(struct View2D *v2d, struct AnimData *adt, struct bAction *act, float ypos, float yscale_fac); +void draw_action_channel(struct View2D *v2d, struct AnimData *adt, struct bAction *act, float ypos, float yscale_fac, int saction_flag); /* Object Summary */ -void draw_object_channel(struct View2D *v2d, struct bDopeSheet *ads, struct Object *ob, float ypos, float yscale_fac); +void draw_object_channel(struct View2D *v2d, struct bDopeSheet *ads, struct Object *ob, float ypos, float yscale_fac, int saction_flag); /* Scene Summary */ -void draw_scene_channel(struct View2D *v2d, struct bDopeSheet *ads, struct Scene *sce, float ypos, float yscale_fac); +void draw_scene_channel(struct View2D *v2d, struct bDopeSheet *ads, struct Scene *sce, float ypos, float yscale_fac, int saction_flag); /* DopeSheet Summary */ -void draw_summary_channel(struct View2D *v2d, struct bAnimContext *ac, float ypos, float yscale_fac); +void draw_summary_channel(struct View2D *v2d, struct bAnimContext *ac, float ypos, float yscale_fac, int saction_flag); /* Grease Pencil datablock summary */ -void draw_gpencil_channel(struct View2D *v2d, struct bDopeSheet *ads, struct bGPdata *gpd, float ypos, float yscale_fac); +void draw_gpencil_channel(struct View2D *v2d, struct bDopeSheet *ads, struct bGPdata *gpd, float ypos, float yscale_fac, int saction_flag); /* Grease Pencil Layer */ -void draw_gpl_channel(struct View2D *v2d, struct bDopeSheet *ads, struct bGPDlayer *gpl, float ypos, float yscale_fac); +void draw_gpl_channel(struct View2D *v2d, struct bDopeSheet *ads, struct bGPDlayer *gpl, float ypos, float yscale_fac, int saction_flag); /* Mask Layer */ -void draw_masklay_channel(struct View2D *v2d, struct bDopeSheet *ads, struct MaskLayer *masklay, float ypos, float yscale_fac); +void draw_masklay_channel(struct View2D *v2d, struct bDopeSheet *ads, struct MaskLayer *masklay, float ypos, float yscale_fac, int saction_flag); /* Keydata Generation --------------- */ /* F-Curve */ -void fcurve_to_keylist(struct AnimData *adt, struct FCurve *fcu, struct DLRBT_Tree *keys); +void fcurve_to_keylist(struct AnimData *adt, struct FCurve *fcu, struct DLRBT_Tree *keys, int saction_flag); /* Action Group */ -void agroup_to_keylist(struct AnimData *adt, struct bActionGroup *agrp, struct DLRBT_Tree *keys); +void agroup_to_keylist(struct AnimData *adt, struct bActionGroup *agrp, struct DLRBT_Tree *keys, int saction_flag); /* Action */ -void action_to_keylist(struct AnimData *adt, struct bAction *act, struct DLRBT_Tree *keys); +void action_to_keylist(struct AnimData *adt, struct bAction *act, struct DLRBT_Tree *keys, int saction_flag); /* Object */ -void ob_to_keylist(struct bDopeSheet *ads, struct Object *ob, struct DLRBT_Tree *keys); +void ob_to_keylist(struct bDopeSheet *ads, struct Object *ob, struct DLRBT_Tree *keys, int saction_flag); /* Cache File */ -void cachefile_to_keylist(struct bDopeSheet *ads, struct CacheFile *cache_file, struct DLRBT_Tree *keys); +void cachefile_to_keylist(struct bDopeSheet *ads, struct CacheFile *cache_file, struct DLRBT_Tree *keys, int saction_flag); /* Scene */ -void scene_to_keylist(struct bDopeSheet *ads, struct Scene *sce, struct DLRBT_Tree *keys); +void scene_to_keylist(struct bDopeSheet *ads, struct Scene *sce, struct DLRBT_Tree *keys, int saction_flag); /* DopeSheet Summary */ -void summary_to_keylist(struct bAnimContext *ac, struct DLRBT_Tree *keys); +void summary_to_keylist(struct bAnimContext *ac, struct DLRBT_Tree *keys, int saction_flag); /* Grease Pencil datablock summary */ void gpencil_to_keylist(struct bDopeSheet *ads, struct bGPdata *gpd, struct DLRBT_Tree *keys, const bool active); /* Grease Pencil Layer */ @@ -160,6 +189,9 @@ void mask_to_keylist(struct bDopeSheet *UNUSED(ads), struct MaskLayer *masklay, /* Comparator callback used for ActKeyColumns and cframe float-value pointer */ short compare_ak_cfraPtr(void *node, void *data); +/* Checks if ActKeyColumn has any block data */ +bool actkeyblock_is_valid(ActKeyColumn *ab); + /* Checks if ActKeyColumn can be used as a block (i.e. drawn/used to detect "holds") */ int actkeyblock_get_valid_hold(ActKeyColumn *ab); diff --git a/source/blender/editors/include/UI_icons.h b/source/blender/editors/include/UI_icons.h index b5e910a650a..cde88e13b1f 100644 --- a/source/blender/editors/include/UI_icons.h +++ b/source/blender/editors/include/UI_icons.h @@ -982,6 +982,12 @@ DEF_ICON_VECTOR(KEYTYPE_EXTREME_VEC) DEF_ICON_VECTOR(KEYTYPE_JITTER_VEC) DEF_ICON_VECTOR(KEYTYPE_MOVING_HOLD_VEC) +DEF_ICON_VECTOR(HANDLETYPE_FREE_VEC) +DEF_ICON_VECTOR(HANDLETYPE_ALIGNED_VEC) +DEF_ICON_VECTOR(HANDLETYPE_VECTOR_VEC) +DEF_ICON_VECTOR(HANDLETYPE_AUTO_VEC) +DEF_ICON_VECTOR(HANDLETYPE_AUTO_CLAMP_VEC) + DEF_ICON_VECTOR(COLORSET_01_VEC) DEF_ICON_VECTOR(COLORSET_02_VEC) DEF_ICON_VECTOR(COLORSET_03_VEC) diff --git a/source/blender/editors/include/UI_resources.h b/source/blender/editors/include/UI_resources.h index fd6fa3add30..277aae923d6 100644 --- a/source/blender/editors/include/UI_resources.h +++ b/source/blender/editors/include/UI_resources.h @@ -217,6 +217,7 @@ typedef enum ThemeColorID { TH_DOPESHEET_CHANNELOB, TH_DOPESHEET_CHANNELSUBOB, + TH_DOPESHEET_IPOLINE, TH_PREVIEW_BACK, diff --git a/source/blender/editors/interface/interface_icons.c b/source/blender/editors/interface/interface_icons.c index 6289bc09f5a..09e16b806f3 100644 --- a/source/blender/editors/interface/interface_icons.c +++ b/source/blender/editors/interface/interface_icons.c @@ -286,7 +286,7 @@ static void vicon_small_tri_right_draw(int x, int y, int w, int UNUSED(h), float immUnbindProgram(); } -static void vicon_keytype_draw_wrapper(int x, int y, int w, int h, float alpha, short key_type) +static void vicon_keytype_draw_wrapper(int x, int y, int w, int h, float alpha, short key_type, short handle_type) { /* init dummy theme state for Action Editor - where these colors are defined * (since we're doing this offscreen, free from any particular space_id) @@ -300,25 +300,30 @@ static void vicon_keytype_draw_wrapper(int x, int y, int w, int h, float alpha, * while the draw_keyframe_shape() function needs the midpoint for * the keyframe */ - int xco = x + w / 2; - int yco = y + h / 2; + float xco = x + w / 2 + 0.5f; + float yco = y + h / 2 + 0.5f; GPUVertFormat *format = immVertexFormat(); uint pos_id = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); uint size_id = GPU_vertformat_attr_add(format, "size", GPU_COMP_F32, 1, GPU_FETCH_FLOAT); uint color_id = GPU_vertformat_attr_add(format, "color", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT); uint outline_color_id = GPU_vertformat_attr_add(format, "outlineColor", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT); + uint flags_id = GPU_vertformat_attr_add(format, "flags", GPU_COMP_U32, 1, GPU_FETCH_INT); immBindBuiltinProgram(GPU_SHADER_KEYFRAME_DIAMOND); GPU_enable_program_point_size(); + immUniform2f("ViewportSize", -1.0f, -1.0f); immBegin(GPU_PRIM_POINTS, 1); /* draw keyframe - * - size: 0.6 * h (found out experimentally... dunno why!) - * - sel: true (so that "keyframe" state shows the iconic yellow icon) + * - size: (default icon size == 16, default dopesheet icon size == 10) + * - sel: true unless in handletype icons (so that "keyframe" state shows the iconic yellow icon) */ - draw_keyframe_shape(xco, yco, 0.6f * h, true, key_type, KEYFRAME_SHAPE_BOTH, alpha, - pos_id, size_id, color_id, outline_color_id); + bool sel = (handle_type == KEYFRAME_HANDLE_NONE); + + draw_keyframe_shape(xco, yco, (10.0f / 16.0f) * h, sel, key_type, KEYFRAME_SHAPE_BOTH, alpha, + pos_id, size_id, color_id, outline_color_id, + flags_id, handle_type, KEYFRAME_EXTREME_NONE); immEnd(); GPU_disable_program_point_size(); @@ -329,27 +334,52 @@ static void vicon_keytype_draw_wrapper(int x, int y, int w, int h, float alpha, static void vicon_keytype_keyframe_draw(int x, int y, int w, int h, float alpha) { - vicon_keytype_draw_wrapper(x, y, w, h, alpha, BEZT_KEYTYPE_KEYFRAME); + vicon_keytype_draw_wrapper(x, y, w, h, alpha, BEZT_KEYTYPE_KEYFRAME, KEYFRAME_HANDLE_NONE); } static void vicon_keytype_breakdown_draw(int x, int y, int w, int h, float alpha) { - vicon_keytype_draw_wrapper(x, y, w, h, alpha, BEZT_KEYTYPE_BREAKDOWN); + vicon_keytype_draw_wrapper(x, y, w, h, alpha, BEZT_KEYTYPE_BREAKDOWN, KEYFRAME_HANDLE_NONE); } static void vicon_keytype_extreme_draw(int x, int y, int w, int h, float alpha) { - vicon_keytype_draw_wrapper(x, y, w, h, alpha, BEZT_KEYTYPE_EXTREME); + vicon_keytype_draw_wrapper(x, y, w, h, alpha, BEZT_KEYTYPE_EXTREME, KEYFRAME_HANDLE_NONE); } static void vicon_keytype_jitter_draw(int x, int y, int w, int h, float alpha) { - vicon_keytype_draw_wrapper(x, y, w, h, alpha, BEZT_KEYTYPE_JITTER); + vicon_keytype_draw_wrapper(x, y, w, h, alpha, BEZT_KEYTYPE_JITTER, KEYFRAME_HANDLE_NONE); } static void vicon_keytype_moving_hold_draw(int x, int y, int w, int h, float alpha) { - vicon_keytype_draw_wrapper(x, y, w, h, alpha, BEZT_KEYTYPE_MOVEHOLD); + vicon_keytype_draw_wrapper(x, y, w, h, alpha, BEZT_KEYTYPE_MOVEHOLD, KEYFRAME_HANDLE_NONE); +} + +static void vicon_handletype_free_draw(int x, int y, int w, int h, float alpha) +{ + vicon_keytype_draw_wrapper(x, y, w, h, alpha, BEZT_KEYTYPE_KEYFRAME, KEYFRAME_HANDLE_FREE); +} + +static void vicon_handletype_aligned_draw(int x, int y, int w, int h, float alpha) +{ + vicon_keytype_draw_wrapper(x, y, w, h, alpha, BEZT_KEYTYPE_KEYFRAME, KEYFRAME_HANDLE_ALIGNED); +} + +static void vicon_handletype_vector_draw(int x, int y, int w, int h, float alpha) +{ + vicon_keytype_draw_wrapper(x, y, w, h, alpha, BEZT_KEYTYPE_KEYFRAME, KEYFRAME_HANDLE_VECTOR); +} + +static void vicon_handletype_auto_draw(int x, int y, int w, int h, float alpha) +{ + vicon_keytype_draw_wrapper(x, y, w, h, alpha, BEZT_KEYTYPE_KEYFRAME, KEYFRAME_HANDLE_AUTO); +} + +static void vicon_handletype_auto_clamp_draw(int x, int y, int w, int h, float alpha) +{ + vicon_keytype_draw_wrapper(x, y, w, h, alpha, BEZT_KEYTYPE_KEYFRAME, KEYFRAME_HANDLE_AUTO_CLAMP); } static void vicon_colorset_draw(int index, int x, int y, int w, int h, float UNUSED(alpha)) @@ -770,6 +800,12 @@ static void init_internal_icons(void) def_internal_vicon(ICON_KEYTYPE_JITTER_VEC, vicon_keytype_jitter_draw); def_internal_vicon(ICON_KEYTYPE_MOVING_HOLD_VEC, vicon_keytype_moving_hold_draw); + def_internal_vicon(ICON_HANDLETYPE_FREE_VEC, vicon_handletype_free_draw); + def_internal_vicon(ICON_HANDLETYPE_ALIGNED_VEC, vicon_handletype_aligned_draw); + def_internal_vicon(ICON_HANDLETYPE_VECTOR_VEC, vicon_handletype_vector_draw); + def_internal_vicon(ICON_HANDLETYPE_AUTO_VEC, vicon_handletype_auto_draw); + def_internal_vicon(ICON_HANDLETYPE_AUTO_CLAMP_VEC, vicon_handletype_auto_clamp_draw); + def_internal_vicon(ICON_COLORSET_01_VEC, vicon_colorset_draw_01); def_internal_vicon(ICON_COLORSET_02_VEC, vicon_colorset_draw_02); def_internal_vicon(ICON_COLORSET_03_VEC, vicon_colorset_draw_03); diff --git a/source/blender/editors/interface/resources.c b/source/blender/editors/interface/resources.c index 220d7064a5d..0ac534e5fcf 100644 --- a/source/blender/editors/interface/resources.c +++ b/source/blender/editors/interface/resources.c @@ -548,6 +548,9 @@ const unsigned char *UI_ThemeGetColorPtr(bTheme *btheme, int spacetype, int colo case TH_DOPESHEET_CHANNELSUBOB: cp = ts->ds_subchannel; break; + case TH_DOPESHEET_IPOLINE: + cp = ts->ds_ipoline; + break; case TH_PREVIEW_BACK: cp = ts->preview_back; diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index 44c2d3191e6..e570340698f 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -2627,10 +2627,10 @@ static int keyframe_jump_exec(bContext *C, wmOperator *op) } /* populate tree with keyframe nodes */ - scene_to_keylist(&ads, scene, &keys); + scene_to_keylist(&ads, scene, &keys, 0); if (ob) { - ob_to_keylist(&ads, ob, &keys); + ob_to_keylist(&ads, ob, &keys, 0); if (ob->type == OB_GPENCIL) { const bool active = !(scene->flag & SCE_KEYS_NO_SELONLY); diff --git a/source/blender/editors/space_action/action_draw.c b/source/blender/editors/space_action/action_draw.c index 3ea3d067216..ef2694ec70a 100644 --- a/source/blender/editors/space_action/action_draw.c +++ b/source/blender/editors/space_action/action_draw.c @@ -357,28 +357,28 @@ void draw_channel_strips(bAnimContext *ac, SpaceAction *saction, ARegion *ar) /* draw 'keyframes' for each specific datatype */ switch (ale->datatype) { case ALE_ALL: - draw_summary_channel(v2d, ale->data, y, ac->yscale_fac); + draw_summary_channel(v2d, ale->data, y, ac->yscale_fac, saction->flag); break; case ALE_SCE: - draw_scene_channel(v2d, ads, ale->key_data, y, ac->yscale_fac); + draw_scene_channel(v2d, ads, ale->key_data, y, ac->yscale_fac, saction->flag); break; case ALE_OB: - draw_object_channel(v2d, ads, ale->key_data, y, ac->yscale_fac); + draw_object_channel(v2d, ads, ale->key_data, y, ac->yscale_fac, saction->flag); break; case ALE_ACT: - draw_action_channel(v2d, adt, ale->key_data, y, ac->yscale_fac); + draw_action_channel(v2d, adt, ale->key_data, y, ac->yscale_fac, saction->flag); break; case ALE_GROUP: - draw_agroup_channel(v2d, adt, ale->data, y, ac->yscale_fac); + draw_agroup_channel(v2d, adt, ale->data, y, ac->yscale_fac, saction->flag); break; case ALE_FCURVE: - draw_fcurve_channel(v2d, adt, ale->key_data, y, ac->yscale_fac); + draw_fcurve_channel(v2d, adt, ale->key_data, y, ac->yscale_fac, saction->flag); break; case ALE_GPFRAME: - draw_gpl_channel(v2d, ads, ale->data, y, ac->yscale_fac); + draw_gpl_channel(v2d, ads, ale->data, y, ac->yscale_fac, saction->flag); break; case ALE_MASKLAY: - draw_masklay_channel(v2d, ads, ale->data, y, ac->yscale_fac); + draw_masklay_channel(v2d, ads, ale->data, y, ac->yscale_fac, saction->flag); break; } } diff --git a/source/blender/editors/space_action/action_select.c b/source/blender/editors/space_action/action_select.c index 59211ba01d7..c00be5f4c39 100644 --- a/source/blender/editors/space_action/action_select.c +++ b/source/blender/editors/space_action/action_select.c @@ -1449,37 +1449,37 @@ static void mouse_action_keys(bAnimContext *ac, const int mval[2], short select_ case ALE_SCE: { Scene *scene = (Scene *)ale->key_data; - scene_to_keylist(ads, scene, &anim_keys); + scene_to_keylist(ads, scene, &anim_keys, 0); break; } case ALE_OB: { Object *ob = (Object *)ale->key_data; - ob_to_keylist(ads, ob, &anim_keys); + ob_to_keylist(ads, ob, &anim_keys, 0); break; } case ALE_ACT: { bAction *act = (bAction *)ale->key_data; - action_to_keylist(adt, act, &anim_keys); + action_to_keylist(adt, act, &anim_keys, 0); break; } case ALE_FCURVE: { FCurve *fcu = (FCurve *)ale->key_data; - fcurve_to_keylist(adt, fcu, &anim_keys); + fcurve_to_keylist(adt, fcu, &anim_keys, 0); break; } } } else if (ale->type == ANIMTYPE_SUMMARY) { /* dopesheet summary covers everything */ - summary_to_keylist(ac, &anim_keys); + summary_to_keylist(ac, &anim_keys, 0); } else if (ale->type == ANIMTYPE_GROUP) { // TODO: why don't we just give groups key_data too? bActionGroup *agrp = (bActionGroup *)ale->data; - agroup_to_keylist(adt, agrp, &anim_keys); + agroup_to_keylist(adt, agrp, &anim_keys, 0); } else if (ale->type == ANIMTYPE_GPLAYER) { // TODO: why don't we just give gplayers key_data too? diff --git a/source/blender/editors/space_clip/clip_dopesheet_draw.c b/source/blender/editors/space_clip/clip_dopesheet_draw.c index dec7487a754..c05a4c1b64c 100644 --- a/source/blender/editors/space_clip/clip_dopesheet_draw.c +++ b/source/blender/editors/space_clip/clip_dopesheet_draw.c @@ -219,14 +219,17 @@ void clip_draw_dopesheet_main(SpaceClip *sc, ARegion *ar, Scene *scene) uint size_id = GPU_vertformat_attr_add(format, "size", GPU_COMP_F32, 1, GPU_FETCH_FLOAT); uint color_id = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT); uint outline_color_id = GPU_vertformat_attr_add(format, "outlineColor", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT); + uint flags_id = GPU_vertformat_attr_add(format, "flags", GPU_COMP_U32, 1, GPU_FETCH_INT); immBindBuiltinProgram(GPU_SHADER_KEYFRAME_DIAMOND); GPU_enable_program_point_size(); + immUniform2f("ViewportSize", BLI_rcti_size_x(&v2d->mask) + 1, BLI_rcti_size_y(&v2d->mask) + 1); immBegin(GPU_PRIM_POINTS, keyframe_len); /* all same size with black outline */ immAttr1f(size_id, 2.0f * STRIP_HEIGHT_HALF); immAttr4ub(outline_color_id, 0, 0, 0, 255); + immAttr1u(flags_id, 0); y = (float) CHANNEL_FIRST; /* start again at the top */ for (channel = dopesheet->channels.first; channel; channel = channel->next) { diff --git a/source/blender/editors/space_nla/nla_draw.c b/source/blender/editors/space_nla/nla_draw.c index 88f2766a915..15a66b225c9 100644 --- a/source/blender/editors/space_nla/nla_draw.c +++ b/source/blender/editors/space_nla/nla_draw.c @@ -101,12 +101,12 @@ void nla_action_get_color(AnimData *adt, bAction *act, float color[4]) } /* draw the keyframes in the specified Action */ -static void nla_action_draw_keyframes(AnimData *adt, bAction *act, float y, float ymin, float ymax) +static void nla_action_draw_keyframes(View2D *v2d, AnimData *adt, bAction *act, float y, float ymin, float ymax) { /* get a list of the keyframes with NLA-scaling applied */ DLRBT_Tree keys; BLI_dlrbTree_init(&keys); - action_to_keylist(adt, act, &keys); + action_to_keylist(adt, act, &keys, 0); if (ELEM(NULL, act, keys.first)) return; @@ -145,8 +145,10 @@ static void nla_action_draw_keyframes(AnimData *adt, bAction *act, float y, floa uint size_id = GPU_vertformat_attr_add(format, "size", GPU_COMP_F32, 1, GPU_FETCH_FLOAT); uint color_id = GPU_vertformat_attr_add(format, "color", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT); uint outline_color_id = GPU_vertformat_attr_add(format, "outlineColor", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT); + uint flags_id = GPU_vertformat_attr_add(format, "flags", GPU_COMP_U32, 1, GPU_FETCH_INT); immBindBuiltinProgram(GPU_SHADER_KEYFRAME_DIAMOND); GPU_enable_program_point_size(); + immUniform2f("ViewportSize", BLI_rcti_size_x(&v2d->mask) + 1, BLI_rcti_size_y(&v2d->mask) + 1); immBegin(GPU_PRIM_POINTS, key_len); /* - disregard the selection status of keyframes so they draw a certain way @@ -154,7 +156,8 @@ static void nla_action_draw_keyframes(AnimData *adt, bAction *act, float y, floa */ for (ActKeyColumn *ak = keys.first; ak; ak = ak->next) { draw_keyframe_shape(ak->cfra, y, 6.0f, false, ak->key_type, KEYFRAME_SHAPE_FRAME, 1.0f, - pos_id, size_id, color_id, outline_color_id); + pos_id, size_id, color_id, outline_color_id, + flags_id, KEYFRAME_HANDLE_NONE, KEYFRAME_EXTREME_NONE); } immEnd(); @@ -750,7 +753,7 @@ void draw_nla_main_data(bAnimContext *ac, SpaceNla *snla, ARegion *ar) immUnbindProgram(); /* draw keyframes in the action */ - nla_action_draw_keyframes(adt, ale->data, y, yminc + NLACHANNEL_SKIP, ymaxc - NLACHANNEL_SKIP); + nla_action_draw_keyframes(v2d, adt, ale->data, y, yminc + NLACHANNEL_SKIP, ymaxc - NLACHANNEL_SKIP); GPU_blend(false); break; |