Monado OpenXR Runtime
m_api.h
Go to the documentation of this file.
1 // Copyright 2019, Collabora, Ltd.
2 // SPDX-License-Identifier: BSL-1.0
3 /*!
4  * @file
5  * @brief C interface to math library.
6  * @author Jakob Bornecrantz <jakob@collabora.com>
7  *
8  * @see xrt_vec3
9  * @see xrt_quat
10  * @see xrt_pose
11  * @see xrt_space_relation
12  * @ingroup aux_math
13  */
14 
15 #pragma once
16 
17 #include "xrt/xrt_defines.h"
18 
19 #ifdef __cplusplus
20 extern "C" {
21 #endif
22 
23 
24 /*!
25  * @defgroup aux_math Math
26  * @ingroup aux
27  *
28  * @brief C interface to some transform-related math functions.
29  */
30 
31 /*!
32  * @dir auxiliary/math
33  * @ingroup aux
34  *
35  * @brief C interface to some transform-related math functions.
36  */
37 
38 /*
39  *
40  * Defines.
41  *
42  */
43 
44 /*!
45  * Standard gravity acceleration constant.
46  *
47  * @ingroup aux_math
48  */
49 #define MATH_GRAVITY_M_S2 (9.8066)
50 
51 
52 /*
53  *
54  * Hash functions.
55  *
56  */
57 
58 /*!
59  * Generate a hash value from the given string, trailing zero not included.
60  *
61  * Hashing function used is not specified so no guarantee of staying the same
62  * between different versions of the software, or even when the same version
63  * is compiled on different platforms/libc++ as it might use std::hash.
64  *
65  * @ingroup aux_math
66  */
67 size_t
68 math_hash_string(const char *str_c, size_t length);
69 
70 
71 /*
72  *
73  * Vector functions
74  *
75  */
76 
77 /*!
78  * Check if this vec3 is valid for math operations.
79  *
80  * @relates xrt_vec3
81  * @ingroup aux_math
82  */
83 bool
84 math_vec3_validate(const struct xrt_vec3 *vec3);
85 
86 /*!
87  * Accumulate a vector by adding in-place.
88  *
89  * Logically, *inAndOut += *additional
90  * OK if the two arguments are the same addresses.
91  *
92  * @relates xrt_vec3
93  * @ingroup aux_math
94  */
95 void
96 math_vec3_accum(const struct xrt_vec3 *additional, struct xrt_vec3 *inAndOut);
97 
98 /*!
99  * Cross product of a vector.
100  *
101  * @relates xrt_vec3
102  * @ingroup aux_math
103  */
104 void
105 math_vec3_cross(const struct xrt_vec3 *l,
106  const struct xrt_vec3 *r,
107  struct xrt_vec3 *result);
108 
109 
110 /*
111  *
112  * Quat functions.
113  *
114  */
115 
116 /*!
117  * Create a rotation from a angle in radians and a vector.
118  *
119  * @relates xrt_quat
120  * @relates xrt_vec3
121  * @ingroup aux_math
122  */
123 void
124 math_quat_from_angle_vector(float angle_rads,
125  const struct xrt_vec3 *vector,
126  struct xrt_quat *result);
127 
128 /*!
129  * Create a rotation from a 3x3 rotation matrix.
130  *
131  * @relates xrt_quat
132  * @relates xrt_matrix_3x3
133  * @ingroup aux_math
134  */
135 void
136 math_quat_from_matrix_3x3(const struct xrt_matrix_3x3 *mat,
137  struct xrt_quat *result);
138 
139 /*!
140  * Create a rotation from two vectors plus x and z, by creating a rotation
141  * matrix by crossing z and x to get the y axis.
142  *
143  * @relates xrt_quat
144  * @relates xrt_vec3
145  * @ingroup aux_math
146  */
147 void
148 math_quat_from_plus_x_z(const struct xrt_vec3 *plus_x,
149  const struct xrt_vec3 *plus_z,
150  struct xrt_quat *result);
151 
152 /*!
153  * Check if this quat can be used in transformation operations.
154  *
155  * @relates xrt_quat
156  * @ingroup aux_math
157  */
158 bool
159 math_quat_validate(const struct xrt_quat *quat);
160 
161 /*!
162  * Normalize a quaternion.
163  *
164  * @relates xrt_quat
165  * @ingroup aux_math
166  */
167 void
168 math_quat_normalize(struct xrt_quat *inout);
169 
170 /*!
171  * Rotate a vector.
172  *
173  * @relates xrt_quat
174  * @relatesalso xrt_vec3
175  * @ingroup aux_math
176  */
177 void
178 math_quat_rotate_vec3(const struct xrt_quat *left,
179  const struct xrt_vec3 *right,
180  struct xrt_vec3 *result);
181 
182 /*!
183  * Rotate a quaternion (compose rotations).
184  *
185  * @relates xrt_quat
186  * @ingroup aux_math
187  */
188 void
189 math_quat_rotate(const struct xrt_quat *left,
190  const struct xrt_quat *right,
191  struct xrt_quat *result);
192 
193 
194 /*!
195  * Integrate an angular velocity vector (exponential map) and apply to a
196  * quaternion.
197  *
198  * ang_vel and dt should share the same units of time, and the ang_vel
199  * vector should be in radians per unit of time.
200  *
201  * @relates xrt_quat
202  * @relatesalso xrt_vec3
203  * @ingroup aux_math
204  */
205 void
206 math_quat_integrate_velocity(const struct xrt_quat *quat,
207  const struct xrt_vec3 *ang_vel,
208  float dt,
209  struct xrt_quat *result);
210 
211 /*!
212  * Compute an angular velocity vector (exponential map format) by taking the
213  * finite difference of two quaternions.
214  *
215  * quat1 is the orientation dt time after the orientation was quat0
216  *
217  * out_ang_vel and dt share the same units of time, and out_ang_vel is be in
218  * radians per unit of time.
219  *
220  * @relates xrt_quat
221  * @relatesalso xrt_vec3
222  * @ingroup aux_math
223  */
224 void
225 math_quat_finite_difference(const struct xrt_quat *quat0,
226  const struct xrt_quat *quat1,
227  float dt,
228  struct xrt_vec3 *out_ang_vel);
229 
230 
231 /*
232  *
233  * Matrix function
234  *
235  */
236 
237 void
238 math_matrix_3x3_transform_vec3(const struct xrt_matrix_3x3 *left,
239  const struct xrt_vec3 *right,
240  struct xrt_vec3 *result);
241 
242 
243 /*
244  *
245  * Pose functions.
246  *
247  */
248 
249 /*!
250  * Check if this pose can be used in transformation operations.
251  *
252  * @relates xrt_pose
253  * @ingroup aux_math
254  */
255 bool
256 math_pose_validate(const struct xrt_pose *pose);
257 
258 /*!
259  * Invert pose.
260  *
261  * OK if input and output are the same addresses.
262  *
263  * @relates xrt_pose
264  * @ingroup aux_math
265  */
266 void
267 math_pose_invert(const struct xrt_pose *pose, struct xrt_pose *outPose);
268 
269 /*!
270  * Apply a rigid-body transformation to a pose.
271  *
272  * OK if input and output are the same addresses.
273  *
274  * @relates xrt_pose
275  * @ingroup aux_math
276  */
277 void
278 math_pose_transform(const struct xrt_pose *transform,
279  const struct xrt_pose *pose,
280  struct xrt_pose *outPose);
281 
282 /*!
283  * Apply a rigid-body transformation to a point.
284  *
285  * The input point and output may be the same pointer.
286  *
287  * @relates xrt_pose
288  * @relates xrt_vec3
289  * @ingroup aux_math
290  */
291 void
292 math_pose_transform_point(const struct xrt_pose *transform,
293  const struct xrt_vec3 *point,
294  struct xrt_vec3 *out_point);
295 
296 /*!
297  * Combine the poses of the target and base space with the relative pose of
298  * those spaces. In a way that OpenXR specifies in the function xrLocateSpace.
299  *
300  * Performs roughly outPose = spacePose * relativePose * baseSpacePose^-1
301  *
302  * OK if input and output are the same addresses.
303  *
304  * @relates xrt_pose
305  * @ingroup aux_math
306  */
307 void
308 math_pose_openxr_locate(const struct xrt_pose *space_pose,
309  const struct xrt_pose *relative_pose,
310  const struct xrt_pose *base_space_pose,
311  struct xrt_pose *result);
312 
313 /*
314  *
315  * Space relation functions
316  *
317  */
318 
319 /*!
320  * Reset a relation to zero velocity, located at origin, and all validity flags.
321  *
322  * @relates xrt_space_relation
323  * @ingroup aux_math
324  */
325 void
327 
328 /*!
329  * Apply a static pose on top of an existing relation.
330  *
331  * Updates all valid pose and derivative fields. Does not modify the validity
332  * mask. Treats both position and orientation of transform as valid.
333  *
334  * @relates xrt_space_relation
335  * @see xrt_pose
336  * @ingroup aux_math
337  */
338 void
339 math_relation_apply_offset(const struct xrt_pose *offset,
340  struct xrt_space_relation *in_out_relation);
341 
342 /*!
343  * Apply another step of space relation on top of an existing relation.
344  *
345  * Updates all valid pose and derivative fields, as well as the validity mask.
346  *
347  * @relates xrt_space_relation
348  * @ingroup aux_math
349  */
350 void
352  const struct xrt_space_relation *additional_relation,
353  struct xrt_space_relation *in_out_relation);
354 
355 /*!
356  * Combine the poses of the target and base space with the relative relation of
357  * those spaces. In a way that OpenXR specifies in the function xrLocateSpace.
358  *
359  * Performs roughly `out_relation->pose = space_pose * relative_relation->pose *
360  * base_space_pose^-1` for the poses, and appropriate rotation
361  *
362  * OK if input and output are the same addresses.
363  *
364  * @relates xrt_space_relation
365  * @see xrt_pose
366  * @ingroup aux_math
367  */
368 void
369 math_relation_openxr_locate(const struct xrt_pose *space_pose,
370  const struct xrt_space_relation *relative_relation,
371  const struct xrt_pose *base_space_pose,
372  struct xrt_space_relation *result);
373 
374 /*!
375  * Perform the computations from
376  * "Computing Half-Fields-Of-View from Simpler Display Models",
377  * to get half-FOVs from things we can retrieve from other APIs.
378  * The origin is in the lower-left corner of the display, so w_1 is the width to
379  * the left of CoP, and h_1 is the height below CoP.
380  *
381  * If vertfov_total is set to 0, it will be computed from h_total.
382  *
383  * Distances are in arbitrary but consistent units. Angles are in radians.
384  *
385  *
386  * In the diagram below, treating it like a FOV for horizontal,
387  * the top angle is horizfov_total, the length of the bottom
388  * is w_total, and the distance between the vertical line and the left corner is
389  * w_1. Vertical is similar - h_1 is above the center line.
390  * The triangle need not be symmetrical, despite how the diagram looks.
391  *
392  * ```
393  * horizfov_total
394  * *
395  * angle_left (neg) -> / | \ <- angle_right
396  * / | \
397  * / | \
398  * / | \
399  * -------------
400  * [ w_1 ]
401  * [ --- w --- ]
402  *
403  * ------- --- |\
404  * | \
405  * h_1 | \ angle_up
406  * h_total ___ |-------* vertfov_total
407  * | / angle_down (neg)
408  * | /
409  * | /
410  * ------- |/
411  * ```
412  *
413  * @return true if successful.
414  * @ingroup aux_math
415  */
416 bool
417 math_compute_fovs(double w_total,
418  double w_1,
419  double horizfov_total,
420  double h_total,
421  double h_1,
422  double vertfov_total,
423  struct xrt_fov *fov);
424 
425 #ifdef __cplusplus
426 }
427 #endif
void math_relation_openxr_locate(const struct xrt_pose *space_pose, const struct xrt_space_relation *relative_relation, const struct xrt_pose *base_space_pose, struct xrt_space_relation *result)
Combine the poses of the target and base space with the relative relation of those spaces...
Definition: m_base.cpp:540
A 3 element vector with single floats.
Definition: xrt_defines.h:131
A pose composed of a position and orientation.
Definition: xrt_defines.h:229
bool math_vec3_validate(const struct xrt_vec3 *vec3)
Check if this vec3 is valid for math operations.
Definition: m_base.cpp:61
void math_quat_finite_difference(const struct xrt_quat *quat0, const struct xrt_quat *quat1, float dt, struct xrt_vec3 *out_ang_vel)
Compute an angular velocity vector (exponential map format) by taking the finite difference of two qu...
void math_relation_accumulate_relation(const struct xrt_space_relation *additional_relation, struct xrt_space_relation *in_out_relation)
Apply another step of space relation on top of an existing relation.
Definition: m_base.cpp:496
void math_relation_apply_offset(const struct xrt_pose *offset, struct xrt_space_relation *in_out_relation)
Apply a static pose on top of an existing relation.
Definition: m_base.cpp:474
size_t math_hash_string(const char *str_c, size_t length)
Generate a hash value from the given string, trailing zero not included.
Definition: m_hash.cpp:15
void math_quat_from_plus_x_z(const struct xrt_vec3 *plus_x, const struct xrt_vec3 *plus_z, struct xrt_quat *result)
Create a rotation from two vectors plus x and z, by creating a rotation matrix by crossing z and x to...
Definition: m_base.cpp:113
void math_pose_transform(const struct xrt_pose *transform, const struct xrt_pose *pose, struct xrt_pose *outPose)
Apply a rigid-body transformation to a pose.
Definition: m_base.cpp:276
A tightly packed 3x3 matrix of floats.
Definition: xrt_defines.h:266
A quaternion with single floats.
Definition: xrt_defines.h:97
A relation with two spaces, includes velocity and acceleration.
Definition: xrt_defines.h:334
void math_quat_integrate_velocity(const struct xrt_quat *quat, const struct xrt_vec3 *ang_vel, float dt, struct xrt_quat *result)
Integrate an angular velocity vector (exponential map) and apply to a quaternion. ...
void math_vec3_accum(const struct xrt_vec3 *additional, struct xrt_vec3 *inAndOut)
Accumulate a vector by adding in-place.
Definition: m_base.cpp:69
Common defines and enums for XRT.
bool math_pose_validate(const struct xrt_pose *pose)
Check if this pose can be used in transformation operations.
Definition: m_base.cpp:226
void math_pose_invert(const struct xrt_pose *pose, struct xrt_pose *outPose)
Invert pose.
Definition: m_base.cpp:235
void math_pose_transform_point(const struct xrt_pose *transform, const struct xrt_vec3 *point, struct xrt_vec3 *out_point)
Apply a rigid-body transformation to a point.
Definition: m_base.cpp:289
Describes a projection matrix fov.
Definition: xrt_defines.h:240
void math_pose_openxr_locate(const struct xrt_pose *space_pose, const struct xrt_pose *relative_pose, const struct xrt_pose *base_space_pose, struct xrt_pose *result)
Combine the poses of the target and base space with the relative pose of those spaces.
Definition: m_base.cpp:301
void math_relation_reset(struct xrt_space_relation *out)
Reset a relation to zero velocity, located at origin, and all validity flags.
Definition: m_base.cpp:468
void math_quat_from_matrix_3x3(const struct xrt_matrix_3x3 *mat, struct xrt_quat *result)
Create a rotation from a 3x3 rotation matrix.
Definition: m_base.cpp:101
void math_vec3_cross(const struct xrt_vec3 *l, const struct xrt_vec3 *r, struct xrt_vec3 *result)
Cross product of a vector.
Definition: m_base.cpp:78
void math_quat_normalize(struct xrt_quat *inout)
Normalize a quaternion.
Definition: m_base.cpp:158
bool math_quat_validate(const struct xrt_quat *quat)
Check if this quat can be used in transformation operations.
Definition: m_base.cpp:136
void math_quat_from_angle_vector(float angle_rads, const struct xrt_vec3 *vector, struct xrt_quat *result)
Create a rotation from a angle in radians and a vector.
Definition: m_base.cpp:93
bool math_compute_fovs(double w_total, double w_1, double horizfov_total, double h_total, double h_1, double vertfov_total, struct xrt_fov *fov)
Perform the computations from "Computing Half-Fields-Of-View from Simpler Display Models"...
Definition: m_optics.c:125
void math_quat_rotate_vec3(const struct xrt_quat *left, const struct xrt_vec3 *right, struct xrt_vec3 *result)
Rotate a vector.
void math_quat_rotate(const struct xrt_quat *left, const struct xrt_quat *right, struct xrt_quat *result)
Rotate a quaternion (compose rotations).
Definition: m_base.cpp:165