/src/serenity/Userland/Libraries/LibGfx/Matrix4x4.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright (c) 2020, Stephan Unverwerth <s.unverwerth@serenityos.org> |
3 | | * |
4 | | * SPDX-License-Identifier: BSD-2-Clause |
5 | | */ |
6 | | |
7 | | #pragma once |
8 | | |
9 | | #include <AK/Math.h> |
10 | | #include <LibGfx/AffineTransform.h> |
11 | | #include <LibGfx/Matrix.h> |
12 | | #include <LibGfx/Vector3.h> |
13 | | #include <LibGfx/Vector4.h> |
14 | | |
15 | | namespace Gfx { |
16 | | |
17 | | template<typename T> |
18 | | using Matrix4x4 = Matrix<4, T>; |
19 | | |
20 | | template<typename T> |
21 | | constexpr static Vector4<T> operator*(Matrix4x4<T> const& m, Vector4<T> const& v) |
22 | 0 | { |
23 | 0 | auto const& elements = m.elements(); |
24 | 0 | return Vector4<T>( |
25 | 0 | v.x() * elements[0][0] + v.y() * elements[0][1] + v.z() * elements[0][2] + v.w() * elements[0][3], |
26 | 0 | v.x() * elements[1][0] + v.y() * elements[1][1] + v.z() * elements[1][2] + v.w() * elements[1][3], |
27 | 0 | v.x() * elements[2][0] + v.y() * elements[2][1] + v.z() * elements[2][2] + v.w() * elements[2][3], |
28 | 0 | v.x() * elements[3][0] + v.y() * elements[3][1] + v.z() * elements[3][2] + v.w() * elements[3][3]); |
29 | 0 | } Unexecuted instantiation: Interpolation.cpp:Gfx::VectorN<4ul, float> Gfx::operator*<float>(Gfx::Matrix<4ul, float> const&, Gfx::VectorN<4ul, float> const&) Unexecuted instantiation: DOMMatrixReadOnly.cpp:Gfx::VectorN<4ul, double> Gfx::operator*<double>(Gfx::Matrix<4ul, double> const&, Gfx::VectorN<4ul, double> const&) Unexecuted instantiation: VideoFrame.cpp:Gfx::VectorN<4ul, float> Gfx::operator*<float>(Gfx::Matrix<4ul, float> const&, Gfx::VectorN<4ul, float> const&) Unexecuted instantiation: ColorConverter.cpp:Gfx::VectorN<4ul, float> Gfx::operator*<float>(Gfx::Matrix<4ul, float> const&, Gfx::VectorN<4ul, float> const&) |
30 | | |
31 | | // FIXME: this is a specific Matrix4x4 * Vector3 interaction that implies W=1; maybe move this out of LibGfx |
32 | | // or replace a Matrix4x4 * Vector4 operation? |
33 | | template<typename T> |
34 | | constexpr static Vector3<T> transform_point(Matrix4x4<T> const& m, Vector3<T> const& p) |
35 | | { |
36 | | auto const& elements = m.elements(); |
37 | | return Vector3<T>( |
38 | | p.x() * elements[0][0] + p.y() * elements[0][1] + p.z() * elements[0][2] + elements[0][3], |
39 | | p.x() * elements[1][0] + p.y() * elements[1][1] + p.z() * elements[1][2] + elements[1][3], |
40 | | p.x() * elements[2][0] + p.y() * elements[2][1] + p.z() * elements[2][2] + elements[2][3]); |
41 | | } |
42 | | |
43 | | template<typename T> |
44 | | constexpr static Matrix4x4<T> translation_matrix(Vector3<T> const& p) |
45 | 0 | { |
46 | 0 | return Matrix4x4<T>( |
47 | 0 | 1, 0, 0, p.x(), |
48 | 0 | 0, 1, 0, p.y(), |
49 | 0 | 0, 0, 1, p.z(), |
50 | 0 | 0, 0, 0, 1); |
51 | 0 | } |
52 | | |
53 | | template<typename T> |
54 | | constexpr static Matrix4x4<T> scale_matrix(Vector3<T> const& s) |
55 | 0 | { |
56 | 0 | return Matrix4x4<T>( |
57 | 0 | s.x(), 0, 0, 0, |
58 | 0 | 0, s.y(), 0, 0, |
59 | 0 | 0, 0, s.z(), 0, |
60 | 0 | 0, 0, 0, 1); |
61 | 0 | } |
62 | | |
63 | | template<typename T> |
64 | | constexpr static Matrix4x4<T> rotation_matrix(Vector3<T> const& axis, T angle) |
65 | 0 | { |
66 | 0 | T c, s; |
67 | 0 | AK::sincos(angle, s, c); |
68 | 0 | T t = 1 - c; |
69 | 0 | T x = axis.x(); |
70 | 0 | T y = axis.y(); |
71 | 0 | T z = axis.z(); |
72 | |
|
73 | 0 | return Matrix4x4<T>( |
74 | 0 | t * x * x + c, t * x * y - z * s, t * x * z + y * s, 0, |
75 | 0 | t * x * y + z * s, t * y * y + c, t * y * z - x * s, 0, |
76 | 0 | t * x * z - y * s, t * y * z + x * s, t * z * z + c, 0, |
77 | 0 | 0, 0, 0, 1); |
78 | 0 | } Unexecuted instantiation: Transformation.cpp:Gfx::Matrix<4ul, float> Gfx::rotation_matrix<float>(Gfx::VectorN<3ul, float> const&, float) Unexecuted instantiation: DOMMatrix.cpp:Gfx::Matrix<4ul, double> Gfx::rotation_matrix<double>(Gfx::VectorN<3ul, double> const&, double) |
79 | | |
80 | | template<typename T> |
81 | | Gfx::AffineTransform extract_2d_affine_transform(Matrix4x4<T> const& matrix) |
82 | 0 | { |
83 | 0 | auto* m = matrix.elements(); |
84 | 0 | return Gfx::AffineTransform(m[0][0], m[1][0], m[0][1], m[1][1], m[0][3], m[1][3]); |
85 | 0 | } |
86 | | |
87 | | typedef Matrix4x4<float> FloatMatrix4x4; |
88 | | typedef Matrix4x4<double> DoubleMatrix4x4; |
89 | | } |
90 | | |
91 | | using Gfx::DoubleMatrix4x4; |
92 | | using Gfx::FloatMatrix4x4; |
93 | | using Gfx::Matrix4x4; |