sandbox
Loading...
Searching...
No Matches
matrix4x4.hpp
1#ifndef LIBSBX_MATH_MATRIX4X4_HPP_
2#define LIBSBX_MATH_MATRIX4X4_HPP_
3
4#include <array>
5#include <cstddef>
6#include <cmath>
7#include <cinttypes>
8#include <concepts>
9#include <fstream>
10#include <ostream>
11#include <type_traits>
12
13#include <fmt/format.h>
14
15#include <libsbx/math/concepts.hpp>
16#include <libsbx/math/fwd.hpp>
17#include <libsbx/math/vector3.hpp>
18#include <libsbx/math/vector4.hpp>
19#include <libsbx/math/matrix.hpp>
20#include <libsbx/math/matrix3x3.hpp>
21#include <libsbx/math/angle.hpp>
22
23namespace sbx::math {
24
25template<scalar Type>
26class basic_matrix4x4 : public basic_matrix<4u, 4u, Type> {
27
29
30 template<scalar Other>
32
33 inline static constexpr auto x_axis = std::size_t{0u};
34 inline static constexpr auto y_axis = std::size_t{1u};
35 inline static constexpr auto z_axis = std::size_t{2u};
36 inline static constexpr auto w_axis = std::size_t{3u};
37
38public:
39
40 using value_type = base_type::value_type;
41 using reference = base_type::reference;
42 using const_reference = base_type::const_reference;
43 using size_type = base_type::size_type;
45
46 inline static constexpr basic_matrix4x4 identity{base_type::identity()};
47
48 inline static constexpr basic_matrix4x4 zero{base_type{value_type{0}}};
49
50 using base_type::base_type;
51
52 constexpr basic_matrix4x4(const base_type& base) noexcept;
53
54 template<scalar Other>
55 constexpr basic_matrix4x4(
56 const column_type_for<Other>& column0,
57 const column_type_for<Other>& column1,
58 const column_type_for<Other>& column2,
59 const column_type_for<Other>& column3
60 ) noexcept;
61
62 template<scalar Other>
63 constexpr basic_matrix4x4(
64 Other x0, Other x1, Other x2, Other x3,
65 Other y0, Other y1, Other y2, Other y3,
66 Other z0, Other z1, Other z2, Other z3,
67 Other w0, Other w1, Other w2, Other w3
68 ) noexcept;
69
70 template<scalar Other>
71 constexpr basic_matrix4x4(const Other v00, const Other v11, const Other v22, const Other v33) noexcept;
72
73 template<scalar Other>
74 constexpr basic_matrix4x4(const basic_matrix3x3<Other>& other) noexcept
75 : base_type{column_type{other[0], 0}, column_type{other[1], 0}, column_type{other[2], 0}, column_type{0, 0, 0, 1}} { }
76
77 constexpr basic_matrix4x4(const basic_matrix4x4& other) noexcept = default;
78
79 constexpr basic_matrix4x4(basic_matrix4x4&& other) noexcept = default;
80
81 constexpr auto operator=(const basic_matrix4x4& other) noexcept -> basic_matrix4x4& = default;
82
83 constexpr auto operator=(basic_matrix4x4&& other) noexcept -> basic_matrix4x4& = default;
84
85 // -- Static member functions --
86
87 [[nodiscard]] constexpr static auto transposed(const basic_matrix4x4& matrix) noexcept -> basic_matrix4x4;
88
89 [[nodiscard]] constexpr static auto inverted(const basic_matrix4x4& matrix) -> basic_matrix4x4;
90
91 [[nodiscard]] constexpr static auto look_at(const basic_vector3<value_type>& position, const basic_vector3<value_type>& target, const basic_vector3<value_type>& up) noexcept -> basic_matrix4x4;
92
93 [[nodiscard]] constexpr static auto perspective(const basic_angle<value_type>& fov, const value_type aspect, const value_type near, const value_type far) noexcept -> basic_matrix4x4;
94
95 [[nodiscard]] constexpr static auto orthographic(const value_type left, const value_type right, const value_type bottom, const value_type top) noexcept -> basic_matrix4x4;
96
97 [[nodiscard]] constexpr static auto orthographic(const value_type left, const value_type right, const value_type bottom, const value_type top, const value_type near, const value_type far) noexcept -> basic_matrix4x4;
98
99 [[nodiscard]] constexpr static auto translated(const basic_matrix4x4& matrix, const basic_vector3<value_type>& vector) noexcept -> basic_matrix4x4;
100
101 [[nodiscard]] constexpr static auto scaled(const basic_matrix4x4& matrix, const basic_vector3<value_type>& vector) noexcept -> basic_matrix4x4;
102
103 [[nodiscard]] constexpr static auto rotated(const basic_matrix4x4& matrix, const basic_vector3<value_type>& axis, const basic_angle<value_type>& angle) noexcept -> basic_matrix4x4;
104
105 [[nodiscard]] constexpr static auto rotation_from_euler_angles(const basic_vector3<value_type>& euler_angles) noexcept -> basic_matrix4x4;
106
107 constexpr auto operator[](size_type index) const noexcept -> const column_type&;
108
109 constexpr auto operator[](size_type index) noexcept -> column_type&;
110
111}; // class basic_matrix4x4
112
113template<scalar Lhs, scalar Rhs>
114[[nodiscard]] constexpr auto operator+(basic_matrix4x4<Lhs> lhs, const basic_matrix4x4<Rhs>& rhs) noexcept -> basic_matrix4x4<Lhs>;
115
116template<scalar Lhs, scalar Rhs>
117[[nodiscard]] constexpr auto operator-(basic_matrix4x4<Lhs> lhs, const basic_matrix4x4<Rhs>& rhs) noexcept -> basic_matrix4x4<Lhs>;
118
119template<scalar Lhs, scalar Rhs>
120[[nodiscard]] constexpr auto operator*(basic_matrix4x4<Lhs> lhs, Rhs scalar) noexcept -> basic_matrix4x4<Lhs>;
121
122template<scalar Lhs, scalar Rhs>
123[[nodiscard]] constexpr auto operator*(basic_matrix4x4<Lhs> lhs, const basic_vector4<Rhs>& rhs) noexcept -> basic_vector4<Lhs>;
124
125template<scalar Lhs, scalar Rhs>
126[[nodiscard]] constexpr auto operator*(basic_matrix4x4<Lhs> lhs, const basic_matrix4x4<Rhs>& rhs) noexcept -> basic_matrix4x4<Lhs>;
127
128template<scalar Lhs, scalar Rhs>
129[[nodiscard]] constexpr auto operator/(basic_matrix4x4<Lhs> lhs, Rhs scalar) noexcept -> basic_matrix4x4<Lhs>;
130
131// template<scalar Scalar>
132// [[nodiscard]] constexpr auto matrix_cast(const basic_matrix4x4<Scalar>& matrix) -> math::basic_matrix3x3<Scalar> {
133// return math::basic_matrix3x3<Scalar>{
134// matrix[0][0], matrix[1][0], matrix[2][0],
135// matrix[0][1], matrix[1][1], matrix[2][1],
136// matrix[0][2], matrix[1][2], matrix[2][2]
137// };
138// }
139
140// template<scalar Scalar>
141// [[nodiscard]] constexpr auto matrix_cast(const basic_matrix3x3<Scalar>& matrix) -> math::basic_matrix4x4<Scalar> {
142// return math::basic_matrix3x3<Scalar>{
143// matrix[0][0], matrix[1][0], matrix[2][0], 0.0f,
144// matrix[0][1], matrix[1][1], matrix[2][1], 0.0f,
145// matrix[0][2], matrix[1][2], matrix[2][2], 0.0f,
146// 0.0f, 0.0f, 0.0f, 1.0f
147// };
148// }
149
150template<scalar Type>
151struct concrete_matrix<4, 4, Type> {
153}; // struct concrete_matrix
154
156
158
159using matrix4x4 = matrix4x4f;
160
161} // namespace sbx::math
162
163template<sbx::math::scalar Type>
164struct fmt::formatter<sbx::math::basic_matrix4x4<Type>> {
165
166 template<typename ParseContext>
167 constexpr auto parse(ParseContext& context) -> decltype(context.begin()) {
168 return context.begin();
169 }
170
171 template<typename FormatContext>
172 auto format(const sbx::math::basic_matrix4x4<Type>& matrix, FormatContext& context) -> decltype(context.out()) {
173 if constexpr (sbx::math::is_floating_point_v<Type>) {
174 return fmt::format_to(context.out(),
175 "\n{:.2f}, {:.2f}, {:.2f}, {:.2f}\n{:.2f}, {:.2f}, {:.2f}, {:.2f}\n{:.2f}, {:.2f}, {:.2f}, {:.2f}\n{:.2f}, {:.2f}, {:.2f}, {:.2f}",
176 matrix[0][0], matrix[1][0], matrix[2][0], matrix[3][0],
177 matrix[0][1], matrix[1][1], matrix[2][1], matrix[3][1],
178 matrix[0][2], matrix[1][2], matrix[2][2], matrix[3][2],
179 matrix[0][3], matrix[1][3], matrix[2][3], matrix[3][3]
180 );
181 } else {
182 return fmt::format_to(context.out(),
183 "\n{}, {}, {}, {}\n{}, {}, {}, {}\n{}, {}, {}, {}\n{}, {}, {}, {}",
184 matrix[0][0], matrix[1][0], matrix[2][0], matrix[3][0],
185 matrix[0][1], matrix[1][1], matrix[2][1], matrix[3][1],
186 matrix[0][2], matrix[1][2], matrix[2][2], matrix[3][2],
187 matrix[0][3], matrix[1][3], matrix[2][3], matrix[3][3]
188 );
189 }
190 }
191
192}; // struct fmt::formatter
193
194#include <libsbx/math/matrix4x4.ipp>
195
196#endif // LIBSBX_MATH_MATRIX4X4_HPP_
Definition: angle.hpp:279
Definition: matrix3x3.hpp:25
Definition: matrix4x4.hpp:26
Definition: matrix.hpp:13
Definition: vector3.hpp:22
Definition: vector4.hpp:22
Definition: fwd.hpp:16