linmath.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608
  1. #ifndef LINMATH_H
  2. #define LINMATH_H
  3. #include <string.h>
  4. #include <math.h>
  5. #include <string.h>
  6. #ifdef LINMATH_NO_INLINE
  7. #define LINMATH_H_FUNC static
  8. #else
  9. #define LINMATH_H_FUNC static inline
  10. #endif
  11. #define LINMATH_H_DEFINE_VEC(n) \
  12. typedef float vec##n[n]; \
  13. LINMATH_H_FUNC void vec##n##_add(vec##n r, vec##n const a, vec##n const b) \
  14. { \
  15. int i; \
  16. for(i=0; i<n; ++i) \
  17. r[i] = a[i] + b[i]; \
  18. } \
  19. LINMATH_H_FUNC void vec##n##_sub(vec##n r, vec##n const a, vec##n const b) \
  20. { \
  21. int i; \
  22. for(i=0; i<n; ++i) \
  23. r[i] = a[i] - b[i]; \
  24. } \
  25. LINMATH_H_FUNC void vec##n##_scale(vec##n r, vec##n const v, float const s) \
  26. { \
  27. int i; \
  28. for(i=0; i<n; ++i) \
  29. r[i] = v[i] * s; \
  30. } \
  31. LINMATH_H_FUNC float vec##n##_mul_inner(vec##n const a, vec##n const b) \
  32. { \
  33. float p = 0.f; \
  34. int i; \
  35. for(i=0; i<n; ++i) \
  36. p += b[i]*a[i]; \
  37. return p; \
  38. } \
  39. LINMATH_H_FUNC float vec##n##_len(vec##n const v) \
  40. { \
  41. return sqrtf(vec##n##_mul_inner(v,v)); \
  42. } \
  43. LINMATH_H_FUNC void vec##n##_norm(vec##n r, vec##n const v) \
  44. { \
  45. float k = 1.f / vec##n##_len(v); \
  46. vec##n##_scale(r, v, k); \
  47. } \
  48. LINMATH_H_FUNC void vec##n##_min(vec##n r, vec##n const a, vec##n const b) \
  49. { \
  50. int i; \
  51. for(i=0; i<n; ++i) \
  52. r[i] = a[i]<b[i] ? a[i] : b[i]; \
  53. } \
  54. LINMATH_H_FUNC void vec##n##_max(vec##n r, vec##n const a, vec##n const b) \
  55. { \
  56. int i; \
  57. for(i=0; i<n; ++i) \
  58. r[i] = a[i]>b[i] ? a[i] : b[i]; \
  59. } \
  60. LINMATH_H_FUNC void vec##n##_dup(vec##n r, vec##n const src) \
  61. { \
  62. int i; \
  63. for(i=0; i<n; ++i) \
  64. r[i] = src[i]; \
  65. }
  66. LINMATH_H_DEFINE_VEC(2)
  67. LINMATH_H_DEFINE_VEC(3)
  68. LINMATH_H_DEFINE_VEC(4)
  69. LINMATH_H_FUNC void vec3_mul_cross(vec3 r, vec3 const a, vec3 const b)
  70. {
  71. r[0] = a[1] * b[2] - a[2] * b[1];
  72. r[1] = a[2] * b[0] - a[0] * b[2];
  73. r[2] = a[0] * b[1] - a[1] * b[0];
  74. }
  75. LINMATH_H_FUNC void vec3_reflect(vec3 r, vec3 const v, vec3 const n)
  76. {
  77. float p = 2.f * vec3_mul_inner(v, n);
  78. int i;
  79. for (i = 0; i < 3; ++i)
  80. r[i] = v[i] - p * n[i];
  81. }
  82. LINMATH_H_FUNC void vec4_mul_cross(vec4 r, vec4 const a, vec4 const b)
  83. {
  84. r[0] = a[1] * b[2] - a[2] * b[1];
  85. r[1] = a[2] * b[0] - a[0] * b[2];
  86. r[2] = a[0] * b[1] - a[1] * b[0];
  87. r[3] = 1.f;
  88. }
  89. LINMATH_H_FUNC void vec4_reflect(vec4 r, vec4 const v, vec4 const n)
  90. {
  91. float p = 2.f * vec4_mul_inner(v, n);
  92. int i;
  93. for (i = 0; i < 4; ++i)
  94. r[i] = v[i] - p * n[i];
  95. }
  96. typedef vec4 mat4x4[4];
  97. LINMATH_H_FUNC void mat4x4_identity(mat4x4 M)
  98. {
  99. int i, j;
  100. for (i = 0; i < 4; ++i)
  101. for (j = 0; j < 4; ++j)
  102. M[i][j] = i == j ? 1.f : 0.f;
  103. }
  104. LINMATH_H_FUNC void mat4x4_dup(mat4x4 M, mat4x4 const N)
  105. {
  106. int i;
  107. for (i = 0; i < 4; ++i)
  108. vec4_dup(M[i], N[i]);
  109. }
  110. LINMATH_H_FUNC void mat4x4_row(vec4 r, mat4x4 const M, int i)
  111. {
  112. int k;
  113. for (k = 0; k < 4; ++k)
  114. r[k] = M[k][i];
  115. }
  116. LINMATH_H_FUNC void mat4x4_col(vec4 r, mat4x4 const M, int i)
  117. {
  118. int k;
  119. for (k = 0; k < 4; ++k)
  120. r[k] = M[i][k];
  121. }
  122. LINMATH_H_FUNC void mat4x4_transpose(mat4x4 M, mat4x4 const N)
  123. {
  124. // Note: if M and N are the same, the user has to
  125. // explicitly make a copy of M and set it to N.
  126. int i, j;
  127. for (j = 0; j < 4; ++j)
  128. for (i = 0; i < 4; ++i)
  129. M[i][j] = N[j][i];
  130. }
  131. LINMATH_H_FUNC void mat4x4_add(mat4x4 M, mat4x4 const a, mat4x4 const b)
  132. {
  133. int i;
  134. for (i = 0; i < 4; ++i)
  135. vec4_add(M[i], a[i], b[i]);
  136. }
  137. LINMATH_H_FUNC void mat4x4_sub(mat4x4 M, mat4x4 const a, mat4x4 const b)
  138. {
  139. int i;
  140. for (i = 0; i < 4; ++i)
  141. vec4_sub(M[i], a[i], b[i]);
  142. }
  143. LINMATH_H_FUNC void mat4x4_scale(mat4x4 M, mat4x4 const a, float k)
  144. {
  145. int i;
  146. for (i = 0; i < 4; ++i)
  147. vec4_scale(M[i], a[i], k);
  148. }
  149. LINMATH_H_FUNC void mat4x4_scale_aniso(mat4x4 M, mat4x4 const a, float x, float y, float z)
  150. {
  151. vec4_scale(M[0], a[0], x);
  152. vec4_scale(M[1], a[1], y);
  153. vec4_scale(M[2], a[2], z);
  154. vec4_dup(M[3], a[3]);
  155. }
  156. LINMATH_H_FUNC void mat4x4_mul(mat4x4 M, mat4x4 const a, mat4x4 const b)
  157. {
  158. mat4x4 temp;
  159. int k, r, c;
  160. for (c = 0; c < 4; ++c) for (r = 0; r < 4; ++r) {
  161. temp[c][r] = 0.f;
  162. for (k = 0; k < 4; ++k)
  163. temp[c][r] += a[k][r] * b[c][k];
  164. }
  165. mat4x4_dup(M, temp);
  166. }
  167. LINMATH_H_FUNC void mat4x4_mul_vec4(vec4 r, mat4x4 const M, vec4 const v)
  168. {
  169. int i, j;
  170. for (j = 0; j < 4; ++j) {
  171. r[j] = 0.f;
  172. for (i = 0; i < 4; ++i)
  173. r[j] += M[i][j] * v[i];
  174. }
  175. }
  176. LINMATH_H_FUNC void mat4x4_translate(mat4x4 T, float x, float y, float z)
  177. {
  178. mat4x4_identity(T);
  179. T[3][0] = x;
  180. T[3][1] = y;
  181. T[3][2] = z;
  182. }
  183. LINMATH_H_FUNC void mat4x4_translate_in_place(mat4x4 M, float x, float y, float z)
  184. {
  185. vec4 t = { x, y, z, 0 };
  186. vec4 r;
  187. int i;
  188. for (i = 0; i < 4; ++i) {
  189. mat4x4_row(r, M, i);
  190. M[3][i] += vec4_mul_inner(r, t);
  191. }
  192. }
  193. LINMATH_H_FUNC void mat4x4_from_vec3_mul_outer(mat4x4 M, vec3 const a, vec3 const b)
  194. {
  195. int i, j;
  196. for (i = 0; i < 4; ++i) for (j = 0; j < 4; ++j)
  197. M[i][j] = i < 3 && j < 3 ? a[i] * b[j] : 0.f;
  198. }
  199. LINMATH_H_FUNC void mat4x4_rotate(mat4x4 R, mat4x4 const M, float x, float y, float z, float angle)
  200. {
  201. float s = sinf(angle);
  202. float c = cosf(angle);
  203. vec3 u = { x, y, z };
  204. if (vec3_len(u) > 1e-4) {
  205. vec3_norm(u, u);
  206. mat4x4 T;
  207. mat4x4_from_vec3_mul_outer(T, u, u);
  208. mat4x4 S = {
  209. { 0, u[2], -u[1], 0},
  210. {-u[2], 0, u[0], 0},
  211. { u[1], -u[0], 0, 0},
  212. { 0, 0, 0, 0}
  213. };
  214. mat4x4_scale(S, S, s);
  215. mat4x4 C;
  216. mat4x4_identity(C);
  217. mat4x4_sub(C, C, T);
  218. mat4x4_scale(C, C, c);
  219. mat4x4_add(T, T, C);
  220. mat4x4_add(T, T, S);
  221. T[3][3] = 1.f;
  222. mat4x4_mul(R, M, T);
  223. }
  224. else {
  225. mat4x4_dup(R, M);
  226. }
  227. }
  228. LINMATH_H_FUNC void mat4x4_rotate_X(mat4x4 Q, mat4x4 const M, float angle)
  229. {
  230. float s = sinf(angle);
  231. float c = cosf(angle);
  232. mat4x4 R = {
  233. {1.f, 0.f, 0.f, 0.f},
  234. {0.f, c, s, 0.f},
  235. {0.f, -s, c, 0.f},
  236. {0.f, 0.f, 0.f, 1.f}
  237. };
  238. mat4x4_mul(Q, M, R);
  239. }
  240. LINMATH_H_FUNC void mat4x4_rotate_Y(mat4x4 Q, mat4x4 const M, float angle)
  241. {
  242. float s = sinf(angle);
  243. float c = cosf(angle);
  244. mat4x4 R = {
  245. { c, 0.f, -s, 0.f},
  246. { 0.f, 1.f, 0.f, 0.f},
  247. { s, 0.f, c, 0.f},
  248. { 0.f, 0.f, 0.f, 1.f}
  249. };
  250. mat4x4_mul(Q, M, R);
  251. }
  252. LINMATH_H_FUNC void mat4x4_rotate_Z(mat4x4 Q, mat4x4 const M, float angle)
  253. {
  254. float s = sinf(angle);
  255. float c = cosf(angle);
  256. mat4x4 R = {
  257. { c, s, 0.f, 0.f},
  258. { -s, c, 0.f, 0.f},
  259. { 0.f, 0.f, 1.f, 0.f},
  260. { 0.f, 0.f, 0.f, 1.f}
  261. };
  262. mat4x4_mul(Q, M, R);
  263. }
  264. LINMATH_H_FUNC void mat4x4_invert(mat4x4 T, mat4x4 const M)
  265. {
  266. float s[6];
  267. float c[6];
  268. s[0] = M[0][0] * M[1][1] - M[1][0] * M[0][1];
  269. s[1] = M[0][0] * M[1][2] - M[1][0] * M[0][2];
  270. s[2] = M[0][0] * M[1][3] - M[1][0] * M[0][3];
  271. s[3] = M[0][1] * M[1][2] - M[1][1] * M[0][2];
  272. s[4] = M[0][1] * M[1][3] - M[1][1] * M[0][3];
  273. s[5] = M[0][2] * M[1][3] - M[1][2] * M[0][3];
  274. c[0] = M[2][0] * M[3][1] - M[3][0] * M[2][1];
  275. c[1] = M[2][0] * M[3][2] - M[3][0] * M[2][2];
  276. c[2] = M[2][0] * M[3][3] - M[3][0] * M[2][3];
  277. c[3] = M[2][1] * M[3][2] - M[3][1] * M[2][2];
  278. c[4] = M[2][1] * M[3][3] - M[3][1] * M[2][3];
  279. c[5] = M[2][2] * M[3][3] - M[3][2] * M[2][3];
  280. /* Assumes it is invertible */
  281. float idet = 1.0f / (s[0] * c[5] - s[1] * c[4] + s[2] * c[3] + s[3] * c[2] - s[4] * c[1] + s[5] * c[0]);
  282. T[0][0] = (M[1][1] * c[5] - M[1][2] * c[4] + M[1][3] * c[3]) * idet;
  283. T[0][1] = (-M[0][1] * c[5] + M[0][2] * c[4] - M[0][3] * c[3]) * idet;
  284. T[0][2] = (M[3][1] * s[5] - M[3][2] * s[4] + M[3][3] * s[3]) * idet;
  285. T[0][3] = (-M[2][1] * s[5] + M[2][2] * s[4] - M[2][3] * s[3]) * idet;
  286. T[1][0] = (-M[1][0] * c[5] + M[1][2] * c[2] - M[1][3] * c[1]) * idet;
  287. T[1][1] = (M[0][0] * c[5] - M[0][2] * c[2] + M[0][3] * c[1]) * idet;
  288. T[1][2] = (-M[3][0] * s[5] + M[3][2] * s[2] - M[3][3] * s[1]) * idet;
  289. T[1][3] = (M[2][0] * s[5] - M[2][2] * s[2] + M[2][3] * s[1]) * idet;
  290. T[2][0] = (M[1][0] * c[4] - M[1][1] * c[2] + M[1][3] * c[0]) * idet;
  291. T[2][1] = (-M[0][0] * c[4] + M[0][1] * c[2] - M[0][3] * c[0]) * idet;
  292. T[2][2] = (M[3][0] * s[4] - M[3][1] * s[2] + M[3][3] * s[0]) * idet;
  293. T[2][3] = (-M[2][0] * s[4] + M[2][1] * s[2] - M[2][3] * s[0]) * idet;
  294. T[3][0] = (-M[1][0] * c[3] + M[1][1] * c[1] - M[1][2] * c[0]) * idet;
  295. T[3][1] = (M[0][0] * c[3] - M[0][1] * c[1] + M[0][2] * c[0]) * idet;
  296. T[3][2] = (-M[3][0] * s[3] + M[3][1] * s[1] - M[3][2] * s[0]) * idet;
  297. T[3][3] = (M[2][0] * s[3] - M[2][1] * s[1] + M[2][2] * s[0]) * idet;
  298. }
  299. LINMATH_H_FUNC void mat4x4_orthonormalize(mat4x4 R, mat4x4 const M)
  300. {
  301. mat4x4_dup(R, M);
  302. float s = 1.f;
  303. vec3 h;
  304. vec3_norm(R[2], R[2]);
  305. s = vec3_mul_inner(R[1], R[2]);
  306. vec3_scale(h, R[2], s);
  307. vec3_sub(R[1], R[1], h);
  308. vec3_norm(R[1], R[1]);
  309. s = vec3_mul_inner(R[0], R[2]);
  310. vec3_scale(h, R[2], s);
  311. vec3_sub(R[0], R[0], h);
  312. s = vec3_mul_inner(R[0], R[1]);
  313. vec3_scale(h, R[1], s);
  314. vec3_sub(R[0], R[0], h);
  315. vec3_norm(R[0], R[0]);
  316. }
  317. LINMATH_H_FUNC void mat4x4_frustum(mat4x4 M, float l, float r, float b, float t, float n, float f)
  318. {
  319. M[0][0] = 2.f * n / (r - l);
  320. M[0][1] = M[0][2] = M[0][3] = 0.f;
  321. M[1][1] = 2.f * n / (t - b);
  322. M[1][0] = M[1][2] = M[1][3] = 0.f;
  323. M[2][0] = (r + l) / (r - l);
  324. M[2][1] = (t + b) / (t - b);
  325. M[2][2] = -(f + n) / (f - n);
  326. M[2][3] = -1.f;
  327. M[3][2] = -2.f * (f * n) / (f - n);
  328. M[3][0] = M[3][1] = M[3][3] = 0.f;
  329. }
  330. LINMATH_H_FUNC void mat4x4_ortho(mat4x4 M, float l, float r, float b, float t, float n, float f)
  331. {
  332. M[0][0] = 2.f / (r - l);
  333. M[0][1] = M[0][2] = M[0][3] = 0.f;
  334. M[1][1] = 2.f / (t - b);
  335. M[1][0] = M[1][2] = M[1][3] = 0.f;
  336. M[2][2] = -2.f / (f - n);
  337. M[2][0] = M[2][1] = M[2][3] = 0.f;
  338. M[3][0] = -(r + l) / (r - l);
  339. M[3][1] = -(t + b) / (t - b);
  340. M[3][2] = -(f + n) / (f - n);
  341. M[3][3] = 1.f;
  342. }
  343. LINMATH_H_FUNC void mat4x4_perspective(mat4x4 m, float y_fov, float aspect, float n, float f)
  344. {
  345. /* NOTE: Degrees are an unhandy unit to work with.
  346. * linmath.h uses radians for everything! */
  347. float const a = 1.f / tanf(y_fov / 2.f);
  348. m[0][0] = a / aspect;
  349. m[0][1] = 0.f;
  350. m[0][2] = 0.f;
  351. m[0][3] = 0.f;
  352. m[1][0] = 0.f;
  353. m[1][1] = a;
  354. m[1][2] = 0.f;
  355. m[1][3] = 0.f;
  356. m[2][0] = 0.f;
  357. m[2][1] = 0.f;
  358. m[2][2] = -((f + n) / (f - n));
  359. m[2][3] = -1.f;
  360. m[3][0] = 0.f;
  361. m[3][1] = 0.f;
  362. m[3][2] = -((2.f * f * n) / (f - n));
  363. m[3][3] = 0.f;
  364. }
  365. LINMATH_H_FUNC void mat4x4_look_at(mat4x4 m, vec3 const eye, vec3 const center, vec3 const up)
  366. {
  367. /* Adapted from Android's OpenGL Matrix.java. */
  368. /* See the OpenGL GLUT documentation for gluLookAt for a description */
  369. /* of the algorithm. We implement it in a straightforward way: */
  370. /* TODO: The negation of of can be spared by swapping the order of
  371. * operands in the following cross products in the right way. */
  372. vec3 f;
  373. vec3_sub(f, center, eye);
  374. vec3_norm(f, f);
  375. vec3 s;
  376. vec3_mul_cross(s, f, up);
  377. vec3_norm(s, s);
  378. vec3 t;
  379. vec3_mul_cross(t, s, f);
  380. m[0][0] = s[0];
  381. m[0][1] = t[0];
  382. m[0][2] = -f[0];
  383. m[0][3] = 0.f;
  384. m[1][0] = s[1];
  385. m[1][1] = t[1];
  386. m[1][2] = -f[1];
  387. m[1][3] = 0.f;
  388. m[2][0] = s[2];
  389. m[2][1] = t[2];
  390. m[2][2] = -f[2];
  391. m[2][3] = 0.f;
  392. m[3][0] = 0.f;
  393. m[3][1] = 0.f;
  394. m[3][2] = 0.f;
  395. m[3][3] = 1.f;
  396. mat4x4_translate_in_place(m, -eye[0], -eye[1], -eye[2]);
  397. }
  398. typedef float quat[4];
  399. #define quat_add vec4_add
  400. #define quat_sub vec4_sub
  401. #define quat_norm vec4_norm
  402. #define quat_scale vec4_scale
  403. #define quat_mul_inner vec4_mul_inner
  404. LINMATH_H_FUNC void quat_identity(quat q)
  405. {
  406. q[0] = q[1] = q[2] = 0.f;
  407. q[3] = 1.f;
  408. }
  409. LINMATH_H_FUNC void quat_mul(quat r, quat const p, quat const q)
  410. {
  411. vec3 w, tmp;
  412. vec3_mul_cross(tmp, p, q);
  413. vec3_scale(w, p, q[3]);
  414. vec3_add(tmp, tmp, w);
  415. vec3_scale(w, q, p[3]);
  416. vec3_add(tmp, tmp, w);
  417. vec3_dup(r, tmp);
  418. r[3] = p[3] * q[3] - vec3_mul_inner(p, q);
  419. }
  420. LINMATH_H_FUNC void quat_conj(quat r, quat const q)
  421. {
  422. int i;
  423. for (i = 0; i < 3; ++i)
  424. r[i] = -q[i];
  425. r[3] = q[3];
  426. }
  427. LINMATH_H_FUNC void quat_rotate(quat r, float angle, vec3 const axis) {
  428. vec3 axis_norm;
  429. vec3_norm(axis_norm, axis);
  430. float s = sinf(angle / 2);
  431. float c = cosf(angle / 2);
  432. vec3_scale(r, axis_norm, s);
  433. r[3] = c;
  434. }
  435. LINMATH_H_FUNC void quat_mul_vec3(vec3 r, quat const q, vec3 const v)
  436. {
  437. /*
  438. * Method by Fabian 'ryg' Giessen (of Farbrausch)
  439. t = 2 * cross(q.xyz, v)
  440. v' = v + q.w * t + cross(q.xyz, t)
  441. */
  442. vec3 t;
  443. vec3 q_xyz = { q[0], q[1], q[2] };
  444. vec3 u = { q[0], q[1], q[2] };
  445. vec3_mul_cross(t, q_xyz, v);
  446. vec3_scale(t, t, 2);
  447. vec3_mul_cross(u, q_xyz, t);
  448. vec3_scale(t, t, q[3]);
  449. vec3_add(r, v, t);
  450. vec3_add(r, r, u);
  451. }
  452. LINMATH_H_FUNC void mat4x4_from_quat(mat4x4 M, quat const q)
  453. {
  454. float a = q[3];
  455. float b = q[0];
  456. float c = q[1];
  457. float d = q[2];
  458. float a2 = a * a;
  459. float b2 = b * b;
  460. float c2 = c * c;
  461. float d2 = d * d;
  462. M[0][0] = a2 + b2 - c2 - d2;
  463. M[0][1] = 2.f * (b * c + a * d);
  464. M[0][2] = 2.f * (b * d - a * c);
  465. M[0][3] = 0.f;
  466. M[1][0] = 2 * (b * c - a * d);
  467. M[1][1] = a2 - b2 + c2 - d2;
  468. M[1][2] = 2.f * (c * d + a * b);
  469. M[1][3] = 0.f;
  470. M[2][0] = 2.f * (b * d + a * c);
  471. M[2][1] = 2.f * (c * d - a * b);
  472. M[2][2] = a2 - b2 - c2 + d2;
  473. M[2][3] = 0.f;
  474. M[3][0] = M[3][1] = M[3][2] = 0.f;
  475. M[3][3] = 1.f;
  476. }
  477. LINMATH_H_FUNC void mat4x4o_mul_quat(mat4x4 R, mat4x4 const M, quat const q)
  478. {
  479. /* XXX: The way this is written only works for orthogonal matrices. */
  480. /* TODO: Take care of non-orthogonal case. */
  481. quat_mul_vec3(R[0], q, M[0]);
  482. quat_mul_vec3(R[1], q, M[1]);
  483. quat_mul_vec3(R[2], q, M[2]);
  484. R[3][0] = R[3][1] = R[3][2] = 0.f;
  485. R[0][3] = M[0][3];
  486. R[1][3] = M[1][3];
  487. R[2][3] = M[2][3];
  488. R[3][3] = M[3][3]; // typically 1.0, but here we make it general
  489. }
  490. LINMATH_H_FUNC void quat_from_mat4x4(quat q, mat4x4 const M)
  491. {
  492. float r = 0.f;
  493. int i;
  494. int perm[] = { 0, 1, 2, 0, 1 };
  495. int* p = perm;
  496. for (i = 0; i < 3; i++) {
  497. float m = M[i][i];
  498. if (m < r)
  499. continue;
  500. m = r;
  501. p = &perm[i];
  502. }
  503. r = sqrtf(1.f + M[p[0]][p[0]] - M[p[1]][p[1]] - M[p[2]][p[2]]);
  504. if (r < 1e-6) {
  505. q[0] = 1.f;
  506. q[1] = q[2] = q[3] = 0.f;
  507. return;
  508. }
  509. q[0] = r / 2.f;
  510. q[1] = (M[p[0]][p[1]] - M[p[1]][p[0]]) / (2.f * r);
  511. q[2] = (M[p[2]][p[0]] - M[p[0]][p[2]]) / (2.f * r);
  512. q[3] = (M[p[2]][p[1]] - M[p[1]][p[2]]) / (2.f * r);
  513. }
  514. LINMATH_H_FUNC void mat4x4_arcball(mat4x4 R, mat4x4 const M, vec2 const _a, vec2 const _b, float s)
  515. {
  516. vec2 a; memcpy(a, _a, sizeof(a));
  517. vec2 b; memcpy(b, _b, sizeof(b));
  518. float z_a = 0.;
  519. float z_b = 0.;
  520. if (vec2_len(a) < 1.) {
  521. z_a = sqrtf(1. - vec2_mul_inner(a, a));
  522. }
  523. else {
  524. vec2_norm(a, a);
  525. }
  526. if (vec2_len(b) < 1.) {
  527. z_b = sqrtf(1. - vec2_mul_inner(b, b));
  528. }
  529. else {
  530. vec2_norm(b, b);
  531. }
  532. vec3 a_ = { a[0], a[1], z_a };
  533. vec3 b_ = { b[0], b[1], z_b };
  534. vec3 c_;
  535. vec3_mul_cross(c_, a_, b_);
  536. float const angle = acos(vec3_mul_inner(a_, b_)) * s;
  537. mat4x4_rotate(R, M, c_[0], c_[1], c_[2], angle);
  538. }
  539. #endif