Compare commits

...

55 Commits

Author SHA1 Message Date
dc43411bd2 fixed unity view matrix building 2025-03-24 06:30:09 +03:00
8959161904 Merge pull request #34 from orange-cpp/u/orange-cpp/add-unity
U/orange cpp/add unity
2025-03-23 01:20:16 +03:00
5d5bd215b2 fix 2025-03-23 01:17:05 +03:00
a48a257648 removed comment 2025-03-23 01:12:46 +03:00
ffba4e256a name fix 2025-03-23 01:06:36 +03:00
d9219cdddb naming fixed 2025-03-23 01:02:11 +03:00
5a1014a239 fix 2025-03-23 00:57:58 +03:00
74f2241bcf uncommented test 2025-03-23 00:52:12 +03:00
8977557a61 fix 2025-03-22 17:41:01 +03:00
481d7b85df improved camera 2025-03-22 17:39:40 +03:00
2b59fb6aa2 updated formulas 2025-03-22 08:36:06 +03:00
4f037a1952 added unity engine tests 2025-03-22 08:12:16 +03:00
ef11183c3f added camera files 2025-03-22 04:26:54 +03:00
326d8baaae Update README.md 2025-03-21 05:31:44 +03:00
e46067b0b9 fixed tests includes 2025-03-21 04:58:28 +03:00
68ac7f7b3d Merge pull request #33 from orange-cpp/u/orange-cpp/changed-file-naming
U/orange cpp/changed file naming
2025-03-21 04:50:56 +03:00
17de6d407c style fix 2025-03-21 04:48:38 +03:00
59d686e252 fix 2025-03-21 04:47:01 +03:00
713af1b772 fix 2025-03-21 04:46:23 +03:00
a8922230b3 fixed name 2025-03-21 04:45:02 +03:00
b8d79eb8b4 fixed example 2025-03-21 04:43:57 +03:00
5acd166d8f fixed include names 2025-03-21 04:40:59 +03:00
c7dda0ff10 changed source files naming 2025-03-21 04:30:17 +03:00
2688d977a9 change 2025-03-21 04:21:31 +03:00
Vladislav Alpatov
b9ac44a901 renamed headers 2025-03-21 04:17:42 +03:00
35658b1f6d Merge pull request #32 from orange-cpp/u/orange-cpp/examples
U/orange cpp/examples
2025-03-19 20:17:45 +03:00
8f4b61319f disabled tests by default 2025-03-19 20:13:06 +03:00
832c2ea5ef removed inline functions 2025-03-19 20:07:44 +03:00
50c336e044 added example 2025-03-19 19:16:22 +03:00
Vladislav Alpatov
e80e22bd5b added some files 2025-03-19 18:58:35 +03:00
27576ed761 added alias 2025-03-19 18:50:47 +03:00
f85243e892 improved print method 2025-03-19 00:56:56 +03:00
9b6d0beb03 Update README.md 2025-03-17 18:20:40 +03:00
ee9829af22 Merge pull request #31 from orange-cpp/u/orange-cpp/IWEngine
Added Infinity Ward Engine Support
2025-03-17 09:20:51 +03:00
cd452b0397 updated comment 2025-03-17 09:14:42 +03:00
2fa0c500a7 added magic number 2025-03-17 08:59:41 +03:00
0740d0778c added iw engine files 2025-03-17 07:20:13 +03:00
f5c271cfa6 changed naming of engines section 2025-03-17 05:27:00 +03:00
064a31f527 Merge pull request #30 from orange-cpp/u/orange-cpp/imgui-integration
ImGUI Vector integration
2025-03-17 04:12:39 +03:00
e5d0adf247 changed default option 2025-03-17 04:11:49 +03:00
8fc107ec0f fix 2025-03-17 04:07:21 +03:00
6dd72d2448 added convertors 2025-03-17 03:56:09 +03:00
c76f6e91b0 fix 2025-03-17 02:41:08 +03:00
d1d06c24ca unit tests buid off by defalut 2025-03-15 19:13:06 +03:00
169011e238 fixed Vec3 Vec4 2025-03-15 19:11:31 +03:00
934ca0da0a added explicit constructor for angle and comment for angle 2025-03-15 18:57:41 +03:00
4200ef63a6 improved mat & camera interface 2025-03-15 18:53:18 +03:00
58e2c3b5b7 fixed members inititalization miss match 2025-03-14 19:43:50 +03:00
Vladislav Alpatov
c3202a3bc3 patch 2025-03-01 21:32:02 +03:00
Vladislav Alpatov
39ab9d065d added option to disable avx2 2025-03-01 21:30:53 +03:00
Vladislav Alpatov
ed372a1c78 fixed for clang support 2025-03-01 21:22:44 +03:00
70313f5ae0 Merge pull request #29 from orange-cpp/u/orange-cpp/template-vectors
Added template Vectors 2d 3d 4d
2025-03-01 21:17:42 +03:00
Vladislav Alpatov
978656b573 refactored 2025-03-01 21:17:03 +03:00
Vladislav Alpatov
a0f746b84c fixed style 2025-03-01 21:15:26 +03:00
Vladislav Alpatov
6d0d267743 now template 2025-03-01 21:11:46 +03:00
94 changed files with 1383 additions and 764 deletions

View File

@@ -5,18 +5,27 @@ project(omath VERSION 1.0.1 LANGUAGES CXX)
include(CMakePackageConfigHelpers) include(CMakePackageConfigHelpers)
option(OMATH_BUILD_TESTS "Build unit tests" ON) option(OMATH_BUILD_TESTS "Build unit tests" OFF)
option(OMATH_THREAT_WARNING_AS_ERROR "Set highest level of warnings and force compiler to treat them as errors" ON) option(OMATH_THREAT_WARNING_AS_ERROR "Set highest level of warnings and force compiler to treat them as errors" ON)
option(OMATH_BUILD_AS_SHARED_LIBRARY "Build Omath as .so or .dll" OFF) option(OMATH_BUILD_AS_SHARED_LIBRARY "Build Omath as .so or .dll" OFF)
option(OMATH_USE_AVX2 "Omath will use AVX2 to boost performance" ON)
option(OMATH_IMGUI_INTEGRATION "Omath will define method to convert omath types to imgui types" OFF)
option(OMATH_BUILD_EXAMPLES "Build example projects with you can learn & play" OFF)
if (OMATH_BUILD_AS_SHARED_LIBRARY) if (OMATH_BUILD_AS_SHARED_LIBRARY)
add_library(omath SHARED source/Vector3.cpp) add_library(omath SHARED source/Matrix.cpp)
else() else()
add_library(omath STATIC source/Vector3.cpp add_library(omath STATIC source/Matrix.cpp)
include/omath/engines/OpenGL/Constants.hpp endif()
include/omath/engines/OpenGL/Formulas.hpp
include/omath/engines/OpenGL/Camera.hpp) add_library(omath::omath ALIAS omath)
if (OMATH_IMGUI_INTEGRATION)
target_compile_definitions(omath PUBLIC OMATH_IMGUI_INTEGRATION)
endif()
if (OMATH_USE_AVX2)
target_compile_definitions(omath PUBLIC OMATH_USE_AVX2)
endif() endif()
set_target_properties(omath PROPERTIES set_target_properties(omath PROPERTIES
@@ -27,6 +36,9 @@ set_target_properties(omath PROPERTIES
CXX_STANDARD 23 CXX_STANDARD 23
CXX_STANDARD_REQUIRED ON) CXX_STANDARD_REQUIRED ON)
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
target_compile_options(omath PRIVATE -mavx2 -mfma)
endif()
target_compile_features(omath PUBLIC cxx_std_23) target_compile_features(omath PUBLIC cxx_std_23)
@@ -38,6 +50,10 @@ if(OMATH_BUILD_TESTS)
add_subdirectory(tests) add_subdirectory(tests)
endif() endif()
if (OMATH_BUILD_EXAMPLES)
add_subdirectory(examples)
endif()
if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC" 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) target_compile_options(omath PRIVATE /W4 /WX)
elseif(OMATH_THREAT_WARNING_AS_ERROR) elseif(OMATH_THREAT_WARNING_AS_ERROR)

View File

@@ -1,6 +1,6 @@
<div align = center> <div align = center>
![banner](https://i.imgur.com/sjtpKi8.png) ![banner](https://i.imgur.com/SM9ccP6.png)
![GitHub License](https://img.shields.io/github/license/orange-cpp/omath) ![GitHub License](https://img.shields.io/github/license/orange-cpp/omath)
![GitHub contributors](https://img.shields.io/github/contributors/orange-cpp/omath) ![GitHub contributors](https://img.shields.io/github/contributors/orange-cpp/omath)
@@ -12,14 +12,14 @@
Oranges's Math Library (omath) is a comprehensive, open-source library aimed at providing efficient, reliable, and versatile mathematical functions and algorithms. Developed primarily in C++, this library is designed to cater to a wide range of mathematical operations essential in scientific computing, engineering, and academic research. Oranges's Math Library (omath) is a comprehensive, open-source library aimed at providing efficient, reliable, and versatile mathematical functions and algorithms. Developed primarily in C++, this library is designed to cater to a wide range of mathematical operations essential in scientific computing, engineering, and academic research.
## 👁‍🗨 Features ## 👁‍🗨 Features
- **Efficiency**: Optimized for performance, ensuring quick computations. - **Efficiency**: Optimized for performance, ensuring quick computations using AVX2.
- **Versatility**: Includes a wide array of mathematical functions and algorithms. - **Versatility**: Includes a wide array of mathematical functions and algorithms.
- **Ease of Use**: Simplified interface for convenient integration into various projects. - **Ease of Use**: Simplified interface for convenient integration into various projects.
- **Projectile Prediction**: Projectile prediction engine with O(N) algo complexity, that can power you projectile aim-bot. - **Projectile Prediction**: Projectile prediction engine with O(N) algo complexity, that can power you projectile aim-bot.
- **3D Projection**: No need to find view-projection matrix anymore you can make your own projection pipeline. - **3D Projection**: No need to find view-projection matrix anymore you can make your own projection pipeline.
- **Collision Detection**: Production ready code to handle collision detection by using simple interfaces. - **Collision Detection**: Production ready code to handle collision detection by using simple interfaces.
- **No Additional Dependencies**: No additional dependencies need to use OMath except unit test execution - **No Additional Dependencies**: No additional dependencies need to use OMath except unit test execution
- **Ready for meta-programming**: Omath use templates for common types like Vectors, Matrixes etc, to handle all types!
## ⏬ Getting Started ## ⏬ Getting Started
### Prerequisites ### Prerequisites
- C++ Compiler - C++ Compiler
@@ -72,8 +72,11 @@ TEST(UnitTestProjection, IsPointOnScreen)
With `omath/projection` module you can achieve simple ESP hack for powered by Source/Unreal/Unity engine games, like [Apex Legends](https://store.steampowered.com/app/1172470/Apex_Legends/). With `omath/projection` module you can achieve simple ESP hack for powered by Source/Unreal/Unity engine games, like [Apex Legends](https://store.steampowered.com/app/1172470/Apex_Legends/).
![banner](https://i.imgur.com/lcJrfcZ.png) ![banner](https://i.imgur.com/lcJrfcZ.png)
![Watch Video](https://youtu.be/lM_NJ1yCunw?si=5E87OrQMeypxSJ3E) Or for InfinityWard Engine based games. Like Call of Duty Black Ops 2!
![banner](https://i.imgur.com/F8dmdoo.png)
Or even advanced projectile aimbot
[Watch Video](https://youtu.be/lM_NJ1yCunw?si=5E87OrQMeypxSJ3E)
</details> </details>
## 🫵🏻 Contributing ## 🫵🏻 Contributing

4
examples/CMakeLists.txt Normal file
View File

@@ -0,0 +1,4 @@
project(examples)
add_executable(ExampleProjectionMatrixBuilder example_proj_mat_builder.cpp)
target_link_libraries(ExampleProjectionMatrixBuilder PRIVATE omath::omath)

View File

@@ -0,0 +1,40 @@
//
// Created by Vlad on 3/19/2025.
//
#include <iostream>
#include <print>
#include <omath/engines/opengl_engine/formulas.hpp>
int main()
{
std::println("OMATH Projection Matrix Builder");
float fov = 0;
float near = 0;
float far = 0;
float viewPortWidth = 0;
float viewPortHeight = 0;
std::print("Enter camera fov: ");
std::cin >> fov;
std::print("Enter camera z near: ");
std::cin >> near;
std::print("Enter camera z far: ");
std::cin >> far;
std::print("Enter camera screen width: ");
std::cin >> viewPortWidth;
std::print("Enter camera screen height: ");
std::cin >> viewPortHeight;
const auto mat =
omath::opengl_engine::CalcPerspectiveProjectionMatrix(fov, viewPortWidth / viewPortHeight, near, far);
std::print("{}", mat.ToString());
};

View File

@@ -1,154 +0,0 @@
//
// Vector4.h
//
#pragma once
#include <omath/Vector3.hpp>
#include <algorithm>
namespace omath
{
class Vector4 : public Vector3
{
public:
float w;
constexpr Vector4(const float x, const float y, const float z, const float w) : Vector3(x, y, z), w(w) {}
constexpr Vector4() : Vector3(), w(0.f) {};
[[nodiscard]]
constexpr bool operator==(const Vector4& src) const
{
return Vector3::operator==(src) && w == src.w;
}
[[nodiscard]]
constexpr bool operator!=(const Vector4& src) const
{
return !(*this == src);
}
constexpr Vector4& operator+=(const Vector4& v)
{
Vector3::operator+=(v);
w += v.w;
return *this;
}
constexpr Vector4& operator-=(const Vector4& v)
{
Vector3::operator-=(v);
w -= v.w;
return *this;
}
constexpr Vector4& operator*=(const float scalar)
{
Vector3::operator*=(scalar);
w *= scalar;
return *this;
}
constexpr Vector4& operator*=(const Vector4& v)
{
Vector3::operator*=(v);
w *= v.w;
return *this;
}
constexpr Vector4& operator/=(const float scalar)
{
Vector3::operator/=(scalar);
w /= scalar;
return *this;
}
constexpr Vector4& operator/=(const Vector4& v)
{
Vector3::operator/=(v);
w /= v.w;
return *this;
}
[[nodiscard]] constexpr float LengthSqr() const
{
return Vector3::LengthSqr() + w * w;
}
[[nodiscard]] constexpr float Dot(const Vector4& vOther) const
{
return Vector3::Dot(vOther) + w * vOther.w;
}
[[nodiscard]] float Length() const;
constexpr Vector4& Abs()
{
Vector3::Abs();
w = w < 0.f ? -w : w;
return *this;
}
constexpr Vector4& Clamp(const float min, const float max)
{
x = std::clamp(x, min, max);
y = std::clamp(y, min, max);
z = std::clamp(z, min, max);
return *this;
}
[[nodiscard]]
constexpr Vector4 operator-() const
{
return {-x, -y, -z, -w};
}
[[nodiscard]]
constexpr Vector4 operator+(const Vector4& v) const
{
return {x + v.x, y + v.y, z + v.z, w + v.w};
}
[[nodiscard]]
constexpr Vector4 operator-(const Vector4& v) const
{
return {x - v.x, y - v.y, z - v.z, w - v.w};
}
[[nodiscard]]
constexpr Vector4 operator*(const float scalar) const
{
return {x * scalar, y * scalar, z * scalar, w * scalar};
}
[[nodiscard]]
constexpr Vector4 operator*(const Vector4& v) const
{
return {x * v.x, y * v.y, z * v.z, w * v.w};
}
[[nodiscard]]
constexpr Vector4 operator/(const float scalar) const
{
return {x / scalar, y / scalar, z / scalar, w / scalar};
}
[[nodiscard]]
constexpr Vector4 operator/(const Vector4& v) const
{
return {x / v.x, y / v.y, z / v.z, w / v.w};
}
[[nodiscard]]
constexpr float Sum() const
{
return Vector3::Sum() + w;
}
};
}

View File

@@ -3,7 +3,7 @@
// //
#pragma once #pragma once
#include "omath/Angles.hpp" #include "omath/angles.hpp"
#include <algorithm> #include <algorithm>
namespace omath namespace omath
@@ -19,7 +19,7 @@ namespace omath
class Angle class Angle
{ {
Type m_angle; Type m_angle;
constexpr Angle(const Type& degrees) constexpr explicit Angle(const Type& degrees)
{ {
if constexpr (flags == AngleFlags::Normalized) if constexpr (flags == AngleFlags::Normalized)
m_angle = angles::WrapAngle(degrees, min, max); m_angle = angles::WrapAngle(degrees, min, max);
@@ -36,7 +36,7 @@ namespace omath
[[nodiscard]] [[nodiscard]]
constexpr static Angle FromDegrees(const Type& degrees) constexpr static Angle FromDegrees(const Type& degrees)
{ {
return {degrees}; return Angle{degrees};
} }
constexpr Angle() : m_angle(0) constexpr Angle() : m_angle(0)
{ {
@@ -45,7 +45,7 @@ namespace omath
[[nodiscard]] [[nodiscard]]
constexpr static Angle FromRadians(const Type& degrees) constexpr static Angle FromRadians(const Type& degrees)
{ {
return {angles::RadiansToDegrees<Type>(degrees)}; return Angle{angles::RadiansToDegrees<Type>(degrees)};
} }
[[nodiscard]] [[nodiscard]]
@@ -96,7 +96,6 @@ namespace omath
return Cos() / Sin(); return Cos() / Sin();
} }
[[nodiscard]]
constexpr Angle& operator+=(const Angle& other) constexpr Angle& operator+=(const Angle& other)
{ {
if constexpr (flags == AngleFlags::Normalized) if constexpr (flags == AngleFlags::Normalized)
@@ -116,7 +115,6 @@ namespace omath
[[nodiscard]] [[nodiscard]]
constexpr std::partial_ordering operator<=>(const Angle& other) const = default; constexpr std::partial_ordering operator<=>(const Angle& other) const = default;
[[nodiscard]]
constexpr Angle& operator-=(const Angle& other) constexpr Angle& operator-=(const Angle& other)
{ {
return operator+=(-other); return operator+=(-other);
@@ -146,7 +144,7 @@ namespace omath
[[nodiscard]] [[nodiscard]]
constexpr Angle operator-() const constexpr Angle operator-() const
{ {
return {-m_angle}; return Angle{-m_angle};
} }
}; };
} }

View File

@@ -3,8 +3,8 @@
// //
#pragma once #pragma once
#include <numbers>
#include <cmath> #include <cmath>
#include <numbers>
namespace omath::angles namespace omath::angles
{ {

View File

@@ -3,22 +3,22 @@
// //
#pragma once #pragma once
#include "omath/Vector3.hpp" #include "omath/triangle.hpp"
#include "omath/Triangle.hpp" #include "omath/vector3.hpp"
namespace omath::collision namespace omath::collision
{ {
class Ray class Ray
{ {
public: public:
Vector3 start; Vector3<float> start;
Vector3 end; Vector3<float> end;
[[nodiscard]] [[nodiscard]]
Vector3 DirectionVector() const; Vector3<float> DirectionVector() const;
[[nodiscard]] [[nodiscard]]
Vector3 DirectionVectorNormalized() const; Vector3<float> DirectionVectorNormalized() const;
}; };
class LineTracer class LineTracer
{ {
@@ -27,12 +27,12 @@ namespace omath::collision
[[nodiscard]] [[nodiscard]]
static bool CanTraceLine(const Ray& ray, const Triangle<Vector3>& triangle); static bool CanTraceLine(const Ray& ray, const Triangle<Vector3<float>>& triangle);
// Realization of MöllerTrumbore intersection algorithm // Realization of MöllerTrumbore intersection algorithm
// https://en.wikipedia.org/wiki/M%C3%B6ller%E2%80%93Trumbore_intersection_algorithm // https://en.wikipedia.org/wiki/M%C3%B6ller%E2%80%93Trumbore_intersection_algorithm
[[nodiscard]] [[nodiscard]]
static Vector3 GetRayHitPoint(const Ray& ray, const Triangle<Vector3>& triangle); static Vector3<float> GetRayHitPoint(const Ray& ray, const Triangle<Vector3<float>>& triangle);
}; };
} }

View File

@@ -4,9 +4,9 @@
#pragma once #pragma once
#include "omath/Vector3.hpp"
#include <cstdint> #include <cstdint>
#include "omath/Vector4.hpp" #include "omath/vector3.hpp"
#include "omath/vector4.hpp"
namespace omath namespace omath
{ {
@@ -18,10 +18,10 @@ namespace omath
}; };
class Color final : public Vector4 class Color final : public Vector4<float>
{ {
public: public:
constexpr Color(float r, float g, float b, float a) : Vector4(r,g,b,a) constexpr Color(const float r, const float g, const float b, const float a) : Vector4(r,g,b,a)
{ {
Clamp(0.f, 1.f); Clamp(0.f, 1.f);
} }

View File

@@ -1,54 +0,0 @@
//
// Created by Orange on 12/23/2024.
//
#pragma once
#include "Constants.hpp"
namespace omath::opengl
{
[[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<float, MatStoreType::COLUMN_MAJOR>(-ForwardVector(angles), RightVector(angles), UpVector(angles), cam_origin);
}
[[nodiscard]]
inline Mat4x4 CalcPerspectiveProjectionMatrix(const float fieldOfView, const float aspectRatio, const float near,
const float far)
{
const float fovHalfTan = std::tan(angles::DegreesToRadians(fieldOfView) / 2.f);
return {
{1.f / (aspectRatio * fovHalfTan), 0, 0, 0},
{0, 1.f / (fovHalfTan), 0, 0},
{0, 0, -(far + near) / (far - near), -(2.f * far * near) / (far - near)},
{0, 0, -1, 0},
};
}
}

View File

@@ -0,0 +1,21 @@
//
// Created by Vlad on 3/17/2025.
//
#pragma once
#include "omath/engines/iw_engine/constants.hpp"
#include "omath/projection/camera.hpp"
namespace omath::iw_engine
{
class Camera final : public projection::Camera<Mat4x4, ViewAngles>
{
public:
Camera(const Vector3<float>& position, const ViewAngles& viewAngles, const projection::ViewPort& viewPort,
const Angle<float, 0.f, 180.f, AngleFlags::Clamped>& fov, float near, float far);
void LookAt(const Vector3<float>& target) override;
protected:
[[nodiscard]] Mat4x4 CalcViewMatrix() const override;
[[nodiscard]] Mat4x4 CalcProjectionMatrix() const override;
};
}

View File

@@ -0,0 +1,25 @@
//
// Created by Vlad on 3/17/2025.
//
#pragma once
#include <omath/vector3.hpp>
#include <omath/mat.hpp>
#include <omath/angle.hpp>
#include <omath/view_angles.hpp>
namespace omath::iw_engine
{
constexpr Vector3<float> kAbsUp = {0, 0, 1};
constexpr Vector3<float> kAbsRight = {0, -1, 0};
constexpr Vector3<float> 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<float, -89.f, 89.f, AngleFlags::Clamped>;
using YawAngle = Angle<float, -180.f, 180.f, AngleFlags::Normalized>;
using RollAngle = Angle<float, -180.f, 180.f, AngleFlags::Normalized>;
using ViewAngles = omath::ViewAngles<PitchAngle, YawAngle, RollAngle>;
}

View File

@@ -0,0 +1,24 @@
//
// Created by Vlad on 3/17/2025.
//
#pragma once
#include "omath/engines/iw_engine/constants.hpp"
namespace omath::iw_engine
{
[[nodiscard]]
Vector3<float> ForwardVector(const ViewAngles& angles);
[[nodiscard]]
Vector3<float> RightVector(const ViewAngles& angles);
[[nodiscard]]
Vector3<float> UpVector(const ViewAngles& angles);
[[nodiscard]] Mat4x4 CalcViewMatrix(const ViewAngles& angles, const Vector3<float>& cam_origin);
[[nodiscard]]
Mat4x4 CalcPerspectiveProjectionMatrix(float fieldOfView, float aspectRatio, float near, float far);
} // namespace omath::iw_engine

View File

@@ -2,17 +2,17 @@
// Created by Orange on 12/23/2024. // Created by Orange on 12/23/2024.
// //
#pragma once #pragma once
#include "Constants.hpp" #include "omath/engines/opengl_engine/constants.hpp"
#include "omath/projection/Camera.hpp" #include "omath/projection/camera.hpp"
namespace omath::opengl namespace omath::opengl_engine
{ {
class Camera final : public projection::Camera<Mat4x4, ViewAngles> class Camera final : public projection::Camera<Mat4x4, ViewAngles>
{ {
public: public:
Camera(const Vector3& position, const ViewAngles& viewAngles, const projection::ViewPort& viewPort, Camera(const Vector3<float>& position, const ViewAngles& viewAngles, const projection::ViewPort& viewPort,
const Angle<float, 0.f, 180.f, AngleFlags::Clamped>& fov, float near, float far); const Angle<float, 0.f, 180.f, AngleFlags::Clamped>& fov, float near, float far);
void LookAt(const Vector3& target) override; void LookAt(const Vector3<float>& target) override;
[[nodiscard]] Mat4x4 CalcViewMatrix() const override; [[nodiscard]] Mat4x4 CalcViewMatrix() const override;
[[nodiscard]] Mat4x4 CalcProjectionMatrix() const override; [[nodiscard]] Mat4x4 CalcProjectionMatrix() const override;
}; };

View File

@@ -3,16 +3,16 @@
// //
#pragma once #pragma once
#include <omath/Vector3.hpp> #include <omath/angle.hpp>
#include <omath/Mat.hpp> #include <omath/mat.hpp>
#include <omath/Angle.hpp> #include <omath/vector3.hpp>
#include <omath/ViewAngles.hpp> #include <omath/view_angles.hpp>
namespace omath::opengl namespace omath::opengl_engine
{ {
constexpr Vector3 kAbsUp = {0, 1, 0}; constexpr Vector3<float> kAbsUp = {0, 1, 0};
constexpr Vector3 kAbsRight = {1, 0, 0}; constexpr Vector3<float> kAbsRight = {1, 0, 0};
constexpr Vector3 kAbsForward = {0, 0, -1}; constexpr Vector3<float> kAbsForward = {0, 0, -1};
using Mat4x4 = Mat<4, 4, float, MatStoreType::COLUMN_MAJOR>; using Mat4x4 = Mat<4, 4, float, MatStoreType::COLUMN_MAJOR>;
using Mat3x3 = Mat<4, 4, float, MatStoreType::COLUMN_MAJOR>; using Mat3x3 = Mat<4, 4, float, MatStoreType::COLUMN_MAJOR>;

View File

@@ -0,0 +1,24 @@
//
// Created by Orange on 12/23/2024.
//
#pragma once
#include "omath/engines/opengl_engine/constants.hpp"
namespace omath::opengl_engine
{
[[nodiscard]]
Vector3<float> ForwardVector(const ViewAngles& angles);
[[nodiscard]]
Vector3<float> RightVector(const ViewAngles& angles);
[[nodiscard]]
Vector3<float> UpVector(const ViewAngles& angles);
[[nodiscard]] Mat4x4 CalcViewMatrix(const ViewAngles& angles, const Vector3<float>& cam_origin);
[[nodiscard]]
Mat4x4 CalcPerspectiveProjectionMatrix(float fieldOfView, float aspectRatio, float near, float far);
} // namespace omath::opengl_engine

View File

@@ -2,17 +2,18 @@
// Created by Orange on 12/4/2024. // Created by Orange on 12/4/2024.
// //
#pragma once #pragma once
#include "Constants.hpp" #include "omath/engines/source_engine/constants.hpp"
#include "omath/projection/Camera.hpp" #include "omath/projection/camera.hpp"
namespace omath::source namespace omath::source_engine
{ {
class Camera final : public projection::Camera<Mat4x4, ViewAngles> class Camera final : public projection::Camera<Mat4x4, ViewAngles>
{ {
public: public:
Camera(const Vector3& position, const ViewAngles& viewAngles, const projection::ViewPort& viewPort, Camera(const Vector3<float>& position, const ViewAngles& viewAngles, const projection::ViewPort& viewPort,
const Angle<float, 0.f, 180.f, AngleFlags::Clamped>& fov, float near, float far); const Angle<float, 0.f, 180.f, AngleFlags::Clamped>& fov, float near, float far);
void LookAt(const Vector3& target) override; void LookAt(const Vector3<float>& target) override;
protected:
[[nodiscard]] Mat4x4 CalcViewMatrix() const override; [[nodiscard]] Mat4x4 CalcViewMatrix() const override;
[[nodiscard]] Mat4x4 CalcProjectionMatrix() const override; [[nodiscard]] Mat4x4 CalcProjectionMatrix() const override;
}; };

View File

@@ -3,15 +3,16 @@
// //
#pragma once #pragma once
#include <omath/Vector3.hpp> #include <omath/vector3.hpp>
#include <omath/Mat.hpp> #include <omath/mat.hpp>
#include <omath/Angle.hpp> #include <omath/angle.hpp>
#include <omath/ViewAngles.hpp> #include <omath/view_angles.hpp>
namespace omath::source
namespace omath::source_engine
{ {
constexpr Vector3 kAbsUp = {0, 0, 1}; constexpr Vector3<float> kAbsUp = {0, 0, 1};
constexpr Vector3 kAbsRight = {0, -1, 0}; constexpr Vector3<float> kAbsRight = {0, -1, 0};
constexpr Vector3 kAbsForward = {1, 0, 0}; constexpr Vector3<float> kAbsForward = {1, 0, 0};
using Mat4x4 = Mat<4, 4, float, MatStoreType::ROW_MAJOR>; using Mat4x4 = Mat<4, 4, float, MatStoreType::ROW_MAJOR>;
using Mat3x3 = Mat<4, 4, float, MatStoreType::ROW_MAJOR>; using Mat3x3 = Mat<4, 4, float, MatStoreType::ROW_MAJOR>;

View File

@@ -0,0 +1,23 @@
//
// Created by Orange on 12/4/2024.
//
#pragma once
#include "omath/engines/source_engine/constants.hpp"
namespace omath::source_engine
{
[[nodiscard]]
Vector3<float> ForwardVector(const ViewAngles& angles);
[[nodiscard]]
Vector3<float> RightVector(const ViewAngles& angles);
[[nodiscard]]
Vector3<float> UpVector(const ViewAngles& angles);
[[nodiscard]] Mat4x4 CalcViewMatrix(const ViewAngles& angles, const Vector3<float>& cam_origin);
[[nodiscard]]
Mat4x4 CalcPerspectiveProjectionMatrix(float fieldOfView, float aspectRatio, float near, float far);
} // namespace omath::source

View File

@@ -0,0 +1,21 @@
//
// Created by Vlad on 3/22/2025.
//
#pragma once
#include "omath/engines/unity_engine/constants.hpp"
#include "omath/projection/camera.hpp"
namespace omath::unity_engine
{
class Camera final : public projection::Camera<Mat4x4, ViewAngles>
{
public:
Camera(const Vector3<float>& position, const ViewAngles& viewAngles, const projection::ViewPort& viewPort,
const Angle<float, 0.f, 180.f, AngleFlags::Clamped>& fov, float near, float far);
void LookAt(const Vector3<float>& target) override;
protected:
[[nodiscard]] Mat4x4 CalcViewMatrix() const override;
[[nodiscard]] Mat4x4 CalcProjectionMatrix() const override;
};
}

View File

@@ -0,0 +1,26 @@
//
// Created by Vlad on 3/22/2025.
//
#pragma once
#include <omath/vector3.hpp>
#include <omath/mat.hpp>
#include <omath/angle.hpp>
#include <omath/view_angles.hpp>
namespace omath::unity_engine
{
constexpr Vector3<float> kAbsUp = {0, 1, 0};
constexpr Vector3<float> kAbsRight = {1, 0, 0};
constexpr Vector3<float> kAbsForward = {0, 0, 1};
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<float, -89.f, 89.f, AngleFlags::Clamped>;
using YawAngle = Angle<float, -180.f, 180.f, AngleFlags::Normalized>;
using RollAngle = Angle<float, -180.f, 180.f, AngleFlags::Normalized>;
using ViewAngles = omath::ViewAngles<PitchAngle, YawAngle, RollAngle>;
} // namespace omath::source

View File

@@ -0,0 +1,24 @@
//
// Created by Vlad on 3/22/2025.
//
#pragma once
#include "omath/engines/unity_engine/constants.hpp"
namespace omath::unity_engine
{
[[nodiscard]]
Vector3<float> ForwardVector(const ViewAngles& angles);
[[nodiscard]]
Vector3<float> RightVector(const ViewAngles& angles);
[[nodiscard]]
Vector3<float> UpVector(const ViewAngles& angles);
[[nodiscard]] Mat4x4 CalcViewMatrix(const ViewAngles& angles, const Vector3<float>& cam_origin);
[[nodiscard]]
Mat4x4 CalcPerspectiveProjectionMatrix(float fieldOfView, float aspectRatio, float near, float far);
} // namespace omath::source

View File

@@ -4,10 +4,11 @@
#pragma once #pragma once
#include <algorithm> #include <algorithm>
#include <array> #include <array>
#include <iomanip>
#include <sstream> #include <sstream>
#include <stdexcept> #include <stdexcept>
#include <utility> #include <utility>
#include "Vector3.hpp" #include "omath/vector3.hpp"
namespace omath namespace omath
{ {
@@ -34,11 +35,13 @@ namespace omath
class Mat final class Mat final
{ {
public: public:
constexpr Mat() constexpr Mat() noexcept
{ {
Clear(); Clear();
} }
constexpr static MatStoreType GetStoreOrdering()
[[nodiscard]]
constexpr static MatStoreType GetStoreOrdering() noexcept
{ {
return StoreType; return StoreType;
} }
@@ -72,6 +75,7 @@ namespace omath
m_data = other.m_data; m_data = other.m_data;
} }
[[nodiscard]]
constexpr Type& operator[](const size_t row, const size_t col) constexpr Type& operator[](const size_t row, const size_t col)
{ {
return At(row, col); return At(row, col);
@@ -100,7 +104,8 @@ namespace omath
return {Rows, Columns}; 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) if (rowIndex >= Rows || columnIndex >= Columns)
throw std::out_of_range("Index out of range"); throw std::out_of_range("Index out of range");
@@ -177,6 +182,7 @@ namespace omath
return *this = *this * other; return *this = *this * other;
} }
[[nodiscard]]
constexpr Mat operator*(const Type& f) const noexcept constexpr Mat operator*(const Type& f) const noexcept
{ {
Mat result(*this); Mat result(*this);
@@ -192,6 +198,7 @@ namespace omath
return *this; return *this;
} }
[[nodiscard]]
constexpr Mat operator/(const Type& f) const noexcept constexpr Mat operator/(const Type& f) const noexcept
{ {
Mat result(*this); Mat result(*this);
@@ -290,15 +297,20 @@ namespace omath
std::string ToString() const noexcept std::string ToString() const noexcept
{ {
std::ostringstream oss; std::ostringstream oss;
oss << "[[";
for (size_t i = 0; i < Rows; ++i) for (size_t i = 0; i < Rows; ++i)
{ {
if (i > 0)
oss << " [";
for (size_t j = 0; j < Columns; ++j) for (size_t j = 0; j < Columns; ++j)
{ {
oss << At(i, j); oss << std::setw(9) << std::fixed << std::setprecision(3) << At(i, j);
if (j != Columns - 1) if (j != Columns - 1)
oss << ' '; oss << ", ";
} }
oss << '\n'; oss << (i == Rows - 1 ? "]]" : "]\n");
} }
return oss.str(); return oss.str();
} }
@@ -333,21 +345,21 @@ namespace omath
template<class Type = float, MatStoreType St = MatStoreType::ROW_MAJOR> template<class Type = float, MatStoreType St = MatStoreType::ROW_MAJOR>
[[nodiscard]] [[nodiscard]]
constexpr static Mat<1, 4, Type, St> MatRowFromVector(const Vector3& vector) noexcept constexpr static Mat<1, 4, Type, St> MatRowFromVector(const Vector3<Type>& vector) noexcept
{ {
return {{vector.x, vector.y, vector.z, 1}}; return {{vector.x, vector.y, vector.z, 1}};
} }
template<class Type = float, MatStoreType St = MatStoreType::ROW_MAJOR> template<class Type = float, MatStoreType St = MatStoreType::ROW_MAJOR>
[[nodiscard]] [[nodiscard]]
constexpr static Mat<4, 1, Type, St> MatColumnFromVector(const Vector3& vector) noexcept constexpr static Mat<4, 1, Type, St> MatColumnFromVector(const Vector3<Type>& vector) noexcept
{ {
return {{vector.x}, {vector.y}, {vector.z}, {1}}; return {{vector.x}, {vector.y}, {vector.z}, {1}};
} }
template<class Type = float, MatStoreType St = MatStoreType::ROW_MAJOR> template<class Type = float, MatStoreType St = MatStoreType::ROW_MAJOR>
[[nodiscard]] [[nodiscard]]
constexpr Mat<4, 4, Type, St> MatTranslation(const Vector3& diff) noexcept constexpr Mat<4, 4, Type, St> MatTranslation(const Vector3<Type>& diff) noexcept
{ {
return return
{ {
@@ -399,8 +411,8 @@ namespace omath
template<class Type = float, MatStoreType St = MatStoreType::ROW_MAJOR> template<class Type = float, MatStoreType St = MatStoreType::ROW_MAJOR>
[[nodiscard]] [[nodiscard]]
static Mat<4, 4, Type, St> MatCameraView(const Vector3& forward, const Vector3& right, const Vector3& up, static Mat<4, 4, Type, St> MatCameraView(const Vector3<Type>& forward, const Vector3<Type>& right,
const Vector3& cameraOrigin) noexcept const Vector3<Type>& up, const Vector3<Type>& cameraOrigin) noexcept
{ {
return Mat<4, 4, Type, St> return Mat<4, 4, Type, St>
{ {
@@ -418,4 +430,30 @@ namespace omath
{ {
return MatRotationAxisZ(angles.yaw) * MatRotationAxisY(angles.pitch) * MatRotationAxisX(angles.roll); return MatRotationAxisZ(angles.yaw) * MatRotationAxisY(angles.pitch) * MatRotationAxisX(angles.roll);
} }
template<class Type = float, MatStoreType St = MatStoreType::ROW_MAJOR>
[[nodiscard]]
Mat<4, 4, Type, St> MatPerspectiveLeftHanded(const float fieldOfView, const float aspectRatio, const float near,
const float far) noexcept
{
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}};
}
template<class Type = float, MatStoreType St = MatStoreType::ROW_MAJOR>
[[nodiscard]]
Mat<4, 4, Type, St> MatPerspectiveRightHanded(const float fieldOfView, const float aspectRatio, const float near,
const float far) noexcept
{
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}};
}
} // namespace omath } // namespace omath

View File

@@ -2,10 +2,10 @@
#include <initializer_list> #include <initializer_list>
#include <memory> #include <memory>
#include <string> #include <string>
#include "omath/vector3.hpp"
namespace omath namespace omath
{ {
class Vector3;
class Matrix final class Matrix final
{ {
@@ -19,10 +19,10 @@ namespace omath
static Matrix ToScreenMatrix(float screenWidth, float screenHeight); static Matrix ToScreenMatrix(float screenWidth, float screenHeight);
[[nodiscard]] [[nodiscard]]
static Matrix TranslationMatrix(const Vector3& diff); static Matrix TranslationMatrix(const Vector3<float>& diff);
[[nodiscard]] [[nodiscard]]
static Matrix OrientationMatrix(const Vector3& forward, const Vector3& right, const Vector3& up); static Matrix OrientationMatrix(const Vector3<float>& forward, const Vector3<float>& right, const Vector3<float>& up);
[[nodiscard]] [[nodiscard]]
static Matrix ProjectionMatrix(float fieldOfView, float aspectRatio, float near, float far); static Matrix ProjectionMatrix(float fieldOfView, float aspectRatio, float near, float far);

View File

@@ -1,25 +0,0 @@
//
// Created by Vlad on 28.07.2024.
//
#pragma once
#include <vector>
#include "NavigationMesh.hpp"
#include "omath/Vector3.hpp"
namespace omath::pathfinding
{
struct PathNode;
class Astar final
{
public:
[[nodiscard]]
static std::vector<Vector3> FindPath(const Vector3& start, const Vector3& end, const NavigationMesh& navMesh);
private:
[[nodiscard]]
static std::vector<Vector3> ReconstructFinalPath(const std::unordered_map<Vector3, PathNode>& closedList, const Vector3& current);
[[nodiscard]]
static auto GetPerfectNode(const std::unordered_map<Vector3, PathNode>& openList, const Vector3& endVertex);
};
}

View File

@@ -0,0 +1,30 @@
//
// Created by Vlad on 28.07.2024.
//
#pragma once
#include <vector>
#include "omath/pathfinding/navigation_mesh.hpp"
#include "omath/vector3.hpp"
namespace omath::pathfinding
{
struct PathNode;
class Astar final
{
public:
[[nodiscard]]
static std::vector<Vector3<float>> FindPath(const Vector3<float>& start, const Vector3<float>& end,
const NavigationMesh& navMesh);
private:
[[nodiscard]]
static std::vector<Vector3<float>>
ReconstructFinalPath(const std::unordered_map<Vector3<float>, PathNode>& closedList,
const Vector3<float>& current);
[[nodiscard]]
static auto GetPerfectNode(const std::unordered_map<Vector3<float>, PathNode>& openList,
const Vector3<float>& endVertex);
};
} // namespace omath::pathfinding

View File

@@ -4,35 +4,35 @@
#pragma once #pragma once
#include "omath/Vector3.hpp"
#include <expected> #include <expected>
#include <vector>
#include <string> #include <string>
#include <vector>
#include "omath/vector3.hpp"
namespace omath::pathfinding namespace omath::pathfinding
{ {
enum Error enum Error
{ {
}; };
class NavigationMesh final class NavigationMesh final
{ {
public: public:
[[nodiscard]]
std::expected<Vector3<float>, std::string> GetClosestVertex(const Vector3<float>& point) const;
[[nodiscard]] [[nodiscard]]
std::expected<Vector3, std::string> GetClosestVertex(const Vector3& point) const; const std::vector<Vector3<float>>& GetNeighbors(const Vector3<float>& vertex) const;
[[nodiscard]]
const std::vector<Vector3>& GetNeighbors(const Vector3& vertex) const;
[[nodiscard]] [[nodiscard]]
bool Empty() const; bool Empty() const;
[[nodiscard]] std::vector<uint8_t> Serialize() const; [[nodiscard]] std::vector<uint8_t> Serialize() const;
void Deserialize(const std::vector<uint8_t>& raw); void Deserialize(const std::vector<uint8_t>& raw);
std::unordered_map<Vector3, std::vector<Vector3>> m_verTextMap; std::unordered_map<Vector3<float>, std::vector<Vector3<float>>> m_verTextMap;
}; };
} } // namespace omath::pathfinding

View File

@@ -2,9 +2,9 @@
// Created by Vlad on 2/23/2025. // Created by Vlad on 2/23/2025.
// //
#pragma once #pragma once
#include "Projectile.hpp" #include "omath/projectile_prediction/projectile.hpp"
#include "Target.hpp" #include "omath/projectile_prediction/target.hpp"
#include "omath/Vector3.hpp" #include "omath/vector3.hpp"
namespace omath::projectile_prediction namespace omath::projectile_prediction
@@ -13,7 +13,7 @@ namespace omath::projectile_prediction
{ {
public: public:
[[nodiscard]] [[nodiscard]]
virtual std::optional<Vector3> MaybeCalculateAimPoint(const Projectile& projectile, virtual std::optional<Vector3<float>> MaybeCalculateAimPoint(const Projectile& projectile,
const Target& target) const = 0; const Target& target) const = 0;
virtual ~ProjPredEngine() = default; virtual ~ProjPredEngine() = default;
}; };

View File

@@ -2,14 +2,14 @@
// Created by Vlad on 2/23/2025. // Created by Vlad on 2/23/2025.
// //
#pragma once #pragma once
#include "ProjPredEngine.hpp" #include "omath/projectile_prediction/proj_pred_engine.hpp"
namespace omath::projectile_prediction namespace omath::projectile_prediction
{ {
class ProjPredEngineAVX2 final : public ProjPredEngine class ProjPredEngineAVX2 final : public ProjPredEngine
{ {
public: public:
[[nodiscard]] std::optional<Vector3> MaybeCalculateAimPoint(const Projectile& projectile, [[nodiscard]] std::optional<Vector3<float>> MaybeCalculateAimPoint(const Projectile& projectile,
const Target& target) const override; const Target& target) const override;
@@ -17,7 +17,7 @@ namespace omath::projectile_prediction
~ProjPredEngineAVX2() override = default; ~ProjPredEngineAVX2() override = default;
private: private:
[[nodiscard]] static std::optional<float> CalculatePitch(const Vector3& projOrigin, const Vector3& targetPos, [[nodiscard]] static std::optional<float> CalculatePitch(const Vector3<float>& projOrigin, const Vector3<float>& targetPos,
float bulletGravity, float v0, float time); float bulletGravity, float v0, float time);
const float m_gravityConstant; const float m_gravityConstant;
const float m_simulationTimeStep; const float m_simulationTimeStep;

View File

@@ -5,10 +5,10 @@
#pragma once #pragma once
#include <optional> #include <optional>
#include "omath/Vector3.hpp" #include "omath/projectile_prediction/proj_pred_engine.hpp"
#include "omath/projectile_prediction/ProjPredEngine.hpp" #include "omath/projectile_prediction/projectile.hpp"
#include "omath/projectile_prediction/Projectile.hpp" #include "omath/projectile_prediction/target.hpp"
#include "omath/projectile_prediction/Target.hpp" #include "omath/vector3.hpp"
namespace omath::projectile_prediction namespace omath::projectile_prediction
@@ -20,7 +20,7 @@ namespace omath::projectile_prediction
float distanceTolerance); float distanceTolerance);
[[nodiscard]] [[nodiscard]]
std::optional<Vector3> MaybeCalculateAimPoint(const Projectile& projectile, std::optional<Vector3<float>> MaybeCalculateAimPoint(const Projectile& projectile,
const Target& target) const override; const Target& target) const override;
private: private:
@@ -31,11 +31,11 @@ namespace omath::projectile_prediction
[[nodiscard]] [[nodiscard]]
std::optional<float> MaybeCalculateProjectileLaunchPitchAngle(const Projectile& projectile, std::optional<float> MaybeCalculateProjectileLaunchPitchAngle(const Projectile& projectile,
const Vector3& targetPosition) const; const Vector3<float>& targetPosition) const;
[[nodiscard]] [[nodiscard]]
bool IsProjectileReachedTarget(const Vector3& targetPosition, const Projectile& projectile, float pitch, bool IsProjectileReachedTarget(const Vector3<float>& targetPosition, const Projectile& projectile, float pitch,
float time) const; float time) const;
}; };
} // namespace omath::projectile_prediction } // namespace omath::projectile_prediction

View File

@@ -3,7 +3,7 @@
// //
#pragma once #pragma once
#include "omath/Vector3.hpp" #include "omath/vector3.hpp"
namespace omath::projectile_prediction namespace omath::projectile_prediction
{ {
@@ -12,9 +12,9 @@ namespace omath::projectile_prediction
public: public:
[[nodiscard]] [[nodiscard]]
Vector3 PredictPosition(float pitch, float yaw, float time, float gravity) const; Vector3<float> PredictPosition(float pitch, float yaw, float time, float gravity) const;
Vector3 m_origin; Vector3<float> m_origin;
float m_launchSpeed{}; float m_launchSpeed{};
float m_gravityScale{}; float m_gravityScale{};
}; };

View File

@@ -3,7 +3,7 @@
// //
#pragma once #pragma once
#include "omath/Vector3.hpp" #include "omath/vector3.hpp"
namespace omath::projectile_prediction namespace omath::projectile_prediction
{ {
@@ -12,7 +12,7 @@ namespace omath::projectile_prediction
public: public:
[[nodiscard]] [[nodiscard]]
constexpr Vector3 PredictPosition(const float time, const float gravity) const constexpr Vector3<float> PredictPosition(const float time, const float gravity) const
{ {
auto predicted = m_origin + m_velocity * time; auto predicted = m_origin + m_velocity * time;
@@ -22,8 +22,8 @@ namespace omath::projectile_prediction
return predicted; return predicted;
} }
Vector3 m_origin; Vector3<float> m_origin;
Vector3 m_velocity; Vector3<float> m_velocity;
bool m_isAirborne{}; bool m_isAirborne{};
}; };
} }

View File

@@ -5,11 +5,11 @@
#pragma once #pragma once
#include <expected> #include <expected>
#include <omath/Mat.hpp> #include <omath/angle.hpp>
#include <omath/Vector3.hpp> #include <omath/mat.hpp>
#include "ErrorCodes.hpp" #include <omath/vector3.hpp>
#include <omath/Angle.hpp>
#include <type_traits> #include <type_traits>
#include "omath/projection/error_codes.hpp"
namespace omath::projection namespace omath::projection
{ {
@@ -31,15 +31,15 @@ namespace omath::projection
{ {
public: public:
virtual ~Camera() = default; virtual ~Camera() = default;
Camera(const Vector3& position, const ViewAnglesType& viewAngles, const ViewPort& viewPort, Camera(const Vector3<float>& position, const ViewAnglesType& viewAngles, const ViewPort& viewPort,
const FieldOfView& 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_viewPort(viewPort), m_fieldOfView(fov), m_farPlaneDistance(far), m_nearPlaneDistance(near),
m_viewAngles(viewAngles), m_origin(position) m_viewAngles(viewAngles), m_origin(position)
{ {
} }
virtual void LookAt(const Vector3& target) = 0; protected:
virtual void LookAt(const Vector3<float>& target) = 0;
[[nodiscard]] virtual Mat4x4Type CalcViewMatrix() const = 0; [[nodiscard]] virtual Mat4x4Type CalcViewMatrix() const = 0;
@@ -50,40 +50,43 @@ namespace omath::projection
return CalcProjectionMatrix() * CalcViewMatrix(); return CalcProjectionMatrix() * CalcViewMatrix();
} }
public:
[[nodiscard]] const Mat4x4Type& GetViewProjectionMatrix() const
{
if (!m_viewProjectionMatrix.has_value())
m_viewProjectionMatrix = CalcViewProjectionMatrix();
return m_viewProjectionMatrix.value();
}
void SetFieldOfView(const FieldOfView& fov) void SetFieldOfView(const FieldOfView& fov)
{ {
m_fieldOfView = fov; m_fieldOfView = fov;
m_viewProjectionMatrix = CalcViewProjectionMatrix();
} }
void SetNearPlane(const float near) void SetNearPlane(const float near)
{ {
m_nearPlaneDistance = near; m_nearPlaneDistance = near;
m_viewProjectionMatrix = CalcViewProjectionMatrix();
} }
void SetFarPlane(const float far) void SetFarPlane(const float far)
{ {
m_farPlaneDistance = far; m_farPlaneDistance = far;
m_viewProjectionMatrix = CalcViewProjectionMatrix();
} }
void SetViewAngles(const ViewAnglesType& viewAngles) void SetViewAngles(const ViewAnglesType& viewAngles)
{ {
m_viewAngles = viewAngles; m_viewAngles = viewAngles;
m_viewProjectionMatrix = CalcViewProjectionMatrix();
} }
void SetOrigin(const Vector3& origin) void SetOrigin(const Vector3<float>& origin)
{ {
m_origin = origin; m_origin = origin;
m_viewProjectionMatrix = CalcViewProjectionMatrix();
} }
void SetViewPort(const ViewPort& viewPort) void SetViewPort(const ViewPort& viewPort)
{ {
m_viewPort = viewPort; m_viewPort = viewPort;
m_viewProjectionMatrix = CalcViewProjectionMatrix();
} }
[[nodiscard]] const FieldOfView& GetFieldOfView() const [[nodiscard]] const FieldOfView& GetFieldOfView() const
@@ -106,17 +109,26 @@ namespace omath::projection
return m_viewAngles; return m_viewAngles;
} }
[[nodiscard]] const Vector3& GetOrigin() const [[nodiscard]] const Vector3<float>& GetOrigin() const
{ {
return m_origin; return m_origin;
} }
[[nodiscard]] std::expected<Vector3, Error> WorldToScreen(const Vector3& worldPosition) const [[nodiscard]] std::expected<Vector3<float>, Error> WorldToScreen(const Vector3<float>& worldPosition) const
{ {
if (!m_viewProjectionMatrix.has_value()) auto normalizedCords = WorldToViewPort(worldPosition);
m_viewProjectionMatrix = CalcViewProjectionMatrix();
auto projected = m_viewProjectionMatrix.value() * MatColumnFromVector<float, Mat4x4Type::GetStoreOrdering()>(worldPosition); if (!normalizedCords.has_value())
return std::unexpected{normalizedCords.error()};
return NdcToScreenPosition(*normalizedCords);
}
[[nodiscard]] std::expected<Vector3<float>, Error> WorldToViewPort(const Vector3<float>& worldPosition) const
{
auto projected = GetViewProjectionMatrix() *
MatColumnFromVector<float, Mat4x4Type::GetStoreOrdering()>(worldPosition);
if (projected.At(3, 0) == 0.0f) if (projected.At(3, 0) == 0.0f)
return std::unexpected(Error::WORLD_POSITION_IS_OUT_OF_SCREEN_BOUNDS); return std::unexpected(Error::WORLD_POSITION_IS_OUT_OF_SCREEN_BOUNDS);
@@ -126,10 +138,7 @@ namespace omath::projection
if (IsNdcOutOfBounds(projected)) if (IsNdcOutOfBounds(projected))
return std::unexpected(Error::WORLD_POSITION_IS_OUT_OF_SCREEN_BOUNDS); return std::unexpected(Error::WORLD_POSITION_IS_OUT_OF_SCREEN_BOUNDS);
const auto screenPositionX = (projected.At(0,0)+1.f) / 2.f * m_viewPort.m_width; return Vector3<float>{projected.At(0, 0), projected.At(1, 0), projected.At(2, 0)};
const auto screenPositionY = (-projected.At(1,0)+1) / 2.f * m_viewPort.m_height;
return Vector3{screenPositionX, screenPositionY, projected.At(2,0)};
} }
protected: protected:
@@ -143,14 +152,24 @@ namespace omath::projection
ViewAnglesType m_viewAngles; ViewAnglesType m_viewAngles;
Vector3 m_origin; Vector3<float> m_origin;
private: private:
template<class Type> template<class Type>
[[nodiscard]] [[nodiscard]]
constexpr static bool IsNdcOutOfBounds(const Type& ndc) constexpr static bool IsNdcOutOfBounds(const Type& ndc)
{ {
return std::ranges::any_of( ndc.RawArray(), [](const auto& val) { return val < -1 || val > 1; }); return std::ranges::any_of(ndc.RawArray(), [](const auto& val) { return val < -1 || val > 1; });
}
[[nodiscard]] Vector3<float> NdcToScreenPosition(const Vector3<float>& ndc) const
{
return
{
(ndc.x + 1.f) / 2.f * m_viewPort.m_width,
(1.f - ndc.y) / 2.f * m_viewPort.m_height,
ndc.z
};
} }
}; };
} // namespace omath::projection } // namespace omath::projection

View File

@@ -2,10 +2,20 @@
// Created by Orange on 11/13/2024. // Created by Orange on 11/13/2024.
// //
#pragma once #pragma once
#include "omath/Vector3.hpp" #include "omath/vector3.hpp"
namespace omath namespace omath
{ {
/*
|\
| \
a | \ hypot
| \
-----
b
*/
template<class Vector> template<class Vector>
class Triangle final class Triangle final
{ {
@@ -16,12 +26,12 @@ namespace omath
{ {
} }
Vector3 m_vertex1; Vector3<float> m_vertex1;
Vector3 m_vertex2; Vector3<float> m_vertex2;
Vector3 m_vertex3; Vector3<float> m_vertex3;
[[nodiscard]] [[nodiscard]]
constexpr Vector3 CalculateNormal() const constexpr Vector3<float> CalculateNormal() const
{ {
const auto b = SideBVector(); const auto b = SideBVector();
const auto a = SideAVector(); const auto a = SideAVector();
@@ -41,7 +51,7 @@ namespace omath
} }
[[nodiscard]] [[nodiscard]]
constexpr Vector3 SideAVector() const constexpr Vector3<float> SideAVector() const
{ {
return m_vertex1 - m_vertex2; return m_vertex1 - m_vertex2;
} }
@@ -61,12 +71,12 @@ namespace omath
return std::abs(sideA*sideA + sideB*sideB - hypot*hypot) <= 0.0001f; return std::abs(sideA*sideA + sideB*sideB - hypot*hypot) <= 0.0001f;
} }
[[nodiscard]] [[nodiscard]]
constexpr Vector3 SideBVector() const constexpr Vector3<float> SideBVector() const
{ {
return m_vertex3 - m_vertex2; return m_vertex3 - m_vertex2;
} }
[[nodiscard]] [[nodiscard]]
constexpr Vector3 MidPoint() const constexpr Vector3<float> MidPoint() const
{ {
return (m_vertex1 + m_vertex2 + m_vertex3) / 3; return (m_vertex1 + m_vertex2 + m_vertex3) / 3;
} }

View File

@@ -3,21 +3,31 @@
// //
#pragma once #pragma once
#include <tuple>
#include <cmath> #include <cmath>
#include <tuple>
#ifdef OMATH_IMGUI_INTEGRATION
#include <imgui.h>
#endif
namespace omath namespace omath
{ {
template<class Type>
requires std::is_arithmetic_v<Type>
class Vector2 class Vector2
{ {
public: public:
float x = 0.f; Type x = static_cast<Type>(0);
float y = 0.f; Type y = static_cast<Type>(0);
// Constructors // Constructors
constexpr Vector2() = default; constexpr Vector2() = default;
constexpr Vector2(const float x, const float y) : x(x), y(y) {} constexpr Vector2(const Type& x, const Type& y) : x(x), y(y)
{
}
// Equality operators // Equality operators
[[nodiscard]] [[nodiscard]]
@@ -65,7 +75,7 @@ namespace omath
return *this; return *this;
} }
constexpr Vector2& operator*=(const float fl) constexpr Vector2& operator*=(const Type& fl)
{ {
x *= fl; x *= fl;
y *= fl; y *= fl;
@@ -73,7 +83,7 @@ namespace omath
return *this; return *this;
} }
constexpr Vector2& operator/=(const float fl) constexpr Vector2& operator/=(const Type& fl)
{ {
x /= fl; x /= fl;
y /= fl; y /= fl;
@@ -81,7 +91,7 @@ namespace omath
return *this; return *this;
} }
constexpr Vector2& operator+=(const float fl) constexpr Vector2& operator+=(const Type& fl)
{ {
x += fl; x += fl;
y += fl; y += fl;
@@ -89,7 +99,7 @@ namespace omath
return *this; return *this;
} }
constexpr Vector2& operator-=(const float fl) constexpr Vector2& operator-=(const Type& fl)
{ {
x -= fl; x -= fl;
y -= fl; y -= fl;
@@ -98,68 +108,57 @@ namespace omath
} }
// Basic vector operations // Basic vector operations
[[nodiscard]] float DistTo(const Vector2& vOther) const [[nodiscard]] Type DistTo(const Vector2& vOther) const
{ {
return std::sqrt(DistToSqr(vOther)); return std::sqrt(DistToSqr(vOther));
} }
[[nodiscard]] constexpr float DistToSqr(const Vector2& vOther) const [[nodiscard]] constexpr Type DistToSqr(const Vector2& vOther) const
{ {
return (x - vOther.x) * (x - vOther.x) + (y - vOther.y) * (y - vOther.y); return (x - vOther.x) * (x - vOther.x) + (y - vOther.y) * (y - vOther.y);
} }
[[nodiscard]] constexpr float Dot(const Vector2& vOther) const [[nodiscard]] constexpr Type Dot(const Vector2& vOther) const
{ {
return x * vOther.x + y * vOther.y; return x * vOther.x + y * vOther.y;
} }
#ifndef _MSC_VER #ifndef _MSC_VER
[[nodiscard]] constexpr float Length() const [[nodiscard]] constexpr Type& Length() const
{ {
return std::hypot(x, y); return std::hypot(x, y);
} }
[[nodiscard]] constexpr Vector2 Normalized() const [[nodiscard]] constexpr Vector2 Normalized() const
{ {
const float len = Length(); const Type len = Length();
return len > 0.f ? *this / len : *this; return len > 0.f ? *this / len : *this;
} }
#else #else
[[nodiscard]] float Length() const [[nodiscard]] Type Length() const
{ {
return std::hypot(x, y); return std::hypot(x, y);
} }
[[nodiscard]] Vector2 Normalized() const [[nodiscard]] Vector2 Normalized() const
{ {
const float len = Length(); const Type len = Length();
return len > 0.f ? *this / len : *this; return len > 0.f ? *this / len : *this;
} }
#endif #endif
[[nodiscard]] constexpr float LengthSqr() const [[nodiscard]] constexpr Type LengthSqr() const
{ {
return x * x + y * y; return x * x + y * y;
} }
constexpr Vector2& Abs() constexpr Vector2& Abs()
{ {
//FIXME: Replace with std::abs, if it will become constexprable // FIXME: Replace with std::abs, if it will become constexprable
x = x < 0 ? -x : x; x = x < 0 ? -x : x;
y = y < 0 ? -y : y; y = y < 0 ? -y : y;
return *this; return *this;
} }
template<class type>
[[nodiscard]] constexpr const type& As() const
{
return *reinterpret_cast<const type*>(this);
}
template<class type>
[[nodiscard]] constexpr type& As()
{
return *reinterpret_cast<type*>(this);
}
[[nodiscard]] constexpr Vector2 operator-() const [[nodiscard]] constexpr Vector2 operator-() const
{ {
return {-x, -y}; return {-x, -y};
@@ -186,16 +185,24 @@ namespace omath
return {x / fl, y / fl}; return {x / fl, y / fl};
} }
// Sum of elements // Sum of elements
[[nodiscard]] constexpr float Sum() const [[nodiscard]] constexpr Type Sum() const
{ {
return x + y; return x + y;
} }
[[nodiscard]] [[nodiscard]]
constexpr std::tuple<float, float> AsTuple() const constexpr std::tuple<Type, Type> AsTuple() const
{ {
return std::make_tuple(x, y); return std::make_tuple(x, y);
} }
#ifdef OMATH_IMGUI_INTEGRATION
[[nodiscard]]
ImVec2 ToImVec2() const
{
return {static_cast<float>(this->x), static_cast<float>(this->y)};
}
#endif
}; };
} } // namespace omath

View File

@@ -5,12 +5,10 @@
#pragma once #pragma once
#include <cstdint> #include <cstdint>
#include <functional>
#include "omath/Vector2.hpp"
#include "omath/Angle.hpp"
#include <expected> #include <expected>
#include <immintrin.h> #include <functional>
#include "omath/angle.hpp"
#include "omath/vector2.hpp"
namespace omath namespace omath
{ {
@@ -20,16 +18,17 @@ namespace omath
IMPOSSIBLE_BETWEEN_ANGLE, IMPOSSIBLE_BETWEEN_ANGLE,
}; };
class Vector3 : public Vector2 template<class Type> requires std::is_arithmetic_v<Type>
class Vector3 : public Vector2<Type>
{ {
public: public:
float z = 0.f; Type z = static_cast<Type>(0);
constexpr Vector3(const float x, const float y, const float z) : Vector2(x, y), z(z) { } constexpr Vector3(const Type& x, const Type& y, const Type& z) : Vector2<Type>(x, y), z(z) { }
constexpr Vector3() : Vector2() {}; constexpr Vector3() : Vector2<Type>() {};
[[nodiscard]] constexpr bool operator==(const Vector3& src) const [[nodiscard]] constexpr bool operator==(const Vector3& src) const
{ {
return Vector2::operator==(src) && (src.z == z); return Vector2<Type>::operator==(src) && (src.z == z);
} }
[[nodiscard]] constexpr bool operator!=(const Vector3& src) const [[nodiscard]] constexpr bool operator!=(const Vector3& src) const
@@ -39,7 +38,7 @@ namespace omath
constexpr Vector3& operator+=(const Vector3& v) constexpr Vector3& operator+=(const Vector3& v)
{ {
Vector2::operator+=(v); Vector2<Type>::operator+=(v);
z += v.z; z += v.z;
return *this; return *this;
@@ -47,7 +46,7 @@ namespace omath
constexpr Vector3& operator-=(const Vector3& v) constexpr Vector3& operator-=(const Vector3& v)
{ {
Vector2::operator-=(v); Vector2<Type>::operator-=(v);
z -= v.z; z -= v.z;
return *this; return *this;
@@ -55,7 +54,7 @@ namespace omath
constexpr Vector3& operator*=(const float fl) constexpr Vector3& operator*=(const float fl)
{ {
Vector2::operator*=(fl); Vector2<Type>::operator*=(fl);
z *= fl; z *= fl;
return *this; return *this;
@@ -63,7 +62,7 @@ namespace omath
constexpr Vector3& operator*=(const Vector3& v) constexpr Vector3& operator*=(const Vector3& v)
{ {
Vector2::operator*=(v); Vector2<Type>::operator*=(v);
z *= v.z; z *= v.z;
return *this; return *this;
@@ -71,7 +70,7 @@ namespace omath
constexpr Vector3& operator/=(const Vector3& v) constexpr Vector3& operator/=(const Vector3& v)
{ {
Vector2::operator/=(v); Vector2<Type>::operator/=(v);
z /= v.z; z /= v.z;
return *this; return *this;
@@ -79,7 +78,7 @@ namespace omath
constexpr Vector3& operator+=(const float fl) constexpr Vector3& operator+=(const float fl)
{ {
Vector2::operator+=(fl); Vector2<Type>::operator+=(fl);
z += fl; z += fl;
return *this; return *this;
@@ -87,7 +86,7 @@ namespace omath
constexpr Vector3& operator/=(const float fl) constexpr Vector3& operator/=(const float fl)
{ {
Vector2::operator/=(fl); Vector2<Type>::operator/=(fl);
z /= fl; z /= fl;
return *this; return *this;
@@ -95,7 +94,7 @@ namespace omath
constexpr Vector3& operator-=(const float fl) constexpr Vector3& operator-=(const float fl)
{ {
Vector2::operator-=(fl); Vector2<Type>::operator-=(fl);
z -= fl; z -= fl;
return *this; return *this;
@@ -103,117 +102,117 @@ namespace omath
constexpr Vector3& Abs() constexpr Vector3& Abs()
{ {
Vector2::Abs(); Vector2<Type>::Abs();
z = z < 0.f ? -z : z; z = z < 0.f ? -z : z;
return *this; return *this;
} }
[[nodiscard]] constexpr float DistToSqr(const Vector3& vOther) const [[nodiscard]] constexpr Type DistToSqr(const Vector3& vOther) const
{ {
return (*this - vOther).LengthSqr(); return (*this - vOther).LengthSqr();
} }
[[nodiscard]] constexpr float Dot(const Vector3& vOther) const [[nodiscard]] constexpr Type Dot(const Vector3& vOther) const
{ {
return Vector2::Dot(vOther) + z * vOther.z; return Vector2<Type>::Dot(vOther) + z * vOther.z;
} }
#ifndef _MSC_VER #ifndef _MSC_VER
[[nodiscard]] constexpr float Length() const [[nodiscard]] constexpr Type Length() const
{ {
return std::hypot(x, y, z); return std::hypot(x, y, z);
} }
[[nodiscard]] constexpr float Length2D() const [[nodiscard]] constexpr Type Length2D() const
{ {
return Vector2::Length(); return Vector2::Length();
} }
[[nodiscard]] float DistTo(const Vector3& vOther) const [[nodiscard]] Type DistTo(const Vector3& vOther) const
{ {
return (*this - vOther).Length(); return (*this - vOther).Length();
} }
[[nodiscard]] constexpr Vector3 Normalized() const [[nodiscard]] constexpr Vector3 Normalized() const
{ {
const float length = this->Length(); const Type length = this->Length();
return length != 0 ? *this / length : *this; return length != 0 ? *this / length : *this;
} }
#else #else
[[nodiscard]] float Length() const [[nodiscard]] Type Length() const
{ {
return std::hypot(x, y, z); return std::hypot(this->x, this->y, z);
} }
[[nodiscard]] Vector3 Normalized() const [[nodiscard]] Vector3 Normalized() const
{ {
const float length = this->Length(); const Type length = this->Length();
return length != 0 ? *this / length : *this; return length != 0 ? *this / length : *this;
} }
[[nodiscard]] float Length2D() const [[nodiscard]] Type Length2D() const
{ {
return Vector2::Length(); return Vector2<Type>::Length();
} }
[[nodiscard]] float DistTo(const Vector3& vOther) const [[nodiscard]] Type DistTo(const Vector3& vOther) const
{ {
return (*this - vOther).Length(); return (*this - vOther).Length();
} }
#endif #endif
[[nodiscard]] constexpr float LengthSqr() const [[nodiscard]] constexpr Type LengthSqr() const
{ {
return Vector2::LengthSqr() + z * z; return Vector2<Type>::LengthSqr() + z * z;
} }
[[nodiscard]] constexpr Vector3 operator-() const [[nodiscard]] constexpr Vector3 operator-() const
{ {
return {-x, -y, -z}; return {-this->x, -this->y, -z};
} }
[[nodiscard]] constexpr Vector3 operator+(const Vector3& v) const [[nodiscard]] constexpr Vector3 operator+(const Vector3& v) const
{ {
return {x + v.x, y + v.y, z + v.z}; return {this->x + v.x, this->y + v.y, z + v.z};
} }
[[nodiscard]] constexpr Vector3 operator-(const Vector3& v) const [[nodiscard]] constexpr Vector3 operator-(const Vector3& v) const
{ {
return {x - v.x, y - v.y, z - v.z}; return {this->x - v.x, this->y - v.y, z - v.z};
} }
[[nodiscard]] constexpr Vector3 operator*(const float fl) const [[nodiscard]] constexpr Vector3 operator*(const float fl) const
{ {
return {x * fl, y * fl, z * fl}; return {this->x * fl, this->y * fl, z * fl};
} }
[[nodiscard]] constexpr Vector3 operator*(const Vector3& v) const [[nodiscard]] constexpr Vector3 operator*(const Vector3& v) const
{ {
return {x * v.x, y * v.y, z * v.z}; return {this->x * v.x, this->y * v.y, z * v.z};
} }
[[nodiscard]] constexpr Vector3 operator/(const float fl) const [[nodiscard]] constexpr Vector3 operator/(const float fl) const
{ {
return {x / fl, y / fl, z / fl}; return {this->x / fl, this->y / fl, z / fl};
} }
[[nodiscard]] constexpr Vector3 operator/(const Vector3& v) const [[nodiscard]] constexpr Vector3 operator/(const Vector3& v) const
{ {
return {x / v.x, y / v.y, z / v.z}; return {this->x / v.x, this->y / v.y, z / v.z};
} }
[[nodiscard]] constexpr Vector3 Cross(const Vector3 &v) const [[nodiscard]] constexpr Vector3 Cross(const Vector3 &v) const
{ {
return return
{ {
y * v.z - z * v.y, this->y * v.z - z * v.y,
z * v.x - x * v.z, z * v.x - this->x * v.z,
x * v.y - y * v.x this->x * v.y - this->y * v.x
}; };
} }
[[nodiscard]] constexpr float Sum() const [[nodiscard]] constexpr Type Sum() const
{ {
return Sum2D() + z; return Sum2D() + z;
} }
@@ -237,16 +236,27 @@ namespace omath
return false; return false;
} }
[[nodiscard]] constexpr float Sum2D() const [[nodiscard]] constexpr Type Sum2D() const
{ {
return Vector2::Sum(); return Vector2<Type>::Sum();
} }
[[nodiscard]] Vector3 ViewAngleTo(const Vector3& other) const; [[nodiscard]] constexpr std::tuple<Type, Type, Type> AsTuple() const
[[nodiscard]] constexpr std::tuple<float, float, float> AsTuple() const
{ {
return std::make_tuple(x, y, z); return std::make_tuple(this->x, this->y, z);
}
[[nodiscard]] Vector3 ViewAngleTo(const Vector3 &other) const
{
const float distance = DistTo(other);
const auto delta = other - *this;
return
{
angles::RadiansToDegrees(std::asin(delta.z / distance)),
angles::RadiansToDegrees(std::atan2(delta.y, delta.x)),
0
};
} }
}; };
} }
@@ -254,9 +264,9 @@ namespace omath
namespace std namespace std
{ {
template<> template<>
struct hash<omath::Vector3> struct hash<omath::Vector3<float>>
{ {
std::size_t operator()(const omath::Vector3& vec) const noexcept std::size_t operator()(const omath::Vector3<float>& vec) const noexcept
{ {
std::size_t hash = 0; std::size_t hash = 0;
constexpr std::hash<float> hasher; constexpr std::hash<float> hasher;

173
include/omath/vector4.hpp Normal file
View File

@@ -0,0 +1,173 @@
//
// Vector4.h
//
#pragma once
#include <algorithm>
#include <omath/vector3.hpp>
namespace omath
{
template <class Type>
class Vector4 : public Vector3<Type>
{
public:
Type w;
constexpr Vector4(const Type& x, const Type& y, const Type& z, const Type& w) : Vector3<Type>(x, y, z), w(w) {}
constexpr Vector4() : Vector3<Type>(), w(0) {};
[[nodiscard]]
constexpr bool operator==(const Vector4& src) const
{
return Vector3<Type>::operator==(src) && w == src.w;
}
[[nodiscard]]
constexpr bool operator!=(const Vector4& src) const
{
return !(*this == src);
}
constexpr Vector4& operator+=(const Vector4& v)
{
Vector3<Type>::operator+=(v);
w += v.w;
return *this;
}
constexpr Vector4& operator-=(const Vector4& v)
{
Vector3<Type>::operator-=(v);
w -= v.w;
return *this;
}
constexpr Vector4& operator*=(const float scalar)
{
Vector3<Type>::operator*=(scalar);
w *= scalar;
return *this;
}
constexpr Vector4& operator*=(const Vector4& v)
{
Vector3<Type>::operator*=(v);
w *= v.w;
return *this;
}
constexpr Vector4& operator/=(const float scalar)
{
Vector3<Type>::operator/=(scalar);
w /= scalar;
return *this;
}
constexpr Vector4& operator/=(const Vector4& v)
{
Vector3<Type>::operator/=(v);
w /= v.w;
return *this;
}
[[nodiscard]] constexpr Type LengthSqr() const
{
return Vector3<Type>::LengthSqr() + w * w;
}
[[nodiscard]] constexpr Type Dot(const Vector4& vOther) const
{
return Vector3<Type>::Dot(vOther) + w * vOther.w;
}
[[nodiscard]] Vector3<Type> Length() const
{
return std::sqrt(LengthSqr());
}
constexpr Vector4& Abs()
{
Vector3<Type>::Abs();
w = w < 0.f ? -w : w;
return *this;
}
constexpr Vector4& Clamp(const Type& min, const Type& max)
{
this->x = std::clamp(this->x, min, max);
this->y = std::clamp(this->y, min, max);
this->z = std::clamp(this->z, min, max);
return *this;
}
[[nodiscard]]
constexpr Vector4 operator-() const
{
return {-this->x, -this->y, -this->z, -w};
}
[[nodiscard]]
constexpr Vector4 operator+(const Vector4& v) const
{
return {this->x + v.x, this->y + v.y, this->z + v.z, w + v.w};
}
[[nodiscard]]
constexpr Vector4 operator-(const Vector4& v) const
{
return {this->x - v.x, this->y - v.y, this->z - v.z, w - v.w};
}
[[nodiscard]]
constexpr Vector4 operator*(const Type& scalar) const
{
return {this->x * scalar, this->y * scalar, this->z * scalar, w * scalar};
}
[[nodiscard]]
constexpr Vector4 operator*(const Vector4& v) const
{
return {this->x * v.x, this->y * v.y, this->z * v.z, w * v.w};
}
[[nodiscard]]
constexpr Vector4 operator/(const Type& scalar) const
{
return {this->x / scalar, this->y / scalar, this->z / scalar, w / scalar};
}
[[nodiscard]]
constexpr Vector4 operator/(const Vector4& v) const
{
return {this->x / v.x, this->y / v.y, this->z / v.z, w / v.w};
}
[[nodiscard]]
constexpr Type Sum() const
{
return Vector3<Type>::Sum() + w;
}
#ifdef OMATH_IMGUI_INTEGRATION
[[nodiscard]]
ImVec4 ToImVec4() const
{
return
{
static_cast<float>(this->x),
static_cast<float>(this->y),
static_cast<float>(this->z),
static_cast<float>(w),
};
}
#endif
};
}

View File

@@ -1,9 +1,6 @@
target_sources(omath PRIVATE target_sources(omath PRIVATE
Vector3.cpp matrix.cpp
Matrix.cpp
color.cpp color.cpp
Vector4.cpp
Vector2.cpp
) )
add_subdirectory(projectile_prediction) add_subdirectory(projectile_prediction)

View File

@@ -1,11 +0,0 @@
//
// Created by Vlad on 02.09.2024.
//
#include "omath/Vector2.hpp"
#include <cmath>
namespace omath
{
}

View File

@@ -1,23 +0,0 @@
//
// Created by vlad on 10/28/23.
//
#include <omath/Vector3.hpp>
#include <cmath>
#include <omath/Angles.hpp>
namespace omath
{
Vector3 Vector3::ViewAngleTo(const Vector3 &other) const
{
const float distance = DistTo(other);
const auto delta = other - *this;
return
{
angles::RadiansToDegrees(std::asin(delta.z / distance)),
angles::RadiansToDegrees(std::atan2(delta.y, delta.x)),
0.f
};
}
}

View File

@@ -1,16 +0,0 @@
//
// Vector4.cpp
//
#include "omath/Vector4.hpp"
#include <cmath>
namespace omath
{
float Vector4::Length() const
{
return std::sqrt(LengthSqr());
}
}

View File

@@ -1,3 +1,3 @@
target_sources(omath PRIVATE target_sources(omath PRIVATE
LineTracer.cpp line_tracer.cpp
) )

View File

@@ -1,25 +1,25 @@
// //
// Created by Orange on 11/13/2024. // Created by Orange on 11/13/2024.
// //
#include "omath/collision/LineTracer.hpp" #include "omath/collision/line_tracer.hpp"
namespace omath::collision namespace omath::collision
{ {
bool LineTracer::CanTraceLine(const Ray& ray, const Triangle<Vector3>& triangle) bool LineTracer::CanTraceLine(const Ray& ray, const Triangle<Vector3<float>>& triangle)
{ {
return GetRayHitPoint(ray, triangle) == ray.end; return GetRayHitPoint(ray, triangle) == ray.end;
} }
Vector3 Ray::DirectionVector() const Vector3<float> Ray::DirectionVector() const
{ {
return end - start; return end - start;
} }
Vector3 Ray::DirectionVectorNormalized() const Vector3<float> Ray::DirectionVectorNormalized() const
{ {
return DirectionVector().Normalized(); return DirectionVector().Normalized();
} }
Vector3 LineTracer::GetRayHitPoint(const Ray& ray, const Triangle<Vector3>& triangle) Vector3<float> LineTracer::GetRayHitPoint(const Ray& ray, const Triangle<Vector3<float>>& triangle)
{ {
constexpr float kEpsilon = std::numeric_limits<float>::epsilon(); constexpr float kEpsilon = std::numeric_limits<float>::epsilon();

View File

@@ -1,2 +1,4 @@
add_subdirectory(Source) add_subdirectory(source_engine)
add_subdirectory(OpenGL) add_subdirectory(opengl_engine)
add_subdirectory(iw_engine)
add_subdirectory(unity_engine)

View File

@@ -1 +0,0 @@
target_sources(omath PRIVATE Camera.cpp)

View File

@@ -1 +0,0 @@
target_sources(omath PRIVATE Camera.cpp)

View File

@@ -0,0 +1 @@
target_sources(omath PRIVATE camera.cpp formulas.cpp)

View File

@@ -0,0 +1,34 @@
//
// Created by Vlad on 3/17/2025.
//
#include "omath/engines/iw_engine/camera.hpp"
#include "omath/engines/iw_engine/formulas.hpp"
namespace omath::iw_engine
{
Camera::Camera(const Vector3<float>& position, const ViewAngles& viewAngles, const projection::ViewPort& viewPort,
const Angle<float, 0.f, 180.f, AngleFlags::Clamped>& fov, const float near, const float far) :
projection::Camera<Mat4x4, ViewAngles>(position, viewAngles, viewPort, fov, near, far)
{
}
void Camera::LookAt([[maybe_unused]] const Vector3<float>& target)
{
const float distance = m_origin.DistTo(target);
const auto delta = target - m_origin;
m_viewAngles.pitch = PitchAngle::FromRadians(std::asin(delta.z / distance));
m_viewAngles.yaw = -YawAngle::FromRadians(std::atan2(delta.y, delta.x));
m_viewAngles.roll = RollAngle::FromRadians(0.f);
}
Mat4x4 Camera::CalcViewMatrix() const
{
return iw_engine::CalcViewMatrix(m_viewAngles, m_origin);
}
Mat4x4 Camera::CalcProjectionMatrix() const
{
return CalcPerspectiveProjectionMatrix(m_fieldOfView.AsDegrees(), m_viewPort.AspectRatio(), m_nearPlaneDistance,
m_farPlaneDistance);
}
} // namespace omath::openg

View File

@@ -0,0 +1,50 @@
//
// Created by Vlad on 3/19/2025.
//
#include "omath/engines/iw_engine/formulas.hpp"
namespace omath::iw_engine
{
Vector3<float> ForwardVector(const ViewAngles& angles)
{
const auto vec = MatRotation(angles) * MatColumnFromVector(kAbsForward);
return {vec.At(0, 0), vec.At(1, 0), vec.At(2, 0)};
}
Vector3<float> RightVector(const ViewAngles& angles)
{
const auto vec = MatRotation(angles) * MatColumnFromVector(kAbsRight);
return {vec.At(0, 0), vec.At(1, 0), vec.At(2, 0)};
}
Vector3<float> UpVector(const ViewAngles& angles)
{
const auto vec = MatRotation(angles) * MatColumnFromVector(kAbsUp);
return {vec.At(0, 0), vec.At(1, 0), vec.At(2, 0)};
}
Mat4x4 CalcViewMatrix(const ViewAngles& angles, const Vector3<float>& cam_origin)
{
return MatCameraView(ForwardVector(angles), RightVector(angles), UpVector(angles), cam_origin);
}
Mat4x4 CalcPerspectiveProjectionMatrix(const float fieldOfView, const float aspectRatio, const float near,
const float far)
{
// NOTE: Need magic number to fix fov calculation, since IW engine inherit Quake proj matrix calculation
constexpr auto kMultiplyFactor = 0.75f;
const float fovHalfTan = std::tan(angles::DegreesToRadians(fieldOfView) / 2.f) * kMultiplyFactor;
return {
{1.f / (aspectRatio * fovHalfTan), 0, 0, 0},
{0, 1.f / (fovHalfTan), 0, 0},
{0, 0, (far + near) / (far - near), -(2.f * far * near) / (far - near)},
{0, 0, 1, 0},
};
};
} // namespace omath::iw_engine

View File

@@ -0,0 +1 @@
target_sources(omath PRIVATE camera.cpp formulas.cpp)

View File

@@ -1,19 +1,19 @@
// //
// Created by Orange on 12/23/2024. // Created by Orange on 12/23/2024.
// //
#include "omath/engines/OpenGL/Camera.hpp" #include "omath/engines/opengl_engine/camera.hpp"
#include "omath/engines/OpenGL/Formulas.hpp" #include "omath/engines/opengl_engine/formulas.hpp"
namespace omath::opengl namespace omath::opengl_engine
{ {
Camera::Camera(const Vector3& position, const ViewAngles& viewAngles, const projection::ViewPort& viewPort, Camera::Camera(const Vector3<float>& position, const ViewAngles& viewAngles, const projection::ViewPort& viewPort,
const Angle<float, 0.f, 180.f, AngleFlags::Clamped>& fov, const float near, const float far) : const Angle<float, 0.f, 180.f, AngleFlags::Clamped>& fov, const float near, const float far) :
projection::Camera<Mat4x4, ViewAngles>(position, viewAngles, viewPort, fov, near, far) projection::Camera<Mat4x4, ViewAngles>(position, viewAngles, viewPort, fov, near, far)
{ {
} }
void Camera::LookAt([[maybe_unused]] const Vector3& target) void Camera::LookAt([[maybe_unused]] const Vector3<float>& target)
{ {
const float distance = m_origin.DistTo(target); const float distance = m_origin.DistTo(target);
const auto delta = target - m_origin; const auto delta = target - m_origin;
@@ -25,7 +25,7 @@ namespace omath::opengl
} }
Mat4x4 Camera::CalcViewMatrix() const Mat4x4 Camera::CalcViewMatrix() const
{ {
return opengl::CalcViewMatrix(m_viewAngles, m_origin); return opengl_engine::CalcViewMatrix(m_viewAngles, m_origin);
} }
Mat4x4 Camera::CalcProjectionMatrix() const Mat4x4 Camera::CalcProjectionMatrix() const
{ {

View File

@@ -0,0 +1,45 @@
//
// Created by Vlad on 3/19/2025.
//
#include "omath/engines/opengl_engine/formulas.hpp"
namespace omath::opengl_engine
{
Vector3<float> ForwardVector(const ViewAngles& angles)
{
const auto vec = MatRotation(angles) * MatColumnFromVector(kAbsForward);
return {vec.At(0, 0), vec.At(1, 0), vec.At(2, 0)};
}
Vector3<float> RightVector(const ViewAngles& angles)
{
const auto vec = MatRotation(angles) * MatColumnFromVector(kAbsRight);
return {vec.At(0, 0), vec.At(1, 0), vec.At(2, 0)};
}
Vector3<float> UpVector(const ViewAngles& angles)
{
const auto vec = MatRotation(angles) * MatColumnFromVector(kAbsUp);
return {vec.At(0, 0), vec.At(1, 0), vec.At(2, 0)};
}
Mat4x4 CalcViewMatrix(const ViewAngles& angles, const Vector3<float>& cam_origin)
{
return MatCameraView<float, MatStoreType::COLUMN_MAJOR>(-ForwardVector(angles), RightVector(angles),
UpVector(angles), cam_origin);
}
Mat4x4 CalcPerspectiveProjectionMatrix(const float fieldOfView, const float aspectRatio, const float near,
const float far)
{
const float fovHalfTan = std::tan(angles::DegreesToRadians(fieldOfView) / 2.f);
return {
{1.f / (aspectRatio * fovHalfTan), 0, 0, 0},
{0, 1.f / (fovHalfTan), 0, 0},
{0, 0, -(far + near) / (far - near), -(2.f * far * near) / (far - near)},
{0, 0, -1, 0},
};
}
} // namespace omath::opengl_engine

View File

@@ -0,0 +1 @@
target_sources(omath PRIVATE camera.cpp formulas.cpp)

View File

@@ -1,19 +1,19 @@
// //
// Created by Orange on 12/4/2024. // Created by Orange on 12/4/2024.
// //
#include "omath/engines/Source/Camera.hpp" #include "omath/engines/source_engine/camera.hpp"
#include "omath/engines/Source/Formulas.hpp" #include "omath/engines/source_engine/formulas.hpp"
namespace omath::source namespace omath::source_engine
{ {
Camera::Camera(const Vector3& position, const ViewAngles& viewAngles, const projection::ViewPort& viewPort, Camera::Camera(const Vector3<float>& position, const ViewAngles& viewAngles, const projection::ViewPort& viewPort,
const projection::FieldOfView& fov, const float near, const float far) : const projection::FieldOfView& fov, const float near, const float far) :
projection::Camera<Mat4x4, ViewAngles>(position, viewAngles, viewPort, fov, near, far) projection::Camera<Mat4x4, ViewAngles>(position, viewAngles, viewPort, fov, near, far)
{ {
} }
void Camera::LookAt(const Vector3& target) void Camera::LookAt(const Vector3<float>& target)
{ {
const float distance = m_origin.DistTo(target); const float distance = m_origin.DistTo(target);
const auto delta = target - m_origin; const auto delta = target - m_origin;
@@ -26,7 +26,7 @@ namespace omath::source
Mat4x4 Camera::CalcViewMatrix() const Mat4x4 Camera::CalcViewMatrix() const
{ {
return source::CalcViewMatrix(m_viewAngles, m_origin); return source_engine::CalcViewMatrix(m_viewAngles, m_origin);
} }
Mat4x4 Camera::CalcProjectionMatrix() const Mat4x4 Camera::CalcProjectionMatrix() const

View File

@@ -1,47 +1,40 @@
// //
// Created by Orange on 12/4/2024. // Created by Vlad on 3/19/2025.
// //
#pragma once #include <omath/engines/source_engine/formulas.hpp>
#include "Constants.hpp"
namespace omath::source
namespace omath::source_engine
{ {
[[nodiscard]] Vector3<float> ForwardVector(const ViewAngles& angles)
inline Vector3 ForwardVector(const ViewAngles& angles)
{ {
const auto vec = MatRotation(angles) * MatColumnFromVector(kAbsForward); const auto vec = MatRotation(angles) * MatColumnFromVector(kAbsForward);
return {vec.At(0, 0), vec.At(1, 0), vec.At(2, 0)}; return {vec.At(0, 0), vec.At(1, 0), vec.At(2, 0)};
} }
[[nodiscard]] Vector3<float> RightVector(const ViewAngles& angles)
inline Vector3 RightVector(const ViewAngles& angles)
{ {
const auto vec = MatRotation(angles) * MatColumnFromVector(kAbsRight); const auto vec = MatRotation(angles) * MatColumnFromVector(kAbsRight);
return {vec.At(0, 0), vec.At(1, 0), vec.At(2, 0)}; return {vec.At(0, 0), vec.At(1, 0), vec.At(2, 0)};
} }
Vector3<float> UpVector(const ViewAngles& angles)
[[nodiscard]]
inline Vector3 UpVector(const ViewAngles& angles)
{ {
const auto vec = MatRotation(angles) * MatColumnFromVector(kAbsUp); const auto vec = MatRotation(angles) * MatColumnFromVector(kAbsUp);
return {vec.At(0, 0), vec.At(1, 0), vec.At(2, 0)}; return {vec.At(0, 0), vec.At(1, 0), vec.At(2, 0)};
} }
[[nodiscard]] inline Mat4x4 CalcViewMatrix(const ViewAngles& angles, const Vector3& cam_origin) Mat4x4 CalcViewMatrix(const ViewAngles& angles, const Vector3<float>& cam_origin)
{ {
return MatCameraView(ForwardVector(angles), RightVector(angles), UpVector(angles), cam_origin); return MatCameraView(ForwardVector(angles), RightVector(angles), UpVector(angles), cam_origin);
} }
Mat4x4 CalcPerspectiveProjectionMatrix(const float fieldOfView, const float aspectRatio, const float near,
[[nodiscard]] 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 // NOTE: Need magic number to fix fov calculation, since source inherit Quake proj matrix calculation
// and use tricky projection matrix formula.
constexpr auto kMultiplyFactor = 0.75f; constexpr auto kMultiplyFactor = 0.75f;
const float fovHalfTan = std::tan(angles::DegreesToRadians(fieldOfView) / 2.f) * kMultiplyFactor; const float fovHalfTan = std::tan(angles::DegreesToRadians(fieldOfView) / 2.f) * kMultiplyFactor;
@@ -51,7 +44,6 @@ namespace omath::source
{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, (far + near) / (far - near), -(2.f * far * near) / (far - near)},
{0, 0, 1, 0}, {0, 0, 1, 0},
}; };
} }
} // namespace omath::source } // namespace omath::source_engine

View File

@@ -0,0 +1 @@
target_sources(omath PRIVATE formulas.cpp camera.cpp)

View File

@@ -0,0 +1,28 @@
//
// Created by Vlad on 3/22/2025.
//
#include <omath/engines/unity_engine/camera.hpp>
#include <omath/engines/unity_engine/formulas.hpp>
namespace omath::unity_engine
{
Camera::Camera(const Vector3<float>& position, const ViewAngles& viewAngles, const projection::ViewPort& viewPort,
const projection::FieldOfView& fov, const float near, const float far) :
projection::Camera<Mat4x4, ViewAngles>(position, viewAngles, viewPort, fov, near, far)
{
}
void Camera::LookAt([[maybe_unused]] const Vector3<float>& target)
{
throw std::runtime_error("Not implemented");
}
Mat4x4 Camera::CalcViewMatrix() const
{
return unity_engine::CalcViewMatrix(m_viewAngles, m_origin);
}
Mat4x4 Camera::CalcProjectionMatrix() const
{
return CalcPerspectiveProjectionMatrix(m_fieldOfView.AsDegrees(), m_viewPort.AspectRatio(), m_nearPlaneDistance,
m_farPlaneDistance);
}
} // namespace omath::unity_engine

View File

@@ -0,0 +1,45 @@
//
// Created by Vlad on 3/22/2025.
//
#include "omath/engines/unity_engine/formulas.hpp"
namespace omath::unity_engine
{
Vector3<float> unity_engine::ForwardVector(const ViewAngles& angles)
{
const auto vec = MatRotation(angles) * MatColumnFromVector(kAbsForward);
return {vec.At(0, 0), vec.At(1, 0), vec.At(2, 0)};
}
Vector3<float> RightVector(const ViewAngles& angles)
{
const auto vec = MatRotation(angles) * MatColumnFromVector(kAbsRight);
return {vec.At(0, 0), vec.At(1, 0), vec.At(2, 0)};
}
Vector3<float> UpVector(const ViewAngles& angles)
{
const auto vec = MatRotation(angles) * MatColumnFromVector(kAbsUp);
return {vec.At(0, 0), vec.At(1, 0), vec.At(2, 0)};
}
Mat4x4 CalcViewMatrix(const ViewAngles& angles, const Vector3<float>& cam_origin)
{
return MatCameraView<float, MatStoreType::ROW_MAJOR>(ForwardVector(angles), -RightVector(angles),
UpVector(angles), cam_origin);
}
Mat4x4 CalcPerspectiveProjectionMatrix(const float fieldOfView, const float aspectRatio, const float near,
const float far)
{
const float fovHalfTan = std::tan(angles::DegreesToRadians(fieldOfView) / 2.f);
return {
{1.f / (aspectRatio * fovHalfTan), 0, 0, 0},
{0, 1.f / (fovHalfTan), 0, 0},
{0, 0, (far + near) / (far - near), -(2.f * far * near) / (far - near)},
{0, 0, -1.f, 0},
};
}
} // namespace omath::unity_engine

View File

@@ -315,7 +315,7 @@ namespace omath
}; };
} }
Matrix Matrix::TranslationMatrix(const Vector3& diff) Matrix Matrix::TranslationMatrix(const Vector3<float>& diff)
{ {
return { return {
{1.f, 0.f, 0.f, 0.f}, {1.f, 0.f, 0.f, 0.f},
@@ -325,7 +325,7 @@ namespace omath
}; };
} }
Matrix Matrix::OrientationMatrix(const Vector3& forward, const Vector3& right, const Vector3& up) Matrix Matrix::OrientationMatrix(const Vector3<float>& forward, const Vector3<float>& right, const Vector3<float>& up)
{ {
return { return {
{right.x, up.x, forward.x, 0.f}, {right.x, up.x, forward.x, 0.f},

View File

@@ -1 +1 @@
target_sources(omath PRIVATE NavigationMesh.cpp Astar.cpp) target_sources(omath PRIVATE navigation_mesh.cpp a_star.cpp)

View File

@@ -1,7 +1,7 @@
// //
// Created by Vlad on 28.07.2024. // Created by Vlad on 28.07.2024.
// //
#include "omath/pathfinding/Astar.hpp" #include "omath/pathfinding/a_star.hpp"
#include <algorithm> #include <algorithm>
#include <optional> #include <optional>
@@ -13,15 +13,15 @@ namespace omath::pathfinding
{ {
struct PathNode final struct PathNode final
{ {
std::optional<Vector3> cameFrom; std::optional<Vector3<float>> cameFrom;
float gCost = 0.f; float gCost = 0.f;
}; };
std::vector<Vector3> Astar::ReconstructFinalPath(const std::unordered_map<Vector3, PathNode>& closedList, std::vector<Vector3<float>> Astar::ReconstructFinalPath(const std::unordered_map<Vector3<float>, PathNode>& closedList,
const Vector3& current) const Vector3<float>& current)
{ {
std::vector<Vector3> path; std::vector<Vector3<float>> path;
std::optional currentOpt = current; std::optional currentOpt = current;
while (currentOpt) while (currentOpt)
@@ -39,7 +39,7 @@ namespace omath::pathfinding
std::ranges::reverse(path); std::ranges::reverse(path);
return path; return path;
} }
auto Astar::GetPerfectNode(const std::unordered_map<Vector3, PathNode>& openList, const Vector3& endVertex) auto Astar::GetPerfectNode(const std::unordered_map<Vector3<float>, PathNode>& openList, const Vector3<float>& endVertex)
{ {
return std::ranges::min_element(openList, return std::ranges::min_element(openList,
[&endVertex](const auto& a, const auto& b) [&endVertex](const auto& a, const auto& b)
@@ -50,10 +50,10 @@ namespace omath::pathfinding
}); });
} }
std::vector<Vector3> Astar::FindPath(const Vector3& start, const Vector3& end, const NavigationMesh& navMesh) std::vector<Vector3<float>> Astar::FindPath(const Vector3<float>& start, const Vector3<float>& end, const NavigationMesh& navMesh)
{ {
std::unordered_map<Vector3, PathNode> closedList; std::unordered_map<Vector3<float>, PathNode> closedList;
std::unordered_map<Vector3, PathNode> openList; std::unordered_map<Vector3<float>, PathNode> openList;
auto maybeStartVertex = navMesh.GetClosestVertex(start); auto maybeStartVertex = navMesh.GetClosestVertex(start);
auto maybeEndVertex = navMesh.GetClosestVertex(end); auto maybeEndVertex = navMesh.GetClosestVertex(end);

View File

@@ -1,13 +1,13 @@
// //
// Created by Vlad on 28.07.2024. // Created by Vlad on 28.07.2024.
// //
#include "omath/pathfinding/NavigationMesh.hpp" #include "omath/pathfinding/navigation_mesh.hpp"
#include <stdexcept>
#include <algorithm> #include <algorithm>
#include <stdexcept>
namespace omath::pathfinding namespace omath::pathfinding
{ {
std::expected<Vector3, std::string> NavigationMesh::GetClosestVertex(const Vector3 &point) const std::expected<Vector3<float>, std::string> NavigationMesh::GetClosestVertex(const Vector3<float> &point) const
{ {
const auto res = std::ranges::min_element(m_verTextMap, const auto res = std::ranges::min_element(m_verTextMap,
[&point](const auto& a, const auto& b) [&point](const auto& a, const auto& b)
@@ -21,7 +21,7 @@ namespace omath::pathfinding
return res->first; return res->first;
} }
const std::vector<Vector3>& NavigationMesh::GetNeighbors(const Vector3 &vertex) const const std::vector<Vector3<float>>& NavigationMesh::GetNeighbors(const Vector3<float> &vertex) const
{ {
return m_verTextMap.at(vertex); return m_verTextMap.at(vertex);
} }
@@ -73,18 +73,18 @@ namespace omath::pathfinding
while (offset < raw.size()) while (offset < raw.size())
{ {
Vector3 vertex; Vector3<float> vertex;
loadFromVector(raw, offset, vertex); loadFromVector(raw, offset, vertex);
uint16_t neighborsCount; uint16_t neighborsCount;
loadFromVector(raw, offset, neighborsCount); loadFromVector(raw, offset, neighborsCount);
std::vector<Vector3> neighbors; std::vector<Vector3<float>> neighbors;
neighbors.reserve(neighborsCount); neighbors.reserve(neighborsCount);
for (size_t i = 0; i < neighborsCount; ++i) for (size_t i = 0; i < neighborsCount; ++i)
{ {
Vector3 neighbor; Vector3<float> neighbor;
loadFromVector(raw, offset, neighbor); loadFromVector(raw, offset, neighbor);
neighbors.push_back(neighbor); neighbors.push_back(neighbor);
} }

View File

@@ -1 +1 @@
target_sources(omath PRIVATE ProjPredEngineLegacy.cpp Projectile.cpp Target.cpp ProjPredEngineAVX2.cpp ProjPredEngine.cpp) target_sources(omath PRIVATE proj_pred_engine_legacy.cpp projectile.cpp target.cpp proj_pred_engine_avx2.cpp proj_pred_engine.cpp)

View File

@@ -1,21 +0,0 @@
//
// Created by Vlad on 6/9/2024.
//
#include "omath/projectile_prediction/Projectile.hpp"
#include <omath/engines/Source/Formulas.hpp>
namespace omath::projectile_prediction
{
Vector3 Projectile::PredictPosition(const float pitch, const float yaw, const float time, const float gravity) const
{
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

View File

@@ -1,7 +1,7 @@
// //
// Created by Vlad on 2/23/2025. // Created by Vlad on 2/23/2025.
// //
#include "omath/projectile_prediction/ProjPredEngine.hpp" #include "omath/projectile_prediction/proj_pred_engine.hpp"
namespace omath::projectile_prediction namespace omath::projectile_prediction

View File

@@ -1,14 +1,16 @@
// //
// Created by Vlad on 2/23/2025. // Created by Vlad on 2/23/2025.
// //
#include "omath/projectile_prediction/ProjPredEngineAVX2.hpp" #include "omath/projectile_prediction/proj_pred_engine_avx2.hpp"
#include "source_location"
namespace omath::projectile_prediction namespace omath::projectile_prediction
{ {
std::optional<Vector3> ProjPredEngineAVX2::MaybeCalculateAimPoint(const Projectile& projectile, std::optional<Vector3<float>>
const Target& target) const ProjPredEngineAVX2::MaybeCalculateAimPoint([[maybe_unused]] const Projectile& projectile,
[[maybe_unused]] const Target& target) const
{ {
#ifdef OMATH_USE_AVX2
const float bulletGravity = m_gravityConstant * projectile.m_gravityScale; const float bulletGravity = m_gravityConstant * projectile.m_gravityScale;
const float v0 = projectile.m_launchSpeed; const float v0 = projectile.m_launchSpeed;
const float v0Sqr = v0 * v0; const float v0Sqr = v0 * v0;
@@ -31,8 +33,8 @@ namespace omath::projectile_prediction
_mm256_fmadd_ps(_mm256_set1_ps(target.m_velocity.y), times, _mm256_set1_ps(target.m_origin.y)); _mm256_fmadd_ps(_mm256_set1_ps(target.m_velocity.y), times, _mm256_set1_ps(target.m_origin.y));
const __m256 timesSq = _mm256_mul_ps(times, times); const __m256 timesSq = _mm256_mul_ps(times, times);
const __m256 targetZ = _mm256_fmadd_ps(_mm256_set1_ps(target.m_velocity.z), times, const __m256 targetZ = _mm256_fmadd_ps(_mm256_set1_ps(target.m_velocity.z), times,
_mm256_fnmadd_ps(_mm256_set1_ps(0.5f * m_gravityConstant), timesSq, _mm256_fnmadd_ps(_mm256_set1_ps(0.5f * m_gravityConstant), timesSq,
_mm256_set1_ps(target.m_origin.z))); _mm256_set1_ps(target.m_origin.z)));
const __m256 deltaX = _mm256_sub_ps(targetX, _mm256_set1_ps(projOrigin.x)); const __m256 deltaX = _mm256_sub_ps(targetX, _mm256_set1_ps(projOrigin.x));
const __m256 deltaY = _mm256_sub_ps(targetY, _mm256_set1_ps(projOrigin.y)); const __m256 deltaY = _mm256_sub_ps(targetY, _mm256_set1_ps(projOrigin.y));
@@ -106,12 +108,13 @@ namespace omath::projectile_prediction
} }
ProjPredEngineAVX2::ProjPredEngineAVX2(const float gravityConstant, const float simulationTimeStep, ProjPredEngineAVX2::ProjPredEngineAVX2(const float gravityConstant, const float simulationTimeStep,
const float maximumSimulationTime) : const float maximumSimulationTime) :
m_gravityConstant(gravityConstant), m_simulationTimeStep(maximumSimulationTime), m_gravityConstant(gravityConstant), m_simulationTimeStep(simulationTimeStep),
m_maximumSimulationTime(simulationTimeStep) m_maximumSimulationTime(maximumSimulationTime)
{ {
} }
std::optional<float> ProjPredEngineAVX2::CalculatePitch(const Vector3& projOrigin, const Vector3& targetPos, std::optional<float> ProjPredEngineAVX2::CalculatePitch(const Vector3<float>& projOrigin,
const float bulletGravity, const float v0, const float time) const Vector3<float>& targetPos, const float bulletGravity,
const float v0, const float time)
{ {
if (time <= 0.0f) if (time <= 0.0f)
return std::nullopt; return std::nullopt;
@@ -134,5 +137,9 @@ namespace omath::projectile_prediction
const float d = std::sqrt(dSqr); const float d = std::sqrt(dSqr);
const float tanTheta = term / d; const float tanTheta = term / d;
return angles::RadiansToDegrees(std::atan(tanTheta)); return angles::RadiansToDegrees(std::atan(tanTheta));
#else
throw std::runtime_error(
std::format("{} AVX2 feature is not enabled!", std::source_location::current().function_name()));
#endif
} }
} // namespace omath::projectile_prediction } // namespace omath::projectile_prediction

View File

@@ -1,6 +1,6 @@
#include "omath/projectile_prediction/ProjPredEngineLegacy.hpp" #include "omath/projectile_prediction/proj_pred_engine_legacy.hpp"
#include <cmath> #include <cmath>
#include <omath/Angles.hpp> #include <omath/angles.hpp>
namespace omath::projectile_prediction namespace omath::projectile_prediction
{ {
@@ -11,7 +11,7 @@ namespace omath::projectile_prediction
{ {
} }
std::optional<Vector3> ProjPredEngineLegacy::MaybeCalculateAimPoint(const Projectile& projectile, std::optional<Vector3<float>> ProjPredEngineLegacy::MaybeCalculateAimPoint(const Projectile& projectile,
const Target& target) const const Target& target) const
{ {
for (float time = 0.f; time < m_maximumSimulationTime; time += m_simulationTimeStep) for (float time = 0.f; time < m_maximumSimulationTime; time += m_simulationTimeStep)
@@ -36,7 +36,7 @@ namespace omath::projectile_prediction
std::optional<float> std::optional<float>
ProjPredEngineLegacy::MaybeCalculateProjectileLaunchPitchAngle(const Projectile& projectile, ProjPredEngineLegacy::MaybeCalculateProjectileLaunchPitchAngle(const Projectile& projectile,
const Vector3& targetPosition) const const Vector3<float>& targetPosition) const
{ {
const auto bulletGravity = m_gravityConstant * projectile.m_gravityScale; const auto bulletGravity = m_gravityConstant * projectile.m_gravityScale;
const auto delta = targetPosition - projectile.m_origin; const auto delta = targetPosition - projectile.m_origin;
@@ -57,7 +57,7 @@ namespace omath::projectile_prediction
return angles::RadiansToDegrees(angle); return angles::RadiansToDegrees(angle);
} }
bool ProjPredEngineLegacy::IsProjectileReachedTarget(const Vector3& targetPosition, const Projectile& projectile, bool ProjPredEngineLegacy::IsProjectileReachedTarget(const Vector3<float>& targetPosition, const Projectile& projectile,
const float pitch, const float time) const const float pitch, const float time) const
{ {
const auto yaw = projectile.m_origin.ViewAngleTo(targetPosition).y; const auto yaw = projectile.m_origin.ViewAngleTo(targetPosition).y;

View File

@@ -0,0 +1,21 @@
//
// Created by Vlad on 6/9/2024.
//
#include "omath/projectile_prediction/projectile.hpp"
#include <omath/engines/source_engine/formulas.hpp>
namespace omath::projectile_prediction
{
Vector3<float> Projectile::PredictPosition(const float pitch, const float yaw, const float time, const float gravity) const
{
auto currentPos = m_origin + source_engine::ForwardVector({source_engine::PitchAngle::FromDegrees(-pitch),
source_engine::YawAngle::FromDegrees(yaw),
source_engine::RollAngle::FromDegrees(0)}) *
m_launchSpeed * time;
currentPos.z -= (gravity * m_gravityScale) * (time * time) * 0.5f;
return currentPos;
}
} // namespace omath::prediction

View File

@@ -2,7 +2,7 @@
// Created by Vlad on 6/9/2024. // Created by Vlad on 6/9/2024.
// //
#include "omath/projectile_prediction/Projectile.hpp" #include "omath/projectile_prediction/projectile.hpp"
namespace omath::prediction namespace omath::prediction

View File

@@ -1 +1 @@
target_sources(omath PRIVATE Camera.cpp) target_sources(omath PRIVATE camera.cpp)

View File

@@ -1,7 +1,7 @@
// //
// Created by Vlad on 27.08.2024. // Created by Vlad on 27.08.2024.
// //
#include "omath/projection/Camera.hpp" #include "omath/projection/camera.hpp"
namespace omath::projection namespace omath::projection

View File

@@ -4,24 +4,25 @@ project(unit-tests)
include(GoogleTest) include(GoogleTest)
add_executable(unit-tests add_executable(unit-tests
general/UnitTestPrediction.cpp general/unit_test_prediction.cpp
general/UnitTestMatrix.cpp general/unit_test_matrix.cpp
general/UnitTestMat.cpp general/unit_test_mat.cpp
general/UnitTestAstar.cpp general/unit_test_a_star.cpp
general/UnitTestProjection.cpp general/unit_test_projection.cpp
general/UnitTestVector3.cpp general/unit_test_vector3.cpp
general/UnitTestVector2.cpp general/unit_test_vector2.cpp
general/UnitTestColor.cpp general/unit_test_color.cpp
general/UnitTestVector4.cpp general/unit_test_vector4.cpp
general/UnitTestLineTrace.cpp general/unit_test_line_trace.cpp
general/UnitTestAngles.cpp general/unit_test_angles.cpp
general/UnitTestViewAngles.cpp general/unit_test_view_angles.cpp
general/UnitTestAngle.cpp general/unit_test_angle.cpp
general/UnitTestTriangle.cpp general/unit_test_triangle.cpp
engines/UnitTestOpenGL.cpp engines/unit_test_open_gl.cpp
engines/UnitTestUnityEngine.cpp engines/unit_test_unity_engine.cpp
engines/UnitTestSourceEngine.cpp engines/unit_test_source_engine.cpp
engines/unit_test_iw_engine.cpp
) )
@@ -34,6 +35,6 @@ set_target_properties(unit-tests PROPERTIES
CXX_STANDARD_REQUIRED ON) CXX_STANDARD_REQUIRED ON)
target_link_libraries(unit-tests PRIVATE gtest gtest_main omath) target_link_libraries(unit-tests PRIVATE gtest gtest_main omath::omath)
gtest_discover_tests(unit-tests) gtest_discover_tests(unit-tests)

View File

@@ -1,69 +0,0 @@
//
// Created by Orange on 11/23/2024.
//
#include <gtest/gtest.h>
#include <omath/engines/Source/Camera.hpp>
#include <omath/engines/Source/Constants.hpp>
#include <omath/engines/Source/Formulas.hpp>
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, ProjectTargetMovedFromCamera)
{
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);
for (float distance = 0.02f; distance < 1000.f; distance += 0.01f)
{
const auto projected = cam.WorldToScreen({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);
}
}
TEST(UnitTestSourceEngine, CameraSetAndGetFov)
{
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);
EXPECT_EQ(cam.GetFieldOfView().AsDegrees(), 90.f);
cam.SetFieldOfView(omath::projection::FieldOfView::FromDegrees(50.f));
EXPECT_EQ(cam.GetFieldOfView().AsDegrees(), 50.f);
}
TEST(UnitTestSourceEngine, CameraSetAndGetOrigin)
{
auto cam = omath::source::Camera({0, 0, 0}, {}, {1920.f, 1080.f}, {}, 0.01f, 1000.f);
EXPECT_EQ(cam.GetOrigin(), omath::Vector3{});
cam.SetFieldOfView(omath::projection::FieldOfView::FromDegrees(50.f));
EXPECT_EQ(cam.GetFieldOfView().AsDegrees(), 50.f);
}

View File

@@ -1,3 +0,0 @@
//
// Created by Orange on 11/27/2024.
//

View File

@@ -0,0 +1,69 @@
//
// Created by Vlad on 3/17/2025.
//
#include <gtest/gtest.h>
#include <omath/engines/iw_engine/camera.hpp>
#include <omath/engines/iw_engine/constants.hpp>
#include <omath/engines/iw_engine/formulas.hpp>
TEST(UnitTestIwEngine, ForwardVector)
{
const auto forward = omath::iw_engine::ForwardVector({});
EXPECT_EQ(forward, omath::iw_engine::kAbsForward);
}
TEST(UnitTestIwEngine, RightVector)
{
const auto right = omath::iw_engine::RightVector({});
EXPECT_EQ(right, omath::iw_engine::kAbsRight);
}
TEST(UnitTestIwEngine, UpVector)
{
const auto up = omath::iw_engine::UpVector({});
EXPECT_EQ(up, omath::iw_engine::kAbsUp);
}
TEST(UnitTestIwEngine, ProjectTargetMovedFromCamera)
{
constexpr auto fov = omath::projection::FieldOfView::FromDegrees(90.f);
const auto cam = omath::iw_engine::Camera({0, 0, 0}, {}, {1920.f, 1080.f}, fov, 0.01f, 1000.f);
for (float distance = 0.02f; distance < 1000.f; distance += 0.01f)
{
const auto projected = cam.WorldToScreen({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);
}
}
TEST(UnitTestIwEngine, CameraSetAndGetFov)
{
constexpr auto fov = omath::projection::FieldOfView::FromDegrees(90.f);
auto cam = omath::iw_engine::Camera({0, 0, 0}, {}, {1920.f, 1080.f}, fov, 0.01f, 1000.f);
EXPECT_EQ(cam.GetFieldOfView().AsDegrees(), 90.f);
cam.SetFieldOfView(omath::projection::FieldOfView::FromDegrees(50.f));
EXPECT_EQ(cam.GetFieldOfView().AsDegrees(), 50.f);
}
TEST(UnitTestIwEngine, CameraSetAndGetOrigin)
{
auto cam = omath::iw_engine::Camera({0, 0, 0}, {}, {1920.f, 1080.f}, {}, 0.01f, 1000.f);
EXPECT_EQ(cam.GetOrigin(), omath::Vector3<float>{});
cam.SetFieldOfView(omath::projection::FieldOfView::FromDegrees(50.f));
EXPECT_EQ(cam.GetFieldOfView().AsDegrees(), 50.f);
}

View File

@@ -2,35 +2,35 @@
// Created by Orange on 11/23/2024. // Created by Orange on 11/23/2024.
// //
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include <omath/engines/OpenGL/Camera.hpp> #include <omath/engines/opengl_engine/camera.hpp>
#include <omath/engines/OpenGL/Constants.hpp> #include <omath/engines/opengl_engine/constants.hpp>
#include <omath/engines/OpenGL/Formulas.hpp> #include <omath/engines/opengl_engine/formulas.hpp>
TEST(UnitTestOpenGL, ForwardVector) TEST(UnitTestOpenGL, ForwardVector)
{ {
const auto forward = omath::opengl::ForwardVector({}); const auto forward = omath::opengl_engine::ForwardVector({});
EXPECT_EQ(forward, omath::opengl::kAbsForward); EXPECT_EQ(forward, omath::opengl_engine::kAbsForward);
} }
TEST(UnitTestOpenGL, RightVector) TEST(UnitTestOpenGL, RightVector)
{ {
const auto right = omath::opengl::RightVector({}); const auto right = omath::opengl_engine::RightVector({});
EXPECT_EQ(right, omath::opengl::kAbsRight); EXPECT_EQ(right, omath::opengl_engine::kAbsRight);
} }
TEST(UnitTestOpenGL, UpVector) TEST(UnitTestOpenGL, UpVector)
{ {
const auto up = omath::opengl::UpVector({}); const auto up = omath::opengl_engine::UpVector({});
EXPECT_EQ(up, omath::opengl::kAbsUp); EXPECT_EQ(up, omath::opengl_engine::kAbsUp);
} }
TEST(UnitTestOpenGL, ProjectTargetMovedFromCamera) TEST(UnitTestOpenGL, ProjectTargetMovedFromCamera)
{ {
constexpr auto fov = omath::projection::FieldOfView::FromDegrees(90.f); constexpr auto fov = omath::projection::FieldOfView::FromDegrees(90.f);
auto cam = omath::opengl::Camera({0, 0, 0}, {}, {1920.f, 1080.f}, fov, 0.01f, 1000.f); const auto cam = omath::opengl_engine::Camera({0, 0, 0}, {}, {1920.f, 1080.f}, fov, 0.01f, 1000.f);
for (float distance = -10.f; distance > -1000.f; distance -= 0.01f) for (float distance = -10.f; distance > -1000.f; distance -= 0.01f)
@@ -50,7 +50,7 @@ TEST(UnitTestOpenGL, ProjectTargetMovedFromCamera)
TEST(UnitTestOpenGL, CameraSetAndGetFov) TEST(UnitTestOpenGL, CameraSetAndGetFov)
{ {
constexpr auto fov = omath::projection::FieldOfView::FromDegrees(90.f); constexpr auto fov = omath::projection::FieldOfView::FromDegrees(90.f);
auto cam = omath::opengl::Camera({0, 0, 0}, {}, {1920.f, 1080.f}, fov, 0.01f, 1000.f); auto cam = omath::opengl_engine::Camera({0, 0, 0}, {}, {1920.f, 1080.f}, fov, 0.01f, 1000.f);
EXPECT_EQ(cam.GetFieldOfView().AsDegrees(), 90.f); EXPECT_EQ(cam.GetFieldOfView().AsDegrees(), 90.f);
cam.SetFieldOfView(omath::projection::FieldOfView::FromDegrees(50.f)); cam.SetFieldOfView(omath::projection::FieldOfView::FromDegrees(50.f));
@@ -60,9 +60,9 @@ TEST(UnitTestOpenGL, CameraSetAndGetFov)
TEST(UnitTestOpenGL, CameraSetAndGetOrigin) TEST(UnitTestOpenGL, CameraSetAndGetOrigin)
{ {
auto cam = omath::opengl::Camera({0, 0, 0}, {}, {1920.f, 1080.f}, {}, 0.01f, 1000.f); auto cam = omath::opengl_engine::Camera({0, 0, 0}, {}, {1920.f, 1080.f}, {}, 0.01f, 1000.f);
EXPECT_EQ(cam.GetOrigin(), omath::Vector3{}); EXPECT_EQ(cam.GetOrigin(), omath::Vector3<float>{});
cam.SetFieldOfView(omath::projection::FieldOfView::FromDegrees(50.f)); cam.SetFieldOfView(omath::projection::FieldOfView::FromDegrees(50.f));
EXPECT_EQ(cam.GetFieldOfView().AsDegrees(), 50.f); EXPECT_EQ(cam.GetFieldOfView().AsDegrees(), 50.f);

View File

@@ -0,0 +1,89 @@
//
// Created by Orange on 11/23/2024.
//
#include <gtest/gtest.h>
#include <omath/engines/source_engine/camera.hpp>
#include <omath/engines/source_engine/constants.hpp>
#include <omath/engines/source_engine/formulas.hpp>
TEST(UnitTestSourceEngine, ForwardVector)
{
const auto forward = omath::source_engine::ForwardVector({});
EXPECT_EQ(forward, omath::source_engine::kAbsForward);
}
TEST(UnitTestSourceEngine, RightVector)
{
const auto right = omath::source_engine::RightVector({});
EXPECT_EQ(right, omath::source_engine::kAbsRight);
}
TEST(UnitTestSourceEngine, UpVector)
{
const auto up = omath::source_engine::UpVector({});
EXPECT_EQ(up, omath::source_engine::kAbsUp);
}
TEST(UnitTestSourceEngine, ProjectTargetMovedFromCamera)
{
constexpr auto fov = omath::projection::FieldOfView::FromDegrees(90.f);
const auto cam = omath::source_engine::Camera({0, 0, 0}, {}, {1920.f, 1080.f}, fov, 0.01f, 1000.f);
for (float distance = 0.02f; distance < 1000.f; distance += 0.01f)
{
const auto projected = cam.WorldToScreen({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);
}
}
TEST(UnitTestSourceEngine, ProjectTargetMovedUp)
{
constexpr auto fov = omath::projection::FieldOfView::FromDegrees(90.f);
const auto cam = omath::source_engine::Camera({0, 0, 0}, {}, {1920.f, 1080.f}, fov, 0.01f, 1000.f);
auto prev = 1080.f;
for (float distance = 0.0f; distance < 10.f; distance += 1.f)
{
const auto projected = cam.WorldToScreen({100.f, 0, distance});
EXPECT_TRUE(projected.has_value());
if (!projected.has_value())
continue;
EXPECT_TRUE(projected->y < prev);
prev = projected->y;
}
}
TEST(UnitTestSourceEngine, CameraSetAndGetFov)
{
constexpr auto fov = omath::projection::FieldOfView::FromDegrees(90.f);
auto cam = omath::source_engine::Camera({0, 0, 0}, {}, {1920.f, 1080.f}, fov, 0.01f, 1000.f);
EXPECT_EQ(cam.GetFieldOfView().AsDegrees(), 90.f);
cam.SetFieldOfView(omath::projection::FieldOfView::FromDegrees(50.f));
EXPECT_EQ(cam.GetFieldOfView().AsDegrees(), 50.f);
}
TEST(UnitTestSourceEngine, CameraSetAndGetOrigin)
{
auto cam = omath::source_engine::Camera({0, 0, 0}, {}, {1920.f, 1080.f}, {}, 0.01f, 1000.f);
EXPECT_EQ(cam.GetOrigin(), omath::Vector3<float>{});
cam.SetFieldOfView(omath::projection::FieldOfView::FromDegrees(50.f));
EXPECT_EQ(cam.GetFieldOfView().AsDegrees(), 50.f);
}

View File

@@ -0,0 +1,77 @@
//
// Created by Orange on 11/27/2024.
//
#include <gtest/gtest.h>
#include <omath/engines/unity_engine/camera.hpp>
#include <omath/engines/unity_engine/constants.hpp>
#include <omath/engines/unity_engine/formulas.hpp>
TEST(UnitTestUnityEngine, ForwardVector)
{
const auto forward = omath::unity_engine::ForwardVector({});
EXPECT_EQ(forward, omath::unity_engine::kAbsForward);
}
TEST(UnitTestUnityEngine, RightVector)
{
const auto right = omath::unity_engine::RightVector({});
EXPECT_EQ(right, omath::unity_engine::kAbsRight);
}
TEST(UnitTestUnityEngine, UpVector)
{
const auto up = omath::unity_engine::UpVector({});
EXPECT_EQ(up, omath::unity_engine::kAbsUp);
}
TEST(UnitTestUnityEngine, ProjectTargetMovedFromCamera)
{
constexpr auto fov = omath::projection::FieldOfView::FromDegrees(60.f);
const auto cam = omath::unity_engine::Camera({0, 0, 0}, {}, {1280.f, 720.f}, fov, 0.01f, 1000.f);
for (float distance = 0.02f; distance < 100.f; distance += 0.01f)
{
const auto projected = cam.WorldToScreen({0, 0, distance});
EXPECT_TRUE(projected.has_value());
if (!projected.has_value())
continue;
EXPECT_NEAR(projected->x, 640, 0.00001f);
EXPECT_NEAR(projected->y, 360, 0.00001f);
}
}
TEST(UnitTestUnityEngine, Project)
{
constexpr auto fov = omath::projection::FieldOfView::FromDegrees(60.f);
const auto cam = omath::unity_engine::Camera({0, 0, 0}, {}, {1280.f, 720.f}, fov, 0.03f, 1000.f);
const auto proj = cam.WorldToScreen({5.f, 3, 10.f});
std::println("{} {}", proj->x, proj->y);
}
TEST(UnitTestUnityEngine, CameraSetAndGetFov)
{
constexpr auto fov = omath::projection::FieldOfView::FromDegrees(90.f);
auto cam = omath::unity_engine::Camera({0, 0, 0}, {}, {1920.f, 1080.f}, fov, 0.01f, 1000.f);
EXPECT_EQ(cam.GetFieldOfView().AsDegrees(), 90.f);
cam.SetFieldOfView(omath::projection::FieldOfView::FromDegrees(50.f));
EXPECT_EQ(cam.GetFieldOfView().AsDegrees(), 50.f);
}
TEST(UnitTestUnityEngine, CameraSetAndGetOrigin)
{
auto cam = omath::unity_engine::Camera({0, 0, 0}, {}, {1920.f, 1080.f}, {}, 0.01f, 1000.f);
EXPECT_EQ(cam.GetOrigin(), omath::Vector3<float>{});
cam.SetFieldOfView(omath::projection::FieldOfView::FromDegrees(50.f));
EXPECT_EQ(cam.GetFieldOfView().AsDegrees(), 50.f);
}

View File

@@ -2,7 +2,7 @@
// Created by Vlad on 18.08.2024. // Created by Vlad on 18.08.2024.
// //
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include <omath/pathfinding/Astar.hpp> #include <omath/pathfinding/a_star.hpp>
TEST(UnitTestAstar, FindingRightPath) TEST(UnitTestAstar, FindingRightPath)

View File

@@ -2,8 +2,7 @@
// Created by Orange on 11/30/2024. // Created by Orange on 11/30/2024.
// //
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include <omath/Angles.hpp> #include <omath/angles.hpp>
#include <omath/Angle.hpp>
TEST(UnitTestAngles, RadiansToDeg) TEST(UnitTestAngles, RadiansToDeg)
{ {

View File

@@ -2,7 +2,7 @@
// Created by Vlad on 01.09.2024. // Created by Vlad on 01.09.2024.
// //
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include <omath/Color.hpp> #include <omath/color.hpp>
using namespace omath; using namespace omath;

View File

@@ -1,7 +1,7 @@
#include "gtest/gtest.h" #include "gtest/gtest.h"
#include "omath/collision/LineTracer.hpp" #include "omath/collision/line_tracer.hpp"
#include "omath/Triangle.hpp" #include "omath/triangle.hpp"
#include "omath/Vector3.hpp" #include "omath/vector3.hpp"
using namespace omath; using namespace omath;
using namespace omath::collision; using namespace omath::collision;
@@ -10,10 +10,10 @@ class LineTracerTest : public ::testing::Test
{ {
protected: protected:
// Set up common variables for use in each test // Set up common variables for use in each test
Vector3 vertex1{0.0f, 0.0f, 0.0f}; Vector3<float> vertex1{0.0f, 0.0f, 0.0f};
Vector3 vertex2{1.0f, 0.0f, 0.0f}; Vector3<float> vertex2{1.0f, 0.0f, 0.0f};
Vector3 vertex3{0.0f, 1.0f, 0.0f}; Vector3<float> vertex3{0.0f, 1.0f, 0.0f};
Triangle<Vector3> triangle{vertex1, vertex2, vertex3}; Triangle<Vector3<float>> triangle{vertex1, vertex2, vertex3};
}; };
// Test that a ray intersecting the triangle returns false for CanTraceLine // Test that a ray intersecting the triangle returns false for CanTraceLine
@@ -71,7 +71,7 @@ TEST_F(LineTracerTest, TriangleFarBeyondRayEndPoint)
constexpr Ray ray{{0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 1.0f}}; constexpr Ray ray{{0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 1.0f}};
// Define a triangle far beyond the ray's endpoint // Define a triangle far beyond the ray's endpoint
constexpr Triangle<Vector3> distantTriangle{ constexpr Triangle<Vector3<float>> distantTriangle{
{1000.0f, 1000.0f, 1000.0f}, {1001.0f, 1000.0f, 1000.0f}, {1000.0f, 1001.0f, 1000.0f} {1000.0f, 1000.0f, 1000.0f}, {1001.0f, 1000.0f, 1000.0f}, {1000.0f, 1001.0f, 1000.0f}
}; };

View File

@@ -1,7 +1,7 @@
// UnitTestMat.cpp // UnitTestMat.cpp
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include "omath/Mat.hpp" #include "omath/mat.hpp"
#include "omath/Vector3.hpp" #include "omath/vector3.hpp"
using namespace omath; using namespace omath;
@@ -127,7 +127,7 @@ TEST_F(UnitTestMat, ToString)
{ {
const std::string str = m2.ToString(); const std::string str = m2.ToString();
EXPECT_FALSE(str.empty()); EXPECT_FALSE(str.empty());
EXPECT_EQ(str, "1 2\n3 4\n"); EXPECT_EQ(str, "[[ 1.000, 2.000]\n [ 3.000, 4.000]]");
} }
// Test assignment operators // Test assignment operators

View File

@@ -2,8 +2,8 @@
// Created by vlad on 5/18/2024. // Created by vlad on 5/18/2024.
// //
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include <omath/Matrix.hpp> #include <omath/matrix.hpp>
#include "omath/Vector3.hpp" #include "omath/vector3.hpp"
using namespace omath; using namespace omath;

View File

@@ -1,5 +1,5 @@
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include <omath/projectile_prediction/ProjPredEngineLegacy.hpp> #include <omath/projectile_prediction/proj_pred_engine_legacy.hpp>
TEST(UnitTestPrediction, PredictionTest) TEST(UnitTestPrediction, PredictionTest)
{ {

View File

@@ -3,15 +3,14 @@
// //
#include <complex> #include <complex>
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include <omath/Matrix.hpp> #include <omath/engines/source_engine/camera.hpp>
#include <omath/engines/Source/Camera.hpp> #include <omath/projection/camera.hpp>
#include <omath/projection/Camera.hpp>
#include <print> #include <print>
TEST(UnitTestProjection, Projection) TEST(UnitTestProjection, Projection)
{ {
const auto x = omath::Angle<float, 0.f, 180.f, omath::AngleFlags::Clamped>::FromDegrees(90.f); const auto x = omath::Angle<float, 0.f, 180.f, omath::AngleFlags::Clamped>::FromDegrees(90.f);
auto cam = omath::source::Camera({0, 0, 0}, omath::source::ViewAngles{}, {1920.f, 1080.f}, x, 0.01f, 1000.f); auto cam = omath::source_engine::Camera({0, 0, 0}, omath::source_engine::ViewAngles{}, {1920.f, 1080.f}, x, 0.01f, 1000.f);
const auto projected = cam.WorldToScreen({1000, 0, 50}); const auto projected = cam.WorldToScreen({1000, 0, 50});
std::print("{} {} {}", projected->x, projected->y, projected->z); std::print("{} {} {}", projected->x, projected->y, projected->z);

View File

@@ -1,10 +1,10 @@
// //
// Created by Orange on 1/6/2025. // Created by Orange on 1/6/2025.
// //
#include "omath/Triangle.hpp" #include <cmath> // For std::sqrt, std::isinf, std::isnan
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include <omath/Vector3.hpp> #include <omath/vector3.hpp>
#include <cmath> // For std::sqrt, std::isinf, std::isnan #include "omath/triangle.hpp"
using namespace omath; using namespace omath;
@@ -13,28 +13,28 @@ class UnitTestTriangle : public ::testing::Test
{ {
protected: protected:
// Define some Triangles to use in tests // Define some Triangles to use in tests
Triangle<Vector3> t1; Triangle<Vector3<float>> t1;
Triangle<Vector3> t2; Triangle<Vector3<float>> t2;
Triangle<Vector3> t3; Triangle<Vector3<float>> t3;
constexpr void SetUp() override constexpr void SetUp() override
{ {
// Triangle with vertices (0, 0, 0), (1, 0, 0), (0, 1, 0) // Triangle with vertices (0, 0, 0), (1, 0, 0), (0, 1, 0)
t1 = Triangle<Vector3>( t1 = Triangle<Vector3<float>>(
Vector3(0.0f, 0.0f, 0.0f), Vector3(0.0f, 0.0f, 0.0f),
Vector3(1.0f, 0.0f, 0.0f), Vector3(1.0f, 0.0f, 0.0f),
Vector3(0.0f, 1.0f, 0.0f) Vector3(0.0f, 1.0f, 0.0f)
); );
// Triangle with vertices (1, 2, 3), (4, 5, 6), (7, 8, 9) // Triangle with vertices (1, 2, 3), (4, 5, 6), (7, 8, 9)
t2 = Triangle<Vector3>( t2 = Triangle<Vector3<float>>(
Vector3(1.0f, 2.0f, 3.0f), Vector3(1.0f, 2.0f, 3.0f),
Vector3(4.0f, 5.0f, 6.0f), Vector3(4.0f, 5.0f, 6.0f),
Vector3(7.0f, 8.0f, 9.0f) Vector3(7.0f, 8.0f, 9.0f)
); );
// An isosceles right triangle // An isosceles right triangle
t3 = Triangle<Vector3>( t3 = Triangle<Vector3<float>>(
Vector3(0.0f, 0.0f, 0.0f), Vector3(0.0f, 0.0f, 0.0f),
Vector3(2.0f, 0.0f, 0.0f), Vector3(2.0f, 0.0f, 0.0f),
Vector3(0.0f, 2.0f, 0.0f) Vector3(0.0f, 2.0f, 0.0f)
@@ -45,7 +45,7 @@ protected:
// Test constructor and vertices // Test constructor and vertices
TEST_F(UnitTestTriangle, Constructor) TEST_F(UnitTestTriangle, Constructor)
{ {
constexpr Triangle<Vector3> t( constexpr Triangle<Vector3<float>> t(
Vector3(1.0f, 2.0f, 3.0f), Vector3(1.0f, 2.0f, 3.0f),
Vector3(4.0f, 5.0f, 6.0f), Vector3(4.0f, 5.0f, 6.0f),
Vector3(7.0f, 8.0f, 9.0f) Vector3(7.0f, 8.0f, 9.0f)
@@ -113,7 +113,7 @@ TEST_F(UnitTestTriangle, SideVectors)
TEST_F(UnitTestTriangle, IsRectangular) TEST_F(UnitTestTriangle, IsRectangular)
{ {
EXPECT_TRUE(Triangle<Vector3>({2,0,0}, {}, {0,2,0}).IsRectangular()); EXPECT_TRUE(Triangle<Vector3<float>>({2,0,0}, {}, {0,2,0}).IsRectangular());
} }
// Test midpoint // Test midpoint
TEST_F(UnitTestTriangle, MidPoint) TEST_F(UnitTestTriangle, MidPoint)

View File

@@ -2,18 +2,18 @@
// Created by Vlad on 02.09.2024. // Created by Vlad on 02.09.2024.
// //
#include <gtest/gtest.h>
#include <omath/Vector2.hpp>
#include <cmath> // For std::isinf and std::isnan
#include <cfloat> // For FLT_MAX and FLT_MIN #include <cfloat> // For FLT_MAX and FLT_MIN
#include <cmath> // For std::isinf and std::isnan
#include <gtest/gtest.h>
#include <omath/vector2.hpp>
using namespace omath; using namespace omath;
class UnitTestVector2 : public ::testing::Test class UnitTestVector2 : public ::testing::Test
{ {
protected: protected:
Vector2 v1; Vector2<float> v1;
Vector2 v2; Vector2<float> v2;
constexpr void SetUp() override constexpr void SetUp() override
{ {
@@ -25,7 +25,7 @@ protected:
// Test constructor and default values // Test constructor and default values
TEST_F(UnitTestVector2, Constructor_Default) TEST_F(UnitTestVector2, Constructor_Default)
{ {
constexpr Vector2 v; constexpr Vector2<float> v;
EXPECT_FLOAT_EQ(v.x, 0.0f); EXPECT_FLOAT_EQ(v.x, 0.0f);
EXPECT_FLOAT_EQ(v.y, 0.0f); EXPECT_FLOAT_EQ(v.y, 0.0f);
} }

View File

@@ -2,19 +2,19 @@
// Created by Vlad on 01.09.2024. // Created by Vlad on 01.09.2024.
// //
#include <gtest/gtest.h>
#include <omath/Vector3.hpp>
#include <cmath>
#include <cfloat> // For FLT_MAX, FLT_MIN #include <cfloat> // For FLT_MAX, FLT_MIN
#include <cmath>
#include <gtest/gtest.h>
#include <limits> // For std::numeric_limits #include <limits> // For std::numeric_limits
#include <omath/vector3.hpp>
using namespace omath; using namespace omath;
class UnitTestVector3 : public ::testing::Test class UnitTestVector3 : public ::testing::Test
{ {
protected: protected:
Vector3 v1; Vector3<float> v1;
Vector3 v2; Vector3<float> v2;
void SetUp() override void SetUp() override
{ {
@@ -26,7 +26,7 @@ protected:
// Test constructor and default values // Test constructor and default values
TEST_F(UnitTestVector3, Constructor_Default) TEST_F(UnitTestVector3, Constructor_Default)
{ {
constexpr Vector3 v; constexpr Vector3<float> v;
EXPECT_FLOAT_EQ(v.x, 0.0f); EXPECT_FLOAT_EQ(v.x, 0.0f);
EXPECT_FLOAT_EQ(v.y, 0.0f); EXPECT_FLOAT_EQ(v.y, 0.0f);
EXPECT_FLOAT_EQ(v.z, 0.0f); EXPECT_FLOAT_EQ(v.z, 0.0f);
@@ -34,7 +34,7 @@ TEST_F(UnitTestVector3, Constructor_Default)
TEST_F(UnitTestVector3, Constructor_Values) TEST_F(UnitTestVector3, Constructor_Values)
{ {
constexpr Vector3 v(1.0f, 2.0f, 3.0f); constexpr Vector3<float> v(1.0f, 2.0f, 3.0f);
EXPECT_FLOAT_EQ(v.x, 1.0f); EXPECT_FLOAT_EQ(v.x, 1.0f);
EXPECT_FLOAT_EQ(v.y, 2.0f); EXPECT_FLOAT_EQ(v.y, 2.0f);
EXPECT_FLOAT_EQ(v.z, 3.0f); EXPECT_FLOAT_EQ(v.z, 3.0f);

View File

@@ -6,16 +6,16 @@
// //
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include <omath/Vector4.hpp>
#include <limits> // For std::numeric_limits #include <limits> // For std::numeric_limits
#include <omath/vector4.hpp>
using namespace omath; using namespace omath;
class UnitTestVector4 : public ::testing::Test class UnitTestVector4 : public ::testing::Test
{ {
protected: protected:
Vector4 v1; Vector4<float> v1;
Vector4 v2; Vector4<float> v2;
void SetUp() override void SetUp() override
{ {
@@ -27,7 +27,7 @@ protected:
// Test constructor and default values // Test constructor and default values
TEST_F(UnitTestVector4, Constructor_Default) TEST_F(UnitTestVector4, Constructor_Default)
{ {
constexpr Vector4 v; constexpr Vector4<float> v;
EXPECT_FLOAT_EQ(v.x, 0.0f); EXPECT_FLOAT_EQ(v.x, 0.0f);
EXPECT_FLOAT_EQ(v.y, 0.0f); EXPECT_FLOAT_EQ(v.y, 0.0f);
EXPECT_FLOAT_EQ(v.z, 0.0f); EXPECT_FLOAT_EQ(v.z, 0.0f);

View File

@@ -1,4 +1,4 @@
// //
// Created by Orange on 11/30/2024. // Created by Orange on 11/30/2024.
// //
#include <omath/ViewAngles.hpp> #include <omath/view_angles.hpp>