From 8cdd8b4a258892499e658a59193945041375ba75 Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Thu, 8 Sep 2022 14:18:26 +0800 Subject: [PATCH 1/3] Added Math helper functions & wrappers for Vectors, Matrix and Quaternion. --- SHADE_Engine/SHADE_Engine.vcxproj | 18 +- SHADE_Engine/SHADE_Engine.vcxproj.filters | 16 + SHADE_Engine/src/Math/SHMath.h | 9 + SHADE_Engine/src/Math/SHMathHelpers.cpp | 34 ++ SHADE_Engine/src/Math/SHMathHelpers.h | 100 ++++ SHADE_Engine/src/Math/SHMathHelpers.hpp | 90 ++++ SHADE_Engine/src/Math/SHMatrix.cpp | 601 ++++++++++++++++++++++ SHADE_Engine/src/Math/SHMatrix.h | 144 ++++++ SHADE_Engine/src/Math/SHQuaternion.cpp | 240 +++++++++ SHADE_Engine/src/Math/SHQuaternion.h | 106 ++++ SHADE_Engine/src/Math/Vector/SHVec2.cpp | 460 +++++++++++++++++ SHADE_Engine/src/Math/Vector/SHVec2.h | 122 +++++ SHADE_Engine/src/Math/Vector/SHVec3.cpp | 477 +++++++++++++++++ SHADE_Engine/src/Math/Vector/SHVec3.h | 129 +++++ SHADE_Engine/src/Math/Vector/SHVec4.cpp | 529 +++++++++++++++++++ SHADE_Engine/src/Math/Vector/SHVec4.h | 133 +++++ SHADE_Engine/src/SHpch.h | 4 +- SHADE_Engine/src/Tools/SHUtilities.h | 50 ++ SHADE_Engine/src/Tools/SHUtilities.hpp | 28 + 19 files changed, 3288 insertions(+), 2 deletions(-) create mode 100644 SHADE_Engine/src/Math/SHMath.h create mode 100644 SHADE_Engine/src/Math/SHMathHelpers.cpp create mode 100644 SHADE_Engine/src/Math/SHMathHelpers.h create mode 100644 SHADE_Engine/src/Math/SHMathHelpers.hpp create mode 100644 SHADE_Engine/src/Math/SHMatrix.cpp create mode 100644 SHADE_Engine/src/Math/SHMatrix.h create mode 100644 SHADE_Engine/src/Math/SHQuaternion.cpp create mode 100644 SHADE_Engine/src/Math/SHQuaternion.h create mode 100644 SHADE_Engine/src/Math/Vector/SHVec2.cpp create mode 100644 SHADE_Engine/src/Math/Vector/SHVec2.h create mode 100644 SHADE_Engine/src/Math/Vector/SHVec3.cpp create mode 100644 SHADE_Engine/src/Math/Vector/SHVec3.h create mode 100644 SHADE_Engine/src/Math/Vector/SHVec4.cpp create mode 100644 SHADE_Engine/src/Math/Vector/SHVec4.h create mode 100644 SHADE_Engine/src/Tools/SHUtilities.h create mode 100644 SHADE_Engine/src/Tools/SHUtilities.hpp diff --git a/SHADE_Engine/SHADE_Engine.vcxproj b/SHADE_Engine/SHADE_Engine.vcxproj index dcc0f3c8..c95e9eea 100644 --- a/SHADE_Engine/SHADE_Engine.vcxproj +++ b/SHADE_Engine/SHADE_Engine.vcxproj @@ -116,6 +116,14 @@ + + + + + + + + @@ -123,6 +131,8 @@ + + @@ -132,6 +142,12 @@ + + + + + + Create @@ -163,4 +179,4 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/SHADE_Engine/SHADE_Engine.vcxproj.filters b/SHADE_Engine/SHADE_Engine.vcxproj.filters index 8d62d05b..5e108d20 100644 --- a/SHADE_Engine/SHADE_Engine.vcxproj.filters +++ b/SHADE_Engine/SHADE_Engine.vcxproj.filters @@ -91,6 +91,16 @@ Tools + + + + + + + + + + @@ -127,5 +137,11 @@ Tools + + + + + + \ No newline at end of file diff --git a/SHADE_Engine/src/Math/SHMath.h b/SHADE_Engine/src/Math/SHMath.h new file mode 100644 index 00000000..9763abe2 --- /dev/null +++ b/SHADE_Engine/src/Math/SHMath.h @@ -0,0 +1,9 @@ +#pragma once + +#include "SHMathHelpers.h" + +#include "Vector/SHVec2.h" +#include "Vector/SHVec3.h" +#include "Vector/SHVec4.h" + +#include "SHMatrix.h" \ No newline at end of file diff --git a/SHADE_Engine/src/Math/SHMathHelpers.cpp b/SHADE_Engine/src/Math/SHMathHelpers.cpp new file mode 100644 index 00000000..f3608778 --- /dev/null +++ b/SHADE_Engine/src/Math/SHMathHelpers.cpp @@ -0,0 +1,34 @@ +/**************************************************************************************** + * \file SHMathHelpers.cpp + * \author Diren D Bharwani, diren.dbharwani, 390002520 + * \brief Implementation for various mathematical helper functions. + * + * \copyright Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or + * disclosure of this file or its contents without the prior written consent + * of DigiPen Institute of Technology is prohibited. +****************************************************************************************/ + +#include +#include + +// Primary Header +#include "SHMathHelpers.h" + +namespace SHADE +{ + /*-----------------------------------------------------------------------------------*/ + /* Static Data Member Definitions */ + /*-----------------------------------------------------------------------------------*/ + + std::default_random_engine SHMath::rng; + + /*-----------------------------------------------------------------------------------*/ + /* Static Function Member Definitions */ + /*-----------------------------------------------------------------------------------*/ + + void SHMath::Initialise() + { + const unsigned SEED = static_cast(std::chrono::system_clock::now().time_since_epoch().count()); + rng.seed(SEED); + } +} \ No newline at end of file diff --git a/SHADE_Engine/src/Math/SHMathHelpers.h b/SHADE_Engine/src/Math/SHMathHelpers.h new file mode 100644 index 00000000..9135230e --- /dev/null +++ b/SHADE_Engine/src/Math/SHMathHelpers.h @@ -0,0 +1,100 @@ +/**************************************************************************************** + * \file SHMathHelpers.h + * \author Diren D Bharwani, diren.dbharwani, 390002520 + * \brief Interface for various mathematical helper functions. + * + * \copyright Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or + * disclosure of this file or its contents without the prior written consent + * of DigiPen Institute of Technology is prohibited. +****************************************************************************************/ + +#pragma once + +#include +#include +#include +#include + + +namespace SHADE +{ + /*-----------------------------------------------------------------------------------*/ + /* Concepts */ + /*-----------------------------------------------------------------------------------*/ + + template + concept IsArithmetic = std::is_arithmetic_v; + + template + concept IsIntegral = std::is_integral_v; + + template + concept IsFloatingPoint = std::is_floating_point_v; + + /*-----------------------------------------------------------------------------------*/ + /* Type Definitions */ + /*-----------------------------------------------------------------------------------*/ + + class SHMath + { + public: + /*---------------------------------------------------------------------------------*/ + /* Static Data Members */ + /*---------------------------------------------------------------------------------*/ + + /** Standard Epsilon value for comparing Single-Precision Floating-Point values. */ + static constexpr float EPSILON = 0.001f; + + /** Single-Precision Floating-Point value of infinity */ + static constexpr float INF = std::numeric_limits::infinity(); + + static constexpr float PI = std::numbers::pi_v; + static constexpr float HALF_PI = PI * 0.5f; + static constexpr float TWO_PI = 2.0f * PI; + + /*---------------------------------------------------------------------------------*/ + /* Static Function Members */ + /*---------------------------------------------------------------------------------*/ + + static void Initialise (); + + template + [[nodiscard]] static constexpr T DegreesToRadians (T angleInDeg); + + template + [[nodiscard]] static constexpr T RadiansToDegrees (T angleInRad); + + template + [[nodiscard]] static T Lerp (T a, T b, T alpha); + + template + [[nodiscard]] static T ClampedLerp (T a, T b, T alpha, T alphaMin, T alphaMax); + + template + [[nodiscard]] static T Wrap (T value, T min, T max); + + template + [[nodiscard]] static T GenerateRandomNumber (T lowerBound = 0, T upperBound = 1); + + /** + * @brief Compares two floating-point values for equality within given tolerances. + * @tparam T A floating-point type + * @param lhs A floating-point value. + * @param rhs A floating-point value. + * @param absTolerance The absolute tolerance to compare the values for equality. + * @param relTolerance The relative tolerance for comparing large values for equality. + * @returns True if the values are equal within the specified tolerances. + */ + template + [[nodiscard]] static bool CompareFloat (T lhs, T rhs, T absTolerance = EPSILON, T relTolerance = EPSILON); + + private: + /*---------------------------------------------------------------------------------*/ + /* Static Data Members */ + /*---------------------------------------------------------------------------------*/ + static std::default_random_engine rng; + }; + +} // namespace SHADE + +#include "SHMathHelpers.hpp" \ No newline at end of file diff --git a/SHADE_Engine/src/Math/SHMathHelpers.hpp b/SHADE_Engine/src/Math/SHMathHelpers.hpp new file mode 100644 index 00000000..f0a1de12 --- /dev/null +++ b/SHADE_Engine/src/Math/SHMathHelpers.hpp @@ -0,0 +1,90 @@ +/**************************************************************************************** + * \file SHMathHelpers.hpp + * \author Diren D Bharwani, diren.dbharwani, 390002520 + * \brief Implementation for various templated mathematical helper functions. + * + * \copyright Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or + * disclosure of this file or its contents without the prior written consent + * of DigiPen Institute of Technology is prohibited. +****************************************************************************************/ + +#pragma once + +// Primary Header +#include "SHMathHelpers.h" + +#include +#include + +// TODOs (Diren): Include pch? + +namespace SHADE +{ + /*-----------------------------------------------------------------------------------*/ + /* Static Function Members Definitions */ + /*-----------------------------------------------------------------------------------*/ + + template + constexpr T SHMath::DegreesToRadians(T angleInDeg) + { + return angleInDeg * static_cast(PI / 180.0f); + } + + template + constexpr T SHMath::RadiansToDegrees(T angleInRad) + { + return angleInRad * static_cast(180.0f / PI); + } + + template + T SHMath::Lerp(T a, T b, T alpha) + { + return a + alpha * (b - a); + } + + template + T SHMath::ClampedLerp(T a, T b, T alpha, T alphaMin, T alphaMax) + { + const T T_ACTUAL = std::clamp(alpha, alphaMin, alphaMax); + return a + T_ACTUAL * (b - a); + } + + template + T SHMath::Wrap(T value, T min, T max) + { + while (value < min) + { + value = max - (min - value); + } + + while (value > max) + { + value = min + (value - max); + } + + return value; + } + + template + T SHMath::GenerateRandomNumber(T lowerBound, T upperBound) + { + if constexpr (IsIntegral) + { + std::uniform_int_distribution distribution(lowerBound, upperBound); + return distribution(rng); + } + if constexpr (IsFloatingPoint) + { + std::uniform_real_distribution distribution(lowerBound, upperBound); + return distribution(rng); + } + } + + + template + bool CompareFloat(T lhs, T rhs, T absTolerance, T relTolerance) + { + return std::fabs(lhs - rhs) <= std::max(absTolerance, relTolerance * std::max(abs(lhs), abs(rhs))); + } + +} // namespace SHADE \ No newline at end of file diff --git a/SHADE_Engine/src/Math/SHMatrix.cpp b/SHADE_Engine/src/Math/SHMatrix.cpp new file mode 100644 index 00000000..8e8281d0 --- /dev/null +++ b/SHADE_Engine/src/Math/SHMatrix.cpp @@ -0,0 +1,601 @@ +/**************************************************************************************** + * \file SHMatrix.hpp + * \author Diren D Bharwani, diren.dbharwani, 390002520 + * \brief Implementation for a Matrix. + * + * \copyright Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or + * disclosure of this file or its contents without the prior written consent + * of DigiPen Institute of Technology is prohibited. +****************************************************************************************/ + +#include + +// Primary Header +#include "SHMatrix.h" + +#include "Vector/SHVec2.h" +#include "Vector/SHVec3.h" +#include "Vector/SHVec4.h" +#include "SHQuaternion.h" + +using namespace DirectX; + +namespace SHADE +{ + /*-----------------------------------------------------------------------------------*/ + /* Static Data Member Definitions */ + /*-----------------------------------------------------------------------------------*/ + + const SHMatrix SHMatrix::Identity + { + 1.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 1.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 1.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f + }; + + /*-----------------------------------------------------------------------------------*/ + /* Constructors & Destructor Definitions */ + /*-----------------------------------------------------------------------------------*/ + + SHMatrix::SHMatrix() noexcept + : XMFLOAT4X4 + ( + 1.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 1.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 1.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f + ) + {} + + SHMatrix::SHMatrix + ( + const SHVec4& r0, const SHVec4& r1, + const SHVec4& r2, const SHVec4& r3 + ) noexcept + : XMFLOAT4X4 + ( + r0.x, r0.y, r0.z, r0.w, + r1.x, r1.y, r1.z, r1.w, + r2.x, r2.y, r2.z, r2.w, + r3.x, r3.y, r3.z, r3.w + ) + {} + + SHMatrix::SHMatrix + ( + float m00, float m01, float m02, float m03, + float m10, float m11, float m12, float m13, + float m20, float m21, float m22, float m23, + float m30, float m31, float m32, float m33 + ) noexcept + : XMFLOAT4X4 + ( + m00, m01, m02, m03, + m10, m11, m12, m13, + m20, m21, m22, m23, + m30, m31, m32, m33 + ) + {} + + /*-----------------------------------------------------------------------------------*/ + /* Operator Overload Definitions */ + /*-----------------------------------------------------------------------------------*/ + + SHMatrix& SHMatrix::operator+=(const SHMatrix& rhs) noexcept + { + return *this = *this + rhs; + } + + SHMatrix& SHMatrix::operator-=(const SHMatrix& rhs) noexcept + { + return *this = *this - rhs; + } + + SHMatrix& SHMatrix::operator*=(const SHMatrix& rhs) noexcept + { + return *this = *this * rhs; + } + + SHMatrix& SHMatrix::operator*=(float rhs) noexcept + { + return *this = *this * rhs; + } + + SHMatrix& SHMatrix::operator/=(const SHMatrix& rhs) noexcept + { + return *this = *this / rhs; + } + + SHMatrix& SHMatrix::operator/=(float rhs) noexcept + { + return *this = *this / rhs; + } + + SHMatrix SHMatrix::operator+(const SHMatrix& rhs) const noexcept + { + SHMatrix result; + + const XMVECTOR L1 = XMLoadFloat4(reinterpret_cast(&_11)); + const XMVECTOR L2 = XMLoadFloat4(reinterpret_cast(&_21)); + const XMVECTOR L3 = XMLoadFloat4(reinterpret_cast(&_31)); + const XMVECTOR L4 = XMLoadFloat4(reinterpret_cast(&_41)); + + const XMVECTOR R1 = XMLoadFloat4(reinterpret_cast(&rhs._11)); + const XMVECTOR R2 = XMLoadFloat4(reinterpret_cast(&rhs._21)); + const XMVECTOR R3 = XMLoadFloat4(reinterpret_cast(&rhs._31)); + const XMVECTOR R4 = XMLoadFloat4(reinterpret_cast(&rhs._41)); + + XMStoreFloat4(reinterpret_cast(&result._11), XMVectorAdd(L1, R1)); + XMStoreFloat4(reinterpret_cast(&result._21), XMVectorAdd(L2, R2)); + XMStoreFloat4(reinterpret_cast(&result._31), XMVectorAdd(L3, R3)); + XMStoreFloat4(reinterpret_cast(&result._41), XMVectorAdd(L4, R4)); + + return result; + } + + SHMatrix SHMatrix::operator-(const SHMatrix& rhs) const noexcept + { + SHMatrix result; + + const XMVECTOR L1 = XMLoadFloat4(reinterpret_cast(&_11)); + const XMVECTOR L2 = XMLoadFloat4(reinterpret_cast(&_21)); + const XMVECTOR L3 = XMLoadFloat4(reinterpret_cast(&_31)); + const XMVECTOR L4 = XMLoadFloat4(reinterpret_cast(&_41)); + + const XMVECTOR R1 = XMLoadFloat4(reinterpret_cast(&rhs._11)); + const XMVECTOR R2 = XMLoadFloat4(reinterpret_cast(&rhs._21)); + const XMVECTOR R3 = XMLoadFloat4(reinterpret_cast(&rhs._31)); + const XMVECTOR R4 = XMLoadFloat4(reinterpret_cast(&rhs._41)); + + XMStoreFloat4(reinterpret_cast(&result._11), XMVectorSubtract(L1, R1)); + XMStoreFloat4(reinterpret_cast(&result._21), XMVectorSubtract(L2, R2)); + XMStoreFloat4(reinterpret_cast(&result._31), XMVectorSubtract(L3, R3)); + XMStoreFloat4(reinterpret_cast(&result._41), XMVectorSubtract(L4, R4)); + + return result; + } + + SHMatrix SHMatrix::operator-() const noexcept + { + SHMatrix result; + + const XMVECTOR L1 = XMLoadFloat4(reinterpret_cast(&_11)); + const XMVECTOR L2 = XMLoadFloat4(reinterpret_cast(&_21)); + const XMVECTOR L3 = XMLoadFloat4(reinterpret_cast(&_31)); + const XMVECTOR L4 = XMLoadFloat4(reinterpret_cast(&_41)); + + XMStoreFloat4(reinterpret_cast(&result._11), XMVectorNegate(L1)); + XMStoreFloat4(reinterpret_cast(&result._21), XMVectorNegate(L2)); + XMStoreFloat4(reinterpret_cast(&result._31), XMVectorNegate(L3)); + XMStoreFloat4(reinterpret_cast(&result._41), XMVectorNegate(L4)); + + return result; + } + + SHMatrix SHMatrix::operator*(const SHMatrix& rhs) const noexcept + { + SHMatrix result; + + const XMMATRIX M1 = XMLoadFloat4x4(this); + const XMMATRIX M2 = XMLoadFloat4x4(&rhs); + + XMStoreFloat4x4(&result, XMMatrixMultiply(M1, M2)); + return result; + } + + SHVec3 SHMatrix::operator*(const SHVec3& rhs) const noexcept + { + return SHVec3::Transform(rhs, *this); + } + + SHVec4 SHMatrix::operator*(const SHVec4& rhs) const noexcept + { + return SHVec4::Transform3D(rhs, *this); + } + + SHMatrix SHMatrix::operator*(float rhs) const noexcept + { + SHMatrix result; + + const XMVECTOR L1 = XMLoadFloat4(reinterpret_cast(&_11)); + const XMVECTOR L2 = XMLoadFloat4(reinterpret_cast(&_21)); + const XMVECTOR L3 = XMLoadFloat4(reinterpret_cast(&_31)); + const XMVECTOR L4 = XMLoadFloat4(reinterpret_cast(&_41)); + + XMStoreFloat4(reinterpret_cast(&result._11), XMVectorScale(L1, rhs)); + XMStoreFloat4(reinterpret_cast(&result._21), XMVectorScale(L2, rhs)); + XMStoreFloat4(reinterpret_cast(&result._31), XMVectorScale(L3, rhs)); + XMStoreFloat4(reinterpret_cast(&result._41), XMVectorScale(L4, rhs)); + + return result; + } + + SHMatrix SHMatrix::operator/(const SHMatrix& rhs) const noexcept + { + SHMatrix result; + + const XMVECTOR L1 = XMLoadFloat4(reinterpret_cast(&_11)); + const XMVECTOR L2 = XMLoadFloat4(reinterpret_cast(&_21)); + const XMVECTOR L3 = XMLoadFloat4(reinterpret_cast(&_31)); + const XMVECTOR L4 = XMLoadFloat4(reinterpret_cast(&_41)); + + const XMVECTOR R1 = XMLoadFloat4(reinterpret_cast(&rhs._11)); + const XMVECTOR R2 = XMLoadFloat4(reinterpret_cast(&rhs._21)); + const XMVECTOR R3 = XMLoadFloat4(reinterpret_cast(&rhs._31)); + const XMVECTOR R4 = XMLoadFloat4(reinterpret_cast(&rhs._41)); + + XMStoreFloat4(reinterpret_cast(&result._11), XMVectorDivide(L1, R1)); + XMStoreFloat4(reinterpret_cast(&result._21), XMVectorDivide(L2, R2)); + XMStoreFloat4(reinterpret_cast(&result._31), XMVectorDivide(L3, R3)); + XMStoreFloat4(reinterpret_cast(&result._41), XMVectorDivide(L4, R4)); + + return result; + } + + SHMatrix SHMatrix::operator/(float rhs) const noexcept + { + SHMatrix result; + + const XMVECTOR L1 = XMLoadFloat4(reinterpret_cast(&_11)); + const XMVECTOR L2 = XMLoadFloat4(reinterpret_cast(&_21)); + const XMVECTOR L3 = XMLoadFloat4(reinterpret_cast(&_31)); + const XMVECTOR L4 = XMLoadFloat4(reinterpret_cast(&_41)); + + const float INV_RHS = 1.0f / rhs; + + XMStoreFloat4(reinterpret_cast(&result._11), XMVectorScale(L1, INV_RHS)); + XMStoreFloat4(reinterpret_cast(&result._21), XMVectorScale(L2, INV_RHS)); + XMStoreFloat4(reinterpret_cast(&result._31), XMVectorScale(L3, INV_RHS)); + XMStoreFloat4(reinterpret_cast(&result._41), XMVectorScale(L4, INV_RHS)); + + return result; + } + + bool SHMatrix::operator==(const SHMatrix& rhs) const noexcept + { + const XMVECTOR L1 = XMLoadFloat4(reinterpret_cast(&_11)); + const XMVECTOR L2 = XMLoadFloat4(reinterpret_cast(&_21)); + const XMVECTOR L3 = XMLoadFloat4(reinterpret_cast(&_31)); + const XMVECTOR L4 = XMLoadFloat4(reinterpret_cast(&_41)); + + const XMVECTOR R1 = XMLoadFloat4(reinterpret_cast(&rhs._11)); + const XMVECTOR R2 = XMLoadFloat4(reinterpret_cast(&rhs._21)); + const XMVECTOR R3 = XMLoadFloat4(reinterpret_cast(&rhs._31)); + const XMVECTOR R4 = XMLoadFloat4(reinterpret_cast(&rhs._41)); + + return + ( + XMVector4Equal(L1, R1) + && XMVector4Equal(L2, R2) + && XMVector4Equal(L3, R4) + && XMVector4Equal(L4, R4) + ) != 0; + } + + + bool SHMatrix::operator!=(const SHMatrix& rhs) const noexcept + { + const XMVECTOR L1 = XMLoadFloat4(reinterpret_cast(&_11)); + const XMVECTOR L2 = XMLoadFloat4(reinterpret_cast(&_21)); + const XMVECTOR L3 = XMLoadFloat4(reinterpret_cast(&_31)); + const XMVECTOR L4 = XMLoadFloat4(reinterpret_cast(&_41)); + + const XMVECTOR R1 = XMLoadFloat4(reinterpret_cast(&rhs._11)); + const XMVECTOR R2 = XMLoadFloat4(reinterpret_cast(&rhs._21)); + const XMVECTOR R3 = XMLoadFloat4(reinterpret_cast(&rhs._31)); + const XMVECTOR R4 = XMLoadFloat4(reinterpret_cast(&rhs._41)); + + return + ( + XMVector4NotEqual(L1, R1) + || XMVector4NotEqual(L2, R2) + || XMVector4NotEqual(L3, R4) + || XMVector4NotEqual(L4, R4) + ) != 0; + } + + SHMatrix operator*(float lhs, const SHMatrix& rhs) noexcept + { + return rhs * lhs; + } + + + /*-----------------------------------------------------------------------------------*/ + /* Function Member Definitions */ + /*-----------------------------------------------------------------------------------*/ + + void SHMatrix::Transpose() noexcept + { + const XMMATRIX M = XMLoadFloat4x4(this); + XMStoreFloat4x4(this, XMMatrixTranspose(M)); + } + + void SHMatrix::Invert() noexcept + { + const XMMATRIX M = XMLoadFloat4x4(this); + XMStoreFloat4x4(this, XMMatrixInverse(nullptr, M)); + } + + float SHMatrix::Determinant() const noexcept + { + const XMMATRIX M = XMLoadFloat4x4(this); + return XMVectorGetX(XMMatrixDeterminant(M)); + } + + std::string SHMatrix::ToString() const noexcept + { + std::stringstream ss; + ss << std::fixed << std::setprecision(3); + ss << "| " << _11 << ", " << _12 << ", " << _13 << ", " << _14 << " |\n"; + ss << "| " << _21 << ", " << _22 << ", " << _23 << ", " << _24 << " |\n"; + ss << "| " << _31 << ", " << _32 << ", " << _33 << ", " << _34 << " |\n"; + ss << "| " << _41 << ", " << _42 << ", " << _43 << ", " << _44 << " |"; + return ss.str(); + } + + + /*-----------------------------------------------------------------------------------*/ + /* Static Function Member Definitions */ + /*-----------------------------------------------------------------------------------*/ + + SHMatrix SHMatrix::Transpose(const SHMatrix& matrix) noexcept + { + SHMatrix result; + + const XMMATRIX M = XMLoadFloat4x4(&matrix); + XMStoreFloat4x4(&result, XMMatrixTranspose(M)); + return result; + } + + SHMatrix SHMatrix::Inverse(const SHMatrix& matrix) noexcept + { + SHMatrix result; + + const XMMATRIX M = XMLoadFloat4x4(&matrix); + XMStoreFloat4x4(&result, XMMatrixInverse(nullptr, M)); + return result; + } + + SHMatrix SHMatrix::Translate(float x, float y, float z) noexcept + { + SHMatrix result; + XMStoreFloat4x4(&result, XMMatrixTranslation(x, y, z)); + + result.Transpose(); + return result; + } + + SHMatrix SHMatrix::Translate(const SHVec3& pos) noexcept + { + SHMatrix result; + XMStoreFloat4x4(&result, XMMatrixTranslation(pos.x, pos.y, pos.z)); + + result.Transpose(); + return result; + } + + SHMatrix SHMatrix::Rotate(const SHVec3& axis, float angleInRad) noexcept + { + SHMatrix result; + + const XMVECTOR A = XMLoadFloat3(&axis); + XMStoreFloat4x4(&result, XMMatrixRotationAxis(A, angleInRad)); + + result.Transpose(); + return result; + } + + SHMatrix SHMatrix::Rotate(float yaw, float pitch, float roll) noexcept + { + SHMatrix result; + XMStoreFloat4x4(&result, XMMatrixRotationRollPitchYaw(pitch, yaw, roll)); + + result.Transpose(); + return result; + } + + SHMatrix SHMatrix::Rotate(const SHVec3& eulerAngles) noexcept + { + SHMatrix result; + XMStoreFloat4x4(&result, XMMatrixRotationRollPitchYaw(eulerAngles.x, eulerAngles.y, eulerAngles.z)); + + result.Transpose(); + return result; + } + + SHMatrix SHMatrix::Rotate(const SHQuaternion& q) noexcept + { + SHMatrix result; + + const XMVECTOR Q = XMLoadFloat4(&q); + XMStoreFloat4x4(&result, XMMatrixRotationQuaternion(Q)); + + result.Transpose(); + return result; + } + + SHMatrix SHMatrix::RotateX(float angleInRad) noexcept + { + SHMatrix result; + XMStoreFloat4x4(&result, XMMatrixRotationX(angleInRad)); + + result.Transpose(); + return result; + } + + SHMatrix SHMatrix::RotateY(float angleInRad) noexcept + { + SHMatrix result; + XMStoreFloat4x4(&result, XMMatrixRotationY(angleInRad)); + + result.Transpose(); + return result; + } + + SHMatrix SHMatrix::RotateZ(float angleInRad) noexcept + { + SHMatrix result; + XMStoreFloat4x4(&result, XMMatrixRotationZ(angleInRad)); + + result.Transpose(); + return result; + } + + SHMatrix SHMatrix::Scale(float uniformScaleFactor) noexcept + { + SHMatrix result; + XMStoreFloat4x4(&result, XMMatrixScaling(uniformScaleFactor, uniformScaleFactor, uniformScaleFactor)); + + return result; + } + + SHMatrix SHMatrix::Scale(float x, float y, float z) noexcept + { + SHMatrix result; + XMStoreFloat4x4(&result, XMMatrixScaling(x, y, z)); + + return result; + } + + SHMatrix SHMatrix::Scale(const SHVec3& scale) noexcept + { + SHMatrix result; + XMStoreFloat4x4(&result, XMMatrixScaling(scale.x, scale.y, scale.z)); + + return result; + } + + SHMatrix SHMatrix::LookAtRH(const SHVec3& eye, const SHVec3& target, const SHVec3& up) noexcept + { + SHMatrix result; + + const XMVECTOR EYE = XMLoadFloat3(&eye); + const XMVECTOR TGT = XMLoadFloat3(&target); + const XMVECTOR UP = XMLoadFloat3(&up); + + XMStoreFloat4x4(&result, XMMatrixLookAtRH(EYE, TGT, UP)); + + result.Transpose(); + return result; + } + + SHMatrix SHMatrix::LookAtLH(const SHVec3& eye, const SHVec3& target, const SHVec3& up) noexcept + { + SHMatrix result; + + const XMVECTOR EYE = XMLoadFloat3(&eye); + const XMVECTOR TGT = XMLoadFloat3(&target); + const XMVECTOR UP = XMLoadFloat3(&up); + + XMStoreFloat4x4(&result, XMMatrixLookAtLH(EYE, TGT, UP)); + + result.Transpose(); + return result; + } + + SHMatrix SHMatrix::CamToWorldRH(const SHVec3& pos, const SHVec3& forward, const SHVec3& up) noexcept + { + SHMatrix result; + + const SHVec3 FWD_HAT = SHVec3::Normalise(-forward); + + const XMVECTOR Z_HAT = XMVector3Normalize(XMLoadFloat3(&FWD_HAT)); + const XMVECTOR X_HAT = XMVector3Normalize(XMVector3Cross(XMLoadFloat3(&up), Z_HAT)); + const XMVECTOR Y_HAT = XMVector3Cross(Z_HAT, X_HAT); + + XMStoreFloat3(reinterpret_cast(&result._11), X_HAT); + XMStoreFloat3(reinterpret_cast(&result._21), Y_HAT); + XMStoreFloat3(reinterpret_cast(&result._31), Z_HAT); + + result._41 = pos.x; + result._42 = pos.y; + result._43 = pos.z; + + result.Transpose(); + return result; + } + + SHMatrix SHMatrix::CamToWorldLH(const SHVec3& pos, const SHVec3& forward, const SHVec3& up) noexcept + { + SHMatrix result; + + const SHVec3 FWD_HAT = SHVec3::Normalise(forward); + + const XMVECTOR Z_HAT = XMVector3Normalize(XMLoadFloat3(&FWD_HAT)); + const XMVECTOR X_HAT = XMVector3Normalize(XMVector3Cross(XMLoadFloat3(&up), Z_HAT)); + const XMVECTOR Y_HAT = XMVector3Cross(Z_HAT, X_HAT); + + XMStoreFloat3(reinterpret_cast(&result._11), X_HAT); + XMStoreFloat3(reinterpret_cast(&result._21), Y_HAT); + XMStoreFloat3(reinterpret_cast(&result._31), Z_HAT); + + result._41 = pos.x; + result._42 = pos.x; + result._43 = pos.x; + + result.Transpose(); + return result; + } + + SHMatrix SHMatrix::PerspectiveFovRH(float fov, float aspectRatio, float nearPlane, float farPlane) noexcept + { + SHMatrix result; + + XMStoreFloat4x4(&result, XMMatrixPerspectiveFovRH(fov, aspectRatio, nearPlane, farPlane)); + + result.Transpose(); + return result; + } + + SHMatrix SHMatrix::PerspectiveFovLH(float fov, float aspectRatio, float nearPlane, float farPlane) noexcept + { + SHMatrix result; + + XMStoreFloat4x4(&result, XMMatrixPerspectiveFovLH(fov, aspectRatio, nearPlane, farPlane)); + + result.Transpose(); + return result; + } + + SHMatrix SHMatrix::PerspectiveRH(float width, float height, float nearPlane, float farPlane) noexcept + { + SHMatrix result; + + XMStoreFloat4x4(&result, XMMatrixPerspectiveRH(width, height, nearPlane, farPlane)); + + result.Transpose(); + return result; + } + + SHMatrix SHMatrix::PerspectiveLH(float width, float height, float nearPlane, float farPlane) noexcept + { + SHMatrix result; + + XMStoreFloat4x4(&result, XMMatrixPerspectiveLH(width, height, nearPlane, farPlane)); + + result.Transpose(); + return result; + } + + SHMatrix SHMatrix::OrthographicRH(float width, float height, float nearPlane, float farPlane) noexcept + { + SHMatrix result; + + XMStoreFloat4x4(&result, XMMatrixOrthographicRH(width, height, nearPlane, farPlane)); + + result.Transpose(); + return result; + } + + SHMatrix SHMatrix::OrthographicLH(float width, float height, float nearPlane, float farPlane) noexcept + { + SHMatrix result; + + XMStoreFloat4x4(&result, XMMatrixOrthographicLH(width, height, nearPlane, farPlane)); + + result.Transpose(); + return result; + } + +} // namespace SHADE \ No newline at end of file diff --git a/SHADE_Engine/src/Math/SHMatrix.h b/SHADE_Engine/src/Math/SHMatrix.h new file mode 100644 index 00000000..2aab05ab --- /dev/null +++ b/SHADE_Engine/src/Math/SHMatrix.h @@ -0,0 +1,144 @@ +/**************************************************************************************** + * \file SHMatrix.h + * \author Diren D Bharwani, diren.dbharwani, 390002520 + * \brief Interface for a Matrix. + * + * \copyright Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or + * disclosure of this file or its contents without the prior written consent + * of DigiPen Institute of Technology is prohibited. +****************************************************************************************/ + +#pragma once + +#include +#include + +#include "Vector/SHVec4.h" + +namespace SHADE +{ + /*-----------------------------------------------------------------------------------*/ + /* Forward Declarations */ + /*-----------------------------------------------------------------------------------*/ + class SHVec2; + class SHVec3; + class SHVec4; + class SHQuaternion; + + /*-----------------------------------------------------------------------------------*/ + /* Type Definitions */ + /*-----------------------------------------------------------------------------------*/ + + /** + * @brief Interface for a Column-Major Row Vector 4x4 Matrix. + */ + class SHMatrix : public DirectX::XMFLOAT4X4 + { + public: + /*---------------------------------------------------------------------------------*/ + /* Static Data Members */ + /*---------------------------------------------------------------------------------*/ + + static constexpr size_t SIZE = 16U; + static constexpr size_t NUM_ROWS = 4U; + static constexpr size_t NUM_COLS = 4U; + + static const SHMatrix Identity; + + /*---------------------------------------------------------------------------------*/ + /* Constructors & Destructor */ + /*---------------------------------------------------------------------------------*/ + + SHMatrix (const SHMatrix& rhs) = default; + SHMatrix (SHMatrix&& rhs) = default; + ~SHMatrix () = default; + + SHMatrix () noexcept; + SHMatrix ( const SHVec4& r0, + const SHVec4& r1, + const SHVec4& r2, + const SHVec4& r3 = SHVec4::UnitW + ) noexcept; + SHMatrix ( + float m00, float m01, float m02, float m03, + float m10, float m11, float m12, float m13, + float m20, float m21, float m22, float m23, + float m30 = 0.0f, float m31 = 0.0f, float m32 = 0.0f, float m33 = 1.0f + ) noexcept; + + /*---------------------------------------------------------------------------------*/ + /* Operator Overloads */ + /*---------------------------------------------------------------------------------*/ + + SHMatrix& operator= (const SHMatrix& rhs) = default; + SHMatrix& operator= (SHMatrix&& rhs) = default; + + SHMatrix& operator+= (const SHMatrix& rhs) noexcept; + SHMatrix& operator-= (const SHMatrix& rhs) noexcept; + SHMatrix& operator*= (const SHMatrix& rhs) noexcept; + SHMatrix& operator*= (float rhs) noexcept; + SHMatrix& operator/= (const SHMatrix& rhs) noexcept; + SHMatrix& operator/= (float rhs) noexcept; + + SHMatrix operator+ (const SHMatrix& rhs) const noexcept; + SHMatrix operator- (const SHMatrix& rhs) const noexcept; + SHMatrix operator- () const noexcept; + SHMatrix operator* (const SHMatrix& rhs) const noexcept; + SHVec3 operator* (const SHVec3& rhs) const noexcept; + SHVec4 operator* (const SHVec4& rhs) const noexcept; + SHMatrix operator* (float rhs) const noexcept; + SHMatrix operator/ (const SHMatrix& rhs) const noexcept; + SHMatrix operator/ (float rhs) const noexcept; + + bool operator== (const SHMatrix& rhs) const noexcept; + bool operator!= (const SHMatrix& rhs) const noexcept; + + /*---------------------------------------------------------------------------------*/ + /* Function Members */ + /*---------------------------------------------------------------------------------*/ + + void Transpose () noexcept; + void Invert () noexcept; + + [[nodiscard]] float Determinant () const noexcept; + [[nodiscard]] std::string ToString () const noexcept; + + /*---------------------------------------------------------------------------------*/ + /* Static Function Members */ + /*---------------------------------------------------------------------------------*/ + + [[nodiscard]] static SHMatrix Transpose (const SHMatrix& matrix) noexcept; + [[nodiscard]] static SHMatrix Inverse (const SHMatrix& matrix) noexcept; + + [[nodiscard]] static SHMatrix Translate (float x, float y, float z) noexcept; + [[nodiscard]] static SHMatrix Translate (const SHVec3& pos) noexcept; + + [[nodiscard]] static SHMatrix Rotate (const SHVec3& axis, float angleInRad) noexcept; + [[nodiscard]] static SHMatrix Rotate (float yaw, float pitch, float roll) noexcept; + [[nodiscard]] static SHMatrix Rotate (const SHVec3& eulerAngles) noexcept; + [[nodiscard]] static SHMatrix Rotate (const SHQuaternion& q) noexcept; + [[nodiscard]] static SHMatrix RotateX (float angleInRad) noexcept; + [[nodiscard]] static SHMatrix RotateY (float angleInRad) noexcept; + [[nodiscard]] static SHMatrix RotateZ (float angleInRad) noexcept; + + [[nodiscard]] static SHMatrix Scale (float uniformScaleFactor) noexcept; + [[nodiscard]] static SHMatrix Scale (float x, float y, float z) noexcept; + [[nodiscard]] static SHMatrix Scale (const SHVec3& scale) noexcept; + + [[nodiscard]] static SHMatrix LookAtRH (const SHVec3& eye, const SHVec3& target, const SHVec3& up) noexcept; + [[nodiscard]] static SHMatrix LookAtLH (const SHVec3& eye, const SHVec3& target, const SHVec3& up) noexcept; + [[nodiscard]] static SHMatrix CamToWorldRH (const SHVec3& pos, const SHVec3& forward, const SHVec3& up) noexcept; + [[nodiscard]] static SHMatrix CamToWorldLH (const SHVec3& pos, const SHVec3& forward, const SHVec3& up) noexcept; + [[nodiscard]] static SHMatrix PerspectiveFovRH (float fov, float aspectRatio, float nearPlane, float farPlane) noexcept; + [[nodiscard]] static SHMatrix PerspectiveFovLH (float fov, float aspectRatio, float nearPlane, float farPlane) noexcept; + [[nodiscard]] static SHMatrix PerspectiveRH (float width, float height, float nearPlane, float farPlane) noexcept; + [[nodiscard]] static SHMatrix PerspectiveLH (float width, float height, float nearPlane, float farPlane) noexcept; + [[nodiscard]] static SHMatrix OrthographicRH (float width, float height, float nearPlane, float farPlane) noexcept; + [[nodiscard]] static SHMatrix OrthographicLH (float width, float height, float nearPlane, float farPlane) noexcept; + + // TODO(Diren): Billboard, Shadow, Projection & Reflection + }; + + SHMatrix operator*(float lhs, const SHMatrix& rhs) noexcept; + +} // namespace SHADE \ No newline at end of file diff --git a/SHADE_Engine/src/Math/SHQuaternion.cpp b/SHADE_Engine/src/Math/SHQuaternion.cpp new file mode 100644 index 00000000..2b1ac173 --- /dev/null +++ b/SHADE_Engine/src/Math/SHQuaternion.cpp @@ -0,0 +1,240 @@ +/**************************************************************************************** + * \file SHQuaternion.cpp + * \author Diren D Bharwani, diren.dbharwani, 390002520 + * \brief Implementation for a Quaternion. + * + * \copyright Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or + * disclosure of this file or its contents without the prior written consent + * of DigiPen Institute of Technology is prohibited. +****************************************************************************************/ + +#include + +// Primary Header +#include "SHQuaternion.h" +// Project Headers +#include "Vector/SHVec3.h" +#include "SHMatrix.h" +#include "Tools/SHLogger.h" + +using namespace DirectX; + +namespace SHADE +{ + /*-----------------------------------------------------------------------------------*/ + /* Static Data Member Definitions */ + /*-----------------------------------------------------------------------------------*/ + + const SHQuaternion SHQuaternion::Identity{ 0.0f, 0.0f, 0.0f, 1.0f }; + + /*-----------------------------------------------------------------------------------*/ + /* Constructors & Destructor Definitions */ + /*-----------------------------------------------------------------------------------*/ + + SHQuaternion::SHQuaternion() noexcept + : XMFLOAT4( 0.0f, 0.0f, 0.0f, 1.0f ) + {} + + SHQuaternion::SHQuaternion(float _x, float _y, float _z, float _w) noexcept + : XMFLOAT4( _x, _y, _z, _w ) + {} + + SHQuaternion::SHQuaternion(float yaw, float pitch, float roll) noexcept + : XMFLOAT4( 0.0f, 0.0f, 0.0f, 1.0f ) + { + XMStoreFloat4(this, XMQuaternionRotationRollPitchYaw(pitch, yaw, roll)); + } + + SHQuaternion::SHQuaternion(const SHVec3& eulerAngles) noexcept + : XMFLOAT4( 0.0f, 0.0f, 0.0f, 1.0f ) + { + const XMVECTOR V = XMLoadFloat3(&eulerAngles); + XMStoreFloat4(this, XMQuaternionRotationRollPitchYawFromVector(V)); + } + + SHQuaternion::SHQuaternion(const SHVec3& axis, float angleInRad) noexcept + : XMFLOAT4( 0.0f, 0.0f, 0.0f, 1.0f ) + { + const XMVECTOR AXIS = XMLoadFloat3(&axis); + XMStoreFloat4(this, XMQuaternionRotationAxis(AXIS, angleInRad)); + } + + SHQuaternion::SHQuaternion(const SHMatrix& rotationMatrix) noexcept + : XMFLOAT4( 0.0f, 0.0f, 0.0f, 1.0f ) + { + const XMMATRIX M = XMLoadFloat4x4(&rotationMatrix); + XMStoreFloat4(this, XMQuaternionRotationMatrix(M)); + } + + /*-----------------------------------------------------------------------------------*/ + /* Operator Overload Definitions */ + /*-----------------------------------------------------------------------------------*/ + + SHQuaternion& SHQuaternion::operator+=(const SHQuaternion& rhs) noexcept + { + return *this = *this + rhs; + } + + SHQuaternion& SHQuaternion::operator-=(const SHQuaternion& rhs) noexcept + { + return *this = *this - rhs; + } + + SHQuaternion& SHQuaternion::operator*=(const SHQuaternion& rhs) noexcept + { + return *this = *this * rhs; + } + + SHQuaternion& SHQuaternion::operator*=(float rhs) noexcept + { + return *this = *this * rhs; + } + + SHQuaternion& SHQuaternion::operator/=(const SHQuaternion& rhs) noexcept + { + return *this = *this / rhs; + } + + SHQuaternion SHQuaternion::operator+(const SHQuaternion& rhs) const noexcept + { + SHQuaternion result; + + const XMVECTOR Q1 = XMLoadFloat4(this); + const XMVECTOR Q2 = XMLoadFloat4(&rhs); + + XMStoreFloat4(&result, XMVectorAdd(Q1, Q2)); + return result; + } + + SHQuaternion SHQuaternion::operator-(const SHQuaternion& rhs) const noexcept + { + SHQuaternion result; + + const XMVECTOR Q1 = XMLoadFloat4(this); + const XMVECTOR Q2 = XMLoadFloat4(&rhs); + + XMStoreFloat4(&result, XMVectorSubtract(Q1, Q2)); + return result; + } + + SHQuaternion SHQuaternion::operator-() const noexcept + { + SHQuaternion result; + + const XMVECTOR Q = XMLoadFloat4(this); + + XMStoreFloat4(&result, XMVectorNegate(Q)); + return result; + } + + SHQuaternion SHQuaternion::operator*(const SHQuaternion& rhs) const noexcept + { + SHQuaternion result; + + const XMVECTOR Q1 = XMLoadFloat4(this); + const XMVECTOR Q2 = XMLoadFloat4(&rhs); + + XMStoreFloat4(&result, XMQuaternionMultiply(Q1, Q2)); + return result; + } + + SHQuaternion SHQuaternion::operator*(float rhs) const noexcept + { + SHQuaternion result; + + const XMVECTOR Q = XMLoadFloat4(this); + + XMStoreFloat4(&result, XMVectorScale(Q, rhs)); + return result; + } + + SHQuaternion SHQuaternion::operator/(const SHQuaternion& rhs) const noexcept + { + SHQuaternion result; + + const XMVECTOR Q1 = XMLoadFloat4(this); + const XMVECTOR Q2 = XMQuaternionInverse(XMLoadFloat4(&rhs)); + + XMStoreFloat4(&result, XMQuaternionMultiply(Q1, Q2)); + return result; + } + + bool SHQuaternion::operator==(const SHQuaternion& rhs) const noexcept + { + const XMVECTOR Q1 = XMLoadFloat4(this); + const XMVECTOR Q2 = XMLoadFloat4(&rhs); + + return XMQuaternionEqual(Q1, Q2); + } + + bool SHQuaternion::operator!=(const SHQuaternion& rhs) const noexcept + { + const XMVECTOR Q1 = XMLoadFloat4(this); + const XMVECTOR Q2 = XMLoadFloat4(&rhs); + + return XMQuaternionNotEqual(Q1, Q2); + } + + SHQuaternion operator*(float lhs, const SHQuaternion& rhs) noexcept + { + return rhs * lhs; + } + + /*-----------------------------------------------------------------------------------*/ + /* Function Member Definitions */ + /*-----------------------------------------------------------------------------------*/ + + void SHQuaternion::Invert() noexcept + { + const XMVECTOR Q = XMLoadFloat4(this); + XMStoreFloat4(this, XMQuaternionInverse(Q)); + } + + float SHQuaternion::Length() const noexcept + { + const XMVECTOR Q = XMLoadFloat4(this); + return XMVectorGetX(XMQuaternionLength(Q)); + } + + float SHQuaternion::LengthSquared() const noexcept + { + const XMVECTOR Q = XMLoadFloat4(this); + return XMVectorGetX(XMQuaternionLengthSq(Q)); + } + + float SHQuaternion::Dot(const SHQuaternion& rhs) const noexcept + { + const XMVECTOR Q1 = XMLoadFloat4(this); + const XMVECTOR Q2 = XMLoadFloat4(&rhs); + + return XMVectorGetX(XMQuaternionDot(Q1, Q2)); + } + + SHQuaternion SHQuaternion::RotateTowards(const SHQuaternion&, float) const noexcept + { + // TODO(Diren): Figure this out. + + return Identity; + } + + SHVec3 SHQuaternion::ToEuler() const noexcept + { + // TODO(Diren): Figure this out. + + return SHVec3::Zero; + } + + std::string SHQuaternion::ToString() const noexcept + { + std::stringstream ss; + ss << std::fixed << std::setprecision(3); + ss << "<" << x << ", " << y << ", " << z << ", " << w <<">"; + return ss.str(); + } + + /*-----------------------------------------------------------------------------------*/ + /* Static Function Member Definitions */ + /*-----------------------------------------------------------------------------------*/ + + +} // namespace SHADE \ No newline at end of file diff --git a/SHADE_Engine/src/Math/SHQuaternion.h b/SHADE_Engine/src/Math/SHQuaternion.h new file mode 100644 index 00000000..103019ae --- /dev/null +++ b/SHADE_Engine/src/Math/SHQuaternion.h @@ -0,0 +1,106 @@ +/**************************************************************************************** + * \file SHQuaternion.h + * \author Diren D Bharwani, diren.dbharwani, 390002520 + * \brief Interface for a Quaternion. + * + * \copyright Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or + * disclosure of this file or its contents without the prior written consent + * of DigiPen Institute of Technology is prohibited. +****************************************************************************************/ + +#pragma once + +#include +#include + +namespace SHADE +{ + /*-----------------------------------------------------------------------------------*/ + /* Forward Declarations */ + /*-----------------------------------------------------------------------------------*/ + + class SHVec3; + class SHMatrix; + + /*-----------------------------------------------------------------------------------*/ + /* Type Definitions */ + /*-----------------------------------------------------------------------------------*/ + + class SHQuaternion : public DirectX::XMFLOAT4 + { + public: + /*---------------------------------------------------------------------------------*/ + /* Static Data Members */ + /*---------------------------------------------------------------------------------*/ + + static const SHQuaternion Identity; + + /*---------------------------------------------------------------------------------*/ + /* Constructors & Destructor */ + /*---------------------------------------------------------------------------------*/ + + SHQuaternion (const SHQuaternion& rhs) = default; + SHQuaternion (SHQuaternion&& rhs) = default; + + SHQuaternion () noexcept; + SHQuaternion (float x, float y, float z, float w) noexcept; + SHQuaternion (float yaw, float pitch, float roll) noexcept; + SHQuaternion (const SHVec3& eulerAngles) noexcept; + SHQuaternion (const SHVec3& axis, float angleInRad) noexcept; + SHQuaternion (const SHMatrix& rotationMatrix) noexcept; + + /*---------------------------------------------------------------------------------*/ + /* Operator Overloads */ + /*---------------------------------------------------------------------------------*/ + + [[nodiscard]] SHQuaternion& operator= (const SHQuaternion& rhs) = default; + [[nodiscard]] SHQuaternion& operator= (SHQuaternion&& rhs) = default; + + [[nodiscard]] SHQuaternion& operator+= (const SHQuaternion& rhs) noexcept; + [[nodiscard]] SHQuaternion& operator-= (const SHQuaternion& rhs) noexcept; + [[nodiscard]] SHQuaternion& operator*= (const SHQuaternion& rhs) noexcept; + [[nodiscard]] SHQuaternion& operator*= (float rhs) noexcept; + [[nodiscard]] SHQuaternion& operator/= (const SHQuaternion& rhs) noexcept; + + [[nodiscard]] SHQuaternion operator+ (const SHQuaternion& rhs) const noexcept; + [[nodiscard]] SHQuaternion operator- (const SHQuaternion& rhs) const noexcept; + [[nodiscard]] SHQuaternion operator- () const noexcept; + [[nodiscard]] SHQuaternion operator* (const SHQuaternion& rhs) const noexcept; + [[nodiscard]] SHQuaternion operator* (float rhs) const noexcept; + [[nodiscard]] SHQuaternion operator/ (const SHQuaternion& rhs) const noexcept; + + [[nodiscard]] bool operator== (const SHQuaternion& rhs) const noexcept; + [[nodiscard]] bool operator!= (const SHQuaternion& rhs) const noexcept; + + /*---------------------------------------------------------------------------------*/ + /* Function Members */ + /*---------------------------------------------------------------------------------*/ + + void Invert () noexcept; + + [[nodiscard]] float Length () const noexcept; + [[nodiscard]] float LengthSquared () const noexcept; + [[nodiscard]] float Dot (const SHQuaternion& rhs) const noexcept; + [[nodiscard]] SHQuaternion RotateTowards (const SHQuaternion& target, float maxAngleInRad) const noexcept; + + [[nodiscard]] SHVec3 ToEuler () const noexcept; + [[nodiscard]] std::string ToString () const noexcept; + + /*---------------------------------------------------------------------------------*/ + /* Static Function Members */ + /*---------------------------------------------------------------------------------*/ + + [[nodiscard]] static SHQuaternion Normalise (const SHQuaternion& q) noexcept; + [[nodiscard]] static SHQuaternion Conjugate (const SHQuaternion& q) noexcept; + [[nodiscard]] static SHQuaternion Angle (const SHQuaternion& q1, const SHQuaternion& q2) noexcept; + + [[nodiscard]] static SHQuaternion Lerp (const SHQuaternion& q1, const SHQuaternion& q2, float t) noexcept; + [[nodiscard]] static SHQuaternion Slerp (const SHQuaternion& q1, const SHQuaternion& q2, float t) noexcept; + + [[nodiscard]] static SHQuaternion Concat (const SHQuaternion& q1, const SHQuaternion& q2) noexcept; + [[nodiscard]] static SHQuaternion Rotate (const SHVec3& from, const SHVec3& to) noexcept; + }; + + SHQuaternion operator*(float lhs, const SHQuaternion& rhs) noexcept; + +} // namespace SHADE \ No newline at end of file diff --git a/SHADE_Engine/src/Math/Vector/SHVec2.cpp b/SHADE_Engine/src/Math/Vector/SHVec2.cpp new file mode 100644 index 00000000..72c80a50 --- /dev/null +++ b/SHADE_Engine/src/Math/Vector/SHVec2.cpp @@ -0,0 +1,460 @@ +/**************************************************************************************** + * \file SHVec2.cpp + * \author Diren D Bharwani, diren.dbharwani, 390002520 + * \brief Implementation for 2D Vector. + * + * \copyright Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or + * disclosure of this file or its contents without the prior written consent + * of DigiPen Institute of Technology is prohibited. +****************************************************************************************/ + +#include + +// Primary Header +#include "SHVec2.h" +// Project Headers +#include "Math/SHMatrix.h" +#include "Tools/SHLogger.h" + +using namespace DirectX; + +namespace SHADE +{ + /*-----------------------------------------------------------------------------------*/ + /* Static Data Member Definitions */ + /*-----------------------------------------------------------------------------------*/ + SHVec2 const SHVec2::Zero { 0.0f, 0.0f }; + SHVec2 const SHVec2::One { 1.0f, 1.0f }; + SHVec2 const SHVec2::Left { -1.0f, 0.0f }; + SHVec2 const SHVec2::Right { 1.0f, 0.0f }; + SHVec2 const SHVec2::Up { 0.0f, 1.0f }; + SHVec2 const SHVec2::Down { 0.0f, -1.0f }; + + /*-----------------------------------------------------------------------------------*/ + /* Constructors & Destructor Definitions */ + /*-----------------------------------------------------------------------------------*/ + + SHVec2::SHVec2() noexcept + : XMFLOAT2( 0.0f, 0.0f ) + {} + + SHVec2::SHVec2(float _x, float _y) noexcept + : XMFLOAT2( _x, _y ) + {} + + /*-----------------------------------------------------------------------------------*/ + /* Operator Overload Definitions */ + /*-----------------------------------------------------------------------------------*/ + + SHVec2& SHVec2::operator+=(const SHVec2& rhs) noexcept + { + return *this = *this + rhs; + } + + SHVec2& SHVec2::operator-=(const SHVec2& rhs) noexcept + { + return *this = *this - rhs; + } + + SHVec2& SHVec2::operator*=(const SHVec2& rhs) noexcept + { + return *this = *this * rhs; + } + + SHVec2& SHVec2::operator*=(float rhs) noexcept + { + return *this = *this * rhs; + } + + SHVec2& SHVec2::operator/=(const SHVec2& rhs) noexcept + { + return *this = *this / rhs; + } + + SHVec2& SHVec2::operator/=(float rhs) noexcept + { + return *this = *this / rhs; + } + + SHVec2 SHVec2::operator+(const SHVec2& rhs) const noexcept + { + SHVec2 result; + + const XMVECTOR V1 = XMLoadFloat2(this); + const XMVECTOR V2 = XMLoadFloat2(&rhs); + + XMStoreFloat2(&result, XMVectorAdd(V1, V2)); + return result; + } + + SHVec2 SHVec2::operator-(const SHVec2& rhs) const noexcept + { + SHVec2 result; + + const XMVECTOR V1 = XMLoadFloat2(this); + const XMVECTOR V2 = XMLoadFloat2(&rhs); + + XMStoreFloat2(&result, XMVectorSubtract(V1, V2)); + return result; + } + + SHVec2 SHVec2::operator-() const noexcept + { + return SHVec2{ -x, -y }; + } + + SHVec2 SHVec2::operator*(const SHVec2& rhs) const noexcept + { + SHVec2 result; + + const XMVECTOR V1 = XMLoadFloat2(this); + const XMVECTOR V2 = XMLoadFloat2(&rhs); + + XMStoreFloat2(&result, XMVectorMultiply(V1, V2)); + return result; + } + + SHVec2 SHVec2::operator*(float rhs) const noexcept + { + SHVec2 result; + + const XMVECTOR V = XMLoadFloat2(this); + + XMStoreFloat2(&result, XMVectorScale(V, rhs)); + return result; + } + + SHVec2 SHVec2::operator/(const SHVec2& rhs) const noexcept + { + SHVec2 result; + + const XMVECTOR V1 = XMLoadFloat2(this); + const XMVECTOR V2 = XMLoadFloat2(&rhs); + + XMStoreFloat2(&result, XMVectorDivide(V1, V2)); + return result; + } + + SHVec2 SHVec2::operator/(float rhs) const noexcept + { + SHVec2 result; + + const XMVECTOR V = XMLoadFloat2(this); + + XMStoreFloat2(&result, XMVectorScale(V, 1.0f / rhs)); + return result; + } + + bool SHVec2::operator==(const SHVec2& rhs) const noexcept + { + const XMVECTOR V1 = XMLoadFloat2(this); + const XMVECTOR V2 = XMLoadFloat2(&rhs); + + return XMVector2Equal(V1, V2); + } + + bool SHVec2::operator!=(const SHVec2& rhs) const noexcept + { + const XMVECTOR V1 = XMLoadFloat2(this); + const XMVECTOR V2 = XMLoadFloat2(&rhs); + + return XMVector2NotEqual(V1, V2); + } + + float SHVec2::operator[](int index) + { + if (index >= SIZE || index < 0) + throw std::invalid_argument("Index out of range!"); + + switch (index) + { + case 0: return x; + case 1: return y; + default: return 0.0f; + } + } + + float SHVec2::operator[](size_t index) + { + if (index >= SIZE) + throw std::invalid_argument("Index out of range!"); + + switch (index) + { + case 0: return x; + case 1: return y; + default: return 0.0f; + } + } + + float SHVec2::operator[](int index) const + { + if (index >= SIZE || index < 0) + throw std::invalid_argument("Index out of range!"); + + switch (index) + { + case 0: return x; + case 1: return y; + default: return 0.0f; + } + } + + float SHVec2::operator[](size_t index) const + { + if (index >= SIZE) + throw std::invalid_argument("Index out of range!"); + + switch (index) + { + case 0: return x; + case 1: return y; + default: return 0.0f; + } + } + + SHVec2 operator* (float lhs, const SHVec2& rhs) noexcept + { + SHVec2 result; + + const XMVECTOR V = XMLoadFloat2(&rhs); + + XMStoreFloat2(&result, XMVectorScale(V, lhs)); + return result; + } + + /*-----------------------------------------------------------------------------------*/ + /* Function Member Definitions */ + /*-----------------------------------------------------------------------------------*/ + + float SHVec2::Length() const noexcept + { + const XMVECTOR V = XMLoadFloat2(this); + + return XMVectorGetX(XMVector2Length(V)); + } + + float SHVec2::LengthSquared() const noexcept + { + const XMVECTOR V = XMLoadFloat2(this); + + return XMVectorGetX(XMVector2LengthSq(V)); + } + + std::string SHVec2::ToString() const noexcept + { + std::stringstream ss; + ss << std::fixed << std::setprecision(3); + ss << "<" << x << ", " << y << ">"; + return ss.str(); + } + + float SHVec2::Dot(const SHVec2& rhs) const noexcept + { + const XMVECTOR V1 = XMLoadFloat2(this); + const XMVECTOR V2 = XMLoadFloat2(&rhs); + + return XMVectorGetX(XMVector2Dot(V1, V2)); + } + + SHVec2 SHVec2::Cross(const SHVec2& rhs) const noexcept + { + SHVec2 result; + + const XMVECTOR V1 = XMLoadFloat2(this); + const XMVECTOR V2 = XMLoadFloat2(&rhs); + + XMStoreFloat2(&result, XMVector2Cross(V1, V2)); + return result; + } + + /*-----------------------------------------------------------------------------------*/ + /* Static Function Member Definitions */ + /*-----------------------------------------------------------------------------------*/ + + SHVec2 SHVec2::Normalise(const SHVec2& vec2) noexcept + { + SHVec2 result; + + const XMVECTOR V = XMLoadFloat2(&vec2); + + XMStoreFloat2(&result, XMVector2Normalize(V)); + return result; + } + + SHVec2 SHVec2::Abs(const SHVec2& vec2) noexcept + { + return SHVec2{ std::fabs(vec2.x), std::fabs(vec2.y) }; + } + + SHVec2 SHVec2::Min(const std::initializer_list& vec2s) noexcept + { + if (vec2s.size() == 0) + { + SHLOG_WARNING("No arguments passed in! Min value is a default SHVec2.") + return SHVec2{}; + } + + SHVec2 result; + + XMVECTOR min = XMLoadFloat2(&(*vec2s.begin())); + for (auto it = vec2s.begin() + 1; it != vec2s.end(); ++it) + { + const XMVECTOR tmp = XMLoadFloat2(&(*it)); + min = XMVectorMin(min, tmp); + } + + XMStoreFloat2(&result, min); + return result; + } + + SHVec2 SHVec2::Max(const std::initializer_list& vec2s) noexcept + { + if (vec2s.size() == 0) + { + SHLOG_WARNING("No arguments passed in! Max value is a default SHVec2.") + return SHVec2{}; + } + + SHVec2 result; + + XMVECTOR max = XMLoadFloat2(&(*vec2s.begin())); + for (auto it = vec2s.begin() + 1; it != vec2s.end(); ++it) + { + const XMVECTOR tmp = XMLoadFloat2(&(*it)); + max = XMVectorMax(max, tmp); + } + + XMStoreFloat2(&result, max); + return result; + } + + SHVec2 SHVec2::Clamp(const SHVec2& v, const SHVec2& vMin, const SHVec2& vMax) noexcept + { + SHVec2 result; + + const XMVECTOR V = XMLoadFloat2(&v); + const XMVECTOR MIN = XMLoadFloat2(&vMin); + const XMVECTOR MAX = XMLoadFloat2(&vMax); + + XMStoreFloat2(&result, XMVectorClamp(V, MIN, MAX)); + return result; + } + + SHVec2 SHVec2::Lerp(const SHVec2& a, const SHVec2& b, float t) noexcept + { + SHVec2 result; + + const XMVECTOR V1 = XMLoadFloat2(&a); + const XMVECTOR V2 = XMLoadFloat2(&b); + + XMStoreFloat2(&result, XMVectorLerp(V1, V2, t)); + return result; + } + + SHVec2 SHVec2::ClampedLerp(const SHVec2& a, const SHVec2& b, float t, float tMin, float tMax) noexcept + { + return Lerp(a, b, std::clamp(t, tMin, tMax)); + } + + float SHVec2::Distance(const SHVec2& lhs, const SHVec2& rhs) noexcept + { + return (lhs - rhs).Length(); + } + + float SHVec2::DistanceSquared(const SHVec2& lhs, const SHVec2& rhs) noexcept + { + return (lhs - rhs).LengthSquared(); + } + + float SHVec2::Angle(const SHVec2& lhs, const SHVec2& rhs) noexcept + { + const XMVECTOR V1 = XMLoadFloat2(&lhs); + const XMVECTOR V2 = XMLoadFloat2(&rhs); + + return XMVectorGetX(XMVector2AngleBetweenVectors(V1, V2)); + } + + float SHVec2::Dot(const SHVec2& lhs, const SHVec2& rhs) noexcept + { + return lhs.Dot(rhs); + } + + SHVec2 SHVec2::Project(const SHVec2& v, const SHVec2& u) noexcept + { + SHVec2 result; + + const XMVECTOR U = XMLoadFloat2(&u); + const float V_DOT_U = Dot(v, u); + const float U_LENSQ = u.LengthSquared(); + + XMStoreFloat2(&result, XMVectorScale(U, V_DOT_U / U_LENSQ)); + return result; + } + + SHVec2 SHVec2::Reflect(const SHVec2& v, const SHVec2& normal) noexcept + { + SHVec2 result; + + const XMVECTOR V = XMLoadFloat2(&v); + const XMVECTOR N = XMLoadFloat2(&normal); + + XMStoreFloat2(&result, XMVector2Reflect(V, N)); + return result; + } + + SHVec2 SHVec2::Rotate(const SHVec2& v, float angleInRad) noexcept + { + SHVec2 result; + + const XMVECTOR V = XMLoadFloat2(&v); + const XMMATRIX R = XMMatrixRotationZ(angleInRad); + + XMStoreFloat2(&result, XMVector2Transform(V, R)); + return result; + } + + SHVec2 SHVec2::Transform(const SHVec2& v, const SHMatrix& transformMtx) noexcept + { + SHVec2 result; + + const XMVECTOR V = XMLoadFloat2(&v); + const XMMATRIX TF = XMLoadFloat4x4(&transformMtx); + + XMStoreFloat2(&result, XMVector2TransformCoord(V, TF)); + return result; + } + + SHVec2 SHVec2::Cross(float lhs, const SHVec2& rhs) noexcept + { + SHVec2 result; + + const XMFLOAT3 LHS { 0.0f, 0.0f, lhs }; + const XMFLOAT3 RHS { rhs.x, rhs.y, 0.0f }; + + const XMVECTOR V1 = XMLoadFloat3(&LHS); + const XMVECTOR V2 = XMLoadFloat3(&RHS); + + XMStoreFloat2(&result, XMVector3Cross(V1, V2)); + return result; + } + + SHVec2 SHVec2::Cross(const SHVec2& lhs, float rhs) noexcept + { + SHVec2 result; + + const XMFLOAT3 LHS { lhs.x, lhs.y, 0.0f }; + const XMFLOAT3 RHS { 0.0f, 0.0f, rhs }; + + const XMVECTOR V1 = XMLoadFloat3(&LHS); + const XMVECTOR V2 = XMLoadFloat3(&RHS); + + XMStoreFloat2(&result, XMVector3Cross(V1, V2)); + return result; + } + + float SHVec2::Cross(const SHVec2& lhs, const SHVec2& rhs) noexcept + { + return (lhs.x * rhs.y) - (lhs.y * rhs.x); + } +} \ No newline at end of file diff --git a/SHADE_Engine/src/Math/Vector/SHVec2.h b/SHADE_Engine/src/Math/Vector/SHVec2.h new file mode 100644 index 00000000..a64d4bb0 --- /dev/null +++ b/SHADE_Engine/src/Math/Vector/SHVec2.h @@ -0,0 +1,122 @@ +/**************************************************************************************** + * \file SHVec2.h + * \author Diren D Bharwani, diren.dbharwani, 390002520 + * \brief Interface for 2D Vector. + * + * \copyright Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or + * disclosure of this file or its contents without the prior written consent + * of DigiPen Institute of Technology is prohibited. +****************************************************************************************/ + +#pragma once + +#include +#include +#include + +namespace SHADE +{ + /*-----------------------------------------------------------------------------------*/ + /* Forward Declarations */ + /*-----------------------------------------------------------------------------------*/ + class SHMatrix; + + /*-----------------------------------------------------------------------------------*/ + /* Type Definitions */ + /*-----------------------------------------------------------------------------------*/ + + class SHVec2 : public DirectX::XMFLOAT2 + { + public: + /*---------------------------------------------------------------------------------*/ + /* Static Data Members */ + /*---------------------------------------------------------------------------------*/ + + static constexpr size_t SIZE = 2U; + + static const SHVec2 Zero; + static const SHVec2 One; + static const SHVec2 Left; + static const SHVec2 Right; + static const SHVec2 Up; + static const SHVec2 Down; + + /*---------------------------------------------------------------------------------*/ + /* Constructors & Destructor */ + /*---------------------------------------------------------------------------------*/ + + SHVec2 (const SHVec2& rhs) = default; + SHVec2 (SHVec2&& rhs) = default; + ~SHVec2 () = default; + + SHVec2 () noexcept; + SHVec2 (float x, float y) noexcept; + + /*---------------------------------------------------------------------------------*/ + /* Operator Overloads */ + /*---------------------------------------------------------------------------------*/ + + [[nodiscard]] SHVec2& operator= (const SHVec2& rhs) = default; + [[nodiscard]] SHVec2& operator= (SHVec2&& rhs) = default; + + [[nodiscard]] SHVec2& operator+= (const SHVec2& rhs) noexcept; + [[nodiscard]] SHVec2& operator-= (const SHVec2& rhs) noexcept; + [[nodiscard]] SHVec2& operator*= (const SHVec2& rhs) noexcept; + [[nodiscard]] SHVec2& operator*= (float rhs) noexcept; + [[nodiscard]] SHVec2& operator/= (const SHVec2& rhs) noexcept; + [[nodiscard]] SHVec2& operator/= (float rhs) noexcept; + + [[nodiscard]] SHVec2 operator+ (const SHVec2& rhs) const noexcept; + [[nodiscard]] SHVec2 operator- (const SHVec2& rhs) const noexcept; + [[nodiscard]] SHVec2 operator- () const noexcept; + [[nodiscard]] SHVec2 operator* (const SHVec2& rhs) const noexcept; + [[nodiscard]] SHVec2 operator* (float rhs) const noexcept; + [[nodiscard]] SHVec2 operator/ (const SHVec2& rhs) const noexcept; + [[nodiscard]] SHVec2 operator/ (float rhs) const noexcept; + + [[nodiscard]] bool operator== (const SHVec2& rhs) const noexcept; + [[nodiscard]] bool operator!= (const SHVec2& rhs) const noexcept; + + [[nodiscard]] float operator[] (int index); + [[nodiscard]] float operator[] (size_t index); + [[nodiscard]] float operator[] (int index) const; + [[nodiscard]] float operator[] (size_t index) const; + + /*---------------------------------------------------------------------------------*/ + /* Function Members */ + /*---------------------------------------------------------------------------------*/ + + [[nodiscard]] float Length () const noexcept; + [[nodiscard]] float LengthSquared () const noexcept; + [[nodiscard]] std::string ToString () const noexcept; + + [[nodiscard]] float Dot (const SHVec2& rhs) const noexcept; + [[nodiscard]] SHVec2 Cross (const SHVec2& rhs) const noexcept; + /*---------------------------------------------------------------------------------*/ + /* Static Function Members */ + /*---------------------------------------------------------------------------------*/ + + [[nodiscard]] static SHVec2 Normalise (const SHVec2& vec2) noexcept; + [[nodiscard]] static SHVec2 Abs (const SHVec2& vec2) noexcept; + [[nodiscard]] static SHVec2 Min (const std::initializer_list& vec2s) noexcept; + [[nodiscard]] static SHVec2 Max (const std::initializer_list& vec2s) noexcept; + [[nodiscard]] static SHVec2 Clamp (const SHVec2& v, const SHVec2& vMin, const SHVec2& vMax) noexcept; + [[nodiscard]] static SHVec2 Lerp (const SHVec2& a, const SHVec2& b, float t) noexcept; + [[nodiscard]] static SHVec2 ClampedLerp (const SHVec2& a, const SHVec2& b, float t, float tMin = 0.0f, float tMax = 1.0f) noexcept; + + [[nodiscard]] static float Distance (const SHVec2& lhs, const SHVec2& rhs) noexcept; + [[nodiscard]] static float DistanceSquared (const SHVec2& lhs, const SHVec2& rhs) noexcept; + [[nodiscard]] static float Angle (const SHVec2& lhs, const SHVec2& rhs) noexcept; + [[nodiscard]] static float Dot (const SHVec2& lhs, const SHVec2& rhs) noexcept; + [[nodiscard]] static SHVec2 Project (const SHVec2& v, const SHVec2& u) noexcept; + [[nodiscard]] static SHVec2 Reflect (const SHVec2& v, const SHVec2& normal) noexcept; + [[nodiscard]] static SHVec2 Rotate (const SHVec2& v, float angleInRad) noexcept; + [[nodiscard]] static SHVec2 Transform (const SHVec2& v, const SHMatrix& transformMtx) noexcept; + [[nodiscard]] static SHVec2 Cross (float lhs, const SHVec2& rhs) noexcept; + [[nodiscard]] static SHVec2 Cross (const SHVec2& lhs, float rhs) noexcept; + [[nodiscard]] static float Cross (const SHVec2& lhs, const SHVec2& rhs) noexcept; + }; + + SHVec2 operator* (float lhs, const SHVec2& rhs) noexcept; + +} // namespace SHADE \ No newline at end of file diff --git a/SHADE_Engine/src/Math/Vector/SHVec3.cpp b/SHADE_Engine/src/Math/Vector/SHVec3.cpp new file mode 100644 index 00000000..73030f9c --- /dev/null +++ b/SHADE_Engine/src/Math/Vector/SHVec3.cpp @@ -0,0 +1,477 @@ +/**************************************************************************************** + * \file SHVec3.cpp + * \author Diren D Bharwani, diren.dbharwani, 390002520 + * \brief Implementation for 3D Vector. + * + * \copyright Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or + * disclosure of this file or its contents without the prior written consent + * of DigiPen Institute of Technology is prohibited. +****************************************************************************************/ + +#include + +// Primary Header +#include "SHVec3.h" +// Project Headers +#include "Math/SHMatrix.h" +#include "Tools/SHLogger.h" + +using namespace DirectX; + +namespace SHADE +{ + /*-----------------------------------------------------------------------------------*/ + /* Static Data Member Definitions */ + /*-----------------------------------------------------------------------------------*/ + SHVec3 const SHVec3::Zero { 0.0f, 0.0f, 0.0f }; + SHVec3 const SHVec3::One { 1.0f, 1.0f, 1.0f }; + SHVec3 const SHVec3::Left { -1.0f, 0.0f, 0.0f }; + SHVec3 const SHVec3::Right { 1.0f, 0.0f, 0.0f }; + SHVec3 const SHVec3::Up { 0.0f, 1.0f, 0.0f }; + SHVec3 const SHVec3::Down { 0.0f, -1.0f, 0.0f }; + SHVec3 const SHVec3::Forward { 0.0f, 0.0f, 1.0f }; + SHVec3 const SHVec3::Back { 0.0f, 0.0f, -1.0f }; + SHVec3 const SHVec3::UnitX { 1.0f, 0.0f, 0.0f }; + SHVec3 const SHVec3::UnitY { 0.0f, 1.0f, 0.0f }; + SHVec3 const SHVec3::UnitZ { 0.0f, 0.0f, 1.0f }; + + /*-----------------------------------------------------------------------------------*/ + /* Constructors & Destructor Definitions */ + /*-----------------------------------------------------------------------------------*/ + + SHVec3::SHVec3() noexcept + : XMFLOAT3( 0.0f, 0.0f, 0.0f ) + {} + + SHVec3::SHVec3(float _x, float _y, float _z) noexcept + : XMFLOAT3( _x, _y, _z ) + {} + + /*-----------------------------------------------------------------------------------*/ + /* Operator Overload Definitions */ + /*-----------------------------------------------------------------------------------*/ + + SHVec3& SHVec3::operator+=(const SHVec3& rhs) noexcept + { + return *this = *this + rhs; + } + + SHVec3& SHVec3::operator-=(const SHVec3& rhs) noexcept + { + return *this = *this - rhs; + } + + SHVec3& SHVec3::operator*=(const SHVec3& rhs) noexcept + { + return *this = *this * rhs; + } + + SHVec3& SHVec3::operator*=(float rhs) noexcept + { + return *this = *this * rhs; + } + + SHVec3& SHVec3::operator/=(const SHVec3& rhs) noexcept + { + return *this = *this / rhs; + } + + SHVec3& SHVec3::operator/=(float rhs) noexcept + { + return *this = *this / rhs; + } + + SHVec3 SHVec3::operator+(const SHVec3& rhs) const noexcept + { + SHVec3 result; + + const XMVECTOR V1 = XMLoadFloat3(this); + const XMVECTOR V2 = XMLoadFloat3(&rhs); + + XMStoreFloat3(&result, XMVectorAdd(V1, V2)); + return result; + } + + SHVec3 SHVec3::operator-(const SHVec3& rhs) const noexcept + { + SHVec3 result; + + const XMVECTOR V1 = XMLoadFloat3(this); + const XMVECTOR V2 = XMLoadFloat3(&rhs); + + XMStoreFloat3(&result, XMVectorSubtract(V1, V2)); + return result; + } + + SHVec3 SHVec3::operator-() const noexcept + { + return SHVec3{ -x, -y, -z }; + } + + + SHVec3 SHVec3::operator*(const SHVec3& rhs) const noexcept + { + SHVec3 result; + + const XMVECTOR V1 = XMLoadFloat3(this); + const XMVECTOR V2 = XMLoadFloat3(&rhs); + + XMStoreFloat3(&result, XMVectorMultiply(V1, V2)); + return result; + } + + SHVec3 SHVec3::operator*(float rhs) const noexcept + { + SHVec3 result; + + const XMVECTOR V = XMLoadFloat3(this); + + XMStoreFloat3(&result, XMVectorScale(V, rhs)); + return result; + } + + SHVec3 SHVec3::operator/(const SHVec3& rhs) const noexcept + { + SHVec3 result; + + const XMVECTOR V1 = XMLoadFloat3(this); + const XMVECTOR V2 = XMLoadFloat3(&rhs); + + XMStoreFloat3(&result, XMVectorDivide(V1, V2)); + return result; + } + + SHVec3 SHVec3::operator/(float rhs) const noexcept + { + SHVec3 result; + + const XMVECTOR V = XMLoadFloat3(this); + + XMStoreFloat3(&result, XMVectorScale(V, 1.0f / rhs)); + return result; + } + + bool SHVec3::operator==(const SHVec3& rhs) const noexcept + { + const XMVECTOR V1 = XMLoadFloat3(this); + const XMVECTOR V2 = XMLoadFloat3(&rhs); + + return XMVector3Equal(V1, V2); + } + + bool SHVec3::operator!=(const SHVec3& rhs) const noexcept + { + const XMVECTOR V1 = XMLoadFloat3(this); + const XMVECTOR V2 = XMLoadFloat3(&rhs); + + return XMVector3NotEqual(V1, V2); + } + + float SHVec3::operator[](int index) + { + if (index >= SIZE || index < 0) + throw std::invalid_argument("Index out of range!"); + + switch (index) + { + case 0: return x; + case 1: return y; + case 2: return z; + default: return 0.0f; + } + } + + float SHVec3::operator[](size_t index) + { + if (index >= SIZE) + throw std::invalid_argument("Index out of range!"); + + switch (index) + { + case 0: return x; + case 1: return y; + case 2: return z; + default: return 0.0f; + } + } + + float SHVec3::operator[](int index) const + { + if (index >= SIZE || index < 0) + throw std::invalid_argument("Index out of range!"); + + switch (index) + { + case 0: return x; + case 1: return y; + case 2: return z; + default: return 0.0f; + } + } + + float SHVec3::operator[](size_t index) const + { + if (index >= SIZE) + throw std::invalid_argument("Index out of range!"); + + switch (index) + { + case 0: return x; + case 1: return y; + case 2: return z; + default: return 0.0f; + } + } + + SHVec3 operator* (float lhs, const SHVec3& rhs) noexcept + { + SHVec3 result; + + const XMVECTOR V = XMLoadFloat3(&rhs); + + XMStoreFloat3(&result, XMVectorScale(V, lhs)); + return result; + } + + /*-----------------------------------------------------------------------------------*/ + /* Function Member Definitions */ + /*-----------------------------------------------------------------------------------*/ + + float SHVec3::Length() const noexcept + { + const XMVECTOR V = XMLoadFloat3(this); + + return XMVectorGetX(XMVector3Length(V)); + } + + float SHVec3::LengthSquared() const noexcept + { + const XMVECTOR V = XMLoadFloat3(this); + + return XMVectorGetX(XMVector3LengthSq(V)); + } + + std::string SHVec3::ToString() const noexcept + { + std::stringstream ss; + ss << std::fixed << std::setprecision(3); + ss << "<" << x << ", " << y << ", " << z << ">"; + return ss.str(); + } + + float SHVec3::Dot(const SHVec3& rhs) const noexcept + { + const XMVECTOR V1 = XMLoadFloat3(this); + const XMVECTOR V2 = XMLoadFloat3(&rhs); + + return XMVectorGetX(XMVector3Dot(V1, V2)); + } + + SHVec3 SHVec3::Cross(const SHVec3& rhs) const noexcept + { + SHVec3 result; + + const XMVECTOR V1 = XMLoadFloat3(this); + const XMVECTOR V2 = XMLoadFloat3(&rhs); + + XMStoreFloat3(&result, XMVector3Cross(V1, V2)); + return result; + } + + /*-----------------------------------------------------------------------------------*/ + /* Static Function Member Definitions */ + /*-----------------------------------------------------------------------------------*/ + + SHVec3 SHVec3::Normalise(const SHVec3& v) noexcept + { + SHVec3 result; + + const XMVECTOR V = XMLoadFloat3(&v); + + XMStoreFloat3(&result, XMVector3Normalize(V)); + return result; + } + + SHVec3 SHVec3::Abs(const SHVec3& v) noexcept + { + return SHVec3{ std::fabs(v.x), std::fabs(v.y), std::fabs(v.z) }; + } + + SHVec3 SHVec3::Min(const std::initializer_list& vs) noexcept + { + if (vs.size() == 0) + { + SHLOG_WARNING("No arguments passed in! Min value is a default SHVec3.") + return SHVec3{}; + } + + SHVec3 result; + + XMVECTOR min = XMLoadFloat3(&(*vs.begin())); + for (auto it = vs.begin() + 1; it != vs.end(); ++it) + { + const XMVECTOR tmp = XMLoadFloat3(&(*it)); + min = XMVectorMin(min, tmp); + } + + XMStoreFloat3(&result, min); + return result; + } + + SHVec3 SHVec3::Max(const std::initializer_list& vs) noexcept + { + if (vs.size() == 0) + { + SHLOG_WARNING("No arguments passed in! Max value is a default SHVec3.") + return SHVec3{}; + } + + SHVec3 result; + + XMVECTOR max = XMLoadFloat3(&(*vs.begin())); + for (auto it = vs.begin() + 1; it != vs.end(); ++it) + { + const XMVECTOR tmp = XMLoadFloat3(&(*it)); + max = XMVectorMax(max, tmp); + } + + XMStoreFloat3(&result, max); + return result; + } + + SHVec3 SHVec3::Clamp(const SHVec3& v, const SHVec3& vMin, const SHVec3& vMax) noexcept + { + SHVec3 result; + + const XMVECTOR V = XMLoadFloat3(&v); + const XMVECTOR MIN = XMLoadFloat3(&vMin); + const XMVECTOR MAX = XMLoadFloat3(&vMax); + + XMStoreFloat3(&result, XMVectorClamp(V, MIN, MAX)); + return result; + } + + SHVec3 SHVec3::Lerp(const SHVec3& a, const SHVec3& b, float t) noexcept + { + SHVec3 result; + + const XMVECTOR V1 = XMLoadFloat3(&a); + const XMVECTOR V2 = XMLoadFloat3(&b); + + XMStoreFloat3(&result, XMVectorLerp(V1, V2, t)); + return result; + } + + SHVec3 SHVec3::ClampedLerp(const SHVec3& a, const SHVec3& b, float t, float tMin, float tMax) noexcept + { + return Lerp(a, b, std::clamp(t, tMin, tMax)); + } + + float SHVec3::Distance(const SHVec3& lhs, const SHVec3& rhs) noexcept + { + return (lhs - rhs).Length(); + } + + float SHVec3::DistanceSquared(const SHVec3& lhs, const SHVec3& rhs) noexcept + { + return (lhs - rhs).LengthSquared(); + } + + float SHVec3::Angle(const SHVec3& lhs, const SHVec3& rhs) noexcept + { + const XMVECTOR V1 = XMLoadFloat3(&lhs); + const XMVECTOR V2 = XMLoadFloat3(&rhs); + + return XMVectorGetX(XMVector3AngleBetweenVectors(V1, V2)); + } + + float SHVec3::Dot(const SHVec3& lhs, const SHVec3& rhs) noexcept + { + return lhs.Dot(rhs); + } + + SHVec3 SHVec3::Cross(const SHVec3& lhs, const SHVec3& rhs) noexcept + { + return lhs.Cross(rhs); + } + + SHVec3 SHVec3::Project(const SHVec3& v, const SHVec3& u) noexcept + { + SHVec3 result; + + const XMVECTOR U = XMLoadFloat3(&u); + const float V_DOT_U = Dot(v, u); + const float U_LENSQ = u.LengthSquared(); + + XMStoreFloat3(&result, XMVectorScale(U, V_DOT_U / U_LENSQ)); + return result; + } + + SHVec3 SHVec3::Reflect(const SHVec3& v, const SHVec3& normal) noexcept + { + SHVec3 result; + + const XMVECTOR V = XMLoadFloat3(&v); + const XMVECTOR N = XMLoadFloat3(&normal); + + XMStoreFloat3(&result, XMVector3Reflect(V, N)); + return result; + } + + SHVec3 SHVec3::Rotate(const SHVec3& v, const SHVec3& axis, float angleInRad) noexcept + { + SHVec3 result; + + const XMVECTOR V = XMLoadFloat3(&v); + + const XMVECTOR AXIS = XMLoadFloat3(&axis); + const XMVECTOR Q = XMQuaternionRotationAxis(AXIS, angleInRad); + + XMStoreFloat3(&result, XMVector3Rotate(V, Q)); + return result; + } + + SHVec3 SHVec3::RotateX(const SHVec3& v, float angleInRad) noexcept + { + SHVec3 result; + + const XMVECTOR V = XMLoadFloat3(&v); + const XMMATRIX R = XMMatrixRotationX(angleInRad); + + XMStoreFloat3(&result, XMVector3TransformCoord(V, R)); + return result; + } + + SHVec3 SHVec3::RotateY(const SHVec3& v, float angleInRad) noexcept + { + SHVec3 result; + + const XMVECTOR V = XMLoadFloat3(&v); + const XMMATRIX R = XMMatrixRotationY(angleInRad); + + XMStoreFloat3(&result, XMVector3TransformCoord(V, R)); + return result; + } + + SHVec3 SHVec3::RotateZ(const SHVec3& v, float angleInRad) noexcept + { + SHVec3 result; + + const XMVECTOR V = XMLoadFloat3(&v); + const XMMATRIX R = XMMatrixRotationZ(angleInRad); + + XMStoreFloat3(&result, XMVector3TransformCoord(V, R)); + return result; + } + + SHVec3 SHVec3::Transform(const SHVec3& v, const SHMatrix& transformMtx) noexcept + { + SHVec3 result; + + const XMVECTOR V = XMLoadFloat3(&v); + const XMMATRIX TF = XMLoadFloat4x4(&transformMtx); + + XMStoreFloat3(&result, XMVector3TransformCoord(V, TF)); + return result; + } +} \ No newline at end of file diff --git a/SHADE_Engine/src/Math/Vector/SHVec3.h b/SHADE_Engine/src/Math/Vector/SHVec3.h new file mode 100644 index 00000000..e172e824 --- /dev/null +++ b/SHADE_Engine/src/Math/Vector/SHVec3.h @@ -0,0 +1,129 @@ +/**************************************************************************************** + * \file SHVec3.h + * \author Diren D Bharwani, diren.dbharwani, 390002520 + * \brief Interface for 3D Vector. + * + * \copyright Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or + * disclosure of this file or its contents without the prior written consent + * of DigiPen Institute of Technology is prohibited. +****************************************************************************************/ + +#pragma once + +#include +#include +#include + +namespace SHADE +{ + /*-----------------------------------------------------------------------------------*/ + /* Forward Declarations */ + /*-----------------------------------------------------------------------------------*/ + class SHMatrix; + + /*-----------------------------------------------------------------------------------*/ + /* Type Definitions */ + /*-----------------------------------------------------------------------------------*/ + + class SHVec3 : public DirectX::XMFLOAT3 + { + public: + /*---------------------------------------------------------------------------------*/ + /* Static Data Members */ + /*---------------------------------------------------------------------------------*/ + + static constexpr size_t SIZE = 3U; + + static const SHVec3 Zero; + static const SHVec3 One; + static const SHVec3 Left; + static const SHVec3 Right; + static const SHVec3 Up; + static const SHVec3 Down; + static const SHVec3 Forward; + static const SHVec3 Back; + static const SHVec3 UnitX; + static const SHVec3 UnitY; + static const SHVec3 UnitZ; + + /*---------------------------------------------------------------------------------*/ + /* Constructors & Destructor */ + /*---------------------------------------------------------------------------------*/ + + SHVec3 (const SHVec3& rhs) = default; + SHVec3 (SHVec3&& rhs) = default; + ~SHVec3 () = default; + + SHVec3 () noexcept; + SHVec3 (float x, float y, float z) noexcept; + + /*---------------------------------------------------------------------------------*/ + /* Operator Overloads */ + /*---------------------------------------------------------------------------------*/ + + [[nodiscard]] SHVec3& operator= (const SHVec3& rhs) = default; + [[nodiscard]] SHVec3& operator= (SHVec3&& rhs) = default; + + [[nodiscard]] SHVec3& operator+= (const SHVec3& rhs) noexcept; + [[nodiscard]] SHVec3& operator-= (const SHVec3& rhs) noexcept; + [[nodiscard]] SHVec3& operator*= (const SHVec3& rhs) noexcept; + [[nodiscard]] SHVec3& operator*= (float rhs) noexcept; + [[nodiscard]] SHVec3& operator/= (const SHVec3& rhs) noexcept; + [[nodiscard]] SHVec3& operator/= (float rhs) noexcept; + + [[nodiscard]] SHVec3 operator+ (const SHVec3& rhs) const noexcept; + [[nodiscard]] SHVec3 operator- (const SHVec3& rhs) const noexcept; + [[nodiscard]] SHVec3 operator- () const noexcept; + [[nodiscard]] SHVec3 operator* (const SHVec3& rhs) const noexcept; + [[nodiscard]] SHVec3 operator* (float rhs) const noexcept; + [[nodiscard]] SHVec3 operator/ (const SHVec3& rhs) const noexcept; + [[nodiscard]] SHVec3 operator/ (float rhs) const noexcept; + + [[nodiscard]] bool operator== (const SHVec3& rhs) const noexcept; + [[nodiscard]] bool operator!= (const SHVec3& rhs) const noexcept; + + [[nodiscard]] float operator[] (int index); + [[nodiscard]] float operator[] (size_t index); + [[nodiscard]] float operator[] (int index) const; + [[nodiscard]] float operator[] (size_t index) const; + + + /*---------------------------------------------------------------------------------*/ + /* Function Members */ + /*---------------------------------------------------------------------------------*/ + + [[nodiscard]] float Length () const noexcept; + [[nodiscard]] float LengthSquared () const noexcept; + [[nodiscard]] std::string ToString () const noexcept; + + [[nodiscard]] float Dot (const SHVec3& rhs) const noexcept; + [[nodiscard]] SHVec3 Cross (const SHVec3& rhs) const noexcept; + /*---------------------------------------------------------------------------------*/ + /* Static Function Members */ + /*---------------------------------------------------------------------------------*/ + + [[nodiscard]] static SHVec3 Normalise (const SHVec3& v) noexcept; + [[nodiscard]] static SHVec3 Abs (const SHVec3& v) noexcept; + [[nodiscard]] static SHVec3 Min (const std::initializer_list& vs) noexcept; + [[nodiscard]] static SHVec3 Max (const std::initializer_list& vs) noexcept; + [[nodiscard]] static SHVec3 Clamp (const SHVec3& v, const SHVec3& vMin, const SHVec3& vMax) noexcept; + [[nodiscard]] static SHVec3 Lerp (const SHVec3& a, const SHVec3& b, float t) noexcept; + [[nodiscard]] static SHVec3 ClampedLerp (const SHVec3& a, const SHVec3& b, float t, float tMin = 0.0f, float tMax = 1.0f) noexcept; + + [[nodiscard]] static float Distance (const SHVec3& lhs, const SHVec3& rhs) noexcept; + [[nodiscard]] static float DistanceSquared (const SHVec3& lhs, const SHVec3& rhs) noexcept; + [[nodiscard]] static float Angle (const SHVec3& lhs, const SHVec3& rhs) noexcept; + [[nodiscard]] static float Dot (const SHVec3& lhs, const SHVec3& rhs) noexcept; + [[nodiscard]] static SHVec3 Cross (const SHVec3& lhs, const SHVec3& rhs) noexcept; + [[nodiscard]] static SHVec3 Project (const SHVec3& v, const SHVec3& u) noexcept; + [[nodiscard]] static SHVec3 Reflect (const SHVec3& v, const SHVec3& normal) noexcept; + [[nodiscard]] static SHVec3 Rotate (const SHVec3& v, const SHVec3& axis, float angleInRad) noexcept; + [[nodiscard]] static SHVec3 RotateX (const SHVec3& v, float angleInRad) noexcept; + [[nodiscard]] static SHVec3 RotateY (const SHVec3& v, float angleInRad) noexcept; + [[nodiscard]] static SHVec3 RotateZ (const SHVec3& v, float angleInRad) noexcept; + [[nodiscard]] static SHVec3 Transform (const SHVec3& v, const SHMatrix& transformMtx) noexcept; + }; + + SHVec3 operator* (float lhs, const SHVec3& rhs) noexcept; + +} // namespace SHADE \ No newline at end of file diff --git a/SHADE_Engine/src/Math/Vector/SHVec4.cpp b/SHADE_Engine/src/Math/Vector/SHVec4.cpp new file mode 100644 index 00000000..5d75af33 --- /dev/null +++ b/SHADE_Engine/src/Math/Vector/SHVec4.cpp @@ -0,0 +1,529 @@ +/**************************************************************************************** + * \file SHVec4.cpp + * \author Diren D Bharwani, diren.dbharwani, 390002520 + * \brief Implementation for 4D Vector. + * + * \copyright Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or + * disclosure of this file or its contents without the prior written consent + * of DigiPen Institute of Technology is prohibited. +****************************************************************************************/ + +#include + +// Primary Header +#include "SHVec4.h" +// Project Headers +#include "Math/SHMatrix.h" +#include "Tools/SHLogger.h" + +using namespace DirectX; + +namespace SHADE +{ + /*-----------------------------------------------------------------------------------*/ + /* Static Data Member Definitions */ + /*-----------------------------------------------------------------------------------*/ + SHVec4 const SHVec4::Zero { 0.0f, 0.0f, 0.0f, 0.0f }; + SHVec4 const SHVec4::One { 1.0f, 1.0f, 1.0f, 1.0f }; + SHVec4 const SHVec4::UnitX { 1.0f, 0.0f, 0.0f, 0.0f }; + SHVec4 const SHVec4::UnitY { 0.0f, 1.0f, 0.0f, 0.0f }; + SHVec4 const SHVec4::UnitZ { 0.0f, 0.0f, 1.0f, 0.0f }; + SHVec4 const SHVec4::UnitW { 0.0f, 0.0f, 0.0f, 1.0f }; + + /*-----------------------------------------------------------------------------------*/ + /* Constructors & Destructor Definitions */ + /*-----------------------------------------------------------------------------------*/ + + SHVec4::SHVec4() noexcept + : XMFLOAT4( 0.0f, 0.0f, 0.0f, 0.0f ) + {} + + SHVec4::SHVec4(float _x, float _y, float _z, float _w) noexcept + : XMFLOAT4( _x, _y, _z, _w ) + {} + + /*-----------------------------------------------------------------------------------*/ + /* Operator Overload Definitions */ + /*-----------------------------------------------------------------------------------*/ + + SHVec4& SHVec4::operator+=(const SHVec4& rhs) noexcept + { + return *this = *this + rhs; + } + + SHVec4& SHVec4::operator-=(const SHVec4& rhs) noexcept + { + return *this = *this - rhs; + } + + SHVec4& SHVec4::operator*=(const SHVec4& rhs) noexcept + { + return *this = *this * rhs; + } + + SHVec4& SHVec4::operator*=(float rhs) noexcept + { + return *this = *this * rhs; + } + + SHVec4& SHVec4::operator/=(const SHVec4& rhs) noexcept + { + return *this = *this / rhs; + } + + SHVec4& SHVec4::operator/=(float rhs) noexcept + { + return *this = *this / rhs; + } + + SHVec4 SHVec4::operator+(const SHVec4& rhs) const noexcept + { + SHVec4 result; + + const XMVECTOR V1 = XMLoadFloat4(this); + const XMVECTOR V2 = XMLoadFloat4(&rhs); + + XMStoreFloat4(&result, XMVectorAdd(V1, V2)); + return result; + } + + SHVec4 SHVec4::operator-(const SHVec4& rhs) const noexcept + { + SHVec4 result; + + const XMVECTOR V1 = XMLoadFloat4(this); + const XMVECTOR V2 = XMLoadFloat4(&rhs); + + XMStoreFloat4(&result, XMVectorSubtract(V1, V2)); + return result; + } + + SHVec4 SHVec4::operator-() const noexcept + { + return SHVec4{ -x, -y, -z, -w }; + } + + SHVec4 SHVec4::operator*(const SHVec4& rhs) const noexcept + { + SHVec4 result; + + const XMVECTOR V1 = XMLoadFloat4(this); + const XMVECTOR V2 = XMLoadFloat4(&rhs); + + XMStoreFloat4(&result, XMVectorMultiply(V1, V2)); + return result; + } + + SHVec4 SHVec4::operator*(float rhs) const noexcept + { + SHVec4 result; + + const XMVECTOR V = XMLoadFloat4(this); + + XMStoreFloat4(&result, XMVectorScale(V, rhs)); + return result; + } + + SHVec4 SHVec4::operator/(const SHVec4& rhs) const noexcept + { + SHVec4 result; + + const XMVECTOR V1 = XMLoadFloat4(this); + const XMVECTOR V2 = XMLoadFloat4(&rhs); + + XMStoreFloat4(&result, XMVectorDivide(V1, V2)); + return result; + } + + SHVec4 SHVec4::operator/(float rhs) const noexcept + { + SHVec4 result; + + const XMVECTOR V = XMLoadFloat4(this); + + XMStoreFloat4(&result, XMVectorScale(V, 1.0f / rhs)); + return result; + } + + bool SHVec4::operator==(const SHVec4& rhs) const noexcept + { + const XMVECTOR V1 = XMLoadFloat4(this); + const XMVECTOR V2 = XMLoadFloat4(&rhs); + + return XMVector4Equal(V1, V2); + } + + bool SHVec4::operator!=(const SHVec4& rhs) const noexcept + { + const XMVECTOR V1 = XMLoadFloat4(this); + const XMVECTOR V2 = XMLoadFloat4(&rhs); + + return XMVector4NotEqual(V1, V2); + } + + float SHVec4::operator[](int index) + { + if (index >= SIZE || index < 0) + throw std::invalid_argument("Index out of range!"); + + switch (index) + { + case 0: return x; + case 1: return y; + case 2: return z; + case 3: return w; + default: return 0.0f; + } + } + + float SHVec4::operator[](size_t index) + { + if (index >= SIZE) + throw std::invalid_argument("Index out of range!"); + + switch (index) + { + case 0: return x; + case 1: return y; + case 2: return z; + case 3: return w; + default: return 0.0f; + } + } + + float SHVec4::operator[](int index) const + { + if (index >= SIZE || index < 0) + throw std::invalid_argument("Index out of range!"); + + switch (index) + { + case 0: return x; + case 1: return y; + case 2: return z; + case 3: return w; + default: return 0.0f; + } + } + + float SHVec4::operator[](size_t index) const + { + if (index >= SIZE) + throw std::invalid_argument("Index out of range!"); + + switch (index) + { + case 0: return x; + case 1: return y; + case 2: return z; + case 3: return w; + default: return 0.0f; + } + } + + SHVec4 operator* (float lhs, const SHVec4& rhs) noexcept + { + SHVec4 result; + + const XMVECTOR V = XMLoadFloat4(&rhs); + + XMStoreFloat4(&result, XMVectorScale(V, lhs)); + return result; + } + + /*-----------------------------------------------------------------------------------*/ + /* Function Member Definitions */ + /*-----------------------------------------------------------------------------------*/ + + float SHVec4::Length() const noexcept + { + const XMVECTOR V = XMLoadFloat4(this); + + return XMVectorGetX(XMVector4Length(V)); + } + + float SHVec4::Length3D() const noexcept + { + const XMVECTOR V = XMLoadFloat4(this); + + return XMVectorGetX(XMVector3Length(V)); + } + + float SHVec4::LengthSquared() const noexcept + { + const XMVECTOR V = XMLoadFloat4(this); + + return XMVectorGetX(XMVector4LengthSq(V)); + } + + float SHVec4::LengthSquared3D() const noexcept + { + const XMVECTOR V = XMLoadFloat4(this); + + return XMVectorGetX(XMVector3LengthSq(V)); + } + + std::string SHVec4::ToString() const noexcept + { + std::stringstream ss; + ss << std::fixed << std::setprecision(3); + ss << "<" << x << ", " << y << ", " << z << ", " << w <<">"; + return ss.str(); + } + + float SHVec4::Dot(const SHVec4& rhs) const noexcept + { + const XMVECTOR V1 = XMLoadFloat4(this); + const XMVECTOR V2 = XMLoadFloat4(&rhs); + + return XMVectorGetX(XMVector4Dot(V1, V2)); + } + + float SHVec4::Dot3D(const SHVec4& rhs) const noexcept + { + const XMVECTOR V1 = XMLoadFloat4(this); + const XMVECTOR V2 = XMLoadFloat4(&rhs); + + return XMVectorGetX(XMVector3Dot(V1, V2)); + } + + SHVec4 SHVec4::Cross3D(const SHVec4& rhs) const noexcept + { + SHVec4 result; + + const XMVECTOR V1 = XMLoadFloat4(this); + const XMVECTOR V2 = XMLoadFloat4(&rhs); + + XMStoreFloat4(&result, XMVector3Cross(V1, V2)); + result.w = 1.0f; + return result; + } + + SHVec4 SHVec4::Cross(const SHVec4& v1, const SHVec4& v2) const noexcept + { + SHVec4 result; + + const XMVECTOR V3 = XMLoadFloat4(this); + const XMVECTOR V1 = XMLoadFloat4(&v1); + const XMVECTOR V2 = XMLoadFloat4(&v2); + + XMStoreFloat4(&result, XMVector4Cross(V3, V1, V2)); + return result; + } + + /*-----------------------------------------------------------------------------------*/ + /* Static Function Member Definitions */ + /*-----------------------------------------------------------------------------------*/ + + SHVec4 SHVec4::Normalise(const SHVec4& v) noexcept + { + SHVec4 result; + + const XMVECTOR V = XMLoadFloat4(&v); + + XMStoreFloat4(&result, XMVector4Normalize(V)); + return result; + } + + SHVec4 SHVec4::Normalise3D(const SHVec4& v) noexcept + { + SHVec4 result; + + const XMVECTOR V = XMLoadFloat4(&v); + + XMStoreFloat4(&result, XMVector3Normalize(V)); + result.w = 1.0f; + return result; + } + + SHVec4 SHVec4::Abs(const SHVec4& v) noexcept + { + return SHVec4{ std::fabs(v.x), std::fabs(v.y), std::fabs(v.z), std::fabs(v.w) }; + } + + SHVec4 SHVec4::Min(const std::initializer_list& vs) noexcept + { + if (vs.size() == 0) + { + SHLOG_WARNING("No arguments passed in! Min value is a default SHVec4.") + return SHVec4{}; + } + + SHVec4 result; + + XMVECTOR min = XMLoadFloat4(&(*vs.begin())); + for (auto it = vs.begin() + 1; it != vs.end(); ++it) + { + const XMVECTOR tmp = XMLoadFloat4(&(*it)); + min = XMVectorMin(min, tmp); + } + + XMStoreFloat4(&result, min); + return result; + } + + SHVec4 SHVec4::Max(const std::initializer_list& vs) noexcept + { + if (vs.size() == 0) + { + SHLOG_WARNING("No arguments passed in! Max value is a default SHVec4.") + return SHVec4{}; + } + + SHVec4 result; + + XMVECTOR max = XMLoadFloat4(&(*vs.begin())); + for (auto it = vs.begin() + 1; it != vs.end(); ++it) + { + const XMVECTOR tmp = XMLoadFloat4(&(*it)); + max = XMVectorMax(max, tmp); + } + + XMStoreFloat4(&result, max); + return result; + } + + SHVec4 SHVec4::Clamp(const SHVec4& v, const SHVec4& vMin, const SHVec4& vMax) noexcept + { + SHVec4 result; + + const XMVECTOR V = XMLoadFloat4(&v); + const XMVECTOR MIN = XMLoadFloat4(&vMin); + const XMVECTOR MAX = XMLoadFloat4(&vMax); + + XMStoreFloat4(&result, XMVectorClamp(V, MIN, MAX)); + return result; + } + + SHVec4 SHVec4::Lerp(const SHVec4& a, const SHVec4& b, float t) noexcept + { + SHVec4 result; + + const XMVECTOR V1 = XMLoadFloat4(&a); + const XMVECTOR V2 = XMLoadFloat4(&b); + + XMStoreFloat4(&result, XMVectorLerp(V1, V2, t)); + return result; + } + + SHVec4 SHVec4::ClampedLerp(const SHVec4& a, const SHVec4& b, float t, float tMin, float tMax) noexcept + { + return Lerp(a, b, std::clamp(t, tMin, tMax)); + } + + float SHVec4::Distance(const SHVec4& lhs, const SHVec4& rhs) noexcept + { + return (lhs - rhs).Length(); + } + + float SHVec4::Distance3D(const SHVec4& lhs, const SHVec4& rhs) noexcept + { + return (lhs - rhs).Length3D(); + } + + float SHVec4::DistanceSquared(const SHVec4& lhs, const SHVec4& rhs) noexcept + { + return (lhs - rhs).LengthSquared(); + } + + float SHVec4::DistanceSquared3D(const SHVec4& lhs, const SHVec4& rhs) noexcept + { + return (lhs - rhs).LengthSquared3D(); + } + + float SHVec4::Angle(const SHVec4& lhs, const SHVec4& rhs) noexcept + { + const XMVECTOR V1 = XMLoadFloat4(&lhs); + const XMVECTOR V2 = XMLoadFloat4(&rhs); + + return XMVectorGetX(XMVector4AngleBetweenVectors(V1, V2)); + } + + float SHVec4::Angle3D(const SHVec4& lhs, const SHVec4& rhs) noexcept + { + const XMVECTOR V1 = XMLoadFloat4(&lhs); + const XMVECTOR V2 = XMLoadFloat4(&rhs); + + return XMVectorGetX(XMVector3AngleBetweenVectors(V1, V2)); + } + + float SHVec4::Dot(const SHVec4& lhs, const SHVec4& rhs) noexcept + { + return lhs.Dot(rhs); + } + + float SHVec4::Dot3D(const SHVec4& lhs, const SHVec4& rhs) noexcept + { + return lhs.Dot3D(rhs); + } + + SHVec4 SHVec4::Cross3D(const SHVec4& lhs, const SHVec4& rhs) noexcept + { + return lhs.Cross3D(rhs); + } + + SHVec4 SHVec4::Cross(const SHVec4& v1, const SHVec4& v2, const SHVec4& v3) noexcept + { + return v1.Cross(v2, v3); + } + + SHVec4 SHVec4::Project(const SHVec4& v, const SHVec4& u) noexcept + { + SHVec4 result; + + const XMVECTOR U = XMLoadFloat4(&u); + const float V_DOT_U = Dot(v, u); + const float U_LENSQ = u.LengthSquared(); + + XMStoreFloat4(&result, XMVectorScale(U, V_DOT_U / U_LENSQ)); + return result; + } + + SHVec4 SHVec4::Project3D(const SHVec4& v, const SHVec4& u) noexcept + { + SHVec4 result; + + const XMVECTOR U = XMLoadFloat4(&u); + const float V_DOT_U = Dot3D(v, u); + const float U_LENSQ = u.LengthSquared3D(); + + XMStoreFloat4(&result, XMVectorScale(U, V_DOT_U / U_LENSQ)); + result.w = 1.0f; + return result; + } + + SHVec4 SHVec4::Reflect(const SHVec4& v, const SHVec4& normal) noexcept + { + SHVec4 result; + + const XMVECTOR V = XMLoadFloat4(&v); + const XMVECTOR N = XMLoadFloat4(&normal); + + XMStoreFloat4(&result, XMVector4Reflect(V, N)); + result.w = 1.0f; + return result; + } + + SHVec4 SHVec4::Reflect3D(const SHVec4& v, const SHVec4& normal) noexcept + { + SHVec4 result; + + const XMVECTOR V = XMLoadFloat4(&v); + const XMVECTOR N = XMLoadFloat4(&normal); + + XMStoreFloat4(&result, XMVector3Reflect(V, N)); + result.w = 1.0f; + return result; + } + + SHVec4 SHVec4::Transform3D(const SHVec4& v, const SHMatrix& transformMtx) noexcept + { + SHVec4 result; + + const XMVECTOR V = XMLoadFloat4(&v); + const XMMATRIX TF = XMLoadFloat4x4(&transformMtx); + + XMStoreFloat4(&result, XMVector3TransformCoord(V, TF)); + return result; + } +} \ No newline at end of file diff --git a/SHADE_Engine/src/Math/Vector/SHVec4.h b/SHADE_Engine/src/Math/Vector/SHVec4.h new file mode 100644 index 00000000..c4caf2c8 --- /dev/null +++ b/SHADE_Engine/src/Math/Vector/SHVec4.h @@ -0,0 +1,133 @@ +/**************************************************************************************** + * \file SHVec4.h + * \author Diren D Bharwani, diren.dbharwani, 390002520 + * \brief Interface for 4D Vector. + * + * \copyright Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or + * disclosure of this file or its contents without the prior written consent + * of DigiPen Institute of Technology is prohibited. +****************************************************************************************/ + +#pragma once + +#include +#include +#include + +namespace SHADE +{ + /*-----------------------------------------------------------------------------------*/ + /* Forward Declarations */ + /*-----------------------------------------------------------------------------------*/ + class SHMatrix; + + /*-----------------------------------------------------------------------------------*/ + /* Type Definitions */ + /*-----------------------------------------------------------------------------------*/ + + class SHVec4 : public DirectX::XMFLOAT4 + { + public: + /*---------------------------------------------------------------------------------*/ + /* Static Data Members */ + /*---------------------------------------------------------------------------------*/ + + static constexpr size_t SIZE = 4U; + + static const SHVec4 Zero; + static const SHVec4 One; + static const SHVec4 UnitX; + static const SHVec4 UnitY; + static const SHVec4 UnitZ; + static const SHVec4 UnitW; + + /*---------------------------------------------------------------------------------*/ + /* Constructors & Destructor */ + /*---------------------------------------------------------------------------------*/ + + SHVec4 (const SHVec4& rhs) = default; + SHVec4 (SHVec4&& rhs) = default; + ~SHVec4 () = default; + + SHVec4 () noexcept; + SHVec4 (float x, float y, float z, float w) noexcept; + + /*---------------------------------------------------------------------------------*/ + /* Operator Overloads */ + /*---------------------------------------------------------------------------------*/ + + [[nodiscard]] SHVec4& operator= (const SHVec4& rhs) = default; + [[nodiscard]] SHVec4& operator= (SHVec4&& rhs) = default; + + [[nodiscard]] SHVec4& operator+= (const SHVec4& rhs) noexcept; + [[nodiscard]] SHVec4& operator-= (const SHVec4& rhs) noexcept; + [[nodiscard]] SHVec4& operator*= (const SHVec4& rhs) noexcept; + [[nodiscard]] SHVec4& operator*= (float rhs) noexcept; + [[nodiscard]] SHVec4& operator/= (const SHVec4& rhs) noexcept; + [[nodiscard]] SHVec4& operator/= (float rhs) noexcept; + + [[nodiscard]] SHVec4 operator+ (const SHVec4& rhs) const noexcept; + [[nodiscard]] SHVec4 operator- (const SHVec4& rhs) const noexcept; + [[nodiscard]] SHVec4 operator- () const noexcept; + [[nodiscard]] SHVec4 operator* (const SHVec4& rhs) const noexcept; + [[nodiscard]] SHVec4 operator* (float rhs) const noexcept; + [[nodiscard]] SHVec4 operator/ (const SHVec4& rhs) const noexcept; + [[nodiscard]] SHVec4 operator/ (float rhs) const noexcept; + + [[nodiscard]] bool operator== (const SHVec4& rhs) const noexcept; + [[nodiscard]] bool operator!= (const SHVec4& rhs) const noexcept; + + [[nodiscard]] float operator[] (int index); + [[nodiscard]] float operator[] (size_t index); + [[nodiscard]] float operator[] (int index) const; + [[nodiscard]] float operator[] (size_t index) const; + + /*---------------------------------------------------------------------------------*/ + /* Function Members */ + /*---------------------------------------------------------------------------------*/ + + [[nodiscard]] float Length () const noexcept; + [[nodiscard]] float Length3D () const noexcept; + [[nodiscard]] float LengthSquared () const noexcept; + [[nodiscard]] float LengthSquared3D () const noexcept; + [[nodiscard]] std::string ToString () const noexcept; + + [[nodiscard]] float Dot (const SHVec4& rhs) const noexcept; + [[nodiscard]] float Dot3D (const SHVec4& rhs) const noexcept; + [[nodiscard]] SHVec4 Cross3D (const SHVec4& rhs) const noexcept; + [[nodiscard]] SHVec4 Cross (const SHVec4& v1, const SHVec4& v2) const noexcept; + + /*---------------------------------------------------------------------------------*/ + /* Static Function Members */ + /*---------------------------------------------------------------------------------*/ + + [[nodiscard]] static SHVec4 Normalise (const SHVec4& v) noexcept; + [[nodiscard]] static SHVec4 Normalise3D (const SHVec4& v) noexcept; + [[nodiscard]] static SHVec4 Abs (const SHVec4& v) noexcept; + [[nodiscard]] static SHVec4 Min (const std::initializer_list& vs) noexcept; + [[nodiscard]] static SHVec4 Max (const std::initializer_list& vs) noexcept; + [[nodiscard]] static SHVec4 Clamp (const SHVec4& v, const SHVec4& vMin, const SHVec4& vMax) noexcept; + [[nodiscard]] static SHVec4 Lerp (const SHVec4& a, const SHVec4& b, float t) noexcept; + [[nodiscard]] static SHVec4 ClampedLerp (const SHVec4& a, const SHVec4& b, float t, float tMin = 0.0f, float tMax = 1.0f) noexcept; + + [[nodiscard]] static float Distance (const SHVec4& lhs, const SHVec4& rhs) noexcept; + [[nodiscard]] static float Distance3D (const SHVec4& lhs, const SHVec4& rhs) noexcept; + [[nodiscard]] static float DistanceSquared (const SHVec4& lhs, const SHVec4& rhs) noexcept; + [[nodiscard]] static float DistanceSquared3D (const SHVec4& lhs, const SHVec4& rhs) noexcept; + [[nodiscard]] static float Angle (const SHVec4& lhs, const SHVec4& rhs) noexcept; + [[nodiscard]] static float Angle3D (const SHVec4& lhs, const SHVec4& rhs) noexcept; + [[nodiscard]] static float Dot (const SHVec4& lhs, const SHVec4& rhs) noexcept; + [[nodiscard]] static float Dot3D (const SHVec4& lhs, const SHVec4& rhs) noexcept; + [[nodiscard]] static SHVec4 Cross3D (const SHVec4& lhs, const SHVec4& rhs) noexcept; + [[nodiscard]] static SHVec4 Cross (const SHVec4& v1, const SHVec4& v2, const SHVec4& v3) noexcept; + [[nodiscard]] static SHVec4 Project (const SHVec4& v, const SHVec4& u) noexcept; + [[nodiscard]] static SHVec4 Project3D (const SHVec4& v, const SHVec4& u) noexcept; + [[nodiscard]] static SHVec4 Reflect (const SHVec4& v, const SHVec4& normal) noexcept; + [[nodiscard]] static SHVec4 Reflect3D (const SHVec4& v, const SHVec4& normal) noexcept; + [[nodiscard]] static SHVec4 Transform3D (const SHVec4& v, const SHMatrix& transformMtx) noexcept; + + }; + + SHVec4 operator* (float lhs, const SHVec4& rhs) noexcept; + +} // namespace SHADE \ No newline at end of file diff --git a/SHADE_Engine/src/SHpch.h b/SHADE_Engine/src/SHpch.h index 19bd69b6..6c31ca3f 100644 --- a/SHADE_Engine/src/SHpch.h +++ b/SHADE_Engine/src/SHpch.h @@ -9,4 +9,6 @@ #pragma once -#include \ No newline at end of file +#include +#include +#include \ No newline at end of file diff --git a/SHADE_Engine/src/Tools/SHUtilities.h b/SHADE_Engine/src/Tools/SHUtilities.h new file mode 100644 index 00000000..543c771c --- /dev/null +++ b/SHADE_Engine/src/Tools/SHUtilities.h @@ -0,0 +1,50 @@ +/**************************************************************************************** + * \file SHutilities.h + * \author Diren D Bharwani, diren.dbharwani, 390002520 + * \brief Interface for various utility functions. + * + * \copyright Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or + * disclosure of this file or its contents without the prior written consent + * of DigiPen Institute of Technology is prohibited. +****************************************************************************************/ + +#pragma once + +#include "Math/SHMathHelpers.h" + +namespace SHADE +{ + /*-----------------------------------------------------------------------------------*/ + /* Concepts */ + /*-----------------------------------------------------------------------------------*/ + + template + concept IsEnum = std::is_enum_v; + + /*-----------------------------------------------------------------------------------*/ + /* Type Definitions */ + /*-----------------------------------------------------------------------------------*/ + + class SHUtilities + { + public: + /*---------------------------------------------------------------------------------*/ + /* Static Function Members */ + /*---------------------------------------------------------------------------------*/ + + /** + * @brief Converts an enum class member from it's type to any other type. + * @tparam InputType Restricted to an enum class + * @tparam OutputType The type to convert the enum class member to. Defaults to int. + * @param[in] enumClassMember A member of the specified enum class. + * @returns The value of the enum class member in the output type. + */ + template + static constexpr OutputType ConvertEnum(InputType enumClassMember) noexcept; + + }; + +} // namespace SHADE + +#include "SHUtilities.hpp" + diff --git a/SHADE_Engine/src/Tools/SHUtilities.hpp b/SHADE_Engine/src/Tools/SHUtilities.hpp new file mode 100644 index 00000000..0e21a9d0 --- /dev/null +++ b/SHADE_Engine/src/Tools/SHUtilities.hpp @@ -0,0 +1,28 @@ +/**************************************************************************************** + * \file SHutilities.hpp + * \author Diren D Bharwani, diren.dbharwani, 390002520 + * \brief Implementation for various templated utility functions. + * + * \copyright Copyright (C) 2022 DigiPen Institute of Technology. Reproduction or + * disclosure of this file or its contents without the prior written consent + * of DigiPen Institute of Technology is prohibited. +****************************************************************************************/ + +#pragma once + +// Primary Header +#include "SHUtilities.h" + +namespace SHADE +{ + /*-----------------------------------------------------------------------------------*/ + /* Static Function Members Definitions */ + /*-----------------------------------------------------------------------------------*/ + + template + constexpr OutputType SHUtilities::ConvertEnum (InputType enumClassMember) noexcept + { + return static_cast(enumClassMember); + } + +} // namespace SHADE \ No newline at end of file From 392b51898a5c8dcc7c59d9394504929e509d5eb0 Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Thu, 8 Sep 2022 22:46:51 +0800 Subject: [PATCH 2/3] Added more implementations for Quaternions --- SHADE_Engine/src/Math/SHQuaternion.cpp | 63 ++++++++++++++++++++++++-- SHADE_Engine/src/Math/SHQuaternion.h | 4 +- 2 files changed, 62 insertions(+), 5 deletions(-) diff --git a/SHADE_Engine/src/Math/SHQuaternion.cpp b/SHADE_Engine/src/Math/SHQuaternion.cpp index 2b1ac173..6164dcb3 100644 --- a/SHADE_Engine/src/Math/SHQuaternion.cpp +++ b/SHADE_Engine/src/Math/SHQuaternion.cpp @@ -212,14 +212,16 @@ namespace SHADE SHQuaternion SHQuaternion::RotateTowards(const SHQuaternion&, float) const noexcept { - // TODO(Diren): Figure this out. + SHQuaternion result; - return Identity; + // TODO (Diren) + + return result; } SHVec3 SHQuaternion::ToEuler() const noexcept { - // TODO(Diren): Figure this out. + // TODO (Diren) return SHVec3::Zero; } @@ -236,5 +238,60 @@ namespace SHADE /* Static Function Member Definitions */ /*-----------------------------------------------------------------------------------*/ + SHQuaternion SHQuaternion::Normalise(const SHQuaternion& q) noexcept + { + SHQuaternion result; + + const XMVECTOR Q = XMLoadFloat4(&q); + + XMStoreFloat4(&result, XMQuaternionNormalize(Q)); + return result; + } + + SHQuaternion SHQuaternion::Conjugate(const SHQuaternion& q) noexcept + { + SHQuaternion result; + + const XMVECTOR Q = XMLoadFloat4(&q); + + XMStoreFloat4(&result, XMQuaternionConjugate(Q)); + return result; + } + + float SHQuaternion::Angle(const SHQuaternion&, const SHQuaternion&) noexcept + { + // TODO (Diren) + + return 0.0f; + } + + SHQuaternion SHQuaternion::Lerp(const SHQuaternion&, const SHQuaternion&, float) noexcept + { + SHQuaternion result; + + // TODO (Diren) + + return result; + } + + SHQuaternion SHQuaternion::Slerp(const SHQuaternion& q1, const SHQuaternion& q2, float t) noexcept + { + SHQuaternion result; + + const XMVECTOR Q1 = XMLoadFloat4(&q1); + const XMVECTOR Q2 = XMLoadFloat4(&q2); + + XMStoreFloat4(&result, XMQuaternionSlerp(Q1, Q2, t)); + return result; + } + + SHQuaternion SHQuaternion::Rotate(const SHVec3& , const SHVec3&) noexcept + { + SHQuaternion result; + + // TODO (Diren) + + return result; + } } // namespace SHADE \ No newline at end of file diff --git a/SHADE_Engine/src/Math/SHQuaternion.h b/SHADE_Engine/src/Math/SHQuaternion.h index 103019ae..27088284 100644 --- a/SHADE_Engine/src/Math/SHQuaternion.h +++ b/SHADE_Engine/src/Math/SHQuaternion.h @@ -92,12 +92,12 @@ namespace SHADE [[nodiscard]] static SHQuaternion Normalise (const SHQuaternion& q) noexcept; [[nodiscard]] static SHQuaternion Conjugate (const SHQuaternion& q) noexcept; - [[nodiscard]] static SHQuaternion Angle (const SHQuaternion& q1, const SHQuaternion& q2) noexcept; + [[nodiscard]] static SHQuaternion Inverse (const SHQuaternion& q) noexcept; + [[nodiscard]] static float Angle (const SHQuaternion& q1, const SHQuaternion& q2) noexcept; [[nodiscard]] static SHQuaternion Lerp (const SHQuaternion& q1, const SHQuaternion& q2, float t) noexcept; [[nodiscard]] static SHQuaternion Slerp (const SHQuaternion& q1, const SHQuaternion& q2, float t) noexcept; - [[nodiscard]] static SHQuaternion Concat (const SHQuaternion& q1, const SHQuaternion& q2) noexcept; [[nodiscard]] static SHQuaternion Rotate (const SHVec3& from, const SHVec3& to) noexcept; }; From f0b916b2753b8a499fbcdfbaeb5b20b793cb2860 Mon Sep 17 00:00:00 2001 From: Diren D Bharwani Date: Thu, 8 Sep 2022 23:21:02 +0800 Subject: [PATCH 3/3] Added missing inverse function for Quaternions --- SHADE_Engine/src/Math/SHQuaternion.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/SHADE_Engine/src/Math/SHQuaternion.cpp b/SHADE_Engine/src/Math/SHQuaternion.cpp index 6164dcb3..208f131d 100644 --- a/SHADE_Engine/src/Math/SHQuaternion.cpp +++ b/SHADE_Engine/src/Math/SHQuaternion.cpp @@ -258,6 +258,17 @@ namespace SHADE return result; } + SHQuaternion SHQuaternion::Inverse(const SHQuaternion& q) noexcept + { + SHQuaternion result; + + const XMVECTOR Q = XMLoadFloat4(&q); + XMStoreFloat4(&result, XMQuaternionInverse(Q)); + + return result; + } + + float SHQuaternion::Angle(const SHQuaternion&, const SHQuaternion&) noexcept { // TODO (Diren)