/////////////////////////////////////////////////////////////////////////////////////////////////// // OpenGL Mathematics Copyright (c) 2005 - 2008 G-Truc Creation (www.g-truc.net) /////////////////////////////////////////////////////////////////////////////////////////////////// // Created : 2005-01-12 // Updated : 2007-03-19 // Licence : This source is under GNU LGPL licence // File : _func.inl /////////////////////////////////////////////////////////////////////////////////////////////////// #ifndef __func_inl__ #define __func_inl__ #include #include #include "./_func.h" namespace glm { //////////////////////////////////////////////////////////////////////// // Trigonometric Functions // radians template inline T radians(T degrees) { const T pi = T(3.1415926535897932384626433832795); return degrees * (pi / T(180)); } template inline detail::_xvec2 radians(const detail::_xvec2& degrees) { return detail::_xvec2( radians(degrees.x), radians(degrees.y)); } template inline detail::_xvec3 radians(const detail::_xvec3& degrees) { return detail::_xvec3( radians(degrees.x), radians(degrees.y), radians(degrees.z)); } template inline detail::_xvec4 radians(const detail::_xvec4& degrees) { return detail::_xvec4( radians(degrees.x), radians(degrees.y), radians(degrees.z), radians(degrees.w)); } // degrees template inline T degrees(T radians) { const T pi = T(3.1415926535897932384626433832795); return radians * (T(180) / pi); } template inline detail::_xvec2 degrees(const detail::_xvec2& radians) { return detail::_xvec2( degrees(radians.x), degrees(radians.y)); } template inline detail::_xvec3 degrees(const detail::_xvec3& radians) { return detail::_xvec3( degrees(radians.x), degrees(radians.y), degrees(radians.z)); } template inline detail::_xvec4 degrees(const detail::_xvec4& radians) { return detail::_xvec4( degrees(radians.x), degrees(radians.y), degrees(radians.z), degrees(radians.w)); } // sin template inline T sin(T angle) { return ::std::sin(angle); } template inline detail::_xvec2 sin(const detail::_xvec2& angle) { return detail::_xvec2( sin(angle.x), sin(angle.y)); } template inline detail::_xvec3 sin(const detail::_xvec3& angle) { return detail::_xvec3( sin(angle.x), sin(angle.y), sin(angle.z)); } template inline detail::_xvec4 sin(const detail::_xvec4& angle) { return detail::_xvec4( sin(angle.x), sin(angle.y), sin(angle.z), sin(angle.w)); } // cos template inline T cos(T angle) { return ::std::cos(angle); } template inline detail::_xvec2 cos(const detail::_xvec2& angle) { return detail::_xvec2( cos(angle.x), cos(angle.y)); } template inline detail::_xvec3 cos(const detail::_xvec3& angle) { return detail::_xvec3( cos(angle.x), cos(angle.y), cos(angle.z)); } template inline detail::_xvec4 cos(const detail::_xvec4& angle) { return detail::_xvec4( cos(angle.x), cos(angle.y), cos(angle.z), cos(angle.w)); } // tan template inline T tan(T angle) { return ::std::tan(angle); } template inline detail::_xvec2 tan(const detail::_xvec2& angle) { return detail::_xvec2( tan(angle.x), tan(angle.y)); } template inline detail::_xvec3 tan(const detail::_xvec3& angle) { return detail::_xvec3( tan(angle.x), tan(angle.y), tan(angle.z)); } template inline detail::_xvec4 tan(const detail::_xvec4& angle) { return detail::_xvec4( tan(angle.x), tan(angle.y), tan(angle.z), tan(angle.w)); } // asin template inline T asin(T x) { return ::std::asin(x); } template inline detail::_xvec2 asin(const detail::_xvec2& x) { return detail::_xvec2( asin(x.x), asin(x.y)); } template inline detail::_xvec3 asin(const detail::_xvec3& x) { return detail::_xvec3( asin(x.x), asin(x.y), asin(x.z)); } template inline detail::_xvec4 asin(const detail::_xvec4& x) { return detail::_xvec4( asin(x.x), asin(x.y), asin(x.z), asin(x.w)); } // acos template inline T acos(T x) { return ::std::acos(x); } template inline detail::_xvec2 acos(const detail::_xvec2& x) { return detail::_xvec2( acos(x.x), acos(x.y)); } template inline detail::_xvec3 acos(const detail::_xvec3& x) { return detail::_xvec3( acos(x.x), acos(x.y), acos(x.z)); } template inline detail::_xvec4 acos(const detail::_xvec4& x) { return detail::_xvec4( acos(x.x), acos(x.y), acos(x.z), acos(x.w)); } // atan template inline T atan(T y, T x) { return ::std::atan2(y, x); } template inline detail::_xvec2 atan(const detail::_xvec2& y, const detail::_xvec2& x) { return detail::_xvec2( atan(y.x, x.x), atan(y.y, x.y)); } template inline detail::_xvec3 atan(const detail::_xvec3& y, const detail::_xvec3& x) { return detail::_xvec3( atan(y.x, x.x), atan(y.y, x.y), atan(y.z, x.z)); } template inline detail::_xvec4 atan(const detail::_xvec4& y, const detail::_xvec4& x) { return detail::_xvec4( atan(y.x, x.x), atan(y.y, x.y), atan(y.z, x.z), atan(y.w, x.w)); } template inline T atan(T x) { return ::std::atan(x); } template inline detail::_xvec2 atan(const detail::_xvec2& x) { return detail::_xvec2( atan(x.x), atan(x.y)); } template inline detail::_xvec3 atan(const detail::_xvec3& x) { return detail::_xvec3( atan(x.x), atan(x.y), atan(x.z)); } template inline detail::_xvec4 atan(const detail::_xvec4& x) { return detail::_xvec4( atan(x.x), atan(x.y), atan(x.z), atan(x.w)); } //////////////////////////////////////////////////////////////////////// // Exponential Functions // pow template inline T pow(T x, T y) { return ::std::pow(x, y); } template inline detail::_xvec2 pow(const detail::_xvec2& x, const detail::_xvec2& y) { return detail::_xvec2( pow(x.x, y.x), pow(x.y, y.y)); } template inline detail::_xvec3 pow(const detail::_xvec3& x, const detail::_xvec3& y) { return detail::_xvec3( pow(x.x, y.x), pow(x.y, y.y), pow(x.z, y.z)); } template inline detail::_xvec4 pow(const detail::_xvec4& x, const detail::_xvec4& y) { return detail::_xvec4( pow(x.x, y.x), pow(x.y, y.y), pow(x.z, y.z), pow(x.w, y.w)); } // exp template inline T exp(T x) { return ::std::exp(x); } template inline detail::_xvec2 exp(const detail::_xvec2& x) { return detail::_xvec2( exp(x.x), exp(x.y)); } template inline detail::_xvec3 exp(const detail::_xvec3& x) { return detail::_xvec3( exp(x.x), exp(x.y), exp(x.z)); } template inline detail::_xvec4 exp(const detail::_xvec4& x) { return detail::_xvec4( exp(x.x), exp(x.y), exp(x.z), exp(x.w)); } // log template inline T log(T x) { return ::std::log(x); } template inline detail::_xvec2 log(const detail::_xvec2& x) { return detail::_xvec2( log(x.x), log(x.y)); } template inline detail::_xvec3 log(const detail::_xvec3& x) { return detail::_xvec3( log(x.x), log(x.y), log(x.z)); } template inline detail::_xvec4 log(const detail::_xvec4& x) { return detail::_xvec4( log(x.x), log(x.y), log(x.z), log(x.w)); } //exp2, ln2 = 0.69314718055994530941723212145818f template inline T exp2(T x) { return ::std::exp(T(0.69314718055994530941723212145818) * x); } template inline detail::_xvec2 exp2(const detail::_xvec2& x) { return detail::_xvec2( exp2(x.x), exp2(x.y)); } template inline detail::_xvec3 exp2(const detail::_xvec3& x) { return detail::_xvec3( exp2(x.x), exp2(x.y), exp2(x.z)); } template inline detail::_xvec4 exp2(const detail::_xvec4& x) { return detail::_xvec4( exp2(x.x), exp2(x.y), exp2(x.z), exp2(x.w)); } // log2, ln2 = 0.69314718055994530941723212145818f template inline T log2(T x) { return ::std::log(x) / T(0.69314718055994530941723212145818); } template inline detail::_xvec2 log2(const detail::_xvec2& x) { return detail::_xvec2( log2(x.x), log2(x.y)); } template inline detail::_xvec3 log2(const detail::_xvec3& x) { return detail::_xvec3( log2(x.x), log2(x.y), log2(x.z)); } template inline detail::_xvec4 log2(const detail::_xvec4& x) { return detail::_xvec4( log2(x.x), log2(x.y), log2(x.z), log2(x.w)); } // sqrt template inline T sqrt(T x) { return T(::std::sqrt(double(x))); } template inline detail::_xvec2 sqrt(const detail::_xvec2& x) { return detail::_xvec2( sqrt(x.x), sqrt(x.y)); } template inline detail::_xvec3 sqrt(const detail::_xvec3& x) { return detail::_xvec3( sqrt(x.x), sqrt(x.y), sqrt(x.z)); } template inline detail::_xvec4 sqrt(const detail::_xvec4& x) { return detail::_xvec4( sqrt(x.x), sqrt(x.y), sqrt(x.z), sqrt(x.w)); } template inline T inversesqrt(T x) { return 1.0f / ::std::sqrt(x); } template inline detail::_xvec2 inversesqrt(const detail::_xvec2& x) { return detail::_xvec2( inversesqrt(x.x), inversesqrt(x.y)); } template inline detail::_xvec3 inversesqrt(const detail::_xvec3& x) { return detail::_xvec3( inversesqrt(x.x), inversesqrt(x.y), inversesqrt(x.z)); } template inline detail::_xvec4 inversesqrt(const detail::_xvec4& x) { return detail::_xvec4( inversesqrt(x.x), inversesqrt(x.y), inversesqrt(x.z), inversesqrt(x.w)); } //////////////////////////////////////////////////////////////////////// // Common Functions // abs template inline T abs(T x) { return x >= T(0) ? x : -x; } template inline detail::_xvec2 abs(const detail::_xvec2& x) { return detail::_xvec2( abs(x.x), abs(x.y)); } template inline detail::_xvec3 abs(const detail::_xvec3& x) { return detail::_xvec3( abs(x.x), abs(x.y), abs(x.z)); } template inline detail::_xvec4 abs(const detail::_xvec4& x) { return detail::_xvec4( abs(x.x), abs(x.y), abs(x.z), abs(x.w)); } // sign /* Try something like based on x >> 31 to get the sign bit */ template inline T sign(T x) { T result; if(x > T(0)) result = T(1); else if(x < T(0)) result = T(-1); else result = T(0); return result; } template inline detail::_xvec2 sign(const detail::_xvec2& x) { return detail::_xvec2( sign(x.x), sign(x.y)); } template inline detail::_xvec3 sign(const detail::_xvec3& x) { return detail::_xvec3( sign(x.x), sign(x.y), sign(x.z)); } template inline detail::_xvec4 sign(const detail::_xvec4& x) { return detail::_xvec4( sign(x.x), sign(x.y), sign(x.z), sign(x.w)); } // floor template inline T floor(T x) { return ::std::floor(x); } template inline detail::_xvec2 floor(const detail::_xvec2& x) { return detail::_xvec2( floor(x.x), floor(x.y)); } template inline detail::_xvec3 floor(const detail::_xvec3& x) { return detail::_xvec3( floor(x.x), floor(x.y), floor(x.z)); } template inline detail::_xvec4 floor(const detail::_xvec4& x) { return detail::_xvec4( floor(x.x), floor(x.y), floor(x.z), floor(x.w)); } // ceil template inline T ceil(T x) { return ::std::ceil(x); } template inline detail::_xvec2 ceil(const detail::_xvec2& x) { return detail::_xvec2( ceil(x.x), ceil(x.y)); } template inline detail::_xvec3 ceil(const detail::_xvec3& x) { return detail::_xvec3( ceil(x.x), ceil(x.y), ceil(x.z)); } template inline detail::_xvec4 ceil(const detail::_xvec4& x) { return detail::_xvec4( ceil(x.x), ceil(x.y), ceil(x.z), ceil(x.w)); } // fract template inline T fract(T x) { return x - ::std::floor(x); } template inline detail::_xvec2 fract(const detail::_xvec2& x) { return detail::_xvec2( fract(x.x), fract(x.y)); } template inline detail::_xvec3 fract(const detail::_xvec3& x) { return detail::_xvec3( fract(x.x), fract(x.y), fract(x.z)); } template inline detail::_xvec4 fract(const detail::_xvec4& x) { return detail::_xvec4( fract(x.x), fract(x.y), fract(x.z), fract(x.w)); } // mod template inline T mod(T x, T y) { return x - y * floor(x / y); } template inline detail::_xvec2 mod(const detail::_xvec2& x, T y) { return detail::_xvec2( mod(x.x, y), mod(x.y, y)); } template inline detail::_xvec3 mod(const detail::_xvec3& x, T y) { return detail::_xvec3( mod(x.x, y), mod(x.y, y), mod(x.z, y)); } template inline detail::_xvec4 mod(const detail::_xvec4& x, T y) { return detail::_xvec4( mod(x.x, y), mod(x.y, y), mod(x.z, y), mod(x.w, y)); } template inline detail::_xvec2 mod(const detail::_xvec2& x, const detail::_xvec2& y) { return detail::_xvec2( mod(x.x, y.x), mod(x.y, y.y)); } template inline detail::_xvec3 mod(const detail::_xvec3& x, const detail::_xvec3& y) { return detail::_xvec3( mod(x.x, y.x), mod(x.y, y.y), mod(x.z, y.z)); } template inline detail::_xvec4 mod(const detail::_xvec4& x, const detail::_xvec4& y) { return detail::_xvec4( mod(x.x, y.x), mod(x.y, y.y), mod(x.z, y.z), mod(x.w, y.w)); } // min template inline T min(T x, T y) { return x < y ? x : y; } template inline detail::_xvec2 min(const detail::_xvec2& x, T y) { return detail::_xvec2( min(x.x, y), min(x.y, y)); } template inline detail::_xvec3 min(const detail::_xvec3& x, T y) { return detail::_xvec3( min(x.x, y), min(x.y, y), min(x.z, y)); } template inline detail::_xvec4 min(const detail::_xvec4& x, T y) { return detail::_xvec4( min(x.x, y), min(x.y, y), min(x.z, y), min(x.w, y)); } template inline detail::_xvec2 min(const detail::_xvec2& x, const detail::_xvec2& y) { return detail::_xvec2( min(x.x, y.x), min(x.y, y.y)); } template inline detail::_xvec3 min(const detail::_xvec3& x, const detail::_xvec3& y) { return detail::_xvec3( min(x.x, y.x), min(x.y, y.y), min(x.z, y.z)); } template inline detail::_xvec4 min(const detail::_xvec4& x, const detail::_xvec4& y) { return detail::_xvec4( min(x.x, y.x), min(x.y, y.y), min(x.z, y.z), min(x.w, y.w)); } // max template inline T max(T x, T y) { return x > y ? x : y; } template inline detail::_xvec2 max(const detail::_xvec2& x, T y) { return detail::_xvec2( max(x.x, y), max(x.y, y)); } template inline detail::_xvec3 max(const detail::_xvec3& x, T y) { return detail::_xvec3( max(x.x, y), max(x.y, y), max(x.z, y)); } template inline detail::_xvec4 max(const detail::_xvec4& x, T y) { return detail::_xvec4( max(x.x, y), max(x.y, y), max(x.z, y), max(x.w, y)); } template inline detail::_xvec2 max(const detail::_xvec2& x, const detail::_xvec2& y) { return detail::_xvec2( max(x.x, y.x), max(x.y, y.y)); } template inline detail::_xvec3 max(const detail::_xvec3& x, const detail::_xvec3& y) { return detail::_xvec3( max(x.x, y.x), max(x.y, y.y), max(x.z, y.z)); } template inline detail::_xvec4 max(const detail::_xvec4& x, const detail::_xvec4& y) { return detail::_xvec4( max(x.x, y.x), max(x.y, y.y), max(x.z, y.z), max(x.w, y.w)); } // clamp template inline T clamp(T x, T minVal, T maxVal) { if(x >= maxVal) return maxVal; if(x <= minVal) return minVal; return x; } template inline detail::_xvec2 clamp(const detail::_xvec2& x, T minVal, T maxVal) { return detail::_xvec2( clamp(x.x, minVal, maxVal), clamp(x.y, minVal, maxVal)); } template inline detail::_xvec3 clamp(const detail::_xvec3& x, T minVal, T maxVal) { return detail::_xvec3( clamp(x.x, minVal, maxVal), clamp(x.y, minVal, maxVal), clamp(x.z, minVal, maxVal)); } template inline detail::_xvec4 clamp(const detail::_xvec4& x, T minVal, T maxVal) { return detail::_xvec4( clamp(x.x, minVal, maxVal), clamp(x.y, minVal, maxVal), clamp(x.z, minVal, maxVal), clamp(x.w, minVal, maxVal)); } template inline detail::_xvec2 clamp(const detail::_xvec2& x, const detail::_xvec2& minVal, const detail::_xvec2& maxVal) { return detail::_xvec2( clamp(x.x, minVal.x, maxVal.x), clamp(x.y, minVal.y, maxVal.y)); } template inline detail::_xvec3 clamp(const detail::_xvec3& x, const detail::_xvec3& minVal, const detail::_xvec3& maxVal) { return detail::_xvec3( clamp(x.x, minVal.x, maxVal.x), clamp(x.y, minVal.y, maxVal.y), clamp(x.z, minVal.z, maxVal.z)); } template inline detail::_xvec4 clamp(const detail::_xvec4& x, const detail::_xvec4& minVal, const detail::_xvec4& maxVal) { return detail::_xvec4( clamp(x.x, minVal.x, maxVal.x), clamp(x.y, minVal.y, maxVal.y), clamp(x.z, minVal.z, maxVal.z), clamp(x.w, minVal.w, maxVal.w)); } // mix template inline T mix(const T& x, const T& y, const U& a) { return x * (T(1) - a) + y * a; } /* // mix template inline T mix(T x, T y, T a) { return x * (T(1) - a) + y * a; } template inline detail::_xvec2 mix(const detail::_xvec2& x, const detail::_xvec2& y, T a) { return x * (T(1) - a) + y * a; } template inline detail::_xvec3 mix(const detail::_xvec3& x, const detail::_xvec3& y, T a) { return x * (T(1) - a) + y * a; } template inline detail::_xvec4 mix(const detail::_xvec4& x, const detail::_xvec4& y, T a) { return x * (T(1) - a) + y * a; } template inline detail::_xvec2 mix(const detail::_xvec2& x, const detail::_xvec2& y, const detail::_xvec2& a) { return x * (T(1) - a) + y * a; } template inline detail::_xvec3 mix(const detail::_xvec3& x, const detail::_xvec3& y, const detail::_xvec3& a) { return x * (T(1) - a) + y * a; } template inline detail::_xvec4 mix(const detail::_xvec4& x, const detail::_xvec4& y, const detail::_xvec4& a) { return x * (T(1) - a) + y * a; } */ // step template inline T step(T edge, T x) { return x <= edge ? T(0) : T(1); } template inline detail::_xvec2 step(T edge, const detail::_xvec2& x) { return detail::_xvec2( x.x <= edge ? T(0) : T(1), x.y <= edge ? T(0) : T(1)); } template inline detail::_xvec3 step(T edge, const detail::_xvec3& x) { return detail::_xvec3( x.x <= edge ? T(0) : T(1), x.y <= edge ? T(0) : T(1), x.z <= edge ? T(0) : T(1)); } template inline detail::_xvec4 step(T edge, const detail::_xvec4& x) { return detail::_xvec4( x.x <= edge ? T(0) : T(1), x.y <= edge ? T(0) : T(1), x.z <= edge ? T(0) : T(1), x.w <= edge ? T(0) : T(1)); } template inline detail::_xvec2 step(const detail::_xvec2& edge, const detail::_xvec2& x) { return detail::_xvec2( x.x <= edge.x ? T(0) : T(1), x.y <= edge.y ? T(0) : T(1)); } template inline detail::_xvec3 step(const detail::_xvec3& edge, const detail::_xvec3& x) { return detail::_xvec3( x.x <= edge.x ? T(0) : T(1), x.y <= edge.y ? T(0) : T(1), x.z <= edge.z ? T(0) : T(1)); } template inline detail::_xvec4 step(const detail::_xvec4& edge, const detail::_xvec4& x) { return detail::_xvec4( x.x <= edge.x ? T(0) : T(1), x.y <= edge.y ? T(0) : T(1), x.z <= edge.z ? T(0) : T(1), x.w <= edge.w ? T(0) : T(1)); } // smoothstep template inline T smoothstep(T edge0, T edge1, T x) { T tmp = clamp((x - edge0) / (edge1 - edge0), T(0), T(1)); return tmp * tmp * (T(3) - T(2) * tmp); } template inline detail::_xvec2 smoothstep(T edge0, T edge1, const detail::_xvec2& x) { return detail::_xvec2( smoothstep(edge0, edge1, x.x), smoothstep(edge0, edge1, x.y)); } template inline detail::_xvec3 smoothstep(T edge0, T edge1, const detail::_xvec3& x) { return detail::_xvec3( smoothstep(edge0, edge1, x.x), smoothstep(edge0, edge1, x.y), smoothstep(edge0, edge1, x.z)); } template inline detail::_xvec4 smoothstep(T edge0, T edge1, const detail::_xvec4& x) { return detail::_xvec4( smoothstep(edge0, edge1, x.x), smoothstep(edge0, edge1, x.y), smoothstep(edge0, edge1, x.z), smoothstep(edge0, edge1, x.w)); } template inline detail::_xvec2 smoothstep(const detail::_xvec2& edge0, const detail::_xvec2& edge1, const detail::_xvec2& x) { return detail::_xvec2( smoothstep(edge0.x, edge1.x, x.x), smoothstep(edge0.y, edge1.y, x.y)); } template inline detail::_xvec3 smoothstep(const detail::_xvec3& edge0, const detail::_xvec3& edge1, const detail::_xvec3& x) { return detail::_xvec3( smoothstep(edge0.x, edge1.x, x.x), smoothstep(edge0.y, edge1.y, x.y), smoothstep(edge0.z, edge1.z, x.z)); } template inline detail::_xvec4 smoothstep(const detail::_xvec4& edge0, const detail::_xvec4& edge1, const detail::_xvec4& x) { return detail::_xvec4( smoothstep(edge0.x, edge1.x, x.x), smoothstep(edge0.y, edge1.y, x.y), smoothstep(edge0.z, edge1.z, x.z), smoothstep(edge0.w, edge1.w, x.w)); } //////////////////////////////////////////////////////////////////////// // Geometric Functions // length template inline T length(T x) { return abs(x); } template inline T length(const detail::_xvec2& x) { T sqr = x.x * x.x + x.y * x.y; return sqrt(sqr); } template inline T length(const detail::_xvec3& x) { T sqr = x.x * x.x + x.y * x.y + x.z * x.z; return sqrt(sqr); } template inline T length(const detail::_xvec4& x) { T sqr = x.x * x.x + x.y * x.y + x.z * x.z + x.w * x.w; return sqrt(sqr); } // distance template inline T distance(const T p0, const T p1) { return length(p1 - p0); } template inline T distance(const detail::_xvec2& p0, const detail::_xvec2& p1) { return length(p1 - p0); } template inline T distance(const detail::_xvec3& p0, const detail::_xvec3& p1) { return length(p1 - p0); } template inline T distance(const detail::_xvec4& p0, const detail::_xvec4& p1) { return length(p1 - p0); } /* template inline valType distance(const genType& p0, const genType& p1) { return length(p1 - p0); } */ // dot template inline T dot(T x, T y) { return x * y; } template inline T dot(const detail::_xvec2& x, const detail::_xvec2& y) { return x.x * y.x + x.y * y.y; } template inline T dot(const detail::_xvec3& x, const detail::_xvec3& y) { return x.x * y.x + x.y * y.y + x.z * y.z; } /* // SSE3 inline float dot(const _xvec4& x, const _xvec4& y) { float Result; __asm { mov esi, x mov edi, y movaps xmm0, [esi] mulps xmm0, [edi] haddps( _xmm0, _xmm0 ) haddps( _xmm0, _xmm0 ) movss Result, xmm0 } return Result; } */ template inline T dot(const detail::_xvec4& x, const detail::_xvec4& y) { return x.x * y.x + x.y * y.y + x.z * y.z + x.w * y.w; } // cross template inline detail::_xvec3 cross(const detail::_xvec3 & x, const detail::_xvec3 & y) { return detail::_xvec3( x.y * y.z - y.y * x.z, x.z * y.x - y.z * x.x, x.x * y.y - y.x * x.y); } // normalize template inline T normalize(T x) { return x < T(0) ? T(-1) : T(1); } // According to issue 10, if length(x) == 0 then result is undefine and generate an error template inline detail::_xvec2 normalize(const detail::_xvec2& x) { T sqr = x.x * x.x + x.y * x.y; return x * inversesqrt(sqr); } template inline detail::_xvec3 normalize(const detail::_xvec3& x) { T sqr = x.x * x.x + x.y * x.y + x.z * x.z; return x * inversesqrt(sqr); } template inline detail::_xvec4 normalize(const detail::_xvec4& x) { T sqr = x.x * x.x + x.y * x.y + x.z * x.z + x.w * x.w; return x * inversesqrt(sqr); } /* // faceforward template inline genType faceforward(const genType& N, const genType& I, const genType& Nref) { return dot(Nref, I) < T(0) ? N : -N; } */ // faceforward template inline T faceforward(T N, T I, T Nref) { return dot(Nref, I) < T(0) ? N : -N; } template inline detail::_xvec2 faceforward(const detail::_xvec2& N, const detail::_xvec2& I, const detail::_xvec2& Nref) { return dot(Nref, I) < T(0) ? N : -N; } template inline detail::_xvec3 faceforward(const detail::_xvec3& N, const detail::_xvec3& I, const detail::_xvec3& Nref) { return dot(Nref, I) < T(0) ? N : -N; } template inline detail::_xvec4 faceforward(const detail::_xvec4& N, const detail::_xvec4& I, const detail::_xvec4& Nref) { return dot(Nref, I) < T(0) ? N : -N; } /* // reflect template genType reflect(const genType& I, const genType& N) { return I - N * dot(N, I) * T(2); } */ // reflect template inline T reflect(T I, T N) { return I - N * dot(N, I) * T(2); } template inline detail::_xvec2 reflect(const detail::_xvec2& I, const detail::_xvec2& N) { return I - N * dot(N, I) * T(2); } template inline detail::_xvec3 reflect(const detail::_xvec3& I, const detail::_xvec3& N) { return I - N * dot(N, I) * T(2); } template inline detail::_xvec4 reflect(const detail::_xvec4& I, const detail::_xvec4& N) { return I - N * dot(N, I) * T(2); } // refract template inline T refract(T I, T N, T eta) { T dot = dot(N, I); T k = T(1) - eta * eta * (T(1) - dot * dot); if(k < T(0)) return T(0); else return eta * I - (eta * dot + sqrt(k)) * N; } template inline detail::_xvec2 refract(const detail::_xvec2& I, const detail::_xvec2& N, T eta) { T dotValue = dot(N, I); T k = T(1) - eta * eta * (T(1) - dotValue * dotValue); if(k < T(0)) return detail::_xvec2(T(0)); else return eta * I - (eta * dotValue + sqrt(k)) * N; } template inline detail::_xvec3 refract(const detail::_xvec3& I, const detail::_xvec3& N, T eta) { T dotValue = dot(N, I); T k = T(1) - eta * eta * (T(1) - dotValue * dotValue); if(k < T(0)) return detail::_xvec3(T(0)); else return eta * I - (eta * dotValue + sqrt(k)) * N; } template inline detail::_xvec4 refract(const detail::_xvec4& I, const detail::_xvec4& N, T eta) { T dotValue = dot(N, I); T k = T(1) - eta * eta * (T(1) - dotValue * dotValue); if(k < T(0)) return detail::_xvec4(T(0)); else return eta * I - (eta * dotValue + sqrt(k)) * N; } //////////////////////////////////////////////////////////////////////// // Matrix Functions // matrixCompMult template inline detail::_xmat2 matrixCompMult(const detail::_xmat2& x, const detail::_xmat2& y) { detail::_xmat2 result; for(int j = 0; j < 2; ++j) for(int i = 0; i < 2; ++i) result[j][i] = x[j][i] * y[j][i]; return result; } template inline detail::_xmat3 matrixCompMult(const detail::_xmat3& x, const detail::_xmat3& y) { detail::_xmat3 result; for(int j = 0; j < 3; ++j) for(int i = 0; i < 3; ++i) result[j][i] = x[j][i] * y[j][i]; return result; } template inline detail::_xmat4 matrixCompMult(const detail::_xmat4& x, const detail::_xmat4& y) { detail::_xmat4 result; for(int j = 0; j < 4; ++j) for(int i = 0; i < 4; ++i) result[j][i] = x[j][i] * y[j][i]; return result; } template inline detail::_xmat2x3 matrixCompMult(const detail::_xmat2x3& x, const detail::_xmat2x3& y) { detail::_xmat2x3 result; for(int j = 0; j < 2; ++j) for(int i = 0; i < 3; ++i) result[j][i] = x[j][i] * y[j][i]; return result; } template inline detail::_xmat3x2 matrixCompMult(const detail::_xmat3x2& x, const detail::_xmat3x2& y) { detail::_xmat3x2 result; for(int j = 0; j < 3; ++j) for(int i = 0; i < 2; ++i) result[j][i] = x[j][i] * y[j][i]; return result; } template inline detail::_xmat2x4 matrixCompMult(const detail::_xmat2x4& x, const detail::_xmat2x4& y) { detail::_xmat2x4 result; for(int j = 0; j < 2; ++j) for(int i = 0; i < 4; ++i) result[j][i] = x[j][i] * y[j][i]; return result; } template inline detail::_xmat4x2 matrixCompMult(const detail::_xmat4x2& x, const detail::_xmat4x2& y) { detail::_xmat4x2 result; for(int j = 0; j < 4; ++j) for(int i = 0; i < 2; ++i) result[j][i] = x[j][i] * y[j][i]; return result; } template inline detail::_xmat3x4 matrixCompMult(const detail::_xmat3x4& x, const detail::_xmat3x4& y) { detail::_xmat3x4 result; for(int j = 0; j < 3; ++j) for(int i = 0; i < 4; ++i) result[j][i] = x[j][i] * y[j][i]; return result; } template inline detail::_xmat4x3 matrixCompMult(const detail::_xmat4x3& x, const detail::_xmat4x3& y) { detail::_xmat4x3 result; for(int j = 0; j < 4; ++j) for(int i = 0; i < 3; ++i) result[j][i] = x[j][i] * y[j][i]; return result; } // outerProduct template inline detail::_xmat2 outerProduct(const detail::_xvec2& c, const detail::_xvec2& r) { detail::_xmat2 m; m[0][0] = c.x * r.x; m[0][1] = c.y * r.x; m[1][0] = c.x * r.y; m[1][1] = c.y * r.y; return m; } template inline detail::_xmat3 outerProduct(const detail::_xvec3& c, const detail::_xvec3& r) { detail::_xmat3 m; m[0][0] = c.x * r.x; m[0][1] = c.y * r.x; m[0][2] = c.z * r.x; m[1][0] = c.x * r.y; m[1][1] = c.y * r.y; m[1][2] = c.z * r.y; m[2][0] = c.x * r.z; m[2][1] = c.y * r.z; m[2][2] = c.z * r.z; return m; } template inline detail::_xmat4 outerProduct(const detail::_xvec4& c, const detail::_xvec4& r) { detail::_xmat4 m; m[0][0] = c.x * r.x; m[0][1] = c.y * r.x; m[0][2] = c.z * r.x; m[0][3] = c.w * r.x; m[1][0] = c.x * r.y; m[1][1] = c.y * r.y; m[1][2] = c.z * r.y; m[1][3] = c.w * r.y; m[2][0] = c.x * r.z; m[2][1] = c.y * r.z; m[2][2] = c.z * r.z; m[2][3] = c.w * r.z; m[3][0] = c.x * r.w; m[3][1] = c.y * r.w; m[3][2] = c.z * r.w; m[3][3] = c.w * r.w; return m; } template inline detail::_xmat2x3 outerProduct(const detail::_xvec3& c, const detail::_xvec2& r) { detail::_xmat2x3 m; m[0][0] = c.x * r.x; m[0][1] = c.y * r.x; m[0][2] = c.z * r.x; m[1][0] = c.x * r.y; m[1][1] = c.y * r.y; m[1][2] = c.z * r.y; return m; } template inline detail::_xmat3x2 outerProduct(const detail::_xvec2& c, const detail::_xvec3& r) { detail::_xmat3x2 m; m[0][0] = c.x * r.x; m[0][1] = c.y * r.x; m[1][0] = c.x * r.y; m[1][1] = c.y * r.y; m[2][0] = c.x * r.z; m[2][1] = c.y * r.z; return m; } template inline detail::_xmat2x4 outerProduct(const detail::_xvec2& c, const detail::_xvec4& r) { detail::_xmat2x4 m; m[0][0] = c.x * r.x; m[0][1] = c.y * r.x; m[0][2] = c.z * r.x; m[0][3] = c.w * r.x; m[1][0] = c.x * r.y; m[1][1] = c.y * r.y; m[1][2] = c.z * r.y; m[1][3] = c.w * r.y; return m; } template inline detail::_xmat4x2 outerProduct(const detail::_xvec4& c, const detail::_xvec2& r) { detail::_xmat4x2 m; m[0][0] = c.x * r.x; m[0][1] = c.y * r.x; m[1][0] = c.x * r.y; m[1][1] = c.y * r.y; m[2][0] = c.x * r.z; m[2][1] = c.y * r.z; m[3][0] = c.x * r.w; m[3][1] = c.y * r.w; return m; } template inline detail::_xmat3x4 outerProduct(const detail::_xvec4& c, const detail::_xvec3& r) { detail::_xmat3x4 m; m[0][0] = c.x * r.x; m[0][1] = c.y * r.x; m[0][2] = c.z * r.x; m[0][3] = c.w * r.x; m[1][0] = c.x * r.y; m[1][1] = c.y * r.y; m[1][2] = c.z * r.y; m[1][3] = c.w * r.y; m[2][0] = c.x * r.z; m[2][1] = c.y * r.z; m[2][2] = c.z * r.z; m[2][3] = c.w * r.z; return m; } template inline detail::_xmat4x3 outerProduct(const detail::_xvec3& c, const detail::_xvec4& r) { detail::_xmat4x3 m; m[0][0] = c.x * r.x; m[0][1] = c.y * r.x; m[0][2] = c.z * r.x; m[1][0] = c.x * r.y; m[1][1] = c.y * r.y; m[1][2] = c.z * r.y; m[2][0] = c.x * r.z; m[2][1] = c.y * r.z; m[2][2] = c.z * r.z; m[3][0] = c.x * r.w; m[3][1] = c.y * r.w; m[3][2] = c.z * r.w; return m; } template inline detail::_xmat2 transpose(const detail::_xmat2& m) { detail::_xmat2 result; result[0][0] = m[0][0]; result[0][1] = m[1][0]; result[1][0] = m[0][1]; result[1][1] = m[1][1]; return result; } template inline detail::_xmat3 transpose(const detail::_xmat3 & m) { detail::_xmat3 result; result[0][0] = m[0][0]; result[0][1] = m[1][0]; result[0][2] = m[2][0]; result[1][0] = m[0][1]; result[1][1] = m[1][1]; result[1][2] = m[2][1]; result[2][0] = m[0][2]; result[2][1] = m[1][2]; result[2][2] = m[2][2]; return result; } template inline detail::_xmat4 transpose(const detail::_xmat4 & m) { detail::_xmat4 result; result[0][0] = m[0][0]; result[0][1] = m[1][0]; result[0][2] = m[2][0]; result[0][3] = m[3][0]; result[1][0] = m[0][1]; result[1][1] = m[1][1]; result[1][2] = m[2][1]; result[1][3] = m[3][1]; result[2][0] = m[0][2]; result[2][1] = m[1][2]; result[2][2] = m[2][2]; result[2][3] = m[3][2]; result[3][0] = m[0][3]; result[3][1] = m[1][3]; result[3][2] = m[2][3]; result[3][3] = m[3][3]; return result; } template inline detail::_xmat2x3 transpose(const detail::_xmat3x2& m) { detail::_xmat2x3 result; result[0][0] = m[0][0]; result[0][1] = m[1][0]; result[0][2] = m[2][0]; result[1][0] = m[0][1]; result[1][1] = m[1][1]; result[1][2] = m[2][1]; return result; } template inline detail::_xmat3x2 transpose(const detail::_xmat2x3& m) { detail::_xmat3x2 result; result[0][0] = m[0][0]; result[0][1] = m[1][0]; result[1][0] = m[0][1]; result[1][1] = m[1][1]; result[2][0] = m[0][2]; result[2][1] = m[1][2]; return result; } template inline detail::_xmat2x4 transpose(const detail::_xmat4x2& m) { detail::_xmat2x4 result; result[0][0] = m[0][0]; result[0][1] = m[1][0]; result[0][2] = m[2][0]; result[0][3] = m[3][0]; result[1][0] = m[0][1]; result[1][1] = m[1][1]; result[1][2] = m[2][1]; result[1][3] = m[3][1]; return result; } template inline detail::_xmat4x2 transpose(const detail::_xmat2x4& m) { detail::_xmat4x2 result; result[0][0] = m[0][0]; result[0][1] = m[1][0]; result[1][0] = m[0][1]; result[1][1] = m[1][1]; result[2][0] = m[0][2]; result[2][1] = m[1][2]; result[3][0] = m[0][3]; result[3][1] = m[1][3]; return result; } template inline detail::_xmat3x4 transpose(const detail::_xmat4x3& m) { detail::_xmat3x4 result; result[0][0] = m[0][0]; result[0][1] = m[1][0]; result[0][2] = m[2][0]; result[0][3] = m[3][0]; result[1][0] = m[0][1]; result[1][1] = m[1][1]; result[1][2] = m[2][1]; result[1][3] = m[3][1]; result[2][0] = m[0][2]; result[2][1] = m[1][2]; result[2][2] = m[2][2]; result[2][3] = m[3][2]; return result; } template inline detail::_xmat4x3 transpose(const detail::_xmat3x4& m) { detail::_xmat4x3 result; result[0][0] = m[0][0]; result[0][1] = m[1][0]; result[0][2] = m[2][0]; result[1][0] = m[0][1]; result[1][1] = m[1][1]; result[1][2] = m[2][1]; result[2][0] = m[0][2]; result[2][1] = m[1][2]; result[2][2] = m[2][2]; result[3][0] = m[0][3]; result[3][1] = m[1][3]; result[3][2] = m[2][3]; result[4][0] = m[0][4]; result[4][1] = m[1][4]; result[4][2] = m[2][4]; return result; } //////////////////////////////////////////////////////////////////////// // Vector Relational Functions // lessThan template inline detail::_bvec2 lessThan(const detail::_xvec2& x, const detail::_xvec2& y) { return detail::_bvec2(x.x < y.x, x.y < y.y); } template inline detail::_bvec3 lessThan(const detail::_xvec3& x, const detail::_xvec3& y) { return detail::_bvec3(x.x < y.x, x.y < y.y, x.z < y.z); } template inline detail::_bvec4 lessThan(const detail::_xvec4& x, const detail::_xvec4& y) { return detail::_bvec4(x.x < y.x, x.y < y.y, x.z < y.z, x.w < y.w); } // lessThanEqual template inline detail::_bvec2 lessThanEqual(const detail::_xvec2& x, const detail::_xvec2& y) { return detail::_bvec2(x.x <= y.x, x.y <= y.y); } template inline detail::_bvec3 lessThanEqual(const detail::_xvec3& x, const detail::_xvec3& y) { return detail::_bvec3(x.x <= y.x, x.y <= y.y, x.z <= y.z); } template inline detail::_bvec4 lessThanEqual(const detail::_xvec4& x, const detail::_xvec4& y) { return detail::_bvec4(x.x <= y.x, x.y <= y.y, x.z <= y.z, x.w <= y.w); } // greaterThan template inline detail::_bvec2 greaterThan(const detail::_xvec2& x, const detail::_xvec2& y) { return detail::_bvec2(x.x > y.x, x.y > y.y); } template inline detail::_bvec3 greaterThan(const detail::_xvec3& x, const detail::_xvec3& y) { return detail::_bvec3(x.x > y.x, x.y > y.y, x.z > y.z); } template inline detail::_bvec4 greaterThan(const detail::_xvec4& x, const detail::_xvec4& y) { return detail::_bvec4(x.x > y.x, x.y > y.y, x.z > y.z, x.w > y.w); } // greaterThanEqual template inline detail::_bvec2 greaterThanEqual(const detail::_xvec2& x, const detail::_xvec2& y) { return detail::_bvec2(x.x >= y.x, x.y >= y.y); } template inline detail::_bvec3 greaterThanEqual(const detail::_xvec3& x, const detail::_xvec3& y) { return detail::_bvec3(x.x >= y.x, x.y >= y.y, x.z >= y.z); } template inline detail::_bvec4 greaterThanEqual(const detail::_xvec4& x, const detail::_xvec4& y) { return detail::_bvec4(x.x >= y.x, x.y >= y.y, x.z >= y.z, x.w >= y.w); } // equal inline detail::_bvec2 equal(const detail::_bvec2& x, const detail::_bvec2& y) { return detail::_bvec2(x.x == y.x, x.y == y.y); } inline detail::_bvec3 equal(const detail::_bvec3& x, const detail::_bvec3& y) { return detail::_bvec3(x.x == y.x, x.y == y.y, x.z == y.z); } inline detail::_bvec4 equal(const detail::_bvec4& x, const detail::_bvec4& y) { return detail::_bvec4(x.x == y.x, x.y == y.y, x.z == y.z, x.w == y.w); } template inline detail::_bvec2 equal(const detail::_xvec2& x, const detail::_xvec2& y) { return detail::_bvec2(x.x == y.x, x.y == y.y); } template inline detail::_bvec3 equal(const detail::_xvec3& x, const detail::_xvec3& y) { return detail::_bvec3(x.x == y.x, x.y == y.y, x.z == y.z); } template inline detail::_bvec4 equal(const detail::_xvec4& x, const detail::_xvec4& y) { return detail::_bvec4(x.x == y.x, x.y == y.y, x.z == y.z, x.w == y.w); } // notEqual inline detail::_bvec2 notEqual(const detail::_bvec2& x, const detail::_bvec2& y) { return detail::_bvec2(x.x != y.x, x.y != y.y); } inline detail::_bvec3 notEqual(const detail::_bvec3 & x, const detail::_bvec3& y) { return detail::_bvec3(x.x != y.x, x.y != y.y, x.z != y.z); } inline detail::_bvec4 notEqual(const detail::_bvec4 & x, const detail::_bvec4& y) { return detail::_bvec4(x.x != y.x, x.y != y.y, x.z != y.z, x.w != y.w); } template inline detail::_bvec2 notEqual(const detail::_xvec2& x, const detail::_xvec2& y) { return detail::_bvec2(x.x != y.x, x.y != y.y); } template inline detail::_bvec3 notEqual(const detail::_xvec3& x, const detail::_xvec3& y) { return detail::_bvec3(x.x != y.x, x.y != y.y, x.z != y.z); } template inline detail::_bvec4 notEqual(const detail::_xvec4& x, const detail::_xvec4& y) { return detail::_bvec4(x.x != y.x, x.y != y.y, x.z != y.z, x.w != y.w); } // any inline bool any(const detail::_bvec2& x) { return x.x || x.y; } inline bool any(const detail::_bvec3& x) { return x.x || x.y || x.z; } inline bool any(const detail::_bvec4& x) { return x.x || x.y || x.z || x.w; } // all inline bool all(const detail::_bvec2& x) { return x.x && x.y; } inline bool all(const detail::_bvec3& x) { return x.x && x.y && x.z; } inline bool all(const detail::_bvec4& x) { return x.x && x.y && x.z && x.w; } #ifdef GLM_COMPILER_VC inline bool not(bool x) { return !x; } inline detail::_bvec2 not(const detail::_bvec2& v) { return detail::_bvec2(!v.x, !v.y); } inline detail::_bvec3 not(const detail::_bvec3& v) { return detail::_bvec3(!v.x, !v.y, !v.z); } inline detail::_bvec4 not(const detail::_bvec4& v) { return detail::_bvec4(!v.x, !v.y, !v.z, !v.w); } #elif GLM_COMPILER_GCC inline detail::_bvec2 operator not(const detail::_bvec2& v) { return detail::_bvec2(!v.x, !v.y); } inline detail::_bvec3 operator not(const detail::_bvec3& v) { return detail::_bvec3(!v.x, !v.y, !v.z); } inline detail::_bvec4 operator not(const detail::_bvec4& v) { return detail::_bvec4(!v.x, !v.y, !v.z, !v.w); } #endif //////////////////////////////////////////////////////////////////////// // Noise Functions // noise1 template inline T noise1(T x) { int iNbr = int(x + T(3) / T(2)) * 1103515245 + 12345; return T(int(iNbr / T(65536)) % 32768) / T(32767); } template inline T noise1(const detail::_xvec2& x) { T fNbr(0); for(int i = 0; i < 2; ++i) fNbr += x[i]; int iNbr = int(fNbr + T(3) / T(2)) * 1103515245 + 12345; return T(int(iNbr / T(65536)) % 32768) / T(32767); } template inline T noise1(const detail::_xvec3& x) { T fNbr(0); for(int i = 0; i < 3; ++i) fNbr += x[i]; int iNbr = int(fNbr + T(3) / T(2)) * 1103515245 + 12345; return T(int(iNbr / T(65536)) % 32768) / T(32767); } template inline T noise1(const detail::_xvec4& x) { T fNbr(0); for(int i = 0; i < 4; i++) fNbr += x[i]; int iNbr = int(fNbr + T(3) / T(2)) * 1103515245 + 12345; return T(int(iNbr / T(65536)) % 32768) / T(32767); } // noise2 template inline detail::_xvec2 noise2(T x) { T f1 = x * T(1103515245) + T(12345); T f2 = f1 * T(1103515245) + T(12345); return detail::_xvec2( noise1(f1), noise1(f2)); } template inline detail::_xvec2 noise2(const detail::_xvec2& x) { T f0(0); for(int i = 0; i < 2; ++i) f0 += x[i]; T f1 = f0 * T(1103515245) + T(12345); T f2 = f1 * T(1103515245) + T(12345); return detail::_xvec2( noise1(f1), noise1(f2)); } template inline detail::_xvec2 noise2(const detail::_xvec3& x) { T f0(0); for(int i = 0; i < 3; ++i) f0 += x[i]; T f1 = f0 * T(1103515245) + T(12345); T f2 = f1 * T(1103515245) + T(12345); return detail::_xvec2( noise1(f1), noise1(f2)); } template inline detail::_xvec2 noise2(const detail::_xvec4& x) { T f0(0); for(int i = 0; i < 4; ++i) f0 += x[i]; T f1 = f0 * T(1103515245) + T(12345); T f2 = f1 * T(1103515245) + T(12345); return detail::_xvec2( noise1(f1), noise1(f2)); } // noise3 template inline detail::_xvec3 noise3(T x) { T f1 = x * T(1103515245) + T(12345); T f2 = f1 * T(1103515245) + T(12345); T f3 = f2 * T(1103515245) + T(12345); return detail::_xvec3( noise1(f1), noise1(f2), noise1(f3)); } template inline detail::_xvec3 noise3(const detail::_xvec2& x) { T f0(0); for(int i = 0; i < 2; ++i) f0 += x[i]; T f1 = f0 * T(1103515245) + T(12345); T f2 = f1 * T(1103515245) + T(12345); T f3 = f2 * T(1103515245) + T(12345); return detail::_xvec3( noise1(f1), noise1(f2), noise1(f3)); } template inline detail::_xvec3 noise3(const detail::_xvec3& x) { T f0(0); for(int i = 0; i < 3; ++i) f0 += x[i]; T f1 = f0 * T(1103515245) + T(12345); T f2 = f1 * T(1103515245) + T(12345); T f3 = f2 * T(1103515245) + T(12345); return detail::_xvec3( noise1(f1), noise1(f2), noise1(f3)); } template inline detail::_xvec3 noise3(const detail::_xvec4& x) { T f0(0); for(int i = 0; i < 4; ++i) f0 += x[i]; T f1 = f0 * T(1103515245) + T(12345); T f2 = f1 * T(1103515245) + T(12345); T f3 = f2 * T(1103515245) + T(12345); return detail::_xvec3( noise1(f1), noise1(f2), noise1(f3)); } // noise4 template inline detail::_xvec4 noise4(T x) { T f1 = x * T(1103515245) + T(12345); T f2 = f1 * T(1103515245) + T(12345); T f3 = f2 * T(1103515245) + T(12345); T f4 = f3 * T(1103515245) + T(12345); return detail::_xvec4( noise1(f1), noise1(f2), noise1(f3), noise1(f4)); } template inline detail::_xvec4 noise4(const detail::_xvec2& x) { T f0(0); for(int i = 0; i < 2; ++i) f0 += x[i]; T f1 = f0 * T(1103515245) + T(12345); T f2 = f1 * T(1103515245) + T(12345); T f3 = f2 * T(1103515245) + T(12345); T f4 = f3 * T(1103515245) + T(12345); return detail::_xvec4( noise1(f1), noise1(f2), noise1(f3), noise1(f4)); } template inline detail::_xvec4 noise4(const detail::_xvec3& x) { T f0(0); for(int i = 0; i < 3; ++i) f0 += x[i]; T f1 = f0 * T(1103515245) + T(12345); T f2 = f1 * T(1103515245) + T(12345); T f3 = f2 * T(1103515245) + T(12345); T f4 = f3 * T(1103515245) + T(12345); return detail::_xvec4( noise1(f1), noise1(f2), noise1(f3), noise1(f4)); } template inline detail::_xvec4 noise4(const detail::_xvec4& x) { T f0(0); for(int i = 0; i < 4; ++i) f0 += x[i]; T f1 = f0 * T(1103515245) + T(12345); T f2 = f1 * T(1103515245) + T(12345); T f3 = f2 * T(1103515245) + T(12345); T f4 = f3 * T(1103515245) + T(12345); return detail::_xvec4( noise1(f1), noise1(f2), noise1(f3), noise1(f4)); } } //namespace glm #endif //__func_inl__