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