XR: Expose the OpenXR user paths in the event data for XR events

The use-case is to allow an event handler (in C or a plugin) to
distinguish which hand produced the XR event.

The alternative is to register separate actions for each hand (e.g.
"trigger_left" and "trigger_right"), and duplicate the device bindings
(Oculus, HTC Vive, etc) for each action. Other than the problem of code
duplication, this isn't conceptually efficient since "trigger_left" and
"trigger_right" both represent the same event "trigger", and the
identity of the hand that produced that event is just a property of
that event.

Adds two string fields to the XrEventData called user_path and
user_path_other. The user_path_other field will be populated if the
event is a bimanual one (i.e. two-handed). This follows the pattern
used by the rest of the XrEventData struct for bimanual events (e.g.
state, state_other).

Reviewed By: muxed-reality
This commit is contained in:
Shashank Shekhar 2022-05-07 11:39:17 +09:00 committed by Peter Kim
parent 98a04ed452
commit 23be3294ff
3 changed files with 65 additions and 0 deletions

View File

@ -1196,6 +1196,50 @@ static int rna_XrEventData_action_length(PointerRNA *ptr)
# endif
}
static void rna_XrEventData_user_path_get(PointerRNA *ptr, char *r_value)
{
# ifdef WITH_XR_OPENXR
const wmXrActionData *data = ptr->data;
strcpy(r_value, data->user_path);
# else
UNUSED_VARS(ptr);
r_value[0] = '\0';
# endif
}
static int rna_XrEventData_user_path_length(PointerRNA *ptr)
{
# ifdef WITH_XR_OPENXR
const wmXrActionData *data = ptr->data;
return strlen(data->user_path);
# else
UNUSED_VARS(ptr);
return 0;
# endif
}
static void rna_XrEventData_user_path_other_get(PointerRNA *ptr, char *r_value)
{
# ifdef WITH_XR_OPENXR
const wmXrActionData *data = ptr->data;
strcpy(r_value, data->user_path_other);
# else
UNUSED_VARS(ptr);
r_value[0] = '\0';
# endif
}
static int rna_XrEventData_user_path_other_length(PointerRNA *ptr)
{
# ifdef WITH_XR_OPENXR
const wmXrActionData *data = ptr->data;
return strlen(data->user_path_other);
# else
UNUSED_VARS(ptr);
return 0;
# endif
}
static int rna_XrEventData_type_get(PointerRNA *ptr)
{
# ifdef WITH_XR_OPENXR
@ -2402,6 +2446,19 @@ static void rna_def_xr_eventdata(BlenderRNA *brna)
prop, "rna_XrEventData_action_get", "rna_XrEventData_action_length", NULL);
RNA_def_property_ui_text(prop, "Action", "XR action name");
prop = RNA_def_property(srna, "user_path", PROP_STRING, PROP_NONE);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_string_funcs(
prop, "rna_XrEventData_user_path_get", "rna_XrEventData_user_path_length", NULL);
RNA_def_property_ui_text(prop, "User Path", "User path of the action. E.g. \"/user/hand/left\"");
prop = RNA_def_property(srna, "user_path_other", PROP_STRING, PROP_NONE);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_string_funcs(
prop, "rna_XrEventData_user_path_other_get", "rna_XrEventData_user_path_other_length", NULL);
RNA_def_property_ui_text(
prop, "User Path Other", "Other user path, for bimanual actions. E.g. \"/user/hand/right\"");
prop = RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_enum_items(prop, rna_enum_xr_action_types);

View File

@ -812,6 +812,10 @@ typedef struct wmXrActionData {
char action_set[64];
/** Action name. */
char action[64];
/** User path. E.g. "/user/hand/left" */
char user_path[64];
/** Other user path, for bimanual actions. E.g. "/user/hand/right" */
char user_path_other[64];
/** Type. */
eXrActionType type;
/** State. Set appropriately based on type. */

View File

@ -1025,6 +1025,10 @@ static wmXrActionData *wm_xr_session_event_create(const char *action_set_name,
wmXrActionData *data = MEM_callocN(sizeof(wmXrActionData), __func__);
strcpy(data->action_set, action_set_name);
strcpy(data->action, action->name);
strcpy(data->user_path, action->subaction_paths[subaction_idx]);
if (bimanual) {
strcpy(data->user_path_other, action->subaction_paths[subaction_idx_other]);
}
data->type = action->type;
switch (action->type) {