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