UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
UnrealMathUtility.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"
7#include "Concepts/Integral.h"
9#include "HAL/PlatformMath.h"
10#include "Math/MathFwd.h"
11#include "Templates/Requires.h"
12
13// Assert on non finite numbers. Used to track NaNs.
14#ifndef ENABLE_NAN_DIAGNOSTIC
15 #if UE_BUILD_DEBUG
16 #define ENABLE_NAN_DIAGNOSTIC 1
17 #else
18 #define ENABLE_NAN_DIAGNOSTIC 0
19 #endif
20#endif
21
22/*-----------------------------------------------------------------------------
23 Definitions.
24-----------------------------------------------------------------------------*/
25
26// Forward declarations.
27struct FTwoVectors;
28struct FLinearColor;
29template<typename ElementType>
30class TRange;
31
32/*-----------------------------------------------------------------------------
33 Floating point constants.
34-----------------------------------------------------------------------------*/
35
36// These macros can have different values across modules inside a single codebase.
37// Tell the IncludeTool static analyzer to ignore that divergence in state:
38#define UE_INCLUDETOOL_IGNORE_INCONSISTENT_STATE
39
40// Define this to 1 in a module's .Build.cs to make legacy names issue deprecation warnings.
41#ifndef UE_DEPRECATE_LEGACY_MATH_CONSTANT_MACRO_NAMES
42 #define UE_DEPRECATE_LEGACY_MATH_CONSTANT_MACRO_NAMES 0
43#endif
44
45// Define this to 0 in a module's .Build.cs to stop that module recognizing the old identifiers.
46#ifndef UE_DEFINE_LEGACY_MATH_CONSTANT_MACRO_NAMES
47 #define UE_DEFINE_LEGACY_MATH_CONSTANT_MACRO_NAMES 1
48#endif
49
50// Process for fixing up a module's use of legacy names:
51//
52// - Define UE_DEPRECATE_LEGACY_MATH_CONSTANT_MACRO_NAMES=1 to the module's .Build.cs.
53// - Build and fix all warnings.
54// - Remove UE_DEPRECATE_LEGACY_MATH_CONSTANT_MACRO_NAMES=1 from the module's .Build.cs.
55// - Define UE_DEFINE_LEGACY_MATH_CONSTANT_MACRO_NAMES=0 from the module's .Build.cs to stop new usage of the legacy macros.
56
57#if UE_DEFINE_LEGACY_MATH_CONSTANT_MACRO_NAMES
58 #if UE_DEPRECATE_LEGACY_MATH_CONSTANT_MACRO_NAMES
59 #define UE_PRIVATE_MATH_DEPRECATION(Before, After) UE_DEPRECATED_MACRO(5.1, "The " #Before " macro has been deprecated in favor of " #After ".")
60 #else
61 #define UE_PRIVATE_MATH_DEPRECATION(Before, After)
62 #endif
64 #undef PI
65 #define PI UE_PRIVATE_MATH_DEPRECATION(PI , UE_PI ) UE_PI
66 #define SMALL_NUMBER UE_PRIVATE_MATH_DEPRECATION(SMALL_NUMBER , UE_SMALL_NUMBER ) UE_SMALL_NUMBER
67 #define KINDA_SMALL_NUMBER UE_PRIVATE_MATH_DEPRECATION(KINDA_SMALL_NUMBER , UE_KINDA_SMALL_NUMBER ) UE_KINDA_SMALL_NUMBER
68 #define BIG_NUMBER UE_PRIVATE_MATH_DEPRECATION(BIG_NUMBER , UE_BIG_NUMBER ) UE_BIG_NUMBER
69 #define EULERS_NUMBER UE_PRIVATE_MATH_DEPRECATION(EULERS_NUMBER , UE_EULERS_NUMBER ) UE_EULERS_NUMBER
70 #define FLOAT_NON_FRACTIONAL UE_PRIVATE_MATH_DEPRECATION(FLOAT_NON_FRACTIONAL , UE_FLOAT_NON_FRACTIONAL ) UE_FLOAT_NON_FRACTIONAL
71 #define DOUBLE_PI UE_PRIVATE_MATH_DEPRECATION(DOUBLE_PI , UE_DOUBLE_PI ) UE_DOUBLE_PI
72 #define DOUBLE_SMALL_NUMBER UE_PRIVATE_MATH_DEPRECATION(DOUBLE_SMALL_NUMBER , UE_DOUBLE_SMALL_NUMBER ) UE_DOUBLE_SMALL_NUMBER
73 #define DOUBLE_KINDA_SMALL_NUMBER UE_PRIVATE_MATH_DEPRECATION(DOUBLE_KINDA_SMALL_NUMBER , UE_DOUBLE_KINDA_SMALL_NUMBER ) UE_DOUBLE_KINDA_SMALL_NUMBER
74 #define DOUBLE_BIG_NUMBER UE_PRIVATE_MATH_DEPRECATION(DOUBLE_BIG_NUMBER , UE_DOUBLE_BIG_NUMBER ) UE_DOUBLE_BIG_NUMBER
75 #define DOUBLE_EULERS_NUMBER UE_PRIVATE_MATH_DEPRECATION(DOUBLE_EULERS_NUMBER , UE_DOUBLE_EULERS_NUMBER ) UE_DOUBLE_EULERS_NUMBER
76 #define DOUBLE_UE_GOLDEN_RATIO UE_PRIVATE_MATH_DEPRECATION(DOUBLE_UE_GOLDEN_RATIO , UE_DOUBLE_GOLDEN_RATIO ) UE_DOUBLE_GOLDEN_RATIO
77 #define DOUBLE_NON_FRACTIONAL UE_PRIVATE_MATH_DEPRECATION(DOUBLE_NON_FRACTIONAL , UE_DOUBLE_NON_FRACTIONAL ) UE_DOUBLE_NON_FRACTIONAL
78 #define MAX_FLT UE_PRIVATE_MATH_DEPRECATION(MAX_FLT , UE_MAX_FLT ) UE_MAX_FLT
79 #define INV_PI UE_PRIVATE_MATH_DEPRECATION(INV_PI , UE_INV_PI ) UE_INV_PI
80 #define HALF_PI UE_PRIVATE_MATH_DEPRECATION(HALF_PI , UE_HALF_PI ) UE_HALF_PI
81 #define TWO_PI UE_PRIVATE_MATH_DEPRECATION(TWO_PI , UE_TWO_PI ) UE_TWO_PI
82 #define PI_SQUARED UE_PRIVATE_MATH_DEPRECATION(PI_SQUARED , UE_PI_SQUARED ) UE_PI_SQUARED
83 #define DOUBLE_INV_PI UE_PRIVATE_MATH_DEPRECATION(DOUBLE_INV_PI , UE_DOUBLE_INV_PI ) UE_DOUBLE_INV_PI
84 #define DOUBLE_HALF_PI UE_PRIVATE_MATH_DEPRECATION(DOUBLE_HALF_PI , UE_DOUBLE_HALF_PI ) UE_DOUBLE_HALF_PI
85 #define DOUBLE_TWO_PI UE_PRIVATE_MATH_DEPRECATION(DOUBLE_TWO_PI , UE_DOUBLE_TWO_PI ) UE_DOUBLE_TWO_PI
86 #define DOUBLE_PI_SQUARED UE_PRIVATE_MATH_DEPRECATION(DOUBLE_PI_SQUARED , UE_DOUBLE_PI_SQUARED ) UE_DOUBLE_PI_SQUARED
87 #define DOUBLE_UE_SQRT_2 UE_PRIVATE_MATH_DEPRECATION(DOUBLE_UE_SQRT_2 , UE_DOUBLE_SQRT_2 ) UE_DOUBLE_SQRT_2
88 #define DOUBLE_UE_SQRT_3 UE_PRIVATE_MATH_DEPRECATION(DOUBLE_UE_SQRT_3 , UE_DOUBLE_SQRT_3 ) UE_DOUBLE_SQRT_3
89 #define DOUBLE_UE_INV_SQRT_2 UE_PRIVATE_MATH_DEPRECATION(DOUBLE_UE_INV_SQRT_2 , UE_DOUBLE_INV_SQRT_2 ) UE_DOUBLE_INV_SQRT_2
90 #define DOUBLE_UE_INV_SQRT_3 UE_PRIVATE_MATH_DEPRECATION(DOUBLE_UE_INV_SQRT_3 , UE_DOUBLE_INV_SQRT_3 ) UE_DOUBLE_INV_SQRT_3
91 #define DOUBLE_UE_HALF_SQRT_2 UE_PRIVATE_MATH_DEPRECATION(DOUBLE_UE_HALF_SQRT_2 , UE_DOUBLE_HALF_SQRT_2 ) UE_DOUBLE_HALF_SQRT_2
92 #define DOUBLE_UE_HALF_SQRT_3 UE_PRIVATE_MATH_DEPRECATION(DOUBLE_UE_HALF_SQRT_3 , UE_DOUBLE_HALF_SQRT_3 ) UE_DOUBLE_HALF_SQRT_3
93 #define DELTA UE_PRIVATE_MATH_DEPRECATION(DELTA , UE_DELTA ) UE_DELTA
94 #define DOUBLE_DELTA UE_PRIVATE_MATH_DEPRECATION(DOUBLE_DELTA , UE_DOUBLE_DELTA ) UE_DOUBLE_DELTA
95 #define FLOAT_NORMAL_THRESH UE_PRIVATE_MATH_DEPRECATION(FLOAT_NORMAL_THRESH , UE_FLOAT_NORMAL_THRESH ) UE_FLOAT_NORMAL_THRESH
96 #define DOUBLE_NORMAL_THRESH UE_PRIVATE_MATH_DEPRECATION(DOUBLE_NORMAL_THRESH , UE_DOUBLE_NORMAL_THRESH ) UE_DOUBLE_NORMAL_THRESH
97 #define THRESH_POINT_ON_PLANE UE_PRIVATE_MATH_DEPRECATION(THRESH_POINT_ON_PLANE , UE_THRESH_POINT_ON_PLANE ) UE_THRESH_POINT_ON_PLANE
98 #define THRESH_POINT_ON_SIDE UE_PRIVATE_MATH_DEPRECATION(THRESH_POINT_ON_SIDE , UE_THRESH_POINT_ON_SIDE ) UE_THRESH_POINT_ON_SIDE
99 #define THRESH_POINTS_ARE_SAME UE_PRIVATE_MATH_DEPRECATION(THRESH_POINTS_ARE_SAME , UE_THRESH_POINTS_ARE_SAME ) UE_THRESH_POINTS_ARE_SAME
100 #define THRESH_POINTS_ARE_NEAR UE_PRIVATE_MATH_DEPRECATION(THRESH_POINTS_ARE_NEAR , UE_THRESH_POINTS_ARE_NEAR ) UE_THRESH_POINTS_ARE_NEAR
101 #define THRESH_NORMALS_ARE_SAME UE_PRIVATE_MATH_DEPRECATION(THRESH_NORMALS_ARE_SAME , UE_THRESH_NORMALS_ARE_SAME ) UE_THRESH_NORMALS_ARE_SAME
102 #define THRESH_UVS_ARE_SAME UE_PRIVATE_MATH_DEPRECATION(THRESH_UVS_ARE_SAME , UE_THRESH_UVS_ARE_SAME ) UE_THRESH_UVS_ARE_SAME
103 #define THRESH_VECTORS_ARE_NEAR UE_PRIVATE_MATH_DEPRECATION(THRESH_VECTORS_ARE_NEAR , UE_THRESH_VECTORS_ARE_NEAR ) UE_THRESH_VECTORS_ARE_NEAR
104 #define THRESH_SPLIT_POLY_WITH_PLANE UE_PRIVATE_MATH_DEPRECATION(THRESH_SPLIT_POLY_WITH_PLANE , UE_THRESH_SPLIT_POLY_WITH_PLANE ) UE_THRESH_SPLIT_POLY_WITH_PLANE
105 #define THRESH_SPLIT_POLY_PRECISELY UE_PRIVATE_MATH_DEPRECATION(THRESH_SPLIT_POLY_PRECISELY , UE_THRESH_SPLIT_POLY_PRECISELY ) UE_THRESH_SPLIT_POLY_PRECISELY
106 #define THRESH_ZERO_NORM_SQUARED UE_PRIVATE_MATH_DEPRECATION(THRESH_ZERO_NORM_SQUARED , UE_THRESH_ZERO_NORM_SQUARED ) UE_THRESH_ZERO_NORM_SQUARED
107 #define THRESH_NORMALS_ARE_PARALLEL UE_PRIVATE_MATH_DEPRECATION(THRESH_NORMALS_ARE_PARALLEL , UE_THRESH_NORMALS_ARE_PARALLEL ) UE_THRESH_NORMALS_ARE_PARALLEL
108 #define THRESH_NORMALS_ARE_ORTHOGONAL UE_PRIVATE_MATH_DEPRECATION(THRESH_NORMALS_ARE_ORTHOGONAL , UE_THRESH_NORMALS_ARE_ORTHOGONAL ) UE_THRESH_NORMALS_ARE_ORTHOGONAL
109 #define THRESH_VECTOR_NORMALIZED UE_PRIVATE_MATH_DEPRECATION(THRESH_VECTOR_NORMALIZED , UE_THRESH_VECTOR_NORMALIZED ) UE_THRESH_VECTOR_NORMALIZED
110 #define THRESH_QUAT_NORMALIZED UE_PRIVATE_MATH_DEPRECATION(THRESH_QUAT_NORMALIZED , UE_THRESH_QUAT_NORMALIZED ) UE_THRESH_QUAT_NORMALIZED
111 #define DOUBLE_THRESH_POINT_ON_PLANE UE_PRIVATE_MATH_DEPRECATION(DOUBLE_THRESH_POINT_ON_PLANE , UE_DOUBLE_THRESH_POINT_ON_PLANE ) UE_DOUBLE_THRESH_POINT_ON_PLANE
112 #define DOUBLE_THRESH_POINT_ON_SIDE UE_PRIVATE_MATH_DEPRECATION(DOUBLE_THRESH_POINT_ON_SIDE , UE_DOUBLE_THRESH_POINT_ON_SIDE ) UE_DOUBLE_THRESH_POINT_ON_SIDE
113 #define DOUBLE_THRESH_POINTS_ARE_SAME UE_PRIVATE_MATH_DEPRECATION(DOUBLE_THRESH_POINTS_ARE_SAME , UE_DOUBLE_THRESH_POINTS_ARE_SAME ) UE_DOUBLE_THRESH_POINTS_ARE_SAME
114 #define DOUBLE_THRESH_POINTS_ARE_NEAR UE_PRIVATE_MATH_DEPRECATION(DOUBLE_THRESH_POINTS_ARE_NEAR , UE_DOUBLE_THRESH_POINTS_ARE_NEAR ) UE_DOUBLE_THRESH_POINTS_ARE_NEAR
115 #define DOUBLE_THRESH_NORMALS_ARE_SAME UE_PRIVATE_MATH_DEPRECATION(DOUBLE_THRESH_NORMALS_ARE_SAME , UE_DOUBLE_THRESH_NORMALS_ARE_SAME ) UE_DOUBLE_THRESH_NORMALS_ARE_SAME
116 #define DOUBLE_THRESH_UVS_ARE_SAME UE_PRIVATE_MATH_DEPRECATION(DOUBLE_THRESH_UVS_ARE_SAME , UE_DOUBLE_THRESH_UVS_ARE_SAME ) UE_DOUBLE_THRESH_UVS_ARE_SAME
117 #define DOUBLE_THRESH_VECTORS_ARE_NEAR UE_PRIVATE_MATH_DEPRECATION(DOUBLE_THRESH_VECTORS_ARE_NEAR , UE_DOUBLE_THRESH_VECTORS_ARE_NEAR ) UE_DOUBLE_THRESH_VECTORS_ARE_NEAR
118 #define DOUBLE_THRESH_SPLIT_POLY_WITH_PLANE UE_PRIVATE_MATH_DEPRECATION(DOUBLE_THRESH_SPLIT_POLY_WITH_PLANE , UE_DOUBLE_THRESH_SPLIT_POLY_WITH_PLANE ) UE_DOUBLE_THRESH_SPLIT_POLY_WITH_PLANE
119 #define DOUBLE_THRESH_SPLIT_POLY_PRECISELY UE_PRIVATE_MATH_DEPRECATION(DOUBLE_THRESH_SPLIT_POLY_PRECISELY , UE_DOUBLE_THRESH_SPLIT_POLY_PRECISELY ) UE_DOUBLE_THRESH_SPLIT_POLY_PRECISELY
120 #define DOUBLE_THRESH_ZERO_NORM_SQUARED UE_PRIVATE_MATH_DEPRECATION(DOUBLE_THRESH_ZERO_NORM_SQUARED , UE_DOUBLE_THRESH_ZERO_NORM_SQUARED ) UE_DOUBLE_THRESH_ZERO_NORM_SQUARED
121 #define DOUBLE_THRESH_NORMALS_ARE_PARALLEL UE_PRIVATE_MATH_DEPRECATION(DOUBLE_THRESH_NORMALS_ARE_PARALLEL , UE_DOUBLE_THRESH_NORMALS_ARE_PARALLEL ) UE_DOUBLE_THRESH_NORMALS_ARE_PARALLEL
122 #define DOUBLE_THRESH_NORMALS_ARE_ORTHOGONAL UE_PRIVATE_MATH_DEPRECATION(DOUBLE_THRESH_NORMALS_ARE_ORTHOGONAL , UE_DOUBLE_THRESH_NORMALS_ARE_ORTHOGONAL ) UE_DOUBLE_THRESH_NORMALS_ARE_ORTHOGONAL
123 #define DOUBLE_THRESH_VECTOR_NORMALIZED UE_PRIVATE_MATH_DEPRECATION(DOUBLE_THRESH_VECTOR_NORMALIZED , UE_DOUBLE_THRESH_VECTOR_NORMALIZED ) UE_DOUBLE_THRESH_VECTOR_NORMALIZED
124 #define DOUBLE_THRESH_QUAT_NORMALIZED UE_PRIVATE_MATH_DEPRECATION(DOUBLE_THRESH_QUAT_NORMALIZED , UE_DOUBLE_THRESH_QUAT_NORMALIZED ) UE_DOUBLE_THRESH_QUAT_NORMALIZED
125#endif
126
127#undef UE_INCLUDETOOL_IGNORE_INCONSISTENT_STATE
128
129#define UE_PI (3.1415926535897932f) /* Extra digits if needed: 3.1415926535897932384626433832795f */
130#define UE_SMALL_NUMBER (1.e-8f)
131#define UE_KINDA_SMALL_NUMBER (1.e-4f)
132#define UE_BIG_NUMBER (3.4e+38f)
133#define UE_EULERS_NUMBER (2.71828182845904523536f)
134#define UE_GOLDEN_RATIO (1.6180339887498948482045868343656381f) /* Also known as divine proportion, golden mean, or golden section - related to the Fibonacci Sequence = (1 + sqrt(5)) / 2 */
135#define UE_FLOAT_NON_FRACTIONAL (8388608.f) /* All single-precision floating point numbers greater than or equal to this have no fractional value. */
136
137
138#define UE_DOUBLE_PI (3.141592653589793238462643383279502884197169399)
139#define UE_DOUBLE_SMALL_NUMBER (1.e-8)
140#define UE_DOUBLE_KINDA_SMALL_NUMBER (1.e-4)
141#define UE_DOUBLE_BIG_NUMBER (3.4e+38)
142#define UE_DOUBLE_EULERS_NUMBER (2.7182818284590452353602874713526624977572)
143#define UE_DOUBLE_GOLDEN_RATIO (1.6180339887498948482045868343656381) /* Also known as divine proportion, golden mean, or golden section - related to the Fibonacci Sequence = (1 + sqrt(5)) / 2 */
144#define UE_DOUBLE_NON_FRACTIONAL (4503599627370496.0) /* All double-precision floating point numbers greater than or equal to this have no fractional value. 2^52 */
145
146// Copied from float.h
147#define UE_MAX_FLT 3.402823466e+38F
148
149// Aux constants.
150#define UE_INV_PI (0.31830988618f)
151#define UE_HALF_PI (1.57079632679f)
152#define UE_TWO_PI (6.28318530717f)
153#define UE_PI_SQUARED (9.86960440108f)
154
155#define UE_DOUBLE_INV_PI (0.31830988618379067154)
156#define UE_DOUBLE_HALF_PI (1.57079632679489661923)
157#define UE_DOUBLE_TWO_PI (6.28318530717958647692)
158#define UE_DOUBLE_PI_SQUARED (9.86960440108935861883)
159
160#define UE_LN2 (0.69314718056f)
161
162// Common square roots
163#define UE_SQRT_2 (1.4142135623730950488016887242097f)
164#define UE_SQRT_3 (1.7320508075688772935274463415059f)
165#define UE_INV_SQRT_2 (0.70710678118654752440084436210485f)
166#define UE_INV_SQRT_3 (0.57735026918962576450914878050196f)
167#define UE_HALF_SQRT_2 (0.70710678118654752440084436210485f)
168#define UE_HALF_SQRT_3 (0.86602540378443864676372317075294f)
169
170#define UE_DOUBLE_SQRT_2 (1.4142135623730950488016887242097)
171#define UE_DOUBLE_SQRT_3 (1.7320508075688772935274463415059)
172#define UE_DOUBLE_INV_SQRT_2 (0.70710678118654752440084436210485)
173#define UE_DOUBLE_INV_SQRT_3 (0.57735026918962576450914878050196)
174#define UE_DOUBLE_HALF_SQRT_2 (0.70710678118654752440084436210485)
175#define UE_DOUBLE_HALF_SQRT_3 (0.86602540378443864676372317075294)
176
177// Common metric unit conversion
178#define UE_KM_TO_M (1000.f)
179#define UE_M_TO_KM (0.001f)
180#define UE_CM_TO_M (0.01f)
181#define UE_M_TO_CM (100.f)
182#define UE_CM2_TO_M2 (0.0001f)
183#define UE_M2_TO_CM2 (10000.f)
184
185// Magic numbers for numerical precision.
186#define UE_DELTA (0.00001f)
187#define UE_DOUBLE_DELTA (0.00001 )
188
193#define UE_FLOAT_NORMAL_THRESH (0.0001f)
194#define UE_DOUBLE_NORMAL_THRESH (0.0001)
195
196//
197// Magic numbers for numerical precision.
198//
199#define UE_THRESH_POINT_ON_PLANE (0.10f) /* Thickness of plane for front/back/inside test */
200#define UE_THRESH_POINT_ON_SIDE (0.20f) /* Thickness of polygon side's side-plane for point-inside/outside/on side test */
201#define UE_THRESH_POINTS_ARE_SAME (0.00002f) /* Two points are same if within this distance */
202#define UE_THRESH_POINTS_ARE_NEAR (0.015f) /* Two points are near if within this distance and can be combined if imprecise math is ok */
203#define UE_THRESH_NORMALS_ARE_SAME (0.00002f) /* Two normal points are same if within this distance */
204#define UE_THRESH_UVS_ARE_SAME (0.0009765625f)/* Two UV are same if within this threshold (1.0f/1024f) */
205 /* Making this too large results in incorrect CSG classification and disaster */
206#define UE_THRESH_VECTORS_ARE_NEAR (0.0004f) /* Two vectors are near if within this distance and can be combined if imprecise math is ok */
207 /* Making this too large results in lighting problems due to inaccurate texture coordinates */
208#define UE_THRESH_SPLIT_POLY_WITH_PLANE (0.25f) /* A plane splits a polygon in half */
209#define UE_THRESH_SPLIT_POLY_PRECISELY (0.01f) /* A plane exactly splits a polygon */
210#define UE_THRESH_ZERO_NORM_SQUARED (0.0001f) /* Size of a unit normal that is considered "zero", squared */
211#define UE_THRESH_NORMALS_ARE_PARALLEL (0.999845f) /* Two unit vectors are parallel if abs(A dot B) is greater than or equal to this. This is roughly cosine(1.0 degrees). */
212#define UE_THRESH_NORMALS_ARE_ORTHOGONAL (0.017455f) /* Two unit vectors are orthogonal (perpendicular) if abs(A dot B) is less than or equal this. This is roughly cosine(89.0 degrees). */
213
214#define UE_THRESH_VECTOR_NORMALIZED (0.01f)
215#define UE_THRESH_QUAT_NORMALIZED (0.01f)
217// Double precision values
218#define UE_DOUBLE_THRESH_POINT_ON_PLANE (0.10) /* Thickness of plane for front/back/inside test */
219#define UE_DOUBLE_THRESH_POINT_ON_SIDE (0.20) /* Thickness of polygon side's side-plane for point-inside/outside/on side test */
220#define UE_DOUBLE_THRESH_POINTS_ARE_SAME (0.00002) /* Two points are same if within this distance */
221#define UE_DOUBLE_THRESH_POINTS_ARE_NEAR (0.015) /* Two points are near if within this distance and can be combined if imprecise math is ok */
222#define UE_DOUBLE_THRESH_NORMALS_ARE_SAME (0.00002) /* Two normal points are same if within this distance */
223#define UE_DOUBLE_THRESH_UVS_ARE_SAME (0.0009765625)/* Two UV are same if within this threshold (1.0/1024.0) */
224 /* Making this too large results in incorrect CSG classification and disaster */
225#define UE_DOUBLE_THRESH_VECTORS_ARE_NEAR (0.0004) /* Two vectors are near if within this distance and can be combined if imprecise math is ok */
226 /* Making this too large results in lighting problems due to inaccurate texture coordinates */
227#define UE_DOUBLE_THRESH_SPLIT_POLY_WITH_PLANE (0.25) /* A plane splits a polygon in half */
228#define UE_DOUBLE_THRESH_SPLIT_POLY_PRECISELY (0.01) /* A plane exactly splits a polygon */
229#define UE_DOUBLE_THRESH_ZERO_NORM_SQUARED (0.0001) /* Size of a unit normal that is considered "zero", squared */
230#define UE_DOUBLE_THRESH_NORMALS_ARE_PARALLEL (0.999845) /* Two unit vectors are parallel if abs(A dot B) is greater than or equal to this. This is roughly cosine(1.0 degrees). */
231#define UE_DOUBLE_THRESH_NORMALS_ARE_ORTHOGONAL (0.017455) /* Two unit vectors are orthogonal (perpendicular) if abs(A dot B) is less than or equal this. This is roughly cosine(89.0 degrees). */
232
233#define UE_DOUBLE_THRESH_VECTOR_NORMALIZED (0.01)
234#define UE_DOUBLE_THRESH_QUAT_NORMALIZED (0.01)
236/*-----------------------------------------------------------------------------
237 Global functions.
238-----------------------------------------------------------------------------*/
239
259template <typename T>
261{
262 constexpr static bool Value = false;
263};
264
269struct FMath : public FPlatformMath
270{
271 // Random Number Functions
272
275 {
276 // Note that on some platforms RAND_MAX is a large number so we cannot do ((rand()/(RAND_MAX+1)) * A)
277 // or else we may include the upper bound results, which should be excluded.
278 return A > 0 ? Min(TruncToInt(FRand() * (float)A), A - 1) : 0;
279 }
280
282 {
283 // Note that on some platforms RAND_MAX is a large number so we cannot do ((rand()/(RAND_MAX+1)) * A)
284 // or else we may include the upper bound results, which should be excluded.
285 return A > 0 ? Min<int64>(TruncToInt(FRand() * (float)A), A - 1) : 0;
286 }
287
290 {
291 const int32 Range = (Max - Min) + 1;
292 return Min + RandHelper(Range);
293 }
294
296 {
297 const int64 Range = (Max - Min) + 1;
298 return Min + RandHelper64(Range);
299 }
300
302 [[nodiscard]] static UE_FORCEINLINE_HINT float RandRange(float InMin, float InMax)
303 {
304 return FRandRange(InMin, InMax);
305 }
306
307 [[nodiscard]] static UE_FORCEINLINE_HINT double RandRange(double InMin, double InMax)
308 {
309 return FRandRange(InMin, InMax);
310 }
311
313 [[nodiscard]] static UE_FORCEINLINE_HINT float FRandRange(float InMin, float InMax)
314 {
315 return InMin + (InMax - InMin) * FRand();
316 }
317
319 [[nodiscard]] static UE_FORCEINLINE_HINT double FRandRange(double InMin, double InMax)
320 {
321 return InMin + (InMax - InMin) * FRand(); // LWC_TODO: Implement FRandDbl() for increased precision
322 }
323
325
328 {
329 return (RandRange(0,1) == 1) ? true : false;
330 }
331
333 [[nodiscard]] static FVector VRand();
334
339 [[nodiscard]] static CORE_API FVector VRandCone(FVector const& Dir, float ConeHalfAngleRad);
340
346
348 [[nodiscard]] static CORE_API FVector2D RandPointInCircle(float CircleRadius);
349
351 [[nodiscard]] static CORE_API FVector RandPointInBox(const FBox& Box);
352
362 [[nodiscard]] static CORE_API FVector GetReflectionVector(const FVector& Direction, const FVector& SurfaceNormal);
363
364 // Predicates
365
367 template< class T, class U>
368 [[nodiscard]] static constexpr UE_FORCEINLINE_HINT bool IsWithin(const T& TestValue, const U& MinValue, const U& MaxValue)
369 {
370 return ((TestValue >= MinValue) && (TestValue < MaxValue));
371 }
372
373
375 template< class T, class U>
376 [[nodiscard]] static constexpr UE_FORCEINLINE_HINT bool IsWithinInclusive(const T& TestValue, const U& MinValue, const U& MaxValue)
377 {
378 return ((TestValue>=MinValue) && (TestValue <= MaxValue));
379 }
380
388 [[nodiscard]] static UE_FORCEINLINE_HINT bool IsNearlyEqual(float A, float B, float ErrorTolerance = UE_SMALL_NUMBER)
389 {
390 return Abs<float>( A - B ) <= ErrorTolerance;
391 }
392
393 [[nodiscard]] static UE_FORCEINLINE_HINT bool IsNearlyEqual(double A, double B, double ErrorTolerance = UE_DOUBLE_SMALL_NUMBER)
394 {
395 return Abs<double>(A - B) <= ErrorTolerance;
396 }
397
400
407 [[nodiscard]] static UE_FORCEINLINE_HINT bool IsNearlyZero(float Value, float ErrorTolerance = UE_SMALL_NUMBER)
408 {
409 return Abs<float>( Value ) <= ErrorTolerance;
410 }
411
418 [[nodiscard]] static UE_FORCEINLINE_HINT bool IsNearlyZero(double Value, double ErrorTolerance = UE_DOUBLE_SMALL_NUMBER)
419 {
420 return Abs<double>( Value ) <= ErrorTolerance;
421 }
422
424
425private:
426 template<typename FloatType, typename IntegralType, IntegralType SignedBit>
427 static inline bool TIsNearlyEqualByULP(FloatType A, FloatType B, int32 MaxUlps)
428 {
429 // Any comparison with NaN always fails.
430 if (FMath::IsNaN(A) || FMath::IsNaN(B))
431 {
432 return false;
433 }
434
435 // If either number is infinite, then ignore ULP and do a simple equality test.
436 // The rationale being that two infinities, of the same sign, should compare the same
437 // no matter the ULP, but FLT_MAX and Inf should not, even if they're neighbors in
438 // their bit representation.
439 if (!FMath::IsFinite(A) || !FMath::IsFinite(B))
440 {
441 return A == B;
442 }
443
444 // Convert the integer representation of the float from sign + magnitude to
445 // a signed number representation where 0 is 1 << 31. This allows us to compare
446 // ULP differences around zero values.
447 auto FloatToSignedNumber = [](IntegralType V) {
448 if (V & SignedBit)
449 {
450 return ~V + 1;
451 }
452 else
453 {
454 return SignedBit | V;
455 }
456 };
457
458 IntegralType SNA = FloatToSignedNumber(FMath::AsUInt(A));
459 IntegralType SNB = FloatToSignedNumber(FMath::AsUInt(B));
460 IntegralType Distance = (SNA >= SNB) ? (SNA - SNB) : (SNB - SNA);
461 return Distance <= IntegralType(MaxUlps);
462 }
463
464public:
465
490
512
518 template <typename T>
519 [[nodiscard]] static constexpr UE_FORCEINLINE_HINT bool IsPowerOfTwo( T Value )
520 {
521 return ((Value & (Value - 1)) == (T)0);
522 }
523
525 [[nodiscard]] static UE_FORCEINLINE_HINT float Floor(float F)
526 {
527 return FloorToFloat(F);
528 }
529
531 [[nodiscard]] static UE_FORCEINLINE_HINT double Floor(double F)
532 {
533 return FloorToDouble(F);
534 }
535
540 template <UE::CIntegral IntegralType>
542 {
543 return I;
544 }
545
546
547 // Math Operations
548
550 template< class T >
551 [[nodiscard]] static constexpr UE_FORCEINLINE_HINT T Max3( const T A, const T B, const T C )
552 {
553 return Max ( Max( A, B ), C );
554 }
555
557 template< class T >
558 [[nodiscard]] static constexpr UE_FORCEINLINE_HINT T Min3( const T A, const T B, const T C )
559 {
560 return Min ( Min( A, B ), C );
561 }
562
563 template< class T >
564 [[nodiscard]] static constexpr UE_FORCEINLINE_HINT int32 Max3Index( const T A, const T B, const T C )
565 {
566 return ( A > B ) ? ( ( A > C ) ? 0 : 2 ) : ( ( B > C ) ? 1 : 2 );
567 }
568
570 template< class T >
571 [[nodiscard]] static constexpr UE_FORCEINLINE_HINT int32 Min3Index( const T A, const T B, const T C )
572 {
573 return ( A < B ) ? ( ( A < C ) ? 0 : 2 ) : ( ( B < C ) ? 1 : 2 );
574 }
575
577 template< class T >
578 [[nodiscard]] static constexpr UE_FORCEINLINE_HINT T Square( const T A )
579 {
580 return A*A;
581 }
582
584 template< class T >
585 [[nodiscard]] static constexpr UE_FORCEINLINE_HINT T Cube( const T A )
586 {
587 return A*A*A;
588 }
589
591 template< class T >
592 [[nodiscard]] static constexpr UE_FORCEINLINE_HINT T Clamp(const T X, const T MinValue, const T MaxValue)
593 {
594 return Max(Min(X, MaxValue), MinValue);
595 }
598
600 [[nodiscard]] static constexpr UE_FORCEINLINE_HINT float Clamp(const float X, const float Min, const float Max) { return Clamp<float>(X, Min, Max); }
601 [[nodiscard]] static constexpr UE_FORCEINLINE_HINT double Clamp(const double X, const double Min, const double Max) { return Clamp<double>(X, Min, Max); }
602
604 [[nodiscard]] static constexpr UE_FORCEINLINE_HINT int64 Clamp(const int64 X, const int32 Min, const int32 Max) { return Clamp<int64>(X, Min, Max); }
605
606public:
609 template <UE::CFloatingPoint T>
610 [[nodiscard]] static constexpr UE_FORCEINLINE_HINT T Wrap(const T X, const T Min, const T Max)
611 {
612 // Our asserts are not constexpr-friendly yet
613 // checkSlow(Min <= Max);
614
615 T Size = Max - Min;
616 if (Size == 0)
617 {
618 // Guard against zero-sized ranges causing division by zero.
619 return Max;
620 }
621
622 T EndVal = X;
623 if (EndVal < Min)
624 {
626 EndVal = (Mod != (T)0) ? Max - Mod : Min;
627 }
628 else if (EndVal > Max)
629 {
631 EndVal = (Mod != (T)0) ? Min + Mod : Max;
632 }
633 return EndVal;
634 }
635
637 template <UE::CIntegral T>
638 [[nodiscard]] static constexpr inline T WrapExclusive(const T X, const T Min, const T Max)
639 {
640 // Use unsigned type allow for large ranges which don't overflow on subtraction.
641 using SizeType = std::make_unsigned_t<T>;
642
643 // Our asserts are not constexpr-friendly yet
644 // checkSlow(Min <= Max);
645
646 SizeType Size = (SizeType)((SizeType)Max - (SizeType)Min);
647 if (Size == 0)
648 {
649 // Guard against zero-sized ranges causing division by zero.
650 return Max;
651 }
652
653 SizeType Mod;
654 if (X < Min)
655 {
656 Mod = (SizeType)FMath::Modulo((SizeType)((SizeType)Min - (SizeType)X), Size);
657 if (Mod > 0)
658 {
659 Mod = (SizeType)(Size - Mod);
660 }
661 }
662 else
663 {
664 Mod = (SizeType)FMath::Modulo((SizeType)((SizeType)X - (SizeType)Min), Size);
665 }
666
667 return (T)(Min + Mod);
668 }
669
670 template <typename ValueType, typename BaseType>
671 [[nodiscard]] static constexpr inline auto Modulo(ValueType Value, BaseType Base)
672 {
673 if constexpr (std::is_floating_point_v<ValueType>)
674 {
675 return FMath::Fmod(Value, Base);
676 }
677 else
678 {
679 return Value % Base;
680 }
681 }
682
684 template< class T >
685 [[nodiscard]] static constexpr UE_FORCEINLINE_HINT T GridSnap(T Location, T Grid)
686 {
687 return (Grid == T{}) ? Location : (Floor((Location + (Grid/(T)2)) / Grid) * Grid);
688 }
691
693 template <class T>
694 [[nodiscard]] static constexpr UE_FORCEINLINE_HINT T DivideAndRoundUp(T Dividend, T Divisor)
695 {
696 return (Dividend + Divisor - 1) / Divisor;
697 }
698
700 template <class T>
701 [[nodiscard]] static constexpr UE_FORCEINLINE_HINT T DivideAndRoundDown(T Dividend, T Divisor)
702 {
703 return Dividend / Divisor;
704 }
705
707 template <class T>
708 [[nodiscard]] static constexpr inline T DivideAndRoundNearest(T Dividend, T Divisor)
709 {
710 return (Dividend >= 0)
711 ? (Dividend + Divisor / 2) / Divisor
712 : (Dividend - Divisor / 2 + 1) / Divisor;
713 }
714
722 [[nodiscard]] static inline float Log2(float Value)
723 {
724 // Cached value for fast conversions
725 constexpr float LogToLog2 = 1.44269502f; // 1.f / Loge(2.f)
726 // Do the platform specific log and convert using the cached value
727 return Loge(Value) * LogToLog2;
728 }
729
737 [[nodiscard]] static inline double Log2(double Value)
738 {
739 // Cached value for fast conversions
740 constexpr double LogToLog2 = 1.4426950408889634; // 1.0 / Loge(2.0);
741 // Do the platform specific log and convert using the cached value
742 return Loge(Value) * LogToLog2;
743 }
744
752 template <UE::CFloatingPoint T>
753 static constexpr inline void SinCos(std::decay_t<T>* ScalarSin, std::decay_t<T>* ScalarCos, T Value )
754 {
755 // Map Value to y in [-pi,pi], x = 2*pi*quotient + remainder.
756 T quotient = (UE_INV_PI*0.5f)*Value;
757 if (Value >= 0.0f)
758 {
759 quotient = (T)((int64)(quotient + 0.5f));
760 }
761 else
762 {
763 quotient = (T)((int64)(quotient - 0.5f));
764 }
765 T y = Value - UE_TWO_PI * quotient;
766
767 // Map y to [-pi/2,pi/2] with sin(y) = sin(Value).
768 T sign;
769 if (y > UE_HALF_PI)
770 {
771 y = UE_PI - y;
772 sign = -1.0f;
773 }
774 else if (y < -UE_HALF_PI)
775 {
776 y = -UE_PI - y;
777 sign = -1.0f;
778 }
779 else
780 {
781 sign = +1.0f;
782 }
783
784 T y2 = y * y;
785
786 // 11-degree minimax approximation
787 *ScalarSin = ( ( ( ( (-2.3889859e-08f * y2 + 2.7525562e-06f) * y2 - 0.00019840874f ) * y2 + 0.0083333310f ) * y2 - 0.16666667f ) * y2 + 1.0f ) * y;
788
789 // 10-degree minimax approximation
790 T p = ( ( ( ( -2.6051615e-07f * y2 + 2.4760495e-05f ) * y2 - 0.0013888378f ) * y2 + 0.041666638f ) * y2 - 0.5f ) * y2 + 1.0f;
791 *ScalarCos = sign*p;
792 }
793
794 static inline void SinCos(double* ScalarSin, double* ScalarCos, double Value)
795 {
796 // No approximations for doubles
797 *ScalarSin = FMath::Sin(Value);
798 *ScalarCos = FMath::Cos(Value);
799 }
800
801 template <
802 typename T,
803 typename U
804 UE_REQUIRES(!std::is_same_v<T, U>)
805 >
807 {
809 }
810
811
812 // Note: We use FASTASIN_HALF_PI instead of HALF_PI inside of FastASin(), since it was the value that accompanied the minimax coefficients below.
813 // It is important to use exactly the same value in all places inside this function to ensure that FastASin(0.0f) == 0.0f.
814 // For comparison:
815 // HALF_PI == 1.57079632679f == 0x3fC90FDB
816 // FASTASIN_HALF_PI == 1.5707963050f == 0x3fC90FDA
817#define FASTASIN_HALF_PI (1.5707963050f)
824 [[nodiscard]] static inline float FastAsin(float Value)
825 {
826 // Clamp input to [-1,1].
827 const bool nonnegative = (Value >= 0.0f);
828 const float x = FMath::Abs(Value);
829 float omx = 1.0f - x;
830 if (omx < 0.0f)
831 {
832 omx = 0.0f;
833 }
834 const float root = FMath::Sqrt(omx);
835 // 7-degree minimax approximation
836 float result = ((((((-0.0012624911f * x + 0.0066700901f) * x - 0.0170881256f) * x + 0.0308918810f) * x - 0.0501743046f) * x + 0.0889789874f) * x - 0.2145988016f) * x + FASTASIN_HALF_PI;
837 result *= root; // acos(|x|)
838 // acos(x) = pi - acos(-x) when x < 0, asin(x) = pi/2 - acos(x)
839 return (nonnegative ? FASTASIN_HALF_PI - result : result - FASTASIN_HALF_PI);
840 }
841#undef FASTASIN_HALF_PI
842
843 [[nodiscard]] static UE_FORCEINLINE_HINT double FastAsin(double Value)
844 {
845 // TODO: add fast approximation
846 return FMath::Asin(Value);
847 }
848
849 // Conversion Functions
850
856 template<class T>
857 [[nodiscard]] static constexpr UE_FORCEINLINE_HINT auto RadiansToDegrees(T const& RadVal) -> decltype(RadVal * (180.f / UE_PI))
858 {
859 return RadVal * (180.f / UE_PI);
860 }
861
862 static constexpr UE_FORCEINLINE_HINT float RadiansToDegrees(float const& RadVal) { return RadVal * (180.f / UE_PI); }
863 static constexpr UE_FORCEINLINE_HINT double RadiansToDegrees(double const& RadVal) { return RadVal * (180.0 / UE_DOUBLE_PI); }
864
870 template<class T>
871 [[nodiscard]] static constexpr UE_FORCEINLINE_HINT auto DegreesToRadians(T const& DegVal) -> decltype(DegVal * (UE_PI / 180.f))
872 {
873 return DegVal * (UE_PI / 180.f);
874 }
875
876 static constexpr UE_FORCEINLINE_HINT float DegreesToRadians(float const& DegVal) { return DegVal * (UE_PI / 180.f); }
877 static constexpr UE_FORCEINLINE_HINT double DegreesToRadians(double const& DegVal) { return DegVal * (UE_DOUBLE_PI / 180.0); }
878
886 template<typename T>
888
890
892 template <
893 typename T,
894 typename T2
895 UE_REQUIRES(std::is_floating_point_v<T> || std::is_floating_point_v<T2>)
896 >
897 [[nodiscard]] static constexpr auto FindDeltaAngleDegrees(T A1, T2 A2) -> decltype(A1 - A2)
898 {
899 // Find the difference
900 auto Delta = A2 - A1;
901
902 using DeltaType = decltype(Delta);
903
904 // Return delta in [-180,180] range
905 return Wrap(Delta, (DeltaType)-180, (DeltaType)180);
906 }
907
909 template <
910 typename T,
911 typename T2
912 UE_REQUIRES(std::is_floating_point_v<T> || std::is_floating_point_v<T2>)
913 >
914 [[nodiscard]] static constexpr auto FindDeltaAngleRadians(T A1, T2 A2) -> decltype(A1 - A2)
915 {
916 // Find the difference
917 auto Delta = A2 - A1;
918
919 using DeltaType = decltype(Delta);
920
921 // Return delta in [-PI,PI] range
923 }
924
926 template <UE::CFloatingPoint T>
927 [[nodiscard]] static constexpr T UnwindRadians(T A)
928 {
929 while(A > UE_PI)
930 {
931 A -= UE_TWO_PI;
932 }
933
934 while(A < -UE_PI)
935 {
936 A += UE_TWO_PI;
937 }
938
939 return A;
940 }
941
943 template <UE::CFloatingPoint T>
944 [[nodiscard]] static constexpr T UnwindDegrees(T A)
945 {
946 while(A > 180.f)
947 {
948 A -= 360.f;
949 }
950
951 while(A < -180.f)
952 {
953 A += 360.f;
954 }
955
956 return A;
957 }
958
965 static CORE_API void WindRelativeAnglesDegrees(float InAngle0, float& InOutAngle1);
966 static CORE_API void WindRelativeAnglesDegrees(double InAngle0, double& InOutAngle1);
967
976 [[nodiscard]] static CORE_API float FixedTurn(float InCurrent, float InDesired, float InDeltaRate);
977
979 template<typename T>
980 static inline void CartesianToPolar(const T X, const T Y, T& OutRad, T& OutAng)
981 {
982 OutRad = Sqrt(Square(X) + Square(Y));
983 OutAng = Atan2(Y, X);
984 }
986 template<typename T>
991
993 template<typename T>
994 static inline void PolarToCartesian(const T Rad, const T Ang, T& OutX, T& OutY)
995 {
996 OutX = Rad * Cos(Ang);
997 OutY = Rad * Sin(Ang);
998 }
1000 template<typename T>
1005
1024 static CORE_API bool GetDotDistance(FVector2D &OutDotDist, const FVector &Direction, const FVector &AxisX, const FVector &AxisY, const FVector &AxisZ);
1025
1041 [[nodiscard]] static CORE_API FVector2D GetAzimuthAndElevation(const FVector &Direction, const FVector &AxisX, const FVector &AxisY, const FVector &AxisZ);
1042
1043 // Interpolation Functions
1044
1046 template <UE::CFloatingPoint T, typename T2>
1047 [[nodiscard]] static constexpr inline auto GetRangePct(T MinValue, T MaxValue, T2 Value)
1048 {
1049 // Avoid Divide by Zero.
1050 // But also if our range is a point, output whether Value is before or after.
1051 const T Divisor = MaxValue - MinValue;
1052 if (FMath::IsNearlyZero(Divisor))
1053 {
1054 using RetType = decltype(T() / T2());
1055 return (Value >= MaxValue) ? (RetType)1 : (RetType)0;
1056 }
1057
1058 return (Value - MinValue) / Divisor;
1059 }
1060
1062 template <UE::CFloatingPoint T, typename T2>
1063 [[nodiscard]] static auto GetRangePct(UE::Math::TVector2<T> const& Range, T2 Value)
1064 {
1065 return GetRangePct(Range.X, Range.Y, Value);
1066 }
1067
1069 template <UE::CFloatingPoint T, typename T2>
1070 [[nodiscard]] static auto GetRangeValue(UE::Math::TVector2<T> const& Range, T2 Pct)
1071 {
1072 return Lerp(Range.X, Range.Y, Pct);
1073 }
1074
1076 template<typename T, typename T2>
1078 {
1079 using RangePctType = decltype(T() * T2());
1082 }
1083
1085 template<typename T, typename T2>
1090
1091 template<class T>
1092 [[nodiscard]] static UE_FORCEINLINE_HINT double GetRangePct(TRange<T> const& Range, T Value)
1093 {
1094 return GetRangePct(Range.GetLowerBoundValue(), Range.GetUpperBoundValue(), Value);
1095 }
1096
1097 template<class T>
1099 {
1100 return FMath::Lerp<T>(Range.GetLowerBoundValue(), Range.GetUpperBoundValue(), Pct);
1101 }
1102
1103 template<class T>
1105 {
1106 const T ClampedPct = FMath::Clamp<T>(GetRangePct(InputRange, Value), 0, 1);
1108 }
1109
1111 template <
1112 typename T,
1113 typename U
1114 UE_REQUIRES(!TCustomLerp<T>::Value && (std::is_floating_point_v<U> || std::is_same_v<T, U>) && !std::is_same_v<T, bool>)
1115 >
1116 [[nodiscard]] static constexpr UE_FORCEINLINE_HINT T Lerp( const T& A, const T& B, const U& Alpha )
1117 {
1118 return (T)(A + Alpha * (B-A));
1119 }
1120
1122 template <
1123 typename T,
1124 typename U
1126 >
1127 [[nodiscard]] static UE_FORCEINLINE_HINT T Lerp(const T& A, const T& B, const U& Alpha)
1128 {
1129 return TCustomLerp<T>::Lerp(A, B, Alpha);
1130 }
1131
1132 // Allow passing of differing A/B types.
1133 template <
1134 typename T1,
1135 typename T2,
1136 typename T3
1137 UE_REQUIRES(!std::is_same_v<T1, T2> && !TCustomLerp<T1>::Value && !TCustomLerp<T2>::Value)
1138 >
1139 [[nodiscard]] static auto Lerp( const T1& A, const T2& B, const T3& Alpha ) -> decltype(A * B)
1140 {
1141 using ABType = decltype(A * B);
1142 return Lerp(ABType(A), ABType(B), Alpha);
1143 }
1144
1146 template< class T >
1147 [[nodiscard]] static constexpr UE_FORCEINLINE_HINT T LerpStable( const T& A, const T& B, double Alpha )
1148 {
1149 return (T)((A * (1.0 - Alpha)) + (B * Alpha));
1150 }
1151
1153 template< class T >
1154 [[nodiscard]] static constexpr UE_FORCEINLINE_HINT T LerpStable(const T& A, const T& B, float Alpha)
1155 {
1156 return (T)((A * (1.0f - Alpha)) + (B * Alpha));
1157 }
1158
1159 // Allow passing of differing A/B types.
1160 template <
1161 typename T1,
1162 typename T2,
1163 typename T3
1164 UE_REQUIRES(!std::is_same_v<T1, T2>)
1165 >
1166 [[nodiscard]] static auto LerpStable( const T1& A, const T2& B, const T3& Alpha ) -> decltype(A * B)
1167 {
1168 using ABType = decltype(A * B);
1169 return LerpStable(ABType(A), ABType(B), Alpha);
1170 }
1171
1173 template <
1174 typename T,
1175 typename U
1176 UE_REQUIRES(!TCustomLerp<T>::Value && (std::is_floating_point_v<U> || std::is_same_v<T, U>))
1177 >
1178 [[nodiscard]] static constexpr inline T BiLerp(const T& P00,const T& P10,const T& P01,const T& P11, const U& FracX, const U& FracY)
1179 {
1180 return Lerp(
1181 Lerp(P00,P10,FracX),
1182 Lerp(P01,P11,FracX),
1183 FracY
1184 );
1185 }
1186
1188 template <
1189 typename T,
1190 typename U
1192 >
1193 [[nodiscard]] static UE_FORCEINLINE_HINT T BiLerp(const T& P00, const T& P10, const T& P01, const T& P11, const U& FracX, const U& FracY)
1194 {
1196 }
1197
1207 template <
1208 typename T,
1209 typename U
1210 UE_REQUIRES(!TCustomLerp<T>::Value && (std::is_floating_point_v<U> || std::is_same_v<T, U>))
1211 >
1212 [[nodiscard]] static constexpr inline T CubicInterp( const T& P0, const T& T0, const T& P1, const T& T1, const U& A )
1213 {
1214 const U A2 = A * A;
1215 const U A3 = A2 * A;
1216
1217 return T((((2*A3)-(3*A2)+1) * P0) + ((A3-(2*A2)+A) * T0) + ((A3-A2) * T1) + (((-2*A3)+(3*A2)) * P1));
1218 }
1219
1221 template <
1222 typename T,
1223 typename U
1225 >
1226 [[nodiscard]] static UE_FORCEINLINE_HINT T CubicInterp(const T& P0, const T& T0, const T& P1, const T& T1, const U& A)
1227 {
1228 return TCustomLerp<T>::CubicInterp(P0, T0, P1, T1, A);
1229 }
1230
1240 template <typename T, UE::CFloatingPoint U>
1241 [[nodiscard]] static constexpr inline T CubicInterpDerivative( const T& P0, const T& T0, const T& P1, const T& T1, const U& A )
1242 {
1243 T a = 6.f*P0 + 3.f*T0 + 3.f*T1 - 6.f*P1;
1244 T b = -6.f*P0 - 4.f*T0 - 2.f*T1 + 6.f*P1;
1245 T c = T0;
1246
1247 const U A2 = A * A;
1248
1249 return T((a * A2) + (b * A) + c);
1250 }
1251
1261 template <typename T, UE::CFloatingPoint U>
1262 [[nodiscard]] static constexpr inline T CubicInterpSecondDerivative( const T& P0, const T& T0, const T& P1, const T& T1, const U& A )
1263 {
1264 T a = 12.f*P0 + 6.f*T0 + 6.f*T1 - 12.f*P1;
1265 T b = -6.f*P0 - 4.f*T0 - 2.f*T1 + 6.f*P1;
1266
1267 return (a * A) + b;
1268 }
1269
1271 template< class T >
1272 [[nodiscard]] static inline T InterpEaseIn(const T& A, const T& B, float Alpha, float Exp)
1273 {
1274 float const ModifiedAlpha = Pow(Alpha, Exp);
1275 return Lerp<T>(A, B, ModifiedAlpha);
1276 }
1277
1279 template< class T >
1280 [[nodiscard]] static inline T InterpEaseOut(const T& A, const T& B, float Alpha, float Exp)
1281 {
1282 float const ModifiedAlpha = 1.f - Pow(1.f - Alpha, Exp);
1283 return Lerp<T>(A, B, ModifiedAlpha);
1284 }
1285
1287 template< class T >
1288 [[nodiscard]] static inline T InterpEaseInOut( const T& A, const T& B, float Alpha, float Exp )
1289 {
1290 return Lerp<T>(A, B, (Alpha < 0.5f) ?
1291 InterpEaseIn(0.f, 1.f, Alpha * 2.f, Exp) * 0.5f :
1292 InterpEaseOut(0.f, 1.f, Alpha * 2.f - 1.f, Exp) * 0.5f + 0.5f);
1293 }
1294
1296 template< class T >
1297 [[nodiscard]] static constexpr inline T InterpStep(const T& A, const T& B, float Alpha, int32 Steps)
1298 {
1299 if (Steps <= 1 || Alpha <= 0)
1300 {
1301 return A;
1302 }
1303 else if (Alpha >= 1)
1304 {
1305 return B;
1306 }
1307
1308 const float StepsAsFloat = static_cast<float>(Steps);
1309 const float NumIntervals = StepsAsFloat - 1.f;
1310 float const ModifiedAlpha = FloorToFloat(Alpha * StepsAsFloat) / NumIntervals;
1311 return Lerp<T>(A, B, ModifiedAlpha);
1312 }
1313
1315 template< class T >
1316 [[nodiscard]] static inline T InterpSinIn(const T& A, const T& B, float Alpha)
1317 {
1318 float const ModifiedAlpha = -1.f * Cos(Alpha * UE_HALF_PI) + 1.f;
1319 return Lerp<T>(A, B, ModifiedAlpha);
1320 }
1321
1323 template< class T >
1324 [[nodiscard]] static inline T InterpSinOut(const T& A, const T& B, float Alpha)
1325 {
1326 float const ModifiedAlpha = Sin(Alpha * UE_HALF_PI);
1327 return Lerp<T>(A, B, ModifiedAlpha);
1328 }
1329
1331 template< class T >
1332 [[nodiscard]] static inline T InterpSinInOut(const T& A, const T& B, float Alpha)
1333 {
1334 return Lerp<T>(A, B, (Alpha < 0.5f) ?
1335 InterpSinIn(0.f, 1.f, Alpha * 2.f) * 0.5f :
1336 InterpSinOut(0.f, 1.f, Alpha * 2.f - 1.f) * 0.5f + 0.5f);
1337 }
1338
1340 template< class T >
1341 [[nodiscard]] static inline T InterpExpoIn(const T& A, const T& B, float Alpha)
1342 {
1343 float const ModifiedAlpha = (Alpha == 0.f) ? 0.f : Pow(2.f, 10.f * (Alpha - 1.f));
1344 return Lerp<T>(A, B, ModifiedAlpha);
1345 }
1346
1348 template< class T >
1349 [[nodiscard]] static inline T InterpExpoOut(const T& A, const T& B, float Alpha)
1350 {
1351 float const ModifiedAlpha = (Alpha == 1.f) ? 1.f : -Pow(2.f, -10.f * Alpha) + 1.f;
1352 return Lerp<T>(A, B, ModifiedAlpha);
1353 }
1354
1356 template< class T >
1357 [[nodiscard]] static inline T InterpExpoInOut(const T& A, const T& B, float Alpha)
1358 {
1359 return Lerp<T>(A, B, (Alpha < 0.5f) ?
1360 InterpExpoIn(0.f, 1.f, Alpha * 2.f) * 0.5f :
1361 InterpExpoOut(0.f, 1.f, Alpha * 2.f - 1.f) * 0.5f + 0.5f);
1362 }
1363
1365 template< class T >
1366 [[nodiscard]] static inline T InterpCircularIn(const T& A, const T& B, float Alpha)
1367 {
1368 float const ModifiedAlpha = -1.f * (Sqrt(1.f - Alpha * Alpha) - 1.f);
1369 return Lerp<T>(A, B, ModifiedAlpha);
1370 }
1371
1373 template< class T >
1374 [[nodiscard]] static inline T InterpCircularOut(const T& A, const T& B, float Alpha)
1375 {
1376 Alpha -= 1.f;
1377 float const ModifiedAlpha = Sqrt(1.f - Alpha * Alpha);
1378 return Lerp<T>(A, B, ModifiedAlpha);
1379 }
1380
1382 template< class T >
1383 [[nodiscard]] static inline T InterpCircularInOut(const T& A, const T& B, float Alpha)
1384 {
1385 return Lerp<T>(A, B, (Alpha < 0.5f) ?
1386 InterpCircularIn(0.f, 1.f, Alpha * 2.f) * 0.5f :
1387 InterpCircularOut(0.f, 1.f, Alpha * 2.f - 1.f) * 0.5f + 0.5f);
1388 }
1389
1390 // Rotator specific interpolation
1391 // Similar to Lerp, but does not take the shortest path. Allows interpolation over more than 180 degrees.
1392 template< typename T, typename U >
1394
1395 /*
1396 * Cubic Catmull-Rom Spline interpolation. Based on http://www.cemyuksel.com/research/catmullrom_param/catmullrom.pdf
1397 * Curves are guaranteed to pass through the control points and are easily chained together.
1398 * Equation supports abitrary parameterization. eg. Uniform=0,1,2,3 ; chordal= |Pn - Pn-1| ; centripetal = |Pn - Pn-1|^0.5
1399 * P0 - The control point preceding the interpolation range.
1400 * P1 - The control point starting the interpolation range.
1401 * P2 - The control point ending the interpolation range.
1402 * P3 - The control point following the interpolation range.
1403 * T0-3 - The interpolation parameters for the corresponding control points.
1404 * T - The interpolation factor in the range 0 to 1. 0 returns P1. 1 returns P2.
1405 */
1406 template< class U >
1407 [[nodiscard]] static constexpr inline U CubicCRSplineInterp(const U& P0, const U& P1, const U& P2, const U& P3, const float T0, const float T1, const float T2, const float T3, const float T)
1408 {
1409 //Based on http://www.cemyuksel.com/research/catmullrom_param/catmullrom.pdf
1410 float InvT1MinusT0 = 1.0f / (T1 - T0);
1411 U L01 = ( P0 * ((T1 - T) * InvT1MinusT0) ) + ( P1 * ((T - T0) * InvT1MinusT0) );
1412 float InvT2MinusT1 = 1.0f / (T2 - T1);
1413 U L12 = ( P1 * ((T2 - T) * InvT2MinusT1) ) + ( P2 * ((T - T1) * InvT2MinusT1) );
1414 float InvT3MinusT2 = 1.0f / (T3 - T2);
1415 U L23 = ( P2 * ((T3 - T) * InvT3MinusT2) ) + ( P3 * ((T - T2) * InvT3MinusT2) );
1416
1417 float InvT2MinusT0 = 1.0f / (T2 - T0);
1418 U L012 = ( L01 * ((T2 - T) * InvT2MinusT0) ) + ( L12 * ((T - T0) * InvT2MinusT0) );
1419 float InvT3MinusT1 = 1.0f / (T3 - T1);
1420 U L123 = ( L12 * ((T3 - T) * InvT3MinusT1) ) + ( L23 * ((T - T1) * InvT3MinusT1) );
1421
1422 return ( ( L012 * ((T2 - T) * InvT2MinusT1) ) + ( L123 * ((T - T1) * InvT2MinusT1) ) );
1423 }
1424
1425 /* Same as CubicCRSplineInterp but with additional saftey checks. If the checks fail P1 is returned. **/
1426 template< class U >
1427 [[nodiscard]] static constexpr inline U CubicCRSplineInterpSafe(const U& P0, const U& P1, const U& P2, const U& P3, const float T0, const float T1, const float T2, const float T3, const float T)
1428 {
1429 //Based on http://www.cemyuksel.com/research/catmullrom_param/catmullrom.pdf
1430 float T1MinusT0 = (T1 - T0);
1431 float T2MinusT1 = (T2 - T1);
1432 float T3MinusT2 = (T3 - T2);
1433 float T2MinusT0 = (T2 - T0);
1434 float T3MinusT1 = (T3 - T1);
1436 {
1437 //There's going to be a divide by zero here so just bail out and return P1
1438 return P1;
1439 }
1440
1441 float InvT1MinusT0 = 1.0f / T1MinusT0;
1442 U L01 = (P0 * ((T1 - T) * InvT1MinusT0)) + (P1 * ((T - T0) * InvT1MinusT0));
1443 float InvT2MinusT1 = 1.0f / T2MinusT1;
1444 U L12 = (P1 * ((T2 - T) * InvT2MinusT1)) + (P2 * ((T - T1) * InvT2MinusT1));
1445 float InvT3MinusT2 = 1.0f / T3MinusT2;
1446 U L23 = (P2 * ((T3 - T) * InvT3MinusT2)) + (P3 * ((T - T2) * InvT3MinusT2));
1447
1448 float InvT2MinusT0 = 1.0f / T2MinusT0;
1449 U L012 = (L01 * ((T2 - T) * InvT2MinusT0)) + (L12 * ((T - T0) * InvT2MinusT0));
1450 float InvT3MinusT1 = 1.0f / T3MinusT1;
1451 U L123 = (L12 * ((T3 - T) * InvT3MinusT1)) + (L23 * ((T - T1) * InvT3MinusT1));
1452
1453 return ((L012 * ((T2 - T) * InvT2MinusT1)) + (L123 * ((T - T1) * InvT2MinusT1)));
1454 }
1455
1456
1457 // Special-case interpolation
1458
1460 [[nodiscard]] static CORE_API FVector VInterpNormalRotationTo(const FVector& Current, const FVector& Target, float DeltaTime, float RotationSpeedDegrees);
1461
1463 [[nodiscard]] static CORE_API FVector VInterpConstantTo(const FVector& Current, const FVector& Target, float DeltaTime, float InterpSpeed);
1464
1466 [[nodiscard]] static CORE_API FVector VInterpTo( const FVector& Current, const FVector& Target, float DeltaTime, float InterpSpeed );
1467
1469 [[nodiscard]] static CORE_API FVector2D Vector2DInterpConstantTo( const FVector2D& Current, const FVector2D& Target, float DeltaTime, float InterpSpeed );
1470
1472 template <typename T>
1473 [[nodiscard]] static CORE_API UE::Math::TVector2<T> Vector2DInterpTo( const UE::Math::TVector2<T>& Current, const UE::Math::TVector2<T>& Target, float DeltaTime, float InterpSpeed );
1474
1476 [[nodiscard]] static CORE_API FRotator RInterpConstantTo( const FRotator& Current, const FRotator& Target, float DeltaTime, float InterpSpeed);
1477
1479 [[nodiscard]] static CORE_API FRotator RInterpTo( const FRotator& Current, const FRotator& Target, float DeltaTime, float InterpSpeed);
1480
1482 template<typename T1, typename T2 = T1, typename T3 = T2, typename T4 = T3>
1483 [[nodiscard]] static auto FInterpConstantTo( T1 Current, T2 Target, T3 DeltaTime, T4 InterpSpeed )
1484 {
1485 static_assert(!std::is_same_v<T1, bool> && !std::is_same_v<T2, bool>, "Boolean types may not be interpolated");
1486 using RetType = decltype(T1() * T2() * T3() * T4());
1487
1488 const RetType Dist = Target - Current;
1489
1490 // If distance is too small, just set the desired location
1491 if( FMath::Square(Dist) < UE_SMALL_NUMBER )
1492 {
1493 return static_cast<RetType>(Target);
1494 }
1495
1496 const RetType Step = InterpSpeed * DeltaTime;
1497 return Current + FMath::Clamp(Dist, -Step, Step);
1498 }
1499
1501 template<typename T1, typename T2 = T1, typename T3 = T2, typename T4 = T3>
1502 [[nodiscard]] static auto FInterpTo( T1 Current, T2 Target, T3 DeltaTime, T4 InterpSpeed )
1503 {
1504 static_assert(!std::is_same_v<T1, bool> && !std::is_same_v<T2, bool>, "Boolean types may not be interpolated");
1505 using RetType = decltype(T1() * T2() * T3() * T4());
1506
1507 // If no interp speed, jump to target value
1508 if( InterpSpeed <= 0.f )
1509 {
1510 return static_cast<RetType>(Target);
1511 }
1512
1513 // Distance to reach
1514 const RetType Dist = Target - Current;
1515
1516 // If distance is too small, just set the desired location
1517 if( FMath::Square(Dist) < UE_SMALL_NUMBER )
1518 {
1519 return static_cast<RetType>(Target);
1520 }
1521
1522 // Delta Move, Clamp so we do not over shoot.
1523 const RetType DeltaMove = Dist * FMath::Clamp<RetType>(DeltaTime * InterpSpeed, 0.f, 1.f);
1524
1525 return Current + DeltaMove;
1526 }
1527
1529 [[nodiscard]] static CORE_API FLinearColor CInterpTo(const FLinearColor& Current, const FLinearColor& Target, float DeltaTime, float InterpSpeed);
1530
1532 template< class T >
1533 [[nodiscard]] static CORE_API UE::Math::TQuat<T> QInterpConstantTo(const UE::Math::TQuat<T>& Current, const UE::Math::TQuat<T>& Target, float DeltaTime, float InterpSpeed);
1534
1536 template< class T >
1537 [[nodiscard]] static CORE_API UE::Math::TQuat<T> QInterpTo(const UE::Math::TQuat<T>& Current, const UE::Math::TQuat<T>& Target, float DeltaTime, float InterpSpeed);
1538
1545 template<class T>
1546 [[nodiscard]] static constexpr T InvExpApprox(T X)
1547 {
1548 constexpr T A(1.00746054f); // 1 / 1! in Taylor series
1549 constexpr T B(0.45053901f); // 1 / 2! in Taylor series
1550 constexpr T C(0.25724632f); // 1 / 3! in Taylor series
1551 return 1 / (1 + A * X + B * X * X + C * X * X * X);
1552 }
1553
1564 template< class T >
1565 static constexpr void ExponentialSmoothingApprox(
1566 T& InOutValue,
1567 const T& InTargetValue,
1568 const float InDeltaTime,
1569 const float InSmoothingTime)
1570 {
1572 {
1573 const float A = InDeltaTime / InSmoothingTime;
1574 float Exp = InvExpApprox(A);
1576 }
1577 else
1578 {
1580 }
1581 }
1582
1600 template< class T >
1601 static constexpr void CriticallyDampedSmoothing(
1602 T& InOutValue,
1603 T& InOutValueRate,
1604 const T& InTargetValue,
1605 const T& InTargetValueRate,
1606 const float InDeltaTime,
1607 const float InSmoothingTime)
1608 {
1610 {
1611 // The closed form solution for critically damped motion towards zero is:
1612 //
1613 // x = ( x0 + t (v0 + w x0) ) exp(-w t)
1614 //
1615 // where w is the natural frequency, x0, v0 are x and dx/dt at time 0 (e.g. Brian Stone - Chatter and Machine Tools pdf)
1616 //
1617 // Differentiate to get velocity (remember d(v0)/dt = 0):
1618 //
1619 // v = ( v0 - w t (v0 + w x0) ) exp(-w t)
1620 //
1621 // We're damping towards a target, so convert - i.e. x = value - target
1622 //
1623 // Target velocity turns into an offset to the position
1625
1626 const float W = 2.0f / InSmoothingTime;
1627 const float A = W * InDeltaTime;
1628 // Approximation requires A < 1, so DeltaTime < SmoothingTime / 2
1629 const float Exp = InvExpApprox(A);
1631 // Target velocity turns into an offset to the position
1633 const T B = (InOutValueRate + X0 * W) * InDeltaTime;
1634 InOutValue = AdjustedTarget + (X0 + B) * Exp;
1635 InOutValueRate = (InOutValueRate - B * W) * Exp;
1636 }
1637 else if (InDeltaTime > 0.0f)
1638 {
1641 }
1642 else
1643 {
1645 InOutValueRate = T(0);
1646 }
1647 }
1648
1664 template< class T >
1665 static void SpringDamper(
1666 T& InOutValue,
1667 T& InOutValueRate,
1668 const T& InTargetValue,
1669 const T& InTargetValueRate,
1670 const float InDeltaTime,
1671 const float InUndampedFrequency,
1672 const float InDampingRatio)
1673 {
1674 if (InDeltaTime <= 0.0f)
1675 {
1676 return;
1677 }
1678
1679 float W = InUndampedFrequency * UE_TWO_PI;
1680 // Handle special cases
1681 if (W < UE_SMALL_NUMBER) // no strength which means no damping either
1682 {
1684 return;
1685 }
1686 else if (InDampingRatio < UE_SMALL_NUMBER) // No damping at all
1687 {
1688 T Err = InOutValue - InTargetValue;
1689 const T B = InOutValueRate / W;
1690 float S, C;
1691 FMath::SinCos(&S, &C, W * InDeltaTime);
1692 InOutValue = InTargetValue + Err * C + B * S;
1693 InOutValueRate = InOutValueRate * C - Err * (W * S);
1694 return;
1695 }
1696
1697 // Target velocity turns into an offset to the position
1698 float SmoothingTime = 2.0f / W;
1700 T Err = InOutValue - AdjustedTarget;
1701
1702 // Handle the cases separately
1703 if (InDampingRatio > 1.0f) // Overdamped
1704 {
1705 const float WD = W * FMath::Sqrt(FMath::Square(InDampingRatio) - 1.0f);
1706 const T C2 = -(InOutValueRate + (W * InDampingRatio - WD) * Err) / (2.0f * WD);
1707 const T C1 = Err - C2;
1708 const float A1 = (WD - InDampingRatio * W);
1709 const float A2 = -(WD + InDampingRatio * W);
1710 // Note that A1 and A2 will always be negative. We will use an approximation for 1/Exp(-A * DeltaTime).
1711 const float A1_DT = -A1 * InDeltaTime;
1712 const float A2_DT = -A2 * InDeltaTime;
1713 // This approximation in practice will be good for all DampingRatios
1714 const float E1 = InvExpApprox(A1_DT);
1715 // As DampingRatio gets big, this approximation gets worse, but mere inaccuracy for overdamped motion is
1716 // not likely to be important, since we end up with 1 / BigNumber
1717 const float E2 = InvExpApprox(A2_DT);
1718 InOutValue = AdjustedTarget + E1 * C1 + E2 * C2;
1719 InOutValueRate = E1 * C1 * A1 + E2 * C2 * A2;
1720 }
1721 else if (InDampingRatio < 1.0f) // Underdamped
1722 {
1723 const float WD = W * FMath::Sqrt(1.0f - FMath::Square(InDampingRatio));
1724 const T A = Err;
1725 const T B = (InOutValueRate + Err * (InDampingRatio * W)) / WD;
1726 float S, C;
1728 const float E0 = InDampingRatio * W * InDeltaTime;
1729 // Needs E0 < 1 so DeltaTime < SmoothingTime / (2 * DampingRatio * Sqrt(1 - DampingRatio^2))
1730 const float E = InvExpApprox(E0);
1731 InOutValue = E * (A * C + B * S);
1733 InOutValueRate += E * (B * (WD * C) - A * (WD * S));
1735 }
1736 else // Critical damping
1737 {
1738 const T& C1 = Err;
1739 T C2 = InOutValueRate + Err * W;
1740 const float E0 = W * InDeltaTime;
1741 // Needs E0 < 1 so InDeltaTime < SmoothingTime / 2
1742 float E = InvExpApprox(E0);
1743 InOutValue = AdjustedTarget + (C1 + C2 * InDeltaTime) * E;
1744 InOutValueRate = (C2 - C1 * W - C2 * (W * InDeltaTime)) * E;
1745 }
1746 }
1747
1763 template< class T >
1765 T& InOutValue,
1766 T& InOutValueRate,
1767 const T& InTargetValue,
1768 const T& InTargetValueRate,
1769 const float InDeltaTime,
1770 const float InSmoothingTime,
1771 const float InDampingRatio)
1772 {
1774 {
1775 if (InDeltaTime <= 0.0f)
1776 {
1777 return;
1778 }
1781 return;
1782 }
1783
1784 // Undamped frequency
1785 float UndampedFrequency = 1.0f / (UE_PI * InSmoothingTime);
1787 }
1788
1798 [[nodiscard]] static float MakePulsatingValue( const double InCurrentTime, const float InPulsesPerSecond, const float InPhase = 0.0f )
1799 {
1800 return 0.5f + 0.5f * FMath::Sin( ( ( 0.25f + InPhase ) * UE_TWO_PI ) + ( (float)InCurrentTime * UE_TWO_PI ) * InPulsesPerSecond );
1801 }
1802
1803 // Geometry intersection
1804
1815 template<typename FReal>
1817
1828 template<typename FReal>
1830
1843 template<typename FReal>
1845
1857 template<typename FReal>
1859
1860
1861 // @parma InOutScissorRect should be set to View.ViewRect before the call
1862 // @return 0: light is not visible, 1:use scissor rect, 2: no scissor rect needed
1863 [[nodiscard]] static CORE_API uint32 ComputeProjectedSphereScissorRect(FIntRect& InOutScissorRect, FVector SphereOrigin, float Radius, FVector ViewOrigin, const FMatrix& ViewMatrix, const FMatrix& ProjMatrix);
1864
1865 // @param ConeOrigin Cone origin
1866 // @param ConeDirection Cone direction
1867 // @param ConeRadius Cone Radius
1868 // @param CosConeAngle Cos of the cone angle
1869 // @param SinConeAngle Sin of the cone angle
1870 // @return Minimal bounding sphere encompassing given cone
1871 template<typename FReal>
1873
1880 [[nodiscard]] static CORE_API bool PlaneAABBIntersection(const FPlane& P, const FBox& AABB);
1881
1889 [[nodiscard]] static CORE_API int32 PlaneAABBRelativePosition(const FPlane& P, const FBox& AABB);
1890
1904 template<typename FReal>
1906
1910 template<typename FReal>
1912
1914 template<typename FReal>
1916
1918 template<typename FReal>
1920
1922 template<typename FReal>
1924
1926 template<typename FReal>
1928
1929 /* Swept-Box vs Box test */
1930 static CORE_API bool LineExtentBoxIntersection(const FBox& inBox, const FVector& Start, const FVector& End, const FVector& Extent, FVector& HitLocation, FVector& HitNormal, float& HitTime);
1931
1933 template<typename FReal>
1934 [[nodiscard]] static bool LineSphereIntersection(const UE::Math::TVector<FReal>& Start,const UE::Math::TVector<FReal>& Dir, FReal Length,const UE::Math::TVector<FReal>& Origin, FReal Radius);
1935
1940 [[nodiscard]] static CORE_API bool SphereConeIntersection(const FVector& SphereCenter, float SphereRadius, const FVector& ConeAxis, float ConeAngleSin, float ConeAngleCos);
1941
1943 template<typename T>
1945
1947 [[nodiscard]] static CORE_API FVector ClosestPointOnInfiniteLine(const FVector& LineStart, const FVector& LineEnd, const FVector& Point);
1948
1950 template<typename FReal>
1952
1957 template<typename FReal>
1959
1971 static CORE_API float PointDistToLine(const FVector &Point, const FVector &Direction, const FVector &Origin, FVector &OutClosestPoint);
1972 [[nodiscard]] static CORE_API float PointDistToLine(const FVector &Point, const FVector &Direction, const FVector &Origin);
1973
1985 template <typename T>
1987
2000 template <typename T>
2002
2012 [[nodiscard]] static CORE_API float PointDistToSegment(const FVector &Point, const FVector &StartPoint, const FVector &EndPoint);
2013
2023 [[nodiscard]] static CORE_API float PointDistToSegmentSquared(const FVector &Point, const FVector &StartPoint, const FVector &EndPoint);
2024
2036
2048 template<typename T>
2050
2058 [[nodiscard]] static CORE_API float GetTForSegmentPlaneIntersect(const FVector& StartPoint, const FVector& EndPoint, const FPlane& Plane);
2059
2069 static CORE_API bool SegmentPlaneIntersection(const FVector& StartPoint, const FVector& EndPoint, const FPlane& Plane, FVector& out_IntersectionPoint);
2070
2071
2082 static CORE_API bool SegmentTriangleIntersection(const FVector& StartPoint, const FVector& EndPoint, const FVector& A, const FVector& B, const FVector& C, FVector& OutIntersectPoint, FVector& OutTriangleNormal);
2083
2095
2096
2107 [[nodiscard]] static CORE_API FVector ClosestPointOnTriangleToPoint(const FVector& Point, const FVector& A, const FVector& B, const FVector& C);
2108
2119 [[nodiscard]] static CORE_API FVector ClosestPointOnTetrahedronToPoint(const FVector& Point, const FVector& A, const FVector& B, const FVector& C, const FVector& D);
2120
2131
2145
2154 [[nodiscard]] static CORE_API bool PointsAreCoplanar(const TArray<FVector>& Points, const float Tolerance = 0.1f);
2155
2162 [[nodiscard]] static CORE_API float TruncateToHalfIfClose(float F, float Tolerance = UE_SMALL_NUMBER);
2163 [[nodiscard]] static CORE_API double TruncateToHalfIfClose(double F, double Tolerance = UE_SMALL_NUMBER);
2164
2170 [[nodiscard]] static CORE_API float RoundHalfToEven(float F);
2171 [[nodiscard]] static CORE_API double RoundHalfToEven(double F);
2172
2178 [[nodiscard]] static CORE_API float RoundHalfFromZero(float F);
2179 [[nodiscard]] static CORE_API double RoundHalfFromZero(double F);
2180
2186 [[nodiscard]] static CORE_API float RoundHalfToZero(float F);
2187 [[nodiscard]] static CORE_API double RoundHalfToZero(double F);
2188
2195 {
2196 return (F < 0.0f) ? FloorToFloat(F) : CeilToFloat(F);
2197 }
2198
2200 {
2201 return (F < 0.0) ? FloorToDouble(F) : CeilToDouble(F);
2202 }
2203
2210 {
2211 return (F < 0.0f) ? CeilToFloat(F) : FloorToFloat(F);
2212 }
2213
2214 [[nodiscard]] static UE_FORCEINLINE_HINT double RoundToZero(double F)
2215 {
2216 return (F < 0.0) ? CeilToDouble(F) : FloorToDouble(F);
2217 }
2218
2225 {
2226 return FloorToFloat(F);
2227 }
2228
2230 {
2231 return FloorToDouble(F);
2232 }
2233
2240 {
2241 return CeilToFloat(F);
2242 }
2243
2245 {
2246 return CeilToDouble(F);
2247 }
2248
2249
2250 // Formatting functions
2251
2259
2260
2261 // Utilities
2262
2270 [[nodiscard]] static CORE_API bool MemoryTest( void* BaseAddress, uint32 NumBytes );
2271
2284 static CORE_API bool Eval( FString Str, float& OutValue );
2285
2295 [[nodiscard]] static CORE_API FVector GetBaryCentric2D(const FVector& Point, const FVector& A, const FVector& B, const FVector& C);
2296
2306 [[nodiscard]] static CORE_API FVector GetBaryCentric2D(const FVector2D& Point, const FVector2D& A, const FVector2D& B, const FVector2D& C);
2307
2318 [[nodiscard]] static CORE_API FVector ComputeBaryCentric2D(const FVector& Point, const FVector& A, const FVector& B, const FVector& C);
2319
2331 [[nodiscard]] static CORE_API bool ComputeBarycentricTri(const FVector& Point, const FVector& A, const FVector& B, const FVector& C, FVector& OutBarycentric, double Tolerance = UE_DOUBLE_SMALL_NUMBER);
2332
2341 [[nodiscard]] static CORE_API FVector4 ComputeBaryCentric3D(const FVector& Point, const FVector& A, const FVector& B, const FVector& C, const FVector& D);
2342
2344 static CORE_API const uint32 BitFlag[32];
2345
2356 template<typename T>
2357 [[nodiscard]] static constexpr T SmoothStep(T A, T B, T X)
2358 {
2359 if (X < A)
2360 {
2361 return 0;
2362 }
2363 else if (X >= B)
2364 {
2365 return 1;
2366 }
2367 const T InterpFraction = (X - A) / (B - A);
2368 return InterpFraction * InterpFraction * (3.0f - 2.0f * InterpFraction);
2369 }
2370
2375 [[nodiscard]] static constexpr bool ExtractBoolFromBitfield(const uint8* Ptr, uint32 Index)
2376 {
2377 const uint8* BytePtr = Ptr + Index / 8;
2378 uint8 Mask = (uint8)(1 << (Index & 0x7));
2379
2380 return (*BytePtr & Mask) != 0;
2381 }
2382
2387 static constexpr void SetBoolInBitField(uint8* Ptr, uint32 Index, bool bSet)
2388 {
2389 uint8* BytePtr = Ptr + Index / 8;
2390 uint8 Mask = (uint8)(1 << (Index & 0x7));
2391
2392 if(bSet)
2393 {
2394 *BytePtr |= Mask;
2395 }
2396 else
2397 {
2398 *BytePtr &= ~Mask;
2399 }
2400 }
2401
2406 static CORE_API void ApplyScaleToFloat(float& Dst, const FVector& DeltaScale, float Magnitude = 1.0f);
2407
2408 // @param x assumed to be in this range: 0..1
2409 // @return 0..255
2411 {
2412 // 0..1 -> 0..255
2413 int32 Ret = (int32)(x * 255.f + 0.5f);
2414
2415 check(Ret >= 0);
2416 check(Ret <= 255);
2417
2418 return (uint8)Ret;
2419 }
2420
2421 // @param x assumed to be in this range: -1..1
2422 // @return 0..255
2424 {
2425 // -1..1 -> 0..1
2426 float y = x * 0.5f + 0.5f;
2427
2428 return Quantize8UnsignedByte(y);
2429 }
2430
2431 // Use the Euclidean method to find the GCD
2433 {
2434 while (b != 0)
2435 {
2436 int32 t = b;
2437 b = a % b;
2438 a = t;
2439 }
2440 return a;
2441 }
2442
2443 // LCM = a/gcd * b
2444 // a and b are the number we want to find the lcm
2446 {
2448 return CurrentGcd == 0 ? 0 : (a / CurrentGcd) * b;
2449 }
2450
2458 [[nodiscard]] static CORE_API float PerlinNoise1D(float Value);
2459
2467 [[nodiscard]] static CORE_API float PerlinNoise2D(const FVector2D& Location);
2468
2469
2477 [[nodiscard]] static CORE_API float PerlinNoise3D(const FVector& Location);
2478
2488 template<typename T>
2489 [[nodiscard]] static inline T WeightedMovingAverage(T CurrentSample, T PreviousSample, T Weight)
2490 {
2491 Weight = Clamp<T>(Weight, 0.f, 1.f);
2492 T WAvg = (CurrentSample * Weight) + (PreviousSample * (1.f - Weight));
2493 return WAvg;
2494 }
2495
2509 template<typename T>
2510 [[nodiscard]] static inline T DynamicWeightedMovingAverage(T CurrentSample, T PreviousSample, T MaxDistance, T MinWeight, T MaxWeight)
2511 {
2512 // We need the distance between samples to determine how much of each weight to use
2513 const T Distance = Abs<T>(CurrentSample - PreviousSample);
2514 T Weight = MinWeight;
2515 if (MaxDistance > 0)
2516 {
2517 // Figure out the lerp value to use between the min/max weights
2518 const T LerpAlpha = Clamp<T>(Distance / MaxDistance, 0.f, 1.f);
2520 }
2521 return WeightedMovingAverage(CurrentSample, PreviousSample, Weight);
2522 }
2523
2536
2537};
2538
2539// LWC Conversion helpers
2540namespace UE
2541{
2542namespace LWC
2543{
2544
2545 // Convert array to a new type
2546 template<typename TDest, typename TSrc, typename InAllocatorType>
2548 {
2549 //static_assert(!std::is_same_v<TDest, TSrc>, "Redundant call to ConvertArrayType"); // Unavoidable if supporting LWC toggle, but a useful check once LWC is locked to enabled.
2550 if constexpr (std::is_same_v<TDest, TSrc>)
2551 {
2552 return From;
2553 }
2554 else
2555 {
2557 Converted.Reserve(From.Num());
2558 for (const TSrc& Item : From)
2559 {
2560 Converted.Add(static_cast<TDest>(Item));
2561 }
2562 return Converted;
2563 }
2564 }
2565
2566 // Convert array to a new type and clamps values to the Max of TDest type
2567 template<typename TDest, typename TSrc, typename InAllocatorType>
2569 {
2570 //static_assert(!std::is_same_v<TDest, TSrc>, "Redundant call to ConvertArrayType"); // Unavoidable if supporting LWC toggle, but a useful check once LWC is locked to enabled.
2571 if constexpr (std::is_same_v<TDest, TSrc>)
2572 {
2573 return From;
2574 }
2575 else
2576 {
2578 Converted.Reserve(From.Num());
2579 for (const TSrc& Item : From)
2580 {
2581 Converted.Add(FMath::Min(TNumericLimits<TDest>::Max(), static_cast<TDest>(Item)));
2582 }
2583 return Converted;
2584 }
2585 }
2586
2587 /*
2588 * Floating point to integer conversions
2589 */
2590
2591 // Generic float type to int type, to enable specializations below.
2592 template <UE::CIntegral OutIntType, UE::CFloatingPoint InFloatType>
2594 {
2595 return (OutIntType)(FloatValue);
2596 }
2597
2598 // float->int32
2599 template<>
2600 inline int32 FloatToIntCastChecked(float FloatValue)
2601 {
2602 // floats over 2^31 - 1 - 64 overflow int32 after conversion.
2603 checkf(FloatValue >= float(TNumericLimits<int32>::Lowest()) && FloatValue <= float(TNumericLimits<int32>::Max() - 64), TEXT("Input value %f will exceed int32 limits"), FloatValue);
2604 return FMath::TruncToInt32(FloatValue);
2605 }
2606
2607 // float->int64
2608 template<>
2609 inline int64 FloatToIntCastChecked(float FloatValue)
2610 {
2611 // floats over 2^63 - 1 - 2^39 overflow int64 after conversion.
2612 checkf(FloatValue >= float(TNumericLimits<int64>::Lowest()) && FloatValue <= float(TNumericLimits<int64>::Max() - (int64)549755813888), TEXT("Input value %f will exceed int64 limits"), FloatValue);
2613 return FMath::TruncToInt64(FloatValue);
2614 }
2615
2616 // double->int32
2617 template<>
2618 inline int32 FloatToIntCastChecked(double FloatValue)
2619 {
2620 checkf(FloatValue >= double(TNumericLimits<int32>::Lowest()) && FloatValue <= double(TNumericLimits<int32>::Max()), TEXT("Input value %f will exceed int32 limits"), FloatValue);
2621 return FMath::TruncToInt32(FloatValue);
2622 }
2623
2624 // double->int64
2625 template<>
2626 inline int64 FloatToIntCastChecked(double FloatValue)
2627 {
2628 // doubles over 2^63 - 1 - 512 overflow int64 after conversion.
2629 checkf(FloatValue >= double(TNumericLimits<int64>::Lowest()) && FloatValue <= double(TNumericLimits<int64>::Max() - 512), TEXT("Input value %f will exceed int64 limits"), FloatValue);
2630 return FMath::TruncToInt64(FloatValue);
2631 }
2632
2633} // namespace LWC
2634} // namespace UE
2635
2636#if UE_ENABLE_INCLUDE_ORDER_DEPRECATED_IN_5_7
2637#include "Templates/Identity.h"
2638#endif
FClangPlatformMath FPlatformMath
Definition AndroidPlatformMath.h:10
#define check(expr)
Definition AssertionMacros.h:314
#define checkf(expr, format,...)
Definition AssertionMacros.h:315
#define TEXT(x)
Definition Platform.h:1272
FPlatformTypes::int64 int64
A 64-bit signed integer.
Definition Platform.h:1127
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
return true
Definition ExternalRpcRegistry.cpp:601
#define X(Name, Desc)
Definition FormatStringSan.h:47
FVector FloorToDouble(const FVector Vec)
Definition HeterogeneousVolumesLiveShadingPipeline.cpp:2340
#define Square(a, x, y)
Definition Predicates.inl:251
#define UE_REQUIRES(...)
Definition Requires.h:86
#define UE_DOUBLE_PI
Definition UnrealMathUtility.h:138
#define UE_DOUBLE_SMALL_NUMBER
Definition UnrealMathUtility.h:139
#define UE_INV_PI
Definition UnrealMathUtility.h:150
#define UE_PI
Definition UnrealMathUtility.h:129
#define UE_SMALL_NUMBER
Definition UnrealMathUtility.h:130
#define UE_HALF_PI
Definition UnrealMathUtility.h:151
#define UE_TWO_PI
Definition UnrealMathUtility.h:152
#define FASTASIN_HALF_PI
Definition UnrealMathUtility.h:817
#define UE_KINDA_SMALL_NUMBER
Definition UnrealMathUtility.h:131
float Val(const FString &Value)
Definition UnrealMath.cpp:3163
uint32 Size
Definition VulkanMemory.cpp:4034
uint8_t uint8
Definition binka_ue_file_header.h:8
uint32_t uint32
Definition binka_ue_file_header.h:6
Definition Array.h:670
UE_REWRITE SizeType Num() const
Definition Array.h:1144
UE_FORCEINLINE_HINT void Reserve(SizeType Number)
Definition Array.h:3016
Definition Range.h:50
TArray< TDest, InAllocatorType > ConvertArrayTypeClampMax(const TArray< TSrc, InAllocatorType > &From)
Definition UnrealMathUtility.h:2568
OutIntType FloatToIntCastChecked(InFloatType FloatValue)
Definition UnrealMathUtility.h:2593
TArray< TDest, InAllocatorType > ConvertArrayType(const TArray< TSrc, InAllocatorType > &From)
Definition UnrealMathUtility.h:2547
Definition AdvancedWidgetsModule.cpp:13
U16 Index
Definition radfft.cpp:71
Definition Color.h:48
Definition UnrealMathUtility.h:270
RESOLVE_FLOAT_AMBIGUITY_3_ARGS(ClampAngle)
static UE::Math::TRotator< T > LerpRange(const UE::Math::TRotator< T > &A, const UE::Math::TRotator< T > &B, U Alpha)
static auto GetRangeValue(UE::Math::TVector2< T > const &Range, T2 Pct)
Definition UnrealMathUtility.h:1070
static constexpr void CriticallyDampedSmoothing(T &InOutValue, T &InOutValueRate, const T &InTargetValue, const T &InTargetValueRate, const float InDeltaTime, const float InSmoothingTime)
Definition UnrealMathUtility.h:1601
static CORE_API int32 PlaneAABBRelativePosition(const FPlane &P, const FBox &AABB)
Definition UnrealMath.cpp:2104
static CORE_API bool GetDistanceWithinConeSegment(FVector Point, FVector ConeStartPoint, FVector ConeLine, float RadiusAtStart, float RadiusAtEnd, float &PercentageOut)
Definition UnrealMath.cpp:2434
RESOLVE_FLOAT_AMBIGUITY_2_ARGS(FRandRange)
static constexpr UE_FORCEINLINE_HINT auto DegreesToRadians(T const &DegVal) -> decltype(DegVal *(UE_PI/180.f))
Definition UnrealMathUtility.h:871
static UE_FORCEINLINE_HINT auto GetMappedRangeValueUnclamped(const UE::Math::TVector2< T > &InputRange, const UE::Math::TVector2< T > &OutputRange, const T2 Value)
Definition UnrealMathUtility.h:1086
static constexpr UE_FORCEINLINE_HINT int64 Clamp(const int64 X, const int32 Min, const int32 Max)
Definition UnrealMathUtility.h:604
static CORE_API FVector ClosestPointOnTetrahedronToPoint(const FVector &Point, const FVector &A, const FVector &B, const FVector &C, const FVector &D)
Definition UnrealMath.cpp:2320
static CORE_API bool SegmentIntersection2D(const FVector &SegmentStartA, const FVector &SegmentEndA, const FVector &SegmentStartB, const FVector &SegmentEndB, FVector &out_IntersectionPoint)
Definition UnrealMath.cpp:1972
static CORE_API UE::Math::TVector2< T > ClosestPointOnSegment2D(const UE::Math::TVector2< T > &Point, const UE::Math::TVector2< T > &StartPoint, const UE::Math::TVector2< T > &EndPoint)
static bool PointBoxIntersection(const UE::Math::TVector< FReal > &Point, const UE::Math::TBox< FReal > &Box)
Definition Box.h:1030
static T InterpCircularOut(const T &A, const T &B, float Alpha)
Definition UnrealMathUtility.h:1374
static UE::Math::TVector< FReal > LinePlaneIntersection(const UE::Math::TVector< FReal > &Point1, const UE::Math::TVector< FReal > &Point2, const UE::Math::TVector< FReal > &PlaneOrigin, const UE::Math::TVector< FReal > &PlaneNormal)
static T InterpEaseInOut(const T &A, const T &B, float Alpha, float Exp)
Definition UnrealMathUtility.h:1288
static T InterpExpoInOut(const T &A, const T &B, float Alpha)
Definition UnrealMathUtility.h:1357
static T DynamicWeightedMovingAverage(T CurrentSample, T PreviousSample, T MaxDistance, T MinWeight, T MaxWeight)
Definition UnrealMathUtility.h:2510
static CORE_API float PerlinNoise1D(float Value)
Definition UnrealMath.cpp:3611
static auto GetRangePct(UE::Math::TVector2< T > const &Range, T2 Value)
Definition UnrealMathUtility.h:1063
static constexpr UE_FORCEINLINE_HINT T LerpStable(const T &A, const T &B, float Alpha)
Definition UnrealMathUtility.h:1154
static auto LerpStable(const T1 &A, const T2 &B, const T3 &Alpha) -> decltype(A *B)
Definition UnrealMathUtility.h:1166
static UE_FORCEINLINE_HINT double RandRange(double InMin, double InMax)
Definition UnrealMathUtility.h:307
static constexpr void SinCos(std::decay_t< T > *ScalarSin, std::decay_t< T > *ScalarCos, T Value)
Definition UnrealMathUtility.h:753
MIX_FLOATS_3_ARGS(Clamp)
static UE_FORCEINLINE_HINT void CartesianToPolar(const UE::Math::TVector2< T > InCart, UE::Math::TVector2< T > &OutPolar)
Definition UnrealMathUtility.h:987
static constexpr UE_FORCEINLINE_HINT auto RadiansToDegrees(T const &RadVal) -> decltype(RadVal *(180.f/UE_PI))
Definition UnrealMathUtility.h:857
static constexpr int32 GreatestCommonDivisor(int32 a, int32 b)
Definition UnrealMathUtility.h:2432
static CORE_API float TruncateToHalfIfClose(float F, float Tolerance=UE_SMALL_NUMBER)
Definition UnrealMath.cpp:2969
static CORE_API UE::Math::TQuat< T > QInterpConstantTo(const UE::Math::TQuat< T > &Current, const UE::Math::TQuat< T > &Target, float DeltaTime, float InterpSpeed)
Definition UnrealMath.cpp:2725
static UE_FORCEINLINE_HINT float RandRange(float InMin, float InMax)
Definition UnrealMathUtility.h:302
static CORE_API FVector GetReflectionVector(const FVector &Direction, const FVector &SurfaceNormal)
Definition UnrealMath.cpp:2962
static UE_FORCEINLINE_HINT bool IsNearlyEqualByULP(float A, float B, int32 MaxUlps=4)
Definition UnrealMathUtility.h:486
static bool SphereAABBIntersection(const UE::Math::TVector< FReal > &SphereCenter, const FReal RadiusSquared, const UE::Math::TBox< FReal > &AABB)
Definition Box.h:1190
static CORE_API UE::Math::TVector2< T > Vector2DInterpTo(const UE::Math::TVector2< T > &Current, const UE::Math::TVector2< T > &Target, float DeltaTime, float InterpSpeed)
Definition UnrealMath.cpp:2630
static constexpr T CubicInterpDerivative(const T &P0, const T &T0, const T &P1, const T &T1, const U &A)
Definition UnrealMathUtility.h:1241
static constexpr T UnwindRadians(T A)
Definition UnrealMathUtility.h:927
static constexpr UE_FORCEINLINE_HINT T DivideAndRoundUp(T Dividend, T Divisor)
Definition UnrealMathUtility.h:694
static CORE_API float RoundHalfToZero(float F)
Definition UnrealMath.cpp:3063
static constexpr UE_FORCEINLINE_HINT IntegralType Floor(IntegralType I)
Definition UnrealMathUtility.h:541
static UE_FORCEINLINE_HINT bool IsNearlyEqual(float A, float B, float ErrorTolerance=UE_SMALL_NUMBER)
Definition UnrealMathUtility.h:388
RESOLVE_FLOAT_PREDICATE_AMBIGUITY_2_ARGS(IsNearlyEqual)
static void PolarToCartesian(const T Rad, const T Ang, T &OutX, T &OutY)
Definition UnrealMathUtility.h:994
static CORE_API float PointDistToSegment(const FVector &Point, const FVector &StartPoint, const FVector &EndPoint)
Definition UnrealMath.cpp:1745
static CORE_API FLinearColor CInterpTo(const FLinearColor &Current, const FLinearColor &Target, float DeltaTime, float InterpSpeed)
Definition UnrealMath.cpp:2701
static FReal RayPlaneIntersectionParam(const UE::Math::TVector< FReal > &RayOrigin, const UE::Math::TVector< FReal > &RayDirection, const UE::Math::TPlane< FReal > &Plane)
static auto GetMappedRangeValueClamped(const UE::Math::TVector2< T > &InputRange, const UE::Math::TVector2< T > &OutputRange, const T2 Value)
Definition UnrealMathUtility.h:1077
static T InterpCircularInOut(const T &A, const T &B, float Alpha)
Definition UnrealMathUtility.h:1383
static constexpr UE_FORCEINLINE_HINT bool IsPowerOfTwo(T Value)
Definition UnrealMathUtility.h:519
static UE_FORCEINLINE_HINT T BiLerp(const T &P00, const T &P10, const T &P01, const T &P11, const U &FracX, const U &FracY)
Definition UnrealMathUtility.h:1193
static UE_FORCEINLINE_HINT T GetRangeValue(TRange< T > const &Range, T Pct)
Definition UnrealMathUtility.h:1098
static CORE_API FVector VInterpNormalRotationTo(const FVector &Current, const FVector &Target, float DeltaTime, float RotationSpeedDegrees)
Definition UnrealMath.cpp:2540
static CORE_API bool MemoryTest(void *BaseAddress, uint32 NumBytes)
Definition UnrealMath.cpp:3109
static constexpr UE_FORCEINLINE_HINT T Lerp(const T &A, const T &B, const U &Alpha)
Definition UnrealMathUtility.h:1116
static CORE_API bool SegmentTriangleIntersection(const FVector &StartPoint, const FVector &EndPoint, const FVector &A, const FVector &B, const FVector &C, FVector &OutIntersectPoint, FVector &OutTriangleNormal)
Definition UnrealMath.cpp:1939
static CORE_API bool SegmentPlaneIntersection(const FVector &StartPoint, const FVector &EndPoint, const FPlane &Plane, FVector &out_IntersectionPoint)
Definition UnrealMath.cpp:1927
static UE_FORCEINLINE_HINT double RoundToZero(double F)
Definition UnrealMathUtility.h:2214
static CORE_API bool GetDotDistance(FVector2D &OutDotDist, const FVector &Direction, const FVector &AxisX, const FVector &AxisY, const FVector &AxisZ)
Definition UnrealMath.cpp:2495
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 double RadiansToDegrees(double const &RadVal)
Definition UnrealMathUtility.h:863
static CORE_API FString FormatIntToHumanReadable(int32 Val)
Definition UnrealMath.cpp:3093
static CORE_API UE::Math::TQuat< T > QInterpTo(const UE::Math::TQuat< T > &Current, const UE::Math::TQuat< T > &Target, float DeltaTime, float InterpSpeed)
Definition UnrealMath.cpp:2752
static CORE_API bool MatrixInverse(FMatrix44f *DstMatrix, const FMatrix44f *SrcMatrix)
Definition UnrealMath.cpp:928
static CORE_API float RoundHalfToEven(float F)
Definition UnrealMath.cpp:2997
static void SinCos(double *ScalarSin, double *ScalarCos, double Value)
Definition UnrealMathUtility.h:794
static CORE_API float PerlinNoise3D(const FVector &Location)
Definition UnrealMath.cpp:3658
static constexpr T CubicInterp(const T &P0, const T &T0, const T &P1, const T &T1, const U &A)
Definition UnrealMathUtility.h:1212
static CORE_API const uint32 BitFlag[32]
Definition UnrealMathUtility.h:63
static constexpr int32 LeastCommonMultiplier(int32 a, int32 b)
Definition UnrealMathUtility.h:2445
static CORE_API FRotator RInterpConstantTo(const FRotator &Current, const FRotator &Target, float DeltaTime, float InterpSpeed)
Definition UnrealMath.cpp:2647
static T InterpEaseOut(const T &A, const T &B, float Alpha, float Exp)
Definition UnrealMathUtility.h:1280
static CORE_API FRotator RInterpTo(const FRotator &Current, const FRotator &Target, float DeltaTime, float InterpSpeed)
Definition UnrealMath.cpp:2671
static CORE_API bool LineExtentBoxIntersection(const FBox &inBox, const FVector &Start, const FVector &End, const FVector &Extent, FVector &HitLocation, FVector &HitNormal, float &HitTime)
Definition UnrealMath.cpp:1028
static CORE_API float FixedTurn(float InCurrent, float InDesired, float InDeltaRate)
Definition UnrealMath.cpp:3488
static UE_FORCEINLINE_HINT double RoundFromZero(double F)
Definition UnrealMathUtility.h:2199
static UE_FORCEINLINE_HINT double Floor(double F)
Definition UnrealMathUtility.h:531
static CORE_API FVector2D Vector2DInterpConstantTo(const FVector2D &Current, const FVector2D &Target, float DeltaTime, float InterpSpeed)
Definition UnrealMath.cpp:2607
static constexpr void ExponentialSmoothingApprox(T &InOutValue, const T &InTargetValue, const float InDeltaTime, const float InSmoothingTime)
Definition UnrealMathUtility.h:1565
static T InterpSinOut(const T &A, const T &B, float Alpha)
Definition UnrealMathUtility.h:1324
static constexpr UE_FORCEINLINE_HINT T Square(const T A)
Definition UnrealMathUtility.h:578
static void CartesianToPolar(const T X, const T Y, T &OutRad, T &OutAng)
Definition UnrealMathUtility.h:980
static constexpr auto GetRangePct(T MinValue, T MaxValue, T2 Value)
Definition UnrealMathUtility.h:1047
static UE_FORCEINLINE_HINT bool IsNearlyZero(double Value, double ErrorTolerance=UE_DOUBLE_SMALL_NUMBER)
Definition UnrealMathUtility.h:418
static T InterpEaseIn(const T &A, const T &B, float Alpha, float Exp)
Definition UnrealMathUtility.h:1272
static UE_FORCEINLINE_HINT float Floor(float F)
Definition UnrealMathUtility.h:525
static constexpr UE_FORCEINLINE_HINT bool IsWithin(const T &TestValue, const U &MinValue, const U &MaxValue)
Definition UnrealMathUtility.h:368
static constexpr T SmoothStep(T A, T B, T X)
Definition UnrealMathUtility.h:2357
static constexpr UE_FORCEINLINE_HINT T DivideAndRoundDown(T Dividend, T Divisor)
Definition UnrealMathUtility.h:701
static CORE_API float PointDistToLine(const FVector &Point, const FVector &Direction, const FVector &Origin, FVector &OutClosestPoint)
Definition UnrealMath.cpp:1679
static bool LineBoxIntersection2D(const UE::Math::TBox2< FReal > &Box, const UE::Math::TVector2< FReal > &Start, const UE::Math::TVector2< FReal > &End)
Definition Box2D.h:638
static CORE_API bool PlaneAABBIntersection(const FPlane &P, const FBox &AABB)
Definition UnrealMath.cpp:2148
static UE_FORCEINLINE_HINT double GetRangePct(TRange< T > const &Range, T Value)
Definition UnrealMathUtility.h:1092
static constexpr UE_FORCEINLINE_HINT float Clamp(const float X, const float Min, const float Max)
Definition UnrealMathUtility.h:600
static CORE_API void ApplyScaleToFloat(float &Dst, const FVector &DeltaScale, float Magnitude=1.0f)
Definition UnrealMath.cpp:3521
static UE_FORCEINLINE_HINT float RoundToNegativeInfinity(float F)
Definition UnrealMathUtility.h:2224
static constexpr auto FindDeltaAngleRadians(T A1, T2 A2) -> decltype(A1 - A2)
Definition UnrealMathUtility.h:914
static CORE_API float PerlinNoise2D(const FVector2D &Location)
Definition UnrealMath.cpp:3629
static UE_FORCEINLINE_HINT T Lerp(const T &A, const T &B, const U &Alpha)
Definition UnrealMathUtility.h:1127
static constexpr UE_FORCEINLINE_HINT double DegreesToRadians(double const &DegVal)
Definition UnrealMathUtility.h:877
static CORE_API FVector2D GetAzimuthAndElevation(const FVector &Direction, const FVector &AxisX, const FVector &AxisY, const FVector &AxisZ)
Definition UnrealMath.cpp:2520
static auto FInterpTo(T1 Current, T2 Target, T3 DeltaTime, T4 InterpSpeed)
Definition UnrealMathUtility.h:1502
static constexpr void SetBoolInBitField(uint8 *Ptr, uint32 Index, bool bSet)
Definition UnrealMathUtility.h:2387
static CORE_API UE::Math::TVector< T > ClosestPointOnSegment(const UE::Math::TVector< T > &Point, const UE::Math::TVector< T > &StartPoint, const UE::Math::TVector< T > &EndPoint)
static constexpr T BiLerp(const T &P00, const T &P10, const T &P01, const T &P11, const U &FracX, const U &FracY)
Definition UnrealMathUtility.h:1178
static double Log2(double Value)
Definition UnrealMathUtility.h:737
RESOLVE_FLOAT_PREDICATE_AMBIGUITY_3_ARGS(IsNearlyEqual)
static bool LineBoxIntersection(const UE::Math::TBox< FReal > &Box, const UE::Math::TVector< FReal > &Start, const UE::Math::TVector< FReal > &End, const UE::Math::TVector< FReal > &Direction)
Definition Box.h:1042
static bool LineSphereIntersection(const UE::Math::TVector< FReal > &Start, const UE::Math::TVector< FReal > &Dir, FReal Length, const UE::Math::TVector< FReal > &Origin, FReal Radius)
static CORE_API FVector4 ComputeBaryCentric3D(const FVector &Point, const FVector &A, const FVector &B, const FVector &C, const FVector &D)
Definition UnrealMath.cpp:2293
static CORE_API bool Eval(FString Str, float &OutValue)
Definition UnrealMath.cpp:3432
static int64 RandRange(int64 Min, int64 Max)
Definition UnrealMathUtility.h:295
static bool IntersectPlanes2(UE::Math::TVector< FReal > &I, UE::Math::TVector< FReal > &D, const UE::Math::TPlane< FReal > &P1, const UE::Math::TPlane< FReal > &P2)
static T ClampAngle(T AngleDegrees, T MinAngleDegrees, T MaxAngleDegrees)
Definition Rotator.h:947
static T GetMappedRangeValueClamped(const TRange< T > &InputRange, const TRange< T > &OutputRange, const T Value)
Definition UnrealMathUtility.h:1104
static void SpringDamperSmoothing(T &InOutValue, T &InOutValueRate, const T &InTargetValue, const T &InTargetValueRate, const float InDeltaTime, const float InSmoothingTime, const float InDampingRatio)
Definition UnrealMathUtility.h:1764
static CORE_API FVector RandPointInBox(const FBox &Box)
Definition UnrealMath.cpp:2955
static UE_FORCEINLINE_HINT void SinCos(T *ScalarSin, T *ScalarCos, U Value)
Definition UnrealMathUtility.h:806
static constexpr T CubicInterpSecondDerivative(const T &P0, const T &T0, const T &P1, const T &T1, const U &A)
Definition UnrealMathUtility.h:1262
static CORE_API FVector ComputeBaryCentric2D(const FVector &Point, const FVector &A, const FVector &B, const FVector &C)
Definition UnrealMath.cpp:2283
static CORE_API FVector VRandCone(FVector const &Dir, float ConeHalfAngleRad)
Definition UnrealMath.cpp:2859
static T WeightedMovingAverage(T CurrentSample, T PreviousSample, T Weight)
Definition UnrealMathUtility.h:2489
static CORE_API FVector ClosestPointOnInfiniteLine(const FVector &LineStart, const FVector &LineEnd, const FVector &Point)
Definition UnrealMath.cpp:346
static UE::Math::TVector< FReal > LinePlaneIntersection(const UE::Math::TVector< FReal > &Point1, const UE::Math::TVector< FReal > &Point2, const UE::Math::TPlane< FReal > &Plane)
static float FastAsin(float Value)
Definition UnrealMathUtility.h:824
static FVector VRand()
Definition Vector.h:2706
static T InterpCircularIn(const T &A, const T &B, float Alpha)
Definition UnrealMathUtility.h:1366
static UE_FORCEINLINE_HINT int64 RandHelper64(int64 A)
Definition UnrealMathUtility.h:281
static int32 RandRange(int32 Min, int32 Max)
Definition UnrealMathUtility.h:289
static constexpr auto Modulo(ValueType Value, BaseType Base)
Definition UnrealMathUtility.h:671
static constexpr U CubicCRSplineInterp(const U &P0, const U &P1, const U &P2, const U &P3, const float T0, const float T1, const float T2, const float T3, const float T)
Definition UnrealMathUtility.h:1407
static constexpr UE_FORCEINLINE_HINT T Clamp(const T X, const T MinValue, const T MaxValue)
Definition UnrealMathUtility.h:592
static CORE_API float RoundHalfFromZero(float F)
Definition UnrealMath.cpp:3033
static CORE_API void SegmentDistToSegment(FVector A1, FVector B1, FVector A2, FVector B2, FVector &OutP1, FVector &OutP2)
Definition UnrealMath.cpp:1917
static T InterpExpoOut(const T &A, const T &B, float Alpha)
Definition UnrealMathUtility.h:1349
RESOLVE_FLOAT_PREDICATE_AMBIGUITY_2_ARGS(IsNearlyZero)
static bool IntersectPlanes3(UE::Math::TVector< FReal > &I, const UE::Math::TPlane< FReal > &P1, const UE::Math::TPlane< FReal > &P2, const UE::Math::TPlane< FReal > &P3)
static UE_FORCEINLINE_HINT bool IsNearlyEqualByULP(double A, double B, int32 MaxUlps=4)
Definition UnrealMathUtility.h:508
static CORE_API FVector ClosestPointOnTriangleToPoint(const FVector &Point, const FVector &A, const FVector &B, const FVector &C)
Definition UnrealMath.cpp:2183
static UE_FORCEINLINE_HINT double FastAsin(double Value)
Definition UnrealMathUtility.h:843
static CORE_API FVector VInterpTo(const FVector &Current, const FVector &Target, float DeltaTime, float InterpSpeed)
Definition UnrealMath.cpp:2584
static constexpr UE_FORCEINLINE_HINT float DegreesToRadians(float const &DegVal)
Definition UnrealMathUtility.h:876
static CORE_API bool ComputeBarycentricTri(const FVector &Point, const FVector &A, const FVector &B, const FVector &C, FVector &OutBarycentric, double Tolerance=UE_DOUBLE_SMALL_NUMBER)
Definition UnrealMath.cpp:2249
static constexpr T WrapExclusive(const T X, const T Min, const T Max)
Definition UnrealMathUtility.h:638
static CORE_API uint32 ComputeProjectedSphereScissorRect(FIntRect &InOutScissorRect, FVector SphereOrigin, float Radius, FVector ViewOrigin, const FMatrix &ViewMatrix, const FMatrix &ProjMatrix)
Definition UnrealMath.cpp:2063
static auto Lerp(const T1 &A, const T2 &B, const T3 &Alpha) -> decltype(A *B)
Definition UnrealMathUtility.h:1139
static UE_FORCEINLINE_HINT float RoundFromZero(float F)
Definition UnrealMathUtility.h:2194
static constexpr UE_FORCEINLINE_HINT T Min3(const T A, const T B, const T C)
Definition UnrealMathUtility.h:558
static CORE_API UE::Math::TVector< T > ClosestPointOnLine(const UE::Math::TVector< T > &LineStart, const UE::Math::TVector< T > &LineEnd, const UE::Math::TVector< T > &Point)
static constexpr T InterpStep(const T &A, const T &B, float Alpha, int32 Steps)
Definition UnrealMathUtility.h:1297
static uint8 Quantize8SignedByte(float x)
Definition UnrealMathUtility.h:2423
static CORE_API float GetTForSegmentPlaneIntersect(const FVector &StartPoint, const FVector &EndPoint, const FPlane &Plane)
Definition UnrealMath.cpp:1922
static CORE_API bool PointsAreCoplanar(const TArray< FVector > &Points, const float Tolerance=0.1f)
Definition UnrealMath.cpp:2470
static UE_FORCEINLINE_HINT double RoundToNegativeInfinity(double F)
Definition UnrealMathUtility.h:2229
static CORE_API float PointDistToSegmentSquared(const FVector &Point, const FVector &StartPoint, const FVector &EndPoint)
Definition UnrealMath.cpp:1751
static CORE_API void SegmentDistToSegmentSafe(UE::Math::TVector< T > A1, UE::Math::TVector< T > B1, UE::Math::TVector< T > A2, UE::Math::TVector< T > B2, UE::Math::TVector< T > &OutP1, UE::Math::TVector< T > &OutP2)
static UE_FORCEINLINE_HINT float RoundToPositiveInfinity(float F)
Definition UnrealMathUtility.h:2239
static UE_FORCEINLINE_HINT float RoundToZero(float F)
Definition UnrealMathUtility.h:2209
static CORE_API void WindRelativeAnglesDegrees(float InAngle0, float &InOutAngle1)
Definition UnrealMath.cpp:3468
static CORE_API FVector GetBaryCentric2D(const FVector &Point, const FVector &A, const FVector &B, const FVector &C)
Definition UnrealMath.cpp:2233
static constexpr UE_FORCEINLINE_HINT int32 Min3Index(const T A, const T B, const T C)
Definition UnrealMathUtility.h:571
static constexpr UE_FORCEINLINE_HINT T Wrap(const T X, const T Min, const T Max)
Definition UnrealMathUtility.h:610
static constexpr T InvExpApprox(T X)
Definition UnrealMathUtility.h:1546
static constexpr bool ExtractBoolFromBitfield(const uint8 *Ptr, uint32 Index)
Definition UnrealMathUtility.h:2375
static UE_FORCEINLINE_HINT bool IsNearlyZero(float Value, float ErrorTolerance=UE_SMALL_NUMBER)
Definition UnrealMathUtility.h:407
static constexpr UE_FORCEINLINE_HINT T Cube(const T A)
Definition UnrealMathUtility.h:585
static constexpr UE_FORCEINLINE_HINT double Clamp(const double X, const double Min, const double Max)
Definition UnrealMathUtility.h:601
static UE_FORCEINLINE_HINT T CubicInterp(const T &P0, const T &T0, const T &P1, const T &T1, const U &A)
Definition UnrealMathUtility.h:1226
static void SpringDamper(T &InOutValue, T &InOutValueRate, const T &InTargetValue, const T &InTargetValueRate, const float InDeltaTime, const float InUndampedFrequency, const float InDampingRatio)
Definition UnrealMathUtility.h:1665
static CORE_API void SphereDistToLine(FVector SphereOrigin, float SphereRadius, FVector LineOrigin, FVector LineDir, FVector &OutClosestPoint)
Definition UnrealMath.cpp:2407
static constexpr UE_FORCEINLINE_HINT T LerpStable(const T &A, const T &B, double Alpha)
Definition UnrealMathUtility.h:1147
static float MakePulsatingValue(const double InCurrentTime, const float InPulsesPerSecond, const float InPhase=0.0f)
Definition UnrealMathUtility.h:1798
MIX_FLOATS_2_ARGS(GridSnap)
static UE_FORCEINLINE_HINT double FRandRange(double InMin, double InMax)
Definition UnrealMathUtility.h:319
static UE_FORCEINLINE_HINT float FRandRange(float InMin, float InMax)
Definition UnrealMathUtility.h:313
static CORE_API FVector VInterpConstantTo(const FVector &Current, const FVector &Target, float DeltaTime, float InterpSpeed)
Definition UnrealMath.cpp:2562
static constexpr UE_FORCEINLINE_HINT T Max3(const T A, const T B, const T C)
Definition UnrealMathUtility.h:551
static UE_FORCEINLINE_HINT bool IsNearlyEqual(double A, double B, double ErrorTolerance=UE_DOUBLE_SMALL_NUMBER)
Definition UnrealMathUtility.h:393
static CORE_API FVector2D RandPointInCircle(float CircleRadius)
Definition UnrealMath.cpp:2938
static auto FInterpConstantTo(T1 Current, T2 Target, T3 DeltaTime, T4 InterpSpeed)
Definition UnrealMathUtility.h:1483
static float Log2(float Value)
Definition UnrealMathUtility.h:722
static UE_FORCEINLINE_HINT double RoundToPositiveInfinity(double F)
Definition UnrealMathUtility.h:2244
static UE::Math::TVector< FReal > RayPlaneIntersection(const UE::Math::TVector< FReal > &RayOrigin, const UE::Math::TVector< FReal > &RayDirection, const UE::Math::TPlane< FReal > &Plane)
static constexpr U CubicCRSplineInterpSafe(const U &P0, const U &P1, const U &P2, const U &P3, const float T0, const float T1, const float T2, const float T3, const float T)
Definition UnrealMathUtility.h:1427
static constexpr T UnwindDegrees(T A)
Definition UnrealMathUtility.h:944
static UE_FORCEINLINE_HINT void PolarToCartesian(const UE::Math::TVector2< T > InPolar, UE::Math::TVector2< T > &OutCart)
Definition UnrealMathUtility.h:1001
static CORE_API bool SphereConeIntersection(const FVector &SphereCenter, float SphereRadius, const FVector &ConeAxis, float ConeAngleSin, float ConeAngleCos)
Definition UnrealMath.cpp:2153
static constexpr UE_FORCEINLINE_HINT T GridSnap(T Location, T Grid)
Definition UnrealMathUtility.h:685
static constexpr auto FindDeltaAngleDegrees(T A1, T2 A2) -> decltype(A1 - A2)
Definition UnrealMathUtility.h:897
static constexpr T DivideAndRoundNearest(T Dividend, T Divisor)
Definition UnrealMathUtility.h:708
static constexpr UE_FORCEINLINE_HINT int32 Max3Index(const T A, const T B, const T C)
Definition UnrealMathUtility.h:564
static uint8 Quantize8UnsignedByte(float x)
Definition UnrealMathUtility.h:2410
static T InterpExpoIn(const T &A, const T &B, float Alpha)
Definition UnrealMathUtility.h:1341
static UE_FORCEINLINE_HINT bool RandBool()
Definition UnrealMathUtility.h:327
static UE_FORCEINLINE_HINT int32 RandHelper(int32 A)
Definition UnrealMathUtility.h:274
static T InterpSinIn(const T &A, const T &B, float Alpha)
Definition UnrealMathUtility.h:1316
static constexpr UE_FORCEINLINE_HINT float RadiansToDegrees(float const &RadVal)
Definition UnrealMathUtility.h:862
static T InterpSinInOut(const T &A, const T &B, float Alpha)
Definition UnrealMathUtility.h:1332
static constexpr UE_FORCEINLINE_HINT bool IsWithinInclusive(const T &TestValue, const U &MinValue, const U &MaxValue)
Definition UnrealMathUtility.h:376
Definition TwoVectors.h:15
Definition UnrealMathUtility.h:261
static constexpr bool Value
Definition UnrealMathUtility.h:262
Definition NumericLimits.h:41
Definition Box2D.h:31
Definition Plane.h:35
Definition Quat.h:39
Definition Rotator.h:37
Definition Sphere.h:29