d/ohmd: Support generic trackers and clean up

This commit is contained in:
Christoph Haag 2023-01-12 00:49:29 +01:00 committed by Jakob Bornecrantz
parent dcbdcede5a
commit 2be4cbf4c3

View file

@ -48,8 +48,10 @@ enum input_indices
// khronos simple inputs for generic controllers // khronos simple inputs for generic controllers
SIMPLE_SELECT_CLICK = 0, SIMPLE_SELECT_CLICK = 0,
SIMPLE_MENU_CLICK, SIMPLE_MENU_CLICK,
SIMPLE_GRIP_POSE,
SIMPLE_AIM_POSE, // use same input field for touch controller, simple controller, and tracker
GRIP_POSE,
AIM_POSE,
// longest list of aliased enums has to start last for INPUT_INDICES_LAST to get the biggest value // longest list of aliased enums has to start last for INPUT_INDICES_LAST to get the biggest value
OCULUS_TOUCH_X_CLICK = 0, OCULUS_TOUCH_X_CLICK = 0,
@ -69,8 +71,6 @@ enum input_indices
OCULUS_TOUCH_THUMBSTICK_TOUCH, OCULUS_TOUCH_THUMBSTICK_TOUCH,
OCULUS_TOUCH_THUMBSTICK, OCULUS_TOUCH_THUMBSTICK,
OCULUS_TOUCH_THUMBREST_TOUCH, OCULUS_TOUCH_THUMBREST_TOUCH,
OCULUS_TOUCH_GRIP_POSE,
OCULUS_TOUCH_AIM_POSE,
INPUT_INDICES_LAST INPUT_INDICES_LAST
}; };
@ -93,6 +93,7 @@ enum openhmd_device_type
OPENHMD_GENERIC_CONTROLLER, OPENHMD_GENERIC_CONTROLLER,
OPENHMD_OCULUS_RIFT_HMD, OPENHMD_OCULUS_RIFT_HMD,
OPENHMD_OCULUS_RIFT_CONTROLLER, OPENHMD_OCULUS_RIFT_CONTROLLER,
OPENHMD_GENERIC_TRACKER,
}; };
struct openhmd_values struct openhmd_values
@ -104,16 +105,20 @@ struct openhmd_values
float warp_scale; float warp_scale;
}; };
enum OHMD_DEVICE_INDEX
{
OHMD_HMD_INDEX = 0,
OHMD_LEFT_INDEX,
OHMD_RIGHT_INDEX,
OHMD_FIRST_TRACKER_INDEX,
};
struct oh_device; struct oh_device;
struct oh_system struct oh_system
{ {
struct xrt_tracking_origin base; struct xrt_tracking_origin base;
struct oh_device *devices[XRT_MAX_DEVICES_PER_PROBE];
//! index into oh_system::devices struct oh_device *devices[XRT_MAX_DEVICES_PER_PROBE];
int hmd_idx;
int left_idx;
int right_idx;
}; };
/*! /*!
@ -322,6 +327,29 @@ oh_device_set_output(struct xrt_device *xdev, enum xrt_output_name name, const u
//! @todo OpenHMD haptic API not finished //! @todo OpenHMD haptic API not finished
} }
static bool
check_head_pose(struct oh_device *ohd, enum xrt_input_name name)
{
return (ohd->ohmd_device_type == OPENHMD_OCULUS_RIFT_HMD || ohd->ohmd_device_type == OPENHMD_GENERIC_HMD) &&
name == XRT_INPUT_GENERIC_HEAD_POSE;
}
static bool
check_controller_pose(struct oh_device *ohd, enum xrt_input_name name)
{
bool touch_pose = (ohd->ohmd_device_type == OPENHMD_OCULUS_RIFT_CONTROLLER &&
(name == XRT_INPUT_TOUCH_AIM_POSE || name == XRT_INPUT_TOUCH_GRIP_POSE));
bool generic_pose = ohd->ohmd_device_type == OPENHMD_GENERIC_CONTROLLER &&
(name == XRT_INPUT_SIMPLE_AIM_POSE || name == XRT_INPUT_SIMPLE_GRIP_POSE);
return touch_pose || generic_pose;
}
static bool
check_tracker_pose(struct oh_device *ohd, enum xrt_input_name name)
{
return (ohd->ohmd_device_type == OPENHMD_GENERIC_TRACKER) && name == XRT_INPUT_GENERIC_TRACKER_POSE;
}
static void static void
oh_device_get_tracked_pose(struct xrt_device *xdev, oh_device_get_tracked_pose(struct xrt_device *xdev,
enum xrt_input_name name, enum xrt_input_name name,
@ -332,14 +360,8 @@ oh_device_get_tracked_pose(struct xrt_device *xdev,
struct xrt_quat quat = XRT_QUAT_IDENTITY; struct xrt_quat quat = XRT_QUAT_IDENTITY;
struct xrt_vec3 pos = XRT_VEC3_ZERO; struct xrt_vec3 pos = XRT_VEC3_ZERO;
// support generic head pose for all hmds, if (!check_head_pose(ohd, name) && !check_controller_pose(ohd, name) && !check_tracker_pose(ohd, name)) {
// support rift poses for rift controllers, and simple poses for generic controller OHMD_ERROR(ohd, "unknown input name: %d", name);
if (name != XRT_INPUT_GENERIC_HEAD_POSE &&
(ohd->ohmd_device_type == OPENHMD_OCULUS_RIFT_CONTROLLER &&
(name != XRT_INPUT_TOUCH_AIM_POSE && name != XRT_INPUT_TOUCH_GRIP_POSE)) &&
ohd->ohmd_device_type == OPENHMD_GENERIC_CONTROLLER &&
(name != XRT_INPUT_SIMPLE_AIM_POSE && name != XRT_INPUT_SIMPLE_GRIP_POSE)) {
OHMD_ERROR(ohd, "unknown input name");
return; return;
} }
@ -423,7 +445,7 @@ oh_device_get_tracked_pose(struct xrt_device *xdev,
} }
// Update state within driver // Update state within driver
ohd->last_update = now; ohd->last_update = (int64_t)now;
ohd->last_relation = *out_relation; ohd->last_relation = *out_relation;
} }
@ -1041,8 +1063,12 @@ create_controller(ohmd_context *ctx, int device_idx, int device_flags, enum xrt_
ohd->ohmd_device_type = OPENHMD_OCULUS_RIFT_CONTROLLER; ohd->ohmd_device_type = OPENHMD_OCULUS_RIFT_CONTROLLER;
ohd->base.name = XRT_DEVICE_TOUCH_CONTROLLER; ohd->base.name = XRT_DEVICE_TOUCH_CONTROLLER;
} else { } else {
ohd->ohmd_device_type = OPENHMD_GENERIC_CONTROLLER; if (device_type == XRT_DEVICE_TYPE_GENERIC_TRACKER) {
ohd->base.name = XRT_DEVICE_GENERIC_HMD; //! @todo generic tracker ohd->ohmd_device_type = OPENHMD_GENERIC_TRACKER;
} else {
ohd->ohmd_device_type = OPENHMD_GENERIC_CONTROLLER;
}
ohd->base.name = XRT_DEVICE_SIMPLE_CONTROLLER; //! @todo Generic tracker input profile?
} }
ohd->ctx = ctx; ohd->ctx = ctx;
ohd->dev = dev; ohd->dev = dev;
@ -1053,58 +1079,66 @@ create_controller(ohmd_context *ctx, int device_idx, int device_flags, enum xrt_
ohd->controls_mapping[i] = 0; ohd->controls_mapping[i] = 0;
} }
if (oculus_touch) { if (device_type == XRT_DEVICE_TYPE_LEFT_HAND_CONTROLLER ||
SET_TOUCH_INPUT(X_CLICK); device_type == XRT_DEVICE_TYPE_RIGHT_HAND_CONTROLLER ||
SET_TOUCH_INPUT(X_TOUCH); device_type == XRT_DEVICE_TYPE_ANY_HAND_CONTROLLER) {
SET_TOUCH_INPUT(Y_CLICK); if (oculus_touch) {
SET_TOUCH_INPUT(Y_TOUCH); SET_TOUCH_INPUT(X_CLICK);
SET_TOUCH_INPUT(MENU_CLICK); SET_TOUCH_INPUT(X_TOUCH);
SET_TOUCH_INPUT(A_CLICK); SET_TOUCH_INPUT(Y_CLICK);
SET_TOUCH_INPUT(A_TOUCH); SET_TOUCH_INPUT(Y_TOUCH);
SET_TOUCH_INPUT(B_CLICK); SET_TOUCH_INPUT(MENU_CLICK);
SET_TOUCH_INPUT(B_TOUCH); SET_TOUCH_INPUT(A_CLICK);
SET_TOUCH_INPUT(SYSTEM_CLICK); SET_TOUCH_INPUT(A_TOUCH);
SET_TOUCH_INPUT(SQUEEZE_VALUE); SET_TOUCH_INPUT(B_CLICK);
SET_TOUCH_INPUT(TRIGGER_TOUCH); SET_TOUCH_INPUT(B_TOUCH);
SET_TOUCH_INPUT(TRIGGER_VALUE); SET_TOUCH_INPUT(SYSTEM_CLICK);
SET_TOUCH_INPUT(THUMBSTICK_CLICK); SET_TOUCH_INPUT(SQUEEZE_VALUE);
SET_TOUCH_INPUT(THUMBSTICK_TOUCH); SET_TOUCH_INPUT(TRIGGER_TOUCH);
SET_TOUCH_INPUT(THUMBSTICK); SET_TOUCH_INPUT(TRIGGER_VALUE);
SET_TOUCH_INPUT(THUMBREST_TOUCH); SET_TOUCH_INPUT(THUMBSTICK_CLICK);
SET_TOUCH_INPUT(GRIP_POSE); SET_TOUCH_INPUT(THUMBSTICK_TOUCH);
SET_TOUCH_INPUT(AIM_POSE); SET_TOUCH_INPUT(THUMBSTICK);
SET_TOUCH_INPUT(THUMBREST_TOUCH);
ohd->base.inputs[GRIP_POSE].name = XRT_INPUT_TOUCH_GRIP_POSE;
ohd->base.inputs[AIM_POSE].name = XRT_INPUT_TOUCH_AIM_POSE;
ohd->make_trigger_digital = false;
ohd->base.outputs[0].name = XRT_OUTPUT_NAME_TOUCH_HAPTIC; ohd->make_trigger_digital = false;
ohd->controls_mapping[OHMD_TRIGGER] = OCULUS_TOUCH_TRIGGER_VALUE; ohd->base.outputs[0].name = XRT_OUTPUT_NAME_TOUCH_HAPTIC;
ohd->controls_mapping[OHMD_SQUEEZE] = OCULUS_TOUCH_SQUEEZE_VALUE;
ohd->controls_mapping[OHMD_MENU] = OCULUS_TOUCH_MENU_CLICK;
ohd->controls_mapping[OHMD_HOME] = OCULUS_TOUCH_SYSTEM_CLICK;
ohd->controls_mapping[OHMD_ANALOG_X] = OCULUS_TOUCH_THUMBSTICK;
ohd->controls_mapping[OHMD_ANALOG_Y] = OCULUS_TOUCH_THUMBSTICK;
ohd->controls_mapping[OHMD_ANALOG_PRESS] = OCULUS_TOUCH_THUMBSTICK_CLICK;
ohd->controls_mapping[OHMD_BUTTON_A] = OCULUS_TOUCH_A_CLICK;
ohd->controls_mapping[OHMD_BUTTON_B] = OCULUS_TOUCH_B_CLICK;
ohd->controls_mapping[OHMD_BUTTON_X] = OCULUS_TOUCH_X_CLICK;
ohd->controls_mapping[OHMD_BUTTON_Y] = OCULUS_TOUCH_Y_CLICK;
} else {
ohd->base.inputs[SIMPLE_SELECT_CLICK].name = XRT_INPUT_SIMPLE_SELECT_CLICK;
ohd->base.inputs[SIMPLE_MENU_CLICK].name = XRT_INPUT_SIMPLE_MENU_CLICK;
ohd->base.inputs[SIMPLE_GRIP_POSE].name = XRT_INPUT_SIMPLE_GRIP_POSE;
ohd->base.inputs[SIMPLE_AIM_POSE].name = XRT_INPUT_SIMPLE_AIM_POSE;
// XRT_INPUT_SIMPLE_SELECT_CLICK is digital input. ohd->controls_mapping[OHMD_TRIGGER] = OCULUS_TOUCH_TRIGGER_VALUE;
// in case the hardware is an analog trigger, change the input after a half pulled trigger. ohd->controls_mapping[OHMD_SQUEEZE] = OCULUS_TOUCH_SQUEEZE_VALUE;
ohd->make_trigger_digital = true; ohd->controls_mapping[OHMD_MENU] = OCULUS_TOUCH_MENU_CLICK;
ohd->controls_mapping[OHMD_HOME] = OCULUS_TOUCH_SYSTEM_CLICK;
ohd->controls_mapping[OHMD_ANALOG_X] = OCULUS_TOUCH_THUMBSTICK;
ohd->controls_mapping[OHMD_ANALOG_Y] = OCULUS_TOUCH_THUMBSTICK;
ohd->controls_mapping[OHMD_ANALOG_PRESS] = OCULUS_TOUCH_THUMBSTICK_CLICK;
ohd->controls_mapping[OHMD_BUTTON_A] = OCULUS_TOUCH_A_CLICK;
ohd->controls_mapping[OHMD_BUTTON_B] = OCULUS_TOUCH_B_CLICK;
ohd->controls_mapping[OHMD_BUTTON_X] = OCULUS_TOUCH_X_CLICK;
ohd->controls_mapping[OHMD_BUTTON_Y] = OCULUS_TOUCH_Y_CLICK;
} else {
ohd->base.inputs[SIMPLE_SELECT_CLICK].name = XRT_INPUT_SIMPLE_SELECT_CLICK;
ohd->base.inputs[SIMPLE_MENU_CLICK].name = XRT_INPUT_SIMPLE_MENU_CLICK;
ohd->base.inputs[GRIP_POSE].name = XRT_INPUT_SIMPLE_GRIP_POSE;
ohd->base.inputs[AIM_POSE].name = XRT_INPUT_SIMPLE_AIM_POSE;
if (output_count > 0) { // XRT_INPUT_SIMPLE_SELECT_CLICK is digital input.
ohd->base.outputs[0].name = XRT_OUTPUT_NAME_SIMPLE_VIBRATION; // in case the hardware is an analog trigger, change the input after a half pulled trigger.
ohd->make_trigger_digital = true;
if (output_count > 0) {
ohd->base.outputs[0].name = XRT_OUTPUT_NAME_SIMPLE_VIBRATION;
}
ohd->controls_mapping[OHMD_TRIGGER] = SIMPLE_SELECT_CLICK;
ohd->controls_mapping[OHMD_MENU] = SIMPLE_MENU_CLICK;
} }
} else if (device_type == XRT_DEVICE_TYPE_GENERIC_TRACKER) {
ohd->controls_mapping[OHMD_TRIGGER] = SIMPLE_SELECT_CLICK; ohd->base.inputs[GRIP_POSE].name = XRT_INPUT_GENERIC_TRACKER_POSE;
ohd->controls_mapping[OHMD_MENU] = SIMPLE_MENU_CLICK; ohd->base.inputs[AIM_POSE].name = XRT_INPUT_GENERIC_TRACKER_POSE;
} }
snprintf(ohd->base.str, XRT_DEVICE_NAME_LEN, "%s (OpenHMD)", prod); snprintf(ohd->base.str, XRT_DEVICE_NAME_LEN, "%s (OpenHMD)", prod);
@ -1133,14 +1167,22 @@ oh_device_create(ohmd_context *ctx, bool no_hmds, struct xrt_device **out_xdevs)
int right_idx = -1; int right_idx = -1;
int right_flags = 0; int right_flags = 0;
if (no_hmds) { int trackers[XRT_MAX_DEVICES_PER_PROBE];
return 0; ohmd_device_flags tracker_flags[XRT_MAX_DEVICES_PER_PROBE];
} uint32_t tracker_count = 0;
/* Probe for devices */ /* Probe for devices */
int device_count = ohmd_ctx_probe(ctx); int device_count = ohmd_ctx_probe(ctx);
/* Then loop */ // clamp device_count to XRT_MAX_DEVICES_PER_PROBE
if (device_count > XRT_MAX_DEVICES_PER_PROBE) {
U_LOG_W("Too many devices from OpenHMD, ignoring %d devices!",
device_count - XRT_MAX_DEVICES_PER_PROBE);
device_count = XRT_MAX_DEVICES_PER_PROBE;
}
/* Find first HMD, first left controller, first right controller, and all trackers */
for (int i = 0; i < device_count; i++) { for (int i = 0; i < device_count; i++) {
int device_class = 0, device_flags = 0; int device_class = 0, device_flags = 0;
const char *prod = NULL; const char *prod = NULL;
@ -1148,6 +1190,17 @@ oh_device_create(ohmd_context *ctx, bool no_hmds, struct xrt_device **out_xdevs)
ohmd_list_geti(ctx, i, OHMD_DEVICE_CLASS, &device_class); ohmd_list_geti(ctx, i, OHMD_DEVICE_CLASS, &device_class);
ohmd_list_geti(ctx, i, OHMD_DEVICE_FLAGS, &device_flags); ohmd_list_geti(ctx, i, OHMD_DEVICE_FLAGS, &device_flags);
if (device_flags & OHMD_DEVICE_FLAGS_NULL_DEVICE) {
U_LOG_D("Rejecting device idx %i, is a NULL device.", i);
continue;
}
prod = ohmd_list_gets(ctx, i, OHMD_PRODUCT);
if (strcmp(prod, "External Device") == 0 && !debug_get_bool_option_ohmd_external()) {
U_LOG_D("Rejecting device idx %i, is a External device.", i);
continue;
}
if (device_class == OHMD_DEVICE_CLASS_CONTROLLER) { if (device_class == OHMD_DEVICE_CLASS_CONTROLLER) {
if ((device_flags & OHMD_DEVICE_FLAGS_LEFT_CONTROLLER) != 0) { if ((device_flags & OHMD_DEVICE_FLAGS_LEFT_CONTROLLER) != 0) {
if (left_idx != -1) { if (left_idx != -1) {
@ -1167,30 +1220,17 @@ oh_device_create(ohmd_context *ctx, bool no_hmds, struct xrt_device **out_xdevs)
} }
continue; continue;
} } else if (device_class == OHMD_DEVICE_CLASS_HMD) {
if (device_class == OHMD_DEVICE_CLASS_HMD) {
if (hmd_idx != -1) { if (hmd_idx != -1) {
continue; continue;
} }
U_LOG_D("Selecting hmd idx %i", i); U_LOG_D("Selecting hmd idx %i", i);
hmd_idx = i; hmd_idx = i;
hmd_flags = device_flags; hmd_flags = device_flags;
} } else if (device_class == OHMD_DEVICE_CLASS_GENERIC_TRACKER) {
uint32_t tracker_index = tracker_count++;
if (device_flags & OHMD_DEVICE_FLAGS_NULL_DEVICE) { trackers[tracker_index] = i;
U_LOG_D("Rejecting device idx %i, is a NULL device.", i); tracker_flags[tracker_index] = device_flags;
continue;
}
prod = ohmd_list_gets(ctx, i, OHMD_PRODUCT);
if (strcmp(prod, "External Device") == 0 && !debug_get_bool_option_ohmd_external()) {
U_LOG_D("Rejecting device idx %i, is a External device.", i);
continue;
}
if (hmd_idx != -1 && left_idx != -1 && right_idx != -1) {
break;
} }
} }
@ -1201,9 +1241,6 @@ oh_device_create(ohmd_context *ctx, bool no_hmds, struct xrt_device **out_xdevs)
struct oh_system *sys = U_TYPED_CALLOC(struct oh_system); struct oh_system *sys = U_TYPED_CALLOC(struct oh_system);
sys->base.type = XRT_TRACKING_TYPE_NONE; sys->base.type = XRT_TRACKING_TYPE_NONE;
sys->base.offset.orientation.w = 1.0f; sys->base.offset.orientation.w = 1.0f;
sys->hmd_idx = -1;
sys->left_idx = -1;
sys->right_idx = -1;
u_var_add_root(sys, "OpenHMD Wrapper", false); u_var_add_root(sys, "OpenHMD Wrapper", false);
@ -1214,8 +1251,7 @@ oh_device_create(ohmd_context *ctx, bool no_hmds, struct xrt_device **out_xdevs)
hmd->sys = sys; hmd->sys = sys;
hmd->base.tracking_origin = &sys->base; hmd->base.tracking_origin = &sys->base;
sys->hmd_idx = created; sys->devices[OHMD_HMD_INDEX] = hmd;
sys->devices[sys->hmd_idx] = hmd;
if (hmd->base.position_tracking_supported) { if (hmd->base.position_tracking_supported) {
sys->base.type = XRT_TRACKING_TYPE_OTHER; sys->base.type = XRT_TRACKING_TYPE_OTHER;
@ -1232,8 +1268,7 @@ oh_device_create(ohmd_context *ctx, bool no_hmds, struct xrt_device **out_xdevs)
left->sys = sys; left->sys = sys;
left->base.tracking_origin = &sys->base; left->base.tracking_origin = &sys->base;
sys->left_idx = created; sys->devices[OHMD_LEFT_INDEX] = left;
sys->devices[sys->left_idx] = left;
out_xdevs[created++] = &left->base; out_xdevs[created++] = &left->base;
} }
@ -1246,20 +1281,32 @@ oh_device_create(ohmd_context *ctx, bool no_hmds, struct xrt_device **out_xdevs)
right->sys = sys; right->sys = sys;
right->base.tracking_origin = &sys->base; right->base.tracking_origin = &sys->base;
sys->right_idx = created; sys->devices[OHMD_RIGHT_INDEX] = right;
sys->devices[sys->right_idx] = right;
out_xdevs[created++] = &right->base; out_xdevs[created++] = &right->base;
} }
} }
for (uint32_t i = 0; i < tracker_count; i++) {
struct oh_device *tracker =
create_controller(ctx, trackers[i], tracker_flags[i], XRT_DEVICE_TYPE_GENERIC_TRACKER);
if (tracker) {
tracker->sys = sys;
tracker->base.tracking_origin = &sys->base;
sys->devices[OHMD_FIRST_TRACKER_INDEX + i] = tracker;
out_xdevs[created++] = &tracker->base;
}
}
for (int i = 0; i < XRT_MAX_DEVICES_PER_PROBE; i++) { for (int i = 0; i < XRT_MAX_DEVICES_PER_PROBE; i++) {
if (sys->devices[i] != NULL) { if (sys->devices[i] != NULL) {
u_var_add_ro_text(sys, sys->devices[i]->base.str, "OpenHMD Device"); u_var_add_ro_text(sys, sys->devices[i]->base.str, "OpenHMD Device");
} }
} }
//! @todo initialize more devices like generic trackers (nolo) ohmd_device_settings_destroy(settings);
return created; return created;
} }