matrix3d.h 75 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516
  1. /*
  2. ** Command & Conquer Generals(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: /G/WWMath/matrix3d.h 49 1/13/00 2:57p Naty_h $ */
  19. /***********************************************************************************************
  20. *** Confidential - Westwood Studios ***
  21. ***********************************************************************************************
  22. * *
  23. * Project Name : Voxel Technology *
  24. * *
  25. * File Name : MATRIX3D.H *
  26. * *
  27. * Programmer : Greg Hjelstrom *
  28. * *
  29. * Start Date : 02/24/97 *
  30. * *
  31. * Last Update : February 24, 1997 [GH] *
  32. * *
  33. *---------------------------------------------------------------------------------------------*
  34. * Functions: *
  35. * Matrix3D::Matrix3D -- Constructors for Matrix3D *
  36. * Matrix3D::Set -- init a Matrix3D from an arrray of 12 floats *
  37. * Matrix3D::Set -- Init a Matrix3D from 12 individual floats *
  38. * Matrix3D::Set -- Init a matrix from 3 axis vectors and a position *
  39. * Matrix3D::Set -- init a matrix to be a rotation about the given axis *
  40. * Matrix3D::Set -- init a matrix to be a rotation about the given axis *
  41. * Matrix3D::Set -- Init a matrix to be a pure translation *
  42. * Matrix3D::Make_Identity -- Initializes the matrix to be the identity matrix *
  43. * Matrix3D::Translate -- Post-Multiplies by a Translation Matrix *
  44. * Matrix3D::Translate -- Post-Multiplies the matrix by a translation matrix *
  45. * M3DC::Translate_X -- Post-Multiplies the matrix by a translation matrix with X only *
  46. * M3DC::Translate_Y -- Post-Multiplies the matrix by a translation matrix with Y only *
  47. * M3DC::Translate_Z -- Post-Multiplies the matrix by a translation matrix with Z only *
  48. * Matrix3D::Rotate_X -- Post-Multiplies the matrix by a rotation about the X axis *
  49. * Matrix3D::Rotate_X -- Post-Multiplies the matrix by a rotation about the X axis *
  50. * Matrix3D::Rotate_Y -- Post-multiplies the matrix by a rotation about the Y axis *
  51. * Matrix3D::Rotate_Y -- Post-Multiplies the matrix by a rotation about Y *
  52. * Matrix3D::Rotate_Z -- Post-multiplies the matrix by a rotation about Z *
  53. * Matrix3D::Rotate_Z -- Post-multiplies the matrix by a rotation about Z *
  54. * M3DC::Pre_Rotate_X -- Pre-multiplies the matrix by a rotation about X *
  55. * M3DC::Pre_Rotate_Y -- Pre-multiplies the matrix by a rotation about Y *
  56. * M3DC::Pre_Rotate_Z -- Pre-multiplies the matrix by a rotation about Z *
  57. * M3DC::Pre_Rotate_X -- Pre-multiplies the matrix by a rotation about X *
  58. * M3DC::Pre_Rotate_Y -- Pre-multiplies the matrix by a rotation about Y *
  59. * M3DC::Pre_Rotate_Z -- Pre-multiplies the matrix by a rotation about Z *
  60. * M3DC::In_Place_Pre_Rotate_X -- Pre-multiplies rotation part of matrix by rotation about X *
  61. * M3DC::In_Place_Pre_Rotate_Y -- Pre-multiplies rotation part of matrix by rotation about Y *
  62. * M3DC::In_Place_Pre_Rotate_Z -- Pre-multiplies rotation part of matrix by rotation about Z *
  63. * M3DC::In_Place_Pre_Rotate_X -- Pre-multiplies rotation part of matrix by rotation about X *
  64. * M3DC::In_Place_Pre_Rotate_Y -- Pre-multiplies rotation part of matrix by rotation about Y *
  65. * M3DC::In_Place_Pre_Rotate_Z -- Pre-multiplies rotation part of matrix by rotation about Z *
  66. * operator * -- Matrix multiplication *
  67. * operator * -- Matrix - vector multiplication *
  68. * operator == -- Matrix equality operator *
  69. * operator != -- Matrix inequality operator *
  70. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  71. #if defined(_MSC_VER)
  72. #pragma once
  73. #endif
  74. #ifndef MATRIX3D_H
  75. #define MATRIX3D_H
  76. #ifdef _UNIX
  77. #include "osdep.h"
  78. #endif
  79. #include "always.h"
  80. #include <assert.h>
  81. #include "vector2.h"
  82. #include "vector3.h"
  83. #include "vector4.h"
  84. class Matrix3;
  85. class Matrix4;
  86. class Quaternion;
  87. /*******************************************************************************
  88. Matrix3D
  89. Three important notes:
  90. - I use *column-vectors*
  91. - I use a *right-handed* coordinate system
  92. - These matrices are *orthogonal*
  93. 3D Transformation matrices. This class is really a 4x4 homogeneous
  94. matrix where the last row is assumed to always be 0 0 0 1. However,
  95. since I don't store the last row, you cant do some things that you can
  96. do with a real 4x4 homogeneous matrix.
  97. I use column-vectors so normally transformations are post-multiplied
  98. and camera transformations should be pre-multiplied. The methods of
  99. this class called Translate, Rotate_X, etc. all perform post-multiplication
  100. with the current matix. These methods (Translate, Rotate_X, etc) also
  101. have been hand-coded to only perform the necessary arithmetic. The
  102. * operator can be used for general purpose matrix multiplication or to
  103. transform a vector by a matrix.
  104. Some operations in this class assume that the matrix is orthogonal.
  105. *********************************************************************************/
  106. class Matrix3D
  107. {
  108. public:
  109. // Constructors
  110. Matrix3D(void) {}
  111. explicit Matrix3D(bool init) { if (init) Make_Identity(); }
  112. explicit Matrix3D(float m[12]);
  113. explicit Matrix3D(
  114. float m11,float m12,float m13,float m14,
  115. float m21,float m22,float m23,float m24,
  116. float m31,float m32,float m33,float m34
  117. );
  118. explicit Matrix3D(
  119. const Vector3 &x, // x-axis unit vector
  120. const Vector3 &y, // y-axis unit vector
  121. const Vector3 &z, // z-axis unit vector
  122. const Vector3 &pos // position
  123. );
  124. explicit Matrix3D(
  125. const Vector3 &axis,
  126. float angle
  127. );
  128. explicit Matrix3D(
  129. const Vector3 &axis,
  130. float sine,
  131. float cosine
  132. );
  133. explicit Matrix3D(
  134. const Matrix3 & rotation,
  135. const Vector3 & position
  136. );
  137. explicit Matrix3D(
  138. const Quaternion & rotation,
  139. const Vector3 & position
  140. );
  141. // Creates identity rotation w. given position.
  142. explicit Matrix3D(const Vector3 & position);
  143. // Copy constructor
  144. Matrix3D(const Matrix3D & m);
  145. // Assignment operator
  146. Matrix3D & operator = (const Matrix3D & m);
  147. // Init functions
  148. void Set(float m[12]);
  149. void Set(
  150. float m11,float m12,float m13,float m14,
  151. float m21,float m22,float m23,float m24,
  152. float m31,float m32,float m33,float m34
  153. );
  154. void Set(
  155. const Vector3 &x, // x-axis unit vector
  156. const Vector3 &y, // y-axis unit vector
  157. const Vector3 &z, // z-axis unit vector
  158. const Vector3 &pos // position
  159. );
  160. void Set(const Vector3 & axis,float angle);
  161. void Set(const Vector3 & axis,float sine,float cosine);
  162. void Set(const Matrix3 & rotation,const Vector3 & position);
  163. void Set(const Quaternion & rotation,const Vector3 & position);
  164. // Creates identity rotation w. given position.
  165. void Set(const Vector3 & position);
  166. // access functions:
  167. Vector4 & operator [] (int i) { return Row[i]; }
  168. const Vector4 & operator [] (int i) const { return Row[i]; }
  169. Vector3 Get_Translation(void) const { return Vector3(Row[0][3],Row[1][3],Row[2][3]); }
  170. void Get_Translation(Vector3 * set) const { set->X = Row[0][3]; set->Y = Row[1][3]; set->Z = Row[2][3]; }
  171. void Set_Translation(const Vector3 & t) { Row[0][3] = t[0]; Row[1][3] = t[1];Row[2][3] = t[2]; }
  172. void Set_Rotation(const Matrix3 & m);
  173. void Set_Rotation(const Quaternion & q);
  174. float Get_X_Translation(void) const { return Row[0][3]; };
  175. float Get_Y_Translation(void) const { return Row[1][3]; };
  176. float Get_Z_Translation(void) const { return Row[2][3]; };
  177. void Set_X_Translation(float x) { Row[0][3] = x; };
  178. void Set_Y_Translation(float y) { Row[1][3] = y; };
  179. void Set_Z_Translation(float z) { Row[2][3] = z; };
  180. void Adjust_Translation(const Vector3 & t) { Row[0][3] += t[0]; Row[1][3] += t[1]; Row[2][3] += t[2]; };
  181. void Adjust_X_Translation(float x) { Row[0][3] += x; };
  182. void Adjust_Y_Translation(float y) { Row[1][3] += y; };
  183. void Adjust_Z_Translation(float z) { Row[2][3] += z; };
  184. // These functions will give you the approximate amount that the
  185. // matrix has been rotated about a given axis. These functions
  186. // cannot be used to re-build a matrx. Use the EulerAnglesClass
  187. // to convert a matrix into a set of three Euler angles.
  188. float Get_X_Rotation(void) const;
  189. float Get_Y_Rotation(void) const;
  190. float Get_Z_Rotation(void) const;
  191. // Each of the transformation methods performs an
  192. // "optimized" post-multiplication with the current matrix.
  193. // All angles are assumed to be radians.
  194. void Make_Identity(void);
  195. void Translate(float x,float y,float z);
  196. void Translate(const Vector3 &t);
  197. void Translate_X(float x);
  198. void Translate_Y(float y);
  199. void Translate_Z(float z);
  200. void Rotate_X(float theta);
  201. void Rotate_Y(float theta);
  202. void Rotate_Z(float theta);
  203. void Rotate_X(float s,float c);
  204. void Rotate_Y(float s,float c);
  205. void Rotate_Z(float s,float c);
  206. // Each of these performs an "optimized" pre-multiplication with the
  207. // current matrix. All angles are assumed to be radians. The "In_Place"
  208. // versions do not affect the translation part of the matrix,
  209. void Pre_Rotate_X(float theta);
  210. void Pre_Rotate_Y(float theta);
  211. void Pre_Rotate_Z(float theta);
  212. void Pre_Rotate_X(float s,float c);
  213. void Pre_Rotate_Y(float s,float c);
  214. void Pre_Rotate_Z(float s,float c);
  215. void In_Place_Pre_Rotate_X(float theta);
  216. void In_Place_Pre_Rotate_Y(float theta);
  217. void In_Place_Pre_Rotate_Z(float theta);
  218. void In_Place_Pre_Rotate_X(float s,float c);
  219. void In_Place_Pre_Rotate_Y(float s,float c);
  220. void In_Place_Pre_Rotate_Z(float s,float c);
  221. // Points the negative Z axis at the target t. Assumes that
  222. // the "world" uses x-y as the ground and z as altitude.
  223. // Used for pointing cameras at targets.
  224. void Look_At(const Vector3 &p,const Vector3 &t,float roll);
  225. // Previous look_at function follows the camera coordinate convention.
  226. // This one follows the object convention used in Commando and G. I
  227. // special cased this convention since it is used so much by us rather
  228. // than supporting every one of the 24(?) possible conventions...
  229. void Obj_Look_At(const Vector3 &p,const Vector3 &t,float roll);
  230. // use the 3x3 sub-matrix only (ignore translation)
  231. Vector3 Rotate_Vector(const Vector3 &vect) const;
  232. Vector3 Inverse_Rotate_Vector(const Vector3 &vect) const;
  233. // these get the a vector representing the direction an axis is pointing
  234. Vector3 Get_X_Vector() const { return Vector3(Row[0][0], Row[1][0], Row[2][0]); }
  235. Vector3 Get_Y_Vector() const { return Vector3(Row[0][1], Row[1][1], Row[2][1]); }
  236. Vector3 Get_Z_Vector() const { return Vector3(Row[0][2], Row[1][2], Row[2][2]); }
  237. void Get_X_Vector(Vector3 * set_x) const { set_x->Set(Row[0][0], Row[1][0], Row[2][0]); }
  238. void Get_Y_Vector(Vector3 * set_y) const { set_y->Set(Row[0][1], Row[1][1], Row[2][1]); }
  239. void Get_Z_Vector(Vector3 * set_z) const { set_z->Set(Row[0][2], Row[1][2], Row[2][2]); }
  240. // Get the inverse of the matrix.
  241. // TODO: currently the "intended-to-be" general inverse function just calls
  242. // the special case Orthogonal inverse functions. Also, when we implement
  243. // general case, check where we were using Get_Inverse since usually it should
  244. // be changed to Get_Orthogonal_Inverse...
  245. void Get_Inverse(Matrix3D & set_inverse) const;
  246. void Get_Orthogonal_Inverse(Matrix3D & set_inverse) const;
  247. // used for importing SurRender matrices
  248. void Copy_3x3_Matrix(float matrix[3][3]);
  249. // Optimized Axis-Aligned Box transforms. One for each of the common forms of
  250. // axis aligned box: min,max vectors and center,extent vectors.
  251. void Transform_Min_Max_AABox(const Vector3 & min,const Vector3 & max,Vector3 * set_min,Vector3 * set_max) const;
  252. void Transform_Center_Extent_AABox(const Vector3 & center,const Vector3 & extent,Vector3 * set_center,Vector3 * set_extent) const;
  253. // matrix multiplication without temporaries
  254. static void Multiply(const Matrix3D &A,const Matrix3D &B,Matrix3D * set_result);
  255. static void Transform_Vector(const Matrix3D & tm,const Vector3 & in,Vector3 * out);
  256. static void Rotate_Vector(const Matrix3D & tm,const Vector3 & in,Vector3 * out);
  257. // transform a vector by the inverse of this matrix (note: assumes the matrix
  258. // is orthogonal; if you've manually scaled or sheared the matrix this function
  259. // will not give correct results)
  260. static void Inverse_Transform_Vector(const Matrix3D & tm,const Vector3 & in,Vector3 * out);
  261. static void Inverse_Rotate_Vector(const Matrix3D & tm,const Vector3 & in,Vector3 * out);
  262. // Check whether a matrix is orthogonal or FORCE it to be :-)
  263. int Is_Orthogonal(void) const;
  264. void Re_Orthogonalize(void);
  265. // some static matrices which are sometimes useful
  266. static const Matrix3D Identity;
  267. static const Matrix3D RotateX90;
  268. static const Matrix3D RotateX180;
  269. static const Matrix3D RotateX270;
  270. static const Matrix3D RotateY90;
  271. static const Matrix3D RotateY180;
  272. static const Matrix3D RotateY270;
  273. static const Matrix3D RotateZ90;
  274. static const Matrix3D RotateZ180;
  275. static const Matrix3D RotateZ270;
  276. protected:
  277. Vector4 Row[3];
  278. friend Vector3 operator * (const Matrix3D &A,const Vector3 &a);
  279. };
  280. /* ---------------------------------------------------------------
  281. Vector Transformation, Matrix concatenation
  282. --------------------------------------------------------------- */
  283. Vector3 operator * (const Matrix3D &A,const Vector3 &v);
  284. Matrix3D operator * (const Matrix3D &A,const Matrix3D &B);
  285. /* ---------------------------------------------------------------
  286. Equality and inequality operators
  287. --------------------------------------------------------------- */
  288. bool operator == (const Matrix3D &A, const Matrix3D &B);
  289. bool operator != (const Matrix3D &A, const Matrix3D &B);
  290. /* ---------------------------------------------------------------
  291. Matrix interpolation
  292. --------------------------------------------------------------- */
  293. Matrix3D Lerp(const Matrix3D &A, const Matrix3D &B, float factor);
  294. /***********************************************************************************************
  295. * M3DC::Matrix3D -- Constructors for Matrix3D *
  296. * *
  297. * INPUT: *
  298. * *
  299. * OUTPUT: *
  300. * *
  301. * WARNINGS: *
  302. * *
  303. * HISTORY: *
  304. * 02/24/1997 GH : Created. *
  305. *=============================================================================================*/
  306. inline Matrix3D::Matrix3D(float m[12])
  307. {
  308. Row[0].Set(m[0],m[1],m[2],m[3]);
  309. Row[1].Set(m[4],m[5],m[6],m[7]);
  310. Row[2].Set(m[8],m[9],m[10],m[11]);
  311. }
  312. inline Matrix3D::Matrix3D
  313. (
  314. float m11,float m12,float m13,float m14,
  315. float m21,float m22,float m23,float m24,
  316. float m31,float m32,float m33,float m34
  317. )
  318. {
  319. Row[0].Set(m11,m12,m13,m14);
  320. Row[1].Set(m21,m22,m23,m24);
  321. Row[2].Set(m31,m32,m33,m34);
  322. }
  323. inline Matrix3D::Matrix3D
  324. (
  325. const Vector3 &x, // x-axis unit vector
  326. const Vector3 &y, // y-axis unit vector
  327. const Vector3 &z, // z-axis unit vector
  328. const Vector3 &pos // position
  329. )
  330. {
  331. Set(x,y,z,pos);
  332. }
  333. inline Matrix3D::Matrix3D(const Vector3 & axis,float angle)
  334. {
  335. Set(axis,angle);
  336. }
  337. inline Matrix3D::Matrix3D(const Vector3 & axis,float sine,float cosine)
  338. {
  339. Set(axis,sine,cosine);
  340. }
  341. inline Matrix3D::Matrix3D(const Matrix3 & rot,const Vector3 & pos)
  342. {
  343. Set(rot,pos);
  344. }
  345. inline Matrix3D::Matrix3D(const Quaternion & rot,const Vector3 & pos)
  346. {
  347. Set(rot,pos);
  348. }
  349. inline Matrix3D::Matrix3D(const Vector3 & position)
  350. {
  351. Set(position);
  352. }
  353. // Copy Constructor
  354. inline Matrix3D::Matrix3D(const Matrix3D & m)
  355. {
  356. Row[0] = m.Row[0];
  357. Row[1] = m.Row[1];
  358. Row[2] = m.Row[2];
  359. }
  360. // Assignment operator
  361. inline Matrix3D & Matrix3D::operator = (const Matrix3D & m)
  362. {
  363. Row[0] = m.Row[0];
  364. Row[1] = m.Row[1];
  365. Row[2] = m.Row[2];
  366. return *this;
  367. }
  368. /***********************************************************************************************
  369. * Matrix3D::Set -- init a Matrix3D from an arrray of 12 floats *
  370. * *
  371. * INPUT: *
  372. * *
  373. * OUTPUT: *
  374. * *
  375. * WARNINGS: *
  376. * *
  377. * HISTORY: *
  378. * 2/24/98 GTH : Created. *
  379. *=============================================================================================*/
  380. inline void Matrix3D::Set(float m[12])
  381. {
  382. Row[0].Set(m[0],m[1],m[2],m[3]);
  383. Row[1].Set(m[4],m[5],m[6],m[7]);
  384. Row[2].Set(m[8],m[9],m[10],m[11]);
  385. }
  386. /***********************************************************************************************
  387. * Matrix3D::Set -- Init a Matrix3D from 12 individual floats *
  388. * *
  389. * INPUT: *
  390. * *
  391. * OUTPUT: *
  392. * *
  393. * WARNINGS: *
  394. * *
  395. * HISTORY: *
  396. * 2/24/98 GTH : Created. *
  397. *=============================================================================================*/
  398. inline void Matrix3D::Set( float m11,float m12,float m13,float m14,
  399. float m21,float m22,float m23,float m24,
  400. float m31,float m32,float m33,float m34)
  401. {
  402. Row[0].Set(m11,m12,m13,m14);
  403. Row[1].Set(m21,m22,m23,m24);
  404. Row[2].Set(m31,m32,m33,m34);
  405. }
  406. /***********************************************************************************************
  407. * Matrix3D::Set -- Init a matrix from 3 axis vectors and a position *
  408. * *
  409. * INPUT: *
  410. * *
  411. * OUTPUT: *
  412. * *
  413. * WARNINGS: *
  414. * *
  415. * HISTORY: *
  416. * 2/24/98 GTH : Created. *
  417. *=============================================================================================*/
  418. inline void Matrix3D::Set( const Vector3 &x, // x-axis unit vector
  419. const Vector3 &y, // y-axis unit vector
  420. const Vector3 &z, // z-axis unit vector
  421. const Vector3 &pos) // position
  422. {
  423. Row[0].Set(x[0],y[0],z[0],pos[0]);
  424. Row[1].Set(x[1],y[1],z[1],pos[1]);
  425. Row[2].Set(x[2],y[2],z[2],pos[2]);
  426. }
  427. /***********************************************************************************************
  428. * Matrix3D::Set -- init a matrix to be a rotation about the given axis *
  429. * *
  430. * INPUT: *
  431. * *
  432. * OUTPUT: *
  433. * *
  434. * WARNINGS: *
  435. * *
  436. * HISTORY: *
  437. * 2/24/98 GTH : Created. *
  438. *=============================================================================================*/
  439. inline void Matrix3D::Set(const Vector3 & axis,float angle)
  440. {
  441. float c = cosf(angle);
  442. float s = sinf(angle);
  443. Set(axis,s,c);
  444. }
  445. /***********************************************************************************************
  446. * Matrix3D::Set -- init a matrix to be a rotation about the given axis *
  447. * *
  448. * INPUT: *
  449. * *
  450. * OUTPUT: *
  451. * *
  452. * WARNINGS: *
  453. * *
  454. * HISTORY: *
  455. * 2/24/98 GTH : Created. *
  456. *=============================================================================================*/
  457. inline void Matrix3D::Set(const Vector3 & axis,float s,float c)
  458. {
  459. assert(WWMath::Fabs(axis.Length2() - 1.0f) < 0.001f);
  460. Row[0].Set(
  461. (float)(axis[0]*axis[0] + c*(1.0f - axis[0]*axis[0])),
  462. (float)(axis[0]*axis[1]*(1.0f - c) - axis[2]*s),
  463. (float)(axis[2]*axis[0]*(1.0f - c) + axis[1]*s),
  464. 0.0f
  465. );
  466. Row[1].Set(
  467. (float)(axis[0]*axis[1]*(1.0f - c) + axis[2]*s),
  468. (float)(axis[1]*axis[1] + c*(1.0f - axis[1]*axis[1])),
  469. (float)(axis[1]*axis[2]*(1.0f - c) - axis[0]*s),
  470. 0.0f
  471. );
  472. Row[2].Set(
  473. (float)(axis[2]*axis[0]*(1.0f - c) - axis[1]*s),
  474. (float)(axis[1]*axis[2]*(1.0f - c) + axis[0]*s),
  475. (float)(axis[2]*axis[2] + c*(1 - axis[2]*axis[2])),
  476. 0.0f
  477. );
  478. }
  479. /***********************************************************************************************
  480. * Matrix3D::Set -- Init a matrix to be a pure translation *
  481. * *
  482. * INPUT: *
  483. * *
  484. * OUTPUT: *
  485. * *
  486. * WARNINGS: *
  487. * *
  488. * HISTORY: *
  489. * 2/24/98 GTH : Created. *
  490. *=============================================================================================*/
  491. inline void Matrix3D::Set(const Vector3 & position)
  492. {
  493. Row[0].Set(1.0f,0.0f,0.0f,position[0]);
  494. Row[1].Set(0.0f,1.0f,0.0f,position[1]);
  495. Row[2].Set(0.0f,0.0f,1.0f,position[2]);
  496. }
  497. /***********************************************************************************************
  498. * M3DC::Make_Identity -- Initializes the matrix to be the identity matrix *
  499. * *
  500. * INPUT: *
  501. * *
  502. * OUTPUT: *
  503. * *
  504. * WARNINGS: *
  505. * *
  506. * HISTORY: *
  507. * 02/24/1997 GH : Created. *
  508. *=============================================================================================*/
  509. inline void Matrix3D::Make_Identity(void)
  510. {
  511. Row[0].Set(1.0f,0.0f,0.0f,0.0f);
  512. Row[1].Set(0.0f,1.0f,0.0f,0.0f);
  513. Row[2].Set(0.0f,0.0f,1.0f,0.0f);
  514. }
  515. /***********************************************************************************************
  516. * M3DC::Translate -- Post-Multiplies by a Translation Matrix *
  517. * *
  518. * INPUT: *
  519. * *
  520. * OUTPUT: *
  521. * *
  522. * WARNINGS: *
  523. * *
  524. * HISTORY: *
  525. * 02/24/1997 GH : Created. *
  526. *=============================================================================================*/
  527. inline void Matrix3D::Translate(float x,float y,float z)
  528. {
  529. Row[0][3] += (float)(Row[0][0]*x + Row[0][1]*y + Row[0][2]*z);
  530. Row[1][3] += (float)(Row[1][0]*x + Row[1][1]*y + Row[1][2]*z);
  531. Row[2][3] += (float)(Row[2][0]*x + Row[2][1]*y + Row[2][2]*z);
  532. }
  533. /***********************************************************************************************
  534. * M3DC::Translate -- Post-Multiplies the matrix by a translation matrix *
  535. * *
  536. * INPUT: *
  537. * *
  538. * OUTPUT: *
  539. * *
  540. * WARNINGS: *
  541. * *
  542. * HISTORY: *
  543. * 02/24/1997 GH : Created. *
  544. *=============================================================================================*/
  545. inline void Matrix3D::Translate(const Vector3 &t)
  546. {
  547. Row[0][3] += Row[0][0]*t[0] + Row[0][1]*t[1] + Row[0][2]*t[2];
  548. Row[1][3] += Row[1][0]*t[0] + Row[1][1]*t[1] + Row[1][2]*t[2];
  549. Row[2][3] += Row[2][0]*t[0] + Row[2][1]*t[1] + Row[2][2]*t[2];
  550. }
  551. /***********************************************************************************************
  552. * M3DC::Translate_X -- Post-Multiplies the matrix by a translation matrix with X only *
  553. * *
  554. * INPUT: *
  555. * *
  556. * OUTPUT: *
  557. * *
  558. * WARNINGS: *
  559. * *
  560. * HISTORY: *
  561. * 07/06/1998 NH : Created. *
  562. *=============================================================================================*/
  563. inline void Matrix3D::Translate_X(float x)
  564. {
  565. Row[0][3] += (float)(Row[0][0]*x);
  566. Row[1][3] += (float)(Row[1][0]*x);
  567. Row[2][3] += (float)(Row[2][0]*x);
  568. }
  569. /***********************************************************************************************
  570. * M3DC::Translate_Y -- Post-Multiplies the matrix by a translation matrix with Y only *
  571. * *
  572. * INPUT: *
  573. * *
  574. * OUTPUT: *
  575. * *
  576. * WARNINGS: *
  577. * *
  578. * HISTORY: *
  579. * 07/06/1998 NH : Created. *
  580. *=============================================================================================*/
  581. inline void Matrix3D::Translate_Y(float y)
  582. {
  583. Row[0][3] += (float)(Row[0][1]*y);
  584. Row[1][3] += (float)(Row[1][1]*y);
  585. Row[2][3] += (float)(Row[2][1]*y);
  586. }
  587. /***********************************************************************************************
  588. * M3DC::Translate_Z -- Post-Multiplies the matrix by a translation matrix with Z only *
  589. * *
  590. * INPUT: *
  591. * *
  592. * OUTPUT: *
  593. * *
  594. * WARNINGS: *
  595. * *
  596. * HISTORY: *
  597. * 07/06/1998 NH : Created. *
  598. *=============================================================================================*/
  599. inline void Matrix3D::Translate_Z(float z)
  600. {
  601. Row[0][3] += (float)(Row[0][2]*z);
  602. Row[1][3] += (float)(Row[1][2]*z);
  603. Row[2][3] += (float)(Row[2][2]*z);
  604. }
  605. /***********************************************************************************************
  606. * M3DC::Rotate_X -- Post-Multiplies the matrix by a rotation about the X axis *
  607. * *
  608. * INPUT: *
  609. * *
  610. * OUTPUT: *
  611. * *
  612. * WARNINGS: *
  613. * *
  614. * HISTORY: *
  615. * 02/24/1997 GH : Created. *
  616. *=============================================================================================*/
  617. inline void Matrix3D::Rotate_X(float theta)
  618. {
  619. float tmp1,tmp2;
  620. float s,c;
  621. s = sinf(theta);
  622. c = cosf(theta);
  623. tmp1 = Row[0][1]; tmp2 = Row[0][2];
  624. Row[0][1] = (float)( c*tmp1 + s*tmp2);
  625. Row[0][2] = (float)(-s*tmp1 + c*tmp2);
  626. tmp1 = Row[1][1]; tmp2 = Row[1][2];
  627. Row[1][1] = (float)( c*tmp1 + s*tmp2);
  628. Row[1][2] = (float)(-s*tmp1 + c*tmp2);
  629. tmp1 = Row[2][1]; tmp2 = Row[2][2];
  630. Row[2][1] = (float)( c*tmp1 + s*tmp2);
  631. Row[2][2] = (float)(-s*tmp1 + c*tmp2);
  632. }
  633. /***********************************************************************************************
  634. * M3DC::Rotate_X -- Post-Multiplies the matrix by a rotation about the X axis *
  635. * *
  636. * INPUT: *
  637. * s - sine of the angle *
  638. * c - cosine of the angle *
  639. * *
  640. * OUTPUT: *
  641. * *
  642. * WARNINGS: *
  643. * *
  644. * HISTORY: *
  645. * 02/24/1997 GH : Created. *
  646. *=============================================================================================*/
  647. inline void Matrix3D::Rotate_X(float s,float c)
  648. {
  649. float tmp1,tmp2;
  650. tmp1 = Row[0][1]; tmp2 = Row[0][2];
  651. Row[0][1] = (float)( c*tmp1 + s*tmp2);
  652. Row[0][2] = (float)(-s*tmp1 + c*tmp2);
  653. tmp1 = Row[1][1]; tmp2 = Row[1][2];
  654. Row[1][1] = (float)( c*tmp1 + s*tmp2);
  655. Row[1][2] = (float)(-s*tmp1 + c*tmp2);
  656. tmp1 = Row[2][1]; tmp2 = Row[2][2];
  657. Row[2][1] = (float)( c*tmp1 + s*tmp2);
  658. Row[2][2] = (float)(-s*tmp1 + c*tmp2);
  659. }
  660. /***********************************************************************************************
  661. * M3DC::Rotate_Y -- Post-multiplies the matrix by a rotation about the Y axis *
  662. * *
  663. * INPUT: *
  664. * theta - angle (in radians) to rotate *
  665. * *
  666. * OUTPUT: *
  667. * *
  668. * WARNINGS: *
  669. * *
  670. * HISTORY: *
  671. * 02/24/1997 GH : Created. *
  672. *=============================================================================================*/
  673. inline void Matrix3D::Rotate_Y(float theta)
  674. {
  675. float tmp1,tmp2;
  676. float s,c;
  677. s = sinf(theta);
  678. c = cosf(theta);
  679. tmp1 = Row[0][0]; tmp2 = Row[0][2];
  680. Row[0][0] = (float)(c*tmp1 - s*tmp2);
  681. Row[0][2] = (float)(s*tmp1 + c*tmp2);
  682. tmp1 = Row[1][0]; tmp2 = Row[1][2];
  683. Row[1][0] = (float)(c*tmp1 - s*tmp2);
  684. Row[1][2] = (float)(s*tmp1 + c*tmp2);
  685. tmp1 = Row[2][0]; tmp2 = Row[2][2];
  686. Row[2][0] = (float)(c*tmp1 - s*tmp2);
  687. Row[2][2] = (float)(s*tmp1 + c*tmp2);
  688. }
  689. /***********************************************************************************************
  690. * M3DC::Rotate_Y -- Post-Multiplies the matrix by a rotation about Y *
  691. * *
  692. * INPUT: *
  693. * s - sine of the angle *
  694. * c - cosine of the angle *
  695. * *
  696. * OUTPUT: *
  697. * *
  698. * WARNINGS: *
  699. * *
  700. * HISTORY: *
  701. * 02/24/1997 GH : Created. *
  702. *=============================================================================================*/
  703. inline void Matrix3D::Rotate_Y(float s,float c)
  704. {
  705. float tmp1,tmp2;
  706. tmp1 = Row[0][0]; tmp2 = Row[0][2];
  707. Row[0][0] = (float)(c*tmp1 - s*tmp2);
  708. Row[0][2] = (float)(s*tmp1 + c*tmp2);
  709. tmp1 = Row[1][0]; tmp2 = Row[1][2];
  710. Row[1][0] = (float)(c*tmp1 - s*tmp2);
  711. Row[1][2] = (float)(s*tmp1 + c*tmp2);
  712. tmp1 = Row[2][0]; tmp2 = Row[2][2];
  713. Row[2][0] = (float)(c*tmp1 - s*tmp2);
  714. Row[2][2] = (float)(s*tmp1 + c*tmp2);
  715. }
  716. /***********************************************************************************************
  717. * M3DC::Rotate_Z -- Post-multiplies the matrix by a rotation about Z *
  718. * *
  719. * INPUT: *
  720. * theta - angle (in radians) to rotate *
  721. * *
  722. * OUTPUT: *
  723. * *
  724. * WARNINGS: *
  725. * *
  726. * HISTORY: *
  727. * 02/24/1997 GH : Created. *
  728. *=============================================================================================*/
  729. inline void Matrix3D::Rotate_Z(float theta)
  730. {
  731. float tmp1,tmp2;
  732. float c,s;
  733. c = cosf(theta);
  734. s = sinf(theta);
  735. tmp1 = Row[0][0]; tmp2 = Row[0][1];
  736. Row[0][0] = (float)( c*tmp1 + s*tmp2);
  737. Row[0][1] = (float)(-s*tmp1 + c*tmp2);
  738. tmp1 = Row[1][0]; tmp2 = Row[1][1];
  739. Row[1][0] = (float)( c*tmp1 + s*tmp2);
  740. Row[1][1] = (float)(-s*tmp1 + c*tmp2);
  741. tmp1 = Row[2][0]; tmp2 = Row[2][1];
  742. Row[2][0] = (float)( c*tmp1 + s*tmp2);
  743. Row[2][1] = (float)(-s*tmp1 + c*tmp2);
  744. }
  745. /***********************************************************************************************
  746. * M3DC::Rotate_Z -- Post-multiplies the matrix by a rotation about Z *
  747. * *
  748. * INPUT: *
  749. * s - sine of the angle to rotate *
  750. * c - cosine of the angle to rotate *
  751. * *
  752. * OUTPUT: *
  753. * *
  754. * WARNINGS: *
  755. * *
  756. * HISTORY: *
  757. * 02/24/1997 GH : Created. *
  758. *=============================================================================================*/
  759. inline void Matrix3D::Rotate_Z(float s,float c)
  760. {
  761. float tmp1,tmp2;
  762. tmp1 = Row[0][0]; tmp2 = Row[0][1];
  763. Row[0][0] = (float)( c*tmp1 + s*tmp2);
  764. Row[0][1] = (float)(-s*tmp1 + c*tmp2);
  765. tmp1 = Row[1][0]; tmp2 = Row[1][1];
  766. Row[1][0] = (float)( c*tmp1 + s*tmp2);
  767. Row[1][1] = (float)(-s*tmp1 + c*tmp2);
  768. tmp1 = Row[2][0]; tmp2 = Row[2][1];
  769. Row[2][0] = (float)( c*tmp1 + s*tmp2);
  770. Row[2][1] = (float)(-s*tmp1 + c*tmp2);
  771. }
  772. /***********************************************************************************************
  773. * M3DC::Pre_Rotate_X -- Pre-multiplies the matrix by a rotation about X *
  774. * *
  775. * INPUT: *
  776. * theta - angle (in radians) to rotate *
  777. * *
  778. * OUTPUT: *
  779. * *
  780. * WARNINGS: *
  781. * *
  782. * HISTORY: *
  783. * 07/1/1999 NH : Created. *
  784. *=============================================================================================*/
  785. inline void Matrix3D::Pre_Rotate_X(float theta)
  786. {
  787. float tmp1,tmp2;
  788. float c,s;
  789. c = cosf(theta);
  790. s = sinf(theta);
  791. tmp1 = Row[1][0]; tmp2 = Row[2][0];
  792. Row[1][0] = (float)(c*tmp1 - s*tmp2);
  793. Row[2][0] = (float)(s*tmp1 + c*tmp2);
  794. tmp1 = Row[1][1]; tmp2 = Row[2][1];
  795. Row[1][1] = (float)(c*tmp1 - s*tmp2);
  796. Row[2][1] = (float)(s*tmp1 + c*tmp2);
  797. tmp1 = Row[1][2]; tmp2 = Row[2][2];
  798. Row[1][2] = (float)(c*tmp1 - s*tmp2);
  799. Row[2][2] = (float)(s*tmp1 + c*tmp2);
  800. tmp1 = Row[1][3]; tmp2 = Row[2][3];
  801. Row[1][3] = (float)(c*tmp1 - s*tmp2);
  802. Row[2][3] = (float)(s*tmp1 + c*tmp2);
  803. }
  804. /***********************************************************************************************
  805. * M3DC::Pre_Rotate_Y -- Pre-multiplies the matrix by a rotation about Y *
  806. * *
  807. * INPUT: *
  808. * theta - angle (in radians) to rotate *
  809. * *
  810. * OUTPUT: *
  811. * *
  812. * WARNINGS: *
  813. * *
  814. * HISTORY: *
  815. * 07/1/1999 NH : Created. *
  816. *=============================================================================================*/
  817. inline void Matrix3D::Pre_Rotate_Y(float theta)
  818. {
  819. float tmp1,tmp2;
  820. float c,s;
  821. c = cosf(theta);
  822. s = sinf(theta);
  823. tmp1 = Row[0][0]; tmp2 = Row[2][0];
  824. Row[0][0] = (float)( c*tmp1 + s*tmp2);
  825. Row[2][0] = (float)(-s*tmp1 + c*tmp2);
  826. tmp1 = Row[0][1]; tmp2 = Row[2][1];
  827. Row[0][1] = (float)( c*tmp1 + s*tmp2);
  828. Row[2][1] = (float)(-s*tmp1 + c*tmp2);
  829. tmp1 = Row[0][2]; tmp2 = Row[2][2];
  830. Row[0][2] = (float)( c*tmp1 + s*tmp2);
  831. Row[2][2] = (float)(-s*tmp1 + c*tmp2);
  832. tmp1 = Row[0][3]; tmp2 = Row[2][3];
  833. Row[0][3] = (float)( c*tmp1 + s*tmp2);
  834. Row[2][3] = (float)(-s*tmp1 + c*tmp2);
  835. }
  836. /***********************************************************************************************
  837. * M3DC::Pre_Rotate_Z -- Pre-multiplies the matrix by a rotation about Z *
  838. * *
  839. * INPUT: *
  840. * theta - angle (in radians) to rotate *
  841. * *
  842. * OUTPUT: *
  843. * *
  844. * WARNINGS: *
  845. * *
  846. * HISTORY: *
  847. * 07/1/1999 NH : Created. *
  848. *=============================================================================================*/
  849. inline void Matrix3D::Pre_Rotate_Z(float theta)
  850. {
  851. float tmp1,tmp2;
  852. float c,s;
  853. c = cosf(theta);
  854. s = sinf(theta);
  855. tmp1 = Row[0][0]; tmp2 = Row[1][0];
  856. Row[0][0] = (float)(c*tmp1 - s*tmp2);
  857. Row[1][0] = (float)(s*tmp1 + c*tmp2);
  858. tmp1 = Row[0][1]; tmp2 = Row[1][1];
  859. Row[0][1] = (float)(c*tmp1 - s*tmp2);
  860. Row[1][1] = (float)(s*tmp1 + c*tmp2);
  861. tmp1 = Row[0][2]; tmp2 = Row[1][2];
  862. Row[0][2] = (float)(c*tmp1 - s*tmp2);
  863. Row[1][2] = (float)(s*tmp1 + c*tmp2);
  864. tmp1 = Row[0][3]; tmp2 = Row[1][3];
  865. Row[0][3] = (float)(c*tmp1 - s*tmp2);
  866. Row[1][3] = (float)(s*tmp1 + c*tmp2);
  867. }
  868. /***********************************************************************************************
  869. * M3DC::Pre_Rotate_X -- Pre-multiplies the matrix by a rotation about X *
  870. * *
  871. * INPUT: *
  872. * s - sine of the angle to rotate *
  873. * c - cosine of the angle to rotate *
  874. * *
  875. * OUTPUT: *
  876. * *
  877. * WARNINGS: *
  878. * *
  879. * HISTORY: *
  880. * 07/1/1999 NH : Created. *
  881. *=============================================================================================*/
  882. inline void Matrix3D::Pre_Rotate_X(float s,float c)
  883. {
  884. float tmp1,tmp2;
  885. tmp1 = Row[1][0]; tmp2 = Row[2][0];
  886. Row[1][0] = (float)(c*tmp1 - s*tmp2);
  887. Row[2][0] = (float)(s*tmp1 + c*tmp2);
  888. tmp1 = Row[1][1]; tmp2 = Row[2][1];
  889. Row[1][1] = (float)(c*tmp1 - s*tmp2);
  890. Row[2][1] = (float)(s*tmp1 + c*tmp2);
  891. tmp1 = Row[1][2]; tmp2 = Row[2][2];
  892. Row[1][2] = (float)(c*tmp1 - s*tmp2);
  893. Row[2][2] = (float)(s*tmp1 + c*tmp2);
  894. tmp1 = Row[1][3]; tmp2 = Row[2][3];
  895. Row[1][3] = (float)(c*tmp1 - s*tmp2);
  896. Row[2][3] = (float)(s*tmp1 + c*tmp2);
  897. }
  898. /***********************************************************************************************
  899. * M3DC::Pre_Rotate_Y -- Pre-multiplies the matrix by a rotation about Y *
  900. * *
  901. * INPUT: *
  902. * s - sine of the angle to rotate *
  903. * c - cosine of the angle to rotate *
  904. * *
  905. * OUTPUT: *
  906. * *
  907. * WARNINGS: *
  908. * *
  909. * HISTORY: *
  910. * 07/1/1999 NH : Created. *
  911. *=============================================================================================*/
  912. inline void Matrix3D::Pre_Rotate_Y(float s,float c)
  913. {
  914. float tmp1,tmp2;
  915. tmp1 = Row[0][0]; tmp2 = Row[2][0];
  916. Row[0][0] = (float)( c*tmp1 + s*tmp2);
  917. Row[2][0] = (float)(-s*tmp1 + c*tmp2);
  918. tmp1 = Row[0][1]; tmp2 = Row[2][1];
  919. Row[0][1] = (float)( c*tmp1 + s*tmp2);
  920. Row[2][1] = (float)(-s*tmp1 + c*tmp2);
  921. tmp1 = Row[0][2]; tmp2 = Row[2][2];
  922. Row[0][2] = (float)( c*tmp1 + s*tmp2);
  923. Row[2][2] = (float)(-s*tmp1 + c*tmp2);
  924. tmp1 = Row[0][3]; tmp2 = Row[2][3];
  925. Row[0][3] = (float)( c*tmp1 + s*tmp2);
  926. Row[2][3] = (float)(-s*tmp1 + c*tmp2);
  927. }
  928. /***********************************************************************************************
  929. * M3DC::Pre_Rotate_Z -- Pre-multiplies the matrix by a rotation about Z *
  930. * *
  931. * INPUT: *
  932. * s - sine of the angle to rotate *
  933. * c - cosine of the angle to rotate *
  934. * *
  935. * OUTPUT: *
  936. * *
  937. * WARNINGS: *
  938. * *
  939. * HISTORY: *
  940. * 07/1/1999 NH : Created. *
  941. *=============================================================================================*/
  942. inline void Matrix3D::Pre_Rotate_Z(float s,float c)
  943. {
  944. float tmp1,tmp2;
  945. tmp1 = Row[0][0]; tmp2 = Row[1][0];
  946. Row[0][0] = (float)(c*tmp1 - s*tmp2);
  947. Row[1][0] = (float)(s*tmp1 + c*tmp2);
  948. tmp1 = Row[0][1]; tmp2 = Row[1][1];
  949. Row[0][1] = (float)(c*tmp1 - s*tmp2);
  950. Row[1][1] = (float)(s*tmp1 + c*tmp2);
  951. tmp1 = Row[0][2]; tmp2 = Row[1][2];
  952. Row[0][2] = (float)(c*tmp1 - s*tmp2);
  953. Row[1][2] = (float)(s*tmp1 + c*tmp2);
  954. tmp1 = Row[0][3]; tmp2 = Row[1][3];
  955. Row[0][3] = (float)(c*tmp1 - s*tmp2);
  956. Row[1][3] = (float)(s*tmp1 + c*tmp2);
  957. }
  958. /***********************************************************************************************
  959. * M3DC::In_Place_Pre_Rotate_X -- Pre-multiplies rotation part of matrix by a rotation about X *
  960. * *
  961. * INPUT: *
  962. * theta - angle (in radians) to rotate *
  963. * *
  964. * OUTPUT: *
  965. * *
  966. * WARNINGS: *
  967. * *
  968. * HISTORY: *
  969. * 07/1/1999 NH : Created. *
  970. *=============================================================================================*/
  971. inline void Matrix3D::In_Place_Pre_Rotate_X(float theta)
  972. {
  973. float tmp1,tmp2;
  974. float c,s;
  975. c = cosf(theta);
  976. s = sinf(theta);
  977. tmp1 = Row[1][0]; tmp2 = Row[2][0];
  978. Row[1][0] = (float)(c*tmp1 - s*tmp2);
  979. Row[2][0] = (float)(s*tmp1 + c*tmp2);
  980. tmp1 = Row[1][1]; tmp2 = Row[2][1];
  981. Row[1][1] = (float)(c*tmp1 - s*tmp2);
  982. Row[2][1] = (float)(s*tmp1 + c*tmp2);
  983. tmp1 = Row[1][2]; tmp2 = Row[2][2];
  984. Row[1][2] = (float)(c*tmp1 - s*tmp2);
  985. Row[2][2] = (float)(s*tmp1 + c*tmp2);
  986. }
  987. /***********************************************************************************************
  988. * M3DC::In_Place_Pre_Rotate_Y -- Pre-multiplies rotation part of matrix by a rotation about Y *
  989. * *
  990. * INPUT: *
  991. * theta - angle (in radians) to rotate *
  992. * *
  993. * OUTPUT: *
  994. * *
  995. * WARNINGS: *
  996. * *
  997. * HISTORY: *
  998. * 07/1/1999 NH : Created. *
  999. *=============================================================================================*/
  1000. inline void Matrix3D::In_Place_Pre_Rotate_Y(float theta)
  1001. {
  1002. float tmp1,tmp2;
  1003. float c,s;
  1004. c = cosf(theta);
  1005. s = sinf(theta);
  1006. tmp1 = Row[0][0]; tmp2 = Row[2][0];
  1007. Row[0][0] = (float)( c*tmp1 + s*tmp2);
  1008. Row[2][0] = (float)(-s*tmp1 + c*tmp2);
  1009. tmp1 = Row[0][1]; tmp2 = Row[2][1];
  1010. Row[0][1] = (float)( c*tmp1 + s*tmp2);
  1011. Row[2][1] = (float)(-s*tmp1 + c*tmp2);
  1012. tmp1 = Row[0][2]; tmp2 = Row[2][2];
  1013. Row[0][2] = (float)( c*tmp1 + s*tmp2);
  1014. Row[2][2] = (float)(-s*tmp1 + c*tmp2);
  1015. }
  1016. /***********************************************************************************************
  1017. * M3DC::In_Place_Pre_Rotate_Z -- Pre-multiplies rotation part of matrix by a rotation about Z *
  1018. * *
  1019. * INPUT: *
  1020. * theta - angle (in radians) to rotate *
  1021. * *
  1022. * OUTPUT: *
  1023. * *
  1024. * WARNINGS: *
  1025. * *
  1026. * HISTORY: *
  1027. * 07/1/1999 NH : Created. *
  1028. *=============================================================================================*/
  1029. inline void Matrix3D::In_Place_Pre_Rotate_Z(float theta)
  1030. {
  1031. float tmp1,tmp2;
  1032. float c,s;
  1033. c = cosf(theta);
  1034. s = sinf(theta);
  1035. tmp1 = Row[0][0]; tmp2 = Row[1][0];
  1036. Row[0][0] = (float)(c*tmp1 - s*tmp2);
  1037. Row[1][0] = (float)(s*tmp1 + c*tmp2);
  1038. tmp1 = Row[0][1]; tmp2 = Row[1][1];
  1039. Row[0][1] = (float)(c*tmp1 - s*tmp2);
  1040. Row[1][1] = (float)(s*tmp1 + c*tmp2);
  1041. tmp1 = Row[0][2]; tmp2 = Row[1][2];
  1042. Row[0][2] = (float)(c*tmp1 - s*tmp2);
  1043. Row[1][2] = (float)(s*tmp1 + c*tmp2);
  1044. }
  1045. /***********************************************************************************************
  1046. * M3DC::In_Place_Pre_Rotate_X -- Pre-multiplies rotation part of matrix by a rotation about X *
  1047. * *
  1048. * INPUT: *
  1049. * s - sine of the angle to rotate *
  1050. * c - cosine of the angle to rotate *
  1051. * *
  1052. * OUTPUT: *
  1053. * *
  1054. * WARNINGS: *
  1055. * *
  1056. * HISTORY: *
  1057. * 07/1/1999 NH : Created. *
  1058. *=============================================================================================*/
  1059. inline void Matrix3D::In_Place_Pre_Rotate_X(float s,float c)
  1060. {
  1061. float tmp1,tmp2;
  1062. tmp1 = Row[1][0]; tmp2 = Row[2][0];
  1063. Row[1][0] = (float)(c*tmp1 - s*tmp2);
  1064. Row[2][0] = (float)(s*tmp1 + c*tmp2);
  1065. tmp1 = Row[1][1]; tmp2 = Row[2][1];
  1066. Row[1][1] = (float)(c*tmp1 - s*tmp2);
  1067. Row[2][1] = (float)(s*tmp1 + c*tmp2);
  1068. tmp1 = Row[1][2]; tmp2 = Row[2][2];
  1069. Row[1][2] = (float)(c*tmp1 - s*tmp2);
  1070. Row[2][2] = (float)(s*tmp1 + c*tmp2);
  1071. }
  1072. /***********************************************************************************************
  1073. * M3DC::In_Place_Pre_Rotate_Y -- Pre-multiplies rotation part of matrix by a rotation about Y *
  1074. * *
  1075. * INPUT: *
  1076. * s - sine of the angle to rotate *
  1077. * c - cosine of the angle to rotate *
  1078. * *
  1079. * OUTPUT: *
  1080. * *
  1081. * WARNINGS: *
  1082. * *
  1083. * HISTORY: *
  1084. * 07/1/1999 NH : Created. *
  1085. *=============================================================================================*/
  1086. inline void Matrix3D::In_Place_Pre_Rotate_Y(float s,float c)
  1087. {
  1088. float tmp1,tmp2;
  1089. tmp1 = Row[0][0]; tmp2 = Row[2][0];
  1090. Row[0][0] = (float)( c*tmp1 + s*tmp2);
  1091. Row[2][0] = (float)(-s*tmp1 + c*tmp2);
  1092. tmp1 = Row[0][1]; tmp2 = Row[2][1];
  1093. Row[0][1] = (float)( c*tmp1 + s*tmp2);
  1094. Row[2][1] = (float)(-s*tmp1 + c*tmp2);
  1095. tmp1 = Row[0][2]; tmp2 = Row[2][2];
  1096. Row[0][2] = (float)( c*tmp1 + s*tmp2);
  1097. Row[2][2] = (float)(-s*tmp1 + c*tmp2);
  1098. }
  1099. /***********************************************************************************************
  1100. * M3DC::In_Place_Pre_Rotate_Z -- Pre-multiplies rotation part of matrix by a rotation about Z *
  1101. * *
  1102. * INPUT: *
  1103. * s - sine of the angle to rotate *
  1104. * c - cosine of the angle to rotate *
  1105. * *
  1106. * OUTPUT: *
  1107. * *
  1108. * WARNINGS: *
  1109. * *
  1110. * HISTORY: *
  1111. * 07/1/1999 NH : Created. *
  1112. *=============================================================================================*/
  1113. inline void Matrix3D::In_Place_Pre_Rotate_Z(float s,float c)
  1114. {
  1115. float tmp1,tmp2;
  1116. tmp1 = Row[0][0]; tmp2 = Row[1][0];
  1117. Row[0][0] = (float)(c*tmp1 - s*tmp2);
  1118. Row[1][0] = (float)(s*tmp1 + c*tmp2);
  1119. tmp1 = Row[0][1]; tmp2 = Row[1][1];
  1120. Row[0][1] = (float)(c*tmp1 - s*tmp2);
  1121. Row[1][1] = (float)(s*tmp1 + c*tmp2);
  1122. tmp1 = Row[0][2]; tmp2 = Row[1][2];
  1123. Row[0][2] = (float)(c*tmp1 - s*tmp2);
  1124. Row[1][2] = (float)(s*tmp1 + c*tmp2);
  1125. }
  1126. /***********************************************************************************************
  1127. * operator * -- Matrix multiplication *
  1128. * *
  1129. * INPUT: *
  1130. * *
  1131. * OUTPUT: *
  1132. * *
  1133. * WARNINGS: *
  1134. * *
  1135. * HISTORY: *
  1136. * 02/24/1997 GH : Created. *
  1137. *=============================================================================================*/
  1138. inline Matrix3D operator * (const Matrix3D &A,const Matrix3D &B)
  1139. {
  1140. Matrix3D C;
  1141. float tmp1,tmp2,tmp3;
  1142. tmp1 = B[0][0];
  1143. tmp2 = B[1][0];
  1144. tmp3 = B[2][0];
  1145. C[0][0] = (float)(A[0][0]*tmp1 + A[0][1]*tmp2 + A[0][2]*tmp3);
  1146. C[1][0] = (float)(A[1][0]*tmp1 + A[1][1]*tmp2 + A[1][2]*tmp3);
  1147. C[2][0] = (float)(A[2][0]*tmp1 + A[2][1]*tmp2 + A[2][2]*tmp3);
  1148. tmp1 = B[0][1];
  1149. tmp2 = B[1][1];
  1150. tmp3 = B[2][1];
  1151. C[0][1] = (float)(A[0][0]*tmp1 + A[0][1]*tmp2 + A[0][2]*tmp3);
  1152. C[1][1] = (float)(A[1][0]*tmp1 + A[1][1]*tmp2 + A[1][2]*tmp3);
  1153. C[2][1] = (float)(A[2][0]*tmp1 + A[2][1]*tmp2 + A[2][2]*tmp3);
  1154. tmp1 = B[0][2];
  1155. tmp2 = B[1][2];
  1156. tmp3 = B[2][2];
  1157. C[0][2] = (float)(A[0][0]*tmp1 + A[0][1]*tmp2 + A[0][2]*tmp3);
  1158. C[1][2] = (float)(A[1][0]*tmp1 + A[1][1]*tmp2 + A[1][2]*tmp3);
  1159. C[2][2] = (float)(A[2][0]*tmp1 + A[2][1]*tmp2 + A[2][2]*tmp3);
  1160. tmp1 = B[0][3];
  1161. tmp2 = B[1][3];
  1162. tmp3 = B[2][3];
  1163. C[0][3] = (float)(A[0][0]*tmp1 + A[0][1]*tmp2 + A[0][2]*tmp3 + A[0][3]);
  1164. C[1][3] = (float)(A[1][0]*tmp1 + A[1][1]*tmp2 + A[1][2]*tmp3 + A[1][3]);
  1165. C[2][3] = (float)(A[2][0]*tmp1 + A[2][1]*tmp2 + A[2][2]*tmp3 + A[2][3]);
  1166. return C;
  1167. }
  1168. /***********************************************************************************************
  1169. * operator * -- Matrix - vector multiplication *
  1170. * *
  1171. * INPUT: *
  1172. * *
  1173. * OUTPUT: *
  1174. * *
  1175. * WARNINGS: *
  1176. * *
  1177. * HISTORY: *
  1178. * 02/24/1997 GH : Created. *
  1179. *=============================================================================================*/
  1180. inline Vector3 operator * (const Matrix3D &A,const Vector3 &a)
  1181. {
  1182. #if 0
  1183. return Vector3
  1184. (
  1185. (A[0][0]*a[0] + A[0][1]*a[1] + A[0][2]*a[2] + A[0][3]),
  1186. (A[1][0]*a[0] + A[1][1]*a[1] + A[1][2]*a[2] + A[1][3]),
  1187. (A[2][0]*a[0] + A[2][1]*a[1] + A[2][2]*a[2] + A[2][3])
  1188. );
  1189. #else
  1190. return Vector3
  1191. (
  1192. (A.Row[0].X*a.X + A.Row[0].Y*a.Y + A.Row[0].Z*a.Z + A.Row[0].W),
  1193. (A.Row[1].X*a.X + A.Row[1].Y*a.Y + A.Row[1].Z*a.Z + A.Row[1].W),
  1194. (A.Row[2].X*a.X + A.Row[2].Y*a.Y + A.Row[2].Z*a.Z + A.Row[2].W)
  1195. );
  1196. #endif
  1197. }
  1198. /***********************************************************************************************
  1199. * operator == -- Matrix equality operator *
  1200. * *
  1201. * INPUT: *
  1202. * *
  1203. * OUTPUT: *
  1204. * *
  1205. * WARNINGS: *
  1206. * *
  1207. * HISTORY: *
  1208. * 04/29/1998 NH : Created. *
  1209. *=============================================================================================*/
  1210. inline bool operator == (const Matrix3D &A, const Matrix3D &B)
  1211. {
  1212. for (int i = 0; i < 3; i++) {
  1213. for (int j = 0; j < 4; j++) {
  1214. if (A[i][j] != B[i][j]) return false;
  1215. }
  1216. }
  1217. return true;
  1218. }
  1219. /***********************************************************************************************
  1220. * operator != -- Matrix inequality operator *
  1221. * *
  1222. * INPUT: *
  1223. * *
  1224. * OUTPUT: *
  1225. * *
  1226. * WARNINGS: *
  1227. * *
  1228. * HISTORY: *
  1229. * 04/29/1998 NH : Created. *
  1230. *=============================================================================================*/
  1231. inline bool operator != (const Matrix3D &A, const Matrix3D &B)
  1232. {
  1233. return !(A == B);
  1234. }
  1235. inline void Matrix3D::Transform_Vector(const Matrix3D & A,const Vector3 & in,Vector3 * out)
  1236. {
  1237. Vector3 tmp;
  1238. Vector3 * v;
  1239. // check for aliased parameters
  1240. if (out == &in) {
  1241. tmp = in;
  1242. v = &tmp;
  1243. } else {
  1244. v = (Vector3 *)&in; // whats the right way to do this...
  1245. }
  1246. out->X = (A[0][0] * v->X + A[0][1] * v->Y + A[0][2] * v->Z + A[0][3]);
  1247. out->Y = (A[1][0] * v->X + A[1][1] * v->Y + A[1][2] * v->Z + A[1][3]);
  1248. out->Z = (A[2][0] * v->X + A[2][1] * v->Y + A[2][2] * v->Z + A[2][3]);
  1249. }
  1250. inline void Matrix3D::Rotate_Vector(const Matrix3D & A,const Vector3 & in,Vector3 * out)
  1251. {
  1252. Vector3 tmp;
  1253. Vector3 * v;
  1254. // check for aliased parameters
  1255. if (out == &in) {
  1256. tmp = in;
  1257. v = &tmp;
  1258. } else {
  1259. v = (Vector3 *)&in;
  1260. }
  1261. out->X = (A[0][0] * v->X + A[0][1] * v->Y + A[0][2] * v->Z);
  1262. out->Y = (A[1][0] * v->X + A[1][1] * v->Y + A[1][2] * v->Z);
  1263. out->Z = (A[2][0] * v->X + A[2][1] * v->Y + A[2][2] * v->Z);
  1264. }
  1265. inline void Matrix3D::Inverse_Transform_Vector(const Matrix3D & A,const Vector3 & in,Vector3 * out)
  1266. {
  1267. Vector3 tmp;
  1268. Vector3 * v;
  1269. // check for aliased parameters
  1270. if (out == &in) {
  1271. tmp = in;
  1272. v = &tmp;
  1273. } else {
  1274. v = (Vector3 *)&in; // whats the right way to do this...
  1275. }
  1276. Vector3 diff(v->X - A[0][3], v->Y - A[1][3], v->Z - A[2][3]);
  1277. Matrix3D::Inverse_Rotate_Vector(A, diff, out);
  1278. }
  1279. inline void Matrix3D::Inverse_Rotate_Vector(const Matrix3D & A,const Vector3 & in,Vector3 * out)
  1280. {
  1281. Vector3 tmp;
  1282. Vector3 * v;
  1283. // check for aliased parameters
  1284. if (out == &in) {
  1285. tmp = in;
  1286. v = &tmp;
  1287. } else {
  1288. v = (Vector3 *)&in;
  1289. }
  1290. out->X = (A[0][0] * v->X + A[1][0] * v->Y + A[2][0] * v->Z);
  1291. out->Y = (A[0][1] * v->X + A[1][1] * v->Y + A[2][1] * v->Z);
  1292. out->Z = (A[0][2] * v->X + A[1][2] * v->Y + A[2][2] * v->Z);
  1293. }
  1294. #endif /* MATRIX3D_H */