65 #ifndef _USE_MATH_DEFINES 66 #define _USE_MATH_DEFINES 78 # if !defined(__GNUC__) || (__GNUC__ == 2 && __GNUC_MINOR__ < 96) 79 # define likely(x) (x) 80 # define unlikely(x) (x) 82 # define likely(x) (__builtin_expect((x), 1)) 83 # define unlikely(x) (__builtin_expect((x), 0)) 97 void operator () () {}
99 #define VEC_STATIC_CHECK(expr) VEC_STATIC_ASSERTION_FAILURE<bool(expr)>() 103 template <
size_t D,
class T =
float>
125 Vec() {
for (size_type i = 0; i < D; i++) v[i] =
T(0); }
128 #define VEC_UNINITIALIZED ((void *) 0) 134 for (size_type i = 0; i < D; i++) v[i] = x;
146 Vec(
const T &
x,
const T &
y,
const T &
z,
const T &
w)
153 template <
class S>
explicit Vec(
const S &
x)
155 for (size_type i = 0; i < D; i++) v[i] = x[i];
161 reference operator [] (size_type i)
165 reference operator [] (
int i)
169 const_reference operator [] (size_type i)
const 173 const_reference operator [] (
int i)
const 180 reference
at(size_type i)
183 throw ::std::out_of_range(
"Vec::at");
186 const_reference
at(size_type i)
const 189 throw ::std::out_of_range(
"Vec::at");
198 const_reference
x()
const 207 const_reference
y()
const 216 const_reference
z()
const 227 using namespace ::
std;
231 for (
size_t i = 1; i < D; i++)
236 for (
size_t i = 0; i < D; i++)
267 operator const T * ()
271 operator const T * ()
const 301 const_iterator
end()
const 311 return reverse_iterator(
end());
315 return const_reverse_iterator(
end());
319 return const_reverse_iterator(
end());
323 return reverse_iterator(begin());
325 const_reverse_iterator
rend()
const 327 return const_reverse_iterator(begin());
329 const_reverse_iterator
crend()
const 331 return const_reverse_iterator(begin());
347 for (size_type i = 0; i < D; i++)
348 if (v[i])
return false;
353 for (size_type i = 0; i < D; i++) v[i] =
T(0);
359 for (size_type i = 0; i < D; i++)
364 for (size_type i = 0; i < D; i++)
372 for (size_type i = 0; i < D; i++)
379 for (size_type i = 0; i < D; i++)
386 for (size_type i = 0; i < D; i++)
393 for (size_type i = 0; i < D; i++)
400 for (size_type i = 0; i < D; i++)
407 for (size_type i = 0; i < D; i++)
417 for (size_type i = 0; i < D; i++)
418 if (x[i] < v[i]) v[i] = x[i];
424 for (size_type i = 0; i < D; i++)
425 if (x[i] > v[i]) v[i] = x[i];
432 using namespace ::
std;
434 for (size_type i = 0; i < D; i++)
swap(v[i], x[i]);
442 value_type total = v[0] * x[0];
443 for (size_type i = 1; i < D; i++)
444 total += v[i] * x[i];
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]);
460 value_type total = v[0];
461 for (size_type i = 1; i < D; i++)
467 using namespace ::
std;
468 value_type total = fabs(v[0]);
469 for (size_type i = 1; i < D; i++)
483 value_type total = v[0];
484 for (size_type i = 1; i < D; i++)
491 for (size_type i = 1; i < D; i++)
499 for (size_type i = 1; i < D; i++)
507 for (size_type i = 0; i < D; i++)
508 result[i] =
func(v[i]);
514 for (size_type i = 0; i < D; i++)
515 result[i] =
func(v[i]);
523 for (size_type i = 0; i < D; i++)
524 result[i] = v[(i + n) % D];
529 using namespace ::
std;
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];
546 #define _GEOMETRY_3D_ 1 565 template <
size_t D,
class T>
568 using namespace ::
std;
570 for (
size_t i = 0; i < D; i++)
571 result[i] = v1[i] + v2[i];
575 template <
size_t D,
class T>
578 using namespace ::
std;
580 for (
size_t i = 0; i < D; i++)
581 result[i] = v1[i] - v2[i];
585 template <
size_t D,
class T>
588 using namespace ::
std;
590 for (
size_t i = 0; i < D; i++)
591 result[i] = v1[i] * v2[i];
595 template <
size_t D,
class T>
598 using namespace ::
std;
600 for (
size_t i = 0; i < D; i++)
601 result[i] = v1[i] / v2[i];
607 template <
size_t D,
class T>
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];
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]);
632 template <
size_t D,
class T>
635 using namespace ::
std;
636 for (
size_t i = 0; i < D; i++)
642 template <
size_t D,
class T>
645 using namespace ::
std;
646 for (
size_t i = 0; i < D; i++)
655 template <
size_t D,
class T>
658 using namespace ::
std;
659 for (
size_t i = 0; i < D; i++) {
662 else if (v1[i] >
v2[i])
668 template <
size_t D,
class T>
674 template <
size_t D,
class T>
675 static inline bool operator <= (const Vec<D, T> &v1,
const Vec<D, T> &
v2)
680 template <
size_t D,
class T>
688 template <
size_t D,
class T>
694 template <
size_t D,
class T>
697 using namespace ::
std;
699 for (
size_t i = 0; i < D; i++)
704 template <
size_t D,
class T>
712 template <
size_t D,
class T>
715 using namespace ::
std;
717 for (
size_t i = 0; i < D; i++)
718 result[i] = x * v[i];
722 template <
size_t D,
class T>
725 using namespace ::
std;
727 for (
size_t i = 0; i < D; i++)
728 result[i] = v[i] * x;
732 template <
size_t D,
class T>
735 using namespace ::
std;
737 for (
size_t i = 0; i < D; i++)
738 result[i] = x / v[i];
742 template <
size_t D,
class T>
745 using namespace ::
std;
747 for (
size_t i = 0; i < D; i++)
748 result[i] = v[i] / x;
754 template <
size_t D,
class T>
755 static inline ::std::ostream &operator << (::std::ostream &os, const Vec<D, T> &v)
758 using namespace ::
std;
760 for (
size_t i = 0; i < D - 1; i++)
762 return os << v[D - 1] <<
")";
765 template <
size_t D,
class T>
768 using namespace ::
std;
772 if (c1 ==
'(' || c1 ==
'[') {
773 is >> v[0] >> ws >> c2;
774 for (
size_t i = 1; i < D; i++) {
776 is >> v[i] >> ws >> c2;
778 is.setstate(ios::failbit);
782 if (c1 ==
'(' && c2 !=
')')
783 is.setstate(ios::failbit);
784 else if (c1 ==
'[' && c2 !=
']')
785 is.setstate(ios::failbit);
809 return (x <
T(0)) ?
T(-1) :
T(1);
821 static inline T clamp(
const T &
x,
const T &
a,
const T &
b)
823 return x > a ? x < b ? x : b : a;
826 template <
class T,
class S>
827 static inline T mix(
const T &
x,
const T &
y,
const S &
a)
829 return (S(1) - a) * x + a * y;
835 return x < a ?
T(0) : T(1);
841 if (b <= a)
return step(x, a);
842 T t = (x - a) / (b - a);
846 template <
size_t D,
class T>
850 return ((Nref
DOT I) <
T(0)) ? N : -N;
853 template <
size_t D,
class T>
856 return I - (
T(2) * (N
DOT I)) * N;
859 template <
size_t D,
class T>
863 using namespace ::
std;
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;
871 template <
size_t D,
class T>
874 using namespace ::
std;
876 for (
size_t i = 1; i < D; i++)
883 template <
size_t D,
class T>
886 using namespace ::
std;
887 return sqrt(
len2(v));
892 template <
size_t D,
class T>
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]);
904 template <
size_t D,
class T>
907 using namespace ::
std;
908 return sqrt(
dist2(v1, v2));
913 template <
size_t D,
class T>
916 using namespace ::
std;
920 for (
size_t i = 1; i < D; i++)
926 for (
size_t i = 0; i < D; i++)
937 return (
typename T::value_type) 0.5 * ((v1 - v0)
CROSS(v2 - v0));
942 template <
size_t D,
class T>
945 using namespace ::
std;
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) \ 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]); \ 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) \ 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); \ 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) \ 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]); \ 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) \ 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]); \ 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) \ 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); \ 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) \ 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]); \ 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) \ 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]); \ 1150 template <
size_t D,
class T>
1151 static inline void swap(const ::trimesh::Vec<D, T> &
v1, const ::trimesh::Vec<D, T> &
v2)
1153 for (
size_t i = 0; i < D; i++)
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 1192 template < ::std::
size_t D,
class T >
const value_type * const_pointer
Vec(const T &x, const T &y, const T &z)
const_pointer data() const
size_type max_size() const
#define VEC_DECLARE_TWOARG_VS(name)
::std::reverse_iterator< const_iterator > const_reverse_iterator
static bool operator>=(const Vec< D, T > &v1, const Vec< D, T > &v2)
static const Vec< D, T > operator&(const Vec< D, T > &v1, const Vec< D, T > &v2)
const_reference at(size_type i) const
#define VEC_DECLARE_THREEARG_VSS(name)
static bool operator!=(const Vec< D, T > &v1, const Vec< D, T > &v2)
value_type sumabs() const
Vec< D, T > cshift(int n) const
const_reverse_iterator rend() const
static const T len2(const Vec< D, T > &v)
#define VEC_DECLARE_TWOARG_VV(name)
static bool operator!(const Vec< D, T > &v)
#define VEC_STATIC_CHECK(expr)
static T smoothstep(const T &a, const T &b, const T &x)
static const Vec< D, T > operator-(const Vec< D, T > &v1, const Vec< D, T > &v2)
const_iterator begin() const
static Vec< D, T > normalize(Vec< D, T > &v)
static const Vec< D, T > operator+(const Vec< D, T > &v1, const Vec< D, T > &v2)
#define VEC_DECLARE_THREEARG_VVV(name)
Vec< D, T > & max(const Vec< D, T > &x)
const_reference z() const
void fill(const value_type &x)
const_reference front() const
const_iterator cend() const
static const Vec< 3, T > operator^(const Vec< 3, T > &v1, const Vec< 3, T > &v2)
::std::reverse_iterator< iterator > reverse_iterator
Vec< D, T > apply(value_type func(value_type)) const
static inline::std::istream & operator>>(::std::istream &is, Vec< D, T > &v)
static bool operator==(const Vec< D, T > &v1, const Vec< D, T > &v2)
static T faceforward(const Vec< D, T > &N, const Vec< D, T > &I, const Vec< D, T > &Nref)
Vec< D, T > & min(const Vec< D, T > &x)
static T fract(const T &x)
#define VEC_DECLARE_ONEARG(name)
static const T dist(const Vec< D, T > &v1, const Vec< D, T > &v2)
value_type dot(const Vec< D, T > &x) const
Vec(const T &x, const T &y, const T &z, const T &w)
static bool operator>(const Vec< D, T > &v1, const Vec< D, T > &v2)
GLubyte GLubyte GLubyte GLubyte w
GLboolean GLboolean GLboolean GLboolean a
const_reference x() const
static const T len(const Vec< D, T > &v)
Vec< 3, T > cross(const Vec< 3, T > &x) const
Vec< D, T > apply(value_type func(const value_type &)) const
void swap(Vec< D, T > &x)
reference at(size_type i)
Vec< D, T > shift(int n) const
const_reverse_iterator rbegin() const
static T reflect(const Vec< D, T > &I, const Vec< D, T > &N)
#define VEC_DECLARE_TWOARG_SV(name)
const value_type & const_reference
static const T angle(const Vec< D, T > &v1, const Vec< D, T > &v2)
const_iterator cbegin() const
GLboolean GLboolean GLboolean b
static T mix(const T &x, const T &y, const S &a)
static const Vec< D, T > operator/(const Vec< D, T > &v1, const Vec< D, T > &v2)
Vec(const T &x, const T &y)
static trimesh::Vec< D, T > abs(const trimesh::Vec< D, T > &v)
GLuint GLsizei GLsizei * length
static T refract(const Vec< D, T > &I, const Vec< D, T > &N, const T &eta)
GLdouble GLdouble GLdouble z
const_iterator end() const
#define VEC_DECLARE_THREEARG_SSV(name)
GLfloat GLfloat GLfloat v2
reverse_iterator rbegin()
value_type product() const
static const T operator*(const Vec< D, T > &v1, const Vec< D, T > &v2)
const_reverse_iterator crbegin() const
#define VEC_UNINITIALIZED
static const T dist2(const Vec< D, T > &v1, const Vec< D, T > &v2)
static void swap(const ::trimesh::Vec< D, T > &v1, const ::trimesh::Vec< D, T > &v2)
static T cube(const T &x)
static T step(const T &a, const T &x)
const_reverse_iterator crend() const
::std::ptrdiff_t difference_type
static T clamp(const T &x, const T &a, const T &b)
static T trinorm(const T &v0, const T &v1, const T &v2)
const value_type * const_iterator
const_reference back() const
const_reference y() const