[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