math.h 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349
  1. /*
  2. * Copyright 2011-2013 Branimir Karadzic. All rights reserved.
  3. * License: http://www.opensource.org/licenses/BSD-2-Clause
  4. */
  5. // FPU math lib
  6. #ifndef __FPU_MATH_H__
  7. #define __FPU_MATH_H__
  8. #define _USE_MATH_DEFINES
  9. #include <math.h>
  10. #include <string.h>
  11. inline float fmin(float _a, float _b)
  12. {
  13. return _a < _b ? _a : _b;
  14. }
  15. inline float fmax(float _a, float _b)
  16. {
  17. return _a > _b ? _a : _b;
  18. }
  19. inline float flerp(float _a, float _b, float _t)
  20. {
  21. return _a + (_b - _a) * _t;
  22. }
  23. inline void vec3Add(float* __restrict _result, const float* __restrict _a, const float* __restrict _b)
  24. {
  25. _result[0] = _a[0] + _b[0];
  26. _result[1] = _a[1] + _b[1];
  27. _result[2] = _a[2] + _b[2];
  28. }
  29. inline void vec3Sub(float* __restrict _result, const float* __restrict _a, const float* __restrict _b)
  30. {
  31. _result[0] = _a[0] - _b[0];
  32. _result[1] = _a[1] - _b[1];
  33. _result[2] = _a[2] - _b[2];
  34. }
  35. inline void vec3Mul(float* __restrict _result, const float* __restrict _a, const float* __restrict _b)
  36. {
  37. _result[0] = _a[0] * _b[0];
  38. _result[1] = _a[1] * _b[1];
  39. _result[2] = _a[2] * _b[2];
  40. }
  41. inline void vec3Mul(float* __restrict _result, const float* __restrict _a, float _b)
  42. {
  43. _result[0] = _a[0] * _b;
  44. _result[1] = _a[1] * _b;
  45. _result[2] = _a[2] * _b;
  46. }
  47. inline float vec3Dot(const float* __restrict _a, const float* __restrict _b)
  48. {
  49. return _a[0]*_b[0] + _a[1]*_b[1] + _a[2]*_b[2];
  50. }
  51. inline void vec3Cross(float* __restrict _result, const float* __restrict _a, const float* __restrict _b)
  52. {
  53. _result[0] = _a[1]*_b[2] - _a[2]*_b[1];
  54. _result[1] = _a[2]*_b[0] - _a[0]*_b[2];
  55. _result[2] = _a[0]*_b[1] - _a[1]*_b[0];
  56. }
  57. inline void vec3Norm(float* __restrict _result, const float* __restrict _a)
  58. {
  59. float scale = 1.0f/sqrtf(vec3Dot(_a, _a) );
  60. _result[0] = _a[0] * scale;
  61. _result[1] = _a[1] * scale;
  62. _result[2] = _a[2] * scale;
  63. }
  64. inline void mtxIdentity(float* _result)
  65. {
  66. memset(_result, 0, sizeof(float)*16);
  67. _result[0] = _result[5] = _result[10] = _result[15] = 1.0f;
  68. }
  69. inline void mtxLookAt(float* __restrict _result, const float* __restrict _eye, const float* __restrict _at)
  70. {
  71. float tmp[4];
  72. vec3Sub(tmp, _at, _eye);
  73. float view[4];
  74. vec3Norm(view, tmp);
  75. float up[3] = { 0.0f, 1.0f, 0.0f };
  76. vec3Cross(tmp, up, view);
  77. float right[4];
  78. vec3Norm(right, tmp);
  79. vec3Cross(up, view, right);
  80. memset(_result, 0, sizeof(float)*16);
  81. _result[ 0] = right[0];
  82. _result[ 1] = up[0];
  83. _result[ 2] = view[0];
  84. _result[ 4] = right[1];
  85. _result[ 5] = up[1];
  86. _result[ 6] = view[1];
  87. _result[ 8] = right[2];
  88. _result[ 9] = up[2];
  89. _result[10] = view[2];
  90. _result[12] = -vec3Dot(right, _eye);
  91. _result[13] = -vec3Dot(up, _eye);
  92. _result[14] = -vec3Dot(view, _eye);
  93. _result[15] = 1.0f;
  94. }
  95. inline void mtxProj(float* _result, float _fovy, float _aspect, float _near, float _far)
  96. {
  97. float height = 1.0f/tanf(_fovy*( (float)M_PI/180.0f)*0.5f);
  98. float width = height * 1.0f/_aspect;
  99. float aa = _far/(_far-_near);
  100. float bb = -_near * aa;
  101. memset(_result, 0, sizeof(float)*16);
  102. _result[0] = width;
  103. _result[5] = height;
  104. _result[10] = aa;
  105. _result[11] = 1.0f;
  106. _result[14] = bb;
  107. }
  108. inline void mtxOrtho(float* _result, float _left, float _right, float _bottom, float _top, float _near, float _far)
  109. {
  110. const float aa = 2.0f/(_right - _left);
  111. const float bb = 2.0f/(_top - _bottom);
  112. const float cc = 1.0f/(_far - _near);
  113. const float dd = (_left + _right)/(_left - _right);
  114. const float ee = (_top + _bottom)/(_bottom - _top);
  115. const float ff = _near / (_near - _far);
  116. memset(_result, 0, sizeof(float)*16);
  117. _result[0] = aa;
  118. _result[5] = bb;
  119. _result[10] = cc;
  120. _result[12] = dd;
  121. _result[13] = ee;
  122. _result[14] = ff;
  123. _result[15] = 1.0f;
  124. }
  125. inline void mtxRotateX(float* _result, float _ax)
  126. {
  127. float sx = sinf(_ax);
  128. float cx = cosf(_ax);
  129. memset(_result, 0, sizeof(float)*16);
  130. _result[ 0] = 1.0f;
  131. _result[ 5] = cx;
  132. _result[ 6] = -sx;
  133. _result[ 9] = sx;
  134. _result[10] = cx;
  135. _result[15] = 1.0f;
  136. }
  137. inline void mtxRotateY(float* _result, float _ay)
  138. {
  139. float sy = sinf(_ay);
  140. float cy = cosf(_ay);
  141. memset(_result, 0, sizeof(float)*16);
  142. _result[ 0] = cy;
  143. _result[ 2] = sy;
  144. _result[ 5] = 1.0f;
  145. _result[ 8] = -sy;
  146. _result[10] = cy;
  147. _result[15] = 1.0f;
  148. }
  149. inline void mtxRotateZ(float* _result, float _az)
  150. {
  151. float sz = sinf(_az);
  152. float cz = cosf(_az);
  153. memset(_result, 0, sizeof(float)*16);
  154. _result[ 0] = cz;
  155. _result[ 1] = -sz;
  156. _result[ 4] = sz;
  157. _result[ 5] = cz;
  158. _result[10] = 1.0f;
  159. _result[15] = 1.0f;
  160. }
  161. inline void mtxRotateXY(float* _result, float _ax, float _ay)
  162. {
  163. float sx = sinf(_ax);
  164. float cx = cosf(_ax);
  165. float sy = sinf(_ay);
  166. float cy = cosf(_ay);
  167. memset(_result, 0, sizeof(float)*16);
  168. _result[ 0] = cy;
  169. _result[ 2] = -sy;
  170. _result[ 4] = -sx*sy;
  171. _result[ 5] = cx;
  172. _result[ 6] = -sx*cy;
  173. _result[ 8] = cx*sy;
  174. _result[ 9] = sx;
  175. _result[10] = cx*cy;
  176. _result[15] = 1.0f;
  177. }
  178. inline void mtxRotateXYZ(float* _result, float _ax, float _ay, float _az)
  179. {
  180. float sx = sinf(_ax);
  181. float cx = cosf(_ax);
  182. float sy = sinf(_ay);
  183. float cy = cosf(_ay);
  184. float sz = sinf(_az);
  185. float cz = cosf(_az);
  186. memset(_result, 0, sizeof(float)*16);
  187. _result[ 0] = cy*cz;
  188. _result[ 1] = -cy*sz;
  189. _result[ 2] = sy;
  190. _result[ 4] = cz*sx*sy + cx*sz;
  191. _result[ 5] = cx*cz - sx*sy*sz;
  192. _result[ 6] = -cy*sx;
  193. _result[ 8] = -cx*cz*sy + sx*sz;
  194. _result[ 9] = cz*sx + cx*sy*sz;
  195. _result[10] = cx*cy;
  196. _result[15] = 1.0f;
  197. }
  198. inline void mtxRotateZYX(float* _result, float _ax, float _ay, float _az)
  199. {
  200. float sx = sinf(_ax);
  201. float cx = cosf(_ax);
  202. float sy = sinf(_ay);
  203. float cy = cosf(_ay);
  204. float sz = sinf(_az);
  205. float cz = cosf(_az);
  206. memset(_result, 0, sizeof(float)*16);
  207. _result[ 0] = cy*cz;
  208. _result[ 1] = cz*sx*sy-cx*sz;
  209. _result[ 2] = cx*cz*sy+sx*sz;
  210. _result[ 4] = cy*sz;
  211. _result[ 5] = cx*cz + sx*sy*sz;
  212. _result[ 6] = -cz*sx + cx*sy*sz;
  213. _result[ 8] = -sy;
  214. _result[ 9] = cy*sx;
  215. _result[10] = cx*cy;
  216. _result[15] = 1.0f;
  217. };
  218. inline void vec3MulMtx(float* __restrict _result, const float* __restrict _vec, const float* __restrict _mat)
  219. {
  220. _result[0] = _vec[0] * _mat[ 0] + _vec[1] * _mat[4] + _vec[2] * _mat[ 8] + _mat[12];
  221. _result[1] = _vec[0] * _mat[ 1] + _vec[1] * _mat[5] + _vec[2] * _mat[ 9] + _mat[13];
  222. _result[2] = _vec[0] * _mat[ 2] + _vec[1] * _mat[6] + _vec[2] * _mat[10] + _mat[14];
  223. }
  224. inline void vec4MulMtx(float* __restrict _result, const float* __restrict _vec, const float* __restrict _mat)
  225. {
  226. _result[0] = _vec[0] * _mat[ 0] + _vec[1] * _mat[4] + _vec[2] * _mat[ 8] + _vec[3] * _mat[12];
  227. _result[1] = _vec[0] * _mat[ 1] + _vec[1] * _mat[5] + _vec[2] * _mat[ 9] + _vec[3] * _mat[13];
  228. _result[2] = _vec[0] * _mat[ 2] + _vec[1] * _mat[6] + _vec[2] * _mat[10] + _vec[3] * _mat[14];
  229. _result[3] = _vec[0] * _mat[ 3] + _vec[1] * _mat[7] + _vec[2] * _mat[11] + _vec[3] * _mat[15];
  230. }
  231. inline void mtxMul(float* __restrict _result, const float* __restrict _a, const float* __restrict _b)
  232. {
  233. vec4MulMtx(&_result[ 0], &_a[ 0], _b);
  234. vec4MulMtx(&_result[ 4], &_a[ 4], _b);
  235. vec4MulMtx(&_result[ 8], &_a[ 8], _b);
  236. vec4MulMtx(&_result[12], &_a[12], _b);
  237. }
  238. inline void mtxTranspose(float* __restrict _result, const float* __restrict _a)
  239. {
  240. _result[ 0] = _a[ 0];
  241. _result[ 4] = _a[ 1];
  242. _result[ 8] = _a[ 2];
  243. _result[12] = _a[ 3];
  244. _result[ 1] = _a[ 4];
  245. _result[ 5] = _a[ 5];
  246. _result[ 9] = _a[ 6];
  247. _result[13] = _a[ 7];
  248. _result[ 2] = _a[ 8];
  249. _result[ 6] = _a[ 9];
  250. _result[10] = _a[10];
  251. _result[14] = _a[11];
  252. _result[ 3] = _a[12];
  253. _result[ 7] = _a[13];
  254. _result[11] = _a[14];
  255. _result[15] = _a[15];
  256. }
  257. inline void mtxInverse(float* __restrict _result, const float* __restrict _a)
  258. {
  259. float xx = _a[ 0];
  260. float xy = _a[ 1];
  261. float xz = _a[ 2];
  262. float xw = _a[ 3];
  263. float yx = _a[ 4];
  264. float yy = _a[ 5];
  265. float yz = _a[ 6];
  266. float yw = _a[ 7];
  267. float zx = _a[ 8];
  268. float zy = _a[ 9];
  269. float zz = _a[10];
  270. float zw = _a[11];
  271. float wx = _a[12];
  272. float wy = _a[13];
  273. float wz = _a[14];
  274. float ww = _a[15];
  275. float det = 0.0f;
  276. det += xx * (yy*(zz*ww - zw*wz) - yz*(zy*ww - zw*wy) + yw*(zy*wz - zz*wy) );
  277. det -= xy * (yx*(zz*ww - zw*wz) - yz*(zx*ww - zw*wx) + yw*(zx*wz - zz*wx) );
  278. det += xz * (yx*(zy*ww - zw*wy) - yy*(zx*ww - zw*wx) + yw*(zx*wy - zy*wx) );
  279. det -= xw * (yx*(zy*wz - zz*wy) - yy*(zx*wz - zz*wx) + yz*(zx*wy - zy*wx) );
  280. float invDet = 1.0f/det;
  281. _result[ 0] = +(yy*(zz*ww - wz*zw) - yz*(zy*ww - wy*zw) + yw*(zy*wz - wy*zz) ) * invDet;
  282. _result[ 1] = -(xy*(zz*ww - wz*zw) - xz*(zy*ww - wy*zw) + xw*(zy*wz - wy*zz) ) * invDet;
  283. _result[ 2] = +(xy*(yz*ww - wz*yw) - xz*(yy*ww - wy*yw) + xw*(yy*wz - wy*yz) ) * invDet;
  284. _result[ 3] = -(xy*(yz*zw - zz*yw) - xz*(yy*zw - zy*yw) + xw*(yy*zz - zy*yz) ) * invDet;
  285. _result[ 4] = -(yx*(zz*ww - wz*zw) - yz*(zx*ww - wx*zw) + yw*(zx*wz - wx*zz) ) * invDet;
  286. _result[ 5] = +(xx*(zz*ww - wz*zw) - xz*(zx*ww - wx*zw) + xw*(zx*wz - wx*zz) ) * invDet;
  287. _result[ 6] = -(xx*(yz*ww - wz*yw) - xz*(yx*ww - wx*yw) + xw*(yx*wz - wx*yz) ) * invDet;
  288. _result[ 7] = +(xx*(yz*zw - zz*yw) - xz*(yx*zw - zx*yw) + xw*(yx*zz - zx*yz) ) * invDet;
  289. _result[ 8] = +(yx*(zy*ww - wy*zw) - yy*(zx*ww - wx*zw) + yw*(zx*wy - wx*zy) ) * invDet;
  290. _result[ 9] = -(xx*(zy*ww - wy*zw) - xy*(zx*ww - wx*zw) + xw*(zx*wy - wx*zy) ) * invDet;
  291. _result[10] = +(xx*(yy*ww - wy*yw) - xy*(yx*ww - wx*yw) + xw*(yx*wy - wx*yy) ) * invDet;
  292. _result[11] = -(xx*(yy*zw - zy*yw) - xy*(yx*zw - zx*yw) + xw*(yx*zy - zx*yy) ) * invDet;
  293. _result[12] = -(yx*(zy*wz - wy*zz) - yy*(zx*wz - wx*zz) + yz*(zx*wy - wx*zy) ) * invDet;
  294. _result[13] = +(xx*(zy*wz - wy*zz) - xy*(zx*wz - wx*zz) + xz*(zx*wy - wx*zy) ) * invDet;
  295. _result[14] = -(xx*(yy*wz - wy*yz) - xy*(yx*wz - wx*yz) + xz*(yx*wy - wx*yy) ) * invDet;
  296. _result[15] = +(xx*(yy*zz - zy*yz) - xy*(yx*zz - zx*yz) + xz*(yx*zy - zx*yy) ) * invDet;
  297. }
  298. #endif // __FPU_MATH_H__