Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/animation/keyframes_keylist.c
- This file was copied from source/blender/editors/animation/keyframes_draw.c.
| Show All 26 Lines | |||||
| #include <math.h> | #include <math.h> | ||||
| #include <stdlib.h> | #include <stdlib.h> | ||||
| #include <string.h> | #include <string.h> | ||||
| #include "MEM_guardedalloc.h" | #include "MEM_guardedalloc.h" | ||||
| #include "BLI_dlrbTree.h" | #include "BLI_dlrbTree.h" | ||||
| #include "BLI_listbase.h" | #include "BLI_listbase.h" | ||||
| #include "BLI_math.h" | |||||
| #include "BLI_rect.h" | |||||
| #include "BLI_utildefines.h" | #include "BLI_utildefines.h" | ||||
| #include "DNA_anim_types.h" | #include "DNA_anim_types.h" | ||||
| #include "DNA_brush_types.h" | |||||
| #include "DNA_cachefile_types.h" | #include "DNA_cachefile_types.h" | ||||
| #include "DNA_gpencil_types.h" | #include "DNA_gpencil_types.h" | ||||
| #include "DNA_mask_types.h" | #include "DNA_mask_types.h" | ||||
| #include "DNA_object_types.h" | #include "DNA_object_types.h" | ||||
| #include "DNA_scene_types.h" | #include "DNA_scene_types.h" | ||||
| #include "BKE_fcurve.h" | #include "BKE_fcurve.h" | ||||
| #include "GPU_immediate.h" | |||||
| #include "GPU_state.h" | |||||
| #include "UI_interface.h" | |||||
| #include "UI_resources.h" | |||||
| #include "UI_view2d.h" | |||||
| #include "ED_anim_api.h" | #include "ED_anim_api.h" | ||||
| #include "ED_keyframes_draw.h" | #include "ED_keyframes_keylist.h" | ||||
| /* *************************** Keyframe Processing *************************** */ | /* *************************** Keyframe Processing *************************** */ | ||||
| /* ActKeyColumns (Keyframe Columns) ------------------------------------------ */ | /* ActKeyColumns (Keyframe Columns) ------------------------------------------ */ | ||||
| BLI_INLINE bool is_cfra_eq(float a, float b) | BLI_INLINE bool is_cfra_eq(float a, float b) | ||||
| { | { | ||||
| return IS_EQT(a, b, BEZT_BINARYSEARCH_THRESH); | return IS_EQT(a, b, BEZT_BINARYSEARCH_THRESH); | ||||
| ▲ Show 20 Lines • Show All 477 Lines • ▼ Show 20 Lines | int actkeyblock_get_valid_hold(ActKeyColumn *ac) | ||||
| if (!actkeyblock_is_valid(ac)) { | if (!actkeyblock_is_valid(ac)) { | ||||
| return 0; | return 0; | ||||
| } | } | ||||
| const int hold_mask = (ACTKEYBLOCK_FLAG_ANY_HOLD | ACTKEYBLOCK_FLAG_STATIC_HOLD); | const int hold_mask = (ACTKEYBLOCK_FLAG_ANY_HOLD | ACTKEYBLOCK_FLAG_STATIC_HOLD); | ||||
| return (ac->block.flag & ~ac->block.conflict) & hold_mask; | return (ac->block.flag & ~ac->block.conflict) & hold_mask; | ||||
| } | } | ||||
| /* *************************** Keyframe Drawing *************************** */ | |||||
| void draw_keyframe_shape(float x, | |||||
| float y, | |||||
| float size, | |||||
| bool sel, | |||||
| short key_type, | |||||
| short mode, | |||||
| float alpha, | |||||
| uint pos_id, | |||||
| uint size_id, | |||||
| uint color_id, | |||||
| uint outline_color_id, | |||||
| uint 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); | |||||
| BLI_assert(draw_fill || draw_outline); | |||||
| /* tweak size of keyframe shape according to type of keyframe | |||||
| * - 'proper' keyframes have key_type = 0, so get drawn at full size | |||||
| */ | |||||
| switch (key_type) { | |||||
| case BEZT_KEYTYPE_KEYFRAME: /* must be full size */ | |||||
| break; | |||||
| case BEZT_KEYTYPE_BREAKDOWN: /* slightly smaller than normal keyframe */ | |||||
| size *= 0.85f; | |||||
| break; | |||||
| case BEZT_KEYTYPE_MOVEHOLD: /* Slightly smaller than normal keyframes | |||||
| * (but by less than for breakdowns). */ | |||||
| size *= 0.925f; | |||||
| break; | |||||
| case BEZT_KEYTYPE_EXTREME: /* slightly larger */ | |||||
| size *= 1.2f; | |||||
| break; | |||||
| default: | |||||
| size -= 0.8f * key_type; | |||||
| } | |||||
| uchar fill_col[4]; | |||||
| uchar outline_col[4]; | |||||
| uint flags = 0; | |||||
| /* draw! */ | |||||
| if (draw_fill) { | |||||
| /* get interior colors from theme (for selected and unselected only) */ | |||||
| switch (key_type) { | |||||
| case BEZT_KEYTYPE_BREAKDOWN: /* bluish frames (default theme) */ | |||||
| UI_GetThemeColor4ubv(sel ? TH_KEYTYPE_BREAKDOWN_SELECT : TH_KEYTYPE_BREAKDOWN, fill_col); | |||||
| break; | |||||
| case BEZT_KEYTYPE_EXTREME: /* reddish frames (default theme) */ | |||||
| UI_GetThemeColor4ubv(sel ? TH_KEYTYPE_EXTREME_SELECT : TH_KEYTYPE_EXTREME, fill_col); | |||||
| break; | |||||
| case BEZT_KEYTYPE_JITTER: /* greenish frames (default theme) */ | |||||
| UI_GetThemeColor4ubv(sel ? TH_KEYTYPE_JITTER_SELECT : TH_KEYTYPE_JITTER, fill_col); | |||||
| break; | |||||
| case BEZT_KEYTYPE_MOVEHOLD: /* similar to traditional keyframes, but different... */ | |||||
| UI_GetThemeColor4ubv(sel ? TH_KEYTYPE_MOVEHOLD_SELECT : TH_KEYTYPE_MOVEHOLD, fill_col); | |||||
| break; | |||||
| case BEZT_KEYTYPE_KEYFRAME: /* traditional yellowish frames (default theme) */ | |||||
| default: | |||||
| UI_GetThemeColor4ubv(sel ? TH_KEYTYPE_KEYFRAME_SELECT : TH_KEYTYPE_KEYFRAME, fill_col); | |||||
| } | |||||
| /* NOTE: we don't use the straight alpha from the theme, or else effects such as | |||||
| * graying out protected/muted channels doesn't work correctly! | |||||
| */ | |||||
| fill_col[3] *= alpha; | |||||
| if (!draw_outline) { | |||||
| /* force outline color to match */ | |||||
| outline_col[0] = fill_col[0]; | |||||
| outline_col[1] = fill_col[1]; | |||||
| outline_col[2] = fill_col[2]; | |||||
| outline_col[3] = fill_col[3]; | |||||
| } | |||||
| } | |||||
| if (draw_outline) { | |||||
| /* exterior - black frame */ | |||||
| UI_GetThemeColor4ubv(sel ? TH_KEYBORDER_SELECT : TH_KEYBORDER, outline_col); | |||||
| outline_col[3] *= alpha; | |||||
| if (!draw_fill) { | |||||
| /* fill color needs to be (outline.rgb, 0) */ | |||||
| fill_col[0] = outline_col[0]; | |||||
| fill_col[1] = outline_col[1]; | |||||
| 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, | |||||
| int saction_flag) | |||||
| { | |||||
| if (keys == NULL) { | |||||
| return; | |||||
| } | |||||
| 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; | |||||
| const float gpencil_sz = smaller_sz * 0.8f; | |||||
| const float screenspace_margin = (0.35f * (float)UI_UNIT_X) / UI_view2d_scale_get_x(v2d); | |||||
| /* locked channels are less strongly shown, as feedback for locked channels in DopeSheet */ | |||||
| /* 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 */ | |||||
| float sel_color[4], unsel_color[4]; | |||||
| float sel_mhcol[4], unsel_mhcol[4]; | |||||
| float ipo_color[4], ipo_color_mix[4]; | |||||
| /* cache colors 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; | |||||
| LISTBASE_FOREACH (ActKeyColumn *, ab, keys) { | |||||
| /* Draw grease pencil bars between keyframes. */ | |||||
| if ((ab->next != NULL) && (ab->block.flag & ACTKEYBLOCK_FLAG_GPENCIL)) { | |||||
| UI_draw_roundbox_corner_set(UI_CNR_TOP_RIGHT | UI_CNR_BOTTOM_RIGHT); | |||||
| float size = 1.0f; | |||||
| switch (ab->next->key_type) { | |||||
| case BEZT_KEYTYPE_BREAKDOWN: | |||||
| case BEZT_KEYTYPE_MOVEHOLD: | |||||
| case BEZT_KEYTYPE_JITTER: | |||||
| size *= 0.5f; | |||||
| break; | |||||
| case BEZT_KEYTYPE_KEYFRAME: | |||||
| size *= 0.8f; | |||||
| break; | |||||
| default: | |||||
| break; | |||||
| } | |||||
| UI_draw_roundbox_4fv( | |||||
| &(const rctf){ | |||||
| .xmin = ab->cfra, | |||||
| .xmax = min_ff(ab->next->cfra - (screenspace_margin * size), ab->next->cfra), | |||||
| .ymin = ypos - gpencil_sz, | |||||
| .ymax = ypos + gpencil_sz, | |||||
| }, | |||||
| true, | |||||
| 0.25f * (float)UI_UNIT_X, | |||||
| (ab->block.sel) ? sel_mhcol : unsel_mhcol); | |||||
| } | |||||
| else { | |||||
| /* Draw other types. */ | |||||
| UI_draw_roundbox_corner_set(UI_CNR_NONE); | |||||
| int valid_hold = actkeyblock_get_valid_hold(ab); | |||||
| if (valid_hold != 0) { | |||||
| if ((valid_hold & ACTKEYBLOCK_FLAG_STATIC_HOLD) == 0) { | |||||
| /* draw "moving hold" long-keyframe block - slightly smaller */ | |||||
| UI_draw_roundbox_4fv( | |||||
| &(const rctf){ | |||||
| .xmin = ab->cfra, | |||||
| .xmax = ab->next->cfra, | |||||
| .ymin = ypos - smaller_sz, | |||||
| .ymax = ypos + smaller_sz, | |||||
| }, | |||||
| true, | |||||
| 3.0f, | |||||
| (ab->block.sel) ? sel_mhcol : unsel_mhcol); | |||||
| } | |||||
| else { | |||||
| /* draw standard long-keyframe block */ | |||||
| UI_draw_roundbox_4fv( | |||||
| &(const rctf){ | |||||
| .xmin = ab->cfra, | |||||
| .xmax = ab->next->cfra, | |||||
| .ymin = ypos - half_icon_sz, | |||||
| .ymax = ypos + half_icon_sz, | |||||
| }, | |||||
| true, | |||||
| 3.0f, | |||||
| (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 */ | |||||
| UI_draw_roundbox_4fv( | |||||
| &(const rctf){ | |||||
| .xmin = ab->cfra, | |||||
| .xmax = ab->next->cfra, | |||||
| .ymin = ypos - ipo_sz, | |||||
| .ymax = ypos + ipo_sz, | |||||
| }, | |||||
| true, | |||||
| 3.0f, | |||||
| (ab->block.conflict & ACTKEYBLOCK_FLAG_NON_BEZIER) ? ipo_color_mix : ipo_color); | |||||
| } | |||||
| } | |||||
| } | |||||
| GPU_blend(GPU_BLEND_ALPHA); | |||||
| /* count keys */ | |||||
| uint key_len = 0; | |||||
| LISTBASE_FOREACH (ActKeyColumn *, ak, keys) { | |||||
| /* Optimization: if keyframe doesn't appear within 5 units (screenspace) | |||||
| * in visible area, don't draw. | |||||
| * This might give some improvements, | |||||
| * since we current have to flip between view/region matrices. | |||||
| */ | |||||
| if (IN_RANGE_INCL(ak->cfra, v2d->cur.xmin, v2d->cur.xmax)) { | |||||
| key_len++; | |||||
| } | |||||
| } | |||||
| if (key_len > 0) { | |||||
| /* draw keys */ | |||||
| 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); | |||||
| GPU_program_point_size(true); | |||||
| immBindBuiltinProgram(GPU_SHADER_KEYFRAME_DIAMOND); | |||||
| immUniform1f("outline_scale", 1.0f); | |||||
| 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; | |||||
| LISTBASE_FOREACH (ActKeyColumn *, ak, keys) { | |||||
| 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, | |||||
| flags_id, | |||||
| handle_type, | |||||
| extreme_type); | |||||
| } | |||||
| } | |||||
| immEnd(); | |||||
| GPU_program_point_size(false); | |||||
| immUnbindProgram(); | |||||
| } | |||||
| GPU_blend(GPU_BLEND_NONE); | |||||
| } | |||||
| /* *************************** Channel Drawing Funcs *************************** */ | |||||
| 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, saction_flag); | |||||
| 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, int saction_flag) | |||||
| { | |||||
| DLRBT_Tree keys; | |||||
| saction_flag &= ~SACTION_SHOW_EXTREMES; | |||||
| BLI_dlrbTree_init(&keys); | |||||
| scene_to_keylist(ads, sce, &keys, saction_flag); | |||||
| 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, int saction_flag) | |||||
| { | |||||
| DLRBT_Tree keys; | |||||
| saction_flag &= ~SACTION_SHOW_EXTREMES; | |||||
| BLI_dlrbTree_init(&keys); | |||||
| ob_to_keylist(ads, ob, &keys, saction_flag); | |||||
| 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, int saction_flag) | |||||
| { | |||||
| DLRBT_Tree keys; | |||||
| bool locked = (fcu->flag & FCURVE_PROTECTED) || | |||||
| ((fcu->grp) && (fcu->grp->flag & AGRP_PROTECTED)) || | |||||
| ((adt && adt->action) && ID_IS_LINKED(adt->action)); | |||||
| BLI_dlrbTree_init(&keys); | |||||
| fcurve_to_keylist(adt, fcu, &keys, saction_flag); | |||||
| 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, int saction_flag) | |||||
| { | |||||
| DLRBT_Tree keys; | |||||
| bool locked = (agrp->flag & AGRP_PROTECTED) || | |||||
| ((adt && adt->action) && ID_IS_LINKED(adt->action)); | |||||
| BLI_dlrbTree_init(&keys); | |||||
| agroup_to_keylist(adt, agrp, &keys, saction_flag); | |||||
| 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, 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, saction_flag); | |||||
| 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, 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, saction_flag); | |||||
| BLI_dlrbTree_free(&keys); | |||||
| } | |||||
| void draw_gpl_channel( | |||||
| View2D *v2d, bDopeSheet *ads, bGPDlayer *gpl, float ypos, float yscale_fac, int saction_flag) | |||||
| { | |||||
| DLRBT_Tree keys; | |||||
| bool locked = (gpl->flag & GP_LAYER_LOCKED) != 0; | |||||
| BLI_dlrbTree_init(&keys); | |||||
| gpl_to_keylist(ads, gpl, &keys); | |||||
| 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, | |||||
| int saction_flag) | |||||
| { | |||||
| DLRBT_Tree keys; | |||||
| bool locked = (masklay->flag & MASK_LAYERFLAG_LOCKED) != 0; | |||||
| BLI_dlrbTree_init(&keys); | |||||
| mask_to_keylist(ads, masklay, &keys); | |||||
| draw_keylist(v2d, &keys, ypos, yscale_fac, locked, saction_flag); | |||||
| BLI_dlrbTree_free(&keys); | |||||
| } | |||||
| /* *************************** Keyframe List Conversions *************************** */ | /* *************************** Keyframe List Conversions *************************** */ | ||||
| void summary_to_keylist(bAnimContext *ac, DLRBT_Tree *keys, int saction_flag) | void summary_to_keylist(bAnimContext *ac, DLRBT_Tree *keys, int saction_flag) | ||||
| { | { | ||||
| if (ac) { | if (ac) { | ||||
| ListBase anim_data = {NULL, NULL}; | ListBase anim_data = {NULL, NULL}; | ||||
| bAnimListElem *ale; | bAnimListElem *ale; | ||||
| int filter; | int filter; | ||||
| ▲ Show 20 Lines • Show All 245 Lines • Show Last 20 Lines | |||||