Common: Small tidy-up and constexpr-ify GSMatrix4x4

This commit is contained in:
Stenzek 2025-01-02 20:52:19 +10:00
parent 83b4757788
commit 90cb266886
No known key found for this signature in database
2 changed files with 71 additions and 124 deletions

View File

@ -66,53 +66,11 @@ void GSMatrix2x2::store(void* m)
std::memcpy(m, E, sizeof(E));
}
GSMatrix4x4::GSMatrix4x4(float e00, float e01, float e02, float e03, float e10, float e11, float e12, float e13,
float e20, float e21, float e22, float e23, float e30, float e31, float e32, float e33)
{
E[0][0] = e00;
E[0][1] = e01;
E[0][2] = e02;
E[0][3] = e03;
E[1][0] = e10;
E[1][1] = e11;
E[1][2] = e12;
E[1][3] = e13;
E[2][0] = e20;
E[2][1] = e21;
E[2][2] = e22;
E[2][3] = e23;
E[3][0] = e30;
E[3][1] = e31;
E[3][2] = e32;
E[3][3] = e33;
}
GSMatrix4x4::GSMatrix4x4(const GSMatrix2x2& m)
{
E[0][0] = m.E[0][0];
E[0][1] = m.E[0][1];
E[0][2] = 0.0f;
E[0][3] = 0.0f;
E[1][0] = m.E[1][0];
E[1][1] = m.E[1][1];
E[1][2] = 0.0f;
E[1][3] = 0.0f;
E[2][0] = 0.0f;
E[2][1] = 0.0f;
E[2][2] = 1.0f;
E[2][3] = 0.0f;
E[3][0] = 0.0f;
E[3][1] = 0.0f;
E[3][2] = 0.0f;
E[3][3] = 1.0f;
}
GSMatrix4x4 GSMatrix4x4::operator*(const GSMatrix4x4& m) const
ALWAYS_INLINE static void MatrixMult4x4(GSMatrix4x4& res, const GSMatrix4x4& lhs, const GSMatrix4x4& rhs)
{
// This isn't speedy by any means, but it's not hot code either.
GSMatrix4x4 res;
#define MultRC(rw, cl) E[rw][0] * m.E[0][cl] + E[rw][1] * m.E[1][cl] + E[rw][2] * m.E[2][cl] + E[rw][3] * m.E[3][cl]
#define MultRC(rw, cl) \
lhs.E[rw][0] * rhs.E[0][cl] + lhs.E[rw][1] * rhs.E[1][cl] + lhs.E[rw][2] * rhs.E[2][cl] + lhs.E[rw][3] * rhs.E[3][cl]
res.E[0][0] = MultRC(0, 0);
res.E[0][1] = MultRC(0, 1);
@ -132,75 +90,22 @@ GSMatrix4x4 GSMatrix4x4::operator*(const GSMatrix4x4& m) const
res.E[3][3] = MultRC(3, 3);
#undef MultRC
}
GSMatrix4x4 GSMatrix4x4::operator*(const GSMatrix4x4& m) const
{
GSMatrix4x4 res;
MatrixMult4x4(res, *this, m);
return res;
}
GSMatrix4x4& GSMatrix4x4::operator*=(const GSMatrix4x4& m)
{
const GSMatrix4x4 copy(*this);
#define MultRC(rw, cl) \
copy.E[rw][0] * m.E[0][cl] + copy.E[rw][1] * m.E[1][cl] + copy.E[rw][2] * m.E[2][cl] + copy.E[rw][3] * m.E[3][cl]
E[0][0] = MultRC(0, 0);
E[0][1] = MultRC(0, 1);
E[0][2] = MultRC(0, 2);
E[0][3] = MultRC(0, 3);
E[1][0] = MultRC(1, 0);
E[1][1] = MultRC(1, 1);
E[1][2] = MultRC(1, 2);
E[1][3] = MultRC(1, 3);
E[2][0] = MultRC(2, 0);
E[2][1] = MultRC(2, 1);
E[2][2] = MultRC(2, 2);
E[2][3] = MultRC(2, 3);
E[3][0] = MultRC(3, 0);
E[3][1] = MultRC(3, 1);
E[3][2] = MultRC(3, 2);
E[3][3] = MultRC(3, 3);
#undef MultRC
MatrixMult4x4(*this, copy, m);
return *this;
}
GSVector4 GSMatrix4x4::operator*(const GSVector4& v) const
{
const GSVector4 r0 = row(0);
const GSVector4 r1 = row(1);
const GSVector4 r2 = row(2);
const GSVector4 r3 = row(3);
return GSVector4(r0.dot(v), r1.dot(v), r2.dot(v), r3.dot(v));
}
GSMatrix4x4 GSMatrix4x4::Identity()
{
GSMatrix4x4 res;
#define MultRC(rw, cl) E[rw][0] * m.E[0][cl] + E[rw][1] * m.E[1][cl] + E[rw][2] * m.E[2][cl] + E[rw][3] * m.E[3][cl]
res.E[0][0] = 1.0f;
res.E[0][1] = 0.0f;
res.E[0][2] = 0.0f;
res.E[0][3] = 0.0f;
res.E[1][0] = 0.0f;
res.E[1][1] = 1.0f;
res.E[1][2] = 0.0f;
res.E[1][3] = 0.0f;
res.E[2][0] = 0.0f;
res.E[2][1] = 0.0f;
res.E[2][2] = 1.0f;
res.E[2][3] = 0.0f;
res.E[3][0] = 0.0f;
res.E[3][1] = 0.0f;
res.E[3][2] = 0.0f;
res.E[3][3] = 1.0f;
return res;
}
GSMatrix4x4 GSMatrix4x4::RotationX(float angle_in_radians)
{
const float sin_angle = std::sin(angle_in_radians);
@ -246,17 +151,7 @@ GSMatrix4x4 GSMatrix4x4::OffCenterOrthographicProjection(float width, float heig
return OffCenterOrthographicProjection(0.0f, 0.0f, width, height, zNear, zFar);
}
GSVector4 GSMatrix4x4::row(size_t i) const
{
return GSVector4::load<true>(&E[i][0]);
}
GSVector4 GSMatrix4x4::col(size_t i) const
{
return GSVector4(E[0][i], E[1][i], E[2][i], E[3][i]);
}
GSMatrix4x4 GSMatrix4x4::Invert() const
GSMatrix4x4 GSMatrix4x4::invert() const
{
GSMatrix4x4 ret;

View File

@ -41,17 +41,60 @@ public:
class alignas(VECTOR_ALIGNMENT) GSMatrix4x4
{
public:
GSMatrix4x4() = default;
GSMatrix4x4(float e00, float e01, float e02, float e03, float e10, float e11, float e12, float e13, float e20,
float e21, float e22, float e23, float e30, float e31, float e32, float e33);
GSMatrix4x4(const GSMatrix2x2& m);
constexpr GSMatrix4x4() = default;
constexpr GSMatrix4x4(float e00, float e01, float e02, float e03, float e10, float e11, float e12, float e13,
float e20, float e21, float e22, float e23, float e30, float e31, float e32, float e33)
{
E[0][0] = e00;
E[0][1] = e01;
E[0][2] = e02;
E[0][3] = e03;
E[1][0] = e10;
E[1][1] = e11;
E[1][2] = e12;
E[1][3] = e13;
E[2][0] = e20;
E[2][1] = e21;
E[2][2] = e22;
E[2][3] = e23;
E[3][0] = e30;
E[3][1] = e31;
E[3][2] = e32;
E[3][3] = e33;
}
constexpr GSMatrix4x4(const GSMatrix2x2& m)
{
E[0][0] = m.E[0][0];
E[0][1] = m.E[0][1];
E[0][2] = 0.0f;
E[0][3] = 0.0f;
E[1][0] = m.E[1][0];
E[1][1] = m.E[1][1];
E[1][2] = 0.0f;
E[1][3] = 0.0f;
E[2][0] = 0.0f;
E[2][1] = 0.0f;
E[2][2] = 1.0f;
E[2][3] = 0.0f;
E[3][0] = 0.0f;
E[3][1] = 0.0f;
E[3][2] = 0.0f;
E[3][3] = 1.0f;
}
GSMatrix4x4 operator*(const GSMatrix4x4& m) const;
GSMatrix4x4& operator*=(const GSMatrix4x4& m);
GSVector4 operator*(const GSVector4& v) const;
GSVector4 operator*(const GSVector4& v) const
{
return GSVector4(row(0).dot(v), row(1).dot(v), row(2).dot(v), row(3).dot(v));
}
static GSMatrix4x4 Identity();
static constexpr GSMatrix4x4 Identity()
{
return GSMatrix4x4(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);
}
static GSMatrix4x4 RotationX(float angle_in_radians);
static GSMatrix4x4 RotationY(float angle_in_radians);
@ -62,10 +105,19 @@ public:
float zFar);
static GSMatrix4x4 OffCenterOrthographicProjection(float width, float height, float zNear, float zFar);
GSVector4 row(size_t i) const;
GSVector4 col(size_t i) const;
GSVector4 row(size_t i) const { return GSVector4::load<true>(&E[i][0]); }
GSVector4 col(size_t i) const { return GSVector4(E[0][i], E[1][i], E[2][i], E[3][i]); }
GSMatrix4x4 Invert() const;
void set_row(size_t i, GSVector4 row) { GSVector4::store<true>(&E[i][0], row); }
void set_col(size_t i, GSVector4 col)
{
E[0][i] = col.x;
E[1][i] = col.y;
E[2][i] = col.z;
E[3][i] = col.w;
}
GSMatrix4x4 invert() const;
void store(void* m);