BsMatrix3.cpp 31 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #include "Math/BsMatrix3.h"
  4. #include "Math/BsQuaternion.h"
  5. #include "Math/BsMath.h"
  6. namespace bs
  7. {
  8. const float Matrix3::EPSILON = 1e-06f;
  9. const Matrix3 Matrix3::ZERO(0,0,0,0,0,0,0,0,0);
  10. const Matrix3 Matrix3::IDENTITY(1,0,0,0,1,0,0,0,1);
  11. const float Matrix3::SVD_EPSILON = 1e-04f;
  12. const unsigned int Matrix3::SVD_MAX_ITERS = 32;
  13. const Matrix3::EulerAngleOrderData Matrix3::EA_LOOKUP[6] =
  14. { { 0, 1, 2, 1.0f}, { 0, 2, 1, -1.0f}, { 1, 0, 2, -1.0f},
  15. { 1, 2, 0, 1.0f}, { 2, 0, 1, 1.0f}, { 2, 1, 0, -1.0f} };;
  16. Vector3 Matrix3::getColumn(UINT32 col) const
  17. {
  18. assert(col < 3);
  19. return Vector3(m[0][col],m[1][col], m[2][col]);
  20. }
  21. void Matrix3::setColumn(UINT32 col, const Vector3& vec)
  22. {
  23. assert(col < 3);
  24. m[0][col] = vec.x;
  25. m[1][col] = vec.y;
  26. m[2][col] = vec.z;
  27. }
  28. void Matrix3::fromAxes(const Vector3& xAxis, const Vector3& yAxis, const Vector3& zAxis)
  29. {
  30. setColumn(0, xAxis);
  31. setColumn(1, yAxis);
  32. setColumn(2, zAxis);
  33. }
  34. bool Matrix3::operator== (const Matrix3& rhs) const
  35. {
  36. for (UINT32 row = 0; row < 3; row++)
  37. {
  38. for (UINT32 col = 0; col < 3; col++)
  39. {
  40. if (m[row][col] != rhs.m[row][col])
  41. return false;
  42. }
  43. }
  44. return true;
  45. }
  46. bool Matrix3::operator!= (const Matrix3& rhs) const
  47. {
  48. return !operator==(rhs);
  49. }
  50. Matrix3 Matrix3::operator+ (const Matrix3& rhs) const
  51. {
  52. Matrix3 sum;
  53. for (UINT32 row = 0; row < 3; row++)
  54. {
  55. for (UINT32 col = 0; col < 3; col++)
  56. {
  57. sum.m[row][col] = m[row][col] + rhs.m[row][col];
  58. }
  59. }
  60. return sum;
  61. }
  62. Matrix3 Matrix3::operator- (const Matrix3& rhs) const
  63. {
  64. Matrix3 diff;
  65. for (UINT32 row = 0; row < 3; row++)
  66. {
  67. for (UINT32 col = 0; col < 3; col++)
  68. {
  69. diff.m[row][col] = m[row][col] -
  70. rhs.m[row][col];
  71. }
  72. }
  73. return diff;
  74. }
  75. Matrix3 Matrix3::operator* (const Matrix3& rhs) const
  76. {
  77. Matrix3 prod;
  78. for (UINT32 row = 0; row < 3; row++)
  79. {
  80. for (UINT32 col = 0; col < 3; col++)
  81. {
  82. prod.m[row][col] = m[row][0]*rhs.m[0][col] +
  83. m[row][1]*rhs.m[1][col] + m[row][2]*rhs.m[2][col];
  84. }
  85. }
  86. return prod;
  87. }
  88. Matrix3 Matrix3::operator- () const
  89. {
  90. Matrix3 neg;
  91. for (UINT32 row = 0; row < 3; row++)
  92. {
  93. for (UINT32 col = 0; col < 3; col++)
  94. neg[row][col] = -m[row][col];
  95. }
  96. return neg;
  97. }
  98. Matrix3 Matrix3::operator* (float rhs) const
  99. {
  100. Matrix3 prod;
  101. for (UINT32 row = 0; row < 3; row++)
  102. {
  103. for (UINT32 col = 0; col < 3; col++)
  104. prod[row][col] = rhs*m[row][col];
  105. }
  106. return prod;
  107. }
  108. Matrix3 operator* (float lhs, const Matrix3& rhs)
  109. {
  110. Matrix3 prod;
  111. for (UINT32 row = 0; row < 3; row++)
  112. {
  113. for (UINT32 col = 0; col < 3; col++)
  114. prod[row][col] = lhs*rhs.m[row][col];
  115. }
  116. return prod;
  117. }
  118. Vector3 Matrix3::transform(const Vector3& vec) const
  119. {
  120. Vector3 prod;
  121. for (UINT32 row = 0; row < 3; row++)
  122. {
  123. prod[row] =
  124. m[row][0]*vec[0] +
  125. m[row][1]*vec[1] +
  126. m[row][2]*vec[2];
  127. }
  128. return prod;
  129. }
  130. Matrix3 Matrix3::transpose() const
  131. {
  132. Matrix3 matTranspose;
  133. for (UINT32 row = 0; row < 3; row++)
  134. {
  135. for (UINT32 col = 0; col < 3; col++)
  136. matTranspose[row][col] = m[col][row];
  137. }
  138. return matTranspose;
  139. }
  140. bool Matrix3::inverse(Matrix3& matInv, float tolerance) const
  141. {
  142. matInv[0][0] = m[1][1]*m[2][2] - m[1][2]*m[2][1];
  143. matInv[0][1] = m[0][2]*m[2][1] - m[0][1]*m[2][2];
  144. matInv[0][2] = m[0][1]*m[1][2] - m[0][2]*m[1][1];
  145. matInv[1][0] = m[1][2]*m[2][0] - m[1][0]*m[2][2];
  146. matInv[1][1] = m[0][0]*m[2][2] - m[0][2]*m[2][0];
  147. matInv[1][2] = m[0][2]*m[1][0] - m[0][0]*m[1][2];
  148. matInv[2][0] = m[1][0]*m[2][1] - m[1][1]*m[2][0];
  149. matInv[2][1] = m[0][1]*m[2][0] - m[0][0]*m[2][1];
  150. matInv[2][2] = m[0][0]*m[1][1] - m[0][1]*m[1][0];
  151. float det = m[0][0]*matInv[0][0] + m[0][1]*matInv[1][0] + m[0][2]*matInv[2][0];
  152. if (Math::abs(det) <= tolerance)
  153. return false;
  154. float invDet = 1.0f/det;
  155. for (UINT32 row = 0; row < 3; row++)
  156. {
  157. for (UINT32 col = 0; col < 3; col++)
  158. matInv[row][col] *= invDet;
  159. }
  160. return true;
  161. }
  162. Matrix3 Matrix3::inverse(float tolerance) const
  163. {
  164. Matrix3 matInv = Matrix3::ZERO;
  165. inverse(matInv, tolerance);
  166. return matInv;
  167. }
  168. float Matrix3::determinant() const
  169. {
  170. float cofactor00 = m[1][1]*m[2][2] - m[1][2]*m[2][1];
  171. float cofactor10 = m[1][2]*m[2][0] - m[1][0]*m[2][2];
  172. float cofactor20 = m[1][0]*m[2][1] - m[1][1]*m[2][0];
  173. float det = m[0][0]*cofactor00 + m[0][1]*cofactor10 + m[0][2]*cofactor20;
  174. return det;
  175. }
  176. void Matrix3::bidiagonalize (Matrix3& matA, Matrix3& matL, Matrix3& matR)
  177. {
  178. float v[3], w[3];
  179. float length, sign, t1, invT1, t2;
  180. bool bIdentity;
  181. // Map first column to (*,0,0)
  182. length = Math::sqrt(matA[0][0]*matA[0][0] + matA[1][0]*matA[1][0] + matA[2][0]*matA[2][0]);
  183. if (length > 0.0f)
  184. {
  185. sign = (matA[0][0] > 0.0f ? 1.0f : -1.0f);
  186. t1 = matA[0][0] + sign*length;
  187. invT1 = 1.0f/t1;
  188. v[1] = matA[1][0]*invT1;
  189. v[2] = matA[2][0]*invT1;
  190. t2 = -2.0f/(1.0f+v[1]*v[1]+v[2]*v[2]);
  191. w[0] = t2*(matA[0][0]+matA[1][0]*v[1]+matA[2][0]*v[2]);
  192. w[1] = t2*(matA[0][1]+matA[1][1]*v[1]+matA[2][1]*v[2]);
  193. w[2] = t2*(matA[0][2]+matA[1][2]*v[1]+matA[2][2]*v[2]);
  194. matA[0][0] += w[0];
  195. matA[0][1] += w[1];
  196. matA[0][2] += w[2];
  197. matA[1][1] += v[1]*w[1];
  198. matA[1][2] += v[1]*w[2];
  199. matA[2][1] += v[2]*w[1];
  200. matA[2][2] += v[2]*w[2];
  201. matL[0][0] = 1.0f+t2;
  202. matL[0][1] = matL[1][0] = t2*v[1];
  203. matL[0][2] = matL[2][0] = t2*v[2];
  204. matL[1][1] = 1.0f+t2*v[1]*v[1];
  205. matL[1][2] = matL[2][1] = t2*v[1]*v[2];
  206. matL[2][2] = 1.0f+t2*v[2]*v[2];
  207. bIdentity = false;
  208. }
  209. else
  210. {
  211. matL = Matrix3::IDENTITY;
  212. bIdentity = true;
  213. }
  214. // Map first row to (*,*,0)
  215. length = Math::sqrt(matA[0][1]*matA[0][1]+matA[0][2]*matA[0][2]);
  216. if ( length > 0.0 )
  217. {
  218. sign = (matA[0][1] > 0.0f ? 1.0f : -1.0f);
  219. t1 = matA[0][1] + sign*length;
  220. v[2] = matA[0][2]/t1;
  221. t2 = -2.0f/(1.0f+v[2]*v[2]);
  222. w[0] = t2*(matA[0][1]+matA[0][2]*v[2]);
  223. w[1] = t2*(matA[1][1]+matA[1][2]*v[2]);
  224. w[2] = t2*(matA[2][1]+matA[2][2]*v[2]);
  225. matA[0][1] += w[0];
  226. matA[1][1] += w[1];
  227. matA[1][2] += w[1]*v[2];
  228. matA[2][1] += w[2];
  229. matA[2][2] += w[2]*v[2];
  230. matR[0][0] = 1.0;
  231. matR[0][1] = matR[1][0] = 0.0;
  232. matR[0][2] = matR[2][0] = 0.0;
  233. matR[1][1] = 1.0f+t2;
  234. matR[1][2] = matR[2][1] = t2*v[2];
  235. matR[2][2] = 1.0f+t2*v[2]*v[2];
  236. }
  237. else
  238. {
  239. matR = Matrix3::IDENTITY;
  240. }
  241. // Map second column to (*,*,0)
  242. length = Math::sqrt(matA[1][1]*matA[1][1]+matA[2][1]*matA[2][1]);
  243. if ( length > 0.0 )
  244. {
  245. sign = (matA[1][1] > 0.0f ? 1.0f : -1.0f);
  246. t1 = matA[1][1] + sign*length;
  247. v[2] = matA[2][1]/t1;
  248. t2 = -2.0f/(1.0f+v[2]*v[2]);
  249. w[1] = t2*(matA[1][1]+matA[2][1]*v[2]);
  250. w[2] = t2*(matA[1][2]+matA[2][2]*v[2]);
  251. matA[1][1] += w[1];
  252. matA[1][2] += w[2];
  253. matA[2][2] += v[2]*w[2];
  254. float a = 1.0f+t2;
  255. float b = t2*v[2];
  256. float c = 1.0f+b*v[2];
  257. if (bIdentity)
  258. {
  259. matL[0][0] = 1.0;
  260. matL[0][1] = matL[1][0] = 0.0;
  261. matL[0][2] = matL[2][0] = 0.0;
  262. matL[1][1] = a;
  263. matL[1][2] = matL[2][1] = b;
  264. matL[2][2] = c;
  265. }
  266. else
  267. {
  268. for (int row = 0; row < 3; row++)
  269. {
  270. float tmp0 = matL[row][1];
  271. float tmp1 = matL[row][2];
  272. matL[row][1] = a*tmp0+b*tmp1;
  273. matL[row][2] = b*tmp0+c*tmp1;
  274. }
  275. }
  276. }
  277. }
  278. void Matrix3::golubKahanStep (Matrix3& matA, Matrix3& matL, Matrix3& matR)
  279. {
  280. float f11 = matA[0][1]*matA[0][1]+matA[1][1]*matA[1][1];
  281. float t22 = matA[1][2]*matA[1][2]+matA[2][2]*matA[2][2];
  282. float t12 = matA[1][1]*matA[1][2];
  283. float trace = f11+t22;
  284. float diff = f11-t22;
  285. float discr = Math::sqrt(diff*diff+4.0f*t12*t12);
  286. float root1 = 0.5f*(trace+discr);
  287. float root2 = 0.5f*(trace-discr);
  288. // Adjust right
  289. float y = matA[0][0] - (Math::abs(root1-t22) <= Math::abs(root2-t22) ? root1 : root2);
  290. float z = matA[0][1];
  291. float invLength = Math::invSqrt(y*y+z*z);
  292. float sin = z*invLength;
  293. float cos = -y*invLength;
  294. float tmp0 = matA[0][0];
  295. float tmp1 = matA[0][1];
  296. matA[0][0] = cos*tmp0-sin*tmp1;
  297. matA[0][1] = sin*tmp0+cos*tmp1;
  298. matA[1][0] = -sin*matA[1][1];
  299. matA[1][1] *= cos;
  300. UINT32 row;
  301. for (row = 0; row < 3; row++)
  302. {
  303. tmp0 = matR[0][row];
  304. tmp1 = matR[1][row];
  305. matR[0][row] = cos*tmp0-sin*tmp1;
  306. matR[1][row] = sin*tmp0+cos*tmp1;
  307. }
  308. // Adjust left
  309. y = matA[0][0];
  310. z = matA[1][0];
  311. invLength = Math::invSqrt(y*y+z*z);
  312. sin = z*invLength;
  313. cos = -y*invLength;
  314. matA[0][0] = cos*matA[0][0]-sin*matA[1][0];
  315. tmp0 = matA[0][1];
  316. tmp1 = matA[1][1];
  317. matA[0][1] = cos*tmp0-sin*tmp1;
  318. matA[1][1] = sin*tmp0+cos*tmp1;
  319. matA[0][2] = -sin*matA[1][2];
  320. matA[1][2] *= cos;
  321. UINT32 col;
  322. for (col = 0; col < 3; col++)
  323. {
  324. tmp0 = matL[col][0];
  325. tmp1 = matL[col][1];
  326. matL[col][0] = cos*tmp0-sin*tmp1;
  327. matL[col][1] = sin*tmp0+cos*tmp1;
  328. }
  329. // Adjust right
  330. y = matA[0][1];
  331. z = matA[0][2];
  332. invLength = Math::invSqrt(y*y+z*z);
  333. sin = z*invLength;
  334. cos = -y*invLength;
  335. matA[0][1] = cos*matA[0][1]-sin*matA[0][2];
  336. tmp0 = matA[1][1];
  337. tmp1 = matA[1][2];
  338. matA[1][1] = cos*tmp0-sin*tmp1;
  339. matA[1][2] = sin*tmp0+cos*tmp1;
  340. matA[2][1] = -sin*matA[2][2];
  341. matA[2][2] *= cos;
  342. for (row = 0; row < 3; row++)
  343. {
  344. tmp0 = matR[1][row];
  345. tmp1 = matR[2][row];
  346. matR[1][row] = cos*tmp0-sin*tmp1;
  347. matR[2][row] = sin*tmp0+cos*tmp1;
  348. }
  349. // Adjust left
  350. y = matA[1][1];
  351. z = matA[2][1];
  352. invLength = Math::invSqrt(y*y+z*z);
  353. sin = z*invLength;
  354. cos = -y*invLength;
  355. matA[1][1] = cos*matA[1][1]-sin*matA[2][1];
  356. tmp0 = matA[1][2];
  357. tmp1 = matA[2][2];
  358. matA[1][2] = cos*tmp0-sin*tmp1;
  359. matA[2][2] = sin*tmp0+cos*tmp1;
  360. for (col = 0; col < 3; col++)
  361. {
  362. tmp0 = matL[col][1];
  363. tmp1 = matL[col][2];
  364. matL[col][1] = cos*tmp0-sin*tmp1;
  365. matL[col][2] = sin*tmp0+cos*tmp1;
  366. }
  367. }
  368. void Matrix3::singularValueDecomposition(Matrix3& matL, Vector3& matS, Matrix3& matR) const
  369. {
  370. UINT32 row, col;
  371. Matrix3 mat = *this;
  372. bidiagonalize(mat, matL, matR);
  373. for (unsigned int i = 0; i < SVD_MAX_ITERS; i++)
  374. {
  375. float tmp, tmp0, tmp1;
  376. float sin0, cos0, tan0;
  377. float sin1, cos1, tan1;
  378. bool test1 = (Math::abs(mat[0][1]) <= SVD_EPSILON*(Math::abs(mat[0][0])+Math::abs(mat[1][1])));
  379. bool test2 = (Math::abs(mat[1][2]) <= SVD_EPSILON*(Math::abs(mat[1][1])+Math::abs(mat[2][2])));
  380. if (test1)
  381. {
  382. if (test2)
  383. {
  384. matS[0] = mat[0][0];
  385. matS[1] = mat[1][1];
  386. matS[2] = mat[2][2];
  387. break;
  388. }
  389. else
  390. {
  391. // 2x2 closed form factorization
  392. tmp = (mat[1][1]*mat[1][1] - mat[2][2]*mat[2][2] + mat[1][2]*mat[1][2])/(mat[1][2]*mat[2][2]);
  393. tan0 = 0.5f*(tmp+Math::sqrt(tmp*tmp + 4.0f));
  394. cos0 = Math::invSqrt(1.0f+tan0*tan0);
  395. sin0 = tan0*cos0;
  396. for (col = 0; col < 3; col++)
  397. {
  398. tmp0 = matL[col][1];
  399. tmp1 = matL[col][2];
  400. matL[col][1] = cos0*tmp0-sin0*tmp1;
  401. matL[col][2] = sin0*tmp0+cos0*tmp1;
  402. }
  403. tan1 = (mat[1][2]-mat[2][2]*tan0)/mat[1][1];
  404. cos1 = Math::invSqrt(1.0f+tan1*tan1);
  405. sin1 = -tan1*cos1;
  406. for (row = 0; row < 3; row++)
  407. {
  408. tmp0 = matR[1][row];
  409. tmp1 = matR[2][row];
  410. matR[1][row] = cos1*tmp0-sin1*tmp1;
  411. matR[2][row] = sin1*tmp0+cos1*tmp1;
  412. }
  413. matS[0] = mat[0][0];
  414. matS[1] = cos0*cos1*mat[1][1] - sin1*(cos0*mat[1][2]-sin0*mat[2][2]);
  415. matS[2] = sin0*sin1*mat[1][1] + cos1*(sin0*mat[1][2]+cos0*mat[2][2]);
  416. break;
  417. }
  418. }
  419. else
  420. {
  421. if (test2)
  422. {
  423. // 2x2 closed form factorization
  424. tmp = (mat[0][0]*mat[0][0] + mat[1][1]*mat[1][1] - mat[0][1]*mat[0][1])/(mat[0][1]*mat[1][1]);
  425. tan0 = 0.5f*(-tmp+Math::sqrt(tmp*tmp + 4.0f));
  426. cos0 = Math::invSqrt(1.0f+tan0*tan0);
  427. sin0 = tan0*cos0;
  428. for (col = 0; col < 3; col++)
  429. {
  430. tmp0 = matL[col][0];
  431. tmp1 = matL[col][1];
  432. matL[col][0] = cos0*tmp0-sin0*tmp1;
  433. matL[col][1] = sin0*tmp0+cos0*tmp1;
  434. }
  435. tan1 = (mat[0][1]-mat[1][1]*tan0)/mat[0][0];
  436. cos1 = Math::invSqrt(1.0f+tan1*tan1);
  437. sin1 = -tan1*cos1;
  438. for (row = 0; row < 3; row++)
  439. {
  440. tmp0 = matR[0][row];
  441. tmp1 = matR[1][row];
  442. matR[0][row] = cos1*tmp0-sin1*tmp1;
  443. matR[1][row] = sin1*tmp0+cos1*tmp1;
  444. }
  445. matS[0] = cos0*cos1*mat[0][0] - sin1*(cos0*mat[0][1]-sin0*mat[1][1]);
  446. matS[1] = sin0*sin1*mat[0][0] + cos1*(sin0*mat[0][1]+cos0*mat[1][1]);
  447. matS[2] = mat[2][2];
  448. break;
  449. }
  450. else
  451. {
  452. golubKahanStep(mat, matL, matR);
  453. }
  454. }
  455. }
  456. // Positize diagonal
  457. for (row = 0; row < 3; row++)
  458. {
  459. if ( matS[row] < 0.0 )
  460. {
  461. matS[row] = -matS[row];
  462. for (col = 0; col < 3; col++)
  463. matR[row][col] = -matR[row][col];
  464. }
  465. }
  466. }
  467. void Matrix3::orthonormalize()
  468. {
  469. // Compute q0
  470. float invLength = Math::invSqrt(m[0][0]*m[0][0]+ m[1][0]*m[1][0] + m[2][0]*m[2][0]);
  471. m[0][0] *= invLength;
  472. m[1][0] *= invLength;
  473. m[2][0] *= invLength;
  474. // Compute q1
  475. float dot0 = m[0][0]*m[0][1] + m[1][0]*m[1][1] + m[2][0]*m[2][1];
  476. m[0][1] -= dot0*m[0][0];
  477. m[1][1] -= dot0*m[1][0];
  478. m[2][1] -= dot0*m[2][0];
  479. invLength = Math::invSqrt(m[0][1]*m[0][1] + m[1][1]*m[1][1] + m[2][1]*m[2][1]);
  480. m[0][1] *= invLength;
  481. m[1][1] *= invLength;
  482. m[2][1] *= invLength;
  483. // Compute q2
  484. float dot1 = m[0][1]*m[0][2] + m[1][1]*m[1][2] + m[2][1]*m[2][2];
  485. dot0 = m[0][0]*m[0][2] + m[1][0]*m[1][2] + m[2][0]*m[2][2];
  486. m[0][2] -= dot0*m[0][0] + dot1*m[0][1];
  487. m[1][2] -= dot0*m[1][0] + dot1*m[1][1];
  488. m[2][2] -= dot0*m[2][0] + dot1*m[2][1];
  489. invLength = Math::invSqrt(m[0][2]*m[0][2] + m[1][2]*m[1][2] + m[2][2]*m[2][2]);
  490. m[0][2] *= invLength;
  491. m[1][2] *= invLength;
  492. m[2][2] *= invLength;
  493. }
  494. void Matrix3::decomposition(Quaternion& rotation, Vector3& scale) const
  495. {
  496. Matrix3 matQ;
  497. Vector3 vecU;
  498. QDUDecomposition(matQ, scale, vecU);
  499. rotation = Quaternion(matQ);
  500. }
  501. void Matrix3::QDUDecomposition(Matrix3& matQ, Vector3& vecD, Vector3& vecU) const
  502. {
  503. // Build orthogonal matrix Q
  504. float invLength = Math::invSqrt(m[0][0]*m[0][0] + m[1][0]*m[1][0] + m[2][0]*m[2][0]);
  505. matQ[0][0] = m[0][0]*invLength;
  506. matQ[1][0] = m[1][0]*invLength;
  507. matQ[2][0] = m[2][0]*invLength;
  508. float dot = matQ[0][0]*m[0][1] + matQ[1][0]*m[1][1] + matQ[2][0]*m[2][1];
  509. matQ[0][1] = m[0][1]-dot*matQ[0][0];
  510. matQ[1][1] = m[1][1]-dot*matQ[1][0];
  511. matQ[2][1] = m[2][1]-dot*matQ[2][0];
  512. invLength = Math::invSqrt(matQ[0][1]*matQ[0][1] + matQ[1][1]*matQ[1][1] + matQ[2][1]*matQ[2][1]);
  513. matQ[0][1] *= invLength;
  514. matQ[1][1] *= invLength;
  515. matQ[2][1] *= invLength;
  516. dot = matQ[0][0]*m[0][2] + matQ[1][0]*m[1][2] + matQ[2][0]*m[2][2];
  517. matQ[0][2] = m[0][2]-dot*matQ[0][0];
  518. matQ[1][2] = m[1][2]-dot*matQ[1][0];
  519. matQ[2][2] = m[2][2]-dot*matQ[2][0];
  520. dot = matQ[0][1]*m[0][2] + matQ[1][1]*m[1][2] + matQ[2][1]*m[2][2];
  521. matQ[0][2] -= dot*matQ[0][1];
  522. matQ[1][2] -= dot*matQ[1][1];
  523. matQ[2][2] -= dot*matQ[2][1];
  524. invLength = Math::invSqrt(matQ[0][2]*matQ[0][2] + matQ[1][2]*matQ[1][2] + matQ[2][2]*matQ[2][2]);
  525. matQ[0][2] *= invLength;
  526. matQ[1][2] *= invLength;
  527. matQ[2][2] *= invLength;
  528. // Guarantee that orthogonal matrix has determinant 1 (no reflections)
  529. float fDet = matQ[0][0]*matQ[1][1]*matQ[2][2] + matQ[0][1]*matQ[1][2]*matQ[2][0] +
  530. matQ[0][2]*matQ[1][0]*matQ[2][1] - matQ[0][2]*matQ[1][1]*matQ[2][0] -
  531. matQ[0][1]*matQ[1][0]*matQ[2][2] - matQ[0][0]*matQ[1][2]*matQ[2][1];
  532. if (fDet < 0.0f)
  533. {
  534. for (UINT32 row = 0; row < 3; row++)
  535. for (UINT32 col = 0; col < 3; col++)
  536. matQ[row][col] = -matQ[row][col];
  537. }
  538. // Build "right" matrix R
  539. Matrix3 matRight;
  540. matRight[0][0] = matQ[0][0]*m[0][0] + matQ[1][0]*m[1][0] +
  541. matQ[2][0]*m[2][0];
  542. matRight[0][1] = matQ[0][0]*m[0][1] + matQ[1][0]*m[1][1] +
  543. matQ[2][0]*m[2][1];
  544. matRight[1][1] = matQ[0][1]*m[0][1] + matQ[1][1]*m[1][1] +
  545. matQ[2][1]*m[2][1];
  546. matRight[0][2] = matQ[0][0]*m[0][2] + matQ[1][0]*m[1][2] +
  547. matQ[2][0]*m[2][2];
  548. matRight[1][2] = matQ[0][1]*m[0][2] + matQ[1][1]*m[1][2] +
  549. matQ[2][1]*m[2][2];
  550. matRight[2][2] = matQ[0][2]*m[0][2] + matQ[1][2]*m[1][2] +
  551. matQ[2][2]*m[2][2];
  552. // The scaling component
  553. vecD[0] = matRight[0][0];
  554. vecD[1] = matRight[1][1];
  555. vecD[2] = matRight[2][2];
  556. // The shear component
  557. float invD0 = 1.0f/vecD[0];
  558. vecU[0] = matRight[0][1]*invD0;
  559. vecU[1] = matRight[0][2]*invD0;
  560. vecU[2] = matRight[1][2]/vecD[1];
  561. }
  562. void Matrix3::toAxisAngle(Vector3& axis, Radian& radians) const
  563. {
  564. float trace = m[0][0] + m[1][1] + m[2][2];
  565. float cos = 0.5f*(trace-1.0f);
  566. radians = Math::acos(cos); // In [0, PI]
  567. if (radians > Radian(0.0f))
  568. {
  569. if (radians < Radian(Math::PI))
  570. {
  571. axis.x = m[2][1]-m[1][2];
  572. axis.y = m[0][2]-m[2][0];
  573. axis.z = m[1][0]-m[0][1];
  574. axis.normalize();
  575. }
  576. else
  577. {
  578. // Angle is PI
  579. float fHalfInverse;
  580. if (m[0][0] >= m[1][1])
  581. {
  582. // r00 >= r11
  583. if (m[0][0] >= m[2][2])
  584. {
  585. // r00 is maximum diagonal term
  586. axis.x = 0.5f*Math::sqrt(m[0][0] - m[1][1] - m[2][2] + 1.0f);
  587. fHalfInverse = 0.5f/axis.x;
  588. axis.y = fHalfInverse*m[0][1];
  589. axis.z = fHalfInverse*m[0][2];
  590. }
  591. else
  592. {
  593. // r22 is maximum diagonal term
  594. axis.z = 0.5f*Math::sqrt(m[2][2] - m[0][0] - m[1][1] + 1.0f);
  595. fHalfInverse = 0.5f/axis.z;
  596. axis.x = fHalfInverse*m[0][2];
  597. axis.y = fHalfInverse*m[1][2];
  598. }
  599. }
  600. else
  601. {
  602. // r11 > r00
  603. if ( m[1][1] >= m[2][2] )
  604. {
  605. // r11 is maximum diagonal term
  606. axis.y = 0.5f*Math::sqrt(m[1][1] - m[0][0] - m[2][2] + 1.0f);
  607. fHalfInverse = 0.5f/axis.y;
  608. axis.x = fHalfInverse*m[0][1];
  609. axis.z = fHalfInverse*m[1][2];
  610. }
  611. else
  612. {
  613. // r22 is maximum diagonal term
  614. axis.z = 0.5f*Math::sqrt(m[2][2] - m[0][0] - m[1][1] + 1.0f);
  615. fHalfInverse = 0.5f/axis.z;
  616. axis.x = fHalfInverse*m[0][2];
  617. axis.y = fHalfInverse*m[1][2];
  618. }
  619. }
  620. }
  621. }
  622. else
  623. {
  624. // The angle is 0 and the matrix is the identity. Any axis will
  625. // work, so just use the x-axis.
  626. axis.x = 1.0f;
  627. axis.y = 0.0f;
  628. axis.z = 0.0f;
  629. }
  630. }
  631. void Matrix3::fromAxisAngle(const Vector3& axis, const Radian& angle)
  632. {
  633. float cos = Math::cos(angle);
  634. float sin = Math::sin(angle);
  635. float oneMinusCos = 1.0f-cos;
  636. float x2 = axis.x*axis.x;
  637. float y2 = axis.y*axis.y;
  638. float z2 = axis.z*axis.z;
  639. float xym = axis.x*axis.y*oneMinusCos;
  640. float xzm = axis.x*axis.z*oneMinusCos;
  641. float yzm = axis.y*axis.z*oneMinusCos;
  642. float xSin = axis.x*sin;
  643. float ySin = axis.y*sin;
  644. float zSin = axis.z*sin;
  645. m[0][0] = x2*oneMinusCos+cos;
  646. m[0][1] = xym-zSin;
  647. m[0][2] = xzm+ySin;
  648. m[1][0] = xym+zSin;
  649. m[1][1] = y2*oneMinusCos+cos;
  650. m[1][2] = yzm-xSin;
  651. m[2][0] = xzm-ySin;
  652. m[2][1] = yzm+xSin;
  653. m[2][2] = z2*oneMinusCos+cos;
  654. }
  655. void Matrix3::toQuaternion(Quaternion& quat) const
  656. {
  657. quat.fromRotationMatrix(*this);
  658. }
  659. void Matrix3::fromQuaternion(const Quaternion& quat)
  660. {
  661. quat.toRotationMatrix(*this);
  662. }
  663. bool Matrix3::toEulerAngles(Radian& xAngle, Radian& yAngle, Radian& zAngle) const
  664. {
  665. xAngle = -Radian(Math::asin(m[1][2]));
  666. if (xAngle < Radian(Math::HALF_PI))
  667. {
  668. if (xAngle > Radian(-Math::HALF_PI))
  669. {
  670. yAngle = Math::atan2(m[0][2], m[2][2]);
  671. zAngle = Math::atan2(m[1][0], m[1][1]);
  672. return true;
  673. }
  674. else
  675. {
  676. // Note: Not an unique solution.
  677. xAngle = Radian(-Math::HALF_PI);
  678. yAngle = Math::atan2(-m[0][1], m[0][0]);
  679. zAngle = Radian(0.0f);
  680. return false;
  681. }
  682. }
  683. else
  684. {
  685. // Note: Not an unique solution.
  686. xAngle = Radian(Math::HALF_PI);
  687. yAngle = Math::atan2(m[0][1], m[0][0]);
  688. zAngle = Radian(0.0f);
  689. return false;
  690. }
  691. }
  692. void Matrix3::fromEulerAngles(const Radian& xAngle, const Radian& yAngle, const Radian& zAngle)
  693. {
  694. float cx = Math::cos(xAngle);
  695. float sx = Math::sin(xAngle);
  696. float cy = Math::cos(yAngle);
  697. float sy = Math::sin(yAngle);
  698. float cz = Math::cos(zAngle);
  699. float sz = Math::sin(zAngle);
  700. m[0][0] = cy * cz + sx * sy * sz;
  701. m[0][1] = cz * sx * sy - cy * sz;
  702. m[0][2] = cx * sy;
  703. m[1][0] = cx * sz;
  704. m[1][1] = cx * cz;
  705. m[1][2] = -sx;
  706. m[2][0] = -cz * sy + cy * sx * sz;
  707. m[2][1] = cy * cz * sx + sy * sz;
  708. m[2][2] = cx * cy;
  709. }
  710. void Matrix3::fromEulerAngles(const Radian& xAngle, const Radian& yAngle, const Radian& zAngle, EulerAngleOrder order)
  711. {
  712. const EulerAngleOrderData& l = EA_LOOKUP[(int)order];
  713. Matrix3 mats[3];
  714. float cx = Math::cos(xAngle);
  715. float sx = Math::sin(xAngle);
  716. mats[0] = Matrix3(
  717. 1.0f, 0.0f, 0.0f,
  718. 0.0f, cx, -sx,
  719. 0.0f, sx, cx);
  720. float cy = Math::cos(yAngle);
  721. float sy = Math::sin(yAngle);
  722. mats[1] = Matrix3(
  723. cy, 0.0f, sy,
  724. 0.0f, 1.0f, 0.0f,
  725. -sy, 0.0f, cy);
  726. float cz = Math::cos(zAngle);
  727. float sz = Math::sin(zAngle);
  728. mats[2] = Matrix3(
  729. cz, -sz, 0.0f,
  730. sz, cz, 0.0f,
  731. 0.0f, 0.0f, 1.0f);
  732. *this = mats[l.c]*(mats[l.b]*mats[l.a]);
  733. }
  734. void Matrix3::tridiagonal(float diag[3], float subDiag[3])
  735. {
  736. // Householder reduction T = Q^t M Q
  737. // Input:
  738. // mat, symmetric 3x3 matrix M
  739. // Output:
  740. // mat, orthogonal matrix Q
  741. // diag, diagonal entries of T
  742. // subd, subdiagonal entries of T (T is symmetric)
  743. float fA = m[0][0];
  744. float fB = m[0][1];
  745. float fC = m[0][2];
  746. float fD = m[1][1];
  747. float fE = m[1][2];
  748. float fF = m[2][2];
  749. diag[0] = fA;
  750. subDiag[2] = 0.0;
  751. if (Math::abs(fC) >= EPSILON)
  752. {
  753. float length = Math::sqrt(fB*fB+fC*fC);
  754. float invLength = 1.0f/length;
  755. fB *= invLength;
  756. fC *= invLength;
  757. float fQ = 2.0f*fB*fE+fC*(fF-fD);
  758. diag[1] = fD+fC*fQ;
  759. diag[2] = fF-fC*fQ;
  760. subDiag[0] = length;
  761. subDiag[1] = fE-fB*fQ;
  762. m[0][0] = 1.0;
  763. m[0][1] = 0.0;
  764. m[0][2] = 0.0;
  765. m[1][0] = 0.0;
  766. m[1][1] = fB;
  767. m[1][2] = fC;
  768. m[2][0] = 0.0;
  769. m[2][1] = fC;
  770. m[2][2] = -fB;
  771. }
  772. else
  773. {
  774. diag[1] = fD;
  775. diag[2] = fF;
  776. subDiag[0] = fB;
  777. subDiag[1] = fE;
  778. m[0][0] = 1.0;
  779. m[0][1] = 0.0;
  780. m[0][2] = 0.0;
  781. m[1][0] = 0.0;
  782. m[1][1] = 1.0;
  783. m[1][2] = 0.0;
  784. m[2][0] = 0.0;
  785. m[2][1] = 0.0;
  786. m[2][2] = 1.0;
  787. }
  788. }
  789. bool Matrix3::QLAlgorithm(float diag[3], float subDiag[3])
  790. {
  791. // QL iteration with implicit shifting to reduce matrix from tridiagonal to diagonal
  792. for (int i = 0; i < 3; i++)
  793. {
  794. const unsigned int maxIter = 32;
  795. unsigned int iter;
  796. for (iter = 0; iter < maxIter; iter++)
  797. {
  798. int j;
  799. for (j = i; j <= 1; j++)
  800. {
  801. float sum = Math::abs(diag[j]) + Math::abs(diag[j+1]);
  802. if (Math::abs(subDiag[j]) + sum == sum)
  803. break;
  804. }
  805. if (j == i)
  806. break;
  807. float tmp0 = (diag[i+1]-diag[i])/(2.0f*subDiag[i]);
  808. float tmp1 = Math::sqrt(tmp0*tmp0+1.0f);
  809. if (tmp0 < 0.0f)
  810. tmp0 = diag[j]-diag[i]+subDiag[i]/(tmp0-tmp1);
  811. else
  812. tmp0 = diag[j]-diag[i]+subDiag[i]/(tmp0+tmp1);
  813. float sin = 1.0f;
  814. float cos = 1.0f;
  815. float tmp2 = 0.0f;
  816. for (int k = j-1; k >= i; k--)
  817. {
  818. float tmp3 = sin*subDiag[k];
  819. float tmp4 = cos*subDiag[k];
  820. if (Math::abs(tmp3) >= Math::abs(tmp0))
  821. {
  822. cos = tmp0/tmp3;
  823. tmp1 = Math::sqrt(cos*cos+1.0f);
  824. subDiag[k+1] = tmp3*tmp1;
  825. sin = 1.0f/tmp1;
  826. cos *= sin;
  827. }
  828. else
  829. {
  830. sin = tmp3/tmp0;
  831. tmp1 = Math::sqrt(sin*sin+1.0f);
  832. subDiag[k+1] = tmp0*tmp1;
  833. cos = 1.0f/tmp1;
  834. sin *= cos;
  835. }
  836. tmp0 = diag[k+1]-tmp2;
  837. tmp1 = (diag[k]-tmp0)*sin+2.0f*tmp4*cos;
  838. tmp2 = sin*tmp1;
  839. diag[k+1] = tmp0+tmp2;
  840. tmp0 = cos*tmp1-tmp4;
  841. for (int row = 0; row < 3; row++)
  842. {
  843. tmp3 = m[row][k+1];
  844. m[row][k+1] = sin*m[row][k] + cos*tmp3;
  845. m[row][k] = cos*m[row][k] - sin*tmp3;
  846. }
  847. }
  848. diag[i] -= tmp2;
  849. subDiag[i] = tmp0;
  850. subDiag[j] = 0.0;
  851. }
  852. if (iter == maxIter)
  853. {
  854. // Should not get here under normal circumstances
  855. return false;
  856. }
  857. }
  858. return true;
  859. }
  860. void Matrix3::eigenSolveSymmetric(float eigenValues[3], Vector3 eigenVectors[3]) const
  861. {
  862. Matrix3 mat = *this;
  863. float subDiag[3];
  864. mat.tridiagonal(eigenValues, subDiag);
  865. mat.QLAlgorithm(eigenValues, subDiag);
  866. for (UINT32 i = 0; i < 3; i++)
  867. {
  868. eigenVectors[i][0] = mat[0][i];
  869. eigenVectors[i][1] = mat[1][i];
  870. eigenVectors[i][2] = mat[2][i];
  871. }
  872. // Make eigenvectors form a right--handed system
  873. Vector3 cross = eigenVectors[1].cross(eigenVectors[2]);
  874. float det = eigenVectors[0].dot(cross);
  875. if (det < 0.0f)
  876. {
  877. eigenVectors[2][0] = -eigenVectors[2][0];
  878. eigenVectors[2][1] = -eigenVectors[2][1];
  879. eigenVectors[2][2] = -eigenVectors[2][2];
  880. }
  881. }
  882. }