t/common: Implement SteamVR builder

This commit is contained in:
BabbleBones 2023-11-25 19:09:07 -05:00 committed by Jakob Bornecrantz
parent d7ed1cb75f
commit 4eac541d96
5 changed files with 245 additions and 29 deletions

View file

@ -28,13 +28,14 @@ if(XRT_BUILD_DRIVER_RIFT_S)
target_sources(target_lists PRIVATE target_builder_rift_s.c) target_sources(target_lists PRIVATE target_builder_rift_s.c)
endif() endif()
if(XRT_BUILD_DRIVER_SURVIVE if(XRT_BUILD_DRIVER_SURVIVE OR XRT_BUILD_DRIVER_VIVE)
OR XRT_BUILD_DRIVER_VIVE
OR XRT_BUILD_DRIVER_STEAMVR_LIGHTHOUSE
)
target_sources(target_lists PRIVATE target_builder_lighthouse.c) target_sources(target_lists PRIVATE target_builder_lighthouse.c)
endif() endif()
if(XRT_BUILD_DRIVER_STEAMVR_LIGHTHOUSE)
target_sources(target_lists PRIVATE target_builder_steamvr.c)
endif()
if(XRT_BUILD_DRIVER_SIMULATED) if(XRT_BUILD_DRIVER_SIMULATED)
target_sources(target_lists PRIVATE target_builder_simulated.c) target_sources(target_lists PRIVATE target_builder_simulated.c)
endif() endif()
@ -171,6 +172,7 @@ endif()
if(XRT_BUILD_DRIVER_STEAMVR_LIGHTHOUSE) if(XRT_BUILD_DRIVER_STEAMVR_LIGHTHOUSE)
target_link_libraries(target_lists PRIVATE drv_steamvr_lh) target_link_libraries(target_lists PRIVATE drv_steamvr_lh)
target_sources(target_lists PRIVATE target_builder_steamvr.c)
endif() endif()
if(XRT_BUILD_DRIVER_ANDROID) if(XRT_BUILD_DRIVER_ANDROID)

View file

@ -23,6 +23,10 @@
#define T_BUILDER_LIGHTHOUSE #define T_BUILDER_LIGHTHOUSE
#endif #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) #if defined(XRT_BUILD_DRIVER_NS) || defined(XRT_DOXYGEN)
#define T_BUILDER_NS #define T_BUILDER_NS
#endif #endif
@ -66,6 +70,14 @@ struct xrt_builder *
t_builder_legacy_create(void); t_builder_legacy_create(void);
#endif #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 #ifdef T_BUILDER_LIGHTHOUSE
/*! /*!
* Builder for Lighthouse-tracked devices (vive, index, tundra trackers, etc.) * Builder for Lighthouse-tracked devices (vive, index, tundra trackers, etc.)

View file

@ -47,10 +47,6 @@
#include "survive/survive_interface.h" #include "survive/survive_interface.h"
#endif #endif
#ifdef XRT_BUILD_DRIVER_STEAMVR_LIGHTHOUSE
#include "steamvr_lh/steamvr_lh_interface.h"
#endif
#ifdef XRT_BUILD_DRIVER_HANDTRACKING #ifdef XRT_BUILD_DRIVER_HANDTRACKING
#include "ht/ht_interface.h" #include "ht/ht_interface.h"
#include "ht_ctrl_emu/ht_ctrl_emu_interface.h" #include "ht_ctrl_emu/ht_ctrl_emu_interface.h"
@ -64,8 +60,6 @@
#if defined(XRT_BUILD_DRIVER_SURVIVE) #if defined(XRT_BUILD_DRIVER_SURVIVE)
#define DEFAULT_DRIVER "survive" #define DEFAULT_DRIVER "survive"
#elif defined(XRT_BUILD_DRIVER_STEAMVR_LIGHTHOUSE)
#define DEFAULT_DRIVER "steamvr"
#else #else
#define DEFAULT_DRIVER "vive" #define DEFAULT_DRIVER "vive"
#endif #endif
@ -92,10 +86,6 @@ DEBUG_GET_ONCE_TRISTATE_OPTION(lh_handtracking, "LH_HANDTRACKING")
#define LH_ASSERT_(predicate) LH_ASSERT(predicate, "Assertion failed " #predicate) #define LH_ASSERT_(predicate) LH_ASSERT(predicate, "Assertion failed " #predicate)
static const char *driver_list[] = { static const char *driver_list[] = {
#ifdef XRT_BUILD_DRIVER_STEAMVR_LIGHTHOUSE
"steamvr_lh",
#endif
#ifdef XRT_BUILD_DRIVER_SURVIVE #ifdef XRT_BUILD_DRIVER_SURVIVE
"survive", "survive",
#endif #endif
@ -309,14 +299,8 @@ lighthouse_estimate_system(struct xrt_builder *xb,
bool have_survive_drv = false; bool have_survive_drv = false;
#endif #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(); 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; lhs->driver = DRIVER_STEAMVR;
} else if (have_survive_drv && strcmp(drv, "survive") == 0) { } else if (have_survive_drv && strcmp(drv, "survive") == 0) {
lhs->driver = DRIVER_SURVIVE; lhs->driver = DRIVER_SURVIVE;
@ -327,9 +311,6 @@ lighthouse_estimate_system(struct xrt_builder *xb,
if (have_survive_drv) { if (have_survive_drv) {
selected = "survive"; selected = "survive";
lhs->driver = DRIVER_SURVIVE; lhs->driver = DRIVER_SURVIVE;
} else if (have_steamvr_drv) {
selected = "steamvr";
lhs->driver = DRIVER_STEAMVR;
} else if (have_vive_drv) { } else if (have_vive_drv) {
selected = "vive"; selected = "vive";
lhs->driver = DRIVER_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); 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 #ifdef XRT_BUILD_DRIVER_HANDTRACKING
bool have_hand_tracking = true; bool have_hand_tracking = true;
#else #else
@ -558,10 +545,8 @@ lighthouse_open_system_impl(struct xrt_builder *xb,
switch (lhs->driver) { switch (lhs->driver) {
case DRIVER_STEAMVR: { case DRIVER_STEAMVR: {
#ifdef XRT_BUILD_DRIVER_STEAMVR_LIGHTHOUSE assert(false);
xsysd->xdev_count += steamvr_lh_get_devices(&xsysd->xdevs[xsysd->xdev_count]); return XRT_ERROR_DEVICE_CREATION_FAILED;
#endif
break;
} }
case DRIVER_SURVIVE: { case DRIVER_SURVIVE: {
#ifdef XRT_BUILD_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.open_system = u_builder_open_system_static_roles;
lhs->base.base.destroy = lighthouse_destroy; lhs->base.base.destroy = lighthouse_destroy;
lhs->base.base.identifier = "lighthouse"; 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_identifiers = driver_list;
lhs->base.base.driver_identifier_count = ARRAY_SIZE(driver_list); lhs->base.base.driver_identifier_count = ARRAY_SIZE(driver_list);

View file

@ -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 <BabbleBones@protonmail.com>
* @author Jakob Bornecrantz <jakob@collabora.com>
* @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;
}

View file

@ -128,6 +128,10 @@ xrt_builder_create_func_t target_builder_list[] = {
t_builder_simula_create, t_builder_simula_create,
#endif // T_BUILDER_SIMULAVR #endif // T_BUILDER_SIMULAVR
#ifdef T_BUILDER_STEAMVR
t_builder_steamvr_create,
#endif // T_BUILDER_STEAMVR
#ifdef T_BUILDER_LIGHTHOUSE #ifdef T_BUILDER_LIGHTHOUSE
t_builder_lighthouse_create, t_builder_lighthouse_create,
#endif // T_BUILDER_LIGHTHOUSE #endif // T_BUILDER_LIGHTHOUSE