a/math: Add projection matrix making function

This commit is contained in:
Jakob Bornecrantz 2023-10-08 16:35:16 +01:00
parent 11fba8d79f
commit 93272b684c
3 changed files with 95 additions and 0 deletions

View file

@ -28,6 +28,7 @@ add_library(
m_lowpass_integer.hpp
m_matrix_2x2.h
m_matrix_4x4_f64.h
m_matrix_projection.cpp
m_optics.c
m_permutation.c
m_permutation.h

View file

@ -655,6 +655,19 @@ math_matrix_4x4_inverse_view_projection(const struct xrt_matrix_4x4 *view,
const struct xrt_matrix_4x4 *projection,
struct xrt_matrix_4x4 *result);
/*!
* Compute a projection matrix with settings for Vulkan, it will also have it's
* far plane at infinite and the NDC depth will be reversed.
*
* @relates xrt_matrix_4x4
* @ingroup aux_math
*/
void
math_matrix_4x4_projection_vulkan_infinite_reverse(const struct xrt_fov *fov,
float near_plane,
struct xrt_matrix_4x4 *result);
/*
*
* Pose functions.

View file

@ -0,0 +1,81 @@
// Copyright 2019-2023, Collabora, Ltd.
// SPDX-License-Identifier: BSL-1.0
/*!
* @file
* @brief Matrix function for creating projection matrices.
* @author Jakob Bornecrantz <jakob@collabora.com>
* @ingroup aux_math
*/
#include "m_mathinclude.h"
#include "xrt/xrt_defines.h"
/*
*
* Helpers.
*
*/
template <typename Scalar, typename ResultType>
void
calc_vulkan_projection_infinite_reverse(const xrt_fov &fov, Scalar near_plane, ResultType &result)
{
const Scalar tan_left = static_cast<Scalar>(tan(fov.angle_left));
const Scalar tan_right = static_cast<Scalar>(tan(fov.angle_right));
const Scalar tan_down = static_cast<Scalar>(tan(fov.angle_down));
const Scalar tan_up = static_cast<Scalar>(tan(fov.angle_up));
// This is here for clarity.
const bool vulkan_projection_space_y = true;
const Scalar tan_width = tan_right - tan_left;
const Scalar tan_height = vulkan_projection_space_y // Projection space y direction:
? (tan_down - tan_up) // Vulkan Y down
: (tan_up - tan_down); // OpenGL Y up
const Scalar a11 = 2 / tan_width;
const Scalar a22 = 2 / tan_height;
const Scalar a31 = (tan_right + tan_left) / tan_width;
const Scalar a32 = (tan_up + tan_down) / tan_height;
/*
* Vulkan's Z clip space is [0 .. 1] (OpenGL [-1 .. 0 .. 1]).
* We are using reverse depth for better floating value.
* - Near is 1
* - Far is 0 (infinite)
*
* https://vincent-p.github.io/posts/vulkan_perspective_matrix/
*/
const Scalar a33 = 0; // vulkan = 0, opengl = -1
const Scalar a34 = -1;
const Scalar a43 = near_plane; // Reverse depth and half vs opengl, `-2 * near_plane`.
// clang-format off
result = ResultType({
a11, 0, 0, 0,
0, a22, 0, 0,
a31, a32, a33, a34,
0, 0, a43, 0,
});
// clang-format on
}
/*
*
* 'Exported' functions.
*
*/
extern "C" void
math_matrix_4x4_projection_vulkan_infinite_reverse(const struct xrt_fov *fov,
float near_plane,
struct xrt_matrix_4x4 *result)
{
calc_vulkan_projection_infinite_reverse<float, xrt_matrix_4x4>(*fov, near_plane, *result);
}