The open source OpenXR runtime

a/math: Add projection matrix making function

+95
+1
src/xrt/auxiliary/math/CMakeLists.txt
··· 28 28 m_lowpass_integer.hpp 29 29 m_matrix_2x2.h 30 30 m_matrix_4x4_f64.h 31 + m_matrix_projection.cpp 31 32 m_optics.c 32 33 m_permutation.c 33 34 m_permutation.h
+13
src/xrt/auxiliary/math/m_api.h
··· 655 655 const struct xrt_matrix_4x4 *projection, 656 656 struct xrt_matrix_4x4 *result); 657 657 658 + /*! 659 + * Compute a projection matrix with settings for Vulkan, it will also have it's 660 + * far plane at infinite and the NDC depth will be reversed. 661 + * 662 + * @relates xrt_matrix_4x4 663 + * @ingroup aux_math 664 + */ 665 + void 666 + math_matrix_4x4_projection_vulkan_infinite_reverse(const struct xrt_fov *fov, 667 + float near_plane, 668 + struct xrt_matrix_4x4 *result); 669 + 670 + 658 671 /* 659 672 * 660 673 * Pose functions.
+81
src/xrt/auxiliary/math/m_matrix_projection.cpp
··· 1 + // Copyright 2019-2023, Collabora, Ltd. 2 + // SPDX-License-Identifier: BSL-1.0 3 + /*! 4 + * @file 5 + * @brief Matrix function for creating projection matrices. 6 + * @author Jakob Bornecrantz <jakob@collabora.com> 7 + * @ingroup aux_math 8 + */ 9 + 10 + #include "m_mathinclude.h" 11 + #include "xrt/xrt_defines.h" 12 + 13 + 14 + /* 15 + * 16 + * Helpers. 17 + * 18 + */ 19 + 20 + template <typename Scalar, typename ResultType> 21 + void 22 + calc_vulkan_projection_infinite_reverse(const xrt_fov &fov, Scalar near_plane, ResultType &result) 23 + { 24 + const Scalar tan_left = static_cast<Scalar>(tan(fov.angle_left)); 25 + const Scalar tan_right = static_cast<Scalar>(tan(fov.angle_right)); 26 + 27 + const Scalar tan_down = static_cast<Scalar>(tan(fov.angle_down)); 28 + const Scalar tan_up = static_cast<Scalar>(tan(fov.angle_up)); 29 + 30 + // This is here for clarity. 31 + const bool vulkan_projection_space_y = true; 32 + 33 + const Scalar tan_width = tan_right - tan_left; 34 + const Scalar tan_height = vulkan_projection_space_y // Projection space y direction: 35 + ? (tan_down - tan_up) // Vulkan Y down 36 + : (tan_up - tan_down); // OpenGL Y up 37 + 38 + const Scalar a11 = 2 / tan_width; 39 + const Scalar a22 = 2 / tan_height; 40 + 41 + const Scalar a31 = (tan_right + tan_left) / tan_width; 42 + const Scalar a32 = (tan_up + tan_down) / tan_height; 43 + 44 + 45 + /* 46 + * Vulkan's Z clip space is [0 .. 1] (OpenGL [-1 .. 0 .. 1]). 47 + * We are using reverse depth for better floating value. 48 + * - Near is 1 49 + * - Far is 0 (infinite) 50 + * 51 + * https://vincent-p.github.io/posts/vulkan_perspective_matrix/ 52 + */ 53 + 54 + const Scalar a33 = 0; // vulkan = 0, opengl = -1 55 + const Scalar a34 = -1; 56 + const Scalar a43 = near_plane; // Reverse depth and half vs opengl, `-2 * near_plane`. 57 + 58 + // clang-format off 59 + result = ResultType({ 60 + a11, 0, 0, 0, 61 + 0, a22, 0, 0, 62 + a31, a32, a33, a34, 63 + 0, 0, a43, 0, 64 + }); 65 + // clang-format on 66 + } 67 + 68 + 69 + /* 70 + * 71 + * 'Exported' functions. 72 + * 73 + */ 74 + 75 + extern "C" void 76 + math_matrix_4x4_projection_vulkan_infinite_reverse(const struct xrt_fov *fov, 77 + float near_plane, 78 + struct xrt_matrix_4x4 *result) 79 + { 80 + calc_vulkan_projection_infinite_reverse<float, xrt_matrix_4x4>(*fov, near_plane, *result); 81 + }