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 
14 namespace CubbyFlow
15 {
16 template <typename T, size_t N>
18 {
19  Reset();
20 }
21 
22 template <typename T, size_t N>
24  const VectorType& point2)
25 {
26  lowerCorner = Min(point1, point2);
27  upperCorner = Max(point1, point2);
28 }
29 
30 template <typename T, size_t N>
32  : lowerCorner(other.lowerCorner), upperCorner(other.upperCorner)
33 {
34  // Do nothing
35 }
36 
37 template <typename T, size_t N>
39  : lowerCorner(std::move(other.lowerCorner)),
40  upperCorner(std::move(other.upperCorner))
41 {
42  // Do nothing
43 }
44 
45 template <typename T, size_t N>
47 {
48  lowerCorner = other.lowerCorner;
49  upperCorner = other.upperCorner;
50 
51  return *this;
52 }
53 
54 template <typename T, size_t N>
56 {
57  lowerCorner = std::move(other.lowerCorner);
58  upperCorner = std::move(other.upperCorner);
59 
60  return *this;
61 }
62 
63 template <typename T, size_t N>
65 {
66  return upperCorner[0] - lowerCorner[0];
67 }
68 
69 template <typename T, size_t N>
70 template <typename U>
71 std::enable_if_t<(N > 1), U> BoundingBox<T, N>::Height() const
72 {
73  return upperCorner[1] - lowerCorner[1];
74 }
75 
76 template <typename T, size_t N>
77 template <typename U>
78 std::enable_if_t<(N > 2), U> BoundingBox<T, N>::Depth() const
79 {
80  return upperCorner[2] - lowerCorner[2];
81 }
82 
83 template <typename T, size_t N>
85 {
86  return upperCorner[axis] - lowerCorner[axis];
87 }
88 
89 template <typename T, size_t N>
90 bool BoundingBox<T, N>::Overlaps(const BoundingBox& other) const
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 
104 template <typename T, size_t N>
105 bool BoundingBox<T, N>::Contains(const VectorType& point) const
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;
112  }
113  }
114 
115  return true;
116 }
117 
118 template <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;
124 
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];
129 
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  }
142  }
143 
144  return true;
145 }
146 
147 template <typename T, size_t N>
149  const RayType& ray) const
150 {
151  BoundingBoxRayIntersection<T> intersection;
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 
193 template <typename T, size_t N>
195 {
196  return (upperCorner + lowerCorner) / static_cast<T>(2);
197 }
198 
199 template <typename T, size_t N>
201 {
202  return VectorType(upperCorner - lowerCorner).Length();
203 }
204 
205 template <typename T, size_t N>
207 {
208  return VectorType(upperCorner - lowerCorner).LengthSquared();
209 }
210 
211 template <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 
218 template <typename T, size_t N>
220 {
221  lowerCorner = Min(lowerCorner, point);
222  upperCorner = Max(upperCorner, point);
223 }
224 
225 template <typename T, size_t N>
227 {
228  lowerCorner = Min(lowerCorner, other.lowerCorner);
229  upperCorner = Max(upperCorner, other.upperCorner);
230 }
231 
232 template <typename T, size_t N>
234 {
235  lowerCorner -= delta;
236  upperCorner += delta;
237 }
238 
239 template <typename T, size_t N>
241  size_t idx) const
242 {
243  VectorType ret;
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 
252 template <typename T, size_t N>
254  const VectorType& point) const
255 {
256  return CubbyFlow::Clamp(point, lowerCorner, upperCorner);
257 }
258 
259 template <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 
273 template <typename T, size_t N>
274 template <typename U>
276 {
277  return BoundingBox<U, N>{ lowerCorner.template CastTo<U>(),
278  upperCorner.template CastTo<U>() };
279 }
280 } // namespace CubbyFlow
281 
282 #endif
ValueType LengthSquared() const
Definition: MatrixExpression-Impl.hpp:286
VectorType upperCorner
Upper corner of the bounding box.
Definition: BoundingBox.hpp:148
VectorType origin
The origin of the ray.
Definition: Ray.hpp:35
Class for N-D ray.
Definition: Ray.hpp:25
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
BoundingBox()
Default constructor.
Definition: BoundingBox-Impl.hpp:17
T near
Distance to the first intersection point.
Definition: BoundingBox.hpp:33
N-D axis-aligned bounding box class.
Definition: BoundingBox.hpp:46
ValueType Length() const
Definition: MatrixExpression-Impl.hpp:278
constexpr size_t ONE_SIZE
One size_t.
Definition: Constants.hpp:47
constexpr auto Max(const MatrixExpression< T, Rows, Cols, M1 > &a, const MatrixExpression< T, Rows, Cols, M2 > &b)
Definition: MatrixExpression-Impl.hpp:1112
bool isIntersecting
True if the box and ray intersects.
Definition: BoundingBox.hpp:30
Definition: Matrix.hpp:27
Definition: pybind11Utils.hpp:20
void Merge(RandomIterator a, size_t size, RandomIterator2 temp, CompareFunction compareFunction)
Definition: Parallel-Impl.hpp:107
T far
Distance to the second (and the last) intersection point.
Definition: BoundingBox.hpp:36
VectorType lowerCorner
Lower corner of the bounding box.
Definition: BoundingBox.hpp:145
constexpr auto Min(const MatrixExpression< T, Rows, Cols, M1 > &a, const MatrixExpression< T, Rows, Cols, M2 > &b)
Definition: MatrixExpression-Impl.hpp:1103
VectorType direction
The direction of the ray.
Definition: Ray.hpp:38
Box-ray intersection result.
Definition: BoundingBox.hpp:27