...
 
Commits (1)
[submodule "src/external/libsurvive"]
path = src/external/libsurvive
url = https://github.com/cnlohr/libsurvive.git
......@@ -57,7 +57,8 @@ cmake_dependent_option(BUILD_WITH_OPENCV "Enable OpenCV backend" ON "OpenCV_FOUN
cmake_dependent_option(BUILD_WITH_LIBUVC "Enable libuvc video driver" ON "LIBUVC_FOUND" OFF)
cmake_dependent_option(BUILD_WITH_FFMPEG "Enable ffmpeg testing video driver" ON "FFMPEG_FOUND" OFF)
cmake_dependent_option(BUILD_WITH_HIDAPI "Enable HIDAPI-based driver(s) (OSVR HDK, PSVR)" ON "HIDAPI_FOUND" OFF)
cmake_dependent_option(BUILD_WITH_OPENHMD "Enable OpenHMD driver" ON "OPENHMD_FOUND" OFF)
option(BUILD_WITH_LIBSURVIVE "Enable libsurvive driver" ON)
cmake_dependent_option(BUILD_WITH_OPENHMD "Enable OpenHMD driver" OFF "OPENHMD_FOUND" OFF)
###
......@@ -104,6 +105,11 @@ if(BUILD_WITH_OPENHMD)
set(BUILD_DRIVER_OHMD TRUE)
endif()
if (BUILD_WITH_LIBSURVIVE)
add_definitions(-DXRT_BUILD_SURVIVE)
set(BUILD_DRIVER_SURVIVE TRUE)
endif()
if(BUILD_WITH_HIDAPI)
add_definitions(-DXRT_HAVE_HIDAPI)
......
# Monado - XR Runtime (XRT)
# Monado - XR Runtime (XRT) - experimental libsurvive branch
Monado is an open source XR runtime delivering immersive experiences such as VR
and AR on on mobile, PC/desktop, and any other device
......@@ -11,6 +11,28 @@ The project currently is being developed for GNU/Linux
and aims to support other operating systems in the near future.
"Monado" has no specific meaning and is just a name.
# About the libsurvive Branch
This branch contains libsurvive as a submodule in src/xrt/external/libsurvive.
Libsurvive is compiled as a shared library and the runtime links to libsurvive.
A device prober using the libsurvive simple api is implemented in src/xrt/drivers/survive.
When starting an OpenXR application, libsurvive will run calibration and save configuration
and calibration data in the current working directory.
Make sure the HMD can see both basestations and is not moved during calibration.
To remove libsurvive's calibration data delete the following files/directories:
rm -r config.json HMD_config.json calinfo
Though working and usable, support for the libsurvive driver is **experimental**.
For example it contains many hardcoded values from OpenHMD's configuration for the Vive 1 and
does not behave well yet when no Vive is connected.
libsurvive may only build when the `-DUSE_OPENCV=OFF` cmake option is used.
## Monado source tree
* `src/xrt/include` - headers that define the internal interfaces of Monado.
......
# Copyright 2019, Collabora, Ltd.
# SPDX-License-Identifier: BSL-1.0
if (BUILD_WITH_LIBSURVIVE)
add_subdirectory(external/libsurvive)
endif()
add_subdirectory(xrt)
Subproject commit 1dd49ea446533cfa77126fe451959a374ace373d
......@@ -92,3 +92,23 @@ if(BUILD_DRIVER_V4L2)
add_library(drv_v4l2 OBJECT ${V4L2_SOURCE_FILES})
set_property(TARGET drv_v4l2 PROPERTY POSITION_INDEPENDENT_CODE ON)
endif()
if (BUILD_WITH_LIBSURVIVE)
set(SURVIVE_SOURCE_FILES
survive/survive_device.c
survive/survive_device.h
survive/survive_interface.h
survive/survive_prober.c
)
# Use OBJECT to not create a archive, since it just gets in the way.
add_library(drv_survive OBJECT ${SURVIVE_SOURCE_FILES})
set_property(TARGET drv_survive PROPERTY POSITION_INDEPENDENT_CODE ON)
target_include_directories(drv_survive SYSTEM
PRIVATE
${PROJECT_SOURCE_DIR}/src/external/libsurvive/include
${PROJECT_SOURCE_DIR}/src/external/libsurvive/include/libsurvive
${PROJECT_SOURCE_DIR}/src/external/libsurvive/redist
)
endif()
// Copyright 2019, Collabora, Ltd.
// SPDX-License-Identifier: Apache-2.0
/*!
* @file
* @brief Adapter to Libsurvive.
* @author Jakob Bornecrantz <jakob@collabora.com>
* @author Christoph Haag <christoph.haag@collabora.com>
*/
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "math/m_api.h"
#include "xrt/xrt_device.h"
#include "util/u_debug.h"
#include "util/u_device.h"
#include "util/u_misc.h"
#include "util/u_time.h"
#include "util/u_device.h"
#include "survive_device.h"
static void
survive_device_destroy(struct xrt_device *xdev)
{
struct survive_device *survive = survive_device(xdev);
if (survive->ctx != NULL) {
survive_simple_close(survive->ctx);
}
free(survive);
}
static void
survive_device_get_tracked_pose(struct xrt_device *xdev,
enum xrt_input_name name,
struct time_state *timekeeping,
int64_t *out_timestamp,
struct xrt_space_relation *out_relation)
{
struct survive_device *survive = survive_device(xdev);
if (name != XRT_INPUT_GENERIC_HEAD_RELATION) {
SURVIVE_ERROR(survive, "unknown input name");
return;
}
int64_t now = time_state_get_now(timekeeping);
//! @todo adjust for latency here
*out_timestamp = now;
out_relation->relation_flags = 0;
bool new_data = false;
static struct xrt_quat last_rot = {.x = 0, .y = 0, .z = 0, .w = 1};
static struct xrt_vec3 last_pos = {.x = 0, .y = 0, .z = 0};
for (const SurviveSimpleObject *it =
survive_simple_get_next_updated(survive->ctx);
it != 0; it = survive_simple_get_next_updated(survive->ctx)) {
const char *codename = survive_simple_object_name(it);
if (strcmp(codename, "HMD") != 0)
continue;
new_data = true;
SurvivePose pose;
uint32_t timecode =
survive_simple_object_get_latest_pose(it, &pose);
(void)timecode;
struct xrt_quat out_rot = {.x = pose.Rot[1],
.y = pose.Rot[2],
.z = pose.Rot[3],
.w = pose.Rot[0]};
//printf ("quat %f %f %f %f\n", out_rot.x, out_rot.y, out_rot.z, out_rot.w);
/* libsurvive looks down when it should be looking forward, so
* rotate the quat.
* because the HMD quat is the opposite of the in world
* rotation, we rotate down. */
struct xrt_quat down_rot;
down_rot.x = sqrtf(2) / 2.;
down_rot.y = 0;
down_rot.z = 0;
down_rot.w = -sqrtf(2) / 2.;
math_quat_rotate(&down_rot, &out_rot, &out_rot);
math_quat_normalize(&out_rot);
out_relation->pose.orientation = out_rot;
/* because the quat is rotated, y and z axes are switched. */
out_relation->pose.position.x = pose.Pos[0];
out_relation->pose.position.y = pose.Pos[2];
out_relation->pose.position.z = -pose.Pos[1];
//printf("Get pose %f %f %f\n", out_relation->pose.position.x, out_relation->pose.position.y, out_relation->pose.position.z);
out_relation->relation_flags =
(enum xrt_space_relation_flags)(
XRT_SPACE_RELATION_ORIENTATION_VALID_BIT |
XRT_SPACE_RELATION_ORIENTATION_TRACKED_BIT) |
XRT_SPACE_RELATION_POSITION_VALID_BIT |
XRT_SPACE_RELATION_POSITION_TRACKED_BIT;
SURVIVE_SPEW(
survive,
"GET_POSITION (%f %f %f) GET_ORIENTATION (%f, %f, %f, %f)",
out_relation->pose.position.x,
out_relation->pose.position.y,
out_relation->pose.position.z, out_rot.x, out_rot.y,
out_rot.z, out_rot.w);
last_rot = out_relation->pose.orientation;
last_pos = out_relation->pose.position;
}
/// @todo: Handle device supplying data too slowly better
if (!new_data) {
out_relation->pose.orientation = last_rot;
out_relation->pose.position = last_pos;
out_relation->relation_flags =
(enum xrt_space_relation_flags)(
XRT_SPACE_RELATION_ORIENTATION_VALID_BIT |
XRT_SPACE_RELATION_ORIENTATION_TRACKED_BIT) |
XRT_SPACE_RELATION_POSITION_VALID_BIT |
XRT_SPACE_RELATION_POSITION_TRACKED_BIT;
}
}
static void
survive_device_get_view_pose(struct xrt_device *xdev,
struct xrt_vec3 *eye_relation,
uint32_t view_index,
struct xrt_pose *out_pose)
{
struct xrt_pose pose = {{0.0f, 0.0f, 0.0f, 1.0f}, {0.0f, 0.0f, 0.0f}};
bool adjust = view_index == 0;
pose.position.x = eye_relation->x / 2.0f;
pose.position.y = eye_relation->y / 2.0f;
pose.position.z = eye_relation->z / 2.0f;
// Adjust for left/right while also making sure there aren't any -0.f.
if (pose.position.x > 0.0f && adjust) {
pose.position.x = -pose.position.x;
}
if (pose.position.y > 0.0f && adjust) {
pose.position.y = -pose.position.y;
}
if (pose.position.z > 0.0f && adjust) {
pose.position.z = -pose.position.z;
}
*out_pose = pose;
}
struct display_info
{
float w_meters;
float h_meters;
int w_pixels;
int h_pixels;
};
struct device_info
{
struct display_info display;
float lens_horizontal_separation;
float lens_vertical_position;
float pano_distortion_k[4];
float pano_aberration_k[4];
float pano_warp_scale;
struct
{
float fov;
struct display_info display;
float lens_center_x_meters;
float lens_center_y_meters;
} views[2];
};
static struct device_info
get_info()
{
struct device_info info = {0};
//! @todo: hardcoded values for Vive 1 from openhmd vive driver
info.display.w_meters = 0.122822f;
info.display.h_meters = 0.068234f;
info.lens_horizontal_separation = 0.056;
info.lens_vertical_position = 0.032;
info.views[0].fov =
2 * atan2f(0.122822f / 2. - 0.056 / 2., 0.023226876441867737);
info.views[1].fov = info.views[0].fov;
info.display.w_pixels = 2160;
info.display.h_pixels = 1200;
info.pano_distortion_k[0] = 1.318397;
info.pano_distortion_k[1] = -1.490242;
info.pano_distortion_k[2] = 0.663824;
info.pano_distortion_k[3] = 0.508021;
info.pano_aberration_k[0] = 1.00010147892f;
info.pano_aberration_k[1] = 1.000f;
info.pano_aberration_k[2] = 1.00019614479f;
/*
* Assumptions made here:
*
* - There is a single, continuous, flat display serving both eyes, with
* no dead space/gap between eyes.
* - This single panel is (effectively) perpendicular to the forward
* (-Z) direction, with edges aligned with the X and Y axes.
* - Lens position is symmetrical about the center ("bridge of nose").
* - Pixels are square and uniform across the entirety of the panel.
*
* If any of these are not true, then either the rendering will
* be inaccurate, or the properties will have to be "fudged" to
* make the math work.
*/
info.views[0].display.w_meters = info.display.w_meters / 2.0;
info.views[0].display.h_meters = info.display.h_meters;
info.views[1].display.w_meters = info.display.w_meters / 2.0;
info.views[1].display.h_meters = info.display.h_meters;
info.views[0].display.w_pixels = info.display.w_pixels / 2;
info.views[0].display.h_pixels = info.display.h_pixels;
info.views[1].display.w_pixels = info.display.w_pixels / 2;
info.views[1].display.h_pixels = info.display.h_pixels;
/*
* Assuming the lenses are centered vertically on the
* display. It's not universal, but 0.5 COP on Y is more
* common than on X, and it looked like many of the
* driver lens_vpos values were copy/pasted or marked
* with FIXME. Safer to fix it to 0.5 than risk an
* extreme geometry mismatch.
*/
const double cop_y = 0.5;
const double h_1 = cop_y * info.display.h_meters;
//! @todo This are probably all wrong!
info.views[0].lens_center_x_meters =
info.views[0].display.w_meters -
info.lens_horizontal_separation / 2.0;
info.views[0].lens_center_y_meters = h_1;
info.views[1].lens_center_x_meters =
info.lens_horizontal_separation / 2.0;
info.views[1].lens_center_y_meters = h_1;
//! @todo This is most definitely wrong!
//! 3Glasses likes the oposite better.
info.pano_warp_scale = (info.views[0].lens_center_x_meters >
info.views[0].lens_center_x_meters)
? info.views[0].lens_center_x_meters
: info.views[0].lens_center_x_meters;
return info;
}
static void
survive_device_update_inputs(struct xrt_device *xdev, struct time_state *timekeeping)
{
// Empty
}
struct survive_device *
survive_device_create(bool print_spew, bool print_debug)
{
enum u_device_alloc_flags flags = (enum u_device_alloc_flags)(
U_DEVICE_ALLOC_HMD | U_DEVICE_ALLOC_TRACKING_NONE);
struct survive_device *survive =
U_DEVICE_ALLOCATE(struct survive_device, flags, 1, 0);
#if 0
char *survive_args[] = {
"Monado-libsurvive",
// Improves the situation when one basestation goes out of view
//"--time-window", "1500000"
};
SurviveSimpleContext *actx = survive_simple_init(
sizeof(survive_args) / sizeof(survive_args[0]), survive_args);
#else
SurviveSimpleContext *actx = survive_simple_init(0, 0);
#endif
//! @todo: when no vive is connected, this prober will behave badly.
// * No calibration present: It segfaults
// * Calibration present. It calls exit()
// it should really return NULL instead.
if (!actx)
return NULL;
survive_simple_start_thread(actx);
survive->base.destroy = survive_device_destroy;
survive->base.update_inputs = survive_device_update_inputs;
survive->base.get_tracked_pose = survive_device_get_tracked_pose;
survive->base.get_view_pose = survive_device_get_view_pose;
survive->ctx = actx;
survive->print_spew = print_spew;
survive->print_debug = print_debug;
strcpy(survive->base.name, "libsurvive");
const struct device_info info = get_info();
{
/* right eye */
if (!math_compute_fovs(info.views[1].display.w_meters,
info.views[1].lens_center_x_meters,
info.views[1].fov,
info.views[1].display.h_meters,
info.views[1].lens_center_y_meters, 0,
&survive->base.hmd->views[1].fov)) {
SURVIVE_ERROR(
survive,
"Failed to compute the partial fields of view.");
free(survive);
return NULL;
}
}
{
/* left eye - just mirroring right eye now */
survive->base.hmd->views[0].fov.angle_up =
survive->base.hmd->views[1].fov.angle_up;
survive->base.hmd->views[0].fov.angle_down =
survive->base.hmd->views[1].fov.angle_down;
survive->base.hmd->views[0].fov.angle_left =
-survive->base.hmd->views[1].fov.angle_right;
survive->base.hmd->views[0].fov.angle_right =
-survive->base.hmd->views[1].fov.angle_left;
}
// clang-format off
// Main display.
survive->base.hmd->distortion.models = XRT_DISTORTION_MODEL_PANOTOOLS;
survive->base.hmd->distortion.preferred = XRT_DISTORTION_MODEL_PANOTOOLS;
survive->base.hmd->screens[0].w_pixels = info.display.w_pixels;
survive->base.hmd->screens[0].h_pixels = info.display.h_pixels;
survive->base.hmd->distortion.pano.distortion_k[0] = info.pano_distortion_k[0];
survive->base.hmd->distortion.pano.distortion_k[1] = info.pano_distortion_k[1];
survive->base.hmd->distortion.pano.distortion_k[2] = info.pano_distortion_k[2];
survive->base.hmd->distortion.pano.distortion_k[3] = info.pano_distortion_k[3];
survive->base.hmd->distortion.pano.aberration_k[0] = info.pano_aberration_k[0];
survive->base.hmd->distortion.pano.aberration_k[1] = info.pano_aberration_k[1];
survive->base.hmd->distortion.pano.aberration_k[2] = info.pano_aberration_k[2];
// Left
survive->base.hmd->views[0].display.w_meters = info.views[0].display.w_meters;
survive->base.hmd->views[0].display.h_meters = info.views[0].display.h_meters;
survive->base.hmd->views[0].lens_center.x_meters = info.views[0].lens_center_x_meters;
survive->base.hmd->views[0].lens_center.y_meters = info.views[0].lens_center_y_meters;
survive->base.hmd->views[0].display.w_pixels = info.views[0].display.w_pixels;
survive->base.hmd->views[0].display.h_pixels = info.views[0].display.h_pixels;
survive->base.hmd->views[0].viewport.x_pixels = 0;
survive->base.hmd->views[0].viewport.y_pixels = 0;
survive->base.hmd->views[0].viewport.w_pixels = info.views[0].display.w_pixels;
survive->base.hmd->views[0].viewport.h_pixels = info.views[0].display.h_pixels;
survive->base.hmd->views[0].rot = u_device_rotation_ident;
// Right
survive->base.hmd->views[1].display.w_meters = info.views[1].display.w_meters;
survive->base.hmd->views[1].display.h_meters = info.views[1].display.h_meters;
survive->base.hmd->views[1].lens_center.x_meters = info.views[1].lens_center_x_meters;
survive->base.hmd->views[1].lens_center.y_meters = info.views[1].lens_center_y_meters;
survive->base.hmd->views[1].display.w_pixels = info.views[1].display.w_pixels;
survive->base.hmd->views[1].display.h_pixels = info.views[1].display.h_pixels;
survive->base.hmd->views[1].viewport.x_pixels = info.views[0].display.w_pixels;
survive->base.hmd->views[1].viewport.y_pixels = 0;
survive->base.hmd->views[1].viewport.w_pixels = info.views[1].display.w_pixels;
survive->base.hmd->views[1].viewport.h_pixels = info.views[1].display.h_pixels;
survive->base.hmd->views[1].rot = u_device_rotation_ident;
// clang-format on
// Find any needed quirks.
bool quirk_video_see_through = false;
bool quirk_video_distortion_vive = false;
quirk_video_distortion_vive = true;
quirk_video_see_through = false;
// Which blend modes does the device support.
survive->base.hmd->blend_mode |= XRT_BLEND_MODE_OPAQUE;
if (quirk_video_see_through) {
survive->base.hmd->blend_mode |= XRT_BLEND_MODE_ALPHA_BLEND;
}
if (quirk_video_distortion_vive) {
survive->base.hmd->distortion.models |= XRT_DISTORTION_MODEL_VIVE;
survive->base.hmd->distortion.preferred = XRT_DISTORTION_MODEL_VIVE;
// clang-format off
// These need to be aquired from the vive config
survive->base.hmd->distortion.vive.aspect_x_over_y = 0.8999999761581421f;
survive->base.hmd->distortion.vive.grow_for_undistort = 0.6000000238418579f;
survive->base.hmd->distortion.vive.undistort_r2_cutoff[0] = 1.11622154712677f;
survive->base.hmd->distortion.vive.undistort_r2_cutoff[1] = 1.101870775222778f;
survive->base.hmd->distortion.vive.center[0][0] = 0.08946027017045266f;
survive->base.hmd->distortion.vive.center[0][1] = -0.009002181016260827f;
survive->base.hmd->distortion.vive.center[1][0] = -0.08933516629552526f;
survive->base.hmd->distortion.vive.center[1][1] = -0.006014565287238661f;
// left
// green
survive->base.hmd->distortion.vive.coefficients[0][0][0] = -0.188236068524731f;
survive->base.hmd->distortion.vive.coefficients[0][0][1] = -0.221086205321053f;
survive->base.hmd->distortion.vive.coefficients[0][0][2] = -0.2537849057915209f;
// blue
survive->base.hmd->distortion.vive.coefficients[0][1][0] = -0.07316590815739493f;
survive->base.hmd->distortion.vive.coefficients[0][1][1] = -0.02332400789561968f;
survive->base.hmd->distortion.vive.coefficients[0][1][2] = 0.02469959434698275f;
// red
survive->base.hmd->distortion.vive.coefficients[0][2][0] = -0.02223805567703767f;
survive->base.hmd->distortion.vive.coefficients[0][2][1] = -0.04931309279533211f;
survive->base.hmd->distortion.vive.coefficients[0][2][2] = -0.07862881939243466f;
// right
// green
survive->base.hmd->distortion.vive.coefficients[1][0][0] = -0.1906209981894497f;
survive->base.hmd->distortion.vive.coefficients[1][0][1] = -0.2248896677207884f;
survive->base.hmd->distortion.vive.coefficients[1][0][2] = -0.2721364516782803f;
// blue
survive->base.hmd->distortion.vive.coefficients[1][1][0] = -0.07346071902951497f;
survive->base.hmd->distortion.vive.coefficients[1][1][1] = -0.02189527566250131f;
survive->base.hmd->distortion.vive.coefficients[1][1][2] = 0.0581378652359256f;
// red
survive->base.hmd->distortion.vive.coefficients[1][2][0] = -0.01755850332081247f;
survive->base.hmd->distortion.vive.coefficients[1][2][1] = -0.04517245633373419f;
survive->base.hmd->distortion.vive.coefficients[1][2][2] = -0.0928909347763f;
// clang-format on
}
if (survive->print_debug) {
u_device_dump_config(&survive->base, __func__, "libsurvive");
}
return survive;
}
// Copyright 2019, Collabora, Ltd.
// SPDX-License-Identifier: Apache-2.0
/*!
* @file
* @brief Interface to OpenHMD driver code.
* @author Jakob Bornecrantz <jakob@collabora.com>
*/
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
#include <survive_api.h>
struct survive_device
{
struct xrt_device base;
SurviveSimpleContext *ctx;
bool print_spew;
bool print_debug;
};
static inline struct survive_device *
survive_device(struct xrt_device *xdev)
{
return (struct survive_device *)xdev;
}
struct survive_device *
survive_device_create(bool print_spew, bool print_debug);
#define SURVIVE_SPEW(c, ...) \
do { \
if (c->print_spew) { \
fprintf(stderr, "%s - ", __func__); \
fprintf(stderr, __VA_ARGS__); \
fprintf(stderr, "\n"); \
} \
} while (false)
#define SURVIVE_DEBUG(c, ...) \
do { \
if (c->print_debug) { \
fprintf(stderr, "%s - ", __func__); \
fprintf(stderr, __VA_ARGS__); \
fprintf(stderr, "\n"); \
} \
} while (false)
#define SURVIVE_ERROR(c, ...) \
do { \
fprintf(stderr, "%s - ", __func__); \
fprintf(stderr, __VA_ARGS__); \
fprintf(stderr, "\n"); \
} while (false)
#ifdef __cplusplus
}
#endif
// Copyright 2019, Collabora, Ltd.
// SPDX-License-Identifier: Apache-2.0
/*!
* @file
* @brief Interface to OpenHMD driver code.
* @author Jakob Bornecrantz <jakob@collabora.com>
*/
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
struct xrt_auto_prober*
survive_create_auto_prober();
#ifdef __cplusplus
}
#endif
// Copyright 2019, Collabora, Ltd.
// SPDX-License-Identifier: Apache-2.0
/*!
* @file
* @brief OpenHMD prober code.
* @author Jakob Bornecrantz <jakob@collabora.com>
*/
#include <stdio.h>
#include <stdlib.h>
#include <survive_api.h>
#include "xrt/xrt_prober.h"
#include "util/u_misc.h"
#include "util/u_debug.h"
#include "survive_device.h"
DEBUG_GET_ONCE_BOOL_OPTION(survive_spew, "SURVIVE_PRINT_SPEW", false)
DEBUG_GET_ONCE_BOOL_OPTION(survive_debug, "SURVIVE_PRINT_DEBUG", false)
struct survive_prober
{
struct xrt_auto_prober base;
SurviveSimpleContext *ctx;
};
static inline struct survive_prober *
survive_prober(struct xrt_auto_prober *p)
{
return (struct survive_prober *)p;
}
static void
survive_prober_destroy(struct xrt_auto_prober *p)
{
struct survive_prober *sp = survive_prober(p);
if (sp->ctx != NULL) {
/// @todo: This segfaults
// survive_simple_close(ohp->ctx);
sp->ctx = NULL;
}
free(sp);
}
static struct xrt_device *
survive_prober_autoprobe(struct xrt_auto_prober *p)
{
struct survive_prober *sp = survive_prober(p);
bool print_spew = debug_get_bool_option_survive_spew();
bool print_debug = debug_get_bool_option_survive_debug();
/// @todo: with libsurvive, whether a context can be created tells us if
/// a supported device is connected and readable.
struct survive_device *sd =
survive_device_create(print_spew, print_debug);
if (sd == NULL || sd->ctx == NULL)
return NULL;
sp->ctx = sd->ctx;
return &sd->base;
}
struct xrt_auto_prober *
survive_create_auto_prober()
{
struct survive_prober *sp = U_TYPED_CALLOC(struct survive_prober);
sp->base.destroy = survive_prober_destroy;
sp->base.lelo_dallas_autoprobe = survive_prober_autoprobe;
return &sp->base;
}
......@@ -102,6 +102,10 @@ oxr_system_fill_in(struct oxr_logger *log,
" failed to probe device");
}
#if 0
TODO: this breaks the rotation when enabling
XRT_SPACE_RELATION_POSITION_VALID_BIT | XRT_SPACE_RELATION_POSITION_TRACKED_BIT
if (head->tracking->type == XRT_TRACKING_TYPE_NONE) {
// "nominal height" 1.6m
head->tracking->offset.position.x = 0.0f;
......@@ -120,6 +124,7 @@ oxr_system_fill_in(struct oxr_logger *log,
right->tracking->offset.position.y = 1.3f;
right->tracking->offset.position.z = -0.5f;
}
#endif
// clang-format off
sys->head = head;
......
......@@ -41,6 +41,11 @@ target_link_libraries(prober PRIVATE
if(DRIVER_OBJECTS)
target_sources(prober PRIVATE ${DRIVER_OBJECTS})
if(BUILD_DRIVER_SURVIVE)
target_sources(prober PRIVATE $<TARGET_OBJECTS:drv_survive>)
target_link_libraries(prober PRIVATE survive)
endif()
endif()
if(DRIVER_LIBRARIES)
......
......@@ -14,6 +14,10 @@
#include "hdk/hdk_interface.h"
#endif
#ifdef XRT_BUILD_SURVIVE
#include "survive/survive_interface.h"
#endif
#ifdef XRT_BUILD_OHMD
#include "ohmd/oh_interface.h"
#endif
......@@ -74,6 +78,10 @@ xrt_auto_prober_creator target_auto_list[] = {
psvr_create_auto_prober,
#endif
#ifdef XRT_BUILD_SURVIVE
survive_create_auto_prober,
#endif
#ifdef XRT_BUILD_OHMD
// OpenHMD last as we want to override it with native drivers.
oh_create_auto_prober,
......
......@@ -53,6 +53,11 @@ if(DRIVER_OBJECTS)
target_sources(${RUNTIME_TARGET} PRIVATE ${DRIVER_OBJECTS})
endif()
if (BUILD_DRIVER_SURVIVE)
target_sources(${RUNTIME_TARGET} PRIVATE $<TARGET_OBJECTS:drv_survive>)
target_link_libraries(${RUNTIME_TARGET} PRIVATE survive)
endif()
if(DRIVER_LIBRARIES)
target_link_libraries(${RUNTIME_TARGET} PRIVATE ${DRIVER_LIBRARIES})
endif()
......