lmatrix4_src.I 49 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422
  1. // Filename: lmatrix4_src.I
  2. // Created by: drose (15Jan99)
  3. //
  4. ////////////////////////////////////////////////////////////////////
  5. //
  6. // PANDA 3D SOFTWARE
  7. // Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
  8. //
  9. // All use of this software is subject to the terms of the Panda 3d
  10. // Software license. You should have received a copy of this license
  11. // along with this source code; you will also find a current copy of
  12. // the license at http://www.panda3d.org/license.txt .
  13. //
  14. // To contact the maintainers of this program write to
  15. // [email protected] .
  16. //
  17. ////////////////////////////////////////////////////////////////////
  18. ////////////////////////////////////////////////////////////////////
  19. // Function: LMatrix4::ident_mat
  20. // Access: Public, Static
  21. // Description: Returns an identity matrix.
  22. //
  23. // This function definition must appear first, since
  24. // some inline functions below take advantage of it.
  25. ////////////////////////////////////////////////////////////////////
  26. INLINE_LINMATH const FLOATNAME(LMatrix4) &FLOATNAME(LMatrix4)::
  27. ident_mat() {
  28. return _ident_mat;
  29. }
  30. ////////////////////////////////////////////////////////////////////
  31. // Function: LMatrix4::Default Constructor
  32. // Access: Public
  33. // Description:
  34. ////////////////////////////////////////////////////////////////////
  35. INLINE_LINMATH FLOATNAME(LMatrix4)::
  36. FLOATNAME(LMatrix4)() {
  37. }
  38. ////////////////////////////////////////////////////////////////////
  39. // Function: LMatrix4::Copy Constructor
  40. // Access: Public
  41. // Description:
  42. ////////////////////////////////////////////////////////////////////
  43. INLINE_LINMATH FLOATNAME(LMatrix4)::
  44. FLOATNAME(LMatrix4)(const FLOATNAME(LMatrix4) &copy) {
  45. memcpy(_m.data,copy._m.data,sizeof(_m.data));
  46. // (*this) = copy;
  47. }
  48. ////////////////////////////////////////////////////////////////////
  49. // Function: LMatrix4::Copy Assignment Operator
  50. // Access: Public
  51. // Description:
  52. ////////////////////////////////////////////////////////////////////
  53. INLINE_LINMATH FLOATNAME(LMatrix4) &FLOATNAME(LMatrix4)::
  54. operator = (const FLOATNAME(LMatrix4) &copy) {
  55. //xxx888
  56. memcpy(_m.data,copy._m.data,sizeof(_m.data));
  57. // set(copy(0, 0), copy(0, 1), copy(0, 2), copy(0, 3),
  58. // copy(1, 0), copy(1, 1), copy(1, 2), copy(1, 3),
  59. // copy(2, 0), copy(2, 1), copy(2, 2), copy(2, 3),
  60. // copy(3, 0), copy(3, 1), copy(3, 2), copy(3, 3));
  61. return *this;
  62. //xxx000
  63. }
  64. ////////////////////////////////////////////////////////////////////
  65. // Function: LMatrix4::Fill Assignment Operator
  66. // Access: Public
  67. // Description:
  68. ////////////////////////////////////////////////////////////////////
  69. INLINE_LINMATH FLOATNAME(LMatrix4) &FLOATNAME(LMatrix4)::
  70. operator = (FLOATTYPE fill_value) {
  71. fill(fill_value);
  72. return *this;
  73. }
  74. ////////////////////////////////////////////////////////////////////
  75. // Function: LMatrix4::Constructor
  76. // Access: Public
  77. // Description:
  78. ////////////////////////////////////////////////////////////////////
  79. INLINE_LINMATH FLOATNAME(LMatrix4)::
  80. FLOATNAME(LMatrix4)(FLOATTYPE e00, FLOATTYPE e01, FLOATTYPE e02, FLOATTYPE e03,
  81. FLOATTYPE e10, FLOATTYPE e11, FLOATTYPE e12, FLOATTYPE e13,
  82. FLOATTYPE e20, FLOATTYPE e21, FLOATTYPE e22, FLOATTYPE e23,
  83. FLOATTYPE e30, FLOATTYPE e31, FLOATTYPE e32, FLOATTYPE e33) {
  84. _m.m._00 = e00;
  85. _m.m._01 = e01;
  86. _m.m._02 = e02;
  87. _m.m._03 = e03;
  88. _m.m._10 = e10;
  89. _m.m._11 = e11;
  90. _m.m._12 = e12;
  91. _m.m._13 = e13;
  92. _m.m._20 = e20;
  93. _m.m._21 = e21;
  94. _m.m._22 = e22;
  95. _m.m._23 = e23;
  96. _m.m._30 = e30;
  97. _m.m._31 = e31;
  98. _m.m._32 = e32;
  99. _m.m._33 = e33;
  100. }
  101. ////////////////////////////////////////////////////////////////////
  102. // Function: LMatrix4::Constructor, upper 3x3
  103. // Access: Public
  104. // Description:
  105. ////////////////////////////////////////////////////////////////////
  106. INLINE_LINMATH FLOATNAME(LMatrix4)::
  107. FLOATNAME(LMatrix4)(const FLOATNAME(LMatrix3) &upper3) {
  108. _m.m._00 = upper3._m.m._00;
  109. _m.m._01 = upper3._m.m._01;
  110. _m.m._02 = upper3._m.m._02;
  111. _m.m._03 = 0.0f;
  112. _m.m._10 = upper3._m.m._10;
  113. _m.m._11 = upper3._m.m._11;
  114. _m.m._12 = upper3._m.m._12;
  115. _m.m._13 = 0.0f;
  116. _m.m._20 = upper3._m.m._20;
  117. _m.m._21 = upper3._m.m._21;
  118. _m.m._22 = upper3._m.m._22;
  119. _m.m._23 = 0.0f;
  120. _m.m._30 = 0.0f;
  121. _m.m._31 = 0.0f;
  122. _m.m._32 = 0.0f;
  123. _m.m._33 = 1.0f;
  124. // set(upper3(0, 0), upper3(0, 1), upper3(0, 2), 0.0f,
  125. // upper3(1, 0), upper3(1, 1), upper3(1, 2), 0.0f,
  126. // upper3(2, 0), upper3(2, 1), upper3(2, 2), 0.0f,
  127. // 0.0f, 0.0f, 0.0f, 1.0f);
  128. }
  129. ////////////////////////////////////////////////////////////////////
  130. // Function: LMatrix4::Constructor, upper 3x3 plus translation
  131. // Access: Public
  132. // Description:
  133. ////////////////////////////////////////////////////////////////////
  134. INLINE_LINMATH FLOATNAME(LMatrix4)::
  135. FLOATNAME(LMatrix4)(const FLOATNAME(LMatrix3) &upper3,
  136. const FLOATNAME(LVecBase3) &trans) {
  137. _m.m._00 = upper3._m.m._00;
  138. _m.m._01 = upper3._m.m._01;
  139. _m.m._02 = upper3._m.m._02;
  140. _m.m._03 = 0.0f;
  141. _m.m._10 = upper3._m.m._10;
  142. _m.m._11 = upper3._m.m._11;
  143. _m.m._12 = upper3._m.m._12;
  144. _m.m._13 = 0.0f;
  145. _m.m._20 = upper3._m.m._20;
  146. _m.m._21 = upper3._m.m._21;
  147. _m.m._22 = upper3._m.m._22;
  148. _m.m._23 = 0.0f;
  149. _m.m._30 = trans._v.v._0;
  150. _m.m._31 = trans._v.v._1;
  151. _m.m._32 = trans._v.v._2;
  152. _m.m._33 = 1.0f;
  153. // set(upper3(0, 0), upper3(0, 1), upper3(0, 2), 0.0f,
  154. // upper3(1, 0), upper3(1, 1), upper3(1, 2), 0.0f,
  155. // upper3(2, 0), upper3(2, 1), upper3(2, 2), 0.0f,
  156. // trans[0], trans[1], trans[2], 1.0f);
  157. }
  158. ////////////////////////////////////////////////////////////////////
  159. // Function: LMatrix4::fill
  160. // Access: Public
  161. // Description: Sets each element of the matrix to the indicated
  162. // fill_value. This is of questionable value, but is
  163. // sometimes useful when initializing to zero.
  164. ////////////////////////////////////////////////////////////////////
  165. INLINE_LINMATH void FLOATNAME(LMatrix4)::
  166. fill(FLOATTYPE fill_value) {
  167. set(fill_value, fill_value, fill_value, fill_value,
  168. fill_value, fill_value, fill_value, fill_value,
  169. fill_value, fill_value, fill_value, fill_value,
  170. fill_value, fill_value, fill_value, fill_value);
  171. }
  172. ////////////////////////////////////////////////////////////////////
  173. // Function: LMatrix4::set
  174. // Access: Public
  175. // Description:
  176. ////////////////////////////////////////////////////////////////////
  177. INLINE_LINMATH void FLOATNAME(LMatrix4)::
  178. set(FLOATTYPE e00, FLOATTYPE e01, FLOATTYPE e02, FLOATTYPE e03,
  179. FLOATTYPE e10, FLOATTYPE e11, FLOATTYPE e12, FLOATTYPE e13,
  180. FLOATTYPE e20, FLOATTYPE e21, FLOATTYPE e22, FLOATTYPE e23,
  181. FLOATTYPE e30, FLOATTYPE e31, FLOATTYPE e32, FLOATTYPE e33) {
  182. _m.m._00 = e00;
  183. _m.m._01 = e01;
  184. _m.m._02 = e02;
  185. _m.m._03 = e03;
  186. _m.m._10 = e10;
  187. _m.m._11 = e11;
  188. _m.m._12 = e12;
  189. _m.m._13 = e13;
  190. _m.m._20 = e20;
  191. _m.m._21 = e21;
  192. _m.m._22 = e22;
  193. _m.m._23 = e23;
  194. _m.m._30 = e30;
  195. _m.m._31 = e31;
  196. _m.m._32 = e32;
  197. _m.m._33 = e33;
  198. }
  199. ////////////////////////////////////////////////////////////////////
  200. // Function: LMatrix4::set_upper_3
  201. // Access: Public
  202. // Description: Sets the upper 3x3 submatrix.
  203. ////////////////////////////////////////////////////////////////////
  204. INLINE_LINMATH void FLOATNAME(LMatrix4)::
  205. set_upper_3(const FLOATNAME(LMatrix3) &upper3) {
  206. _m.m._00 = upper3(0, 0);
  207. _m.m._01 = upper3(0, 1);
  208. _m.m._02 = upper3(0, 2);
  209. _m.m._10 = upper3(1, 0);
  210. _m.m._11 = upper3(1, 1);
  211. _m.m._12 = upper3(1, 2);
  212. _m.m._20 = upper3(2, 0);
  213. _m.m._21 = upper3(2, 1);
  214. _m.m._22 = upper3(2, 2);
  215. }
  216. ////////////////////////////////////////////////////////////////////
  217. // Function: LMatrix4::get_upper_3
  218. // Access: Public
  219. // Description: Retrieves the upper 3x3 submatrix.
  220. ////////////////////////////////////////////////////////////////////
  221. INLINE_LINMATH FLOATNAME(LMatrix3) FLOATNAME(LMatrix4)::
  222. get_upper_3() const {
  223. return FLOATNAME(LMatrix3)
  224. (_m.m._00, _m.m._01, _m.m._02,
  225. _m.m._10, _m.m._11, _m.m._12,
  226. _m.m._20, _m.m._21, _m.m._22);
  227. }
  228. ////////////////////////////////////////////////////////////////////
  229. // Function: LMatrix4::set_row
  230. // Access: Public
  231. // Description: Replaces the indicated row of the matrix.
  232. ////////////////////////////////////////////////////////////////////
  233. INLINE_LINMATH void FLOATNAME(LMatrix4)::
  234. set_row(int row, const FLOATNAME(LVecBase4) &v) {
  235. (*this)(row, 0) = v._v.v._0;
  236. (*this)(row, 1) = v._v.v._1;
  237. (*this)(row, 2) = v._v.v._2;
  238. (*this)(row, 3) = v._v.v._3;
  239. }
  240. ////////////////////////////////////////////////////////////////////
  241. // Function: LMatrix4::set_col
  242. // Access: Public
  243. // Description: Replaces the indicated column of the matrix.
  244. ////////////////////////////////////////////////////////////////////
  245. INLINE_LINMATH void FLOATNAME(LMatrix4)::
  246. set_col(int col, const FLOATNAME(LVecBase4) &v) {
  247. (*this)(0, col) = v._v.v._0;
  248. (*this)(1, col) = v._v.v._1;
  249. (*this)(2, col) = v._v.v._2;
  250. (*this)(3, col) = v._v.v._3;
  251. }
  252. ////////////////////////////////////////////////////////////////////
  253. // Function: LMatrix4::set_row
  254. // Access: Public
  255. // Description: Replaces the indicated row of the matrix with the
  256. // indicated 3-component vector, ignoring the last
  257. // column.
  258. ////////////////////////////////////////////////////////////////////
  259. INLINE_LINMATH void FLOATNAME(LMatrix4)::
  260. set_row(int row, const FLOATNAME(LVecBase3) &v) {
  261. (*this)(row, 0) = v._v.v._0;
  262. (*this)(row, 1) = v._v.v._1;
  263. (*this)(row, 2) = v._v.v._2;
  264. }
  265. ////////////////////////////////////////////////////////////////////
  266. // Function: LMatrix4::set_col
  267. // Access: Public
  268. // Description: Replaces the indicated column of the matrix with the
  269. // indicated 3-component vector, ignoring the last
  270. // row.
  271. ////////////////////////////////////////////////////////////////////
  272. INLINE_LINMATH void FLOATNAME(LMatrix4)::
  273. set_col(int col, const FLOATNAME(LVecBase3) &v) {
  274. (*this)(0, col) = v._v.v._0;
  275. (*this)(1, col) = v._v.v._1;
  276. (*this)(2, col) = v._v.v._2;
  277. }
  278. ////////////////////////////////////////////////////////////////////
  279. // Function: LMatrix4::get_row
  280. // Access: Public
  281. // Description: Retrieves the indicated row of the matrix as a
  282. // 4-component vector.
  283. ////////////////////////////////////////////////////////////////////
  284. INLINE_LINMATH FLOATNAME(LVecBase4) FLOATNAME(LMatrix4)::
  285. get_row(int row) const {
  286. return FLOATNAME(LVecBase4)((*this)(row, 0),
  287. (*this)(row, 1),
  288. (*this)(row, 2),
  289. (*this)(row, 3));
  290. }
  291. INLINE_LINMATH void FLOATNAME(LMatrix4)::
  292. get_row(FLOATNAME(LVecBase4) &result_vec,int row) const {
  293. result_vec._v.v._0 = (*this)(row, 0);
  294. result_vec._v.v._1 = (*this)(row, 1);
  295. result_vec._v.v._2 = (*this)(row, 2);
  296. result_vec._v.v._3 = (*this)(row, 3);
  297. }
  298. ////////////////////////////////////////////////////////////////////
  299. // Function: LMatrix4::get_col
  300. // Access: Public
  301. // Description: Retrieves the indicated column of the matrix as a
  302. // 4-component vector.
  303. ////////////////////////////////////////////////////////////////////
  304. INLINE_LINMATH FLOATNAME(LVecBase4) FLOATNAME(LMatrix4)::
  305. get_col(int col) const {
  306. return FLOATNAME(LVecBase4)((*this)(0, col),
  307. (*this)(1, col),
  308. (*this)(2, col),
  309. (*this)(3, col));
  310. }
  311. ////////////////////////////////////////////////////////////////////
  312. // Function: LMatrix4::get_row3
  313. // Access: Public
  314. // Description: Retrieves the row column of the matrix as a
  315. // 3-component vector, ignoring the last column.
  316. ////////////////////////////////////////////////////////////////////
  317. INLINE_LINMATH FLOATNAME(LVecBase3) FLOATNAME(LMatrix4)::
  318. get_row3(int row) const {
  319. return FLOATNAME(LVecBase3)((*this)(row, 0),
  320. (*this)(row, 1),
  321. (*this)(row, 2));
  322. }
  323. INLINE_LINMATH void FLOATNAME(LMatrix4)::
  324. get_row3(FLOATNAME(LVecBase3) &result_vec,int row) const {
  325. result_vec._v.v._0 = (*this)(row, 0);
  326. result_vec._v.v._1 = (*this)(row, 1);
  327. result_vec._v.v._2 = (*this)(row, 2);
  328. }
  329. ////////////////////////////////////////////////////////////////////
  330. // Function: LMatrix4::get_col3
  331. // Access: Public
  332. // Description: Retrieves the indicated column of the matrix as a
  333. // 3-component vector, ignoring the last row.
  334. ////////////////////////////////////////////////////////////////////
  335. INLINE_LINMATH FLOATNAME(LVecBase3) FLOATNAME(LMatrix4)::
  336. get_col3(int col) const {
  337. return FLOATNAME(LVecBase3)((*this)(0, col),
  338. (*this)(1, col),
  339. (*this)(2, col));
  340. }
  341. ////////////////////////////////////////////////////////////////////
  342. // Function: LMatrix4::Indexing operator
  343. // Access: Public
  344. // Description:
  345. ////////////////////////////////////////////////////////////////////
  346. INLINE_LINMATH FLOATTYPE &FLOATNAME(LMatrix4)::
  347. operator () (int row, int col) {
  348. nassertr(row >= 0 && row < 4 && col >= 0 && col < 4, _m.data[0]);
  349. return _m.data[row * 4 + col];
  350. }
  351. ////////////////////////////////////////////////////////////////////
  352. // Function: LMatrix4::Indexing operator
  353. // Access: Public
  354. // Description:
  355. ////////////////////////////////////////////////////////////////////
  356. INLINE_LINMATH FLOATTYPE FLOATNAME(LMatrix4)::
  357. operator () (int row, int col) const {
  358. nassertr(row >= 0 && row < 4 && col >= 0 && col < 4, 0.0f);
  359. return _m.data[row * 4 + col];
  360. }
  361. ////////////////////////////////////////////////////////////////////
  362. // Function: LMatrix4::is_nan
  363. // Access: Public
  364. // Description: Returns true if any component of the matrix is
  365. // not-a-number, false otherwise.
  366. ////////////////////////////////////////////////////////////////////
  367. INLINE_LINMATH bool FLOATNAME(LMatrix4)::
  368. is_nan() const {
  369. return
  370. cnan(_m.data[0]) || cnan(_m.data[1]) || cnan(_m.data[2]) || cnan(_m.data[3]) ||
  371. cnan(_m.data[4]) || cnan(_m.data[5]) || cnan(_m.data[6]) || cnan(_m.data[7]) ||
  372. cnan(_m.data[8]) || cnan(_m.data[9]) || cnan(_m.data[10]) || cnan(_m.data[11]) ||
  373. cnan(_m.data[12]) || cnan(_m.data[13]) || cnan(_m.data[14]) || cnan(_m.data[15]);
  374. }
  375. ////////////////////////////////////////////////////////////////////
  376. // Function: LMatrix4::get_cell
  377. // Access: Public
  378. // Description: Returns a particular element of the matrix.
  379. ////////////////////////////////////////////////////////////////////
  380. INLINE_LINMATH FLOATTYPE FLOATNAME(LMatrix4)::
  381. get_cell(int row, int col) const {
  382. nassertr(row >= 0 && row < 4 && col >= 0 && col < 4, 0.0f);
  383. return _m.data[row * 4 + col];
  384. }
  385. ////////////////////////////////////////////////////////////////////
  386. // Function: LMatrix4::set_cell
  387. // Access: Public
  388. // Description: Changes a particular element of the matrix.
  389. ////////////////////////////////////////////////////////////////////
  390. INLINE_LINMATH void FLOATNAME(LMatrix4)::
  391. set_cell(int row, int col, FLOATTYPE value) {
  392. nassertv(row >= 0 && row < 4 && col >= 0 && col < 4);
  393. _m.data[row * 4 + col] = value;
  394. }
  395. ////////////////////////////////////////////////////////////////////
  396. // Function: LMatrix4::get_data
  397. // Access: Public
  398. // Description: Returns the address of the first of the nine data
  399. // elements in the matrix. The remaining elements
  400. // occupy the next eight positions in row-major order.
  401. ////////////////////////////////////////////////////////////////////
  402. INLINE_LINMATH const FLOATTYPE *FLOATNAME(LMatrix4)::
  403. get_data() const {
  404. return _m.data;
  405. }
  406. ////////////////////////////////////////////////////////////////////
  407. // Function: LMatrix4::get_num_components
  408. // Access: Public
  409. // Description: Returns the number of elements in the matrix, 16.
  410. ////////////////////////////////////////////////////////////////////
  411. INLINE_LINMATH int FLOATNAME(LMatrix4)::
  412. get_num_components() const {
  413. return 16;
  414. }
  415. ////////////////////////////////////////////////////////////////////
  416. // Function: LMatrix4::begin
  417. // Access: Public
  418. // Description: Returns an iterator that may be used to traverse the
  419. // elements of the matrix, STL-style.
  420. ////////////////////////////////////////////////////////////////////
  421. INLINE_LINMATH FLOATNAME(LMatrix4)::iterator FLOATNAME(LMatrix4)::
  422. begin() {
  423. return _m.data;
  424. }
  425. ////////////////////////////////////////////////////////////////////
  426. // Function: LMatrix4::end
  427. // Access: Public
  428. // Description: Returns an iterator that may be used to traverse the
  429. // elements of the matrix, STL-style.
  430. ////////////////////////////////////////////////////////////////////
  431. INLINE_LINMATH FLOATNAME(LMatrix4)::iterator FLOATNAME(LMatrix4)::
  432. end() {
  433. return begin() + 16;
  434. }
  435. ////////////////////////////////////////////////////////////////////
  436. // Function: LMatrix4::begin
  437. // Access: Public
  438. // Description: Returns an iterator that may be used to traverse the
  439. // elements of the matrix, STL-style.
  440. ////////////////////////////////////////////////////////////////////
  441. INLINE_LINMATH FLOATNAME(LMatrix4)::const_iterator FLOATNAME(LMatrix4)::
  442. begin() const {
  443. return _m.data;
  444. }
  445. ////////////////////////////////////////////////////////////////////
  446. // Function: LMatrix4::end
  447. // Access: Public
  448. // Description: Returns an iterator that may be used to traverse the
  449. // elements of the matrix, STL-style.
  450. ////////////////////////////////////////////////////////////////////
  451. INLINE_LINMATH FLOATNAME(LMatrix4)::const_iterator FLOATNAME(LMatrix4)::
  452. end() const {
  453. return begin() + 16;
  454. }
  455. ////////////////////////////////////////////////////////////////////
  456. // Function: LMatrix4::Ordering Operator
  457. // Access: Public
  458. // Description: This performs a lexicographical comparison. It's of
  459. // questionable mathematical meaning, but sometimes has
  460. // a practical purpose for sorting unique vectors,
  461. // especially in an STL container. Also see
  462. // compare_to().
  463. ////////////////////////////////////////////////////////////////////
  464. INLINE_LINMATH bool FLOATNAME(LMatrix4)::
  465. operator < (const FLOATNAME(LMatrix4) &other) const {
  466. return compare_to(other) < 0;
  467. }
  468. ////////////////////////////////////////////////////////////////////
  469. // Function: LMatrix4::Equality Operator
  470. // Access: Public
  471. // Description:
  472. ////////////////////////////////////////////////////////////////////
  473. INLINE_LINMATH bool FLOATNAME(LMatrix4)::
  474. operator == (const FLOATNAME(LMatrix4) &other) const {
  475. return compare_to(other) == 0;
  476. }
  477. ////////////////////////////////////////////////////////////////////
  478. // Function: LMatrix4::Inequality Operator
  479. // Access: Public
  480. // Description:
  481. ////////////////////////////////////////////////////////////////////
  482. INLINE_LINMATH bool FLOATNAME(LMatrix4)::
  483. operator != (const FLOATNAME(LMatrix4) &other) const {
  484. return !operator == (other);
  485. }
  486. ////////////////////////////////////////////////////////////////////
  487. // Function: LMatrix4::compare_to
  488. // Access: Public
  489. // Description: This flavor of compare_to uses a default threshold
  490. // value based on the numeric type.
  491. ////////////////////////////////////////////////////////////////////
  492. INLINE_LINMATH int FLOATNAME(LMatrix4)::
  493. compare_to(const FLOATNAME(LMatrix4) &other) const {
  494. return compare_to(other, NEARLY_ZERO(FLOATTYPE));
  495. }
  496. #define VECTOR4_MATRIX4_PRODUCT(v_res, v, mat) \
  497. v_res._v.v._0 = v._v.v._0*mat._m.m._00 + v._v.v._1*mat._m.m._10 + v._v.v._2*mat._m.m._20 + v._v.v._3*mat._m.m._30; \
  498. v_res._v.v._1 = v._v.v._0*mat._m.m._01 + v._v.v._1*mat._m.m._11 + v._v.v._2*mat._m.m._21 + v._v.v._3*mat._m.m._31; \
  499. v_res._v.v._2 = v._v.v._0*mat._m.m._02 + v._v.v._1*mat._m.m._12 + v._v.v._2*mat._m.m._22 + v._v.v._3*mat._m.m._32; \
  500. v_res._v.v._3 = v._v.v._0*mat._m.m._03 + v._v.v._1*mat._m.m._13 + v._v.v._2*mat._m.m._23 + v._v.v._3*mat._m.m._33;
  501. ////////////////////////////////////////////////////////////////////
  502. // Function: LMatrix4::xform
  503. // Access: Public
  504. // Description: 4-component vector or point times matrix. This is a
  505. // fully general operation.
  506. ////////////////////////////////////////////////////////////////////
  507. INLINE_LINMATH FLOATNAME(LVecBase4) FLOATNAME(LMatrix4)::
  508. xform(const FLOATNAME(LVecBase4) &v) const {
  509. FLOATNAME(LVecBase4) v_res;
  510. VECTOR4_MATRIX4_PRODUCT(v_res, v,(*this));
  511. return v_res;
  512. /* return FLOATNAME(LVecBase4)(v.dot(get_col(0)),
  513. v.dot(get_col(1)),
  514. v.dot(get_col(2)),
  515. v.dot(get_col(3)));
  516. */
  517. }
  518. ////////////////////////////////////////////////////////////////////
  519. // Function: LMatrix4::xform_point
  520. // Access: Public
  521. // Description: The matrix transforms a 3-component point (including
  522. // translation component) and returns the result. This
  523. // assumes the matrix is an affine transform.
  524. ////////////////////////////////////////////////////////////////////
  525. INLINE_LINMATH FLOATNAME(LVecBase3) FLOATNAME(LMatrix4)::
  526. xform_point(const FLOATNAME(LVecBase3) &v) const {
  527. FLOATNAME(LVecBase3) v_res;
  528. // v._v.v._3 == 1.0f for this case
  529. v_res._v.v._0 = v._v.v._0*_m.m._00 + v._v.v._1*_m.m._10 + v._v.v._2*_m.m._20 + _m.m._30;
  530. v_res._v.v._1 = v._v.v._0*_m.m._01 + v._v.v._1*_m.m._11 + v._v.v._2*_m.m._21 + _m.m._31;
  531. v_res._v.v._2 = v._v.v._0*_m.m._02 + v._v.v._1*_m.m._12 + v._v.v._2*_m.m._22 + _m.m._32;
  532. return v_res;
  533. /*
  534. return FLOATNAME(LVecBase3)(v.dot(get_col3(0)) + _m.m._30,
  535. v.dot(get_col3(1)) + _m.m._31,
  536. v.dot(get_col3(2)) + _m.m._32);
  537. */
  538. }
  539. ////////////////////////////////////////////////////////////////////
  540. // Function: LMatrix4::xform_vec
  541. // Access: Public
  542. // Description: The matrix transforms a 3-component vector (without
  543. // translation component) and returns the result. This
  544. // assumes the matrix is an affine transform.
  545. ////////////////////////////////////////////////////////////////////
  546. INLINE_LINMATH FLOATNAME(LVecBase3) FLOATNAME(LMatrix4)::
  547. xform_vec(const FLOATNAME(LVecBase3) &v) const {
  548. FLOATNAME(LVecBase3) v_res;
  549. // v._v.v._3 == 0.0f for this case
  550. v_res._v.v._0 = v._v.v._0*_m.m._00 + v._v.v._1*_m.m._10 + v._v.v._2*_m.m._20;
  551. v_res._v.v._1 = v._v.v._0*_m.m._01 + v._v.v._1*_m.m._11 + v._v.v._2*_m.m._21;
  552. v_res._v.v._2 = v._v.v._0*_m.m._02 + v._v.v._1*_m.m._12 + v._v.v._2*_m.m._22;
  553. return v_res;
  554. /*
  555. return FLOATNAME(LVecBase3)(v.dot(get_col3(0)),
  556. v.dot(get_col3(1)),
  557. v.dot(get_col3(2)));
  558. */
  559. }
  560. ////////////////////////////////////////////////////////////////////
  561. // Function: LMatrix4::mult_cel
  562. // Access: Private
  563. // Description: Returns one cell of the result of a matrix-matrix
  564. // multiplication operation.
  565. ////////////////////////////////////////////////////////////////////
  566. INLINE_LINMATH FLOATTYPE FLOATNAME(LMatrix4)::
  567. mult_cel(const FLOATNAME(LMatrix4) &other, int row, int col) const {
  568. return get_row(row).dot(other.get_col(col));
  569. }
  570. #define MATRIX4_PRODUCT(res, a, b) \
  571. res._m.m._00 = a._m.m._00*b._m.m._00 + a._m.m._01*b._m.m._10 + a._m.m._02*b._m.m._20 + a._m.m._03*b._m.m._30; \
  572. res._m.m._01 = a._m.m._00*b._m.m._01 + a._m.m._01*b._m.m._11 + a._m.m._02*b._m.m._21 + a._m.m._03*b._m.m._31; \
  573. res._m.m._02 = a._m.m._00*b._m.m._02 + a._m.m._01*b._m.m._12 + a._m.m._02*b._m.m._22 + a._m.m._03*b._m.m._32; \
  574. res._m.m._03 = a._m.m._00*b._m.m._03 + a._m.m._01*b._m.m._13 + a._m.m._02*b._m.m._23 + a._m.m._03*b._m.m._33; \
  575. \
  576. res._m.m._10 = a._m.m._10*b._m.m._00 + a._m.m._11*b._m.m._10 + a._m.m._12*b._m.m._20 + a._m.m._13*b._m.m._30; \
  577. res._m.m._11 = a._m.m._10*b._m.m._01 + a._m.m._11*b._m.m._11 + a._m.m._12*b._m.m._21 + a._m.m._13*b._m.m._31; \
  578. res._m.m._12 = a._m.m._10*b._m.m._02 + a._m.m._11*b._m.m._12 + a._m.m._12*b._m.m._22 + a._m.m._13*b._m.m._32; \
  579. res._m.m._13 = a._m.m._10*b._m.m._03 + a._m.m._11*b._m.m._13 + a._m.m._12*b._m.m._23 + a._m.m._13*b._m.m._33; \
  580. \
  581. res._m.m._20 = a._m.m._20*b._m.m._00 + a._m.m._21*b._m.m._10 + a._m.m._22*b._m.m._20 + a._m.m._23*b._m.m._30; \
  582. res._m.m._21 = a._m.m._20*b._m.m._01 + a._m.m._21*b._m.m._11 + a._m.m._22*b._m.m._21 + a._m.m._23*b._m.m._31; \
  583. res._m.m._22 = a._m.m._20*b._m.m._02 + a._m.m._21*b._m.m._12 + a._m.m._22*b._m.m._22 + a._m.m._23*b._m.m._32; \
  584. res._m.m._23 = a._m.m._20*b._m.m._03 + a._m.m._21*b._m.m._13 + a._m.m._22*b._m.m._23 + a._m.m._23*b._m.m._33; \
  585. \
  586. res._m.m._30 = a._m.m._30*b._m.m._00 + a._m.m._31*b._m.m._10 + a._m.m._32*b._m.m._20 + a._m.m._33*b._m.m._30; \
  587. res._m.m._31 = a._m.m._30*b._m.m._01 + a._m.m._31*b._m.m._11 + a._m.m._32*b._m.m._21 + a._m.m._33*b._m.m._31; \
  588. res._m.m._32 = a._m.m._30*b._m.m._02 + a._m.m._31*b._m.m._12 + a._m.m._32*b._m.m._22 + a._m.m._33*b._m.m._32; \
  589. res._m.m._33 = a._m.m._30*b._m.m._03 + a._m.m._31*b._m.m._13 + a._m.m._32*b._m.m._23 + a._m.m._33*b._m.m._33;
  590. ////////////////////////////////////////////////////////////////////
  591. // Function: LMatrix4::matrix * matrix
  592. // Access: Public
  593. // Description:
  594. ////////////////////////////////////////////////////////////////////
  595. INLINE_LINMATH FLOATNAME(LMatrix4) FLOATNAME(LMatrix4)::
  596. operator * (const FLOATNAME(LMatrix4) &other) const {
  597. FLOATNAME(LMatrix4) t;
  598. MATRIX4_PRODUCT(t,(*this),other);
  599. /*
  600. typedef union {
  601. struct {
  602. FLOATTYPE _m.m._11, _m.m._12, _m.m._13, _m.m._14;
  603. FLOATTYPE _m.m._21, _m.m._22, _m.m._23, _m.m._24;
  604. FLOATTYPE _m.m._31, _m.m._32, _m.m._33, _m.m._34;
  605. FLOATTYPE _m.m._41, _m.m._42, _m.m._43, _m.m._44;
  606. };
  607. FLOATTYPE m[4][4];
  608. } MYMATRIX4;
  609. FLOATNAME(LMatrix4) t;
  610. MYMATRIX4 *result_ptr=(MYMATRIX4 *)t.get_m.data();
  611. MYMATRIX4 *mat1_ptr=(MYMATRIX4 *)this->get_m.data();
  612. MYMATRIX4 *mat2_ptr=(MYMATRIX4 *)other.get_m.data();
  613. MATRIX4_PRODUCT(result_ptr,mat1_ptr,mat2_ptr);
  614. */
  615. /*
  616. t(0, 0) = mult_cel(other, 0, 0);
  617. t(0, 1) = mult_cel(other, 0, 1);
  618. t(0, 2) = mult_cel(other, 0, 2);
  619. t(0, 3) = mult_cel(other, 0, 3);
  620. t(1, 0) = mult_cel(other, 1, 0);
  621. t(1, 1) = mult_cel(other, 1, 1);
  622. t(1, 2) = mult_cel(other, 1, 2);
  623. t(1, 3) = mult_cel(other, 1, 3);
  624. t(2, 0) = mult_cel(other, 2, 0);
  625. t(2, 1) = mult_cel(other, 2, 1);
  626. t(2, 2) = mult_cel(other, 2, 2);
  627. t(2, 3) = mult_cel(other, 2, 3);
  628. t(3, 0) = mult_cel(other, 3, 0);
  629. t(3, 1) = mult_cel(other, 3, 1);
  630. t(3, 2) = mult_cel(other, 3, 2);
  631. t(3, 3) = mult_cel(other, 3, 3);
  632. */
  633. return t;
  634. }
  635. // this = other1 * other2
  636. INLINE_LINMATH void FLOATNAME(LMatrix4)::
  637. multiply(const FLOATNAME(LMatrix4) &other1, const FLOATNAME(LMatrix4) &other2) {
  638. // faster than operator * since it writes result in place, avoiding extra copying
  639. // this will fail if you try to mat.multiply(mat,other_mat)
  640. #ifdef _DEBUG
  641. assert((&other1 != this) && (&other2 != this));
  642. #endif
  643. MATRIX4_PRODUCT((*this),other1,other2);
  644. }
  645. // this = scale_mat(scale_vector) * other_mat, efficiently
  646. INLINE_LINMATH void FLOATNAME(LMatrix4)::
  647. scale_multiply(const FLOATNAME(LVecBase3) &scale_vector,const FLOATNAME(LMatrix4) &other_mat) {
  648. #ifdef _DEBUG
  649. assert(&other_mat != this);
  650. #endif
  651. // optimize for 0.0 or 1.0 factors?
  652. _m.m._00 = other_mat._m.m._00 * scale_vector._v.v._0;
  653. _m.m._01 = other_mat._m.m._01 * scale_vector._v.v._0;
  654. _m.m._02 = other_mat._m.m._02 * scale_vector._v.v._0;
  655. _m.m._03 = other_mat._m.m._03 * scale_vector._v.v._0;
  656. _m.m._10 = other_mat._m.m._10 * scale_vector._v.v._1;
  657. _m.m._11 = other_mat._m.m._11 * scale_vector._v.v._1;
  658. _m.m._12 = other_mat._m.m._12 * scale_vector._v.v._1;
  659. _m.m._13 = other_mat._m.m._13 * scale_vector._v.v._1;
  660. _m.m._20 = other_mat._m.m._20 * scale_vector._v.v._2;
  661. _m.m._21 = other_mat._m.m._21 * scale_vector._v.v._2;
  662. _m.m._22 = other_mat._m.m._22 * scale_vector._v.v._2;
  663. _m.m._23 = other_mat._m.m._23 * scale_vector._v.v._2;
  664. }
  665. ////////////////////////////////////////////////////////////////////
  666. // Function: LMatrix4::matrix * scalar
  667. // Access: Public
  668. // Description:
  669. ////////////////////////////////////////////////////////////////////
  670. INLINE_LINMATH FLOATNAME(LMatrix4) FLOATNAME(LMatrix4)::
  671. operator * (FLOATTYPE scalar) const {
  672. FLOATNAME(LMatrix4) t;
  673. t._m.m._00 = _m.m._00 * scalar;
  674. t._m.m._01 = _m.m._01 * scalar;
  675. t._m.m._02 = _m.m._02 * scalar;
  676. t._m.m._03 = _m.m._03 * scalar;
  677. t._m.m._10 = _m.m._10 * scalar;
  678. t._m.m._11 = _m.m._11 * scalar;
  679. t._m.m._12 = _m.m._12 * scalar;
  680. t._m.m._13 = _m.m._13 * scalar;
  681. t._m.m._20 = _m.m._20 * scalar;
  682. t._m.m._21 = _m.m._21 * scalar;
  683. t._m.m._22 = _m.m._22 * scalar;
  684. t._m.m._23 = _m.m._23 * scalar;
  685. t._m.m._30 = _m.m._30 * scalar;
  686. t._m.m._31 = _m.m._31 * scalar;
  687. t._m.m._32 = _m.m._32 * scalar;
  688. t._m.m._33 = _m.m._33 * scalar;
  689. return t;
  690. }
  691. ////////////////////////////////////////////////////////////////////
  692. // Function: LMatrix4::matrix / scalar
  693. // Access: Public
  694. // Description:
  695. ////////////////////////////////////////////////////////////////////
  696. INLINE_LINMATH FLOATNAME(LMatrix4) FLOATNAME(LMatrix4)::
  697. operator / (FLOATTYPE scalar) const {
  698. FLOATNAME(LMatrix4) t;
  699. FLOATTYPE recip_scalar = 1.0f/scalar;
  700. t._m.m._00 = _m.m._00 * recip_scalar;
  701. t._m.m._01 = _m.m._01 * recip_scalar;
  702. t._m.m._02 = _m.m._02 * recip_scalar;
  703. t._m.m._03 = _m.m._03 * recip_scalar;
  704. t._m.m._10 = _m.m._10 * recip_scalar;
  705. t._m.m._11 = _m.m._11 * recip_scalar;
  706. t._m.m._12 = _m.m._12 * recip_scalar;
  707. t._m.m._13 = _m.m._13 * recip_scalar;
  708. t._m.m._20 = _m.m._20 * recip_scalar;
  709. t._m.m._21 = _m.m._21 * recip_scalar;
  710. t._m.m._22 = _m.m._22 * recip_scalar;
  711. t._m.m._23 = _m.m._23 * recip_scalar;
  712. t._m.m._30 = _m.m._30 * recip_scalar;
  713. t._m.m._31 = _m.m._31 * recip_scalar;
  714. t._m.m._32 = _m.m._32 * recip_scalar;
  715. t._m.m._33 = _m.m._33 * recip_scalar;
  716. return t;
  717. }
  718. ////////////////////////////////////////////////////////////////////
  719. // Function: LMatrix4::matrix += matrix
  720. // Access: Public
  721. // Description: Performs a memberwise addition between two matrices.
  722. ////////////////////////////////////////////////////////////////////
  723. INLINE_LINMATH FLOATNAME(LMatrix4) &FLOATNAME(LMatrix4)::
  724. operator += (const FLOATNAME(LMatrix4) &other) {
  725. _m.m._00 += other._m.m._00;
  726. _m.m._01 += other._m.m._01;
  727. _m.m._02 += other._m.m._02;
  728. _m.m._03 += other._m.m._03;
  729. _m.m._10 += other._m.m._10;
  730. _m.m._11 += other._m.m._11;
  731. _m.m._12 += other._m.m._12;
  732. _m.m._13 += other._m.m._13;
  733. _m.m._20 += other._m.m._20;
  734. _m.m._21 += other._m.m._21;
  735. _m.m._22 += other._m.m._22;
  736. _m.m._23 += other._m.m._23;
  737. _m.m._30 += other._m.m._30;
  738. _m.m._31 += other._m.m._31;
  739. _m.m._32 += other._m.m._32;
  740. _m.m._33 += other._m.m._33;
  741. return *this;
  742. }
  743. ////////////////////////////////////////////////////////////////////
  744. // Function: LMatrix4::matrix -= matrix
  745. // Access: Public
  746. // Description: Performs a memberwise addition between two matrices.
  747. ////////////////////////////////////////////////////////////////////
  748. INLINE_LINMATH FLOATNAME(LMatrix4) &FLOATNAME(LMatrix4)::
  749. operator -= (const FLOATNAME(LMatrix4) &other) {
  750. _m.m._00 -= other._m.m._00;
  751. _m.m._01 -= other._m.m._01;
  752. _m.m._02 -= other._m.m._02;
  753. _m.m._03 -= other._m.m._03;
  754. _m.m._10 -= other._m.m._10;
  755. _m.m._11 -= other._m.m._11;
  756. _m.m._12 -= other._m.m._12;
  757. _m.m._13 -= other._m.m._13;
  758. _m.m._20 -= other._m.m._20;
  759. _m.m._21 -= other._m.m._21;
  760. _m.m._22 -= other._m.m._22;
  761. _m.m._23 -= other._m.m._23;
  762. _m.m._30 -= other._m.m._30;
  763. _m.m._31 -= other._m.m._31;
  764. _m.m._32 -= other._m.m._32;
  765. _m.m._33 -= other._m.m._33;
  766. return *this;
  767. }
  768. ////////////////////////////////////////////////////////////////////
  769. // Function: LMatrix4::matrix *= matrix
  770. // Access: Public
  771. // Description:
  772. ////////////////////////////////////////////////////////////////////
  773. INLINE_LINMATH FLOATNAME(LMatrix4) &FLOATNAME(LMatrix4)::
  774. operator *= (const FLOATNAME(LMatrix4) &other) {
  775. (*this) = (*this) * other;
  776. return *this;
  777. }
  778. ////////////////////////////////////////////////////////////////////
  779. // Function: LMatrix4::matrix *= scalar
  780. // Access: Public
  781. // Description:
  782. ////////////////////////////////////////////////////////////////////
  783. INLINE_LINMATH FLOATNAME(LMatrix4) &FLOATNAME(LMatrix4)::
  784. operator *= (FLOATTYPE scalar) {
  785. _m.m._00 *= scalar;
  786. _m.m._01 *= scalar;
  787. _m.m._02 *= scalar;
  788. _m.m._03 *= scalar;
  789. _m.m._10 *= scalar;
  790. _m.m._11 *= scalar;
  791. _m.m._12 *= scalar;
  792. _m.m._13 *= scalar;
  793. _m.m._20 *= scalar;
  794. _m.m._21 *= scalar;
  795. _m.m._22 *= scalar;
  796. _m.m._23 *= scalar;
  797. _m.m._30 *= scalar;
  798. _m.m._31 *= scalar;
  799. _m.m._32 *= scalar;
  800. _m.m._33 *= scalar;
  801. return *this;
  802. }
  803. ////////////////////////////////////////////////////////////////////
  804. // Function: LMatrix4::matrix /= scalar
  805. // Access: Public
  806. // Description:
  807. ////////////////////////////////////////////////////////////////////
  808. INLINE_LINMATH FLOATNAME(LMatrix4) &FLOATNAME(LMatrix4)::
  809. operator /= (FLOATTYPE scalar) {
  810. FLOATTYPE recip_scalar = 1.0f/scalar;
  811. _m.m._00 *= recip_scalar;
  812. _m.m._01 *= recip_scalar;
  813. _m.m._02 *= recip_scalar;
  814. _m.m._03 *= recip_scalar;
  815. _m.m._10 *= recip_scalar;
  816. _m.m._11 *= recip_scalar;
  817. _m.m._12 *= recip_scalar;
  818. _m.m._13 *= recip_scalar;
  819. _m.m._20 *= recip_scalar;
  820. _m.m._21 *= recip_scalar;
  821. _m.m._22 *= recip_scalar;
  822. _m.m._23 *= recip_scalar;
  823. _m.m._30 *= recip_scalar;
  824. _m.m._31 *= recip_scalar;
  825. _m.m._32 *= recip_scalar;
  826. _m.m._33 *= recip_scalar;
  827. return *this;
  828. }
  829. ////////////////////////////////////////////////////////////////////
  830. // Function: LMatrix4::transpose_from
  831. // Access: Public
  832. // Description:
  833. ////////////////////////////////////////////////////////////////////
  834. INLINE_LINMATH void FLOATNAME(LMatrix4)::
  835. transpose_from(const FLOATNAME(LMatrix4) &other) {
  836. _m.m._00 = other._m.m._00;
  837. _m.m._01 = other._m.m._10;
  838. _m.m._02 = other._m.m._20;
  839. _m.m._03 = other._m.m._30;
  840. _m.m._10 = other._m.m._01;
  841. _m.m._11 = other._m.m._11;
  842. _m.m._12 = other._m.m._21;
  843. _m.m._13 = other._m.m._31;
  844. _m.m._20 = other._m.m._02;
  845. _m.m._21 = other._m.m._12;
  846. _m.m._22 = other._m.m._22;
  847. _m.m._23 = other._m.m._32;
  848. _m.m._30 = other._m.m._03;
  849. _m.m._31 = other._m.m._13;
  850. _m.m._32 = other._m.m._23;
  851. _m.m._33 = other._m.m._33;
  852. }
  853. ////////////////////////////////////////////////////////////////////
  854. // Function: LMatrix4::transpose_in_place
  855. // Access: Public
  856. // Description:
  857. ////////////////////////////////////////////////////////////////////
  858. INLINE_LINMATH void FLOATNAME(LMatrix4)::
  859. transpose_in_place() {
  860. // FLOATNAME(LMatrix4) temp = (*this);
  861. // transpose_from(temp);
  862. #define SWAP__(x,y) { FLOATTYPE temp = (x); (x) = (y); (y) = temp;}
  863. SWAP__(_m.m._01,_m.m._10);
  864. SWAP__(_m.m._02,_m.m._20);
  865. SWAP__(_m.m._03,_m.m._30);
  866. SWAP__(_m.m._12,_m.m._21);
  867. SWAP__(_m.m._13,_m.m._31);
  868. SWAP__(_m.m._23,_m.m._32);
  869. #undef SWAP__
  870. }
  871. ////////////////////////////////////////////////////////////////////
  872. // Function: LMatrix4::invert_from
  873. // Access: Public
  874. // Description: Computes the inverse of the other matrix, and stores
  875. // the result in this matrix. This is a fully general
  876. // operation and makes no assumptions about the type of
  877. // transform represented by the matrix.
  878. //
  879. // The other matrix must be a different object than this
  880. // matrix. However, if you need to invert a matrix in
  881. // place, see invert_in_place.
  882. //
  883. // The return value is true if the matrix was
  884. // successfully inverted, false if the was a
  885. // singularity.
  886. ////////////////////////////////////////////////////////////////////
  887. // bugbug: we could optimize this for rotation/scale/translation matrices
  888. // (transpose upper 3x3 and take negative of translation component)
  889. INLINE_LINMATH bool FLOATNAME(LMatrix4)::
  890. invert_from(const FLOATNAME(LMatrix4) &other) {
  891. if (IS_NEARLY_EQUAL(other._m.m._30, 0.0f) &&
  892. IS_NEARLY_EQUAL(other._m.m._31, 0.0f) &&
  893. IS_NEARLY_EQUAL(other._m.m._32, 0.0f) &&
  894. IS_NEARLY_EQUAL(other._m.m._33, 1.0f)) {
  895. return invert_affine_from(other);
  896. }
  897. (*this) = other;
  898. int index[4];
  899. if (!decompose_mat(index)) {
  900. #ifdef NDEBUG
  901. linmath_cat.warning() << "Tried to invert singular LMatrix4.\n";
  902. #endif
  903. return false;
  904. }
  905. FLOATNAME(LMatrix4) inv = FLOATNAME(LMatrix4)::ident_mat();
  906. int row;
  907. for (row = 0; row < 4; row++) {
  908. back_sub_mat(index, inv, row);
  909. }
  910. transpose_from(inv);
  911. return true;
  912. }
  913. ////////////////////////////////////////////////////////////////////
  914. // Function: LMatrix4::invert_affine_from
  915. // Access: Public
  916. // Description: Performs an invert of the indicated matrix, storing
  917. // the result in this matrix. The calculation is only
  918. // correct of the other matrix represents an affine
  919. // transform.
  920. //
  921. // The other matrix must be a different object than this
  922. // matrix. However, if you need to invert a matrix in
  923. // place, see invert_in_place.
  924. //
  925. // The return value is true if the matrix was
  926. // successfully inverted, false if the was a
  927. // singularity.
  928. ////////////////////////////////////////////////////////////////////
  929. // bugbug: we could optimize this for rotation/scale/translation matrices
  930. // (transpose upper 3x3 and take negative of translation component)
  931. INLINE_LINMATH bool FLOATNAME(LMatrix4)::
  932. invert_affine_from(const FLOATNAME(LMatrix4) &other) {
  933. FLOATNAME(LMatrix3) rot;
  934. // probably could use transpose here
  935. if (!rot.invert_from(other.get_upper_3())) {
  936. return false;
  937. }
  938. set_upper_3(rot);
  939. // set_col(3, FLOATNAME(LVecBase4)(0.0f, 0.0f, 0.0f, 1.0f));
  940. _m.m._03 = 0.0f;
  941. _m.m._13 = 0.0f;
  942. _m.m._23 = 0.0f;
  943. _m.m._33 = 1.0f;
  944. // compute -C*inv(A)
  945. /*
  946. for (int i = 0; i < 3; i++) {
  947. (*this)(3, i) = 0.0f;
  948. for (int j = 0; j < 3; j++) {
  949. (*this)(3, i) -= other(3, j) * (*this)(j, i);
  950. }
  951. }
  952. */
  953. _m.m._30 = -(other._m.m._30 * _m.m._00 +
  954. other._m.m._31 * _m.m._10 +
  955. other._m.m._32 * _m.m._20);
  956. _m.m._31 = -(other._m.m._30 * _m.m._01 +
  957. other._m.m._31 * _m.m._11 +
  958. other._m.m._32 * _m.m._21);
  959. _m.m._32 = -(other._m.m._30 * _m.m._02 +
  960. other._m.m._31 * _m.m._12 +
  961. other._m.m._32 * _m.m._22);
  962. return true;
  963. }
  964. ////////////////////////////////////////////////////////////////////
  965. // Function: LMatrix4::invert_in_place
  966. // Access: Public
  967. // Description: Inverts the current matrix. Returns true if the
  968. // inverse is successful, false if the matrix was
  969. // singular.
  970. ////////////////////////////////////////////////////////////////////
  971. INLINE_LINMATH bool FLOATNAME(LMatrix4)::
  972. invert_in_place() {
  973. FLOATNAME(LMatrix4) temp = (*this);
  974. return invert_from(temp);
  975. }
  976. ////////////////////////////////////////////////////////////////////
  977. // Function: LMatrix::translate_mat
  978. // Access: Public, Static
  979. // Description: Returns a matrix that applies the indicated
  980. // translation.
  981. ////////////////////////////////////////////////////////////////////
  982. INLINE_LINMATH FLOATNAME(LMatrix4) FLOATNAME(LMatrix4)::
  983. translate_mat(const FLOATNAME(LVecBase3) &trans) {
  984. return FLOATNAME(LMatrix4)(1.0f, 0.0f, 0.0f, 0.0f,
  985. 0.0f, 1.0f, 0.0f, 0.0f,
  986. 0.0f, 0.0f, 1.0f, 0.0f,
  987. trans._v.v._0, trans._v.v._1, trans._v.v._2, 1.0f);
  988. }
  989. ////////////////////////////////////////////////////////////////////
  990. // Function: LMatrix::translate_mat
  991. // Access: Public, Static
  992. // Description: Returns a matrix that applies the indicated
  993. // translation.
  994. ////////////////////////////////////////////////////////////////////
  995. INLINE_LINMATH FLOATNAME(LMatrix4) FLOATNAME(LMatrix4)::
  996. translate_mat(FLOATTYPE tx, FLOATTYPE ty, FLOATTYPE tz) {
  997. return FLOATNAME(LMatrix4)(1.0f, 0.0f, 0.0f, 0.0f,
  998. 0.0f, 1.0f, 0.0f, 0.0f,
  999. 0.0f, 0.0f, 1.0f, 0.0f,
  1000. tx, ty, tz, 1.0f);
  1001. }
  1002. ////////////////////////////////////////////////////////////////////
  1003. // Function: LMatrix::rotate_mat
  1004. // Access: Public, Static
  1005. // Description: Returns a matrix that rotates by the given angle in
  1006. // degrees counterclockwise about the indicated vector.
  1007. ////////////////////////////////////////////////////////////////////
  1008. INLINE_LINMATH FLOATNAME(LMatrix4) FLOATNAME(LMatrix4)::
  1009. rotate_mat(FLOATTYPE angle, FLOATNAME(LVecBase3) axis,
  1010. CoordinateSystem cs) {
  1011. if (cs == CS_default) {
  1012. cs = default_coordinate_system;
  1013. }
  1014. FLOATNAME(LMatrix4) mat;
  1015. if(IS_LEFT_HANDED_COORDSYSTEM(cs)) {
  1016. // In a left-handed coordinate system, counterclockwise is the
  1017. // other direction.
  1018. angle = -angle;
  1019. }
  1020. FLOATTYPE axis_0 = axis._v.v._0;
  1021. FLOATTYPE axis_1 = axis._v.v._1;
  1022. FLOATTYPE axis_2 = axis._v.v._2;
  1023. // Normalize the axis.
  1024. /*
  1025. // hack check for prenormalization, only works for simple unit vecs,
  1026. // which is what we usually pass in anyway. screws up if you happen to
  1027. // pass in something like (.5,.5,0). need to add flag parameter so caller
  1028. // can request normalization if needed
  1029. if((cabs(axis_0)+cabs(axis_1)+cabs(axis_2)) != 1.0f) {
  1030. */
  1031. FLOATTYPE length_sq = axis_0 * axis_0 + axis_1 * axis_1 + axis_2 * axis_2;
  1032. #ifdef _DEBUG
  1033. nassertr(length_sq != 0.0f, ident_mat());
  1034. #endif
  1035. FLOATTYPE recip_length = 1.0f/csqrt(length_sq);
  1036. axis_0 *= recip_length;
  1037. axis_1 *= recip_length;
  1038. axis_2 *= recip_length;
  1039. // }
  1040. FLOATTYPE angle_rad=deg_2_rad(angle);
  1041. FLOATTYPE s,c;
  1042. csincos(angle_rad,&s,&c);
  1043. FLOATTYPE t = 1.0f - c;
  1044. FLOATTYPE t0,t1,t2,s0,s1,s2;
  1045. t0 = t * axis_0;
  1046. t1 = t * axis_1;
  1047. t2 = t * axis_2;
  1048. s0 = s * axis_0;
  1049. s1 = s * axis_1;
  1050. s2 = s * axis_2;
  1051. mat._m.m._00 = t0 * axis_0 + c;
  1052. mat._m.m._01 = t0 * axis_1 + s2;
  1053. mat._m.m._02 = t0 * axis_2 - s1;
  1054. mat._m.m._10 = t1 * axis_0 - s2;
  1055. mat._m.m._11 = t1 * axis_1 + c;
  1056. mat._m.m._12 = t1 * axis_2 + s0;
  1057. mat._m.m._20 = t2 * axis_0 + s1;
  1058. mat._m.m._21 = t2 * axis_1 - s0;
  1059. mat._m.m._22 = t2 * axis_2 + c;
  1060. mat._m.m._03 = 0.0f;
  1061. mat._m.m._13 = 0.0f;
  1062. mat._m.m._23 = 0.0f;
  1063. mat._m.m._30 = 0.0f;
  1064. mat._m.m._31 = 0.0f;
  1065. mat._m.m._32 = 0.0f;
  1066. mat._m.m._33 = 1.0f;
  1067. return mat;
  1068. }
  1069. ////////////////////////////////////////////////////////////////////
  1070. // Function: LMatrix::rotate_mat_normaxis
  1071. // Access: Public, Static
  1072. // Description: Returns a matrix that rotates by the given angle in
  1073. // degrees counterclockwise about the indicated vector.
  1074. // Assumes axis has been prenormalized.
  1075. ////////////////////////////////////////////////////////////////////
  1076. INLINE_LINMATH FLOATNAME(LMatrix4) FLOATNAME(LMatrix4)::
  1077. rotate_mat_normaxis(FLOATTYPE angle, const FLOATNAME(LVecBase3) &axis,
  1078. CoordinateSystem cs) {
  1079. FLOATNAME(LMatrix4) mat;
  1080. rotate_mat_normaxis(angle,axis,mat,cs);
  1081. return mat;
  1082. }
  1083. INLINE_LINMATH void FLOATNAME(LMatrix4)::
  1084. rotate_mat_normaxis(FLOATTYPE angle, const FLOATNAME(LVecBase3) &axis,
  1085. FLOATNAME(LMatrix4) &result_mat, CoordinateSystem cs) {
  1086. if (cs == CS_default) {
  1087. cs = default_coordinate_system;
  1088. }
  1089. if(IS_LEFT_HANDED_COORDSYSTEM(cs)) {
  1090. // In a left-handed coordinate system, counterclockwise is the
  1091. // other direction.
  1092. angle = -angle;
  1093. }
  1094. FLOATTYPE axis_0 = axis._v.v._0;
  1095. FLOATTYPE axis_1 = axis._v.v._1;
  1096. FLOATTYPE axis_2 = axis._v.v._2;
  1097. FLOATTYPE angle_rad=deg_2_rad(angle);
  1098. FLOATTYPE s,c;
  1099. csincos(angle_rad,&s,&c);
  1100. FLOATTYPE t = 1.0f - c;
  1101. FLOATTYPE t0,t1,t2,s0,s1,s2;
  1102. t0 = t * axis_0;
  1103. t1 = t * axis_1;
  1104. t2 = t * axis_2;
  1105. s0 = s * axis_0;
  1106. s1 = s * axis_1;
  1107. s2 = s * axis_2;
  1108. result_mat._m.m._00 = t0 * axis_0 + c;
  1109. result_mat._m.m._01 = t0 * axis_1 + s2;
  1110. result_mat._m.m._02 = t0 * axis_2 - s1;
  1111. result_mat._m.m._10 = t1 * axis_0 - s2;
  1112. result_mat._m.m._11 = t1 * axis_1 + c;
  1113. result_mat._m.m._12 = t1 * axis_2 + s0;
  1114. result_mat._m.m._20 = t2 * axis_0 + s1;
  1115. result_mat._m.m._21 = t2 * axis_1 - s0;
  1116. result_mat._m.m._22 = t2 * axis_2 + c;
  1117. result_mat._m.m._03 = 0.0f;
  1118. result_mat._m.m._13 = 0.0f;
  1119. result_mat._m.m._23 = 0.0f;
  1120. result_mat._m.m._30 = 0.0f;
  1121. result_mat._m.m._31 = 0.0f;
  1122. result_mat._m.m._32 = 0.0f;
  1123. result_mat._m.m._33 = 1.0f;
  1124. }
  1125. ////////////////////////////////////////////////////////////////////
  1126. // Function: LMatrix::scale_mat
  1127. // Access: Public, Static
  1128. // Description: Returns a matrix that applies the indicated
  1129. // scale in each of the three axes.
  1130. ////////////////////////////////////////////////////////////////////
  1131. INLINE_LINMATH FLOATNAME(LMatrix4) FLOATNAME(LMatrix4)::
  1132. scale_mat(const FLOATNAME(LVecBase3) &scale) {
  1133. return FLOATNAME(LMatrix4)(scale._v.v._0, 0.0f, 0.0f, 0.0f,
  1134. 0.0f, scale._v.v._1, 0.0f, 0.0f,
  1135. 0.0f, 0.0f, scale._v.v._2, 0.0f,
  1136. 0.0f, 0.0f, 0.0f, 1.0f);
  1137. }
  1138. ////////////////////////////////////////////////////////////////////
  1139. // Function: LMatrix::scale_mat
  1140. // Access: Public, Static
  1141. // Description: Returns a matrix that applies the indicated
  1142. // scale in each of the three axes.
  1143. ////////////////////////////////////////////////////////////////////
  1144. INLINE_LINMATH FLOATNAME(LMatrix4) FLOATNAME(LMatrix4)::
  1145. scale_mat(FLOATTYPE sx, FLOATTYPE sy, FLOATTYPE sz) {
  1146. return FLOATNAME(LMatrix4)(
  1147. sx, 0.0f, 0.0f, 0.0f,
  1148. 0.0f, sy, 0.0f, 0.0f,
  1149. 0.0f, 0.0f, sz, 0.0f,
  1150. 0.0f, 0.0f, 0.0f, 1.0f);
  1151. }
  1152. ////////////////////////////////////////////////////////////////////
  1153. // Function: LMatrix::scale_mat
  1154. // Access: Public, Static
  1155. // Description: Returns a matrix that applies the indicated
  1156. // uniform scale.
  1157. ////////////////////////////////////////////////////////////////////
  1158. INLINE_LINMATH FLOATNAME(LMatrix4) FLOATNAME(LMatrix4)::
  1159. scale_mat(FLOATTYPE scale) {
  1160. return FLOATNAME(LMatrix4)(
  1161. scale, 0.0f, 0.0f, 0.0f,
  1162. 0.0f, scale, 0.0f, 0.0f,
  1163. 0.0f, 0.0f, scale, 0.0f,
  1164. 0.0f, 0.0f, 0.0f, 1.0f);
  1165. }
  1166. ////////////////////////////////////////////////////////////////////
  1167. // Function: LMatrix::y_to_z_up_mat
  1168. // Access: Public, Static
  1169. // Description: Returns a matrix that transforms from the Y-up
  1170. // coordinate system to the Z-up coordinate system.
  1171. ////////////////////////////////////////////////////////////////////
  1172. INLINE_LINMATH const FLOATNAME(LMatrix4) &FLOATNAME(LMatrix4)::
  1173. y_to_z_up_mat() {
  1174. return _y_to_z_up_mat;
  1175. }
  1176. ////////////////////////////////////////////////////////////////////
  1177. // Function: LMatrix::z_to_y_up_mat
  1178. // Access: Public, Static
  1179. // Description: Returns a matrix that transforms from the Y-up
  1180. // coordinate system to the Z-up coordinate system.
  1181. ////////////////////////////////////////////////////////////////////
  1182. INLINE_LINMATH const FLOATNAME(LMatrix4) &FLOATNAME(LMatrix4)::
  1183. z_to_y_up_mat() {
  1184. return _z_to_y_up_mat;
  1185. }
  1186. ////////////////////////////////////////////////////////////////////
  1187. // Function: LMatrix4::almost_equal
  1188. // Access: Public
  1189. // Description: Returns true if two matrices are memberwise equal
  1190. // within a default tolerance based on the numeric type.
  1191. ////////////////////////////////////////////////////////////////////
  1192. INLINE_LINMATH bool FLOATNAME(LMatrix4)::
  1193. almost_equal(const FLOATNAME(LMatrix4) &other) const {
  1194. return almost_equal(other, NEARLY_ZERO(FLOATTYPE));
  1195. }
  1196. ////////////////////////////////////////////////////////////////////
  1197. // Function: LMatrix4::generate_hash
  1198. // Access: Public
  1199. // Description: Adds the vector to the indicated hash generator.
  1200. ////////////////////////////////////////////////////////////////////
  1201. INLINE_LINMATH void FLOATNAME(LMatrix4)::
  1202. generate_hash(ChecksumHashGenerator &hashgen) const {
  1203. generate_hash(hashgen, NEARLY_ZERO(FLOATTYPE));
  1204. }
  1205. ////////////////////////////////////////////////////////////////////
  1206. // Function: transpose
  1207. // Description: Transposes the given matrix and returns it.
  1208. ////////////////////////////////////////////////////////////////////
  1209. INLINE_LINMATH FLOATNAME(LMatrix4)
  1210. transpose(const FLOATNAME(LMatrix4) &a) {
  1211. FLOATNAME(LMatrix4) result;
  1212. result.transpose_from(a);
  1213. return result;
  1214. }
  1215. ////////////////////////////////////////////////////////////////////
  1216. // Function: invert
  1217. // Description: Inverts the given matrix and returns it.
  1218. ////////////////////////////////////////////////////////////////////
  1219. INLINE_LINMATH FLOATNAME(LMatrix4)
  1220. invert(const FLOATNAME(LMatrix4) &a) {
  1221. FLOATNAME(LMatrix4) result;
  1222. bool nonsingular = result.invert_from(a);
  1223. nassertr(nonsingular, FLOATNAME(LMatrix4)::ident_mat());
  1224. return result;
  1225. }