map_vec_mat.hpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591
  1. //Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
  2. //Distributed under the Boost Software License, Version 1.0. (See accompanying
  3. //file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  4. #ifndef UUID_3EDF999CA1C011DEBA5C8DA956D89593
  5. #define UUID_3EDF999CA1C011DEBA5C8DA956D89593
  6. #include <boost/qvm/inline.hpp>
  7. #include <boost/qvm/deduce_mat.hpp>
  8. #include <boost/qvm/vec_traits.hpp>
  9. #include <boost/qvm/assert.hpp>
  10. #include <boost/qvm/enable_if.hpp>
  11. namespace
  12. boost
  13. {
  14. namespace
  15. qvm
  16. {
  17. ////////////////////////////////////////////////
  18. namespace
  19. qvm_detail
  20. {
  21. template <class OriginalVector>
  22. class
  23. col_mat_
  24. {
  25. col_mat_( col_mat_ const & );
  26. col_mat_ & operator=( col_mat_ const & );
  27. ~col_mat_();
  28. public:
  29. template <class T>
  30. BOOST_QVM_INLINE_TRIVIAL
  31. col_mat_ &
  32. operator=( T const & x )
  33. {
  34. assign(*this,x);
  35. return *this;
  36. }
  37. template <class R>
  38. BOOST_QVM_INLINE_TRIVIAL
  39. operator R() const
  40. {
  41. R r;
  42. assign(r,*this);
  43. return r;
  44. }
  45. };
  46. }
  47. template <class OriginalVector>
  48. struct
  49. mat_traits< qvm_detail::col_mat_<OriginalVector> >
  50. {
  51. typedef qvm_detail::col_mat_<OriginalVector> this_matrix;
  52. typedef typename vec_traits<OriginalVector>::scalar_type scalar_type;
  53. static int const rows=vec_traits<OriginalVector>::dim;
  54. static int const cols=1;
  55. template <int Row,int Col>
  56. static
  57. BOOST_QVM_INLINE_CRITICAL
  58. scalar_type
  59. read_element( this_matrix const & x )
  60. {
  61. BOOST_QVM_STATIC_ASSERT(Col==0);
  62. BOOST_QVM_STATIC_ASSERT(Row>=0);
  63. BOOST_QVM_STATIC_ASSERT(Row<rows);
  64. return vec_traits<OriginalVector>::template read_element<Row>(reinterpret_cast<OriginalVector const &>(x));
  65. }
  66. template <int Row,int Col>
  67. static
  68. BOOST_QVM_INLINE_CRITICAL
  69. scalar_type &
  70. write_element( this_matrix & x )
  71. {
  72. BOOST_QVM_STATIC_ASSERT(Col==0);
  73. BOOST_QVM_STATIC_ASSERT(Row>=0);
  74. BOOST_QVM_STATIC_ASSERT(Row<rows);
  75. return vec_traits<OriginalVector>::template write_element<Row>(reinterpret_cast<OriginalVector &>(x));
  76. }
  77. static
  78. BOOST_QVM_INLINE_CRITICAL
  79. scalar_type
  80. read_element_idx( int row, int col, this_matrix const & x )
  81. {
  82. BOOST_QVM_ASSERT(col==0);
  83. BOOST_QVM_ASSERT(row>=0);
  84. BOOST_QVM_ASSERT(row<rows);
  85. return vec_traits<OriginalVector>::read_element_idx(row,reinterpret_cast<OriginalVector const &>(x));
  86. }
  87. static
  88. BOOST_QVM_INLINE_CRITICAL
  89. scalar_type &
  90. write_element_idx( int row, int col, this_matrix & x )
  91. {
  92. BOOST_QVM_ASSERT(col==0);
  93. BOOST_QVM_ASSERT(row>=0);
  94. BOOST_QVM_ASSERT(row<rows);
  95. return vec_traits<OriginalVector>::write_element_idx(row,reinterpret_cast<OriginalVector &>(x));
  96. }
  97. };
  98. template <class OriginalVector,int R,int C>
  99. struct
  100. deduce_mat<qvm_detail::col_mat_<OriginalVector>,R,C>
  101. {
  102. typedef mat<typename vec_traits<OriginalVector>::scalar_type,R,C> type;
  103. };
  104. template <class OriginalVector,int R,int C>
  105. struct
  106. deduce_mat2<qvm_detail::col_mat_<OriginalVector>,qvm_detail::col_mat_<OriginalVector>,R,C>
  107. {
  108. typedef mat<typename vec_traits<OriginalVector>::scalar_type,R,C> type;
  109. };
  110. template <class A>
  111. typename boost::enable_if_c<
  112. is_vec<A>::value,
  113. qvm_detail::col_mat_<A> const &>::type
  114. BOOST_QVM_INLINE_TRIVIAL
  115. col_mat( A const & a )
  116. {
  117. return reinterpret_cast<typename qvm_detail::col_mat_<A> const &>(a);
  118. }
  119. template <class A>
  120. typename boost::enable_if_c<
  121. is_vec<A>::value,
  122. qvm_detail::col_mat_<A> &>::type
  123. BOOST_QVM_INLINE_TRIVIAL
  124. col_mat( A & a )
  125. {
  126. return reinterpret_cast<typename qvm_detail::col_mat_<A> &>(a);
  127. }
  128. ////////////////////////////////////////////////
  129. namespace
  130. qvm_detail
  131. {
  132. template <class OriginalVector>
  133. class
  134. row_mat_
  135. {
  136. row_mat_( row_mat_ const & );
  137. row_mat_ & operator=( row_mat_ const & );
  138. ~row_mat_();
  139. public:
  140. template <class T>
  141. BOOST_QVM_INLINE_TRIVIAL
  142. row_mat_ &
  143. operator=( T const & x )
  144. {
  145. assign(*this,x);
  146. return *this;
  147. }
  148. template <class R>
  149. BOOST_QVM_INLINE_TRIVIAL
  150. operator R() const
  151. {
  152. R r;
  153. assign(r,*this);
  154. return r;
  155. }
  156. };
  157. }
  158. template <class OriginalVector>
  159. struct
  160. mat_traits< qvm_detail::row_mat_<OriginalVector> >
  161. {
  162. typedef qvm_detail::row_mat_<OriginalVector> this_matrix;
  163. typedef typename vec_traits<OriginalVector>::scalar_type scalar_type;
  164. static int const rows=1;
  165. static int const cols=vec_traits<OriginalVector>::dim;
  166. template <int Row,int Col>
  167. static
  168. BOOST_QVM_INLINE_CRITICAL
  169. scalar_type
  170. read_element( this_matrix const & x )
  171. {
  172. BOOST_QVM_STATIC_ASSERT(Row==0);
  173. BOOST_QVM_STATIC_ASSERT(Col>=0);
  174. BOOST_QVM_STATIC_ASSERT(Col<cols);
  175. return vec_traits<OriginalVector>::template read_element<Col>(reinterpret_cast<OriginalVector const &>(x));
  176. }
  177. template <int Row,int Col>
  178. static
  179. BOOST_QVM_INLINE_CRITICAL
  180. scalar_type &
  181. write_element( this_matrix & x )
  182. {
  183. BOOST_QVM_STATIC_ASSERT(Row==0);
  184. BOOST_QVM_STATIC_ASSERT(Col>=0);
  185. BOOST_QVM_STATIC_ASSERT(Col<cols);
  186. return vec_traits<OriginalVector>::template write_element<Col>(reinterpret_cast<OriginalVector &>(x));
  187. }
  188. static
  189. BOOST_QVM_INLINE_CRITICAL
  190. scalar_type
  191. read_element_idx( int row, int col, this_matrix const & x )
  192. {
  193. BOOST_QVM_ASSERT(row==0);
  194. BOOST_QVM_ASSERT(col>=0);
  195. BOOST_QVM_ASSERT(col<cols);
  196. return vec_traits<OriginalVector>::read_element_idx(col,reinterpret_cast<OriginalVector const &>(x));
  197. }
  198. static
  199. BOOST_QVM_INLINE_CRITICAL
  200. scalar_type &
  201. write_element_idx( int row, int col, this_matrix & x )
  202. {
  203. BOOST_QVM_ASSERT(row==0);
  204. BOOST_QVM_ASSERT(col>=0);
  205. BOOST_QVM_ASSERT(col<cols);
  206. return vec_traits<OriginalVector>::write_element_idx(col,reinterpret_cast<OriginalVector &>(x));
  207. }
  208. };
  209. template <class OriginalVector,int R,int C>
  210. struct
  211. deduce_mat<qvm_detail::row_mat_<OriginalVector>,R,C>
  212. {
  213. typedef mat<typename vec_traits<OriginalVector>::scalar_type,R,C> type;
  214. };
  215. template <class OriginalVector,int R,int C>
  216. struct
  217. deduce_mat2<qvm_detail::row_mat_<OriginalVector>,qvm_detail::row_mat_<OriginalVector>,R,C>
  218. {
  219. typedef mat<typename vec_traits<OriginalVector>::scalar_type,R,C> type;
  220. };
  221. template <class A>
  222. typename boost::enable_if_c<
  223. is_vec<A>::value,
  224. qvm_detail::row_mat_<A> const &>::type
  225. BOOST_QVM_INLINE_TRIVIAL
  226. row_mat( A const & a )
  227. {
  228. return reinterpret_cast<typename qvm_detail::row_mat_<A> const &>(a);
  229. }
  230. template <class A>
  231. typename boost::enable_if_c<
  232. is_vec<A>::value,
  233. qvm_detail::row_mat_<A> &>::type
  234. BOOST_QVM_INLINE_TRIVIAL
  235. row_mat( A & a )
  236. {
  237. return reinterpret_cast<typename qvm_detail::row_mat_<A> &>(a);
  238. }
  239. ////////////////////////////////////////////////
  240. namespace
  241. qvm_detail
  242. {
  243. template <class OriginalVector>
  244. class
  245. translation_mat_
  246. {
  247. translation_mat_( translation_mat_ const & );
  248. translation_mat_ & operator=( translation_mat_ const & );
  249. ~translation_mat_();
  250. public:
  251. template <class T>
  252. BOOST_QVM_INLINE_TRIVIAL
  253. translation_mat_ &
  254. operator=( T const & x )
  255. {
  256. assign(*this,x);
  257. return *this;
  258. }
  259. template <class R>
  260. BOOST_QVM_INLINE_TRIVIAL
  261. operator R() const
  262. {
  263. R r;
  264. assign(r,*this);
  265. return r;
  266. }
  267. };
  268. template <class M,int Row,int Col,bool TransCol=(Col==mat_traits<M>::cols-1)>
  269. struct read_translation_matat;
  270. template <class OriginalVector,int Row,int Col,bool TransCol>
  271. struct
  272. read_translation_matat<translation_mat_<OriginalVector>,Row,Col,TransCol>
  273. {
  274. static
  275. BOOST_QVM_INLINE_CRITICAL
  276. typename mat_traits< translation_mat_<OriginalVector> >::scalar_type
  277. f( translation_mat_<OriginalVector> const & )
  278. {
  279. return scalar_traits<typename mat_traits< translation_mat_<OriginalVector> >::scalar_type>::value(0);
  280. }
  281. };
  282. template <class OriginalVector,int D>
  283. struct
  284. read_translation_matat<translation_mat_<OriginalVector>,D,D,false>
  285. {
  286. static
  287. BOOST_QVM_INLINE_CRITICAL
  288. typename mat_traits< translation_mat_<OriginalVector> >::scalar_type
  289. f( translation_mat_<OriginalVector> const & )
  290. {
  291. return scalar_traits<typename mat_traits< translation_mat_<OriginalVector> >::scalar_type>::value(1);
  292. }
  293. };
  294. template <class OriginalVector,int D>
  295. struct
  296. read_translation_matat<translation_mat_<OriginalVector>,D,D,true>
  297. {
  298. static
  299. BOOST_QVM_INLINE_CRITICAL
  300. typename mat_traits< translation_mat_<OriginalVector> >::scalar_type
  301. f( translation_mat_<OriginalVector> const & )
  302. {
  303. return scalar_traits<typename mat_traits< translation_mat_<OriginalVector> >::scalar_type>::value(1);
  304. }
  305. };
  306. template <class OriginalVector,int Row,int Col>
  307. struct
  308. read_translation_matat<translation_mat_<OriginalVector>,Row,Col,true>
  309. {
  310. static
  311. BOOST_QVM_INLINE_CRITICAL
  312. typename mat_traits< translation_mat_<OriginalVector> >::scalar_type
  313. f( translation_mat_<OriginalVector> const & x )
  314. {
  315. return vec_traits<OriginalVector>::template read_element<Row>(reinterpret_cast<OriginalVector const &>(x));
  316. }
  317. };
  318. }
  319. template <class OriginalVector>
  320. struct
  321. mat_traits< qvm_detail::translation_mat_<OriginalVector> >
  322. {
  323. typedef qvm_detail::translation_mat_<OriginalVector> this_matrix;
  324. typedef typename vec_traits<OriginalVector>::scalar_type scalar_type;
  325. static int const rows=vec_traits<OriginalVector>::dim+1;
  326. static int const cols=vec_traits<OriginalVector>::dim+1;
  327. template <int Row,int Col>
  328. static
  329. BOOST_QVM_INLINE_CRITICAL
  330. scalar_type
  331. read_element( this_matrix const & x )
  332. {
  333. BOOST_QVM_STATIC_ASSERT(Row>=0);
  334. BOOST_QVM_STATIC_ASSERT(Row<rows);
  335. BOOST_QVM_STATIC_ASSERT(Col>=0);
  336. BOOST_QVM_STATIC_ASSERT(Col<cols);
  337. return qvm_detail::read_translation_matat<qvm_detail::translation_mat_<OriginalVector>,Row,Col>::f(x);
  338. }
  339. template <int Row,int Col>
  340. static
  341. BOOST_QVM_INLINE_CRITICAL
  342. scalar_type &
  343. write_element( this_matrix & x )
  344. {
  345. BOOST_QVM_STATIC_ASSERT(Row>=0);
  346. BOOST_QVM_STATIC_ASSERT(Row<rows);
  347. BOOST_QVM_STATIC_ASSERT(Col==cols-1);
  348. BOOST_QVM_STATIC_ASSERT(Col!=Row);
  349. return vec_traits<OriginalVector>::template write_element<Row>(reinterpret_cast<OriginalVector &>(x));
  350. }
  351. static
  352. BOOST_QVM_INLINE_CRITICAL
  353. scalar_type
  354. read_element_idx( int row, int col, this_matrix const & x )
  355. {
  356. BOOST_QVM_ASSERT(row>=0);
  357. BOOST_QVM_ASSERT(row<rows);
  358. BOOST_QVM_ASSERT(col>=0);
  359. BOOST_QVM_ASSERT(col<cols);
  360. return
  361. row==col?
  362. scalar_traits<scalar_type>::value(1):
  363. (col==cols-1?
  364. vec_traits<OriginalVector>::read_element_idx(row,reinterpret_cast<OriginalVector const &>(x)):
  365. scalar_traits<scalar_type>::value(0));
  366. }
  367. static
  368. BOOST_QVM_INLINE_CRITICAL
  369. scalar_type &
  370. write_element_idx( int row, int col, this_matrix const & x )
  371. {
  372. BOOST_QVM_ASSERT(row>=0);
  373. BOOST_QVM_ASSERT(row<rows);
  374. BOOST_QVM_ASSERT(col==cols-1);
  375. BOOST_QVM_ASSERT(col!=row);
  376. return vec_traits<OriginalVector>::write_element_idx(row,reinterpret_cast<OriginalVector &>(x));
  377. }
  378. };
  379. template <class OriginalVector,int R,int C>
  380. struct
  381. deduce_mat<qvm_detail::translation_mat_<OriginalVector>,R,C>
  382. {
  383. typedef mat<typename vec_traits<OriginalVector>::scalar_type,R,C> type;
  384. };
  385. template <class OriginalVector,int R,int C>
  386. struct
  387. deduce_mat2<qvm_detail::translation_mat_<OriginalVector>,qvm_detail::translation_mat_<OriginalVector>,R,C>
  388. {
  389. typedef mat<typename vec_traits<OriginalVector>::scalar_type,R,C> type;
  390. };
  391. template <class A>
  392. typename boost::enable_if_c<
  393. is_vec<A>::value,
  394. qvm_detail::translation_mat_<A> const &>::type
  395. BOOST_QVM_INLINE_TRIVIAL
  396. translation_mat( A const & a )
  397. {
  398. return reinterpret_cast<typename qvm_detail::translation_mat_<A> const &>(a);
  399. }
  400. template <class A>
  401. typename boost::enable_if_c<
  402. is_vec<A>::value,
  403. qvm_detail::translation_mat_<A> &>::type
  404. BOOST_QVM_INLINE_TRIVIAL
  405. translation_mat( A & a )
  406. {
  407. return reinterpret_cast<typename qvm_detail::translation_mat_<A> &>(a);
  408. }
  409. ////////////////////////////////////////////////
  410. namespace
  411. qvm_detail
  412. {
  413. template <class OriginalVector>
  414. class
  415. diag_mat_
  416. {
  417. diag_mat_( diag_mat_ const & );
  418. diag_mat_ & operator=( diag_mat_ const & );
  419. ~diag_mat_();
  420. public:
  421. template <class T>
  422. BOOST_QVM_INLINE_TRIVIAL
  423. diag_mat_ &
  424. operator=( T const & x )
  425. {
  426. assign(*this,x);
  427. return *this;
  428. }
  429. template <class R>
  430. BOOST_QVM_INLINE_TRIVIAL
  431. operator R() const
  432. {
  433. R r;
  434. assign(r,*this);
  435. return r;
  436. }
  437. };
  438. }
  439. template <class OriginalVector>
  440. struct
  441. mat_traits< qvm_detail::diag_mat_<OriginalVector> >
  442. {
  443. typedef qvm_detail::diag_mat_<OriginalVector> this_matrix;
  444. typedef typename vec_traits<OriginalVector>::scalar_type scalar_type;
  445. static int const rows=vec_traits<OriginalVector>::dim;
  446. static int const cols=vec_traits<OriginalVector>::dim;
  447. template <int Row,int Col>
  448. static
  449. BOOST_QVM_INLINE_CRITICAL
  450. scalar_type
  451. read_element( this_matrix const & x )
  452. {
  453. BOOST_QVM_STATIC_ASSERT(Row>=0);
  454. BOOST_QVM_STATIC_ASSERT(Row<rows);
  455. BOOST_QVM_STATIC_ASSERT(Col>=0);
  456. BOOST_QVM_STATIC_ASSERT(Col<cols);
  457. return Row==Col?vec_traits<OriginalVector>::template read_element<Row>(reinterpret_cast<OriginalVector const &>(x)):scalar_traits<scalar_type>::value(0);
  458. }
  459. template <int Row,int Col>
  460. static
  461. BOOST_QVM_INLINE_CRITICAL
  462. scalar_type &
  463. write_element( this_matrix & x )
  464. {
  465. BOOST_QVM_STATIC_ASSERT(Row>=0);
  466. BOOST_QVM_STATIC_ASSERT(Row<rows);
  467. BOOST_QVM_STATIC_ASSERT(Row==Col);
  468. return vec_traits<OriginalVector>::template write_element<Row>(reinterpret_cast<OriginalVector &>(x));
  469. }
  470. static
  471. BOOST_QVM_INLINE_CRITICAL
  472. scalar_type
  473. read_element_idx( int row, int col, this_matrix const & x )
  474. {
  475. BOOST_QVM_ASSERT(row>=0);
  476. BOOST_QVM_ASSERT(row<rows);
  477. BOOST_QVM_ASSERT(col>=0);
  478. BOOST_QVM_ASSERT(col<cols);
  479. return row==col?vec_traits<OriginalVector>::read_element_idx(row,reinterpret_cast<OriginalVector const &>(x)):scalar_traits<scalar_type>::value(0);
  480. }
  481. static
  482. BOOST_QVM_INLINE_CRITICAL
  483. scalar_type &
  484. write_element_idx( int row, int col, this_matrix & x )
  485. {
  486. BOOST_QVM_ASSERT(row>=0);
  487. BOOST_QVM_ASSERT(row<rows);
  488. BOOST_QVM_ASSERT(row==col);
  489. return vec_traits<OriginalVector>::write_element_idx(row,reinterpret_cast<OriginalVector &>(x));
  490. }
  491. };
  492. template <class OriginalVector,int R,int C>
  493. struct
  494. deduce_mat<qvm_detail::diag_mat_<OriginalVector>,R,C>
  495. {
  496. typedef mat<typename vec_traits<OriginalVector>::scalar_type,R,C> type;
  497. };
  498. template <class OriginalVector,int R,int C>
  499. struct
  500. deduce_mat2<qvm_detail::diag_mat_<OriginalVector>,qvm_detail::diag_mat_<OriginalVector>,R,C>
  501. {
  502. typedef mat<typename vec_traits<OriginalVector>::scalar_type,R,C> type;
  503. };
  504. template <class A>
  505. typename boost::enable_if_c<
  506. is_vec<A>::value,
  507. qvm_detail::diag_mat_<A> const &>::type
  508. BOOST_QVM_INLINE_TRIVIAL
  509. diag_mat( A const & a )
  510. {
  511. return reinterpret_cast<typename qvm_detail::diag_mat_<A> const &>(a);
  512. }
  513. template <class A>
  514. typename boost::enable_if_c<
  515. is_vec<A>::value,
  516. qvm_detail::diag_mat_<A> &>::type
  517. BOOST_QVM_INLINE_TRIVIAL
  518. diag_mat( A & a )
  519. {
  520. return reinterpret_cast<typename qvm_detail::diag_mat_<A> &>(a);
  521. }
  522. ////////////////////////////////////////////////
  523. }
  524. }
  525. #endif