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 default;
48
49template <typename T, size_t N>
51{
52 lowerCorner = std::move(other.lowerCorner);
53 upperCorner = std::move(other.upperCorner);
54
55 return *this;
56}
57
58template <typename T, size_t N>
60{
61 return upperCorner[0] - lowerCorner[0];
62}
63
64template <typename T, size_t N>
65template <typename U>
66std::enable_if_t<(N > 1), U> BoundingBox<T, N>::Height() const
68 return upperCorner[1] - lowerCorner[1];
69}
71template <typename T, size_t N>
72template <typename U>
73std::enable_if_t<(N > 2), U> BoundingBox<T, N>::Depth() const
74{
75 return upperCorner[2] - lowerCorner[2];
77
78template <typename T, size_t N>
80{
81 return upperCorner[axis] - lowerCorner[axis];
82}
84template <typename T, size_t N>
86{
87 for (size_t i = 0; i < N; ++i)
88 {
89 if (upperCorner[i] < other.lowerCorner[i] ||
90 lowerCorner[i] > other.upperCorner[i])
91 {
92 return false;
93 }
94 }
95
96 return true;
97}
98
99template <typename T, size_t N>
101{
102 for (size_t i = 0; i < N; ++i)
103 {
104 if (upperCorner[i] < point[i] || lowerCorner[i] > point[i])
106 return false;
107 }
108 }
110 return true;
111}
113template <typename T, size_t N>
116 T min = 0;
117 T max = std::numeric_limits<T>::max();
118 const VectorType& rayInvDir = T(1) / ray.direction;
119
120 for (size_t i = 0; i < N; ++i)
122 T near = (lowerCorner[i] - ray.origin[i]) * rayInvDir[i];
123 T far = (upperCorner[i] - ray.origin[i]) * rayInvDir[i];
125 if (near > far)
126 {
127 std::swap(near, far);
128 }
130 min = near > min ? near : min;
131 max = far < max ? far : max;
133 if (min > max)
134 {
135 return false;
136 }
137 }
139 return true;
140}
141
142template <typename T, size_t N>
144 const RayType& ray) const
145{
147
148 T min = 0;
149 T max = std::numeric_limits<T>::max();
150 const VectorType& rayInvDir = T(1) / ray.direction;
151
152 for (size_t i = 0; i < N; ++i)
153 {
154 T near = (lowerCorner[i] - ray.origin[i]) * rayInvDir[i];
155 T far = (upperCorner[i] - ray.origin[i]) * rayInvDir[i];
156
157 if (near > far)
158 {
159 std::swap(near, far);
160 }
161
162 min = near > min ? near : min;
163 max = far < max ? far : max;
164
165 if (min > max)
166 {
167 intersection.isIntersecting = false;
168 return intersection;
169 }
170 }
171
172 intersection.isIntersecting = true;
173
174 if (Contains(ray.origin))
175 {
176 intersection.near = max;
177 intersection.far = std::numeric_limits<T>::max();
178 }
179 else
180 {
181 intersection.near = min;
182 intersection.far = max;
183 }
184
185 return intersection;
186}
187
188template <typename T, size_t N>
190{
191 return (upperCorner + lowerCorner) / static_cast<T>(2);
192}
193
194template <typename T, size_t N>
196{
197 return VectorType(upperCorner - lowerCorner).Length();
198}
199
200template <typename T, size_t N>
202{
203 return VectorType(upperCorner - lowerCorner).LengthSquared();
204}
205
206template <typename T, size_t N>
208{
209 lowerCorner = VectorType::MakeConstant(std::numeric_limits<T>::max());
210 upperCorner = VectorType::MakeConstant(-std::numeric_limits<T>::max());
211}
212
213template <typename T, size_t N>
215{
216 lowerCorner = Min(lowerCorner, point);
217 upperCorner = Max(upperCorner, point);
218}
219
220template <typename T, size_t N>
222{
223 lowerCorner = Min(lowerCorner, other.lowerCorner);
224 upperCorner = Max(upperCorner, other.upperCorner);
225}
226
227template <typename T, size_t N>
229{
230 lowerCorner -= delta;
231 upperCorner += delta;
232}
233
234template <typename T, size_t N>
236 size_t idx) const
237{
239 for (size_t i = 0; i < N; ++i)
240 {
241 ret[i] = lowerCorner[i] + (((ONE_SIZE << i) & idx) != 0) *
242 (upperCorner[i] - lowerCorner[i]);
243 }
244 return ret;
245}
246
247template <typename T, size_t N>
249 const VectorType& point) const
250{
251 return CubbyFlow::Clamp(point, lowerCorner, upperCorner);
252}
253
254template <typename T, size_t N>
256{
257 for (size_t i = 0; i < N; ++i)
258 {
259 if (lowerCorner[i] >= upperCorner[i])
260 {
261 return true;
262 }
263 }
264
265 return false;
266}
267
268template <typename T, size_t N>
269template <typename U>
271{
272 return BoundingBox<U, N>{ lowerCorner.template CastTo<U>(),
273 upperCorner.template CastTo<U>() };
274}
275} // namespace CubbyFlow
276
277#endif
N-D axis-aligned bounding box class.
Definition BoundingBox.hpp:47
T Width() const
Returns width of the box.
Definition BoundingBox-Impl.hpp:59
bool Contains(const VectorType &point) const
Returns true if the input vector is inside of this box.
Definition BoundingBox-Impl.hpp:100
bool Intersects(const RayType &ray) const
Returns true if the input ray is intersecting with this box.
Definition BoundingBox-Impl.hpp:114
BoundingBoxRayIntersection< T > ClosestIntersection(const RayType &ray) const
Definition BoundingBox-Impl.hpp:143
T Length(size_t axis)
Returns length of the box in given axis.
Definition BoundingBox-Impl.hpp:79
VectorType MidPoint() const
Returns the mid-point of this box.
Definition BoundingBox-Impl.hpp:189
VectorType Corner(size_t idx) const
Returns corner position. Index starts from x-first order.
Definition BoundingBox-Impl.hpp:235
T DiagonalLength() const
Returns diagonal length of this box.
Definition BoundingBox-Impl.hpp:195
void Reset()
Resets this box to initial state (min=infinite, max=-infinite).
Definition BoundingBox-Impl.hpp:207
bool IsEmpty() const
Returns true if the box is empty.
Definition BoundingBox-Impl.hpp:255
void Merge(const VectorType &point)
Merges this and other point.
Definition BoundingBox-Impl.hpp:214
BoundingBox & operator=(const BoundingBox &other)
Copy assignment operator.
void Expand(T delta)
Definition BoundingBox-Impl.hpp:228
T DiagonalLengthSquared() const
Returns squared diagonal length of this box.
Definition BoundingBox-Impl.hpp:201
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:85
BoundingBox< U, N > CastTo() const
Returns box with different value type.
Definition BoundingBox-Impl.hpp:270
VectorType Clamp(const VectorType &point) const
Returns the clamped point.
Definition BoundingBox-Impl.hpp:248
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:22
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:719