Open Source Tomb Raider Engine
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

Matrix.cpp 19KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728
  1. /* -*- Mode: C++; tab-width: 3; indent-tabs-mode: t; c-basic-offset: 3 -*- */
  2. /*================================================================
  3. *
  4. * Project : Freyja
  5. * Author : Terry 'Mongoose' Hendrix II
  6. * Website : http://www.westga.edu/~stu7440/
  7. * Email : stu7440@westga.edu
  8. * Object : Matrix
  9. * License : No use w/o permission (C) 2002 Mongoose
  10. * Comments: 3d Matrix class
  11. *
  12. *
  13. * This file was generated using Mongoose's C++
  14. * template generator script. <stu7440@westga.edu>
  15. *
  16. *-- History -------------------------------------------------
  17. *
  18. * 2002.05.11:
  19. * Mongoose - Created
  20. =================================================================*/
  21. #include <stdio.h>
  22. #include <math.h>
  23. #include <hel/Matrix.h>
  24. ////////////////////////////////////////////////////////////
  25. // Constructors
  26. ////////////////////////////////////////////////////////////
  27. Matrix::Matrix()
  28. {
  29. setIdentity();
  30. }
  31. Matrix::Matrix(matrix_t m)
  32. {
  33. setMatrix(m);
  34. }
  35. Matrix::Matrix(Quaternion &q)
  36. {
  37. matrix_t m;
  38. q.getMatrix(m);
  39. setMatrix(m);
  40. }
  41. Matrix::~Matrix()
  42. {
  43. }
  44. ////////////////////////////////////////////////////////////
  45. // Public Accessors
  46. ////////////////////////////////////////////////////////////
  47. bool Matrix::getInvert(matrix_t out)
  48. {
  49. matrix_t m;
  50. #ifdef COLUMN_ORDER
  51. getMatrix(m);
  52. #else
  53. getTransposeMatrix(m);
  54. #endif
  55. /* Mongoose: This code was from a Jeff Lander tutorial which was based
  56. on MESA GL's InvertMatrix */
  57. /* NB. OpenGL Matrices are COLUMN major. */
  58. #define SWAP_ROWS(a, b) { float *_tmp = a; (a)=(b); (b)=_tmp; }
  59. #define MAT(m,r,c) (m)[(c)*4+(r)]
  60. float wtmp[4][8];
  61. float m0, m1, m2, m3, s;
  62. float *r0, *r1, *r2, *r3;
  63. r0 = wtmp[0], r1 = wtmp[1], r2 = wtmp[2], r3 = wtmp[3];
  64. r0[0] = MAT(m,0,0), r0[1] = MAT(m,0,1),
  65. r0[2] = MAT(m,0,2), r0[3] = MAT(m,0,3),
  66. r0[4] = 1.0, r0[5] = r0[6] = r0[7] = 0.0,
  67. r1[0] = MAT(m,1,0), r1[1] = MAT(m,1,1),
  68. r1[2] = MAT(m,1,2), r1[3] = MAT(m,1,3),
  69. r1[5] = 1.0, r1[4] = r1[6] = r1[7] = 0.0,
  70. r2[0] = MAT(m,2,0), r2[1] = MAT(m,2,1),
  71. r2[2] = MAT(m,2,2), r2[3] = MAT(m,2,3),
  72. r2[6] = 1.0, r2[4] = r2[5] = r2[7] = 0.0,
  73. r3[0] = MAT(m,3,0), r3[1] = MAT(m,3,1),
  74. r3[2] = MAT(m,3,2), r3[3] = MAT(m,3,3),
  75. r3[7] = 1.0, r3[4] = r3[5] = r3[6] = 0.0;
  76. /* choose pivot - or die */
  77. if (fabs(r3[0])>fabs(r2[0])) SWAP_ROWS(r3, r2);
  78. if (fabs(r2[0])>fabs(r1[0])) SWAP_ROWS(r2, r1);
  79. if (fabs(r1[0])>fabs(r0[0])) SWAP_ROWS(r1, r0);
  80. if (0.0 == r0[0]) return false;
  81. /* eliminate first variable */
  82. m1 = r1[0]/r0[0]; m2 = r2[0]/r0[0]; m3 = r3[0]/r0[0];
  83. s = r0[1]; r1[1] -= m1 * s; r2[1] -= m2 * s; r3[1] -= m3 * s;
  84. s = r0[2]; r1[2] -= m1 * s; r2[2] -= m2 * s; r3[2] -= m3 * s;
  85. s = r0[3]; r1[3] -= m1 * s; r2[3] -= m2 * s; r3[3] -= m3 * s;
  86. s = r0[4];
  87. if (s != 0.0) { r1[4] -= m1 * s; r2[4] -= m2 * s; r3[4] -= m3 * s; }
  88. s = r0[5];
  89. if (s != 0.0) { r1[5] -= m1 * s; r2[5] -= m2 * s; r3[5] -= m3 * s; }
  90. s = r0[6];
  91. if (s != 0.0) { r1[6] -= m1 * s; r2[6] -= m2 * s; r3[6] -= m3 * s; }
  92. s = r0[7];
  93. if (s != 0.0) { r1[7] -= m1 * s; r2[7] -= m2 * s; r3[7] -= m3 * s; }
  94. /* choose pivot - or die */
  95. if (fabs(r3[1])>fabs(r2[1])) SWAP_ROWS(r3, r2);
  96. if (fabs(r2[1])>fabs(r1[1])) SWAP_ROWS(r2, r1);
  97. if (0.0 == r1[1]) return false;
  98. /* eliminate second variable */
  99. m2 = r2[1]/r1[1]; m3 = r3[1]/r1[1];
  100. r2[2] -= m2 * r1[2]; r3[2] -= m3 * r1[2];
  101. r2[3] -= m2 * r1[3]; r3[3] -= m3 * r1[3];
  102. s = r1[4]; if (0.0 != s) { r2[4] -= m2 * s; r3[4] -= m3 * s; }
  103. s = r1[5]; if (0.0 != s) { r2[5] -= m2 * s; r3[5] -= m3 * s; }
  104. s = r1[6]; if (0.0 != s) { r2[6] -= m2 * s; r3[6] -= m3 * s; }
  105. s = r1[7]; if (0.0 != s) { r2[7] -= m2 * s; r3[7] -= m3 * s; }
  106. /* choose pivot - or die */
  107. if (fabs(r3[2])>fabs(r2[2])) SWAP_ROWS(r3, r2);
  108. if (0.0 == r2[2]) return false;
  109. /* eliminate third variable */
  110. m3 = r3[2]/r2[2];
  111. r3[3] -= m3 * r2[3], r3[4] -= m3 * r2[4],
  112. r3[5] -= m3 * r2[5], r3[6] -= m3 * r2[6],
  113. r3[7] -= m3 * r2[7];
  114. /* last check */
  115. if (0.0 == r3[3]) return false;
  116. s = 1.0/r3[3]; /* now back substitute row 3 */
  117. r3[4] *= s; r3[5] *= s; r3[6] *= s; r3[7] *= s;
  118. m2 = r2[3]; /* now back substitute row 2 */
  119. s = 1.0/r2[2];
  120. r2[4] = s * (r2[4] - r3[4] * m2), r2[5] = s * (r2[5] - r3[5] * m2),
  121. r2[6] = s * (r2[6] - r3[6] * m2), r2[7] = s * (r2[7] - r3[7] * m2);
  122. m1 = r1[3];
  123. r1[4] -= r3[4] * m1, r1[5] -= r3[5] * m1,
  124. r1[6] -= r3[6] * m1, r1[7] -= r3[7] * m1;
  125. m0 = r0[3];
  126. r0[4] -= r3[4] * m0, r0[5] -= r3[5] * m0,
  127. r0[6] -= r3[6] * m0, r0[7] -= r3[7] * m0;
  128. m1 = r1[2]; /* now back substitute row 1 */
  129. s = 1.0/r1[1];
  130. r1[4] = s * (r1[4] - r2[4] * m1), r1[5] = s * (r1[5] - r2[5] * m1),
  131. r1[6] = s * (r1[6] - r2[6] * m1), r1[7] = s * (r1[7] - r2[7] * m1);
  132. m0 = r0[2];
  133. r0[4] -= r2[4] * m0, r0[5] -= r2[5] * m0,
  134. r0[6] -= r2[6] * m0, r0[7] -= r2[7] * m0;
  135. m0 = r0[1]; /* now back substitute row 0 */
  136. s = 1.0/r0[0];
  137. r0[4] = s * (r0[4] - r1[4] * m0), r0[5] = s * (r0[5] - r1[5] * m0),
  138. r0[6] = s * (r0[6] - r1[6] * m0), r0[7] = s * (r0[7] - r1[7] * m0);
  139. MAT(out,0,0) = r0[4];
  140. MAT(out,0,1) = r0[5], MAT(out,0,2) = r0[6];
  141. MAT(out,0,3) = r0[7], MAT(out,1,0) = r1[4];
  142. MAT(out,1,1) = r1[5], MAT(out,1,2) = r1[6];
  143. MAT(out,1,3) = r1[7], MAT(out,2,0) = r2[4];
  144. MAT(out,2,1) = r2[5], MAT(out,2,2) = r2[6];
  145. MAT(out,2,3) = r2[7], MAT(out,3,0) = r3[4];
  146. MAT(out,3,1) = r3[5], MAT(out,3,2) = r3[6];
  147. MAT(out,3,3) = r3[7];
  148. return true;
  149. #undef MAT
  150. #undef SWAP_ROWS
  151. }
  152. void Matrix::getMatrix(matrix_t mat)
  153. {
  154. copy(mMatrix, mat);
  155. }
  156. void Matrix::getTransposeMatrix(matrix_t m)
  157. {
  158. m[ 0]= mMatrix[0]; m[ 1]= mMatrix[4]; m[ 2]= mMatrix[ 8]; m[ 3]=mMatrix[12];
  159. m[ 4]= mMatrix[1]; m[ 5]= mMatrix[5]; m[ 6]= mMatrix[ 9]; m[ 7]=mMatrix[13];
  160. m[ 8]= mMatrix[2]; m[ 9]= mMatrix[6]; m[10]= mMatrix[10]; m[11]=mMatrix[14];
  161. m[12]= mMatrix[3]; m[13]= mMatrix[7]; m[14]= mMatrix[11]; m[15]=mMatrix[15];
  162. }
  163. Matrix Matrix::multiply(const Matrix &a, const Matrix &b)
  164. {
  165. Matrix c;
  166. multiply(a.mMatrix, b.mMatrix, c.mMatrix);
  167. return c;
  168. }
  169. Matrix Matrix::operator *(const Matrix &a)
  170. {
  171. return multiply(a, *this);
  172. }
  173. Vector3d Matrix::operator *(Vector3d v)
  174. {
  175. vec_t x = v.mVec[0], y = v.mVec[1], z = v.mVec[2];
  176. #ifdef COLUMN_ORDER
  177. // Column order
  178. return Vector3d(mMatrix[0]*x + mMatrix[4]*y + mMatrix[ 8]*z + mMatrix[12],
  179. mMatrix[1]*x + mMatrix[5]*y + mMatrix[ 9]*z + mMatrix[13],
  180. mMatrix[2]*x + mMatrix[6]*y + mMatrix[10]*z + mMatrix[14]);
  181. #else
  182. // Row order
  183. return Vector3d(mMatrix[0]*x + mMatrix[1]*y + mMatrix[ 2]*z + mMatrix[ 3],
  184. mMatrix[4]*x + mMatrix[5]*y + mMatrix[ 6]*z + mMatrix[ 7],
  185. mMatrix[8]*x + mMatrix[9]*y + mMatrix[10]*z + mMatrix[11]);
  186. #endif
  187. }
  188. void Matrix::multiply3v(vec3_t v, vec3_t result)
  189. {
  190. vec_t x = v[0], y = v[1], z = v[2];
  191. result[0] = mMatrix[0]*x + mMatrix[1]*y + mMatrix[ 2]*z + mMatrix[ 3];
  192. result[1] = mMatrix[4]*x + mMatrix[5]*y + mMatrix[ 6]*z + mMatrix[ 7];
  193. result[2] = mMatrix[8]*x + mMatrix[9]*y + mMatrix[10]*z + mMatrix[11];
  194. }
  195. void Matrix::multiply4d(double *v, double *result)
  196. {
  197. double x = v[0], y = v[1], z = v[2], w = v[3];
  198. result[0] = mMatrix[ 0]*x + mMatrix[ 1]*y + mMatrix[ 2]*z + mMatrix[ 3]*w;
  199. result[1] = mMatrix[ 4]*x + mMatrix[ 5]*y + mMatrix[ 6]*z + mMatrix[ 7]*w;
  200. result[2] = mMatrix[ 8]*x + mMatrix[ 9]*y + mMatrix[10]*z + mMatrix[11]*w;
  201. result[3] = mMatrix[12]*x + mMatrix[13]*y + mMatrix[14]*z + mMatrix[15]*w;
  202. }
  203. void Matrix::multiply4v(vec4_t v, vec4_t result)
  204. {
  205. vec_t x = v[0], y = v[1], z = v[2], w = v[3];
  206. result[0] = mMatrix[ 0]*x + mMatrix[ 1]*y + mMatrix[ 2]*z + mMatrix[ 3]*w;
  207. result[1] = mMatrix[ 4]*x + mMatrix[ 5]*y + mMatrix[ 6]*z + mMatrix[ 7]*w;
  208. result[2] = mMatrix[ 8]*x + mMatrix[ 9]*y + mMatrix[10]*z + mMatrix[11]*w;
  209. result[3] = mMatrix[12]*x + mMatrix[13]*y + mMatrix[14]*z + mMatrix[15]*w;
  210. }
  211. void Matrix::print()
  212. {
  213. #ifdef COLUMN_ORDER
  214. printf("{\n%f %f %f %f\n%f %f %f %f\n%f %f %f %f\n%f %f %f %f\n}\n",
  215. mMatrix[0], mMatrix[4], mMatrix[ 8], mMatrix[12],
  216. mMatrix[1], mMatrix[5], mMatrix[ 9], mMatrix[13],
  217. mMatrix[2], mMatrix[6], mMatrix[10], mMatrix[14],
  218. mMatrix[3], mMatrix[7], mMatrix[11], mMatrix[15]);
  219. #else
  220. printf("{\n%f %f %f %f\n%f %f %f %f\n%f %f %f %f\n%f %f %f %f\n}\n",
  221. mMatrix[ 0], mMatrix[ 1], mMatrix[ 2], mMatrix[ 3],
  222. mMatrix[ 4], mMatrix[ 5], mMatrix[ 6], mMatrix[ 7],
  223. mMatrix[ 8], mMatrix[ 9], mMatrix[10], mMatrix[11],
  224. mMatrix[12], mMatrix[13], mMatrix[14], mMatrix[15]);
  225. #endif
  226. }
  227. bool Matrix::isIdentity()
  228. {
  229. // Hhhmm... floating point using direct comparisions
  230. if (mMatrix[ 0] == 1 && mMatrix[ 1] == 0 && mMatrix[ 2] == 0 &&
  231. mMatrix[ 3] == 0 && mMatrix[ 4] == 0 && mMatrix[ 5] == 1 &&
  232. mMatrix[ 6] == 0 && mMatrix[ 7] == 0 && mMatrix[ 8] == 0 &&
  233. mMatrix[ 9] == 0 && mMatrix[10] == 1 && mMatrix[11] == 0 &&
  234. mMatrix[12] == 0 && mMatrix[13] == 0 && mMatrix[14] == 0 &&
  235. mMatrix[15] == 1)
  236. return true;
  237. return false;
  238. }
  239. ////////////////////////////////////////////////////////////
  240. // Public Mutators
  241. ////////////////////////////////////////////////////////////
  242. void Matrix::setMatrix(matrix_t mat)
  243. {
  244. copy(mat, mMatrix);
  245. }
  246. void Matrix::setIdentity()
  247. {
  248. mMatrix[ 0] = 1; mMatrix[ 1] = 0; mMatrix[ 2] = 0; mMatrix[ 3] = 0;
  249. mMatrix[ 4] = 0; mMatrix[ 5] = 1; mMatrix[ 6] = 0; mMatrix[ 7] = 0;
  250. mMatrix[ 8] = 0; mMatrix[ 9] = 0; mMatrix[10] = 1; mMatrix[11] = 0;
  251. mMatrix[12] = 0; mMatrix[13] = 0; mMatrix[14] = 0; mMatrix[15] = 1;
  252. }
  253. void Matrix::scale(const vec_t *xyz)
  254. {
  255. scale(xyz[0], xyz[1], xyz[2]);
  256. }
  257. void Matrix::scale(vec_t sx, vec_t sy, vec_t sz)
  258. {
  259. matrix_t smatrix;
  260. matrix_t tmp;
  261. smatrix[ 0] = sx;smatrix[ 1] = 0; smatrix[ 2] = 0; smatrix[ 3] = 0;
  262. smatrix[ 4] = 0; smatrix[ 5] = sy;smatrix[ 6] = 0; smatrix[ 7] = 0;
  263. smatrix[ 8] = 0; smatrix[ 9] = 0; smatrix[10] = sz;smatrix[11] = 0;
  264. smatrix[12] = 0; smatrix[13] = 0; smatrix[14] = 0; smatrix[15] = 1;
  265. copy(mMatrix, tmp);
  266. multiply(tmp, smatrix, mMatrix);
  267. }
  268. void Matrix::rotate(const vec_t *xyz)
  269. {
  270. rotate(xyz[0], xyz[1], xyz[2]);
  271. }
  272. void Matrix::rotate(vec_t ax, vec_t ay, vec_t az)
  273. {
  274. matrix_t xmat, ymat, zmat, tmp, tmp2;
  275. xmat[ 0]=1; xmat[ 1]=0; xmat[ 2]=0; xmat[ 3]=0;
  276. xmat[ 4]=0; xmat[ 5]=cos(ax); xmat[ 6]=sin(ax); xmat[ 7]=0;
  277. xmat[ 8]=0; xmat[ 9]=-sin(ax); xmat[10]=cos(ax); xmat[11]=0;
  278. xmat[12]=0; xmat[13]=0; xmat[14]=0; xmat[15]=1;
  279. ymat[ 0]=cos(ay); ymat[ 1]=0; ymat[ 2]=-sin(ay); ymat[ 3]=0;
  280. ymat[ 4]=0; ymat[ 5]=1; ymat[ 6]=0; ymat[ 7]=0;
  281. ymat[ 8]=sin(ay); ymat[ 9]=0; ymat[10]=cos(ay); ymat[11]=0;
  282. ymat[12]=0; ymat[13]=0; ymat[14]=0; ymat[15]=1;
  283. zmat[ 0]=cos(az); zmat[ 1]=sin(az); zmat[ 2]=0; zmat[ 3]=0;
  284. zmat[ 4]=-sin(az); zmat[ 5]=cos(az); zmat[ 6]=0; zmat[ 7]=0;
  285. zmat[ 8]=0; zmat[ 9]=0; zmat[10]=1; zmat[11]=0;
  286. zmat[12]=0; zmat[13]=0; zmat[14]=0; zmat[15]=1;
  287. multiply(mMatrix, ymat, tmp);
  288. multiply(tmp, xmat, tmp2);
  289. multiply(tmp2, zmat, mMatrix);
  290. }
  291. void Matrix::translate(const vec_t *xyz)
  292. {
  293. translate(xyz[0], xyz[1], xyz[2]);
  294. }
  295. void Matrix::translate(vec_t tx, vec_t ty, vec_t tz)
  296. {
  297. matrix_t tmat, tmp;
  298. tmat[ 0]=1; tmat[ 1]=0; tmat[ 2]=0; tmat[ 3]=0;
  299. tmat[ 4]=0; tmat[ 5]=1; tmat[ 6]=0; tmat[ 7]=0;
  300. tmat[ 8]=0; tmat[ 9]=0; tmat[10]=1; tmat[11]=0;
  301. tmat[12]=tx; tmat[13]=ty; tmat[14]=tz; tmat[15]=1;
  302. copy(mMatrix, tmp);
  303. multiply(tmp, tmat, mMatrix);
  304. }
  305. ////////////////////////////////////////////////////////////
  306. // Private Accessors
  307. ////////////////////////////////////////////////////////////
  308. ////////////////////////////////////////////////////////////
  309. // Private Mutators
  310. ////////////////////////////////////////////////////////////
  311. void Matrix::copy(matrix_t source, matrix_t dest)
  312. {
  313. #ifdef FASTER_MATRIX
  314. memcpy(dest, source, sizeof(matrix_t));
  315. #else
  316. dest[ 0] = source[ 0];
  317. dest[ 1] = source[ 1];
  318. dest[ 2] = source[ 2];
  319. dest[ 3] = source[ 3];
  320. dest[ 4] = source[ 4];
  321. dest[ 5] = source[ 5];
  322. dest[ 6] = source[ 6];
  323. dest[ 7] = source[ 7];
  324. dest[ 8] = source[8];
  325. dest[ 9] = source[9];
  326. dest[10] = source[10];
  327. dest[11] = source[11];
  328. dest[12] = source[12];
  329. dest[13] = source[13];
  330. dest[14] = source[14];
  331. dest[15] = source[15];
  332. #endif
  333. }
  334. void Matrix::multiply(const matrix_t a, const matrix_t b, matrix_t result)
  335. {
  336. /* Generated code for matrix mult */
  337. #ifdef COLUMN_ORDER
  338. /* Column order */
  339. result[ 0] = a[ 0] * b[ 0] + a[ 4] * b[ 1] + a[ 8] * b[ 2] + a[12] * b[ 3];
  340. result[ 1] = a[ 0] * b[ 4] + a[ 4] * b[ 5] + a[ 8] * b[ 6] + a[12] * b[ 7];
  341. result[ 2] = a[ 0] * b[ 8] + a[ 4] * b[ 9] + a[ 8] * b[10] + a[12] * b[11];
  342. result[ 3] = a[ 0] * b[12] + a[ 4] * b[13] + a[ 8] * b[14] + a[12] * b[15];
  343. result[ 4] = a[ 1] * b[ 0] + a[ 5] * b[ 1] + a[ 9] * b[ 2] + a[13] * b[ 3];
  344. result[ 5] = a[ 1] * b[ 4] + a[ 5] * b[ 5] + a[ 9] * b[ 6] + a[13] * b[ 7];
  345. result[ 6] = a[ 1] * b[ 8] + a[ 5] * b[ 9] + a[ 9] * b[10] + a[13] * b[11];
  346. result[ 7] = a[ 1] * b[12] + a[ 5] * b[13] + a[ 9] * b[14] + a[13] * b[15];
  347. result[ 8] = a[ 2] * b[ 0] + a[ 6] * b[ 1] + a[10] * b[ 2] + a[14] * b[ 3];
  348. result[ 9] = a[ 2] * b[ 4] + a[ 6] * b[ 5] + a[10] * b[ 6] + a[14] * b[ 7];
  349. result[10] = a[ 2] * b[ 8] + a[ 6] * b[ 9] + a[10] * b[10] + a[14] * b[11];
  350. result[11] = a[ 2] * b[12] + a[ 6] * b[13] + a[10] * b[14] + a[14] * b[15];
  351. result[12] = a[ 3] * b[ 0] + a[ 7] * b[ 1] + a[11] * b[ 2] + a[15] * b[ 3];
  352. result[13] = a[ 3] * b[ 4] + a[ 7] * b[ 5] + a[11] * b[ 6] + a[15] * b[ 7];
  353. result[14] = a[ 3] * b[ 8] + a[ 7] * b[ 9] + a[11] * b[10] + a[15] * b[11];
  354. result[15] = a[ 3] * b[12] + a[ 7] * b[13] + a[11] * b[14] + a[15] * b[15];
  355. #else
  356. /* Row order */
  357. result[ 0] = a[ 0] * b[ 0] + a[ 1] * b[ 4] + a[ 2] * b[ 8] + a[ 3] * b[12];
  358. result[ 1] = a[ 0] * b[ 1] + a[ 1] * b[ 5] + a[ 2] * b[ 9] + a[ 3] * b[13];
  359. result[ 2] = a[ 0] * b[ 2] + a[ 1] * b[ 6] + a[ 2] * b[10] + a[ 3] * b[14];
  360. result[ 3] = a[ 0] * b[ 3] + a[ 1] * b[ 7] + a[ 2] * b[11] + a[ 3] * b[15];
  361. result[ 4] = a[ 4] * b[ 0] + a[ 5] * b[ 4] + a[ 6] * b[ 8] + a[ 7] * b[12];
  362. result[ 5] = a[ 4] * b[ 1] + a[ 5] * b[ 5] + a[ 6] * b[ 9] + a[ 7] * b[13];
  363. result[ 6] = a[ 4] * b[ 2] + a[ 5] * b[ 6] + a[ 6] * b[10] + a[ 7] * b[14];
  364. result[ 7] = a[ 4] * b[ 3] + a[ 5] * b[ 7] + a[ 6] * b[11] + a[ 7] * b[15];
  365. result[ 8] = a[ 8] * b[ 0] + a[ 9] * b[ 4] + a[10] * b[ 8] + a[11] * b[12];
  366. result[ 9] = a[ 8] * b[ 1] + a[ 9] * b[ 5] + a[10] * b[ 9] + a[11] * b[13];
  367. result[10] = a[ 8] * b[ 2] + a[ 9] * b[ 6] + a[10] * b[10] + a[11] * b[14];
  368. result[11] = a[ 8] * b[ 3] + a[ 9] * b[ 7] + a[10] * b[11] + a[11] * b[15];
  369. result[12] = a[12] * b[ 0] + a[13] * b[ 4] + a[14] * b[ 8] + a[15] * b[12];
  370. result[13] = a[12] * b[ 1] + a[13] * b[ 5] + a[14] * b[ 9] + a[15] * b[13];
  371. result[14] = a[12] * b[ 2] + a[13] * b[ 6] + a[14] * b[10] + a[15] * b[14];
  372. result[15] = a[12] * b[ 3] + a[13] * b[ 7] + a[14] * b[11] + a[15] * b[15];
  373. #endif
  374. }
  375. ////////////////////////////////////////////////////////////
  376. // Unit Test
  377. ////////////////////////////////////////////////////////////
  378. #ifdef MATRIX_UNIT_TEST
  379. #include <strings.h>
  380. /* <Order> is (r)ow or (c)ol */
  381. void generateMatrixSourceTest(char order)
  382. {
  383. int i, j, k;
  384. if (order == 'r')
  385. {
  386. printf("/* Row order */\n");
  387. }
  388. else
  389. {
  390. printf("/* Column order */\n");
  391. }
  392. for (i = 0; i < 4; ++i)
  393. {
  394. for (j = 0; j < 4; ++j)
  395. {
  396. if (order == 'r')
  397. {
  398. printf("result[%2i] = ", j+i*4);
  399. }
  400. else
  401. {
  402. printf("result[%2i] = ", j+i*4);
  403. }
  404. for (k = 0; k < 4; ++k)
  405. {
  406. if (order == 'r')
  407. {
  408. printf("a[%2i] * b[%2i]%s",
  409. k+i*4, j+k*4, (k == 3) ? ";\n" : " + ");
  410. }
  411. else
  412. {
  413. printf("a[%2i] * b[%2i]%s",
  414. i+k*4, k+j*4, (k == 3) ? ";\n" : " + ");
  415. }
  416. //sum+=(elements[i+k*4]*m.elements[k+j*4]);
  417. }
  418. //result.elements[i+j*4]=sum;
  419. }
  420. printf("\n");
  421. }
  422. printf("\n");
  423. printf("/* Transpose */\n");
  424. for(i = 0; i < 4; ++i)
  425. {
  426. for (j = 0; j < 4; ++j)
  427. {
  428. printf("a[%2i] = b[%2i]%s",
  429. j+i*4, i+j*4, (j == 3) ? ";\n" : "; ");
  430. }
  431. }
  432. }
  433. int runMatrixUnitTest()
  434. {
  435. unsigned int i, errs;
  436. Matrix a, b, c;
  437. matrix_t m;
  438. // Test 3 cases of identity use
  439. for (errs = 0, i = 0; i < 3; ++i)
  440. {
  441. // Fill A matrix with garbage
  442. m[ 0] = m[ 1] = m[ 2] = m[ 3] = 45.0f;
  443. m[ 4] = m[ 5] = m[ 6] = m[ 7] = 90.0f;
  444. m[ 8] = m[ 9] = m[10] = m[11] = 180.0f;
  445. m[12] = m[13] = m[14] = m[15] = 270.0f;
  446. a.setMatrix(m);
  447. switch (i)
  448. {
  449. case 0:
  450. printf("Set to Identity");
  451. a.setIdentity();
  452. break;
  453. case 1:
  454. printf("Identity * Identity");
  455. c.setIdentity();
  456. b.setIdentity();
  457. a = c * b;
  458. break;
  459. case 2:
  460. printf("Identity *= Identity");
  461. a.setIdentity();
  462. b.setIdentity();
  463. a = a * b;
  464. break;
  465. }
  466. if (a.isIdentity())
  467. {
  468. printf(" \t[ Passed ]\n");
  469. }
  470. else
  471. {
  472. ++errs;
  473. printf(" \t[ Failed ]\a\n"); // beep
  474. a.print();
  475. }
  476. printf("\n");
  477. }
  478. /* 2003.06.18, Mongoose - These tests are weak and
  479. only spot check some of the matrix */
  480. /* Cheap translation test */
  481. a.setIdentity();
  482. printf("I -> Translate (10, 20, 30)\n");
  483. a.translate(10, 20, 30);
  484. #ifdef COLUMN_ORDER
  485. unsigned char i0 = 0, i1 = 4, i2 = 8, i3 = 12;
  486. unsigned char i4 = 1, i5 = 5, i6 = 9, i7 = 13;
  487. unsigned char i8 = 2, i9 = 6, i10 = 10, i11 = 14;
  488. unsigned char i12 = 3, i13 = 7, i14 = 11, i15 = 15;
  489. #else
  490. unsigned char i0 = 0, i1 = 1, i2 = 2; // i3 = 3
  491. unsigned char i4 = 4, i6 = 6; // i5 = 5, i7 = 7
  492. unsigned char i8 = 8, i9 = 9, i10 = 10; // i11 = 11
  493. unsigned char i12 = 12, i13 = 13, i14 = 14, i15 = 15;
  494. #endif
  495. if (a.mMatrix[i12] != 10 ||
  496. a.mMatrix[i13] != 20 ||
  497. a.mMatrix[i14] != 30)
  498. {
  499. ++errs;
  500. printf(" \t[ Failed ]\a\n"); // beep
  501. a.print();
  502. }
  503. /* Cheap X rotation test */
  504. a.setIdentity();
  505. printf("I -> Rotate (90 degrees, 0, 0)\n");
  506. a.rotate(90*0.01745329251994329f, 0, 0);
  507. if (a.mMatrix[i0] != 1 || a.mMatrix[i15] != 1 ||
  508. a.mMatrix[i9] != -1 || a.mMatrix[i6] != 1)
  509. {
  510. ++errs;
  511. printf(" \t[ Failed ]\a\n"); // beep
  512. a.print();
  513. }
  514. /* Cheap Y rotation test */
  515. a.setIdentity();
  516. printf("I -> Rotate (0, 90 degrees, 0)\n");
  517. a.rotate(0, 90*0.01745329251994329f, 0);
  518. if (a.mMatrix[i8] != 1 || a.mMatrix[i2] != -1 ||
  519. a.mMatrix[i15] != 1)
  520. {
  521. ++errs;
  522. printf(" \t[ Failed ]\a\n"); // beep
  523. a.print();
  524. }
  525. /* Cheap Z rotation test */
  526. a.setIdentity();
  527. printf("I -> Rotate (0, 0, 90 degrees)\n");
  528. a.rotate(0, 0, 90*0.01745329251994329f);
  529. if (a.mMatrix[i4] != -1 || a.mMatrix[i15] != 1 ||
  530. a.mMatrix[i1] != 1 || a.mMatrix[i10] != 1)
  531. {
  532. ++errs;
  533. printf(" \t[ Failed ]\a\n"); // beep
  534. a.print();
  535. }
  536. printf("\n%i errors\n", errs);
  537. printf("\n");
  538. printf("Prescision test...\n");
  539. printf("I ->\n");
  540. a.setIdentity();
  541. printf(" -> Rotate (0, 0, 90 degrees)\n");
  542. a.rotate(0, 0, 90*0.01745329251994329f);
  543. printf(" -> Translate (10, 20, 30)\n");
  544. a.translate(10, 20, 30);
  545. printf(" -> scale (10, 10, 10)\n");
  546. a.scale(10, 10, 10);
  547. a.print();
  548. printf("\n");
  549. printf(" -> scale (0.1, 0.1, 0.1)\n");
  550. a.scale(0.1, 0.1, 0.1);
  551. printf(" -> Translate (-10, -20, -30)\n");
  552. a.translate(-10, -20, -30);
  553. printf(" -> Rotate (0, 0, -90 degrees)\n");
  554. a.rotate(0, 0, -90*0.01745329251994329f);
  555. a.print();
  556. printf("\n%i errors\n", errs);
  557. return errs;
  558. }
  559. int main(int argc, char *argv[])
  560. {
  561. if (argc > 2)
  562. {
  563. if (strcmp(argv[1], "-src") == 0)
  564. {
  565. generateMatrixSourceTest(argv[2][0]);
  566. return 0;
  567. }
  568. }
  569. printf("[Matrix class test]\n");
  570. runMatrixUnitTest();
  571. return 0;
  572. }
  573. #endif