diff --git a/.github/workflows/format-check.yml b/.github/workflows/format-check.yml index 5672141..81c4ba7 100644 --- a/.github/workflows/format-check.yml +++ b/.github/workflows/format-check.yml @@ -48,7 +48,7 @@ jobs: if ! git diff --name-only -z --diff-filter=AM $BASE $HEAD \ | grep -zE '\.(cpp|hpp|c|h)$' \ | grep -zEv 'External/' \ - | xargs -0 -r clang-format --dry-run --Werror; then + | xargs -0 -r clang-format-19 --dry-run --Werror; then echo "" echo "❌ Formatting issues detected" exit 1 diff --git a/Source/Core/Engine/Engine.cpp b/Source/Core/Engine/Engine.cpp index f7c0e47..6750a61 100644 --- a/Source/Core/Engine/Engine.cpp +++ b/Source/Core/Engine/Engine.cpp @@ -1,13 +1,14 @@ #include "stdafx.h" + #include "Engine.h" + +#include "Util/jsonUtil.h" #include "Window/Window.h" #include "frameData.h" -#include "Util/jsonUtil.h" - #include namespace { - constexpr std::string_view gConfigFilePath = "../engineConfig.json"; +constexpr std::string_view gConfigFilePath = "../engineConfig.json"; } RF::Engine::Engine(const RF::EngineCreationParams& params) { @@ -23,11 +24,16 @@ RF::Engine::Engine(const RF::EngineCreationParams& params) { mWindow->Init(windowParams); } -void RF::Engine::Update(const FrameData& frameData) { frameData; } +void RF::Engine::Update(const FrameData& frameData) { + frameData; +} -void RF::Engine::Render(const FrameData& frameData) { frameData; } +void RF::Engine::Render(const FrameData& frameData) { + frameData; +} -void RF::Engine::Shutdown() {} +void RF::Engine::Shutdown() { +} void RF::Engine::OnResize(const unsigned int width, const unsigned int height) { mWindow->SetSize(width, height); diff --git a/Source/Core/Engine/Engine.h b/Source/Core/Engine/Engine.h index 33aa437..0771d46 100644 --- a/Source/Core/Engine/Engine.h +++ b/Source/Core/Engine/Engine.h @@ -1,35 +1,36 @@ #pragma once + namespace RF { - struct FrameData; - struct WindowCreationParams; - class Window; +struct FrameData; +struct WindowCreationParams; +class Window; - struct EngineCreationParams { - WNDPROC windowProc = nullptr; - int cmdShow = 0; - HINSTANCE hInstance = nullptr; - }; +struct EngineCreationParams { + WNDPROC windowProc = nullptr; + int cmdShow = 0; + HINSTANCE hInstance = nullptr; +}; - class Engine { - public: - Engine() = delete; - Engine(const EngineCreationParams& params); - ~Engine() = default; - Engine(const Engine&) = delete; - void operator=(const Engine&) = delete; +class Engine { + public: + Engine() = delete; + Engine(const EngineCreationParams& params); + ~Engine() = default; + Engine(const Engine&) = delete; + void operator=(const Engine&) = delete; - void Update(const FrameData& frameData); - void Render(const FrameData& frameData); + void Update(const FrameData& frameData); + void Render(const FrameData& frameData); - void Shutdown(); + void Shutdown(); - void OnResize(const unsigned int width, const unsigned int height); + void OnResize(const unsigned int width, const unsigned int height); - private: - void LoadConfigFile(RF::WindowCreationParams& windowParams); + private: + void LoadConfigFile(RF::WindowCreationParams& windowParams); - std::unique_ptr mWindow; + std::unique_ptr mWindow; - std::wstring mAssetsPath; - }; -} \ No newline at end of file + std::wstring mAssetsPath; +}; +} // namespace RF \ No newline at end of file diff --git a/Source/Core/Engine/Window/Window.cpp b/Source/Core/Engine/Window/Window.cpp index 5e3481a..932c36c 100644 --- a/Source/Core/Engine/Window/Window.cpp +++ b/Source/Core/Engine/Window/Window.cpp @@ -1,4 +1,5 @@ #include "stdafx.h" + #include "Window.h" void RF::Window::Init(const WindowCreationParams& params) { @@ -9,7 +10,7 @@ void RF::Window::Init(const WindowCreationParams& params) { mAspectRatio = static_cast(params.width) / static_cast(params.height); // Initialize the window class - WNDCLASSEX windowClass = { 0 }; + WNDCLASSEX windowClass = {0}; windowClass.cbSize = sizeof(WNDCLASSEX); windowClass.style = CS_HREDRAW | CS_VREDRAW; windowClass.lpfnWndProc = params.windowProc; @@ -17,39 +18,32 @@ void RF::Window::Init(const WindowCreationParams& params) { windowClass.hCursor = LoadCursor(nullptr, IDC_ARROW); windowClass.lpszClassName = mWindowTitle.c_str(); windowClass.hbrBackground = reinterpret_cast((COLOR_WINDOW + 2)); - //windowClass.hIcon = icon; // TODO in the future + // windowClass.hIcon = icon; // TODO in the future RegisterClassEx(&windowClass); - RECT windowRect = { 0, 0, static_cast(mWidth), static_cast(mHeight) }; + RECT windowRect = {0, 0, static_cast(mWidth), static_cast(mHeight)}; AdjustWindowRect(&windowRect, WS_OVERLAPPEDWINDOW, FALSE); // Create the window - mHWND = CreateWindow( - windowClass.lpszClassName, - mWindowTitle.c_str(), - WS_OVERLAPPEDWINDOW, - CW_USEDEFAULT, - CW_USEDEFAULT, - windowRect.right - windowRect.left, - windowRect.bottom - windowRect.top, - nullptr, // No parent window - nullptr, // No menus (Maybe for editor in future) - params.hInstance, - params.engine); + mHWND = CreateWindow(windowClass.lpszClassName, mWindowTitle.c_str(), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, + CW_USEDEFAULT, windowRect.right - windowRect.left, windowRect.bottom - windowRect.top, + nullptr, // No parent window + nullptr, // No menus (Maybe for editor in future) + params.hInstance, params.engine); ShowWindow(mHWND, params.cmdShow); } void RF::Window::SetSize(const unsigned int width, const unsigned int height) { - mWidth = width; + mWidth = width; mHeight = height; - // TODO: Resize event + // TODO: Resize event } void RF::Window::SetTitle(const std::wstring& title) { - mWindowTitle = title; + mWindowTitle = title; ApplyWindowText(); } @@ -65,11 +59,13 @@ const std::wstring RF::Window::Title() const { } HWND RF::Window::GetHWND() const { - return mHWND; + return mHWND; } -void RF::Window::SetFullScreen(const bool isFullScreen) { isFullScreen; } +void RF::Window::SetFullScreen(const bool isFullScreen) { + isFullScreen; +} void RF::Window::ApplyWindowText() { - SetWindowText(mHWND, Title().c_str()); + SetWindowText(mHWND, Title().c_str()); } diff --git a/Source/Core/Engine/Window/Window.h b/Source/Core/Engine/Window/Window.h index b64c7e7..53472f3 100644 --- a/Source/Core/Engine/Window/Window.h +++ b/Source/Core/Engine/Window/Window.h @@ -1,45 +1,47 @@ #pragma once + namespace RF { - class Engine; - - struct WindowCreationParams { - unsigned int width = 1920; - unsigned int height = 1080; - std::wstring title = L"RuneForge"; - bool isFullScreen = false; - bool isResizable = true; - - HINSTANCE hInstance = nullptr; - int cmdShow = 0; - RF::Engine* engine = nullptr; - WNDPROC windowProc = nullptr; - }; - - class Window { - public: - Window() = default; - Window(const Window&) = delete; - void operator=(const Window&) = delete; - - void Init(const WindowCreationParams& params); - void SetSize(const unsigned int width, const unsigned int height); // TODO - Vector2ui - //const RF::V2ui Size() const; // TODO - Vector2ui - - void SetTitle(const std::wstring& title); - void SetCustomText(const std::wstring& text); - const std::wstring Title() const; - - HWND GetHWND() const; - - void SetFullScreen(const bool isFullScreen); - private: - void ApplyWindowText(); - - std::wstring mWindowTitle = {}; - std::wstring mCustomText = {}; - unsigned int mWidth = {}; - unsigned int mHeight = {}; - float mAspectRatio = {}; - HWND mHWND = {}; - }; -} +class Engine; + +struct WindowCreationParams { + unsigned int width = 1920; + unsigned int height = 1080; + std::wstring title = L"RuneForge"; + bool isFullScreen = false; + bool isResizable = true; + + HINSTANCE hInstance = nullptr; + int cmdShow = 0; + RF::Engine* engine = nullptr; + WNDPROC windowProc = nullptr; +}; + +class Window { + public: + Window() = default; + Window(const Window&) = delete; + void operator=(const Window&) = delete; + + void Init(const WindowCreationParams& params); + void SetSize(const unsigned int width, const unsigned int height); // TODO - Vector2ui + // const RF::V2ui Size() const; // TODO - Vector2ui + + void SetTitle(const std::wstring& title); + void SetCustomText(const std::wstring& text); + const std::wstring Title() const; + + HWND GetHWND() const; + + void SetFullScreen(const bool isFullScreen); + + private: + void ApplyWindowText(); + + std::wstring mWindowTitle = {}; + std::wstring mCustomText = {}; + unsigned int mWidth = {}; + unsigned int mHeight = {}; + float mAspectRatio = {}; + HWND mHWND = {}; +}; +} // namespace RF diff --git a/Source/Core/Engine/frameData.h b/Source/Core/Engine/frameData.h index f8cbdbe..2f4ea31 100644 --- a/Source/Core/Engine/frameData.h +++ b/Source/Core/Engine/frameData.h @@ -1,7 +1,8 @@ #pragma once + namespace RF { - struct FrameData { - float deltaTime = 0.0f; - float totalTime = 0.0f; - }; -} \ No newline at end of file +struct FrameData { + float deltaTime = 0.0f; + float totalTime = 0.0f; +}; +} // namespace RF \ No newline at end of file diff --git a/Source/Core/Math/Math.h b/Source/Core/Math/Math.h index c90b261..7cc7412 100644 --- a/Source/Core/Math/Math.h +++ b/Source/Core/Math/Math.h @@ -2,32 +2,55 @@ #include #ifndef PI -#define PI 3.14159265358979323846f + #define PI 3.14159265358979323846f #endif namespace math { - static inline constexpr float TWO_PI = 2.0f * PI; - static inline constexpr float HALF_PI = 0.5f * PI; - - static inline constexpr float Deg2Rad(float deg) noexcept { return deg * (PI / 180.0f); } - static inline constexpr float Rad2Deg(float rad) noexcept { return rad * (180.0f / PI); } - - template static inline constexpr T Square(const T &x) noexcept { return x * x; } - template static inline constexpr T Cube(const T &x) noexcept { return x * x * x; } - - template static inline constexpr const T &Min(const T &a, const T &b) noexcept { return (a < b) ? a : b; } - template static inline constexpr const T &Max(const T &a, const T &b) noexcept { return (a > b) ? a : b; } - template static inline constexpr const T &Clamp(const T &x, const T &lo, const T &hi) noexcept { return (x < lo) ? lo : (x > hi ? hi : x); } - - static inline float WrapDeg(float d) noexcept { - float result = std::fmod(d, 360.0f); - return (result < 0.0f) ? result + 360.0f : result; - } - - static inline float WrapRad(float r) noexcept { - float result = std::fmod(r, TWO_PI); - return (result < 0.0f) ? result + TWO_PI : result; - } - -} \ No newline at end of file +static inline constexpr float TWO_PI = 2.0f * PI; +static inline constexpr float HALF_PI = 0.5f * PI; + +static inline constexpr float Deg2Rad(float deg) noexcept { + return deg * (PI / 180.0f); +} + +static inline constexpr float Rad2Deg(float rad) noexcept { + return rad * (180.0f / PI); +} + +template +static inline constexpr T Square(const T& x) noexcept { + return x * x; +} + +template +static inline constexpr T Cube(const T& x) noexcept { + return x * x * x; +} + +template +static inline constexpr const T& Min(const T& a, const T& b) noexcept { + return (a < b) ? a : b; +} + +template +static inline constexpr const T& Max(const T& a, const T& b) noexcept { + return (a > b) ? a : b; +} + +template +static inline constexpr const T& Clamp(const T& x, const T& lo, const T& hi) noexcept { + return (x < lo) ? lo : (x > hi ? hi : x); +} + +static inline float WrapDeg(float d) noexcept { + float result = std::fmod(d, 360.0f); + return (result < 0.0f) ? result + 360.0f : result; +} + +static inline float WrapRad(float r) noexcept { + float result = std::fmod(r, TWO_PI); + return (result < 0.0f) ? result + TWO_PI : result; +} + +} // namespace math \ No newline at end of file diff --git a/Source/Core/Math/Matrix3x3.h b/Source/Core/Math/Matrix3x3.h index 90d2402..856e580 100644 --- a/Source/Core/Math/Matrix3x3.h +++ b/Source/Core/Math/Matrix3x3.h @@ -5,17 +5,27 @@ /// Matrix3x3 wrapper class for DirectXMath's XMMATRIX. /// class Matrix3x3 { -public: - Matrix3x3() : mMatrix(DirectX::XMMatrixIdentity()) {} - Matrix3x3(const Matrix3x3& other) : mMatrix(other) {} - Matrix3x3(Matrix3x3& other) : mMatrix(other) {} - Matrix3x3(const DirectX::XMMATRIX& other) : mMatrix(other) {} - Matrix3x3(DirectX::XMMATRIX& other) : mMatrix(other) {} - Matrix3x3(const float* floatArray) : mMatrix(floatArray) {} - Matrix3x3( - const float r0c0, const float r0c1, const float r0c2, - const float r1c0, const float r1c1, const float r1c2, - const float r2c0, const float r2c1, const float r2c2); + public: + Matrix3x3() : mMatrix(DirectX::XMMatrixIdentity()) { + } + + Matrix3x3(const Matrix3x3& other) : mMatrix(other) { + } + + Matrix3x3(Matrix3x3& other) : mMatrix(other) { + } + + Matrix3x3(const DirectX::XMMATRIX& other) : mMatrix(other) { + } + + Matrix3x3(DirectX::XMMATRIX& other) : mMatrix(other) { + } + + Matrix3x3(const float* floatArray) : mMatrix(floatArray) { + } + + Matrix3x3(const float r0c0, const float r0c1, const float r0c2, const float r1c0, const float r1c1, + const float r1c2, const float r2c0, const float r2c1, const float r2c2); float& operator()(const unsigned int row, const unsigned int column) noexcept; Matrix3x3& operator=(const Matrix3x3& other) noexcept; @@ -30,7 +40,10 @@ class Matrix3x3 { Matrix3x3& operator*=(const float scalar) noexcept; Matrix3x3 operator/(const float scalar) const noexcept; Matrix3x3& operator/=(const float scalar) noexcept; - operator DirectX::XMMATRIX() const noexcept { return mMatrix; } + + operator DirectX::XMMATRIX() const noexcept { + return mMatrix; + } Matrix3x3 Transpose() const; Matrix3x3 Inverse() const; // Todo, add parameter for determinant when Vector3 is implemented @@ -39,22 +52,17 @@ class Matrix3x3 { static inline Matrix3x3 CreateRotationAroundZ(const float angle); // Todo, implement these methods when Vector3 is implemented - //Matrix3x3 CreateTranslationMatrix(const Vector3& scaleVector); - //Matrix3x3 CreateScaleMatrix(const Vector3& scaleVector); - //Matrix3x3 CreateRotationMatrix(const Vector3& scaleVector); + // Matrix3x3 CreateTranslationMatrix(const Vector3& scaleVector); + // Matrix3x3 CreateScaleMatrix(const Vector3& scaleVector); + // Matrix3x3 CreateRotationMatrix(const Vector3& scaleVector); DirectX::XMMATRIX mMatrix = {}; }; -inline Matrix3x3::Matrix3x3( - const float r0c0, const float r0c1, const float r0c2, - const float r1c0, const float r1c1, const float r1c2, - const float r2c0, const float r2c1, const float r2c2) : - mMatrix({ - r0c0, r0c1, r0c2, 0.0f, - r1c0, r1c1, r1c2, 0.0f, - r2c0, r2c1, r2c2, 0.0f, - 0.0f, 0.0f, 0.0f, 1.0f }) { } +inline Matrix3x3::Matrix3x3(const float r0c0, const float r0c1, const float r0c2, const float r1c0, const float r1c1, + const float r1c2, const float r2c0, const float r2c1, const float r2c2) + : mMatrix({r0c0, r0c1, r0c2, 0.0f, r1c0, r1c1, r1c2, 0.0f, r2c0, r2c1, r2c2, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}) { +} float& Matrix3x3::operator()(const unsigned int row, const unsigned int column) noexcept { assert(row < 3 && column < 3 && "Matrix3x3: Index out of bounds"); @@ -63,7 +71,7 @@ float& Matrix3x3::operator()(const unsigned int row, const unsigned int column) } Matrix3x3& Matrix3x3::operator=(const Matrix3x3& other) noexcept { - if(this != &other) { + if (this != &other) { mMatrix = other.mMatrix; } diff --git a/Source/Core/Math/Vector2.h b/Source/Core/Math/Vector2.h index 74272a5..2ed6bf3 100644 --- a/Source/Core/Math/Vector2.h +++ b/Source/Core/Math/Vector2.h @@ -5,128 +5,153 @@ constexpr float vecEpsilon = 1e-6f; class Vector2 { -public: - float x = 0.0f; - float y = 0.0f; - - static const Vector2 Zero; - static const Vector2 UnitX; - static const Vector2 UnitY; - static const Vector2 UnitScale; - - // Constructors // - - constexpr Vector2() noexcept : x(0), y(0) {} - constexpr Vector2(float X, float Y) noexcept : x(X), y(Y) {} - explicit constexpr Vector2(const float(&arr)[2]) noexcept : x(arr[0]), y(arr[1]) {} - Vector2(const DirectX::XMFLOAT2 &xmf2) noexcept : x(xmf2.x), y(xmf2.y) {} - Vector2(DirectX::FXMVECTOR fxm) noexcept { *this = fxm; } - - // DirectX Conversions // - - operator DirectX::XMFLOAT2() const noexcept { - return DirectX::XMFLOAT2(x, y); - } - Vector2 &operator=(const DirectX::XMFLOAT2 &xmf2) noexcept { - x = xmf2.x; - y = xmf2.y; - return *this; - } - Vector2 &operator=(DirectX::FXMVECTOR fxm) noexcept { - DirectX::XMFLOAT2 temp; - DirectX::XMStoreFloat2(&temp, fxm); - x = temp.x; - y = temp.y; - return *this; - } - - // Explicit conversion(1 for position, 0 for direction) - [[nodiscard]] DirectX::XMVECTOR ToXMVECTOR(float w) const noexcept { - return DirectX::XMVectorSet(x, y, 0.0f, w); - } - - // Compound Assignment Operators (modifying *this) // - - Vector2 &operator+=(const Vector2 &rhs) noexcept { - x += rhs.x; - y += rhs.y; - return *this; - } - Vector2 &operator-=(const Vector2 &rhs) noexcept { - x -= rhs.x; - y -= rhs.y; - return *this; - } - Vector2 &operator*=(float s) noexcept { - x *= s; - y *= s; - return *this; - } - Vector2 &operator/=(float s) noexcept { - assert(s != 0.0f && "Division by zero in Vector2::operator/="); - x /= s; - y /= s; - return *this; - } - - // Arithmetic Operators (returning a copy) // - - friend Vector2 operator+(Vector2 a, const Vector2 &b) noexcept { - a += b; - return a; - } - friend Vector2 operator-(Vector2 a, const Vector2 &b) noexcept { - a -= b; - return a; - } - friend Vector2 operator/(Vector2 a, float s) noexcept { - assert(s != 0.0f && "Division by zero in Vector2::operator/"); - a /= s; - return a; - } - friend Vector2 operator*(Vector2 a, float s) noexcept { - a *= s; - return a; - } - friend Vector2 operator*(float s, Vector2 a) noexcept { - a *= s; - return a; - } - - // Comparison operators // - - bool operator==(const Vector2 &rhs) const noexcept { - return fabs(x - rhs.x) < vecEpsilon && fabs(y - rhs.y) < vecEpsilon; - } - bool operator!=(const Vector2 &rhs) const noexcept { - return !(*this == rhs); - } - - // Helper functions // - - constexpr float LengthSquared() const noexcept { - return x * x + y * y; - } - float Length() const noexcept { - return sqrtf(LengthSquared()); - } - float Dot(const Vector2 &other) const noexcept { - return x * other.x + y * other.y; - } - [[nodiscard]] Vector2 Normalized() const noexcept { - float lsq = LengthSquared(); - if (lsq <= 1e-8f) { return Vector2::Zero; } - return (*this) * (1.0f / sqrtf(lsq)); - } - [[nodiscard]] Vector2 Reflect(const Vector2 &normal) const noexcept { - assert(fabs(normal.LengthSquared() - 1.0f) < 1e-3f && "Vector3::Reflect received non-normalized normal"); - - float dot = this->Dot(normal); - float factor = 2.0f * dot; - - return *this - factor * normal; - } - + public: + float x = 0.0f; + float y = 0.0f; + + static const Vector2 Zero; + static const Vector2 UnitX; + static const Vector2 UnitY; + static const Vector2 UnitScale; + + // Constructors // + + constexpr Vector2() noexcept : x(0), y(0) { + } + + constexpr Vector2(float X, float Y) noexcept : x(X), y(Y) { + } + + explicit constexpr Vector2(const float (&arr)[2]) noexcept : x(arr[0]), y(arr[1]) { + } + + Vector2(const DirectX::XMFLOAT2& xmf2) noexcept : x(xmf2.x), y(xmf2.y) { + } + + Vector2(DirectX::FXMVECTOR fxm) noexcept { + *this = fxm; + } + + // DirectX Conversions // + + operator DirectX::XMFLOAT2() const noexcept { + return DirectX::XMFLOAT2(x, y); + } + + Vector2& operator=(const DirectX::XMFLOAT2& xmf2) noexcept { + x = xmf2.x; + y = xmf2.y; + return *this; + } + + Vector2& operator=(DirectX::FXMVECTOR fxm) noexcept { + DirectX::XMFLOAT2 temp; + DirectX::XMStoreFloat2(&temp, fxm); + x = temp.x; + y = temp.y; + return *this; + } + + // Explicit conversion(1 for position, 0 for direction) + [[nodiscard]] DirectX::XMVECTOR ToXMVECTOR(float w) const noexcept { + return DirectX::XMVectorSet(x, y, 0.0f, w); + } + + // Compound Assignment Operators (modifying *this) // + + Vector2& operator+=(const Vector2& rhs) noexcept { + x += rhs.x; + y += rhs.y; + return *this; + } + + Vector2& operator-=(const Vector2& rhs) noexcept { + x -= rhs.x; + y -= rhs.y; + return *this; + } + + Vector2& operator*=(float s) noexcept { + x *= s; + y *= s; + return *this; + } + + Vector2& operator/=(float s) noexcept { + assert(s != 0.0f && "Division by zero in Vector2::operator/="); + x /= s; + y /= s; + return *this; + } + + // Arithmetic Operators (returning a copy) // + + friend Vector2 operator+(Vector2 a, const Vector2& b) noexcept { + a += b; + return a; + } + + friend Vector2 operator-(Vector2 a, const Vector2& b) noexcept { + a -= b; + return a; + } + + friend Vector2 operator/(Vector2 a, float s) noexcept { + assert(s != 0.0f && "Division by zero in Vector2::operator/"); + a /= s; + return a; + } + + friend Vector2 operator*(Vector2 a, float s) noexcept { + a *= s; + return a; + } + + friend Vector2 operator*(float s, Vector2 a) noexcept { + a *= s; + return a; + } + + // Comparison operators // + + bool operator==(const Vector2& rhs) const noexcept { + return fabs(x - rhs.x) < vecEpsilon && fabs(y - rhs.y) < vecEpsilon; + } + + bool operator!=(const Vector2& rhs) const noexcept { + return !(*this == rhs); + } + + // Helper functions // + + constexpr float LengthSquared() const noexcept { + return x * x + y * y; + } + + float Length() const noexcept { + return sqrtf(LengthSquared()); + } + + float Dot(const Vector2& other) const noexcept { + return x * other.x + y * other.y; + } + + [[nodiscard]] Vector2 Normalized() const noexcept { + float lsq = LengthSquared(); + if (lsq <= 1e-8f) { + return Vector2::Zero; + } + return (*this) * (1.0f / sqrtf(lsq)); + } + + [[nodiscard]] Vector2 Reflect(const Vector2& normal) const noexcept { + assert(fabs(normal.LengthSquared() - 1.0f) < 1e-3f && "Vector3::Reflect received non-normalized normal"); + + float dot = this->Dot(normal); + float factor = 2.0f * dot; + + return *this - factor * normal; + } }; inline const Vector2 Vector2::Zero(0, 0); @@ -134,113 +159,133 @@ inline const Vector2 Vector2::UnitX(1, 0); inline const Vector2 Vector2::UnitY(0, 1); inline const Vector2 Vector2::UnitScale(1, 1); - class Vector2i { -public: - int x = 0; - int y = 0; - - static const Vector2i Zero; - static const Vector2i UnitX; - static const Vector2i UnitY; - static const Vector2i UnitScale; - - // Constructors // - - constexpr Vector2i() noexcept : x(0), y(0) {} - constexpr Vector2i(int X, int Y) noexcept : x(X), y(Y) {} - explicit constexpr Vector2i(const int(&arr)[2]) noexcept : x(arr[0]), y(arr[1]) {} - Vector2i(const DirectX::XMINT2 &xi) noexcept : x(xi.x), y(xi.y) {} - - // DirectX Conversions // - - operator DirectX::XMINT2() const noexcept { - return DirectX::XMINT2(x, y); - } - operator DirectX::XMFLOAT2() const noexcept { - return DirectX::XMFLOAT2(static_cast(x), static_cast(y)); - } - Vector2i &operator=(const DirectX::XMINT2 &xi) noexcept { - x = xi.x; - y = xi.y; - return *this; - } - Vector2i &operator=(DirectX::FXMVECTOR fxm) noexcept { - DirectX::XMFLOAT2 temp; - DirectX::XMStoreFloat2(&temp, fxm); - x = static_cast(temp.x); - y = static_cast(temp.y); - return *this; - } - - // Explicit conversion(1 for position, 0 for direction) - [[nodiscard]] DirectX::XMVECTOR ToXMVECTOR(float w) const noexcept { - return DirectX::XMVectorSet(static_cast(x), static_cast(y), 0.0f, w); - } - - // Compound Assignment Operators (modifying *this) // - - Vector2i &operator+=(const Vector2i &rhs) noexcept { - x += rhs.x; - y += rhs.y; - return *this; - } - Vector2i &operator-=(const Vector2i &rhs) noexcept { - x -= rhs.x; - y -= rhs.y; - return *this; - } - Vector2i &operator*=(int s) noexcept { - x *= s; - y *= s; - return *this; - } - Vector2i &operator/=(int s) noexcept { - assert(s != 0 && "Division by zero in Vector2i::operator/="); - x /= s; - y /= s; - return *this; - } - - // Arithmetic Operators (returning a copy) // - - friend Vector2i operator+(Vector2i a, const Vector2i &b) noexcept { - a += b; - return a; - } - friend Vector2i operator-(Vector2i a, const Vector2i &b) noexcept { - a -= b; - return a; - } - friend Vector2i operator*(Vector2i a, int s) noexcept { - a *= s; - return a; - } - friend Vector2i operator*(int s, Vector2i a) noexcept { - a *= s; - return a; - } - friend Vector2i operator/(Vector2i a, int s) noexcept { - assert(s != 0 && "Division by zero in Vector2i::operator/"); - a /= s; - return a; - } - - // Comparison operators // - - bool operator==(const Vector2i &other) const noexcept { - return x == other.x && y == other.y; - } - bool operator!=(const Vector2i &other) const noexcept { - return !(*this == other); - } - - // Helper Functions // - - constexpr int LengthSquared() const noexcept { - return x * x + y * y; - } - int Dot(const Vector2i &other) const noexcept { return x * other.x + y * other.y; } + public: + int x = 0; + int y = 0; + + static const Vector2i Zero; + static const Vector2i UnitX; + static const Vector2i UnitY; + static const Vector2i UnitScale; + + // Constructors // + + constexpr Vector2i() noexcept : x(0), y(0) { + } + + constexpr Vector2i(int X, int Y) noexcept : x(X), y(Y) { + } + + explicit constexpr Vector2i(const int (&arr)[2]) noexcept : x(arr[0]), y(arr[1]) { + } + + Vector2i(const DirectX::XMINT2& xi) noexcept : x(xi.x), y(xi.y) { + } + + // DirectX Conversions // + + operator DirectX::XMINT2() const noexcept { + return DirectX::XMINT2(x, y); + } + + operator DirectX::XMFLOAT2() const noexcept { + return DirectX::XMFLOAT2(static_cast(x), static_cast(y)); + } + + Vector2i& operator=(const DirectX::XMINT2& xi) noexcept { + x = xi.x; + y = xi.y; + return *this; + } + + Vector2i& operator=(DirectX::FXMVECTOR fxm) noexcept { + DirectX::XMFLOAT2 temp; + DirectX::XMStoreFloat2(&temp, fxm); + x = static_cast(temp.x); + y = static_cast(temp.y); + return *this; + } + + // Explicit conversion(1 for position, 0 for direction) + [[nodiscard]] DirectX::XMVECTOR ToXMVECTOR(float w) const noexcept { + return DirectX::XMVectorSet(static_cast(x), static_cast(y), 0.0f, w); + } + + // Compound Assignment Operators (modifying *this) // + + Vector2i& operator+=(const Vector2i& rhs) noexcept { + x += rhs.x; + y += rhs.y; + return *this; + } + + Vector2i& operator-=(const Vector2i& rhs) noexcept { + x -= rhs.x; + y -= rhs.y; + return *this; + } + + Vector2i& operator*=(int s) noexcept { + x *= s; + y *= s; + return *this; + } + + Vector2i& operator/=(int s) noexcept { + assert(s != 0 && "Division by zero in Vector2i::operator/="); + x /= s; + y /= s; + return *this; + } + + // Arithmetic Operators (returning a copy) // + + friend Vector2i operator+(Vector2i a, const Vector2i& b) noexcept { + a += b; + return a; + } + + friend Vector2i operator-(Vector2i a, const Vector2i& b) noexcept { + a -= b; + return a; + } + + friend Vector2i operator*(Vector2i a, int s) noexcept { + a *= s; + return a; + } + + friend Vector2i operator*(int s, Vector2i a) noexcept { + a *= s; + return a; + } + + friend Vector2i operator/(Vector2i a, int s) noexcept { + assert(s != 0 && "Division by zero in Vector2i::operator/"); + a /= s; + return a; + } + + // Comparison operators // + + bool operator==(const Vector2i& other) const noexcept { + return x == other.x && y == other.y; + } + + bool operator!=(const Vector2i& other) const noexcept { + return !(*this == other); + } + + // Helper Functions // + + constexpr int LengthSquared() const noexcept { + return x * x + y * y; + } + + int Dot(const Vector2i& other) const noexcept { + return x * other.x + y * other.y; + } }; inline const Vector2i Vector2i::Zero(0, 0); diff --git a/Source/Core/Math/Vector3.h b/Source/Core/Math/Vector3.h index 1c22654..f9725f7 100644 --- a/Source/Core/Math/Vector3.h +++ b/Source/Core/Math/Vector3.h @@ -1,162 +1,196 @@ #pragma once +#include "Vector2.h" #include #include -#include "Vector2.h" class Vector3 { -public: - float x = 0.0f; - float y = 0.0f; - float z = 0.0f; - - static const Vector3 Zero; - static const Vector3 UnitX; - static const Vector3 UnitY; - static const Vector3 UnitZ; - static const Vector3 UnitScale; - - // Constructors // - - constexpr Vector3() noexcept : x(0), y(0), z(0) {} - constexpr Vector3(float X, float Y, float Z) noexcept : x(X), y(Y), z(Z) {} - constexpr Vector3(const DirectX::XMFLOAT3 &xmf3) noexcept : x(xmf3.x), y(xmf3.y), z(xmf3.z) {} - explicit constexpr Vector3(const float(&arr)[3]) noexcept : x(arr[0]), y(arr[1]), z(arr[2]) {} - - // DirectX Conversions // - - operator DirectX::XMFLOAT3() const noexcept { - return DirectX::XMFLOAT3(x, y, z); - } - Vector3 &operator=(const DirectX::XMFLOAT3 &xmf3) noexcept { - x = xmf3.x; y = xmf3.y; z = xmf3.z; - return *this; - } - Vector3 &operator=(DirectX::FXMVECTOR fxm) noexcept { - DirectX::XMFLOAT3 temp; - DirectX::XMStoreFloat3(&temp, fxm); - x = temp.x; y = temp.y; z = temp.z; - return *this; - } - - // Explicit conversion(1 for position, 0 for direction) - [[nodiscard]] DirectX::XMVECTOR ToXMVECTOR(float w) const noexcept { - return DirectX::XMVectorSet(x, y, z, w); - } - - // Compound Assignment Operators (modifying *this) // - - Vector3 &operator+=(const Vector3 &rhs) noexcept { - x += rhs.x; y += rhs.y; z += rhs.z; - return *this; - } - Vector3 &operator-=(const Vector3 &rhs) noexcept { - x -= rhs.x; y -= rhs.y; z -= rhs.z; - return *this; - } - Vector3 &operator*=(float s) noexcept { - x *= s; y *= s; z *= s; - return *this; - } - Vector3 &operator/=(float s) noexcept { - assert(s != 0.0f && "Division by zero in Vector3::operator/="); - x /= s; y /= s; z /= s; - return *this; - } - - // Arithmetic Operators (returning a copy) // - - friend Vector3 operator+(Vector3 a, const Vector3 &b) noexcept { - a += b; - return a; - } - friend Vector3 operator-(Vector3 a, const Vector3 &b) noexcept { - a -= b; - return a; - } - friend Vector3 operator/(Vector3 a, float s) noexcept { - assert(s != 0.0f && "Division by zero in Vector3::operator/"); - a /= s; - return a; - } - friend Vector3 operator*(Vector3 a, float s) noexcept { - a *= s; - return a; - } - friend Vector3 operator*(float s, Vector3 a) noexcept { - a *= s; - return a; - } - - // Comparison operators // - - bool operator==(const Vector3 &rhs) const noexcept { - return - fabs(x - rhs.x) < vecEpsilon && - fabs(y - rhs.y) < vecEpsilon && - fabs(z - rhs.z) < vecEpsilon; - } - bool operator!=(const Vector3 &rhs) const noexcept { - return !(*this == rhs); - } - - - // Helper Functions // - - constexpr float LengthSquared() const noexcept { - return x * x + y * y + z * z; - } - float Length() const noexcept { - return sqrt(LengthSquared()); - } - float Dot(const Vector3 &other) const noexcept { - return (x * other.x) + (y * other.y) + (z * other.z); - } - [[nodiscard]] Vector3 Normalized() const noexcept { - float lsq = LengthSquared(); - if (lsq <= 1e-8f) { return Vector3::Zero; } - return (*this) * (1.0f / sqrt(lsq)); - } - [[nodiscard]] Vector3 Cross(const Vector3 &other) const noexcept { - return Vector3( - (y * other.z) - (z * other.y), - (z * other.x) - (x * other.z), - (x * other.y) - (y * other.x) - ); - } - [[nodiscard]] Vector3 Reflect(const Vector3 &normal) const noexcept { - assert(fabs(normal.LengthSquared() - 1.0f) < 1e-3f && "Vector3::Reflect received non-normalized normal"); - - float dot = this->Dot(normal); - float factor = 2.0f * dot; - - return *this - factor * normal; - } - [[nodiscard]] Vector3 RotateYaw(float yaw) const noexcept { - float cosy = cosf(yaw); - float siny = sinf(yaw); - float xNew = x * cosy + z * siny; - float zNew = -x * siny + z * cosy; - return Vector3(xNew, y, zNew); - } - [[nodiscard]] Vector3 RotatePitch(float pitch) const noexcept { - float cosp = cosf(pitch); - float sinp = sinf(pitch); - float yNew = y * cosp - z * sinp; - float zNew = y * sinp + z * cosp; - return Vector3(x, yNew, zNew); - } - [[nodiscard]] Vector3 RotatePitchYaw(float yaw, float pitch) const noexcept { - return this->RotatePitch(pitch).RotateYaw(yaw); - } - [[nodiscard]] Vector2 xy() const noexcept { - return Vector2(x, y); - } - [[nodiscard]] Vector2 xz() const noexcept { - return Vector2(x, z); - } - [[nodiscard]] Vector2 yz() const noexcept { - return Vector2(y, z); - } + public: + float x = 0.0f; + float y = 0.0f; + float z = 0.0f; + + static const Vector3 Zero; + static const Vector3 UnitX; + static const Vector3 UnitY; + static const Vector3 UnitZ; + static const Vector3 UnitScale; + + // Constructors // + + constexpr Vector3() noexcept : x(0), y(0), z(0) { + } + + constexpr Vector3(float X, float Y, float Z) noexcept : x(X), y(Y), z(Z) { + } + + constexpr Vector3(const DirectX::XMFLOAT3& xmf3) noexcept : x(xmf3.x), y(xmf3.y), z(xmf3.z) { + } + + explicit constexpr Vector3(const float (&arr)[3]) noexcept : x(arr[0]), y(arr[1]), z(arr[2]) { + } + + // DirectX Conversions // + + operator DirectX::XMFLOAT3() const noexcept { + return DirectX::XMFLOAT3(x, y, z); + } + + Vector3& operator=(const DirectX::XMFLOAT3& xmf3) noexcept { + x = xmf3.x; + y = xmf3.y; + z = xmf3.z; + return *this; + } + + Vector3& operator=(DirectX::FXMVECTOR fxm) noexcept { + DirectX::XMFLOAT3 temp; + DirectX::XMStoreFloat3(&temp, fxm); + x = temp.x; + y = temp.y; + z = temp.z; + return *this; + } + + // Explicit conversion(1 for position, 0 for direction) + [[nodiscard]] DirectX::XMVECTOR ToXMVECTOR(float w) const noexcept { + return DirectX::XMVectorSet(x, y, z, w); + } + + // Compound Assignment Operators (modifying *this) // + + Vector3& operator+=(const Vector3& rhs) noexcept { + x += rhs.x; + y += rhs.y; + z += rhs.z; + return *this; + } + + Vector3& operator-=(const Vector3& rhs) noexcept { + x -= rhs.x; + y -= rhs.y; + z -= rhs.z; + return *this; + } + + Vector3& operator*=(float s) noexcept { + x *= s; + y *= s; + z *= s; + return *this; + } + + Vector3& operator/=(float s) noexcept { + assert(s != 0.0f && "Division by zero in Vector3::operator/="); + x /= s; + y /= s; + z /= s; + return *this; + } + + // Arithmetic Operators (returning a copy) // + + friend Vector3 operator+(Vector3 a, const Vector3& b) noexcept { + a += b; + return a; + } + + friend Vector3 operator-(Vector3 a, const Vector3& b) noexcept { + a -= b; + return a; + } + + friend Vector3 operator/(Vector3 a, float s) noexcept { + assert(s != 0.0f && "Division by zero in Vector3::operator/"); + a /= s; + return a; + } + + friend Vector3 operator*(Vector3 a, float s) noexcept { + a *= s; + return a; + } + + friend Vector3 operator*(float s, Vector3 a) noexcept { + a *= s; + return a; + } + + // Comparison operators // + + bool operator==(const Vector3& rhs) const noexcept { + return fabs(x - rhs.x) < vecEpsilon && fabs(y - rhs.y) < vecEpsilon && fabs(z - rhs.z) < vecEpsilon; + } + + bool operator!=(const Vector3& rhs) const noexcept { + return !(*this == rhs); + } + + // Helper Functions // + + constexpr float LengthSquared() const noexcept { + return x * x + y * y + z * z; + } + + float Length() const noexcept { + return sqrt(LengthSquared()); + } + + float Dot(const Vector3& other) const noexcept { + return (x * other.x) + (y * other.y) + (z * other.z); + } + + [[nodiscard]] Vector3 Normalized() const noexcept { + float lsq = LengthSquared(); + if (lsq <= 1e-8f) { + return Vector3::Zero; + } + return (*this) * (1.0f / sqrt(lsq)); + } + + [[nodiscard]] Vector3 Cross(const Vector3& other) const noexcept { + return Vector3((y * other.z) - (z * other.y), (z * other.x) - (x * other.z), (x * other.y) - (y * other.x)); + } + + [[nodiscard]] Vector3 Reflect(const Vector3& normal) const noexcept { + assert(fabs(normal.LengthSquared() - 1.0f) < 1e-3f && "Vector3::Reflect received non-normalized normal"); + + float dot = this->Dot(normal); + float factor = 2.0f * dot; + + return *this - factor * normal; + } + + [[nodiscard]] Vector3 RotateYaw(float yaw) const noexcept { + float cosy = cosf(yaw); + float siny = sinf(yaw); + float xNew = x * cosy + z * siny; + float zNew = -x * siny + z * cosy; + return Vector3(xNew, y, zNew); + } + + [[nodiscard]] Vector3 RotatePitch(float pitch) const noexcept { + float cosp = cosf(pitch); + float sinp = sinf(pitch); + float yNew = y * cosp - z * sinp; + float zNew = y * sinp + z * cosp; + return Vector3(x, yNew, zNew); + } + + [[nodiscard]] Vector3 RotatePitchYaw(float yaw, float pitch) const noexcept { + return this->RotatePitch(pitch).RotateYaw(yaw); + } + + [[nodiscard]] Vector2 xy() const noexcept { + return Vector2(x, y); + } + + [[nodiscard]] Vector2 xz() const noexcept { + return Vector2(x, z); + } + + [[nodiscard]] Vector2 yz() const noexcept { + return Vector2(y, z); + } }; inline const Vector3 Vector3::Zero(0, 0, 0); @@ -165,157 +199,204 @@ inline const Vector3 Vector3::UnitY(0, 1, 0); inline const Vector3 Vector3::UnitZ(0, 0, 1); inline const Vector3 Vector3::UnitScale(1, 1, 1); - class Vector3i { -public: - int x = 0; - int y = 0; - int z = 0; - - static const Vector3i Zero; - static const Vector3i UnitX; - static const Vector3i UnitY; - static const Vector3i UnitZ; - static const Vector3i UnitScale; - - // Constructors // - - constexpr Vector3i() noexcept : x(0), y(0), z(0) {} - constexpr Vector3i(int X, int Y, int Z) noexcept : x(X), y(Y), z(Z) {} - explicit constexpr Vector3i(const int(&arr)[3]) noexcept : x(arr[0]), y(arr[1]), z(arr[2]) {} - Vector3i(const DirectX::XMINT3 &xi) noexcept : x(xi.x), y(xi.y), z(xi.z) {} - - // DirectX Conversions // - - operator DirectX::XMINT3() const noexcept { - return DirectX::XMINT3(x, y, z); - } - operator DirectX::XMFLOAT3() const noexcept { - return DirectX::XMFLOAT3(static_cast(x), static_cast(y), static_cast(z)); - } - Vector3i &operator=(const DirectX::XMINT3 &xi) noexcept { - x = xi.x; y = xi.y; z = xi.z; - return *this; - } - Vector3i &operator=(DirectX::FXMVECTOR fxm) noexcept { - DirectX::XMFLOAT3 temp; - DirectX::XMStoreFloat3(&temp, fxm); - x = static_cast(temp.x); - y = static_cast(temp.y); - z = static_cast(temp.z); - return *this; - } - - // Explicit conversion(1 for position, 0 for direction) - [[nodiscard]] DirectX::XMVECTOR ToXMVECTOR(float w) const noexcept { - return DirectX::XMVectorSet(static_cast(x), static_cast(y), static_cast(z), w); - } - - // Compound Assignment Operators (modifying *this) // - - Vector3i &operator+=(const Vector3i &rhs) noexcept { - x += rhs.x; y += rhs.y; z += rhs.z; return *this; - } - Vector3i &operator-=(const Vector3i &rhs) noexcept { - x -= rhs.x; y -= rhs.y; z -= rhs.z; return *this; - } - Vector3i &operator*=(int s) noexcept { - x *= s; y *= s; z *= s; return *this; - } - Vector3i &operator/=(int s) noexcept { - assert(s != 0 && "Division by zero in Vector3i::operator/="); - x /= s; - y /= s; - z /= s; - return *this; - } - - // Arithmetic Operators (returning a copy) // - - friend Vector3i operator+(Vector3i a, const Vector3i &b) noexcept { - a += b; return a; - } - friend Vector3i operator-(Vector3i a, const Vector3i &b) noexcept { - a -= b; return a; - } - friend Vector3i operator*(Vector3i a, int s) noexcept { - a *= s; return a; - } - friend Vector3i operator*(int s, Vector3i a) noexcept { - a *= s; return a; - } - friend Vector3i operator/(Vector3i a, int s) noexcept { - assert(s != 0 && "Division by zero in Vector3i::operator/"); - a /= s; return a; - } - - // Comparison operators // - - bool operator==(const Vector3i &rhs) const noexcept { - constexpr float eps = vecEpsilon; - return - abs(x - rhs.x) < eps && - abs(y - rhs.y) < eps && - abs(z - rhs.z) < eps; - } - bool operator!=(const Vector3i &rhs) const noexcept { - return !(*this == rhs); - } - - // Helper functions // - - constexpr int LengthSquared() const noexcept { - return x * x + y * y + z * z; - } - constexpr int Dot(const Vector3i &other) const noexcept { - return x * other.x + y * other.y + z * other.z; - } - - [[nodiscard]] Vector2i xy() const noexcept { - return Vector2i(x, y); - } - [[nodiscard]] Vector2i xz() const noexcept { - return Vector2i(x, z); - } - [[nodiscard]] Vector2i yz() const noexcept { - return Vector2i(y, z); - } - - enum class RotateAxis { X, Y, Z, }; - // Steps can be -/+ for left/right rotation. - [[nodiscard]] Vector3i Rotate90(RotateAxis axis, int steps) const noexcept { - - steps = ((steps % 4) + 4) % 4; // normalize steps to 0..3 - - if (steps == 0) { return *this; } - - switch (axis) { - case RotateAxis::X: - switch (steps) { - case 1: return Vector3i(x, -z, y); - case 2: return Vector3i(x, -y, -z); - case 3: return Vector3i(x, z, -y); - } - break; - case RotateAxis::Y: - switch (steps) { - case 1: return Vector3i(z, y, -x); - case 2: return Vector3i(-x, y, -z); - case 3: return Vector3i(-z, y, x); - } - break; - case RotateAxis::Z: - switch (steps) { - case 1: return Vector3i(-y, x, z); - case 2: return Vector3i(-x, -y, z); - case 3: return Vector3i(y, -x, z); - } - break; - } - - return *this; - } - + public: + int x = 0; + int y = 0; + int z = 0; + + static const Vector3i Zero; + static const Vector3i UnitX; + static const Vector3i UnitY; + static const Vector3i UnitZ; + static const Vector3i UnitScale; + + // Constructors // + + constexpr Vector3i() noexcept : x(0), y(0), z(0) { + } + + constexpr Vector3i(int X, int Y, int Z) noexcept : x(X), y(Y), z(Z) { + } + + explicit constexpr Vector3i(const int (&arr)[3]) noexcept : x(arr[0]), y(arr[1]), z(arr[2]) { + } + + Vector3i(const DirectX::XMINT3& xi) noexcept : x(xi.x), y(xi.y), z(xi.z) { + } + + // DirectX Conversions // + + operator DirectX::XMINT3() const noexcept { + return DirectX::XMINT3(x, y, z); + } + + operator DirectX::XMFLOAT3() const noexcept { + return DirectX::XMFLOAT3(static_cast(x), static_cast(y), static_cast(z)); + } + + Vector3i& operator=(const DirectX::XMINT3& xi) noexcept { + x = xi.x; + y = xi.y; + z = xi.z; + return *this; + } + + Vector3i& operator=(DirectX::FXMVECTOR fxm) noexcept { + DirectX::XMFLOAT3 temp; + DirectX::XMStoreFloat3(&temp, fxm); + x = static_cast(temp.x); + y = static_cast(temp.y); + z = static_cast(temp.z); + return *this; + } + + // Explicit conversion(1 for position, 0 for direction) + [[nodiscard]] DirectX::XMVECTOR ToXMVECTOR(float w) const noexcept { + return DirectX::XMVectorSet(static_cast(x), static_cast(y), static_cast(z), w); + } + + // Compound Assignment Operators (modifying *this) // + + Vector3i& operator+=(const Vector3i& rhs) noexcept { + x += rhs.x; + y += rhs.y; + z += rhs.z; + return *this; + } + + Vector3i& operator-=(const Vector3i& rhs) noexcept { + x -= rhs.x; + y -= rhs.y; + z -= rhs.z; + return *this; + } + + Vector3i& operator*=(int s) noexcept { + x *= s; + y *= s; + z *= s; + return *this; + } + + Vector3i& operator/=(int s) noexcept { + assert(s != 0 && "Division by zero in Vector3i::operator/="); + x /= s; + y /= s; + z /= s; + return *this; + } + + // Arithmetic Operators (returning a copy) // + + friend Vector3i operator+(Vector3i a, const Vector3i& b) noexcept { + a += b; + return a; + } + + friend Vector3i operator-(Vector3i a, const Vector3i& b) noexcept { + a -= b; + return a; + } + + friend Vector3i operator*(Vector3i a, int s) noexcept { + a *= s; + return a; + } + + friend Vector3i operator*(int s, Vector3i a) noexcept { + a *= s; + return a; + } + + friend Vector3i operator/(Vector3i a, int s) noexcept { + assert(s != 0 && "Division by zero in Vector3i::operator/"); + a /= s; + return a; + } + + // Comparison operators // + + bool operator==(const Vector3i& rhs) const noexcept { + constexpr float eps = vecEpsilon; + return abs(x - rhs.x) < eps && abs(y - rhs.y) < eps && abs(z - rhs.z) < eps; + } + + bool operator!=(const Vector3i& rhs) const noexcept { + return !(*this == rhs); + } + + // Helper functions // + + constexpr int LengthSquared() const noexcept { + return x * x + y * y + z * z; + } + + constexpr int Dot(const Vector3i& other) const noexcept { + return x * other.x + y * other.y + z * other.z; + } + + [[nodiscard]] Vector2i xy() const noexcept { + return Vector2i(x, y); + } + + [[nodiscard]] Vector2i xz() const noexcept { + return Vector2i(x, z); + } + + [[nodiscard]] Vector2i yz() const noexcept { + return Vector2i(y, z); + } + + enum class RotateAxis { + X, + Y, + Z, + }; + + // Steps can be -/+ for left/right rotation. + [[nodiscard]] Vector3i Rotate90(RotateAxis axis, int steps) const noexcept { + steps = ((steps % 4) + 4) % 4; // normalize steps to 0..3 + + if (steps == 0) { + return *this; + } + + switch (axis) { + case RotateAxis::X: + switch (steps) { + case 1: + return Vector3i(x, -z, y); + case 2: + return Vector3i(x, -y, -z); + case 3: + return Vector3i(x, z, -y); + } + break; + case RotateAxis::Y: + switch (steps) { + case 1: + return Vector3i(z, y, -x); + case 2: + return Vector3i(-x, y, -z); + case 3: + return Vector3i(-z, y, x); + } + break; + case RotateAxis::Z: + switch (steps) { + case 1: + return Vector3i(-y, x, z); + case 2: + return Vector3i(-x, -y, z); + case 3: + return Vector3i(y, -x, z); + } + break; + } + + return *this; + } }; inline const Vector3i Vector3i::Zero(0, 0, 0); diff --git a/Source/Core/Platform/WindowsApplication.cpp b/Source/Core/Platform/WindowsApplication.cpp index fb179b5..d2fdfcb 100644 --- a/Source/Core/Platform/WindowsApplication.cpp +++ b/Source/Core/Platform/WindowsApplication.cpp @@ -1,11 +1,12 @@ #include "stdafx.h" + #include "WindowsApplication.h" + #include "Engine/Engine.h" #include "Engine/Window/Window.h" #include "Engine/frameData.h" int RF::WindowsApplication::Run(HINSTANCE hInstance, int cmdShow) { - RF::EngineCreationParams engineParams; engineParams.windowProc = WindowProc; engineParams.cmdShow = cmdShow; @@ -13,9 +14,8 @@ int RF::WindowsApplication::Run(HINSTANCE hInstance, int cmdShow) { RF::Engine engine(engineParams); - MSG msg = { 0 }; + MSG msg = {0}; while (msg.message != WM_QUIT) { - // Process queued messages if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { TranslateMessage(&msg); @@ -35,26 +35,23 @@ int RF::WindowsApplication::Run(HINSTANCE hInstance, int cmdShow) { } LRESULT RF::WindowsApplication::WindowProc(HWND hWND, UINT message, WPARAM wParam, LPARAM lParam) { - RF::Engine* engine = reinterpret_cast(GetWindowLongPtr(hWND, GWLP_USERDATA)); switch (message) { - case WM_CREATE: { - // Saves the engine* passed from window constructor - LPCREATESTRUCT pCreateStruct = reinterpret_cast(lParam); - SetWindowLongPtr(hWND, GWLP_USERDATA, reinterpret_cast(pCreateStruct->lpCreateParams)); - return 0; - } - case WM_DESTROY: { - - PostQuitMessage(0); - return 0; - } - case WM_SIZE: - { - engine->OnResize(LOWORD(lParam), HIWORD(lParam)); - return 0; - } + case WM_CREATE: { + // Saves the engine* passed from window constructor + LPCREATESTRUCT pCreateStruct = reinterpret_cast(lParam); + SetWindowLongPtr(hWND, GWLP_USERDATA, reinterpret_cast(pCreateStruct->lpCreateParams)); + return 0; + } + case WM_DESTROY: { + PostQuitMessage(0); + return 0; + } + case WM_SIZE: { + engine->OnResize(LOWORD(lParam), HIWORD(lParam)); + return 0; + } } return DefWindowProc(hWND, message, wParam, lParam); diff --git a/Source/Core/Platform/WindowsApplication.h b/Source/Core/Platform/WindowsApplication.h index f5c59cc..e20cab4 100644 --- a/Source/Core/Platform/WindowsApplication.h +++ b/Source/Core/Platform/WindowsApplication.h @@ -1,12 +1,13 @@ #pragma once + namespace RF { - class Engine; +class Engine; class WindowsApplication { -public: + public: int Run(HINSTANCE hInstance, int cmdShow); -private: + private: static LRESULT CALLBACK WindowProc(HWND hWND, UINT message, WPARAM wParam, LPARAM lParam); }; -} \ No newline at end of file +} // namespace RF \ No newline at end of file diff --git a/Source/Core/Util/jsonUtil.cpp b/Source/Core/Util/jsonUtil.cpp index 7850cb5..89727af 100644 --- a/Source/Core/Util/jsonUtil.cpp +++ b/Source/Core/Util/jsonUtil.cpp @@ -1,18 +1,19 @@ #include "stdafx.h" -#include + #include "jsonUtil.h" +#include + namespace RF::Json { - constexpr std::string_view gJson = ".json"; +constexpr std::string_view gJson = ".json"; - bool isJson(const std::string& directory) { - auto strPos = directory.find_last_of('.'); - std::string lineEnding(directory.begin() + strPos, directory.end()); +bool isJson(const std::string& directory) { + auto strPos = directory.find_last_of('.'); + std::string lineEnding(directory.begin() + strPos, directory.end()); - return lineEnding == gJson; - } + return lineEnding == gJson; } - +} // namespace RF::Json nlohmann::json RF::Json::Parse(const std::string& directory) { if (!isJson(directory)) { diff --git a/Source/Core/Util/jsonUtil.h b/Source/Core/Util/jsonUtil.h index 5a6f002..493697a 100644 --- a/Source/Core/Util/jsonUtil.h +++ b/Source/Core/Util/jsonUtil.h @@ -1,35 +1,36 @@ #pragma once -namespace RF { - namespace Json { - /// - /// Parses the contents of the specified directory and returns the result as a JSON object. - /// - /// The path to the directory to be parsed. - /// A nlohmann::json object containing the parsed data from the directory. - nlohmann::json Parse(const std::string& directory); - /// - /// Serializes a JSON object to a specified directory. - /// - /// The path to the directory where the JSON object will be serialized. - /// The JSON object to serialize. - void Serialize(const std::string& directory, const nlohmann::json& obj); +namespace RF { +namespace Json { +/// +/// Parses the contents of the specified directory and returns the result as a JSON object. +/// +/// The path to the directory to be parsed. +/// A nlohmann::json object containing the parsed data from the directory. +nlohmann::json Parse(const std::string& directory); - /// - /// Tries to extract a value from a given json object using the specified key. - /// - /// - /// JSON object to extract data from - /// Name of the wanted value - /// A default value to fall back on if key doesn't excist - /// - template - T TryGet(const nlohmann::json& json, const std::string& key, const T& defaultValue) { - if(!json.contains(key)) { - return defaultValue; - } +/// +/// Serializes a JSON object to a specified directory. +/// +/// The path to the directory where the JSON object will be serialized. +/// The JSON object to serialize. +void Serialize(const std::string& directory, const nlohmann::json& obj); - return json.at(key).get(); - } +/// +/// Tries to extract a value from a given json object using the specified key. +/// +/// +/// JSON object to extract data from +/// Name of the wanted value +/// A default value to fall back on if key doesn't excist +/// +template +T TryGet(const nlohmann::json& json, const std::string& key, const T& defaultValue) { + if (!json.contains(key)) { + return defaultValue; } -} \ No newline at end of file + + return json.at(key).get(); +} +} // namespace Json +} // namespace RF \ No newline at end of file diff --git a/Source/Core/pch/stdafx.h b/Source/Core/pch/stdafx.h index 73e37c4..f724f69 100644 --- a/Source/Core/pch/stdafx.h +++ b/Source/Core/pch/stdafx.h @@ -1,11 +1,11 @@ #pragma once // stl +#include +#include +#include #include #include -#include #include -#include -#include // Windows #include diff --git a/Source/CoreTests/Math/Matrix3x3Tests.cpp b/Source/CoreTests/Math/Matrix3x3Tests.cpp index 0cc63c3..7056aa7 100644 --- a/Source/CoreTests/Math/Matrix3x3Tests.cpp +++ b/Source/CoreTests/Math/Matrix3x3Tests.cpp @@ -1,31 +1,30 @@ #include -#include #include "Math/Matrix3x3.h" #include "Utility/TestUtility.h" +#include using namespace DirectX; TestUtility testUtility; - namespace DirectX { - inline bool XMMatrixEqual(const DirectX::XMMATRIX& lhs, const DirectX::XMMATRIX& rhs) noexcept { - static const DirectX::XMVECTOR epsilon = DirectX::XMVectorReplicate(0.00001f); - return DirectX::XMVector4NearEqual(lhs.r[0], rhs.r[0], epsilon) && - DirectX::XMVector4NearEqual(lhs.r[1], rhs.r[1], epsilon) && - DirectX::XMVector4NearEqual(lhs.r[2], rhs.r[2], epsilon) && - DirectX::XMVector4NearEqual(lhs.r[3], rhs.r[3], epsilon); - } +inline bool XMMatrixEqual(const DirectX::XMMATRIX& lhs, const DirectX::XMMATRIX& rhs) noexcept { + static const DirectX::XMVECTOR epsilon = DirectX::XMVectorReplicate(0.00001f); + return DirectX::XMVector4NearEqual(lhs.r[0], rhs.r[0], epsilon) && + DirectX::XMVector4NearEqual(lhs.r[1], rhs.r[1], epsilon) && + DirectX::XMVector4NearEqual(lhs.r[2], rhs.r[2], epsilon) && + DirectX::XMVector4NearEqual(lhs.r[3], rhs.r[3], epsilon); +} - inline bool operator==(const DirectX::XMMATRIX& lhs, const DirectX::XMMATRIX& rhs) noexcept { - return XMMatrixEqual(lhs, rhs); - } +inline bool operator==(const DirectX::XMMATRIX& lhs, const DirectX::XMMATRIX& rhs) noexcept { + return XMMatrixEqual(lhs, rhs); +} - inline bool operator!=(const DirectX::XMMATRIX& lhs, const DirectX::XMMATRIX& rhs) noexcept { - return !(lhs == rhs); - } +inline bool operator!=(const DirectX::XMMATRIX& lhs, const DirectX::XMMATRIX& rhs) noexcept { + return !(lhs == rhs); } +} // namespace DirectX inline bool operator==(const Matrix3x3& lhs, const Matrix3x3& rhs) noexcept { return DirectX::XMMatrixEqual(lhs, rhs); @@ -40,499 +39,473 @@ inline bool operator==(const DirectX::XMMATRIX& lhs, const Matrix3x3& rhs) noexc } namespace RFMath { - //*********************************************************************** - TEST(Matrix3x3Tests, DefaultContructor) { - Matrix3x3 matrix; +//*********************************************************************** +TEST(Matrix3x3Tests, DefaultContructor) { + Matrix3x3 matrix; - EXPECT_EQ(matrix, XMMatrixIdentity()); - } + EXPECT_EQ(matrix, XMMatrixIdentity()); +} - //*********************************************************************** - TEST(Matrix3x3Tests, CopyContructor) { - for (int i = 0; i < 50; ++i) { - float randomValue = testUtility.GetRandomFloat(); +//*********************************************************************** +TEST(Matrix3x3Tests, CopyContructor) { + for (int i = 0; i < 50; ++i) { + float randomValue = testUtility.GetRandomFloat(); - Matrix3x3 matrix1; - matrix1(0, 0) = randomValue; - matrix1(0, 1) = randomValue; - matrix1(1, 1) = randomValue; - matrix1(1, 2) = randomValue; - matrix1(2, 2) = randomValue; + Matrix3x3 matrix1; + matrix1(0, 0) = randomValue; + matrix1(0, 1) = randomValue; + matrix1(1, 1) = randomValue; + matrix1(1, 2) = randomValue; + matrix1(2, 2) = randomValue; - Matrix3x3 matrix2(matrix1); - EXPECT_EQ(matrix1, matrix2); + Matrix3x3 matrix2(matrix1); + EXPECT_EQ(matrix1, matrix2); - XMMATRIX dxMatrix(matrix1); - EXPECT_EQ(matrix1, dxMatrix); - } + XMMATRIX dxMatrix(matrix1); + EXPECT_EQ(matrix1, dxMatrix); } +} - //*********************************************************************** - TEST(Matrix3x3Tests, AssignmentOperator) { - float randomValue = testUtility.GetRandomFloat(1.5f, 10000.0f); - - auto row = testUtility.GetRandomInt(0, 3); - auto column = testUtility.GetRandomInt(0, 3); +//*********************************************************************** +TEST(Matrix3x3Tests, AssignmentOperator) { + float randomValue = testUtility.GetRandomFloat(1.5f, 10000.0f); - Matrix3x3 matrix1; - matrix1(row, column) = randomValue; + auto row = testUtility.GetRandomInt(0, 3); + auto column = testUtility.GetRandomInt(0, 3); - Matrix3x3 matrix2; - EXPECT_NE(matrix2(row, column), randomValue); + Matrix3x3 matrix1; + matrix1(row, column) = randomValue; - matrix2 = matrix1; - EXPECT_EQ(matrix2.mMatrix, matrix1.mMatrix); - } + Matrix3x3 matrix2; + EXPECT_NE(matrix2(row, column), randomValue); - //*********************************************************************** - TEST(Matrix3x3Tests, MultiplicationOperator) { - const float r1 = testUtility.GetRandomFloat(-1000.0f, 1000.0f); - Matrix3x3 randomMatrix1 = { - r1, r1, r1, - r1, r1, r1, - r1, r1, r1, - }; + matrix2 = matrix1; + EXPECT_EQ(matrix2.mMatrix, matrix1.mMatrix); +} - const float r2 = testUtility.GetRandomFloat(-1000.0f, 1000.0f); - Matrix3x3 randomMatrix2 = { - r2, r2, r2, - r2, r2, r2, - r2, r2, r2, - }; +//*********************************************************************** +TEST(Matrix3x3Tests, MultiplicationOperator) { + const float r1 = testUtility.GetRandomFloat(-1000.0f, 1000.0f); + Matrix3x3 randomMatrix1 = { + r1, r1, r1, r1, r1, r1, r1, r1, r1, + }; - auto resultMatrix = randomMatrix1 * randomMatrix2; + const float r2 = testUtility.GetRandomFloat(-1000.0f, 1000.0f); + Matrix3x3 randomMatrix2 = { + r2, r2, r2, r2, r2, r2, r2, r2, r2, + }; - // | a | b | c | | j | k | l | | aj + bm + cp | ak + bn + cq | al + bo + cr | - // |---+---+---| |---+---+---| |--------------+--------------+--------------| - // | d | e | f | X | m | n | o | = | dj + em + fp | dk + en + fq | dl + eo + fr | - // |---+---+---| |---+---+---| |--------------+--------------+--------------| - // | g | h | i | | p | q | r | | gj + hm + ip | gk + hn + iq | gl + ho + ir | + auto resultMatrix = randomMatrix1 * randomMatrix2; + // | a | b | c | | j | k | l | | aj + bm + cp | ak + bn + cq | al + bo + cr | + // |---+---+---| |---+---+---| |--------------+--------------+--------------| + // | d | e | f | X | m | n | o | = | dj + em + fp | dk + en + fq | dl + eo + fr | + // |---+---+---| |---+---+---| |--------------+--------------+--------------| + // | g | h | i | | p | q | r | | gj + hm + ip | gk + hn + iq | gl + ho + ir | - // row 0 - { - // r0c0 - const float expR0C0 = - randomMatrix1(0, 0) * randomMatrix2(0, 0) + // a * j - randomMatrix1(0, 1) * randomMatrix2(1, 0) + // b * m - randomMatrix1(0, 2) * randomMatrix2(2, 0); // c * p + // row 0 + { + // r0c0 + const float expR0C0 = randomMatrix1(0, 0) * randomMatrix2(0, 0) + // a * j + randomMatrix1(0, 1) * randomMatrix2(1, 0) + // b * m + randomMatrix1(0, 2) * randomMatrix2(2, 0); // c * p - EXPECT_NEAR(resultMatrix(0, 0), expR0C0, gFloatMargin); + EXPECT_NEAR(resultMatrix(0, 0), expR0C0, gFloatMargin); - // r0c1 - const float expR0C1 = - randomMatrix1(0, 0) * randomMatrix2(0, 1) + // a * k - randomMatrix1(0, 1) * randomMatrix2(1, 1) + // b * n - randomMatrix1(0, 2) * randomMatrix2(2, 1); // c * q + // r0c1 + const float expR0C1 = randomMatrix1(0, 0) * randomMatrix2(0, 1) + // a * k + randomMatrix1(0, 1) * randomMatrix2(1, 1) + // b * n + randomMatrix1(0, 2) * randomMatrix2(2, 1); // c * q - EXPECT_NEAR(resultMatrix(0, 1), expR0C1, gFloatMargin); + EXPECT_NEAR(resultMatrix(0, 1), expR0C1, gFloatMargin); - // r0c2 - const float expR0C2 = - randomMatrix1(0, 0) * randomMatrix2(0, 2) + // a * l - randomMatrix1(0, 1) * randomMatrix2(1, 2) + // b * o - randomMatrix1(0, 2) * randomMatrix2(2, 2); // c * r + // r0c2 + const float expR0C2 = randomMatrix1(0, 0) * randomMatrix2(0, 2) + // a * l + randomMatrix1(0, 1) * randomMatrix2(1, 2) + // b * o + randomMatrix1(0, 2) * randomMatrix2(2, 2); // c * r - EXPECT_NEAR(resultMatrix(0, 2), expR0C2, gFloatMargin); - } + EXPECT_NEAR(resultMatrix(0, 2), expR0C2, gFloatMargin); + } - // row 1 - { - // r1c0 - const float expR1C0 = - randomMatrix1(1, 0) * randomMatrix2(0, 0) + // d * j - randomMatrix1(1, 1) * randomMatrix2(1, 0) + // e * m - randomMatrix1(1, 2) * randomMatrix2(2, 0); // f * p + // row 1 + { + // r1c0 + const float expR1C0 = randomMatrix1(1, 0) * randomMatrix2(0, 0) + // d * j + randomMatrix1(1, 1) * randomMatrix2(1, 0) + // e * m + randomMatrix1(1, 2) * randomMatrix2(2, 0); // f * p - EXPECT_NEAR(resultMatrix(1, 0), expR1C0, gFloatMargin); + EXPECT_NEAR(resultMatrix(1, 0), expR1C0, gFloatMargin); - // r1c1 - const float expR1C1 = - randomMatrix1(1, 0) * randomMatrix2(0, 1) + // d * k - randomMatrix1(1, 1) * randomMatrix2(1, 1) + // e * n - randomMatrix1(1, 2) * randomMatrix2(2, 1); // f * q + // r1c1 + const float expR1C1 = randomMatrix1(1, 0) * randomMatrix2(0, 1) + // d * k + randomMatrix1(1, 1) * randomMatrix2(1, 1) + // e * n + randomMatrix1(1, 2) * randomMatrix2(2, 1); // f * q - EXPECT_NEAR(resultMatrix(1, 1), expR1C1, gFloatMargin); + EXPECT_NEAR(resultMatrix(1, 1), expR1C1, gFloatMargin); - // r1c2 - const float expR1C2 = - randomMatrix1(1, 0) * randomMatrix2(0, 2) + // d * l - randomMatrix1(1, 1) * randomMatrix2(1, 2) + // e * o - randomMatrix1(1, 2) * randomMatrix2(2, 2); // f * r + // r1c2 + const float expR1C2 = randomMatrix1(1, 0) * randomMatrix2(0, 2) + // d * l + randomMatrix1(1, 1) * randomMatrix2(1, 2) + // e * o + randomMatrix1(1, 2) * randomMatrix2(2, 2); // f * r - EXPECT_NEAR(resultMatrix(1, 2), expR1C2, gFloatMargin); - } + EXPECT_NEAR(resultMatrix(1, 2), expR1C2, gFloatMargin); + } - // row 2 - { - // r2c0 - const float expR2C0 = - randomMatrix1(2, 0) * randomMatrix2(0, 0) + // g * j - randomMatrix1(2, 1) * randomMatrix2(1, 0) + // h * m - randomMatrix1(2, 2) * randomMatrix2(2, 0); // i * p + // row 2 + { + // r2c0 + const float expR2C0 = randomMatrix1(2, 0) * randomMatrix2(0, 0) + // g * j + randomMatrix1(2, 1) * randomMatrix2(1, 0) + // h * m + randomMatrix1(2, 2) * randomMatrix2(2, 0); // i * p - EXPECT_NEAR(resultMatrix(2, 0), expR2C0, gFloatMargin); + EXPECT_NEAR(resultMatrix(2, 0), expR2C0, gFloatMargin); - // r2c1 - const float expR2C1 = - randomMatrix1(2, 0) * randomMatrix2(0, 1) + // g * k - randomMatrix1(2, 1) * randomMatrix2(1, 1) + // h * n - randomMatrix1(2, 2) * randomMatrix2(2, 1); // i * q + // r2c1 + const float expR2C1 = randomMatrix1(2, 0) * randomMatrix2(0, 1) + // g * k + randomMatrix1(2, 1) * randomMatrix2(1, 1) + // h * n + randomMatrix1(2, 2) * randomMatrix2(2, 1); // i * q - EXPECT_NEAR(resultMatrix(2, 1), expR2C1, gFloatMargin); + EXPECT_NEAR(resultMatrix(2, 1), expR2C1, gFloatMargin); - // r2c2 - const float expR2C2 = - randomMatrix1(2, 0) * randomMatrix2(0, 2) + // g * l - randomMatrix1(2, 1) * randomMatrix2(1, 2) + // h * o - randomMatrix1(2, 2) * randomMatrix2(2, 2); // i * r + // r2c2 + const float expR2C2 = randomMatrix1(2, 0) * randomMatrix2(0, 2) + // g * l + randomMatrix1(2, 1) * randomMatrix2(1, 2) + // h * o + randomMatrix1(2, 2) * randomMatrix2(2, 2); // i * r - EXPECT_NEAR(resultMatrix(2, 2), expR2C2, gFloatMargin); - } + EXPECT_NEAR(resultMatrix(2, 2), expR2C2, gFloatMargin); } +} - //*********************************************************************** - TEST(Matrix3x3Tests, MultiplicationAssignmentOperator) { - const float r1 = testUtility.GetRandomFloat(-1000.0f, 1000.0f); - Matrix3x3 randomMatrix1 = { - r1, r1, r1, - r1, r1, r1, - r1, r1, r1, - }; +//*********************************************************************** +TEST(Matrix3x3Tests, MultiplicationAssignmentOperator) { + const float r1 = testUtility.GetRandomFloat(-1000.0f, 1000.0f); + Matrix3x3 randomMatrix1 = { + r1, r1, r1, r1, r1, r1, r1, r1, r1, + }; - const float r2 = testUtility.GetRandomFloat(-1000.0f, 1000.0f); - Matrix3x3 randomMatrix2 = { - r2, r2, r2, - r2, r2, r2, - r2, r2, r2, - }; + const float r2 = testUtility.GetRandomFloat(-1000.0f, 1000.0f); + Matrix3x3 randomMatrix2 = { + r2, r2, r2, r2, r2, r2, r2, r2, r2, + }; - Matrix3x3 originalMatrix1 = randomMatrix1; - ASSERT_EQ(randomMatrix1, originalMatrix1); + Matrix3x3 originalMatrix1 = randomMatrix1; + ASSERT_EQ(randomMatrix1, originalMatrix1); - randomMatrix1 *= randomMatrix2; + randomMatrix1 *= randomMatrix2; - // row 0 - { - // r0c0 - const float expR0C0 = - originalMatrix1(0, 0) * randomMatrix2(0, 0) + // a * j - originalMatrix1(0, 1) * randomMatrix2(1, 0) + // b * m - originalMatrix1(0, 2) * randomMatrix2(2, 0); // c * p + // row 0 + { + // r0c0 + const float expR0C0 = originalMatrix1(0, 0) * randomMatrix2(0, 0) + // a * j + originalMatrix1(0, 1) * randomMatrix2(1, 0) + // b * m + originalMatrix1(0, 2) * randomMatrix2(2, 0); // c * p - EXPECT_NEAR(randomMatrix1(0, 0), expR0C0, gFloatMargin); + EXPECT_NEAR(randomMatrix1(0, 0), expR0C0, gFloatMargin); - // r0c1 - const float expR0C1 = - originalMatrix1(0, 0) * randomMatrix2(0, 1) + // a * k - originalMatrix1(0, 1) * randomMatrix2(1, 1) + // b * n - originalMatrix1(0, 2) * randomMatrix2(2, 1); // c * q + // r0c1 + const float expR0C1 = originalMatrix1(0, 0) * randomMatrix2(0, 1) + // a * k + originalMatrix1(0, 1) * randomMatrix2(1, 1) + // b * n + originalMatrix1(0, 2) * randomMatrix2(2, 1); // c * q - EXPECT_NEAR(randomMatrix1(0, 1), expR0C1, gFloatMargin); + EXPECT_NEAR(randomMatrix1(0, 1), expR0C1, gFloatMargin); - // r0c2 - const float expR0C2 = - originalMatrix1(0, 0) * randomMatrix2(0, 2) + // a * l - originalMatrix1(0, 1) * randomMatrix2(1, 2) + // b * o - originalMatrix1(0, 2) * randomMatrix2(2, 2); // c * r + // r0c2 + const float expR0C2 = originalMatrix1(0, 0) * randomMatrix2(0, 2) + // a * l + originalMatrix1(0, 1) * randomMatrix2(1, 2) + // b * o + originalMatrix1(0, 2) * randomMatrix2(2, 2); // c * r - EXPECT_NEAR(randomMatrix1(0, 2), expR0C2, gFloatMargin); - } + EXPECT_NEAR(randomMatrix1(0, 2), expR0C2, gFloatMargin); + } - // row 1 - { - // r1c0 - const float expR1C0 = - originalMatrix1(1, 0) * randomMatrix2(0, 0) + // d * j - originalMatrix1(1, 1) * randomMatrix2(1, 0) + // e * m - originalMatrix1(1, 2) * randomMatrix2(2, 0); // f * p + // row 1 + { + // r1c0 + const float expR1C0 = originalMatrix1(1, 0) * randomMatrix2(0, 0) + // d * j + originalMatrix1(1, 1) * randomMatrix2(1, 0) + // e * m + originalMatrix1(1, 2) * randomMatrix2(2, 0); // f * p - EXPECT_NEAR(randomMatrix1(1, 0), expR1C0, gFloatMargin); + EXPECT_NEAR(randomMatrix1(1, 0), expR1C0, gFloatMargin); - // r1c1 - const float expR1C1 = - originalMatrix1(1, 0) * randomMatrix2(0, 1) + // d * k - originalMatrix1(1, 1) * randomMatrix2(1, 1) + // e * n - originalMatrix1(1, 2) * randomMatrix2(2, 1); // f * q + // r1c1 + const float expR1C1 = originalMatrix1(1, 0) * randomMatrix2(0, 1) + // d * k + originalMatrix1(1, 1) * randomMatrix2(1, 1) + // e * n + originalMatrix1(1, 2) * randomMatrix2(2, 1); // f * q - EXPECT_NEAR(randomMatrix1(1, 1), expR1C1, gFloatMargin); + EXPECT_NEAR(randomMatrix1(1, 1), expR1C1, gFloatMargin); - // r1c2 - const float expR1C2 = - originalMatrix1(1, 0) * randomMatrix2(0, 2) + // d * l - originalMatrix1(1, 1) * randomMatrix2(1, 2) + // e * o - originalMatrix1(1, 2) * randomMatrix2(2, 2); // f * r + // r1c2 + const float expR1C2 = originalMatrix1(1, 0) * randomMatrix2(0, 2) + // d * l + originalMatrix1(1, 1) * randomMatrix2(1, 2) + // e * o + originalMatrix1(1, 2) * randomMatrix2(2, 2); // f * r - EXPECT_NEAR(randomMatrix1(1, 2), expR1C2, gFloatMargin); - } + EXPECT_NEAR(randomMatrix1(1, 2), expR1C2, gFloatMargin); + } - // row 2 - { - // r2c0 - const float expR2C0 = - originalMatrix1(2, 0) * randomMatrix2(0, 0) + // g * j - originalMatrix1(2, 1) * randomMatrix2(1, 0) + // h * m - originalMatrix1(2, 2) * randomMatrix2(2, 0); // i * p + // row 2 + { + // r2c0 + const float expR2C0 = originalMatrix1(2, 0) * randomMatrix2(0, 0) + // g * j + originalMatrix1(2, 1) * randomMatrix2(1, 0) + // h * m + originalMatrix1(2, 2) * randomMatrix2(2, 0); // i * p - EXPECT_NEAR(randomMatrix1(2, 0), expR2C0, gFloatMargin); + EXPECT_NEAR(randomMatrix1(2, 0), expR2C0, gFloatMargin); - // r2c1 - const float expR2C1 = - originalMatrix1(2, 0) * randomMatrix2(0, 1) + // g * k - originalMatrix1(2, 1) * randomMatrix2(1, 1) + // h * n - originalMatrix1(2, 2) * randomMatrix2(2, 1); // i * q + // r2c1 + const float expR2C1 = originalMatrix1(2, 0) * randomMatrix2(0, 1) + // g * k + originalMatrix1(2, 1) * randomMatrix2(1, 1) + // h * n + originalMatrix1(2, 2) * randomMatrix2(2, 1); // i * q - EXPECT_NEAR(randomMatrix1(2, 1), expR2C1, gFloatMargin); + EXPECT_NEAR(randomMatrix1(2, 1), expR2C1, gFloatMargin); - // r2c2 - const float expR2C2 = - originalMatrix1(2, 0) * randomMatrix2(0, 2) + // g * l - originalMatrix1(2, 1) * randomMatrix2(1, 2) + // h * o - originalMatrix1(2, 2) * randomMatrix2(2, 2); // i * r + // r2c2 + const float expR2C2 = originalMatrix1(2, 0) * randomMatrix2(0, 2) + // g * l + originalMatrix1(2, 1) * randomMatrix2(1, 2) + // h * o + originalMatrix1(2, 2) * randomMatrix2(2, 2); // i * r - EXPECT_NEAR(randomMatrix1(2, 2), expR2C2, gFloatMargin); - } + EXPECT_NEAR(randomMatrix1(2, 2), expR2C2, gFloatMargin); } +} - //*********************************************************************** - TEST(Matrix3x3Tests, AdditionOperator) { - for (int i = 0; i < 50; ++i) { - float randomValue = testUtility.GetRandomFloat(); - Matrix3x3 matrix1; - matrix1(0, 0) = randomValue; - matrix1(1, 1) = randomValue; - matrix1(2, 2) = randomValue; - Matrix3x3 matrix2; - matrix2(0, 0) = randomValue; - matrix2(1, 1) = randomValue; - matrix2(2, 2) = randomValue; - Matrix3x3 result = matrix1 + matrix2; - EXPECT_EQ(result(0, 0), randomValue + randomValue); - EXPECT_EQ(result(1, 1), randomValue + randomValue); - EXPECT_EQ(result(2, 2), randomValue + randomValue); - } +//*********************************************************************** +TEST(Matrix3x3Tests, AdditionOperator) { + for (int i = 0; i < 50; ++i) { + float randomValue = testUtility.GetRandomFloat(); + Matrix3x3 matrix1; + matrix1(0, 0) = randomValue; + matrix1(1, 1) = randomValue; + matrix1(2, 2) = randomValue; + Matrix3x3 matrix2; + matrix2(0, 0) = randomValue; + matrix2(1, 1) = randomValue; + matrix2(2, 2) = randomValue; + Matrix3x3 result = matrix1 + matrix2; + EXPECT_EQ(result(0, 0), randomValue + randomValue); + EXPECT_EQ(result(1, 1), randomValue + randomValue); + EXPECT_EQ(result(2, 2), randomValue + randomValue); } +} - //*********************************************************************** - TEST(Matrix3x3Tests, AdditionAssignmentOperator) { - for (int i = 0; i < 50; ++i) { - float randomValue = testUtility.GetRandomFloat(); - Matrix3x3 matrix1; - matrix1(0, 0) = randomValue; - matrix1(1, 1) = randomValue; - matrix1(2, 2) = randomValue; - Matrix3x3 matrix2; - matrix2(0, 0) = randomValue; - matrix2(1, 1) = randomValue; - matrix2(2, 2) = randomValue; - matrix1 += matrix2; - EXPECT_EQ(matrix1(0, 0), randomValue + randomValue); - EXPECT_EQ(matrix1(1, 1), randomValue + randomValue); - EXPECT_EQ(matrix1(2, 2), randomValue + randomValue); - } +//*********************************************************************** +TEST(Matrix3x3Tests, AdditionAssignmentOperator) { + for (int i = 0; i < 50; ++i) { + float randomValue = testUtility.GetRandomFloat(); + Matrix3x3 matrix1; + matrix1(0, 0) = randomValue; + matrix1(1, 1) = randomValue; + matrix1(2, 2) = randomValue; + Matrix3x3 matrix2; + matrix2(0, 0) = randomValue; + matrix2(1, 1) = randomValue; + matrix2(2, 2) = randomValue; + matrix1 += matrix2; + EXPECT_EQ(matrix1(0, 0), randomValue + randomValue); + EXPECT_EQ(matrix1(1, 1), randomValue + randomValue); + EXPECT_EQ(matrix1(2, 2), randomValue + randomValue); } +} - //*********************************************************************** - TEST(Matrix3x3Tests, SubtractionOperator) { - for (int i = 0; i < 50; ++i) { - float randomValue = testUtility.GetRandomFloat(); - Matrix3x3 matrix1; - matrix1(0, 0) = randomValue; - matrix1(1, 1) = randomValue; - matrix1(2, 2) = randomValue; - Matrix3x3 matrix2; - matrix2(0, 0) = randomValue; - matrix2(1, 1) = randomValue; - matrix2(2, 2) = randomValue; - Matrix3x3 result = matrix1 - matrix2; - EXPECT_EQ(result(0, 0), 0.0f); - EXPECT_EQ(result(1, 1), 0.0f); - EXPECT_EQ(result(2, 2), 0.0f); - } +//*********************************************************************** +TEST(Matrix3x3Tests, SubtractionOperator) { + for (int i = 0; i < 50; ++i) { + float randomValue = testUtility.GetRandomFloat(); + Matrix3x3 matrix1; + matrix1(0, 0) = randomValue; + matrix1(1, 1) = randomValue; + matrix1(2, 2) = randomValue; + Matrix3x3 matrix2; + matrix2(0, 0) = randomValue; + matrix2(1, 1) = randomValue; + matrix2(2, 2) = randomValue; + Matrix3x3 result = matrix1 - matrix2; + EXPECT_EQ(result(0, 0), 0.0f); + EXPECT_EQ(result(1, 1), 0.0f); + EXPECT_EQ(result(2, 2), 0.0f); } +} - //*********************************************************************** - TEST(Matrix3x3Tests, SubtractionAssignmentOperator) { - for (int i = 0; i < 50; ++i) { - float randomValue = testUtility.GetRandomFloat(); - Matrix3x3 matrix1; - matrix1(0, 0) = randomValue; - matrix1(1, 1) = randomValue; - matrix1(2, 2) = randomValue; - Matrix3x3 matrix2; - matrix2(0, 0) = randomValue; - matrix2(1, 1) = randomValue; - matrix2(2, 2) = randomValue; - matrix1 -= matrix2; - EXPECT_EQ(matrix1(0, 0), 0.0f); - EXPECT_EQ(matrix1(1, 1), 0.0f); - EXPECT_EQ(matrix1(2, 2), 0.0f); - } +//*********************************************************************** +TEST(Matrix3x3Tests, SubtractionAssignmentOperator) { + for (int i = 0; i < 50; ++i) { + float randomValue = testUtility.GetRandomFloat(); + Matrix3x3 matrix1; + matrix1(0, 0) = randomValue; + matrix1(1, 1) = randomValue; + matrix1(2, 2) = randomValue; + Matrix3x3 matrix2; + matrix2(0, 0) = randomValue; + matrix2(1, 1) = randomValue; + matrix2(2, 2) = randomValue; + matrix1 -= matrix2; + EXPECT_EQ(matrix1(0, 0), 0.0f); + EXPECT_EQ(matrix1(1, 1), 0.0f); + EXPECT_EQ(matrix1(2, 2), 0.0f); } +} - //*********************************************************************** - TEST(Matrix3x3Tests, ScalarMultiplicationOperator) { - for (int i = 0; i < 50; ++i) { - float randomValue = testUtility.GetRandomFloat(); - Matrix3x3 matrix1; - matrix1(0, 0) = randomValue; - matrix1(1, 1) = randomValue; - matrix1(2, 2) = randomValue; - float scalar = testUtility.GetRandomFloat(); - Matrix3x3 result = matrix1 * scalar; - EXPECT_EQ(result(0, 0), randomValue * scalar); - EXPECT_EQ(result(1, 1), randomValue * scalar); - EXPECT_EQ(result(2, 2), randomValue * scalar); - } +//*********************************************************************** +TEST(Matrix3x3Tests, ScalarMultiplicationOperator) { + for (int i = 0; i < 50; ++i) { + float randomValue = testUtility.GetRandomFloat(); + Matrix3x3 matrix1; + matrix1(0, 0) = randomValue; + matrix1(1, 1) = randomValue; + matrix1(2, 2) = randomValue; + float scalar = testUtility.GetRandomFloat(); + Matrix3x3 result = matrix1 * scalar; + EXPECT_EQ(result(0, 0), randomValue * scalar); + EXPECT_EQ(result(1, 1), randomValue * scalar); + EXPECT_EQ(result(2, 2), randomValue * scalar); } +} - //*********************************************************************** - TEST(Matrix3x3Tests, ScalarMultiplicationAssignmentOperator) { - for (int i = 0; i < 50; ++i) { - float randomValue = testUtility.GetRandomFloat(); - Matrix3x3 matrix1; - matrix1(0, 0) = randomValue; - matrix1(1, 1) = randomValue; - matrix1(2, 2) = randomValue; - float scalar = testUtility.GetRandomFloat(); - matrix1 *= scalar; - EXPECT_EQ(matrix1(0, 0), randomValue * scalar); - EXPECT_EQ(matrix1(1, 1), randomValue * scalar); - EXPECT_EQ(matrix1(2, 2), randomValue * scalar); - } +//*********************************************************************** +TEST(Matrix3x3Tests, ScalarMultiplicationAssignmentOperator) { + for (int i = 0; i < 50; ++i) { + float randomValue = testUtility.GetRandomFloat(); + Matrix3x3 matrix1; + matrix1(0, 0) = randomValue; + matrix1(1, 1) = randomValue; + matrix1(2, 2) = randomValue; + float scalar = testUtility.GetRandomFloat(); + matrix1 *= scalar; + EXPECT_EQ(matrix1(0, 0), randomValue * scalar); + EXPECT_EQ(matrix1(1, 1), randomValue * scalar); + EXPECT_EQ(matrix1(2, 2), randomValue * scalar); } +} - //*********************************************************************** - TEST(Matrix3x3Tests, ScalarDivisionOperator) { - for (int i = 0; i < 50; ++i) { - float randomValue = testUtility.GetRandomFloat(1.0f, 10000.0f); - Matrix3x3 matrix1; - matrix1(0, 0) = randomValue; - matrix1(1, 1) = randomValue; - matrix1(2, 2) = randomValue; - float scalar = testUtility.GetRandomFloat(1.0f, 10000.0f); - Matrix3x3 result = matrix1 / scalar; - EXPECT_EQ(result(0, 0), randomValue / scalar); - EXPECT_EQ(result(1, 1), randomValue / scalar); - EXPECT_EQ(result(2, 2), randomValue / scalar); - } +//*********************************************************************** +TEST(Matrix3x3Tests, ScalarDivisionOperator) { + for (int i = 0; i < 50; ++i) { + float randomValue = testUtility.GetRandomFloat(1.0f, 10000.0f); + Matrix3x3 matrix1; + matrix1(0, 0) = randomValue; + matrix1(1, 1) = randomValue; + matrix1(2, 2) = randomValue; + float scalar = testUtility.GetRandomFloat(1.0f, 10000.0f); + Matrix3x3 result = matrix1 / scalar; + EXPECT_EQ(result(0, 0), randomValue / scalar); + EXPECT_EQ(result(1, 1), randomValue / scalar); + EXPECT_EQ(result(2, 2), randomValue / scalar); } +} - //*********************************************************************** - TEST(Matrix3x3Tests, ScalarDivisionAssignmentOperator) { - for (int i = 0; i < 50; ++i) { - float randomValue = testUtility.GetRandomFloat(1.0f, 10000.0f); - Matrix3x3 matrix1; - matrix1(0, 0) = randomValue; - matrix1(1, 1) = randomValue; - matrix1(2, 2) = randomValue; - float scalar = testUtility.GetRandomFloat(1.0f, 10000.0f); - matrix1 /= scalar; - EXPECT_EQ(matrix1(0, 0), randomValue / scalar); - EXPECT_EQ(matrix1(1, 1), randomValue / scalar); - EXPECT_EQ(matrix1(2, 2), randomValue / scalar); - } +//*********************************************************************** +TEST(Matrix3x3Tests, ScalarDivisionAssignmentOperator) { + for (int i = 0; i < 50; ++i) { + float randomValue = testUtility.GetRandomFloat(1.0f, 10000.0f); + Matrix3x3 matrix1; + matrix1(0, 0) = randomValue; + matrix1(1, 1) = randomValue; + matrix1(2, 2) = randomValue; + float scalar = testUtility.GetRandomFloat(1.0f, 10000.0f); + matrix1 /= scalar; + EXPECT_EQ(matrix1(0, 0), randomValue / scalar); + EXPECT_EQ(matrix1(1, 1), randomValue / scalar); + EXPECT_EQ(matrix1(2, 2), randomValue / scalar); } +} - //*********************************************************************** - TEST(Matrix3x3Tests, Transpose) { - for (int i = 0; i < 50; ++i) { - float randomValue = testUtility.GetRandomFloat(); - Matrix3x3 matrix1; - matrix1(0, 1) = randomValue; - matrix1(1, 2) = randomValue; - matrix1(2, 0) = randomValue; - Matrix3x3 result = matrix1.Transpose(); - EXPECT_EQ(result(1, 0), randomValue); - EXPECT_EQ(result(2, 1), randomValue); - EXPECT_EQ(result(0, 2), randomValue); - } +//*********************************************************************** +TEST(Matrix3x3Tests, Transpose) { + for (int i = 0; i < 50; ++i) { + float randomValue = testUtility.GetRandomFloat(); + Matrix3x3 matrix1; + matrix1(0, 1) = randomValue; + matrix1(1, 2) = randomValue; + matrix1(2, 0) = randomValue; + Matrix3x3 result = matrix1.Transpose(); + EXPECT_EQ(result(1, 0), randomValue); + EXPECT_EQ(result(2, 1), randomValue); + EXPECT_EQ(result(0, 2), randomValue); } +} - //*********************************************************************** - TEST(Matrix3x3Tests, Inverse) { - for (int i = 0; i < 50; ++i) { - - Matrix3x3 matrix; - //DirectX::XMMATRIX dxMatrix; +//*********************************************************************** +TEST(Matrix3x3Tests, Inverse) { + for (int i = 0; i < 50; ++i) { + Matrix3x3 matrix; + // DirectX::XMMATRIX dxMatrix; - // Assign random values to the matrixes - { - for (int r = 0; r < 3; ++r) { - for (int c = 0; c < 3; ++c) { - const float randomValue = testUtility.GetRandomFloat(-100.0f, 100.0f); + // Assign random values to the matrixes + { + for (int r = 0; r < 3; ++r) { + for (int c = 0; c < 3; ++c) { + const float randomValue = testUtility.GetRandomFloat(-100.0f, 100.0f); - matrix(r, c) = randomValue; - //dxMatrix.r[r].m128_f32[c] = randomValue; - } + matrix(r, c) = randomValue; + // dxMatrix.r[r].m128_f32[c] = randomValue; } } + } - Matrix3x3 result = matrix.Inverse(); - DirectX::XMMATRIX dxResult = DirectX::XMMatrixInverse(nullptr, matrix); + Matrix3x3 result = matrix.Inverse(); + DirectX::XMMATRIX dxResult = DirectX::XMMatrixInverse(nullptr, matrix); - // Test values - { - for (int r = 0; r < 3; ++r) { - for (int c = 0; c < 3; ++c) { - const float matrixFloatValue = result(r, c); - const float dxFloatValue = dxResult.r[r].m128_f32[c]; + // Test values + { + for (int r = 0; r < 3; ++r) { + for (int c = 0; c < 3; ++c) { + const float matrixFloatValue = result(r, c); + const float dxFloatValue = dxResult.r[r].m128_f32[c]; - EXPECT_NEAR(matrixFloatValue, dxFloatValue, gFloatMargin); - } + EXPECT_NEAR(matrixFloatValue, dxFloatValue, gFloatMargin); } } } } +} - //*********************************************************************** - TEST(Matrix3x3Tests, CreateRotationAroundX) { - for (int i = 0; i < 50; ++i) { - float randomValue = testUtility.GetRandomFloat(-3.14f, 3.14f); - Matrix3x3 result = Matrix3x3::CreateRotationAroundX(randomValue); - XMMATRIX dxResult = XMMatrixRotationX(randomValue); - EXPECT_EQ(result, dxResult); - } +//*********************************************************************** +TEST(Matrix3x3Tests, CreateRotationAroundX) { + for (int i = 0; i < 50; ++i) { + float randomValue = testUtility.GetRandomFloat(-3.14f, 3.14f); + Matrix3x3 result = Matrix3x3::CreateRotationAroundX(randomValue); + XMMATRIX dxResult = XMMatrixRotationX(randomValue); + EXPECT_EQ(result, dxResult); } +} - //*********************************************************************** - TEST(Matrix3x3Tests, CreateRotationAroundY) { - for (int i = 0; i < 50; ++i) { - float randomValue = testUtility.GetRandomFloat(-3.14f, 3.14f); - Matrix3x3 result = Matrix3x3::CreateRotationAroundY(randomValue); - XMMATRIX dxResult = XMMatrixRotationY(randomValue); - EXPECT_EQ(result, dxResult); - } +//*********************************************************************** +TEST(Matrix3x3Tests, CreateRotationAroundY) { + for (int i = 0; i < 50; ++i) { + float randomValue = testUtility.GetRandomFloat(-3.14f, 3.14f); + Matrix3x3 result = Matrix3x3::CreateRotationAroundY(randomValue); + XMMATRIX dxResult = XMMatrixRotationY(randomValue); + EXPECT_EQ(result, dxResult); } +} - //*********************************************************************** - TEST(Matrix3x3Tests, CreateRotationAroundZ) { - for (int i = 0; i < 50; ++i) { - float randomValue = testUtility.GetRandomFloat(-3.14f, 3.14f); - Matrix3x3 result = Matrix3x3::CreateRotationAroundZ(randomValue); - XMMATRIX dxResult = XMMatrixRotationZ(randomValue); - EXPECT_EQ(result, dxResult); - } +//*********************************************************************** +TEST(Matrix3x3Tests, CreateRotationAroundZ) { + for (int i = 0; i < 50; ++i) { + float randomValue = testUtility.GetRandomFloat(-3.14f, 3.14f); + Matrix3x3 result = Matrix3x3::CreateRotationAroundZ(randomValue); + XMMATRIX dxResult = XMMatrixRotationZ(randomValue); + EXPECT_EQ(result, dxResult); } +} - //*********************************************************************** - TEST(Matrix3x3Tests, DivideByZero) { - float randomValue = testUtility.GetRandomFloat(1.0f, 10000.0f); - Matrix3x3 matrix1; - matrix1(0, 0) = randomValue; - matrix1(1, 1) = randomValue; - matrix1(2, 2) = randomValue; +//*********************************************************************** +TEST(Matrix3x3Tests, DivideByZero) { + float randomValue = testUtility.GetRandomFloat(1.0f, 10000.0f); + Matrix3x3 matrix1; + matrix1(0, 0) = randomValue; + matrix1(1, 1) = randomValue; + matrix1(2, 2) = randomValue; - EXPECT_DEATH({auto result = matrix1 / 0.0f;}, "Attempting to divide by zero"); + EXPECT_DEATH({ auto result = matrix1 / 0.0f; }, "Attempting to divide by zero"); - EXPECT_DEATH({ matrix1 /= 0.0f; }, "Attempting to divide by zero"); - } - //*********************************************************************** - TEST(Matrix3x3Tests, ParenthesisOperatorOutOfBounds) { - Matrix3x3 matrix; + EXPECT_DEATH({ matrix1 /= 0.0f; }, "Attempting to divide by zero"); +} - EXPECT_DEATH({ matrix(4,0) = 1.0f; }, "Matrix3x3: Index out of bounds"); - EXPECT_DEATH({ matrix(0,4) = 1.0f; }, "Matrix3x3: Index out of bounds"); - } +//*********************************************************************** +TEST(Matrix3x3Tests, ParenthesisOperatorOutOfBounds) { + Matrix3x3 matrix; + + EXPECT_DEATH({ matrix(4, 0) = 1.0f; }, "Matrix3x3: Index out of bounds"); + EXPECT_DEATH({ matrix(0, 4) = 1.0f; }, "Matrix3x3: Index out of bounds"); } +} // namespace RFMath + // namespace RFMath \ No newline at end of file diff --git a/Source/CoreTests/Utility/TestUtility.h b/Source/CoreTests/Utility/TestUtility.h index 6fc9652..9cf0198 100644 --- a/Source/CoreTests/Utility/TestUtility.h +++ b/Source/CoreTests/Utility/TestUtility.h @@ -2,16 +2,17 @@ #include namespace { - constexpr float gFloatMargin = 0.00001f; +constexpr float gFloatMargin = 0.00001f; } class TestUtility { -public: + public: TestUtility(); float GetRandomFloat(float aMin = -10000.0f, float aMax = 10000.0f); double GetRandomDouble(double aMin = -10000.0, double aMax = 10000.0); int GetRandomInt(int aMin = -10000, int aMax = 10000); -private: + + private: std::mt19937 mRandomEngine; }; \ No newline at end of file diff --git a/Source/CoreTests/Vector2Tests.cpp b/Source/CoreTests/Vector2Tests.cpp index 9ab2836..bf06c81 100644 --- a/Source/CoreTests/Vector2Tests.cpp +++ b/Source/CoreTests/Vector2Tests.cpp @@ -1,214 +1,216 @@ #include -#include "Math/Vector2.h" +#include "Math/Vector2.h" namespace RFMath { - - // ---------------- Vector2 (float) ---------------- // +// ---------------- Vector2 (float) ---------------- // #pragma region Vector2Tests - TEST(Vector2Tests, ConstructorAndEquality) { - // Default constructor - Vector2 v0; - EXPECT_FLOAT_EQ(v0.x, 0.0f); - EXPECT_FLOAT_EQ(v0.y, 0.0f); - - // Parameterized constructor - Vector2 v1(1.0f, 2.0f); - EXPECT_FLOAT_EQ(v1.x, 1.0f); - EXPECT_FLOAT_EQ(v1.y, 2.0f); - - // XMFLOAT2 constructor - DirectX::XMFLOAT2 xf{ 3.0f, 4.0f }; - Vector2 v2(xf); - EXPECT_FLOAT_EQ(v2.x, 3.0f); - EXPECT_FLOAT_EQ(v2.y, 4.0f); - - // Array constructor (if implemented) - float arr[2] = { 5.0f, 6.0f }; - Vector2 v3(arr); - EXPECT_FLOAT_EQ(v3.x, arr[0]); - EXPECT_FLOAT_EQ(v3.y, arr[1]); - - // Zero constant - Vector2 vZero = Vector2::Zero; - EXPECT_FLOAT_EQ(vZero.x, 0.0f); - EXPECT_FLOAT_EQ(vZero.y, 0.0f); - } - - TEST(Vector2Tests, LengthAndLengthSquared) { - Vector2 v(3.0f, 4.0f); - EXPECT_FLOAT_EQ(v.LengthSquared(), 25.0f); - EXPECT_FLOAT_EQ(v.Length(), 5.0f); - } - - TEST(Vector2Tests, DotProduct) { - Vector2 a(1.0f, 2.0f); - Vector2 b(3.0f, 4.0f); - EXPECT_FLOAT_EQ(a.Dot(b), 11.0f); // 1*3 + 2*4 - } - - TEST(Vector2Tests, Normalize) { - Vector2 v(3.0f, 4.0f); - Vector2 n = v.Normalized(); - EXPECT_NEAR(n.Length(), 1.0f, vecEpsilon); - EXPECT_NEAR(n.x, 0.6f, vecEpsilon); - EXPECT_NEAR(n.y, 0.8f, vecEpsilon); - } - - TEST(Vector2Tests, Reflect) { - Vector2 v(1, -1); - Vector2 n(0, 1); // unit Y - Vector2 r = v.Reflect(n); - EXPECT_FLOAT_EQ(r.x, 1); - EXPECT_FLOAT_EQ(r.y, 1); - - Vector2 noDiscardCache = Vector2::Zero; // just to avoid warning from [[nodiscard]] - Vector2 badNormal(0, 1.5f); // not normalized - Vector2 badNormal2(0, 0.9f); // not normalized - - // Expect assert/death - EXPECT_DEATH({ noDiscardCache = v.Reflect(badNormal); }, "Vector3::Reflect received non-normalized normal"); - EXPECT_DEATH({ noDiscardCache = v.Reflect(badNormal2); }, "Vector3::Reflect received non-normalized normal"); - } - - TEST(Vector2Tests, OperatorsArithmetic) { - Vector2 a(2, 3); - Vector2 b(1, -1); - - EXPECT_EQ(a + b, Vector2(3, 2)); - EXPECT_EQ(a - b, Vector2(1, 4)); - - EXPECT_EQ(a * 2.0f, Vector2(4, 6)); - EXPECT_EQ(2.0f * a, Vector2(4, 6)); - EXPECT_EQ(a / 2.0f, Vector2(1, 1.5f)); - - EXPECT_DEATH({ a / 0.0f; }, "Division by zero"); - } - - TEST(Vector2Tests, OperatorsCompoundAssignment) { - Vector2 a(2, 3); - Vector2 b(1, -1); - - a += b; - EXPECT_EQ(a, Vector2(3, 2)); - - a -= Vector2(2, 2); - EXPECT_EQ(a, Vector2(1, 0)); - - a *= 3.0f; - EXPECT_EQ(a, Vector2(3, 0)); - - a /= 3.0f; - EXPECT_EQ(a, Vector2(1, 0)); - - EXPECT_DEATH({ a /= 0.0f; }, "Division by zero"); - } - - TEST(Vector2Tests, ToXMVECTOR) { - Vector2 v(1.5f, -2.5f); - DirectX::XMVECTOR vec = v.ToXMVECTOR(1.0f); - - DirectX::XMFLOAT4 unpack; - DirectX::XMStoreFloat4(&unpack, vec); - EXPECT_FLOAT_EQ(unpack.x, 1.5f); - EXPECT_FLOAT_EQ(unpack.y, -2.5f); - EXPECT_FLOAT_EQ(unpack.z, 0.0f); - EXPECT_FLOAT_EQ(unpack.w, 1.0f); - } +TEST(Vector2Tests, ConstructorAndEquality) { + // Default constructor + Vector2 v0; + EXPECT_FLOAT_EQ(v0.x, 0.0f); + EXPECT_FLOAT_EQ(v0.y, 0.0f); + + // Parameterized constructor + Vector2 v1(1.0f, 2.0f); + EXPECT_FLOAT_EQ(v1.x, 1.0f); + EXPECT_FLOAT_EQ(v1.y, 2.0f); + + // XMFLOAT2 constructor + DirectX::XMFLOAT2 xf{3.0f, 4.0f}; + Vector2 v2(xf); + EXPECT_FLOAT_EQ(v2.x, 3.0f); + EXPECT_FLOAT_EQ(v2.y, 4.0f); + + // Array constructor (if implemented) + float arr[2] = {5.0f, 6.0f}; + Vector2 v3(arr); + EXPECT_FLOAT_EQ(v3.x, arr[0]); + EXPECT_FLOAT_EQ(v3.y, arr[1]); + + // Zero constant + Vector2 vZero = Vector2::Zero; + EXPECT_FLOAT_EQ(vZero.x, 0.0f); + EXPECT_FLOAT_EQ(vZero.y, 0.0f); +} + +TEST(Vector2Tests, LengthAndLengthSquared) { + Vector2 v(3.0f, 4.0f); + EXPECT_FLOAT_EQ(v.LengthSquared(), 25.0f); + EXPECT_FLOAT_EQ(v.Length(), 5.0f); +} + +TEST(Vector2Tests, DotProduct) { + Vector2 a(1.0f, 2.0f); + Vector2 b(3.0f, 4.0f); + EXPECT_FLOAT_EQ(a.Dot(b), 11.0f); // 1*3 + 2*4 +} + +TEST(Vector2Tests, Normalize) { + Vector2 v(3.0f, 4.0f); + Vector2 n = v.Normalized(); + EXPECT_NEAR(n.Length(), 1.0f, vecEpsilon); + EXPECT_NEAR(n.x, 0.6f, vecEpsilon); + EXPECT_NEAR(n.y, 0.8f, vecEpsilon); +} + +TEST(Vector2Tests, Reflect) { + Vector2 v(1, -1); + Vector2 n(0, 1); // unit Y + Vector2 r = v.Reflect(n); + EXPECT_FLOAT_EQ(r.x, 1); + EXPECT_FLOAT_EQ(r.y, 1); + + Vector2 noDiscardCache = Vector2::Zero; // just to avoid warning from [[nodiscard]] + Vector2 badNormal(0, 1.5f); // not normalized + Vector2 badNormal2(0, 0.9f); // not normalized + + // Expect assert/death + EXPECT_DEATH({ noDiscardCache = v.Reflect(badNormal); }, "Vector3::Reflect received non-normalized normal"); + EXPECT_DEATH({ noDiscardCache = v.Reflect(badNormal2); }, "Vector3::Reflect received non-normalized normal"); +} + +TEST(Vector2Tests, OperatorsArithmetic) { + Vector2 a(2, 3); + Vector2 b(1, -1); + + EXPECT_EQ(a + b, Vector2(3, 2)); + EXPECT_EQ(a - b, Vector2(1, 4)); + + EXPECT_EQ(a * 2.0f, Vector2(4, 6)); + EXPECT_EQ(2.0f * a, Vector2(4, 6)); + EXPECT_EQ(a / 2.0f, Vector2(1, 1.5f)); + + EXPECT_DEATH({ a / 0.0f; }, "Division by zero"); +} + +TEST(Vector2Tests, OperatorsCompoundAssignment) { + Vector2 a(2, 3); + Vector2 b(1, -1); + + a += b; + EXPECT_EQ(a, Vector2(3, 2)); + + a -= Vector2(2, 2); + EXPECT_EQ(a, Vector2(1, 0)); + + a *= 3.0f; + EXPECT_EQ(a, Vector2(3, 0)); + + a /= 3.0f; + EXPECT_EQ(a, Vector2(1, 0)); + + EXPECT_DEATH({ a /= 0.0f; }, "Division by zero"); +} + +TEST(Vector2Tests, ToXMVECTOR) { + Vector2 v(1.5f, -2.5f); + DirectX::XMVECTOR vec = v.ToXMVECTOR(1.0f); + + DirectX::XMFLOAT4 unpack; + DirectX::XMStoreFloat4(&unpack, vec); + EXPECT_FLOAT_EQ(unpack.x, 1.5f); + EXPECT_FLOAT_EQ(unpack.y, -2.5f); + EXPECT_FLOAT_EQ(unpack.z, 0.0f); + EXPECT_FLOAT_EQ(unpack.w, 1.0f); +} + #pragma endregion - // ---------------- Vector2i (int) ---------------- // +// ---------------- Vector2i (int) ---------------- // #pragma region Vector2iTests - TEST(Vector2iTests, ConstructorAndEquality) { - // Default constructor - Vector2i v0; - EXPECT_EQ(v0.x, 0); - EXPECT_EQ(v0.y, 0); - - // Parameterized constructor - Vector2i v1(1, 2); - EXPECT_EQ(v1.x, 1); - EXPECT_EQ(v1.y, 2); - - // Array constructor - int arr[2] = { 3, 4 }; - Vector2i v2(arr); - EXPECT_EQ(v2.x, 3); - EXPECT_EQ(v2.y, 4); - - // Zero constant - Vector2i vZero = Vector2i::Zero; - EXPECT_EQ(vZero.x, 0); - EXPECT_EQ(vZero.y, 0); - } - - TEST(Vector2iTests, DotProduct) { - Vector2i a(2, 3); - Vector2i b(4, -1); - EXPECT_EQ(a.Dot(b), 5); // 2*4 + 3*(-1) - } - - TEST(Vector2iTests, OperatorsArithmetic) { - Vector2i a(2, 3); - Vector2i b(1, -1); - - EXPECT_EQ(a + b, Vector2i(3, 2)); - EXPECT_EQ(a - b, Vector2i(1, 4)); - - EXPECT_EQ(a * 2, Vector2i(4, 6)); - EXPECT_EQ(2 * a, Vector2i(4, 6)); - EXPECT_EQ(a / 2, Vector2i(1, 1)); - } - - TEST(Vector2iTests, OperatorsCompoundAssignment) { - Vector2i a(2, 3); - Vector2i b(1, -1); - - a += b; - EXPECT_EQ(a, Vector2i(3, 2)); - - a -= Vector2i(2, 2); - EXPECT_EQ(a, Vector2i(1, 0)); - - a *= 3; - EXPECT_EQ(a, Vector2i(3, 0)); - - a /= 3; - EXPECT_EQ(a, Vector2i(1, 0)); - - EXPECT_DEATH({ a / 0; }, "Division by zero"); - } - TEST(Vector2iTests, ToXMVECTOR) { - Vector2i v(3, -4); - DirectX::XMVECTOR vec = v.ToXMVECTOR(0.0f); - - DirectX::XMFLOAT4 unpack; - DirectX::XMStoreFloat4(&unpack, vec); - EXPECT_FLOAT_EQ(unpack.x, 3.0f); - EXPECT_FLOAT_EQ(unpack.y, -4.0f); - EXPECT_FLOAT_EQ(unpack.z, 0.0f); - EXPECT_FLOAT_EQ(unpack.w, 0.0f); - - EXPECT_DEATH({ v /= 0; }, "Division by zero"); - } - - TEST(Vector2iTests, ConversionToXMINT2) { - Vector2i v(7, -8); - DirectX::XMINT2 dx = static_cast(v); - EXPECT_EQ(dx.x, 7); - EXPECT_EQ(dx.y, -8); - } - - TEST(Vector2iTests, AssignFromXMINT2) { - DirectX::XMINT2 dx(9, -10); - Vector2i v; - v = dx; - EXPECT_EQ(v.x, 9); - EXPECT_EQ(v.y, -10); - } +TEST(Vector2iTests, ConstructorAndEquality) { + // Default constructor + Vector2i v0; + EXPECT_EQ(v0.x, 0); + EXPECT_EQ(v0.y, 0); + + // Parameterized constructor + Vector2i v1(1, 2); + EXPECT_EQ(v1.x, 1); + EXPECT_EQ(v1.y, 2); + + // Array constructor + int arr[2] = {3, 4}; + Vector2i v2(arr); + EXPECT_EQ(v2.x, 3); + EXPECT_EQ(v2.y, 4); + + // Zero constant + Vector2i vZero = Vector2i::Zero; + EXPECT_EQ(vZero.x, 0); + EXPECT_EQ(vZero.y, 0); +} + +TEST(Vector2iTests, DotProduct) { + Vector2i a(2, 3); + Vector2i b(4, -1); + EXPECT_EQ(a.Dot(b), 5); // 2*4 + 3*(-1) +} + +TEST(Vector2iTests, OperatorsArithmetic) { + Vector2i a(2, 3); + Vector2i b(1, -1); + + EXPECT_EQ(a + b, Vector2i(3, 2)); + EXPECT_EQ(a - b, Vector2i(1, 4)); + + EXPECT_EQ(a * 2, Vector2i(4, 6)); + EXPECT_EQ(2 * a, Vector2i(4, 6)); + EXPECT_EQ(a / 2, Vector2i(1, 1)); +} + +TEST(Vector2iTests, OperatorsCompoundAssignment) { + Vector2i a(2, 3); + Vector2i b(1, -1); + + a += b; + EXPECT_EQ(a, Vector2i(3, 2)); + + a -= Vector2i(2, 2); + EXPECT_EQ(a, Vector2i(1, 0)); + + a *= 3; + EXPECT_EQ(a, Vector2i(3, 0)); + + a /= 3; + EXPECT_EQ(a, Vector2i(1, 0)); + + EXPECT_DEATH({ a / 0; }, "Division by zero"); +} + +TEST(Vector2iTests, ToXMVECTOR) { + Vector2i v(3, -4); + DirectX::XMVECTOR vec = v.ToXMVECTOR(0.0f); + + DirectX::XMFLOAT4 unpack; + DirectX::XMStoreFloat4(&unpack, vec); + EXPECT_FLOAT_EQ(unpack.x, 3.0f); + EXPECT_FLOAT_EQ(unpack.y, -4.0f); + EXPECT_FLOAT_EQ(unpack.z, 0.0f); + EXPECT_FLOAT_EQ(unpack.w, 0.0f); + + EXPECT_DEATH({ v /= 0; }, "Division by zero"); +} + +TEST(Vector2iTests, ConversionToXMINT2) { + Vector2i v(7, -8); + DirectX::XMINT2 dx = static_cast(v); + EXPECT_EQ(dx.x, 7); + EXPECT_EQ(dx.y, -8); +} + +TEST(Vector2iTests, AssignFromXMINT2) { + DirectX::XMINT2 dx(9, -10); + Vector2i v; + v = dx; + EXPECT_EQ(v.x, 9); + EXPECT_EQ(v.y, -10); +} + #pragma endregion -} \ No newline at end of file +} // namespace RFMath \ No newline at end of file diff --git a/Source/CoreTests/Vector3Tests.cpp b/Source/CoreTests/Vector3Tests.cpp index 6c654c9..168a343 100644 --- a/Source/CoreTests/Vector3Tests.cpp +++ b/Source/CoreTests/Vector3Tests.cpp @@ -1,307 +1,308 @@ #include -#include "Math/Vector3.h" + #include "Math/Math.h" +#include "Math/Vector3.h" namespace RFMath { - // ---------------- Vector3 (float) ---------------- // +// ---------------- Vector3 (float) ---------------- // #pragma region Vector3Tests - TEST(Vector3Tests, ConstructorAndEquality) { - // Default constructor - Vector3 v0; - EXPECT_FLOAT_EQ(v0.x, 0.0f); - EXPECT_FLOAT_EQ(v0.y, 0.0f); - EXPECT_FLOAT_EQ(v0.z, 0.0f); - - // Parameterized constructor - Vector3 v1(1.0f, 2.0f, 3.0f); - EXPECT_FLOAT_EQ(v1.x, 1.0f); - EXPECT_FLOAT_EQ(v1.y, 2.0f); - EXPECT_FLOAT_EQ(v1.z, 3.0f); - - // XMFLOAT3 constructor - DirectX::XMFLOAT3 xf{ 4.0f, 5.0f, 6.0f }; - Vector3 v2(xf); - EXPECT_FLOAT_EQ(v2.x, 4.0f); - EXPECT_FLOAT_EQ(v2.y, 5.0f); - EXPECT_FLOAT_EQ(v2.z, 6.0f); - - // Array constructor - float arr[3] = { 7.0f, 8.0f, 9.0f }; - Vector3 v3(arr); - EXPECT_FLOAT_EQ(v3.x, arr[0]); - EXPECT_FLOAT_EQ(v3.y, arr[1]); - EXPECT_FLOAT_EQ(v3.z, arr[2]); - - // Zero constant - Vector3 vZero = Vector3::Zero; - EXPECT_FLOAT_EQ(vZero.x, 0.0f); - EXPECT_FLOAT_EQ(vZero.y, 0.0f); - EXPECT_FLOAT_EQ(vZero.z, 0.0f); - } - - TEST(Vector3Tests, ToXMVECTORConversion) { - Vector3 v(1.0f, 2.0f, 3.0f); - DirectX::XMVECTOR vec = v.ToXMVECTOR(1.0f); // w = 1.0f (position) - - DirectX::XMFLOAT4 result; - DirectX::XMStoreFloat4(&result, vec); - - EXPECT_FLOAT_EQ(result.x, 1.0f); - EXPECT_FLOAT_EQ(result.y, 2.0f); - EXPECT_FLOAT_EQ(result.z, 3.0f); - EXPECT_FLOAT_EQ(result.w, 1.0f); - } - - TEST(Vector3Tests, ArithmeticOperators) { - Vector3 a(1, 2, 3); - Vector3 b(4, 5, 6); - - // Addition & Subtraction - Vector3 c = a + b; - EXPECT_EQ(c, Vector3(5, 7, 9)); - Vector3 d = c - a; - EXPECT_EQ(d, b); - - // Scalar Multiplication - Vector3 scaled = a * 2.0f; - EXPECT_EQ(scaled, Vector3(2, 4, 6)); - Vector3 scaled2 = 2.0f * a; - EXPECT_EQ(scaled2, Vector3(2, 4, 6)); - - // Scalar Division - Vector3 divided = scaled / 2.0f; - EXPECT_EQ(divided, a); - - EXPECT_DEATH({ a /= 0.0f; }, "Division by zero in Vector3::operator/="); - } - - TEST(Vector3Tests, OperatorsCompoundAssignment) { - Vector3 a(2, 3, 4); - Vector3 b(1, -1, 2); - - a += b; - EXPECT_EQ(a, Vector3(3, 2, 6)); - - a -= Vector3(1, 1, 1); - EXPECT_EQ(a, Vector3(2, 1, 5)); - - a *= 2.0f; - EXPECT_EQ(a, Vector3(4, 2, 10)); - - a /= 2.0f; - EXPECT_EQ(a, Vector3(2, 1, 5)); - - EXPECT_DEATH({ a / 0.0f; }, "Division by zero in Vector3::operator/"); - } - - TEST(Vector3Tests, LengthAndLengthSquared) { - Vector3 v(3.0f, 4.0f, 12.0f); - - float lenSq = v.LengthSquared(); - EXPECT_FLOAT_EQ(lenSq, 3 * 3 + 4 * 4 + 12 * 12); // 169 - - float len = v.Length(); - EXPECT_FLOAT_EQ(len, 13.0f); - } - - TEST(Vector3Tests, DotProduct) { - Vector3 a(1, 2, 3); - Vector3 b(4, -5, 6); - float dot = a.Dot(b); - EXPECT_FLOAT_EQ(dot, 1 * 4 + 2 * (-5) + 3 * 6); // 12 - } - - TEST(Vector3Tests, CrossProduct) { - Vector3 a(1, 0, 0); - Vector3 b(0, 1, 0); - Vector3 c = a.Cross(b); - EXPECT_FLOAT_EQ(c.x, 0); - EXPECT_FLOAT_EQ(c.y, 0); - EXPECT_FLOAT_EQ(c.z, 1); - } - - TEST(Vector3Tests, Normalization) { - Vector3 v(3, 0, 4); - Vector3 n = v.Normalized(); - EXPECT_NEAR(n.Length(), 1.0f, vecEpsilon); - } - - TEST(Vector3Tests, Reflection) { - Vector3 v(1, -1, 0); - Vector3 normal = Vector3::UnitY; // (0,1,0) - Vector3 r = v.Reflect(normal); - EXPECT_FLOAT_EQ(r.x, 1); - EXPECT_FLOAT_EQ(r.y, 1); - EXPECT_FLOAT_EQ(r.z, 0); - - Vector3 noDiscardCache = Vector3::Zero; // just to avoid warning from [[nodiscard]] - Vector3 badNormal(0, 1.5f, 0); // not normalized - Vector3 badNormal2(0, 0.9f, 0); // not normalized - - // Expect assert/death - EXPECT_DEATH({ noDiscardCache = v.Reflect(badNormal); }, "Vector3::Reflect received non-normalized normal"); - EXPECT_DEATH({ noDiscardCache = v.Reflect(badNormal2); }, "Vector3::Reflect received non-normalized normal"); - } - - TEST(Vector3Tests, Rotations) { - Vector3 v(1, 0, 0); - - auto yaw90 = v.RotateYaw(math::HALF_PI); // +90 yaw - EXPECT_NEAR(yaw90.x, 0, vecEpsilon); - EXPECT_NEAR(yaw90.z, -1, vecEpsilon); - - auto pitch90 = v.RotatePitch(math::HALF_PI); // +90 pitch - EXPECT_NEAR(pitch90.y, 0, vecEpsilon); // stays 0 - EXPECT_NEAR(pitch90.z, 0, vecEpsilon); // stays 0 - } - - TEST(Vector3Tests, SubVectorAccessors) { - Vector3 v(1.0f, 2.0f, 3.0f); - - Vector2 xy = v.xy(); - EXPECT_FLOAT_EQ(xy.x, 1.0f); - EXPECT_FLOAT_EQ(xy.y, 2.0f); - - Vector2 xz = v.xz(); - EXPECT_FLOAT_EQ(xz.x, 1.0f); - EXPECT_FLOAT_EQ(xz.y, 3.0f); - - Vector2 yz = v.yz(); - EXPECT_FLOAT_EQ(yz.x, 2.0f); - EXPECT_FLOAT_EQ(yz.y, 3.0f); - } +TEST(Vector3Tests, ConstructorAndEquality) { + // Default constructor + Vector3 v0; + EXPECT_FLOAT_EQ(v0.x, 0.0f); + EXPECT_FLOAT_EQ(v0.y, 0.0f); + EXPECT_FLOAT_EQ(v0.z, 0.0f); + + // Parameterized constructor + Vector3 v1(1.0f, 2.0f, 3.0f); + EXPECT_FLOAT_EQ(v1.x, 1.0f); + EXPECT_FLOAT_EQ(v1.y, 2.0f); + EXPECT_FLOAT_EQ(v1.z, 3.0f); + + // XMFLOAT3 constructor + DirectX::XMFLOAT3 xf{4.0f, 5.0f, 6.0f}; + Vector3 v2(xf); + EXPECT_FLOAT_EQ(v2.x, 4.0f); + EXPECT_FLOAT_EQ(v2.y, 5.0f); + EXPECT_FLOAT_EQ(v2.z, 6.0f); + + // Array constructor + float arr[3] = {7.0f, 8.0f, 9.0f}; + Vector3 v3(arr); + EXPECT_FLOAT_EQ(v3.x, arr[0]); + EXPECT_FLOAT_EQ(v3.y, arr[1]); + EXPECT_FLOAT_EQ(v3.z, arr[2]); + + // Zero constant + Vector3 vZero = Vector3::Zero; + EXPECT_FLOAT_EQ(vZero.x, 0.0f); + EXPECT_FLOAT_EQ(vZero.y, 0.0f); + EXPECT_FLOAT_EQ(vZero.z, 0.0f); +} + +TEST(Vector3Tests, ToXMVECTORConversion) { + Vector3 v(1.0f, 2.0f, 3.0f); + DirectX::XMVECTOR vec = v.ToXMVECTOR(1.0f); // w = 1.0f (position) + + DirectX::XMFLOAT4 result; + DirectX::XMStoreFloat4(&result, vec); + + EXPECT_FLOAT_EQ(result.x, 1.0f); + EXPECT_FLOAT_EQ(result.y, 2.0f); + EXPECT_FLOAT_EQ(result.z, 3.0f); + EXPECT_FLOAT_EQ(result.w, 1.0f); +} + +TEST(Vector3Tests, ArithmeticOperators) { + Vector3 a(1, 2, 3); + Vector3 b(4, 5, 6); + + // Addition & Subtraction + Vector3 c = a + b; + EXPECT_EQ(c, Vector3(5, 7, 9)); + Vector3 d = c - a; + EXPECT_EQ(d, b); + + // Scalar Multiplication + Vector3 scaled = a * 2.0f; + EXPECT_EQ(scaled, Vector3(2, 4, 6)); + Vector3 scaled2 = 2.0f * a; + EXPECT_EQ(scaled2, Vector3(2, 4, 6)); + + // Scalar Division + Vector3 divided = scaled / 2.0f; + EXPECT_EQ(divided, a); + + EXPECT_DEATH({ a /= 0.0f; }, "Division by zero in Vector3::operator/="); +} + +TEST(Vector3Tests, OperatorsCompoundAssignment) { + Vector3 a(2, 3, 4); + Vector3 b(1, -1, 2); + + a += b; + EXPECT_EQ(a, Vector3(3, 2, 6)); + + a -= Vector3(1, 1, 1); + EXPECT_EQ(a, Vector3(2, 1, 5)); + + a *= 2.0f; + EXPECT_EQ(a, Vector3(4, 2, 10)); + + a /= 2.0f; + EXPECT_EQ(a, Vector3(2, 1, 5)); + + EXPECT_DEATH({ a / 0.0f; }, "Division by zero in Vector3::operator/"); +} + +TEST(Vector3Tests, LengthAndLengthSquared) { + Vector3 v(3.0f, 4.0f, 12.0f); + + float lenSq = v.LengthSquared(); + EXPECT_FLOAT_EQ(lenSq, 3 * 3 + 4 * 4 + 12 * 12); // 169 + + float len = v.Length(); + EXPECT_FLOAT_EQ(len, 13.0f); +} + +TEST(Vector3Tests, DotProduct) { + Vector3 a(1, 2, 3); + Vector3 b(4, -5, 6); + float dot = a.Dot(b); + EXPECT_FLOAT_EQ(dot, 1 * 4 + 2 * (-5) + 3 * 6); // 12 +} + +TEST(Vector3Tests, CrossProduct) { + Vector3 a(1, 0, 0); + Vector3 b(0, 1, 0); + Vector3 c = a.Cross(b); + EXPECT_FLOAT_EQ(c.x, 0); + EXPECT_FLOAT_EQ(c.y, 0); + EXPECT_FLOAT_EQ(c.z, 1); +} + +TEST(Vector3Tests, Normalization) { + Vector3 v(3, 0, 4); + Vector3 n = v.Normalized(); + EXPECT_NEAR(n.Length(), 1.0f, vecEpsilon); +} + +TEST(Vector3Tests, Reflection) { + Vector3 v(1, -1, 0); + Vector3 normal = Vector3::UnitY; // (0,1,0) + Vector3 r = v.Reflect(normal); + EXPECT_FLOAT_EQ(r.x, 1); + EXPECT_FLOAT_EQ(r.y, 1); + EXPECT_FLOAT_EQ(r.z, 0); + + Vector3 noDiscardCache = Vector3::Zero; // just to avoid warning from [[nodiscard]] + Vector3 badNormal(0, 1.5f, 0); // not normalized + Vector3 badNormal2(0, 0.9f, 0); // not normalized + + // Expect assert/death + EXPECT_DEATH({ noDiscardCache = v.Reflect(badNormal); }, "Vector3::Reflect received non-normalized normal"); + EXPECT_DEATH({ noDiscardCache = v.Reflect(badNormal2); }, "Vector3::Reflect received non-normalized normal"); +} + +TEST(Vector3Tests, Rotations) { + Vector3 v(1, 0, 0); + + auto yaw90 = v.RotateYaw(math::HALF_PI); // +90 yaw + EXPECT_NEAR(yaw90.x, 0, vecEpsilon); + EXPECT_NEAR(yaw90.z, -1, vecEpsilon); + + auto pitch90 = v.RotatePitch(math::HALF_PI); // +90 pitch + EXPECT_NEAR(pitch90.y, 0, vecEpsilon); // stays 0 + EXPECT_NEAR(pitch90.z, 0, vecEpsilon); // stays 0 +} + +TEST(Vector3Tests, SubVectorAccessors) { + Vector3 v(1.0f, 2.0f, 3.0f); + + Vector2 xy = v.xy(); + EXPECT_FLOAT_EQ(xy.x, 1.0f); + EXPECT_FLOAT_EQ(xy.y, 2.0f); + + Vector2 xz = v.xz(); + EXPECT_FLOAT_EQ(xz.x, 1.0f); + EXPECT_FLOAT_EQ(xz.y, 3.0f); + + Vector2 yz = v.yz(); + EXPECT_FLOAT_EQ(yz.x, 2.0f); + EXPECT_FLOAT_EQ(yz.y, 3.0f); +} #pragma endregion - // ---------------- Vector3i (int) ---------------- // +// ---------------- Vector3i (int) ---------------- // #pragma region Vector3iTests - TEST(Vector3iTests, ConstructorAndEquality) { - // Default constructor - Vector3i v0; - EXPECT_EQ(v0.x, 0); - EXPECT_EQ(v0.y, 0); - EXPECT_EQ(v0.z, 0); - - // Parameterized constructor - Vector3i v1(1, 2, 3); - EXPECT_EQ(v1.x, 1); - EXPECT_EQ(v1.y, 2); - EXPECT_EQ(v1.z, 3); - - // Array constructor - int arr[3] = { 4, 5, 6 }; - Vector3i v2(arr); - EXPECT_EQ(v2.x, 4); - EXPECT_EQ(v2.y, 5); - EXPECT_EQ(v2.z, 6); - - // Zero constant - Vector3i vZero = Vector3i::Zero; - EXPECT_EQ(vZero.x, 0); - EXPECT_EQ(vZero.y, 0); - EXPECT_EQ(vZero.z, 0); - } - - TEST(Vector3iTests, ToXMVECTORConversion) { - Vector3i v(1, 2, 3); - DirectX::XMVECTOR vec = v.ToXMVECTOR(0.0f); // w = 0.0f (direction) - - DirectX::XMFLOAT4 result; - DirectX::XMStoreFloat4(&result, vec); - - EXPECT_FLOAT_EQ(result.x, 1.0f); - EXPECT_FLOAT_EQ(result.y, 2.0f); - EXPECT_FLOAT_EQ(result.z, 3.0f); - EXPECT_FLOAT_EQ(result.w, 0.0f); - } - - TEST(Vector3iTests, ArithmeticOperators) { - Vector3i a(1, 2, 3); - Vector3i b(4, 5, 6); - - // Addition & Subtraction - Vector3i c = a + b; - EXPECT_EQ(c, Vector3i(5, 7, 9)); - Vector3i d = c - a; - EXPECT_EQ(d, b); - - // Scalar Multiplication - Vector3i scaled = a * 2; - EXPECT_EQ(scaled, Vector3i(2, 4, 6)); - Vector3i scaled2 = 2 * a; - EXPECT_EQ(scaled2, Vector3i(2, 4, 6)); - - // Scalar Division - Vector3i divided = scaled / 2; - EXPECT_EQ(divided, a); - - EXPECT_DEATH({ a / 0; }, "Division by zero in Vector3i::operator/"); - } - - TEST(Vector3iTests, OperatorsCompoundAssignment) { - Vector3i a(2, 3, 4); - Vector3i b(1, -1, 2); - - a += b; - EXPECT_EQ(a, Vector3i(3, 2, 6)); - - a -= Vector3i(1, 1, 1); - EXPECT_EQ(a, Vector3i(2, 1, 5)); - - a *= 2; - EXPECT_EQ(a, Vector3i(4, 2, 10)); - - a /= 2; - EXPECT_EQ(a, Vector3i(2, 1, 5)); - - EXPECT_DEATH({ a /= 0; }, "Division by zero in Vector3i::operator/="); - } - - TEST(Vector3iTests, LengthSquared) { - Vector3i v(3, 4, 12); - - int lenSq = v.LengthSquared(); - EXPECT_EQ(lenSq, 3 * 3 + 4 * 4 + 12 * 12); // 169 - } - - TEST(Vector3iTests, Rotate90AroundAxes) { - Vector3i v(1, 2, 3); - - auto r1 = v.Rotate90(Vector3i::RotateAxis::X, 1); - EXPECT_EQ(r1.x, 1); - EXPECT_EQ(r1.y, -3); - EXPECT_EQ(r1.z, 2); - - auto r2 = v.Rotate90(Vector3i::RotateAxis::Y, -1); // negative steps - EXPECT_EQ(r2.x, -3); - EXPECT_EQ(r2.y, 2); - EXPECT_EQ(r2.z, 1); - - auto r3 = v.Rotate90(Vector3i::RotateAxis::Z, 2); - EXPECT_EQ(r3.x, -1); - EXPECT_EQ(r3.y, -2); - EXPECT_EQ(r3.z, 3); - } - - TEST(Vector3iTests, SubVectorAccessors) { - Vector3i v(1, 2, 3); - - Vector2i xy = v.xy(); - EXPECT_EQ(xy.x, 1); - EXPECT_EQ(xy.y, 2); - - Vector2i xz = v.xz(); - EXPECT_EQ(xz.x, 1); - EXPECT_EQ(xz.y, 3); +TEST(Vector3iTests, ConstructorAndEquality) { + // Default constructor + Vector3i v0; + EXPECT_EQ(v0.x, 0); + EXPECT_EQ(v0.y, 0); + EXPECT_EQ(v0.z, 0); + + // Parameterized constructor + Vector3i v1(1, 2, 3); + EXPECT_EQ(v1.x, 1); + EXPECT_EQ(v1.y, 2); + EXPECT_EQ(v1.z, 3); + + // Array constructor + int arr[3] = {4, 5, 6}; + Vector3i v2(arr); + EXPECT_EQ(v2.x, 4); + EXPECT_EQ(v2.y, 5); + EXPECT_EQ(v2.z, 6); + + // Zero constant + Vector3i vZero = Vector3i::Zero; + EXPECT_EQ(vZero.x, 0); + EXPECT_EQ(vZero.y, 0); + EXPECT_EQ(vZero.z, 0); +} + +TEST(Vector3iTests, ToXMVECTORConversion) { + Vector3i v(1, 2, 3); + DirectX::XMVECTOR vec = v.ToXMVECTOR(0.0f); // w = 0.0f (direction) + + DirectX::XMFLOAT4 result; + DirectX::XMStoreFloat4(&result, vec); + + EXPECT_FLOAT_EQ(result.x, 1.0f); + EXPECT_FLOAT_EQ(result.y, 2.0f); + EXPECT_FLOAT_EQ(result.z, 3.0f); + EXPECT_FLOAT_EQ(result.w, 0.0f); +} + +TEST(Vector3iTests, ArithmeticOperators) { + Vector3i a(1, 2, 3); + Vector3i b(4, 5, 6); + + // Addition & Subtraction + Vector3i c = a + b; + EXPECT_EQ(c, Vector3i(5, 7, 9)); + Vector3i d = c - a; + EXPECT_EQ(d, b); + + // Scalar Multiplication + Vector3i scaled = a * 2; + EXPECT_EQ(scaled, Vector3i(2, 4, 6)); + Vector3i scaled2 = 2 * a; + EXPECT_EQ(scaled2, Vector3i(2, 4, 6)); + + // Scalar Division + Vector3i divided = scaled / 2; + EXPECT_EQ(divided, a); + + EXPECT_DEATH({ a / 0; }, "Division by zero in Vector3i::operator/"); +} + +TEST(Vector3iTests, OperatorsCompoundAssignment) { + Vector3i a(2, 3, 4); + Vector3i b(1, -1, 2); + + a += b; + EXPECT_EQ(a, Vector3i(3, 2, 6)); + + a -= Vector3i(1, 1, 1); + EXPECT_EQ(a, Vector3i(2, 1, 5)); + + a *= 2; + EXPECT_EQ(a, Vector3i(4, 2, 10)); + + a /= 2; + EXPECT_EQ(a, Vector3i(2, 1, 5)); + + EXPECT_DEATH({ a /= 0; }, "Division by zero in Vector3i::operator/="); +} + +TEST(Vector3iTests, LengthSquared) { + Vector3i v(3, 4, 12); + + int lenSq = v.LengthSquared(); + EXPECT_EQ(lenSq, 3 * 3 + 4 * 4 + 12 * 12); // 169 +} + +TEST(Vector3iTests, Rotate90AroundAxes) { + Vector3i v(1, 2, 3); + + auto r1 = v.Rotate90(Vector3i::RotateAxis::X, 1); + EXPECT_EQ(r1.x, 1); + EXPECT_EQ(r1.y, -3); + EXPECT_EQ(r1.z, 2); + + auto r2 = v.Rotate90(Vector3i::RotateAxis::Y, -1); // negative steps + EXPECT_EQ(r2.x, -3); + EXPECT_EQ(r2.y, 2); + EXPECT_EQ(r2.z, 1); + + auto r3 = v.Rotate90(Vector3i::RotateAxis::Z, 2); + EXPECT_EQ(r3.x, -1); + EXPECT_EQ(r3.y, -2); + EXPECT_EQ(r3.z, 3); +} + +TEST(Vector3iTests, SubVectorAccessors) { + Vector3i v(1, 2, 3); + + Vector2i xy = v.xy(); + EXPECT_EQ(xy.x, 1); + EXPECT_EQ(xy.y, 2); + + Vector2i xz = v.xz(); + EXPECT_EQ(xz.x, 1); + EXPECT_EQ(xz.y, 3); - Vector2i yz = v.yz(); - EXPECT_EQ(yz.x, 2); - EXPECT_EQ(yz.y, 3); - } + Vector2i yz = v.yz(); + EXPECT_EQ(yz.x, 2); + EXPECT_EQ(yz.y, 3); +} #pragma endregion -} \ No newline at end of file +} // namespace RFMath \ No newline at end of file diff --git a/Source/Editor/pch/stdafx.h b/Source/Editor/pch/stdafx.h index e24d04e..7a9a9ce 100644 --- a/Source/Editor/pch/stdafx.h +++ b/Source/Editor/pch/stdafx.h @@ -1,4 +1,4 @@ #pragma once -#include #include +#include #include diff --git a/Source/Project/main.cpp b/Source/Project/main.cpp index 2c3648c..39c9a09 100644 --- a/Source/Project/main.cpp +++ b/Source/Project/main.cpp @@ -1,14 +1,14 @@ #include "stdafx.h" -#include + #include "Core/Platform/WindowsApplication.h" +#include -_Use_decl_annotations_ -int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hInstancePrev, PSTR cmdline, int cmdshow) { +_Use_decl_annotations_ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hInstancePrev, PSTR cmdline, int cmdshow) { hInstancePrev; cmdline; hInstance; cmdshow; RF::WindowsApplication app; - return app.Run(hInstance, cmdshow); + return app.Run(hInstance, cmdshow); } diff --git a/Source/Project/pch/stdafx.h b/Source/Project/pch/stdafx.h index d8f7784..cbbb10d 100644 --- a/Source/Project/pch/stdafx.h +++ b/Source/Project/pch/stdafx.h @@ -1,9 +1,9 @@ #pragma once -// STL -#include +// STL #include +#include #include -#include // Windows -#include \ No newline at end of file +#include +#include \ No newline at end of file