diff --git a/CMakeLists.txt b/CMakeLists.txt index 406feb4b..c50a9453 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,9 +10,10 @@ option(OMATH_THREAT_WARNING_AS_ERROR "Set highest level of warnings and force co 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) option(OMATH_IMGUI_INTEGRATION "Omath will define method to convert omath types to imgui types" OFF) +option(OMATH_BUILD_EXAMPLES "Build example projects with you can learn & play" OFF) if (OMATH_BUILD_AS_SHARED_LIBRARY) - add_library(omath SHARED source/Vector3.cpp) + add_library(omath SHARED source/Matrix.cpp) else() add_library(omath STATIC source/Matrix.cpp) endif() @@ -49,6 +50,10 @@ if(OMATH_BUILD_TESTS) add_subdirectory(tests) endif() +if (OMATH_BUILD_EXAMPLES) + add_subdirectory(examples) +endif() + if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC" AND OMATH_THREAT_WARNING_AS_ERROR) target_compile_options(omath PRIVATE /W4 /WX) elseif(OMATH_THREAT_WARNING_AS_ERROR) diff --git a/README.md b/README.md index c4d896ab..0058d791 100644 --- a/README.md +++ b/README.md @@ -12,14 +12,14 @@ Oranges's Math Library (omath) is a comprehensive, open-source library aimed at providing efficient, reliable, and versatile mathematical functions and algorithms. Developed primarily in C++, this library is designed to cater to a wide range of mathematical operations essential in scientific computing, engineering, and academic research. ## 👁‍🗨 Features -- **Efficiency**: Optimized for performance, ensuring quick computations. +- **Efficiency**: Optimized for performance, ensuring quick computations using AVX2. - **Versatility**: Includes a wide array of mathematical functions and algorithms. - **Ease of Use**: Simplified interface for convenient integration into various projects. - **Projectile Prediction**: Projectile prediction engine with O(N) algo complexity, that can power you projectile aim-bot. - **3D Projection**: No need to find view-projection matrix anymore you can make your own projection pipeline. - **Collision Detection**: Production ready code to handle collision detection by using simple interfaces. - **No Additional Dependencies**: No additional dependencies need to use OMath except unit test execution - +- **Ready for meta-programming**: Omath use templates for common types like Vectors, Matrixes etc, to handle all types! ## ⏬ Getting Started ### Prerequisites - C++ Compiler diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt new file mode 100644 index 00000000..11580f0e --- /dev/null +++ b/examples/CMakeLists.txt @@ -0,0 +1,4 @@ +project(examples) + +add_executable(ExampleProjectionMatrixBuilder ExampleProjMatBuilder.cpp) +target_link_libraries(ExampleProjectionMatrixBuilder PRIVATE omath::omath) \ No newline at end of file diff --git a/examples/ExampleProjMatBuilder.cpp b/examples/ExampleProjMatBuilder.cpp new file mode 100644 index 00000000..f06cc3c9 --- /dev/null +++ b/examples/ExampleProjMatBuilder.cpp @@ -0,0 +1,40 @@ +// +// Created by Vlad on 3/19/2025. +// +#include +#include +#include +#include +#include + + +int main() +{ + std::println("OMATH Projection Matrix Builder"); + + float fov = 0; + float near = 0; + float far = 0; + float viewPortWidth = 0; + float viewPortHeight = 0; + + std::print("Enter camera fov: "); + std::cin >> fov; + + std::print("Enter camera z near: "); + std::cin >> near; + + std::print("Enter camera z far: "); + std::cin >> far; + + std::print("Enter camera screen width: "); + std::cin >> viewPortWidth; + + std::print("Enter camera screen height: "); + std::cin >> viewPortHeight; + + const auto mat = + omath::opengl_engine::CalcPerspectiveProjectionMatrix(fov, viewPortWidth / viewPortHeight, near, far); + + std::print("{}", mat.ToString()); +}; diff --git a/include/omath/engines/iw_engine/Formulas.hpp b/include/omath/engines/iw_engine/Formulas.hpp index c98e7278..1249c983 100644 --- a/include/omath/engines/iw_engine/Formulas.hpp +++ b/include/omath/engines/iw_engine/Formulas.hpp @@ -8,49 +8,17 @@ 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)}; - } + Vector3 ForwardVector(const ViewAngles& angles); [[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)}; - } + Vector3 RightVector(const ViewAngles& angles); [[nodiscard]] - inline Vector3 UpVector(const ViewAngles& angles) - { - const auto vec = MatRotation(angles) * MatColumnFromVector(kAbsUp); + Vector3 UpVector(const ViewAngles& angles); - 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]] Mat4x4 CalcViewMatrix(const ViewAngles& angles, const Vector3& cam_origin); [[nodiscard]] - inline 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 - 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, 0, (far + near) / (far - near), -(2.f * far * near) / (far - near)}, - {0, 0, 1, 0}, - }; - } + Mat4x4 CalcPerspectiveProjectionMatrix(float fieldOfView, float aspectRatio, float near, float far); } // namespace omath::source diff --git a/include/omath/engines/opengl_engine/Formulas.hpp b/include/omath/engines/opengl_engine/Formulas.hpp index b63ffdcc..e0e97414 100644 --- a/include/omath/engines/opengl_engine/Formulas.hpp +++ b/include/omath/engines/opengl_engine/Formulas.hpp @@ -8,47 +8,17 @@ namespace omath::opengl_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)}; - } + Vector3 ForwardVector(const ViewAngles& angles); [[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)}; - } + Vector3 RightVector(const ViewAngles& angles); [[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)}; - } + Vector3 UpVector(const ViewAngles& angles); - [[nodiscard]] inline Mat4x4 CalcViewMatrix(const ViewAngles& angles, const Vector3& cam_origin) - { - return MatCameraView(-ForwardVector(angles), RightVector(angles), UpVector(angles), cam_origin); - } + [[nodiscard]] Mat4x4 CalcViewMatrix(const ViewAngles& angles, const Vector3& 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}, - - }; - } -} \ No newline at end of file + Mat4x4 CalcPerspectiveProjectionMatrix(float fieldOfView, float aspectRatio, float near, float far); +} // namespace omath::opengl_engine diff --git a/include/omath/engines/source_engine/Formulas.hpp b/include/omath/engines/source_engine/Formulas.hpp index 549d16a5..d47d2b62 100644 --- a/include/omath/engines/source_engine/Formulas.hpp +++ b/include/omath/engines/source_engine/Formulas.hpp @@ -7,50 +7,17 @@ namespace omath::source_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)}; - } + Vector3 ForwardVector(const ViewAngles& angles); [[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)}; - } + Vector3 RightVector(const ViewAngles& angles); [[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)}; - } + Vector3 UpVector(const ViewAngles& angles); - [[nodiscard]] inline Mat4x4 CalcViewMatrix(const ViewAngles& angles, const Vector3& cam_origin) - { - return MatCameraView(ForwardVector(angles), RightVector(angles), UpVector(angles), cam_origin); - } + [[nodiscard]] Mat4x4 CalcViewMatrix(const ViewAngles& angles, const Vector3& cam_origin); [[nodiscard]] - inline 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 - 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, 0, (far + near) / (far - near), -(2.f * far * near) / (far - near)}, - {0, 0, 1, 0}, - - }; - } + Mat4x4 CalcPerspectiveProjectionMatrix(float fieldOfView, float aspectRatio, float near, float far); } // namespace omath::source diff --git a/source/engines/iw_engine/CMakeLists.txt b/source/engines/iw_engine/CMakeLists.txt index 0abf8686..0153efab 100644 --- a/source/engines/iw_engine/CMakeLists.txt +++ b/source/engines/iw_engine/CMakeLists.txt @@ -1 +1 @@ -target_sources(omath PRIVATE Camera.cpp) \ No newline at end of file +target_sources(omath PRIVATE Camera.cpp Formulas.cpp) \ No newline at end of file diff --git a/source/engines/iw_engine/Formulas.cpp b/source/engines/iw_engine/Formulas.cpp new file mode 100644 index 00000000..0561b431 --- /dev/null +++ b/source/engines/iw_engine/Formulas.cpp @@ -0,0 +1,47 @@ +// +// Created by Vlad on 3/19/2025. +// +#include "omath/engines/iw_engine/Formulas.hpp" + + +namespace omath::iw_engine +{ + + 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)}; + } + + 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)}; + } + 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)}; + } + Mat4x4 CalcViewMatrix(const ViewAngles& angles, const Vector3& 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 + 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, 0, (far + near) / (far - near), -(2.f * far * near) / (far - near)}, + {0, 0, 1, 0}, + }; + } +} // namespace omath::iw_engine diff --git a/source/engines/opengl_engine/CMakeLists.txt b/source/engines/opengl_engine/CMakeLists.txt index 0abf8686..0153efab 100644 --- a/source/engines/opengl_engine/CMakeLists.txt +++ b/source/engines/opengl_engine/CMakeLists.txt @@ -1 +1 @@ -target_sources(omath PRIVATE Camera.cpp) \ No newline at end of file +target_sources(omath PRIVATE Camera.cpp Formulas.cpp) \ No newline at end of file diff --git a/source/engines/opengl_engine/Formulas.cpp b/source/engines/opengl_engine/Formulas.cpp new file mode 100644 index 00000000..c2fa6984 --- /dev/null +++ b/source/engines/opengl_engine/Formulas.cpp @@ -0,0 +1,46 @@ +// +// Created by Vlad on 3/19/2025. +// +#include "omath/engines/opengl_engine/Formulas.hpp" + + +namespace omath::opengl_engine +{ + + 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)}; + } + 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)}; + } + 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)}; + } + Mat4x4 CalcViewMatrix(const ViewAngles& angles, const Vector3& 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) + { + 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::opengl_engine diff --git a/source/engines/source_engine/CMakeLists.txt b/source/engines/source_engine/CMakeLists.txt index 0abf8686..0153efab 100644 --- a/source/engines/source_engine/CMakeLists.txt +++ b/source/engines/source_engine/CMakeLists.txt @@ -1 +1 @@ -target_sources(omath PRIVATE Camera.cpp) \ No newline at end of file +target_sources(omath PRIVATE Camera.cpp Formulas.cpp) \ No newline at end of file diff --git a/source/engines/source_engine/Formulas.cpp b/source/engines/source_engine/Formulas.cpp new file mode 100644 index 00000000..1bbb90a4 --- /dev/null +++ b/source/engines/source_engine/Formulas.cpp @@ -0,0 +1,49 @@ +// +// Created by Vlad on 3/19/2025. +// +#include + + +namespace omath::source_engine +{ + 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)}; + } + + 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)}; + } + 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)}; + } + + Mat4x4 CalcViewMatrix(const ViewAngles& angles, const Vector3& 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 + 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, 0, (far + near) / (far - near), -(2.f * far * near) / (far - near)}, + {0, 0, 1, 0}, + + }; + } +} // namespace omath::source_engine