195 lines
6.7 KiB
C++
195 lines
6.7 KiB
C++
#pragma once
|
|
|
|
#include <Core/Math/Vector.h>
|
|
#include <math.h>
|
|
|
|
namespace Juliet
|
|
{
|
|
struct Matrix
|
|
{
|
|
float m[4][4];
|
|
};
|
|
|
|
[[nodiscard]] inline Matrix MatrixIdentity()
|
|
{
|
|
Matrix result = {};
|
|
result.m[0][0] = 1.0f;
|
|
result.m[1][1] = 1.0f;
|
|
result.m[2][2] = 1.0f;
|
|
result.m[3][3] = 1.0f;
|
|
return result;
|
|
}
|
|
|
|
[[nodiscard]] inline Matrix operator*(const Matrix& lhs, const Matrix& rhs)
|
|
{
|
|
Matrix result = {};
|
|
for (int i = 0; i < 4; ++i)
|
|
{
|
|
for (int j = 0; j < 4; ++j)
|
|
{
|
|
for (int k = 0; k < 4; ++k)
|
|
{
|
|
result.m[i][j] += lhs.m[i][k] * rhs.m[k][j];
|
|
}
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
[[nodiscard]] inline Matrix MatrixTranslation(float x, float y, float z)
|
|
{
|
|
Matrix result = MatrixIdentity();
|
|
result.m[0][3] = x;
|
|
result.m[1][3] = y;
|
|
result.m[2][3] = z;
|
|
return result;
|
|
}
|
|
|
|
[[nodiscard]] inline Matrix MatrixScale(float x, float y, float z)
|
|
{
|
|
Matrix result = MatrixIdentity();
|
|
result.m[0][0] = x;
|
|
result.m[1][1] = y;
|
|
result.m[2][2] = z;
|
|
return result;
|
|
}
|
|
|
|
[[nodiscard]] inline Matrix MatrixRotationX(float radians)
|
|
{
|
|
float c = cosf(radians);
|
|
float s = sinf(radians);
|
|
Matrix result = MatrixIdentity();
|
|
result.m[1][1] = c;
|
|
result.m[1][2] = -s;
|
|
result.m[2][1] = s;
|
|
result.m[2][2] = c;
|
|
return result;
|
|
}
|
|
|
|
[[nodiscard]] inline Matrix MatrixRotationY(float radians)
|
|
{
|
|
float c = cosf(radians);
|
|
float s = sinf(radians);
|
|
Matrix result = MatrixIdentity();
|
|
result.m[0][0] = c;
|
|
result.m[0][2] = s;
|
|
result.m[2][0] = -s;
|
|
result.m[2][2] = c;
|
|
return result;
|
|
}
|
|
|
|
[[nodiscard]] inline Matrix MatrixRotationZ(float radians)
|
|
{
|
|
float c = cosf(radians);
|
|
float s = sinf(radians);
|
|
Matrix result = MatrixIdentity();
|
|
result.m[0][0] = c;
|
|
result.m[0][1] = -s;
|
|
result.m[1][0] = s;
|
|
result.m[1][1] = c;
|
|
return result;
|
|
}
|
|
|
|
inline void MatrixTranslate(Matrix& m, const Vector3& v)
|
|
{
|
|
m.m[0][3] += v.x;
|
|
m.m[1][3] += v.y;
|
|
m.m[2][3] += v.z;
|
|
}
|
|
|
|
[[nodiscard]] inline Matrix MatrixRotation(float x, float y, float z)
|
|
{
|
|
return MatrixRotationX(x) * MatrixRotationY(y) * MatrixRotationZ(z);
|
|
}
|
|
|
|
inline Matrix LookAt(const Vector3& eye, const Vector3& target, const Vector3& up)
|
|
{
|
|
// Left-Handed convention
|
|
Vector3 zaxis = Normalize(target - eye); // Forward is +z
|
|
Vector3 xaxis = Normalize(Cross(up, zaxis));
|
|
Vector3 yaxis = Cross(zaxis, xaxis);
|
|
|
|
Matrix result = {};
|
|
// Row 0
|
|
result.m[0][0] = xaxis.x;
|
|
result.m[0][1] = xaxis.y;
|
|
result.m[0][2] = xaxis.z;
|
|
result.m[0][3] = -Dot(xaxis, eye);
|
|
|
|
// Row 1
|
|
result.m[1][0] = yaxis.x;
|
|
result.m[1][1] = yaxis.y;
|
|
result.m[1][2] = yaxis.z;
|
|
result.m[1][3] = -Dot(yaxis, eye);
|
|
|
|
// Row 2
|
|
result.m[2][0] = zaxis.x;
|
|
result.m[2][1] = zaxis.y;
|
|
result.m[2][2] = zaxis.z;
|
|
result.m[2][3] = -Dot(zaxis, eye);
|
|
|
|
// Row 3
|
|
result.m[3][3] = 1.0f;
|
|
|
|
return result;
|
|
}
|
|
|
|
inline Matrix PerspectiveFov(float fovY, float aspectRatio, float nearZ, float farZ)
|
|
{
|
|
// Left-Handed Perspective
|
|
float yScale = 1.0f / tanf(fovY * 0.5f);
|
|
float xScale = yScale / aspectRatio;
|
|
|
|
Matrix result = {};
|
|
result.m[0][0] = xScale;
|
|
result.m[1][1] = yScale;
|
|
result.m[2][2] = farZ / (farZ - nearZ);
|
|
result.m[2][3] = (-nearZ * farZ) / (farZ - nearZ);
|
|
result.m[3][2] = 1.0f;
|
|
result.m[3][3] = 0.0f;
|
|
return result;
|
|
}
|
|
|
|
[[nodiscard]] inline Matrix MatrixInverse(const Matrix& m)
|
|
{
|
|
Matrix out = {};
|
|
|
|
float m00 = m.m[0][0], m01 = m.m[0][1], m02 = m.m[0][2], m03 = m.m[0][3];
|
|
float m10 = m.m[1][0], m11 = m.m[1][1], m12 = m.m[1][2], m13 = m.m[1][3];
|
|
float m20 = m.m[2][0], m21 = m.m[2][1], m22 = m.m[2][2], m23 = m.m[2][3];
|
|
float m30 = m.m[3][0], m31 = m.m[3][1], m32 = m.m[3][2], m33 = m.m[3][3];
|
|
|
|
out.m[0][0] = m11 * m22 * m33 - m11 * m23 * m32 - m21 * m12 * m33 + m21 * m13 * m32 + m31 * m12 * m23 - m31 * m13 * m22;
|
|
out.m[1][0] = -m10 * m22 * m33 + m10 * m23 * m32 + m20 * m12 * m33 - m20 * m13 * m32 - m30 * m12 * m23 + m30 * m13 * m22;
|
|
out.m[2][0] = m10 * m21 * m33 - m10 * m23 * m31 - m20 * m11 * m33 + m20 * m13 * m31 + m30 * m11 * m23 - m30 * m13 * m21;
|
|
out.m[3][0] = -m10 * m21 * m32 + m10 * m22 * m31 + m20 * m11 * m32 - m20 * m12 * m31 - m30 * m11 * m22 + m30 * m12 * m21;
|
|
|
|
out.m[0][1] = -m01 * m22 * m33 + m01 * m23 * m32 + m21 * m02 * m33 - m21 * m03 * m32 - m31 * m02 * m23 + m31 * m03 * m22;
|
|
out.m[1][1] = m00 * m22 * m33 - m00 * m23 * m32 - m20 * m02 * m33 + m20 * m03 * m32 + m30 * m02 * m23 - m30 * m03 * m22;
|
|
out.m[2][1] = -m00 * m21 * m33 + m00 * m23 * m31 + m20 * m01 * m33 - m20 * m03 * m31 - m30 * m01 * m23 + m30 * m03 * m21;
|
|
out.m[3][1] = m00 * m21 * m32 - m00 * m22 * m31 - m20 * m01 * m32 + m20 * m02 * m31 + m30 * m01 * m22 - m30 * m02 * m21;
|
|
|
|
out.m[0][2] = m01 * m12 * m33 - m01 * m13 * m32 - m11 * m02 * m33 + m11 * m03 * m32 + m31 * m02 * m13 - m31 * m03 * m12;
|
|
out.m[1][2] = -m00 * m12 * m33 + m00 * m13 * m32 + m10 * m02 * m33 - m10 * m03 * m32 - m30 * m02 * m13 + m30 * m03 * m12;
|
|
out.m[2][2] = m00 * m11 * m33 - m00 * m13 * m31 - m10 * m01 * m33 + m10 * m03 * m31 + m30 * m01 * m13 - m30 * m03 * m11;
|
|
out.m[3][2] = -m00 * m11 * m32 + m00 * m12 * m31 + m10 * m01 * m32 - m10 * m02 * m31 - m30 * m01 * m12 + m30 * m02 * m11;
|
|
|
|
out.m[0][3] = -m01 * m12 * m23 + m01 * m13 * m22 + m11 * m02 * m23 - m11 * m03 * m22 - m21 * m02 * m13 + m21 * m03 * m12;
|
|
out.m[1][3] = m00 * m12 * m23 - m00 * m13 * m22 - m10 * m02 * m23 + m10 * m03 * m22 + m20 * m02 * m13 - m20 * m03 * m12;
|
|
out.m[2][3] = -m00 * m11 * m23 + m00 * m13 * m21 + m10 * m01 * m23 - m10 * m03 * m21 - m20 * m01 * m13 + m20 * m03 * m11;
|
|
out.m[3][3] = m00 * m11 * m22 - m00 * m12 * m21 - m10 * m01 * m22 + m10 * m02 * m21 + m20 * m01 * m12 - m20 * m02 * m11;
|
|
|
|
float det = m00 * out.m[0][0] + m01 * out.m[1][0] + m02 * out.m[2][0] + m03 * out.m[3][0];
|
|
|
|
if (det != 0.0f)
|
|
{
|
|
float invDet = 1.0f / det;
|
|
for (int r = 0; r < 4; ++r)
|
|
for (int c = 0; c < 4; ++c)
|
|
out.m[r][c] *= invDet;
|
|
}
|
|
|
|
return out;
|
|
}
|
|
} // namespace Juliet
|