34#include <glm/geometric.hpp>
35#include <glm/vec3.hpp>
37#include <utility/math/vector.hpp>
39namespace utility::math
52 template<CanBeVectorComponent T>
56 std::is_floating_point_v<T>,
57 "Aabb requires a floating-point component type (float or double)");
67 : _min(std::numeric_limits<T>::max())
68 , _max(std::numeric_limits<T>::lowest())
93 template<std::input_iterator Iterator,
94 std::sentinel_for<Iterator> Sentinel>
98 for (; first != last; ++first) {
116 return fromPoints(points.begin(), points.end());
125 for (std::size_t i = 0; i < 3; ++i) {
126 _min[i] = std::min(_min[i], point[i]);
127 _max[i] = std::max(_max[i], point[i]);
139 if (other.isEmpty()) {
155 return _min * T { 0.5 } + _max * T { 0.5 };
182 [[nodiscard]] T
radius(
void)
const noexcept
184 return static_cast<T
>(glm::length(
185 static_cast<const glm::vec<3, T> &
>(
halfSize())));
201 for (std::size_t i = 0; i < 3; ++i) {
202 result[i] = (normal[i] >= T { 0 }) ? _max[i] : _min[i];
219 for (std::size_t i = 0; i < 3; ++i) {
220 if (point[i] < _min[i] || point[i] > _max[i]) {
235 if (
isEmpty() || other.isEmpty()) {
238 for (std::size_t i = 0; i < 3; ++i) {
239 if (_min[i] > other._max[i] || other._min[i] > _max[i]) {
250 [[nodiscard]]
bool isEmpty(
void)
const noexcept
252 for (std::size_t i = 0; i < 3; ++i) {
253 if (_min[i] > _max[i]) {
286 using AabbF = Aabb<float>;
291 using AabbD = Aabb<double>;
299 std::ostream &operator<<(std::ostream &stream,
const AabbF &box);
307 std::ostream &operator<<(std::ostream &stream,
const AabbD &box);
Axis-aligned bounding box (AABB) in 3D space.
void include(const Aabb &other) noexcept
Grow the box to contain another box (union).
bool isEmpty(void) const noexcept
Test whether the box is empty (inverted).
T radius(void) const noexcept
Get the radius of the bounding sphere around the box.
Vector< T, 3 > positiveVertex(const Vector< T, 3 > &normal) const noexcept
Get the corner farthest along a direction (the "p-vertex").
Vector< T, 3 > getMax(void) const noexcept
Get the maximum corner.
static Aabb fromPoints(Iterator first, Sentinel last)
Build the tightest box containing a range of 3D points.
void include(const Vector< T, 3 > &point) noexcept
Grow the box to contain a point.
Vector< T, 3 > halfSize(void) const noexcept
Get half the size of the box along each axis.
Aabb(const Vector< T, 3 > &min, const Vector< T, 3 > &max)
Construct from explicit minimum and maximum corners.
Vector< T, 3 > center(void) const noexcept
Get the center of the box.
Vector< T, 3 > extents(void) const noexcept
Get the full size of the box along each axis.
Aabb(void)
Default constructor creating an empty (inverted) box.
bool contains(const Vector< T, 3 > &point) const noexcept
Test whether a point lies inside the box (boundaries included).
bool intersects(const Aabb &other) const noexcept
Test whether two boxes overlap (touching counts).
static Aabb fromPoints(std::span< const Vector< T, 3 > > points)
Build the tightest box containing a contiguous range of points.
Vector< T, 3 > getMin(void) const noexcept
Get the minimum corner.
3D vector class inheriting from glm::vec3.