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