lmatrix3_src.I 40 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141
  1. // Filename: lmatrix3_src.I
  2. // Created by: drose (29Jan99)
  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: LMatrix3::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(LMatrix3) &FLOATNAME(LMatrix3)::
  27. ident_mat() {
  28. return _ident_mat;
  29. }
  30. ////////////////////////////////////////////////////////////////////
  31. // Function: LMatrix3::Default Constructor
  32. // Access: Public
  33. // Description:
  34. ////////////////////////////////////////////////////////////////////
  35. INLINE_LINMATH FLOATNAME(LMatrix3)::
  36. FLOATNAME(LMatrix3)() {
  37. }
  38. ////////////////////////////////////////////////////////////////////
  39. // Function: LMatrix3::Copy Constructor
  40. // Access: Public
  41. // Description:
  42. ////////////////////////////////////////////////////////////////////
  43. INLINE_LINMATH FLOATNAME(LMatrix3)::
  44. FLOATNAME(LMatrix3)(const FLOATNAME(LMatrix3) &copy) {
  45. memcpy(_m.data,copy._m.data,sizeof(_m.data));
  46. // (*this) = copy;
  47. }
  48. ////////////////////////////////////////////////////////////////////
  49. // Function: LMatrix3::Copy Assignment Operator
  50. // Access: Public
  51. // Description:
  52. ////////////////////////////////////////////////////////////////////
  53. INLINE_LINMATH FLOATNAME(LMatrix3) &FLOATNAME(LMatrix3)::
  54. operator = (const FLOATNAME(LMatrix3) &copy) {
  55. memcpy(_m.data,copy._m.data,sizeof(_m.data));
  56. // set(copy(0, 0), copy(0, 1), copy(0, 2),
  57. // copy(1, 0), copy(1, 1), copy(1, 2),
  58. // copy(2, 0), copy(2, 1), copy(2, 2));
  59. return *this;
  60. }
  61. ////////////////////////////////////////////////////////////////////
  62. // Function: LMatrix3::Fill Assignment Operator
  63. // Access: Public
  64. // Description:
  65. ////////////////////////////////////////////////////////////////////
  66. INLINE_LINMATH FLOATNAME(LMatrix3) &FLOATNAME(LMatrix3)::
  67. operator = (FLOATTYPE fill_value) {
  68. fill(fill_value);
  69. return *this;
  70. }
  71. ////////////////////////////////////////////////////////////////////
  72. // Function: LMatrix3::Constructor
  73. // Access: Public
  74. // Description:
  75. ////////////////////////////////////////////////////////////////////
  76. INLINE_LINMATH FLOATNAME(LMatrix3)::
  77. FLOATNAME(LMatrix3)(FLOATTYPE e00, FLOATTYPE e01, FLOATTYPE e02,
  78. FLOATTYPE e10, FLOATTYPE e11, FLOATTYPE e12,
  79. FLOATTYPE e20, FLOATTYPE e21, FLOATTYPE e22) {
  80. _m.m._00 = e00;
  81. _m.m._01 = e01;
  82. _m.m._02 = e02;
  83. _m.m._10 = e10;
  84. _m.m._11 = e11;
  85. _m.m._12 = e12;
  86. _m.m._20 = e20;
  87. _m.m._21 = e21;
  88. _m.m._22 = e22;
  89. // set(e00, e01, e02,
  90. // e10, e11, e12,
  91. // e20, e21, e22);
  92. }
  93. ////////////////////////////////////////////////////////////////////
  94. // Function: LMatrix3::set
  95. // Access: Public
  96. // Description:
  97. ////////////////////////////////////////////////////////////////////
  98. INLINE_LINMATH void FLOATNAME(LMatrix3)::
  99. set(FLOATTYPE e00, FLOATTYPE e01, FLOATTYPE e02,
  100. FLOATTYPE e10, FLOATTYPE e11, FLOATTYPE e12,
  101. FLOATTYPE e20, FLOATTYPE e21, FLOATTYPE e22) {
  102. _m.m._00 = e00;
  103. _m.m._01 = e01;
  104. _m.m._02 = e02;
  105. _m.m._10 = e10;
  106. _m.m._11 = e11;
  107. _m.m._12 = e12;
  108. _m.m._20 = e20;
  109. _m.m._21 = e21;
  110. _m.m._22 = e22;
  111. /*
  112. _m.m._00 = e00;
  113. _m.m._01 = e01;
  114. _m.m._02 = e02;
  115. _m.m._10 = e10;
  116. _m.m._11 = e11;
  117. _m.m._12 = e12;
  118. _m.m._20 = e20;
  119. _m.m._21 = e21;
  120. _m.m._22 = e22;
  121. */
  122. }
  123. ////////////////////////////////////////////////////////////////////
  124. // Function: LMatrix3::set_row
  125. // Access: Public
  126. // Description: Replaces the indicated row of the matrix from a
  127. // three-component vector.
  128. ////////////////////////////////////////////////////////////////////
  129. INLINE_LINMATH void FLOATNAME(LMatrix3)::
  130. set_row(int row, const FLOATNAME(LVecBase3) &v) {
  131. (*this)(row, 0) = v._v.v._0;
  132. (*this)(row, 1) = v._v.v._1;
  133. (*this)(row, 2) = v._v.v._2;
  134. }
  135. ////////////////////////////////////////////////////////////////////
  136. // Function: LMatrix3::set_column
  137. // Access: Public
  138. // Description: Replaces the indicated column of the matrix from a
  139. // three-component vector.
  140. ////////////////////////////////////////////////////////////////////
  141. INLINE_LINMATH void FLOATNAME(LMatrix3)::
  142. set_col(int col, const FLOATNAME(LVecBase3) &v) {
  143. (*this)(0, col) = v._v.v._0;
  144. (*this)(1, col) = v._v.v._1;
  145. (*this)(2, col) = v._v.v._2;
  146. }
  147. ////////////////////////////////////////////////////////////////////
  148. // Function: LMatrix3::set_row
  149. // Access: Public
  150. // Description: Replaces the indicated row of the matrix from a
  151. // two-component vector, ignoring the last column.
  152. ////////////////////////////////////////////////////////////////////
  153. INLINE_LINMATH void FLOATNAME(LMatrix3)::
  154. set_row(int row, const FLOATNAME(LVecBase2) &v) {
  155. (*this)(row, 0) = v._v.v._0;
  156. (*this)(row, 1) = v._v.v._1;
  157. }
  158. ////////////////////////////////////////////////////////////////////
  159. // Function: LMatrix3::set_column
  160. // Access: Public
  161. // Description: Replaces the indicated column of the matrix from a
  162. // two-component vector, ignoring the last row.
  163. ////////////////////////////////////////////////////////////////////
  164. INLINE_LINMATH void FLOATNAME(LMatrix3)::
  165. set_col(int col, const FLOATNAME(LVecBase2) &v) {
  166. (*this)(0, col) = v._v.v._0;
  167. (*this)(1, col) = v._v.v._1;
  168. }
  169. ////////////////////////////////////////////////////////////////////
  170. // Function: LMatrix3::get_row
  171. // Access: Public
  172. // Description: Returns the indicated row of the matrix as a
  173. // three-component vector.
  174. ////////////////////////////////////////////////////////////////////
  175. INLINE_LINMATH FLOATNAME(LVecBase3) FLOATNAME(LMatrix3)::
  176. get_row(int row) const {
  177. return FLOATNAME(LVecBase3)((*this)(row, 0), (*this)(row, 1), (*this)(row, 2));
  178. }
  179. INLINE_LINMATH void FLOATNAME(LMatrix3)::
  180. get_row(FLOATNAME(LVecBase3) &result_vec,int row) const {
  181. result_vec._v.v._0 = (*this)(row, 0);
  182. result_vec._v.v._1 = (*this)(row, 1);
  183. result_vec._v.v._2 = (*this)(row, 2);
  184. }
  185. ////////////////////////////////////////////////////////////////////
  186. // Function: LMatrix3::get_col
  187. // Access: Public
  188. // Description: Returns the indicated column of the matrix as a
  189. // three-component vector.
  190. ////////////////////////////////////////////////////////////////////
  191. INLINE_LINMATH FLOATNAME(LVecBase3) FLOATNAME(LMatrix3)::
  192. get_col(int col) const {
  193. return FLOATNAME(LVecBase3)((*this)(0, col), (*this)(1, col), (*this)(2, col));
  194. }
  195. ////////////////////////////////////////////////////////////////////
  196. // Function: LMatrix3::get_row2
  197. // Access: Public
  198. // Description: Returns the indicated row of the matrix as a
  199. // two-component vector, ignoring the last column.
  200. ////////////////////////////////////////////////////////////////////
  201. INLINE_LINMATH FLOATNAME(LVecBase2) FLOATNAME(LMatrix3)::
  202. get_row2(int row) const {
  203. return FLOATNAME(LVecBase2)((*this)(row, 0), (*this)(row, 1));
  204. }
  205. ////////////////////////////////////////////////////////////////////
  206. // Function: LMatrix3::get_col2
  207. // Access: Public
  208. // Description: Returns the indicated column of the matrix as a
  209. // two-component vector, ignoring the last row.
  210. ////////////////////////////////////////////////////////////////////
  211. INLINE_LINMATH FLOATNAME(LVecBase2) FLOATNAME(LMatrix3)::
  212. get_col2(int col) const {
  213. return FLOATNAME(LVecBase2)((*this)(0, col), (*this)(1, col));
  214. }
  215. ////////////////////////////////////////////////////////////////////
  216. // Function: LMatrix3::Indexing operator
  217. // Access: Public
  218. // Description:
  219. ////////////////////////////////////////////////////////////////////
  220. INLINE_LINMATH FLOATTYPE &FLOATNAME(LMatrix3)::
  221. operator () (int row, int col) {
  222. nassertr(row >= 0 && row < 3 && col >= 0 && col < 3, _m.data[0]);
  223. return _m.data[row * 3 + col];
  224. }
  225. ////////////////////////////////////////////////////////////////////
  226. // Function: LMatrix3::Indexing operator
  227. // Access: Public
  228. // Description:
  229. ////////////////////////////////////////////////////////////////////
  230. INLINE_LINMATH FLOATTYPE FLOATNAME(LMatrix3)::
  231. operator () (int row, int col) const {
  232. nassertr(row >= 0 && row < 3 && col >= 0 && col < 3, 0.0);
  233. return _m.data[row * 3 + col];
  234. }
  235. ////////////////////////////////////////////////////////////////////
  236. // Function: LMatrix3::is_nan
  237. // Access: Public
  238. // Description: Returns true if any component of the matrix is
  239. // not-a-number, false otherwise.
  240. ////////////////////////////////////////////////////////////////////
  241. INLINE_LINMATH bool FLOATNAME(LMatrix3)::
  242. is_nan() const {
  243. return
  244. cnan(_m.data[0]) || cnan(_m.data[1]) || cnan(_m.data[2]) ||
  245. cnan(_m.data[3]) || cnan(_m.data[4]) || cnan(_m.data[5]) ||
  246. cnan(_m.data[6]) || cnan(_m.data[7]) || cnan(_m.data[8]);
  247. }
  248. ////////////////////////////////////////////////////////////////////
  249. // Function: LMatrix3::get_cell
  250. // Access: Public
  251. // Description: Returns a particular element of the matrix.
  252. ////////////////////////////////////////////////////////////////////
  253. INLINE_LINMATH FLOATTYPE FLOATNAME(LMatrix3)::
  254. get_cell(int row, int col) const {
  255. nassertr(row >= 0 && row < 3 && col >= 0 && col < 3, 0.0);
  256. return _m.data[row * 3 + col];
  257. }
  258. ////////////////////////////////////////////////////////////////////
  259. // Function: LMatrix3::set_cell
  260. // Access: Public
  261. // Description: Changes a particular element of the matrix.
  262. ////////////////////////////////////////////////////////////////////
  263. INLINE_LINMATH void FLOATNAME(LMatrix3)::
  264. set_cell(int row, int col, FLOATTYPE value) {
  265. nassertv(row >= 0 && row < 3 && col >= 0 && col < 3);
  266. _m.data[row * 3 + col] = value;
  267. }
  268. ////////////////////////////////////////////////////////////////////
  269. // Function: LMatrix3::get_data
  270. // Access: Public
  271. // Description: Returns the address of the first of the nine data
  272. // elements in the matrix. The remaining elements
  273. // occupy the next eight positions in row-major order.
  274. ////////////////////////////////////////////////////////////////////
  275. INLINE_LINMATH const FLOATTYPE *FLOATNAME(LMatrix3)::
  276. get_data() const {
  277. return _m.data;
  278. }
  279. ////////////////////////////////////////////////////////////////////
  280. // Function: LMatrix3::get_num_components
  281. // Access: Public
  282. // Description: Returns the number of elements in the matrix, nine.
  283. ////////////////////////////////////////////////////////////////////
  284. INLINE_LINMATH int FLOATNAME(LMatrix3)::
  285. get_num_components() const {
  286. return 9;
  287. }
  288. ////////////////////////////////////////////////////////////////////
  289. // Function: LMatrix3::begin
  290. // Access: Public
  291. // Description: Returns an iterator that may be used to traverse the
  292. // elements of the matrix, STL-style.
  293. ////////////////////////////////////////////////////////////////////
  294. INLINE_LINMATH FLOATNAME(LMatrix3)::iterator FLOATNAME(LMatrix3)::
  295. begin() {
  296. return _m.data;
  297. }
  298. ////////////////////////////////////////////////////////////////////
  299. // Function: LMatrix3::end
  300. // Access: Public
  301. // Description: Returns an iterator that may be used to traverse the
  302. // elements of the matrix, STL-style.
  303. ////////////////////////////////////////////////////////////////////
  304. INLINE_LINMATH FLOATNAME(LMatrix3)::iterator FLOATNAME(LMatrix3)::
  305. end() {
  306. return begin() + get_num_components();
  307. }
  308. ////////////////////////////////////////////////////////////////////
  309. // Function: LMatrix3::begin
  310. // Access: Public
  311. // Description: Returns an iterator that may be used to traverse the
  312. // elements of the matrix, STL-style.
  313. ////////////////////////////////////////////////////////////////////
  314. INLINE_LINMATH FLOATNAME(LMatrix3)::const_iterator FLOATNAME(LMatrix3)::
  315. begin() const {
  316. return _m.data;
  317. }
  318. ////////////////////////////////////////////////////////////////////
  319. // Function: LMatrix3::end
  320. // Access: Public
  321. // Description: Returns an iterator that may be used to traverse the
  322. // elements of the matrix, STL-style.
  323. ////////////////////////////////////////////////////////////////////
  324. INLINE_LINMATH FLOATNAME(LMatrix3)::const_iterator FLOATNAME(LMatrix3)::
  325. end() const {
  326. return begin() + get_num_components();
  327. }
  328. ////////////////////////////////////////////////////////////////////
  329. // Function: LMatrix3::Ordering Operator
  330. // Access: Public
  331. // Description: This performs a lexicographical comparison. It's of
  332. // questionable mathematical meaning, but sometimes has
  333. // a practical purpose for sorting unique vectors,
  334. // especially in an STL container. Also see
  335. // compare_to().
  336. ////////////////////////////////////////////////////////////////////
  337. INLINE_LINMATH bool FLOATNAME(LMatrix3)::
  338. operator < (const FLOATNAME(LMatrix3) &other) const {
  339. return compare_to(other) < 0;
  340. }
  341. ////////////////////////////////////////////////////////////////////
  342. // Function: LMatrix3::Equality Operator
  343. // Access: Public
  344. // Description:
  345. ////////////////////////////////////////////////////////////////////
  346. INLINE_LINMATH bool FLOATNAME(LMatrix3)::
  347. operator == (const FLOATNAME(LMatrix3) &other) const {
  348. return compare_to(other) == 0;
  349. }
  350. ////////////////////////////////////////////////////////////////////
  351. // Function: LMatrix3::Inequality Operator
  352. // Access: Public
  353. // Description:
  354. ////////////////////////////////////////////////////////////////////
  355. INLINE_LINMATH bool FLOATNAME(LMatrix3)::
  356. operator != (const FLOATNAME(LMatrix3) &other) const {
  357. return !operator == (other);
  358. }
  359. ////////////////////////////////////////////////////////////////////
  360. // Function: LMatrix3::compare_to
  361. // Access: Public
  362. // Description: This flavor of compare_to uses a default threshold
  363. // value based on the numeric type.
  364. ////////////////////////////////////////////////////////////////////
  365. INLINE_LINMATH int FLOATNAME(LMatrix3)::
  366. compare_to(const FLOATNAME(LMatrix3) &other) const {
  367. return compare_to(other, NEARLY_ZERO(FLOATTYPE));
  368. }
  369. #define VECTOR3_MATRIX3_PRODUCT(v_res, v, mat) \
  370. 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; \
  371. 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; \
  372. 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;
  373. // bugbug: need 2 check if this is correct, or reversed from previous implementation
  374. // before checkin
  375. ////////////////////////////////////////////////////////////////////
  376. // Function: LMatrix3::xform
  377. // Access: Public
  378. // Description: 3-component vector or point times matrix. This is a
  379. // fully general operation.
  380. ////////////////////////////////////////////////////////////////////
  381. INLINE_LINMATH FLOATNAME(LVecBase3) FLOATNAME(LMatrix3)::
  382. xform(const FLOATNAME(LVecBase3) &v) const {
  383. FLOATNAME(LVecBase3) v_res;
  384. VECTOR3_MATRIX3_PRODUCT(v_res, v,(*this));
  385. return v_res;
  386. // return FLOATNAME(LVecBase3)(v.dot(get_col(0)),
  387. // v.dot(get_col(1)),
  388. // v.dot(get_col(2)));
  389. }
  390. ////////////////////////////////////////////////////////////////////
  391. // Function: LMatrix3::xform_point
  392. // Access: Public
  393. // Description: The matrix transforms a 2-component point (including
  394. // translation component) and returns the result. This
  395. // assumes the matrix is an affine transform.
  396. ////////////////////////////////////////////////////////////////////
  397. INLINE_LINMATH FLOATNAME(LVecBase2) FLOATNAME(LMatrix3)::
  398. xform_point(const FLOATNAME(LVecBase2) &v) const {
  399. FLOATNAME(LVecBase2) v_res;
  400. // v._v.v._2 == 1.0f for this case
  401. v_res._v.v._0 = v._v.v._0*_m.m._00 + v._v.v._1*_m.m._10 + _m.m._20;
  402. v_res._v.v._1 = v._v.v._0*_m.m._01 + v._v.v._1*_m.m._11 + _m.m._21;
  403. return v_res;
  404. // return FLOATNAME(LVecBase2)(v.dot(get_col2(0)) + _m.m._20,
  405. // v.dot(get_col2(1)) + _m.m._21);
  406. }
  407. ////////////////////////////////////////////////////////////////////
  408. // Function: LMatrix3::xform_vec
  409. // Access: Public
  410. // Description: The matrix transforms a 2-component vector (without
  411. // translation component) and returns the result. This
  412. // assumes the matrix is an affine transform.
  413. ////////////////////////////////////////////////////////////////////
  414. INLINE_LINMATH FLOATNAME(LVecBase2) FLOATNAME(LMatrix3)::
  415. xform_vec(const FLOATNAME(LVecBase2) &v) const {
  416. FLOATNAME(LVecBase2) v_res;
  417. // v._v.v._2 == 0.0f for this case
  418. v_res._v.v._0 = v._v.v._0*_m.m._00 + v._v.v._1*_m.m._10;
  419. v_res._v.v._1 = v._v.v._0*_m.m._01 + v._v.v._1*_m.m._11;
  420. return v_res;
  421. // return FLOATNAME(LVecBase2)(v.dot(get_col2(0)),
  422. // v.dot(get_col2(1)));
  423. }
  424. ////////////////////////////////////////////////////////////////////
  425. // Function: LMatrix3::mult_cel
  426. // Access: Private
  427. // Description: Returns one cell of the result of a matrix-matrix
  428. // multiplication operation.
  429. ////////////////////////////////////////////////////////////////////
  430. INLINE_LINMATH FLOATTYPE FLOATNAME(LMatrix3)::
  431. mult_cel(const FLOATNAME(LMatrix3) &other, int row, int col) const {
  432. return get_row(row).dot(other.get_col(col));
  433. }
  434. #define MATRIX3_PRODUCT(res, a, b) \
  435. 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; \
  436. 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; \
  437. 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; \
  438. 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; \
  439. 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; \
  440. 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; \
  441. 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; \
  442. 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; \
  443. 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;
  444. ////////////////////////////////////////////////////////////////////
  445. // Function: LMatrix3::matrix * matrix
  446. // Access: Public
  447. // Description:
  448. ////////////////////////////////////////////////////////////////////
  449. INLINE_LINMATH FLOATNAME(LMatrix3) FLOATNAME(LMatrix3)::
  450. operator * (const FLOATNAME(LMatrix3) &other) const {
  451. FLOATNAME(LMatrix3) t;
  452. MATRIX3_PRODUCT(t,(*this),other);
  453. /*
  454. typedef union {
  455. struct {
  456. FLOATTYPE _m.m._11, _m.m._12, _m.m._13;
  457. FLOATTYPE _m.m._21, _m.m._22, _m.m._23;
  458. FLOATTYPE _m.m._31, _m.m._32, _m.m._33;
  459. };
  460. FLOATTYPE m[3][3];
  461. } MYMATRIX3;
  462. FLOATNAME(LMatrix3) t;
  463. MYMATRIX3 *result_ptr=(MYMATRIX3 *)t.get_m.data();
  464. MYMATRIX3 *mat1_ptr=(MYMATRIX3 *)this->get_m.data();
  465. MYMATRIX3 *mat2_ptr=(MYMATRIX3 *)other.get_m.data();
  466. MATRIX3_PRODUCT(result_ptr,mat1_ptr,mat2_ptr);
  467. */
  468. /*
  469. t(0, 0) = mult_cel(other, 0, 0);
  470. t(0, 1) = mult_cel(other, 0, 1);
  471. t(0, 2) = mult_cel(other, 0, 2);
  472. t(1, 0) = mult_cel(other, 1, 0);
  473. t(1, 1) = mult_cel(other, 1, 1);
  474. t(1, 2) = mult_cel(other, 1, 2);
  475. t(2, 0) = mult_cel(other, 2, 0);
  476. t(2, 1) = mult_cel(other, 2, 1);
  477. t(2, 2) = mult_cel(other, 2, 2);
  478. */
  479. return t;
  480. }
  481. // this = other1 * other2
  482. INLINE_LINMATH void FLOATNAME(LMatrix3)::
  483. multiply(const FLOATNAME(LMatrix3) &other1, const FLOATNAME(LMatrix3) &other2) {
  484. // faster than operator * since it writes result in place, avoiding extra copying
  485. // this will fail if you try to mat.multiply(mat,other_mat)
  486. #ifdef _DEBUG
  487. assert((&other1 != this) && (&other2 != this));
  488. #endif
  489. MATRIX3_PRODUCT((*this),other1,other2);
  490. }
  491. // this = scale_mat(scale_vector) * other_mat, efficiently
  492. INLINE_LINMATH void FLOATNAME(LMatrix3)::
  493. scale_multiply(const FLOATNAME(LVecBase3) &scale_vector,const FLOATNAME(LMatrix3) &other_mat) {
  494. #ifdef _DEBUG
  495. assert(&other_mat != this);
  496. #endif
  497. // optimize for 0.0 or 1.0 factors?
  498. _m.m._00 = other_mat._m.m._00 * scale_vector._v.v._0;
  499. _m.m._01 = other_mat._m.m._01 * scale_vector._v.v._0;
  500. _m.m._02 = other_mat._m.m._02 * scale_vector._v.v._0;
  501. _m.m._10 = other_mat._m.m._10 * scale_vector._v.v._1;
  502. _m.m._11 = other_mat._m.m._11 * scale_vector._v.v._1;
  503. _m.m._12 = other_mat._m.m._12 * scale_vector._v.v._1;
  504. _m.m._20 = other_mat._m.m._20 * scale_vector._v.v._2;
  505. _m.m._21 = other_mat._m.m._21 * scale_vector._v.v._2;
  506. _m.m._22 = other_mat._m.m._22 * scale_vector._v.v._2;
  507. }
  508. ////////////////////////////////////////////////////////////////////
  509. // Function: LMatrix3::matrix * scalar
  510. // Access: Public
  511. // Description:
  512. ////////////////////////////////////////////////////////////////////
  513. INLINE_LINMATH FLOATNAME(LMatrix3) FLOATNAME(LMatrix3)::
  514. operator * (FLOATTYPE scalar) const {
  515. FLOATNAME(LMatrix3) t;
  516. t._m.m._00 = _m.m._00 * scalar;
  517. t._m.m._01 = _m.m._01 * scalar;
  518. t._m.m._02 = _m.m._02 * scalar;
  519. t._m.m._10 = _m.m._10 * scalar;
  520. t._m.m._11 = _m.m._11 * scalar;
  521. t._m.m._12 = _m.m._12 * scalar;
  522. t._m.m._20 = _m.m._20 * scalar;
  523. t._m.m._21 = _m.m._21 * scalar;
  524. t._m.m._22 = _m.m._22 * scalar;
  525. return t;
  526. }
  527. ////////////////////////////////////////////////////////////////////
  528. // Function: LMatrix3::matrix / scalar
  529. // Access: Public
  530. // Description:
  531. ////////////////////////////////////////////////////////////////////
  532. INLINE_LINMATH FLOATNAME(LMatrix3) FLOATNAME(LMatrix3)::
  533. operator / (FLOATTYPE scalar) const {
  534. FLOATTYPE recip_scalar = 1.0f/scalar;
  535. return (*this) * recip_scalar;
  536. }
  537. ////////////////////////////////////////////////////////////////////
  538. // Function: LMatrix3::matrix += matrix
  539. // Access: Public
  540. // Description: Performs a memberwise addition between two matrices.
  541. ////////////////////////////////////////////////////////////////////
  542. INLINE_LINMATH FLOATNAME(LMatrix3) &FLOATNAME(LMatrix3)::
  543. operator += (const FLOATNAME(LMatrix3) &other) {
  544. _m.m._00 += other._m.m._00;
  545. _m.m._01 += other._m.m._01;
  546. _m.m._02 += other._m.m._02;
  547. _m.m._10 += other._m.m._10;
  548. _m.m._11 += other._m.m._11;
  549. _m.m._12 += other._m.m._12;
  550. _m.m._20 += other._m.m._20;
  551. _m.m._21 += other._m.m._21;
  552. _m.m._22 += other._m.m._22;
  553. return *this;
  554. }
  555. ////////////////////////////////////////////////////////////////////
  556. // Function: LMatrix3::matrix -= matrix
  557. // Access: Public
  558. // Description: Performs a memberwise subtraction between two matrices.
  559. ////////////////////////////////////////////////////////////////////
  560. INLINE_LINMATH FLOATNAME(LMatrix3) &FLOATNAME(LMatrix3)::
  561. operator -= (const FLOATNAME(LMatrix3) &other) {
  562. _m.m._00 -= other._m.m._00;
  563. _m.m._01 -= other._m.m._01;
  564. _m.m._02 -= other._m.m._02;
  565. _m.m._10 -= other._m.m._10;
  566. _m.m._11 -= other._m.m._11;
  567. _m.m._12 -= other._m.m._12;
  568. _m.m._20 -= other._m.m._20;
  569. _m.m._21 -= other._m.m._21;
  570. _m.m._22 -= other._m.m._22;
  571. return *this;
  572. }
  573. ////////////////////////////////////////////////////////////////////
  574. // Function: LMatrix3::matrix *= matrix
  575. // Access: Public
  576. // Description:
  577. ////////////////////////////////////////////////////////////////////
  578. INLINE_LINMATH FLOATNAME(LMatrix3) &FLOATNAME(LMatrix3)::
  579. operator *= (const FLOATNAME(LMatrix3) &other) {
  580. (*this) = (*this) * other;
  581. // bugbug can we do any optimization here?
  582. return *this;
  583. }
  584. ////////////////////////////////////////////////////////////////////
  585. // Function: LMatrix3::matrix *= scalar
  586. // Access: Public
  587. // Description: Performs a memberwise scale.
  588. ////////////////////////////////////////////////////////////////////
  589. INLINE_LINMATH FLOATNAME(LMatrix3) &FLOATNAME(LMatrix3)::
  590. operator *= (FLOATTYPE scalar) {
  591. _m.m._00 *= scalar;
  592. _m.m._01 *= scalar;
  593. _m.m._02 *= scalar;
  594. _m.m._10 *= scalar;
  595. _m.m._11 *= scalar;
  596. _m.m._12 *= scalar;
  597. _m.m._20 *= scalar;
  598. _m.m._21 *= scalar;
  599. _m.m._22 *= scalar;
  600. return *this;
  601. }
  602. ////////////////////////////////////////////////////////////////////
  603. // Function: LMatrix3::matrix /= scalar
  604. // Access: Public
  605. // Description: Performs a memberwise scale.
  606. ////////////////////////////////////////////////////////////////////
  607. INLINE_LINMATH FLOATNAME(LMatrix3) &FLOATNAME(LMatrix3)::
  608. operator /= (FLOATTYPE scalar) {
  609. FLOATTYPE recip_scalar = 1.0f/scalar;
  610. _m.m._00 *= recip_scalar;
  611. _m.m._01 *= recip_scalar;
  612. _m.m._02 *= recip_scalar;
  613. _m.m._10 *= recip_scalar;
  614. _m.m._11 *= recip_scalar;
  615. _m.m._12 *= recip_scalar;
  616. _m.m._20 *= recip_scalar;
  617. _m.m._21 *= recip_scalar;
  618. _m.m._22 *= recip_scalar;
  619. return *this;
  620. }
  621. ////////////////////////////////////////////////////////////////////
  622. // Function: LMatrix3::transpose_from
  623. // Access: Public
  624. // Description:
  625. ////////////////////////////////////////////////////////////////////
  626. INLINE_LINMATH void FLOATNAME(LMatrix3)::
  627. transpose_from(const FLOATNAME(LMatrix3) &other) {
  628. _m.m._00 = other._m.m._00;
  629. _m.m._01 = other._m.m._10;
  630. _m.m._02 = other._m.m._20;
  631. _m.m._10 = other._m.m._01;
  632. _m.m._11 = other._m.m._11;
  633. _m.m._12 = other._m.m._21;
  634. _m.m._20 = other._m.m._02;
  635. _m.m._21 = other._m.m._12;
  636. _m.m._22 = other._m.m._22;
  637. }
  638. ////////////////////////////////////////////////////////////////////
  639. // Function: LMatrix3::transpose_in_place
  640. // Access: Public
  641. // Description:
  642. ////////////////////////////////////////////////////////////////////
  643. INLINE_LINMATH void FLOATNAME(LMatrix3)::
  644. transpose_in_place() {
  645. // FLOATNAME(LMatrix3) temp = (*this);
  646. // transpose_from(temp);
  647. #define SWAP__(x,y) { FLOATTYPE temp = (x); (x) = (y); (y) = temp;}
  648. SWAP__(_m.m._01,_m.m._10);
  649. SWAP__(_m.m._02,_m.m._20);
  650. SWAP__(_m.m._12,_m.m._21);
  651. #undef SWAP__
  652. }
  653. // Matrix inversion code from Numerical Recipes in C.
  654. // dont trust compilers to inline these
  655. #define DET2(E00,E01,E10,E11) ((E00)*(E11) - (E10)*(E01))
  656. #define MATRIX3_DETERMINANT(mat) \
  657. ( (mat)._00 * DET2((mat)._11,(mat)._12,(mat)._21,(mat)._22) \
  658. -(mat)._01 * DET2((mat)._10,(mat)._12,(mat)._20,(mat)._22) \
  659. +(mat)._02 * DET2((mat)._10,(mat)._11,(mat)._20,(mat)._21))
  660. ////////////////////////////////////////////////////////////////////
  661. // Function: LMatrix3::det2
  662. // Access: Private, Static
  663. // Description: Returns the determinant of a 2x2 matrix.
  664. ////////////////////////////////////////////////////////////////////
  665. INLINE_LINMATH FLOATTYPE FLOATNAME(LMatrix3)::
  666. det2(FLOATTYPE e00, FLOATTYPE e01, FLOATTYPE e10, FLOATTYPE e11) const {
  667. // return (e00 * e11 - e10 * e01);
  668. return DET2(e00,e01,e10,e11);
  669. }
  670. ////////////////////////////////////////////////////////////////////
  671. // Function: LMatrix3::determinant
  672. // Access: Public
  673. // Description: Returns the determinant of the matrix.
  674. ////////////////////////////////////////////////////////////////////
  675. INLINE_LINMATH FLOATTYPE FLOATNAME(LMatrix3)::
  676. determinant() const {
  677. /*
  678. return
  679. (*this)(0,0) * det2((*this)(1,1),(*this)(1,2),(*this)(2,1),(*this)(2,2))
  680. -(*this)(0,1) * det2((*this)(1,0),(*this)(1,2),(*this)(2,0),(*this)(2,2))
  681. +(*this)(0,2) * det2((*this)(1,0),(*this)(1,1),(*this)(2,0),(*this)(2,1));
  682. */
  683. return MATRIX3_DETERMINANT(_m.m);
  684. }
  685. ////////////////////////////////////////////////////////////////////
  686. // Function: LMatrix3::invert_from
  687. // Access: Public
  688. // Description: Computes the inverse of the other matrix, and stores
  689. // the result in this matrix. This is a fully general
  690. // operation and makes no assumptions about the type of
  691. // transform represented by the matrix.
  692. //
  693. // The other matrix must be a different object than this
  694. // matrix. However, if you need to invert a matrix in
  695. // place, see invert_in_place.
  696. //
  697. // The return value is true if the matrix was
  698. // successfully inverted, false if the was a
  699. // singularity.
  700. ////////////////////////////////////////////////////////////////////
  701. INLINE_LINMATH bool FLOATNAME(LMatrix3)::
  702. invert_from(const FLOATNAME(LMatrix3) &other) {
  703. FLOATTYPE other_det = MATRIX3_DETERMINANT(other._m.m);
  704. // We throw the value out only if it's smaller than our "small"
  705. // threshold squared. This helps reduce overly-sensitive
  706. // rejections.
  707. if (IS_THRESHOLD_ZERO(other_det, (NEARLY_ZERO(FLOATTYPE) * NEARLY_ZERO(FLOATTYPE)))) {
  708. // if (IS_NEARLY_ZERO(other_det)) {
  709. #ifdef NOTIFY_DEBUG
  710. linmath_cat.warning() << "Tried to invert singular LMatrix3.\n";
  711. #endif
  712. (*this) = ident_mat();
  713. return false;
  714. }
  715. other_det = 1.0f / other_det;
  716. _m.m._00 = other_det * DET2(other._m.m._11, other._m.m._12, other._m.m._21, other._m.m._22);
  717. _m.m._10 = -other_det * DET2(other._m.m._10, other._m.m._12, other._m.m._20, other._m.m._22);
  718. _m.m._20 = other_det * DET2(other._m.m._10, other._m.m._11, other._m.m._20, other._m.m._21);
  719. _m.m._01 = -other_det * DET2(other._m.m._01, other._m.m._02, other._m.m._21, other._m.m._22);
  720. _m.m._11 = other_det * DET2(other._m.m._00, other._m.m._02, other._m.m._20, other._m.m._22);
  721. _m.m._21 = -other_det * DET2(other._m.m._00, other._m.m._01, other._m.m._20, other._m.m._21);
  722. _m.m._02 = other_det * DET2(other._m.m._01, other._m.m._02, other._m.m._11, other._m.m._12);
  723. _m.m._12 = -other_det * DET2(other._m.m._00, other._m.m._02, other._m.m._10, other._m.m._12);
  724. _m.m._22 = other_det * DET2(other._m.m._00, other._m.m._01, other._m.m._10, other._m.m._11);
  725. return true;
  726. }
  727. ////////////////////////////////////////////////////////////////////
  728. // Function: LMatrix3::invert_in_place
  729. // Access: Public
  730. // Description: Inverts the current matrix. Returns true if the
  731. // inverse is successful, false if the matrix was
  732. // singular.
  733. ////////////////////////////////////////////////////////////////////
  734. INLINE_LINMATH bool FLOATNAME(LMatrix3)::
  735. invert_in_place() {
  736. FLOATNAME(LMatrix3) temp = (*this);
  737. return invert_from(temp);
  738. }
  739. ////////////////////////////////////////////////////////////////////
  740. // Function: LMatrix::translate_mat
  741. // Access: Public, Static
  742. // Description: Returns a matrix that applies the indicated
  743. // translation.
  744. ////////////////////////////////////////////////////////////////////
  745. INLINE_LINMATH FLOATNAME(LMatrix3) FLOATNAME(LMatrix3)::
  746. translate_mat(const FLOATNAME(LVecBase2) &trans) {
  747. return FLOATNAME(LMatrix3)(1.0f, 0.0f, 0.0f,
  748. 0.0f, 1.0f, 0.0f,
  749. trans._v.v._0, trans._v.v._1, 1.0f);
  750. }
  751. ////////////////////////////////////////////////////////////////////
  752. // Function: LMatrix::translate_mat
  753. // Access: Public, Static
  754. // Description: Returns a matrix that applies the indicated
  755. // translation.
  756. ////////////////////////////////////////////////////////////////////
  757. INLINE_LINMATH FLOATNAME(LMatrix3) FLOATNAME(LMatrix3)::
  758. translate_mat(FLOATTYPE tx, FLOATTYPE ty) {
  759. return FLOATNAME(LMatrix3)(1.0f, 0.0f, 0.0f,
  760. 0.0f, 1.0f, 0.0f,
  761. tx, ty, 1.0f);
  762. }
  763. ////////////////////////////////////////////////////////////////////
  764. // Function: LMatrix::rotate_mat
  765. // Access: Public, Static
  766. // Description: Returns a matrix that rotates by the given angle in
  767. // degrees counterclockwise.
  768. ////////////////////////////////////////////////////////////////////
  769. INLINE_LINMATH FLOATNAME(LMatrix3) FLOATNAME(LMatrix3)::
  770. rotate_mat(FLOATTYPE angle) {
  771. FLOATTYPE angle_rad=deg_2_rad(angle);
  772. FLOATTYPE s,c;
  773. csincos(angle_rad,&s,&c);
  774. return FLOATNAME(LMatrix3)( c, s, 0.0f,
  775. -s, c, 0.0f,
  776. 0.0f, 0.0f, 1.0f);
  777. }
  778. ////////////////////////////////////////////////////////////////////
  779. // Function: LMatrix::scale_mat
  780. // Access: Public, Static
  781. // Description: Returns a matrix that applies the indicated
  782. // scale in each of the two axes.
  783. ////////////////////////////////////////////////////////////////////
  784. INLINE_LINMATH FLOATNAME(LMatrix3) FLOATNAME(LMatrix3)::
  785. scale_mat(const FLOATNAME(LVecBase2) &scale) {
  786. return FLOATNAME(LMatrix3)(scale._v.v._0, 0.0f, 0.0f,
  787. 0.0f, scale._v.v._1, 0.0f,
  788. 0.0f, 0.0f, 1.0f);
  789. }
  790. ////////////////////////////////////////////////////////////////////
  791. // Function: LMatrix::scale_mat
  792. // Access: Public, Static
  793. // Description: Returns a matrix that applies the indicated
  794. // scale in each of the two axes.
  795. ////////////////////////////////////////////////////////////////////
  796. INLINE_LINMATH FLOATNAME(LMatrix3) FLOATNAME(LMatrix3)::
  797. scale_mat(FLOATTYPE sx, FLOATTYPE sy) {
  798. return FLOATNAME(LMatrix3)(sx, 0.0f, 0.0f,
  799. 0.0f, sy, 0.0f,
  800. 0.0f, 0.0f, 1.0f);
  801. }
  802. ////////////////////////////////////////////////////////////////////
  803. // Function: LMatrix::rotate_mat
  804. // Access: Public, Static
  805. // Description: Returns a matrix that rotates by the given angle in
  806. // degrees counterclockwise about the indicated vector.
  807. ////////////////////////////////////////////////////////////////////
  808. INLINE_LINMATH FLOATNAME(LMatrix3) FLOATNAME(LMatrix3)::
  809. rotate_mat(FLOATTYPE angle, FLOATNAME(LVecBase3) axis,
  810. CoordinateSystem cs) {
  811. if (cs == CS_default) {
  812. cs = default_coordinate_system;
  813. }
  814. FLOATNAME(LMatrix3) mat;
  815. if(IS_LEFT_HANDED_COORDSYSTEM(cs)) {
  816. // In a left-handed coordinate system, counterclockwise is the
  817. // other direction.
  818. angle = -angle;
  819. }
  820. FLOATTYPE axis_0 = axis._v.v._0;
  821. FLOATTYPE axis_1 = axis._v.v._1;
  822. FLOATTYPE axis_2 = axis._v.v._2;
  823. // Normalize the axis.
  824. FLOATTYPE length_sq = axis_0 * axis_0 + axis_1 * axis_1 + axis_2 * axis_2;
  825. #ifdef _DEBUG
  826. nassertr(length_sq != 0.0f, ident_mat());
  827. #endif
  828. FLOATTYPE recip_length = 1.0f/csqrt(length_sq);
  829. axis_0 *= recip_length;
  830. axis_1 *= recip_length;
  831. axis_2 *= recip_length;
  832. FLOATTYPE angle_rad=deg_2_rad(angle);
  833. FLOATTYPE s,c;
  834. csincos(angle_rad,&s,&c);
  835. FLOATTYPE t = 1.0f - c;
  836. FLOATTYPE t0,t1,t2,s0,s1,s2;
  837. t0 = t * axis_0;
  838. t1 = t * axis_1;
  839. t2 = t * axis_2;
  840. s0 = s * axis_0;
  841. s1 = s * axis_1;
  842. s2 = s * axis_2;
  843. mat._m.m._00 = t0 * axis_0 + c;
  844. mat._m.m._01 = t0 * axis_1 + s2;
  845. mat._m.m._02 = t0 * axis_2 - s1;
  846. mat._m.m._10 = t1 * axis_0 - s2;
  847. mat._m.m._11 = t1 * axis_1 + c;
  848. mat._m.m._12 = t1 * axis_2 + s0;
  849. mat._m.m._20 = t2 * axis_0 + s1;
  850. mat._m.m._21 = t2 * axis_1 - s0;
  851. mat._m.m._22 = t2 * axis_2 + c;
  852. /*
  853. mat._m.m._00 = t * axis._v.v._0 * axis._v.v._0 + c;
  854. mat._m.m._01 = t * axis._v.v._0 * axis._v.v._1 + s * axis._v.v._2;
  855. mat._m.m._02 = t * axis._v.v._0 * axis._v.v._2 - s * axis._v.v._1;
  856. mat._m.m._10 = t * axis._v.v._1 * axis._v.v._0 - s * axis._v.v._2;
  857. mat._m.m._11 = t * axis._v.v._1 * axis._v.v._1 + c;
  858. mat._m.m._12 = t * axis._v.v._1 * axis._v.v._2 + s * axis._v.v._0;
  859. mat._m.m._20 = t * axis._v.v._2 * axis._v.v._0 + s * axis._v.v._1;
  860. mat._m.m._21 = t * axis._v.v._2 * axis._v.v._1 - s * axis._v.v._0;
  861. mat._m.m._22 = t * axis._v.v._2 * axis._v.v._2 + c;
  862. */
  863. return mat;
  864. }
  865. ////////////////////////////////////////////////////////////////////
  866. // Function: LMatrix::rotate_mat_normaxis
  867. // Access: Public, Static
  868. // Description: Returns a matrix that rotates by the given angle in
  869. // degrees counterclockwise about the indicated vector.
  870. // Assumes axis has been normalized.
  871. ////////////////////////////////////////////////////////////////////
  872. INLINE_LINMATH FLOATNAME(LMatrix3) FLOATNAME(LMatrix3)::
  873. rotate_mat_normaxis(FLOATTYPE angle, const FLOATNAME(LVecBase3) &axis,
  874. CoordinateSystem cs) {
  875. if (cs == CS_default) {
  876. cs = default_coordinate_system;
  877. }
  878. FLOATNAME(LMatrix3) mat;
  879. if(IS_LEFT_HANDED_COORDSYSTEM(cs)) {
  880. // In a left-handed coordinate system, counterclockwise is the
  881. // other direction.
  882. angle = -angle;
  883. }
  884. FLOATTYPE axis_0 = axis._v.v._0;
  885. FLOATTYPE axis_1 = axis._v.v._1;
  886. FLOATTYPE axis_2 = axis._v.v._2;
  887. FLOATTYPE angle_rad=deg_2_rad(angle);
  888. FLOATTYPE s,c;
  889. csincos(angle_rad,&s,&c);
  890. FLOATTYPE t = 1.0f - c;
  891. FLOATTYPE t0,t1,t2,s0,s1,s2;
  892. t0 = t * axis_0;
  893. t1 = t * axis_1;
  894. t2 = t * axis_2;
  895. s0 = s * axis_0;
  896. s1 = s * axis_1;
  897. s2 = s * axis_2;
  898. mat._m.m._00 = t0 * axis_0 + c;
  899. mat._m.m._01 = t0 * axis_1 + s2;
  900. mat._m.m._02 = t0 * axis_2 - s1;
  901. mat._m.m._10 = t1 * axis_0 - s2;
  902. mat._m.m._11 = t1 * axis_1 + c;
  903. mat._m.m._12 = t1 * axis_2 + s0;
  904. mat._m.m._20 = t2 * axis_0 + s1;
  905. mat._m.m._21 = t2 * axis_1 - s0;
  906. mat._m.m._22 = t2 * axis_2 + c;
  907. /*
  908. mat._m.m._00 = t * axis._v.v._0 * axis._v.v._0 + c;
  909. mat._m.m._01 = t * axis._v.v._0 * axis._v.v._1 + s * axis._v.v._2;
  910. mat._m.m._02 = t * axis._v.v._0 * axis._v.v._2 - s * axis._v.v._1;
  911. mat._m.m._10 = t * axis._v.v._1 * axis._v.v._0 - s * axis._v.v._2;
  912. mat._m.m._11 = t * axis._v.v._1 * axis._v.v._1 + c;
  913. mat._m.m._12 = t * axis._v.v._1 * axis._v.v._2 + s * axis._v.v._0;
  914. mat._m.m._20 = t * axis._v.v._2 * axis._v.v._0 + s * axis._v.v._1;
  915. mat._m.m._21 = t * axis._v.v._2 * axis._v.v._1 - s * axis._v.v._0;
  916. mat._m.m._22 = t * axis._v.v._2 * axis._v.v._2 + c;
  917. */
  918. return mat;
  919. }
  920. ////////////////////////////////////////////////////////////////////
  921. // Function: LMatrix::scale_mat
  922. // Access: Public, Static
  923. // Description: Returns a matrix that applies the indicated
  924. // scale in each of the three axes.
  925. ////////////////////////////////////////////////////////////////////
  926. INLINE_LINMATH FLOATNAME(LMatrix3) FLOATNAME(LMatrix3)::
  927. scale_mat(const FLOATNAME(LVecBase3) &scale) {
  928. return FLOATNAME(LMatrix3)(scale[0], 0.0f, 0.0f,
  929. 0.0f, scale._v.v._1, 0.0f,
  930. 0.0f, 0.0f, scale._v.v._2);
  931. }
  932. ////////////////////////////////////////////////////////////////////
  933. // Function: LMatrix::scale_mat
  934. // Access: Public, Static
  935. // Description: Returns a matrix that applies the indicated
  936. // scale in each of the three axes.
  937. ////////////////////////////////////////////////////////////////////
  938. INLINE_LINMATH FLOATNAME(LMatrix3) FLOATNAME(LMatrix3)::
  939. scale_mat(FLOATTYPE sx, FLOATTYPE sy, FLOATTYPE sz) {
  940. return FLOATNAME(LMatrix3)(sx, 0.0f, 0.0f,
  941. 0.0f, sy, 0.0f,
  942. 0.0f, 0.0f, sz);
  943. }
  944. ////////////////////////////////////////////////////////////////////
  945. // Function: LMatrix3::almost_equal
  946. // Access: Public
  947. // Description: Returns true if two matrices are memberwise equal
  948. // within a default tolerance based on the numeric type.
  949. ////////////////////////////////////////////////////////////////////
  950. INLINE_LINMATH bool FLOATNAME(LMatrix3)::
  951. almost_equal(const FLOATNAME(LMatrix3) &other) const {
  952. return almost_equal(other, NEARLY_ZERO(FLOATTYPE));
  953. }
  954. ////////////////////////////////////////////////////////////////////
  955. // Function: LMatrix3::generate_hash
  956. // Access: Public
  957. // Description: Adds the vector to the indicated hash generator.
  958. ////////////////////////////////////////////////////////////////////
  959. INLINE_LINMATH void FLOATNAME(LMatrix3)::
  960. generate_hash(ChecksumHashGenerator &hashgen) const {
  961. generate_hash(hashgen, NEARLY_ZERO(FLOATTYPE));
  962. }
  963. ////////////////////////////////////////////////////////////////////
  964. // Function: transpose
  965. // Description: Transposes the given matrix and returns it.
  966. ////////////////////////////////////////////////////////////////////
  967. INLINE_LINMATH FLOATNAME(LMatrix3)
  968. transpose(const FLOATNAME(LMatrix3) &a) {
  969. FLOATNAME(LMatrix3) result;
  970. result.transpose_from(a);
  971. return result;
  972. }
  973. ////////////////////////////////////////////////////////////////////
  974. // Function: invert
  975. // Description: Inverts the given matrix and returns it.
  976. ////////////////////////////////////////////////////////////////////
  977. INLINE_LINMATH FLOATNAME(LMatrix3)
  978. invert(const FLOATNAME(LMatrix3) &a) {
  979. FLOATNAME(LMatrix3) result;
  980. bool nonsingular = result.invert_from(a);
  981. nassertr(nonsingular, FLOATNAME(LMatrix3)::ident_mat());
  982. return result;
  983. }