7#include "../rapid/numeric_array.hpp"
9#include "../concepts.hpp"
10#include "../unfair_mutex.hpp"
50 constexpr axis_aligned_rectangle(
float x,
float y,
float width,
float height) noexcept : v{x, y, x + width, y + height}
69 v(
static_cast<f32x4>(p0).xy00() +
static_cast<f32x4>(p3)._00xy())
71 tt_axiom(p0.is_valid());
72 tt_axiom(p3.is_valid());
81 v(
static_cast<f32x4>(p0).xyxy() +
static_cast<f32x4>(extent)._00xy())
89 [[nodiscard]]
constexpr bool is_valid() const noexcept
91 return le(v, v.zwzw()) == 0b1111;
96 [[nodiscard]]
bool empty() const noexcept
98 return eq(v, v.zwxy()) == 0b1111;
103 [[nodiscard]]
operator bool() const noexcept
115 return *
this = *
this | rhs;
125 return *
this = *
this | rhs;
128 [[nodiscard]]
constexpr point2 operator[](
size_t i)
const noexcept
131 case 0:
return point2{v.xy01()};
132 case 1:
return point2{v.zy01()};
133 case 2:
return point2{v.xw01()};
134 case 3:
return point2{v.zw01()};
135 default: tt_no_default();
140 [[nodiscard]]
constexpr friend point2 get(axis_aligned_rectangle
const &rhs)
noexcept
142 if constexpr (I == 0) {
143 return point2{rhs.v.xy01()};
144 }
else if constexpr (I == 1) {
145 return point2{rhs.v.zy01()};
146 }
else if constexpr (I == 2) {
147 return point2{rhs.v.xw01()};
148 }
else if constexpr (I == 3) {
149 return point2{rhs.v.zw01()};
151 tt_static_no_default();
164 [[nodiscard]]
float width() const noexcept
166 return (v.zwzw() - v).x();
169 [[nodiscard]]
float height() const noexcept
171 return (v.zwzw() - v).y();
174 [[nodiscard]]
float bottom() const noexcept
179 [[nodiscard]]
float top() const noexcept
184 [[nodiscard]]
float left() const noexcept
189 [[nodiscard]]
float right() const noexcept
196 [[nodiscard]]
float middle() const noexcept
198 return (bottom() + top()) * 0.5f;
203 [[nodiscard]]
float center() const noexcept
205 return (left() + right()) * 0.5f;
210 v = v.xyxw() +
f32x4{0.0f, 0.0f, newWidth, 0.0f};
214 axis_aligned_rectangle &set_height(
float newHeight)
noexcept
216 v = v.xyzy() + f32x4{0.0f, 0.0f, 0.0f, newHeight};
227 return ge(
static_cast<f32x4>(rhs).xyxy(), v) == 0b0011;
240 if (
alignment == horizontal_alignment::left) {
243 }
else if (
alignment == horizontal_alignment::right) {
244 x = haystack.right() - needle.width();
246 }
else if (
alignment == horizontal_alignment::center) {
247 x = haystack.center() - needle.width() * 0.5f;
254 if (
alignment == vertical_alignment::bottom) {
255 y = haystack.bottom();
257 }
else if (
alignment == vertical_alignment::top) {
258 y = haystack.top() - needle.height();
260 }
else if (
alignment == vertical_alignment::middle) {
261 y = haystack.middle() - needle.height() * 0.5f;
267 return {
point2{x, y}, needle};
292 return lhs.v == rhs.v;
295 [[nodiscard]]
friend bool operator!=(axis_aligned_rectangle
const &lhs, axis_aligned_rectangle
const &rhs)
noexcept
297 return !(lhs == rhs);
300 [[nodiscard]]
friend bool overlaps(axis_aligned_rectangle
const &lhs, axis_aligned_rectangle
const &rhs)
noexcept
302 if (lhs.empty() || rhs.
empty()) {
306 ttlet rhs_swap = rhs.v.zwxy();
309 if ((gt(lhs.v, rhs_swap) & 0b0011) != 0) {
314 if ((lt(lhs.v, rhs_swap) & 0b1100) != 0) {
321 [[nodiscard]]
friend axis_aligned_rectangle
322 operator|(axis_aligned_rectangle
const &lhs, axis_aligned_rectangle
const &rhs)
noexcept
329 return axis_aligned_rectangle{
min(get<0>(lhs), get<0>(rhs)),
max(get<3>(lhs), get<3>(rhs))};
333 [[nodiscard]]
friend axis_aligned_rectangle operator|(axis_aligned_rectangle
const &lhs, point2
const &rhs)
noexcept
336 return axis_aligned_rectangle{rhs, rhs};
338 return axis_aligned_rectangle{
min(get<0>(lhs), rhs),
max(get<3>(lhs), rhs)};
346 return get<0>(rhs) + (get<3>(rhs) - get<0>(rhs)) * 0.5f;
356 ttlet new_extent = lhs.size() * rhs;
358 ttlet offset = diff * 0.5f;
360 ttlet p0 = get<0>(lhs) - offset;
361 ttlet p3 = max(get<3>(lhs) + offset, p0);
389 auto p0 = round(get<0>(rhs));
390 auto p3 = round(get<3>(rhs));
398 auto p0 =
floor(get<0>(rhs));
399 auto p3 =
ceil(get<3>(rhs));
407 auto p0 =
ceil(get<0>(rhs));
408 auto p3 =
floor(get<3>(rhs));
418 ttlet p0 = max(get<0>(lhs), get<0>(rhs));
419 ttlet p3 = min(get<3>(lhs), get<3>(rhs));
420 if (p0.x() < p3.x() && p0.y() < p3.y()) {
445class atomic<tt::axis_aligned_rectangle> {
447 static constexpr bool is_always_lock_free =
false;
449 constexpr atomic() noexcept : _value() {}
469 return is_always_lock_free;
474 ttlet
lock = std::scoped_lock(_mutex);
480 ttlet
lock = std::scoped_lock(_mutex);
487 ttlet
lock = std::scoped_lock(_mutex);
488 return std::exchange(_value, desired);
495 std::memory_order)
noexcept
497 ttlet
lock = std::scoped_lock(_mutex);
498 if (_value == expected) {
510 std::memory_order success,
511 std::memory_order failure)
noexcept
519 std::memory_order order = std::memory_order_seq_cst)
noexcept
527 std::memory_order order = std::memory_order_seq_cst)
noexcept
535 ttlet
lock = std::scoped_lock(_mutex);
543 ttlet
lock = std::scoped_lock(_mutex);
544 return _value |= arg;
alignment
Vertical and horizontal alignment.
Definition alignment.hpp:47
Class which represents an axis-aligned rectangle.
Definition axis_aligned_rectangle.hpp:20
friend axis_aligned_rectangle shrink(axis_aligned_rectangle const &lhs, float rhs) noexcept
Shrink the rectangle for the same amount in all directions.
Definition axis_aligned_rectangle.hpp:382
axis_aligned_rectangle & operator|=(axis_aligned_rectangle const &rhs) noexcept
Expand the current rectangle to include the new rectangle.
Definition axis_aligned_rectangle.hpp:113
bool contains(point2 const &rhs) const noexcept
Check if a 2D coordinate is inside the rectangle.
Definition axis_aligned_rectangle.hpp:224
static axis_aligned_rectangle _align(axis_aligned_rectangle outside, axis_aligned_rectangle inside, alignment alignment) noexcept
Need to call the hidden friend function from within another class.
Definition axis_aligned_rectangle.hpp:285
friend axis_aligned_rectangle ceil(axis_aligned_rectangle const &rhs) noexcept
Round rectangle by expanding to pixel edge.
Definition axis_aligned_rectangle.hpp:396
friend point2 center(axis_aligned_rectangle const &rhs) noexcept
Get the center of the rectangle.
Definition axis_aligned_rectangle.hpp:344
float middle() const noexcept
The middle on the y-axis between bottom and top.
Definition axis_aligned_rectangle.hpp:196
constexpr bool is_valid() const noexcept
Make sure p0 is left/bottom from p3.
Definition axis_aligned_rectangle.hpp:89
friend axis_aligned_rectangle fit(axis_aligned_rectangle const &bounds, axis_aligned_rectangle const &rectangle) noexcept
Make a rectangle fit inside bounds.
friend axis_aligned_rectangle scale(axis_aligned_rectangle const &lhs, float rhs) noexcept
Expand the rectangle for the same amount in all directions.
Definition axis_aligned_rectangle.hpp:354
friend axis_aligned_rectangle floor(axis_aligned_rectangle const &rhs) noexcept
Round rectangle by shrinking to pixel edge.
Definition axis_aligned_rectangle.hpp:405
constexpr axis_aligned_rectangle(point2 const &p0, extent2 const &extent) noexcept
Create a rectangle from the size.
Definition axis_aligned_rectangle.hpp:80
constexpr axis_aligned_rectangle(point2 const &p0, point2 const &p3) noexcept
Create a rectangle from the left-bottom and right-top points.
Definition axis_aligned_rectangle.hpp:68
friend axis_aligned_rectangle align(axis_aligned_rectangle haystack, axis_aligned_rectangle needle, alignment alignment) noexcept
Align a rectangle within another rectangle.
Definition axis_aligned_rectangle.hpp:277
friend axis_aligned_rectangle expand(axis_aligned_rectangle const &lhs, float rhs) noexcept
Expand the rectangle for the same amount in all directions.
Definition axis_aligned_rectangle.hpp:371
axis_aligned_rectangle & operator|=(point2 const &rhs) noexcept
Expand the current rectangle to include the new rectangle.
Definition axis_aligned_rectangle.hpp:123
extent2 size() const noexcept
Get size of the rectangle.
Definition axis_aligned_rectangle.hpp:159
constexpr axis_aligned_rectangle(float x, float y, float width, float height) noexcept
Create a box from the position and size.
Definition axis_aligned_rectangle.hpp:50
bool empty() const noexcept
Check if the rectangle has no area.
Definition axis_aligned_rectangle.hpp:96
friend axis_aligned_rectangle intersect(axis_aligned_rectangle const &lhs, axis_aligned_rectangle const &rhs) noexcept
Return the overlapping part of two rectangles.
Definition axis_aligned_rectangle.hpp:416
constexpr axis_aligned_rectangle(extent2 const &extent) noexcept
Create a rectangle from the size.
Definition axis_aligned_rectangle.hpp:59
friend axis_aligned_rectangle align(axis_aligned_rectangle haystack, extent2 needle, alignment alignment) noexcept
Align a rectangle within another rectangle.
Definition axis_aligned_rectangle.hpp:237
float center() const noexcept
The center on the x-axis between left and right.
Definition axis_aligned_rectangle.hpp:203
Class which represents an rectangle.
Definition rectangle.hpp:16
Definition sfloat_rgba32.hpp:15
T compare_exchange_weak(T... args)
T is_lock_free(T... args)