mirror of
https://github.com/Milxnor/Project-Reboot-3.0.git
synced 2026-01-13 02:42:22 +01:00
131 lines
3.0 KiB
C++
131 lines
3.0 KiB
C++
#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<<Bit))
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
return Bit;
|
|
*/
|
|
// same output as reference
|
|
|
|
// see http://codinggorilla.domemtech.com/?p=81 or http://en.wikipedia.org/wiki/Binary_logarithm but modified to return 0 for a input value of 0
|
|
// 686ms on test data
|
|
uint32 pos = 0;
|
|
if (Value >= 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 <class T>
|
|
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
|
|
}; |