mat_operations3.hpp 70 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915
  1. //Copyright (c) 2008-2017 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 BOOST_QVM_B3A6DB3C87C3E99245ED1C6B747DE
  5. #define BOOST_QVM_B3A6DB3C87C3E99245ED1C6B747DE
  6. //This file was generated by a program. Do not edit manually.
  7. #include <boost/qvm/assert.hpp>
  8. #include <boost/qvm/deduce_mat.hpp>
  9. #include <boost/qvm/deduce_vec.hpp>
  10. #include <boost/qvm/error.hpp>
  11. #include <boost/qvm/gen/mat_assign3.hpp>
  12. #include <boost/qvm/quat_traits.hpp>
  13. #include <boost/qvm/scalar_traits.hpp>
  14. #include <boost/qvm/throw_exception.hpp>
  15. namespace
  16. boost
  17. {
  18. namespace
  19. qvm
  20. {
  21. template <class A,class B>
  22. BOOST_QVM_INLINE_OPERATIONS
  23. typename lazy_enable_if_c<
  24. mat_traits<A>::rows==3 && mat_traits<B>::rows==3 &&
  25. mat_traits<A>::cols==3 && mat_traits<B>::cols==3,
  26. deduce_mat2<A,B,3,3> >::type
  27. operator+( A const & a, B const & b )
  28. {
  29. typedef typename deduce_mat2<A,B,3,3>::type R;
  30. BOOST_QVM_STATIC_ASSERT(mat_traits<R>::rows==3);
  31. BOOST_QVM_STATIC_ASSERT(mat_traits<R>::cols==3);
  32. R r;
  33. mat_traits<R>::template write_element<0,0>(r)=mat_traits<A>::template read_element<0,0>(a)+mat_traits<B>::template read_element<0,0>(b);
  34. mat_traits<R>::template write_element<0,1>(r)=mat_traits<A>::template read_element<0,1>(a)+mat_traits<B>::template read_element<0,1>(b);
  35. mat_traits<R>::template write_element<0,2>(r)=mat_traits<A>::template read_element<0,2>(a)+mat_traits<B>::template read_element<0,2>(b);
  36. mat_traits<R>::template write_element<1,0>(r)=mat_traits<A>::template read_element<1,0>(a)+mat_traits<B>::template read_element<1,0>(b);
  37. mat_traits<R>::template write_element<1,1>(r)=mat_traits<A>::template read_element<1,1>(a)+mat_traits<B>::template read_element<1,1>(b);
  38. mat_traits<R>::template write_element<1,2>(r)=mat_traits<A>::template read_element<1,2>(a)+mat_traits<B>::template read_element<1,2>(b);
  39. mat_traits<R>::template write_element<2,0>(r)=mat_traits<A>::template read_element<2,0>(a)+mat_traits<B>::template read_element<2,0>(b);
  40. mat_traits<R>::template write_element<2,1>(r)=mat_traits<A>::template read_element<2,1>(a)+mat_traits<B>::template read_element<2,1>(b);
  41. mat_traits<R>::template write_element<2,2>(r)=mat_traits<A>::template read_element<2,2>(a)+mat_traits<B>::template read_element<2,2>(b);
  42. return r;
  43. }
  44. namespace
  45. sfinae
  46. {
  47. using ::boost::qvm::operator+;
  48. }
  49. namespace
  50. qvm_detail
  51. {
  52. template <int R,int C>
  53. struct plus_mm_defined;
  54. template <>
  55. struct
  56. plus_mm_defined<3,3>
  57. {
  58. static bool const value=true;
  59. };
  60. }
  61. template <class A,class B>
  62. BOOST_QVM_INLINE_OPERATIONS
  63. typename lazy_enable_if_c<
  64. mat_traits<A>::rows==3 && mat_traits<B>::rows==3 &&
  65. mat_traits<A>::cols==1 && mat_traits<B>::cols==1,
  66. deduce_mat2<A,B,3,1> >::type
  67. operator+( A const & a, B const & b )
  68. {
  69. typedef typename deduce_mat2<A,B,3,1>::type R;
  70. BOOST_QVM_STATIC_ASSERT(mat_traits<R>::rows==3);
  71. BOOST_QVM_STATIC_ASSERT(mat_traits<R>::cols==1);
  72. R r;
  73. mat_traits<R>::template write_element<0,0>(r)=mat_traits<A>::template read_element<0,0>(a)+mat_traits<B>::template read_element<0,0>(b);
  74. mat_traits<R>::template write_element<1,0>(r)=mat_traits<A>::template read_element<1,0>(a)+mat_traits<B>::template read_element<1,0>(b);
  75. mat_traits<R>::template write_element<2,0>(r)=mat_traits<A>::template read_element<2,0>(a)+mat_traits<B>::template read_element<2,0>(b);
  76. return r;
  77. }
  78. namespace
  79. sfinae
  80. {
  81. using ::boost::qvm::operator+;
  82. }
  83. namespace
  84. qvm_detail
  85. {
  86. template <int R,int C>
  87. struct plus_mm_defined;
  88. template <>
  89. struct
  90. plus_mm_defined<3,1>
  91. {
  92. static bool const value=true;
  93. };
  94. }
  95. template <class A,class B>
  96. BOOST_QVM_INLINE_OPERATIONS
  97. typename lazy_enable_if_c<
  98. mat_traits<A>::rows==1 && mat_traits<B>::rows==1 &&
  99. mat_traits<A>::cols==3 && mat_traits<B>::cols==3,
  100. deduce_mat2<A,B,1,3> >::type
  101. operator+( A const & a, B const & b )
  102. {
  103. typedef typename deduce_mat2<A,B,1,3>::type R;
  104. BOOST_QVM_STATIC_ASSERT(mat_traits<R>::rows==1);
  105. BOOST_QVM_STATIC_ASSERT(mat_traits<R>::cols==3);
  106. R r;
  107. mat_traits<R>::template write_element<0,0>(r)=mat_traits<A>::template read_element<0,0>(a)+mat_traits<B>::template read_element<0,0>(b);
  108. mat_traits<R>::template write_element<0,1>(r)=mat_traits<A>::template read_element<0,1>(a)+mat_traits<B>::template read_element<0,1>(b);
  109. mat_traits<R>::template write_element<0,2>(r)=mat_traits<A>::template read_element<0,2>(a)+mat_traits<B>::template read_element<0,2>(b);
  110. return r;
  111. }
  112. namespace
  113. sfinae
  114. {
  115. using ::boost::qvm::operator+;
  116. }
  117. namespace
  118. qvm_detail
  119. {
  120. template <int R,int C>
  121. struct plus_mm_defined;
  122. template <>
  123. struct
  124. plus_mm_defined<1,3>
  125. {
  126. static bool const value=true;
  127. };
  128. }
  129. template <class A,class B>
  130. BOOST_QVM_INLINE_OPERATIONS
  131. typename lazy_enable_if_c<
  132. mat_traits<A>::rows==3 && mat_traits<B>::rows==3 &&
  133. mat_traits<A>::cols==3 && mat_traits<B>::cols==3,
  134. deduce_mat2<A,B,3,3> >::type
  135. operator-( A const & a, B const & b )
  136. {
  137. typedef typename deduce_mat2<A,B,3,3>::type R;
  138. BOOST_QVM_STATIC_ASSERT(mat_traits<R>::rows==3);
  139. BOOST_QVM_STATIC_ASSERT(mat_traits<R>::cols==3);
  140. R r;
  141. mat_traits<R>::template write_element<0,0>(r)=mat_traits<A>::template read_element<0,0>(a)-mat_traits<B>::template read_element<0,0>(b);
  142. mat_traits<R>::template write_element<0,1>(r)=mat_traits<A>::template read_element<0,1>(a)-mat_traits<B>::template read_element<0,1>(b);
  143. mat_traits<R>::template write_element<0,2>(r)=mat_traits<A>::template read_element<0,2>(a)-mat_traits<B>::template read_element<0,2>(b);
  144. mat_traits<R>::template write_element<1,0>(r)=mat_traits<A>::template read_element<1,0>(a)-mat_traits<B>::template read_element<1,0>(b);
  145. mat_traits<R>::template write_element<1,1>(r)=mat_traits<A>::template read_element<1,1>(a)-mat_traits<B>::template read_element<1,1>(b);
  146. mat_traits<R>::template write_element<1,2>(r)=mat_traits<A>::template read_element<1,2>(a)-mat_traits<B>::template read_element<1,2>(b);
  147. mat_traits<R>::template write_element<2,0>(r)=mat_traits<A>::template read_element<2,0>(a)-mat_traits<B>::template read_element<2,0>(b);
  148. mat_traits<R>::template write_element<2,1>(r)=mat_traits<A>::template read_element<2,1>(a)-mat_traits<B>::template read_element<2,1>(b);
  149. mat_traits<R>::template write_element<2,2>(r)=mat_traits<A>::template read_element<2,2>(a)-mat_traits<B>::template read_element<2,2>(b);
  150. return r;
  151. }
  152. namespace
  153. sfinae
  154. {
  155. using ::boost::qvm::operator-;
  156. }
  157. namespace
  158. qvm_detail
  159. {
  160. template <int R,int C>
  161. struct minus_mm_defined;
  162. template <>
  163. struct
  164. minus_mm_defined<3,3>
  165. {
  166. static bool const value=true;
  167. };
  168. }
  169. template <class A,class B>
  170. BOOST_QVM_INLINE_OPERATIONS
  171. typename lazy_enable_if_c<
  172. mat_traits<A>::rows==3 && mat_traits<B>::rows==3 &&
  173. mat_traits<A>::cols==1 && mat_traits<B>::cols==1,
  174. deduce_mat2<A,B,3,1> >::type
  175. operator-( A const & a, B const & b )
  176. {
  177. typedef typename deduce_mat2<A,B,3,1>::type R;
  178. BOOST_QVM_STATIC_ASSERT(mat_traits<R>::rows==3);
  179. BOOST_QVM_STATIC_ASSERT(mat_traits<R>::cols==1);
  180. R r;
  181. mat_traits<R>::template write_element<0,0>(r)=mat_traits<A>::template read_element<0,0>(a)-mat_traits<B>::template read_element<0,0>(b);
  182. mat_traits<R>::template write_element<1,0>(r)=mat_traits<A>::template read_element<1,0>(a)-mat_traits<B>::template read_element<1,0>(b);
  183. mat_traits<R>::template write_element<2,0>(r)=mat_traits<A>::template read_element<2,0>(a)-mat_traits<B>::template read_element<2,0>(b);
  184. return r;
  185. }
  186. namespace
  187. sfinae
  188. {
  189. using ::boost::qvm::operator-;
  190. }
  191. namespace
  192. qvm_detail
  193. {
  194. template <int R,int C>
  195. struct minus_mm_defined;
  196. template <>
  197. struct
  198. minus_mm_defined<3,1>
  199. {
  200. static bool const value=true;
  201. };
  202. }
  203. template <class A,class B>
  204. BOOST_QVM_INLINE_OPERATIONS
  205. typename lazy_enable_if_c<
  206. mat_traits<A>::rows==1 && mat_traits<B>::rows==1 &&
  207. mat_traits<A>::cols==3 && mat_traits<B>::cols==3,
  208. deduce_mat2<A,B,1,3> >::type
  209. operator-( A const & a, B const & b )
  210. {
  211. typedef typename deduce_mat2<A,B,1,3>::type R;
  212. BOOST_QVM_STATIC_ASSERT(mat_traits<R>::rows==1);
  213. BOOST_QVM_STATIC_ASSERT(mat_traits<R>::cols==3);
  214. R r;
  215. mat_traits<R>::template write_element<0,0>(r)=mat_traits<A>::template read_element<0,0>(a)-mat_traits<B>::template read_element<0,0>(b);
  216. mat_traits<R>::template write_element<0,1>(r)=mat_traits<A>::template read_element<0,1>(a)-mat_traits<B>::template read_element<0,1>(b);
  217. mat_traits<R>::template write_element<0,2>(r)=mat_traits<A>::template read_element<0,2>(a)-mat_traits<B>::template read_element<0,2>(b);
  218. return r;
  219. }
  220. namespace
  221. sfinae
  222. {
  223. using ::boost::qvm::operator-;
  224. }
  225. namespace
  226. qvm_detail
  227. {
  228. template <int R,int C>
  229. struct minus_mm_defined;
  230. template <>
  231. struct
  232. minus_mm_defined<1,3>
  233. {
  234. static bool const value=true;
  235. };
  236. }
  237. template <class A,class B>
  238. BOOST_QVM_INLINE_OPERATIONS
  239. typename enable_if_c<
  240. mat_traits<A>::rows==3 && mat_traits<B>::rows==3 &&
  241. mat_traits<A>::cols==3 && mat_traits<B>::cols==3,
  242. A &>::type
  243. operator+=( A & a, B const & b )
  244. {
  245. mat_traits<A>::template write_element<0,0>(a)+=mat_traits<B>::template read_element<0,0>(b);
  246. mat_traits<A>::template write_element<0,1>(a)+=mat_traits<B>::template read_element<0,1>(b);
  247. mat_traits<A>::template write_element<0,2>(a)+=mat_traits<B>::template read_element<0,2>(b);
  248. mat_traits<A>::template write_element<1,0>(a)+=mat_traits<B>::template read_element<1,0>(b);
  249. mat_traits<A>::template write_element<1,1>(a)+=mat_traits<B>::template read_element<1,1>(b);
  250. mat_traits<A>::template write_element<1,2>(a)+=mat_traits<B>::template read_element<1,2>(b);
  251. mat_traits<A>::template write_element<2,0>(a)+=mat_traits<B>::template read_element<2,0>(b);
  252. mat_traits<A>::template write_element<2,1>(a)+=mat_traits<B>::template read_element<2,1>(b);
  253. mat_traits<A>::template write_element<2,2>(a)+=mat_traits<B>::template read_element<2,2>(b);
  254. return a;
  255. }
  256. namespace
  257. sfinae
  258. {
  259. using ::boost::qvm::operator+=;
  260. }
  261. namespace
  262. qvm_detail
  263. {
  264. template <int R,int C>
  265. struct plus_eq_mm_defined;
  266. template <>
  267. struct
  268. plus_eq_mm_defined<3,3>
  269. {
  270. static bool const value=true;
  271. };
  272. }
  273. template <class A,class B>
  274. BOOST_QVM_INLINE_OPERATIONS
  275. typename enable_if_c<
  276. mat_traits<A>::rows==3 && mat_traits<B>::rows==3 &&
  277. mat_traits<A>::cols==1 && mat_traits<B>::cols==1,
  278. A &>::type
  279. operator+=( A & a, B const & b )
  280. {
  281. mat_traits<A>::template write_element<0,0>(a)+=mat_traits<B>::template read_element<0,0>(b);
  282. mat_traits<A>::template write_element<1,0>(a)+=mat_traits<B>::template read_element<1,0>(b);
  283. mat_traits<A>::template write_element<2,0>(a)+=mat_traits<B>::template read_element<2,0>(b);
  284. return a;
  285. }
  286. namespace
  287. sfinae
  288. {
  289. using ::boost::qvm::operator+=;
  290. }
  291. namespace
  292. qvm_detail
  293. {
  294. template <int R,int C>
  295. struct plus_eq_mm_defined;
  296. template <>
  297. struct
  298. plus_eq_mm_defined<3,1>
  299. {
  300. static bool const value=true;
  301. };
  302. }
  303. template <class A,class B>
  304. BOOST_QVM_INLINE_OPERATIONS
  305. typename enable_if_c<
  306. mat_traits<A>::rows==1 && mat_traits<B>::rows==1 &&
  307. mat_traits<A>::cols==3 && mat_traits<B>::cols==3,
  308. A &>::type
  309. operator+=( A & a, B const & b )
  310. {
  311. mat_traits<A>::template write_element<0,0>(a)+=mat_traits<B>::template read_element<0,0>(b);
  312. mat_traits<A>::template write_element<0,1>(a)+=mat_traits<B>::template read_element<0,1>(b);
  313. mat_traits<A>::template write_element<0,2>(a)+=mat_traits<B>::template read_element<0,2>(b);
  314. return a;
  315. }
  316. namespace
  317. sfinae
  318. {
  319. using ::boost::qvm::operator+=;
  320. }
  321. namespace
  322. qvm_detail
  323. {
  324. template <int R,int C>
  325. struct plus_eq_mm_defined;
  326. template <>
  327. struct
  328. plus_eq_mm_defined<1,3>
  329. {
  330. static bool const value=true;
  331. };
  332. }
  333. template <class A,class B>
  334. BOOST_QVM_INLINE_OPERATIONS
  335. typename enable_if_c<
  336. mat_traits<A>::rows==3 && mat_traits<B>::rows==3 &&
  337. mat_traits<A>::cols==3 && mat_traits<B>::cols==3,
  338. A &>::type
  339. operator-=( A & a, B const & b )
  340. {
  341. mat_traits<A>::template write_element<0,0>(a)-=mat_traits<B>::template read_element<0,0>(b);
  342. mat_traits<A>::template write_element<0,1>(a)-=mat_traits<B>::template read_element<0,1>(b);
  343. mat_traits<A>::template write_element<0,2>(a)-=mat_traits<B>::template read_element<0,2>(b);
  344. mat_traits<A>::template write_element<1,0>(a)-=mat_traits<B>::template read_element<1,0>(b);
  345. mat_traits<A>::template write_element<1,1>(a)-=mat_traits<B>::template read_element<1,1>(b);
  346. mat_traits<A>::template write_element<1,2>(a)-=mat_traits<B>::template read_element<1,2>(b);
  347. mat_traits<A>::template write_element<2,0>(a)-=mat_traits<B>::template read_element<2,0>(b);
  348. mat_traits<A>::template write_element<2,1>(a)-=mat_traits<B>::template read_element<2,1>(b);
  349. mat_traits<A>::template write_element<2,2>(a)-=mat_traits<B>::template read_element<2,2>(b);
  350. return a;
  351. }
  352. namespace
  353. sfinae
  354. {
  355. using ::boost::qvm::operator-=;
  356. }
  357. namespace
  358. qvm_detail
  359. {
  360. template <int R,int C>
  361. struct minus_eq_mm_defined;
  362. template <>
  363. struct
  364. minus_eq_mm_defined<3,3>
  365. {
  366. static bool const value=true;
  367. };
  368. }
  369. template <class A,class B>
  370. BOOST_QVM_INLINE_OPERATIONS
  371. typename enable_if_c<
  372. mat_traits<A>::rows==3 && mat_traits<B>::rows==3 &&
  373. mat_traits<A>::cols==1 && mat_traits<B>::cols==1,
  374. A &>::type
  375. operator-=( A & a, B const & b )
  376. {
  377. mat_traits<A>::template write_element<0,0>(a)-=mat_traits<B>::template read_element<0,0>(b);
  378. mat_traits<A>::template write_element<1,0>(a)-=mat_traits<B>::template read_element<1,0>(b);
  379. mat_traits<A>::template write_element<2,0>(a)-=mat_traits<B>::template read_element<2,0>(b);
  380. return a;
  381. }
  382. namespace
  383. sfinae
  384. {
  385. using ::boost::qvm::operator-=;
  386. }
  387. namespace
  388. qvm_detail
  389. {
  390. template <int R,int C>
  391. struct minus_eq_mm_defined;
  392. template <>
  393. struct
  394. minus_eq_mm_defined<3,1>
  395. {
  396. static bool const value=true;
  397. };
  398. }
  399. template <class A,class B>
  400. BOOST_QVM_INLINE_OPERATIONS
  401. typename enable_if_c<
  402. mat_traits<A>::rows==1 && mat_traits<B>::rows==1 &&
  403. mat_traits<A>::cols==3 && mat_traits<B>::cols==3,
  404. A &>::type
  405. operator-=( A & a, B const & b )
  406. {
  407. mat_traits<A>::template write_element<0,0>(a)-=mat_traits<B>::template read_element<0,0>(b);
  408. mat_traits<A>::template write_element<0,1>(a)-=mat_traits<B>::template read_element<0,1>(b);
  409. mat_traits<A>::template write_element<0,2>(a)-=mat_traits<B>::template read_element<0,2>(b);
  410. return a;
  411. }
  412. namespace
  413. sfinae
  414. {
  415. using ::boost::qvm::operator-=;
  416. }
  417. namespace
  418. qvm_detail
  419. {
  420. template <int R,int C>
  421. struct minus_eq_mm_defined;
  422. template <>
  423. struct
  424. minus_eq_mm_defined<1,3>
  425. {
  426. static bool const value=true;
  427. };
  428. }
  429. template <class A,class B>
  430. BOOST_QVM_INLINE_OPERATIONS
  431. typename lazy_enable_if_c<
  432. mat_traits<A>::rows==3 && mat_traits<A>::cols==3 && is_scalar<B>::value,
  433. deduce_mat<A> >::type
  434. operator*( A const & a, B b )
  435. {
  436. typedef typename deduce_mat<A>::type R;
  437. R r;
  438. mat_traits<R>::template write_element<0,0>(r)=mat_traits<A>::template read_element<0,0>(a)*b;
  439. mat_traits<R>::template write_element<0,1>(r)=mat_traits<A>::template read_element<0,1>(a)*b;
  440. mat_traits<R>::template write_element<0,2>(r)=mat_traits<A>::template read_element<0,2>(a)*b;
  441. mat_traits<R>::template write_element<1,0>(r)=mat_traits<A>::template read_element<1,0>(a)*b;
  442. mat_traits<R>::template write_element<1,1>(r)=mat_traits<A>::template read_element<1,1>(a)*b;
  443. mat_traits<R>::template write_element<1,2>(r)=mat_traits<A>::template read_element<1,2>(a)*b;
  444. mat_traits<R>::template write_element<2,0>(r)=mat_traits<A>::template read_element<2,0>(a)*b;
  445. mat_traits<R>::template write_element<2,1>(r)=mat_traits<A>::template read_element<2,1>(a)*b;
  446. mat_traits<R>::template write_element<2,2>(r)=mat_traits<A>::template read_element<2,2>(a)*b;
  447. return r;
  448. }
  449. namespace
  450. sfinae
  451. {
  452. using ::boost::qvm::operator*;
  453. }
  454. namespace
  455. qvm_detail
  456. {
  457. template <int R,int C>
  458. struct mul_ms_defined;
  459. template <>
  460. struct
  461. mul_ms_defined<3,3>
  462. {
  463. static bool const value=true;
  464. };
  465. }
  466. template <class A,class B>
  467. BOOST_QVM_INLINE_OPERATIONS
  468. typename lazy_enable_if_c<
  469. is_scalar<A>::value && mat_traits<B>::rows==3 && mat_traits<B>::cols==3,
  470. deduce_mat<B> >::type
  471. operator*( A a, B const & b )
  472. {
  473. typedef typename deduce_mat<B>::type R;
  474. R r;
  475. mat_traits<R>::template write_element<0,0>(r)=a*mat_traits<B>::template read_element<0,0>(b);
  476. mat_traits<R>::template write_element<0,1>(r)=a*mat_traits<B>::template read_element<0,1>(b);
  477. mat_traits<R>::template write_element<0,2>(r)=a*mat_traits<B>::template read_element<0,2>(b);
  478. mat_traits<R>::template write_element<1,0>(r)=a*mat_traits<B>::template read_element<1,0>(b);
  479. mat_traits<R>::template write_element<1,1>(r)=a*mat_traits<B>::template read_element<1,1>(b);
  480. mat_traits<R>::template write_element<1,2>(r)=a*mat_traits<B>::template read_element<1,2>(b);
  481. mat_traits<R>::template write_element<2,0>(r)=a*mat_traits<B>::template read_element<2,0>(b);
  482. mat_traits<R>::template write_element<2,1>(r)=a*mat_traits<B>::template read_element<2,1>(b);
  483. mat_traits<R>::template write_element<2,2>(r)=a*mat_traits<B>::template read_element<2,2>(b);
  484. return r;
  485. }
  486. namespace
  487. sfinae
  488. {
  489. using ::boost::qvm::operator*;
  490. }
  491. namespace
  492. qvm_detail
  493. {
  494. template <int R,int C>
  495. struct mul_sm_defined;
  496. template <>
  497. struct
  498. mul_sm_defined<3,3>
  499. {
  500. static bool const value=true;
  501. };
  502. }
  503. template <class A,class B>
  504. BOOST_QVM_INLINE_OPERATIONS
  505. typename lazy_enable_if_c<
  506. mat_traits<A>::rows==3 && mat_traits<A>::cols==1 && is_scalar<B>::value,
  507. deduce_mat<A> >::type
  508. operator*( A const & a, B b )
  509. {
  510. typedef typename deduce_mat<A>::type R;
  511. R r;
  512. mat_traits<R>::template write_element<0,0>(r)=mat_traits<A>::template read_element<0,0>(a)*b;
  513. mat_traits<R>::template write_element<1,0>(r)=mat_traits<A>::template read_element<1,0>(a)*b;
  514. mat_traits<R>::template write_element<2,0>(r)=mat_traits<A>::template read_element<2,0>(a)*b;
  515. return r;
  516. }
  517. namespace
  518. sfinae
  519. {
  520. using ::boost::qvm::operator*;
  521. }
  522. namespace
  523. qvm_detail
  524. {
  525. template <int R,int C>
  526. struct mul_ms_defined;
  527. template <>
  528. struct
  529. mul_ms_defined<3,1>
  530. {
  531. static bool const value=true;
  532. };
  533. }
  534. template <class A,class B>
  535. BOOST_QVM_INLINE_OPERATIONS
  536. typename lazy_enable_if_c<
  537. is_scalar<A>::value && mat_traits<B>::rows==3 && mat_traits<B>::cols==1,
  538. deduce_mat<B> >::type
  539. operator*( A a, B const & b )
  540. {
  541. typedef typename deduce_mat<B>::type R;
  542. R r;
  543. mat_traits<R>::template write_element<0,0>(r)=a*mat_traits<B>::template read_element<0,0>(b);
  544. mat_traits<R>::template write_element<1,0>(r)=a*mat_traits<B>::template read_element<1,0>(b);
  545. mat_traits<R>::template write_element<2,0>(r)=a*mat_traits<B>::template read_element<2,0>(b);
  546. return r;
  547. }
  548. namespace
  549. sfinae
  550. {
  551. using ::boost::qvm::operator*;
  552. }
  553. namespace
  554. qvm_detail
  555. {
  556. template <int R,int C>
  557. struct mul_sm_defined;
  558. template <>
  559. struct
  560. mul_sm_defined<3,1>
  561. {
  562. static bool const value=true;
  563. };
  564. }
  565. template <class A,class B>
  566. BOOST_QVM_INLINE_OPERATIONS
  567. typename lazy_enable_if_c<
  568. mat_traits<A>::rows==1 && mat_traits<A>::cols==3 && is_scalar<B>::value,
  569. deduce_mat<A> >::type
  570. operator*( A const & a, B b )
  571. {
  572. typedef typename deduce_mat<A>::type R;
  573. R r;
  574. mat_traits<R>::template write_element<0,0>(r)=mat_traits<A>::template read_element<0,0>(a)*b;
  575. mat_traits<R>::template write_element<0,1>(r)=mat_traits<A>::template read_element<0,1>(a)*b;
  576. mat_traits<R>::template write_element<0,2>(r)=mat_traits<A>::template read_element<0,2>(a)*b;
  577. return r;
  578. }
  579. namespace
  580. sfinae
  581. {
  582. using ::boost::qvm::operator*;
  583. }
  584. namespace
  585. qvm_detail
  586. {
  587. template <int R,int C>
  588. struct mul_ms_defined;
  589. template <>
  590. struct
  591. mul_ms_defined<1,3>
  592. {
  593. static bool const value=true;
  594. };
  595. }
  596. template <class A,class B>
  597. BOOST_QVM_INLINE_OPERATIONS
  598. typename lazy_enable_if_c<
  599. is_scalar<A>::value && mat_traits<B>::rows==1 && mat_traits<B>::cols==3,
  600. deduce_mat<B> >::type
  601. operator*( A a, B const & b )
  602. {
  603. typedef typename deduce_mat<B>::type R;
  604. R r;
  605. mat_traits<R>::template write_element<0,0>(r)=a*mat_traits<B>::template read_element<0,0>(b);
  606. mat_traits<R>::template write_element<0,1>(r)=a*mat_traits<B>::template read_element<0,1>(b);
  607. mat_traits<R>::template write_element<0,2>(r)=a*mat_traits<B>::template read_element<0,2>(b);
  608. return r;
  609. }
  610. namespace
  611. sfinae
  612. {
  613. using ::boost::qvm::operator*;
  614. }
  615. namespace
  616. qvm_detail
  617. {
  618. template <int R,int C>
  619. struct mul_sm_defined;
  620. template <>
  621. struct
  622. mul_sm_defined<1,3>
  623. {
  624. static bool const value=true;
  625. };
  626. }
  627. template <class A,class B>
  628. BOOST_QVM_INLINE_OPERATIONS
  629. typename enable_if_c<
  630. mat_traits<A>::rows==3 && mat_traits<A>::cols==3 && is_scalar<B>::value,
  631. A &>::type
  632. operator*=( A & a, B b )
  633. {
  634. mat_traits<A>::template write_element<0,0>(a)*=b;
  635. mat_traits<A>::template write_element<0,1>(a)*=b;
  636. mat_traits<A>::template write_element<0,2>(a)*=b;
  637. mat_traits<A>::template write_element<1,0>(a)*=b;
  638. mat_traits<A>::template write_element<1,1>(a)*=b;
  639. mat_traits<A>::template write_element<1,2>(a)*=b;
  640. mat_traits<A>::template write_element<2,0>(a)*=b;
  641. mat_traits<A>::template write_element<2,1>(a)*=b;
  642. mat_traits<A>::template write_element<2,2>(a)*=b;
  643. return a;
  644. }
  645. namespace
  646. sfinae
  647. {
  648. using ::boost::qvm::operator*=;
  649. }
  650. namespace
  651. qvm_detail
  652. {
  653. template <int R,int C>
  654. struct mul_eq_ms_defined;
  655. template <>
  656. struct
  657. mul_eq_ms_defined<3,3>
  658. {
  659. static bool const value=true;
  660. };
  661. }
  662. template <class A,class B>
  663. BOOST_QVM_INLINE_OPERATIONS
  664. typename enable_if_c<
  665. mat_traits<A>::rows==3 && mat_traits<A>::cols==1 && is_scalar<B>::value,
  666. A &>::type
  667. operator*=( A & a, B b )
  668. {
  669. mat_traits<A>::template write_element<0,0>(a)*=b;
  670. mat_traits<A>::template write_element<1,0>(a)*=b;
  671. mat_traits<A>::template write_element<2,0>(a)*=b;
  672. return a;
  673. }
  674. namespace
  675. sfinae
  676. {
  677. using ::boost::qvm::operator*=;
  678. }
  679. namespace
  680. qvm_detail
  681. {
  682. template <int R,int C>
  683. struct mul_eq_ms_defined;
  684. template <>
  685. struct
  686. mul_eq_ms_defined<3,1>
  687. {
  688. static bool const value=true;
  689. };
  690. }
  691. template <class A,class B>
  692. BOOST_QVM_INLINE_OPERATIONS
  693. typename enable_if_c<
  694. mat_traits<A>::rows==1 && mat_traits<A>::cols==3 && is_scalar<B>::value,
  695. A &>::type
  696. operator*=( A & a, B b )
  697. {
  698. mat_traits<A>::template write_element<0,0>(a)*=b;
  699. mat_traits<A>::template write_element<0,1>(a)*=b;
  700. mat_traits<A>::template write_element<0,2>(a)*=b;
  701. return a;
  702. }
  703. namespace
  704. sfinae
  705. {
  706. using ::boost::qvm::operator*=;
  707. }
  708. namespace
  709. qvm_detail
  710. {
  711. template <int R,int C>
  712. struct mul_eq_ms_defined;
  713. template <>
  714. struct
  715. mul_eq_ms_defined<1,3>
  716. {
  717. static bool const value=true;
  718. };
  719. }
  720. template <class A,class B>
  721. BOOST_QVM_INLINE_OPERATIONS
  722. typename lazy_enable_if_c<
  723. mat_traits<A>::rows==3 && mat_traits<A>::cols==3 && is_scalar<B>::value,
  724. deduce_mat<A> >::type
  725. operator/( A const & a, B b )
  726. {
  727. typedef typename deduce_mat<A>::type R;
  728. R r;
  729. mat_traits<R>::template write_element<0,0>(r)=mat_traits<A>::template read_element<0,0>(a)/b;
  730. mat_traits<R>::template write_element<0,1>(r)=mat_traits<A>::template read_element<0,1>(a)/b;
  731. mat_traits<R>::template write_element<0,2>(r)=mat_traits<A>::template read_element<0,2>(a)/b;
  732. mat_traits<R>::template write_element<1,0>(r)=mat_traits<A>::template read_element<1,0>(a)/b;
  733. mat_traits<R>::template write_element<1,1>(r)=mat_traits<A>::template read_element<1,1>(a)/b;
  734. mat_traits<R>::template write_element<1,2>(r)=mat_traits<A>::template read_element<1,2>(a)/b;
  735. mat_traits<R>::template write_element<2,0>(r)=mat_traits<A>::template read_element<2,0>(a)/b;
  736. mat_traits<R>::template write_element<2,1>(r)=mat_traits<A>::template read_element<2,1>(a)/b;
  737. mat_traits<R>::template write_element<2,2>(r)=mat_traits<A>::template read_element<2,2>(a)/b;
  738. return r;
  739. }
  740. namespace
  741. sfinae
  742. {
  743. using ::boost::qvm::operator/;
  744. }
  745. namespace
  746. qvm_detail
  747. {
  748. template <int R,int C>
  749. struct div_ms_defined;
  750. template <>
  751. struct
  752. div_ms_defined<3,3>
  753. {
  754. static bool const value=true;
  755. };
  756. }
  757. template <class A,class B>
  758. BOOST_QVM_INLINE_OPERATIONS
  759. typename lazy_enable_if_c<
  760. is_scalar<A>::value && mat_traits<B>::rows==3 && mat_traits<B>::cols==3,
  761. deduce_mat<B> >::type
  762. operator/( A a, B const & b )
  763. {
  764. typedef typename deduce_mat<B>::type R;
  765. R r;
  766. mat_traits<R>::template write_element<0,0>(r)=a/mat_traits<B>::template read_element<0,0>(b);
  767. mat_traits<R>::template write_element<0,1>(r)=a/mat_traits<B>::template read_element<0,1>(b);
  768. mat_traits<R>::template write_element<0,2>(r)=a/mat_traits<B>::template read_element<0,2>(b);
  769. mat_traits<R>::template write_element<1,0>(r)=a/mat_traits<B>::template read_element<1,0>(b);
  770. mat_traits<R>::template write_element<1,1>(r)=a/mat_traits<B>::template read_element<1,1>(b);
  771. mat_traits<R>::template write_element<1,2>(r)=a/mat_traits<B>::template read_element<1,2>(b);
  772. mat_traits<R>::template write_element<2,0>(r)=a/mat_traits<B>::template read_element<2,0>(b);
  773. mat_traits<R>::template write_element<2,1>(r)=a/mat_traits<B>::template read_element<2,1>(b);
  774. mat_traits<R>::template write_element<2,2>(r)=a/mat_traits<B>::template read_element<2,2>(b);
  775. return r;
  776. }
  777. namespace
  778. sfinae
  779. {
  780. using ::boost::qvm::operator/;
  781. }
  782. namespace
  783. qvm_detail
  784. {
  785. template <int R,int C>
  786. struct div_sm_defined;
  787. template <>
  788. struct
  789. div_sm_defined<3,3>
  790. {
  791. static bool const value=true;
  792. };
  793. }
  794. template <class A,class B>
  795. BOOST_QVM_INLINE_OPERATIONS
  796. typename lazy_enable_if_c<
  797. mat_traits<A>::rows==3 && mat_traits<A>::cols==1 && is_scalar<B>::value,
  798. deduce_mat<A> >::type
  799. operator/( A const & a, B b )
  800. {
  801. typedef typename deduce_mat<A>::type R;
  802. R r;
  803. mat_traits<R>::template write_element<0,0>(r)=mat_traits<A>::template read_element<0,0>(a)/b;
  804. mat_traits<R>::template write_element<1,0>(r)=mat_traits<A>::template read_element<1,0>(a)/b;
  805. mat_traits<R>::template write_element<2,0>(r)=mat_traits<A>::template read_element<2,0>(a)/b;
  806. return r;
  807. }
  808. namespace
  809. sfinae
  810. {
  811. using ::boost::qvm::operator/;
  812. }
  813. namespace
  814. qvm_detail
  815. {
  816. template <int R,int C>
  817. struct div_ms_defined;
  818. template <>
  819. struct
  820. div_ms_defined<3,1>
  821. {
  822. static bool const value=true;
  823. };
  824. }
  825. template <class A,class B>
  826. BOOST_QVM_INLINE_OPERATIONS
  827. typename lazy_enable_if_c<
  828. is_scalar<A>::value && mat_traits<B>::rows==3 && mat_traits<B>::cols==1,
  829. deduce_mat<B> >::type
  830. operator/( A a, B const & b )
  831. {
  832. typedef typename deduce_mat<B>::type R;
  833. R r;
  834. mat_traits<R>::template write_element<0,0>(r)=a/mat_traits<B>::template read_element<0,0>(b);
  835. mat_traits<R>::template write_element<1,0>(r)=a/mat_traits<B>::template read_element<1,0>(b);
  836. mat_traits<R>::template write_element<2,0>(r)=a/mat_traits<B>::template read_element<2,0>(b);
  837. return r;
  838. }
  839. namespace
  840. sfinae
  841. {
  842. using ::boost::qvm::operator/;
  843. }
  844. namespace
  845. qvm_detail
  846. {
  847. template <int R,int C>
  848. struct div_sm_defined;
  849. template <>
  850. struct
  851. div_sm_defined<3,1>
  852. {
  853. static bool const value=true;
  854. };
  855. }
  856. template <class A,class B>
  857. BOOST_QVM_INLINE_OPERATIONS
  858. typename lazy_enable_if_c<
  859. mat_traits<A>::rows==1 && mat_traits<A>::cols==3 && is_scalar<B>::value,
  860. deduce_mat<A> >::type
  861. operator/( A const & a, B b )
  862. {
  863. typedef typename deduce_mat<A>::type R;
  864. R r;
  865. mat_traits<R>::template write_element<0,0>(r)=mat_traits<A>::template read_element<0,0>(a)/b;
  866. mat_traits<R>::template write_element<0,1>(r)=mat_traits<A>::template read_element<0,1>(a)/b;
  867. mat_traits<R>::template write_element<0,2>(r)=mat_traits<A>::template read_element<0,2>(a)/b;
  868. return r;
  869. }
  870. namespace
  871. sfinae
  872. {
  873. using ::boost::qvm::operator/;
  874. }
  875. namespace
  876. qvm_detail
  877. {
  878. template <int R,int C>
  879. struct div_ms_defined;
  880. template <>
  881. struct
  882. div_ms_defined<1,3>
  883. {
  884. static bool const value=true;
  885. };
  886. }
  887. template <class A,class B>
  888. BOOST_QVM_INLINE_OPERATIONS
  889. typename enable_if_c<
  890. mat_traits<A>::rows==3 && mat_traits<A>::cols==3 && is_scalar<B>::value,
  891. A &>::type
  892. operator/=( A & a, B b )
  893. {
  894. mat_traits<A>::template write_element<0,0>(a)/=b;
  895. mat_traits<A>::template write_element<0,1>(a)/=b;
  896. mat_traits<A>::template write_element<0,2>(a)/=b;
  897. mat_traits<A>::template write_element<1,0>(a)/=b;
  898. mat_traits<A>::template write_element<1,1>(a)/=b;
  899. mat_traits<A>::template write_element<1,2>(a)/=b;
  900. mat_traits<A>::template write_element<2,0>(a)/=b;
  901. mat_traits<A>::template write_element<2,1>(a)/=b;
  902. mat_traits<A>::template write_element<2,2>(a)/=b;
  903. return a;
  904. }
  905. namespace
  906. sfinae
  907. {
  908. using ::boost::qvm::operator/=;
  909. }
  910. namespace
  911. qvm_detail
  912. {
  913. template <int R,int C>
  914. struct div_eq_ms_defined;
  915. template <>
  916. struct
  917. div_eq_ms_defined<3,3>
  918. {
  919. static bool const value=true;
  920. };
  921. }
  922. template <class A,class B>
  923. BOOST_QVM_INLINE_OPERATIONS
  924. typename enable_if_c<
  925. mat_traits<A>::rows==3 && mat_traits<A>::cols==1 && is_scalar<B>::value,
  926. A &>::type
  927. operator/=( A & a, B b )
  928. {
  929. mat_traits<A>::template write_element<0,0>(a)/=b;
  930. mat_traits<A>::template write_element<1,0>(a)/=b;
  931. mat_traits<A>::template write_element<2,0>(a)/=b;
  932. return a;
  933. }
  934. namespace
  935. sfinae
  936. {
  937. using ::boost::qvm::operator/=;
  938. }
  939. namespace
  940. qvm_detail
  941. {
  942. template <int R,int C>
  943. struct div_eq_ms_defined;
  944. template <>
  945. struct
  946. div_eq_ms_defined<3,1>
  947. {
  948. static bool const value=true;
  949. };
  950. }
  951. template <class A,class B>
  952. BOOST_QVM_INLINE_OPERATIONS
  953. typename enable_if_c<
  954. mat_traits<A>::rows==1 && mat_traits<A>::cols==3 && is_scalar<B>::value,
  955. A &>::type
  956. operator/=( A & a, B b )
  957. {
  958. mat_traits<A>::template write_element<0,0>(a)/=b;
  959. mat_traits<A>::template write_element<0,1>(a)/=b;
  960. mat_traits<A>::template write_element<0,2>(a)/=b;
  961. return a;
  962. }
  963. namespace
  964. sfinae
  965. {
  966. using ::boost::qvm::operator/=;
  967. }
  968. namespace
  969. qvm_detail
  970. {
  971. template <int R,int C>
  972. struct div_eq_ms_defined;
  973. template <>
  974. struct
  975. div_eq_ms_defined<1,3>
  976. {
  977. static bool const value=true;
  978. };
  979. }
  980. template <class R,class A>
  981. BOOST_QVM_INLINE_OPERATIONS
  982. typename enable_if_c<
  983. mat_traits<R>::rows==3 && mat_traits<A>::rows==3 &&
  984. mat_traits<R>::cols==3 && mat_traits<A>::cols==3,
  985. R>::type
  986. convert_to( A const & a )
  987. {
  988. R r;
  989. mat_traits<R>::template write_element<0,0>(r) = mat_traits<A>::template read_element<0,0>(a);
  990. mat_traits<R>::template write_element<0,1>(r) = mat_traits<A>::template read_element<0,1>(a);
  991. mat_traits<R>::template write_element<0,2>(r) = mat_traits<A>::template read_element<0,2>(a);
  992. mat_traits<R>::template write_element<1,0>(r) = mat_traits<A>::template read_element<1,0>(a);
  993. mat_traits<R>::template write_element<1,1>(r) = mat_traits<A>::template read_element<1,1>(a);
  994. mat_traits<R>::template write_element<1,2>(r) = mat_traits<A>::template read_element<1,2>(a);
  995. mat_traits<R>::template write_element<2,0>(r) = mat_traits<A>::template read_element<2,0>(a);
  996. mat_traits<R>::template write_element<2,1>(r) = mat_traits<A>::template read_element<2,1>(a);
  997. mat_traits<R>::template write_element<2,2>(r) = mat_traits<A>::template read_element<2,2>(a);
  998. return r;
  999. }
  1000. template <class R,class A>
  1001. BOOST_QVM_INLINE
  1002. typename enable_if_c<
  1003. is_mat<R>::value && is_quat<A>::value &&
  1004. mat_traits<R>::rows==3 && mat_traits<R>::cols==3,
  1005. R>::type
  1006. convert_to( A const & q )
  1007. {
  1008. typedef typename mat_traits<R>::scalar_type T;
  1009. T const a=quat_traits<A>::template read_element<0>(q);
  1010. T const b=quat_traits<A>::template read_element<1>(q);
  1011. T const c=quat_traits<A>::template read_element<2>(q);
  1012. T const d=quat_traits<A>::template read_element<3>(q);
  1013. T const bb = b*b;
  1014. T const cc = c*c;
  1015. T const dd = d*d;
  1016. T const bc = b*c;
  1017. T const bd = b*d;
  1018. T const cd = c*d;
  1019. T const ab = a*b;
  1020. T const ac = a*c;
  1021. T const ad = a*d;
  1022. T const one = scalar_traits<T>::value(1);
  1023. T const two = one+one;
  1024. R r;
  1025. mat_traits<R>::template write_element<0,0>(r) = one - two*(cc+dd);
  1026. mat_traits<R>::template write_element<0,1>(r) = two*(bc-ad);
  1027. mat_traits<R>::template write_element<0,2>(r) = two*(bd+ac);
  1028. mat_traits<R>::template write_element<1,0>(r) = two*(bc+ad);
  1029. mat_traits<R>::template write_element<1,1>(r) = one - two*(bb+dd);
  1030. mat_traits<R>::template write_element<1,2>(r) = two*(cd-ab);
  1031. mat_traits<R>::template write_element<2,0>(r) = two*(bd-ac);
  1032. mat_traits<R>::template write_element<2,1>(r) = two*(cd+ab);
  1033. mat_traits<R>::template write_element<2,2>(r) = one - two*(bb+cc);
  1034. return r;
  1035. }
  1036. namespace
  1037. sfinae
  1038. {
  1039. using ::boost::qvm::convert_to;
  1040. }
  1041. namespace
  1042. qvm_detail
  1043. {
  1044. template <int R,int C>
  1045. struct convert_to_m_defined;
  1046. template <>
  1047. struct
  1048. convert_to_m_defined<3,3>
  1049. {
  1050. static bool const value=true;
  1051. };
  1052. }
  1053. template <class R,class A>
  1054. BOOST_QVM_INLINE_OPERATIONS
  1055. typename enable_if_c<
  1056. mat_traits<R>::rows==3 && mat_traits<A>::rows==3 &&
  1057. mat_traits<R>::cols==1 && mat_traits<A>::cols==1,
  1058. R>::type
  1059. convert_to( A const & a )
  1060. {
  1061. R r;
  1062. mat_traits<R>::template write_element<0,0>(r) = mat_traits<A>::template read_element<0,0>(a);
  1063. mat_traits<R>::template write_element<1,0>(r) = mat_traits<A>::template read_element<1,0>(a);
  1064. mat_traits<R>::template write_element<2,0>(r) = mat_traits<A>::template read_element<2,0>(a);
  1065. return r;
  1066. }
  1067. namespace
  1068. sfinae
  1069. {
  1070. using ::boost::qvm::convert_to;
  1071. }
  1072. namespace
  1073. qvm_detail
  1074. {
  1075. template <int R,int C>
  1076. struct convert_to_m_defined;
  1077. template <>
  1078. struct
  1079. convert_to_m_defined<3,1>
  1080. {
  1081. static bool const value=true;
  1082. };
  1083. }
  1084. template <class R,class A>
  1085. BOOST_QVM_INLINE_OPERATIONS
  1086. typename enable_if_c<
  1087. mat_traits<R>::rows==1 && mat_traits<A>::rows==1 &&
  1088. mat_traits<R>::cols==3 && mat_traits<A>::cols==3,
  1089. R>::type
  1090. convert_to( A const & a )
  1091. {
  1092. R r;
  1093. mat_traits<R>::template write_element<0,0>(r) = mat_traits<A>::template read_element<0,0>(a);
  1094. mat_traits<R>::template write_element<0,1>(r) = mat_traits<A>::template read_element<0,1>(a);
  1095. mat_traits<R>::template write_element<0,2>(r) = mat_traits<A>::template read_element<0,2>(a);
  1096. return r;
  1097. }
  1098. namespace
  1099. sfinae
  1100. {
  1101. using ::boost::qvm::convert_to;
  1102. }
  1103. namespace
  1104. qvm_detail
  1105. {
  1106. template <int R,int C>
  1107. struct convert_to_m_defined;
  1108. template <>
  1109. struct
  1110. convert_to_m_defined<1,3>
  1111. {
  1112. static bool const value=true;
  1113. };
  1114. }
  1115. template <class A,class B>
  1116. BOOST_QVM_INLINE_OPERATIONS
  1117. typename enable_if_c<
  1118. mat_traits<A>::rows==3 && mat_traits<B>::rows==3 &&
  1119. mat_traits<A>::cols==3 && mat_traits<B>::cols==3,
  1120. bool>::type
  1121. operator==( A const & a, B const & b )
  1122. {
  1123. return
  1124. mat_traits<A>::template read_element<0,0>(a)==mat_traits<B>::template read_element<0,0>(b) &&
  1125. mat_traits<A>::template read_element<0,1>(a)==mat_traits<B>::template read_element<0,1>(b) &&
  1126. mat_traits<A>::template read_element<0,2>(a)==mat_traits<B>::template read_element<0,2>(b) &&
  1127. mat_traits<A>::template read_element<1,0>(a)==mat_traits<B>::template read_element<1,0>(b) &&
  1128. mat_traits<A>::template read_element<1,1>(a)==mat_traits<B>::template read_element<1,1>(b) &&
  1129. mat_traits<A>::template read_element<1,2>(a)==mat_traits<B>::template read_element<1,2>(b) &&
  1130. mat_traits<A>::template read_element<2,0>(a)==mat_traits<B>::template read_element<2,0>(b) &&
  1131. mat_traits<A>::template read_element<2,1>(a)==mat_traits<B>::template read_element<2,1>(b) &&
  1132. mat_traits<A>::template read_element<2,2>(a)==mat_traits<B>::template read_element<2,2>(b);
  1133. }
  1134. namespace
  1135. sfinae
  1136. {
  1137. using ::boost::qvm::operator==;
  1138. }
  1139. namespace
  1140. qvm_detail
  1141. {
  1142. template <int R,int C>
  1143. struct eq_mm_defined;
  1144. template <>
  1145. struct
  1146. eq_mm_defined<3,3>
  1147. {
  1148. static bool const value=true;
  1149. };
  1150. }
  1151. template <class A,class B>
  1152. BOOST_QVM_INLINE_OPERATIONS
  1153. typename enable_if_c<
  1154. mat_traits<A>::rows==3 && mat_traits<B>::rows==3 &&
  1155. mat_traits<A>::cols==1 && mat_traits<B>::cols==1,
  1156. bool>::type
  1157. operator==( A const & a, B const & b )
  1158. {
  1159. return
  1160. mat_traits<A>::template read_element<0,0>(a)==mat_traits<B>::template read_element<0,0>(b) &&
  1161. mat_traits<A>::template read_element<1,0>(a)==mat_traits<B>::template read_element<1,0>(b) &&
  1162. mat_traits<A>::template read_element<2,0>(a)==mat_traits<B>::template read_element<2,0>(b);
  1163. }
  1164. namespace
  1165. sfinae
  1166. {
  1167. using ::boost::qvm::operator==;
  1168. }
  1169. namespace
  1170. qvm_detail
  1171. {
  1172. template <int R,int C>
  1173. struct eq_mm_defined;
  1174. template <>
  1175. struct
  1176. eq_mm_defined<3,1>
  1177. {
  1178. static bool const value=true;
  1179. };
  1180. }
  1181. template <class A,class B>
  1182. BOOST_QVM_INLINE_OPERATIONS
  1183. typename enable_if_c<
  1184. mat_traits<A>::rows==1 && mat_traits<B>::rows==1 &&
  1185. mat_traits<A>::cols==3 && mat_traits<B>::cols==3,
  1186. bool>::type
  1187. operator==( A const & a, B const & b )
  1188. {
  1189. return
  1190. mat_traits<A>::template read_element<0,0>(a)==mat_traits<B>::template read_element<0,0>(b) &&
  1191. mat_traits<A>::template read_element<0,1>(a)==mat_traits<B>::template read_element<0,1>(b) &&
  1192. mat_traits<A>::template read_element<0,2>(a)==mat_traits<B>::template read_element<0,2>(b);
  1193. }
  1194. namespace
  1195. sfinae
  1196. {
  1197. using ::boost::qvm::operator==;
  1198. }
  1199. namespace
  1200. qvm_detail
  1201. {
  1202. template <int R,int C>
  1203. struct eq_mm_defined;
  1204. template <>
  1205. struct
  1206. eq_mm_defined<1,3>
  1207. {
  1208. static bool const value=true;
  1209. };
  1210. }
  1211. template <class A,class B>
  1212. BOOST_QVM_INLINE_OPERATIONS
  1213. typename enable_if_c<
  1214. mat_traits<A>::rows==3 && mat_traits<B>::rows==3 &&
  1215. mat_traits<A>::cols==3 && mat_traits<B>::cols==3,
  1216. bool>::type
  1217. operator!=( A const & a, B const & b )
  1218. {
  1219. return
  1220. !(mat_traits<A>::template read_element<0,0>(a)==mat_traits<B>::template read_element<0,0>(b)) ||
  1221. !(mat_traits<A>::template read_element<0,1>(a)==mat_traits<B>::template read_element<0,1>(b)) ||
  1222. !(mat_traits<A>::template read_element<0,2>(a)==mat_traits<B>::template read_element<0,2>(b)) ||
  1223. !(mat_traits<A>::template read_element<1,0>(a)==mat_traits<B>::template read_element<1,0>(b)) ||
  1224. !(mat_traits<A>::template read_element<1,1>(a)==mat_traits<B>::template read_element<1,1>(b)) ||
  1225. !(mat_traits<A>::template read_element<1,2>(a)==mat_traits<B>::template read_element<1,2>(b)) ||
  1226. !(mat_traits<A>::template read_element<2,0>(a)==mat_traits<B>::template read_element<2,0>(b)) ||
  1227. !(mat_traits<A>::template read_element<2,1>(a)==mat_traits<B>::template read_element<2,1>(b)) ||
  1228. !(mat_traits<A>::template read_element<2,2>(a)==mat_traits<B>::template read_element<2,2>(b));
  1229. }
  1230. namespace
  1231. sfinae
  1232. {
  1233. using ::boost::qvm::operator!=;
  1234. }
  1235. namespace
  1236. qvm_detail
  1237. {
  1238. template <int R,int C>
  1239. struct neq_mm_defined;
  1240. template <>
  1241. struct
  1242. neq_mm_defined<3,3>
  1243. {
  1244. static bool const value=true;
  1245. };
  1246. }
  1247. template <class A,class B>
  1248. BOOST_QVM_INLINE_OPERATIONS
  1249. typename enable_if_c<
  1250. mat_traits<A>::rows==3 && mat_traits<B>::rows==3 &&
  1251. mat_traits<A>::cols==1 && mat_traits<B>::cols==1,
  1252. bool>::type
  1253. operator!=( A const & a, B const & b )
  1254. {
  1255. return
  1256. !(mat_traits<A>::template read_element<0,0>(a)==mat_traits<B>::template read_element<0,0>(b)) ||
  1257. !(mat_traits<A>::template read_element<1,0>(a)==mat_traits<B>::template read_element<1,0>(b)) ||
  1258. !(mat_traits<A>::template read_element<2,0>(a)==mat_traits<B>::template read_element<2,0>(b));
  1259. }
  1260. namespace
  1261. sfinae
  1262. {
  1263. using ::boost::qvm::operator!=;
  1264. }
  1265. namespace
  1266. qvm_detail
  1267. {
  1268. template <int R,int C>
  1269. struct neq_mm_defined;
  1270. template <>
  1271. struct
  1272. neq_mm_defined<3,1>
  1273. {
  1274. static bool const value=true;
  1275. };
  1276. }
  1277. template <class A,class B>
  1278. BOOST_QVM_INLINE_OPERATIONS
  1279. typename enable_if_c<
  1280. mat_traits<A>::rows==1 && mat_traits<B>::rows==1 &&
  1281. mat_traits<A>::cols==3 && mat_traits<B>::cols==3,
  1282. bool>::type
  1283. operator!=( A const & a, B const & b )
  1284. {
  1285. return
  1286. !(mat_traits<A>::template read_element<0,0>(a)==mat_traits<B>::template read_element<0,0>(b)) ||
  1287. !(mat_traits<A>::template read_element<0,1>(a)==mat_traits<B>::template read_element<0,1>(b)) ||
  1288. !(mat_traits<A>::template read_element<0,2>(a)==mat_traits<B>::template read_element<0,2>(b));
  1289. }
  1290. namespace
  1291. sfinae
  1292. {
  1293. using ::boost::qvm::operator!=;
  1294. }
  1295. namespace
  1296. qvm_detail
  1297. {
  1298. template <int R,int C>
  1299. struct neq_mm_defined;
  1300. template <>
  1301. struct
  1302. neq_mm_defined<1,3>
  1303. {
  1304. static bool const value=true;
  1305. };
  1306. }
  1307. template <class A>
  1308. BOOST_QVM_INLINE_OPERATIONS
  1309. typename lazy_enable_if_c<
  1310. mat_traits<A>::rows==3 && mat_traits<A>::cols==3,
  1311. deduce_mat<A> >::type
  1312. operator-( A const & a )
  1313. {
  1314. typedef typename deduce_mat<A>::type R;
  1315. R r;
  1316. mat_traits<R>::template write_element<0,0>(r)=-mat_traits<A>::template read_element<0,0>(a);
  1317. mat_traits<R>::template write_element<0,1>(r)=-mat_traits<A>::template read_element<0,1>(a);
  1318. mat_traits<R>::template write_element<0,2>(r)=-mat_traits<A>::template read_element<0,2>(a);
  1319. mat_traits<R>::template write_element<1,0>(r)=-mat_traits<A>::template read_element<1,0>(a);
  1320. mat_traits<R>::template write_element<1,1>(r)=-mat_traits<A>::template read_element<1,1>(a);
  1321. mat_traits<R>::template write_element<1,2>(r)=-mat_traits<A>::template read_element<1,2>(a);
  1322. mat_traits<R>::template write_element<2,0>(r)=-mat_traits<A>::template read_element<2,0>(a);
  1323. mat_traits<R>::template write_element<2,1>(r)=-mat_traits<A>::template read_element<2,1>(a);
  1324. mat_traits<R>::template write_element<2,2>(r)=-mat_traits<A>::template read_element<2,2>(a);
  1325. return r;
  1326. }
  1327. namespace
  1328. sfinae
  1329. {
  1330. using ::boost::qvm::operator-;
  1331. }
  1332. namespace
  1333. qvm_detail
  1334. {
  1335. template <int R,int C>
  1336. struct minus_m_defined;
  1337. template <>
  1338. struct
  1339. minus_m_defined<3,3>
  1340. {
  1341. static bool const value=true;
  1342. };
  1343. }
  1344. template <class A>
  1345. BOOST_QVM_INLINE_OPERATIONS
  1346. typename lazy_enable_if_c<
  1347. mat_traits<A>::rows==3 && mat_traits<A>::cols==1,
  1348. deduce_mat<A> >::type
  1349. operator-( A const & a )
  1350. {
  1351. typedef typename deduce_mat<A>::type R;
  1352. R r;
  1353. mat_traits<R>::template write_element<0,0>(r)=-mat_traits<A>::template read_element<0,0>(a);
  1354. mat_traits<R>::template write_element<1,0>(r)=-mat_traits<A>::template read_element<1,0>(a);
  1355. mat_traits<R>::template write_element<2,0>(r)=-mat_traits<A>::template read_element<2,0>(a);
  1356. return r;
  1357. }
  1358. namespace
  1359. sfinae
  1360. {
  1361. using ::boost::qvm::operator-;
  1362. }
  1363. namespace
  1364. qvm_detail
  1365. {
  1366. template <int R,int C>
  1367. struct minus_m_defined;
  1368. template <>
  1369. struct
  1370. minus_m_defined<3,1>
  1371. {
  1372. static bool const value=true;
  1373. };
  1374. }
  1375. template <class A>
  1376. BOOST_QVM_INLINE_OPERATIONS
  1377. typename lazy_enable_if_c<
  1378. mat_traits<A>::rows==1 && mat_traits<A>::cols==3,
  1379. deduce_mat<A> >::type
  1380. operator-( A const & a )
  1381. {
  1382. typedef typename deduce_mat<A>::type R;
  1383. R r;
  1384. mat_traits<R>::template write_element<0,0>(r)=-mat_traits<A>::template read_element<0,0>(a);
  1385. mat_traits<R>::template write_element<0,1>(r)=-mat_traits<A>::template read_element<0,1>(a);
  1386. mat_traits<R>::template write_element<0,2>(r)=-mat_traits<A>::template read_element<0,2>(a);
  1387. return r;
  1388. }
  1389. namespace
  1390. sfinae
  1391. {
  1392. using ::boost::qvm::operator-;
  1393. }
  1394. namespace
  1395. qvm_detail
  1396. {
  1397. template <int R,int C>
  1398. struct minus_m_defined;
  1399. template <>
  1400. struct
  1401. minus_m_defined<1,3>
  1402. {
  1403. static bool const value=true;
  1404. };
  1405. }
  1406. template <class A>
  1407. BOOST_QVM_INLINE_OPERATIONS
  1408. typename enable_if_c<
  1409. mat_traits<A>::rows==3 && mat_traits<A>::cols==3,
  1410. typename mat_traits<A>::scalar_type>::type
  1411. determinant( A const & a )
  1412. {
  1413. typedef typename mat_traits<A>::scalar_type T;
  1414. T const a00=mat_traits<A>::template read_element<0,0>(a);
  1415. T const a01=mat_traits<A>::template read_element<0,1>(a);
  1416. T const a02=mat_traits<A>::template read_element<0,2>(a);
  1417. T const a10=mat_traits<A>::template read_element<1,0>(a);
  1418. T const a11=mat_traits<A>::template read_element<1,1>(a);
  1419. T const a12=mat_traits<A>::template read_element<1,2>(a);
  1420. T const a20=mat_traits<A>::template read_element<2,0>(a);
  1421. T const a21=mat_traits<A>::template read_element<2,1>(a);
  1422. T const a22=mat_traits<A>::template read_element<2,2>(a);
  1423. T det=(a00*(a11*a22-a12*a21)-a01*(a10*a22-a12*a20)+a02*(a10*a21-a11*a20));
  1424. return det;
  1425. }
  1426. namespace
  1427. sfinae
  1428. {
  1429. using ::boost::qvm::determinant;
  1430. }
  1431. namespace
  1432. qvm_detail
  1433. {
  1434. template <int D>
  1435. struct determinant_defined;
  1436. template <>
  1437. struct
  1438. determinant_defined<3>
  1439. {
  1440. static bool const value=true;
  1441. };
  1442. }
  1443. template <class A,class B>
  1444. BOOST_QVM_INLINE_OPERATIONS
  1445. typename lazy_enable_if_c<
  1446. mat_traits<A>::rows==3 && mat_traits<A>::cols==3 && is_scalar<B>::value,
  1447. deduce_mat<A> >::type
  1448. inverse( A const & a, B det )
  1449. {
  1450. typedef typename mat_traits<A>::scalar_type T;
  1451. BOOST_QVM_ASSERT(det!=scalar_traits<B>::value(0));
  1452. T const a00=mat_traits<A>::template read_element<0,0>(a);
  1453. T const a01=mat_traits<A>::template read_element<0,1>(a);
  1454. T const a02=mat_traits<A>::template read_element<0,2>(a);
  1455. T const a10=mat_traits<A>::template read_element<1,0>(a);
  1456. T const a11=mat_traits<A>::template read_element<1,1>(a);
  1457. T const a12=mat_traits<A>::template read_element<1,2>(a);
  1458. T const a20=mat_traits<A>::template read_element<2,0>(a);
  1459. T const a21=mat_traits<A>::template read_element<2,1>(a);
  1460. T const a22=mat_traits<A>::template read_element<2,2>(a);
  1461. T const f=scalar_traits<T>::value(1)/det;
  1462. typedef typename deduce_mat<A>::type R;
  1463. R r;
  1464. mat_traits<R>::template write_element<0,0>(r)= f*(a11*a22-a12*a21);
  1465. mat_traits<R>::template write_element<0,1>(r)=-f*(a01*a22-a02*a21);
  1466. mat_traits<R>::template write_element<0,2>(r)= f*(a01*a12-a02*a11);
  1467. mat_traits<R>::template write_element<1,0>(r)=-f*(a10*a22-a12*a20);
  1468. mat_traits<R>::template write_element<1,1>(r)= f*(a00*a22-a02*a20);
  1469. mat_traits<R>::template write_element<1,2>(r)=-f*(a00*a12-a02*a10);
  1470. mat_traits<R>::template write_element<2,0>(r)= f*(a10*a21-a11*a20);
  1471. mat_traits<R>::template write_element<2,1>(r)=-f*(a00*a21-a01*a20);
  1472. mat_traits<R>::template write_element<2,2>(r)= f*(a00*a11-a01*a10);
  1473. return r;
  1474. }
  1475. template <class A>
  1476. BOOST_QVM_INLINE_OPERATIONS
  1477. typename lazy_enable_if_c<
  1478. mat_traits<A>::rows==3 && mat_traits<A>::cols==3,
  1479. deduce_mat<A> >::type
  1480. inverse( A const & a )
  1481. {
  1482. typedef typename mat_traits<A>::scalar_type T;
  1483. T det=determinant(a);
  1484. if( det==scalar_traits<T>::value(0) )
  1485. BOOST_QVM_THROW_EXCEPTION(zero_determinant_error());
  1486. return inverse(a,det);
  1487. }
  1488. namespace
  1489. sfinae
  1490. {
  1491. using ::boost::qvm::inverse;
  1492. }
  1493. namespace
  1494. qvm_detail
  1495. {
  1496. template <int D>
  1497. struct inverse_m_defined;
  1498. template <>
  1499. struct
  1500. inverse_m_defined<3>
  1501. {
  1502. static bool const value=true;
  1503. };
  1504. }
  1505. template <class A,class B>
  1506. BOOST_QVM_INLINE_OPERATIONS
  1507. typename lazy_enable_if_c<
  1508. mat_traits<A>::rows==3 && mat_traits<B>::rows==3 &&
  1509. mat_traits<A>::cols==3 && mat_traits<B>::cols==3,
  1510. deduce_mat2<A,B,3,3> >::type
  1511. operator*( A const & a, B const & b )
  1512. {
  1513. typedef typename mat_traits<A>::scalar_type Ta;
  1514. typedef typename mat_traits<B>::scalar_type Tb;
  1515. Ta const a00 = mat_traits<A>::template read_element<0,0>(a);
  1516. Ta const a01 = mat_traits<A>::template read_element<0,1>(a);
  1517. Ta const a02 = mat_traits<A>::template read_element<0,2>(a);
  1518. Ta const a10 = mat_traits<A>::template read_element<1,0>(a);
  1519. Ta const a11 = mat_traits<A>::template read_element<1,1>(a);
  1520. Ta const a12 = mat_traits<A>::template read_element<1,2>(a);
  1521. Ta const a20 = mat_traits<A>::template read_element<2,0>(a);
  1522. Ta const a21 = mat_traits<A>::template read_element<2,1>(a);
  1523. Ta const a22 = mat_traits<A>::template read_element<2,2>(a);
  1524. Tb const b00 = mat_traits<B>::template read_element<0,0>(b);
  1525. Tb const b01 = mat_traits<B>::template read_element<0,1>(b);
  1526. Tb const b02 = mat_traits<B>::template read_element<0,2>(b);
  1527. Tb const b10 = mat_traits<B>::template read_element<1,0>(b);
  1528. Tb const b11 = mat_traits<B>::template read_element<1,1>(b);
  1529. Tb const b12 = mat_traits<B>::template read_element<1,2>(b);
  1530. Tb const b20 = mat_traits<B>::template read_element<2,0>(b);
  1531. Tb const b21 = mat_traits<B>::template read_element<2,1>(b);
  1532. Tb const b22 = mat_traits<B>::template read_element<2,2>(b);
  1533. typedef typename deduce_mat2<A,B,3,3>::type R;
  1534. BOOST_QVM_STATIC_ASSERT(mat_traits<R>::rows==3);
  1535. BOOST_QVM_STATIC_ASSERT(mat_traits<R>::cols==3);
  1536. R r;
  1537. mat_traits<R>::template write_element<0,0>(r)=a00*b00+a01*b10+a02*b20;
  1538. mat_traits<R>::template write_element<0,1>(r)=a00*b01+a01*b11+a02*b21;
  1539. mat_traits<R>::template write_element<0,2>(r)=a00*b02+a01*b12+a02*b22;
  1540. mat_traits<R>::template write_element<1,0>(r)=a10*b00+a11*b10+a12*b20;
  1541. mat_traits<R>::template write_element<1,1>(r)=a10*b01+a11*b11+a12*b21;
  1542. mat_traits<R>::template write_element<1,2>(r)=a10*b02+a11*b12+a12*b22;
  1543. mat_traits<R>::template write_element<2,0>(r)=a20*b00+a21*b10+a22*b20;
  1544. mat_traits<R>::template write_element<2,1>(r)=a20*b01+a21*b11+a22*b21;
  1545. mat_traits<R>::template write_element<2,2>(r)=a20*b02+a21*b12+a22*b22;
  1546. return r;
  1547. }
  1548. namespace
  1549. sfinae
  1550. {
  1551. using ::boost::qvm::operator*;
  1552. }
  1553. namespace
  1554. qvm_detail
  1555. {
  1556. template <int R,int CR,int C>
  1557. struct mul_mm_defined;
  1558. template <>
  1559. struct
  1560. mul_mm_defined<3,3,3>
  1561. {
  1562. static bool const value=true;
  1563. };
  1564. }
  1565. template <class A,class B>
  1566. BOOST_QVM_INLINE_OPERATIONS
  1567. typename enable_if_c<
  1568. mat_traits<A>::rows==3 && mat_traits<B>::rows==3 &&
  1569. mat_traits<A>::cols==3 && mat_traits<B>::cols==3,
  1570. A &>::type
  1571. operator*=( A & a, B const & b )
  1572. {
  1573. typedef typename mat_traits<A>::scalar_type Ta;
  1574. typedef typename mat_traits<B>::scalar_type Tb;
  1575. Ta const a00 = mat_traits<A>::template read_element<0,0>(a);
  1576. Ta const a01 = mat_traits<A>::template read_element<0,1>(a);
  1577. Ta const a02 = mat_traits<A>::template read_element<0,2>(a);
  1578. Ta const a10 = mat_traits<A>::template read_element<1,0>(a);
  1579. Ta const a11 = mat_traits<A>::template read_element<1,1>(a);
  1580. Ta const a12 = mat_traits<A>::template read_element<1,2>(a);
  1581. Ta const a20 = mat_traits<A>::template read_element<2,0>(a);
  1582. Ta const a21 = mat_traits<A>::template read_element<2,1>(a);
  1583. Ta const a22 = mat_traits<A>::template read_element<2,2>(a);
  1584. Tb const b00 = mat_traits<B>::template read_element<0,0>(b);
  1585. Tb const b01 = mat_traits<B>::template read_element<0,1>(b);
  1586. Tb const b02 = mat_traits<B>::template read_element<0,2>(b);
  1587. Tb const b10 = mat_traits<B>::template read_element<1,0>(b);
  1588. Tb const b11 = mat_traits<B>::template read_element<1,1>(b);
  1589. Tb const b12 = mat_traits<B>::template read_element<1,2>(b);
  1590. Tb const b20 = mat_traits<B>::template read_element<2,0>(b);
  1591. Tb const b21 = mat_traits<B>::template read_element<2,1>(b);
  1592. Tb const b22 = mat_traits<B>::template read_element<2,2>(b);
  1593. mat_traits<A>::template write_element<0,0>(a)=a00*b00+a01*b10+a02*b20;
  1594. mat_traits<A>::template write_element<0,1>(a)=a00*b01+a01*b11+a02*b21;
  1595. mat_traits<A>::template write_element<0,2>(a)=a00*b02+a01*b12+a02*b22;
  1596. mat_traits<A>::template write_element<1,0>(a)=a10*b00+a11*b10+a12*b20;
  1597. mat_traits<A>::template write_element<1,1>(a)=a10*b01+a11*b11+a12*b21;
  1598. mat_traits<A>::template write_element<1,2>(a)=a10*b02+a11*b12+a12*b22;
  1599. mat_traits<A>::template write_element<2,0>(a)=a20*b00+a21*b10+a22*b20;
  1600. mat_traits<A>::template write_element<2,1>(a)=a20*b01+a21*b11+a22*b21;
  1601. mat_traits<A>::template write_element<2,2>(a)=a20*b02+a21*b12+a22*b22;
  1602. return a;
  1603. }
  1604. namespace
  1605. sfinae
  1606. {
  1607. using ::boost::qvm::operator*=;
  1608. }
  1609. namespace
  1610. qvm_detail
  1611. {
  1612. template <int D>
  1613. struct mul_eq_mm_defined;
  1614. template <>
  1615. struct
  1616. mul_eq_mm_defined<3>
  1617. {
  1618. static bool const value=true;
  1619. };
  1620. }
  1621. template <class A,class B>
  1622. BOOST_QVM_INLINE_OPERATIONS
  1623. typename lazy_enable_if_c<
  1624. mat_traits<A>::rows==3 && mat_traits<B>::rows==3 &&
  1625. mat_traits<A>::cols==3 && mat_traits<B>::cols==1,
  1626. deduce_mat2<A,B,3,1> >::type
  1627. operator*( A const & a, B const & b )
  1628. {
  1629. typedef typename mat_traits<A>::scalar_type Ta;
  1630. typedef typename mat_traits<B>::scalar_type Tb;
  1631. Ta const a00 = mat_traits<A>::template read_element<0,0>(a);
  1632. Ta const a01 = mat_traits<A>::template read_element<0,1>(a);
  1633. Ta const a02 = mat_traits<A>::template read_element<0,2>(a);
  1634. Ta const a10 = mat_traits<A>::template read_element<1,0>(a);
  1635. Ta const a11 = mat_traits<A>::template read_element<1,1>(a);
  1636. Ta const a12 = mat_traits<A>::template read_element<1,2>(a);
  1637. Ta const a20 = mat_traits<A>::template read_element<2,0>(a);
  1638. Ta const a21 = mat_traits<A>::template read_element<2,1>(a);
  1639. Ta const a22 = mat_traits<A>::template read_element<2,2>(a);
  1640. Tb const b00 = mat_traits<B>::template read_element<0,0>(b);
  1641. Tb const b10 = mat_traits<B>::template read_element<1,0>(b);
  1642. Tb const b20 = mat_traits<B>::template read_element<2,0>(b);
  1643. typedef typename deduce_mat2<A,B,3,1>::type R;
  1644. BOOST_QVM_STATIC_ASSERT(mat_traits<R>::rows==3);
  1645. BOOST_QVM_STATIC_ASSERT(mat_traits<R>::cols==1);
  1646. R r;
  1647. mat_traits<R>::template write_element<0,0>(r)=a00*b00+a01*b10+a02*b20;
  1648. mat_traits<R>::template write_element<1,0>(r)=a10*b00+a11*b10+a12*b20;
  1649. mat_traits<R>::template write_element<2,0>(r)=a20*b00+a21*b10+a22*b20;
  1650. return r;
  1651. }
  1652. namespace
  1653. sfinae
  1654. {
  1655. using ::boost::qvm::operator*;
  1656. }
  1657. namespace
  1658. qvm_detail
  1659. {
  1660. template <int R,int CR,int C>
  1661. struct mul_mm_defined;
  1662. template <>
  1663. struct
  1664. mul_mm_defined<3,3,1>
  1665. {
  1666. static bool const value=true;
  1667. };
  1668. }
  1669. template <class A,class B>
  1670. BOOST_QVM_INLINE_OPERATIONS
  1671. typename lazy_enable_if_c<
  1672. mat_traits<A>::rows==1 && mat_traits<B>::rows==3 &&
  1673. mat_traits<A>::cols==3 && mat_traits<B>::cols==3,
  1674. deduce_mat2<A,B,1,3> >::type
  1675. operator*( A const & a, B const & b )
  1676. {
  1677. typedef typename mat_traits<A>::scalar_type Ta;
  1678. typedef typename mat_traits<B>::scalar_type Tb;
  1679. Ta const a00 = mat_traits<A>::template read_element<0,0>(a);
  1680. Ta const a01 = mat_traits<A>::template read_element<0,1>(a);
  1681. Ta const a02 = mat_traits<A>::template read_element<0,2>(a);
  1682. Tb const b00 = mat_traits<B>::template read_element<0,0>(b);
  1683. Tb const b01 = mat_traits<B>::template read_element<0,1>(b);
  1684. Tb const b02 = mat_traits<B>::template read_element<0,2>(b);
  1685. Tb const b10 = mat_traits<B>::template read_element<1,0>(b);
  1686. Tb const b11 = mat_traits<B>::template read_element<1,1>(b);
  1687. Tb const b12 = mat_traits<B>::template read_element<1,2>(b);
  1688. Tb const b20 = mat_traits<B>::template read_element<2,0>(b);
  1689. Tb const b21 = mat_traits<B>::template read_element<2,1>(b);
  1690. Tb const b22 = mat_traits<B>::template read_element<2,2>(b);
  1691. typedef typename deduce_mat2<A,B,1,3>::type R;
  1692. BOOST_QVM_STATIC_ASSERT(mat_traits<R>::rows==1);
  1693. BOOST_QVM_STATIC_ASSERT(mat_traits<R>::cols==3);
  1694. R r;
  1695. mat_traits<R>::template write_element<0,0>(r)=a00*b00+a01*b10+a02*b20;
  1696. mat_traits<R>::template write_element<0,1>(r)=a00*b01+a01*b11+a02*b21;
  1697. mat_traits<R>::template write_element<0,2>(r)=a00*b02+a01*b12+a02*b22;
  1698. return r;
  1699. }
  1700. namespace
  1701. sfinae
  1702. {
  1703. using ::boost::qvm::operator*;
  1704. }
  1705. namespace
  1706. qvm_detail
  1707. {
  1708. template <int R,int CR,int C>
  1709. struct mul_mm_defined;
  1710. template <>
  1711. struct
  1712. mul_mm_defined<1,3,3>
  1713. {
  1714. static bool const value=true;
  1715. };
  1716. }
  1717. }
  1718. }
  1719. #endif