llmatrix4.cpp 23 KB

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