Monado OpenXR Runtime
oxr_conversions.h
Go to the documentation of this file.
1// Copyright 2018-2024, Collabora, Ltd.
2// Copyright 2024-2025, NVIDIA CORPORATION.
3// SPDX-License-Identifier: BSL-1.0
4/*!
5 * @file
6 * @brief Smaller helper functions to convert between xrt and OpenXR things.
7 * @author Christoph Haag <christoph.haag@collabora.com>
8 * @author Jakob Bornecrantz <jakob@collabora.com>
9 * @ingroup oxr_main
10 */
11
12#pragma once
13
14#include "xrt/xrt_defines.h"
15#include "xrt/xrt_space.h"
18
19#include "oxr_defines.h"
20
21
22/*
23 *
24 * Space things.
25 *
26 */
27
28static inline XrSpaceLocationFlags
29xrt_to_xr_space_location_flags(enum xrt_space_relation_flags relation_flags)
30{
31 // clang-format off
32 bool valid_ori = (relation_flags & XRT_SPACE_RELATION_ORIENTATION_VALID_BIT) != 0;
33 bool tracked_ori = (relation_flags & XRT_SPACE_RELATION_ORIENTATION_TRACKED_BIT) != 0;
34 bool valid_pos = (relation_flags & XRT_SPACE_RELATION_POSITION_VALID_BIT) != 0;
35 bool tracked_pos = (relation_flags & XRT_SPACE_RELATION_POSITION_TRACKED_BIT) != 0;
36
37 bool linear_vel = (relation_flags & XRT_SPACE_RELATION_LINEAR_VELOCITY_VALID_BIT) != 0;
38 bool angular_vel = (relation_flags & XRT_SPACE_RELATION_ANGULAR_VELOCITY_VALID_BIT) != 0;
39 // clang-format on
40
41 XrSpaceLocationFlags location_flags = (XrSpaceLocationFlags)0;
42 if (valid_ori) {
43 location_flags |= XR_SPACE_LOCATION_ORIENTATION_VALID_BIT;
44 }
45 if (tracked_ori) {
46 location_flags |= XR_SPACE_LOCATION_ORIENTATION_TRACKED_BIT;
47 }
48 if (valid_pos) {
49 location_flags |= XR_SPACE_LOCATION_POSITION_VALID_BIT;
50 }
51 if (tracked_pos) {
52 location_flags |= XR_SPACE_LOCATION_POSITION_TRACKED_BIT;
53 }
54 if (linear_vel) {
55 location_flags |= XR_SPACE_VELOCITY_LINEAR_VALID_BIT;
56 }
57 if (angular_vel) {
58 location_flags |= XR_SPACE_VELOCITY_ANGULAR_VALID_BIT;
59 }
60
61 return location_flags;
62}
63
64static inline XrReferenceSpaceType
65oxr_ref_space_to_xr(enum oxr_space_type space_type)
66{
67 switch (space_type) {
68 case OXR_SPACE_TYPE_REFERENCE_VIEW: return XR_REFERENCE_SPACE_TYPE_VIEW;
69 case OXR_SPACE_TYPE_REFERENCE_LOCAL: return XR_REFERENCE_SPACE_TYPE_LOCAL;
70 case OXR_SPACE_TYPE_REFERENCE_LOCAL_FLOOR: return XR_REFERENCE_SPACE_TYPE_LOCAL_FLOOR_EXT;
71 case OXR_SPACE_TYPE_REFERENCE_STAGE: return XR_REFERENCE_SPACE_TYPE_STAGE;
72 case OXR_SPACE_TYPE_REFERENCE_UNBOUNDED_MSFT: return XR_REFERENCE_SPACE_TYPE_UNBOUNDED_MSFT;
73 case OXR_SPACE_TYPE_REFERENCE_COMBINED_EYE_VARJO: return XR_REFERENCE_SPACE_TYPE_COMBINED_EYE_VARJO;
74 case OXR_SPACE_TYPE_REFERENCE_LOCALIZATION_MAP_ML: return XR_REFERENCE_SPACE_TYPE_LOCALIZATION_MAP_ML;
75
76 case OXR_SPACE_TYPE_ACTION: return XR_REFERENCE_SPACE_TYPE_MAX_ENUM;
77 case OXR_SPACE_TYPE_XDEV_POSE: return XR_REFERENCE_SPACE_TYPE_MAX_ENUM;
78 }
79
80 return XR_REFERENCE_SPACE_TYPE_MAX_ENUM;
81}
82
83static inline enum oxr_space_type
84xr_ref_space_to_oxr(XrReferenceSpaceType space_type)
85{
86 switch (space_type) {
87 case XR_REFERENCE_SPACE_TYPE_VIEW: return OXR_SPACE_TYPE_REFERENCE_VIEW;
88 case XR_REFERENCE_SPACE_TYPE_LOCAL: return OXR_SPACE_TYPE_REFERENCE_LOCAL;
89 case XR_REFERENCE_SPACE_TYPE_LOCAL_FLOOR_EXT: return OXR_SPACE_TYPE_REFERENCE_LOCAL_FLOOR;
90 case XR_REFERENCE_SPACE_TYPE_STAGE: return OXR_SPACE_TYPE_REFERENCE_STAGE;
91 case XR_REFERENCE_SPACE_TYPE_UNBOUNDED_MSFT: return OXR_SPACE_TYPE_REFERENCE_UNBOUNDED_MSFT;
92 case XR_REFERENCE_SPACE_TYPE_COMBINED_EYE_VARJO: return OXR_SPACE_TYPE_REFERENCE_COMBINED_EYE_VARJO;
93 case XR_REFERENCE_SPACE_TYPE_LOCALIZATION_MAP_ML: return OXR_SPACE_TYPE_REFERENCE_LOCALIZATION_MAP_ML;
94
95 case XR_REFERENCE_SPACE_TYPE_MAX_ENUM: return (enum oxr_space_type) - 1;
96 }
97
98 // wrap around or negative depending on enum data type, invalid value either way.
99 return (enum oxr_space_type) - 1;
100}
101
102static inline const char *
103xr_ref_space_to_string(XrReferenceSpaceType space_type)
104{
105 switch (space_type) {
106 case XR_REFERENCE_SPACE_TYPE_VIEW: return "XR_REFERENCE_SPACE_TYPE_VIEW";
107 case XR_REFERENCE_SPACE_TYPE_LOCAL: return "XR_REFERENCE_SPACE_TYPE_LOCAL";
108 case XR_REFERENCE_SPACE_TYPE_LOCAL_FLOOR_EXT: return "XR_REFERENCE_SPACE_TYPE_LOCAL_FLOOR_EXT";
109 case XR_REFERENCE_SPACE_TYPE_STAGE: return "XR_REFERENCE_SPACE_TYPE_STAGE";
110 case XR_REFERENCE_SPACE_TYPE_UNBOUNDED_MSFT: return "XR_REFERENCE_SPACE_TYPE_UNBOUNDED_MSFT";
111 case XR_REFERENCE_SPACE_TYPE_COMBINED_EYE_VARJO: return "XR_REFERENCE_SPACE_TYPE_COMBINED_EYE_VARJO";
112 case XR_REFERENCE_SPACE_TYPE_MAX_ENUM: return "XR_REFERENCE_SPACE_TYPE_MAX_ENUM";
113 default: return "UNKNOWN REFERENCE SPACE";
114 }
115}
116
117static inline enum xrt_reference_space_type
118oxr_ref_space_to_xrt(enum oxr_space_type space_type)
119{
120 switch (space_type) {
121 case OXR_SPACE_TYPE_REFERENCE_VIEW: return XRT_SPACE_REFERENCE_TYPE_VIEW;
122 case OXR_SPACE_TYPE_REFERENCE_LOCAL: return XRT_SPACE_REFERENCE_TYPE_LOCAL;
123 case OXR_SPACE_TYPE_REFERENCE_LOCAL_FLOOR: return XRT_SPACE_REFERENCE_TYPE_LOCAL_FLOOR;
124 case OXR_SPACE_TYPE_REFERENCE_STAGE: return XRT_SPACE_REFERENCE_TYPE_STAGE;
125 case OXR_SPACE_TYPE_REFERENCE_UNBOUNDED_MSFT: return XRT_SPACE_REFERENCE_TYPE_UNBOUNDED;
126
127 // Has no mapping to a Monado semantic space.
128 case OXR_SPACE_TYPE_REFERENCE_COMBINED_EYE_VARJO: return XRT_SPACE_REFERENCE_TYPE_INVALID;
129 case OXR_SPACE_TYPE_REFERENCE_LOCALIZATION_MAP_ML: return XRT_SPACE_REFERENCE_TYPE_INVALID;
130 case OXR_SPACE_TYPE_ACTION: return XRT_SPACE_REFERENCE_TYPE_INVALID;
131 case OXR_SPACE_TYPE_XDEV_POSE: return XRT_SPACE_REFERENCE_TYPE_INVALID;
132 }
133
134 /*
135 * This is the default case, we do not have a explicit default case
136 * so that we get warnings for unhandled enum members. This is fine
137 * because the C specification says if there is no default case and
138 * and a non-matching value is given no case is executed.
139 */
140
142}
143
144static inline enum xrt_reference_space_type
145xr_ref_space_to_xrt(XrReferenceSpaceType space_type)
146{
147 switch (space_type) {
148 case XR_REFERENCE_SPACE_TYPE_VIEW: return XRT_SPACE_REFERENCE_TYPE_VIEW;
149 case XR_REFERENCE_SPACE_TYPE_LOCAL: return XRT_SPACE_REFERENCE_TYPE_LOCAL;
150 case XR_REFERENCE_SPACE_TYPE_LOCAL_FLOOR_EXT: return XRT_SPACE_REFERENCE_TYPE_LOCAL_FLOOR;
151 case XR_REFERENCE_SPACE_TYPE_STAGE: return XRT_SPACE_REFERENCE_TYPE_STAGE;
152 case XR_REFERENCE_SPACE_TYPE_UNBOUNDED_MSFT: return XRT_SPACE_REFERENCE_TYPE_UNBOUNDED;
153
154 case XR_REFERENCE_SPACE_TYPE_COMBINED_EYE_VARJO: return XRT_SPACE_REFERENCE_TYPE_INVALID;
155 case XR_REFERENCE_SPACE_TYPE_LOCALIZATION_MAP_ML: return XRT_SPACE_REFERENCE_TYPE_INVALID;
156 case XR_REFERENCE_SPACE_TYPE_MAX_ENUM: return XRT_SPACE_REFERENCE_TYPE_INVALID;
157 }
158
160}
161
162
163/*
164 *
165 * Form factor things.
166 *
167 */
168
169static inline enum xrt_form_factor
170xr_form_factor_to_xrt(XrFormFactor form_factor)
171{
172 switch (form_factor) {
173 case XR_FORM_FACTOR_HANDHELD_DISPLAY: return XRT_FORM_FACTOR_HANDHELD;
174 case XR_FORM_FACTOR_HEAD_MOUNTED_DISPLAY: return XRT_FORM_FACTOR_HMD;
175 case XR_FORM_FACTOR_MAX_ENUM: assert(false); return 0; // As good as any.
176 }
177
178 // Used as default, to get warnings.
179 return XRT_FORM_FACTOR_HMD;
180}
181
182static inline enum XrFormFactor
183xrt_form_factor_to_xr(enum xrt_form_factor form_factor)
184{
185 switch (form_factor) {
186 case XRT_FORM_FACTOR_HANDHELD: return XR_FORM_FACTOR_HANDHELD_DISPLAY;
187 case XRT_FORM_FACTOR_HMD: return XR_FORM_FACTOR_HEAD_MOUNTED_DISPLAY;
188 }
189
190 // Used as default, to get warnings.
191 return XR_FORM_FACTOR_HEAD_MOUNTED_DISPLAY;
192}
193
194
195/*
196 *
197 * IO things.
198 *
199 */
200
201static inline const char *
202xrt_input_type_to_str(enum xrt_input_type type)
203{
204 // clang-format off
205 switch (type) {
206 case XRT_INPUT_TYPE_VEC1_ZERO_TO_ONE: return "XRT_INPUT_TYPE_VEC1_ZERO_TO_ONE";
207 case XRT_INPUT_TYPE_VEC1_MINUS_ONE_TO_ONE: return "XRT_INPUT_TYPE_VEC1_MINUS_ONE_TO_ONE";
208 case XRT_INPUT_TYPE_VEC2_MINUS_ONE_TO_ONE: return "XRT_INPUT_TYPE_VEC2_MINUS_ONE_TO_ONE";
209 case XRT_INPUT_TYPE_VEC3_MINUS_ONE_TO_ONE: return "XRT_INPUT_TYPE_VEC3_MINUS_ONE_TO_ONE";
210 case XRT_INPUT_TYPE_BOOLEAN: return "XRT_INPUT_TYPE_BOOLEAN";
211 case XRT_INPUT_TYPE_POSE: return "XRT_INPUT_TYPE_POSE";
212 default: return "XRT_INPUT_UNKNOWN";
213 }
214 // clang-format on
215}
216
217static inline enum xrt_perf_set_level
218xr_perf_level_to_xrt(XrPerfSettingsLevelEXT level)
219{
220 switch (level) {
221 case XR_PERF_SETTINGS_LEVEL_POWER_SAVINGS_EXT: return XRT_PERF_SET_LEVEL_POWER_SAVINGS;
222 case XR_PERF_SETTINGS_LEVEL_SUSTAINED_LOW_EXT: return XRT_PERF_SET_LEVEL_SUSTAINED_LOW;
223 case XR_PERF_SETTINGS_LEVEL_SUSTAINED_HIGH_EXT: return XRT_PERF_SET_LEVEL_SUSTAINED_HIGH;
224 case XR_PERF_SETTINGS_LEVEL_BOOST_EXT: return XRT_PERF_SET_LEVEL_BOOST;
225 default: assert(false); return 0;
226 }
227}
228
229static inline enum xrt_perf_domain
230xr_perf_domain_to_xrt(XrPerfSettingsDomainEXT domain)
231{
232 switch (domain) {
233 case XR_PERF_SETTINGS_DOMAIN_CPU_EXT: return XRT_PERF_DOMAIN_CPU;
234 case XR_PERF_SETTINGS_DOMAIN_GPU_EXT: return XRT_PERF_DOMAIN_GPU;
235 default: assert(false); return 0;
236 }
237}
238
239static inline XrPerfSettingsDomainEXT
240xrt_perf_domain_to_xr(enum xrt_perf_domain domain)
241{
242 switch (domain) {
243 case XRT_PERF_DOMAIN_CPU: return XR_PERF_SETTINGS_DOMAIN_CPU_EXT;
244 case XRT_PERF_DOMAIN_GPU: return XR_PERF_SETTINGS_DOMAIN_GPU_EXT;
245 default: assert(false); return 0;
246 }
247}
248
249static inline XrPerfSettingsSubDomainEXT
250xrt_perf_sub_domain_to_xr(enum xrt_perf_sub_domain subDomain)
251{
252 switch (subDomain) {
253 case XRT_PERF_SUB_DOMAIN_COMPOSITING: return XR_PERF_SETTINGS_SUB_DOMAIN_COMPOSITING_EXT;
254 case XRT_PERF_SUB_DOMAIN_RENDERING: return XR_PERF_SETTINGS_SUB_DOMAIN_RENDERING_EXT;
255 case XRT_PERF_SUB_DOMAIN_THERMAL: return XR_PERF_SETTINGS_SUB_DOMAIN_THERMAL_EXT;
256 default: assert(false); return 0;
257 }
258}
259
260static inline XrPerfSettingsNotificationLevelEXT
261xrt_perf_notify_level_to_xr(enum xrt_perf_notify_level level)
262{
263 switch (level) {
264 case XRT_PERF_NOTIFY_LEVEL_NORMAL: return XR_PERF_SETTINGS_NOTIF_LEVEL_NORMAL_EXT;
265 case XRT_PERF_NOTIFY_LEVEL_WARNING: return XR_PERF_SETTINGS_NOTIF_LEVEL_WARNING_EXT;
266 case XRT_PERF_NOTIFY_LEVEL_IMPAIRED: return XR_PERF_SETTINGS_NOTIF_LEVEL_IMPAIRED_EXT;
267 default: assert(false); return 0;
268 }
269}
270
271static inline enum xrt_input_name
272xr_hand_tracking_data_source_to_xrt(XrHandTrackingDataSourceEXT data_source, enum XrHandEXT hand)
273{
274 switch (data_source) {
275 case XR_HAND_TRACKING_DATA_SOURCE_UNOBSTRUCTED_EXT:
276 return (hand == XR_HAND_LEFT_EXT) ? XRT_INPUT_HT_UNOBSTRUCTED_LEFT : XRT_INPUT_HT_UNOBSTRUCTED_RIGHT;
277 case XR_HAND_TRACKING_DATA_SOURCE_CONTROLLER_EXT:
278 return (hand == XR_HAND_LEFT_EXT) ? XRT_INPUT_HT_CONFORMING_LEFT : XRT_INPUT_HT_CONFORMING_RIGHT;
279 default: assert(false); return (enum xrt_input_name)(-1);
280 }
281}
282
283static inline XrHandTrackingDataSourceEXT
284xrt_hand_tracking_data_source_to_xr(enum xrt_input_name ht_input_name)
285{
286 switch (ht_input_name) {
287 case XRT_INPUT_HT_UNOBSTRUCTED_LEFT:
288 case XRT_INPUT_HT_UNOBSTRUCTED_RIGHT: return XR_HAND_TRACKING_DATA_SOURCE_UNOBSTRUCTED_EXT;
289 case XRT_INPUT_HT_CONFORMING_LEFT:
290 case XRT_INPUT_HT_CONFORMING_RIGHT: return XR_HAND_TRACKING_DATA_SOURCE_CONTROLLER_EXT;
291 default: assert(false); return XR_HAND_TRACKING_DATA_SOURCE_MAX_ENUM_EXT;
292 }
293}
294
295
296/*
297 *
298 * Basic types
299 *
300 */
301
302static inline XrExtent2Di
303xrt_size_to_xr(const struct xrt_size *x)
304{
305 return (XrExtent2Di){
306 .width = x->w,
307 .height = x->h,
308 };
309}
310
311static inline XrVector2f
312xrt_vec2_to_xr(const struct xrt_vec2 *v)
313{
314 return (XrVector2f){
315 .x = v->x,
316 .y = v->y,
317 };
318}
319
320static inline XrVector3f
321xrt_vec3_to_xr(const struct xrt_vec3 *v)
322{
323 return (XrVector3f){
324 .x = v->x,
325 .y = v->y,
326 .z = v->z,
327 };
328}
329
330static inline XrQuaternionf
331xrt_quat_to_xr(const struct xrt_quat *q)
332{
333 return (XrQuaternionf){
334 .x = q->x,
335 .y = q->y,
336 .z = q->z,
337 .w = q->w,
338 };
339}
340
341static inline XrPosef
342xrt_pose_to_xr(const struct xrt_pose *q)
343{
344 return (XrPosef){
345 .orientation = xrt_quat_to_xr(&q->orientation),
346 .position = xrt_vec3_to_xr(&q->position),
347 };
348}
349
350
351/*
352 *
353 * View things
354 *
355 */
356
357static inline XrViewConfigurationType
358xrt_view_type_to_xr(enum xrt_view_type view_type)
359{
360 switch (view_type) {
361 case XRT_VIEW_TYPE_MONO: return XR_VIEW_CONFIGURATION_TYPE_PRIMARY_MONO;
362 case XRT_VIEW_TYPE_STEREO: return XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO;
363 }
364
365 // Used as default, to get warnings.
366 assert(false && "Invalid view type");
367 return XR_VIEW_CONFIGURATION_TYPE_MAX_ENUM;
368}
oxr_space_type
Internal enum for the type of space, lets us reason about action spaces.
Definition: oxr_defines.h:106
xrt_input_type
Base type of this inputs.
Definition: xrt_defines.h:833
xrt_form_factor
What form factor is this device, mostly maps onto OpenXR's XrFormFactor.
Definition: xrt_defines.h:2165
xrt_input_name
Every internal input source known to monado with a baked in type.
Definition: xrt_defines.h:1355
xrt_reference_space_type
Type of a OpenXR mapped reference space, maps to the semantic spaces on the xrt_space_overseer struct...
Definition: xrt_defines.h:612
#define XRT_SPACE_REFERENCE_TYPE_INVALID
An invalid xrt_reference_space_type, since it's invalid it's not listed in the enum.
Definition: xrt_defines.h:633
xrt_space_relation_flags
Flags of which components of a xrt_space_relation is valid.
Definition: xrt_defines.h:642
@ XRT_INPUT_TYPE_POSE
A tracked pose.
Definition: xrt_defines.h:846
@ XRT_INPUT_TYPE_VEC2_MINUS_ONE_TO_ONE
Vec2 input, components in [-1, 1].
Definition: xrt_defines.h:840
@ XRT_INPUT_TYPE_VEC3_MINUS_ONE_TO_ONE
Vec3 input, components in [-1, 1].
Definition: xrt_defines.h:842
@ XRT_INPUT_TYPE_VEC1_MINUS_ONE_TO_ONE
Float input in [-1, 1].
Definition: xrt_defines.h:838
@ XRT_INPUT_TYPE_BOOLEAN
Boolean (digital, binary) input.
Definition: xrt_defines.h:844
@ XRT_INPUT_TYPE_VEC1_ZERO_TO_ONE
Float input in [0, 1].
Definition: xrt_defines.h:836
@ XRT_FORM_FACTOR_HANDHELD
Handheld display.
Definition: xrt_defines.h:2167
@ XRT_FORM_FACTOR_HMD
Head mounted display.
Definition: xrt_defines.h:2166
Shared internal defines and enums in the state tracker.
A pose composed of a position and orientation.
Definition: xrt_defines.h:479
A quaternion with single floats.
Definition: xrt_defines.h:235
Image size.
Definition: xrt_defines.h:423
A 2 element vector with single floats.
Definition: xrt_defines.h:268
A 3 element vector with single floats.
Definition: xrt_defines.h:289
Common defines and enums for XRT.
xrt_perf_notify_level
Performance level.
Definition: xrt_defines.h:2212
xrt_perf_domain
Domain type.
Definition: xrt_defines.h:2185
xrt_view_type
View type to be rendered to by the compositor.
Definition: xrt_defines.h:2174
xrt_perf_set_level
Performance level.
Definition: xrt_defines.h:2201
Include all of the openxr headers in one place.
Header defining xrt space and space overseer.
Include all of the Vulkan headers in one place, and cope with any "messy" includes implied by it.