PageRenderTime 36ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 1ms

/indra/llmath/m4math.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 882 lines | 658 code | 156 blank | 68 comment | 20 complexity | 994ba95d813443312b3d463f0e6be527 MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**
  2. * @file m4math.cpp
  3. * @brief LLMatrix4 class implementation.
  4. *
  5. * $LicenseInfo:firstyear=2000&license=viewerlgpl$
  6. * Second Life Viewer Source Code
  7. * Copyright (C) 2010, Linden Research, Inc.
  8. *
  9. * This library is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU Lesser General Public
  11. * License as published by the Free Software Foundation;
  12. * version 2.1 of the License only.
  13. *
  14. * This library is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  17. * Lesser General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Lesser General Public
  20. * License along with this library; if not, write to the Free Software
  21. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  22. *
  23. * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
  24. * $/LicenseInfo$
  25. */
  26. #include "linden_common.h"
  27. //#include "vmath.h"
  28. #include "v3math.h"
  29. #include "v4math.h"
  30. #include "m4math.h"
  31. #include "m3math.h"
  32. #include "llquaternion.h"
  33. // LLMatrix4
  34. // Constructors
  35. LLMatrix4::LLMatrix4(const F32 *mat)
  36. {
  37. mMatrix[0][0] = mat[0];
  38. mMatrix[0][1] = mat[1];
  39. mMatrix[0][2] = mat[2];
  40. mMatrix[0][3] = mat[3];
  41. mMatrix[1][0] = mat[4];
  42. mMatrix[1][1] = mat[5];
  43. mMatrix[1][2] = mat[6];
  44. mMatrix[1][3] = mat[7];
  45. mMatrix[2][0] = mat[8];
  46. mMatrix[2][1] = mat[9];
  47. mMatrix[2][2] = mat[10];
  48. mMatrix[2][3] = mat[11];
  49. mMatrix[3][0] = mat[12];
  50. mMatrix[3][1] = mat[13];
  51. mMatrix[3][2] = mat[14];
  52. mMatrix[3][3] = mat[15];
  53. }
  54. LLMatrix4::LLMatrix4(const LLMatrix3 &mat, const LLVector4 &vec)
  55. {
  56. mMatrix[0][0] = mat.mMatrix[0][0];
  57. mMatrix[0][1] = mat.mMatrix[0][1];
  58. mMatrix[0][2] = mat.mMatrix[0][2];
  59. mMatrix[0][3] = 0.f;
  60. mMatrix[1][0] = mat.mMatrix[1][0];
  61. mMatrix[1][1] = mat.mMatrix[1][1];
  62. mMatrix[1][2] = mat.mMatrix[1][2];
  63. mMatrix[1][3] = 0.f;
  64. mMatrix[2][0] = mat.mMatrix[2][0];
  65. mMatrix[2][1] = mat.mMatrix[2][1];
  66. mMatrix[2][2] = mat.mMatrix[2][2];
  67. mMatrix[2][3] = 0.f;
  68. mMatrix[3][0] = vec.mV[0];
  69. mMatrix[3][1] = vec.mV[1];
  70. mMatrix[3][2] = vec.mV[2];
  71. mMatrix[3][3] = 1.f;
  72. }
  73. LLMatrix4::LLMatrix4(const LLMatrix3 &mat)
  74. {
  75. mMatrix[0][0] = mat.mMatrix[0][0];
  76. mMatrix[0][1] = mat.mMatrix[0][1];
  77. mMatrix[0][2] = mat.mMatrix[0][2];
  78. mMatrix[0][3] = 0.f;
  79. mMatrix[1][0] = mat.mMatrix[1][0];
  80. mMatrix[1][1] = mat.mMatrix[1][1];
  81. mMatrix[1][2] = mat.mMatrix[1][2];
  82. mMatrix[1][3] = 0.f;
  83. mMatrix[2][0] = mat.mMatrix[2][0];
  84. mMatrix[2][1] = mat.mMatrix[2][1];
  85. mMatrix[2][2] = mat.mMatrix[2][2];
  86. mMatrix[2][3] = 0.f;
  87. mMatrix[3][0] = 0.f;
  88. mMatrix[3][1] = 0.f;
  89. mMatrix[3][2] = 0.f;
  90. mMatrix[3][3] = 1.f;
  91. }
  92. LLMatrix4::LLMatrix4(const LLQuaternion &q)
  93. {
  94. *this = initRotation(q);
  95. }
  96. LLMatrix4::LLMatrix4(const LLQuaternion &q, const LLVector4 &pos)
  97. {
  98. *this = initRotTrans(q, pos);
  99. }
  100. LLMatrix4::LLMatrix4(const F32 angle, const LLVector4 &vec, const LLVector4 &pos)
  101. {
  102. initRotTrans(LLQuaternion(angle, vec), pos);
  103. }
  104. LLMatrix4::LLMatrix4(const F32 angle, const LLVector4 &vec)
  105. {
  106. initRotation(LLQuaternion(angle, vec));
  107. mMatrix[3][0] = 0.f;
  108. mMatrix[3][1] = 0.f;
  109. mMatrix[3][2] = 0.f;
  110. mMatrix[3][3] = 1.f;
  111. }
  112. LLMatrix4::LLMatrix4(const F32 roll, const F32 pitch, const F32 yaw, const LLVector4 &pos)
  113. {
  114. LLMatrix3 mat(roll, pitch, yaw);
  115. initRotTrans(LLQuaternion(mat), pos);
  116. }
  117. LLMatrix4::LLMatrix4(const F32 roll, const F32 pitch, const F32 yaw)
  118. {
  119. LLMatrix3 mat(roll, pitch, yaw);
  120. initRotation(LLQuaternion(mat));
  121. mMatrix[3][0] = 0.f;
  122. mMatrix[3][1] = 0.f;
  123. mMatrix[3][2] = 0.f;
  124. mMatrix[3][3] = 1.f;
  125. }
  126. LLMatrix4::~LLMatrix4(void)
  127. {
  128. }
  129. // Clear and Assignment Functions
  130. const LLMatrix4& LLMatrix4::setZero()
  131. {
  132. mMatrix[0][0] = 0.f;
  133. mMatrix[0][1] = 0.f;
  134. mMatrix[0][2] = 0.f;
  135. mMatrix[0][3] = 0.f;
  136. mMatrix[1][0] = 0.f;
  137. mMatrix[1][1] = 0.f;
  138. mMatrix[1][2] = 0.f;
  139. mMatrix[1][3] = 0.f;
  140. mMatrix[2][0] = 0.f;
  141. mMatrix[2][1] = 0.f;
  142. mMatrix[2][2] = 0.f;
  143. mMatrix[2][3] = 0.f;
  144. mMatrix[3][0] = 0.f;
  145. mMatrix[3][1] = 0.f;
  146. mMatrix[3][2] = 0.f;
  147. mMatrix[3][3] = 0.f;
  148. return *this;
  149. }
  150. // various useful mMatrix functions
  151. const LLMatrix4& LLMatrix4::transpose()
  152. {
  153. LLMatrix4 mat;
  154. mat.mMatrix[0][0] = mMatrix[0][0];
  155. mat.mMatrix[1][0] = mMatrix[0][1];
  156. mat.mMatrix[2][0] = mMatrix[0][2];
  157. mat.mMatrix[3][0] = mMatrix[0][3];
  158. mat.mMatrix[0][1] = mMatrix[1][0];
  159. mat.mMatrix[1][1] = mMatrix[1][1];
  160. mat.mMatrix[2][1] = mMatrix[1][2];
  161. mat.mMatrix[3][1] = mMatrix[1][3];
  162. mat.mMatrix[0][2] = mMatrix[2][0];
  163. mat.mMatrix[1][2] = mMatrix[2][1];
  164. mat.mMatrix[2][2] = mMatrix[2][2];
  165. mat.mMatrix[3][2] = mMatrix[2][3];
  166. mat.mMatrix[0][3] = mMatrix[3][0];
  167. mat.mMatrix[1][3] = mMatrix[3][1];
  168. mat.mMatrix[2][3] = mMatrix[3][2];
  169. mat.mMatrix[3][3] = mMatrix[3][3];
  170. *this = mat;
  171. return *this;
  172. }
  173. F32 LLMatrix4::determinant() const
  174. {
  175. F32 value =
  176. mMatrix[0][3] * mMatrix[1][2] * mMatrix[2][1] * mMatrix[3][0] -
  177. mMatrix[0][2] * mMatrix[1][3] * mMatrix[2][1] * mMatrix[3][0] -
  178. mMatrix[0][3] * mMatrix[1][1] * mMatrix[2][2] * mMatrix[3][0] +
  179. mMatrix[0][1] * mMatrix[1][3] * mMatrix[2][2] * mMatrix[3][0] +
  180. mMatrix[0][2] * mMatrix[1][1] * mMatrix[2][3] * mMatrix[3][0] -
  181. mMatrix[0][1] * mMatrix[1][2] * mMatrix[2][3] * mMatrix[3][0] -
  182. mMatrix[0][3] * mMatrix[1][2] * mMatrix[2][0] * mMatrix[3][1] +
  183. mMatrix[0][2] * mMatrix[1][3] * mMatrix[2][0] * mMatrix[3][1] +
  184. mMatrix[0][3] * mMatrix[1][0] * mMatrix[2][2] * mMatrix[3][1] -
  185. mMatrix[0][0] * mMatrix[1][3] * mMatrix[2][2] * mMatrix[3][1] -
  186. mMatrix[0][2] * mMatrix[1][0] * mMatrix[2][3] * mMatrix[3][1] +
  187. mMatrix[0][0] * mMatrix[1][2] * mMatrix[2][3] * mMatrix[3][1] +
  188. mMatrix[0][3] * mMatrix[1][1] * mMatrix[2][0] * mMatrix[3][2] -
  189. mMatrix[0][1] * mMatrix[1][3] * mMatrix[2][0] * mMatrix[3][2] -
  190. mMatrix[0][3] * mMatrix[1][0] * mMatrix[2][1] * mMatrix[3][2] +
  191. mMatrix[0][0] * mMatrix[1][3] * mMatrix[2][1] * mMatrix[3][2] +
  192. mMatrix[0][1] * mMatrix[1][0] * mMatrix[2][3] * mMatrix[3][2] -
  193. mMatrix[0][0] * mMatrix[1][1] * mMatrix[2][3] * mMatrix[3][2] -
  194. mMatrix[0][2] * mMatrix[1][1] * mMatrix[2][0] * mMatrix[3][3] +
  195. mMatrix[0][1] * mMatrix[1][2] * mMatrix[2][0] * mMatrix[3][3] +
  196. mMatrix[0][2] * mMatrix[1][0] * mMatrix[2][1] * mMatrix[3][3] -
  197. mMatrix[0][0] * mMatrix[1][2] * mMatrix[2][1] * mMatrix[3][3] -
  198. mMatrix[0][1] * mMatrix[1][0] * mMatrix[2][2] * mMatrix[3][3] +
  199. mMatrix[0][0] * mMatrix[1][1] * mMatrix[2][2] * mMatrix[3][3];
  200. return value;
  201. }
  202. // Only works for pure orthonormal, homogeneous transform matrices.
  203. const LLMatrix4& LLMatrix4::invert(void)
  204. {
  205. // transpose the rotation part
  206. F32 temp;
  207. temp = mMatrix[VX][VY]; mMatrix[VX][VY] = mMatrix[VY][VX]; mMatrix[VY][VX] = temp;
  208. temp = mMatrix[VX][VZ]; mMatrix[VX][VZ] = mMatrix[VZ][VX]; mMatrix[VZ][VX] = temp;
  209. temp = mMatrix[VY][VZ]; mMatrix[VY][VZ] = mMatrix[VZ][VY]; mMatrix[VZ][VY] = temp;
  210. // rotate the translation part by the new rotation
  211. // (temporarily store in empty column of matrix)
  212. U32 j;
  213. for (j=0; j<3; j++)
  214. {
  215. mMatrix[j][VW] = mMatrix[VW][VX] * mMatrix[VX][j] +
  216. mMatrix[VW][VY] * mMatrix[VY][j] +
  217. mMatrix[VW][VZ] * mMatrix[VZ][j];
  218. }
  219. // negate and copy the temporary vector back to the tranlation row
  220. mMatrix[VW][VX] = -mMatrix[VX][VW];
  221. mMatrix[VW][VY] = -mMatrix[VY][VW];
  222. mMatrix[VW][VZ] = -mMatrix[VZ][VW];
  223. // zero the empty column again
  224. mMatrix[VX][VW] = mMatrix[VY][VW] = mMatrix[VZ][VW] = 0.0f;
  225. return *this;
  226. }
  227. LLVector4 LLMatrix4::getFwdRow4() const
  228. {
  229. return LLVector4(mMatrix[VX][VX], mMatrix[VX][VY], mMatrix[VX][VZ], mMatrix[VX][VW]);
  230. }
  231. LLVector4 LLMatrix4::getLeftRow4() const
  232. {
  233. return LLVector4(mMatrix[VY][VX], mMatrix[VY][VY], mMatrix[VY][VZ], mMatrix[VY][VW]);
  234. }
  235. LLVector4 LLMatrix4::getUpRow4() const
  236. {
  237. return LLVector4(mMatrix[VZ][VX], mMatrix[VZ][VY], mMatrix[VZ][VZ], mMatrix[VZ][VW]);
  238. }
  239. // SJB: This code is correct for a logicly stored (non-transposed) matrix;
  240. // Our matrices are stored transposed, OpenGL style, so this generates the
  241. // INVERSE quaternion (-x, -y, -z, w)!
  242. // Because we use similar logic in LLQuaternion::getMatrix3,
  243. // we are internally consistant so everything works OK :)
  244. LLQuaternion LLMatrix4::quaternion() const
  245. {
  246. LLQuaternion quat;
  247. F32 tr, s, q[4];
  248. U32 i, j, k;
  249. U32 nxt[3] = {1, 2, 0};
  250. tr = mMatrix[0][0] + mMatrix[1][1] + mMatrix[2][2];
  251. // check the diagonal
  252. if (tr > 0.f)
  253. {
  254. s = (F32)sqrt (tr + 1.f);
  255. quat.mQ[VS] = s / 2.f;
  256. s = 0.5f / s;
  257. quat.mQ[VX] = (mMatrix[1][2] - mMatrix[2][1]) * s;
  258. quat.mQ[VY] = (mMatrix[2][0] - mMatrix[0][2]) * s;
  259. quat.mQ[VZ] = (mMatrix[0][1] - mMatrix[1][0]) * s;
  260. }
  261. else
  262. {
  263. // diagonal is negative
  264. i = 0;
  265. if (mMatrix[1][1] > mMatrix[0][0])
  266. i = 1;
  267. if (mMatrix[2][2] > mMatrix[i][i])
  268. i = 2;
  269. j = nxt[i];
  270. k = nxt[j];
  271. s = (F32)sqrt ((mMatrix[i][i] - (mMatrix[j][j] + mMatrix[k][k])) + 1.f);
  272. q[i] = s * 0.5f;
  273. if (s != 0.f)
  274. s = 0.5f / s;
  275. q[3] = (mMatrix[j][k] - mMatrix[k][j]) * s;
  276. q[j] = (mMatrix[i][j] + mMatrix[j][i]) * s;
  277. q[k] = (mMatrix[i][k] + mMatrix[k][i]) * s;
  278. quat.setQuat(q);
  279. }
  280. return quat;
  281. }
  282. void LLMatrix4::initRows(const LLVector4 &row0,
  283. const LLVector4 &row1,
  284. const LLVector4 &row2,
  285. const LLVector4 &row3)
  286. {
  287. mMatrix[0][0] = row0.mV[0];
  288. mMatrix[0][1] = row0.mV[1];
  289. mMatrix[0][2] = row0.mV[2];
  290. mMatrix[0][3] = row0.mV[3];
  291. mMatrix[1][0] = row1.mV[0];
  292. mMatrix[1][1] = row1.mV[1];
  293. mMatrix[1][2] = row1.mV[2];
  294. mMatrix[1][3] = row1.mV[3];
  295. mMatrix[2][0] = row2.mV[0];
  296. mMatrix[2][1] = row2.mV[1];
  297. mMatrix[2][2] = row2.mV[2];
  298. mMatrix[2][3] = row2.mV[3];
  299. mMatrix[3][0] = row3.mV[0];
  300. mMatrix[3][1] = row3.mV[1];
  301. mMatrix[3][2] = row3.mV[2];
  302. mMatrix[3][3] = row3.mV[3];
  303. }
  304. const LLMatrix4& LLMatrix4::initRotation(const F32 angle, const F32 x, const F32 y, const F32 z)
  305. {
  306. LLMatrix3 mat(angle, x, y, z);
  307. return initMatrix(mat);
  308. }
  309. const LLMatrix4& LLMatrix4::initRotation(F32 angle, const LLVector4 &vec)
  310. {
  311. LLMatrix3 mat(angle, vec);
  312. return initMatrix(mat);
  313. }
  314. const LLMatrix4& LLMatrix4::initRotation(const F32 roll, const F32 pitch, const F32 yaw)
  315. {
  316. LLMatrix3 mat(roll, pitch, yaw);
  317. return initMatrix(mat);
  318. }
  319. const LLMatrix4& LLMatrix4::initRotation(const LLQuaternion &q)
  320. {
  321. LLMatrix3 mat(q);
  322. return initMatrix(mat);
  323. }
  324. // Position and Rotation
  325. const LLMatrix4& LLMatrix4::initRotTrans(const F32 angle, const F32 rx, const F32 ry, const F32 rz,
  326. const F32 tx, const F32 ty, const F32 tz)
  327. {
  328. LLMatrix3 mat(angle, rx, ry, rz);
  329. LLVector3 translation(tx, ty, tz);
  330. initMatrix(mat);
  331. setTranslation(translation);
  332. return (*this);
  333. }
  334. const LLMatrix4& LLMatrix4::initRotTrans(const F32 angle, const LLVector3 &axis, const LLVector3&translation)
  335. {
  336. LLMatrix3 mat(angle, axis);
  337. initMatrix(mat);
  338. setTranslation(translation);
  339. return (*this);
  340. }
  341. const LLMatrix4& LLMatrix4::initRotTrans(const F32 roll, const F32 pitch, const F32 yaw, const LLVector4 &translation)
  342. {
  343. LLMatrix3 mat(roll, pitch, yaw);
  344. initMatrix(mat);
  345. setTranslation(translation);
  346. return (*this);
  347. }
  348. /*
  349. const LLMatrix4& LLMatrix4::initRotTrans(const LLVector4 &fwd,
  350. const LLVector4 &left,
  351. const LLVector4 &up,
  352. const LLVector4 &translation)
  353. {
  354. LLMatrix3 mat(fwd, left, up);
  355. initMatrix(mat);
  356. setTranslation(translation);
  357. return (*this);
  358. }
  359. */
  360. const LLMatrix4& LLMatrix4::initRotTrans(const LLQuaternion &q, const LLVector4 &translation)
  361. {
  362. LLMatrix3 mat(q);
  363. initMatrix(mat);
  364. setTranslation(translation);
  365. return (*this);
  366. }
  367. const LLMatrix4& LLMatrix4::initScale(const LLVector3 &scale)
  368. {
  369. setIdentity();
  370. mMatrix[VX][VX] = scale.mV[VX];
  371. mMatrix[VY][VY] = scale.mV[VY];
  372. mMatrix[VZ][VZ] = scale.mV[VZ];
  373. return (*this);
  374. }
  375. const LLMatrix4& LLMatrix4::initAll(const LLVector3 &scale, const LLQuaternion &q, const LLVector3 &pos)
  376. {
  377. F32 sx, sy, sz;
  378. F32 xx, xy, xz, xw, yy, yz, yw, zz, zw;
  379. sx = scale.mV[0];
  380. sy = scale.mV[1];
  381. sz = scale.mV[2];
  382. xx = q.mQ[VX] * q.mQ[VX];
  383. xy = q.mQ[VX] * q.mQ[VY];
  384. xz = q.mQ[VX] * q.mQ[VZ];
  385. xw = q.mQ[VX] * q.mQ[VW];
  386. yy = q.mQ[VY] * q.mQ[VY];
  387. yz = q.mQ[VY] * q.mQ[VZ];
  388. yw = q.mQ[VY] * q.mQ[VW];
  389. zz = q.mQ[VZ] * q.mQ[VZ];
  390. zw = q.mQ[VZ] * q.mQ[VW];
  391. mMatrix[0][0] = (1.f - 2.f * ( yy + zz )) *sx;
  392. mMatrix[0][1] = ( 2.f * ( xy + zw )) *sx;
  393. mMatrix[0][2] = ( 2.f * ( xz - yw )) *sx;
  394. mMatrix[1][0] = ( 2.f * ( xy - zw )) *sy;
  395. mMatrix[1][1] = (1.f - 2.f * ( xx + zz )) *sy;
  396. mMatrix[1][2] = ( 2.f * ( yz + xw )) *sy;
  397. mMatrix[2][0] = ( 2.f * ( xz + yw )) *sz;
  398. mMatrix[2][1] = ( 2.f * ( yz - xw )) *sz;
  399. mMatrix[2][2] = (1.f - 2.f * ( xx + yy )) *sz;
  400. mMatrix[3][0] = pos.mV[0];
  401. mMatrix[3][1] = pos.mV[1];
  402. mMatrix[3][2] = pos.mV[2];
  403. mMatrix[3][3] = 1.0;
  404. // TODO -- should we set the translation portion to zero?
  405. return (*this);
  406. }
  407. // Rotate exisitng mMatrix
  408. const LLMatrix4& LLMatrix4::rotate(const F32 angle, const F32 x, const F32 y, const F32 z)
  409. {
  410. LLVector4 vec4(x, y, z);
  411. LLMatrix4 mat(angle, vec4);
  412. *this *= mat;
  413. return *this;
  414. }
  415. const LLMatrix4& LLMatrix4::rotate(const F32 angle, const LLVector4 &vec)
  416. {
  417. LLMatrix4 mat(angle, vec);
  418. *this *= mat;
  419. return *this;
  420. }
  421. const LLMatrix4& LLMatrix4::rotate(const F32 roll, const F32 pitch, const F32 yaw)
  422. {
  423. LLMatrix4 mat(roll, pitch, yaw);
  424. *this *= mat;
  425. return *this;
  426. }
  427. const LLMatrix4& LLMatrix4::rotate(const LLQuaternion &q)
  428. {
  429. LLMatrix4 mat(q);
  430. *this *= mat;
  431. return *this;
  432. }
  433. const LLMatrix4& LLMatrix4::translate(const LLVector3 &vec)
  434. {
  435. mMatrix[3][0] += vec.mV[0];
  436. mMatrix[3][1] += vec.mV[1];
  437. mMatrix[3][2] += vec.mV[2];
  438. return (*this);
  439. }
  440. void LLMatrix4::setFwdRow(const LLVector3 &row)
  441. {
  442. mMatrix[VX][VX] = row.mV[VX];
  443. mMatrix[VX][VY] = row.mV[VY];
  444. mMatrix[VX][VZ] = row.mV[VZ];
  445. }
  446. void LLMatrix4::setLeftRow(const LLVector3 &row)
  447. {
  448. mMatrix[VY][VX] = row.mV[VX];
  449. mMatrix[VY][VY] = row.mV[VY];
  450. mMatrix[VY][VZ] = row.mV[VZ];
  451. }
  452. void LLMatrix4::setUpRow(const LLVector3 &row)
  453. {
  454. mMatrix[VZ][VX] = row.mV[VX];
  455. mMatrix[VZ][VY] = row.mV[VY];
  456. mMatrix[VZ][VZ] = row.mV[VZ];
  457. }
  458. void LLMatrix4::setFwdCol(const LLVector3 &col)
  459. {
  460. mMatrix[VX][VX] = col.mV[VX];
  461. mMatrix[VY][VX] = col.mV[VY];
  462. mMatrix[VZ][VX] = col.mV[VZ];
  463. }
  464. void LLMatrix4::setLeftCol(const LLVector3 &col)
  465. {
  466. mMatrix[VX][VY] = col.mV[VX];
  467. mMatrix[VY][VY] = col.mV[VY];
  468. mMatrix[VZ][VY] = col.mV[VZ];
  469. }
  470. void LLMatrix4::setUpCol(const LLVector3 &col)
  471. {
  472. mMatrix[VX][VZ] = col.mV[VX];
  473. mMatrix[VY][VZ] = col.mV[VY];
  474. mMatrix[VZ][VZ] = col.mV[VZ];
  475. }
  476. const LLMatrix4& LLMatrix4::setTranslation(const F32 tx, const F32 ty, const F32 tz)
  477. {
  478. mMatrix[VW][VX] = tx;
  479. mMatrix[VW][VY] = ty;
  480. mMatrix[VW][VZ] = tz;
  481. return (*this);
  482. }
  483. const LLMatrix4& LLMatrix4::setTranslation(const LLVector3 &translation)
  484. {
  485. mMatrix[VW][VX] = translation.mV[VX];
  486. mMatrix[VW][VY] = translation.mV[VY];
  487. mMatrix[VW][VZ] = translation.mV[VZ];
  488. return (*this);
  489. }
  490. const LLMatrix4& LLMatrix4::setTranslation(const LLVector4 &translation)
  491. {
  492. mMatrix[VW][VX] = translation.mV[VX];
  493. mMatrix[VW][VY] = translation.mV[VY];
  494. mMatrix[VW][VZ] = translation.mV[VZ];
  495. return (*this);
  496. }
  497. // LLMatrix3 Extraction and Setting
  498. LLMatrix3 LLMatrix4::getMat3() const
  499. {
  500. LLMatrix3 retmat;
  501. retmat.mMatrix[0][0] = mMatrix[0][0];
  502. retmat.mMatrix[0][1] = mMatrix[0][1];
  503. retmat.mMatrix[0][2] = mMatrix[0][2];
  504. retmat.mMatrix[1][0] = mMatrix[1][0];
  505. retmat.mMatrix[1][1] = mMatrix[1][1];
  506. retmat.mMatrix[1][2] = mMatrix[1][2];
  507. retmat.mMatrix[2][0] = mMatrix[2][0];
  508. retmat.mMatrix[2][1] = mMatrix[2][1];
  509. retmat.mMatrix[2][2] = mMatrix[2][2];
  510. return retmat;
  511. }
  512. const LLMatrix4& LLMatrix4::initMatrix(const LLMatrix3 &mat)
  513. {
  514. mMatrix[0][0] = mat.mMatrix[0][0];
  515. mMatrix[0][1] = mat.mMatrix[0][1];
  516. mMatrix[0][2] = mat.mMatrix[0][2];
  517. mMatrix[0][3] = 0.f;
  518. mMatrix[1][0] = mat.mMatrix[1][0];
  519. mMatrix[1][1] = mat.mMatrix[1][1];
  520. mMatrix[1][2] = mat.mMatrix[1][2];
  521. mMatrix[1][3] = 0.f;
  522. mMatrix[2][0] = mat.mMatrix[2][0];
  523. mMatrix[2][1] = mat.mMatrix[2][1];
  524. mMatrix[2][2] = mat.mMatrix[2][2];
  525. mMatrix[2][3] = 0.f;
  526. mMatrix[3][0] = 0.f;
  527. mMatrix[3][1] = 0.f;
  528. mMatrix[3][2] = 0.f;
  529. mMatrix[3][3] = 1.f;
  530. return (*this);
  531. }
  532. const LLMatrix4& LLMatrix4::initMatrix(const LLMatrix3 &mat, const LLVector4 &translation)
  533. {
  534. mMatrix[0][0] = mat.mMatrix[0][0];
  535. mMatrix[0][1] = mat.mMatrix[0][1];
  536. mMatrix[0][2] = mat.mMatrix[0][2];
  537. mMatrix[0][3] = 0.f;
  538. mMatrix[1][0] = mat.mMatrix[1][0];
  539. mMatrix[1][1] = mat.mMatrix[1][1];
  540. mMatrix[1][2] = mat.mMatrix[1][2];
  541. mMatrix[1][3] = 0.f;
  542. mMatrix[2][0] = mat.mMatrix[2][0];
  543. mMatrix[2][1] = mat.mMatrix[2][1];
  544. mMatrix[2][2] = mat.mMatrix[2][2];
  545. mMatrix[2][3] = 0.f;
  546. mMatrix[3][0] = translation.mV[0];
  547. mMatrix[3][1] = translation.mV[1];
  548. mMatrix[3][2] = translation.mV[2];
  549. mMatrix[3][3] = 1.f;
  550. return (*this);
  551. }
  552. // LLMatrix4 Operators
  553. LLVector4 operator*(const LLVector4 &a, const LLMatrix4 &b)
  554. {
  555. // Operate "to the left" on row-vector a
  556. return LLVector4(a.mV[VX] * b.mMatrix[VX][VX] +
  557. a.mV[VY] * b.mMatrix[VY][VX] +
  558. a.mV[VZ] * b.mMatrix[VZ][VX] +
  559. a.mV[VW] * b.mMatrix[VW][VX],
  560. a.mV[VX] * b.mMatrix[VX][VY] +
  561. a.mV[VY] * b.mMatrix[VY][VY] +
  562. a.mV[VZ] * b.mMatrix[VZ][VY] +
  563. a.mV[VW] * b.mMatrix[VW][VY],
  564. a.mV[VX] * b.mMatrix[VX][VZ] +
  565. a.mV[VY] * b.mMatrix[VY][VZ] +
  566. a.mV[VZ] * b.mMatrix[VZ][VZ] +
  567. a.mV[VW] * b.mMatrix[VW][VZ],
  568. a.mV[VX] * b.mMatrix[VX][VW] +
  569. a.mV[VY] * b.mMatrix[VY][VW] +
  570. a.mV[VZ] * b.mMatrix[VZ][VW] +
  571. a.mV[VW] * b.mMatrix[VW][VW]);
  572. }
  573. LLVector4 rotate_vector(const LLVector4 &a, const LLMatrix4 &b)
  574. {
  575. // Rotates but does not translate
  576. // Operate "to the left" on row-vector a
  577. LLVector4 vec;
  578. vec.mV[VX] = a.mV[VX] * b.mMatrix[VX][VX] +
  579. a.mV[VY] * b.mMatrix[VY][VX] +
  580. a.mV[VZ] * b.mMatrix[VZ][VX];
  581. vec.mV[VY] = a.mV[VX] * b.mMatrix[VX][VY] +
  582. a.mV[VY] * b.mMatrix[VY][VY] +
  583. a.mV[VZ] * b.mMatrix[VZ][VY];
  584. vec.mV[VZ] = a.mV[VX] * b.mMatrix[VX][VZ] +
  585. a.mV[VY] * b.mMatrix[VY][VZ] +
  586. a.mV[VZ] * b.mMatrix[VZ][VZ];
  587. // vec.mV[VW] = a.mV[VX] * b.mMatrix[VX][VW] +
  588. // a.mV[VY] * b.mMatrix[VY][VW] +
  589. // a.mV[VZ] * b.mMatrix[VZ][VW] +
  590. vec.mV[VW] = a.mV[VW];
  591. return vec;
  592. }
  593. LLVector3 rotate_vector(const LLVector3 &a, const LLMatrix4 &b)
  594. {
  595. // Rotates but does not translate
  596. // Operate "to the left" on row-vector a
  597. LLVector3 vec;
  598. vec.mV[VX] = a.mV[VX] * b.mMatrix[VX][VX] +
  599. a.mV[VY] * b.mMatrix[VY][VX] +
  600. a.mV[VZ] * b.mMatrix[VZ][VX];
  601. vec.mV[VY] = a.mV[VX] * b.mMatrix[VX][VY] +
  602. a.mV[VY] * b.mMatrix[VY][VY] +
  603. a.mV[VZ] * b.mMatrix[VZ][VY];
  604. vec.mV[VZ] = a.mV[VX] * b.mMatrix[VX][VZ] +
  605. a.mV[VY] * b.mMatrix[VY][VZ] +
  606. a.mV[VZ] * b.mMatrix[VZ][VZ];
  607. return vec;
  608. }
  609. bool operator==(const LLMatrix4 &a, const LLMatrix4 &b)
  610. {
  611. U32 i, j;
  612. for (i = 0; i < NUM_VALUES_IN_MAT4; i++)
  613. {
  614. for (j = 0; j < NUM_VALUES_IN_MAT4; j++)
  615. {
  616. if (a.mMatrix[j][i] != b.mMatrix[j][i])
  617. return FALSE;
  618. }
  619. }
  620. return TRUE;
  621. }
  622. bool operator!=(const LLMatrix4 &a, const LLMatrix4 &b)
  623. {
  624. U32 i, j;
  625. for (i = 0; i < NUM_VALUES_IN_MAT4; i++)
  626. {
  627. for (j = 0; j < NUM_VALUES_IN_MAT4; j++)
  628. {
  629. if (a.mMatrix[j][i] != b.mMatrix[j][i])
  630. return TRUE;
  631. }
  632. }
  633. return FALSE;
  634. }
  635. bool operator<(const LLMatrix4& a, const LLMatrix4 &b)
  636. {
  637. U32 i, j;
  638. for (i = 0; i < NUM_VALUES_IN_MAT4; i++)
  639. {
  640. for (j = 0; j < NUM_VALUES_IN_MAT4; j++)
  641. {
  642. if (a.mMatrix[i][j] != b.mMatrix[i][j])
  643. {
  644. return a.mMatrix[i][j] < b.mMatrix[i][j];
  645. }
  646. }
  647. }
  648. return false;
  649. }
  650. const LLMatrix4& operator*=(LLMatrix4 &a, F32 k)
  651. {
  652. U32 i, j;
  653. for (i = 0; i < NUM_VALUES_IN_MAT4; i++)
  654. {
  655. for (j = 0; j < NUM_VALUES_IN_MAT4; j++)
  656. {
  657. a.mMatrix[j][i] *= k;
  658. }
  659. }
  660. return a;
  661. }
  662. std::ostream& operator<<(std::ostream& s, const LLMatrix4 &a)
  663. {
  664. s << "{ "
  665. << a.mMatrix[VX][VX] << ", "
  666. << a.mMatrix[VX][VY] << ", "
  667. << a.mMatrix[VX][VZ] << ", "
  668. << a.mMatrix[VX][VW]
  669. << "; "
  670. << a.mMatrix[VY][VX] << ", "
  671. << a.mMatrix[VY][VY] << ", "
  672. << a.mMatrix[VY][VZ] << ", "
  673. << a.mMatrix[VY][VW]
  674. << "; "
  675. << a.mMatrix[VZ][VX] << ", "
  676. << a.mMatrix[VZ][VY] << ", "
  677. << a.mMatrix[VZ][VZ] << ", "
  678. << a.mMatrix[VZ][VW]
  679. << "; "
  680. << a.mMatrix[VW][VX] << ", "
  681. << a.mMatrix[VW][VY] << ", "
  682. << a.mMatrix[VW][VZ] << ", "
  683. << a.mMatrix[VW][VW]
  684. << " }";
  685. return s;
  686. }
  687. LLSD LLMatrix4::getValue() const
  688. {
  689. LLSD ret;
  690. ret[0] = mMatrix[0][0];
  691. ret[1] = mMatrix[0][1];
  692. ret[2] = mMatrix[0][2];
  693. ret[3] = mMatrix[0][3];
  694. ret[4] = mMatrix[1][0];
  695. ret[5] = mMatrix[1][1];
  696. ret[6] = mMatrix[1][2];
  697. ret[7] = mMatrix[1][3];
  698. ret[8] = mMatrix[2][0];
  699. ret[9] = mMatrix[2][1];
  700. ret[10] = mMatrix[2][2];
  701. ret[11] = mMatrix[2][3];
  702. ret[12] = mMatrix[3][0];
  703. ret[13] = mMatrix[3][1];
  704. ret[14] = mMatrix[3][2];
  705. ret[15] = mMatrix[3][3];
  706. return ret;
  707. }
  708. void LLMatrix4::setValue(const LLSD& data)
  709. {
  710. mMatrix[0][0] = data[0].asReal();
  711. mMatrix[0][1] = data[1].asReal();
  712. mMatrix[0][2] = data[2].asReal();
  713. mMatrix[0][3] = data[3].asReal();
  714. mMatrix[1][0] = data[4].asReal();
  715. mMatrix[1][1] = data[5].asReal();
  716. mMatrix[1][2] = data[6].asReal();
  717. mMatrix[1][3] = data[7].asReal();
  718. mMatrix[2][0] = data[8].asReal();
  719. mMatrix[2][1] = data[9].asReal();
  720. mMatrix[2][2] = data[10].asReal();
  721. mMatrix[2][3] = data[11].asReal();
  722. mMatrix[3][0] = data[12].asReal();
  723. mMatrix[3][1] = data[13].asReal();
  724. mMatrix[3][2] = data[14].asReal();
  725. mMatrix[3][3] = data[15].asReal();
  726. }