HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
extent3.hpp
Go to the documentation of this file.
1// Copyright Take Vos 2021-2022.
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
9#pragma once
10
11#include "vector3.hpp"
12#include "extent2.hpp"
13#include "../utility/utility.hpp"
14#include "../macros.hpp"
15#include <hikocpu/hikocpu.hpp>
16#include <compare>
17#include <concepts>
18#include <format>
19#include <ostream>
20#include <exception>
21
22hi_export_module(hikogui.geometry : extent3);
23
24hi_export namespace hi { inline namespace v1 {
25
33class extent3 {
34public:
35 using array_type = simd<float, 4>;
36 using value_type = array_type::value_type;
37
38 constexpr extent3(extent3 const&) noexcept = default;
39 constexpr extent3(extent3&&) noexcept = default;
40 constexpr extent3& operator=(extent3 const&) noexcept = default;
41 constexpr extent3& operator=(extent3&&) noexcept = default;
42
45 [[nodiscard]] constexpr extent3(extent2 const& other) noexcept : _v(static_cast<array_type>(other))
46 {
47 hi_axiom(holds_invariant());
48 }
49
50 [[nodiscard]] constexpr explicit operator extent2() const noexcept
51 {
52 auto tmp = _v;
53 tmp.z() = 0.0f;
54 return extent2{tmp};
55 }
56
59 [[nodiscard]] constexpr explicit operator array_type() const noexcept
60 {
61 return _v;
62 }
63
64 [[nodiscard]] constexpr explicit extent3(array_type const& other) noexcept : _v(other)
65 {
66 hi_axiom(holds_invariant());
67 }
68
69 [[nodiscard]] constexpr explicit operator bool() const noexcept
70 {
71 return _v.x() != 0.0f or _v.y() != 0.0f or _v.z() != 0.0f;
72 }
73
74 [[nodiscard]] constexpr explicit operator vector3() const noexcept
75 {
76 return vector3{static_cast<array_type>(*this)};
77 }
78
81 [[nodiscard]] constexpr extent3() noexcept : _v(0.0f, 0.0f, 0.0f, 0.0f) {}
82
88 [[nodiscard]] constexpr extent3(float width, float height, float depth = 0.0f) noexcept : _v(width, height, depth, 0.0f)
89 {
90 hi_axiom(holds_invariant());
91 }
92
93 [[nodiscard]] constexpr static extent3 infinity() noexcept
94 {
95 return extent3{
99 }
100
101 [[nodiscard]] constexpr static extent3 large() noexcept
102 {
103 return extent3{large_number_v<float>, large_number_v<float>, large_number_v<float>};
104 }
105
106 [[nodiscard]] constexpr static extent3 nan() noexcept
107 {
108 auto r = extent3{};
112 return r;
113 }
114
121 [[nodiscard]] constexpr float& width() noexcept
122 {
123 return _v.x();
124 }
125
132 [[nodiscard]] constexpr float& height() noexcept
133 {
134 return _v.y();
135 }
136
143 [[nodiscard]] constexpr float& depth() noexcept
144 {
145 return _v.z();
146 }
147
154 [[nodiscard]] constexpr float width() const noexcept
155 {
156 return _v.x();
157 }
158
165 [[nodiscard]] constexpr float height() const noexcept
166 {
167 return _v.y();
168 }
169
176 [[nodiscard]] constexpr float depth() const noexcept
177 {
178 return _v.z();
179 }
180
181 [[nodiscard]] constexpr vector3 right() const noexcept
182 {
183 return vector3{_v.x000()};
184 }
185
186 [[nodiscard]] constexpr vector3 up() const noexcept
187 {
188 return vector3{_v._0y00()};
189 }
190
191 constexpr extent3& operator+=(extent3 const& rhs) noexcept
192 {
193 return *this = *this + rhs;
194 }
195
201 [[nodiscard]] constexpr friend extent3 operator+(extent3 const& lhs, extent3 const& rhs) noexcept
202 {
203 return extent3{lhs._v + rhs._v};
204 }
205
211 [[nodiscard]] constexpr friend extent3 operator-(extent3 const& lhs, extent3 const& rhs) noexcept
212 {
213 return extent3{lhs._v - rhs._v};
214 }
215
221 [[nodiscard]] constexpr friend extent3 operator*(extent3 const& lhs, float const& rhs) noexcept
222 {
223 return extent3{lhs._v * array_type::broadcast(rhs)};
224 }
225
226 [[nodiscard]] constexpr friend extent3 operator+(extent3 const& lhs, vector2 const& rhs) noexcept
227 {
228 return extent3{static_cast<array_type>(lhs) + static_cast<array_type>(rhs)};
229 }
230
231 [[nodiscard]] constexpr friend extent3 operator+(extent3 const& lhs, vector3 const& rhs) noexcept
232 {
233 return extent3{static_cast<array_type>(lhs) + static_cast<array_type>(rhs)};
234 }
235
236 [[nodiscard]] constexpr friend vector3 operator+(vector3 const& lhs, extent3 const& rhs) noexcept
237 {
238 return vector3{static_cast<array_type>(lhs) + static_cast<array_type>(rhs)};
239 }
240
246 [[nodiscard]] constexpr friend extent3 operator+(extent3 const& lhs, float const& rhs) noexcept
247 {
248 auto r = extent3{};
249 for (std::size_t i = 0; i != 3; ++i) {
250 r._v[i] = lhs._v[i] + rhs;
251 }
252
253 return r;
254 }
255
261 [[nodiscard]] constexpr friend extent3 operator*(float const& lhs, extent3 const& rhs) noexcept
262 {
263 return extent3{array_type::broadcast(lhs) * rhs._v};
264 }
265
271 [[nodiscard]] constexpr friend bool operator==(extent3 const& lhs, extent3 const& rhs) noexcept
272 {
273 return equal(lhs._v, rhs._v);
274 }
275
276 [[nodiscard]] constexpr friend std::partial_ordering operator<=>(extent3 const& lhs, extent3 const& rhs) noexcept
277 {
278 constexpr std::size_t mask = 0b0111;
279
280 auto const equal = (lhs._v == rhs._v).mask() & mask;
281 if (equal == mask) {
282 // Only equivalent if all elements are equal.
283 return std::partial_ordering::equivalent;
284 }
285
286 auto const less = (lhs._v < rhs._v).mask() & mask;
287 if ((less | equal) == mask) {
288 // If one or more elements is less (but none are greater) then the ordering is less.
289 return std::partial_ordering::less;
290 }
291
292 auto const greater = (lhs._v < rhs._v).mask() & mask;
293 if ((greater | equal) == mask) {
294 // If one or more elements is greater (but none are less) then the ordering is greater.
295 return std::partial_ordering::greater;
296 }
297
298 // Some elements are less and others are greater, we don't have an ordering.
299 return std::partial_ordering::unordered;
300 }
301
306 [[nodiscard]] hi_force_inline constexpr friend float squared_hypot(extent3 const& rhs) noexcept
307 {
308 return dot<0b0111>(rhs._v, rhs._v).x();
309 }
310
315 [[nodiscard]] friend float hypot(extent3 const& rhs) noexcept
316 {
317 return hypot<0b0111>(rhs._v).x();
318 }
319
324 [[nodiscard]] constexpr friend float rcp_hypot(extent3 const& rhs) noexcept
325 {
326 return rhypot<0b0111>(rhs._v).x();
327 }
328
333 [[nodiscard]] constexpr friend extent3 normalize(extent3 const& rhs) noexcept
334 {
335 return extent3{normalize<0b0111>(rhs._v)};
336 }
337
338 [[nodiscard]] constexpr friend extent3 ceil(extent3 const& rhs) noexcept
339 {
340 return extent3{ceil(array_type{rhs})};
341 }
342
343 [[nodiscard]] constexpr friend extent3 floor(extent3 const& rhs) noexcept
344 {
345 return extent3{floor(static_cast<array_type>(rhs))};
346 }
347
348 [[nodiscard]] constexpr friend extent3 round(extent3 const& rhs) noexcept
349 {
350 return extent3{round(static_cast<array_type>(rhs))};
351 }
352
353 [[nodiscard]] constexpr friend extent3 min(extent3 const& lhs, extent3 const& rhs) noexcept
354 {
355 return extent3{min(static_cast<array_type>(lhs), static_cast<array_type>(rhs))};
356 }
357
358 [[nodiscard]] constexpr friend extent3 max(extent3 const& lhs, extent3 const& rhs) noexcept
359 {
360 return extent3{max(static_cast<array_type>(lhs), static_cast<array_type>(rhs))};
361 }
362
363 [[nodiscard]] constexpr friend extent3 clamp(extent3 const& value, extent3 const& min, extent3 const& max) noexcept
364 {
365 return extent3{clamp(static_cast<array_type>(value), static_cast<array_type>(min), static_cast<array_type>(max))};
366 }
367
372 [[nodiscard]] constexpr bool holds_invariant() const noexcept
373 {
374 return _v.x() >= 0.0f and _v.y() >= 0.0f and _v.z() >= 0.0f and _v.w() == 0.0f;
375 }
376
377 [[nodiscard]] friend std::string to_string(extent3 const& rhs) noexcept
378 {
379 return std::format("[{}, {}, {}]", rhs._v.x(), rhs._v.y(), rhs._v.z());
380 }
381
382 friend std::ostream& operator<<(std::ostream& lhs, extent3 const& rhs) noexcept
383 {
384 return lhs << to_string(rhs);
385 }
386
387private:
388 array_type _v;
389};
390
391}} // namespace hi::v1
392
393// XXX #617 MSVC bug does not handle partial specialization in modules.
394hi_export template<>
395struct std::formatter<hi::extent3, char> : std::formatter<std::string, char> {
396 auto format(hi::extent3 const& t, auto& fc) const
397 {
398 return std::formatter<std::string, char>::format(std::format("[{}, {}, {}]", t.width(), t.height(), t.depth()), fc);
399 }
400};
Defined the geo::extent, extent2 and extent3 types.
@ other
The gui_event does not have associated data.
The HikoGUI namespace.
Definition array_generic.hpp:20
DOXYGEN BUG.
Definition algorithm_misc.hpp:20
Definition simd_intf.hpp:18
A high-level geometric extent.
Definition extent2.hpp:32
A high-level geometric extent.
Definition extent3.hpp:33
constexpr extent3(extent2 const &other) noexcept
Construct a extent from a lower dimension extent.
Definition extent3.hpp:45
constexpr friend extent3 operator+(extent3 const &lhs, float const &rhs) noexcept
Add a scaler to the extent.
Definition extent3.hpp:246
constexpr float height() const noexcept
Access the y-as-height element from the extent.
Definition extent3.hpp:165
constexpr friend float rcp_hypot(extent3 const &rhs) noexcept
Get the length of the extent.
Definition extent3.hpp:324
constexpr extent3(float width, float height, float depth=0.0f) noexcept
Construct a 3D extent from width, height and depth.
Definition extent3.hpp:88
constexpr friend extent3 normalize(extent3 const &rhs) noexcept
Normalize a extent to a unit extent.
Definition extent3.hpp:333
constexpr friend extent3 operator-(extent3 const &lhs, extent3 const &rhs) noexcept
Subtract two extents from each other.
Definition extent3.hpp:211
constexpr friend extent3 operator*(extent3 const &lhs, float const &rhs) noexcept
Scale the extent by a scaler.
Definition extent3.hpp:221
constexpr float depth() const noexcept
Access the z-as-depth element from the extent.
Definition extent3.hpp:176
constexpr float & height() noexcept
Access the y-as-height element from the extent.
Definition extent3.hpp:132
constexpr float & depth() noexcept
Access the z-as-depth element from the extent.
Definition extent3.hpp:143
constexpr float width() const noexcept
Access the x-as-width element from the extent.
Definition extent3.hpp:154
constexpr friend bool operator==(extent3 const &lhs, extent3 const &rhs) noexcept
Compare if two extents are equal.
Definition extent3.hpp:271
constexpr extent3() noexcept
Construct a empty extent / zero length.
Definition extent3.hpp:81
constexpr bool holds_invariant() const noexcept
Check if the extent is valid.
Definition extent3.hpp:372
constexpr friend extent3 operator*(float const &lhs, extent3 const &rhs) noexcept
Scale the extent by a scaler.
Definition extent3.hpp:261
friend float hypot(extent3 const &rhs) noexcept
Get the length of the extent.
Definition extent3.hpp:315
constexpr float & width() noexcept
Access the x-as-width element from the extent.
Definition extent3.hpp:121
hi_force_inline constexpr friend float squared_hypot(extent3 const &rhs) noexcept
Get the squared length of the extent.
Definition extent3.hpp:306
constexpr friend extent3 operator+(extent3 const &lhs, extent3 const &rhs) noexcept
Add two extents from each other.
Definition extent3.hpp:201
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
T infinity(T... args)
T signaling_NaN(T... args)