diff --git a/include/omath/mat.hpp b/include/omath/mat.hpp index 674612a..09252cd 100644 --- a/include/omath/mat.hpp +++ b/include/omath/mat.hpp @@ -430,4 +430,30 @@ namespace omath { return MatRotationAxisZ(angles.yaw) * MatRotationAxisY(angles.pitch) * MatRotationAxisX(angles.roll); } + + template + [[nodiscard]] + Mat<4, 4, Type, St> MatPerspectiveLeftHanded(const float fieldOfView, const float aspectRatio, const float near, + const float far) noexcept + { + const float fovHalfTan = std::tan(angles::DegreesToRadians(fieldOfView) / 2.f); + + return {{1.f / (aspectRatio * fovHalfTan), 0.f, 0.f, 0.f}, + {0.f, 1.f / fovHalfTan, 0.f, 0.f}, + {0.f, 0.f, (far + near) / (far - near), -(2.f * near * far) / (far - near)}, + {0.f, 0.f, 1.f, 0.f}}; + } + + template + [[nodiscard]] + Mat<4, 4, Type, St> MatPerspectiveRightHanded(const float fieldOfView, const float aspectRatio, const float near, + const float far) noexcept + { + const float fovHalfTan = std::tan(angles::DegreesToRadians(fieldOfView) / 2.f); + + return {{1.f / (aspectRatio * fovHalfTan), 0.f, 0.f, 0.f}, + {0.f, 1.f / fovHalfTan, 0.f, 0.f}, + {0.f, 0.f, -(far + near) / (far - near), -(2.f * near * far) / (far - near)}, + {0.f, 0.f, -1.f, 0.f}}; + } } // namespace omath diff --git a/source/engines/iw_engine/formulas.cpp b/source/engines/iw_engine/formulas.cpp index 3bc47dc..ec9220d 100644 --- a/source/engines/iw_engine/formulas.cpp +++ b/source/engines/iw_engine/formulas.cpp @@ -26,22 +26,25 @@ namespace omath::iw_engine return {vec.At(0, 0), vec.At(1, 0), vec.At(2, 0)}; } + Mat4x4 CalcViewMatrix(const ViewAngles& angles, const Vector3& cam_origin) { - return MatCameraView(ForwardVector(angles), RightVector(angles), UpVector(angles), cam_origin); + return MatCameraView(ForwardVector(angles), RightVector(angles), -UpVector(angles), cam_origin); } + Mat4x4 CalcPerspectiveProjectionMatrix(const float fieldOfView, const float aspectRatio, const float near, const float far) { - // NOTE: Need magic number to fix fov calculation, since source inherit Quake proj matrix calculation + // NOTE: Need magic number to fix fov calculation, since IW engine inherit Quake proj matrix calculation constexpr auto kMultiplyFactor = 0.75f; + const float fovHalfTan = std::tan(angles::DegreesToRadians(fieldOfView) / 2.f) * kMultiplyFactor; return { {1.f / (aspectRatio * fovHalfTan), 0, 0, 0}, - {0, 1.f / fovHalfTan, 0, 0}, + {0, 1.f / (fovHalfTan), 0, 0}, {0, 0, (far + near) / (far - near), -(2.f * far * near) / (far - near)}, {0, 0, 1, 0}, }; - } + }; } // namespace omath::iw_engine diff --git a/source/engines/source_engine/formulas.cpp b/source/engines/source_engine/formulas.cpp index 1051138..620e9f3 100644 --- a/source/engines/source_engine/formulas.cpp +++ b/source/engines/source_engine/formulas.cpp @@ -28,8 +28,9 @@ namespace omath::source_engine Mat4x4 CalcViewMatrix(const ViewAngles& angles, const Vector3& cam_origin) { - return MatCameraView(ForwardVector(angles), RightVector(angles), UpVector(angles), cam_origin); + return MatCameraView(ForwardVector(angles), RightVector(angles), -UpVector(angles), cam_origin); } + Mat4x4 CalcPerspectiveProjectionMatrix(const float fieldOfView, const float aspectRatio, const float near, const float far) { @@ -43,7 +44,6 @@ namespace omath::source_engine {0, 1.f / (fovHalfTan), 0, 0}, {0, 0, (far + near) / (far - near), -(2.f * far * near) / (far - near)}, {0, 0, 1, 0}, - }; } } // namespace omath::source_engine diff --git a/source/engines/unity_engine/camera.cpp b/source/engines/unity_engine/camera.cpp index e1b256c..5270f5a 100644 --- a/source/engines/unity_engine/camera.cpp +++ b/source/engines/unity_engine/camera.cpp @@ -2,6 +2,7 @@ // Created by Vlad on 3/22/2025. // #include +#include namespace omath::unity_engine