/* * Copyright (c) 2020, Stephan Unverwerth * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once #include #include #include #include #include namespace Gfx { template using Matrix4x4 = Matrix<4, T>; template constexpr static Vector4 operator*(Matrix4x4 const& m, Vector4 const& 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]); } // FIXME: this is a specific Matrix4x4 * Vector3 interaction that implies W=1; maybe move this out of LibGfx // or replace a Matrix4x4 * Vector4 operation? template constexpr static Vector3 transform_point(Matrix4x4 const& m, Vector3 const& 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]); } template constexpr static Matrix4x4 translation_matrix(Vector3 const& 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 scale_matrix(Vector3 const& s) { return Matrix4x4( s.x(), 0, 0, 0, 0, s.y(), 0, 0, 0, 0, s.z(), 0, 0, 0, 0, 1); } template constexpr static Matrix4x4 rotation_matrix(Vector3 const& axis, T angle) { T c, s; AK::sincos(angle, s, c); 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); } template Gfx::AffineTransform extract_2d_affine_transform(Matrix4x4 const& matrix) { auto* m = matrix.elements(); return Gfx::AffineTransform(m[0][0], m[1][0], m[0][1], m[1][1], m[0][3], m[1][3]); } typedef Matrix4x4 FloatMatrix4x4; typedef Matrix4x4 DoubleMatrix4x4; } using Gfx::DoubleMatrix4x4; using Gfx::FloatMatrix4x4; using Gfx::Matrix4x4;