From f3b3eb70a6c0576db88115e5b9742295809ca6fd Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Thu, 7 Jul 2016 23:37:15 +1200 Subject: Dopesheet: Added "Moving Hold" as a keyframe type Currently "long keyframes" are only useful for indicating where stationary holds occur. If however you try to create a "moving hold" (where the values are slightly different, but in terms of overall effect, it's still a hold) then it could get tricky to keep track of where these occur. Now it's possible to tag such keyframes (using the keyframe types - RKEY) as being part of a moving hold. These will not only be drawn differently from normal keyframes, but they will also result in a "long keyframe" being drawn between each pair of them, just like if they had been completely stationary instead. Currently the theming/styling of these is a bit rough. They reuse the existing theme colours for long keyframes. --- source/blender/editors/animation/keyframes_draw.c | 107 +++++++++++++++++---- source/blender/editors/animation/keyframes_edit.c | 10 ++ source/blender/editors/include/ED_keyframes_draw.h | 8 +- source/blender/editors/include/UI_icons.h | 1 + source/blender/editors/include/UI_resources.h | 2 + source/blender/editors/interface/interface_icons.c | 6 ++ source/blender/editors/interface/resources.c | 24 +++++ source/blender/makesdna/DNA_curve_types.h | 1 + source/blender/makesrna/intern/rna_fcurve.c | 1 + 9 files changed, 141 insertions(+), 19 deletions(-) (limited to 'source/blender') diff --git a/source/blender/editors/animation/keyframes_draw.c b/source/blender/editors/animation/keyframes_draw.c index 4ec2cb2ba37..6e776953356 100644 --- a/source/blender/editors/animation/keyframes_draw.c +++ b/source/blender/editors/animation/keyframes_draw.c @@ -40,6 +40,7 @@ #include "MEM_guardedalloc.h" #include "BLI_dlrbTree.h" +#include "BLI_math.h" #include "BLI_utildefines.h" #include "DNA_anim_types.h" @@ -282,6 +283,9 @@ static ActKeyBlock *bezts_to_new_actkeyblock(BezTriple *prev, BezTriple *beztn) ab->sel = (BEZT_ISSEL_ANY(prev) || BEZT_ISSEL_ANY(beztn)) ? SELECT : 0; ab->modified = 1; + if (BEZKEYTYPE(beztn) == BEZT_KEYTYPE_MOVEHOLD) + ab->flag |= ACTKEYBLOCK_FLAG_MOVING_HOLD; + return ab; } @@ -305,16 +309,28 @@ static void add_bezt_to_keyblocks_list(DLRBT_Tree *blocks, BezTriple *first_bezt } - /* check if block needed - same value(s)? - * -> firstly, handles must have same central value as each other - * -> secondly, handles which control that section of the curve must be constant - */ + /* check if block needed */ if (prev == NULL) return; - if (IS_EQF(beztn->vec[1][1], prev->vec[1][1]) == 0) return; - - if (IS_EQF(beztn->vec[1][1], beztn->vec[0][1]) == 0) return; - if (IS_EQF(prev->vec[1][1], prev->vec[2][1]) == 0) return; + if (BEZKEYTYPE(beztn) == BEZT_KEYTYPE_MOVEHOLD) { + /* Animator tagged a "moving hold" + * - Previous key must also be tagged as a moving hold, otherwise + * we're just dealing with the first of a pair, and we don't + * want to be creating any phantom holds... + */ + if (BEZKEYTYPE(prev) != BEZT_KEYTYPE_MOVEHOLD) + return; + } + else { + /* Check for same values... + * - Handles must have same central value as each other + * - Handles which control that section of the curve must be constant + */ + if (IS_EQF(beztn->vec[1][1], prev->vec[1][1]) == 0) return; + + if (IS_EQF(beztn->vec[1][1], beztn->vec[0][1]) == 0) return; + if (IS_EQF(prev->vec[1][1], prev->vec[2][1]) == 0) return; + } /* if there are no blocks already, just add as root */ if (blocks->root == NULL) { @@ -340,7 +356,13 @@ static void add_bezt_to_keyblocks_list(DLRBT_Tree *blocks, BezTriple *first_bezt */ if (IS_EQT(ab->start, prev->vec[1][0], BEZT_BINARYSEARCH_THRESH)) { /* set selection status and 'touched' status */ - if (BEZT_ISSEL_ANY(beztn)) ab->sel = SELECT; + if (BEZT_ISSEL_ANY(beztn)) + ab->sel = SELECT; + + /* XXX: only when the first one was a moving hold? */ + if (BEZKEYTYPE(beztn) == BEZT_KEYTYPE_MOVEHOLD) + ab->flag |= ACTKEYBLOCK_FLAG_MOVING_HOLD; + ab->modified++; /* done... no need to insert */ @@ -485,7 +507,27 @@ void draw_keyframe_shape(float x, float y, float xscale, float hsize, short sel, /* tweak size of keyframe shape according to type of keyframe * - 'proper' keyframes have key_type = 0, so get drawn at full size */ - hsize -= 0.5f * key_type; + switch (key_type) { + case BEZT_KEYTYPE_KEYFRAME: /* must be full size */ + break; + + case BEZT_KEYTYPE_BREAKDOWN: /* slightly smaller than normal keyframe */ + hsize *= 0.85f; + break; + + case BEZT_KEYTYPE_MOVEHOLD: /* slightly smaller than normal keyframes (but by less than for breakdowns) */ + //hsize *= 0.72f; + hsize *= 0.95f; + break; + + case BEZT_KEYTYPE_EXTREME: /* slightly larger */ + hsize *= 1.2f; + break; + + default: + hsize -= 0.5f * key_type; + break; + } /* adjust view transform before starting */ glTranslatef(x, y, 0.0f); @@ -518,6 +560,15 @@ void draw_keyframe_shape(float x, float y, float xscale, float hsize, short sel, else UI_GetThemeColor4fv(TH_KEYTYPE_JITTER, inner_col); break; } + case BEZT_KEYTYPE_MOVEHOLD: /* similar to traditional keyframes, but different... */ + { + /* XXX: Should these get their own theme options instead? */ + if (sel) UI_GetThemeColorShade4fv(TH_STRIP_SELECT, 35, inner_col); + else UI_GetThemeColorShade4fv(TH_STRIP, 50, inner_col); + + inner_col[3] = 1.0f; /* full opacity, to avoid problems with visual glitches */ + break; + } case BEZT_KEYTYPE_KEYFRAME: /* traditional yellowish frames (default theme) */ default: { @@ -563,7 +614,10 @@ static void draw_keylist(View2D *v2d, DLRBT_Tree *keys, DLRBT_Tree *blocks, floa ActKeyBlock *ab; float alpha; float xscale; - float iconsize = (U.widget_unit / 4.0f) * yscale_fac; + + const float iconsize = (U.widget_unit / 4.0f) * yscale_fac; + const float mhsize = iconsize * 0.7f; + glEnable(GL_BLEND); /* get View2D scaling factor */ @@ -576,6 +630,7 @@ static void draw_keylist(View2D *v2d, DLRBT_Tree *keys, DLRBT_Tree *blocks, floa /* draw keyblocks */ if (blocks) { float sel_color[4], unsel_color[4]; + float sel_mhcol[4], unsel_mhcol[4]; /* cache colours first */ UI_GetThemeColor4fv(TH_STRIP_SELECT, sel_color); @@ -584,16 +639,32 @@ static void draw_keylist(View2D *v2d, DLRBT_Tree *keys, DLRBT_Tree *blocks, floa sel_color[3] *= alpha; unsel_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; + /* NOTE: the tradeoff for changing colors between each draw is dwarfed by the cost of checking validity */ for (ab = blocks->first; ab; ab = ab->next) { if (actkeyblock_is_valid(ab, keys)) { - /* draw block */ - if (ab->sel) - glColor4fv(sel_color); - else - glColor4fv(unsel_color); - - glRectf(ab->start, ypos - iconsize, ab->end, ypos + iconsize); + if (ab->flag & ACTKEYBLOCK_FLAG_MOVING_HOLD) { + /* draw "moving hold" long-keyframe block - slightly smaller */ + if (ab->sel) + glColor4fv(sel_mhcol); + else + glColor4fv(unsel_mhcol); + + glRectf(ab->start, ypos - mhsize, ab->end, ypos + mhsize); + } + else { + /* draw standard long-keyframe block */ + if (ab->sel) + glColor4fv(sel_color); + else + glColor4fv(unsel_color); + + glRectf(ab->start, ypos - iconsize, ab->end, ypos + iconsize); + } } } } diff --git a/source/blender/editors/animation/keyframes_edit.c b/source/blender/editors/animation/keyframes_edit.c index 7b35a154fc8..4571df0f077 100644 --- a/source/blender/editors/animation/keyframes_edit.c +++ b/source/blender/editors/animation/keyframes_edit.c @@ -1208,6 +1208,13 @@ static short set_keytype_jitter(KeyframeEditData *UNUSED(ked), BezTriple *bezt) return 0; } +static short set_keytype_moving_hold(KeyframeEditData *UNUSED(ked), BezTriple *bezt) +{ + if (bezt->f2 & SELECT) + BEZKEYTYPE(bezt) = BEZT_KEYTYPE_MOVEHOLD; + return 0; +} + /* Set the interpolation type of the selected BezTriples in each F-Curve to the specified one */ KeyframeEditFunc ANIM_editkeyframes_keytype(short code) { @@ -1221,6 +1228,9 @@ KeyframeEditFunc ANIM_editkeyframes_keytype(short code) case BEZT_KEYTYPE_JITTER: /* jitter keyframe */ return set_keytype_jitter; + case BEZT_KEYTYPE_MOVEHOLD: /* moving hold */ + return set_keytype_moving_hold; + case BEZT_KEYTYPE_KEYFRAME: /* proper keyframe */ default: return set_keytype_keyframe; diff --git a/source/blender/editors/include/ED_keyframes_draw.h b/source/blender/editors/include/ED_keyframes_draw.h index 43264a6edaa..b1f3f012e09 100644 --- a/source/blender/editors/include/ED_keyframes_draw.h +++ b/source/blender/editors/include/ED_keyframes_draw.h @@ -80,7 +80,7 @@ typedef struct ActKeyBlock { /* key-block info */ char sel; - short handle_type; + short flag; float val; float start, end; @@ -89,6 +89,12 @@ typedef struct ActKeyBlock { short totcurve; } ActKeyBlock; +/* ActKeyBlock - Flag */ +typedef enum eActKeyBlock_Flag { + /* Key block represents a moving hold */ + ACTKEYBLOCK_FLAG_MOVING_HOLD = (1 << 0), +} eActKeyBlock_Flag; + /* *********************** Keyframe Drawing ****************************** */ /* options for keyframe shape drawing */ diff --git a/source/blender/editors/include/UI_icons.h b/source/blender/editors/include/UI_icons.h index 2c80701bf69..d85b60dcc43 100644 --- a/source/blender/editors/include/UI_icons.h +++ b/source/blender/editors/include/UI_icons.h @@ -1020,6 +1020,7 @@ DEF_VICO(KEYTYPE_KEYFRAME_VEC) DEF_VICO(KEYTYPE_BREAKDOWN_VEC) DEF_VICO(KEYTYPE_EXTREME_VEC) DEF_VICO(KEYTYPE_JITTER_VEC) +DEF_VICO(KEYTYPE_MOVING_HOLD_VEC) DEF_VICO(COLORSET_01_VEC) DEF_VICO(COLORSET_02_VEC) diff --git a/source/blender/editors/include/UI_resources.h b/source/blender/editors/include/UI_resources.h index dc843952229..a81221ed54b 100644 --- a/source/blender/editors/include/UI_resources.h +++ b/source/blender/editors/include/UI_resources.h @@ -347,6 +347,8 @@ void UI_GetThemeColorShade3ubv(int colorid, int offset, unsigned char col[3]) // get four color values, scaled to 0.0-1.0 range void UI_GetThemeColor4fv(int colorid, float col[4]); +// get four color values, range 0.0-1.0, complete with shading offset for the RGB components +void UI_GetThemeColorShade4fv(int colorid, int offset, float col[4]); // get the 3 or 4 byte values void UI_GetThemeColor3ubv(int colorid, unsigned char col[3]); diff --git a/source/blender/editors/interface/interface_icons.c b/source/blender/editors/interface/interface_icons.c index 6dc60f1d70b..e00d8cf7c07 100644 --- a/source/blender/editors/interface/interface_icons.c +++ b/source/blender/editors/interface/interface_icons.c @@ -505,6 +505,11 @@ 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); } +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); +} + static void vicon_colorset_draw(int index, int x, int y, int w, int h, float UNUSED(alpha)) { bTheme *btheme = UI_GetTheme(); @@ -792,6 +797,7 @@ static void init_internal_icons(void) def_internal_vicon(VICO_KEYTYPE_BREAKDOWN_VEC, vicon_keytype_breakdown_draw); def_internal_vicon(VICO_KEYTYPE_EXTREME_VEC, vicon_keytype_extreme_draw); def_internal_vicon(VICO_KEYTYPE_JITTER_VEC, vicon_keytype_jitter_draw); + def_internal_vicon(VICO_KEYTYPE_MOVING_HOLD_VEC, vicon_keytype_moving_hold_draw); def_internal_vicon(VICO_COLORSET_01_VEC, vicon_colorset_draw_01); def_internal_vicon(VICO_COLORSET_02_VEC, vicon_colorset_draw_02); diff --git a/source/blender/editors/interface/resources.c b/source/blender/editors/interface/resources.c index a9607d93672..c8ff335f2a0 100644 --- a/source/blender/editors/interface/resources.c +++ b/source/blender/editors/interface/resources.c @@ -1473,6 +1473,30 @@ void UI_GetThemeColor3ubv(int colorid, unsigned char col[3]) col[2] = cp[2]; } +/* get the color, range 0.0-1.0, complete with shading offset */ +void UI_GetThemeColorShade4fv(int colorid, int offset, float col[4]) +{ + int r, g, b, a; + const unsigned char *cp; + + cp = UI_ThemeGetColorPtr(theme_active, theme_spacetype, colorid); + + r = offset + (int) cp[0]; + CLAMP(r, 0, 255); + g = offset + (int) cp[1]; + CLAMP(g, 0, 255); + b = offset + (int) cp[2]; + CLAMP(b, 0, 255); + + a = (int) cp[3]; /* no shading offset... */ + CLAMP(a, 0, 255); + + col[0] = ((float)r) / 255.0f; + col[1] = ((float)g) / 255.0f; + col[2] = ((float)b) / 255.0f; + col[3] = ((float)a) / 255.0f; +} + /* get the color, in char pointer */ void UI_GetThemeColor4ubv(int colorid, unsigned char col[4]) { diff --git a/source/blender/makesdna/DNA_curve_types.h b/source/blender/makesdna/DNA_curve_types.h index 61169e4b1b1..902fa4ce987 100644 --- a/source/blender/makesdna/DNA_curve_types.h +++ b/source/blender/makesdna/DNA_curve_types.h @@ -424,6 +424,7 @@ typedef enum eBezTriple_KeyframeType { BEZT_KEYTYPE_EXTREME = 1, /* 'extreme' keyframe */ BEZT_KEYTYPE_BREAKDOWN = 2, /* 'breakdown' keyframe */ BEZT_KEYTYPE_JITTER = 3, /* 'jitter' keyframe (for adding 'filler' secondary motion) */ + BEZT_KEYTYPE_MOVEHOLD = 4, /* one end of a 'moving hold' */ } eBezTriple_KeyframeType; /* checks if the given BezTriple is selected */ diff --git a/source/blender/makesrna/intern/rna_fcurve.c b/source/blender/makesrna/intern/rna_fcurve.c index 3043c5452c0..5fb581eb74a 100644 --- a/source/blender/makesrna/intern/rna_fcurve.c +++ b/source/blender/makesrna/intern/rna_fcurve.c @@ -72,6 +72,7 @@ EnumPropertyItem rna_enum_fmodifier_type_items[] = { EnumPropertyItem rna_enum_beztriple_keyframe_type_items[] = { {BEZT_KEYTYPE_KEYFRAME, "KEYFRAME", VICO_KEYTYPE_KEYFRAME_VEC, "Keyframe", "Normal keyframe - e.g. for key poses"}, {BEZT_KEYTYPE_BREAKDOWN, "BREAKDOWN", VICO_KEYTYPE_BREAKDOWN_VEC, "Breakdown", "A breakdown pose - e.g. for transitions between key poses"}, + {BEZT_KEYTYPE_MOVEHOLD, "MOVING_HOLD", VICO_KEYTYPE_MOVING_HOLD_VEC, "Moving Hold", "A keyframe that is part of a moving hold"}, {BEZT_KEYTYPE_EXTREME, "EXTREME", VICO_KEYTYPE_EXTREME_VEC, "Extreme", "An 'extreme' pose, or some other purpose as needed"}, {BEZT_KEYTYPE_JITTER, "JITTER", VICO_KEYTYPE_JITTER_VEC, "Jitter", "A filler or baked keyframe for keying on ones, or some other purpose as needed"}, {0, NULL, 0, NULL, NULL} -- cgit v1.2.3