wwmath.h 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. /*
  2. ** Command & Conquer Generals(tm)
  3. ** Copyright 2025 Electronic Arts Inc.
  4. **
  5. ** This program is free software: you can redistribute it and/or modify
  6. ** it under the terms of the GNU General Public License as published by
  7. ** the Free Software Foundation, either version 3 of the License, or
  8. ** (at your option) any later version.
  9. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ** GNU General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. /***********************************************************************************************
  19. *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
  20. ***********************************************************************************************
  21. * *
  22. * Project Name : WWMath *
  23. * *
  24. * $Archive:: /Commando/Code/wwmath/wwmath.h $*
  25. * *
  26. * Author:: Greg Hjelstrom *
  27. * *
  28. * $Modtime:: 3/16/00 8:28p $*
  29. * *
  30. * $Revision:: 40 $*
  31. * *
  32. *---------------------------------------------------------------------------------------------*
  33. * Functions: *
  34. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  35. #if defined(_MSC_VER)
  36. #pragma once
  37. #endif
  38. #ifndef WWMATH_H
  39. #define WWMATH_H
  40. #include "always.h"
  41. #include <math.h>
  42. #include <assert.h>
  43. /*
  44. ** Some global constants.
  45. */
  46. #define WWMATH_EPSILON 0.0001f
  47. #define WWMATH_EPSILON2 WWMATH_EPSILON * WWMATH_EPSILON
  48. #define WWMATH_PI 3.141592654f
  49. #define WWMATH_FLOAT_MAX (FLT_MAX)
  50. #define WWMATH_SQRT2 1.414213562f
  51. #define WWMATH_SQRT3 1.732050808f
  52. #define WWMATH_OOSQRT2 0.707106781f
  53. #define WWMATH_OOSQRT3 0.577350269f
  54. /*
  55. ** Macros to convert between degrees and radians
  56. */
  57. #ifndef RAD_TO_DEG
  58. #define RAD_TO_DEG(x) (((double)x)*180.0/WWMATH_PI)
  59. #endif
  60. #ifndef DEG_TO_RAD
  61. #define DEG_TO_RAD(x) (((double)x)*WWMATH_PI/180.0)
  62. #endif
  63. #ifndef RAD_TO_DEGF
  64. #define RAD_TO_DEGF(x) (((float)x)*180.0f/WWMATH_PI)
  65. #endif
  66. #ifndef DEG_TO_RADF
  67. #define DEG_TO_RADF(x) (((float)x)*WWMATH_PI/180.0f)
  68. #endif
  69. /*
  70. ** Some simple math functions which work on the built-in types.
  71. ** Include the various other header files in the WWMATH library
  72. ** in order to get matrices, quaternions, etc.
  73. */
  74. class WWMath
  75. {
  76. public:
  77. static float Fabs(float val) { return (float)fabs(val); }
  78. static float Sqrt(float val) { return (float)sqrt(val); }
  79. static float Inv_Sqrt(float val) { return 1.0f / (float)sqrt(val); }
  80. static float Sign(float val);
  81. static float Floor(float val) { return (float)floor(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 float Wrap(float val, float min = 0.0f, float max = 1.0f);
  88. static double Wrap(double val, double min = 0.0f, double max = 1.0f);
  89. static float Min(float a, float b);
  90. static float Max(float a, float b);
  91. static float Lerp(float a, float b, float lerp );
  92. static double Lerp(double a, double b, float lerp );
  93. static long Float_To_Long(float f);
  94. static long Float_To_Long(double f);
  95. static unsigned char Unit_Float_To_Byte(float f) { return (unsigned char)(f*255.0f); }
  96. static float Byte_To_Unit_Float(unsigned char byte) { return ((float)byte) / 255.0f; }
  97. static bool Is_Valid_Float(float x);
  98. static bool Is_Valid_Double(double x);
  99. };
  100. inline float WWMath::Sign(float val)
  101. {
  102. if (val > 0.0f) {
  103. return +1.0f;
  104. }
  105. if (val < 0.0f) {
  106. return -1.0f;
  107. }
  108. return 0.0f;
  109. }
  110. inline bool WWMath::Fast_Is_Float_Positive(const float & val)
  111. {
  112. return !((*(int *)(&val)) & 0x80000000);
  113. }
  114. inline float WWMath::Random_Float(float min,float max)
  115. {
  116. return Random_Float() * (max-min) + min;
  117. }
  118. inline float WWMath::Clamp(float val, float min /*= 0.0f*/, float max /*= 1.0f*/)
  119. {
  120. if(val < min) return min;
  121. if(val > max) return max;
  122. return val;
  123. }
  124. inline double WWMath::Clamp(double val, double min /*= 0.0f*/, double max /*= 1.0f*/)
  125. {
  126. if(val < min) return min;
  127. if(val > max) return max;
  128. return val;
  129. }
  130. inline float WWMath::Wrap(float val, float min /*= 0.0f*/, float max /*= 1.0f*/)
  131. {
  132. // Implemented as an if rather than a while, to long loops
  133. if ( val >= max ) val -= (max-min);
  134. if ( val < min ) val += (max-min);
  135. if ( val < min ) {
  136. val = min;
  137. }
  138. if ( val > max ) {
  139. val = max;
  140. }
  141. return val;
  142. }
  143. inline double WWMath::Wrap(double val, double min /*= 0.0f*/, double max /*= 1.0f*/)
  144. {
  145. // Implemented as an if rather than a while, to long loops
  146. if ( val >= max ) val -= (max-min);
  147. if ( val < min ) val += (max-min);
  148. if ( val < min ) {
  149. val = min;
  150. }
  151. if ( val > max ) {
  152. val = max;
  153. }
  154. return val;
  155. }
  156. inline float WWMath::Min(float a, float b)
  157. {
  158. if (a<b) return a;
  159. return b;
  160. }
  161. inline float WWMath::Max(float a, float b)
  162. {
  163. if (a>b) return a;
  164. return b;
  165. }
  166. inline float WWMath::Lerp(float a, float b, float lerp )
  167. {
  168. return (a + (b - a)*lerp);
  169. }
  170. inline double WWMath::Lerp(double a, double b, float lerp )
  171. {
  172. return (a + (b - a)*lerp);
  173. }
  174. inline long WWMath::Float_To_Long (float f)
  175. {
  176. #if defined(_MSC_VER) && defined(_M_IX86)
  177. long retval;
  178. __asm fld dword ptr [f]
  179. __asm fistp dword ptr [retval]
  180. return retval;
  181. #else
  182. return (long) f;
  183. #endif
  184. }
  185. inline long WWMath::Float_To_Long (double f)
  186. {
  187. #if defined(_MSC_VER) && defined(_M_IX86)
  188. long retval;
  189. __asm fld qword ptr [f]
  190. __asm fistp dword ptr [retval]
  191. return retval;
  192. #else
  193. return (long) f;
  194. #endif
  195. }
  196. inline bool WWMath::Is_Valid_Float(float x)
  197. {
  198. unsigned long * plong = (unsigned long *)(&x);
  199. unsigned long exponent = ((*plong) & 0x7F800000) >> (32-9);
  200. // if exponent is 0xFF, this is a NAN
  201. if (exponent == 0xFF) {
  202. return false;
  203. }
  204. return true;
  205. }
  206. inline bool WWMath::Is_Valid_Double(double x)
  207. {
  208. unsigned long * plong = (unsigned long *)(&x) + 1;
  209. unsigned long exponent = ((*plong) & 0x7FF00000) >> (32-12);
  210. // if exponent is 0x7FF, this is a NAN
  211. if (exponent == 0x7FF) {
  212. return false;
  213. }
  214. return true;
  215. }
  216. #endif