From a25aef049e62c56b03fd55bdcad07cd0e29bd32b Mon Sep 17 00:00:00 2001 From: Orange Date: Sun, 24 Nov 2024 20:37:15 +0300 Subject: [PATCH 01/24] improved code quality --- include/omath/Mat.hpp | 40 +++++++++++++++++++++------------ source/collision/LineTracer.cpp | 1 - 2 files changed, 26 insertions(+), 15 deletions(-) diff --git a/include/omath/Mat.hpp b/include/omath/Mat.hpp index 18907fa..1e717ab 100644 --- a/include/omath/Mat.hpp +++ b/include/omath/Mat.hpp @@ -70,13 +70,13 @@ namespace omath } [[nodiscard]] - static consteval size_t RowCount() noexcept + static constexpr size_t RowCount() noexcept { return Rows; } [[nodiscard]] - static consteval size_t ColumnsCount() noexcept + static constexpr size_t ColumnsCount() noexcept { return Columns; } @@ -133,9 +133,9 @@ namespace omath // Operator overloading for multiplication with another Mat template - constexpr Mat operator*(const Mat &other) const + constexpr Mat operator*(const Mat &other) const { - Mat result; + Mat result; for (size_t i = 0; i < Rows; ++i) for (size_t j = 0; j < OtherColumns; ++j) @@ -157,7 +157,7 @@ namespace omath } template - constexpr Mat operator*=(const Mat &other) + constexpr Mat operator*=(const Mat &other) { return *this = *this * other; } @@ -207,9 +207,9 @@ namespace omath } [[nodiscard]] - constexpr Mat Transposed() const noexcept + constexpr Mat Transposed() const noexcept { - Mat transposed; + Mat transposed; for (size_t i = 0; i < Rows; ++i) for (size_t j = 0; j < Columns; ++j) transposed.At(j, i) = At(i, j); @@ -240,9 +240,9 @@ namespace omath } [[nodiscard]] - constexpr Mat Minor(const size_t row, const size_t column) const + constexpr Mat Minor(const size_t row, const size_t column) const { - Mat result; + Mat result; for (size_t i = 0, m = 0; i < Rows; ++i) { if (i == row) @@ -288,6 +288,18 @@ namespace omath return oss.str(); } + [[nodiscard]] + bool operator==(const Mat & mat) const + { + return m_data == mat.m_data; + } + + [[nodiscard]] + bool operator!=(const Mat & mat) const + { + return !operator==(mat); + } + // Static methods that return fixed-size matrices [[nodiscard]] constexpr static Mat<4, 4> ToScreenMat(const Type &screenWidth, const Type &screenHeight) noexcept @@ -322,7 +334,7 @@ namespace omath {right.x, up.x, forward.x, 0}, {right.y, up.y, forward.y, 0}, {right.z, up.z, forward.z, 0}, - {0, 0, 0, 1}, + {0, 0, 0, 1}, }; } @@ -354,10 +366,10 @@ namespace omath return { { - {vector.x}, - {vector.y}, - {vector.z}, - {1} + vector.x, + vector.y, + vector.z, + 1 } }; } diff --git a/source/collision/LineTracer.cpp b/source/collision/LineTracer.cpp index 905350b..83bcdd2 100644 --- a/source/collision/LineTracer.cpp +++ b/source/collision/LineTracer.cpp @@ -1,7 +1,6 @@ // // Created by Orange on 11/13/2024. // -#pragma once #include "omath/collision/LineTracer.hpp" namespace omath::collision From 6e5f2331adbe05054a7a01ddacfecb5ac9d8cb89 Mon Sep 17 00:00:00 2001 From: Orange Date: Wed, 27 Nov 2024 15:21:07 +0300 Subject: [PATCH 02/24] added files --- .gitmodules | 3 ++ .idea/vcs.xml | 1 + CMakeLists.txt | 6 ++-- CMakePresets.json | 4 +-- extlibs/CMakeLists.txt | 3 +- extlibs/glm | 1 + include/omath/engines/opengl.hpp | 35 +++++++++++++++++++++++ include/omath/engines/source.hpp | 28 +++++++++++++++++++ tests/CMakeLists.txt | 3 +- tests/UnitTestOpenGL.cpp | 48 ++++++++++++++++++++++++++++++++ 10 files changed, 125 insertions(+), 7 deletions(-) create mode 160000 extlibs/glm create mode 100644 include/omath/engines/opengl.hpp create mode 100644 include/omath/engines/source.hpp create mode 100644 tests/UnitTestOpenGL.cpp diff --git a/.gitmodules b/.gitmodules index c16587c..b6c1697 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,6 @@ [submodule "extlibs/googletest"] path = extlibs/googletest url = https://github.com/google/googletest.git +[submodule "extlibs/glm"] + path = extlibs/glm + url = https://github.com/g-truc/glm.git diff --git a/.idea/vcs.xml b/.idea/vcs.xml index adc159a..edda590 100644 --- a/.idea/vcs.xml +++ b/.idea/vcs.xml @@ -2,6 +2,7 @@ + \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 72ca0fb..b2d004b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -23,10 +23,10 @@ if(OMATH_BUILD_TESTS) add_subdirectory(tests) endif() -if (WIN32 AND OMATH_THREAT_WARNING_AS_ERROR) +if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC" AND OMATH_THREAT_WARNING_AS_ERROR) target_compile_options(omath PRIVATE /W4 /WX) -elseif(UNIX AND OMATH_THREAT_WARNING_AS_ERROR) - target_compile_options(omath PRIVATE -Wall -Wextra -Wpedantic) +elseif(OMATH_THREAT_WARNING_AS_ERROR) + target_compile_options(omath PRIVATE -Wall -Wextra -Wpedantic -Werror) endif() target_include_directories(omath diff --git a/CMakePresets.json b/CMakePresets.json index d67436b..74671b4 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -8,8 +8,8 @@ "binaryDir": "${sourceDir}/cmake-build/build/${presetName}", "installDir": "${sourceDir}/cmake-build/install/${presetName}", "cacheVariables": { - "CMAKE_C_COMPILER": "cl.exe", - "CMAKE_CXX_COMPILER": "cl.exe" + "CMAKE_C_COMPILER": "clang.exe", + "CMAKE_CXX_COMPILER": "clang++.exe" }, "condition": { "type": "equals", diff --git a/extlibs/CMakeLists.txt b/extlibs/CMakeLists.txt index bf73c7a..caca17c 100644 --- a/extlibs/CMakeLists.txt +++ b/extlibs/CMakeLists.txt @@ -1 +1,2 @@ -add_subdirectory(googletest) \ No newline at end of file +add_subdirectory(googletest) +add_subdirectory(glm) \ No newline at end of file diff --git a/extlibs/glm b/extlibs/glm new file mode 160000 index 0000000..33b4a62 --- /dev/null +++ b/extlibs/glm @@ -0,0 +1 @@ +Subproject commit 33b4a621a697a305bc3a7610d290677b96beb181 diff --git a/include/omath/engines/opengl.hpp b/include/omath/engines/opengl.hpp new file mode 100644 index 0000000..6b70756 --- /dev/null +++ b/include/omath/engines/opengl.hpp @@ -0,0 +1,35 @@ +// +// Created by Orange on 11/23/2024. +// +#pragma once +#include "omath/Vector3.hpp" +#include "omath/Mat.hpp" + + +namespace omath::opengl +{ + constexpr Vector3 kAbsUp = {0, 1, 0}; + constexpr Vector3 kAbsRight = {1, 0, 0}; + constexpr Vector3 kAbsForward = {0, 0, -1}; + + template requires std::is_floating_point_v || std::is_integral_v + [[nodiscard]] Mat<4, 4, Type, MatStoreType::COLUMN_MAJOR> PerspectiveProjectionMatrix() + { + + } + + template requires std::is_floating_point_v || std::is_integral_v + [[nodiscard]] Mat<4, 4, Type, MatStoreType::COLUMN_MAJOR> PerspectiveProjectionMatrix( + const float fieldOfView, const Type &aspectRatio, const Type &near, const Type &far) + { + const float fovHalfTan = std::tan(angles::DegreesToRadians(fieldOfView) / 2); + + return + { + {static_cast(1) / (aspectRatio * fovHalfTan), 0, 0, 0}, + {0, static_cast(1) / (fovHalfTan), 0, 0}, + {0, 0, -(far + near) / (far - near), -(static_cast(2) * far * near) / (far - near)}, + {0, 0, -1, 0}, + }; + } +} diff --git a/include/omath/engines/source.hpp b/include/omath/engines/source.hpp new file mode 100644 index 0000000..24308fc --- /dev/null +++ b/include/omath/engines/source.hpp @@ -0,0 +1,28 @@ +// +// Created by Orange on 11/24/2024. +// +#pragma once + + +namespace omath::source +{ + constexpr Vector3 kAbsUp = {0, 0, 1}; + constexpr Vector3 kAbsRight = {0, -1, 0}; + constexpr Vector3 kAbsForward = {1, 0, 0}; + + + template requires std::is_floating_point_v || std::is_integral_v + [[nodiscard]] Mat<4, 4, Type, MatStoreType::COLUMN_MAJOR> PerspectiveProjectionMatrix( + const float fieldOfView, const Type &aspectRatio, const Type &near, const Type &far) + { + const float fovHalfTan = std::tan(angles::DegreesToRadians(fieldOfView) / 2); + + return + { + {static_cast(1) / (aspectRatio * fovHalfTan), 0, 0, 0}, + {0, static_cast(1) / (fovHalfTan), 0, 0}, + {0, 0, (far + near) / (far - near), -(static_cast(2) * far * near) / (far - near)}, + {0, 0, 1, 0}, + }; + } +} diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 1c604c1..3b9b056 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -15,8 +15,9 @@ add_executable(unit-tests UnitTestColor.cpp UnitTestVector4.cpp UnitTestLineTrace.cpp + UnitTestOpenGL.cpp ) -target_link_libraries(unit-tests PRIVATE gtest gtest_main omath) +target_link_libraries(unit-tests PRIVATE gtest gtest_main omath glm) gtest_discover_tests(unit-tests) \ No newline at end of file diff --git a/tests/UnitTestOpenGL.cpp b/tests/UnitTestOpenGL.cpp new file mode 100644 index 0000000..e4f1561 --- /dev/null +++ b/tests/UnitTestOpenGL.cpp @@ -0,0 +1,48 @@ +// +// Created by Orange on 11/23/2024. +// +#include +#include +#include +#include +#include +#include +#include + +#include "glm/ext/matrix_clip_space.hpp" +#include "glm/ext/matrix_transform.hpp" + + +TEST(UnitTestOpenGL, Projection) +{ + + const auto proj_glm = glm::perspective(glm::radians(90.f), 16.f / 9.f, 0.1f, 1000.f); + const auto proj_glm2 = glm::perspectiveLH_NO(glm::radians(90.f), 16.f / 9.f, 0.1f, 1000.f); + // const auto proj_omath = omath::Mat<4, 4, float, omath::MatStoreType::COLUMN_MAJOR>((const float*)&proj_glm); + // EXPECT_EQ(omath::opengl::PerspectiveProjectionMatrix(90, 16.f / 9.f, 0.1f, 1000.f), proj_omath); + + + glm::vec4 ndc_glm2 = proj_glm * glm::vec4(300.f, 0.f, -1000.f, 1.f); + ndc_glm2 /= ndc_glm2.w; + const omath::Mat<4, 1, float, omath::MatStoreType::COLUMN_MAJOR> cords_omath = + { + {0}, + {0}, + {-0.2f}, + {1} + }; + + //auto ndc_omath = proj_omath * cords_omath; + // ndc_omath /= ndc_omath.At(3, 0); + +} +TEST(UnitTestOpenGL, Projection2) +{ + const auto orient = omath::Mat<>::OrientationMat(omath::opengl::kAbsForward, omath::opengl::kAbsRight, omath::opengl::kAbsUp); + + const omath::Mat<4, 1> cords_omath = + { + {0}, {0}, {10}, {1} + }; + std::cout << (orient.Transposed() * cords_omath).ToString(); +} \ No newline at end of file From 480d11dbc0c3405e54cf7e97ff7c5b7ed6c9a355 Mon Sep 17 00:00:00 2001 From: Orange Date: Wed, 27 Nov 2024 15:35:30 +0300 Subject: [PATCH 03/24] added clang tidy --- .clang-tidy | 147 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 147 insertions(+) create mode 100644 .clang-tidy diff --git a/.clang-tidy b/.clang-tidy new file mode 100644 index 0000000..fd8c681 --- /dev/null +++ b/.clang-tidy @@ -0,0 +1,147 @@ +# Generated from CLion Inspection settings +--- +Checks: '-*, +bugprone-argument-comment, +bugprone-assert-side-effect, +bugprone-bad-signal-to-kill-thread, +bugprone-branch-clone, +bugprone-copy-constructor-init, +bugprone-dangling-handle, +bugprone-dynamic-static-initializers, +bugprone-fold-init-type, +bugprone-forward-declaration-namespace, +bugprone-forwarding-reference-overload, +bugprone-inaccurate-erase, +bugprone-incorrect-roundings, +bugprone-integer-division, +bugprone-lambda-function-name, +bugprone-macro-parentheses, +bugprone-macro-repeated-side-effects, +bugprone-misplaced-operator-in-strlen-in-alloc, +bugprone-misplaced-pointer-arithmetic-in-alloc, +bugprone-misplaced-widening-cast, +bugprone-move-forwarding-reference, +bugprone-multiple-statement-macro, +bugprone-no-escape, +bugprone-parent-virtual-call, +bugprone-posix-return, +bugprone-reserved-identifier, +bugprone-sizeof-container, +bugprone-sizeof-expression, +bugprone-spuriously-wake-up-functions, +bugprone-string-constructor, +bugprone-string-integer-assignment, +bugprone-string-literal-with-embedded-nul, +bugprone-suspicious-enum-usage, +bugprone-suspicious-include, +bugprone-suspicious-memset-usage, +bugprone-suspicious-missing-comma, +bugprone-suspicious-semicolon, +bugprone-suspicious-string-compare, +bugprone-suspicious-memory-comparison, +bugprone-suspicious-realloc-usage, +bugprone-swapped-arguments, +bugprone-terminating-continue, +bugprone-throw-keyword-missing, +bugprone-too-small-loop-variable, +bugprone-undefined-memory-manipulation, +bugprone-undelegated-constructor, +bugprone-unhandled-self-assignment, +bugprone-unused-raii, +bugprone-unused-return-value, +bugprone-use-after-move, +bugprone-virtual-near-miss, +cert-dcl21-cpp, +cert-dcl58-cpp, +cert-err34-c, +cert-err52-cpp, +cert-err60-cpp, +cert-flp30-c, +cert-msc50-cpp, +cert-msc51-cpp, +cert-str34-c, +cppcoreguidelines-interfaces-global-init, +cppcoreguidelines-narrowing-conversions, +cppcoreguidelines-pro-type-member-init, +cppcoreguidelines-pro-type-static-cast-downcast, +cppcoreguidelines-slicing, +google-default-arguments, +google-explicit-constructor, +google-runtime-operator, +hicpp-exception-baseclass, +hicpp-multiway-paths-covered, +misc-misplaced-const, +misc-new-delete-overloads, +misc-no-recursion, +misc-non-copyable-objects, +misc-throw-by-value-catch-by-reference, +misc-unconventional-assign-operator, +misc-uniqueptr-reset-release, +modernize-avoid-bind, +modernize-concat-nested-namespaces, +modernize-deprecated-headers, +modernize-deprecated-ios-base-aliases, +modernize-loop-convert, +modernize-make-shared, +modernize-make-unique, +modernize-pass-by-value, +modernize-raw-string-literal, +modernize-redundant-void-arg, +modernize-replace-auto-ptr, +modernize-replace-disallow-copy-and-assign-macro, +modernize-replace-random-shuffle, +modernize-return-braced-init-list, +modernize-shrink-to-fit, +modernize-unary-static-assert, +modernize-use-auto, +modernize-use-bool-literals, +modernize-use-emplace, +modernize-use-equals-default, +modernize-use-equals-delete, +modernize-use-nodiscard, +modernize-use-noexcept, +modernize-use-nullptr, +modernize-use-override, +modernize-use-transparent-functors, +modernize-use-uncaught-exceptions, +mpi-buffer-deref, +mpi-type-mismatch, +openmp-use-default-none, +performance-faster-string-find, +performance-for-range-copy, +performance-implicit-conversion-in-loop, +performance-inefficient-algorithm, +performance-inefficient-string-concatenation, +performance-inefficient-vector-operation, +performance-move-const-arg, +performance-move-constructor-init, +performance-no-automatic-move, +performance-noexcept-move-constructor, +performance-trivially-destructible, +performance-type-promotion-in-math-fn, +performance-unnecessary-copy-initialization, +performance-unnecessary-value-param, +portability-simd-intrinsics, +readability-avoid-const-params-in-decls, +readability-const-return-type, +readability-container-size-empty, +readability-convert-member-functions-to-static, +readability-delete-null-pointer, +readability-deleted-default, +readability-inconsistent-declaration-parameter-name, +readability-make-member-function-const, +readability-misleading-indentation, +readability-misplaced-array-index, +readability-non-const-parameter, +readability-redundant-control-flow, +readability-redundant-declaration, +readability-redundant-function-ptr-dereference, +readability-redundant-smartptr-get, +readability-redundant-string-cstr, +readability-redundant-string-init, +readability-simplify-subscript-expr, +readability-static-accessed-through-instance, +readability-static-definition-in-anonymous-namespace, +readability-string-compare, +readability-uniqueptr-delete-release, +readability-use-anyofallof' \ No newline at end of file From 6a9a51b39c61c27e98586cc2e8ec2f6c5d3745eb Mon Sep 17 00:00:00 2001 From: Orange Date: Wed, 27 Nov 2024 19:36:28 +0300 Subject: [PATCH 04/24] refactored tests --- include/omath/engines/opengl.hpp | 22 ++++++++++++++----- include/omath/engines/source.hpp | 3 ++- include/omath/engines/unity.hpp | 12 +++++++++++ include/omath/projection/Camera.hpp | 1 - source/projection/Camera.cpp | 4 ---- tests/CMakeLists.txt | 25 ++++++++++++---------- tests/{ => engines}/UnitTestOpenGL.cpp | 8 +++---- tests/engines/UnitTestSourceEngine.cpp | 3 +++ tests/engines/UnitTestUnityEngine.cpp | 3 +++ tests/{ => general}/UnitTestAstar.cpp | 0 tests/{ => general}/UnitTestColor.cpp | 0 tests/{ => general}/UnitTestLineTrace.cpp | 0 tests/{ => general}/UnitTestMat.cpp | 0 tests/{ => general}/UnitTestMatrix.cpp | 0 tests/{ => general}/UnitTestPrediction.cpp | 0 tests/{ => general}/UnitTestProjection.cpp | 0 tests/{ => general}/UnitTestVector2.cpp | 0 tests/{ => general}/UnitTestVector3.cpp | 0 tests/{ => general}/UnitTestVector4.cpp | 0 19 files changed, 55 insertions(+), 26 deletions(-) create mode 100644 include/omath/engines/unity.hpp rename tests/{ => engines}/UnitTestOpenGL.cpp (79%) create mode 100644 tests/engines/UnitTestSourceEngine.cpp create mode 100644 tests/engines/UnitTestUnityEngine.cpp rename tests/{ => general}/UnitTestAstar.cpp (100%) rename tests/{ => general}/UnitTestColor.cpp (100%) rename tests/{ => general}/UnitTestLineTrace.cpp (100%) rename tests/{ => general}/UnitTestMat.cpp (100%) rename tests/{ => general}/UnitTestMatrix.cpp (100%) rename tests/{ => general}/UnitTestPrediction.cpp (100%) rename tests/{ => general}/UnitTestProjection.cpp (100%) rename tests/{ => general}/UnitTestVector2.cpp (100%) rename tests/{ => general}/UnitTestVector3.cpp (100%) rename tests/{ => general}/UnitTestVector4.cpp (100%) diff --git a/include/omath/engines/opengl.hpp b/include/omath/engines/opengl.hpp index 6b70756..6bed17e 100644 --- a/include/omath/engines/opengl.hpp +++ b/include/omath/engines/opengl.hpp @@ -12,15 +12,27 @@ namespace omath::opengl constexpr Vector3 kAbsRight = {1, 0, 0}; constexpr Vector3 kAbsForward = {0, 0, -1}; - template requires std::is_floating_point_v || std::is_integral_v - [[nodiscard]] Mat<4, 4, Type, MatStoreType::COLUMN_MAJOR> PerspectiveProjectionMatrix() - { + template + requires std::is_floating_point_v || std::is_integral_v + [[nodiscard]] Mat<4, 4, Type, MatStoreType::COLUMN_MAJOR> ViewMatrix(const Vector3& forward, + const Vector3& right, + const Vector3& up, + const Vector3& cam_origin) + { + return + { + {right.x, up.x, -forward.x, 0}, + {right.y, up.y, -forward.y, 0}, + {right.z, up.z, -forward.z, 0}, + {-cam_origin.x, -cam_origin.y, -cam_origin.z, 1}, + }; } - template requires std::is_floating_point_v || std::is_integral_v + template + requires std::is_floating_point_v || std::is_integral_v [[nodiscard]] Mat<4, 4, Type, MatStoreType::COLUMN_MAJOR> PerspectiveProjectionMatrix( - const float fieldOfView, const Type &aspectRatio, const Type &near, const Type &far) + const float fieldOfView, const Type& aspectRatio, const Type& near, const Type& far) { const float fovHalfTan = std::tan(angles::DegreesToRadians(fieldOfView) / 2); diff --git a/include/omath/engines/source.hpp b/include/omath/engines/source.hpp index 24308fc..32c248a 100644 --- a/include/omath/engines/source.hpp +++ b/include/omath/engines/source.hpp @@ -2,7 +2,8 @@ // Created by Orange on 11/24/2024. // #pragma once - +#include "omath/Vector3.hpp" +#include "omath/Mat.hpp" namespace omath::source { diff --git a/include/omath/engines/unity.hpp b/include/omath/engines/unity.hpp new file mode 100644 index 0000000..ff43bb2 --- /dev/null +++ b/include/omath/engines/unity.hpp @@ -0,0 +1,12 @@ +// +// Created by Orange on 11/27/2024. +// + +#pragma once +#include + + +namespace omath::unity +{ + +}; diff --git a/include/omath/projection/Camera.hpp b/include/omath/projection/Camera.hpp index d2d450e..ac5a241 100644 --- a/include/omath/projection/Camera.hpp +++ b/include/omath/projection/Camera.hpp @@ -7,7 +7,6 @@ #include #include #include -#include #include "ErrorCodes.hpp" diff --git a/source/projection/Camera.cpp b/source/projection/Camera.cpp index c26f75a..af9782b 100644 --- a/source/projection/Camera.cpp +++ b/source/projection/Camera.cpp @@ -3,10 +3,6 @@ // #include "omath/projection/Camera.hpp" -#include - -#include "omath/Angles.hpp" - namespace omath::projection { diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 3b9b056..6d8d48e 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -5,17 +5,20 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/out/${CMAKE_BUILD_TYPE}" include(GoogleTest) add_executable(unit-tests - UnitTestPrediction.cpp - UnitTestMatrix.cpp - UnitTestMat.cpp - UnitTestAstar.cpp - UnitTestProjection.cpp - UnitTestVector3.cpp - UnitTestVector2.cpp - UnitTestColor.cpp - UnitTestVector4.cpp - UnitTestLineTrace.cpp - UnitTestOpenGL.cpp + general/UnitTestPrediction.cpp + general/UnitTestMatrix.cpp + general/UnitTestMat.cpp + general/UnitTestAstar.cpp + general/UnitTestProjection.cpp + general/UnitTestVector3.cpp + general/UnitTestVector2.cpp + general/UnitTestColor.cpp + general/UnitTestVector4.cpp + general/UnitTestLineTrace.cpp + + engines/UnitTestOpenGL.cpp + engines/UnitTestUnityEngine.cpp + engines/UnitTestSourceEngine.cpp ) target_link_libraries(unit-tests PRIVATE gtest gtest_main omath glm) diff --git a/tests/UnitTestOpenGL.cpp b/tests/engines/UnitTestOpenGL.cpp similarity index 79% rename from tests/UnitTestOpenGL.cpp rename to tests/engines/UnitTestOpenGL.cpp index e4f1561..0c44e4a 100644 --- a/tests/UnitTestOpenGL.cpp +++ b/tests/engines/UnitTestOpenGL.cpp @@ -38,11 +38,11 @@ TEST(UnitTestOpenGL, Projection) } TEST(UnitTestOpenGL, Projection2) { - const auto orient = omath::Mat<>::OrientationMat(omath::opengl::kAbsForward, omath::opengl::kAbsRight, omath::opengl::kAbsUp); + const auto orient = omath::opengl::ViewMatrix(omath::opengl::kAbsForward, -omath::opengl::kAbsRight, omath::opengl::kAbsUp, {}); - const omath::Mat<4, 1> cords_omath = + const omath::Mat<4, 1,float, omath::MatStoreType::COLUMN_MAJOR> cords_omath = { - {0}, {0}, {10}, {1} + {0}, {0}, {-10}, {1} }; - std::cout << (orient.Transposed() * cords_omath).ToString(); + std::cout << (orient * cords_omath).ToString(); } \ No newline at end of file diff --git a/tests/engines/UnitTestSourceEngine.cpp b/tests/engines/UnitTestSourceEngine.cpp new file mode 100644 index 0000000..4f6b72b --- /dev/null +++ b/tests/engines/UnitTestSourceEngine.cpp @@ -0,0 +1,3 @@ +// +// Created by Orange on 11/27/2024. +// diff --git a/tests/engines/UnitTestUnityEngine.cpp b/tests/engines/UnitTestUnityEngine.cpp new file mode 100644 index 0000000..4f6b72b --- /dev/null +++ b/tests/engines/UnitTestUnityEngine.cpp @@ -0,0 +1,3 @@ +// +// Created by Orange on 11/27/2024. +// diff --git a/tests/UnitTestAstar.cpp b/tests/general/UnitTestAstar.cpp similarity index 100% rename from tests/UnitTestAstar.cpp rename to tests/general/UnitTestAstar.cpp diff --git a/tests/UnitTestColor.cpp b/tests/general/UnitTestColor.cpp similarity index 100% rename from tests/UnitTestColor.cpp rename to tests/general/UnitTestColor.cpp diff --git a/tests/UnitTestLineTrace.cpp b/tests/general/UnitTestLineTrace.cpp similarity index 100% rename from tests/UnitTestLineTrace.cpp rename to tests/general/UnitTestLineTrace.cpp diff --git a/tests/UnitTestMat.cpp b/tests/general/UnitTestMat.cpp similarity index 100% rename from tests/UnitTestMat.cpp rename to tests/general/UnitTestMat.cpp diff --git a/tests/UnitTestMatrix.cpp b/tests/general/UnitTestMatrix.cpp similarity index 100% rename from tests/UnitTestMatrix.cpp rename to tests/general/UnitTestMatrix.cpp diff --git a/tests/UnitTestPrediction.cpp b/tests/general/UnitTestPrediction.cpp similarity index 100% rename from tests/UnitTestPrediction.cpp rename to tests/general/UnitTestPrediction.cpp diff --git a/tests/UnitTestProjection.cpp b/tests/general/UnitTestProjection.cpp similarity index 100% rename from tests/UnitTestProjection.cpp rename to tests/general/UnitTestProjection.cpp diff --git a/tests/UnitTestVector2.cpp b/tests/general/UnitTestVector2.cpp similarity index 100% rename from tests/UnitTestVector2.cpp rename to tests/general/UnitTestVector2.cpp diff --git a/tests/UnitTestVector3.cpp b/tests/general/UnitTestVector3.cpp similarity index 100% rename from tests/UnitTestVector3.cpp rename to tests/general/UnitTestVector3.cpp diff --git a/tests/UnitTestVector4.cpp b/tests/general/UnitTestVector4.cpp similarity index 100% rename from tests/UnitTestVector4.cpp rename to tests/general/UnitTestVector4.cpp From a33ee638b9715d606594ebbce93402a223bfac06 Mon Sep 17 00:00:00 2001 From: Orange Date: Sat, 30 Nov 2024 03:37:25 +0300 Subject: [PATCH 05/24] added more unit tests --- include/omath/Angles.hpp | 35 +++++++++++++++--- include/omath/collision/LineTracer.hpp | 1 + include/omath/engines/opengl.hpp | 8 ++--- include/omath/pathfinding/NavigationMesh.hpp | 6 ++++ tests/CMakeLists.txt | 2 ++ tests/engines/UnitTestOpenGL.cpp | 4 +-- tests/general/UnitTestAngles.cpp | 38 ++++++++++++++++++++ 7 files changed, 84 insertions(+), 10 deletions(-) create mode 100644 tests/general/UnitTestAngles.cpp diff --git a/include/omath/Angles.hpp b/include/omath/Angles.hpp index 9e557fd..0dc6d61 100644 --- a/include/omath/Angles.hpp +++ b/include/omath/Angles.hpp @@ -7,12 +7,39 @@ namespace omath::angles { - [[nodiscard]] constexpr float RadiansToDegrees(const float radiands) + template + requires std::is_floating_point_v + [[nodiscard]] constexpr float RadiansToDegrees(const type& radians) { - return radiands * (180.f / std::numbers::pi_v); + return radians * (type(180) / std::numbers::pi_v); } - [[nodiscard]] constexpr float DegreesToRadians(const float degrees) + + template + requires std::is_floating_point_v + [[nodiscard]] constexpr float DegreesToRadians(const type& degrees) { - return degrees * (std::numbers::pi_v / 180.f); + return degrees * (std::numbers::pi_v / type(180)); + } + + template + requires std::is_floating_point_v + [[nodiscard]] type HorizontalFovToVertical(const type& horFov, const type& aspect) + { + const auto fovRad = DegreesToRadians(horFov); + + const auto vertFov = type(2) * std::atan(std::tan(fovRad / type(2)) / aspect); + + return RadiansToDegrees(vertFov); + } + + template + requires std::is_floating_point_v + [[nodiscard]] type VerticalFovToHorizontal(const type& vertFov, const type& aspect) + { + const auto fovRad = DegreesToRadians(vertFov); + + const auto horFov = type(2) * std::atan(std::tan(fovRad / type(2)) * aspect); + + return RadiansToDegrees(horFov); } } diff --git a/include/omath/collision/LineTracer.hpp b/include/omath/collision/LineTracer.hpp index 1de6d1e..fc1d7fa 100644 --- a/include/omath/collision/LineTracer.hpp +++ b/include/omath/collision/LineTracer.hpp @@ -26,6 +26,7 @@ namespace omath::collision public: LineTracer() = delete; + [[nodiscard]] static bool CanTraceLine(const Ray& ray, const Triangle3d& triangle); diff --git a/include/omath/engines/opengl.hpp b/include/omath/engines/opengl.hpp index 6bed17e..bcda994 100644 --- a/include/omath/engines/opengl.hpp +++ b/include/omath/engines/opengl.hpp @@ -22,10 +22,10 @@ namespace omath::opengl { return { - {right.x, up.x, -forward.x, 0}, - {right.y, up.y, -forward.y, 0}, - {right.z, up.z, -forward.z, 0}, - {-cam_origin.x, -cam_origin.y, -cam_origin.z, 1}, + {right.x, up.x, -forward.x, 0}, + {right.y, up.y, -forward.y, 0}, + {right.z, up.z, -forward.z, 0}, + {-cam_origin.x, -cam_origin.y, -cam_origin.z, 1}, }; } diff --git a/include/omath/pathfinding/NavigationMesh.hpp b/include/omath/pathfinding/NavigationMesh.hpp index e7aceb4..525cbc4 100644 --- a/include/omath/pathfinding/NavigationMesh.hpp +++ b/include/omath/pathfinding/NavigationMesh.hpp @@ -12,6 +12,12 @@ namespace omath::pathfinding { + + enum Error + { + + }; + class NavigationMesh final { public: diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 6d8d48e..109cdc7 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -15,10 +15,12 @@ add_executable(unit-tests general/UnitTestColor.cpp general/UnitTestVector4.cpp general/UnitTestLineTrace.cpp + general/UnitTestAngles.cpp engines/UnitTestOpenGL.cpp engines/UnitTestUnityEngine.cpp engines/UnitTestSourceEngine.cpp + ) target_link_libraries(unit-tests PRIVATE gtest gtest_main omath glm) diff --git a/tests/engines/UnitTestOpenGL.cpp b/tests/engines/UnitTestOpenGL.cpp index 0c44e4a..2cb6889 100644 --- a/tests/engines/UnitTestOpenGL.cpp +++ b/tests/engines/UnitTestOpenGL.cpp @@ -5,8 +5,8 @@ #include #include #include -#include -#include +#include +#include #include #include "glm/ext/matrix_clip_space.hpp" diff --git a/tests/general/UnitTestAngles.cpp b/tests/general/UnitTestAngles.cpp new file mode 100644 index 0000000..324ce4d --- /dev/null +++ b/tests/general/UnitTestAngles.cpp @@ -0,0 +1,38 @@ +// +// Created by Orange on 11/30/2024. +// +#include +#include + + +TEST(UnitTestAngles, RadiansToDeg) +{ + constexpr float rad = 67; + + EXPECT_NEAR(omath::angles::RadiansToDegrees(rad), 3838.82f, 0.01f); +} + +TEST(UnitTestAngles, DegreesToRadians) +{ + constexpr float degree = 90; + + EXPECT_NEAR(omath::angles::DegreesToRadians(degree), 1.5708f, 0.01f); +} + +TEST(UnitTestAngles, HorizontalFovToVerical) +{ + constexpr float hFov = 90; + constexpr float aspectRation = 16.0f / 9.0f; + const auto verticalFov = omath::angles::HorizontalFovToVertical(hFov, aspectRation); + + EXPECT_NEAR(verticalFov, 58.71f, 0.01f); +} + +TEST(UnitTestAngles, VerticalToHorizontal) +{ + constexpr float vFov = 58.71; + constexpr float aspectRation = 16.0f / 9.0f; + const auto horizontalFov = omath::angles::VerticalFovToHorizontal(vFov, aspectRation); + + EXPECT_NEAR(horizontalFov, 89.99f, 0.01f); +} \ No newline at end of file From 1fe5e6e276b88a689c91ae276d601b0cbe8132d7 Mon Sep 17 00:00:00 2001 From: Orange Date: Sat, 30 Nov 2024 13:54:06 +0300 Subject: [PATCH 06/24] added new class --- SECURITY.md | 2 +- include/omath/Angle.hpp | 156 +++++++++++++++++++++++++++ include/omath/Angles.hpp | 43 +++++--- include/omath/Mat.hpp | 66 ++++++------ include/omath/Triangle3d.hpp | 3 +- include/omath/ViewAngles.hpp | 35 ++++++ include/omath/engines/source.hpp | 3 + tests/CMakeLists.txt | 1 + tests/general/UnitTestAngles.cpp | 14 ++- tests/general/UnitTestViewAngles.cpp | 4 + 10 files changed, 280 insertions(+), 47 deletions(-) create mode 100644 include/omath/Angle.hpp create mode 100644 include/omath/ViewAngles.hpp create mode 100644 tests/general/UnitTestViewAngles.cpp diff --git a/SECURITY.md b/SECURITY.md index 190b1a5..f114405 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -2,4 +2,4 @@ ## Reporting a Vulnerability -Please report security issues to `orange-cpp@yandex.com` \ No newline at end of file +Please report security issues to `orange-cpp@yandex.ru` \ No newline at end of file diff --git a/include/omath/Angle.hpp b/include/omath/Angle.hpp new file mode 100644 index 0000000..8ddaa2e --- /dev/null +++ b/include/omath/Angle.hpp @@ -0,0 +1,156 @@ +// +// Created by Orange on 11/30/2024. +// + +#pragma once +#include "omath/Angles.hpp" + + +namespace omath +{ + enum class AngleFlags + { + Normalized = 0, + Clamped = 1, + }; + + template + requires std::is_arithmetic_v + class Angle + { + Type m_angle; + public: + + constexpr explicit Angle(const Type& degrees) + { + if constexpr (flags == AngleFlags::Normalized) + m_angle = angles::WrapAngle(degrees, min, max); + + else if constexpr (flags == AngleFlags::Clamped) + m_angle = std::clamp(degrees, min, max); + else + { + static_assert(false); + std::unreachable(); + } + } + + [[nodiscard]] + constexpr static Angle FromDegrees(const Type& degrees) + { + return {degrees}; + } + + [[nodiscard]] + constexpr static Angle FromRadians(const Type& degrees) + { + return {angles::RadiansToDegrees(degrees)}; + } + + [[nodiscard]] + constexpr const Type& operator*() const + { + return m_angle; + } + + [[nodiscard]] + constexpr Type& operator*() + { + return m_angle; + } + + [[nodiscard]] + constexpr const Type& Value() const + { + return **std::as_const(this); + } + + [[nodiscard]] + constexpr Type& Value() + { + return **this; + } + + [[nodiscard]] + constexpr Type AsRadians() const + { + return angles::RadiansToDegrees(m_angle); + } + + [[nodiscard]] + Type Sin() const + { + return std::sin(AsRadians()); + } + + [[nodiscard]] + Type Cos() const + { + return std::sin(AsRadians()); + } + + [[nodiscard]] + Type Tan() const + { + return std::tan(AsRadians()); + } + + [[nodiscard]] + Type Atan() const + { + return std::atan(AsRadians()); + } + + [[nodiscard]] + Type Cot() const + { + return Cos() / Sin(); + } + + [[nodiscard]] + constexpr Angle& operator+=(const Type& other) + { + if constexpr (flags == AngleFlags::Normalized) + m_angle = angles::WrapAngle(m_angle + other, min, max); + + else if constexpr (flags == AngleFlags::Clamped) + m_angle = std::clamp(m_angle + other, min, max); + else + { + static_assert(false); + std::unreachable(); + } + + return *this; + } + + [[nodiscard]] + constexpr Angle& operator-=(const Type& other) + { + return operator+=(-other); + } + + [[nodiscard]] + constexpr Angle& operator+(const Type& other) + { + if constexpr (flags == AngleFlags::Normalized) + return {angles::WrapAngle(m_angle + other, min, max)}; + + else if constexpr (flags == AngleFlags::Clamped) + return {std::clamp(m_angle + other, min, max)}; + + else + static_assert(false); + + std::unreachable(); + } + + [[nodiscard]] + constexpr Angle& operator-(const Type& other) + { + return operator+(-other); + } + + + }; +} diff --git a/include/omath/Angles.hpp b/include/omath/Angles.hpp index 0dc6d61..7b0a3d1 100644 --- a/include/omath/Angles.hpp +++ b/include/omath/Angles.hpp @@ -4,21 +4,23 @@ #pragma once #include +#include + namespace omath::angles { - template - requires std::is_floating_point_v - [[nodiscard]] constexpr float RadiansToDegrees(const type& radians) + template + requires std::is_floating_point_v + [[nodiscard]] constexpr float RadiansToDegrees(const Type& radians) { - return radians * (type(180) / std::numbers::pi_v); + return radians * (Type(180) / std::numbers::pi_v); } - template - requires std::is_floating_point_v - [[nodiscard]] constexpr float DegreesToRadians(const type& degrees) + template + requires std::is_floating_point_v + [[nodiscard]] constexpr float DegreesToRadians(const Type& degrees) { - return degrees * (std::numbers::pi_v / type(180)); + return degrees * (std::numbers::pi_v / Type(180)); } template @@ -32,14 +34,31 @@ namespace omath::angles return RadiansToDegrees(vertFov); } - template - requires std::is_floating_point_v - [[nodiscard]] type VerticalFovToHorizontal(const type& vertFov, const type& aspect) + template + requires std::is_floating_point_v + [[nodiscard]] Type VerticalFovToHorizontal(const Type& vertFov, const Type& aspect) { const auto fovRad = DegreesToRadians(vertFov); - const auto horFov = type(2) * std::atan(std::tan(fovRad / type(2)) * aspect); + const auto horFov = Type(2) * std::atan(std::tan(fovRad / Type(2)) * aspect); return RadiansToDegrees(horFov); } + + template + requires std::is_arithmetic_v + [[nodiscard]] Type WrapAngle(const Type& angle, const Type& min, const Type& max) + { + if (angle <= max && angle >= min) + return angle; + + const Type range = max - min; + + Type wrappedAngle = std::fmod(angle - min, range); + + if (wrappedAngle < 0) + wrappedAngle += range; + + return wrappedAngle + min; + } } diff --git a/include/omath/Mat.hpp b/include/omath/Mat.hpp index 1e717ab..536ca37 100644 --- a/include/omath/Mat.hpp +++ b/include/omath/Mat.hpp @@ -25,7 +25,7 @@ namespace omath }; template - requires (std::is_floating_point_v || std::is_integral_v) + requires std::is_arithmetic_v class Mat final { public: @@ -34,7 +34,7 @@ namespace omath Clear(); } - constexpr Mat(const std::initializer_list>& rows) + constexpr Mat(const std::initializer_list >& rows) { if (rows.size() != Rows) throw std::invalid_argument("Initializer list rows size does not match template parameter Rows"); @@ -59,12 +59,12 @@ namespace omath std::copy_n(rawData, Rows * Columns, m_data.begin()); } - constexpr Mat(const Mat &other) noexcept + constexpr Mat(const Mat& other) noexcept { m_data = other.m_data; } - constexpr Mat(Mat &&other) noexcept + constexpr Mat(Mat&& other) noexcept { m_data = std::move(other.m_data); } @@ -87,7 +87,7 @@ namespace omath return {Rows, Columns}; } - [[nodiscard]] constexpr const Type &At(const size_t rowIndex, const size_t columnIndex) const + [[nodiscard]] constexpr const Type& At(const size_t rowIndex, const size_t columnIndex) const { if (rowIndex >= Rows || columnIndex >= Columns) throw std::out_of_range("Index out of range"); @@ -105,9 +105,9 @@ namespace omath } } - [[nodiscard]] constexpr Type &At(const size_t rowIndex, const size_t columnIndex) + [[nodiscard]] constexpr Type& At(const size_t rowIndex, const size_t columnIndex) { - return const_cast(std::as_const(*this).At(rowIndex, columnIndex)); + return const_cast(std::as_const(*this).At(rowIndex, columnIndex)); } [[nodiscard]] @@ -126,14 +126,15 @@ namespace omath Set(0); } - constexpr void Set(const Type &value) noexcept + constexpr void Set(const Type& value) noexcept { std::ranges::fill(m_data, value); } // Operator overloading for multiplication with another Mat template - constexpr Mat operator*(const Mat &other) const + constexpr Mat operator*( + const Mat& other) const { Mat result; @@ -148,7 +149,7 @@ namespace omath return result; } - constexpr Mat &operator*=(const Type &f) noexcept + constexpr Mat& operator*=(const Type& f) noexcept { for (size_t i = 0; i < Rows; ++i) for (size_t j = 0; j < Columns; ++j) @@ -157,19 +158,20 @@ namespace omath } template - constexpr Mat operator*=(const Mat &other) + constexpr Mat operator*=( + const Mat& other) { return *this = *this * other; } - constexpr Mat operator*(const Type &f) const noexcept + constexpr Mat operator*(const Type& f) const noexcept { Mat result(*this); result *= f; return result; } - constexpr Mat &operator/=(const Type &f) noexcept + constexpr Mat& operator/=(const Type& f) noexcept { for (size_t i = 0; i < Rows; ++i) for (size_t j = 0; j < Columns; ++j) @@ -177,14 +179,14 @@ namespace omath return *this; } - constexpr Mat operator/(const Type &f) const noexcept + constexpr Mat operator/(const Type& f) const noexcept { Mat result(*this); result /= f; return result; } - constexpr Mat &operator=(const Mat &other) noexcept + constexpr Mat& operator=(const Mat& other) noexcept { if (this == &other) return *this; @@ -194,7 +196,7 @@ namespace omath return *this; } - constexpr Mat &operator=(Mat &&other) noexcept + constexpr Mat& operator=(Mat&& other) noexcept { if (this == &other) return *this; @@ -260,15 +262,15 @@ namespace omath } [[nodiscard]] - constexpr const std::array& RawArray() const + constexpr const std::array& RawArray() const { return m_data; } [[nodiscard]] - constexpr std::array& RawArray() + constexpr std::array& RawArray() { - return const_cast>(std::as_const(*this).RawArray()); + return const_cast>(std::as_const(*this).RawArray()); } [[nodiscard]] @@ -289,20 +291,20 @@ namespace omath } [[nodiscard]] - bool operator==(const Mat & mat) const + bool operator==(const Mat& mat) const { return m_data == mat.m_data; } [[nodiscard]] - bool operator!=(const Mat & mat) const + bool operator!=(const Mat& mat) const { return !operator==(mat); } // Static methods that return fixed-size matrices [[nodiscard]] - constexpr static Mat<4, 4> ToScreenMat(const Type &screenWidth, const Type &screenHeight) noexcept + constexpr static Mat<4, 4> ToScreenMat(const Type& screenWidth, const Type& screenHeight) noexcept { return { @@ -314,7 +316,7 @@ namespace omath } [[nodiscard]] - constexpr static Mat<4, 4> TranslationMat(const Vector3 &diff) noexcept + constexpr static Mat<4, 4> TranslationMat(const Vector3& diff) noexcept { return { @@ -326,24 +328,24 @@ namespace omath } [[nodiscard]] - constexpr static Mat<4, 4> OrientationMat(const Vector3 &forward, const Vector3 &right, - const Vector3 &up) noexcept + constexpr static Mat<4, 4> OrientationMat(const Vector3& forward, const Vector3& right, + const Vector3& up) noexcept { return { {right.x, up.x, forward.x, 0}, {right.y, up.y, forward.y, 0}, {right.z, up.z, forward.z, 0}, - {0, 0, 0, 1}, + {0, 0, 0, 1}, }; } [[nodiscard]] - constexpr static Mat<4, 4> ProjectionMat(const Type &fieldOfView, const Type &aspectRatio, - const Type &near, const Type &far, const Type &lensZoom) noexcept + constexpr static Mat<4, 4> ProjectionMat(const Type& fieldOfView, const Type& aspectRatio, + const Type& near, const Type& far, const Type& lensZoom) noexcept { - const Type &fovHalfTan = std::tan(angles::DegreesToRadians(fieldOfView) / 2); - const Type &frustumHeight = far - near; + const Type& fovHalfTan = std::tan(angles::DegreesToRadians(fieldOfView) / 2); + const Type& frustumHeight = far - near; return { @@ -355,13 +357,13 @@ namespace omath } [[nodiscard]] - constexpr static Mat<4, 1> MatRowFromVector(const Vector3 &vector) noexcept + constexpr static Mat<4, 1> MatRowFromVector(const Vector3& vector) noexcept { return {{vector.x, vector.y, vector.z, 1}}; } [[nodiscard]] - constexpr static Mat<1, 4> MatColumnFromVector(const Vector3 &vector) noexcept + constexpr static Mat<1, 4> MatColumnFromVector(const Vector3& vector) noexcept { return { diff --git a/include/omath/Triangle3d.hpp b/include/omath/Triangle3d.hpp index f755ebf..370aa95 100644 --- a/include/omath/Triangle3d.hpp +++ b/include/omath/Triangle3d.hpp @@ -10,6 +10,7 @@ namespace omath { public: Triangle3d(const Vector3& vertex1, const Vector3& vertex2, const Vector3& vertex3); + Vector3 m_vertex1; Vector3 m_vertex2; Vector3 m_vertex3; @@ -29,4 +30,4 @@ namespace omath [[nodiscard]] Vector3 SideBVector() const; }; -} \ No newline at end of file +} diff --git a/include/omath/ViewAngles.hpp b/include/omath/ViewAngles.hpp new file mode 100644 index 0000000..cf36ca2 --- /dev/null +++ b/include/omath/ViewAngles.hpp @@ -0,0 +1,35 @@ +// +// Created by Orange on 11/30/2024. +// +#pragma once +#include +#include <__algorithm/clamp.h> + +#include "omath/Angles.hpp" + + +namespace omath +{ + template + requires std::is_arithmetic_v + class ViewAngles + { + Type pitch; + Type yaw; + Type roll; + + constexpr void SetPitch(const Type& newPitch) + { + pitch = std::clamp(newPitch, min, max); + } + void SetYaw(const Type& newYaw) + { + yaw = std::clamp(newYaw, min, max); + } + void SetRoll(const Type& newRoll) + { + roll = angles::WrapAngle(newRoll, min, max); + } + + }; +} diff --git a/include/omath/engines/source.hpp b/include/omath/engines/source.hpp index 32c248a..61eb1b6 100644 --- a/include/omath/engines/source.hpp +++ b/include/omath/engines/source.hpp @@ -12,6 +12,7 @@ namespace omath::source constexpr Vector3 kAbsForward = {1, 0, 0}; + template requires std::is_floating_point_v || std::is_integral_v [[nodiscard]] Mat<4, 4, Type, MatStoreType::COLUMN_MAJOR> PerspectiveProjectionMatrix( const float fieldOfView, const Type &aspectRatio, const Type &near, const Type &far) @@ -26,4 +27,6 @@ namespace omath::source {0, 0, 1, 0}, }; } + + } diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 109cdc7..dbde66f 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -16,6 +16,7 @@ add_executable(unit-tests general/UnitTestVector4.cpp general/UnitTestLineTrace.cpp general/UnitTestAngles.cpp + general/UnitTestViewAngles.cpp engines/UnitTestOpenGL.cpp engines/UnitTestUnityEngine.cpp diff --git a/tests/general/UnitTestAngles.cpp b/tests/general/UnitTestAngles.cpp index 324ce4d..37b00ff 100644 --- a/tests/general/UnitTestAngles.cpp +++ b/tests/general/UnitTestAngles.cpp @@ -3,7 +3,7 @@ // #include #include - +#include TEST(UnitTestAngles, RadiansToDeg) { @@ -35,4 +35,16 @@ TEST(UnitTestAngles, VerticalToHorizontal) const auto horizontalFov = omath::angles::VerticalFovToHorizontal(vFov, aspectRation); EXPECT_NEAR(horizontalFov, 89.99f, 0.01f); +} +TEST(UnitTestAngles, WrapAngle) +{ + const float wrapped = omath::angles::WrapAngle(361.f, 0.f, 360.f); + + EXPECT_NEAR(wrapped, 1.f, 0.01f); +} +TEST(UnitTestAngles, WrapAngleNegativeRange) +{ + const float wrapped = omath::angles::WrapAngle(-90.f, 0.f, 360.f); + + EXPECT_NEAR(wrapped, 270.f, 0.01f); } \ No newline at end of file diff --git a/tests/general/UnitTestViewAngles.cpp b/tests/general/UnitTestViewAngles.cpp new file mode 100644 index 0000000..97c90e3 --- /dev/null +++ b/tests/general/UnitTestViewAngles.cpp @@ -0,0 +1,4 @@ +// +// Created by Orange on 11/30/2024. +// +#include \ No newline at end of file From dac0684405c62e0e6dc2e84a6d0f702a2b6d8e41 Mon Sep 17 00:00:00 2001 From: Orange Date: Sat, 30 Nov 2024 13:55:15 +0300 Subject: [PATCH 07/24] fixed format --- .clang-format | 62 ++++++++++++++++++++++++++++++++++++++++ include/omath/Matrix.hpp | 26 ++++++++--------- 2 files changed, 75 insertions(+), 13 deletions(-) create mode 100644 .clang-format diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..d074535 --- /dev/null +++ b/.clang-format @@ -0,0 +1,62 @@ +# Generated from CLion C/C++ Code Style settings +--- +Language: Cpp +BasedOnStyle: LLVM +AccessModifierOffset: -4 +AlignConsecutiveAssignments: false +AlignConsecutiveDeclarations: false +AlignOperands: true +AlignTrailingComments: false +AllowShortBlocksOnASingleLine: false +AllowShortFunctionsOnASingleLine: None +AlwaysBreakTemplateDeclarations: Yes +BraceWrapping: + AfterCaseLabel: true + AfterClass: true + AfterControlStatement: true + AfterEnum: true + AfterFunction: true + AfterNamespace: true + AfterStruct: true + AfterUnion: true + AfterExternBlock: true + BeforeCatch: false + BeforeElse: false + BeforeLambdaBody: true + BeforeWhile: false + IndentBraces: false + SplitEmptyFunction: true + SplitEmptyRecord: true + SplitEmptyNamespace: true +BreakBeforeBraces: Custom +BreakConstructorInitializers: AfterColon +BreakConstructorInitializersBeforeComma: false +ColumnLimit: 120 +ConstructorInitializerAllOnOneLineOrOnePerLine: false +ContinuationIndentWidth: 8 +IncludeCategories: + - Regex: '^<.*' + Priority: 1 + - Regex: '^".*' + Priority: 2 + - Regex: '.*' + Priority: 3 +IncludeIsMainRegex: '([-_](test|unittest))?$' +IndentCaseLabels: true +IndentWidth: 4 +InsertNewlineAtEOF: true +MacroBlockBegin: '' +MacroBlockEnd: '' +MaxEmptyLinesToKeep: 2 +NamespaceIndentation: All +PointerAlignment: Left +SpaceAfterCStyleCast: true +SpaceAfterTemplateKeyword: false +SpaceBeforeRangeBasedForLoopColon: false +SpaceInEmptyParentheses: false +SpacesInAngles: false +SpacesInConditionalStatement: false +SpacesInCStyleCastParentheses: false +SpacesInParentheses: false +TabWidth: 4 +... diff --git a/include/omath/Matrix.hpp b/include/omath/Matrix.hpp index 81e7b4f..1fbdb4b 100644 --- a/include/omath/Matrix.hpp +++ b/include/omath/Matrix.hpp @@ -1,7 +1,7 @@ #pragma once +#include #include #include -#include namespace omath { @@ -27,11 +27,11 @@ namespace omath [[nodiscard]] static Matrix ProjectionMatrix(float fieldOfView, float aspectRatio, float near, float far); - Matrix(const Matrix &other); + Matrix(const Matrix& other); - Matrix(size_t rows, size_t columns, const float *pRaw); + Matrix(size_t rows, size_t columns, const float* pRaw); - Matrix(Matrix &&other) noexcept; + Matrix(Matrix&& other) noexcept; [[nodiscard]] size_t RowCount() const noexcept; @@ -43,7 +43,7 @@ namespace omath std::pair Size() const noexcept; [[nodiscard]] - float &At(size_t iRow, size_t iCol); + float& At(size_t iRow, size_t iCol); [[nodiscard]] float Sum(); @@ -56,17 +56,17 @@ namespace omath void Set(float val); [[nodiscard]] - const float &At(size_t iRow, size_t iCol) const; + const float& At(size_t iRow, size_t iCol) const; - Matrix operator*(const Matrix &other) const; + Matrix operator*(const Matrix& other) const; - Matrix& operator*=(const Matrix &other); + Matrix& operator*=(const Matrix& other); Matrix operator*(float f) const; - Matrix &operator*=(float f); + Matrix& operator*=(float f); - Matrix &operator/=(float f); + Matrix& operator/=(float f); void Clear(); @@ -85,9 +85,9 @@ namespace omath [[nodiscard]] const float* Raw() const; - Matrix &operator=(const Matrix &other); + Matrix& operator=(const Matrix& other); - Matrix &operator=(Matrix &&other) noexcept; + Matrix& operator=(Matrix&& other) noexcept; Matrix operator/(float f) const; @@ -101,4 +101,4 @@ namespace omath size_t m_columns; std::unique_ptr m_data; }; -} \ No newline at end of file +} // namespace omath From 7e29ea339e6d48df9d4d618bbe711a269abf790e Mon Sep 17 00:00:00 2001 From: Orange Date: Sat, 30 Nov 2024 14:11:39 +0300 Subject: [PATCH 08/24] modified output dir --- CMakeLists.txt | 3 ++ source/Matrix.cpp | 109 +++++++++++++++++++++------------------------- 2 files changed, 52 insertions(+), 60 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b2d004b..f79bac9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,6 +6,9 @@ project(omath VERSION 1.0.0) set(CMAKE_CXX_STANDARD 26) +set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/out/${CMAKE_BUILD_TYPE}") +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/out/${CMAKE_BUILD_TYPE}") + 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) diff --git a/source/Matrix.cpp b/source/Matrix.cpp index de92ab9..b07dde4 100644 --- a/source/Matrix.cpp +++ b/source/Matrix.cpp @@ -1,13 +1,12 @@ #include "omath/Matrix.hpp" -#include "omath/Vector3.hpp" #include "omath/Angles.hpp" +#include "omath/Vector3.hpp" +#include #include -#include #include #include -#include namespace omath @@ -31,23 +30,23 @@ namespace omath m_columns = rows.begin()->size(); - for (const auto& row : rows) + for (const auto& row: rows) if (row.size() != m_columns) throw std::invalid_argument("All rows must have the same number of columns."); m_data = std::make_unique(m_rows * m_columns); size_t i = 0; - for (const auto& row : rows) + for (const auto& row: rows) { size_t j = 0; - for (const auto& value : row) + for (const auto& value: row) At(i, j++) = value; ++i; } } - Matrix::Matrix(const Matrix &other) + Matrix::Matrix(const Matrix& other) { m_rows = other.m_rows; m_columns = other.m_columns; @@ -59,7 +58,7 @@ namespace omath At(i, j) = other.At(i, j); } - Matrix::Matrix(const size_t rows, const size_t columns, const float *pRaw) + Matrix::Matrix(const size_t rows, const size_t columns, const float* pRaw) { m_rows = rows; m_columns = columns; @@ -67,9 +66,8 @@ namespace omath m_data = std::make_unique(m_rows * m_columns); - for (size_t i = 0; i < rows*columns; ++i) + for (size_t i = 0; i < rows * columns; ++i) At(i / rows, i % columns) = pRaw[i]; - } size_t Matrix::RowCount() const noexcept @@ -77,7 +75,7 @@ namespace omath return m_rows; } - Matrix::Matrix(Matrix &&other) noexcept + Matrix::Matrix(Matrix&& other) noexcept { m_rows = other.m_rows; m_columns = other.m_columns; @@ -99,7 +97,7 @@ namespace omath return {RowCount(), ColumnsCount()}; } - float &Matrix::At(const size_t iRow, const size_t iCol) + float& Matrix::At(const size_t iRow, const size_t iCol) { return const_cast(std::as_const(*this).At(iRow, iCol)); } @@ -115,12 +113,12 @@ namespace omath return sum; } - const float &Matrix::At(const size_t iRow, const size_t iCol) const + const float& Matrix::At(const size_t iRow, const size_t iCol) const { return m_data[iRow * m_columns + iCol]; } - Matrix Matrix::operator*(const Matrix &other) const + Matrix Matrix::operator*(const Matrix& other) const { if (m_columns != other.m_rows) throw std::runtime_error("n != m"); @@ -136,7 +134,7 @@ namespace omath return outMat; } - Matrix & Matrix::operator*=(const Matrix &other) + Matrix& Matrix::operator*=(const Matrix& other) { *this = *this * other; return *this; @@ -152,7 +150,7 @@ namespace omath return out; } - Matrix &Matrix::operator*=(const float f) + Matrix& Matrix::operator*=(const float f) { for (size_t i = 0; i < RowCount(); i++) for (size_t j = 0; j < ColumnsCount(); j++) @@ -164,8 +162,8 @@ namespace omath { Set(0.f); } - - Matrix &Matrix::operator=(const Matrix &other) + + Matrix& Matrix::operator=(const Matrix& other) { if (this == &other) return *this; @@ -175,10 +173,9 @@ namespace omath At(i, j) = other.At(i, j); return *this; - } - Matrix &Matrix::operator=(Matrix &&other) noexcept + Matrix& Matrix::operator=(Matrix&& other) noexcept { if (this == &other) return *this; @@ -191,10 +188,9 @@ namespace omath other.m_columns = 0; return *this; - } - Matrix &Matrix::operator/=(const float f) + Matrix& Matrix::operator/=(const float f) { for (size_t i = 0; i < m_rows; ++i) for (size_t j = 0; j < m_columns; ++j) @@ -221,9 +217,9 @@ namespace omath { for (size_t j = 0; j < m_columns; ++j) { - str += std::format("{:.1f}",At(i, j)); + str += std::format("{:.1f}", At(i, j)); - if (j == m_columns-1) + if (j == m_columns - 1) str += '\n'; else str += ' '; @@ -306,49 +302,42 @@ namespace omath Matrix Matrix::ToScreenMatrix(const float screenWidth, const float screenHeight) { - return - { - {screenWidth / 2.f, 0.f, 0.f, 0.f}, - {0.f, -screenHeight / 2.f, 0.f, 0.f}, - {0.f, 0.f, 1.f, 0.f}, - {screenWidth / 2.f, screenHeight / 2.f, 0.f, 1.f}, - }; - } - - Matrix Matrix::TranslationMatrix(const Vector3 &diff) - { - return - { - {1.f, 0.f, 0.f, 0.f}, - {0.f, 1.f, 0.f, 0.f}, - {0.f, 0.f, 1.f, 0.f}, - {diff.x, diff.y, diff.z, 1.f}, + return { + {screenWidth / 2.f, 0.f, 0.f, 0.f}, + {0.f, -screenHeight / 2.f, 0.f, 0.f}, + {0.f, 0.f, 1.f, 0.f}, + {screenWidth / 2.f, screenHeight / 2.f, 0.f, 1.f}, }; } - Matrix Matrix::OrientationMatrix(const Vector3 &forward, const Vector3 &right, const Vector3 &up) + Matrix Matrix::TranslationMatrix(const Vector3& diff) { - return - { - {right.x, up.x, forward.x, 0.f}, - {right.y, up.y, forward.y, 0.f}, - {right.z, up.z, forward.z, 0.f}, - {0.f, 0.f, 0.f, 1.f}, + return { + {1.f, 0.f, 0.f, 0.f}, + {0.f, 1.f, 0.f, 0.f}, + {0.f, 0.f, 1.f, 0.f}, + {diff.x, diff.y, diff.z, 1.f}, }; } - Matrix Matrix::ProjectionMatrix(const float fieldOfView, const float aspectRatio, const float near, - const float far) + Matrix Matrix::OrientationMatrix(const Vector3& forward, const Vector3& right, const Vector3& up) + { + return { + {right.x, up.x, forward.x, 0.f}, + {right.y, up.y, forward.y, 0.f}, + {right.z, up.z, forward.z, 0.f}, + {0.f, 0.f, 0.f, 1.f}, + }; + } + + Matrix Matrix::ProjectionMatrix(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.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} - }; + 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}}; } const float* Matrix::Raw() const @@ -356,9 +345,9 @@ namespace omath return m_data.get(); } - void Matrix::SetDataFromRaw(const float *pRawMatrix) + void Matrix::SetDataFromRaw(const float* pRawMatrix) { - for (size_t i = 0; i < m_columns*m_rows; ++i) + for (size_t i = 0; i < m_columns * m_rows; ++i) At(i / m_rows, i % m_columns) = pRawMatrix[i]; } @@ -368,4 +357,4 @@ namespace omath m_rows = 0; m_data = nullptr; } -} \ No newline at end of file +} // namespace omath From 883d27ed581ddf403be2cdf0800b1e98ff4959d4 Mon Sep 17 00:00:00 2001 From: Orange Date: Sat, 30 Nov 2024 14:27:32 +0300 Subject: [PATCH 09/24] updated coc --- CODE_OF_CONDUCT.md | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index a3f36ab..b394840 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -1,4 +1,4 @@ -## Goal +## 🎯 Goal My goal is to provide a space where it is safe for everyone to contribute to, and get support for, open-source software in a respectful and cooperative @@ -10,7 +10,7 @@ surrounding community a place for everyone. As members, contributors, and everyone else who may participate in the development, I strive to keep the entire experience civil. -## Standards +## 📜 Standards Our community standards exist in order to make sure everyone feels comfortable contributing to the project(s) together. @@ -27,14 +27,14 @@ Examples of breaking each rule respectively include: - Posting distasteful imagery, trolling, or posting things unrelated to the topic at hand. - Treating someone as worse because of their lack of understanding of an issue. -## Enforcement +## ⚡ Enforcement Enforcement of this CoC is done by Orange++ and/or other core contributors. I, as the core developer, will strive my best to keep this community civil and following the standards outlined above. -### Reporting incidents +### 🚩 Reporting incidents If you believe an incident of breaking these standards has occurred, but nobody has taken appropriate action, you can privately contact the people responsible for dealing @@ -47,10 +47,10 @@ with such incidents in multiple ways: - `@orange_cpp` ***Telegram*** -- `@orange-cpp` +- `@orange_cpp` I guarantee your privacy and will not share those reports with anyone. -## Enforcement Strategy +## ⚖️ Enforcement Strategy Depending on the severity of the infraction, any action from the list below may be applied. Please keep in mind cases are reviewed on a per-case basis and members are the ultimate @@ -63,27 +63,27 @@ to be taken is still up to the member. For example, if the matter at hand regards a representative of a marginalized group or minority, the member might ask for a first-hand opinion from another representative of such group. -### Correction/Edit +### ✏️ Correction/Edit If your message is found to be misleading or poorly worded, a member might edit your message. -### Warning/Deletion +### ⚠️ Warning/Deletion If your message is found inappropriate, a member might give you a public or private warning, and/or delete your message. -### Mute +### 🔇 Mute If your message is disruptive, or you have been repeatedly violating the standards, a member might mute (or temporarily ban) you. -### Ban +### ⛔ Ban If your message is hateful, very disruptive, or other, less serious infractions are repeated ignoring previous punishments, a member might ban you permanently. -## Scope +## 🔎 Scope This CoC shall apply to all projects ran under the Orange++ lead and all _official_ communities outside of GitHub. From f8e7faa5709ac03e474fc19597eb2bdb106a036c Mon Sep 17 00:00:00 2001 From: Orange Date: Sat, 30 Nov 2024 14:28:15 +0300 Subject: [PATCH 10/24] coc fix --- CODE_OF_CONDUCT.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index b394840..f212606 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -48,6 +48,7 @@ with such incidents in multiple ways: ***Telegram*** - `@orange_cpp` + I guarantee your privacy and will not share those reports with anyone. ## ⚖️ Enforcement Strategy From 46b4eb9151ee59f945ea8b9f170f0af0a21e8278 Mon Sep 17 00:00:00 2001 From: Orange Date: Sun, 1 Dec 2024 03:51:40 +0300 Subject: [PATCH 11/24] huge improvement --- CMakePresets.json | 4 +- extlibs/CMakeLists.txt | 3 +- include/omath/Angle.hpp | 52 +++++----- include/omath/Angles.hpp | 4 +- include/omath/Mat.hpp | 118 ++++++++++++----------- include/omath/Vector3.hpp | 4 - include/omath/ViewAngles.hpp | 30 +----- include/omath/engines/source.hpp | 127 ++++++++++++++++++++++--- include/omath/projection/Camera.hpp | 55 ++++++++--- source/Vector3.cpp | 46 --------- source/prediction/Projectile.cpp | 4 +- source/projection/Camera.cpp | 45 --------- tests/CMakeLists.txt | 3 +- tests/engines/UnitTestOpenGL.cpp | 12 +-- tests/engines/UnitTestSourceEngine.cpp | 28 +++++- tests/general/UnitTestAngle.cpp | 3 + tests/general/UnitTestProjection.cpp | 13 ++- 17 files changed, 297 insertions(+), 254 deletions(-) create mode 100644 tests/general/UnitTestAngle.cpp diff --git a/CMakePresets.json b/CMakePresets.json index 74671b4..d67436b 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -8,8 +8,8 @@ "binaryDir": "${sourceDir}/cmake-build/build/${presetName}", "installDir": "${sourceDir}/cmake-build/install/${presetName}", "cacheVariables": { - "CMAKE_C_COMPILER": "clang.exe", - "CMAKE_CXX_COMPILER": "clang++.exe" + "CMAKE_C_COMPILER": "cl.exe", + "CMAKE_CXX_COMPILER": "cl.exe" }, "condition": { "type": "equals", diff --git a/extlibs/CMakeLists.txt b/extlibs/CMakeLists.txt index caca17c..bf73c7a 100644 --- a/extlibs/CMakeLists.txt +++ b/extlibs/CMakeLists.txt @@ -1,2 +1 @@ -add_subdirectory(googletest) -add_subdirectory(glm) \ No newline at end of file +add_subdirectory(googletest) \ No newline at end of file diff --git a/include/omath/Angle.hpp b/include/omath/Angle.hpp index 8ddaa2e..9b5c64f 100644 --- a/include/omath/Angle.hpp +++ b/include/omath/Angle.hpp @@ -5,6 +5,8 @@ #pragma once #include "omath/Angles.hpp" +#include + namespace omath { @@ -14,14 +16,12 @@ namespace omath Clamped = 1, }; - template + template requires std::is_arithmetic_v class Angle { Type m_angle; - public: - - constexpr explicit Angle(const Type& degrees) + constexpr Angle(const Type& degrees) { if constexpr (flags == AngleFlags::Normalized) m_angle = angles::WrapAngle(degrees, min, max); @@ -34,17 +34,20 @@ namespace omath std::unreachable(); } } - + public: [[nodiscard]] constexpr static Angle FromDegrees(const Type& degrees) { return {degrees}; } + constexpr Angle() : m_angle(0) + { + } [[nodiscard]] constexpr static Angle FromRadians(const Type& degrees) { - return {angles::RadiansToDegrees(degrees)}; + return {angles::RadiansToDegrees(degrees)}; } [[nodiscard]] @@ -54,23 +57,11 @@ namespace omath } [[nodiscard]] - constexpr Type& operator*() + constexpr Type AsDegrees() const { return m_angle; } - [[nodiscard]] - constexpr const Type& Value() const - { - return **std::as_const(this); - } - - [[nodiscard]] - constexpr Type& Value() - { - return **this; - } - [[nodiscard]] constexpr Type AsRadians() const { @@ -86,7 +77,7 @@ namespace omath [[nodiscard]] Type Cos() const { - return std::sin(AsRadians()); + return std::cos(AsRadians()); } [[nodiscard]] @@ -108,13 +99,13 @@ namespace omath } [[nodiscard]] - constexpr Angle& operator+=(const Type& other) + constexpr Angle& operator+=(const Angle& other) { if constexpr (flags == AngleFlags::Normalized) - m_angle = angles::WrapAngle(m_angle + other, min, max); + m_angle = angles::WrapAngle(m_angle + other.m_angle, min, max); else if constexpr (flags == AngleFlags::Clamped) - m_angle = std::clamp(m_angle + other, min, max); + m_angle = std::clamp(m_angle + other.m_angle, min, max); else { static_assert(false); @@ -125,19 +116,22 @@ namespace omath } [[nodiscard]] - constexpr Angle& operator-=(const Type& other) + constexpr std::partial_ordering operator<=>(const Angle& other) const = default; + + [[nodiscard]] + constexpr Angle& operator-=(const Angle& other) { return operator+=(-other); } [[nodiscard]] - constexpr Angle& operator+(const Type& other) + constexpr Angle& operator+(const Angle& other) { if constexpr (flags == AngleFlags::Normalized) - return {angles::WrapAngle(m_angle + other, min, max)}; + return {angles::WrapAngle(m_angle + other.m_angle, min, max)}; else if constexpr (flags == AngleFlags::Clamped) - return {std::clamp(m_angle + other, min, max)}; + return {std::clamp(m_angle + other.m_angle, min, max)}; else static_assert(false); @@ -146,11 +140,9 @@ namespace omath } [[nodiscard]] - constexpr Angle& operator-(const Type& other) + constexpr Angle& operator-(const Angle& other) { return operator+(-other); } - - }; } diff --git a/include/omath/Angles.hpp b/include/omath/Angles.hpp index 7b0a3d1..47a287a 100644 --- a/include/omath/Angles.hpp +++ b/include/omath/Angles.hpp @@ -11,14 +11,14 @@ namespace omath::angles { template requires std::is_floating_point_v - [[nodiscard]] constexpr float RadiansToDegrees(const Type& radians) + [[nodiscard]] constexpr Type RadiansToDegrees(const Type& radians) { return radians * (Type(180) / std::numbers::pi_v); } template requires std::is_floating_point_v - [[nodiscard]] constexpr float DegreesToRadians(const Type& degrees) + [[nodiscard]] constexpr Type DegreesToRadians(const Type& degrees) { return degrees * (std::numbers::pi_v / Type(180)); } diff --git a/include/omath/Mat.hpp b/include/omath/Mat.hpp index 536ca37..2f25bd5 100644 --- a/include/omath/Mat.hpp +++ b/include/omath/Mat.hpp @@ -5,10 +5,10 @@ #include #include #include -#include -#include "Vector3.hpp" #include +#include #include "Angles.hpp" +#include "Vector3.hpp" namespace omath @@ -33,8 +33,11 @@ namespace omath { Clear(); } - - constexpr Mat(const std::initializer_list >& rows) + constexpr static MatStoreType GetStoreOrdering() + { + return StoreType; + } + constexpr Mat(const std::initializer_list>& rows) { if (rows.size() != Rows) throw std::invalid_argument("Initializer list rows size does not match template parameter Rows"); @@ -44,7 +47,7 @@ namespace omath { if (rowIt->size() != Columns) throw std::invalid_argument( - "All rows must have the same number of columns as template parameter Columns"); + "All rows must have the same number of columns as template parameter Columns"); auto colIt = rowIt->begin(); for (size_t j = 0; j < Columns; ++j, ++colIt) @@ -133,8 +136,8 @@ namespace omath // Operator overloading for multiplication with another Mat template - constexpr Mat operator*( - const Mat& other) const + constexpr Mat + operator*(const Mat& other) const { Mat result; @@ -158,8 +161,8 @@ namespace omath } template - constexpr Mat operator*=( - const Mat& other) + constexpr Mat + operator*=(const Mat& other) { return *this = *this * other; } @@ -306,24 +309,22 @@ namespace omath [[nodiscard]] constexpr static Mat<4, 4> ToScreenMat(const Type& screenWidth, const Type& screenHeight) noexcept { - return - { - {screenWidth / 2, 0, 0, 0}, - {0, -screenHeight / 2, 0, 0}, - {0, 0, 1, 0}, - {screenWidth / 2, screenHeight / 2, 0, 1}, + return { + {screenWidth / 2, 0, 0, 0}, + {0, -screenHeight / 2, 0, 0}, + {0, 0, 1, 0}, + {screenWidth / 2, screenHeight / 2, 0, 1}, }; } [[nodiscard]] constexpr static Mat<4, 4> TranslationMat(const Vector3& diff) noexcept { - return - { - {1, 0, 0, 0}, - {0, 1, 0, 0}, - {0, 0, 1, 0}, - {diff.x, diff.y, diff.z, 1}, + return { + {1, 0, 0, 0}, + {0, 1, 0, 0}, + {0, 0, 1, 0}, + {diff.x, diff.y, diff.z, 1}, }; } @@ -331,52 +332,55 @@ namespace omath constexpr static Mat<4, 4> OrientationMat(const Vector3& forward, const Vector3& right, const Vector3& up) noexcept { - return - { - {right.x, up.x, forward.x, 0}, - {right.y, up.y, forward.y, 0}, - {right.z, up.z, forward.z, 0}, - {0, 0, 0, 1}, + return { + {right.x, up.x, forward.x, 0}, + {right.y, up.y, forward.y, 0}, + {right.z, up.z, forward.z, 0}, + {0, 0, 0, 1}, }; } [[nodiscard]] - constexpr static Mat<4, 4> ProjectionMat(const Type& fieldOfView, const Type& aspectRatio, - const Type& near, const Type& far, const Type& lensZoom) noexcept + constexpr static Mat<4, 4> ProjectionMat(const Type& fieldOfView, const Type& aspectRatio, const Type& near, + const Type& far, const Type& lensZoom) noexcept { const Type& fovHalfTan = std::tan(angles::DegreesToRadians(fieldOfView) / 2); const Type& frustumHeight = far - near; - return - { - {-1 / (aspectRatio * fovHalfTan) * lensZoom, 0, 0, 0}, - {0, -1 / fovHalfTan * lensZoom, 0, 0}, - {0, 0, -far / frustumHeight, -1}, - {0, 0, near * far / frustumHeight, 0} - }; - } - - [[nodiscard]] - constexpr static Mat<4, 1> MatRowFromVector(const Vector3& vector) noexcept - { - return {{vector.x, vector.y, vector.z, 1}}; - } - - [[nodiscard]] - constexpr static Mat<1, 4> MatColumnFromVector(const Vector3& vector) noexcept - { - return - { - { - vector.x, - vector.y, - vector.z, - 1 - } - }; + return {{-1 / (aspectRatio * fovHalfTan) * lensZoom, 0, 0, 0}, + {0, -1 / fovHalfTan * lensZoom, 0, 0}, + {0, 0, -far / frustumHeight, -1}, + {0, 0, near * far / frustumHeight, 0}}; } private: std::array m_data; }; -} + + template + [[nodiscard]] + constexpr static Mat<1, 4, T, St> MatRowFromVector(const Vector3& vector) noexcept + { + return {{vector.x, vector.y, vector.z, 1}}; + } + + template + [[nodiscard]] + constexpr static Mat<4, 1, T, St> MatColumnFromVector(const Vector3& vector) noexcept + { + return { + {vector.x}, {vector.y}, {vector.z}, {1}}; + } + + template + [[nodiscard]] + constexpr Mat<4, 4, T, St> MatTranslation(const Vector3& diff) noexcept + { + return { + {1, 0, 0, 0}, + {0, 1, 0, 0}, + {0, 0, 1, 0}, + {diff.x, diff.y, diff.z, 1}, + }; + } +} // namespace omath diff --git a/include/omath/Vector3.hpp b/include/omath/Vector3.hpp index a9a687e..e22d815 100644 --- a/include/omath/Vector3.hpp +++ b/include/omath/Vector3.hpp @@ -216,10 +216,6 @@ namespace omath [[nodiscard]] Vector3 ViewAngleTo(const Vector3& other) const; - [[nodiscard]] static Vector3 ForwardVector(float pitch, float yaw); - [[nodiscard]] static Vector3 RightVector(float pitch, float yaw, float roll); - [[nodiscard]] static Vector3 UpVector(float pitch, float yaw, float roll); - [[nodiscard]] std::tuple AsTuple() const { return std::make_tuple(x, y, z); diff --git a/include/omath/ViewAngles.hpp b/include/omath/ViewAngles.hpp index cf36ca2..d744f6b 100644 --- a/include/omath/ViewAngles.hpp +++ b/include/omath/ViewAngles.hpp @@ -2,34 +2,14 @@ // Created by Orange on 11/30/2024. // #pragma once -#include -#include <__algorithm/clamp.h> - -#include "omath/Angles.hpp" - namespace omath { - template - requires std::is_arithmetic_v - class ViewAngles + template + struct ViewAngles { - Type pitch; - Type yaw; - Type roll; - - constexpr void SetPitch(const Type& newPitch) - { - pitch = std::clamp(newPitch, min, max); - } - void SetYaw(const Type& newYaw) - { - yaw = std::clamp(newYaw, min, max); - } - void SetRoll(const Type& newRoll) - { - roll = angles::WrapAngle(newRoll, min, max); - } - + PitchType pitch; + YawType yaw; + RollType roll; }; } diff --git a/include/omath/engines/source.hpp b/include/omath/engines/source.hpp index 61eb1b6..5bb085e 100644 --- a/include/omath/engines/source.hpp +++ b/include/omath/engines/source.hpp @@ -2,8 +2,12 @@ // Created by Orange on 11/24/2024. // #pragma once -#include "omath/Vector3.hpp" #include "omath/Mat.hpp" +#include "omath/Vector3.hpp" + +#include +#include +#include namespace omath::source { @@ -11,22 +15,119 @@ namespace omath::source constexpr Vector3 kAbsRight = {0, -1, 0}; constexpr Vector3 kAbsForward = {1, 0, 0}; + using PitchAngle = Angle; + using YawAngle = Angle; + using RollAngle = Angle; + + using ViewAngles = omath::ViewAngles; - template requires std::is_floating_point_v || std::is_integral_v - [[nodiscard]] Mat<4, 4, Type, MatStoreType::COLUMN_MAJOR> PerspectiveProjectionMatrix( - const float fieldOfView, const Type &aspectRatio, const Type &near, const Type &far) + inline Vector3 ForwardVector(const ViewAngles& angles); + inline Vector3 RightVector(const ViewAngles& angles); + inline Vector3 UpVector(const ViewAngles& angles); + + + template + requires std::is_floating_point_v || std::is_integral_v + [[nodiscard]] constexpr Mat<4, 4, Type, MatStoreType::COLUMN_MAJOR> ViewMatrixFromVecs(const Vector3& forward, const Vector3& right, + const Vector3& up, const Vector3& camera_pos) { - const float fovHalfTan = std::tan(angles::DegreesToRadians(fieldOfView) / 2); - - return - { - {static_cast(1) / (aspectRatio * fovHalfTan), 0, 0, 0}, - {0, static_cast(1) / (fovHalfTan), 0, 0}, - {0, 0, (far + near) / (far - near), -(static_cast(2) * far * near) / (far - near)}, - {0, 0, 1, 0}, + return MatTranslation(-camera_pos) * Mat<4, 4, Type, MatStoreType::COLUMN_MAJOR>{ + {right.x, up.x, forward.x, 0}, + {right.y, up.y, forward.y, 0}, + {right.z, up.z, forward.z, 0}, + {0, 0, 0, 1}, }; } -} + template + requires std::is_floating_point_v || std::is_integral_v + [[nodiscard]] Mat<4, 4, Type, MatStoreType::COLUMN_MAJOR> ViewMatrix(const ViewAngles& angles, const Vector3& cam_origin) + { + return ViewMatrixFromVecs(ForwardVector(angles), RightVector(angles), UpVector(angles), cam_origin); + } + + template + requires std::is_floating_point_v || std::is_integral_v + [[nodiscard]] Mat<4, 4, Type, MatStoreType::COLUMN_MAJOR> + PerspectiveProjectionMatrix(const Type& fieldOfView, const Type& aspectRatio, const Type& near, const Type& far) + { + const float fovHalfTan = std::tan(angles::DegreesToRadians(fieldOfView) / 2); + + return { + {static_cast(1) / (aspectRatio * fovHalfTan), 0, 0, 0}, + {0, static_cast(1) / (fovHalfTan), 0, 0}, + {0, 0, (far + near) / (far - near), -(static_cast(2) * far * near) / (far - near)}, + {0, 0, 1, 0}, + }; + } + // Copied from + // https://github.com/ValveSoftware/source-sdk-2013/blob/0d8dceea4310fde5706b3ce1c70609d72a38efdf/mp/src/mathlib/mathlib_base.cpp#L919 + [[nodiscard]] + inline Vector3 ForwardVector(const ViewAngles& angles) + { + const auto cosPitch = angles.pitch.Cos(); + const auto sinPitch = angles.pitch.Sin(); + + const auto cosYaw = angles.yaw.Cos(); + const auto sinYaw = angles.yaw.Sin(); + + + return {cosPitch * cosYaw, cosPitch * sinYaw, -sinPitch}; + } + + [[nodiscard]] + inline Vector3 RightVector(const ViewAngles& angles) + { + const auto cosPitch = angles.pitch.Cos(); + const auto sinPitch = angles.pitch.Sin(); + + const auto cosYaw = angles.yaw.Cos(); + const auto sinYaw = angles.yaw.Sin(); + + const auto cosRoll = angles.roll.Cos(); + const auto sinRoll = angles.roll.Sin(); + + + return + { + -1 * sinRoll * sinPitch * cosYaw + -1 * cosRoll * -sinYaw, + -1 * sinRoll * sinPitch * sinYaw + -1 * cosRoll * cosYaw, + -1 * sinRoll * cosPitch + }; + } + + [[nodiscard]] + inline Vector3 UpVector(const ViewAngles& angles) + { + const auto cosPitch = angles.pitch.Cos(); + const auto sinPitch = angles.pitch.Sin(); + + const auto cosYaw = angles.yaw.Cos(); + const auto sinYaw = angles.yaw.Sin(); + + const auto cosRoll = angles.roll.Cos(); + const auto sinRoll = angles.roll.Sin(); + + + return + { + cosRoll * sinPitch * cosYaw + - sinRoll * -sinYaw, + cosRoll * sinPitch * sinYaw + - sinRoll * cosYaw, + cosRoll * cosPitch, + }; + } + using Camera = omath::projection::Camera), decltype(PerspectiveProjectionMatrix)>; + + + // Camera(const Vector3& position, const ViewAnglesType& viewAngles, const ViewPort& viewPort, + // const Angle& fov, const float near, const float far, + // const std::function& viewMatFunc, const std::function& projFunc) + + inline Camera CreateCamera(const Vector3& position, const auto& viewAngles, const projection::ViewPort& viewPort, + const Angle& fov, const float near, const float far) + { + return Camera(position, viewAngles, viewPort, fov, near, far, ViewMatrix, PerspectiveProjectionMatrix); + } +} // namespace omath::source diff --git a/include/omath/projection/Camera.hpp b/include/omath/projection/Camera.hpp index ac5a241..e190664 100644 --- a/include/omath/projection/Camera.hpp +++ b/include/omath/projection/Camera.hpp @@ -5,9 +5,11 @@ #pragma once #include -#include #include +#include #include "ErrorCodes.hpp" +#include +#include namespace omath::projection @@ -18,29 +20,60 @@ namespace omath::projection float m_width; float m_height; - [[nodiscard]] constexpr float AspectRatio() const {return m_width / m_height;} + [[nodiscard]] constexpr float AspectRatio() const + { + return m_width / m_height; + } }; + template + requires std::is_same_v, + std::invoke_result_t> class Camera { public: - Camera(const Vector3& position, const Vector3& viewAngles, const ViewPort& viewPort, - float fov, float near, float far, float lensZoom); - void SetViewAngles(const Vector3& viewAngles); + Camera(const Vector3& position, const ViewAnglesType& viewAngles, const ViewPort& viewPort, + const Angle& fov, const float near, const float far, + const std::function& viewMatFunc, const std::function& projFunc) : + m_viewPort(viewPort), m_fieldOfView(fov), m_farPlaneDistance(far), m_nearPlaneDistance(near), + m_viewAngles(viewAngles), m_origin(position), CreateViewMatrix(viewMatFunc), CreateProjectionMatrix(projFunc) + { + } - [[nodiscard]] Mat<4, 4> GetViewMatrix() const; + void LookAt(const Vector3& target); - [[nodiscard]] std::expected WorldToScreen(const Vector3& worldPosition) const; + [[nodiscard]] auto GetViewMatrix() const + { + return CreateViewMatrix(m_viewAngles, m_origin); + } + + [[nodiscard]] auto GetProjectionMatrix() const + { + return CreateProjectionMatrix(m_fieldOfView.AsDegrees(), m_viewPort.AspectRatio(), m_nearPlaneDistance, m_farPlaneDistance); + } + + [[nodiscard]] std::expected WorldToScreen([[maybe_unused]] const Vector3& worldPosition) const + { + using mat = std::invoke_result_t; + const auto vecAsMatrix = MatColumnFromVector(worldPosition); + + const auto projected = GetViewMatrix().Transposed() * vecAsMatrix; + + + return Vector3{projected.At(0,0), projected.At(1,0), projected.At(2,0)}; + } ViewPort m_viewPort{}; - float m_fieldOfView; + Angle m_fieldOfView; float m_farPlaneDistance; float m_nearPlaneDistance; - float m_lensZoom; private: - Vector3 m_viewAngles; + ViewAnglesType m_viewAngles; Vector3 m_origin; + + std::function CreateViewMatrix; + std::function CreateProjectionMatrix; }; -} +} // namespace omath::projection diff --git a/source/Vector3.cpp b/source/Vector3.cpp index acd2b02..45b9f1e 100644 --- a/source/Vector3.cpp +++ b/source/Vector3.cpp @@ -20,50 +20,4 @@ namespace omath 0.f }; } - - Vector3 Vector3::ForwardVector(const float pitch, const float yaw) - { - const auto cosPitch = std::cos(angles::DegreesToRadians(pitch)); - const auto sinPitch = std::sin(angles::DegreesToRadians(pitch)); - - const auto cosYaw = std::cos(angles::DegreesToRadians(yaw)); - const auto sinYaw = std::sin(angles::DegreesToRadians(yaw)); - - - return - { - cosPitch*cosYaw, - cosPitch*sinYaw, - sinPitch - }; - } - - Vector3 Vector3::RightVector(const float pitch, const float yaw, const float roll) - { - const auto radPitch = angles::DegreesToRadians(pitch); - const auto radYaw = angles::DegreesToRadians(yaw); - const auto radRoll = angles::DegreesToRadians(roll); - - const auto cosPitch = std::cos(radPitch); - const auto sinPitch = std::sin(radPitch); - - const auto cosYaw = std::cos(radYaw); - const auto sinYaw = std::sin(radYaw); - - const auto cosRoll = std::cos(radRoll); - const auto sinRoll = std::sin(radRoll); - - - return - { - sinRoll*sinPitch*cosYaw + cosRoll*sinYaw, - sinRoll*sinPitch*sinYaw - cosRoll*cosYaw, - -sinRoll*cosPitch - }; - } - - Vector3 Vector3::UpVector(float pitch, float yaw, float roll) - { - return RightVector(pitch, yaw, roll).Cross(ForwardVector(pitch, yaw)); - } } \ No newline at end of file diff --git a/source/prediction/Projectile.cpp b/source/prediction/Projectile.cpp index 26cfd8e..3ceb951 100644 --- a/source/prediction/Projectile.cpp +++ b/source/prediction/Projectile.cpp @@ -4,13 +4,13 @@ #include "omath/prediction/Projectile.hpp" #include - +#include namespace omath::prediction { Vector3 Projectile::PredictPosition(const float pitch, const float yaw, const float time, const float gravity) const { - auto currentPos = m_origin + Vector3::ForwardVector(pitch, yaw) * m_launchSpeed * time; + auto currentPos = m_origin + omath::source::ForwardVector({source::PitchAngle::FromDegrees(pitch), source::YawAngle::FromDegrees(yaw), source::RollAngle::FromDegrees(0)}) * m_launchSpeed * time; currentPos.z -= (gravity * m_gravityScale) * std::pow(time, 2.f) * 0.5f; return currentPos; diff --git a/source/projection/Camera.cpp b/source/projection/Camera.cpp index af9782b..dc0e070 100644 --- a/source/projection/Camera.cpp +++ b/source/projection/Camera.cpp @@ -6,49 +6,4 @@ namespace omath::projection { - Camera::Camera(const Vector3 &position, const Vector3 &viewAngles, const ViewPort &viewPort, - const float fov, const float near, const float far, const float lensZoom) - { - m_origin = position; - m_viewAngles = viewAngles; - m_viewPort = viewPort; - m_fieldOfView = fov; - m_nearPlaneDistance = near; - m_farPlaneDistance = far; - m_lensZoom = lensZoom; - } - - Mat<4, 4> Camera::GetViewMatrix() const - { - const auto forward = Vector3::ForwardVector(m_viewAngles.x, m_viewAngles.y); - const auto right = Vector3::RightVector(m_viewAngles.x, m_viewAngles.y, m_viewAngles.z); - const auto up = Vector3::UpVector(m_viewAngles.x, m_viewAngles.y, m_viewAngles.z); - - return Mat<>::TranslationMat(-m_origin) * Mat<>::OrientationMat(forward, right, up); - } - - std::expected Camera::WorldToScreen(const Vector3& worldPosition) const - { - const auto posVecAsMatrix = Mat<>::MatColumnFromVector(worldPosition); - - - const auto projectionMatrix = Mat<>::ProjectionMat(m_fieldOfView, m_viewPort.AspectRatio(), - m_nearPlaneDistance, m_farPlaneDistance, m_lensZoom); - - Mat<1, 4> projected = posVecAsMatrix * (GetViewMatrix() * projectionMatrix); - - if (projected.At(0, 3) == 0.f) - return std::unexpected(Error::WORLD_POSITION_IS_OUT_OF_SCREEN_BOUNDS); - - projected /= projected.At(0, 3); - - if (projected.At(0, 0) < -1.f || projected.At(0, 0) > 1.f || - projected.At(0, 1) < -1.f || projected.At(0, 1) > 1.f || - projected.At(0, 2) < -1.f || projected.At(0, 2) > 1.f) - return std::unexpected(Error::WORLD_POSITION_IS_OUT_OF_SCREEN_BOUNDS); - - projected *= Mat<4, 4>::ToScreenMat(m_viewPort.m_width, m_viewPort.m_height); - - return Vector3{projected.At(0, 0), projected.At(0, 1), projected.At(0, 2)}; - } } diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index dbde66f..77c9508 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -17,6 +17,7 @@ add_executable(unit-tests general/UnitTestLineTrace.cpp general/UnitTestAngles.cpp general/UnitTestViewAngles.cpp + general/UnitTestAngle.cpp engines/UnitTestOpenGL.cpp engines/UnitTestUnityEngine.cpp @@ -24,6 +25,6 @@ add_executable(unit-tests ) -target_link_libraries(unit-tests PRIVATE gtest gtest_main omath glm) +target_link_libraries(unit-tests PRIVATE gtest gtest_main omath) gtest_discover_tests(unit-tests) \ No newline at end of file diff --git a/tests/engines/UnitTestOpenGL.cpp b/tests/engines/UnitTestOpenGL.cpp index 2cb6889..cbe252b 100644 --- a/tests/engines/UnitTestOpenGL.cpp +++ b/tests/engines/UnitTestOpenGL.cpp @@ -7,17 +7,17 @@ #include #include #include -#include +// #include -#include "glm/ext/matrix_clip_space.hpp" -#include "glm/ext/matrix_transform.hpp" +// #include "glm/ext/matrix_clip_space.hpp" +// #include "glm/ext/matrix_transform.hpp" TEST(UnitTestOpenGL, Projection) { - const auto proj_glm = glm::perspective(glm::radians(90.f), 16.f / 9.f, 0.1f, 1000.f); - const auto proj_glm2 = glm::perspectiveLH_NO(glm::radians(90.f), 16.f / 9.f, 0.1f, 1000.f); + /*const auto proj_glm = glm::perspective(glm::radians(90.f), 16.f / 9.f, 0.1f, 1000.f); + // const auto proj_glm2 = glm::perspectiveLH_NO(glm::radians(90.f), 16.f / 9.f, 0.1f, 1000.f); // const auto proj_omath = omath::Mat<4, 4, float, omath::MatStoreType::COLUMN_MAJOR>((const float*)&proj_glm); // EXPECT_EQ(omath::opengl::PerspectiveProjectionMatrix(90, 16.f / 9.f, 0.1f, 1000.f), proj_omath); @@ -34,7 +34,7 @@ TEST(UnitTestOpenGL, Projection) //auto ndc_omath = proj_omath * cords_omath; // ndc_omath /= ndc_omath.At(3, 0); - + */ } TEST(UnitTestOpenGL, Projection2) { diff --git a/tests/engines/UnitTestSourceEngine.cpp b/tests/engines/UnitTestSourceEngine.cpp index 4f6b72b..9c1861f 100644 --- a/tests/engines/UnitTestSourceEngine.cpp +++ b/tests/engines/UnitTestSourceEngine.cpp @@ -1,3 +1,29 @@ // -// Created by Orange on 11/27/2024. +// Created by Orange on 11/23/2024. // +#include +#include + + + + + +TEST(UnitTestSourceEngine, ForwardVector) +{ + const auto forward = omath::source::ForwardVector({}); + + EXPECT_EQ(forward, omath::source::kAbsForward); +} + +TEST(UnitTestSourceEngine, RightVector) +{ + const auto right = omath::source::RightVector({}); + + EXPECT_EQ(right, omath::source::kAbsRight); +} + +TEST(UnitTestSourceEngine, UpVector) +{ + const auto up = omath::source::UpVector({}); + EXPECT_EQ(up, omath::source::kAbsUp); +} \ No newline at end of file diff --git a/tests/general/UnitTestAngle.cpp b/tests/general/UnitTestAngle.cpp new file mode 100644 index 0000000..66bc0d1 --- /dev/null +++ b/tests/general/UnitTestAngle.cpp @@ -0,0 +1,3 @@ +// +// Created by Orange on 11/30/2024. +// diff --git a/tests/general/UnitTestProjection.cpp b/tests/general/UnitTestProjection.cpp index 3424633..fc0ced4 100644 --- a/tests/general/UnitTestProjection.cpp +++ b/tests/general/UnitTestProjection.cpp @@ -4,16 +4,15 @@ #include #include #include -#include +#include #include +#include TEST(UnitTestProjection, Projection) { - const omath::projection::Camera camera({0.f, 0.f, 0.f}, {0, 0.f, 0.f} , {1920.f, 1080.f}, 110.f, 0.375f, 5000.f, 1.335f); + auto x = omath::Angle::FromDegrees(90.f); + auto cam = omath::source::CreateCamera({-10, 0, 0}, omath::source::ViewAngles{}, {1920.f, 1080.f}, x, 0.1f, 1000.f); - const auto projected = camera.WorldToScreen({5000, 0, 0}); - - - EXPECT_TRUE(projected.has_value()); - EXPECT_EQ(projected->z, 1.f); + const auto projected = cam.WorldToScreen({10, 0, 0}); + std::print("{} {} {}", projected->x, projected->y, projected->z); } \ No newline at end of file From 339dbade7e1dfffdaeb7d97f171a78f7df975ff6 Mon Sep 17 00:00:00 2001 From: Orange Date: Sun, 1 Dec 2024 04:10:25 +0300 Subject: [PATCH 12/24] patch --- include/omath/engines/source.hpp | 8 ++++---- include/omath/projection/Camera.hpp | 11 ++++++++--- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/include/omath/engines/source.hpp b/include/omath/engines/source.hpp index 5bb085e..a5e7ac9 100644 --- a/include/omath/engines/source.hpp +++ b/include/omath/engines/source.hpp @@ -29,10 +29,10 @@ namespace omath::source template requires std::is_floating_point_v || std::is_integral_v - [[nodiscard]] constexpr Mat<4, 4, Type, MatStoreType::COLUMN_MAJOR> ViewMatrixFromVecs(const Vector3& forward, const Vector3& right, + [[nodiscard]] constexpr Mat<4, 4, Type, MatStoreType::ROW_MAJOR> ViewMatrixFromVecs(const Vector3& forward, const Vector3& right, const Vector3& up, const Vector3& camera_pos) { - return MatTranslation(-camera_pos) * Mat<4, 4, Type, MatStoreType::COLUMN_MAJOR>{ + return MatTranslation(-camera_pos) * Mat<4, 4, Type, MatStoreType::ROW_MAJOR>{ {right.x, up.x, forward.x, 0}, {right.y, up.y, forward.y, 0}, {right.z, up.z, forward.z, 0}, @@ -43,14 +43,14 @@ namespace omath::source template requires std::is_floating_point_v || std::is_integral_v - [[nodiscard]] Mat<4, 4, Type, MatStoreType::COLUMN_MAJOR> ViewMatrix(const ViewAngles& angles, const Vector3& cam_origin) + [[nodiscard]] Mat<4, 4, Type, MatStoreType::ROW_MAJOR> ViewMatrix(const ViewAngles& angles, const Vector3& cam_origin) { return ViewMatrixFromVecs(ForwardVector(angles), RightVector(angles), UpVector(angles), cam_origin); } template requires std::is_floating_point_v || std::is_integral_v - [[nodiscard]] Mat<4, 4, Type, MatStoreType::COLUMN_MAJOR> + [[nodiscard]] Mat<4, 4, Type, MatStoreType::ROW_MAJOR> PerspectiveProjectionMatrix(const Type& fieldOfView, const Type& aspectRatio, const Type& near, const Type& far) { const float fovHalfTan = std::tan(angles::DegreesToRadians(fieldOfView) / 2); diff --git a/include/omath/projection/Camera.hpp b/include/omath/projection/Camera.hpp index e190664..0a19dca 100644 --- a/include/omath/projection/Camera.hpp +++ b/include/omath/projection/Camera.hpp @@ -52,13 +52,18 @@ namespace omath::projection return CreateProjectionMatrix(m_fieldOfView.AsDegrees(), m_viewPort.AspectRatio(), m_nearPlaneDistance, m_farPlaneDistance); } + [[nodiscard]] auto GetViewProjectionMatrix() const + { + return GetProjectionMatrix() * GetViewMatrix().Transposed(); + } [[nodiscard]] std::expected WorldToScreen([[maybe_unused]] const Vector3& worldPosition) const { using mat = std::invoke_result_t; - const auto vecAsMatrix = MatColumnFromVector(worldPosition); - - const auto projected = GetViewMatrix().Transposed() * vecAsMatrix; + Mat<4, 1> projected = GetViewProjectionMatrix() * MatColumnFromVector(worldPosition); + if (projected.At(3, 0) == 0.0f) + return std::unexpected(Error::WORLD_POSITION_IS_OUT_OF_SCREEN_BOUNDS); + projected /= projected.At(3, 0); return Vector3{projected.At(0,0), projected.At(1,0), projected.At(2,0)}; } From 5473515ffd2f932928384015d05fe45ac7c82058 Mon Sep 17 00:00:00 2001 From: Orange Date: Sun, 1 Dec 2024 14:06:52 +0300 Subject: [PATCH 13/24] refactored some stuff --- include/omath/Mat.hpp | 12 ++++++------ include/omath/engines/source.hpp | 10 +++++----- include/omath/projection/Camera.hpp | 4 ++-- tests/general/UnitTestMat.cpp | 29 ----------------------------- 4 files changed, 13 insertions(+), 42 deletions(-) diff --git a/include/omath/Mat.hpp b/include/omath/Mat.hpp index 2f25bd5..2840212 100644 --- a/include/omath/Mat.hpp +++ b/include/omath/Mat.hpp @@ -321,10 +321,10 @@ namespace omath constexpr static Mat<4, 4> TranslationMat(const Vector3& diff) noexcept { return { - {1, 0, 0, 0}, - {0, 1, 0, 0}, - {0, 0, 1, 0}, - {diff.x, diff.y, diff.z, 1}, + {1, 0, 0, diff.x}, + {0, 1, 0, diff.y}, + {0, 0, 1, diff.z}, + {0, 0, 0, 1}, }; } @@ -376,11 +376,11 @@ namespace omath [[nodiscard]] constexpr Mat<4, 4, T, St> MatTranslation(const Vector3& diff) noexcept { - return { + return Mat<4, 4, T, St>{ {1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {diff.x, diff.y, diff.z, 1}, - }; + }.Transposed(); } } // namespace omath diff --git a/include/omath/engines/source.hpp b/include/omath/engines/source.hpp index a5e7ac9..669a531 100644 --- a/include/omath/engines/source.hpp +++ b/include/omath/engines/source.hpp @@ -32,12 +32,12 @@ namespace omath::source [[nodiscard]] constexpr Mat<4, 4, Type, MatStoreType::ROW_MAJOR> ViewMatrixFromVecs(const Vector3& forward, const Vector3& right, const Vector3& up, const Vector3& camera_pos) { - return MatTranslation(-camera_pos) * Mat<4, 4, Type, MatStoreType::ROW_MAJOR>{ - {right.x, up.x, forward.x, 0}, - {right.y, up.y, forward.y, 0}, - {right.z, up.z, forward.z, 0}, + return Mat<4, 4, Type, MatStoreType::ROW_MAJOR>{ + {right.x, right.y, right.z, 0}, + {up.x, up.y, up.z, 0}, + {forward.x, forward.y, forward.z, 0}, {0, 0, 0, 1}, - }; + } * MatTranslation(-camera_pos) ; } diff --git a/include/omath/projection/Camera.hpp b/include/omath/projection/Camera.hpp index 0a19dca..3932677 100644 --- a/include/omath/projection/Camera.hpp +++ b/include/omath/projection/Camera.hpp @@ -54,7 +54,7 @@ namespace omath::projection [[nodiscard]] auto GetViewProjectionMatrix() const { - return GetProjectionMatrix() * GetViewMatrix().Transposed(); + return GetProjectionMatrix() * GetViewMatrix(); } [[nodiscard]] std::expected WorldToScreen([[maybe_unused]] const Vector3& worldPosition) const { @@ -65,7 +65,7 @@ namespace omath::projection return std::unexpected(Error::WORLD_POSITION_IS_OUT_OF_SCREEN_BOUNDS); projected /= projected.At(3, 0); - return Vector3{projected.At(0,0), projected.At(1,0), projected.At(2,0)}; + return Vector3{++projected.At(0,0) / 2 * m_viewPort.m_width , ++projected.At(1,0) / 2 * m_viewPort.m_height, projected.At(2,0)}; } ViewPort m_viewPort{}; diff --git a/tests/general/UnitTestMat.cpp b/tests/general/UnitTestMat.cpp index 94d451a..0105c28 100644 --- a/tests/general/UnitTestMat.cpp +++ b/tests/general/UnitTestMat.cpp @@ -154,35 +154,6 @@ TEST_F(UnitTestMat, StaticMethod_ToScreenMat) EXPECT_FLOAT_EQ(screenMat.At(3, 3), 1.0f); } -// Test static method: TranslationMat -TEST_F(UnitTestMat, StaticMethod_TranslationMat) -{ - Vector3 diff{10.0f, 20.0f, 30.0f}; - Mat<4, 4> transMat = Mat<4, 4>::TranslationMat(diff); - EXPECT_FLOAT_EQ(transMat.At(0, 0), 1.0f); - EXPECT_FLOAT_EQ(transMat.At(3, 0), diff.x); - EXPECT_FLOAT_EQ(transMat.At(3, 1), diff.y); - EXPECT_FLOAT_EQ(transMat.At(3, 2), diff.z); - EXPECT_FLOAT_EQ(transMat.At(3, 3), 1.0f); -} - -// Test static method: OrientationMat -TEST_F(UnitTestMat, StaticMethod_OrientationMat) -{ - constexpr Vector3 forward{0.0f, 0.0f, 1.0f}; - constexpr Vector3 right{1.0f, 0.0f, 0.0f}; - constexpr Vector3 up{0.0f, 1.0f, 0.0f}; - constexpr Mat<4, 4> orientMat = Mat<4, 4>::OrientationMat(forward, right, up); - EXPECT_FLOAT_EQ(orientMat.At(0, 0), right.x); - EXPECT_FLOAT_EQ(orientMat.At(0, 1), up.x); - EXPECT_FLOAT_EQ(orientMat.At(0, 2), forward.x); - EXPECT_FLOAT_EQ(orientMat.At(1, 0), right.y); - EXPECT_FLOAT_EQ(orientMat.At(1, 1), up.y); - EXPECT_FLOAT_EQ(orientMat.At(1, 2), forward.y); - EXPECT_FLOAT_EQ(orientMat.At(2, 0), right.z); - EXPECT_FLOAT_EQ(orientMat.At(2, 1), up.z); - EXPECT_FLOAT_EQ(orientMat.At(2, 2), forward.z); -} // Test exception handling in At() method TEST_F(UnitTestMat, Method_At_OutOfRange) From 04a5535ade2af9920040da6cf97c70c8ef258a5c Mon Sep 17 00:00:00 2001 From: Orange Date: Sun, 1 Dec 2024 22:02:16 +0300 Subject: [PATCH 14/24] added multiply factor for source engine matrix --- include/omath/engines/source.hpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/include/omath/engines/source.hpp b/include/omath/engines/source.hpp index 669a531..0aa6e7b 100644 --- a/include/omath/engines/source.hpp +++ b/include/omath/engines/source.hpp @@ -49,15 +49,17 @@ namespace omath::source } template - requires std::is_floating_point_v || std::is_integral_v + requires std::is_arithmetic_v && std::is_signed_v [[nodiscard]] Mat<4, 4, Type, MatStoreType::ROW_MAJOR> PerspectiveProjectionMatrix(const Type& fieldOfView, const Type& aspectRatio, const Type& near, const Type& far) { - const float fovHalfTan = std::tan(angles::DegreesToRadians(fieldOfView) / 2); + constexpr auto kMultiplyFactor = Type(0.75); + + const float fovHalfTan = std::tan(angles::DegreesToRadians(fieldOfView) / 2) * kMultiplyFactor; return { - {static_cast(1) / (aspectRatio * fovHalfTan), 0, 0, 0}, - {0, static_cast(1) / (fovHalfTan), 0, 0}, + {-static_cast(1) / (aspectRatio * fovHalfTan), 0, 0, 0}, + {0, -static_cast(1) / (fovHalfTan), 0, 0}, {0, 0, (far + near) / (far - near), -(static_cast(2) * far * near) / (far - near)}, {0, 0, 1, 0}, }; From 9c0285e353e8f242d64dae4369a4e447ee259fac Mon Sep 17 00:00:00 2001 From: Orange Date: Mon, 2 Dec 2024 10:57:47 +0300 Subject: [PATCH 15/24] added check, removed deprecated code --- include/omath/Mat.hpp | 53 +++++------------------------ include/omath/engines/opengl.hpp | 2 +- include/omath/engines/source.hpp | 2 +- include/omath/projection/Camera.hpp | 19 +++++++++-- 4 files changed, 27 insertions(+), 49 deletions(-) diff --git a/include/omath/Mat.hpp b/include/omath/Mat.hpp index 2840212..a3f1807 100644 --- a/include/omath/Mat.hpp +++ b/include/omath/Mat.hpp @@ -7,7 +7,6 @@ #include #include #include -#include "Angles.hpp" #include "Vector3.hpp" @@ -317,42 +316,6 @@ namespace omath }; } - [[nodiscard]] - constexpr static Mat<4, 4> TranslationMat(const Vector3& diff) noexcept - { - return { - {1, 0, 0, diff.x}, - {0, 1, 0, diff.y}, - {0, 0, 1, diff.z}, - {0, 0, 0, 1}, - }; - } - - [[nodiscard]] - constexpr static Mat<4, 4> OrientationMat(const Vector3& forward, const Vector3& right, - const Vector3& up) noexcept - { - return { - {right.x, up.x, forward.x, 0}, - {right.y, up.y, forward.y, 0}, - {right.z, up.z, forward.z, 0}, - {0, 0, 0, 1}, - }; - } - - [[nodiscard]] - constexpr static Mat<4, 4> ProjectionMat(const Type& fieldOfView, const Type& aspectRatio, const Type& near, - const Type& far, const Type& lensZoom) noexcept - { - const Type& fovHalfTan = std::tan(angles::DegreesToRadians(fieldOfView) / 2); - const Type& frustumHeight = far - near; - - return {{-1 / (aspectRatio * fovHalfTan) * lensZoom, 0, 0, 0}, - {0, -1 / fovHalfTan * lensZoom, 0, 0}, - {0, 0, -far / frustumHeight, -1}, - {0, 0, near * far / frustumHeight, 0}}; - } - private: std::array m_data; }; @@ -368,19 +331,19 @@ namespace omath [[nodiscard]] constexpr static Mat<4, 1, T, St> MatColumnFromVector(const Vector3& vector) noexcept { - return { - {vector.x}, {vector.y}, {vector.z}, {1}}; + return {{vector.x}, {vector.y}, {vector.z}, {1}}; } template [[nodiscard]] constexpr Mat<4, 4, T, St> MatTranslation(const Vector3& diff) noexcept { - return Mat<4, 4, T, St>{ - {1, 0, 0, 0}, - {0, 1, 0, 0}, - {0, 0, 1, 0}, - {diff.x, diff.y, diff.z, 1}, - }.Transposed(); + return + { + {1, 0, 0, diff.x}, + {0, 1, 0, diff.y}, + {0, 0, 1, diff.z}, + {0, 0, 0, 1}, + }; } } // namespace omath diff --git a/include/omath/engines/opengl.hpp b/include/omath/engines/opengl.hpp index bcda994..78d7821 100644 --- a/include/omath/engines/opengl.hpp +++ b/include/omath/engines/opengl.hpp @@ -4,7 +4,7 @@ #pragma once #include "omath/Vector3.hpp" #include "omath/Mat.hpp" - +#include "omath/Angle.hpp" namespace omath::opengl { diff --git a/include/omath/engines/source.hpp b/include/omath/engines/source.hpp index 0aa6e7b..cabbaea 100644 --- a/include/omath/engines/source.hpp +++ b/include/omath/engines/source.hpp @@ -55,7 +55,7 @@ namespace omath::source { constexpr auto kMultiplyFactor = Type(0.75); - const float fovHalfTan = std::tan(angles::DegreesToRadians(fieldOfView) / 2) * kMultiplyFactor; + const Type fovHalfTan = std::tan(angles::DegreesToRadians(fieldOfView) / 2) * kMultiplyFactor; return { {-static_cast(1) / (aspectRatio * fovHalfTan), 0, 0, 0}, diff --git a/include/omath/projection/Camera.hpp b/include/omath/projection/Camera.hpp index 3932677..ba87ba6 100644 --- a/include/omath/projection/Camera.hpp +++ b/include/omath/projection/Camera.hpp @@ -31,6 +31,7 @@ namespace omath::projection std::invoke_result_t> class Camera { + public: Camera(const Vector3& position, const ViewAnglesType& viewAngles, const ViewPort& viewPort, const Angle& fov, const float near, const float far, @@ -56,15 +57,20 @@ namespace omath::projection { return GetProjectionMatrix() * GetViewMatrix(); } - [[nodiscard]] std::expected WorldToScreen([[maybe_unused]] const Vector3& worldPosition) const + + [[nodiscard]] std::expected WorldToScreen(const Vector3& worldPosition) const { using mat = std::invoke_result_t; - Mat<4, 1> projected = GetViewProjectionMatrix() * MatColumnFromVector(worldPosition); + auto projected = GetViewProjectionMatrix() * MatColumnFromVector(worldPosition); if (projected.At(3, 0) == 0.0f) return std::unexpected(Error::WORLD_POSITION_IS_OUT_OF_SCREEN_BOUNDS); + projected /= projected.At(3, 0); + if (IsNdcOutOfBounds(projected)) + return std::unexpected(Error::WORLD_POSITION_IS_OUT_OF_SCREEN_BOUNDS); + return Vector3{++projected.At(0,0) / 2 * m_viewPort.m_width , ++projected.At(1,0) / 2 * m_viewPort.m_height, projected.At(2,0)}; } @@ -75,10 +81,19 @@ namespace omath::projection float m_nearPlaneDistance; private: + ViewAnglesType m_viewAngles; Vector3 m_origin; std::function CreateViewMatrix; std::function CreateProjectionMatrix; + + + template + [[nodiscard]] + constexpr static bool IsNdcOutOfBounds(const Type& ndc) + { + return std::ranges::any_of( ndc.RawArray(), [](const auto& val) { return val < -1 || val > 1; }); + } }; } // namespace omath::projection From 0afa20b4e5d763213c03cc3a89f75a3c325cafa9 Mon Sep 17 00:00:00 2001 From: Orange Date: Wed, 4 Dec 2024 04:58:29 +0300 Subject: [PATCH 16/24] refactored camera --- include/omath/Angle.hpp | 2 +- include/omath/Mat.hpp | 50 +++++++- include/omath/engines/Source/Camera.hpp | 22 ++++ include/omath/engines/Source/Constants.h | 24 ++++ include/omath/engines/Source/Formulas.hpp | 98 ++++++++++++++++ include/omath/engines/opengl.hpp | 44 ++++--- include/omath/engines/source.hpp | 135 ---------------------- include/omath/projection/Camera.hpp | 33 ++---- source/CMakeLists.txt | 3 +- source/engines/CMakeLists.txt | 1 + source/engines/Source/CMakeLists.txt | 1 + source/engines/Source/Camera.cpp | 31 +++++ source/prediction/Projectile.cpp | 4 +- tests/engines/UnitTestOpenGL.cpp | 1 - tests/engines/UnitTestSourceEngine.cpp | 3 +- tests/general/UnitTestProjection.cpp | 4 +- 16 files changed, 262 insertions(+), 194 deletions(-) create mode 100644 include/omath/engines/Source/Camera.hpp create mode 100644 include/omath/engines/Source/Constants.h create mode 100644 include/omath/engines/Source/Formulas.hpp delete mode 100644 include/omath/engines/source.hpp create mode 100644 source/engines/CMakeLists.txt create mode 100644 source/engines/Source/CMakeLists.txt create mode 100644 source/engines/Source/Camera.cpp diff --git a/include/omath/Angle.hpp b/include/omath/Angle.hpp index 9b5c64f..7d50e93 100644 --- a/include/omath/Angle.hpp +++ b/include/omath/Angle.hpp @@ -16,7 +16,7 @@ namespace omath Clamped = 1, }; - template + template requires std::is_arithmetic_v class Angle { diff --git a/include/omath/Mat.hpp b/include/omath/Mat.hpp index a3f1807..3059dd3 100644 --- a/include/omath/Mat.hpp +++ b/include/omath/Mat.hpp @@ -320,23 +320,23 @@ namespace omath std::array m_data; }; - template + template [[nodiscard]] - constexpr static Mat<1, 4, T, St> MatRowFromVector(const Vector3& vector) noexcept + constexpr static Mat<1, 4, Type, St> MatRowFromVector(const Vector3& vector) noexcept { return {{vector.x, vector.y, vector.z, 1}}; } - template + template [[nodiscard]] - constexpr static Mat<4, 1, T, St> MatColumnFromVector(const Vector3& vector) noexcept + constexpr static Mat<4, 1, Type, St> MatColumnFromVector(const Vector3& vector) noexcept { return {{vector.x}, {vector.y}, {vector.z}, {1}}; } - template + template [[nodiscard]] - constexpr Mat<4, 4, T, St> MatTranslation(const Vector3& diff) noexcept + constexpr Mat<4, 4, Type, St> MatTranslation(const Vector3& diff) noexcept { return { @@ -346,4 +346,42 @@ namespace omath {0, 0, 0, 1}, }; } + + template + [[nodiscard]] + constexpr Mat<3, 3, Type, St> RotationMatrixAxisX(const Angle& roll) noexcept + { + return + { + {1, 0, 0}, + {0, 0, roll.Cos(), -roll.Sin()}, + {0, 0, roll.Sin(), roll.Cos()}, + }; + } + + template + [[nodiscard]] + constexpr Mat<3, 3, Type, St> RotationMatrixAxisY(const Angle& pitch) noexcept + { + return + { + {pitch.Cos(), 0, pitch.Sin()}, + {0 , 1, 0}, + {-pitch.Sin(), 0, pitch.Cos()}, + }; + } + + template + [[nodiscard]] + constexpr Mat<3, 3, Type, St> RotationMatrixAxisZ(const Angle& Yaw) noexcept + { + return + { + {Yaw.Cos(), -Yaw.Sin(), 0}, + {Yaw.Sin(), Yaw.Cos(), 0}, + {0, 0, 1}, + }; + } + + } // namespace omath diff --git a/include/omath/engines/Source/Camera.hpp b/include/omath/engines/Source/Camera.hpp new file mode 100644 index 0000000..7e73c98 --- /dev/null +++ b/include/omath/engines/Source/Camera.hpp @@ -0,0 +1,22 @@ +// +// Created by Orange on 12/4/2024. +// +#pragma once +#include "Constants.h" +#include "omath/projection/Camera.hpp" + +namespace omath::source +{ + class Camera final : public projection::Camera + { + public: + Camera(const Vector3& position, const ViewAngles& viewAngles, + const projection::ViewPort& viewPort, const Angle& fov, float near, const float far) : + projection::Camera(position, viewAngles, viewPort, fov, near, far) + { + } + void LookAt(const Vector3& target) override; + [[nodiscard]] Mat4x4 GetViewMatrix() const override; + [[nodiscard]] Mat4x4 GetProjectionMatrix() const override; + }; +} \ No newline at end of file diff --git a/include/omath/engines/Source/Constants.h b/include/omath/engines/Source/Constants.h new file mode 100644 index 0000000..f77b195 --- /dev/null +++ b/include/omath/engines/Source/Constants.h @@ -0,0 +1,24 @@ +// +// Created by Orange on 12/4/2024. +// +#pragma once + +#include +#include +#include +#include +namespace omath::source +{ + 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 PitchAngle = Angle; + using YawAngle = Angle; + using RollAngle = Angle; + + using ViewAngles = omath::ViewAngles; +} // namespace omath::source diff --git a/include/omath/engines/Source/Formulas.hpp b/include/omath/engines/Source/Formulas.hpp new file mode 100644 index 0000000..39e16c3 --- /dev/null +++ b/include/omath/engines/Source/Formulas.hpp @@ -0,0 +1,98 @@ +// +// Created by Orange on 12/4/2024. +// +#pragma once +#include "Constants.h" + + +namespace omath::source +{ + [[nodiscard]] + inline Vector3 ForwardVector(const ViewAngles& angles) + { + const auto cosPitch = angles.pitch.Cos(); + const auto sinPitch = angles.pitch.Sin(); + + const auto cosYaw = angles.yaw.Cos(); + const auto sinYaw = angles.yaw.Sin(); + + + return {cosPitch * cosYaw, cosPitch * sinYaw, -sinPitch}; + } + + [[nodiscard]] + inline Vector3 RightVector(const ViewAngles& angles) + { + const auto cosPitch = angles.pitch.Cos(); + const auto sinPitch = angles.pitch.Sin(); + + const auto cosYaw = angles.yaw.Cos(); + const auto sinYaw = angles.yaw.Sin(); + + const auto cosRoll = angles.roll.Cos(); + const auto sinRoll = angles.roll.Sin(); + + + return + { + -1 * sinRoll * sinPitch * cosYaw + -1 * cosRoll * -sinYaw, + -1 * sinRoll * sinPitch * sinYaw + -1 * cosRoll * cosYaw, + -1 * sinRoll * cosPitch + }; + } + + [[nodiscard]] + inline Vector3 UpVector(const ViewAngles& angles) + { + const auto cosPitch = angles.pitch.Cos(); + const auto sinPitch = angles.pitch.Sin(); + + const auto cosYaw = angles.yaw.Cos(); + const auto sinYaw = angles.yaw.Sin(); + + const auto cosRoll = angles.roll.Cos(); + const auto sinRoll = angles.roll.Sin(); + + + return + { + cosRoll * sinPitch * cosYaw + - sinRoll * -sinYaw, + cosRoll * sinPitch * sinYaw + - sinRoll * cosYaw, + cosRoll * cosPitch, + }; + } + + [[nodiscard]] + constexpr Mat4x4 ViewMatrixFromVecs(const Vector3& forward, const Vector3& right, const Vector3& up, + const Vector3& camera_pos) + { + return Mat4x4{ + {right.x, right.y, right.z, 0}, + {up.x, up.y, up.z, 0}, + {forward.x, forward.y, forward.z, 0}, + {0, 0, 0, 1}, + } * + MatTranslation(-camera_pos); + } + + [[nodiscard]] inline Mat4x4 ViewMatrix(const ViewAngles& angles, const Vector3& cam_origin) + { + return ViewMatrixFromVecs(ForwardVector(angles), RightVector(angles), UpVector(angles), cam_origin); + } + + + [[nodiscard]] + inline Mat4x4 PerspectiveProjectionMatrix(const float fieldOfView, const float aspectRatio, const float near, const float far) + { + 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 diff --git a/include/omath/engines/opengl.hpp b/include/omath/engines/opengl.hpp index 78d7821..68edf9d 100644 --- a/include/omath/engines/opengl.hpp +++ b/include/omath/engines/opengl.hpp @@ -2,9 +2,10 @@ // Created by Orange on 11/23/2024. // #pragma once -#include "omath/Vector3.hpp" -#include "omath/Mat.hpp" + #include "omath/Angle.hpp" +#include "omath/Mat.hpp" +#include "omath/Vector3.hpp" namespace omath::opengl { @@ -14,34 +15,31 @@ namespace omath::opengl template - requires std::is_floating_point_v || std::is_integral_v - [[nodiscard]] Mat<4, 4, Type, MatStoreType::COLUMN_MAJOR> ViewMatrix(const Vector3& forward, - const Vector3& right, - const Vector3& up, - const Vector3& cam_origin) + requires std::is_arithmetic_v + [[nodiscard]] Mat<4, 4, Type, MatStoreType::COLUMN_MAJOR> ViewMatrix(const Vector3& forward, const Vector3& right, + const Vector3& up, const Vector3& cam_origin) { - return + return Mat<4, 4, Type, MatStoreType::COLUMN_MAJOR> { - {right.x, up.x, -forward.x, 0}, - {right.y, up.y, -forward.y, 0}, - {right.z, up.z, -forward.z, 0}, - {-cam_origin.x, -cam_origin.y, -cam_origin.z, 1}, - }; + {right.x, right.y, right.z, 0}, + {up.x, up.y, up.z, 0}, + {-forward.x, -forward.y, -forward.z, 0}, + {0, 0, 0, 1}, + } * MatTranslation(-cam_origin); } template - requires std::is_floating_point_v || std::is_integral_v - [[nodiscard]] Mat<4, 4, Type, MatStoreType::COLUMN_MAJOR> PerspectiveProjectionMatrix( - const float fieldOfView, const Type& aspectRatio, const Type& near, const Type& far) + requires std::is_arithmetic_v + [[nodiscard]] Mat<4, 4, Type, MatStoreType::COLUMN_MAJOR> + PerspectiveProjectionMatrix(const float fieldOfView, const Type& aspectRatio, const Type& near, const Type& far) { const float fovHalfTan = std::tan(angles::DegreesToRadians(fieldOfView) / 2); - return - { - {static_cast(1) / (aspectRatio * fovHalfTan), 0, 0, 0}, - {0, static_cast(1) / (fovHalfTan), 0, 0}, - {0, 0, -(far + near) / (far - near), -(static_cast(2) * far * near) / (far - near)}, - {0, 0, -1, 0}, + return { + {static_cast(1) / (aspectRatio * fovHalfTan), 0, 0, 0}, + {0, static_cast(1) / (fovHalfTan), 0, 0}, + {0, 0, -(far + near) / (far - near), -(static_cast(2) * far * near) / (far - near)}, + {0, 0, -1, 0}, }; } -} +} // namespace omath::opengl diff --git a/include/omath/engines/source.hpp b/include/omath/engines/source.hpp deleted file mode 100644 index cabbaea..0000000 --- a/include/omath/engines/source.hpp +++ /dev/null @@ -1,135 +0,0 @@ -// -// Created by Orange on 11/24/2024. -// -#pragma once -#include "omath/Mat.hpp" -#include "omath/Vector3.hpp" - -#include -#include -#include - -namespace omath::source -{ - constexpr Vector3 kAbsUp = {0, 0, 1}; - constexpr Vector3 kAbsRight = {0, -1, 0}; - constexpr Vector3 kAbsForward = {1, 0, 0}; - - using PitchAngle = Angle; - using YawAngle = Angle; - using RollAngle = Angle; - - using ViewAngles = omath::ViewAngles; - - - inline Vector3 ForwardVector(const ViewAngles& angles); - inline Vector3 RightVector(const ViewAngles& angles); - inline Vector3 UpVector(const ViewAngles& angles); - - - template - requires std::is_floating_point_v || std::is_integral_v - [[nodiscard]] constexpr Mat<4, 4, Type, MatStoreType::ROW_MAJOR> ViewMatrixFromVecs(const Vector3& forward, const Vector3& right, - const Vector3& up, const Vector3& camera_pos) - { - return Mat<4, 4, Type, MatStoreType::ROW_MAJOR>{ - {right.x, right.y, right.z, 0}, - {up.x, up.y, up.z, 0}, - {forward.x, forward.y, forward.z, 0}, - {0, 0, 0, 1}, - } * MatTranslation(-camera_pos) ; - } - - - template - requires std::is_floating_point_v || std::is_integral_v - [[nodiscard]] Mat<4, 4, Type, MatStoreType::ROW_MAJOR> ViewMatrix(const ViewAngles& angles, const Vector3& cam_origin) - { - return ViewMatrixFromVecs(ForwardVector(angles), RightVector(angles), UpVector(angles), cam_origin); - } - - template - requires std::is_arithmetic_v && std::is_signed_v - [[nodiscard]] Mat<4, 4, Type, MatStoreType::ROW_MAJOR> - PerspectiveProjectionMatrix(const Type& fieldOfView, const Type& aspectRatio, const Type& near, const Type& far) - { - constexpr auto kMultiplyFactor = Type(0.75); - - const Type fovHalfTan = std::tan(angles::DegreesToRadians(fieldOfView) / 2) * kMultiplyFactor; - - return { - {-static_cast(1) / (aspectRatio * fovHalfTan), 0, 0, 0}, - {0, -static_cast(1) / (fovHalfTan), 0, 0}, - {0, 0, (far + near) / (far - near), -(static_cast(2) * far * near) / (far - near)}, - {0, 0, 1, 0}, - }; - } - // Copied from - // https://github.com/ValveSoftware/source-sdk-2013/blob/0d8dceea4310fde5706b3ce1c70609d72a38efdf/mp/src/mathlib/mathlib_base.cpp#L919 - [[nodiscard]] - inline Vector3 ForwardVector(const ViewAngles& angles) - { - const auto cosPitch = angles.pitch.Cos(); - const auto sinPitch = angles.pitch.Sin(); - - const auto cosYaw = angles.yaw.Cos(); - const auto sinYaw = angles.yaw.Sin(); - - - return {cosPitch * cosYaw, cosPitch * sinYaw, -sinPitch}; - } - - [[nodiscard]] - inline Vector3 RightVector(const ViewAngles& angles) - { - const auto cosPitch = angles.pitch.Cos(); - const auto sinPitch = angles.pitch.Sin(); - - const auto cosYaw = angles.yaw.Cos(); - const auto sinYaw = angles.yaw.Sin(); - - const auto cosRoll = angles.roll.Cos(); - const auto sinRoll = angles.roll.Sin(); - - - return - { - -1 * sinRoll * sinPitch * cosYaw + -1 * cosRoll * -sinYaw, - -1 * sinRoll * sinPitch * sinYaw + -1 * cosRoll * cosYaw, - -1 * sinRoll * cosPitch - }; - } - - [[nodiscard]] - inline Vector3 UpVector(const ViewAngles& angles) - { - const auto cosPitch = angles.pitch.Cos(); - const auto sinPitch = angles.pitch.Sin(); - - const auto cosYaw = angles.yaw.Cos(); - const auto sinYaw = angles.yaw.Sin(); - - const auto cosRoll = angles.roll.Cos(); - const auto sinRoll = angles.roll.Sin(); - - - return - { - cosRoll * sinPitch * cosYaw + - sinRoll * -sinYaw, - cosRoll * sinPitch * sinYaw + - sinRoll * cosYaw, - cosRoll * cosPitch, - }; - } - using Camera = omath::projection::Camera), decltype(PerspectiveProjectionMatrix)>; - - - // Camera(const Vector3& position, const ViewAnglesType& viewAngles, const ViewPort& viewPort, - // const Angle& fov, const float near, const float far, - // const std::function& viewMatFunc, const std::function& projFunc) - - inline Camera CreateCamera(const Vector3& position, const auto& viewAngles, const projection::ViewPort& viewPort, - const Angle& fov, const float near, const float far) - { - return Camera(position, viewAngles, viewPort, fov, near, far, ViewMatrix, PerspectiveProjectionMatrix); - } -} // namespace omath::source diff --git a/include/omath/projection/Camera.hpp b/include/omath/projection/Camera.hpp index ba87ba6..c94da1f 100644 --- a/include/omath/projection/Camera.hpp +++ b/include/omath/projection/Camera.hpp @@ -26,42 +26,33 @@ namespace omath::projection } }; - template - requires std::is_same_v, - std::invoke_result_t> + template class Camera { public: + virtual ~Camera() = default; Camera(const Vector3& position, const ViewAnglesType& viewAngles, const ViewPort& viewPort, - const Angle& fov, const float near, const float far, - const std::function& viewMatFunc, const std::function& projFunc) : + const Angle& fov, const float near, const float far) : m_viewPort(viewPort), m_fieldOfView(fov), m_farPlaneDistance(far), m_nearPlaneDistance(near), - m_viewAngles(viewAngles), m_origin(position), CreateViewMatrix(viewMatFunc), CreateProjectionMatrix(projFunc) + m_viewAngles(viewAngles), m_origin(position) { } - void LookAt(const Vector3& target); + virtual void LookAt(const Vector3& target) = 0; - [[nodiscard]] auto GetViewMatrix() const - { - return CreateViewMatrix(m_viewAngles, m_origin); - } + [[nodiscard]] virtual Mat4x4Type GetViewMatrix() const = 0; - [[nodiscard]] auto GetProjectionMatrix() const - { - return CreateProjectionMatrix(m_fieldOfView.AsDegrees(), m_viewPort.AspectRatio(), m_nearPlaneDistance, m_farPlaneDistance); - } + [[nodiscard]] virtual Mat4x4Type GetProjectionMatrix() const = 0; - [[nodiscard]] auto GetViewProjectionMatrix() const + [[nodiscard]] Mat4x4Type GetViewProjectionMatrix() const { return GetProjectionMatrix() * GetViewMatrix(); } [[nodiscard]] std::expected WorldToScreen(const Vector3& worldPosition) const { - using mat = std::invoke_result_t; - auto projected = GetViewProjectionMatrix() * MatColumnFromVector(worldPosition); + auto projected = GetViewProjectionMatrix() * MatColumnFromVector(worldPosition); if (projected.At(3, 0) == 0.0f) return std::unexpected(Error::WORLD_POSITION_IS_OUT_OF_SCREEN_BOUNDS); @@ -74,20 +65,18 @@ namespace omath::projection return Vector3{++projected.At(0,0) / 2 * m_viewPort.m_width , ++projected.At(1,0) / 2 * m_viewPort.m_height, projected.At(2,0)}; } + protected: ViewPort m_viewPort{}; Angle m_fieldOfView; float m_farPlaneDistance; float m_nearPlaneDistance; - private: ViewAnglesType m_viewAngles; Vector3 m_origin; - std::function CreateViewMatrix; - std::function CreateProjectionMatrix; - + private: template [[nodiscard]] diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index ab4e824..0e0ea74 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -10,4 +10,5 @@ target_sources(omath PRIVATE add_subdirectory(prediction) add_subdirectory(pathfinding) add_subdirectory(projection) -add_subdirectory(collision) \ No newline at end of file +add_subdirectory(collision) +add_subdirectory(engines) \ No newline at end of file diff --git a/source/engines/CMakeLists.txt b/source/engines/CMakeLists.txt new file mode 100644 index 0000000..f01db76 --- /dev/null +++ b/source/engines/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(Source) \ No newline at end of file diff --git a/source/engines/Source/CMakeLists.txt b/source/engines/Source/CMakeLists.txt new file mode 100644 index 0000000..0abf868 --- /dev/null +++ b/source/engines/Source/CMakeLists.txt @@ -0,0 +1 @@ +target_sources(omath PRIVATE Camera.cpp) \ No newline at end of file diff --git a/source/engines/Source/Camera.cpp b/source/engines/Source/Camera.cpp new file mode 100644 index 0000000..285d930 --- /dev/null +++ b/source/engines/Source/Camera.cpp @@ -0,0 +1,31 @@ +// +// Created by Orange on 12/4/2024. +// +#include "omath/engines/Source/Camera.hpp" +#include "omath/engines/Source/Formulas.hpp" + + +namespace omath::source +{ + + void Camera::LookAt(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::GetViewMatrix() const + { + return ViewMatrix(m_viewAngles, m_origin); + } + + Mat4x4 Camera::GetProjectionMatrix() const + { + return PerspectiveProjectionMatrix(m_fieldOfView.AsDegrees(), m_viewPort.AspectRatio(), m_nearPlaneDistance, m_farPlaneDistance); + } +} // namespace omath::source diff --git a/source/prediction/Projectile.cpp b/source/prediction/Projectile.cpp index 3ceb951..3c58d29 100644 --- a/source/prediction/Projectile.cpp +++ b/source/prediction/Projectile.cpp @@ -4,13 +4,13 @@ #include "omath/prediction/Projectile.hpp" #include -#include +#include namespace omath::prediction { Vector3 Projectile::PredictPosition(const float pitch, const float yaw, const float time, const float gravity) const { - auto currentPos = m_origin + omath::source::ForwardVector({source::PitchAngle::FromDegrees(pitch), source::YawAngle::FromDegrees(yaw), source::RollAngle::FromDegrees(0)}) * m_launchSpeed * time; + auto currentPos = m_origin + omath::source::ForwardVector({source::PitchAngle::FromDegrees(-pitch), source::YawAngle::FromDegrees(yaw), source::RollAngle::FromDegrees(0)}) * m_launchSpeed * time; currentPos.z -= (gravity * m_gravityScale) * std::pow(time, 2.f) * 0.5f; return currentPos; diff --git a/tests/engines/UnitTestOpenGL.cpp b/tests/engines/UnitTestOpenGL.cpp index cbe252b..1ea9459 100644 --- a/tests/engines/UnitTestOpenGL.cpp +++ b/tests/engines/UnitTestOpenGL.cpp @@ -6,7 +6,6 @@ #include #include #include -#include // #include // #include "glm/ext/matrix_clip_space.hpp" diff --git a/tests/engines/UnitTestSourceEngine.cpp b/tests/engines/UnitTestSourceEngine.cpp index 9c1861f..28a5805 100644 --- a/tests/engines/UnitTestSourceEngine.cpp +++ b/tests/engines/UnitTestSourceEngine.cpp @@ -2,7 +2,8 @@ // Created by Orange on 11/23/2024. // #include -#include +#include +#include diff --git a/tests/general/UnitTestProjection.cpp b/tests/general/UnitTestProjection.cpp index fc0ced4..70fce84 100644 --- a/tests/general/UnitTestProjection.cpp +++ b/tests/general/UnitTestProjection.cpp @@ -4,14 +4,14 @@ #include #include #include -#include +#include #include #include TEST(UnitTestProjection, Projection) { auto x = omath::Angle::FromDegrees(90.f); - auto cam = omath::source::CreateCamera({-10, 0, 0}, omath::source::ViewAngles{}, {1920.f, 1080.f}, x, 0.1f, 1000.f); + auto cam = omath::source::Camera({-10, 0, 0}, omath::source::ViewAngles{}, {1920.f, 1080.f}, x, 0.1f, 1000.f); const auto projected = cam.WorldToScreen({10, 0, 0}); std::print("{} {} {}", projected->x, projected->y, projected->z); From db060e7f4d6dc54741fc4fe333f7d1f4f38fbd2f Mon Sep 17 00:00:00 2001 From: Orange Date: Wed, 4 Dec 2024 06:15:03 +0300 Subject: [PATCH 17/24] fixed bug --- include/omath/Angle.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/omath/Angle.hpp b/include/omath/Angle.hpp index 7d50e93..b46da50 100644 --- a/include/omath/Angle.hpp +++ b/include/omath/Angle.hpp @@ -65,7 +65,7 @@ namespace omath [[nodiscard]] constexpr Type AsRadians() const { - return angles::RadiansToDegrees(m_angle); + return angles::DegreesToRadians(m_angle); } [[nodiscard]] From 95c5073d86cf4ca7a30ee3aa8dfb2230d20fdda0 Mon Sep 17 00:00:00 2001 From: Orange Date: Wed, 4 Dec 2024 06:43:54 +0300 Subject: [PATCH 18/24] added rotation matrix --- include/omath/Mat.hpp | 19 ++++++---- include/omath/engines/Source/Formulas.hpp | 43 ++++------------------- 2 files changed, 18 insertions(+), 44 deletions(-) diff --git a/include/omath/Mat.hpp b/include/omath/Mat.hpp index 3059dd3..7f6aae5 100644 --- a/include/omath/Mat.hpp +++ b/include/omath/Mat.hpp @@ -349,19 +349,19 @@ namespace omath template [[nodiscard]] - constexpr Mat<3, 3, Type, St> RotationMatrixAxisX(const Angle& roll) noexcept + Mat<3, 3, Type, St> RotationMatAxisX(const Angle& roll) noexcept { return { - {1, 0, 0}, - {0, 0, roll.Cos(), -roll.Sin()}, - {0, 0, roll.Sin(), roll.Cos()}, + {1, 0, 0}, + {0, roll.Cos(), -roll.Sin()}, + {0, roll.Sin(), roll.Cos()}, }; } template [[nodiscard]] - constexpr Mat<3, 3, Type, St> RotationMatrixAxisY(const Angle& pitch) noexcept + Mat<3, 3, Type, St> RotationMatAxisY(const Angle& pitch) noexcept { return { @@ -373,7 +373,7 @@ namespace omath template [[nodiscard]] - constexpr Mat<3, 3, Type, St> RotationMatrixAxisZ(const Angle& Yaw) noexcept + Mat<3, 3, Type, St> RotationMatAxisZ(const Angle& Yaw) noexcept { return { @@ -383,5 +383,10 @@ namespace omath }; } - + template + [[nodiscard]] + Mat<3, 3, Type, St> RotationMat(const ViewAngles& angles) noexcept + { + return RotationMatAxisY(angles.pitch) * RotationMatAxisZ(angles.yaw) * RotationMatAxisX(angles.roll); + } } // namespace omath diff --git a/include/omath/engines/Source/Formulas.hpp b/include/omath/engines/Source/Formulas.hpp index 39e16c3..0721d96 100644 --- a/include/omath/engines/Source/Formulas.hpp +++ b/include/omath/engines/Source/Formulas.hpp @@ -10,56 +10,25 @@ namespace omath::source [[nodiscard]] inline Vector3 ForwardVector(const ViewAngles& angles) { - const auto cosPitch = angles.pitch.Cos(); - const auto sinPitch = angles.pitch.Sin(); + const auto vec = RotationMat(angles) * Mat<3, 1>({{kAbsForward.x}, {kAbsForward.y}, {kAbsForward.z}}); - const auto cosYaw = angles.yaw.Cos(); - const auto sinYaw = angles.yaw.Sin(); - - - return {cosPitch * cosYaw, cosPitch * sinYaw, -sinPitch}; + return {vec.At(0, 0), vec.At(1, 0), vec.At(2, 0)}; } [[nodiscard]] inline Vector3 RightVector(const ViewAngles& angles) { - const auto cosPitch = angles.pitch.Cos(); - const auto sinPitch = angles.pitch.Sin(); + const auto vec = RotationMat(angles) * Mat<3, 1>({{kAbsRight.x}, {kAbsRight.y}, {kAbsRight.z}}); - const auto cosYaw = angles.yaw.Cos(); - const auto sinYaw = angles.yaw.Sin(); - - const auto cosRoll = angles.roll.Cos(); - const auto sinRoll = angles.roll.Sin(); - - - return - { - -1 * sinRoll * sinPitch * cosYaw + -1 * cosRoll * -sinYaw, - -1 * sinRoll * sinPitch * sinYaw + -1 * cosRoll * cosYaw, - -1 * sinRoll * cosPitch - }; + return {vec.At(0, 0), vec.At(1, 0), vec.At(2, 0)}; } [[nodiscard]] inline Vector3 UpVector(const ViewAngles& angles) { - const auto cosPitch = angles.pitch.Cos(); - const auto sinPitch = angles.pitch.Sin(); + const auto vec = RotationMat(angles) * Mat<3, 1>({{kAbsUp.x}, {kAbsUp.y}, {kAbsUp.z}}); - const auto cosYaw = angles.yaw.Cos(); - const auto sinYaw = angles.yaw.Sin(); - - const auto cosRoll = angles.roll.Cos(); - const auto sinRoll = angles.roll.Sin(); - - - return - { - cosRoll * sinPitch * cosYaw + - sinRoll * -sinYaw, - cosRoll * sinPitch * sinYaw + - sinRoll * cosYaw, - cosRoll * cosPitch, - }; + return {vec.At(0, 0), vec.At(1, 0), vec.At(2, 0)}; } [[nodiscard]] From e0dd432e69c73d8b62e2221095086f5610368410 Mon Sep 17 00:00:00 2001 From: Orange Date: Wed, 4 Dec 2024 12:09:23 +0300 Subject: [PATCH 19/24] switched to 4x4 --- include/omath/Mat.hpp | 31 +++++++++++++---------- include/omath/engines/Source/Formulas.hpp | 8 +++--- 2 files changed, 21 insertions(+), 18 deletions(-) diff --git a/include/omath/Mat.hpp b/include/omath/Mat.hpp index 7f6aae5..84628da 100644 --- a/include/omath/Mat.hpp +++ b/include/omath/Mat.hpp @@ -349,44 +349,47 @@ namespace omath template [[nodiscard]] - Mat<3, 3, Type, St> RotationMatAxisX(const Angle& roll) noexcept + Mat<4, 4, Type, St> RotationMatAxisX(const Angle& angle) noexcept { return { - {1, 0, 0}, - {0, roll.Cos(), -roll.Sin()}, - {0, roll.Sin(), roll.Cos()}, + {1, 0, 0, 0}, + {0, angle.Cos(), -angle.Sin(), 0}, + {0, angle.Sin(), angle.Cos(), 0}, + {0, 0, 0, 1} }; } template [[nodiscard]] - Mat<3, 3, Type, St> RotationMatAxisY(const Angle& pitch) noexcept + Mat<4, 4, Type, St> RotationMatAxisY(const Angle& angle) noexcept { return { - {pitch.Cos(), 0, pitch.Sin()}, - {0 , 1, 0}, - {-pitch.Sin(), 0, pitch.Cos()}, + {angle.Cos(), 0, angle.Sin(), 0}, + {0 , 1, 0, 0}, + {-angle.Sin(), 0, angle.Cos(), 0}, + {0 , 0, 0, 1} }; } template [[nodiscard]] - Mat<3, 3, Type, St> RotationMatAxisZ(const Angle& Yaw) noexcept + Mat<4, 4, Type, St> RotationMatAxisZ(const Angle& angle) noexcept { return { - {Yaw.Cos(), -Yaw.Sin(), 0}, - {Yaw.Sin(), Yaw.Cos(), 0}, - {0, 0, 1}, + {angle.Cos(), -angle.Sin(), 0, 0}, + {angle.Sin(), angle.Cos(), 0, 0}, + {0, 0, 1, 0}, + {0, 0, 0, 1}, }; } template [[nodiscard]] - Mat<3, 3, Type, St> RotationMat(const ViewAngles& angles) noexcept + Mat<4, 4, Type, St> RotationMat(const ViewAngles& angles) noexcept { - return RotationMatAxisY(angles.pitch) * RotationMatAxisZ(angles.yaw) * RotationMatAxisX(angles.roll); + return RotationMatAxisZ(angles.yaw) * RotationMatAxisY(angles.pitch) * RotationMatAxisX(angles.roll); } } // namespace omath diff --git a/include/omath/engines/Source/Formulas.hpp b/include/omath/engines/Source/Formulas.hpp index 0721d96..28a37c6 100644 --- a/include/omath/engines/Source/Formulas.hpp +++ b/include/omath/engines/Source/Formulas.hpp @@ -10,7 +10,7 @@ namespace omath::source [[nodiscard]] inline Vector3 ForwardVector(const ViewAngles& angles) { - const auto vec = RotationMat(angles) * Mat<3, 1>({{kAbsForward.x}, {kAbsForward.y}, {kAbsForward.z}}); + const auto vec = RotationMat(angles) * MatColumnFromVector(kAbsForward); return {vec.At(0, 0), vec.At(1, 0), vec.At(2, 0)}; } @@ -18,7 +18,7 @@ namespace omath::source [[nodiscard]] inline Vector3 RightVector(const ViewAngles& angles) { - const auto vec = RotationMat(angles) * Mat<3, 1>({{kAbsRight.x}, {kAbsRight.y}, {kAbsRight.z}}); + const auto vec = RotationMat(angles) * MatColumnFromVector(kAbsRight); return {vec.At(0, 0), vec.At(1, 0), vec.At(2, 0)}; } @@ -26,7 +26,7 @@ namespace omath::source [[nodiscard]] inline Vector3 UpVector(const ViewAngles& angles) { - const auto vec = RotationMat(angles) * Mat<3, 1>({{kAbsUp.x}, {kAbsUp.y}, {kAbsUp.z}}); + const auto vec = RotationMat(angles) * MatColumnFromVector(kAbsUp); return {vec.At(0, 0), vec.At(1, 0), vec.At(2, 0)}; } @@ -58,7 +58,7 @@ namespace omath::source const float fovHalfTan = std::tan(angles::DegreesToRadians(fieldOfView) / 2.f) * kMultiplyFactor; return { - {-1.f / (aspectRatio * fovHalfTan), 0, 0, 0}, + {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}, From 0587ee440d49361ce92f9c83c8df01f7a80334ae Mon Sep 17 00:00:00 2001 From: Orange Date: Wed, 4 Dec 2024 12:27:17 +0300 Subject: [PATCH 20/24] fixed view matrix --- include/omath/engines/Source/Formulas.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/omath/engines/Source/Formulas.hpp b/include/omath/engines/Source/Formulas.hpp index 28a37c6..8a9c9e8 100644 --- a/include/omath/engines/Source/Formulas.hpp +++ b/include/omath/engines/Source/Formulas.hpp @@ -37,7 +37,7 @@ namespace omath::source { return Mat4x4{ {right.x, right.y, right.z, 0}, - {up.x, up.y, up.z, 0}, + {-up.x, -up.y, -up.z, 0}, {forward.x, forward.y, forward.z, 0}, {0, 0, 0, 1}, } * @@ -59,7 +59,7 @@ namespace omath::source 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}, }; From 4b50ac8c1d60593b3457030da287264349ef7980 Mon Sep 17 00:00:00 2001 From: Orange Date: Wed, 4 Dec 2024 16:04:41 +0300 Subject: [PATCH 21/24] optimized view proj matrix generation --- include/omath/projection/Camera.hpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/include/omath/projection/Camera.hpp b/include/omath/projection/Camera.hpp index c94da1f..a6723a1 100644 --- a/include/omath/projection/Camera.hpp +++ b/include/omath/projection/Camera.hpp @@ -37,6 +37,7 @@ namespace omath::projection m_viewPort(viewPort), m_fieldOfView(fov), m_farPlaneDistance(far), m_nearPlaneDistance(near), m_viewAngles(viewAngles), m_origin(position) { + } virtual void LookAt(const Vector3& target) = 0; @@ -45,12 +46,15 @@ namespace omath::projection [[nodiscard]] virtual Mat4x4Type GetProjectionMatrix() const = 0; - [[nodiscard]] Mat4x4Type GetViewProjectionMatrix() const + [[nodiscard]] Mat4x4Type GetViewProjectionMatrix() { - return GetProjectionMatrix() * GetViewMatrix(); + if (!m_viewProjectionMatrix) + m_viewProjectionMatrix = GetProjectionMatrix() * GetViewMatrix(); + + return m_viewProjectionMatrix.value(); } - [[nodiscard]] std::expected WorldToScreen(const Vector3& worldPosition) const + [[nodiscard]] std::expected WorldToScreen(const Vector3& worldPosition) { auto projected = GetViewProjectionMatrix() * MatColumnFromVector(worldPosition); @@ -77,7 +81,7 @@ namespace omath::projection Vector3 m_origin; private: - + std::optional m_viewProjectionMatrix = std::nullopt; template [[nodiscard]] constexpr static bool IsNdcOutOfBounds(const Type& ndc) From ecdd9ecdd6f584b816caa20e0c3072740066c42d Mon Sep 17 00:00:00 2001 From: Orange Date: Sun, 8 Dec 2024 05:19:49 +0300 Subject: [PATCH 22/24] improved some code --- include/omath/Angle.hpp | 6 +++ include/omath/Mat.hpp | 31 +++++++++++---- include/omath/engines/OpenGL/Constants.hpp | 14 +++++++ include/omath/engines/OpenGL/Formulas.hpp | 4 ++ .../engines/{opengl.hpp => OpenGL/OpenGL.hpp} | 0 include/omath/engines/Source/Camera.hpp | 7 +--- include/omath/engines/Source/Constants.h | 2 +- include/omath/engines/Source/Formulas.hpp | 39 +++++++------------ include/omath/projection/Camera.hpp | 15 +++---- source/engines/Source/Camera.cpp | 11 ++++-- tests/engines/UnitTestOpenGL.cpp | 12 +----- tests/engines/UnitTestSourceEngine.cpp | 28 +++++++++++-- tests/general/UnitTestProjection.cpp | 4 +- 13 files changed, 106 insertions(+), 67 deletions(-) create mode 100644 include/omath/engines/OpenGL/Constants.hpp create mode 100644 include/omath/engines/OpenGL/Formulas.hpp rename include/omath/engines/{opengl.hpp => OpenGL/OpenGL.hpp} (100%) diff --git a/include/omath/Angle.hpp b/include/omath/Angle.hpp index b46da50..26c6ebf 100644 --- a/include/omath/Angle.hpp +++ b/include/omath/Angle.hpp @@ -144,5 +144,11 @@ namespace omath { return operator+(-other); } + + [[nodiscard]] + constexpr Angle operator-() const + { + return {-m_angle}; + } }; } diff --git a/include/omath/Mat.hpp b/include/omath/Mat.hpp index 84628da..66ade7e 100644 --- a/include/omath/Mat.hpp +++ b/include/omath/Mat.hpp @@ -349,7 +349,7 @@ namespace omath template [[nodiscard]] - Mat<4, 4, Type, St> RotationMatAxisX(const Angle& angle) noexcept + Mat<4, 4, Type, St> MatRotationAxisX(const Angle& angle) noexcept { return { @@ -362,7 +362,7 @@ namespace omath template [[nodiscard]] - Mat<4, 4, Type, St> RotationMatAxisY(const Angle& angle) noexcept + Mat<4, 4, Type, St> MatRotationAxisY(const Angle& angle) noexcept { return { @@ -375,21 +375,36 @@ namespace omath template [[nodiscard]] - Mat<4, 4, Type, St> RotationMatAxisZ(const Angle& angle) noexcept + Mat<4, 4, Type, St> MatRotationAxisZ(const Angle& angle) noexcept { return { {angle.Cos(), -angle.Sin(), 0, 0}, - {angle.Sin(), angle.Cos(), 0, 0}, - {0, 0, 1, 0}, - {0, 0, 0, 1}, + {angle.Sin(), angle.Cos(), 0, 0}, + { 0, 0, 1, 0}, + { 0, 0, 0, 1}, }; } + template + [[nodiscard]] + static Mat<4, 4, Type, St> MatCameraView(const Vector3& forward, const Vector3& right, const Vector3& up, + const Vector3& cameraOrigin) noexcept + { + return Mat<4, 4, Type, St> + { + {right.x, right.y, right.z, 0}, + {up.x, up.y, up.z, 0}, + {forward.x, forward.y, forward.z, 0}, + {0, 0, 0, 1}, + + } * MatTranslation(-cameraOrigin); + } + template [[nodiscard]] - Mat<4, 4, Type, St> RotationMat(const ViewAngles& angles) noexcept + Mat<4, 4, Type, St> MatRotation(const ViewAngles& angles) noexcept { - return RotationMatAxisZ(angles.yaw) * RotationMatAxisY(angles.pitch) * RotationMatAxisX(angles.roll); + return MatRotationAxisZ(angles.yaw) * MatRotationAxisY(angles.pitch) * MatRotationAxisX(angles.roll); } } // namespace omath diff --git a/include/omath/engines/OpenGL/Constants.hpp b/include/omath/engines/OpenGL/Constants.hpp new file mode 100644 index 0000000..aec3520 --- /dev/null +++ b/include/omath/engines/OpenGL/Constants.hpp @@ -0,0 +1,14 @@ +// +// Created by Orange on 12/4/2024. +// +#pragma once + +#include + + +namespace omath::opengl +{ + constexpr Vector3 kAbsUp = {0, 1, 0}; + constexpr Vector3 kAbsRight = {1, 0, 0}; + constexpr Vector3 kAbsForward = {0, 0, -1}; +} \ No newline at end of file diff --git a/include/omath/engines/OpenGL/Formulas.hpp b/include/omath/engines/OpenGL/Formulas.hpp new file mode 100644 index 0000000..2a50756 --- /dev/null +++ b/include/omath/engines/OpenGL/Formulas.hpp @@ -0,0 +1,4 @@ +// +// Created by Orange on 12/4/2024. +// +#pragma once \ No newline at end of file diff --git a/include/omath/engines/opengl.hpp b/include/omath/engines/OpenGL/OpenGL.hpp similarity index 100% rename from include/omath/engines/opengl.hpp rename to include/omath/engines/OpenGL/OpenGL.hpp diff --git a/include/omath/engines/Source/Camera.hpp b/include/omath/engines/Source/Camera.hpp index 7e73c98..aca13cf 100644 --- a/include/omath/engines/Source/Camera.hpp +++ b/include/omath/engines/Source/Camera.hpp @@ -10,11 +10,8 @@ namespace omath::source class Camera final : public projection::Camera { public: - Camera(const Vector3& position, const ViewAngles& viewAngles, - const projection::ViewPort& viewPort, const Angle& fov, float near, const float far) : - projection::Camera(position, viewAngles, viewPort, fov, near, far) - { - } + Camera(const Vector3& position, const ViewAngles& viewAngles, const projection::ViewPort& viewPort, + const Angle& fov, float near, float far); void LookAt(const Vector3& target) override; [[nodiscard]] Mat4x4 GetViewMatrix() const override; [[nodiscard]] Mat4x4 GetProjectionMatrix() const override; diff --git a/include/omath/engines/Source/Constants.h b/include/omath/engines/Source/Constants.h index f77b195..ecf1b40 100644 --- a/include/omath/engines/Source/Constants.h +++ b/include/omath/engines/Source/Constants.h @@ -15,7 +15,7 @@ namespace omath::source 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; diff --git a/include/omath/engines/Source/Formulas.hpp b/include/omath/engines/Source/Formulas.hpp index 8a9c9e8..652f263 100644 --- a/include/omath/engines/Source/Formulas.hpp +++ b/include/omath/engines/Source/Formulas.hpp @@ -10,7 +10,7 @@ namespace omath::source [[nodiscard]] inline Vector3 ForwardVector(const ViewAngles& angles) { - const auto vec = RotationMat(angles) * MatColumnFromVector(kAbsForward); + const auto vec = MatRotation(angles) * MatColumnFromVector(kAbsForward); return {vec.At(0, 0), vec.At(1, 0), vec.At(2, 0)}; } @@ -18,7 +18,7 @@ namespace omath::source [[nodiscard]] inline Vector3 RightVector(const ViewAngles& angles) { - const auto vec = RotationMat(angles) * MatColumnFromVector(kAbsRight); + const auto vec = MatRotation(angles) * MatColumnFromVector(kAbsRight); return {vec.At(0, 0), vec.At(1, 0), vec.At(2, 0)}; } @@ -26,42 +26,33 @@ namespace omath::source [[nodiscard]] inline Vector3 UpVector(const ViewAngles& angles) { - const auto vec = RotationMat(angles) * MatColumnFromVector(kAbsUp); + const auto vec = MatRotation(angles) * MatColumnFromVector(kAbsUp); return {vec.At(0, 0), vec.At(1, 0), vec.At(2, 0)}; } - [[nodiscard]] - constexpr Mat4x4 ViewMatrixFromVecs(const Vector3& forward, const Vector3& right, const Vector3& up, - const Vector3& camera_pos) + [[nodiscard]] inline Mat4x4 CalcViewMatrix(const ViewAngles& angles, const Vector3& cam_origin) { - return Mat4x4{ - {right.x, right.y, right.z, 0}, - {-up.x, -up.y, -up.z, 0}, - {forward.x, forward.y, forward.z, 0}, - {0, 0, 0, 1}, - } * - MatTranslation(-camera_pos); - } - - [[nodiscard]] inline Mat4x4 ViewMatrix(const ViewAngles& angles, const Vector3& cam_origin) - { - return ViewMatrixFromVecs(ForwardVector(angles), RightVector(angles), UpVector(angles), cam_origin); + return MatCameraView(ForwardVector(angles), RightVector(angles), UpVector(angles), cam_origin); } [[nodiscard]] - inline Mat4x4 PerspectiveProjectionMatrix(const float fieldOfView, const float aspectRatio, const float near, const float far) + inline Mat4x4 CalcPerspectiveProjectionMatrix(const float fieldOfView, const float aspectRatio, const float near, + const float far) { + // NOTE: Needed tp make thing draw normal, since source is wierd + // and use tricky projection matrix formula. 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}, - }; + {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/include/omath/projection/Camera.hpp b/include/omath/projection/Camera.hpp index a6723a1..15db451 100644 --- a/include/omath/projection/Camera.hpp +++ b/include/omath/projection/Camera.hpp @@ -25,6 +25,7 @@ namespace omath::projection return m_width / m_height; } }; + using FieldOfView = const Angle; template class Camera @@ -33,7 +34,7 @@ namespace omath::projection public: virtual ~Camera() = default; Camera(const Vector3& position, const ViewAnglesType& viewAngles, const ViewPort& viewPort, - const Angle& fov, const float near, const float far) : + const FieldOfView& fov, const float near, const float far) : m_viewPort(viewPort), m_fieldOfView(fov), m_farPlaneDistance(far), m_nearPlaneDistance(near), m_viewAngles(viewAngles), m_origin(position) { @@ -48,15 +49,12 @@ namespace omath::projection [[nodiscard]] Mat4x4Type GetViewProjectionMatrix() { - if (!m_viewProjectionMatrix) - m_viewProjectionMatrix = GetProjectionMatrix() * GetViewMatrix(); - - return m_viewProjectionMatrix.value(); + return GetProjectionMatrix() * GetViewMatrix(); } - [[nodiscard]] std::expected WorldToScreen(const Vector3& worldPosition) + [[nodiscard]] std::expected WorldToScreen(const Mat4x4Type& viewProj, const Vector3& worldPosition) const { - auto projected = GetViewProjectionMatrix() * MatColumnFromVector(worldPosition); + auto projected = viewProj * MatColumnFromVector(worldPosition); if (projected.At(3, 0) == 0.0f) return std::unexpected(Error::WORLD_POSITION_IS_OUT_OF_SCREEN_BOUNDS); @@ -66,7 +64,7 @@ namespace omath::projection if (IsNdcOutOfBounds(projected)) return std::unexpected(Error::WORLD_POSITION_IS_OUT_OF_SCREEN_BOUNDS); - return Vector3{++projected.At(0,0) / 2 * m_viewPort.m_width , ++projected.At(1,0) / 2 * m_viewPort.m_height, projected.At(2,0)}; + return Vector3{(projected.At(0,0)+1) / 2 * m_viewPort.m_width , (-projected.At(1,0)+1) / 2 * m_viewPort.m_height, projected.At(2,0)}; } protected: @@ -81,7 +79,6 @@ namespace omath::projection Vector3 m_origin; private: - std::optional m_viewProjectionMatrix = std::nullopt; template [[nodiscard]] constexpr static bool IsNdcOutOfBounds(const Type& ndc) diff --git a/source/engines/Source/Camera.cpp b/source/engines/Source/Camera.cpp index 285d930..51eb507 100644 --- a/source/engines/Source/Camera.cpp +++ b/source/engines/Source/Camera.cpp @@ -8,6 +8,11 @@ namespace omath::source { + Camera::Camera(const Vector3& position, const ViewAngles& viewAngles, const projection::ViewPort& viewPort, + const projection::FieldOfView& fov, const float near, const float far) : + projection::Camera(position, viewAngles, viewPort, fov, near, far) + { + } void Camera::LookAt(const Vector3& target) { const float distance = m_origin.DistTo(target); @@ -15,17 +20,17 @@ namespace omath::source m_viewAngles.pitch = PitchAngle::FromRadians(std::asin(delta.z / distance)); - m_viewAngles.yaw = YawAngle::FromRadians(std::atan2(delta.y, delta.x)); + m_viewAngles.yaw = -YawAngle::FromRadians(std::atan2(delta.y, delta.x)); m_viewAngles.roll = RollAngle::FromRadians(0.f); } Mat4x4 Camera::GetViewMatrix() const { - return ViewMatrix(m_viewAngles, m_origin); + return CalcViewMatrix(m_viewAngles, m_origin); } Mat4x4 Camera::GetProjectionMatrix() const { - return PerspectiveProjectionMatrix(m_fieldOfView.AsDegrees(), m_viewPort.AspectRatio(), m_nearPlaneDistance, m_farPlaneDistance); + return CalcPerspectiveProjectionMatrix(m_fieldOfView.AsDegrees(), m_viewPort.AspectRatio(), m_nearPlaneDistance, m_farPlaneDistance); } } // namespace omath::source diff --git a/tests/engines/UnitTestOpenGL.cpp b/tests/engines/UnitTestOpenGL.cpp index 1ea9459..46f5afc 100644 --- a/tests/engines/UnitTestOpenGL.cpp +++ b/tests/engines/UnitTestOpenGL.cpp @@ -5,7 +5,7 @@ #include #include #include -#include + // #include // #include "glm/ext/matrix_clip_space.hpp" @@ -34,14 +34,4 @@ TEST(UnitTestOpenGL, Projection) //auto ndc_omath = proj_omath * cords_omath; // ndc_omath /= ndc_omath.At(3, 0); */ -} -TEST(UnitTestOpenGL, Projection2) -{ - const auto orient = omath::opengl::ViewMatrix(omath::opengl::kAbsForward, -omath::opengl::kAbsRight, omath::opengl::kAbsUp, {}); - - const omath::Mat<4, 1,float, omath::MatStoreType::COLUMN_MAJOR> cords_omath = - { - {0}, {0}, {-10}, {1} - }; - std::cout << (orient * cords_omath).ToString(); } \ No newline at end of file diff --git a/tests/engines/UnitTestSourceEngine.cpp b/tests/engines/UnitTestSourceEngine.cpp index 28a5805..9ec3ae5 100644 --- a/tests/engines/UnitTestSourceEngine.cpp +++ b/tests/engines/UnitTestSourceEngine.cpp @@ -2,16 +2,14 @@ // Created by Orange on 11/23/2024. // #include +#include #include #include - - - TEST(UnitTestSourceEngine, ForwardVector) { - const auto forward = omath::source::ForwardVector({}); + const auto forward = omath::source::ForwardVector({{}, {}, {}}); EXPECT_EQ(forward, omath::source::kAbsForward); } @@ -27,4 +25,26 @@ TEST(UnitTestSourceEngine, UpVector) { const auto up = omath::source::UpVector({}); EXPECT_EQ(up, omath::source::kAbsUp); +} + +TEST(UnitTestSourceEngine, PerpectiveProjectionAtCenter) +{ + constexpr auto fov = omath::projection::FieldOfView::FromDegrees(90.f); + auto cam = omath::source::Camera({0, 0, 0}, {}, {1920.f, 1080.f}, fov, 0.01f, 1000.f); + + + const auto viewProjMatrix = cam.GetViewProjectionMatrix(); + + for (float distance = 0.02f; distance < 1000.f; distance += 0.01f) + { + const auto projected = cam.WorldToScreen(viewProjMatrix, {distance, 0, 0}); + + EXPECT_TRUE(projected.has_value()); + + if (!projected.has_value()) + continue; + + EXPECT_NEAR(projected->x, 960, 0.00001f); + EXPECT_NEAR(projected->y, 540, 0.00001f); + } } \ No newline at end of file diff --git a/tests/general/UnitTestProjection.cpp b/tests/general/UnitTestProjection.cpp index 70fce84..ab8b71c 100644 --- a/tests/general/UnitTestProjection.cpp +++ b/tests/general/UnitTestProjection.cpp @@ -11,8 +11,8 @@ TEST(UnitTestProjection, Projection) { auto x = omath::Angle::FromDegrees(90.f); - auto cam = omath::source::Camera({-10, 0, 0}, omath::source::ViewAngles{}, {1920.f, 1080.f}, x, 0.1f, 1000.f); + auto cam = omath::source::Camera({0, 0, 0}, omath::source::ViewAngles{}, {1920.f, 1080.f}, x, 0.01f, 1000.f); - const auto projected = cam.WorldToScreen({10, 0, 0}); + const auto projected = cam.WorldToScreen(cam.GetViewProjectionMatrix(), {1000, 0, 50}); std::print("{} {} {}", projected->x, projected->y, projected->z); } \ No newline at end of file From 2488388aa4f482ee8ddb7bf6284fba31aedeff00 Mon Sep 17 00:00:00 2001 From: Orange Date: Sun, 8 Dec 2024 05:39:24 +0300 Subject: [PATCH 23/24] moved file --- include/omath/Mat.hpp | 6 +++--- include/omath/engines/{unity.hpp => Unity/Unity.hpp} | 0 2 files changed, 3 insertions(+), 3 deletions(-) rename include/omath/engines/{unity.hpp => Unity/Unity.hpp} (100%) diff --git a/include/omath/Mat.hpp b/include/omath/Mat.hpp index 66ade7e..3cb6f91 100644 --- a/include/omath/Mat.hpp +++ b/include/omath/Mat.hpp @@ -353,10 +353,10 @@ namespace omath { return { - {1, 0, 0, 0}, + {1, 0, 0, 0}, {0, angle.Cos(), -angle.Sin(), 0}, - {0, angle.Sin(), angle.Cos(), 0}, - {0, 0, 0, 1} + {0, angle.Sin(), angle.Cos(), 0}, + {0, 0, 0, 1} }; } diff --git a/include/omath/engines/unity.hpp b/include/omath/engines/Unity/Unity.hpp similarity index 100% rename from include/omath/engines/unity.hpp rename to include/omath/engines/Unity/Unity.hpp From ce9da764137ef6c3c44ea76b483a4678f407e366 Mon Sep 17 00:00:00 2001 From: Orange Date: Mon, 16 Dec 2024 12:31:56 +0300 Subject: [PATCH 24/24] removed useless stuff --- .gitmodules | 5 +-- extlibs/glm | 1 - include/omath/engines/OpenGL/Constants.hpp | 14 ------- include/omath/engines/OpenGL/Formulas.hpp | 4 -- include/omath/engines/OpenGL/OpenGL.hpp | 45 ---------------------- include/omath/engines/Source/Formulas.hpp | 1 - include/omath/engines/Unity/Unity.hpp | 12 ------ include/omath/prediction/Target.hpp | 2 +- source/prediction/Engine.cpp | 2 +- source/prediction/Projectile.cpp | 9 +++-- tests/engines/UnitTestSourceEngine.cpp | 2 +- tests/general/UnitTestPrediction.cpp | 5 ++- 12 files changed, 13 insertions(+), 89 deletions(-) delete mode 160000 extlibs/glm delete mode 100644 include/omath/engines/OpenGL/Constants.hpp delete mode 100644 include/omath/engines/OpenGL/Formulas.hpp delete mode 100644 include/omath/engines/OpenGL/OpenGL.hpp delete mode 100644 include/omath/engines/Unity/Unity.hpp diff --git a/.gitmodules b/.gitmodules index b6c1697..c158edf 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,3 @@ [submodule "extlibs/googletest"] path = extlibs/googletest - url = https://github.com/google/googletest.git -[submodule "extlibs/glm"] - path = extlibs/glm - url = https://github.com/g-truc/glm.git + url = https://github.com/google/googletest.git \ No newline at end of file diff --git a/extlibs/glm b/extlibs/glm deleted file mode 160000 index 33b4a62..0000000 --- a/extlibs/glm +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 33b4a621a697a305bc3a7610d290677b96beb181 diff --git a/include/omath/engines/OpenGL/Constants.hpp b/include/omath/engines/OpenGL/Constants.hpp deleted file mode 100644 index aec3520..0000000 --- a/include/omath/engines/OpenGL/Constants.hpp +++ /dev/null @@ -1,14 +0,0 @@ -// -// Created by Orange on 12/4/2024. -// -#pragma once - -#include - - -namespace omath::opengl -{ - constexpr Vector3 kAbsUp = {0, 1, 0}; - constexpr Vector3 kAbsRight = {1, 0, 0}; - constexpr Vector3 kAbsForward = {0, 0, -1}; -} \ No newline at end of file diff --git a/include/omath/engines/OpenGL/Formulas.hpp b/include/omath/engines/OpenGL/Formulas.hpp deleted file mode 100644 index 2a50756..0000000 --- a/include/omath/engines/OpenGL/Formulas.hpp +++ /dev/null @@ -1,4 +0,0 @@ -// -// Created by Orange on 12/4/2024. -// -#pragma once \ No newline at end of file diff --git a/include/omath/engines/OpenGL/OpenGL.hpp b/include/omath/engines/OpenGL/OpenGL.hpp deleted file mode 100644 index 68edf9d..0000000 --- a/include/omath/engines/OpenGL/OpenGL.hpp +++ /dev/null @@ -1,45 +0,0 @@ -// -// Created by Orange on 11/23/2024. -// -#pragma once - -#include "omath/Angle.hpp" -#include "omath/Mat.hpp" -#include "omath/Vector3.hpp" - -namespace omath::opengl -{ - constexpr Vector3 kAbsUp = {0, 1, 0}; - constexpr Vector3 kAbsRight = {1, 0, 0}; - constexpr Vector3 kAbsForward = {0, 0, -1}; - - - template - requires std::is_arithmetic_v - [[nodiscard]] Mat<4, 4, Type, MatStoreType::COLUMN_MAJOR> ViewMatrix(const Vector3& forward, const Vector3& right, - const Vector3& up, const Vector3& cam_origin) - { - return Mat<4, 4, Type, MatStoreType::COLUMN_MAJOR> - { - {right.x, right.y, right.z, 0}, - {up.x, up.y, up.z, 0}, - {-forward.x, -forward.y, -forward.z, 0}, - {0, 0, 0, 1}, - } * MatTranslation(-cam_origin); - } - - template - requires std::is_arithmetic_v - [[nodiscard]] Mat<4, 4, Type, MatStoreType::COLUMN_MAJOR> - PerspectiveProjectionMatrix(const float fieldOfView, const Type& aspectRatio, const Type& near, const Type& far) - { - const float fovHalfTan = std::tan(angles::DegreesToRadians(fieldOfView) / 2); - - return { - {static_cast(1) / (aspectRatio * fovHalfTan), 0, 0, 0}, - {0, static_cast(1) / (fovHalfTan), 0, 0}, - {0, 0, -(far + near) / (far - near), -(static_cast(2) * far * near) / (far - near)}, - {0, 0, -1, 0}, - }; - } -} // namespace omath::opengl diff --git a/include/omath/engines/Source/Formulas.hpp b/include/omath/engines/Source/Formulas.hpp index 652f263..3c8a6d7 100644 --- a/include/omath/engines/Source/Formulas.hpp +++ b/include/omath/engines/Source/Formulas.hpp @@ -4,7 +4,6 @@ #pragma once #include "Constants.h" - namespace omath::source { [[nodiscard]] diff --git a/include/omath/engines/Unity/Unity.hpp b/include/omath/engines/Unity/Unity.hpp deleted file mode 100644 index ff43bb2..0000000 --- a/include/omath/engines/Unity/Unity.hpp +++ /dev/null @@ -1,12 +0,0 @@ -// -// Created by Orange on 11/27/2024. -// - -#pragma once -#include - - -namespace omath::unity -{ - -}; diff --git a/include/omath/prediction/Target.hpp b/include/omath/prediction/Target.hpp index e44b868..a2b37ce 100644 --- a/include/omath/prediction/Target.hpp +++ b/include/omath/prediction/Target.hpp @@ -13,7 +13,7 @@ namespace omath::prediction public: [[nodiscard]] - constexpr Vector3 PredictPosition(float time, float gravity) const + constexpr Vector3 PredictPosition(const float time, const float gravity) const { auto predicted = m_origin + m_velocity * time; diff --git a/source/prediction/Engine.cpp b/source/prediction/Engine.cpp index 2bc1b1c..4452a52 100644 --- a/source/prediction/Engine.cpp +++ b/source/prediction/Engine.cpp @@ -58,7 +58,7 @@ namespace omath::prediction return std::nullopt; root = std::sqrt(root); - const float angle = std::atan((std::pow(projectile.m_launchSpeed, 2.f) - root) / (bulletGravity * distance2d)); + const float angle = std::atan((launchSpeedSqr - root) / (bulletGravity * distance2d)); return angles::RadiansToDegrees(angle); } diff --git a/source/prediction/Projectile.cpp b/source/prediction/Projectile.cpp index 3c58d29..281b327 100644 --- a/source/prediction/Projectile.cpp +++ b/source/prediction/Projectile.cpp @@ -10,9 +10,12 @@ namespace omath::prediction { Vector3 Projectile::PredictPosition(const float pitch, const float yaw, const float time, const float gravity) const { - auto currentPos = m_origin + omath::source::ForwardVector({source::PitchAngle::FromDegrees(-pitch), source::YawAngle::FromDegrees(yaw), source::RollAngle::FromDegrees(0)}) * m_launchSpeed * time; - currentPos.z -= (gravity * m_gravityScale) * std::pow(time, 2.f) * 0.5f; + auto currentPos = m_origin + source::ForwardVector({source::PitchAngle::FromDegrees(-pitch), + source::YawAngle::FromDegrees(yaw), + source::RollAngle::FromDegrees(0)}) * + m_launchSpeed * time; + currentPos.z -= (gravity * m_gravityScale) * (time * time) * 0.5f; return currentPos; } -} +} // namespace omath::prediction diff --git a/tests/engines/UnitTestSourceEngine.cpp b/tests/engines/UnitTestSourceEngine.cpp index 9ec3ae5..4d641a1 100644 --- a/tests/engines/UnitTestSourceEngine.cpp +++ b/tests/engines/UnitTestSourceEngine.cpp @@ -9,7 +9,7 @@ TEST(UnitTestSourceEngine, ForwardVector) { - const auto forward = omath::source::ForwardVector({{}, {}, {}}); + const auto forward = omath::source::ForwardVector({}); EXPECT_EQ(forward, omath::source::kAbsForward); } diff --git a/tests/general/UnitTestPrediction.cpp b/tests/general/UnitTestPrediction.cpp index 64fe578..5002d39 100644 --- a/tests/general/UnitTestPrediction.cpp +++ b/tests/general/UnitTestPrediction.cpp @@ -3,8 +3,9 @@ TEST(UnitTestPrediction, PredictionTest) { - const omath::prediction::Target target{.m_origin = {100, 0, 90}, .m_velocity = {0, 0, 0}, .m_isAirborne = false}; - const omath::prediction::Projectile proj = {.m_origin = {3,2,1}, .m_launchSpeed = 5000, .m_gravityScale= 0.4}; + constexpr omath::prediction::Target target{ + .m_origin = {100, 0, 90}, .m_velocity = {0, 0, 0}, .m_isAirborne = false}; + constexpr omath::prediction::Projectile proj = {.m_origin = {3,2,1}, .m_launchSpeed = 5000, .m_gravityScale= 0.4}; const auto viewPoint = omath::prediction::Engine(400, 1.f / 1000.f, 50, 5.f).MaybeCalculateAimPoint(proj, target); const auto [pitch, yaw, _] = proj.m_origin.ViewAngleTo(viewPoint.value()).AsTuple();