/* * 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) { return Vector4( v.x() * m[0, 0] + v.y() * m[0, 1] + v.z() * m[0, 2] + v.w() * m[0, 3], v.x() * m[1, 0] + v.y() * m[1, 1] + v.z() * m[1, 2] + v.w() * m[1, 3], v.x() * m[2, 0] + v.y() * m[2, 1] + v.z() * m[2, 2] + v.w() * m[2, 3], v.x() * m[3, 0] + v.y() * m[3, 1] + v.z() * m[3, 2] + v.w() * m[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) { return Vector3( p.x() * m[0, 0] + p.y() * m[0, 1] + p.z() * m[0, 2] + m[0, 3], p.x() * m[1, 0] + p.y() * m[1, 1] + p.z() * m[1, 2] + m[1, 3], p.x() * m[2, 0] + p.y() * m[2, 1] + p.z() * m[2, 2] + m[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& m) { 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;