WWmatrix3.h 43 KB

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