OpenGL Mathematics (GLM)
You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and dots ('.'), can be up to 35 characters long. Letters must be lowercase.
 
 
 

863 lines
20 KiB

///////////////////////////////////////////////////////////////////////////////////////////////////
// OpenGL Mathematics Copyright (c) 2005 - 2010 G-Truc Creation (www.g-truc.net)
///////////////////////////////////////////////////////////////////////////////////////////////////
// Created : 2007-02-21
// Updated : 2007-02-21
// Licence : This source is under MIT License
// File : glm/gtx/vecx.inl
///////////////////////////////////////////////////////////////////////////////////////////////////
#include <cassert>
namespace glm
{
namespace detail{
template <int N> const typename _bvecxGTX<N>::size_type _bvecxGTX<N>::value_size = N;
// Bool constructors
template <int N>
inline _bvecxGTX<N>::_bvecxGTX()
{
for(int i = 0; i < N; ++i)
this->data[i] = false;
}
template <int N>
inline _bvecxGTX<N>::_bvecxGTX(const _bvecxGTX<N>& v)
{
for(int i = 0; i < N; ++i)
this->data[i] = v[i];
}
template <int N>
inline _bvecxGTX<N>::_bvecxGTX(const bool s)
{
for(int i = 0; i < N; ++i)
this->data[i] = s;
}
// Accesses
template <int N>
inline bool& _bvecxGTX<N>::operator[](int i)
{
assert(i >= 0 && i < N);
return this->data[i];
}
template <int N>
inline bool _bvecxGTX<N>::operator[](int i) const
{
assert(i >= 0 && i < N);
return this->data[i];
}
template <int N>
inline _bvecxGTX<N>::operator bool*()
{
return data;
}
template <int N>
inline _bvecxGTX<N>::operator const bool*() const
{
return data;
}
// Operators
template <int N>
inline _bvecxGTX<N>& _bvecxGTX<N>::operator=(const _bvecxGTX<N>& v)
{
for(int i = 0; i < N; ++i)
this->data[i] = v[i];
return *this;
}
template <int N>
inline _bvecxGTX<N> _bvecxGTX<N>::operator! () const
{
_bvecxGTX<N> result;
for(int i = 0; i < N; ++i)
result[i] = !this->data[i];
return result;
}
template <int N, typename T> const typename _xvecxGTX<N, T>::size_type _xvecxGTX<N, T>::value_size = N;
// Common constructors
template <int N, typename T>
inline _xvecxGTX<N, T>::_xvecxGTX()
{
for(int i = 0; i < N; ++i)
this->data[i] = T(0);
}
template <int N, typename T>
inline _xvecxGTX<N, T>::_xvecxGTX(const _xvecxGTX<N, T>& v)
{
for(int i = 0; i < N; ++i)
this->data[i] = v[i];
}
// T constructors
template <int N, typename T>
inline _xvecxGTX<N, T>::_xvecxGTX(const T s)
{
for(int i = 0; i < N; ++i)
this->data[i] = s;
}
// Accesses
template <int N, typename T>
inline T& _xvecxGTX<N, T>::operator[](int i)
{
assert(i >= 0 && i < N);
return this->data[i];
}
template <int N, typename T>
inline T _xvecxGTX<N, T>::operator[](int i) const
{
assert(i >= 0 && i < N);
return this->data[i];
}
template <int N, typename T>
inline _xvecxGTX<N, T>::operator T*()
{
return data;
}
template <int N, typename T>
inline _xvecxGTX<N, T>::operator const T*() const
{
return data;
}
template <int N, typename T>
inline _xvecxGTX<N, T>& _xvecxGTX<N, T>::operator=(const _xvecxGTX<N, T>& v)
{
for(int i = 0; i < N; ++i)
this->data[i] = v[i];
return *this;
}
template <int N, typename T>
inline _xvecxGTX<N, T>& _xvecxGTX<N, T>::operator+= (const T s)
{
for(int i = 0; i < N; ++i)
this->data[i] += s;
return *this;
}
template <int N, typename T>
inline _xvecxGTX<N, T>& _xvecxGTX<N, T>::operator+=(const _xvecxGTX<N, T>& v)
{
for(int i = 0; i < N; ++i)
this->data[i] += v[i];
return *this;
}
template <int N, typename T>
inline _xvecxGTX<N, T>& _xvecxGTX<N, T>::operator-= (const T s)
{
for(int i = 0; i < N; ++i)
this->data[i] -= s;
return *this;
}
template <int N, typename T>
inline _xvecxGTX<N, T>& _xvecxGTX<N, T>::operator-=(const _xvecxGTX<N, T>& v)
{
for(int i = 0; i < N; ++i)
this->data[i] -= v[i];
return *this;
}
template <int N, typename T>
inline _xvecxGTX<N, T>& _xvecxGTX<N, T>::operator*=(const T s)
{
for(int i = 0; i < N; ++i)
this->data[i] *= s;
return *this;
}
template <int N, typename T>
inline _xvecxGTX<N, T>& _xvecxGTX<N, T>::operator*= (const _xvecxGTX<N, T>& v)
{
for(int i = 0; i < N; ++i)
this->data[i] *= v[i];
return *this;
}
template <int N, typename T>
inline _xvecxGTX<N, T>& _xvecxGTX<N, T>::operator/=(const T s)
{
for(int i = 0; i < N; ++i)
this->data[i] /= s;
return *this;
}
template <int N, typename T>
inline _xvecxGTX<N, T>& _xvecxGTX<N, T>::operator/= (const _xvecxGTX<N, T>& v)
{
for(int i = 0; i < N; ++i)
this->data[i] /= v[i];
return *this;
}
// Unary constant operators
template <int N, typename T>
inline const detail::_xvecxGTX<N, T> operator- (const detail::_xvecxGTX<N, T>& v)
{
detail::_xvecxGTX<N, T> result;
for(int i = 0; i< N; ++i)
result[i] = -v[i];
return result;
}
template <int N, typename T>
inline const detail::_xvecxGTX<N, T> operator++ (const detail::_xvecxGTX<N, T>& v, int)
{
detail::_xvecxGTX<N, T> result;
for(int i = 0; i< N; ++i)
result[i] = v[i] + T(1);
return result;
}
template <int N, typename T>
inline const detail::_xvecxGTX<N, T> operator-- (const detail::_xvecxGTX<N, T>& v, int)
{
detail::_xvecxGTX<N, T> result;
for(int i = 0; i< N; ++i)
result[i] = v[i] - T(1);
return result;
}
// Binary operators
template <int N, typename T>
inline detail::_xvecxGTX<N, T> operator+ (const detail::_xvecxGTX<N, T>& v, const T s)
{
detail::_xvecxGTX<N, T> result;
for(int i = 0; i< N; ++i)
result[i] = v[i] + s;
return result;
}
template <int N, typename T>
inline detail::_xvecxGTX<N, T> operator+ (const T s, const detail::_xvecxGTX<N, T>& v)
{
detail::_xvecxGTX<N, T> result;
for(int i = 0; i< N; ++i)
result[i] = v[i] + s;
return result;
}
template <int N, typename T>
inline detail::_xvecxGTX<N, T> operator+ (const detail::_xvecxGTX<N, T>& v1, const detail::_xvecxGTX<N, T>& v2)
{
detail::_xvecxGTX<N, T> result;
for(int i = 0; i< N; ++i)
result[i] = v1[i] + v2[i];
return result;
}
template <int N, typename T>
inline detail::_xvecxGTX<N, T> operator- (const detail::_xvecxGTX<N, T>& v, const T s)
{
detail::_xvecxGTX<N, T> result;
for(int i = 0; i< N; ++i)
result[i] = v[i] - s;
return result;
}
template <int N, typename T>
inline detail::_xvecxGTX<N, T> operator- (const T s, const detail::_xvecxGTX<N, T>& v)
{
detail::_xvecxGTX<N, T> result;
for(int i = 0; i< N; ++i)
result[i] = s - v[i];
return result;
}
template <int N, typename T>
inline detail::_xvecxGTX<N, T> operator- (const detail::_xvecxGTX<N, T>& v1, const detail::_xvecxGTX<N, T>& v2)
{
detail::_xvecxGTX<N, T> result;
for(int i = 0; i< N; ++i)
result[i] = v1[i] - v2[i];
return result;
}
template <int N, typename T>
inline detail::_xvecxGTX<N, T> operator* (const detail::_xvecxGTX<N, T>& v, const T s)
{
detail::_xvecxGTX<N, T> result;
for(int i = 0; i< N; ++i)
result[i] = v[i] * s;
return result;
}
template <int N, typename T>
inline detail::_xvecxGTX<N, T> operator* (const T s, const detail::_xvecxGTX<N, T>& v)
{
detail::_xvecxGTX<N, T> result;
for(int i = 0; i< N; ++i)
result[i] = s * v[i];
return result;
}
template <int N, typename T>
inline detail::_xvecxGTX<N, T> operator* (const detail::_xvecxGTX<N, T>& v1, const detail::_xvecxGTX<N, T>& v2)
{
detail::_xvecxGTX<N, T> result;
for(int i = 0; i< N; ++i)
result[i] = v1[i] * v2[i];
return result;
}
template <int N, typename T>
inline detail::_xvecxGTX<N, T> operator/ (const detail::_xvecxGTX<N, T>& v, const T s)
{
detail::_xvecxGTX<N, T> result;
for(int i = 0; i< N; ++i)
result[i] = v[i] / s;
return result;
}
template <int N, typename T>
inline detail::_xvecxGTX<N, T> operator/ (const T s, const detail::_xvecxGTX<N, T>& v)
{
detail::_xvecxGTX<N, T> result;
for(int i = 0; i< N; ++i)
result[i] = s / v[i];
return result;
}
template <int N, typename T>
inline detail::_xvecxGTX<N, T> operator/ (const detail::_xvecxGTX<N, T>& v1, const detail::_xvecxGTX<N, T>& v2)
{
detail::_xvecxGTX<N, T> result;
for(int i = 0; i< N; ++i)
result[i] = v1[i] / v2[i];
return result;
}
}//namespace detail
namespace gtx{
namespace vecx{
// Trigonometric Functions
template <int N, typename T>
detail::_xvecxGTX<N, T> radiansGTX(const detail::_xvecxGTX<N, T>& degrees)
{
detail::_xvecxGTX<N, T> result;
for(int i = 0; i< N; ++i)
result[i] = radians(degrees[i]);
return result;
}
template <int N, typename T>
detail::_xvecxGTX<N, T> degreesGTX(const detail::_xvecxGTX<N, T>& radians)
{
detail::_xvecxGTX<N, T> result;
for(int i = 0; i< N; ++i)
result[i] = degrees(radians[i]);
return result;
}
template <int N, typename T>
detail::_xvecxGTX<N, T> sinGTX(const detail::_xvecxGTX<N, T>& angle)
{
detail::_xvecxGTX<N, T> result;
for(int i = 0; i< N; ++i)
result[i] = sin(angle[i]);
return result;
}
template <int N, typename T>
detail::_xvecxGTX<N, T> cosGTX(const detail::_xvecxGTX<N, T>& angle)
{
detail::_xvecxGTX<N, T> result;
for(int i = 0; i< N; ++i)
result[i] = cos(angle[i]);
return result;
}
template <int N, typename T>
detail::_xvecxGTX<N, T> tanGTX(const detail::_xvecxGTX<N, T>& angle)
{
detail::_xvecxGTX<N, T> result;
for(int i = 0; i< N; ++i)
result[i] = tan(angle[i]);
return result;
}
template <int N, typename T>
detail::_xvecxGTX<N, T> asinGTX(const detail::_xvecxGTX<N, T>& x)
{
detail::_xvecxGTX<N, T> result;
for(int i = 0; i< N; ++i)
result[i] = asin(x[i]);
return result;
}
template <int N, typename T>
detail::_xvecxGTX<N, T> acosGTX(const detail::_xvecxGTX<N, T>& x)
{
detail::_xvecxGTX<N, T> result;
for(int i = 0; i< N; ++i)
result[i] = acos(x[i]);
return result;
}
template <int N, typename T>
detail::_xvecxGTX<N, T> atanGTX(const detail::_xvecxGTX<N, T>& y, const detail::_xvecxGTX<N, T>& x)
{
detail::_xvecxGTX<N, T> result;
for(int i = 0; i< N; ++i)
result[i] = atan(y[i], x[i]);
return result;
}
template <int N, typename T>
detail::_xvecxGTX<N, T> atanGTX(const detail::_xvecxGTX<N, T>& y_over_x)
{
detail::_xvecxGTX<N, T> result;
for(int i = 0; i< N; ++i)
result[i] = atan(y_over_x[i]);
return result;
}
// Exponential Functions
template <int N, typename T>
detail::_xvecxGTX<N, T> powGTX(const detail::_xvecxGTX<N, T>& x, const detail::_xvecxGTX<N, T>& y)
{
detail::_xvecxGTX<N, T> result;
for(int i = 0; i< N; ++i)
result[i] = pow(x[i], y[i]);
return result;
}
template <int N, typename T>
detail::_xvecxGTX<N, T> expGTX(const detail::_xvecxGTX<N, T>& x)
{
detail::_xvecxGTX<N, T> result;
for(int i = 0; i< N; ++i)
result[i] = exp(x[i]);
return result;
}
template <int N, typename T>
detail::_xvecxGTX<N, T> logGTX(const detail::_xvecxGTX<N, T>& x)
{
detail::_xvecxGTX<N, T> result;
for(int i = 0; i< N; ++i)
result[i] = log(x[i]);
return result;
}
template <int N, typename T>
detail::_xvecxGTX<N, T> exp2GTX(const detail::_xvecxGTX<N, T>& x)
{
detail::_xvecxGTX<N, T> result;
for(int i = 0; i< N; ++i)
result[i] = exp2(x[i]);
return result;
}
template <int N, typename T>
detail::_xvecxGTX<N, T> log2GTX(const detail::_xvecxGTX<N, T>& x)
{
detail::_xvecxGTX<N, T> result;
for(int i = 0; i< N; ++i)
result[i] = log2(x[i]);
return result;
}
template <int N, typename T>
detail::_xvecxGTX<N, T> sqrtGTX(const detail::_xvecxGTX<N, T>& x)
{
detail::_xvecxGTX<N, T> result;
for(int i = 0; i< N; ++i)
result[i] = sqrt(x[i]);
return result;
}
template <int N, typename T>
detail::_xvecxGTX<N, T> inversesqrtGTX(const detail::_xvecxGTX<N, T>& x)
{
detail::_xvecxGTX<N, T> result;
for(int i = 0; i< N; ++i)
result[i] = inversesqrt(x[i]);
return result;
}
// Common Functions
template <int N, typename T>
detail::_xvecxGTX<N, T> absGTX(const detail::_xvecxGTX<N, T>& x)
{
detail::_xvecxGTX<N, T> result;
for(int i = 0; i< N; ++i)
result[i] = abs(x[i]);
return result;
}
template <int N, typename T>
detail::_xvecxGTX<N, T> signGTX(const detail::_xvecxGTX<N, T>& x)
{
detail::_xvecxGTX<N, T> result;
for(int i = 0; i< N; ++i)
result[i] = sign(x[i]);
return result;
}
template <int N, typename T>
detail::_xvecxGTX<N, T> floorGTX(const detail::_xvecxGTX<N, T>& x)
{
detail::_xvecxGTX<N, T> result;
for(int i = 0; i< N; ++i)
result[i] = floor(x[i]);
return result;
}
template <int N, typename T>
detail::_xvecxGTX<N, T> ceilGTX(const detail::_xvecxGTX<N, T>& x)
{
detail::_xvecxGTX<N, T> result;
for(int i = 0; i< N; ++i)
result[i] = ceil(x[i]);
return result;
}
template <int N, typename T>
detail::_xvecxGTX<N, T> fractGTX(const detail::_xvecxGTX<N, T>& x)
{
detail::_xvecxGTX<N, T> result;
for(int i = 0; i< N; ++i)
result[i] = fract(x[i]);
return result;
}
template <int N, typename T>
detail::_xvecxGTX<N, T> modGTX(const detail::_xvecxGTX<N, T>& x, T y)
{
detail::_xvecxGTX<N, T> result;
for(int i = 0; i< N; ++i)
result[i] = mod(x[i], y);
return result;
}
template <int N, typename T>
detail::_xvecxGTX<N, T> modGTX(
const detail::_xvecxGTX<N, T>& x,
const detail::_xvecxGTX<N, T>& y)
{
detail::_xvecxGTX<N, T> result;
for(int i = 0; i< N; ++i)
result[i] = mod(x[i], y[i]);
return result;
}
template <int N, typename T>
detail::_xvecxGTX<N, T> minGTX(
const detail::_xvecxGTX<N, T>& x,
T y)
{
detail::_xvecxGTX<N, T> result;
for(int i = 0; i< N; ++i)
result[i] = min(x[i], y);
return result;
}
template <int N, typename T>
detail::_xvecxGTX<N, T> minGTX(
const detail::_xvecxGTX<N, T>& x,
const detail::_xvecxGTX<N, T>& y)
{
detail::_xvecxGTX<N, T> result;
for(int i = 0; i< N; ++i)
result[i] = min(x[i], y[i]);
return result;
}
template <int N, typename T>
detail::_xvecxGTX<N, T> maxGTX(
const detail::_xvecxGTX<N, T>& x,
T y)
{
detail::_xvecxGTX<N, T> result;
for(int i = 0; i< N; ++i)
result[i] = max(x[i], y);
return result;
}
template <int N, typename T>
detail::_xvecxGTX<N, T> maxGTX(
const detail::_xvecxGTX<N, T>& x,
const detail::_xvecxGTX<N, T>& y)
{
detail::_xvecxGTX<N, T> result;
for(int i = 0; i< N; ++i)
result[i] = max(x[i], y[i]);
return result;
}
template <int N, typename T>
detail::_xvecxGTX<N, T> clampGTX(
const detail::_xvecxGTX<N, T>& x,
T minVal,
T maxVal)
{
detail::_xvecxGTX<N, T> result;
for(int i = 0; i< N; ++i)
result[i] = clamp(x[i], minVal, maxVal);
return result;
}
template <int N, typename T>
detail::_xvecxGTX<N, T> clampGTX(
const detail::_xvecxGTX<N, T>& x,
const detail::_xvecxGTX<N, T>& minVal,
const detail::_xvecxGTX<N, T>& maxVal)
{
detail::_xvecxGTX<N, T> result;
for(int i = 0; i< N; ++i)
result[i] = clamp(x[i], minVal[i], maxVal[i]);
return result;
}
template <int N, typename T>
detail::_xvecxGTX<N, T> stepGTX(
T edge,
const detail::_xvecxGTX<N, T>& x)
{
detail::_xvecxGTX<N, T> result;
for(int i = 0; i< N; ++i)
result[i] = step(edge, x[i]);
return result;
}
template <int N, typename T>
detail::_xvecxGTX<N, T> stepGTX(
const detail::_xvecxGTX<N, T>& edge,
const detail::_xvecxGTX<N, T>& x)
{
detail::_xvecxGTX<N, T> result;
for(int i = 0; i< N; ++i)
result[i] = step(edge[i], x[i]);
return result;
}
template <int N, typename T>
detail::_xvecxGTX<N, T> smoothstepGTX(
T edge0,
T edge1,
const detail::_xvecxGTX<N, T>& x)
{
detail::_xvecxGTX<N, T> result;
for(int i = 0; i< N; ++i)
result[i] = step(edge0, edge1, x[i]);
return result;
}
template <int N, typename T>
detail::_xvecxGTX<N, T> smoothstepGTX(
const detail::_xvecxGTX<N, T>& edge0,
const detail::_xvecxGTX<N, T>& edge1,
const detail::_xvecxGTX<N, T>& x)
{
detail::_xvecxGTX<N, T> result;
for(int i = 0; i< N; ++i)
result[i] = step(edge0[i], edge1[i], x[i]);
return result;
}
// Geometric Functions
template <int N, typename T>
T lengthGTX(
const detail::_xvecxGTX<N, T>& x)
{
T sqr = dot(x, x);
return sqrt(sqr);
}
template <int N, typename T>
T distanceGTX(
const detail::_xvecxGTX<N, T>& p0,
const detail::_xvecxGTX<N, T>& p1)
{
return lengthGTX(p1 - p0);
}
template <int N, typename T>
T dotGTX(
const detail::_xvecxGTX<N, T>& x,
const detail::_xvecxGTX<N, T>& y)
{
T result = T(0);
for(int i = 0; i < N; ++i)
result += x[i] * y[i];
return result;
}
template <int N, typename T>
detail::_xvecxGTX<N, T> normalizeGTX(
const detail::_xvecxGTX<N, T>& x)
{
T sqr = dot(x, x);
return x * inversesqrt(sqr);
}
template <int N, typename T>
detail::_xvecxGTX<N, T> faceforwardGTX(
const detail::_xvecxGTX<N, T>& Normal,
const detail::_xvecxGTX<N, T>& I,
const detail::_xvecxGTX<N, T>& Nref)
{
return dot(Nref, I) < T(0) ? Normal : -Normal;
}
template <int N, typename T>
detail::_xvecxGTX<N, T> reflectGTX(
const detail::_xvecxGTX<N, T>& I,
const detail::_xvecxGTX<N, T>& Normal)
{
return I - Normal * dot(Normal, I) * T(2);
}
template <int N, typename T>
detail::_xvecxGTX<N, T> refractGTX(
const detail::_xvecxGTX<N, T>& I,
const detail::_xvecxGTX<N, T>& Normal,
T eta)
{
T dot = dot(Normal, I);
T k = T(1) - eta * eta * (T(1) - dot * dot);
if(k < T(0))
return detail::_xvecxGTX<N, T>(T(0));
else
return eta * I - (eta * dot + sqrt(k)) * Normal;
}
// Vector Relational Functions
template <int N, typename T>
detail::_bvecxGTX<N> lessThanGTX(
const detail::_xvecxGTX<N, T>& x,
const detail::_xvecxGTX<N, T>& y)
{
detail::_bvecxGTX<N> result;
for(int i = 0; i< N; ++i)
result[i] = lessThan(x[i], y[i]);
return result;
}
template <int N, typename T>
detail::_bvecxGTX<N> lessThanEqualGTX(
const detail::_xvecxGTX<N, T>& x,
const detail::_xvecxGTX<N, T>& y)
{
detail::_bvecxGTX<N> result;
for(int i = 0; i< N; ++i)
result[i] = lessThanEqual(x[i], y[i]);
return result;
}
template <int N, typename T>
detail::_bvecxGTX<N> greaterThanGTX(
const detail::_xvecxGTX<N, T>& x,
const detail::_xvecxGTX<N, T>& y)
{
detail::_bvecxGTX<N> result;
for(int i = 0; i< N; ++i)
result[i] = greaterThan(x[i], y[i]);
return result;
}
template <int N, typename T>
detail::_bvecxGTX<N> greaterThanEqualGTX(
const detail::_xvecxGTX<N, T>& x,
const detail::_xvecxGTX<N, T>& y)
{
detail::_bvecxGTX<N> result;
for(int i = 0; i< N; ++i)
result[i] = greaterThanEqual(x[i], y[i]);
return result;
}
template <int N>
detail::_bvecxGTX<N> equalGTX(
const detail::_bvecxGTX<N>& x,
const detail::_bvecxGTX<N>& y)
{
detail::_bvecxGTX<N> result;
for(int i = 0; i< N; ++i)
result[i] = equal(x[i], y[i]);
return result;
}
template <int N, typename T>
detail::_bvecxGTX<N> equalGTX(
const detail::_xvecxGTX<N, T>& x,
const detail::_xvecxGTX<N, T>& y)
{
detail::_bvecxGTX<N> result;
for(int i = 0; i< N; ++i)
result[i] = equal(x[i], y[i]);
return result;
}
template <int N>
detail::_bvecxGTX<N> notEqualGTX(
const detail::_bvecxGTX<N>& x,
const detail::_bvecxGTX<N>& y)
{
detail::_bvecxGTX<N> result;
for(int i = 0; i< N; ++i)
result[i] = equal(x[i], y[i]);
return result;
}
template <int N, typename T>
detail::_bvecxGTX<N> notEqualGTX(
const detail::_xvecxGTX<N, T>& x,
const detail::_xvecxGTX<N, T>& y)
{
detail::_bvecxGTX<N> result;
for(int i = 0; i< N; ++i)
result[i] = notEqual(x[i], y[i]);
return result;
}
template <int N>
bool anyGTX(const detail::_bvecxGTX<N>& x)
{
for(int i = 0; i< N; ++i)
if(x[i]) return true;
return false;
}
template <int N>
bool allGTX(const detail::_bvecxGTX<N>& x)
{
for(int i = 0; i< N; ++i)
if(!x[i]) return false;
return true;
}
template <int N>
detail::_bvecxGTX<N> notGTX(
const detail::_bvecxGTX<N>& v)
{
detail::_bvecxGTX<N> result;
for(int i = 0; i< N; ++i)
result[i] = !v[i];
return result;
}
}//namespace vecx
}//namespace gtx
} //namespace glm