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)
47 float c2r2)
noexcept requires(D == 3) :
48 _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)
68 float c3r3)
noexcept requires(D == 3) :
69 _col0(c0r0, c0r1, c0r2, c0r3), _col1(c1r0, c1r1, c1r2, c1r3), _col2(c2r0, c2r1, c2r2, c2r3), _col3(c3r0, c3r1, c3r2, c3r3)
74 requires(E < D) [[nodiscard]]
constexpr matrix(
matrix<E> const &other) noexcept :
75 _col0(get<0>(other)), _col1(get<1>(other)), _col2(get<2>(other)), _col3(get<3>(other))
80 requires(E < D)
constexpr matrix &
operator=(
matrix<E> const &rhs)
noexcept
101 [[nodiscard]]
friend constexpr f32x4 get(
matrix const &rhs)
noexcept
103 if constexpr (I == 0) {
105 }
else if constexpr (I == 1) {
107 }
else if constexpr (I == 2) {
109 }
else if constexpr (I == 3) {
112 tt_static_no_default();
116 [[nodiscard]]
constexpr bool is_valid()
const noexcept
121 [[nodiscard]]
constexpr auto operator*(
f32x4 const &rhs)
const noexcept
123 return f32x4{_col0 * rhs.xxxx() + _col1 * rhs.yyyy() + _col2 * rhs.zzzz() + _col3 * rhs.wwww()};
127 [[nodiscard]]
constexpr auto operator*(
vector<E> const &rhs)
const noexcept
129 tt_axiom(rhs.is_valid());
131 _col0 *
static_cast<f32x4>(rhs).xxxx() + _col1 *
static_cast<f32x4>(rhs).yyyy() +
132 _col2 *
static_cast<f32x4>(rhs).zzzz()};
136 [[nodiscard]]
constexpr auto operator*(
extent<E> const &rhs)
const noexcept
138 tt_axiom(rhs.is_valid());
140 _col0 *
static_cast<f32x4>(rhs).xxxx() + _col1 *
static_cast<f32x4>(rhs).yyyy() +
141 _col2 *
static_cast<f32x4>(rhs).zzzz()};
145 [[nodiscard]]
constexpr auto operator*(
point<E> const &rhs)
const noexcept
147 tt_axiom(rhs.is_valid());
149 _col0 *
static_cast<f32x4>(rhs).xxxx() + _col1 *
static_cast<f32x4>(rhs).yyyy() +
150 _col2 *
static_cast<f32x4>(rhs).zzzz() + _col3 *
static_cast<f32x4>(rhs).wwww()};
153 [[nodiscard]]
constexpr auto operator*(
rect const &rhs)
const noexcept
155 return rect{*
this * rhs.corner<0>(), *
this * rhs.corner<1>(), *
this * rhs.corner<2>(), *
this * rhs.corner<3>()};
164 tt_axiom(rhs.is_valid());
166 _col0 *
static_cast<f32x4>(rhs).xxxx() + _col1 *
static_cast<f32x4>(rhs).yyyy() +
167 _col2 *
static_cast<f32x4>(rhs).zzzz() + _col3};
177 return matrix<D>{*
this * get<0>(rhs), *
this * get<1>(rhs), *
this * get<2>(rhs), *
this * get<3>(rhs)};
184 return matrix<3>{*
this * get<0>(rhs), *
this * get<1>(rhs), *
this * get<2>(rhs), *
this * get<3>(rhs)};
191 auto tmp =
transpose(rhs._col0, rhs._col1, rhs._col2, rhs._col3);
192 return {std::get<0>(tmp), std::get<1>(tmp), std::get<2>(tmp), std::get<3>(tmp)};
196 [[nodiscard]]
constexpr bool operator==(
matrix<E> const &rhs)
const noexcept
198 return _col0 == rhs._col0 && _col1 == rhs._col1 && _col2 == rhs._col2 && _col3 == rhs._col3;
210 ttlet s0c0 = _col0 * _col1.yxwz();
216 ttlet s1c1 = _col0 * _col2.yxwz();
217 ttlet s0c0s1c1 = hsub(s0c0, s1c1);
223 ttlet s2c2 = _col0 * _col3.yxwz();
229 ttlet s3c3 = _col1 * _col2.yxwz();
230 ttlet s2c2s3c3 = hsub(s2c2, s3c3);
236 ttlet s4c4 = _col1 * _col3.yxwz();
242 ttlet s5c5 = _col2 * _col3.yxwz();
243 ttlet s4c4s5c5 = hsub(s4c4, s5c5);
251 ttlet s0123 = s0c0s1c1.xz00() + s2c2s3c3._00xz();
252 ttlet s45__ = s4c4s5c5.xz00();
254 ttlet c5432 = s4c4s5c5.wy00() + s2c2s3c3._00wy();
255 ttlet c10__ = s0c0s1c1.wy00();
257 ttlet det_prod_half0 = neg<0b0010>(s0123 * c5432);
258 ttlet det_prod_half1 = neg<0b0001>(s45__ * c10__);
260 ttlet det_sum0 = hadd(det_prod_half0, det_prod_half1);
261 ttlet det_sum1 = hadd(det_sum0, det_sum0);
262 ttlet det = hadd(det_sum1, det_sum1).xxxx();
264 if (det.x() == 0.0f) {
268 ttlet invdet = rcp(det);
277 auto tmp_c5543 = neg<0b1010>(c5432.xxyz());
278 auto tmp_c4221 = neg<0b0101>(c5432.yww0() + c10__._000x());
279 auto tmp_c3100 = neg<0b1010>(c5432.z000() + c10__._0xyy());
280 ttlet inv_col0 = ((t._col1.yxxx() * tmp_c5543) + (t._col1.zzyy() * tmp_c4221) + (t._col1.wwwz() * tmp_c3100)) * invdet;
286 tmp_c5543 = -tmp_c5543;
287 tmp_c4221 = -tmp_c4221;
288 tmp_c3100 = -tmp_c3100;
289 ttlet inv_col1 = ((t._col0.yxxx() * tmp_c5543) + (t._col0.zzyy() * tmp_c4221) + (t._col0.wwwz() * tmp_c3100)) * invdet;
295 auto tmp_s5543 = neg<0b1010>(s45__.yyx0() + s0123._000w());
296 auto tmp_s4221 = neg<0b0101>(s45__.x000() + s0123._0zzy());
297 auto tmp_s3100 = neg<0b1010>(s0123.wyxx());
298 ttlet inv_col2 = ((t._col3.yxxx() * tmp_s5543) + (t._col3.zzyy() * tmp_s4221) + (t._col3.wwwz() * tmp_s3100)) * invdet;
304 tmp_s5543 = -tmp_s5543;
305 tmp_s4221 = -tmp_s4221;
306 tmp_s3100 = -tmp_s3100;
307 ttlet inv_col3 = ((t._col2.yxxx() * tmp_s5543) + (t._col2.zzyy() * tmp_s4221) + (t._col2.wwwz() * tmp_s3100)) * invdet;
309 return {inv_col0, inv_col1, inv_col2, inv_col3};
static constexpr matrix uniform(aarect src_rectangle, aarect dst_rectangle, alignment alignment) noexcept
Create a transformation matrix to translate and uniformly-scale a src_rectangle to a dst_rectangle.
Definition scale.hpp:140