Ocean
BoundingSphere.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) Meta Platforms, Inc. and affiliates.
3  *
4  * This source code is licensed under the MIT license found in the
5  * LICENSE file in the root directory of this source tree.
6  */
7 
8 #ifndef META_OCEAN_MATH_BOUNDING_SPHERE_H
9 #define META_OCEAN_MATH_BOUNDING_SPHERE_H
10 
11 #include "ocean/math/Math.h"
12 #include "ocean/math/BoundingBox.h"
13 #include "ocean/math/Sphere3.h"
14 
15 namespace Ocean
16 {
17 
18 /**
19  * This class implements a bounding sphere.
20  * @ingroup math
21  */
22 class OCEAN_MATH_EXPORT BoundingSphere : public SphereT3<Scalar>
23 {
24  public:
25 
26  /**
27  * Creates an invalid bounding sphere.
28  */
29  inline BoundingSphere();
30 
31  /**
32  * Creates a new bounding sphere by a center point and a radius.
33  * @param center Center of the bounding sphere
34  * @param radius Radius of the bounding sphere
35  */
36  inline BoundingSphere(const Vector3& center, const Scalar radius);
37 
38  /**
39  * Creates a new bounding sphere by a given bounding box.
40  * @param boundingBox Bounding box to be converted
41  */
42  inline explicit BoundingSphere(const BoundingBox& boundingBox);
43 
44  /**
45  * Returns both intersection points between a given ray and this sphere.
46  * The intersection points are determined without consideration of the ray direction<br>.
47  * @param ray Ray to determine the nearest intersection point for
48  * @param position0 Resulting nearest intersection position
49  * @param distance0 Resulting nearest intersection distance, regarding to the length of the ray direction
50  * @param position1 Resulting farthest intersection position
51  * @param distance1 Resulting farthest intersection distance, regarding to the length of the ray direction
52  * @return True, if so
53  */
54  bool intersections(const Line3& ray, Vector3& position0, Scalar& distance0, Vector3& position1, Scalar& distance1) const;
55 
56  /**
57  * Returns both intersection points between a given ray and this sphere.
58  * The intersection points are determined without consideration of the ray direction<br>.
59  * @param ray Ray to determine the nearest intersection point for
60  * @param transformation Transformation of the given world transformation (for the sphere)
61  * @param invertedTransformation Inverted transformation of the given world transformation (for the sphere)
62  * @param position0 Resulting nearest intersection position
63  * @param distance0 Resulting nearest intersection distance, regarding to the length of the ray direction
64  * @param position1 Resulting farthest intersection position
65  * @param distance1 Resulting farthest intersection distance, regarding to the length of the ray direction
66  * @return True, if so
67  */
68  inline bool intersections(const Line3& ray, const HomogenousMatrix4& transformation, const HomogenousMatrix4& invertedTransformation, Vector3& position0, Scalar& distance0, Vector3& position1, Scalar& distance1) const;
69 
70  /**
71  * Returns both intersection points between a given ray and this sphere.
72  * The intersection points are determined without consideration of the ray direction<br>.
73  * @param ray Ray to determine the nearest intersection point for
74  * @param position0 Resulting nearest intersection position
75  * @param distance0 Resulting nearest intersection distance, regarding to the length of the ray direction
76  * @param normal0 Resulting nearest intersection normal
77  * @param position1 Resulting farthest intersection position
78  * @param distance1 Resulting farthest intersection distance, regarding to the length of the ray direction
79  * @param normal1 Resulting farthest intersection normal
80  * @return True, if so
81  */
82  inline bool intersections(const Line3& ray, Vector3& position0, Scalar& distance0, Vector3& normal0, Vector3& position1, Scalar& distance1, Vector3& normal1) const;
83 
84  /**
85  * Returns both intersection points between a given ray and this sphere.
86  * The intersection points are determined without consideration of the ray direction<br>.
87  * @param ray Ray to determine the nearest intersection point for
88  * @param transformation Transformation of the given world transformation (for the sphere)
89  * @param invertedTransformation Inverted transformation of the given world transformation (for the sphere)
90  * @param position0 Resulting nearest intersection position
91  * @param distance0 Resulting nearest intersection distance, regarding to the length of the ray direction
92  * @param normal0 Resulting nearest intersection normal
93  * @param position1 Resulting farthest intersection position
94  * @param distance1 Resulting farthest intersection distance, regarding to the length of the ray direction
95  * @param normal1 Resulting farthest intersection normal
96  * @return True, if so
97  */
98  inline bool intersections(const Line3& ray, const HomogenousMatrix4& transformation, const HomogenousMatrix4& invertedTransformation, Vector3& position0, Scalar& distance0, Vector3& normal0, Vector3& position1, Scalar& distance1, Vector3& normal1) const;
99 
100  /**
101  * Returns the front intersection point between a given ray and this sphere whenever the distance is positive.
102  * The dot product between the ray direction and the intersection normal will be negative.<br>
103  * @param ray Ray to determine the intersection point for
104  * @param position Resulting intersection position
105  * @param distance Resulting intersection distance
106  * @return True, if so
107  */
108  bool positiveFrontIntersection(const Line3& ray, Vector3& position, Scalar& distance) const;
109 
110  /**
111  * Returns the front intersection point between a given ray and this sphere whenever the distance is positive.
112  * The dot product between the ray direction and the intersection normal will be negative.<br>
113  * @param ray Ray to determine the intersection point for
114  * @param position Resulting intersection position
115  * @param distance Resulting intersection distance
116  * @param normal Resulting intersection normal
117  * @return True, if so
118  */
119  inline bool positiveFrontIntersection(const Line3& ray, Vector3& position, Scalar& distance, Vector3& normal) const;
120 
121  /**
122  * Returns the front intersection point between a given ray and this sphere whenever the distance is positive.
123  * The dot product between the ray direction and the intersection normal will be negative.<br>
124  * @param ray Ray to determine the intersection point for
125  * @param transformation Transformation of the given world transformation (for the sphere)
126  * @param invertedTransformation Inverted transformation of the given world transformation (for the sphere)
127  * @param position Resulting intersection position
128  * @param distance Resulting intersection distance
129  * @return True, if so
130  */
131  inline bool positiveFrontIntersection(const Line3& ray, const HomogenousMatrix4& transformation, const HomogenousMatrix4& invertedTransformation, Vector3& position, Scalar& distance) const;
132 
133  /**
134  * Returns the front intersection point between a given ray and this sphere whenever the distance is positive.
135  * The dot product between the ray direction and the intersection normal will be negative.<br>
136  * @param ray Ray to determine the intersection point for
137  * @param transformation Transformation of the given world transformation (for the sphere)
138  * @param invertedTransformation Inverted transformation of the given world transformation (for the sphere)
139  * @param position Resulting intersection position
140  * @param distance Resulting intersection distance
141  * @param normal Resulting intersection normal
142  * @return True, if so
143  */
144  inline bool positiveFrontIntersection(const Line3& ray, const HomogenousMatrix4& transformation, const HomogenousMatrix4& invertedTransformation, Vector3& position, Scalar& distance, Vector3& normal) const;
145 
146  /**
147  * Returns the back intersection point between a given ray and this sphere whenever the distance is positive.
148  * The dot product between the ray direction and the intersection normal will be positive.<br>
149  * @param ray Ray to determine the intersection point for
150  * @param position Resulting intersection position
151  * @param distance Resulting intersection distance
152  * @return True, if so
153  */
154  bool positiveBackIntersection(const Line3& ray, Vector3& position, Scalar& distance) const;
155 
156  /**
157  * Returns the back intersection point between a given ray and this sphere whenever the distance is positive.
158  * The dot product between the ray direction and the intersection normal will be positive.<br>
159  * @param ray Ray to determine the intersection point for
160  * @param position Resulting intersection position
161  * @param distance Resulting intersection distance
162  * @param normal Resulting intersection normal
163  * @return True, if so
164  */
165  inline bool positiveBackIntersection(const Line3& ray, Vector3& position, Scalar& distance, Vector3& normal) const;
166 
167  /**
168  * Returns the back intersection point between a given ray and this sphere whenever the distance is positive.
169  * The dot product between the ray direction and the intersection normal will be positive.<br>
170  * @param ray Ray to determine the intersection point for
171  * @param transformation Transformation of the given world transformation (for the sphere)
172  * @param invertedTransformation Inverted transformation of the given world transformation (for the sphere)
173  * @param position Resulting intersection position
174  * @param distance Resulting intersection distance
175  * @return True, if so
176  */
177  inline bool positiveBackIntersection(const Line3& ray, const HomogenousMatrix4& transformation, const HomogenousMatrix4& invertedTransformation, Vector3& position, Scalar& distance) const;
178 
179  /**
180  * Returns the back intersection point between a given ray and this sphere whenever the distance is positive.
181  * The dot product between the ray direction and the intersection normal will be positive.<br>
182  * @param ray Ray to determine the intersection point for
183  * @param transformation Transformation of the given world transformation (for the sphere)
184  * @param invertedTransformation Inverted transformation of the given world transformation (for the sphere)
185  * @param position Resulting intersection position
186  * @param distance Resulting intersection distance
187  * @param normal Resulting intersection normal
188  * @return True, if so
189  */
190  inline bool positiveBackIntersection(const Line3& ray, const HomogenousMatrix4& transformation, const HomogenousMatrix4& invertedTransformation, Vector3& position, Scalar& distance, Vector3& normal) const;
191 
192  private:
193 
194  /// Inverse of the sphere radius.
196 };
197 
199  Sphere3(),
200  inverseRadius_(0)
201 {
202  // nothing to do here
203 }
204 
205 inline BoundingSphere::BoundingSphere(const Vector3& center, const Scalar radius) :
206  Sphere3(center, radius),
207  inverseRadius_((radius > 0) ? (Scalar(1) / radius) : Scalar(0))
208 {
209  // nothing to do here
210 }
211 
212 inline BoundingSphere::BoundingSphere(const BoundingBox& boundingBox) :
213  Sphere3(boundingBox)
214 {
215  inverseRadius_ = (radius_ > 0) ? (Scalar(1) / radius_) : Scalar(0);
216 }
217 
218 inline bool BoundingSphere::intersections(const Line3& ray, const HomogenousMatrix4& transformation, const HomogenousMatrix4& invertedTransformation, Vector3& position0, Scalar& distance0, Vector3& position1, Scalar& distance1) const
219 {
220  ocean_assert(isValid());
221  ocean_assert(transformation.isValid());
222  ocean_assert(invertedTransformation.isValid());
223  ocean_assert(ray.isValid());
224 
225  if (intersections(Line3(invertedTransformation * ray.point(), invertedTransformation.rotationMatrix(ray.direction())), position0, distance0, position1, distance1))
226  {
227  position0 = transformation * position0;
228  position1 = transformation * position1;
229  return true;
230  }
231 
232  return false;
233 }
234 
235 inline bool BoundingSphere::intersections(const Line3& ray, Vector3& position0, Scalar& distance0, Vector3& normal0, Vector3& position1, Scalar& distance1, Vector3& normal1) const
236 {
237  ocean_assert(isValid());
238  ocean_assert(ray.isValid());
239 
240  if (intersections(ray, position0, distance0, position1, distance1))
241  {
242  normal0 = (position0 - center_) * inverseRadius_;
243  normal1 = (position1 - center_) * inverseRadius_;
244 
245  return true;
246  }
247 
248  return false;
249 }
250 
251 inline bool BoundingSphere::intersections(const Line3& ray, const HomogenousMatrix4& transformation, const HomogenousMatrix4& invertedTransformation, Vector3& position0, Scalar& distance0, Vector3& normal0, Vector3& position1, Scalar& distance1, Vector3& normal1) const
252 {
253  ocean_assert(isValid());
254  ocean_assert(transformation.isValid());
255  ocean_assert(invertedTransformation.isValid());
256  ocean_assert(ray.isValid());
257 
258  if (intersections(Line3(invertedTransformation * ray.point(), invertedTransformation.rotationMatrix(ray.direction())), position0, distance0, normal0, position1, distance1, normal1))
259  {
260  position0 = transformation * position0;
261  normal0 = invertedTransformation.transposedRotationMatrix(normal0).normalizedOrZero();
262 
263  position1 = transformation * position1;
264  normal1 = invertedTransformation.transposedRotationMatrix(normal1).normalizedOrZero();
265  return true;
266  }
267 
268  return false;
269 }
270 
271 inline bool BoundingSphere::positiveFrontIntersection(const Line3& ray, Vector3& position, Scalar& distance, Vector3& normal) const
272 {
273  ocean_assert(isValid());
274  ocean_assert(ray.isValid());
275 
276  if (positiveFrontIntersection(ray, position, distance))
277  {
278  normal = (position - center_) * inverseRadius_;
279  ocean_assert(ray.direction() * normal <= 0);
280 
281  return true;
282  }
283 
284  return false;
285 }
286 
287 inline bool BoundingSphere::positiveFrontIntersection(const Line3& ray, const HomogenousMatrix4& transformation, const HomogenousMatrix4& invertedTransformation, Vector3& position, Scalar& distance) const
288 {
289  ocean_assert(isValid());
290  ocean_assert(transformation.isValid());
291  ocean_assert(invertedTransformation.isValid());
292  ocean_assert(ray.isValid());
293 
294  if (positiveFrontIntersection(Line3(invertedTransformation * ray.point(), invertedTransformation.rotationMatrix(ray.direction())), position, distance))
295  {
296  position = transformation * position;
297  return true;
298  }
299 
300  return false;
301 }
302 
303 inline bool BoundingSphere::positiveFrontIntersection(const Line3& ray, const HomogenousMatrix4& transformation, const HomogenousMatrix4& invertedTransformation, Vector3& position, Scalar& distance, Vector3& normal) const
304 {
305  ocean_assert(isValid());
306  ocean_assert(transformation.isValid());
307  ocean_assert(invertedTransformation.isValid());
308  ocean_assert(ray.isValid());
309 
310  if (positiveFrontIntersection(Line3(invertedTransformation * ray.point(), invertedTransformation.rotationMatrix(ray.direction())), position, distance, normal))
311  {
312  position = transformation * position;
313  normal = invertedTransformation.transposedRotationMatrix(normal).normalizedOrZero();
314  return true;
315  }
316 
317  return false;
318 }
319 
320 inline bool BoundingSphere::positiveBackIntersection(const Line3& ray, Vector3& position, Scalar& distance, Vector3& normal) const
321 {
322  ocean_assert(isValid());
323  ocean_assert(ray.isValid());
324 
325  if (positiveBackIntersection(ray, position, distance))
326  {
327  normal = (position - center_) * inverseRadius_;
328  ocean_assert(ray.direction() * normal >= 0);
329 
330  return true;
331  }
332 
333  return false;
334 }
335 
336 inline bool BoundingSphere::positiveBackIntersection(const Line3& ray, const HomogenousMatrix4& transformation, const HomogenousMatrix4& invertedTransformation, Vector3& position, Scalar& distance) const
337 {
338  ocean_assert(isValid());
339  ocean_assert(transformation.isValid());
340  ocean_assert(invertedTransformation.isValid());
341  ocean_assert(ray.isValid());
342 
343  if (positiveBackIntersection(Line3(invertedTransformation * ray.point(), invertedTransformation.rotationMatrix(ray.direction())), position, distance))
344  {
345  position = transformation * position;
346  return true;
347  }
348 
349  return false;
350 }
351 
352 inline bool BoundingSphere::positiveBackIntersection(const Line3& ray, const HomogenousMatrix4& transformation, const HomogenousMatrix4& invertedTransformation, Vector3& position, Scalar& distance, Vector3& normal) const
353 {
354  ocean_assert(isValid());
355  ocean_assert(transformation.isValid());
356  ocean_assert(invertedTransformation.isValid());
357  ocean_assert(ray.isValid());
358 
359  if (positiveBackIntersection(Line3(invertedTransformation * ray.point(), invertedTransformation.rotationMatrix(ray.direction())), position, distance, normal))
360  {
361  position = transformation * position;
362  normal = invertedTransformation.transposedRotationMatrix(normal).normalizedOrZero();
363  return true;
364  }
365 
366  return false;
367 }
368 
369 }
370 
371 #endif // META_OCEAN_MATH_BOUNDING_SPHERE_H
This class implements a 3D bounding box.
Definition: BoundingBox.h:23
This class implements a bounding sphere.
Definition: BoundingSphere.h:23
BoundingSphere()
Creates an invalid bounding sphere.
Definition: BoundingSphere.h:198
Scalar inverseRadius_
Inverse of the sphere radius.
Definition: BoundingSphere.h:195
bool positiveBackIntersection(const Line3 &ray, Vector3 &position, Scalar &distance) const
Returns the back intersection point between a given ray and this sphere whenever the distance is posi...
bool positiveFrontIntersection(const Line3 &ray, Vector3 &position, Scalar &distance) const
Returns the front intersection point between a given ray and this sphere whenever the distance is pos...
bool intersections(const Line3 &ray, Vector3 &position0, Scalar &distance0, Vector3 &position1, Scalar &distance1) const
Returns both intersection points between a given ray and this sphere.
VectorT3< T > transposedRotationMatrix(const VectorT3< T > &vector) const
Transforms a 3D vector by application of only the inner transposed rotation matrix (including scale a...
Definition: HomogenousMatrix4.h:1947
SquareMatrixT3< T > rotationMatrix() const
Returns the rotation matrix of the transformation.
Definition: HomogenousMatrix4.h:1493
bool isValid() const
Returns whether this matrix is a valid homogeneous transformation.
Definition: HomogenousMatrix4.h:1806
This class implements an infinite line in 3D space.
Definition: Line3.h:70
bool isValid() const
Returns whether this line has valid parameters.
Definition: Line3.h:303
const VectorT3< T > & direction() const
Returns the direction of the line.
Definition: Line3.h:284
const VectorT3< T > & point() const
Returns a point on the line.
Definition: Line3.h:271
This class implements a 3D sphere.
Definition: Sphere3.h:57
VectorT3< Scalar > center_
Sphere center.
Definition: Sphere3.h:179
bool isValid() const
Returns whether this radius of this sphere is not negative and thus the sphere is valid.
Definition: Sphere3.h:281
Scalar radius_
Sphere radius.
Definition: Sphere3.h:182
VectorT3< T > normalizedOrZero() const
Returns the normalized vector.
Definition: Vector3.h:619
LineT3< Scalar > Line3
Definition of the Line3 object, depending on the OCEAN_MATH_USE_SINGLE_PRECISION either with single o...
Definition: Line3.h:21
float Scalar
Definition of a scalar type.
Definition: Math.h:128
The namespace covering the entire Ocean framework.
Definition: Accessor.h:15