m4math.cpp
上传用户:king477883
上传日期:2021-03-01
资源大小:9553k
文件大小:19k
源码类别:

游戏引擎

开发平台:

C++ Builder

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