Vec.h
Go to the documentation of this file.
1 #pragma once
2 
3 #ifndef VEC_H
4 #define VEC_H
5 /*
6 Szymon Rusinkiewicz
7 Princeton University
8 
9 Vec.h
10 Class for a constant-length vector
11 
12 Supports the following operations:
13 
14 vec v1; // Initialized to (0, 0, 0)
15 vec v2(1.23f); // Initialized to (1.23f, 1.23f, 1.23f)
16 vec v3(1, 2, 3); // Initialized to (1, 2, 3)
17 vec v4(v3); // Copy constructor
18 
19 float farray[3];
20 vec v5 = vec(farray); // Explicit: "v4 = farray" won't work
21 
22 Vec<3,double> vd; // The "vec" used above is Vec<3,float>
23 point p1, p2, p3; // Same as vec
24 
25 v3 = v1 + v2; // Also -, *, / (all componentwise)
26 v3 = 3.5f * v1; // Also vec * scalar, vec / scalar
27 // NOTE: scalar has to be the same type:
28 // it won't work to do double * vec<float>
29 v1 = min(v2, v3); // Componentwise min/max
30 v1 = sin(v2); // Componentwise - all the usual functions...
31 swap(v1, v2); // In-place swap
32 
33 v3 = v1 DOT v2; // Actually operator^
34 v3 = v1 CROSS v2; // Actually operator%
35 
36 float f = v1[0]; // Subscript
37 float *fp = v1; // Implicit conversion to float *
38 
39 f = len(v1); // Length (also len2 == squared length)
40 f = dist(p1, p2); // Distance (also dist2 == squared distance)
41 normalize(v1); // Normalize (i.e., make it unit length)
42 // normalize(vec(0,0,0)) => vec(1,0,0)
43 v1 = trinorm(p1,p2,p3); // Normal of triangle (area-weighted)
44 
45 cout << v1 << endl; // iostream output in the form (1,2,3)
46 cin >> v2; // iostream input using the same syntax
47 
48 Also defines the utility functions sqr, cube, sgn, fract, clamp, mix,
49 step, smoothstep, faceforward, reflect, refract, and angle
50 */
51 
52 
53 // Windows defines min and max as macros, which prevents us from using the
54 // type-safe versions from std::, as well as interfering with method defns.
55 // Also define NOMINMAX, which prevents future bad definitions.
56 #ifdef min
57 # undef min
58 #endif
59 #ifdef max
60 # undef max
61 #endif
62 #ifndef NOMINMAX
63 # define NOMINMAX
64 #endif
65 #ifndef _USE_MATH_DEFINES
66 #define _USE_MATH_DEFINES
67 #endif
68 
69 #include <cstddef>
70 #include <cmath>
71 #include <iterator>
72 #include <stdexcept>
73 #include <iostream>
74 #include <algorithm>
75 
76 // Let gcc optimize conditional branches a bit better...
77 #ifndef likely
78 # if !defined(__GNUC__) || (__GNUC__ == 2 && __GNUC_MINOR__ < 96)
79 # define likely(x) (x)
80 # define unlikely(x) (x)
81 # else
82 # define likely(x) (__builtin_expect((x), 1))
83 # define unlikely(x) (__builtin_expect((x), 0))
84 # endif
85 #endif
86 
87 
88 namespace trimesh {
89 
90  using ::std::size_t;
91 
92 
93  // Boost-like compile-time assertion checking
94  template <bool X> struct VEC_STATIC_ASSERTION_FAILURE;
95  template <> struct VEC_STATIC_ASSERTION_FAILURE<true>
96  {
97  void operator () () {}
98  };
99 #define VEC_STATIC_CHECK(expr) VEC_STATIC_ASSERTION_FAILURE<bool(expr)>()
100 
101 
102  // Vec class declaration
103  template <size_t D, class T = float>
104  class Vec {
105  public:
106  // Types
107  typedef T value_type;
108  typedef value_type *pointer;
109  typedef const value_type *const_pointer;
110  typedef value_type &reference;
111  typedef const value_type &const_reference;
112  typedef value_type *iterator;
113  typedef const value_type *const_iterator;
114  typedef ::std::reverse_iterator<iterator> reverse_iterator;
115  typedef ::std::reverse_iterator<const_iterator> const_reverse_iterator;
116  typedef ::std::size_t size_type;
117  typedef ::std::ptrdiff_t difference_type;
118 
119  protected:
120  // The internal representation: standard array
121  T v[D];
122 
123  public:
124  // Constructor for no arguments. Everything initialized to 0.
125  Vec() { for (size_type i = 0; i < D; i++) v[i] = T(0); }
126 
127  // Uninitialized constructor - meant mostly for internal use
128 #define VEC_UNINITIALIZED ((void *) 0)
129  Vec(void *) {}
130 
131  // Constructor for one argument - default value. Explicit.
132  explicit Vec(const T &x)
133  {
134  for (size_type i = 0; i < D; i++) v[i] = x;
135  }
136 
137  // Constructors for 2-4 arguments
138  Vec(const T &x, const T &y)
139  {
140  VEC_STATIC_CHECK(D == 2); v[0] = x; v[1] = y;
141  }
142  Vec(const T &x, const T &y, const T &z)
143  {
144  VEC_STATIC_CHECK(D == 3); v[0] = x; v[1] = y; v[2] = z;
145  }
146  Vec(const T &x, const T &y, const T &z, const T &w)
147  {
148  VEC_STATIC_CHECK(D == 4); v[0] = x; v[1] = y; v[2] = z; v[3] = w;
149  }
150 
151  // Constructor from anything that can be accessed using []
152  // Pretty aggressive, so marked as explicit.
153  template <class S> explicit Vec(const S &x)
154  {
155  for (size_type i = 0; i < D; i++) v[i] = x[i];
156  }
157 
158  // Using default copy constructor, assignment operator, and destructor
159 
160  // Array reference - no bounds checking
161  reference operator [] (size_type i)
162  {
163  return v[i];
164  }
165  reference operator [] (int i)
166  {
167  return v[i];
168  }
169  const_reference operator [] (size_type i) const
170  {
171  return v[i];
172  }
173  const_reference operator [] (int i) const
174  {
175  return v[i];
176  }
177 
178 
179  // Array reference with bounds checking
180  reference at(size_type i)
181  {
182  if (i >= D)
183  throw ::std::out_of_range("Vec::at");
184  return v[i];
185  }
186  const_reference at(size_type i) const
187  {
188  if (i >= D)
189  throw ::std::out_of_range("Vec::at");
190  return v[i];
191  }
192 
193  /*------------wang kang at 2013-10-11---------------------*/
194  reference x()
195  {
196  return at(0);
197  }
198  const_reference x() const
199  {
200  return at(0);
201  }
202 
203  reference y()
204  {
205  return at(1);
206  }
207  const_reference y() const
208  {
209  return at(1);
210  }
211 
212  reference z()
213  {
214  return at(2);
215  }
216  const_reference z() const
217  {
218  return at(2);
219  }
220 
221  T length() const
222  {
223  return len(*this);
224  }
225  void normalize()
226  {
227  using namespace ::std;
228  T l = length();
229  if (unlikely(l <= T(0))) {
230  v[0] = T(1);
231  for (size_t i = 1; i < D; i++)
232  v[i] = T(0);
233  }
234 
235  l = T(1) / l;
236  for (size_t i = 0; i < D; i++)
237  v[i] *= l;
238  }
239 
240 
241 
242  /*-------------------------------------------------------------*/
243 
244  // Other accessors, for compatibility with std::array
245  reference front()
246  {
247  return v[0];
248  }
249  const_reference front() const
250  {
251  return v[0];
252  }
253  reference back()
254  {
255  return v[D - 1];
256  }
257  const_reference back() const
258  {
259  return v[D - 1];
260  }
261 
262  // Conversion to pointer
263  operator T * ()
264  {
265  return v;
266  }
267  operator const T * ()
268  {
269  return v;
270  }
271  operator const T * () const
272  {
273  return v;
274  }
275  pointer data()
276  {
277  return v;
278  }
279  const_pointer data() const
280  {
281  return v;
282  }
283 
284  // Iterators
285  iterator begin()
286  {
287  return v;
288  }
289  const_iterator begin() const
290  {
291  return v;
292  }
293  const_iterator cbegin() const
294  {
295  return v;
296  }
297  iterator end()
298  {
299  return begin() + D;
300  }
301  const_iterator end() const
302  {
303  return begin() + D;
304  }
305  const_iterator cend() const
306  {
307  return begin() + D;
308  }
309  reverse_iterator rbegin()
310  {
311  return reverse_iterator(end());
312  }
313  const_reverse_iterator rbegin() const
314  {
315  return const_reverse_iterator(end());
316  }
317  const_reverse_iterator crbegin() const
318  {
319  return const_reverse_iterator(end());
320  }
321  reverse_iterator rend()
322  {
323  return reverse_iterator(begin());
324  }
325  const_reverse_iterator rend() const
326  {
327  return const_reverse_iterator(begin());
328  }
329  const_reverse_iterator crend() const
330  {
331  return const_reverse_iterator(begin());
332  }
333 
334  // Capacity
335  size_type size() const
336  {
337  return D;
338  }
339  size_type max_size() const
340  {
341  return D;
342  }
343 
344  // empty() and clear() - check for all zero or set to zero
345  bool empty() const
346  {
347  for (size_type i = 0; i < D; i++)
348  if (v[i]) return false;
349  return true;
350  }
351  void clear()
352  {
353  for (size_type i = 0; i < D; i++) v[i] = T(0);
354  }
355 
356  // Set all elements to some constant
357  void fill(const value_type &x)
358  {
359  for (size_type i = 0; i < D; i++)
360  v[i] = x;
361  }
362  Vec<D, T> &operator = (const value_type &x)
363  {
364  for (size_type i = 0; i < D; i++)
365  v[i] = x;
366  return *this;
367  }
368 
369  // Member operators
370  Vec<D, T> &operator += (const Vec<D, T> &x)
371  {
372  for (size_type i = 0; i < D; i++)
373 #pragma omp atomic
374  v[i] += x[i];
375  return *this;
376  }
377  Vec<D, T> &operator -= (const Vec<D, T> &x)
378  {
379  for (size_type i = 0; i < D; i++)
380 #pragma omp atomic
381  v[i] -= x[i];
382  return *this;
383  }
384  Vec<D, T> &operator *= (const Vec<D, T> &x)
385  {
386  for (size_type i = 0; i < D; i++)
387 #pragma omp atomic
388  v[i] *= x[i];
389  return *this;
390  }
391  Vec<D, T> &operator *= (const T &x)
392  {
393  for (size_type i = 0; i < D; i++)
394 #pragma omp atomic
395  v[i] *= x;
396  return *this;
397  }
398  Vec<D, T> &operator /= (const Vec<D, T> &x)
399  {
400  for (size_type i = 0; i < D; i++)
401 #pragma omp atomic
402  v[i] /= x[i];
403  return *this;
404  }
405  Vec<D, T> &operator /= (const T &x)
406  {
407  for (size_type i = 0; i < D; i++)
408 #pragma omp atomic
409  v[i] /= x;
410  return *this;
411  }
412 
413  // Set each component to min/max of this and the other vector
415  {
416 #pragma omp critical
417  for (size_type i = 0; i < D; i++)
418  if (x[i] < v[i]) v[i] = x[i];
419  return *this;
420  }
422  {
423 #pragma omp critical
424  for (size_type i = 0; i < D; i++)
425  if (x[i] > v[i]) v[i] = x[i];
426  return *this;
427  }
428 
429  // Swap with another vector. (Also exists as a global function.)
430  void swap(Vec<D, T> &x)
431  {
432  using namespace ::std;
433 #pragma omp critical
434  for (size_type i = 0; i < D; i++) swap(v[i], x[i]);
435  }
436 
437  // Outside of class: + - * / % ^ << >> == != < > <= >=
438 
439  // Dot product with another vector (also exists as an operator)
440  value_type dot(const Vec<D, T> &x) const
441  {
442  value_type total = v[0] * x[0];
443  for (size_type i = 1; i < D; i++)
444  total += v[i] * x[i];
445  return total;
446  }
447 
448  // Cross product with another vector (also exists as an operator)
449  Vec<3, T> cross(const Vec<3, T> &x) const
450  {
451  VEC_STATIC_CHECK(D == 3);
452  return Vec<3, T>(v[1] * x[2] - v[2] * x[1],
453  v[2] * x[0] - v[0] * x[2],
454  v[0] * x[1] - v[1] * x[0]);
455  }
456 
457  // Some partial compatibility with std::valarray, plus generalizations
458  value_type sum() const
459  {
460  value_type total = v[0];
461  for (size_type i = 1; i < D; i++)
462  total += v[i];
463  return total;
464  }
465  value_type sumabs() const
466  {
467  using namespace ::std;
468  value_type total = fabs(v[0]);
469  for (size_type i = 1; i < D; i++)
470  total += fabs(v[i]);
471  return total;
472  }
473  value_type avg() const
474  {
475  return sum() / D;
476  }
477  value_type mean() const
478  {
479  return sum() / D;
480  }
481  value_type product() const
482  {
483  value_type total = v[0];
484  for (size_type i = 1; i < D; i++)
485  total *= v[i];
486  return total;
487  }
488  value_type min() const
489  {
490  value_type m = v[0];
491  for (size_type i = 1; i < D; i++)
492  if (v[i] < m)
493  m = v[i];
494  return m;
495  }
496  value_type max() const
497  {
498  value_type m = v[0];
499  for (size_type i = 1; i < D; i++)
500  if (v[i] > m)
501  m = v[i];
502  return m;
503  }
504  Vec<D, T> apply(value_type func(value_type)) const
505  {
507  for (size_type i = 0; i < D; i++)
508  result[i] = func(v[i]);
509  return result;
510  }
511  Vec<D, T> apply(value_type func(const value_type&)) const
512  {
514  for (size_type i = 0; i < D; i++)
515  result[i] = func(v[i]);
516  return result;
517  }
518  Vec<D, T> cshift(int n) const
519  {
521  if (n < 0)
522  n = (n % D) + D;
523  for (size_type i = 0; i < D; i++)
524  result[i] = v[(i + n) % D];
525  return result;
526  }
527  Vec<D, T> shift(int n) const
528  {
529  using namespace ::std;
530  if (abs(n) >= D)
531  return Vec<D, T>();
532  Vec<D, T> result; // Must be initialized to zero
533  size_type start = n < 0 ? -n : 0;
534  size_type stop = n > 0 ? D - n : D;
535  for (size_type i = start; i < stop; i++)
536  result[i] = v[i + n];
537  return result;
538  }
539 
540  // TODO for C++11: std::get()
541  }; // class Vec
542 
543 
544  // Shorthands for particular flavors of Vecs
546 #define _GEOMETRY_3D_ 1
547 #ifdef _GEOMETRY_3D_
550 #else
551  typedef Vec<2, float> point;
552  typedef Vec<3, float> point3;
553 #endif
554 
556 
562 
563 
564  // Nonmember operators that take two Vecs
565  template <size_t D, class T>
566  static inline const Vec<D, T> operator + (const Vec<D, T> &v1, const Vec<D, T> &v2)
567  {
568  using namespace ::std;
570  for (size_t i = 0; i < D; i++)
571  result[i] = v1[i] + v2[i];
572  return result;
573  }
574 
575  template <size_t D, class T>
576  static inline const Vec<D, T> operator - (const Vec<D, T> &v1, const Vec<D, T> &v2)
577  {
578  using namespace ::std;
580  for (size_t i = 0; i < D; i++)
581  result[i] = v1[i] - v2[i];
582  return result;
583  }
584 
585  template <size_t D, class T>
586  static inline const Vec<D, T> operator & (const Vec<D, T> &v1, const Vec<D, T> &v2)
587  {
588  using namespace ::std;
590  for (size_t i = 0; i < D; i++)
591  result[i] = v1[i] * v2[i];
592  return result;
593  }
594 
595  template <size_t D, class T>
596  static inline const Vec<D, T> operator / (const Vec<D, T> &v1, const Vec<D, T> &v2)
597  {
598  using namespace ::std;
600  for (size_t i = 0; i < D; i++)
601  result[i] = v1[i] / v2[i];
602  return result;
603  }
604 
605 
606  // Dot product
607  template <size_t D, class T>
608  static inline const T operator * (const Vec<D, T> &v1, const Vec<D, T> &v2)
609  {
610  using namespace ::std;
611  T sum = v1[0] * v2[0];
612  for (size_t i = 1; i < D; i++)
613  sum += v1[i] * v2[i];
614  return sum;
615  }
616 #define DOT *
617 
618 
619  // Cross product - only in 3 dimensions
620  template <class T>
621  static inline const Vec<3, T> operator ^ (const Vec<3, T> &v1, const Vec<3, T> &v2)
622  {
623  return Vec<3, T>(v1[1] * v2[2] - v1[2] * v2[1],
624  v1[2] * v2[0] - v1[0] * v2[2],
625  v1[0] * v2[1] - v1[1] * v2[0]);
626  }
627 #define CROSS ^
628 
629 
630  // Component-wise equality and inequality (#include the usual caveats
631  // about comparing floats for equality...)
632  template <size_t D, class T>
633  static inline bool operator == (const Vec<D, T> &v1, const Vec<D, T> &v2)
634  {
635  using namespace ::std;
636  for (size_t i = 0; i < D; i++)
637  if (v1[i] != v2[i])
638  return false;
639  return true;
640  }
641 
642  template <size_t D, class T>
643  static inline bool operator != (const Vec<D, T> &v1, const Vec<D, T> &v2)
644  {
645  using namespace ::std;
646  for (size_t i = 0; i < D; i++)
647  if (v1[i] != v2[i])
648  return true;
649  return false;
650  }
651 
652 
653  // Comparison by lexicographical ordering - not necessarily useful on its own,
654  // but necessary in order to put Vecs in sets, maps, etc.
655  template <size_t D, class T>
656  static inline bool operator < (const Vec<D, T> &v1, const Vec<D, T> &v2)
657  {
658  using namespace ::std;
659  for (size_t i = 0; i < D; i++) {
660  if (v1[i] < v2[i])
661  return true;
662  else if (v1[i] > v2[i])
663  return false;
664  }
665  return false;
666  }
667 
668  template <size_t D, class T>
669  static inline bool operator >(const Vec<D, T> &v1, const Vec<D, T> &v2)
670  {
671  return v2 < v1;
672  }
673 
674  template <size_t D, class T>
675  static inline bool operator <= (const Vec<D, T> &v1, const Vec<D, T> &v2)
676  {
677  return !(v2 < v1);
678  }
679 
680  template <size_t D, class T>
681  static inline bool operator >= (const Vec<D, T> &v1, const Vec<D, T> &v2)
682  {
683  return !(v1 < v2);
684  }
685 
686 
687  // Unary operators
688  template <size_t D, class T>
689  static inline const Vec<D, T> &operator + (const Vec<D, T> &v)
690  {
691  return v;
692  }
693 
694  template <size_t D, class T>
695  static inline const Vec<D, T> operator - (const Vec<D, T> &v)
696  {
697  using namespace ::std;
699  for (size_t i = 0; i < D; i++)
700  result[i] = -v[i];
701  return result;
702  }
703 
704  template <size_t D, class T>
705  static inline bool operator ! (const Vec<D, T> &v)
706  {
707  return v.empty();
708  }
709 
710 
711  // Vec/scalar operators
712  template <size_t D, class T>
713  static inline const Vec<D, T> operator * (const T &x, const Vec<D, T> &v)
714  {
715  using namespace ::std;
717  for (size_t i = 0; i < D; i++)
718  result[i] = x * v[i];
719  return result;
720  }
721 
722  template <size_t D, class T>
723  static inline const Vec<D, T> operator * (const Vec<D, T> &v, const T &x)
724  {
725  using namespace ::std;
727  for (size_t i = 0; i < D; i++)
728  result[i] = v[i] * x;
729  return result;
730  }
731 
732  template <size_t D, class T>
733  static inline const Vec<D, T> operator / (const T &x, const Vec<D, T> &v)
734  {
735  using namespace ::std;
737  for (size_t i = 0; i < D; i++)
738  result[i] = x / v[i];
739  return result;
740  }
741 
742  template <size_t D, class T>
743  static inline const Vec<D, T> operator / (const Vec<D, T> &v, const T &x)
744  {
745  using namespace ::std;
747  for (size_t i = 0; i < D; i++)
748  result[i] = v[i] / x;
749  return result;
750  }
751 
752 
753  // iostream operators
754  template <size_t D, class T>
755  static inline ::std::ostream &operator << (::std::ostream &os, const Vec<D, T> &v)
756 
757  {
758  using namespace ::std;
759  os << "(";
760  for (size_t i = 0; i < D - 1; i++)
761  os << v[i] << ", ";
762  return os << v[D - 1] << ")";
763  }
764 
765  template <size_t D, class T>
766  static inline ::std::istream &operator >> (::std::istream &is, Vec<D, T> &v)
767  {
768  using namespace ::std;
769  char c1 = 0, c2 = 0;
770 
771  is >> c1;
772  if (c1 == '(' || c1 == '[') {
773  is >> v[0] >> ws >> c2;
774  for (size_t i = 1; i < D; i++) {
775  if (c2 == ',')
776  is >> v[i] >> ws >> c2;
777  else
778  is.setstate(ios::failbit);
779  }
780  }
781 
782  if (c1 == '(' && c2 != ')')
783  is.setstate(ios::failbit);
784  else if (c1 == '[' && c2 != ']')
785  is.setstate(ios::failbit);
786 
787  return is;
788  }
789 
790 
791  // Utility functions for square and cube, to go along with sqrt and cbrt
792  template <class T>
793  static inline T sqr(const T &x)
794  {
795  return x*x;
796  }
797 
798  template <class T>
799  static inline T cube(const T &x)
800  {
801  return x*x*x;
802  }
803 
804 
805  // Sign of a scalar. Note that sgn(0) == 1.
806  template <class T>
807  static inline T sgn(const T &x)
808  {
809  return (x < T(0)) ? T(-1) : T(1);
810  }
811 
812 
813  // Utility functions based on GLSL
814  template <class T>
815  static inline T fract(const T &x)
816  {
817  return x - floor(x);
818  }
819 
820  template <class T>
821  static inline T clamp(const T &x, const T &a, const T &b)
822  {
823  return x > a ? x < b ? x : b : a; // returns a on NaN
824  }
825 
826  template <class T, class S>
827  static inline T mix(const T &x, const T &y, const S &a)
828  {
829  return (S(1) - a) * x + a * y;
830  }
831 
832  template <class T>
833  static inline T step(const T &a, const T &x)
834  {
835  return x < a ? T(0) : T(1);
836  }
837 
838  template <class T>
839  static inline T smoothstep(const T &a, const T &b, const T &x)
840  {
841  if (b <= a) return step(x, a);
842  T t = (x - a) / (b - a);
843  return t <= T(0) ? T(0) : t >= T(1) ? T(1) : t * t * (T(3) - T(2) * t);
844  }
845 
846  template <size_t D, class T>
847  static inline T faceforward(const Vec<D, T> &N, const Vec<D, T> &I,
848  const Vec<D, T> &Nref)
849  {
850  return ((Nref DOT I) < T(0)) ? N : -N;
851  }
852 
853  template <size_t D, class T>
854  static inline T reflect(const Vec<D, T> &I, const Vec<D, T> &N)
855  {
856  return I - (T(2) * (N DOT I)) * N;
857  }
858 
859  template <size_t D, class T>
860  static inline T refract(const Vec<D, T> &I, const Vec<D, T> &N,
861  const T &eta)
862  {
863  using namespace ::std;
864  T NdotI = N DOT I;
865  T k = T(1) - sqr(eta) * (T(1) - sqr(NdotI));
866  return (k < T(0)) ? T(0) : eta * I - (eta * NdotI * sqrt(k)) * N;
867  }
868 
869 
870  // Squared length
871  template <size_t D, class T>
872  static inline const T len2(const Vec<D, T> &v)
873  {
874  using namespace ::std;
875  T l2 = v[0] * v[0];
876  for (size_t i = 1; i < D; i++)
877  l2 += v[i] * v[i];
878  return l2;
879  }
880 
881 
882  // Length
883  template <size_t D, class T>
884  static inline const T len(const Vec<D, T> &v)
885  {
886  using namespace ::std;
887  return sqrt(len2(v));
888  }
889 
890 
891  // Squared distance
892  template <size_t D, class T>
893  static inline const T dist2(const Vec<D, T> &v1, const Vec<D, T> &v2)
894  {
895  using namespace ::std;
896  T d2 = sqr(v2[0] - v1[0]);
897  for (size_t i = 1; i < D; i++)
898  d2 += sqr(v2[i] - v1[i]);
899  return d2;
900  }
901 
902 
903  // Distance
904  template <size_t D, class T>
905  static inline const T dist(const Vec<D, T> &v1, const Vec<D, T> &v2)
906  {
907  using namespace ::std;
908  return sqrt(dist2(v1, v2));
909  }
910 
911 
912  // In-place normalization to unit length
913  template <size_t D, class T>
914  static inline Vec<D, T> normalize(Vec<D, T> &v)
915  {
916  using namespace ::std;
917  T l = len(v);
918  if (unlikely(l <= T(0))) {
919  v[0] = T(1);
920  for (size_t i = 1; i < D; i++)
921  v[i] = T(0);
922  return v;
923  }
924 
925  l = T(1) / l;
926  for (size_t i = 0; i < D; i++)
927  v[i] *= l;
928 
929  return v;
930  }
931 
932 
933  // Area-weighted triangle face normal
934  template <class T>
935  static inline T trinorm(const T &v0, const T &v1, const T &v2)
936  {
937  return (typename T::value_type) 0.5 * ((v1 - v0) CROSS(v2 - v0));
938  }
939 
940 
941  // Angle between two vectors
942  template <size_t D, class T>
943  static inline const T angle(const Vec<D, T> &v1, const Vec<D, T> &v2)
944  {
945  using namespace ::std;
946  return atan2(len(v1 CROSS v2), v1 DOT v2);
947  }
948 
949 
950 }; // namespace trimesh
951 
952 /*
953 // POSIX / C99 compatibility functions for MSVS
954 #ifdef _WIN32
955 #ifdef cbrt
956 # undef cbrt
957 #endif
958 inline float cbrt(float x)
959 {
960 using namespace ::std;
961 return (x < 0.0f) ? -pow(-x, 1.0f / 3.0f) : pow(x, 1.0f / 3.0f);
962 }
963 inline double cbrt(double x)
964 {
965 using namespace ::std;
966 return (x < 0.0) ? -pow(-x, 1.0 / 3.0) : pow(x, 1.0 / 3.0);
967 }
968 inline long double cbrt(long double x)
969 {
970 using namespace ::std;
971 return (x < 0.0L) ? -pow(-x, 1.0L / 3.0L) : pow(x, 1.0L / 3.0L);
972 }
973 #ifdef round
974 # undef round
975 #endif
976 inline float round(float x)
977 {
978 return (x < 0.0f) ? float(int(x - 0.5f)) : float(int(x + 0.5f));
979 }
980 inline double round(double x)
981 {
982 return (x < 0.0f) ? double(int(x - 0.5)) : double(int(x + 0.5));
983 }
984 inline long double round(long double x)
985 {
986 return (x < 0.0f) ? (long double)(int(x - 0.5L)) : (long double)(int(x + 0.5L));
987 }
988 #ifdef trunc
989 # undef trunc
990 #endif
991 inline float trunc(float x)
992 {
993 return (x < 0.0f) ? float(int(x)) : float(int(x));
994 }
995 inline double trunc(double x)
996 {
997 return (x < 0.0f) ? double(int(x)) : double(int(x));
998 }
999 inline long double trunc(long double x)
1000 {
1001 return (x < 0.0f) ? (long double)(int(x)) : (long double)(int(x));
1002 }
1003 #endif // _WIN32
1004 */
1005 
1006 // Generic macros for declaring 1-, 2-, and 3- argument
1007 // componentwise functions on Vecs.
1008 #define VEC_DECLARE_ONEARG(name) \
1009  template < ::std::size_t D, class T > \
1010  static inline trimesh::Vec<D,T> name(const trimesh::Vec<D,T> &v) \
1011  { \
1012  using namespace ::std; \
1013  using namespace ::trimesh; \
1014  Vec<D,T> result(VEC_UNINITIALIZED); \
1015  for (size_t i = 0; i < D; i++) \
1016  result[i] = name(v[i]); \
1017  return result; \
1018  }
1019 
1020 // Vector-scalar, scalar-vector, and componentwise vector-vector versions
1021 #define VEC_DECLARE_TWOARG_VS(name) \
1022  template < ::std::size_t D, class T > \
1023  static inline trimesh::Vec<D,T> name(const trimesh::Vec<D,T> &v, const T &a) \
1024  { \
1025  using namespace ::std; \
1026  using namespace ::trimesh; \
1027  Vec<D,T> result(VEC_UNINITIALIZED); \
1028  for (size_t i = 0; i < D; i++) \
1029  result[i] = name(v[i], a); \
1030  return result; \
1031  }
1032 #define VEC_DECLARE_TWOARG_SV(name) \
1033  template < ::std::size_t D, class T > \
1034  static inline trimesh::Vec<D,T> name(const T &a, const trimesh::Vec<D,T> &v) \
1035  { \
1036  using namespace ::std; \
1037  using namespace ::trimesh; \
1038  Vec<D,T> result(VEC_UNINITIALIZED); \
1039  for (size_t i = 0; i < D; i++) \
1040  result[i] = name(a, v[i]); \
1041  return result; \
1042  }
1043 #define VEC_DECLARE_TWOARG_VV(name) \
1044  template < ::std::size_t D, class T > \
1045  static inline trimesh::Vec<D,T> name(const trimesh::Vec<D,T> &v, const trimesh::Vec<D,T> &w) \
1046  { \
1047  using namespace ::std; \
1048  using namespace ::trimesh; \
1049  Vec<D,T> result(VEC_UNINITIALIZED); \
1050  for (size_t i = 0; i < D; i++) \
1051  result[i] = name(v[i], w[i]); \
1052  return result; \
1053  }
1054 
1055 #define VEC_DECLARE_THREEARG_VSS(name) \
1056  template < ::std::size_t D, class T > \
1057  static inline trimesh::Vec<D,T> name(const trimesh::Vec<D,T> &v, const T &a, const T &b) \
1058  { \
1059  using namespace ::std; \
1060  using namespace ::trimesh; \
1061  Vec<D,T> result(VEC_UNINITIALIZED); \
1062  for (size_t i = 0; i < D; i++) \
1063  result[i] = name(v[i], a, b); \
1064  return result; \
1065  }
1066 #define VEC_DECLARE_THREEARG_SSV(name) \
1067  template < ::std::size_t D, class T > \
1068  static inline trimesh::Vec<D,T> name(const T &a, const T &b, const trimesh::Vec<D,T> &v) \
1069  { \
1070  using namespace ::std; \
1071  using namespace ::trimesh; \
1072  Vec<D,T> result(VEC_UNINITIALIZED); \
1073  for (size_t i = 0; i < D; i++) \
1074  result[i] = name(a, b, v[i]); \
1075  return result; \
1076  }
1077 #define VEC_DECLARE_THREEARG_VVV(name) \
1078  template < ::std::size_t D, class T > \
1079  static inline trimesh::Vec<D,T> name(const trimesh::Vec<D,T> &v, const trimesh::Vec<D,T> &w, const trimesh::Vec<D,T> &x) \
1080  { \
1081  using namespace ::std; \
1082  using namespace ::trimesh; \
1083  Vec<D,T> result(VEC_UNINITIALIZED); \
1084  for (size_t i = 0; i < D; i++) \
1085  result[i] = name(v[i], w[i], x[i]); \
1086  return result; \
1087  }
1088 
1089 
1090 // The following is the list of functions in C89 and C++98, with the exception
1091 // of frexp, ldexp, and modf (which have irregular calling conventions).
1092 // They are supposed to be in namespace std, but Visual Studio and some
1093 // older compilers also declare them in the global namespace.
1094 // In the name of compatibility, we (reluctantly) do likewise.
1095 VEC_DECLARE_ONEARG(acos)
1096 VEC_DECLARE_ONEARG(asin)
1097 VEC_DECLARE_ONEARG(atan)
1098 VEC_DECLARE_TWOARG_VV(atan2)
1099 VEC_DECLARE_ONEARG(ceil)
1100 VEC_DECLARE_ONEARG(cos)
1101 VEC_DECLARE_ONEARG(cosh)
1102 VEC_DECLARE_ONEARG(exp)
1103 VEC_DECLARE_ONEARG(fabs)
1104 VEC_DECLARE_ONEARG(floor)
1107 VEC_DECLARE_ONEARG(log)
1108 VEC_DECLARE_ONEARG(log10)
1112 VEC_DECLARE_ONEARG(sin)
1113 VEC_DECLARE_ONEARG(sinh)
1114 VEC_DECLARE_ONEARG(sqrt)
1115 VEC_DECLARE_ONEARG(tan)
1116 VEC_DECLARE_ONEARG(tanh)
1117 namespace std {
1118  using ::acos;
1119  using ::asin;
1120  using ::atan;
1121  using ::atan2;
1122  using ::ceil;
1123  using ::cos;
1124  using ::cosh;
1125  using ::exp;
1126  using ::fabs;
1127  using ::floor;
1128  using ::fmod;
1129  using ::log;
1130  using ::log10;
1131  using ::pow;
1132  using ::sin;
1133  using ::sinh;
1134  using ::sqrt;
1135  using ::tan;
1136  using ::tanh;
1137 };
1138 
1139 
1140 // These are only in namespace std.
1141 namespace std {
1148 
1149  // Swap two Vecs. Not atomic, unlike class method.
1150  template <size_t D, class T>
1151  static inline void swap(const ::trimesh::Vec<D, T> &v1, const ::trimesh::Vec<D, T> &v2)
1152  {
1153  for (size_t i = 0; i < D; i++)
1154  swap(v1[i], v2[i]);
1155  }
1156 };
1157 
1158 
1159 // These are POSIX and are commonly used. Global namespace.
1160 // Compatibility versions of these for MSVC are above.
1161 VEC_DECLARE_ONEARG(cbrt)
1162 VEC_DECLARE_ONEARG(round)
1163 VEC_DECLARE_ONEARG(trunc)
1164 
1165 
1166 // These are new functions declared in namespace trimesh.
1167 namespace trimesh {
1178 };
1179 
1180 
1181 #undef VEC_DECLARE_ONEARG
1182 #undef VEC_DECLARE_TWOARG_VS
1183 #undef VEC_DECLARE_TWOARG_SV
1184 #undef VEC_DECLARE_TWOARG_VV
1185 #undef VEC_DECLARE_THREEARG_VSS
1186 #undef VEC_DECLARE_THREEARG_SSV
1187 #undef VEC_DECLARE_THREEARG_VVV
1188 
1189 
1190 // Both valarrays and GLSL use abs() on a vector to mean fabs().
1191 // Let's do the same...
1192 template < ::std::size_t D, class T >
1194 {
1195  return fabs(v);
1196 }
1197 namespace std {
1198  using ::abs;
1199 };
1200 
1201 
1202 #endif
GLdouble n
const value_type * const_pointer
Definition: Vec.h:109
Vec(const T &x, const T &y, const T &z)
Definition: Vec.h:142
const_pointer data() const
Definition: Vec.h:279
size_type max_size() const
Definition: Vec.h:339
#define VEC_DECLARE_TWOARG_VS(name)
Definition: Vec.h:1021
Definition: Vec.h:88
::std::reverse_iterator< const_iterator > const_reverse_iterator
Definition: Vec.h:115
reference front()
Definition: Vec.h:245
static bool operator>=(const Vec< D, T > &v1, const Vec< D, T > &v2)
Definition: Vec.h:681
value_type * pointer
Definition: Vec.h:108
static const Vec< D, T > operator&(const Vec< D, T > &v1, const Vec< D, T > &v2)
Definition: Vec.h:586
static T sgn(const T &x)
Definition: Vec.h:807
const_reference at(size_type i) const
Definition: Vec.h:186
#define VEC_DECLARE_THREEARG_VSS(name)
Definition: Vec.h:1055
static bool operator!=(const Vec< D, T > &v1, const Vec< D, T > &v2)
Definition: Vec.h:643
iterator end()
Definition: Vec.h:297
GLenum clamp
value_type sumabs() const
Definition: Vec.h:465
Vec< D, T > cshift(int n) const
Definition: Vec.h:518
const GLfloat * m
Vec(const S &x)
Definition: Vec.h:153
const_reverse_iterator rend() const
Definition: Vec.h:325
static const T len2(const Vec< D, T > &v)
Definition: Vec.h:872
GLuint start
Vec< 2, float > vec2
Definition: Vec.h:555
#define VEC_DECLARE_TWOARG_VV(name)
Definition: Vec.h:1043
static bool operator!(const Vec< D, T > &v)
Definition: Vec.h:705
value_type & reference
Definition: Vec.h:110
#define VEC_STATIC_CHECK(expr)
Definition: Vec.h:99
static T smoothstep(const T &a, const T &b, const T &x)
Definition: Vec.h:839
#define unlikely(x)
Definition: Vec.h:80
static const Vec< D, T > operator-(const Vec< D, T > &v1, const Vec< D, T > &v2)
Definition: Vec.h:576
const_iterator begin() const
Definition: Vec.h:289
GLfloat GLfloat v1
static Vec< D, T > normalize(Vec< D, T > &v)
Definition: Vec.h:914
static const Vec< D, T > operator+(const Vec< D, T > &v1, const Vec< D, T > &v2)
Definition: Vec.h:566
#define VEC_DECLARE_THREEARG_VVV(name)
Definition: Vec.h:1077
Vec< 4, float > vec4
Definition: Vec.h:558
Vec< D, T > & max(const Vec< D, T > &x)
Definition: Vec.h:421
const_reference z() const
Definition: Vec.h:216
void fill(const value_type &x)
Definition: Vec.h:357
reference x()
Definition: Vec.h:194
const_reference front() const
Definition: Vec.h:249
const_iterator cend() const
Definition: Vec.h:305
T length() const
Definition: Vec.h:221
static const Vec< 3, T > operator^(const Vec< 3, T > &v1, const Vec< 3, T > &v2)
Definition: Vec.h:621
::std::reverse_iterator< iterator > reverse_iterator
Definition: Vec.h:114
pointer data()
Definition: Vec.h:275
Vec< D, T > apply(value_type func(value_type)) const
Definition: Vec.h:504
static inline::std::istream & operator>>(::std::istream &is, Vec< D, T > &v)
Definition: Vec.h:766
Vec< 4, int > ivec4
Definition: Vec.h:561
static bool operator==(const Vec< D, T > &v1, const Vec< D, T > &v2)
Definition: Vec.h:633
static T faceforward(const Vec< D, T > &N, const Vec< D, T > &I, const Vec< D, T > &Nref)
Definition: Vec.h:847
Vec< D, T > & min(const Vec< D, T > &x)
Definition: Vec.h:414
Vec< 3, int > ivec3
Definition: Vec.h:560
static T fract(const T &x)
Definition: Vec.h:815
#define VEC_DECLARE_ONEARG(name)
Definition: Vec.h:1008
static const T dist(const Vec< D, T > &v1, const Vec< D, T > &v2)
Definition: Vec.h:905
GLint GLenum GLint x
reference back()
Definition: Vec.h:253
value_type dot(const Vec< D, T > &x) const
Definition: Vec.h:440
Vec(const T &x, const T &y, const T &z, const T &w)
Definition: Vec.h:146
static bool operator>(const Vec< D, T > &v1, const Vec< D, T > &v2)
Definition: Vec.h:669
GLubyte GLubyte GLubyte GLubyte w
value_type avg() const
Definition: Vec.h:473
GLboolean GLboolean GLboolean GLboolean a
const_reference x() const
Definition: Vec.h:198
iterator begin()
Definition: Vec.h:285
static const T len(const Vec< D, T > &v)
Definition: Vec.h:884
T value_type
Definition: Vec.h:107
value_type min() const
Definition: Vec.h:488
Vec< 3, T > cross(const Vec< 3, T > &x) const
Definition: Vec.h:449
Vec< D, T > apply(value_type func(const value_type &)) const
Definition: Vec.h:511
void swap(Vec< D, T > &x)
Definition: Vec.h:430
reference at(size_type i)
Definition: Vec.h:180
GLuint GLuint end
Vec< D, T > shift(int n) const
Definition: Vec.h:527
const_reverse_iterator rbegin() const
Definition: Vec.h:313
void normalize()
Definition: Vec.h:225
bool empty() const
Definition: Vec.h:345
static T reflect(const Vec< D, T > &I, const Vec< D, T > &N)
Definition: Vec.h:854
value_type max() const
Definition: Vec.h:496
Vec< 2, float > point2
Definition: Vec.h:548
#define VEC_DECLARE_TWOARG_SV(name)
Definition: Vec.h:1032
const value_type & const_reference
Definition: Vec.h:111
static const T angle(const Vec< D, T > &v1, const Vec< D, T > &v2)
Definition: Vec.h:943
const_iterator cbegin() const
Definition: Vec.h:293
Vec(void *)
Definition: Vec.h:129
reference y()
Definition: Vec.h:203
GLfloat v0
GLdouble GLdouble t
GLboolean GLboolean GLboolean b
static T mix(const T &x, const T &y, const S &a)
Definition: Vec.h:827
static const Vec< D, T > operator/(const Vec< D, T > &v1, const Vec< D, T > &v2)
Definition: Vec.h:596
Vec(const T &x, const T &y)
Definition: Vec.h:138
static trimesh::Vec< D, T > abs(const trimesh::Vec< D, T > &v)
Definition: Vec.h:1193
GLuint GLsizei GLsizei * length
static T refract(const Vec< D, T > &I, const Vec< D, T > &N, const T &eta)
Definition: Vec.h:860
GLdouble GLdouble GLdouble z
#define DOT
Definition: Vec.h:616
GLenum func
size_type size() const
Definition: Vec.h:335
const_iterator end() const
Definition: Vec.h:301
#define VEC_DECLARE_THREEARG_SSV(name)
Definition: Vec.h:1066
const GLdouble * v
#define T(x)
GLfloat GLfloat GLfloat v2
Vec< 3, float > vec
Definition: Vec.h:545
Vec< 3, float > point
Definition: Vec.h:549
reverse_iterator rbegin()
Definition: Vec.h:309
Vec(const T &x)
Definition: Vec.h:132
value_type product() const
Definition: Vec.h:481
static const T operator*(const Vec< D, T > &v1, const Vec< D, T > &v2)
Definition: Vec.h:608
const_reverse_iterator crbegin() const
Definition: Vec.h:317
#define VEC_UNINITIALIZED
Definition: Vec.h:128
value_type * iterator
Definition: Vec.h:112
value_type sum() const
Definition: Vec.h:458
static const T dist2(const Vec< D, T > &v1, const Vec< D, T > &v2)
Definition: Vec.h:893
static void swap(const ::trimesh::Vec< D, T > &v1, const ::trimesh::Vec< D, T > &v2)
Definition: Vec.h:1151
reference z()
Definition: Vec.h:212
#define CROSS
Definition: Vec.h:627
static T cube(const T &x)
Definition: Vec.h:799
static T step(const T &a, const T &x)
Definition: Vec.h:833
value_type mean() const
Definition: Vec.h:477
const_reverse_iterator crend() const
Definition: Vec.h:329
::std::size_t size_type
Definition: Vec.h:116
::std::ptrdiff_t difference_type
Definition: Vec.h:117
static T clamp(const T &x, const T &a, const T &b)
Definition: Vec.h:821
static T trinorm(const T &v0, const T &v1, const T &v2)
Definition: Vec.h:935
GLuint64EXT * result
const value_type * const_iterator
Definition: Vec.h:113
reverse_iterator rend()
Definition: Vec.h:321
GLint y
void clear()
Definition: Vec.h:351
static T sqr(const T &x)
Definition: Vec.h:793
const_reference back() const
Definition: Vec.h:257
Vec< 2, int > ivec2
Definition: Vec.h:559
const_reference y() const
Definition: Vec.h:207
Vec< 3, float > vec3
Definition: Vec.h:557


choreo_task_sequence_planner
Author(s): Yijiang Huang
autogenerated on Thu Jul 18 2019 04:03:14