vec_mat_operations.hpp 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. #ifndef BOOST_QVM_VEC_MAT_OPERATIONS_HPP_INCLUDED
  2. #define BOOST_QVM_VEC_MAT_OPERATIONS_HPP_INCLUDED
  3. // Copyright 2008-2022 Emil Dotchevski and Reverge Studios, Inc.
  4. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  5. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. #include <boost/qvm/vec_mat_operations2.hpp>
  7. #include <boost/qvm/vec_mat_operations3.hpp>
  8. #include <boost/qvm/vec_mat_operations4.hpp>
  9. namespace boost { namespace qvm {
  10. namespace
  11. qvm_detail
  12. {
  13. template <int M,int N>
  14. struct
  15. mul_mv_defined
  16. {
  17. static bool const value=false;
  18. };
  19. }
  20. template <class A,class B>
  21. BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
  22. typename lazy_enable_if_c<
  23. is_mat<A>::value && is_vec<B>::value &&
  24. mat_traits<A>::cols==vec_traits<B>::dim &&
  25. !qvm_detail::mul_mv_defined<mat_traits<A>::rows,mat_traits<A>::cols>::value,
  26. deduce_vec2<A,B,mat_traits<A>::rows> >::type
  27. operator*( A const & a, B const & b )
  28. {
  29. typedef typename deduce_vec2<A,B,mat_traits<A>::rows>::type R;
  30. R r;
  31. for( int i=0; i<mat_traits<A>::rows; ++i )
  32. {
  33. typedef typename vec_traits<R>::scalar_type Tr;
  34. Tr x(scalar_traits<Tr>::value(0));
  35. for( int j=0; j<mat_traits<A>::cols; ++j )
  36. x += mat_traits<A>::read_element_idx(i,j,a)*vec_traits<B>::read_element_idx(j,b);
  37. write_vec_element_idx(i,r,x);
  38. }
  39. return r;
  40. }
  41. namespace
  42. qvm_detail
  43. {
  44. template <int M,int N>
  45. struct
  46. mul_vm_defined
  47. {
  48. static bool const value=false;
  49. };
  50. }
  51. template <class A,class B>
  52. BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
  53. typename lazy_enable_if_c<
  54. is_vec<A>::value && is_mat<B>::value &&
  55. vec_traits<A>::dim==mat_traits<B>::rows &&
  56. !qvm_detail::mul_vm_defined<mat_traits<B>::rows,mat_traits<B>::cols>::value,
  57. deduce_vec2<A,B,mat_traits<B>::cols> >::type
  58. operator*( A const & a, B const & b )
  59. {
  60. typedef typename deduce_vec2<A,B,mat_traits<B>::cols>::type R;
  61. R r;
  62. for( int i=0; i<mat_traits<B>::cols; ++i )
  63. {
  64. typedef typename vec_traits<R>::scalar_type Tr;
  65. Tr x(scalar_traits<Tr>::value(0));
  66. for( int j=0; j<mat_traits<B>::rows; ++j )
  67. x += vec_traits<A>::read_element_idx(j,a)*mat_traits<B>::read_element_idx(j,i,b);
  68. write_vec_element_idx(i,r,x);
  69. }
  70. return r;
  71. }
  72. ////////////////////////////////////////////////
  73. template <class A,class B>
  74. BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
  75. typename lazy_enable_if_c<
  76. mat_traits<A>::rows==4 && mat_traits<A>::cols==4 &&
  77. vec_traits<B>::dim==3,
  78. deduce_vec2<A,B,3> >::type
  79. transform_point( A const & a, B const & b )
  80. {
  81. typedef typename mat_traits<A>::scalar_type Ta;
  82. typedef typename vec_traits<B>::scalar_type Tb;
  83. Ta const a00 = mat_traits<A>::template read_element<0,0>(a);
  84. Ta const a01 = mat_traits<A>::template read_element<0,1>(a);
  85. Ta const a02 = mat_traits<A>::template read_element<0,2>(a);
  86. Ta const a03 = mat_traits<A>::template read_element<0,3>(a);
  87. Ta const a10 = mat_traits<A>::template read_element<1,0>(a);
  88. Ta const a11 = mat_traits<A>::template read_element<1,1>(a);
  89. Ta const a12 = mat_traits<A>::template read_element<1,2>(a);
  90. Ta const a13 = mat_traits<A>::template read_element<1,3>(a);
  91. Ta const a20 = mat_traits<A>::template read_element<2,0>(a);
  92. Ta const a21 = mat_traits<A>::template read_element<2,1>(a);
  93. Ta const a22 = mat_traits<A>::template read_element<2,2>(a);
  94. Ta const a23 = mat_traits<A>::template read_element<2,3>(a);
  95. Tb const b0 = vec_traits<B>::template read_element<0>(b);
  96. Tb const b1 = vec_traits<B>::template read_element<1>(b);
  97. Tb const b2 = vec_traits<B>::template read_element<2>(b);
  98. typedef typename deduce_vec2<A,B,3>::type R;
  99. BOOST_QVM_STATIC_ASSERT(vec_traits<R>::dim==3);
  100. R r;
  101. write_vec_element<0>(r, a00*b0+a01*b1+a02*b2+a03);
  102. write_vec_element<1>(r, a10*b0+a11*b1+a12*b2+a13);
  103. write_vec_element<2>(r, a20*b0+a21*b1+a22*b2+a23);
  104. return r;
  105. }
  106. template <class A,class B>
  107. BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
  108. typename lazy_enable_if_c<
  109. mat_traits<A>::rows==4 && mat_traits<A>::cols==4 &&
  110. vec_traits<B>::dim==3,
  111. deduce_vec2<A,B,3> >::type
  112. transform_vector( A const & a, B const & b )
  113. {
  114. typedef typename mat_traits<A>::scalar_type Ta;
  115. typedef typename vec_traits<B>::scalar_type Tb;
  116. Ta const a00 = mat_traits<A>::template read_element<0,0>(a);
  117. Ta const a01 = mat_traits<A>::template read_element<0,1>(a);
  118. Ta const a02 = mat_traits<A>::template read_element<0,2>(a);
  119. Ta const a10 = mat_traits<A>::template read_element<1,0>(a);
  120. Ta const a11 = mat_traits<A>::template read_element<1,1>(a);
  121. Ta const a12 = mat_traits<A>::template read_element<1,2>(a);
  122. Ta const a20 = mat_traits<A>::template read_element<2,0>(a);
  123. Ta const a21 = mat_traits<A>::template read_element<2,1>(a);
  124. Ta const a22 = mat_traits<A>::template read_element<2,2>(a);
  125. Tb const b0 = vec_traits<B>::template read_element<0>(b);
  126. Tb const b1 = vec_traits<B>::template read_element<1>(b);
  127. Tb const b2 = vec_traits<B>::template read_element<2>(b);
  128. typedef typename deduce_vec2<A,B,3>::type R;
  129. BOOST_QVM_STATIC_ASSERT(vec_traits<R>::dim==3);
  130. R r;
  131. write_vec_element<0>(r, a00*b0+a01*b1+a02*b2);
  132. write_vec_element<1>(r, a10*b0+a11*b1+a12*b2);
  133. write_vec_element<2>(r, a20*b0+a21*b1+a22*b2);
  134. return r;
  135. }
  136. ////////////////////////////////////////////////
  137. namespace
  138. sfinae
  139. {
  140. using ::boost::qvm::operator*;
  141. using ::boost::qvm::transform_point;
  142. using ::boost::qvm::transform_vector;
  143. }
  144. } }
  145. #endif