From 2eccb4023f1fe4fd0525b2e7d53356b2a9dc1f47 Mon Sep 17 00:00:00 2001 From: Orange Date: Thu, 23 Apr 2026 18:33:00 +0300 Subject: [PATCH] fix --- source/engines/unreal_engine/formulas.cpp | 31 ++++++++++++++++++----- 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/source/engines/unreal_engine/formulas.cpp b/source/engines/unreal_engine/formulas.cpp index 1890a13..7e0b24c 100644 --- a/source/engines/unreal_engine/formulas.cpp +++ b/source/engines/unreal_engine/formulas.cpp @@ -2,7 +2,6 @@ // Created by Vlad on 3/22/2025. // #include "omath/engines/unreal_engine/formulas.hpp" - namespace omath::unreal_engine { Vector3 forward_vector(const ViewAngles& angles) noexcept @@ -25,7 +24,7 @@ namespace omath::unreal_engine } Mat4X4 calc_view_matrix(const ViewAngles& angles, const Vector3& cam_origin) noexcept { - return mat_camera_view(forward_vector(angles), -right_vector(angles), + return mat_camera_view(forward_vector(angles), right_vector(angles), up_vector(angles), cam_origin); } Mat4X4 rotation_matrix(const ViewAngles& angles) noexcept @@ -34,13 +33,33 @@ namespace omath::unreal_engine * mat_rotation_axis_z(angles.yaw) * mat_rotation_axis_y(-angles.pitch); } + + Mat4X4 calc_perspective_projection_matrix(const float field_of_view, const float aspect_ratio, const float near, const float far, const NDCDepthRange ndc_depth_range) noexcept { - if (ndc_depth_range == NDCDepthRange::ZERO_TO_ONE) - return mat_perspective_left_handed( - field_of_view, aspect_ratio, near, far); + // UE stores horizontal FOV in FMinimalViewInfo — mirror engine's + // FMinimalViewInfo::CalculateProjectionMatrixGivenViewRectangle: + // XAxisMultiplier = 1 / tan(hfov/2) + // YAxisMultiplier = aspect / tan(hfov/2) + const float inv_tan_half_hfov = 1.f / std::tan(angles::degrees_to_radians(field_of_view) / 2.f); + const float x_axis = inv_tan_half_hfov; + const float y_axis = inv_tan_half_hfov * aspect_ratio; - return mat_perspective_left_handed(field_of_view, aspect_ratio, near, far); + if (ndc_depth_range == NDCDepthRange::ZERO_TO_ONE) + return { + {x_axis, 0, 0, 0}, + {0, y_axis, 0, 0}, + {0, 0, far / (far - near), -(near * far) / (far - near)}, + {0, 0, 1, 0}, + }; + if (ndc_depth_range == NDCDepthRange::NEGATIVE_ONE_TO_ONE) + return { + {x_axis, 0, 0, 0}, + {0, y_axis, 0, 0}, + {0, 0, (far + near) / (far - near), -(2.f * far * near) / (far - near)}, + {0, 0, 1, 0}, + }; + std::unreachable(); } } // namespace omath::unreal_engine