HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
scale.hpp
1// Copyright Take Vos 2021.
2// Distributed under the Boost Software License, Version 1.0.
3// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
4
5#pragma once
6
7#include "matrix.hpp"
8#include "identity.hpp"
9#include "translate.hpp"
10
11namespace tt {
12namespace geo {
13
14template<int D>
15class scale {
16public:
17 static_assert(D == 2 || D == 3, "Only 2D or 3D scale-matrices are supported");
18
19 constexpr scale(scale const &) noexcept = default;
20 constexpr scale(scale &&) noexcept = default;
21 constexpr scale &operator=(scale const &) noexcept = default;
22 constexpr scale &operator=(scale &&) noexcept = default;
23
24 [[nodiscard]] constexpr explicit operator f32x4() const noexcept
25 {
26 tt_axiom(is_valid());
27 return _v;
28 }
29
30 [[nodiscard]] constexpr explicit scale(f32x4 const &v) noexcept : _v(v)
31 {
32 tt_axiom(is_valid());
33 }
34
35 [[nodiscard]] constexpr operator matrix<D>() const noexcept
36 {
37 tt_axiom(is_valid());
38 return matrix<D>{_v.x000(), _v._0y00(), _v._00z0(), _v._000w()};
39 }
40
41 [[nodiscard]] constexpr scale() noexcept : _v(1.0, 1.0, 1.0, 1.0) {}
42
43 [[nodiscard]] constexpr scale(identity const &) noexcept : _v(1.0, 1.0, 1.0, 1.0) {}
44
45 [[nodiscard]] constexpr scale(float value) noexcept requires(D == 2) : _v(value, value, 1.0, 1.0) {}
46
47 [[nodiscard]] constexpr scale(float value) noexcept requires(D == 3) : _v(value, value, value, 1.0) {}
48
49 [[nodiscard]] constexpr scale(float x, float y) noexcept requires(D == 2) : _v(x, y, 1.0, 1.0) {}
50
51 [[nodiscard]] constexpr scale(float x, float y, float z = 1.0) noexcept requires(D == 3) : _v(x, y, z, 1.0) {}
52
58 template<int E, int F>
59 requires(E <= D && F <= D) [[nodiscard]] static constexpr scale uniform(vector<E> src_extent, vector<F> dst_extent) noexcept
60 {
61 tt_axiom(dst_extent.x() != 0.0f && src_extent.x() != 0.0f);
62 tt_axiom(dst_extent.y() != 0.0f && src_extent.y() != 0.0f);
63
64 if constexpr (D == 2) {
65 ttlet non_uniform_scale = static_cast<f32x4>(dst_extent).xyxy() / static_cast<f32x4>(src_extent).xyxy();
66 ttlet uniform_scale = std::min(non_uniform_scale.x(), non_uniform_scale.y());
67 return scale{uniform_scale};
68
69 } else if constexpr (D == 3) {
70 tt_axiom(dst_extent.z() != 0.0f && src_extent.z() != 0.0f);
71 ttlet non_uniform_scale = static_cast<f32x4>(dst_extent).xyzx() / static_cast<f32x4>(src_extent).xyzx();
72 ttlet uniform_scale = std::min({non_uniform_scale.x(), non_uniform_scale.y(), non_uniform_scale.z()});
73 return scale{uniform_scale};
74
75 } else {
76 tt_static_no_default();
77 }
78 }
79
80 [[nodiscard]] constexpr f32x4 operator*(f32x4 const &rhs) const noexcept
81 {
82 tt_axiom(is_valid());
83 return _v * rhs;
84 }
85
86 template<int E>
87 [[nodiscard]] constexpr vector<E> operator*(vector<E> const &rhs) const noexcept
88 {
89 tt_axiom(is_valid() && rhs.is_valid());
90 return vector<E>{_v * static_cast<f32x4>(rhs)};
91 }
92
93 template<int E>
94 [[nodiscard]] constexpr point<E> operator*(point<E> const &rhs) const noexcept
95 {
96 tt_axiom(is_valid() && rhs.is_valid());
97 return point<E>{_v * static_cast<f32x4>(rhs)};
98 }
99
100 [[nodiscard]] constexpr aarect operator*(aarect const &rhs) const noexcept requires(D == 2)
101 {
102 return aarect::p0p3(_v * rhs.p0(), _v * rhs.p3());
103 }
104
105 [[nodiscard]] constexpr rect operator*(rect const &rhs) const noexcept
106 {
107 return rect{_v * rhs.corner<0>(), _v * rhs.corner<1>(), _v * rhs.corner<2>(), _v * rhs.corner<3>()};
108 }
109
110 [[nodiscard]] constexpr scale operator*(identity const &) const noexcept
111 {
112 tt_axiom(is_valid());
113 return *this;
114 }
115
116 template<int E>
117 [[nodiscard]] constexpr auto operator*(scale<E> const &rhs) const noexcept
118 {
119 tt_axiom(is_valid() && rhs.is_valid());
120 return scale<std::max(D, E)>{_v * static_cast<f32x4>(rhs)};
121 }
122
123 template<int E>
124 [[nodiscard]] constexpr bool operator==(scale<E> const &rhs) const noexcept
125 {
126 tt_axiom(is_valid() && rhs.is_valid());
127 return {_v == static_cast<f32x4>(rhs)};
128 }
129
130 [[nodiscard]] constexpr bool is_valid() const noexcept
131 {
132 return _v.w() == 1.0f && (D == 3 || _v.z() == 1.0f);
133 }
134
135private:
136 f32x4 _v;
137};
138
139template<int D>
140[[nodiscard]] constexpr matrix<D> matrix<D>::uniform(aarect src_rectangle, aarect dst_rectangle, alignment alignment) noexcept
141{
142 ttlet scale = tt::geo::scale<D>::uniform(vector2{src_rectangle.extent()}, vector2{dst_rectangle.extent()});
143 ttlet scaled_rectangle = scale * src_rectangle;
144 ttlet translation = translate<D>::align(scaled_rectangle, dst_rectangle, alignment);
145 return translation * scale;
146}
147
148
149} // namespace geo
150
151using scale2 = geo::scale<2>;
152using scale3 = geo::scale<3>;
153
154} // namespace tt
static axis_aligned_rectangle p0p3(numeric_array< float, 4 > const &v) noexcept
Create axis_aligned_rectangle from packed p0p3 coordinates.
Definition aarect.hpp:86
Definition identity.hpp:11
Definition matrix.hpp:18
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
Definition scale.hpp:15
static constexpr scale uniform(vector< E > src_extent, vector< F > dst_extent) noexcept
Get a uniform-scale-transform to scale an extent to another extent.
Definition scale.hpp:59
static constexpr translate align(aarect src_rectangle, aarect dst_rectangle, alignment alignment) noexcept
Align a rectangle within another rectangle.
Definition translate.hpp:72
A high-level geometric vector Part of the high-level vector, point, mat and color types.
Definition vector.hpp:20
constexpr float & x() noexcept
Access the x element from the vector.
Definition vector.hpp:71
constexpr float & z() noexcept
Access the z element from the vector.
Definition vector.hpp:87
constexpr float & y() noexcept
Access the y element from the vector.
Definition vector.hpp:79
Class which represents an rectangle.
Definition rect.hpp:16
T max(T... args)
T min(T... args)