Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/editors/transform/transform_gizmo_3d.c')
-rw-r--r--source/blender/editors/transform/transform_gizmo_3d.c448
1 files changed, 288 insertions, 160 deletions
diff --git a/source/blender/editors/transform/transform_gizmo_3d.c b/source/blender/editors/transform/transform_gizmo_3d.c
index aa8dad2b95f..5b749e05052 100644
--- a/source/blender/editors/transform/transform_gizmo_3d.c
+++ b/source/blender/editors/transform/transform_gizmo_3d.c
@@ -45,7 +45,6 @@
#include "WM_api.h"
#include "WM_message.h"
#include "WM_types.h"
-#include "wm.h"
#include "ED_armature.h"
#include "ED_gizmo_library.h"
@@ -71,6 +70,10 @@
#include "GPU_state.h"
+static void gizmo_refresh_from_matrix(wmGizmoGroup *gzgroup,
+ const float twmat[4][4],
+ const float scale[3]);
+
/* return codes for select, and drawing flags */
#define MAN_TRANS_X (1 << 0)
@@ -155,6 +158,9 @@ typedef struct GizmoGroup {
float viewinv_m3[3][3];
} prev;
+ /* Only for Rotate operator. */
+ float rotation;
+
struct wmGizmo *gizmos[MAN_AXIS_LAST];
} GizmoGroup;
@@ -1269,103 +1275,31 @@ static void gizmo_xform_message_subscribe(wmGizmoGroup *gzgroup,
WM_msg_subscribe_rna_anon_prop(mbus, EditBone, lock, &msg_sub_value_gz_tag_refresh);
}
-void drawDial3d(const TransInfo *t)
+static void gizmo_3d_dial_matrixbasis_calc(const ARegion *region,
+ float axis[3],
+ float center_global[3],
+ float mval_init[2],
+ float r_mat_basis[4][4])
{
- if (t->mode == TFM_ROTATION && t->spacetype == SPACE_VIEW3D) {
- if (t->options & CTX_PAINT_CURVE) {
- /* Matrices are in the screen space. Not supported. */
- return;
- }
-
- wmGizmo *gz = wm_gizmomap_modal_get(t->region->gizmo_map);
- if (gz == NULL) {
- /* We only draw Dial3d if the operator has been called by a gizmo. */
- return;
- }
-
- float mat_basis[4][4];
- float mat_final[4][4];
- float color[4];
- float increment = 0.0f;
- float line_with = GIZMO_AXIS_LINE_WIDTH + 1.0f;
- float scale = UI_DPI_FAC * U.gizmo_size;
-
- int axis_idx;
-
- const TransCon *tc = &(t->con);
- if (tc->mode & CON_APPLY) {
- if (tc->mode & CON_AXIS0) {
- axis_idx = MAN_AXIS_ROT_X;
- negate_v3_v3(mat_basis[2], t->spacemtx[0]);
- }
- else if (tc->mode & CON_AXIS1) {
- axis_idx = MAN_AXIS_ROT_Y;
- negate_v3_v3(mat_basis[2], t->spacemtx[1]);
- }
- else {
- BLI_assert((tc->mode & CON_AXIS2) != 0);
- axis_idx = MAN_AXIS_ROT_Z;
- negate_v3_v3(mat_basis[2], t->spacemtx[2]);
- }
- }
- else {
- axis_idx = MAN_AXIS_ROT_C;
- copy_v3_v3(mat_basis[2], t->spacemtx[t->orient_axis]);
- scale *= 1.2f;
- line_with -= 1.0f;
- }
-
- copy_v3_v3(mat_basis[3], t->center_global);
- mat_basis[2][3] = -dot_v3v3(mat_basis[2], mat_basis[3]);
-
- if (ED_view3d_win_to_3d_on_plane(
- t->region, mat_basis[2], (float[2]){UNPACK2(t->mouse.imval)}, false, mat_basis[1])) {
- sub_v3_v3(mat_basis[1], mat_basis[3]);
- normalize_v3(mat_basis[1]);
- cross_v3_v3v3(mat_basis[0], mat_basis[1], mat_basis[2]);
- }
- else {
- /* The plane and the mouse direction are parallel.
- * Calculate a matrix orthogonal to the axis. */
- ortho_basis_v3v3_v3(mat_basis[0], mat_basis[1], mat_basis[2]);
- }
-
- mat_basis[0][3] = 0.0f;
- mat_basis[1][3] = 0.0f;
- mat_basis[2][3] = 0.0f;
- mat_basis[3][3] = 1.0f;
-
- copy_m4_m4(mat_final, mat_basis);
- scale *= ED_view3d_pixel_size_no_ui_scale(t->region->regiondata, mat_final[3]);
- mul_mat3_m4_fl(mat_final, scale);
+ copy_v3_v3(r_mat_basis[2], axis);
+ copy_v3_v3(r_mat_basis[3], center_global);
+ r_mat_basis[2][3] = -dot_v3v3(axis, center_global);
- if (activeSnap(t) && (!transformModeUseSnap(t) ||
- (t->tsnap.mode & (SCE_SNAP_MODE_INCREMENT | SCE_SNAP_MODE_GRID)))) {
- increment = (t->modifiers & MOD_PRECISION) ? t->snap[1] : t->snap[0];
- }
-
- BLI_assert(axis_idx >= MAN_AXIS_RANGE_ROT_START && axis_idx < MAN_AXIS_RANGE_ROT_END);
- gizmo_get_axis_color(axis_idx, NULL, color, color);
-
- GPU_depth_test(GPU_DEPTH_NONE);
- GPU_blend(GPU_BLEND_ALPHA);
- GPU_line_smooth(true);
-
- ED_gizmotypes_dial_3d_draw_util(mat_basis,
- mat_final,
- line_with,
- color,
- false,
- &(struct Dial3dParams){
- .draw_options = ED_GIZMO_DIAL_DRAW_FLAG_ANGLE_VALUE,
- .angle_delta = t->values_final[0],
- .angle_increment = increment,
- });
-
- GPU_line_smooth(false);
- GPU_depth_test(GPU_DEPTH_LESS_EQUAL);
- GPU_blend(GPU_BLEND_NONE);
+ if (ED_view3d_win_to_3d_on_plane(region, axis, mval_init, false, r_mat_basis[1])) {
+ sub_v3_v3(r_mat_basis[1], center_global);
+ normalize_v3(r_mat_basis[1]);
+ cross_v3_v3v3(r_mat_basis[0], r_mat_basis[1], r_mat_basis[2]);
+ }
+ else {
+ /* The plane and the mouse direction are parallel.
+ * Calculate a matrix orthogonal to the axis. */
+ ortho_basis_v3v3_v3(r_mat_basis[0], r_mat_basis[1], r_mat_basis[2]);
}
+
+ r_mat_basis[0][3] = 0.0f;
+ r_mat_basis[1][3] = 0.0f;
+ r_mat_basis[2][3] = 0.0f;
+ r_mat_basis[3][3] = 1.0f;
}
/** \} */
@@ -1374,6 +1308,23 @@ void drawDial3d(const TransInfo *t)
/** \name Transform Gizmo
* \{ */
+/** Scale of the two-axis planes. */
+#define MAN_AXIS_SCALE_PLANE_SCALE 0.07f
+/** Offset of the two-axis planes, depends on the gizmos scale. Define to avoid repeating. */
+#define MAN_AXIS_SCALE_PLANE_OFFSET 7.0f
+
+static void rotation_get_fn(const wmGizmo *UNUSED(gz), wmGizmoProperty *gz_prop, void *value)
+{
+ const GizmoGroup *ggd = (const GizmoGroup *)gz_prop->custom_func.user_data;
+ *(float *)value = ggd->rotation;
+}
+
+static void rotation_set_fn(const wmGizmo *UNUSED(gz), wmGizmoProperty *gz_prop, const void *value)
+{
+ GizmoGroup *ggd = (GizmoGroup *)gz_prop->custom_func.user_data;
+ ggd->rotation = *(const float *)value;
+}
+
static GizmoGroup *gizmogroup_init(wmGizmoGroup *gzgroup)
{
GizmoGroup *ggd;
@@ -1384,6 +1335,9 @@ static GizmoGroup *gizmogroup_init(wmGizmoGroup *gzgroup)
const wmGizmoType *gzt_dial = WM_gizmotype_find("GIZMO_GT_dial_3d", true);
const wmGizmoType *gzt_prim = WM_gizmotype_find("GIZMO_GT_primitive_3d", true);
+ wmGizmoPropertyFnParams params = {
+ .value_get_fn = rotation_get_fn, .value_set_fn = rotation_set_fn, .user_data = ggd};
+
#define GIZMO_NEW_ARROW(v, draw_style) \
{ \
ggd->gizmos[v] = WM_gizmo_new_ptr(gzt_arrow, gzgroup, NULL); \
@@ -1394,6 +1348,7 @@ static GizmoGroup *gizmogroup_init(wmGizmoGroup *gzgroup)
{ \
ggd->gizmos[v] = WM_gizmo_new_ptr(gzt_dial, gzgroup, NULL); \
RNA_enum_set(ggd->gizmos[v]->ptr, "draw_options", draw_options); \
+ WM_gizmo_target_property_def_func(ggd->gizmos[v], "offset", &params); \
} \
((void)0)
#define GIZMO_NEW_PRIM(v, draw_style) \
@@ -1461,18 +1416,104 @@ static int gizmo_modal(bContext *C,
ARegion *region = CTX_wm_region(C);
RegionView3D *rv3d = region->regiondata;
- struct TransformBounds tbounds;
-
- if (ED_transform_calc_gizmo_stats(C,
- &(struct TransformCalcParams){
- .use_only_center = true,
- },
- &tbounds)) {
- gizmo_prepare_mat(C, rv3d, &tbounds);
- WM_gizmo_set_matrix_location(widget, rv3d->twmat[3]);
+ wmGizmoGroup *gzgroup = widget->parent_gzgroup;
+
+ /* Recalculating the orientation has two problems.
+ * - The matrix calculated based on the transformed selection may not match the matrix
+ * that was set when transform started.
+ * - Inspecting the selection for every update is expensive (for *every* redraw).
+ *
+ * Instead, use #transform_apply_matrix to transform `rv3d->twmat` or the final scale value
+ * when scaling.
+ */
+ if (false) {
+ struct TransformBounds tbounds;
+
+ if (ED_transform_calc_gizmo_stats(C,
+ &(struct TransformCalcParams){
+ .use_only_center = true,
+ },
+ &tbounds)) {
+ gizmo_prepare_mat(C, rv3d, &tbounds);
+ for (wmGizmo *gz = gzgroup->gizmos.first; gz; gz = gz->next) {
+ WM_gizmo_set_matrix_location(gz, rv3d->twmat[3]);
+ }
+ }
}
+ else {
+ GizmoGroup *ggd = gzgroup->customdata;
+
+ short axis_type = 0;
+ MAN_ITER_AXES_BEGIN (axis, axis_idx) {
+ if (axis == widget) {
+ axis_type = gizmo_get_axis_type(axis_idx);
+ break;
+ }
+ }
+ MAN_ITER_AXES_END;
+
+ /* Showing axes which aren't being manipulated doesn't always work so well.
+ *
+ * For rotate: global axis will reset after finish.
+ * Also, gimbal axis isn't properly recalculated while transforming.
+ */
+ if (axis_type == MAN_AXES_ROTATE) {
+ MAN_ITER_AXES_BEGIN (axis, axis_idx) {
+ if (axis == widget) {
+ continue;
+ }
+
+ bool is_plane_dummy;
+ const uint aidx_norm = gizmo_orientation_axis(axis_idx, &is_plane_dummy);
+ /* Always show the axis-aligned handle as it's distracting when it's disabled. */
+ if (aidx_norm == 3) {
+ continue;
+ }
+ WM_gizmo_set_flag(axis, WM_GIZMO_HIDDEN, true);
+ }
+ MAN_ITER_AXES_END;
+ }
- ED_region_tag_redraw_editor_overlays(region);
+ wmWindow *win = CTX_wm_window(C);
+ wmOperator *op = NULL;
+ for (int i = 0; i < widget->op_data_len; i++) {
+ wmGizmoOpElem *gzop = WM_gizmo_operator_get(widget, i);
+ op = WM_operator_find_modal_by_type(win, gzop->type);
+ if (op != NULL) {
+ break;
+ }
+ }
+
+ if (op != NULL) {
+ float twmat[4][4];
+ float scale_buf[3];
+ float *scale = NULL;
+ bool update = false;
+ copy_m4_m4(twmat, rv3d->twmat);
+
+ if (axis_type == MAN_AXES_SCALE) {
+ scale = scale_buf;
+ transform_final_value_get(op->customdata, scale, 3);
+ update = true;
+ }
+ else if (axis_type == MAN_AXES_ROTATE) {
+ transform_final_value_get(op->customdata, &ggd->rotation, 1);
+ if (widget != ggd->gizmos[MAN_AXIS_ROT_C]) {
+ ggd->rotation *= -1;
+ }
+ RNA_float_set(
+ widget->ptr, "incremental_angle", transform_snap_increment_get(op->customdata));
+ }
+ else if (transform_apply_matrix(op->customdata, twmat)) {
+ update = true;
+ }
+
+ if (update) {
+ gizmo_refresh_from_matrix(gzgroup, twmat, scale);
+ ED_region_tag_redraw_editor_overlays(region);
+ }
+ }
+ }
return OPERATOR_RUNNING_MODAL;
}
@@ -1524,9 +1565,8 @@ static void gizmogroup_init_properties_from_twtype(wmGizmoGroup *gzgroup)
case MAN_AXIS_SCALE_XY:
case MAN_AXIS_SCALE_YZ:
case MAN_AXIS_SCALE_ZX: {
- const float ofs_ax = 7.0f;
- const float ofs[3] = {ofs_ax, ofs_ax, 0.0f};
- WM_gizmo_set_scale(axis, 0.07f);
+ const float ofs[3] = {MAN_AXIS_SCALE_PLANE_OFFSET, MAN_AXIS_SCALE_PLANE_OFFSET, 0.0f};
+ WM_gizmo_set_scale(axis, MAN_AXIS_SCALE_PLANE_SCALE);
WM_gizmo_set_matrix_offset_location(axis, ofs);
WM_gizmo_set_flag(axis, WM_GIZMO_DRAW_OFFSET_SCALE, true);
break;
@@ -1638,46 +1678,23 @@ static void WIDGETGROUP_gizmo_setup(const bContext *C, wmGizmoGroup *gzgroup)
gizmogroup_init_properties_from_twtype(gzgroup);
}
-static void WIDGETGROUP_gizmo_refresh(const bContext *C, wmGizmoGroup *gzgroup)
+/**
+ * Set properties for axes.
+ *
+ * \param twmat: The transform matrix (typically #RegionView3D.twmat).
+ * \param scale: Optional scale, to show scale while modally dragging the scale handles.
+ */
+static void gizmo_refresh_from_matrix(wmGizmoGroup *gzgroup,
+ const float twmat[4][4],
+ const float scale[3])
{
GizmoGroup *ggd = gzgroup->customdata;
- Scene *scene = CTX_data_scene(C);
- ScrArea *area = CTX_wm_area(C);
- View3D *v3d = area->spacedata.first;
- ARegion *region = CTX_wm_region(C);
- RegionView3D *rv3d = region->regiondata;
- struct TransformBounds tbounds;
-
- if (ggd->use_twtype_refresh) {
- ggd->twtype = v3d->gizmo_show_object & ggd->twtype_init;
- if (ggd->twtype != ggd->twtype_prev) {
- ggd->twtype_prev = ggd->twtype;
- gizmogroup_init_properties_from_twtype(gzgroup);
- }
- }
-
- const int orient_index = BKE_scene_orientation_get_index_from_flag(scene, ggd->twtype_init);
-
- /* skip, we don't draw anything anyway */
- if ((ggd->all_hidden = (ED_transform_calc_gizmo_stats(C,
- &(struct TransformCalcParams){
- .use_only_center = true,
- .orientation_index = orient_index + 1,
- },
- &tbounds) == 0))) {
- return;
- }
-
- gizmo_prepare_mat(C, rv3d, &tbounds);
-
- /* *** set properties for axes *** */
MAN_ITER_AXES_BEGIN (axis, axis_idx) {
const short axis_type = gizmo_get_axis_type(axis_idx);
const int aidx_norm = gizmo_orientation_axis(axis_idx, NULL);
- WM_gizmo_set_matrix_location(axis, rv3d->twmat[3]);
-
+ WM_gizmo_set_matrix_location(axis, twmat[3]);
switch (axis_idx) {
case MAN_AXIS_TRANS_X:
case MAN_AXIS_TRANS_Y:
@@ -1690,8 +1707,17 @@ static void WIDGETGROUP_gizmo_refresh(const bContext *C, wmGizmoGroup *gzgroup)
gizmo_line_range(ggd->twtype, axis_type, &start_co[2], &len);
- WM_gizmo_set_matrix_rotation_from_z_axis(axis, rv3d->twmat[aidx_norm]);
- RNA_float_set(axis->ptr, "length", len);
+ const float *z_axis = twmat[aidx_norm];
+ if (axis_type == MAN_AXES_SCALE) {
+ /* Scale handles are cubes that don't look right when not aligned with other axes.
+ * This is noticeable when the axis is rotated to something besides the global-axis. */
+ const int aidx_norm_y = (aidx_norm + 2) % 3;
+ const float *y_axis = twmat[aidx_norm_y];
+ WM_gizmo_set_matrix_rotation_from_yz_axis(axis, y_axis, z_axis);
+ }
+ else {
+ WM_gizmo_set_matrix_rotation_from_z_axis(axis, z_axis);
+ }
if (axis_idx >= MAN_AXIS_RANGE_TRANS_START && axis_idx < MAN_AXIS_RANGE_TRANS_END) {
if (ggd->twtype & V3D_GIZMO_SHOW_OBJECT_ROTATE) {
@@ -1699,24 +1725,56 @@ static void WIDGETGROUP_gizmo_refresh(const bContext *C, wmGizmoGroup *gzgroup)
start_co[2] += 0.215f;
}
}
+
+ if (scale) {
+ if (axis_type == MAN_AXES_SCALE) {
+ len = ((start_co[2] + len) * scale[aidx_norm]) - start_co[2];
+ }
+ }
+
+ RNA_float_set(axis->ptr, "length", len);
+
WM_gizmo_set_matrix_offset_location(axis, start_co);
+
WM_gizmo_set_flag(axis, WM_GIZMO_DRAW_OFFSET_SCALE, true);
+
break;
}
case MAN_AXIS_ROT_X:
case MAN_AXIS_ROT_Y:
case MAN_AXIS_ROT_Z:
- WM_gizmo_set_matrix_rotation_from_z_axis(axis, rv3d->twmat[aidx_norm]);
- break;
+ case MAN_AXIS_ROT_C: {
+ if (axis_idx != MAN_AXIS_ROT_C) {
+ WM_gizmo_set_matrix_rotation_from_z_axis(axis, twmat[aidx_norm]);
+ }
+
+ /* Remove #ED_GIZMO_DIAL_DRAW_FLAG_ANGLE_VALUE. It is used only for modal drawing. */
+ PropertyRNA *prop = RNA_struct_find_property(axis->ptr, "draw_options");
+ RNA_property_enum_set(axis->ptr,
+ prop,
+ RNA_property_enum_get(axis->ptr, prop) &
+ ~ED_GIZMO_DIAL_DRAW_FLAG_ANGLE_VALUE);
+ } break;
case MAN_AXIS_TRANS_XY:
case MAN_AXIS_TRANS_YZ:
case MAN_AXIS_TRANS_ZX:
case MAN_AXIS_SCALE_XY:
case MAN_AXIS_SCALE_YZ:
case MAN_AXIS_SCALE_ZX: {
- const float *y_axis = rv3d->twmat[aidx_norm - 1 < 0 ? 2 : aidx_norm - 1];
- const float *z_axis = rv3d->twmat[aidx_norm];
+ const int aidx_norm_x = (aidx_norm + 1) % 3;
+ const int aidx_norm_y = (aidx_norm + 2) % 3;
+ const float *y_axis = twmat[aidx_norm_y];
+ const float *z_axis = twmat[aidx_norm];
WM_gizmo_set_matrix_rotation_from_yz_axis(axis, y_axis, z_axis);
+
+ if (axis_type == MAN_AXES_SCALE) {
+ float ofs[3] = {MAN_AXIS_SCALE_PLANE_OFFSET, MAN_AXIS_SCALE_PLANE_OFFSET, 0.0f};
+ if (scale) {
+ ofs[0] *= scale[aidx_norm_x];
+ ofs[1] *= scale[aidx_norm_y];
+ }
+ WM_gizmo_set_matrix_offset_location(axis, ofs);
+ }
break;
}
}
@@ -1733,6 +1791,49 @@ static void WIDGETGROUP_gizmo_refresh(const bContext *C, wmGizmoGroup *gzgroup)
}
}
+static void WIDGETGROUP_gizmo_refresh(const bContext *C, wmGizmoGroup *gzgroup)
+{
+ ARegion *region = CTX_wm_region(C);
+
+ {
+ wmGizmo *gz = WM_gizmomap_get_modal(region->gizmo_map);
+ if (gz && gz->parent_gzgroup == gzgroup) {
+ return;
+ }
+ }
+
+ GizmoGroup *ggd = gzgroup->customdata;
+ Scene *scene = CTX_data_scene(C);
+ ScrArea *area = CTX_wm_area(C);
+ View3D *v3d = area->spacedata.first;
+ RegionView3D *rv3d = region->regiondata;
+ struct TransformBounds tbounds;
+
+ if (ggd->use_twtype_refresh) {
+ ggd->twtype = v3d->gizmo_show_object & ggd->twtype_init;
+ if (ggd->twtype != ggd->twtype_prev) {
+ ggd->twtype_prev = ggd->twtype;
+ gizmogroup_init_properties_from_twtype(gzgroup);
+ }
+ }
+
+ const int orient_index = BKE_scene_orientation_get_index_from_flag(scene, ggd->twtype_init);
+
+ /* skip, we don't draw anything anyway */
+ if ((ggd->all_hidden = (ED_transform_calc_gizmo_stats(C,
+ &(struct TransformCalcParams){
+ .use_only_center = true,
+ .orientation_index = orient_index + 1,
+ },
+ &tbounds) == 0))) {
+ return;
+ }
+
+ gizmo_prepare_mat(C, rv3d, &tbounds);
+
+ gizmo_refresh_from_matrix(gzgroup, rv3d->twmat, NULL);
+}
+
static void WIDGETGROUP_gizmo_message_subscribe(const bContext *C,
wmGizmoGroup *gzgroup,
struct wmMsgBus *mbus)
@@ -1756,11 +1857,22 @@ static void WIDGETGROUP_gizmo_draw_prepare(const bContext *C, wmGizmoGroup *gzgr
copy_m3_m4(viewinv_m3, rv3d->viewinv);
float idot[3];
+ /* Re-calculate hidden unless modal. */
+ bool is_modal = false;
+ {
+ wmGizmo *gz = WM_gizmomap_get_modal(region->gizmo_map);
+ if (gz && gz->parent_gzgroup == gzgroup) {
+ is_modal = true;
+ }
+ }
+
/* when looking through a selected camera, the gizmo can be at the
* exact same position as the view, skip so we don't break selection */
if (ggd->all_hidden || fabsf(ED_view3d_pixel_size(rv3d, rv3d->twmat[3])) < 5e-7f) {
MAN_ITER_AXES_BEGIN (axis, axis_idx) {
- WM_gizmo_set_flag(axis, WM_GIZMO_HIDDEN, true);
+ if (!is_modal) {
+ WM_gizmo_set_flag(axis, WM_GIZMO_HIDDEN, true);
+ }
}
MAN_ITER_AXES_END;
return;
@@ -1771,12 +1883,15 @@ static void WIDGETGROUP_gizmo_draw_prepare(const bContext *C, wmGizmoGroup *gzgr
MAN_ITER_AXES_BEGIN (axis, axis_idx) {
const short axis_type = gizmo_get_axis_type(axis_idx);
/* XXX maybe unset _HIDDEN flag on redraw? */
-
if (gizmo_is_axis_visible(rv3d, ggd->twtype, idot, axis_type, axis_idx)) {
- WM_gizmo_set_flag(axis, WM_GIZMO_HIDDEN, false);
+ if (!is_modal) {
+ WM_gizmo_set_flag(axis, WM_GIZMO_HIDDEN, false);
+ }
}
else {
- WM_gizmo_set_flag(axis, WM_GIZMO_HIDDEN, true);
+ if (!is_modal) {
+ WM_gizmo_set_flag(axis, WM_GIZMO_HIDDEN, true);
+ }
continue;
}
@@ -1785,13 +1900,15 @@ static void WIDGETGROUP_gizmo_draw_prepare(const bContext *C, wmGizmoGroup *gzgr
WM_gizmo_set_color(axis, color);
WM_gizmo_set_color_highlight(axis, color_hi);
- switch (axis_idx) {
- case MAN_AXIS_TRANS_C:
- case MAN_AXIS_ROT_C:
- case MAN_AXIS_SCALE_C:
- case MAN_AXIS_ROT_T:
- WM_gizmo_set_matrix_rotation_from_z_axis(axis, rv3d->viewinv[2]);
- break;
+ if (!is_modal) {
+ switch (axis_idx) {
+ case MAN_AXIS_TRANS_C:
+ case MAN_AXIS_ROT_C:
+ case MAN_AXIS_SCALE_C:
+ case MAN_AXIS_ROT_T:
+ WM_gizmo_set_matrix_rotation_from_z_axis(axis, rv3d->viewinv[2]);
+ break;
+ }
}
}
MAN_ITER_AXES_END;
@@ -1879,6 +1996,17 @@ static void WIDGETGROUP_gizmo_invoke_prepare(const bContext *C,
}
}
}
+ else if (ELEM(axis_idx, MAN_AXIS_ROT_X, MAN_AXIS_ROT_Y, MAN_AXIS_ROT_Z, MAN_AXIS_ROT_C)) {
+ gizmo_3d_dial_matrixbasis_calc(CTX_wm_region(C),
+ gz->matrix_basis[2],
+ gz->matrix_basis[3],
+ (float[2]){UNPACK2(event->mval)},
+ gz->matrix_basis);
+ PropertyRNA *prop = RNA_struct_find_property(gz->ptr, "draw_options");
+ RNA_property_enum_set(
+ gz->ptr, prop, RNA_property_enum_get(gz->ptr, prop) | ED_GIZMO_DIAL_DRAW_FLAG_ANGLE_VALUE);
+ RNA_float_set(gz->ptr, "incremental_angle", 0.0f);
+ }
}
static bool WIDGETGROUP_gizmo_poll_generic(View3D *v3d)
@@ -1944,8 +2072,8 @@ void VIEW3D_GGT_xform_gizmo(wmGizmoGroupType *gzgt)
gzgt->name = "3D View: Transform Gizmo";
gzgt->idname = "VIEW3D_GGT_xform_gizmo";
- gzgt->flag = WM_GIZMOGROUPTYPE_3D | WM_GIZMOGROUPTYPE_DRAW_MODAL_EXCLUDE |
- WM_GIZMOGROUPTYPE_TOOL_FALLBACK_KEYMAP | WM_GIZMOGROUPTYPE_DELAY_REFRESH_FOR_TWEAK;
+ gzgt->flag = WM_GIZMOGROUPTYPE_3D | WM_GIZMOGROUPTYPE_TOOL_FALLBACK_KEYMAP |
+ WM_GIZMOGROUPTYPE_DELAY_REFRESH_FOR_TWEAK;
gzgt->gzmap_params.spaceid = SPACE_VIEW3D;
gzgt->gzmap_params.regionid = RGN_TYPE_WINDOW;