SHADE_Y3/SHADE_Engine/src/Math/SHMatrix.cpp

601 lines
19 KiB
C++
Raw Normal View History

/****************************************************************************************
* \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 <SHpch.h>
// 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<const XMFLOAT4*>(&_11));
const XMVECTOR L2 = XMLoadFloat4(reinterpret_cast<const XMFLOAT4*>(&_21));
const XMVECTOR L3 = XMLoadFloat4(reinterpret_cast<const XMFLOAT4*>(&_31));
const XMVECTOR L4 = XMLoadFloat4(reinterpret_cast<const XMFLOAT4*>(&_41));
const XMVECTOR R1 = XMLoadFloat4(reinterpret_cast<const XMFLOAT4*>(&rhs._11));
const XMVECTOR R2 = XMLoadFloat4(reinterpret_cast<const XMFLOAT4*>(&rhs._21));
const XMVECTOR R3 = XMLoadFloat4(reinterpret_cast<const XMFLOAT4*>(&rhs._31));
const XMVECTOR R4 = XMLoadFloat4(reinterpret_cast<const XMFLOAT4*>(&rhs._41));
XMStoreFloat4(reinterpret_cast<XMFLOAT4*>(&result._11), XMVectorAdd(L1, R1));
XMStoreFloat4(reinterpret_cast<XMFLOAT4*>(&result._21), XMVectorAdd(L2, R2));
XMStoreFloat4(reinterpret_cast<XMFLOAT4*>(&result._31), XMVectorAdd(L3, R3));
XMStoreFloat4(reinterpret_cast<XMFLOAT4*>(&result._41), XMVectorAdd(L4, R4));
return result;
}
SHMatrix SHMatrix::operator-(const SHMatrix& rhs) const noexcept
{
SHMatrix result;
const XMVECTOR L1 = XMLoadFloat4(reinterpret_cast<const XMFLOAT4*>(&_11));
const XMVECTOR L2 = XMLoadFloat4(reinterpret_cast<const XMFLOAT4*>(&_21));
const XMVECTOR L3 = XMLoadFloat4(reinterpret_cast<const XMFLOAT4*>(&_31));
const XMVECTOR L4 = XMLoadFloat4(reinterpret_cast<const XMFLOAT4*>(&_41));
const XMVECTOR R1 = XMLoadFloat4(reinterpret_cast<const XMFLOAT4*>(&rhs._11));
const XMVECTOR R2 = XMLoadFloat4(reinterpret_cast<const XMFLOAT4*>(&rhs._21));
const XMVECTOR R3 = XMLoadFloat4(reinterpret_cast<const XMFLOAT4*>(&rhs._31));
const XMVECTOR R4 = XMLoadFloat4(reinterpret_cast<const XMFLOAT4*>(&rhs._41));
XMStoreFloat4(reinterpret_cast<XMFLOAT4*>(&result._11), XMVectorSubtract(L1, R1));
XMStoreFloat4(reinterpret_cast<XMFLOAT4*>(&result._21), XMVectorSubtract(L2, R2));
XMStoreFloat4(reinterpret_cast<XMFLOAT4*>(&result._31), XMVectorSubtract(L3, R3));
XMStoreFloat4(reinterpret_cast<XMFLOAT4*>(&result._41), XMVectorSubtract(L4, R4));
return result;
}
SHMatrix SHMatrix::operator-() const noexcept
{
SHMatrix result;
const XMVECTOR L1 = XMLoadFloat4(reinterpret_cast<const XMFLOAT4*>(&_11));
const XMVECTOR L2 = XMLoadFloat4(reinterpret_cast<const XMFLOAT4*>(&_21));
const XMVECTOR L3 = XMLoadFloat4(reinterpret_cast<const XMFLOAT4*>(&_31));
const XMVECTOR L4 = XMLoadFloat4(reinterpret_cast<const XMFLOAT4*>(&_41));
XMStoreFloat4(reinterpret_cast<XMFLOAT4*>(&result._11), XMVectorNegate(L1));
XMStoreFloat4(reinterpret_cast<XMFLOAT4*>(&result._21), XMVectorNegate(L2));
XMStoreFloat4(reinterpret_cast<XMFLOAT4*>(&result._31), XMVectorNegate(L3));
XMStoreFloat4(reinterpret_cast<XMFLOAT4*>(&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<const XMFLOAT4*>(&_11));
const XMVECTOR L2 = XMLoadFloat4(reinterpret_cast<const XMFLOAT4*>(&_21));
const XMVECTOR L3 = XMLoadFloat4(reinterpret_cast<const XMFLOAT4*>(&_31));
const XMVECTOR L4 = XMLoadFloat4(reinterpret_cast<const XMFLOAT4*>(&_41));
XMStoreFloat4(reinterpret_cast<XMFLOAT4*>(&result._11), XMVectorScale(L1, rhs));
XMStoreFloat4(reinterpret_cast<XMFLOAT4*>(&result._21), XMVectorScale(L2, rhs));
XMStoreFloat4(reinterpret_cast<XMFLOAT4*>(&result._31), XMVectorScale(L3, rhs));
XMStoreFloat4(reinterpret_cast<XMFLOAT4*>(&result._41), XMVectorScale(L4, rhs));
return result;
}
SHMatrix SHMatrix::operator/(const SHMatrix& rhs) const noexcept
{
SHMatrix result;
const XMVECTOR L1 = XMLoadFloat4(reinterpret_cast<const XMFLOAT4*>(&_11));
const XMVECTOR L2 = XMLoadFloat4(reinterpret_cast<const XMFLOAT4*>(&_21));
const XMVECTOR L3 = XMLoadFloat4(reinterpret_cast<const XMFLOAT4*>(&_31));
const XMVECTOR L4 = XMLoadFloat4(reinterpret_cast<const XMFLOAT4*>(&_41));
const XMVECTOR R1 = XMLoadFloat4(reinterpret_cast<const XMFLOAT4*>(&rhs._11));
const XMVECTOR R2 = XMLoadFloat4(reinterpret_cast<const XMFLOAT4*>(&rhs._21));
const XMVECTOR R3 = XMLoadFloat4(reinterpret_cast<const XMFLOAT4*>(&rhs._31));
const XMVECTOR R4 = XMLoadFloat4(reinterpret_cast<const XMFLOAT4*>(&rhs._41));
XMStoreFloat4(reinterpret_cast<XMFLOAT4*>(&result._11), XMVectorDivide(L1, R1));
XMStoreFloat4(reinterpret_cast<XMFLOAT4*>(&result._21), XMVectorDivide(L2, R2));
XMStoreFloat4(reinterpret_cast<XMFLOAT4*>(&result._31), XMVectorDivide(L3, R3));
XMStoreFloat4(reinterpret_cast<XMFLOAT4*>(&result._41), XMVectorDivide(L4, R4));
return result;
}
SHMatrix SHMatrix::operator/(float rhs) const noexcept
{
SHMatrix result;
const XMVECTOR L1 = XMLoadFloat4(reinterpret_cast<const XMFLOAT4*>(&_11));
const XMVECTOR L2 = XMLoadFloat4(reinterpret_cast<const XMFLOAT4*>(&_21));
const XMVECTOR L3 = XMLoadFloat4(reinterpret_cast<const XMFLOAT4*>(&_31));
const XMVECTOR L4 = XMLoadFloat4(reinterpret_cast<const XMFLOAT4*>(&_41));
const float INV_RHS = 1.0f / rhs;
XMStoreFloat4(reinterpret_cast<XMFLOAT4*>(&result._11), XMVectorScale(L1, INV_RHS));
XMStoreFloat4(reinterpret_cast<XMFLOAT4*>(&result._21), XMVectorScale(L2, INV_RHS));
XMStoreFloat4(reinterpret_cast<XMFLOAT4*>(&result._31), XMVectorScale(L3, INV_RHS));
XMStoreFloat4(reinterpret_cast<XMFLOAT4*>(&result._41), XMVectorScale(L4, INV_RHS));
return result;
}
bool SHMatrix::operator==(const SHMatrix& rhs) const noexcept
{
const XMVECTOR L1 = XMLoadFloat4(reinterpret_cast<const XMFLOAT4*>(&_11));
const XMVECTOR L2 = XMLoadFloat4(reinterpret_cast<const XMFLOAT4*>(&_21));
const XMVECTOR L3 = XMLoadFloat4(reinterpret_cast<const XMFLOAT4*>(&_31));
const XMVECTOR L4 = XMLoadFloat4(reinterpret_cast<const XMFLOAT4*>(&_41));
const XMVECTOR R1 = XMLoadFloat4(reinterpret_cast<const XMFLOAT4*>(&rhs._11));
const XMVECTOR R2 = XMLoadFloat4(reinterpret_cast<const XMFLOAT4*>(&rhs._21));
const XMVECTOR R3 = XMLoadFloat4(reinterpret_cast<const XMFLOAT4*>(&rhs._31));
const XMVECTOR R4 = XMLoadFloat4(reinterpret_cast<const XMFLOAT4*>(&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<const XMFLOAT4*>(&_11));
const XMVECTOR L2 = XMLoadFloat4(reinterpret_cast<const XMFLOAT4*>(&_21));
const XMVECTOR L3 = XMLoadFloat4(reinterpret_cast<const XMFLOAT4*>(&_31));
const XMVECTOR L4 = XMLoadFloat4(reinterpret_cast<const XMFLOAT4*>(&_41));
const XMVECTOR R1 = XMLoadFloat4(reinterpret_cast<const XMFLOAT4*>(&rhs._11));
const XMVECTOR R2 = XMLoadFloat4(reinterpret_cast<const XMFLOAT4*>(&rhs._21));
const XMVECTOR R3 = XMLoadFloat4(reinterpret_cast<const XMFLOAT4*>(&rhs._31));
const XMVECTOR R4 = XMLoadFloat4(reinterpret_cast<const XMFLOAT4*>(&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<XMFLOAT3*>(&result._11), X_HAT);
XMStoreFloat3(reinterpret_cast<XMFLOAT3*>(&result._21), Y_HAT);
XMStoreFloat3(reinterpret_cast<XMFLOAT3*>(&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<XMFLOAT3*>(&result._11), X_HAT);
XMStoreFloat3(reinterpret_cast<XMFLOAT3*>(&result._21), Y_HAT);
XMStoreFloat3(reinterpret_cast<XMFLOAT3*>(&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