diff options
author | Lukas Tönne <lukas.toenne@gmail.com> | 2017-08-19 14:02:03 +0300 |
---|---|---|
committer | Lukas Tönne <lukas.toenne@gmail.com> | 2017-08-19 14:02:03 +0300 |
commit | 45f0f3dc0457a53a25103784f0e0d100c7a17cbe (patch) | |
tree | 94767d8e4fa6ea23f2bbd2274f239ecbbdc5931a /source/blender/editors/manipulator_library/manipulator_types/grab3d_manipulator.c | |
parent | 0d67f8d5c46fcc97cbb0544ef7d8c3c0056025c4 (diff) | |
parent | 9a262ed47ecb1c9f43053b0653364c59d9595fdf (diff) |
Merge branch 'blender2.8' into strand_editmode
Diffstat (limited to 'source/blender/editors/manipulator_library/manipulator_types/grab3d_manipulator.c')
-rw-r--r-- | source/blender/editors/manipulator_library/manipulator_types/grab3d_manipulator.c | 194 |
1 files changed, 153 insertions, 41 deletions
diff --git a/source/blender/editors/manipulator_library/manipulator_types/grab3d_manipulator.c b/source/blender/editors/manipulator_library/manipulator_types/grab3d_manipulator.c index d4b98ec514a..38e350762c1 100644 --- a/source/blender/editors/manipulator_library/manipulator_types/grab3d_manipulator.c +++ b/source/blender/editors/manipulator_library/manipulator_types/grab3d_manipulator.c @@ -23,7 +23,7 @@ * * \name Grab Manipulator * - * 3D Manipulator + * 3D Manipulator, also works in 2D views. * * \brief Simple manipulator to grab and translate. * @@ -31,8 +31,6 @@ * - `matrix[1]` currently not used. * - `matrix[2]` is the widget direction (for all manipulators). * - * TODO: use matrix_space - * */ #include "BIF_gl.h" @@ -65,6 +63,20 @@ #include "../manipulator_geometry.h" #include "../manipulator_library_intern.h" +typedef struct GrabManipulator3D { + wmManipulator manipulator; + /* Added to 'matrix_basis' when calculating the matrix. */ + float prop_co[3]; +} GrabManipulator3D; + +static void manipulator_grab_matrix_basis_get(const wmManipulator *mpr, float r_matrix[4][4]) +{ + GrabManipulator3D *grab = (GrabManipulator3D *)mpr; + + copy_m4_m4(r_matrix, grab->manipulator.matrix_basis); + add_v3_v3(r_matrix[3], grab->prop_co); +} + static void manipulator_grab_modal( bContext *C, wmManipulator *mpr, const wmEvent *event, eWM_ManipulatorTweak tweak_flag); @@ -75,11 +87,7 @@ typedef struct GrabInteraction { /* only for when using properties */ float init_prop_co[3]; - /* final output values, used for drawing */ - struct { - float co_ofs[3]; - float co_final[3]; - } output; + float init_matrix_final[4][4]; } GrabInteraction; #define DIAL_RESOLUTION 32 @@ -87,13 +95,13 @@ typedef struct GrabInteraction { /* -------------------------------------------------------------------- */ static void grab_geom_draw( - const wmManipulator *mpr, const float col[4], const bool select) + const wmManipulator *mpr, const float color[4], const bool select, const int draw_options) { #ifdef USE_MANIPULATOR_CUSTOM_DIAL UNUSED_VARS(grab3d, col, axis_modal_mat); wm_manipulator_geometryinfo_draw(&wm_manipulator_geom_data_grab3d, select); #else - const int draw_options = RNA_enum_get(mpr->ptr, "draw_options"); + const int draw_style = RNA_enum_get(mpr->ptr, "draw_style"); const bool filled = (draw_options & ED_MANIPULATOR_GRAB_DRAW_FLAG_FILL) != 0; glLineWidth(mpr->line_width); @@ -103,13 +111,27 @@ static void grab_geom_draw( immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); - immUniformColor4fv(col); + immUniformColor4fv(color); - if (filled) { - imm_draw_circle_fill(pos, 0, 0, 1.0, DIAL_RESOLUTION); + if (draw_style == ED_MANIPULATOR_GRAB_STYLE_RING_2D) { + if (filled) { + imm_draw_circle_fill(pos, 0, 0, 1.0f, DIAL_RESOLUTION); + } + else { + imm_draw_circle_wire(pos, 0, 0, 1.0f, DIAL_RESOLUTION); + } + } + else if (draw_style == ED_MANIPULATOR_GRAB_STYLE_CROSS_2D) { + immBegin(GWN_PRIM_LINES, 4); + immVertex2f(pos, 1.0f, 1.0f); + immVertex2f(pos, -1.0f, -1.0f); + + immVertex2f(pos, -1.0f, 1.0f); + immVertex2f(pos, 1.0f, -1.0f); + immEnd(); } else { - imm_draw_circle_wire(pos, 0, 0, 1.0, DIAL_RESOLUTION); + BLI_assert(0); } immUnbindProgram(); @@ -129,45 +151,68 @@ static void grab3d_get_translate( }; RegionView3D *rv3d = ar->regiondata; - const float *co_ref = inter->init_prop_co; + float co_ref[3]; + mul_v3_mat3_m4v3(co_ref, mpr->matrix_space, inter->init_prop_co); const float zfac = ED_view3d_calc_zfac(rv3d, co_ref, NULL); ED_view3d_win_to_delta(ar, mval_delta, co_delta, zfac); + + float matrix_space_inv[3][3]; + copy_m3_m4(matrix_space_inv, mpr->matrix_space); + invert_m3(matrix_space_inv); + mul_m3_v3(matrix_space_inv, co_delta); } static void grab3d_draw_intern( const bContext *C, wmManipulator *mpr, const bool select, const bool highlight) { - float mat[4][4]; - float col[4]; - - BLI_assert(CTX_wm_area(C)->spacetype == SPACE_VIEW3D); - UNUSED_VARS_NDEBUG(C); - - manipulator_color_get(mpr, highlight, col); - - copy_m4_m4(mat, mpr->matrix_basis); - mul_mat3_m4_fl(mat, mpr->scale_final); + GrabInteraction *inter = mpr->interaction_data; + const int draw_options = RNA_enum_get(mpr->ptr, "draw_options"); + const bool align_view = (draw_options & ED_MANIPULATOR_GRAB_DRAW_FLAG_ALIGN_VIEW) != 0; + float color[4]; + float matrix_final[4][4]; + float matrix_align[4][4]; + + manipulator_color_get(mpr, highlight, color); + + { + float matrix_basis_adjust[4][4]; + manipulator_grab_matrix_basis_get(mpr, matrix_basis_adjust); + WM_manipulator_calc_matrix_final_params( + mpr, &((struct WM_ManipulatorMatrixParams) { + .matrix_basis = matrix_basis_adjust, + }), matrix_final); + } gpuPushMatrix(); - if (mpr->interaction_data) { - GrabInteraction *inter = mpr->interaction_data; - gpuTranslate3fv(inter->output.co_ofs); + gpuMultMatrix(matrix_final); + + if (align_view) { + float matrix_final_unit[4][4]; + RegionView3D *rv3d = CTX_wm_region_view3d(C); + normalize_m4_m4(matrix_final_unit, matrix_final); + mul_m4_m4m4(matrix_align, rv3d->viewmat, matrix_final_unit); + zero_v3(matrix_align[3]); + transpose_m4(matrix_align); + gpuMultMatrix(matrix_align); } - gpuMultMatrix(mat); - gpuMultMatrix(mpr->matrix_offset); + glEnable(GL_BLEND); - grab_geom_draw(mpr, col, select); + grab_geom_draw(mpr, color, select, draw_options); glDisable(GL_BLEND); gpuPopMatrix(); if (mpr->interaction_data) { gpuPushMatrix(); - gpuMultMatrix(mat); - gpuMultMatrix(mpr->matrix_offset); + gpuMultMatrix(inter->init_matrix_final); + + if (align_view) { + gpuMultMatrix(matrix_align); + } + glEnable(GL_BLEND); - grab_geom_draw(mpr, (const float [4]){0.5f, 0.5f, 0.5f, 0.5f}, select); + grab_geom_draw(mpr, (const float [4]){0.5f, 0.5f, 0.5f, 0.5f}, select, draw_options); glDisable(GL_BLEND); gpuPopMatrix(); } @@ -195,17 +240,35 @@ static void manipulator_grab_modal( bContext *C, wmManipulator *mpr, const wmEvent *event, eWM_ManipulatorTweak UNUSED(tweak_flag)) { + GrabManipulator3D *grab = (GrabManipulator3D *)mpr; GrabInteraction *inter = mpr->interaction_data; + ARegion *ar = CTX_wm_region(C); - grab3d_get_translate(mpr, event, CTX_wm_region(C), inter->output.co_ofs); - - add_v3_v3v3(inter->output.co_final, inter->init_prop_co, inter->output.co_ofs); + float prop_delta[3]; + if (CTX_wm_area(C)->spacetype == SPACE_VIEW3D) { + grab3d_get_translate(mpr, event, ar, prop_delta); + } + else { + float mval_proj_init[2], mval_proj_curr[2]; + if ((manipulator_window_project_2d( + C, mpr, inter->init_mval, 2, false, mval_proj_init) == false) || + (manipulator_window_project_2d( + C, mpr, (const float[2]){UNPACK2(event->mval)}, 2, false, mval_proj_curr) == false)) + { + return; + } + sub_v2_v2v2(prop_delta, mval_proj_curr, mval_proj_init); + prop_delta[2] = 0.0f; + } + add_v3_v3v3(grab->prop_co, inter->init_prop_co, prop_delta); /* set the property for the operator and call its modal function */ wmManipulatorProperty *mpr_prop = WM_manipulator_target_property_find(mpr, "offset"); if (WM_manipulator_target_property_is_valid(mpr_prop)) { - WM_manipulator_target_property_value_set_array(C, mpr, mpr_prop, inter->output.co_final); + WM_manipulator_target_property_value_set_array(C, mpr, mpr_prop, grab->prop_co); } + + ED_region_tag_redraw(ar); } static void manipulator_grab_invoke( @@ -216,14 +279,57 @@ static void manipulator_grab_invoke( inter->init_mval[0] = event->mval[0]; inter->init_mval[1] = event->mval[1]; +#if 0 + copy_v3_v3(inter->init_prop_co, grab->prop_co); +#else wmManipulatorProperty *mpr_prop = WM_manipulator_target_property_find(mpr, "offset"); if (WM_manipulator_target_property_is_valid(mpr_prop)) { WM_manipulator_target_property_value_get_array(mpr, mpr_prop, inter->init_prop_co); } +#endif + + { + float matrix_basis_adjust[4][4]; + manipulator_grab_matrix_basis_get(mpr, matrix_basis_adjust); + WM_manipulator_calc_matrix_final_params( + mpr, &((struct WM_ManipulatorMatrixParams) { + .matrix_basis = matrix_basis_adjust, + }), inter->init_matrix_final); + } mpr->interaction_data = inter; } + +static int manipulator_grab_test_select( + bContext *C, wmManipulator *mpr, const wmEvent *event) +{ + float point_local[2]; + + if (manipulator_window_project_2d( + C, mpr, (const float[2]){UNPACK2(event->mval)}, 2, true, point_local) == false) + { + return 0; + } + + if (len_squared_v2(point_local) < SQUARE(mpr->scale_final)) { + return true; + } + + return 0; +} + +static void manipulator_grab_property_update(wmManipulator *mpr, wmManipulatorProperty *mpr_prop) +{ + GrabManipulator3D *grab = (GrabManipulator3D *)mpr; + WM_manipulator_target_property_value_get_array(mpr, mpr_prop, grab->prop_co); +} + +static int manipulator_grab_cursor_get(wmManipulator *UNUSED(mpr)) +{ + return BC_HANDCURSOR; +} + /* -------------------------------------------------------------------- */ /** \name Grab Manipulator API * @@ -237,22 +343,28 @@ static void MANIPULATOR_WT_grab_3d(wmManipulatorType *wt) /* api callbacks */ wt->draw = manipulator_grab_draw; wt->draw_select = manipulator_grab_draw_select; + wt->test_select = manipulator_grab_test_select; + wt->matrix_basis_get = manipulator_grab_matrix_basis_get; wt->invoke = manipulator_grab_invoke; + wt->property_update = manipulator_grab_property_update; wt->modal = manipulator_grab_modal; + wt->cursor_get = manipulator_grab_cursor_get; - wt->struct_size = sizeof(wmManipulator); + wt->struct_size = sizeof(GrabManipulator3D); /* rna */ static EnumPropertyItem rna_enum_draw_style[] = { - {ED_MANIPULATOR_GRAB_STYLE_RING, "RING", 0, "Ring", ""}, + {ED_MANIPULATOR_GRAB_STYLE_RING_2D, "RING_2D", 0, "Ring", ""}, + {ED_MANIPULATOR_GRAB_STYLE_CROSS_2D, "CROSS_2D", 0, "Ring", ""}, {0, NULL, 0, NULL, NULL} }; static EnumPropertyItem rna_enum_draw_options[] = { {ED_MANIPULATOR_GRAB_DRAW_FLAG_FILL, "FILL", 0, "Filled", ""}, + {ED_MANIPULATOR_GRAB_DRAW_FLAG_ALIGN_VIEW, "ALIGN_VIEW", 0, "Align View", ""}, {0, NULL, 0, NULL, NULL} }; - RNA_def_enum(wt->srna, "draw_style", rna_enum_draw_style, ED_MANIPULATOR_GRAB_STYLE_RING, "Draw Style", ""); + RNA_def_enum(wt->srna, "draw_style", rna_enum_draw_style, ED_MANIPULATOR_GRAB_STYLE_RING_2D, "Draw Style", ""); RNA_def_enum_flag(wt->srna, "draw_options", rna_enum_draw_options, 0, "Draw Options", ""); WM_manipulatortype_target_property_def(wt, "offset", PROP_FLOAT, 3); |