diff --git a/src/xrt/targets/common/CMakeLists.txt b/src/xrt/targets/common/CMakeLists.txt index eff4eb4bf..f1fcc9cb7 100644 --- a/src/xrt/targets/common/CMakeLists.txt +++ b/src/xrt/targets/common/CMakeLists.txt @@ -28,13 +28,14 @@ if(XRT_BUILD_DRIVER_RIFT_S) target_sources(target_lists PRIVATE target_builder_rift_s.c) endif() -if(XRT_BUILD_DRIVER_SURVIVE - OR XRT_BUILD_DRIVER_VIVE - OR XRT_BUILD_DRIVER_STEAMVR_LIGHTHOUSE - ) +if(XRT_BUILD_DRIVER_SURVIVE OR XRT_BUILD_DRIVER_VIVE) target_sources(target_lists PRIVATE target_builder_lighthouse.c) endif() +if(XRT_BUILD_DRIVER_STEAMVR_LIGHTHOUSE) + target_sources(target_lists PRIVATE target_builder_steamvr.c) +endif() + if(XRT_BUILD_DRIVER_SIMULATED) target_sources(target_lists PRIVATE target_builder_simulated.c) endif() @@ -171,6 +172,7 @@ endif() if(XRT_BUILD_DRIVER_STEAMVR_LIGHTHOUSE) target_link_libraries(target_lists PRIVATE drv_steamvr_lh) + target_sources(target_lists PRIVATE target_builder_steamvr.c) endif() if(XRT_BUILD_DRIVER_ANDROID) diff --git a/src/xrt/targets/common/target_builder_interface.h b/src/xrt/targets/common/target_builder_interface.h index 33e0ec735..fdbafc00c 100644 --- a/src/xrt/targets/common/target_builder_interface.h +++ b/src/xrt/targets/common/target_builder_interface.h @@ -23,6 +23,10 @@ #define T_BUILDER_LIGHTHOUSE #endif +#if defined(XRT_BUILD_DRIVER_STEAMVR_LIGHTHOUSE) || defined(XRT_DOXYGEN) +#define T_BUILDER_STEAMVR +#endif + #if defined(XRT_BUILD_DRIVER_NS) || defined(XRT_DOXYGEN) #define T_BUILDER_NS #endif @@ -66,6 +70,14 @@ struct xrt_builder * t_builder_legacy_create(void); #endif +#ifdef T_BUILDER_STEAMVR +/*! + * Builder for SteamVR proprietary wrapper (vive, index, tundra trackers, etc.) + */ +struct xrt_builder * +t_builder_steamvr_create(void); +#endif + #ifdef T_BUILDER_LIGHTHOUSE /*! * Builder for Lighthouse-tracked devices (vive, index, tundra trackers, etc.) diff --git a/src/xrt/targets/common/target_builder_lighthouse.c b/src/xrt/targets/common/target_builder_lighthouse.c index 3af063c49..889f30dea 100644 --- a/src/xrt/targets/common/target_builder_lighthouse.c +++ b/src/xrt/targets/common/target_builder_lighthouse.c @@ -47,10 +47,6 @@ #include "survive/survive_interface.h" #endif -#ifdef XRT_BUILD_DRIVER_STEAMVR_LIGHTHOUSE -#include "steamvr_lh/steamvr_lh_interface.h" -#endif - #ifdef XRT_BUILD_DRIVER_HANDTRACKING #include "ht/ht_interface.h" #include "ht_ctrl_emu/ht_ctrl_emu_interface.h" @@ -64,8 +60,6 @@ #if defined(XRT_BUILD_DRIVER_SURVIVE) #define DEFAULT_DRIVER "survive" -#elif defined(XRT_BUILD_DRIVER_STEAMVR_LIGHTHOUSE) -#define DEFAULT_DRIVER "steamvr" #else #define DEFAULT_DRIVER "vive" #endif @@ -92,10 +86,6 @@ DEBUG_GET_ONCE_TRISTATE_OPTION(lh_handtracking, "LH_HANDTRACKING") #define LH_ASSERT_(predicate) LH_ASSERT(predicate, "Assertion failed " #predicate) static const char *driver_list[] = { -#ifdef XRT_BUILD_DRIVER_STEAMVR_LIGHTHOUSE - "steamvr_lh", -#endif - #ifdef XRT_BUILD_DRIVER_SURVIVE "survive", #endif @@ -309,14 +299,8 @@ lighthouse_estimate_system(struct xrt_builder *xb, bool have_survive_drv = false; #endif -#ifdef XRT_BUILD_DRIVER_STEAMVR_LIGHTHOUSE - bool have_steamvr_drv = true; -#else - bool have_steamvr_drv = false; -#endif - const char *drv = debug_get_option_lh_impl(); - if (have_steamvr_drv && strcmp(drv, "steamvr") == 0) { + if (strcmp(drv, "steamvr") == 0) { lhs->driver = DRIVER_STEAMVR; } else if (have_survive_drv && strcmp(drv, "survive") == 0) { lhs->driver = DRIVER_SURVIVE; @@ -327,9 +311,6 @@ lighthouse_estimate_system(struct xrt_builder *xb, if (have_survive_drv) { selected = "survive"; lhs->driver = DRIVER_SURVIVE; - } else if (have_steamvr_drv) { - selected = "steamvr"; - lhs->driver = DRIVER_STEAMVR; } else if (have_vive_drv) { selected = "vive"; lhs->driver = DRIVER_VIVE; @@ -339,6 +320,12 @@ lighthouse_estimate_system(struct xrt_builder *xb, LH_WARN("Requested driver %s was not available, so we went with %s instead", drv, selected); } + // Error on wrong configuration. + if (lhs->driver == DRIVER_STEAMVR) { + LH_ERROR("Use new env variable STEAMVR_LH_ENABLE=true to enable SteamVR driver"); + return XRT_ERROR_PROBING_FAILED; + } + #ifdef XRT_BUILD_DRIVER_HANDTRACKING bool have_hand_tracking = true; #else @@ -558,10 +545,8 @@ lighthouse_open_system_impl(struct xrt_builder *xb, switch (lhs->driver) { case DRIVER_STEAMVR: { -#ifdef XRT_BUILD_DRIVER_STEAMVR_LIGHTHOUSE - xsysd->xdev_count += steamvr_lh_get_devices(&xsysd->xdevs[xsysd->xdev_count]); -#endif - break; + assert(false); + return XRT_ERROR_DEVICE_CREATION_FAILED; } case DRIVER_SURVIVE: { #ifdef XRT_BUILD_DRIVER_SURVIVE @@ -790,7 +775,7 @@ t_builder_lighthouse_create(void) lhs->base.base.open_system = u_builder_open_system_static_roles; lhs->base.base.destroy = lighthouse_destroy; lhs->base.base.identifier = "lighthouse"; - lhs->base.base.name = "Lighthouse-tracked (Vive, Index, Tundra trackers, etc.) devices builder"; + lhs->base.base.name = "Lighthouse-tracked FLOSS (Vive, Index, Tundra trackers, etc.) devices builder"; lhs->base.base.driver_identifiers = driver_list; lhs->base.base.driver_identifier_count = ARRAY_SIZE(driver_list); diff --git a/src/xrt/targets/common/target_builder_steamvr.c b/src/xrt/targets/common/target_builder_steamvr.c new file mode 100644 index 000000000..1386fb8aa --- /dev/null +++ b/src/xrt/targets/common/target_builder_steamvr.c @@ -0,0 +1,213 @@ +// Copyright 2023, Duncan Spaulding. +// Copyright 2022-2023, Collabora, Ltd. +// SPDX-License-Identifier: BSL-1.0 +/*! + * @file + * @brief Builder for SteamVR proprietary driver wrapper. + * @author BabbleBones + * @author Jakob Bornecrantz + * @ingroup xrt_iface + */ + +#include "tracking/t_hand_tracking.h" +#include "tracking/t_tracking.h" + +#include "xrt/xrt_config_drivers.h" +#include "xrt/xrt_device.h" +#include "xrt/xrt_prober.h" + +#include "util/u_builders.h" +#include "util/u_config_json.h" +#include "util/u_debug.h" +#include "util/u_device.h" +#include "util/u_sink.h" +#include "util/u_system_helpers.h" + +#include "vive/vive_builder.h" + +#include "target_builder_interface.h" + +#include "steamvr_lh/steamvr_lh_interface.h" + +#ifndef XRT_BUILD_DRIVER_STEAMVR_LIGHTHOUSE +#error "This builder requires the SteamVR Lighthouse driver" +#endif + + +/* + * + * Misc stuff. + * + */ + +DEBUG_GET_ONCE_LOG_OPTION(steamvr_log, "STEAMVR_LH_LOG", U_LOGGING_WARN) +DEBUG_GET_ONCE_BOOL_OPTION(steamvr_enable, "STEAMVR_LH_ENABLE", false) + +#define LH_TRACE(...) U_LOG_IFL_T(debug_get_log_option_steamvr_log(), __VA_ARGS__) +#define LH_DEBUG(...) U_LOG_IFL_D(debug_get_log_option_steamvr_log(), __VA_ARGS__) +#define LH_INFO(...) U_LOG_IFL_I(debug_get_log_option_steamvr_log(), __VA_ARGS__) +#define LH_WARN(...) U_LOG_IFL_W(debug_get_log_option_steamvr_log(), __VA_ARGS__) +#define LH_ERROR(...) U_LOG_IFL_E(debug_get_log_option_steamvr_log(), __VA_ARGS__) + +static const char *driver_list[] = { + "steamvr_lh", +}; + +struct steamvr_builder +{ + struct xrt_builder base; + + /*! + * Is our HMD a Valve Index? + */ + bool is_valve_index; +}; + + +/* + * + * Member functions. + * + */ + +static xrt_result_t +steamvr_estimate_system(struct xrt_builder *xb, + cJSON *config, + struct xrt_prober *xp, + struct xrt_builder_estimate *estimate) +{ + struct steamvr_builder *svrb = (struct steamvr_builder *)xb; + + // Currently no built in support for hand tracking. + bool have_hand_tracking = false; + + if (debug_get_bool_option_steamvr_enable()) { + return vive_builder_estimate( // + xp, // xp + true, // have_6dof + have_hand_tracking, // have_hand_tracking + &svrb->is_valve_index, // out_have_valve_index + estimate); // out_estimate + } else { + return XRT_SUCCESS; + } +} + +static xrt_result_t +steamvr_open_system(struct xrt_builder *xb, + cJSON *config, + struct xrt_prober *xp, + struct xrt_system_devices **out_xsysd, + struct xrt_space_overseer **out_xso) +{ + struct steamvr_builder *svrb = (struct steamvr_builder *)xb; + struct u_system_devices_static *usysds = NULL; + struct xrt_system_devices *xsysd = NULL; + xrt_result_t result = XRT_SUCCESS; + + // Sanity checking. + if (out_xsysd == NULL || *out_xsysd != NULL) { + LH_ERROR("Invalid output system pointer"); + return XRT_ERROR_DEVICE_CREATION_FAILED; + } + + // Use the static system devices helper, no dynamic roles. + usysds = u_system_devices_static_allocate(); + xsysd = &usysds->base.base; + + // Do creation. + xsysd->xdev_count += steamvr_lh_get_devices(&xsysd->xdevs[xsysd->xdev_count]); + + // Device indices. + int head_idx = -1; + int left_idx = -1; + int right_idx = -1; + + // Look for regular devices. + u_device_assign_xdev_roles(xsysd->xdevs, xsysd->xdev_count, &head_idx, &left_idx, &right_idx); + + // Sanity check. + if (head_idx < 0) { + LH_ERROR("Unable to find HMD"); + result = XRT_ERROR_DEVICE_CREATION_FAILED; + goto end_err; + } + + // Devices to populate. + struct xrt_device *head = NULL; + struct xrt_device *left = NULL, *right = NULL; + struct xrt_device *left_ht = NULL, *right_ht = NULL; + + // Always have a head. + head = xsysd->xdevs[head_idx]; + + // It's okay if we didn't find controllers + if (left_idx >= 0) { + left = xsysd->xdevs[left_idx]; + left_ht = u_system_devices_get_ht_device_left(xsysd); + } + + if (right_idx >= 0) { + right = xsysd->xdevs[right_idx]; + right_ht = u_system_devices_get_ht_device_right(xsysd); + } + + if (svrb->is_valve_index) { + // This space left intentionally blank + } + + // Assign to role(s). + xsysd->static_roles.head = head; + xsysd->static_roles.hand_tracking.left = left_ht; + xsysd->static_roles.hand_tracking.right = right_ht; + + u_system_devices_static_finalize( // + usysds, // usysds + left, // left + right); // right + + *out_xsysd = xsysd; + u_builder_create_space_overseer_legacy( // + head, // head + left, // left + right, // right + xsysd->xdevs, // xdevs + xsysd->xdev_count, // xdev_count + out_xso); // out_xso + + return XRT_SUCCESS; + +end_err: + xrt_system_devices_destroy(&xsysd); + + return result; +} + +static void +steamvr_destroy(struct xrt_builder *xb) +{ + struct steamvr_builder *svrb = (struct steamvr_builder *)xb; + free(svrb); +} + + +/* + * + * 'Exported' functions. + * + */ + +struct xrt_builder * +t_builder_steamvr_create(void) +{ + struct steamvr_builder *svrb = U_TYPED_CALLOC(struct steamvr_builder); + svrb->base.estimate_system = steamvr_estimate_system; + svrb->base.open_system = steamvr_open_system; + svrb->base.destroy = steamvr_destroy; + svrb->base.identifier = "steamvr"; + svrb->base.name = "SteamVR proprietary wrapper (Vive, Index, Tundra trackers, etc.) devices builder"; + svrb->base.driver_identifiers = driver_list; + svrb->base.driver_identifier_count = ARRAY_SIZE(driver_list); + + return &svrb->base; +} diff --git a/src/xrt/targets/common/target_lists.c b/src/xrt/targets/common/target_lists.c index 16cd1d209..91001b935 100644 --- a/src/xrt/targets/common/target_lists.c +++ b/src/xrt/targets/common/target_lists.c @@ -128,6 +128,10 @@ xrt_builder_create_func_t target_builder_list[] = { t_builder_simula_create, #endif // T_BUILDER_SIMULAVR +#ifdef T_BUILDER_STEAMVR + t_builder_steamvr_create, +#endif // T_BUILDER_STEAMVR + #ifdef T_BUILDER_LIGHTHOUSE t_builder_lighthouse_create, #endif // T_BUILDER_LIGHTHOUSE