Shamrock 2025.10.0
Astrophysical Code
Loading...
Searching...
No Matches
AABB.hpp
Go to the documentation of this file.
1// -------------------------------------------------------//
2//
3// SHAMROCK code for hydrodynamics
4// Copyright (c) 2021-2026 Timothée David--Cléris <tim.shamrock@proton.me>
5// SPDX-License-Identifier: CeCILL Free Software License Agreement v2.1
6// Shamrock is licensed under the CeCILL 2.1 License, see LICENSE for more information
7//
8// -------------------------------------------------------//
9
10#pragma once
11
21#include "shambase/assert.hpp"
22#include "shambackends/math.hpp"
23#include "shambackends/vec.hpp"
24#include <limits>
25
26namespace shammath {
27
33 template<class T>
34 struct Ray {
36 using Tscal = typename T_prop::component_type;
37
38 T origin;
39 T direction;
40 T inv_direction;
41
48 inline Ray(T origin, T direction)
49 : origin(origin), direction(direction), inv_direction(Tscal{1.} / direction) {
50
51 Tscal f = sycl::length(direction);
52 SHAM_ASSERT(f > 0);
53
54 this->direction /= f;
55 this->inv_direction *= f;
56 }
57 };
58
66 template<class T>
67 struct RingRay {
69 using Tscal = typename T_prop::component_type;
70
71 T center;
72 Tscal radius;
73 T e_x;
74 T e_y;
75
76 T get_ez() { return sycl::cross(e_x, e_y); }
84 inline RingRay(T center, Tscal radius, T e_x, T e_y)
85 : center(center), radius(radius), e_x(e_x), e_y(e_y) {}
86 };
87
98 template<class T>
99 struct AABB {
100
102 using Tscal = typename T_prop::component_type;
103
106
107 inline AABB() = default;
108
118 inline AABB(T lower, T upper)
119 : lower(lower), upper(upper) {
120
121 };
122
131 inline AABB(std::tuple<T, T> range)
132 : lower(std::get<0>(range)), upper(std::get<1>(range)) {}
133
142 inline AABB(std::pair<T, T> range) : lower(std::get<0>(range)), upper(std::get<1>(range)) {}
143
152 inline T delt() const { return upper - lower; }
153
154 inline Tscal get_radius() const { return sycl::length(delt()) / 2; }
155
164 inline Tscal get_volume() { return sham::product_accumulate(upper - lower); }
165
174 inline T get_center() const noexcept { return (lower + upper) / 2; }
175
184 inline T sum_bounds() const noexcept { return lower + upper; }
185
197 inline AABB expand_all(Tscal value) { return AABB{lower - value, upper + value}; }
198
212 template<class Tb>
213 inline AABB<Tb> convert() {
214 using Tb_prop = shambase::VectorProperties<Tb>;
215 static_assert(
216 Tb_prop::dim == T_prop::dim, "you cannot change the dimension in convert");
217
218 return {
219 lower.template convert<Tb_prop::component_type>(),
220 upper.template convert<Tb_prop::component_type>()};
221 }
222
234 inline AABB get_intersect(AABB other) const noexcept {
235 return {sham::max(lower, other.lower), sham::min(upper, other.upper)};
236 }
237
244 inline bool contains(AABB other) const noexcept {
245 // return lower <= other.lower && upper >= other.upper;
246 return sham::vec_compare_leq(lower, other.lower)
247 && sham::vec_compare_geq(upper, other.upper);
248 }
249
256 inline bool contains_asymmetric(T point) const noexcept {
257 return sham::vec_compare_leq(lower, point) && sham::vec_compare_g(upper, point);
258 }
259
268 [[nodiscard]] inline bool is_not_empty() const noexcept {
269 return sham::vec_compare_geq(upper, lower);
270 }
271
280 [[nodiscard]] inline bool is_volume_not_null() const noexcept {
281 return sham::vec_compare_g(upper, lower);
282 }
283
293 [[nodiscard]] inline bool is_surface() const noexcept {
294 return sham::component_have_only_one_zero(delt()) && (is_not_empty());
295 }
296
307 [[nodiscard]] inline bool is_surface_or_volume() const noexcept {
308 return sham::component_have_at_most_one_zero(delt()) && (is_not_empty());
309 }
310
320 [[nodiscard]] inline T clamp_coord(T coord) const noexcept {
321 return sycl::clamp(coord, lower, upper);
322 }
323
333 [[nodiscard]] inline bool intersect_ray(Ray<T> ray) const noexcept;
334
344 [[nodiscard]] inline bool intersect_ring_ray_approx(RingRay<T> ring_ray) const noexcept;
345
347 inline bool operator==(const AABB<T> &other) const noexcept {
348 return sham::equals(lower, other.lower) && sham::equals(upper, other.upper);
349 }
350
352 inline bool operator!=(const AABB<T> &other) const noexcept { return !(*this == other); }
353 };
354
355 template<class T>
356 [[nodiscard]] inline bool AABB<T>::intersect_ray(Ray<T> ray) const noexcept {
358
359 Tscal tx1 = (lower.x() - ray.origin.x()) * ray.inv_direction.x();
360 Tscal tx2 = (upper.x() - ray.origin.x()) * ray.inv_direction.x();
361
362 tmin = sycl::max(tmin, sycl::min(tx1, tx2));
363 tmax = sycl::min(tmax, sycl::max(tx1, tx2));
364
365 Tscal ty1 = (lower.y() - ray.origin.y()) * ray.inv_direction.y();
366 Tscal ty2 = (upper.y() - ray.origin.y()) * ray.inv_direction.y();
367
368 tmin = sycl::max(tmin, sycl::min(ty1, ty2));
369 tmax = sycl::min(tmax, sycl::max(ty1, ty2));
370
371 Tscal tz1 = (lower.z() - ray.origin.z()) * ray.inv_direction.z();
372 Tscal tz2 = (upper.z() - ray.origin.z()) * ray.inv_direction.z();
373
374 tmin = sycl::max(tmin, sycl::min(tz1, tz2));
375 tmax = sycl::min(tmax, sycl::max(tz1, tz2));
376
377 return tmax >= tmin;
378 }
379
380 template<class T>
381 [[nodiscard]] inline bool AABB<T>::intersect_ring_ray_approx(
382 RingRay<T> ring_ray) const noexcept {
383 T aabb_center = get_center();
384 Tscal aabb_radius = get_radius();
385
386 T r_center = ring_ray.center - aabb_center;
387
388 Tscal x_val = sycl::dot(r_center, ring_ray.e_x);
389 Tscal y_val = sycl::dot(r_center, ring_ray.e_y);
390 Tscal z_val = sycl::dot(r_center, ring_ray.get_ez());
391
392 Tscal r_val = sycl::sqrt(x_val * x_val + y_val * y_val);
393 Tscal delta_r = r_val - ring_ray.radius;
394 Tscal rab2_ring = z_val * z_val + delta_r * delta_r;
395
396 return rab2_ring <= aabb_radius * aabb_radius;
397 }
398
399} // namespace shammath
Source location utility.
Shamrock assertion utility.
#define SHAM_ASSERT(x)
Shorthand for SHAM_ASSERT_NAMED without a message.
Definition assert.hpp:67
void throw_with_loc(std::string message, SourceLocation loc=SourceLocation{})
Throw an exception and append the source location to it.
namespace for math utility
Definition AABB.hpp:26
STL namespace.
Axis-Aligned bounding box.
Definition AABB.hpp:99
typename T_prop::component_type Tscal
Scalar type of the coordinates.
Definition AABB.hpp:102
T delt() const
Returns the delta of the AABB.
Definition AABB.hpp:152
T get_center() const noexcept
Returns the center of the AABB.
Definition AABB.hpp:174
bool is_surface() const noexcept
Checks if the AABB is a surface.
Definition AABB.hpp:293
T clamp_coord(T coord) const noexcept
Clamp a coordinate to the box.
Definition AABB.hpp:320
bool is_surface_or_volume() const noexcept
Checks if the AABB is a surface or a volume.
Definition AABB.hpp:307
bool contains(AABB other) const noexcept
Check if AABB fully contains another AABB.
Definition AABB.hpp:244
bool intersect_ray(Ray< T > ray) const noexcept
Check if the ray intersect the AABB.
Definition AABB.hpp:356
bool is_volume_not_null() const noexcept
Checks if the AABB has a non-zero volume.
Definition AABB.hpp:280
AABB(std::pair< T, T > range)
Construct an AABB from a pair of lower and upper bounds.
Definition AABB.hpp:142
bool operator!=(const AABB< T > &other) const noexcept
not equal operator
Definition AABB.hpp:352
AABB(T lower, T upper)
Construct an AABB from lower and upper bounds.
Definition AABB.hpp:118
AABB< Tb > convert()
Converts the AABB to a different type.
Definition AABB.hpp:213
T lower
Lower bound of the AABB.
Definition AABB.hpp:104
AABB expand_all(Tscal value)
Expand the AABB by a given value on all dimensions.
Definition AABB.hpp:197
bool intersect_ring_ray_approx(RingRay< T > ring_ray) const noexcept
Check if the ring ray intersect the AABB.
Definition AABB.hpp:381
bool contains_asymmetric(T point) const noexcept
Check if point is in AABB using half-open interval [lower, upper)
Definition AABB.hpp:256
bool is_not_empty() const noexcept
Checks if the AABB is non-empty.
Definition AABB.hpp:268
Tscal get_volume()
Returns the volume of the AABB.
Definition AABB.hpp:164
bool operator==(const AABB< T > &other) const noexcept
equal operator
Definition AABB.hpp:347
AABB(std::tuple< T, T > range)
Construct an AABB from a tuple of lower and upper bounds.
Definition AABB.hpp:131
T upper
Upper bound of the AABB.
Definition AABB.hpp:105
AABB get_intersect(AABB other) const noexcept
Compute the intersection of two AABB.
Definition AABB.hpp:234
T sum_bounds() const noexcept
Returns the sum of the lower and upper bounds of the AABB.
Definition AABB.hpp:184
Ray representation for intersection testing.
Definition AABB.hpp:34
Ray(T origin, T direction)
Construct a normalized ray from origin and direction.
Definition AABB.hpp:48
Ring ray representation for intersection testing.
Definition AABB.hpp:67
RingRay(T center, Tscal radius, T e_x, T e_y)
Construct a ring ray from center, e_x, and e_y.
Definition AABB.hpp:84