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.
This commit is contained in:
parent
2ba2860e11
commit
f3b3eb70a6
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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]);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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])
|
||||
{
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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}
|
||||
|
|
Loading…
Reference in New Issue