matrix3.h 45 KB

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