diff --git a/include/omath/projection/camera.hpp b/include/omath/projection/camera.hpp index add81ce..b386cfb 100644 --- a/include/omath/projection/camera.hpp +++ b/include/omath/projection/camera.hpp @@ -117,8 +117,9 @@ namespace omath::projection [[nodiscard]] std::expected, Error> WorldToScreen(const Vector3& worldPosition) const { const auto& viewProjMatrix = GetViewProjectionMatrix(); + const auto cameraCord = CalcViewMatrix() * MatColumnFromVector(worldPosition);; - auto projected = viewProjMatrix * MatColumnFromVector(worldPosition); + auto projected = CalcProjectionMatrix() * cameraCord; if (projected.At(3, 0) == 0.0f) return std::unexpected(Error::WORLD_POSITION_IS_OUT_OF_SCREEN_BOUNDS); @@ -129,7 +130,7 @@ namespace omath::projection return std::unexpected(Error::WORLD_POSITION_IS_OUT_OF_SCREEN_BOUNDS); const auto screenPositionX = (projected.At(0,0)+1.f) / 2.f * m_viewPort.m_width; - const auto screenPositionY = (-projected.At(1,0)+1) / 2.f * m_viewPort.m_height; + const auto screenPositionY = (projected.At(1,0)+1.f) / 2.f * m_viewPort.m_height; return Vector3{screenPositionX, screenPositionY, projected.At(2,0)}; } diff --git a/source/engines/unity_engine/formulas.cpp b/source/engines/unity_engine/formulas.cpp index 7a273cf..2a09d7d 100644 --- a/source/engines/unity_engine/formulas.cpp +++ b/source/engines/unity_engine/formulas.cpp @@ -4,6 +4,7 @@ #include "omath/engines/unity_engine/formulas.hpp" + namespace omath::unity_engine { Vector3 unity_engine::ForwardVector(const ViewAngles& angles) @@ -38,7 +39,7 @@ namespace omath::unity_engine {1.f / (aspectRatio * fovHalfTan), 0, 0, 0}, {0, 1.f / (fovHalfTan), 0, 0}, {0, 0, (far + near) / (far - near), -(2.f * far * near) / (far - near)}, - {0, 0, 1, 0}, + {0, 0, 1.f, 0}, }; } diff --git a/tests/engines/unit_test_source_engine.cpp b/tests/engines/unit_test_source_engine.cpp index 1b9592c..c129249 100644 --- a/tests/engines/unit_test_source_engine.cpp +++ b/tests/engines/unit_test_source_engine.cpp @@ -47,6 +47,26 @@ TEST(UnitTestSourceEngine, ProjectTargetMovedFromCamera) } } +TEST(UnitTestSourceEngine, ProjectTargetMovedUp) +{ + constexpr auto fov = omath::projection::FieldOfView::FromDegrees(90.f); + const auto cam = omath::source_engine::Camera({0, 0, 0}, {}, {1920.f, 1080.f}, fov, 0.01f, 1000.f); + + auto prev = 1080.f; + for (float distance = 0.0f; distance < 10.f; distance += 1.f) + { + const auto projected = cam.WorldToScreen({100.f, 0, distance}); + EXPECT_TRUE(projected.has_value()); + + if (!projected.has_value()) + continue; + + EXPECT_TRUE(projected->y < prev); + + prev = projected->y; + } +} + TEST(UnitTestSourceEngine, CameraSetAndGetFov) { 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 4f6b72b..607c6f6 100644 --- a/tests/engines/unit_test_unity_engine.cpp +++ b/tests/engines/unit_test_unity_engine.cpp @@ -1,3 +1,81 @@ // // Created by Orange on 11/27/2024. // +// +// Created by Orange on 11/23/2024. +// +#include +#include +#include +#include + + +TEST(UnitTestUnityEngine, ForwardVector) +{ + const auto forward = omath::unity_engine::ForwardVector({}); + + EXPECT_EQ(forward, omath::unity_engine::kAbsForward); +} + +TEST(UnitTestUnityEngine, RightVector) +{ + const auto right = omath::unity_engine::RightVector({}); + + EXPECT_EQ(right, omath::unity_engine::kAbsRight); +} + +TEST(UnitTestUnityEngine, UpVector) +{ + const auto up = omath::unity_engine::UpVector({}); + EXPECT_EQ(up, omath::unity_engine::kAbsUp); +} + +/*TEST(UnitTestUnityEngine, ProjectTargetMovedFromCamera) +{ + constexpr auto fov = omath::projection::FieldOfView::FromDegrees(60.f); + const auto cam = omath::unity_engine::Camera({0, 0, 0}, {}, {1280.f, 720.f}, fov, 0.01f, 1000.f); + + + for (float distance = 0.02f; distance < 100.f; distance += 0.01f) + { + const auto projected = cam.WorldToScreen({0, 0, distance}); + + EXPECT_TRUE(projected.has_value()); + + if (!projected.has_value()) + continue; + + EXPECT_NEAR(projected->x, 640, 0.00001f); + EXPECT_NEAR(projected->y, 360, 0.00001f); + } +}*/ +TEST(UnitTestUnityEngine, Project) +{ + constexpr auto fov = omath::projection::FieldOfView::FromDegrees(60.f); + + const auto cam = omath::unity_engine::Camera({0, 0, 0}, {}, {1280.f, 720.f}, fov, 0.03f, 1000.f); + const auto proj = cam.WorldToScreen({0.f, 2.f, 10.f}); + std::println("Unity projected: {}, {}", proj->x, proj->y); + std::println("{}", cam.GetViewProjectionMatrix().ToString()); +} + +TEST(UnitTestUnityEngine, CameraSetAndGetFov) +{ + constexpr auto fov = omath::projection::FieldOfView::FromDegrees(90.f); + auto cam = omath::unity_engine::Camera({0, 0, 0}, {}, {1920.f, 1080.f}, fov, 0.01f, 1000.f); + + EXPECT_EQ(cam.GetFieldOfView().AsDegrees(), 90.f); + cam.SetFieldOfView(omath::projection::FieldOfView::FromDegrees(50.f)); + + EXPECT_EQ(cam.GetFieldOfView().AsDegrees(), 50.f); +} + +TEST(UnitTestUnityEngine, CameraSetAndGetOrigin) +{ + auto cam = omath::unity_engine::Camera({0, 0, 0}, {}, {1920.f, 1080.f}, {}, 0.01f, 1000.f); + + EXPECT_EQ(cam.GetOrigin(), omath::Vector3{}); + cam.SetFieldOfView(omath::projection::FieldOfView::FromDegrees(50.f)); + + EXPECT_EQ(cam.GetFieldOfView().AsDegrees(), 50.f); +} \ No newline at end of file