charcoal/archive/math/mat4x4.h

266 lines
5.6 KiB
C
Raw Normal View History

#pragma once
#include "vec4.h"
namespace egm
{
template <typename T>
struct tmat4x4
{
// Column Major
tvec4<T> a;
tvec4<T> b;
tvec4<T> c;
tvec4<T> d;
//Identity Matrix
tmat4x4() : a(1, 0, 0, 0), b(0, 1, 0, 0), c(0, 0, 1, 0), d(0, 0, 0, 1) {}
//Sets column by column
tmat4x4(const tvec4<T>& a, const tvec4<T>& b, const tvec4<T>& c, const tvec4<T>& d) : a(a), b(b), c(c), d(d) {}
//Sets by value (letter = column, number = row)
tmat4x4(
const T& a1, const T& a2, const T& a3, const T& a4,
const T& b1, const T& b2, const T& b3, const T& b4,
const T& c1, const T& c2, const T& c3, const T& c4,
const T& d1, const T& d2, const T& d3, const T& d4
) :
a(a1, a2, a3, a4),
b(b1, b2, b3, b4),
c(c1, c2, c3, c4),
d(d1, d2, d3, d4)
{}
tvec4<T>& operator[](const unsigned int& index)
{
switch (index)
{
case 0:
return a;
case 1:
return b;
case 2:
return c;
case 3:
return d;
default:
throw "Index Out Of Bounds";
}
}
bool operator==(const tmat4x4<T>& o)
{
return (o.a == a && o.b == b && o.c == c && o.d == d);
}
tmat4x4<T>& operator=(const tmat4x4<T>& o)
{
a = o.a;
b = o.b;
c = o.c;
d = o.d;
return *this;
}
tmat4x4<T> operator+(const tmat4x4<T>& o) const
{
return {
a + o.a,
b + o.b,
c + o.c,
d + o.d
};
}
tmat4x4<T>& operator+=(const tmat4x4<T>& o)
{
a += o.a;
b += o.b;
c += o.c;
d += o.d;
return *this;
}
tmat4x4<T> operator-(const tmat4x4<T>& o) const
{
return {
a - o.a,
b - o.b,
c - o.c,
d - o.d
};
}
tmat4x4<T>& operator-=(const tmat4x4<T>& o)
{
a -= o.a;
b -= o.b;
c -= o.c;
d -= o.d;
return *this;
}
tvec4<T> operator*(const tvec4<T>& v) const
{
// Probably should make a commented out row major version
return {
a.x * v.x + a.y * v.y + a.z * v.z + a.w * v.w,
b.x * v.x + b.y * v.y + b.z * v.z + b.w * v.w,
c.x * v.x + c.y * v.y + c.z * v.z + c.w * v.w,
d.x * v.x + d.y * v.y + d.z * v.z + d.w * v.w,
};
}
tmat4x4<T> operator*(const tmat4x4<T>& m) const
{
/* Row Major
return {
m.a.x * a.x + m.b.x * a.y + m.c.x * a.z + m.d.x * a.w,
m.a.y * a.x + m.b.y * a.y + m.c.y * a.z + m.d.y * a.w,
m.a.z * a.x + m.b.z * a.y + m.c.z * a.z + m.d.z * a.w,
m.a.w * a.x + m.b.w * a.y + m.c.w * a.z + m.d.w * a.w,
m.a.x * b.x + m.b.x * b.y + m.c.x * b.z + m.d.x * b.w,
m.a.y * b.x + m.b.y * b.y + m.c.y * b.z + m.d.y * b.w,
m.a.z * b.x + m.b.z * b.y + m.c.z * b.z + m.d.z * b.w,
m.a.w * b.x + m.b.w * b.y + m.c.w * b.z + m.d.w * b.w,
m.a.x * c.x + m.b.x * c.y + m.c.x * c.z + m.d.x * c.w,
m.a.y * c.x + m.b.y * c.y + m.c.y * c.z + m.d.y * c.w,
m.a.z * c.x + m.b.z * c.y + m.c.z * c.z + m.d.z * c.w,
m.a.w * c.x + m.b.w * c.y + m.c.w * c.z + m.d.w * c.w,
m.a.x * d.x + m.b.x * d.y + m.c.x * d.z + m.d.x * d.w,
m.a.y * d.x + m.b.y * d.y + m.c.y * d.z + m.d.y * d.w,
m.a.z * d.x + m.b.z * d.y + m.c.z * d.z + m.d.z * d.w,
m.a.w * d.x + m.b.w * d.y + m.c.w * d.z + m.d.w * d.w,
};
*/
// Column Major
// Something is wrong here......
return {
a.x * m.a.x + b.x * m.a.y + c.x * m.a.z + d.x * m.a.w,
a.y * m.a.x + b.y * m.a.y + c.y * m.a.z + d.y * m.a.w,
a.z * m.a.x + b.z * m.a.y + c.z * m.a.z + d.z * m.a.w,
a.w * m.a.x + b.w * m.a.y + c.w * m.a.z + d.w * m.a.w,
a.x * m.b.x + b.x * m.b.y + c.x * m.b.z + d.x * m.b.w,
a.y * m.b.x + b.y * m.b.y + c.y * m.b.z + d.y * m.b.w,
a.z * m.b.x + b.z * m.b.y + c.z * m.b.z + d.z * m.b.w,
a.w * m.b.x + b.w * m.b.y + c.w * m.b.z + d.w * m.b.w,
a.x * m.c.x + b.x * m.c.y + c.x * m.c.z + d.x * m.c.w,
a.y * m.c.x + b.y * m.c.y + c.y * m.c.z + d.y * m.c.w,
a.z * m.c.x + b.z * m.c.y + c.z * m.c.z + d.z * m.c.w,
a.w * m.c.x + b.w * m.c.y + c.w * m.c.z + d.w * m.c.w,
a.x * m.d.x + b.x * m.d.y + c.x * m.d.z + d.x * m.d.w,
a.y * m.d.x + b.y * m.d.y + c.y * m.d.z + d.y * m.d.w,
a.z * m.d.x + b.z * m.d.y + c.z * m.d.z + d.z * m.d.w,
a.w * m.d.x + b.w * m.d.y + c.w * m.d.z + d.w * m.d.w,
};
}
tmat4x4<T>& operator*=(const tmat4x4<T>& o)
{
return *this = *this * o;
}
tmat4x4<T> operator*(const T& scalar) const
{
return {
a * scalar,
b * scalar,
c * scalar,
d * scalar
};
}
tmat4x4<T>& operator*=(const T& scalar)
{
a *= scalar;
b *= scalar;
c *= scalar;
d *= scalar;
return *this;
}
tmat4x4<T> operator/(const T& scalar) const
{
return {
a / scalar,
b / scalar,
c / scalar,
d / scalar
};
}
tmat4x4<T>& operator/=(const T& scalar)
{
a /= scalar;
b /= scalar;
c /= scalar;
d /= scalar;
return *this;
}
const T* data() const
{
return &a.x;
}
void zero()
{
a.x = 0;
a.y = 0;
a.z = 0;
a.w = 0;
b.x = 0;
b.y = 0;
b.z = 0;
b.w = 0;
c.x = 0;
c.y = 0;
c.z = 0;
c.w = 0;
d.x = 0;
d.y = 0;
d.z = 0;
d.w = 0;
}
void to_identity()
{
a.x = static_cast<T>(1);
a.y = static_cast<T>(0);
a.z = static_cast<T>(0);
a.w = static_cast<T>(0);
b.x = static_cast<T>(0);
b.y = static_cast<T>(1);
b.z = static_cast<T>(0);
b.w = static_cast<T>(0);
c.x = static_cast<T>(0);
c.y = static_cast<T>(0);
c.z = static_cast<T>(1);
c.w = static_cast<T>(0);
d.x = static_cast<T>(0);
d.y = static_cast<T>(0);
d.z = static_cast<T>(0);
d.w = static_cast<T>(1);
}
};
typedef tmat4x4<float> mat4x4;
typedef tmat4x4<double> dmat4x4;
typedef tmat4x4<int> imat4x4;
const mat4x4 IDENTITY_MATRIX(
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
);
}