]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/qvm/mat_operations.hpp
update sources to ceph Nautilus 14.2.1
[ceph.git] / ceph / src / boost / boost / qvm / mat_operations.hpp
CommitLineData
b32b8144
FG
1//Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.\r
2\r
3//Distributed under the Boost Software License, Version 1.0. (See accompanying\r
4//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\r
5\r
6#ifndef UUID_4F915D9ED30A11DF962186E3DFD72085\r
7#define UUID_4F915D9ED30A11DF962186E3DFD72085\r
8\r
9#include <boost/qvm/detail/mat_assign.hpp>\r
10#include <boost/qvm/mat_operations2.hpp>\r
11#include <boost/qvm/mat_operations3.hpp>\r
12#include <boost/qvm/mat_operations4.hpp>\r
13#include <boost/qvm/math.hpp>\r
14#include <boost/qvm/detail/determinant_impl.hpp>\r
15#include <boost/qvm/detail/cofactor_impl.hpp>\r
16#include <boost/qvm/detail/transp_impl.hpp>\r
17#include <boost/qvm/scalar_traits.hpp>\r
18#include <string>\r
19\r
20namespace\r
21boost\r
22 {\r
23 namespace\r
24 qvm\r
25 {\r
26 namespace\r
27 qvm_detail\r
28 {\r
29 BOOST_QVM_INLINE_CRITICAL\r
30 void const *\r
31 get_valid_ptr_mat_operations()\r
32 {\r
33 static int const obj=0;\r
34 return &obj;\r
35 }\r
36 }\r
37\r
38 ////////////////////////////////////////////////\r
39\r
40 namespace\r
41 qvm_to_string_detail\r
42 {\r
43 template <class T>\r
44 std::string to_string( T const & x );\r
45 }\r
46\r
47 namespace\r
48 qvm_detail\r
49 {\r
50 template <int R,int C>\r
51 struct\r
52 to_string_m_defined\r
53 {\r
54 static bool const value=false;\r
55 };\r
56\r
57 template <int I,int SizeMinusOne>\r
58 struct\r
59 to_string_matrix_elements\r
60 {\r
61 template <class A>\r
62 static\r
63 std::string\r
64 f( A const & a )\r
65 {\r
66 using namespace qvm_to_string_detail;\r
67 return\r
68 ( (I%mat_traits<A>::cols)==0 ? '(' : ',' ) +\r
69 to_string(mat_traits<A>::template read_element<I/mat_traits<A>::cols,I%mat_traits<A>::cols>(a)) +\r
70 ( (I%mat_traits<A>::cols)==mat_traits<A>::cols-1 ? ")" : "" ) +\r
71 to_string_matrix_elements<I+1,SizeMinusOne>::f(a);\r
72 }\r
73 };\r
74\r
75 template <int SizeMinusOne>\r
76 struct\r
77 to_string_matrix_elements<SizeMinusOne,SizeMinusOne>\r
78 {\r
79 template <class A>\r
80 static\r
81 std::string\r
82 f( A const & a )\r
83 {\r
84 using namespace qvm_to_string_detail;\r
85 return\r
86 ( (SizeMinusOne%mat_traits<A>::cols)==0 ? '(' : ',' ) +\r
87 to_string(mat_traits<A>::template read_element<SizeMinusOne/mat_traits<A>::cols,SizeMinusOne%mat_traits<A>::cols>(a)) +\r
88 ')';\r
89 }\r
90 };\r
91 }\r
92\r
93 template <class A>\r
94 inline\r
95 typename boost::enable_if_c<\r
96 is_mat<A>::value &&\r
97 !qvm_detail::to_string_m_defined<mat_traits<A>::rows,mat_traits<A>::cols>::value,\r
98 std::string>::type\r
99 to_string( A const & a )\r
100 {\r
101 return "("+qvm_detail::to_string_matrix_elements<0,mat_traits<A>::rows*mat_traits<A>::cols-1>::f(a)+')';\r
102 }\r
103\r
104 ////////////////////////////////////////////////\r
105\r
106 template <class A,class B,class Cmp>\r
107 BOOST_QVM_INLINE_OPERATIONS\r
108 typename enable_if_c<\r
109 is_mat<A>::value && is_mat<B>::value &&\r
110 mat_traits<A>::rows==mat_traits<B>::rows &&\r
111 mat_traits<A>::cols==mat_traits<B>::cols,\r
112 bool>::type\r
113 cmp( A const & a, B const & b, Cmp f )\r
114 {\r
115 typedef typename deduce_scalar<\r
116 typename mat_traits<A>::scalar_type,\r
117 typename mat_traits<B>::scalar_type>::type T;\r
118 int const rows=mat_traits<A>::rows;\r
119 int const cols=mat_traits<A>::cols;\r
120 T m1[rows][cols]; assign(m1,a);\r
121 T m2[rows][cols]; assign(m2,b);\r
122 for( int i=0; i!=rows; ++i )\r
123 for( int j=0; j!=cols; ++j )\r
124 if( !f(m1[i][j],m2[i][j]) )\r
125 return false;\r
126 return true;\r
127 }\r
128\r
129 ////////////////////////////////////////////////\r
130\r
131 namespace\r
132 qvm_detail\r
133 {\r
134 template <int M,int N>\r
135 struct\r
136 convert_to_m_defined\r
137 {\r
138 static bool const value=false;\r
139 };\r
140 }\r
141\r
142 template <class R,class A>\r
143 BOOST_QVM_INLINE_TRIVIAL\r
144 typename enable_if_c<\r
145 is_mat<R>::value && is_mat<A>::value &&\r
146 mat_traits<R>::rows==mat_traits<A>::rows &&\r
147 mat_traits<R>::cols==mat_traits<A>::cols &&\r
148 !qvm_detail::convert_to_m_defined<mat_traits<A>::rows,mat_traits<A>::cols>::value,\r
149 R>::type\r
150 convert_to( A const & a )\r
151 {\r
152 R r; assign(r,a);\r
153 return r;\r
154 }\r
155\r
156 ////////////////////////////////////////////////\r
157\r
158 namespace\r
159 qvm_detail\r
160 {\r
161 template <int D>\r
162 struct\r
163 determinant_defined\r
164 {\r
165 static bool const value=false;\r
166 };\r
167 }\r
168\r
169 template <class A>\r
170 BOOST_QVM_INLINE_TRIVIAL\r
171 typename enable_if_c<\r
172 is_mat<A>::value &&\r
173 mat_traits<A>::rows==mat_traits<A>::cols &&\r
174 !qvm_detail::determinant_defined<mat_traits<A>::rows>::value,\r
175 typename mat_traits<A>::scalar_type>::type\r
176 determinant( A const & a )\r
177 {\r
178 return qvm_detail::determinant_impl(a);\r
179 }\r
180\r
181 ////////////////////////////////////////////////\r
182\r
183 namespace\r
184 qvm_detail\r
185 {\r
186 template <class T,int Dim>\r
187 class\r
188 identity_mat_\r
189 {\r
190 identity_mat_( identity_mat_ const & );\r
191 identity_mat_ & operator=( identity_mat_ const & );\r
192 ~identity_mat_();\r
193\r
194 public:\r
195\r
196 template <class R>\r
197 BOOST_QVM_INLINE_TRIVIAL\r
198 operator R() const\r
199 {\r
200 R r;\r
201 assign(r,*this);\r
202 return r;\r
203 }\r
204 };\r
205 }\r
206\r
207 template <class T,int Dim>\r
208 struct\r
209 mat_traits< qvm_detail::identity_mat_<T,Dim> >\r
210 {\r
211 typedef qvm_detail::identity_mat_<T,Dim> this_matrix;\r
212 typedef T scalar_type;\r
213 static int const rows=Dim;\r
214 static int const cols=Dim;\r
215\r
216 template <int Row,int Col>\r
217 static\r
218 BOOST_QVM_INLINE_CRITICAL\r
219 scalar_type\r
220 read_element( this_matrix const & x )\r
221 {\r
222 BOOST_QVM_STATIC_ASSERT(Row>=0);\r
223 BOOST_QVM_STATIC_ASSERT(Row<Dim);\r
224 BOOST_QVM_STATIC_ASSERT(Col>=0);\r
225 BOOST_QVM_STATIC_ASSERT(Col<Dim);\r
226 return scalar_traits<scalar_type>::value(Row==Col);\r
227 }\r
228\r
229 static\r
230 BOOST_QVM_INLINE_CRITICAL\r
231 scalar_type\r
232 read_element_idx( int row, int col, this_matrix const & x )\r
233 {\r
234 BOOST_QVM_ASSERT(row>=0);\r
235 BOOST_QVM_ASSERT(row<Dim);\r
236 BOOST_QVM_ASSERT(col>=0);\r
237 BOOST_QVM_ASSERT(col<Dim);\r
238 return scalar_traits<scalar_type>::value(row==col);\r
239 }\r
240 };\r
241\r
242 template <class T,int Dim>\r
243 BOOST_QVM_INLINE_TRIVIAL\r
244 qvm_detail::identity_mat_<T,Dim> const &\r
245 identity_mat()\r
246 {\r
247 return *(qvm_detail::identity_mat_<T,Dim> const *)qvm_detail::get_valid_ptr_mat_operations();\r
248 }\r
249\r
250 template <class A>\r
251 BOOST_QVM_INLINE_OPERATIONS\r
252 typename enable_if_c<\r
253 is_mat<A>::value &&\r
254 mat_traits<A>::rows==mat_traits<A>::cols,\r
255 void>::type\r
256 set_identity( A & a )\r
257 {\r
258 assign(a,identity_mat<typename mat_traits<A>::scalar_type,mat_traits<A>::rows>());\r
259 }\r
260\r
261 ////////////////////////////////////////////////\r
262\r
263 namespace\r
264 qvm_detail\r
265 {\r
266 template <class T>\r
267 struct\r
268 projection_\r
269 {\r
270 T const _00;\r
271 T const _11;\r
272 T const _22;\r
273 T const _23;\r
274 T const _32;\r
275\r
276 BOOST_QVM_INLINE_TRIVIAL\r
277 projection_( T _00, T _11, T _22, T _23, T _32 ):\r
278 _00(_00),\r
279 _11(_11),\r
280 _22(_22),\r
281 _23(_23),\r
282 _32(_32)\r
283 {\r
284 }\r
285\r
286 template <class R>\r
287 BOOST_QVM_INLINE_TRIVIAL\r
288 operator R() const\r
289 {\r
290 R r;\r
291 assign(r,*this);\r
292 return r;\r
293 }\r
294 };\r
295\r
296 template <int Row,int Col>\r
297 struct\r
298 projection_get\r
299 {\r
300 template <class T>\r
301 static\r
302 BOOST_QVM_INLINE_CRITICAL\r
303 T\r
304 get( projection_<T> const & )\r
305 {\r
306 return scalar_traits<T>::value(0);\r
307 }\r
308 };\r
309\r
310 template <> struct projection_get<0,0> { template <class T> static BOOST_QVM_INLINE_CRITICAL T get( projection_<T> const & m ) { return m._00; } };\r
311 template <> struct projection_get<1,1> { template <class T> static BOOST_QVM_INLINE_CRITICAL T get( projection_<T> const & m ) { return m._11; } };\r
312 template <> struct projection_get<2,2> { template <class T> static BOOST_QVM_INLINE_CRITICAL T get( projection_<T> const & m ) { return m._22; } };\r
313 template <> struct projection_get<2,3> { template <class T> static BOOST_QVM_INLINE_CRITICAL T get( projection_<T> const & m ) { return m._23; } };\r
314 template <> struct projection_get<3,2> { template <class T> static BOOST_QVM_INLINE_CRITICAL T get( projection_<T> const & m ) { return m._32; } };\r
315 }\r
316\r
317 template <class T>\r
318 struct\r
319 mat_traits< qvm_detail::projection_<T> >\r
320 {\r
321 typedef qvm_detail::projection_<T> this_matrix;\r
322 typedef T scalar_type;\r
323 static int const rows=4;\r
324 static int const cols=4;\r
325\r
326 template <int Row,int Col>\r
327 static\r
328 BOOST_QVM_INLINE_CRITICAL\r
329 scalar_type\r
330 read_element( this_matrix const & x )\r
331 {\r
332 BOOST_QVM_STATIC_ASSERT(Row>=0);\r
333 BOOST_QVM_STATIC_ASSERT(Row<rows);\r
334 BOOST_QVM_STATIC_ASSERT(Col>=0);\r
335 BOOST_QVM_STATIC_ASSERT(Col<cols);\r
336 return qvm_detail::projection_get<Row,Col>::get(x);\r
337 }\r
338 };\r
339\r
340 template <class T>\r
341 qvm_detail::projection_<T>\r
342 BOOST_QVM_INLINE_OPERATIONS\r
343 perspective_lh( T fov_y, T aspect_ratio, T z_near, T z_far )\r
344 {\r
345 T const one = scalar_traits<T>::value(1);\r
346 T const ys = one/tan<T>(fov_y/scalar_traits<T>::value(2));\r
347 T const xs = ys/aspect_ratio;\r
348 T const zd = z_far-z_near;\r
349 T const z1 = z_far/zd;\r
350 T const z2 = -z_near*z1;\r
351 return qvm_detail::projection_<T>(xs,ys,z1,z2,one);\r
352 }\r
353\r
354 template <class T>\r
355 qvm_detail::projection_<T>\r
356 BOOST_QVM_INLINE_OPERATIONS\r
357 perspective_rh( T fov_y, T aspect_ratio, T z_near, T z_far )\r
358 {\r
359 T const one = scalar_traits<T>::value(1);\r
360 T const ys = one/tan<T>(fov_y/scalar_traits<T>::value(2));\r
361 T const xs = ys/aspect_ratio;\r
362 T const zd = z_near-z_far;\r
363 T const z1 = z_far/zd;\r
364 T const z2 = z_near*z1;\r
365 return qvm_detail::projection_<T>(xs,ys,z1,z2,-one);\r
366 }\r
367\r
368 ////////////////////////////////////////////////\r
369\r
370 namespace\r
371 qvm_detail\r
372 {\r
373 template <class OriginalType,class Scalar>\r
374 class\r
375 matrix_scalar_cast_\r
376 {\r
377 matrix_scalar_cast_( matrix_scalar_cast_ const & );\r
378 matrix_scalar_cast_ & operator=( matrix_scalar_cast_ const & );\r
379 ~matrix_scalar_cast_();\r
380\r
381 public:\r
382\r
383 template <class T>\r
384 BOOST_QVM_INLINE_TRIVIAL\r
385 matrix_scalar_cast_ &\r
386 operator=( T const & x )\r
387 {\r
388 assign(*this,x);\r
389 return *this;\r
390 }\r
391\r
392 template <class R>\r
393 BOOST_QVM_INLINE_TRIVIAL\r
394 operator R() const\r
395 {\r
396 R r;\r
397 assign(r,*this);\r
398 return r;\r
399 }\r
400 };\r
401\r
402 template <bool> struct scalar_cast_matrix_filter { };\r
403 template <> struct scalar_cast_matrix_filter<true> { typedef int type; };\r
404 }\r
405\r
406 template <class OriginalType,class Scalar>\r
407 struct\r
408 mat_traits< qvm_detail::matrix_scalar_cast_<OriginalType,Scalar> >\r
409 {\r
410 typedef Scalar scalar_type;\r
411 typedef qvm_detail::matrix_scalar_cast_<OriginalType,Scalar> this_matrix;\r
412 static int const rows=mat_traits<OriginalType>::rows;\r
413 static int const cols=mat_traits<OriginalType>::cols;\r
414\r
415 template <int Row,int Col>\r
416 static\r
417 BOOST_QVM_INLINE_CRITICAL\r
418 scalar_type\r
419 read_element( this_matrix const & x )\r
420 {\r
421 BOOST_QVM_STATIC_ASSERT(Row>=0);\r
422 BOOST_QVM_STATIC_ASSERT(Row<rows);\r
423 BOOST_QVM_STATIC_ASSERT(Col>=0);\r
424 BOOST_QVM_STATIC_ASSERT(Col<cols);\r
425 return scalar_type(mat_traits<OriginalType>::template read_element<Row,Col>(reinterpret_cast<OriginalType const &>(x)));\r
426 }\r
427\r
428 static\r
429 BOOST_QVM_INLINE_CRITICAL\r
430 scalar_type\r
431 read_element_idx( int row, int col, this_matrix const & x )\r
432 {\r
433 BOOST_QVM_ASSERT(row>=0);\r
434 BOOST_QVM_ASSERT(row<rows);\r
435 BOOST_QVM_ASSERT(col>=0);\r
436 BOOST_QVM_ASSERT(col<cols);\r
437 return scalar_type(mat_traits<OriginalType>::read_element_idx(col,row,reinterpret_cast<OriginalType const &>(x)));\r
438 }\r
439 };\r
440\r
441 template <class OriginalType,class Scalar,int R,int C>\r
442 struct\r
443 deduce_mat<qvm_detail::matrix_scalar_cast_<OriginalType,Scalar>,R,C>\r
444 {\r
445 typedef mat<Scalar,R,C> type;\r
446 };\r
447\r
448 template <class Scalar,class T>\r
449 BOOST_QVM_INLINE_TRIVIAL\r
450 qvm_detail::matrix_scalar_cast_<T,Scalar> const &\r
451 scalar_cast( T const & x, typename qvm_detail::scalar_cast_matrix_filter<is_mat<T>::value>::type=0 )\r
452 {\r
453 return reinterpret_cast<qvm_detail::matrix_scalar_cast_<T,Scalar> const &>(x);\r
454 }\r
455\r
456 ////////////////////////////////////////////////\r
457\r
458 namespace\r
459 qvm_detail\r
460 {\r
461 template <int M,int N>\r
462 struct\r
463 div_eq_ms_defined\r
464 {\r
465 static bool const value=false;\r
466 };\r
467 }\r
468\r
469 template <class A,class B>\r
470 BOOST_QVM_INLINE_OPERATIONS\r
471 typename enable_if_c<\r
472 is_mat<A>::value && is_scalar<B>::value &&\r
473 !qvm_detail::div_eq_ms_defined<mat_traits<A>::rows,mat_traits<A>::cols>::value,\r
474 A &>::type\r
475 operator/=( A & a, B b )\r
476 {\r
477 for( int i=0; i!=mat_traits<A>::rows; ++i )\r
478 for( int j=0; j!=mat_traits<A>::cols; ++j )\r
479 mat_traits<A>::write_element_idx(i,j,a)/=b;\r
480 return a;\r
481 }\r
482\r
483 ////////////////////////////////////////////////\r
484\r
485 namespace\r
486 qvm_detail\r
487 {\r
488 template <int M,int N>\r
489 struct\r
490 div_ms_defined\r
491 {\r
492 static bool const value=false;\r
493 };\r
494 }\r
495\r
496 template <class A,class B>\r
497 BOOST_QVM_INLINE_OPERATIONS\r
498 typename lazy_enable_if_c<\r
499 is_mat<A>::value && is_scalar<B>::value &&\r
500 !qvm_detail::div_ms_defined<mat_traits<A>::rows,mat_traits<A>::cols>::value,\r
501 deduce_mat<A> >::type\r
502 operator/( A const & a, B b )\r
503 {\r
504 typedef typename deduce_mat<A>::type R;\r
505 R r;\r
506 for( int i=0; i!=mat_traits<A>::rows; ++i )\r
507 for( int j=0; j!=mat_traits<A>::cols; ++j )\r
508 mat_traits<R>::write_element_idx(i,j,r)=mat_traits<A>::read_element_idx(i,j,a)/b;\r
509 return r;\r
510 }\r
511\r
512 ////////////////////////////////////////////////\r
513\r
514 namespace\r
515 qvm_detail\r
516 {\r
517 template <int M,int N>\r
518 struct\r
519 eq_mm_defined\r
520 {\r
521 static bool const value=false;\r
522 };\r
523 }\r
524\r
525 template <class A,class B>\r
526 BOOST_QVM_INLINE_OPERATIONS\r
527 typename enable_if_c<\r
528 is_mat<A>::value && is_mat<B>::value &&\r
529 mat_traits<A>::rows==mat_traits<B>::rows &&\r
530 mat_traits<A>::cols==mat_traits<B>::cols &&\r
531 !qvm_detail::eq_mm_defined<mat_traits<A>::rows,mat_traits<A>::cols>::value,\r
532 bool>::type\r
533 operator==( A const & a, B const & b )\r
534 {\r
535 for( int i=0; i!=mat_traits<A>::rows; ++i )\r
536 for( int j=0; j!=mat_traits<A>::cols; ++j )\r
537 if( mat_traits<A>::read_element_idx(i,j,a)!=mat_traits<B>::read_element_idx(i,j,b) )\r
538 return false;\r
539 return true;\r
540 }\r
541\r
542 ////////////////////////////////////////////////\r
543\r
544 namespace\r
545 qvm_detail\r
546 {\r
547 template <int M,int N>\r
548 struct\r
549 minus_eq_mm_defined\r
550 {\r
551 static bool const value=false;\r
552 };\r
553 }\r
554\r
555 template <class A,class B>\r
556 BOOST_QVM_INLINE_OPERATIONS\r
557 typename enable_if_c<\r
558 is_mat<A>::value && is_mat<B>::value &&\r
559 mat_traits<A>::rows==mat_traits<B>::rows &&\r
560 mat_traits<A>::cols==mat_traits<B>::cols &&\r
561 !qvm_detail::minus_eq_mm_defined<mat_traits<A>::rows,mat_traits<A>::cols>::value,\r
562 A &>::type\r
563 operator-=( A & a, B const & b )\r
564 {\r
565 for( int i=0; i!=mat_traits<A>::rows; ++i )\r
566 for( int j=0; j!=mat_traits<A>::cols; ++j )\r
567 mat_traits<A>::write_element_idx(i,j,a)-=mat_traits<B>::read_element_idx(i,j,b);\r
568 return a;\r
569 }\r
570\r
571 ////////////////////////////////////////////////\r
572\r
573 namespace\r
574 qvm_detail\r
575 {\r
576 template <int M,int N>\r
577 struct\r
578 minus_m_defined\r
579 {\r
580 static bool const value=false;\r
581 };\r
582 }\r
583\r
584 template <class A>\r
585 BOOST_QVM_INLINE_OPERATIONS\r
586 typename lazy_enable_if_c<\r
587 is_mat<A>::value &&\r
588 !qvm_detail::minus_m_defined<mat_traits<A>::rows,mat_traits<A>::cols>::value,\r
589 deduce_mat<A> >::type\r
590 operator-( A const & a )\r
591 {\r
592 typedef typename deduce_mat<A>::type R;\r
593 R r;\r
594 for( int i=0; i!=mat_traits<A>::rows; ++i )\r
595 for( int j=0; j!=mat_traits<A>::cols; ++j )\r
596 mat_traits<R>::write_element_idx(i,j,r)=-mat_traits<A>::read_element_idx(i,j,a);\r
597 return r;\r
598 }\r
599\r
600 ////////////////////////////////////////////////\r
601\r
602 namespace\r
603 qvm_detail\r
604 {\r
605 template <int M,int N>\r
606 struct\r
607 minus_mm_defined\r
608 {\r
609 static bool const value=false;\r
610 };\r
611 }\r
612\r
613 template <class A,class B>\r
614 BOOST_QVM_INLINE_OPERATIONS\r
615 typename lazy_enable_if_c<\r
616 is_mat<A>::value && is_mat<B>::value &&\r
617 mat_traits<A>::rows==mat_traits<B>::rows &&\r
618 mat_traits<A>::cols==mat_traits<B>::cols &&\r
619 !qvm_detail::minus_mm_defined<mat_traits<A>::rows,mat_traits<A>::cols>::value,\r
620 deduce_mat2<A,B,mat_traits<A>::rows,mat_traits<A>::cols> >::type\r
621 operator-( A const & a, B const & b )\r
622 {\r
623 typedef typename deduce_mat2<A,B,mat_traits<A>::rows,mat_traits<A>::cols>::type R;\r
624 R r;\r
625 for( int i=0; i!=mat_traits<A>::rows; ++i )\r
626 for( int j=0; j!=mat_traits<A>::cols; ++j )\r
627 mat_traits<R>::write_element_idx(i,j,r)=mat_traits<A>::read_element_idx(i,j,a)-mat_traits<B>::read_element_idx(i,j,b);\r
628 return r;\r
629 }\r
630\r
631 ////////////////////////////////////////////////\r
632\r
633 namespace\r
634 qvm_detail\r
635 {\r
636 template <int D>\r
637 struct\r
638 mul_eq_mm_defined\r
639 {\r
640 static bool const value=false;\r
641 };\r
642 }\r
643\r
644 template <class A,class B>\r
645 BOOST_QVM_INLINE_OPERATIONS\r
646 typename enable_if_c<\r
647 is_mat<A>::value &&\r
648 is_mat<B>::value &&\r
649 mat_traits<A>::rows==mat_traits<A>::cols &&\r
650 mat_traits<A>::rows==mat_traits<B>::rows &&\r
651 mat_traits<A>::cols==mat_traits<B>::cols &&\r
652 !qvm_detail::mul_eq_mm_defined<mat_traits<A>::rows>::value,\r
653 A &>::type\r
654 operator*=( A & r, B const & b )\r
655 {\r
656 typedef typename mat_traits<A>::scalar_type Ta;\r
657 Ta a[mat_traits<A>::rows][mat_traits<A>::cols];\r
658 for( int i=0; i<mat_traits<A>::rows; ++i )\r
659 for( int j=0; j<mat_traits<B>::cols; ++j )\r
660 a[i][j]=mat_traits<A>::read_element_idx(i,j,r);\r
661 for( int i=0; i<mat_traits<A>::rows; ++i )\r
662 for( int j=0; j<mat_traits<B>::cols; ++j )\r
663 {\r
664 Ta x(scalar_traits<Ta>::value(0));\r
665 for( int k=0; k<mat_traits<A>::cols; ++k )\r
666 x += a[i][k]*mat_traits<B>::read_element_idx(k,j,b);\r
667 mat_traits<A>::write_element_idx(i,j,r) = x;\r
668 }\r
669 return r;\r
670 }\r
671\r
672 ////////////////////////////////////////////////\r
673\r
674 namespace\r
675 qvm_detail\r
676 {\r
677 template <int M,int N>\r
678 struct\r
679 mul_eq_ms_defined\r
680 {\r
681 static bool const value=false;\r
682 };\r
683 }\r
684\r
685 template <class A,class B>\r
686 BOOST_QVM_INLINE_OPERATIONS\r
687 typename enable_if_c<\r
688 is_mat<A>::value && is_scalar<B>::value &&\r
689 !qvm_detail::mul_eq_ms_defined<mat_traits<A>::rows,mat_traits<A>::cols>::value,\r
690 A &>::type\r
691 operator*=( A & a, B b )\r
692 {\r
693 for( int i=0; i!=mat_traits<A>::rows; ++i )\r
694 for( int j=0; j!=mat_traits<A>::cols; ++j )\r
695 mat_traits<A>::write_element_idx(i,j,a)*=b;\r
696 return a;\r
697 }\r
698\r
699 ////////////////////////////////////////////////\r
700\r
701 namespace\r
702 qvm_detail\r
703 {\r
704 template <int R,int CR,int C>\r
705 struct\r
706 mul_mm_defined\r
707 {\r
708 static bool const value=false;\r
709 };\r
710 }\r
711\r
712 template <class A,class B>\r
713 BOOST_QVM_INLINE_OPERATIONS\r
714 typename lazy_enable_if_c<\r
715 is_mat<A>::value && is_mat<B>::value &&\r
716 mat_traits<A>::cols==mat_traits<B>::rows &&\r
717 !qvm_detail::mul_mm_defined<mat_traits<A>::rows,mat_traits<A>::cols,mat_traits<B>::cols>::value,\r
718 deduce_mat2<A,B,mat_traits<A>::rows,mat_traits<B>::cols> >::type\r
719 operator*( A const & a, B const & b )\r
720 {\r
721 typedef typename deduce_mat2<A,B,mat_traits<A>::rows,mat_traits<B>::cols>::type R;\r
722 R r;\r
723 for( int i=0; i<mat_traits<A>::rows; ++i )\r
724 for( int j=0; j<mat_traits<B>::cols; ++j )\r
725 {\r
726 typedef typename mat_traits<A>::scalar_type Ta;\r
727 Ta x(scalar_traits<Ta>::value(0));\r
728 for( int k=0; k<mat_traits<A>::cols; ++k )\r
729 x += mat_traits<A>::read_element_idx(i,k,a)*mat_traits<B>::read_element_idx(k,j,b);\r
730 mat_traits<R>::write_element_idx(i,j,r) = x;\r
731 }\r
732 return r;\r
733 }\r
734\r
735 ////////////////////////////////////////////////\r
736\r
737 namespace\r
738 qvm_detail\r
739 {\r
740 template <int M,int N>\r
741 struct\r
742 mul_ms_defined\r
743 {\r
744 static bool const value=false;\r
745 };\r
746 }\r
747\r
748 template <class A,class B>\r
749 BOOST_QVM_INLINE_OPERATIONS\r
750 typename lazy_enable_if_c<\r
751 is_mat<A>::value && is_scalar<B>::value &&\r
752 !qvm_detail::mul_ms_defined<mat_traits<A>::rows,mat_traits<A>::cols>::value,\r
753 deduce_mat<A> >::type\r
754 operator*( A const & a, B b )\r
755 {\r
756 typedef typename deduce_mat<A>::type R;\r
757 R r;\r
758 for( int i=0; i!=mat_traits<A>::rows; ++i )\r
759 for( int j=0; j!=mat_traits<A>::cols; ++j )\r
760 mat_traits<R>::write_element_idx(i,j,r)=mat_traits<A>::read_element_idx(i,j,a)*b;\r
761 return r;\r
762 }\r
763\r
764 ////////////////////////////////////////////////\r
765\r
766 namespace\r
767 qvm_detail\r
768 {\r
769 template <int M,int N>\r
770 struct\r
771 mul_sm_defined\r
772 {\r
773 static bool const value=false;\r
774 };\r
775 }\r
776\r
777 template <class A,class B>\r
778 BOOST_QVM_INLINE_OPERATIONS\r
779 typename lazy_enable_if_c<\r
780 is_scalar<A>::value && is_mat<B>::value &&\r
781 !qvm_detail::mul_sm_defined<mat_traits<B>::rows,mat_traits<B>::cols>::value,\r
782 deduce_mat<B> >::type\r
783 operator*( A a, B const & b )\r
784 {\r
785 typedef typename deduce_mat<B>::type R;\r
786 R r;\r
787 for( int i=0; i!=mat_traits<B>::rows; ++i )\r
788 for( int j=0; j!=mat_traits<B>::cols; ++j )\r
789 mat_traits<R>::write_element_idx(i,j,r)=a*mat_traits<B>::read_element_idx(i,j,b);\r
790 return r;\r
791 }\r
792\r
793 ////////////////////////////////////////////////\r
794\r
795 namespace\r
796 qvm_detail\r
797 {\r
798 template <int M,int N>\r
799 struct\r
800 neq_mm_defined\r
801 {\r
802 static bool const value=false;\r
803 };\r
804 }\r
805\r
806 template <class A,class B>\r
807 BOOST_QVM_INLINE_OPERATIONS\r
808 typename enable_if_c<\r
809 is_mat<A>::value && is_mat<B>::value &&\r
810 mat_traits<A>::rows==mat_traits<B>::rows &&\r
811 mat_traits<A>::cols==mat_traits<B>::cols &&\r
812 !qvm_detail::neq_mm_defined<mat_traits<A>::rows,mat_traits<A>::cols>::value,\r
813 bool>::type\r
814 operator!=( A const & a, B const & b )\r
815 {\r
816 for( int i=0; i!=mat_traits<A>::rows; ++i )\r
817 for( int j=0; j!=mat_traits<A>::cols; ++j )\r
818 if( mat_traits<A>::read_element_idx(i,j,a)!=mat_traits<B>::read_element_idx(i,j,b) )\r
819 return true;\r
820 return false;\r
821 }\r
822\r
823 ////////////////////////////////////////////////\r
824\r
825 namespace\r
826 qvm_detail\r
827 {\r
828 template <int M,int N>\r
829 struct\r
830 plus_eq_mm_defined\r
831 {\r
832 static bool const value=false;\r
833 };\r
834 }\r
835\r
836 template <class A,class B>\r
837 BOOST_QVM_INLINE_OPERATIONS\r
838 typename enable_if_c<\r
839 is_mat<A>::value && is_mat<B>::value &&\r
840 mat_traits<A>::rows==mat_traits<B>::rows &&\r
841 mat_traits<A>::cols==mat_traits<B>::cols &&\r
842 !qvm_detail::plus_eq_mm_defined<mat_traits<A>::rows,mat_traits<A>::cols>::value,\r
843 A &>::type\r
844 operator+=( A & a, B const & b )\r
845 {\r
846 for( int i=0; i!=mat_traits<A>::rows; ++i )\r
847 for( int j=0; j!=mat_traits<A>::cols; ++j )\r
848 mat_traits<A>::write_element_idx(i,j,a)+=mat_traits<B>::read_element_idx(i,j,b);\r
849 return a;\r
850 }\r
851\r
852 ////////////////////////////////////////////////\r
853\r
854 namespace\r
855 qvm_detail\r
856 {\r
857 template <int M,int N>\r
858 struct\r
859 plus_mm_defined\r
860 {\r
861 static bool const value=false;\r
862 };\r
863 }\r
864\r
865 template <class A,class B>\r
866 BOOST_QVM_INLINE_OPERATIONS\r
867 typename lazy_enable_if_c<\r
868 is_mat<A>::value && is_mat<B>::value &&\r
869 mat_traits<A>::rows==mat_traits<B>::rows &&\r
870 mat_traits<A>::cols==mat_traits<B>::cols &&\r
871 !qvm_detail::plus_mm_defined<mat_traits<A>::rows,mat_traits<A>::cols>::value,\r
872 deduce_mat2<A,B,mat_traits<A>::rows,mat_traits<A>::cols> >::type\r
873 operator+( A const & a, B const & b )\r
874 {\r
875 typedef typename deduce_mat2<A,B,mat_traits<A>::rows,mat_traits<A>::cols>::type R;\r
876 R r;\r
877 for( int i=0; i!=mat_traits<A>::rows; ++i )\r
878 for( int j=0; j!=mat_traits<A>::cols; ++j )\r
879 mat_traits<R>::write_element_idx(i,j,r)=mat_traits<A>::read_element_idx(i,j,a)+mat_traits<B>::read_element_idx(i,j,b);\r
880 return r;\r
881 }\r
882\r
883 ////////////////////////////////////////////////\r
884\r
885 namespace\r
886 qvm_detail\r
887 {\r
888 template <class T>\r
889 class\r
890 mref_\r
891 {\r
892 mref_( mref_ const & );\r
893 mref_ & operator=( mref_ const & );\r
894 ~mref_();\r
895\r
896 public:\r
897\r
898 template <class R>\r
899 BOOST_QVM_INLINE_TRIVIAL\r
900 mref_ &\r
901 operator=( R const & x )\r
902 {\r
903 assign(*this,x);\r
904 return *this;\r
905 }\r
906\r
907 template <class R>\r
908 BOOST_QVM_INLINE_TRIVIAL\r
909 operator R() const\r
910 {\r
911 R r;\r
912 assign(r,*this);\r
913 return r;\r
914 }\r
915 };\r
916 }\r
917\r
918 template <class M>\r
919 struct\r
920 mat_traits< qvm_detail::mref_<M> >\r
921 {\r
922 typedef typename mat_traits<M>::scalar_type scalar_type;\r
923 typedef qvm_detail::mref_<M> this_matrix;\r
924 static int const rows=mat_traits<M>::rows;\r
925 static int const cols=mat_traits<M>::cols;\r
926\r
927 template <int Row,int Col>\r
928 static\r
929 BOOST_QVM_INLINE_CRITICAL\r
930 scalar_type\r
931 read_element( this_matrix const & x )\r
932 {\r
933 BOOST_QVM_STATIC_ASSERT(Row>=0);\r
934 BOOST_QVM_STATIC_ASSERT(Row<rows);\r
935 BOOST_QVM_STATIC_ASSERT(Col>=0);\r
936 BOOST_QVM_STATIC_ASSERT(Col<cols);\r
937 return mat_traits<M>::template read_element<Row,Col>(reinterpret_cast<M const &>(x));\r
938 }\r
939\r
940 template <int Row,int Col>\r
941 static\r
942 BOOST_QVM_INLINE_CRITICAL\r
943 scalar_type &\r
944 write_element( this_matrix & x )\r
945 {\r
946 BOOST_QVM_STATIC_ASSERT(Row>=0);\r
947 BOOST_QVM_STATIC_ASSERT(Row<rows);\r
948 BOOST_QVM_STATIC_ASSERT(Col>=0);\r
949 BOOST_QVM_STATIC_ASSERT(Col<cols);\r
950 return mat_traits<M>::template write_element<Row,Col>(reinterpret_cast<M &>(x));\r
951 }\r
952\r
953 static\r
954 BOOST_QVM_INLINE_CRITICAL\r
955 scalar_type\r
956 read_element_idx( int row, int col, this_matrix const & x )\r
957 {\r
958 BOOST_QVM_ASSERT(row>=0);\r
959 BOOST_QVM_ASSERT(row<rows);\r
960 BOOST_QVM_ASSERT(col>=0);\r
961 BOOST_QVM_ASSERT(col<cols);\r
962 return mat_traits<M>::read_element_idx(row,col,reinterpret_cast<M const &>(x));\r
963 }\r
964\r
965 static\r
966 BOOST_QVM_INLINE_CRITICAL\r
967 scalar_type &\r
968 write_element_idx( int row, int col, this_matrix & x )\r
969 {\r
970 BOOST_QVM_ASSERT(row>=0);\r
971 BOOST_QVM_ASSERT(row<rows);\r
972 BOOST_QVM_ASSERT(col>=0);\r
973 BOOST_QVM_ASSERT(col<cols);\r
974 return mat_traits<M>::write_element_idx(row,col,reinterpret_cast<M &>(x));\r
975 }\r
976 };\r
977\r
978 template <class M,int R,int C>\r
979 struct\r
980 deduce_mat<qvm_detail::mref_<M>,R,C>\r
981 {\r
982 typedef mat<typename mat_traits<M>::scalar_type,R,C> type;\r
983 };\r
984\r
985 template <class M>\r
986 BOOST_QVM_INLINE_TRIVIAL\r
987 typename enable_if_c<\r
988 is_mat<M>::value,\r
989 qvm_detail::mref_<M> const &>::type\r
990 mref( M const & a )\r
991 {\r
992 return reinterpret_cast<qvm_detail::mref_<M> const &>(a);\r
993 }\r
994\r
995 template <class M>\r
996 BOOST_QVM_INLINE_TRIVIAL\r
997 typename enable_if_c<\r
998 is_mat<M>::value,\r
999 qvm_detail::mref_<M> &>::type\r
1000 mref( M & a )\r
1001 {\r
1002 return reinterpret_cast<qvm_detail::mref_<M> &>(a);\r
1003 }\r
1004\r
1005 ////////////////////////////////////////////////\r
1006\r
1007 namespace\r
1008 qvm_detail\r
1009 {\r
1010 template <class T,int Rows,int Cols>\r
1011 class\r
1012 zero_mat_\r
1013 {\r
1014 zero_mat_( zero_mat_ const & );\r
1015 zero_mat_ & operator=( zero_mat_ const & );\r
1016 ~zero_mat_();\r
1017\r
1018 public:\r
1019\r
1020 template <class R>\r
1021 BOOST_QVM_INLINE_TRIVIAL\r
1022 operator R() const\r
1023 {\r
1024 R r;\r
1025 assign(r,*this);\r
1026 return r;\r
1027 }\r
1028 };\r
1029 }\r
1030\r
1031 template <class T,int Rows,int Cols>\r
1032 struct\r
1033 mat_traits< qvm_detail::zero_mat_<T,Rows,Cols> >\r
1034 {\r
1035 typedef qvm_detail::zero_mat_<T,Rows,Cols> this_matrix;\r
1036 typedef T scalar_type;\r
1037 static int const rows=Rows;\r
1038 static int const cols=Cols;\r
1039\r
1040 template <int Row,int Col>\r
1041 static\r
1042 BOOST_QVM_INLINE_CRITICAL\r
1043 scalar_type\r
1044 read_element( this_matrix const & )\r
1045 {\r
1046 BOOST_QVM_STATIC_ASSERT(Row>=0);\r
1047 BOOST_QVM_STATIC_ASSERT(Row<Rows);\r
1048 BOOST_QVM_STATIC_ASSERT(Col>=0);\r
1049 BOOST_QVM_STATIC_ASSERT(Col<Cols);\r
1050 return scalar_traits<scalar_type>::value(0);\r
1051 }\r
1052\r
1053 static\r
1054 BOOST_QVM_INLINE_CRITICAL\r
1055 scalar_type\r
1056 read_element_idx( int row, int col, this_matrix const & )\r
1057 {\r
1058 BOOST_QVM_ASSERT(row>=0);\r
1059 BOOST_QVM_ASSERT(row<rows);\r
1060 BOOST_QVM_ASSERT(col>=0);\r
1061 BOOST_QVM_ASSERT(col<cols);\r
1062 return scalar_traits<scalar_type>::value(0);\r
1063 }\r
1064 };\r
1065\r
1066 template <class T,int Rows,int Cols,int R,int C>\r
1067 struct\r
1068 deduce_mat<qvm_detail::zero_mat_<T,Rows,Cols>,R,C>\r
1069 {\r
1070 typedef mat<T,R,C> type;\r
1071 };\r
1072\r
1073 template <class T,int Rows,int Cols>\r
1074 BOOST_QVM_INLINE_TRIVIAL\r
1075 qvm_detail::zero_mat_<T,Rows,Cols> const &\r
1076 zero_mat()\r
1077 {\r
1078 return *(qvm_detail::zero_mat_<T,Rows,Cols> const *)qvm_detail::get_valid_ptr_mat_operations();\r
1079 }\r
1080\r
1081 template <class T,int Dim>\r
1082 BOOST_QVM_INLINE_TRIVIAL\r
1083 qvm_detail::zero_mat_<T,Dim,Dim> const &\r
1084 zero_mat()\r
1085 {\r
1086 return *(qvm_detail::zero_mat_<T,Dim,Dim> const *)qvm_detail::get_valid_ptr_mat_operations();\r
1087 }\r
1088\r
1089 template <class A>\r
1090 BOOST_QVM_INLINE_OPERATIONS\r
1091 typename enable_if_c<\r
1092 is_mat<A>::value,\r
1093 void>::type\r
1094 set_zero( A & a )\r
1095 {\r
1096 assign(a,zero_mat<typename mat_traits<A>::scalar_type,mat_traits<A>::rows,mat_traits<A>::cols>());\r
1097 }\r
1098\r
1099 ////////////////////////////////////////////////\r
1100\r
1101 namespace\r
1102 qvm_detail\r
1103 {\r
11fdf7f2 1104 template <int D,class S>\r
b32b8144
FG
1105 struct\r
1106 rot_mat_\r
1107 {\r
11fdf7f2 1108 typedef S scalar_type;\r
b32b8144
FG
1109 scalar_type a[3][3];\r
1110\r
b32b8144 1111 BOOST_QVM_INLINE\r
11fdf7f2
TL
1112 rot_mat_(\r
1113 scalar_type a00, scalar_type a01, scalar_type a02,\r
1114 scalar_type a10, scalar_type a11, scalar_type a12,\r
1115 scalar_type a20, scalar_type a21, scalar_type a22 )\r
b32b8144 1116 {\r
11fdf7f2
TL
1117 a[0][0] = a00;\r
1118 a[0][1] = a01;\r
1119 a[0][2] = a02;\r
1120 a[1][0] = a10;\r
1121 a[1][1] = a11;\r
1122 a[1][2] = a12;\r
1123 a[2][0] = a20;\r
1124 a[2][1] = a21;\r
1125 a[2][2] = a22;\r
b32b8144
FG
1126 }\r
1127\r
1128 template <class R>\r
1129 BOOST_QVM_INLINE_TRIVIAL\r
1130 operator R() const\r
1131 {\r
1132 R r;\r
1133 assign(r,*this);\r
1134 return r;\r
1135 }\r
1136 };\r
1137\r
1138 template <int Row,int Col>\r
1139 struct\r
1140 rot_m_get\r
1141 {\r
1142 template <class T>\r
1143 static\r
1144 BOOST_QVM_INLINE_CRITICAL\r
1145 T\r
1146 get( T const (&)[3][3] )\r
1147 {\r
1148 return scalar_traits<T>::value(Row==Col);\r
1149 }\r
1150 };\r
1151\r
1152 template <> struct rot_m_get<0,0> { template <class T> static BOOST_QVM_INLINE_CRITICAL T get( T const (&a)[3][3] ) { return a[0][0]; } };\r
1153 template <> struct rot_m_get<0,1> { template <class T> static BOOST_QVM_INLINE_CRITICAL T get( T const (&a)[3][3] ) { return a[0][1]; } };\r
1154 template <> struct rot_m_get<0,2> { template <class T> static BOOST_QVM_INLINE_CRITICAL T get( T const (&a)[3][3] ) { return a[0][2]; } };\r
1155 template <> struct rot_m_get<1,0> { template <class T> static BOOST_QVM_INLINE_CRITICAL T get( T const (&a)[3][3] ) { return a[1][0]; } };\r
1156 template <> struct rot_m_get<1,1> { template <class T> static BOOST_QVM_INLINE_CRITICAL T get( T const (&a)[3][3] ) { return a[1][1]; } };\r
1157 template <> struct rot_m_get<1,2> { template <class T> static BOOST_QVM_INLINE_CRITICAL T get( T const (&a)[3][3] ) { return a[1][2]; } };\r
1158 template <> struct rot_m_get<2,0> { template <class T> static BOOST_QVM_INLINE_CRITICAL T get( T const (&a)[3][3] ) { return a[2][0]; } };\r
1159 template <> struct rot_m_get<2,1> { template <class T> static BOOST_QVM_INLINE_CRITICAL T get( T const (&a)[3][3] ) { return a[2][1]; } };\r
1160 template <> struct rot_m_get<2,2> { template <class T> static BOOST_QVM_INLINE_CRITICAL T get( T const (&a)[3][3] ) { return a[2][2]; } };\r
1161 }\r
1162\r
1163 template <class M>\r
1164 struct mat_traits;\r
1165\r
11fdf7f2 1166 template <int D,class S>\r
b32b8144 1167 struct\r
11fdf7f2 1168 mat_traits< qvm_detail::rot_mat_<D,S> >\r
b32b8144 1169 {\r
11fdf7f2 1170 typedef qvm_detail::rot_mat_<D,S> this_matrix;\r
b32b8144
FG
1171 typedef typename this_matrix::scalar_type scalar_type;\r
1172 static int const rows=D;\r
1173 static int const cols=D;\r
1174\r
1175 template <int Row,int Col>\r
1176 static\r
1177 BOOST_QVM_INLINE_CRITICAL\r
1178 scalar_type\r
1179 read_element( this_matrix const & x )\r
1180 {\r
1181 BOOST_QVM_STATIC_ASSERT(Row>=0);\r
1182 BOOST_QVM_STATIC_ASSERT(Row<D);\r
1183 BOOST_QVM_STATIC_ASSERT(Col>=0);\r
1184 BOOST_QVM_STATIC_ASSERT(Col<D);\r
1185 return qvm_detail::rot_m_get<Row,Col>::get(x.a);\r
1186 }\r
1187\r
1188 static\r
1189 BOOST_QVM_INLINE_CRITICAL\r
1190 scalar_type\r
1191 read_element_idx( int row, int col, this_matrix const & x )\r
1192 {\r
1193 BOOST_QVM_ASSERT(row>=0);\r
1194 BOOST_QVM_ASSERT(row<D);\r
1195 BOOST_QVM_ASSERT(col>=0);\r
1196 BOOST_QVM_ASSERT(col<D);\r
1197 return row<3 && col<3?\r
1198 x.a[row][col] :\r
1199 scalar_traits<scalar_type>::value(row==col);\r
1200 }\r
1201 };\r
1202\r
11fdf7f2 1203 template <int Dim,class V,class Angle>\r
b32b8144
FG
1204 BOOST_QVM_INLINE\r
1205 typename enable_if_c<\r
11fdf7f2
TL
1206 is_vec<V>::value && vec_traits<V>::dim==3,\r
1207 qvm_detail::rot_mat_<Dim,Angle> >::type\r
1208 rot_mat( V const & axis, Angle angle )\r
1209 {\r
1210 typedef Angle scalar_type;\r
1211 scalar_type const x=vec_traits<V>::template read_element<0>(axis);\r
1212 scalar_type const y=vec_traits<V>::template read_element<1>(axis);\r
1213 scalar_type const z=vec_traits<V>::template read_element<2>(axis);\r
1214 scalar_type const m2=x*x+y*y+z*z;\r
1215 if( m2==scalar_traits<scalar_type>::value(0) )\r
1216 BOOST_QVM_THROW_EXCEPTION(zero_magnitude_error());\r
1217 scalar_type const s = sin<scalar_type>(angle);\r
1218 scalar_type const c = cos<scalar_type>(angle);\r
1219 scalar_type const x2 = x*x;\r
1220 scalar_type const y2 = y*y;\r
1221 scalar_type const z2 = z*z;\r
1222 scalar_type const xy = x*y;\r
1223 scalar_type const xz = x*z;\r
1224 scalar_type const yz = y*z;\r
1225 scalar_type const xs = x*s;\r
1226 scalar_type const ys = y*s;\r
1227 scalar_type const zs = z*s;\r
1228 scalar_type const one = scalar_traits<scalar_type>::value(1);\r
1229 scalar_type const c1 = one-c;\r
1230 return qvm_detail::rot_mat_<Dim,Angle>(\r
1231 x2+(one-x2)*c, xy*c1-zs, xz*(one-c)+ys,\r
1232 xy*c1+zs, y2+(one-y2)*c, yz*c1-xs,\r
1233 xz*c1-ys, yz*c1+xs, z2+(one-z2)*c );\r
b32b8144
FG
1234 }\r
1235\r
1236 template <class A,class B,class Angle>\r
1237 BOOST_QVM_INLINE_OPERATIONS\r
1238 typename enable_if_c<\r
1239 is_mat<A>::value &&\r
1240 mat_traits<A>::rows==mat_traits<A>::cols &&\r
1241 mat_traits<A>::rows>=3 &&\r
1242 is_vec<B>::value && vec_traits<B>::dim==3,\r
1243 void>::type\r
1244 set_rot( A & a, B const & axis, Angle angle )\r
1245 {\r
1246 assign(a,rot_mat<mat_traits<A>::rows>(axis,angle));\r
1247 }\r
1248\r
1249 template <class A,class B,class Angle>\r
1250 BOOST_QVM_INLINE_OPERATIONS\r
1251 typename enable_if_c<\r
1252 is_mat<A>::value &&\r
1253 mat_traits<A>::rows==mat_traits<A>::cols &&\r
1254 mat_traits<A>::rows>=3 &&\r
1255 is_vec<B>::value && vec_traits<B>::dim==3,\r
1256 void>::type\r
1257 rotate( A & a, B const & axis, Angle angle )\r
1258 {\r
1259 a *= rot_mat<mat_traits<A>::rows>(axis,angle);\r
1260 }\r
1261\r
1262 ////////////////////////////////////////////////\r
1263\r
11fdf7f2
TL
1264 template <int Dim,class Angle>\r
1265 BOOST_QVM_INLINE\r
1266 qvm_detail::rot_mat_<Dim,Angle>\r
1267 rot_mat_xzy( Angle x1, Angle z2, Angle y3 )\r
1268 {\r
1269 typedef Angle scalar_type;\r
1270 scalar_type const c1 = cos<scalar_type>(x1);\r
1271 scalar_type const s1 = sin<scalar_type>(x1);\r
1272 scalar_type const c2 = cos<scalar_type>(z2);\r
1273 scalar_type const s2 = sin<scalar_type>(z2);\r
1274 scalar_type const c3 = cos<scalar_type>(y3);\r
1275 scalar_type const s3 = sin<scalar_type>(y3);\r
1276 return qvm_detail::rot_mat_<Dim,Angle>(\r
1277 c2*c3, -s2, c2*s3,\r
1278 s1*s3 + c1*c3*s2, c1*c2, c1*s2*s3 - c3*s1,\r
1279 c3*s1*s2 - c1*s3, c2*s1, c1*c3 + s1*s2*s3 );\r
1280 }\r
1281\r
1282 template <class A,class Angle>\r
1283 BOOST_QVM_INLINE_OPERATIONS\r
1284 typename enable_if_c<\r
1285 is_mat<A>::value &&\r
1286 mat_traits<A>::rows==mat_traits<A>::cols &&\r
1287 mat_traits<A>::rows>=3,\r
1288 void>::type\r
1289 set_rot_xzy( A & a, Angle x1, Angle z2, Angle y3 )\r
1290 {\r
1291 assign(a,rot_mat_xzy<mat_traits<A>::rows>(x1,z2,y3));\r
1292 }\r
1293\r
1294 template <class A,class Angle>\r
1295 BOOST_QVM_INLINE_OPERATIONS\r
1296 typename enable_if_c<\r
1297 is_mat<A>::value &&\r
1298 mat_traits<A>::rows==mat_traits<A>::cols &&\r
1299 mat_traits<A>::rows>=3,\r
1300 void>::type\r
1301 rotate_xzy( A & a, Angle x1, Angle z2, Angle y3 )\r
1302 {\r
1303 a *= rot_mat_xzy<mat_traits<A>::rows>(x1,z2,y3);\r
1304 }\r
1305\r
1306 ////////////////////////////////////////////////\r
1307\r
1308 template <int Dim,class Angle>\r
1309 BOOST_QVM_INLINE\r
1310 qvm_detail::rot_mat_<Dim,Angle>\r
1311 rot_mat_xyz( Angle x1, Angle y2, Angle z3 )\r
1312 {\r
1313 typedef Angle scalar_type;\r
1314 scalar_type const c1 = cos<scalar_type>(x1);\r
1315 scalar_type const s1 = sin<scalar_type>(x1);\r
1316 scalar_type const c2 = cos<scalar_type>(y2);\r
1317 scalar_type const s2 = sin<scalar_type>(y2);\r
1318 scalar_type const c3 = cos<scalar_type>(z3);\r
1319 scalar_type const s3 = sin<scalar_type>(z3);\r
1320 return qvm_detail::rot_mat_<Dim,Angle>(\r
1321 c2*c3, -c2*s3, s2,\r
1322 c1*s3 + c3*s1*s2, c1*c3 - s1*s2*s3, -c2*s1,\r
1323 s1*s3 - c1*c3*s2, c3*s1 + c1*s2*s3, c1*c2 );\r
1324 }\r
1325\r
1326 template <class A,class Angle>\r
1327 BOOST_QVM_INLINE_OPERATIONS\r
1328 typename enable_if_c<\r
1329 is_mat<A>::value &&\r
1330 mat_traits<A>::rows==mat_traits<A>::cols &&\r
1331 mat_traits<A>::rows>=3,\r
1332 void>::type\r
1333 set_rot_xyz( A & a, Angle x1, Angle y2, Angle z3 )\r
1334 {\r
1335 assign(a,rot_mat_xyz<mat_traits<A>::rows>(x1,y2,z3));\r
1336 }\r
1337\r
1338 template <class A,class Angle>\r
1339 BOOST_QVM_INLINE_OPERATIONS\r
1340 typename enable_if_c<\r
1341 is_mat<A>::value &&\r
1342 mat_traits<A>::rows==mat_traits<A>::cols &&\r
1343 mat_traits<A>::rows>=3,\r
1344 void>::type\r
1345 rotate_xyz( A & a, Angle x1, Angle y2, Angle z3 )\r
1346 {\r
1347 a *= rot_mat_xyz<mat_traits<A>::rows>(x1,y2,z3);\r
1348 }\r
1349\r
1350 ////////////////////////////////////////////////\r
1351\r
1352 template <int Dim,class Angle>\r
1353 BOOST_QVM_INLINE\r
1354 qvm_detail::rot_mat_<Dim,Angle>\r
1355 rot_mat_yxz( Angle y1, Angle x2, Angle z3 )\r
1356 {\r
1357 typedef Angle scalar_type;\r
1358 scalar_type const c1 = cos<scalar_type>(y1);\r
1359 scalar_type const s1 = sin<scalar_type>(y1);\r
1360 scalar_type const c2 = cos<scalar_type>(x2);\r
1361 scalar_type const s2 = sin<scalar_type>(x2);\r
1362 scalar_type const c3 = cos<scalar_type>(z3);\r
1363 scalar_type const s3 = sin<scalar_type>(z3);\r
1364 return qvm_detail::rot_mat_<Dim,Angle>(\r
1365 c1*c3 + s1*s2*s3, c3*s1*s2 - c1*s3, c2*s1,\r
1366 c2*s3, c2*c3, -s2,\r
1367 c1*s2*s3 - c3*s1, c1*c3*s2 + s1*s3, c1*c2 );\r
1368 }\r
1369\r
1370 template <class A,class Angle>\r
1371 BOOST_QVM_INLINE_OPERATIONS\r
1372 typename enable_if_c<\r
1373 is_mat<A>::value &&\r
1374 mat_traits<A>::rows==mat_traits<A>::cols &&\r
1375 mat_traits<A>::rows>=3,\r
1376 void>::type\r
1377 set_rot_yxz( A & a, Angle y1, Angle x2, Angle z3 )\r
1378 {\r
1379 assign(a,rot_mat_yxz<mat_traits<A>::rows>(y1,x2,z3));\r
1380 }\r
1381\r
1382 template <class A,class Angle>\r
1383 BOOST_QVM_INLINE_OPERATIONS\r
1384 typename enable_if_c<\r
1385 is_mat<A>::value &&\r
1386 mat_traits<A>::rows==mat_traits<A>::cols &&\r
1387 mat_traits<A>::rows>=3,\r
1388 void>::type\r
1389 rotate_yxz( A & a, Angle y1, Angle x2, Angle z3 )\r
1390 {\r
1391 a *= rot_mat_yxz<mat_traits<A>::rows>(y1,x2,z3);\r
1392 }\r
1393\r
1394 ////////////////////////////////////////////////\r
1395\r
1396 template <int Dim,class Angle>\r
1397 BOOST_QVM_INLINE\r
1398 qvm_detail::rot_mat_<Dim,Angle>\r
1399 rot_mat_yzx( Angle y1, Angle z2, Angle x3 )\r
1400 {\r
1401 typedef Angle scalar_type;\r
1402 scalar_type const c1 = cos<scalar_type>(y1);\r
1403 scalar_type const s1 = sin<scalar_type>(y1);\r
1404 scalar_type const c2 = cos<scalar_type>(z2);\r
1405 scalar_type const s2 = sin<scalar_type>(z2);\r
1406 scalar_type const c3 = cos<scalar_type>(x3);\r
1407 scalar_type const s3 = sin<scalar_type>(x3);\r
1408 return qvm_detail::rot_mat_<Dim,Angle>(\r
1409 c1*c2, s1*s3 - c1*c3*s2, c3*s1 + c1*s2*s3,\r
1410 s2, c2*c3, -c2*s3,\r
1411 -c2*s1, c1*s3 + c3*s1*s2, c1*c3 - s1*s2*s3 );\r
1412 }\r
1413\r
1414 template <class A,class Angle>\r
1415 BOOST_QVM_INLINE_OPERATIONS\r
1416 typename enable_if_c<\r
1417 is_mat<A>::value &&\r
1418 mat_traits<A>::rows==mat_traits<A>::cols &&\r
1419 mat_traits<A>::rows>=3,\r
1420 void>::type\r
1421 set_rot_yzx( A & a, Angle y1, Angle z2, Angle x3 )\r
1422 {\r
1423 assign(a,rot_mat_yzx<mat_traits<A>::rows>(y1,z2,x3));\r
1424 }\r
1425\r
1426 template <class A,class Angle>\r
1427 BOOST_QVM_INLINE_OPERATIONS\r
1428 typename enable_if_c<\r
1429 is_mat<A>::value &&\r
1430 mat_traits<A>::rows==mat_traits<A>::cols &&\r
1431 mat_traits<A>::rows>=3,\r
1432 void>::type\r
1433 rotate_yzx( A & a, Angle y1, Angle z2, Angle x3 )\r
1434 {\r
1435 a *= rot_mat_yzx<mat_traits<A>::rows>(y1,z2,x3);\r
1436 }\r
1437\r
1438 ////////////////////////////////////////////////\r
1439\r
1440 template <int Dim,class Angle>\r
1441 BOOST_QVM_INLINE\r
1442 qvm_detail::rot_mat_<Dim,Angle>\r
1443 rot_mat_zyx( Angle z1, Angle y2, Angle x3 )\r
1444 {\r
1445 typedef Angle scalar_type;\r
1446 scalar_type const c1 = cos<scalar_type>(z1);\r
1447 scalar_type const s1 = sin<scalar_type>(z1);\r
1448 scalar_type const c2 = cos<scalar_type>(y2);\r
1449 scalar_type const s2 = sin<scalar_type>(y2);\r
1450 scalar_type const c3 = cos<scalar_type>(x3);\r
1451 scalar_type const s3 = sin<scalar_type>(x3);\r
1452 return qvm_detail::rot_mat_<Dim,Angle>(\r
1453 c1*c2, c1*s2*s3 - c3*s1, s1*s3 + c1*c3*s2,\r
1454 c2*s1, c1*c3 + s1*s2*s3, c3*s1*s2 - c1*s3,\r
1455 -s2, c2*s3, c2*c3 );\r
1456 }\r
1457\r
1458 template <class A,class Angle>\r
1459 BOOST_QVM_INLINE_OPERATIONS\r
1460 typename enable_if_c<\r
1461 is_mat<A>::value &&\r
1462 mat_traits<A>::rows==mat_traits<A>::cols &&\r
1463 mat_traits<A>::rows>=3,\r
1464 void>::type\r
1465 set_rot_zyx( A & a, Angle z1, Angle y2, Angle x3 )\r
1466 {\r
1467 assign(a,rot_mat_zyx<mat_traits<A>::rows>(z1,y2,x3));\r
1468 }\r
1469\r
1470 template <class A,class Angle>\r
1471 BOOST_QVM_INLINE_OPERATIONS\r
1472 typename enable_if_c<\r
1473 is_mat<A>::value &&\r
1474 mat_traits<A>::rows==mat_traits<A>::cols &&\r
1475 mat_traits<A>::rows>=3,\r
1476 void>::type\r
1477 rotate_zyx( A & a, Angle z1, Angle y2, Angle x3 )\r
1478 {\r
1479 a *= rot_mat_zyx<mat_traits<A>::rows>(z1,y2,x3);\r
1480 }\r
1481\r
1482 ////////////////////////////////////////////////\r
1483\r
1484 template <int Dim,class Angle>\r
1485 BOOST_QVM_INLINE\r
1486 qvm_detail::rot_mat_<Dim,Angle>\r
1487 rot_mat_zxy( Angle z1, Angle x2, Angle y3 )\r
1488 {\r
1489 typedef Angle scalar_type;\r
1490 scalar_type const c1 = cos<scalar_type>(z1);\r
1491 scalar_type const s1 = sin<scalar_type>(z1);\r
1492 scalar_type const c2 = cos<scalar_type>(x2);\r
1493 scalar_type const s2 = sin<scalar_type>(x2);\r
1494 scalar_type const c3 = cos<scalar_type>(y3);\r
1495 scalar_type const s3 = sin<scalar_type>(y3);\r
1496 return qvm_detail::rot_mat_<Dim,Angle>(\r
1497 c1*c3 - s1*s2*s3, -c2*s1, c1*s3 + c3*s1*s2,\r
1498 c3*s1 + c1*s2*s3, c1*c2, s1*s3 - c1*c3*s2,\r
1499 -c2*s3, s2, c2*c3 );\r
1500 }\r
1501\r
1502 template <class A,class Angle>\r
1503 BOOST_QVM_INLINE_OPERATIONS\r
1504 typename enable_if_c<\r
1505 is_mat<A>::value &&\r
1506 mat_traits<A>::rows==mat_traits<A>::cols &&\r
1507 mat_traits<A>::rows>=3,\r
1508 void>::type\r
1509 set_rot_zxy( A & a, Angle z1, Angle x2, Angle y3 )\r
1510 {\r
1511 assign(a,rot_mat_zxy<mat_traits<A>::rows>(z1,x2,y3));\r
1512 }\r
1513\r
1514 template <class A,class Angle>\r
1515 BOOST_QVM_INLINE_OPERATIONS\r
1516 typename enable_if_c<\r
1517 is_mat<A>::value &&\r
1518 mat_traits<A>::rows==mat_traits<A>::cols &&\r
1519 mat_traits<A>::rows>=3,\r
1520 void>::type\r
1521 rotate_zxy( A & a, Angle z1, Angle x2, Angle y3 )\r
1522 {\r
1523 a *= rot_mat_zxy<mat_traits<A>::rows>(z1,x2,y3);\r
1524 }\r
1525\r
1526 ////////////////////////////////////////////////\r
1527\r
1528 template <int Dim,class Angle>\r
1529 BOOST_QVM_INLINE\r
1530 qvm_detail::rot_mat_<Dim,Angle>\r
1531 rot_mat_xzx( Angle x1, Angle z2, Angle x3 )\r
1532 {\r
1533 typedef Angle scalar_type;\r
1534 scalar_type const c1 = cos<scalar_type>(x1);\r
1535 scalar_type const s1 = sin<scalar_type>(x1);\r
1536 scalar_type const c2 = cos<scalar_type>(z2);\r
1537 scalar_type const s2 = sin<scalar_type>(z2);\r
1538 scalar_type const c3 = cos<scalar_type>(x3);\r
1539 scalar_type const s3 = sin<scalar_type>(x3);\r
1540 return qvm_detail::rot_mat_<Dim,Angle>(\r
1541 c2, -c3*s2, s2*s3,\r
1542 c1*s2, c1*c2*c3 - s1*s3, -c3*s1 - c1*c2*s3,\r
1543 s1*s2, c1*s3 + c2*c3*s1, c1*c3 - c2*s1*s3 );\r
1544 }\r
1545\r
1546 template <class A,class Angle>\r
1547 BOOST_QVM_INLINE_OPERATIONS\r
1548 typename enable_if_c<\r
1549 is_mat<A>::value &&\r
1550 mat_traits<A>::rows==mat_traits<A>::cols &&\r
1551 mat_traits<A>::rows>=3,\r
1552 void>::type\r
1553 set_rot_xzx( A & a, Angle x1, Angle z2, Angle x3 )\r
1554 {\r
1555 assign(a,rot_mat_xzx<mat_traits<A>::rows>(x1,z2,x3));\r
1556 }\r
1557\r
1558 template <class A,class Angle>\r
1559 BOOST_QVM_INLINE_OPERATIONS\r
1560 typename enable_if_c<\r
1561 is_mat<A>::value &&\r
1562 mat_traits<A>::rows==mat_traits<A>::cols &&\r
1563 mat_traits<A>::rows>=3,\r
1564 void>::type\r
1565 rotate_xzx( A & a, Angle x1, Angle z2, Angle x3 )\r
1566 {\r
1567 a *= rot_mat_xzx<mat_traits<A>::rows>(x1,z2,x3);\r
1568 }\r
1569\r
1570 ////////////////////////////////////////////////\r
1571\r
1572 template <int Dim,class Angle>\r
1573 BOOST_QVM_INLINE\r
1574 qvm_detail::rot_mat_<Dim,Angle>\r
1575 rot_mat_xyx( Angle x1, Angle y2, Angle x3 )\r
1576 {\r
1577 typedef Angle scalar_type;\r
1578 scalar_type const c1 = cos<scalar_type>(x1);\r
1579 scalar_type const s1 = sin<scalar_type>(x1);\r
1580 scalar_type const c2 = cos<scalar_type>(y2);\r
1581 scalar_type const s2 = sin<scalar_type>(y2);\r
1582 scalar_type const c3 = cos<scalar_type>(x3);\r
1583 scalar_type const s3 = sin<scalar_type>(x3);\r
1584 return qvm_detail::rot_mat_<Dim,Angle>(\r
1585 c2, s2*s3, c3*s2,\r
1586 s1*s2, c1*c3 - c2*s1*s3, -c1*s3 - c2*c3*s1,\r
1587 -c1*s2, c3*s1 + c1*c2*s3, c1*c2*c3 - s1*s3 );\r
1588 }\r
1589\r
1590 template <class A,class Angle>\r
1591 BOOST_QVM_INLINE_OPERATIONS\r
1592 typename enable_if_c<\r
1593 is_mat<A>::value &&\r
1594 mat_traits<A>::rows==mat_traits<A>::cols &&\r
1595 mat_traits<A>::rows>=3,\r
1596 void>::type\r
1597 set_rot_xyx( A & a, Angle x1, Angle y2, Angle x3 )\r
1598 {\r
1599 assign(a,rot_mat_xyx<mat_traits<A>::rows>(x1,y2,x3));\r
1600 }\r
1601\r
1602 template <class A,class Angle>\r
1603 BOOST_QVM_INLINE_OPERATIONS\r
1604 typename enable_if_c<\r
1605 is_mat<A>::value &&\r
1606 mat_traits<A>::rows==mat_traits<A>::cols &&\r
1607 mat_traits<A>::rows>=3,\r
1608 void>::type\r
1609 rotate_xyx( A & a, Angle x1, Angle y2, Angle x3 )\r
1610 {\r
1611 a *= rot_mat_xyx<mat_traits<A>::rows>(x1,y2,x3);\r
1612 }\r
1613\r
1614 ////////////////////////////////////////////////\r
1615\r
1616 template <int Dim,class Angle>\r
1617 BOOST_QVM_INLINE\r
1618 qvm_detail::rot_mat_<Dim,Angle>\r
1619 rot_mat_yxy( Angle y1, Angle x2, Angle y3 )\r
1620 {\r
1621 typedef Angle scalar_type;\r
1622 scalar_type const c1 = cos<scalar_type>(y1);\r
1623 scalar_type const s1 = sin<scalar_type>(y1);\r
1624 scalar_type const c2 = cos<scalar_type>(x2);\r
1625 scalar_type const s2 = sin<scalar_type>(x2);\r
1626 scalar_type const c3 = cos<scalar_type>(y3);\r
1627 scalar_type const s3 = sin<scalar_type>(y3);\r
1628 return qvm_detail::rot_mat_<Dim,Angle>(\r
1629 c1*c3 - c2*s1*s3, s1*s2, c1*s3 + c2*c3*s1,\r
1630 s2*s3, c2, -c3*s2,\r
1631 -c3*s1 - c1*c2*s3, c1*s2, c1*c2*c3 - s1*s3 );\r
1632 }\r
1633\r
1634 template <class A,class Angle>\r
1635 BOOST_QVM_INLINE_OPERATIONS\r
1636 typename enable_if_c<\r
1637 is_mat<A>::value &&\r
1638 mat_traits<A>::rows==mat_traits<A>::cols &&\r
1639 mat_traits<A>::rows>=3,\r
1640 void>::type\r
1641 set_rot_yxy( A & a, Angle y1, Angle x2, Angle y3 )\r
1642 {\r
1643 assign(a,rot_mat_yxy<mat_traits<A>::rows>(y1,x2,y3));\r
1644 }\r
1645\r
1646 template <class A,class Angle>\r
1647 BOOST_QVM_INLINE_OPERATIONS\r
1648 typename enable_if_c<\r
1649 is_mat<A>::value &&\r
1650 mat_traits<A>::rows==mat_traits<A>::cols &&\r
1651 mat_traits<A>::rows>=3,\r
1652 void>::type\r
1653 rotate_yxy( A & a, Angle y1, Angle x2, Angle y3 )\r
1654 {\r
1655 a *= rot_mat_yxy<mat_traits<A>::rows>(y1,x2,y3);\r
1656 }\r
1657\r
1658 ////////////////////////////////////////////////\r
1659\r
1660 template <int Dim,class Angle>\r
1661 BOOST_QVM_INLINE\r
1662 qvm_detail::rot_mat_<Dim,Angle>\r
1663 rot_mat_yzy( Angle y1, Angle z2, Angle y3 )\r
1664 {\r
1665 typedef Angle scalar_type;\r
1666 scalar_type const c1 = cos<scalar_type>(y1);\r
1667 scalar_type const s1 = sin<scalar_type>(y1);\r
1668 scalar_type const c2 = cos<scalar_type>(z2);\r
1669 scalar_type const s2 = sin<scalar_type>(z2);\r
1670 scalar_type const c3 = cos<scalar_type>(y3);\r
1671 scalar_type const s3 = sin<scalar_type>(y3);\r
1672 return qvm_detail::rot_mat_<Dim,Angle>(\r
1673 c1*c2*c3 - s1*s3, -c1*s2, c3*s1 + c1*c2*s3,\r
1674 c3*s2, c2, s2*s3,\r
1675 -c1*s3 - c2*c3*s1, s1*s2, c1*c3 - c2*s1*s3 );\r
1676 }\r
1677\r
1678 template <class A,class Angle>\r
1679 BOOST_QVM_INLINE_OPERATIONS\r
1680 typename enable_if_c<\r
1681 is_mat<A>::value &&\r
1682 mat_traits<A>::rows==mat_traits<A>::cols &&\r
1683 mat_traits<A>::rows>=3,\r
1684 void>::type\r
1685 set_rot_yzy( A & a, Angle y1, Angle z2, Angle y3 )\r
1686 {\r
1687 assign(a,rot_mat_yzy<mat_traits<A>::rows>(y1,z2,y3));\r
1688 }\r
1689\r
1690 template <class A,class Angle>\r
1691 BOOST_QVM_INLINE_OPERATIONS\r
1692 typename enable_if_c<\r
1693 is_mat<A>::value &&\r
1694 mat_traits<A>::rows==mat_traits<A>::cols &&\r
1695 mat_traits<A>::rows>=3,\r
1696 void>::type\r
1697 rotate_yzy( A & a, Angle y1, Angle z2, Angle y3 )\r
1698 {\r
1699 a *= rot_mat_yzy<mat_traits<A>::rows>(y1,z2,y3);\r
1700 }\r
1701\r
1702 ////////////////////////////////////////////////\r
1703\r
1704 template <int Dim,class Angle>\r
1705 BOOST_QVM_INLINE\r
1706 qvm_detail::rot_mat_<Dim,Angle>\r
1707 rot_mat_zyz( Angle z1, Angle y2, Angle z3 )\r
1708 {\r
1709 typedef Angle scalar_type;\r
1710 scalar_type const c1 = cos<scalar_type>(z1);\r
1711 scalar_type const s1 = sin<scalar_type>(z1);\r
1712 scalar_type const c2 = cos<scalar_type>(y2);\r
1713 scalar_type const s2 = sin<scalar_type>(y2);\r
1714 scalar_type const c3 = cos<scalar_type>(z3);\r
1715 scalar_type const s3 = sin<scalar_type>(z3);\r
1716 return qvm_detail::rot_mat_<Dim,Angle>(\r
1717 c1*c2*c3 - s1*s3, -c3*s1 - c1*c2*s3, c1*s2,\r
1718 c1*s3 + c2*c3*s1, c1*c3 - c2*s1*s3, s1*s2,\r
1719 -c3*s2, s2*s3, c2 );\r
1720 }\r
1721\r
1722 template <class A,class Angle>\r
1723 BOOST_QVM_INLINE_OPERATIONS\r
1724 typename enable_if_c<\r
1725 is_mat<A>::value &&\r
1726 mat_traits<A>::rows==mat_traits<A>::cols &&\r
1727 mat_traits<A>::rows>=3,\r
1728 void>::type\r
1729 set_rot_zyz( A & a, Angle z1, Angle y2, Angle z3 )\r
1730 {\r
1731 assign(a,rot_mat_zyz<mat_traits<A>::rows>(z1,y2,z3));\r
1732 }\r
1733\r
1734 template <class A,class Angle>\r
1735 BOOST_QVM_INLINE_OPERATIONS\r
1736 typename enable_if_c<\r
1737 is_mat<A>::value &&\r
1738 mat_traits<A>::rows==mat_traits<A>::cols &&\r
1739 mat_traits<A>::rows>=3,\r
1740 void>::type\r
1741 rotate_zyz( A & a, Angle z1, Angle y2, Angle z3 )\r
1742 {\r
1743 a *= rot_mat_zyz<mat_traits<A>::rows>(z1,y2,z3);\r
1744 }\r
1745\r
1746 ////////////////////////////////////////////////\r
1747\r
1748 template <int Dim,class Angle>\r
1749 BOOST_QVM_INLINE\r
1750 qvm_detail::rot_mat_<Dim,Angle>\r
1751 rot_mat_zxz( Angle z1, Angle x2, Angle z3 )\r
1752 {\r
1753 typedef Angle scalar_type;\r
1754 scalar_type const c1 = cos<scalar_type>(z1);\r
1755 scalar_type const s1 = sin<scalar_type>(z1);\r
1756 scalar_type const c2 = cos<scalar_type>(x2);\r
1757 scalar_type const s2 = sin<scalar_type>(x2);\r
1758 scalar_type const c3 = cos<scalar_type>(z3);\r
1759 scalar_type const s3 = sin<scalar_type>(z3);\r
1760 return qvm_detail::rot_mat_<Dim,Angle>(\r
1761 c1*c3 - c2*s1*s3, -c1*s3 - c2*c3*s1, s1*s2,\r
1762 c3*s1 + c1*c2*s3, c1*c2*c3 - s1*s3, -c1*s2,\r
1763 s2*s3, c3*s2, c2 );\r
1764 }\r
1765\r
1766 template <class A,class Angle>\r
1767 BOOST_QVM_INLINE_OPERATIONS\r
1768 typename enable_if_c<\r
1769 is_mat<A>::value &&\r
1770 mat_traits<A>::rows==mat_traits<A>::cols &&\r
1771 mat_traits<A>::rows>=3,\r
1772 void>::type\r
1773 set_rot_zxz( A & a, Angle z1, Angle x2, Angle z3 )\r
1774 {\r
1775 assign(a,rot_mat_zxz<mat_traits<A>::rows>(z1,x2,z3));\r
1776 }\r
1777\r
1778 template <class A,class Angle>\r
1779 BOOST_QVM_INLINE_OPERATIONS\r
1780 typename enable_if_c<\r
1781 is_mat<A>::value &&\r
1782 mat_traits<A>::rows==mat_traits<A>::cols &&\r
1783 mat_traits<A>::rows>=3,\r
1784 void>::type\r
1785 rotate_zxz( A & a, Angle z1, Angle x2, Angle z3 )\r
1786 {\r
1787 a *= rot_mat_zxz<mat_traits<A>::rows>(z1,x2,z3);\r
1788 }\r
1789\r
1790 ////////////////////////////////////////////////\r
1791\r
b32b8144
FG
1792 namespace\r
1793 qvm_detail\r
1794 {\r
1795 template <int Dim,class Angle>\r
1796 struct\r
1797 rotx_mat_\r
1798 {\r
1799 BOOST_QVM_INLINE_TRIVIAL\r
1800 rotx_mat_()\r
1801 {\r
1802 }\r
1803\r
1804 template <class R>\r
1805 BOOST_QVM_INLINE_TRIVIAL\r
1806 operator R() const\r
1807 {\r
1808 R r;\r
1809 assign(r,*this);\r
1810 return r;\r
1811 }\r
1812\r
1813 private:\r
1814\r
1815 rotx_mat_( rotx_mat_ const & );\r
1816 rotx_mat_ & operator=( rotx_mat_ const & );\r
1817 ~rotx_mat_();\r
1818 };\r
1819\r
1820 template <int Row,int Col>\r
1821 struct\r
1822 rotx_m_get\r
1823 {\r
1824 template <class T>\r
1825 static\r
1826 BOOST_QVM_INLINE_CRITICAL\r
1827 T\r
1828 get( T const & )\r
1829 {\r
1830 return scalar_traits<T>::value(Row==Col);\r
1831 }\r
1832 };\r
1833\r
1834 template <>\r
1835 struct\r
1836 rotx_m_get<1,1>\r
1837 {\r
1838 template <class T>\r
1839 static\r
1840 BOOST_QVM_INLINE_CRITICAL\r
1841 T\r
1842 get( T const & angle )\r
1843 {\r
1844 return cos<T>(angle);\r
1845 }\r
1846 };\r
1847\r
1848 template <>\r
1849 struct\r
1850 rotx_m_get<1,2>\r
1851 {\r
1852 template <class T>\r
1853 static\r
1854 BOOST_QVM_INLINE_CRITICAL\r
1855 T\r
1856 get( T const & angle )\r
1857 {\r
1858 return -sin<T>(angle);\r
1859 }\r
1860 };\r
1861\r
1862 template <>\r
1863 struct\r
1864 rotx_m_get<2,1>\r
1865 {\r
1866 template <class T>\r
1867 static\r
1868 BOOST_QVM_INLINE_CRITICAL\r
1869 T\r
1870 get( T const & angle )\r
1871 {\r
1872 return sin<T>(angle);\r
1873 }\r
1874 };\r
1875\r
1876 template <>\r
1877 struct\r
1878 rotx_m_get<2,2>\r
1879 {\r
1880 template <class T>\r
1881 static\r
1882 BOOST_QVM_INLINE_CRITICAL\r
1883 T\r
1884 get( T const & angle )\r
1885 {\r
1886 return cos<T>(angle);\r
1887 }\r
1888 };\r
1889 }\r
1890\r
1891 template <int Dim,class Angle>\r
1892 struct\r
1893 mat_traits< qvm_detail::rotx_mat_<Dim,Angle> >\r
1894 {\r
1895 typedef qvm_detail::rotx_mat_<Dim,Angle> this_matrix;\r
1896 typedef Angle scalar_type;\r
1897 static int const rows=Dim;\r
1898 static int const cols=Dim;\r
1899\r
1900 template <int Row,int Col>\r
1901 static\r
1902 BOOST_QVM_INLINE_CRITICAL\r
1903 scalar_type\r
1904 read_element( this_matrix const & x )\r
1905 {\r
1906 BOOST_QVM_STATIC_ASSERT(Row>=0);\r
1907 BOOST_QVM_STATIC_ASSERT(Col>=0);\r
1908 BOOST_QVM_STATIC_ASSERT(Row<Dim);\r
1909 BOOST_QVM_STATIC_ASSERT(Col<Dim);\r
1910 return qvm_detail::rotx_m_get<Row,Col>::get(reinterpret_cast<Angle const &>(x));\r
1911 }\r
1912\r
1913 static\r
1914 BOOST_QVM_INLINE_CRITICAL\r
1915 scalar_type\r
1916 read_element_idx( int row, int col, this_matrix const & x )\r
1917 {\r
1918 BOOST_QVM_ASSERT(row>=0);\r
1919 BOOST_QVM_ASSERT(col>=0);\r
1920 BOOST_QVM_ASSERT(row<Dim);\r
1921 BOOST_QVM_ASSERT(col<Dim);\r
1922 Angle const & a=reinterpret_cast<Angle const &>(x);\r
1923 if( row==1 )\r
1924 {\r
1925 if( col==1 )\r
1926 return cos<scalar_type>(a);\r
1927 if( col==2 )\r
1928 return -sin<scalar_type>(a);\r
1929 }\r
1930 if( row==2 )\r
1931 {\r
1932 if( col==1 )\r
1933 return sin<scalar_type>(a);\r
1934 if( col==2 )\r
1935 return cos<scalar_type>(a);\r
1936 }\r
1937 return scalar_traits<scalar_type>::value(row==col);\r
1938 }\r
1939 };\r
1940\r
1941 template <int Dim,class Angle>\r
1942 struct\r
1943 deduce_mat<qvm_detail::rotx_mat_<Dim,Angle>,Dim,Dim>\r
1944 {\r
1945 typedef mat<Angle,Dim,Dim> type;\r
1946 };\r
1947\r
1948 template <int Dim,class Angle>\r
1949 struct\r
1950 deduce_mat2<qvm_detail::rotx_mat_<Dim,Angle>,qvm_detail::rotx_mat_<Dim,Angle>,Dim,Dim>\r
1951 {\r
1952 typedef mat<Angle,Dim,Dim> type;\r
1953 };\r
1954\r
1955 template <int Dim,class Angle>\r
1956 BOOST_QVM_INLINE_TRIVIAL\r
1957 qvm_detail::rotx_mat_<Dim,Angle> const &\r
1958 rotx_mat( Angle const & angle )\r
1959 {\r
1960 BOOST_QVM_STATIC_ASSERT(Dim>=3);\r
1961 return reinterpret_cast<qvm_detail::rotx_mat_<Dim,Angle> const &>(angle);\r
1962 }\r
1963\r
1964 template <class A,class Angle>\r
1965 BOOST_QVM_INLINE_OPERATIONS\r
1966 typename enable_if_c<\r
1967 is_mat<A>::value &&\r
1968 mat_traits<A>::rows>=3 &&\r
1969 mat_traits<A>::rows==mat_traits<A>::cols,\r
1970 void>::type\r
1971 set_rotx( A & a, Angle angle )\r
1972 {\r
1973 assign(a,rotx_mat<mat_traits<A>::rows>(angle));\r
1974 }\r
1975\r
1976 template <class A,class Angle>\r
1977 BOOST_QVM_INLINE_OPERATIONS\r
1978 typename enable_if_c<\r
1979 is_mat<A>::value &&\r
1980 mat_traits<A>::rows>=3 &&\r
1981 mat_traits<A>::rows==mat_traits<A>::cols,\r
1982 void>::type\r
1983 rotate_x( A & a, Angle angle )\r
1984 {\r
1985 a *= rotx_mat<mat_traits<A>::rows>(angle);\r
1986 }\r
1987\r
1988 ////////////////////////////////////////////////\r
1989\r
1990 namespace\r
1991 qvm_detail\r
1992 {\r
1993 template <int Dim,class Angle>\r
1994 struct\r
1995 roty_mat_\r
1996 {\r
1997 BOOST_QVM_INLINE_TRIVIAL\r
1998 roty_mat_()\r
1999 {\r
2000 }\r
2001\r
2002 template <class R>\r
2003 BOOST_QVM_INLINE_TRIVIAL\r
2004 operator R() const\r
2005 {\r
2006 R r;\r
2007 assign(r,*this);\r
2008 return r;\r
2009 }\r
2010\r
2011 private:\r
2012\r
2013 roty_mat_( roty_mat_ const & );\r
2014 roty_mat_ & operator=( roty_mat_ const & );\r
2015 ~roty_mat_();\r
2016 };\r
2017\r
2018 template <int Row,int Col>\r
2019 struct\r
2020 roty_m_get\r
2021 {\r
2022 template <class T>\r
2023 static\r
2024 BOOST_QVM_INLINE_CRITICAL\r
2025 T\r
2026 get( T const & )\r
2027 {\r
2028 return scalar_traits<T>::value(Row==Col);\r
2029 }\r
2030 };\r
2031\r
2032 template <>\r
2033 struct\r
2034 roty_m_get<0,0>\r
2035 {\r
2036 template <class T>\r
2037 static\r
2038 BOOST_QVM_INLINE_CRITICAL\r
2039 T\r
2040 get( T const & angle )\r
2041 {\r
2042 return cos<T>(angle);\r
2043 }\r
2044 };\r
2045\r
2046 template <>\r
2047 struct\r
2048 roty_m_get<0,2>\r
2049 {\r
2050 template <class T>\r
2051 static\r
2052 BOOST_QVM_INLINE_CRITICAL\r
2053 T\r
2054 get( T const & angle )\r
2055 {\r
2056 return sin<T>(angle);\r
2057 }\r
2058 };\r
2059\r
2060 template <>\r
2061 struct\r
2062 roty_m_get<2,0>\r
2063 {\r
2064 template <class T>\r
2065 static\r
2066 BOOST_QVM_INLINE_CRITICAL\r
2067 T\r
2068 get( T const & angle )\r
2069 {\r
2070 return -sin<T>(angle);\r
2071 }\r
2072 };\r
2073\r
2074 template <>\r
2075 struct\r
2076 roty_m_get<2,2>\r
2077 {\r
2078 template <class T>\r
2079 static\r
2080 BOOST_QVM_INLINE_CRITICAL\r
2081 T\r
2082 get( T const & angle )\r
2083 {\r
2084 return cos<T>(angle);\r
2085 }\r
2086 };\r
2087 }\r
2088\r
2089 template <int Dim,class Angle>\r
2090 struct\r
2091 mat_traits< qvm_detail::roty_mat_<Dim,Angle> >\r
2092 {\r
2093 typedef qvm_detail::roty_mat_<Dim,Angle> this_matrix;\r
2094 typedef Angle scalar_type;\r
2095 static int const rows=Dim;\r
2096 static int const cols=Dim;\r
2097\r
2098 template <int Row,int Col>\r
2099 static\r
2100 BOOST_QVM_INLINE_CRITICAL\r
2101 scalar_type\r
2102 read_element( this_matrix const & x )\r
2103 {\r
2104 BOOST_QVM_STATIC_ASSERT(Row>=0);\r
2105 BOOST_QVM_STATIC_ASSERT(Col>=0);\r
2106 BOOST_QVM_STATIC_ASSERT(Row<Dim);\r
2107 BOOST_QVM_STATIC_ASSERT(Col<Dim);\r
2108 return qvm_detail::roty_m_get<Row,Col>::get(reinterpret_cast<Angle const &>(x));\r
2109 }\r
2110\r
2111 static\r
2112 BOOST_QVM_INLINE_CRITICAL\r
2113 scalar_type\r
2114 read_element_idx( int row, int col, this_matrix const & x )\r
2115 {\r
2116 BOOST_QVM_ASSERT(row>=0);\r
2117 BOOST_QVM_ASSERT(col>=0);\r
2118 BOOST_QVM_ASSERT(row<Dim);\r
2119 BOOST_QVM_ASSERT(col<Dim);\r
2120 Angle const & a=reinterpret_cast<Angle const &>(x);\r
2121 if( row==0 )\r
2122 {\r
2123 if( col==0 )\r
2124 return cos<scalar_type>(a);\r
2125 if( col==2 )\r
2126 return sin<scalar_type>(a);\r
2127 }\r
2128 if( row==2 )\r
2129 {\r
2130 if( col==0 )\r
2131 return -sin<scalar_type>(a);\r
2132 if( col==2 )\r
2133 return cos<scalar_type>(a);\r
2134 }\r
2135 return scalar_traits<scalar_type>::value(row==col);\r
2136 }\r
2137 };\r
2138\r
2139 template <int Dim,class Angle>\r
2140 struct\r
2141 deduce_mat<qvm_detail::roty_mat_<Dim,Angle>,Dim,Dim>\r
2142 {\r
2143 typedef mat<Angle,Dim,Dim> type;\r
2144 };\r
2145\r
2146 template <int Dim,class Angle>\r
2147 struct\r
2148 deduce_mat2<qvm_detail::roty_mat_<Dim,Angle>,qvm_detail::roty_mat_<Dim,Angle>,Dim,Dim>\r
2149 {\r
2150 typedef mat<Angle,Dim,Dim> type;\r
2151 };\r
2152\r
2153 template <int Dim,class Angle>\r
2154 BOOST_QVM_INLINE_TRIVIAL\r
2155 qvm_detail::roty_mat_<Dim,Angle> const &\r
2156 roty_mat( Angle const & angle )\r
2157 {\r
2158 BOOST_QVM_STATIC_ASSERT(Dim>=3);\r
2159 return reinterpret_cast<qvm_detail::roty_mat_<Dim,Angle> const &>(angle);\r
2160 }\r
2161\r
2162 template <class A,class Angle>\r
2163 BOOST_QVM_INLINE_OPERATIONS\r
2164 typename enable_if_c<\r
2165 is_mat<A>::value &&\r
2166 mat_traits<A>::rows>=2 &&\r
2167 mat_traits<A>::rows==mat_traits<A>::cols,\r
2168 void>::type\r
2169 set_roty( A & a, Angle angle )\r
2170 {\r
2171 assign(a,roty_mat<mat_traits<A>::rows>(angle));\r
2172 }\r
2173\r
2174 template <class A,class Angle>\r
2175 BOOST_QVM_INLINE_OPERATIONS\r
2176 typename enable_if_c<\r
2177 is_mat<A>::value &&\r
2178 mat_traits<A>::rows>=3 &&\r
2179 mat_traits<A>::rows==mat_traits<A>::cols,\r
2180 void>::type\r
2181 rotate_y( A & a, Angle angle )\r
2182 {\r
2183 a *= roty_mat<mat_traits<A>::rows>(angle);\r
2184 }\r
2185\r
2186 ////////////////////////////////////////////////\r
2187\r
2188 namespace\r
2189 qvm_detail\r
2190 {\r
2191 template <int Dim,class Angle>\r
2192 struct\r
2193 rotz_mat_\r
2194 {\r
2195 BOOST_QVM_INLINE_TRIVIAL\r
2196 rotz_mat_()\r
2197 {\r
2198 }\r
2199\r
2200 template <class R>\r
2201 BOOST_QVM_INLINE_TRIVIAL\r
2202 operator R() const\r
2203 {\r
2204 R r;\r
2205 assign(r,*this);\r
2206 return r;\r
2207 }\r
2208\r
2209 private:\r
2210\r
2211 rotz_mat_( rotz_mat_ const & );\r
2212 rotz_mat_ & operator=( rotz_mat_ const & );\r
2213 ~rotz_mat_();\r
2214 };\r
2215\r
2216 template <int Row,int Col>\r
2217 struct\r
2218 rotz_m_get\r
2219 {\r
2220 template <class T>\r
2221 static\r
2222 BOOST_QVM_INLINE_CRITICAL\r
2223 T\r
2224 get( T const & )\r
2225 {\r
2226 return scalar_traits<T>::value(Row==Col);\r
2227 }\r
2228 };\r
2229\r
2230 template <>\r
2231 struct\r
2232 rotz_m_get<0,0>\r
2233 {\r
2234 template <class T>\r
2235 static\r
2236 BOOST_QVM_INLINE_CRITICAL\r
2237 T\r
2238 get( T const & angle )\r
2239 {\r
2240 return cos<T>(angle);\r
2241 }\r
2242 };\r
2243\r
2244 template <>\r
2245 struct\r
2246 rotz_m_get<0,1>\r
2247 {\r
2248 template <class T>\r
2249 static\r
2250 BOOST_QVM_INLINE_CRITICAL\r
2251 T\r
2252 get( T const & angle )\r
2253 {\r
2254 return -sin<T>(angle);\r
2255 }\r
2256 };\r
2257\r
2258 template <>\r
2259 struct\r
2260 rotz_m_get<1,0>\r
2261 {\r
2262 template <class T>\r
2263 static\r
2264 BOOST_QVM_INLINE_CRITICAL\r
2265 T\r
2266 get( T const & angle )\r
2267 {\r
2268 return sin<T>(angle);\r
2269 }\r
2270 };\r
2271\r
2272 template <>\r
2273 struct\r
2274 rotz_m_get<1,1>\r
2275 {\r
2276 template <class T>\r
2277 static\r
2278 BOOST_QVM_INLINE_CRITICAL\r
2279 T\r
2280 get( T const & angle )\r
2281 {\r
2282 return cos<T>(angle);\r
2283 }\r
2284 };\r
2285 }\r
2286\r
2287 template <int Dim,class Angle>\r
2288 struct\r
2289 mat_traits< qvm_detail::rotz_mat_<Dim,Angle> >\r
2290 {\r
2291 typedef qvm_detail::rotz_mat_<Dim,Angle> this_matrix;\r
2292 typedef Angle scalar_type;\r
2293 static int const rows=Dim;\r
2294 static int const cols=Dim;\r
2295\r
2296 template <int Row,int Col>\r
2297 static\r
2298 BOOST_QVM_INLINE_CRITICAL\r
2299 scalar_type\r
2300 read_element( this_matrix const & x )\r
2301 {\r
2302 BOOST_QVM_STATIC_ASSERT(Row>=0);\r
2303 BOOST_QVM_STATIC_ASSERT(Col>=0);\r
2304 BOOST_QVM_STATIC_ASSERT(Row<Dim);\r
2305 BOOST_QVM_STATIC_ASSERT(Col<Dim);\r
2306 return qvm_detail::rotz_m_get<Row,Col>::get(reinterpret_cast<Angle const &>(x));\r
2307 }\r
2308\r
2309 static\r
2310 BOOST_QVM_INLINE_CRITICAL\r
2311 scalar_type\r
2312 read_element_idx( int row, int col, this_matrix const & x )\r
2313 {\r
2314 BOOST_QVM_ASSERT(row>=0);\r
2315 BOOST_QVM_ASSERT(col>=0);\r
2316 BOOST_QVM_ASSERT(row<Dim);\r
2317 BOOST_QVM_ASSERT(col<Dim);\r
2318 Angle const & a=reinterpret_cast<Angle const &>(x);\r
2319 if( row==0 )\r
2320 {\r
2321 if( col==0 )\r
2322 return cos<scalar_type>(a);\r
2323 if( col==1 )\r
2324 return -sin<scalar_type>(a);\r
2325 }\r
2326 if( row==1 )\r
2327 {\r
2328 if( col==0 )\r
2329 return sin<scalar_type>(a);\r
2330 if( col==1 )\r
2331 return cos<scalar_type>(a);\r
2332 }\r
2333 return scalar_traits<scalar_type>::value(row==col);\r
2334 }\r
2335 };\r
2336\r
2337 template <int Dim,class Angle>\r
2338 struct\r
2339 deduce_mat<qvm_detail::rotz_mat_<Dim,Angle>,Dim,Dim>\r
2340 {\r
2341 typedef mat<Angle,Dim,Dim> type;\r
2342 };\r
2343\r
2344 template <int Dim,class Angle,int R,int C>\r
2345 struct\r
2346 deduce_mat2<qvm_detail::rotz_mat_<Dim,Angle>,qvm_detail::rotz_mat_<Dim,Angle>,R,C>\r
2347 {\r
2348 typedef mat<Angle,R,C> type;\r
2349 };\r
2350\r
2351 template <int Dim,class Angle>\r
2352 BOOST_QVM_INLINE_TRIVIAL\r
2353 qvm_detail::rotz_mat_<Dim,Angle> const &\r
2354 rotz_mat( Angle const & angle )\r
2355 {\r
2356 BOOST_QVM_STATIC_ASSERT(Dim>=2);\r
2357 return reinterpret_cast<qvm_detail::rotz_mat_<Dim,Angle> const &>(angle);\r
2358 }\r
2359\r
2360 template <class A,class Angle>\r
2361 BOOST_QVM_INLINE_OPERATIONS\r
2362 typename enable_if_c<\r
2363 is_mat<A>::value &&\r
2364 mat_traits<A>::rows>=2 &&\r
2365 mat_traits<A>::rows==mat_traits<A>::cols,\r
2366 void>::type\r
2367 set_rotz( A & a, Angle angle )\r
2368 {\r
2369 assign(a,rotz_mat<mat_traits<A>::rows>(angle));\r
2370 }\r
2371\r
2372 template <class A,class Angle>\r
2373 BOOST_QVM_INLINE_OPERATIONS\r
2374 typename enable_if_c<\r
2375 is_mat<A>::value &&\r
2376 mat_traits<A>::rows>=2 &&\r
2377 mat_traits<A>::rows==mat_traits<A>::cols,\r
2378 void>::type\r
2379 rotate_z( A & a, Angle angle )\r
2380 {\r
2381 a *= rotz_mat<mat_traits<A>::rows>(angle);\r
2382 }\r
2383\r
2384 ////////////////////////////////////////////////\r
2385\r
2386 namespace\r
2387 qvm_detail\r
2388 {\r
2389 template <int D>\r
2390 struct\r
2391 inverse_m_defined\r
2392 {\r
2393 static bool const value=false;\r
2394 };\r
2395 }\r
2396\r
2397 template <class A,class B>\r
2398 BOOST_QVM_INLINE_TRIVIAL\r
2399 typename lazy_enable_if_c<\r
2400 is_mat<A>::value && is_scalar<B>::value &&\r
2401 mat_traits<A>::rows==mat_traits<A>::cols &&\r
2402 !qvm_detail::inverse_m_defined<mat_traits<A>::rows>::value,\r
2403 deduce_mat<A> >::type\r
2404 inverse( A const & a, B det )\r
2405 {\r
2406 typedef typename mat_traits<A>::scalar_type T;\r
2407 BOOST_QVM_ASSERT(det!=scalar_traits<T>::value(0));\r
2408 T f=scalar_traits<T>::value(1)/det;\r
2409 typedef typename deduce_mat<A>::type cofactor_return_type;\r
2410 cofactor_return_type c=qvm_detail::cofactor_impl(a);\r
2411 return reinterpret_cast<qvm_detail::transposed_<cofactor_return_type> const &>(c) * f;\r
2412 }\r
2413\r
2414 template <class A>\r
2415 BOOST_QVM_INLINE_TRIVIAL\r
2416 typename lazy_enable_if_c<\r
2417 is_mat<A>::value &&\r
2418 mat_traits<A>::rows==mat_traits<A>::cols &&\r
2419 !qvm_detail::inverse_m_defined<mat_traits<A>::rows>::value,\r
2420 deduce_mat<A> >::type\r
2421 inverse( A const & a )\r
2422 {\r
2423 typedef typename mat_traits<A>::scalar_type T;\r
2424 T det=determinant(a);\r
2425 if( det==scalar_traits<T>::value(0) )\r
2426 BOOST_QVM_THROW_EXCEPTION(zero_determinant_error());\r
2427 return inverse(a,det);\r
2428 }\r
2429\r
2430 ////////////////////////////////////////////////\r
2431\r
2432 namespace\r
2433 sfinae\r
2434 {\r
2435 using ::boost::qvm::to_string;\r
2436 using ::boost::qvm::assign;\r
2437 using ::boost::qvm::determinant;\r
2438 using ::boost::qvm::cmp;\r
2439 using ::boost::qvm::convert_to;\r
2440 using ::boost::qvm::set_identity;\r
2441 using ::boost::qvm::set_zero;\r
2442 using ::boost::qvm::scalar_cast;\r
2443 using ::boost::qvm::operator/=;\r
2444 using ::boost::qvm::operator/;\r
2445 using ::boost::qvm::operator==;\r
2446 using ::boost::qvm::operator-=;\r
2447 using ::boost::qvm::operator-;\r
2448 using ::boost::qvm::operator*=;\r
2449 using ::boost::qvm::operator*;\r
2450 using ::boost::qvm::operator!=;\r
2451 using ::boost::qvm::operator+=;\r
2452 using ::boost::qvm::operator+;\r
2453 using ::boost::qvm::mref;\r
2454 using ::boost::qvm::rot_mat;\r
2455 using ::boost::qvm::set_rot;\r
2456 using ::boost::qvm::rotate;\r
2457 using ::boost::qvm::set_rotx;\r
2458 using ::boost::qvm::rotate_x;\r
2459 using ::boost::qvm::set_roty;\r
2460 using ::boost::qvm::rotate_y;\r
2461 using ::boost::qvm::set_rotz;\r
2462 using ::boost::qvm::rotate_z;\r
2463 using ::boost::qvm::inverse;\r
2464 }\r
2465\r
2466 ////////////////////////////////////////////////\r
2467 }\r
2468 }\r
2469\r
2470#endif\r