UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
Sphere.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
7#include "Math/Matrix.h"
8#include "Math/Transform.h"
10#include "Math/Vector.h"
11#include "Math/Vector4.h"
19
23namespace UE {
24namespace Math {
25template <typename T> struct TMatrix;
26
27template<typename T>
28struct TSphere
29{
30public:
31 using FReal = T;
32
35
37 T W;
38
39
41 [[nodiscard]] TSphere() = default;
42
49 : Center(0.0f, 0.0f, 0.0f)
50 , W(0)
51 { }
52
60 : Center(InV)
61 , W(InW)
62 { }
63
69 [[nodiscard]] explicit inline TSphere(EForceInit)
71 , W(0.0f)
72 { }
73
81
82
90
91 // Conversion from other variant type.
92 template<typename FArg UE_REQUIRES(!std::is_same_v<T, FArg>)>
93 [[nodiscard]] explicit TSphere(const TSphere<FArg>& From)
94 : TSphere<T>(TVector<T>(From.Center), T(From.W))
95 {
96 }
97
105 [[nodiscard]] bool Equals(const TSphere<T>& Sphere, T Tolerance = UE_KINDA_SMALL_NUMBER) const
106 {
107 return Center.Equals(Sphere.Center, Tolerance) && FMath::Abs(W - Sphere.W) <= Tolerance;
108 }
109
116 [[nodiscard]] bool operator==(const TSphere<T>& Other) const
117 {
118 return Center == Other.Center && W == Other.W;
119 }
120
127 [[nodiscard]] bool operator!=(const TSphere<T>& Other) const
128 {
129 return !(*this == Other);
130 }
131
139 {
140 return TSphere<T>(*this) += Other;
141 }
142
150
158 [[nodiscard]] bool IsInside(const TSphere<T>& Other, T Tolerance = UE_KINDA_SMALL_NUMBER) const
159 {
160 if (W > Other.W + Tolerance)
161 {
162 return false;
163 }
164
165 return (Center - Other.Center).SizeSquared() <= FMath::Square(Other.W + Tolerance - W);
166 }
167
174 [[nodiscard]] bool IsInside(const FVector& In, T Tolerance = UE_KINDA_SMALL_NUMBER) const
175 {
176 return (Center - In).SizeSquared() <= FMath::Square(W + Tolerance);
177 }
178
187 {
188 return (Center - Other.Center).SizeSquared() <= FMath::Square(FMath::Max(0.f, Other.W + W + Tolerance));
189 }
190
198
206
212 [[nodiscard]] T GetVolume() const
213 {
214 return (4.f / 3.f) * UE_PI * (W * W * W);
215 }
216
222 [[nodiscard]] FString ToString() const
223 {
224 return FString::Printf(TEXT("Center=(%s), Radius=(%s)"), *Center.ToString(), *LexToSanitizedString(W));
225 }
226
227 // Note: TSphere is usually written via binary serialization. This function exists for SerializeFromMismatchedTag conversion usage.
229 {
230 Ar << *this;
231 return true;
232 }
233
235 {
236 if constexpr (std::is_same_v<T, float>)
237 {
238 return UE_SERIALIZE_VARIANT_FROM_MISMATCHED_TAG(Ar, Sphere, Sphere3f, Sphere3d);
239 }
240 else if constexpr (std::is_same_v<T, double>)
241 {
242 return UE_SERIALIZE_VARIANT_FROM_MISMATCHED_TAG(Ar, Sphere, Sphere3d, Sphere3f);
243 }
244 else
245 {
246 static_assert(sizeof(T) == 0, "Unimplemented");
247 return false;
248 }
249 }
250
251};
252
262{
263 Ar << Sphere.Center << Sphere.W;
264 return Ar;
265}
266
276{
277 Ar << Sphere.Center;
278
280 {
281 Ar << Sphere.W;
282 }
283 else
284 {
285 checkf(Ar.IsLoading(), TEXT("float -> double conversion applied outside of load!"));
286 // Stored as floats, so serialize float and copy.
287 float SW;
288 Ar << SW;
289 Sphere.W = (double)SW;
290 }
291
292 return Ar;
293}
294
295template<typename T>
297{
298 TSphere<T> Result;
299
302
303 const TVector<T> XAxis(M.M[0][0], M.M[0][1], M.M[0][2]);
304 const TVector<T> YAxis(M.M[1][0], M.M[1][1], M.M[1][2]);
305 const TVector<T> ZAxis(M.M[2][0], M.M[2][1], M.M[2][2]);
306
307 Result.W = FMath::Sqrt(FMath::Max(XAxis | XAxis, FMath::Max(YAxis | YAxis, ZAxis | ZAxis))) * W;
308
309 return Result;
310}
311
312
313template<typename T>
315{
316 TSphere<T> Result;
317
318 Result.Center = M.TransformPosition(this->Center);
319 Result.W = M.GetMaximumAxisScale() * W;
320
321 return Result;
322}
323
324template<typename T>
326{
327 if (W == 0.f)
328 {
329 *this = Other;
330 return *this;
331 }
332
333 TVector<T> ToOther = Other.Center - Center;
334 T DistSqr = ToOther.SizeSquared();
335
336 if (FMath::Square(W - Other.W) + UE_KINDA_SMALL_NUMBER >= DistSqr)
337 {
338 // Pick the smaller
339 if (W < Other.W)
340 {
341 *this = Other;
342 }
343 }
344 else
345 {
346 T Dist = FMath::Sqrt(DistSqr);
347
349 NewSphere.W = (Dist + Other.W + W) * 0.5f;
350 NewSphere.Center = Center;
351
352 if (Dist > UE_SMALL_NUMBER)
353 {
354 NewSphere.Center += ToOther * ((NewSphere.W - W) / Dist);
355 }
356
357 // make sure both are inside afterwards
358 checkSlow(Other.IsInside(NewSphere, 1.f));
359 checkSlow(IsInside(NewSphere, 1.f));
360
361 *this = NewSphere;
362 }
363
364 return *this;
365}
366
367// Forward declarations for complex constructors.
372
373} // namespace Math
374} // namespace UE
375
376
378
379template<> struct TCanBulkSerialize<FSphere3f> { enum { Value = true }; };
380template<> struct TIsPODType<FSphere3f> { enum { Value = true }; };
381template<> struct TIsUECoreVariant<FSphere3f> { enum { Value = true }; };
382
383template<> struct TCanBulkSerialize<FSphere3d> { enum { Value = true }; };
384template<> struct TIsPODType<FSphere3d> { enum { Value = true }; };
385template<> struct TIsUECoreVariant<FSphere3d> { enum { Value = true }; };
386
387/* FMath inline functions
388 *****************************************************************************/
389
393template<typename FReal>
395{
396 // Based on: https://bartwronski.com/2017/04/13/cull-that-cone/
397 const FReal COS_PI_OVER_4 = 0.70710678118f; // Cos(Pi/4); // LWC_TODO: precision improvement possible here
399 {
400 return UE::Math::TSphere<FReal>(ConeOrigin + ConeDirection * ConeRadius * CosConeAngle, ConeRadius * SinConeAngle);
401 }
402 else
403 {
404 const FReal BoundingRadius = ConeRadius / (2.0f * CosConeAngle);
405 return UE::Math::TSphere<FReal>(ConeOrigin + ConeDirection * BoundingRadius, BoundingRadius);
406 }
407}
#define checkSlow(expr)
Definition AssertionMacros.h:332
#define checkf(expr, format,...)
Definition AssertionMacros.h:315
EForceInit
Definition CoreMiscDefines.h:154
@ ForceInit
Definition CoreMiscDefines.h:155
#define TEXT(x)
Definition Platform.h:1272
FPlatformTypes::int32 int32
A 32-bit signed integer.
Definition Platform.h:1125
#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 UE_SERIALIZE_VARIANT_FROM_MISMATCHED_TAG(AR_OR_SLOT, ALIAS, TYPE, ALT_TYPE)
Definition LargeWorldCoordinatesSerializer.h:9
#define UE_DECLARE_LWC_TYPE(...)
Definition LargeWorldCoordinates.h:27
#define UE_PI
Definition UnrealMathUtility.h:129
#define UE_SMALL_NUMBER
Definition UnrealMathUtility.h:130
#define UE_KINDA_SMALL_NUMBER
Definition UnrealMathUtility.h:131
StringType LexToSanitizedString(const T &Value)
Definition UnrealString.h:180
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 UE::Math::TSphere< FReal > ComputeBoundingSphereForCone(UE::Math::TVector< FReal > const &ConeOrigin, UE::Math::TVector< FReal > const &ConeDirection, FReal ConeRadius, FReal CosConeAngle, FReal SinConeAngle)
Definition Sphere.h:394
static constexpr UE_FORCEINLINE_HINT T Square(const T A)
Definition UnrealMathUtility.h:578
Definition Array.h:45
@ Value
Definition Array.h:46
Definition IsPODType.h:12
@ Value
Definition IsPODType.h:13
Definition IsUECoreType.h:19
@ Value
Definition IsUECoreType.h:20
Definition Matrix.h:43
TVector4< T > TransformPosition(const TVector< T > &V) const
Definition Matrix.inl:184
T M[4][4]
Definition Matrix.h:49
Definition Sphere.h:29
CORE_API TSphere(const TSphere< T > *Spheres, int32 Count)
TSphere< T > TransformBy(const TMatrix< T > &M) const
Definition Sphere.h:296
TSphere< T > & operator+=(const TSphere< T > &Other)
Definition Sphere.h:325
bool Equals(const TSphere< T > &Sphere, T Tolerance=UE_KINDA_SMALL_NUMBER) const
Definition Sphere.h:105
TSphere(TVector< T > InV, T InW)
Definition Sphere.h:59
TVector< T > Center
Definition Sphere.h:34
bool Serialize(FArchive &Ar)
Definition Sphere.h:228
bool IsInside(const TSphere< T > &Other, T Tolerance=UE_KINDA_SMALL_NUMBER) const
Definition Sphere.h:158
TSphere(int32)
Definition Sphere.h:48
TSphere(EForceInit)
Definition Sphere.h:69
bool operator!=(const TSphere< T > &Other) const
Definition Sphere.h:127
T GetVolume() const
Definition Sphere.h:212
TSphere< T > TransformBy(const FTransform &M) const
Definition Sphere.h:314
TSphere(const TSphere< FArg > &From)
Definition Sphere.h:93
bool SerializeFromMismatchedTag(FName StructTag, FArchive &Ar)
Definition Sphere.h:234
bool operator==(const TSphere< T > &Other) const
Definition Sphere.h:116
FString ToString() const
Definition Sphere.h:222
T W
Definition Sphere.h:37
CORE_API TSphere(const TVector< T > *Points, int32 Count)
bool IsInside(const FVector &In, T Tolerance=UE_KINDA_SMALL_NUMBER) const
Definition Sphere.h:174
UE_FORCEINLINE_HINT bool Intersects(const TSphere< T > &Other, T Tolerance=UE_KINDA_SMALL_NUMBER) const
Definition Sphere.h:186
T FReal
Definition Sphere.h:31
TSphere< T > operator+(const TSphere< T > &Other) const
Definition Sphere.h:138
T GetMaximumAxisScale() const
Definition TransformNonVectorized.h:1581
UE_FORCEINLINE_HINT TVector< T > TransformPosition(const TVector< T > &V) const
Definition TransformNonVectorized.h:1423
Definition Vector4.h:30
Definition Vector.h:51
T SizeSquared() const
Definition Vector.h:1728