20 static_assert(D == 2 || D == 3,
"Only 2D or 3D rotation-matrices are supported");
24 constexpr matrix &operator=(
matrix const &)
noexcept =
default;
25 constexpr matrix &operator=(
matrix &&)
noexcept =
default;
27 constexpr matrix() noexcept :
28 _col0(1.0f, 0.0f, 0.0f, 0.0f),
29 _col1(0.0f, 1.0f, 0.0f, 0.0f),
30 _col2(0.0f, 0.0f, 1.0f, 0.0f),
31 _col3(0.0f, 0.0f, 0.0f, 1.0f){};
34 _col0(col0), _col1(col1), _col2(col2), _col3(col3)
39 _col0(
static_cast<f32x4>(col0)),
40 _col1(
static_cast<f32x4>(col1)),
41 _col2(
static_cast<f32x4>(col2)),
42 _col3{0.0f, 0.0f, 0.0f, 1.0f}
55 float c2r2)
noexcept requires(D == 3) :
56 _col0(c0r0, c0r1, c0r2, 0.0f), _col1(c1r0, c1r1, c1r2, 0.0f), _col2(c2r0, c2r1, c2r2, 0.0f), _col3(0.0f, 0.0f, 0.0f, 1.0f)
76 float c3r3)
noexcept requires(D == 3) :
77 _col0(c0r0, c0r1, c0r2, c0r3), _col1(c1r0, c1r1, c1r2, c1r3), _col2(c2r0, c2r1, c2r2, c2r3), _col3(c3r0, c3r1, c3r2, c3r3)
82 requires(E < D) [[nodiscard]]
constexpr matrix(
matrix<E> const &other) noexcept :
83 _col0(get<0>(other)), _col1(get<1>(other)), _col2(get<2>(other)), _col3(get<3>(other))
88 requires(E < D)
constexpr matrix &
operator=(
matrix<E> const &rhs)
noexcept
109 [[nodiscard]]
friend constexpr f32x4 get(
matrix const &rhs)
noexcept
111 if constexpr (I == 0) {
113 }
else if constexpr (I == 1) {
115 }
else if constexpr (I == 2) {
117 }
else if constexpr (I == 3) {
120 tt_static_no_default();
124 [[nodiscard]]
constexpr bool is_valid()
const noexcept
129 [[nodiscard]]
constexpr auto operator*(
f32x4 const &rhs)
const noexcept
131 return f32x4{_col0 * rhs.xxxx() + _col1 * rhs.yyyy() + _col2 * rhs.zzzz() + _col3 * rhs.wwww()};
135 [[nodiscard]]
constexpr auto operator*(
vector<E> const &rhs)
const noexcept
137 tt_axiom(rhs.is_valid());
139 _col0 *
static_cast<f32x4>(rhs).xxxx() + _col1 *
static_cast<f32x4>(rhs).yyyy() +
140 _col2 *
static_cast<f32x4>(rhs).zzzz()};
144 [[nodiscard]]
constexpr auto operator*(
extent<E> const &rhs)
const noexcept
146 tt_axiom(rhs.is_valid());
148 _col0 *
static_cast<f32x4>(rhs).xxxx() + _col1 *
static_cast<f32x4>(rhs).yyyy() +
149 _col2 *
static_cast<f32x4>(rhs).zzzz()};
153 [[nodiscard]]
constexpr auto operator*(
point<E> const &rhs)
const noexcept
155 tt_axiom(rhs.is_valid());
157 _col0 *
static_cast<f32x4>(rhs).xxxx() + _col1 *
static_cast<f32x4>(rhs).yyyy() +
158 _col2 *
static_cast<f32x4>(rhs).zzzz() + _col3 *
static_cast<f32x4>(rhs).wwww()};
161 [[nodiscard]]
constexpr auto operator*(
rectangle const &rhs)
const noexcept
163 return rectangle{*
this * get<0>(rhs), *
this * get<1>(rhs), *
this * get<2>(rhs), *
this * get<3>(rhs)};
172 tt_axiom(rhs.is_valid());
174 _col0 *
static_cast<f32x4>(rhs).xxxx() + _col1 *
static_cast<f32x4>(rhs).yyyy() +
175 _col2 *
static_cast<f32x4>(rhs).zzzz() + _col3};
185 return matrix<D>{*
this * get<0>(rhs), *
this * get<1>(rhs), *
this * get<2>(rhs), *
this * get<3>(rhs)};
192 return matrix<3>{*
this * get<0>(rhs), *
this * get<1>(rhs), *
this * get<2>(rhs), *
this * get<3>(rhs)};
199 auto tmp =
transpose(rhs._col0, rhs._col1, rhs._col2, rhs._col3);
200 return {std::get<0>(tmp), std::get<1>(tmp), std::get<2>(tmp), std::get<3>(tmp)};
204 [[nodiscard]]
constexpr bool operator==(
matrix<E> const &rhs)
const noexcept
206 return _col0 == rhs._col0 && _col1 == rhs._col1 && _col2 == rhs._col2 && _col3 == rhs._col3;
218 ttlet s0c0 = _col0 * _col1.yxwz();
224 ttlet s1c1 = _col0 * _col2.yxwz();
225 ttlet s0c0s1c1 = hsub(s0c0, s1c1);
231 ttlet s2c2 = _col0 * _col3.yxwz();
237 ttlet s3c3 = _col1 * _col2.yxwz();
238 ttlet s2c2s3c3 = hsub(s2c2, s3c3);
244 ttlet s4c4 = _col1 * _col3.yxwz();
250 ttlet s5c5 = _col2 * _col3.yxwz();
251 ttlet s4c4s5c5 = hsub(s4c4, s5c5);
259 ttlet s0123 = s0c0s1c1.xz00() + s2c2s3c3._00xz();
260 ttlet s45__ = s4c4s5c5.xz00();
262 ttlet c5432 = s4c4s5c5.wy00() + s2c2s3c3._00wy();
263 ttlet c10__ = s0c0s1c1.wy00();
265 ttlet det_prod_half0 = neg<0b0010>(s0123 * c5432);
266 ttlet det_prod_half1 = neg<0b0001>(s45__ * c10__);
268 ttlet det_sum0 = hadd(det_prod_half0, det_prod_half1);
269 ttlet det_sum1 = hadd(det_sum0, det_sum0);
270 ttlet det = hadd(det_sum1, det_sum1).xxxx();
272 if (det.x() == 0.0f) {
276 ttlet invdet = rcp(det);
285 auto tmp_c5543 = neg<0b1010>(c5432.xxyz());
286 auto tmp_c4221 = neg<0b0101>(c5432.yww0() + c10__._000x());
287 auto tmp_c3100 = neg<0b1010>(c5432.z000() + c10__._0xyy());
288 ttlet inv_col0 = ((t._col1.yxxx() * tmp_c5543) + (t._col1.zzyy() * tmp_c4221) + (t._col1.wwwz() * tmp_c3100)) * invdet;
294 tmp_c5543 = -tmp_c5543;
295 tmp_c4221 = -tmp_c4221;
296 tmp_c3100 = -tmp_c3100;
297 ttlet inv_col1 = ((t._col0.yxxx() * tmp_c5543) + (t._col0.zzyy() * tmp_c4221) + (t._col0.wwwz() * tmp_c3100)) * invdet;
303 auto tmp_s5543 = neg<0b1010>(s45__.yyx0() + s0123._000w());
304 auto tmp_s4221 = neg<0b0101>(s45__.x000() + s0123._0zzy());
305 auto tmp_s3100 = neg<0b1010>(s0123.wyxx());
306 ttlet inv_col2 = ((t._col3.yxxx() * tmp_s5543) + (t._col3.zzyy() * tmp_s4221) + (t._col3.wwwz() * tmp_s3100)) * invdet;
312 tmp_s5543 = -tmp_s5543;
313 tmp_s4221 = -tmp_s4221;
314 tmp_s3100 = -tmp_s3100;
315 ttlet inv_col3 = ((t._col2.yxxx() * tmp_s5543) + (t._col2.zzyy() * tmp_s4221) + (t._col2.wwwz() * tmp_s3100)) * invdet;
317 return {inv_col0, inv_col1, inv_col2, inv_col3};
static constexpr matrix uniform(aarectangle src_rectangle, aarectangle dst_rectangle, alignment alignment) noexcept
Create a transformation matrix to translate and uniformly-scale a src_rectangle to a dst_rectangle.
Definition scale.hpp:141