Browse Source

Vectorize

Christophe Riccio 14 years ago
parent
commit
e6fded40dc

+ 42 - 2
glm/core/_vectorize.hpp

@@ -26,7 +26,7 @@
 /// @author Christophe Riccio
 /// @author Christophe Riccio
 ///////////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////////
 
 
-#define VECTORIZE_1PARAM(func) \
+#define VECTORIZE_VEC(func) \
     template <typename T> \
     template <typename T> \
     GLM_FUNC_QUALIFIER detail::tvec2<T> func( \
     GLM_FUNC_QUALIFIER detail::tvec2<T> func( \
 		detail::tvec2<T> const & v) \
 		detail::tvec2<T> const & v) \
@@ -57,7 +57,47 @@
             func(v.w)); \
             func(v.w)); \
     }
     }
 
 
-#define VECTORIZE_2PARAMS(func) \
+#define VECTORIZE_VEC_SCA(func) \
+    template <typename T> \
+    GLM_FUNC_QUALIFIER detail::tvec2<T> func \
+	( \
+		detail::tvec2<T> const & x,  \
+		typename detail::tvec2<T>::value_type const & y \
+	) \
+    { \
+        return detail::tvec2<T>( \
+            func(x.x, y), \
+            func(x.y, y)); \
+    } \
+	 \
+    template <typename T> \
+    GLM_FUNC_QUALIFIER detail::tvec3<T> func \
+	( \
+		detail::tvec3<T> const & x,  \
+		typename detail::tvec3<T>::value_type const & y \
+	) \
+    { \
+        return detail::tvec3<T>( \
+            func(x.x, y), \
+            func(x.y, y), \
+            func(x.z, y)); \
+    } \
+	 \
+    template <typename T> \
+    GLM_FUNC_QUALIFIER detail::tvec4<T> func \
+	( \
+		detail::tvec4<T> const & x,  \
+		typename detail::tvec4<T>::value_type const & y \
+	) \
+    { \
+        return detail::tvec4<T>( \
+            func(x.x, y), \
+            func(x.y, y), \
+            func(x.z, y), \
+            func(x.w, y)); \
+    }
+
+#define VECTORIZE_VEC_VEC(func) \
     template <typename T> \
     template <typename T> \
     GLM_FUNC_QUALIFIER detail::tvec2<T> func \
     GLM_FUNC_QUALIFIER detail::tvec2<T> func \
 	( \
 	( \

+ 26 - 250
glm/core/func_common.inl

@@ -70,7 +70,7 @@ namespace detail
 		return detail::Abs_<genFIType, std::numeric_limits<genFIType>::is_signed>::get(x);
 		return detail::Abs_<genFIType, std::numeric_limits<genFIType>::is_signed>::get(x);
     }
     }
 
 
-	VECTORIZE_1PARAM(abs)
+	VECTORIZE_VEC(abs)
 
 
     // sign
     // sign
 	//Try something like based on x >> 31 to get the sign bit
 	//Try something like based on x >> 31 to get the sign bit
@@ -94,7 +94,7 @@ namespace detail
         return result;
         return result;
 	}
 	}
 	
 	
-	VECTORIZE_1PARAM(sign)
+	VECTORIZE_VEC(sign)
 
 
     // floor
     // floor
     template <>
     template <>
@@ -111,7 +111,7 @@ namespace detail
         return ::std::floor(x);
         return ::std::floor(x);
     }
     }
 
 
-	VECTORIZE_1PARAM(floor)
+	VECTORIZE_VEC(floor)
 
 
     // trunc
     // trunc
     template <typename genType>
     template <typename genType>
@@ -121,7 +121,7 @@ namespace detail
         return x < 0 ? -floor(-x) : floor(x);
         return x < 0 ? -floor(-x) : floor(x);
     }
     }
 
 
-	VECTORIZE_1PARAM(trunc)
+	VECTORIZE_VEC(trunc)
 
 
     // round
     // round
     template <typename genType>
     template <typename genType>
@@ -134,7 +134,7 @@ namespace detail
 		return genType(int(x + genType(0.5)));
 		return genType(int(x + genType(0.5)));
     }
     }
 
 
-	VECTORIZE_1PARAM(round)
+	VECTORIZE_VEC(round)
 
 
 /*
 /*
     // roundEven
     // roundEven
@@ -161,7 +161,7 @@ namespace detail
 		return genType(int(x + RoundValue));
 		return genType(int(x + RoundValue));
     }
     }
 	
 	
-	VECTORIZE_1PARAM(roundEven)
+	VECTORIZE_VEC(roundEven)
 
 
     // ceil
     // ceil
     template <typename genType>
     template <typename genType>
@@ -172,7 +172,7 @@ namespace detail
         return ::std::ceil(x);
         return ::std::ceil(x);
     }
     }
 
 
-	VECTORIZE_1PARAM(ceil)
+	VECTORIZE_VEC(ceil)
 
 
     // fract
     // fract
     template <typename genType>
     template <typename genType>
@@ -186,7 +186,7 @@ namespace detail
         return x - ::std::floor(x);
         return x - ::std::floor(x);
     }
     }
 
 
-	VECTORIZE_1PARAM(fract)
+	VECTORIZE_VEC(fract)
 
 
     // mod
     // mod
     template <typename genType>
     template <typename genType>
@@ -201,83 +201,8 @@ namespace detail
         return x - y * floor(x / y);
         return x - y * floor(x / y);
     }
     }
 
 
-    template <typename T>
-    GLM_FUNC_QUALIFIER detail::tvec2<T> mod
-	(
-		detail::tvec2<T> const & x, 
-		typename detail::tvec2<T>::value_type const & y
-	)
-    {
-        return detail::tvec2<T>(
-            mod(x.x, y),
-            mod(x.y, y));
-    }
-
-    template <typename T>
-    GLM_FUNC_QUALIFIER detail::tvec3<T> mod
-	(
-		detail::tvec3<T> const & x, 
-		typename detail::tvec3<T>::value_type const & y
-	)
-    {
-        return detail::tvec3<T>(
-            mod(x.x, y),
-            mod(x.y, y),
-            mod(x.z, y));
-    }
-
-    template <typename T>
-    GLM_FUNC_QUALIFIER detail::tvec4<T> mod
-	(
-		detail::tvec4<T> const & x, 
-		typename detail::tvec4<T>::value_type const & y
-	)
-    {
-        return detail::tvec4<T>(
-            mod(x.x, y),
-            mod(x.y, y),
-            mod(x.z, y),
-            mod(x.w, y));
-    }
-
-    template <typename T>
-    GLM_FUNC_QUALIFIER detail::tvec2<T> mod
-	(
-		detail::tvec2<T> const & x, 
-		detail::tvec2<T> const & y
-	)
-    {
-        return detail::tvec2<T>(
-            mod(x.x, y.x),
-            mod(x.y, y.y));
-    }
-
-    template <typename T>
-    GLM_FUNC_QUALIFIER detail::tvec3<T> mod
-	(
-		detail::tvec3<T> const & x, 
-		detail::tvec3<T> const & y
-	)
-    {
-        return detail::tvec3<T>(
-            mod(x.x, y.x),
-            mod(x.y, y.y),
-            mod(x.z, y.z));
-    }
-
-    template <typename T>
-    GLM_FUNC_QUALIFIER detail::tvec4<T> mod
-	(
-		detail::tvec4<T> const & x, 
-		detail::tvec4<T> const & y
-	)
-    {
-        return detail::tvec4<T>(
-            mod(x.x, y.x),
-            mod(x.y, y.y),
-            mod(x.z, y.z),
-            mod(x.w, y.w));
-    }
+	VECTORIZE_VEC_SCA(mod)
+	VECTORIZE_VEC_VEC(mod)
 
 
     // modf
     // modf
     template <typename genType>
     template <typename genType>
@@ -298,39 +223,39 @@ namespace detail
     GLM_FUNC_QUALIFIER detail::tvec2<valType> modf
     GLM_FUNC_QUALIFIER detail::tvec2<valType> modf
 	(
 	(
 		detail::tvec2<valType> const & x, 
 		detail::tvec2<valType> const & x, 
-		detail::tvec2<valType> const & y
+		detail::tvec2<valType> & i
 	)
 	)
     {
     {
         return detail::tvec2<valType>(
         return detail::tvec2<valType>(
-            modf(x.x, y.x),
-            modf(x.y, y.y));
+            modf(x.x, i.x),
+            modf(x.y, i.y));
     }
     }
 
 
     template <typename valType>
     template <typename valType>
     GLM_FUNC_QUALIFIER detail::tvec3<valType> modf
     GLM_FUNC_QUALIFIER detail::tvec3<valType> modf
 	(
 	(
 		detail::tvec3<valType> const & x, 
 		detail::tvec3<valType> const & x, 
-		detail::tvec3<valType> const & y
+		detail::tvec3<valType> & i
 	)
 	)
     {
     {
         return detail::tvec3<valType>(
         return detail::tvec3<valType>(
-            modf(x.x, y.x),
-            modf(x.y, y.y),
-            modf(x.z, y.z));
+            modf(x.x, i.x),
+            modf(x.y, i.y),
+            modf(x.z, i.z));
     }
     }
 
 
     template <typename valType>
     template <typename valType>
     GLM_FUNC_QUALIFIER detail::tvec4<valType> modf
     GLM_FUNC_QUALIFIER detail::tvec4<valType> modf
 	(
 	(
 		detail::tvec4<valType> const & x, 
 		detail::tvec4<valType> const & x, 
-		detail::tvec4<valType> const & y
+		detail::tvec4<valType> & i
 	)
 	)
     {
     {
         return detail::tvec4<valType>(
         return detail::tvec4<valType>(
-            modf(x.x, y.x),
-            modf(x.y, y.y),
-            modf(x.z, y.z),
-            modf(x.w, y.w));
+            modf(x.x, i.x),
+            modf(x.y, i.y),
+            modf(x.z, i.z),
+            modf(x.w, i.w));
     }
     }
 
 
 	//// Only valid if (INT_MIN <= x-y <= INT_MAX)
 	//// Only valid if (INT_MIN <= x-y <= INT_MAX)
@@ -357,83 +282,8 @@ namespace detail
         return x < y ? x : y;
         return x < y ? x : y;
     }
     }
 
 
-    template <typename T>
-    GLM_FUNC_QUALIFIER detail::tvec2<T> min
-	(
-		detail::tvec2<T> const & x, 
-		typename detail::tvec2<T>::value_type const & y
-	)
-    {
-        return detail::tvec2<T>(
-            min(x.x, y),
-            min(x.y, y));
-    }
-
-    template <typename T>
-    GLM_FUNC_QUALIFIER detail::tvec3<T> min
-	(
-		detail::tvec3<T> const & x, 
-		typename detail::tvec3<T>::value_type const & y
-	)
-    {
-        return detail::tvec3<T>(
-            min(x.x, y),
-            min(x.y, y),
-            min(x.z, y));
-    }
-
-    template <typename T>
-    GLM_FUNC_QUALIFIER detail::tvec4<T> min
-	(
-		detail::tvec4<T> const & x, 
-		typename detail::tvec4<T>::value_type const & y
-	)
-    {
-        return detail::tvec4<T>(
-            min(x.x, y),
-            min(x.y, y),
-            min(x.z, y),
-            min(x.w, y));
-    }
-
-    template <typename T>
-    GLM_FUNC_QUALIFIER detail::tvec2<T> min
-	(
-		detail::tvec2<T> const & x, 
-		detail::tvec2<T> const & y
-	)
-    {
-        return detail::tvec2<T>(
-            min(x.x, y.x),
-            min(x.y, y.y));
-    }
-
-    template <typename T>
-    GLM_FUNC_QUALIFIER detail::tvec3<T> min
-	(
-		detail::tvec3<T> const & x, 
-		detail::tvec3<T> const & y
-	)
-    {
-        return detail::tvec3<T>(
-            min(x.x, y.x),
-            min(x.y, y.y),
-            min(x.z, y.z));
-    }
-
-    template <typename T>
-    GLM_FUNC_QUALIFIER detail::tvec4<T> min
-	(
-		detail::tvec4<T> const & x, 
-		detail::tvec4<T> const & y
-	)
-    {
-        return detail::tvec4<T>(
-            min(x.x, y.x),
-            min(x.y, y.y),
-            min(x.z, y.z),
-            min(x.w, y.w));
-    }
+	VECTORIZE_VEC_SCA(min)
+	VECTORIZE_VEC_VEC(min)
 
 
     // max
     // max
     template <typename genType>
     template <typename genType>
@@ -451,82 +301,8 @@ namespace detail
 		return x > y ? x : y;
 		return x > y ? x : y;
     }
     }
 
 
-    template <typename T>
-    GLM_FUNC_QUALIFIER detail::tvec2<T> max
-	(
-		detail::tvec2<T> const & x, 
-		typename detail::tvec2<T>::value_type y
-	)
-    {
-        return detail::tvec2<T>(
-            max(x.x, y),
-            max(x.y, y));
-    }
-
-    template <typename T>
-    GLM_FUNC_QUALIFIER detail::tvec3<T> max
-	(
-		detail::tvec3<T> const & x, 
-		typename detail::tvec3<T>::value_type y
-	)
-    {
-        return detail::tvec3<T>(
-            max(x.x, y),
-            max(x.y, y),
-            max(x.z, y));
-    }
-
-    template <typename T>
-    GLM_FUNC_QUALIFIER detail::tvec4<T> max
-	(
-		detail::tvec4<T> const & x, 
-		typename detail::tvec4<T>::value_type y
-	)
-    {
-        return detail::tvec4<T>(
-            max(x.x, y),
-            max(x.y, y),
-            max(x.z, y),
-            max(x.w, y));
-    }
-
-    template <typename T>
-    GLM_FUNC_QUALIFIER detail::tvec2<T> max
-	(
-		detail::tvec2<T> const & x, 
-		detail::tvec2<T> const & y
-	)
-    {
-        return detail::tvec2<T>(
-            max(x.x, y.x),
-            max(x.y, y.y));
-    }
-
-    template <typename T>
-    GLM_FUNC_QUALIFIER detail::tvec3<T> max
-	(
-		detail::tvec3<T> const & x, 
-		detail::tvec3<T> const & y
-	)
-    {
-        return detail::tvec3<T>(
-            max(x.x, y.x),
-            max(x.y, y.y),
-            max(x.z, y.z));
-    }
-
-    template <typename T>
-    GLM_FUNC_QUALIFIER detail::tvec4<T> max
-	(
-		detail::tvec4<T> const & x, 
-		detail::tvec4<T> const & y)
-    {
-        return detail::tvec4<T>(
-            max(x.x, y.x),
-            max(x.y, y.y),
-            max(x.z, y.z),
-            max(x.w, y.w));
-    }
+	VECTORIZE_VEC_SCA(max)
+	VECTORIZE_VEC_VEC(max)
 
 
     // clamp
     // clamp
     template <typename valType>
     template <typename valType>

+ 8 - 248
glm/core/func_exponential.inl

@@ -41,44 +41,7 @@ namespace glm
         return ::std::pow(x, y);
         return ::std::pow(x, y);
     }
     }
 
 
-    template <typename T>
-    GLM_FUNC_QUALIFIER detail::tvec2<T> pow
-	(
-		detail::tvec2<T> const & x, 
-		detail::tvec2<T> const & y
-	)
-    {
-        return detail::tvec2<T>(
-            pow(x.x, y.x),
-            pow(x.y, y.y));
-    }
-
-    template <typename T>
-    GLM_FUNC_QUALIFIER detail::tvec3<T> pow
-	(
-		detail::tvec3<T> const & x, 
-		detail::tvec3<T> const & y
-	)
-    {
-        return detail::tvec3<T>(
-            pow(x.x, y.x),
-            pow(x.y, y.y),
-            pow(x.z, y.z));
-    }
-
-    template <typename T>
-    GLM_FUNC_QUALIFIER detail::tvec4<T> pow
-	(
-		detail::tvec4<T> const & x, 
-		detail::tvec4<T> const & y
-	)
-    {
-        return detail::tvec4<T>(
-            pow(x.x, y.x),
-            pow(x.y, y.y),
-            pow(x.z, y.z),
-            pow(x.w, y.w));
-    }
+	VECTORIZE_VEC_VEC(pow)
 
 
     // exp
     // exp
     template <typename genType>
     template <typename genType>
@@ -92,41 +55,7 @@ namespace glm
         return ::std::exp(x);
         return ::std::exp(x);
     }
     }
 
 
-    template <typename T>
-    GLM_FUNC_QUALIFIER detail::tvec2<T> exp
-	(
-		detail::tvec2<T> const & x
-	)
-    {
-        return detail::tvec2<T>(
-            exp(x.x),
-            exp(x.y));
-    }
-
-    template <typename T>
-    GLM_FUNC_QUALIFIER detail::tvec3<T> exp
-	(
-		detail::tvec3<T> const & x
-	)
-    {
-        return detail::tvec3<T>(
-            exp(x.x),
-            exp(x.y),
-            exp(x.z));
-    }
-
-    template <typename T>
-    GLM_FUNC_QUALIFIER detail::tvec4<T> exp
-	(
-		detail::tvec4<T> const & x
-	)
-    {
-        return detail::tvec4<T>(
-            exp(x.x),
-            exp(x.y),
-            exp(x.z),
-            exp(x.w));
-    }
+	VECTORIZE_VEC(exp)
 
 
     // log
     // log
     template <typename genType>
     template <typename genType>
@@ -140,41 +69,7 @@ namespace glm
         return ::std::log(x);
         return ::std::log(x);
     }
     }
 
 
-    template <typename T>
-    GLM_FUNC_QUALIFIER detail::tvec2<T> log
-	(
-		detail::tvec2<T> const & x
-	)
-    {
-        return detail::tvec2<T>(
-            log(x.x),
-            log(x.y));
-    }
-
-    template <typename T>
-    GLM_FUNC_QUALIFIER detail::tvec3<T> log
-	(
-		detail::tvec3<T> const & x
-	)
-    {
-        return detail::tvec3<T>(
-            log(x.x),
-            log(x.y),
-            log(x.z));
-    }
-
-    template <typename T>
-    GLM_FUNC_QUALIFIER detail::tvec4<T> log
-	(
-		detail::tvec4<T> const & x
-	)
-    {
-        return detail::tvec4<T>(
-            log(x.x),
-            log(x.y),
-            log(x.z),
-            log(x.w));
-    }
+	VECTORIZE_VEC(log)
 
 
     //exp2, ln2 = 0.69314718055994530941723212145818f
     //exp2, ln2 = 0.69314718055994530941723212145818f
     template <typename genType>
     template <typename genType>
@@ -188,41 +83,7 @@ namespace glm
         return ::std::exp(genType(0.69314718055994530941723212145818) * x);
         return ::std::exp(genType(0.69314718055994530941723212145818) * x);
     }
     }
 
 
-    template <typename T>
-    GLM_FUNC_QUALIFIER detail::tvec2<T> exp2
-	(
-		detail::tvec2<T> const & x
-	)
-    {
-        return detail::tvec2<T>(
-            exp2(x.x),
-            exp2(x.y));
-    }
-
-    template <typename T>
-    GLM_FUNC_QUALIFIER detail::tvec3<T> exp2
-	(
-		detail::tvec3<T> const & x
-	)
-    {
-        return detail::tvec3<T>(
-            exp2(x.x),
-            exp2(x.y),
-            exp2(x.z));
-    }
-
-    template <typename T>
-    GLM_FUNC_QUALIFIER detail::tvec4<T> exp2
-	(
-		detail::tvec4<T> const & x
-	)
-    {
-        return detail::tvec4<T>(
-            exp2(x.x),
-            exp2(x.y),
-            exp2(x.z),
-            exp2(x.w));
-    }
+	VECTORIZE_VEC(exp2)
 
 
 namespace detail
 namespace detail
 {
 {
@@ -255,44 +116,11 @@ namespace detail
 		genType const & x
 		genType const & x
 	)
 	)
     {
     {
+		assert(x > genType(0)); // log2 is only defined on the range (0, inf]
 		return detail::compute_log2<detail::float_or_int_trait<genType>::ID>()(x);
 		return detail::compute_log2<detail::float_or_int_trait<genType>::ID>()(x);
     }
     }
 
 
-    template <typename T>
-    GLM_FUNC_QUALIFIER detail::tvec2<T> log2
-	(
-		detail::tvec2<T> const & x
-	)
-    {
-        return detail::tvec2<T>(
-            log2(x.x),
-            log2(x.y));
-    }
-
-    template <typename T>
-    GLM_FUNC_QUALIFIER detail::tvec3<T> log2
-	(
-		detail::tvec3<T> const & x
-	)
-    {
-        return detail::tvec3<T>(
-            log2(x.x),
-            log2(x.y),
-            log2(x.z));
-    }
-
-    template <typename T>
-    GLM_FUNC_QUALIFIER detail::tvec4<T> log2
-	(
-		detail::tvec4<T> const & x
-	)
-    {
-        return detail::tvec4<T>(
-            log2(x.x),
-            log2(x.y),
-            log2(x.z),
-            log2(x.w));
-    }
+	VECTORIZE_VEC(log2)
 
 
     // sqrt
     // sqrt
     template <typename genType>
     template <typename genType>
@@ -306,41 +134,7 @@ namespace detail
         return genType(::std::sqrt(x));
         return genType(::std::sqrt(x));
     }
     }
 
 
-    template <typename T>
-    GLM_FUNC_QUALIFIER detail::tvec2<T> sqrt
-	(
-		detail::tvec2<T> const & x
-	)
-    {
-        return detail::tvec2<T>(
-            glm::sqrt(x.x),
-            glm::sqrt(x.y));
-    }
-
-    template <typename T>
-    GLM_FUNC_QUALIFIER detail::tvec3<T> sqrt
-	(
-		detail::tvec3<T> const & x
-	)
-    {
-        return detail::tvec3<T>(
-            glm::sqrt(x.x),
-            glm::sqrt(x.y),
-            glm::sqrt(x.z));
-    }
-
-    template <typename T>
-    GLM_FUNC_QUALIFIER detail::tvec4<T> sqrt
-	(
-		detail::tvec4<T> const & x
-	)
-    {
-        return detail::tvec4<T>(
-            glm::sqrt(x.x),
-            glm::sqrt(x.y),
-            glm::sqrt(x.z),
-            glm::sqrt(x.w));
-    }
+	VECTORIZE_VEC(sqrt)
 
 
     template <typename genType>
     template <typename genType>
     GLM_FUNC_QUALIFIER genType inversesqrt
     GLM_FUNC_QUALIFIER genType inversesqrt
@@ -353,40 +147,6 @@ namespace detail
         return genType(1) / ::std::sqrt(x);
         return genType(1) / ::std::sqrt(x);
     }
     }
 
 
-    template <typename T>
-    GLM_FUNC_QUALIFIER detail::tvec2<T> inversesqrt
-	(
-		detail::tvec2<T> const & x
-	)
-    {
-        return detail::tvec2<T>(
-            inversesqrt(x.x),
-            inversesqrt(x.y));
-    }
-
-    template <typename T>
-    GLM_FUNC_QUALIFIER detail::tvec3<T> inversesqrt
-	(
-		detail::tvec3<T> const & x
-	)
-    {
-        return detail::tvec3<T>(
-            inversesqrt(x.x),
-            inversesqrt(x.y),
-            inversesqrt(x.z));
-    }
-
-    template <typename T>
-    GLM_FUNC_QUALIFIER detail::tvec4<T> inversesqrt
-	(
-		detail::tvec4<T> const & x
-	)
-    {
-        return detail::tvec4<T>(
-            inversesqrt(x.x),
-            inversesqrt(x.y),
-            inversesqrt(x.z),
-            inversesqrt(x.w));
-    }
+	VECTORIZE_VEC(inversesqrt)
 
 
 }//namespace glm
 }//namespace glm

+ 1 - 35
glm/core/func_integer.inl

@@ -415,41 +415,7 @@ namespace glm
 		return Out;
 		return Out;
 	}	
 	}	
 
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER detail::tvec2<T> bitfieldReverse
-	(
-		detail::tvec2<T> const & value
-	)
-	{
-		return detail::tvec2<T>(
-			bitfieldReverse(value[0]),
-			bitfieldReverse(value[1]));
-	}
-
-	template <typename T>
-	GLM_FUNC_QUALIFIER detail::tvec3<T> bitfieldReverse
-	(
-		detail::tvec3<T> const & value
-	)
-	{
-		return detail::tvec3<T>(
-			bitfieldReverse(value[0]),
-			bitfieldReverse(value[1]),
-			bitfieldReverse(value[2]));
-	}
-
-	template <typename T>
-	GLM_FUNC_QUALIFIER detail::tvec4<T> bitfieldReverse
-	(
-		detail::tvec4<T> const & value
-	)
-	{
-		return detail::tvec4<T>(
-			bitfieldReverse(value[0]),
-			bitfieldReverse(value[1]),
-			bitfieldReverse(value[2]),
-			bitfieldReverse(value[3]));
-	}
+	VECTORIZE_VEC(bitfieldReverse)
 
 
 	// bitCount
 	// bitCount
 	template <typename genIUType>
 	template <typename genIUType>

+ 108 - 109
glm/core/func_packing.inl

@@ -26,134 +26,133 @@
 /// @author Christophe Riccio
 /// @author Christophe Riccio
 ///////////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////////
 
 
-namespace glm{
-
-GLM_FUNC_QUALIFIER detail::uint32 packUnorm2x16(detail::tvec2<detail::float32> const & v)
+namespace glm
 {
 {
-	detail::uint16 A(detail::uint16(round(clamp(v.x, 0.0f, 1.0f) * 65535.0f)));
-	detail::uint16 B(detail::uint16(round(clamp(v.y, 0.0f, 1.0f) * 65535.0f)));
-	return detail::uint32((B << 16) | A);
-}
+	GLM_FUNC_QUALIFIER detail::uint32 packUnorm2x16(detail::tvec2<detail::float32> const & v)
+	{
+		detail::uint16 A(detail::uint16(round(clamp(v.x, 0.0f, 1.0f) * 65535.0f)));
+		detail::uint16 B(detail::uint16(round(clamp(v.y, 0.0f, 1.0f) * 65535.0f)));
+		return detail::uint32((B << 16) | A);
+	}
 
 
-GLM_FUNC_QUALIFIER detail::tvec2<detail::float32> unpackUnorm2x16(detail::uint32 const & p)
-{
-	detail::uint32 Mask16((1 << 16) - 1);
-	detail::uint32 A((p >>  0) & Mask16);
-	detail::uint32 B((p >> 16) & Mask16);
-	return detail::tvec2<detail::float32>(
-		A * 1.0f / 65535.0f, 
-		B * 1.0f / 65535.0f);
-}
+	GLM_FUNC_QUALIFIER detail::tvec2<detail::float32> unpackUnorm2x16(detail::uint32 const & p)
+	{
+		detail::uint32 Mask16((1 << 16) - 1);
+		detail::uint32 A((p >>  0) & Mask16);
+		detail::uint32 B((p >> 16) & Mask16);
+		return detail::tvec2<detail::float32>(
+			A * 1.0f / 65535.0f, 
+			B * 1.0f / 65535.0f);
+	}
 	
 	
-GLM_FUNC_QUALIFIER detail::uint32 packSnorm2x16(detail::tvec2<detail::float32> const & v)
-{
-	union iu
+	GLM_FUNC_QUALIFIER detail::uint32 packSnorm2x16(detail::tvec2<detail::float32> const & v)
 	{
 	{
-		detail::int16 i;
-		detail::uint16 u;
-	} A, B;
+		union iu
+		{
+			detail::int16 i;
+			detail::uint16 u;
+		} A, B;
 		
 		
-	detail::tvec2<detail::float32> Unpack = clamp(v ,-1.0f, 1.0f) * 32767.0f;
-	A.i = detail::int16(round(Unpack.x));
-	B.i = detail::int16(round(Unpack.y));
-	detail::uint32 Pack = (detail::uint32(B.u) << 16) | (detail::uint32(A.u) << 0);
-	return Pack;
-}
+		detail::tvec2<detail::float32> Unpack = clamp(v ,-1.0f, 1.0f) * 32767.0f;
+		A.i = detail::int16(round(Unpack.x));
+		B.i = detail::int16(round(Unpack.y));
+		detail::uint32 Pack = (detail::uint32(B.u) << 16) | (detail::uint32(A.u) << 0);
+		return Pack;
+	}
 
 
-GLM_FUNC_QUALIFIER detail::tvec2<detail::float32> unpackSnorm2x16(detail::uint32 const & p)
-{
-	union iu
+	GLM_FUNC_QUALIFIER detail::tvec2<detail::float32> unpackSnorm2x16(detail::uint32 const & p)
 	{
 	{
-		detail::int16 i;
-		detail::uint16 u;
-	} A, B;
+		union iu
+		{
+			detail::int16 i;
+			detail::uint16 u;
+		} A, B;
 		
 		
-	detail::uint32 Mask16((1 << 16) - 1);
-	A.u = detail::uint16((p >>  0) & Mask16);
-	B.u = detail::uint16((p >> 16) & Mask16);
-	detail::tvec2<detail::float32> Pack(A.i, B.i);
+		detail::uint32 Mask16((1 << 16) - 1);
+		A.u = detail::uint16((p >>  0) & Mask16);
+		B.u = detail::uint16((p >> 16) & Mask16);
+		detail::tvec2<detail::float32> Pack(A.i, B.i);
 		
 		
-	return clamp(Pack * 1.0f / 32767.0f, -1.0f, 1.0f);
-}
+		return clamp(Pack * 1.0f / 32767.0f, -1.0f, 1.0f);
+	}
 
 
-GLM_FUNC_QUALIFIER detail::uint32 packUnorm4x8(detail::tvec4<detail::float32> const & v)
-{
-	detail::uint8 A((detail::uint8)round(clamp(v.x, 0.0f, 1.0f) * 255.0f));
-	detail::uint8 B((detail::uint8)round(clamp(v.y, 0.0f, 1.0f) * 255.0f));
-	detail::uint8 C((detail::uint8)round(clamp(v.z, 0.0f, 1.0f) * 255.0f));
-	detail::uint8 D((detail::uint8)round(clamp(v.w, 0.0f, 1.0f) * 255.0f));
-	return detail::uint32((D << 24) | (C << 16) | (B << 8) | A);
-}
+	GLM_FUNC_QUALIFIER detail::uint32 packUnorm4x8(detail::tvec4<detail::float32> const & v)
+	{
+		detail::uint8 A((detail::uint8)round(clamp(v.x, 0.0f, 1.0f) * 255.0f));
+		detail::uint8 B((detail::uint8)round(clamp(v.y, 0.0f, 1.0f) * 255.0f));
+		detail::uint8 C((detail::uint8)round(clamp(v.z, 0.0f, 1.0f) * 255.0f));
+		detail::uint8 D((detail::uint8)round(clamp(v.w, 0.0f, 1.0f) * 255.0f));
+		return detail::uint32((D << 24) | (C << 16) | (B << 8) | A);
+	}
 
 
-GLM_FUNC_QUALIFIER detail::tvec4<detail::float32> unpackUnorm4x8(detail::uint32 const & p)
-{	
-	detail::uint32 Mask8((1 << 8) - 1);
-	detail::uint32 A((p >>  0) & Mask8);
-	detail::uint32 B((p >>  8) & Mask8);
-	detail::uint32 C((p >> 16) & Mask8);
-	detail::uint32 D((p >> 24) & Mask8);
-	return detail::tvec4<detail::float32>(
-		A * 1.0f / 255.0f, 
-		B * 1.0f / 255.0f, 
-		C * 1.0f / 255.0f, 
-		D * 1.0f / 255.0f);
-}
+	GLM_FUNC_QUALIFIER detail::tvec4<detail::float32> unpackUnorm4x8(detail::uint32 const & p)
+	{	
+		detail::uint32 Mask8((1 << 8) - 1);
+		detail::uint32 A((p >>  0) & Mask8);
+		detail::uint32 B((p >>  8) & Mask8);
+		detail::uint32 C((p >> 16) & Mask8);
+		detail::uint32 D((p >> 24) & Mask8);
+		return detail::tvec4<detail::float32>(
+			A * 1.0f / 255.0f, 
+			B * 1.0f / 255.0f, 
+			C * 1.0f / 255.0f, 
+			D * 1.0f / 255.0f);
+	}
 	
 	
-GLM_FUNC_QUALIFIER detail::uint32 packSnorm4x8(detail::tvec4<detail::float32> const & v)
-{
-	union iu
+	GLM_FUNC_QUALIFIER detail::uint32 packSnorm4x8(detail::tvec4<detail::float32> const & v)
 	{
 	{
-		detail::int8 i;
-		detail::uint8 u;
-	} A, B, C, D;
+		union iu
+		{
+			detail::int8 i;
+			detail::uint8 u;
+		} A, B, C, D;
 	
 	
-	detail::tvec4<detail::float32> Unpack = clamp(v ,-1.0f, 1.0f) * 127.0f;
-	A.i = detail::int8(round(Unpack.x));
-	B.i = detail::int8(round(Unpack.y));
-	C.i = detail::int8(round(Unpack.z));
-	D.i = detail::int8(round(Unpack.w));
-	detail::uint32 Pack = (detail::uint32(D.u) << 24) | (detail::uint32(C.u) << 16) | (detail::uint32(B.u) << 8) | (detail::uint32(A.u) << 0);
-	return Pack;
-}
+		detail::tvec4<detail::float32> Unpack = clamp(v ,-1.0f, 1.0f) * 127.0f;
+		A.i = detail::int8(round(Unpack.x));
+		B.i = detail::int8(round(Unpack.y));
+		C.i = detail::int8(round(Unpack.z));
+		D.i = detail::int8(round(Unpack.w));
+		detail::uint32 Pack = (detail::uint32(D.u) << 24) | (detail::uint32(C.u) << 16) | (detail::uint32(B.u) << 8) | (detail::uint32(A.u) << 0);
+		return Pack;
+	}
 	
 	
-GLM_FUNC_QUALIFIER detail::tvec4<detail::float32> unpackSnorm4x8(detail::uint32 const & p)
-{	
-	union iu
-	{
-		detail::int8 i;
-		detail::uint8 u;
-	} A, B, C, D;
+	GLM_FUNC_QUALIFIER detail::tvec4<detail::float32> unpackSnorm4x8(detail::uint32 const & p)
+	{	
+		union iu
+		{
+			detail::int8 i;
+			detail::uint8 u;
+		} A, B, C, D;
 	
 	
-	detail::uint32 Mask8((1 << 8) - 1);
-	A.u = detail::uint8((p >>  0) & Mask8);
-	B.u = detail::uint8((p >>  8) & Mask8);
-	C.u = detail::uint8((p >> 16) & Mask8);
-	D.u = detail::uint8((p >> 24) & Mask8);
-	detail::tvec4<detail::float32> Pack(A.i, B.i, C.i, D.i);
+		detail::uint32 Mask8((1 << 8) - 1);
+		A.u = detail::uint8((p >>  0) & Mask8);
+		B.u = detail::uint8((p >>  8) & Mask8);
+		C.u = detail::uint8((p >> 16) & Mask8);
+		D.u = detail::uint8((p >> 24) & Mask8);
+		detail::tvec4<detail::float32> Pack(A.i, B.i, C.i, D.i);
 	
 	
-	return clamp(Pack * 1.0f / 127.0f, -1.0f, 1.0f);
-}
+		return clamp(Pack * 1.0f / 127.0f, -1.0f, 1.0f);
+	}
 
 
-GLM_FUNC_QUALIFIER double packDouble2x32(detail::tvec2<detail::uint32> const & v)
-{
-	return *(double*)&v;
-}
-
-GLM_FUNC_QUALIFIER detail::tvec2<uint> unpackDouble2x32(double const & v)
-{
-	return *(detail::tvec2<uint>*)&v;
-}
+	GLM_FUNC_QUALIFIER double packDouble2x32(detail::tvec2<detail::uint32> const & v)
+	{
+		return *(double*)&v;
+	}
 
 
-GLM_FUNC_QUALIFIER uint packHalf2x16(detail::tvec2<float> const & v)
-{
-	detail::tvec2<detail::hdata> Pack(detail::toFloat16(v.x), detail::toFloat16(v.y));
-	return *(uint*)&Pack;
-}
+	GLM_FUNC_QUALIFIER detail::tvec2<uint> unpackDouble2x32(double const & v)
+	{
+		return *(detail::tvec2<uint>*)&v;
+	}
 
 
-GLM_FUNC_QUALIFIER vec2 unpackHalf2x16(uint const & v)
-{
-	detail::tvec2<detail::hdata> Unpack = *(detail::tvec2<detail::hdata>*)&v;
-	return vec2(detail::toFloat32(Unpack.x), detail::toFloat32(Unpack.y));
-}
+	GLM_FUNC_QUALIFIER uint packHalf2x16(detail::tvec2<float> const & v)
+	{
+		detail::tvec2<detail::hdata> Pack(detail::toFloat16(v.x), detail::toFloat16(v.y));
+		return *(uint*)&Pack;
+	}
 
 
+	GLM_FUNC_QUALIFIER vec2 unpackHalf2x16(uint const & v)
+	{
+		detail::tvec2<detail::hdata> Unpack = *(detail::tvec2<detail::hdata>*)&v;
+		return vec2(detail::toFloat32(Unpack.x), detail::toFloat32(Unpack.y));
+	}
 }//namespace glm
 }//namespace glm

+ 725 - 726
glm/core/func_trigonometric.inl

@@ -26,732 +26,731 @@
 /// @author Christophe Riccio
 /// @author Christophe Riccio
 ///////////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////////
 
 
-namespace glm{
-
-// radians
-template <typename genType>
-GLM_FUNC_QUALIFIER genType radians
-(
-	genType const & degrees
-)
-{
-	GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'radians' only accept floating-point input");
-
-    const genType pi = genType(3.1415926535897932384626433832795);
-    return degrees * (pi / genType(180));
-}
-
-template <typename T>
-GLM_FUNC_QUALIFIER detail::tvec2<T> radians
-(
-	detail::tvec2<T> const & degrees
-)
-{
-    return detail::tvec2<T>(
-        radians(degrees.x),
-        radians(degrees.y));
-}
-
-template <typename T>
-GLM_FUNC_QUALIFIER detail::tvec3<T> radians
-(
-	detail::tvec3<T> const & degrees
-)
-{
-    return detail::tvec3<T>(
-        radians(degrees.x),
-        radians(degrees.y),
-        radians(degrees.z));
-}
-
-template <typename T>
-GLM_FUNC_QUALIFIER detail::tvec4<T> radians
-(
-	detail::tvec4<T> const & degrees
-)
-{
-    return detail::tvec4<T>(
-        radians(degrees.x),
-        radians(degrees.y),
-        radians(degrees.z),
-        radians(degrees.w));
-}
-
-// degrees
-template <typename genType>
-GLM_FUNC_QUALIFIER genType degrees
-(
-	genType const & radians
-)
-{
-	GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'degrees' only accept floating-point input");
-
-    const genType pi = genType(3.1415926535897932384626433832795);
-    return radians * (genType(180) / pi);
-}
-
-template <typename T>
-GLM_FUNC_QUALIFIER detail::tvec2<T> degrees
-(
-	detail::tvec2<T> const & radians
-)
-{
-    return detail::tvec2<T>(
-        degrees(radians.x),
-        degrees(radians.y));
-}
-
-template <typename T>
-GLM_FUNC_QUALIFIER detail::tvec3<T> degrees
-(	
-	detail::tvec3<T> const & radians
-)
-{
-    return detail::tvec3<T>(
-        degrees(radians.x),
-        degrees(radians.y),
-        degrees(radians.z));
-}
-
-template <typename T>
-GLM_FUNC_QUALIFIER detail::tvec4<T> degrees
-(
-	detail::tvec4<T> const & radians
-)
-{
-    return detail::tvec4<T>(
-        degrees(radians.x),
-        degrees(radians.y),
-        degrees(radians.z),
-        degrees(radians.w));
-}
-
-// sin
-template <typename genType>
-GLM_FUNC_QUALIFIER genType sin
-(
-	genType const & angle
-)
-{
-	GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'sin' only accept floating-point input");
-
-	return ::std::sin(angle);
-}
-
-template <typename T>
-GLM_FUNC_QUALIFIER detail::tvec2<T> sin
-(
-	detail::tvec2<T> const & angle
-)
-{
-    return detail::tvec2<T>(
-        sin(angle.x),
-        sin(angle.y));
-}
-
-template <typename T>
-GLM_FUNC_QUALIFIER detail::tvec3<T> sin
-(
-	detail::tvec3<T> const & angle
-)
-{
-    return detail::tvec3<T>(
-        sin(angle.x),
-        sin(angle.y),
-        sin(angle.z));
-}
-
-template <typename T>
-GLM_FUNC_QUALIFIER detail::tvec4<T> sin
-(
-	detail::tvec4<T> const & angle
-)
-{
-    return detail::tvec4<T>(
-        sin(angle.x),
-        sin(angle.y),
-        sin(angle.z),
-        sin(angle.w));
-}
-
-// cos
-template <typename genType>
-GLM_FUNC_QUALIFIER genType cos(genType const & angle)
-{
-	GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'cos' only accept floating-point input");
-
-    return ::std::cos(angle);
-}
-
-template <typename T>
-GLM_FUNC_QUALIFIER detail::tvec2<T> cos
-(
-	detail::tvec2<T> const & angle
-)
-{
-    return detail::tvec2<T>(
-        cos(angle.x),
-        cos(angle.y));
-}
-
-template <typename T>
-GLM_FUNC_QUALIFIER detail::tvec3<T> cos
-(
-	detail::tvec3<T> const & angle
-)
-{
-    return detail::tvec3<T>(
-        cos(angle.x),
-        cos(angle.y),
-        cos(angle.z));
-}
-
-template <typename T>
-GLM_FUNC_QUALIFIER detail::tvec4<T> cos
-(	
-	detail::tvec4<T> const & angle
-)
-{
-    return detail::tvec4<T>(
-        cos(angle.x),
-        cos(angle.y),
-        cos(angle.z),
-        cos(angle.w));
-}
-
-// tan
-template <typename genType>
-GLM_FUNC_QUALIFIER genType tan
-(
-	genType const & angle
-)
-{
-	GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'tan' only accept floating-point input");
-
-    return ::std::tan(angle);
-}
-
-template <typename T>
-GLM_FUNC_QUALIFIER detail::tvec2<T> tan
-(
-	detail::tvec2<T> const & angle
-)
-{
-    return detail::tvec2<T>(
-        tan(angle.x),
-        tan(angle.y));
-}
-
-template <typename T>
-GLM_FUNC_QUALIFIER detail::tvec3<T> tan
-(
-	detail::tvec3<T> const & angle
-)
-{
-    return detail::tvec3<T>(
-        tan(angle.x),
-        tan(angle.y),
-        tan(angle.z));
-}
-
-template <typename T>
-GLM_FUNC_QUALIFIER detail::tvec4<T> tan
-(
-	detail::tvec4<T> const & angle
-)
-{
-    return detail::tvec4<T>(
-        tan(angle.x),
-        tan(angle.y),
-        tan(angle.z),
-        tan(angle.w));
-}
-
-// asin
-template <typename genType>
-GLM_FUNC_QUALIFIER genType asin
-(
-	genType const & x
-)
-{
-	GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'asin' only accept floating-point input");
-
-    return ::std::asin(x);
-}
-
-template <typename T>
-GLM_FUNC_QUALIFIER detail::tvec2<T> asin
-(
-	detail::tvec2<T> const & x
-)
-{
-    return detail::tvec2<T>(
-        asin(x.x),
-        asin(x.y));
-}
-
-template <typename T>
-GLM_FUNC_QUALIFIER detail::tvec3<T> asin
-(
-	detail::tvec3<T> const & x
-)
-{
-    return detail::tvec3<T>(
-        asin(x.x),
-        asin(x.y),
-        asin(x.z));
-}
-
-template <typename T>
-GLM_FUNC_QUALIFIER detail::tvec4<T> asin
-(
-	detail::tvec4<T> const & x
-)
-{
-    return detail::tvec4<T>(
-        asin(x.x),
-        asin(x.y),
-        asin(x.z),
-        asin(x.w));
-}
-
-// acos
-template <typename genType>
-GLM_FUNC_QUALIFIER genType acos
-(
-	genType const & x
-)
-{
-	GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'acos' only accept floating-point input");
-
-    return ::std::acos(x);
-}
-
-template <typename T>
-GLM_FUNC_QUALIFIER detail::tvec2<T> acos
-(
-	detail::tvec2<T> const & x
-)
-{
-    return detail::tvec2<T>(
-        acos(x.x),
-        acos(x.y));
-}
-
-template <typename T>
-GLM_FUNC_QUALIFIER detail::tvec3<T> acos
-(
-	detail::tvec3<T> const & x
-)
-{
-    return detail::tvec3<T>(
-        acos(x.x),
-        acos(x.y),
-        acos(x.z));
-}
-
-template <typename T>
-GLM_FUNC_QUALIFIER detail::tvec4<T> acos
-(
-	detail::tvec4<T> const & x
-)
-{
-    return detail::tvec4<T>(
-        acos(x.x),
-        acos(x.y),
-        acos(x.z),
-        acos(x.w));
-}
-
-// atan
-template <typename genType>
-GLM_FUNC_QUALIFIER genType atan
-(
-	genType const & y, 
-	genType const & x
-)
-{
-	GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'atan' only accept floating-point input");
-
-    return ::std::atan2(y, x);
-}
-
-template <typename T>
-GLM_FUNC_QUALIFIER detail::tvec2<T> atan
-(
-	detail::tvec2<T> const & y, 
-	detail::tvec2<T> const & x
-)
-{
-    return detail::tvec2<T>(
-        atan(y.x, x.x),
-        atan(y.y, x.y));
-}
-
-template <typename T>
-GLM_FUNC_QUALIFIER detail::tvec3<T> atan
-(
-	detail::tvec3<T> const & y, 
-	detail::tvec3<T> const & x
-)
-{
-    return detail::tvec3<T>(
-        atan(y.x, x.x),
-        atan(y.y, x.y),
-        atan(y.z, x.z));
-}
-
-template <typename T>
-GLM_FUNC_QUALIFIER detail::tvec4<T> atan
-(
-	detail::tvec4<T> const & y, 
-	detail::tvec4<T> const & x
-)
-{
-    return detail::tvec4<T>(
-        atan(y.x, x.x),
-        atan(y.y, x.y),
-        atan(y.z, x.z),
-        atan(y.w, x.w));
-}
-
-template <typename genType>
-GLM_FUNC_QUALIFIER genType atan
-(
-	genType const & x
-)
-{
-	GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'atan' only accept floating-point input");
-
-    return ::std::atan(x);
-}
-
-template <typename T>
-GLM_FUNC_QUALIFIER detail::tvec2<T> atan
-(
-	detail::tvec2<T> const & x
-)
-{
-    return detail::tvec2<T>(
-        atan(x.x),
-        atan(x.y));
-}
-
-template <typename T>
-GLM_FUNC_QUALIFIER detail::tvec3<T> atan
-(
-	detail::tvec3<T> const & x
-)
-{
-    return detail::tvec3<T>(
-        atan(x.x),
-        atan(x.y),
-        atan(x.z));
-}
-
-template <typename T>
-GLM_FUNC_QUALIFIER detail::tvec4<T> atan
-(
-	detail::tvec4<T> const & x
-)
-{
-    return detail::tvec4<T>(
-        atan(x.x),
-        atan(x.y),
-        atan(x.z),
-        atan(x.w));
-}
-
-// sinh
-template <typename genType> 
-GLM_FUNC_QUALIFIER genType sinh
-(
-	genType const & angle
-)
-{
-    GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'sinh' only accept floating-point input");
-
-	return std::sinh(angle);
-}
-
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tvec2<T> sinh
-(
-	detail::tvec2<T> const & angle
-)
-{
-    return detail::tvec2<T>(
-        sinh(angle.x),
-        sinh(angle.y));
-}
-
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tvec3<T> sinh
-(
-	detail::tvec3<T> const & angle
-)
-{
-    return detail::tvec3<T>(
-        sinh(angle.x),
-        sinh(angle.y),
-        sinh(angle.z));
-}
-
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tvec4<T> sinh
-(
-	detail::tvec4<T> const & angle
-)
-{
-    return detail::tvec4<T>(
-        sinh(angle.x),
-        sinh(angle.y),
-        sinh(angle.z),
-        sinh(angle.w));
-}
-
-// cosh
-template <typename genType> 
-GLM_FUNC_QUALIFIER genType cosh
-(
-	genType const & angle
-)
-{
-    GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'cosh' only accept floating-point input");
-
-	return std::cosh(angle);
-}
-
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tvec2<T> cosh
-(
-	detail::tvec2<T> const & angle
-)
-{
-    return detail::tvec2<T>(
-        cosh(angle.x),
-        cosh(angle.y));
-}
-
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tvec3<T> cosh
-(
-	detail::tvec3<T> const & angle
-)
-{
-    return detail::tvec3<T>(
-        cosh(angle.x),
-        cosh(angle.y),
-        cosh(angle.z));
-}
-
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tvec4<T> cosh
-(
-	detail::tvec4<T> const & angle
-)
-{
-    return detail::tvec4<T>(
-        cosh(angle.x),
-        cosh(angle.y),
-        cosh(angle.z),
-        cosh(angle.w));
-}
-
-// tanh
-template <typename genType>
-GLM_FUNC_QUALIFIER genType tanh
-(
-	genType const & angle
-)
-{
-    GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'tanh' only accept floating-point input");
-
-	return std::tanh(angle);
-}
-
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tvec2<T> tanh
-(
-	detail::tvec2<T> const & angle
-)
-{
-    return detail::tvec2<T>(
-        tanh(angle.x),
-        tanh(angle.y));
-}
-
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tvec3<T> tanh
-(
-	detail::tvec3<T> const & angle
-)
-{
-    return detail::tvec3<T>(
-        tanh(angle.x),
-        tanh(angle.y),
-        tanh(angle.z));
-}
-
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tvec4<T> tanh
-(
-	detail::tvec4<T> const & angle
-)
-{
-    return detail::tvec4<T>(
-        tanh(angle.x),
-        tanh(angle.y),
-        tanh(angle.z),
-        tanh(angle.w));
-}
-
-// asinh
-template <typename genType> 
-GLM_FUNC_QUALIFIER genType asinh
-(
-	genType const & x
-)
-{
-	GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'asinh' only accept floating-point input");
+namespace glm
+{
+	// radians
+	template <typename genType>
+	GLM_FUNC_QUALIFIER genType radians
+	(
+		genType const & degrees
+	)
+	{
+		GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'radians' only accept floating-point input");
+
+		const genType pi = genType(3.1415926535897932384626433832795);
+		return degrees * (pi / genType(180));
+	}
+
+	template <typename T>
+	GLM_FUNC_QUALIFIER detail::tvec2<T> radians
+	(
+		detail::tvec2<T> const & degrees
+	)
+	{
+		return detail::tvec2<T>(
+			radians(degrees.x),
+			radians(degrees.y));
+	}
+
+	template <typename T>
+	GLM_FUNC_QUALIFIER detail::tvec3<T> radians
+	(
+		detail::tvec3<T> const & degrees
+	)
+	{
+		return detail::tvec3<T>(
+			radians(degrees.x),
+			radians(degrees.y),
+			radians(degrees.z));
+	}
+
+	template <typename T>
+	GLM_FUNC_QUALIFIER detail::tvec4<T> radians
+	(
+		detail::tvec4<T> const & degrees
+	)
+	{
+		return detail::tvec4<T>(
+			radians(degrees.x),
+			radians(degrees.y),
+			radians(degrees.z),
+			radians(degrees.w));
+	}
+
+	// degrees
+	template <typename genType>
+	GLM_FUNC_QUALIFIER genType degrees
+	(
+		genType const & radians
+	)
+	{
+		GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'degrees' only accept floating-point input");
+
+		const genType pi = genType(3.1415926535897932384626433832795);
+		return radians * (genType(180) / pi);
+	}
+
+	template <typename T>
+	GLM_FUNC_QUALIFIER detail::tvec2<T> degrees
+	(
+		detail::tvec2<T> const & radians
+	)
+	{
+		return detail::tvec2<T>(
+			degrees(radians.x),
+			degrees(radians.y));
+	}
+
+	template <typename T>
+	GLM_FUNC_QUALIFIER detail::tvec3<T> degrees
+	(	
+		detail::tvec3<T> const & radians
+	)
+	{
+		return detail::tvec3<T>(
+			degrees(radians.x),
+			degrees(radians.y),
+			degrees(radians.z));
+	}
+
+	template <typename T>
+	GLM_FUNC_QUALIFIER detail::tvec4<T> degrees
+	(
+		detail::tvec4<T> const & radians
+	)
+	{
+		return detail::tvec4<T>(
+			degrees(radians.x),
+			degrees(radians.y),
+			degrees(radians.z),
+			degrees(radians.w));
+	}
+
+	// sin
+	template <typename genType>
+	GLM_FUNC_QUALIFIER genType sin
+	(
+		genType const & angle
+	)
+	{
+		GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'sin' only accept floating-point input");
+
+		return ::std::sin(angle);
+	}
+
+	template <typename T>
+	GLM_FUNC_QUALIFIER detail::tvec2<T> sin
+	(
+		detail::tvec2<T> const & angle
+	)
+	{
+		return detail::tvec2<T>(
+			sin(angle.x),
+			sin(angle.y));
+	}
+
+	template <typename T>
+	GLM_FUNC_QUALIFIER detail::tvec3<T> sin
+	(
+		detail::tvec3<T> const & angle
+	)
+	{
+		return detail::tvec3<T>(
+			sin(angle.x),
+			sin(angle.y),
+			sin(angle.z));
+	}
+
+	template <typename T>
+	GLM_FUNC_QUALIFIER detail::tvec4<T> sin
+	(
+		detail::tvec4<T> const & angle
+	)
+	{
+		return detail::tvec4<T>(
+			sin(angle.x),
+			sin(angle.y),
+			sin(angle.z),
+			sin(angle.w));
+	}
+
+	// cos
+	template <typename genType>
+	GLM_FUNC_QUALIFIER genType cos(genType const & angle)
+	{
+		GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'cos' only accept floating-point input");
+
+		return ::std::cos(angle);
+	}
+
+	template <typename T>
+	GLM_FUNC_QUALIFIER detail::tvec2<T> cos
+	(
+		detail::tvec2<T> const & angle
+	)
+	{
+		return detail::tvec2<T>(
+			cos(angle.x),
+			cos(angle.y));
+	}
+
+	template <typename T>
+	GLM_FUNC_QUALIFIER detail::tvec3<T> cos
+	(
+		detail::tvec3<T> const & angle
+	)
+	{
+		return detail::tvec3<T>(
+			cos(angle.x),
+			cos(angle.y),
+			cos(angle.z));
+	}
+
+	template <typename T>
+	GLM_FUNC_QUALIFIER detail::tvec4<T> cos
+	(	
+		detail::tvec4<T> const & angle
+	)
+	{
+		return detail::tvec4<T>(
+			cos(angle.x),
+			cos(angle.y),
+			cos(angle.z),
+			cos(angle.w));
+	}
+
+	// tan
+	template <typename genType>
+	GLM_FUNC_QUALIFIER genType tan
+	(
+		genType const & angle
+	)
+	{
+		GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'tan' only accept floating-point input");
+
+		return ::std::tan(angle);
+	}
+
+	template <typename T>
+	GLM_FUNC_QUALIFIER detail::tvec2<T> tan
+	(
+		detail::tvec2<T> const & angle
+	)
+	{
+		return detail::tvec2<T>(
+			tan(angle.x),
+			tan(angle.y));
+	}
+
+	template <typename T>
+	GLM_FUNC_QUALIFIER detail::tvec3<T> tan
+	(
+		detail::tvec3<T> const & angle
+	)
+	{
+		return detail::tvec3<T>(
+			tan(angle.x),
+			tan(angle.y),
+			tan(angle.z));
+	}
+
+	template <typename T>
+	GLM_FUNC_QUALIFIER detail::tvec4<T> tan
+	(
+		detail::tvec4<T> const & angle
+	)
+	{
+		return detail::tvec4<T>(
+			tan(angle.x),
+			tan(angle.y),
+			tan(angle.z),
+			tan(angle.w));
+	}
+
+	// asin
+	template <typename genType>
+	GLM_FUNC_QUALIFIER genType asin
+	(
+		genType const & x
+	)
+	{
+		GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'asin' only accept floating-point input");
+
+		return ::std::asin(x);
+	}
+
+	template <typename T>
+	GLM_FUNC_QUALIFIER detail::tvec2<T> asin
+	(
+		detail::tvec2<T> const & x
+	)
+	{
+		return detail::tvec2<T>(
+			asin(x.x),
+			asin(x.y));
+	}
+
+	template <typename T>
+	GLM_FUNC_QUALIFIER detail::tvec3<T> asin
+	(
+		detail::tvec3<T> const & x
+	)
+	{
+		return detail::tvec3<T>(
+			asin(x.x),
+			asin(x.y),
+			asin(x.z));
+	}
+
+	template <typename T>
+	GLM_FUNC_QUALIFIER detail::tvec4<T> asin
+	(
+		detail::tvec4<T> const & x
+	)
+	{
+		return detail::tvec4<T>(
+			asin(x.x),
+			asin(x.y),
+			asin(x.z),
+			asin(x.w));
+	}
+
+	// acos
+	template <typename genType>
+	GLM_FUNC_QUALIFIER genType acos
+	(
+		genType const & x
+	)
+	{
+		GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'acos' only accept floating-point input");
+
+		return ::std::acos(x);
+	}
+
+	template <typename T>
+	GLM_FUNC_QUALIFIER detail::tvec2<T> acos
+	(
+		detail::tvec2<T> const & x
+	)
+	{
+		return detail::tvec2<T>(
+			acos(x.x),
+			acos(x.y));
+	}
+
+	template <typename T>
+	GLM_FUNC_QUALIFIER detail::tvec3<T> acos
+	(
+		detail::tvec3<T> const & x
+	)
+	{
+		return detail::tvec3<T>(
+			acos(x.x),
+			acos(x.y),
+			acos(x.z));
+	}
+
+	template <typename T>
+	GLM_FUNC_QUALIFIER detail::tvec4<T> acos
+	(
+		detail::tvec4<T> const & x
+	)
+	{
+		return detail::tvec4<T>(
+			acos(x.x),
+			acos(x.y),
+			acos(x.z),
+			acos(x.w));
+	}
+
+	// atan
+	template <typename genType>
+	GLM_FUNC_QUALIFIER genType atan
+	(
+		genType const & y, 
+		genType const & x
+	)
+	{
+		GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'atan' only accept floating-point input");
+
+		return ::std::atan2(y, x);
+	}
+
+	template <typename T>
+	GLM_FUNC_QUALIFIER detail::tvec2<T> atan
+	(
+		detail::tvec2<T> const & y, 
+		detail::tvec2<T> const & x
+	)
+	{
+		return detail::tvec2<T>(
+			atan(y.x, x.x),
+			atan(y.y, x.y));
+	}
+
+	template <typename T>
+	GLM_FUNC_QUALIFIER detail::tvec3<T> atan
+	(
+		detail::tvec3<T> const & y, 
+		detail::tvec3<T> const & x
+	)
+	{
+		return detail::tvec3<T>(
+			atan(y.x, x.x),
+			atan(y.y, x.y),
+			atan(y.z, x.z));
+	}
+
+	template <typename T>
+	GLM_FUNC_QUALIFIER detail::tvec4<T> atan
+	(
+		detail::tvec4<T> const & y, 
+		detail::tvec4<T> const & x
+	)
+	{
+		return detail::tvec4<T>(
+			atan(y.x, x.x),
+			atan(y.y, x.y),
+			atan(y.z, x.z),
+			atan(y.w, x.w));
+	}
+
+	template <typename genType>
+	GLM_FUNC_QUALIFIER genType atan
+	(
+		genType const & x
+	)
+	{
+		GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'atan' only accept floating-point input");
+
+		return ::std::atan(x);
+	}
+
+	template <typename T>
+	GLM_FUNC_QUALIFIER detail::tvec2<T> atan
+	(
+		detail::tvec2<T> const & x
+	)
+	{
+		return detail::tvec2<T>(
+			atan(x.x),
+			atan(x.y));
+	}
+
+	template <typename T>
+	GLM_FUNC_QUALIFIER detail::tvec3<T> atan
+	(
+		detail::tvec3<T> const & x
+	)
+	{
+		return detail::tvec3<T>(
+			atan(x.x),
+			atan(x.y),
+			atan(x.z));
+	}
+
+	template <typename T>
+	GLM_FUNC_QUALIFIER detail::tvec4<T> atan
+	(
+		detail::tvec4<T> const & x
+	)
+	{
+		return detail::tvec4<T>(
+			atan(x.x),
+			atan(x.y),
+			atan(x.z),
+			atan(x.w));
+	}
+
+	// sinh
+	template <typename genType> 
+	GLM_FUNC_QUALIFIER genType sinh
+	(
+		genType const & angle
+	)
+	{
+		GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'sinh' only accept floating-point input");
+
+		return std::sinh(angle);
+	}
+
+	template <typename T> 
+	GLM_FUNC_QUALIFIER detail::tvec2<T> sinh
+	(
+		detail::tvec2<T> const & angle
+	)
+	{
+		return detail::tvec2<T>(
+			sinh(angle.x),
+			sinh(angle.y));
+	}
+
+	template <typename T> 
+	GLM_FUNC_QUALIFIER detail::tvec3<T> sinh
+	(
+		detail::tvec3<T> const & angle
+	)
+	{
+		return detail::tvec3<T>(
+			sinh(angle.x),
+			sinh(angle.y),
+			sinh(angle.z));
+	}
+
+	template <typename T> 
+	GLM_FUNC_QUALIFIER detail::tvec4<T> sinh
+	(
+		detail::tvec4<T> const & angle
+	)
+	{
+		return detail::tvec4<T>(
+			sinh(angle.x),
+			sinh(angle.y),
+			sinh(angle.z),
+			sinh(angle.w));
+	}
+
+	// cosh
+	template <typename genType> 
+	GLM_FUNC_QUALIFIER genType cosh
+	(
+		genType const & angle
+	)
+	{
+		GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'cosh' only accept floating-point input");
+
+		return std::cosh(angle);
+	}
+
+	template <typename T> 
+	GLM_FUNC_QUALIFIER detail::tvec2<T> cosh
+	(
+		detail::tvec2<T> const & angle
+	)
+	{
+		return detail::tvec2<T>(
+			cosh(angle.x),
+			cosh(angle.y));
+	}
+
+	template <typename T> 
+	GLM_FUNC_QUALIFIER detail::tvec3<T> cosh
+	(
+		detail::tvec3<T> const & angle
+	)
+	{
+		return detail::tvec3<T>(
+			cosh(angle.x),
+			cosh(angle.y),
+			cosh(angle.z));
+	}
+
+	template <typename T> 
+	GLM_FUNC_QUALIFIER detail::tvec4<T> cosh
+	(
+		detail::tvec4<T> const & angle
+	)
+	{
+		return detail::tvec4<T>(
+			cosh(angle.x),
+			cosh(angle.y),
+			cosh(angle.z),
+			cosh(angle.w));
+	}
+
+	// tanh
+	template <typename genType>
+	GLM_FUNC_QUALIFIER genType tanh
+	(
+		genType const & angle
+	)
+	{
+		GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'tanh' only accept floating-point input");
+
+		return std::tanh(angle);
+	}
+
+	template <typename T> 
+	GLM_FUNC_QUALIFIER detail::tvec2<T> tanh
+	(
+		detail::tvec2<T> const & angle
+	)
+	{
+		return detail::tvec2<T>(
+			tanh(angle.x),
+			tanh(angle.y));
+	}
+
+	template <typename T> 
+	GLM_FUNC_QUALIFIER detail::tvec3<T> tanh
+	(
+		detail::tvec3<T> const & angle
+	)
+	{
+		return detail::tvec3<T>(
+			tanh(angle.x),
+			tanh(angle.y),
+			tanh(angle.z));
+	}
+
+	template <typename T> 
+	GLM_FUNC_QUALIFIER detail::tvec4<T> tanh
+	(
+		detail::tvec4<T> const & angle
+	)
+	{
+		return detail::tvec4<T>(
+			tanh(angle.x),
+			tanh(angle.y),
+			tanh(angle.z),
+			tanh(angle.w));
+	}
+
+	// asinh
+	template <typename genType> 
+	GLM_FUNC_QUALIFIER genType asinh
+	(
+		genType const & x
+	)
+	{
+		GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'asinh' only accept floating-point input");
 		
 		
-	return (x < genType(0) ? genType(-1) : (x > genType(0) ? genType(1) : genType(0))) * log(abs(x) + sqrt(genType(1) + x * x));
-}
-
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tvec2<T> asinh
-(
-	detail::tvec2<T> const & x
-)
-{
-    return detail::tvec2<T>(
-        asinh(x.x),
-        asinh(x.y));
-}
-
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tvec3<T> asinh
-(
-	detail::tvec3<T> const & x
-)
-{
-    return detail::tvec3<T>(
-        asinh(x.x),
-        asinh(x.y),
-        asinh(x.z));
-}
-
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tvec4<T> asinh
-(
-	detail::tvec4<T> const & x
-)
-{
-    return detail::tvec4<T>(
-        asinh(x.x),
-        asinh(x.y),
-        asinh(x.z),
-        asinh(x.w));
-}
-
-// acosh
-template <typename genType> 
-GLM_FUNC_QUALIFIER genType acosh
-(
-	genType const & x
-)
-{
-	GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'acosh' only accept floating-point input");
-
-	if(x < genType(1))
-		return genType(0);
-	return log(x + sqrt(x * x - genType(1)));
-}
-
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tvec2<T> acosh
-(
-	detail::tvec2<T> const & x
-)
-{
-	return detail::tvec2<T>(
-		acosh(x.x),
-		acosh(x.y));
-}
-
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tvec3<T> acosh
-(
-	detail::tvec3<T> const & x
-)
-{
-    return detail::tvec3<T>(
-        acosh(x.x),
-        acosh(x.y),
-        acosh(x.z));
-}
-
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tvec4<T> acosh
-(
-	detail::tvec4<T> const & x
-)
-{
-    return detail::tvec4<T>(
-        acosh(x.x),
-        acosh(x.y),
-        acosh(x.z),
-        acosh(x.w));
-}
-
-// atanh
-template <typename genType>
-GLM_FUNC_QUALIFIER genType atanh
-(
-	genType const & x
-)
-{
-	GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'atanh' only accept floating-point input");
+		return (x < genType(0) ? genType(-1) : (x > genType(0) ? genType(1) : genType(0))) * log(abs(x) + sqrt(genType(1) + x * x));
+	}
+
+	template <typename T> 
+	GLM_FUNC_QUALIFIER detail::tvec2<T> asinh
+	(
+		detail::tvec2<T> const & x
+	)
+	{
+		return detail::tvec2<T>(
+			asinh(x.x),
+			asinh(x.y));
+	}
+
+	template <typename T> 
+	GLM_FUNC_QUALIFIER detail::tvec3<T> asinh
+	(
+		detail::tvec3<T> const & x
+	)
+	{
+		return detail::tvec3<T>(
+			asinh(x.x),
+			asinh(x.y),
+			asinh(x.z));
+	}
+
+	template <typename T> 
+	GLM_FUNC_QUALIFIER detail::tvec4<T> asinh
+	(
+		detail::tvec4<T> const & x
+	)
+	{
+		return detail::tvec4<T>(
+			asinh(x.x),
+			asinh(x.y),
+			asinh(x.z),
+			asinh(x.w));
+	}
+
+	// acosh
+	template <typename genType> 
+	GLM_FUNC_QUALIFIER genType acosh
+	(
+		genType const & x
+	)
+	{
+		GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'acosh' only accept floating-point input");
+
+		if(x < genType(1))
+			return genType(0);
+		return log(x + sqrt(x * x - genType(1)));
+	}
+
+	template <typename T> 
+	GLM_FUNC_QUALIFIER detail::tvec2<T> acosh
+	(
+		detail::tvec2<T> const & x
+	)
+	{
+		return detail::tvec2<T>(
+			acosh(x.x),
+			acosh(x.y));
+	}
+
+	template <typename T> 
+	GLM_FUNC_QUALIFIER detail::tvec3<T> acosh
+	(
+		detail::tvec3<T> const & x
+	)
+	{
+		return detail::tvec3<T>(
+			acosh(x.x),
+			acosh(x.y),
+			acosh(x.z));
+	}
+
+	template <typename T> 
+	GLM_FUNC_QUALIFIER detail::tvec4<T> acosh
+	(
+		detail::tvec4<T> const & x
+	)
+	{
+		return detail::tvec4<T>(
+			acosh(x.x),
+			acosh(x.y),
+			acosh(x.z),
+			acosh(x.w));
+	}
+
+	// atanh
+	template <typename genType>
+	GLM_FUNC_QUALIFIER genType atanh
+	(
+		genType const & x
+	)
+	{
+		GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'atanh' only accept floating-point input");
 		
 		
-	if(abs(x) >= genType(1))
-		return 0;
-	return genType(0.5) * log((genType(1) + x) / (genType(1) - x));
-}
-
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tvec2<T> atanh
-(
-	detail::tvec2<T> const & x
-)
-{
-    return detail::tvec2<T>(
-        atanh(x.x),
-        atanh(x.y));
-}
-
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tvec3<T> atanh
-(
-	detail::tvec3<T> const & x
-)
-{
-    return detail::tvec3<T>(
-        atanh(x.x),
-        atanh(x.y),
-        atanh(x.z));
-}
-
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tvec4<T> atanh
-(
-	detail::tvec4<T> const & x
-)
-{
-    return detail::tvec4<T>(
-        atanh(x.x),
-        atanh(x.y),
-        atanh(x.z),
-        atanh(x.w));
-}
-
+		if(abs(x) >= genType(1))
+			return 0;
+		return genType(0.5) * log((genType(1) + x) / (genType(1) - x));
+	}
+
+	template <typename T> 
+	GLM_FUNC_QUALIFIER detail::tvec2<T> atanh
+	(
+		detail::tvec2<T> const & x
+	)
+	{
+		return detail::tvec2<T>(
+			atanh(x.x),
+			atanh(x.y));
+	}
+
+	template <typename T> 
+	GLM_FUNC_QUALIFIER detail::tvec3<T> atanh
+	(
+		detail::tvec3<T> const & x
+	)
+	{
+		return detail::tvec3<T>(
+			atanh(x.x),
+			atanh(x.y),
+			atanh(x.z));
+	}
+
+	template <typename T> 
+	GLM_FUNC_QUALIFIER detail::tvec4<T> atanh
+	(
+		detail::tvec4<T> const & x
+	)
+	{
+		return detail::tvec4<T>(
+			atanh(x.x),
+			atanh(x.y),
+			atanh(x.z),
+			atanh(x.w));
+	}
 }//namespace glm
 }//namespace glm