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/.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
diff --git a/.gitmodules b/.gitmodules
index c16587c..c158edf 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,3 +1,3 @@
[submodule "extlibs/googletest"]
path = extlibs/googletest
- url = https://github.com/google/googletest.git
+ url = https://github.com/google/googletest.git
\ No newline at end of file
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..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)
@@ -23,10 +26,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/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md
index a3f36ab..f212606 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,11 @@ 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 +64,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.
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..26c6ebf
--- /dev/null
+++ b/include/omath/Angle.hpp
@@ -0,0 +1,154 @@
+//
+// Created by Orange on 11/30/2024.
+//
+
+#pragma once
+#include "omath/Angles.hpp"
+
+#include
+
+
+namespace omath
+{
+ enum class AngleFlags
+ {
+ Normalized = 0,
+ Clamped = 1,
+ };
+
+ template
+ requires std::is_arithmetic_v
+ class Angle
+ {
+ Type m_angle;
+ constexpr 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();
+ }
+ }
+ 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)};
+ }
+
+ [[nodiscard]]
+ constexpr const Type& operator*() const
+ {
+ return m_angle;
+ }
+
+ [[nodiscard]]
+ constexpr Type AsDegrees() const
+ {
+ return m_angle;
+ }
+
+ [[nodiscard]]
+ constexpr Type AsRadians() const
+ {
+ return angles::DegreesToRadians(m_angle);
+ }
+
+ [[nodiscard]]
+ Type Sin() const
+ {
+ return std::sin(AsRadians());
+ }
+
+ [[nodiscard]]
+ Type Cos() const
+ {
+ return std::cos(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 Angle& other)
+ {
+ if constexpr (flags == AngleFlags::Normalized)
+ m_angle = angles::WrapAngle(m_angle + other.m_angle, min, max);
+
+ else if constexpr (flags == AngleFlags::Clamped)
+ m_angle = std::clamp(m_angle + other.m_angle, min, max);
+ else
+ {
+ static_assert(false);
+ std::unreachable();
+ }
+
+ return *this;
+ }
+
+ [[nodiscard]]
+ 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 Angle& other)
+ {
+ if constexpr (flags == AngleFlags::Normalized)
+ return {angles::WrapAngle(m_angle + other.m_angle, min, max)};
+
+ else if constexpr (flags == AngleFlags::Clamped)
+ return {std::clamp(m_angle + other.m_angle, min, max)};
+
+ else
+ static_assert(false);
+
+ std::unreachable();
+ }
+
+ [[nodiscard]]
+ constexpr Angle& operator-(const Angle& other)
+ {
+ return operator+(-other);
+ }
+
+ [[nodiscard]]
+ constexpr Angle operator-() const
+ {
+ return {-m_angle};
+ }
+ };
+}
diff --git a/include/omath/Angles.hpp b/include/omath/Angles.hpp
index 9e557fd..47a287a 100644
--- a/include/omath/Angles.hpp
+++ b/include/omath/Angles.hpp
@@ -4,15 +4,61 @@
#pragma once
#include
+#include
+
namespace omath::angles
{
- [[nodiscard]] constexpr float RadiansToDegrees(const float radiands)
+ template
+ requires std::is_floating_point_v
+ [[nodiscard]] constexpr Type 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 Type 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);
+ }
+
+ 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 18907fa..3cb6f91 100644
--- a/include/omath/Mat.hpp
+++ b/include/omath/Mat.hpp
@@ -5,10 +5,9 @@
#include
#include
#include
+#include
#include
#include "Vector3.hpp"
-#include
-#include "Angles.hpp"
namespace omath
@@ -25,7 +24,7 @@ namespace omath
};
template
- requires (std::is_floating_point_v || std::is_integral_v)
+ requires std::is_arithmetic_v
class Mat final
{
public:
@@ -33,7 +32,10 @@ namespace omath
{
Clear();
}
-
+ constexpr static MatStoreType GetStoreOrdering()
+ {
+ return StoreType;
+ }
constexpr Mat(const std::initializer_list>& rows)
{
if (rows.size() != Rows)
@@ -44,7 +46,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)
@@ -59,24 +61,24 @@ 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);
}
[[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;
}
@@ -87,7 +89,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 +107,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,16 +128,17 @@ 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;
+ Mat result;
for (size_t i = 0; i < Rows; ++i)
for (size_t j = 0; j < OtherColumns; ++j)
@@ -148,7 +151,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 +160,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 +181,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 +198,7 @@ namespace omath
return *this;
}
- constexpr Mat &operator=(Mat &&other) noexcept
+ constexpr Mat& operator=(Mat&& other) noexcept
{
if (this == &other)
return *this;
@@ -207,9 +211,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 +244,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)
@@ -260,15 +264,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]]
@@ -288,81 +292,119 @@ 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
+ 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},
- };
- }
-
- [[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},
- };
- }
-
- [[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}
- };
- }
-
- [[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 {
+ {screenWidth / 2, 0, 0, 0},
+ {0, -screenHeight / 2, 0, 0},
+ {0, 0, 1, 0},
+ {screenWidth / 2, screenHeight / 2, 0, 1},
};
}
private:
std::array m_data;
};
-}
+
+ template
+ [[nodiscard]]
+ constexpr static Mat<1, 4, Type, St> MatRowFromVector(const Vector3& vector) noexcept
+ {
+ return {{vector.x, vector.y, vector.z, 1}};
+ }
+
+ template
+ [[nodiscard]]
+ constexpr static Mat<4, 1, Type, St> MatColumnFromVector(const Vector3& vector) noexcept
+ {
+ return {{vector.x}, {vector.y}, {vector.z}, {1}};
+ }
+
+ template
+ [[nodiscard]]
+ constexpr Mat<4, 4, Type, St> MatTranslation(const Vector3& diff) noexcept
+ {
+ return
+ {
+ {1, 0, 0, diff.x},
+ {0, 1, 0, diff.y},
+ {0, 0, 1, diff.z},
+ {0, 0, 0, 1},
+ };
+ }
+
+ template
+ [[nodiscard]]
+ Mat<4, 4, Type, St> MatRotationAxisX(const Angle& angle) noexcept
+ {
+ return
+ {
+ {1, 0, 0, 0},
+ {0, angle.Cos(), -angle.Sin(), 0},
+ {0, angle.Sin(), angle.Cos(), 0},
+ {0, 0, 0, 1}
+ };
+ }
+
+ template
+ [[nodiscard]]
+ Mat<4, 4, Type, St> MatRotationAxisY(const Angle& angle) noexcept
+ {
+ return
+ {
+ {angle.Cos(), 0, angle.Sin(), 0},
+ {0 , 1, 0, 0},
+ {-angle.Sin(), 0, angle.Cos(), 0},
+ {0 , 0, 0, 1}
+ };
+ }
+
+ template
+ [[nodiscard]]
+ 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},
+ };
+ }
+
+ 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> MatRotation(const ViewAngles& angles) noexcept
+ {
+ return MatRotationAxisZ(angles.yaw) * MatRotationAxisY(angles.pitch) * MatRotationAxisX(angles.roll);
+ }
+} // namespace omath
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
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/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
new file mode 100644
index 0000000..d744f6b
--- /dev/null
+++ b/include/omath/ViewAngles.hpp
@@ -0,0 +1,15 @@
+//
+// Created by Orange on 11/30/2024.
+//
+#pragma once
+
+namespace omath
+{
+ template
+ struct ViewAngles
+ {
+ PitchType pitch;
+ YawType yaw;
+ RollType roll;
+ };
+}
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/Source/Camera.hpp b/include/omath/engines/Source/Camera.hpp
new file mode 100644
index 0000000..aca13cf
--- /dev/null
+++ b/include/omath/engines/Source/Camera.hpp
@@ -0,0 +1,19 @@
+//
+// 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, float 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..ecf1b40
--- /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 Mat1x3 = Mat<1, 3, 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..3c8a6d7
--- /dev/null
+++ b/include/omath/engines/Source/Formulas.hpp
@@ -0,0 +1,57 @@
+//
+// Created by Orange on 12/4/2024.
+//
+#pragma once
+#include "Constants.h"
+
+namespace omath::source
+{
+ [[nodiscard]]
+ inline Vector3 ForwardVector(const ViewAngles& angles)
+ {
+ const auto vec = MatRotation(angles) * MatColumnFromVector(kAbsForward);
+
+ return {vec.At(0, 0), vec.At(1, 0), vec.At(2, 0)};
+ }
+
+ [[nodiscard]]
+ inline Vector3 RightVector(const ViewAngles& angles)
+ {
+ const auto vec = MatRotation(angles) * MatColumnFromVector(kAbsRight);
+
+ return {vec.At(0, 0), vec.At(1, 0), vec.At(2, 0)};
+ }
+
+ [[nodiscard]]
+ inline Vector3 UpVector(const ViewAngles& angles)
+ {
+ const auto vec = MatRotation(angles) * MatColumnFromVector(kAbsUp);
+
+ return {vec.At(0, 0), vec.At(1, 0), vec.At(2, 0)};
+ }
+
+ [[nodiscard]] inline Mat4x4 CalcViewMatrix(const ViewAngles& angles, const Vector3& cam_origin)
+ {
+ return MatCameraView(ForwardVector(angles), RightVector(angles), UpVector(angles), cam_origin);
+ }
+
+
+ [[nodiscard]]
+ inline Mat4x4 CalcPerspectiveProjectionMatrix(const float fieldOfView, const float aspectRatio, const float near,
+ const float far)
+ {
+ // 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},
+
+ };
+ }
+} // namespace omath::source
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/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/include/omath/projection/Camera.hpp b/include/omath/projection/Camera.hpp
index d2d450e..15db451 100644
--- a/include/omath/projection/Camera.hpp
+++ b/include/omath/projection/Camera.hpp
@@ -5,10 +5,11 @@
#pragma once
#include
-#include
#include
-#include
+#include
#include "ErrorCodes.hpp"
+#include
+#include
namespace omath::projection
@@ -19,29 +20,70 @@ 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;
+ }
};
+ using FieldOfView = const Angle;
+ template
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);
+ virtual ~Camera() = default;
+ Camera(const Vector3& position, const ViewAnglesType& viewAngles, const ViewPort& viewPort,
+ 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)
+ {
- [[nodiscard]] Mat<4, 4> GetViewMatrix() const;
+ }
- [[nodiscard]] std::expected WorldToScreen(const Vector3& worldPosition) const;
+ virtual void LookAt(const Vector3& target) = 0;
+ [[nodiscard]] virtual Mat4x4Type GetViewMatrix() const = 0;
+
+ [[nodiscard]] virtual Mat4x4Type GetProjectionMatrix() const = 0;
+
+ [[nodiscard]] Mat4x4Type GetViewProjectionMatrix()
+ {
+ return GetProjectionMatrix() * GetViewMatrix();
+ }
+
+ [[nodiscard]] std::expected WorldToScreen(const Mat4x4Type& viewProj, const Vector3& worldPosition) const
+ {
+ auto projected = viewProj * 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)+1) / 2 * m_viewPort.m_width , (-projected.At(1,0)+1) / 2 * m_viewPort.m_height, projected.At(2,0)};
+ }
+
+ protected:
ViewPort m_viewPort{};
- float m_fieldOfView;
+ Angle m_fieldOfView;
float m_farPlaneDistance;
float m_nearPlaneDistance;
- float m_lensZoom;
+
+
+ ViewAnglesType m_viewAngles;
+ Vector3 m_origin;
private:
- Vector3 m_viewAngles;
- Vector3 m_origin;
+ 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
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/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
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/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
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..51eb507
--- /dev/null
+++ b/source/engines/Source/Camera.cpp
@@ -0,0 +1,36 @@
+//
+// Created by Orange on 12/4/2024.
+//
+#include "omath/engines/Source/Camera.hpp"
+#include "omath/engines/Source/Formulas.hpp"
+
+
+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);
+ 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 CalcViewMatrix(m_viewAngles, m_origin);
+ }
+
+ Mat4x4 Camera::GetProjectionMatrix() const
+ {
+ return CalcPerspectiveProjectionMatrix(m_fieldOfView.AsDegrees(), m_viewPort.AspectRatio(), m_nearPlaneDistance, m_farPlaneDistance);
+ }
+} // namespace omath::source
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 26cfd8e..281b327 100644
--- a/source/prediction/Projectile.cpp
+++ b/source/prediction/Projectile.cpp
@@ -4,15 +4,18 @@
#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;
- 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/source/projection/Camera.cpp b/source/projection/Camera.cpp
index c26f75a..dc0e070 100644
--- a/source/projection/Camera.cpp
+++ b/source/projection/Camera.cpp
@@ -3,56 +3,7 @@
//
#include "omath/projection/Camera.hpp"
-#include
-
-#include "omath/Angles.hpp"
-
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 1c604c1..77c9508 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -5,16 +5,24 @@ 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
+ 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
+ general/UnitTestAngles.cpp
+ general/UnitTestViewAngles.cpp
+ general/UnitTestAngle.cpp
+
+ engines/UnitTestOpenGL.cpp
+ engines/UnitTestUnityEngine.cpp
+ engines/UnitTestSourceEngine.cpp
+
)
target_link_libraries(unit-tests PRIVATE gtest gtest_main omath)
diff --git a/tests/UnitTestProjection.cpp b/tests/UnitTestProjection.cpp
deleted file mode 100644
index 3424633..0000000
--- a/tests/UnitTestProjection.cpp
+++ /dev/null
@@ -1,19 +0,0 @@
-//
-// Created by Vlad on 27.08.2024.
-//
-#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);
-
- const auto projected = camera.WorldToScreen({5000, 0, 0});
-
-
- EXPECT_TRUE(projected.has_value());
- EXPECT_EQ(projected->z, 1.f);
-}
\ No newline at end of file
diff --git a/tests/engines/UnitTestOpenGL.cpp b/tests/engines/UnitTestOpenGL.cpp
new file mode 100644
index 0000000..46f5afc
--- /dev/null
+++ b/tests/engines/UnitTestOpenGL.cpp
@@ -0,0 +1,37 @@
+//
+// Created by Orange on 11/23/2024.
+//
+#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);
+ */
+}
\ No newline at end of file
diff --git a/tests/engines/UnitTestSourceEngine.cpp b/tests/engines/UnitTestSourceEngine.cpp
new file mode 100644
index 0000000..4d641a1
--- /dev/null
+++ b/tests/engines/UnitTestSourceEngine.cpp
@@ -0,0 +1,50 @@
+//
+// Created by Orange on 11/23/2024.
+//
+#include
+#include
+#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);
+}
+
+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/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/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/UnitTestAngles.cpp b/tests/general/UnitTestAngles.cpp
new file mode 100644
index 0000000..37b00ff
--- /dev/null
+++ b/tests/general/UnitTestAngles.cpp
@@ -0,0 +1,50 @@
+//
+// Created by Orange on 11/30/2024.
+//
+#include
+#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);
+}
+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/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 81%
rename from tests/UnitTestMat.cpp
rename to tests/general/UnitTestMat.cpp
index 94d451a..0105c28 100644
--- a/tests/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)
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 61%
rename from tests/UnitTestPrediction.cpp
rename to tests/general/UnitTestPrediction.cpp
index 64fe578..5002d39 100644
--- a/tests/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();
diff --git a/tests/general/UnitTestProjection.cpp b/tests/general/UnitTestProjection.cpp
new file mode 100644
index 0000000..ab8b71c
--- /dev/null
+++ b/tests/general/UnitTestProjection.cpp
@@ -0,0 +1,18 @@
+//
+// Created by Vlad on 27.08.2024.
+//
+#include
+#include
+#include
+#include
+#include
+#include
+
+TEST(UnitTestProjection, Projection)
+{
+ auto x = omath::Angle::FromDegrees(90.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(cam.GetViewProjectionMatrix(), {1000, 0, 50});
+ std::print("{} {} {}", projected->x, projected->y, projected->z);
+}
\ No newline at end of file
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
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