diff --git a/include/omath/angle.hpp b/include/omath/angle.hpp index 07d5510..11d36d9 100644 --- a/include/omath/angle.hpp +++ b/include/omath/angle.hpp @@ -3,9 +3,9 @@ // #pragma once -#include "omath/angles.hpp" #include #include +#include "omath/angles.hpp" namespace omath @@ -17,7 +17,7 @@ namespace omath }; template - requires std::is_arithmetic_v + requires std::is_arithmetic_v class Angle { Type m_angle; @@ -34,6 +34,7 @@ namespace omath std::unreachable(); } } + public: [[nodiscard]] constexpr static Angle FromDegrees(const Type& degrees) @@ -42,7 +43,6 @@ namespace omath } constexpr Angle() : m_angle(0) { - } [[nodiscard]] constexpr static Angle FromRadians(const Type& degrees) @@ -149,4 +149,4 @@ namespace omath return Angle{-m_angle}; } }; -} +} // namespace omath diff --git a/include/omath/engines/iw_engine/formulas.hpp b/include/omath/engines/iw_engine/formulas.hpp index a604f48..60d1fee 100644 --- a/include/omath/engines/iw_engine/formulas.hpp +++ b/include/omath/engines/iw_engine/formulas.hpp @@ -16,8 +16,10 @@ namespace omath::iw_engine [[nodiscard]] Vector3 UpVector(const ViewAngles& angles); - [[nodiscard]] Mat4x4 CalcViewMatrix(const ViewAngles& angles, const Vector3& cam_origin); + [[nodiscard]] + Mat4x4 RotationMatrix(const ViewAngles& angles); + [[nodiscard]] Mat4x4 CalcViewMatrix(const ViewAngles& angles, const Vector3& cam_origin); [[nodiscard]] Mat4x4 CalcPerspectiveProjectionMatrix(float fieldOfView, float aspectRatio, float near, float far); diff --git a/include/omath/engines/opengl_engine/constants.hpp b/include/omath/engines/opengl_engine/constants.hpp index 66aac7d..3e0a762 100644 --- a/include/omath/engines/opengl_engine/constants.hpp +++ b/include/omath/engines/opengl_engine/constants.hpp @@ -17,9 +17,10 @@ namespace omath::opengl_engine using Mat4x4 = Mat<4, 4, float, MatStoreType::COLUMN_MAJOR>; using Mat3x3 = Mat<4, 4, float, MatStoreType::COLUMN_MAJOR>; using Mat1x3 = Mat<1, 3, float, MatStoreType::COLUMN_MAJOR>; - using PitchAngle = Angle; - using YawAngle = Angle; - using RollAngle = Angle; + using PitchAngle = Angle; + using YawAngle = Angle; + using RollAngle = Angle; + using ViewAngles = omath::ViewAngles; } \ No newline at end of file diff --git a/include/omath/engines/opengl_engine/formulas.hpp b/include/omath/engines/opengl_engine/formulas.hpp index d9dcfe7..7f24ef6 100644 --- a/include/omath/engines/opengl_engine/formulas.hpp +++ b/include/omath/engines/opengl_engine/formulas.hpp @@ -18,6 +18,8 @@ namespace omath::opengl_engine [[nodiscard]] Mat4x4 CalcViewMatrix(const ViewAngles& angles, const Vector3& cam_origin); + [[nodiscard]] + Mat4x4 RotationMatrix(const ViewAngles& angles); [[nodiscard]] Mat4x4 CalcPerspectiveProjectionMatrix(float fieldOfView, float aspectRatio, float near, float far); diff --git a/include/omath/engines/source_engine/formulas.hpp b/include/omath/engines/source_engine/formulas.hpp index fd6415e..450de1e 100644 --- a/include/omath/engines/source_engine/formulas.hpp +++ b/include/omath/engines/source_engine/formulas.hpp @@ -9,6 +9,9 @@ namespace omath::source_engine [[nodiscard]] Vector3 ForwardVector(const ViewAngles& angles); + [[nodiscard]] + Mat4x4 RotationMatrix(const ViewAngles& angles); + [[nodiscard]] Vector3 RightVector(const ViewAngles& angles); @@ -17,7 +20,6 @@ namespace omath::source_engine [[nodiscard]] Mat4x4 CalcViewMatrix(const ViewAngles& angles, const Vector3& cam_origin); - [[nodiscard]] Mat4x4 CalcPerspectiveProjectionMatrix(float fieldOfView, float aspectRatio, float near, float far); } // namespace omath::source diff --git a/include/omath/engines/unity_engine/constants.hpp b/include/omath/engines/unity_engine/constants.hpp index dae1775..27ec9a3 100644 --- a/include/omath/engines/unity_engine/constants.hpp +++ b/include/omath/engines/unity_engine/constants.hpp @@ -18,7 +18,7 @@ namespace omath::unity_engine using Mat4x4 = Mat<4, 4, float, MatStoreType::ROW_MAJOR>; using Mat3x3 = Mat<4, 4, float, MatStoreType::ROW_MAJOR>; using Mat1x3 = Mat<1, 3, float, MatStoreType::ROW_MAJOR>; - using PitchAngle = Angle; + using PitchAngle = Angle; using YawAngle = Angle; using RollAngle = Angle; diff --git a/include/omath/engines/unity_engine/formulas.hpp b/include/omath/engines/unity_engine/formulas.hpp index 6352cd1..8b36953 100644 --- a/include/omath/engines/unity_engine/formulas.hpp +++ b/include/omath/engines/unity_engine/formulas.hpp @@ -18,6 +18,8 @@ namespace omath::unity_engine [[nodiscard]] Mat4x4 CalcViewMatrix(const ViewAngles& angles, const Vector3& cam_origin); + [[nodiscard]] + Mat4x4 RotationMatrix(const ViewAngles& angles); [[nodiscard]] Mat4x4 CalcPerspectiveProjectionMatrix(float fieldOfView, float aspectRatio, float near, float far); diff --git a/include/omath/mat.hpp b/include/omath/mat.hpp index 68f867f..1d7b451 100644 --- a/include/omath/mat.hpp +++ b/include/omath/mat.hpp @@ -428,13 +428,6 @@ namespace omath } * MatTranslation(-cameraOrigin); } - template - [[nodiscard]] - Mat<4, 4, Type, St> MatRotation(const ViewAngles& angles) noexcept - { - 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, diff --git a/source/engines/iw_engine/formulas.cpp b/source/engines/iw_engine/formulas.cpp index f4fe076..0c293fe 100644 --- a/source/engines/iw_engine/formulas.cpp +++ b/source/engines/iw_engine/formulas.cpp @@ -9,23 +9,27 @@ namespace omath::iw_engine Vector3 ForwardVector(const ViewAngles& angles) { - const auto vec = MatRotation(angles) * MatColumnFromVector(kAbsForward); + const auto vec = RotationMatrix(angles) * MatColumnFromVector(kAbsForward); return {vec.At(0, 0), vec.At(1, 0), vec.At(2, 0)}; } Vector3 RightVector(const ViewAngles& angles) { - const auto vec = MatRotation(angles) * MatColumnFromVector(kAbsRight); + const auto vec = RotationMatrix(angles) * MatColumnFromVector(kAbsRight); return {vec.At(0, 0), vec.At(1, 0), vec.At(2, 0)}; } Vector3 UpVector(const ViewAngles& angles) { - const auto vec = MatRotation(angles) * MatColumnFromVector(kAbsUp); + const auto vec = RotationMatrix(angles) * MatColumnFromVector(kAbsUp); return {vec.At(0, 0), vec.At(1, 0), vec.At(2, 0)}; } + Mat4x4 RotationMatrix(const ViewAngles& angles) + { + return MatRotationAxisZ(angles.yaw) * MatRotationAxisY(angles.pitch) * MatRotationAxisX(angles.roll); + } Mat4x4 CalcViewMatrix(const ViewAngles& angles, const Vector3& cam_origin) { diff --git a/source/engines/opengl_engine/formulas.cpp b/source/engines/opengl_engine/formulas.cpp index 8162bdb..f3e5b5c 100644 --- a/source/engines/opengl_engine/formulas.cpp +++ b/source/engines/opengl_engine/formulas.cpp @@ -9,19 +9,19 @@ namespace omath::opengl_engine Vector3 ForwardVector(const ViewAngles& angles) { - const auto vec = MatRotation(angles) * MatColumnFromVector(kAbsForward); + const auto vec = RotationMatrix(angles) * MatColumnFromVector(kAbsForward); return {vec.At(0, 0), vec.At(1, 0), vec.At(2, 0)}; } Vector3 RightVector(const ViewAngles& angles) { - const auto vec = MatRotation(angles) * MatColumnFromVector(kAbsRight); + const auto vec = RotationMatrix(angles) * MatColumnFromVector(kAbsRight); return {vec.At(0, 0), vec.At(1, 0), vec.At(2, 0)}; } Vector3 UpVector(const ViewAngles& angles) { - const auto vec = MatRotation(angles) * MatColumnFromVector(kAbsUp); + const auto vec = RotationMatrix(angles) * MatColumnFromVector(kAbsUp); return {vec.At(0, 0), vec.At(1, 0), vec.At(2, 0)}; } @@ -30,6 +30,12 @@ namespace omath::opengl_engine return MatCameraView(-ForwardVector(angles), RightVector(angles), UpVector(angles), cam_origin); } + Mat4x4 RotationMatrix(const ViewAngles& angles) + { + return MatRotationAxisZ(angles.roll) * + MatRotationAxisY(-angles.yaw) * + MatRotationAxisX(-angles.pitch); + } Mat4x4 CalcPerspectiveProjectionMatrix(const float fieldOfView, const float aspectRatio, const float near, const float far) { diff --git a/source/engines/source_engine/formulas.cpp b/source/engines/source_engine/formulas.cpp index f037cad..5dcca88 100644 --- a/source/engines/source_engine/formulas.cpp +++ b/source/engines/source_engine/formulas.cpp @@ -8,20 +8,25 @@ namespace omath::source_engine { Vector3 ForwardVector(const ViewAngles& angles) { - const auto vec = MatRotation(angles) * MatColumnFromVector(kAbsForward); + const auto vec = RotationMatrix(angles) * MatColumnFromVector(kAbsForward); return {vec.At(0, 0), vec.At(1, 0), vec.At(2, 0)}; } + Mat4x4 RotationMatrix(const ViewAngles& angles) + { + return MatRotationAxisZ(angles.yaw) * MatRotationAxisY(angles.pitch) * MatRotationAxisX(angles.roll); + } + Vector3 RightVector(const ViewAngles& angles) { - const auto vec = MatRotation(angles) * MatColumnFromVector(kAbsRight); + const auto vec = RotationMatrix(angles) * MatColumnFromVector(kAbsRight); return {vec.At(0, 0), vec.At(1, 0), vec.At(2, 0)}; } Vector3 UpVector(const ViewAngles& angles) { - const auto vec = MatRotation(angles) * MatColumnFromVector(kAbsUp); + const auto vec = RotationMatrix(angles) * MatColumnFromVector(kAbsUp); return {vec.At(0, 0), vec.At(1, 0), vec.At(2, 0)}; } diff --git a/source/engines/unity_engine/formulas.cpp b/source/engines/unity_engine/formulas.cpp index d3a872f..798920d 100644 --- a/source/engines/unity_engine/formulas.cpp +++ b/source/engines/unity_engine/formulas.cpp @@ -9,19 +9,19 @@ namespace omath::unity_engine { Vector3 ForwardVector(const ViewAngles& angles) { - const auto vec = MatRotation(angles) * MatColumnFromVector(kAbsForward); + const auto vec = RotationMatrix(angles) * MatColumnFromVector(kAbsForward); return {vec.At(0, 0), vec.At(1, 0), vec.At(2, 0)}; } Vector3 RightVector(const ViewAngles& angles) { - const auto vec = MatRotation(angles) * MatColumnFromVector(kAbsRight); + const auto vec = RotationMatrix(angles) * MatColumnFromVector(kAbsRight); return {vec.At(0, 0), vec.At(1, 0), vec.At(2, 0)}; } Vector3 UpVector(const ViewAngles& angles) { - const auto vec = MatRotation(angles) * MatColumnFromVector(kAbsUp); + const auto vec = RotationMatrix(angles) * MatColumnFromVector(kAbsUp); return {vec.At(0, 0), vec.At(1, 0), vec.At(2, 0)}; } @@ -30,6 +30,12 @@ namespace omath::unity_engine return MatCameraView(ForwardVector(angles), -RightVector(angles), UpVector(angles), cam_origin); } + Mat4x4 RotationMatrix(const ViewAngles& angles) + { + return MatRotationAxisZ(angles.roll) * + MatRotationAxisY(angles.yaw) * + MatRotationAxisX(angles.pitch); + } Mat4x4 CalcPerspectiveProjectionMatrix(const float fieldOfView, const float aspectRatio, const float near, const float far) { diff --git a/source/projectile_prediction/proj_pred_engine_avx2.cpp b/source/projectile_prediction/proj_pred_engine_avx2.cpp index 632f5b6..48d2b69 100644 --- a/source/projectile_prediction/proj_pred_engine_avx2.cpp +++ b/source/projectile_prediction/proj_pred_engine_avx2.cpp @@ -5,7 +5,7 @@ #include #include - +#include #if defined(OMATH_USE_AVX2) && defined(__i386__) && defined(__x86_64__) #include #include diff --git a/tests/engines/unit_test_iw_engine.cpp b/tests/engines/unit_test_iw_engine.cpp index 679af03..86b7d0b 100644 --- a/tests/engines/unit_test_iw_engine.cpp +++ b/tests/engines/unit_test_iw_engine.cpp @@ -27,6 +27,42 @@ TEST(UnitTestIwEngine, UpVector) EXPECT_EQ(up, omath::iw_engine::kAbsUp); } +TEST(UnitTestIwEngine, ForwardVectorRotationYaw) +{ + omath::iw_engine::ViewAngles angles; + + angles.yaw = omath::iw_engine::YawAngle::FromDegrees(-90.f); + + const auto forward = omath::iw_engine::ForwardVector(angles); + EXPECT_NEAR(forward.x, omath::iw_engine::kAbsRight.x, 0.00001f); + EXPECT_NEAR(forward.y, omath::iw_engine::kAbsRight.y, 0.00001f); + EXPECT_NEAR(forward.z, omath::iw_engine::kAbsRight.z, 0.00001f); +} + +TEST(UnitTestIwEngine, ForwardVectorRotationPitch) +{ + omath::iw_engine::ViewAngles angles; + + angles.pitch = omath::iw_engine::PitchAngle::FromDegrees(-89.f); + + const auto forward = omath::iw_engine::ForwardVector(angles); + EXPECT_NEAR(forward.x, omath::iw_engine::kAbsUp.x, 0.02f); + EXPECT_NEAR(forward.y, omath::iw_engine::kAbsUp.y, 0.01f); + EXPECT_NEAR(forward.z, omath::iw_engine::kAbsUp.z, 0.01f); +} + +TEST(UnitTestIwEngine, ForwardVectorRotationRoll) +{ + omath::iw_engine::ViewAngles angles; + + angles.roll = omath::iw_engine::RollAngle::FromDegrees(90.f); + + const auto forward = omath::iw_engine::UpVector(angles); + EXPECT_NEAR(forward.x, omath::iw_engine::kAbsRight.x, 0.00001f); + EXPECT_NEAR(forward.y, omath::iw_engine::kAbsRight.y, 0.00001f); + EXPECT_NEAR(forward.z, omath::iw_engine::kAbsRight.z, 0.00001f); +} + TEST(UnitTestIwEngine, ProjectTargetMovedFromCamera) { constexpr auto fov = omath::projection::FieldOfView::FromDegrees(90.f); diff --git a/tests/engines/unit_test_open_gl.cpp b/tests/engines/unit_test_open_gl.cpp index 5e0a462..170b306 100644 --- a/tests/engines/unit_test_open_gl.cpp +++ b/tests/engines/unit_test_open_gl.cpp @@ -10,14 +10,12 @@ TEST(UnitTestOpenGL, ForwardVector) { const auto forward = omath::opengl_engine::ForwardVector({}); - EXPECT_EQ(forward, omath::opengl_engine::kAbsForward); } TEST(UnitTestOpenGL, RightVector) { const auto right = omath::opengl_engine::RightVector({}); - EXPECT_EQ(right, omath::opengl_engine::kAbsRight); } @@ -27,6 +25,44 @@ TEST(UnitTestOpenGL, UpVector) EXPECT_EQ(up, omath::opengl_engine::kAbsUp); } +TEST(UnitTestOpenGL, ForwardVectorRotationYaw) +{ + omath::opengl_engine::ViewAngles angles; + + angles.yaw = omath::opengl_engine::YawAngle::FromDegrees(90.f); + + const auto forward = omath::opengl_engine::ForwardVector(angles); + EXPECT_NEAR(forward.x, omath::opengl_engine::kAbsRight.x, 0.00001f); + EXPECT_NEAR(forward.y, omath::opengl_engine::kAbsRight.y, 0.00001f); + EXPECT_NEAR(forward.z, omath::opengl_engine::kAbsRight.z, 0.00001f); +} + + + +TEST(UnitTestOpenGL, ForwardVectorRotationPitch) +{ + omath::opengl_engine::ViewAngles angles; + + angles.pitch = omath::opengl_engine::PitchAngle::FromDegrees(-90.f); + + const auto forward = omath::opengl_engine::ForwardVector(angles); + EXPECT_NEAR(forward.x, omath::opengl_engine::kAbsUp.x, 0.00001f); + EXPECT_NEAR(forward.y, omath::opengl_engine::kAbsUp.y, 0.00001f); + EXPECT_NEAR(forward.z, omath::opengl_engine::kAbsUp.z, 0.00001f); +} + +TEST(UnitTestOpenGL, ForwardVectorRotationRoll) +{ + omath::opengl_engine::ViewAngles angles; + + angles.roll = omath::opengl_engine::RollAngle::FromDegrees(-90.f); + + const auto forward = omath::opengl_engine::UpVector(angles); + EXPECT_NEAR(forward.x, omath::opengl_engine::kAbsRight.x, 0.00001f); + EXPECT_NEAR(forward.y, omath::opengl_engine::kAbsRight.y, 0.00001f); + EXPECT_NEAR(forward.z, omath::opengl_engine::kAbsRight.z, 0.00001f); +} + TEST(UnitTestOpenGL, ProjectTargetMovedFromCamera) { constexpr auto fov = omath::projection::FieldOfView::FromDegrees(90.f); diff --git a/tests/engines/unit_test_source_engine.cpp b/tests/engines/unit_test_source_engine.cpp index c129249..eebd58e 100644 --- a/tests/engines/unit_test_source_engine.cpp +++ b/tests/engines/unit_test_source_engine.cpp @@ -27,6 +27,42 @@ TEST(UnitTestSourceEngine, UpVector) EXPECT_EQ(up, omath::source_engine::kAbsUp); } +TEST(UnitTestSourceEngine, ForwardVectorRotationYaw) +{ + omath::source_engine::ViewAngles angles; + + angles.yaw = omath::source_engine::YawAngle::FromDegrees(-90.f); + + const auto forward = omath::source_engine::ForwardVector(angles); + EXPECT_NEAR(forward.x, omath::source_engine::kAbsRight.x, 0.00001f); + EXPECT_NEAR(forward.y, omath::source_engine::kAbsRight.y, 0.00001f); + EXPECT_NEAR(forward.z, omath::source_engine::kAbsRight.z, 0.00001f); +} + +TEST(UnitTestSourceEngine, ForwardVectorRotationPitch) +{ + omath::source_engine::ViewAngles angles; + + angles.pitch = omath::source_engine::PitchAngle::FromDegrees(-89.f); + + const auto forward = omath::source_engine::ForwardVector(angles); + EXPECT_NEAR(forward.x, omath::source_engine::kAbsUp.x, 0.02f); + EXPECT_NEAR(forward.y, omath::source_engine::kAbsUp.y, 0.01f); + EXPECT_NEAR(forward.z, omath::source_engine::kAbsUp.z, 0.01f); +} + +TEST(UnitTestSourceEngine, ForwardVectorRotationRoll) +{ + omath::source_engine::ViewAngles angles; + + angles.roll = omath::source_engine::RollAngle::FromDegrees(90.f); + + const auto forward = omath::source_engine::UpVector(angles); + EXPECT_NEAR(forward.x, omath::source_engine::kAbsRight.x, 0.00001f); + EXPECT_NEAR(forward.y, omath::source_engine::kAbsRight.y, 0.00001f); + EXPECT_NEAR(forward.z, omath::source_engine::kAbsRight.z, 0.00001f); +} + TEST(UnitTestSourceEngine, ProjectTargetMovedFromCamera) { constexpr auto fov = omath::projection::FieldOfView::FromDegrees(90.f); diff --git a/tests/engines/unit_test_unity_engine.cpp b/tests/engines/unit_test_unity_engine.cpp index 2e0daaa..7fb95a2 100644 --- a/tests/engines/unit_test_unity_engine.cpp +++ b/tests/engines/unit_test_unity_engine.cpp @@ -14,6 +14,42 @@ TEST(UnitTestUnityEngine, ForwardVector) EXPECT_EQ(forward, omath::unity_engine::kAbsForward); } +TEST(UnitTestUnityEngine, ForwardVectorRotationYaw) +{ + omath::unity_engine::ViewAngles angles; + + angles.yaw = omath::unity_engine::YawAngle::FromDegrees(90.f); + + const auto forward = omath::unity_engine::ForwardVector(angles); + EXPECT_NEAR(forward.x, omath::unity_engine::kAbsRight.x, 0.00001f); + EXPECT_NEAR(forward.y, omath::unity_engine::kAbsRight.y, 0.00001f); + EXPECT_NEAR(forward.z, omath::unity_engine::kAbsRight.z, 0.00001f); +} + +TEST(UnitTestUnityEngine, ForwardVectorRotationPitch) +{ + omath::unity_engine::ViewAngles angles; + + angles.pitch = omath::unity_engine::PitchAngle::FromDegrees(-90.f); + + const auto forward = omath::unity_engine::ForwardVector(angles); + EXPECT_NEAR(forward.x, omath::unity_engine::kAbsUp.x, 0.00001f); + EXPECT_NEAR(forward.y, omath::unity_engine::kAbsUp.y, 0.00001f); + EXPECT_NEAR(forward.z, omath::unity_engine::kAbsUp.z, 0.00001f); +} + +TEST(UnitTestUnityEngine, ForwardVectorRotationRoll) +{ + omath::unity_engine::ViewAngles angles; + + angles.roll = omath::unity_engine::RollAngle::FromDegrees(-90.f); + + const auto forward = omath::unity_engine::UpVector(angles); + EXPECT_NEAR(forward.x, omath::unity_engine::kAbsRight.x, 0.00001f); + EXPECT_NEAR(forward.y, omath::unity_engine::kAbsRight.y, 0.00001f); + EXPECT_NEAR(forward.z, omath::unity_engine::kAbsRight.z, 0.00001f); +} + TEST(UnitTestUnityEngine, RightVector) { const auto right = omath::unity_engine::RightVector({});