llmath.h 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361
  1. /**
  2. * @file llmath.h
  3. * @brief Useful math constants and macros.
  4. *
  5. * $LicenseInfo:firstyear=2000&license=viewergpl$
  6. *
  7. * Copyright (c) 2000-2009, Linden Research, Inc.
  8. *
  9. * Second Life Viewer Source Code
  10. * The source code in this file ("Source Code") is provided by Linden Lab
  11. * to you under the terms of the GNU General Public License, version 2.0
  12. * ("GPL"), unless you have obtained a separate licensing agreement
  13. * ("Other License"), formally executed by you and Linden Lab. Terms of
  14. * the GPL can be found in doc/GPL-license.txt in this distribution, or
  15. * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  16. *
  17. * There are special exceptions to the terms and conditions of the GPL as
  18. * it is applied to this Source Code. View the full text of the exception
  19. * in the file doc/FLOSS-exception.txt in this software distribution, or
  20. * online at
  21. * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  22. *
  23. * By copying, modifying or distributing this software, you acknowledge
  24. * that you have read and understood your obligations described above,
  25. * and agree to abide by those obligations.
  26. *
  27. * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  28. * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  29. * COMPLETENESS OR PERFORMANCE.
  30. * $/LicenseInfo$
  31. */
  32. #ifndef LLMATH_H
  33. #define LLMATH_H
  34. #include <cmath>
  35. #include <cstdlib>
  36. #include <limits>
  37. #include <vector>
  38. #if !LL_WINDOWS
  39. # include <stdint.h>
  40. #endif
  41. #include "hbintrinsics.h" // Includes appropriate intrinsics headers. HB
  42. // llsd.cpp uses llisnan() and llsdutil.cpp uses is_approx_equal_fraction(),
  43. // so these were moved from llmath.h into llcommonmath.h so that llcommon does
  44. // not depend on llmath. HB
  45. #include "llcommonmath.h"
  46. constexpr F32 GRAVITY = -9.8f;
  47. // Mathematical constants
  48. constexpr F32 F_PI = 3.1415926535897932384626433832795f;
  49. constexpr F32 F_TWO_PI = 6.283185307179586476925286766559f;
  50. constexpr F32 F_PI_BY_TWO = 1.5707963267948966192313216916398f;
  51. constexpr F32 F_SQRT_TWO_PI = 2.506628274631000502415765284811f;
  52. constexpr F32 F_E = 2.71828182845904523536f;
  53. constexpr F32 F_SQRT2 = 1.4142135623730950488016887242097f;
  54. constexpr F32 F_SQRT3 = 1.73205080756888288657986402541f;
  55. constexpr F32 OO_SQRT2 = 0.7071067811865475244008443621049f;
  56. constexpr F32 DEG_TO_RAD = 0.017453292519943295769236907684886f;
  57. constexpr F32 RAD_TO_DEG = 57.295779513082320876798154814105f;
  58. constexpr F32 F_LN10 = 2.3025850929940456840179914546844f;
  59. constexpr F32 OO_LN10 = 0.43429448190325182765112891891661f;
  60. constexpr F32 F_LN2 = 0.69314718056f;
  61. constexpr F32 OO_LN2 = 1.4426950408889634073599246810019f;
  62. constexpr F32 F_APPROXIMATELY_ZERO = 0.00001f;
  63. constexpr F32 F_ALMOST_ZERO = 0.0001f;
  64. constexpr F32 F_ALMOST_ONE = 1.f - F_ALMOST_ZERO;
  65. // Sets the gimballock threshold 0.025 away from +/-90 degrees.
  66. // Formula: GIMBAL_THRESHOLD = sinf(DEG_TO_RAD * gimbal_threshold_angle);
  67. constexpr F32 GIMBAL_THRESHOLD = 0.000436f;
  68. // BUG: Eliminate in favor of F_APPROXIMATELY_ZERO above ?
  69. constexpr F32 FP_MAG_THRESHOLD = 0.0000001f;
  70. // *TODO: replace with logic like is_approx_equal
  71. LL_INLINE bool is_approx_zero(F32 f)
  72. {
  73. return -F_APPROXIMATELY_ZERO < f && f < F_APPROXIMATELY_ZERO;
  74. }
  75. // These functions work by interpreting sign+exp+mantissa as an unsigned
  76. // integer.
  77. // For example:
  78. // x = <sign>1 <exponent>00000010 <mantissa>00000000000000000000000
  79. // y = <sign>1 <exponent>00000001 <mantissa>11111111111111111111111
  80. //
  81. // interpreted as ints =
  82. // x = 10000001000000000000000000000000
  83. // y = 10000000111111111111111111111111
  84. // which is clearly a different of 1 in the least significant bit.
  85. // Values with the same exponent can be trivially shown to work.
  86. //
  87. // WARNING: Denormals of opposite sign do not work
  88. // x = <sign>1 <exponent>00000000 <mantissa>00000000000000000000001
  89. // y = <sign>0 <exponent>00000000 <mantissa>00000000000000000000001
  90. // Although these values differ by 2 in the LSB, the sign bit makes the int
  91. // comparison fail.
  92. //
  93. // WARNING: NaNs can compare equal
  94. // There is no special treatment of exceptional values like NaNs
  95. //
  96. // WARNING: Infinity is comparable with F32_MAX and negative infinity is
  97. // comparable with F32_MIN
  98. LL_INLINE bool is_zero(F32 x)
  99. {
  100. return (*(U32*)(&x) & 0x7fffffff) == 0;
  101. }
  102. LL_INLINE bool is_approx_equal(F32 x, F32 y)
  103. {
  104. constexpr S32 COMPARE_MANTISSA_UP_TO_BIT = 0x02;
  105. return (std::abs((S32)((U32&)x - (U32&)y)) < COMPARE_MANTISSA_UP_TO_BIT);
  106. }
  107. LL_INLINE bool is_approx_equal(F64 x, F64 y)
  108. {
  109. constexpr S64 COMPARE_MANTISSA_UP_TO_BIT = 0x02;
  110. return (std::abs((S32)((U64&)x - (U64&)y)) < COMPARE_MANTISSA_UP_TO_BIT);
  111. }
  112. LL_INLINE S32 lltrunc(F32 f)
  113. {
  114. return (S32)f;
  115. }
  116. LL_INLINE S32 lltrunc(F64 f)
  117. {
  118. return (S32)f;
  119. }
  120. LL_INLINE S32 llfloor(F32 f)
  121. {
  122. return (S32)floorf(f);
  123. }
  124. LL_INLINE S32 llceil(F32 f)
  125. {
  126. // This could probably be optimized, but this works.
  127. return (S32)ceilf(f);
  128. }
  129. // Does an arithmetic round (0.5 always rounds up)
  130. LL_INLINE S32 ll_round(F32 val)
  131. {
  132. return llfloor(val + 0.5f);
  133. }
  134. LL_INLINE F32 ll_round(F32 val, F32 nearest)
  135. {
  136. return F32(floorf(val * (1.f / nearest) + 0.5f)) * nearest;
  137. }
  138. LL_INLINE F64 ll_round(F64 val, F64 nearest)
  139. {
  140. return F64(floor(val * (1.0 / nearest) + 0.5)) * nearest;
  141. }
  142. LL_INLINE S32 ll_roundp(F32 val)
  143. {
  144. return val + 0.5f;
  145. }
  146. LL_INLINE S32 ll_roundp(F64 val)
  147. {
  148. return val + 0.5;
  149. }
  150. LL_INLINE F32 snap_to_sig_figs(F32 foo, S32 sig_figs)
  151. {
  152. // compute the power of ten
  153. F32 bar = 1.f;
  154. for (S32 i = 0; i < sig_figs; ++i)
  155. {
  156. bar *= 10.f;
  157. }
  158. #if 0 // The ll_round() implementation sucks. Do not use it.
  159. F32 new_foo = (F32)ll_round(foo * bar);
  160. #else
  161. F32 sign = (foo > 0.f) ? 1.f : -1.f;
  162. F32 new_foo = F32(S64(foo * bar + sign * 0.5f));
  163. new_foo /= bar;
  164. #endif
  165. return new_foo;
  166. }
  167. LL_INLINE F32 lerp(F32 a, F32 b, F32 u)
  168. {
  169. return a + (b - a) * u;
  170. }
  171. LL_INLINE F32 ramp(F32 x, F32 a, F32 b)
  172. {
  173. return a == b ? 0.f : (a - x) / (a - b);
  174. }
  175. LL_INLINE F32 rescale(F32 x, F32 x1, F32 x2, F32 y1, F32 y2)
  176. {
  177. return lerp(y1, y2, ramp(x, x1, x2));
  178. }
  179. LL_INLINE F32 clamp_rescale(F32 x, F32 x1, F32 x2, F32 y1, F32 y2)
  180. {
  181. if (y1 < y2)
  182. {
  183. return llclamp(rescale(x, x1, x2, y1, y2), y1, y2);
  184. }
  185. return llclamp(rescale(x, x1, x2, y1, y2), y2, y1);
  186. }
  187. LL_INLINE F32 cubic_step(F32 x)
  188. {
  189. x = llclampf(x);
  190. return (x * x) * (3.f - 2.f * x);
  191. }
  192. // SDK - Renamed this to get_lower_power_two, since this is what this actually
  193. // does.
  194. LL_INLINE U32 get_lower_power_two(U32 val, U32 max_power_two)
  195. {
  196. if (!max_power_two)
  197. {
  198. max_power_two = 1 << 31;
  199. }
  200. if (max_power_two & (max_power_two - 1))
  201. {
  202. return 0;
  203. }
  204. for ( ; val < max_power_two; max_power_two >>= 1) ;
  205. return max_power_two;
  206. }
  207. // Calculate next highest power of two, limited by max_power_two. This is taken
  208. // from a brilliant little code snipped on:
  209. // http://acius2.blogspot.fr/2007/11/calculating-next-power-of-2.html
  210. // Basically we convert the binary to a solid string of 1's with the same
  211. // number of digits, then add one. We subtract 1 initially to handle the case
  212. // where the number passed in is actually a power of two.
  213. // WARNING: this only works with 32 bits integers.
  214. LL_INLINE U32 get_next_power_two(U32 val, U32 max_power_two)
  215. {
  216. if (!max_power_two)
  217. {
  218. max_power_two = 1 << 31;
  219. }
  220. if (val >= max_power_two)
  221. {
  222. return max_power_two;
  223. }
  224. --val;
  225. val = (val >> 1) | val;
  226. val = (val >> 2) | val;
  227. val = (val >> 4) | val;
  228. val = (val >> 8) | val;
  229. val = (val >> 16) | val;
  230. return ++val;
  231. }
  232. // Get the gaussian value given the linear distance from axis x and guassian
  233. // value o
  234. LL_INLINE F32 llgaussian(F32 x, F32 o)
  235. {
  236. return 1.f / (F_SQRT_TWO_PI * o) * powf(F_E, - (x * x) / (2 * o * o));
  237. }
  238. // This converts a linear value to a SRGB non-linear value. Useful for gamma
  239. // correction and such.
  240. LL_INLINE F32 linearToSRGB(F32 val)
  241. {
  242. if (val < 0.0031308f)
  243. {
  244. return val * 12.92f;
  245. }
  246. return 1.055f * powf(val, 1.f / 2.4f) - 0.055f;
  247. }
  248. // This converts a linear value to a SRGB non-linear value. Useful for gamma
  249. // correction and such.
  250. LL_INLINE F32 sRGBtoLinear(F32 val)
  251. {
  252. if (val < 0.04045f)
  253. {
  254. constexpr F32 k1 = 1.f / 12.92f;
  255. return val * k1;
  256. }
  257. constexpr F32 k2 = 1.f / 1.055f;
  258. return powf((val + 0.055f) * k2, 2.4f);
  259. }
  260. ///////////////////////////////////////////////////////////////////////////////
  261. // Fast exp
  262. // Implementation of fast expf() approximation (from a paper by Nicol N.
  263. // Schraudolph: http://www.inf.ethz.ch/~schraudo/pubs/exp.pdf
  264. #ifndef LL_BIG_ENDIAN
  265. # error Unknown endianness. Did you omit to include llpreprocessor.h ?
  266. #endif
  267. static union
  268. {
  269. double d;
  270. struct
  271. {
  272. #if LL_BIG_ENDIAN
  273. S32 i, j;
  274. #else
  275. S32 j, i;
  276. #endif
  277. } n;
  278. } LLECO; // Not sure what the name means
  279. #define LL_EXP_A (1048576 * OO_LN2) // Use 1512775 for integer
  280. #define LL_EXP_C (60801) // This value of C good for -4 < y < 4
  281. #define LL_FAST_EXP(y) (LLECO.n.i = ll_round(F32(LL_EXP_A*(y))) + (1072693248 - LL_EXP_C), LLECO.d)
  282. LL_INLINE F32 llfastpow(F32 x, F32 y)
  283. {
  284. return (F32)(LL_FAST_EXP(y * logf(x)));
  285. }
  286. ///////////////////////////////////////////////////////////////////////////////
  287. // Include the simd math headers
  288. #if LL_GNUC
  289. // gcc v5.0+ spews stupid warnings about "maybe uninitialized" variables
  290. # pragma GCC diagnostic push
  291. # pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
  292. #endif
  293. #include "llsimdtypes.h"
  294. #include "llquaternion.h"
  295. #include "llvector4logical.h"
  296. #include "llvector4a.h"
  297. #include "llmatrix3a.h"
  298. #include "llmatrix3.h"
  299. #include "llquaternion2.h"
  300. #define LL_INL_INCLUDE
  301. #include "llvector4a.inl"
  302. #include "llmatrix3a.inl"
  303. #include "llquaternion2.inl"
  304. #undef LL_INL_INCLUDE
  305. #if LL_GNUC
  306. # pragma GCC diagnostic pop
  307. #endif
  308. #endif // LLMATH_H