12#ifndef TT__INCLUDE__WWMATH_H
13#define TT__INCLUDE__WWMATH_H
16#define WWMATH_EPSILON 0.0001f
17#define WWMATH_EPSILON2 WWMATH_EPSILON * WWMATH_EPSILON
18#define WWMATH_PI 3.141592654f
19#define WWMATH_FLOAT_MAX (FLT_MAX)
20#define WWMATH_FLOAT_MIN (FLT_MIN)
21#define WWMATH_FLOAT_TINY (1.0e-37f)
22#define WWMATH_SQRT2 1.414213562f
23#define WWMATH_SQRT3 1.732050808f
24#define WWMATH_OOSQRT2 0.707106781f
25#define WWMATH_OOSQRT3 0.577350269f
27#define RAD_TO_DEG(x) (((double)x)*180.0/WWMATH_PI)
30#define DEG_TO_RAD(x) (((double)x)*WWMATH_PI/180.0)
33#define RAD_TO_DEGF(x) (((float)x)*180.0f/WWMATH_PI)
36#define DEG_TO_RADF(x) (((float)x)*WWMATH_PI/180.0f)
38const int ARC_TABLE_SIZE=1024;
39const int SIN_TABLE_SIZE=1024;
41SCRIPTS_API
extern REF_ARR_DECL(
float, _FastAcosTable, ARC_TABLE_SIZE);
42SCRIPTS_API
extern REF_ARR_DECL(
float, _FastAsinTable, ARC_TABLE_SIZE);
43SCRIPTS_API
extern REF_ARR_DECL(
float, _FastSinTable, SIN_TABLE_SIZE);
44SCRIPTS_API
extern REF_ARR_DECL(
float, _FastInvSinTable, SIN_TABLE_SIZE);
46extern float _FastAcosTable[ARC_TABLE_SIZE];
47extern float _FastAsinTable[ARC_TABLE_SIZE];
48extern float _FastSinTable[SIN_TABLE_SIZE];
49extern float _FastInvSinTable[SIN_TABLE_SIZE];
51class SCRIPTS_API WWMath
54 static void Init(
void);
55 static void Shutdown(
void);
56 static TT_INLINE
float Fabs(
float val)
58 int value=*(
int*)&val;
60 return *(
float*)&value;
62 static TT_INLINE
int Float_To_Int_Chop(
const float& f);
63 static TT_INLINE
int Float_To_Int_Floor(
const float& f);
64 static TT_INLINE
float Cos(
float val);
65 static TT_INLINE
float Sin(
float val);
66 static TT_INLINE
float Sqrt(
float val);
67 static float __fastcall Inv_Sqrt(
float a);
68 static TT_INLINE
long Float_To_Long(
float f);
69 static TT_INLINE
float Fast_Sin(
float val);
70 static TT_INLINE
float Fast_Inv_Sin(
float val);
71 static TT_INLINE
float Fast_Cos(
float val);
72 static TT_INLINE
float Fast_Inv_Cos(
float val);
73 static TT_INLINE
float Fast_Acos(
float val);
74 static TT_INLINE
float Fast_Asin(
float val);
75 static TT_INLINE
float Acos(
float val);
76 static TT_INLINE
float Asin(
float val);
77 static float Atan(
float x) {
return static_cast<float>(atan(x)); }
78 static float Atan2(
float y,
float x) {
return static_cast<float>(atan2(y,x)); }
79 static float Sign(
float val);
80 static float Ceil(
float val) {
return ceilf(val); }
81 static float Floor(
float val) {
return floorf(val); }
82 static bool Fast_Is_Float_Positive(
const float & val);
83 static float Random_Float(
void);
84 static float Random_Float(
float min,
float max);
85 static float Clamp(
float val,
float min = 0.0f,
float max = 1.0f);
86 static double Clamp(
double val,
double min = 0.0f,
double max = 1.0f);
87 static int Clamp_Int(
int val,
int min_val,
int max_val);
88 static float Wrap(
float val,
float min = 0.0f,
float max = 1.0f);
89 static double Wrap(
double val,
double min = 0.0f,
double max = 1.0f);
90 static float Min(
float a,
float b);
91 static float Max(
float a,
float b);
92 static float Lerp(
float a,
float b,
float lerp );
93 static double Lerp(
double a,
double b,
float lerp );
94 static int Lerp(
int a,
int b,
float lerp );
95 static long Float_To_Long(
double f);
96 static unsigned char Unit_Float_To_Byte(
float f) {
return (
unsigned char)(f*255.0f); }
97 static float Byte_To_Unit_Float(
unsigned char byte) {
return ((
float)
byte) / 255.0f; }
98 static bool Is_Valid_Float(
float x);
99 static bool Is_Valid_Double(
double x);
101TT_INLINE
float WWMath::Sign(
float val)
112TT_INLINE
bool WWMath::Fast_Is_Float_Positive(
const float & val)
114 return !((*(
int *)(&val)) & 0x80000000);
117TT_INLINE
float WWMath::Random_Float(
float min,
float max)
119 return Random_Float() * (max-min) + min;
122TT_INLINE
float WWMath::Clamp(
float val,
float min,
float max)
124 if(val < min)
return min;
125 if(val > max)
return max;
129TT_INLINE
double WWMath::Clamp(
double val,
double min,
double max)
131 if(val < min)
return min;
132 if(val > max)
return max;
136TT_INLINE
int WWMath::Clamp_Int(
int val,
int min_val,
int max_val)
138 if(val < min_val)
return min_val;
139 if(val > max_val)
return max_val;
143TT_INLINE
float WWMath::Wrap(
float val,
float min,
float max)
145 if ( val >= max ) val -= (max-min);
146 if ( val < min ) val += (max-min);
156TT_INLINE
double WWMath::Wrap(
double val,
double min,
double max)
158 if ( val >= max ) val -= (max-min);
159 if ( val < min ) val += (max-min);
169TT_INLINE
float WWMath::Min(
float a,
float b)
175TT_INLINE
float WWMath::Max(
float a,
float b)
181TT_INLINE
float WWMath::Lerp(
float a,
float b,
float lerp )
183 return (a + (b - a)*lerp);
186TT_INLINE
double WWMath::Lerp(
double a,
double b,
float lerp )
188 return (a + (b - a)*lerp);
191TT_INLINE
int WWMath::Lerp(
int a,
int b,
float lerp )
193 return (a + (
int)((b - a)*lerp));
196TT_INLINE
bool WWMath::Is_Valid_Float(
float x)
198 unsigned long * plong = (
unsigned long *)(&x);
199 unsigned long exponent = ((*plong) & 0x7F800000) >> (32-9);
200 if (exponent == 0xFF) {
206TT_INLINE
bool WWMath::Is_Valid_Double(
double x)
208 unsigned long * plong = (
unsigned long *)(&x) + 1;
209 unsigned long exponent = ((*plong) & 0x7FF00000) >> (32-12);
210 if (exponent == 0x7FF) {
216TT_INLINE
long WWMath::Float_To_Long(
float f)
218 return _mm_cvtt_ss2si(_mm_load_ss(&f));
221TT_INLINE
long WWMath::Float_To_Long(
double f)
223 return _mm_cvttsd_si32(_mm_load_pd(&f));
226TT_INLINE
float WWMath::Cos(
float val)
231TT_INLINE
float WWMath::Sin(
float val)
236TT_INLINE
float WWMath::Fast_Sin(
float val)
238 val*=float(SIN_TABLE_SIZE) / (2.0f * WWMATH_PI);
239 int idx0=Float_To_Int_Floor(val);
241 float frac=val-(float)idx0;
242 idx0 = ((unsigned)idx0) & (SIN_TABLE_SIZE-1);
243 idx1 = ((unsigned)idx1) & (SIN_TABLE_SIZE-1);
244 return (1.0f - frac) * _FastSinTable[idx0] + frac * _FastSinTable[idx1];
247TT_INLINE
float WWMath::Fast_Inv_Sin(
float val)
249 return 1.0f / WWMath::Fast_Sin(val);
252TT_INLINE
float WWMath::Fast_Cos(
float val)
254 val+=(WWMATH_PI * 0.5f);
255 val*=float(SIN_TABLE_SIZE) / (2.0f * WWMATH_PI);
256 int idx0=Float_To_Int_Floor(val);
258 float frac=val-(float)idx0;
259 idx0 = ((unsigned)idx0) & (SIN_TABLE_SIZE-1);
260 idx1 = ((unsigned)idx1) & (SIN_TABLE_SIZE-1);
261 return (1.0f - frac) * _FastSinTable[idx0] + frac * _FastSinTable[idx1];
264TT_INLINE
float WWMath::Fast_Inv_Cos(
float val)
266 return 1.0f / WWMath::Fast_Cos(val);
269TT_INLINE
float WWMath::Fast_Acos(
float val)
271 if (WWMath::Fabs(val) > 0.975f) {
272 return WWMath::Acos(val);
274 val*=float(ARC_TABLE_SIZE/2);
275 int idx0=Float_To_Int_Floor(val);
277 float frac=val-(float)idx0;
278 idx0+=ARC_TABLE_SIZE/2;
279 idx1+=ARC_TABLE_SIZE/2;
280 TT_ASSERT((idx0 >= 0) && (idx0 < ARC_TABLE_SIZE));
281 TT_ASSERT((idx1 >= 0) && (idx1 < ARC_TABLE_SIZE));
282 return (1.0f - frac) * _FastAcosTable[idx0] + frac * _FastAcosTable[idx1];
285TT_INLINE
float WWMath::Acos(
float val)
287 return (
float)acos(val);
290TT_INLINE
float WWMath::Fast_Asin(
float val)
292 if (WWMath::Fabs(val) > 0.975f) {
293 return WWMath::Asin(val);
295 val*=float(ARC_TABLE_SIZE/2);
296 int idx0=Float_To_Int_Floor(val);
298 float frac=val-(float)idx0;
299 idx0+=ARC_TABLE_SIZE/2;
300 idx1+=ARC_TABLE_SIZE/2;
301 TT_ASSERT((idx0 >= 0) && (idx0 < ARC_TABLE_SIZE));
302 TT_ASSERT((idx1 >= 0) && (idx1 < ARC_TABLE_SIZE));
303 return (1.0f - frac) * _FastAsinTable[idx0] + frac * _FastAsinTable[idx1];
305TT_INLINE
float WWMath::Asin(
float val)
307 return (
float)asin(val);
310TT_INLINE
float WWMath::Sqrt(
float val)
315TT_INLINE
int WWMath::Float_To_Int_Chop(
const float& f)
317 int a = *
reinterpret_cast<const int*
>(&f);
319 int mantissa = (a&((1<<23)-1))|(1<<23);
320 int exponent = ((a&0x7fffffff)>>23)-127;
321 int r = ((
unsigned int)(mantissa)<<8)>>(31-exponent);
322 return ((r ^ (sign)) - sign ) &~ (exponent>>31);
325TT_INLINE
int WWMath::Float_To_Int_Floor (
const float& f)
327 int a = *
reinterpret_cast<const int*
>(&f);
330 int exponent = (a>>23)-127;
331 int expsign = ~(exponent>>31);
332 int imask = ( (1<<(31-(exponent))))-1;
333 int mantissa = (a&((1<<23)-1));
334 int r = ((
unsigned int)(mantissa|(1<<23))<<8)>>(31-exponent);
335#pragma warning(suppress: 6290)
336 r = ((r & expsign) ^ (sign)) + ((!((mantissa<<8)&imask)&(expsign^((a-1)>>31)))&sign);
340inline float WWMath::Inv_Sqrt(
float number)
342 return 1.f / sqrt(number);