Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/gizmo_library/gizmo_types/dial3d_gizmo.c
| Show First 20 Lines • Show All 64 Lines • ▼ Show 20 Lines | |||||
| /* own includes */ | /* own includes */ | ||||
| #include "../gizmo_geometry.h" | #include "../gizmo_geometry.h" | ||||
| #include "../gizmo_library_intern.h" | #include "../gizmo_library_intern.h" | ||||
| /* To use custom dials exported to geom_dial_gizmo.c */ | /* To use custom dials exported to geom_dial_gizmo.c */ | ||||
| // #define USE_GIZMO_CUSTOM_DIAL | // #define USE_GIZMO_CUSTOM_DIAL | ||||
| static int gizmo_dial_modal( | |||||
| bContext *C, wmGizmo *gz, const wmEvent *event, | |||||
| eWM_GizmoFlagTweak tweak_flag); | |||||
| typedef struct DialInteraction { | typedef struct DialInteraction { | ||||
| struct { | struct { | ||||
| float mval[2]; | float mval[2]; | ||||
| /* Only for when using properties. */ | /* Only for when using properties. */ | ||||
| float prop_angle; | float prop_angle; | ||||
| } init; | } init; | ||||
| struct { | struct { | ||||
| /* Cache the last angle to detect rotations bigger than -/+ PI. */ | /* Cache the last angle to detect rotations bigger than -/+ PI. */ | ||||
| eWM_GizmoFlagTweak tweak_flag; | eWM_GizmoFlagTweak tweak_flag; | ||||
| float angle; | float angle; | ||||
| } prev; | } prev; | ||||
| /* Number of full rotations. */ | /* Number of full rotations. */ | ||||
| int rotations; | int rotations; | ||||
| bool has_drag; | bool has_drag; | ||||
| /* Final output values, used for drawing. */ | /* Final output values, used for drawing. */ | ||||
| struct { | struct { | ||||
| float angle_ofs; | float angle_ofs; | ||||
| float angle_delta; | float angle_delta; | ||||
| float angle_increment; | |||||
campbellbarton: This isn't output as far as I can see, its a snap setting. Would move under `has_drag` | |||||
| } output; | } output; | ||||
| } DialInteraction; | } DialInteraction; | ||||
| #define DIAL_WIDTH 1.0f | #define DIAL_WIDTH 1.0f | ||||
| #define DIAL_RESOLUTION 48 | #define DIAL_RESOLUTION 48 | ||||
| /* Could make option, negative to clip more (don't show when view aligned). */ | /* Could make option, negative to clip more (don't show when view aligned). */ | ||||
| #define DIAL_CLIP_BIAS 0.02 | #define DIAL_CLIP_BIAS 0.02 | ||||
| ▲ Show 20 Lines • Show All 78 Lines • ▼ Show 20 Lines | static void dial_ghostarc_draw_helpline( | ||||
| immVertex3fv(pos, co_outer); | immVertex3fv(pos, co_outer); | ||||
| immEnd(); | immEnd(); | ||||
| immUnbindProgram(); | immUnbindProgram(); | ||||
| GPU_matrix_pop(); | GPU_matrix_pop(); | ||||
| } | } | ||||
| /** | |||||
| * Draws segments to indicate the position of each increment. | |||||
| */ | |||||
| static void dial_ghostarc_draw_incremental_angle(const float incremental_angle) | |||||
| { | |||||
| const int tot_incr = (2 * M_PI) / incremental_angle; | |||||
| GPU_line_width(1.0f); | |||||
| uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); | |||||
| immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); | |||||
| immUniformColor3f(1.0f, 1.0f, 1.0f); | |||||
| immBegin(GPU_PRIM_LINES, tot_incr * 2); | |||||
| float v[3] = { 0 }; | |||||
| for (int i = 0; i < tot_incr; i++) { | |||||
| v[0] = sinf(incremental_angle * i); | |||||
| v[1] = cosf(incremental_angle * i); | |||||
| mul_v2_fl(v, DIAL_WIDTH * 1.1f); | |||||
| immVertex3fv(pos, v); | |||||
| mul_v2_fl(v, 1.1f); | |||||
| immVertex3fv(pos, v); | |||||
| } | |||||
| immEnd(); | |||||
| immUnbindProgram(); | |||||
| } | |||||
| static void dial_ghostarc_draw( | static void dial_ghostarc_draw( | ||||
| const float angle_ofs, const float angle_delta, | const float angle_ofs, const float angle_delta, | ||||
| const float arc_inner_factor, const float color[4]) | const float arc_inner_factor, const float color[4]) | ||||
| { | { | ||||
| const float width_inner = DIAL_WIDTH; | const float width_inner = DIAL_WIDTH; | ||||
| GPUVertFormat *format = immVertexFormat(); | GPUVertFormat *format = immVertexFormat(); | ||||
| uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); | uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); | ||||
| immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); | immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); | ||||
| ▲ Show 20 Lines • Show All 112 Lines • ▼ Show 20 Lines | static void dial_draw_intern( | ||||
| gizmo_color_get(gz, highlight, color); | gizmo_color_get(gz, highlight, color); | ||||
| WM_gizmo_calc_matrix_final(gz, matrix_final); | WM_gizmo_calc_matrix_final(gz, matrix_final); | ||||
| GPU_matrix_push(); | GPU_matrix_push(); | ||||
| GPU_matrix_mul(matrix_final); | GPU_matrix_mul(matrix_final); | ||||
| /* FIXME(campbell): look into removing this. */ | |||||
| if ((gz->flag & WM_GIZMO_DRAW_VALUE) && | |||||
| (gz->state & WM_GIZMO_STATE_MODAL)) | |||||
| { | |||||
| /* XXX, View3D rotation gizmo doesn't call modal. */ | |||||
| if (!WM_gizmo_target_property_is_valid_any(gz)) { | |||||
| wmWindow *win = CTX_wm_window(C); | |||||
| gizmo_dial_modal((bContext *)C, gz, win->eventstate, 0); | |||||
| } | |||||
| } | |||||
| GPU_polygon_smooth(false); | GPU_polygon_smooth(false); | ||||
| const float arc_partial_angle = RNA_float_get(gz->ptr, "arc_partial_angle"); | const float arc_partial_angle = RNA_float_get(gz->ptr, "arc_partial_angle"); | ||||
| const float arc_inner_factor = RNA_float_get(gz->ptr, "arc_inner_factor"); | const float arc_inner_factor = RNA_float_get(gz->ptr, "arc_inner_factor"); | ||||
| if (select == false) { | if (select == false && (gz->state & WM_GIZMO_STATE_MODAL)) { | ||||
| DialInteraction *inter = gz->interaction_data; | |||||
| float angle_ofs = 0.0f; | float angle_ofs = 0.0f; | ||||
| float angle_delta = 0.0f; | |||||
| bool show_ghostarc = false; | bool show_ghostarc = false; | ||||
| /* Draw rotation indicator arc first. */ | /* Draw rotation indicator arc first. */ | ||||
| wmGizmoProperty *gz_prop = WM_gizmo_target_property_find(gz, "offset"); | |||||
| const int draw_options = RNA_enum_get(gz->ptr, "draw_options"); | const int draw_options = RNA_enum_get(gz->ptr, "draw_options"); | ||||
| if (WM_gizmo_target_property_is_valid(gz_prop) && | if (draw_options & ED_GIZMO_DIAL_DRAW_FLAG_ANGLE_VALUE) | ||||
| (draw_options & ED_GIZMO_DIAL_DRAW_FLAG_ANGLE_VALUE)) | |||||
| { | { | ||||
| angle_ofs = 0.0f; | angle_ofs = 0.0f; | ||||
| angle_delta = WM_gizmo_target_property_float_get(gz, gz_prop); | |||||
| show_ghostarc = true; | show_ghostarc = true; | ||||
| } | } | ||||
| else if ((gz->flag & WM_GIZMO_DRAW_VALUE) && | else if (gz->flag & WM_GIZMO_DRAW_VALUE) | ||||
| (gz->state & WM_GIZMO_STATE_MODAL)) | |||||
| { | { | ||||
| DialInteraction *inter = gz->interaction_data; | |||||
| angle_ofs = inter->output.angle_ofs; | angle_ofs = inter->output.angle_ofs; | ||||
| angle_delta = inter->output.angle_delta; | |||||
| show_ghostarc = true; | show_ghostarc = true; | ||||
| } | } | ||||
| if (show_ghostarc) { | if (show_ghostarc) { | ||||
| dial_ghostarc_draw_with_helplines(angle_ofs, angle_delta, arc_inner_factor, color, draw_options); | dial_ghostarc_draw_with_helplines( | ||||
| angle_ofs, inter->output.angle_delta, | |||||
| arc_inner_factor, color, draw_options); | |||||
| if ((draw_options & ED_GIZMO_DIAL_DRAW_FLAG_ANGLE_MIRROR) != 0) { | if ((draw_options & ED_GIZMO_DIAL_DRAW_FLAG_ANGLE_MIRROR) != 0) { | ||||
| angle_ofs += M_PI; | angle_ofs += M_PI; | ||||
| dial_ghostarc_draw_with_helplines(angle_ofs, angle_delta, arc_inner_factor, color, draw_options); | dial_ghostarc_draw_with_helplines( | ||||
| angle_ofs, inter->output.angle_delta, | |||||
| arc_inner_factor, color, draw_options); | |||||
| } | |||||
| } | } | ||||
| if (inter->output.angle_increment) { | |||||
| dial_ghostarc_draw_incremental_angle(inter->output.angle_increment); | |||||
| } | } | ||||
| } | } | ||||
| /* Draw actual dial gizmo. */ | /* Draw actual dial gizmo. */ | ||||
| dial_geom_draw(gz, color, select, gz->matrix_basis, clip_plane, arc_partial_angle, arc_inner_factor); | dial_geom_draw(gz, color, select, gz->matrix_basis, clip_plane, arc_partial_angle, arc_inner_factor); | ||||
| GPU_matrix_pop(); | GPU_matrix_pop(); | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 55 Lines • ▼ Show 20 Lines | static int gizmo_dial_modal( | ||||
| eWM_GizmoFlagTweak tweak_flag) | eWM_GizmoFlagTweak tweak_flag) | ||||
| { | { | ||||
| DialInteraction *inter = gz->interaction_data; | DialInteraction *inter = gz->interaction_data; | ||||
| if ((event->type != MOUSEMOVE) && (inter->prev.tweak_flag == tweak_flag)) { | if ((event->type != MOUSEMOVE) && (inter->prev.tweak_flag == tweak_flag)) { | ||||
| return OPERATOR_RUNNING_MODAL; | return OPERATOR_RUNNING_MODAL; | ||||
| } | } | ||||
| /* Coordinate at which the arc drawing will be started. */ | /* Coordinate at which the arc drawing will be started. */ | ||||
| const float co_outer[4] = {0.0f, DIAL_WIDTH, 0.0f}; | const float co_outer[4] = {0.0f, DIAL_WIDTH, 0.0f}; | ||||
| float angle_ofs, angle_delta; | float angle_ofs, angle_delta, angle_increment = 0.0f; | ||||
| dial_ghostarc_get_angles( | dial_ghostarc_get_angles( | ||||
| gz, event, CTX_wm_region(C), gz->matrix_basis, co_outer, &angle_ofs, &angle_delta); | gz, event, CTX_wm_region(C), gz->matrix_basis, co_outer, &angle_ofs, &angle_delta); | ||||
| if (tweak_flag & WM_GIZMO_TWEAK_SNAP) { | if (tweak_flag & WM_GIZMO_TWEAK_SNAP) { | ||||
| const double snap = DEG2RAD(5); | angle_increment = DEG2RAD(5); | ||||
| angle_delta = (float)roundf((double)angle_delta / snap) * snap; | angle_delta = (float)roundf((double)angle_delta / angle_increment) * angle_increment; | ||||
Done Inline ActionsThis should use the angle_increment setting for snapping. Not hard coded value. campbellbarton: This should use the angle_increment setting for snapping. Not hard coded value. | |||||
| } | } | ||||
| if (tweak_flag & WM_GIZMO_TWEAK_PRECISE) { | if (tweak_flag & WM_GIZMO_TWEAK_PRECISE) { | ||||
| angle_increment *= 0.1f; | |||||
| angle_delta *= 0.1f; | angle_delta *= 0.1f; | ||||
| } | } | ||||
| if (angle_delta != 0.0f) { | if (angle_delta != 0.0f) { | ||||
| inter->has_drag = true; | inter->has_drag = true; | ||||
| } | } | ||||
| inter->output.angle_increment = angle_increment; | |||||
| inter->output.angle_delta = angle_delta; | inter->output.angle_delta = angle_delta; | ||||
| inter->output.angle_ofs = angle_ofs; | inter->output.angle_ofs = angle_ofs; | ||||
| /* Set the property for the operator and call its modal function. */ | /* Set the property for the operator and call its modal function. */ | ||||
| wmGizmoProperty *gz_prop = WM_gizmo_target_property_find(gz, "offset"); | wmGizmoProperty *gz_prop = WM_gizmo_target_property_find(gz, "offset"); | ||||
| if (WM_gizmo_target_property_is_valid(gz_prop)) { | if (WM_gizmo_target_property_is_valid(gz_prop)) { | ||||
| WM_gizmo_target_property_float_set(C, gz, gz_prop, inter->init.prop_angle + angle_delta); | WM_gizmo_target_property_float_set(C, gz, gz_prop, inter->init.prop_angle + angle_delta); | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 112 Lines • Show Last 20 Lines | |||||
This isn't output as far as I can see, its a snap setting. Would move under has_drag