diff --git a/CMakeLists.txt b/CMakeLists.txt index b2bf452..dab8ddf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,7 +5,7 @@ project(omath VERSION 1.0.1 LANGUAGES CXX) include(CMakePackageConfigHelpers) -option(OMATH_BUILD_TESTS "Build unit tests" OFF) +option(OMATH_BUILD_TESTS "Build unit tests" ON) option(OMATH_THREAT_WARNING_AS_ERROR "Set highest level of warnings and force compiler to treat them as errors" ON) option(OMATH_BUILD_AS_SHARED_LIBRARY "Build Omath as .so or .dll" OFF) option(OMATH_USE_AVX2 "Omath will use AVX2 to boost performance" ON) diff --git a/include/omath/engines/iw_engine/Camera.hpp b/include/omath/engines/iw_engine/Camera.hpp new file mode 100644 index 0000000..cd413f3 --- /dev/null +++ b/include/omath/engines/iw_engine/Camera.hpp @@ -0,0 +1,21 @@ +// +// Created by Vlad on 3/17/2025. +// + +#pragma once +#include "Constants.hpp" +#include "omath/projection/Camera.hpp" + +namespace omath::iw_engine +{ + class Camera final : public projection::Camera + { + public: + Camera(const Vector3& position, const ViewAngles& viewAngles, const projection::ViewPort& viewPort, + const Angle& fov, float near, float far); + void LookAt(const Vector3& target) override; + protected: + [[nodiscard]] Mat4x4 CalcViewMatrix() const override; + [[nodiscard]] Mat4x4 CalcProjectionMatrix() const override; + }; +} \ No newline at end of file diff --git a/include/omath/engines/iw_engine/Constants.hpp b/include/omath/engines/iw_engine/Constants.hpp new file mode 100644 index 0000000..8897915 --- /dev/null +++ b/include/omath/engines/iw_engine/Constants.hpp @@ -0,0 +1,25 @@ +// +// Created by Vlad on 3/17/2025. +// + +#pragma once +#include +#include +#include +#include + +namespace omath::iw_engine +{ + constexpr Vector3 kAbsUp = {0, 0, 1}; + constexpr Vector3 kAbsRight = {0, -1, 0}; + constexpr Vector3 kAbsForward = {1, 0, 0}; + + 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 YawAngle = Angle; + using RollAngle = Angle; + + using ViewAngles = omath::ViewAngles; +} \ No newline at end of file diff --git a/include/omath/engines/iw_engine/Formulas.hpp b/include/omath/engines/iw_engine/Formulas.hpp new file mode 100644 index 0000000..bd757d2 --- /dev/null +++ b/include/omath/engines/iw_engine/Formulas.hpp @@ -0,0 +1,54 @@ +// +// Created by Vlad on 3/17/2025. +// + +#pragma once +#include "Constants.hpp" + +namespace omath::iw_engine +{ + [[nodiscard]] + inline Vector3 ForwardVector(const ViewAngles& angles) + { + const auto vec = MatRotation(angles) * MatColumnFromVector(kAbsForward); + + return {vec.At(0, 0), vec.At(1, 0), vec.At(2, 0)}; + } + + [[nodiscard]] + inline Vector3 RightVector(const ViewAngles& angles) + { + const auto vec = MatRotation(angles) * MatColumnFromVector(kAbsRight); + + return {vec.At(0, 0), vec.At(1, 0), vec.At(2, 0)}; + } + + [[nodiscard]] + inline Vector3 UpVector(const ViewAngles& angles) + { + const auto vec = MatRotation(angles) * MatColumnFromVector(kAbsUp); + + return {vec.At(0, 0), vec.At(1, 0), vec.At(2, 0)}; + } + + [[nodiscard]] inline Mat4x4 CalcViewMatrix(const ViewAngles& angles, const Vector3& cam_origin) + { + return MatCameraView(ForwardVector(angles), RightVector(angles), UpVector(angles), cam_origin); + } + + + [[nodiscard]] + inline Mat4x4 CalcPerspectiveProjectionMatrix(const float fieldOfView, const float aspectRatio, const float near, + const float far) + { + const float fovHalfTan = std::tan(angles::DegreesToRadians(fieldOfView) / 2.f); + + return + { + {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}, + }; + } +} // namespace omath::source diff --git a/source/engines/CMakeLists.txt b/source/engines/CMakeLists.txt index bfb0765..eb223b0 100644 --- a/source/engines/CMakeLists.txt +++ b/source/engines/CMakeLists.txt @@ -1,2 +1,3 @@ add_subdirectory(source_engine) -add_subdirectory(opengl_engine) \ No newline at end of file +add_subdirectory(opengl_engine) +add_subdirectory(iw_engine) diff --git a/source/engines/iw_engine/CMakeLists.txt b/source/engines/iw_engine/CMakeLists.txt new file mode 100644 index 0000000..0abf868 --- /dev/null +++ b/source/engines/iw_engine/CMakeLists.txt @@ -0,0 +1 @@ +target_sources(omath PRIVATE Camera.cpp) \ No newline at end of file diff --git a/source/engines/iw_engine/Camera.cpp b/source/engines/iw_engine/Camera.cpp new file mode 100644 index 0000000..5b7cfe0 --- /dev/null +++ b/source/engines/iw_engine/Camera.cpp @@ -0,0 +1,34 @@ +// +// Created by Vlad on 3/17/2025. +// +#include "omath/engines/iw_engine/Camera.hpp" +#include "omath/engines/iw_engine/Formulas.hpp" + +namespace omath::iw_engine +{ + + Camera::Camera(const Vector3& position, const ViewAngles& viewAngles, const projection::ViewPort& viewPort, + const Angle& fov, const float near, const float far) : + projection::Camera(position, viewAngles, viewPort, fov, near, far) + { + } + void Camera::LookAt([[maybe_unused]] const Vector3& target) + { + const float distance = m_origin.DistTo(target); + const auto delta = target - m_origin; + + + m_viewAngles.pitch = PitchAngle::FromRadians(std::asin(delta.z / distance)); + m_viewAngles.yaw = -YawAngle::FromRadians(std::atan2(delta.y, delta.x)); + m_viewAngles.roll = RollAngle::FromRadians(0.f); + } + Mat4x4 Camera::CalcViewMatrix() const + { + return iw_engine::CalcViewMatrix(m_viewAngles, m_origin); + } + Mat4x4 Camera::CalcProjectionMatrix() const + { + return CalcPerspectiveProjectionMatrix(m_fieldOfView.AsDegrees(), m_viewPort.AspectRatio(), m_nearPlaneDistance, + m_farPlaneDistance); + } +} // namespace omath::openg \ No newline at end of file diff --git a/tests/engines/UnitTestIwEngine.cpp b/tests/engines/UnitTestIwEngine.cpp new file mode 100644 index 0000000..9df832c --- /dev/null +++ b/tests/engines/UnitTestIwEngine.cpp @@ -0,0 +1,3 @@ +// +// Created by Vlad on 3/17/2025. +//