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:
authorPeter Kim <pk15950@gmail.com>2022-04-04 10:55:07 +0300
committerPeter Kim <pk15950@gmail.com>2022-04-04 10:55:07 +0300
commit9a808748887f567345e605e2704fb1cd930b4614 (patch)
tree1f2b7068a6c167166983dbd0e2f3402dc36c7f26
parentb0825be786b1fb98e9a446a88c2c7221f949ce10 (diff)
XR: Add dedicated handling/API for VR trackers
Allows for easier testing/debugging of tracker functionality by separating trackers from session controller data. Also, this should make it possible to use controllers and trackers during a VR session simultaneously.
-rw-r--r--source/blender/makesdna/DNA_xr_types.h2
-rw-r--r--source/blender/makesrna/intern/rna_xr.c159
-rw-r--r--source/blender/windowmanager/WM_api.h12
-rw-r--r--source/blender/windowmanager/xr/intern/wm_xr_action.c84
-rw-r--r--source/blender/windowmanager/xr/intern/wm_xr_draw.c31
-rw-r--r--source/blender/windowmanager/xr/intern/wm_xr_intern.h13
-rw-r--r--source/blender/windowmanager/xr/intern/wm_xr_session.c260
7 files changed, 494 insertions, 67 deletions
diff --git a/source/blender/makesdna/DNA_xr_types.h b/source/blender/makesdna/DNA_xr_types.h
index 6097dfcfe7e..e4b92fe885b 100644
--- a/source/blender/makesdna/DNA_xr_types.h
+++ b/source/blender/makesdna/DNA_xr_types.h
@@ -115,6 +115,8 @@ typedef enum eXrPoseFlag {
/* Pose represents controller grip/aim. */
XR_POSE_GRIP = (1 << 0),
XR_POSE_AIM = (1 << 1),
+ /* Pose represents VR tracker. */
+ XR_POSE_TRACKER = (1 << 2),
} eXrPoseFlag;
typedef enum eXrMotionCaptureFlag {
diff --git a/source/blender/makesrna/intern/rna_xr.c b/source/blender/makesrna/intern/rna_xr.c
index db35807b151..65f99166e51 100644
--- a/source/blender/makesrna/intern/rna_xr.c
+++ b/source/blender/makesrna/intern/rna_xr.c
@@ -523,6 +523,29 @@ static void rna_XrActionMapItem_pose_is_controller_aim_set(PointerRNA *ptr, bool
# endif
}
+static bool rna_XrActionMapItem_pose_is_tracker_get(PointerRNA *ptr)
+{
+# ifdef WITH_XR_OPENXR
+ XrActionMapItem *ami = ptr->data;
+ if ((ami->pose_flag & XR_POSE_TRACKER) != 0) {
+ return true;
+ }
+# else
+ UNUSED_VARS(ptr);
+# endif
+ return false;
+}
+
+static void rna_XrActionMapItem_pose_is_tracker_set(PointerRNA *ptr, bool value)
+{
+# ifdef WITH_XR_OPENXR
+ XrActionMapItem *ami = ptr->data;
+ SET_FLAG_FROM_TEST(ami->pose_flag, value, XR_POSE_TRACKER);
+# else
+ UNUSED_VARS(ptr, value);
+# endif
+}
+
static void rna_XrActionMapItem_bindings_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
{
# ifdef WITH_XR_OPENXR
@@ -1048,6 +1071,32 @@ bool rna_XrSessionState_controller_pose_actions_set(bContext *C,
# endif
}
+bool rna_XrSessionState_tracker_pose_action_add(bContext *C,
+ const char *action_set_name,
+ const char *tracker_action_name)
+{
+# ifdef WITH_XR_OPENXR
+ wmWindowManager *wm = CTX_wm_manager(C);
+ return WM_xr_tracker_pose_action_add(&wm->xr, action_set_name, tracker_action_name);
+# else
+ UNUSED_VARS(C, action_set_name, tracker_action_name);
+ return false;
+# endif
+}
+
+bool rna_XrSessionState_tracker_pose_action_remove(bContext *C,
+ const char *action_set_name,
+ const char *tracker_action_name)
+{
+# ifdef WITH_XR_OPENXR
+ wmWindowManager *wm = CTX_wm_manager(C);
+ return WM_xr_tracker_pose_action_remove(&wm->xr, action_set_name, tracker_action_name);
+# else
+ UNUSED_VARS(C, action_set_name, tracker_action_name);
+ return false;
+# endif
+}
+
void rna_XrSessionState_action_state_get(bContext *C,
const char *action_set_name,
const char *action_name,
@@ -1171,6 +1220,32 @@ static void rna_XrSessionState_controller_aim_rotation_get(bContext *C,
# endif
}
+static void rna_XrSessionState_tracker_location_get(bContext *C,
+ const char *user_path,
+ float r_values[3])
+{
+# ifdef WITH_XR_OPENXR
+ const wmWindowManager *wm = CTX_wm_manager(C);
+ WM_xr_session_state_tracker_location_get(&wm->xr, user_path, r_values);
+# else
+ UNUSED_VARS(C, user_path);
+ zero_v3(r_values);
+# endif
+}
+
+static void rna_XrSessionState_tracker_rotation_get(bContext *C,
+ const char *user_path,
+ float r_values[4])
+{
+# ifdef WITH_XR_OPENXR
+ const wmWindowManager *wm = CTX_wm_manager(C);
+ WM_xr_session_state_tracker_rotation_get(&wm->xr, user_path, r_values);
+# else
+ UNUSED_VARS(C, user_path);
+ unit_qt(r_values);
+# endif
+}
+
static void rna_XrSessionState_viewer_pose_location_get(PointerRNA *ptr, float *r_values)
{
# ifdef WITH_XR_OPENXR
@@ -1827,6 +1902,11 @@ static void rna_def_xr_actionmap(BlenderRNA *brna)
RNA_def_property_ui_text(
prop, "Is Controller Aim", "The action poses will be used for the VR controller aims");
+ prop = RNA_def_property(srna, "pose_is_tracker", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_funcs(
+ prop, "rna_XrActionMapItem_pose_is_tracker_get", "rna_XrActionMapItem_pose_is_tracker_set");
+ RNA_def_property_ui_text(prop, "Is Tracker", "The action poses represent a VR tracker");
+
prop = RNA_def_property(srna, "haptic_name", PROP_STRING, PROP_NONE);
RNA_def_property_ui_text(
prop, "Haptic Name", "Name of the haptic action to apply when executing this action");
@@ -2359,6 +2439,42 @@ static void rna_def_xr_session_state(BlenderRNA *brna)
parm = RNA_def_boolean(func, "result", 0, "Result", "");
RNA_def_function_return(func, parm);
+ func = RNA_def_function(
+ srna, "tracker_pose_action_add", "rna_XrSessionState_tracker_pose_action_add");
+ RNA_def_function_ui_description(func, "Add a VR tracker pose to the session");
+ RNA_def_function_flag(func, FUNC_NO_SELF);
+ parm = RNA_def_pointer(func, "context", "Context", "", "");
+ RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED);
+ parm = RNA_def_string(func, "action_set", NULL, MAX_NAME, "Action Set", "Action set name");
+ RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED);
+ parm = RNA_def_string(func,
+ "tracker_action",
+ NULL,
+ MAX_NAME,
+ "Tracker Action",
+ "Name of the action representing the VR tracker");
+ RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED);
+ parm = RNA_def_boolean(func, "result", 0, "Result", "");
+ RNA_def_function_return(func, parm);
+
+ func = RNA_def_function(
+ srna, "tracker_pose_action_remove", "rna_XrSessionState_tracker_pose_action_remove");
+ RNA_def_function_ui_description(func, "Remove a VR tracker pose from the session");
+ RNA_def_function_flag(func, FUNC_NO_SELF);
+ parm = RNA_def_pointer(func, "context", "Context", "", "");
+ RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED);
+ parm = RNA_def_string(func, "action_set", NULL, MAX_NAME, "Action Set", "Action set name");
+ RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED);
+ parm = RNA_def_string(func,
+ "tracker_action",
+ NULL,
+ MAX_NAME,
+ "Tracker Action",
+ "Name of the action representing the VR tracker");
+ RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED);
+ parm = RNA_def_boolean(func, "result", 0, "Result", "");
+ RNA_def_function_return(func, parm);
+
func = RNA_def_function(srna, "action_state_get", "rna_XrSessionState_action_state_get");
RNA_def_function_ui_description(func, "Get the current state of a VR action");
RNA_def_function_flag(func, FUNC_NO_SELF);
@@ -2541,6 +2657,49 @@ static void rna_def_xr_session_state(BlenderRNA *brna)
RNA_def_property_ui_range(parm, -FLT_MAX, FLT_MAX, 1, 5);
RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_OUTPUT);
+ func = RNA_def_function(srna, "tracker_location_get", "rna_XrSessionState_tracker_location_get");
+ RNA_def_function_ui_description(func, "Get the last known tracker location in world space");
+ RNA_def_function_flag(func, FUNC_NO_SELF);
+ parm = RNA_def_pointer(func, "context", "Context", "", "");
+ RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED);
+ parm = RNA_def_string(
+ func, "user_path", NULL, XR_MAX_USER_PATH_LENGTH, "User Path", "OpenXR user path");
+ RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED);
+ parm = RNA_def_float_translation(func,
+ "location",
+ 3,
+ NULL,
+ -FLT_MAX,
+ FLT_MAX,
+ "Location",
+ "Tracker location",
+ -FLT_MAX,
+ FLT_MAX);
+ RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_OUTPUT);
+
+ func = RNA_def_function(srna, "tracker_rotation_get", "rna_XrSessionState_tracker_rotation_get");
+ RNA_def_function_ui_description(
+ func, "Get the last known tracker rotation (quaternion) in world space");
+ RNA_def_function_flag(func, FUNC_NO_SELF);
+ parm = RNA_def_pointer(func, "context", "Context", "", "");
+ RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED);
+ parm = RNA_def_string(
+ func, "user_path", NULL, XR_MAX_USER_PATH_LENGTH, "User Path", "OpenXR user path");
+ RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED);
+ parm = RNA_def_float_vector(func,
+ "rotation",
+ 4,
+ NULL,
+ -FLT_MAX,
+ FLT_MAX,
+ "Rotation",
+ "Tracker quaternion rotation",
+ -FLT_MAX,
+ FLT_MAX);
+ parm->subtype = PROP_QUATERNION;
+ RNA_def_property_ui_range(parm, -FLT_MAX, FLT_MAX, 1, 5);
+ RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_OUTPUT);
+
prop = RNA_def_property(srna, "viewer_pose_location", PROP_FLOAT, PROP_TRANSLATION);
RNA_def_property_array(prop, 3);
RNA_def_property_float_funcs(prop, "rna_XrSessionState_viewer_pose_location_get", NULL, NULL);
diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h
index cf5d082445c..7bb2ce18ef7 100644
--- a/source/blender/windowmanager/WM_api.h
+++ b/source/blender/windowmanager/WM_api.h
@@ -1592,6 +1592,12 @@ bool WM_xr_session_state_controller_aim_location_get(const wmXrData *xr,
bool WM_xr_session_state_controller_aim_rotation_get(const wmXrData *xr,
unsigned int subaction_idx,
float r_rotation[4]);
+bool WM_xr_session_state_tracker_location_get(const wmXrData *xr,
+ const char *subaction_path,
+ float r_location[3]);
+bool WM_xr_session_state_tracker_rotation_get(const wmXrData *xr,
+ const char *subaction_path,
+ float r_rotation[4]);
bool WM_xr_session_state_nav_location_get(const wmXrData *xr, float r_location[3]);
void WM_xr_session_state_nav_location_set(wmXrData *xr, const float location[3]);
bool WM_xr_session_state_nav_rotation_get(const wmXrData *xr, float r_rotation[4]);
@@ -1647,6 +1653,12 @@ bool WM_xr_controller_pose_actions_set(wmXrData *xr,
const char *action_set_name,
const char *grip_action_name,
const char *aim_action_name);
+bool WM_xr_tracker_pose_action_add(wmXrData *xr,
+ const char *action_set_name,
+ const char *tracker_action_name);
+bool WM_xr_tracker_pose_action_remove(wmXrData *xr,
+ const char *action_set_name,
+ const char *tracker_action_name);
/**
* XR action functions to be called post-XR session start.
diff --git a/source/blender/windowmanager/xr/intern/wm_xr_action.c b/source/blender/windowmanager/xr/intern/wm_xr_action.c
index 6750e7a7d77..e45acb5a7b4 100644
--- a/source/blender/windowmanager/xr/intern/wm_xr_action.c
+++ b/source/blender/windowmanager/xr/intern/wm_xr_action.c
@@ -43,6 +43,7 @@ static void action_set_destroy(void *val)
MEM_SAFE_FREE(action_set->name);
+ BLI_freelistN(&action_set->tracker_actions);
BLI_freelistN(&action_set->active_modal_actions);
BLI_freelistN(&action_set->active_haptic_actions);
@@ -200,6 +201,11 @@ void WM_xr_action_set_destroy(wmXrData *xr, const char *action_set_name)
action_set->controller_grip_action = action_set->controller_aim_action = NULL;
}
+ if (!BLI_listbase_is_empty(&action_set->tracker_actions)) {
+ wm_xr_session_tracker_data_clear(session_state);
+ BLI_freelistN(&action_set->tracker_actions);
+ }
+
BLI_freelistN(&action_set->active_modal_actions);
BLI_freelistN(&action_set->active_haptic_actions);
@@ -309,6 +315,14 @@ void WM_xr_action_destroy(wmXrData *xr, const char *action_set_name, const char
action_set->controller_grip_action = action_set->controller_aim_action = NULL;
}
+ LISTBASE_FOREACH (LinkData *, ld, &action_set->tracker_actions) {
+ wmXrAction *tracker_action = ld->data;
+ if (STREQ(tracker_action->name, action_name)) {
+ WM_xr_tracker_pose_action_remove(xr, action_set_name, action_name);
+ break;
+ }
+ }
+
LISTBASE_FOREACH (LinkData *, ld, &action_set->active_modal_actions) {
wmXrAction *active_modal_action = ld->data;
if (STREQ(active_modal_action->name, action_name)) {
@@ -409,6 +423,7 @@ bool WM_xr_active_action_set_set(wmXrData *xr, const char *action_set_name)
xr->runtime->session_state.active_action_set = action_set;
+ /* Update controller/tracker data. */
if (action_set->controller_grip_action && action_set->controller_aim_action) {
wm_xr_session_controller_data_populate(
action_set->controller_grip_action, action_set->controller_aim_action, xr);
@@ -417,6 +432,13 @@ bool WM_xr_active_action_set_set(wmXrData *xr, const char *action_set_name)
wm_xr_session_controller_data_clear(&xr->runtime->session_state);
}
+ if (!BLI_listbase_is_empty(&action_set->tracker_actions)) {
+ wm_xr_session_tracker_data_populate(&action_set->tracker_actions, xr);
+ }
+ else {
+ wm_xr_session_tracker_data_clear(&xr->runtime->session_state);
+ }
+
return true;
}
@@ -462,6 +484,68 @@ bool WM_xr_controller_pose_actions_set(wmXrData *xr,
return true;
}
+bool WM_xr_tracker_pose_action_add(wmXrData *xr,
+ const char *action_set_name,
+ const char *tracker_action_name)
+{
+ wmXrActionSet *action_set = action_set_find(xr, action_set_name);
+ if (!action_set) {
+ return false;
+ }
+
+ wmXrAction *tracker_action = action_find(xr, action_set_name, tracker_action_name);
+ if (!tracker_action) {
+ return false;
+ }
+
+ LinkData *ld = MEM_callocN(sizeof(*ld), __func__);
+ ld->data = tracker_action;
+ BLI_addtail(&action_set->tracker_actions, ld);
+
+ if (action_set == xr->runtime->session_state.active_action_set) {
+ wm_xr_session_tracker_data_populate(&action_set->tracker_actions, xr);
+ }
+
+ return true;
+}
+
+bool WM_xr_tracker_pose_action_remove(wmXrData *xr,
+ const char *action_set_name,
+ const char *tracker_action_name)
+{
+ wmXrActionSet *action_set = action_set_find(xr, action_set_name);
+ if (!action_set) {
+ return false;
+ }
+
+ wmXrAction *tracker_action = action_find(xr, action_set_name, tracker_action_name);
+ if (!tracker_action) {
+ return false;
+ }
+
+ bool removed = false;
+
+ LISTBASE_FOREACH (LinkData *, ld, &action_set->tracker_actions) {
+ wmXrAction *tracker_action = ld->data;
+ if (STREQ(tracker_action->name, tracker_action_name)) {
+ BLI_freelinkN(&action_set->tracker_actions, ld);
+ removed = true;
+ break;
+ }
+ }
+
+ if (action_set == xr->runtime->session_state.active_action_set) {
+ if (BLI_listbase_is_empty(&action_set->tracker_actions)) {
+ wm_xr_session_tracker_data_clear(&xr->runtime->session_state);
+ }
+ else {
+ wm_xr_session_tracker_data_populate(&action_set->tracker_actions, xr);
+ }
+ }
+
+ return removed;
+}
+
bool WM_xr_action_state_get(const wmXrData *xr,
const char *action_set_name,
const char *action_name,
diff --git a/source/blender/windowmanager/xr/intern/wm_xr_draw.c b/source/blender/windowmanager/xr/intern/wm_xr_draw.c
index 303ecca17f0..57d20e5f0c2 100644
--- a/source/blender/windowmanager/xr/intern/wm_xr_draw.c
+++ b/source/blender/windowmanager/xr/intern/wm_xr_draw.c
@@ -225,7 +225,7 @@ static GPUBatch *wm_xr_controller_model_batch_create(GHOST_XrContextHandle xr_co
static void wm_xr_controller_model_draw(const XrSessionSettings *settings,
GHOST_XrContextHandle xr_context,
- wmXrSessionState *state)
+ ListBase *controllers)
{
GHOST_XrControllerModelData model_data;
@@ -244,7 +244,7 @@ static void wm_xr_controller_model_draw(const XrSessionSettings *settings,
GPU_depth_test(GPU_DEPTH_NONE);
GPU_blend(GPU_BLEND_ALPHA);
- LISTBASE_FOREACH (wmXrController *, controller, &state->controllers) {
+ LISTBASE_FOREACH (wmXrController *, controller, controllers) {
GPUBatch *model = controller->model;
if (!model) {
model = controller->model = wm_xr_controller_model_batch_create(xr_context,
@@ -287,7 +287,7 @@ static void wm_xr_controller_model_draw(const XrSessionSettings *settings,
}
}
-static void wm_xr_controller_aim_draw(const XrSessionSettings *settings, wmXrSessionState *state)
+static void wm_xr_controller_aim_draw(const XrSessionSettings *settings, ListBase *controllers)
{
bool draw_ray;
switch (settings->controller_draw_style) {
@@ -320,9 +320,9 @@ static void wm_xr_controller_aim_draw(const XrSessionSettings *settings, wmXrSes
GPU_depth_test(GPU_DEPTH_LESS_EQUAL);
GPU_blend(GPU_BLEND_ALPHA);
- immBegin(GPU_PRIM_LINES, (uint)BLI_listbase_count(&state->controllers) * 2);
+ immBegin(GPU_PRIM_LINES, (uint)BLI_listbase_count(controllers) * 2);
- LISTBASE_FOREACH (wmXrController *, controller, &state->controllers) {
+ LISTBASE_FOREACH (wmXrController *, controller, controllers) {
const float(*mat)[4] = controller->aim_mat;
madd_v3_v3v3fl(ray, mat[3], mat[2], -scale);
@@ -344,9 +344,9 @@ static void wm_xr_controller_aim_draw(const XrSessionSettings *settings, wmXrSes
GPU_depth_test(GPU_DEPTH_NONE);
GPU_blend(GPU_BLEND_NONE);
- immBegin(GPU_PRIM_LINES, (uint)BLI_listbase_count(&state->controllers) * 6);
+ immBegin(GPU_PRIM_LINES, (uint)BLI_listbase_count(controllers) * 6);
- LISTBASE_FOREACH (wmXrController *, controller, &state->controllers) {
+ LISTBASE_FOREACH (wmXrController *, controller, controllers) {
const float(*mat)[4] = controller->aim_mat;
madd_v3_v3v3fl(x_axis, mat[3], mat[0], scale);
madd_v3_v3v3fl(y_axis, mat[3], mat[1], scale);
@@ -379,8 +379,19 @@ void wm_xr_draw_controllers(const bContext *UNUSED(C), ARegion *UNUSED(region),
wmXrData *xr = customdata;
const XrSessionSettings *settings = &xr->session_settings;
GHOST_XrContextHandle xr_context = xr->runtime->context;
- wmXrSessionState *state = &xr->runtime->session_state;
+ ListBase *controllers = &xr->runtime->session_state.controllers;
- wm_xr_controller_model_draw(settings, xr_context, state);
- wm_xr_controller_aim_draw(settings, state);
+ wm_xr_controller_model_draw(settings, xr_context, controllers);
+ wm_xr_controller_aim_draw(settings, controllers);
+}
+
+void wm_xr_draw_trackers(const bContext *UNUSED(C), ARegion *UNUSED(region), void *customdata)
+{
+ wmXrData *xr = customdata;
+ const XrSessionSettings *settings = &xr->session_settings;
+ GHOST_XrContextHandle xr_context = xr->runtime->context;
+ ListBase *trackers = &xr->runtime->session_state.trackers;
+
+ wm_xr_controller_model_draw(settings, xr_context, trackers);
+ wm_xr_controller_aim_draw(settings, trackers);
}
diff --git a/source/blender/windowmanager/xr/intern/wm_xr_intern.h b/source/blender/windowmanager/xr/intern/wm_xr_intern.h
index c493deba7e4..4de28f43213 100644
--- a/source/blender/windowmanager/xr/intern/wm_xr_intern.h
+++ b/source/blender/windowmanager/xr/intern/wm_xr_intern.h
@@ -52,6 +52,8 @@ typedef struct wmXrSessionState {
/** Last known controller data. */
ListBase controllers; /* #wmXrController */
+ /** Last known tracker data. */
+ ListBase trackers; /* #wmXrController */
/** The currently active action set that will be updated on calls to
* wm_xr_session_actions_update(). If NULL, all action sets will be treated as active and
@@ -92,6 +94,8 @@ typedef struct {
struct ARegionType *controller_art;
/** Controller draw callback handle. */
void *controller_draw_handle;
+ /** Tracker draw callback handle. */
+ void *tracker_draw_handle;
} wmXrSurfaceData;
typedef struct wmXrDrawData {
@@ -176,11 +180,13 @@ typedef struct wmXrActionSet {
/** XR pose actions that determine the controller grip/aim transforms. */
wmXrAction *controller_grip_action;
wmXrAction *controller_aim_action;
+ /** XR pose actions that determine tracker transforms. */
+ ListBase tracker_actions; /* #LinkData */
/** Currently active modal actions. */
- ListBase active_modal_actions;
+ ListBase active_modal_actions; /* #LinkData */
/** Currently active haptic actions. */
- ListBase active_haptic_actions;
+ ListBase active_haptic_actions; /* wmXrHapticAction */
} wmXrActionSet;
typedef struct wmXrMotionCapturePose {
@@ -223,6 +229,8 @@ void wm_xr_session_controller_data_populate(const wmXrAction *grip_action,
const wmXrAction *aim_action,
wmXrData *xr);
void wm_xr_session_controller_data_clear(wmXrSessionState *state);
+void wm_xr_session_tracker_data_populate(const ListBase *tracker_actions, wmXrData *xr);
+void wm_xr_session_tracker_data_clear(wmXrSessionState *state);
/* wm_xr_draw.c */
void wm_xr_pose_to_mat(const GHOST_XrPose *pose, float r_mat[4][4]);
@@ -237,6 +245,7 @@ void wm_xr_pose_scale_to_imat(const GHOST_XrPose *pose, float scale, float r_ima
*/
void wm_xr_draw_view(const GHOST_XrDrawViewInfo *draw_view, void *customdata);
void wm_xr_draw_controllers(const struct bContext *C, struct ARegion *region, void *customdata);
+void wm_xr_draw_trackers(const struct bContext *C, struct ARegion *region, void *customdata);
/* wm_xr_mocap.c */
void wm_xr_mocap_orig_poses_store(const XrSessionSettings *settings, wmXrSessionState *state);
diff --git a/source/blender/windowmanager/xr/intern/wm_xr_session.c b/source/blender/windowmanager/xr/intern/wm_xr_session.c
index 7c6caaa876e..09cbea56b69 100644
--- a/source/blender/windowmanager/xr/intern/wm_xr_session.c
+++ b/source/blender/windowmanager/xr/intern/wm_xr_session.c
@@ -75,22 +75,21 @@ static void wm_xr_session_create_cb(void)
wm_xr_mocap_orig_poses_store(settings, state);
}
-static void wm_xr_session_controller_data_free(wmXrSessionState *state)
+static void wm_xr_session_controller_data_free(ListBase *controllers)
{
- ListBase *lb = &state->controllers;
wmXrController *c;
-
- while ((c = BLI_pophead(lb))) {
+ while ((c = BLI_pophead(controllers))) {
if (c->model) {
GPU_batch_discard(c->model);
}
- BLI_freelinkN(lb, c);
+ BLI_freelinkN(controllers, c);
}
}
void wm_xr_session_data_free(wmXrSessionState *state)
{
- wm_xr_session_controller_data_free(state);
+ wm_xr_session_controller_data_free(&state->controllers);
+ wm_xr_session_controller_data_free(&state->trackers);
BLI_freelistN(&state->mocap_orig_poses);
}
@@ -509,6 +508,48 @@ bool WM_xr_session_state_controller_aim_rotation_get(const wmXrData *xr,
return true;
}
+bool WM_xr_session_state_tracker_location_get(const wmXrData *xr,
+ const char *subaction_path,
+ float r_location[3])
+{
+ if (!WM_xr_session_is_ready(xr) || !xr->runtime->session_state.is_view_data_set) {
+ zero_v3(r_location);
+ return false;
+ }
+
+ const wmXrController *tracker = BLI_findstring(&xr->runtime->session_state.trackers,
+ subaction_path,
+ offsetof(wmXrController, subaction_path));
+ if (!tracker) {
+ zero_v3(r_location);
+ return false;
+ }
+
+ copy_v3_v3(r_location, tracker->grip_pose.position);
+ return true;
+}
+
+bool WM_xr_session_state_tracker_rotation_get(const wmXrData *xr,
+ const char *subaction_path,
+ float r_rotation[4])
+{
+ if (!WM_xr_session_is_ready(xr) || !xr->runtime->session_state.is_view_data_set) {
+ unit_qt(r_rotation);
+ return false;
+ }
+
+ const wmXrController *tracker = BLI_findstring(&xr->runtime->session_state.trackers,
+ subaction_path,
+ offsetof(wmXrController, subaction_path));
+ if (!tracker) {
+ unit_qt(r_rotation);
+ return false;
+ }
+
+ copy_qt_qt(r_rotation, tracker->grip_pose.orientation_quat);
+ return true;
+}
+
bool WM_xr_session_state_nav_location_get(const wmXrData *xr, float r_location[3])
{
if (!WM_xr_session_is_ready(xr) || !xr->runtime->session_state.is_view_data_set) {
@@ -618,14 +659,70 @@ static void wm_xr_session_controller_pose_calc(const GHOST_XrPose *raw_pose,
static void wm_xr_session_controller_data_update(const wmXrAction *grip_action,
const wmXrAction *aim_action,
+ unsigned int subaction_idx,
+ const float view_ofs[3],
+ const float base_mat[4][4],
+ const float nav_mat[4][4],
bContext *C,
XrSessionSettings *settings,
GHOST_XrContextHandle xr_context,
- wmXrSessionState *state,
- wmWindow *win)
+ Scene *scene,
+ ViewLayer *view_layer,
+ wmWindow *win,
+ bScreen *screen_anim,
+ bool *notify,
+ wmXrController *controller)
+{
+ wm_xr_session_controller_pose_calc(&((GHOST_XrPose *)grip_action->states)[subaction_idx],
+ view_ofs,
+ base_mat,
+ nav_mat,
+ &controller->grip_pose,
+ controller->grip_mat,
+ controller->grip_mat_base);
+ wm_xr_session_controller_pose_calc(&((GHOST_XrPose *)aim_action->states)[subaction_idx],
+ view_ofs,
+ base_mat,
+ nav_mat,
+ &controller->aim_pose,
+ controller->aim_mat,
+ controller->aim_mat_base);
+
+ /* Update motion capture objects. */
+ wm_xr_mocap_objects_update(controller->subaction_path,
+ &controller->grip_pose,
+ C,
+ settings,
+ scene,
+ view_layer,
+ win,
+ screen_anim,
+ notify);
+
+ /* Update controller model. */
+ if (!controller->model) {
+ /* Notify GHOST to load/continue loading the controller model data. This can be called more
+ * than once since the model may not be available from the runtime yet. The batch itself will
+ * be created in wm_xr_draw_controllers(). */
+ GHOST_XrLoadControllerModel(xr_context, controller->subaction_path);
+ }
+ else {
+ GHOST_XrUpdateControllerModelComponents(xr_context, controller->subaction_path);
+ }
+}
+
+static void wm_xr_session_controller_and_tracker_data_update(const wmXrAction *grip_action,
+ const wmXrAction *aim_action,
+ const ListBase *tracker_actions,
+ bContext *C,
+ XrSessionSettings *settings,
+ GHOST_XrContextHandle xr_context,
+ wmXrSessionState *state,
+ wmWindow *win)
{
BLI_assert(grip_action->count_subaction_paths == aim_action->count_subaction_paths);
BLI_assert(grip_action->count_subaction_paths == BLI_listbase_count(&state->controllers));
+ BLI_assert(BLI_listbase_count(tracker_actions) <= BLI_listbase_count(&state->trackers));
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
@@ -633,6 +730,7 @@ static void wm_xr_session_controller_data_update(const wmXrAction *grip_action,
bScreen *screen_anim = ED_screen_animation_playing(wm);
bool notify = true;
unsigned int subaction_idx = 0;
+ wmXrController *tracker = state->trackers.first;
float view_ofs[3], base_mat[4][4], nav_mat[4][4];
if ((settings->flag & XR_SESSION_USE_POSITION_TRACKING) == 0) {
@@ -648,42 +746,47 @@ static void wm_xr_session_controller_data_update(const wmXrAction *grip_action,
wm_xr_pose_scale_to_mat(&state->prev_base_pose, state->prev_base_scale, base_mat);
wm_xr_pose_scale_to_mat(&state->nav_pose, state->nav_scale, nav_mat);
+ /* Update controllers. */
LISTBASE_FOREACH_INDEX (wmXrController *, controller, &state->controllers, subaction_idx) {
- wm_xr_session_controller_pose_calc(&((GHOST_XrPose *)grip_action->states)[subaction_idx],
- view_ofs,
- base_mat,
- nav_mat,
- &controller->grip_pose,
- controller->grip_mat,
- controller->grip_mat_base);
- wm_xr_session_controller_pose_calc(&((GHOST_XrPose *)aim_action->states)[subaction_idx],
- view_ofs,
- base_mat,
- nav_mat,
- &controller->aim_pose,
- controller->aim_mat,
- controller->aim_mat_base);
-
- /* Update motion capture objects. */
- wm_xr_mocap_objects_update(controller->subaction_path,
- &controller->grip_pose,
- C,
- settings,
- scene,
- view_layer,
- win,
- screen_anim,
- &notify);
-
- /* Update controller model. */
- if (!controller->model) {
- /* Notify GHOST to load/continue loading the controller model data. This can be called more
- * than once since the model may not be available from the runtime yet. The batch itself will
- * be created in wm_xr_draw_controllers(). */
- GHOST_XrLoadControllerModel(xr_context, controller->subaction_path);
- }
- else {
- GHOST_XrUpdateControllerModelComponents(xr_context, controller->subaction_path);
+ wm_xr_session_controller_data_update(grip_action,
+ aim_action,
+ subaction_idx,
+ view_ofs,
+ base_mat,
+ nav_mat,
+ C,
+ settings,
+ xr_context,
+ scene,
+ view_layer,
+ win,
+ screen_anim,
+ &notify,
+ controller);
+ }
+
+ /* Update trackers. */
+ LISTBASE_FOREACH (LinkData *, ld, tracker_actions) {
+ const wmXrAction *tracker_action = ld->data;
+
+ for (subaction_idx = 0; subaction_idx < tracker_action->count_subaction_paths;
+ ++subaction_idx) {
+ wm_xr_session_controller_data_update(tracker_action,
+ tracker_action,
+ subaction_idx,
+ view_ofs,
+ base_mat,
+ nav_mat,
+ C,
+ settings,
+ xr_context,
+ scene,
+ view_layer,
+ win,
+ screen_anim,
+ &notify,
+ tracker);
+ tracker = tracker->next;
}
}
}
@@ -1244,14 +1347,16 @@ void wm_xr_session_actions_update(const bContext *C)
/* Only update controller data and dispatch events for active action set. */
if (active_action_set) {
- if (active_action_set->controller_grip_action && active_action_set->controller_aim_action) {
- wm_xr_session_controller_data_update(active_action_set->controller_grip_action,
- active_action_set->controller_aim_action,
- (bContext *)C,
- settings,
- xr_context,
- state,
- win);
+ if ((active_action_set->controller_grip_action && active_action_set->controller_aim_action) ||
+ !BLI_listbase_is_empty(&active_action_set->tracker_actions)) {
+ wm_xr_session_controller_and_tracker_data_update(active_action_set->controller_grip_action,
+ active_action_set->controller_aim_action,
+ &active_action_set->tracker_actions,
+ (bContext *)C,
+ settings,
+ xr_context,
+ state,
+ win);
}
if (win) {
@@ -1273,15 +1378,13 @@ void wm_xr_session_controller_data_populate(const wmXrAction *grip_action,
wmXrSessionState *state = &xr->runtime->session_state;
ListBase *controllers = &state->controllers;
-
BLI_assert(grip_action->count_subaction_paths == aim_action->count_subaction_paths);
const unsigned int count = grip_action->count_subaction_paths;
- wm_xr_session_controller_data_free(state);
+ wm_xr_session_controller_data_free(controllers);
for (unsigned int i = 0; i < count; ++i) {
wmXrController *controller = MEM_callocN(sizeof(*controller), __func__);
-
BLI_assert(STREQ(grip_action->subaction_paths[i], aim_action->subaction_paths[i]));
strcpy(controller->subaction_path, grip_action->subaction_paths[i]);
@@ -1302,7 +1405,7 @@ void wm_xr_session_controller_data_populate(const wmXrAction *grip_action,
void wm_xr_session_controller_data_clear(wmXrSessionState *state)
{
- wm_xr_session_controller_data_free(state);
+ wm_xr_session_controller_data_free(&state->controllers);
/* Deactivate draw callback. */
if (g_xr_surface) {
@@ -1316,6 +1419,53 @@ void wm_xr_session_controller_data_clear(wmXrSessionState *state)
}
}
+void wm_xr_session_tracker_data_populate(const ListBase *tracker_actions, wmXrData *xr)
+{
+ wmXrSessionState *state = &xr->runtime->session_state;
+ ListBase *trackers = &state->trackers;
+
+ wm_xr_session_controller_data_free(trackers);
+
+ LISTBASE_FOREACH (const LinkData *, ld, tracker_actions) {
+ const wmXrAction *tracker_action = ld->data;
+
+ for (unsigned int subaction_idx = 0; subaction_idx < tracker_action->count_subaction_paths;
+ ++subaction_idx) {
+ wmXrController *tracker = MEM_callocN(sizeof(*tracker), __func__);
+ strcpy(tracker->subaction_path, tracker_action->subaction_paths[subaction_idx]);
+
+ BLI_addtail(trackers, tracker);
+ }
+ }
+
+ /* Activate draw callback. */
+ if (g_xr_surface) {
+ wmXrSurfaceData *surface_data = g_xr_surface->customdata;
+ if (surface_data && !surface_data->tracker_draw_handle) {
+ if (surface_data->controller_art) {
+ surface_data->tracker_draw_handle = ED_region_draw_cb_activate(
+ surface_data->controller_art, wm_xr_draw_trackers, xr, REGION_DRAW_POST_VIEW);
+ }
+ }
+ }
+}
+
+void wm_xr_session_tracker_data_clear(wmXrSessionState *state)
+{
+ wm_xr_session_controller_data_free(&state->trackers);
+
+ /* Deactivate draw callback. */
+ if (g_xr_surface) {
+ wmXrSurfaceData *surface_data = g_xr_surface->customdata;
+ if (surface_data && surface_data->tracker_draw_handle) {
+ if (surface_data->controller_art) {
+ ED_region_draw_cb_exit(surface_data->controller_art, surface_data->tracker_draw_handle);
+ }
+ surface_data->tracker_draw_handle = NULL;
+ }
+ }
+}
+
/** \} */ /* XR-Session Actions */
/* -------------------------------------------------------------------- */