#pragma once #include "GenericPlatformMath.h" struct FMath : public FGenericPlatformMath { template< class T > static FORCEINLINE T Clamp(const T X, const T Min, const T Max) { return X < Min ? Min : X < Max ? X : Max; } template< class T > static FORCEINLINE T Square(const T A) { return A * A; } static float SRand() // T(REP) { return rand(); } static FORCEINLINE uint32 FloorLog2(uint32 Value) { /* // reference implementation // 1500ms on test data uint32 Bit = 32; for (; Bit > 0;) { Bit--; if (Value & (1<= 1 << 16) { Value >>= 16; pos += 16; } if (Value >= 1 << 8) { Value >>= 8; pos += 8; } if (Value >= 1 << 4) { Value >>= 4; pos += 4; } if (Value >= 1 << 2) { Value >>= 2; pos += 2; } if (Value >= 1 << 1) { pos += 1; } return (Value == 0) ? 0 : pos; // even faster would be method3 but it can introduce more cache misses and it would need to store the table somewhere // 304ms in test data /*int LogTable256[256]; void prep() { LogTable256[0] = LogTable256[1] = 0; for (int i = 2; i < 256; i++) { LogTable256[i] = 1 + LogTable256[i / 2]; } LogTable256[0] = -1; // if you want log(0) to return -1 } int _forceinline method3(uint32 v) { int r; // r will be lg(v) uint32 tt; // temporaries if ((tt = v >> 24) != 0) { r = (24 + LogTable256[tt]); } else if ((tt = v >> 16) != 0) { r = (16 + LogTable256[tt]); } else if ((tt = v >> 8 ) != 0) { r = (8 + LogTable256[tt]); } else { r = LogTable256[v]; } return r; }*/ } static FORCEINLINE uint32 CountLeadingZeros(uint32 Value) { if (Value == 0) return 32; return 31 - FloorLog2(Value); } template static constexpr FORCEINLINE T DivideAndRoundUp(T Dividend, T Divisor) { return (Dividend + Divisor - 1) / Divisor; } static FORCEINLINE int32 Rand() { return rand(); } static FORCEINLINE float FRand() { return Rand() / (float)RAND_MAX; } #define FASTASIN_HALF_PI (1.5707963050f) /** * Computes the ASin of a scalar value. * * @param Value input angle * @return ASin of Value */ static FORCEINLINE float FastAsin(float Value) { // Clamp input to [-1,1]. bool nonnegative = (Value >= 0.0f); float x = FMath::Abs(Value); float omx = 1.0f - x; if (omx < 0.0f) { omx = 0.0f; } float root = FMath::Sqrt(omx); // 7-degree minimax approximation 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; result *= root; // acos(|x|) // acos(x) = pi - acos(-x) when x < 0, asin(x) = pi/2 - acos(x) return (nonnegative ? FASTASIN_HALF_PI - result : result - FASTASIN_HALF_PI); } #undef FASTASIN_HALF_PI };