The open source OpenXR runtime
at main 170 lines 4.9 kB view raw
1// Copyright 2022-2023, Collabora, Ltd. 2// SPDX-License-Identifier: BSL-1.0 3/*! 4 * @file 5 * @brief Simulated driver builder. 6 * @author Jakob Bornecrantz <jakob@collabora.com> 7 * @ingroup xrt_iface 8 */ 9 10#include "xrt/xrt_config_drivers.h" 11#include "xrt/xrt_prober.h" 12 13#include "util/u_misc.h" 14#include "util/u_debug.h" 15#include "util/u_builders.h" 16#include "util/u_config_json.h" 17#include "util/u_system_helpers.h" 18 19#include "target_builder_interface.h" 20 21#include "simulated/simulated_interface.h" 22 23#include <assert.h> 24 25 26#ifndef XRT_BUILD_DRIVER_SIMULATED 27#error "Must only be built with XRT_BUILD_DRIVER_SIMULATED set" 28#endif 29 30DEBUG_GET_ONCE_BOOL_OPTION(simulated_enabled, "SIMULATED_ENABLE", false) 31DEBUG_GET_ONCE_OPTION(simulated_left, "SIMULATED_LEFT", NULL) 32DEBUG_GET_ONCE_OPTION(simulated_right, "SIMULATED_RIGHT", NULL) 33 34 35/* 36 * 37 * Helper functions. 38 * 39 */ 40 41static const char *driver_list[] = { 42 "simulated", 43}; 44 45struct xrt_device * 46create_controller(const char *str, 47 enum xrt_device_type type, 48 const struct xrt_pose *center, 49 struct xrt_tracking_origin *origin) 50{ 51 enum xrt_device_name name = XRT_DEVICE_SIMPLE_CONTROLLER; 52 53 if (str == NULL) { 54 return NULL; 55 } else if (strcmp(str, "simple") == 0) { 56 name = XRT_DEVICE_SIMPLE_CONTROLLER; 57 type = XRT_DEVICE_TYPE_ANY_HAND_CONTROLLER; // Override left/right 58 } else if (strcmp(str, "wmr") == 0) { 59 name = XRT_DEVICE_WMR_CONTROLLER; 60 } else if (strcmp(str, "ml2") == 0) { 61 name = XRT_DEVICE_ML2_CONTROLLER; 62 type = XRT_DEVICE_TYPE_ANY_HAND_CONTROLLER; // Override left/right 63 } else { 64 U_LOG_E("Unsupported controller '%s' available are: simple, wmr, ml2.", str); 65 return NULL; 66 } 67 68 return simulated_create_controller(name, type, center, origin); 69} 70 71 72/* 73 * 74 * Member functions. 75 * 76 */ 77 78static xrt_result_t 79simulated_estimate_system(struct xrt_builder *xb, 80 cJSON *config, 81 struct xrt_prober *xp, 82 struct xrt_builder_estimate *estimate) 83{ 84 estimate->certain.head = true; 85 estimate->certain.left = true; 86 estimate->certain.right = true; 87 estimate->priority = -50; 88 89 return XRT_SUCCESS; 90} 91 92static xrt_result_t 93simulated_open_system_impl(struct xrt_builder *xb, 94 cJSON *config, 95 struct xrt_prober *xp, 96 struct xrt_tracking_origin *origin, 97 struct xrt_system_devices *xsysd, 98 struct xrt_frame_context *xfctx, 99 struct u_builder_roles_helper *ubrh) 100{ 101 const struct xrt_pose head_center = {XRT_QUAT_IDENTITY, {0.0f, 1.6f, 0.0f}}; // "nominal height" 1.6m 102 const struct xrt_pose left_center = {XRT_QUAT_IDENTITY, {-0.2f, 1.3f, -0.5f}}; 103 const struct xrt_pose right_center = {XRT_QUAT_IDENTITY, {0.2f, 1.3f, -0.5f}}; 104 const enum xrt_device_type left_type = XRT_DEVICE_TYPE_LEFT_HAND_CONTROLLER; 105 const enum xrt_device_type right_type = XRT_DEVICE_TYPE_RIGHT_HAND_CONTROLLER; 106 107 const char *left_str = debug_get_option_simulated_left(); 108 const char *right_str = debug_get_option_simulated_right(); 109 110 struct xrt_device *head = simulated_hmd_create(SIMULATED_MOVEMENT_WOBBLE, &head_center); 111 struct xrt_device *left = create_controller(left_str, left_type, &left_center, head->tracking_origin); 112 struct xrt_device *right = create_controller(right_str, right_type, &right_center, head->tracking_origin); 113 114 // Make the objects be tracked in space. 115 //! @todo Make these be a option to the hmd create function, or just make it be there from the start. 116 head->supported.orientation_tracking = true; 117 head->supported.position_tracking = true; 118 //! @todo Create a shared tracking origin on the system devices struct instead. 119 head->tracking_origin->type = XRT_TRACKING_TYPE_OTHER; // Just anything other then none. 120 121 // Add to device list. 122 xsysd->xdevs[xsysd->xdev_count++] = head; 123 if (left != NULL) { 124 xsysd->xdevs[xsysd->xdev_count++] = left; 125 } 126 if (right != NULL) { 127 xsysd->xdevs[xsysd->xdev_count++] = right; 128 } 129 130 // Assign to role(s). 131 ubrh->head = head; 132 ubrh->left = left; 133 ubrh->right = right; 134 135 return XRT_SUCCESS; 136} 137 138static void 139simulated_destroy(struct xrt_builder *xb) 140{ 141 free(xb); 142} 143 144 145/* 146 * 147 * 'Exported' functions. 148 * 149 */ 150 151struct xrt_builder * 152t_builder_simulated_create(void) 153{ 154 struct u_builder *ub = U_TYPED_CALLOC(struct u_builder); 155 156 // xrt_builder fields. 157 ub->base.estimate_system = simulated_estimate_system; 158 ub->base.open_system = u_builder_open_system_static_roles; 159 ub->base.destroy = simulated_destroy; 160 ub->base.identifier = "simulated"; 161 ub->base.name = "Simulated devices builder"; 162 ub->base.driver_identifiers = driver_list; 163 ub->base.driver_identifier_count = ARRAY_SIZE(driver_list); 164 ub->base.exclude_from_automatic_discovery = !debug_get_bool_option_simulated_enabled(); 165 166 // u_builder fields. 167 ub->open_system_static_roles = simulated_open_system_impl; 168 169 return &ub->base; 170}