[Bf-blender-cvs] [648350e4564] master: UI: show gizmo while transforming

Campbell Barton noreply at git.blender.org
Sun Jun 5 15:26:00 CEST 2022


Commit: 648350e456490f8d6258e7de9bf94d3a6a34dbb2
Author: Campbell Barton
Date:   Sun Jun 5 23:09:33 2022 +1000
Branches: master
https://developer.blender.org/rB648350e456490f8d6258e7de9bf94d3a6a34dbb2

UI: show gizmo while transforming

When interacting with translate/rotate/scale gizmo, show the gizmo while
it's in use. There are some exceptions to this, as showing all scale
gizmos while scaling causes the gizmos to become large & distracting so
in this case only the gizmo being dragged is shown.

Resolves T63743.

===================================================================

M	source/blender/editors/transform/transform.c
M	source/blender/editors/transform/transform.h
M	source/blender/editors/transform/transform_gizmo_3d.c
M	source/blender/editors/transform/transform_mode_rotate.c
M	source/blender/editors/transform/transform_mode_trackball.c
M	source/blender/editors/transform/transform_mode_translate.c
M	source/blender/windowmanager/WM_api.h
M	source/blender/windowmanager/gizmo/WM_gizmo_api.h
M	source/blender/windowmanager/gizmo/intern/wm_gizmo_map.c
M	source/blender/windowmanager/intern/wm_event_system.c

===================================================================

diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c
index f8793e2a747..25eb80672e3 100644
--- a/source/blender/editors/transform/transform.c
+++ b/source/blender/editors/transform/transform.c
@@ -2054,3 +2054,17 @@ bool checkUseAxisMatrix(TransInfo *t)
 
   return false;
 }
+
+bool transform_apply_matrix(TransInfo *t, float mat[4][4])
+{
+  if (t->transform_matrix != NULL) {
+    t->transform_matrix(t, mat);
+    return true;
+  }
+  return false;
+}
+
+void transform_final_value_get(const TransInfo *t, float *value, const int value_num)
+{
+  memcpy(value, t->values_final, sizeof(float) * value_num);
+}
diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h
index a3df6a44682..d1c2676169d 100644
--- a/source/blender/editors/transform/transform.h
+++ b/source/blender/editors/transform/transform.h
@@ -533,6 +533,13 @@ typedef struct TransInfo {
   /* Event handler function that determines whether the viewport needs to be redrawn. */
   eRedrawFlag (*handleEvent)(struct TransInfo *, const struct wmEvent *);
 
+  /**
+   * Optional callback to transform a single matrix.
+   *
+   * \note used by the gizmo to transform the matrix used to position it.
+   */
+  void (*transform_matrix)(struct TransInfo *t, float mat_xform[4][4]);
+
   /** Constraint Data. */
   TransCon con;
 
@@ -713,6 +720,12 @@ void removeAspectRatio(TransInfo *t, float vec[2]);
  */
 struct wmKeyMap *transform_modal_keymap(struct wmKeyConfig *keyconf);
 
+/**
+ * Transform a single matrix using the current `t->final_values`.
+ */
+bool transform_apply_matrix(TransInfo *t, float mat[4][4]);
+void transform_final_value_get(const TransInfo *t, float *value, int value_num);
+
 /** \} */
 
 /* -------------------------------------------------------------------- */
diff --git a/source/blender/editors/transform/transform_gizmo_3d.c b/source/blender/editors/transform/transform_gizmo_3d.c
index aa8dad2b95f..4499be66d5a 100644
--- a/source/blender/editors/transform/transform_gizmo_3d.c
+++ b/source/blender/editors/transform/transform_gizmo_3d.c
@@ -71,6 +71,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)
@@ -1461,18 +1465,98 @@ 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.
+     * - For scale: showing the other axes isn't so useful and can be distracting
+     *   since the handles can get very big-small.
+     */
+    if (ELEM(axis_type, MAN_AXES_ROTATE, MAN_AXES_SCALE)) {
+      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;
+    }
+
+    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 (transform_apply_matrix(op->customdata, twmat)) {
+        update = true;
+      }
 
-  ED_region_tag_redraw_editor_overlays(region);
+      if (update) {
+        gizmo_refresh_from_matrix(gzgroup, twmat, scale);
+        ED_region_tag_redraw_editor_overlays(region);
+      }
+    }
+  }
 
   return OPERATOR_RUNNING_MODAL;
 }
@@ -1638,46 +1722,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,7 +1751,7 @@ 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]);
+        WM_gizmo_set_matrix_rotation_from_z_axis(axis, twmat[aidx_norm]);
         RNA_float_set(axis->ptr, "length", len);
 
         if (axis_idx >= MAN_AXIS_RANGE_TRANS_START && axis_idx < MAN_AXIS_RANGE_TRANS_END) {
@@ -1700,13 +1761,20 @@ static void WIDGETGROUP_gizmo_refresh(const bContext *C, wmGizmoGroup *gzgroup)
           }
         }
         WM_gizmo_set_matrix_offset_location(axis, start_co);
+
         WM_gizmo_set_flag(axis, WM_GIZMO_DRAW_OFFSET_SCALE, true);
+
+        if (scale) {
+          if (axis_type == MAN_AXES_SCALE) {
+            mul_v3_fl(axis->matrix_basis[2], scale[aidx_norm]);
+          }
+        }
         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]);
+        WM_gizmo_set_matrix_rotation_from_z_axis(axis, twmat[aidx_norm]);
         break;
       case MAN_AXIS_TRANS_XY:
       case MAN_AXIS_TRANS_YZ:
@@ -1714,9 +1782,18 @@ static void WIDGETGROUP_gizmo_refresh(const bContext *C, wmGizmoGroup *gzgroup)
       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_ax

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list