diff --git a/Userland/Demos/Cube/Cube.cpp b/Userland/Demos/Cube/Cube.cpp index b3afab088a5..6c9de1a8f8c 100644 --- a/Userland/Demos/Cube/Cube.cpp +++ b/Userland/Demos/Cube/Cube.cpp @@ -128,13 +128,13 @@ void Cube::timer_event(Core::TimerEvent&) static float angle = 0; angle += 0.02f; - auto matrix = FloatMatrix4x4::translate(FloatVector3(0, 0, 1.5f)) - * FloatMatrix4x4::rotate(FloatVector3(1, 0, 0), angle * 1.17356641f) - * FloatMatrix4x4::rotate(FloatVector3(0, 1, 0), angle * 0.90533273f) - * FloatMatrix4x4::rotate(FloatVector3(0, 0, 1), angle); + auto matrix = Gfx::translation_matrix(FloatVector3(0, 0, 1.5f)) + * Gfx::rotation_matrix(FloatVector3(1, 0, 0), angle * 1.17356641f) + * Gfx::rotation_matrix(FloatVector3(0, 1, 0), angle * 0.90533273f) + * Gfx::rotation_matrix(FloatVector3(0, 0, 1), angle); for (int i = 0; i < 8; i++) { - transformed_vertices[i] = matrix.transform_point(vertices[i]); + transformed_vertices[i] = transform_point(matrix, vertices[i]); } GUI::Painter painter(*m_bitmap); diff --git a/Userland/Demos/GLTeapot/main.cpp b/Userland/Demos/GLTeapot/main.cpp index 9e99b7d6d0b..6d0530a2526 100644 --- a/Userland/Demos/GLTeapot/main.cpp +++ b/Userland/Demos/GLTeapot/main.cpp @@ -82,10 +82,10 @@ void GLContextWidget::timer_event(Core::TimerEvent&) glCallList(m_init_list); angle -= 0.01f; - auto matrix = FloatMatrix4x4::translate(FloatVector3(0, 0, -8.5)) - * FloatMatrix4x4::rotate(FloatVector3(1, 0, 0), angle) - * FloatMatrix4x4::rotate(FloatVector3(0, 1, 0), 0.0f) - * FloatMatrix4x4::rotate(FloatVector3(0, 0, 1), angle); + auto matrix = Gfx::translation_matrix(FloatVector3(0, 0, -8.5)) + * Gfx::rotation_matrix(FloatVector3(1, 0, 0), angle) + * Gfx::rotation_matrix(FloatVector3(0, 1, 0), 0.0f) + * Gfx::rotation_matrix(FloatVector3(0, 0, 1), angle); // We need to transpose here because OpenGL expects matrices in column major order // but our matrix class stores elements in row major order. diff --git a/Userland/Libraries/LibGL/SoftwareGLContext.cpp b/Userland/Libraries/LibGL/SoftwareGLContext.cpp index 2e0b051eed0..e952dab48ea 100644 --- a/Userland/Libraries/LibGL/SoftwareGLContext.cpp +++ b/Userland/Libraries/LibGL/SoftwareGLContext.cpp @@ -576,7 +576,7 @@ void SoftwareGLContext::gl_rotate(GLdouble angle, GLdouble x, GLdouble y, GLdoub FloatVector3 axis = { (float)x, (float)y, (float)z }; axis.normalize(); - auto rotation_mat = FloatMatrix4x4::rotate(axis, angle); + auto rotation_mat = Gfx::rotation_matrix(axis, static_cast(angle)); if (m_current_matrix_mode == GL_MODELVIEW) m_model_view_matrix = m_model_view_matrix * rotation_mat; @@ -596,9 +596,9 @@ void SoftwareGLContext::gl_scale(GLdouble x, GLdouble y, GLdouble z) } if (m_current_matrix_mode == GL_MODELVIEW) { - m_model_view_matrix = m_model_view_matrix * FloatMatrix4x4::scale({ static_cast(x), static_cast(y), static_cast(z) }); + m_model_view_matrix = m_model_view_matrix * Gfx::scale_matrix(FloatVector3 { static_cast(x), static_cast(y), static_cast(z) }); } else if (m_current_matrix_mode == GL_PROJECTION) { - m_projection_matrix = m_projection_matrix * FloatMatrix4x4::scale({ static_cast(x), static_cast(y), static_cast(z) }); + m_projection_matrix = m_projection_matrix * Gfx::scale_matrix(FloatVector3 { static_cast(x), static_cast(y), static_cast(z) }); } m_error = GL_NO_ERROR; @@ -614,9 +614,9 @@ void SoftwareGLContext::gl_translate(GLdouble x, GLdouble y, GLdouble z) } if (m_current_matrix_mode == GL_MODELVIEW) { - m_model_view_matrix = m_model_view_matrix * FloatMatrix4x4::translate({ (float)x, (float)y, (float)z }); + m_model_view_matrix = m_model_view_matrix * Gfx::translation_matrix(FloatVector3 { (float)x, (float)y, (float)z }); } else if (m_current_matrix_mode == GL_PROJECTION) { - m_projection_matrix = m_projection_matrix * FloatMatrix4x4::translate({ (float)x, (float)y, (float)z }); + m_projection_matrix = m_projection_matrix * Gfx::translation_matrix(FloatVector3 { (float)x, (float)y, (float)z }); } m_error = GL_NO_ERROR; diff --git a/Userland/Libraries/LibGfx/Matrix.h b/Userland/Libraries/LibGfx/Matrix.h index b348c36e436..58f5e4ec6ed 100644 --- a/Userland/Libraries/LibGfx/Matrix.h +++ b/Userland/Libraries/LibGfx/Matrix.h @@ -44,8 +44,8 @@ public: constexpr Matrix operator*(const Matrix& other) const { Matrix product; - for (int i = 0; i < N; ++i) { - for (int j = 0; j < N; ++j) { + for (size_t i = 0; i < N; ++i) { + for (size_t j = 0; j < N; ++j) { auto& element = product.m_elements[i][j]; if constexpr (N == 4) { @@ -75,6 +75,31 @@ public: return product; } + constexpr static Matrix identity() + { + Matrix result; + for (size_t i = 0; i < N; ++i) { + for (size_t j = 0; j < N; ++j) { + if (i == j) + result.m_elements[i][j] = 1; + else + result.m_elements[i][j] = 0; + } + } + return result; + } + + constexpr Matrix transpose() const + { + Matrix result; + for (size_t i = 0; i < N; ++i) { + for (size_t j = 0; j < N; ++j) { + result.m_elements[i][j] = m_elements[j][i]; + } + } + return result; + } + private: T m_elements[N][N]; }; diff --git a/Userland/Libraries/LibGfx/Matrix4x4.h b/Userland/Libraries/LibGfx/Matrix4x4.h index 780c4115135..52164a14ff1 100644 --- a/Userland/Libraries/LibGfx/Matrix4x4.h +++ b/Userland/Libraries/LibGfx/Matrix4x4.h @@ -14,117 +14,78 @@ namespace Gfx { template -class Matrix4x4 final { -public: - constexpr Matrix4x4() = default; - constexpr Matrix4x4(T _11, T _12, T _13, T _14, - T _21, T _22, T _23, T _24, - T _31, T _32, T _33, T _34, - T _41, T _42, T _43, T _44) - : m_elements { - _11, _12, _13, _14, - _21, _22, _23, _24, - _31, _32, _33, _34, - _41, _42, _43, _44 - } - { - } +using Matrix4x4 = Matrix<4, T>; - constexpr auto elements() const { return m_elements; } - constexpr auto elements() { return m_elements; } +template +constexpr static Vector4 operator*(const Matrix4x4& m, const Vector4& v) +{ + auto const& elements = m.elements(); + return Vector4( + v.x() * elements[0][0] + v.y() * elements[0][1] + v.z() * elements[0][2] + v.w() * elements[0][3], + v.x() * elements[1][0] + v.y() * elements[1][1] + v.z() * elements[1][2] + v.w() * elements[1][3], + v.x() * elements[2][0] + v.y() * elements[2][1] + v.z() * elements[2][2] + v.w() * elements[2][3], + v.x() * elements[3][0] + v.y() * elements[3][1] + v.z() * elements[3][2] + v.w() * elements[3][3]); +} - constexpr Matrix4x4 operator*(const Matrix4x4& other) const - { - Matrix4x4 product; - for (int i = 0; i < 4; ++i) { - for (int j = 0; j < 4; ++j) { - product.m_elements[i][j] = m_elements[i][0] * other.m_elements[0][j] - + m_elements[i][1] * other.m_elements[1][j] - + m_elements[i][2] * other.m_elements[2][j] - + m_elements[i][3] * other.m_elements[3][j]; - } - } - return product; - } +template +constexpr static Vector3 transform_point(const Matrix4x4& m, const Vector3& p) +{ + auto const& elements = m.elements(); + return Vector3( + p.x() * elements[0][0] + p.y() * elements[0][1] + p.z() * elements[0][2] + elements[0][3], + p.x() * elements[1][0] + p.y() * elements[1][1] + p.z() * elements[1][2] + elements[1][3], + p.x() * elements[2][0] + p.y() * elements[2][1] + p.z() * elements[2][2] + elements[2][3]); +} - constexpr Vector4 operator*(const Vector4& v) const - { - return Vector4( - v.x() * m_elements[0][0] + v.y() * m_elements[0][1] + v.z() * m_elements[0][2] + v.w() * m_elements[0][3], - v.x() * m_elements[1][0] + v.y() * m_elements[1][1] + v.z() * m_elements[1][2] + v.w() * m_elements[1][3], - v.x() * m_elements[2][0] + v.y() * m_elements[2][1] + v.z() * m_elements[2][2] + v.w() * m_elements[2][3], - v.x() * m_elements[3][0] + v.y() * m_elements[3][1] + v.z() * m_elements[3][2] + v.w() * m_elements[3][3]); - } +template +constexpr static Vector3 transform_direction(const Matrix4x4& m, const Vector3& d) +{ + auto const& elements = m.elements(); + return Vector3( + d.x() * elements[0][0] + d.y() * elements[0][1] + d.z() * elements[0][2], + d.x() * elements[1][0] + d.y() * elements[1][1] + d.z() * elements[1][2], + d.x() * elements[2][0] + d.y() * elements[2][1] + d.z() * elements[2][2]); +} - constexpr Vector3 transform_point(const Vector3& p) const - { - return Vector3( - p.x() * m_elements[0][0] + p.y() * m_elements[0][1] + p.z() * m_elements[0][2] + m_elements[0][3], - p.x() * m_elements[1][0] + p.y() * m_elements[1][1] + p.z() * m_elements[1][2] + m_elements[1][3], - p.x() * m_elements[2][0] + p.y() * m_elements[2][1] + p.z() * m_elements[2][2] + m_elements[2][3]); - } +template +constexpr static Matrix4x4 translation_matrix(const Vector3& p) +{ + return Matrix4x4( + 1, 0, 0, p.x(), + 0, 1, 0, p.y(), + 0, 0, 1, p.z(), + 0, 0, 0, 1); +} - constexpr static Matrix4x4 identity() - { - return Matrix4x4( - 1, 0, 0, 0, - 0, 1, 0, 0, - 0, 0, 1, 0, - 0, 0, 0, 1); - } +template +constexpr static Matrix4x4 scale_matrix(const Vector3& s) +{ + return Matrix4x4( + s.x(), 0, 0, 0, + 0, s.y(), 0, 0, + 0, 0, s.z(), 0, + 0, 0, 0, 1); +} - constexpr static Matrix4x4 translate(const Vector3& p) - { - return Matrix4x4( - 1, 0, 0, p.x(), - 0, 1, 0, p.y(), - 0, 0, 1, p.z(), - 0, 0, 0, 1); - } +template +constexpr static Matrix4x4 rotation_matrix(const Vector3& axis, T angle) +{ + T c = cos(angle); + T s = sin(angle); + T t = 1 - c; + T x = axis.x(); + T y = axis.y(); + T z = axis.z(); - constexpr static Matrix4x4 scale(const Vector3& s) - { - return Matrix4x4( - s.x(), 0, 0, 0, - 0, s.y(), 0, 0, - 0, 0, s.z(), 0, - 0, 0, 0, 1); - } - - constexpr static Matrix4x4 rotate(const Vector3& axis, T angle) - { - T c = cos(angle); - T s = sin(angle); - T t = 1 - c; - T x = axis.x(); - T y = axis.y(); - T z = axis.z(); - - return Matrix4x4( - t * x * x + c, t * x * y - z * s, t * x * z + y * s, 0, - t * x * y + z * s, t * y * y + c, t * y * z - x * s, 0, - t * x * z - y * s, t * y * z + x * s, t * z * z + c, 0, - 0, 0, 0, 1); - } - - constexpr Matrix4x4 transpose() const - { - Matrix4x4 result; - for (int i = 0; i < 4; ++i) { - for (int j = 0; j < 4; ++j) { - result.m_elements[i][j] = m_elements[j][i]; - } - } - return result; - } - -private: - T m_elements[4][4]; -}; + return Matrix4x4( + t * x * x + c, t * x * y - z * s, t * x * z + y * s, 0, + t * x * y + z * s, t * y * y + c, t * y * z - x * s, 0, + t * x * z - y * s, t * y * z + x * s, t * z * z + c, 0, + 0, 0, 0, 1); +} typedef Matrix4x4 FloatMatrix4x4; typedef Matrix4x4 DoubleMatrix4x4; - } using Gfx::DoubleMatrix4x4;