matrix3.h 44 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029
  1. /*
  2. ** Command & Conquer Renegade(tm)
  3. ** Copyright 2025 Electronic Arts Inc.
  4. **
  5. ** This program is free software: you can redistribute it and/or modify
  6. ** it under the terms of the GNU General Public License as published by
  7. ** the Free Software Foundation, either version 3 of the License, or
  8. ** (at your option) any later version.
  9. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ** GNU General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. /* $Header: /Commando/Code/wwmath/matrix3.h 36 5/11/01 7:11p Jani_p $ */
  19. /***********************************************************************************************
  20. *** Confidential - Westwood Studios ***
  21. ***********************************************************************************************
  22. * *
  23. * Project Name : WW3D *
  24. * *
  25. * File Name : MATRIX3.H *
  26. * *
  27. * Programmer : Greg Hjelstrom *
  28. * *
  29. * Start Date : 06/02/97 *
  30. * *
  31. * Last Update : June 2, 1997 [GH] *
  32. * *
  33. *---------------------------------------------------------------------------------------------*
  34. * Functions: *
  35. * Matrix3::Matrix3 -- Constructor, optionally initialize to Identitiy matrix *
  36. * Matrix3::Matrix3 -- Copy Constructor *
  37. * Matrix3::Matrix3 -- Convert a Matrix3D (fake 4x4) to a Matrix3 *
  38. * Matrix3::Matrix3 -- Constructor *
  39. * Matrix3::Transpose -- Returns transpose of the matrix *
  40. * Matrix3::Inverse -- returns the inverse of the matrix *
  41. * Matrix3::Determinant -- returns the determinant of the matrix *
  42. * Matrix3::operator = -- assignment operator *
  43. * Matrix3::operator += -- "plus equals" operator *
  44. * Matrix3::operator-= -- "minus equals" operator *
  45. * Matrix3::operator *= -- "times equals" operator *
  46. * Matrix3::operator /= -- "divide equals" operator *
  47. * Create_X_Rotation_Matrix3 -- creates a matrix3 which is a rotation about X *
  48. * Create_Y_Rotation_Matrix3 -- Creates a Matrix3 which is a rotation about Y *
  49. * Create_Z_Rotation_Matrix3 -- Creates a matrix3 which is a rotation about Z *
  50. * Matrix3::Rotate_X -- Post-mutiplies an x rotation onto the current matrix *
  51. * Matrix3::Rotate_Y -- Post-multiplies the matrix with a rotation about Y *
  52. * Matrix3::Rotate_Z -- Post-multiplies the matrix with a rotation about Z *
  53. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  54. #if defined(_MSC_VER)
  55. #pragma once
  56. #endif
  57. #ifndef Matrix3_H
  58. #define Matrix3_H
  59. #include "always.h"
  60. #include "vector3.h"
  61. #include "wwdebug.h"
  62. #ifdef _UNIX
  63. #include "osdep.h"
  64. #endif
  65. class Matrix3D;
  66. class Matrix4;
  67. class Quaternion;
  68. class Matrix3
  69. {
  70. public:
  71. /*
  72. ** Constructors
  73. */
  74. WWINLINE Matrix3(void) {};
  75. WWINLINE Matrix3(const Matrix3 & m);
  76. WWINLINE explicit Matrix3(bool identity);
  77. WWINLINE explicit Matrix3(const Vector3 & v0, const Vector3 & v1, const Vector3 & v2);
  78. explicit Matrix3(const Matrix3D & m);
  79. explicit Matrix3(const Matrix4 & m);
  80. WWINLINE explicit Matrix3(
  81. float m11,float m12,float m13,
  82. float m21,float m22,float m23,
  83. float m31,float m32,float m33
  84. );
  85. WWINLINE explicit Matrix3(const Vector3 & axis,float angle);
  86. WWINLINE explicit Matrix3(const Vector3 & axis,float s_angle,float c_angle);
  87. WWINLINE explicit Matrix3(const Quaternion & q);
  88. /*
  89. ** 'Set' functions
  90. */
  91. void Set(const Matrix3D & m);
  92. void Set(const Matrix4 & m);
  93. WWINLINE void Set(const Vector3 & v0, const Vector3 & v1, const Vector3 & v2);
  94. WWINLINE void Set(
  95. float m11,float m12,float m13,
  96. float m21,float m22,float m23,
  97. float m31,float m32,float m33
  98. );
  99. WWINLINE void Set(const Vector3 & axis,float angle);
  100. WWINLINE void Set(const Vector3 & axis,float s_angle,float c_angle);
  101. void Set(const Quaternion & q);
  102. /*
  103. ** Access operators
  104. */
  105. WWINLINE Vector3 & operator [] (int i) { return Row[i]; }
  106. WWINLINE const Vector3 & operator [] (int i) const { return Row[i]; }
  107. /*
  108. ** Transpose and Inverse
  109. */
  110. WWINLINE Matrix3 Transpose (void) const;
  111. WWINLINE Matrix3 Inverse (void) const;
  112. WWINLINE float Determinant (void) const;
  113. /*
  114. ** Assignment operators
  115. */
  116. WWINLINE Matrix3 & operator = (const Matrix3 & m);
  117. Matrix3 & operator = (const Matrix3D & m);
  118. Matrix3 & operator = (const Matrix4 & m);
  119. WWINLINE Matrix3 & operator += (const Matrix3 & m);
  120. WWINLINE Matrix3 & operator -= (const Matrix3 & m);
  121. WWINLINE Matrix3 & operator *= (float d);
  122. WWINLINE Matrix3 & operator /= (float d);
  123. WWINLINE void Make_Identity(void);
  124. /*
  125. ** Automatically concatenate a rotation onto the current matrix
  126. */
  127. WWINLINE void Rotate_X(float theta);
  128. WWINLINE void Rotate_X(float s,float c);
  129. WWINLINE void Rotate_Y(float theta);
  130. WWINLINE void Rotate_Y(float s,float c);
  131. WWINLINE void Rotate_Z(float theta);
  132. WWINLINE void Rotate_Z(float s,float c);
  133. /*
  134. ** These functions will give you the approximate amount that the
  135. ** matrix has been rotated about a given axis. These functions
  136. ** cannot be used to re-build a matrx. Use the EulerAnglesClass
  137. ** to convert a matrix into a set of three Euler angles.
  138. */
  139. float Get_X_Rotation(void) const;
  140. float Get_Y_Rotation(void) const;
  141. float Get_Z_Rotation(void) const;
  142. /*
  143. ** These functions return a vector representing the direction an
  144. ** axis is pointing.
  145. */
  146. WWINLINE Vector3 Get_X_Vector(void) const;
  147. WWINLINE Vector3 Get_Y_Vector(void) const;
  148. WWINLINE Vector3 Get_Z_Vector(void) const;
  149. WWINLINE void Get_X_Vector(Vector3 * set_x) const;
  150. WWINLINE void Get_Y_Vector(Vector3 * set_y) const;
  151. WWINLINE void Get_Z_Vector(Vector3 * set_z) const;
  152. /*
  153. ** Negation
  154. */
  155. WWINLINE friend Matrix3 operator - (const Matrix3& a);
  156. /*
  157. ** Scalar multiplication and division
  158. */
  159. WWINLINE friend Matrix3 operator * (const Matrix3& a,float d);
  160. WWINLINE friend Matrix3 operator * (float d,const Matrix3& a);
  161. WWINLINE friend Matrix3 operator / (const Matrix3& a,float d);
  162. /*
  163. ** matrix addition
  164. */
  165. WWINLINE friend Matrix3 operator + (const Matrix3& a, const Matrix3& b);
  166. static WWINLINE void Add(const Matrix3 & a, const Matrix3 & b,Matrix3 * res);
  167. /*
  168. ** matrix subtraction
  169. */
  170. WWINLINE friend Matrix3 operator - (const Matrix3 & a, const Matrix3 & b);
  171. static WWINLINE void Subtract(const Matrix3 & a, const Matrix3 & b,Matrix3 * res);
  172. /*
  173. ** matrix multiplication
  174. */
  175. WWINLINE friend Matrix3 operator * (const Matrix3 & a, const Matrix3 & b);
  176. WWINLINE friend Matrix3 operator * (const Matrix3D & a, const Matrix3 & b);
  177. WWINLINE friend Matrix3 operator * (const Matrix3 & a, const Matrix3D & b);
  178. static void Multiply(const Matrix3 & a, const Matrix3 & b,Matrix3 * res);
  179. static void Multiply(const Matrix3D & a, const Matrix3 & b,Matrix3 * res);
  180. static void Multiply(const Matrix3 & a, const Matrix3D & b,Matrix3 * res);
  181. /*
  182. ** Matrix-Vector multiplication
  183. */
  184. WWINLINE friend Vector3 operator * (const Matrix3 & a, const Vector3 & v);
  185. static WWINLINE void Rotate_Vector(const Matrix3 & tm,const Vector3 & in,Vector3 * out);
  186. static WWINLINE void Transpose_Rotate_Vector(const Matrix3 & tm,const Vector3 & in,Vector3 * out);
  187. /*
  188. ** Comparison operators
  189. */
  190. WWINLINE friend int operator == (const Matrix3 & a, const Matrix3 & b);
  191. WWINLINE friend int operator != (const Matrix3 & a, const Matrix3 & b);
  192. /*
  193. ** Swap two matrices in place
  194. */
  195. WWINLINE friend void Swap(Matrix3 & a,Matrix3 & b);
  196. /*
  197. ** Check whether a matrix is orthogonal, make it orthogonal
  198. */
  199. int Is_Orthogonal(void) const;
  200. void Re_Orthogonalize(void);
  201. /*
  202. ** Miscellaneous
  203. */
  204. WWINLINE void Rotate_AABox_Extent(const Vector3 & extent,Vector3 * new_extent);
  205. /*
  206. ** Some useful pre-initialized Matrix3's
  207. */
  208. static const Matrix3 Identity;
  209. static const Matrix3 RotateX90;
  210. static const Matrix3 RotateX180;
  211. static const Matrix3 RotateX270;
  212. static const Matrix3 RotateY90;
  213. static const Matrix3 RotateY180;
  214. static const Matrix3 RotateY270;
  215. static const Matrix3 RotateZ90;
  216. static const Matrix3 RotateZ180;
  217. static const Matrix3 RotateZ270;
  218. protected:
  219. Vector3 Row[3];
  220. };
  221. /***********************************************************************************************
  222. * Matrix3::Matrix3 -- Constructor, optionally initialize to Identitiy matrix *
  223. * *
  224. * INPUT: *
  225. * *
  226. * OUTPUT: *
  227. * *
  228. * WARNINGS: *
  229. * *
  230. * HISTORY: *
  231. * 06/02/1997 GH : Created. *
  232. *=============================================================================================*/
  233. WWINLINE Matrix3::Matrix3(bool identity)
  234. {
  235. if (identity) {
  236. Row[0].Set(1.0,0.0,0.0);
  237. Row[1].Set(0.0,1.0,0.0);
  238. Row[2].Set(0.0,0.0,1.0);
  239. }
  240. }
  241. /***********************************************************************************************
  242. * Matrix3::Matrix3 -- Copy Constructor *
  243. * *
  244. * INPUT: *
  245. * *
  246. * OUTPUT: *
  247. * *
  248. * WARNINGS: *
  249. * *
  250. * HISTORY: *
  251. * 06/02/1997 GH : Created. *
  252. *=============================================================================================*/
  253. WWINLINE Matrix3::Matrix3(const Matrix3 & m)
  254. {
  255. Row[0] = m.Row[0]; Row[1] = m.Row[1]; Row[2] = m.Row[2];
  256. }
  257. /***********************************************************************************************
  258. * Matrix3::Matrix3 -- Constructor *
  259. * *
  260. * INPUT: *
  261. * *
  262. * OUTPUT: *
  263. * *
  264. * WARNINGS: *
  265. * *
  266. * HISTORY: *
  267. * 06/02/1997 GH : Created. *
  268. *=============================================================================================*/
  269. WWINLINE Matrix3::Matrix3(const Vector3 & r0, const Vector3 & r1, const Vector3 & r2)
  270. {
  271. Row[0] = r0;
  272. Row[1] = r1;
  273. Row[2] = r2;
  274. }
  275. WWINLINE void Matrix3::Set(const Vector3 & r0, const Vector3 & r1, const Vector3 & r2)
  276. {
  277. Row[0] = r0;
  278. Row[1] = r1;
  279. Row[2] = r2;
  280. }
  281. WWINLINE void Matrix3::Make_Identity(void)
  282. {
  283. Row[0].Set(1.0f,0.0f,0.0f);
  284. Row[1].Set(0.0f,1.0f,0.0f);
  285. Row[2].Set(0.0f,0.0f,1.0f);
  286. }
  287. WWINLINE Matrix3::Matrix3
  288. (
  289. float m11,float m12,float m13,
  290. float m21,float m22,float m23,
  291. float m31,float m32,float m33
  292. )
  293. {
  294. Row[0].Set(m11,m12,m13);
  295. Row[1].Set(m21,m22,m23);
  296. Row[2].Set(m31,m32,m33);
  297. }
  298. WWINLINE void Matrix3::Set
  299. (
  300. float m11,float m12,float m13,
  301. float m21,float m22,float m23,
  302. float m31,float m32,float m33
  303. )
  304. {
  305. Row[0].Set(m11,m12,m13);
  306. Row[1].Set(m21,m22,m23);
  307. Row[2].Set(m31,m32,m33);
  308. }
  309. WWINLINE Matrix3::Matrix3(const Vector3 & axis,float angle)
  310. {
  311. Set(axis,angle);
  312. }
  313. WWINLINE Matrix3::Matrix3(const Vector3 & axis,float s_angle,float c_angle)
  314. {
  315. Set(axis,s_angle,c_angle);
  316. }
  317. WWINLINE void Matrix3::Set(const Vector3 & axis,float angle)
  318. {
  319. Set(axis,sinf(angle),cosf(angle));
  320. }
  321. WWINLINE void Matrix3::Set(const Vector3 & axis,float s,float c)
  322. {
  323. WWASSERT(WWMath::Fabs(axis.Length2() - 1.0f) < 0.001f);
  324. Row[0].Set(
  325. (float)(axis[0]*axis[0] + c*(1.0f - axis[0]*axis[0])),
  326. (float)(axis[0]*axis[1]*(1.0f - c) - axis[2]*s),
  327. (float)(axis[2]*axis[0]*(1.0f - c) + axis[1]*s)
  328. );
  329. Row[1].Set(
  330. (float)(axis[0]*axis[1]*(1.0f - c) + axis[2]*s),
  331. (float)(axis[1]*axis[1] + c*(1.0f - axis[1]*axis[1])),
  332. (float)(axis[1]*axis[2]*(1.0f - c) - axis[0]*s)
  333. );
  334. Row[2].Set(
  335. (float)(axis[2]*axis[0]*(1.0f - c) - axis[1]*s),
  336. (float)(axis[1]*axis[2]*(1.0f - c) + axis[0]*s),
  337. (float)(axis[2]*axis[2] + c*(1 - axis[2]*axis[2]))
  338. );
  339. }
  340. WWINLINE Matrix3::Matrix3(const Quaternion & q)
  341. {
  342. this->Set(q);
  343. }
  344. /***********************************************************************************************
  345. * Matrix3::Transpose -- Returns transpose of the matrix *
  346. * *
  347. * INPUT: *
  348. * *
  349. * OUTPUT: *
  350. * *
  351. * WARNINGS: *
  352. * *
  353. * HISTORY: *
  354. * 06/02/1997 GH : Created. *
  355. *=============================================================================================*/
  356. WWINLINE Matrix3 Matrix3::Transpose() const
  357. {
  358. return Matrix3(
  359. Vector3(Row[0][0], Row[1][0], Row[2][0]),
  360. Vector3(Row[0][1], Row[1][1], Row[2][1]),
  361. Vector3(Row[0][2], Row[1][2], Row[2][2])
  362. );
  363. }
  364. /***********************************************************************************************
  365. * Matrix3::Inverse -- returns the inverse of the matrix *
  366. * *
  367. * INPUT: *
  368. * *
  369. * OUTPUT: *
  370. * *
  371. * WARNINGS: *
  372. * *
  373. * HISTORY: *
  374. * 06/02/1997 GH : Created. *
  375. *=============================================================================================*/
  376. WWINLINE Matrix3 Matrix3::Inverse() const // Gauss-Jordan elimination with partial pivoting
  377. {
  378. Matrix3 a(*this); // As a evolves from original mat into identity
  379. Matrix3 b(true); // b evolves from identity into inverse(a)
  380. int i, j, i1;
  381. // Loop over cols of a from left to right, eliminating above and below diagonal
  382. for (j=0; j<3; j++) {
  383. // Find largest pivot in column j among rows j..3
  384. i1 = j;
  385. for (i=j+1; i<3; i++) {
  386. if (WWMath::Fabs(a[i][j]) > WWMath::Fabs(a[i1][j])) {
  387. i1 = i;
  388. }
  389. }
  390. // Swap rows i1 and j in a and b to put pivot on diagonal
  391. Swap(a.Row[i1], a.Row[j]);
  392. Swap(b.Row[i1], b.Row[j]);
  393. // Scale row j to have a unit diagonal
  394. if (a[j][j]==0.) {
  395. //Matrix3::inverse: singular matrix; can't invert
  396. }
  397. b.Row[j] /= a.Row[j][j];
  398. a.Row[j] /= a.Row[j][j];
  399. // Eliminate off-diagonal elems in col j of a, doing identical ops to b
  400. for (i=0; i<3; i++) {
  401. if (i != j) {
  402. b.Row[i] -= a[i][j] * b.Row[j];
  403. a.Row[i] -= a[i][j] * a.Row[j];
  404. }
  405. }
  406. }
  407. return b;
  408. }
  409. /***********************************************************************************************
  410. * Matrix3::Determinant -- returns the determinant of the matrix *
  411. * *
  412. * INPUT: *
  413. * *
  414. * OUTPUT: *
  415. * *
  416. * WARNINGS: *
  417. * *
  418. * HISTORY: *
  419. * 1/7/20 DRM : Created. *
  420. *=============================================================================================*/
  421. WWINLINE float Matrix3::Determinant(void) const
  422. {
  423. return Row[0][0] * (Row[1][1] * Row[2][2] - Row[1][2] * Row[2][1])
  424. - Row[0][1] * (Row[1][0] * Row[2][2] - Row[1][2] * Row[2][0])
  425. - Row[0][2] * (Row[1][0] * Row[2][1] - Row[1][1] * Row[2][0]);
  426. }
  427. /***********************************************************************************************
  428. * Matrix3::operator = -- assignment operator *
  429. * *
  430. * INPUT: *
  431. * *
  432. * OUTPUT: *
  433. * *
  434. * WARNINGS: *
  435. * *
  436. * HISTORY: *
  437. * 06/02/1997 GH : Created. *
  438. *=============================================================================================*/
  439. WWINLINE Matrix3 & Matrix3::operator = (const Matrix3 & m)
  440. {
  441. Row[0] = m.Row[0]; Row[1] = m.Row[1]; Row[2] = m.Row[2];
  442. return *this;
  443. }
  444. /***********************************************************************************************
  445. * Matrix3::operator += -- "plus equals" operator *
  446. * *
  447. * INPUT: *
  448. * *
  449. * OUTPUT: *
  450. * *
  451. * WARNINGS: *
  452. * *
  453. * HISTORY: *
  454. * 06/02/1997 GH : Created. *
  455. *=============================================================================================*/
  456. WWINLINE Matrix3& Matrix3::operator += (const Matrix3 & m)
  457. {
  458. Row[0] += m.Row[0]; Row[1] += m.Row[1]; Row[2] += m.Row[2];
  459. return *this;
  460. }
  461. /***********************************************************************************************
  462. * Matrix3::operator-= -- "minus equals" operator *
  463. * *
  464. * INPUT: *
  465. * *
  466. * OUTPUT: *
  467. * *
  468. * WARNINGS: *
  469. * *
  470. * HISTORY: *
  471. * 06/02/1997 GH : Created. *
  472. *=============================================================================================*/
  473. WWINLINE Matrix3& Matrix3::operator -= (const Matrix3 & m)
  474. {
  475. Row[0] -= m.Row[0]; Row[1] -= m.Row[1]; Row[2] -= m.Row[2];
  476. return *this;
  477. }
  478. /***********************************************************************************************
  479. * Matrix3::operator *= -- "times equals" operator *
  480. * *
  481. * INPUT: *
  482. * *
  483. * OUTPUT: *
  484. * *
  485. * WARNINGS: *
  486. * *
  487. * HISTORY: *
  488. * 06/02/1997 GH : Created. *
  489. *=============================================================================================*/
  490. WWINLINE Matrix3& Matrix3::operator *= (float d)
  491. {
  492. Row[0] *= d; Row[1] *= d; Row[2] *= d;
  493. return *this;
  494. }
  495. /***********************************************************************************************
  496. * Matrix3::operator /= -- "divide equals" operator *
  497. * *
  498. * INPUT: *
  499. * *
  500. * OUTPUT: *
  501. * *
  502. * WARNINGS: *
  503. * *
  504. * HISTORY: *
  505. * 06/02/1997 GH : Created. *
  506. *=============================================================================================*/
  507. WWINLINE Matrix3& Matrix3::operator /= (float d)
  508. {
  509. Row[0] /= d; Row[1] /= d; Row[2] /= d;
  510. return *this;
  511. }
  512. /***********************************************************************************************
  513. * Matrix3::Get_X_Rotation -- approximates the rotation about the X axis *
  514. * *
  515. * INPUT: *
  516. * *
  517. * OUTPUT: *
  518. * *
  519. * WARNINGS: *
  520. * *
  521. * HISTORY: *
  522. * 08/11/1997 GH : Created. *
  523. *=============================================================================================*/
  524. WWINLINE float Matrix3::Get_X_Rotation(void) const
  525. {
  526. Vector3 v = (*this) * Vector3(0.0,1.0,0.0);
  527. return WWMath::Atan2(v[2], v[1]);
  528. }
  529. /***********************************************************************************************
  530. * Matrix3::Get_Y_Rotation -- approximates the rotation about the Y axis *
  531. * *
  532. * INPUT: *
  533. * *
  534. * OUTPUT: *
  535. * *
  536. * WARNINGS: *
  537. * *
  538. * HISTORY: *
  539. * 08/11/1997 GH : Created. *
  540. *=============================================================================================*/
  541. WWINLINE float Matrix3::Get_Y_Rotation(void) const
  542. {
  543. Vector3 v = (*this) * Vector3(0.0,0.0,1.0);
  544. return WWMath::Atan2(v[0],v[2]);
  545. }
  546. /***********************************************************************************************
  547. * Matrix3::Get_Z_Rotation -- approximates the rotation about the Z axis *
  548. * *
  549. * INPUT: *
  550. * *
  551. * OUTPUT: *
  552. * *
  553. * WARNINGS: *
  554. * *
  555. * HISTORY: *
  556. * 08/11/1997 GH : Created. *
  557. *=============================================================================================*/
  558. WWINLINE float Matrix3::Get_Z_Rotation(void) const
  559. {
  560. Vector3 v = (*this) * Vector3(1.0,0.0,0.0);
  561. return WWMath::Atan2(v[1],v[0]);
  562. }
  563. WWINLINE Vector3 Matrix3::Get_X_Vector(void) const
  564. {
  565. return Vector3(Row[0][0], Row[1][0], Row[2][0]);
  566. }
  567. WWINLINE Vector3 Matrix3::Get_Y_Vector(void) const
  568. {
  569. return Vector3(Row[0][1], Row[1][1], Row[2][1]);
  570. }
  571. WWINLINE Vector3 Matrix3::Get_Z_Vector(void) const
  572. {
  573. return Vector3(Row[0][2], Row[1][2], Row[2][2]);
  574. }
  575. WWINLINE void Matrix3::Get_X_Vector(Vector3 * set) const
  576. {
  577. set->Set(Row[0][0], Row[1][0], Row[2][0]);
  578. }
  579. WWINLINE void Matrix3::Get_Y_Vector(Vector3 * set) const
  580. {
  581. set->Set(Row[0][1], Row[1][1], Row[2][1]);
  582. }
  583. WWINLINE void Matrix3::Get_Z_Vector(Vector3 * set) const
  584. {
  585. set->Set(Row[0][2], Row[1][2], Row[2][2]);
  586. }
  587. WWINLINE Matrix3 operator - (const Matrix3 & a)
  588. {
  589. return Matrix3(-a.Row[0], -a.Row[1], -a.Row[2]);
  590. }
  591. WWINLINE Matrix3 operator * (const Matrix3 & a, float d)
  592. {
  593. return Matrix3(a.Row[0] * d, a.Row[1] * d, a.Row[2] * d);
  594. }
  595. WWINLINE Matrix3 operator * (float d, const Matrix3 & a)
  596. {
  597. return a*d;
  598. }
  599. WWINLINE Matrix3 operator / (const Matrix3 & a, float d)
  600. {
  601. float ood = 1.0f / d;
  602. return Matrix3(a.Row[0] * ood, a.Row[1] * ood, a.Row[2] * ood);
  603. }
  604. /*
  605. ** matrix addition
  606. */
  607. WWINLINE Matrix3 operator + (const Matrix3 & a, const Matrix3 & b)
  608. {
  609. return Matrix3(
  610. a.Row[0] + b.Row[0],
  611. a.Row[1] + b.Row[1],
  612. a.Row[2] + b.Row[2]
  613. );
  614. }
  615. WWINLINE void Matrix3::Add(const Matrix3 & a, const Matrix3 & b,Matrix3 * c)
  616. {
  617. WWASSERT(c);
  618. Vector3::Add(a.Row[0],b.Row[0],&(c->Row[0]));
  619. Vector3::Add(a.Row[1],b.Row[1],&(c->Row[1]));
  620. Vector3::Add(a.Row[2],b.Row[2],&(c->Row[2]));
  621. }
  622. /*
  623. ** matrix subtraction
  624. */
  625. WWINLINE Matrix3 operator - (const Matrix3 & a, const Matrix3 & b)
  626. {
  627. return Matrix3(
  628. a.Row[0] - b.Row[0],
  629. a.Row[1] - b.Row[1],
  630. a.Row[2] - b.Row[2]
  631. );
  632. }
  633. WWINLINE void Matrix3::Subtract(const Matrix3 & a, const Matrix3 & b,Matrix3 * c)
  634. {
  635. WWASSERT(c);
  636. Vector3::Subtract(a.Row[0],b.Row[0],&(c->Row[0]));
  637. Vector3::Subtract(a.Row[1],b.Row[1],&(c->Row[1]));
  638. Vector3::Subtract(a.Row[2],b.Row[2],&(c->Row[2]));
  639. }
  640. /*
  641. ** matrix multiplication
  642. */
  643. WWINLINE Matrix3 operator * (const Matrix3 & a, const Matrix3 & b)
  644. {
  645. #define ROWCOL(i,j) a[i][0]*b[0][j] + a[i][1]*b[1][j] + a[i][2]*b[2][j]
  646. return Matrix3(
  647. Vector3(ROWCOL(0,0), ROWCOL(0,1), ROWCOL(0,2) ),
  648. Vector3(ROWCOL(1,0), ROWCOL(1,1), ROWCOL(1,2) ),
  649. Vector3(ROWCOL(2,0), ROWCOL(2,1), ROWCOL(2,2) )
  650. );
  651. #undef ROWCOL
  652. }
  653. /*
  654. ** Multiply a Matrix3 by a Vector3. Yeilds a Vector3 result
  655. */
  656. WWINLINE Vector3 operator * (const Matrix3 & a, const Vector3 & v)
  657. {
  658. return Vector3(
  659. a[0][0] * v[0] + a[0][1] * v[1] + a[0][2] * v[2],
  660. a[1][0] * v[0] + a[1][1] * v[1] + a[1][2] * v[2],
  661. a[2][0] * v[0] + a[2][1] * v[1] + a[2][2] * v[2]
  662. );
  663. }
  664. WWINLINE int operator == (const Matrix3 & a, const Matrix3 & b)
  665. {
  666. return ((a [0] == b [0]) && (a [1] == b [1]) && (a [2] == b [2]));
  667. }
  668. WWINLINE int operator != (const Matrix3 & a, const Matrix3 & b)
  669. {
  670. return (!(a == b));
  671. }
  672. /***********************************************************************************************
  673. * Matrix3::Rotate_X -- Post-mutiplies an x rotation onto the current matrix *
  674. * *
  675. * INPUT: *
  676. * *
  677. * OUTPUT: *
  678. * *
  679. * WARNINGS: *
  680. * *
  681. * HISTORY: *
  682. * 08/26/1997 GH : Created. *
  683. *=============================================================================================*/
  684. WWINLINE void Matrix3::Rotate_X(float theta)
  685. {
  686. Rotate_X(sinf(theta),cosf(theta));
  687. }
  688. WWINLINE void Matrix3::Rotate_X(float s,float c)
  689. {
  690. float tmp1,tmp2;
  691. tmp1 = Row[0][1]; tmp2 = Row[0][2];
  692. Row[0][1] = (float)( c*tmp1 + s*tmp2);
  693. Row[0][2] = (float)(-s*tmp1 + c*tmp2);
  694. tmp1 = Row[1][1]; tmp2 = Row[1][2];
  695. Row[1][1] = (float)( c*tmp1 + s*tmp2);
  696. Row[1][2] = (float)(-s*tmp1 + c*tmp2);
  697. tmp1 = Row[2][1]; tmp2 = Row[2][2];
  698. Row[2][1] = (float)( c*tmp1 + s*tmp2);
  699. Row[2][2] = (float)(-s*tmp1 + c*tmp2);
  700. }
  701. /***********************************************************************************************
  702. * Matrix3::Rotate_Y -- Post-multiplies the matrix with a rotation about Y *
  703. * *
  704. * INPUT: *
  705. * *
  706. * OUTPUT: *
  707. * *
  708. * WARNINGS: *
  709. * *
  710. * HISTORY: *
  711. * 08/26/1997 GH : Created. *
  712. *=============================================================================================*/
  713. WWINLINE void Matrix3::Rotate_Y(float theta)
  714. {
  715. Rotate_Y(sinf(theta),cosf(theta));
  716. }
  717. WWINLINE void Matrix3::Rotate_Y(float s,float c)
  718. {
  719. float tmp1,tmp2;
  720. tmp1 = Row[0][0]; tmp2 = Row[0][2];
  721. Row[0][0] = (float)(c*tmp1 - s*tmp2);
  722. Row[0][2] = (float)(s*tmp1 + c*tmp2);
  723. tmp1 = Row[1][0]; tmp2 = Row[1][2];
  724. Row[1][0] = (float)(c*tmp1 - s*tmp2);
  725. Row[1][2] = (float)(s*tmp1 + c*tmp2);
  726. tmp1 = Row[2][0]; tmp2 = Row[2][2];
  727. Row[2][0] = (float)(c*tmp1 - s*tmp2);
  728. Row[2][2] = (float)(s*tmp1 + c*tmp2);
  729. }
  730. /***********************************************************************************************
  731. * Matrix3::Rotate_Z -- Post-multiplies the matrix with a rotation about Z *
  732. * *
  733. * INPUT: *
  734. * *
  735. * OUTPUT: *
  736. * *
  737. * WARNINGS: *
  738. * *
  739. * HISTORY: *
  740. * 08/26/1997 GH : Created. *
  741. *=============================================================================================*/
  742. WWINLINE void Matrix3::Rotate_Z(float theta)
  743. {
  744. Rotate_Z(sinf(theta),cosf(theta));
  745. }
  746. WWINLINE void Matrix3::Rotate_Z(float s,float c)
  747. {
  748. float tmp1,tmp2;
  749. tmp1 = Row[0][0]; tmp2 = Row[0][1];
  750. Row[0][0] = (float)( c*tmp1 + s*tmp2);
  751. Row[0][1] = (float)(-s*tmp1 + c*tmp2);
  752. tmp1 = Row[1][0]; tmp2 = Row[1][1];
  753. Row[1][0] = (float)( c*tmp1 + s*tmp2);
  754. Row[1][1] = (float)(-s*tmp1 + c*tmp2);
  755. tmp1 = Row[2][0]; tmp2 = Row[2][1];
  756. Row[2][0] = (float)( c*tmp1 + s*tmp2);
  757. Row[2][1] = (float)(-s*tmp1 + c*tmp2);
  758. }
  759. /***********************************************************************************************
  760. * Create_X_Rotation_Matrix3 -- creates a matrix3 which is a rotation about X *
  761. * *
  762. * INPUT: *
  763. * *
  764. * OUTPUT: *
  765. * *
  766. * WARNINGS: *
  767. * *
  768. * HISTORY: *
  769. * 08/26/1997 GH : Created. *
  770. *=============================================================================================*/
  771. WWINLINE Matrix3 Create_X_Rotation_Matrix3(float s,float c)
  772. {
  773. Matrix3 mat;
  774. mat[0][0] = 1.0f;
  775. mat[0][1] = 0.0f;
  776. mat[0][2] = 0.0f;
  777. mat[1][0] = 0.0f;
  778. mat[1][1] = c;
  779. mat[1][2] = -s;
  780. mat[2][0] = 0.0f;
  781. mat[2][1] = s;
  782. mat[2][2] = c;
  783. return mat;
  784. }
  785. WWINLINE Matrix3 Create_X_Rotation_Matrix3(float rad)
  786. {
  787. return Create_X_Rotation_Matrix3(sinf(rad),cosf(rad));
  788. }
  789. /***********************************************************************************************
  790. * Create_Y_Rotation_Matrix3 -- Creates a Matrix3 which is a rotation about Y *
  791. * *
  792. * INPUT: *
  793. * *
  794. * OUTPUT: *
  795. * *
  796. * WARNINGS: *
  797. * *
  798. * HISTORY: *
  799. * 08/26/1997 GH : Created. *
  800. *=============================================================================================*/
  801. WWINLINE Matrix3 Create_Y_Rotation_Matrix3(float s,float c)
  802. {
  803. Matrix3 mat;
  804. mat[0][0] = c;
  805. mat[0][1] = 0.0f;
  806. mat[0][2] = s;
  807. mat[1][0] = 0.0f;
  808. mat[1][1] = 1.0f;
  809. mat[1][2] = 0.0f;
  810. mat[2][0] = -s;
  811. mat[2][1] = 0.0f;
  812. mat[2][2] = c;
  813. return mat;
  814. }
  815. WWINLINE Matrix3 Create_Y_Rotation_Matrix3(float rad)
  816. {
  817. return Create_Y_Rotation_Matrix3(sinf(rad),cosf(rad));
  818. }
  819. /***********************************************************************************************
  820. * Create_Z_Rotation_Matrix3 -- Creates a matrix3 which is a rotation about Z *
  821. * *
  822. * INPUT: *
  823. * *
  824. * OUTPUT: *
  825. * *
  826. * WARNINGS: *
  827. * *
  828. * HISTORY: *
  829. * 08/26/1997 GH : Created. *
  830. *=============================================================================================*/
  831. WWINLINE Matrix3 Create_Z_Rotation_Matrix3(float s,float c)
  832. {
  833. Matrix3 mat;
  834. mat[0][0] = c;
  835. mat[0][1] = -s;
  836. mat[0][2] = 0.0f;
  837. mat[1][0] = s;
  838. mat[1][1] = c;
  839. mat[1][2] = 0.0f;
  840. mat[2][0] = 0.0f;
  841. mat[2][1] = 0.0f;
  842. mat[2][2] = 1.0f;
  843. return mat;
  844. }
  845. WWINLINE Matrix3 Create_Z_Rotation_Matrix3(float rad)
  846. {
  847. return Create_Z_Rotation_Matrix3(sinf(rad),cosf(rad));
  848. }
  849. WWINLINE void Matrix3::Rotate_Vector(const Matrix3 & A,const Vector3 & in,Vector3 * out)
  850. {
  851. Vector3 tmp;
  852. Vector3 * v;
  853. // check for aliased parameters
  854. if (out == &in) {
  855. tmp = in;
  856. v = &tmp;
  857. } else {
  858. v = (Vector3 *)&in; // whats the right way to do this...
  859. }
  860. out->X = (A[0][0] * v->X + A[0][1] * v->Y + A[0][2] * v->Z);
  861. out->Y = (A[1][0] * v->X + A[1][1] * v->Y + A[1][2] * v->Z);
  862. out->Z = (A[2][0] * v->X + A[2][1] * v->Y + A[2][2] * v->Z);
  863. }
  864. WWINLINE void Matrix3::Transpose_Rotate_Vector(const Matrix3 & A,const Vector3 & in,Vector3 * out)
  865. {
  866. Vector3 tmp;
  867. Vector3 * v;
  868. // check for aliased parameters
  869. if (out == &in) {
  870. tmp = in;
  871. v = &tmp;
  872. } else {
  873. v = (Vector3 *)&in;
  874. }
  875. out->X = (A[0][0] * v->X + A[1][0] * v->Y + A[2][0] * v->Z);
  876. out->Y = (A[0][1] * v->X + A[1][1] * v->Y + A[2][1] * v->Z);
  877. out->Z = (A[0][2] * v->X + A[1][2] * v->Y + A[2][2] * v->Z);
  878. }
  879. WWINLINE void Matrix3::Rotate_AABox_Extent(const Vector3 & extent,Vector3 * set_extent)
  880. {
  881. // push each extent out to the projections of the original extents
  882. for (int i=0; i<3; i++) {
  883. // start the center out at the translation portion of the matrix
  884. // and the extent at zero
  885. (*set_extent)[i] = 0.0f;
  886. for (int j=0; j<3; j++) {
  887. (*set_extent)[i] += WWMath::Fabs(Row[i][j] * extent[j]);
  888. }
  889. }
  890. }
  891. #endif /*Matrix3_H*/