11#include "translate2.hpp"
15#include "../macros.hpp"
21hi_export_module(hikogui.geometry : matrix2);
23hi_export
namespace hi {
inline namespace v1 {
50 auto const a = f32x4::broadcast(1.0f);
64 constexpr matrix2(f32x4 col0, f32x4 col1, f32x4 col2, f32x4 col3 = f32x4{0.0f, 0.0f, 0.0f, 1.0f})
noexcept :
65 _col0(col0), _col1(col1), _col2(col2), _col3(col3)
67 hi_axiom(holds_invariant());
78 _col0(static_cast<f32x4>(col0)),
79 _col1(static_cast<f32x4>(col1)),
80 _col2(static_cast<f32x4>(col2)),
81 _col3(static_cast<f32x4>(col3).xyz1())
83 hi_axiom(holds_invariant());
92 _col0(
static_cast<f32x4
>(col0)),
93 _col1(
static_cast<f32x4
>(col1)),
94 _col2(f32x4{0.0f, 0.0f, 1.0f, 0.0f}),
95 _col3(f32x4{0.0f, 0.0f, 0.0f, 1.0f})
97 hi_axiom(holds_invariant());
124 float c2r2) noexcept :
125 _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)
127 hi_axiom(holds_invariant());
168 float c3r3) noexcept :
169 _col0(c0r0, c0r1, c0r2, c0r3), _col1(c1r0, c1r1, c1r2, c1r3), _col2(c2r0, c2r1, c2r2, c2r3), _col3(c3r0, c3r1, c3r2, c3r3)
171 hi_axiom(holds_invariant());
176 auto const ones = f32x4::broadcast(1.0f);
178 _col1 = ones._0y00();
179 _col2 = ones._00z0();
180 _col3 = ones._000w() + f32x4{rhs};
183 [[nodiscard]]
constexpr matrix2(scale2
const& rhs)
noexcept
185 _col0 = f32x4{rhs}.x000();
186 _col1 = f32x4{rhs}._0y00();
187 _col2 = f32x4{rhs}._00z0();
188 _col3 = f32x4{rhs}._000w();
207 auto const x_mul = f32x4{rhs}.xxxx() * f32x4{rhs};
208 auto const y_mul = f32x4{rhs}.yyyy() * f32x4{rhs};
209 auto const z_mul = f32x4{rhs}.zzzz() * f32x4{rhs};
211 auto twos = f32x4{-2.0f, 2.0f, 2.0f, 0.0f};
212 auto one = f32x4{1.0f, 0.0f, 0.0f, 0.0f};
213 _col0 =
one + addsub_mask<0b0011>(z_mul.zwxy(), y_mul.yxwz()) * twos;
216 _col1 =
one + addsub_mask<0b0110>(x_mul.yxwz(), z_mul.wzyx()) * twos;
219 _col2 =
one + addsub_mask<0b0101>(y_mul.wzyx(), x_mul.zwxy()) * twos;
227 hi_axiom(holds_invariant());
228 return {_col0, _col1, _col2, _col3};
240 [[nodiscard]]
constexpr static matrix2
243 auto const scale =
scale2::uniform(src_rectangle.size(), dst_rectangle.size());
244 auto const scaled_rectangle = scale * src_rectangle;
246 return translation * scale;
255 [[nodiscard]]
friend constexpr f32x4
const&
get(matrix2
const& rhs)
noexcept
257 if constexpr (I == 0) {
259 }
else if constexpr (I == 1) {
261 }
else if constexpr (I == 2) {
263 }
else if constexpr (I == 3) {
266 hi_static_no_default();
276 [[nodiscard]]
friend constexpr f32x4&
get(matrix2& rhs)
noexcept
278 if constexpr (I == 0) {
280 }
else if constexpr (I == 1) {
282 }
else if constexpr (I == 2) {
284 }
else if constexpr (I == 3) {
287 hi_static_no_default();
291 [[nodiscard]]
constexpr bool holds_invariant() const noexcept
293 return _col0.z() == 0.0f and _col0.w() == 0.0f and _col1.z() == 0.0f and _col1.w() == 0.0f and _col2.x() == 0.0f and
294 _col2.y() == 0.0f and _col2.z() == 1.0f and _col2.w() == 0.0f and _col3.z() == 0.0f and _col3.w() == 1.0f;
302 [[nodiscard]]
constexpr f32x4
operator*(f32x4
const& rhs)
const noexcept
304 return {_col0 * rhs.xxxx() + _col1 * rhs.yyyy() + _col2 * rhs.zzzz() + _col3 * rhs.wwww()};
309 [[nodiscard]]
friend constexpr matrix2
transpose(matrix2
const& rhs)
noexcept
311 auto tmp =
transpose(rhs._col0, rhs._col1, rhs._col2, rhs._col3);
312 return matrix2{std::get<0>(tmp), std::get<1>(tmp), std::get<2>(tmp), std::get<3>(tmp)};
348 template<
char DstX,
char DstY,
char DstZ,
char DstW = 'w'>
349 [[nodiscard]]
friend constexpr matrix2
reflect(matrix2
const& rhs)
noexcept
351 return matrix2{reflect_column<DstX>(), reflect_column<DstY>(), reflect_column<DstZ>(), reflect_column<DstW>()} * rhs;
359 [[nodiscard]]
constexpr friend bool operator==(matrix2
const& lhs, matrix2
const& rhs)
noexcept
361 return equal(lhs._col0, rhs._col0) and equal(lhs._col1, rhs._col1) and equal(lhs._col3, rhs._col3);
373 auto const s0c0 = _col0 * _col1.yxwz();
379 auto const s1c1 = _col0 * _col2.yxwz();
380 auto const s0c0s1c1 = hsub(s0c0, s1c1);
386 auto const s2c2 = _col0 * _col3.yxwz();
392 auto const s3c3 = _col1 * _col2.yxwz();
393 auto const s2c2s3c3 = hsub(s2c2, s3c3);
399 auto const s4c4 = _col1 * _col3.yxwz();
405 auto const s5c5 = _col2 * _col3.yxwz();
406 auto const s4c4s5c5 = hsub(s4c4, s5c5);
414 auto const s0123 = s0c0s1c1.xz00() + s2c2s3c3._00xz();
415 auto const s45__ = s4c4s5c5.xz00();
417 auto const c5432 = s4c4s5c5.wy00() + s2c2s3c3._00wy();
418 auto const c10__ = s0c0s1c1.wy00();
420 auto const det_prod_half0 = neg_mask<0b0010>(s0123 * c5432);
421 auto const det_prod_half1 = neg_mask<0b0001>(s45__ * c10__);
423 auto const det_sum0 = hadd(det_prod_half0, det_prod_half1);
424 auto const det_sum1 = hadd(det_sum0, det_sum0);
425 auto const det = hadd(det_sum1, det_sum1).xxxx();
427 if (det.x() == 0.0f) {
431 auto const invdet = rcp(det);
440 auto tmp_c5543 = neg_mask<0b1010>(c5432.xxyz());
441 auto tmp_c4221 = neg_mask<0b0101>(c5432.yww0() + c10__._000x());
442 auto tmp_c3100 = neg_mask<0b1010>(c5432.z000() + c10__._0xyy());
443 auto const inv_col0 = ((t._col1.yxxx() * tmp_c5543) + (t._col1.zzyy() * tmp_c4221) + (t._col1.wwwz() * tmp_c3100)) * invdet;
449 tmp_c5543 = -tmp_c5543;
450 tmp_c4221 = -tmp_c4221;
451 tmp_c3100 = -tmp_c3100;
452 auto const inv_col1 = ((t._col0.yxxx() * tmp_c5543) + (t._col0.zzyy() * tmp_c4221) + (t._col0.wwwz() * tmp_c3100)) * invdet;
458 auto tmp_s5543 = neg_mask<0b1010>(s45__.yyx0() + s0123._000w());
459 auto tmp_s4221 = neg_mask<0b0101>(s45__.x000() + s0123._0zzy());
460 auto tmp_s3100 = neg_mask<0b1010>(s0123.wyxx());
461 auto const inv_col2 = ((t._col3.yxxx() * tmp_s5543) + (t._col3.zzyy() * tmp_s4221) + (t._col3.wwwz() * tmp_s3100)) * invdet;
467 tmp_s5543 = -tmp_s5543;
468 tmp_s4221 = -tmp_s4221;
469 tmp_s3100 = -tmp_s3100;
470 auto const inv_col3 = ((t._col2.yxxx() * tmp_s5543) + (t._col2.zzyy() * tmp_s4221) + (t._col2.wwwz() * tmp_s3100)) * invdet;
472 return matrix2{inv_col0, inv_col1, inv_col2, inv_col3};
482 [[nodiscard]]
constexpr static f32x4 reflect_column() noexcept
484 if constexpr (Axis ==
'x') {
485 return f32x4{1.0f, 0.0f, 0.0f, 0.0f};
486 }
else if constexpr (Axis ==
'X') {
487 return f32x4{-1.0f, 0.0f, 0.0f, 0.0f};
488 }
else if constexpr (Axis ==
'y') {
489 return f32x4{0.0f, 1.0f, 0.0f, 0.0f};
490 }
else if constexpr (Axis ==
'Y') {
491 return f32x4{0.0f, -1.0f, 0.0f, 0.0f};
492 }
else if constexpr (Axis ==
'z') {
493 return f32x4{0.0f, 0.0f, 1.0f, 0.0f};
494 }
else if constexpr (Axis ==
'Z') {
495 return f32x4{0.0f, 0.0f, -1.0f, 0.0f};
496 }
else if constexpr (Axis ==
'w') {
497 return f32x4{0.0f, 0.0f, 0.0f, 1.0f};
498 }
else if constexpr (Axis ==
'W') {
499 return f32x4{0.0f, 0.0f, 0.0f, -1.0f};
501 hi_static_no_default();
The HikoGUI namespace.
Definition array_generic.hpp:21
The HikoGUI API version 1.
Definition array_generic.hpp:22
@ one
The number was one, and this means something in the current language.
Definition unicode_plural.hpp:35
constexpr matrix2 operator*(matrix2 const &lhs, matrix2 const &rhs) noexcept
Matrix/Matrix multiplication.
Definition transform.hpp:69
Class which represents an axis-aligned rectangle.
Definition aarectangle.hpp:33
Horizontal/Vertical alignment combination.
Definition alignment.hpp:244
A 2D or 3D homogenius matrix for transforming homogenious vectors and points.
Definition matrix2.hpp:39
constexpr matrix2(rotate2 const &rhs) noexcept
Convert quaternion to matrix.
Definition matrix2.hpp:194
constexpr matrix2(float c0r0, float c1r0, float c2r0, float c0r1, float c1r1, float c2r1, float c0r2, float c1r2, float c2r2) noexcept
Construct a 3x3 matrix from scalar values.
Definition matrix2.hpp:115
constexpr friend bool operator==(matrix2 const &lhs, matrix2 const &rhs) noexcept
Compare two matrices potentially of different dimensions.
Definition matrix2.hpp:359
constexpr matrix2(vector3 col0, vector3 col1, vector3 col2, vector3 col3=vector3{}) noexcept
Construct a matrix from four vectors.
Definition matrix2.hpp:77
friend constexpr f32x4 & get(matrix2 &rhs) noexcept
Get a column.
Definition matrix2.hpp:276
constexpr matrix2(float c0r0, float c1r0, float c2r0, float c3r0, float c0r1, float c1r1, float c2r1, float c3r1, float c0r2, float c1r2, float c2r2, float c3r2, float c0r3, float c1r3, float c2r3, float c3r3) noexcept
Construct a 4x4 matrix from scalar values.
Definition matrix2.hpp:152
constexpr f32x4 operator*(f32x4 const &rhs) const noexcept
Transform a f32x4 numeric array by the matrix.
Definition matrix2.hpp:302
static constexpr matrix2 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 matrix2.hpp:241
friend constexpr matrix2 transpose(matrix2 const &rhs) noexcept
Matrix transpose.
Definition matrix2.hpp:309
constexpr matrix2 operator~() const
Invert matrix.
Definition matrix2.hpp:366
constexpr matrix2(f32x4 col0, f32x4 col1, f32x4 col2, f32x4 col3=f32x4{0.0f, 0.0f, 0.0f, 1.0f}) noexcept
Construct a matrix from four columns.
Definition matrix2.hpp:64
constexpr matrix2(vector2 col0, vector2 col1) noexcept
Construct a matrix from two vectors.
Definition matrix2.hpp:91
constexpr matrix2() noexcept
Constructs an identity matrix.
Definition matrix2.hpp:48
friend constexpr matrix2 reflect(matrix2 const &rhs) noexcept
Reflect axis of a matrix.
Definition matrix2.hpp:349
friend constexpr f32x4 const & get(matrix2 const &rhs) noexcept
Get a column.
Definition matrix2.hpp:255
Definition rotate2.hpp:17
static constexpr scale2 uniform(extent2 src_extent, extent2 dst_extent) noexcept
Get a uniform-scale-transform to scale an extent to another extent.
Definition scale2.hpp:51
Definition translate2.hpp:18
static constexpr translate2 align(aarectangle src_rectangle, aarectangle dst_rectangle, alignment alignment) noexcept
Align a rectangle within another rectangle.
Definition translate2.hpp:84
A high-level geometric vector Part of the high-level vector, point, mat and color types.
Definition vector2.hpp:27
A high-level geometric vector Part of the high-level vector, point, mat and color types.
Definition vector3.hpp:26