math.h 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627
  1. /*
  2. * Copyright 2011-2018 Branimir Karadzic. All rights reserved.
  3. * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
  4. */
  5. // FPU math lib
  6. #ifndef BX_MATH_H_HEADER_GUARD
  7. #define BX_MATH_H_HEADER_GUARD
  8. #include "bx.h"
  9. #include "uint32_t.h"
  10. namespace bx
  11. {
  12. constexpr float kPi = 3.1415926535897932384626433832795f;
  13. constexpr float kPi2 = 6.2831853071795864769252867665590f;
  14. constexpr float kInvPi = 1.0f/kPi;
  15. constexpr float kPiHalf = 1.5707963267948966192313216916398f;
  16. constexpr float kPiQuarter = 0.7853981633974483096156608458199f;
  17. constexpr float kSqrt2 = 1.4142135623730950488016887242097f;
  18. constexpr float kLogNat10 = 2.3025850929940456840179914546844f;
  19. constexpr float kInvLogNat2 = 1.4426950408889634073599246810019f;
  20. constexpr float kLogNat2Hi = 0.6931471805599453094172321214582f;
  21. constexpr float kLogNat2Lo = 1.90821492927058770002e-10f;
  22. constexpr float kE = 2.7182818284590452353602874713527f;
  23. constexpr float kNearZero = 1.0f/float(1 << 28);
  24. constexpr float kFloatMin = 1.175494e-38f;
  25. constexpr float kFloatMax = 3.402823e+38f;
  26. extern const float kInfinity;
  27. ///
  28. typedef float (*LerpFn)(float _a, float _b, float _t);
  29. ///
  30. struct Handness
  31. {
  32. enum Enum
  33. {
  34. Left,
  35. Right,
  36. };
  37. };
  38. ///
  39. struct NearFar
  40. {
  41. enum Enum
  42. {
  43. Default,
  44. Reverse,
  45. };
  46. };
  47. ///
  48. struct Vec3
  49. {
  50. float x, y, z;
  51. };
  52. /// Returns converted the argument _deg to radians.
  53. ///
  54. BX_CONST_FUNC float toRad(float _deg);
  55. /// Returns converted the argument _rad to degrees.
  56. ///
  57. BX_CONST_FUNC float toDeg(float _rad);
  58. /// Reinterprets the bit pattern of _a as uint32_t.
  59. ///
  60. BX_CONST_FUNC uint32_t floatToBits(float _a);
  61. /// Reinterprets the bit pattern of _a as float.
  62. ///
  63. BX_CONST_FUNC float bitsToFloat(uint32_t _a);
  64. /// Reinterprets the bit pattern of _a as uint64_t.
  65. ///
  66. BX_CONST_FUNC uint64_t doubleToBits(double _a);
  67. /// Reinterprets the bit pattern of _a as double.
  68. ///
  69. BX_CONST_FUNC double bitsToDouble(uint64_t _a);
  70. /// Returns sortable floating point value.
  71. ///
  72. BX_CONST_FUNC uint32_t floatFlip(uint32_t _value);
  73. /// Returns true if _f is a number that is NaN.
  74. ///
  75. BX_CONST_FUNC bool isNan(float _f);
  76. /// Returns true if _f is a number that is NaN.
  77. ///
  78. BX_CONST_FUNC bool isNan(double _f);
  79. /// Returns true if _f is not infinite and is not a NaN.
  80. ///
  81. BX_CONST_FUNC bool isFinite(float _f);
  82. /// Returns true if _f is not infinite and is not a NaN.
  83. ///
  84. BX_CONST_FUNC bool isFinite(double _f);
  85. /// Returns true if _f is infinite and is not a NaN.
  86. ///
  87. BX_CONST_FUNC bool isInfinite(float _f);
  88. /// Returns true if _f is infinite and is not a NaN.
  89. ///
  90. BX_CONST_FUNC bool isInfinite(double _f);
  91. /// Returns the largest integer value not greater than _f.
  92. ///
  93. BX_CONST_FUNC float floor(float _f);
  94. /// Returns the smallest integer value not less than _f.
  95. ///
  96. BX_CONST_FUNC float ceil(float _f);
  97. /// Returns the nearest integer value to _f, rounding halfway cases away from zero,
  98. ///
  99. BX_CONST_FUNC float round(float _f);
  100. /// Returns linear interpolation between two values _a and _b.
  101. ///
  102. BX_CONSTEXPR_FUNC float lerp(float _a, float _b, float _t);
  103. /// Returns the sign of _a.
  104. ///
  105. BX_CONSTEXPR_FUNC float sign(float _a);
  106. /// Returns the absolute of _a.
  107. ///
  108. BX_CONSTEXPR_FUNC float abs(float _a);
  109. /// Returns the square of _a.
  110. ///
  111. BX_CONSTEXPR_FUNC float square(float _a);
  112. /// Returns the cosine of the argument _a.
  113. ///
  114. BX_CONST_FUNC float sin(float _a);
  115. /// Returns hyperbolic sine of the argument _a.
  116. ///
  117. BX_CONST_FUNC float sinh(float _a);
  118. /// Returns radian angle between -pi/2 and +pi/2 whose sine is _a.
  119. ///
  120. BX_CONST_FUNC float asin(float _a);
  121. /// Returns the cosine of the argument _a.
  122. ///
  123. BX_CONST_FUNC float cos(float _a);
  124. /// Returns hyperbolic cosine of the argument _a.
  125. ///
  126. BX_CONST_FUNC float cosh(float _a);
  127. /// Returns radian angle between 0 and pi whose cosine is _a.
  128. ///
  129. BX_CONST_FUNC float acos(float _a);
  130. /// Returns the circular tangent of the radian argument _a.
  131. ///
  132. BX_CONST_FUNC float tan(float _a);
  133. /// Returns hyperbolic tangent of the argument _a.
  134. ///
  135. BX_CONST_FUNC float tanh(float _a);
  136. /// Returns radian angle between -pi/2 and +pi/2 whose tangent is _a.
  137. ///
  138. BX_CONST_FUNC float atan(float _a);
  139. /// Retruns the inverse tangent of _y/_x.
  140. ///
  141. BX_CONST_FUNC float atan2(float _y, float _x);
  142. /// Computes _a raised to the _b power.
  143. ///
  144. BX_CONST_FUNC float pow(float _a, float _b);
  145. /// Returns the result of multiplying _a by 2 raised to the power of the exponent.
  146. ///
  147. BX_CONST_FUNC float ldexp(float _a, int32_t _b);
  148. /// Returns decomposed given floating point value _a into a normalized fraction and
  149. /// an integral power of two.
  150. ///
  151. float frexp(float _a, int32_t* _outExp);
  152. /// Returns e (2.71828...) raised to the _a power.
  153. ///
  154. BX_CONST_FUNC float exp(float _a);
  155. /// Returns 2 raised to the _a power.
  156. ///
  157. BX_CONST_FUNC float exp2(float _a);
  158. /// Returns the base e (2.71828...) logarithm of _a.
  159. ///
  160. BX_CONST_FUNC float log(float _a);
  161. /// Returns the base 2 logarithm of _a.
  162. ///
  163. BX_CONST_FUNC float log2(float _a);
  164. /// Returns the square root of _a.
  165. ///
  166. BX_CONST_FUNC float sqrt(float _a);
  167. /// Returns reciprocal square root of _a.
  168. ///
  169. BX_CONST_FUNC float rsqrt(float _a);
  170. /// Returns the nearest integer not greater in magnitude than _a.
  171. ///
  172. BX_CONSTEXPR_FUNC float trunc(float _a);
  173. /// Returns the fractional (or decimal) part of _a, which is greater than or equal to 0
  174. /// and less than 1.
  175. ///
  176. BX_CONSTEXPR_FUNC float fract(float _a);
  177. /// Returns result of multipla and add (_a * _b + _c).
  178. ///
  179. BX_CONSTEXPR_FUNC float mad(float _a, float _b, float _c);
  180. /// Returns the floating-point remainder of the division operation _a/_b.
  181. ///
  182. BX_CONST_FUNC float mod(float _a, float _b);
  183. ///
  184. BX_CONSTEXPR_FUNC bool equal(float _a, float _b, float _epsilon);
  185. ///
  186. BX_CONST_FUNC bool equal(const float* _a, const float* _b, uint32_t _num, float _epsilon);
  187. ///
  188. BX_CONST_FUNC float wrap(float _a, float _wrap);
  189. ///
  190. BX_CONSTEXPR_FUNC float step(float _edge, float _a);
  191. ///
  192. BX_CONSTEXPR_FUNC float pulse(float _a, float _start, float _end);
  193. ///
  194. BX_CONSTEXPR_FUNC float smoothStep(float _a);
  195. ///
  196. BX_CONSTEXPR_FUNC float bias(float _time, float _bias);
  197. ///
  198. BX_CONSTEXPR_FUNC float gain(float _time, float _gain);
  199. ///
  200. BX_CONST_FUNC float angleDiff(float _a, float _b);
  201. /// Returns shortest distance linear interpolation between two angles.
  202. ///
  203. BX_CONST_FUNC float angleLerp(float _a, float _b, float _t);
  204. ///
  205. Vec3 load(const void* _ptr);
  206. ///
  207. void store(void* _ptr, const Vec3& _a);
  208. ///
  209. BX_CONSTEXPR_FUNC Vec3 abs(const Vec3& _a);
  210. ///
  211. BX_CONSTEXPR_FUNC Vec3 neg(const Vec3& _a);
  212. ///
  213. BX_CONSTEXPR_FUNC Vec3 add(const Vec3& _a, const Vec3& _b);
  214. ///
  215. BX_CONSTEXPR_FUNC Vec3 add(const Vec3& _a, float _b);
  216. ///
  217. BX_CONSTEXPR_FUNC Vec3 sub(const Vec3& _a, const Vec3& _b);
  218. ///
  219. BX_CONSTEXPR_FUNC Vec3 sub(const Vec3& _a, float _b);
  220. ///
  221. BX_CONSTEXPR_FUNC Vec3 mul(const Vec3& _a, const Vec3& _b);
  222. ///
  223. BX_CONSTEXPR_FUNC Vec3 mul(const Vec3& _a, float _b);
  224. ///
  225. BX_CONSTEXPR_FUNC Vec3 mad(const Vec3& _a, const Vec3& _b, const Vec3& _c);
  226. ///
  227. BX_CONSTEXPR_FUNC float dot(const Vec3& _a, const Vec3& _b);
  228. ///
  229. BX_CONSTEXPR_FUNC Vec3 cross(const Vec3& _a, const Vec3& _b);
  230. ///
  231. BX_CONST_FUNC float length(const Vec3& _a);
  232. ///
  233. BX_CONSTEXPR_FUNC Vec3 lerp(const Vec3& _a, const Vec3& _b, float _t);
  234. ///
  235. BX_CONSTEXPR_FUNC Vec3 lerp(const Vec3& _a, const Vec3& _b, const Vec3& _t);
  236. ///
  237. BX_CONST_FUNC Vec3 normalize(const Vec3& _a);
  238. ///
  239. BX_CONSTEXPR_FUNC Vec3 min(const Vec3& _a, const Vec3& _b);
  240. ///
  241. BX_CONSTEXPR_FUNC Vec3 max(const Vec3& _a, const Vec3& _b);
  242. ///
  243. BX_CONSTEXPR_FUNC Vec3 rcp(const Vec3& _a);
  244. ///
  245. void calcTangentFrame(Vec3& _outT, Vec3& _outB, const Vec3& _n);
  246. ///
  247. void calcTangentFrame(Vec3& _outT, Vec3& _outB, const Vec3& _n, float _angle);
  248. ///
  249. BX_CONST_FUNC Vec3 fromLatLong(float _u, float _v);
  250. ///
  251. void toLatLong(float* _outU, float* _outV, const Vec3& _dir);
  252. ///
  253. void vec3Add(float* _result, const float* _a, const float* _b);
  254. ///
  255. void vec3Sub(float* _result, const float* _a, const float* _b);
  256. ///
  257. void vec3Mul(float* _result, const float* _a, const float* _b);
  258. ///
  259. void vec3Mul(float* _result, const float* _a, float _b);
  260. ///
  261. float vec3Dot(const float* _a, const float* _b);
  262. ///
  263. void vec3Cross(float* _result, const float* _a, const float* _b);
  264. ///
  265. float vec3Length(const float* _a);
  266. ///
  267. float vec3Norm(float* _result, const float* _a);
  268. /// Calculate tangent frame from normal.
  269. ///
  270. void vec3TangentFrame(const float* _n, float* _t, float* _b);
  271. /// Calculate tangent frame from normal and angle.
  272. ///
  273. void vec3TangentFrame(const float* _n, float* _t, float* _b, float _angle);
  274. ///
  275. void vec3FromLatLong(float* _vec, float _u, float _v);
  276. /// Convert direction to 2D latitude and longitude.
  277. ///
  278. /// @param[out] _outU U-coordinate.
  279. /// @param[out] _outV V-coordinate.
  280. /// @param[in] _dir Normalized direction vector.
  281. ///
  282. void vec3ToLatLong(float* _outU, float* _outV, const float* _dir);
  283. ///
  284. void quatIdentity(float* _result);
  285. ///
  286. void quatMove(float* _result, const float* _a);
  287. ///
  288. void quatMulXYZ(float* _result, const float* _qa, const float* _qb);
  289. ///
  290. void quatMul(float* _result, const float* _qa, const float* _qb);
  291. ///
  292. void quatInvert(float* _result, const float* _quat);
  293. ///
  294. float quatDot(const float* _a, const float* _b);
  295. ///
  296. void quatNorm(float* _result, const float* _quat);
  297. ///
  298. void quatToEuler(float* _result, const float* _quat);
  299. ///
  300. void quatRotateAxis(float* _result, const float* _axis, float _angle);
  301. ///
  302. void quatRotateX(float* _result, float _ax);
  303. ///
  304. void quatRotateY(float* _result, float _ay);
  305. ///
  306. void quatRotateZ(float* _result, float _az);
  307. ///
  308. void vec3MulQuat(float* _result, const float* _vec, const float* _quat);
  309. ///
  310. void mtxIdentity(float* _result);
  311. ///
  312. void mtxTranslate(float* _result, float _tx, float _ty, float _tz);
  313. ///
  314. void mtxScale(float* _result, float _sx, float _sy, float _sz);
  315. ///
  316. void mtxScale(float* _result, float _scale);
  317. ///
  318. void mtxFromNormal(float* _result, const float* _normal, float _scale, const float* _pos);
  319. ///
  320. void mtxFromNormal(float* _result, const float* _normal, float _scale, const float* _pos, float _angle);
  321. ///
  322. void mtxQuat(float* _result, const float* _quat);
  323. ///
  324. void mtxQuatTranslation(float* _result, const float* _quat, const float* _translation);
  325. ///
  326. void mtxQuatTranslationHMD(float* _result, const float* _quat, const float* _translation);
  327. ///
  328. void mtxLookAtLh(float* _result, const Vec3& _eye, const Vec3& _at, const Vec3& _up = { 0.0f, 1.0f, 0.0f });
  329. ///
  330. void mtxLookAtRh(float* _result, const Vec3& _eye, const Vec3& _at, const Vec3& _up = { 0.0f, 1.0f, 0.0f });
  331. ///
  332. void mtxLookAt(float* _result, const Vec3& _eye, const Vec3& _at, const Vec3& _up = { 0.0f, 1.0f, 0.0f });
  333. ///
  334. void mtxProj(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, float _far, bool _oglNdc);
  335. ///
  336. void mtxProj(float* _result, const float _fov[4], float _near, float _far, bool _oglNdc);
  337. ///
  338. void mtxProj(float* _result, float _fovy, float _aspect, float _near, float _far, bool _oglNdc);
  339. ///
  340. void mtxProjLh(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, float _far, bool _oglNdc);
  341. ///
  342. void mtxProjLh(float* _result, const float _fov[4], float _near, float _far, bool _oglNdc);
  343. ///
  344. void mtxProjLh(float* _result, float _fovy, float _aspect, float _near, float _far, bool _oglNdc);
  345. ///
  346. void mtxProjRh(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, float _far, bool _oglNdc);
  347. ///
  348. void mtxProjRh(float* _result, const float _fov[4], float _near, float _far, bool _oglNdc);
  349. ///
  350. void mtxProjRh(float* _result, float _fovy, float _aspect, float _near, float _far, bool _oglNdc);
  351. ///
  352. void mtxProjInf(float* _result, const float _fov[4], float _near, bool _oglNdc);
  353. ///
  354. void mtxProjInf(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, bool _oglNdc);
  355. ///
  356. void mtxProjInf(float* _result, float _fovy, float _aspect, float _near, bool _oglNdc);
  357. ///
  358. void mtxProjInfLh(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, bool _oglNdc);
  359. ///
  360. void mtxProjInfLh(float* _result, const float _fov[4], float _near, bool _oglNdc);
  361. ///
  362. void mtxProjInfLh(float* _result, float _fovy, float _aspect, float _near, bool _oglNdc);
  363. ///
  364. void mtxProjInfRh(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, bool _oglNdc);
  365. ///
  366. void mtxProjInfRh(float* _result, const float _fov[4], float _near, bool _oglNdc);
  367. ///
  368. void mtxProjInfRh(float* _result, float _fovy, float _aspect, float _near, bool _oglNdc);
  369. ///
  370. void mtxProjRevInfLh(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, bool _oglNdc);
  371. ///
  372. void mtxProjRevInfLh(float* _result, const float _fov[4], float _near, bool _oglNdc);
  373. ///
  374. void mtxProjRevInfLh(float* _result, float _fovy, float _aspect, float _near, bool _oglNdc);
  375. ///
  376. void mtxProjRevInfRh(float* _result, float _ut, float _dt, float _lt, float _rt, float _near, bool _oglNdc);
  377. ///
  378. void mtxProjRevInfRh(float* _result, const float _fov[4], float _near, bool _oglNdc);
  379. ///
  380. void mtxProjRevInfRh(float* _result, float _fovy, float _aspect, float _near, bool _oglNdc);
  381. ///
  382. void mtxOrtho(float* _result, float _left, float _right, float _bottom, float _top, float _near, float _far, float _offset, bool _oglNdc);
  383. ///
  384. void mtxOrthoLh(float* _result, float _left, float _right, float _bottom, float _top, float _near, float _far, float _offset, bool _oglNdc);
  385. ///
  386. void mtxOrthoRh(float* _result, float _left, float _right, float _bottom, float _top, float _near, float _far, float _offset, bool _oglNdc);
  387. ///
  388. void mtxRotateX(float* _result, float _ax);
  389. ///
  390. void mtxRotateY(float* _result, float _ay);
  391. ///
  392. void mtxRotateZ(float* _result, float _az);
  393. ///
  394. void mtxRotateXY(float* _result, float _ax, float _ay);
  395. ///
  396. void mtxRotateXYZ(float* _result, float _ax, float _ay, float _az);
  397. ///
  398. void mtxRotateZYX(float* _result, float _ax, float _ay, float _az);
  399. ///
  400. void mtxSRT(float* _result, float _sx, float _sy, float _sz, float _ax, float _ay, float _az, float _tx, float _ty, float _tz);
  401. ///
  402. void vec3MulMtx(float* _result, const float* _vec, const float* _mat);
  403. ///
  404. void vec3MulMtxXyz0(float* _result, const float* _vec, const float* _mat);
  405. ///
  406. void vec3MulMtxH(float* _result, const float* _vec, const float* _mat);
  407. ///
  408. void vec4Mul(float* _result, const float* _a, const float* _b);
  409. ///
  410. void vec4Mul(float* _result, const float* _a, float _b);
  411. ///
  412. void vec4MulMtx(float* _result, const float* _vec, const float* _mat);
  413. ///
  414. void mtxMul(float* _result, const float* _a, const float* _b);
  415. ///
  416. void mtxTranspose(float* _result, const float* _a);
  417. ///
  418. void mtx3Inverse(float* _result, const float* _a);
  419. ///
  420. void mtxInverse(float* _result, const float* _a);
  421. /// Convert LH to RH projection matrix and vice versa.
  422. ///
  423. void mtxProjFlipHandedness(float* _dst, const float* _src);
  424. /// Convert LH to RH view matrix and vice versa.
  425. ///
  426. void mtxViewFlipHandedness(float* _dst, const float* _src);
  427. ///
  428. void calcNormal(float _result[3], const float _va[3], const float _vb[3], const float _vc[3]);
  429. ///
  430. void calcPlane(float _result[4], const float _va[3], const float _vb[3], const float _vc[3]);
  431. ///
  432. void calcPlane(float _result[4], const float _normal[3], const float _pos[3]);
  433. ///
  434. void calcLinearFit2D(float _result[2], const void* _points, uint32_t _stride, uint32_t _numPoints);
  435. ///
  436. void calcLinearFit3D(float _result[3], const void* _points, uint32_t _stride, uint32_t _numPoints);
  437. ///
  438. void rgbToHsv(float _hsv[3], const float _rgb[3]);
  439. ///
  440. void hsvToRgb(float _rgb[3], const float _hsv[3]);
  441. ///
  442. BX_CONST_FUNC float toLinear(float _a);
  443. ///
  444. BX_CONST_FUNC float toGamma(float _a);
  445. } // namespace bx
  446. #include "inline/math.inl"
  447. #endif // BX_MATH_H_HEADER_GUARD