sandbox
Loading...
Searching...
No Matches
volume.hpp
1// SPDX-License-Identifier: MIT
2#ifndef LIBSBX_MATH_VOLUME_HPP_
3#define LIBSBX_MATH_VOLUME_HPP_
4
5#include <ranges>
6
8#include <libsbx/math/vector3.hpp>
9#include <libsbx/math/matrix4x4.hpp>
10
11namespace sbx::math {
12
13template<scalar Type>
15
16public:
17
18 using value_type = Type;
20
21 basic_volume() noexcept = default;
22
23 basic_volume(const vector_type& min, const vector_type& max) noexcept
24 : _min{min},
25 _max{max} { }
26
27 static auto transformed(const basic_volume& volume, const math::matrix4x4& matrix) -> basic_volume {
28 auto min = math::vector3{std::numeric_limits<std::float_t>::max()};
29 auto max = math::vector3{std::numeric_limits<std::float_t>::lowest()};
30
31 for (const auto& corner : volume.corners()) {
32 const auto transformed = math::vector3{matrix * math::vector4{corner, 1.0f}};
33 min = math::vector3::min(min, transformed);
34 max = math::vector3::max(max, transformed);
35 }
36
37 return basic_volume{min, max};
38 }
39
40 auto min() const noexcept -> const vector_type& {
41 return _min;
42 }
43
44 auto max() const noexcept -> const vector_type& {
45 return _max;
46 }
47
48 auto center() const noexcept -> vector_type {
49 return (_min + _max) / 2.0f;
50 }
51
52 auto corners() const noexcept -> std::array<math::vector3, 8u> {
53 return std::array<math::vector3, 8u>{
54 math::vector3{_min.x(), _min.y(), _min.z()},
55 math::vector3{_min.x(), _min.y(), _max.z()},
56 math::vector3{_min.x(), _max.y(), _min.z()},
57 math::vector3{_min.x(), _max.y(), _max.z()},
58 math::vector3{_max.x(), _min.y(), _min.z()},
59 math::vector3{_max.x(), _min.y(), _max.z()},
60 math::vector3{_max.x(), _max.y(), _min.z()},
61 math::vector3{_max.x(), _max.y(), _max.z()}
62 };
63 }
64
65 auto contains(const vector_type& point) const noexcept -> bool {
66 return point.x() >= _min.x() && point.x() <= _max.x() && point.y() >= _min.y() && point.y() <= _max.y() && point.z() >= _min.z() && point.z() <= _max.z();
67 }
68
69 auto contains(const basic_volume& other) const noexcept -> bool {
70 return _min.x() <= other.min().x() && _min.y() <= other.min().y() && _min.z() <= other.min().z() && _max.x() >= other.max().x() && _max.y() >= other.max().y() && _max.z() >= other.max().z();
71 }
72
73 auto intersects(const basic_volume& other) const noexcept -> bool {
74 return _min.x() <= other.max().x() && _max.x() >= other.min().x() && _min.y() <= other.max().y() && _max.y() >= other.min().y() && _min.z() <= other.max().z() && _max.z() >= other.min().z();
75 }
76
77 auto extend() const noexcept -> math::vector3 {
78 return _max - _min;
79 }
80
81 auto diagonal_length() const noexcept -> value_type {
82 return extend().length();
83 }
84
85 auto is_empty() const noexcept -> bool {
86 return _min.x() >= _max.x() || _min.y() >= _max.y() || _min.z() >= _max.z();
87 }
88
89 auto include(const basic_volume& other) noexcept -> void {
90 _min = vector_type::min(_min, other.min());
91 _max = vector_type::max(_max, other.max());
92 }
93
94 static auto merge(const basic_volume& a, const basic_volume& b) -> basic_volume {
95 return basic_volume{
96 vector_type::min(a.min(), b.min()),
97 vector_type::max(a.max(), b.max())
98 };
99 }
100
101 static auto are_overlapping(const basic_volume& a, const basic_volume& b) -> bool {
102 return (a.min().x() <= b.max().x() && a.max().x() >= b.min().x()) && (a.min().y() <= b.max().y() && a.max().y() >= b.min().y()) && (a.min().z() <= b.max().z() && a.max().z() >= b.min().z());
103 }
104
105 template<std::ranges::input_range Range, typename Projection = std::identity>
106 requires (std::convertible_to<std::invoke_result_t<Projection, std::ranges::range_reference_t<Range>>, vector_type>)
107 static auto construct(Range&& range, Projection projection = {}) -> basic_volume {
108 auto iterator = std::ranges::begin(range);
109 const auto end = std::ranges::end(range);
110
111 if (iterator == end) {
112 return basic_volume{};
113 }
114
115 auto first_point = std::invoke(projection, *iterator);
116
117 auto min = first_point;
118 auto max = first_point;
119
120 ++iterator;
121
122 for (; iterator != end; ++iterator) {
123 const auto point = std::invoke(projection, *iterator);
124
125 min = vector_type::min(min, point);
126 max = vector_type::max(max, point);
127 }
128
129 return basic_volume{min, max};
130 }
131
132private:
133
134 vector_type _min;
135 vector_type _max;
136
137}; // class basic_volume
138
140
141using volume = volumef;
142
143} // namespace sbx::math
144
145#endif // LIBSBX_MATH_VOLUME_HPP_
Definition: matrix4x4.hpp:26
Definition: vector4.hpp:24
static constexpr auto min(const basic_vector &vector) noexcept -> value_type
Returns the minimum component of a vector.
Definition: vector.ipp:20
static constexpr auto max(const basic_vector &vector) noexcept -> value_type
Returns the maximum component of a vector.
Definition: vector.ipp:45
Definition: volume.hpp:14
Core numeric concepts and type traits.