[Bf-blender-cvs] [5370da566eb] xr-dev: XR: Add grab transform operator

Peter Kim noreply at git.blender.org
Tue Feb 22 09:48:26 CET 2022


Commit: 5370da566eb646a8776c0399cf2843171e947a8c
Author: Peter Kim
Date:   Tue Feb 22 16:12:19 2022 +0900
Branches: xr-dev
https://developer.blender.org/rB5370da566eb646a8776c0399cf2843171e947a8c

XR: Add grab transform operator

>From xr-controller-support branch.

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

M	source/blender/windowmanager/xr/intern/wm_xr_operators.c

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

diff --git a/source/blender/windowmanager/xr/intern/wm_xr_operators.c b/source/blender/windowmanager/xr/intern/wm_xr_operators.c
index d32b011ff5f..133c43cb5b4 100644
--- a/source/blender/windowmanager/xr/intern/wm_xr_operators.c
+++ b/source/blender/windowmanager/xr/intern/wm_xr_operators.c
@@ -23,6 +23,7 @@
 #include "DEG_depsgraph.h"
 #include "DEG_depsgraph_query.h"
 
+#include "ED_keyframing.h"
 #include "ED_mesh.h"
 #include "ED_object.h"
 #include "ED_screen.h"
@@ -200,6 +201,30 @@ static void wm_xr_grab_update(wmOperator *op, const wmXrActionData *actiondata)
   }
 }
 
+static bool wm_xr_grab_can_do_bimanual(const wmXrActionData *actiondata, const XrGrabData *data)
+{
+  /* Returns true if: 1) Bimanual interaction is currently occurring (i.e. inputs on both
+   * controllers are pressed) and 2) bimanual interaction occurred on the last update. This second
+   * part is needed to avoid "jumpy" navigation/transform changes when transitioning from
+   * one-handed to two-handed interaction (see #wm_xr_grab_compute/compute_bimanual() for how
+   * navigation/transform deltas are calculated). */
+  return (actiondata->bimanual && data->bimanual_prev);
+}
+
+static bool wm_xr_grab_is_bimanual_ending(const wmXrActionData *actiondata, const XrGrabData *data)
+{
+  return (!actiondata->bimanual && data->bimanual_prev);
+}
+
+static bool wm_xr_grab_is_locked(const XrGrabData *data, const bool bimanual)
+{
+  if (bimanual) {
+    return data->loc_lock && data->rot_lock && data->scale_lock;
+  }
+  /* Ignore scale lock, as one-handed interaction cannot change navigation/transform scale. */
+  return data->loc_lock && data->rot_lock;
+}
+
 static void orient_mat_z_normalized(float R[4][4], const float z_axis[3])
 {
   const float scale = len_v3(R[0]);
@@ -260,6 +285,7 @@ static void wm_xr_grab_compute(const wmXrActionData *actiondata,
                                const XrGrabData *data,
                                const float nav_mat[4][4],
                                const float nav_inv[4][4],
+                               const float ob_inv[4][4],
                                bool reverse,
                                float r_delta[4][4])
 {
@@ -286,6 +312,11 @@ static void wm_xr_grab_compute(const wmXrActionData *actiondata,
         nav_mat, nav_inv, data->loc_lock, data->locz_lock, data->rotz_lock, prev, curr);
   }
 
+  if (ob_inv) {
+    mul_m4_m4m4(prev, ob_inv, prev);
+    mul_m4_m4m4(curr, ob_inv, curr);
+  }
+
   if (reverse) {
     invert_m4(curr);
     mul_m4_m4m4(r_delta, prev, curr);
@@ -312,6 +343,7 @@ static void wm_xr_grab_compute_bimanual(const wmXrActionData *actiondata,
                                         const XrGrabData *data,
                                         const float nav_mat[4][4],
                                         const float nav_inv[4][4],
+                                        const float ob_inv[4][4],
                                         bool reverse,
                                         float r_delta[4][4])
 {
@@ -381,6 +413,11 @@ static void wm_xr_grab_compute_bimanual(const wmXrActionData *actiondata,
         nav_mat, nav_inv, data->loc_lock, data->locz_lock, data->rotz_lock, prev, curr);
   }
 
+  if (ob_inv) {
+    mul_m4_m4m4(prev, ob_inv, prev);
+    mul_m4_m4m4(curr, ob_inv, curr);
+  }
+
   if (reverse) {
     invert_m4(curr);
     mul_m4_m4m4(r_delta, prev, curr);
@@ -420,32 +457,6 @@ static int wm_xr_navigation_grab_exec(bContext *UNUSED(C), wmOperator *UNUSED(op
   return OPERATOR_CANCELLED;
 }
 
-static bool wm_xr_navigation_grab_can_do_bimanual(const wmXrActionData *actiondata,
-                                                  const XrGrabData *data)
-{
-  /* Returns true if: 1) Bimanual interaction is currently occurring (i.e. inputs on both
-   * controllers are pressed) and 2) bimanual interaction occurred on the last update. This second
-   * part is needed to avoid "jumpy" navigation changes when transitioning from one-handed to
-   * two-handed interaction (see #wm_xr_grab_compute/compute_bimanual() for how navigation deltas
-   * are calculated). */
-  return (actiondata->bimanual && data->bimanual_prev);
-}
-
-static bool wm_xr_navigation_grab_is_bimanual_ending(const wmXrActionData *actiondata,
-                                                     const XrGrabData *data)
-{
-  return (!actiondata->bimanual && data->bimanual_prev);
-}
-
-static bool wm_xr_navigation_grab_is_locked(const XrGrabData *data, const bool bimanual)
-{
-  if (bimanual) {
-    return data->loc_lock && data->rot_lock && data->scale_lock;
-  }
-  /* Ignore scale lock, as one-handed interaction cannot change navigation scale. */
-  return data->loc_lock && data->rot_lock;
-}
-
 static void wm_xr_navigation_grab_apply(wmXrData *xr,
                                         const wmXrActionData *actiondata,
                                         const XrGrabData *data,
@@ -467,12 +478,22 @@ static void wm_xr_navigation_grab_apply(wmXrData *xr,
   }
 
   if (bimanual) {
-    wm_xr_grab_compute_bimanual(
-        actiondata, data, need_navinv ? nav_mat : NULL, need_navinv ? nav_inv : NULL, true, delta);
+    wm_xr_grab_compute_bimanual(actiondata,
+                                data,
+                                need_navinv ? nav_mat : NULL,
+                                need_navinv ? nav_inv : NULL,
+                                NULL,
+                                true,
+                                delta);
   }
   else {
-    wm_xr_grab_compute(
-        actiondata, data, need_navinv ? nav_mat : NULL, need_navinv ? nav_inv : NULL, true, delta);
+    wm_xr_grab_compute(actiondata,
+                       data,
+                       need_navinv ? nav_mat : NULL,
+                       need_navinv ? nav_inv : NULL,
+                       NULL,
+                       true,
+                       delta);
   }
 
   mul_m4_m4m4(out, delta, nav_mat);
@@ -526,7 +547,7 @@ static int wm_xr_navigation_grab_modal(bContext *C, wmOperator *op, const wmEven
   wmWindowManager *wm = CTX_wm_manager(C);
   wmXrData *xr = &wm->xr;
 
-  const bool do_bimanual = wm_xr_navigation_grab_can_do_bimanual(actiondata, data);
+  const bool do_bimanual = wm_xr_grab_can_do_bimanual(actiondata, data);
 
   data->loc_lock = RNA_boolean_get(op->ptr, "lock_location");
   data->locz_lock = RNA_boolean_get(op->ptr, "lock_location_z");
@@ -535,10 +556,10 @@ static int wm_xr_navigation_grab_modal(bContext *C, wmOperator *op, const wmEven
   data->scale_lock = RNA_boolean_get(op->ptr, "lock_scale");
 
   /* Check if navigation is locked. */
-  if (!wm_xr_navigation_grab_is_locked(data, do_bimanual)) {
+  if (!wm_xr_grab_is_locked(data, do_bimanual)) {
     /* Prevent unwanted snapping (i.e. "jumpy" navigation changes when transitioning from
      * two-handed to one-handed interaction) at the end of a bimanual interaction. */
-    if (!wm_xr_navigation_grab_is_bimanual_ending(actiondata, data)) {
+    if (!wm_xr_grab_is_bimanual_ending(actiondata, data)) {
       wm_xr_navigation_grab_apply(xr, actiondata, data, do_bimanual);
     }
   }
@@ -1903,6 +1924,454 @@ static void WM_OT_xr_select_raycast(wmOperatorType *ot)
 
 /** \} */
 
+/* -------------------------------------------------------------------- */
+/** \name XR Transform Grab
+ *
+ * Transforms selected objects relative to an XR controller's pose.
+ * \{ */
+
+static int wm_xr_transform_grab_invoke(bContext *C, wmOperator *op, const wmEvent *event)
+{
+  if (!wm_xr_operator_test_event(op, event)) {
+    return OPERATOR_PASS_THROUGH;
+  }
+
+  bool loc_lock, rot_lock, scale_lock;
+  float loc_t, rot_t, loc_ofs_orig[3], rot_ofs_orig[4];
+  bool loc_ofs_set = false;
+  bool rot_ofs_set = false;
+
+  loc_lock = RNA_boolean_get(op->ptr, "location_lock");
+  if (!loc_lock) {
+    loc_t = RNA_float_get(op->ptr, "location_interpolation");
+    PropertyRNA *prop = RNA_struct_find_property(op->ptr, "location_offset");
+    if (prop && RNA_property_is_set(op->ptr, prop)) {
+      RNA_property_float_get_array(op->ptr, prop, loc_ofs_orig);
+      loc_ofs_set = true;
+    }
+  }
+
+  rot_lock = RNA_boolean_get(op->ptr, "rotation_lock");
+  if (!rot_lock) {
+    rot_t = RNA_float_get(op->ptr, "rotation_interpolation");
+    PropertyRNA *prop = RNA_struct_find_property(op->ptr, "rotation_offset");
+    if (prop && RNA_property_is_set(op->ptr, prop)) {
+      float eul[3];
+      RNA_property_float_get_array(op->ptr, prop, eul);
+      eul_to_quat(rot_ofs_orig, eul);
+      normalize_qt(rot_ofs_orig);
+      rot_ofs_set = true;
+    }
+  }
+
+  scale_lock = RNA_boolean_get(op->ptr, "scale_lock");
+
+  if (loc_lock && rot_lock && scale_lock) {
+    return OPERATOR_CANCELLED;
+  }
+
+  const wmXrActionData *actiondata = event->customdata;
+  Object *obedit = CTX_data_edit_object(C);
+  BMEditMesh *em = (obedit && (obedit->type == OB_MESH)) ? BKE_editmesh_from_object(obedit) : NULL;
+  bool selected = false;
+
+  if (em) { /* TODO_XR: Non-mesh objects. */
+    /* Check for selection. */
+    Scene *scene = CTX_data_scene(C);
+    ToolSettings *ts = scene->toolsettings;
+    BMesh *bm = em->bm;
+    BMIter iter;
+    if ((ts->selectmode & SCE_SELECT_FACE) != 0) {
+      BMFace *f;
+      BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
+        if (BM_elem_flag_test(f, BM_ELEM_SELECT)) {
+          selected = true;
+          break;
+        }
+      }
+    }
+    if (!selected) {
+      if ((ts->selectmode & SCE_SELECT_EDGE) != 0) {
+        BMEdge *e;
+        BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
+          if (BM_elem_flag_test(e, BM_ELEM_SELECT)) {
+            selected = true;
+            break;
+          }
+        }
+      }
+      if (!selected) {
+        if ((ts->selectmode & SCE_SELECT_VERTEX) != 0) {
+          BMVert *v;
+          BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
+            if (BM_elem_flag_test(v, BM_ELEM_SELECT)) {
+              selected = true;
+              break;
+            }
+          }
+        }
+      }
+    }
+  }
+  else {
+    float controller_loc[3], controller_rot[4], controller_mat[4][4];
+    float loc_ofs[3], loc_ofs_controller[3], rot_ofs[4], rot_ofs_controller[4],
+        rot_ofs_orig_inv[

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list