Visualization Library 2.0.0

A lightweight C++ OpenGL middleware for 2D/3D graphics

VL     Star     Watch     Fork     Issue

[Download] [Tutorials] [All Classes] [Grouped Classes]
glsl_math.hpp
Go to the documentation of this file.
1 /**************************************************************************************/
2 /* */
3 /* Visualization Library */
4 /* http://visualizationlibrary.org */
5 /* */
6 /* Copyright (c) 2005-2020, Michele Bosi */
7 /* All rights reserved. */
8 /* */
9 /* Redistribution and use in source and binary forms, with or without modification, */
10 /* are permitted provided that the following conditions are met: */
11 /* */
12 /* - Redistributions of source code must retain the above copyright notice, this */
13 /* list of conditions and the following disclaimer. */
14 /* */
15 /* - Redistributions in binary form must reproduce the above copyright notice, this */
16 /* list of conditions and the following disclaimer in the documentation and/or */
17 /* other materials provided with the distribution. */
18 /* */
19 /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND */
20 /* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED */
21 /* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE */
22 /* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR */
23 /* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES */
24 /* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; */
25 /* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON */
26 /* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */
27 /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */
28 /* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
29 /* */
30 /**************************************************************************************/
31 
32 #ifndef glslmath_INCLUDE_ONCE
33 #define glslmath_INCLUDE_ONCE
34 
87 #include <cmath>
88 #include <limits>
89 #include <vlCore/Vector4.hpp>
90 #include <vlCore/Matrix4.hpp>
91 
92 #undef min
93 #undef max
94 
95 #if defined(__CUDACC__)
96 #undef isnan
97 #undef isinf
98 #endif
99 
100 namespace vl
101 {
102  // hyperbolic functions not implemented in Visual C++
103 
104  // taken from http://support.microsoft.com/kb/625449/it
105 
106  template<typename T>
107  T asinh(T x) { return log(x+::sqrt(x*x+1)); }
108 
109  template<typename T>
110  T acosh(T x)
111  {
112  // must be x>=1, if not return Nan (Not a Number)
113  if(!(x>=1)) return ::sqrt((T)-1);
114 
115  // return only the positive result (as sqrt does).
116  return log(x+::sqrt(x*x-1));
117  }
118 
119  template<typename T>
120  T atanh(T x)
121  {
122  // must be x>-1, x<1, if not return Nan (Not a Number)
123  if(!(x>-1 && x<1)) return ::sqrt((T)-1);
124 
125  return log((1+x)/(1-x))/2;
126  }
127 
128  // isinf, isnan functions not implemented in Visual C++
129 
130  template<typename T> bool isnan(T value) { return !(value == value); }
131  template<typename T> bool isinf(T value) { return value < std::numeric_limits<T>::min() || value > std::numeric_limits<T>::max(); }
132  template<typename T> bool isinf_pos(T value) { return value > std::numeric_limits<T>::max(); }
133  template<typename T> bool isinf_neg(T value) { return value < std::numeric_limits<T>::min(); }
134 
135  //-----------------------------------------------------------------------------
136  // GLSL functions
137  //-----------------------------------------------------------------------------
138 
139  template<typename T>
140  T modf(T a, T& intpart);
141 
142  // --------------- angle and trigonometric functions ---------------
143 
144  // --------------- radians ---------------
145 
146  template<typename T>
147  T radians(T degrees) { return degrees * (T)dDEG_TO_RAD; }
148 
149  template<typename T>
151  return Vector2<T>( degrees.x() * (T)dDEG_TO_RAD,
152  degrees.y() * (T)dDEG_TO_RAD );
153  }
154 
155  template<typename T>
157  return Vector3<T>( degrees.x() * (T)dDEG_TO_RAD,
158  degrees.y() * (T)dDEG_TO_RAD,
159  degrees.z() * (T)dDEG_TO_RAD );
160  }
161 
162  template<typename T>
164  return Vector4<T>( degrees.x() * (T)dDEG_TO_RAD,
165  degrees.y() * (T)dDEG_TO_RAD,
166  degrees.z() * (T)dDEG_TO_RAD,
167  degrees.w() * (T)dDEG_TO_RAD );
168  }
169 
170  // --------------- degrees ---------------
171 
172  template<typename T>
173  T degrees(T radians) { return radians * (T)dRAD_TO_DEG; }
174 
175  template<typename T>
177  return Vector2<T>( radians.x() * (T)dRAD_TO_DEG,
178  radians.y() * (T)dRAD_TO_DEG );
179  }
180 
181  template<typename T>
183  return Vector3<T>( radians.x() * (T)dRAD_TO_DEG,
184  radians.y() * (T)dRAD_TO_DEG,
185  radians.z() * (T)dRAD_TO_DEG );
186  }
187 
188  template<typename T>
190  return Vector4<T>( radians.x() * (T)dRAD_TO_DEG,
191  radians.y() * (T)dRAD_TO_DEG,
192  radians.z() * (T)dRAD_TO_DEG,
193  radians.w() * (T)dRAD_TO_DEG );
194  }
195 
196  // --------------- sin ---------------
197 
198  template<typename T>
199  T sin(T a) { return ::sin(a); }
200 
201  template<typename T>
202  Vector2<T> sin(const Vector2<T>& angle) {
203  return Vector2<T>( ::sin(angle.x()),
204  ::sin(angle.y()) );
205  }
206 
207  template<typename T>
208  Vector3<T> sin(const Vector3<T>& angle) {
209  return Vector3<T>( ::sin(angle.x()),
210  ::sin(angle.y()),
211  ::sin(angle.z()) );
212  }
213 
214  template<typename T>
215  Vector4<T> sin(const Vector4<T>& angle) {
216  return Vector4<T>( ::sin(angle.x()),
217  ::sin(angle.y()),
218  ::sin(angle.z()),
219  ::sin(angle.w()) );
220  }
221 
222  // --------------- cos ---------------
223 
224  template<typename T>
225  T cos(T a) { return ::cos(a); }
226 
227  template<typename T>
228  Vector2<T> cos(const Vector2<T>& angle) {
229  return Vector2<T>( ::cos(angle.x()),
230  ::cos(angle.y()) );
231  }
232 
233  template<typename T>
234  Vector3<T> cos(const Vector3<T>& angle) {
235  return Vector3<T>( ::cos(angle.x()),
236  ::cos(angle.y()),
237  ::cos(angle.z()) );
238  }
239 
240  template<typename T>
241  Vector4<T> cos(const Vector4<T>& angle) {
242  return Vector4<T>( ::cos(angle.x()),
243  ::cos(angle.y()),
244  ::cos(angle.z()),
245  ::cos(angle.w()) );
246  }
247 
248  // --------------- tan ---------------
249 
250  template<typename T>
251  T tan(T a) { return ::tan(a); }
252 
253  template<typename T>
254  Vector2<T> tan(const Vector2<T>& angle) {
255  return Vector2<T>( ::tan(angle.x()),
256  ::tan(angle.y()) );
257  }
258 
259  template<typename T>
260  Vector3<T> tan(const Vector3<T>& angle) {
261  return Vector3<T>( ::tan(angle.x()),
262  ::tan(angle.y()),
263  ::tan(angle.z()) );
264  }
265 
266  template<typename T>
267  Vector4<T> tan(const Vector4<T>& angle) {
268  return Vector4<T>( ::tan(angle.x()),
269  ::tan(angle.y()),
270  ::tan(angle.z()),
271  ::tan(angle.w()) );
272  }
273 
274  // --------------- atan ---------------
275 
276  template<typename T>
277  T atan(T a) { return ::atan(a); }
278 
279  template<typename T>
280  Vector2<T> atan(const Vector2<T>& a, const Vector2<T>& b) {
281  return Vector2<T>( ::atan2(a.x(), b.x()),
282  ::atan2(a.y(), b.y()) );
283  }
284 
285  template<typename T>
286  Vector3<T> atan(const Vector3<T>& a, const Vector3<T>& b) {
287  return Vector3<T>( ::atan2(a.x(), b.x()),
288  ::atan2(a.y(), b.y()),
289  ::atan2(a.z(), b.z()) );
290  }
291 
292  template<typename T>
293  Vector4<T> atan(const Vector4<T>& a, const Vector4<T>& b) {
294  return Vector4<T>( ::atan2(a.x(), b.x()),
295  ::atan2(a.y(), b.y()),
296  ::atan2(a.z(), b.z()),
297  ::atan2(a.w(), b.w()) );
298  }
299 
300  // --------------- asin ---------------
301 
302  template<typename T>
303  T asin(T a) { return ::asin(a); }
304 
305  template<typename T>
306  Vector2<T> asin(const Vector2<T>& angle) {
307  return Vector2<T>( ::asin(angle.x()),
308  ::asin(angle.y()) );
309  }
310 
311  template<typename T>
312  Vector3<T> asin(const Vector3<T>& angle) {
313  return Vector3<T>( ::asin(angle.x()),
314  ::asin(angle.y()),
315  ::asin(angle.z()) );
316  }
317 
318  template<typename T>
319  Vector4<T> asin(const Vector4<T>& angle) {
320  return Vector4<T>( ::asin(angle.x()),
321  ::asin(angle.y()),
322  ::asin(angle.z()),
323  ::asin(angle.w()) );
324  }
325 
326  // --------------- acos ---------------
327 
328  template<typename T>
329  T acos(T a) { return ::acos(a); }
330 
331  template<typename T>
332  Vector2<T> acos(const Vector2<T>& angle) {
333  return Vector2<T>( ::acos(angle.x()),
334  ::acos(angle.y()) );
335  }
336 
337  template<typename T>
338  Vector3<T> acos(const Vector3<T>& angle) {
339  return Vector3<T>( ::acos(angle.x()),
340  ::acos(angle.y()),
341  ::acos(angle.z()) );
342  }
343 
344  template<typename T>
345  Vector4<T> acos(const Vector4<T>& angle) {
346  return Vector4<T>( ::acos(angle.x()),
347  ::acos(angle.y()),
348  ::acos(angle.z()),
349  ::acos(angle.w()) );
350  }
351 
352  // --------------- hyperbolic functions ---------------
353 
354  // --------------- sinh ---------------
355 
356  template<typename T>
357  T sinh(T a) { return (exp(a) - exp(-a)) / 2; }
358 
359  template<typename T>
360  Vector2<T> sinh(const Vector2<T>& a) { return Vector2<T>( sinh(a.x()), sinh(a.y()) ); }
361 
362  template<typename T>
363  Vector3<T> sinh(const Vector3<T>& a) { return Vector3<T>( sinh(a.x()), sinh(a.y()), sinh(a.z()) ); }
364 
365  template<typename T>
366  Vector4<T> sinh(const Vector4<T>& a) { return Vector4<T>( sinh(a.x()), sinh(a.y()), sinh(a.z()), sinh(a.w()) ); }
367 
368  // --------------- cosh ---------------
369 
370  template<typename T>
371  T cosh(T a) { return (exp(a) + exp(-a)) / 2; }
372 
373  template<typename T>
374  Vector2<T> cosh(const Vector2<T>& a) { return Vector2<T>( cosh(a.x()), cosh(a.y()) ); }
375 
376  template<typename T>
377  Vector3<T> cosh(const Vector3<T>& a) { return Vector3<T>( cosh(a.x()), cosh(a.y()), cosh(a.z()) ); }
378 
379  template<typename T>
380  Vector4<T> cosh(const Vector4<T>& a) { return Vector4<T>( cosh(a.x()), cosh(a.y()), cosh(a.z()), cosh(a.w()) ); }
381 
382  // --------------- tanh ---------------
383 
384  template<typename T>
385  T tanh(T a) { return sinh(a) / cosh(a); }
386 
387  template<typename T>
388  Vector2<T> tanh(const Vector2<T>& a) { return Vector2<T>( tanh(a.x()), tanh(a.y()) ); }
389 
390  template<typename T>
391  Vector3<T> tanh(const Vector3<T>& a) { return Vector3<T>( tanh(a.x()), tanh(a.y()), tanh(a.z()) ); }
392 
393  template<typename T>
394  Vector4<T> tanh(const Vector4<T>& a) { return Vector4<T>( tanh(a.x()), tanh(a.y()), tanh(a.z()), tanh(a.w()) ); }
395 
396  // --------------- asinh ---------------
397 
398  template<typename T>
399  Vector2<T> asinh(const Vector2<T>& a) { return Vector2<T>( asinh(a.x()), asinh(a.y()) ); }
400 
401  template<typename T>
402  Vector3<T> asinh(const Vector3<T>& a) { return Vector3<T>( asinh(a.x()), asinh(a.y()), asinh(a.z()) ); }
403 
404  template<typename T>
405  Vector4<T> asinh(const Vector4<T>& a) { return Vector4<T>( asinh(a.x()), asinh(a.y()), asinh(a.z()), asinh(a.w()) ); }
406 
407  // --------------- acosh ---------------
408 
409  template<typename T>
410  Vector2<T> acosh(const Vector2<T>& a) { return Vector2<T>( acosh(a.x()), acosh(a.y()) ); }
411 
412  template<typename T>
413  Vector3<T> acosh(const Vector3<T>& a) { return Vector3<T>( acosh(a.x()), acosh(a.y()), acosh(a.z()) ); }
414 
415  template<typename T>
416  Vector4<T> acosh(const Vector4<T>& a) { return Vector4<T>( acosh(a.x()), acosh(a.y()), acosh(a.z()), acosh(a.w()) ); }
417 
418  // --------------- atanh ---------------
419 
420  template<typename T>
421  Vector2<T> atanh(const Vector2<T>& a) { return Vector2<T>( atanh(a.x()), atanh(a.y()) ); }
422 
423  template<typename T>
424  Vector3<T> atanh(const Vector3<T>& a) { return Vector3<T>( atanh(a.x()), atanh(a.y()), atanh(a.z()) ); }
425 
426  template<typename T>
427  Vector4<T> atanh(const Vector4<T>& a) { return Vector4<T>( atanh(a.x()), atanh(a.y()), atanh(a.z()), atanh(a.w()) ); }
428 
429  // --------------- exponential functions ---------------
430 
431  // --------------- pow ---------------
432 
433  template<typename T>
434  T pow(T a, T b) { return (T)::pow(a, b); }
435 
436  template<typename T>
437  Vector2<T> pow(const Vector2<T>& a, const Vector2<T>& b) {
438  return Vector2<T>( (T)::pow(a.x(), b.x()),
439  (T)::pow(a.y(), b.y()) );
440  }
441 
442  template<typename T>
443  Vector3<T> pow(const Vector3<T>& a, const Vector3<T>& b) {
444  return Vector3<T>( (T)::pow(a.x(), b.x()),
445  (T)::pow(a.y(), b.y()),
446  (T)::pow(a.z(), b.z()) );
447  }
448 
449  template<typename T>
450  Vector4<T> pow(const Vector4<T>& a, const Vector4<T>& b) {
451  return Vector4<T>( (T)::pow(a.x(), b.x()),
452  (T)::pow(a.y(), b.y()),
453  (T)::pow(a.z(), b.z()),
454  (T)::pow(a.w(), b.w()) );
455  }
456 
457  // --------------- exp ---------------
458 
459  template<typename T>
460  T exp(T a) { return (T)::exp(a); }
461 
462  template<typename T>
464  return Vector2<T>( (T)::exp(a.x()),
465  (T)::exp(a.y()) );
466  }
467 
468  template<typename T>
470  return Vector3<T>( (T)::exp(a.x()),
471  (T)::exp(a.y()),
472  (T)::exp(a.z()) );
473  }
474 
475  template<typename T>
477  return Vector4<T>( (T)::exp(a.x()),
478  (T)::exp(a.y()),
479  (T)::exp(a.z()),
480  (T)::exp(a.w()) );
481  }
482 
483  // --------------- log ---------------
484 
485  template<typename T>
486  T log(T a) { return (T)::log(a); }
487 
488  template<typename T>
490  return Vector2<T>( (T)::log(a.x()),
491  (T)::log(a.y()) );
492  }
493 
494  template<typename T>
496  return Vector3<T>( (T)::log(a.x()),
497  (T)::log(a.y()),
498  (T)::log(a.z()) );
499  }
500 
501  template<typename T>
503  return Vector4<T>( (T)::log(a.x()),
504  (T)::log(a.y()),
505  (T)::log(a.z()),
506  (T)::log(a.w()) );
507  }
508 
509  // --------------- exp2 ---------------
510 
511  template<typename T>
512  T exp2(T a) { return (T)::pow(2, a); }
513 
514  template<typename T>
516  return Vector2<T>( (T)::pow(2, a.x()),
517  (T)::pow(2, a.y()) );
518  }
519 
520  template<typename T>
522  return Vector3<T>( (T)::pow(2, a.x()),
523  (T)::pow(2, a.y()),
524  (T)::pow(2, a.z()) );
525  }
526 
527  template<typename T>
529  return Vector4<T>( (T)::pow(2, a.x()),
530  (T)::pow(2, a.y()),
531  (T)::pow(2, a.z()),
532  (T)::pow(2, a.w()) );
533  }
534 
535  // --------------- log2 ---------------
536 
537  template<typename T>
538  T log2(T a) { return log10(a) / log10(2); }
539 
540  template<typename T>
542  return Vector2<T>( log2(a.x()),
543  log2(a.y()) );
544  }
545 
546  template<typename T>
548  return Vector3<T>( log2(a.x()),
549  log2(a.y()),
550  log2(a.z()) );
551  }
552 
553  template<typename T>
555  return Vector4<T>( log2(a.x()),
556  log2(a.y()),
557  log2(a.z()),
558  log2(a.w()) );
559  }
560 
561  // --------------- log10 ---------------
562 
563  // this is not present in the GLSL standard
564 
565  template<typename T>
566  T log10(T a) { return (T)::log10(a); }
567 
568  template<typename T>
570  return Vector2<T>( (T)::log10(a.x()),
571  (T)::log10(a.y()) );
572  }
573 
574  template<typename T>
576  return Vector3<T>( (T)::log10(a.x()),
577  (T)::log10(a.y()),
578  (T)::log10(a.z()) );
579  }
580 
581  template<typename T>
583  return Vector4<T>( (T)::log10(a.x()),
584  (T)::log10(a.y()),
585  (T)::log10(a.z()),
586  (T)::log10(a.w()) );
587  }
588 
589  // --------------- sqrt ---------------
590 
591  template<typename T>
592  T sqrt(T a) { return ::sqrt(a); }
593 
594  template<typename T>
596  return Vector2<T>( ::sqrt(a.x()),
597  ::sqrt(a.y()) );
598  }
599 
600  template<typename T>
602  return Vector3<T>( ::sqrt(a.x()),
603  ::sqrt(a.y()),
604  ::sqrt(a.z()) );
605  }
606 
607  template<typename T>
609  return Vector4<T>( ::sqrt(a.x()),
610  ::sqrt(a.y()),
611  ::sqrt(a.z()),
612  ::sqrt(a.w()) );
613  }
614 
615  // --------------- inversesqrt ---------------
616 
617  template<typename T>
618  T inversesqrt(T a) { return ::sqrt(a); }
619 
620  template<typename T>
622  return Vector2<T>( T(1) / ::sqrt(a.x()),
623  T(1) / ::sqrt(a.y()) );
624  }
625 
626  template<typename T>
628  return Vector3<T>( T(1) / ::sqrt(a.x()),
629  T(1) / ::sqrt(a.y()),
630  T(1) / ::sqrt(a.z()) );
631  }
632 
633  template<typename T>
635  return Vector4<T>( T(1) / ::sqrt(a.x()),
636  T(1) / ::sqrt(a.y()),
637  T(1) / ::sqrt(a.z()),
638  T(1) / ::sqrt(a.w()) );
639  }
640 
641  // --------------- common functions ---------------
642 
643  // --------------- abs ---------------
644 
645  template<typename T>
646  T abs(T a) { return a >= 0 ? a : -a; }
647 
648  template<typename T>
650  {
651  return Vector2<T>( a.x() >= 0 ? a.x() : -a.x(), a.y() >= 0 ? a.y() : -a.y() );
652  }
653 
654  template<typename T>
656  {
657  return Vector3<T>( a.x() >= 0 ? a.x() : -a.x(), a.y() >= 0 ? a.y() : -a.y(), a.z() >= 0 ? a.z() : -a.z() );
658  }
659 
660  template<typename T>
662  {
663  return Vector4<T>( a.x() >= 0 ? a.x() : -a.x(), a.y() >= 0 ? a.y() : -a.y(), a.z() >= 0 ? a.z() : -a.z(), a.w() >= 0 ? a.w() : -a.w() );
664  }
665 
666  // --------------- sign ---------------
667 
668  template<typename T>
669  T sign(T a) { return a > 0 ? 1 : a == 0 ? 0 : (T)-1; }
670 
671  template<typename T>
673  {
674  return Vector2<T>( a.x() > 0 ? 1 : a.x() == 0 ? 0 : (T)-1,
675  a.y() > 0 ? 1 : a.y() == 0 ? 0 : (T)-1 );
676  }
677 
678  template<typename T>
680  {
681  return Vector3<T>( a.x() > 0 ? 1 : a.x() == 0 ? 0 : (T)-1,
682  a.y() > 0 ? 1 : a.y() == 0 ? 0 : (T)-1,
683  a.z() > 0 ? 1 : a.z() == 0 ? 0 : (T)-1 );
684  }
685 
686  template<typename T>
688  {
689  return Vector4<T>( a.x() > 0 ? 1 : a.x() == 0 ? 0 : (T)-1,
690  a.y() > 0 ? 1 : a.y() == 0 ? 0 : (T)-1,
691  a.z() > 0 ? 1 : a.z() == 0 ? 0 : (T)-1,
692  a.w() > 0 ? 1 : a.w() == 0 ? 0 : (T)-1 );
693  }
694 
695  // --------------- floor ---------------
696 
697  template<typename T>
698  T floor(T a) { return ::floor(a); }
699 
700  template<typename T>
702  return Vector2<T>( ::floor(a.x()),
703  ::floor(a.y()) );
704  }
705 
706  template<typename T>
708  return Vector3<T>( ::floor(a.x()),
709  ::floor(a.y()),
710  ::floor(a.z()) );
711  }
712 
713  template<typename T>
715  return Vector4<T>( ::floor(a.x()),
716  ::floor(a.y()),
717  ::floor(a.z()),
718  ::floor(a.w()) );
719  }
720 
721  // --------------- fract ---------------
722 
723  template<typename T>
724  T fract(T a) { return a - floor(a); }
725 
726  template<typename T>
727  Vector2<T> fract(const Vector2<T>& a) { return a - floor(a); }
728 
729  template<typename T>
730  Vector3<T> fract(const Vector3<T>& a) { return a - floor(a); }
731 
732  template<typename T>
733  Vector4<T> fract(const Vector4<T>& a) { return a - floor(a); }
734 
735  // --------------- trunc ---------------
736 
737  template<typename T>
738  T trunc(T a) { return a - fract(a); }
739 
740  template<typename T>
742  return Vector2<T>( a.x() - fract(a.x()),
743  a.y() - fract(a.y()) );
744  }
745 
746  template<typename T>
748  return Vector3<T>( a.x() - fract(a.x()),
749  a.y() - fract(a.y()),
750  a.z() - fract(a.z()) );
751  }
752 
753  template<typename T>
755  return Vector4<T>( a.x() - fract(a.x()),
756  a.y() - fract(a.y()),
757  a.z() - fract(a.z()),
758  a.w() - fract(a.w()) );
759  }
760 
761  // --------------- round ---------------
762 
763  template<typename T>
764  T round(T x) { return ((x - floor(x)) >= 0.5) ? ceil(x) : floor(x); }
765 
766  template<typename T>
768  return Vector2<T>( round(a.x()),
769  round(a.y()) );
770  }
771 
772  template<typename T>
774  return Vector3<T>( round(a.x()),
775  round(a.y()),
776  round(a.z()) );
777  }
778 
779  template<typename T>
781  return Vector4<T>( round(a.x()),
782  round(a.y()),
783  round(a.z()),
784  round(a.w()) );
785  }
786 
787  // --------------- modf ---------------
788 
789  inline
790  float modf(float a, float& intpart) {
791  #if defined(_MSC_VER)
792  return ::modf(a,&intpart);
793  #else
794  double dintpart = intpart;
795  float r = (float)::modf((double)a,&dintpart);
796  intpart = (float)dintpart;
797  return r;
798  #endif
799  }
800 
801  inline
802  double modf(double a, double& intpart) { return ::modf(a,&intpart); }
803 
804  template<typename T>
805  Vector2<T> modf(const Vector2<T>& a, Vector2<T>& intpart) {
806  return Vector2<T>( modf(a.x(), intpart.x()),
807  modf(a.y(), intpart.y()) );
808  }
809 
810  template<typename T>
811  Vector3<T> modf(const Vector3<T>& a, Vector3<T>& intpart) {
812  return Vector3<T>( modf(a.x(), intpart.x()),
813  modf(a.y(), intpart.y()),
814  modf(a.z(), intpart.z()) );
815  }
816 
817  template<typename T>
818  Vector4<T> modf(const Vector4<T>& a, Vector4<T>& intpart) {
819  return Vector4<T>( modf(a.x(), intpart.x()),
820  modf(a.y(), intpart.y()),
821  modf(a.z(), intpart.z()),
822  modf(a.w(), intpart.w()) );
823  }
824 
825  // --------------- roundEven ---------------
826 
827  inline
828  float roundEven(float a, float epsilon)
829  {
830  if( a < 0 )
831  return -roundEven(-a, epsilon);
832  else
833  {
834  float intpart;
835  vl::modf( a, intpart );
836 
837  // 0.5 case
838  if ((a -(intpart + 0.5f)) < epsilon)
839  {
840  // is even
841  if (::fmod(intpart, 2) < epsilon)
842  return intpart;
843  else
844  // is odd
845  return ceil(intpart + 0.5f);
846  }
847  else
848  // all the other cases
849  return round(a);
850  }
851  }
852 
853  inline
854  double roundEven(double a, double epsilon)
855  {
856  if( a < 0 )
857  return -roundEven(-a, epsilon);
858  else
859  {
860  double intpart;
861  vl::modf( a, intpart );
862 
863  // 0.5 case
864  if ((a -(intpart + 0.5)) < epsilon)
865  {
866  // is even
867  if (::fmod(intpart, 2) < epsilon)
868  return intpart;
869  else
870  // is odd
871  return ceil(intpart + 0.5);
872  }
873  else
874  // all the other cases
875  return round(a);
876  }
877  }
878 
879  template<typename T>
880  Vector2<T> roundEven(const Vector2<T>& a, T epsilon = 0.00001) {
881  return Vector2<T>( roundEven(a.x(), epsilon),
882  roundEven(a.y(), epsilon) );
883  }
884 
885  template<typename T>
886  Vector3<T> roundEven(const Vector3<T>& a, T epsilon = 0.00001) {
887  return Vector3<T>( roundEven(a.x(), epsilon),
888  roundEven(a.y(), epsilon),
889  roundEven(a.z(), epsilon) );
890  }
891 
892  template<typename T>
893  Vector4<T> roundEven(const Vector4<T>& a, T epsilon = 0.00001) {
894  return Vector4<T>( roundEven(a.x(), epsilon),
895  roundEven(a.y(), epsilon),
896  roundEven(a.z(), epsilon),
897  roundEven(a.w(), epsilon) );
898  }
899 
900  // --------------- ceil ---------------
901 
902  template<typename T>
903  T ceil(T a) { return ::ceil(a); }
904 
905  template<typename T>
907  return Vector2<T>( ::ceil(a.x()),
908  ::ceil(a.y()) );
909  }
910 
911  template<typename T>
913  return Vector3<T>( ::ceil(a.x()),
914  ::ceil(a.y()),
915  ::ceil(a.z()) );
916  }
917 
918  template<typename T>
920  return Vector4<T>( ::ceil(a.x()),
921  ::ceil(a.y()),
922  ::ceil(a.z()),
923  ::ceil(a.w()) );
924  }
925 
926  // --------------- mod ---------------
927 
928  template<typename T>
929  T mod(T a, T b) { return a - b * floor(a/b); }
930 
931  template<typename T>
932  Vector2<T> mod(const Vector2<T>& a, T b) { return a - b * floor(a/b); }
933 
934  template<typename T>
935  Vector3<T> mod(const Vector3<T>& a, T b) { return a - b * floor(a/b); }
936 
937  template<typename T>
938  Vector4<T> mod(const Vector4<T>& a, T b) { return a - b * floor(a/b); }
939 
940  template<typename T>
941  Vector2<T> mod(const Vector2<T>& a, const Vector2<T>& b) { return a - b * floor(a/b); }
942 
943  template<typename T>
944  Vector3<T> mod(const Vector3<T>& a, const Vector3<T>& b) { return a - b * floor(a/b); }
945 
946  template<typename T>
947  Vector4<T> mod(const Vector4<T>& a, const Vector4<T>& b) { return a - b * floor(a/b); }
948 
949  // --------------- mix ---------------
950 
951  template<typename T>
952  T mix(T a, T b, T t) { return a*(1-t) + b*t; }
953 
954  template<typename T>
955  Vector2<T> mix(const Vector2<T>& a, const Vector2<T>& b, T t) { return a*(1-t) + b*t; }
956 
957  template<typename T>
958  Vector3<T> mix(const Vector3<T>& a, const Vector3<T>& b, T t) { return a*(1-t) + b*t; }
959 
960  template<typename T>
961  Vector4<T> mix(const Vector4<T>& a, const Vector4<T>& b, T t) { return a*(1-t) + b*t; }
962 
963  template<typename T>
964  Vector2<T> mix(const Vector2<T>& a, const Vector2<T>& b, const Vector2<T>& t)
965  {
966  return Vector2<T>( a.x()*(1-t.x()) + b.x()*t.x(),
967  a.y()*(1-t.y()) + b.y()*t.y() );
968  }
969 
970  template<typename T>
971  Vector3<T> mix(const Vector3<T>& a, const Vector3<T>& b, const Vector3<T>& t)
972  {
973  return Vector3<T>( a.x()*(1-t.x()) + b.x()*t.x(),
974  a.y()*(1-t.y()) + b.y()*t.y(),
975  a.z()*(1-t.z()) + b.z()*t.z() );
976  }
977 
978  template<typename T>
979  Vector4<T> mix(const Vector4<T>& a, const Vector4<T>& b, const Vector4<T>& t)
980  {
981  return Vector4<T>( a.x()*(1-t.x()) + b.x()*t.x(),
982  a.y()*(1-t.y()) + b.y()*t.y(),
983  a.z()*(1-t.z()) + b.z()*t.z(),
984  a.w()*(1-t.w()) + b.w()*t.w() );
985  }
986 
987  // --------------- step ---------------
988 
989  template<typename T>
990  T step( T edge, T a ) { if (a<edge) return 0; else return 1; }
991 
992  template<typename T>
993  Vector2<T> step( const Vector2<T>& edge, const Vector2<T>& a )
994  {
995  return Vector2<T>( a.x()<edge.x() ? 0 : (T)1,
996  a.y()<edge.y() ? 0 : (T)1 );
997  }
998 
999  template<typename T>
1000  Vector3<T> step( const Vector3<T>& edge, const Vector3<T>& a )
1001  {
1002  return Vector3<T>( a.x()<edge.x() ? 0 : (T)1,
1003  a.y()<edge.y() ? 0 : (T)1,
1004  a.z()<edge.z() ? 0 : (T)1 );
1005  }
1006 
1007  template<typename T>
1008  Vector4<T> step( const Vector4<T>& edge, const Vector4<T>& a )
1009  {
1010  return Vector4<T>( a.x()<edge.x() ? 0 : (T)1,
1011  a.y()<edge.y() ? 0 : (T)1,
1012  a.z()<edge.z() ? 0 : (T)1,
1013  a.w()<edge.w() ? 0 : (T)1 );
1014  }
1015  // --------------- smoothstep ---------------
1016 
1017  template<typename T>
1018  T smoothstep(T edge0, T edge1, T a)
1019  {
1020  T t = clamp( (a - edge0) / (edge1 - edge0), (T)0, (T)1);
1021  return t * t * (3 - 2 * t);
1022  }
1023 
1024  template<typename T>
1025  Vector2<T> smoothstep(const Vector2<T>& edge0, const Vector2<T>& edge1, const Vector2<T>& a)
1026  {
1027  Vector2<T> v;
1028  T t;
1029  t = clamp( (a.x() - edge0.x()) / (edge1.x() - edge0.x()), (T)0, (T)1); v.x() = t * t * (3 - 2 * t);
1030  t = clamp( (a.y() - edge0.y()) / (edge1.y() - edge0.y()), (T)0, (T)1); v.y() = t * t * (3 - 2 * t);
1031  return v;
1032  }
1033 
1034  template<typename T>
1035  Vector3<T> smoothstep(const Vector3<T>& edge0, const Vector3<T>& edge1, const Vector3<T>& a)
1036  {
1037  Vector3<T> v;
1038  T t;
1039  t = clamp( (a.x() - edge0.x()) / (edge1.x() - edge0.x()), (T)0, (T)1); v.x() = t * t * (3 - 2 * t);
1040  t = clamp( (a.y() - edge0.y()) / (edge1.y() - edge0.y()), (T)0, (T)1); v.y() = t * t * (3 - 2 * t);
1041  t = clamp( (a.z() - edge0.z()) / (edge1.z() - edge0.z()), (T)0, (T)1); v.z() = t * t * (3 - 2 * t);
1042  return v;
1043  }
1044 
1045  template<typename T>
1046  Vector4<T> smoothstep(const Vector4<T>& edge0, const Vector4<T>& edge1, const Vector4<T>& a)
1047  {
1048  Vector4<T> v;
1049  T t;
1050  t = clamp( (a.x() - edge0.x()) / (edge1.x() - edge0.x()), (T)0, (T)1); v.x() = t * t * (3 - 2 * t);
1051  t = clamp( (a.y() - edge0.y()) / (edge1.y() - edge0.y()), (T)0, (T)1); v.y() = t * t * (3 - 2 * t);
1052  t = clamp( (a.z() - edge0.z()) / (edge1.z() - edge0.z()), (T)0, (T)1); v.z() = t * t * (3 - 2 * t);
1053  t = clamp( (a.w() - edge0.w()) / (edge1.w() - edge0.w()), (T)0, (T)1); v.w() = t * t * (3 - 2 * t);
1054  return v;
1055  }
1056 
1057  // --------------- isnan ---------------
1058 
1059  template<typename T>
1060  ivec2 isnan(const Vector2<T>& a) { return ivec2( isnan(a.x()), isnan(a.y()) ); }
1061 
1062  template<typename T>
1063  ivec3 isnan(const Vector3<T>& a) { return ivec3( isnan(a.x()), isnan(a.y()), isnan(a.z()) ); }
1064 
1065  template<typename T>
1066  ivec4 isnan(const Vector4<T>& a) { return ivec4( isnan(a.x()), isnan(a.y()), isnan(a.z()), isnan(a.w()) ); }
1067 
1068  // --------------- isinf ---------------
1069 
1070  template<typename T>
1071  ivec2 isinf(const Vector2<T>& a) { return ivec2( isinf(a.x()), isinf(a.y()) ); }
1072 
1073  template<typename T>
1074  ivec3 isinf(const Vector3<T>& a) { return ivec3( isinf(a.x()), isinf(a.y()), isinf(a.z()) ); }
1075 
1076  template<typename T>
1077  ivec4 isinf(const Vector4<T>& a) { return ivec4( isinf(a.x()), isinf(a.y()), isinf(a.z()), isinf(a.w()) ); }
1078 
1079  // --------------- geometric functions ---------------
1080 
1081  // --------------- length ---------------
1082 
1083  template<typename T>
1084  T length(T v) { return v; }
1085 
1086  template<typename T>
1087  T length(const Vector2<T>& v) { return v.length(); }
1088 
1089  template<typename T>
1090  T length(const Vector3<T>& v) { return v.length(); }
1091 
1092  template<typename T>
1093  T length(const Vector4<T>& v) { return v.length(); }
1094 
1095  // --------------- distance ---------------
1096 
1097  template<typename T>
1098  T distance(T p0, T p1) { return length(p0-p1); }
1099 
1100  template<typename T>
1101  T distance(const Vector2<T>& p0, const Vector2<T>& p1) { return length(p0-p1); }
1102 
1103  template<typename T>
1104  T distance(const Vector3<T>& p0, const Vector3<T>& p1) { return length(p0-p1); }
1105 
1106  template<typename T>
1107  T distance(const Vector4<T>& p0, const Vector4<T>& p1) { return length(p0-p1); }
1108 
1109  // --------------- dot ---------------
1110 
1111  inline float dot(float a, float b) { return a*b; }
1112 
1113  // ....................................
1114 
1115  inline double dot(double a, double b) { return a*b; }
1116 
1117  // ....................................
1118 
1119  inline real dot(int a, int b) { return (real)a*b; }
1120 
1121  // ....................................
1122 
1123  inline real dot(unsigned int a, unsigned int b) { return (real)a*b; }
1124 
1125  // --------------- normalize ---------------
1126 
1127  template<typename T>
1128  T normalize(T) { return (T)1; }
1129 
1130  template<typename T>
1131  Vector2<T> normalize(const Vector2<T>& v) { Vector2<T> t = v; t.normalize(); return t; }
1132 
1133  template<typename T>
1134  Vector3<T> normalize(const Vector3<T>& v) { Vector3<T> t = v; t.normalize(); return t; }
1135 
1136  template<typename T>
1137  Vector4<T> normalize(const Vector4<T>& v) { Vector4<T> t = v; t.normalize(); return t; }
1138 
1139  // --------------- faceforward ---------------
1140 
1141  template<typename T>
1142  T faceforward(T N, T I, T Nref) { if ( dot(Nref,I) < 0 ) return N; else return -N; }
1143 
1144  template<typename T>
1145  Vector2<T> faceforward(const Vector2<T>& N, const Vector2<T>& I, const Vector2<T>& Nref) { if ( dot(Nref,I) < 0 ) return N; else return -N; }
1146 
1147  template<typename T>
1148  Vector3<T> faceforward(const Vector3<T>& N, const Vector3<T>& I, const Vector3<T>& Nref) { if ( dot(Nref,I) < 0 ) return N; else return -N; }
1149 
1150  template<typename T>
1151  Vector4<T> faceforward(const Vector4<T>& N, const Vector4<T>& I, const Vector4<T>& Nref) { if ( dot(Nref,I) < 0 ) return N; else return -N; }
1152 
1153  // --------------- reflect ----------------
1154 
1155  template<typename T>
1156  T reflect(T I, T N) { return I-2*dot(N,I)*N; }
1157 
1158  template<typename T>
1159  Vector2<T> reflect(const Vector2<T>& I, const Vector2<T>& N) { return I-2*dot(N,I)*N; }
1160 
1161  template<typename T>
1162  Vector3<T> reflect(const Vector3<T>& I, const Vector3<T>& N) { return I-2*dot(N,I)*N; }
1163 
1164  template<typename T>
1165  Vector4<T> reflect(const Vector4<T>& I, const Vector4<T>& N) { return I-2*dot(N,I)*N; }
1166 
1167  // --------------- refract ---------------
1168 
1169  template<typename T>
1170  T refract(T I, T N, T eta)
1171  {
1172  T k = 1 - eta * eta * (1 - dot(N, I) * dot(N, I));
1173  if (k < 0)
1174  return 0;
1175  else
1176  return eta * I - (eta * dot(N, I) + ::sqrt(k)) * N;
1177  }
1178 
1179  template<typename T>
1180  Vector2<T> refract(const Vector2<T>& I, const Vector2<T>& N, T eta)
1181  {
1182  T k = 1 - eta * eta * (1 - dot(N, I) * dot(N, I));
1183  if (k < 0)
1184  return Vector2<T>(0,0);
1185  else
1186  return eta * I - N * (eta * dot(N, I) + ::sqrt(k));
1187  }
1188 
1189  template<typename T>
1190  Vector3<T> refract(const Vector3<T>& I, const Vector3<T>& N, T eta)
1191  {
1192  T k = 1 - eta * eta * (1 - dot(N, I) * dot(N, I));
1193  if (k < 0)
1194  return Vector3<T>(0,0,0);
1195  else
1196  return eta * I - N * (eta * dot(N, I) + ::sqrt(k));
1197  }
1198 
1199  template<typename T>
1200  Vector4<T> refract(const Vector4<T>& I, const Vector4<T>& N, T eta)
1201  {
1202  T k = 1 - eta * eta * (1 - dot(N, I) * dot(N, I));
1203  if (k < 0)
1204  return Vector4<T>(0,0,0,0);
1205  else
1206  return eta * I - N * (eta * dot(N, I) + ::sqrt(k));
1207  }
1208 
1209  // --------------- matrix functions ---------------
1210 
1211  // --------------- matrixCompMult ---------------
1212 
1213  template<typename T>
1215  {
1216  Matrix2<T> t;
1217  for(int i=0; i<2; ++i)
1218  for(int j=0; j<2; ++j)
1219  t.e(j,i) = a.e(j,i) * b.e(j,i);
1220  return t;
1221  }
1222 
1223  template<typename T>
1225  {
1226  Matrix3<T> t;
1227  for(int i=0; i<3; ++i)
1228  for(int j=0; j<3; ++j)
1229  t.e(j,i) = a.e(j,i) * b.e(j,i);
1230  return t;
1231  }
1232 
1233  template<typename T>
1235  {
1236  Matrix4<T> t;
1237  for(int i=0; i<4; ++i)
1238  for(int j=0; j<4; ++j)
1239  t.e(j,i) = a.e(j,i) * b.e(j,i);
1240  return t;
1241  }
1242 
1243  // --------------- outerProduct ---------------
1244 
1245  template<typename T>
1247  {
1248  Matrix2<T> m;
1249  for(int i=0; i<2; ++i)
1250  for(int j=0; j<2; ++j)
1251  m.e(i,j) = a[i] * b[j];
1252  return m;
1253  }
1254 
1255  template<typename T>
1257  {
1258  Matrix3<T> m;
1259  for(int i=0; i<3; ++i)
1260  for(int j=0; j<3; ++j)
1261  m.e(i,j) = a[i] * b[j];
1262  return m;
1263  }
1264 
1265  template<typename T>
1267  {
1268  Matrix4<T> m;
1269  for(int i=0; i<4; ++i)
1270  for(int j=0; j<4; ++j)
1271  m.e(i,j) = a[i] * b[j];
1272  return m;
1273  }
1274 
1275  // --------------- transpose ---------------
1276 
1277  template<typename T>
1279  {
1280  Matrix2<T> t;
1281  for(int i=0; i<2; ++i)
1282  for(int j=0; j<2; ++j)
1283  t.e(j,i) = a.e(i,j);
1284  return t;
1285  }
1286 
1287  template<typename T>
1289  {
1290  Matrix3<T> t;
1291  for(int i=0; i<3; ++i)
1292  for(int j=0; j<3; ++j)
1293  t.e(j,i) = a.e(i,j);
1294  return t;
1295  }
1296 
1297  template<typename T>
1299  {
1300  Matrix4<T> t;
1301  for(int i=0; i<4; ++i)
1302  for(int j=0; j<4; ++j)
1303  t.e(j,i) = a.e(i,j);
1304  return t;
1305  }
1306 
1307  // --------------- vector relational functions ---------------
1308 
1309  // --------------- lessThan ---------------
1310 
1311  template<typename T>
1312  ivec4 lessThan(const Vector4<T>& a, const Vector4<T>& b) {
1313  return ivec4( a.x() < b.x() ? 1 : 0,
1314  a.y() < b.y() ? 1 : 0,
1315  a.z() < b.z() ? 1 : 0,
1316  a.w() < b.w() ? 1 : 0 );
1317  }
1318 
1319  template<typename T>
1320  ivec3 lessThan(const Vector3<T>& a, const Vector3<T>& b) {
1321  return ivec3( a.x() < b.x() ? 1 : 0,
1322  a.y() < b.y() ? 1 : 0,
1323  a.z() < b.z() ? 1 : 0 );
1324  }
1325 
1326  template<typename T>
1327  ivec2 lessThan(const Vector2<T>& a, const Vector2<T>& b) {
1328  return ivec2( a.x() < b.x() ? 1 : 0,
1329  a.y() < b.y() ? 1 : 0 );
1330  }
1331 
1332  // --------------- lessThanEqual ---------------
1333 
1334  template<typename T>
1336  return ivec4( a.x() <= b.x() ? 1 : 0,
1337  a.y() <= b.y() ? 1 : 0,
1338  a.z() <= b.z() ? 1 : 0,
1339  a.w() <= b.w() ? 1 : 0 );
1340  }
1341 
1342  template<typename T>
1344  return ivec3( a.x() <= b.x() ? 1 : 0,
1345  a.y() <= b.y() ? 1 : 0,
1346  a.z() <= b.z() ? 1 : 0 );
1347  }
1348 
1349  template<typename T>
1351  return ivec2( a.x() <= b.x() ? 1 : 0,
1352  a.y() <= b.y() ? 1 : 0 );
1353  }
1354 
1355  // --------------- greaterThan ---------------
1356 
1357  template<typename T>
1358  ivec4 greaterThan(const Vector4<T>& a, const Vector4<T>& b) {
1359  return ivec4( a.x() > b.x() ? 1 : 0,
1360  a.y() > b.y() ? 1 : 0,
1361  a.z() > b.z() ? 1 : 0,
1362  a.w() > b.w() ? 1 : 0 );
1363  }
1364 
1365  template<typename T>
1366  ivec3 greaterThan(const Vector3<T>& a, const Vector3<T>& b) {
1367  return ivec3( a.x() > b.x() ? 1 : 0,
1368  a.y() > b.y() ? 1 : 0,
1369  a.z() > b.z() ? 1 : 0 );
1370  }
1371 
1372  template<typename T>
1373  ivec2 greaterThan(const Vector2<T>& a, const Vector2<T>& b) {
1374  return ivec2( a.x() > b.x() ? 1 : 0,
1375  a.y() > b.y() ? 1 : 0 );
1376  }
1377 
1378  // --------------- greaterThanEqual ---------------
1379 
1380  template<typename T>
1382  return ivec4( a.x() >= b.x() ? 1 : 0,
1383  a.y() >= b.y() ? 1 : 0,
1384  a.z() >= b.z() ? 1 : 0,
1385  a.w() >= b.w() ? 1 : 0 );
1386  }
1387 
1388  template<typename T>
1390  return ivec3( a.x() >= b.x() ? 1 : 0,
1391  a.y() >= b.y() ? 1 : 0,
1392  a.z() >= b.z() ? 1 : 0 );
1393  }
1394 
1395  template<typename T>
1397  return ivec2( a.x() >= b.x() ? 1 : 0,
1398  a.y() >= b.y() ? 1 : 0 );
1399  }
1400 
1401  // --------------- equal ---------------
1402 
1403  template<typename T>
1404  ivec4 equal(const Vector4<T>& a, const Vector4<T>& b) {
1405  return ivec4( a.x() == b.x() ? 1 : 0,
1406  a.y() == b.y() ? 1 : 0,
1407  a.z() == b.z() ? 1 : 0,
1408  a.w() == b.w() ? 1 : 0 );
1409  }
1410 
1411  template<typename T>
1412  ivec3 equal(const Vector3<T>& a, const Vector3<T>& b) {
1413  return ivec3( a.x() == b.x() ? 1 : 0,
1414  a.y() == b.y() ? 1 : 0,
1415  a.z() == b.z() ? 1 : 0 );
1416  }
1417 
1418  template<typename T>
1419  ivec2 equal(const Vector2<T>& a, const Vector2<T>& b) {
1420  return ivec2( a.x() == b.x() ? 1 : 0,
1421  a.y() == b.y() ? 1 : 0 );
1422  }
1423 
1424  // --------------- notEqual ---------------
1425 
1426  template<typename T>
1427  ivec4 notEqual(const Vector4<T>& a, const Vector4<T>& b) {
1428  return ivec4( a.x() != b.x() ? 1 : 0,
1429  a.y() != b.y() ? 1 : 0,
1430  a.z() != b.z() ? 1 : 0,
1431  a.w() != b.w() ? 1 : 0 );
1432  }
1433 
1434  template<typename T>
1435  ivec3 notEqual(const Vector3<T>& a, const Vector3<T>& b) {
1436  return ivec3( a.x() != b.x() ? 1 : 0,
1437  a.y() != b.y() ? 1 : 0,
1438  a.z() != b.z() ? 1 : 0 );
1439  }
1440 
1441  template<typename T>
1442  ivec2 notEqual(const Vector2<T>& a, const Vector2<T>& b) {
1443  return ivec2( a.x() != b.x() ? 1 : 0,
1444  a.y() != b.y() ? 1 : 0 );
1445  }
1446 
1447  // --------------- any ---------------
1448 
1449  inline bool any(const ivec2& a) { return a.x() != 0 || a.y() != 0; }
1450  inline bool any(const ivec3& a) { return a.x() != 0 || a.y() != 0 || a.z() != 0; }
1451  inline bool any(const ivec4& a) { return a.x() != 0 || a.y() != 0 || a.z() != 0 || a.w() != 0; }
1452 
1453  // --------------- all ---------------
1454 
1455  inline bool all(const ivec2& a) { return a.x() != 0 && a.y() != 0; }
1456  inline bool all(const ivec3& a) { return a.x() != 0 && a.y() != 0 && a.z() != 0; }
1457  inline bool all(const ivec4& a) { return a.x() != 0 && a.y() != 0 && a.z() != 0 && a.w() != 0; }
1458 
1459  // --------------- not ---------------
1460 
1461 #if defined(_MSC_VER)
1462  inline ivec2 not(const ivec2& a) { return ivec2( a.x() != 0 ? 0 : 1, a.y() != 0 ? 0 : 1); }
1463  inline ivec3 not(const ivec3& a) { return ivec3( a.x() != 0 ? 0 : 1, a.y() != 0 ? 0 : 1, a.z() != 0 ? 0 : 1); }
1464  inline ivec4 not(const ivec4& a) { return ivec4( a.x() != 0 ? 0 : 1, a.y() != 0 ? 0 : 1, a.z() != 0 ? 0 : 1, a.w() != 0 ? 0 : 1 ); }
1465 #endif
1466 }
1467 
1468 #endif
T asin(T a)
Definition: glsl_math.hpp:303
T radians(T degrees)
Definition: glsl_math.hpp:147
T atanh(T x)
Definition: glsl_math.hpp:120
const T_Scalar & z() const
Definition: Vector4.hpp:103
float clamp(float x, float minval, float maxval)
Definition: Vector2.hpp:315
T log2(T a)
Definition: glsl_math.hpp:538
Vector2< int > ivec2
A 2 components vector with int precision.
Definition: Vector2.hpp:278
T mix(T a, T b, T t)
Definition: glsl_math.hpp:952
T tanh(T a)
Definition: glsl_math.hpp:385
const Vector3 & normalize(T_Scalar *len=NULL)
Definition: Vector3.hpp:227
const T_Scalar & e(int i, int j) const
Definition: Matrix4.hpp:660
const T_Scalar & x() const
Definition: Vector4.hpp:101
T sqrt(T a)
Definition: glsl_math.hpp:592
ivec4 notEqual(const Vector4< T > &a, const Vector4< T > &b)
Definition: glsl_math.hpp:1427
T sign(T a)
Definition: glsl_math.hpp:669
bool any(const ivec2 &a)
Definition: glsl_math.hpp:1449
T sin(T a)
Definition: glsl_math.hpp:199
T degrees(T radians)
Definition: glsl_math.hpp:173
const T_Scalar & z() const
Definition: Vector3.hpp:91
T step(T edge, T a)
Definition: glsl_math.hpp:990
const Vector2 & normalize(T_Scalar *len=NULL)
Definition: Vector2.hpp:257
T fract(T a)
Definition: glsl_math.hpp:724
The Matrix2 class is a template class that implements a generic 2x2 matrix, see also vl::dmat2...
Definition: Matrix2.hpp:49
T_Scalar length() const
Definition: Vector4.hpp:251
bool isinf(T value)
Definition: glsl_math.hpp:131
T inversesqrt(T a)
Definition: glsl_math.hpp:618
T pow(T a, T b)
Definition: glsl_math.hpp:434
const T_Scalar & e(int i, int j) const
Definition: Matrix3.hpp:519
T refract(T I, T N, T eta)
Definition: glsl_math.hpp:1170
const double dRAD_TO_DEG
Constant to convert radian into degree using double precision.
Definition: std_types.hpp:68
The Vector4 class is a template class that implements a generic 4 components vector, see also vl::fvec4, vl::dvec4, vl::uvec4, vl::ivec4, vl::svec4, vl::usvec4, vl::bvec4, vl::ubvec4.
Definition: Vector4.hpp:44
T asinh(T x)
Definition: glsl_math.hpp:107
T faceforward(T N, T I, T Nref)
Definition: glsl_math.hpp:1142
bool isnan(T value)
Definition: glsl_math.hpp:130
ivec4 lessThan(const Vector4< T > &a, const Vector4< T > &b)
Definition: glsl_math.hpp:1312
T reflect(T I, T N)
Definition: glsl_math.hpp:1156
T log(T a)
Definition: glsl_math.hpp:486
T sinh(T a)
Definition: glsl_math.hpp:357
Visualization Library main namespace.
bool isinf_neg(T value)
Definition: glsl_math.hpp:133
float dot(float a, float b)
Definition: glsl_math.hpp:1111
const double dDEG_TO_RAD
Constant to convert degree into radian using double precision.
Definition: std_types.hpp:66
T distance(T p0, T p1)
Definition: glsl_math.hpp:1098
Vector4< T > floor(const Vector4< T > &a)
Definition: glsl_math.hpp:714
Matrix2< T > transpose(const Matrix2< T > &a)
Definition: glsl_math.hpp:1278
The Matrix3 class is a template class that implements a generic 3x3 matrix, see also vl::dmat3...
Definition: Matrix3.hpp:48
T trunc(T a)
Definition: glsl_math.hpp:738
T_Scalar length() const
Definition: Vector2.hpp:254
Vector4< T > tan(const Vector4< T > &angle)
Definition: glsl_math.hpp:267
The Vector3 class is a template class that implements a generic 3 components vector, see also vl::fvec3, vl::dvec3, vl::uvec3, vl::ivec3, vl::svec3, vl::usvec3, vl::bvec3, vl::ubvec3.
Definition: Vector3.hpp:44
T log10(T a)
Definition: glsl_math.hpp:566
Vector4< int > ivec4
A 4 components vector with int precision.
Definition: Vector4.hpp:275
float max(float a, float b)
Definition: Vector2.hpp:311
float min(float a, float b)
Definition: Vector2.hpp:307
T mod(T a, T b)
Definition: glsl_math.hpp:929
const T_Scalar & e(int i, int j) const
Definition: Matrix2.hpp:398
ivec4 greaterThanEqual(const Vector4< T > &a, const Vector4< T > &b)
Definition: glsl_math.hpp:1381
T acosh(T x)
Definition: glsl_math.hpp:110
T_Scalar length() const
Definition: Vector3.hpp:224
const T_Scalar & y() const
Definition: Vector3.hpp:90
T ceil(T a)
Definition: glsl_math.hpp:903
const T_Scalar & y() const
Definition: Vector4.hpp:102
T abs(T a)
Definition: glsl_math.hpp:646
T atan(T a)
Definition: glsl_math.hpp:277
The Matrix4 class is a template class that implements a generic 4x4 matrix, see also vl::dmat4...
Definition: Matrix4.hpp:48
float roundEven(float a, float epsilon)
Definition: glsl_math.hpp:828
Matrix2< T > matrixCompMult(const Matrix2< T > &a, const Matrix2< T > &b)
Definition: glsl_math.hpp:1214
T cosh(T a)
Definition: glsl_math.hpp:371
Vector3< int > ivec3
A 3 components vector with int precision.
Definition: Vector3.hpp:248
ivec4 greaterThan(const Vector4< T > &a, const Vector4< T > &b)
Definition: glsl_math.hpp:1358
T modf(T a, T &intpart)
T exp(T a)
Definition: glsl_math.hpp:460
The Vector2 class is a template class that implements a generic 2 components vector, see also vl::fvec2, vl::dvec2, vl::uvec2, vl::ivec2, vl::svec2, vl::usvec2, vl::bvec2, vl::ubvec2.
Definition: Vector2.hpp:97
Vector4< T > cos(const Vector4< T > &angle)
Definition: glsl_math.hpp:241
Vector4< T > modf(const Vector4< T > &a, Vector4< T > &intpart)
Definition: glsl_math.hpp:818
Vector4< T > sqrt(const Vector4< T > &a)
Definition: glsl_math.hpp:608
const Vector4 & normalize(T_Scalar *len=NULL)
Definition: Vector4.hpp:254
Vector4< T > acos(const Vector4< T > &angle)
Definition: glsl_math.hpp:345
T cos(T a)
Definition: glsl_math.hpp:225
const T_Scalar & x() const
Definition: Vector3.hpp:89
Vector4< T > sin(const Vector4< T > &angle)
Definition: glsl_math.hpp:215
Vector4< T > ceil(const Vector4< T > &a)
Definition: glsl_math.hpp:919
T smoothstep(T edge0, T edge1, T a)
Definition: glsl_math.hpp:1018
const T_Scalar & x() const
Definition: Vector2.hpp:132
T length(T v)
Definition: glsl_math.hpp:1084
Vector4< T > asin(const Vector4< T > &angle)
Definition: glsl_math.hpp:319
T acos(T a)
Definition: glsl_math.hpp:329
T exp2(T a)
Definition: glsl_math.hpp:512
bool isinf_pos(T value)
Definition: glsl_math.hpp:132
Matrix2< T > outerProduct(const Vector2< T > &a, const Vector2< T > &b)
Definition: glsl_math.hpp:1246
const T_Scalar & y() const
Definition: Vector2.hpp:133
T floor(T a)
Definition: glsl_math.hpp:698
Vector4< T > atan(const Vector4< T > &a, const Vector4< T > &b)
Definition: glsl_math.hpp:293
ivec4 lessThanEqual(const Vector4< T > &a, const Vector4< T > &b)
Definition: glsl_math.hpp:1335
ivec4 equal(const Vector4< T > &a, const Vector4< T > &b)
Definition: glsl_math.hpp:1404
T tan(T a)
Definition: glsl_math.hpp:251
T round(T x)
Definition: glsl_math.hpp:764
T normalize(T)
Definition: glsl_math.hpp:1128
bool all(const ivec2 &a)
Definition: glsl_math.hpp:1455
const T_Scalar & w() const
Definition: Vector4.hpp:104