Changeset View
Standalone View
source/blender/editors/space_graph/graph_draw.c
| Show All 29 Lines | |||||
| #include "BLI_utildefines.h" | #include "BLI_utildefines.h" | ||||
| #include "DNA_anim_types.h" | #include "DNA_anim_types.h" | ||||
| #include "DNA_screen_types.h" | #include "DNA_screen_types.h" | ||||
| #include "DNA_space_types.h" | #include "DNA_space_types.h" | ||||
| #include "DNA_userdef_types.h" | #include "DNA_userdef_types.h" | ||||
| #include "DNA_windowmanager_types.h" | #include "DNA_windowmanager_types.h" | ||||
| #include "BKE_anim_data.h" | |||||
| #include "BKE_context.h" | #include "BKE_context.h" | ||||
| #include "BKE_curve.h" | #include "BKE_curve.h" | ||||
| #include "BKE_fcurve.h" | #include "BKE_fcurve.h" | ||||
| #include "BKE_nla.h" | |||||
| #include "GPU_immediate.h" | #include "GPU_immediate.h" | ||||
| #include "GPU_matrix.h" | #include "GPU_matrix.h" | ||||
| #include "GPU_state.h" | #include "GPU_state.h" | ||||
| #include "ED_anim_api.h" | #include "ED_anim_api.h" | ||||
| #include "graph_intern.h" | #include "graph_intern.h" | ||||
| Show All 23 Lines | |||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| /** \name FCurve Modifier Drawing | /** \name FCurve Modifier Drawing | ||||
| * | * | ||||
| * \{ */ | * \{ */ | ||||
| /* Envelope -------------- */ | /* Envelope -------------- */ | ||||
| /* TODO: draw a shaded poly showing the region of influence too!!! */ | /* TODO: draw a shaded poly showing the region of influence too!!! */ | ||||
| static void draw_fcurve_modifier_controls_envelope(FModifier *fcm, View2D *v2d) | /** | ||||
| * \param adt_nla_remap: Send NULL if no NLA remapping necessary. | |||||
| */ | |||||
| static void draw_fcurve_modifier_controls_envelope(FModifier *fcm, | |||||
| View2D *v2d, | |||||
| AnimData *adt_nla_remap) | |||||
| { | { | ||||
| FMod_Envelope *env = (FMod_Envelope *)fcm->data; | FMod_Envelope *env = (FMod_Envelope *)fcm->data; | ||||
| FCM_EnvelopeData *fed; | FCM_EnvelopeData *fed; | ||||
| const float fac = 0.05f * BLI_rctf_size_x(&v2d->cur); | const float fac = 0.05f * BLI_rctf_size_x(&v2d->cur); | ||||
| int i; | int i; | ||||
| const uint shdr_pos = GPU_vertformat_attr_add( | const uint shdr_pos = GPU_vertformat_attr_add( | ||||
| immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); | immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); | ||||
| Show All 30 Lines | if (env->totvert > 0) { | ||||
| immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); | immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); | ||||
| /* for now, point color is fixed, and is white */ | /* for now, point color is fixed, and is white */ | ||||
| immUniformColor3f(1.0f, 1.0f, 1.0f); | immUniformColor3f(1.0f, 1.0f, 1.0f); | ||||
| immBeginAtMost(GPU_PRIM_POINTS, env->totvert * 2); | immBeginAtMost(GPU_PRIM_POINTS, env->totvert * 2); | ||||
| for (i = 0, fed = env->data; i < env->totvert; i++, fed++) { | for (i = 0, fed = env->data; i < env->totvert; i++, fed++) { | ||||
| const float env_scene_time = BKE_nla_tweakedit_remap( | |||||
| adt_nla_remap, fed->time, NLATIME_CONVERT_MAP); | |||||
| /* only draw if visible | /* only draw if visible | ||||
| * - min/max here are fixed, not relative | * - min/max here are fixed, not relative | ||||
| */ | */ | ||||
| if (IN_RANGE(fed->time, (v2d->cur.xmin - fac), (v2d->cur.xmax + fac))) { | if (IN_RANGE(env_scene_time, (v2d->cur.xmin - fac), (v2d->cur.xmax + fac))) { | ||||
| immVertex2f(shdr_pos, fed->time, fed->min); | immVertex2f(shdr_pos, env_scene_time, fed->min); | ||||
| immVertex2f(shdr_pos, fed->time, fed->max); | immVertex2f(shdr_pos, env_scene_time, fed->max); | ||||
| } | } | ||||
| } | } | ||||
| immEnd(); | immEnd(); | ||||
| immUnbindProgram(); | immUnbindProgram(); | ||||
| } | } | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 426 Lines • ▼ Show 20 Lines | if (first && last) { | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| /* Curve ---------------- */ | /* Curve ---------------- */ | ||||
| /* Helper func - just draw the F-Curve by sampling the visible region | /* Helper func - just draw the F-Curve by sampling the visible region | ||||
| * (for drawing curves with modifiers). */ | * (for drawing curves with modifiers). */ | ||||
| static void draw_fcurve_curve(bAnimContext *ac, ID *id, FCurve *fcu_, View2D *v2d, uint pos) | static void draw_fcurve_curve( | ||||
| bAnimContext *ac, ID *id, FCurve *fcu_, View2D *v2d, uint pos, const bool use_nla_remap) | |||||
sybren: `use_nla_remap` can be `const` | |||||
| { | { | ||||
| SpaceGraph *sipo = (SpaceGraph *)ac->sl; | SpaceGraph *sipo = (SpaceGraph *)ac->sl; | ||||
| short mapping_flag = ANIM_get_normalization_flags(ac); | short mapping_flag = ANIM_get_normalization_flags(ac); | ||||
| /* when opening a blend file on a different sized screen or while dragging the toolbar this can | /* when opening a blend file on a different sized screen or while dragging the toolbar this can | ||||
| * happen best just bail out in this case. */ | * happen best just bail out in this case. */ | ||||
| if (UI_view2d_scale_get_x(v2d) <= 0.0f) { | if (UI_view2d_scale_get_x(v2d) <= 0.0f) { | ||||
| return; | return; | ||||
| ▲ Show 20 Lines • Show All 57 Lines • ▼ Show 20 Lines | static void draw_fcurve_curve( | ||||
| * the displayed values appear correctly in the viewport | * the displayed values appear correctly in the viewport | ||||
| */ | */ | ||||
| int n = roundf((etime - stime) / samplefreq); | int n = roundf((etime - stime) / samplefreq); | ||||
| if (n > 0) { | if (n > 0) { | ||||
| immBegin(GPU_PRIM_LINE_STRIP, (n + 1)); | immBegin(GPU_PRIM_LINE_STRIP, (n + 1)); | ||||
| AnimData *adt = use_nla_remap ? BKE_animdata_from_id(id) : NULL; | |||||
| /* NLA remapping is linear so we don't have to remap per iteration. */ | |||||
| const float eval_start = BKE_nla_tweakedit_remap(adt, stime, NLATIME_CONVERT_UNMAP); | |||||
| const float eval_freq = BKE_nla_tweakedit_remap( | |||||
Done Inline Actionseval_start and eval_freq can be const sybren: `eval_start` and `eval_freq` can be const | |||||
| adt, stime + samplefreq, NLATIME_CONVERT_UNMAP) - | |||||
| eval_start; | |||||
| for (int i = 0; i <= n; i++) { | for (int i = 0; i <= n; i++) { | ||||
| float ctime = stime + i * samplefreq; | float ctime = stime + i * samplefreq; | ||||
| immVertex2f(pos, ctime, (evaluate_fcurve(&fcurve_for_draw, ctime) + offset) * unitFac); | const float eval_time = eval_start + i * eval_freq; | ||||
| immVertex2f(pos, ctime, (evaluate_fcurve(&fcurve_for_draw, eval_time) + offset) * unitFac); | |||||
Done Inline Actionseval_time can be const sybren: `eval_time` can be `const` | |||||
| } | } | ||||
| immEnd(); | immEnd(); | ||||
| } | } | ||||
| } | } | ||||
| /* helper func - draw a samples-based F-Curve */ | /* helper func - draw a samples-based F-Curve */ | ||||
| static void draw_fcurve_curve_samples( | static void draw_fcurve_curve_samples( | ||||
| ▲ Show 20 Lines • Show All 350 Lines • ▼ Show 20 Lines | else { | ||||
| immUniformColor3fvAlpha(fcu->color, fcurve_display_alpha(fcu)); | immUniformColor3fvAlpha(fcu->color, fcurve_display_alpha(fcu)); | ||||
| } | } | ||||
| /* draw F-Curve */ | /* draw F-Curve */ | ||||
| if ((fcu->modifiers.first) || (fcu->flag & FCURVE_INT_VALUES)) { | if ((fcu->modifiers.first) || (fcu->flag & FCURVE_INT_VALUES)) { | ||||
| /* draw a curve affected by modifiers or only allowed to have integer values | /* draw a curve affected by modifiers or only allowed to have integer values | ||||
| * by sampling it at various small-intervals over the visible region | * by sampling it at various small-intervals over the visible region | ||||
| */ | */ | ||||
| draw_fcurve_curve(ac, ale->id, fcu, ®ion->v2d, shdr_pos); | if (adt) { | ||||
| /** We have to do this mapping dance since the keyframes were remapped but the Fmodifier | |||||
| * evaluations are not. | |||||
Done Inline Actions2x "instead" makes this a bit more confusing than it is. sybren: 2x "instead" makes this a bit more confusing than it is. | |||||
| * | |||||
Not Done Inline ActionsWhat is the reason that you did the unmap-eval-remap here? Wouldn't it be more correct to make the FCurve Modifier evaluation NLA-aware? If so, maybe add a TODO here that indicates that. If this really is the best solution, remove the XXX as it has little meaning then. sybren: What is the reason that you did the unmap-eval-remap here? Wouldn't it be more correct to make… | |||||
Done Inline ActionsThen all evaluate_fcurve() calls would require passing an additional fmodifier_eval_time whenever we remap the fcurve. Keyframes and fmodifiers would be in different time spaces which seems unnecessarily complicated. The current code-base generally uses BKE_nla_tweakedit_remap() when working with both keys and fmodifiers. GuiltyGhost: Then all //evaluate_fcurve()// calls would require passing an additional `fmodifier_eval_time`… | |||||
| * So we undo the keyframe remapping and instead remap the evaluation time when drawing the | |||||
| * curve itself. Afterward, we go back and redo the keyframe remapping so the controls are | |||||
Done Inline ActionsI know other code still uses 1/0 for true/false, but new code shouldn't. sybren: I know other code still uses `1`/`0` for `true`/`false`, but new code shouldn't. | |||||
| * drawn properly. */ | |||||
| ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, true, false); | |||||
| draw_fcurve_curve(ac, ale->id, fcu, ®ion->v2d, shdr_pos, true); | |||||
| ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, false, false); | |||||
| } | |||||
| else { | |||||
| draw_fcurve_curve(ac, ale->id, fcu, ®ion->v2d, shdr_pos, false); | |||||
| } | |||||
| } | } | ||||
| else if (((fcu->bezt) || (fcu->fpt)) && (fcu->totvert)) { | else if (((fcu->bezt) || (fcu->fpt)) && (fcu->totvert)) { | ||||
| /* just draw curve based on defined data (i.e. no modifiers) */ | /* just draw curve based on defined data (i.e. no modifiers) */ | ||||
| if (fcu->bezt) { | if (fcu->bezt) { | ||||
| if (fcurve_can_use_simple_bezt_drawing(fcu)) { | if (fcurve_can_use_simple_bezt_drawing(fcu)) { | ||||
| draw_fcurve_curve_bezts(ac, ale->id, fcu, ®ion->v2d, shdr_pos); | draw_fcurve_curve_bezts(ac, ale->id, fcu, ®ion->v2d, shdr_pos); | ||||
| } | } | ||||
| else { | else { | ||||
| draw_fcurve_curve(ac, ale->id, fcu, ®ion->v2d, shdr_pos); | draw_fcurve_curve(ac, ale->id, fcu, ®ion->v2d, shdr_pos, false); | ||||
| } | } | ||||
| } | } | ||||
| else if (fcu->fpt) { | else if (fcu->fpt) { | ||||
| draw_fcurve_curve_samples(ac, ale->id, fcu, ®ion->v2d, shdr_pos); | draw_fcurve_curve_samples(ac, ale->id, fcu, ®ion->v2d, shdr_pos); | ||||
| } | } | ||||
| } | } | ||||
| immUnbindProgram(); | immUnbindProgram(); | ||||
| Show All 9 Lines | static void draw_fcurve(bAnimContext *ac, SpaceGraph *sipo, ARegion *region, bAnimListElem *ale) | ||||
| * we must obey this. | * we must obey this. | ||||
| */ | */ | ||||
| if (!(sipo->flag & SIPO_SELCUVERTSONLY) || (fcu->flag & FCURVE_SELECTED)) { | if (!(sipo->flag & SIPO_SELCUVERTSONLY) || (fcu->flag & FCURVE_SELECTED)) { | ||||
| if (!BKE_fcurve_are_keyframes_usable(fcu) && !(fcu->fpt && fcu->totvert)) { | if (!BKE_fcurve_are_keyframes_usable(fcu) && !(fcu->fpt && fcu->totvert)) { | ||||
| /* only draw controls if this is the active modifier */ | /* only draw controls if this is the active modifier */ | ||||
| if ((fcu->flag & FCURVE_ACTIVE) && (fcm)) { | if ((fcu->flag & FCURVE_ACTIVE) && (fcm)) { | ||||
| switch (fcm->type) { | switch (fcm->type) { | ||||
| case FMODIFIER_TYPE_ENVELOPE: /* envelope */ | case FMODIFIER_TYPE_ENVELOPE: /* envelope */ | ||||
| draw_fcurve_modifier_controls_envelope(fcm, ®ion->v2d); | draw_fcurve_modifier_controls_envelope(fcm, ®ion->v2d, adt); | ||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| else if (((fcu->bezt) || (fcu->fpt)) && (fcu->totvert)) { | else if (((fcu->bezt) || (fcu->fpt)) && (fcu->totvert)) { | ||||
| short mapping_flag = ANIM_get_normalization_flags(ac); | short mapping_flag = ANIM_get_normalization_flags(ac); | ||||
| float offset; | float offset; | ||||
| float unit_scale = ANIM_unit_mapping_get_factor( | float unit_scale = ANIM_unit_mapping_get_factor( | ||||
| ▲ Show 20 Lines • Show All 324 Lines • Show Last 20 Lines | |||||
use_nla_remap can be const