6#include "Math/MathFwd.h"
7#include "Math/Matrix.h"
8#include "Math/Transform.h"
9#include "Math/UnrealMathUtility.h"
10#include "Math/Vector.h"
11#include "Math/Vector4.h"
12#include "Misc/AssertionMacros.h"
13#include "Misc/LargeWorldCoordinates.h"
14#include "Serialization/Archive.h"
15#include "Serialization/StructuredArchiveAdapters.h"
16#include "Templates/IsUECoreType.h"
17#include "Templates/UnrealTypeTraits.h"
18#include "UObject/ObjectVersion.h"
21
22
25template <
typename T>
struct TMatrix;
44
45
46
47
49 : Center(0.0f, 0.0f, 0.0f)
54
55
56
57
58
59 TSphere(TVector<T> InV, T InW)
65
66
67
68
75
76
77
78
79
80 TSphere(
const TVector<T>* Points, int32 Count);
84
85
86
87
88
89 TSphere(
const TSphere<T>* Spheres, int32 Count);
93 explicit TSphere(
const TSphere<FArg>& From) : TSphere<T>(TVector<T>(From.Center), T(From.W)) {}
96
97
98
99
100
101
104 return Center.Equals(Sphere.Center, Tolerance) && FMath::Abs(W - Sphere.W) <= Tolerance;
108
109
110
111
112
113 bool operator==(
const TSphere<T>& Other)
const
115 return Center == Other.Center && W == Other.W;
119
120
121
122
123
124 bool operator!=(
const TSphere<T>& Other)
const
126 return !(*
this == Other);
130
131
132
133
134
135 TSphere<T> operator+(
const TSphere<T>& Other)
const
137 return TSphere<T>(*
this) += Other;
141
142
143
144
145
146 TSphere<T>& operator+=(
const TSphere<T>& Other);
149
150
151
152
153
154
157 if (W > Other.W + Tolerance)
162 return (Center - Other.Center).SizeSquared() <= FMath::Square(Other.W + Tolerance - W);
166
167
168
169
170
173 return (Center - In).SizeSquared() <= FMath::Square(W + Tolerance);
177
178
179
180
181
182
185 return (Center - Other.Center).SizeSquared() <= FMath::Square(FMath::Max(0.f, Other.W + W + Tolerance));
189
190
191
192
193
194 TSphere<T> TransformBy(
const TMatrix<T>& M)
const;
197
198
199
200
201
202 TSphere<T> TransformBy(
const FTransform& M)
const;
205
206
207
208
211 return (4.f / 3.f) *
UE_PI * (W * W * W);
215
216
217
218
219 FString ToString()
const
221 return FString::Printf(
TEXT(
"Center=(%s), Radius=(%s)"), *Center.ToString(), *W.ToString());
225 bool Serialize(FArchive& Ar)
231 bool SerializeFromMismatchedTag(FName StructTag, FArchive& Ar);
236
237
238
239
240
241
243inline FArchive& operator<<(FArchive& Ar, TSphere<
float>& Sphere)
245 Ar << Sphere.Center << Sphere.W;
250
251
252
253
254
255
257inline FArchive& operator<<(FArchive& Ar, TSphere<
double>& Sphere)
261 if (Ar.UEVer() >= EUnrealEngineObjectUE5Version::LARGE_WORLD_COORDINATES)
267 checkf(Ar.IsLoading(), TEXT(
"float -> double conversion applied outside of load!"));
271 Sphere.W = (
double)SW;
278TSphere<T> TSphere<T>::TransformBy(
const TMatrix<T>& M)
const
282 FVector4 TransformedCenter = M.TransformPosition(
this->Center);
283 Result.Center = TVector<T>(TransformedCenter.X, TransformedCenter.Y, TransformedCenter.Z);
285 const TVector<T> XAxis(M.M[0][0], M.M[0][1], M.M[0][2]);
286 const TVector<T> YAxis(M.M[1][0], M.M[1][1], M.M[1][2]);
287 const TVector<T> ZAxis(M.M[2][0], M.M[2][1], M.M[2][2]);
289 Result.W = FMath::Sqrt(FMath::Max(XAxis | XAxis, FMath::Max(YAxis | YAxis, ZAxis | ZAxis))) * W;
296TSphere<T> TSphere<T>::TransformBy(
const FTransform& M)
const
300 Result.Center = M.TransformPosition(
this->Center);
301 Result.W = M.GetMaximumAxisScale() * W;
307TSphere<T>& TSphere<T>::operator+=(
const TSphere<T>& Other)
315 TVector<T> ToOther = Other.Center - Center;
316 T DistSqr = ToOther.SizeSquared();
328 T Dist = FMath::Sqrt(DistSqr);
330 TSphere<T> NewSphere;
331 NewSphere.W = (Dist + Other.W + W) * 0.5f;
332 NewSphere.Center = Center;
336 NewSphere.Center += ToOther * ((NewSphere.W - W) / Dist);
340 checkSlow(Other.IsInside(NewSphere, 1.f));
350template<> TSphere<
float>::TSphere(
const TVector<
float>* Points, int32 Count);
351template<> TSphere<
double>::TSphere(
const TVector<
double>* Points, int32 Count);
352template<> TSphere<
float>::TSphere(
const TSphere<
float>* Spheres, int32 Count);
353template<> TSphere<
double>::TSphere(
const TSphere<
double>* Spheres, int32 Count);
362template<>
struct TIsPODType<FSphere3f> {
enum {
Value =
true }; };
363template<>
struct TIsUECoreVariant<FSphere3f> {
enum { Value =
true }; };
366template<>
struct TIsPODType<FSphere3d> {
enum {
Value =
true }; };
367template<>
struct TIsUECoreVariant<FSphere3d> {
enum { Value =
true }; };
370inline bool FSphere3f::SerializeFromMismatchedTag(FName StructTag, FArchive& Ar)
376inline bool FSphere3d::SerializeFromMismatchedTag(FName StructTag, FArchive& Ar)
383
386
387
388template<
typename FReal>
389FORCEINLINE UE::Math::TSphere<FReal> FMath::ComputeBoundingSphereForCone(UE::Math::TVector<FReal>
const& ConeOrigin, UE::Math::TVector<FReal>
const& ConeDirection, FReal ConeRadius, FReal CosConeAngle, FReal SinConeAngle)
392 const FReal COS_PI_OVER_4 = 0.70710678118f;
393 if (CosConeAngle < COS_PI_OVER_4)
395 return UE::Math::TSphere<FReal>(ConeOrigin + ConeDirection * ConeRadius * CosConeAngle, ConeRadius * SinConeAngle);
399 const FReal BoundingRadius = ConeRadius / (2.0f * CosConeAngle);
400 return UE::Math::TSphere<FReal>(ConeOrigin + ConeDirection * BoundingRadius, BoundingRadius);
#define checkf(expr, format,...)
#define UE_DECLARE_LWC_TYPE(...)
#define UE_SERIALIZE_VARIANT_FROM_MISMATCHED_TAG(AR_OR_SLOT, ALIAS, TYPE, ALT_TYPE)
#define UE_KINDA_SMALL_NUMBER
#define TEMPLATE_REQUIRES(...)