The open source OpenXR runtime
at prediction-2 253 lines 8.3 kB view raw
1// Copyright 2025, rcelyte 2// SPDX-License-Identifier: BSL-1.0 3/*! 4 * @file 5 * @brief Parser for a small subset of the SolarXR Flatbuffers protocol, as defined at 6 * https://github.com/SlimeVR/SolarXR-Protocol 7 * @ingroup drv_solarxr 8 */ 9 10#pragma once 11#include "xrt/xrt_defines.h" 12#include <assert.h> 13 14#ifdef __cplusplus 15extern "C" { 16#endif 17 18typedef uint32_t flatbuffers_uoffset_t; // little-endian byte order 19 20enum solarxr_body_part 21{ 22 SOLARXR_BODY_PART_NONE = 0, 23 SOLARXR_BODY_PART_HEAD = 1, 24 SOLARXR_BODY_PART_NECK = 2, 25 SOLARXR_BODY_PART_CHEST = 3, 26 SOLARXR_BODY_PART_WAIST = 4, 27 SOLARXR_BODY_PART_HIP = 5, 28 SOLARXR_BODY_PART_LEFT_UPPER_LEG = 6, 29 SOLARXR_BODY_PART_RIGHT_UPPER_LEG = 7, 30 SOLARXR_BODY_PART_LEFT_LOWER_LEG = 8, 31 SOLARXR_BODY_PART_RIGHT_LOWER_LEG = 9, 32 SOLARXR_BODY_PART_LEFT_FOOT = 10, 33 SOLARXR_BODY_PART_RIGHT_FOOT = 11, 34 SOLARXR_BODY_PART_LEFT_LOWER_ARM = 14, 35 SOLARXR_BODY_PART_RIGHT_LOWER_ARM = 15, 36 SOLARXR_BODY_PART_LEFT_UPPER_ARM = 16, 37 SOLARXR_BODY_PART_RIGHT_UPPER_ARM = 17, 38 SOLARXR_BODY_PART_LEFT_HAND = 18, 39 SOLARXR_BODY_PART_RIGHT_HAND = 19, 40 SOLARXR_BODY_PART_LEFT_SHOULDER = 20, 41 SOLARXR_BODY_PART_RIGHT_SHOULDER = 21, 42 SOLARXR_BODY_PART_UPPER_CHEST = 22, 43 SOLARXR_BODY_PART_LEFT_HIP = 23, 44 SOLARXR_BODY_PART_RIGHT_HIP = 24, 45 SOLARXR_BODY_PART_LEFT_THUMB_PROXIMAL = 25, 46 SOLARXR_BODY_PART_LEFT_THUMB_INTERMEDIATE = 26, 47 SOLARXR_BODY_PART_LEFT_THUMB_DISTAL = 27, 48 SOLARXR_BODY_PART_LEFT_INDEX_PROXIMAL = 28, 49 SOLARXR_BODY_PART_LEFT_INDEX_INTERMEDIATE = 29, 50 SOLARXR_BODY_PART_LEFT_INDEX_DISTAL = 30, 51 SOLARXR_BODY_PART_LEFT_MIDDLE_PROXIMAL = 31, 52 SOLARXR_BODY_PART_LEFT_MIDDLE_INTERMEDIATE = 32, 53 SOLARXR_BODY_PART_LEFT_MIDDLE_DISTAL = 33, 54 SOLARXR_BODY_PART_LEFT_RING_PROXIMAL = 34, 55 SOLARXR_BODY_PART_LEFT_RING_INTERMEDIATE = 35, 56 SOLARXR_BODY_PART_LEFT_RING_DISTAL = 36, 57 SOLARXR_BODY_PART_LEFT_LITTLE_PROXIMAL = 37, 58 SOLARXR_BODY_PART_LEFT_LITTLE_INTERMEDIATE = 38, 59 SOLARXR_BODY_PART_LEFT_LITTLE_DISTAL = 39, 60 SOLARXR_BODY_PART_RIGHT_THUMB_PROXIMAL = 40, 61 SOLARXR_BODY_PART_RIGHT_THUMB_INTERMEDIATE = 41, 62 SOLARXR_BODY_PART_RIGHT_THUMB_DISTAL = 42, 63 SOLARXR_BODY_PART_RIGHT_INDEX_PROXIMAL = 43, 64 SOLARXR_BODY_PART_RIGHT_INDEX_INTERMEDIATE = 44, 65 SOLARXR_BODY_PART_RIGHT_INDEX_DISTAL = 45, 66 SOLARXR_BODY_PART_RIGHT_MIDDLE_PROXIMAL = 46, 67 SOLARXR_BODY_PART_RIGHT_MIDDLE_INTERMEDIATE = 47, 68 SOLARXR_BODY_PART_RIGHT_MIDDLE_DISTAL = 48, 69 SOLARXR_BODY_PART_RIGHT_RING_PROXIMAL = 49, 70 SOLARXR_BODY_PART_RIGHT_RING_INTERMEDIATE = 50, 71 SOLARXR_BODY_PART_RIGHT_RING_DISTAL = 51, 72 SOLARXR_BODY_PART_RIGHT_LITTLE_PROXIMAL = 52, 73 SOLARXR_BODY_PART_RIGHT_LITTLE_INTERMEDIATE = 53, 74 SOLARXR_BODY_PART_RIGHT_LITTLE_DISTAL = 54, 75 SOLARXR_BODY_PART_MAX_ENUM, 76}; 77 78#define FLATBUFFERS_VECTOR(type_) \ 79 struct \ 80 { \ 81 uint32_t length; \ 82 const type_ *data; \ 83 } 84 85struct solarxr_tracker_id 86{ // table solarxr_protocol.datatypes.TrackerId 87 bool has_device_id; 88 uint8_t device_id; 89 uint8_t tracker_num; 90}; 91 92struct solarxr_tracker_info 93{ // table solarxr_protocol.data_feed.tracker.TrackerInfo 94 enum solarxr_body_part body_part; 95 FLATBUFFERS_VECTOR(char) display_name; 96}; 97 98typedef struct 99{ 100 flatbuffers_uoffset_t offset; 101} solarxr_tracker_data_t; 102 103struct solarxr_tracker_data 104{ // table solarxr_protocol.data_feed.tracker.TrackerData 105 bool has_info; 106 bool has_rotation; 107 bool has_position; 108 bool has_raw_angular_velocity; 109 bool has_linear_acceleration; 110 struct solarxr_tracker_id tracker_id; 111 struct solarxr_tracker_info info; 112 struct xrt_quat rotation; 113 struct xrt_vec3 position; 114 struct xrt_vec3 raw_angular_velocity; 115 struct xrt_vec3 linear_acceleration; 116}; 117 118typedef struct 119{ 120 flatbuffers_uoffset_t offset; 121} solarxr_device_data_t; 122 123struct solarxr_device_data 124{ // table solarxr_protocol.data_feed.device_data.DeviceData 125 uint8_t id; 126 FLATBUFFERS_VECTOR(solarxr_tracker_data_t) trackers; // solarxr_protocol.data_feed.tracker.TrackerData[] 127}; 128 129typedef struct 130{ 131 flatbuffers_uoffset_t offset; 132} solarxr_bone_t; 133 134struct solarxr_bone 135{ // table solarxr_protocol.data_feed.Bone 136 enum solarxr_body_part body_part; 137 struct xrt_quat rotation_g; 138 float bone_length; 139 struct xrt_vec3 head_position_g; 140}; 141 142struct solarxr_data_feed_update 143{ // table solarxr_protocol.data_feed.DataFeedUpdate 144 FLATBUFFERS_VECTOR(solarxr_device_data_t) devices; // solarxr_protocol.data_feed.device_data.DeviceData[] 145 FLATBUFFERS_VECTOR(solarxr_tracker_data_t) 146 synthetic_trackers; // solarxr_protocol.data_feed.tracker.TrackerData[] 147 FLATBUFFERS_VECTOR(solarxr_bone_t) bones; // solarxr_protocol.data_feed.Bone[] 148}; 149 150enum solarxr_data_feed_message_type 151{ 152 SOLARXR_DATA_FEED_MESSAGE_POLL_DATA_FEED = 1, 153 SOLARXR_DATA_FEED_MESSAGE_DATA_FEED_UPDATE = 3, 154}; 155 156union solarxr_data_feed_message { // union solarxr_protocol.data_feed.DataFeedMessage 157 struct solarxr_data_feed_update data_feed_update; 158}; 159 160typedef struct 161{ 162 flatbuffers_uoffset_t offset; 163} solarxr_data_feed_message_header_t; 164 165struct solarxr_data_feed_message_header 166{ // table solarxr_protocol.data_feed.DataFeedMessageHeader 167 enum solarxr_data_feed_message_type message_type; 168 union solarxr_data_feed_message message; 169}; 170 171struct solarxr_steamvr_trackers_setting 172{ // table solarxr_protocol.rpc.SteamVRTrackersSetting 173 bool waist; 174 bool chest; 175 bool left_foot; 176 bool right_foot; 177 bool left_knee; 178 bool right_knee; 179 bool left_elbow; 180 bool right_elbow; 181 bool left_hand; 182 bool right_hand; 183}; 184 185struct solarxr_settings_response 186{ // table solarxr_protocol.rpc.SettingsResponse 187 struct solarxr_steamvr_trackers_setting steam_vr_trackers; 188}; 189 190enum solarxr_rpc_message_type 191{ 192 SOLARXR_RPC_MESSAGE_TYPE_SETTINGS_REQUEST = 6, 193 SOLARXR_RPC_MESSAGE_TYPE_SETTINGS_RESPONSE = 7, 194}; 195 196union solarxr_rpc_message { // union solarxr_protocol.rpc.RpcMessage 197 struct solarxr_settings_response settings_response; 198}; 199 200typedef struct 201{ 202 flatbuffers_uoffset_t offset; 203} solarxr_rpc_message_header_t; 204 205struct solarxr_rpc_message_header 206{ // table solarxr_protocol.rpc.RpcMessageHeader 207 enum solarxr_rpc_message_type message_type; 208 union solarxr_rpc_message message; 209}; 210 211typedef struct 212{ 213 flatbuffers_uoffset_t offset; 214} solarxr_message_bundle_t; 215 216struct solarxr_message_bundle 217{ // table solarxr_protocol.MessageBundle 218 FLATBUFFERS_VECTOR(solarxr_data_feed_message_header_t) 219 data_feed_msgs; // solarxr_protocol.data_feed.DataFeedMessageHeader[] 220 FLATBUFFERS_VECTOR(solarxr_rpc_message_header_t) rpc_msgs; // solarxr_protocol.rpc.RpcMessageHeader[] 221}; 222 223bool 224read_solarxr_message_bundle(struct solarxr_message_bundle *out, 225 const uint8_t buffer[], 226 size_t buffer_len, 227 const solarxr_message_bundle_t *ref); 228bool 229read_solarxr_data_feed_message_header(struct solarxr_data_feed_message_header *out, 230 const uint8_t buffer[], 231 size_t buffer_len, 232 const solarxr_data_feed_message_header_t *ref); 233bool 234read_solarxr_rpc_message_header(struct solarxr_rpc_message_header *out, 235 const uint8_t buffer[], 236 size_t buffer_len, 237 const solarxr_rpc_message_header_t *ref); 238bool 239read_solarxr_device_data(struct solarxr_device_data *out, 240 const uint8_t buffer[], 241 size_t buffer_len, 242 const solarxr_device_data_t *ref); 243bool 244read_solarxr_tracker_data(struct solarxr_tracker_data *out, 245 const uint8_t buffer[], 246 size_t buffer_len, 247 const solarxr_tracker_data_t *ref); 248bool 249read_solarxr_bone(struct solarxr_bone *out, const uint8_t buffer[], size_t buffer_len, const solarxr_bone_t *ref); 250 251#ifdef __cplusplus 252} 253#endif