The open source OpenXR runtime
at main 193 lines 5.3 kB view raw
1// Copyright 2022, Collabora, Ltd. 2// SPDX-License-Identifier: BSL-1.0 3/*! 4 * @file 5 * @brief Hand tracking interfaces. 6 * @author Jakob Bornecrantz <jakob@collabora.com> 7 * @ingroup xrt_iface 8 */ 9 10#pragma once 11 12#include "xrt/xrt_defines.h" 13#include "xrt/xrt_frame.h" 14#include "xrt/xrt_tracking.h" 15 16 17#ifdef __cplusplus 18extern "C" { 19#endif 20 21/*! 22 * @brief Image boundary type. 23 * 24 * Currently used by hand-tracking to determine if parts of the hand are not visible to the camera, ie. they are outside 25 * of the camera's vignette. 26 * 27 * Feel free to move this out of t_hand_tracking if this becomes more generally applicable. 28 * 29 * @ingroup xrt_iface 30 */ 31enum t_image_boundary_type 32{ 33 HT_IMAGE_BOUNDARY_NONE, 34 HT_IMAGE_BOUNDARY_CIRCLE, 35}; 36 37/*! 38 * @brief Circular image boundary. 39 * 40 * Currently used by hand-tracking to determine if parts of the hand are not visible to the camera, ie. they are outside 41 * of the camera's vignette. 42 * 43 * Feel free to move this out of t_hand_tracking if this becomes more generally applicable. 44 * 45 * @ingroup xrt_iface 46 */ 47struct t_image_boundary_circle 48{ 49 // The center, in normalized 0-1 UV coordinates. 50 // Should probably be between 0 and 1 in pixel coordinates. 51 struct xrt_vec2 normalized_center; 52 // The radius, divided by the image width. 53 // For Index, should be around 0.5. 54 float normalized_radius; 55}; 56 57/*! 58 * @brief Logical orientation of the camera image, relative to the user's head. 59 * For example, Rift S uses CAMERA_ORIENTATION_90 for the two front cameras. 60 * 61 * Feel free to move this out of t_hand_tracking if this becomes more generally applicable. 62 * 63 */ 64enum t_camera_orientation 65{ 66 CAMERA_ORIENTATION_0 = 0, // Normal "horizontal" orientation 67 CAMERA_ORIENTATION_90 = 90, // Camera rotated 90° to the right 68 CAMERA_ORIENTATION_180 = 180, // Camera rotated 180° upside down 69 CAMERA_ORIENTATION_270 = 270, // Camera rotated 270° to the left 70}; 71 72 73/*! 74 * @brief Information about image boundary and camera orientation for one view. 75 * 76 * Currently used by hand-tracking to determine if parts of the hand are not 77 * visible to the camera, ie. they are outside of the camera's vignette. 78 * 79 * @ingroup xrt_iface 80 */ 81struct t_camera_extra_info_one_view 82{ 83 enum t_image_boundary_type boundary_type; 84 85 union { 86 struct t_image_boundary_circle circle; 87 } boundary; 88 89 enum t_camera_orientation camera_orientation; 90}; 91 92/*! 93 * @brief Information about image boundaries and camera orientations for all the 94 * cameras used in a tracking system. 95 * 96 * Currently used by hand-tracking to determine if parts of the hand are not 97 * visible to the camera, ie. they are outside of the camera's vignette. 98 * 99 * @ingroup xrt_iface 100 */ 101struct t_camera_extra_info 102{ 103 //!@todo Hardcoded to 2 - needs to increase as we support headsets with more cameras. 104 struct t_camera_extra_info_one_view views[2]; 105}; 106 107/*! 108 * Creation info for the creation of a hand tracker 109 */ 110struct t_hand_tracking_create_info 111{ 112 struct t_camera_extra_info cams_info; //!< Extra camera info 113 struct xrt_hand_masks_sink *masks_sink; //!< Optional sink to stream hand bounding boxes to 114}; 115 116/*! 117 * Synchronously processes frames and returns two hands. 118 */ 119struct t_hand_tracking_sync 120{ 121 /*! 122 * Process left and right view and get back a result synchronously. 123 */ 124 void (*process)(struct t_hand_tracking_sync *ht_sync, 125 struct xrt_frame *left_frame, 126 struct xrt_frame *right_frame, 127 struct xrt_hand_joint_set *out_left_hand, 128 struct xrt_hand_joint_set *out_right_hand, 129 int64_t *out_timestamp_ns); 130 131 /*! 132 * Destroy this hand tracker sync object. 133 */ 134 void (*destroy)(struct t_hand_tracking_sync *ht_sync); 135}; 136 137/*! 138 * @copydoc t_hand_tracking_sync::process 139 * 140 * @public @memberof t_hand_tracking_sync 141 */ 142static inline void 143t_ht_sync_process(struct t_hand_tracking_sync *ht_sync, 144 struct xrt_frame *left_frame, 145 struct xrt_frame *right_frame, 146 struct xrt_hand_joint_set *out_left_hand, 147 struct xrt_hand_joint_set *out_right_hand, 148 int64_t *out_timestamp_ns) 149{ 150 ht_sync->process(ht_sync, left_frame, right_frame, out_left_hand, out_right_hand, out_timestamp_ns); 151} 152 153/*! 154 * @copydoc t_hand_tracking_sync::destroy 155 * 156 * Helper for calling through the function pointer: does a null check and sets 157 * ht_sync_ptr to null if freed. 158 * 159 * @public @memberof t_hand_tracking_sync 160 */ 161static inline void 162t_ht_sync_destroy(struct t_hand_tracking_sync **ht_sync_ptr) 163{ 164 struct t_hand_tracking_sync *ht_sync = *ht_sync_ptr; 165 if (ht_sync == NULL) { 166 return; 167 } 168 169 ht_sync->destroy(ht_sync); 170 *ht_sync_ptr = NULL; 171} 172 173struct t_hand_tracking_async 174{ 175 struct xrt_frame_node node; 176 struct xrt_frame_sink left; 177 struct xrt_frame_sink right; 178 struct xrt_slam_sinks sinks; //!< Pointers to `left` and `right` sinks 179 180 void (*get_hand)(struct t_hand_tracking_async *ht_async, 181 enum xrt_input_name name, 182 int64_t desired_timestamp_ns, 183 struct xrt_hand_joint_set *out_value, 184 int64_t *out_timestamp_ns); 185}; 186 187struct t_hand_tracking_async * 188t_hand_tracking_async_default_create(struct xrt_frame_context *xfctx, struct t_hand_tracking_sync *sync); 189 190 191#ifdef __cplusplus 192} // extern "C" 193#endif