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 #include <boost/qvm/operations.hpp>
7 #include <boost/qvm/quat.hpp>
8 #include <boost/qvm/vec.hpp>
9 #include <boost/qvm/mat.hpp>
10
11 namespace
12 my_stuff
13 {
14 struct
15 mat
16 {
17 float a[3][3];
18 };
19
20 struct
21 vec
22 {
23 float a[3];
24 };
25
26 struct
27 quat
28 {
29 float a[4];
30 };
31 }
32
33 namespace
34 boost
35 {
36 namespace
37 qvm
38 {
39 template <>
40 struct
41 mat_traits<my_stuff::mat>
42 {
43 typedef float scalar_type;
44 static int const rows=3;
45 static int const cols=3;
46
47 template <int R,int C>
48 static
49 scalar_type &
write_elementboost::qvm::mat_traits50 write_element( my_stuff::mat & m )
51 {
52 BOOST_QVM_STATIC_ASSERT(R>=0);
53 BOOST_QVM_STATIC_ASSERT(R<rows);
54 BOOST_QVM_STATIC_ASSERT(C>=0);
55 BOOST_QVM_STATIC_ASSERT(C<cols);
56 return m.a[R][C];
57 }
58
59 template <int R,int C>
60 static
61 scalar_type
read_elementboost::qvm::mat_traits62 read_element( my_stuff::mat const & m )
63 {
64 BOOST_QVM_STATIC_ASSERT(R>=0);
65 BOOST_QVM_STATIC_ASSERT(R<rows);
66 BOOST_QVM_STATIC_ASSERT(C>=0);
67 BOOST_QVM_STATIC_ASSERT(C<cols);
68 return m.a[R][C];
69 }
70
71 static
72 inline
73 scalar_type &
write_element_idxboost::qvm::mat_traits74 write_element_idx( int r, int c, my_stuff::mat & m )
75 {
76 BOOST_QVM_ASSERT(r>=0);
77 BOOST_QVM_ASSERT(r<rows);
78 BOOST_QVM_ASSERT(c>=0);
79 BOOST_QVM_ASSERT(c<cols);
80 return m.a[r][c];
81 }
82
83 static
84 inline
85 scalar_type
read_element_idxboost::qvm::mat_traits86 read_element_idx( int r, int c, my_stuff::mat const & m )
87 {
88 BOOST_QVM_ASSERT(r>=0);
89 BOOST_QVM_ASSERT(r<rows);
90 BOOST_QVM_ASSERT(c>=0);
91 BOOST_QVM_ASSERT(c<cols);
92 return m.a[r][c];
93 }
94 };
95
96 template <>
97 struct
98 vec_traits<my_stuff::vec>
99 {
100 static int const dim=3;
101 typedef float scalar_type;
102
103 template <int I>
104 static
105 scalar_type &
write_elementboost::qvm::vec_traits106 write_element( my_stuff::vec & m )
107 {
108 BOOST_QVM_STATIC_ASSERT(I>=0);
109 BOOST_QVM_STATIC_ASSERT(I<dim);
110 return m.a[I];
111 }
112
113 template <int I>
114 static
115 scalar_type
read_elementboost::qvm::vec_traits116 read_element( my_stuff::vec const & m )
117 {
118 BOOST_QVM_STATIC_ASSERT(I>=0);
119 BOOST_QVM_STATIC_ASSERT(I<dim);
120 return m.a[I];
121 }
122
123 static
124 inline
125 scalar_type &
write_element_idxboost::qvm::vec_traits126 write_element_idx( int i, my_stuff::vec & m )
127 {
128 BOOST_QVM_ASSERT(i>=0);
129 BOOST_QVM_ASSERT(i<dim);
130 return m.a[i];
131 }
132
133 static
134 inline
135 scalar_type
read_element_idxboost::qvm::vec_traits136 read_element_idx( int i, my_stuff::vec const & m )
137 {
138 BOOST_QVM_ASSERT(i>=0);
139 BOOST_QVM_ASSERT(i<dim);
140 return m.a[i];
141 }
142 };
143
144 template <>
145 struct
146 quat_traits<my_stuff::quat>
147 {
148 typedef float scalar_type;
149
150 template <int I>
151 static
152 scalar_type &
write_elementboost::qvm::quat_traits153 write_element( my_stuff::quat & m )
154 {
155 BOOST_QVM_STATIC_ASSERT(I>=0);
156 BOOST_QVM_STATIC_ASSERT(I<4);
157 return m.a[I];
158 }
159
160 template <int I>
161 static
162 scalar_type
read_elementboost::qvm::quat_traits163 read_element( my_stuff::quat const & m )
164 {
165 BOOST_QVM_STATIC_ASSERT(I>=0);
166 BOOST_QVM_STATIC_ASSERT(I<4);
167 return m.a[I];
168 }
169 };
170 }
171 }
172
173 namespace
174 my_stuff
175 {
176 mat &
operator /=(mat & x,float y)177 operator/=( mat & x, float y )
178 {
179 return boost::qvm::operator/=(x,y);
180 }
181
182 vec &
operator /=(vec & x,float y)183 operator/=( vec & x, float y )
184 {
185 return boost::qvm::operator/=(x,y);
186 }
187
188 quat &
operator /=(quat & x,float y)189 operator/=( quat & x, float y )
190 {
191 return boost::qvm::operator/=(x,y);
192 }
193
194 mat &
operator *=(mat & x,float y)195 operator*=( mat & x, float y )
196 {
197 return boost::qvm::operator*=(x,y);
198 }
199
200 vec &
operator *=(vec & x,float y)201 operator*=( vec & x, float y )
202 {
203 return boost::qvm::operator*=(x,y);
204 }
205
206 quat &
operator *=(quat & x,float y)207 operator*=( quat & x, float y )
208 {
209 return boost::qvm::operator*=(x,y);
210 }
211
212 mat
operator /(mat const & x,float y)213 operator/( mat const & x, float y )
214 {
215 return boost::qvm::operator/(x,y);
216 }
217
218 vec
operator /(vec const & x,float y)219 operator/( vec const & x, float y )
220 {
221 return boost::qvm::operator/(x,y);
222 }
223
224 quat
operator /(quat const & x,float y)225 operator/( quat const & x, float y )
226 {
227 return boost::qvm::operator/(x,y);
228 }
229
230 mat
operator *(mat const & x,float y)231 operator*( mat const & x, float y )
232 {
233 return boost::qvm::operator*(x,y);
234 }
235
236 vec
operator *(vec const & x,float y)237 operator*( vec const & x, float y )
238 {
239 return boost::qvm::operator*(x,y);
240 }
241
242 quat
operator *(quat const & x,float y)243 operator*( quat const & x, float y )
244 {
245 return boost::qvm::operator*(x,y);
246 }
247
248 mat &
operator *=(mat & x,mat const & y)249 operator*=( mat & x, mat const & y )
250 {
251 return boost::qvm::operator*=(x,y);
252 }
253
254 mat
operator *=(mat const & x,mat const & y)255 operator*=( mat const & x, mat const & y )
256 {
257 return boost::qvm::operator*(x,y);
258 }
259
260 vec
operator *(mat const & x,vec const & y)261 operator*( mat const & x, vec const & y )
262 {
263 return boost::qvm::operator*(x,y);
264 }
265
266 vec
operator *(quat const & x,vec const & y)267 operator*( quat const & x, vec const & y )
268 {
269 return boost::qvm::operator*(x,y);
270 }
271
272 vec
operator *(vec const & x,mat const & y)273 operator*( vec const & x, mat const & y )
274 {
275 return boost::qvm::operator*(x,y);
276 }
277
278 bool
operator ==(mat const & x,mat const & y)279 operator==( mat const & x, mat const & y )
280 {
281 return boost::qvm::operator==(x,y);
282 }
283
284 bool
operator !=(mat const & x,mat const & y)285 operator!=( mat const & x, mat const & y )
286 {
287 return boost::qvm::operator!=(x,y);
288 }
289
290 bool
operator ==(vec const & x,vec const & y)291 operator==( vec const & x, vec const & y )
292 {
293 return boost::qvm::operator==(x,y);
294 }
295
296 bool
operator !=(vec const & x,vec const & y)297 operator!=( vec const & x, vec const & y )
298 {
299 return boost::qvm::operator!=(x,y);
300 }
301
302 bool
operator ==(quat const & x,quat const & y)303 operator==( quat const & x, quat const & y )
304 {
305 return boost::qvm::operator==(x,y);
306 }
307
308 bool
operator !=(quat const & x,quat const & y)309 operator!=( quat const & x, quat const & y )
310 {
311 return boost::qvm::operator!=(x,y);
312 }
313 }
314
315 int
main()316 main()
317 {
318 using namespace boost::qvm::sfinae;
319 using namespace my_stuff;
320 typedef boost::qvm::mat<double,3,3> mat2;
321 typedef boost::qvm::vec<double,3> vec2;
322 typedef boost::qvm::quat<double> quat2;
323
324 mat ma1, mb1; set_zero(ma1); set_zero(mb1);
325 vec va1, vb1; set_zero(va1); set_zero(vb1);
326 quat qa1, qb1; set_zero(qa1); set_zero(qb1);
327 mat2 ma2, mb2; set_zero(ma2); set_zero(mb2);
328 vec2 va2, vb2; set_zero(va2); set_zero(vb2);
329 quat2 qa2, qb2; set_zero(qa2); set_zero(qb2);
330
331 set_zero(ma1);
332 set_zero(mb1);
333 set_zero(va1);
334 set_zero(vb1);
335 set_zero(qa1);
336 set_zero(qb1);
337 set_zero(ma2);
338 set_zero(mb2);
339 set_zero(va2);
340 set_zero(vb2);
341 set_zero(qa2);
342 set_zero(qb2);
343
344 ma1/=2;
345 va1/=2;
346 qa1/=2;
347 ma2/=2;
348 va2/=2;
349 qa2/=2;
350
351 ma1*=2;
352 va1*=2;
353 qa1*=2;
354 ma2*=2;
355 va2*=2;
356 qa2*=2;
357
358 mb1=ma1/2;
359 vb1=va1/2;
360 qb1=qb1/2;
361 mb2=convert_to<mat2>(ma1/2);
362 vb2=convert_to<vec2>(va1/2);
363 qb2=convert_to<quat2>(qa1/2);
364 mb1=scalar_cast<float>(ma2/2);
365 vb1=scalar_cast<float>(va2/2);
366 qb1=scalar_cast<float>(qa2/2);
367
368 mb1=ma1*2;
369 vb1=va1*2;
370 qb1=qa1*2;
371 mb2=convert_to<mat2>(ma1*2);
372 vb2=convert_to<vec2>(va1*2);
373 qb2=convert_to<quat2>(qa1*2);
374 mb1=scalar_cast<float>(ma2*2);
375 vb1=scalar_cast<float>(va2*2);
376 qb1=scalar_cast<float>(qa2*2);
377
378 ma1*=mb1;
379 ma1*=scalar_cast<float>(ma2);
380 ma2*=ma1;
381
382 va1=ma1*va1;
383 va1=qa1*va1;
384 va1=scalar_cast<float>(ma2*va1);
385 va1=scalar_cast<float>(ma1*va2);
386 va1=scalar_cast<float>(ma2*va2);
387 va1=scalar_cast<float>(qa2*va1);
388 va1=scalar_cast<float>(qa1*va2);
389 va1=scalar_cast<float>(qa2*va2);
390
391 va2=convert_to<vec2>(ma1*va1);
392 va2=convert_to<vec2>(qa1*va1);
393 va2=ma2*va1;
394 va2=ma1*va2;
395 va2=ma2*va2;
396 va2=qa2*va1;
397 va2=qa1*va2;
398 va2=qa2*va2;
399
400 va1=va1*ma1;
401 va1=scalar_cast<float>(va1*ma2);
402 va1=scalar_cast<float>(va2*ma1);
403 va1=scalar_cast<float>(va2*ma2);
404
405 va2=convert_to<vec2>(va1*ma1);
406 va2=va1*ma2;
407 va2=va2*ma1;
408 va2=va2*ma2;
409
410 (void) (ma1==mb1);
411 (void) (ma1==ma2);
412 (void) (ma2==ma1);
413
414 (void) (ma1!=mb1);
415 (void) (ma1!=ma2);
416 (void) (ma2!=ma1);
417
418 (void) (va1==vb1);
419 (void) (va1==va2);
420 (void) (va2==va1);
421
422 (void) (va1!=vb1);
423 (void) (va1!=va2);
424 (void) (va2!=va1);
425
426 (void) (qa1==qb1);
427 (void) (qa1==qa2);
428 (void) (qa2==qa1);
429
430 (void) (qa1!=qb1);
431 (void) (qa1!=qa2);
432 (void) (qa2!=qa1);
433
434 return 0;
435 }
436