matrix3d.h 81 KB

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