matrix3d.h 86 KB

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