Monado OpenXR Runtime
Loading...
Searching...
No Matches
m_api.h
Go to the documentation of this file.
1// Copyright 2019-2021, 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 * @author Moshi Turner <moshiturner@protonmail.com>
8 * @author Nis Madsen <nima_zero_one@protonmail.com>
9 *
10 * @see xrt_vec3
11 * @see xrt_quat
12 * @see xrt_pose
13 * @see xrt_space_relation
14 * @ingroup aux_math
15 */
16
17#pragma once
18
19#include "xrt/xrt_defines.h"
20
21#include "math/m_mathinclude.h"
22
23#ifdef __cplusplus
24extern "C" {
25#endif
26
27
28/*!
29 * @defgroup aux_math Math
30 * @ingroup aux
31 *
32 * @brief C interface to some transform-related math functions.
33 */
34
35/*!
36 * @dir auxiliary/math
37 * @ingroup aux
38 *
39 * @brief C interface to some transform-related math functions.
40 */
41
42/*
43 *
44 * Defines.
45 *
46 */
47
48/*!
49 * Standard gravity acceleration constant.
50 *
51 * @ingroup aux_math
52 */
53#define MATH_GRAVITY_M_S2 (9.8066)
54
55/*!
56 * Minimum of A and B.
57 *
58 * @ingroup aux_math
59 */
60#ifndef MIN // Avoid clash with OpenCV def
61#define MIN(A, B) ((A) < (B) ? (A) : (B))
62#endif
63
64/*!
65 * Maximum of A and B.
66 *
67 * @ingroup aux_math
68 */
69#ifndef MAX // Avoid clash with OpenCV def
70#define MAX(A, B) ((A) > (B) ? (A) : (B))
71#endif
72
73/*!
74 * X clamped to the range [A, B].
75 *
76 * @ingroup aux_math
77 */
78#define CLAMP(X, A, B) (MIN(MAX((X), (A)), (B)))
79
80/*!
81 * Degrees to radians conversion.
82 *
83 * @ingroup aux_math
84 */
85// clang-format off
86// @todo: Remove the clang-format off/on when we move to a newer clang-format in CI.
87#define DEG_TO_RAD(DEG) ((DEG) * M_PI / 180.)
88// clang-format on
89
90/*!
91 * Radians to degrees conversion.
92 *
93 * @ingroup aux_math
94 */
95// clang-format off
96#define RAD_TO_DEG(RAD) ((RAD) * 180.0 / M_PI)
97// clang-format on
98
99
100/*
101 *
102 * Hash functions.
103 *
104 */
105
106/*!
107 * Generate a hash value from the given string, trailing zero not included.
108 *
109 * Hashing function used is not specified so no guarantee of staying the same
110 * between different versions of the software, or even when the same version
111 * is compiled on different platforms/libc++ as it might use std::hash.
112 *
113 * @ingroup aux_math
114 */
115size_t
116math_hash_string(const char *str_c, size_t length);
117
118
119/*
120 *
121 * Vector functions
122 *
123 */
124
125/*!
126 * Check if this vec3 is valid for math operations.
127 *
128 * @relates xrt_vec3
129 * @ingroup aux_math
130 */
131bool
132math_vec3_validate(const struct xrt_vec3 *vec3);
133
134/*!
135 * Accumulate a vector by adding in-place.
136 *
137 * Logically, *inAndOut += *additional
138 * OK if the two arguments are the same addresses.
139 *
140 * @relates xrt_vec3
141 * @ingroup aux_math
142 */
143void
144math_vec3_accum(const struct xrt_vec3 *additional, struct xrt_vec3 *inAndOut);
145
146/*!
147 * Subtract from a vector in-place.
148 *
149 * Logically, *inAndOut -= *subtrahend
150 * OK if the two arguments are the same addresses.
151 *
152 * @relates xrt_vec3
153 * @ingroup aux_math
154 */
155void
156math_vec3_subtract(const struct xrt_vec3 *subtrahend, struct xrt_vec3 *inAndOut);
157
158/*!
159 * Multiply a vector in-place.
160 *
161 * Logically, *inAndOut *= scalar
162 *
163 * @relates xrt_vec3
164 * @ingroup aux_math
165 */
166void
167math_vec3_scalar_mul(float scalar, struct xrt_vec3 *inAndOut);
168
169/*!
170 * Cross product of a vector.
171 *
172 * @relates xrt_vec3
173 * @ingroup aux_math
174 */
175void
176math_vec3_cross(const struct xrt_vec3 *l, const struct xrt_vec3 *r, struct xrt_vec3 *result);
177
178/*!
179 * Get translation vector from isometry matrix (col-major).
180 *
181 * @relates xrt_vec3
182 * @ingroup aux_math
183 */
184void
185math_vec3_translation_from_isometry(const struct xrt_matrix_4x4 *isometry, struct xrt_vec3 *result);
186
187/*!
188 * Normalize a vec3 in place.
189 *
190 * @relates xrt_vec3
191 * @ingroup aux_math
192 */
193void
194math_vec3_normalize(struct xrt_vec3 *in);
195
196/*!
197 * Convert a vec3 from the OpenCV coordinate system to the OpenXR coordinate system and back. OpenCV camera space
198 * coordinates has +Y down and +Z away from the user.
199 *
200 * The input and output may be the same pointer.
201 *
202 * @relates xrt_vec3
203 * @ingroup aux_math
204 */
205void
206math_vec3_convert_from_opencv(const struct xrt_vec3 *in, struct xrt_vec3 *out);
207
208
209/*
210 *
211 * 64 bit vector functions.
212 *
213 */
214
215/*!
216 * Cross product of a vec3_f64.
217 *
218 * @relates xrt_vec3_f64
219 * @ingroup aux_math
220 */
221void
222math_vec3_f64_cross(const struct xrt_vec3_f64 *l, const struct xrt_vec3_f64 *r, struct xrt_vec3_f64 *result);
223
224/*!
225 * Normalize a vec3_f64 in place.
226 *
227 * @relates xrt_vec3_f64
228 * @ingroup aux_math
229 */
230void
231math_vec3_f64_normalize(struct xrt_vec3_f64 *in);
232
233/*!
234 * Convert a vec3_f64 from the OpenCV coordinate system to the OpenXR coordinate system. OpenCV camera space coordinates
235 * has +Y down and +Z away from the user.
236 *
237 * The input and output may be the same pointer.
238 *
239 * @relates xrt_vec3
240 * @ingroup aux_math
241 */
242void
243math_vec3_f64_convert_opencv(const struct xrt_vec3_f64 *in, struct xrt_vec3_f64 *out);
244
245
246/*
247 *
248 * Quat functions.
249 *
250 */
251
252/*!
253 * Create a rotation from an angle in radians and a unit vector.
254 *
255 * @relates xrt_quat
256 * @see xrt_vec3
257 * @ingroup aux_math
258 */
259void
260math_quat_from_angle_vector(float angle_rads, const struct xrt_vec3 *vector, struct xrt_quat *result);
261
262/*!
263 * Create a rotation from euler angles to a quaternion
264 * @relates xrt_quat
265 * @ingroup aux_math
266 */
267void
268math_quat_from_euler_angles(const struct xrt_vec3 *angles, struct xrt_quat *result);
269
270/*!
271 * Create a rotation from a quaternion to euler angles
272 * @relates xrt_quat
273 * @ingroup aux_math
274 */
275void
276math_quat_to_euler_angles(const struct xrt_quat *quat, struct xrt_vec3 *euler_angles);
277
278/*!
279 * Create a rotation from a 3x3 rotation (row major) matrix.
280 *
281 * @relates xrt_quat
282 * @see xrt_matrix_3x3
283 * @ingroup aux_math
284 */
285void
286math_quat_from_matrix_3x3(const struct xrt_matrix_3x3 *mat, struct xrt_quat *result);
287
288/*!
289 * Create a rotation from two vectors plus x and z, by creating a rotation
290 * matrix by crossing z and x to get the y axis.
291 *
292 * Input vectors should be normalized.
293 *
294 * @relates xrt_quat
295 * @see xrt_vec3
296 * @ingroup aux_math
297 */
298void
299math_quat_from_plus_x_z(const struct xrt_vec3 *plus_x, const struct xrt_vec3 *plus_z, struct xrt_quat *result);
300
301/*!
302 * Create a rotation from two vectors vec_a and vec_b that would
303 * rotate vec_a into vec_b
304 *
305 * @relates xrt_quat
306 * @see xrt_vec3
307 * @ingroup aux_math
308 */
309void
310math_quat_from_vec_a_to_vec_b(const struct xrt_vec3 *vec_a, const struct xrt_vec3 *vec_b, struct xrt_quat *result);
311
312/*!
313 * Check if this quat can be used in transformation operations.
314 *
315 * @relates xrt_quat
316 * @ingroup aux_math
317 */
318bool
319math_quat_validate(const struct xrt_quat *quat);
320
321/*!
322 * Check if this quat is (approximately) identity.
323 *
324 * @relates xrt_quat
325 * @ingroup aux_math
326 */
327bool
328math_quat_is_identity(const struct xrt_quat *quat, float epsilon);
329
330/*!
331 * Check if this quat is within 1% of unit length.
332 *
333 * @relates xrt_quat
334 * @ingroup aux_math
335 */
336bool
337math_quat_validate_within_1_percent(const struct xrt_quat *quat);
338
339/*!
340 * Invert a quaternion.
341 *
342 * @relates xrt_quat
343 * @ingroup aux_math
344 */
345void
346math_quat_invert(const struct xrt_quat *quat, struct xrt_quat *out_quat);
347
348/*!
349 * The euclidean norm or length of a quaternion. Same as if it were a vec4.
350 *
351 * @relates xrt_quat
352 * @ingroup aux_math
353 */
354float
355math_quat_len(const struct xrt_quat *quat);
356
357/*!
358 * The dot product of 2 quaternions. It has a analogous interpretation
359 * as for vec3. For unit quaternions, it provides cos(theta) of the
360 * angle between the 2 quaternion rotations.
361 *
362 * @relates xrt_quat
363 * @ingroup aux_math
364 */
365static inline float
366math_quat_dot(const struct xrt_quat *l, const struct xrt_quat *r)
367{
368 return l->x * r->x + l->y * r->y + l->z * r->z + l->w * r->w;
369}
370
371/*!
372 * Normalize a quaternion.
373 *
374 * @relates xrt_quat
375 * @ingroup aux_math
376 */
377void
378math_quat_normalize(struct xrt_quat *inout);
379
380/*!
381 * Normalizes a quaternion if it has accumulated float precision errors.
382 * Returns true if the quaternion was already normalized or was normalized after
383 * being found within a small float precision tolerance.
384 * Returns false if the quaternion was not at all normalized.
385 *
386 * @relates xrt_quat
387 * @ingroup aux_math
388 */
389bool
390math_quat_ensure_normalized(struct xrt_quat *inout);
391
392/*!
393 * Rotate a vector.
394 *
395 * @relates xrt_quat
396 * @see xrt_vec3
397 * @ingroup aux_math
398 */
399void
400math_quat_rotate_vec3(const struct xrt_quat *left, const struct xrt_vec3 *right, struct xrt_vec3 *result);
401
402/*!
403 * Rotate a quaternion (compose rotations).
404 *
405 * @relates xrt_quat
406 * @ingroup aux_math
407 */
408void
409math_quat_rotate(const struct xrt_quat *left, const struct xrt_quat *right, struct xrt_quat *result);
410
411/*!
412 * Inverse of @ref math_quat_rotate. Removes @p left rotation from @p right.
413 *
414 * @relates xrt_quat
415 * @ingroup aux_math
416 */
417void
418math_quat_unrotate(const struct xrt_quat *left, const struct xrt_quat *right, struct xrt_quat *result);
419
420/*!
421 * Integrate a local angular velocity vector (exponential map) and apply to a
422 * quaternion.
423 *
424 * ang_vel and dt should share the same units of time, and the ang_vel
425 * vector should be in radians per unit of time.
426 *
427 * @relates xrt_quat
428 * @see xrt_vec3
429 * @ingroup aux_math
430 */
431void
432math_quat_integrate_velocity(const struct xrt_quat *quat,
433 const struct xrt_vec3 *ang_vel,
434 float dt,
435 struct xrt_quat *result);
436
437/*!
438 * Compute a global angular velocity vector (exponential map format) by taking
439 * the finite difference of two quaternions.
440 *
441 * quat1 is the orientation dt time after the orientation was quat0
442 *
443 * out_ang_vel and dt share the same units of time, and out_ang_vel is be in
444 * radians per unit of time.
445 *
446 * @relates xrt_quat
447 * @see xrt_vec3
448 * @ingroup aux_math
449 */
450void
451math_quat_finite_difference(const struct xrt_quat *quat0,
452 const struct xrt_quat *quat1,
453 float dt,
454 struct xrt_vec3 *out_ang_vel);
455
456/*!
457 * Takes a Rodrigues rotation vector and returns its corresponding unit quaternion.
458 *
459 * Useful for head tracking and pose-prediction.
460 *
461 * @relates xrt_quat
462 * @see xrt_vec3
463 * @ingroup aux_math
464 */
465void
466math_quat_exp_so3(const struct xrt_vec3 *axis_angle, struct xrt_quat *out_quat);
467
468
469/*!
470 * Takes a unit quaternion and returns its corresponding Rodrigues rotation vector.
471 *
472 * Useful for head tracking and pose-prediction.
473 *
474 * @relates xrt_quat
475 * @see xrt_vec3
476 * @ingroup aux_math
477 */
478void
479math_quat_ln_so3(const struct xrt_quat *quat, struct xrt_vec3 *out_axis_angle);
480
481/*!
482 * Used to rotate a derivative like a angular velocity.
483 *
484 * @relates xrt_quat
485 * @see xrt_vec3
486 * @ingroup aux_math
487 */
488void
489math_quat_rotate_derivative(const struct xrt_quat *quat, const struct xrt_vec3 *deriv, struct xrt_vec3 *result);
490
491
492/*!
493 * Slerp (spherical linear interpolation) between two quaternions
494 *
495 * @relates xrt_quat
496 * @ingroup aux_math
497 */
498void
499math_quat_slerp(const struct xrt_quat *left, const struct xrt_quat *right, float t, struct xrt_quat *result);
500
501
502/*!
503 * Converts a 2D vector to a quaternion
504 *
505 * @relates xrt_quat
506 * @ingroup aux_math
507 */
508void
509math_quat_from_swing(const struct xrt_vec2 *swing, struct xrt_quat *result);
510
511
512/*!
513 * Converts a 2D vector and a float to a quaternion
514 *
515 * @relates xrt_quat
516 * @ingroup aux_math
517 */
518void
519math_quat_from_swing_twist(const struct xrt_vec2 *swing, const float twist, struct xrt_quat *result);
520
521/*!
522 * Converts a quaternion to XY-swing and Z-twist
523 *
524 * @relates xrt_quat
525 * @ingroup aux_math
526 */
527void
528math_quat_to_swing_twist(const struct xrt_quat *in, struct xrt_vec2 *out_swing, float *out_twist);
529
530/*!
531 * Decompose a quaternion to swing and twist component rotations around a target
532 * axis. The swing is always orthogonal to the target axis, and twist rotation is always
533 * around the axis.
534 *
535 * swing * twist gives back the original quat
536 * (e.g. math_quat_rotate(&swing, &twist, &orig_q))
537 *
538 * See https://arxiv.org/pdf/1506.05481.pdf
539 *
540 * @relates xrt_quat
541 * @ingroup aux_math
542 */
543void
544math_quat_decompose_swing_twist(const struct xrt_quat *in,
545 const struct xrt_vec3 *twist_axis,
546 struct xrt_quat *swing,
547 struct xrt_quat *twist);
548
549/*
550 *
551 * Matrix functions
552 *
553 */
554
555/*!
556 * Initialize a 3x3 matrix to the identity matrix
557 *
558 * @see xrt_matrix_3x3
559 * @ingroup aux_math
560 */
561void
563
564/*!
565 * Initialize a 3x3 matrix from a quaternion
566 *
567 * @see xrt_matrix_3x3
568 * @ingroup aux_math
569 */
570void
571math_matrix_3x3_from_quat(const struct xrt_quat *q, struct xrt_matrix_3x3 *result_out);
572
573/*!
574 * Initialize a double 3x3 matrix to the identity matrix
575 *
576 * @see xrt_matrix_3x3
577 * @ingroup aux_math
578 */
579void
581
582/*!
583 * Transform a vec3 by a 3x3 matrix
584 *
585 * @see xrt_matrix_3x3
586 * @ingroup aux_math
587 */
588void
590 const struct xrt_vec3 *right,
591 struct xrt_vec3 *result_out);
592
593/*!
594 * Transform a vec3 by a 4x4 matrix, extending the vector with w = 1.0
595 *
596 * @see xrt_matrix_4x4
597 * @ingroup aux_math
598 */
599void
601 const struct xrt_vec3 *right,
602 struct xrt_vec3 *result_out);
603
604/*!
605 * Transform a double vec3 by a 3x3 double matrix
606 *
607 * @see xrt_matrix_3x3
608 * @ingroup aux_math
609 */
610void
612 const struct xrt_vec3_f64 *right,
613 struct xrt_vec3_f64 *result_out);
614
615/*!
616 * Multiply Matrix3x3.
617 *
618 * @relates xrt_matrix_3x3
619 * @ingroup aux_math
620 */
621void
622math_matrix_3x3_multiply(const struct xrt_matrix_3x3 *left,
623 const struct xrt_matrix_3x3 *right,
624 struct xrt_matrix_3x3 *result_out);
625
626/*!
627 * Invert Matrix3x3
628 *
629 * @relates xrt_matrix_3x3
630 * @ingroup aux_math
631 */
632void
633math_matrix_3x3_inverse(const struct xrt_matrix_3x3 *in, struct xrt_matrix_3x3 *result);
634
635/*!
636 * Transpose Matrix3x3
637 *
638 * @relates xrt_matrix_3x3
639 * @ingroup aux_math
640 */
641void
642math_matrix_3x3_transpose(const struct xrt_matrix_3x3 *in, struct xrt_matrix_3x3 *result);
643
644/*!
645 * Create a rotation from two vectors plus x and z, by
646 * creating a rotation matrix by crossing z and x to
647 * get the y axis.
648 *
649 * Input vectors should be normalized.
650 *
651 * @relates xrt_matrix_3x3
652 * @ingroup aux_math
653 */
654void
655math_matrix_3x3_f64_from_plus_x_z(const struct xrt_vec3_f64 *plus_x,
656 const struct xrt_vec3_f64 *plus_z,
657 struct xrt_matrix_3x3_f64 *result);
658
659/*!
660 * Get the rotation matrix from an isomertry matrix (col-major).
661 *
662 * @relates xrt_matrix_4x4
663 * @ingroup aux_math
664 */
665void
666math_matrix_3x3_rotation_from_isometry(const struct xrt_matrix_4x4 *isometry, struct xrt_matrix_3x3 *result);
667
668/*!
669 * Initialize Matrix4x4 with identity.
670 *
671 * @relates xrt_matrix_4x4
672 * @ingroup aux_math
673 */
674void
675math_matrix_4x4_identity(struct xrt_matrix_4x4 *result);
676
677/*!
678 * Multiply Matrix4x4.
679 *
680 * @relates xrt_matrix_4x4
681 * @ingroup aux_math
682 */
683void
684math_matrix_4x4_multiply(const struct xrt_matrix_4x4 *left,
685 const struct xrt_matrix_4x4 *right,
686 struct xrt_matrix_4x4 *result);
687
688/*!
689 * Invert Matrix4x4.
690 *
691 * @relates xrt_matrix_4x4
692 * @ingroup aux_math
693 */
694void
695math_matrix_4x4_inverse(const struct xrt_matrix_4x4 *in, struct xrt_matrix_4x4 *result);
696
697/*!
698 * Invert a homogeneous isometry 4x4 (col-major) matrix in SE(3).
699 *
700 * @relates xrt_matrix_4x4
701 * @ingroup aux_math
702 */
703void
704math_matrix_4x4_isometry_inverse(const struct xrt_matrix_4x4 *in, struct xrt_matrix_4x4 *result);
705
706/*!
707 * Transpose Matrix4x4
708 *
709 * @relates xrt_matrix_4x4
710 * @ingroup aux_math
711 */
712void
713math_matrix_4x4_transpose(const struct xrt_matrix_4x4 *in, struct xrt_matrix_4x4 *result);
714
715/*!
716 * Compute view matrix from xrt_pose.
717 *
718 * @relates xrt_matrix_4x4
719 * @ingroup aux_math
720 */
721void
722math_matrix_4x4_view_from_pose(const struct xrt_pose *pose, struct xrt_matrix_4x4 *result);
723
724/*!
725 * Get an isometry matrix —in SE(3)— from a rotation matrix —SO(3)— and a
726 * translation vector. All col-major matrices.
727 *
728 * @relates xrt_matrix_4x4
729 * @ingroup aux_math
730 */
731void
732math_matrix_4x4_isometry_from_rt(const struct xrt_matrix_3x3 *rotation,
733 const struct xrt_vec3 *translation,
734 struct xrt_matrix_4x4 *result);
735
736/*!
737 * Get a col-major isometry matrix —in SE(3)— from a pose.
738 *
739 * @relates xrt_matrix_4x4
740 * @ingroup aux_math
741 */
742void
743math_matrix_4x4_isometry_from_pose(const struct xrt_pose *pose, struct xrt_matrix_4x4 *result);
744
745/*!
746 * Compute quad layer model matrix from xrt_pose and xrt_vec2 size.
747 *
748 * @relates xrt_matrix_4x4
749 * @ingroup aux_math
750 */
751void
752math_matrix_4x4_model(const struct xrt_pose *pose, const struct xrt_vec3 *size, struct xrt_matrix_4x4 *result);
753
754/*!
755 * Compute inverse view projection matrix,
756 * using only the starting 3x3 block of the view.
757 *
758 * @relates xrt_matrix_4x4
759 * @ingroup aux_math
760 */
761void
762math_matrix_4x4_inverse_view_projection(const struct xrt_matrix_4x4 *view,
763 const struct xrt_matrix_4x4 *projection,
764 struct xrt_matrix_4x4 *result);
765
766/*!
767 * Compute a projection matrix with settings for Vulkan, it will also have it's
768 * far plane at infinite and the NDC depth will be reversed.
769 *
770 * @relates xrt_matrix_4x4
771 * @ingroup aux_math
772 */
773void
774math_matrix_4x4_projection_vulkan_infinite_reverse(const struct xrt_fov *fov,
775 float near_plane,
776 struct xrt_matrix_4x4 *result);
777
778
779/*
780 *
781 * Pose functions.
782 *
783 */
784
785
786/*!
787 * Somewhat laboriously make an xrt_pose identity.
788 *
789 * @relates xrt_pose
790 * @ingroup aux_math
791 */
792void
793math_pose_identity(struct xrt_pose *pose);
794
795/*!
796 * Check if this pose can be used in transformation operations.
797 *
798 * @relates xrt_pose
799 * @ingroup aux_math
800 */
801bool
802math_pose_validate(const struct xrt_pose *pose);
803
804/*!
805 * Invert pose.
806 *
807 * OK if input and output are the same addresses.
808 *
809 * @relates xrt_pose
810 * @ingroup aux_math
811 */
812void
813math_pose_invert(const struct xrt_pose *pose, struct xrt_pose *outPose);
814
815/*!
816 * Converts a (col-major) isometry into a pose.
817 *
818 * @relates xrt_pose
819 * @ingroup aux_math
820 */
821void
822math_pose_from_isometry(const struct xrt_matrix_4x4 *transform, struct xrt_pose *result);
823
824/*!
825 * Interpolated pose between poses `a` and `b` by lerping position and slerping
826 * orientation by t.
827 *
828 * @relates xrt_pose
829 * @ingroup aux_math
830 */
831void
832math_pose_interpolate(const struct xrt_pose *a, const struct xrt_pose *b, float t, struct xrt_pose *outPose);
833
834/*!
835 * Apply a rigid-body transformation to a pose.
836 *
837 * OK if input and output are the same addresses.
838 *
839 * @relates xrt_pose
840 * @ingroup aux_math
841 */
842void
843math_pose_transform(const struct xrt_pose *transform, const struct xrt_pose *pose, struct xrt_pose *outPose);
844
845/*!
846 * Apply a rigid-body transformation to a point.
847 *
848 * The input point and output may be the same pointer.
849 *
850 * @relates xrt_pose
851 * @see xrt_vec3
852 * @ingroup aux_math
853 */
854void
855math_pose_transform_point(const struct xrt_pose *transform, const struct xrt_vec3 *point, struct xrt_vec3 *out_point);
856
857/*!
858 * Convert a pose from the OpenCV coordinate system to the OpenXR coordinate system and back. OpenCV camera space
859 * coordinates has +Y down and +Z away from the user.
860 *
861 * The input and output may be the same pointer.
862 *
863 * @relates xrt_pose
864 * @ingroup aux_math
865 */
866void
867math_pose_convert_from_opencv(const struct xrt_pose *in, struct xrt_pose *out);
868
869
870/*
871 *
872 * Inline functions.
873 *
874 */
875
876/*!
877 * Map a number from one range to another range.
878 * Exactly the same as Arduino's map().
879 */
880static inline double
881math_map_ranges(double value, double from_low, double from_high, double to_low, double to_high)
882{
883 return (value - from_low) * (to_high - to_low) / (from_high - from_low) + to_low;
884}
885
886static inline double
887math_lerp(double from, double to, double amount)
888{
889 return (from * (1.0 - amount)) + (to * (amount));
890}
891
892/*
893 *
894 * Optics functions.
895 *
896 */
897
898/*!
899 * Perform the computations from
900 * "Computing Half-Fields-Of-View from Simpler Display Models",
901 * to get half-FOVs from things we can retrieve from other APIs.
902 * The origin is in the lower-left corner of the display, so w_1 is the width to
903 * the left of CoP, and h_1 is the height below CoP.
904 *
905 * If vertfov_total is set to 0, it will be computed from h_total.
906 *
907 * Distances are in arbitrary but consistent units. Angles are in radians.
908 *
909 *
910 * In the diagram below, treating it like a FOV for horizontal,
911 * the top angle is horizfov_total, the length of the bottom
912 * is w_total, and the distance between the vertical line and the left corner is
913 * w_1. Vertical is similar - h_1 is above the center line.
914 * The triangle need not be symmetrical, despite how the diagram looks.
915 *
916 * ```
917 * horizfov_total
918 * *
919 * angle_left (neg) -> / | \ <- angle_right
920 * / | \
921 * / | \
922 * / | \
923 * -------------
924 * [ w_1 ]
925 * [ --- w --- ]
926 *
927 * ------- --- |\
928 * | \
929 * h_1 | \ angle_up
930 * h_total ___ |-------* vertfov_total
931 * | / angle_down (neg)
932 * | /
933 * | /
934 * ------- |/
935 * ```
936 *
937 * @return true if successful.
938 * @ingroup aux_math
939 */
940bool
941math_compute_fovs(double w_total,
942 double w_1,
943 double horizfov_total,
944 double h_total,
945 double h_1,
946 double vertfov_total,
947 struct xrt_fov *fov);
948
949/*!
950 * Compute the FOV to use when parallelizing canted views.
951 *
952 * Some applications do not support rendering for view orientations that are
953 * not parallel to each other.
954 * When using a headset with physically canted displays, such applications
955 * require parallelizing the views, i.e. forcing the orientations of the views
956 * to be parallel.
957 * When the application passes content rendered for parallel views to the
958 * compositor, the compositor typically reprojects this content such that it
959 * matches the physical canting of the displays, effectively rotating the view
960 * orientation.
961 *
962 * When rotating the view orientation, parts of the FOV are cut off on the side
963 * the view rotates away from and parts of previously unseen content is pulled
964 * in from the side the view rotates towards. Therefore, when parallezing
965 * views, the application should render with an adjusted FOV that covers the
966 * area that will be in the FOV of the view *after* the compositor reprojects
967 * it back to the physical canted orientation.
968 *
969 * @ingroup aux_math
970 */
971void
972math_compute_parallelized_fov(const struct xrt_fov *fov,
973 const struct xrt_quat *canted_view_orientation,
974 struct xrt_fov *out_parallelized_fov);
975
976#ifdef __cplusplus
977}
978#endif
void math_matrix_3x3_f64_identity(struct xrt_matrix_3x3_f64 *mat)
Initialize a double 3x3 matrix to the identity matrix.
Definition m_base.cpp:663
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:119
void math_matrix_3x3_identity(struct xrt_matrix_3x3 *mat)
Initialize a 3x3 matrix to the identity matrix.
Definition m_base.cpp:637
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_matrix_3x3_f64_transform_vec3_f64(const struct xrt_matrix_3x3_f64 *left, const struct xrt_vec3_f64 *right, struct xrt_vec3_f64 *result_out)
Transform a double vec3 by a 3x3 double matrix.
Definition m_base.cpp:669
void math_matrix_4x4_transform_vec3(const struct xrt_matrix_4x4 *left, const struct xrt_vec3 *right, struct xrt_vec3 *result_out)
Transform a vec3 by a 4x4 matrix, extending the vector with w = 1.0.
Definition m_base.cpp:721
static float math_quat_dot(const struct xrt_quat *l, const struct xrt_quat *r)
The dot product of 2 quaternions.
Definition m_api.h:366
void math_matrix_3x3_transform_vec3(const struct xrt_matrix_3x3 *left, const struct xrt_vec3 *right, struct xrt_vec3 *result_out)
Transform a vec3 by a 3x3 matrix.
Definition m_base.cpp:708
void math_compute_parallelized_fov(const struct xrt_fov *fov, const struct xrt_quat *canted_view_orientation, struct xrt_fov *out_parallelized_fov)
Compute the FOV to use when parallelizing canted views.
Definition m_optics.c:165
void math_matrix_3x3_from_quat(const struct xrt_quat *q, struct xrt_matrix_3x3 *result_out)
Initialize a 3x3 matrix from a quaternion.
Definition m_base.cpp:643
static double math_map_ranges(double value, double from_low, double from_high, double to_low, double to_high)
Map a number from one range to another range.
Definition m_api.h:881
Wrapper header for <math.h> to ensure pi-related math constants are defined.
Describes a projection matrix fov.
Definition xrt_defines.h:533
A tightly packed 3x3 matrix of doubles.
Definition xrt_defines.h:590
A tightly packed 3x3 matrix of floats.
Definition xrt_defines.h:580
A tightly packed 4x4 matrix of floats.
Definition xrt_defines.h:607
A pose composed of a position and orientation.
Definition xrt_defines.h:513
A quaternion with single floats.
Definition xrt_defines.h:246
A 2 element vector with single floats.
Definition xrt_defines.h:279
A 3 element vector with single doubles.
Definition xrt_defines.h:322
A 3 element vector with single floats.
Definition xrt_defines.h:310
Common defines and enums for XRT.