UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
BoxSphereBounds.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3#pragma once
4
5#include "CoreTypes.h"
6#include "Math/MathFwd.h" // IWYU pragma: export
9#include "Logging/LogMacros.h"
10#include "Math/Vector.h"
11#include "Math/Sphere.h"
12#include "Math/Box.h"
14
18namespace UE
19{
20namespace Math
21{
22
23template<typename T, typename TExtent>
25{
26 using FReal = T;
27
30
33
36
37public:
38
40 [[nodiscard]] TBoxSphereBounds() = default;
41
47 [[nodiscard]] explicit inline TBoxSphereBounds( EForceInit )
50 , SphereRadius(0)
51 {
53 }
54
69
77 {
79 Box.GetCenterAndExtents(Origin, LocalExtent);
81
82 SphereRadius = (TExtent)FMath::Min(LocalExtent.Size(), (Sphere.Center - Origin).Size() + Sphere.W);
83
85 }
86
104
116
125 [[nodiscard]] TBoxSphereBounds( const TVector<T>* Points, uint32 NumPoints );
126
127 // Conversion to other type.
128 template<typename TFrom, typename TExtentFrom UE_REQUIRES(!(std::is_same_v<T, TFrom> && std::is_same_v<TExtent, TExtentFrom>))>
133
134public:
135
138 {
139 if constexpr (std::is_same_v<T, float>)
140 {
141 // Falls back to UseSerializeItem to convert per property.
142 return false;
143 }
144 else if constexpr (std::is_same_v<T, double>)
145 {
146 // Falls back to UseSerializeItem to convert per property.
147 return false;
148 }
149 else
150 {
151 static_assert(sizeof(T) == 0, "Unimplemented");
152 return false;
153 }
154 }
155
163
171
179
180public:
181
189 {
190 TVector<T> Mins = Origin - BoxExtent;
192
193 return ::ComputeSquaredDistanceFromBoxToPoint(Mins, Maxs, Point);
194 }
195
205 {
206 return (A.Origin - B.Origin).SizeSquared() <= FMath::Square(FMath::Max<TExtent>(0, A.SphereRadius + B.SphereRadius + Tolerance));
207 }
208
217 {
218 return A.GetBox().Intersect(B.GetBox());
219 }
220
230
238 {
239 if (Extrema)
240 {
241 return Origin + BoxExtent;
242 }
243
244 return Origin - BoxExtent;
245 }
246
256
267
275
283
289 [[nodiscard]] FString ToString() const;
290
300
301#if ENABLE_NAN_DIAGNOSTIC
302 inline void DiagnosticCheckNaN() const
303 {
304 if (Origin.ContainsNaN())
305 {
306 logOrEnsureNanError(TEXT("Origin contains NaN: %s"), *Origin.ToString());
307 const_cast<TBoxSphereBounds*>(this)->Origin = TVector<T>::ZeroVector;
308 }
310 {
311 logOrEnsureNanError(TEXT("BoxExtent contains NaN: %s"), *BoxExtent.ToString());
313 }
314 if (FMath::IsNaN(SphereRadius) || !FMath::IsFinite(SphereRadius))
315 {
316 logOrEnsureNanError(TEXT("SphereRadius contains NaN: %f"), SphereRadius);
317 const_cast<TBoxSphereBounds*>(this)->SphereRadius = 0.f;
318 }
319 }
320#else
322#endif
323
324 [[nodiscard]] inline bool ContainsNaN() const
325 {
326 return Origin.ContainsNaN() || BoxExtent.ContainsNaN() || !FMath::IsFinite(SphereRadius);
327 }
328
329
330public:
335 struct Builder
336 {
341
343 {
344 return Append(Box);
345 }
346
351
356
358 {
359 return BoxSphereBounds.IsSet();
360 }
361
363 {
364 return BoxSphereBounds.Get(TBoxSphereBounds<T, TExtent>(ForceInitToZero));
365 }
366
367 private:
368 inline Builder& Append(const TBoxSphereBounds<T, TExtent>& Other)
369 {
370 if (IsValid())
371 {
372 *BoxSphereBounds = *BoxSphereBounds + Other;
373 }
374 else
375 {
376 BoxSphereBounds.Emplace(Other);
377 }
378 return *this;
379 }
380
382 };
383};
384
385
386/* TBoxSphereBounds<T, TExtent> inline functions
387 *****************************************************************************/
388
397{
398 Ar << Bounds.Origin << Bounds.BoxExtent << Bounds.SphereRadius;
399 return Ar;
400}
401
410{
411 Ar << Bounds.Origin << Bounds.BoxExtent;
413 {
414 Ar << Bounds.SphereRadius;
415 }
416 else
417 {
418 checkf(Ar.IsLoading(), TEXT("float -> double conversion applied outside of load!"));
419 // Stored as floats, so serialize float and copy.
420 float Radius;
421 Ar << Radius;
422 Bounds.SphereRadius = Radius;
423 }
424
425 return Ar;
426}
427
428template<typename T, typename TExtent>
430{
432
433 // find an axis aligned bounding box for the points.
434 for (uint32 PointIndex = 0; PointIndex < NumPoints; PointIndex++)
435 {
436 BoundingBox += Points[PointIndex];
437 }
438
440 BoundingBox.GetCenterAndExtents(Origin, LocalExtent);
441 BoxExtent = TVector<TExtent>(LocalExtent);
442
443 // using the center of the bounding box as the origin of the sphere, find the radius of the bounding sphere.
445
446 for (uint32 PointIndex = 0; PointIndex < NumPoints; PointIndex++)
447 {
448 SquaredSphereRadius = FMath::Max<TExtent>(SquaredSphereRadius, (Points[PointIndex] - Origin).SizeSquared()); // LWC_TODO: Precision loss
449 }
450
451 SphereRadius = FMath::Sqrt(SquaredSphereRadius);
452
453 DiagnosticCheckNaN();
454}
455
456template<typename T, typename TExtent>
458{
460
461 BoundingBox += (this->Origin - this->BoxExtent);
462 BoundingBox += (this->Origin + this->BoxExtent);
463 BoundingBox += (Other.Origin - Other.BoxExtent);
464 BoundingBox += (Other.Origin + Other.BoxExtent);
465
466 // build a bounding sphere from the bounding box's origin and the radii of A and B.
468
469 Result.SphereRadius = FMath::Min<TExtent>(Result.SphereRadius, FMath::Max<TExtent>((Origin - Result.Origin).Size() + SphereRadius, (Other.Origin - Result.Origin).Size() + Other.SphereRadius));
470 Result.DiagnosticCheckNaN();
471
472 return Result;
473}
474
475template<typename T, typename TExtent>
477{
478 return Origin == Other.Origin && BoxExtent == Other.BoxExtent && SphereRadius == Other.SphereRadius;
479}
480
481template<typename T, typename TExtent>
486
487template<typename T, typename TExtent>
489{
490 Ar << *this;
491 return true;
492}
493
494template<typename T, typename TExtent>
496{
497 return FString::Printf(TEXT("Origin=%s, BoxExtent=(%s), SphereRadius=(%f)"), *Origin.ToString(), *BoxExtent.ToString(), SphereRadius);
498}
499
500template<typename T, typename TExtent>
502{
503#if ENABLE_NAN_DIAGNOSTIC
504 if (M.ContainsNaN())
505 {
506 logOrEnsureNanError(TEXT("Input Matrix contains NaN/Inf! %s"), *M.ToString());
507 (const_cast<TMatrix<T>*>(&M))->SetIdentity();
508 }
509#endif
510
511 TBoxSphereBounds<T> Result;
512
513 const TVectorRegisterType<T> VecOrigin = VectorLoadFloat3(&Origin);
514 const TVectorRegisterType<T> VecExtent = VectorLoadFloat3(&BoxExtent);
515
520
521 TVectorRegisterType<T> NewOrigin = VectorMultiply(VectorReplicate(VecOrigin, 0), m0);
522 NewOrigin = VectorMultiplyAdd(VectorReplicate(VecOrigin, 1), m1, NewOrigin);
523 NewOrigin = VectorMultiplyAdd(VectorReplicate(VecOrigin, 2), m2, NewOrigin);
524 NewOrigin = VectorAdd(NewOrigin, m3);
525
529
530 VectorStoreFloat3(NewExtent, &(Result.BoxExtent.X));
531 VectorStoreFloat3(NewOrigin, &(Result.Origin.X));
532
537 Result.SphereRadius = FMath::Sqrt(VectorGetComponent(MaxRadius, 0)) * SphereRadius;
538
539 // For non-uniform scaling, computing sphere radius from a box results in a smaller sphere.
541 Result.SphereRadius = FMath::Min(Result.SphereRadius, BoxExtentMagnitude);
542
543 Result.DiagnosticCheckNaN();
544 return TBoxSphereBounds<T, TExtent>(Result);
545}
546
553 template<typename T, typename TExtent>
555{
556#if ENABLE_NAN_DIAGNOSTIC
558#endif
559
560 const TMatrix<T> Mat = M.ToMatrixWithScale();
561 TBoxSphereBounds<T, TExtent> Result = TransformBy(Mat);
562 return Result;
563}
564
565} // namespace UE::Math
566} // namespace UE
567
568template <> struct TIsPODType<FBoxSphereBounds3f> { enum { Value = true }; };
569template <> struct TIsPODType<FBoxSphereBounds3d> { enum { Value = true }; };
570template <> struct TIsUECoreVariant<FBoxSphereBounds3f> { enum { Value = true }; };
571template <> struct TIsUECoreVariant<FBoxSphereBounds3d> { enum { Value = true }; };
572template <> struct TIsUECoreVariant<FCompactBoxSphereBounds3d> { enum { Value = true }; };
#define checkf(expr, format,...)
Definition AssertionMacros.h:315
EForceInit
Definition CoreMiscDefines.h:154
@ ForceInitToZero
Definition CoreMiscDefines.h:156
@ ForceInit
Definition CoreMiscDefines.h:155
#define TEXT(x)
Definition Platform.h:1272
#define UE_FORCEINLINE_HINT
Definition Platform.h:723
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
#define logOrEnsureNanError(_FormatString_,...)
Definition LogMacros.h:436
FORCEINLINE VectorRegister4Double VectorLoadFloat3(const double *Ptr)
Definition UnrealMathFPU.h:427
FORCEINLINE VectorRegister4Float VectorMultiply(const VectorRegister4Float &Vec1, const VectorRegister4Float &Vec2)
Definition UnrealMathFPU.h:758
FORCEINLINE VectorRegister4Float VectorMax(const VectorRegister4Float &Vec1, const VectorRegister4Float &Vec2)
Definition UnrealMathFPU.h:1713
#define VectorGetComponent(Vec, ComponentIndex)
Definition UnrealMathFPU.h:385
VectorRegister4Float VectorLoadAligned(const float *Ptr)
Definition UnrealMathFPU.h:451
FORCEINLINE VectorRegister4Float VectorMultiplyAdd(const VectorRegister4Float &Vec1, const VectorRegister4Float &Vec2, const VectorRegister4Float &Vec3)
Definition UnrealMathFPU.h:786
FORCEINLINE VectorRegister4Float VectorAbs(const VectorRegister4Float &Vec)
Definition UnrealMathFPU.h:661
FORCEINLINE VectorRegister4Float VectorAdd(const VectorRegister4Float &Vec1, const VectorRegister4Float &Vec2)
Definition UnrealMathFPU.h:704
FORCEINLINE float VectorDot3Scalar(const VectorRegister4Float &Vec1, const VectorRegister4Float &Vec2)
Definition UnrealMathFPU.h:861
FORCEINLINE void VectorStoreFloat3(const VectorRegister4Float &Vec, float *Dst)
Definition UnrealMathFPU.h:594
#define VectorReplicate(Vec, ElementIndex)
Definition UnrealMathFPU.h:627
#define UE_KINDA_SMALL_NUMBER
Definition UnrealMathUtility.h:131
typename UE::Math::VectorRegisterPrivate::TVectorRegisterTypeHelper< T >::Type TVectorRegisterType
Definition VectorRegister.h:49
uint32 Size
Definition VulkanMemory.cpp:4034
uint32_t uint32
Definition binka_ue_file_header.h:6
bool ContainsNaN() const
Definition Vector.h:188
Definition Archive.h:1208
UE_FORCEINLINE_HINT bool IsLoading() const
Definition Archive.h:236
UE_FORCEINLINE_HINT FPackageFileVersion UEVer() const
Definition Archive.h:204
Definition NameTypes.h:617
FArchive & operator<<(FArchive &Ar, TBoxSphereBounds< float, float > &Bounds)
Definition BoxSphereBounds.h:396
Definition AdvancedWidgetsModule.cpp:13
static constexpr UE_FORCEINLINE_HINT T Square(const T A)
Definition UnrealMathUtility.h:578
Definition IsPODType.h:12
@ Value
Definition IsPODType.h:13
Definition IsUECoreType.h:19
@ Value
Definition IsUECoreType.h:20
Definition Optional.h:131
Definition BoxSphereBounds.h:336
UE_FORCEINLINE_HINT Builder & operator+=(const TSphere< T > &Sphere)
Definition BoxSphereBounds.h:347
UE_FORCEINLINE_HINT Builder & operator+=(const TVector< T > &Point)
Definition BoxSphereBounds.h:352
UE_FORCEINLINE_HINT Builder & operator+=(const TBox< T > &Box)
Definition BoxSphereBounds.h:342
UE_FORCEINLINE_HINT Builder & operator+=(const TBoxSphereBounds< T, TExtent > &Other)
Definition BoxSphereBounds.h:337
UE_FORCEINLINE_HINT bool IsValid() const
Definition BoxSphereBounds.h:357
Definition BoxSphereBounds.h:25
UE_FORCEINLINE_HINT void DiagnosticCheckNaN() const
Definition BoxSphereBounds.h:321
TVector< T > GetBoxExtrema(uint32 Extrema) const
Definition BoxSphereBounds.h:237
TBoxSphereBounds(const TBoxSphereBounds< TFrom, TExtentFrom > &From)
Definition BoxSphereBounds.h:129
TBoxSphereBounds(EForceInit)
Definition BoxSphereBounds.h:47
TVector< TExtent > BoxExtent
Definition BoxSphereBounds.h:32
TBoxSphereBounds< T, TExtent > operator+(const TBoxSphereBounds< T, TExtent > &Other) const
Definition BoxSphereBounds.h:457
FString ToString() const
Definition BoxSphereBounds.h:495
UE_FORCEINLINE_HINT TBoxSphereBounds< T, TExtent > ExpandBy(TExtent ExpandAmount) const
Definition BoxSphereBounds.h:263
TBoxSphereBounds(const TVector< T > &InOrigin, const TVector< TExtent > &InBoxExtent, TExtent InSphereRadius)
Definition BoxSphereBounds.h:62
TBoxSphereBounds(const TVector< T > *Points, uint32 NumPoints)
Definition BoxSphereBounds.h:429
friend TBoxSphereBounds< T, TExtent > Union(const TBoxSphereBounds< T, TExtent > &A, const TBoxSphereBounds< T, TExtent > &B)
Definition BoxSphereBounds.h:296
TBoxSphereBounds(const TBox< T > &Box)
Definition BoxSphereBounds.h:94
TExtent SphereRadius
Definition BoxSphereBounds.h:35
static UE_FORCEINLINE_HINT bool SpheresIntersect(const TBoxSphereBounds< T, TExtent > &A, const TBoxSphereBounds< T, TExtent > &B, TExtent Tolerance=UE_KINDA_SMALL_NUMBER)
Definition BoxSphereBounds.h:204
bool ContainsNaN() const
Definition BoxSphereBounds.h:324
TBoxSphereBounds(const TBox< T > &Box, const TSphere< T > &Sphere)
Definition BoxSphereBounds.h:76
TBoxSphereBounds(const TSphere< T > &Sphere)
Definition BoxSphereBounds.h:108
bool SerializeFromMismatchedTag(FName StructTag, FArchive &Ar)
Definition BoxSphereBounds.h:137
TBoxSphereBounds< T, TExtent > TransformBy(const TMatrix< T > &M) const
Definition BoxSphereBounds.h:501
bool Serialize(FArchive &Ar)
Definition BoxSphereBounds.h:488
TBoxSphereBounds< T, TExtent > TransformBy(const TTransform< T > &M) const
Definition BoxSphereBounds.h:554
UE_FORCEINLINE_HINT bool operator!=(const TBoxSphereBounds< T, TExtent > &Other) const
Definition BoxSphereBounds.h:482
static UE_FORCEINLINE_HINT bool BoxesIntersect(const TBoxSphereBounds< T, TExtent > &A, const TBoxSphereBounds< T, TExtent > &B)
Definition BoxSphereBounds.h:216
UE_FORCEINLINE_HINT bool operator==(const TBoxSphereBounds< T, TExtent > &Other) const
Definition BoxSphereBounds.h:476
TVector< T > Origin
Definition BoxSphereBounds.h:29
UE_FORCEINLINE_HINT TSphere< T > GetSphere() const
Definition BoxSphereBounds.h:252
UE_FORCEINLINE_HINT TBox< T > GetBox() const
Definition BoxSphereBounds.h:226
T ComputeSquaredDistanceFromBoxToPoint(const TVector< T > &Point) const
Definition BoxSphereBounds.h:188
T FReal
Definition BoxSphereBounds.h:26
Definition Box.h:35
Definition Matrix.h:43
FString ToString() const
Definition Matrix.h:367
T M[4][4]
Definition Matrix.h:49
bool ContainsNaN() const
Definition Matrix.inl:586
Definition Sphere.h:29
Definition TransformNonVectorized.h:39
TMatrix< T > ToMatrixWithScale() const
Definition TransformNonVectorized.h:241
UE_FORCEINLINE_HINT void DiagnosticCheckNaN_All() const
Definition TransformNonVectorized.h:108
Definition Vector.h:51
FString ToString() const
Definition Vector.h:2304
bool ContainsNaN() const
Definition Vector.h:2296
T Size() const
Definition Vector.h:1716