File indexing completed on 2025-01-18 09:51:08
0001 #ifndef BOOST_QVM_VEC_MAT_OPERATIONS_HPP_INCLUDED
0002 #define BOOST_QVM_VEC_MAT_OPERATIONS_HPP_INCLUDED
0003
0004
0005
0006
0007
0008
0009 #include <boost/qvm/vec_mat_operations2.hpp>
0010 #include <boost/qvm/vec_mat_operations3.hpp>
0011 #include <boost/qvm/vec_mat_operations4.hpp>
0012
0013 namespace boost { namespace qvm {
0014
0015 namespace
0016 qvm_detail
0017 {
0018 template <int M,int N>
0019 struct
0020 mul_mv_defined
0021 {
0022 static bool const value=false;
0023 };
0024 }
0025
0026 template <class A,class B>
0027 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
0028 typename lazy_enable_if_c<
0029 is_mat<A>::value && is_vec<B>::value &&
0030 mat_traits<A>::cols==vec_traits<B>::dim &&
0031 !qvm_detail::mul_mv_defined<mat_traits<A>::rows,mat_traits<A>::cols>::value,
0032 deduce_vec2<A,B,mat_traits<A>::rows> >::type
0033 operator*( A const & a, B const & b )
0034 {
0035 typedef typename deduce_vec2<A,B,mat_traits<A>::rows>::type R;
0036 R r;
0037 for( int i=0; i<mat_traits<A>::rows; ++i )
0038 {
0039 typedef typename vec_traits<R>::scalar_type Tr;
0040 Tr x(scalar_traits<Tr>::value(0));
0041 for( int j=0; j<mat_traits<A>::cols; ++j )
0042 x += mat_traits<A>::read_element_idx(i,j,a)*vec_traits<B>::read_element_idx(j,b);
0043 write_vec_element_idx(i,r,x);
0044 }
0045 return r;
0046 }
0047
0048 namespace
0049 qvm_detail
0050 {
0051 template <int M,int N>
0052 struct
0053 mul_vm_defined
0054 {
0055 static bool const value=false;
0056 };
0057 }
0058
0059 template <class A,class B>
0060 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
0061 typename lazy_enable_if_c<
0062 is_vec<A>::value && is_mat<B>::value &&
0063 vec_traits<A>::dim==mat_traits<B>::rows &&
0064 !qvm_detail::mul_vm_defined<mat_traits<B>::rows,mat_traits<B>::cols>::value,
0065 deduce_vec2<A,B,mat_traits<B>::cols> >::type
0066 operator*( A const & a, B const & b )
0067 {
0068 typedef typename deduce_vec2<A,B,mat_traits<B>::cols>::type R;
0069 R r;
0070 for( int i=0; i<mat_traits<B>::cols; ++i )
0071 {
0072 typedef typename vec_traits<R>::scalar_type Tr;
0073 Tr x(scalar_traits<Tr>::value(0));
0074 for( int j=0; j<mat_traits<B>::rows; ++j )
0075 x += vec_traits<A>::read_element_idx(j,a)*mat_traits<B>::read_element_idx(j,i,b);
0076 write_vec_element_idx(i,r,x);
0077 }
0078 return r;
0079 }
0080
0081
0082
0083 template <class A,class B>
0084 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
0085 typename lazy_enable_if_c<
0086 mat_traits<A>::rows==4 && mat_traits<A>::cols==4 &&
0087 vec_traits<B>::dim==3,
0088 deduce_vec2<A,B,3> >::type
0089 transform_point( A const & a, B const & b )
0090 {
0091 typedef typename mat_traits<A>::scalar_type Ta;
0092 typedef typename vec_traits<B>::scalar_type Tb;
0093 Ta const a00 = mat_traits<A>::template read_element<0,0>(a);
0094 Ta const a01 = mat_traits<A>::template read_element<0,1>(a);
0095 Ta const a02 = mat_traits<A>::template read_element<0,2>(a);
0096 Ta const a03 = mat_traits<A>::template read_element<0,3>(a);
0097 Ta const a10 = mat_traits<A>::template read_element<1,0>(a);
0098 Ta const a11 = mat_traits<A>::template read_element<1,1>(a);
0099 Ta const a12 = mat_traits<A>::template read_element<1,2>(a);
0100 Ta const a13 = mat_traits<A>::template read_element<1,3>(a);
0101 Ta const a20 = mat_traits<A>::template read_element<2,0>(a);
0102 Ta const a21 = mat_traits<A>::template read_element<2,1>(a);
0103 Ta const a22 = mat_traits<A>::template read_element<2,2>(a);
0104 Ta const a23 = mat_traits<A>::template read_element<2,3>(a);
0105 Tb const b0 = vec_traits<B>::template read_element<0>(b);
0106 Tb const b1 = vec_traits<B>::template read_element<1>(b);
0107 Tb const b2 = vec_traits<B>::template read_element<2>(b);
0108 typedef typename deduce_vec2<A,B,3>::type R;
0109 BOOST_QVM_STATIC_ASSERT(vec_traits<R>::dim==3);
0110 R r;
0111 write_vec_element<0>(r, a00*b0+a01*b1+a02*b2+a03);
0112 write_vec_element<1>(r, a10*b0+a11*b1+a12*b2+a13);
0113 write_vec_element<2>(r, a20*b0+a21*b1+a22*b2+a23);
0114 return r;
0115 }
0116
0117 template <class A,class B>
0118 BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_OPERATIONS
0119 typename lazy_enable_if_c<
0120 mat_traits<A>::rows==4 && mat_traits<A>::cols==4 &&
0121 vec_traits<B>::dim==3,
0122 deduce_vec2<A,B,3> >::type
0123 transform_vector( A const & a, B const & b )
0124 {
0125 typedef typename mat_traits<A>::scalar_type Ta;
0126 typedef typename vec_traits<B>::scalar_type Tb;
0127 Ta const a00 = mat_traits<A>::template read_element<0,0>(a);
0128 Ta const a01 = mat_traits<A>::template read_element<0,1>(a);
0129 Ta const a02 = mat_traits<A>::template read_element<0,2>(a);
0130 Ta const a10 = mat_traits<A>::template read_element<1,0>(a);
0131 Ta const a11 = mat_traits<A>::template read_element<1,1>(a);
0132 Ta const a12 = mat_traits<A>::template read_element<1,2>(a);
0133 Ta const a20 = mat_traits<A>::template read_element<2,0>(a);
0134 Ta const a21 = mat_traits<A>::template read_element<2,1>(a);
0135 Ta const a22 = mat_traits<A>::template read_element<2,2>(a);
0136 Tb const b0 = vec_traits<B>::template read_element<0>(b);
0137 Tb const b1 = vec_traits<B>::template read_element<1>(b);
0138 Tb const b2 = vec_traits<B>::template read_element<2>(b);
0139 typedef typename deduce_vec2<A,B,3>::type R;
0140 BOOST_QVM_STATIC_ASSERT(vec_traits<R>::dim==3);
0141 R r;
0142 write_vec_element<0>(r, a00*b0+a01*b1+a02*b2);
0143 write_vec_element<1>(r, a10*b0+a11*b1+a12*b2);
0144 write_vec_element<2>(r, a20*b0+a21*b1+a22*b2);
0145 return r;
0146 }
0147
0148
0149
0150 namespace
0151 sfinae
0152 {
0153 using ::boost::qvm::operator*;
0154 using ::boost::qvm::transform_point;
0155 using ::boost::qvm::transform_vector;
0156 }
0157
0158 } }
0159
0160 #endif