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 rotation vector equal to half of a Rodrigues rotation vector and returns its corresponding unit quaternion.
458 * Useful for head tracking and pose-prediction.
459 *
460 * @relates xrt_quat
461 * @see xrt_vec3
462 * @ingroup aux_math
463 */
464void
465math_quat_exp(const struct xrt_vec3 *axis_angle, struct xrt_quat *out_quat);
466
467
468/*!
469 * Takes a unit quaternion and returns a rotation vector equal to half of its corresponding Rodrigues rotation vector.
470 * Useful for head tracking and pose-prediction.
471 *
472 * @relates xrt_quat
473 * @see xrt_vec3
474 * @ingroup aux_math
475 */
476void
477math_quat_ln(const struct xrt_quat *quat, struct xrt_vec3 *out_axis_angle);
478
479/*!
480 * Used to rotate a derivative like a angular velocity.
481 *
482 * @relates xrt_quat
483 * @see xrt_vec3
484 * @ingroup aux_math
485 */
486void
487math_quat_rotate_derivative(const struct xrt_quat *quat, const struct xrt_vec3 *deriv, struct xrt_vec3 *result);
488
489
490/*!
491 * Slerp (spherical linear interpolation) between two quaternions
492 *
493 * @relates xrt_quat
494 * @ingroup aux_math
495 */
496void
497math_quat_slerp(const struct xrt_quat *left, const struct xrt_quat *right, float t, struct xrt_quat *result);
498
499
500/*!
501 * Converts a 2D vector to a quaternion
502 *
503 * @relates xrt_quat
504 * @ingroup aux_math
505 */
506void
507math_quat_from_swing(const struct xrt_vec2 *swing, struct xrt_quat *result);
508
509
510/*!
511 * Converts a 2D vector and a float to a quaternion
512 *
513 * @relates xrt_quat
514 * @ingroup aux_math
515 */
516void
517math_quat_from_swing_twist(const struct xrt_vec2 *swing, const float twist, struct xrt_quat *result);
518
519/*!
520 * Converts a quaternion to XY-swing and Z-twist
521 *
522 * @relates xrt_quat
523 * @ingroup aux_math
524 */
525void
526math_quat_to_swing_twist(const struct xrt_quat *in, struct xrt_vec2 *out_swing, float *out_twist);
527
528/*!
529 * Decompose a quaternion to swing and twist component rotations around a target
530 * axis. The swing is always orthogonal to the target axis, and twist rotation is always
531 * around the axis.
532 *
533 * swing * twist gives back the original quat
534 * (e.g. math_quat_rotate(&swing, &twist, &orig_q))
535 *
536 * See https://arxiv.org/pdf/1506.05481.pdf
537 *
538 * @relates xrt_quat
539 * @ingroup aux_math
540 */
541void
542math_quat_decompose_swing_twist(const struct xrt_quat *in,
543 const struct xrt_vec3 *twist_axis,
544 struct xrt_quat *swing,
545 struct xrt_quat *twist);
546
547/*
548 *
549 * Matrix functions
550 *
551 */
552
553/*!
554 * Initialize a 3x3 matrix to the identity matrix
555 *
556 * @see xrt_matrix_3x3
557 * @ingroup aux_math
558 */
559void
561
562/*!
563 * Initialize a 3x3 matrix from a quaternion
564 *
565 * @see xrt_matrix_3x3
566 * @ingroup aux_math
567 */
568void
569math_matrix_3x3_from_quat(const struct xrt_quat *q, struct xrt_matrix_3x3 *result_out);
570
571/*!
572 * Initialize a double 3x3 matrix to the identity matrix
573 *
574 * @see xrt_matrix_3x3
575 * @ingroup aux_math
576 */
577void
579
580/*!
581 * Transform a vec3 by a 3x3 matrix
582 *
583 * @see xrt_matrix_3x3
584 * @ingroup aux_math
585 */
586void
588 const struct xrt_vec3 *right,
589 struct xrt_vec3 *result_out);
590
591/*!
592 * Transform a vec3 by a 4x4 matrix, extending the vector with w = 1.0
593 *
594 * @see xrt_matrix_4x4
595 * @ingroup aux_math
596 */
597void
599 const struct xrt_vec3 *right,
600 struct xrt_vec3 *result_out);
601
602/*!
603 * Transform a double vec3 by a 3x3 double matrix
604 *
605 * @see xrt_matrix_3x3
606 * @ingroup aux_math
607 */
608void
610 const struct xrt_vec3_f64 *right,
611 struct xrt_vec3_f64 *result_out);
612
613/*!
614 * Multiply Matrix3x3.
615 *
616 * @relates xrt_matrix_3x3
617 * @ingroup aux_math
618 */
619void
620math_matrix_3x3_multiply(const struct xrt_matrix_3x3 *left,
621 const struct xrt_matrix_3x3 *right,
622 struct xrt_matrix_3x3 *result_out);
623
624/*!
625 * Invert Matrix3x3
626 *
627 * @relates xrt_matrix_3x3
628 * @ingroup aux_math
629 */
630void
631math_matrix_3x3_inverse(const struct xrt_matrix_3x3 *in, struct xrt_matrix_3x3 *result);
632
633/*!
634 * Transpose Matrix3x3
635 *
636 * @relates xrt_matrix_3x3
637 * @ingroup aux_math
638 */
639void
640math_matrix_3x3_transpose(const struct xrt_matrix_3x3 *in, struct xrt_matrix_3x3 *result);
641
642/*!
643 * Create a rotation from two vectors plus x and z, by
644 * creating a rotation matrix by crossing z and x to
645 * get the y axis.
646 *
647 * Input vectors should be normalized.
648 *
649 * @relates xrt_matrix_3x3
650 * @ingroup aux_math
651 */
652void
653math_matrix_3x3_f64_from_plus_x_z(const struct xrt_vec3_f64 *plus_x,
654 const struct xrt_vec3_f64 *plus_z,
655 struct xrt_matrix_3x3_f64 *result);
656
657/*!
658 * Get the rotation matrix from an isomertry matrix (col-major).
659 *
660 * @relates xrt_matrix_4x4
661 * @ingroup aux_math
662 */
663void
664math_matrix_3x3_rotation_from_isometry(const struct xrt_matrix_4x4 *isometry, struct xrt_matrix_3x3 *result);
665
666/*!
667 * Initialize Matrix4x4 with identity.
668 *
669 * @relates xrt_matrix_4x4
670 * @ingroup aux_math
671 */
672void
673math_matrix_4x4_identity(struct xrt_matrix_4x4 *result);
674
675/*!
676 * Multiply Matrix4x4.
677 *
678 * @relates xrt_matrix_4x4
679 * @ingroup aux_math
680 */
681void
682math_matrix_4x4_multiply(const struct xrt_matrix_4x4 *left,
683 const struct xrt_matrix_4x4 *right,
684 struct xrt_matrix_4x4 *result);
685
686/*!
687 * Invert Matrix4x4.
688 *
689 * @relates xrt_matrix_4x4
690 * @ingroup aux_math
691 */
692void
693math_matrix_4x4_inverse(const struct xrt_matrix_4x4 *in, struct xrt_matrix_4x4 *result);
694
695/*!
696 * Invert a homogeneous isometry 4x4 (col-major) matrix in SE(3).
697 *
698 * @relates xrt_matrix_4x4
699 * @ingroup aux_math
700 */
701void
702math_matrix_4x4_isometry_inverse(const struct xrt_matrix_4x4 *in, struct xrt_matrix_4x4 *result);
703
704/*!
705 * Transpose Matrix4x4
706 *
707 * @relates xrt_matrix_4x4
708 * @ingroup aux_math
709 */
710void
711math_matrix_4x4_transpose(const struct xrt_matrix_4x4 *in, struct xrt_matrix_4x4 *result);
712
713/*!
714 * Compute view matrix from xrt_pose.
715 *
716 * @relates xrt_matrix_4x4
717 * @ingroup aux_math
718 */
719void
720math_matrix_4x4_view_from_pose(const struct xrt_pose *pose, struct xrt_matrix_4x4 *result);
721
722/*!
723 * Get an isometry matrix —in SE(3)— from a rotation matrix —SO(3)— and a
724 * translation vector. All col-major matrices.
725 *
726 * @relates xrt_matrix_4x4
727 * @ingroup aux_math
728 */
729void
730math_matrix_4x4_isometry_from_rt(const struct xrt_matrix_3x3 *rotation,
731 const struct xrt_vec3 *translation,
732 struct xrt_matrix_4x4 *result);
733
734/*!
735 * Get a col-major isometry matrix —in SE(3)— from a pose.
736 *
737 * @relates xrt_matrix_4x4
738 * @ingroup aux_math
739 */
740void
741math_matrix_4x4_isometry_from_pose(const struct xrt_pose *pose, struct xrt_matrix_4x4 *result);
742
743/*!
744 * Compute quad layer model matrix from xrt_pose and xrt_vec2 size.
745 *
746 * @relates xrt_matrix_4x4
747 * @ingroup aux_math
748 */
749void
750math_matrix_4x4_model(const struct xrt_pose *pose, const struct xrt_vec3 *size, struct xrt_matrix_4x4 *result);
751
752/*!
753 * Compute inverse view projection matrix,
754 * using only the starting 3x3 block of the view.
755 *
756 * @relates xrt_matrix_4x4
757 * @ingroup aux_math
758 */
759void
760math_matrix_4x4_inverse_view_projection(const struct xrt_matrix_4x4 *view,
761 const struct xrt_matrix_4x4 *projection,
762 struct xrt_matrix_4x4 *result);
763
764/*!
765 * Compute a projection matrix with settings for Vulkan, it will also have it's
766 * far plane at infinite and the NDC depth will be reversed.
767 *
768 * @relates xrt_matrix_4x4
769 * @ingroup aux_math
770 */
771void
772math_matrix_4x4_projection_vulkan_infinite_reverse(const struct xrt_fov *fov,
773 float near_plane,
774 struct xrt_matrix_4x4 *result);
775
776
777/*
778 *
779 * Pose functions.
780 *
781 */
782
783
784/*!
785 * Somewhat laboriously make an xrt_pose identity.
786 *
787 * @relates xrt_pose
788 * @ingroup aux_math
789 */
790void
791math_pose_identity(struct xrt_pose *pose);
792
793/*!
794 * Check if this pose can be used in transformation operations.
795 *
796 * @relates xrt_pose
797 * @ingroup aux_math
798 */
799bool
800math_pose_validate(const struct xrt_pose *pose);
801
802/*!
803 * Invert pose.
804 *
805 * OK if input and output are the same addresses.
806 *
807 * @relates xrt_pose
808 * @ingroup aux_math
809 */
810void
811math_pose_invert(const struct xrt_pose *pose, struct xrt_pose *outPose);
812
813/*!
814 * Converts a (col-major) isometry into a pose.
815 *
816 * @relates xrt_pose
817 * @ingroup aux_math
818 */
819void
820math_pose_from_isometry(const struct xrt_matrix_4x4 *transform, struct xrt_pose *result);
821
822/*!
823 * Interpolated pose between poses `a` and `b` by lerping position and slerping
824 * orientation by t.
825 *
826 * @relates xrt_pose
827 * @ingroup aux_math
828 */
829void
830math_pose_interpolate(const struct xrt_pose *a, const struct xrt_pose *b, float t, struct xrt_pose *outPose);
831
832/*!
833 * Apply a rigid-body transformation to a pose.
834 *
835 * OK if input and output are the same addresses.
836 *
837 * @relates xrt_pose
838 * @ingroup aux_math
839 */
840void
841math_pose_transform(const struct xrt_pose *transform, const struct xrt_pose *pose, struct xrt_pose *outPose);
842
843/*!
844 * Apply a rigid-body transformation to a point.
845 *
846 * The input point and output may be the same pointer.
847 *
848 * @relates xrt_pose
849 * @see xrt_vec3
850 * @ingroup aux_math
851 */
852void
853math_pose_transform_point(const struct xrt_pose *transform, const struct xrt_vec3 *point, struct xrt_vec3 *out_point);
854
855/*!
856 * Convert a pose from the OpenCV coordinate system to the OpenXR coordinate system and back. OpenCV camera space
857 * coordinates has +Y down and +Z away from the user.
858 *
859 * The input and output may be the same pointer.
860 *
861 * @relates xrt_pose
862 * @ingroup aux_math
863 */
864void
865math_pose_convert_from_opencv(const struct xrt_pose *in, struct xrt_pose *out);
866
867
868/*
869 *
870 * Inline functions.
871 *
872 */
873
874/*!
875 * Map a number from one range to another range.
876 * Exactly the same as Arduino's map().
877 */
878static inline double
879math_map_ranges(double value, double from_low, double from_high, double to_low, double to_high)
880{
881 return (value - from_low) * (to_high - to_low) / (from_high - from_low) + to_low;
882}
883
884static inline double
885math_lerp(double from, double to, double amount)
886{
887 return (from * (1.0 - amount)) + (to * (amount));
888}
889
890/*
891 *
892 * Optics functions.
893 *
894 */
895
896/*!
897 * Perform the computations from
898 * "Computing Half-Fields-Of-View from Simpler Display Models",
899 * to get half-FOVs from things we can retrieve from other APIs.
900 * The origin is in the lower-left corner of the display, so w_1 is the width to
901 * the left of CoP, and h_1 is the height below CoP.
902 *
903 * If vertfov_total is set to 0, it will be computed from h_total.
904 *
905 * Distances are in arbitrary but consistent units. Angles are in radians.
906 *
907 *
908 * In the diagram below, treating it like a FOV for horizontal,
909 * the top angle is horizfov_total, the length of the bottom
910 * is w_total, and the distance between the vertical line and the left corner is
911 * w_1. Vertical is similar - h_1 is above the center line.
912 * The triangle need not be symmetrical, despite how the diagram looks.
913 *
914 * ```
915 * horizfov_total
916 * *
917 * angle_left (neg) -> / | \ <- angle_right
918 * / | \
919 * / | \
920 * / | \
921 * -------------
922 * [ w_1 ]
923 * [ --- w --- ]
924 *
925 * ------- --- |\
926 * | \
927 * h_1 | \ angle_up
928 * h_total ___ |-------* vertfov_total
929 * | / angle_down (neg)
930 * | /
931 * | /
932 * ------- |/
933 * ```
934 *
935 * @return true if successful.
936 * @ingroup aux_math
937 */
938bool
939math_compute_fovs(double w_total,
940 double w_1,
941 double horizfov_total,
942 double h_total,
943 double h_1,
944 double vertfov_total,
945 struct xrt_fov *fov);
946
947/*!
948 * Compute the FOV to use when parallelizing canted views.
949 *
950 * Some applications do not support rendering for view orientations that are
951 * not parallel to each other.
952 * When using a headset with physically canted displays, such applications
953 * require parallelizing the views, i.e. forcing the orientations of the views
954 * to be parallel.
955 * When the application passes content rendered for parallel views to the
956 * compositor, the compositor typically reprojects this content such that it
957 * matches the physical canting of the displays, effectively rotating the view
958 * orientation.
959 *
960 * When rotating the view orientation, parts of the FOV are cut off on the side
961 * the view rotates away from and parts of previously unseen content is pulled
962 * in from the side the view rotates towards. Therefore, when parallezing
963 * views, the application should render with an adjusted FOV that covers the
964 * area that will be in the FOV of the view *after* the compositor reprojects
965 * it back to the physical canted orientation.
966 *
967 * @ingroup aux_math
968 */
969void
970math_compute_parallelized_fov(const struct xrt_fov *fov,
971 const struct xrt_quat *canted_view_orientation,
972 struct xrt_fov *out_parallelized_fov);
973
974#ifdef __cplusplus
975}
976#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:879
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.