orx  1.14
Portable Game Engine
orxMath.h
Go to the documentation of this file.
1 /* Orx - Portable Game Engine
2  *
3  * Copyright (c) 2008-2022 Orx-Project
4  *
5  * This software is provided 'as-is', without any express or implied
6  * warranty. In no event will the authors be held liable for any damages
7  * arising from the use of this software.
8  *
9  * Permission is granted to anyone to use this software for any purpose,
10  * including commercial applications, and to alter it and redistribute it
11  * freely, subject to the following restrictions:
12  *
13  * 1. The origin of this software must not be misrepresented; you must not
14  * claim that you wrote the original software. If you use this software
15  * in a product, an acknowledgment in the product documentation would be
16  * appreciated but is not required.
17  *
18  * 2. Altered source versions must be plainly marked as such, and must not be
19  * misrepresented as being the original software.
20  *
21  * 3. This notice may not be removed or altered from any source
22  * distribution.
23  */
24 
43 #ifndef _orxMATH_H_
44 #define _orxMATH_H_
45 
46 #include "orxInclude.h"
47 #include "debug/orxDebug.h"
48 
51 #include <math.h>
52 #ifdef __orxMSVC__
53  #include <intrin.h>
54 #endif /* __orxMSVC__ */
55 
56 
66 #define orxLERP(A, B, T) ((A) + ((T) * ((B) - (A))))
67 
68 
74 #define orxMIN(A, B) (((A) > (B)) ? (B) : (A))
75 
81 #define orxMAX(A, B) (((A) < (B)) ? (B) : (A))
82 
89 #define orxCLAMP(V, MIN, MAX) orxMAX(orxMIN(V, MAX), MIN)
90 
95 #define orxF2U(V) ((orxU32) (V))
96 
101 #define orxF2S(V) ((orxS32) (V))
102 
107 #define orxU2F(V) ((orxFLOAT)(V))
108 
113 #define orxS2F(V) ((orxFLOAT)(V))
114 
115 
116 /*** Module functions *** */
117 
121 extern orxDLLAPI void orxFASTCALL orxMath_InitRandom(orxU32 _u32Seed);
122 
128 extern orxDLLAPI orxFLOAT orxFASTCALL orxMath_GetRandomFloat(orxFLOAT _fMin, orxFLOAT _fMax);
129 
136 extern orxDLLAPI orxFLOAT orxFASTCALL orxMath_GetSteppedRandomFloat(orxFLOAT _fMin, orxFLOAT _fMax, orxFLOAT _fStep);
137 
143 extern orxDLLAPI orxU32 orxFASTCALL orxMath_GetRandomU32(orxU32 _u32Min, orxU32 _u32Max);
144 
151 extern orxDLLAPI orxU32 orxFASTCALL orxMath_GetSteppedRandomU32(orxU32 _u32Min, orxU32 _u32Max, orxU32 _u32Step);
152 
158 extern orxDLLAPI orxS32 orxFASTCALL orxMath_GetRandomS32(orxS32 _s32Min, orxS32 _s32Max);
159 
166 extern orxDLLAPI orxS32 orxFASTCALL orxMath_GetSteppedRandomS32(orxS32 _s32Min, orxS32 _s32Max, orxS32 _s32Step);
167 
173 extern orxDLLAPI orxU64 orxFASTCALL orxMath_GetRandomU64(orxU64 _u64Min, orxU64 _u64Max);
174 
181 extern orxDLLAPI orxU64 orxFASTCALL orxMath_GetSteppedRandomU64(orxU64 _u64Min, orxU64 _u64Max, orxU64 _u64Step);
182 
188 extern orxDLLAPI orxS64 orxFASTCALL orxMath_GetRandomS64(orxS64 _s64Min, orxS64 _s64Max);
189 
196 extern orxDLLAPI orxS64 orxFASTCALL orxMath_GetSteppedRandomS64(orxS64 _s64Min, orxS64 _s64Max, orxS64 _s64Step);
197 
201 extern orxDLLAPI void orxFASTCALL orxMath_GetRandomSeeds(orxU32 _au32Seeds[4]);
202 
206 extern orxDLLAPI void orxFASTCALL orxMath_SetRandomSeeds(const orxU32 _au32Seeds[4]);
207 
208 
209 /*** Inlined functions *** */
210 
215 static orxINLINE orxU32 orxMath_GetBitCount(orxU32 _u32Value)
216 {
217  orxU32 u32Result;
218 
219 #ifdef __orxMSVC__
220 
221  /* Uses intrinsic */
222  u32Result = __popcnt(_u32Value);
223 
224 #else /* __orxMSVC__ */
225 
226  /* Uses intrinsic */
227  u32Result = (orxU32)__builtin_popcount(_u32Value);
228 
229 #endif /* __orxMSVC__ */
230 
231  /* Done! */
232  return u32Result;
233 }
234 
239 static orxINLINE orxU32 orxMath_GetTrailingZeroCount(orxU32 _u32Value)
240 {
241  orxU32 u32Result;
242 
243  /* Checks */
244  orxASSERT(_u32Value != 0);
245 
246 #ifdef __orxMSVC__
247 
248  /* Uses intrinsic */
249  _BitScanForward((unsigned long *)&u32Result, _u32Value);
250 
251 #else /* __orxMSVC__ */
252 
253  /* Uses intrinsic */
254  u32Result = (orxU32)__builtin_ctz(_u32Value);
255 
256 #endif /* __orxMSVC__ */
257 
258  /* Done! */
259  return u32Result;
260 }
261 
266 static orxINLINE orxU32 orxMath_GetTrailingZeroCount64(orxU64 _u64Value)
267 {
268  orxU32 u32Result;
269 
270  /* Checks */
271  orxASSERT(_u64Value != 0);
272 
273 #ifdef __orxMSVC__
274 
275  #ifdef __orx64__
276 
277  /* Uses intrinsic */
278  _BitScanForward64((unsigned long *)&u32Result, _u64Value);
279 
280  #else /* __orx64__ */
281 
282  /* Updates result */
283  u32Result = ((_u64Value & 0xFFFFFFFFULL) == 0) ? orxMath_GetTrailingZeroCount((orxU32)(_u64Value >> 32)) + 32 : orxMath_GetTrailingZeroCount((orxU32)_u64Value);
284 
285  #endif /* __orx64__ */
286 
287 #else /* __orxMSVC__ */
288 
289  /* Uses intrinsic */
290  u32Result = (orxU32)__builtin_ctzll(_u64Value);
291 
292 #endif /* __orxMSVC__ */
293 
294  /* Done! */
295  return u32Result;
296 }
297 
302 static orxINLINE orxBOOL orxMath_IsPowerOfTwo(orxU32 _u32Value)
303 {
304  orxBOOL bResult;
305 
306  /* Updates result */
307  bResult = ((_u32Value & (_u32Value - 1)) == 0) ? orxTRUE : orxFALSE;
308 
309  /* Done! */
310  return bResult;
311 }
312 
317 static orxINLINE orxU32 orxMath_GetNextPowerOfTwo(orxU32 _u32Value)
318 {
319  orxU32 u32Result;
320 
321  /* Non-zero? */
322  if(_u32Value != 0)
323  {
324  /* Updates result */
325  u32Result = _u32Value - 1;
326  u32Result = u32Result | (u32Result >> 1);
327  u32Result = u32Result | (u32Result >> 2);
328  u32Result = u32Result | (u32Result >> 4);
329  u32Result = u32Result | (u32Result >> 8);
330  u32Result = u32Result | (u32Result >> 16);
331  u32Result++;
332  }
333  else
334  {
335  /* Updates result */
336  u32Result = 1;
337  }
338 
339  /* Done! */
340  return u32Result;
341 }
342 
349 static orxINLINE orxFLOAT orxMath_SmoothStep(orxFLOAT _fMin, orxFLOAT _fMax, orxFLOAT _fValue)
350 {
351  orxFLOAT fTemp, fResult;
352 
353  /* Gets normalized and clamped value */
354  fTemp = (_fValue - _fMin) / (_fMax - _fMin);
355  fTemp = orxCLAMP(fTemp, orxFLOAT_0, orxFLOAT_1);
356 
357  /* Gets smoothed result */
358  fResult = fTemp * fTemp * (orx2F(3.0f) - (orx2F(2.0f) * fTemp));
359 
360  /* Done! */
361  return fResult;
362 }
363 
370 static orxINLINE orxFLOAT orxMath_SmootherStep(orxFLOAT _fMin, orxFLOAT _fMax, orxFLOAT _fValue)
371 {
372  orxFLOAT fTemp, fResult;
373 
374  /* Gets normalized and clamped value */
375  fTemp = (_fValue - _fMin) / (_fMax - _fMin);
376  fTemp = orxCLAMP(fTemp, orxFLOAT_0, orxFLOAT_1);
377 
378  /* Gets smoothed result */
379  fResult = fTemp * fTemp * fTemp * (fTemp * ((fTemp * orx2F(6.0f)) - orx2F(15.0f)) + orx2F(10.0f));
380 
381  /* Done! */
382  return fResult;
383 }
384 
385 
386 /*** Math Definitions ***/
387 
388 #define orxMATH_KF_SQRT_2 orx2F(1.414213562f)
389 #define orxMATH_KF_EPSILON orx2F(0.0001f)
390 #define orxMATH_KF_TINY_EPSILON orx2F(1.0e-037f)
391 #define orxMATH_KF_MAX orx2F(3.402823466e+38F)
392 #define orxMATH_KF_2_PI orx2F(6.283185307f)
393 #define orxMATH_KF_PI orx2F(3.141592654f)
394 #define orxMATH_KF_PI_BY_2 orx2F(1.570796327f)
395 #define orxMATH_KF_PI_BY_4 orx2F(0.785398163f)
396 #define orxMATH_KF_DEG_TO_RAD orx2F(3.141592654f / 180.0f)
397 #define orxMATH_KF_RAD_TO_DEG orx2F(180.0f / 3.141592654f)
400 /*** Trigonometric function ***/
401 
406 static orxINLINE orxFLOAT orxMath_Sin(orxFLOAT _fOp)
407 {
408  orxFLOAT fResult;
409 
410  /* Updates result */
411  fResult = sinf(_fOp);
412 
413  /* Done! */
414  return fResult;
415 }
416 
421 static orxINLINE orxFLOAT orxMath_Cos(orxFLOAT _fOp)
422 {
423  orxFLOAT fResult;
424 
425  /* Updates result */
426  fResult = cosf(_fOp);
427 
428  /* Done! */
429  return fResult;
430 }
431 
436 static orxINLINE orxFLOAT orxMath_Tan(orxFLOAT _fOp)
437 {
438  orxFLOAT fResult;
439 
440  /* Updates result */
441  fResult = tanf(_fOp);
442 
443  /* Done! */
444  return fResult;
445 }
446 
451 static orxINLINE orxFLOAT orxMath_ACos(orxFLOAT _fOp)
452 {
453  orxFLOAT fResult;
454 
455  /* Updates result */
456  fResult = acosf(_fOp);
457 
458  /* Done! */
459  return fResult;
460 }
461 
466 static orxINLINE orxFLOAT orxMath_ASin(orxFLOAT _fOp)
467 {
468  orxFLOAT fResult;
469 
470  /* Updates result */
471  fResult = asinf(_fOp);
472 
473  /* Done! */
474  return fResult;
475 }
476 
482 static orxINLINE orxFLOAT orxMath_ATan(orxFLOAT _fOp1, orxFLOAT _fOp2)
483 {
484  orxFLOAT fResult;
485 
486  /* Updates result */
487  fResult = atan2f(_fOp1, _fOp2);
488 
489  /* Done! */
490  return fResult;
491 }
492 
493 
494 /*** Misc functions ***/
495 
500 static orxINLINE orxFLOAT orxMath_Sqrt(orxFLOAT _fOp)
501 {
502  orxFLOAT fResult;
503 
504  /* Updates result */
505  fResult = sqrtf(_fOp);
506 
507  /* Done! */
508  return fResult;
509 }
510 
515 static orxINLINE orxFLOAT orxMath_Floor(orxFLOAT _fOp)
516 {
517  orxFLOAT fResult;
518 
519  /* Updates result */
520  fResult = floorf(_fOp);
521 
522  /* Done! */
523  return fResult;
524 }
525 
530 static orxINLINE orxFLOAT orxMath_Ceil(orxFLOAT _fOp)
531 {
532  orxFLOAT fResult;
533 
534  /* Updates result */
535  fResult = ceilf(_fOp);
536 
537  /* Done! */
538  return fResult;
539 }
540 
545 static orxINLINE orxFLOAT orxMath_Round(orxFLOAT _fOp)
546 {
547  orxFLOAT fResult;
548 
549 #ifdef __orxMSVC__
550 
551  /* Updates result */
552  fResult = floorf(_fOp + orx2F(0.5f));
553 
554 #else /* __orxMSVC__ */
555 
556  /* Updates result */
557  fResult = rintf(_fOp);
558 
559 #endif /* __orxMSVC__ */
560 
561  /* Done! */
562  return fResult;
563 }
564 
570 static orxINLINE orxFLOAT orxMath_Mod(orxFLOAT _fOp1, orxFLOAT _fOp2)
571 {
572  orxFLOAT fResult;
573 
574  /* Updates result */
575  fResult = fmodf(_fOp1, _fOp2);
576 
577  /* Done! */
578  return fResult;
579 }
580 
586 static orxINLINE orxFLOAT orxMath_Pow(orxFLOAT _fOp, orxFLOAT _fExp)
587 {
588  orxFLOAT fResult;
589 
590  /* Updates result */
591  fResult = powf(_fOp, _fExp);
592 
593  /* Done! */
594  return fResult;
595 }
596 
601 static orxINLINE orxFLOAT orxMath_Abs(orxFLOAT _fOp)
602 {
603  orxFLOAT fResult;
604 
605  /* Updates result */
606  fResult = fabsf(_fOp);
607 
608  /* Done! */
609  return fResult;
610 }
611 
612 #endif /* _orxMATH_H_ */
613 
static orxINLINE orxFLOAT orxMath_Ceil(orxFLOAT _fOp)
Definition: orxMath.h:530
static orxINLINE orxFLOAT orxMath_SmoothStep(orxFLOAT _fMin, orxFLOAT _fMax, orxFLOAT _fValue)
Definition: orxMath.h:349
static orxINLINE orxFLOAT orxMath_Round(orxFLOAT _fOp)
Definition: orxMath.h:545
static orxINLINE orxU32 orxMath_GetBitCount(orxU32 _u32Value)
Definition: orxMath.h:215
static orxINLINE orxU32 orxMath_GetTrailingZeroCount(orxU32 _u32Value)
Definition: orxMath.h:239
static orxINLINE orxFLOAT orxMath_ASin(orxFLOAT _fOp)
Definition: orxMath.h:466
#define orxTRUE
Definition: orxType.h:198
static const orxFLOAT orxFLOAT_1
Definition: orxType.h:203
orxDLLAPI orxFLOAT orxFASTCALL orxMath_GetSteppedRandomFloat(orxFLOAT _fMin, orxFLOAT _fMax, orxFLOAT _fStep)
orxDLLAPI orxU64 orxFASTCALL orxMath_GetSteppedRandomU64(orxU64 _u64Min, orxU64 _u64Max, orxU64 _u64Step)
#define orxCLAMP(V, MIN, MAX)
Definition: orxMath.h:89
static orxINLINE orxFLOAT orxMath_Sqrt(orxFLOAT _fOp)
Definition: orxMath.h:500
#define orxFALSE
Definition: orxType.h:197
orxDLLAPI orxS32 orxFASTCALL orxMath_GetRandomS32(orxS32 _s32Min, orxS32 _s32Max)
static orxINLINE orxFLOAT orxMath_Sin(orxFLOAT _fOp)
Definition: orxMath.h:406
orxDLLAPI orxS32 orxFASTCALL orxMath_GetSteppedRandomS32(orxS32 _s32Min, orxS32 _s32Max, orxS32 _s32Step)
static orxINLINE orxFLOAT orxMath_Floor(orxFLOAT _fOp)
Definition: orxMath.h:515
static orxINLINE orxFLOAT orxMath_Abs(orxFLOAT _fOp)
Definition: orxMath.h:601
static orxINLINE orxU32 orxMath_GetNextPowerOfTwo(orxU32 _u32Value)
Definition: orxMath.h:317
orxDLLAPI orxU32 orxFASTCALL orxMath_GetSteppedRandomU32(orxU32 _u32Min, orxU32 _u32Max, orxU32 _u32Step)
orxDLLAPI orxS64 orxFASTCALL orxMath_GetSteppedRandomS64(orxS64 _s64Min, orxS64 _s64Max, orxS64 _s64Step)
static orxINLINE orxFLOAT orxMath_ACos(orxFLOAT _fOp)
Definition: orxMath.h:451
static orxINLINE orxU32 orxMath_GetTrailingZeroCount64(orxU64 _u64Value)
Definition: orxMath.h:266
orxDLLAPI void orxFASTCALL orxMath_SetRandomSeeds(const orxU32 _au32Seeds[4])
static orxINLINE orxFLOAT orxMath_Cos(orxFLOAT _fOp)
Definition: orxMath.h:421
orxDLLAPI void orxFASTCALL orxMath_GetRandomSeeds(orxU32 _au32Seeds[4])
orxDLLAPI void orxFASTCALL orxMath_InitRandom(orxU32 _u32Seed)
static orxINLINE orxFLOAT orxMath_Mod(orxFLOAT _fOp1, orxFLOAT _fOp2)
Definition: orxMath.h:570
orxDLLAPI orxU64 orxFASTCALL orxMath_GetRandomU64(orxU64 _u64Min, orxU64 _u64Max)
#define orxDLLAPI
Definition: orxDecl.h:370
static orxINLINE orxFLOAT orxMath_SmootherStep(orxFLOAT _fMin, orxFLOAT _fMax, orxFLOAT _fValue)
Definition: orxMath.h:370
orxDLLAPI orxFLOAT orxFASTCALL orxMath_GetRandomFloat(orxFLOAT _fMin, orxFLOAT _fMax)
orxDLLAPI orxS64 orxFASTCALL orxMath_GetRandomS64(orxS64 _s64Min, orxS64 _s64Max)
static orxINLINE orxFLOAT orxMath_Pow(orxFLOAT _fOp, orxFLOAT _fExp)
Definition: orxMath.h:586
static const orxFLOAT orxFLOAT_0
Definition: orxType.h:202
static orxINLINE orxFLOAT orxMath_ATan(orxFLOAT _fOp1, orxFLOAT _fOp2)
Definition: orxMath.h:482
orxDLLAPI orxU32 orxFASTCALL orxMath_GetRandomU32(orxU32 _u32Min, orxU32 _u32Max)
static orxINLINE orxFLOAT orxMath_Tan(orxFLOAT _fOp)
Definition: orxMath.h:436
#define orxASSERT(TEST,...)
Definition: orxDebug.h:372
static orxINLINE orxBOOL orxMath_IsPowerOfTwo(orxU32 _u32Value)
Definition: orxMath.h:302

Generated for orx by doxygen 1.8.11