diff --git a/src/xrt/drivers/qwerty/qwerty_device.c b/src/xrt/drivers/qwerty/qwerty_device.c index 5f8a9c4bf..02fa9dc6a 100644 --- a/src/xrt/drivers/qwerty/qwerty_device.c +++ b/src/xrt/drivers/qwerty/qwerty_device.c @@ -7,6 +7,117 @@ * @ingroup drv_qwerty */ -typedef int _silence_compiler_about_empty_translation_unit; +#include "qwerty_device.h" -// @todo +#include "util/u_device.h" + +#include "util/u_distortion_mesh.h" + +#include "math/m_api.h" +#include "math/m_mathinclude.h" + +#include "xrt/xrt_device.h" + +#include +#include + +struct qwerty_device * +qwerty_device(struct xrt_device *xd) +{ + struct qwerty_device *qd = (struct qwerty_device *)xd; + assert(qd); + return qd; +} + +static void +qwerty_update_inputs(struct xrt_device *xd) +{ + return; +} + +static void +qwerty_get_tracked_pose(struct xrt_device *xd, + enum xrt_input_name name, + uint64_t at_timestamp_ns, + struct xrt_space_relation *out_relation) +{ + if (name != XRT_INPUT_GENERIC_HEAD_POSE) { + printf("Unexpected input name = 0x%04X\n", name >> 8); // @todo: use u_logging.h + return; + } + + struct xrt_pose identity = {{0.0f, 0.0f, 0.0f, 1.0f}, {0.0f, 0.0f, 0.0f}}; + out_relation->pose = identity; + out_relation->relation_flags = + XRT_SPACE_RELATION_ORIENTATION_VALID_BIT | XRT_SPACE_RELATION_POSITION_VALID_BIT | + XRT_SPACE_RELATION_ORIENTATION_TRACKED_BIT | XRT_SPACE_RELATION_POSITION_TRACKED_BIT; +} + +static void +qwerty_get_view_pose(struct xrt_device *xd, + struct xrt_vec3 *eye_relation, + uint32_t view_index, + struct xrt_pose *out_pose) +{ + // Adapted from dummy_hmd_get_view_pose() + struct xrt_pose pose = {{0.0f, 0.0f, 0.0f, 1.0f}, {0.0f, 0.0f, 0.0f}}; + bool is_left = view_index == 0; + float adjust = is_left ? -0.5f : 0.5f; + struct xrt_vec3 eye_offset = *eye_relation; + math_vec3_scalar_mul(adjust, &eye_offset); + math_vec3_accum(&eye_offset, &pose.position); + *out_pose = pose; +} + +static void +qwerty_destroy(struct xrt_device *xd) +{ + u_device_free(xd); +} + +struct qwerty_device * +qwerty_hmd_create(void) +{ + enum u_device_alloc_flags flags = U_DEVICE_ALLOC_HMD | U_DEVICE_ALLOC_TRACKING_NONE; + size_t num_inputs = 1, num_outputs = 0; + struct qwerty_device *qd = U_DEVICE_ALLOCATE(struct qwerty_device, flags, num_inputs, num_outputs); + assert(qd); + + struct xrt_device *xd = &qd->base; + xd->name = XRT_DEVICE_GENERIC_HMD; + xd->device_type = XRT_DEVICE_TYPE_HMD; + + snprintf(xd->str, XRT_DEVICE_NAME_LEN, QWERTY_HMD_STR); + snprintf(xd->serial, XRT_DEVICE_NAME_LEN, QWERTY_HMD_STR); + + // Fill in xd->hmd + struct u_device_simple_info info; + info.display.w_pixels = 1280; + info.display.h_pixels = 720; + info.display.w_meters = 0.13f; + info.display.h_meters = 0.07f; + info.lens_horizontal_separation_meters = 0.13f / 2.0f; + info.lens_vertical_position_meters = 0.07f / 2.0f; + info.views[0].fov = 85.0f * (M_PI / 180.0f); + info.views[1].fov = 85.0f * (M_PI / 180.0f); + + if (!u_device_setup_split_side_by_side(xd, &info)) { + printf("Failed to setup HMD properties\n"); // @todo: Use u_logging.h + qwerty_destroy(xd); + assert(false); + return NULL; + } + + xd->tracking_origin->type = XRT_TRACKING_TYPE_OTHER; + snprintf(xd->tracking_origin->name, XRT_TRACKING_NAME_LEN, QWERTY_HMD_TRACKER_STR); + + xd->inputs[0].name = XRT_INPUT_GENERIC_HEAD_POSE; + + xd->update_inputs = qwerty_update_inputs; + xd->get_tracked_pose = qwerty_get_tracked_pose; + xd->get_view_pose = qwerty_get_view_pose; + xd->destroy = qwerty_destroy; + u_distortion_mesh_set_none(xd); // Fill in xd->compute_distortion() + + return qd; +} diff --git a/src/xrt/drivers/qwerty/qwerty_device.h b/src/xrt/drivers/qwerty/qwerty_device.h index 103f9ce4b..d1b1b4933 100644 --- a/src/xrt/drivers/qwerty/qwerty_device.h +++ b/src/xrt/drivers/qwerty/qwerty_device.h @@ -8,6 +8,11 @@ */ #pragma once +#include "xrt/xrt_device.h" + +#define QWERTY_HMD_STR "Qwerty HMD" +#define QWERTY_HMD_TRACKER_STR QWERTY_HMD_STR " Tracker" + #ifdef __cplusplus extern "C" { #endif @@ -17,7 +22,19 @@ extern "C" { * @{ */ -// @todo +//! @implements xrt_device +struct qwerty_device +{ + struct xrt_device base; +}; + +//! Cast to qwerty_device. Ensures returning a valid device or crashing. +struct qwerty_device * +qwerty_device(struct xrt_device *xd); + +//! Create qwerty_hmd. Crash on failure. +struct qwerty_device * +qwerty_hmd_create(void); /*! * @} diff --git a/src/xrt/drivers/qwerty/qwerty_prober.c b/src/xrt/drivers/qwerty/qwerty_prober.c index 3b60215ce..136dc5d1f 100644 --- a/src/xrt/drivers/qwerty/qwerty_prober.c +++ b/src/xrt/drivers/qwerty/qwerty_prober.c @@ -7,6 +7,7 @@ * @ingroup drv_qwerty */ +#include "qwerty_device.h" #include "util/u_misc.h" #include "xrt/xrt_prober.h" @@ -35,8 +36,16 @@ qwerty_prober_autoprobe(struct xrt_auto_prober *xap, struct xrt_prober *xp, struct xrt_device **out_xdevs) { - // @todo - return 0; + bool hmd_wanted = !no_hmds; // Hopefully easier to reason about + + struct qwerty_device *qhmd = qwerty_hmd_create(); + + if (hmd_wanted) { + out_xdevs[0] = &qhmd->base; + } + + int num_qwerty_devices = hmd_wanted; + return num_qwerty_devices; } struct xrt_auto_prober * diff --git a/src/xrt/include/xrt/xrt_tracking.h b/src/xrt/include/xrt/xrt_tracking.h index 1744a3057..4ae4b84f4 100644 --- a/src/xrt/include/xrt/xrt_tracking.h +++ b/src/xrt/include/xrt/xrt_tracking.h @@ -57,6 +57,17 @@ enum xrt_tracking_type // The device(s) are tracked by external SLAM XRT_TRACKING_TYPE_EXTERNAL_SLAM, + + /* @remove: on next commit + Is it a good idea to add a new tracking type instead of using _NONE? Two reasons: + 1. _NONE makes u_device_setup_tracking_origins modify tracking origins in + the app but this is not yet synced with the service + 2. _NONE is not quite exact, for what I understand qwerty devices *are* + being tracked. Though I might be missunderstanding what tracking is. + */ + + // The device(s) are tracked by other methods. + XRT_TRACKING_TYPE_OTHER, }; /*!