HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
vector.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 "../numeric_array.hpp"
8
9namespace tt {
10namespace geo {
11
19template<int D>
20class vector {
21public:
22 static_assert(D == 2 || D == 3, "Only 2D or 3D vectors are supported");
23
24 constexpr vector(vector const &) noexcept = default;
25 constexpr vector(vector &&) noexcept = default;
26 constexpr vector &operator=(vector const &) noexcept = default;
27 constexpr vector &operator=(vector &&) noexcept = default;
28
31 template<int E>
32 requires(E < D) [[nodiscard]] constexpr vector(vector<E> const &other) noexcept : _v(static_cast<f32x4>(other))
33 {
34 tt_axiom(is_valid());
35 }
36
39 [[nodiscard]] constexpr explicit operator f32x4() const noexcept
40 {
41 return _v;
42 }
43
46 [[nodiscard]] constexpr explicit vector(f32x4 const &other) noexcept : _v(other)
47 {
48 tt_axiom(is_valid());
49 }
50
53 [[nodiscard]] constexpr vector() noexcept : _v(0.0f, 0.0f, 0.0f, 0.0f) {}
54
59 [[nodiscard]] constexpr vector(float x, float y) noexcept requires(D == 2) : _v(x, y, 0.0f, 0.0f) {}
60
66 [[nodiscard]] constexpr vector(float x, float y, float z = 0.0f) noexcept requires(D == 3) : _v(x, y, z, 0.0f) {}
67
71 [[nodiscard]] constexpr float &x() noexcept
72 {
73 return _v.x();
74 }
75
79 [[nodiscard]] constexpr float &y() noexcept
80 {
81 return _v.y();
82 }
83
87 [[nodiscard]] constexpr float &z() noexcept requires(D == 3)
88 {
89 return _v.z();
90 }
91
95 [[nodiscard]] constexpr float const &x() const noexcept
96 {
97 return _v.x();
98 }
99
103 [[nodiscard]] constexpr float const &y() const noexcept
104 {
105 return _v.y();
106 }
107
111 [[nodiscard]] constexpr float const &z() const noexcept requires(D == 3)
112 {
113 return _v.z();
114 }
115
119 [[nodiscard]] constexpr vector operator-() const noexcept
120 {
121 tt_axiom(is_valid());
122 return vector{-_v};
123 }
124
130 [[nodiscard]] constexpr friend vector operator+(vector const &lhs, vector const &rhs) noexcept
131 {
132 tt_axiom(lhs.is_valid() && rhs.is_valid());
133 return vector{lhs._v + rhs._v};
134 }
135
141 [[nodiscard]] constexpr friend vector operator-(vector const &lhs, vector const &rhs) noexcept
142 {
143 tt_axiom(lhs.is_valid() && rhs.is_valid());
144 return vector{lhs._v - rhs._v};
145 }
146
152 [[nodiscard]] constexpr friend vector operator*(vector const &lhs, float const &rhs) noexcept
153 {
154 tt_axiom(lhs.is_valid());
155 return vector{lhs._v * rhs};
156 }
157
163 [[nodiscard]] constexpr friend vector operator*(float const &lhs, vector const &rhs) noexcept
164 {
165 tt_axiom(rhs.is_valid());
166 return vector{lhs * rhs._v};
167 }
168
174 [[nodiscard]] constexpr friend bool operator==(vector const &lhs, vector const &rhs) noexcept
175 {
176 tt_axiom(lhs.is_valid() && rhs.is_valid());
177 return lhs._v == rhs._v;
178 }
179
184 [[nodiscard]] constexpr friend float squared_hypot(vector const &rhs) noexcept
185 {
186 tt_axiom(rhs.is_valid());
187 return squared_hypot<element_mask>(rhs._v);
188 }
189
194 [[nodiscard]] constexpr friend float hypot(vector const &rhs) noexcept
195 {
196 tt_axiom(rhs.is_valid());
197 return hypot<element_mask>(rhs._v);
198 }
199
204 [[nodiscard]] constexpr friend float rcp_hypot(vector const &rhs) noexcept
205 {
206 tt_axiom(rhs.is_valid());
207 return rcp_hypot<element_mask>(rhs._v);
208 }
209
214 [[nodiscard]] constexpr friend vector normalize(vector const &rhs) noexcept
215 {
216 tt_axiom(rhs.is_valid());
217 return vector{normalize<element_mask>(rhs._v)};
218 }
219
225 [[nodiscard]] constexpr friend float dot(vector const &lhs, vector const &rhs) noexcept
226 {
227 tt_axiom(lhs.is_valid() && rhs.is_valid());
228 return dot<element_mask>(lhs._v, rhs._v);
229 }
230
234 [[nodiscard]] constexpr bool is_valid() const noexcept
235 {
236 return _v.w() == 0.0f && (D == 3 || _v.z() == 0.0f);
237 }
238
239private:
240 f32x4 _v;
241
242 static constexpr size_t element_mask = (1_uz << D) - 1;
243};
244
249[[nodiscard]] constexpr vector<2> cross(vector<2> const &rhs) noexcept
250{
251 tt_axiom(rhs.is_valid());
252 return vector<2>{cross_2D(static_cast<f32x4>(rhs))};
253}
254
259[[nodiscard]] constexpr vector<2> normal(vector<2> const &rhs) noexcept
260{
261 tt_axiom(rhs.is_valid());
262 return normalize(cross(rhs));
263}
264
273[[nodiscard]] constexpr float cross(vector<2> const &lhs, vector<2> const &rhs) noexcept
274{
275 tt_axiom(lhs.is_valid() && rhs.is_valid());
276 return cross_2D(static_cast<f32x4>(lhs), static_cast<f32x4>(rhs));
277}
278
284[[nodiscard]] constexpr vector<3> cross(vector<3> const &lhs, vector<3> const &rhs) noexcept
285{
286 tt_axiom(lhs.is_valid() && rhs.is_valid());
287 return vector<3>{cross_3D(static_cast<f32x4>(lhs), static_cast<f32x4>(rhs))};
288}
289
290}
291
292using vector2 = geo::vector<2>;
293using vector3 = geo::vector<3>;
294
295} // namespace tt
A high-level geometric vector Part of the high-level vector, point, mat and color types.
Definition vector.hpp:20
constexpr float const & x() const noexcept
Access the x element from the vector.
Definition vector.hpp:95
constexpr vector(f32x4 const &other) noexcept
Construct a vector from a f32x4-numeric_array.
Definition vector.hpp:46
constexpr float & x() noexcept
Access the x element from the vector.
Definition vector.hpp:71
constexpr vector(float x, float y) noexcept
Construct a 2D vector from x and y elements.
Definition vector.hpp:59
constexpr friend float hypot(vector const &rhs) noexcept
Get the length of the vector.
Definition vector.hpp:194
constexpr vector(float x, float y, float z=0.0f) noexcept
Construct a 3D vector from x, y and z elements.
Definition vector.hpp:66
constexpr friend bool operator==(vector const &lhs, vector const &rhs) noexcept
Compare if two vectors are equal.
Definition vector.hpp:174
constexpr float const & y() const noexcept
Access the y element from the vector.
Definition vector.hpp:103
constexpr friend vector normalize(vector const &rhs) noexcept
Normalize a vector to a unit vector.
Definition vector.hpp:214
constexpr friend vector operator*(float const &lhs, vector const &rhs) noexcept
Scale the vector by a scaler.
Definition vector.hpp:163
constexpr vector() noexcept
Construct a empty vector / zero length.
Definition vector.hpp:53
constexpr friend vector operator-(vector const &lhs, vector const &rhs) noexcept
Subtract two vectors from each other.
Definition vector.hpp:141
constexpr float & z() noexcept
Access the z element from the vector.
Definition vector.hpp:87
constexpr vector operator-() const noexcept
Mirror this vector.
Definition vector.hpp:119
constexpr vector(vector< E > const &other) noexcept
Construct a vector from a lower dimension vector.
Definition vector.hpp:32
constexpr friend vector operator*(vector const &lhs, float const &rhs) noexcept
Scale the vector by a scaler.
Definition vector.hpp:152
constexpr float const & z() const noexcept
Access the z element from the vector.
Definition vector.hpp:111
constexpr friend float squared_hypot(vector const &rhs) noexcept
Get the squared length of the vector.
Definition vector.hpp:184
constexpr bool is_valid() const noexcept
Check if the vector is valid.
Definition vector.hpp:234
constexpr friend float dot(vector const &lhs, vector const &rhs) noexcept
Get the dot product between two vectors.
Definition vector.hpp:225
constexpr friend float rcp_hypot(vector const &rhs) noexcept
Get the length of the vector.
Definition vector.hpp:204
constexpr friend vector operator+(vector const &lhs, vector const &rhs) noexcept
Add two vectors from each other.
Definition vector.hpp:130
constexpr float & y() noexcept
Access the y element from the vector.
Definition vector.hpp:79