CmMatrix3.cpp 34 KB

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