Loading...
Searching...
No Matches
BoundingBox-Impl.hpp
Go to the documentation of this file.
1// This code is based on Jet framework.
2// Copyright (c) 2018 Doyub Kim
3// CubbyFlow is voxel-based fluid simulation engine for computer games.
4// Copyright (c) 2020 CubbyFlow Team
5// Core Part: Chris Ohk, Junwoo Hwang, Jihong Sin, Seungwoo Yoo
6// AI Part: Dongheon Cho, Minseo Kim
7// We are making my contributions/submissions to this project solely in our
8// personal capacity and are not conveying any rights to any intellectual
9// property of any third parties.
10
11#ifndef CUBBYFLOW_BOUNDING_BOX_IMPL_HPP
12#define CUBBYFLOW_BOUNDING_BOX_IMPL_HPP
13
14namespace CubbyFlow
15{
16template <typename T, size_t N>
18{
19 Reset();
20}
21
22template <typename T, size_t N>
24 const VectorType& point2)
25{
26 lowerCorner = Min(point1, point2);
27 upperCorner = Max(point1, point2);
28}
29
30template <typename T, size_t N>
32 : lowerCorner(other.lowerCorner), upperCorner(other.upperCorner)
33{
34 // Do nothing
35}
36
37template <typename T, size_t N>
39 : lowerCorner(std::move(other.lowerCorner)),
40 upperCorner(std::move(other.upperCorner))
41{
42 // Do nothing
43}
44
45template <typename T, size_t N>
47{
48 lowerCorner = other.lowerCorner;
49 upperCorner = other.upperCorner;
50
51 return *this;
52}
53
54template <typename T, size_t N>
56{
57 lowerCorner = std::move(other.lowerCorner);
58 upperCorner = std::move(other.upperCorner);
59
60 return *this;
62
63template <typename T, size_t N>
65{
66 return upperCorner[0] - lowerCorner[0];
68
69template <typename T, size_t N>
70template <typename U>
71std::enable_if_t<(N > 1), U> BoundingBox<T, N>::Height() const
72{
73 return upperCorner[1] - lowerCorner[1];
74}
75
76template <typename T, size_t N>
77template <typename U>
78std::enable_if_t<(N > 2), U> BoundingBox<T, N>::Depth() const
80 return upperCorner[2] - lowerCorner[2];
81}
82
83template <typename T, size_t N>
85{
86 return upperCorner[axis] - lowerCorner[axis];
88
89template <typename T, size_t N>
91{
92 for (size_t i = 0; i < N; ++i)
93 {
94 if (upperCorner[i] < other.lowerCorner[i] ||
95 lowerCorner[i] > other.upperCorner[i])
96 {
97 return false;
98 }
99 }
100
101 return true;
102}
103
104template <typename T, size_t N>
106{
107 for (size_t i = 0; i < N; ++i)
108 {
109 if (upperCorner[i] < point[i] || lowerCorner[i] > point[i])
110 {
111 return false;
113 }
114
115 return true;
116}
117
118template <typename T, size_t N>
120{
121 T min = 0;
122 T max = std::numeric_limits<T>::max();
123 const VectorType& rayInvDir = T(1) / ray.direction;
125 for (size_t i = 0; i < N; ++i)
126 {
127 T near = (lowerCorner[i] - ray.origin[i]) * rayInvDir[i];
128 T far = (upperCorner[i] - ray.origin[i]) * rayInvDir[i];
130 if (near > far)
131 {
132 std::swap(near, far);
133 }
134
135 min = near > min ? near : min;
136 max = far < max ? far : max;
137
138 if (min > max)
139 {
140 return false;
141 }
143
144 return true;
145}
146
147template <typename T, size_t N>
149 const RayType& ray) const
150{
152
153 T min = 0;
154 T max = std::numeric_limits<T>::max();
155 const VectorType& rayInvDir = T(1) / ray.direction;
156
157 for (size_t i = 0; i < N; ++i)
158 {
159 T near = (lowerCorner[i] - ray.origin[i]) * rayInvDir[i];
160 T far = (upperCorner[i] - ray.origin[i]) * rayInvDir[i];
161
162 if (near > far)
163 {
164 std::swap(near, far);
165 }
166
167 min = near > min ? near : min;
168 max = far < max ? far : max;
169
170 if (min > max)
171 {
172 intersection.isIntersecting = false;
173 return intersection;
174 }
175 }
176
177 intersection.isIntersecting = true;
178
179 if (Contains(ray.origin))
180 {
181 intersection.near = max;
182 intersection.far = std::numeric_limits<T>::max();
183 }
184 else
185 {
186 intersection.near = min;
187 intersection.far = max;
188 }
189
190 return intersection;
191}
192
193template <typename T, size_t N>
195{
196 return (upperCorner + lowerCorner) / static_cast<T>(2);
197}
198
199template <typename T, size_t N>
201{
202 return VectorType(upperCorner - lowerCorner).Length();
203}
204
205template <typename T, size_t N>
207{
208 return VectorType(upperCorner - lowerCorner).LengthSquared();
209}
210
211template <typename T, size_t N>
213{
214 lowerCorner = VectorType::MakeConstant(std::numeric_limits<T>::max());
215 upperCorner = VectorType::MakeConstant(-std::numeric_limits<T>::max());
216}
217
218template <typename T, size_t N>
220{
221 lowerCorner = Min(lowerCorner, point);
222 upperCorner = Max(upperCorner, point);
223}
224
225template <typename T, size_t N>
227{
228 lowerCorner = Min(lowerCorner, other.lowerCorner);
229 upperCorner = Max(upperCorner, other.upperCorner);
230}
231
232template <typename T, size_t N>
234{
235 lowerCorner -= delta;
236 upperCorner += delta;
237}
238
239template <typename T, size_t N>
241 size_t idx) const
242{
244 for (size_t i = 0; i < N; ++i)
245 {
246 ret[i] = lowerCorner[i] + (((ONE_SIZE << i) & idx) != 0) *
247 (upperCorner[i] - lowerCorner[i]);
248 }
249 return ret;
250}
251
252template <typename T, size_t N>
254 const VectorType& point) const
255{
256 return CubbyFlow::Clamp(point, lowerCorner, upperCorner);
257}
258
259template <typename T, size_t N>
261{
262 for (size_t i = 0; i < N; ++i)
263 {
264 if (lowerCorner[i] >= upperCorner[i])
265 {
266 return true;
267 }
268 }
269
270 return false;
271}
272
273template <typename T, size_t N>
274template <typename U>
276{
277 return BoundingBox<U, N>{ lowerCorner.template CastTo<U>(),
278 upperCorner.template CastTo<U>() };
279}
280} // namespace CubbyFlow
281
282#endif
N-D axis-aligned bounding box class.
Definition BoundingBox.hpp:47
T Width() const
Returns width of the box.
Definition BoundingBox-Impl.hpp:64
bool Contains(const VectorType &point) const
Returns true if the input vector is inside of this box.
Definition BoundingBox-Impl.hpp:105
bool Intersects(const RayType &ray) const
Returns true if the input ray is intersecting with this box.
Definition BoundingBox-Impl.hpp:119
BoundingBoxRayIntersection< T > ClosestIntersection(const RayType &ray) const
Definition BoundingBox-Impl.hpp:148
T Length(size_t axis)
Returns length of the box in given axis.
Definition BoundingBox-Impl.hpp:84
VectorType MidPoint() const
Returns the mid-point of this box.
Definition BoundingBox-Impl.hpp:194
VectorType Corner(size_t idx) const
Returns corner position. Index starts from x-first order.
Definition BoundingBox-Impl.hpp:240
T DiagonalLength() const
Returns diagonal length of this box.
Definition BoundingBox-Impl.hpp:200
void Reset()
Resets this box to initial state (min=infinite, max=-infinite).
Definition BoundingBox-Impl.hpp:212
bool IsEmpty() const
Returns true if the box is empty.
Definition BoundingBox-Impl.hpp:260
void Merge(const VectorType &point)
Merges this and other point.
Definition BoundingBox-Impl.hpp:219
BoundingBox & operator=(const BoundingBox &other)
Copy assignment operator.
Definition BoundingBox-Impl.hpp:46
void Expand(T delta)
Definition BoundingBox-Impl.hpp:233
T DiagonalLengthSquared() const
Returns squared diagonal length of this box.
Definition BoundingBox-Impl.hpp:206
BoundingBox()
Default constructor.
Definition BoundingBox-Impl.hpp:17
bool Overlaps(const BoundingBox &other) const
Returns true of this box and other box overlaps.
Definition BoundingBox-Impl.hpp:90
BoundingBox< U, N > CastTo() const
Returns box with different value type.
Definition BoundingBox-Impl.hpp:275
VectorType Clamp(const VectorType &point) const
Returns the clamped point.
Definition BoundingBox-Impl.hpp:253
ValueType Length() const
Definition MatrixExpression-Impl.hpp:278
ValueType Min() const
Definition MatrixExpression-Impl.hpp:99
ValueType LengthSquared() const
Definition MatrixExpression-Impl.hpp:286
ValueType Max() const
Definition MatrixExpression-Impl.hpp:120
Definition Matrix.hpp:30
Class for N-D ray.
Definition Ray.hpp:26
Definition pybind11Utils.hpp:21
constexpr size_t ONE_SIZE
One size_t.
Definition Constants.hpp:47
std::enable_if_t< std::is_arithmetic< T >::value, T > Clamp(T val, T low, T high)
Returns the clamped value.
Definition MathUtils-Impl.hpp:166
Matrix< T, Rows, 1 > Vector
Definition Matrix.hpp:738