• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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