Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/transform/transform_gizmo_2d.c
| Show First 20 Lines • Show All 280 Lines • ▼ Show 20 Lines | if (selected_strips > 1) { | ||||
| /* Don't draw the cage as transforming multiple strips isn't currently very useful as it | /* Don't draw the cage as transforming multiple strips isn't currently very useful as it | ||||
| * doesn't behave as one would expect. | * doesn't behave as one would expect. | ||||
| * | * | ||||
| * This is because our current transform system doesn't support shearing which would make the | * This is because our current transform system doesn't support shearing which would make the | ||||
| * scaling transforms of the bounding box behave weirdly. | * scaling transforms of the bounding box behave weirdly. | ||||
| * In addition to this, the rotation of the bounding box can not currently be hooked up | * In addition to this, the rotation of the bounding box can not currently be hooked up | ||||
| * properly to read the result from the transform system (when transforming multiple strips). | * properly to read the result from the transform system (when transforming multiple strips). | ||||
| */ | */ | ||||
| const int pivot_point = scene->toolsettings->sequencer_tool_settings->pivot_point; | |||||
| if (pivot_point == V3D_AROUND_CURSOR) { | |||||
| SpaceSeq *sseq = area->spacedata.first; | |||||
| SEQ_image_preview_unit_to_px(scene, sseq->cursor, r_center); | |||||
| } | |||||
| else { | |||||
| mid_v2_v2v2(r_center, r_min, r_max); | mid_v2_v2v2(r_center, r_min, r_max); | ||||
| } | |||||
| zero_v2(r_min); | zero_v2(r_min); | ||||
| zero_v2(r_max); | zero_v2(r_max); | ||||
| return has_select; | return has_select; | ||||
| } | } | ||||
| } | } | ||||
| if (has_select == false) { | if (has_select == false) { | ||||
| zero_v2(r_min); | zero_v2(r_min); | ||||
| ▲ Show 20 Lines • Show All 50 Lines • ▼ Show 20 Lines | SEQ_ITERATOR_FOREACH (seq, strips) { | ||||
| return transform->rotation * mirror[0] * mirror[1]; | return transform->rotation * mirror[0] * mirror[1]; | ||||
| } | } | ||||
| } | } | ||||
| SEQ_collection_free(strips); | SEQ_collection_free(strips); | ||||
| return 0.0f; | return 0.0f; | ||||
| } | } | ||||
| static bool gizmo2d_calc_center(const bContext *C, float r_center[2]) | static bool seq_get_strip_pivot_median(const Scene *scene, float r_pivot[2]) | ||||
| { | |||||
| zero_v2(r_pivot); | |||||
| ListBase *seqbase = SEQ_active_seqbase_get(SEQ_editing_get(scene)); | |||||
| SeqCollection *strips = SEQ_query_rendered_strips(seqbase, scene->r.cfra, 0); | |||||
| SEQ_filter_selected_strips(strips); | |||||
| bool has_select = SEQ_collection_len(strips) != 0; | |||||
| if (has_select) { | |||||
| Sequence *seq; | |||||
| SEQ_ITERATOR_FOREACH (seq, strips) { | |||||
| float origin[2]; | |||||
| SEQ_image_transform_origin_offset_pixelspace_get(scene, seq, origin); | |||||
| add_v2_v2(r_pivot, origin); | |||||
| } | |||||
| mul_v2_fl(r_pivot, 1.0f / SEQ_collection_len(strips)); | |||||
| } | |||||
| SEQ_collection_free(strips); | |||||
| return has_select; | |||||
| } | |||||
| static bool gizmo2d_calc_transform_pivot(const bContext *C, float r_pivot[2]) | |||||
| { | { | ||||
| ScrArea *area = CTX_wm_area(C); | ScrArea *area = CTX_wm_area(C); | ||||
| Scene *scene = CTX_data_scene(C); | Scene *scene = CTX_data_scene(C); | ||||
| bool has_select = false; | bool has_select = false; | ||||
| zero_v2(r_center); | |||||
| if (area->spacetype == SPACE_IMAGE) { | if (area->spacetype == SPACE_IMAGE) { | ||||
| SpaceImage *sima = area->spacedata.first; | SpaceImage *sima = area->spacedata.first; | ||||
| ViewLayer *view_layer = CTX_data_view_layer(C); | ViewLayer *view_layer = CTX_data_view_layer(C); | ||||
| ED_uvedit_center_from_pivot_ex(sima, scene, view_layer, r_center, sima->around, &has_select); | ED_uvedit_center_from_pivot_ex(sima, scene, view_layer, r_pivot, sima->around, &has_select); | ||||
| } | } | ||||
| else if (area->spacetype == SPACE_SEQ) { | else if (area->spacetype == SPACE_SEQ) { | ||||
| SpaceSeq *sseq = area->spacedata.first; | SpaceSeq *sseq = area->spacedata.first; | ||||
| const int pivot_point = scene->toolsettings->sequencer_tool_settings->pivot_point; | const int pivot_point = scene->toolsettings->sequencer_tool_settings->pivot_point; | ||||
| if (pivot_point == V3D_AROUND_CURSOR) { | |||||
| SEQ_image_preview_unit_to_px(scene, sseq->cursor, r_pivot); | |||||
| ListBase *seqbase = SEQ_active_seqbase_get(SEQ_editing_get(scene)); | ListBase *seqbase = SEQ_active_seqbase_get(SEQ_editing_get(scene)); | ||||
| SeqCollection *strips = SEQ_query_rendered_strips(seqbase, scene->r.cfra, 0); | SeqCollection *strips = SEQ_query_rendered_strips(seqbase, scene->r.cfra, 0); | ||||
| SEQ_filter_selected_strips(strips); | SEQ_filter_selected_strips(strips); | ||||
| has_select = SEQ_collection_len(strips) != 0; | has_select = SEQ_collection_len(strips) != 0; | ||||
| SEQ_collection_free(strips); | |||||
| if (pivot_point == V3D_AROUND_CURSOR) { | |||||
| SEQ_image_preview_unit_to_px(scene, sseq->cursor, r_center); | |||||
| } | } | ||||
| else if (has_select) { | else { | ||||
| Sequence *seq; | has_select = seq_get_strip_pivot_median(scene, r_pivot); | ||||
| SEQ_ITERATOR_FOREACH (seq, strips) { | |||||
| float origin[2]; | |||||
| SEQ_image_transform_origin_offset_pixelspace_get(scene, seq, origin); | |||||
| add_v2_v2(r_center, origin); | |||||
| } | } | ||||
| mul_v2_fl(r_center, 1.0f / SEQ_collection_len(strips)); | |||||
| } | } | ||||
| else { | |||||
| SEQ_collection_free(strips); | BLI_assert_msg(0, "Unhandled space type!"); | ||||
| } | } | ||||
| return has_select; | return has_select; | ||||
| } | } | ||||
| /** | /** | ||||
| * Convert origin (or any other point) from view to region space. | * Convert origin (or any other point) from view to region space. | ||||
| */ | */ | ||||
| BLI_INLINE void gizmo2d_origin_to_region(ARegion *region, float *r_origin) | BLI_INLINE void gizmo2d_origin_to_region(ARegion *region, float *r_origin) | ||||
| { | { | ||||
| UI_view2d_view_to_region_fl(®ion->v2d, r_origin[0], r_origin[1], &r_origin[0], &r_origin[1]); | UI_view2d_view_to_region_fl(®ion->v2d, r_origin[0], r_origin[1], &r_origin[0], &r_origin[1]); | ||||
| } | } | ||||
| /** | /** | ||||
| * Custom handler for gizmo widgets | * Custom handler for gizmo widgets | ||||
| */ | */ | ||||
| static int gizmo2d_modal(bContext *C, | static int gizmo2d_modal(bContext *C, | ||||
| wmGizmo *widget, | wmGizmo *widget, | ||||
| const wmEvent *UNUSED(event), | const wmEvent *UNUSED(event), | ||||
| eWM_GizmoFlagTweak UNUSED(tweak_flag)) | eWM_GizmoFlagTweak UNUSED(tweak_flag)) | ||||
| { | { | ||||
| ARegion *region = CTX_wm_region(C); | ARegion *region = CTX_wm_region(C); | ||||
| float origin[3]; | float origin[3]; | ||||
| gizmo2d_calc_center(C, origin); | gizmo2d_calc_transform_pivot(C, origin); | ||||
| gizmo2d_origin_to_region(region, origin); | gizmo2d_origin_to_region(region, origin); | ||||
| WM_gizmo_set_matrix_location(widget, origin); | WM_gizmo_set_matrix_location(widget, origin); | ||||
| ED_region_tag_redraw_editor_overlays(region); | ED_region_tag_redraw_editor_overlays(region); | ||||
| return OPERATOR_RUNNING_MODAL; | return OPERATOR_RUNNING_MODAL; | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 115 Lines • ▼ Show 20 Lines | static void rotate_around_center_v2(float point[2], const float center[2], const float angle) | ||||
| add_v2_v2(point, center); | add_v2_v2(point, center); | ||||
| } | } | ||||
| static void gizmo2d_xform_refresh(const bContext *C, wmGizmoGroup *gzgroup) | static void gizmo2d_xform_refresh(const bContext *C, wmGizmoGroup *gzgroup) | ||||
| { | { | ||||
| GizmoGroup2D *ggd = gzgroup->customdata; | GizmoGroup2D *ggd = gzgroup->customdata; | ||||
| bool has_select; | bool has_select; | ||||
| if (ggd->no_cage) { | if (ggd->no_cage) { | ||||
| has_select = gizmo2d_calc_center(C, ggd->origin); | has_select = gizmo2d_calc_transform_pivot(C, ggd->origin); | ||||
| } | } | ||||
| else { | else { | ||||
| has_select = gizmo2d_calc_bounds(C, ggd->origin, ggd->min, ggd->max); | has_select = gizmo2d_calc_bounds(C, ggd->origin, ggd->min, ggd->max); | ||||
| ggd->rotation = gizmo2d_calc_rotation(C); | ggd->rotation = gizmo2d_calc_rotation(C); | ||||
| } | } | ||||
| bool show_cage = !ggd->no_cage && !equals_v2v2(ggd->min, ggd->max); | bool show_cage = !ggd->no_cage && !equals_v2v2(ggd->min, ggd->max); | ||||
| Show All 39 Lines | static void gizmo2d_xform_draw_prepare(const bContext *C, wmGizmoGroup *gzgroup) | ||||
| /* Define the bounding box of the gizmo in the offset transform matrix. */ | /* Define the bounding box of the gizmo in the offset transform matrix. */ | ||||
| unit_m4(ggd->cage->matrix_offset); | unit_m4(ggd->cage->matrix_offset); | ||||
| ggd->cage->matrix_offset[0][0] = (ggd->max[0] - ggd->min[0]); | ggd->cage->matrix_offset[0][0] = (ggd->max[0] - ggd->min[0]); | ||||
| ggd->cage->matrix_offset[1][1] = (ggd->max[1] - ggd->min[1]); | ggd->cage->matrix_offset[1][1] = (ggd->max[1] - ggd->min[1]); | ||||
| ScrArea *area = CTX_wm_area(C); | ScrArea *area = CTX_wm_area(C); | ||||
| if (area->spacetype == SPACE_SEQ) { | if (area->spacetype == SPACE_SEQ) { | ||||
| gizmo2d_calc_center(C, origin); | Scene *scene = CTX_data_scene(C); | ||||
| seq_get_strip_pivot_median(scene, origin); | |||||
| float matrix_rotate[4][4]; | float matrix_rotate[4][4]; | ||||
| unit_m4(matrix_rotate); | unit_m4(matrix_rotate); | ||||
| copy_v3_v3(matrix_rotate[3], origin); | copy_v3_v3(matrix_rotate[3], origin); | ||||
| rotate_m4(matrix_rotate, 'Z', ggd->rotation); | rotate_m4(matrix_rotate, 'Z', ggd->rotation); | ||||
| unit_m4(ggd->cage->matrix_basis); | unit_m4(ggd->cage->matrix_basis); | ||||
| mul_m4_m4m4(ggd->cage->matrix_basis, matrix_rotate, ggd->cage->matrix_basis); | mul_m4_m4m4(ggd->cage->matrix_basis, matrix_rotate, ggd->cage->matrix_basis); | ||||
| ▲ Show 20 Lines • Show All 46 Lines • ▼ Show 20 Lines | static void gizmo2d_xform_invoke_prepare(const bContext *C, | ||||
| float c[3] = {mid[0], mid[1], 0.0f}; | float c[3] = {mid[0], mid[1], 0.0f}; | ||||
| float orient_matrix[3][3]; | float orient_matrix[3][3]; | ||||
| ScrArea *area = CTX_wm_area(C); | ScrArea *area = CTX_wm_area(C); | ||||
| if (ggd->rotation != 0.0f && area->spacetype == SPACE_SEQ) { | if (ggd->rotation != 0.0f && area->spacetype == SPACE_SEQ) { | ||||
| float origin[3]; | float origin[3]; | ||||
| gizmo2d_calc_center(C, origin); | Scene *scene = CTX_data_scene(C); | ||||
| seq_get_strip_pivot_median(scene, origin); | |||||
| /* We need to rotate the cardinal points so they align with the rotated bounding box. */ | /* We need to rotate the cardinal points so they align with the rotated bounding box. */ | ||||
| rotate_around_center_v2(n, origin, ggd->rotation); | rotate_around_center_v2(n, origin, ggd->rotation); | ||||
| rotate_around_center_v2(w, origin, ggd->rotation); | rotate_around_center_v2(w, origin, ggd->rotation); | ||||
| rotate_around_center_v2(e, origin, ggd->rotation); | rotate_around_center_v2(e, origin, ggd->rotation); | ||||
| rotate_around_center_v2(s, origin, ggd->rotation); | rotate_around_center_v2(s, origin, ggd->rotation); | ||||
| rotate_around_center_v2(nw, origin, ggd->rotation); | rotate_around_center_v2(nw, origin, ggd->rotation); | ||||
| ▲ Show 20 Lines • Show All 104 Lines • ▼ Show 20 Lines | static GizmoGroup_Resize2D *gizmogroup2d_resize_init(wmGizmoGroup *gzgroup) | ||||
| return ggd; | return ggd; | ||||
| } | } | ||||
| static void gizmo2d_resize_refresh(const bContext *C, wmGizmoGroup *gzgroup) | static void gizmo2d_resize_refresh(const bContext *C, wmGizmoGroup *gzgroup) | ||||
| { | { | ||||
| GizmoGroup_Resize2D *ggd = gzgroup->customdata; | GizmoGroup_Resize2D *ggd = gzgroup->customdata; | ||||
| float origin[3]; | float origin[3]; | ||||
| const bool has_select = gizmo2d_calc_center(C, origin); | const bool has_select = gizmo2d_calc_transform_pivot(C, origin); | ||||
| if (has_select == false) { | if (has_select == false) { | ||||
| for (int i = 0; i < ARRAY_SIZE(ggd->gizmo_xy); i++) { | for (int i = 0; i < ARRAY_SIZE(ggd->gizmo_xy); i++) { | ||||
| ggd->gizmo_xy[i]->flag |= WM_GIZMO_HIDDEN; | ggd->gizmo_xy[i]->flag |= WM_GIZMO_HIDDEN; | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| for (int i = 0; i < ARRAY_SIZE(ggd->gizmo_xy); i++) { | for (int i = 0; i < ARRAY_SIZE(ggd->gizmo_xy); i++) { | ||||
| ▲ Show 20 Lines • Show All 143 Lines • ▼ Show 20 Lines | static GizmoGroup_Rotate2D *gizmogroup2d_rotate_init(wmGizmoGroup *gzgroup) | ||||
| return ggd; | return ggd; | ||||
| } | } | ||||
| static void gizmo2d_rotate_refresh(const bContext *C, wmGizmoGroup *gzgroup) | static void gizmo2d_rotate_refresh(const bContext *C, wmGizmoGroup *gzgroup) | ||||
| { | { | ||||
| GizmoGroup_Rotate2D *ggd = gzgroup->customdata; | GizmoGroup_Rotate2D *ggd = gzgroup->customdata; | ||||
| float origin[3]; | float origin[3]; | ||||
| const bool has_select = gizmo2d_calc_center(C, origin); | const bool has_select = gizmo2d_calc_transform_pivot(C, origin); | ||||
| if (has_select == false) { | if (has_select == false) { | ||||
| ggd->gizmo->flag |= WM_GIZMO_HIDDEN; | ggd->gizmo->flag |= WM_GIZMO_HIDDEN; | ||||
| } | } | ||||
| else { | else { | ||||
| ggd->gizmo->flag &= ~WM_GIZMO_HIDDEN; | ggd->gizmo->flag &= ~WM_GIZMO_HIDDEN; | ||||
| copy_v2_v2(ggd->origin, origin); | copy_v2_v2(ggd->origin, origin); | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 71 Lines • Show Last 20 Lines | |||||