mat.h 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638
  1. /*
  2. December 2022
  3. Requires vec.h: https://gist.github.com/mrbid/77a92019e1ab8b86109bf103166bd04e
  4. Credits:
  5. Aaftab Munshi, Dan Ginsburg, Dave Shreiner, James William Fletcher, Intel, Gabriel Cramer, Test_User
  6. */
  7. #ifndef MAT_H
  8. #define MAT_H
  9. #include "vec.h"
  10. typedef struct
  11. {
  12. float m[4][4];
  13. } mat;
  14. void mIdent(mat *m);
  15. void mCopy(mat *r, const mat *v);
  16. void mMul(mat *r, const mat *a, const mat *b);
  17. void mMulP(vec *r, const mat *a, const float x, const float y, const float z);
  18. void mMulV(vec *r, const mat *a, const vec v);
  19. void mScale(mat *r, const float x, const float y, const float z);
  20. void mTranslate(mat *r, const float x, const float y, const float z);
  21. void mRotate(mat *r, const float radians, float x, float y, float z); // rotate axis (rotate X to move Y up and down)
  22. void mRotX(mat *r, const float radians); // rotate on axis
  23. void mRotY(mat *r, const float radians); // rotate on axis
  24. void mRotZ(mat *r, const float radians); // rotate on axis
  25. void mAngleAxisRotate(mat *r, const mat view, const float xrot, const float yrot, const float zrot); // gimbal free rotations
  26. void mFrustum(mat *r, const float left, const float right, const float bottom, const float top, const float nearZ, const float farZ);
  27. void mPerspective(mat *r, const float fovy, const float aspect, const float nearZ, const float farZ);
  28. void mOrtho(mat *r, const float left, const float right, const float bottom, const float top, const float nearZ, const float farZ);
  29. void mLookAt(mat *r, const vec origin, const vec unit_dir);
  30. void mInvert(float *dst, const float *mat);
  31. void mTranspose(mat *r, const mat *m);
  32. void mSetViewDir(mat *r, const vec dir_norm);
  33. void mGetViewDir(vec *r, const mat matrix);
  34. void mGetViewX(vec *r, const mat matrix);
  35. void mGetViewY(vec *r, const mat matrix);
  36. void mGetViewZ(vec *r, const mat matrix);
  37. void mSetDir(mat *r, const vec dir_norm);
  38. void mGetDirX(vec *r, const mat matrix);
  39. void mGetDirY(vec *r, const mat matrix);
  40. void mGetDirZ(vec *r, const mat matrix);
  41. void mGetPos(vec *r, const mat matrix);
  42. void mSetPos(mat *r, const vec pos);
  43. void mDump(const mat matrix);
  44. //
  45. void mIdent(mat *m)
  46. {
  47. memset(m, 0x0, sizeof(mat));
  48. m->m[0][0] = 1.0f;
  49. m->m[1][1] = 1.0f;
  50. m->m[2][2] = 1.0f;
  51. m->m[3][3] = 1.0f;
  52. }
  53. void mCopy(mat *r, const mat *v)
  54. {
  55. memcpy(r, v, sizeof(mat));
  56. }
  57. void mMul(mat *r, const mat *a, const mat *b)
  58. {
  59. mat tmp;
  60. for(int i = 0; i < 4; i++)
  61. {
  62. tmp.m[i][0] = (a->m[i][0] * b->m[0][0]) +
  63. (a->m[i][1] * b->m[1][0]) +
  64. (a->m[i][2] * b->m[2][0]) +
  65. (a->m[i][3] * b->m[3][0]) ;
  66. tmp.m[i][1] = (a->m[i][0] * b->m[0][1]) +
  67. (a->m[i][1] * b->m[1][1]) +
  68. (a->m[i][2] * b->m[2][1]) +
  69. (a->m[i][3] * b->m[3][1]) ;
  70. tmp.m[i][2] = (a->m[i][0] * b->m[0][2]) +
  71. (a->m[i][1] * b->m[1][2]) +
  72. (a->m[i][2] * b->m[2][2]) +
  73. (a->m[i][3] * b->m[3][2]) ;
  74. tmp.m[i][3] = (a->m[i][0] * b->m[0][3]) +
  75. (a->m[i][1] * b->m[1][3]) +
  76. (a->m[i][2] * b->m[2][3]) +
  77. (a->m[i][3] * b->m[3][3]) ;
  78. }
  79. memcpy(r, &tmp, sizeof(mat));
  80. }
  81. void mMulP(vec *r, const mat *a, const float x, const float y, const float z)
  82. {
  83. r->x = (a->m[0][0] * x) +
  84. (a->m[0][1] * x) +
  85. (a->m[0][2] * x) +
  86. (a->m[0][3] * x) ;
  87. r->y = (a->m[1][0] * y) +
  88. (a->m[1][1] * y) +
  89. (a->m[1][2] * y) +
  90. (a->m[1][3] * y) ;
  91. r->z = (a->m[2][0] * z) +
  92. (a->m[2][1] * z) +
  93. (a->m[2][2] * z) +
  94. (a->m[2][3] * z) ;
  95. }
  96. void mMulV(vec *r, const mat *a, const vec v)
  97. {
  98. r->x = (a->m[0][0] * v.x) +
  99. (a->m[0][1] * v.x) +
  100. (a->m[0][2] * v.x) +
  101. (a->m[0][3] * v.x) ;
  102. r->y = (a->m[1][0] * v.y) +
  103. (a->m[1][1] * v.y) +
  104. (a->m[1][2] * v.y) +
  105. (a->m[1][3] * v.y) ;
  106. r->z = (a->m[2][0] * v.z) +
  107. (a->m[2][1] * v.z) +
  108. (a->m[2][2] * v.z) +
  109. (a->m[2][3] * v.z) ;
  110. r->w = (a->m[3][0] * v.w) +
  111. (a->m[3][1] * v.w) +
  112. (a->m[3][2] * v.w) +
  113. (a->m[3][3] * v.w) ;
  114. }
  115. void mScale(mat *r, const float x, const float y, const float z)
  116. {
  117. r->m[0][0] *= x;
  118. r->m[0][1] *= x;
  119. r->m[0][2] *= x;
  120. r->m[0][3] *= x;
  121. r->m[1][0] *= y;
  122. r->m[1][1] *= y;
  123. r->m[1][2] *= y;
  124. r->m[1][3] *= y;
  125. r->m[2][0] *= z;
  126. r->m[2][1] *= z;
  127. r->m[2][2] *= z;
  128. r->m[2][3] *= z;
  129. }
  130. void mTranslate(mat *r, const float x, const float y, const float z)
  131. {
  132. r->m[3][0] += (r->m[0][0] * x + r->m[1][0] * y + r->m[2][0] * z);
  133. r->m[3][1] += (r->m[0][1] * x + r->m[1][1] * y + r->m[2][1] * z);
  134. r->m[3][2] += (r->m[0][2] * x + r->m[1][2] * y + r->m[2][2] * z);
  135. r->m[3][3] += (r->m[0][3] * x + r->m[1][3] * y + r->m[2][3] * z);
  136. }
  137. void mRotate(mat *r, const float radians, float x, float y, float z)
  138. {
  139. const float mag = 1.f/sqrtf(x * x + y * y + z * z);
  140. const float sinAngle = sinf(radians);
  141. const float cosAngle = cosf(radians);
  142. if(mag > 0.0f)
  143. {
  144. x *= mag;
  145. y *= mag;
  146. z *= mag;
  147. const float xx = x * x;
  148. const float yy = y * y;
  149. const float zz = z * z;
  150. const float xy = x * y;
  151. const float yz = y * z;
  152. const float zx = z * x;
  153. const float xs = x * sinAngle;
  154. const float ys = y * sinAngle;
  155. const float zs = z * sinAngle;
  156. const float oneMinusCos = 1.0f - cosAngle;
  157. mat rotMat;
  158. rotMat.m[0][0] = (oneMinusCos * xx) + cosAngle;
  159. rotMat.m[0][1] = (oneMinusCos * xy) - zs;
  160. rotMat.m[0][2] = (oneMinusCos * zx) + ys;
  161. rotMat.m[0][3] = 0.0F;
  162. rotMat.m[1][0] = (oneMinusCos * xy) + zs;
  163. rotMat.m[1][1] = (oneMinusCos * yy) + cosAngle;
  164. rotMat.m[1][2] = (oneMinusCos * yz) - xs;
  165. rotMat.m[1][3] = 0.0F;
  166. rotMat.m[2][0] = (oneMinusCos * zx) - ys;
  167. rotMat.m[2][1] = (oneMinusCos * yz) + xs;
  168. rotMat.m[2][2] = (oneMinusCos * zz) + cosAngle;
  169. rotMat.m[2][3] = 0.0F;
  170. rotMat.m[3][0] = 0.0F;
  171. rotMat.m[3][1] = 0.0F;
  172. rotMat.m[3][2] = 0.0F;
  173. rotMat.m[3][3] = 1.0F;
  174. mMul(r, &rotMat, r);
  175. }
  176. }
  177. void mRotX(mat *r, const float radians)
  178. {
  179. const float s = sinf(radians);
  180. const float c = cosf(radians);
  181. const mat t = { c, 0.f, s, 0.f,
  182. 0.f, 1.f, 0.f, 0.f,
  183. -s, 0.f, c, 0.f,
  184. 0.f, 0.f, 0.f, 1.f };
  185. mMul(r, &t, r);
  186. }
  187. void mRotY(mat *r, const float radians)
  188. {
  189. const float s = sinf(radians);
  190. const float c = cosf(radians);
  191. const mat t = { 1.f, 0.f, 0.f, 0.f,
  192. 0.f, c, -s, 0.f,
  193. 0.f, s, c, 0.f,
  194. 0.f, 0.f, 0.f, 1.f };
  195. mMul(r, &t, r);
  196. }
  197. void mRotZ(mat *r, const float radians)
  198. {
  199. const float s = sinf(radians);
  200. const float c = cosf(radians);
  201. const mat t = { c, -s, 0.f, 0.f,
  202. s, c, 0.f, 0.f,
  203. 0.f, 0.f, 1.f, 0.f,
  204. 0.f, 0.f, 0.f, 1.f };
  205. mMul(r, &t, r);
  206. }
  207. void mAngleAxisRotate(mat *r, const mat view, const float xrot, const float yrot, const float zrot)
  208. {
  209. // Test_User angle-axis rotation
  210. // https://en.wikipedia.org/wiki/Axis%E2%80%93angle_representation
  211. // https://en.wikipedia.org/wiki/Rodrigues%27_rotation_formula
  212. // this is incrementing the rotation of the provided view matrix by the xrot,yrot,zrot
  213. vec tmp0, tmp1;
  214. vec vecview[3] = {
  215. {view.m[0][0], view.m[1][0], view.m[2][0]}, // r
  216. {view.m[0][1], view.m[1][1], view.m[2][1]}, // u
  217. {view.m[0][2], view.m[1][2], view.m[2][2]} // f
  218. };
  219. // left/right
  220. vMulS(&tmp0, vecview[0], cosf(xrot));
  221. vCross(&tmp1, vecview[1], vecview[0]);
  222. vMulS(&tmp1, tmp1, sinf(xrot));
  223. vMulS(&vecview[0], vecview[1], vDot(vecview[1], vecview[0]) * (1.f - cosf(xrot)));
  224. vAdd(&vecview[0], vecview[0], tmp0);
  225. vAdd(&vecview[0], vecview[0], tmp1);
  226. // up/down
  227. vMulS(&tmp0, vecview[1], cosf(yrot));
  228. vCross(&tmp1, vecview[0], vecview[1]);
  229. vMulS(&tmp1, tmp1, sinf(yrot));
  230. vMulS(&vecview[1], vecview[0], vDot(vecview[0], vecview[1]) * (1.f - cosf(yrot)));
  231. vAdd(&vecview[1], vecview[1], tmp0);
  232. vAdd(&vecview[1], vecview[1], tmp1);
  233. vCross(&vecview[2], vecview[0], vecview[1]);
  234. vCross(&vecview[1], vecview[2], vecview[0]);
  235. // roll
  236. vMulS(&tmp0, vecview[0], cosf(zrot));
  237. vCross(&tmp1, vecview[2], vecview[0]);
  238. vMulS(&tmp1, tmp1, sinf(zrot));
  239. vMulS(&vecview[0], vecview[2], vDot(vecview[2], vecview[0]) * (1.f - cosf(zrot)));
  240. vAdd(&vecview[0], vecview[0], tmp0);
  241. vAdd(&vecview[0], vecview[0], tmp1);
  242. vCross(&vecview[1], vecview[2], vecview[0]);
  243. vNorm(&vecview[0]);
  244. vNorm(&vecview[1]);
  245. vNorm(&vecview[2]);
  246. *r = (mat){
  247. vecview[0].x, vecview[1].x, vecview[2].x, 0.f,
  248. vecview[0].y, vecview[1].y, vecview[2].y, 0.f,
  249. vecview[0].z, vecview[1].z, vecview[2].z, 0.f,
  250. 0.f, 0.f, 0.f, 1.f
  251. };
  252. }
  253. void mFrustum(mat *r, const float left, const float right, const float bottom, const float top, const float nearZ, const float farZ)
  254. {
  255. const float dX = right - left;
  256. const float dY = top - bottom;
  257. const float dZ = farZ - nearZ;
  258. const float rdX = 1.f/dX;
  259. const float rdY = 1.f/dY;
  260. const float rdZ = 1.f/dZ;
  261. mat frust;
  262. if(nearZ <= 0.0f || farZ <= 0.0f || dX <= 0.0f || dY <= 0.0f || dZ <= 0.0f)
  263. return;
  264. frust.m[0][0] = 2.0f * nearZ * rdX;
  265. frust.m[0][1] = frust.m[0][2] = frust.m[0][3] = 0.0f;
  266. frust.m[1][1] = 2.0f * nearZ * rdY;
  267. frust.m[1][0] = frust.m[1][2] = frust.m[1][3] = 0.0f;
  268. frust.m[2][0] = (right + left) * rdX;
  269. frust.m[2][1] = (top + bottom) * rdY;
  270. frust.m[2][2] = -(nearZ + farZ) * rdZ;
  271. frust.m[2][3] = -1.0f;
  272. frust.m[3][2] = -2.0f * nearZ * farZ * rdZ;
  273. frust.m[3][0] = frust.m[3][1] = frust.m[3][3] = 0.0f;
  274. mMul(r, &frust, r);
  275. }
  276. void mPerspective(mat *r, const float fovy, const float aspect, const float nearZ, const float farZ)
  277. {
  278. float frustumW, frustumH;
  279. frustumH = tanf(fovy * 0.002777778078f * PI ) * nearZ; // 0x3b360b62
  280. frustumW = frustumH * aspect;
  281. mFrustum(r, -frustumW, frustumW, -frustumH, frustumH, nearZ, farZ);
  282. }
  283. void mOrtho(mat *r, const float left, const float right, const float bottom, const float top, const float nearZ, const float farZ)
  284. {
  285. const float dX = right - left;
  286. const float dY = top - bottom;
  287. const float dZ = farZ - nearZ;
  288. const float rdX = 1.f/dX;
  289. const float rdY = 1.f/dY;
  290. const float rdZ = 1.f/dZ;
  291. mat ortho;
  292. if(dX == 0.0f || dY == 0.0f || dZ == 0.0f)
  293. return;
  294. mIdent(&ortho);
  295. ortho.m[0][0] = 2.0f * rdX;
  296. ortho.m[3][0] = -(right + left) * rdX;
  297. ortho.m[1][1] = 2.0f * rdY;
  298. ortho.m[3][1] = -(top + bottom) * rdY;
  299. ortho.m[2][2] = -2.0f * rdZ;
  300. ortho.m[3][2] = -(nearZ + farZ) * rdZ;
  301. mMul(r, &ortho, r);
  302. }
  303. void mLookAt(mat *r, const vec origin, const vec unit_dir)
  304. {
  305. static const vec up = (vec){0.f, 0.f, 1.f};
  306. vec dirn;
  307. dirn.x = unit_dir.x;
  308. dirn.y = unit_dir.y;
  309. dirn.z = unit_dir.z;
  310. vec c;
  311. vCross(&c, up, dirn);
  312. vNorm(&c);
  313. vec rup;
  314. vCross(&rup, dirn, c);
  315. r->m[0][0] = c.x;
  316. r->m[0][1] = c.y;
  317. r->m[0][2] = c.z;
  318. r->m[1][0] = rup.x;
  319. r->m[1][1] = rup.y;
  320. r->m[1][2] = rup.z;
  321. r->m[2][0] = dirn.x;
  322. r->m[2][1] = dirn.y;
  323. r->m[2][2] = dirn.z;
  324. r->m[3][0] = origin.x;
  325. r->m[3][1] = origin.y;
  326. r->m[3][2] = origin.z;
  327. }
  328. void mInvert(float *dst, const float *mat)
  329. {
  330. // original source: ftp://download.intel.com/design/PentiumIII/sml/24504301.pdf
  331. // mirrored: https://github.com/esAux/esAux-Menger/raw/main/SIMD%20Matrix%20Inverse.pdf
  332. // Cramer Invert
  333. float tmp[12]; /* temp array for pairs */
  334. float src[16]; /* array of transpose source matrix */
  335. float det; /* determinant */
  336. /* transpose matrix */
  337. for(int i = 0; i < 4; i++)
  338. {
  339. src[i] = mat[i*4];
  340. src[i + 4] = mat[i*4 + 1];
  341. src[i + 8] = mat[i*4 + 2];
  342. src[i + 12] = mat[i*4 + 3];
  343. }
  344. /* calculate pairs for first 8 elements (cofactors) */
  345. tmp[0] = src[10] * src[15];
  346. tmp[1] = src[11] * src[14];
  347. tmp[2] = src[9] * src[15];
  348. tmp[3] = src[11] * src[13];
  349. tmp[4] = src[9] * src[14];
  350. tmp[5] = src[10] * src[13];
  351. tmp[6] = src[8] * src[15];
  352. tmp[7] = src[11] * src[12];
  353. tmp[8] = src[8] * src[14];
  354. tmp[9] = src[10] * src[12];
  355. tmp[10] = src[8] * src[13];
  356. tmp[11] = src[9] * src[12];
  357. /* calculate first 8 elements (cofactors) */
  358. dst[0] = tmp[0]*src[5] + tmp[3]*src[6] + tmp[4]*src[7];
  359. dst[0] -= tmp[1]*src[5] + tmp[2]*src[6] + tmp[5]*src[7];
  360. dst[1] = tmp[1]*src[4] + tmp[6]*src[6] + tmp[9]*src[7];
  361. dst[1] -= tmp[0]*src[4] + tmp[7]*src[6] + tmp[8]*src[7];
  362. dst[2] = tmp[2]*src[4] + tmp[7]*src[5] + tmp[10]*src[7];
  363. dst[2] -= tmp[3]*src[4] + tmp[6]*src[5] + tmp[11]*src[7];
  364. dst[3] = tmp[5]*src[4] + tmp[8]*src[5] + tmp[11]*src[6];
  365. dst[3] -= tmp[4]*src[4] + tmp[9]*src[5] + tmp[10]*src[6];
  366. dst[4] = tmp[1]*src[1] + tmp[2]*src[2] + tmp[5]*src[3];
  367. dst[4] -= tmp[0]*src[1] + tmp[3]*src[2] + tmp[4]*src[3];
  368. dst[5] = tmp[0]*src[0] + tmp[7]*src[2] + tmp[8]*src[3];
  369. dst[5] -= tmp[1]*src[0] + tmp[6]*src[2] + tmp[9]*src[3];
  370. dst[6] = tmp[3]*src[0] + tmp[6]*src[1] + tmp[11]*src[3];
  371. dst[6] -= tmp[2]*src[0] + tmp[7]*src[1] + tmp[10]*src[3];
  372. dst[7] = tmp[4]*src[0] + tmp[9]*src[1] + tmp[10]*src[2];
  373. dst[7] -= tmp[5]*src[0] + tmp[8]*src[1] + tmp[11]*src[2];
  374. /* calculate pairs for second 8 elements (cofactors) */
  375. tmp[0] = src[2]*src[7];
  376. tmp[1] = src[3]*src[6];
  377. tmp[2] = src[1]*src[7];
  378. tmp[3] = src[3]*src[5];
  379. tmp[4] = src[1]*src[6];
  380. tmp[5] = src[2]*src[5];
  381. tmp[6] = src[0]*src[7];
  382. tmp[7] = src[3]*src[4];
  383. tmp[8] = src[0]*src[6];
  384. tmp[9] = src[2]*src[4];
  385. tmp[10] = src[0]*src[5];
  386. tmp[11] = src[1]*src[4];
  387. /* calculate second 8 elements (cofactors) */
  388. dst[8] = tmp[0]*src[13] + tmp[3]*src[14] + tmp[4]*src[15];
  389. dst[8] -= tmp[1]*src[13] + tmp[2]*src[14] + tmp[5]*src[15];
  390. dst[9] = tmp[1]*src[12] + tmp[6]*src[14] + tmp[9]*src[15];
  391. dst[9] -= tmp[0]*src[12] + tmp[7]*src[14] + tmp[8]*src[15];
  392. dst[10] = tmp[2]*src[12] + tmp[7]*src[13] + tmp[10]*src[15];
  393. dst[10]-= tmp[3]*src[12] + tmp[6]*src[13] + tmp[11]*src[15];
  394. dst[11] = tmp[5]*src[12] + tmp[8]*src[13] + tmp[11]*src[14];
  395. dst[11]-= tmp[4]*src[12] + tmp[9]*src[13] + tmp[10]*src[14];
  396. dst[12] = tmp[2]*src[10] + tmp[5]*src[11] + tmp[1]*src[9];
  397. dst[12]-= tmp[4]*src[11] + tmp[0]*src[9] + tmp[3]*src[10];
  398. dst[13] = tmp[8]*src[11] + tmp[0]*src[8] + tmp[7]*src[10];
  399. dst[13]-= tmp[6]*src[10] + tmp[9]*src[11] + tmp[1]*src[8];
  400. dst[14] = tmp[6]*src[9] + tmp[11]*src[11] + tmp[3]*src[8];
  401. dst[14]-= tmp[10]*src[11] + tmp[2]*src[8] + tmp[7]*src[9];
  402. dst[15] = tmp[10]*src[10] + tmp[4]*src[8] + tmp[9]*src[9];
  403. dst[15]-= tmp[8]*src[9] + tmp[11]*src[10] + tmp[5]*src[8];
  404. /* calculate determinant */
  405. det = src[0]*dst[0]+src[1]*dst[1]+src[2]*dst[2]+src[3]*dst[3];
  406. /* calculate matrix inverse */
  407. det = 1.0f/det;
  408. for(int j = 0; j < 16; j++){dst[j] *= det;}
  409. }
  410. void mTranspose(mat *r, const mat *m)
  411. {
  412. r->m[0][0] = m->m[0][0];
  413. r->m[1][0] = m->m[0][1];
  414. r->m[2][0] = m->m[0][2];
  415. r->m[3][0] = m->m[0][3];
  416. r->m[0][1] = m->m[1][0];
  417. r->m[1][1] = m->m[1][1];
  418. r->m[2][1] = m->m[1][2];
  419. r->m[3][1] = m->m[1][3];
  420. r->m[0][2] = m->m[2][0];
  421. r->m[1][2] = m->m[2][1];
  422. r->m[2][2] = m->m[2][2];
  423. r->m[3][2] = m->m[2][3];
  424. r->m[0][3] = m->m[3][0];
  425. r->m[1][3] = m->m[3][1];
  426. r->m[2][3] = m->m[3][2];
  427. r->m[3][3] = m->m[3][3];
  428. }
  429. //
  430. void mSetViewDir(mat *r, const vec dir_norm)
  431. {
  432. static const vec up_norm = (vec){0.f, 0.f, 1.f};
  433. vec c;
  434. vCross(&c, up_norm, dir_norm);
  435. vNorm(&c);
  436. vec rup;
  437. vCross(&rup, dir_norm, c);
  438. r->m[0][0] = -c.x;
  439. r->m[1][0] = -c.y;
  440. r->m[2][0] = -c.z;
  441. r->m[0][1] = -rup.x;
  442. r->m[1][1] = -rup.y;
  443. r->m[2][1] = -rup.z;
  444. r->m[0][2] = -dir_norm.x;
  445. r->m[1][2] = -dir_norm.y;
  446. r->m[2][2] = -dir_norm.z;
  447. }
  448. void mGetViewDir(vec *r, const mat matrix)
  449. {
  450. mGetViewZ(r, matrix);
  451. }
  452. void mGetViewX(vec *r, const mat matrix)
  453. {
  454. r->x = -matrix.m[0][0];
  455. r->y = -matrix.m[1][0];
  456. r->z = -matrix.m[2][0];
  457. }
  458. void mGetViewY(vec *r, const mat matrix)
  459. {
  460. r->x = -matrix.m[0][1];
  461. r->y = -matrix.m[1][1];
  462. r->z = -matrix.m[2][1];
  463. }
  464. void mGetViewZ(vec *r, const mat matrix)
  465. {
  466. r->x = -matrix.m[0][2];
  467. r->y = -matrix.m[1][2];
  468. r->z = -matrix.m[2][2];
  469. }
  470. //
  471. void mSetDir(mat *r, const vec dir_norm)
  472. {
  473. static const vec up_norm = (vec){0.f, 0.f, 1.f};
  474. vec c;
  475. vCross(&c, up_norm, dir_norm);
  476. vNorm(&c);
  477. vec rup;
  478. vCross(&rup, dir_norm, c);
  479. r->m[0][0] = c.x;
  480. r->m[0][1] = c.y;
  481. r->m[0][2] = c.z;
  482. r->m[2][0] = rup.x;
  483. r->m[2][1] = rup.y;
  484. r->m[2][2] = rup.z;
  485. r->m[1][0] = -dir_norm.x;
  486. r->m[1][1] = -dir_norm.y;
  487. r->m[1][2] = -dir_norm.z;
  488. }
  489. void mGetDirX(vec *r, const mat matrix)
  490. {
  491. r->x = matrix.m[0][0];
  492. r->y = matrix.m[0][1];
  493. r->z = matrix.m[0][2];
  494. }
  495. void mGetDirY(vec *r, const mat matrix)
  496. {
  497. r->x = matrix.m[1][0];
  498. r->y = matrix.m[1][1];
  499. r->z = matrix.m[1][2];
  500. }
  501. void mGetDirZ(vec *r, const mat matrix)
  502. {
  503. r->x = matrix.m[2][0];
  504. r->y = matrix.m[2][1];
  505. r->z = matrix.m[2][2];
  506. }
  507. void mGetPos(vec *r, const mat matrix)
  508. {
  509. r->x = matrix.m[3][0];
  510. r->y = matrix.m[3][1];
  511. r->z = matrix.m[3][2];
  512. }
  513. void mSetPos(mat *r, const vec pos)
  514. {
  515. r->m[3][0] = pos.x;
  516. r->m[3][1] = pos.y;
  517. r->m[3][2] = pos.z;
  518. }
  519. void mDump(const mat matrix)
  520. {
  521. printf("%+.2f %+.2f %+.2f %+.2f\n", matrix.m[0][0], matrix.m[0][1], matrix.m[0][2], matrix.m[0][3]);
  522. printf("%+.2f %+.2f %+.2f %+.2f\n", matrix.m[1][0], matrix.m[1][1], matrix.m[1][2], matrix.m[1][3]);
  523. printf("%+.2f %+.2f %+.2f %+.2f\n", matrix.m[2][0], matrix.m[2][1], matrix.m[2][2], matrix.m[2][3]);
  524. printf("%+.2f %+.2f %+.2f %+.2f\n", matrix.m[3][0], matrix.m[3][1], matrix.m[3][2], matrix.m[3][3]);
  525. printf("---\n");
  526. }
  527. #endif