2
0
Эх сурвалжийг харах

Merge branch 'swizzle' of ssh://ogl-math.git.sourceforge.net/gitroot/ogl-math/ogl-math into swizzle

Christophe Riccio 14 жил өмнө
parent
commit
12f0a2a20b
79 өөрчлөгдсөн 8287 нэмэгдсэн , 11662 устгасан
  1. 71 10
      glm/core/_vectorize.hpp
  2. 156 100
      glm/core/func_common.hpp
  3. 26 250
      glm/core/func_common.inl
  4. 21 0
      glm/core/func_exponential.hpp
  5. 10 248
      glm/core/func_exponential.inl
  6. 18 4
      glm/core/func_geometric.hpp
  7. 2 0
      glm/core/func_geometric.inl
  8. 84 58
      glm/core/func_integer.hpp
  9. 2 35
      glm/core/func_integer.inl
  10. 38 18
      glm/core/func_matrix.hpp
  11. 2 0
      glm/core/func_matrix.inl
  12. 8 0
      glm/core/func_noise.hpp
  13. 108 109
      glm/core/func_packing.inl
  14. 73 43
      glm/core/func_trigonometric.hpp
  15. 214 725
      glm/core/func_trigonometric.inl
  16. 41 23
      glm/core/func_vector_relational.hpp
  17. 487 975
      glm/gtc/half_float.inl
  18. 47 41
      glm/gtc/matrix_access.inl
  19. 128 123
      glm/gtc/matrix_inverse.inl
  20. 380 381
      glm/gtc/matrix_transform.inl
  21. 831 832
      glm/gtc/noise.inl
  22. 2 2
      glm/gtc/quaternion.inl
  23. 113 177
      glm/gtc/random.inl
  24. 87 161
      glm/gtc/swizzle.inl
  25. 581 751
      glm/gtx/bit.inl
  26. 18 19
      glm/gtx/closest_point.inl
  27. 723 724
      glm/gtx/color_cast.inl
  28. 124 125
      glm/gtx/color_space.inl
  29. 50 51
      glm/gtx/color_space_YCoCg.inl
  30. 114 115
      glm/gtx/compatibility.inl
  31. 33 34
      glm/gtx/component_wise.inl
  32. 3 768
      glm/gtx/constants.inl
  33. 219 220
      glm/gtx/epsilon.inl
  34. 232 233
      glm/gtx/euler_angles.inl
  35. 41 42
      glm/gtx/extend.inl
  36. 8 8
      glm/gtx/fast_exponential.hpp
  37. 139 279
      glm/gtx/fast_exponential.inl
  38. 129 224
      glm/gtx/fast_square_root.inl
  39. 52 243
      glm/gtx/fast_trigonometry.inl
  40. 30 31
      glm/gtx/gradient_paint.inl
  41. 21 18
      glm/gtx/handed_coordinate_space.inl
  42. 16 16
      glm/gtx/inertia.hpp
  43. 96 81
      glm/gtx/inertia.inl
  44. 8 6
      glm/gtx/int_10_10_10_2.inl
  45. 137 137
      glm/gtx/integer.inl
  46. 157 158
      glm/gtx/intersect.inl
  47. 14 76
      glm/gtx/log_base.inl
  48. 31 27
      glm/gtx/matrix_cross_product.inl
  49. 103 98
      glm/gtx/matrix_interpolation.inl
  50. 24 24
      glm/gtx/matrix_major_storage.hpp
  51. 151 150
      glm/gtx/matrix_major_storage.inl
  52. 105 106
      glm/gtx/matrix_operation.inl
  53. 16 16
      glm/gtx/matrix_query.hpp
  54. 123 109
      glm/gtx/matrix_query.inl
  55. 11 10
      glm/gtx/mixed_product.inl
  56. 105 178
      glm/gtx/multiple.inl
  57. 20 46
      glm/gtx/norm.hpp
  58. 144 114
      glm/gtx/norm.inl
  59. 11 12
      glm/gtx/normal.inl
  60. 97 98
      glm/gtx/normalize_dot.inl
  61. 47 48
      glm/gtx/optimum_pow.inl
  62. 32 33
      glm/gtx/orthonormalize.inl
  63. 4 18
      glm/gtx/perpendicular.hpp
  64. 10 25
      glm/gtx/perpendicular.inl
  65. 4 2
      glm/gtx/polar_coordinates.hpp
  66. 8 4
      glm/gtx/polar_coordinates.inl
  67. 4 18
      glm/gtx/projection.hpp
  68. 10 25
      glm/gtx/projection.inl
  69. 260 261
      glm/gtx/quaternion.inl
  70. 172 579
      glm/gtx/reciprocal.inl
  71. 144 125
      glm/gtx/rotate_vector.inl
  72. 142 143
      glm/gtx/transform2.inl
  73. 130 229
      glm/gtx/ulp.inl
  74. 2 2
      glm/gtx/unsigned_int.inl
  75. 40 41
      glm/gtx/vector_access.inl
  76. 39 40
      glm/gtx/vector_angle.inl
  77. 152 153
      glm/gtx/vector_query.inl
  78. 101 102
      glm/gtx/verbose_operator.inl
  79. 151 152
      glm/gtx/wrap.inl

+ 71 - 10
glm/core/_vectorize.hpp

@@ -26,7 +26,7 @@
 /// @author Christophe Riccio
 /// @author Christophe Riccio
 ///////////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////////
 
 
-#define VECTORIZE_1PARAM(func) \
+#define VECTORIZE2_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) \
@@ -34,8 +34,9 @@
         return detail::tvec2<T>( \
         return detail::tvec2<T>( \
             func(v.x), \
             func(v.x), \
             func(v.y)); \
             func(v.y)); \
-    } \
-	\
+    }
+
+#define VECTORIZE3_VEC(func) \
     template <typename T> \
     template <typename T> \
     GLM_FUNC_QUALIFIER detail::tvec3<T> func( \
     GLM_FUNC_QUALIFIER detail::tvec3<T> func( \
 		detail::tvec3<T> const & v) \
 		detail::tvec3<T> const & v) \
@@ -44,8 +45,9 @@
             func(v.x), \
             func(v.x), \
             func(v.y), \
             func(v.y), \
             func(v.z)); \
             func(v.z)); \
-    } \
-	\
+    }
+
+#define VECTORIZE4_VEC(func) \
     template <typename T> \
     template <typename T> \
     GLM_FUNC_QUALIFIER detail::tvec4<T> func( \
     GLM_FUNC_QUALIFIER detail::tvec4<T> func( \
 		detail::tvec4<T> const & v) \
 		detail::tvec4<T> const & v) \
@@ -57,7 +59,59 @@
             func(v.w)); \
             func(v.w)); \
     }
     }
 
 
-#define VECTORIZE_2PARAMS(func) \
+#define VECTORIZE_VEC(func) \
+	VECTORIZE2_VEC(func) \
+	VECTORIZE3_VEC(func) \
+	VECTORIZE4_VEC(func)
+
+#define VECTORIZE2_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)); \
+    }
+
+#define VECTORIZE3_VEC_SCA(func) \
+    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)); \
+    }
+
+#define VECTORIZE4_VEC_SCA(func) \
+    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_SCA(func) \
+	VECTORIZE2_VEC_SCA(func) \
+	VECTORIZE3_VEC_SCA(func) \
+	VECTORIZE4_VEC_SCA(func)
+
+#define VECTORIZE2_VEC_VEC(func) \
     template <typename T> \
     template <typename T> \
     GLM_FUNC_QUALIFIER detail::tvec2<T> func \
     GLM_FUNC_QUALIFIER detail::tvec2<T> func \
 	( \
 	( \
@@ -68,8 +122,9 @@
         return detail::tvec2<T>( \
         return detail::tvec2<T>( \
             func(x.x, y.x), \
             func(x.x, y.x), \
             func(x.y, y.y)); \
             func(x.y, y.y)); \
-    } \
-	 \
+    }
+
+#define VECTORIZE3_VEC_VEC(func) \
     template <typename T> \
     template <typename T> \
     GLM_FUNC_QUALIFIER detail::tvec3<T> func \
     GLM_FUNC_QUALIFIER detail::tvec3<T> func \
 	( \
 	( \
@@ -81,8 +136,9 @@
             func(x.x, y.x), \
             func(x.x, y.x), \
             func(x.y, y.y), \
             func(x.y, y.y), \
             func(x.z, y.z)); \
             func(x.z, y.z)); \
-    } \
-	 \
+    }
+
+#define VECTORIZE4_VEC_VEC(func) \
     template <typename T> \
     template <typename T> \
     GLM_FUNC_QUALIFIER detail::tvec4<T> func \
     GLM_FUNC_QUALIFIER detail::tvec4<T> func \
 	( \
 	( \
@@ -96,3 +152,8 @@
             func(x.z, y.z), \
             func(x.z, y.z), \
             func(x.w, y.w)); \
             func(x.w, y.w)); \
     }
     }
+
+#define VECTORIZE_VEC_VEC(func) \
+	VECTORIZE2_VEC_VEC(func) \
+	VECTORIZE3_VEC_VEC(func) \
+	VECTORIZE4_VEC_VEC(func)

+ 156 - 100
glm/core/func_common.hpp

@@ -44,72 +44,90 @@ namespace glm
 	/// @{
 	/// @{
 
 
 	/// Returns x if x >= 0; otherwise, it returns -x.
 	/// Returns x if x >= 0; otherwise, it returns -x.
+	/// 
+	/// @tparam genType floating-point or signed integer; scalar or vector types.
     /// 
     /// 
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/abs.xml">GLSL abs man page</a>
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/abs.xml">GLSL abs man page</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3</a>
-    template <typename genFIType> 
-	genFIType abs(genFIType const & x);
+    template <typename genType> 
+	genType abs(genType const & x);
 
 
 	/// Returns 1.0 if x > 0, 0.0 if x == 0, or -1.0 if x < 0. 
 	/// Returns 1.0 if x > 0, 0.0 if x == 0, or -1.0 if x < 0. 
-    /// 
+	/// 
+	/// @tparam genType Floating-point or signed integer; scalar or vector types.
+	/// 
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/sign.xml">GLSL sign man page</a>
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/sign.xml">GLSL sign man page</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3</a>
-	template <typename genFIType> 
-	genFIType sign(genFIType const & x);
+	template <typename genType> 
+	genType sign(genType const & x);
 
 
-    //! Returns a value equal to the nearest integer that is less then or equal to x. 
-    //! 
+    /// Returns a value equal to the nearest integer that is less then or equal to x. 
+	/// 
+	/// @tparam genType Floating-point scalar or vector types.
+    /// 
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/floor.xml">GLSL floor man page</a>
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/floor.xml">GLSL floor man page</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3</a>
 	template <typename genType> 
 	template <typename genType> 
 	genType floor(genType const & x);
 	genType floor(genType const & x);
 
 
-	//! Returns a value equal to the nearest integer to x 
-	//! whose absolute value is not larger than the absolute value of x. 
-    //! 
+	/// Returns a value equal to the nearest integer to x 
+	/// whose absolute value is not larger than the absolute value of x. 
+	/// 
+	/// @tparam genType Floating-point scalar or vector types.
+    /// 
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/trunc.xml">GLSL trunc man page</a>
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/trunc.xml">GLSL trunc man page</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3</a>
 	template <typename genType> 
 	template <typename genType> 
 	genType trunc(genType const & x);
 	genType trunc(genType const & x);
 
 
-	//! Returns a value equal to the nearest integer to x. 
-	//! The fraction 0.5 will round in a direction chosen by the 
-	//! implementation, presumably the direction that is fastest. 
-	//! This includes the possibility that round(x) returns the 
-	//! same value as roundEven(x) for all values of x. 
-    //! 
+	/// Returns a value equal to the nearest integer to x. 
+	/// The fraction 0.5 will round in a direction chosen by the 
+	/// implementation, presumably the direction that is fastest. 
+	/// This includes the possibility that round(x) returns the 
+	/// same value as roundEven(x) for all values of x. 
+	/// 
+	/// @tparam genType Floating-point scalar or vector types.
+    /// 
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/round.xml">GLSL round man page</a>
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/round.xml">GLSL round man page</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3</a>
 	template <typename genType> 
 	template <typename genType> 
 	genType round(genType const & x);
 	genType round(genType const & x);
 
 
-	//! Returns a value equal to the nearest integer to x.
-	//! A fractional part of 0.5 will round toward the nearest even
-	//! integer. (Both 3.5 and 4.5 for x will return 4.0.) 
-    //! 
+	/// Returns a value equal to the nearest integer to x.
+	/// A fractional part of 0.5 will round toward the nearest even
+	/// integer. (Both 3.5 and 4.5 for x will return 4.0.) 
+	///
+	/// @tparam genType Floating-point scalar or vector types.
+    /// 
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/roundEven.xml">GLSL roundEven man page</a>
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/roundEven.xml">GLSL roundEven man page</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3</a>
 	template <typename genType> 
 	template <typename genType> 
 	genType roundEven(genType const & x);
 	genType roundEven(genType const & x);
 
 
-	//! Returns a value equal to the nearest integer 
-	//! that is greater than or equal to x. 
-    //! 
+	/// Returns a value equal to the nearest integer 
+	/// that is greater than or equal to x. 
+    /// 
+	/// @tparam genType Floating-point scalar or vector types.
+	///
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/ceil.xml">GLSL ceil man page</a>
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/ceil.xml">GLSL ceil man page</a>
 	/// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3</a>
 	/// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3</a>
     template <typename genType> 
     template <typename genType> 
 	genType ceil(genType const & x);
 	genType ceil(genType const & x);
 
 
-	//! Return x - floor(x).
-    //! 
+	/// Return x - floor(x).
+    /// 
+	/// @tparam genType Floating-point scalar or vector types.
+	///
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/fract.xml">GLSL fract man page</a>
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/fract.xml">GLSL fract man page</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3</a>
     template <typename genType> 
     template <typename genType> 
 	genType fract(genType const & x);
 	genType fract(genType const & x);
 
 
-	//! Modulus. Returns x - y * floor(x / y) 
-	//! for each component in x using the floating point value y.
-    //! 
+	/// Modulus. Returns x - y * floor(x / y) 
+	/// for each component in x using the floating point value y.
+	///
+	/// @tparam genType Floating-point scalar or vector types.
+    ///
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/mod.xml">GLSL mod man page</a>
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/mod.xml">GLSL mod man page</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3</a>
     template <typename genType> 
     template <typename genType> 
@@ -117,9 +135,11 @@ namespace glm
 		genType const & x, 
 		genType const & x, 
 		genType const & y);
 		genType const & y);
 
 
-	//! Modulus. Returns x - y * floor(x / y) 
-	//! for each component in x using the floating point value y.
-    //! 
+	/// Modulus. Returns x - y * floor(x / y) 
+	/// for each component in x using the floating point value y.
+	/// 
+	/// @tparam genType Floating-point scalar or vector types.
+    /// 
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/mod.xml">GLSL mod man page</a>
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/mod.xml">GLSL mod man page</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3</a>
     template <typename genType> 
     template <typename genType> 
@@ -127,11 +147,13 @@ namespace glm
 		genType const & x, 
 		genType const & x, 
 		typename genType::value_type const & y);
 		typename genType::value_type const & y);
 
 
-	//! Returns the fractional part of x and sets i to the integer
-	//! part (as a whole number floating point value). Both the
-	//! return value and the output parameter will have the same
-	//! sign as x.
-    //! 
+	/// Returns the fractional part of x and sets i to the integer
+	/// part (as a whole number floating point value). Both the
+	/// return value and the output parameter will have the same
+	/// sign as x.
+    /// 
+	/// @tparam genType Floating-point scalar or vector types.
+	///
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/modf.xml">GLSL modf man page</a>
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/modf.xml">GLSL modf man page</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3</a>
 	template <typename genType> 
 	template <typename genType> 
@@ -140,6 +162,8 @@ namespace glm
 		genType & i);
 		genType & i);
 
 
     /// Returns y if y < x; otherwise, it returns x.
     /// Returns y if y < x; otherwise, it returns x.
+	///
+	/// @tparam genType Floating-point or integer; scalar or vector types.
     /// 
     /// 
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/min.xml">GLSL min man page</a>
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/min.xml">GLSL min man page</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3</a>
@@ -154,6 +178,8 @@ namespace glm
 		typename genType::value_type const & y);
 		typename genType::value_type const & y);
 
 
     /// Returns y if x < y; otherwise, it returns x.
     /// Returns y if x < y; otherwise, it returns x.
+	/// 
+	/// @tparam genType Floating-point or integer; scalar or vector types.
     /// 
     /// 
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/max.xml">GLSL max man page</a>
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/max.xml">GLSL max man page</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3</a>
@@ -167,9 +193,11 @@ namespace glm
 		genType const & x, 
 		genType const & x, 
 		typename genType::value_type const & y);
 		typename genType::value_type const & y);
 
 
-    //! Returns min(max(x, minVal), maxVal) for each component in x 
-	//! using the floating-point values minVal and maxVal.
-    //! 
+    /// Returns min(max(x, minVal), maxVal) for each component in x 
+	/// using the floating-point values minVal and maxVal.
+    ///
+	/// @tparam genType Floating-point or integer; scalar or vector types.
+	///
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/clamp.xml">GLSL clamp man page</a>
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/clamp.xml">GLSL clamp man page</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3</a>
 	template <typename genType> 
 	template <typename genType> 
@@ -243,16 +271,18 @@ namespace glm
 		typename genType::value_type const & edge, 
 		typename genType::value_type const & edge, 
 		genType const & x);
 		genType const & x);
 
 
-	//! Returns 0.0 if x <= edge0 and 1.0 if x >= edge1 and
-	//! performs smooth Hermite interpolation between 0 and 1
-	//! when edge0 < x < edge1. This is useful in cases where
-	//! you would want a threshold function with a smooth
-	//! transition. This is equivalent to:
-	//! genType t;
-	//! t = clamp ((x – edge0) / (edge1 – edge0), 0, 1);
-	//! return t * t * (3 – 2 * t);
-	//! Results are undefined if edge0 >= edge1.
-    //! 
+	/// Returns 0.0 if x <= edge0 and 1.0 if x >= edge1 and
+	/// performs smooth Hermite interpolation between 0 and 1
+	/// when edge0 < x < edge1. This is useful in cases where
+	/// you would want a threshold function with a smooth
+	/// transition. This is equivalent to:
+	/// genType t;
+	/// t = clamp ((x – edge0) / (edge1 – edge0), 0, 1);
+	/// return t * t * (3 – 2 * t);
+	/// Results are undefined if edge0 >= edge1.
+	///
+	/// @tparam genType Floating-point scalar or vector types.
+    /// 
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/smoothstep.xml">GLSL smoothstep man page</a>
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/smoothstep.xml">GLSL smoothstep man page</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3</a>
 	template <typename genType> 
 	template <typename genType> 
@@ -267,97 +297,123 @@ namespace glm
 		typename genType::value_type const & edge1, 
 		typename genType::value_type const & edge1, 
 		genType const & x);
 		genType const & x);
 
 
-	//! Returns true if x holds a NaN (not a number)
-	//! representation in the underlying implementation's set of
-	//! floating point representations. Returns false otherwise,
-	//! including for implementations with no NaN
-	//! representations.
-    //! 
+	/// Returns true if x holds a NaN (not a number)
+	/// representation in the underlying implementation's set of
+	/// floating point representations. Returns false otherwise,
+	/// including for implementations with no NaN
+	/// representations.
+    /// 
+	/// @tparam genType Floating-point scalar or vector types.
+	///
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/isnan.xml">GLSL isnan man page</a>
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/isnan.xml">GLSL isnan man page</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3</a>
 	template <typename genType> 
 	template <typename genType> 
 	typename genType::bool_type isnan(genType const & x);
 	typename genType::bool_type isnan(genType const & x);
 
 
-	//! Returns true if x holds a positive infinity or negative
-	//! infinity representation in the underlying implementation's
-	//! set of floating point representations. Returns false
-	//! otherwise, including for implementations with no infinity
-	//! representations.
-    //! 
+	/// Returns true if x holds a positive infinity or negative
+	/// infinity representation in the underlying implementation's
+	/// set of floating point representations. Returns false
+	/// otherwise, including for implementations with no infinity
+	/// representations.
+    /// 
+	/// @tparam genType Floating-point scalar or vector types.
+	/// 
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/isinf.xml">GLSL isinf man page</a>
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/isinf.xml">GLSL isinf man page</a>
 	/// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3</a>
 	/// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3</a>
 	template <typename genType> 
 	template <typename genType> 
 	typename genType::bool_type isinf(genType const & x);
 	typename genType::bool_type isinf(genType const & x);
 
 
-	//! Returns a signed integer value representing
-	//! the encoding of a floating-point value. The floatingpoint
-	//! value's bit-level representation is preserved.
-    //! 
+	/// Returns a signed integer value representing
+	/// the encoding of a floating-point value. The floatingpoint
+	/// value's bit-level representation is preserved.
+	///
+	/// @tparam genType Single-precision floating-point scalar or vector types.
+	/// @tparam genIType Signed integer scalar or vector types.
+    /// 
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/floatBitsToInt.xml">GLSL floatBitsToInt man page</a>
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/floatBitsToInt.xml">GLSL floatBitsToInt man page</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3</a>
 	template <typename genType, typename genIType>
 	template <typename genType, typename genIType>
 	genIType floatBitsToInt(genType const & value);
 	genIType floatBitsToInt(genType const & value);
 
 
-	//! Returns a unsigned integer value representing
-	//! the encoding of a floating-point value. The floatingpoint
-	//! value's bit-level representation is preserved.
-    //! 
+	/// Returns a unsigned integer value representing
+	/// the encoding of a floating-point value. The floatingpoint
+	/// value's bit-level representation is preserved.
+	///
+	/// @tparam genType Single-precision floating-point scalar or vector types.
+	/// @tparam genUType Unsigned integer scalar or vector types.
+    /// 
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/floatBitsToUint.xml">GLSL floatBitsToUint man page</a>
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/floatBitsToUint.xml">GLSL floatBitsToUint man page</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3</a>
 	template <typename genType, typename genUType>
 	template <typename genType, typename genUType>
 	genUType floatBitsToUint(genType const & value);
 	genUType floatBitsToUint(genType const & value);
 
 
-	//! Returns a floating-point value corresponding to a signed
-	//! integer encoding of a floating-point value.
-	//! If an inf or NaN is passed in, it will not signal, and the
-	//! resulting floating point value is unspecified. Otherwise,
-	//! the bit-level representation is preserved.
-    //! 
+	/// Returns a floating-point value corresponding to a signed
+	/// integer encoding of a floating-point value.
+	/// If an inf or NaN is passed in, it will not signal, and the
+	/// resulting floating point value is unspecified. Otherwise,
+	/// the bit-level representation is preserved.
+    /// 
+	/// @tparam genType Single-precision floating-point scalar or vector types.
+	/// @tparam genIType Signed integer scalar or vector types.
+	/// 
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/intBitsToFloat.xml">GLSL intBitsToFloat man page</a>
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/intBitsToFloat.xml">GLSL intBitsToFloat man page</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3</a>
+	/// 
+	/// @todo - Clarify this declaration, we don't need to actually specify the return type
 	template <typename genType, typename genIType>
 	template <typename genType, typename genIType>
 	genType intBitsToFloat(genIType const & value);
 	genType intBitsToFloat(genIType const & value);
         
         
-    //! Returns a floating-point value corresponding to a
-    //! unsigned integer encoding of a floating-point value.
-    //! If an inf or NaN is passed in, it will not signal, and the
-    //! resulting floating point value is unspecified. Otherwise,
-    //! the bit-level representation is preserved.
-    //! 
+    /// Returns a floating-point value corresponding to a
+    /// unsigned integer encoding of a floating-point value.
+    /// If an inf or NaN is passed in, it will not signal, and the
+    /// resulting floating point value is unspecified. Otherwise,
+    /// the bit-level representation is preserved.
+    /// 
+	/// @tparam genType Single-precision floating-point scalar or vector types.
+	/// @tparam genUType Unsigned integer scalar or vector types.
+    /// 
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/uintBitsToFloat.xml">GLSL uintBitsToFloat man page</a>
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/uintBitsToFloat.xml">GLSL uintBitsToFloat man page</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3</a>
+	/// 
+	/// @todo - Clarify this declaration, we don't need to actually specify the return type
     template <typename genType, typename genUType>
     template <typename genType, typename genUType>
     genType uintBitsToFloat(genUType const & value);
     genType uintBitsToFloat(genUType const & value);
         
         
-	//! Computes and returns a * b + c.
-    //! 
+	/// Computes and returns a * b + c.
+	/// 
+	/// @tparam genType Floating-point scalar or vector types.
+    /// 
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/fma.xml">GLSL fma man page</a>
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/fma.xml">GLSL fma man page</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3</a>
 	template <typename genType>
 	template <typename genType>
 	genType fma(genType const & a, genType const & b, genType const & c);
 	genType fma(genType const & a, genType const & b, genType const & c);
 
 
-	//! Splits x into a floating-point significand in the range
-	//! [0.5, 1.0) and an integral exponent of two, such that:
-	//! x = significand * exp(2, exponent)
-	//! 
-	//! The significand is returned by the function and the
-	//! exponent is returned in the parameter exp. For a
-	//! floating-point value of zero, the significant and exponent
-	//! are both zero. For a floating-point value that is an
-	//! infinity or is not a number, the results are undefined.
-	//! 
+	/// Splits x into a floating-point significand in the range
+	/// [0.5, 1.0) and an integral exponent of two, such that:
+	/// x = significand * exp(2, exponent)
+	/// 
+	/// The significand is returned by the function and the
+	/// exponent is returned in the parameter exp. For a
+	/// floating-point value of zero, the significant and exponent
+	/// are both zero. For a floating-point value that is an
+	/// infinity or is not a number, the results are undefined.
+	/// 
+	/// @tparam genType Floating-point scalar or vector types.
+	/// 
 	/// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/frexp.xml">GLSL frexp man page</a>
 	/// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/frexp.xml">GLSL frexp man page</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3</a>
 	template <typename genType, typename genIType>
 	template <typename genType, typename genIType>
 	genType frexp(genType const & x, genIType & exp);
 	genType frexp(genType const & x, genIType & exp);
 
 
-	//! Builds a floating-point number from x and the
-	//! corresponding integral exponent of two in exp, returning:
-	//! significand * exp(2, exponent)
-	//! 
-	//! If this product is too large to be represented in the
-	//! floating-point type, the result is undefined.
-	//! 
+	/// Builds a floating-point number from x and the
+	/// corresponding integral exponent of two in exp, returning:
+	/// significand * exp(2, exponent)
+	/// 
+	/// If this product is too large to be represented in the
+	/// floating-point type, the result is undefined.
+	/// 
+	/// @tparam genType Floating-point scalar or vector types.
+	///  
 	/// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/ldexp.xml">GLSL ldexp man page</a>; 
 	/// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/ldexp.xml">GLSL ldexp man page</a>; 
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3</a>
 	template <typename genType, typename genIType>
 	template <typename genType, typename genIType>

+ 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>

+ 21 - 0
glm/core/func_exponential.hpp

@@ -42,6 +42,9 @@ namespace glm
 	/// @{
 	/// @{
 
 
 	/// Returns x raised to the y power. 
 	/// Returns x raised to the y power. 
+	///
+	/// @param x pow function is defined for input values of x defined in the range (inf-, inf+) in the limit of the type precision.
+	/// @tparam genType Floating-point scalar or vector types.
     ///
     ///
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/pow.xml">GLSL pow man page</a>
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/pow.xml">GLSL pow man page</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.2</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.2</a>
@@ -49,6 +52,9 @@ namespace glm
 	genType pow(genType const & x, genType const & y);
 	genType pow(genType const & x, genType const & y);
 
 
 	/// Returns the natural exponentiation of x, i.e., e^x.
 	/// Returns the natural exponentiation of x, i.e., e^x.
+	///
+	/// @param x exp function is defined for input values of x defined in the range (inf-, inf+) in the limit of the type precision.
+	/// @tparam genType Floating-point scalar or vector types.
     /// 
     /// 
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/exp.xml">GLSL exp man page</a>
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/exp.xml">GLSL exp man page</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.2</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.2</a>
@@ -58,6 +64,9 @@ namespace glm
 	/// Returns the natural logarithm of x, i.e., 
 	/// Returns the natural logarithm of x, i.e., 
 	/// returns the value y which satisfies the equation x = e^y. 
 	/// returns the value y which satisfies the equation x = e^y. 
 	/// Results are undefined if x <= 0.
 	/// Results are undefined if x <= 0.
+	///
+	/// @param x log function is defined for input values of x defined in the range (0, inf+) in the limit of the type precision.
+	/// @tparam genType Floating-point scalar or vector types.
     /// 
     /// 
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/log.xml">GLSL log man page</a>
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/log.xml">GLSL log man page</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.2</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.2</a>
@@ -65,6 +74,9 @@ namespace glm
 	genType log(genType const & x);
 	genType log(genType const & x);
 
 
 	/// Returns 2 raised to the x power.
 	/// Returns 2 raised to the x power.
+	/// 
+	/// @param x exp2 function is defined for input values of x defined in the range (inf-, inf+) in the limit of the type precision.
+	/// @tparam genType Floating-point scalar or vector types.
     /// 
     /// 
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/exp2.xml">GLSL exp2 man page</a>
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/exp2.xml">GLSL exp2 man page</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.2</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.2</a>
@@ -74,6 +86,9 @@ namespace glm
 	/// Returns the base 2 log of x, i.e., returns the value y, 
 	/// Returns the base 2 log of x, i.e., returns the value y, 
 	/// which satisfies the equation x = 2 ^ y.
 	/// which satisfies the equation x = 2 ^ y.
     /// 
     /// 
+	/// @param x log2 function is defined for input values of x defined in the range (0, inf+) in the limit of the type precision.
+	/// @tparam genType Floating-point scalar or vector types.
+	///
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/log2.xml">GLSL log2 man page</a>
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/log2.xml">GLSL log2 man page</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.2</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.2</a>
 	template <typename genType> 
 	template <typename genType> 
@@ -81,6 +96,9 @@ namespace glm
 
 
 	/// Returns the positive square root of x.
 	/// Returns the positive square root of x.
     /// 
     /// 
+	/// @param x sqrt function is defined for input values of x defined in the range [0, inf+) in the limit of the type precision.
+	/// @tparam genType Floating-point scalar or vector types.
+	/// 
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/sqrt.xml">GLSL sqrt man page</a>
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/sqrt.xml">GLSL sqrt man page</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.2</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.2</a>
 	template <typename genType> 
 	template <typename genType> 
@@ -88,6 +106,9 @@ namespace glm
     
     
 	/// Returns the reciprocal of the positive square root of x.
 	/// Returns the reciprocal of the positive square root of x.
     /// 
     /// 
+	/// @param x inversesqrt function is defined for input values of x defined in the range [0, inf+) in the limit of the type precision.
+	/// @tparam genType Floating-point scalar or vector types.
+	/// 
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/inversesqrt.xml">GLSL inversesqrt man page</a>
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/inversesqrt.xml">GLSL inversesqrt man page</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.2</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.2</a>
 	template <typename genType> 
 	template <typename genType> 

+ 10 - 248
glm/core/func_exponential.inl

@@ -26,6 +26,8 @@
 /// @author Christophe Riccio
 /// @author Christophe Riccio
 ///////////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////////
 
 
+#include "_vectorize.hpp"
+
 namespace glm
 namespace glm
 {
 {
     // pow
     // pow
@@ -41,44 +43,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 +57,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 +71,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 +85,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 +118,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 +136,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 +149,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

+ 18 - 4
glm/core/func_geometric.hpp

@@ -43,6 +43,8 @@ namespace glm
 
 
 	/// Returns the length of x, i.e., sqrt(x * x).
 	/// Returns the length of x, i.e., sqrt(x * x).
     /// 
     /// 
+	/// @tparam genType Floating-point vector types.
+	/// 
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/length.xml">GLSL length man page</a>
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/length.xml">GLSL length man page</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.5</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.5</a>
 	template <typename genType> 
 	template <typename genType> 
@@ -50,6 +52,8 @@ namespace glm
 		genType const & x); 
 		genType const & x); 
 
 
 	/// Returns the distance betwwen p0 and p1, i.e., length(p0 - p1).
 	/// Returns the distance betwwen p0 and p1, i.e., length(p0 - p1).
+	///
+	/// @tparam genType Floating-point vector types.
     /// 
     /// 
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/distance.xml">GLSL distance man page</a>
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/distance.xml">GLSL distance man page</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.5</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.5</a>
@@ -59,6 +63,8 @@ namespace glm
 		genType const & p1);
 		genType const & p1);
 
 
 	/// Returns the dot product of x and y, i.e., result = x * y.
 	/// Returns the dot product of x and y, i.e., result = x * y.
+	///
+	/// @tparam genType Floating-point vector types.
     /// 
     /// 
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/dot.xml">GLSL dot man page</a>
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/dot.xml">GLSL dot man page</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.5</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.5</a>
@@ -68,13 +74,15 @@ namespace glm
 		genType const & y);
 		genType const & y);
 
 
 	/// Returns the cross product of x and y.
 	/// Returns the cross product of x and y.
+	///
+	/// @tparam valType Floating-point scalar types.
     /// 
     /// 
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/cross.xml">GLSL cross man page</a>
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/cross.xml">GLSL cross man page</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.5</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.5</a>
-    template <typename T> 
-	detail::tvec3<T> cross(
-		detail::tvec3<T> const & x, 
-		detail::tvec3<T> const & y);
+    template <typename valType> 
+	detail::tvec3<valType> cross(
+		detail::tvec3<valType> const & x, 
+		detail::tvec3<valType> const & y);
 
 
 	/// Returns a vector in the same direction as x but with length of 1.
 	/// Returns a vector in the same direction as x but with length of 1.
     /// 
     /// 
@@ -85,6 +93,8 @@ namespace glm
 		genType const & x);
 		genType const & x);
 
 
 	/// If dot(Nref, I) < 0.0, return N, otherwise, return -N.
 	/// If dot(Nref, I) < 0.0, return N, otherwise, return -N.
+	///
+	/// @tparam genType Floating-point vector types.
     /// 
     /// 
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/faceforward.xml">GLSL faceforward man page</a>
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/faceforward.xml">GLSL faceforward man page</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.5</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.5</a>
@@ -96,6 +106,8 @@ namespace glm
   
   
 	/// For the incident vector I and surface orientation N, 
 	/// For the incident vector I and surface orientation N, 
 	/// returns the reflection direction : result = I - 2.0 * dot(N, I) * N.
 	/// returns the reflection direction : result = I - 2.0 * dot(N, I) * N.
+	///
+	/// @tparam genType Floating-point vector types.
     /// 
     /// 
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/reflect.xml">GLSL reflect man page</a>
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/reflect.xml">GLSL reflect man page</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.5</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.5</a>
@@ -107,6 +119,8 @@ namespace glm
 	/// For the incident vector I and surface normal N, 
 	/// For the incident vector I and surface normal N, 
 	/// and the ratio of indices of refraction eta, 
 	/// and the ratio of indices of refraction eta, 
 	/// return the refraction vector.
 	/// return the refraction vector.
+	///
+	/// @tparam genType Floating-point vector types.
     /// 
     /// 
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/refract.xml">GLSL refract man page</a>
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/refract.xml">GLSL refract man page</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.5</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.5</a>

+ 2 - 0
glm/core/func_geometric.inl

@@ -26,6 +26,8 @@
 /// @author Christophe Riccio
 /// @author Christophe Riccio
 ///////////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////////
 
 
+#include "_vectorize.hpp"
+
 namespace glm
 namespace glm
 {
 {
     // length
     // length

+ 84 - 58
glm/core/func_integer.hpp

@@ -43,10 +43,12 @@ namespace glm
 	/// @addtogroup core_func_integer
 	/// @addtogroup core_func_integer
 	/// @{
 	/// @{
 
 
-	//! Adds 32-bit unsigned integer x and y, returning the sum
-	//! modulo pow(2, 32). The value carry is set to 0 if the sum was
-	//! less than pow(2, 32), or to 1 otherwise.
-	//!
+	/// Adds 32-bit unsigned integer x and y, returning the sum
+	/// modulo pow(2, 32). The value carry is set to 0 if the sum was
+	/// less than pow(2, 32), or to 1 otherwise.
+	///
+	/// @tparam genUType Unsigned integer scalar or vector types.
+	/// 
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/uaddCarry.xml">GLSL uaddCarry man page</a>
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/uaddCarry.xml">GLSL uaddCarry man page</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.8</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.8</a>
 	template <typename genUType>
 	template <typename genUType>
@@ -55,10 +57,12 @@ namespace glm
 		genUType const & y, 
 		genUType const & y, 
 		genUType & carry);
 		genUType & carry);
 
 
-	//! Subtracts the 32-bit unsigned integer y from x, returning
-	//! the difference if non-negative, or pow(2, 32) plus the difference
-	//! otherwise. The value borrow is set to 0 if x >= y, or to 1 otherwise.
-	//!
+	/// Subtracts the 32-bit unsigned integer y from x, returning
+	/// the difference if non-negative, or pow(2, 32) plus the difference
+	/// otherwise. The value borrow is set to 0 if x >= y, or to 1 otherwise.
+	///
+	/// @tparam genUType Unsigned integer scalar or vector types.
+	/// 
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/usubBorrow.xml">GLSL usubBorrow man page</a>
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/usubBorrow.xml">GLSL usubBorrow man page</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.8</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.8</a>
 	template <typename genUType>
 	template <typename genUType>
@@ -67,10 +71,12 @@ namespace glm
 		genUType const & y, 
 		genUType const & y, 
 		genUType & borrow);
 		genUType & borrow);
 		
 		
-	//! Multiplies 32-bit integers x and y, producing a 64-bit
-	//! result. The 32 least-significant bits are returned in lsb.
-	//! The 32 most-significant bits are returned in msb.
-	//!
+	/// Multiplies 32-bit integers x and y, producing a 64-bit
+	/// result. The 32 least-significant bits are returned in lsb.
+	/// The 32 most-significant bits are returned in msb.
+	///
+	/// @tparam genUType Unsigned integer scalar or vector types.
+	/// 
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/umulExtended.xml">GLSL umulExtended man page</a>
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/umulExtended.xml">GLSL umulExtended man page</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.8</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.8</a>
 	template <typename genUType>
 	template <typename genUType>
@@ -80,10 +86,12 @@ namespace glm
 		genUType & msb, 
 		genUType & msb, 
 		genUType & lsb);
 		genUType & lsb);
 		
 		
-	//! Multiplies 32-bit integers x and y, producing a 64-bit
-	//! result. The 32 least-significant bits are returned in lsb.
-	//! The 32 most-significant bits are returned in msb.
-	//!
+	/// Multiplies 32-bit integers x and y, producing a 64-bit
+	/// result. The 32 least-significant bits are returned in lsb.
+	/// The 32 most-significant bits are returned in msb.
+	/// 
+	/// @tparam genIType Signed integer scalar or vector types.
+	///
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/imulExtended.xml">GLSL imulExtended man page</a>
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/imulExtended.xml">GLSL imulExtended man page</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.8</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.8</a>
 	template <typename genIType>
 	template <typename genIType>
@@ -93,17 +101,19 @@ namespace glm
 		genIType & msb, 
 		genIType & msb, 
 		genIType & lsb);
 		genIType & lsb);
 
 
-	//! Extracts bits [offset, offset + bits - 1] from value,
-	//! returning them in the least significant bits of the result.
-	//! For unsigned data types, the most significant bits of the
-	//! result will be set to zero. For signed data types, the
-	//! most significant bits will be set to the value of bit offset + base – 1.
-	//!
-	//! If bits is zero, the result will be zero. The result will be
-	//! undefined if offset or bits is negative, or if the sum of
-	//! offset and bits is greater than the number of bits used
-	//! to store the operand.
-	//!
+	/// Extracts bits [offset, offset + bits - 1] from value,
+	/// returning them in the least significant bits of the result.
+	/// For unsigned data types, the most significant bits of the
+	/// result will be set to zero. For signed data types, the
+	/// most significant bits will be set to the value of bit offset + base – 1.
+	///
+	/// If bits is zero, the result will be zero. The result will be
+	/// undefined if offset or bits is negative, or if the sum of
+	/// offset and bits is greater than the number of bits used
+	/// to store the operand.
+	///
+	/// @tparam genIUType Signed or unsigned integer scalar or vector types.
+	/// 
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/bitfieldExtract.xml">GLSL bitfieldExtract man page</a>
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/bitfieldExtract.xml">GLSL bitfieldExtract man page</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.8</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.8</a>
 	template <typename genIUType>
 	template <typename genIUType>
@@ -112,16 +122,18 @@ namespace glm
 		int const & Offset, 
 		int const & Offset, 
 		int const & Bits);
 		int const & Bits);
 
 
-	//! Returns the insertion the bits least-significant bits of insert into base.
-	//!
-	//! The result will have bits [offset, offset + bits - 1] taken
-	//! from bits [0, bits – 1] of insert, and all other bits taken
-	//! directly from the corresponding bits of base. If bits is
-	//! zero, the result will simply be base. The result will be
-	//! undefined if offset or bits is negative, or if the sum of
-	//! offset and bits is greater than the number of bits used to
-	//! store the operand.
-	//!
+	/// Returns the insertion the bits least-significant bits of insert into base.
+	///
+	/// The result will have bits [offset, offset + bits - 1] taken
+	/// from bits [0, bits – 1] of insert, and all other bits taken
+	/// directly from the corresponding bits of base. If bits is
+	/// zero, the result will simply be base. The result will be
+	/// undefined if offset or bits is negative, or if the sum of
+	/// offset and bits is greater than the number of bits used to
+	/// store the operand.
+	///
+	/// @tparam genIUType Signed or unsigned integer scalar or vector types.
+	///
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/bitfieldInsert.xml">GLSL bitfieldInsert man page</a>
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/bitfieldInsert.xml">GLSL bitfieldInsert man page</a>
 	/// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.8</a>
 	/// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.8</a>
 	template <typename genIUType>
 	template <typename genIUType>
@@ -131,40 +143,54 @@ namespace glm
 		int const & Offset, 
 		int const & Offset, 
 		int const & Bits);
 		int const & Bits);
 
 
-	//! Returns the reversal of the bits of value. 
-	//! The bit numbered n of the result will be taken from bit (bits - 1) - n of value, 
-	//! where bits is the total number of bits used to represent value.
-	//!
+	/// Returns the reversal of the bits of value. 
+	/// The bit numbered n of the result will be taken from bit (bits - 1) - n of value, 
+	/// where bits is the total number of bits used to represent value.
+	///
+	/// @tparam genIUType Signed or unsigned integer scalar or vector types.
+	///
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/bitfieldReverse.xml">GLSL bitfieldReverse man page</a>
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/bitfieldReverse.xml">GLSL bitfieldReverse man page</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.8</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.8</a>
 	template <typename genIUType>
 	template <typename genIUType>
 	genIUType bitfieldReverse(genIUType const & value);
 	genIUType bitfieldReverse(genIUType const & value);
 		
 		
-	//! Returns the number of bits set to 1 in the binary representation of value.
-	//!
+	/// Returns the number of bits set to 1 in the binary representation of value.
+	///
+	/// @tparam genIUType Signed or unsigned integer scalar or vector types.
+	///
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/bitCount.xml">GLSL bitCount man page</a>
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/bitCount.xml">GLSL bitCount man page</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.8</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.8</a>
-	template <typename T, template <typename> class C>
-	typename C<T>::signed_type bitCount(C<T> const & Value);
+	///
+	/// @todo Clarify the declaration to specify that scalars are suported.
+	template <typename T, template <typename> class genIUType>
+	typename genIUType<T>::signed_type bitCount(genIUType<T> const & Value);
 
 
-	//! Returns the bit number of the least significant bit set to
-	//! 1 in the binary representation of value. 
-	//! If value is zero, -1 will be returned.
-	//!
+	/// Returns the bit number of the least significant bit set to
+	/// 1 in the binary representation of value. 
+	/// If value is zero, -1 will be returned.
+	///
+	/// @tparam genIUType Signed or unsigned integer scalar or vector types.
+	///
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/findLSB.xml">GLSL findLSB man page</a>
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/findLSB.xml">GLSL findLSB man page</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.8</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.8</a>
-	template <typename T, template <typename> class C>
-	typename C<T>::signed_type findLSB(C<T> const & Value);
+	///
+	/// @todo Clarify the declaration to specify that scalars are suported.
+	template <typename T, template <typename> class genIUType>
+	typename genIUType<T>::signed_type findLSB(genIUType<T> const & Value);
 
 
-	//! Returns the bit number of the most significant bit in the binary representation of value.
-	//! For positive integers, the result will be the bit number of the most significant bit set to 1. 
-	//! For negative integers, the result will be the bit number of the most significant
-	//! bit set to 0. For a value of zero or negative one, -1 will be returned.
-	//!
+	/// Returns the bit number of the most significant bit in the binary representation of value.
+	/// For positive integers, the result will be the bit number of the most significant bit set to 1. 
+	/// For negative integers, the result will be the bit number of the most significant
+	/// bit set to 0. For a value of zero or negative one, -1 will be returned.
+	///
+	/// @tparam genIUType Signed or unsigned integer scalar or vector types.
+	///
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/findMSB.xml">GLSL findMSB man page</a>
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/findMSB.xml">GLSL findMSB man page</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.8</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.8</a>
-	template <typename T, template <typename> class C>
-	typename C<T>::signed_type findMSB(C<T> const & Value);
+	///
+	/// @todo Clarify the declaration to specify that scalars are suported.
+	template <typename T, template <typename> class genIUType>
+	typename genIUType<T>::signed_type findMSB(genIUType<T> const & Value);
 
 
 	/// @}
 	/// @}
 }//namespace glm
 }//namespace glm

+ 2 - 35
glm/core/func_integer.inl

@@ -26,6 +26,7 @@
 /// @author Christophe Riccio
 /// @author Christophe Riccio
 ///////////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////////
 
 
+#include "_vectorize.hpp"
 #if(GLM_COMPILER & GLM_COMPILER_VC)
 #if(GLM_COMPILER & GLM_COMPILER_VC)
 #include <intrin.h>
 #include <intrin.h>
 #pragma intrinsic(_BitScanReverse)
 #pragma intrinsic(_BitScanReverse)
@@ -415,41 +416,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>

+ 38 - 18
glm/core/func_matrix.hpp

@@ -47,6 +47,8 @@ namespace glm
 
 
 	/// Multiply matrix x by matrix y component-wise, i.e., 
 	/// Multiply matrix x by matrix y component-wise, i.e., 
 	/// result[i][j] is the scalar product of x[i][j] and y[i][j].
 	/// result[i][j] is the scalar product of x[i][j] and y[i][j].
+	/// 
+	/// @tparam matType Floating-point matrix types.
     ///
     ///
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/matrixCompMult.xml">GLSL matrixCompMult man page</a>
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/matrixCompMult.xml">GLSL matrixCompMult man page</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.6</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.6</a>
@@ -58,15 +60,21 @@ namespace glm
 	/// Treats the first parameter c as a column vector 
 	/// Treats the first parameter c as a column vector 
 	/// and the second parameter r as a row vector
 	/// and the second parameter r as a row vector
 	/// and does a linear algebraic matrix multiply c * r.
 	/// and does a linear algebraic matrix multiply c * r.
+	/// 
+	/// @tparam matType Floating-point matrix types.
     ///
     ///
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/outerProduct.xml">GLSL outerProduct man page</a>
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/outerProduct.xml">GLSL outerProduct man page</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.6</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.6</a>
+	/// 
+	/// @todo Clarify the declaration to specify that matType doesn't have to be provided when used.
     template <typename vecType, typename matType> 
     template <typename vecType, typename matType> 
 	matType outerProduct(
 	matType outerProduct(
 		vecType const & c, 
 		vecType const & c, 
 		vecType const & r);
 		vecType const & r);
 
 
 	/// Returns the transposed matrix of x
 	/// Returns the transposed matrix of x
+	/// 
+	/// @tparam matType Floating-point matrix types.
     ///
     ///
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/transpose.xml">GLSL transpose man page</a>
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/transpose.xml">GLSL transpose man page</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.6</a>	
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.6</a>	
@@ -75,52 +83,64 @@ namespace glm
 		matType const & x);
 		matType const & x);
 	
 	
 	/// Return the determinant of a mat2 matrix. 
 	/// Return the determinant of a mat2 matrix. 
+	/// 
+	/// @tparam valType Floating-point scalar types.
     ///
     ///
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/determinant.xml">GLSL determinant man page</a>
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/determinant.xml">GLSL determinant man page</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.6</a>	
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.6</a>	
-	template <typename T> 
-	typename detail::tmat2x2<T>::value_type determinant(
-		detail::tmat2x2<T> const & m);
+	template <typename valType> 
+	typename detail::tmat2x2<valType>::value_type determinant(
+		detail::tmat2x2<valType> const & m);
 
 
 	/// Return the determinant of a mat3 matrix. 
 	/// Return the determinant of a mat3 matrix. 
+	/// 
+	/// @tparam valType Floating-point scalar types.
     ///
     ///
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/determinant.xml">GLSL determinant man page</a>
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/determinant.xml">GLSL determinant man page</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.6</a>	
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.6</a>	
-	template <typename T> 
-	typename detail::tmat3x3<T>::value_type determinant(
-		detail::tmat3x3<T> const & m);
+	template <typename valType> 
+	typename detail::tmat3x3<valType>::value_type determinant(
+		detail::tmat3x3<valType> const & m);
 
 
 	/// Return the determinant of a mat4 matrix. 
 	/// Return the determinant of a mat4 matrix. 
+	/// 
+	/// @tparam valType Floating-point scalar types.
     ///
     ///
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/determinant.xml">GLSL determinant man page</a>
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/determinant.xml">GLSL determinant man page</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.6</a>		
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.6</a>		
-    template <typename T> 
-	typename detail::tmat4x4<T>::value_type determinant(
-		detail::tmat4x4<T> const & m);
+    template <typename valType> 
+	typename detail::tmat4x4<valType>::value_type determinant(
+		detail::tmat4x4<valType> const & m);
 
 
 	/// Return the inverse of a mat2 matrix. 
 	/// Return the inverse of a mat2 matrix. 
+	/// 
+	/// @tparam valType Floating-point scalar types.
     ///
     ///
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/inverse.xml">GLSL inverse man page</a>
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/inverse.xml">GLSL inverse man page</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.6</a>	 
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.6</a>	 
-	template <typename T> 
-	detail::tmat2x2<T> inverse(
-		detail::tmat2x2<T> const & m);
+	template <typename valType> 
+	detail::tmat2x2<valType> inverse(
+		detail::tmat2x2<valType> const & m);
 
 
 	/// Return the inverse of a mat3 matrix. 
 	/// Return the inverse of a mat3 matrix. 
+	/// 
+	/// @tparam valType Floating-point scalar types.
     ///
     ///
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/inverse.xml">GLSL inverse man page</a>
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/inverse.xml">GLSL inverse man page</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.6</a> 
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.6</a> 
-	template <typename T> 
-	detail::tmat3x3<T> inverse(
-		detail::tmat3x3<T> const & m);
+	template <typename valType> 
+	detail::tmat3x3<valType> inverse(
+		detail::tmat3x3<valType> const & m);
 
 
 	/// Return the inverse of a mat4 matrix. 
 	/// Return the inverse of a mat4 matrix. 
+	/// 
+	/// @tparam valType Floating-point scalar types.
     ///
     ///
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/inverse.xml">GLSL inverse man page</a>
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/inverse.xml">GLSL inverse man page</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.6</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.6</a>
-	template <typename T> 
-	detail::tmat4x4<T> inverse(
-		detail::tmat4x4<T> const & m);
+	template <typename valType> 
+	detail::tmat4x4<valType> inverse(
+		detail::tmat4x4<valType> const & m);
 
 
 	/// @}
 	/// @}
 }//namespace glm
 }//namespace glm

+ 2 - 0
glm/core/func_matrix.inl

@@ -26,6 +26,8 @@
 /// @author Christophe Riccio
 /// @author Christophe Riccio
 ///////////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////////
 
 
+#include "_vectorize.hpp"
+
 namespace glm
 namespace glm
 {
 {
 	// matrixCompMult
 	// matrixCompMult

+ 8 - 0
glm/core/func_noise.hpp

@@ -44,6 +44,8 @@ namespace glm
 	/// @{
 	/// @{
 
 
 	/// Returns a 1D noise value based on the input value x.
 	/// Returns a 1D noise value based on the input value x.
+	///
+	/// @tparam genType Floating-point scalar or vector types.
     /// 
     /// 
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/noise1.xml">GLSL noise1 man page</a>
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/noise1.xml">GLSL noise1 man page</a>
 	/// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.13</a>
 	/// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.13</a>
@@ -51,6 +53,8 @@ namespace glm
 	typename genType::value_type noise1(genType const & x);
 	typename genType::value_type noise1(genType const & x);
 
 
 	/// Returns a 2D noise value based on the input value x.
 	/// Returns a 2D noise value based on the input value x.
+	///
+	/// @tparam genType Floating-point scalar or vector types.
     /// 
     /// 
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/noise2.xml">GLSL noise2 man page</a>
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/noise2.xml">GLSL noise2 man page</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.13</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.13</a>
@@ -58,6 +62,8 @@ namespace glm
 	detail::tvec2<typename genType::value_type> noise2(genType const & x);
 	detail::tvec2<typename genType::value_type> noise2(genType const & x);
 
 
 	/// Returns a 3D noise value based on the input value x.
 	/// Returns a 3D noise value based on the input value x.
+	///
+	/// @tparam genType Floating-point scalar or vector types.
     /// 
     /// 
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/noise3.xml">GLSL noise3 man page</a>
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/noise3.xml">GLSL noise3 man page</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.13</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.13</a>
@@ -65,6 +71,8 @@ namespace glm
 	detail::tvec3<typename genType::value_type> noise3(genType const & x);
 	detail::tvec3<typename genType::value_type> noise3(genType const & x);
 
 
 	/// Returns a 4D noise value based on the input value x.
 	/// Returns a 4D noise value based on the input value x.
+	///
+	/// @tparam genType Floating-point scalar or vector types.
     /// 
     /// 
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/noise4.xml">GLSL noise4 man page</a>
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/noise4.xml">GLSL noise4 man page</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.13</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.13</a>

+ 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

+ 73 - 43
glm/core/func_trigonometric.hpp

@@ -45,119 +45,149 @@ namespace glm
 	/// @addtogroup core_func_trigonometric
 	/// @addtogroup core_func_trigonometric
 	/// @{
 	/// @{
 
 
-	//! Converts degrees to radians and returns the result.
-    //!
+	/// Converts degrees to radians and returns the result.
+	///
+	/// @tparam genType Floating-point scalar or vector types.
+    ///
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/radians.xml">GLSL radians man page</a>
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/radians.xml">GLSL radians man page</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.1</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.1</a>
 	template <typename genType> 
 	template <typename genType> 
 	genType radians(genType const & degrees);
 	genType radians(genType const & degrees);
 
 
-	//! Converts radians to degrees and returns the result.
-    //!
+	/// Converts radians to degrees and returns the result.
+    ///
+	/// @tparam genType Floating-point scalar or vector types.
+	/// 
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/degrees.xml">GLSL degrees man page</a>
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/degrees.xml">GLSL degrees man page</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.1</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.1</a>
 	template <typename genType> 
 	template <typename genType> 
 	genType degrees(genType const & radians);
 	genType degrees(genType const & radians);
 
 
-	//! The standard trigonometric sine function. 
-	//! The values returned by this function will range from [-1, 1].
-    //!
+	/// The standard trigonometric sine function. 
+	/// The values returned by this function will range from [-1, 1].
+	/// 
+	/// @tparam genType Floating-point scalar or vector types.
+    ///
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/sin.xml">GLSL sin man page</a>
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/sin.xml">GLSL sin man page</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.1</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.1</a>
 	template <typename genType> 
 	template <typename genType> 
 	genType sin(genType const & angle);
 	genType sin(genType const & angle);
 
 
-	//! The standard trigonometric cosine function. 
-	//! The values returned by this function will range from [-1, 1].
-    //!
+	/// The standard trigonometric cosine function. 
+	/// The values returned by this function will range from [-1, 1].
+	/// 
+	/// @tparam genType Floating-point scalar or vector types.
+    ///
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/cos.xml">GLSL cos man page</a>
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/cos.xml">GLSL cos man page</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.1</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.1</a>
 	template <typename genType> 
 	template <typename genType> 
 	genType cos(genType const & angle);
 	genType cos(genType const & angle);
 
 
-	//! The standard trigonometric tangent function.
-    //!
+	/// The standard trigonometric tangent function.
+    ///
+	/// @tparam genType Floating-point scalar or vector types.
+	/// 
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/tan.xml">GLSL tan man page</a>
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/tan.xml">GLSL tan man page</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.1</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.1</a>
 	template <typename genType> 
 	template <typename genType> 
 	genType tan(genType const & angle); 
 	genType tan(genType const & angle); 
 
 
-	//! Arc sine. Returns an angle whose sine is x. 
-	//! The range of values returned by this function is [-PI/2, PI/2]. 
-	//! Results are undefined if |x| > 1.
-    //!
+	/// Arc sine. Returns an angle whose sine is x. 
+	/// The range of values returned by this function is [-PI/2, PI/2]. 
+	/// Results are undefined if |x| > 1.
+    ///
+	/// @tparam genType Floating-point scalar or vector types.
+	/// 
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/asin.xml">GLSL asin man page</a>
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/asin.xml">GLSL asin man page</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.1</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.1</a>
 	template <typename genType> 
 	template <typename genType> 
 	genType asin(genType const & x);
 	genType asin(genType const & x);
 
 
-	//! Arc cosine. Returns an angle whose sine is x. 
-	//! The range of values returned by this function is [0, PI]. 
-	//! Results are undefined if |x| > 1.
-    //!
+	/// Arc cosine. Returns an angle whose sine is x. 
+	/// The range of values returned by this function is [0, PI]. 
+	/// Results are undefined if |x| > 1.
+    ///
+	/// @tparam genType Floating-point scalar or vector types.
+	/// 
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/acos.xml">GLSL acos man page</a>
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/acos.xml">GLSL acos man page</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.1</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.1</a>
 	template <typename genType> 
 	template <typename genType> 
 	genType acos(genType const & x);
 	genType acos(genType const & x);
 
 
-	//! Arc tangent. Returns an angle whose tangent is y/x. 
-	//! The signs of x and y are used to determine what 
-	//! quadrant the angle is in. The range of values returned 
-	//! by this function is [-PI, PI]. Results are undefined 
-	//! if x and y are both 0. 
-    //!
+	/// Arc tangent. Returns an angle whose tangent is y/x. 
+	/// The signs of x and y are used to determine what 
+	/// quadrant the angle is in. The range of values returned 
+	/// by this function is [-PI, PI]. Results are undefined 
+	/// if x and y are both 0. 
+    ///
+	/// @tparam genType Floating-point scalar or vector types.
+	/// 
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/atan.xml">GLSL atan man page</a>
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/atan.xml">GLSL atan man page</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.1</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.1</a>
 	template <typename genType> 
 	template <typename genType> 
 	genType atan(genType const & y, genType const & x);
 	genType atan(genType const & y, genType const & x);
 
 
-	//! Arc tangent. Returns an angle whose tangent is y_over_x. 
-	//! The range of values returned by this function is [-PI/2, PI/2].
-    //!
+	/// Arc tangent. Returns an angle whose tangent is y_over_x. 
+	/// The range of values returned by this function is [-PI/2, PI/2].
+    ///
+	/// @tparam genType Floating-point scalar or vector types.
+	/// 
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/atan.xml">GLSL atan man page</a>
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/atan.xml">GLSL atan man page</a>
 	/// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.1</a>
 	/// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.1</a>
 	template <typename genType> 
 	template <typename genType> 
 	genType atan(genType const & y_over_x);
 	genType atan(genType const & y_over_x);
 
 
-	//! Returns the hyperbolic sine function, (exp(x) - exp(-x)) / 2
-    //!
+	/// Returns the hyperbolic sine function, (exp(x) - exp(-x)) / 2
+    ///
+	/// @tparam genType Floating-point scalar or vector types.
+	/// 
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/sinh.xml">GLSL sinh man page</a>
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/sinh.xml">GLSL sinh man page</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.1</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.1</a>
 	template <typename genType> 
 	template <typename genType> 
 	genType sinh(genType const & angle);
 	genType sinh(genType const & angle);
 
 
-	//! Returns the hyperbolic cosine function, (exp(x) + exp(-x)) / 2
-    //!
+	/// Returns the hyperbolic cosine function, (exp(x) + exp(-x)) / 2
+    ///
+	/// @tparam genType Floating-point scalar or vector types.
+	/// 
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/cosh.xml">GLSL cosh man page</a>
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/cosh.xml">GLSL cosh man page</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.1</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.1</a>
 	template <typename genType> 
 	template <typename genType> 
 	genType cosh(genType const & angle);
 	genType cosh(genType const & angle);
 
 
-	//! Returns the hyperbolic tangent function, sinh(angle) / cosh(angle)
-    //!
+	/// Returns the hyperbolic tangent function, sinh(angle) / cosh(angle)
+    ///
+	/// @tparam genType Floating-point scalar or vector types.
+	/// 
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/tanh.xml">GLSL tanh man page</a>
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/tanh.xml">GLSL tanh man page</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.1</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.1</a>
 	template <typename genType> 
 	template <typename genType> 
 	genType tanh(genType const & angle);
 	genType tanh(genType const & angle);
 
 
-	//! Arc hyperbolic sine; returns the inverse of sinh.
-    //!
+	/// Arc hyperbolic sine; returns the inverse of sinh.
+    ///
+	/// @tparam genType Floating-point scalar or vector types.
+	/// 
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/asinh.xml">GLSL asinh man page</a>
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/asinh.xml">GLSL asinh man page</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.1</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.1</a>
 	template <typename genType> 
 	template <typename genType> 
 	genType asinh(genType const & x);
 	genType asinh(genType const & x);
 	
 	
-	//! Arc hyperbolic cosine; returns the non-negative inverse
-	//! of cosh. Results are undefined if x < 1.
-    //!
+	/// Arc hyperbolic cosine; returns the non-negative inverse
+	/// of cosh. Results are undefined if x < 1.
+    ///
+	/// @tparam genType Floating-point scalar or vector types.
+	/// 
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/acosh.xml">GLSL acosh man page</a>
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/acosh.xml">GLSL acosh man page</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.1</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.1</a>
 	template <typename genType> 
 	template <typename genType> 
 	genType acosh(genType const & x);
 	genType acosh(genType const & x);
 
 
-	//! Arc hyperbolic tangent; returns the inverse of tanh.
-	//! Results are undefined if abs(x) >= 1.
-    //!
+	/// Arc hyperbolic tangent; returns the inverse of tanh.
+	/// Results are undefined if abs(x) >= 1.
+	///
+	/// @tparam genType Floating-point scalar or vector types.
+    ///
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/atanh.xml">GLSL atanh man page</a>
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/atanh.xml">GLSL atanh man page</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.1</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.1</a>
 	template <typename genType> 
 	template <typename genType> 

+ 214 - 725
glm/core/func_trigonometric.inl

@@ -26,732 +26,221 @@
 /// @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");
+#include "_vectorize.hpp"
+
+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");
+
+		genType const pi = genType(3.1415926535897932384626433832795);
+		return degrees * (pi / genType(180));
+	}
+
+	VECTORIZE_VEC(radians)
+	
+	// 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);
+	}
+
+	VECTORIZE_VEC(degrees)
+
+	// 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);
+	}
+
+	VECTORIZE_VEC(sin)
+
+	// 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);
+	}
+
+	VECTORIZE_VEC(cos)
+
+	// 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);
+	}
+
+	VECTORIZE_VEC(tan)
+
+	// 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);
+	}
+
+	VECTORIZE_VEC(asin)
+
+	// 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);
+	}
+
+	VECTORIZE_VEC(acos)
+
+	// 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);
+	}
+
+	VECTORIZE_VEC_VEC(atan)
+
+	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);
+	}
+
+	VECTORIZE_VEC(atan)
+
+	// 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);
+	}
+
+	VECTORIZE_VEC(sinh)
+
+	// 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);
+	}
+
+	VECTORIZE_VEC(cosh)
+
+	// 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);
+	}
+
+	VECTORIZE_VEC(tanh)
+
+	// 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));
+	}
+
+	VECTORIZE_VEC(asinh)
+
+	// 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)));
+	}
+
+	VECTORIZE_VEC(acosh)
+
+	// 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));
+	}
+
+	VECTORIZE_VEC(atanh)
 
 
 }//namespace glm
 }//namespace glm

+ 41 - 23
glm/core/func_vector_relational.hpp

@@ -48,65 +48,83 @@ namespace glm
 	/// @addtogroup core_func_vector_relational
 	/// @addtogroup core_func_vector_relational
 	/// @{
 	/// @{
 
 
-	//! Returns the component-wise comparison result of x < y.
-    //!
+	/// Returns the component-wise comparison result of x < y.
+	/// 
+	/// @tparam vecType Floating-point or integer vector types.
+    ///
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/lessThan.xml">GLSL lessThan man page</a>
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/lessThan.xml">GLSL lessThan man page</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.7</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.7</a>
-    //template <typename T, template <typename> class vecType> 
-	//GLM_FUNC_QUALIFIER typename vecType<T>::bool_type lessThan(vecType<T> const & x, vecType<T> const & y);
+    template <typename vecType> 
+	GLM_FUNC_QUALIFIER typename vecType::bool_type lessThan(vecType const & x, vecType const & y);
 
 
-	//! Returns the component-wise comparison of result x <= y.
-    //!
+	/// Returns the component-wise comparison of result x <= y.
+    ///
+	/// @tparam vecType Floating-point or integer vector types.
+	///
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/lessThanEqual.xml">GLSL lessThanEqual man page</a>
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/lessThanEqual.xml">GLSL lessThanEqual man page</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.7</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.7</a>
 	template <typename T, template <typename> class vecType> 
 	template <typename T, template <typename> class vecType> 
 	GLM_FUNC_QUALIFIER typename vecType<T>::bool_type lessThanEqual(vecType<T> const & x, vecType<T> const & y);
 	GLM_FUNC_QUALIFIER typename vecType<T>::bool_type lessThanEqual(vecType<T> const & x, vecType<T> const & y);
 
 
-	//! Returns the component-wise comparison of result x > y.
-    //!
+	/// Returns the component-wise comparison of result x > y.
+    ///
+	/// @tparam vecType Floating-point or integer vector types.
+	/// 
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/greaterThan.xml">GLSL greaterThan man page</a>
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/greaterThan.xml">GLSL greaterThan man page</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.7</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.7</a>
 	template <typename T, template <typename> class vecType> 
 	template <typename T, template <typename> class vecType> 
 	GLM_FUNC_QUALIFIER typename vecType<T>::bool_type greaterThan(vecType<T> const & x, vecType<T> const & y);
 	GLM_FUNC_QUALIFIER typename vecType<T>::bool_type greaterThan(vecType<T> const & x, vecType<T> const & y);
 
 
-	//! Returns the component-wise comparison of result x >= y.
-    //!
+	/// Returns the component-wise comparison of result x >= y.
+    ///
+	/// @tparam vecType Floating-point or integer vector types.
+	/// 
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/greaterThanEqual.xml">GLSL greaterThanEqual man page</a>
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/greaterThanEqual.xml">GLSL greaterThanEqual man page</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.7</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.7</a>
 	template <typename T, template <typename> class vecType> 
 	template <typename T, template <typename> class vecType> 
 	typename vecType<T>::bool_type greaterThanEqual(vecType<T> const & x, vecType<T> const & y);
 	typename vecType<T>::bool_type greaterThanEqual(vecType<T> const & x, vecType<T> const & y);
 
 
-	//! Returns the component-wise comparison of result x == y.
-    //!
+	/// Returns the component-wise comparison of result x == y.
+    ///
+	/// @tparam vecType Floating-point, integer or boolean vector types.
+	/// 
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/equal.xml">GLSL equal man page</a>
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/equal.xml">GLSL equal man page</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.7</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.7</a>
-	//template <typename T, template <typename> class vecType> 
-	//GLM_FUNC_QUALIFIER typename vecType<T>::bool_type equal(vecType<T> const & x, vecType<T> const & y);
+	template <typename T, template <typename> class vecType> 
+	GLM_FUNC_QUALIFIER typename vecType<T>::bool_type equal(vecType<T> const & x, vecType<T> const & y);
 
 
-	//! Returns the component-wise comparison of result x != y.
-    //!
+	/// Returns the component-wise comparison of result x != y.
+	/// 
+	/// @tparam vecType Floating-point, integer or boolean vector types.
+    ///
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/notEqual.xml">GLSL notEqual man page</a>
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/notEqual.xml">GLSL notEqual man page</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.7</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.7</a>
 	template <typename T, template <typename> class vecType> 
 	template <typename T, template <typename> class vecType> 
 	typename vecType<T>::bool_type notEqual(vecType<T> const & x, vecType<T> const & y);
 	typename vecType<T>::bool_type notEqual(vecType<T> const & x, vecType<T> const & y);
 
 
-	//! Returns true if any component of x is true.
-    //!
+	/// Returns true if any component of x is true.
+	///
+	/// @tparam vecType Boolean vector types.
+    /// 
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/any.xml">GLSL any man page</a>
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/any.xml">GLSL any man page</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.7</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.7</a>
 	template <template <typename> class vecType> 
 	template <template <typename> class vecType> 
 	bool any(vecType<bool> const & v);
 	bool any(vecType<bool> const & v);
 
 
-	//! Returns true if all components of x are true.
-    //!
+	/// Returns true if all components of x are true.
+	///
+	/// @tparam vecType Boolean vector types.
+    ///
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/all.xml">GLSL all man page</a>
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/all.xml">GLSL all man page</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.7</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.7</a>
 	template <template <typename> class vecType> 
 	template <template <typename> class vecType> 
 	bool all(vecType<bool> const & v);
 	bool all(vecType<bool> const & v);
 
 
-	//! Returns the component-wise logical complement of x.
-    //! /!\ Because of language incompatibilities between C++ and GLSL, GLM defines the function not but not_ instead.
-    //!
+	/// Returns the component-wise logical complement of x.
+    /// /!\ Because of language incompatibilities between C++ and GLSL, GLM defines the function not but not_ instead.
+	///
+	/// @tparam vecType Boolean vector types.
+    ///
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/not.xml">GLSL not man page</a>
     /// @see - <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/not.xml">GLSL not man page</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.7</a>
     /// @see - <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.7</a>
 	template <template <typename> class vecType> 
 	template <template <typename> class vecType> 

+ 487 - 975
glm/gtc/half_float.inl

@@ -27,981 +27,493 @@
 ///////////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////////
 
 
 namespace glm{
 namespace glm{
-namespace detail{
-
-#if 0//ndef _MSC_EXTENSIONS
-
-//////////////////////////////////////
-// hvec2
-
-GLM_FUNC_QUALIFIER tvec2<thalf>::size_type tvec2<thalf>::length() const
-{
-    return 2;
-}
-
-GLM_FUNC_QUALIFIER tvec2<thalf>::size_type tvec2<thalf>::value_size()
-{
-	return 2;
-}
-
-//////////////////////////////////////
-// Accesses
-
-GLM_FUNC_QUALIFIER thalf & tvec2<thalf>::operator[](tvec2<thalf>::size_type i)
-{
-	assert(/*i >= tvec2<thalf>::size_type(0) && */i < tvec2<thalf>::value_size());
-	return (&x)[i];
-}
-
-GLM_FUNC_QUALIFIER thalf const & tvec2<thalf>::operator[](tvec2<thalf>::size_type i) const
-{
-	assert(/*i >= tvec2<thalf>::size_type(0) && */i < tvec2<thalf>::value_size());
-	return (&x)[i];
-}
-
-//////////////////////////////////////
-// Implicit basic constructors
-
-GLM_FUNC_QUALIFIER tvec2<thalf>::tvec2() :
-	x(thalf(0.f)),
-	y(thalf(0.f))
-{}
-
-GLM_FUNC_QUALIFIER tvec2<thalf>::tvec2
-(
-	tvec2<thalf> const & v
-) :
-	x(v.x),
-	y(v.y)
-{}
-
-//////////////////////////////////////
-// Explicit basic constructors
-
-GLM_FUNC_QUALIFIER tvec2<thalf>::tvec2
-(
-	thalf const & s
-) :
-	x(s),
-	y(s)
-{}
-
-GLM_FUNC_QUALIFIER tvec2<thalf>::tvec2
-(
-	thalf const & s1, 
-	thalf const & s2
-) :
-	x(s1),
-	y(s2)
-{}
-
-//////////////////////////////////////
-// Swizzle constructors
-
-GLM_FUNC_QUALIFIER tvec2<thalf>::tvec2
-(
-	tref2<thalf> const & r
-) :
-	x(r.x),
-	y(r.y)
-{}
-
-//////////////////////////////////////
-// Convertion scalar constructors
-
-template <typename U> 
-GLM_FUNC_QUALIFIER tvec2<thalf>::tvec2
-(
-	U const & x
-) :
-	x(thalf(x)),
-	y(thalf(x))
-{}
-
-template <typename U, typename V> 
-GLM_FUNC_QUALIFIER tvec2<thalf>::tvec2
-(
-	U const & x, 
-	V const & y
-) :
-	x(thalf(x)),
-	y(thalf(y))
-{}
-
-//////////////////////////////////////
-// Convertion vector constructors
-
-template <typename U> 
-GLM_FUNC_QUALIFIER tvec2<thalf>::tvec2
-(
-	tvec2<U> const & v
-) :
-	x(thalf(v.x)),
-	y(thalf(v.y))
-{}
-
-template <typename U> 
-GLM_FUNC_QUALIFIER tvec2<thalf>::tvec2
-(	
-	tvec3<U> const & v
-) :
-	x(thalf(v.x)),
-	y(thalf(v.y))
-{}
-
-template <typename U> 
-GLM_FUNC_QUALIFIER tvec2<thalf>::tvec2
-(
-	tvec4<U> const & v
-) :
-	x(thalf(v.x)),
-	y(thalf(v.y))
-{}
-
-//////////////////////////////////////
-// Unary arithmetic operators
-
-GLM_FUNC_QUALIFIER tvec2<thalf> & tvec2<thalf>::operator= 
-(
-	tvec2<thalf> const & v
-)
-{
-	this->x = v.x;
-	this->y = v.y;
-	return *this;
-}
-
-GLM_FUNC_QUALIFIER tvec2<thalf> & tvec2<thalf>::operator+=
-(
-	thalf const & s
-)
-{
-	this->x += s;
-	this->y += s;
-	return *this;
-}
-
-GLM_FUNC_QUALIFIER tvec2<thalf> & tvec2<thalf>::operator+=
-(
-	tvec2<thalf> const & v
-)
-{
-	this->x += v.x;
-	this->y += v.y;
-	return *this;
-}
-
-GLM_FUNC_QUALIFIER tvec2<thalf> & tvec2<thalf>::operator-=
-(
-	thalf const & s
-)
-{
-	this->x -= s;
-	this->y -= s;
-	return *this;
-}
-
-GLM_FUNC_QUALIFIER tvec2<thalf> & tvec2<thalf>::operator-=
-(
-	tvec2<thalf> const & v
-)
-{
-	this->x -= v.x;
-	this->y -= v.y;
-	return *this;
-}
-
-GLM_FUNC_QUALIFIER tvec2<thalf>& tvec2<thalf>::operator*=
-(
-	thalf const & s
-)
-{
-	this->x *= s;
-	this->y *= s;
-	return *this;
-}
-
-GLM_FUNC_QUALIFIER tvec2<thalf> & tvec2<thalf>::operator*=
-(
-	tvec2<thalf> const & v
-)
-{
-	this->x *= v.x;
-	this->y *= v.y;
-	return *this;
-}
-
-GLM_FUNC_QUALIFIER tvec2<thalf> & tvec2<thalf>::operator/=
-(
-	thalf const & s
-)
-{
-	this->x /= s;
-	this->y /= s;
-	return *this;
-}
-
-GLM_FUNC_QUALIFIER tvec2<thalf> & tvec2<thalf>::operator/=
-(
-	tvec2<thalf> const & v
-)
-{
-	this->x /= v.x;
-	this->y /= v.y;
-	return *this;
-}
-
-GLM_FUNC_QUALIFIER tvec2<thalf> & tvec2<thalf>::operator++()
-{
-	++this->x;
-	++this->y;
-	return *this;
-}
-
-GLM_FUNC_QUALIFIER tvec2<thalf>& tvec2<thalf>::operator--()
-{
-	--this->x;
-	--this->y;
-	return *this;
-}
-
-//////////////////////////////////////
-// Swizzle operators
-
-GLM_FUNC_QUALIFIER thalf tvec2<thalf>::swizzle(comp x) const
-{
-	return (*this)[x];
-}
-
-GLM_FUNC_QUALIFIER tvec2<thalf> tvec2<thalf>::swizzle(comp x, comp y) const
-{
-	return tvec2<thalf>(
-		(*this)[x],
-		(*this)[y]);
-}
-
-GLM_FUNC_QUALIFIER tvec3<thalf> tvec2<thalf>::swizzle(comp x, comp y, comp z) const
-{
-	return tvec3<thalf>(
-		(*this)[x],
-		(*this)[y],
-		(*this)[z]);
-}
-
-GLM_FUNC_QUALIFIER tvec4<thalf> tvec2<thalf>::swizzle(comp x, comp y, comp z, comp w) const
-{
-	return tvec4<thalf>(
-		(*this)[x],
-		(*this)[y],
-		(*this)[z],
-		(*this)[w]);
-}
-
-GLM_FUNC_QUALIFIER tref2<thalf> tvec2<thalf>::swizzle(comp x, comp y)
-{
-	return tref2<thalf>(
-		(*this)[x],
-		(*this)[y]);
-}
-
-//////////////////////////////////////
-// hvec3
-
-GLM_FUNC_QUALIFIER tvec3<thalf>::size_type tvec3<thalf>::length() const
-{
-    return 3;
-}
-
-GLM_FUNC_QUALIFIER tvec3<thalf>::size_type tvec3<thalf>::value_size()
-{
-	return 3;
-}
-
-//////////////////////////////////////
-// Accesses
-
-GLM_FUNC_QUALIFIER thalf & tvec3<thalf>::operator[]
-(
-	tvec3<thalf>::size_type i
-)
-{
-	assert(/*i >= tvec3<thalf>::size_type(0) &&*/ i < tvec3<thalf>::value_size());
-
-	return (&x)[i];
-}
-
-GLM_FUNC_QUALIFIER thalf const & tvec3<thalf>::operator[]
-(
-	tvec3<thalf>::size_type i
-) const
-{
-	assert(/*i >= tvec3<thalf>::size_type(0) &&*/ i < tvec3<thalf>::value_size());
-
-	return (&x)[i];
-}
-
-//////////////////////////////////////
-// Implicit basic constructors
-
-GLM_FUNC_QUALIFIER tvec3<thalf>::tvec3() :
-	x(thalf(0)),
-	y(thalf(0)),
-	z(thalf(0))
-{}
-
-GLM_FUNC_QUALIFIER tvec3<thalf>::tvec3
-(
-	tvec3<thalf> const & v
-) :
-	x(v.x),
-	y(v.y),
-	z(v.z)
-{}
-
-//////////////////////////////////////
-// Explicit basic constructors
-
-GLM_FUNC_QUALIFIER tvec3<thalf>::tvec3
-(
-	thalf const & s
-) :
-	x(s),
-	y(s),
-	z(s)
-{}
-
-GLM_FUNC_QUALIFIER tvec3<thalf>::tvec3
-(
-	thalf const & s0, 
-	thalf const & s1, 
-	thalf const & s2
-) :
-	x(s0),
-	y(s1),
-	z(s2)
-{}
-
-//////////////////////////////////////
-// Swizzle constructors
-
-GLM_FUNC_QUALIFIER tvec3<thalf>::tvec3
-(
-	tref3<thalf> const & r
-) :
-	x(r.x),
-	y(r.y),
-	z(r.z)
-{}
-
-//////////////////////////////////////
-// Convertion scalar constructors
-
-template <typename U> 
-GLM_FUNC_QUALIFIER tvec3<thalf>::tvec3
-(
-	U const & x
-) :
-	x(thalf(x)),
-	y(thalf(x)),
-	z(thalf(x))
-{}
-
-template <typename A, typename B, typename C> 
-GLM_FUNC_QUALIFIER tvec3<thalf>::tvec3
-(
-	A const & x, 
-	B const & y, 
-	C const & z
-) :
-	x(thalf(x)),
-	y(thalf(y)),
-	z(thalf(z))
-{}
-
-//////////////////////////////////////
-// Convertion vector constructors
-
-template <typename A, typename B> 
-GLM_FUNC_QUALIFIER tvec3<thalf>::tvec3
-(
-	tvec2<A> const & v, 
-	B const & s
-) :
-	x(thalf(v.x)),
-	y(thalf(v.y)),
-	z(thalf(s))
-{}
-
-template <typename A, typename B> 
-GLM_FUNC_QUALIFIER tvec3<thalf>::tvec3
-(
-	A const & s, 
-	tvec2<B> const & v
-) :
-	x(thalf(s)),
-	y(thalf(v.x)),
-	z(thalf(v.y))
-{}
-
-template <typename U> 
-GLM_FUNC_QUALIFIER tvec3<thalf>::tvec3
-(
-	tvec3<U> const & v
-) :
-	x(thalf(v.x)),
-	y(thalf(v.y)),
-	z(thalf(v.z))
-{}
-
-template <typename U> 
-GLM_FUNC_QUALIFIER tvec3<thalf>::tvec3
-(
-	tvec4<U> const & v
-) :
-	x(thalf(v.x)),
-	y(thalf(v.y)),
-	z(thalf(v.z))
-{}
-
-//////////////////////////////////////
-// Unary arithmetic operators
-
-GLM_FUNC_QUALIFIER tvec3<thalf> & tvec3<thalf>::operator= 
-(
-	tvec3<thalf> const & v
-)
-{
-	this->x = v.x;
-	this->y = v.y;
-	this->z = v.z;
-	return *this;
-}
-
-GLM_FUNC_QUALIFIER tvec3<thalf> & tvec3<thalf>::operator+=
-(
-	thalf const & s
-)
-{
-	this->x += s;
-	this->y += s;
-	this->z += s;
-	return *this;
-}
-
-GLM_FUNC_QUALIFIER tvec3<thalf> & tvec3<thalf>::operator+=
-(
-	tvec3<thalf> const & v
-)
-{
-	this->x += v.x;
-	this->y += v.y;
-	this->z += v.z;
-	return *this;
-}
-
-GLM_FUNC_QUALIFIER tvec3<thalf> & tvec3<thalf>::operator-=
-(
-	thalf const & s
-)
-{
-	this->x -= s;
-	this->y -= s;
-	this->z -= s;
-	return *this;
-}
-
-GLM_FUNC_QUALIFIER tvec3<thalf> & tvec3<thalf>::operator-=
-(
-	tvec3<thalf> const & v
-)
-{
-	this->x -= v.x;
-	this->y -= v.y;
-	this->z -= v.z;
-	return *this;
-}
-
-GLM_FUNC_QUALIFIER tvec3<thalf> & tvec3<thalf>::operator*=
-(
-	thalf const & s
-)
-{
-	this->x *= s;
-	this->y *= s;
-	this->z *= s;
-	return *this;
-}
-
-GLM_FUNC_QUALIFIER tvec3<thalf> & tvec3<thalf>::operator*=
-(
-	tvec3<thalf> const & v
-)
-{
-	this->x *= v.x;
-	this->y *= v.y;
-	this->z *= v.z;
-	return *this;
-}
-
-GLM_FUNC_QUALIFIER tvec3<thalf> & tvec3<thalf>::operator/=
-(
-	thalf const & s
-)
-{
-	this->x /= s;
-	this->y /= s;
-	this->z /= s;
-	return *this;
-}
-
-GLM_FUNC_QUALIFIER tvec3<thalf> & tvec3<thalf>::operator/=
-(
-	tvec3<thalf> const & v
-)
-{
-	this->x /= v.x;
-	this->y /= v.y;
-	this->z /= v.z;
-	return *this;
-}
-
-GLM_FUNC_QUALIFIER tvec3<thalf> & tvec3<thalf>::operator++()
-{
-	++this->x;
-	++this->y;
-	++this->z;
-	return *this;
-}
-
-GLM_FUNC_QUALIFIER tvec3<thalf> & tvec3<thalf>::operator--()
-{
-	--this->x;
-	--this->y;
-	--this->z;
-	return *this;
-}
-
-//////////////////////////////////////
-// Swizzle operators
-
-GLM_FUNC_QUALIFIER thalf tvec3<thalf>::swizzle(comp x) const
-{
-	return (*this)[x];
-}
-
-GLM_FUNC_QUALIFIER tvec2<thalf> tvec3<thalf>::swizzle(comp x, comp y) const
-{
-	return tvec2<thalf>(
-		(*this)[x],
-		(*this)[y]);
-}
-
-GLM_FUNC_QUALIFIER tvec3<thalf> tvec3<thalf>::swizzle(comp x, comp y, comp z) const
-{
-	return tvec3<thalf>(
-		(*this)[x],
-		(*this)[y],
-		(*this)[z]);
-}
-
-GLM_FUNC_QUALIFIER tvec4<thalf> tvec3<thalf>::swizzle(comp x, comp y, comp z, comp w) const
-{
-	return tvec4<thalf>(
-		(*this)[x],
-		(*this)[y],
-		(*this)[z],
-		(*this)[w]);
-}
-
-GLM_FUNC_QUALIFIER tref3<thalf> tvec3<thalf>::swizzle(comp x, comp y, comp z)
-{
-	return tref3<thalf>(
-		(*this)[x],
-		(*this)[y],
-		(*this)[z]);
-}
-
-//////////////////////////////////////
-// hvec4
-
-GLM_FUNC_QUALIFIER tvec4<thalf>::size_type tvec4<thalf>::length() const
-{
-    return 4;
-}
-
-GLM_FUNC_QUALIFIER tvec4<thalf>::size_type tvec4<thalf>::value_size()
-{
-	return 4;
-}
-	
-//////////////////////////////////////
-// Accesses
-
-GLM_FUNC_QUALIFIER thalf & tvec4<thalf>::operator[]
-(
-	tvec4<thalf>::size_type i
-)
-{
-	assert(/*i >= tvec4<thalf>::size_type(0) && */i < tvec4<thalf>::value_size());
-
-	return (&x)[i];
-}
-
-GLM_FUNC_QUALIFIER thalf const & tvec4<thalf>::operator[]
-(
-	tvec4<thalf>::size_type i
-) const
-{
-	assert(/*i >= tvec4<thalf>::size_type(0) && */i < tvec4<thalf>::value_size());
-
-	return (&x)[i];
-}
-
-//////////////////////////////////////
-// Implicit basic constructors
-
-GLM_FUNC_QUALIFIER tvec4<thalf>::tvec4() :
-	x(thalf(0)),
-	y(thalf(0)),
-	z(thalf(0)),
-	w(thalf(0))
-{}
-
-GLM_FUNC_QUALIFIER tvec4<thalf>::tvec4
-(
-	tvec4<thalf> const & v
-) :
-	x(v.x),
-	y(v.y),
-	z(v.z),
-	w(v.w)
-{}
-
-//////////////////////////////////////
-// Explicit basic constructors
-
-GLM_FUNC_QUALIFIER tvec4<thalf>::tvec4
-(
-	thalf const & s
-) :
-	x(s),
-	y(s),
-	z(s),
-	w(s)
-{}
-
-GLM_FUNC_QUALIFIER tvec4<thalf>::tvec4
-(
-	thalf const & s1, 
-	thalf const & s2, 
-	thalf const & s3, 
-	thalf const & s4
-) :
-	x(s1),
-	y(s2),
-	z(s3),
-	w(s4)
-{}
-
-//////////////////////////////////////
-// Swizzle constructors
-
-GLM_FUNC_QUALIFIER tvec4<thalf>::tvec4
-(
-	tref4<thalf> const & r
-) :
-	x(r.x),
-	y(r.y),
-	z(r.z),
-	w(r.w)
-{}
-
-//////////////////////////////////////
-// Convertion scalar constructors
-
-template <typename U> 
-GLM_FUNC_QUALIFIER tvec4<thalf>::tvec4
-(
-	U const & x
-) :
-	x(thalf(x)),
-	y(thalf(x)),
-	z(thalf(x)),
-	w(thalf(x))
-{}
-
-template <typename A, typename B, typename C, typename D> 
-GLM_FUNC_QUALIFIER tvec4<thalf>::tvec4
-(
-	A const & x, 
-	B const & y, 
-	C const & z, 
-	D const & w
-) :
-	x(thalf(x)),
-	y(thalf(y)),
-	z(thalf(z)),
-	w(thalf(w))
-{}
-
-//////////////////////////////////////
-// Convertion vector constructors
-
-template <typename A, typename B, typename C> 
-GLM_FUNC_QUALIFIER tvec4<thalf>::tvec4
-(
-	tvec2<A> const & v, 
-	B const & s1, 
-	C const & s2
-) :
-	x(thalf(v.x)),
-	y(thalf(v.y)),
-	z(thalf(s1)),
-	w(thalf(s2))
-{}
-
-template <typename A, typename B, typename C> 
-GLM_FUNC_QUALIFIER tvec4<thalf>::tvec4
-(
-	A const & s1, 
-	tvec2<B> const & v, 
-	C const & s2
-) :
-	x(thalf(s1)),
-	y(thalf(v.x)),
-	z(thalf(v.y)),
-	w(thalf(s2))
-{}
-
-template <typename A, typename B, typename C> 
-GLM_FUNC_QUALIFIER tvec4<thalf>::tvec4
-(
-	A const & s1, 
-	B const & s2, 
-	tvec2<C> const & v
-) :
-	x(thalf(s1)),
-	y(thalf(s2)),
-	z(thalf(v.x)),
-	w(thalf(v.y))
-{}
-
-template <typename A, typename B> 
-GLM_FUNC_QUALIFIER tvec4<thalf>::tvec4
-(
-	tvec3<A> const & v, 
-	B const & s
-) :
-	x(thalf(v.x)),
-	y(thalf(v.y)),
-	z(thalf(v.z)),
-	w(thalf(s))
-{}
-
-template <typename A, typename B> 
-GLM_FUNC_QUALIFIER tvec4<thalf>::tvec4
-(
-	A const & s, 
-	tvec3<B> const & v
-) :
-	x(thalf(s)),
-	y(thalf(v.x)),
-	z(thalf(v.y)),
-	w(thalf(v.z))
-{}
-
-template <typename A, typename B> 
-GLM_FUNC_QUALIFIER tvec4<thalf>::tvec4
-(
-	tvec2<A> const & v1, 
-	tvec2<B> const & v2
-) :
-	x(thalf(v1.x)),
-	y(thalf(v1.y)),
-	z(thalf(v2.x)),
-	w(thalf(v2.y))
-{}
-
-template <typename U> 
-GLM_FUNC_QUALIFIER tvec4<thalf>::tvec4
-(
-	tvec4<U> const & v
-) :
-	x(thalf(v.x)),
-	y(thalf(v.y)),
-	z(thalf(v.z)),
-	w(thalf(v.w))
-{}
-
-//////////////////////////////////////
-// Unary arithmetic operators
-
-GLM_FUNC_QUALIFIER tvec4<thalf>& tvec4<thalf>::operator= 
-(
-	tvec4<thalf> const & v
-)
-{
-	this->x = v.x;
-	this->y = v.y;
-	this->z = v.z;
-	this->w = v.w;
-	return *this;
-}
-
-GLM_FUNC_QUALIFIER tvec4<thalf>& tvec4<thalf>::operator+=
-(
-	thalf const & s
-)
-{
-	this->x += s;
-	this->y += s;
-	this->z += s;
-	this->w += s;
-	return *this;
-}
-
-GLM_FUNC_QUALIFIER tvec4<thalf>& tvec4<thalf>::operator+=
-(
-	tvec4<thalf> const & v
-)
-{
-	this->x += v.x;
-	this->y += v.y;
-	this->z += v.z;
-	this->w += v.w;
-	return *this;
-}
-
-GLM_FUNC_QUALIFIER tvec4<thalf>& tvec4<thalf>::operator-=
-(
-	thalf const & s
-)
-{
-	this->x -= s;
-	this->y -= s;
-	this->z -= s;
-	this->w -= s;
-	return *this;
-}
-
-GLM_FUNC_QUALIFIER tvec4<thalf>& tvec4<thalf>::operator-=
-(
-	tvec4<thalf> const & v
-)
-{
-	this->x -= v.x;
-	this->y -= v.y;
-	this->z -= v.z;
-	this->w -= v.w;
-	return *this;
-}
-
-GLM_FUNC_QUALIFIER tvec4<thalf>& tvec4<thalf>::operator*=
-(
-	thalf const & s
-)
-{
-	this->x *= s;
-	this->y *= s;
-	this->z *= s;
-	this->w *= s;
-	return *this;
-}
-
-GLM_FUNC_QUALIFIER tvec4<thalf>& tvec4<thalf>::operator*=
-(
-	tvec4<thalf> const & v
-)
-{
-	this->x *= v.x;
-	this->y *= v.y;
-	this->z *= v.z;
-	this->w *= v.w;
-	return *this;
-}
-
-GLM_FUNC_QUALIFIER tvec4<thalf>& tvec4<thalf>::operator/=
-(
-	thalf const & s
-)
-{
-	this->x /= s;
-	this->y /= s;
-	this->z /= s;
-	this->w /= s;
-	return *this;
-}
-
-GLM_FUNC_QUALIFIER tvec4<thalf>& tvec4<thalf>::operator/=
-(
-	tvec4<thalf> const & v
-)
-{
-	this->x /= v.x;
-	this->y /= v.y;
-	this->z /= v.z;
-	this->w /= v.w;
-	return *this;
-}
-
-GLM_FUNC_QUALIFIER tvec4<thalf>& tvec4<thalf>::operator++()
-{
-	++this->x;
-	++this->y;
-	++this->z;
-	++this->w;
-	return *this;
-}
-
-GLM_FUNC_QUALIFIER tvec4<thalf>& tvec4<thalf>::operator--()
-{
-	--this->x;
-	--this->y;
-	--this->z;
-	--this->w;
-	return *this;
-}
-
-//////////////////////////////////////
-// Swizzle operators
-
-GLM_FUNC_QUALIFIER thalf tvec4<thalf>::swizzle(comp x) const
-{
-	return (*this)[x];
-}
-
-GLM_FUNC_QUALIFIER tvec2<thalf> tvec4<thalf>::swizzle(comp x, comp y) const
-{
-	return tvec2<thalf>(
-		(*this)[x],
-		(*this)[y]);
-}
-
-GLM_FUNC_QUALIFIER tvec3<thalf> tvec4<thalf>::swizzle(comp x, comp y, comp z) const
-{
-	return tvec3<thalf>(
-		(*this)[x],
-		(*this)[y],
-		(*this)[z]);
-}
-
-GLM_FUNC_QUALIFIER tvec4<thalf> tvec4<thalf>::swizzle(comp x, comp y, comp z, comp w) const
-{
-	return tvec4<thalf>(
-		(*this)[x],
-		(*this)[y],
-		(*this)[z],
-		(*this)[w]);
-}
-
-GLM_FUNC_QUALIFIER tref4<thalf> tvec4<thalf>::swizzle(comp x, comp y, comp z, comp w)
-{
-	return tref4<thalf>(
-		(*this)[x],
-		(*this)[y],
-		(*this)[z],
-		(*this)[w]);
-}
+namespace detail
+{
+#ifndef _MSC_EXTENSIONS
+
+	//////////////////////////////////////
+	// hvec2
+
+	GLM_FUNC_QUALIFIER tvec2<thalf>::size_type tvec2<thalf>::length() const
+	{
+		return 2;
+	}
+
+	GLM_FUNC_QUALIFIER tvec2<thalf>::size_type tvec2<thalf>::value_size()
+	{
+		return 2;
+	}
+
+	//////////////////////////////////////
+	// Accesses
+
+	GLM_FUNC_QUALIFIER thalf & tvec2<thalf>::operator[](tvec2<thalf>::size_type i)
+	{
+		assert(/*i >= tvec2<thalf>::size_type(0) && */i < tvec2<thalf>::value_size());
+		return (&x)[i];
+	}
+
+	GLM_FUNC_QUALIFIER thalf const & tvec2<thalf>::operator[](tvec2<thalf>::size_type i) const
+	{
+		assert(/*i >= tvec2<thalf>::size_type(0) && */i < tvec2<thalf>::value_size());
+		return (&x)[i];
+	}
+
+	//////////////////////////////////////
+	// Implicit basic constructors
+
+	GLM_FUNC_QUALIFIER tvec2<thalf>::tvec2() :
+		x(thalf(0.f)),
+		y(thalf(0.f))
+	{}
+
+	GLM_FUNC_QUALIFIER tvec2<thalf>::tvec2
+	(
+		tvec2<thalf> const & v
+	) :
+		x(v.x),
+		y(v.y)
+	{}
+
+	//////////////////////////////////////
+	// Explicit basic constructors
+
+	GLM_FUNC_QUALIFIER tvec2<thalf>::tvec2
+	(
+		thalf const & s
+	) :
+		x(s),
+		y(s)
+	{}
+
+	GLM_FUNC_QUALIFIER tvec2<thalf>::tvec2
+	(
+		thalf const & s1, 
+		thalf const & s2
+	) :
+		x(s1),
+		y(s2)
+	{}
+
+	//////////////////////////////////////
+	// Swizzle constructors
+
+	GLM_FUNC_QUALIFIER tvec2<thalf>::tvec2
+	(
+		tref2<thalf> const & r
+	) :
+		x(r.x),
+		y(r.y)
+	{}
+
+	//////////////////////////////////////
+	// Convertion scalar constructors
+
+	template <typename U> 
+	GLM_FUNC_QUALIFIER tvec2<thalf>::tvec2
+	(
+		U const & x
+	) :
+		x(thalf(x)),
+		y(thalf(x))
+	{}
+
+	template <typename U, typename V> 
+	GLM_FUNC_QUALIFIER tvec2<thalf>::tvec2
+	(
+		U const & x, 
+		V const & y
+	) :
+		x(thalf(x)),
+		y(thalf(y))
+	{}
+
+	//////////////////////////////////////
+	// Convertion vector constructors
+
+	template <typename U> 
+	GLM_FUNC_QUALIFIER tvec2<thalf>::tvec2
+	(
+		tvec2<U> const & v
+	) :
+		x(thalf(v.x)),
+		y(thalf(v.y))
+	{}
+
+	template <typename U> 
+	GLM_FUNC_QUALIFIER tvec2<thalf>::tvec2
+	(	
+		tvec3<U> const & v
+	) :
+		x(thalf(v.x)),
+		y(thalf(v.y))
+	{}
+
+	template <typename U> 
+	GLM_FUNC_QUALIFIER tvec2<thalf>::tvec2
+	(
+		tvec4<U> const & v
+	) :
+		x(thalf(v.x)),
+		y(thalf(v.y))
+	{}
+
+	//////////////////////////////////////
+	// Unary arithmetic operators
+
+	GLM_FUNC_QUALIFIER tvec2<thalf> & tvec2<thalf>::operator= 
+	(
+		tvec2<thalf> const & v
+	)
+	{
+		this->x = v.x;
+		this->y = v.y;
+		return *this;
+	}
+
+	GLM_FUNC_QUALIFIER tvec2<thalf> & tvec2<thalf>::operator+=
+	(
+		thalf const & s
+	)
+	{
+		this->x += s;
+		this->y += s;
+		return *this;
+	}
+
+	GLM_FUNC_QUALIFIER tvec2<thalf> & tvec2<thalf>::operator+=
+	(
+		tvec2<thalf> const & v
+	)
+	{
+		this->x += v.x;
+		this->y += v.y;
+		return *this;
+	}
+
+	GLM_FUNC_QUALIFIER tvec2<thalf> & tvec2<thalf>::operator-=
+	(
+		thalf const & s
+	)
+	{
+		this->x -= s;
+		this->y -= s;
+		return *this;
+	}
+
+	GLM_FUNC_QUALIFIER tvec2<thalf> & tvec2<thalf>::operator-=
+	(
+		tvec2<thalf> const & v
+	)
+	{
+		this->x -= v.x;
+		this->y -= v.y;
+		return *this;
+	}
+
+	GLM_FUNC_QUALIFIER tvec2<thalf>& tvec2<thalf>::operator*=
+	(
+		thalf const & s
+	)
+	{
+		this->x *= s;
+		this->y *= s;
+		return *this;
+	}
+
+	GLM_FUNC_QUALIFIER tvec2<thalf> & tvec2<thalf>::operator*=
+	(
+		tvec2<thalf> const & v
+	)
+	{
+		this->x *= v.x;
+		this->y *= v.y;
+		return *this;
+	}
+
+	GLM_FUNC_QUALIFIER tvec2<thalf> & tvec2<thalf>::operator/=
+	(
+		thalf const & s
+	)
+	{
+		this->x /= s;
+		this->y /= s;
+		return *this;
+	}
+
+	GLM_FUNC_QUALIFIER tvec2<thalf> & tvec2<thalf>::operator/=
+	(
+		tvec2<thalf> const & v
+	)
+	{
+		this->x /= v.x;
+		this->y /= v.y;
+		return *this;
+	}
+
+	GLM_FUNC_QUALIFIER tvec2<thalf> & tvec2<thalf>::operator++()
+	{
+		++this->x;
+		++this->y;
+		return *this;
+	}
+
+	GLM_FUNC_QUALIFIER tvec2<thalf>& tvec2<thalf>::operator--()
+	{
+		--this->x;
+		--this->y;
+		return *this;
+	}
+
+	//////////////////////////////////////
+	// Swizzle operators
+
+	GLM_FUNC_QUALIFIER thalf tvec2<thalf>::swizzle(comp x) const
+	{
+		return (*this)[x];
+	}
+
+	GLM_FUNC_QUALIFIER tvec2<thalf> tvec2<thalf>::swizzle(comp x, comp y) const
+	{
+		return tvec2<thalf>(
+			(*this)[x],
+			(*this)[y]);
+	}
+
+	GLM_FUNC_QUALIFIER tvec3<thalf> tvec2<thalf>::swizzle(comp x, comp y, comp z) const
+	{
+		return tvec3<thalf>(
+			(*this)[x],
+			(*this)[y],
+			(*this)[z]);
+	}
+
+	GLM_FUNC_QUALIFIER tvec4<thalf> tvec2<thalf>::swizzle(comp x, comp y, comp z, comp w) const
+	{
+		return tvec4<thalf>(
+			(*this)[x],
+			(*this)[y],
+			(*this)[z],
+			(*this)[w]);
+	}
+
+	GLM_FUNC_QUALIFIER tref2<thalf> tvec2<thalf>::swizzle(comp x, comp y)
+	{
+		return tref2<thalf>(
+			(*this)[x],
+			(*this)[y]);
+	}
+
+	//////////////////////////////////////
+	// hvec3
+
+	GLM_FUNC_QUALIFIER tvec3<thalf>::size_type tvec3<thalf>::length() const
+	{
+		return 3;
+	}
+
+	GLM_FUNC_QUALIFIER tvec3<thalf>::size_type tvec3<thalf>::value_size()
+	{
+		return 3;
+	}
+
+	//////////////////////////////////////
+	// Accesses
+
+	GLM_FUNC_QUALIFIER thalf & tvec3<thalf>::operator[]
+	(
+		tvec3<thalf>::size_type i
+	)
+	{
+		assert(/*i >= tvec3<thalf>::size_type(0) &&*/ i < tvec3<thalf>::value_size());
+
+		return (&x)[i];
+	}
+
+	GLM_FUNC_QUALIFIER thalf const & tvec3<thalf>::operator[]
+	(
+		tvec3<thalf>::size_type i
+	) const
+	{
+		assert(/*i >= tvec3<thalf>::size_type(0) &&*/ i < tvec3<thalf>::value_size());
+
+		return (&x)[i];
+	}
+
+	//////////////////////////////////////
+	// Implicit basic constructors
+
+	GLM_FUNC_QUALIFIER tvec3<thalf>::tvec3() :
+		x(thalf(0)),
+		y(thalf(0)),
+		z(thalf(0))
+	{}
+
+	GLM_FUNC_QUALIFIER tvec3<thalf>::tvec3
+	(
+		tvec3<thalf> const & v
+	) :
+		x(v.x),
+		y(v.y),
+		z(v.z)
+	{}
+
+	//////////////////////////////////////
+	// Explicit basic constructors
+
+	GLM_FUNC_QUALIFIER tvec3<thalf>::tvec3
+	(
+		thalf const & s
+	) :
+		x(s),
+		y(s),
+		z(s)
+	{}
+
+	GLM_FUNC_QUALIFIER tvec3<thalf>::tvec3
+	(
+		thalf const & s0, 
+		thalf const & s1, 
+		thalf const & s2
+	) :
+		x(s0),
+		y(s1),
+		z(s2)
+	{}
+
+	//////////////////////////////////////
+	// Swizzle constructors
+
+	GLM_FUNC_QUALIFIER tvec3<thalf>::tvec3
+	(
+		tref3<thalf> const & r
+	) :
+		x(r.x),
+		y(r.y),
+		z(r.z)
+	{}
+
+	//////////////////////////////////////
+	// Convertion scalar constructors
+
+	template <typename U> 
+	GLM_FUNC_QUALIFIER tvec3<thalf>::tvec3
+	(
+		U const & x
+	) :
+		x(thalf(x)),
+		y(thalf(x)),
+		z(thalf(x))
+	{}
+
+	template <typename A, typename B, typename C> 
+	GLM_FUNC_QUALIFIER tvec3<thalf>::tvec3
+	(
+		A const & x, 
+		B const & y, 
+		C const & z
+	) :
+		x(thalf(x)),
+		y(thalf(y)),
+		z(thalf(z))
+	{}
+
+	//////////////////////////////////////
+	// Convertion vector constructors
+
+	template <typename A, typename B> 
+	GLM_FUNC_QUALIFIER tvec3<thalf>::tvec3
+	(
+		tvec2<A> const & v, 
+		B const & s
+	) :
+		x(thalf(v.x)),
+		y(thalf(v.y)),
+		z(thalf(s))
+	{}
+
+	template <typename A, typename B> 
+	GLM_FUNC_QUALIFIER tvec3<thalf>::tvec3
+	(
+		A const & s, 
+		tvec2<B> const & v
+	) :
+		x(thalf(s)),
+		y(thalf(v.x)),
+		z(thalf(v.y))
+	{}
+
+	template <typename U> 
+	GLM_FUNC_QUALIFIER tvec3<thalf>::tvec3
+	(
+		tvec3<U> const & v
+	) :
+		x(thalf(v.x)),
+		y(thalf(v.y)),
+		z(thalf(v.z))
+	{}
+
+	template <typename U> 
+	GLM_FUNC_QUALIFIER tvec3<thalf>::tvec3
+	(
+		tvec4<U> const & v
+	) :
+		x(thalf(v.x)),
+		y(thalf(v.y)),
+		z(thalf(v.z))
+	{}
+
+	//////////////////////////////////////
+	// Unary arithmetic operators
+
+	GLM_FUNC_QUALIFIER tvec3<thalf> & tvec3<thalf>::operator= 
+	(
+		tvec3<thalf> const & v
+	)
+	{
+		this->x = v.x;
+		this->y = v.y;
+		this->z = v.z;
+		return *this;
+	}
+
+	GLM_FUNC_QUALIFIER tvec3<thalf> & tvec3<thalf>::operator+=
+	(
+		thalf const & s
+	)
+	{
+		this->x += s;
+		this->y += s;
+		this->z += s;
+		return *this;
+	}
+
+	GLM_FUNC_QUALIFIER tvec3<thalf> & tvec3<thalf>::operator+=
+	(
+		tvec3<thalf> const & v
+	)
+	{
+		this->x += v.x;
+		this->y += v.y;
+		this->z += v.z;
+		return *this;
+	}
+
+	GLM_FUNC_QUALIFIER tvec3<thalf> & tvec3<thalf>::operator-=
+	(
+		thalf const & s
+	)
+	{
+		this->x -= s;
+		this->y -= s;
+		this->z -= s;
+		return *this;
+	}
+
+	GLM_FUNC_QUALIFIER tvec3<thalf> & tvec3<thalf>::operator-=
+	(
+		tvec3<thalf> const & v
+	)
 
 
 #endif//_MSC_EXTENSIONS
 #endif//_MSC_EXTENSIONS
 
 

+ 47 - 41
glm/gtc/matrix_access.inl

@@ -26,49 +26,55 @@
 /// @author Christophe Riccio
 /// @author Christophe Riccio
 ///////////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////////
 
 
-namespace glm{
-
-template <typename genType>
-GLM_FUNC_QUALIFIER genType row(
-	genType const & m, 
-	int index, 
-	typename genType::row_type const & x)
-{
-    genType Result = m;
-    for(typename genType::size_type i = 0; i < genType::row_size(); ++i)
-		Result[i][index] = x[i];
-    return Result;
-}
-
-template <typename genType>
-GLM_FUNC_QUALIFIER typename genType::row_type row(
-	genType const & m, 
-	int index)
+namespace glm
 {
 {
-	typename genType::row_type Result;
-	for(typename genType::size_type i = 0; i < genType::row_size(); ++i)
-		Result[i] = m[i][index];
-	return Result;
-}
+	template <typename genType>
+	GLM_FUNC_QUALIFIER genType row
+	(
+		genType const & m, 
+		int index, 
+		typename genType::row_type const & x
+	)
+	{
+		genType Result = m;
+		for(typename genType::size_type i = 0; i < genType::row_size(); ++i)
+			Result[i][index] = x[i];
+		return Result;
+	}
 
 
-template <typename genType>
-GLM_FUNC_QUALIFIER genType column(
-	genType const & m, 
-	int index, 
-	typename genType::col_type const & x)
-{
-    genType Result = m;
-    Result[index] = x;
-    return Result;
-}
+	template <typename genType>
+	GLM_FUNC_QUALIFIER typename genType::row_type row
+	(
+		genType const & m, 
+		int index
+	)
+	{
+		typename genType::row_type Result;
+		for(typename genType::size_type i = 0; i < genType::row_size(); ++i)
+			Result[i] = m[i][index];
+		return Result;
+	}
 
 
-template <typename genType>
-GLM_FUNC_QUALIFIER typename genType::col_type column(
-	genType const & m, 
-	int index)
-{
-    return m[index];
-}
+	template <typename genType>
+	GLM_FUNC_QUALIFIER genType column
+	(
+		genType const & m, 
+		int index, 
+		typename genType::col_type const & x
+	)
+	{
+		genType Result = m;
+		Result[index] = x;
+		return Result;
+	}
 
 
+	template <typename genType>
+	GLM_FUNC_QUALIFIER typename genType::col_type column
+	(
+		genType const & m, 
+		int index
+	)
+	{
+		return m[index];
+	}
 }//namespace glm
 }//namespace glm
-

+ 128 - 123
glm/gtc/matrix_inverse.inl

@@ -26,129 +26,134 @@
 /// @author Christophe Riccio
 /// @author Christophe Riccio
 ///////////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////////
 
 
-namespace glm{
-
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tmat3x3<T> affineInverse
-(
-	detail::tmat3x3<T> const & m
-)
-{
-	detail::tmat3x3<T> Result(m);
-	Result[2] = detail::tvec3<T>(0, 0, 1);
-	Result = transpose(Result);
-	detail::tvec3<T> Translation = Result * detail::tvec3<T>(-detail::tvec2<T>(m[2]), m[2][2]);
-	Result[2] = Translation;
-	return Result;
-}
-
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tmat4x4<T> affineInverse
-(
-	detail::tmat4x4<T> const & m
-)
-{
-	detail::tmat4x4<T> Result(m);
-	Result[3] = detail::tvec4<T>(0, 0, 0, 1);
-	Result = transpose(Result);
-	detail::tvec4<T> Translation = Result * detail::tvec4<T>(-detail::tvec3<T>(m[3]), m[3][3]);
-	Result[3] = Translation;
-	return Result;
-}
-
-template <typename valType> 
-GLM_FUNC_QUALIFIER detail::tmat2x2<valType> inverseTranspose(
-	detail::tmat2x2<valType> const & m)
-{
-	valType Determinant = m[0][0] * m[1][1] - m[1][0] * m[0][1];
-
-	detail::tmat2x2<valType> Inverse(
-		+ m[1][1] / Determinant,
-		- m[0][1] / Determinant,
-		- m[1][0] / Determinant, 
-		+ m[0][0] / Determinant);
-
-	return Inverse;
-}
-
-template <typename valType> 
-GLM_FUNC_QUALIFIER detail::tmat3x3<valType> inverseTranspose(
-	detail::tmat3x3<valType> const & m)
-{
-	valType Determinant = 
-		+ m[0][0] * (m[1][1] * m[2][2] - m[1][2] * m[2][1])
-		- m[0][1] * (m[1][0] * m[2][2] - m[1][2] * m[2][0])
-		+ m[0][2] * (m[1][0] * m[2][1] - m[1][1] * m[2][0]);
-
-	detail::tmat3x3<valType> Inverse;
-	Inverse[0][0] = + (m[1][1] * m[2][2] - m[2][1] * m[1][2]);
-	Inverse[0][1] = - (m[1][0] * m[2][2] - m[2][0] * m[1][2]);
-	Inverse[0][2] = + (m[1][0] * m[2][1] - m[2][0] * m[1][1]);
-	Inverse[1][0] = - (m[0][1] * m[2][2] - m[2][1] * m[0][2]);
-	Inverse[1][1] = + (m[0][0] * m[2][2] - m[2][0] * m[0][2]);
-	Inverse[1][2] = - (m[0][0] * m[2][1] - m[2][0] * m[0][1]);
-	Inverse[2][0] = + (m[0][1] * m[1][2] - m[1][1] * m[0][2]);
-	Inverse[2][1] = - (m[0][0] * m[1][2] - m[1][0] * m[0][2]);
-	Inverse[2][2] = + (m[0][0] * m[1][1] - m[1][0] * m[0][1]);
-	Inverse /= Determinant;
-
-	return Inverse;
-}
-
-template <typename valType> 
-GLM_FUNC_QUALIFIER detail::tmat4x4<valType> inverseTranspose(
-	detail::tmat4x4<valType> const & m)
+namespace glm
 {
 {
-	valType SubFactor00 = m[2][2] * m[3][3] - m[3][2] * m[2][3];
-	valType SubFactor01 = m[2][1] * m[3][3] - m[3][1] * m[2][3];
-	valType SubFactor02 = m[2][1] * m[3][2] - m[3][1] * m[2][2];
-	valType SubFactor03 = m[2][0] * m[3][3] - m[3][0] * m[2][3];
-	valType SubFactor04 = m[2][0] * m[3][2] - m[3][0] * m[2][2];
-	valType SubFactor05 = m[2][0] * m[3][1] - m[3][0] * m[2][1];
-	valType SubFactor06 = m[1][2] * m[3][3] - m[3][2] * m[1][3];
-	valType SubFactor07 = m[1][1] * m[3][3] - m[3][1] * m[1][3];
-	valType SubFactor08 = m[1][1] * m[3][2] - m[3][1] * m[1][2];
-	valType SubFactor09 = m[1][0] * m[3][3] - m[3][0] * m[1][3];
-	valType SubFactor10 = m[1][0] * m[3][2] - m[3][0] * m[1][2];
-	valType SubFactor11 = m[1][1] * m[3][3] - m[3][1] * m[1][3];
-	valType SubFactor12 = m[1][0] * m[3][1] - m[3][0] * m[1][1];
-	valType SubFactor13 = m[1][2] * m[2][3] - m[2][2] * m[1][3];
-	valType SubFactor14 = m[1][1] * m[2][3] - m[2][1] * m[1][3];
-	valType SubFactor15 = m[1][1] * m[2][2] - m[2][1] * m[1][2];
-	valType SubFactor16 = m[1][0] * m[2][3] - m[2][0] * m[1][3];
-	valType SubFactor17 = m[1][0] * m[2][2] - m[2][0] * m[1][2];
-	valType SubFactor18 = m[1][0] * m[2][1] - m[2][0] * m[1][1];
-
-	detail::tmat4x4<valType> Inverse;
-	Inverse[0][0] = + (m[1][1] * SubFactor00 - m[1][2] * SubFactor01 + m[1][3] * SubFactor02);
-	Inverse[0][1] = - (m[1][0] * SubFactor00 - m[1][2] * SubFactor03 + m[1][3] * SubFactor04);
-	Inverse[0][2] = + (m[1][0] * SubFactor01 - m[1][1] * SubFactor03 + m[1][3] * SubFactor05);
-	Inverse[0][3] = - (m[1][0] * SubFactor02 - m[1][1] * SubFactor04 + m[1][2] * SubFactor05);
-
-	Inverse[1][0] = - (m[0][1] * SubFactor00 - m[0][2] * SubFactor01 + m[0][3] * SubFactor02);
-	Inverse[1][1] = + (m[0][0] * SubFactor00 - m[0][2] * SubFactor03 + m[0][3] * SubFactor04);
-	Inverse[1][2] = - (m[0][0] * SubFactor01 - m[0][1] * SubFactor03 + m[0][3] * SubFactor05);
-	Inverse[1][3] = + (m[0][0] * SubFactor02 - m[0][1] * SubFactor04 + m[0][2] * SubFactor05);
-
-	Inverse[2][0] = + (m[0][1] * SubFactor06 - m[0][2] * SubFactor07 + m[0][3] * SubFactor08);
-	Inverse[2][1] = - (m[0][0] * SubFactor06 - m[0][2] * SubFactor09 + m[0][3] * SubFactor10);
-	Inverse[2][2] = + (m[0][0] * SubFactor11 - m[0][1] * SubFactor09 + m[0][3] * SubFactor12);
-	Inverse[2][3] = - (m[0][0] * SubFactor08 - m[0][1] * SubFactor10 + m[0][2] * SubFactor12);
-
-	Inverse[3][0] = - (m[0][1] * SubFactor13 - m[0][2] * SubFactor14 + m[0][3] * SubFactor15);
-	Inverse[3][1] = + (m[0][0] * SubFactor13 - m[0][2] * SubFactor16 + m[0][3] * SubFactor17);
-	Inverse[3][2] = - (m[0][0] * SubFactor14 - m[0][1] * SubFactor16 + m[0][3] * SubFactor18);
-	Inverse[3][3] = + (m[0][0] * SubFactor15 - m[0][1] * SubFactor17 + m[0][2] * SubFactor18);
-
-	valType Determinant = 
-		+ m[0][0] * Inverse[0][0] 
-		+ m[0][1] * Inverse[0][1] 
-		+ m[0][2] * Inverse[0][2] 
-		+ m[0][3] * Inverse[0][3];
-
-	Inverse /= Determinant;
+	template <typename T> 
+	GLM_FUNC_QUALIFIER detail::tmat3x3<T> affineInverse
+	(
+		detail::tmat3x3<T> const & m
+	)
+	{
+		detail::tmat3x3<T> Result(m);
+		Result[2] = detail::tvec3<T>(0, 0, 1);
+		Result = transpose(Result);
+		detail::tvec3<T> Translation = Result * detail::tvec3<T>(-detail::tvec2<T>(m[2]), m[2][2]);
+		Result[2] = Translation;
+		return Result;
+	}
+
+	template <typename T> 
+	GLM_FUNC_QUALIFIER detail::tmat4x4<T> affineInverse
+	(
+		detail::tmat4x4<T> const & m
+	)
+	{
+		detail::tmat4x4<T> Result(m);
+		Result[3] = detail::tvec4<T>(0, 0, 0, 1);
+		Result = transpose(Result);
+		detail::tvec4<T> Translation = Result * detail::tvec4<T>(-detail::tvec3<T>(m[3]), m[3][3]);
+		Result[3] = Translation;
+		return Result;
+	}
+
+	template <typename valType> 
+	GLM_FUNC_QUALIFIER detail::tmat2x2<valType> inverseTranspose
+	(
+		detail::tmat2x2<valType> const & m
+	)
+	{
+		valType Determinant = m[0][0] * m[1][1] - m[1][0] * m[0][1];
+
+		detail::tmat2x2<valType> Inverse(
+			+ m[1][1] / Determinant,
+			- m[0][1] / Determinant,
+			- m[1][0] / Determinant, 
+			+ m[0][0] / Determinant);
+
+		return Inverse;
+	}
+
+	template <typename valType> 
+	GLM_FUNC_QUALIFIER detail::tmat3x3<valType> inverseTranspose
+	(
+		detail::tmat3x3<valType> const & m
+	)
+	{
+		valType Determinant = 
+			+ m[0][0] * (m[1][1] * m[2][2] - m[1][2] * m[2][1])
+			- m[0][1] * (m[1][0] * m[2][2] - m[1][2] * m[2][0])
+			+ m[0][2] * (m[1][0] * m[2][1] - m[1][1] * m[2][0]);
+
+		detail::tmat3x3<valType> Inverse;
+		Inverse[0][0] = + (m[1][1] * m[2][2] - m[2][1] * m[1][2]);
+		Inverse[0][1] = - (m[1][0] * m[2][2] - m[2][0] * m[1][2]);
+		Inverse[0][2] = + (m[1][0] * m[2][1] - m[2][0] * m[1][1]);
+		Inverse[1][0] = - (m[0][1] * m[2][2] - m[2][1] * m[0][2]);
+		Inverse[1][1] = + (m[0][0] * m[2][2] - m[2][0] * m[0][2]);
+		Inverse[1][2] = - (m[0][0] * m[2][1] - m[2][0] * m[0][1]);
+		Inverse[2][0] = + (m[0][1] * m[1][2] - m[1][1] * m[0][2]);
+		Inverse[2][1] = - (m[0][0] * m[1][2] - m[1][0] * m[0][2]);
+		Inverse[2][2] = + (m[0][0] * m[1][1] - m[1][0] * m[0][1]);
+		Inverse /= Determinant;
+
+		return Inverse;
+	}
+
+	template <typename valType> 
+	GLM_FUNC_QUALIFIER detail::tmat4x4<valType> inverseTranspose
+	(
+		detail::tmat4x4<valType> const & m
+	)
+	{
+		valType SubFactor00 = m[2][2] * m[3][3] - m[3][2] * m[2][3];
+		valType SubFactor01 = m[2][1] * m[3][3] - m[3][1] * m[2][3];
+		valType SubFactor02 = m[2][1] * m[3][2] - m[3][1] * m[2][2];
+		valType SubFactor03 = m[2][0] * m[3][3] - m[3][0] * m[2][3];
+		valType SubFactor04 = m[2][0] * m[3][2] - m[3][0] * m[2][2];
+		valType SubFactor05 = m[2][0] * m[3][1] - m[3][0] * m[2][1];
+		valType SubFactor06 = m[1][2] * m[3][3] - m[3][2] * m[1][3];
+		valType SubFactor07 = m[1][1] * m[3][3] - m[3][1] * m[1][3];
+		valType SubFactor08 = m[1][1] * m[3][2] - m[3][1] * m[1][2];
+		valType SubFactor09 = m[1][0] * m[3][3] - m[3][0] * m[1][3];
+		valType SubFactor10 = m[1][0] * m[3][2] - m[3][0] * m[1][2];
+		valType SubFactor11 = m[1][1] * m[3][3] - m[3][1] * m[1][3];
+		valType SubFactor12 = m[1][0] * m[3][1] - m[3][0] * m[1][1];
+		valType SubFactor13 = m[1][2] * m[2][3] - m[2][2] * m[1][3];
+		valType SubFactor14 = m[1][1] * m[2][3] - m[2][1] * m[1][3];
+		valType SubFactor15 = m[1][1] * m[2][2] - m[2][1] * m[1][2];
+		valType SubFactor16 = m[1][0] * m[2][3] - m[2][0] * m[1][3];
+		valType SubFactor17 = m[1][0] * m[2][2] - m[2][0] * m[1][2];
+		valType SubFactor18 = m[1][0] * m[2][1] - m[2][0] * m[1][1];
+
+		detail::tmat4x4<valType> Inverse;
+		Inverse[0][0] = + (m[1][1] * SubFactor00 - m[1][2] * SubFactor01 + m[1][3] * SubFactor02);
+		Inverse[0][1] = - (m[1][0] * SubFactor00 - m[1][2] * SubFactor03 + m[1][3] * SubFactor04);
+		Inverse[0][2] = + (m[1][0] * SubFactor01 - m[1][1] * SubFactor03 + m[1][3] * SubFactor05);
+		Inverse[0][3] = - (m[1][0] * SubFactor02 - m[1][1] * SubFactor04 + m[1][2] * SubFactor05);
+
+		Inverse[1][0] = - (m[0][1] * SubFactor00 - m[0][2] * SubFactor01 + m[0][3] * SubFactor02);
+		Inverse[1][1] = + (m[0][0] * SubFactor00 - m[0][2] * SubFactor03 + m[0][3] * SubFactor04);
+		Inverse[1][2] = - (m[0][0] * SubFactor01 - m[0][1] * SubFactor03 + m[0][3] * SubFactor05);
+		Inverse[1][3] = + (m[0][0] * SubFactor02 - m[0][1] * SubFactor04 + m[0][2] * SubFactor05);
+
+		Inverse[2][0] = + (m[0][1] * SubFactor06 - m[0][2] * SubFactor07 + m[0][3] * SubFactor08);
+		Inverse[2][1] = - (m[0][0] * SubFactor06 - m[0][2] * SubFactor09 + m[0][3] * SubFactor10);
+		Inverse[2][2] = + (m[0][0] * SubFactor11 - m[0][1] * SubFactor09 + m[0][3] * SubFactor12);
+		Inverse[2][3] = - (m[0][0] * SubFactor08 - m[0][1] * SubFactor10 + m[0][2] * SubFactor12);
+
+		Inverse[3][0] = - (m[0][1] * SubFactor13 - m[0][2] * SubFactor14 + m[0][3] * SubFactor15);
+		Inverse[3][1] = + (m[0][0] * SubFactor13 - m[0][2] * SubFactor16 + m[0][3] * SubFactor17);
+		Inverse[3][2] = - (m[0][0] * SubFactor14 - m[0][1] * SubFactor16 + m[0][3] * SubFactor18);
+		Inverse[3][3] = + (m[0][0] * SubFactor15 - m[0][1] * SubFactor17 + m[0][2] * SubFactor18);
+
+		valType Determinant = 
+			+ m[0][0] * Inverse[0][0] 
+			+ m[0][1] * Inverse[0][1] 
+			+ m[0][2] * Inverse[0][2] 
+			+ m[0][3] * Inverse[0][3];
+
+		Inverse /= Determinant;
     
     
-	return Inverse;
-}
-
+		return Inverse;
+	}
 }//namespace glm
 }//namespace glm

+ 380 - 381
glm/gtc/matrix_transform.inl

@@ -26,388 +26,387 @@
 /// @author Christophe Riccio
 /// @author Christophe Riccio
 ///////////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////////
 
 
-namespace glm{
-
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tmat4x4<T> translate
-(
-	detail::tmat4x4<T> const & m,
-	detail::tvec3<T> const & v
-)
+namespace glm
 {
 {
-	detail::tmat4x4<T> Result(m);
-	Result[3] = m[0] * v[0] + m[1] * v[1] + m[2] * v[2] + m[3];
-	return Result;
-}
+	template <typename T> 
+	GLM_FUNC_QUALIFIER detail::tmat4x4<T> translate
+	(
+		detail::tmat4x4<T> const & m,
+		detail::tvec3<T> const & v
+	)
+	{
+		detail::tmat4x4<T> Result(m);
+		Result[3] = m[0] * v[0] + m[1] * v[1] + m[2] * v[2] + m[3];
+		return Result;
+	}
 		
 		
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tmat4x4<T> rotate
-(
-	detail::tmat4x4<T> const & m,
-	T const & angle, 
-	detail::tvec3<T> const & v
-)
-{
-    T a = radians(angle);
-    T c = cos(a);
-    T s = sin(a);
-
-    detail::tvec3<T> axis = normalize(v);
-
-	detail::tvec3<T> temp = (T(1) - c) * axis;
-
-    detail::tmat4x4<T> Rotate(detail::tmat4x4<T>::null);
-	Rotate[0][0] = c + temp[0] * axis[0];
-	Rotate[0][1] = 0 + temp[0] * axis[1] + s * axis[2];
-	Rotate[0][2] = 0 + temp[0] * axis[2] - s * axis[1];
-
-	Rotate[1][0] = 0 + temp[1] * axis[0] - s * axis[2];
-	Rotate[1][1] = c + temp[1] * axis[1];
-	Rotate[1][2] = 0 + temp[1] * axis[2] + s * axis[0];
-
-	Rotate[2][0] = 0 + temp[2] * axis[0] + s * axis[1];
-	Rotate[2][1] = 0 + temp[2] * axis[1] - s * axis[0];
-	Rotate[2][2] = c + temp[2] * axis[2];
-
-	detail::tmat4x4<T> Result(detail::tmat4x4<T>::null);
-	Result[0] = m[0] * Rotate[0][0] + m[1] * Rotate[0][1] + m[2] * Rotate[0][2];
-	Result[1] = m[0] * Rotate[1][0] + m[1] * Rotate[1][1] + m[2] * Rotate[1][2];
-	Result[2] = m[0] * Rotate[2][0] + m[1] * Rotate[2][1] + m[2] * Rotate[2][2];
-	Result[3] = m[3];
-	return Result;
-}
-
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tmat4x4<T> scale
-(
-	detail::tmat4x4<T> const & m,
-	detail::tvec3<T> const & v
-)
-{
-    detail::tmat4x4<T> Result(detail::tmat4x4<T>::null);
-	Result[0] = m[0] * v[0];
-	Result[1] = m[1] * v[1];
-	Result[2] = m[2] * v[2];
-	Result[3] = m[3];
-	return Result;
-}
-
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tmat4x4<T> translate_slow
-(
-	detail::tmat4x4<T> const & m,
-	detail::tvec3<T> const & v
-)
-{
-    detail::tmat4x4<T> Result(T(1));
-    Result[3] = detail::tvec4<T>(v, T(1));
-    return m * Result;
-
-	//detail::tmat4x4<valType> Result(m);
-	Result[3] = m[0] * v[0] + m[1] * v[1] + m[2] * v[2] + m[3];
-	//Result[3][0] = m[0][0] * v[0] + m[1][0] * v[1] + m[2][0] * v[2] + m[3][0];
-	//Result[3][1] = m[0][1] * v[0] + m[1][1] * v[1] + m[2][1] * v[2] + m[3][1];
-	//Result[3][2] = m[0][2] * v[0] + m[1][2] * v[1] + m[2][2] * v[2] + m[3][2];
-	//Result[3][3] = m[0][3] * v[0] + m[1][3] * v[1] + m[2][3] * v[2] + m[3][3];
-	//return Result;
-}
+	template <typename T> 
+	GLM_FUNC_QUALIFIER detail::tmat4x4<T> rotate
+	(
+		detail::tmat4x4<T> const & m,
+		T const & angle, 
+		detail::tvec3<T> const & v
+	)
+	{
+		T a = radians(angle);
+		T c = cos(a);
+		T s = sin(a);
+
+		detail::tvec3<T> axis = normalize(v);
+
+		detail::tvec3<T> temp = (T(1) - c) * axis;
+
+		detail::tmat4x4<T> Rotate(detail::tmat4x4<T>::null);
+		Rotate[0][0] = c + temp[0] * axis[0];
+		Rotate[0][1] = 0 + temp[0] * axis[1] + s * axis[2];
+		Rotate[0][2] = 0 + temp[0] * axis[2] - s * axis[1];
+
+		Rotate[1][0] = 0 + temp[1] * axis[0] - s * axis[2];
+		Rotate[1][1] = c + temp[1] * axis[1];
+		Rotate[1][2] = 0 + temp[1] * axis[2] + s * axis[0];
+
+		Rotate[2][0] = 0 + temp[2] * axis[0] + s * axis[1];
+		Rotate[2][1] = 0 + temp[2] * axis[1] - s * axis[0];
+		Rotate[2][2] = c + temp[2] * axis[2];
+
+		detail::tmat4x4<T> Result(detail::tmat4x4<T>::null);
+		Result[0] = m[0] * Rotate[0][0] + m[1] * Rotate[0][1] + m[2] * Rotate[0][2];
+		Result[1] = m[0] * Rotate[1][0] + m[1] * Rotate[1][1] + m[2] * Rotate[1][2];
+		Result[2] = m[0] * Rotate[2][0] + m[1] * Rotate[2][1] + m[2] * Rotate[2][2];
+		Result[3] = m[3];
+		return Result;
+	}
+
+	template <typename T> 
+	GLM_FUNC_QUALIFIER detail::tmat4x4<T> scale
+	(
+		detail::tmat4x4<T> const & m,
+		detail::tvec3<T> const & v
+	)
+	{
+		detail::tmat4x4<T> Result(detail::tmat4x4<T>::null);
+		Result[0] = m[0] * v[0];
+		Result[1] = m[1] * v[1];
+		Result[2] = m[2] * v[2];
+		Result[3] = m[3];
+		return Result;
+	}
+
+	template <typename T> 
+	GLM_FUNC_QUALIFIER detail::tmat4x4<T> translate_slow
+	(
+		detail::tmat4x4<T> const & m,
+		detail::tvec3<T> const & v
+	)
+	{
+		detail::tmat4x4<T> Result(T(1));
+		Result[3] = detail::tvec4<T>(v, T(1));
+		return m * Result;
+
+		//detail::tmat4x4<valType> Result(m);
+		Result[3] = m[0] * v[0] + m[1] * v[1] + m[2] * v[2] + m[3];
+		//Result[3][0] = m[0][0] * v[0] + m[1][0] * v[1] + m[2][0] * v[2] + m[3][0];
+		//Result[3][1] = m[0][1] * v[0] + m[1][1] * v[1] + m[2][1] * v[2] + m[3][1];
+		//Result[3][2] = m[0][2] * v[0] + m[1][2] * v[1] + m[2][2] * v[2] + m[3][2];
+		//Result[3][3] = m[0][3] * v[0] + m[1][3] * v[1] + m[2][3] * v[2] + m[3][3];
+		//return Result;
+	}
 		
 		
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tmat4x4<T> rotate_slow
-(
-	detail::tmat4x4<T> const & m,
-	T const & angle, 
-	detail::tvec3<T> const & v
-)
-{
-    T a = radians(angle);
-    T c = cos(a);
-    T s = sin(a);
-    detail::tmat4x4<T> Result;
-
-    detail::tvec3<T> axis = normalize(v);
-
-    Result[0][0] = c + (1 - c)      * axis.x     * axis.x;
-	Result[0][1] = (1 - c) * axis.x * axis.y + s * axis.z;
-	Result[0][2] = (1 - c) * axis.x * axis.z - s * axis.y;
-	Result[0][3] = 0;
-
-	Result[1][0] = (1 - c) * axis.y * axis.x - s * axis.z;
-	Result[1][1] = c + (1 - c) * axis.y * axis.y;
-	Result[1][2] = (1 - c) * axis.y * axis.z + s * axis.x;
-	Result[1][3] = 0;
-
-	Result[2][0] = (1 - c) * axis.z * axis.x + s * axis.y;
-	Result[2][1] = (1 - c) * axis.z * axis.y - s * axis.x;
-	Result[2][2] = c + (1 - c) * axis.z * axis.z;
-	Result[2][3] = 0;
-
-    Result[3] = detail::tvec4<T>(0, 0, 0, 1);
-    return m * Result;
-}
-
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tmat4x4<T> scale_slow
-(
-	detail::tmat4x4<T> const & m,
-	detail::tvec3<T> const & v
-)
-{
-    detail::tmat4x4<T> Result(T(1));
-    Result[0][0] = v.x;
-    Result[1][1] = v.y;
-    Result[2][2] = v.z;
-    return m * Result;
-}
-
-template <typename valType> 
-GLM_FUNC_QUALIFIER detail::tmat4x4<valType> ortho
-(
-	valType const & left, 
-	valType const & right, 
-	valType const & bottom, 
-	valType const & top, 
-	valType const & zNear, 
-	valType const & zFar
-)
-{
-	detail::tmat4x4<valType> Result(1);
-	Result[0][0] = valType(2) / (right - left);
-	Result[1][1] = valType(2) / (top - bottom);
-	Result[2][2] = - valType(2) / (zFar - zNear);
-	Result[3][0] = - (right + left) / (right - left);
-	Result[3][1] = - (top + bottom) / (top - bottom);
-	Result[3][2] = - (zFar + zNear) / (zFar - zNear);
-	return Result;
-}
-
-template <typename valType> 
-GLM_FUNC_QUALIFIER detail::tmat4x4<valType> ortho(
-	valType const & left, 
-	valType const & right, 
-	valType const & bottom, 
-	valType const & top)
-{
-	detail::tmat4x4<valType> Result(1);
-	Result[0][0] = valType(2) / (right - left);
-	Result[1][1] = valType(2) / (top - bottom);
-	Result[2][2] = - valType(1);
-	Result[3][0] = - (right + left) / (right - left);
-	Result[3][1] = - (top + bottom) / (top - bottom);
-	return Result;
-}
-
-template <typename valType> 
-GLM_FUNC_QUALIFIER detail::tmat4x4<valType> frustum
-(
-	valType const & left, 
-	valType const & right, 
-	valType const & bottom, 
-	valType const & top, 
-	valType const & nearVal, 
-	valType const & farVal
-)
-{
-	detail::tmat4x4<valType> Result(0);
-	Result[0][0] = (valType(2) * nearVal) / (right - left);
-	Result[1][1] = (valType(2) * nearVal) / (top - bottom);
-	Result[2][0] = (right + left) / (right - left);
-	Result[2][1] = (top + bottom) / (top - bottom);
-	Result[2][2] = -(farVal + nearVal) / (farVal - nearVal);
-	Result[2][3] = valType(-1);
-	Result[3][2] = -(valType(2) * farVal * nearVal) / (farVal - nearVal);
-	return Result;
-}
-
-template <typename valType> 
-GLM_FUNC_QUALIFIER detail::tmat4x4<valType> perspective
-(
-	valType const & fovy, 
-	valType const & aspect, 
-	valType const & zNear, 
-	valType const & zFar
-)
-{
-	valType range = tan(radians(fovy / valType(2))) * zNear;	
-	valType left = -range * aspect;
-	valType right = range * aspect;
-	valType bottom = -range;
-	valType top = range;
-
-	detail::tmat4x4<valType> Result(valType(0));
-	Result[0][0] = (valType(2) * zNear) / (right - left);
-	Result[1][1] = (valType(2) * zNear) / (top - bottom);
-	Result[2][2] = - (zFar + zNear) / (zFar - zNear);
-	Result[2][3] = - valType(1);
-	Result[3][2] = - (valType(2) * zFar * zNear) / (zFar - zNear);
-	return Result;
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tmat4x4<valType> perspectiveFov
-(
-	valType const & fov, 
-	valType const & width, 
-	valType const & height, 
-	valType const & zNear, 
-	valType const & zFar
-)
-{
-	valType rad = glm::radians(fov);
-	valType h = glm::cos(valType(0.5) * rad) / glm::sin(valType(0.5) * rad);
-	valType w = h * height / width;
-
-	detail::tmat4x4<valType> Result(valType(0));
-	Result[0][0] = w;
-	Result[1][1] = h;
-	Result[2][2] = (zFar + zNear) / (zFar - zNear);
-	Result[2][3] = valType(1);
-	Result[3][2] = -(valType(2) * zFar * zNear) / (zFar - zNear);
-	return Result;
-}
-
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tmat4x4<T> infinitePerspective
-(
-	T fovy, 
-	T aspect, 
-	T zNear
-)
-{
-	T range = tan(radians(fovy / T(2))) * zNear;	
-	T left = -range * aspect;
-	T right = range * aspect;
-	T bottom = -range;
-	T top = range;
-
-	detail::tmat4x4<T> Result(T(0));
-	Result[0][0] = (T(2) * zNear) / (right - left);
-	Result[1][1] = (T(2) * zNear) / (top - bottom);
-	Result[2][2] = - T(1);
-	Result[2][3] = - T(1);
-	Result[3][2] = - T(2) * zNear;
-	return Result;
-}
-
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tmat4x4<T> tweakedInfinitePerspective
-(
-	T fovy, 
-	T aspect, 
-	T zNear
-)
-{
-	T range = tan(radians(fovy / T(2))) * zNear;	
-	T left = -range * aspect;
-	T right = range * aspect;
-	T bottom = -range;
-	T top = range;
-
-	detail::tmat4x4<T> Result(T(0));
-	Result[0][0] = (T(2) * zNear) / (right - left);
-	Result[1][1] = (T(2) * zNear) / (top - bottom);
-	Result[2][2] = T(0.0001) - T(1);
-	Result[2][3] = T(-1);
-	Result[3][2] = - (T(0.0001) - T(2)) * zNear;
-	return Result;
-}
-
-template <typename T, typename U>
-GLM_FUNC_QUALIFIER detail::tvec3<T> project
-(
-	detail::tvec3<T> const & obj, 
-	detail::tmat4x4<T> const & model, 
-	detail::tmat4x4<T> const & proj, 
-	detail::tvec4<U> const & viewport
-)
-{
-	detail::tvec4<T> tmp = detail::tvec4<T>(obj, T(1));
-	tmp = model * tmp;
-	tmp = proj * tmp;
-
-	tmp /= tmp.w;
-	tmp = tmp * T(0.5) + T(0.5);
-	tmp[0] = tmp[0] * T(viewport[2]) + T(viewport[0]);
-	tmp[1] = tmp[1] * T(viewport[3]) + T(viewport[1]);
-
-	return detail::tvec3<T>(tmp);
-}
-
-template <typename T, typename U>
-GLM_FUNC_QUALIFIER detail::tvec3<T> unProject
-(
-	detail::tvec3<T> const & win, 
-	detail::tmat4x4<T> const & model, 
-	detail::tmat4x4<T> const & proj, 
-	detail::tvec4<U> const & viewport
-)
-{
-	detail::tmat4x4<T> inverse = glm::inverse(proj * model);
-
-	detail::tvec4<T> tmp = detail::tvec4<T>(win, T(1));
-	tmp.x = (tmp.x - T(viewport[0])) / T(viewport[2]);
-	tmp.y = (tmp.y - T(viewport[1])) / T(viewport[3]);
-	tmp = tmp * T(2) - T(1);
-
-	detail::tvec4<T> obj = inverse * tmp;
-	obj /= obj.w;
-
-	return detail::tvec3<T>(obj);
-}
-
-template <typename T, typename U> 
-detail::tmat4x4<T> pickMatrix
-(
-	detail::tvec2<T> const & center, 
-	detail::tvec2<T> const & delta, 
-	detail::tvec4<U> const & viewport
-)
-{
-	assert(delta.x > T(0) && delta.y > T(0));
-	detail::tmat4x4<T> Result(1.0f);
-
-	if(!(delta.x > T(0) && delta.y > T(0))) 
-		return Result; // Error
-
-	detail::tvec3<T> Temp(
-		(T(viewport[2]) - T(2) * (center.x - T(viewport[0]))) / delta.x,
-		(T(viewport[3]) - T(2) * (center.y - T(viewport[1]))) / delta.y,
-		T(0));
-
-	// Translate and scale the picked region to the entire window
-	Result = translate(Result, Temp);
-	return scale(Result, detail::tvec3<T>(T(viewport[2]) / delta.x, T(viewport[3]) / delta.y, T(1)));
-}
-
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tmat4x4<T> lookAt
-(
-	detail::tvec3<T> const & eye,
-	detail::tvec3<T> const & center,
-	detail::tvec3<T> const & up
-)
-{
-    detail::tvec3<T> f = normalize(center - eye);
-    detail::tvec3<T> u = normalize(up);
-    detail::tvec3<T> s = normalize(cross(f, u));
-    u = cross(s, f);
-
-    detail::tmat4x4<T> Result(1);
-    Result[0][0] = s.x;
-    Result[1][0] = s.y;
-    Result[2][0] = s.z;
-    Result[0][1] = u.x;
-    Result[1][1] = u.y;
-    Result[2][1] = u.z;
-    Result[0][2] =-f.x;
-    Result[1][2] =-f.y;
-    Result[2][2] =-f.z;
-/*  Test this instead of translate3D
-    Result[3][0] =-dot(s, eye);
-    Result[3][1] =-dot(y, eye);
-    Result[3][2] = dot(f, eye);
-*/  
-	return translate(Result, -eye);
-}
-
+	template <typename T> 
+	GLM_FUNC_QUALIFIER detail::tmat4x4<T> rotate_slow
+	(
+		detail::tmat4x4<T> const & m,
+		T const & angle, 
+		detail::tvec3<T> const & v
+	)
+	{
+		T a = radians(angle);
+		T c = cos(a);
+		T s = sin(a);
+		detail::tmat4x4<T> Result;
+
+		detail::tvec3<T> axis = normalize(v);
+
+		Result[0][0] = c + (1 - c)      * axis.x     * axis.x;
+		Result[0][1] = (1 - c) * axis.x * axis.y + s * axis.z;
+		Result[0][2] = (1 - c) * axis.x * axis.z - s * axis.y;
+		Result[0][3] = 0;
+
+		Result[1][0] = (1 - c) * axis.y * axis.x - s * axis.z;
+		Result[1][1] = c + (1 - c) * axis.y * axis.y;
+		Result[1][2] = (1 - c) * axis.y * axis.z + s * axis.x;
+		Result[1][3] = 0;
+
+		Result[2][0] = (1 - c) * axis.z * axis.x + s * axis.y;
+		Result[2][1] = (1 - c) * axis.z * axis.y - s * axis.x;
+		Result[2][2] = c + (1 - c) * axis.z * axis.z;
+		Result[2][3] = 0;
+
+		Result[3] = detail::tvec4<T>(0, 0, 0, 1);
+		return m * Result;
+	}
+
+	template <typename T> 
+	GLM_FUNC_QUALIFIER detail::tmat4x4<T> scale_slow
+	(
+		detail::tmat4x4<T> const & m,
+		detail::tvec3<T> const & v
+	)
+	{
+		detail::tmat4x4<T> Result(T(1));
+		Result[0][0] = v.x;
+		Result[1][1] = v.y;
+		Result[2][2] = v.z;
+		return m * Result;
+	}
+
+	template <typename valType> 
+	GLM_FUNC_QUALIFIER detail::tmat4x4<valType> ortho
+	(
+		valType const & left, 
+		valType const & right, 
+		valType const & bottom, 
+		valType const & top, 
+		valType const & zNear, 
+		valType const & zFar
+	)
+	{
+		detail::tmat4x4<valType> Result(1);
+		Result[0][0] = valType(2) / (right - left);
+		Result[1][1] = valType(2) / (top - bottom);
+		Result[2][2] = - valType(2) / (zFar - zNear);
+		Result[3][0] = - (right + left) / (right - left);
+		Result[3][1] = - (top + bottom) / (top - bottom);
+		Result[3][2] = - (zFar + zNear) / (zFar - zNear);
+		return Result;
+	}
+
+	template <typename valType> 
+	GLM_FUNC_QUALIFIER detail::tmat4x4<valType> ortho(
+		valType const & left, 
+		valType const & right, 
+		valType const & bottom, 
+		valType const & top)
+	{
+		detail::tmat4x4<valType> Result(1);
+		Result[0][0] = valType(2) / (right - left);
+		Result[1][1] = valType(2) / (top - bottom);
+		Result[2][2] = - valType(1);
+		Result[3][0] = - (right + left) / (right - left);
+		Result[3][1] = - (top + bottom) / (top - bottom);
+		return Result;
+	}
+
+	template <typename valType> 
+	GLM_FUNC_QUALIFIER detail::tmat4x4<valType> frustum
+	(
+		valType const & left, 
+		valType const & right, 
+		valType const & bottom, 
+		valType const & top, 
+		valType const & nearVal, 
+		valType const & farVal
+	)
+	{
+		detail::tmat4x4<valType> Result(0);
+		Result[0][0] = (valType(2) * nearVal) / (right - left);
+		Result[1][1] = (valType(2) * nearVal) / (top - bottom);
+		Result[2][0] = (right + left) / (right - left);
+		Result[2][1] = (top + bottom) / (top - bottom);
+		Result[2][2] = -(farVal + nearVal) / (farVal - nearVal);
+		Result[2][3] = valType(-1);
+		Result[3][2] = -(valType(2) * farVal * nearVal) / (farVal - nearVal);
+		return Result;
+	}
+
+	template <typename valType> 
+	GLM_FUNC_QUALIFIER detail::tmat4x4<valType> perspective
+	(
+		valType const & fovy, 
+		valType const & aspect, 
+		valType const & zNear, 
+		valType const & zFar
+	)
+	{
+		valType range = tan(radians(fovy / valType(2))) * zNear;	
+		valType left = -range * aspect;
+		valType right = range * aspect;
+		valType bottom = -range;
+		valType top = range;
+
+		detail::tmat4x4<valType> Result(valType(0));
+		Result[0][0] = (valType(2) * zNear) / (right - left);
+		Result[1][1] = (valType(2) * zNear) / (top - bottom);
+		Result[2][2] = - (zFar + zNear) / (zFar - zNear);
+		Result[2][3] = - valType(1);
+		Result[3][2] = - (valType(2) * zFar * zNear) / (zFar - zNear);
+		return Result;
+	}
+
+	template <typename valType>
+	GLM_FUNC_QUALIFIER detail::tmat4x4<valType> perspectiveFov
+	(
+		valType const & fov, 
+		valType const & width, 
+		valType const & height, 
+		valType const & zNear, 
+		valType const & zFar
+	)
+	{
+		valType rad = glm::radians(fov);
+		valType h = glm::cos(valType(0.5) * rad) / glm::sin(valType(0.5) * rad);
+		valType w = h * height / width;
+
+		detail::tmat4x4<valType> Result(valType(0));
+		Result[0][0] = w;
+		Result[1][1] = h;
+		Result[2][2] = (zFar + zNear) / (zFar - zNear);
+		Result[2][3] = valType(1);
+		Result[3][2] = -(valType(2) * zFar * zNear) / (zFar - zNear);
+		return Result;
+	}
+
+	template <typename T> 
+	GLM_FUNC_QUALIFIER detail::tmat4x4<T> infinitePerspective
+	(
+		T fovy, 
+		T aspect, 
+		T zNear
+	)
+	{
+		T range = tan(radians(fovy / T(2))) * zNear;	
+		T left = -range * aspect;
+		T right = range * aspect;
+		T bottom = -range;
+		T top = range;
+
+		detail::tmat4x4<T> Result(T(0));
+		Result[0][0] = (T(2) * zNear) / (right - left);
+		Result[1][1] = (T(2) * zNear) / (top - bottom);
+		Result[2][2] = - T(1);
+		Result[2][3] = - T(1);
+		Result[3][2] = - T(2) * zNear;
+		return Result;
+	}
+
+	template <typename T> 
+	GLM_FUNC_QUALIFIER detail::tmat4x4<T> tweakedInfinitePerspective
+	(
+		T fovy, 
+		T aspect, 
+		T zNear
+	)
+	{
+		T range = tan(radians(fovy / T(2))) * zNear;	
+		T left = -range * aspect;
+		T right = range * aspect;
+		T bottom = -range;
+		T top = range;
+
+		detail::tmat4x4<T> Result(T(0));
+		Result[0][0] = (T(2) * zNear) / (right - left);
+		Result[1][1] = (T(2) * zNear) / (top - bottom);
+		Result[2][2] = T(0.0001) - T(1);
+		Result[2][3] = T(-1);
+		Result[3][2] = - (T(0.0001) - T(2)) * zNear;
+		return Result;
+	}
+
+	template <typename T, typename U>
+	GLM_FUNC_QUALIFIER detail::tvec3<T> project
+	(
+		detail::tvec3<T> const & obj, 
+		detail::tmat4x4<T> const & model, 
+		detail::tmat4x4<T> const & proj, 
+		detail::tvec4<U> const & viewport
+	)
+	{
+		detail::tvec4<T> tmp = detail::tvec4<T>(obj, T(1));
+		tmp = model * tmp;
+		tmp = proj * tmp;
+
+		tmp /= tmp.w;
+		tmp = tmp * T(0.5) + T(0.5);
+		tmp[0] = tmp[0] * T(viewport[2]) + T(viewport[0]);
+		tmp[1] = tmp[1] * T(viewport[3]) + T(viewport[1]);
+
+		return detail::tvec3<T>(tmp);
+	}
+
+	template <typename T, typename U>
+	GLM_FUNC_QUALIFIER detail::tvec3<T> unProject
+	(
+		detail::tvec3<T> const & win, 
+		detail::tmat4x4<T> const & model, 
+		detail::tmat4x4<T> const & proj, 
+		detail::tvec4<U> const & viewport
+	)
+	{
+		detail::tmat4x4<T> inverse = glm::inverse(proj * model);
+
+		detail::tvec4<T> tmp = detail::tvec4<T>(win, T(1));
+		tmp.x = (tmp.x - T(viewport[0])) / T(viewport[2]);
+		tmp.y = (tmp.y - T(viewport[1])) / T(viewport[3]);
+		tmp = tmp * T(2) - T(1);
+
+		detail::tvec4<T> obj = inverse * tmp;
+		obj /= obj.w;
+
+		return detail::tvec3<T>(obj);
+	}
+
+	template <typename T, typename U> 
+	detail::tmat4x4<T> pickMatrix
+	(
+		detail::tvec2<T> const & center, 
+		detail::tvec2<T> const & delta, 
+		detail::tvec4<U> const & viewport
+	)
+	{
+		assert(delta.x > T(0) && delta.y > T(0));
+		detail::tmat4x4<T> Result(1.0f);
+
+		if(!(delta.x > T(0) && delta.y > T(0))) 
+			return Result; // Error
+
+		detail::tvec3<T> Temp(
+			(T(viewport[2]) - T(2) * (center.x - T(viewport[0]))) / delta.x,
+			(T(viewport[3]) - T(2) * (center.y - T(viewport[1]))) / delta.y,
+			T(0));
+
+		// Translate and scale the picked region to the entire window
+		Result = translate(Result, Temp);
+		return scale(Result, detail::tvec3<T>(T(viewport[2]) / delta.x, T(viewport[3]) / delta.y, T(1)));
+	}
+
+	template <typename T> 
+	GLM_FUNC_QUALIFIER detail::tmat4x4<T> lookAt
+	(
+		detail::tvec3<T> const & eye,
+		detail::tvec3<T> const & center,
+		detail::tvec3<T> const & up
+	)
+	{
+		detail::tvec3<T> f = normalize(center - eye);
+		detail::tvec3<T> u = normalize(up);
+		detail::tvec3<T> s = normalize(cross(f, u));
+		u = cross(s, f);
+
+		detail::tmat4x4<T> Result(1);
+		Result[0][0] = s.x;
+		Result[1][0] = s.y;
+		Result[2][0] = s.z;
+		Result[0][1] = u.x;
+		Result[1][1] = u.y;
+		Result[2][1] = u.z;
+		Result[0][2] =-f.x;
+		Result[1][2] =-f.y;
+		Result[2][2] =-f.z;
+	/*  Test this instead of translate3D
+		Result[3][0] =-dot(s, eye);
+		Result[3][1] =-dot(y, eye);
+		Result[3][2] = dot(f, eye);
+	*/  
+		return translate(Result, -eye);
+	}
 }//namespace glm
 }//namespace glm

+ 831 - 832
glm/gtc/noise.inl

@@ -15,838 +15,837 @@
 // - GLM core
 // - GLM core
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 
-namespace glm{
-
-template <typename T>
-GLM_FUNC_QUALIFIER T mod289(T const & x)
-{
-	return x - floor(x * T(1.0 / 289.0)) * T(289.0);
-}
-
-template <typename T>
-GLM_FUNC_QUALIFIER T permute(T const & x)
+namespace glm
 {
 {
-	return mod289(((x * T(34)) + T(1)) * x);
-}
-
-template <typename T, template<typename> class vecType>
-GLM_FUNC_QUALIFIER vecType<T> permute(vecType<T> const & x)
-{
-	return mod289(((x * T(34)) + T(1)) * x);
-}
+	template <typename T>
+	GLM_FUNC_QUALIFIER T mod289(T const & x)
+	{
+		return x - floor(x * T(1.0 / 289.0)) * T(289.0);
+	}
+
+	template <typename T>
+	GLM_FUNC_QUALIFIER T permute(T const & x)
+	{
+		return mod289(((x * T(34)) + T(1)) * x);
+	}
+
+	template <typename T, template<typename> class vecType>
+	GLM_FUNC_QUALIFIER vecType<T> permute(vecType<T> const & x)
+	{
+		return mod289(((x * T(34)) + T(1)) * x);
+	}
   
   
-template <typename T>
-GLM_FUNC_QUALIFIER T taylorInvSqrt(T const & r)
-{
-	return T(1.79284291400159) - T(0.85373472095314) * r;
-}
-
-template <typename T, template<typename> class vecType>
-GLM_FUNC_QUALIFIER vecType<T> taylorInvSqrt(vecType<T> const & r)
-{
-	return T(1.79284291400159) - T(0.85373472095314) * r;
-}
-
-template <typename T, template <typename> class vecType> 
-GLM_FUNC_QUALIFIER vecType<T> fade(vecType<T> const & t) 
-{
-	return t * t * t * (t * (t * T(6) - T(15)) + T(10));
-}
-
-template <typename T>
-GLM_FUNC_QUALIFIER detail::tvec4<T> grad4(T const & j, detail::tvec4<T> const & ip)
-{
-	detail::tvec3<T> pXYZ = floor(fract(detail::tvec3<T>(j) * detail::tvec3<T>(ip)) * T(7)) * ip[2] - T(1);
-	T pW = T(1.5) - dot(abs(pXYZ), detail::tvec3<T>(1));
-	detail::tvec4<T> s = detail::tvec4<T>(lessThan(detail::tvec4<T>(pXYZ, pW), detail::tvec4<T>(0.0)));
-	pXYZ = pXYZ + (detail::tvec3<T>(s) * T(2) - T(1)) * s.w; 
-	return detail::tvec4<T>(pXYZ, pW);
-}
-
-// Classic Perlin noise
-template <typename T>
-GLM_FUNC_QUALIFIER T perlin(detail::tvec2<T> const & P)
-{
-	detail::tvec4<T> Pi = glm::floor(detail::tvec4<T>(P.x, P.y, P.x, P.y)) + detail::tvec4<T>(0.0, 0.0, 1.0, 1.0);
-	detail::tvec4<T> Pf = glm::fract(detail::tvec4<T>(P.x, P.y, P.x, P.y)) - detail::tvec4<T>(0.0, 0.0, 1.0, 1.0);
-	Pi = mod(Pi, T(289)); // To avoid truncation effects in permutation
-	detail::tvec4<T> ix(Pi.x, Pi.z, Pi.x, Pi.z);
-	detail::tvec4<T> iy(Pi.y, Pi.y, Pi.w, Pi.w);
-	detail::tvec4<T> fx(Pf.x, Pf.z, Pf.x, Pf.z);
-	detail::tvec4<T> fy(Pf.y, Pf.y, Pf.w, Pf.w);
-
-	detail::tvec4<T> i = glm::permute(glm::permute(ix) + iy);
-
-	detail::tvec4<T> gx = T(2) * glm::fract(i / T(41)) - T(1);
-	detail::tvec4<T> gy = glm::abs(gx) - T(0.5);
-	detail::tvec4<T> tx = glm::floor(gx + T(0.5));
-	gx = gx - tx;
-
-	detail::tvec2<T> g00(gx.x, gy.x);
-	detail::tvec2<T> g10(gx.y, gy.y);
-	detail::tvec2<T> g01(gx.z, gy.z);
-	detail::tvec2<T> g11(gx.w, gy.w);
-
-	detail::tvec4<T> norm = taylorInvSqrt(detail::tvec4<T>(dot(g00, g00), dot(g01, g01), dot(g10, g10), dot(g11, g11)));
-	g00 *= norm.x;  
-	g01 *= norm.y;  
-	g10 *= norm.z;  
-	g11 *= norm.w;  
-
-	T n00 = dot(g00, detail::tvec2<T>(fx.x, fy.x));
-	T n10 = dot(g10, detail::tvec2<T>(fx.y, fy.y));
-	T n01 = dot(g01, detail::tvec2<T>(fx.z, fy.z));
-	T n11 = dot(g11, detail::tvec2<T>(fx.w, fy.w));
-
-	detail::tvec2<T> fade_xy = fade(detail::tvec2<T>(Pf.x, Pf.y));
-	detail::tvec2<T> n_x = mix(detail::tvec2<T>(n00, n01), detail::tvec2<T>(n10, n11), fade_xy.x);
-	T n_xy = mix(n_x.x, n_x.y, fade_xy.y);
-	return T(2.3) * n_xy;
-}
-
-// Classic Perlin noise
-template <typename T>
-GLM_FUNC_QUALIFIER T perlin(detail::tvec3<T> const & P)
-{
-	detail::tvec3<T> Pi0 = floor(P); // Integer part for indexing
-	detail::tvec3<T> Pi1 = Pi0 + T(1); // Integer part + 1
-	Pi0 = mod289(Pi0);
-	Pi1 = mod289(Pi1);
-	detail::tvec3<T> Pf0 = fract(P); // Fractional part for interpolation
-	detail::tvec3<T> Pf1 = Pf0 - T(1); // Fractional part - 1.0
-	detail::tvec4<T> ix(Pi0.x, Pi1.x, Pi0.x, Pi1.x);
-	detail::tvec4<T> iy = detail::tvec4<T>(detail::tvec2<T>(Pi0.y), detail::tvec2<T>(Pi1.y));
-	detail::tvec4<T> iz0(Pi0.z);
-	detail::tvec4<T> iz1(Pi1.z);
-
-	detail::tvec4<T> ixy = permute(permute(ix) + iy);
-	detail::tvec4<T> ixy0 = permute(ixy + iz0);
-	detail::tvec4<T> ixy1 = permute(ixy + iz1);
-
-	detail::tvec4<T> gx0 = ixy0 * T(1.0 / 7.0);
-	detail::tvec4<T> gy0 = fract(floor(gx0) * T(1.0 / 7.0)) - T(0.5);
-	gx0 = fract(gx0);
-	detail::tvec4<T> gz0 = detail::tvec4<T>(0.5) - abs(gx0) - abs(gy0);
-	detail::tvec4<T> sz0 = step(gz0, detail::tvec4<T>(0.0));
-	gx0 -= sz0 * (step(T(0), gx0) - T(0.5));
-	gy0 -= sz0 * (step(T(0), gy0) - T(0.5));
-
-	detail::tvec4<T> gx1 = ixy1 * T(1.0 / 7.0);
-	detail::tvec4<T> gy1 = fract(floor(gx1) * T(1.0 / 7.0)) - T(0.5);
-	gx1 = fract(gx1);
-	detail::tvec4<T> gz1 = detail::tvec4<T>(0.5) - abs(gx1) - abs(gy1);
-	detail::tvec4<T> sz1 = step(gz1, detail::tvec4<T>(0.0));
-	gx1 -= sz1 * (step(T(0), gx1) - T(0.5));
-	gy1 -= sz1 * (step(T(0), gy1) - T(0.5));
-
-	detail::tvec3<T> g000(gx0.x, gy0.x, gz0.x);
-	detail::tvec3<T> g100(gx0.y, gy0.y, gz0.y);
-	detail::tvec3<T> g010(gx0.z, gy0.z, gz0.z);
-	detail::tvec3<T> g110(gx0.w, gy0.w, gz0.w);
-	detail::tvec3<T> g001(gx1.x, gy1.x, gz1.x);
-	detail::tvec3<T> g101(gx1.y, gy1.y, gz1.y);
-	detail::tvec3<T> g011(gx1.z, gy1.z, gz1.z);
-	detail::tvec3<T> g111(gx1.w, gy1.w, gz1.w);
-
-	detail::tvec4<T> norm0 = taylorInvSqrt(detail::tvec4<T>(dot(g000, g000), dot(g010, g010), dot(g100, g100), dot(g110, g110)));
-	g000 *= norm0.x;
-	g010 *= norm0.y;
-	g100 *= norm0.z;
-	g110 *= norm0.w;
-	detail::tvec4<T> norm1 = taylorInvSqrt(detail::tvec4<T>(dot(g001, g001), dot(g011, g011), dot(g101, g101), dot(g111, g111)));
-	g001 *= norm1.x;
-	g011 *= norm1.y;
-	g101 *= norm1.z;
-	g111 *= norm1.w;
-
-	T n000 = dot(g000, Pf0);
-	T n100 = dot(g100, detail::tvec3<T>(Pf1.x, Pf0.y, Pf0.z));
-	T n010 = dot(g010, detail::tvec3<T>(Pf0.x, Pf1.y, Pf0.z));
-	T n110 = dot(g110, detail::tvec3<T>(Pf1.x, Pf1.y, Pf0.z));
-	T n001 = dot(g001, detail::tvec3<T>(Pf0.x, Pf0.y, Pf1.z));
-	T n101 = dot(g101, detail::tvec3<T>(Pf1.x, Pf0.y, Pf1.z));
-	T n011 = dot(g011, detail::tvec3<T>(Pf0.x, Pf1.y, Pf1.z));
-	T n111 = dot(g111, Pf1);
-
-	detail::tvec3<T> fade_xyz = fade(Pf0);
-	detail::tvec4<T> n_z = mix(detail::tvec4<T>(n000, n100, n010, n110), detail::tvec4<T>(n001, n101, n011, n111), fade_xyz.z);
-	detail::tvec2<T> n_yz = mix(detail::tvec2<T>(n_z.x, n_z.y), detail::tvec2<T>(n_z.z, n_z.w), fade_xyz.y);
-	T n_xyz = mix(n_yz.x, n_yz.y, fade_xyz.x); 
-	return T(2.2) * n_xyz;
-}
-/*
-// Classic Perlin noise
-template <typename T>
-GLM_FUNC_QUALIFIER T perlin(detail::tvec3<T> const & P)
-{
-	detail::tvec3<T> Pi0 = floor(P); // Integer part for indexing
-	detail::tvec3<T> Pi1 = Pi0 + T(1); // Integer part + 1
-	Pi0 = mod(Pi0, T(289));
-	Pi1 = mod(Pi1, T(289));
-	detail::tvec3<T> Pf0 = fract(P); // Fractional part for interpolation
-	detail::tvec3<T> Pf1 = Pf0 - T(1); // Fractional part - 1.0
-	detail::tvec4<T> ix(Pi0.x, Pi1.x, Pi0.x, Pi1.x);
-	detail::tvec4<T> iy(Pi0.y, Pi0.y, Pi1.y, Pi1.y);
-	detail::tvec4<T> iz0(Pi0.z);
-	detail::tvec4<T> iz1(Pi1.z);
-
-	detail::tvec4<T> ixy = permute(permute(ix) + iy);
-	detail::tvec4<T> ixy0 = permute(ixy + iz0);
-	detail::tvec4<T> ixy1 = permute(ixy + iz1);
-
-	detail::tvec4<T> gx0 = ixy0 / T(7);
-	detail::tvec4<T> gy0 = fract(floor(gx0) / T(7)) - T(0.5);
-	gx0 = fract(gx0);
-	detail::tvec4<T> gz0 = detail::tvec4<T>(0.5) - abs(gx0) - abs(gy0);
-	detail::tvec4<T> sz0 = step(gz0, detail::tvec4<T>(0.0));
-	gx0 -= sz0 * (step(0.0, gx0) - T(0.5));
-	gy0 -= sz0 * (step(0.0, gy0) - T(0.5));
-
-	detail::tvec4<T> gx1 = ixy1 / T(7);
-	detail::tvec4<T> gy1 = fract(floor(gx1) / T(7)) - T(0.5);
-	gx1 = fract(gx1);
-	detail::tvec4<T> gz1 = detail::tvec4<T>(0.5) - abs(gx1) - abs(gy1);
-	detail::tvec4<T> sz1 = step(gz1, detail::tvec4<T>(0.0));
-	gx1 -= sz1 * (step(T(0), gx1) - T(0.5));
-	gy1 -= sz1 * (step(T(0), gy1) - T(0.5));
-
-	detail::tvec3<T> g000(gx0.x, gy0.x, gz0.x);
-	detail::tvec3<T> g100(gx0.y, gy0.y, gz0.y);
-	detail::tvec3<T> g010(gx0.z, gy0.z, gz0.z);
-	detail::tvec3<T> g110(gx0.w, gy0.w, gz0.w);
-	detail::tvec3<T> g001(gx1.x, gy1.x, gz1.x);
-	detail::tvec3<T> g101(gx1.y, gy1.y, gz1.y);
-	detail::tvec3<T> g011(gx1.z, gy1.z, gz1.z);
-	detail::tvec3<T> g111(gx1.w, gy1.w, gz1.w);
-
-	detail::tvec4<T> norm0 = taylorInvSqrt(detail::tvec4<T>(dot(g000, g000), dot(g010, g010), dot(g100, g100), dot(g110, g110)));
-	g000 *= norm0.x;
-	g010 *= norm0.y;
-	g100 *= norm0.z;
-	g110 *= norm0.w;
-	detail::tvec4<T> norm1 = taylorInvSqrt(detail::tvec4<T>(dot(g001, g001), dot(g011, g011), dot(g101, g101), dot(g111, g111)));
-	g001 *= norm1.x;
-	g011 *= norm1.y;
-	g101 *= norm1.z;
-	g111 *= norm1.w;
-
-	T n000 = dot(g000, Pf0);
-	T n100 = dot(g100, detail::tvec3<T>(Pf1.x, Pf0.y, Pf0.z));
-	T n010 = dot(g010, detail::tvec3<T>(Pf0.x, Pf1.y, Pf0.z));
-	T n110 = dot(g110, detail::tvec3<T>(Pf1.x, Pf1.y, Pf0.z));
-	T n001 = dot(g001, detail::tvec3<T>(Pf0.x, Pf0.y, Pf1.z));
-	T n101 = dot(g101, detail::tvec3<T>(Pf1.x, Pf0.y, Pf1.z));
-	T n011 = dot(g011, detail::tvec3<T>(Pf0.x, Pf1.y, Pf1.z));
-	T n111 = dot(g111, Pf1);
-
-	detail::tvec3<T> fade_xyz = fade(Pf0);
-	detail::tvec4<T> n_z = mix(detail::tvec4<T>(n000, n100, n010, n110), detail::tvec4<T>(n001, n101, n011, n111), fade_xyz.z);
-	detail::tvec2<T> n_yz = mix(
-        detail::tvec2<T>(n_z.x, n_z.y), 
-        detail::tvec2<T>(n_z.z, n_z.w), fade_xyz.y);
-	T n_xyz = mix(n_yz.x, n_yz.y, fade_xyz.x); 
-	return T(2.2) * n_xyz;
-}
-*/
-// Classic Perlin noise
-template <typename T>
-GLM_FUNC_QUALIFIER T perlin(detail::tvec4<T> const & P)
-{
-	detail::tvec4<T> Pi0 = floor(P); // Integer part for indexing
-	detail::tvec4<T> Pi1 = Pi0 + T(1); // Integer part + 1
-	Pi0 = mod(Pi0, T(289));
-	Pi1 = mod(Pi1, T(289));
-	detail::tvec4<T> Pf0 = fract(P); // Fractional part for interpolation
-	detail::tvec4<T> Pf1 = Pf0 - T(1); // Fractional part - 1.0
-	detail::tvec4<T> ix(Pi0.x, Pi1.x, Pi0.x, Pi1.x);
-	detail::tvec4<T> iy(Pi0.y, Pi0.y, Pi1.y, Pi1.y);
-	detail::tvec4<T> iz0(Pi0.z);
-	detail::tvec4<T> iz1(Pi1.z);
-	detail::tvec4<T> iw0(Pi0.w);
-	detail::tvec4<T> iw1(Pi1.w);
-
-	detail::tvec4<T> ixy = permute(permute(ix) + iy);
-	detail::tvec4<T> ixy0 = permute(ixy + iz0);
-	detail::tvec4<T> ixy1 = permute(ixy + iz1);
-	detail::tvec4<T> ixy00 = permute(ixy0 + iw0);
-	detail::tvec4<T> ixy01 = permute(ixy0 + iw1);
-	detail::tvec4<T> ixy10 = permute(ixy1 + iw0);
-	detail::tvec4<T> ixy11 = permute(ixy1 + iw1);
-
-	detail::tvec4<T> gx00 = ixy00 / T(7);
-	detail::tvec4<T> gy00 = floor(gx00) / T(7);
-	detail::tvec4<T> gz00 = floor(gy00) / T(6);
-	gx00 = fract(gx00) - T(0.5);
-	gy00 = fract(gy00) - T(0.5);
-	gz00 = fract(gz00) - T(0.5);
-	detail::tvec4<T> gw00 = detail::tvec4<T>(0.75) - abs(gx00) - abs(gy00) - abs(gz00);
-	detail::tvec4<T> sw00 = step(gw00, detail::tvec4<T>(0.0));
-	gx00 -= sw00 * (step(T(0), gx00) - T(0.5));
-	gy00 -= sw00 * (step(T(0), gy00) - T(0.5));
-
-	detail::tvec4<T> gx01 = ixy01 / T(7);
-	detail::tvec4<T> gy01 = floor(gx01) / T(7);
-	detail::tvec4<T> gz01 = floor(gy01) / T(6);
-	gx01 = fract(gx01) - T(0.5);
-	gy01 = fract(gy01) - T(0.5);
-	gz01 = fract(gz01) - T(0.5);
-	detail::tvec4<T> gw01 = detail::tvec4<T>(0.75) - abs(gx01) - abs(gy01) - abs(gz01);
-	detail::tvec4<T> sw01 = step(gw01, detail::tvec4<T>(0.0));
-	gx01 -= sw01 * (step(T(0), gx01) - T(0.5));
-	gy01 -= sw01 * (step(T(0), gy01) - T(0.5));
-
-	detail::tvec4<T> gx10 = ixy10 / T(7);
-	detail::tvec4<T> gy10 = floor(gx10) / T(7);
-	detail::tvec4<T> gz10 = floor(gy10) / T(6);
-	gx10 = fract(gx10) - T(0.5);
-	gy10 = fract(gy10) - T(0.5);
-	gz10 = fract(gz10) - T(0.5);
-	detail::tvec4<T> gw10 = detail::tvec4<T>(0.75) - abs(gx10) - abs(gy10) - abs(gz10);
-	detail::tvec4<T> sw10 = step(gw10, detail::tvec4<T>(0));
-	gx10 -= sw10 * (step(T(0), gx10) - T(0.5));
-	gy10 -= sw10 * (step(T(0), gy10) - T(0.5));
-
-	detail::tvec4<T> gx11 = ixy11 / T(7);
-	detail::tvec4<T> gy11 = floor(gx11) / T(7);
-	detail::tvec4<T> gz11 = floor(gy11) / T(6);
-	gx11 = fract(gx11) - T(0.5);
-	gy11 = fract(gy11) - T(0.5);
-	gz11 = fract(gz11) - T(0.5);
-	detail::tvec4<T> gw11 = detail::tvec4<T>(0.75) - abs(gx11) - abs(gy11) - abs(gz11);
-	detail::tvec4<T> sw11 = step(gw11, detail::tvec4<T>(0.0));
-	gx11 -= sw11 * (step(T(0), gx11) - T(0.5));
-	gy11 -= sw11 * (step(T(0), gy11) - T(0.5));
-
-	detail::tvec4<T> g0000(gx00.x, gy00.x, gz00.x, gw00.x);
-	detail::tvec4<T> g1000(gx00.y, gy00.y, gz00.y, gw00.y);
-	detail::tvec4<T> g0100(gx00.z, gy00.z, gz00.z, gw00.z);
-	detail::tvec4<T> g1100(gx00.w, gy00.w, gz00.w, gw00.w);
-	detail::tvec4<T> g0010(gx10.x, gy10.x, gz10.x, gw10.x);
-	detail::tvec4<T> g1010(gx10.y, gy10.y, gz10.y, gw10.y);
-	detail::tvec4<T> g0110(gx10.z, gy10.z, gz10.z, gw10.z);
-	detail::tvec4<T> g1110(gx10.w, gy10.w, gz10.w, gw10.w);
-	detail::tvec4<T> g0001(gx01.x, gy01.x, gz01.x, gw01.x);
-	detail::tvec4<T> g1001(gx01.y, gy01.y, gz01.y, gw01.y);
-	detail::tvec4<T> g0101(gx01.z, gy01.z, gz01.z, gw01.z);
-	detail::tvec4<T> g1101(gx01.w, gy01.w, gz01.w, gw01.w);
-	detail::tvec4<T> g0011(gx11.x, gy11.x, gz11.x, gw11.x);
-	detail::tvec4<T> g1011(gx11.y, gy11.y, gz11.y, gw11.y);
-	detail::tvec4<T> g0111(gx11.z, gy11.z, gz11.z, gw11.z);
-	detail::tvec4<T> g1111(gx11.w, gy11.w, gz11.w, gw11.w);
-
-	detail::tvec4<T> norm00 = taylorInvSqrt(detail::tvec4<T>(dot(g0000, g0000), dot(g0100, g0100), dot(g1000, g1000), dot(g1100, g1100)));
-	g0000 *= norm00.x;
-	g0100 *= norm00.y;
-	g1000 *= norm00.z;
-	g1100 *= norm00.w;
-
-	detail::tvec4<T> norm01 = taylorInvSqrt(detail::tvec4<T>(dot(g0001, g0001), dot(g0101, g0101), dot(g1001, g1001), dot(g1101, g1101)));
-	g0001 *= norm01.x;
-	g0101 *= norm01.y;
-	g1001 *= norm01.z;
-	g1101 *= norm01.w;
-
-	detail::tvec4<T> norm10 = taylorInvSqrt(detail::tvec4<T>(dot(g0010, g0010), dot(g0110, g0110), dot(g1010, g1010), dot(g1110, g1110)));
-	g0010 *= norm10.x;
-	g0110 *= norm10.y;
-	g1010 *= norm10.z;
-	g1110 *= norm10.w;
-
-	detail::tvec4<T> norm11 = taylorInvSqrt(detail::tvec4<T>(dot(g0011, g0011), dot(g0111, g0111), dot(g1011, g1011), dot(g1111, g1111)));
-	g0011 *= norm11.x;
-	g0111 *= norm11.y;
-	g1011 *= norm11.z;
-	g1111 *= norm11.w;
-
-	T n0000 = dot(g0000, Pf0);
-	T n1000 = dot(g1000, detail::tvec4<T>(Pf1.x, Pf0.y, Pf0.z, Pf0.w));
-	T n0100 = dot(g0100, detail::tvec4<T>(Pf0.x, Pf1.y, Pf0.z, Pf0.w));
-	T n1100 = dot(g1100, detail::tvec4<T>(Pf1.x, Pf1.y, Pf0.z, Pf0.w));
-	T n0010 = dot(g0010, detail::tvec4<T>(Pf0.x, Pf0.y, Pf1.z, Pf0.w));
-	T n1010 = dot(g1010, detail::tvec4<T>(Pf1.x, Pf0.y, Pf1.z, Pf0.w));
-	T n0110 = dot(g0110, detail::tvec4<T>(Pf0.x, Pf1.y, Pf1.z, Pf0.w));
-	T n1110 = dot(g1110, detail::tvec4<T>(Pf1.x, Pf1.y, Pf1.z, Pf0.w));
-	T n0001 = dot(g0001, detail::tvec4<T>(Pf0.x, Pf0.y, Pf0.z, Pf1.w));
-	T n1001 = dot(g1001, detail::tvec4<T>(Pf1.x, Pf0.y, Pf0.z, Pf1.w));
-	T n0101 = dot(g0101, detail::tvec4<T>(Pf0.x, Pf1.y, Pf0.z, Pf1.w));
-	T n1101 = dot(g1101, detail::tvec4<T>(Pf1.x, Pf1.y, Pf0.z, Pf1.w));
-	T n0011 = dot(g0011, detail::tvec4<T>(Pf0.x, Pf0.y, Pf1.z, Pf1.w));
-	T n1011 = dot(g1011, detail::tvec4<T>(Pf1.x, Pf0.y, Pf1.z, Pf1.w));
-	T n0111 = dot(g0111, detail::tvec4<T>(Pf0.x, Pf1.y, Pf1.z, Pf1.w));
-	T n1111 = dot(g1111, Pf1);
-
-	detail::tvec4<T> fade_xyzw = fade(Pf0);
-	detail::tvec4<T> n_0w = mix(detail::tvec4<T>(n0000, n1000, n0100, n1100), detail::tvec4<T>(n0001, n1001, n0101, n1101), fade_xyzw.w);
-	detail::tvec4<T> n_1w = mix(detail::tvec4<T>(n0010, n1010, n0110, n1110), detail::tvec4<T>(n0011, n1011, n0111, n1111), fade_xyzw.w);
-	detail::tvec4<T> n_zw = mix(n_0w, n_1w, fade_xyzw.z);
-	detail::tvec2<T> n_yzw = mix(detail::tvec2<T>(n_zw.x, n_zw.y), detail::tvec2<T>(n_zw.z, n_zw.w), fade_xyzw.y);
-	T n_xyzw = mix(n_yzw.x, n_yzw.y, fade_xyzw.x);
-	return T(2.2) * n_xyzw;
-}
-
-// Classic Perlin noise, periodic variant
-template <typename T>
-GLM_FUNC_QUALIFIER T perlin(detail::tvec2<T> const & P, detail::tvec2<T> const & rep)
-{
-	detail::tvec4<T> Pi = floor(detail::tvec4<T>(P.x, P.y, P.x, P.y)) + detail::tvec4<T>(0.0, 0.0, 1.0, 1.0);
-	detail::tvec4<T> Pf = fract(detail::tvec4<T>(P.x, P.y, P.x, P.y)) - detail::tvec4<T>(0.0, 0.0, 1.0, 1.0);
-	Pi = mod(Pi, detail::tvec4<T>(rep.x, rep.y, rep.x, rep.y)); // To create noise with explicit period
-	Pi = mod(Pi, T(289)); // To avoid truncation effects in permutation
-	detail::tvec4<T> ix(Pi.x, Pi.z, Pi.x, Pi.z);
-	detail::tvec4<T> iy(Pi.y, Pi.y, Pi.w, Pi.w);
-	detail::tvec4<T> fx(Pf.x, Pf.z, Pf.x, Pf.z);
-	detail::tvec4<T> fy(Pf.y, Pf.y, Pf.w, Pf.w);
-
-	detail::tvec4<T> i = permute(permute(ix) + iy);
-
-	detail::tvec4<T> gx = T(2) * fract(i / T(41)) - T(1);
-	detail::tvec4<T> gy = abs(gx) - T(0.5);
-	detail::tvec4<T> tx = floor(gx + T(0.5));
-	gx = gx - tx;
-
-	detail::tvec2<T> g00(gx.x, gy.x);
-	detail::tvec2<T> g10(gx.y, gy.y);
-	detail::tvec2<T> g01(gx.z, gy.z);
-	detail::tvec2<T> g11(gx.w, gy.w);
-
-	detail::tvec4<T> norm = taylorInvSqrt(detail::tvec4<T>(dot(g00, g00), dot(g01, g01), dot(g10, g10), dot(g11, g11)));
-	g00 *= norm.x;  
-	g01 *= norm.y;  
-	g10 *= norm.z;  
-	g11 *= norm.w;  
-
-	T n00 = dot(g00, detail::tvec2<T>(fx.x, fy.x));
-	T n10 = dot(g10, detail::tvec2<T>(fx.y, fy.y));
-	T n01 = dot(g01, detail::tvec2<T>(fx.z, fy.z));
-	T n11 = dot(g11, detail::tvec2<T>(fx.w, fy.w));
-
-	detail::tvec2<T> fade_xy = fade(detail::tvec2<T>(Pf.x, Pf.y));
-	detail::tvec2<T> n_x = mix(detail::tvec2<T>(n00, n01), detail::tvec2<T>(n10, n11), fade_xy.x);
-	T n_xy = mix(n_x.x, n_x.y, fade_xy.y);
-	return T(2.3) * n_xy;
-}
-
-// Classic Perlin noise, periodic variant
-template <typename T>
-GLM_FUNC_QUALIFIER T perlin(detail::tvec3<T> const & P, detail::tvec3<T> const & rep)
-{
-	detail::tvec3<T> Pi0 = mod(floor(P), rep); // Integer part, modulo period
-	detail::tvec3<T> Pi1 = mod(Pi0 + detail::tvec3<T>(1.0), rep); // Integer part + 1, mod period
-	Pi0 = mod(Pi0, T(289));
-	Pi1 = mod(Pi1, T(289));
-	detail::tvec3<T> Pf0 = fract(P); // Fractional part for interpolation
-	detail::tvec3<T> Pf1 = Pf0 - detail::tvec3<T>(1.0); // Fractional part - 1.0
-	detail::tvec4<T> ix = detail::tvec4<T>(Pi0.x, Pi1.x, Pi0.x, Pi1.x);
-	detail::tvec4<T> iy = detail::tvec4<T>(Pi0.y, Pi0.y, Pi1.y, Pi1.y);
-	detail::tvec4<T> iz0(Pi0.z);
-	detail::tvec4<T> iz1(Pi1.z);
-
-	detail::tvec4<T> ixy = permute(permute(ix) + iy);
-	detail::tvec4<T> ixy0 = permute(ixy + iz0);
-	detail::tvec4<T> ixy1 = permute(ixy + iz1);
-
-	detail::tvec4<T> gx0 = ixy0 / T(7);
-	detail::tvec4<T> gy0 = fract(floor(gx0) / T(7)) - T(0.5);
-	gx0 = fract(gx0);
-	detail::tvec4<T> gz0 = detail::tvec4<T>(0.5) - abs(gx0) - abs(gy0);
-	detail::tvec4<T> sz0 = step(gz0, detail::tvec4<T>(0));
-	gx0 -= sz0 * (step(0.0, gx0) - T(0.5));
-	gy0 -= sz0 * (step(0.0, gy0) - T(0.5));
-
-	detail::tvec4<T> gx1 = ixy1 / T(7);
-	detail::tvec4<T> gy1 = fract(floor(gx1) / T(7)) - T(0.5);
-	gx1 = fract(gx1);
-	detail::tvec4<T> gz1 = detail::tvec4<T>(0.5) - abs(gx1) - abs(gy1);
-	detail::tvec4<T> sz1 = step(gz1, detail::tvec4<T>(0.0));
-	gx1 -= sz1 * (step(0.0, gx1) - T(0.5));
-	gy1 -= sz1 * (step(0.0, gy1) - T(0.5));
-
-	detail::tvec3<T> g000 = detail::tvec3<T>(gx0.x, gy0.x, gz0.x);
-	detail::tvec3<T> g100 = detail::tvec3<T>(gx0.y, gy0.y, gz0.y);
-	detail::tvec3<T> g010 = detail::tvec3<T>(gx0.z, gy0.z, gz0.z);
-	detail::tvec3<T> g110 = detail::tvec3<T>(gx0.w, gy0.w, gz0.w);
-	detail::tvec3<T> g001 = detail::tvec3<T>(gx1.x, gy1.x, gz1.x);
-	detail::tvec3<T> g101 = detail::tvec3<T>(gx1.y, gy1.y, gz1.y);
-	detail::tvec3<T> g011 = detail::tvec3<T>(gx1.z, gy1.z, gz1.z);
-	detail::tvec3<T> g111 = detail::tvec3<T>(gx1.w, gy1.w, gz1.w);
-
-	detail::tvec4<T> norm0 = taylorInvSqrt(detail::tvec4<T>(dot(g000, g000), dot(g010, g010), dot(g100, g100), dot(g110, g110)));
-	g000 *= norm0.x;
-	g010 *= norm0.y;
-	g100 *= norm0.z;
-	g110 *= norm0.w;
-	detail::tvec4<T> norm1 = taylorInvSqrt(detail::tvec4<T>(dot(g001, g001), dot(g011, g011), dot(g101, g101), dot(g111, g111)));
-	g001 *= norm1.x;
-	g011 *= norm1.y;
-	g101 *= norm1.z;
-	g111 *= norm1.w;
-
-	T n000 = dot(g000, Pf0);
-	T n100 = dot(g100, detail::tvec3<T>(Pf1.x, Pf0.y, Pf0.z));
-	T n010 = dot(g010, detail::tvec3<T>(Pf0.x, Pf1.y, Pf0.z));
-	T n110 = dot(g110, detail::tvec3<T>(Pf1.x, Pf1.y, Pf0.z));
-	T n001 = dot(g001, detail::tvec3<T>(Pf0.x, Pf0.y, Pf1.z));
-	T n101 = dot(g101, detail::tvec3<T>(Pf1.x, Pf0.y, Pf1.z));
-	T n011 = dot(g011, detail::tvec3<T>(Pf0.x, Pf1.y, Pf1.z));
-	T n111 = dot(g111, Pf1);
-
-	detail::tvec3<T> fade_xyz = fade(Pf0);
-	detail::tvec4<T> n_z = mix(detail::tvec4<T>(n000, n100, n010, n110), detail::tvec4<T>(n001, n101, n011, n111), fade_xyz.z);
-	detail::tvec2<T> n_yz = mix(detail::tvec2<T>(n_z.x, n_z.y), detail::tvec2<T>(n_z.z, n_z.w), fade_xyz.y);
-	T n_xyz = mix(n_yz.x, n_yz.y, fade_xyz.x); 
-	return T(2.2) * n_xyz;
-}
-
-// Classic Perlin noise, periodic version
-template <typename T>
-GLM_FUNC_QUALIFIER T perlin(detail::tvec4<T> const & P, detail::tvec4<T> const & rep)
-{
-	detail::tvec4<T> Pi0 = mod(floor(P), rep); // Integer part modulo rep
-	detail::tvec4<T> Pi1 = mod(Pi0 + T(1), rep); // Integer part + 1 mod rep
-	detail::tvec4<T> Pf0 = fract(P); // Fractional part for interpolation
-	detail::tvec4<T> Pf1 = Pf0 - T(1); // Fractional part - 1.0
-	detail::tvec4<T> ix = detail::tvec4<T>(Pi0.x, Pi1.x, Pi0.x, Pi1.x);
-	detail::tvec4<T> iy = detail::tvec4<T>(Pi0.y, Pi0.y, Pi1.y, Pi1.y);
-	detail::tvec4<T> iz0(Pi0.z);
-	detail::tvec4<T> iz1(Pi1.z);
-	detail::tvec4<T> iw0(Pi0.w);
-	detail::tvec4<T> iw1(Pi1.w);
-
-	detail::tvec4<T> ixy = permute(permute(ix) + iy);
-	detail::tvec4<T> ixy0 = permute(ixy + iz0);
-	detail::tvec4<T> ixy1 = permute(ixy + iz1);
-	detail::tvec4<T> ixy00 = permute(ixy0 + iw0);
-	detail::tvec4<T> ixy01 = permute(ixy0 + iw1);
-	detail::tvec4<T> ixy10 = permute(ixy1 + iw0);
-	detail::tvec4<T> ixy11 = permute(ixy1 + iw1);
-
-	detail::tvec4<T> gx00 = ixy00 / T(7);
-	detail::tvec4<T> gy00 = floor(gx00) / T(7);
-	detail::tvec4<T> gz00 = floor(gy00) / T(6);
-	gx00 = fract(gx00) - T(0.5);
-	gy00 = fract(gy00) - T(0.5);
-	gz00 = fract(gz00) - T(0.5);
-	detail::tvec4<T> gw00 = detail::tvec4<T>(0.75) - abs(gx00) - abs(gy00) - abs(gz00);
-	detail::tvec4<T> sw00 = step(gw00, detail::tvec4<T>(0));
-	gx00 -= sw00 * (step(0.0, gx00) - T(0.5));
-	gy00 -= sw00 * (step(0.0, gy00) - T(0.5));
-
-	detail::tvec4<T> gx01 = ixy01 / T(7);
-	detail::tvec4<T> gy01 = floor(gx01) / T(7);
-	detail::tvec4<T> gz01 = floor(gy01) / T(6);
-	gx01 = fract(gx01) - T(0.5);
-	gy01 = fract(gy01) - T(0.5);
-	gz01 = fract(gz01) - T(0.5);
-	detail::tvec4<T> gw01 = detail::tvec4<T>(0.75) - abs(gx01) - abs(gy01) - abs(gz01);
-	detail::tvec4<T> sw01 = step(gw01, detail::tvec4<T>(0.0));
-	gx01 -= sw01 * (step(0.0, gx01) - T(0.5));
-	gy01 -= sw01 * (step(0.0, gy01) - T(0.5));
-
-	detail::tvec4<T> gx10 = ixy10 / T(7);
-	detail::tvec4<T> gy10 = floor(gx10) / T(7);
-	detail::tvec4<T> gz10 = floor(gy10) / T(6);
-	gx10 = fract(gx10) - T(0.5);
-	gy10 = fract(gy10) - T(0.5);
-	gz10 = fract(gz10) - T(0.5);
-	detail::tvec4<T> gw10 = detail::tvec4<T>(0.75) - abs(gx10) - abs(gy10) - abs(gz10);
-	detail::tvec4<T> sw10 = step(gw10, detail::tvec4<T>(0.0));
-	gx10 -= sw10 * (step(0.0, gx10) - T(0.5));
-	gy10 -= sw10 * (step(0.0, gy10) - T(0.5));
-
-	detail::tvec4<T> gx11 = ixy11 / T(7);
-	detail::tvec4<T> gy11 = floor(gx11) / T(7);
-	detail::tvec4<T> gz11 = floor(gy11) / T(6);
-	gx11 = fract(gx11) - T(0.5);
-	gy11 = fract(gy11) - T(0.5);
-	gz11 = fract(gz11) - T(0.5);
-	detail::tvec4<T> gw11 = detail::tvec4<T>(0.75) - abs(gx11) - abs(gy11) - abs(gz11);
-	detail::tvec4<T> sw11 = step(gw11, detail::tvec4<T>(0.0));
-	gx11 -= sw11 * (step(0.0, gx11) - T(0.5));
-	gy11 -= sw11 * (step(0.0, gy11) - T(0.5));
-
-	detail::tvec4<T> g0000(gx00.x, gy00.x, gz00.x, gw00.x);
-	detail::tvec4<T> g1000(gx00.y, gy00.y, gz00.y, gw00.y);
-	detail::tvec4<T> g0100(gx00.z, gy00.z, gz00.z, gw00.z);
-	detail::tvec4<T> g1100(gx00.w, gy00.w, gz00.w, gw00.w);
-	detail::tvec4<T> g0010(gx10.x, gy10.x, gz10.x, gw10.x);
-	detail::tvec4<T> g1010(gx10.y, gy10.y, gz10.y, gw10.y);
-	detail::tvec4<T> g0110(gx10.z, gy10.z, gz10.z, gw10.z);
-	detail::tvec4<T> g1110(gx10.w, gy10.w, gz10.w, gw10.w);
-	detail::tvec4<T> g0001(gx01.x, gy01.x, gz01.x, gw01.x);
-	detail::tvec4<T> g1001(gx01.y, gy01.y, gz01.y, gw01.y);
-	detail::tvec4<T> g0101(gx01.z, gy01.z, gz01.z, gw01.z);
-	detail::tvec4<T> g1101(gx01.w, gy01.w, gz01.w, gw01.w);
-	detail::tvec4<T> g0011(gx11.x, gy11.x, gz11.x, gw11.x);
-	detail::tvec4<T> g1011(gx11.y, gy11.y, gz11.y, gw11.y);
-	detail::tvec4<T> g0111(gx11.z, gy11.z, gz11.z, gw11.z);
-	detail::tvec4<T> g1111(gx11.w, gy11.w, gz11.w, gw11.w);
-
-	detail::tvec4<T> norm00 = taylorInvSqrt(detail::tvec4<T>(dot(g0000, g0000), dot(g0100, g0100), dot(g1000, g1000), dot(g1100, g1100)));
-	g0000 *= norm00.x;
-	g0100 *= norm00.y;
-	g1000 *= norm00.z;
-	g1100 *= norm00.w;
-
-	detail::tvec4<T> norm01 = taylorInvSqrt(detail::tvec4<T>(dot(g0001, g0001), dot(g0101, g0101), dot(g1001, g1001), dot(g1101, g1101)));
-	g0001 *= norm01.x;
-	g0101 *= norm01.y;
-	g1001 *= norm01.z;
-	g1101 *= norm01.w;
-
-	detail::tvec4<T> norm10 = taylorInvSqrt(detail::tvec4<T>(dot(g0010, g0010), dot(g0110, g0110), dot(g1010, g1010), dot(g1110, g1110)));
-	g0010 *= norm10.x;
-	g0110 *= norm10.y;
-	g1010 *= norm10.z;
-	g1110 *= norm10.w;
-
-	detail::tvec4<T> norm11 = taylorInvSqrt(detail::tvec4<T>(dot(g0011, g0011), dot(g0111, g0111), dot(g1011, g1011), dot(g1111, g1111)));
-	g0011 *= norm11.x;
-	g0111 *= norm11.y;
-	g1011 *= norm11.z;
-	g1111 *= norm11.w;
-
-	T n0000 = dot(g0000, Pf0);
-	T n1000 = dot(g1000, detail::tvec4<T>(Pf1.x, Pf0.y, Pf0.z, Pf0.w));
-	T n0100 = dot(g0100, detail::tvec4<T>(Pf0.x, Pf1.y, Pf0.z, Pf0.w));
-	T n1100 = dot(g1100, detail::tvec4<T>(Pf1.x, Pf1.y, Pf0.z, Pf0.w));
-	T n0010 = dot(g0010, detail::tvec4<T>(Pf0.x, Pf0.y, Pf1.z, Pf0.w));
-	T n1010 = dot(g1010, detail::tvec4<T>(Pf1.x, Pf0.y, Pf1.z, Pf0.w));
-	T n0110 = dot(g0110, detail::tvec4<T>(Pf0.x, Pf1.y, Pf1.z, Pf0.w));
-	T n1110 = dot(g1110, detail::tvec4<T>(Pf1.x, Pf1.y, Pf1.z, Pf0.w));
-	T n0001 = dot(g0001, detail::tvec4<T>(Pf0.x, Pf0.y, Pf0.z, Pf1.w));
-	T n1001 = dot(g1001, detail::tvec4<T>(Pf1.x, Pf0.y, Pf0.z, Pf1.w));
-	T n0101 = dot(g0101, detail::tvec4<T>(Pf0.x, Pf1.y, Pf0.z, Pf1.w));
-	T n1101 = dot(g1101, detail::tvec4<T>(Pf1.x, Pf1.y, Pf0.z, Pf1.w));
-	T n0011 = dot(g0011, detail::tvec4<T>(Pf0.x, Pf0.y, Pf1.z, Pf1.w));
-	T n1011 = dot(g1011, detail::tvec4<T>(Pf1.x, Pf0.y, Pf1.z, Pf1.w));
-	T n0111 = dot(g0111, detail::tvec4<T>(Pf0.x, Pf1.y, Pf1.z, Pf1.w));
-	T n1111 = dot(g1111, Pf1);
-
-	detail::tvec4<T> fade_xyzw = fade(Pf0);
-	detail::tvec4<T> n_0w = mix(detail::tvec4<T>(n0000, n1000, n0100, n1100), detail::tvec4<T>(n0001, n1001, n0101, n1101), fade_xyzw.w);
-	detail::tvec4<T> n_1w = mix(detail::tvec4<T>(n0010, n1010, n0110, n1110), detail::tvec4<T>(n0011, n1011, n0111, n1111), fade_xyzw.w);
-	detail::tvec4<T> n_zw = mix(n_0w, n_1w, fade_xyzw.z);
-	detail::tvec2<T> n_yzw = mix(detail::tvec2<T>(n_zw.x, n_zw.y), detail::tvec2<T>(n_zw.z, n_zw.w), fade_xyzw.y);
-	T n_xyzw = mix(n_yzw.x, n_yzw.y, fade_xyzw.x);
-	return T(2.2) * n_xyzw;
-}
-
-template <typename T>
-GLM_FUNC_QUALIFIER T simplex(glm::detail::tvec2<T> const & v)
-{
-	detail::tvec4<T> const C = detail::tvec4<T>(
-		T( 0.211324865405187),  // (3.0 -  sqrt(3.0)) / 6.0
-		T( 0.366025403784439),  //  0.5 * (sqrt(3.0)  - 1.0)
-		T(-0.577350269189626),	// -1.0 + 2.0 * C.x
-		T( 0.024390243902439)); //  1.0 / 41.0
-
-	// First corner
-	detail::tvec2<T> i  = floor(v + dot(v, detail::tvec2<T>(C[1])));
-	detail::tvec2<T> x0 = v -   i + dot(i, detail::tvec2<T>(C[0]));
-
-	// Other corners
-	//i1.x = step( x0.y, x0.x ); // x0.x > x0.y ? 1.0 : 0.0
-	//i1.y = 1.0 - i1.x;
-	detail::tvec2<T> i1 = (x0.x > x0.y) ? detail::tvec2<T>(1, 0) : detail::tvec2<T>(0, 1);
-	// x0 = x0 - 0.0 + 0.0 * C.xx ;
-	// x1 = x0 - i1 + 1.0 * C.xx ;
-	// x2 = x0 - 1.0 + 2.0 * C.xx ;
-	detail::tvec4<T> x12 = detail::tvec4<T>(x0.x, x0.y, x0.x, x0.y) + detail::tvec4<T>(C.x, C.x, C.z, C.z);
-	x12 = detail::tvec4<T>(detail::tvec2<T>(x12) - i1, x12.z, x12.w);
-
-	// Permutations
-	i = mod(i, T(289)); // Avoid truncation effects in permutation
-	detail::tvec3<T> p = permute(
-		permute(i.y + detail::tvec3<T>(T(0), i1.y, T(1)))
-		+ i.x + detail::tvec3<T>(T(0), i1.x, T(1)));
-
-	detail::tvec3<T> m = max(T(0.5) - detail::tvec3<T>(
-		dot(x0, x0), 
-		dot(detail::tvec2<T>(x12.x, x12.y), detail::tvec2<T>(x12.x, x12.y)), 
-		dot(detail::tvec2<T>(x12.z, x12.w), detail::tvec2<T>(x12.z, x12.w))), T(0));
-	m = m * m ;
-	m = m * m ;
-
-	// Gradients: 41 points uniformly over a line, mapped onto a diamond.
-	// The ring size 17*17 = 289 is close to a multiple of 41 (41*7 = 287)
-
-	detail::tvec3<T> x = T(2) * fract(p * C.w) - T(1);
-	detail::tvec3<T> h = abs(x) - T(0.5);
-	detail::tvec3<T> ox = floor(x + T(0.5));
-	detail::tvec3<T> a0 = x - ox;
-
-	// Normalise gradients implicitly by scaling m
-	// Inlined for speed: m *= taylorInvSqrt( a0*a0 + h*h );
-	m *= T(1.79284291400159) - T(0.85373472095314) * (a0 * a0 + h * h);
-
-	// Compute final noise value at P
-	detail::tvec3<T> g;
-	g.x  = a0.x  * x0.x  + h.x  * x0.y;
-	//g.yz = a0.yz * x12.xz + h.yz * x12.yw;
-	g.y = a0.y * x12.x + h.y * x12.y;
-	g.z = a0.z * x12.z + h.z * x12.w;
-	return T(130) * dot(m, g);
-}
-
-template <typename T>
-GLM_FUNC_QUALIFIER T simplex(detail::tvec3<T> const & v)
-{ 
-	detail::tvec2<T> const C(1.0 / 6.0, 1.0 / 3.0);
-	detail::tvec4<T> const D(0.0, 0.5, 1.0, 2.0);
-
-	// First corner
-	detail::tvec3<T> i(floor(v + dot(v, detail::tvec3<T>(C.y))));
-	detail::tvec3<T> x0(v - i + dot(i, detail::tvec3<T>(C.x)));
-
-	// Other corners
-	detail::tvec3<T> g(step(detail::tvec3<T>(x0.y, x0.z, x0.x), x0));
-	detail::tvec3<T> l(T(1) - g);
-	detail::tvec3<T> i1(min(g, detail::tvec3<T>(l.z, l.x, l.y)));
-	detail::tvec3<T> i2(max(g, detail::tvec3<T>(l.z, l.x, l.y)));
-
-	//   x0 = x0 - 0.0 + 0.0 * C.xxx;
-	//   x1 = x0 - i1  + 1.0 * C.xxx;
-	//   x2 = x0 - i2  + 2.0 * C.xxx;
-	//   x3 = x0 - 1.0 + 3.0 * C.xxx;
-	detail::tvec3<T> x1(x0 - i1 + C.x);
-	detail::tvec3<T> x2(x0 - i2 + C.y); // 2.0*C.x = 1/3 = C.y
-	detail::tvec3<T> x3(x0 - D.y);      // -1.0+3.0*C.x = -0.5 = -D.y
-
-	// Permutations
-	i = mod289(i); 
-	detail::tvec4<T> p(permute(permute(permute( 
-		i.z + detail::tvec4<T>(T(0), i1.z, i2.z, T(1))) + 
-		i.y + detail::tvec4<T>(T(0), i1.y, i2.y, T(1))) + 
-		i.x + detail::tvec4<T>(T(0), i1.x, i2.x, T(1))));
-
-	// Gradients: 7x7 points over a square, mapped onto an octahedron.
-	// The ring size 17*17 = 289 is close to a multiple of 49 (49*6 = 294)
-	T n_ = T(0.142857142857); // 1.0/7.0
-	detail::tvec3<T> ns(n_ * detail::tvec3<T>(D.w, D.y, D.z) - detail::tvec3<T>(D.x, D.z, D.x));
-
-	detail::tvec4<T> j(p - T(49) * floor(p * ns.z * ns.z));  //  mod(p,7*7)
-
-	detail::tvec4<T> x_(floor(j * ns.z));
-	detail::tvec4<T> y_(floor(j - T(7) * x_));    // mod(j,N)
-
-	detail::tvec4<T> x(x_ * ns.x + ns.y);
-	detail::tvec4<T> y(y_ * ns.x + ns.y);
-	detail::tvec4<T> h(T(1) - abs(x) - abs(y));
-
-	detail::tvec4<T> b0(x.x, x.y, y.x, y.y);
-	detail::tvec4<T> b1(x.z, x.w, y.z, y.w);
-
-	// vec4 s0 = vec4(lessThan(b0,0.0))*2.0 - 1.0;
-	// vec4 s1 = vec4(lessThan(b1,0.0))*2.0 - 1.0;
-	detail::tvec4<T> s0(floor(b0) * T(2) + T(1));
-	detail::tvec4<T> s1(floor(b1) * T(2) + T(1));
-	detail::tvec4<T> sh(-step(h, detail::tvec4<T>(0.0)));
-
-	detail::tvec4<T> a0 = detail::tvec4<T>(b0.x, b0.z, b0.y, b0.w) + detail::tvec4<T>(s0.x, s0.z, s0.y, s0.w) * detail::tvec4<T>(sh.x, sh.x, sh.y, sh.y);
-	detail::tvec4<T> a1 = detail::tvec4<T>(b1.x, b1.z, b1.y, b1.w) + detail::tvec4<T>(s1.x, s1.z, s1.y, s1.w) * detail::tvec4<T>(sh.z, sh.z, sh.w, sh.w);
-
-	detail::tvec3<T> p0(a0.x, a0.y, h.x);
-	detail::tvec3<T> p1(a0.z, a0.w, h.y);
-	detail::tvec3<T> p2(a1.x, a1.y, h.z);
-	detail::tvec3<T> p3(a1.z, a1.w, h.w);
-
-	// Normalise gradients
-	detail::tvec4<T> norm = taylorInvSqrt(detail::tvec4<T>(dot(p0, p0), dot(p1, p1), dot(p2, p2), dot(p3, p3)));
-	p0 *= norm.x;
-	p1 *= norm.y;
-	p2 *= norm.z;
-	p3 *= norm.w;
-
-	// Mix final noise value
-	detail::tvec4<T> m = max(T(0.6) - detail::tvec4<T>(dot(x0, x0), dot(x1, x1), dot(x2, x2), dot(x3, x3)), T(0));
-	m = m * m;
-	return T(42) * dot(m * m, detail::tvec4<T>(dot(p0, x0), dot(p1, x1), dot(p2, x2), dot(p3, x3)));
-}
-
-template <typename T>
-GLM_FUNC_QUALIFIER T simplex(detail::tvec4<T> const & v)
-{
-	detail::tvec4<T> const C(
-		0.138196601125011,  // (5 - sqrt(5))/20  G4
-		0.276393202250021,  // 2 * G4
-		0.414589803375032,  // 3 * G4
-		-0.447213595499958); // -1 + 4 * G4
-
-	// (sqrt(5) - 1)/4 = F4, used once below
-	T const F4 = T(0.309016994374947451);
-
-	// First corner
-	detail::tvec4<T> i  = floor(v + dot(v, vec4(F4)));
-	detail::tvec4<T> x0 = v -   i + dot(i, vec4(C.x));
-
-	// Other corners
-
-	// Rank sorting originally contributed by Bill Licea-Kane, AMD (formerly ATI)
-	detail::tvec4<T> i0;
-	detail::tvec3<T> isX = step(detail::tvec3<T>(x0.y, x0.z, x0.w), detail::tvec3<T>(x0.x));
-	detail::tvec3<T> isYZ = step(detail::tvec3<T>(x0.z, x0.w, x0.w), detail::tvec3<T>(x0.y, x0.y, x0.z));
-	//  i0.x = dot(isX, vec3(1.0));
-	//i0.x = isX.x + isX.y + isX.z;
-	//i0.yzw = T(1) - isX;
-    i0 = detail::tvec4<T>(isX.x + isX.y + isX.z, T(1) - isX);
-	//  i0.y += dot(isYZ.xy, vec2(1.0));
-	i0.y += isYZ.x + isYZ.y;
-	//i0.zw += 1.0 - detail::tvec2<T>(isYZ.x, isYZ.y);
-    i0.z += T(1) - isYZ.x;
-    i0.w += T(1) - isYZ.y;
-	i0.z += isYZ.z;
-	i0.w += T(1) - isYZ.z;
-
-	// i0 now contains the unique values 0,1,2,3 in each channel
-	detail::tvec4<T> i3 = clamp(i0, 0.0, 1.0);
-	detail::tvec4<T> i2 = clamp(i0 - 1.0, 0.0, 1.0);
-	detail::tvec4<T> i1 = clamp(i0 - 2.0, 0.0, 1.0);
-
-	//  x0 = x0 - 0.0 + 0.0 * C.xxxx
-	//  x1 = x0 - i1  + 0.0 * C.xxxx
-	//  x2 = x0 - i2  + 0.0 * C.xxxx
-	//  x3 = x0 - i3  + 0.0 * C.xxxx
-	//  x4 = x0 - 1.0 + 4.0 * C.xxxx
-	detail::tvec4<T> x1 = x0 - i1 + C.x;
-	detail::tvec4<T> x2 = x0 - i2 + C.y;
-	detail::tvec4<T> x3 = x0 - i3 + C.z;
-	detail::tvec4<T> x4 = x0 + C.w;
-
-	// Permutations
-	i = mod(i, T(289)); 
-	T j0 = permute(permute(permute(permute(i.w) + i.z) + i.y) + i.x);
-	detail::tvec4<T> j1 = permute(permute(permute(permute(
-				i.w + detail::tvec4<T>(i1.w, i2.w, i3.w, T(1)))
-			+ i.z + detail::tvec4<T>(i1.z, i2.z, i3.z, T(1)))
-			+ i.y + detail::tvec4<T>(i1.y, i2.y, i3.y, T(1)))
-			+ i.x + detail::tvec4<T>(i1.x, i2.x, i3.x, T(1)));
-
-	// Gradients: 7x7x6 points over a cube, mapped onto a 4-cross polytope
-	// 7*7*6 = 294, which is close to the ring size 17*17 = 289.
-	detail::tvec4<T> ip = detail::tvec4<T>(T(1) / T(294), T(1) / T(49), T(1) / T(7), T(0));
-
-	detail::tvec4<T> p0 = grad4(j0,   ip);
-	detail::tvec4<T> p1 = grad4(j1.x, ip);
-	detail::tvec4<T> p2 = grad4(j1.y, ip);
-	detail::tvec4<T> p3 = grad4(j1.z, ip);
-	detail::tvec4<T> p4 = grad4(j1.w, ip);
-
-	// Normalise gradients
-	detail::tvec4<T> norm = taylorInvSqrt(detail::tvec4<T>(dot(p0, p0), dot(p1, p1), dot(p2, p2), dot(p3, p3)));
-	p0 *= norm.x;
-	p1 *= norm.y;
-	p2 *= norm.z;
-	p3 *= norm.w;
-	p4 *= taylorInvSqrt(dot(p4, p4));
-
-	// Mix contributions from the five corners
-	detail::tvec3<T> m0 = max(T(0.6) - detail::tvec3<T>(dot(x0, x0), dot(x1, x1), dot(x2, x2)), T(0));
-	detail::tvec2<T> m1 = max(T(0.6) - detail::tvec2<T>(dot(x3, x3), dot(x4, x4)             ), T(0));
-	m0 = m0 * m0;
-	m1 = m1 * m1;
-	return T(49) * 
-		(dot(m0 * m0, detail::tvec3<T>(dot(p0, x0), dot(p1, x1), dot(p2, x2))) + 
-		dot(m1 * m1, detail::tvec2<T>(dot(p3, x3), dot(p4, x4))));
-}
-
+	template <typename T>
+	GLM_FUNC_QUALIFIER T taylorInvSqrt(T const & r)
+	{
+		return T(1.79284291400159) - T(0.85373472095314) * r;
+	}
+
+	template <typename T, template<typename> class vecType>
+	GLM_FUNC_QUALIFIER vecType<T> taylorInvSqrt(vecType<T> const & r)
+	{
+		return T(1.79284291400159) - T(0.85373472095314) * r;
+	}
+
+	template <typename T, template <typename> class vecType> 
+	GLM_FUNC_QUALIFIER vecType<T> fade(vecType<T> const & t) 
+	{
+		return t * t * t * (t * (t * T(6) - T(15)) + T(10));
+	}
+
+	template <typename T>
+	GLM_FUNC_QUALIFIER detail::tvec4<T> grad4(T const & j, detail::tvec4<T> const & ip)
+	{
+		detail::tvec3<T> pXYZ = floor(fract(detail::tvec3<T>(j) * detail::tvec3<T>(ip)) * T(7)) * ip[2] - T(1);
+		T pW = T(1.5) - dot(abs(pXYZ), detail::tvec3<T>(1));
+		detail::tvec4<T> s = detail::tvec4<T>(lessThan(detail::tvec4<T>(pXYZ, pW), detail::tvec4<T>(0.0)));
+		pXYZ = pXYZ + (detail::tvec3<T>(s) * T(2) - T(1)) * s.w; 
+		return detail::tvec4<T>(pXYZ, pW);
+	}
+
+	// Classic Perlin noise
+	template <typename T>
+	GLM_FUNC_QUALIFIER T perlin(detail::tvec2<T> const & P)
+	{
+		detail::tvec4<T> Pi = glm::floor(detail::tvec4<T>(P.x, P.y, P.x, P.y)) + detail::tvec4<T>(0.0, 0.0, 1.0, 1.0);
+		detail::tvec4<T> Pf = glm::fract(detail::tvec4<T>(P.x, P.y, P.x, P.y)) - detail::tvec4<T>(0.0, 0.0, 1.0, 1.0);
+		Pi = mod(Pi, T(289)); // To avoid truncation effects in permutation
+		detail::tvec4<T> ix(Pi.x, Pi.z, Pi.x, Pi.z);
+		detail::tvec4<T> iy(Pi.y, Pi.y, Pi.w, Pi.w);
+		detail::tvec4<T> fx(Pf.x, Pf.z, Pf.x, Pf.z);
+		detail::tvec4<T> fy(Pf.y, Pf.y, Pf.w, Pf.w);
+
+		detail::tvec4<T> i = glm::permute(glm::permute(ix) + iy);
+
+		detail::tvec4<T> gx = T(2) * glm::fract(i / T(41)) - T(1);
+		detail::tvec4<T> gy = glm::abs(gx) - T(0.5);
+		detail::tvec4<T> tx = glm::floor(gx + T(0.5));
+		gx = gx - tx;
+
+		detail::tvec2<T> g00(gx.x, gy.x);
+		detail::tvec2<T> g10(gx.y, gy.y);
+		detail::tvec2<T> g01(gx.z, gy.z);
+		detail::tvec2<T> g11(gx.w, gy.w);
+
+		detail::tvec4<T> norm = taylorInvSqrt(detail::tvec4<T>(dot(g00, g00), dot(g01, g01), dot(g10, g10), dot(g11, g11)));
+		g00 *= norm.x;  
+		g01 *= norm.y;  
+		g10 *= norm.z;  
+		g11 *= norm.w;  
+
+		T n00 = dot(g00, detail::tvec2<T>(fx.x, fy.x));
+		T n10 = dot(g10, detail::tvec2<T>(fx.y, fy.y));
+		T n01 = dot(g01, detail::tvec2<T>(fx.z, fy.z));
+		T n11 = dot(g11, detail::tvec2<T>(fx.w, fy.w));
+
+		detail::tvec2<T> fade_xy = fade(detail::tvec2<T>(Pf.x, Pf.y));
+		detail::tvec2<T> n_x = mix(detail::tvec2<T>(n00, n01), detail::tvec2<T>(n10, n11), fade_xy.x);
+		T n_xy = mix(n_x.x, n_x.y, fade_xy.y);
+		return T(2.3) * n_xy;
+	}
+
+	// Classic Perlin noise
+	template <typename T>
+	GLM_FUNC_QUALIFIER T perlin(detail::tvec3<T> const & P)
+	{
+		detail::tvec3<T> Pi0 = floor(P); // Integer part for indexing
+		detail::tvec3<T> Pi1 = Pi0 + T(1); // Integer part + 1
+		Pi0 = mod289(Pi0);
+		Pi1 = mod289(Pi1);
+		detail::tvec3<T> Pf0 = fract(P); // Fractional part for interpolation
+		detail::tvec3<T> Pf1 = Pf0 - T(1); // Fractional part - 1.0
+		detail::tvec4<T> ix(Pi0.x, Pi1.x, Pi0.x, Pi1.x);
+		detail::tvec4<T> iy = detail::tvec4<T>(detail::tvec2<T>(Pi0.y), detail::tvec2<T>(Pi1.y));
+		detail::tvec4<T> iz0(Pi0.z);
+		detail::tvec4<T> iz1(Pi1.z);
+
+		detail::tvec4<T> ixy = permute(permute(ix) + iy);
+		detail::tvec4<T> ixy0 = permute(ixy + iz0);
+		detail::tvec4<T> ixy1 = permute(ixy + iz1);
+
+		detail::tvec4<T> gx0 = ixy0 * T(1.0 / 7.0);
+		detail::tvec4<T> gy0 = fract(floor(gx0) * T(1.0 / 7.0)) - T(0.5);
+		gx0 = fract(gx0);
+		detail::tvec4<T> gz0 = detail::tvec4<T>(0.5) - abs(gx0) - abs(gy0);
+		detail::tvec4<T> sz0 = step(gz0, detail::tvec4<T>(0.0));
+		gx0 -= sz0 * (step(T(0), gx0) - T(0.5));
+		gy0 -= sz0 * (step(T(0), gy0) - T(0.5));
+
+		detail::tvec4<T> gx1 = ixy1 * T(1.0 / 7.0);
+		detail::tvec4<T> gy1 = fract(floor(gx1) * T(1.0 / 7.0)) - T(0.5);
+		gx1 = fract(gx1);
+		detail::tvec4<T> gz1 = detail::tvec4<T>(0.5) - abs(gx1) - abs(gy1);
+		detail::tvec4<T> sz1 = step(gz1, detail::tvec4<T>(0.0));
+		gx1 -= sz1 * (step(T(0), gx1) - T(0.5));
+		gy1 -= sz1 * (step(T(0), gy1) - T(0.5));
+
+		detail::tvec3<T> g000(gx0.x, gy0.x, gz0.x);
+		detail::tvec3<T> g100(gx0.y, gy0.y, gz0.y);
+		detail::tvec3<T> g010(gx0.z, gy0.z, gz0.z);
+		detail::tvec3<T> g110(gx0.w, gy0.w, gz0.w);
+		detail::tvec3<T> g001(gx1.x, gy1.x, gz1.x);
+		detail::tvec3<T> g101(gx1.y, gy1.y, gz1.y);
+		detail::tvec3<T> g011(gx1.z, gy1.z, gz1.z);
+		detail::tvec3<T> g111(gx1.w, gy1.w, gz1.w);
+
+		detail::tvec4<T> norm0 = taylorInvSqrt(detail::tvec4<T>(dot(g000, g000), dot(g010, g010), dot(g100, g100), dot(g110, g110)));
+		g000 *= norm0.x;
+		g010 *= norm0.y;
+		g100 *= norm0.z;
+		g110 *= norm0.w;
+		detail::tvec4<T> norm1 = taylorInvSqrt(detail::tvec4<T>(dot(g001, g001), dot(g011, g011), dot(g101, g101), dot(g111, g111)));
+		g001 *= norm1.x;
+		g011 *= norm1.y;
+		g101 *= norm1.z;
+		g111 *= norm1.w;
+
+		T n000 = dot(g000, Pf0);
+		T n100 = dot(g100, detail::tvec3<T>(Pf1.x, Pf0.y, Pf0.z));
+		T n010 = dot(g010, detail::tvec3<T>(Pf0.x, Pf1.y, Pf0.z));
+		T n110 = dot(g110, detail::tvec3<T>(Pf1.x, Pf1.y, Pf0.z));
+		T n001 = dot(g001, detail::tvec3<T>(Pf0.x, Pf0.y, Pf1.z));
+		T n101 = dot(g101, detail::tvec3<T>(Pf1.x, Pf0.y, Pf1.z));
+		T n011 = dot(g011, detail::tvec3<T>(Pf0.x, Pf1.y, Pf1.z));
+		T n111 = dot(g111, Pf1);
+
+		detail::tvec3<T> fade_xyz = fade(Pf0);
+		detail::tvec4<T> n_z = mix(detail::tvec4<T>(n000, n100, n010, n110), detail::tvec4<T>(n001, n101, n011, n111), fade_xyz.z);
+		detail::tvec2<T> n_yz = mix(detail::tvec2<T>(n_z.x, n_z.y), detail::tvec2<T>(n_z.z, n_z.w), fade_xyz.y);
+		T n_xyz = mix(n_yz.x, n_yz.y, fade_xyz.x); 
+		return T(2.2) * n_xyz;
+	}
+	/*
+	// Classic Perlin noise
+	template <typename T>
+	GLM_FUNC_QUALIFIER T perlin(detail::tvec3<T> const & P)
+	{
+		detail::tvec3<T> Pi0 = floor(P); // Integer part for indexing
+		detail::tvec3<T> Pi1 = Pi0 + T(1); // Integer part + 1
+		Pi0 = mod(Pi0, T(289));
+		Pi1 = mod(Pi1, T(289));
+		detail::tvec3<T> Pf0 = fract(P); // Fractional part for interpolation
+		detail::tvec3<T> Pf1 = Pf0 - T(1); // Fractional part - 1.0
+		detail::tvec4<T> ix(Pi0.x, Pi1.x, Pi0.x, Pi1.x);
+		detail::tvec4<T> iy(Pi0.y, Pi0.y, Pi1.y, Pi1.y);
+		detail::tvec4<T> iz0(Pi0.z);
+		detail::tvec4<T> iz1(Pi1.z);
+
+		detail::tvec4<T> ixy = permute(permute(ix) + iy);
+		detail::tvec4<T> ixy0 = permute(ixy + iz0);
+		detail::tvec4<T> ixy1 = permute(ixy + iz1);
+
+		detail::tvec4<T> gx0 = ixy0 / T(7);
+		detail::tvec4<T> gy0 = fract(floor(gx0) / T(7)) - T(0.5);
+		gx0 = fract(gx0);
+		detail::tvec4<T> gz0 = detail::tvec4<T>(0.5) - abs(gx0) - abs(gy0);
+		detail::tvec4<T> sz0 = step(gz0, detail::tvec4<T>(0.0));
+		gx0 -= sz0 * (step(0.0, gx0) - T(0.5));
+		gy0 -= sz0 * (step(0.0, gy0) - T(0.5));
+
+		detail::tvec4<T> gx1 = ixy1 / T(7);
+		detail::tvec4<T> gy1 = fract(floor(gx1) / T(7)) - T(0.5);
+		gx1 = fract(gx1);
+		detail::tvec4<T> gz1 = detail::tvec4<T>(0.5) - abs(gx1) - abs(gy1);
+		detail::tvec4<T> sz1 = step(gz1, detail::tvec4<T>(0.0));
+		gx1 -= sz1 * (step(T(0), gx1) - T(0.5));
+		gy1 -= sz1 * (step(T(0), gy1) - T(0.5));
+
+		detail::tvec3<T> g000(gx0.x, gy0.x, gz0.x);
+		detail::tvec3<T> g100(gx0.y, gy0.y, gz0.y);
+		detail::tvec3<T> g010(gx0.z, gy0.z, gz0.z);
+		detail::tvec3<T> g110(gx0.w, gy0.w, gz0.w);
+		detail::tvec3<T> g001(gx1.x, gy1.x, gz1.x);
+		detail::tvec3<T> g101(gx1.y, gy1.y, gz1.y);
+		detail::tvec3<T> g011(gx1.z, gy1.z, gz1.z);
+		detail::tvec3<T> g111(gx1.w, gy1.w, gz1.w);
+
+		detail::tvec4<T> norm0 = taylorInvSqrt(detail::tvec4<T>(dot(g000, g000), dot(g010, g010), dot(g100, g100), dot(g110, g110)));
+		g000 *= norm0.x;
+		g010 *= norm0.y;
+		g100 *= norm0.z;
+		g110 *= norm0.w;
+		detail::tvec4<T> norm1 = taylorInvSqrt(detail::tvec4<T>(dot(g001, g001), dot(g011, g011), dot(g101, g101), dot(g111, g111)));
+		g001 *= norm1.x;
+		g011 *= norm1.y;
+		g101 *= norm1.z;
+		g111 *= norm1.w;
+
+		T n000 = dot(g000, Pf0);
+		T n100 = dot(g100, detail::tvec3<T>(Pf1.x, Pf0.y, Pf0.z));
+		T n010 = dot(g010, detail::tvec3<T>(Pf0.x, Pf1.y, Pf0.z));
+		T n110 = dot(g110, detail::tvec3<T>(Pf1.x, Pf1.y, Pf0.z));
+		T n001 = dot(g001, detail::tvec3<T>(Pf0.x, Pf0.y, Pf1.z));
+		T n101 = dot(g101, detail::tvec3<T>(Pf1.x, Pf0.y, Pf1.z));
+		T n011 = dot(g011, detail::tvec3<T>(Pf0.x, Pf1.y, Pf1.z));
+		T n111 = dot(g111, Pf1);
+
+		detail::tvec3<T> fade_xyz = fade(Pf0);
+		detail::tvec4<T> n_z = mix(detail::tvec4<T>(n000, n100, n010, n110), detail::tvec4<T>(n001, n101, n011, n111), fade_xyz.z);
+		detail::tvec2<T> n_yz = mix(
+			detail::tvec2<T>(n_z.x, n_z.y), 
+			detail::tvec2<T>(n_z.z, n_z.w), fade_xyz.y);
+		T n_xyz = mix(n_yz.x, n_yz.y, fade_xyz.x); 
+		return T(2.2) * n_xyz;
+	}
+	*/
+	// Classic Perlin noise
+	template <typename T>
+	GLM_FUNC_QUALIFIER T perlin(detail::tvec4<T> const & P)
+	{
+		detail::tvec4<T> Pi0 = floor(P); // Integer part for indexing
+		detail::tvec4<T> Pi1 = Pi0 + T(1); // Integer part + 1
+		Pi0 = mod(Pi0, T(289));
+		Pi1 = mod(Pi1, T(289));
+		detail::tvec4<T> Pf0 = fract(P); // Fractional part for interpolation
+		detail::tvec4<T> Pf1 = Pf0 - T(1); // Fractional part - 1.0
+		detail::tvec4<T> ix(Pi0.x, Pi1.x, Pi0.x, Pi1.x);
+		detail::tvec4<T> iy(Pi0.y, Pi0.y, Pi1.y, Pi1.y);
+		detail::tvec4<T> iz0(Pi0.z);
+		detail::tvec4<T> iz1(Pi1.z);
+		detail::tvec4<T> iw0(Pi0.w);
+		detail::tvec4<T> iw1(Pi1.w);
+
+		detail::tvec4<T> ixy = permute(permute(ix) + iy);
+		detail::tvec4<T> ixy0 = permute(ixy + iz0);
+		detail::tvec4<T> ixy1 = permute(ixy + iz1);
+		detail::tvec4<T> ixy00 = permute(ixy0 + iw0);
+		detail::tvec4<T> ixy01 = permute(ixy0 + iw1);
+		detail::tvec4<T> ixy10 = permute(ixy1 + iw0);
+		detail::tvec4<T> ixy11 = permute(ixy1 + iw1);
+
+		detail::tvec4<T> gx00 = ixy00 / T(7);
+		detail::tvec4<T> gy00 = floor(gx00) / T(7);
+		detail::tvec4<T> gz00 = floor(gy00) / T(6);
+		gx00 = fract(gx00) - T(0.5);
+		gy00 = fract(gy00) - T(0.5);
+		gz00 = fract(gz00) - T(0.5);
+		detail::tvec4<T> gw00 = detail::tvec4<T>(0.75) - abs(gx00) - abs(gy00) - abs(gz00);
+		detail::tvec4<T> sw00 = step(gw00, detail::tvec4<T>(0.0));
+		gx00 -= sw00 * (step(T(0), gx00) - T(0.5));
+		gy00 -= sw00 * (step(T(0), gy00) - T(0.5));
+
+		detail::tvec4<T> gx01 = ixy01 / T(7);
+		detail::tvec4<T> gy01 = floor(gx01) / T(7);
+		detail::tvec4<T> gz01 = floor(gy01) / T(6);
+		gx01 = fract(gx01) - T(0.5);
+		gy01 = fract(gy01) - T(0.5);
+		gz01 = fract(gz01) - T(0.5);
+		detail::tvec4<T> gw01 = detail::tvec4<T>(0.75) - abs(gx01) - abs(gy01) - abs(gz01);
+		detail::tvec4<T> sw01 = step(gw01, detail::tvec4<T>(0.0));
+		gx01 -= sw01 * (step(T(0), gx01) - T(0.5));
+		gy01 -= sw01 * (step(T(0), gy01) - T(0.5));
+
+		detail::tvec4<T> gx10 = ixy10 / T(7);
+		detail::tvec4<T> gy10 = floor(gx10) / T(7);
+		detail::tvec4<T> gz10 = floor(gy10) / T(6);
+		gx10 = fract(gx10) - T(0.5);
+		gy10 = fract(gy10) - T(0.5);
+		gz10 = fract(gz10) - T(0.5);
+		detail::tvec4<T> gw10 = detail::tvec4<T>(0.75) - abs(gx10) - abs(gy10) - abs(gz10);
+		detail::tvec4<T> sw10 = step(gw10, detail::tvec4<T>(0));
+		gx10 -= sw10 * (step(T(0), gx10) - T(0.5));
+		gy10 -= sw10 * (step(T(0), gy10) - T(0.5));
+
+		detail::tvec4<T> gx11 = ixy11 / T(7);
+		detail::tvec4<T> gy11 = floor(gx11) / T(7);
+		detail::tvec4<T> gz11 = floor(gy11) / T(6);
+		gx11 = fract(gx11) - T(0.5);
+		gy11 = fract(gy11) - T(0.5);
+		gz11 = fract(gz11) - T(0.5);
+		detail::tvec4<T> gw11 = detail::tvec4<T>(0.75) - abs(gx11) - abs(gy11) - abs(gz11);
+		detail::tvec4<T> sw11 = step(gw11, detail::tvec4<T>(0.0));
+		gx11 -= sw11 * (step(T(0), gx11) - T(0.5));
+		gy11 -= sw11 * (step(T(0), gy11) - T(0.5));
+
+		detail::tvec4<T> g0000(gx00.x, gy00.x, gz00.x, gw00.x);
+		detail::tvec4<T> g1000(gx00.y, gy00.y, gz00.y, gw00.y);
+		detail::tvec4<T> g0100(gx00.z, gy00.z, gz00.z, gw00.z);
+		detail::tvec4<T> g1100(gx00.w, gy00.w, gz00.w, gw00.w);
+		detail::tvec4<T> g0010(gx10.x, gy10.x, gz10.x, gw10.x);
+		detail::tvec4<T> g1010(gx10.y, gy10.y, gz10.y, gw10.y);
+		detail::tvec4<T> g0110(gx10.z, gy10.z, gz10.z, gw10.z);
+		detail::tvec4<T> g1110(gx10.w, gy10.w, gz10.w, gw10.w);
+		detail::tvec4<T> g0001(gx01.x, gy01.x, gz01.x, gw01.x);
+		detail::tvec4<T> g1001(gx01.y, gy01.y, gz01.y, gw01.y);
+		detail::tvec4<T> g0101(gx01.z, gy01.z, gz01.z, gw01.z);
+		detail::tvec4<T> g1101(gx01.w, gy01.w, gz01.w, gw01.w);
+		detail::tvec4<T> g0011(gx11.x, gy11.x, gz11.x, gw11.x);
+		detail::tvec4<T> g1011(gx11.y, gy11.y, gz11.y, gw11.y);
+		detail::tvec4<T> g0111(gx11.z, gy11.z, gz11.z, gw11.z);
+		detail::tvec4<T> g1111(gx11.w, gy11.w, gz11.w, gw11.w);
+
+		detail::tvec4<T> norm00 = taylorInvSqrt(detail::tvec4<T>(dot(g0000, g0000), dot(g0100, g0100), dot(g1000, g1000), dot(g1100, g1100)));
+		g0000 *= norm00.x;
+		g0100 *= norm00.y;
+		g1000 *= norm00.z;
+		g1100 *= norm00.w;
+
+		detail::tvec4<T> norm01 = taylorInvSqrt(detail::tvec4<T>(dot(g0001, g0001), dot(g0101, g0101), dot(g1001, g1001), dot(g1101, g1101)));
+		g0001 *= norm01.x;
+		g0101 *= norm01.y;
+		g1001 *= norm01.z;
+		g1101 *= norm01.w;
+
+		detail::tvec4<T> norm10 = taylorInvSqrt(detail::tvec4<T>(dot(g0010, g0010), dot(g0110, g0110), dot(g1010, g1010), dot(g1110, g1110)));
+		g0010 *= norm10.x;
+		g0110 *= norm10.y;
+		g1010 *= norm10.z;
+		g1110 *= norm10.w;
+
+		detail::tvec4<T> norm11 = taylorInvSqrt(detail::tvec4<T>(dot(g0011, g0011), dot(g0111, g0111), dot(g1011, g1011), dot(g1111, g1111)));
+		g0011 *= norm11.x;
+		g0111 *= norm11.y;
+		g1011 *= norm11.z;
+		g1111 *= norm11.w;
+
+		T n0000 = dot(g0000, Pf0);
+		T n1000 = dot(g1000, detail::tvec4<T>(Pf1.x, Pf0.y, Pf0.z, Pf0.w));
+		T n0100 = dot(g0100, detail::tvec4<T>(Pf0.x, Pf1.y, Pf0.z, Pf0.w));
+		T n1100 = dot(g1100, detail::tvec4<T>(Pf1.x, Pf1.y, Pf0.z, Pf0.w));
+		T n0010 = dot(g0010, detail::tvec4<T>(Pf0.x, Pf0.y, Pf1.z, Pf0.w));
+		T n1010 = dot(g1010, detail::tvec4<T>(Pf1.x, Pf0.y, Pf1.z, Pf0.w));
+		T n0110 = dot(g0110, detail::tvec4<T>(Pf0.x, Pf1.y, Pf1.z, Pf0.w));
+		T n1110 = dot(g1110, detail::tvec4<T>(Pf1.x, Pf1.y, Pf1.z, Pf0.w));
+		T n0001 = dot(g0001, detail::tvec4<T>(Pf0.x, Pf0.y, Pf0.z, Pf1.w));
+		T n1001 = dot(g1001, detail::tvec4<T>(Pf1.x, Pf0.y, Pf0.z, Pf1.w));
+		T n0101 = dot(g0101, detail::tvec4<T>(Pf0.x, Pf1.y, Pf0.z, Pf1.w));
+		T n1101 = dot(g1101, detail::tvec4<T>(Pf1.x, Pf1.y, Pf0.z, Pf1.w));
+		T n0011 = dot(g0011, detail::tvec4<T>(Pf0.x, Pf0.y, Pf1.z, Pf1.w));
+		T n1011 = dot(g1011, detail::tvec4<T>(Pf1.x, Pf0.y, Pf1.z, Pf1.w));
+		T n0111 = dot(g0111, detail::tvec4<T>(Pf0.x, Pf1.y, Pf1.z, Pf1.w));
+		T n1111 = dot(g1111, Pf1);
+
+		detail::tvec4<T> fade_xyzw = fade(Pf0);
+		detail::tvec4<T> n_0w = mix(detail::tvec4<T>(n0000, n1000, n0100, n1100), detail::tvec4<T>(n0001, n1001, n0101, n1101), fade_xyzw.w);
+		detail::tvec4<T> n_1w = mix(detail::tvec4<T>(n0010, n1010, n0110, n1110), detail::tvec4<T>(n0011, n1011, n0111, n1111), fade_xyzw.w);
+		detail::tvec4<T> n_zw = mix(n_0w, n_1w, fade_xyzw.z);
+		detail::tvec2<T> n_yzw = mix(detail::tvec2<T>(n_zw.x, n_zw.y), detail::tvec2<T>(n_zw.z, n_zw.w), fade_xyzw.y);
+		T n_xyzw = mix(n_yzw.x, n_yzw.y, fade_xyzw.x);
+		return T(2.2) * n_xyzw;
+	}
+
+	// Classic Perlin noise, periodic variant
+	template <typename T>
+	GLM_FUNC_QUALIFIER T perlin(detail::tvec2<T> const & P, detail::tvec2<T> const & rep)
+	{
+		detail::tvec4<T> Pi = floor(detail::tvec4<T>(P.x, P.y, P.x, P.y)) + detail::tvec4<T>(0.0, 0.0, 1.0, 1.0);
+		detail::tvec4<T> Pf = fract(detail::tvec4<T>(P.x, P.y, P.x, P.y)) - detail::tvec4<T>(0.0, 0.0, 1.0, 1.0);
+		Pi = mod(Pi, detail::tvec4<T>(rep.x, rep.y, rep.x, rep.y)); // To create noise with explicit period
+		Pi = mod(Pi, T(289)); // To avoid truncation effects in permutation
+		detail::tvec4<T> ix(Pi.x, Pi.z, Pi.x, Pi.z);
+		detail::tvec4<T> iy(Pi.y, Pi.y, Pi.w, Pi.w);
+		detail::tvec4<T> fx(Pf.x, Pf.z, Pf.x, Pf.z);
+		detail::tvec4<T> fy(Pf.y, Pf.y, Pf.w, Pf.w);
+
+		detail::tvec4<T> i = permute(permute(ix) + iy);
+
+		detail::tvec4<T> gx = T(2) * fract(i / T(41)) - T(1);
+		detail::tvec4<T> gy = abs(gx) - T(0.5);
+		detail::tvec4<T> tx = floor(gx + T(0.5));
+		gx = gx - tx;
+
+		detail::tvec2<T> g00(gx.x, gy.x);
+		detail::tvec2<T> g10(gx.y, gy.y);
+		detail::tvec2<T> g01(gx.z, gy.z);
+		detail::tvec2<T> g11(gx.w, gy.w);
+
+		detail::tvec4<T> norm = taylorInvSqrt(detail::tvec4<T>(dot(g00, g00), dot(g01, g01), dot(g10, g10), dot(g11, g11)));
+		g00 *= norm.x;  
+		g01 *= norm.y;  
+		g10 *= norm.z;  
+		g11 *= norm.w;  
+
+		T n00 = dot(g00, detail::tvec2<T>(fx.x, fy.x));
+		T n10 = dot(g10, detail::tvec2<T>(fx.y, fy.y));
+		T n01 = dot(g01, detail::tvec2<T>(fx.z, fy.z));
+		T n11 = dot(g11, detail::tvec2<T>(fx.w, fy.w));
+
+		detail::tvec2<T> fade_xy = fade(detail::tvec2<T>(Pf.x, Pf.y));
+		detail::tvec2<T> n_x = mix(detail::tvec2<T>(n00, n01), detail::tvec2<T>(n10, n11), fade_xy.x);
+		T n_xy = mix(n_x.x, n_x.y, fade_xy.y);
+		return T(2.3) * n_xy;
+	}
+
+	// Classic Perlin noise, periodic variant
+	template <typename T>
+	GLM_FUNC_QUALIFIER T perlin(detail::tvec3<T> const & P, detail::tvec3<T> const & rep)
+	{
+		detail::tvec3<T> Pi0 = mod(floor(P), rep); // Integer part, modulo period
+		detail::tvec3<T> Pi1 = mod(Pi0 + detail::tvec3<T>(1.0), rep); // Integer part + 1, mod period
+		Pi0 = mod(Pi0, T(289));
+		Pi1 = mod(Pi1, T(289));
+		detail::tvec3<T> Pf0 = fract(P); // Fractional part for interpolation
+		detail::tvec3<T> Pf1 = Pf0 - detail::tvec3<T>(1.0); // Fractional part - 1.0
+		detail::tvec4<T> ix = detail::tvec4<T>(Pi0.x, Pi1.x, Pi0.x, Pi1.x);
+		detail::tvec4<T> iy = detail::tvec4<T>(Pi0.y, Pi0.y, Pi1.y, Pi1.y);
+		detail::tvec4<T> iz0(Pi0.z);
+		detail::tvec4<T> iz1(Pi1.z);
+
+		detail::tvec4<T> ixy = permute(permute(ix) + iy);
+		detail::tvec4<T> ixy0 = permute(ixy + iz0);
+		detail::tvec4<T> ixy1 = permute(ixy + iz1);
+
+		detail::tvec4<T> gx0 = ixy0 / T(7);
+		detail::tvec4<T> gy0 = fract(floor(gx0) / T(7)) - T(0.5);
+		gx0 = fract(gx0);
+		detail::tvec4<T> gz0 = detail::tvec4<T>(0.5) - abs(gx0) - abs(gy0);
+		detail::tvec4<T> sz0 = step(gz0, detail::tvec4<T>(0));
+		gx0 -= sz0 * (step(0.0, gx0) - T(0.5));
+		gy0 -= sz0 * (step(0.0, gy0) - T(0.5));
+
+		detail::tvec4<T> gx1 = ixy1 / T(7);
+		detail::tvec4<T> gy1 = fract(floor(gx1) / T(7)) - T(0.5);
+		gx1 = fract(gx1);
+		detail::tvec4<T> gz1 = detail::tvec4<T>(0.5) - abs(gx1) - abs(gy1);
+		detail::tvec4<T> sz1 = step(gz1, detail::tvec4<T>(0.0));
+		gx1 -= sz1 * (step(0.0, gx1) - T(0.5));
+		gy1 -= sz1 * (step(0.0, gy1) - T(0.5));
+
+		detail::tvec3<T> g000 = detail::tvec3<T>(gx0.x, gy0.x, gz0.x);
+		detail::tvec3<T> g100 = detail::tvec3<T>(gx0.y, gy0.y, gz0.y);
+		detail::tvec3<T> g010 = detail::tvec3<T>(gx0.z, gy0.z, gz0.z);
+		detail::tvec3<T> g110 = detail::tvec3<T>(gx0.w, gy0.w, gz0.w);
+		detail::tvec3<T> g001 = detail::tvec3<T>(gx1.x, gy1.x, gz1.x);
+		detail::tvec3<T> g101 = detail::tvec3<T>(gx1.y, gy1.y, gz1.y);
+		detail::tvec3<T> g011 = detail::tvec3<T>(gx1.z, gy1.z, gz1.z);
+		detail::tvec3<T> g111 = detail::tvec3<T>(gx1.w, gy1.w, gz1.w);
+
+		detail::tvec4<T> norm0 = taylorInvSqrt(detail::tvec4<T>(dot(g000, g000), dot(g010, g010), dot(g100, g100), dot(g110, g110)));
+		g000 *= norm0.x;
+		g010 *= norm0.y;
+		g100 *= norm0.z;
+		g110 *= norm0.w;
+		detail::tvec4<T> norm1 = taylorInvSqrt(detail::tvec4<T>(dot(g001, g001), dot(g011, g011), dot(g101, g101), dot(g111, g111)));
+		g001 *= norm1.x;
+		g011 *= norm1.y;
+		g101 *= norm1.z;
+		g111 *= norm1.w;
+
+		T n000 = dot(g000, Pf0);
+		T n100 = dot(g100, detail::tvec3<T>(Pf1.x, Pf0.y, Pf0.z));
+		T n010 = dot(g010, detail::tvec3<T>(Pf0.x, Pf1.y, Pf0.z));
+		T n110 = dot(g110, detail::tvec3<T>(Pf1.x, Pf1.y, Pf0.z));
+		T n001 = dot(g001, detail::tvec3<T>(Pf0.x, Pf0.y, Pf1.z));
+		T n101 = dot(g101, detail::tvec3<T>(Pf1.x, Pf0.y, Pf1.z));
+		T n011 = dot(g011, detail::tvec3<T>(Pf0.x, Pf1.y, Pf1.z));
+		T n111 = dot(g111, Pf1);
+
+		detail::tvec3<T> fade_xyz = fade(Pf0);
+		detail::tvec4<T> n_z = mix(detail::tvec4<T>(n000, n100, n010, n110), detail::tvec4<T>(n001, n101, n011, n111), fade_xyz.z);
+		detail::tvec2<T> n_yz = mix(detail::tvec2<T>(n_z.x, n_z.y), detail::tvec2<T>(n_z.z, n_z.w), fade_xyz.y);
+		T n_xyz = mix(n_yz.x, n_yz.y, fade_xyz.x); 
+		return T(2.2) * n_xyz;
+	}
+
+	// Classic Perlin noise, periodic version
+	template <typename T>
+	GLM_FUNC_QUALIFIER T perlin(detail::tvec4<T> const & P, detail::tvec4<T> const & rep)
+	{
+		detail::tvec4<T> Pi0 = mod(floor(P), rep); // Integer part modulo rep
+		detail::tvec4<T> Pi1 = mod(Pi0 + T(1), rep); // Integer part + 1 mod rep
+		detail::tvec4<T> Pf0 = fract(P); // Fractional part for interpolation
+		detail::tvec4<T> Pf1 = Pf0 - T(1); // Fractional part - 1.0
+		detail::tvec4<T> ix = detail::tvec4<T>(Pi0.x, Pi1.x, Pi0.x, Pi1.x);
+		detail::tvec4<T> iy = detail::tvec4<T>(Pi0.y, Pi0.y, Pi1.y, Pi1.y);
+		detail::tvec4<T> iz0(Pi0.z);
+		detail::tvec4<T> iz1(Pi1.z);
+		detail::tvec4<T> iw0(Pi0.w);
+		detail::tvec4<T> iw1(Pi1.w);
+
+		detail::tvec4<T> ixy = permute(permute(ix) + iy);
+		detail::tvec4<T> ixy0 = permute(ixy + iz0);
+		detail::tvec4<T> ixy1 = permute(ixy + iz1);
+		detail::tvec4<T> ixy00 = permute(ixy0 + iw0);
+		detail::tvec4<T> ixy01 = permute(ixy0 + iw1);
+		detail::tvec4<T> ixy10 = permute(ixy1 + iw0);
+		detail::tvec4<T> ixy11 = permute(ixy1 + iw1);
+
+		detail::tvec4<T> gx00 = ixy00 / T(7);
+		detail::tvec4<T> gy00 = floor(gx00) / T(7);
+		detail::tvec4<T> gz00 = floor(gy00) / T(6);
+		gx00 = fract(gx00) - T(0.5);
+		gy00 = fract(gy00) - T(0.5);
+		gz00 = fract(gz00) - T(0.5);
+		detail::tvec4<T> gw00 = detail::tvec4<T>(0.75) - abs(gx00) - abs(gy00) - abs(gz00);
+		detail::tvec4<T> sw00 = step(gw00, detail::tvec4<T>(0));
+		gx00 -= sw00 * (step(0.0, gx00) - T(0.5));
+		gy00 -= sw00 * (step(0.0, gy00) - T(0.5));
+
+		detail::tvec4<T> gx01 = ixy01 / T(7);
+		detail::tvec4<T> gy01 = floor(gx01) / T(7);
+		detail::tvec4<T> gz01 = floor(gy01) / T(6);
+		gx01 = fract(gx01) - T(0.5);
+		gy01 = fract(gy01) - T(0.5);
+		gz01 = fract(gz01) - T(0.5);
+		detail::tvec4<T> gw01 = detail::tvec4<T>(0.75) - abs(gx01) - abs(gy01) - abs(gz01);
+		detail::tvec4<T> sw01 = step(gw01, detail::tvec4<T>(0.0));
+		gx01 -= sw01 * (step(0.0, gx01) - T(0.5));
+		gy01 -= sw01 * (step(0.0, gy01) - T(0.5));
+
+		detail::tvec4<T> gx10 = ixy10 / T(7);
+		detail::tvec4<T> gy10 = floor(gx10) / T(7);
+		detail::tvec4<T> gz10 = floor(gy10) / T(6);
+		gx10 = fract(gx10) - T(0.5);
+		gy10 = fract(gy10) - T(0.5);
+		gz10 = fract(gz10) - T(0.5);
+		detail::tvec4<T> gw10 = detail::tvec4<T>(0.75) - abs(gx10) - abs(gy10) - abs(gz10);
+		detail::tvec4<T> sw10 = step(gw10, detail::tvec4<T>(0.0));
+		gx10 -= sw10 * (step(0.0, gx10) - T(0.5));
+		gy10 -= sw10 * (step(0.0, gy10) - T(0.5));
+
+		detail::tvec4<T> gx11 = ixy11 / T(7);
+		detail::tvec4<T> gy11 = floor(gx11) / T(7);
+		detail::tvec4<T> gz11 = floor(gy11) / T(6);
+		gx11 = fract(gx11) - T(0.5);
+		gy11 = fract(gy11) - T(0.5);
+		gz11 = fract(gz11) - T(0.5);
+		detail::tvec4<T> gw11 = detail::tvec4<T>(0.75) - abs(gx11) - abs(gy11) - abs(gz11);
+		detail::tvec4<T> sw11 = step(gw11, detail::tvec4<T>(0.0));
+		gx11 -= sw11 * (step(0.0, gx11) - T(0.5));
+		gy11 -= sw11 * (step(0.0, gy11) - T(0.5));
+
+		detail::tvec4<T> g0000(gx00.x, gy00.x, gz00.x, gw00.x);
+		detail::tvec4<T> g1000(gx00.y, gy00.y, gz00.y, gw00.y);
+		detail::tvec4<T> g0100(gx00.z, gy00.z, gz00.z, gw00.z);
+		detail::tvec4<T> g1100(gx00.w, gy00.w, gz00.w, gw00.w);
+		detail::tvec4<T> g0010(gx10.x, gy10.x, gz10.x, gw10.x);
+		detail::tvec4<T> g1010(gx10.y, gy10.y, gz10.y, gw10.y);
+		detail::tvec4<T> g0110(gx10.z, gy10.z, gz10.z, gw10.z);
+		detail::tvec4<T> g1110(gx10.w, gy10.w, gz10.w, gw10.w);
+		detail::tvec4<T> g0001(gx01.x, gy01.x, gz01.x, gw01.x);
+		detail::tvec4<T> g1001(gx01.y, gy01.y, gz01.y, gw01.y);
+		detail::tvec4<T> g0101(gx01.z, gy01.z, gz01.z, gw01.z);
+		detail::tvec4<T> g1101(gx01.w, gy01.w, gz01.w, gw01.w);
+		detail::tvec4<T> g0011(gx11.x, gy11.x, gz11.x, gw11.x);
+		detail::tvec4<T> g1011(gx11.y, gy11.y, gz11.y, gw11.y);
+		detail::tvec4<T> g0111(gx11.z, gy11.z, gz11.z, gw11.z);
+		detail::tvec4<T> g1111(gx11.w, gy11.w, gz11.w, gw11.w);
+
+		detail::tvec4<T> norm00 = taylorInvSqrt(detail::tvec4<T>(dot(g0000, g0000), dot(g0100, g0100), dot(g1000, g1000), dot(g1100, g1100)));
+		g0000 *= norm00.x;
+		g0100 *= norm00.y;
+		g1000 *= norm00.z;
+		g1100 *= norm00.w;
+
+		detail::tvec4<T> norm01 = taylorInvSqrt(detail::tvec4<T>(dot(g0001, g0001), dot(g0101, g0101), dot(g1001, g1001), dot(g1101, g1101)));
+		g0001 *= norm01.x;
+		g0101 *= norm01.y;
+		g1001 *= norm01.z;
+		g1101 *= norm01.w;
+
+		detail::tvec4<T> norm10 = taylorInvSqrt(detail::tvec4<T>(dot(g0010, g0010), dot(g0110, g0110), dot(g1010, g1010), dot(g1110, g1110)));
+		g0010 *= norm10.x;
+		g0110 *= norm10.y;
+		g1010 *= norm10.z;
+		g1110 *= norm10.w;
+
+		detail::tvec4<T> norm11 = taylorInvSqrt(detail::tvec4<T>(dot(g0011, g0011), dot(g0111, g0111), dot(g1011, g1011), dot(g1111, g1111)));
+		g0011 *= norm11.x;
+		g0111 *= norm11.y;
+		g1011 *= norm11.z;
+		g1111 *= norm11.w;
+
+		T n0000 = dot(g0000, Pf0);
+		T n1000 = dot(g1000, detail::tvec4<T>(Pf1.x, Pf0.y, Pf0.z, Pf0.w));
+		T n0100 = dot(g0100, detail::tvec4<T>(Pf0.x, Pf1.y, Pf0.z, Pf0.w));
+		T n1100 = dot(g1100, detail::tvec4<T>(Pf1.x, Pf1.y, Pf0.z, Pf0.w));
+		T n0010 = dot(g0010, detail::tvec4<T>(Pf0.x, Pf0.y, Pf1.z, Pf0.w));
+		T n1010 = dot(g1010, detail::tvec4<T>(Pf1.x, Pf0.y, Pf1.z, Pf0.w));
+		T n0110 = dot(g0110, detail::tvec4<T>(Pf0.x, Pf1.y, Pf1.z, Pf0.w));
+		T n1110 = dot(g1110, detail::tvec4<T>(Pf1.x, Pf1.y, Pf1.z, Pf0.w));
+		T n0001 = dot(g0001, detail::tvec4<T>(Pf0.x, Pf0.y, Pf0.z, Pf1.w));
+		T n1001 = dot(g1001, detail::tvec4<T>(Pf1.x, Pf0.y, Pf0.z, Pf1.w));
+		T n0101 = dot(g0101, detail::tvec4<T>(Pf0.x, Pf1.y, Pf0.z, Pf1.w));
+		T n1101 = dot(g1101, detail::tvec4<T>(Pf1.x, Pf1.y, Pf0.z, Pf1.w));
+		T n0011 = dot(g0011, detail::tvec4<T>(Pf0.x, Pf0.y, Pf1.z, Pf1.w));
+		T n1011 = dot(g1011, detail::tvec4<T>(Pf1.x, Pf0.y, Pf1.z, Pf1.w));
+		T n0111 = dot(g0111, detail::tvec4<T>(Pf0.x, Pf1.y, Pf1.z, Pf1.w));
+		T n1111 = dot(g1111, Pf1);
+
+		detail::tvec4<T> fade_xyzw = fade(Pf0);
+		detail::tvec4<T> n_0w = mix(detail::tvec4<T>(n0000, n1000, n0100, n1100), detail::tvec4<T>(n0001, n1001, n0101, n1101), fade_xyzw.w);
+		detail::tvec4<T> n_1w = mix(detail::tvec4<T>(n0010, n1010, n0110, n1110), detail::tvec4<T>(n0011, n1011, n0111, n1111), fade_xyzw.w);
+		detail::tvec4<T> n_zw = mix(n_0w, n_1w, fade_xyzw.z);
+		detail::tvec2<T> n_yzw = mix(detail::tvec2<T>(n_zw.x, n_zw.y), detail::tvec2<T>(n_zw.z, n_zw.w), fade_xyzw.y);
+		T n_xyzw = mix(n_yzw.x, n_yzw.y, fade_xyzw.x);
+		return T(2.2) * n_xyzw;
+	}
+
+	template <typename T>
+	GLM_FUNC_QUALIFIER T simplex(glm::detail::tvec2<T> const & v)
+	{
+		detail::tvec4<T> const C = detail::tvec4<T>(
+			T( 0.211324865405187),  // (3.0 -  sqrt(3.0)) / 6.0
+			T( 0.366025403784439),  //  0.5 * (sqrt(3.0)  - 1.0)
+			T(-0.577350269189626),	// -1.0 + 2.0 * C.x
+			T( 0.024390243902439)); //  1.0 / 41.0
+
+		// First corner
+		detail::tvec2<T> i  = floor(v + dot(v, detail::tvec2<T>(C[1])));
+		detail::tvec2<T> x0 = v -   i + dot(i, detail::tvec2<T>(C[0]));
+
+		// Other corners
+		//i1.x = step( x0.y, x0.x ); // x0.x > x0.y ? 1.0 : 0.0
+		//i1.y = 1.0 - i1.x;
+		detail::tvec2<T> i1 = (x0.x > x0.y) ? detail::tvec2<T>(1, 0) : detail::tvec2<T>(0, 1);
+		// x0 = x0 - 0.0 + 0.0 * C.xx ;
+		// x1 = x0 - i1 + 1.0 * C.xx ;
+		// x2 = x0 - 1.0 + 2.0 * C.xx ;
+		detail::tvec4<T> x12 = detail::tvec4<T>(x0.x, x0.y, x0.x, x0.y) + detail::tvec4<T>(C.x, C.x, C.z, C.z);
+		x12 = detail::tvec4<T>(detail::tvec2<T>(x12) - i1, x12.z, x12.w);
+
+		// Permutations
+		i = mod(i, T(289)); // Avoid truncation effects in permutation
+		detail::tvec3<T> p = permute(
+			permute(i.y + detail::tvec3<T>(T(0), i1.y, T(1)))
+			+ i.x + detail::tvec3<T>(T(0), i1.x, T(1)));
+
+		detail::tvec3<T> m = max(T(0.5) - detail::tvec3<T>(
+			dot(x0, x0), 
+			dot(detail::tvec2<T>(x12.x, x12.y), detail::tvec2<T>(x12.x, x12.y)), 
+			dot(detail::tvec2<T>(x12.z, x12.w), detail::tvec2<T>(x12.z, x12.w))), T(0));
+		m = m * m ;
+		m = m * m ;
+
+		// Gradients: 41 points uniformly over a line, mapped onto a diamond.
+		// The ring size 17*17 = 289 is close to a multiple of 41 (41*7 = 287)
+
+		detail::tvec3<T> x = T(2) * fract(p * C.w) - T(1);
+		detail::tvec3<T> h = abs(x) - T(0.5);
+		detail::tvec3<T> ox = floor(x + T(0.5));
+		detail::tvec3<T> a0 = x - ox;
+
+		// Normalise gradients implicitly by scaling m
+		// Inlined for speed: m *= taylorInvSqrt( a0*a0 + h*h );
+		m *= T(1.79284291400159) - T(0.85373472095314) * (a0 * a0 + h * h);
+
+		// Compute final noise value at P
+		detail::tvec3<T> g;
+		g.x  = a0.x  * x0.x  + h.x  * x0.y;
+		//g.yz = a0.yz * x12.xz + h.yz * x12.yw;
+		g.y = a0.y * x12.x + h.y * x12.y;
+		g.z = a0.z * x12.z + h.z * x12.w;
+		return T(130) * dot(m, g);
+	}
+
+	template <typename T>
+	GLM_FUNC_QUALIFIER T simplex(detail::tvec3<T> const & v)
+	{ 
+		detail::tvec2<T> const C(1.0 / 6.0, 1.0 / 3.0);
+		detail::tvec4<T> const D(0.0, 0.5, 1.0, 2.0);
+
+		// First corner
+		detail::tvec3<T> i(floor(v + dot(v, detail::tvec3<T>(C.y))));
+		detail::tvec3<T> x0(v - i + dot(i, detail::tvec3<T>(C.x)));
+
+		// Other corners
+		detail::tvec3<T> g(step(detail::tvec3<T>(x0.y, x0.z, x0.x), x0));
+		detail::tvec3<T> l(T(1) - g);
+		detail::tvec3<T> i1(min(g, detail::tvec3<T>(l.z, l.x, l.y)));
+		detail::tvec3<T> i2(max(g, detail::tvec3<T>(l.z, l.x, l.y)));
+
+		//   x0 = x0 - 0.0 + 0.0 * C.xxx;
+		//   x1 = x0 - i1  + 1.0 * C.xxx;
+		//   x2 = x0 - i2  + 2.0 * C.xxx;
+		//   x3 = x0 - 1.0 + 3.0 * C.xxx;
+		detail::tvec3<T> x1(x0 - i1 + C.x);
+		detail::tvec3<T> x2(x0 - i2 + C.y); // 2.0*C.x = 1/3 = C.y
+		detail::tvec3<T> x3(x0 - D.y);      // -1.0+3.0*C.x = -0.5 = -D.y
+
+		// Permutations
+		i = mod289(i); 
+		detail::tvec4<T> p(permute(permute(permute( 
+			i.z + detail::tvec4<T>(T(0), i1.z, i2.z, T(1))) + 
+			i.y + detail::tvec4<T>(T(0), i1.y, i2.y, T(1))) + 
+			i.x + detail::tvec4<T>(T(0), i1.x, i2.x, T(1))));
+
+		// Gradients: 7x7 points over a square, mapped onto an octahedron.
+		// The ring size 17*17 = 289 is close to a multiple of 49 (49*6 = 294)
+		T n_ = T(0.142857142857); // 1.0/7.0
+		detail::tvec3<T> ns(n_ * detail::tvec3<T>(D.w, D.y, D.z) - detail::tvec3<T>(D.x, D.z, D.x));
+
+		detail::tvec4<T> j(p - T(49) * floor(p * ns.z * ns.z));  //  mod(p,7*7)
+
+		detail::tvec4<T> x_(floor(j * ns.z));
+		detail::tvec4<T> y_(floor(j - T(7) * x_));    // mod(j,N)
+
+		detail::tvec4<T> x(x_ * ns.x + ns.y);
+		detail::tvec4<T> y(y_ * ns.x + ns.y);
+		detail::tvec4<T> h(T(1) - abs(x) - abs(y));
+
+		detail::tvec4<T> b0(x.x, x.y, y.x, y.y);
+		detail::tvec4<T> b1(x.z, x.w, y.z, y.w);
+
+		// vec4 s0 = vec4(lessThan(b0,0.0))*2.0 - 1.0;
+		// vec4 s1 = vec4(lessThan(b1,0.0))*2.0 - 1.0;
+		detail::tvec4<T> s0(floor(b0) * T(2) + T(1));
+		detail::tvec4<T> s1(floor(b1) * T(2) + T(1));
+		detail::tvec4<T> sh(-step(h, detail::tvec4<T>(0.0)));
+
+		detail::tvec4<T> a0 = detail::tvec4<T>(b0.x, b0.z, b0.y, b0.w) + detail::tvec4<T>(s0.x, s0.z, s0.y, s0.w) * detail::tvec4<T>(sh.x, sh.x, sh.y, sh.y);
+		detail::tvec4<T> a1 = detail::tvec4<T>(b1.x, b1.z, b1.y, b1.w) + detail::tvec4<T>(s1.x, s1.z, s1.y, s1.w) * detail::tvec4<T>(sh.z, sh.z, sh.w, sh.w);
+
+		detail::tvec3<T> p0(a0.x, a0.y, h.x);
+		detail::tvec3<T> p1(a0.z, a0.w, h.y);
+		detail::tvec3<T> p2(a1.x, a1.y, h.z);
+		detail::tvec3<T> p3(a1.z, a1.w, h.w);
+
+		// Normalise gradients
+		detail::tvec4<T> norm = taylorInvSqrt(detail::tvec4<T>(dot(p0, p0), dot(p1, p1), dot(p2, p2), dot(p3, p3)));
+		p0 *= norm.x;
+		p1 *= norm.y;
+		p2 *= norm.z;
+		p3 *= norm.w;
+
+		// Mix final noise value
+		detail::tvec4<T> m = max(T(0.6) - detail::tvec4<T>(dot(x0, x0), dot(x1, x1), dot(x2, x2), dot(x3, x3)), T(0));
+		m = m * m;
+		return T(42) * dot(m * m, detail::tvec4<T>(dot(p0, x0), dot(p1, x1), dot(p2, x2), dot(p3, x3)));
+	}
+
+	template <typename T>
+	GLM_FUNC_QUALIFIER T simplex(detail::tvec4<T> const & v)
+	{
+		detail::tvec4<T> const C(
+			0.138196601125011,  // (5 - sqrt(5))/20  G4
+			0.276393202250021,  // 2 * G4
+			0.414589803375032,  // 3 * G4
+			-0.447213595499958); // -1 + 4 * G4
+
+		// (sqrt(5) - 1)/4 = F4, used once below
+		T const F4 = T(0.309016994374947451);
+
+		// First corner
+		detail::tvec4<T> i  = floor(v + dot(v, vec4(F4)));
+		detail::tvec4<T> x0 = v -   i + dot(i, vec4(C.x));
+
+		// Other corners
+
+		// Rank sorting originally contributed by Bill Licea-Kane, AMD (formerly ATI)
+		detail::tvec4<T> i0;
+		detail::tvec3<T> isX = step(detail::tvec3<T>(x0.y, x0.z, x0.w), detail::tvec3<T>(x0.x));
+		detail::tvec3<T> isYZ = step(detail::tvec3<T>(x0.z, x0.w, x0.w), detail::tvec3<T>(x0.y, x0.y, x0.z));
+		//  i0.x = dot(isX, vec3(1.0));
+		//i0.x = isX.x + isX.y + isX.z;
+		//i0.yzw = T(1) - isX;
+		i0 = detail::tvec4<T>(isX.x + isX.y + isX.z, T(1) - isX);
+		//  i0.y += dot(isYZ.xy, vec2(1.0));
+		i0.y += isYZ.x + isYZ.y;
+		//i0.zw += 1.0 - detail::tvec2<T>(isYZ.x, isYZ.y);
+		i0.z += T(1) - isYZ.x;
+		i0.w += T(1) - isYZ.y;
+		i0.z += isYZ.z;
+		i0.w += T(1) - isYZ.z;
+
+		// i0 now contains the unique values 0,1,2,3 in each channel
+		detail::tvec4<T> i3 = clamp(i0, 0.0, 1.0);
+		detail::tvec4<T> i2 = clamp(i0 - 1.0, 0.0, 1.0);
+		detail::tvec4<T> i1 = clamp(i0 - 2.0, 0.0, 1.0);
+
+		//  x0 = x0 - 0.0 + 0.0 * C.xxxx
+		//  x1 = x0 - i1  + 0.0 * C.xxxx
+		//  x2 = x0 - i2  + 0.0 * C.xxxx
+		//  x3 = x0 - i3  + 0.0 * C.xxxx
+		//  x4 = x0 - 1.0 + 4.0 * C.xxxx
+		detail::tvec4<T> x1 = x0 - i1 + C.x;
+		detail::tvec4<T> x2 = x0 - i2 + C.y;
+		detail::tvec4<T> x3 = x0 - i3 + C.z;
+		detail::tvec4<T> x4 = x0 + C.w;
+
+		// Permutations
+		i = mod(i, T(289)); 
+		T j0 = permute(permute(permute(permute(i.w) + i.z) + i.y) + i.x);
+		detail::tvec4<T> j1 = permute(permute(permute(permute(
+					i.w + detail::tvec4<T>(i1.w, i2.w, i3.w, T(1)))
+				+ i.z + detail::tvec4<T>(i1.z, i2.z, i3.z, T(1)))
+				+ i.y + detail::tvec4<T>(i1.y, i2.y, i3.y, T(1)))
+				+ i.x + detail::tvec4<T>(i1.x, i2.x, i3.x, T(1)));
+
+		// Gradients: 7x7x6 points over a cube, mapped onto a 4-cross polytope
+		// 7*7*6 = 294, which is close to the ring size 17*17 = 289.
+		detail::tvec4<T> ip = detail::tvec4<T>(T(1) / T(294), T(1) / T(49), T(1) / T(7), T(0));
+
+		detail::tvec4<T> p0 = grad4(j0,   ip);
+		detail::tvec4<T> p1 = grad4(j1.x, ip);
+		detail::tvec4<T> p2 = grad4(j1.y, ip);
+		detail::tvec4<T> p3 = grad4(j1.z, ip);
+		detail::tvec4<T> p4 = grad4(j1.w, ip);
+
+		// Normalise gradients
+		detail::tvec4<T> norm = taylorInvSqrt(detail::tvec4<T>(dot(p0, p0), dot(p1, p1), dot(p2, p2), dot(p3, p3)));
+		p0 *= norm.x;
+		p1 *= norm.y;
+		p2 *= norm.z;
+		p3 *= norm.w;
+		p4 *= taylorInvSqrt(dot(p4, p4));
+
+		// Mix contributions from the five corners
+		detail::tvec3<T> m0 = max(T(0.6) - detail::tvec3<T>(dot(x0, x0), dot(x1, x1), dot(x2, x2)), T(0));
+		detail::tvec2<T> m1 = max(T(0.6) - detail::tvec2<T>(dot(x3, x3), dot(x4, x4)             ), T(0));
+		m0 = m0 * m0;
+		m1 = m1 * m1;
+		return T(49) * 
+			(dot(m0 * m0, detail::tvec3<T>(dot(p0, x0), dot(p1, x1), dot(p2, x2))) + 
+			dot(m1 * m1, detail::tvec2<T>(dot(p3, x3), dot(p4, x4))));
+	}
 }//namespace glm
 }//namespace glm

+ 2 - 2
glm/gtc/quaternion.inl

@@ -29,8 +29,8 @@
 #include <limits>
 #include <limits>
 
 
 namespace glm{
 namespace glm{
-namespace detail{
-
+namespace detail
+{
     template <typename T> 
     template <typename T> 
     GLM_FUNC_QUALIFIER tquat<T>::tquat() : 
     GLM_FUNC_QUALIFIER tquat<T>::tquat() : 
         x(0),
         x(0),

+ 113 - 177
glm/gtc/random.inl

@@ -9,200 +9,136 @@
 
 
 #include <ctime>
 #include <ctime>
 #include <cassert>
 #include <cassert>
+#include "../core/_vectorize.hpp"
 
 
 namespace glm{
 namespace glm{
-
-template <> 
-GLM_FUNC_QUALIFIER glm::half linearRand
-(
-	glm::half const & Min, 
-	glm::half const & Max
-)
-{
-	return glm::half(float(std::rand()) / float(RAND_MAX) * (float(Max) - float(Min)) + float(Min));
-}
-	
-template <> 
-GLM_FUNC_QUALIFIER float linearRand
-(
-	float const & Min, 
-	float const & Max
-)
-{
-	return float(std::rand()) / float(RAND_MAX) * (Max - Min) + Min;
-}
-	
-template <> 
-GLM_FUNC_QUALIFIER double linearRand
-(
-	double const & Min, 
-	double const & Max
-)
-{
-	return double(std::rand()) / double(RAND_MAX) * (Max - Min) + Min;
-}
-	
-template <typename T>
-GLM_FUNC_QUALIFIER detail::tvec2<T> linearRand
-(
-	detail::tvec2<T> const & Min, 
-	detail::tvec2<T> const & Max
-)
-{
-	return detail::tvec2<T>(
-		linearRand(Min.x, Max.x),
-		linearRand(Min.y, Max.y));
-}
-	
-template <typename T>
-GLM_FUNC_QUALIFIER detail::tvec3<T> linearRand
-(
-	detail::tvec3<T> const & Min, 
-	detail::tvec3<T> const & Max
-)
+namespace detail
 {
 {
-	return detail::tvec3<T>(
-		linearRand(Min.x, Max.x),
-		linearRand(Min.y, Max.y),
-		linearRand(Min.z, Max.z));
-}
+	struct compute_linearRand
+	{
+		template <typename T>
+		GLM_FUNC_QUALIFIER T operator() (T const & Min, T const & Max) const
+		{
+			GLM_STATIC_ASSERT(0, "'linearRand' invalid template parameter type. GLM_GTC_random only supports floating-point template types.");
+			return Min;
+		}
+	};
 
 
-template <typename T>
-GLM_FUNC_QUALIFIER detail::tvec4<T> linearRand
-(
-	detail::tvec4<T> const & Min, 
-	detail::tvec4<T> const & Max
-)
-{
-	return detail::tvec4<T>(
-		linearRand(Min.x, Max.x),
-		linearRand(Min.y, Max.y),
-		linearRand(Min.z, Max.z),
-		linearRand(Min.w, Max.w));
-}
+	template <>
+	GLM_FUNC_QUALIFIER half compute_linearRand::operator()<half> (half const & Min, half const & Max) const
+	{
+		return half(float(std::rand()) / float(RAND_MAX) * (float(Max) - float(Min)) + float(Min));
+	}
 
 
-template <typename genType> 
-GLM_FUNC_QUALIFIER genType gaussRand
-(
-	genType const & Mean,	
-	genType const & Deviation
-)
-{
-    genType w, x1, x2;
+	template <>
+	GLM_FUNC_QUALIFIER float compute_linearRand::operator()<float> (float const & Min, float const & Max) const
+	{
+		return float(std::rand()) / float(RAND_MAX) * (Max - Min) + Min;
+	}
+
+	template <>
+	GLM_FUNC_QUALIFIER double compute_linearRand::operator()<double> (double const & Min, double const & Max) const
+	{
+		return double(std::rand()) / double(RAND_MAX) * (Max - Min) + Min;
+	}
+}//namespace detail
+
+	template <typename genType> 
+	GLM_FUNC_QUALIFIER genType linearRand
+	(
+		genType const & Min, 
+		genType const & Max
+	)
+	{
+		return detail::compute_linearRand()(Min, Max);
+	}
+
+	VECTORIZE_VEC_VEC(linearRand)
+
+	template <typename genType> 
+	GLM_FUNC_QUALIFIER genType gaussRand
+	(
+		genType const & Mean,	
+		genType const & Deviation
+	)
+	{
+		genType w, x1, x2;
 	
 	
-    do
-    {
-        x1 = linearRand(genType(-1), genType(1));
-        x2 = linearRand(genType(-1), genType(1));
+		do
+		{
+			x1 = linearRand(genType(-1), genType(1));
+			x2 = linearRand(genType(-1), genType(1));
 		
 		
-        w = x1 * x1 + x2 * x2;
-    } while(w > genType(1));
+			w = x1 * x1 + x2 * x2;
+		} while(w > genType(1));
 	
 	
-    return x2 * Deviation * Deviation * sqrt((genType(-2) * log(w)) / w) + Mean;
-}
+		return x2 * Deviation * Deviation * sqrt((genType(-2) * log(w)) / w) + Mean;
+	}
 
 
-template <typename T>
-GLM_FUNC_QUALIFIER detail::tvec2<T> gaussRand
-(
-	detail::tvec2<T> const & Mean, 
-	detail::tvec2<T> const & Deviation
-)
-{
-	return detail::tvec2<T>(
-		gaussRand(Mean.x, Deviation.x),
-		gaussRand(Mean.y, Deviation.y));
-}
-	
-template <typename T>
-GLM_FUNC_QUALIFIER detail::tvec3<T> gaussRand
-(
-	detail::tvec3<T> const & Mean, 
-	detail::tvec3<T> const & Deviation
-)
-{
-	return detail::tvec3<T>(
-		gaussRand(Mean.x, Deviation.x),
-		gaussRand(Mean.y, Deviation.y),
-		gaussRand(Mean.z, Deviation.z));
-}
-	
-template <typename T>
-GLM_FUNC_QUALIFIER detail::tvec4<T> gaussRand
-(
-	detail::tvec4<T> const & Mean, 
-	detail::tvec4<T> const & Deviation
-)
-{
-	return detail::tvec4<T>(
-		gaussRand(Mean.x, Deviation.x),
-		gaussRand(Mean.y, Deviation.y),
-		gaussRand(Mean.z, Deviation.z),
-		gaussRand(Mean.w, Deviation.w));
-}
-	
-template <typename T>
-GLM_FUNC_QUALIFIER detail::tvec2<T> diskRand
-(
-	T const & Radius
-)
-{		
-	detail::tvec2<T> Result(T(0));
-	T LenRadius(T(0));
+	VECTORIZE_VEC_VEC(gaussRand)
+
+	template <typename T>
+	GLM_FUNC_QUALIFIER detail::tvec2<T> diskRand
+	(
+		T const & Radius
+	)
+	{		
+		detail::tvec2<T> Result(T(0));
+		T LenRadius(T(0));
 		
 		
-	do
-	{
-		Result = linearRand(detail::tvec2<T>(-Radius), detail::tvec2<T>(Radius));
-		LenRadius = length(Result);
-	}
-	while(LenRadius > Radius);
+		do
+		{
+			Result = linearRand(detail::tvec2<T>(-Radius), detail::tvec2<T>(Radius));
+			LenRadius = length(Result);
+		}
+		while(LenRadius > Radius);
 		
 		
-	return Result;
-}
+		return Result;
+	}
 	
 	
-template <typename T>
-GLM_FUNC_QUALIFIER detail::tvec3<T> ballRand
-(
-	T const & Radius
-)
-{		
-	detail::tvec3<T> Result(T(0));
-	T LenRadius(T(0));
+	template <typename T>
+	GLM_FUNC_QUALIFIER detail::tvec3<T> ballRand
+	(
+		T const & Radius
+	)
+	{		
+		detail::tvec3<T> Result(T(0));
+		T LenRadius(T(0));
 		
 		
-	do
-	{
-		Result = linearRand(detail::tvec3<T>(-Radius), detail::tvec3<T>(Radius));
-		LenRadius = length(Result);
-	}
-	while(LenRadius > Radius);
+		do
+		{
+			Result = linearRand(detail::tvec3<T>(-Radius), detail::tvec3<T>(Radius));
+			LenRadius = length(Result);
+		}
+		while(LenRadius > Radius);
 		
 		
-	return Result;
-}
+		return Result;
+	}
 	
 	
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tvec2<T> circularRand
-(
-	T const & Radius
-)
-{
-	T a = linearRand(T(0), T(6.283185307179586476925286766559f));
-	return detail::tvec2<T>(cos(a), sin(a)) * Radius;		
-}
+	template <typename T> 
+	GLM_FUNC_QUALIFIER detail::tvec2<T> circularRand
+	(
+		T const & Radius
+	)
+	{
+		T a = linearRand(T(0), T(6.283185307179586476925286766559f));
+		return detail::tvec2<T>(cos(a), sin(a)) * Radius;		
+	}
 	
 	
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tvec3<T> sphericalRand
-(
-	T const & Radius
-)
-{
-	T z = linearRand(T(-1), T(1));
-	T a = linearRand(T(0), T(6.283185307179586476925286766559f));
+	template <typename T> 
+	GLM_FUNC_QUALIFIER detail::tvec3<T> sphericalRand
+	(
+		T const & Radius
+	)
+	{
+		T z = linearRand(T(-1), T(1));
+		T a = linearRand(T(0), T(6.283185307179586476925286766559f));
 	
 	
-	T r = sqrt(T(1) - z * z);
+		T r = sqrt(T(1) - z * z);
 	
 	
-	T x = r * cos(a);
-	T y = r * sin(a);
+		T x = r * cos(a);
+		T y = r * sin(a);
 	
 	
-	return detail::tvec3<T>(x, y, z) * Radius;	
-}
-
+		return detail::tvec3<T>(x, y, z) * Radius;	
+	}
 }//namespace glm
 }//namespace glm

+ 87 - 161
glm/gtc/swizzle.inl

@@ -26,165 +26,91 @@
 /// @author Christophe Riccio
 /// @author Christophe Riccio
 ///////////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////////
 
 
-namespace glm{
-
-template <typename T, template <typename> class vecType>
-GLM_FUNC_QUALIFIER T swizzle
-(	
-	vecType<T> const & v,
-	comp x
-)
-{
-	assert(int(x) < int(vecType<T>::value_size));
-	return v[x];
-}
-
-template <typename T, template <typename> class vecType>
-GLM_FUNC_QUALIFIER detail::tvec2<T> swizzle
-(
-	vecType<T> const & v,
-	comp x, comp y
-)
-{
-	return detail::tvec2<T>(
-		v[x],
-		v[y]);
-}
-
-template <typename T, template <typename> class vecType>
-GLM_FUNC_QUALIFIER detail::tvec3<T> swizzle
-(
-	vecType<T> const & v,
-	comp x, comp y, comp z
-)
-{
-	return detail::tvec3<T>(
-		v[x],
-		v[y],
-		v[z]);
-}
-
-template <typename T, template <typename> class vecType>
-GLM_FUNC_QUALIFIER detail::tvec4<T> swizzle
-(
-	vecType<T> const & v,
-	comp x, comp y, comp z, comp w
-)
-{
-	return detail::tvec4<T>(v[x], v[y],	v[z], v[w]);
-}
-
-template <typename T>
-GLM_FUNC_QUALIFIER T& swizzle
-(
-	detail::tvec4<T> & v,
-	comp x
-)
-{
-	return v[x];
-}
-
-template <typename T>
-GLM_FUNC_QUALIFIER detail::tref2<T> swizzle
-(
-	detail::tvec4<T> & v,
-	comp x, comp y
-)
-{
-	return detail::tref2<T>(v[x], v[y]);
-}
-
-template <typename T>
-GLM_FUNC_QUALIFIER detail::tref3<T> swizzle
-(
-	detail::tvec4<T> & v,
-	comp x, comp y, comp z
-)
-{
-	return detail::tref3<T>(v[x], v[y],	v[z]);
-}
-
-template <typename T>
-GLM_FUNC_QUALIFIER detail::tref4<T> swizzle
-(
-	detail::tvec4<T> & v,
-	comp x, comp y, comp z, comp w
-)
-{
-	return detail::tref4<T>(v[x], v[y],	v[z], v[w]);
-}
-/*
-template <comp x>
-GLM_FUNC_QUALIFIER float& swizzle
-(
-	detail::tvec4<float> & v
-)
-{
-	return v[x];
-}
-
-template <comp x>
-GLM_FUNC_QUALIFIER int& swizzle
-(
-	detail::tvec4<int> & v
-)
-{
-	return v[x];
-}
-
-template <comp x, comp y>
-GLM_FUNC_QUALIFIER detail::tref2<float> swizzle
-(
-	detail::tvec4<float> & v
-)
-{
-	return detail::tref2<float>(v[x], v[y]);
-}
-
-template <comp x, comp y>
-GLM_FUNC_QUALIFIER detail::tref2<int> swizzle
-(
-	detail::tvec4<int> & v
-)
-{
-	return detail::tref2<int>(v[x], v[y]);
-}
-
-template <comp x, comp y, comp z>
-GLM_FUNC_QUALIFIER detail::tref3<float> swizzle
-(
-	detail::tvec4<float> & v
-)
-{
-	return detail::tref3<float>(v[x], v[y],	v[z]);
-}
-	
-template <comp x, comp y, comp z>
-GLM_FUNC_QUALIFIER detail::tref3<int> swizzle
-(
-	detail::tvec4<int> & v
-)
-{
-	return detail::tref3<int>(v[x], v[y], v[z]);
-}
-
-template <comp x, comp y, comp z, comp w>
-GLM_FUNC_QUALIFIER detail::tref4<float> swizzle
-(
-	detail::tvec4<float> & v
-)
-{
-	return detail::tref4<float>(v[x], v[y],	v[z], v[w]);
-}
-
-template <comp x, comp y, comp z, comp w>
-GLM_FUNC_QUALIFIER detail::tref4<int> swizzle
-(
-	detail::tvec4<int> & v
-)
-{
-	return detail::tref4<int>(v[x], v[y],	v[z], v[w]);
-}
-*/
-
+namespace glm
+{
+	template <typename T, template <typename> class vecType>
+	GLM_FUNC_QUALIFIER T swizzle
+	(	
+		vecType<T> const & v,
+		comp x
+	)
+	{
+		assert(int(x) < int(vecType<T>::value_size));
+		return v[x];
+	}
+
+	template <typename T, template <typename> class vecType>
+	GLM_FUNC_QUALIFIER detail::tvec2<T> swizzle
+	(
+		vecType<T> const & v,
+		comp x, comp y
+	)
+	{
+		return detail::tvec2<T>(
+			v[x],
+			v[y]);
+	}
+
+	template <typename T, template <typename> class vecType>
+	GLM_FUNC_QUALIFIER detail::tvec3<T> swizzle
+	(
+		vecType<T> const & v,
+		comp x, comp y, comp z
+	)
+	{
+		return detail::tvec3<T>(
+			v[x],
+			v[y],
+			v[z]);
+	}
+
+	template <typename T, template <typename> class vecType>
+	GLM_FUNC_QUALIFIER detail::tvec4<T> swizzle
+	(
+		vecType<T> const & v,
+		comp x, comp y, comp z, comp w
+	)
+	{
+		return detail::tvec4<T>(v[x], v[y],	v[z], v[w]);
+	}
+
+	template <typename T>
+	GLM_FUNC_QUALIFIER T& swizzle
+	(
+		detail::tvec4<T> & v,
+		comp x
+	)
+	{
+		return v[x];
+	}
+
+	template <typename T>
+	GLM_FUNC_QUALIFIER detail::tref2<T> swizzle
+	(
+		detail::tvec4<T> & v,
+		comp x, comp y
+	)
+	{
+		return detail::tref2<T>(v[x], v[y]);
+	}
+
+	template <typename T>
+	GLM_FUNC_QUALIFIER detail::tref3<T> swizzle
+	(
+		detail::tvec4<T> & v,
+		comp x, comp y, comp z
+	)
+	{
+		return detail::tref3<T>(v[x], v[y],	v[z]);
+	}
+
+	template <typename T>
+	GLM_FUNC_QUALIFIER detail::tref4<T> swizzle
+	(
+		detail::tvec4<T> & v,
+		comp x, comp y, comp z, comp w
+	)
+	{
+		return detail::tref4<T>(v[x], v[y],	v[z], v[w]);
+	}
 }//namespace glm
 }//namespace glm

+ 581 - 751
glm/gtx/bit.inl

@@ -8,766 +8,596 @@
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 
 #include "../core/_detail.hpp"
 #include "../core/_detail.hpp"
+#include "../core/_vectorize.hpp"
 
 
-namespace glm{
-
-template <typename genIType>
-GLM_FUNC_QUALIFIER genIType mask
-(
-	genIType const & count
-)
-{
-	return ((genIType(1) << (count)) - genIType(1));
-}
-
-template <typename valIType>
-GLM_FUNC_QUALIFIER detail::tvec2<valIType> mask
-(
-	detail::tvec2<valIType> const & count
-)
-{
-	return detail::tvec2<valIType>(
-		mask(count[0]),
-		mask(count[1]));
-}
-
-template <typename valIType>
-GLM_FUNC_QUALIFIER detail::tvec3<valIType> mask
-(
-	detail::tvec3<valIType> const & count
-)
-{
-	return detail::tvec3<valIType>(
-		mask(count[0]),
-		mask(count[1]),
-		mask(count[2]));
-}
-
-template <typename valIType>
-GLM_FUNC_QUALIFIER detail::tvec4<valIType> mask
-(
-	detail::tvec4<valIType> const & count
-)
-{
-	return detail::tvec4<valIType>(
-		mask(count[0]),
-		mask(count[1]),
-		mask(count[2]),
-		mask(count[3]));
-}
-
-// extractField
-template <typename genIType>
-GLM_FUNC_QUALIFIER genIType extractField
-(
-	half const & value, 
-	genIType const & first, 
-	genIType const & count
-)
-{
-	assert(first + count < sizeof(half));
-	return (value._data() << first) >> ((sizeof(half) << 3) - count);
-}
-
-template <typename genIType>
-GLM_FUNC_QUALIFIER genIType extractField
-(
-	float const & value, 
-	genIType const & first, 
-	genIType const & count
-)
-{
-	assert(first + count < sizeof(float));
-	return (detail::uif32(value).i << first) >> ((sizeof(float) << 3) - count);
-}
-
-template <typename genIType>
-GLM_FUNC_QUALIFIER genIType extractField
-(
-	double const & value, 
-	genIType const & first, 
-	genIType const & count
-)
+namespace glm
 {
 {
-	assert(first + count < sizeof(double));
-	return (detail::uif64(value).i << first) >> ((sizeof(double) << genIType(3)) - count);
-}
-
-template <typename genIUType, typename sizeType>
-GLM_FUNC_QUALIFIER genIUType extractField
-(
-	genIUType const & Value, 
-	sizeType const & First, 
-	sizeType const & Count
-)
-{
-	sizeType GenSize = sizeof(genIUType) << 3;
+	template <typename genIType>
+	GLM_FUNC_QUALIFIER genIType mask
+	(
+		genIType const & count
+	)
+	{
+		return ((genIType(1) << (count)) - genIType(1));
+	}
 
 
-	assert(First + Count <= GenSize);
+	VECTORIZE_VEC(mask)
 
 
-	genIUType ShiftLeft = Count ? Value << (GenSize - (Count + First)) : 0;
-	genIUType ShiftBack = ShiftLeft >> genIUType(GenSize - Count);
+	// extractField
+	template <typename genIType>
+	GLM_FUNC_QUALIFIER genIType extractField
+	(
+		half const & value, 
+		genIType const & first, 
+		genIType const & count
+	)
+	{
+		assert(first + count < sizeof(half));
+		return (value._data() << first) >> ((sizeof(half) << 3) - count);
+	}
 
 
-	return ShiftBack;
-}
+	template <typename genIType>
+	GLM_FUNC_QUALIFIER genIType extractField
+	(
+		float const & value, 
+		genIType const & first, 
+		genIType const & count
+	)
+	{
+		assert(first + count < sizeof(float));
+		return (detail::uif32(value).i << first) >> ((sizeof(float) << 3) - count);
+	}
 
 
-template <typename genIUType, typename sizeType>
-GLM_FUNC_QUALIFIER detail::tvec2<genIUType> extractField
-(
-	detail::tvec2<genIUType> const & value, 
-	sizeType const & first, 
-	sizeType const & count
-)
-{
-	return detail::tvec2<genIUType>(
-		extractField(value[0], first, count),
-		extractField(value[1], first, count));
-}
-
-template <typename genIUType, typename sizeType>
-GLM_FUNC_QUALIFIER detail::tvec3<genIUType> extractField
-(
-	detail::tvec3<genIUType> const & value, 
-	sizeType const & first, 
-	sizeType const & count
-)
-{
-	return detail::tvec3<genIUType>(
-		extractField(value[0], first, count),
-		extractField(value[1], first, count),
-		extractField(value[2], first, count));
-}
-
-template <typename genIUType, typename sizeType>
-GLM_FUNC_QUALIFIER detail::tvec4<genIUType> extractField
-(
-	detail::tvec4<genIUType> const & value, 
-	sizeType const & first, 
-	sizeType const & count
-)
-{
-	return detail::tvec4<genIUType>(
-		extractField(value[0], first, count),
-		extractField(value[1], first, count),
-		extractField(value[2], first, count),
-		extractField(value[3], first, count));
-}
-
-template <typename genIUType, typename sizeType>
-GLM_FUNC_QUALIFIER detail::tvec2<genIUType> extractField
-(
-	detail::tvec2<genIUType> const & value, 
-	detail::tvec2<sizeType> const & first, 
-	detail::tvec2<sizeType> const & count
-)
-{
-	return detail::tvec2<genIUType>(
-		extractField(value[0], first[0], count[0]),
-		extractField(value[1], first[1], count[1]));
-}
-
-template <typename genIUType, typename sizeType>
-GLM_FUNC_QUALIFIER detail::tvec3<genIUType> extractField
-(
-	detail::tvec3<genIUType> const & value, 
-	detail::tvec3<sizeType> const & first, 
-	detail::tvec3<sizeType> const & count
-)
-{
-	return detail::tvec3<genIUType>(
-		extractField(value[0], first[0], count[0]),
-		extractField(value[1], first[1], count[1]),
-		extractField(value[2], first[2], count[2]));
-}
-
-template <typename genIUType, typename sizeType>
-GLM_FUNC_QUALIFIER detail::tvec4<genIUType> extractField
-(
-	detail::tvec4<genIUType> const & value, 
-	detail::tvec4<sizeType> const & first, 
-	detail::tvec4<sizeType> const & count
-)
-{
-	return detail::tvec4<genIUType>(
-		extractField(value[0], first[0], count[0]),
-		extractField(value[1], first[1], count[1]),
-		extractField(value[2], first[2], count[2]),
-		extractField(value[3], first[3], count[3]));
-}
-
-template <typename genIUType, typename sizeType>
-GLM_FUNC_QUALIFIER detail::tvec2<genIUType> extractField
-(
-	genIUType const & value, 
-	detail::tvec2<sizeType> const & first, 
-	detail::tvec2<sizeType> const & count
-)
-{
-	return detail::tvec2<genIUType>(
-		extractField(value, first[0], count[0]),
-		extractField(value, first[1], count[1]));
-}
-
-template <typename genIUType, typename sizeType>
-GLM_FUNC_QUALIFIER detail::tvec3<genIUType> extractField
-(
-	genIUType const & value, 
-	detail::tvec3<sizeType> const & first, 
-	detail::tvec3<sizeType> const & count
-)
-{
-	return detail::tvec3<genIUType>(
-		extractField(value, first[0], count[0]),
-		extractField(value, first[1], count[1]),
-		extractField(value, first[2], count[2]));
-}
-
-template <typename genIUType, typename sizeType>
-GLM_FUNC_QUALIFIER detail::tvec4<genIUType> extractField
-(
-	genIUType const & value, 
-	detail::tvec4<sizeType> const & first, 
-	detail::tvec4<sizeType> const & count
-)
-{
-	return detail::tvec4<genIUType>(
-		extractField(value, first[0], count[0]),
-		extractField(value, first[1], count[1]),
-		extractField(value, first[2], count[2]),
-		extractField(value, first[3], count[3]));
-}
-
-// lowestBit
-template <typename genType>
-GLM_FUNC_QUALIFIER int lowestBit
-(
-	genType const & Value
-)
-{
-	assert(Value != genType(0)); // not valid call
-
-	genType Bit;
-	for(Bit = genType(0); !(Value & (1 << Bit)); ++Bit){}
-	return Bit;
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec2<int> lowestBit
-(
-	detail::tvec2<valType> const & value
-)
-{
-	return detail::tvec2<int>(
-		lowestBit(value[0]),
-		lowestBit(value[1]));
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec3<int> lowestBit
-(
-	detail::tvec3<valType> const & value
-)
-{
-	return detail::tvec3<int>(
-		lowestBit(value[0]),
-		lowestBit(value[1]),
-		lowestBit(value[2]));
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec4<int> lowestBit
-(
-	detail::tvec4<valType> const & value
-)
-{
-	return detail::tvec4<int>(
-		lowestBit(value[0]),
-		lowestBit(value[1]),
-		lowestBit(value[2]),
-		lowestBit(value[3]));
-}
-
-// highestBit
-template <typename genType>
-GLM_FUNC_QUALIFIER int highestBit
-(
-	genType const & value
-)
-{
-	assert(value != genType(0)); // not valid call
-
-	genType bit = genType(-1);
-	for(genType tmp = value; tmp; tmp >>= 1, ++bit){}
-	return bit;
-}
-
-//template <>
-//GLM_FUNC_QUALIFIER int highestBit<int>
-//(
-//	int value
-//)
-//{
-//	int bit = -1;
-//	for(int tmp = value; tmp; tmp >>= 1, ++bit);
-//	return bit;
-//}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec2<int> highestBit
-(
-	detail::tvec2<valType> const & value
-)
-{
-	return detail::tvec2<int>(
-		highestBit(value[0]),
-		highestBit(value[1]));
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec3<int> highestBit
-(
-	detail::tvec3<valType> const & value
-)
-{
-	return detail::tvec3<int>(
-		highestBit(value[0]),
-		highestBit(value[1]),
-		highestBit(value[2]));
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec4<int> highestBit
-(
-	detail::tvec4<valType> const & value
-)
-{
-	return detail::tvec4<int>(
-		highestBit(value[0]),
-		highestBit(value[1]),
-		highestBit(value[2]),
-		highestBit(value[3]));
-}
-
-// highestBitValue
-template <typename genType>
-GLM_FUNC_QUALIFIER genType highestBitValue
-(
-	genType const & value
-)
-{
-	genType tmp = value;
-	genType result = genType(0);
-	while(tmp)
+	template <typename genIType>
+	GLM_FUNC_QUALIFIER genIType extractField
+	(
+		double const & value, 
+		genIType const & first, 
+		genIType const & count
+	)
 	{
 	{
-		result = (tmp & (~tmp + 1)); // grab lowest bit
-		tmp &= ~result; // clear lowest bit
+		assert(first + count < sizeof(double));
+		return (detail::uif64(value).i << first) >> ((sizeof(double) << genIType(3)) - count);
 	}
 	}
-	return result;
-}
 
 
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec2<int> highestBitValue
-(
-	detail::tvec2<valType> const & value
-)
-{
-	return detail::tvec2<int>(
-		highestBitValue(value[0]),
-		highestBitValue(value[1]));
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec3<int> highestBitValue
-(
-	detail::tvec3<valType> const & value
-)
-{
-	return detail::tvec3<int>(
-		highestBitValue(value[0]),
-		highestBitValue(value[1]),
-		highestBitValue(value[2]));
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec4<int> highestBitValue
-(
-	detail::tvec4<valType> const & value
-)
-{
-	return detail::tvec4<int>(
-		highestBitValue(value[0]),
-		highestBitValue(value[1]),
-		highestBitValue(value[2]),
-		highestBitValue(value[3]));
-}
-
-// isPowerOfTwo
-template <typename genType>
-GLM_FUNC_QUALIFIER bool isPowerOfTwo(genType const & Value)
-{
-	//detail::If<std::numeric_limits<genType>::is_signed>::apply(abs, Value);
-	//return !(Value & (Value - 1));
-
-    // For old complier?
-	genType Result = Value;
-	if(std::numeric_limits<genType>::is_signed)
-		Result = abs(Result);
-	return !(Result & (Result - 1));
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec2<bool> isPowerOfTwo
-(
-	detail::tvec2<valType> const & value
-)
-{
-	return detail::tvec2<bool>(
-		isPowerOfTwo(value[0]),
-		isPowerOfTwo(value[1]));
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec3<bool> isPowerOfTwo
-(
-	detail::tvec3<valType> const & value
-)
-{
-	return detail::tvec3<bool>(
-		isPowerOfTwo(value[0]),
-		isPowerOfTwo(value[1]),
-		isPowerOfTwo(value[2]));
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec4<bool> isPowerOfTwo
-(
-	detail::tvec4<valType> const & value
-)
-{
-	return detail::tvec4<bool>(
-		isPowerOfTwo(value[0]),
-		isPowerOfTwo(value[1]),
-		isPowerOfTwo(value[2]),
-		isPowerOfTwo(value[3]));
-}
-
-// powerOfTwoAbove
-template <typename genType>
-GLM_FUNC_QUALIFIER genType powerOfTwoAbove(genType const & value)
-{
-	return isPowerOfTwo(value) ? value : highestBitValue(value) << 1;
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec2<valType> powerOfTwoAbove
-(
-	detail::tvec2<valType> const & value
-)
-{
-	return detail::tvec2<valType>(
-		powerOfTwoAbove(value[0]),
-		powerOfTwoAbove(value[1]));
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec3<valType> powerOfTwoAbove
-(
-	detail::tvec3<valType> const & value
-)
-{
-	return detail::tvec3<valType>(
-		powerOfTwoAbove(value[0]),
-		powerOfTwoAbove(value[1]),
-		powerOfTwoAbove(value[2]));
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec4<valType> powerOfTwoAbove
-(
-	detail::tvec4<valType> const & value
-)
-{
-	return detail::tvec4<valType>(
-		powerOfTwoAbove(value[0]),
-		powerOfTwoAbove(value[1]),
-		powerOfTwoAbove(value[2]),
-		powerOfTwoAbove(value[3]));
-}
-
-// powerOfTwoBelow
-template <typename genType>
-GLM_FUNC_QUALIFIER genType powerOfTwoBelow
-(
-	genType const & value
-)
-{
-	return isPowerOfTwo(value) ? value : highestBitValue(value);
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec2<valType> powerOfTwoBelow
-(
-	detail::tvec2<valType> const & value
-)
-{
-	return detail::tvec2<valType>(
-		powerOfTwoBelow(value[0]),
-		powerOfTwoBelow(value[1]));
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec3<valType> powerOfTwoBelow
-(
-	detail::tvec3<valType> const & value
-)
-{
-	return detail::tvec3<valType>(
-		powerOfTwoBelow(value[0]),
-		powerOfTwoBelow(value[1]),
-		powerOfTwoBelow(value[2]));
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec4<valType> powerOfTwoBelow
-(
-	detail::tvec4<valType> const & value
-)
-{
-	return detail::tvec4<valType>(
-		powerOfTwoBelow(value[0]),
-		powerOfTwoBelow(value[1]),
-		powerOfTwoBelow(value[2]),
-		powerOfTwoBelow(value[3]));
-}
-
-// powerOfTwoNearest
-template <typename genType>
-GLM_FUNC_QUALIFIER genType powerOfTwoNearest
-(
-	genType const & value
-)
-{
-	if(isPowerOfTwo(value))
-		return value;
-
-	genType prev = highestBitValue(value);
-	genType next = prev << 1;
-	return (next - value) < (value - prev) ? next : prev;
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec2<valType> powerOfTwoNearest
-(
-	detail::tvec2<valType> const & value
-)
-{
-	return detail::tvec2<valType>(
-		powerOfTwoNearest(value[0]),
-		powerOfTwoNearest(value[1]));
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec3<valType> powerOfTwoNearest
-(
-	detail::tvec3<valType> const & value
-)
-{
-	return detail::tvec3<valType>(
-		powerOfTwoNearest(value[0]),
-		powerOfTwoNearest(value[1]),
-		powerOfTwoNearest(value[2]));
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec4<valType> powerOfTwoNearest
-(
-	detail::tvec4<valType> const & value
-)
-{
-	return detail::tvec4<valType>(
-		powerOfTwoNearest(value[0]),
-		powerOfTwoNearest(value[1]),
-		powerOfTwoNearest(value[2]),
-		powerOfTwoNearest(value[3]));
-}
-
-template <typename genType>
-GLM_FUNC_QUALIFIER genType bitRevert(genType const & In)
-{
-	GLM_STATIC_ASSERT(std::numeric_limits<genType>::is_integer, "'bitRevert' only accept integer values");
-
-	genType Out = 0;
-	std::size_t BitSize = sizeof(genType) * 8;
-	for(std::size_t i = 0; i < BitSize; ++i)
-		if(In & (genType(1) << i))
-			Out |= genType(1) << (BitSize - 1 - i);
-	return Out;
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec2<valType> bitRevert
-(
-	detail::tvec2<valType> const & Value
-)
-{
-	return detail::tvec2<valType>(
-		bitRevert(Value[0]),
-		bitRevert(Value[1]));
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec3<valType> bitRevert
-(
-	detail::tvec3<valType> const & Value
-)
-{
-	return detail::tvec3<valType>(
-		bitRevert(Value[0]),
-		bitRevert(Value[1]),
-		bitRevert(Value[2]));
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec4<valType> bitRevert
-(
-	detail::tvec4<valType> const & Value
-)
-{
-	return detail::tvec4<valType>(
-		bitRevert(Value[0]),
-		bitRevert(Value[1]),
-		bitRevert(Value[2]),
-		bitRevert(Value[3]));
-}
-
-template <typename genType>
-GLM_FUNC_QUALIFIER genType bitRotateRight(genType const & In, std::size_t Shift)
-{
-	GLM_STATIC_ASSERT(std::numeric_limits<genType>::is_integer, "'bitRotateRight' only accept integer values");
-
-	std::size_t BitSize = sizeof(genType) * 8;
-	return (In << Shift) | (In >> (BitSize - Shift));
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec2<valType> bitRotateRight
-(
-	detail::tvec2<valType> const & Value, 
-	std::size_t Shift
-)
-{
-	return detail::tvec2<valType>(
-		bitRotateRight(Value[0], Shift),
-		bitRotateRight(Value[1], Shift));
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec3<valType> bitRotateRight
-(
-	detail::tvec3<valType> const & Value, 
-	std::size_t Shift
-)
-{
-	return detail::tvec3<valType>(
-		bitRotateRight(Value[0], Shift),
-		bitRotateRight(Value[1], Shift),
-		bitRotateRight(Value[2], Shift));
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec4<valType> bitRotateRight
-(
-	detail::tvec4<valType> const & Value, 
-	std::size_t Shift
-)
-{
-	return detail::tvec4<valType>(
-		bitRotateRight(Value[0], Shift),
-		bitRotateRight(Value[1], Shift),
-		bitRotateRight(Value[2], Shift),
-		bitRotateRight(Value[3], Shift));
-}
-
-template <typename genType>
-GLM_FUNC_QUALIFIER genType bitRotateLeft(genType const & In, std::size_t Shift)
-{
-	GLM_STATIC_ASSERT(std::numeric_limits<genType>::is_integer, "'bitRotateLeft' only accept integer values");
-
-	std::size_t BitSize = sizeof(genType) * 8;
-	return (In >> Shift) | (In << (BitSize - Shift));
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec2<valType> bitRotateLeft
-(
-	detail::tvec2<valType> const & Value, 
-	std::size_t Shift
-)
-{
-	return detail::tvec2<valType>(
-		bitRotateLeft(Value[0], Shift),
-		bitRotateLeft(Value[1], Shift));
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec3<valType> bitRotateLeft
-(
-	detail::tvec3<valType> const & Value, 
-	std::size_t Shift
-)
-{
-	return detail::tvec3<valType>(
-		bitRotateLeft(Value[0], Shift),
-		bitRotateLeft(Value[1], Shift),
-		bitRotateLeft(Value[2], Shift));
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec4<valType> bitRotateLeft
-(
-	detail::tvec4<valType> const & Value, 
-	std::size_t Shift
-)
-{
-	return detail::tvec4<valType>(
-		bitRotateLeft(Value[0], Shift),
-		bitRotateLeft(Value[1], Shift),
-		bitRotateLeft(Value[2], Shift),
-		bitRotateLeft(Value[3], Shift));
-}
-
-template <typename genIUType>
-GLM_FUNC_QUALIFIER genIUType fillBitfieldWithOne
-(
-	genIUType const & Value,
-	int const & FromBit, 
-	int const & ToBit
-)
-{
-	assert(FromBit <= ToBit);
-	assert(ToBit <= sizeof(genIUType) * std::size_t(8));
-
-	genIUType Result = Value;
-	for(std::size_t i = 0; i <= ToBit; ++i)
-		Result |= (1 << i);
-	return Result;
-}
-
-template <typename genIUType>
-GLM_FUNC_QUALIFIER genIUType fillBitfieldWithZero
-(
-	genIUType const & Value,
-	int const & FromBit, 
-	int const & ToBit
-)
-{
-	assert(FromBit <= ToBit);
-	assert(ToBit <= sizeof(genIUType) * std::size_t(8));
+	template <typename genIUType, typename sizeType>
+	GLM_FUNC_QUALIFIER genIUType extractField
+	(
+		genIUType const & Value, 
+		sizeType const & First, 
+		sizeType const & Count
+	)
+	{
+		sizeType GenSize = sizeof(genIUType) << 3;
+
+		assert(First + Count <= GenSize);
+
+		genIUType ShiftLeft = Count ? Value << (GenSize - (Count + First)) : 0;
+		genIUType ShiftBack = ShiftLeft >> genIUType(GenSize - Count);
+
+		return ShiftBack;
+	}
+
+	template <typename genIUType, typename sizeType>
+	GLM_FUNC_QUALIFIER detail::tvec2<genIUType> extractField
+	(
+		detail::tvec2<genIUType> const & value, 
+		sizeType const & first, 
+		sizeType const & count
+	)
+	{
+		return detail::tvec2<genIUType>(
+			extractField(value[0], first, count),
+			extractField(value[1], first, count));
+	}
+
+	template <typename genIUType, typename sizeType>
+	GLM_FUNC_QUALIFIER detail::tvec3<genIUType> extractField
+	(
+		detail::tvec3<genIUType> const & value, 
+		sizeType const & first, 
+		sizeType const & count
+	)
+	{
+		return detail::tvec3<genIUType>(
+			extractField(value[0], first, count),
+			extractField(value[1], first, count),
+			extractField(value[2], first, count));
+	}
+
+	template <typename genIUType, typename sizeType>
+	GLM_FUNC_QUALIFIER detail::tvec4<genIUType> extractField
+	(
+		detail::tvec4<genIUType> const & value, 
+		sizeType const & first, 
+		sizeType const & count
+	)
+	{
+		return detail::tvec4<genIUType>(
+			extractField(value[0], first, count),
+			extractField(value[1], first, count),
+			extractField(value[2], first, count),
+			extractField(value[3], first, count));
+	}
+
+	template <typename genIUType, typename sizeType>
+	GLM_FUNC_QUALIFIER detail::tvec2<genIUType> extractField
+	(
+		detail::tvec2<genIUType> const & value, 
+		detail::tvec2<sizeType> const & first, 
+		detail::tvec2<sizeType> const & count
+	)
+	{
+		return detail::tvec2<genIUType>(
+			extractField(value[0], first[0], count[0]),
+			extractField(value[1], first[1], count[1]));
+	}
+
+	template <typename genIUType, typename sizeType>
+	GLM_FUNC_QUALIFIER detail::tvec3<genIUType> extractField
+	(
+		detail::tvec3<genIUType> const & value, 
+		detail::tvec3<sizeType> const & first, 
+		detail::tvec3<sizeType> const & count
+	)
+	{
+		return detail::tvec3<genIUType>(
+			extractField(value[0], first[0], count[0]),
+			extractField(value[1], first[1], count[1]),
+			extractField(value[2], first[2], count[2]));
+	}
+
+	template <typename genIUType, typename sizeType>
+	GLM_FUNC_QUALIFIER detail::tvec4<genIUType> extractField
+	(
+		detail::tvec4<genIUType> const & value, 
+		detail::tvec4<sizeType> const & first, 
+		detail::tvec4<sizeType> const & count
+	)
+	{
+		return detail::tvec4<genIUType>(
+			extractField(value[0], first[0], count[0]),
+			extractField(value[1], first[1], count[1]),
+			extractField(value[2], first[2], count[2]),
+			extractField(value[3], first[3], count[3]));
+	}
+
+	template <typename genIUType, typename sizeType>
+	GLM_FUNC_QUALIFIER detail::tvec2<genIUType> extractField
+	(
+		genIUType const & value, 
+		detail::tvec2<sizeType> const & first, 
+		detail::tvec2<sizeType> const & count
+	)
+	{
+		return detail::tvec2<genIUType>(
+			extractField(value, first[0], count[0]),
+			extractField(value, first[1], count[1]));
+	}
+
+	template <typename genIUType, typename sizeType>
+	GLM_FUNC_QUALIFIER detail::tvec3<genIUType> extractField
+	(
+		genIUType const & value, 
+		detail::tvec3<sizeType> const & first, 
+		detail::tvec3<sizeType> const & count
+	)
+	{
+		return detail::tvec3<genIUType>(
+			extractField(value, first[0], count[0]),
+			extractField(value, first[1], count[1]),
+			extractField(value, first[2], count[2]));
+	}
+
+	template <typename genIUType, typename sizeType>
+	GLM_FUNC_QUALIFIER detail::tvec4<genIUType> extractField
+	(
+		genIUType const & value, 
+		detail::tvec4<sizeType> const & first, 
+		detail::tvec4<sizeType> const & count
+	)
+	{
+		return detail::tvec4<genIUType>(
+			extractField(value, first[0], count[0]),
+			extractField(value, first[1], count[1]),
+			extractField(value, first[2], count[2]),
+			extractField(value, first[3], count[3]));
+	}
+
+	// lowestBit
+	template <typename genType>
+	GLM_FUNC_QUALIFIER int lowestBit
+	(
+		genType const & Value
+	)
+	{
+		assert(Value != genType(0)); // not valid call
+
+		genType Bit;
+		for(Bit = genType(0); !(Value & (1 << Bit)); ++Bit){}
+		return Bit;
+	}
+
+	template <typename valType>
+	GLM_FUNC_QUALIFIER detail::tvec2<int> lowestBit
+	(
+		detail::tvec2<valType> const & value
+	)
+	{
+		return detail::tvec2<int>(
+			lowestBit(value[0]),
+			lowestBit(value[1]));
+	}
+
+	template <typename valType>
+	GLM_FUNC_QUALIFIER detail::tvec3<int> lowestBit
+	(
+		detail::tvec3<valType> const & value
+	)
+	{
+		return detail::tvec3<int>(
+			lowestBit(value[0]),
+			lowestBit(value[1]),
+			lowestBit(value[2]));
+	}
+
+	template <typename valType>
+	GLM_FUNC_QUALIFIER detail::tvec4<int> lowestBit
+	(
+		detail::tvec4<valType> const & value
+	)
+	{
+		return detail::tvec4<int>(
+			lowestBit(value[0]),
+			lowestBit(value[1]),
+			lowestBit(value[2]),
+			lowestBit(value[3]));
+	}
+
+	// highestBit
+	template <typename genType>
+	GLM_FUNC_QUALIFIER int highestBit
+	(
+		genType const & value
+	)
+	{
+		assert(value != genType(0)); // not valid call
+
+		genType bit = genType(-1);
+		for(genType tmp = value; tmp; tmp >>= 1, ++bit){}
+		return bit;
+	}
+
+	//template <>
+	//GLM_FUNC_QUALIFIER int highestBit<int>
+	//(
+	//	int value
+	//)
+	//{
+	//	int bit = -1;
+	//	for(int tmp = value; tmp; tmp >>= 1, ++bit);
+	//	return bit;
+	//}
+
+	template <typename valType>
+	GLM_FUNC_QUALIFIER detail::tvec2<int> highestBit
+	(
+		detail::tvec2<valType> const & value
+	)
+	{
+		return detail::tvec2<int>(
+			highestBit(value[0]),
+			highestBit(value[1]));
+	}
+
+	template <typename valType>
+	GLM_FUNC_QUALIFIER detail::tvec3<int> highestBit
+	(
+		detail::tvec3<valType> const & value
+	)
+	{
+		return detail::tvec3<int>(
+			highestBit(value[0]),
+			highestBit(value[1]),
+			highestBit(value[2]));
+	}
+
+	template <typename valType>
+	GLM_FUNC_QUALIFIER detail::tvec4<int> highestBit
+	(
+		detail::tvec4<valType> const & value
+	)
+	{
+		return detail::tvec4<int>(
+			highestBit(value[0]),
+			highestBit(value[1]),
+			highestBit(value[2]),
+			highestBit(value[3]));
+	}
+
+	// highestBitValue
+	template <typename genType>
+	GLM_FUNC_QUALIFIER genType highestBitValue
+	(
+		genType const & value
+	)
+	{
+		genType tmp = value;
+		genType result = genType(0);
+		while(tmp)
+		{
+			result = (tmp & (~tmp + 1)); // grab lowest bit
+			tmp &= ~result; // clear lowest bit
+		}
+		return result;
+	}
+
+	template <typename valType>
+	GLM_FUNC_QUALIFIER detail::tvec2<int> highestBitValue
+	(
+		detail::tvec2<valType> const & value
+	)
+	{
+		return detail::tvec2<int>(
+			highestBitValue(value[0]),
+			highestBitValue(value[1]));
+	}
+
+	template <typename valType>
+	GLM_FUNC_QUALIFIER detail::tvec3<int> highestBitValue
+	(
+		detail::tvec3<valType> const & value
+	)
+	{
+		return detail::tvec3<int>(
+			highestBitValue(value[0]),
+			highestBitValue(value[1]),
+			highestBitValue(value[2]));
+	}
+
+	template <typename valType>
+	GLM_FUNC_QUALIFIER detail::tvec4<int> highestBitValue
+	(
+		detail::tvec4<valType> const & value
+	)
+	{
+		return detail::tvec4<int>(
+			highestBitValue(value[0]),
+			highestBitValue(value[1]),
+			highestBitValue(value[2]),
+			highestBitValue(value[3]));
+	}
+
+	// isPowerOfTwo
+	template <typename genType>
+	GLM_FUNC_QUALIFIER bool isPowerOfTwo(genType const & Value)
+	{
+		//detail::If<std::numeric_limits<genType>::is_signed>::apply(abs, Value);
+		//return !(Value & (Value - 1));
+
+		// For old complier?
+		genType Result = Value;
+		if(std::numeric_limits<genType>::is_signed)
+			Result = abs(Result);
+		return !(Result & (Result - 1));
+	}
+
+	template <typename valType>
+	GLM_FUNC_QUALIFIER detail::tvec2<bool> isPowerOfTwo
+	(
+		detail::tvec2<valType> const & value
+	)
+	{
+		return detail::tvec2<bool>(
+			isPowerOfTwo(value[0]),
+			isPowerOfTwo(value[1]));
+	}
+
+	template <typename valType>
+	GLM_FUNC_QUALIFIER detail::tvec3<bool> isPowerOfTwo
+	(
+		detail::tvec3<valType> const & value
+	)
+	{
+		return detail::tvec3<bool>(
+			isPowerOfTwo(value[0]),
+			isPowerOfTwo(value[1]),
+			isPowerOfTwo(value[2]));
+	}
+
+	template <typename valType>
+	GLM_FUNC_QUALIFIER detail::tvec4<bool> isPowerOfTwo
+	(
+		detail::tvec4<valType> const & value
+	)
+	{
+		return detail::tvec4<bool>(
+			isPowerOfTwo(value[0]),
+			isPowerOfTwo(value[1]),
+			isPowerOfTwo(value[2]),
+			isPowerOfTwo(value[3]));
+	}
 
 
-	genIUType Result = Value;
-	for(std::size_t i = 0; i <= ToBit; ++i)
-		Result &= ~(1 << i);
-	return Result;
-}
+	// powerOfTwoAbove
+	template <typename genType>
+	GLM_FUNC_QUALIFIER genType powerOfTwoAbove(genType const & value)
+	{
+		return isPowerOfTwo(value) ? value : highestBitValue(value) << 1;
+	}
+
+	VECTORIZE_VEC(powerOfTwoAbove)
+
+	// powerOfTwoBelow
+	template <typename genType>
+	GLM_FUNC_QUALIFIER genType powerOfTwoBelow
+	(
+		genType const & value
+	)
+	{
+		return isPowerOfTwo(value) ? value : highestBitValue(value);
+	}
+
+	VECTORIZE_VEC(powerOfTwoBelow)
 
 
+	// powerOfTwoNearest
+	template <typename genType>
+	GLM_FUNC_QUALIFIER genType powerOfTwoNearest
+	(
+		genType const & value
+	)
+	{
+		if(isPowerOfTwo(value))
+			return value;
+
+		genType prev = highestBitValue(value);
+		genType next = prev << 1;
+		return (next - value) < (value - prev) ? next : prev;
+	}
+
+	VECTORIZE_VEC(powerOfTwoNearest)
+
+	template <typename genType>
+	GLM_FUNC_QUALIFIER genType bitRevert(genType const & In)
+	{
+		GLM_STATIC_ASSERT(std::numeric_limits<genType>::is_integer, "'bitRevert' only accept integer values");
+
+		genType Out = 0;
+		std::size_t BitSize = sizeof(genType) * 8;
+		for(std::size_t i = 0; i < BitSize; ++i)
+			if(In & (genType(1) << i))
+				Out |= genType(1) << (BitSize - 1 - i);
+		return Out;
+	}
+
+	VECTORIZE_VEC(bitRevert)
+
+	template <typename genType>
+	GLM_FUNC_QUALIFIER genType bitRotateRight(genType const & In, std::size_t Shift)
+	{
+		GLM_STATIC_ASSERT(std::numeric_limits<genType>::is_integer, "'bitRotateRight' only accept integer values");
+
+		std::size_t BitSize = sizeof(genType) * 8;
+		return (In << Shift) | (In >> (BitSize - Shift));
+	}
+
+	template <typename valType>
+	GLM_FUNC_QUALIFIER detail::tvec2<valType> bitRotateRight
+	(
+		detail::tvec2<valType> const & Value, 
+		std::size_t Shift
+	)
+	{
+		return detail::tvec2<valType>(
+			bitRotateRight(Value[0], Shift),
+			bitRotateRight(Value[1], Shift));
+	}
+
+	template <typename valType>
+	GLM_FUNC_QUALIFIER detail::tvec3<valType> bitRotateRight
+	(
+		detail::tvec3<valType> const & Value, 
+		std::size_t Shift
+	)
+	{
+		return detail::tvec3<valType>(
+			bitRotateRight(Value[0], Shift),
+			bitRotateRight(Value[1], Shift),
+			bitRotateRight(Value[2], Shift));
+	}
+
+	template <typename valType>
+	GLM_FUNC_QUALIFIER detail::tvec4<valType> bitRotateRight
+	(
+		detail::tvec4<valType> const & Value, 
+		std::size_t Shift
+	)
+	{
+		return detail::tvec4<valType>(
+			bitRotateRight(Value[0], Shift),
+			bitRotateRight(Value[1], Shift),
+			bitRotateRight(Value[2], Shift),
+			bitRotateRight(Value[3], Shift));
+	}
+
+	template <typename genType>
+	GLM_FUNC_QUALIFIER genType bitRotateLeft(genType const & In, std::size_t Shift)
+	{
+		GLM_STATIC_ASSERT(std::numeric_limits<genType>::is_integer, "'bitRotateLeft' only accept integer values");
+
+		std::size_t BitSize = sizeof(genType) * 8;
+		return (In >> Shift) | (In << (BitSize - Shift));
+	}
+
+	template <typename valType>
+	GLM_FUNC_QUALIFIER detail::tvec2<valType> bitRotateLeft
+	(
+		detail::tvec2<valType> const & Value, 
+		std::size_t Shift
+	)
+	{
+		return detail::tvec2<valType>(
+			bitRotateLeft(Value[0], Shift),
+			bitRotateLeft(Value[1], Shift));
+	}
+
+	template <typename valType>
+	GLM_FUNC_QUALIFIER detail::tvec3<valType> bitRotateLeft
+	(
+		detail::tvec3<valType> const & Value, 
+		std::size_t Shift
+	)
+	{
+		return detail::tvec3<valType>(
+			bitRotateLeft(Value[0], Shift),
+			bitRotateLeft(Value[1], Shift),
+			bitRotateLeft(Value[2], Shift));
+	}
+
+	template <typename valType>
+	GLM_FUNC_QUALIFIER detail::tvec4<valType> bitRotateLeft
+	(
+		detail::tvec4<valType> const & Value, 
+		std::size_t Shift
+	)
+	{
+		return detail::tvec4<valType>(
+			bitRotateLeft(Value[0], Shift),
+			bitRotateLeft(Value[1], Shift),
+			bitRotateLeft(Value[2], Shift),
+			bitRotateLeft(Value[3], Shift));
+	}
+
+	template <typename genIUType>
+	GLM_FUNC_QUALIFIER genIUType fillBitfieldWithOne
+	(
+		genIUType const & Value,
+		int const & FromBit, 
+		int const & ToBit
+	)
+	{
+		assert(FromBit <= ToBit);
+		assert(ToBit <= sizeof(genIUType) * std::size_t(8));
+
+		genIUType Result = Value;
+		for(std::size_t i = 0; i <= ToBit; ++i)
+			Result |= (1 << i);
+		return Result;
+	}
+
+	template <typename genIUType>
+	GLM_FUNC_QUALIFIER genIUType fillBitfieldWithZero
+	(
+		genIUType const & Value,
+		int const & FromBit, 
+		int const & ToBit
+	)
+	{
+		assert(FromBit <= ToBit);
+		assert(ToBit <= sizeof(genIUType) * std::size_t(8));
+
+		genIUType Result = Value;
+		for(std::size_t i = 0; i <= ToBit; ++i)
+			Result &= ~(1 << i);
+		return Result;
+	}
 }//namespace glm
 }//namespace glm

+ 18 - 19
glm/gtx/closest_point.inl

@@ -10,28 +10,27 @@
 #ifndef glm_gtx_closest_point
 #ifndef glm_gtx_closest_point
 #define glm_gtx_closest_point
 #define glm_gtx_closest_point
 
 
-namespace glm{
-
-template <typename valType> 
-GLM_FUNC_QUALIFIER detail::tvec3<valType> closestPointOnLine
-(
-	detail::tvec3<valType> const & point, 
-	detail::tvec3<valType> const & a, 
-	detail::tvec3<valType> const & b
-)
+namespace glm
 {
 {
-    valType LineLength = distance(a, b);
-    detail::tvec3<valType> Vector = point - a;
-    detail::tvec3<valType> LineDirection = (b - a) / LineLength;
-
-    // Project Vector to LineDirection to get the distance of point from a
-    valType Distance = dot(Vector, LineDirection);
+	template <typename valType> 
+	GLM_FUNC_QUALIFIER detail::tvec3<valType> closestPointOnLine
+	(
+		detail::tvec3<valType> const & point, 
+		detail::tvec3<valType> const & a, 
+		detail::tvec3<valType> const & b
+	)
+	{
+		valType LineLength = distance(a, b);
+		detail::tvec3<valType> Vector = point - a;
+		detail::tvec3<valType> LineDirection = (b - a) / LineLength;
 
 
-    if(Distance <= valType(0)) return a;
-    if(Distance >= LineLength) return b;
-    return a + LineDirection * Distance;
-}
+		// Project Vector to LineDirection to get the distance of point from a
+		valType Distance = dot(Vector, LineDirection);
 
 
+		if(Distance <= valType(0)) return a;
+		if(Distance >= LineLength) return b;
+		return a + LineDirection * Distance;
+	}
 }//namespace glm
 }//namespace glm
 
 
 #endif//glm_gtx_closest_point
 #endif//glm_gtx_closest_point

+ 723 - 724
glm/gtx/color_cast.inl

@@ -7,728 +7,727 @@
 // File    : glm/gtx/color_cast.inl
 // File    : glm/gtx/color_cast.inl
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 
-namespace glm{
-
-template <typename T> 
-GLM_FUNC_QUALIFIER uint8 u8channel_cast(T a)
-{
-	return static_cast<uint8>(a * T(255));
-}
-
-template <typename T> 
-GLM_FUNC_QUALIFIER uint16 u16channel_cast(T a)
-{
-	return static_cast<uint16>(a * T(65535));
-}
-
-template <typename T>
-GLM_FUNC_QUALIFIER uint32 u32_rgbx_cast(const detail::tvec3<T>& c)
-{
-	uint32 result = 0;
-	result += static_cast<uint32>(c.x * detail::tvec3<T>::value_type(255)) <<  0;
-	result += static_cast<uint32>(c.y * detail::tvec3<T>::value_type(255)) <<  8;
-	result += static_cast<uint32>(c.z * detail::tvec3<T>::value_type(255)) << 16;
-	return result;
-}
-
-template <typename T>
-GLM_FUNC_QUALIFIER uint32 u32_xrgb_cast(const detail::tvec3<T>& c)
-{
-	uint32 result = 0;
-    result += static_cast<uint32>(c.x * detail::tvec3<T>::value_type(255)) <<  8;
-	result += static_cast<uint32>(c.y * detail::tvec3<T>::value_type(255)) << 16;
-	result += static_cast<uint32>(c.z * detail::tvec3<T>::value_type(255)) << 24;
-	return result;
-}
-
-template <typename T>
-GLM_FUNC_QUALIFIER uint32 u32_bgrx_cast(const detail::tvec3<T>& c)
-{
-	uint32 result = 0;
-	result += static_cast<uint32>(c.x * detail::tvec3<T>::value_type(255)) << 16;
-	result += static_cast<uint32>(c.y * detail::tvec3<T>::value_type(255)) <<  8;
-	result += static_cast<uint32>(c.z * detail::tvec3<T>::value_type(255)) <<  0;
-	return result;
-}
-
-template <typename T>
-GLM_FUNC_QUALIFIER uint32 u32_xbgr_cast(const detail::tvec3<T>& c)
-{
-	uint32 result = 0;
-	result += static_cast<uint32>(c.x * detail::tvec3<T>::value_type(255)) << 24;
-	result += static_cast<uint32>(c.y * detail::tvec3<T>::value_type(255)) << 16;
-	result += static_cast<uint32>(c.z * detail::tvec3<T>::value_type(255)) <<  8;
-	result += static_cast<uint32>(c.w * detail::tvec3<T>::value_type(255)) <<  0;
-	return result;
-}
-
-template <typename T>
-GLM_FUNC_QUALIFIER uint32 u32_rgba_cast(const detail::tvec4<T>& c)
-{
-	uint32 result = 0;
-	result += static_cast<uint32>(c.x * detail::tvec4<T>::value_type(255)) <<  0;
-	result += static_cast<uint32>(c.y * detail::tvec4<T>::value_type(255)) <<  8;
-	result += static_cast<uint32>(c.z * detail::tvec4<T>::value_type(255)) << 16;
-	result += static_cast<uint32>(c.w * detail::tvec4<T>::value_type(255)) << 24;
-	return result;
-}
-
-template <typename T>
-GLM_FUNC_QUALIFIER uint32 u32_argb_cast(const detail::tvec4<T>& c)
-{
-	uint32 result = 0;
-	result += static_cast<uint32>(c.x * detail::tvec4<T>::value_type(255)) <<  8;
-	result += static_cast<uint32>(c.y * detail::tvec4<T>::value_type(255)) << 16;
-	result += static_cast<uint32>(c.z * detail::tvec4<T>::value_type(255)) << 24;
-	result += static_cast<uint32>(c.w * detail::tvec4<T>::value_type(255)) <<  0;
-	return result;
-}
-
-template <typename T>
-GLM_FUNC_QUALIFIER uint32 u32_bgra_cast(const detail::tvec4<T>& c)
-{
-	uint32 result = 0;
-	result += static_cast<uint32>(c.x * detail::tvec4<T>::value_type(255)) << 16;
-	result += static_cast<uint32>(c.y * detail::tvec4<T>::value_type(255)) <<  8;
-	result += static_cast<uint32>(c.z * detail::tvec4<T>::value_type(255)) <<  0;
-	result += static_cast<uint32>(c.w * detail::tvec4<T>::value_type(255)) << 24;
-	return result;
-}
-
-template <typename T>
-GLM_FUNC_QUALIFIER uint32 u32_abgr_cast(const detail::tvec4<T>& c)
-{
-	uint32 result = 0;
-	result += static_cast<uint32>(c.x * detail::tvec4<T>::value_type(255)) << 24;
-	result += static_cast<uint32>(c.y * detail::tvec4<T>::value_type(255)) << 16;
-	result += static_cast<uint32>(c.z * detail::tvec4<T>::value_type(255)) <<  8;
-	result += static_cast<uint32>(c.w * detail::tvec4<T>::value_type(255)) <<  0;
-	return result;
-}
-
-template <typename T>
-GLM_FUNC_QUALIFIER uint64 u64_rgbx_cast(const detail::tvec3<T>& c)
-{
-	uint64 result = 0;
-	result += static_cast<uint64>(c.x * detail::tvec3<T>::value_type(65535)) <<  0;
-	result += static_cast<uint64>(c.y * detail::tvec3<T>::value_type(65535)) << 16;
-	result += static_cast<uint64>(c.z * detail::tvec3<T>::value_type(65535)) << 32;
-	return result;
-}
-
-template <typename T>
-GLM_FUNC_QUALIFIER uint64 u32_xrgb_cast(const detail::tvec3<T>& c)
-{
-	uint64 result = 0;
-	result += static_cast<uint64>(c.x * detail::tvec3<T>::value_type(65535)) << 16;
-	result += static_cast<uint64>(c.y * detail::tvec3<T>::value_type(65535)) << 32;
-	result += static_cast<uint64>(c.z * detail::tvec3<T>::value_type(65535)) << 48;
-	return result;
-}
-
-template <typename T>
-GLM_FUNC_QUALIFIER uint64 u32_bgrx_cast(const detail::tvec3<T>& c)
-{
-	uint64 result = 0;
-	result += static_cast<uint64>(c.x * detail::tvec3<T>::value_type(65535)) << 32;
-	result += static_cast<uint64>(c.y * detail::tvec3<T>::value_type(65535)) << 16;
-	result += static_cast<uint64>(c.z * detail::tvec3<T>::value_type(65535)) <<  0;
-	return result;
-}
-
-template <typename T>
-GLM_FUNC_QUALIFIER uint64 u32_xbgr_cast(const detail::tvec3<T>& c)
-{
-	uint64 result = 0;
-	result += static_cast<uint64>(c.x * detail::tvec3<T>::value_type(65535)) << 48;
-	result += static_cast<uint64>(c.y * detail::tvec3<T>::value_type(65535)) << 32;
-	result += static_cast<uint64>(c.z * detail::tvec3<T>::value_type(65535)) << 16;
-	result += static_cast<uint64>(c.w * detail::tvec3<T>::value_type(65535)) <<  0;
-	return result;
-}
-
-template <typename T>
-GLM_FUNC_QUALIFIER uint64 u64_rgba_cast(const detail::tvec4<T>& c)
-{
-	uint64 result = 0;
-	result += static_cast<uint64>(c.x * detail::tvec4<T>::value_type(65535)) <<  0;
-	result += static_cast<uint64>(c.y * detail::tvec4<T>::value_type(65535)) << 16;
-	result += static_cast<uint64>(c.z * detail::tvec4<T>::value_type(65535)) << 32;
-	result += static_cast<uint64>(c.w * detail::tvec4<T>::value_type(65535)) << 48;
-	return result;
-}
-
-template <typename T>
-GLM_FUNC_QUALIFIER uint64 u64_argb_cast(const detail::tvec4<T>& c)
-{
-	uint64 result = 0;
-	result += static_cast<uint64>(c.x * detail::tvec4<T>::value_type(65535)) << 16;
-	result += static_cast<uint64>(c.y * detail::tvec4<T>::value_type(65535)) << 32;
-	result += static_cast<uint64>(c.z * detail::tvec4<T>::value_type(65535)) << 48;
-	result += static_cast<uint64>(c.w * detail::tvec4<T>::value_type(65535)) <<  0;
-	return result;
-}
-
-template <typename T>
-GLM_FUNC_QUALIFIER uint64 u64_bgra_cast(const detail::tvec4<T>& c)
-{
-	uint64 result = 0;
-	result += static_cast<uint64>(c.x * detail::tvec4<T>::value_type(65535)) << 32;
-	result += static_cast<uint64>(c.y * detail::tvec4<T>::value_type(65535)) << 16;
-	result += static_cast<uint64>(c.z * detail::tvec4<T>::value_type(65535)) <<  0;
-	result += static_cast<uint64>(c.w * detail::tvec4<T>::value_type(65535)) << 48;
-	return result;
-}
-
-template <typename T>
-GLM_FUNC_QUALIFIER uint64 u64_abgr_cast(const detail::tvec4<T>& c)
-{
-	uint64 result = 0;
-	result += static_cast<uint64>(c.x * detail::tvec4<T>::value_type(65535)) << 48;
-	result += static_cast<uint64>(c.y * detail::tvec4<T>::value_type(65535)) << 32;
-	result += static_cast<uint64>(c.z * detail::tvec4<T>::value_type(65535)) << 16;
-	result += static_cast<uint64>(c.w * detail::tvec4<T>::value_type(65535)) <<  0;
-	return result;
-}
-
-template <>
-GLM_FUNC_QUALIFIER f16 f16_channel_cast<uint32>(uint32 color)
-{
-	return f16(static_cast<float>(color >>  0) / static_cast<float>(255));
-}
-
-template <>
-GLM_FUNC_QUALIFIER f16vec3 f16_rgbx_cast<uint32>(uint32 color)
-{
-	f16vec3 result;
-	result.x = f16(static_cast<float>((color >>  0) & 0xFF) / static_cast<float>(255));
-	result.y = f16(static_cast<float>((color >>  8) & 0xFF) / static_cast<float>(255));
-	result.z = f16(static_cast<float>((color >> 16) & 0xFF) / static_cast<float>(255));
-	return result;
-}
-
-template <>
-GLM_FUNC_QUALIFIER f16vec3 f16_xrgb_cast<uint32>(uint32 color)
-{
-	f16vec3 result;
-	result.x = f16(static_cast<float>((color >>  8) & 0xFF) / static_cast<float>(255));
-	result.y = f16(static_cast<float>((color >> 16) & 0xFF) / static_cast<float>(255));
-	result.z = f16(static_cast<float>((color >> 24) & 0xFF) / static_cast<float>(255));
-	return result;
-}
-
-template <>
-GLM_FUNC_QUALIFIER f16vec3 f16_bgrx_cast<uint32>(uint32 color)
-{
-	f16vec3 result;
-	result.x = f16(static_cast<float>((color >> 16) & 0xFF) / static_cast<float>(255));
-	result.y = f16(static_cast<float>((color >>  8) & 0xFF) / static_cast<float>(255));
-	result.z = f16(static_cast<float>((color >>  0) & 0xFF) / static_cast<float>(255));
-	return result;
-}
-
-template <>
-GLM_FUNC_QUALIFIER f16vec3 f16_xbgr_cast<uint32>(uint32 color)
-{
-	f16vec3 result;
-	result.x = f16(static_cast<float>((color >> 24) & 0xFF) / static_cast<float>(255));
-	result.y = f16(static_cast<float>((color >> 16) & 0xFF) / static_cast<float>(255));
-	result.z = f16(static_cast<float>((color >>  8) & 0xFF) / static_cast<float>(255));
-	return result;
-}
-
-template <>
-GLM_FUNC_QUALIFIER f16vec4 f16_rgba_cast<uint32>(uint32 color)
-{
-	f16vec4 result;
-	result.x = f16(static_cast<float>((color >>  0) & 0xFF) / static_cast<float>(255));
-	result.y = f16(static_cast<float>((color >>  8) & 0xFF) / static_cast<float>(255));
-	result.z = f16(static_cast<float>((color >> 16) & 0xFF) / static_cast<float>(255));
-	result.w = f16(static_cast<float>((color >> 24) & 0xFF) / static_cast<float>(255));
-	return result;
-}
-
-template <>
-GLM_FUNC_QUALIFIER f16vec4 f16_argb_cast<uint32>(uint32 color)
-{
-	f16vec4 result;
-	result.x = f16(static_cast<float>((color >>  8) & 0xFF) / static_cast<float>(255));
-	result.y = f16(static_cast<float>((color >> 16) & 0xFF) / static_cast<float>(255));
-	result.z = f16(static_cast<float>((color >> 24) & 0xFF) / static_cast<float>(255));
-	result.w = f16(static_cast<float>((color >>  0) & 0xFF) / static_cast<float>(255));
-	return result;
-}
-
-template <>
-GLM_FUNC_QUALIFIER f16vec4 f16_bgra_cast<uint32>(uint32 color)
-{
-	f16vec4 result;
-	result.x = f16(static_cast<float>((color >> 16) & 0xFF) / static_cast<float>(255));
-	result.y = f16(static_cast<float>((color >>  8) & 0xFF) / static_cast<float>(255));
-	result.z = f16(static_cast<float>((color >>  0) & 0xFF) / static_cast<float>(255));
-	result.w = f16(static_cast<float>((color >> 24) & 0xFF) / static_cast<float>(255));
-	return result;
-}
-
-template <>
-GLM_FUNC_QUALIFIER f16vec4 f16_abgr_cast<uint32>(uint32 color)
-{
-	f16vec4 result;
-	result.x = f16(static_cast<float>((color >> 24) & 0xFF) / static_cast<float>(255));
-	result.y = f16(static_cast<float>((color >> 16) & 0xFF) / static_cast<float>(255));
-	result.z = f16(static_cast<float>((color >>  8) & 0xFF) / static_cast<float>(255));
-	result.w = f16(static_cast<float>((color >>  0) & 0xFF) / static_cast<float>(255));
-	return result;
-}
-
-template <>
-GLM_FUNC_QUALIFIER float f32_channel_cast<uint8>(uint8 color)
-{
-	return static_cast<float>(color >>  0) / static_cast<float>(255);
-}
-
-template <>
-GLM_FUNC_QUALIFIER detail::tvec3<float> f32_rgbx_cast<uint32>(uint32 color)
-{
-	detail::tvec3<float> result;
-	result.x = static_cast<float>((color >>  0) & 0xFF) / static_cast<float>(255);
-	result.y = static_cast<float>((color >>  8) & 0xFF) / static_cast<float>(255);
-	result.z = static_cast<float>((color >> 16) & 0xFF) / static_cast<float>(255);
-	return result;
-}
-
-template <>
-GLM_FUNC_QUALIFIER detail::tvec3<float> f32_xrgb_cast<uint32>(uint32 color)
-{
-	detail::tvec3<float> result;
-	result.x = static_cast<float>((color >>  8) & 0xFF) / static_cast<float>(255);
-	result.y = static_cast<float>((color >> 16) & 0xFF) / static_cast<float>(255);
-	result.z = static_cast<float>((color >> 24) & 0xFF) / static_cast<float>(255);
-	return result;
-}
-
-template <>
-GLM_FUNC_QUALIFIER detail::tvec3<float> f32_bgrx_cast<uint32>(uint32 color)
-{
-	detail::tvec3<float> result;
-	result.x = static_cast<float>((color >> 16) & 0xFF) / static_cast<float>(255);
-	result.y = static_cast<float>((color >>  8) & 0xFF) / static_cast<float>(255);
-	result.z = static_cast<float>((color >>  0) & 0xFF) / static_cast<float>(255);
-	return result;
-}
-
-template <>
-GLM_FUNC_QUALIFIER detail::tvec3<float> f32_xbgr_cast<uint32>(uint32 color)
-{
-	detail::tvec3<float> result;
-	result.x = static_cast<float>((color >> 24) & 0xFF) / static_cast<float>(255);
-	result.y = static_cast<float>((color >> 16) & 0xFF) / static_cast<float>(255);
-	result.z = static_cast<float>((color >>  8) & 0xFF) / static_cast<float>(255);
-	return result;
-}
-
-template <>
-GLM_FUNC_QUALIFIER detail::tvec4<float> f32_rgba_cast<uint32>(uint32 color)
-{
-	detail::tvec4<float> result;
-	result.x = static_cast<float>((color >>  0) & 0xFF) / static_cast<float>(255);
-	result.y = static_cast<float>((color >>  8) & 0xFF) / static_cast<float>(255);
-	result.z = static_cast<float>((color >> 16) & 0xFF) / static_cast<float>(255);
-	result.w = static_cast<float>((color >> 24) & 0xFF) / static_cast<float>(255);
-	return result;
-}
-
-template <>
-GLM_FUNC_QUALIFIER detail::tvec4<float> f32_argb_cast<uint32>(uint32 color)
-{
-	detail::tvec4<float> result;
-	result.x = static_cast<float>((color >>  8) & 0xFF) / static_cast<float>(255);
-	result.y = static_cast<float>((color >> 16) & 0xFF) / static_cast<float>(255);
-	result.z = static_cast<float>((color >> 24) & 0xFF) / static_cast<float>(255);
-	result.w = static_cast<float>((color >>  0) & 0xFF) / static_cast<float>(255);
-	return result;
-}
-
-template <>
-GLM_FUNC_QUALIFIER detail::tvec4<float> f32_bgra_cast<uint32>(uint32 color)
-{
-	detail::tvec4<float> result;
-	result.x = static_cast<float>((color >> 16) & 0xFF) / static_cast<float>(255);
-	result.y = static_cast<float>((color >>  8) & 0xFF) / static_cast<float>(255);
-	result.z = static_cast<float>((color >>  0) & 0xFF) / static_cast<float>(255);
-	result.w = static_cast<float>((color >> 24) & 0xFF) / static_cast<float>(255);
-	return result;
-}
-
-template <>
-GLM_FUNC_QUALIFIER detail::tvec4<float> f32_abgr_cast<uint32>(uint32 color)
-{
-	detail::tvec4<float> result;
-	result.x = static_cast<float>((color >> 24) & 0xFF) / static_cast<float>(255);
-	result.y = static_cast<float>((color >> 16) & 0xFF) / static_cast<float>(255);
-	result.z = static_cast<float>((color >>  8) & 0xFF) / static_cast<float>(255);
-	result.w = static_cast<float>((color >>  0) & 0xFF) / static_cast<float>(255);
-	return result;
-}
-
-template <>
-GLM_FUNC_QUALIFIER double f64_channel_cast<uint8>(uint8 color)
-{
-	return static_cast<double>(color >>  0) / static_cast<double>(255);
-}
-
-template <>
-GLM_FUNC_QUALIFIER detail::tvec3<double> f64_rgbx_cast<uint32>(uint32 color)
-{
-	detail::tvec3<double> result;
-	result.x = static_cast<double>((color >>  0) & 0xFF) / static_cast<double>(255);
-	result.y = static_cast<double>((color >>  8) & 0xFF) / static_cast<double>(255);
-	result.z = static_cast<double>((color >> 16) & 0xFF) / static_cast<double>(255);
-	return result;
-}
-
-template <>
-GLM_FUNC_QUALIFIER detail::tvec3<double> f64_xrgb_cast<uint32>(uint32 color)
-{
-	detail::tvec3<double> result;
-	result.x = static_cast<double>((color >>  8) & 0xFF) / static_cast<double>(255);
-	result.y = static_cast<double>((color >> 16) & 0xFF) / static_cast<double>(255);
-	result.z = static_cast<double>((color >> 24) & 0xFF) / static_cast<double>(255);
-	return result;
-}
-
-template <>
-GLM_FUNC_QUALIFIER detail::tvec3<double> f64_bgrx_cast<uint32>(uint32 color)
-{
-	detail::tvec3<double> result;
-	result.x = static_cast<double>((color >> 16) & 0xFF) / static_cast<double>(255);
-	result.y = static_cast<double>((color >>  8) & 0xFF) / static_cast<double>(255);
-	result.z = static_cast<double>((color >>  0) & 0xFF) / static_cast<double>(255);
-	return result;
-}
-
-template <>
-GLM_FUNC_QUALIFIER detail::tvec3<double> f64_xbgr_cast<uint32>(uint32 color)
-{
-	detail::tvec3<double> result;
-	result.x = static_cast<double>((color >> 24) & 0xFF) / static_cast<double>(255);
-	result.y = static_cast<double>((color >> 16) & 0xFF) / static_cast<double>(255);
-	result.z = static_cast<double>((color >>  8) & 0xFF) / static_cast<double>(255);
-	return result;
-}
-
-template <>
-GLM_FUNC_QUALIFIER detail::tvec4<double> f64_rgba_cast<uint32>(uint32 color)
-{
-	detail::tvec4<double> result;
-	result.x = static_cast<double>((color >>  0) & 0xFF) / static_cast<double>(255);
-	result.y = static_cast<double>((color >>  8) & 0xFF) / static_cast<double>(255);
-	result.z = static_cast<double>((color >> 16) & 0xFF) / static_cast<double>(255);
-	result.w = static_cast<double>((color >> 24) & 0xFF) / static_cast<double>(255);
-	return result;
-}
-
-template <>
-GLM_FUNC_QUALIFIER detail::tvec4<double> f64_argb_cast<uint32>(uint32 color)
-{
-	detail::tvec4<double> result;
-	result.x = static_cast<double>((color >>  8) & 0xFF) / static_cast<double>(255);
-	result.y = static_cast<double>((color >> 16) & 0xFF) / static_cast<double>(255);
-	result.z = static_cast<double>((color >> 24) & 0xFF) / static_cast<double>(255);
-	result.w = static_cast<double>((color >>  0) & 0xFF) / static_cast<double>(255);
-	return result;
-}
-
-template <>
-GLM_FUNC_QUALIFIER detail::tvec4<double> f64_bgra_cast<uint32>(uint32 color)
-{
-	detail::tvec4<double> result;
-	result.x = static_cast<double>((color >> 16) & 0xFF) / static_cast<double>(255);
-	result.y = static_cast<double>((color >>  8) & 0xFF) / static_cast<double>(255);
-	result.z = static_cast<double>((color >>  0) & 0xFF) / static_cast<double>(255);
-	result.w = static_cast<double>((color >> 24) & 0xFF) / static_cast<double>(255);
-	return result;
-}
-
-template <>
-GLM_FUNC_QUALIFIER detail::tvec4<double> f64_abgr_cast<uint32>(uint32 color)
-{
-	detail::tvec4<double> result;
-	result.x = static_cast<double>((color >> 24) & 0xFF) / static_cast<double>(255);
-	result.y = static_cast<double>((color >> 16) & 0xFF) / static_cast<double>(255);
-	result.z = static_cast<double>((color >>  8) & 0xFF) / static_cast<double>(255);
-	result.w = static_cast<double>((color >>  0) & 0xFF) / static_cast<double>(255);
-	return result;
-}
-
-template <>
-GLM_FUNC_QUALIFIER detail::thalf f16_channel_cast<uint16>(uint16 color)
-{
-	return detail::thalf(static_cast<float>(color >>  0) / static_cast<float>(65535));
-}
-
-template <>
-GLM_FUNC_QUALIFIER detail::tvec3<detail::thalf> f16_rgbx_cast<uint64>(uint64 color)
-{
-	detail::tvec3<detail::thalf> result;
-	result.x = detail::thalf(static_cast<float>((color >>  0) & 0xFFFF) / static_cast<float>(65535));
-	result.y = detail::thalf(static_cast<float>((color >> 16) & 0xFFFF) / static_cast<float>(65535));
-	result.z = detail::thalf(static_cast<float>((color >> 32) & 0xFFFF) / static_cast<float>(65535));
-	return result;
-}
-
-template <>
-GLM_FUNC_QUALIFIER detail::tvec3<detail::thalf> f16_xrgb_cast<uint64>(uint64 color)
-{
-	detail::tvec3<detail::thalf> result;
-	result.x = detail::thalf(static_cast<float>((color >> 16) & 0xFFFF) / static_cast<float>(65535));
-	result.y = detail::thalf(static_cast<float>((color >> 32) & 0xFFFF) / static_cast<float>(65535));
-	result.z = detail::thalf(static_cast<float>((color >> 48) & 0xFFFF) / static_cast<float>(65535));
-	return result;
-}
-
-template <>
-GLM_FUNC_QUALIFIER detail::tvec3<detail::thalf> f16_bgrx_cast<uint64>(uint64 color)
-{
-	detail::tvec3<detail::thalf> result;
-	result.x = detail::thalf(static_cast<float>((color >> 32) & 0xFFFF) / static_cast<float>(65535));
-	result.y = detail::thalf(static_cast<float>((color >> 16) & 0xFFFF) / static_cast<float>(65535));
-	result.z = detail::thalf(static_cast<float>((color >>  0) & 0xFFFF) / static_cast<float>(65535));
-	return result;
-}
-
-template <>
-GLM_FUNC_QUALIFIER detail::tvec3<detail::thalf> f16_xbgr_cast<uint64>(uint64 color)
-{
-	detail::tvec3<detail::thalf> result;
-	result.x = detail::thalf(static_cast<float>((color >> 48) & 0xFFFF) / static_cast<float>(65535));
-	result.y = detail::thalf(static_cast<float>((color >> 32) & 0xFFFF) / static_cast<float>(65535));
-	result.z = detail::thalf(static_cast<float>((color >> 16) & 0xFFFF) / static_cast<float>(65535));
-	return result;
-}
-
-template <>
-GLM_FUNC_QUALIFIER detail::tvec4<detail::thalf> f16_rgba_cast<uint64>(uint64 color)
-{
-	detail::tvec4<detail::thalf> result;
-	result.x = detail::thalf(static_cast<float>((color >>  0) & 0xFFFF) / static_cast<float>(65535));
-	result.y = detail::thalf(static_cast<float>((color >> 16) & 0xFFFF) / static_cast<float>(65535));
-	result.z = detail::thalf(static_cast<float>((color >> 32) & 0xFFFF) / static_cast<float>(65535));
-	result.w = detail::thalf(static_cast<float>((color >> 48) & 0xFFFF) / static_cast<float>(65535));
-	return result;
-}
-
-template <>
-GLM_FUNC_QUALIFIER detail::tvec4<detail::thalf> f16_argb_cast<uint64>(uint64 color)
-{
-	detail::tvec4<detail::thalf> result;
-	result.x = detail::thalf(static_cast<float>((color >> 16) & 0xFFFF) / static_cast<float>(65535));
-	result.y = detail::thalf(static_cast<float>((color >> 32) & 0xFFFF) / static_cast<float>(65535));
-	result.z = detail::thalf(static_cast<float>((color >> 48) & 0xFFFF) / static_cast<float>(65535));
-	result.w = detail::thalf(static_cast<float>((color >>  0) & 0xFFFF) / static_cast<float>(65535));
-	return result;
-}
-
-template <>
-GLM_FUNC_QUALIFIER detail::tvec4<detail::thalf> f16_bgra_cast<uint64>(uint64 color)
-{
-	detail::tvec4<detail::thalf> result;
-	result.x = detail::thalf(static_cast<float>((color >> 32) & 0xFFFF) / static_cast<float>(65535));
-	result.y = detail::thalf(static_cast<float>((color >> 16) & 0xFFFF) / static_cast<float>(65535));
-	result.z = detail::thalf(static_cast<float>((color >>  0) & 0xFFFF) / static_cast<float>(65535));
-	result.w = detail::thalf(static_cast<float>((color >> 48) & 0xFFFF) / static_cast<float>(65535));
-	return result;
-}
-
-template <>
-GLM_FUNC_QUALIFIER detail::tvec4<detail::thalf> f16_abgr_cast<uint64>(uint64 color)
-{
-	detail::tvec4<detail::thalf> result;
-	result.x = detail::thalf(static_cast<float>((color >> 48) & 0xFFFF) / static_cast<float>(65535));
-	result.y = detail::thalf(static_cast<float>((color >> 32) & 0xFFFF) / static_cast<float>(65535));
-	result.z = detail::thalf(static_cast<float>((color >> 16) & 0xFFFF) / static_cast<float>(65535));
-	result.w = detail::thalf(static_cast<float>((color >>  0) & 0xFFFF) / static_cast<float>(65535));
-	return result;
-}
-
-template <>
-GLM_FUNC_QUALIFIER float f32_channel_cast<uint16>(uint16 color)
-{
-	return static_cast<float>(color >>  0) / static_cast<float>(65535);
-}
-
-template <>
-GLM_FUNC_QUALIFIER detail::tvec3<float> f32_rgbx_cast<uint64>(uint64 color)
-{
-	detail::tvec3<float> result;
-	result.x = static_cast<float>((color >>  0) & 0xFFFF) / static_cast<float>(65535);
-	result.y = static_cast<float>((color >> 16) & 0xFFFF) / static_cast<float>(65535);
-	result.z = static_cast<float>((color >> 32) & 0xFFFF) / static_cast<float>(65535);
-	return result;
-}
-
-template <>
-GLM_FUNC_QUALIFIER detail::tvec3<float> f32_xrgb_cast<uint64>(uint64 color)
-{
-	detail::tvec3<float> result;
-	result.x = static_cast<float>((color >> 16) & 0xFFFF) / static_cast<float>(65535);
-	result.y = static_cast<float>((color >> 32) & 0xFFFF) / static_cast<float>(65535);
-	result.z = static_cast<float>((color >> 48) & 0xFFFF) / static_cast<float>(65535);
-	return result;
-}
-
-template <>
-GLM_FUNC_QUALIFIER detail::tvec3<float> f32_bgrx_cast<uint64>(uint64 color)
-{
-	detail::tvec3<float> result;
-	result.x = static_cast<float>((color >> 32) & 0xFFFF) / static_cast<float>(65535);
-	result.y = static_cast<float>((color >> 16) & 0xFFFF) / static_cast<float>(65535);
-	result.z = static_cast<float>((color >>  0) & 0xFFFF) / static_cast<float>(65535);
-	return result;
-}
-
-template <>
-GLM_FUNC_QUALIFIER detail::tvec3<float> f32_xbgr_cast<uint64>(uint64 color)
-{
-	detail::tvec3<float> result;
-	result.x = static_cast<float>((color >> 48) & 0xFFFF) / static_cast<float>(65535);
-	result.y = static_cast<float>((color >> 32) & 0xFFFF) / static_cast<float>(65535);
-	result.z = static_cast<float>((color >> 16) & 0xFFFF) / static_cast<float>(65535);
-	return result;
-}
-
-template <>
-GLM_FUNC_QUALIFIER detail::tvec4<float> f32_rgba_cast<uint64>(uint64 color)
-{
-	detail::tvec4<float> result;
-	result.x = static_cast<float>((color >>  0) & 0xFFFF) / static_cast<float>(65535);
-	result.y = static_cast<float>((color >> 16) & 0xFFFF) / static_cast<float>(65535);
-	result.z = static_cast<float>((color >> 32) & 0xFFFF) / static_cast<float>(65535);
-	result.w = static_cast<float>((color >> 48) & 0xFFFF) / static_cast<float>(65535);
-	return result;
-}
-
-template <>
-GLM_FUNC_QUALIFIER detail::tvec4<float> f32_argb_cast<uint64>(uint64 color)
-{
-	detail::tvec4<float> result;
-	result.x = static_cast<float>((color >> 16) & 0xFFFF) / static_cast<float>(65535);
-	result.y = static_cast<float>((color >> 32) & 0xFFFF) / static_cast<float>(65535);
-	result.z = static_cast<float>((color >> 48) & 0xFFFF) / static_cast<float>(65535);
-	result.w = static_cast<float>((color >>  0) & 0xFFFF) / static_cast<float>(65535);
-	return result;
-}
-
-template <>
-GLM_FUNC_QUALIFIER detail::tvec4<float> f32_bgra_cast<uint64>(uint64 color)
-{
-	detail::tvec4<float> result;
-	result.x = static_cast<float>((color >> 32) & 0xFFFF) / static_cast<float>(65535);
-	result.y = static_cast<float>((color >> 16) & 0xFFFF) / static_cast<float>(65535);
-	result.z = static_cast<float>((color >>  0) & 0xFFFF) / static_cast<float>(65535);
-	result.w = static_cast<float>((color >> 48) & 0xFFFF) / static_cast<float>(65535);
-	return result;
-}
-
-template <>
-GLM_FUNC_QUALIFIER detail::tvec4<float> f32_abgr_cast<uint64>(uint64 color)
-{
-	detail::tvec4<float> result;
-	result.x = static_cast<float>((color >> 48) & 0xFFFF) / static_cast<float>(65535);
-	result.y = static_cast<float>((color >> 32) & 0xFFFF) / static_cast<float>(65535);
-	result.z = static_cast<float>((color >> 16) & 0xFFFF) / static_cast<float>(65535);
-	result.w = static_cast<float>((color >>  0) & 0xFFFF) / static_cast<float>(65535);
-	return result;
-}
-
-template <>
-GLM_FUNC_QUALIFIER double f64_channel_cast<uint16>(uint16 color)
-{
-	return static_cast<double>(color >>  0) / static_cast<double>(65535);
-}
-
-template <>
-GLM_FUNC_QUALIFIER detail::tvec3<double> f64_rgbx_cast<uint64>(uint64 color)
-{
-	detail::tvec3<double> result;
-	result.x = static_cast<double>((color >>  0) & 0xFFFF) / static_cast<double>(65535);
-	result.y = static_cast<double>((color >> 16) & 0xFFFF) / static_cast<double>(65535);
-	result.z = static_cast<double>((color >> 32) & 0xFFFF) / static_cast<double>(65535);
-	return result;
-}
-
-template <>
-GLM_FUNC_QUALIFIER detail::tvec3<double> f64_xrgb_cast<uint64>(uint64 color)
-{
-	detail::tvec3<double> result;
-	result.x = static_cast<double>((color >> 16) & 0xFFFF) / static_cast<double>(65535);
-	result.y = static_cast<double>((color >> 32) & 0xFFFF) / static_cast<double>(65535);
-	result.z = static_cast<double>((color >> 48) & 0xFFFF) / static_cast<double>(65535);
-	return result;
-}
-
-template <>
-GLM_FUNC_QUALIFIER detail::tvec3<double> f64_bgrx_cast<uint64>(uint64 color)
-{
-	detail::tvec3<double> result;
-	result.x = static_cast<double>((color >> 32) & 0xFFFF) / static_cast<double>(65535);
-	result.y = static_cast<double>((color >> 16) & 0xFFFF) / static_cast<double>(65535);
-	result.z = static_cast<double>((color >>  0) & 0xFFFF) / static_cast<double>(65535);
-	return result;
-}
-
-template <>
-GLM_FUNC_QUALIFIER detail::tvec3<double> f64_xbgr_cast<uint64>(uint64 color)
-{
-	detail::tvec3<double> result;
-	result.x = static_cast<double>((color >> 48) & 0xFFFF) / static_cast<double>(65535);
-	result.y = static_cast<double>((color >> 32) & 0xFFFF) / static_cast<double>(65535);
-	result.z = static_cast<double>((color >> 16) & 0xFFFF) / static_cast<double>(65535);
-	return result;
-}
-
-template <>
-GLM_FUNC_QUALIFIER detail::tvec4<double> f64_rgba_cast<uint64>(uint64 color)
-{
-	detail::tvec4<double> result;
-	result.x = static_cast<double>((color >>  0) & 0xFFFF) / static_cast<double>(65535);
-	result.y = static_cast<double>((color >> 16) & 0xFFFF) / static_cast<double>(65535);
-	result.z = static_cast<double>((color >> 32) & 0xFFFF) / static_cast<double>(65535);
-	result.w = static_cast<double>((color >> 48) & 0xFFFF) / static_cast<double>(65535);
-	return result;
-}
-
-template <>
-GLM_FUNC_QUALIFIER detail::tvec4<double> f64_argb_cast<uint64>(uint64 color)
-{
-	detail::tvec4<double> result;
-	result.x = static_cast<double>((color >> 16) & 0xFFFF) / static_cast<double>(65535);
-	result.y = static_cast<double>((color >> 32) & 0xFFFF) / static_cast<double>(65535);
-	result.z = static_cast<double>((color >> 48) & 0xFFFF) / static_cast<double>(65535);
-	result.w = static_cast<double>((color >>  0) & 0xFFFF) / static_cast<double>(65535);
-	return result;
-}
-
-template <>
-GLM_FUNC_QUALIFIER detail::tvec4<double> f64_bgra_cast<uint64>(uint64 color)
-{
-	detail::tvec4<double> result;
-	result.x = static_cast<double>((color >> 32) & 0xFFFF) / static_cast<double>(65535);
-	result.y = static_cast<double>((color >> 16) & 0xFFFF) / static_cast<double>(65535);
-	result.z = static_cast<double>((color >>  0) & 0xFFFF) / static_cast<double>(65535);
-	result.w = static_cast<double>((color >> 48) & 0xFFFF) / static_cast<double>(65535);
-	return result;
-}
-
-template <>
-GLM_FUNC_QUALIFIER detail::tvec4<double> f64_abgr_cast<uint64>(uint64 color)
-{
-	detail::tvec4<double> result;
-	result.x = static_cast<double>((color >> 48) & 0xFFFF) / static_cast<double>(65535);
-	result.y = static_cast<double>((color >> 32) & 0xFFFF) / static_cast<double>(65535);
-	result.z = static_cast<double>((color >> 16) & 0xFFFF) / static_cast<double>(65535);
-	result.w = static_cast<double>((color >>  0) & 0xFFFF) / static_cast<double>(65535);
-	return result;
-}
-
+namespace glm
+{
+	template <typename T> 
+	GLM_FUNC_QUALIFIER uint8 u8channel_cast(T a)
+	{
+		return static_cast<uint8>(a * T(255));
+	}
+
+	template <typename T> 
+	GLM_FUNC_QUALIFIER uint16 u16channel_cast(T a)
+	{
+		return static_cast<uint16>(a * T(65535));
+	}
+
+	template <typename T>
+	GLM_FUNC_QUALIFIER uint32 u32_rgbx_cast(const detail::tvec3<T>& c)
+	{
+		uint32 result = 0;
+		result += static_cast<uint32>(c.x * detail::tvec3<T>::value_type(255)) <<  0;
+		result += static_cast<uint32>(c.y * detail::tvec3<T>::value_type(255)) <<  8;
+		result += static_cast<uint32>(c.z * detail::tvec3<T>::value_type(255)) << 16;
+		return result;
+	}
+
+	template <typename T>
+	GLM_FUNC_QUALIFIER uint32 u32_xrgb_cast(const detail::tvec3<T>& c)
+	{
+		uint32 result = 0;
+		result += static_cast<uint32>(c.x * detail::tvec3<T>::value_type(255)) <<  8;
+		result += static_cast<uint32>(c.y * detail::tvec3<T>::value_type(255)) << 16;
+		result += static_cast<uint32>(c.z * detail::tvec3<T>::value_type(255)) << 24;
+		return result;
+	}
+
+	template <typename T>
+	GLM_FUNC_QUALIFIER uint32 u32_bgrx_cast(const detail::tvec3<T>& c)
+	{
+		uint32 result = 0;
+		result += static_cast<uint32>(c.x * detail::tvec3<T>::value_type(255)) << 16;
+		result += static_cast<uint32>(c.y * detail::tvec3<T>::value_type(255)) <<  8;
+		result += static_cast<uint32>(c.z * detail::tvec3<T>::value_type(255)) <<  0;
+		return result;
+	}
+
+	template <typename T>
+	GLM_FUNC_QUALIFIER uint32 u32_xbgr_cast(const detail::tvec3<T>& c)
+	{
+		uint32 result = 0;
+		result += static_cast<uint32>(c.x * detail::tvec3<T>::value_type(255)) << 24;
+		result += static_cast<uint32>(c.y * detail::tvec3<T>::value_type(255)) << 16;
+		result += static_cast<uint32>(c.z * detail::tvec3<T>::value_type(255)) <<  8;
+		result += static_cast<uint32>(c.w * detail::tvec3<T>::value_type(255)) <<  0;
+		return result;
+	}
+
+	template <typename T>
+	GLM_FUNC_QUALIFIER uint32 u32_rgba_cast(const detail::tvec4<T>& c)
+	{
+		uint32 result = 0;
+		result += static_cast<uint32>(c.x * detail::tvec4<T>::value_type(255)) <<  0;
+		result += static_cast<uint32>(c.y * detail::tvec4<T>::value_type(255)) <<  8;
+		result += static_cast<uint32>(c.z * detail::tvec4<T>::value_type(255)) << 16;
+		result += static_cast<uint32>(c.w * detail::tvec4<T>::value_type(255)) << 24;
+		return result;
+	}
+
+	template <typename T>
+	GLM_FUNC_QUALIFIER uint32 u32_argb_cast(const detail::tvec4<T>& c)
+	{
+		uint32 result = 0;
+		result += static_cast<uint32>(c.x * detail::tvec4<T>::value_type(255)) <<  8;
+		result += static_cast<uint32>(c.y * detail::tvec4<T>::value_type(255)) << 16;
+		result += static_cast<uint32>(c.z * detail::tvec4<T>::value_type(255)) << 24;
+		result += static_cast<uint32>(c.w * detail::tvec4<T>::value_type(255)) <<  0;
+		return result;
+	}
+
+	template <typename T>
+	GLM_FUNC_QUALIFIER uint32 u32_bgra_cast(const detail::tvec4<T>& c)
+	{
+		uint32 result = 0;
+		result += static_cast<uint32>(c.x * detail::tvec4<T>::value_type(255)) << 16;
+		result += static_cast<uint32>(c.y * detail::tvec4<T>::value_type(255)) <<  8;
+		result += static_cast<uint32>(c.z * detail::tvec4<T>::value_type(255)) <<  0;
+		result += static_cast<uint32>(c.w * detail::tvec4<T>::value_type(255)) << 24;
+		return result;
+	}
+
+	template <typename T>
+	GLM_FUNC_QUALIFIER uint32 u32_abgr_cast(const detail::tvec4<T>& c)
+	{
+		uint32 result = 0;
+		result += static_cast<uint32>(c.x * detail::tvec4<T>::value_type(255)) << 24;
+		result += static_cast<uint32>(c.y * detail::tvec4<T>::value_type(255)) << 16;
+		result += static_cast<uint32>(c.z * detail::tvec4<T>::value_type(255)) <<  8;
+		result += static_cast<uint32>(c.w * detail::tvec4<T>::value_type(255)) <<  0;
+		return result;
+	}
+
+	template <typename T>
+	GLM_FUNC_QUALIFIER uint64 u64_rgbx_cast(const detail::tvec3<T>& c)
+	{
+		uint64 result = 0;
+		result += static_cast<uint64>(c.x * detail::tvec3<T>::value_type(65535)) <<  0;
+		result += static_cast<uint64>(c.y * detail::tvec3<T>::value_type(65535)) << 16;
+		result += static_cast<uint64>(c.z * detail::tvec3<T>::value_type(65535)) << 32;
+		return result;
+	}
+
+	template <typename T>
+	GLM_FUNC_QUALIFIER uint64 u32_xrgb_cast(const detail::tvec3<T>& c)
+	{
+		uint64 result = 0;
+		result += static_cast<uint64>(c.x * detail::tvec3<T>::value_type(65535)) << 16;
+		result += static_cast<uint64>(c.y * detail::tvec3<T>::value_type(65535)) << 32;
+		result += static_cast<uint64>(c.z * detail::tvec3<T>::value_type(65535)) << 48;
+		return result;
+	}
+
+	template <typename T>
+	GLM_FUNC_QUALIFIER uint64 u32_bgrx_cast(const detail::tvec3<T>& c)
+	{
+		uint64 result = 0;
+		result += static_cast<uint64>(c.x * detail::tvec3<T>::value_type(65535)) << 32;
+		result += static_cast<uint64>(c.y * detail::tvec3<T>::value_type(65535)) << 16;
+		result += static_cast<uint64>(c.z * detail::tvec3<T>::value_type(65535)) <<  0;
+		return result;
+	}
+
+	template <typename T>
+	GLM_FUNC_QUALIFIER uint64 u32_xbgr_cast(const detail::tvec3<T>& c)
+	{
+		uint64 result = 0;
+		result += static_cast<uint64>(c.x * detail::tvec3<T>::value_type(65535)) << 48;
+		result += static_cast<uint64>(c.y * detail::tvec3<T>::value_type(65535)) << 32;
+		result += static_cast<uint64>(c.z * detail::tvec3<T>::value_type(65535)) << 16;
+		result += static_cast<uint64>(c.w * detail::tvec3<T>::value_type(65535)) <<  0;
+		return result;
+	}
+
+	template <typename T>
+	GLM_FUNC_QUALIFIER uint64 u64_rgba_cast(const detail::tvec4<T>& c)
+	{
+		uint64 result = 0;
+		result += static_cast<uint64>(c.x * detail::tvec4<T>::value_type(65535)) <<  0;
+		result += static_cast<uint64>(c.y * detail::tvec4<T>::value_type(65535)) << 16;
+		result += static_cast<uint64>(c.z * detail::tvec4<T>::value_type(65535)) << 32;
+		result += static_cast<uint64>(c.w * detail::tvec4<T>::value_type(65535)) << 48;
+		return result;
+	}
+
+	template <typename T>
+	GLM_FUNC_QUALIFIER uint64 u64_argb_cast(const detail::tvec4<T>& c)
+	{
+		uint64 result = 0;
+		result += static_cast<uint64>(c.x * detail::tvec4<T>::value_type(65535)) << 16;
+		result += static_cast<uint64>(c.y * detail::tvec4<T>::value_type(65535)) << 32;
+		result += static_cast<uint64>(c.z * detail::tvec4<T>::value_type(65535)) << 48;
+		result += static_cast<uint64>(c.w * detail::tvec4<T>::value_type(65535)) <<  0;
+		return result;
+	}
+
+	template <typename T>
+	GLM_FUNC_QUALIFIER uint64 u64_bgra_cast(const detail::tvec4<T>& c)
+	{
+		uint64 result = 0;
+		result += static_cast<uint64>(c.x * detail::tvec4<T>::value_type(65535)) << 32;
+		result += static_cast<uint64>(c.y * detail::tvec4<T>::value_type(65535)) << 16;
+		result += static_cast<uint64>(c.z * detail::tvec4<T>::value_type(65535)) <<  0;
+		result += static_cast<uint64>(c.w * detail::tvec4<T>::value_type(65535)) << 48;
+		return result;
+	}
+
+	template <typename T>
+	GLM_FUNC_QUALIFIER uint64 u64_abgr_cast(const detail::tvec4<T>& c)
+	{
+		uint64 result = 0;
+		result += static_cast<uint64>(c.x * detail::tvec4<T>::value_type(65535)) << 48;
+		result += static_cast<uint64>(c.y * detail::tvec4<T>::value_type(65535)) << 32;
+		result += static_cast<uint64>(c.z * detail::tvec4<T>::value_type(65535)) << 16;
+		result += static_cast<uint64>(c.w * detail::tvec4<T>::value_type(65535)) <<  0;
+		return result;
+	}
+
+	template <>
+	GLM_FUNC_QUALIFIER f16 f16_channel_cast<uint32>(uint32 color)
+	{
+		return f16(static_cast<float>(color >>  0) / static_cast<float>(255));
+	}
+
+	template <>
+	GLM_FUNC_QUALIFIER f16vec3 f16_rgbx_cast<uint32>(uint32 color)
+	{
+		f16vec3 result;
+		result.x = f16(static_cast<float>((color >>  0) & 0xFF) / static_cast<float>(255));
+		result.y = f16(static_cast<float>((color >>  8) & 0xFF) / static_cast<float>(255));
+		result.z = f16(static_cast<float>((color >> 16) & 0xFF) / static_cast<float>(255));
+		return result;
+	}
+
+	template <>
+	GLM_FUNC_QUALIFIER f16vec3 f16_xrgb_cast<uint32>(uint32 color)
+	{
+		f16vec3 result;
+		result.x = f16(static_cast<float>((color >>  8) & 0xFF) / static_cast<float>(255));
+		result.y = f16(static_cast<float>((color >> 16) & 0xFF) / static_cast<float>(255));
+		result.z = f16(static_cast<float>((color >> 24) & 0xFF) / static_cast<float>(255));
+		return result;
+	}
+
+	template <>
+	GLM_FUNC_QUALIFIER f16vec3 f16_bgrx_cast<uint32>(uint32 color)
+	{
+		f16vec3 result;
+		result.x = f16(static_cast<float>((color >> 16) & 0xFF) / static_cast<float>(255));
+		result.y = f16(static_cast<float>((color >>  8) & 0xFF) / static_cast<float>(255));
+		result.z = f16(static_cast<float>((color >>  0) & 0xFF) / static_cast<float>(255));
+		return result;
+	}
+
+	template <>
+	GLM_FUNC_QUALIFIER f16vec3 f16_xbgr_cast<uint32>(uint32 color)
+	{
+		f16vec3 result;
+		result.x = f16(static_cast<float>((color >> 24) & 0xFF) / static_cast<float>(255));
+		result.y = f16(static_cast<float>((color >> 16) & 0xFF) / static_cast<float>(255));
+		result.z = f16(static_cast<float>((color >>  8) & 0xFF) / static_cast<float>(255));
+		return result;
+	}
+
+	template <>
+	GLM_FUNC_QUALIFIER f16vec4 f16_rgba_cast<uint32>(uint32 color)
+	{
+		f16vec4 result;
+		result.x = f16(static_cast<float>((color >>  0) & 0xFF) / static_cast<float>(255));
+		result.y = f16(static_cast<float>((color >>  8) & 0xFF) / static_cast<float>(255));
+		result.z = f16(static_cast<float>((color >> 16) & 0xFF) / static_cast<float>(255));
+		result.w = f16(static_cast<float>((color >> 24) & 0xFF) / static_cast<float>(255));
+		return result;
+	}
+
+	template <>
+	GLM_FUNC_QUALIFIER f16vec4 f16_argb_cast<uint32>(uint32 color)
+	{
+		f16vec4 result;
+		result.x = f16(static_cast<float>((color >>  8) & 0xFF) / static_cast<float>(255));
+		result.y = f16(static_cast<float>((color >> 16) & 0xFF) / static_cast<float>(255));
+		result.z = f16(static_cast<float>((color >> 24) & 0xFF) / static_cast<float>(255));
+		result.w = f16(static_cast<float>((color >>  0) & 0xFF) / static_cast<float>(255));
+		return result;
+	}
+
+	template <>
+	GLM_FUNC_QUALIFIER f16vec4 f16_bgra_cast<uint32>(uint32 color)
+	{
+		f16vec4 result;
+		result.x = f16(static_cast<float>((color >> 16) & 0xFF) / static_cast<float>(255));
+		result.y = f16(static_cast<float>((color >>  8) & 0xFF) / static_cast<float>(255));
+		result.z = f16(static_cast<float>((color >>  0) & 0xFF) / static_cast<float>(255));
+		result.w = f16(static_cast<float>((color >> 24) & 0xFF) / static_cast<float>(255));
+		return result;
+	}
+
+	template <>
+	GLM_FUNC_QUALIFIER f16vec4 f16_abgr_cast<uint32>(uint32 color)
+	{
+		f16vec4 result;
+		result.x = f16(static_cast<float>((color >> 24) & 0xFF) / static_cast<float>(255));
+		result.y = f16(static_cast<float>((color >> 16) & 0xFF) / static_cast<float>(255));
+		result.z = f16(static_cast<float>((color >>  8) & 0xFF) / static_cast<float>(255));
+		result.w = f16(static_cast<float>((color >>  0) & 0xFF) / static_cast<float>(255));
+		return result;
+	}
+
+	template <>
+	GLM_FUNC_QUALIFIER float f32_channel_cast<uint8>(uint8 color)
+	{
+		return static_cast<float>(color >>  0) / static_cast<float>(255);
+	}
+
+	template <>
+	GLM_FUNC_QUALIFIER detail::tvec3<float> f32_rgbx_cast<uint32>(uint32 color)
+	{
+		detail::tvec3<float> result;
+		result.x = static_cast<float>((color >>  0) & 0xFF) / static_cast<float>(255);
+		result.y = static_cast<float>((color >>  8) & 0xFF) / static_cast<float>(255);
+		result.z = static_cast<float>((color >> 16) & 0xFF) / static_cast<float>(255);
+		return result;
+	}
+
+	template <>
+	GLM_FUNC_QUALIFIER detail::tvec3<float> f32_xrgb_cast<uint32>(uint32 color)
+	{
+		detail::tvec3<float> result;
+		result.x = static_cast<float>((color >>  8) & 0xFF) / static_cast<float>(255);
+		result.y = static_cast<float>((color >> 16) & 0xFF) / static_cast<float>(255);
+		result.z = static_cast<float>((color >> 24) & 0xFF) / static_cast<float>(255);
+		return result;
+	}
+
+	template <>
+	GLM_FUNC_QUALIFIER detail::tvec3<float> f32_bgrx_cast<uint32>(uint32 color)
+	{
+		detail::tvec3<float> result;
+		result.x = static_cast<float>((color >> 16) & 0xFF) / static_cast<float>(255);
+		result.y = static_cast<float>((color >>  8) & 0xFF) / static_cast<float>(255);
+		result.z = static_cast<float>((color >>  0) & 0xFF) / static_cast<float>(255);
+		return result;
+	}
+
+	template <>
+	GLM_FUNC_QUALIFIER detail::tvec3<float> f32_xbgr_cast<uint32>(uint32 color)
+	{
+		detail::tvec3<float> result;
+		result.x = static_cast<float>((color >> 24) & 0xFF) / static_cast<float>(255);
+		result.y = static_cast<float>((color >> 16) & 0xFF) / static_cast<float>(255);
+		result.z = static_cast<float>((color >>  8) & 0xFF) / static_cast<float>(255);
+		return result;
+	}
+
+	template <>
+	GLM_FUNC_QUALIFIER detail::tvec4<float> f32_rgba_cast<uint32>(uint32 color)
+	{
+		detail::tvec4<float> result;
+		result.x = static_cast<float>((color >>  0) & 0xFF) / static_cast<float>(255);
+		result.y = static_cast<float>((color >>  8) & 0xFF) / static_cast<float>(255);
+		result.z = static_cast<float>((color >> 16) & 0xFF) / static_cast<float>(255);
+		result.w = static_cast<float>((color >> 24) & 0xFF) / static_cast<float>(255);
+		return result;
+	}
+
+	template <>
+	GLM_FUNC_QUALIFIER detail::tvec4<float> f32_argb_cast<uint32>(uint32 color)
+	{
+		detail::tvec4<float> result;
+		result.x = static_cast<float>((color >>  8) & 0xFF) / static_cast<float>(255);
+		result.y = static_cast<float>((color >> 16) & 0xFF) / static_cast<float>(255);
+		result.z = static_cast<float>((color >> 24) & 0xFF) / static_cast<float>(255);
+		result.w = static_cast<float>((color >>  0) & 0xFF) / static_cast<float>(255);
+		return result;
+	}
+
+	template <>
+	GLM_FUNC_QUALIFIER detail::tvec4<float> f32_bgra_cast<uint32>(uint32 color)
+	{
+		detail::tvec4<float> result;
+		result.x = static_cast<float>((color >> 16) & 0xFF) / static_cast<float>(255);
+		result.y = static_cast<float>((color >>  8) & 0xFF) / static_cast<float>(255);
+		result.z = static_cast<float>((color >>  0) & 0xFF) / static_cast<float>(255);
+		result.w = static_cast<float>((color >> 24) & 0xFF) / static_cast<float>(255);
+		return result;
+	}
+
+	template <>
+	GLM_FUNC_QUALIFIER detail::tvec4<float> f32_abgr_cast<uint32>(uint32 color)
+	{
+		detail::tvec4<float> result;
+		result.x = static_cast<float>((color >> 24) & 0xFF) / static_cast<float>(255);
+		result.y = static_cast<float>((color >> 16) & 0xFF) / static_cast<float>(255);
+		result.z = static_cast<float>((color >>  8) & 0xFF) / static_cast<float>(255);
+		result.w = static_cast<float>((color >>  0) & 0xFF) / static_cast<float>(255);
+		return result;
+	}
+
+	template <>
+	GLM_FUNC_QUALIFIER double f64_channel_cast<uint8>(uint8 color)
+	{
+		return static_cast<double>(color >>  0) / static_cast<double>(255);
+	}
+
+	template <>
+	GLM_FUNC_QUALIFIER detail::tvec3<double> f64_rgbx_cast<uint32>(uint32 color)
+	{
+		detail::tvec3<double> result;
+		result.x = static_cast<double>((color >>  0) & 0xFF) / static_cast<double>(255);
+		result.y = static_cast<double>((color >>  8) & 0xFF) / static_cast<double>(255);
+		result.z = static_cast<double>((color >> 16) & 0xFF) / static_cast<double>(255);
+		return result;
+	}
+
+	template <>
+	GLM_FUNC_QUALIFIER detail::tvec3<double> f64_xrgb_cast<uint32>(uint32 color)
+	{
+		detail::tvec3<double> result;
+		result.x = static_cast<double>((color >>  8) & 0xFF) / static_cast<double>(255);
+		result.y = static_cast<double>((color >> 16) & 0xFF) / static_cast<double>(255);
+		result.z = static_cast<double>((color >> 24) & 0xFF) / static_cast<double>(255);
+		return result;
+	}
+
+	template <>
+	GLM_FUNC_QUALIFIER detail::tvec3<double> f64_bgrx_cast<uint32>(uint32 color)
+	{
+		detail::tvec3<double> result;
+		result.x = static_cast<double>((color >> 16) & 0xFF) / static_cast<double>(255);
+		result.y = static_cast<double>((color >>  8) & 0xFF) / static_cast<double>(255);
+		result.z = static_cast<double>((color >>  0) & 0xFF) / static_cast<double>(255);
+		return result;
+	}
+
+	template <>
+	GLM_FUNC_QUALIFIER detail::tvec3<double> f64_xbgr_cast<uint32>(uint32 color)
+	{
+		detail::tvec3<double> result;
+		result.x = static_cast<double>((color >> 24) & 0xFF) / static_cast<double>(255);
+		result.y = static_cast<double>((color >> 16) & 0xFF) / static_cast<double>(255);
+		result.z = static_cast<double>((color >>  8) & 0xFF) / static_cast<double>(255);
+		return result;
+	}
+
+	template <>
+	GLM_FUNC_QUALIFIER detail::tvec4<double> f64_rgba_cast<uint32>(uint32 color)
+	{
+		detail::tvec4<double> result;
+		result.x = static_cast<double>((color >>  0) & 0xFF) / static_cast<double>(255);
+		result.y = static_cast<double>((color >>  8) & 0xFF) / static_cast<double>(255);
+		result.z = static_cast<double>((color >> 16) & 0xFF) / static_cast<double>(255);
+		result.w = static_cast<double>((color >> 24) & 0xFF) / static_cast<double>(255);
+		return result;
+	}
+
+	template <>
+	GLM_FUNC_QUALIFIER detail::tvec4<double> f64_argb_cast<uint32>(uint32 color)
+	{
+		detail::tvec4<double> result;
+		result.x = static_cast<double>((color >>  8) & 0xFF) / static_cast<double>(255);
+		result.y = static_cast<double>((color >> 16) & 0xFF) / static_cast<double>(255);
+		result.z = static_cast<double>((color >> 24) & 0xFF) / static_cast<double>(255);
+		result.w = static_cast<double>((color >>  0) & 0xFF) / static_cast<double>(255);
+		return result;
+	}
+
+	template <>
+	GLM_FUNC_QUALIFIER detail::tvec4<double> f64_bgra_cast<uint32>(uint32 color)
+	{
+		detail::tvec4<double> result;
+		result.x = static_cast<double>((color >> 16) & 0xFF) / static_cast<double>(255);
+		result.y = static_cast<double>((color >>  8) & 0xFF) / static_cast<double>(255);
+		result.z = static_cast<double>((color >>  0) & 0xFF) / static_cast<double>(255);
+		result.w = static_cast<double>((color >> 24) & 0xFF) / static_cast<double>(255);
+		return result;
+	}
+
+	template <>
+	GLM_FUNC_QUALIFIER detail::tvec4<double> f64_abgr_cast<uint32>(uint32 color)
+	{
+		detail::tvec4<double> result;
+		result.x = static_cast<double>((color >> 24) & 0xFF) / static_cast<double>(255);
+		result.y = static_cast<double>((color >> 16) & 0xFF) / static_cast<double>(255);
+		result.z = static_cast<double>((color >>  8) & 0xFF) / static_cast<double>(255);
+		result.w = static_cast<double>((color >>  0) & 0xFF) / static_cast<double>(255);
+		return result;
+	}
+
+	template <>
+	GLM_FUNC_QUALIFIER detail::thalf f16_channel_cast<uint16>(uint16 color)
+	{
+		return detail::thalf(static_cast<float>(color >>  0) / static_cast<float>(65535));
+	}
+
+	template <>
+	GLM_FUNC_QUALIFIER detail::tvec3<detail::thalf> f16_rgbx_cast<uint64>(uint64 color)
+	{
+		detail::tvec3<detail::thalf> result;
+		result.x = detail::thalf(static_cast<float>((color >>  0) & 0xFFFF) / static_cast<float>(65535));
+		result.y = detail::thalf(static_cast<float>((color >> 16) & 0xFFFF) / static_cast<float>(65535));
+		result.z = detail::thalf(static_cast<float>((color >> 32) & 0xFFFF) / static_cast<float>(65535));
+		return result;
+	}
+
+	template <>
+	GLM_FUNC_QUALIFIER detail::tvec3<detail::thalf> f16_xrgb_cast<uint64>(uint64 color)
+	{
+		detail::tvec3<detail::thalf> result;
+		result.x = detail::thalf(static_cast<float>((color >> 16) & 0xFFFF) / static_cast<float>(65535));
+		result.y = detail::thalf(static_cast<float>((color >> 32) & 0xFFFF) / static_cast<float>(65535));
+		result.z = detail::thalf(static_cast<float>((color >> 48) & 0xFFFF) / static_cast<float>(65535));
+		return result;
+	}
+
+	template <>
+	GLM_FUNC_QUALIFIER detail::tvec3<detail::thalf> f16_bgrx_cast<uint64>(uint64 color)
+	{
+		detail::tvec3<detail::thalf> result;
+		result.x = detail::thalf(static_cast<float>((color >> 32) & 0xFFFF) / static_cast<float>(65535));
+		result.y = detail::thalf(static_cast<float>((color >> 16) & 0xFFFF) / static_cast<float>(65535));
+		result.z = detail::thalf(static_cast<float>((color >>  0) & 0xFFFF) / static_cast<float>(65535));
+		return result;
+	}
+
+	template <>
+	GLM_FUNC_QUALIFIER detail::tvec3<detail::thalf> f16_xbgr_cast<uint64>(uint64 color)
+	{
+		detail::tvec3<detail::thalf> result;
+		result.x = detail::thalf(static_cast<float>((color >> 48) & 0xFFFF) / static_cast<float>(65535));
+		result.y = detail::thalf(static_cast<float>((color >> 32) & 0xFFFF) / static_cast<float>(65535));
+		result.z = detail::thalf(static_cast<float>((color >> 16) & 0xFFFF) / static_cast<float>(65535));
+		return result;
+	}
+
+	template <>
+	GLM_FUNC_QUALIFIER detail::tvec4<detail::thalf> f16_rgba_cast<uint64>(uint64 color)
+	{
+		detail::tvec4<detail::thalf> result;
+		result.x = detail::thalf(static_cast<float>((color >>  0) & 0xFFFF) / static_cast<float>(65535));
+		result.y = detail::thalf(static_cast<float>((color >> 16) & 0xFFFF) / static_cast<float>(65535));
+		result.z = detail::thalf(static_cast<float>((color >> 32) & 0xFFFF) / static_cast<float>(65535));
+		result.w = detail::thalf(static_cast<float>((color >> 48) & 0xFFFF) / static_cast<float>(65535));
+		return result;
+	}
+
+	template <>
+	GLM_FUNC_QUALIFIER detail::tvec4<detail::thalf> f16_argb_cast<uint64>(uint64 color)
+	{
+		detail::tvec4<detail::thalf> result;
+		result.x = detail::thalf(static_cast<float>((color >> 16) & 0xFFFF) / static_cast<float>(65535));
+		result.y = detail::thalf(static_cast<float>((color >> 32) & 0xFFFF) / static_cast<float>(65535));
+		result.z = detail::thalf(static_cast<float>((color >> 48) & 0xFFFF) / static_cast<float>(65535));
+		result.w = detail::thalf(static_cast<float>((color >>  0) & 0xFFFF) / static_cast<float>(65535));
+		return result;
+	}
+
+	template <>
+	GLM_FUNC_QUALIFIER detail::tvec4<detail::thalf> f16_bgra_cast<uint64>(uint64 color)
+	{
+		detail::tvec4<detail::thalf> result;
+		result.x = detail::thalf(static_cast<float>((color >> 32) & 0xFFFF) / static_cast<float>(65535));
+		result.y = detail::thalf(static_cast<float>((color >> 16) & 0xFFFF) / static_cast<float>(65535));
+		result.z = detail::thalf(static_cast<float>((color >>  0) & 0xFFFF) / static_cast<float>(65535));
+		result.w = detail::thalf(static_cast<float>((color >> 48) & 0xFFFF) / static_cast<float>(65535));
+		return result;
+	}
+
+	template <>
+	GLM_FUNC_QUALIFIER detail::tvec4<detail::thalf> f16_abgr_cast<uint64>(uint64 color)
+	{
+		detail::tvec4<detail::thalf> result;
+		result.x = detail::thalf(static_cast<float>((color >> 48) & 0xFFFF) / static_cast<float>(65535));
+		result.y = detail::thalf(static_cast<float>((color >> 32) & 0xFFFF) / static_cast<float>(65535));
+		result.z = detail::thalf(static_cast<float>((color >> 16) & 0xFFFF) / static_cast<float>(65535));
+		result.w = detail::thalf(static_cast<float>((color >>  0) & 0xFFFF) / static_cast<float>(65535));
+		return result;
+	}
+
+	template <>
+	GLM_FUNC_QUALIFIER float f32_channel_cast<uint16>(uint16 color)
+	{
+		return static_cast<float>(color >>  0) / static_cast<float>(65535);
+	}
+
+	template <>
+	GLM_FUNC_QUALIFIER detail::tvec3<float> f32_rgbx_cast<uint64>(uint64 color)
+	{
+		detail::tvec3<float> result;
+		result.x = static_cast<float>((color >>  0) & 0xFFFF) / static_cast<float>(65535);
+		result.y = static_cast<float>((color >> 16) & 0xFFFF) / static_cast<float>(65535);
+		result.z = static_cast<float>((color >> 32) & 0xFFFF) / static_cast<float>(65535);
+		return result;
+	}
+
+	template <>
+	GLM_FUNC_QUALIFIER detail::tvec3<float> f32_xrgb_cast<uint64>(uint64 color)
+	{
+		detail::tvec3<float> result;
+		result.x = static_cast<float>((color >> 16) & 0xFFFF) / static_cast<float>(65535);
+		result.y = static_cast<float>((color >> 32) & 0xFFFF) / static_cast<float>(65535);
+		result.z = static_cast<float>((color >> 48) & 0xFFFF) / static_cast<float>(65535);
+		return result;
+	}
+
+	template <>
+	GLM_FUNC_QUALIFIER detail::tvec3<float> f32_bgrx_cast<uint64>(uint64 color)
+	{
+		detail::tvec3<float> result;
+		result.x = static_cast<float>((color >> 32) & 0xFFFF) / static_cast<float>(65535);
+		result.y = static_cast<float>((color >> 16) & 0xFFFF) / static_cast<float>(65535);
+		result.z = static_cast<float>((color >>  0) & 0xFFFF) / static_cast<float>(65535);
+		return result;
+	}
+
+	template <>
+	GLM_FUNC_QUALIFIER detail::tvec3<float> f32_xbgr_cast<uint64>(uint64 color)
+	{
+		detail::tvec3<float> result;
+		result.x = static_cast<float>((color >> 48) & 0xFFFF) / static_cast<float>(65535);
+		result.y = static_cast<float>((color >> 32) & 0xFFFF) / static_cast<float>(65535);
+		result.z = static_cast<float>((color >> 16) & 0xFFFF) / static_cast<float>(65535);
+		return result;
+	}
+
+	template <>
+	GLM_FUNC_QUALIFIER detail::tvec4<float> f32_rgba_cast<uint64>(uint64 color)
+	{
+		detail::tvec4<float> result;
+		result.x = static_cast<float>((color >>  0) & 0xFFFF) / static_cast<float>(65535);
+		result.y = static_cast<float>((color >> 16) & 0xFFFF) / static_cast<float>(65535);
+		result.z = static_cast<float>((color >> 32) & 0xFFFF) / static_cast<float>(65535);
+		result.w = static_cast<float>((color >> 48) & 0xFFFF) / static_cast<float>(65535);
+		return result;
+	}
+
+	template <>
+	GLM_FUNC_QUALIFIER detail::tvec4<float> f32_argb_cast<uint64>(uint64 color)
+	{
+		detail::tvec4<float> result;
+		result.x = static_cast<float>((color >> 16) & 0xFFFF) / static_cast<float>(65535);
+		result.y = static_cast<float>((color >> 32) & 0xFFFF) / static_cast<float>(65535);
+		result.z = static_cast<float>((color >> 48) & 0xFFFF) / static_cast<float>(65535);
+		result.w = static_cast<float>((color >>  0) & 0xFFFF) / static_cast<float>(65535);
+		return result;
+	}
+
+	template <>
+	GLM_FUNC_QUALIFIER detail::tvec4<float> f32_bgra_cast<uint64>(uint64 color)
+	{
+		detail::tvec4<float> result;
+		result.x = static_cast<float>((color >> 32) & 0xFFFF) / static_cast<float>(65535);
+		result.y = static_cast<float>((color >> 16) & 0xFFFF) / static_cast<float>(65535);
+		result.z = static_cast<float>((color >>  0) & 0xFFFF) / static_cast<float>(65535);
+		result.w = static_cast<float>((color >> 48) & 0xFFFF) / static_cast<float>(65535);
+		return result;
+	}
+
+	template <>
+	GLM_FUNC_QUALIFIER detail::tvec4<float> f32_abgr_cast<uint64>(uint64 color)
+	{
+		detail::tvec4<float> result;
+		result.x = static_cast<float>((color >> 48) & 0xFFFF) / static_cast<float>(65535);
+		result.y = static_cast<float>((color >> 32) & 0xFFFF) / static_cast<float>(65535);
+		result.z = static_cast<float>((color >> 16) & 0xFFFF) / static_cast<float>(65535);
+		result.w = static_cast<float>((color >>  0) & 0xFFFF) / static_cast<float>(65535);
+		return result;
+	}
+
+	template <>
+	GLM_FUNC_QUALIFIER double f64_channel_cast<uint16>(uint16 color)
+	{
+		return static_cast<double>(color >>  0) / static_cast<double>(65535);
+	}
+
+	template <>
+	GLM_FUNC_QUALIFIER detail::tvec3<double> f64_rgbx_cast<uint64>(uint64 color)
+	{
+		detail::tvec3<double> result;
+		result.x = static_cast<double>((color >>  0) & 0xFFFF) / static_cast<double>(65535);
+		result.y = static_cast<double>((color >> 16) & 0xFFFF) / static_cast<double>(65535);
+		result.z = static_cast<double>((color >> 32) & 0xFFFF) / static_cast<double>(65535);
+		return result;
+	}
+
+	template <>
+	GLM_FUNC_QUALIFIER detail::tvec3<double> f64_xrgb_cast<uint64>(uint64 color)
+	{
+		detail::tvec3<double> result;
+		result.x = static_cast<double>((color >> 16) & 0xFFFF) / static_cast<double>(65535);
+		result.y = static_cast<double>((color >> 32) & 0xFFFF) / static_cast<double>(65535);
+		result.z = static_cast<double>((color >> 48) & 0xFFFF) / static_cast<double>(65535);
+		return result;
+	}
+
+	template <>
+	GLM_FUNC_QUALIFIER detail::tvec3<double> f64_bgrx_cast<uint64>(uint64 color)
+	{
+		detail::tvec3<double> result;
+		result.x = static_cast<double>((color >> 32) & 0xFFFF) / static_cast<double>(65535);
+		result.y = static_cast<double>((color >> 16) & 0xFFFF) / static_cast<double>(65535);
+		result.z = static_cast<double>((color >>  0) & 0xFFFF) / static_cast<double>(65535);
+		return result;
+	}
+
+	template <>
+	GLM_FUNC_QUALIFIER detail::tvec3<double> f64_xbgr_cast<uint64>(uint64 color)
+	{
+		detail::tvec3<double> result;
+		result.x = static_cast<double>((color >> 48) & 0xFFFF) / static_cast<double>(65535);
+		result.y = static_cast<double>((color >> 32) & 0xFFFF) / static_cast<double>(65535);
+		result.z = static_cast<double>((color >> 16) & 0xFFFF) / static_cast<double>(65535);
+		return result;
+	}
+
+	template <>
+	GLM_FUNC_QUALIFIER detail::tvec4<double> f64_rgba_cast<uint64>(uint64 color)
+	{
+		detail::tvec4<double> result;
+		result.x = static_cast<double>((color >>  0) & 0xFFFF) / static_cast<double>(65535);
+		result.y = static_cast<double>((color >> 16) & 0xFFFF) / static_cast<double>(65535);
+		result.z = static_cast<double>((color >> 32) & 0xFFFF) / static_cast<double>(65535);
+		result.w = static_cast<double>((color >> 48) & 0xFFFF) / static_cast<double>(65535);
+		return result;
+	}
+
+	template <>
+	GLM_FUNC_QUALIFIER detail::tvec4<double> f64_argb_cast<uint64>(uint64 color)
+	{
+		detail::tvec4<double> result;
+		result.x = static_cast<double>((color >> 16) & 0xFFFF) / static_cast<double>(65535);
+		result.y = static_cast<double>((color >> 32) & 0xFFFF) / static_cast<double>(65535);
+		result.z = static_cast<double>((color >> 48) & 0xFFFF) / static_cast<double>(65535);
+		result.w = static_cast<double>((color >>  0) & 0xFFFF) / static_cast<double>(65535);
+		return result;
+	}
+
+	template <>
+	GLM_FUNC_QUALIFIER detail::tvec4<double> f64_bgra_cast<uint64>(uint64 color)
+	{
+		detail::tvec4<double> result;
+		result.x = static_cast<double>((color >> 32) & 0xFFFF) / static_cast<double>(65535);
+		result.y = static_cast<double>((color >> 16) & 0xFFFF) / static_cast<double>(65535);
+		result.z = static_cast<double>((color >>  0) & 0xFFFF) / static_cast<double>(65535);
+		result.w = static_cast<double>((color >> 48) & 0xFFFF) / static_cast<double>(65535);
+		return result;
+	}
+
+	template <>
+	GLM_FUNC_QUALIFIER detail::tvec4<double> f64_abgr_cast<uint64>(uint64 color)
+	{
+		detail::tvec4<double> result;
+		result.x = static_cast<double>((color >> 48) & 0xFFFF) / static_cast<double>(65535);
+		result.y = static_cast<double>((color >> 32) & 0xFFFF) / static_cast<double>(65535);
+		result.z = static_cast<double>((color >> 16) & 0xFFFF) / static_cast<double>(65535);
+		result.w = static_cast<double>((color >>  0) & 0xFFFF) / static_cast<double>(65535);
+		return result;
+	}
 }//namespace glm
 }//namespace glm

+ 124 - 125
glm/gtx/color_space.inl

@@ -7,144 +7,143 @@
 // File    : glm/gtx/color_space.inl
 // File    : glm/gtx/color_space.inl
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 
-namespace glm{
-
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tvec3<T> rgbColor(const detail::tvec3<T>& hsvColor)
+namespace glm
 {
 {
-	detail::tvec3<T> hsv = hsvColor;
-    detail::tvec3<T> rgbColor;
-
-	if(hsv.y == T(0))
-		// achromatic (grey)
-        rgbColor = detail::tvec3<T>(hsv.z);
-	else
+	template <typename T> 
+	GLM_FUNC_QUALIFIER detail::tvec3<T> rgbColor(const detail::tvec3<T>& hsvColor)
 	{
 	{
-        T sector = floor(hsv.x / T(60));
-		T frac = (hsv.x / T(60)) - sector;
-        // factorial part of h
-        T o = hsv.z * (T(1) - hsv.y);
-        T p = hsv.z * (T(1) - hsv.y * frac);
-        T q = hsv.z * (T(1) - hsv.y * (T(1) - frac));
+		detail::tvec3<T> hsv = hsvColor;
+		detail::tvec3<T> rgbColor;
 
 
-        switch(int(sector))
-        {
-        default:
-        case 0:
-            rgbColor.r = hsv.z;
-            rgbColor.g = q;
-            rgbColor.b = o;
-            break;
-        case 1:
-            rgbColor.r = p;
-            rgbColor.g = hsv.z;
-            rgbColor.b = o;
-            break;
-        case 2:
-            rgbColor.r = o;
-            rgbColor.g = hsv.z;
-            rgbColor.b = q;
-            break;
-        case 3:
-            rgbColor.r = o;
-            rgbColor.g = p;
-            rgbColor.b = hsv.z;
-            break;
-        case 4:
-            rgbColor.r = q; 
-            rgbColor.g = o; 
-            rgbColor.b = hsv.z;
-            break;
-		case 5:
-            rgbColor.r = hsv.z; 
-            rgbColor.g = o; 
-            rgbColor.b = p;
-            break;
-        }
+		if(hsv.y == T(0))
+			// achromatic (grey)
+			rgbColor = detail::tvec3<T>(hsv.z);
+		else
+		{
+			T sector = floor(hsv.x / T(60));
+			T frac = (hsv.x / T(60)) - sector;
+			// factorial part of h
+			T o = hsv.z * (T(1) - hsv.y);
+			T p = hsv.z * (T(1) - hsv.y * frac);
+			T q = hsv.z * (T(1) - hsv.y * (T(1) - frac));
+
+			switch(int(sector))
+			{
+			default:
+			case 0:
+				rgbColor.r = hsv.z;
+				rgbColor.g = q;
+				rgbColor.b = o;
+				break;
+			case 1:
+				rgbColor.r = p;
+				rgbColor.g = hsv.z;
+				rgbColor.b = o;
+				break;
+			case 2:
+				rgbColor.r = o;
+				rgbColor.g = hsv.z;
+				rgbColor.b = q;
+				break;
+			case 3:
+				rgbColor.r = o;
+				rgbColor.g = p;
+				rgbColor.b = hsv.z;
+				break;
+			case 4:
+				rgbColor.r = q; 
+				rgbColor.g = o; 
+				rgbColor.b = hsv.z;
+				break;
+			case 5:
+				rgbColor.r = hsv.z; 
+				rgbColor.g = o; 
+				rgbColor.b = p;
+				break;
+			}
+		}
+
+		return rgbColor;
 	}
 	}
 
 
-	return rgbColor;
-}
-
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tvec3<T> hsvColor(const detail::tvec3<T>& rgbColor)
-{
-    detail::tvec3<T> hsv = rgbColor;
-	float Min   = min(min(rgbColor.r, rgbColor.g), rgbColor.b);
-	float Max   = max(max(rgbColor.r, rgbColor.g), rgbColor.b);
-	float Delta = Max - Min;
-
-	hsv.z = Max;                               
-    	
-	if(Max != T(0))
+	template <typename T> 
+	GLM_FUNC_QUALIFIER detail::tvec3<T> hsvColor(const detail::tvec3<T>& rgbColor)
 	{
 	{
-		hsv.y = Delta / hsv.z;    
-		T h = T(0);
+		detail::tvec3<T> hsv = rgbColor;
+		float Min   = min(min(rgbColor.r, rgbColor.g), rgbColor.b);
+		float Max   = max(max(rgbColor.r, rgbColor.g), rgbColor.b);
+		float Delta = Max - Min;
 
 
-		if(rgbColor.r == Max)
-			// between yellow & magenta
-			h = T(0) + T(60) * (rgbColor.g - rgbColor.b) / Delta;
-		else if(rgbColor.g == Max)
-			// between cyan & yellow
-			h = T(120) + T(60) * (rgbColor.b - rgbColor.r) / Delta;
-		else
-			// between magenta & cyan
-			h = T(240) + T(60) * (rgbColor.r - rgbColor.g) / Delta;
+		hsv.z = Max;                               
+    	
+		if(Max != T(0))
+		{
+			hsv.y = Delta / hsv.z;    
+			T h = T(0);
+
+			if(rgbColor.r == Max)
+				// between yellow & magenta
+				h = T(0) + T(60) * (rgbColor.g - rgbColor.b) / Delta;
+			else if(rgbColor.g == Max)
+				// between cyan & yellow
+				h = T(120) + T(60) * (rgbColor.b - rgbColor.r) / Delta;
+			else
+				// between magenta & cyan
+				h = T(240) + T(60) * (rgbColor.r - rgbColor.g) / Delta;
             
             
-		if(h < T(0)) 
-            hsv.x = h + T(360);
+			if(h < T(0)) 
+				hsv.x = h + T(360);
+			else
+				hsv.x = h;
+		}
 		else
 		else
-			hsv.x = h;
+		{
+			// If r = g = b = 0 then s = 0, h is undefined
+			hsv.y = T(0);
+			hsv.x = T(0);
+		}
+
+		return hsv;
 	}
 	}
-	else
+
+	template <typename T> 
+	GLM_FUNC_QUALIFIER detail::tmat4x4<T> saturation(const T s)
 	{
 	{
-		// If r = g = b = 0 then s = 0, h is undefined
-		hsv.y = T(0);
-		hsv.x = T(0);
+		detail::tvec3<T> rgbw = detail::tvec3<T>(T(0.2126), T(0.7152), T(0.0722));
+
+		T col0 = (T(1) - s) * rgbw.r;
+		T col1 = (T(1) - s) * rgbw.g;
+		T col2 = (T(1) - s) * rgbw.b;
+
+		detail::tmat4x4<T> result(T(1));
+		result[0][0] = col0 + s;
+		result[0][1] = col0;
+		result[0][2] = col0;
+		result[1][0] = col1;
+		result[1][1] = col1 + s;
+		result[1][2] = col1;
+		result[2][0] = col2;
+		result[2][1] = col2;
+		result[2][2] = col2 + s;
+		return result;
 	}
 	}
 
 
-	return hsv;
-}
-
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tmat4x4<T> saturation(const T s)
-{
-	detail::tvec3<T> rgbw = detail::tvec3<T>(T(0.2126), T(0.7152), T(0.0722));
-
-	T col0 = (T(1) - s) * rgbw.r;
-	T col1 = (T(1) - s) * rgbw.g;
-	T col2 = (T(1) - s) * rgbw.b;
-
-	detail::tmat4x4<T> result(T(1));
-	result[0][0] = col0 + s;
-	result[0][1] = col0;
-	result[0][2] = col0;
-	result[1][0] = col1;
-	result[1][1] = col1 + s;
-	result[1][2] = col1;
-	result[2][0] = col2;
-	result[2][1] = col2;
-	result[2][2] = col2 + s;
-	return result;
-}
-
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tvec3<T> saturation(const T s, const detail::tvec3<T>& color)
-{
-	return detail::tvec3<T>(saturation(s) * detail::tvec4<T>(color, T(0)));
-}
-
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tvec4<T> saturation(const T s, const detail::tvec4<T>& color)
-{
-	return saturation(s) * color;
-}
+	template <typename T> 
+	GLM_FUNC_QUALIFIER detail::tvec3<T> saturation(const T s, const detail::tvec3<T>& color)
+	{
+		return detail::tvec3<T>(saturation(s) * detail::tvec4<T>(color, T(0)));
+	}
 
 
-template <typename T> 
-GLM_FUNC_QUALIFIER T luminosity(const detail::tvec3<T>& color)
-{
-	const detail::tvec3<T> tmp = detail::tvec3<T>(0.33, 0.59, 0.11);
-	return dot(color, tmp);
-}
+	template <typename T> 
+	GLM_FUNC_QUALIFIER detail::tvec4<T> saturation(const T s, const detail::tvec4<T>& color)
+	{
+		return saturation(s) * color;
+	}
 
 
+	template <typename T> 
+	GLM_FUNC_QUALIFIER T luminosity(const detail::tvec3<T>& color)
+	{
+		const detail::tvec3<T> tmp = detail::tvec3<T>(0.33, 0.59, 0.11);
+		return dot(color, tmp);
+	}
 }//namespace glm
 }//namespace glm

+ 50 - 51
glm/gtx/color_space_YCoCg.inl

@@ -7,59 +7,58 @@
 // File    : glm/gtx/color_space_YCoCg.inl
 // File    : glm/gtx/color_space_YCoCg.inl
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 
-namespace glm{
-
-template <typename valType> 
-GLM_FUNC_QUALIFIER detail::tvec3<valType> rgb2YCoCg
-(
-	detail::tvec3<valType> const & rgbColor
-)
+namespace glm
 {
 {
-	detail::tvec3<valType> result;
-	result.x/*Y */ =   rgbColor.r / valType(4) + rgbColor.g / valType(2) + rgbColor.b / valType(4);
-	result.y/*Co*/ =   rgbColor.r / valType(2) + rgbColor.g * valType(0) - rgbColor.b / valType(2);
-	result.z/*Cg*/ = - rgbColor.r / valType(4) + rgbColor.g / valType(2) - rgbColor.b / valType(4);
-	return result;
-}
+	template <typename valType> 
+	GLM_FUNC_QUALIFIER detail::tvec3<valType> rgb2YCoCg
+	(
+		detail::tvec3<valType> const & rgbColor
+	)
+	{
+		detail::tvec3<valType> result;
+		result.x/*Y */ =   rgbColor.r / valType(4) + rgbColor.g / valType(2) + rgbColor.b / valType(4);
+		result.y/*Co*/ =   rgbColor.r / valType(2) + rgbColor.g * valType(0) - rgbColor.b / valType(2);
+		result.z/*Cg*/ = - rgbColor.r / valType(4) + rgbColor.g / valType(2) - rgbColor.b / valType(4);
+		return result;
+	}
 
 
-template <typename valType> 
-GLM_FUNC_QUALIFIER detail::tvec3<valType> rgb2YCoCgR
-(
-	detail::tvec3<valType> const & rgbColor
-)
-{
-	detail::tvec3<valType> result;
-	result.x/*Y */ = rgbColor.g / valType(2) + (rgbColor.r + rgbColor.b) / valType(4);
-	result.y/*Co*/ = rgbColor.r - rgbColor.b;
-	result.z/*Cg*/ = rgbColor.g - (rgbColor.r + rgbColor.b) / valType(2);
-	return result;
-}
+	template <typename valType> 
+	GLM_FUNC_QUALIFIER detail::tvec3<valType> rgb2YCoCgR
+	(
+		detail::tvec3<valType> const & rgbColor
+	)
+	{
+		detail::tvec3<valType> result;
+		result.x/*Y */ = rgbColor.g / valType(2) + (rgbColor.r + rgbColor.b) / valType(4);
+		result.y/*Co*/ = rgbColor.r - rgbColor.b;
+		result.z/*Cg*/ = rgbColor.g - (rgbColor.r + rgbColor.b) / valType(2);
+		return result;
+	}
 
 
-template <typename valType> 
-GLM_FUNC_QUALIFIER detail::tvec3<valType> YCoCg2rgb
-(
-	detail::tvec3<valType> const & YCoCgColor
-)
-{
-	detail::tvec3<valType> result;
-	result.r = YCoCgColor.x + YCoCgColor.y - YCoCgColor.z;
-	result.g = YCoCgColor.x                + YCoCgColor.z;
-	result.b = YCoCgColor.x - YCoCgColor.y - YCoCgColor.z;
-	return result;
-}
-
-template <typename valType> 
-GLM_FUNC_QUALIFIER detail::tvec3<valType> YCoCgR2rgb
-(
-	detail::tvec3<valType> const & YCoCgRColor
-)
-{
-	detail::tvec3<valType> result;
-	valType tmp = YCoCgRColor.x - (YCoCgRColor.z / valType(2));
-	result.g = YCoCgRColor.z + tmp;
-	result.b = tmp - (YCoCgRColor.y / valType(2));
-	result.r = result.b + YCoCgRColor.y;
-	return result;
-}
+	template <typename valType> 
+	GLM_FUNC_QUALIFIER detail::tvec3<valType> YCoCg2rgb
+	(
+		detail::tvec3<valType> const & YCoCgColor
+	)
+	{
+		detail::tvec3<valType> result;
+		result.r = YCoCgColor.x + YCoCgColor.y - YCoCgColor.z;
+		result.g = YCoCgColor.x                + YCoCgColor.z;
+		result.b = YCoCgColor.x - YCoCgColor.y - YCoCgColor.z;
+		return result;
+	}
 
 
+	template <typename valType> 
+	GLM_FUNC_QUALIFIER detail::tvec3<valType> YCoCgR2rgb
+	(
+		detail::tvec3<valType> const & YCoCgRColor
+	)
+	{
+		detail::tvec3<valType> result;
+		valType tmp = YCoCgRColor.x - (YCoCgRColor.z / valType(2));
+		result.g = YCoCgRColor.z + tmp;
+		result.b = tmp - (YCoCgRColor.y / valType(2));
+		result.r = result.b + YCoCgRColor.y;
+		return result;
+	}
 }//namespace glm
 }//namespace glm

+ 114 - 115
glm/gtx/compatibility.inl

@@ -7,131 +7,130 @@
 // File    : glm/gtx/compatibility.inl
 // File    : glm/gtx/compatibility.inl
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 
-namespace glm{
-
-// isfinite
-template <typename genType> 
-GLM_FUNC_QUALIFIER bool isfinite(
-	genType const & x)
+namespace glm
 {
 {
-#if(GLM_COMPILER & GLM_COMPILER_VC)
-	return _finite(x);
-#else//(GLM_COMPILER & GLM_COMPILER_GCC)
-	return std::isfinite(x) != 0;
-#endif
-}
+	// isfinite
+	template <typename genType> 
+	GLM_FUNC_QUALIFIER bool isfinite(
+		genType const & x)
+	{
+	#if(GLM_COMPILER & GLM_COMPILER_VC)
+		return _finite(x);
+	#else//(GLM_COMPILER & GLM_COMPILER_GCC)
+		return std::isfinite(x) != 0;
+	#endif
+	}
 
 
-template <typename valType> 
-GLM_FUNC_QUALIFIER detail::tvec2<bool> isfinite(
-	detail::tvec2<valType> const & x)
-{
-	return detail::tvec2<bool>(
-		isfinite(x.x),
-		isfinite(x.y));
-}
+	template <typename valType> 
+	GLM_FUNC_QUALIFIER detail::tvec2<bool> isfinite(
+		detail::tvec2<valType> const & x)
+	{
+		return detail::tvec2<bool>(
+			isfinite(x.x),
+			isfinite(x.y));
+	}
 
 
-template <typename valType> 
-GLM_FUNC_QUALIFIER detail::tvec3<bool> isfinite(
-	detail::tvec3<valType> const & x)
-{
-	return detail::tvec3<bool>(
-		isfinite(x.x),
-		isfinite(x.y),
-		isfinite(x.z));
-}
+	template <typename valType> 
+	GLM_FUNC_QUALIFIER detail::tvec3<bool> isfinite(
+		detail::tvec3<valType> const & x)
+	{
+		return detail::tvec3<bool>(
+			isfinite(x.x),
+			isfinite(x.y),
+			isfinite(x.z));
+	}
 
 
-template <typename valType> 
-GLM_FUNC_QUALIFIER detail::tvec4<bool> isfinite(
-	detail::tvec4<valType> const & x)
-{
-	return detail::tvec4<bool>(
-		isfinite(x.x),
-		isfinite(x.y),
-		isfinite(x.z),
-		isfinite(x.w));
-}
+	template <typename valType> 
+	GLM_FUNC_QUALIFIER detail::tvec4<bool> isfinite(
+		detail::tvec4<valType> const & x)
+	{
+		return detail::tvec4<bool>(
+			isfinite(x.x),
+			isfinite(x.y),
+			isfinite(x.z),
+			isfinite(x.w));
+	}
 
 
-// isinf
-template <typename genType> 
-GLM_FUNC_QUALIFIER bool isinf(
-	genType const & x)
-{
-#if(GLM_COMPILER & GLM_COMPILER_VC)
-	return _fpclass(x) == _FPCLASS_NINF || _fpclass(x) == _FPCLASS_PINF;
-#else
-	return std::isinf(x) != 0;
-#endif
-}
+	// isinf
+	template <typename genType> 
+	GLM_FUNC_QUALIFIER bool isinf(
+		genType const & x)
+	{
+	#if(GLM_COMPILER & GLM_COMPILER_VC)
+		return _fpclass(x) == _FPCLASS_NINF || _fpclass(x) == _FPCLASS_PINF;
+	#else
+		return std::isinf(x) != 0;
+	#endif
+	}
 
 
-template <typename valType> 
-GLM_FUNC_QUALIFIER detail::tvec2<bool> isinf(
-	detail::tvec2<valType> const & x)
-{
-	return detail::tvec2<bool>(
-		isinf(x.x),
-		isinf(x.y));
-}
+	template <typename valType> 
+	GLM_FUNC_QUALIFIER detail::tvec2<bool> isinf(
+		detail::tvec2<valType> const & x)
+	{
+		return detail::tvec2<bool>(
+			isinf(x.x),
+			isinf(x.y));
+	}
 
 
-template <typename valType> 
-GLM_FUNC_QUALIFIER detail::tvec3<bool> isinf(
-	detail::tvec3<valType> const & x)
-{
-	return detail::tvec3<bool>(
-		isinf(x.x),
-		isinf(x.y),
-		isinf(x.z));
-}
+	template <typename valType> 
+	GLM_FUNC_QUALIFIER detail::tvec3<bool> isinf(
+		detail::tvec3<valType> const & x)
+	{
+		return detail::tvec3<bool>(
+			isinf(x.x),
+			isinf(x.y),
+			isinf(x.z));
+	}
 
 
-template <typename valType> 
-GLM_FUNC_QUALIFIER detail::tvec4<bool> isinf(
-	detail::tvec4<valType> const & x)
-{
-	return detail::tvec4<bool>(
-		isinf(x.x),
-		isinf(x.y),
-		isinf(x.z),
-		isinf(x.w));
-}
-
-// isnan
-template <typename genType> 
-GLM_FUNC_QUALIFIER bool isnan(genType const & x)
-{
-#if(GLM_COMPILER & GLM_COMPILER_VC)
-	return _isnan(x);
-#else
-	return std::isnan(x) != 0;
-#endif
-}
+	template <typename valType> 
+	GLM_FUNC_QUALIFIER detail::tvec4<bool> isinf(
+		detail::tvec4<valType> const & x)
+	{
+		return detail::tvec4<bool>(
+			isinf(x.x),
+			isinf(x.y),
+			isinf(x.z),
+			isinf(x.w));
+	}
 
 
-template <typename valType> 
-GLM_FUNC_QUALIFIER detail::tvec2<bool> isnan(
-	detail::tvec2<valType> const & x)
-{
-	return detail::tvec2<bool>(
-		isnan(x.x),
-		isnan(x.y));
-}
+	// isnan
+	template <typename genType> 
+	GLM_FUNC_QUALIFIER bool isnan(genType const & x)
+	{
+	#if(GLM_COMPILER & GLM_COMPILER_VC)
+		return _isnan(x);
+	#else
+		return std::isnan(x) != 0;
+	#endif
+	}
 
 
-template <typename valType> 
-GLM_FUNC_QUALIFIER detail::tvec3<bool> isnan(
-	detail::tvec3<valType> const & x)
-{
-	return detail::tvec3<bool>(
-		isnan(x.x),
-		isnan(x.y),
-		isnan(x.z));
-}
+	template <typename valType> 
+	GLM_FUNC_QUALIFIER detail::tvec2<bool> isnan(
+		detail::tvec2<valType> const & x)
+	{
+		return detail::tvec2<bool>(
+			isnan(x.x),
+			isnan(x.y));
+	}
 
 
-template <typename valType> 
-GLM_FUNC_QUALIFIER detail::tvec4<bool> isnan(
-	detail::tvec4<valType> const & x)
-{
-	return detail::tvec4<bool>(
-		isnan(x.x),
-		isnan(x.y),
-		isnan(x.z),
-		isnan(x.w));
-}
+	template <typename valType> 
+	GLM_FUNC_QUALIFIER detail::tvec3<bool> isnan(
+		detail::tvec3<valType> const & x)
+	{
+		return detail::tvec3<bool>(
+			isnan(x.x),
+			isnan(x.y),
+			isnan(x.z));
+	}
 
 
+	template <typename valType> 
+	GLM_FUNC_QUALIFIER detail::tvec4<bool> isnan(
+		detail::tvec4<valType> const & x)
+	{
+		return detail::tvec4<bool>(
+			isnan(x.x),
+			isnan(x.y),
+			isnan(x.z),
+			isnan(x.w));
+	}
 }//namespace glm
 }//namespace glm

+ 33 - 34
glm/gtx/component_wise.inl

@@ -7,42 +7,41 @@
 // File    : gtx_component_wise.inl
 // File    : gtx_component_wise.inl
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 
-namespace glm{
-
-template <typename genType>
-GLM_FUNC_QUALIFIER typename genType::value_type compAdd(genType const & v)
+namespace glm
 {
 {
-    typename genType::size_type result = typename genType::value_type(0);
-	for(typename genType::size_type i = 0; i < genType::value_size(); ++i)
-		result += v[i];
-	return result;
-}
+	template <typename genType>
+	GLM_FUNC_QUALIFIER typename genType::value_type compAdd(genType const & v)
+	{
+		typename genType::size_type result = typename genType::value_type(0);
+		for(typename genType::size_type i = 0; i < genType::value_size(); ++i)
+			result += v[i];
+		return result;
+	}
 
 
-template <typename genType>
-GLM_FUNC_QUALIFIER typename genType::value_type compMul(genType const & v)
-{
-    typename genType::value_type result = typename genType::value_type(1);
-	for(typename genType::size_type i = 0; i < genType::value_size(); ++i)
-		result *= v[i];
-	return result;
-}
+	template <typename genType>
+	GLM_FUNC_QUALIFIER typename genType::value_type compMul(genType const & v)
+	{
+		typename genType::value_type result = typename genType::value_type(1);
+		for(typename genType::size_type i = 0; i < genType::value_size(); ++i)
+			result *= v[i];
+		return result;
+	}
 
 
-template <typename genType>
-GLM_FUNC_QUALIFIER typename genType::value_type compMin(genType const & v)
-{
-    typename genType::value_type result = typename genType::value_type(v[0]);
-	for(typename genType::size_type i = 1; i < genType::value_size(); ++i)
-		result = min(result, v[i]);
-	return result;
-}
-
-template <typename genType>
-GLM_FUNC_QUALIFIER typename genType::value_type compMax(genType const & v)
-{
-    typename genType::value_type result = typename genType::value_type(v[0]);
-	for(typename genType::size_type i = 1; i < genType::value_size(); ++i)
-		result = max(result, v[i]);
-	return result;
-}
+	template <typename genType>
+	GLM_FUNC_QUALIFIER typename genType::value_type compMin(genType const & v)
+	{
+		typename genType::value_type result = typename genType::value_type(v[0]);
+		for(typename genType::size_type i = 1; i < genType::value_size(); ++i)
+			result = min(result, v[i]);
+		return result;
+	}
 
 
+	template <typename genType>
+	GLM_FUNC_QUALIFIER typename genType::value_type compMax(genType const & v)
+	{
+		typename genType::value_type result = typename genType::value_type(v[0]);
+		for(typename genType::size_type i = 1; i < genType::value_size(); ++i)
+			result = max(result, v[i]);
+		return result;
+	}
 }//namespace glm
 }//namespace glm

+ 3 - 768
glm/gtx/constants.inl

@@ -20,773 +20,8 @@
 /// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 /// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 /// THE SOFTWARE.
 /// THE SOFTWARE.
 ///
 ///
-/// @ref gtc_half_float
-/// @file glm/gtc/half_float.inl
-/// @date 2009-04-29 / 2011-06-05
+/// @ref gtx_constants
+/// @file glm/gtx/constants.inl
+/// @date 2011-10-14 / 2011-10-14
 /// @author Christophe Riccio
 /// @author Christophe Riccio
 ///////////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////////
-
-#include "../core/_detail.hpp"
-
-namespace glm{
-
-template <typename genIType>
-GLM_FUNC_QUALIFIER genIType mask
-(
-	genIType const & count
-)
-{
-	return ((genIType(1) << (count)) - genIType(1));
-}
-
-template <typename valIType>
-GLM_FUNC_QUALIFIER detail::tvec2<valIType> mask
-(
-	detail::tvec2<valIType> const & count
-)
-{
-	return detail::tvec2<valIType>(
-		mask(count[0]),
-		mask(count[1]));
-}
-
-template <typename valIType>
-GLM_FUNC_QUALIFIER detail::tvec3<valIType> mask
-(
-	detail::tvec3<valIType> const & count
-)
-{
-	return detail::tvec3<valIType>(
-		mask(count[0]),
-		mask(count[1]),
-		mask(count[2]));
-}
-
-template <typename valIType>
-GLM_FUNC_QUALIFIER detail::tvec4<valIType> mask
-(
-	detail::tvec4<valIType> const & count
-)
-{
-	return detail::tvec4<valIType>(
-		mask(count[0]),
-		mask(count[1]),
-		mask(count[2]),
-		mask(count[3]));
-}
-
-// extractField
-template <typename genIType>
-GLM_FUNC_QUALIFIER genIType extractField
-(
-	half const & value, 
-	genIType const & first, 
-	genIType const & count
-)
-{
-	assert(first + count < sizeof(half));
-	return (value._data() << first) >> ((sizeof(half) << 3) - count);
-}
-
-template <typename genIType>
-GLM_FUNC_QUALIFIER genIType extractField
-(
-	float const & value, 
-	genIType const & first, 
-	genIType const & count
-)
-{
-	assert(first + count < sizeof(float));
-	return (detail::uif32(value).i << first) >> ((sizeof(float) << 3) - count);
-}
-
-template <typename genIType>
-GLM_FUNC_QUALIFIER genIType extractField
-(
-	double const & value, 
-	genIType const & first, 
-	genIType const & count
-)
-{
-	assert(first + count < sizeof(double));
-	return (detail::uif64(value).i << first) >> ((sizeof(double) << genIType(3)) - count);
-}
-
-template <typename genIUType, typename sizeType>
-GLM_FUNC_QUALIFIER genIUType extractField
-(
-	genIUType const & Value, 
-	sizeType const & First, 
-	sizeType const & Count
-)
-{
-	sizeType GenSize = sizeof(genIUType) << 3;
-
-	assert(First + Count <= GenSize);
-
-	genIUType ShiftLeft = Count ? Value << (GenSize - (Count + First)) : 0;
-	genIUType ShiftBack = ShiftLeft >> genIUType(GenSize - Count);
-
-	return ShiftBack;
-}
-
-template <typename genIUType, typename sizeType>
-GLM_FUNC_QUALIFIER detail::tvec2<genIUType> extractField
-(
-	detail::tvec2<genIUType> const & value, 
-	sizeType const & first, 
-	sizeType const & count
-)
-{
-	return detail::tvec2<genIUType>(
-		extractField(value[0], first, count),
-		extractField(value[1], first, count));
-}
-
-template <typename genIUType, typename sizeType>
-GLM_FUNC_QUALIFIER detail::tvec3<genIUType> extractField
-(
-	detail::tvec3<genIUType> const & value, 
-	sizeType const & first, 
-	sizeType const & count
-)
-{
-	return detail::tvec3<genIUType>(
-		extractField(value[0], first, count),
-		extractField(value[1], first, count),
-		extractField(value[2], first, count));
-}
-
-template <typename genIUType, typename sizeType>
-GLM_FUNC_QUALIFIER detail::tvec4<genIUType> extractField
-(
-	detail::tvec4<genIUType> const & value, 
-	sizeType const & first, 
-	sizeType const & count
-)
-{
-	return detail::tvec4<genIUType>(
-		extractField(value[0], first, count),
-		extractField(value[1], first, count),
-		extractField(value[2], first, count),
-		extractField(value[3], first, count));
-}
-
-template <typename genIUType, typename sizeType>
-GLM_FUNC_QUALIFIER detail::tvec2<genIUType> extractField
-(
-	detail::tvec2<genIUType> const & value, 
-	detail::tvec2<sizeType> const & first, 
-	detail::tvec2<sizeType> const & count
-)
-{
-	return detail::tvec2<genIUType>(
-		extractField(value[0], first[0], count[0]),
-		extractField(value[1], first[1], count[1]));
-}
-
-template <typename genIUType, typename sizeType>
-GLM_FUNC_QUALIFIER detail::tvec3<genIUType> extractField
-(
-	detail::tvec3<genIUType> const & value, 
-	detail::tvec3<sizeType> const & first, 
-	detail::tvec3<sizeType> const & count
-)
-{
-	return detail::tvec3<genIUType>(
-		extractField(value[0], first[0], count[0]),
-		extractField(value[1], first[1], count[1]),
-		extractField(value[2], first[2], count[2]));
-}
-
-template <typename genIUType, typename sizeType>
-GLM_FUNC_QUALIFIER detail::tvec4<genIUType> extractField
-(
-	detail::tvec4<genIUType> const & value, 
-	detail::tvec4<sizeType> const & first, 
-	detail::tvec4<sizeType> const & count
-)
-{
-	return detail::tvec4<genIUType>(
-		extractField(value[0], first[0], count[0]),
-		extractField(value[1], first[1], count[1]),
-		extractField(value[2], first[2], count[2]),
-		extractField(value[3], first[3], count[3]));
-}
-
-template <typename genIUType, typename sizeType>
-GLM_FUNC_QUALIFIER detail::tvec2<genIUType> extractField
-(
-	genIUType const & value, 
-	detail::tvec2<sizeType> const & first, 
-	detail::tvec2<sizeType> const & count
-)
-{
-	return detail::tvec2<genIUType>(
-		extractField(value, first[0], count[0]),
-		extractField(value, first[1], count[1]));
-}
-
-template <typename genIUType, typename sizeType>
-GLM_FUNC_QUALIFIER detail::tvec3<genIUType> extractField
-(
-	genIUType const & value, 
-	detail::tvec3<sizeType> const & first, 
-	detail::tvec3<sizeType> const & count
-)
-{
-	return detail::tvec3<genIUType>(
-		extractField(value, first[0], count[0]),
-		extractField(value, first[1], count[1]),
-		extractField(value, first[2], count[2]));
-}
-
-template <typename genIUType, typename sizeType>
-GLM_FUNC_QUALIFIER detail::tvec4<genIUType> extractField
-(
-	genIUType const & value, 
-	detail::tvec4<sizeType> const & first, 
-	detail::tvec4<sizeType> const & count
-)
-{
-	return detail::tvec4<genIUType>(
-		extractField(value, first[0], count[0]),
-		extractField(value, first[1], count[1]),
-		extractField(value, first[2], count[2]),
-		extractField(value, first[3], count[3]));
-}
-
-// lowestBit
-template <typename genType>
-GLM_FUNC_QUALIFIER int lowestBit
-(
-	genType const & Value
-)
-{
-	assert(Value != genType(0)); // not valid call
-
-	genType Bit;
-	for(Bit = genType(0); !(Value & (1 << Bit)); ++Bit){}
-	return Bit;
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec2<int> lowestBit
-(
-	detail::tvec2<valType> const & value
-)
-{
-	return detail::tvec2<int>(
-		lowestBit(value[0]),
-		lowestBit(value[1]));
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec3<int> lowestBit
-(
-	detail::tvec3<valType> const & value
-)
-{
-	return detail::tvec3<int>(
-		lowestBit(value[0]),
-		lowestBit(value[1]),
-		lowestBit(value[2]));
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec4<int> lowestBit
-(
-	detail::tvec4<valType> const & value
-)
-{
-	return detail::tvec4<int>(
-		lowestBit(value[0]),
-		lowestBit(value[1]),
-		lowestBit(value[2]),
-		lowestBit(value[3]));
-}
-
-// highestBit
-template <typename genType>
-GLM_FUNC_QUALIFIER int highestBit
-(
-	genType const & value
-)
-{
-	assert(value != genType(0)); // not valid call
-
-	genType bit = genType(-1);
-	for(genType tmp = value; tmp; tmp >>= 1, ++bit){}
-	return bit;
-}
-
-//template <>
-//GLM_FUNC_QUALIFIER int highestBit<int>
-//(
-//	int value
-//)
-//{
-//	int bit = -1;
-//	for(int tmp = value; tmp; tmp >>= 1, ++bit);
-//	return bit;
-//}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec2<int> highestBit
-(
-	detail::tvec2<valType> const & value
-)
-{
-	return detail::tvec2<int>(
-		highestBit(value[0]),
-		highestBit(value[1]));
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec3<int> highestBit
-(
-	detail::tvec3<valType> const & value
-)
-{
-	return detail::tvec3<int>(
-		highestBit(value[0]),
-		highestBit(value[1]),
-		highestBit(value[2]));
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec4<int> highestBit
-(
-	detail::tvec4<valType> const & value
-)
-{
-	return detail::tvec4<int>(
-		highestBit(value[0]),
-		highestBit(value[1]),
-		highestBit(value[2]),
-		highestBit(value[3]));
-}
-
-// highestBitValue
-template <typename genType>
-GLM_FUNC_QUALIFIER genType highestBitValue
-(
-	genType const & value
-)
-{
-	genType tmp = value;
-	genType result = genType(0);
-	while(tmp)
-	{
-		result = (tmp & (~tmp + 1)); // grab lowest bit
-		tmp &= ~result; // clear lowest bit
-	}
-	return result;
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec2<int> highestBitValue
-(
-	detail::tvec2<valType> const & value
-)
-{
-	return detail::tvec2<int>(
-		highestBitValue(value[0]),
-		highestBitValue(value[1]));
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec3<int> highestBitValue
-(
-	detail::tvec3<valType> const & value
-)
-{
-	return detail::tvec3<int>(
-		highestBitValue(value[0]),
-		highestBitValue(value[1]),
-		highestBitValue(value[2]));
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec4<int> highestBitValue
-(
-	detail::tvec4<valType> const & value
-)
-{
-	return detail::tvec4<int>(
-		highestBitValue(value[0]),
-		highestBitValue(value[1]),
-		highestBitValue(value[2]),
-		highestBitValue(value[3]));
-}
-
-// isPowerOfTwo
-template <typename genType>
-GLM_FUNC_QUALIFIER bool isPowerOfTwo(genType const & Value)
-{
-	//detail::If<std::numeric_limits<genType>::is_signed>::apply(abs, Value);
-	//return !(Value & (Value - 1));
-
-    // For old complier?
-	genType Result = Value;
-	if(std::numeric_limits<genType>::is_signed)
-		Result = abs(Result);
-	return !(Result & (Result - 1));
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec2<bool> isPowerOfTwo
-(
-	detail::tvec2<valType> const & value
-)
-{
-	return detail::tvec2<bool>(
-		isPowerOfTwo(value[0]),
-		isPowerOfTwo(value[1]));
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec3<bool> isPowerOfTwo
-(
-	detail::tvec3<valType> const & value
-)
-{
-	return detail::tvec3<bool>(
-		isPowerOfTwo(value[0]),
-		isPowerOfTwo(value[1]),
-		isPowerOfTwo(value[2]));
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec4<bool> isPowerOfTwo
-(
-	detail::tvec4<valType> const & value
-)
-{
-	return detail::tvec4<bool>(
-		isPowerOfTwo(value[0]),
-		isPowerOfTwo(value[1]),
-		isPowerOfTwo(value[2]),
-		isPowerOfTwo(value[3]));
-}
-
-// powerOfTwoAbove
-template <typename genType>
-GLM_FUNC_QUALIFIER genType powerOfTwoAbove(genType const & value)
-{
-	return isPowerOfTwo(value) ? value : highestBitValue(value) << 1;
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec2<valType> powerOfTwoAbove
-(
-	detail::tvec2<valType> const & value
-)
-{
-	return detail::tvec2<valType>(
-		powerOfTwoAbove(value[0]),
-		powerOfTwoAbove(value[1]));
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec3<valType> powerOfTwoAbove
-(
-	detail::tvec3<valType> const & value
-)
-{
-	return detail::tvec3<valType>(
-		powerOfTwoAbove(value[0]),
-		powerOfTwoAbove(value[1]),
-		powerOfTwoAbove(value[2]));
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec4<valType> powerOfTwoAbove
-(
-	detail::tvec4<valType> const & value
-)
-{
-	return detail::tvec4<valType>(
-		powerOfTwoAbove(value[0]),
-		powerOfTwoAbove(value[1]),
-		powerOfTwoAbove(value[2]),
-		powerOfTwoAbove(value[3]));
-}
-
-// powerOfTwoBelow
-template <typename genType>
-GLM_FUNC_QUALIFIER genType powerOfTwoBelow
-(
-	genType const & value
-)
-{
-	return isPowerOfTwo(value) ? value : highestBitValue(value);
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec2<valType> powerOfTwoBelow
-(
-	detail::tvec2<valType> const & value
-)
-{
-	return detail::tvec2<valType>(
-		powerOfTwoBelow(value[0]),
-		powerOfTwoBelow(value[1]));
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec3<valType> powerOfTwoBelow
-(
-	detail::tvec3<valType> const & value
-)
-{
-	return detail::tvec3<valType>(
-		powerOfTwoBelow(value[0]),
-		powerOfTwoBelow(value[1]),
-		powerOfTwoBelow(value[2]));
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec4<valType> powerOfTwoBelow
-(
-	detail::tvec4<valType> const & value
-)
-{
-	return detail::tvec4<valType>(
-		powerOfTwoBelow(value[0]),
-		powerOfTwoBelow(value[1]),
-		powerOfTwoBelow(value[2]),
-		powerOfTwoBelow(value[3]));
-}
-
-// powerOfTwoNearest
-template <typename genType>
-GLM_FUNC_QUALIFIER genType powerOfTwoNearest
-(
-	genType const & value
-)
-{
-	if(isPowerOfTwo(value))
-		return value;
-
-	genType prev = highestBitValue(value);
-	genType next = prev << 1;
-	return (next - value) < (value - prev) ? next : prev;
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec2<valType> powerOfTwoNearest
-(
-	detail::tvec2<valType> const & value
-)
-{
-	return detail::tvec2<valType>(
-		powerOfTwoNearest(value[0]),
-		powerOfTwoNearest(value[1]));
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec3<valType> powerOfTwoNearest
-(
-	detail::tvec3<valType> const & value
-)
-{
-	return detail::tvec3<valType>(
-		powerOfTwoNearest(value[0]),
-		powerOfTwoNearest(value[1]),
-		powerOfTwoNearest(value[2]));
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec4<valType> powerOfTwoNearest
-(
-	detail::tvec4<valType> const & value
-)
-{
-	return detail::tvec4<valType>(
-		powerOfTwoNearest(value[0]),
-		powerOfTwoNearest(value[1]),
-		powerOfTwoNearest(value[2]),
-		powerOfTwoNearest(value[3]));
-}
-
-template <typename genType>
-GLM_FUNC_QUALIFIER genType bitRevert(genType const & In)
-{
-	GLM_STATIC_ASSERT(std::numeric_limits<genType>::is_integer, "'bitRevert' only accept integer values");
-
-	genType Out = 0;
-	std::size_t BitSize = sizeof(genType) * 8;
-	for(std::size_t i = 0; i < BitSize; ++i)
-		if(In & (genType(1) << i))
-			Out |= genType(1) << (BitSize - 1 - i);
-	return Out;
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec2<valType> bitRevert
-(
-	detail::tvec2<valType> const & Value
-)
-{
-	return detail::tvec2<valType>(
-		bitRevert(Value[0]),
-		bitRevert(Value[1]));
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec3<valType> bitRevert
-(
-	detail::tvec3<valType> const & Value
-)
-{
-	return detail::tvec3<valType>(
-		bitRevert(Value[0]),
-		bitRevert(Value[1]),
-		bitRevert(Value[2]));
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec4<valType> bitRevert
-(
-	detail::tvec4<valType> const & Value
-)
-{
-	return detail::tvec4<valType>(
-		bitRevert(Value[0]),
-		bitRevert(Value[1]),
-		bitRevert(Value[2]),
-		bitRevert(Value[3]));
-}
-
-template <typename genType>
-GLM_FUNC_QUALIFIER genType bitRotateRight(genType const & In, std::size_t Shift)
-{
-	GLM_STATIC_ASSERT(std::numeric_limits<genType>::is_integer, "'bitRotateRight' only accept integer values");
-
-	std::size_t BitSize = sizeof(genType) * 8;
-	return (In << Shift) | (In >> (BitSize - Shift));
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec2<valType> bitRotateRight
-(
-	detail::tvec2<valType> const & Value, 
-	std::size_t Shift
-)
-{
-	return detail::tvec2<valType>(
-		bitRotateRight(Value[0], Shift),
-		bitRotateRight(Value[1], Shift));
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec3<valType> bitRotateRight
-(
-	detail::tvec3<valType> const & Value, 
-	std::size_t Shift
-)
-{
-	return detail::tvec3<valType>(
-		bitRotateRight(Value[0], Shift),
-		bitRotateRight(Value[1], Shift),
-		bitRotateRight(Value[2], Shift));
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec4<valType> bitRotateRight
-(
-	detail::tvec4<valType> const & Value, 
-	std::size_t Shift
-)
-{
-	return detail::tvec4<valType>(
-		bitRotateRight(Value[0], Shift),
-		bitRotateRight(Value[1], Shift),
-		bitRotateRight(Value[2], Shift),
-		bitRotateRight(Value[3], Shift));
-}
-
-template <typename genType>
-GLM_FUNC_QUALIFIER genType bitRotateLeft(genType const & In, std::size_t Shift)
-{
-	GLM_STATIC_ASSERT(std::numeric_limits<genType>::is_integer, "'bitRotateLeft' only accept integer values");
-
-	std::size_t BitSize = sizeof(genType) * 8;
-	return (In >> Shift) | (In << (BitSize - Shift));
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec2<valType> bitRotateLeft
-(
-	detail::tvec2<valType> const & Value, 
-	std::size_t Shift
-)
-{
-	return detail::tvec2<valType>(
-		bitRotateLeft(Value[0], Shift),
-		bitRotateLeft(Value[1], Shift));
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec3<valType> bitRotateLeft
-(
-	detail::tvec3<valType> const & Value, 
-	std::size_t Shift
-)
-{
-	return detail::tvec3<valType>(
-		bitRotateLeft(Value[0], Shift),
-		bitRotateLeft(Value[1], Shift),
-		bitRotateLeft(Value[2], Shift));
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec4<valType> bitRotateLeft
-(
-	detail::tvec4<valType> const & Value, 
-	std::size_t Shift
-)
-{
-	return detail::tvec4<valType>(
-		bitRotateLeft(Value[0], Shift),
-		bitRotateLeft(Value[1], Shift),
-		bitRotateLeft(Value[2], Shift),
-		bitRotateLeft(Value[3], Shift));
-}
-
-template <typename genIUType>
-GLM_FUNC_QUALIFIER genIUType fillBitfieldWithOne
-(
-	genIUType const & Value,
-	int const & FromBit, 
-	int const & ToBit
-)
-{
-	assert(FromBit <= ToBit);
-	assert(ToBit <= sizeof(genIUType) * std::size_t(8));
-
-	genIUType Result = Value;
-	for(std::size_t i = 0; i <= ToBit; ++i)
-		Result |= (1 << i);
-	return Result;
-}
-
-template <typename genIUType>
-GLM_FUNC_QUALIFIER genIUType fillBitfieldWithZero
-(
-	genIUType const & Value,
-	int const & FromBit, 
-	int const & ToBit
-)
-{
-	assert(FromBit <= ToBit);
-	assert(ToBit <= sizeof(genIUType) * std::size_t(8));
-
-	genIUType Result = Value;
-	for(std::size_t i = 0; i <= ToBit; ++i)
-		Result &= ~(1 << i);
-	return Result;
-}
-
-}//namespace glm

+ 219 - 220
glm/gtx/epsilon.inl

@@ -7,224 +7,223 @@
 // File    : glm/gtx/epsilon.inl
 // File    : glm/gtx/epsilon.inl
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 
-namespace glm{
-
-template <typename genType>
-GLM_FUNC_QUALIFIER bool equalEpsilon
-(
-	genType const & x, 
-	genType const & y, 
-	genType const & epsilon
-)
-{
-    return abs(x - y) < epsilon;
-}
-
-template <typename genType>
-GLM_FUNC_QUALIFIER bool notEqualEpsilon
-(
-	genType const & x, 
-	genType const & y, 
-	genType const & epsilon
-)
-{
-    return abs(x - y) >= epsilon;
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec2<bool> equalEpsilon
-(
-	detail::tvec2<valType> const & x, 
-	detail::tvec2<valType> const & y, 
-	valType const & epsilon)
-{
-    return detail::tvec2<bool>(
-        abs(x.x - y.x) < epsilon,
-        abs(x.y - y.y) < epsilon);
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec3<bool> equalEpsilon
-(
-	detail::tvec3<valType> const & x, 
-	detail::tvec3<valType> const & y, 
-	valType const & epsilon)
-{
-    return detail::tvec3<bool>(
-        abs(x.x - y.x) < epsilon,
-        abs(x.y - y.y) < epsilon,
-        abs(x.z - y.z) < epsilon);
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec4<bool> equalEpsilon
-(
-	detail::tvec4<valType> const & x, 
-	detail::tvec4<valType> const & y, 
-	valType const & epsilon
-)
-{
-    return detail::tvec4<bool>(
-        abs(x.x - y.x) < epsilon,
-        abs(x.y - y.y) < epsilon,
-        abs(x.z - y.z) < epsilon,
-        abs(x.w - y.w) < epsilon);
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec2<bool> notEqualEpsilon
-(
-	detail::tvec2<valType> const & x, 
-	detail::tvec2<valType> const & y, 
-	valType const & epsilon
-)
-{
-    return detail::tvec2<bool>(
-        abs(x.x - y.x) >= epsilon,
-        abs(x.y - y.y) >= epsilon);
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec3<bool> notEqualEpsilon
-(
-	detail::tvec3<valType> const & x, 
-	detail::tvec3<valType> const & y, 
-	valType const & epsilon
-)
-{
-    return detail::tvec3<bool>(
-        abs(x.x - y.x) >= epsilon,
-        abs(x.y - y.y) >= epsilon,
-        abs(x.z - y.z) >= epsilon);
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec4<bool> notEqualEpsilon
-(
-	detail::tvec4<valType> const & x, 
-	detail::tvec4<valType> const & y, 
-	valType const & epsilon
-)
-{
-    return detail::tvec4<bool>(
-        abs(x.x - y.x) >= epsilon,
-        abs(x.y - y.y) >= epsilon,
-        abs(x.z - y.z) >= epsilon,
-        abs(x.w - y.w) >= epsilon);
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec2<bool> equalEpsilon
-(
-	detail::tvec2<valType> const & x, 
-	detail::tvec2<valType> const & y, 
-	detail::tvec2<valType> const & epsilon
-)
-{
-    return detail::tvec2<bool>(
-        abs(x.x - y.x) < epsilon.x,
-        abs(x.y - y.y) < epsilon.y);
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec3<bool> equalEpsilon
-(
-	detail::tvec3<valType> const & x, 
-	detail::tvec3<valType> const & y, 
-	detail::tvec3<valType> const & epsilon
-)
-{
-    return detail::tvec3<bool>(
-        abs(x.x - y.x) < epsilon.x,
-        abs(x.y - y.y) < epsilon.y,
-        abs(x.z - y.z) < epsilon.z);
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec4<bool> equalEpsilon
-(
-	detail::tvec4<valType> const & x, 
-	detail::tvec4<valType> const & y, 
-	detail::tvec4<valType> const & epsilon
-)
-{
-    return detail::tvec4<bool>(
-        abs(x.x - y.x) < epsilon.x,
-        abs(x.y - y.y) < epsilon.y,
-        abs(x.z - y.z) < epsilon.z,
-        abs(x.w - y.w) < epsilon.w);
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec4<bool> equalEpsilon
-(
-	detail::tquat<valType> const & x, 
-	detail::tquat<valType> const & y, 
-	detail::tquat<valType> const & epsilon
-)
-{
-    return detail::tvec4<bool>(
-        abs(x.x - y.x) < epsilon.x,
-        abs(x.y - y.y) < epsilon.y,
-        abs(x.z - y.z) < epsilon.z,
-        abs(x.w - y.w) < epsilon.w);
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec2<bool> notEqualEpsilon
-(
-	detail::tvec2<valType> const & x, 
-	detail::tvec2<valType> const & y, 
-	detail::tvec2<valType> const & epsilon
-)
-{
-    return detail::tvec2<bool>(
-        abs(x.x - y.x) >= epsilon.x,
-        abs(x.y - y.y) >= epsilon.y);
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec3<bool> notEqualEpsilon
-(
-	detail::tvec3<valType> const & x, 
-	detail::tvec3<valType> const & y, 
-	detail::tvec3<valType> const & epsilon
-)
-{
-    return detail::tvec3<bool>(
-        abs(x.x - y.x) >= epsilon.x,
-        abs(x.y - y.y) >= epsilon.y,
-        abs(x.z - y.z) >= epsilon.z);
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec4<bool> notEqualEpsilon
-(
-	detail::tvec4<valType> const & x, 
-	detail::tvec4<valType> const & y, 
-	detail::tvec4<valType> const & epsilon
-)
-{
-    return detail::tvec4<bool>(
-        abs(x.x - y.x) >= epsilon.x,
-        abs(x.y - y.y) >= epsilon.y,
-        abs(x.z - y.z) >= epsilon.z,
-        abs(x.w - y.w) >= epsilon.w);
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec4<bool> notEqualEpsilon
-(
-	detail::tquat<valType> const & x, 
-	detail::tquat<valType> const & y, 
-	detail::tquat<valType> const & epsilon
-)
-{
-    return detail::tvec4<bool>(
-        abs(x.x - y.x) >= epsilon.x,
-        abs(x.y - y.y) >= epsilon.y,
-        abs(x.z - y.z) >= epsilon.z,
-        abs(x.w - y.w) >= epsilon.w);
-}
-
+namespace glm
+{
+	template <typename genType>
+	GLM_FUNC_QUALIFIER bool equalEpsilon
+	(
+		genType const & x, 
+		genType const & y, 
+		genType const & epsilon
+	)
+	{
+		return abs(x - y) < epsilon;
+	}
+
+	template <typename genType>
+	GLM_FUNC_QUALIFIER bool notEqualEpsilon
+	(
+		genType const & x, 
+		genType const & y, 
+		genType const & epsilon
+	)
+	{
+		return abs(x - y) >= epsilon;
+	}
+
+	template <typename valType>
+	GLM_FUNC_QUALIFIER detail::tvec2<bool> equalEpsilon
+	(
+		detail::tvec2<valType> const & x, 
+		detail::tvec2<valType> const & y, 
+		valType const & epsilon)
+	{
+		return detail::tvec2<bool>(
+			abs(x.x - y.x) < epsilon,
+			abs(x.y - y.y) < epsilon);
+	}
+
+	template <typename valType>
+	GLM_FUNC_QUALIFIER detail::tvec3<bool> equalEpsilon
+	(
+		detail::tvec3<valType> const & x, 
+		detail::tvec3<valType> const & y, 
+		valType const & epsilon)
+	{
+		return detail::tvec3<bool>(
+			abs(x.x - y.x) < epsilon,
+			abs(x.y - y.y) < epsilon,
+			abs(x.z - y.z) < epsilon);
+	}
+
+	template <typename valType>
+	GLM_FUNC_QUALIFIER detail::tvec4<bool> equalEpsilon
+	(
+		detail::tvec4<valType> const & x, 
+		detail::tvec4<valType> const & y, 
+		valType const & epsilon
+	)
+	{
+		return detail::tvec4<bool>(
+			abs(x.x - y.x) < epsilon,
+			abs(x.y - y.y) < epsilon,
+			abs(x.z - y.z) < epsilon,
+			abs(x.w - y.w) < epsilon);
+	}
+
+	template <typename valType>
+	GLM_FUNC_QUALIFIER detail::tvec2<bool> notEqualEpsilon
+	(
+		detail::tvec2<valType> const & x, 
+		detail::tvec2<valType> const & y, 
+		valType const & epsilon
+	)
+	{
+		return detail::tvec2<bool>(
+			abs(x.x - y.x) >= epsilon,
+			abs(x.y - y.y) >= epsilon);
+	}
+
+	template <typename valType>
+	GLM_FUNC_QUALIFIER detail::tvec3<bool> notEqualEpsilon
+	(
+		detail::tvec3<valType> const & x, 
+		detail::tvec3<valType> const & y, 
+		valType const & epsilon
+	)
+	{
+		return detail::tvec3<bool>(
+			abs(x.x - y.x) >= epsilon,
+			abs(x.y - y.y) >= epsilon,
+			abs(x.z - y.z) >= epsilon);
+	}
+
+	template <typename valType>
+	GLM_FUNC_QUALIFIER detail::tvec4<bool> notEqualEpsilon
+	(
+		detail::tvec4<valType> const & x, 
+		detail::tvec4<valType> const & y, 
+		valType const & epsilon
+	)
+	{
+		return detail::tvec4<bool>(
+			abs(x.x - y.x) >= epsilon,
+			abs(x.y - y.y) >= epsilon,
+			abs(x.z - y.z) >= epsilon,
+			abs(x.w - y.w) >= epsilon);
+	}
+
+	template <typename valType>
+	GLM_FUNC_QUALIFIER detail::tvec2<bool> equalEpsilon
+	(
+		detail::tvec2<valType> const & x, 
+		detail::tvec2<valType> const & y, 
+		detail::tvec2<valType> const & epsilon
+	)
+	{
+		return detail::tvec2<bool>(
+			abs(x.x - y.x) < epsilon.x,
+			abs(x.y - y.y) < epsilon.y);
+	}
+
+	template <typename valType>
+	GLM_FUNC_QUALIFIER detail::tvec3<bool> equalEpsilon
+	(
+		detail::tvec3<valType> const & x, 
+		detail::tvec3<valType> const & y, 
+		detail::tvec3<valType> const & epsilon
+	)
+	{
+		return detail::tvec3<bool>(
+			abs(x.x - y.x) < epsilon.x,
+			abs(x.y - y.y) < epsilon.y,
+			abs(x.z - y.z) < epsilon.z);
+	}
+
+	template <typename valType>
+	GLM_FUNC_QUALIFIER detail::tvec4<bool> equalEpsilon
+	(
+		detail::tvec4<valType> const & x, 
+		detail::tvec4<valType> const & y, 
+		detail::tvec4<valType> const & epsilon
+	)
+	{
+		return detail::tvec4<bool>(
+			abs(x.x - y.x) < epsilon.x,
+			abs(x.y - y.y) < epsilon.y,
+			abs(x.z - y.z) < epsilon.z,
+			abs(x.w - y.w) < epsilon.w);
+	}
+
+	template <typename valType>
+	GLM_FUNC_QUALIFIER detail::tvec4<bool> equalEpsilon
+	(
+		detail::tquat<valType> const & x, 
+		detail::tquat<valType> const & y, 
+		detail::tquat<valType> const & epsilon
+	)
+	{
+		return detail::tvec4<bool>(
+			abs(x.x - y.x) < epsilon.x,
+			abs(x.y - y.y) < epsilon.y,
+			abs(x.z - y.z) < epsilon.z,
+			abs(x.w - y.w) < epsilon.w);
+	}
+
+	template <typename valType>
+	GLM_FUNC_QUALIFIER detail::tvec2<bool> notEqualEpsilon
+	(
+		detail::tvec2<valType> const & x, 
+		detail::tvec2<valType> const & y, 
+		detail::tvec2<valType> const & epsilon
+	)
+	{
+		return detail::tvec2<bool>(
+			abs(x.x - y.x) >= epsilon.x,
+			abs(x.y - y.y) >= epsilon.y);
+	}
+
+	template <typename valType>
+	GLM_FUNC_QUALIFIER detail::tvec3<bool> notEqualEpsilon
+	(
+		detail::tvec3<valType> const & x, 
+		detail::tvec3<valType> const & y, 
+		detail::tvec3<valType> const & epsilon
+	)
+	{
+		return detail::tvec3<bool>(
+			abs(x.x - y.x) >= epsilon.x,
+			abs(x.y - y.y) >= epsilon.y,
+			abs(x.z - y.z) >= epsilon.z);
+	}
+
+	template <typename valType>
+	GLM_FUNC_QUALIFIER detail::tvec4<bool> notEqualEpsilon
+	(
+		detail::tvec4<valType> const & x, 
+		detail::tvec4<valType> const & y, 
+		detail::tvec4<valType> const & epsilon
+	)
+	{
+		return detail::tvec4<bool>(
+			abs(x.x - y.x) >= epsilon.x,
+			abs(x.y - y.y) >= epsilon.y,
+			abs(x.z - y.z) >= epsilon.z,
+			abs(x.w - y.w) >= epsilon.w);
+	}
+
+	template <typename valType>
+	GLM_FUNC_QUALIFIER detail::tvec4<bool> notEqualEpsilon
+	(
+		detail::tquat<valType> const & x, 
+		detail::tquat<valType> const & y, 
+		detail::tquat<valType> const & epsilon
+	)
+	{
+		return detail::tvec4<bool>(
+			abs(x.x - y.x) >= epsilon.x,
+			abs(x.y - y.y) >= epsilon.y,
+			abs(x.z - y.z) >= epsilon.z,
+			abs(x.w - y.w) >= epsilon.w);
+	}
 }//namespace glm
 }//namespace glm

+ 232 - 233
glm/gtx/euler_angles.inl

@@ -7,239 +7,238 @@
 // File    : glm/gtx/euler_angles.inl
 // File    : glm/gtx/euler_angles.inl
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 
-namespace glm{
-
-template <typename valType> 
-GLM_FUNC_QUALIFIER detail::tmat4x4<valType> eulerAngleX
-(
-	valType const & angleX
-)
+namespace glm
 {
 {
-	valType cosX = glm::cos(angleX);
-	valType sinX = glm::sin(angleX);
+	template <typename valType> 
+	GLM_FUNC_QUALIFIER detail::tmat4x4<valType> eulerAngleX
+	(
+		valType const & angleX
+	)
+	{
+		valType cosX = glm::cos(angleX);
+		valType sinX = glm::sin(angleX);
 	
 	
-	return detail::tmat4x4<valType>(
-		valType(1), valType(0), valType(0), valType(0),
-		valType(0), cosX,		sinX,		valType(0),
-		valType(0),-sinX,		cosX,		valType(0),
-		valType(0), valType(0), valType(0), valType(1));
-}
-
-template <typename valType> 
-GLM_FUNC_QUALIFIER detail::tmat4x4<valType> eulerAngleY
-(
-	valType const & angleY
-)
-{
-	valType cosY = glm::cos(angleY);
-	valType sinY = glm::sin(angleY);
-
-	return detail::tmat4x4<valType>(
-		cosY,		valType(0),	sinY,		valType(0),
-		valType(0),	valType(1),	valType(0), valType(0),
-		-sinY,		valType(0),	cosY,		valType(0),
-		valType(0),	valType(0),	valType(0), valType(1));
-}
-
-template <typename valType> 
-GLM_FUNC_QUALIFIER detail::tmat4x4<valType> eulerAngleZ
-(
-	valType const & angleZ
-)
-{
-	valType cosZ = glm::cos(angleZ); 
-	valType sinZ = glm::sin(angleZ);
-
-	return detail::tmat4x4<valType>(
-		cosZ,		sinZ,		valType(0), valType(0),
-		-sinZ,		cosZ,		valType(0), valType(0),
-		valType(0),	valType(0),	valType(1), valType(0),
-		valType(0),	valType(0),	valType(0), valType(1));
-}
-
-template <typename valType> 
-GLM_FUNC_QUALIFIER detail::tmat4x4<valType> eulerAngleXY
-(
-	valType const & angleX, 
-	valType const & angleY
-)
-{
-	valType cosX = glm::cos(angleX);
-	valType sinX = glm::sin(angleX);
-	valType cosY = glm::cos(angleY);
-	valType sinY = glm::sin(angleY);
-
-	return detail::tmat4x4<valType>(
-		cosY,		-sinX * sinY,	cosX * sinY,	valType(0),
-		valType(0), cosX,			sinX,			valType(0),
-		-sinY ,		-sinX * cosY,	cosX * cosY,	valType(0),
-		valType(0), valType(0),     valType(0),		valType(1));
-}
-
-template <typename valType> 
-GLM_FUNC_QUALIFIER detail::tmat4x4<valType> eulerAngleYX
-(
-	valType const & angleY, 
-	valType const & angleX
-)
-{
-	valType cosX = glm::cos(angleX); 
-	valType sinX = glm::sin(angleX); 
-	valType cosY = glm::cos(angleY); 
-	valType sinY = glm::sin(angleY);
-
-	return detail::tmat4x4<valType>(
-		cosY,			valType(0),		sinY,			valType(0),
-		-sinX * sinY,	cosX,			sinX * cosY,	valType(0),
-		-cosX * sinY,	-sinX,			cosX * cosY,	valType(0),
-		valType(0),		valType(0),		valType(0),		valType(1));
-}
-
-template <typename valType> 
-GLM_FUNC_QUALIFIER detail::tmat4x4<valType> eulerAngleXZ
-(
-	valType const & angleX, 
-	valType const & angleZ
-)
-{
-	return eulerAngleX(angleX) * eulerAngleZ(angleZ);
-}
-
-template <typename valType> 
-GLM_FUNC_QUALIFIER detail::tmat4x4<valType> eulerAngleZX
-(
-	valType const & angleZ, 
-	valType const & angleX
-)
-{
-	return eulerAngleZ(angleZ) * eulerAngleX(angleX);
-}
-
-template <typename valType> 
-GLM_FUNC_QUALIFIER detail::tmat4x4<valType> eulerAngleYXZ
-(
-	valType const & yaw, 
-	valType const & pitch, 
-	valType const & roll
-)
-{
-    valType tmp_ch = glm::cos(yaw);
-    valType tmp_sh = glm::sin(yaw);
-    valType tmp_cp = glm::cos(pitch);
-    valType tmp_sp = glm::sin(pitch);
-    valType tmp_cb = glm::cos(roll);
-    valType tmp_sb = glm::sin(roll);
-
-    detail::tmat4x4<valType> Result;
-    Result[0][0] = tmp_ch * tmp_cb + tmp_sh * tmp_sp * tmp_sb;
-    Result[0][1] = tmp_sb * tmp_cp;
-    Result[0][2] = -tmp_sh * tmp_cb + tmp_ch * tmp_sp * tmp_sb;
-    Result[0][3] = valType(0);
-    Result[1][0] = -tmp_ch * tmp_sb + tmp_sh * tmp_sp * tmp_cb;
-    Result[1][1] = tmp_cb * tmp_cp;
-    Result[1][2] = tmp_sb * tmp_sh + tmp_ch * tmp_sp * tmp_cb;
-    Result[1][3] = valType(0);
-    Result[2][0] = tmp_sh * tmp_cp;
-    Result[2][1] = -tmp_sp;
-    Result[2][2] = tmp_ch * tmp_cp;
-    Result[2][3] = valType(0);
-    Result[3][0] = valType(0);
-    Result[3][1] = valType(0);
-    Result[3][2] = valType(0);
-    Result[3][3] = valType(1);
-    return Result;
-}
-
-template <typename valType> 
-GLM_FUNC_QUALIFIER detail::tmat4x4<valType> yawPitchRoll
-(
-	valType const & yaw, 
-	valType const & pitch, 
-	valType const & roll
-)
-{
-    valType tmp_ch = glm::cos(yaw);
-    valType tmp_sh = glm::sin(yaw);
-    valType tmp_cp = glm::cos(pitch);
-    valType tmp_sp = glm::sin(pitch);
-    valType tmp_cb = glm::cos(roll);
-    valType tmp_sb = glm::sin(roll);
-
-    detail::tmat4x4<valType> Result;
-    Result[0][0] = tmp_ch * tmp_cb + tmp_sh * tmp_sp * tmp_sb;
-    Result[0][1] = tmp_sb * tmp_cp;
-    Result[0][2] = -tmp_sh * tmp_cb + tmp_ch * tmp_sp * tmp_sb;
-    Result[0][3] = valType(0);
-    Result[1][0] = -tmp_ch * tmp_sb + tmp_sh * tmp_sp * tmp_cb;
-    Result[1][1] = tmp_cb * tmp_cp;
-    Result[1][2] = tmp_sb * tmp_sh + tmp_ch * tmp_sp * tmp_cb;
-    Result[1][3] = valType(0);
-    Result[2][0] = tmp_sh * tmp_cp;
-    Result[2][1] = -tmp_sp;
-    Result[2][2] = tmp_ch * tmp_cp;
-    Result[2][3] = valType(0);
-    Result[3][0] = valType(0);
-    Result[3][1] = valType(0);
-    Result[3][2] = valType(0);
-    Result[3][3] = valType(1);
-    return Result;
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tmat2x2<valType> orientate2
-(
-	valType const & angle
-)
-{
-    valType c = glm::cos(angle);
-    valType s = glm::sin(angle);
-
-	detail::tmat2x2<valType> Result;
-    Result[0][0] = c;
-    Result[0][1] = s;
-    Result[1][0] = -s;
-    Result[1][1] = c;
-	return Result;
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tmat3x3<valType> orientate3
-(
-	valType const & angle
-)
-{
-    valType c = glm::cos(angle);
-    valType s = glm::sin(angle);
-
-	detail::tmat3x3<valType> Result;
-    Result[0][0] = c;
-    Result[0][1] = s;
-	Result[0][2] = 0.0f;
-    Result[1][0] = -s;
-    Result[1][1] = c;
-	Result[1][2] = 0.0f;
-	Result[2][0] = 0.0f;
-	Result[2][1] = 0.0f;
-	Result[2][2] = 1.0f;
-	return Result;
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tmat3x3<valType> orientate3
-(
-	detail::tvec3<valType> const & angles
-)
-{
-	return detail::tmat3x3<valType>(yawPitchRoll(angles.x, angles.y, angles.z));
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tmat4x4<valType> orientate4
-(
-	detail::tvec3<valType> const & angles
-)
-{
-    return yawPitchRoll(angles.z, angles.x, angles.y);
-}
-
+		return detail::tmat4x4<valType>(
+			valType(1), valType(0), valType(0), valType(0),
+			valType(0), cosX,		sinX,		valType(0),
+			valType(0),-sinX,		cosX,		valType(0),
+			valType(0), valType(0), valType(0), valType(1));
+	}
+
+	template <typename valType> 
+	GLM_FUNC_QUALIFIER detail::tmat4x4<valType> eulerAngleY
+	(
+		valType const & angleY
+	)
+	{
+		valType cosY = glm::cos(angleY);
+		valType sinY = glm::sin(angleY);
+
+		return detail::tmat4x4<valType>(
+			cosY,		valType(0),	sinY,		valType(0),
+			valType(0),	valType(1),	valType(0), valType(0),
+			-sinY,		valType(0),	cosY,		valType(0),
+			valType(0),	valType(0),	valType(0), valType(1));
+	}
+
+	template <typename valType> 
+	GLM_FUNC_QUALIFIER detail::tmat4x4<valType> eulerAngleZ
+	(
+		valType const & angleZ
+	)
+	{
+		valType cosZ = glm::cos(angleZ); 
+		valType sinZ = glm::sin(angleZ);
+
+		return detail::tmat4x4<valType>(
+			cosZ,		sinZ,		valType(0), valType(0),
+			-sinZ,		cosZ,		valType(0), valType(0),
+			valType(0),	valType(0),	valType(1), valType(0),
+			valType(0),	valType(0),	valType(0), valType(1));
+	}
+
+	template <typename valType> 
+	GLM_FUNC_QUALIFIER detail::tmat4x4<valType> eulerAngleXY
+	(
+		valType const & angleX, 
+		valType const & angleY
+	)
+	{
+		valType cosX = glm::cos(angleX);
+		valType sinX = glm::sin(angleX);
+		valType cosY = glm::cos(angleY);
+		valType sinY = glm::sin(angleY);
+
+		return detail::tmat4x4<valType>(
+			cosY,		-sinX * sinY,	cosX * sinY,	valType(0),
+			valType(0), cosX,			sinX,			valType(0),
+			-sinY ,		-sinX * cosY,	cosX * cosY,	valType(0),
+			valType(0), valType(0),     valType(0),		valType(1));
+	}
+
+	template <typename valType> 
+	GLM_FUNC_QUALIFIER detail::tmat4x4<valType> eulerAngleYX
+	(
+		valType const & angleY, 
+		valType const & angleX
+	)
+	{
+		valType cosX = glm::cos(angleX); 
+		valType sinX = glm::sin(angleX); 
+		valType cosY = glm::cos(angleY); 
+		valType sinY = glm::sin(angleY);
+
+		return detail::tmat4x4<valType>(
+			cosY,			valType(0),		sinY,			valType(0),
+			-sinX * sinY,	cosX,			sinX * cosY,	valType(0),
+			-cosX * sinY,	-sinX,			cosX * cosY,	valType(0),
+			valType(0),		valType(0),		valType(0),		valType(1));
+	}
+
+	template <typename valType> 
+	GLM_FUNC_QUALIFIER detail::tmat4x4<valType> eulerAngleXZ
+	(
+		valType const & angleX, 
+		valType const & angleZ
+	)
+	{
+		return eulerAngleX(angleX) * eulerAngleZ(angleZ);
+	}
+
+	template <typename valType> 
+	GLM_FUNC_QUALIFIER detail::tmat4x4<valType> eulerAngleZX
+	(
+		valType const & angleZ, 
+		valType const & angleX
+	)
+	{
+		return eulerAngleZ(angleZ) * eulerAngleX(angleX);
+	}
+
+	template <typename valType> 
+	GLM_FUNC_QUALIFIER detail::tmat4x4<valType> eulerAngleYXZ
+	(
+		valType const & yaw, 
+		valType const & pitch, 
+		valType const & roll
+	)
+	{
+		valType tmp_ch = glm::cos(yaw);
+		valType tmp_sh = glm::sin(yaw);
+		valType tmp_cp = glm::cos(pitch);
+		valType tmp_sp = glm::sin(pitch);
+		valType tmp_cb = glm::cos(roll);
+		valType tmp_sb = glm::sin(roll);
+
+		detail::tmat4x4<valType> Result;
+		Result[0][0] = tmp_ch * tmp_cb + tmp_sh * tmp_sp * tmp_sb;
+		Result[0][1] = tmp_sb * tmp_cp;
+		Result[0][2] = -tmp_sh * tmp_cb + tmp_ch * tmp_sp * tmp_sb;
+		Result[0][3] = valType(0);
+		Result[1][0] = -tmp_ch * tmp_sb + tmp_sh * tmp_sp * tmp_cb;
+		Result[1][1] = tmp_cb * tmp_cp;
+		Result[1][2] = tmp_sb * tmp_sh + tmp_ch * tmp_sp * tmp_cb;
+		Result[1][3] = valType(0);
+		Result[2][0] = tmp_sh * tmp_cp;
+		Result[2][1] = -tmp_sp;
+		Result[2][2] = tmp_ch * tmp_cp;
+		Result[2][3] = valType(0);
+		Result[3][0] = valType(0);
+		Result[3][1] = valType(0);
+		Result[3][2] = valType(0);
+		Result[3][3] = valType(1);
+		return Result;
+	}
+
+	template <typename valType> 
+	GLM_FUNC_QUALIFIER detail::tmat4x4<valType> yawPitchRoll
+	(
+		valType const & yaw, 
+		valType const & pitch, 
+		valType const & roll
+	)
+	{
+		valType tmp_ch = glm::cos(yaw);
+		valType tmp_sh = glm::sin(yaw);
+		valType tmp_cp = glm::cos(pitch);
+		valType tmp_sp = glm::sin(pitch);
+		valType tmp_cb = glm::cos(roll);
+		valType tmp_sb = glm::sin(roll);
+
+		detail::tmat4x4<valType> Result;
+		Result[0][0] = tmp_ch * tmp_cb + tmp_sh * tmp_sp * tmp_sb;
+		Result[0][1] = tmp_sb * tmp_cp;
+		Result[0][2] = -tmp_sh * tmp_cb + tmp_ch * tmp_sp * tmp_sb;
+		Result[0][3] = valType(0);
+		Result[1][0] = -tmp_ch * tmp_sb + tmp_sh * tmp_sp * tmp_cb;
+		Result[1][1] = tmp_cb * tmp_cp;
+		Result[1][2] = tmp_sb * tmp_sh + tmp_ch * tmp_sp * tmp_cb;
+		Result[1][3] = valType(0);
+		Result[2][0] = tmp_sh * tmp_cp;
+		Result[2][1] = -tmp_sp;
+		Result[2][2] = tmp_ch * tmp_cp;
+		Result[2][3] = valType(0);
+		Result[3][0] = valType(0);
+		Result[3][1] = valType(0);
+		Result[3][2] = valType(0);
+		Result[3][3] = valType(1);
+		return Result;
+	}
+
+	template <typename valType>
+	GLM_FUNC_QUALIFIER detail::tmat2x2<valType> orientate2
+	(
+		valType const & angle
+	)
+	{
+		valType c = glm::cos(angle);
+		valType s = glm::sin(angle);
+
+		detail::tmat2x2<valType> Result;
+		Result[0][0] = c;
+		Result[0][1] = s;
+		Result[1][0] = -s;
+		Result[1][1] = c;
+		return Result;
+	}
+
+	template <typename valType>
+	GLM_FUNC_QUALIFIER detail::tmat3x3<valType> orientate3
+	(
+		valType const & angle
+	)
+	{
+		valType c = glm::cos(angle);
+		valType s = glm::sin(angle);
+
+		detail::tmat3x3<valType> Result;
+		Result[0][0] = c;
+		Result[0][1] = s;
+		Result[0][2] = 0.0f;
+		Result[1][0] = -s;
+		Result[1][1] = c;
+		Result[1][2] = 0.0f;
+		Result[2][0] = 0.0f;
+		Result[2][1] = 0.0f;
+		Result[2][2] = 1.0f;
+		return Result;
+	}
+
+	template <typename valType>
+	GLM_FUNC_QUALIFIER detail::tmat3x3<valType> orientate3
+	(
+		detail::tvec3<valType> const & angles
+	)
+	{
+		return detail::tmat3x3<valType>(yawPitchRoll(angles.x, angles.y, angles.z));
+	}
+
+	template <typename valType>
+	GLM_FUNC_QUALIFIER detail::tmat4x4<valType> orientate4
+	(
+		detail::tvec3<valType> const & angles
+	)
+	{
+		return yawPitchRoll(angles.z, angles.x, angles.y);
+	}
 }//namespace glm
 }//namespace glm

+ 41 - 42
glm/gtx/extend.inl

@@ -7,50 +7,49 @@
 // File    : glm/gtx/extend.inl
 // File    : glm/gtx/extend.inl
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 
-namespace glm{
-
-template <typename genType>
-genType extend
-(
-	genType const & Origin, 
-	genType const & Source, 
-	genType const & Distance
-)
+namespace glm
 {
 {
-    return Origin + (Source - Origin) * Distance;
-}
+	template <typename genType>
+	genType extend
+	(
+		genType const & Origin, 
+		genType const & Source, 
+		genType const & Distance
+	)
+	{
+		return Origin + (Source - Origin) * Distance;
+	}
 
 
-template <typename valType>
-detail::tvec2<valType> extend
-(
-	detail::tvec2<valType> const & Origin, 
-	detail::tvec2<valType> const & Source, 
-	valType const & Distance
-)
-{
-    return Origin + (Source - Origin) * Distance;
-}
+	template <typename valType>
+	detail::tvec2<valType> extend
+	(
+		detail::tvec2<valType> const & Origin, 
+		detail::tvec2<valType> const & Source, 
+		valType const & Distance
+	)
+	{
+		return Origin + (Source - Origin) * Distance;
+	}
 
 
-template <typename valType>
-detail::tvec3<valType> extend
-(
-	detail::tvec3<valType> const & Origin, 
-	detail::tvec3<valType> const & Source, 
-	valType const & Distance
-)
-{
-    return Origin + (Source - Origin) * Distance;
-}
-
-template <typename valType>
-detail::tvec4<valType> extend
-(
-	detail::tvec4<valType> const & Origin, 
-	detail::tvec4<valType> const & Source, 
-	valType const & Distance
-)
-{
-    return Origin + (Source - Origin) * Distance;
-}
+	template <typename valType>
+	detail::tvec3<valType> extend
+	(
+		detail::tvec3<valType> const & Origin, 
+		detail::tvec3<valType> const & Source, 
+		valType const & Distance
+	)
+	{
+		return Origin + (Source - Origin) * Distance;
+	}
 
 
+	template <typename valType>
+	detail::tvec4<valType> extend
+	(
+		detail::tvec4<valType> const & Origin, 
+		detail::tvec4<valType> const & Source, 
+		valType const & Distance
+	)
+	{
+		return Origin + (Source - Origin) * Distance;
+	}
 }//namespace glm
 }//namespace glm

+ 8 - 8
glm/gtx/fast_exponential.hpp

@@ -54,17 +54,17 @@ namespace glm
 
 
 	//! Faster than the common pow function but less accurate.
 	//! Faster than the common pow function but less accurate.
 	//! From GLM_GTX_fast_exponential extension.
 	//! From GLM_GTX_fast_exponential extension.
-	template <typename valType> 
-	valType fastPow(
-		valType const & x, 
-		valType const & y);
+	template <typename genType> 
+	genType fastPow(
+		genType const & x, 
+		genType const & y);
 
 
 	//! Faster than the common pow function but less accurate.
 	//! Faster than the common pow function but less accurate.
 	//! From GLM_GTX_fast_exponential extension.
 	//! From GLM_GTX_fast_exponential extension.
-	template <typename T, typename U> 
-	T fastPow(
-		const T& x, 
-		const U& y);
+	template <typename genTypeT, typename genTypeU> 
+	genTypeT fastPow(
+		genTypeT const & x, 
+		genTypeU const & y);
 		
 		
 	//! Faster than the common exp function but less accurate.
 	//! Faster than the common exp function but less accurate.
 	//! From GLM_GTX_fast_exponential extension.
 	//! From GLM_GTX_fast_exponential extension.

+ 139 - 279
glm/gtx/fast_exponential.inl

@@ -7,284 +7,144 @@
 // File    : glm/gtx/fast_exponential.inl
 // File    : glm/gtx/fast_exponential.inl
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 
-namespace glm{
-
-// fastPow:
-template <typename T>
-GLM_FUNC_QUALIFIER T fastPow(const T x, const T y)
-{
-    return exp(y * log(x));
-}
-
-template <typename T>
-GLM_FUNC_QUALIFIER detail::tvec2<T> fastPow(
-	const detail::tvec2<T>& x, 
-	const detail::tvec2<T>& y)
-{
-    return detail::tvec2<T>(
-        fastPow(x.x, y.x),
-        fastPow(x.y, y.y));
-}
-
-template <typename T>
-GLM_FUNC_QUALIFIER detail::tvec3<T> fastPow(
-	const detail::tvec3<T>& x, 
-	const detail::tvec3<T>& y)
-{
-    return detail::tvec3<T>(
-        fastPow(x.x, y.x),
-        fastPow(x.y, y.y),
-        fastPow(x.z, y.z));
-}
-
-template <typename T>
-GLM_FUNC_QUALIFIER detail::tvec4<T> fastPow(
-	const detail::tvec4<T>& x, 
-	const detail::tvec4<T>& y)
-{
-    return detail::tvec4<T>(
-        fastPow(x.x, y.x),
-        fastPow(x.y, y.y),
-        fastPow(x.z, y.z),
-        fastPow(x.w, y.w));
-}
-
-template <typename T>
-GLM_FUNC_QUALIFIER T fastPow(const T x, int y)
-{
-    T f = T(1);
-    for(int i = 0; i < y; ++i)
-        f *= x;
-    return f;
-}
-
-template <typename T>
-GLM_FUNC_QUALIFIER detail::tvec2<T> fastPow(
-	const detail::tvec2<T>& x, 
-	const detail::tvec2<int>& y)
-{
-    return detail::tvec2<T>(
-        fastPow(x.x, y.x),
-        fastPow(x.y, y.y));
-}
-
-template <typename T>
-GLM_FUNC_QUALIFIER detail::tvec3<T> fastPow(
-	const detail::tvec3<T>& x, 
-	const detail::tvec3<int>& y)
-{
-    return detail::tvec3<T>(
-        fastPow(x.x, y.x),
-        fastPow(x.y, y.y),
-        fastPow(x.z, y.z));
-}
-
-template <typename T>
-GLM_FUNC_QUALIFIER detail::tvec4<T> fastPow(
-	const detail::tvec4<T>& x, 
-	const detail::tvec4<int>& y)
-{
-    return detail::tvec4<T>(
-        fastPow(x.x, y.x),
-        fastPow(x.y, y.y),
-        fastPow(x.z, y.z),
-        fastPow(x.w, y.w));
-}
-
-// fastExp
-// Note: This function provides accurate results only for value between -1 and 1, else avoid it.
-template <typename T>
-GLM_FUNC_QUALIFIER T fastExp(const T x)
-{
-    // This has a better looking and same performance in release mode than the following code. However, in debug mode it's slower.
-    // return 1.0f + x * (1.0f + x * 0.5f * (1.0f + x * 0.3333333333f * (1.0f + x * 0.25 * (1.0f + x * 0.2f))));
-    T x2 = x * x;
-    T x3 = x2 * x;
-    T x4 = x3 * x;
-    T x5 = x4 * x;
-    return T(1) + x + (x2 * T(0.5)) + (x3 * T(0.1666666667)) + (x4 * T(0.041666667)) + (x5 * T(0.008333333333));
-}
-/*  // Try to handle all values of float... but often shower than std::exp, glm::floor and the loop kill the performance
-GLM_FUNC_QUALIFIER float fastExp(float x)
-{
-    const float e = 2.718281828f;
-    const float IntegerPart = floor(x);
-    const float FloatPart = x - IntegerPart;
-    float z = 1.f;
-
-    for(int i = 0; i < int(IntegerPart); ++i)
-        z *= e;
-
-    const float x2 = FloatPart * FloatPart;
-    const float x3 = x2 * FloatPart;
-    const float x4 = x3 * FloatPart;
-    const float x5 = x4 * FloatPart;
-    return z * (1.0f + FloatPart + (x2 * 0.5f) + (x3 * 0.1666666667f) + (x4 * 0.041666667f) + (x5 * 0.008333333333f));
-}
-
-// Increase accuracy on number bigger that 1 and smaller than -1 but it's not enough for high and negative numbers
-GLM_FUNC_QUALIFIER float fastExp(float x)
-{
-    // This has a better looking and same performance in release mode than the following code. However, in debug mode it's slower.
-    // return 1.0f + x * (1.0f + x * 0.5f * (1.0f + x * 0.3333333333f * (1.0f + x * 0.25 * (1.0f + x * 0.2f))));
-    float x2 = x * x;
-    float x3 = x2 * x;
-    float x4 = x3 * x;
-    float x5 = x4 * x;
-    float x6 = x5 * x;
-    float x7 = x6 * x;
-    float x8 = x7 * x;
-    return 1.0f + x + (x2 * 0.5f) + (x3 * 0.1666666667f) + (x4 * 0.041666667f) + (x5 * 0.008333333333f)+ (x6 * 0.00138888888888f) + (x7 * 0.000198412698f) + (x8 * 0.0000248015873f);;
-}
-*/
-template <typename T>
-GLM_FUNC_QUALIFIER detail::tvec2<T> fastExp(
-	const detail::tvec2<T>& x)
-{
-    return detail::tvec2<T>(
-        fastExp(x.x),
-        fastExp(x.y));
-}
-
-template <typename T>
-GLM_FUNC_QUALIFIER detail::tvec3<T> fastExp(
-	const detail::tvec3<T>& x)
-{
-    return detail::tvec3<T>(
-        fastExp(x.x),
-        fastExp(x.y),
-        fastExp(x.z));
-}
-
-template <typename T>
-GLM_FUNC_QUALIFIER detail::tvec4<T> fastExp(
-	const detail::tvec4<T>& x)
-{
-    return detail::tvec4<T>(
-        fastExp(x.x),
-        fastExp(x.y),
-        fastExp(x.z),
-        fastExp(x.w));
-}
-
-// fastLog
-template <typename T>
-GLM_FUNC_QUALIFIER T fastLog(const T x)
-{
-    return std::log(x);
-}
-
-/* Slower than the VC7.1 function...
-GLM_FUNC_QUALIFIER float fastLog(float x)
-{
-    float y1 = (x - 1.0f) / (x + 1.0f);
-    float y2 = y1 * y1;
-    return 2.0f * y1 * (1.0f + y2 * (0.3333333333f + y2 * (0.2f + y2 * 0.1428571429f)));
-}
-*/
-
-template <typename T>
-GLM_FUNC_QUALIFIER detail::tvec2<T> fastLog(
-	const detail::tvec2<T>& x)
-{
-    return detail::tvec2<T>(
-        fastLog(x.x),
-        fastLog(x.y));
-}
-
-template <typename T>
-GLM_FUNC_QUALIFIER detail::tvec3<T> fastLog(
-	const detail::tvec3<T>& x)
-{
-    return detail::tvec3<T>(
-        fastLog(x.x),
-        fastLog(x.y),
-        fastLog(x.z));
-}
-
-template <typename T>
-GLM_FUNC_QUALIFIER detail::tvec4<T> fastLog(
-	const detail::tvec4<T>& x)
-{
-    return detail::tvec4<T>(
-        fastLog(x.x),
-        fastLog(x.y),
-        fastLog(x.z),
-        fastLog(x.w));
-}
-
-//fastExp2, ln2 = 0.69314718055994530941723212145818f
-template <typename T>
-GLM_FUNC_QUALIFIER T fastExp2(const T x)
-{
-    return fastExp(0.69314718055994530941723212145818f * x);
-}
-
-template <typename T>
-GLM_FUNC_QUALIFIER detail::tvec2<T> fastExp2(
-	const detail::tvec2<T>& x)
-{
-    return detail::tvec2<T>(
-        fastExp2(x.x),
-        fastExp2(x.y));
-}
-
-template <typename T>
-GLM_FUNC_QUALIFIER detail::tvec3<T> fastExp2(
-	const detail::tvec3<T>& x)
-{
-    return detail::tvec3<T>(
-        fastExp2(x.x),
-        fastExp2(x.y),
-        fastExp2(x.z));
-}
-
-template <typename T>
-GLM_FUNC_QUALIFIER detail::tvec4<T> fastExp2(
-	const detail::tvec4<T>& x)
-{
-    return detail::tvec4<T>(
-        fastExp2(x.x),
-        fastExp2(x.y),
-        fastExp2(x.z),
-        fastExp2(x.w));
-}
-
-// fastLog2, ln2 = 0.69314718055994530941723212145818f
-template <typename T>
-GLM_FUNC_QUALIFIER T fastLog2(const T x)
-{
-    return fastLog(x) / 0.69314718055994530941723212145818f;
-}
-
-template <typename T>
-GLM_FUNC_QUALIFIER detail::tvec2<T> fastLog2(
-	const detail::tvec2<T>& x)
-{
-    return detail::tvec2<T>(
-        fastLog2(x.x),
-        fastLog2(x.y));
-}
-
-template <typename T>
-GLM_FUNC_QUALIFIER detail::tvec3<T> fastLog2(
-	const detail::tvec3<T>& x)
-{
-    return detail::tvec3<T>(
-        fastLog2(x.x),
-        fastLog2(x.y),
-        fastLog2(x.z));
-}
-
-template <typename T>
-GLM_FUNC_QUALIFIER detail::tvec4<T> fastLog2(
-	const detail::tvec4<T>& x)
-{
-    return detail::tvec4<T>(
-        fastLog2(x.x),
-        fastLog2(x.y),
-        fastLog2(x.z),
-        fastLog2(x.w));
-}
+#include "../core/_vectorize.hpp"
+
+namespace glm
+{
+	// fastPow:
+	template <typename genType>
+	GLM_FUNC_QUALIFIER genType fastPow(genType const & x, genType const & y)
+	{
+		return exp(y * log(x));
+	}
+
+	VECTORIZE_VEC_VEC(fastPow)
+
+	template <typename T>
+	GLM_FUNC_QUALIFIER T fastPow(const T x, int y)
+	{
+		T f = T(1);
+		for(int i = 0; i < y; ++i)
+			f *= x;
+		return f;
+	}
+
+	template <typename T>
+	GLM_FUNC_QUALIFIER detail::tvec2<T> fastPow(
+		const detail::tvec2<T>& x, 
+		const detail::tvec2<int>& y)
+	{
+		return detail::tvec2<T>(
+			fastPow(x.x, y.x),
+			fastPow(x.y, y.y));
+	}
+
+	template <typename T>
+	GLM_FUNC_QUALIFIER detail::tvec3<T> fastPow(
+		const detail::tvec3<T>& x, 
+		const detail::tvec3<int>& y)
+	{
+		return detail::tvec3<T>(
+			fastPow(x.x, y.x),
+			fastPow(x.y, y.y),
+			fastPow(x.z, y.z));
+	}
+
+	template <typename T>
+	GLM_FUNC_QUALIFIER detail::tvec4<T> fastPow(
+		const detail::tvec4<T>& x, 
+		const detail::tvec4<int>& y)
+	{
+		return detail::tvec4<T>(
+			fastPow(x.x, y.x),
+			fastPow(x.y, y.y),
+			fastPow(x.z, y.z),
+			fastPow(x.w, y.w));
+	}
+
+	// fastExp
+	// Note: This function provides accurate results only for value between -1 and 1, else avoid it.
+	template <typename T>
+	GLM_FUNC_QUALIFIER T fastExp(const T x)
+	{
+		// This has a better looking and same performance in release mode than the following code. However, in debug mode it's slower.
+		// return 1.0f + x * (1.0f + x * 0.5f * (1.0f + x * 0.3333333333f * (1.0f + x * 0.25 * (1.0f + x * 0.2f))));
+		T x2 = x * x;
+		T x3 = x2 * x;
+		T x4 = x3 * x;
+		T x5 = x4 * x;
+		return T(1) + x + (x2 * T(0.5)) + (x3 * T(0.1666666667)) + (x4 * T(0.041666667)) + (x5 * T(0.008333333333));
+	}
+	/*  // Try to handle all values of float... but often shower than std::exp, glm::floor and the loop kill the performance
+	GLM_FUNC_QUALIFIER float fastExp(float x)
+	{
+		const float e = 2.718281828f;
+		const float IntegerPart = floor(x);
+		const float FloatPart = x - IntegerPart;
+		float z = 1.f;
+
+		for(int i = 0; i < int(IntegerPart); ++i)
+			z *= e;
+
+		const float x2 = FloatPart * FloatPart;
+		const float x3 = x2 * FloatPart;
+		const float x4 = x3 * FloatPart;
+		const float x5 = x4 * FloatPart;
+		return z * (1.0f + FloatPart + (x2 * 0.5f) + (x3 * 0.1666666667f) + (x4 * 0.041666667f) + (x5 * 0.008333333333f));
+	}
+
+	// Increase accuracy on number bigger that 1 and smaller than -1 but it's not enough for high and negative numbers
+	GLM_FUNC_QUALIFIER float fastExp(float x)
+	{
+		// This has a better looking and same performance in release mode than the following code. However, in debug mode it's slower.
+		// return 1.0f + x * (1.0f + x * 0.5f * (1.0f + x * 0.3333333333f * (1.0f + x * 0.25 * (1.0f + x * 0.2f))));
+		float x2 = x * x;
+		float x3 = x2 * x;
+		float x4 = x3 * x;
+		float x5 = x4 * x;
+		float x6 = x5 * x;
+		float x7 = x6 * x;
+		float x8 = x7 * x;
+		return 1.0f + x + (x2 * 0.5f) + (x3 * 0.1666666667f) + (x4 * 0.041666667f) + (x5 * 0.008333333333f)+ (x6 * 0.00138888888888f) + (x7 * 0.000198412698f) + (x8 * 0.0000248015873f);;
+	}
+	*/
+
+	VECTORIZE_VEC(fastExp)
+
+	// fastLog
+	template <typename genType>
+	GLM_FUNC_QUALIFIER genType fastLog(genType const & x)
+	{
+		return std::log(x);
+	}
+
+	/* Slower than the VC7.1 function...
+	GLM_FUNC_QUALIFIER float fastLog(float x)
+	{
+		float y1 = (x - 1.0f) / (x + 1.0f);
+		float y2 = y1 * y1;
+		return 2.0f * y1 * (1.0f + y2 * (0.3333333333f + y2 * (0.2f + y2 * 0.1428571429f)));
+	}
+	*/
+
+	VECTORIZE_VEC(fastLog)
+
+	//fastExp2, ln2 = 0.69314718055994530941723212145818f
+	template <typename genType>
+	GLM_FUNC_QUALIFIER genType fastExp2(genType const & x)
+	{
+		return fastExp(0.69314718055994530941723212145818f * x);
+	}
+
+	VECTORIZE_VEC(fastExp2)
+
+	// fastLog2, ln2 = 0.69314718055994530941723212145818f
+	template <typename genType>
+	GLM_FUNC_QUALIFIER genType fastLog2(genType const & x)
+	{
+		return fastLog(x) / 0.69314718055994530941723212145818f;
+	}
+
+	VECTORIZE_VEC(fastLog2)
 
 
 }//namespace glm
 }//namespace glm

+ 129 - 224
glm/gtx/fast_square_root.inl

@@ -2,232 +2,137 @@
 // OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
 // OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // Created : 2006-01-04
 // Created : 2006-01-04
-// Updated : 2008-10-07
+// Updated : 2011-10-14
 // Licence : This source is under MIT License
 // Licence : This source is under MIT License
 // File    : glm/gtx/fast_square_root.inl
 // File    : glm/gtx/fast_square_root.inl
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 
-namespace glm{
-
-// fastSqrt
-template <typename genType>
-GLM_FUNC_QUALIFIER genType fastSqrt
-(
-	genType const & x
-)
-{
-    return genType(1) / fastInverseSqrt(x);
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec2<valType> fastSqrt
-(
-	detail::tvec2<valType> const & x
-)
-{
-    return detail::tvec2<valType>(
-        fastSqrt(x.x), 
-        fastSqrt(x.y));
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec3<valType> fastSqrt
-(
-	detail::tvec3<valType> const & x
-)
-{
-    return detail::tvec3<valType>(
-        fastSqrt(x.x), 
-        fastSqrt(x.y), 
-        fastSqrt(x.z));
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec4<valType> fastSqrt
-(
-	detail::tvec4<valType> const & x
-)
-{
-    return detail::tvec4<valType>(
-        fastSqrt(x.x), 
-        fastSqrt(x.y), 
-        fastSqrt(x.z), 
-        fastSqrt(x.w));
-}
-
-// fastInversesqrt
-template <typename genType>
-GLM_FUNC_QUALIFIER genType fastInverseSqrt
-(
-	genType const & x
-)
-{
-	genType tmp = x;
-    float xhalf = 0.5f * float(tmp);
-    uint i = *(uint*)&x;
-    i = 0x5f375a86 - (i >> 1);
-    //x = *(float*)&i;
-	//x = *((float*)(char*)&i);
-	tmp = detail::uif(i).f;
-	tmp = tmp * (1.5f - xhalf * tmp * tmp);
-    return genType(tmp);
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec2<valType> fastInverseSqrt
-(
-	detail::tvec2<valType> const & x
-)
-{
-    return detail::tvec2<valType>(
-        fastInverseSqrt(x.x), 
-        fastInverseSqrt(x.y));
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec3<valType> fastInverseSqrt
-(
-	detail::tvec3<valType> const & x
-)
-{
-    return detail::tvec3<valType>(
-        fastInverseSqrt(x.x), 
-        fastInverseSqrt(x.y), 
-        fastInverseSqrt(x.z));
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec4<valType> fastInverseSqrt
-(
-	detail::tvec4<valType> const & x
-)
-{
-    return detail::tvec4<valType>(
-        fastInverseSqrt(x.x), 
-        fastInverseSqrt(x.y), 
-        fastInverseSqrt(x.z), 
-        fastInverseSqrt(x.w));
-}
-
-// fastLength
-template <typename genType>
-GLM_FUNC_QUALIFIER genType fastLength
-(
-	genType const & x
-)
-{
-    return abs(x);
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER valType fastLength
-(
-	detail::tvec2<valType> const & x
-)
-{
-    valType sqr = x.x * x.x + x.y * x.y;
-    return fastSqrt(sqr);
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER valType fastLength
-(
-	detail::tvec3<valType> const & x
-)
-{
-    valType sqr = x.x * x.x + x.y * x.y + x.z * x.z;
-    return fastSqrt(sqr);
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER valType fastLength
-(
-	detail::tvec4<valType> const & x
-)
-{
-    valType sqr = x.x * x.x + x.y * x.y + x.z * x.z + x.w * x.w;
-    return fastSqrt(sqr);
-}
-
-// fastDistance
-template <typename genType>
-GLM_FUNC_QUALIFIER genType fastDistance
-(
-	genType const & x, 
-	genType const & y
-)
-{
-    return fastLength(y - x);
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER valType fastDistance
-(
-	detail::tvec2<valType> const & x, 
-	detail::tvec2<valType> const & y
-)
-{
-    return fastLength(y - x);
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER valType fastDistance
-(
-	detail::tvec3<valType> const & x, 
-	detail::tvec3<valType> const & y
-)
-{
-    return fastLength(y - x);
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER valType fastDistance
-(
-	detail::tvec4<valType> const & x, 
-	detail::tvec4<valType> const & y
-)
-{
-    return fastLength(y - x);
-}
-
-// fastNormalize
-template <typename genType>
-GLM_FUNC_QUALIFIER genType fastNormalize
-(
-	genType const & x
-)
-{
-    return x > genType(0) ? genType(1) : -genType(1);
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec2<valType> fastNormalize
-(
-	detail::tvec2<valType> const & x
-)
-{
-    valType sqr = x.x * x.x + x.y * x.y;
-    return x * fastInverseSqrt(sqr);
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec3<valType> fastNormalize
-(
-	detail::tvec3<valType> const & x
-)
-{
-    valType sqr = x.x * x.x + x.y * x.y + x.z * x.z;
-    return x * fastInverseSqrt(sqr);
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec4<valType> fastNormalize
-(
-	detail::tvec4<valType> const & x
-)
-{
-    valType sqr = x.x * x.x + x.y * x.y + x.z * x.z + x.w * x.w;
-    return x * fastInverseSqrt(sqr);
-}
-
+#include "../core/_vectorize.hpp"
+
+namespace glm
+{
+	// fastSqrt
+	template <typename genType>
+	GLM_FUNC_QUALIFIER genType fastSqrt
+	(
+		genType const & x
+	)
+	{
+		GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'fastSqrt' only accept floating-point input");
+
+		return genType(1) / fastInverseSqrt(x);
+	}
+
+	VECTORIZE_VEC(fastSqrt)
+
+	// fastInversesqrt
+	template <typename genType>
+	GLM_FUNC_QUALIFIER genType fastInverseSqrt
+	(
+		genType const & x
+	)
+	{
+		genType tmp = x;
+		float xhalf = 0.5f * float(tmp);
+		uint i = *(uint*)&x;
+		i = 0x5f375a86 - (i >> 1);
+		//x = *(float*)&i;
+		//x = *((float*)(char*)&i);
+		tmp = detail::uif(i).f;
+		tmp = tmp * (1.5f - xhalf * tmp * tmp);
+		return genType(tmp);
+	}
+
+	VECTORIZE_VEC(fastInverseSqrt)
+
+	// fastLength
+	template <typename genType>
+	GLM_FUNC_QUALIFIER genType fastLength
+	(
+		genType const & x
+	)
+	{
+		return abs(x);
+	}
+
+	template <typename valType>
+	GLM_FUNC_QUALIFIER valType fastLength
+	(
+		detail::tvec2<valType> const & x
+	)
+	{
+		valType sqr = x.x * x.x + x.y * x.y;
+		return fastSqrt(sqr);
+	}
+
+	template <typename valType>
+	GLM_FUNC_QUALIFIER valType fastLength
+	(
+		detail::tvec3<valType> const & x
+	)
+	{
+		valType sqr = x.x * x.x + x.y * x.y + x.z * x.z;
+		return fastSqrt(sqr);
+	}
+
+	template <typename valType>
+	GLM_FUNC_QUALIFIER valType fastLength
+	(
+		detail::tvec4<valType> const & x
+	)
+	{
+		valType sqr = x.x * x.x + x.y * x.y + x.z * x.z + x.w * x.w;
+		return fastSqrt(sqr);
+	}
+
+	// fastDistance
+	template <typename genType>
+	GLM_FUNC_QUALIFIER genType fastDistance
+	(
+		genType const & x, 
+		genType const & y
+	)
+	{
+		return fastLength(y - x);
+	}
+
+	// fastNormalize
+	template <typename genType>
+	GLM_FUNC_QUALIFIER genType fastNormalize
+	(
+		genType const & x
+	)
+	{
+		return x > genType(0) ? genType(1) : -genType(1);
+	}
+
+	template <typename valType>
+	GLM_FUNC_QUALIFIER detail::tvec2<valType> fastNormalize
+	(
+		detail::tvec2<valType> const & x
+	)
+	{
+		valType sqr = x.x * x.x + x.y * x.y;
+		return x * fastInverseSqrt(sqr);
+	}
+
+	template <typename valType>
+	GLM_FUNC_QUALIFIER detail::tvec3<valType> fastNormalize
+	(
+		detail::tvec3<valType> const & x
+	)
+	{
+		valType sqr = x.x * x.x + x.y * x.y + x.z * x.z;
+		return x * fastInverseSqrt(sqr);
+	}
+
+	template <typename valType>
+	GLM_FUNC_QUALIFIER detail::tvec4<valType> fastNormalize
+	(
+		detail::tvec4<valType> const & x
+	)
+	{
+		valType sqr = x.x * x.x + x.y * x.y + x.z * x.z + x.w * x.w;
+		return x * fastInverseSqrt(sqr);
+	}
 }//namespace glm
 }//namespace glm

+ 52 - 243
glm/gtx/fast_trigonometry.inl

@@ -2,267 +2,76 @@
 // OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
 // OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // Created : 2006-01-08
 // Created : 2006-01-08
-// Updated : 2006-01-08
+// Updated : 2011-10-14
 // Licence : This source is under MIT License
 // Licence : This source is under MIT License
 // File    : glm/gtx/fast_trigonometry.inl
 // File    : glm/gtx/fast_trigonometry.inl
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 
-namespace glm{
+#include "../core/_vectorize.hpp"
 
 
-// sin
-template <typename T> 
-GLM_FUNC_QUALIFIER T fastSin(const T x)
+namespace glm
 {
 {
-    return x - ((x * x * x) / T(6)) + ((x * x * x * x * x) / T(120)) - ((x * x * x * x * x * x * x) / T(5040));
-}
+	// sin
+	template <typename T> 
+	GLM_FUNC_QUALIFIER T fastSin(T const & x)
+	{
+		return x - ((x * x * x) / T(6)) + ((x * x * x * x * x) / T(120)) - ((x * x * x * x * x * x * x) / T(5040));
+	}
 
 
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tvec2<T> fastSin(
-	const detail::tvec2<T>& x)
-{
-    return detail::tvec2<T>(
-        fastSin(x.x),
-        fastSin(x.y));
-}
+	VECTORIZE_VEC(fastSin)
 
 
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tvec3<T> fastSin(
-	const detail::tvec3<T>& x)
-{
-    return detail::tvec3<T>(
-        fastSin(x.x),
-        fastSin(x.y),
-        fastSin(x.z));
-}
+	// cos
+	template <typename T> 
+	GLM_FUNC_QUALIFIER T fastCos(T const & x)
+	{
+		return T(1) - (x * x * T(0.5)) + (x * x * x * x * T(0.041666666666)) - (x * x * x * x * x * x * T(0.00138888888888));
+	}
 
 
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tvec4<T> fastSin(
-	const detail::tvec4<T>& x)
-{
-    return detail::tvec4<T>(
-        fastSin(x.x),
-        fastSin(x.y),
-        fastSin(x.z),
-        fastSin(x.w));
-}
+	VECTORIZE_VEC(fastCos)
 
 
-// cos
-template <typename T> 
-GLM_FUNC_QUALIFIER T fastCos(const T x)
-{
-    return T(1) - (x * x * T(0.5)) + (x * x * x * x * T(0.041666666666)) - (x * x * x * x * x * x * T(0.00138888888888));
-}
+	// tan
+	template <typename T> 
+	GLM_FUNC_QUALIFIER T fastTan(T const & x)
+	{
+		return x + (x * x * x * T(0.3333333333)) + (x * x * x * x * x * T(0.1333333333333)) + (x * x * x * x * x * x * x * T(0.0539682539));
+	}
 
 
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tvec2<T> fastCos(
-	const detail::tvec2<T>& x)
-{
-    return detail::tvec2<T>(
-        fastCos(x.x),
-        fastCos(x.y));
-}
+	VECTORIZE_VEC(fastTan)
 
 
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tvec3<T> fastCos(
-	const detail::tvec3<T>& x)
-{
-    return detail::tvec3<T>(
-        fastCos(x.x),
-        fastCos(x.y),
-        fastCos(x.z));
-}
+	// asin
+	template <typename T> 
+	GLM_FUNC_QUALIFIER T fastAsin(T const & x)
+	{
+		return x + (x * x * x * T(0.166666667)) + (x * x * x * x * x * T(0.075)) + (x * x * x * x * x * x * x * T(0.0446428571)) + (x * x * x * x * x * x * x * x * x * T(0.0303819444));// + (x * x * x * x * x * x * x * x * x * x * x * T(0.022372159));
+	}
 
 
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tvec4<T> fastCos(
-	const detail::tvec4<T>& x)
-{
-    return detail::tvec4<T>(
-        fastCos(x.x),
-        fastCos(x.y),
-        fastCos(x.z),
-        fastCos(x.w));
-}
+	VECTORIZE_VEC(fastAsin)
 
 
-// tan
-template <typename T> 
-GLM_FUNC_QUALIFIER T fastTan(const T x)
-{
-    return x + (x * x * x * T(0.3333333333)) + (x * x * x * x * x * T(0.1333333333333)) + (x * x * x * x * x * x * x * T(0.0539682539));
-}
+	// acos
+	template <typename T> 
+	GLM_FUNC_QUALIFIER T fastAcos(T const & x)
+	{
+		return T(1.5707963267948966192313216916398) - fastAsin(x); //(PI / 2)
+	}
 
 
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tvec2<T> fastTan(
-	const detail::tvec2<T>& x)
-{
-    return detail::tvec2<T>(
-        fastTan(x.x),
-        fastTan(x.y));
-}
+	VECTORIZE_VEC(fastAcos)
 
 
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tvec3<T> fastTan(
-	const detail::tvec3<T>& x)
-{
-    return detail::tvec3<T>(
-        fastTan(x.x),
-        fastTan(x.y),
-        fastTan(x.z));
-}
+	// atan
+	template <typename T> 
+	GLM_FUNC_QUALIFIER T fastAtan(T const & y, T const & x)
+	{
+		T sgn = sign(y) * sign(x);
+		return abs(fastAtan(y / x)) * sgn;
+	}
 
 
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tvec4<T> fastTan(
-	const detail::tvec4<T>& x)
-{
-    return detail::tvec4<T>(
-        fastTan(x.x),
-        fastTan(x.y),
-        fastTan(x.z),
-        fastTan(x.w));
-}
+	VECTORIZE_VEC_VEC(fastAtan)
 
 
-// asin
-template <typename T> 
-GLM_FUNC_QUALIFIER T fastAsin(const T x)
-{
-    return x + (x * x * x * T(0.166666667)) + (x * x * x * x * x * T(0.075)) + (x * x * x * x * x * x * x * T(0.0446428571)) + (x * x * x * x * x * x * x * x * x * T(0.0303819444));// + (x * x * x * x * x * x * x * x * x * x * x * T(0.022372159));
-}
-
-template <typename T> detail::tvec2<T> fastAsin(
-	const detail::tvec2<T>& x)
-{
-    return detail::tvec2<T>(
-        fastAsin(x.x),
-        fastAsin(x.y));
-}
-
-template <typename T> detail::tvec3<T> fastAsin(
-	const detail::tvec3<T>& x)
-{
-    return detail::tvec3<T>(
-        fastAsin(x.x),
-        fastAsin(x.y),
-        fastAsin(x.z));
-}
+	template <typename T> 
+	GLM_FUNC_QUALIFIER T fastAtan(T const & x)
+	{
+		return x - (x * x * x * T(0.333333333333)) + (x * x * x * x * x * T(0.2)) - (x * x * x * x * x * x * x * T(0.1428571429)) + (x * x * x * x * x * x * x * x * x * T(0.111111111111)) - (x * x * x * x * x * x * x * x * x * x * x * T(0.0909090909));
+	}
 
 
-template <typename T> detail::tvec4<T> fastAsin(
-	const detail::tvec4<T>& x)
-{
-    return detail::tvec4<T>(
-        fastAsin(x.x),
-        fastAsin(x.y),
-        fastAsin(x.z),
-        fastAsin(x.w));
-}
-
-// acos
-template <typename T> 
-GLM_FUNC_QUALIFIER T fastAcos(const T x)
-{
-    return T(1.5707963267948966192313216916398) - fastAsin(x); //(PI / 2)
-}
-
-template <typename T> detail::tvec2<T> fastAcos(
-	const detail::tvec2<T>& x)
-{
-    return detail::tvec2<T>(
-        fastAcos(x.x),
-        fastAcos(x.y));
-}
-
-template <typename T> detail::tvec3<T> fastAcos(
-	const detail::tvec3<T>& x)
-{
-    return detail::tvec3<T>(
-        fastAcos(x.x),
-        fastAcos(x.y),
-        fastAcos(x.z));
-}
-
-template <typename T> detail::tvec4<T> fastAcos(
-	const detail::tvec4<T>& x)
-{
-    return detail::tvec4<T>(
-        fastAcos(x.x),
-        fastAcos(x.y),
-        fastAcos(x.z),
-        fastAcos(x.w));
-}
-
-// atan
-template <typename T> 
-GLM_FUNC_QUALIFIER T fastAtan(const T y, const T x)
-{
-    T sgn = sign(y) * sign(x);
-    return abs(fastAtan(y / x)) * sgn;
-}
-
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tvec2<T> fastAtan(
-	const detail::tvec2<T>& y, 
-	const detail::tvec2<T>& x)
-{
-    return detail::tvec2<T>(
-        fastAtan(y.x, x.x),
-        fastAtan(y.y, x.y));
-}
-
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tvec3<T> fastAtan(
-	const detail::tvec3<T>& y, 
-	const detail::tvec3<T>& x)
-{
-    return detail::tvec3<T>(
-        fastAtan(y.x, x.x),
-        fastAtan(y.y, x.y),
-        fastAtan(y.z, x.z));
-}
-
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tvec4<T> fastAtan(
-	const detail::tvec4<T>& y, 
-	const detail::tvec4<T>& x)
-{
-    return detail::tvec4<T>(
-        fastAtan(y.x, x.x),
-        fastAtan(y.y, x.y),
-        fastAtan(y.z, x.z),
-        fastAtan(y.w, x.w));
-}
-
-template <typename T> 
-GLM_FUNC_QUALIFIER T fastAtan(const T x)
-{
-    return x - (x * x * x * T(0.333333333333)) + (x * x * x * x * x * T(0.2)) - (x * x * x * x * x * x * x * T(0.1428571429)) + (x * x * x * x * x * x * x * x * x * T(0.111111111111)) - (x * x * x * x * x * x * x * x * x * x * x * T(0.0909090909));
-}
-
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tvec2<T> fastAtan(
-	const detail::tvec2<T>& x)
-{
-    return detail::tvec2<T>(
-        fastAtan(x.x),
-        fastAtan(x.y));
-}
-
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tvec3<T> fastAtan(
-	const detail::tvec3<T>& x)
-{
-    return detail::tvec3<T>(
-        fastAtan(x.x),
-        fastAtan(x.y),
-        fastAtan(x.z));
-}
-
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tvec4<T> fastAtan(
-	const detail::tvec4<T>& x)
-{
-    return detail::tvec4<T>(
-        fastAtan(x.x),
-        fastAtan(x.y),
-        fastAtan(x.z),
-        fastAtan(x.w));
-}
+	VECTORIZE_VEC(fastAtan)
 
 
 }//namespace glm
 }//namespace glm

+ 30 - 31
glm/gtx/gradient_paint.inl

@@ -7,38 +7,37 @@
 // File    : glm/gtx/gradient_paint.inl
 // File    : glm/gtx/gradient_paint.inl
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 
-namespace glm{
-
-template <typename valType>
-valType radialGradient
-(
-	detail::tvec2<valType> const & Center,
-	valType const & Radius,
-	detail::tvec2<valType> const & Focal,
-	detail::tvec2<valType> const & Position
-)
+namespace glm
 {
 {
-	detail::tvec2<valType> F = Focal - Center;
-	detail::tvec2<valType> D = Position - Focal;
-	valType Radius2 = pow2(Radius);
-	valType Fx2 = pow2(F.x);
-	valType Fy2 = pow2(F.y);
-
-	valType Numerator = (D.x * F.x + D.y * F.y) + sqrt(Radius2 * (pow2(D.x) + pow2(D.y)) - pow2(D.x * F.y - D.y * F.x));
-	valType Denominator = Radius2 - (Fx2 + Fy2);
-	return Numerator / Denominator;
-}
+	template <typename valType>
+	valType radialGradient
+	(
+		detail::tvec2<valType> const & Center,
+		valType const & Radius,
+		detail::tvec2<valType> const & Focal,
+		detail::tvec2<valType> const & Position
+	)
+	{
+		detail::tvec2<valType> F = Focal - Center;
+		detail::tvec2<valType> D = Position - Focal;
+		valType Radius2 = pow2(Radius);
+		valType Fx2 = pow2(F.x);
+		valType Fy2 = pow2(F.y);
 
 
-template <typename valType>
-valType linearGradient
-(
-	detail::tvec2<valType> const & Point0,
-	detail::tvec2<valType> const & Point1,
-	detail::tvec2<valType> const & Position
-)
-{
-	detail::tvec2<valType> Dist = Point1 - Point0;
-	return (Dist.x * (Position.x - Point0.x) + Dist.y * (Position.y - Point0.y)) / glm::dot(Dist, Dist);
-}
+		valType Numerator = (D.x * F.x + D.y * F.y) + sqrt(Radius2 * (pow2(D.x) + pow2(D.y)) - pow2(D.x * F.y - D.y * F.x));
+		valType Denominator = Radius2 - (Fx2 + Fy2);
+		return Numerator / Denominator;
+	}
 
 
+	template <typename valType>
+	valType linearGradient
+	(
+		detail::tvec2<valType> const & Point0,
+		detail::tvec2<valType> const & Point1,
+		detail::tvec2<valType> const & Position
+	)
+	{
+		detail::tvec2<valType> Dist = Point1 - Point0;
+		return (Dist.x * (Position.x - Point0.x) + Dist.y * (Position.y - Point0.y)) / glm::dot(Dist, Dist);
+	}
 }//namespace glm
 }//namespace glm

+ 21 - 18
glm/gtx/handed_coordinate_space.inl

@@ -7,24 +7,27 @@
 // File    : glm/gtx/handed_coordinate_space.inl
 // File    : glm/gtx/handed_coordinate_space.inl
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 
-namespace glm{
-
-template <typename T> 
-GLM_FUNC_QUALIFIER bool rightHanded(
-	detail::tvec3<T> const & tangent, 
-	detail::tvec3<T> const & binormal,
-	detail::tvec3<T> const & normal)
-{
-    return dot(cross(normal, tangent), binormal) > T(0);
-}
-
-template <typename T> 
-GLM_FUNC_QUALIFIER bool leftHanded(
-	detail::tvec3<T> const & tangent, 
-	detail::tvec3<T> const & binormal, 
-	detail::tvec3<T> const & normal)
+namespace glm
 {
 {
-    return dot(cross(normal, tangent), binormal) < T(0);
-}
+	template <typename T> 
+	GLM_FUNC_QUALIFIER bool rightHanded
+	(
+		detail::tvec3<T> const & tangent, 
+		detail::tvec3<T> const & binormal,
+		detail::tvec3<T> const & normal
+	)
+	{
+		return dot(cross(normal, tangent), binormal) > T(0);
+	}
 
 
+	template <typename T> 
+	GLM_FUNC_QUALIFIER bool leftHanded
+	(
+		detail::tvec3<T> const & tangent, 
+		detail::tvec3<T> const & binormal, 
+		detail::tvec3<T> const & normal
+	)
+	{
+		return dot(cross(normal, tangent), binormal) < T(0);
+	}
 }//namespace glm
 }//namespace glm

+ 16 - 16
glm/gtx/inertia.hpp

@@ -55,57 +55,57 @@ namespace glm
 	//! From GLM_GTX_inertia extension.
 	//! From GLM_GTX_inertia extension.
 	template <typename T> 
 	template <typename T> 
 	detail::tmat3x3<T> boxInertia3(
 	detail::tmat3x3<T> boxInertia3(
-		const T Mass, 
-		const detail::tvec3<T>& Scale);
+		T const & Mass, 
+		detail::tvec3<T> const & Scale);
 		
 		
 	//! Build an inertia matrix for a box.
 	//! Build an inertia matrix for a box.
 	//! From GLM_GTX_inertia extension.
 	//! From GLM_GTX_inertia extension.
 	template <typename T> 
 	template <typename T> 
 	detail::tmat4x4<T> boxInertia4(
 	detail::tmat4x4<T> boxInertia4(
-		const T Mass, 
-		const detail::tvec3<T>& Scale);
+		T const & Mass, 
+		detail::tvec3<T> const & Scale);
 		
 		
 	//! Build an inertia matrix for a disk.
 	//! Build an inertia matrix for a disk.
 	//! From GLM_GTX_inertia extension.
 	//! From GLM_GTX_inertia extension.
 	template <typename T> 
 	template <typename T> 
 	detail::tmat3x3<T> diskInertia3(
 	detail::tmat3x3<T> diskInertia3(
-		const T Mass, 
-		const T Radius);
+		T const & Mass, 
+		T const & Radius);
 
 
 	//! Build an inertia matrix for a disk.
 	//! Build an inertia matrix for a disk.
 	//! From GLM_GTX_inertia extension.
 	//! From GLM_GTX_inertia extension.
 	template <typename T> 
 	template <typename T> 
 	detail::tmat4x4<T> diskInertia4(
 	detail::tmat4x4<T> diskInertia4(
-		const T Mass, 
-		const T Radius);
+		T const & Mass, 
+		T const & Radius);
 
 
 	//! Build an inertia matrix for a ball.
 	//! Build an inertia matrix for a ball.
 	//! From GLM_GTX_inertia extension.
 	//! From GLM_GTX_inertia extension.
 	template <typename T> 
 	template <typename T> 
 	detail::tmat3x3<T> ballInertia3(
 	detail::tmat3x3<T> ballInertia3(
-		const T Mass, 
-		const T Radius);
+		T const & Mass, 
+		T const & Radius);
 		
 		
 	//! Build an inertia matrix for a ball.
 	//! Build an inertia matrix for a ball.
 	//! From GLM_GTX_inertia extension.
 	//! From GLM_GTX_inertia extension.
 	template <typename T> 
 	template <typename T> 
 	detail::tmat4x4<T> ballInertia4(
 	detail::tmat4x4<T> ballInertia4(
-		const T Mass, 
-		const T Radius);
+		T const & Mass, 
+		T const & Radius);
 
 
 	//! Build an inertia matrix for a sphere.
 	//! Build an inertia matrix for a sphere.
 	//! From GLM_GTX_inertia extension.
 	//! From GLM_GTX_inertia extension.
 	template <typename T> 
 	template <typename T> 
 	detail::tmat3x3<T> sphereInertia3(
 	detail::tmat3x3<T> sphereInertia3(
-		const T Mass, 
-		const T Radius);
+		T const & Mass, 
+		T const & Radius);
 
 
 	//! Build an inertia matrix for a sphere.
 	//! Build an inertia matrix for a sphere.
 	//! From GLM_GTX_inertia extension.
 	//! From GLM_GTX_inertia extension.
 	template <typename T> 
 	template <typename T> 
 	detail::tmat4x4<T> sphereInertia4(
 	detail::tmat4x4<T> sphereInertia4(
-		const T Mass, 
-		const T Radius);
+		T const & Mass, 
+		T const & Radius);
 
 
 	/// @}
 	/// @}
 }// namespace glm
 }// namespace glm

+ 96 - 81
glm/gtx/inertia.inl

@@ -7,93 +7,108 @@
 // File    : glm/gtx/inertia.inl
 // File    : glm/gtx/inertia.inl
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 
-namespace glm{
-
-template <typename T>
-GLM_FUNC_QUALIFIER detail::tmat3x3<T> boxInertia3(
-	const T Mass, 
-	const detail::tvec3<T>& Scale)
+namespace glm
 {
 {
-	detail::tmat3x3<T> Result(T(1));
-	Result[0][0] = (Scale.y * Scale.y + Scale.z * Scale.z) * Mass / T(12);
-	Result[1][1] = (Scale.x * Scale.x + Scale.z * Scale.z) * Mass / T(12);
-	Result[2][2] = (Scale.x * Scale.x + Scale.y * Scale.y) * Mass / T(12);
-    return Result;
-}
+	template <typename T>
+	GLM_FUNC_QUALIFIER detail::tmat3x3<T> boxInertia3
+	(
+		T const & Mass, 
+		detail::tvec3<T> const & Scale
+	)
+	{
+		detail::tmat3x3<T> Result(T(1));
+		Result[0][0] = (Scale.y * Scale.y + Scale.z * Scale.z) * Mass / T(12);
+		Result[1][1] = (Scale.x * Scale.x + Scale.z * Scale.z) * Mass / T(12);
+		Result[2][2] = (Scale.x * Scale.x + Scale.y * Scale.y) * Mass / T(12);
+		return Result;
+	}
 
 
-template <typename T>
-GLM_FUNC_QUALIFIER detail::tmat4x4<T> boxInertia4(
-	const T Mass, 
-	const detail::tvec3<T>& Scale)
-{
-	detail::tmat4x4<T> Result(T(1));
-	Result[0][0] = (Scale.y * Scale.y + Scale.z * Scale.z) * Mass / T(12);
-	Result[1][1] = (Scale.x * Scale.x + Scale.z * Scale.z) * Mass / T(12);
-	Result[2][2] = (Scale.x * Scale.x + Scale.y * Scale.y) * Mass / T(12);
-    return Result;
-}
+	template <typename T>
+	GLM_FUNC_QUALIFIER detail::tmat4x4<T> boxInertia4
+	(
+		T const & Mass, 
+		detail::tvec3<T> const & Scale
+	)
+	{
+		detail::tmat4x4<T> Result(T(1));
+		Result[0][0] = (Scale.y * Scale.y + Scale.z * Scale.z) * Mass / T(12);
+		Result[1][1] = (Scale.x * Scale.x + Scale.z * Scale.z) * Mass / T(12);
+		Result[2][2] = (Scale.x * Scale.x + Scale.y * Scale.y) * Mass / T(12);
+		return Result;
+	}
 
 
-template <typename T>
-GLM_FUNC_QUALIFIER detail::tmat3x3<T> diskInertia3(
-	const T Mass, 
-	const T Radius)
-{
-    T a = Mass * Radius * Radius / T(2);
-    detail::tmat3x3<T> Result(a);
-    Result[2][2] *= T(2);
-    return Result;
-}
+	template <typename T>
+	GLM_FUNC_QUALIFIER detail::tmat3x3<T> diskInertia3
+	(
+		T const & Mass, 
+		T const & Radius
+	)
+	{
+		T a = Mass * Radius * Radius / T(2);
+		detail::tmat3x3<T> Result(a);
+		Result[2][2] *= T(2);
+		return Result;
+	}
 
 
-template <typename T>
-GLM_FUNC_QUALIFIER detail::tmat4x4<T> diskInertia4(
-	const T Mass, 
-	const T Radius)
-{
-    T a = Mass * Radius * Radius / T(2);
-    detail::tmat4x4<T> Result(a);
-    Result[2][2] *= T(2);
-    Result[3][3] = T(1);
-    return Result;
-}
+	template <typename T>
+	GLM_FUNC_QUALIFIER detail::tmat4x4<T> diskInertia4
+	(
+		T const & Mass, 
+		T const & Radius
+	)
+	{
+		T a = Mass * Radius * Radius / T(2);
+		detail::tmat4x4<T> Result(a);
+		Result[2][2] *= T(2);
+		Result[3][3] = T(1);
+		return Result;
+	}
 
 
-template <typename T>
-GLM_FUNC_QUALIFIER detail::tmat3x3<T> ballInertia3(
-	const T Mass, 
-	const T Radius)
-{
-    T a = T(2) * Mass * Radius * Radius / T(5);
-    return detail::tmat3x3<T>(a);
-}
+	template <typename T>
+	GLM_FUNC_QUALIFIER detail::tmat3x3<T> ballInertia3
+	(
+		T const & Mass, 
+		T const & Radius
+	)
+	{
+		T a = T(2) * Mass * Radius * Radius / T(5);
+		return detail::tmat3x3<T>(a);
+	}
 
 
-template <typename T>
-GLM_FUNC_QUALIFIER detail::tmat4x4<T> ballInertia4(
-	const T Mass, 
-	const T Radius)
-{
-    T a = T(2) * Mass * Radius * Radius / T(5);
-    detail::tmat4x4<T> Result(a);
-    Result[3][3] = T(1);
-    return Result;
-}
-
-template <typename T>
-GLM_FUNC_QUALIFIER detail::tmat3x3<T> sphereInertia3(
-	const T Mass, 
-	const T Radius)
-{
-    T a = T(2) * Mass * Radius * Radius / T(3);
-    return detail::tmat3x3<T>(a);
-}
+	template <typename T>
+	GLM_FUNC_QUALIFIER detail::tmat4x4<T> ballInertia4
+	(
+		T const & Mass, 
+		T const & Radius
+	)
+	{
+		T a = T(2) * Mass * Radius * Radius / T(5);
+		detail::tmat4x4<T> Result(a);
+		Result[3][3] = T(1);
+		return Result;
+	}
 
 
-template <typename T>
-GLM_FUNC_QUALIFIER detail::tmat4x4<T> sphereInertia4(
-	const T Mass, 
-	const T Radius)
-{
-    T a = T(2) * Mass * Radius * Radius / T(3);
-    detail::tmat4x4<T> Result(a);
-    Result[3][3] = T(1);
-    return Result;
-}
+	template <typename T>
+	GLM_FUNC_QUALIFIER detail::tmat3x3<T> sphereInertia3
+	(
+		T const & Mass, 
+		T const & Radius
+	)
+	{
+		T a = T(2) * Mass * Radius * Radius / T(3);
+		return detail::tmat3x3<T>(a);
+	}
 
 
+	template <typename T>
+	GLM_FUNC_QUALIFIER detail::tmat4x4<T> sphereInertia4
+	(
+		T const & Mass, 
+		T const & Radius
+	)
+	{
+		T a = T(2) * Mass * Radius * Radius / T(3);
+		detail::tmat4x4<T> Result(a);
+		Result[3][3] = T(1);
+		return Result;
+	}
 }//namespace glm
 }//namespace glm

+ 8 - 6
glm/gtx/int_10_10_10_2.inl

@@ -7,11 +7,13 @@
 // File    : glm/gtx/int_10_10_10_2.inl
 // File    : glm/gtx/int_10_10_10_2.inl
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 
-namespace glm{
-
-GLM_FUNC_QUALIFIER dword uint10_10_10_2_cast(glm::vec4 const & v)
+namespace glm
 {
 {
-    return dword(uint(v.x * 2047.f) << 0 | uint(v.y * 2047.f) << 10 | uint(v.z * 2047.f) << 20 | uint(v.w * 3.f) << 30);
-}
-
+	GLM_FUNC_QUALIFIER dword uint10_10_10_2_cast
+	(
+		glm::vec4 const & v
+	)
+	{
+		return dword(uint(v.x * 2047.f) << 0 | uint(v.y * 2047.f) << 10 | uint(v.z * 2047.f) << 20 | uint(v.w * 3.f) << 30);
+	}
 }//namespace glm
 }//namespace glm

+ 137 - 137
glm/gtx/integer.inl

@@ -7,35 +7,35 @@
 // File    : glm/gtx/integer.inl
 // File    : glm/gtx/integer.inl
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 
-namespace glm{
-
-// pow
-GLM_FUNC_QUALIFIER int pow(int x, int y)
-{
-	if(y == 0)
-		return 1;
-    int result = x;
-    for(int i = 1; i < y; ++i)
-        result *= x;
-    return result;
-}
-
-// sqrt: From Christopher J. Musial, An integer square root, Graphics Gems, 1990, page 387
-GLM_FUNC_QUALIFIER int sqrt(int x)
+namespace glm
 {
 {
-    if(x <= 1) return x;
+	// pow
+	GLM_FUNC_QUALIFIER int pow(int x, int y)
+	{
+		if(y == 0)
+			return 1;
+		int result = x;
+		for(int i = 1; i < y; ++i)
+			result *= x;
+		return result;
+	}
+
+	// sqrt: From Christopher J. Musial, An integer square root, Graphics Gems, 1990, page 387
+	GLM_FUNC_QUALIFIER int sqrt(int x)
+	{
+		if(x <= 1) return x;
 
 
-    int NextTrial = x >> 1;
-    int CurrentAnswer;
+		int NextTrial = x >> 1;
+		int CurrentAnswer;
 
 
-    do
-    {
-        CurrentAnswer = NextTrial;
-        NextTrial = (NextTrial + x / NextTrial) >> 1;
-    } while(NextTrial < CurrentAnswer);
+		do
+		{
+			CurrentAnswer = NextTrial;
+			NextTrial = (NextTrial + x / NextTrial) >> 1;
+		} while(NextTrial < CurrentAnswer);
 
 
-    return CurrentAnswer;
-}
+		return CurrentAnswer;
+	}
 
 
 // Henry Gordon Dietz: http://aggregate.org/MAGIC/
 // Henry Gordon Dietz: http://aggregate.org/MAGIC/
 namespace detail
 namespace detail
@@ -69,132 +69,132 @@ namespace detail
 	};
 	};
 }//namespace detail
 }//namespace detail
 
 
-// Henry Gordon Dietz: http://aggregate.org/MAGIC/
-unsigned int floor_log2(unsigned int x)
-{
-	x |= (x >> 1);
-	x |= (x >> 2);
-	x |= (x >> 4);
-	x |= (x >> 8);
-	x |= (x >> 16);
+	// Henry Gordon Dietz: http://aggregate.org/MAGIC/
+	unsigned int floor_log2(unsigned int x)
+	{
+		x |= (x >> 1);
+		x |= (x >> 2);
+		x |= (x >> 4);
+		x |= (x >> 8);
+		x |= (x >> 16);
 
 
-	return(detail::ones32(x) - 1);
-}
+		return(detail::ones32(x) - 1);
+	}
 
 
-// mod
-GLM_FUNC_QUALIFIER int mod(int x, int y)
-{
-	return x - y * (x / y);
-}
+	// mod
+	GLM_FUNC_QUALIFIER int mod(int x, int y)
+	{
+		return x - y * (x / y);
+	}
 
 
-// factorial (!12 max, integer only)
-template <typename genType>
-GLM_FUNC_QUALIFIER genType factorial(genType const & x)
-{
-	genType Temp = x;
-    genType Result;
-    for(Result = 1; Temp > 1; --Temp)
-        Result *= Temp;
-    return Result;
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec2<valType> factorial(
-	detail::tvec2<valType> const & x)
-{
-    return detail::tvec2<valType>(
-        factorial(x.x),
-        factorial(x.y));
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec3<valType> factorial(
-	detail::tvec3<valType> const & x)
-{
-    return detail::tvec3<valType>(
-        factorial(x.x),
-        factorial(x.y),
-        factorial(x.z));
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec4<valType> factorial(
-	detail::tvec4<valType> const & x)
-{
-    return detail::tvec4<valType>(
-        factorial(x.x),
-        factorial(x.y),
-        factorial(x.z),
-        factorial(x.w));
-}
-
-GLM_FUNC_QUALIFIER uint pow(uint x, uint y)
-{
-    uint result = x;
-    for(uint i = 1; i < y; ++i)
-        result *= x;
-    return result;
-}
+	// factorial (!12 max, integer only)
+	template <typename genType>
+	GLM_FUNC_QUALIFIER genType factorial(genType const & x)
+	{
+		genType Temp = x;
+		genType Result;
+		for(Result = 1; Temp > 1; --Temp)
+			Result *= Temp;
+		return Result;
+	}
 
 
-GLM_FUNC_QUALIFIER uint sqrt(uint x)
-{
-    if(x <= 1) return x;
+	template <typename valType>
+	GLM_FUNC_QUALIFIER detail::tvec2<valType> factorial(
+		detail::tvec2<valType> const & x)
+	{
+		return detail::tvec2<valType>(
+			factorial(x.x),
+			factorial(x.y));
+	}
+
+	template <typename valType>
+	GLM_FUNC_QUALIFIER detail::tvec3<valType> factorial(
+		detail::tvec3<valType> const & x)
+	{
+		return detail::tvec3<valType>(
+			factorial(x.x),
+			factorial(x.y),
+			factorial(x.z));
+	}
+
+	template <typename valType>
+	GLM_FUNC_QUALIFIER detail::tvec4<valType> factorial(
+		detail::tvec4<valType> const & x)
+	{
+		return detail::tvec4<valType>(
+			factorial(x.x),
+			factorial(x.y),
+			factorial(x.z),
+			factorial(x.w));
+	}
 
 
-    uint NextTrial = x >> 1;
-    uint CurrentAnswer;
+	GLM_FUNC_QUALIFIER uint pow(uint x, uint y)
+	{
+		uint result = x;
+		for(uint i = 1; i < y; ++i)
+			result *= x;
+		return result;
+	}
 
 
-    do
-    {
-        CurrentAnswer = NextTrial;
-        NextTrial = (NextTrial + x / NextTrial) >> 1;
-    } while(NextTrial < CurrentAnswer);
+	GLM_FUNC_QUALIFIER uint sqrt(uint x)
+	{
+		if(x <= 1) return x;
 
 
-    return CurrentAnswer;
-}
+		uint NextTrial = x >> 1;
+		uint CurrentAnswer;
 
 
-GLM_FUNC_QUALIFIER uint mod(uint x, uint y)
-{
-	return x - y * (x / y);
-}
+		do
+		{
+			CurrentAnswer = NextTrial;
+			NextTrial = (NextTrial + x / NextTrial) >> 1;
+		} while(NextTrial < CurrentAnswer);
+
+		return CurrentAnswer;
+	}
+
+	GLM_FUNC_QUALIFIER uint mod(uint x, uint y)
+	{
+		return x - y * (x / y);
+	}
 
 
 #if(GLM_COMPILER & (GLM_COMPILER_VC | GLM_COMPILER_GCC))
 #if(GLM_COMPILER & (GLM_COMPILER_VC | GLM_COMPILER_GCC))
 
 
-GLM_FUNC_QUALIFIER unsigned int nlz(unsigned int x) 
-{
-	return 31u - findMSB(x);
-}
+	GLM_FUNC_QUALIFIER unsigned int nlz(unsigned int x) 
+	{
+		return 31u - findMSB(x);
+	}
 
 
 #else
 #else
 
 
-// Hackers Delight: http://www.hackersdelight.org/HDcode/nlz.c.txt
-GLM_FUNC_QUALIFIER unsigned int nlz(unsigned int x) 
-{
-   int y, m, n;
-
-   y = -int(x >> 16);      // If left half of x is 0,
-   m = (y >> 16) & 16;  // set n = 16.  If left half
-   n = 16 - m;          // is nonzero, set n = 0 and
-   x = x >> m;          // shift x right 16.
-                        // Now x is of the form 0000xxxx.
-   y = x - 0x100;       // If positions 8-15 are 0,
-   m = (y >> 16) & 8;   // add 8 to n and shift x left 8.
-   n = n + m;
-   x = x << m;
-
-   y = x - 0x1000;      // If positions 12-15 are 0,
-   m = (y >> 16) & 4;   // add 4 to n and shift x left 4.
-   n = n + m;
-   x = x << m;
-
-   y = x - 0x4000;      // If positions 14-15 are 0,
-   m = (y >> 16) & 2;   // add 2 to n and shift x left 2.
-   n = n + m;
-   x = x << m;
-
-   y = x >> 14;         // Set y = 0, 1, 2, or 3.
-   m = y & ~(y >> 1);   // Set m = 0, 1, 2, or 2 resp.
-   return unsigned(n + 2 - m);
-}
+	// Hackers Delight: http://www.hackersdelight.org/HDcode/nlz.c.txt
+	GLM_FUNC_QUALIFIER unsigned int nlz(unsigned int x) 
+	{
+	   int y, m, n;
+
+	   y = -int(x >> 16);      // If left half of x is 0,
+	   m = (y >> 16) & 16;  // set n = 16.  If left half
+	   n = 16 - m;          // is nonzero, set n = 0 and
+	   x = x >> m;          // shift x right 16.
+							// Now x is of the form 0000xxxx.
+	   y = x - 0x100;       // If positions 8-15 are 0,
+	   m = (y >> 16) & 8;   // add 8 to n and shift x left 8.
+	   n = n + m;
+	   x = x << m;
+
+	   y = x - 0x1000;      // If positions 12-15 are 0,
+	   m = (y >> 16) & 4;   // add 4 to n and shift x left 4.
+	   n = n + m;
+	   x = x << m;
+
+	   y = x - 0x4000;      // If positions 14-15 are 0,
+	   m = (y >> 16) & 2;   // add 2 to n and shift x left 2.
+	   n = n + m;
+	   x = x << m;
+
+	   y = x >> 14;         // Set y = 0, 1, 2, or 3.
+	   m = y & ~(y >> 1);   // Set m = 0, 1, 2, or 2 resp.
+	   return unsigned(n + 2 - m);
+	}
 
 
 #endif//(GLM_COMPILER)
 #endif//(GLM_COMPILER)
 
 

+ 157 - 158
glm/gtx/intersect.inl

@@ -10,188 +10,187 @@
 #include <cfloat>
 #include <cfloat>
 #include <limits>
 #include <limits>
 
 
-namespace glm{
-
-template <typename genType>
-GLM_FUNC_QUALIFIER bool intersectRayTriangle
-(
-	genType const & orig, genType const & dir,
-	genType const & v0, genType const & v1, genType const & v2,
-	genType & baryPosition
-)
+namespace glm
 {
 {
-	genType e1 = v1 - v0;
-	genType e2 = v2 - v0;
+	template <typename genType>
+	GLM_FUNC_QUALIFIER bool intersectRayTriangle
+	(
+		genType const & orig, genType const & dir,
+		genType const & v0, genType const & v1, genType const & v2,
+		genType & baryPosition
+	)
+	{
+		genType e1 = v1 - v0;
+		genType e2 = v2 - v0;
 
 
-	genType p = glm::cross(dir, e2);
+		genType p = glm::cross(dir, e2);
 
 
-	typename genType::value_type a = glm::dot(e1, p);
+		typename genType::value_type a = glm::dot(e1, p);
 
 
-	typename genType::value_type Epsilon = std::numeric_limits<typename genType::value_type>::epsilon();
-	if(a < Epsilon)
-		return false;
+		typename genType::value_type Epsilon = std::numeric_limits<typename genType::value_type>::epsilon();
+		if(a < Epsilon)
+			return false;
 
 
-	typename genType::value_type f = typename genType::value_type(1.0f) / a;
+		typename genType::value_type f = typename genType::value_type(1.0f) / a;
 
 
-	genType s = orig - v0;
-	baryPosition.x = f * glm::dot(s, p);
-	if(baryPosition.x < typename genType::value_type(0.0f))
-		return false;
-	if(baryPosition.x > typename genType::value_type(1.0f))
-		return false;
+		genType s = orig - v0;
+		baryPosition.x = f * glm::dot(s, p);
+		if(baryPosition.x < typename genType::value_type(0.0f))
+			return false;
+		if(baryPosition.x > typename genType::value_type(1.0f))
+			return false;
 
 
-	genType q = glm::cross(s, e1);
-	baryPosition.y = f * glm::dot(dir, q);
-	if(baryPosition.y < typename genType::value_type(0.0f))
-		return false;
-	if(baryPosition.y + baryPosition.x > typename genType::value_type(1.0f))
-		return false;
+		genType q = glm::cross(s, e1);
+		baryPosition.y = f * glm::dot(dir, q);
+		if(baryPosition.y < typename genType::value_type(0.0f))
+			return false;
+		if(baryPosition.y + baryPosition.x > typename genType::value_type(1.0f))
+			return false;
 
 
-	baryPosition.z = f * glm::dot(e2, q);
-
-	return baryPosition.z >= typename genType::value_type(0.0f);
-}
-
-//template <typename genType>
-//GLM_FUNC_QUALIFIER bool intersectRayTriangle
-//(
-//	genType const & orig, genType const & dir,
-//	genType const & vert0, genType const & vert1, genType const & vert2,
-//	genType & position
-//)
-//{
-//	typename genType::value_type Epsilon = std::numeric_limits<typename genType::value_type>::epsilon();
-//
-//	genType edge1 = vert1 - vert0;
-//	genType edge2 = vert2 - vert0;
-//
-//	genType pvec = cross(dir, edge2);
-//
-//	float det = dot(edge1, pvec);
-//	if(det < Epsilon)
-//		return false;
-//
-//	genType tvec = orig - vert0;
-//
-//	position.y = dot(tvec, pvec);
-//	if (position.y < typename genType::value_type(0) || position.y > det)
-//		return typename genType::value_type(0);
-//
-//	genType qvec = cross(tvec, edge1);
-//
-//	position.z = dot(dir, qvec);
-//	if (position.z < typename genType::value_type(0) || position.y + position.z > det)
-//		return typename genType::value_type(0);
-//
-//	position.x = dot(edge2, qvec);
-//	position *= typename genType::value_type(1) / det;
-//
-//	return typename genType::value_type(1);
-//}
-
-template <typename genType>
-GLM_FUNC_QUALIFIER bool intersectLineTriangle
-(
-	genType const & orig, genType const & dir,
-	genType const & vert0, genType const & vert1, genType const & vert2,
-	genType & position
-)
-{
-    typename genType::value_type Epsilon = std::numeric_limits<typename genType::value_type>::epsilon();
+		baryPosition.z = f * glm::dot(e2, q);
 
 
-	genType edge1 = vert1 - vert0;
-	genType edge2 = vert2 - vert0;
-
-	genType pvec = cross(dir, edge2);
+		return baryPosition.z >= typename genType::value_type(0.0f);
+	}
 
 
-	float det = dot(edge1, pvec);
+	//template <typename genType>
+	//GLM_FUNC_QUALIFIER bool intersectRayTriangle
+	//(
+	//	genType const & orig, genType const & dir,
+	//	genType const & vert0, genType const & vert1, genType const & vert2,
+	//	genType & position
+	//)
+	//{
+	//	typename genType::value_type Epsilon = std::numeric_limits<typename genType::value_type>::epsilon();
+	//
+	//	genType edge1 = vert1 - vert0;
+	//	genType edge2 = vert2 - vert0;
+	//
+	//	genType pvec = cross(dir, edge2);
+	//
+	//	float det = dot(edge1, pvec);
+	//	if(det < Epsilon)
+	//		return false;
+	//
+	//	genType tvec = orig - vert0;
+	//
+	//	position.y = dot(tvec, pvec);
+	//	if (position.y < typename genType::value_type(0) || position.y > det)
+	//		return typename genType::value_type(0);
+	//
+	//	genType qvec = cross(tvec, edge1);
+	//
+	//	position.z = dot(dir, qvec);
+	//	if (position.z < typename genType::value_type(0) || position.y + position.z > det)
+	//		return typename genType::value_type(0);
+	//
+	//	position.x = dot(edge2, qvec);
+	//	position *= typename genType::value_type(1) / det;
+	//
+	//	return typename genType::value_type(1);
+	//}
+
+	template <typename genType>
+	GLM_FUNC_QUALIFIER bool intersectLineTriangle
+	(
+		genType const & orig, genType const & dir,
+		genType const & vert0, genType const & vert1, genType const & vert2,
+		genType & position
+	)
+	{
+		typename genType::value_type Epsilon = std::numeric_limits<typename genType::value_type>::epsilon();
 
 
-	if (det > -Epsilon && det < Epsilon)
-		return false;
-	float inv_det = typename genType::value_type(1) / det;
+		genType edge1 = vert1 - vert0;
+		genType edge2 = vert2 - vert0;
 
 
-	genType tvec = orig - vert0;
+		genType pvec = cross(dir, edge2);
 
 
-	position.y = dot(tvec, pvec) * inv_det;
-	if (position.y < typename genType::value_type(0) || position.y > typename genType::value_type(1))
-		return false;
+		float det = dot(edge1, pvec);
 
 
-	genType qvec = cross(tvec, edge1);
+		if (det > -Epsilon && det < Epsilon)
+			return false;
+		float inv_det = typename genType::value_type(1) / det;
 
 
-	position.z = dot(dir, qvec) * inv_det;
-	if (position.z < typename genType::value_type(0) || position.y + position.z > typename genType::value_type(1))
-		return false;
+		genType tvec = orig - vert0;
 
 
-	position.x = dot(edge2, qvec) * inv_det;
+		position.y = dot(tvec, pvec) * inv_det;
+		if (position.y < typename genType::value_type(0) || position.y > typename genType::value_type(1))
+			return false;
 
 
-	return true;
-}
+		genType qvec = cross(tvec, edge1);
 
 
-template <typename genType>
-GLM_FUNC_QUALIFIER bool intersectRaySphere
-(
-	genType const & rayStarting, genType const & rayDirection,
-	genType const & sphereCenter, typename genType::value_type sphereRadius,
-	genType & position, genType & normal
-)
-{
-	typename genType::value_type Epsilon = std::numeric_limits<typename genType::value_type>::epsilon();
+		position.z = dot(dir, qvec) * inv_det;
+		if (position.z < typename genType::value_type(0) || position.y + position.z > typename genType::value_type(1))
+			return false;
 
 
-	typename genType::value_type a = dot(rayDirection, rayDirection);
-	typename genType::value_type b = typename genType::value_type(2) * dot(rayStarting, rayDirection);
-	typename genType::value_type c = dot(rayStarting, rayStarting) - sphereRadius * sphereRadius;
-	typename genType::value_type d = b * b - typename genType::value_type(4) * a * c;
-	typename genType::value_type e = sqrt(d);
-	typename genType::value_type x1 = (-b - e) / (typename genType::value_type(2) * a);
-	typename genType::value_type x2 = (-b + e) / (typename genType::value_type(2) * a);
+		position.x = dot(edge2, qvec) * inv_det;
 
 
-	if(x1 > Epsilon)
-	{
-		position = rayStarting + rayDirection * sphereRadius;
-		normal = (position - sphereCenter) / sphereRadius;
 		return true;
 		return true;
 	}
 	}
-	else if(x2 > Epsilon)
-	{
-		position = rayStarting + rayDirection * sphereRadius;
-		normal = (position - sphereCenter) / sphereRadius;
-		return true;
-	}
-	return false;
-}
-
-template <typename genType>
-GLM_FUNC_QUALIFIER bool intersectLineSphere
-(
-	genType const & point0, genType const & point1,
-	genType const & center, typename genType::value_type radius,
-	genType & position, genType & normal
-)
-{
-	typename genType::value_type Epsilon = std::numeric_limits<typename genType::value_type>::epsilon();
-
-    genType dir = point1 - point0;
-    typename genType::value_type a = dot(dir, dir);
-	typename genType::value_type b = typename genType::value_type(2) * dot(center, dir);
-	typename genType::value_type c = dot(center, center) - radius * radius;
-	typename genType::value_type d = b * b - typename genType::value_type(4) * a * c;
-	typename genType::value_type e = sqrt(d);
-	typename genType::value_type x1 = (-b - e) / (typename genType::value_type(2) * a);
-	typename genType::value_type x2 = (-b + e) / (typename genType::value_type(2) * a);
-
-	if(x1 > Epsilon)
+
+	template <typename genType>
+	GLM_FUNC_QUALIFIER bool intersectRaySphere
+	(
+		genType const & rayStarting, genType const & rayDirection,
+		genType const & sphereCenter, typename genType::value_type sphereRadius,
+		genType & position, genType & normal
+	)
 	{
 	{
-		position = center + dir * radius;
-		normal = (position - center) / radius;
-		return true;
+		typename genType::value_type Epsilon = std::numeric_limits<typename genType::value_type>::epsilon();
+
+		typename genType::value_type a = dot(rayDirection, rayDirection);
+		typename genType::value_type b = typename genType::value_type(2) * dot(rayStarting, rayDirection);
+		typename genType::value_type c = dot(rayStarting, rayStarting) - sphereRadius * sphereRadius;
+		typename genType::value_type d = b * b - typename genType::value_type(4) * a * c;
+		typename genType::value_type e = sqrt(d);
+		typename genType::value_type x1 = (-b - e) / (typename genType::value_type(2) * a);
+		typename genType::value_type x2 = (-b + e) / (typename genType::value_type(2) * a);
+
+		if(x1 > Epsilon)
+		{
+			position = rayStarting + rayDirection * sphereRadius;
+			normal = (position - sphereCenter) / sphereRadius;
+			return true;
+		}
+		else if(x2 > Epsilon)
+		{
+			position = rayStarting + rayDirection * sphereRadius;
+			normal = (position - sphereCenter) / sphereRadius;
+			return true;
+		}
+		return false;
 	}
 	}
-	else if(x2 > Epsilon)
+
+	template <typename genType>
+	GLM_FUNC_QUALIFIER bool intersectLineSphere
+	(
+		genType const & point0, genType const & point1,
+		genType const & center, typename genType::value_type radius,
+		genType & position, genType & normal
+	)
 	{
 	{
-		position = center + dir * radius;
-		normal = (position - center) / radius;
-		return true;
+		typename genType::value_type Epsilon = std::numeric_limits<typename genType::value_type>::epsilon();
+
+		genType dir = point1 - point0;
+		typename genType::value_type a = dot(dir, dir);
+		typename genType::value_type b = typename genType::value_type(2) * dot(center, dir);
+		typename genType::value_type c = dot(center, center) - radius * radius;
+		typename genType::value_type d = b * b - typename genType::value_type(4) * a * c;
+		typename genType::value_type e = sqrt(d);
+		typename genType::value_type x1 = (-b - e) / (typename genType::value_type(2) * a);
+		typename genType::value_type x2 = (-b + e) / (typename genType::value_type(2) * a);
+
+		if(x1 > Epsilon)
+		{
+			position = center + dir * radius;
+			normal = (position - center) / radius;
+			return true;
+		}
+		else if(x2 > Epsilon)
+		{
+			position = center + dir * radius;
+			normal = (position - center) / radius;
+			return true;
+		}
+		return false;
 	}
 	}
-	return false;
-}
-
 }//namespace glm
 }//namespace glm

+ 14 - 76
glm/gtx/log_base.inl

@@ -7,82 +7,20 @@
 // File    : glm/gtx/log_base.inl
 // File    : glm/gtx/log_base.inl
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 
-namespace glm{
+#include "../core/_vectorize.hpp"
 
 
-template <typename genType> 
-GLM_FUNC_QUALIFIER genType log(
-	genType const & x, 
-	genType const & base)
+namespace glm
 {
 {
-	assert(x != genType(0));
-
-	return glm::log(x) / glm::log(base);
-}
-
-template <typename valType> 
-GLM_FUNC_QUALIFIER detail::tvec2<valType> log(
-	detail::tvec2<valType> const & v, 
-	valType const & base)
-{
-	return detail::tvec2<valType>(
-		log(v.x, base),
-		log(v.y, base));
-}
-
-template <typename valType> 
-GLM_FUNC_QUALIFIER detail::tvec3<valType> log(
-	detail::tvec3<valType> const & v, 
-	valType const & base)
-{
-	return detail::tvec3<valType>(
-		log(v.x, base),
-		log(v.y, base),
-		log(v.z, base));
-}
-
-template <typename valType> 
-GLM_FUNC_QUALIFIER detail::tvec4<valType> log(
-	detail::tvec4<valType> const & v, 
-	valType const & base)
-{
-	return detail::tvec4<valType>(
-		log(v.x, base),
-		log(v.y, base),
-		log(v.z, base),
-		log(v.w, base));
-}
-
-template <typename valType> 
-GLM_FUNC_QUALIFIER detail::tvec2<valType> log(
-	detail::tvec2<valType> const & v, 
-	detail::tvec2<valType> const & base)
-{
-	return detail::tvec2<valType>(
-		log(v.x, base.x),
-		log(v.y, base.y));
-}
-
-template <typename valType> 
-GLM_FUNC_QUALIFIER detail::tvec3<valType> log(
-	detail::tvec3<valType> const & v, 
-	detail::tvec3<valType> const & base)
-{
-	return detail::tvec3<valType>(
-		log(v.x, base.x),
-		log(v.y, base.y),
-		log(v.z, base.z));
-}
-
-template <typename valType> 
-GLM_FUNC_QUALIFIER detail::tvec4<valType> log(
-	detail::tvec4<valType> const & v, 
-	detail::tvec4<valType> const & base)
-{
-	return detail::tvec4<valType>(
-		log(v.x, base.x),
-		log(v.y, base.y),
-		log(v.z, base.z),
-		log(v.w, base.w));
-}
-
+	template <typename genType> 
+	GLM_FUNC_QUALIFIER genType log(
+		genType const & x, 
+		genType const & base)
+	{
+		assert(x != genType(0));
+
+		return glm::log(x) / glm::log(base);
+	}
+
+	VECTORIZE_VEC_SCA(log)
+	VECTORIZE_VEC_VEC(log)
 }//namespace glm
 }//namespace glm

+ 31 - 27
glm/gtx/matrix_cross_product.inl

@@ -7,34 +7,38 @@
 // File    : glm/gtx/matrix_cross_product.inl
 // File    : glm/gtx/matrix_cross_product.inl
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 
-namespace glm{
-
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tmat3x3<T> matrixCross3(
-    detail::tvec3<T> const & x)
+namespace glm
 {
 {
-    detail::tmat3x3<T> Result(T(0));
-    Result[0][1] = x.z;
-    Result[1][0] = -x.z;
-    Result[0][2] = -x.y;
-    Result[2][0] = x.y;
-    Result[1][2] = x.x;
-    Result[2][1] = -x.x;
-    return Result;
-}
+	template <typename T> 
+	GLM_FUNC_QUALIFIER detail::tmat3x3<T> matrixCross3
+	(
+		detail::tvec3<T> const & x
+	)
+	{
+		detail::tmat3x3<T> Result(T(0));
+		Result[0][1] = x.z;
+		Result[1][0] = -x.z;
+		Result[0][2] = -x.y;
+		Result[2][0] = x.y;
+		Result[1][2] = x.x;
+		Result[2][1] = -x.x;
+		return Result;
+	}
 
 
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tmat4x4<T> matrixCross4(
-    detail::tvec3<T> const & x)
-{
-    detail::tmat4x4<T> Result(T(0));
-    Result[0][1] = x.z;
-    Result[1][0] = -x.z;
-    Result[0][2] = -x.y;
-    Result[2][0] = x.y;
-    Result[1][2] = x.x;
-    Result[2][1] = -x.x;
-    return Result;
-}
+	template <typename T> 
+	GLM_FUNC_QUALIFIER detail::tmat4x4<T> matrixCross4
+	(
+		detail::tvec3<T> const & x
+	)
+	{
+		detail::tmat4x4<T> Result(T(0));
+		Result[0][1] = x.z;
+		Result[1][0] = -x.z;
+		Result[0][2] = -x.y;
+		Result[2][0] = x.y;
+		Result[1][2] = x.x;
+		Result[2][1] = -x.x;
+		return Result;
+	}
 
 
 }//namespace glm
 }//namespace glm

+ 103 - 98
glm/gtx/matrix_interpolation.inl

@@ -7,107 +7,112 @@
 // File    : glm/gtx/matrix_interpolation.inl
 // File    : glm/gtx/matrix_interpolation.inl
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 
-namespace glm{
-
-template <typename T>
-GLM_FUNC_QUALIFIER void axisAngle(
-    detail::tmat4x4<T> const & mat,
-    detail::tvec3<T> & axis,
-    T & angle)
+namespace glm
 {
 {
-    T epsilon = (T)0.01;
-    T epsilon2 = (T)0.1;
-
-    if ((fabs(mat[1][0] - mat[0][1]) < epsilon) && (fabs(mat[2][0] - mat[0][2]) < epsilon) && (fabs(mat[2][1] - mat[1][2]) < epsilon)) {
-        if ((fabs(mat[1][0] + mat[0][1]) < epsilon2) && (fabs(mat[2][0] + mat[0][2]) < epsilon2) && (fabs(mat[2][1] + mat[1][2]) < epsilon2) && (fabs(mat[0][0] + mat[1][1] + mat[2][2] - (T)3.0) < epsilon2)) {
-            angle = (T)0.0;
-            axis.x = (T)1.0;
-            axis.y = (T)0.0;
-            axis.z = (T)0.0;
-            return;
-        }
-        angle = T(3.1415926535897932384626433832795);
-        T xx = (mat[0][0] + (T)1.0) / (T)2.0;
-        T yy = (mat[1][1] + (T)1.0) / (T)2.0;
-        T zz = (mat[2][2] + (T)1.0) / (T)2.0;
-        T xy = (mat[1][0] + mat[0][1]) / (T)4.0;
-        T xz = (mat[2][0] + mat[0][2]) / (T)4.0;
-        T yz = (mat[2][1] + mat[1][2]) / (T)4.0;
-        if ((xx > yy) && (xx > zz)) {
-            if (xx < epsilon) {
-                axis.x = (T)0.0;
-                axis.y = (T)0.7071;
-                axis.z = (T)0.7071;
-            } else {
-                axis.x = sqrt(xx);
-                axis.y = xy / axis.x;
-                axis.z = xz / axis.x;
-            }
-        } else if (yy > zz) {
-            if (yy < epsilon) {
-                axis.x = (T)0.7071;
-                axis.y = (T)0.0;
-                axis.z = (T)0.7071;
-            } else {
-                axis.y = sqrt(yy);
-                axis.x = xy / axis.y;
-                axis.z = yz / axis.y;
-            }
-        } else {
-            if (zz < epsilon) {
-                axis.x = (T)0.7071;
-                axis.y = (T)0.7071;
-                axis.z = (T)0.0;
-            } else {
-                axis.z = sqrt(zz);
-                axis.x = xz / axis.z;
-                axis.y = yz / axis.z;
-            }
-        }
-        return;
-    }
-    T s = sqrt((mat[2][1] - mat[1][2]) * (mat[2][1] - mat[1][2]) + (mat[2][0] - mat[0][2]) * (mat[2][0] - mat[0][2]) + (mat[1][0] - mat[0][1]) * (mat[1][0] - mat[0][1]));
-    if (glm::abs(s) < T(0.001))
-        s = (T)1.0;
-    angle = acos((mat[0][0] + mat[1][1] + mat[2][2] - (T)1.0) / (T)2.0);
-    axis.x = (mat[1][2] - mat[2][1]) / s;
-    axis.y = (mat[2][0] - mat[0][2]) / s;
-    axis.z = (mat[0][1] - mat[1][0]) / s;
-}
+	template <typename T>
+	GLM_FUNC_QUALIFIER void axisAngle
+	(
+		detail::tmat4x4<T> const & mat,
+		detail::tvec3<T> & axis,
+		T & angle
+	)
+	{
+		T epsilon = (T)0.01;
+		T epsilon2 = (T)0.1;
 
 
-template <typename T>
-GLM_FUNC_QUALIFIER detail::tmat4x4<T> axisAngleMatrix(
-	detail::tvec3<T> const & axis,
-	T const angle)
-{
-    T c = cos(angle);
-    T s = sin(angle);
-    T t = T(1) - c;
-    detail::tvec3<T> n = normalize(axis);
+		if ((fabs(mat[1][0] - mat[0][1]) < epsilon) && (fabs(mat[2][0] - mat[0][2]) < epsilon) && (fabs(mat[2][1] - mat[1][2]) < epsilon)) {
+			if ((fabs(mat[1][0] + mat[0][1]) < epsilon2) && (fabs(mat[2][0] + mat[0][2]) < epsilon2) && (fabs(mat[2][1] + mat[1][2]) < epsilon2) && (fabs(mat[0][0] + mat[1][1] + mat[2][2] - (T)3.0) < epsilon2)) {
+				angle = (T)0.0;
+				axis.x = (T)1.0;
+				axis.y = (T)0.0;
+				axis.z = (T)0.0;
+				return;
+			}
+			angle = T(3.1415926535897932384626433832795);
+			T xx = (mat[0][0] + (T)1.0) / (T)2.0;
+			T yy = (mat[1][1] + (T)1.0) / (T)2.0;
+			T zz = (mat[2][2] + (T)1.0) / (T)2.0;
+			T xy = (mat[1][0] + mat[0][1]) / (T)4.0;
+			T xz = (mat[2][0] + mat[0][2]) / (T)4.0;
+			T yz = (mat[2][1] + mat[1][2]) / (T)4.0;
+			if ((xx > yy) && (xx > zz)) {
+				if (xx < epsilon) {
+					axis.x = (T)0.0;
+					axis.y = (T)0.7071;
+					axis.z = (T)0.7071;
+				} else {
+					axis.x = sqrt(xx);
+					axis.y = xy / axis.x;
+					axis.z = xz / axis.x;
+				}
+			} else if (yy > zz) {
+				if (yy < epsilon) {
+					axis.x = (T)0.7071;
+					axis.y = (T)0.0;
+					axis.z = (T)0.7071;
+				} else {
+					axis.y = sqrt(yy);
+					axis.x = xy / axis.y;
+					axis.z = yz / axis.y;
+				}
+			} else {
+				if (zz < epsilon) {
+					axis.x = (T)0.7071;
+					axis.y = (T)0.7071;
+					axis.z = (T)0.0;
+				} else {
+					axis.z = sqrt(zz);
+					axis.x = xz / axis.z;
+					axis.y = yz / axis.z;
+				}
+			}
+			return;
+		}
+		T s = sqrt((mat[2][1] - mat[1][2]) * (mat[2][1] - mat[1][2]) + (mat[2][0] - mat[0][2]) * (mat[2][0] - mat[0][2]) + (mat[1][0] - mat[0][1]) * (mat[1][0] - mat[0][1]));
+		if (glm::abs(s) < T(0.001))
+			s = (T)1.0;
+		angle = acos((mat[0][0] + mat[1][1] + mat[2][2] - (T)1.0) / (T)2.0);
+		axis.x = (mat[1][2] - mat[2][1]) / s;
+		axis.y = (mat[2][0] - mat[0][2]) / s;
+		axis.z = (mat[0][1] - mat[1][0]) / s;
+	}
 
 
-    return detail::tmat4x4<T>(
-        t * n.x * n.x + c,          t * n.x * n.y + n.z * s,    t * n.x * n.z - n.y * s,    T(0),
-        t * n.x * n.y - n.z * s,    t * n.y * n.y + c,          t * n.y * n.z + n.x * s,    T(0),
-        t * n.x * n.z + n.y * s,    t * n.y * n.z - n.x * s,    t * n.z * n.z + c,          T(0),
-        T(0),                        T(0),                        T(0),                     T(1)
-    );
-}
+	template <typename T>
+	GLM_FUNC_QUALIFIER detail::tmat4x4<T> axisAngleMatrix
+	(
+		detail::tvec3<T> const & axis,
+		T const angle
+	)
+	{
+		T c = cos(angle);
+		T s = sin(angle);
+		T t = T(1) - c;
+		detail::tvec3<T> n = normalize(axis);
 
 
-template <typename T>
-GLM_FUNC_QUALIFIER detail::tmat4x4<T> interpolate(
-	detail::tmat4x4<T> const & m1,
-	detail::tmat4x4<T> const & m2,
-	T const delta)
-{
-	detail::tmat4x4<T> dltRotation = m2 * transpose(m1);
-	detail::tvec3<T> dltAxis;
-	T dltAngle;
-	axisAngle(dltRotation, dltAxis, dltAngle);
-	detail::tmat4x4<T> out = axisAngleMatrix(dltAxis, dltAngle * delta) * rotationMatrix(m1);
-	out[3][0] = m1[3][0] + delta * (m2[3][0] - m1[3][0]);
-	out[3][1] = m1[3][1] + delta * (m2[3][1] - m1[3][1]);
-	out[3][2] = m1[3][2] + delta * (m2[3][2] - m1[3][2]);
-	return out;
-}
+		return detail::tmat4x4<T>(
+			t * n.x * n.x + c,          t * n.x * n.y + n.z * s,    t * n.x * n.z - n.y * s,    T(0),
+			t * n.x * n.y - n.z * s,    t * n.y * n.y + c,          t * n.y * n.z + n.x * s,    T(0),
+			t * n.x * n.z + n.y * s,    t * n.y * n.z - n.x * s,    t * n.z * n.z + c,          T(0),
+			T(0),                        T(0),                        T(0),                     T(1)
+		);
+	}
 
 
+	template <typename T>
+	GLM_FUNC_QUALIFIER detail::tmat4x4<T> interpolate
+	(
+		detail::tmat4x4<T> const & m1,
+		detail::tmat4x4<T> const & m2,
+		T const delta
+	)
+	{
+		detail::tmat4x4<T> dltRotation = m2 * transpose(m1);
+		detail::tvec3<T> dltAxis;
+		T dltAngle;
+		axisAngle(dltRotation, dltAxis, dltAngle);
+		detail::tmat4x4<T> out = axisAngleMatrix(dltAxis, dltAngle * delta) * rotationMatrix(m1);
+		out[3][0] = m1[3][0] + delta * (m2[3][0] - m1[3][0]);
+		out[3][1] = m1[3][1] + delta * (m2[3][1] - m1[3][1]);
+		out[3][2] = m1[3][2] + delta * (m2[3][2] - m1[3][2]);
+		return out;
+	}
 }//namespace glm
 }//namespace glm

+ 24 - 24
glm/gtx/matrix_major_storage.hpp

@@ -55,85 +55,85 @@ namespace glm
 	//! From GLM_GTX_matrix_major_storage extension.
 	//! From GLM_GTX_matrix_major_storage extension.
 	template <typename T> 
 	template <typename T> 
 	detail::tmat2x2<T> rowMajor2(
 	detail::tmat2x2<T> rowMajor2(
-		const detail::tvec2<T>& v1, 
-		const detail::tvec2<T>& v2);
+		detail::tvec2<T> const & v1, 
+		detail::tvec2<T> const & v2);
 		
 		
 	//! Build a row major matrix from other matrix.
 	//! Build a row major matrix from other matrix.
 	//! From GLM_GTX_matrix_major_storage extension.
 	//! From GLM_GTX_matrix_major_storage extension.
 	template <typename T> 
 	template <typename T> 
 	detail::tmat2x2<T> rowMajor2(
 	detail::tmat2x2<T> rowMajor2(
-		const detail::tmat2x2<T>& m);
+		detail::tmat2x2<T> const & m);
 
 
 	//! Build a row major matrix from row vectors.
 	//! Build a row major matrix from row vectors.
 	//! From GLM_GTX_matrix_major_storage extension.
 	//! From GLM_GTX_matrix_major_storage extension.
 	template <typename T> 
 	template <typename T> 
 	detail::tmat3x3<T> rowMajor3(
 	detail::tmat3x3<T> rowMajor3(
-		const detail::tvec3<T>& v1, 
-		const detail::tvec3<T>& v2, 
-		const detail::tvec3<T>& v3);
+		detail::tvec3<T> const & v1, 
+		detail::tvec3<T> const & v2, 
+		detail::tvec3<T> const & v3);
 
 
 	//! Build a row major matrix from other matrix.
 	//! Build a row major matrix from other matrix.
 	//! From GLM_GTX_matrix_major_storage extension.
 	//! From GLM_GTX_matrix_major_storage extension.
 	template <typename T> 
 	template <typename T> 
 	detail::tmat3x3<T> rowMajor3(
 	detail::tmat3x3<T> rowMajor3(
-		const detail::tmat3x3<T>& m);
+		detail::tmat3x3<T> const & m);
 
 
 	//! Build a row major matrix from row vectors.
 	//! Build a row major matrix from row vectors.
 	//! From GLM_GTX_matrix_major_storage extension.
 	//! From GLM_GTX_matrix_major_storage extension.
 	template <typename T> 
 	template <typename T> 
 	detail::tmat4x4<T> rowMajor4(
 	detail::tmat4x4<T> rowMajor4(
-		const detail::tvec4<T>& v1, 
-		const detail::tvec4<T>& v2,
-		const detail::tvec4<T>& v3, 
-		const detail::tvec4<T>& v4);
+		detail::tvec4<T> const & v1, 
+		detail::tvec4<T> const & v2,
+		detail::tvec4<T> const & v3, 
+		detail::tvec4<T> const & v4);
 
 
 	//! Build a row major matrix from other matrix.
 	//! Build a row major matrix from other matrix.
 	//! From GLM_GTX_matrix_major_storage extension.
 	//! From GLM_GTX_matrix_major_storage extension.
 	template <typename T> 
 	template <typename T> 
 	detail::tmat4x4<T> rowMajor4(
 	detail::tmat4x4<T> rowMajor4(
-		const detail::tmat4x4<T>& m);
+		detail::tmat4x4<T> const & m);
 
 
 	//! Build a column major matrix from column vectors.
 	//! Build a column major matrix from column vectors.
 	//! From GLM_GTX_matrix_major_storage extension.
 	//! From GLM_GTX_matrix_major_storage extension.
 	template <typename T> 
 	template <typename T> 
 	detail::tmat2x2<T> colMajor2(
 	detail::tmat2x2<T> colMajor2(
-		const detail::tvec2<T>& v1, 
-		const detail::tvec2<T>& v2);
+		detail::tvec2<T> const & v1, 
+		detail::tvec2<T> const & v2);
 		
 		
 	//! Build a column major matrix from other matrix.
 	//! Build a column major matrix from other matrix.
 	//! From GLM_GTX_matrix_major_storage extension.
 	//! From GLM_GTX_matrix_major_storage extension.
 	template <typename T> 
 	template <typename T> 
 	detail::tmat2x2<T> colMajor2(
 	detail::tmat2x2<T> colMajor2(
-		const detail::tmat2x2<T>& m);
+		detail::tmat2x2<T> const & m);
 
 
 	//! Build a column major matrix from column vectors.
 	//! Build a column major matrix from column vectors.
 	//! From GLM_GTX_matrix_major_storage extension.
 	//! From GLM_GTX_matrix_major_storage extension.
 	template <typename T> 
 	template <typename T> 
 	detail::tmat3x3<T> colMajor3(
 	detail::tmat3x3<T> colMajor3(
-		const detail::tvec3<T>& v1, 
-		const detail::tvec3<T>& v2, 
-		const detail::tvec3<T>& v3);
+		detail::tvec3<T> const & v1, 
+		detail::tvec3<T> const & v2, 
+		detail::tvec3<T> const & v3);
 		
 		
 	//! Build a column major matrix from other matrix.
 	//! Build a column major matrix from other matrix.
 	//! From GLM_GTX_matrix_major_storage extension.
 	//! From GLM_GTX_matrix_major_storage extension.
 	template <typename T> 
 	template <typename T> 
 	detail::tmat3x3<T> colMajor3(
 	detail::tmat3x3<T> colMajor3(
-		const detail::tmat3x3<T>& m);
+		detail::tmat3x3<T> const & m);
 		
 		
 	//! Build a column major matrix from column vectors.
 	//! Build a column major matrix from column vectors.
 	//! From GLM_GTX_matrix_major_storage extension.
 	//! From GLM_GTX_matrix_major_storage extension.
 	template <typename T> 
 	template <typename T> 
 	detail::tmat4x4<T> colMajor4(
 	detail::tmat4x4<T> colMajor4(
-		const detail::tvec4<T>& v1, 
-		const detail::tvec4<T>& v2, 
-		const detail::tvec4<T>& v3, 
-		const detail::tvec4<T>& v4);
+		detail::tvec4<T> const & v1, 
+		detail::tvec4<T> const & v2, 
+		detail::tvec4<T> const & v3, 
+		detail::tvec4<T> const & v4);
 				
 				
 	//! Build a column major matrix from other matrix.
 	//! Build a column major matrix from other matrix.
 	//! From GLM_GTX_matrix_major_storage extension.
 	//! From GLM_GTX_matrix_major_storage extension.
 	template <typename T> 
 	template <typename T> 
 	detail::tmat4x4<T> colMajor4(
 	detail::tmat4x4<T> colMajor4(
-		const detail::tmat4x4<T>& m);
+		detail::tmat4x4<T> const & m);
 
 
 	/// @}
 	/// @}
 }//namespace glm
 }//namespace glm

+ 151 - 150
glm/gtx/matrix_major_storage.inl

@@ -7,166 +7,167 @@
 // File    : glm/gtx/matrix_major_storage.inl
 // File    : glm/gtx/matrix_major_storage.inl
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 
-namespace glm{
-
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tmat2x2<T> rowMajor2(
-	const detail::tvec2<T>& v1, 
-	const detail::tvec2<T>& v2)
+namespace glm
 {
 {
-    detail::tmat2x2<T> Result;
-    Result[0][0] = v1.x;
-    Result[1][0] = v1.y;
-    Result[0][1] = v2.x;
-    Result[1][1] = v2.y;
-    return Result;
-}
+	template <typename T> 
+	GLM_FUNC_QUALIFIER detail::tmat2x2<T> rowMajor2
+	(
+		detail::tvec2<T> const & v1, 
+		detail::tvec2<T> const & v2
+	)
+	{
+		detail::tmat2x2<T> Result;
+		Result[0][0] = v1.x;
+		Result[1][0] = v1.y;
+		Result[0][1] = v2.x;
+		Result[1][1] = v2.y;
+		return Result;
+	}
 
 
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tmat2x2<T> rowMajor2(
-	const detail::tmat2x2<T>& m)
-{
-    detail::tmat2x2<T> 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 <typename T> 
+	GLM_FUNC_QUALIFIER detail::tmat2x2<T> rowMajor2(
+		const detail::tmat2x2<T>& m)
+	{
+		detail::tmat2x2<T> 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 <typename T> 
-GLM_FUNC_QUALIFIER detail::tmat3x3<T> rowMajor3(
-	const detail::tvec3<T>& v1, 
-	const detail::tvec3<T>& v2, 
-	const detail::tvec3<T>& v3)
-{
-    detail::tmat3x3<T> Result;
-    Result[0][0] = v1.x;
-    Result[1][0] = v1.y;
-    Result[2][0] = v1.z;
-    Result[0][1] = v2.x;
-    Result[1][1] = v2.y;
-    Result[2][1] = v2.z;
-    Result[0][2] = v3.x;
-    Result[1][2] = v3.y;
-    Result[2][2] = v3.z;
-    return Result;
-}
+	template <typename T> 
+	GLM_FUNC_QUALIFIER detail::tmat3x3<T> rowMajor3(
+		const detail::tvec3<T>& v1, 
+		const detail::tvec3<T>& v2, 
+		const detail::tvec3<T>& v3)
+	{
+		detail::tmat3x3<T> Result;
+		Result[0][0] = v1.x;
+		Result[1][0] = v1.y;
+		Result[2][0] = v1.z;
+		Result[0][1] = v2.x;
+		Result[1][1] = v2.y;
+		Result[2][1] = v2.z;
+		Result[0][2] = v3.x;
+		Result[1][2] = v3.y;
+		Result[2][2] = v3.z;
+		return Result;
+	}
 
 
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tmat3x3<T> rowMajor3(
-	const detail::tmat3x3<T>& m)
-{
-    detail::tmat3x3<T> 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 <typename T> 
+	GLM_FUNC_QUALIFIER detail::tmat3x3<T> rowMajor3(
+		const detail::tmat3x3<T>& m)
+	{
+		detail::tmat3x3<T> 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 <typename T> 
-GLM_FUNC_QUALIFIER detail::tmat4x4<T> rowMajor4(
-	const detail::tvec4<T>& v1, 
-	const detail::tvec4<T>& v2, 
-	const detail::tvec4<T>& v3, 
-	const detail::tvec4<T>& v4)
-{
-    detail::tmat4x4<T> Result;
-    Result[0][0] = v1.x;
-    Result[1][0] = v1.y;
-    Result[2][0] = v1.z;
-    Result[3][0] = v1.w;
-    Result[0][1] = v2.x;
-    Result[1][1] = v2.y;
-    Result[2][1] = v2.z;
-    Result[3][1] = v2.w;
-    Result[0][2] = v3.x;
-    Result[1][2] = v3.y;
-    Result[2][2] = v3.z;
-    Result[3][2] = v3.w;
-    Result[0][3] = v4.x;
-    Result[1][3] = v4.y;
-    Result[2][3] = v4.z;
-    Result[3][3] = v4.w;
-    return Result;
-}
+	template <typename T> 
+	GLM_FUNC_QUALIFIER detail::tmat4x4<T> rowMajor4(
+		const detail::tvec4<T>& v1, 
+		const detail::tvec4<T>& v2, 
+		const detail::tvec4<T>& v3, 
+		const detail::tvec4<T>& v4)
+	{
+		detail::tmat4x4<T> Result;
+		Result[0][0] = v1.x;
+		Result[1][0] = v1.y;
+		Result[2][0] = v1.z;
+		Result[3][0] = v1.w;
+		Result[0][1] = v2.x;
+		Result[1][1] = v2.y;
+		Result[2][1] = v2.z;
+		Result[3][1] = v2.w;
+		Result[0][2] = v3.x;
+		Result[1][2] = v3.y;
+		Result[2][2] = v3.z;
+		Result[3][2] = v3.w;
+		Result[0][3] = v4.x;
+		Result[1][3] = v4.y;
+		Result[2][3] = v4.z;
+		Result[3][3] = v4.w;
+		return Result;
+	}
 
 
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tmat4x4<T> rowMajor4(
-	const detail::tmat4x4<T>& m)
-{
-    detail::tmat4x4<T> 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 <typename T> 
+	GLM_FUNC_QUALIFIER detail::tmat4x4<T> rowMajor4(
+		const detail::tmat4x4<T>& m)
+	{
+		detail::tmat4x4<T> 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 <typename T> 
-GLM_FUNC_QUALIFIER detail::tmat2x2<T> colMajor2(
-	const detail::tvec2<T>& v1, 
-	const detail::tvec2<T>& v2)
-{
-    return detail::tmat2x2<T>(v1, v2);
-}
+	template <typename T> 
+	GLM_FUNC_QUALIFIER detail::tmat2x2<T> colMajor2(
+		const detail::tvec2<T>& v1, 
+		const detail::tvec2<T>& v2)
+	{
+		return detail::tmat2x2<T>(v1, v2);
+	}
 
 
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tmat2x2<T> colMajor2(
-	const detail::tmat2x2<T>& m)
-{
-    return detail::tmat2x2<T>(m);
-}
-
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tmat3x3<T> colMajor3(
-	const detail::tvec3<T>& v1, 
-	const detail::tvec3<T>& v2, 
-	const detail::tvec3<T>& v3)
-{
-    return detail::tmat3x3<T>(v1, v2, v3);
-}
+	template <typename T> 
+	GLM_FUNC_QUALIFIER detail::tmat2x2<T> colMajor2(
+		const detail::tmat2x2<T>& m)
+	{
+		return detail::tmat2x2<T>(m);
+	}
 
 
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tmat3x3<T> colMajor3(
-	const detail::tmat3x3<T>& m)
-{
-    return detail::tmat3x3<T>(m);
-}
+	template <typename T> 
+	GLM_FUNC_QUALIFIER detail::tmat3x3<T> colMajor3(
+		const detail::tvec3<T>& v1, 
+		const detail::tvec3<T>& v2, 
+		const detail::tvec3<T>& v3)
+	{
+		return detail::tmat3x3<T>(v1, v2, v3);
+	}
 
 
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tmat4x4<T> colMajor4(
-	const detail::tvec4<T>& v1, 
-	const detail::tvec4<T>& v2, 
-	const detail::tvec4<T>& v3, 
-	const detail::tvec4<T>& v4)
-{
-    return detail::tmat4x4<T>(v1, v2, v3, v4);
-}
+	template <typename T> 
+	GLM_FUNC_QUALIFIER detail::tmat3x3<T> colMajor3(
+		const detail::tmat3x3<T>& m)
+	{
+		return detail::tmat3x3<T>(m);
+	}
 
 
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tmat4x4<T> colMajor4(
-	const detail::tmat4x4<T>& m)
-{
-    return detail::tmat4x4<T>(m);
-}
+	template <typename T> 
+	GLM_FUNC_QUALIFIER detail::tmat4x4<T> colMajor4(
+		const detail::tvec4<T>& v1, 
+		const detail::tvec4<T>& v2, 
+		const detail::tvec4<T>& v3, 
+		const detail::tvec4<T>& v4)
+	{
+		return detail::tmat4x4<T>(v1, v2, v3, v4);
+	}
 
 
+	template <typename T> 
+	GLM_FUNC_QUALIFIER detail::tmat4x4<T> colMajor4(
+		const detail::tmat4x4<T>& m)
+	{
+		return detail::tmat4x4<T>(m);
+	}
 }//namespace glm
 }//namespace glm

+ 105 - 106
glm/gtx/matrix_operation.inl

@@ -7,119 +7,118 @@
 // File    : glm/gtx/matrix_operation.inl
 // File    : glm/gtx/matrix_operation.inl
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 
-namespace glm{
-
-template <typename valType> 
-GLM_FUNC_QUALIFIER detail::tmat2x2<valType> diagonal2x2
-(
-	detail::tvec2<valType> const & v
-)
+namespace glm
 {
 {
-	detail::tmat2x2<valType> Result(valType(1));
-	Result[0][0] = v[0];
-	Result[1][1] = v[1];
-	return Result;
-}
+	template <typename valType> 
+	GLM_FUNC_QUALIFIER detail::tmat2x2<valType> diagonal2x2
+	(
+		detail::tvec2<valType> const & v
+	)
+	{
+		detail::tmat2x2<valType> Result(valType(1));
+		Result[0][0] = v[0];
+		Result[1][1] = v[1];
+		return Result;
+	}
 
 
-template <typename valType> 
-GLM_FUNC_QUALIFIER detail::tmat2x3<valType> diagonal2x3
-(
-	detail::tvec2<valType> const & v
-)
-{
-	detail::tmat2x3<valType> Result(valType(1));
-	Result[0][0] = v[0];
-	Result[1][1] = v[1];
-	return Result;
-}
+	template <typename valType> 
+	GLM_FUNC_QUALIFIER detail::tmat2x3<valType> diagonal2x3
+	(
+		detail::tvec2<valType> const & v
+	)
+	{
+		detail::tmat2x3<valType> Result(valType(1));
+		Result[0][0] = v[0];
+		Result[1][1] = v[1];
+		return Result;
+	}
 
 
-template <typename valType> 
-GLM_FUNC_QUALIFIER detail::tmat2x4<valType> diagonal2x4
-(
-	detail::tvec2<valType> const & v
-)
-{
-	detail::tmat2x4<valType> Result(valType(1));
-	Result[0][0] = v[0];
-	Result[1][1] = v[1];
-	return Result;
-}
-
-template <typename valType> 
-GLM_FUNC_QUALIFIER detail::tmat3x2<valType> diagonal3x2
-(
-	detail::tvec2<valType> const & v
-)
-{
-	detail::tmat3x2<valType> Result(valType(1));
-	Result[0][0] = v[0];
-	Result[1][1] = v[1];
-	return Result;
-}
+	template <typename valType> 
+	GLM_FUNC_QUALIFIER detail::tmat2x4<valType> diagonal2x4
+	(
+		detail::tvec2<valType> const & v
+	)
+	{
+		detail::tmat2x4<valType> Result(valType(1));
+		Result[0][0] = v[0];
+		Result[1][1] = v[1];
+		return Result;
+	}
 
 
-template <typename valType> 
-GLM_FUNC_QUALIFIER detail::tmat3x3<valType> diagonal3x3
-(
-	detail::tvec3<valType> const & v
-)
-{
-	detail::tmat3x3<valType> Result(valType(1));
-	Result[0][0] = v[0];
-	Result[1][1] = v[1];
-	Result[2][2] = v[2];
-	return Result;
-}
+	template <typename valType> 
+	GLM_FUNC_QUALIFIER detail::tmat3x2<valType> diagonal3x2
+	(
+		detail::tvec2<valType> const & v
+	)
+	{
+		detail::tmat3x2<valType> Result(valType(1));
+		Result[0][0] = v[0];
+		Result[1][1] = v[1];
+		return Result;
+	}
 
 
-template <typename valType> 
-GLM_FUNC_QUALIFIER detail::tmat3x4<valType> diagonal3x4
-(
-	detail::tvec3<valType> const & v
-)
-{
-	detail::tmat3x4<valType> Result(valType(1));
-	Result[0][0] = v[0];
-	Result[1][1] = v[1];
-	Result[2][2] = v[2];
-	return Result;
-}
+	template <typename valType> 
+	GLM_FUNC_QUALIFIER detail::tmat3x3<valType> diagonal3x3
+	(
+		detail::tvec3<valType> const & v
+	)
+	{
+		detail::tmat3x3<valType> Result(valType(1));
+		Result[0][0] = v[0];
+		Result[1][1] = v[1];
+		Result[2][2] = v[2];
+		return Result;
+	}
 
 
-template <typename valType> 
-GLM_FUNC_QUALIFIER detail::tmat4x4<valType> diagonal4x4
-(
-	detail::tvec4<valType> const & v
-)
-{
-	detail::tmat4x4<valType> Result(valType(1));
-	Result[0][0] = v[0];
-	Result[1][1] = v[1];
-	Result[2][2] = v[2];
-	Result[3][3] = v[3];
-	return Result;		
-}
+	template <typename valType> 
+	GLM_FUNC_QUALIFIER detail::tmat3x4<valType> diagonal3x4
+	(
+		detail::tvec3<valType> const & v
+	)
+	{
+		detail::tmat3x4<valType> Result(valType(1));
+		Result[0][0] = v[0];
+		Result[1][1] = v[1];
+		Result[2][2] = v[2];
+		return Result;
+	}
 
 
-template <typename valType> 
-GLM_FUNC_QUALIFIER detail::tmat4x3<valType> diagonal4x3
-(
-	detail::tvec3<valType> const & v
-)
-{
-	detail::tmat4x3<valType> Result(valType(1));
-	Result[0][0] = v[0];
-	Result[1][1] = v[1];
-	Result[2][2] = v[2];
-	return Result;		
-}
+	template <typename valType> 
+	GLM_FUNC_QUALIFIER detail::tmat4x4<valType> diagonal4x4
+	(
+		detail::tvec4<valType> const & v
+	)
+	{
+		detail::tmat4x4<valType> Result(valType(1));
+		Result[0][0] = v[0];
+		Result[1][1] = v[1];
+		Result[2][2] = v[2];
+		Result[3][3] = v[3];
+		return Result;		
+	}
 
 
-template <typename valType> 
-GLM_FUNC_QUALIFIER detail::tmat4x2<valType> diagonal4x2
-(
-	detail::tvec2<valType> const & v
-)
-{
-	detail::tmat4x2<valType> Result(valType(1));
-	Result[0][0] = v[0];
-	Result[1][1] = v[1];
-	return Result;		
-}
+	template <typename valType> 
+	GLM_FUNC_QUALIFIER detail::tmat4x3<valType> diagonal4x3
+	(
+		detail::tvec3<valType> const & v
+	)
+	{
+		detail::tmat4x3<valType> Result(valType(1));
+		Result[0][0] = v[0];
+		Result[1][1] = v[1];
+		Result[2][2] = v[2];
+		return Result;		
+	}
 
 
+	template <typename valType> 
+	GLM_FUNC_QUALIFIER detail::tmat4x2<valType> diagonal4x2
+	(
+		detail::tvec2<valType> const & v
+	)
+	{
+		detail::tmat4x2<valType> Result(valType(1));
+		Result[0][0] = v[0];
+		Result[1][1] = v[1];
+		return Result;		
+	}
 }//namespace glm
 }//namespace glm

+ 16 - 16
glm/gtx/matrix_query.hpp

@@ -56,57 +56,57 @@ namespace glm
 	//! From GLM_GTX_matrix_query extension.
 	//! From GLM_GTX_matrix_query extension.
 	template<typename T> 
 	template<typename T> 
 	bool isNull(
 	bool isNull(
-		const detail::tmat2x2<T>& m, 
-		const T epsilon = std::numeric_limits<T>::epsilon());
+		detail::tmat2x2<T> const & m, 
+		T const & epsilon = std::numeric_limits<T>::epsilon());
 		
 		
 	//! Return if a matrix a null matrix.
 	//! Return if a matrix a null matrix.
 	//! From GLM_GTX_matrix_query extension.
 	//! From GLM_GTX_matrix_query extension.
 	template<typename T> 
 	template<typename T> 
 	bool isNull(
 	bool isNull(
-		const detail::tmat3x3<T>& m, 
-		const T epsilon = std::numeric_limits<T>::epsilon());
+		detail::tmat3x3<T> const & m, 
+		T const & epsilon = std::numeric_limits<T>::epsilon());
 		
 		
 	//! Return if a matrix a null matrix.
 	//! Return if a matrix a null matrix.
 	//! From GLM_GTX_matrix_query extension.
 	//! From GLM_GTX_matrix_query extension.
 	template<typename T> 
 	template<typename T> 
 	bool isNull(
 	bool isNull(
-		const detail::tmat4x4<T>& m, 
-		const T epsilon = std::numeric_limits<T>::epsilon());
+		detail::tmat4x4<T> const & m, 
+		T const & epsilon = std::numeric_limits<T>::epsilon());
 			
 			
 	//! Return if a matrix an identity matrix. 
 	//! Return if a matrix an identity matrix. 
 	//! From GLM_GTX_matrix_query extension.
 	//! From GLM_GTX_matrix_query extension.
 	template<typename genType> 
 	template<typename genType> 
 	bool isIdentity(
 	bool isIdentity(
-		const genType& m, 
-		const typename genType::value_type epsilon = std::numeric_limits<typename genType::value_type>::epsilon());
+		genType const & m, 
+		typename genType::value_type const & epsilon = std::numeric_limits<typename genType::value_type>::epsilon());
 
 
 	//! Return if a matrix a normalized matrix.
 	//! Return if a matrix a normalized matrix.
 	//! From GLM_GTX_matrix_query extension.
 	//! From GLM_GTX_matrix_query extension.
 	template<typename T> 
 	template<typename T> 
 	bool isNormalized(
 	bool isNormalized(
-		const detail::tmat2x2<T>& m, 
-		const T epsilon = std::numeric_limits<T>::epsilon());
+		detail::tmat2x2<T> const & m, 
+		T const & epsilon = std::numeric_limits<T>::epsilon());
 		
 		
 	//! Return if a matrix a normalized matrix.
 	//! Return if a matrix a normalized matrix.
 	//! From GLM_GTX_matrix_query extension.
 	//! From GLM_GTX_matrix_query extension.
 	template<typename T> 
 	template<typename T> 
 	bool isNormalized(
 	bool isNormalized(
-		const detail::tmat3x3<T>& m, 
-		const T epsilon = std::numeric_limits<T>::epsilon());
+		detail::tmat3x3<T> const & m, 
+		T const & epsilon = std::numeric_limits<T>::epsilon());
 		
 		
 	//! Return if a matrix a normalized matrix.
 	//! Return if a matrix a normalized matrix.
 	//! From GLM_GTX_matrix_query extension.
 	//! From GLM_GTX_matrix_query extension.
 	template<typename T> 
 	template<typename T> 
 	bool isNormalized(
 	bool isNormalized(
-		const detail::tmat4x4<T>& m, 
-		const T epsilon = std::numeric_limits<T>::epsilon());
+		detail::tmat4x4<T> const & m, 
+		T const & epsilon = std::numeric_limits<T>::epsilon());
 
 
 	//! Return if a matrix an orthonormalized matrix.
 	//! Return if a matrix an orthonormalized matrix.
 	//! From GLM_GTX_matrix_query extension.
 	//! From GLM_GTX_matrix_query extension.
 	template<typename genType> 
 	template<typename genType> 
 	bool isOrthogonal(
 	bool isOrthogonal(
-		const genType& m, 
-		const typename genType::value_type epsilon = std::numeric_limits<typename genType::value_type>::epsilon());
+		genType const & m, 
+		typename genType::value_type const & epsilon = std::numeric_limits<typename genType::value_type>::epsilon());
 
 
 	/// @}
 	/// @}
 }//namespace glm
 }//namespace glm

+ 123 - 109
glm/gtx/matrix_query.inl

@@ -10,131 +10,145 @@
 // - GLM core
 // - GLM core
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 
-namespace glm{
-
-template<typename T> 
-GLM_FUNC_QUALIFIER bool isNull(
-	const detail::tmat2x2<T>& m, 
-	const T epsilon)
-{
-	bool result = true;
-	for(int i = 0; result && i < 2 ; ++i)
-		result = isNull(m[i], epsilon);
-	return result;
-}
-
-template<typename T> 
-GLM_FUNC_QUALIFIER bool isNull(
-	const detail::tmat3x3<T>& m, 
-	const T epsilon)
-{
-	bool result = true;
-	for(int i = 0; result && i < 3 ; ++i)
-		result = isNull(m[i], epsilon);
-	return result;
-}
-
-template<typename T> 
-GLM_FUNC_QUALIFIER bool isNull(
-	const detail::tmat4x4<T>& m, 
-	const T epsilon)
+namespace glm
 {
 {
-	bool result = true;
-	for(int i = 0; result && i < 4 ; ++i)
-		result = isNull(m[i], epsilon);
-	return result;
-}
+	template<typename T> 
+	GLM_FUNC_QUALIFIER bool isNull
+	(
+		detail::tmat2x2<T> const & m, 
+		T const & epsilon)
+	{
+		bool result = true;
+		for(int i = 0; result && i < 2 ; ++i)
+			result = isNull(m[i], epsilon);
+		return result;
+	}
 
 
-template<typename genType> 
-GLM_FUNC_QUALIFIER bool isIdentity(
-	const genType& m, 
-	const typename genType::value_type epsilon)
-{
-	bool result = true;
-	for(typename genType::value_type i = typename genType::value_type(0); result && i < genType::col_size(); ++i)
+	template<typename T> 
+	GLM_FUNC_QUALIFIER bool isNull
+	(
+		detail::tmat3x3<T> const & m, 
+		T const & epsilon
+	)
 	{
 	{
-		for(typename genType::value_type j = typename genType::value_type(0); result && j < i ; ++j)
-			result = abs(m[i][j]) <= epsilon;
-		if(result)
-			result = abs(m[i][i] - typename genType::value_type(1)) <= epsilon;
-		for(typename genType::value_type j = i + typename genType::value_type(1); result && j < genType::row_size(); ++j)
-			result = abs(m[i][j]) <= epsilon;
+		bool result = true;
+		for(int i = 0; result && i < 3 ; ++i)
+			result = isNull(m[i], epsilon);
+		return result;
 	}
 	}
-	return result;
-}
 
 
-template<typename T> 
-GLM_FUNC_QUALIFIER bool isNormalized(
-	const detail::tmat2x2<T>& m, 
-	const T epsilon)
-{
-	bool result = true;
-	for(int i = 0; result && i < 2; ++i)
-		result = isNormalized(m[i], epsilon);
-	for(int i = 0; result && i < 2; ++i)
+	template<typename T> 
+	GLM_FUNC_QUALIFIER bool isNull
+	(
+		detail::tmat4x4<T> const & m, 
+		T const & epsilon
+	)
 	{
 	{
-		detail::tvec2<T> v;
-		for(int j = 0; j < 2; ++j)
-			v[j] = m[j][i];
-		result = isNormalized(v, epsilon);
+		bool result = true;
+		for(int i = 0; result && i < 4 ; ++i)
+			result = isNull(m[i], epsilon);
+		return result;
 	}
 	}
-	return result;
-}
 
 
-template<typename T> 
-GLM_FUNC_QUALIFIER bool isNormalized(
-	const detail::tmat3x3<T>& m, 
-	const T epsilon)
-{
-	bool result = true;
-	for(int i = 0; result && i < 3; ++i)
-		result = isNormalized(m[i], epsilon);
-	for(int i = 0; result && i < 3; ++i)
+	template<typename genType> 
+	GLM_FUNC_QUALIFIER bool isIdentity
+	(
+		genType const & m, 
+		typename genType::value_type const & epsilon
+	)
 	{
 	{
-		detail::tvec3<T> v;
-		for(int j = 0; j < 3; ++j)
-			v[j] = m[j][i];
-		result = isNormalized(v, epsilon);
+		bool result = true;
+		for(typename genType::value_type i = typename genType::value_type(0); result && i < genType::col_size(); ++i)
+		{
+			for(typename genType::value_type j = typename genType::value_type(0); result && j < i ; ++j)
+				result = abs(m[i][j]) <= epsilon;
+			if(result)
+				result = abs(m[i][i] - typename genType::value_type(1)) <= epsilon;
+			for(typename genType::value_type j = i + typename genType::value_type(1); result && j < genType::row_size(); ++j)
+				result = abs(m[i][j]) <= epsilon;
+		}
+		return result;
 	}
 	}
-	return result;
-}
 
 
-template<typename T> 
-GLM_FUNC_QUALIFIER bool isNormalized(
-	const detail::tmat4x4<T>& m, 
-	const T epsilon)
-{
-	bool result = true;
-	for(int i = 0; result && i < 4; ++i)
-		result = isNormalized(m[i], epsilon);
-	for(int i = 0; result && i < 4; ++i)
+	template<typename T> 
+	GLM_FUNC_QUALIFIER bool isNormalized
+	(
+		detail::tmat2x2<T> const & m, 
+		T const & epsilon
+	)
 	{
 	{
-		detail::tvec4<T> v;
-		for(int j = 0; j < 4; ++j)
-			v[j] = m[j][i];
-		result = isNormalized(v, epsilon);
+		bool result = true;
+		for(int i = 0; result && i < 2; ++i)
+			result = isNormalized(m[i], epsilon);
+		for(int i = 0; result && i < 2; ++i)
+		{
+			detail::tvec2<T> v;
+			for(int j = 0; j < 2; ++j)
+				v[j] = m[j][i];
+			result = isNormalized(v, epsilon);
+		}
+		return result;
 	}
 	}
-	return result;
-}
 
 
-template<typename genType> 
-GLM_FUNC_QUALIFIER bool isOrthogonal(
-	const genType& m, 
-	const typename genType::value_type epsilon)
-{
-	bool result = true;
-	for(int i = 0; result && i < genType::col_size() - 1; ++i)
-	for(int j= i + 1; result && j < genType::col_size(); ++j)
-		result = areOrthogonal(m[i], m[j], epsilon);
+	template<typename T> 
+	GLM_FUNC_QUALIFIER bool isNormalized
+	(
+		detail::tmat3x3<T> const & m, 
+		T const & epsilon
+	)
+	{
+		bool result = true;
+		for(int i = 0; result && i < 3; ++i)
+			result = isNormalized(m[i], epsilon);
+		for(int i = 0; result && i < 3; ++i)
+		{
+			detail::tvec3<T> v;
+			for(int j = 0; j < 3; ++j)
+				v[j] = m[j][i];
+			result = isNormalized(v, epsilon);
+		}
+		return result;
+	}
 
 
-	if(result)
+	template<typename T> 
+	GLM_FUNC_QUALIFIER bool isNormalized
+	(
+		detail::tmat4x4<T> const & m, 
+		T const & epsilon
+	)
 	{
 	{
-		genType tmp = transpose(m);
-		for(int i = 0; result && i < genType::col_size() - 1 ; ++i)
-		for(int j = i + 1; result && j < genType::col_size(); ++j)
-			result = areOrthogonal(tmp[i], tmp[j], epsilon);
+		bool result = true;
+		for(int i = 0; result && i < 4; ++i)
+			result = isNormalized(m[i], epsilon);
+		for(int i = 0; result && i < 4; ++i)
+		{
+			detail::tvec4<T> v;
+			for(int j = 0; j < 4; ++j)
+				v[j] = m[j][i];
+			result = isNormalized(v, epsilon);
+		}
+		return result;
 	}
 	}
-	return result;
-}
 
 
+	template<typename genType> 
+	GLM_FUNC_QUALIFIER bool isOrthogonal
+	(
+		genType const & m, 
+		typename genType::value_type const & epsilon
+	)
+	{
+		bool result = true;
+		for(int i = 0; result && i < genType::col_size() - 1; ++i)
+		for(int j= i + 1; result && j < genType::col_size(); ++j)
+			result = areOrthogonal(m[i], m[j], epsilon);
+
+		if(result)
+		{
+			genType tmp = transpose(m);
+			for(int i = 0; result && i < genType::col_size() - 1 ; ++i)
+			for(int j = i + 1; result && j < genType::col_size(); ++j)
+				result = areOrthogonal(tmp[i], tmp[j], epsilon);
+		}
+		return result;
+	}
 }//namespace glm
 }//namespace glm

+ 11 - 10
glm/gtx/mixed_product.inl

@@ -7,15 +7,16 @@
 // File    : glm/gtx/mixed_product.inl
 // File    : glm/gtx/mixed_product.inl
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 
-namespace glm{
-
-template <typename valType> 
-GLM_FUNC_QUALIFIER valType mixedProduct(
-    detail::tvec3<valType> const & v1, 
-    detail::tvec3<valType> const & v2, 
-    detail::tvec3<valType> const & v3)
+namespace glm
 {
 {
-    return dot(cross(v1, v2), v3);
-}
-
+	template <typename valType> 
+	GLM_FUNC_QUALIFIER valType mixedProduct
+	(
+		detail::tvec3<valType> const & v1, 
+		detail::tvec3<valType> const & v2, 
+		detail::tvec3<valType> const & v3
+	)
+	{
+		return dot(cross(v1, v2), v3);
+	}
 }//namespace glm
 }//namespace glm

+ 105 - 178
glm/gtx/multiple.inl

@@ -10,184 +10,111 @@
 // - GLM core
 // - GLM core
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 
-namespace glm{
+#include "../core/_vectorize.hpp"
 
 
-//////////////////////
-// higherMultiple
-
-template <typename genType> 
-GLM_FUNC_QUALIFIER genType higherMultiple
-(
-	genType const & Source, 
-	genType const & Multiple
-)
-{
-	genType Tmp = Source % Multiple;
-	return Tmp ? Source + Multiple - Tmp : Source;
-}
-
-template <> 
-GLM_FUNC_QUALIFIER detail::thalf higherMultiple
-(
-	detail::thalf const & SourceH, 
-	detail::thalf const & MultipleH
-)
-{
-	float Source = SourceH.toFloat();
-	float Multiple = MultipleH.toFloat();
-
-	int Tmp = int(float(Source)) % int(Multiple);
-	return detail::thalf(Tmp ? Source + Multiple - float(Tmp) : Source);
-}
-
-template <> 
-GLM_FUNC_QUALIFIER float higherMultiple
-(	
-	float const & Source, 
-	float const & Multiple
-)
-{
-	int Tmp = int(Source) % int(Multiple);
-	return Tmp ? Source + Multiple - float(Tmp) : Source;
-}
-
-template <> 
-GLM_FUNC_QUALIFIER double higherMultiple
-(
-	double const & Source, 
-	double const & Multiple
-)
+namespace glm
 {
 {
-	long Tmp = long(Source) % long(Multiple);
-	return Tmp ? Source + Multiple - double(Tmp) : Source;
-}
-
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tvec2<T> higherMultiple
-(
-	detail::tvec2<T> const & Source, 
-	detail::tvec2<T> const & Multiple
-)
-{
-	detail::tvec2<T> Result;
-	for(typename detail::tvec2<T>::size_type i = 0; i < detail::tvec2<T>::value_size(); ++i)
-		Result[i] = higherMultiple(Source[i], Multiple[i]);
-	return Result;
-}
-
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tvec3<T> higherMultiple
-(
-	detail::tvec3<T> const & Source, 
-	detail::tvec3<T> const & Multiple
-)
-{
-	detail::tvec3<T> Result;
-	for(typename detail::tvec3<T>::size_type i = 0; i < detail::tvec3<T>::value_size(); ++i)
-		Result[i] = higherMultiple(Source[i], Multiple[i]);
-	return Result;
-}
-
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tvec4<T> higherMultiple
-(
-	detail::tvec4<T> const & Source, 
-	detail::tvec4<T> const & Multiple
-)
-{
-	detail::tvec4<T> Result;
-	for(typename detail::tvec4<T>::size_type i = 0; i < detail::tvec4<T>::value_size(); ++i)
-		Result[i] = higherMultiple(Source[i], Multiple[i]);
-	return Result;
-}
-
-//////////////////////
-// lowerMultiple
-
-template <typename genType> 
-GLM_FUNC_QUALIFIER genType lowerMultiple
-(
-	genType const & Source, 
-	genType const & Multiple
-)
-{
-	genType Tmp = Source % Multiple;
-	return Tmp ? Source - Tmp : Source;
-}
-
-template <> 
-GLM_FUNC_QUALIFIER detail::thalf lowerMultiple
-(
-	detail::thalf const & SourceH, 
-	detail::thalf const & MultipleH
-)
-{
-	float Source = SourceH.toFloat();
-	float Multiple = MultipleH.toFloat();
-
-	int Tmp = int(float(Source)) % int(float(Multiple));
-	return detail::thalf(Tmp ? Source - float(Tmp) : Source);
-}
-
-template <> 
-GLM_FUNC_QUALIFIER float lowerMultiple
-(
-	float const & Source, 
-	float const & Multiple
-)
-{
-	int Tmp = int(Source) % int(Multiple);
-	return Tmp ? Source - float(Tmp) : Source;
-}
-
-template <> 
-GLM_FUNC_QUALIFIER double lowerMultiple
-(
-	double const & Source, 
-	double const & Multiple
-)
-{
-	long Tmp = long(Source) % long(Multiple);
-	return Tmp ? Source - double(Tmp) : Source;
-}
-
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tvec2<T> lowerMultiple
-(
-	detail::tvec2<T> const & Source, 
-	detail::tvec2<T> const & Multiple
-)
-{
-	detail::tvec2<T> Result;
-	for(typename detail::tvec2<T>::size_type i = 0; i < detail::tvec2<T>::value_size(); ++i)
-		Result[i] = lowerMultiple(Source[i], Multiple[i]);
-	return Result;
-}
-
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tvec3<T> lowerMultiple
-(
-	detail::tvec3<T> const & Source, 
-	detail::tvec3<T> const & Multiple
-)
-{
-	detail::tvec3<T> Result;
-	for(typename detail::tvec3<T>::size_type i = 0; i < detail::tvec3<T>::value_size(); ++i)
-		Result[i] = lowerMultiple(Source[i], Multiple[i]);
-	return Result;
-}
-
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tvec4<T> lowerMultiple
-(
-	detail::tvec4<T> const & Source, 
-	detail::tvec4<T> const & Multiple
-)
-{
-	detail::tvec4<T> Result;
-	for(typename detail::tvec4<T>::size_type i = 0; i < detail::tvec4<T>::value_size(); ++i)
-		Result[i] = lowerMultiple(Source[i], Multiple[i]);
-	return Result;
-}
-
+	//////////////////////
+	// higherMultiple
+
+	template <typename genType> 
+	GLM_FUNC_QUALIFIER genType higherMultiple
+	(
+		genType const & Source, 
+		genType const & Multiple
+	)
+	{
+		genType Tmp = Source % Multiple;
+		return Tmp ? Source + Multiple - Tmp : Source;
+	}
+
+	template <> 
+	GLM_FUNC_QUALIFIER detail::thalf higherMultiple
+	(
+		detail::thalf const & SourceH, 
+		detail::thalf const & MultipleH
+	)
+	{
+		float Source = SourceH.toFloat();
+		float Multiple = MultipleH.toFloat();
+
+		int Tmp = int(float(Source)) % int(Multiple);
+		return detail::thalf(Tmp ? Source + Multiple - float(Tmp) : Source);
+	}
+
+	template <> 
+	GLM_FUNC_QUALIFIER float higherMultiple
+	(	
+		float const & Source, 
+		float const & Multiple
+	)
+	{
+		int Tmp = int(Source) % int(Multiple);
+		return Tmp ? Source + Multiple - float(Tmp) : Source;
+	}
+
+	template <> 
+	GLM_FUNC_QUALIFIER double higherMultiple
+	(
+		double const & Source, 
+		double const & Multiple
+	)
+	{
+		long Tmp = long(Source) % long(Multiple);
+		return Tmp ? Source + Multiple - double(Tmp) : Source;
+	}
+
+	VECTORIZE_VEC_VEC(higherMultiple)
+
+	//////////////////////
+	// lowerMultiple
+
+	template <typename genType> 
+	GLM_FUNC_QUALIFIER genType lowerMultiple
+	(
+		genType const & Source, 
+		genType const & Multiple
+	)
+	{
+		genType Tmp = Source % Multiple;
+		return Tmp ? Source - Tmp : Source;
+	}
+
+	template <> 
+	GLM_FUNC_QUALIFIER detail::thalf lowerMultiple
+	(
+		detail::thalf const & SourceH, 
+		detail::thalf const & MultipleH
+	)
+	{
+		float Source = SourceH.toFloat();
+		float Multiple = MultipleH.toFloat();
+
+		int Tmp = int(float(Source)) % int(float(Multiple));
+		return detail::thalf(Tmp ? Source - float(Tmp) : Source);
+	}
+
+	template <> 
+	GLM_FUNC_QUALIFIER float lowerMultiple
+	(
+		float const & Source, 
+		float const & Multiple
+	)
+	{
+		int Tmp = int(Source) % int(Multiple);
+		return Tmp ? Source - float(Tmp) : Source;
+	}
+
+	template <> 
+	GLM_FUNC_QUALIFIER double lowerMultiple
+	(
+		double const & Source, 
+		double const & Multiple
+	)
+	{
+		long Tmp = long(Source) % long(Multiple);
+		return Tmp ? Source - double(Tmp) : Source;
+	}
+
+	VECTORIZE_VEC_VEC(lowerMultiple)
 }//namespace glm
 }//namespace glm

+ 20 - 46
glm/gtx/norm.hpp

@@ -56,99 +56,73 @@ namespace glm
 	//! From GLM_GTX_norm extension.
 	//! From GLM_GTX_norm extension.
 	template <typename T> 
 	template <typename T> 
 	T length2(
 	T length2(
-		const T x);
+		T const & x);
 
 
 	//! Returns the squared length of x.
 	//! Returns the squared length of x.
 	//! From GLM_GTX_norm extension.
 	//! From GLM_GTX_norm extension.
-	template <typename T> 
-	T length2(
-		const detail::tvec2<T> & x);
-
-	//! Returns the squared length of x.
-	//! From GLM_GTX_norm extension.
-	template <typename T>
-	T length2(
-		const detail::tvec3<T>& x);
-		
-	//! Returns the squared length of x.
-	//! From GLM_GTX_norm extension.
-	template <typename T> 
-	T length2(
-		const detail::tvec4<T>& x);
+	template <typename genType> 
+	typename genType::value_type length2(
+		genType const & x);
 		
 		
 	//! Returns the squared length of x.
 	//! Returns the squared length of x.
 	//! From GLM_GTX_norm extension.
 	//! From GLM_GTX_norm extension.
 	template <typename T>
 	template <typename T>
 	T length2(
 	T length2(
-		const detail::tquat<T>& q);
+		detail::tquat<T> const & q);
 
 
 	//! Returns the squared distance between p0 and p1, i.e., length(p0 - p1).
 	//! Returns the squared distance between p0 and p1, i.e., length(p0 - p1).
 	//! From GLM_GTX_norm extension.
 	//! From GLM_GTX_norm extension.
 	template <typename T>
 	template <typename T>
 	T distance2(
 	T distance2(
-		const T p0, 
-		const T p1);
+		T const & p0, 
+		T const & p1);
 		
 		
 	//! Returns the squared distance between p0 and p1, i.e., length(p0 - p1).
 	//! Returns the squared distance between p0 and p1, i.e., length(p0 - p1).
 	//! From GLM_GTX_norm extension.
 	//! From GLM_GTX_norm extension.
-	template <typename T> 
-	T distance2(
-		const detail::tvec2<T>& p0, 
-		const detail::tvec2<T>& p1);
-
-	//! Returns the squared distance between p0 and p1, i.e., length(p0 - p1).
-	//! From GLM_GTX_norm extension.
-	template <typename T>
-	T distance2(
-		const detail::tvec3<T>& p0,
-		const detail::tvec3<T>& p1);
-
-	//! Returns the squared distance between p0 and p1, i.e., length(p0 - p1).
-	//! From GLM_GTX_norm extension.
-	template <typename T>
-	T distance2(
-		const detail::tvec4<T>& p0, 
-		const detail::tvec4<T>& p1);
+	template <typename genType> 
+	typename genType::value_type distance2(
+		genType const & p0, 
+		genType const & p1);
 
 
 	//! Returns the L1 norm between x and y.
 	//! Returns the L1 norm between x and y.
 	//! From GLM_GTX_norm extension.
 	//! From GLM_GTX_norm extension.
 	template <typename T>
 	template <typename T>
 	T l1Norm(
 	T l1Norm(
-		const detail::tvec3<T>& x,
-		const detail::tvec3<T>& y);
+		detail::tvec3<T> const & x,
+		detail::tvec3<T> const & y);
 		
 		
 	//! Returns the L1 norm of v.
 	//! Returns the L1 norm of v.
 	//! From GLM_GTX_norm extension.
 	//! From GLM_GTX_norm extension.
 	template <typename T> 
 	template <typename T> 
 	T l1Norm(
 	T l1Norm(
-		const detail::tvec3<T>& v);
+		detail::tvec3<T> const & v);
 		
 		
 	//! Returns the L2 norm between x and y.
 	//! Returns the L2 norm between x and y.
 	//! From GLM_GTX_norm extension.
 	//! From GLM_GTX_norm extension.
 	template <typename T> 
 	template <typename T> 
 	T l2Norm(
 	T l2Norm(
-		const detail::tvec3<T>& x, 
-		const detail::tvec3<T>& y);
+		detail::tvec3<T> const & x, 
+		detail::tvec3<T> const & y);
 		
 		
 	//! Returns the L2 norm of v.
 	//! Returns the L2 norm of v.
 	//! From GLM_GTX_norm extension.
 	//! From GLM_GTX_norm extension.
 	template <typename T> 
 	template <typename T> 
 	T l2Norm(
 	T l2Norm(
-		const detail::tvec3<T>& x);
+		detail::tvec3<T> const & x);
 		
 		
 	//! Returns the L norm between x and y.
 	//! Returns the L norm between x and y.
 	//! From GLM_GTX_norm extension.
 	//! From GLM_GTX_norm extension.
 	template <typename T> 
 	template <typename T> 
 	T lxNorm(
 	T lxNorm(
-		const detail::tvec3<T>& x,
-		const detail::tvec3<T>& y,
+		detail::tvec3<T> const & x,
+		detail::tvec3<T> const & y,
 		unsigned int Depth);
 		unsigned int Depth);
 
 
 	//! Returns the L norm of v.
 	//! Returns the L norm of v.
 	//! From GLM_GTX_norm extension.
 	//! From GLM_GTX_norm extension.
 	template <typename T>
 	template <typename T>
 	T lxNorm(
 	T lxNorm(
-		const detail::tvec3<T>& x,
+		detail::tvec3<T> const & x,
 		unsigned int Depth);
 		unsigned int Depth);
 
 
 	/// @}
 	/// @}

+ 144 - 114
glm/gtx/norm.inl

@@ -7,120 +7,150 @@
 // File    : glm/gtx/norm.inl
 // File    : glm/gtx/norm.inl
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 
-namespace glm{
-
-template <typename T>
-GLM_FUNC_QUALIFIER T length2(
-	const T x)
-{
-    return x * x;
-}
-
-template <typename T>
-GLM_FUNC_QUALIFIER T length2(
-	const detail::tvec2<T>& x)
-{
-    return dot(x, x);
-}
-
-template <typename T>
-GLM_FUNC_QUALIFIER T length2(
-	const detail::tvec3<T>& x)
-{
-    return dot(x, x);
-}
-
-template <typename T>
-GLM_FUNC_QUALIFIER T length2(
-	const detail::tvec4<T>& x)
-{
-    return dot(x, x);
-}
-
-template <typename T> 
-GLM_FUNC_QUALIFIER T length2(
-	const detail::tquat<T>& q)
-{
-    return q.x * q.x + q.y * q.y + q.z * q.z + q.w * q.w;
-}
-
-template <typename T> 
-T distance2(
-	const T p0, 
-	const T p1)
-{
-	return length2(p1 - p0);
-}
-
-template <typename T> 
-T distance2(
-	const detail::tvec2<T>& p0, 
-	const detail::tvec2<T>& p1)
-{
-	return length2(p1 - p0);
-}
-
-template <typename T> 
-T distance2(
-	const detail::tvec3<T>& p0, 
-	const detail::tvec3<T>& p1)
-{
-	return length2(p1 - p0);
-}
-
-template <typename T>
-T distance2(
-	const detail::tvec4<T>& p0, 
-	const detail::tvec4<T>& p1)
-{
-	return length2(p1 - p0);
-}
-
-template <typename T> 
-GLM_FUNC_QUALIFIER T l1Norm(
-	const detail::tvec3<T>& a, 
-	const detail::tvec3<T>& b)
-{
-    return abs(b.x - a.x) + abs(b.y - a.y) + abs(b.z - a.z);
-}
-
-template <typename T> 
-GLM_FUNC_QUALIFIER T l1Norm(
-	const detail::tvec3<T>& v)
-{
-    return abs(v.x) + abs(v.y) + abs(v.z);
-}
-
-template <typename T> 
-GLM_FUNC_QUALIFIER T l2Norm(
-	const detail::tvec3<T>& a, 
-	const detail::tvec3<T>& b)
-{
-    return length(b - a);
-}
-
-template <typename T> 
-GLM_FUNC_QUALIFIER T l2Norm(
-	const detail::tvec3<T>& v)
-{
-    return length(v);
-}
-
-template <typename T> 
-GLM_FUNC_QUALIFIER T lxNorm(
-	const detail::tvec3<T>& x, 
-	const detail::tvec3<T>& y, 
-	unsigned int Depth)
-{
-	return pow(pow(y.x - x.x, T(Depth)) + pow(y.y - x.y, T(Depth)) + pow(y.z - x.z, T(Depth)), T(1) / T(Depth));
-}
-
-template <typename T> 
-GLM_FUNC_QUALIFIER T lxNorm(
-	const detail::tvec3<T>& v, 
-	unsigned int Depth)
+namespace glm
 {
 {
-	return pow(pow(v.x, T(Depth)) + pow(v.y, T(Depth)) + pow(v.z, T(Depth)), T(1) / T(Depth));
-}
+	template <typename T>
+	GLM_FUNC_QUALIFIER T length2
+	(
+		T const & x
+	)
+	{
+		return x * x;
+	}
+
+	template <typename T>
+	GLM_FUNC_QUALIFIER T length2
+	(
+		detail::tvec2<T> const & x
+	)
+	{
+		return dot(x, x);
+	}
+
+	template <typename T>
+	GLM_FUNC_QUALIFIER T length2
+	(
+		detail::tvec3<T> const & x
+	)
+	{
+		return dot(x, x);
+	}
+
+	template <typename T>
+	GLM_FUNC_QUALIFIER T length2
+	(
+		detail::tvec4<T> const & x
+	)
+	{
+		return dot(x, x);
+	}
+
+	template <typename T> 
+	GLM_FUNC_QUALIFIER T length2
+	(
+		detail::tquat<T> const & q
+	)
+	{
+		return q.x * q.x + q.y * q.y + q.z * q.z + q.w * q.w;
+	}
+
+	template <typename T> 
+	GLM_FUNC_QUALIFIER T distance2
+	(
+		T const & p0, 
+		T const & p1
+	)
+	{
+		return length2(p1 - p0);
+	}
+
+	template <typename T> 
+	GLM_FUNC_QUALIFIER T distance2
+	(
+		detail::tvec2<T> const & p0, 
+		detail::tvec2<T> const & p1
+	)
+	{
+		return length2(p1 - p0);
+	}
+
+	template <typename T> 
+	GLM_FUNC_QUALIFIER T distance2
+	(
+		detail::tvec3<T> const & p0, 
+		detail::tvec3<T> const & p1
+	)
+	{
+		return length2(p1 - p0);
+	}
+
+	template <typename T>
+	GLM_FUNC_QUALIFIER T distance2
+	(
+		detail::tvec4<T> const & p0, 
+		detail::tvec4<T> const & p1
+	)
+	{
+		return length2(p1 - p0);
+	}
+
+	template <typename T> 
+	GLM_FUNC_QUALIFIER T l1Norm
+	(
+		detail::tvec3<T> const & a, 
+		detail::tvec3<T> const & b
+	)
+	{
+		return abs(b.x - a.x) + abs(b.y - a.y) + abs(b.z - a.z);
+	}
+
+	template <typename T> 
+	GLM_FUNC_QUALIFIER T l1Norm
+	(
+		detail::tvec3<T> const & v
+	)
+	{
+		return abs(v.x) + abs(v.y) + abs(v.z);
+	}
+
+	template <typename T> 
+	GLM_FUNC_QUALIFIER T l2Norm
+	(
+		detail::tvec3<T> const & a, 
+		detail::tvec3<T> const & b
+	)
+	{
+		return length(b - a);
+	}
+
+	template <typename T> 
+	GLM_FUNC_QUALIFIER T l2Norm
+	(
+		detail::tvec3<T> const & v
+	)
+	{
+		return length(v);
+	}
+
+	template <typename T> 
+	GLM_FUNC_QUALIFIER T lxNorm
+	(
+		detail::tvec3<T> const & x, 
+		detail::tvec3<T> const & y, 
+		unsigned int Depth
+	)
+	{
+		return pow(pow(y.x - x.x, T(Depth)) + pow(y.y - x.y, T(Depth)) + pow(y.z - x.z, T(Depth)), T(1) / T(Depth));
+	}
+
+	template <typename T> 
+	GLM_FUNC_QUALIFIER T lxNorm
+	(
+		detail::tvec3<T> const & v, 
+		unsigned int Depth
+	)
+	{
+		return pow(pow(v.x, T(Depth)) + pow(v.y, T(Depth)) + pow(v.z, T(Depth)), T(1) / T(Depth));
+	}
 
 
 }//namespace glm
 }//namespace glm

+ 11 - 12
glm/gtx/normal.inl

@@ -7,17 +7,16 @@
 // File    : glm/gtx/normal.inl
 // File    : glm/gtx/normal.inl
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 
-namespace glm{
-
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tvec3<T> triangleNormal
-(
-    detail::tvec3<T> const & p1, 
-    detail::tvec3<T> const & p2, 
-    detail::tvec3<T> const & p3
-)
+namespace glm
 {
 {
-    return normalize(cross(p1 - p2, p1 - p3));
-}
-
+	template <typename T> 
+	GLM_FUNC_QUALIFIER detail::tvec3<T> triangleNormal
+	(
+		detail::tvec3<T> const & p1, 
+		detail::tvec3<T> const & p2, 
+		detail::tvec3<T> const & p3
+	)
+	{
+		return normalize(cross(p1 - p2, p1 - p3));
+	}
 }//namespace glm
 }//namespace glm

+ 97 - 98
glm/gtx/normalize_dot.inl

@@ -7,110 +7,109 @@
 // File    : glm/gtx/normalize_dot.inl
 // File    : glm/gtx/normalize_dot.inl
 //////////////////////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////////////
 
 
-namespace glm{
-
-template <typename genType> 
-GLM_FUNC_QUALIFIER genType normalizeDot
-(
-	genType const & x, 
-	genType const & y
-)
+namespace glm
 {
 {
-	return 
-		glm::dot(x, y) * 
-		glm::inversesqrt(glm::dot(x, x) * 
-		glm::dot(y, y));
-}
+	template <typename genType> 
+	GLM_FUNC_QUALIFIER genType normalizeDot
+	(
+		genType const & x, 
+		genType const & y
+	)
+	{
+		return 
+			glm::dot(x, y) * 
+			glm::inversesqrt(glm::dot(x, x) * 
+			glm::dot(y, y));
+	}
 
 
-template <typename valType> 
-GLM_FUNC_QUALIFIER valType normalizeDot
-(
-	detail::tvec2<valType> const & x, 
-	detail::tvec2<valType> const & y
-)
-{
-	return 
-		glm::dot(x, y) * 
-		glm::inversesqrt(glm::dot(x, x) * 
-		glm::dot(y, y));
-}
+	template <typename valType> 
+	GLM_FUNC_QUALIFIER valType normalizeDot
+	(
+		detail::tvec2<valType> const & x, 
+		detail::tvec2<valType> const & y
+	)
+	{
+		return 
+			glm::dot(x, y) * 
+			glm::inversesqrt(glm::dot(x, x) * 
+			glm::dot(y, y));
+	}
 
 
-template <typename valType> 
-GLM_FUNC_QUALIFIER valType normalizeDot
-(
-	detail::tvec3<valType> const & x, 
-	detail::tvec3<valType> const & y
-)
-{
-	return 
-		glm::dot(x, y) * 
-		glm::inversesqrt(glm::dot(x, x) * 
-		glm::dot(y, y));
-}
+	template <typename valType> 
+	GLM_FUNC_QUALIFIER valType normalizeDot
+	(
+		detail::tvec3<valType> const & x, 
+		detail::tvec3<valType> const & y
+	)
+	{
+		return 
+			glm::dot(x, y) * 
+			glm::inversesqrt(glm::dot(x, x) * 
+			glm::dot(y, y));
+	}
 
 
-template <typename valType> 
-GLM_FUNC_QUALIFIER valType normalizeDot
-(
-	detail::tvec4<valType> const & x, 
-	detail::tvec4<valType> const & y
-)
-{
-	return 
-		glm::dot(x, y) * 
-		glm::inversesqrt(glm::dot(x, x) * 
-		glm::dot(y, y));
-}
+	template <typename valType> 
+	GLM_FUNC_QUALIFIER valType normalizeDot
+	(
+		detail::tvec4<valType> const & x, 
+		detail::tvec4<valType> const & y
+	)
+	{
+		return 
+			glm::dot(x, y) * 
+			glm::inversesqrt(glm::dot(x, x) * 
+			glm::dot(y, y));
+	}
 
 
-template <typename genType> 
-GLM_FUNC_QUALIFIER genType fastNormalizeDot
-(
-	genType const & x, 
-	genType const & y
-)
-{
-	return 
-		glm::dot(x, y) * 
-		fastInverseSqrt(glm::dot(x, x) * 
-		glm::dot(y, y));
-}
+	template <typename genType> 
+	GLM_FUNC_QUALIFIER genType fastNormalizeDot
+	(
+		genType const & x, 
+		genType const & y
+	)
+	{
+		return 
+			glm::dot(x, y) * 
+			fastInverseSqrt(glm::dot(x, x) * 
+			glm::dot(y, y));
+	}
 
 
-template <typename valType> 
-GLM_FUNC_QUALIFIER valType fastNormalizeDot
-(
-	detail::tvec2<valType> const & x, 
-	detail::tvec2<valType> const & y
-)
-{
-	return 
-		glm::dot(x, y) * 
-		fastInverseSqrt(glm::dot(x, x) * 
-		glm::dot(y, y));
-}
-
-template <typename valType> 
-GLM_FUNC_QUALIFIER valType fastNormalizeDot
-(
-	detail::tvec3<valType> const & x, 
-	detail::tvec3<valType> const & y
-)
-{
-	return 
-		glm::dot(x, y) * 
-		fastInverseSqrt(glm::dot(x, x) * 
-		glm::dot(y, y));
-}
+	template <typename valType> 
+	GLM_FUNC_QUALIFIER valType fastNormalizeDot
+	(
+		detail::tvec2<valType> const & x, 
+		detail::tvec2<valType> const & y
+	)
+	{
+		return 
+			glm::dot(x, y) * 
+			fastInverseSqrt(glm::dot(x, x) * 
+			glm::dot(y, y));
+	}
 
 
-template <typename valType> 
-GLM_FUNC_QUALIFIER valType fastNormalizeDot
-(
-	detail::tvec4<valType> const & x, 
-	detail::tvec4<valType> const & y
-)
-{
-	return 
-		glm::dot(x, y) * 
-		fastInverseSqrt(glm::dot(x, x) * 
-		glm::dot(y, y));
-}
+	template <typename valType> 
+	GLM_FUNC_QUALIFIER valType fastNormalizeDot
+	(
+		detail::tvec3<valType> const & x, 
+		detail::tvec3<valType> const & y
+	)
+	{
+		return 
+			glm::dot(x, y) * 
+			fastInverseSqrt(glm::dot(x, x) * 
+			glm::dot(y, y));
+	}
 
 
+	template <typename valType> 
+	GLM_FUNC_QUALIFIER valType fastNormalizeDot
+	(
+		detail::tvec4<valType> const & x, 
+		detail::tvec4<valType> const & y
+	)
+	{
+		return 
+			glm::dot(x, y) * 
+			fastInverseSqrt(glm::dot(x, x) * 
+			glm::dot(y, y));
+	}
 }//namespace glm
 }//namespace glm

+ 47 - 48
glm/gtx/optimum_pow.inl

@@ -7,53 +7,52 @@
 // File    : glm/gtx/optimum_pow.inl
 // File    : glm/gtx/optimum_pow.inl
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 
-namespace glm{
-
-template <typename genType> 
-GLM_FUNC_QUALIFIER genType pow2(const genType& x)
-{
-    return x * x;
-}
-
-template <typename genType> 
-GLM_FUNC_QUALIFIER genType pow3(const genType& x)
-{
-    return x * x * x;
-}
-
-template <typename genType> 
-GLM_FUNC_QUALIFIER genType pow4(const genType& x)
-{
-    return x * x * x * x;
-}
-
-GLM_FUNC_QUALIFIER bool powOfTwo(int x)
+namespace glm
 {
 {
-    return !(x & (x - 1));
-}
-
-GLM_FUNC_QUALIFIER detail::tvec2<bool> powOfTwo(const detail::tvec2<int>& x)
-{
-    return detail::tvec2<bool>(
-        powOfTwo(x.x),
-        powOfTwo(x.y));
-}
-
-GLM_FUNC_QUALIFIER detail::tvec3<bool> powOfTwo(const detail::tvec3<int>& x)
-{
-    return detail::tvec3<bool>(
-        powOfTwo(x.x),
-        powOfTwo(x.y),
-        powOfTwo(x.z));
-}
-
-GLM_FUNC_QUALIFIER detail::tvec4<bool> powOfTwo(const detail::tvec4<int>& x)
-{
-    return detail::tvec4<bool>(
-        powOfTwo(x.x),
-        powOfTwo(x.y),
-        powOfTwo(x.z),
-        powOfTwo(x.w));
-}
-
+	template <typename genType> 
+	GLM_FUNC_QUALIFIER genType pow2(const genType& x)
+	{
+		return x * x;
+	}
+
+	template <typename genType> 
+	GLM_FUNC_QUALIFIER genType pow3(const genType& x)
+	{
+		return x * x * x;
+	}
+
+	template <typename genType> 
+	GLM_FUNC_QUALIFIER genType pow4(const genType& x)
+	{
+		return x * x * x * x;
+	}
+
+	GLM_FUNC_QUALIFIER bool powOfTwo(int x)
+	{
+		return !(x & (x - 1));
+	}
+
+	GLM_FUNC_QUALIFIER detail::tvec2<bool> powOfTwo(const detail::tvec2<int>& x)
+	{
+		return detail::tvec2<bool>(
+			powOfTwo(x.x),
+			powOfTwo(x.y));
+	}
+
+	GLM_FUNC_QUALIFIER detail::tvec3<bool> powOfTwo(const detail::tvec3<int>& x)
+	{
+		return detail::tvec3<bool>(
+			powOfTwo(x.x),
+			powOfTwo(x.y),
+			powOfTwo(x.z));
+	}
+
+	GLM_FUNC_QUALIFIER detail::tvec4<bool> powOfTwo(const detail::tvec4<int>& x)
+	{
+		return detail::tvec4<bool>(
+			powOfTwo(x.x),
+			powOfTwo(x.y),
+			powOfTwo(x.z),
+			powOfTwo(x.w));
+	}
 }//namespace glm
 }//namespace glm

+ 32 - 33
glm/gtx/orthonormalize.inl

@@ -7,38 +7,37 @@
 // File    : glm/gtx/orthonormalize.inl
 // File    : glm/gtx/orthonormalize.inl
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 
-namespace glm{
-
-template <typename T>
-GLM_FUNC_QUALIFIER detail::tmat3x3<T> orthonormalize
-(
-	const detail::tmat3x3<T>& m
-)
-{
-    detail::tmat3x3<T> r = m;
-
-    r[0] = normalize(r[0]);
-
-	float d0 = dot(r[0], r[1]);
-	r[1] -= r[0] * d0;
-	r[1] = normalize(r[1]);
-
-	float d1 = dot(r[1], r[2]);
-	d0 = dot(r[0], r[2]);
-	r[2] -= r[0] * d0 + r[1] * d1;
-	r[2] = normalize(r[2]);
-
-    return r;
-}
-
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tvec3<T> orthonormalize
-(
-	const detail::tvec3<T>& x, 
-	const detail::tvec3<T>& y
-)
+namespace glm
 {
 {
-    return normalize(x - y * dot(y, x));
-}
-
+	template <typename T>
+	GLM_FUNC_QUALIFIER detail::tmat3x3<T> orthonormalize
+	(
+		const detail::tmat3x3<T>& m
+	)
+	{
+		detail::tmat3x3<T> r = m;
+
+		r[0] = normalize(r[0]);
+
+		float d0 = dot(r[0], r[1]);
+		r[1] -= r[0] * d0;
+		r[1] = normalize(r[1]);
+
+		float d1 = dot(r[1], r[2]);
+		d0 = dot(r[0], r[2]);
+		r[2] -= r[0] * d0 + r[1] * d1;
+		r[2] = normalize(r[2]);
+
+		return r;
+	}
+
+	template <typename T> 
+	GLM_FUNC_QUALIFIER detail::tvec3<T> orthonormalize
+	(
+		const detail::tvec3<T>& x, 
+		const detail::tvec3<T>& y
+	)
+	{
+		return normalize(x - y * dot(y, x));
+	}
 }//namespace glm
 }//namespace glm

+ 4 - 18
glm/gtx/perpendicular.hpp

@@ -54,24 +54,10 @@ namespace glm
 
 
 	//! Projects x a perpendicular axis of Normal.
 	//! Projects x a perpendicular axis of Normal.
 	//! From GLM_GTX_perpendicular extension.
 	//! From GLM_GTX_perpendicular extension.
-	template <typename T> 
-	detail::tvec2<T> perp(
-		detail::tvec2<T> const & x, 
-		detail::tvec2<T> const & Normal);
-
-    //! Projects x a perpendicular axis of Normal.
-	//! From GLM_GTX_perpendicular extension.
-	template <typename T> 
-	detail::tvec3<T> perp(
-		detail::tvec3<T> const & x, 
-		detail::tvec3<T> const & Normal);
-
-    //! Projects x a perpendicular axis of Normal.
-	//! From GLM_GTX_perpendicular extension.
-	template <typename T> 
-	detail::tvec4<T> perp(
-		detail::tvec4<T> const & x, 
-		detail::tvec4<T> const & Normal);
+	template <typename vecType> 
+	vecType perp(
+		vecType const & x, 
+		vecType const & Normal);
 
 
 	/// @}
 	/// @}
 }//namespace glm
 }//namespace glm

+ 10 - 25
glm/gtx/perpendicular.inl

@@ -7,30 +7,15 @@
 // File    : glm/gtx/perpendicular.inl
 // File    : glm/gtx/perpendicular.inl
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 
-namespace glm{
-
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tvec2<T> perp(
-	detail::tvec2<T> const & x, 
-	detail::tvec2<T> const & Normal)
-{
-    return x - proj(x, Normal);
-}
-
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tvec3<T> perp(
-	detail::tvec3<T> const & x, 
-	detail::tvec3<T> const & Normal)
+namespace glm
 {
 {
-    return x - proj(x, Normal);
-}
-
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tvec4<T> perp(
-	detail::tvec4<T> const & x, 
-	detail::tvec4<T> const & Normal)
-{
-    return x - proj(x, Normal);
-}
-
+	template <typename vecType> 
+	GLM_FUNC_QUALIFIER vecType perp
+	(
+		vecType const & x, 
+		vecType const & Normal
+	)
+	{
+		return x - proj(x, Normal);
+	}
 }//namespace glm
 }//namespace glm

+ 4 - 2
glm/gtx/polar_coordinates.hpp

@@ -53,12 +53,14 @@ namespace glm
 	//! Convert Euclidean to Polar coordinates, x is the xz distance, y, the latitude and z the longitude.
 	//! Convert Euclidean to Polar coordinates, x is the xz distance, y, the latitude and z the longitude.
 	//! From GLM_GTX_polar_coordinates extension.
 	//! From GLM_GTX_polar_coordinates extension.
 	template <typename T> 
 	template <typename T> 
-	detail::tvec3<T> polar(const detail::tvec3<T>& euclidean);
+	detail::tvec3<T> polar(
+		detail::tvec3<T> const & euclidean);
 
 
 	//! Convert Polar to Euclidean coordinates.
 	//! Convert Polar to Euclidean coordinates.
 	//! From GLM_GTX_polar_coordinates extension.
 	//! From GLM_GTX_polar_coordinates extension.
 	template <typename T> 
 	template <typename T> 
-	detail::tvec3<T> euclidean(const detail::tvec3<T>& polar);
+	detail::tvec3<T> euclidean(
+		detail::tvec3<T> const & polar);
 
 
 	/// @}
 	/// @}
 }//namespace glm
 }//namespace glm

+ 8 - 4
glm/gtx/polar_coordinates.inl

@@ -10,8 +10,10 @@
 namespace glm
 namespace glm
 {
 {
 	template <typename T> 
 	template <typename T> 
-	GLM_FUNC_QUALIFIER detail::tvec3<T> polar(
-		const detail::tvec3<T>& euclidean)
+	GLM_FUNC_QUALIFIER detail::tvec3<T> polar
+	(
+		detail::tvec3<T> const & euclidean
+	)
 	{
 	{
 		T length = length(euclidean);
 		T length = length(euclidean);
 		detail::tvec3<T> tmp = euclidean / length;
 		detail::tvec3<T> tmp = euclidean / length;
@@ -24,8 +26,10 @@ namespace glm
 	}
 	}
 
 
 	template <typename T> 
 	template <typename T> 
-	GLM_FUNC_QUALIFIER detail::tvec3<T> euclidean(
-		const detail::tvec3<T>& polar)
+	GLM_FUNC_QUALIFIER detail::tvec3<T> euclidean
+	(
+		detail::tvec3<T> const & polar
+	)
 	{
 	{
 		T latitude = radians(polar.x);
 		T latitude = radians(polar.x);
 		T longitude = radians(polar.y);
 		T longitude = radians(polar.y);

+ 4 - 18
glm/gtx/projection.hpp

@@ -52,24 +52,10 @@ namespace glm
 
 
 	//! Projects x on Normal.
 	//! Projects x on Normal.
 	//! From GLM_GTX_projection extension.
 	//! From GLM_GTX_projection extension.
-	template <typename T> 
-	detail::tvec2<T> proj(
-		detail::tvec2<T> const & x, 
-		detail::tvec2<T> const & Normal);
-		
-	//! Projects x on Normal.
-	//! From GLM_GTX_projection extension.
-	template <typename T> 
-	detail::tvec3<T> proj(
-		detail::tvec3<T> const & x, 
-		detail::tvec3<T> const & Normal);
-
-	//! Projects x on Normal.
-	//! From GLM_GTX_projection extension.
-	template <typename T> 
-	detail::tvec4<T> proj(
-		detail::tvec4<T> const & x, 
-		detail::tvec4<T> const & Normal);
+	template <typename vecType> 
+	vecType proj(
+		vecType const & x, 
+		vecType const & Normal);
 
 
 	/// @}
 	/// @}
 }//namespace glm
 }//namespace glm

+ 10 - 25
glm/gtx/projection.inl

@@ -7,30 +7,15 @@
 // File    : glm/gtx/projection.inl
 // File    : glm/gtx/projection.inl
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 
-namespace glm{
-
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tvec2<T> proj(
-	detail::tvec2<T> const & x, 
-	detail::tvec2<T> const & Normal)
-{
-	return glm::dot(x, Normal) / glm::dot(Normal, Normal) * Normal;
-}
-
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tvec3<T> proj(
-	detail::tvec3<T> const & x, 
-	detail::tvec3<T> const & Normal)
+namespace glm
 {
 {
-	return dot(x, Normal) / glm::dot(Normal, Normal) * Normal;
-}
-
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tvec4<T> proj(
-	detail::tvec4<T> const & x, 
-	detail::tvec4<T> const & Normal)
-{
-	return glm::dot(x, Normal) / glm::dot(Normal, Normal) * Normal;
-}
-
+	template <typename vecType> 
+	GLM_FUNC_QUALIFIER vecType proj
+	(
+		vecType const & x, 
+		vecType const & Normal
+	)
+	{
+		return glm::dot(x, Normal) / glm::dot(Normal, Normal) * Normal;
+	}
 }//namespace glm
 }//namespace glm

+ 260 - 261
glm/gtx/quaternion.inl

@@ -9,291 +9,290 @@
 
 
 #include <limits>
 #include <limits>
 
 
-namespace glm{
-
-template <typename valType> 
-GLM_FUNC_QUALIFIER detail::tvec3<valType> cross
-(
-	detail::tvec3<valType> const & v, 
-	detail::tquat<valType> const & q
-)
+namespace glm
 {
 {
-	return inverse(q) * v;
-}
+	template <typename valType> 
+	GLM_FUNC_QUALIFIER detail::tvec3<valType> cross
+	(
+		detail::tvec3<valType> const & v, 
+		detail::tquat<valType> const & q
+	)
+	{
+		return inverse(q) * v;
+	}
 
 
-template <typename valType> 
-GLM_FUNC_QUALIFIER detail::tvec3<valType> cross
-(
-	detail::tquat<valType> const & q, 
-	detail::tvec3<valType> const & v
-)
-{
-	return q * v;
-}
+	template <typename valType> 
+	GLM_FUNC_QUALIFIER detail::tvec3<valType> cross
+	(
+		detail::tquat<valType> const & q, 
+		detail::tvec3<valType> const & v
+	)
+	{
+		return q * v;
+	}
 
 
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tquat<T> squad
-(
-	detail::tquat<T> const & q1, 
-	detail::tquat<T> const & q2, 
-	detail::tquat<T> const & s1, 
-	detail::tquat<T> const & s2, 
-	T const & h)
-{
-    return mix(mix(q1, q2, h), mix(s1, s2, h), T(2) * h (T(1) - h));
-}
+	template <typename T> 
+	GLM_FUNC_QUALIFIER detail::tquat<T> squad
+	(
+		detail::tquat<T> const & q1, 
+		detail::tquat<T> const & q2, 
+		detail::tquat<T> const & s1, 
+		detail::tquat<T> const & s2, 
+		T const & h)
+	{
+		return mix(mix(q1, q2, h), mix(s1, s2, h), T(2) * h (T(1) - h));
+	}
 
 
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tquat<T> intermediate
-(
-	detail::tquat<T> const & prev, 
-	detail::tquat<T> const & curr, 
-	detail::tquat<T> const & next
-)
-{
-    detail::tquat<T> invQuat = inverse(curr);
-    return ext((log(next + invQuat) + log(prev + invQuat)) / T(-4)) * curr;
-}
+	template <typename T> 
+	GLM_FUNC_QUALIFIER detail::tquat<T> intermediate
+	(
+		detail::tquat<T> const & prev, 
+		detail::tquat<T> const & curr, 
+		detail::tquat<T> const & next
+	)
+	{
+		detail::tquat<T> invQuat = inverse(curr);
+		return ext((log(next + invQuat) + log(prev + invQuat)) / T(-4)) * curr;
+	}
 
 
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tquat<T> exp
-(
-	detail::tquat<T> const & q, 
-	T const & exponent
-)
-{
-    detail::tvec3<T> u(q.x, q.y, q.z);
-	float a = glm::length(u);
-    detail::tvec3<T> v(u / a);
-    return detail::tquat<T>(cos(a), sin(a) * v);
-}
+	template <typename T> 
+	GLM_FUNC_QUALIFIER detail::tquat<T> exp
+	(
+		detail::tquat<T> const & q, 
+		T const & exponent
+	)
+	{
+		detail::tvec3<T> u(q.x, q.y, q.z);
+		float a = glm::length(u);
+		detail::tvec3<T> v(u / a);
+		return detail::tquat<T>(cos(a), sin(a) * v);
+	}
 
 
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tquat<T> log
-(
-	detail::tquat<T> const & q
-)
-{
-    if((q.x == T(0)) && (q.y == T(0)) && (q.z == T(0)))
-    {
-        if(q.w > T(0))
-            return detail::tquat<T>(log(q.w), T(0), T(0), T(0));
-        else if(q.w < T(0))
-            return detail::tquat<T>(log(-q.w), T(3.1415926535897932384626433832795), T(0),T(0));
-        else
-            return detail::tquat<T>(std::numeric_limits<T>::infinity(), std::numeric_limits<T>::infinity(), std::numeric_limits<T>::infinity(), std::numeric_limits<T>::infinity());
-    } 
-    else 
-    {
-        T Vec3Len = sqrt(q.x * q.x + q.y * q.y + q.z * q.z);
-        T QuatLen = sqrt(Vec3Len * Vec3Len + q.w * q.w);
-        T t = atan(Vec3Len, T(q.w)) / Vec3Len;
-        return detail::tquat<T>(t * q.x, t * q.y, t * q.z, log(QuatLen));
-    }
-}
+	template <typename T> 
+	GLM_FUNC_QUALIFIER detail::tquat<T> log
+	(
+		detail::tquat<T> const & q
+	)
+	{
+		if((q.x == T(0)) && (q.y == T(0)) && (q.z == T(0)))
+		{
+			if(q.w > T(0))
+				return detail::tquat<T>(log(q.w), T(0), T(0), T(0));
+			else if(q.w < T(0))
+				return detail::tquat<T>(log(-q.w), T(3.1415926535897932384626433832795), T(0),T(0));
+			else
+				return detail::tquat<T>(std::numeric_limits<T>::infinity(), std::numeric_limits<T>::infinity(), std::numeric_limits<T>::infinity(), std::numeric_limits<T>::infinity());
+		} 
+		else 
+		{
+			T Vec3Len = sqrt(q.x * q.x + q.y * q.y + q.z * q.z);
+			T QuatLen = sqrt(Vec3Len * Vec3Len + q.w * q.w);
+			T t = atan(Vec3Len, T(q.w)) / Vec3Len;
+			return detail::tquat<T>(t * q.x, t * q.y, t * q.z, log(QuatLen));
+		}
+	}
 
 
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tquat<T> pow
-(
-	detail::tquat<T> const & x, 
-	T const & y
-)
-{
-    if(abs(x.w) > T(0.9999))
-        return x;
-    float Angle = acos(y);
-    float NewAngle = Angle * y;
-    float Div = sin(NewAngle) / sin(Angle);
-    return detail::tquat<T>(
-        cos(NewAngle),
-        x.x * Div,
-        x.y * Div,
-        x.z * Div);
-}
+	template <typename T> 
+	GLM_FUNC_QUALIFIER detail::tquat<T> pow
+	(
+		detail::tquat<T> const & x, 
+		T const & y
+	)
+	{
+		if(abs(x.w) > T(0.9999))
+			return x;
+		float Angle = acos(y);
+		float NewAngle = Angle * y;
+		float Div = sin(NewAngle) / sin(Angle);
+		return detail::tquat<T>(
+			cos(NewAngle),
+			x.x * Div,
+			x.y * Div,
+			x.z * Div);
+	}
 
 
-//template <typename T> 
-//GLM_FUNC_QUALIFIER detail::tquat<T> sqrt
-//(
-//	detail::tquat<T> const & q
-//)
-//{
-//	T q0 = T(1) - dot(q, q);
-//	return T(2) * (T(1) + q0) * q;
-//}
+	//template <typename T> 
+	//GLM_FUNC_QUALIFIER detail::tquat<T> sqrt
+	//(
+	//	detail::tquat<T> const & q
+	//)
+	//{
+	//	T q0 = T(1) - dot(q, q);
+	//	return T(2) * (T(1) + q0) * q;
+	//}
 
 
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tvec3<T> rotate
-(
-	detail::tquat<T> const & q, 
-	detail::tvec3<T> const & v
-)
-{
-	return q * v;
-}
+	template <typename T> 
+	GLM_FUNC_QUALIFIER detail::tvec3<T> rotate
+	(
+		detail::tquat<T> const & q, 
+		detail::tvec3<T> const & v
+	)
+	{
+		return q * v;
+	}
 
 
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tvec4<T> rotate
-(
-	detail::tquat<T> const & q, 
-	detail::tvec4<T> const & v
-)
-{
-    return q * v;
-}
+	template <typename T> 
+	GLM_FUNC_QUALIFIER detail::tvec4<T> rotate
+	(
+		detail::tquat<T> const & q, 
+		detail::tvec4<T> const & v
+	)
+	{
+		return q * v;
+	}
 
 
-template <typename T> 
-GLM_FUNC_QUALIFIER T angle
-(
-	detail::tquat<T> const & x
-)
-{
-    return glm::degrees(acos(x.w) * T(2));
-}
+	template <typename T> 
+	GLM_FUNC_QUALIFIER T angle
+	(
+		detail::tquat<T> const & x
+	)
+	{
+		return glm::degrees(acos(x.w) * T(2));
+	}
 
 
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tvec3<T> axis
-(
-	detail::tquat<T> const & x
-)
-{
-    T tmp1 = T(1) - x.w * x.w;
-    if(tmp1 <= T(0))
-        return detail::tvec3<T>(0, 0, 1);
-    T tmp2 = T(1) / sqrt(tmp1);
-    return detail::tvec3<T>(x.x * tmp2, x.y * tmp2, x.z * tmp2);
-}
+	template <typename T> 
+	GLM_FUNC_QUALIFIER detail::tvec3<T> axis
+	(
+		detail::tquat<T> const & x
+	)
+	{
+		T tmp1 = T(1) - x.w * x.w;
+		if(tmp1 <= T(0))
+			return detail::tvec3<T>(0, 0, 1);
+		T tmp2 = T(1) / sqrt(tmp1);
+		return detail::tvec3<T>(x.x * tmp2, x.y * tmp2, x.z * tmp2);
+	}
 
 
-template <typename valType> 
-GLM_FUNC_QUALIFIER detail::tquat<valType> angleAxis
-(
-	valType const & angle, 
-	valType const & x, 
-	valType const & y, 
-	valType const & z
-)
-{
-    return angleAxis(angle, detail::tvec3<valType>(x, y, z));
-}
+	template <typename valType> 
+	GLM_FUNC_QUALIFIER detail::tquat<valType> angleAxis
+	(
+		valType const & angle, 
+		valType const & x, 
+		valType const & y, 
+		valType const & z
+	)
+	{
+		return angleAxis(angle, detail::tvec3<valType>(x, y, z));
+	}
 
 
-template <typename valType> 
-GLM_FUNC_QUALIFIER detail::tquat<valType> angleAxis
-(
-	valType const & angle, 
-	detail::tvec3<valType> const & v
-)
-{
-    detail::tquat<valType> result;
+	template <typename valType> 
+	GLM_FUNC_QUALIFIER detail::tquat<valType> angleAxis
+	(
+		valType const & angle, 
+		detail::tvec3<valType> const & v
+	)
+	{
+		detail::tquat<valType> result;
 
 
-	valType a = glm::radians(angle);
-    valType s = glm::sin(a * valType(0.5));
+		valType a = glm::radians(angle);
+		valType s = glm::sin(a * valType(0.5));
 
 
-    result.w = glm::cos(a * valType(0.5));
-    result.x = v.x * s;
-    result.y = v.y * s;
-    result.z = v.z * s;
-    return result;
-}
+		result.w = glm::cos(a * valType(0.5));
+		result.x = v.x * s;
+		result.y = v.y * s;
+		result.z = v.z * s;
+		return result;
+	}
 
 
-template <typename T> 
-GLM_FUNC_QUALIFIER T extractRealComponent
-(
-	detail::tquat<T> const & q
-)
-{
-    T w = T(1.0) - q.x * q.x - q.y * q.y - q.z * q.z;
-    if(w < T(0))
-        return T(0);
-    else
-        return -sqrt(w);
-}
-
-template <typename valType> 
-GLM_FUNC_QUALIFIER valType roll
-(
-	detail::tquat<valType> const & q
-)
-{
-	return glm::degrees(atan2(valType(2) * (q.x * q.y + q.w * q.z), q.w * q.w + q.x * q.x - q.y * q.y - q.z * q.z));
-}
+	template <typename T> 
+	GLM_FUNC_QUALIFIER T extractRealComponent
+	(
+		detail::tquat<T> const & q
+	)
+	{
+		T w = T(1.0) - q.x * q.x - q.y * q.y - q.z * q.z;
+		if(w < T(0))
+			return T(0);
+		else
+			return -sqrt(w);
+	}
 
 
-template <typename valType> 
-GLM_FUNC_QUALIFIER valType pitch
-(
-	detail::tquat<valType> const & q
-)
-{
-	return glm::degrees(atan2(valType(2) * (q.y * q.z + q.w * q.x), q.w * q.w - q.x * q.x - q.y * q.y + q.z * q.z));
-}
+	template <typename valType> 
+	GLM_FUNC_QUALIFIER valType roll
+	(
+		detail::tquat<valType> const & q
+	)
+	{
+		return glm::degrees(atan2(valType(2) * (q.x * q.y + q.w * q.z), q.w * q.w + q.x * q.x - q.y * q.y - q.z * q.z));
+	}
 
 
-template <typename valType> 
-GLM_FUNC_QUALIFIER valType yaw
-(
-	detail::tquat<valType> const & q
-)
-{
-	return glm::degrees(asin(valType(-2) * (q.x * q.z - q.w * q.y)));
-}
+	template <typename valType> 
+	GLM_FUNC_QUALIFIER valType pitch
+	(
+		detail::tquat<valType> const & q
+	)
+	{
+		return glm::degrees(atan2(valType(2) * (q.y * q.z + q.w * q.x), q.w * q.w - q.x * q.x - q.y * q.y + q.z * q.z));
+	}
 
 
-template <typename valType> 
-GLM_FUNC_QUALIFIER detail::tvec3<valType> eularAngles
-(
-	detail::tquat<valType> const & x
-)
-{
-    return detail::tvec3<valType>(pitch(x), yaw(x), roll(x));
-}
+	template <typename valType> 
+	GLM_FUNC_QUALIFIER valType yaw
+	(
+		detail::tquat<valType> const & q
+	)
+	{
+		return glm::degrees(asin(valType(-2) * (q.x * q.z - q.w * q.y)));
+	}
 
 
-template <typename T>
-GLM_FUNC_QUALIFIER detail::tquat<T> shortMix
-(
-	detail::tquat<T> const & x, 
-	detail::tquat<T> const & y, 
-	T const & a
-)
-{
-    if(a <= typename detail::tquat<T>::value_type(0)) return x;
-    if(a >= typename detail::tquat<T>::value_type(1)) return y;
+	template <typename valType> 
+	GLM_FUNC_QUALIFIER detail::tvec3<valType> eularAngles
+	(
+		detail::tquat<valType> const & x
+	)
+	{
+		return detail::tvec3<valType>(pitch(x), yaw(x), roll(x));
+	}
 
 
-	T fCos = dot(x, y);
-    detail::tquat<T> y2(y); //BUG!!! tquat<T> y2;
-	if(fCos < T(0))
-    {
-        y2 = -y;
-        fCos = -fCos;
-    }
+	template <typename T>
+	GLM_FUNC_QUALIFIER detail::tquat<T> shortMix
+	(
+		detail::tquat<T> const & x, 
+		detail::tquat<T> const & y, 
+		T const & a
+	)
+	{
+		if(a <= typename detail::tquat<T>::value_type(0)) return x;
+		if(a >= typename detail::tquat<T>::value_type(1)) return y;
 
 
-    //if(fCos > 1.0f) // problem
-	T k0, k1;
-	if(fCos > T(0.9999))
-    {
-		k0 = T(1) - a;
-		k1 = T(0) + a; //BUG!!! 1.0f + a;
-    }
-    else
-    {
-		T fSin = sqrt(T(1) - fCos * fCos);
-		T fAngle = atan(fSin, fCos);
-		T fOneOverSin = T(1) / fSin;
-		k0 = sin((T(1) - a) * fAngle) * fOneOverSin;
-		k1 = sin((T(0) + a) * fAngle) * fOneOverSin;
-    }
+		T fCos = dot(x, y);
+		detail::tquat<T> y2(y); //BUG!!! tquat<T> y2;
+		if(fCos < T(0))
+		{
+			y2 = -y;
+			fCos = -fCos;
+		}
 
 
-    return detail::tquat<T>(
-        k0 * x.w + k1 * y2.w,
-        k0 * x.x + k1 * y2.x,
-        k0 * x.y + k1 * y2.y,
-        k0 * x.z + k1 * y2.z);
-}
+		//if(fCos > 1.0f) // problem
+		T k0, k1;
+		if(fCos > T(0.9999))
+		{
+			k0 = T(1) - a;
+			k1 = T(0) + a; //BUG!!! 1.0f + a;
+		}
+		else
+		{
+			T fSin = sqrt(T(1) - fCos * fCos);
+			T fAngle = atan(fSin, fCos);
+			T fOneOverSin = T(1) / fSin;
+			k0 = sin((T(1) - a) * fAngle) * fOneOverSin;
+			k1 = sin((T(0) + a) * fAngle) * fOneOverSin;
+		}
 
 
-template <typename T>
-GLM_FUNC_QUALIFIER detail::tquat<T> fastMix
-(
-	detail::tquat<T> const & x, 
-	detail::tquat<T> const & y, 
-	T const & a
-)
-{
-	return glm::normalize(x * (T(1) - a) + (y * a));
-}
+		return detail::tquat<T>(
+			k0 * x.w + k1 * y2.w,
+			k0 * x.x + k1 * y2.x,
+			k0 * x.y + k1 * y2.y,
+			k0 * x.z + k1 * y2.z);
+	}
 
 
+	template <typename T>
+	GLM_FUNC_QUALIFIER detail::tquat<T> fastMix
+	(
+		detail::tquat<T> const & x, 
+		detail::tquat<T> const & y, 
+		T const & a
+	)
+	{
+		return glm::normalize(x * (T(1) - a) + (y * a));
+	}
 }//namespace glm
 }//namespace glm

+ 172 - 579
glm/gtx/reciprocal.inl

@@ -2,588 +2,181 @@
 // OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
 // OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // Created : 2008-10-09
 // Created : 2008-10-09
-// Updated : 2008-10-09
+// Updated : 2011-10-14
 // Licence : This source is under MIT License
 // Licence : This source is under MIT License
 // File    : glm/gtx/reciprocal.inl
 // File    : glm/gtx/reciprocal.inl
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 
-namespace glm{
-
-// sec
-template <typename genType>
-GLM_FUNC_QUALIFIER genType sec
-(
-	genType const & angle
-)
-{
-	GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'sec' only accept floating-point values");
-
-	return genType(1) / glm::cos(angle);
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec2<valType> sec
-(
-	detail::tvec2<valType> const & angle
-)
-{
-    return detail::tvec2<valType>(
-        sec(angle.x),
-        sec(angle.y));
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec3<valType> sec
-(
-	detail::tvec3<valType> const & angle
-)
-{
-    return detail::tvec3<valType>(
-        sec(angle.x),
-        sec(angle.y),
-        sec(angle.z));
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec4<valType> sec
-(
-	detail::tvec4<valType> const & angle
-)
-{
-    return detail::tvec4<valType>(
-        sec(angle.x),
-        sec(angle.y),
-        sec(angle.z),
-        sec(angle.w));
-}
-
-// csc
-template <typename genType>
-GLM_FUNC_QUALIFIER genType csc
-(
-	genType const & angle
-)
-{
-	GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'csc' only accept floating-point values");
-
-    return genType(1) / glm::sin(angle);
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec2<valType> csc
-(
-	detail::tvec2<valType> const & angle
-)
-{
-    return detail::tvec2<valType>(
-        csc(angle.x),
-        csc(angle.y));
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec3<valType> csc
-(
-	detail::tvec3<valType> const & angle
-)
-{
-    return detail::tvec3<valType>(
-        csc(angle.x),
-        csc(angle.y),
-        csc(angle.z));
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec4<valType> csc
-(	
-	detail::tvec4<valType> const & angle
-)
-{
-    return detail::tvec4<valType>(
-        csc(angle.x),
-        csc(angle.y),
-        csc(angle.z),
-        csc(angle.w));
-}
-
-// cot
-template <typename genType>
-GLM_FUNC_QUALIFIER genType cot
-(
-	genType const & angle
-)
-{
-	GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'cot' only accept floating-point values");
-
-	return genType(1) / glm::tan(angle);
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec2<valType> cot
-(
-	detail::tvec2<valType> const & angle
-)
-{
-    return detail::tvec2<valType>(
-        cot(angle.x),
-        cot(angle.y));
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec3<valType> cot
-(
-	detail::tvec3<valType> const & angle
-)
-{
-    return detail::tvec3<valType>(
-        cot(angle.x),
-        cot(angle.y),
-        cot(angle.z));
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec4<valType> cot
-(
-	detail::tvec4<valType> const & angle
-)
-{
-    return detail::tvec4<valType>(
-        cot(angle.x),
-        cot(angle.y),
-        cot(angle.z),
-        cot(angle.w));
-}
-
-// asec
-template <typename genType>
-GLM_FUNC_QUALIFIER genType asec
-(
-	genType const & x
-)
-{
-	GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'asec' only accept floating-point values");
+#include "../core/_vectorize.hpp"
+
+namespace glm
+{
+	// sec
+	template <typename genType>
+	GLM_FUNC_QUALIFIER genType sec
+	(
+		genType const & angle
+	)
+	{
+		GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'sec' only accept floating-point values");
+
+		return genType(1) / glm::cos(angle);
+	}
+
+	VECTORIZE_VEC(sec)
+
+	// csc
+	template <typename genType>
+	GLM_FUNC_QUALIFIER genType csc
+	(
+		genType const & angle
+	)
+	{
+		GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'csc' only accept floating-point values");
+
+		return genType(1) / glm::sin(angle);
+	}
+
+	VECTORIZE_VEC(csc)
+
+	// cot
+	template <typename genType>
+	GLM_FUNC_QUALIFIER genType cot
+	(
+		genType const & angle
+	)
+	{
+		GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'cot' only accept floating-point values");
+
+		return genType(1) / glm::tan(angle);
+	}
+
+	VECTORIZE_VEC(cot)
+
+	// asec
+	template <typename genType>
+	GLM_FUNC_QUALIFIER genType asec
+	(
+		genType const & x
+	)
+	{
+		GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'asec' only accept floating-point values");
 	
 	
-	return acos(genType(1) / x);
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec2<valType> asec
-(
-	detail::tvec2<valType> const & x
-)
-{
-    return detail::tvec2<valType>(
-        asec(x.x),
-        asec(x.y));
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec3<valType> asec
-(
-	detail::tvec3<valType> const & x
-)
-{
-    return detail::tvec3<valType>(
-        asec(x.x),
-        asec(x.y),
-        asec(x.z));
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec4<valType> asec
-(
-	detail::tvec4<valType> const & x
-)
-{
-    return detail::tvec4<valType>(
-        asec(x.x),
-        asec(x.y),
-        asec(x.z),
-        asec(x.w));
-}
-
-// acsc
-template <typename genType>
-GLM_FUNC_QUALIFIER genType acsc
-(
-	genType const & x
-)
-{
-	GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'acsc' only accept floating-point values");
-
-	return asin(genType(1) / x);
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec2<valType> acsc
-(
-	detail::tvec2<valType> const & x
-)
-{
-    return detail::tvec2<valType>(
-        acsc(x.x),
-        acsc(x.y));
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec3<valType> acsc
-(
-	detail::tvec3<valType> const & x
-)
-{
-    return detail::tvec3<valType>(
-        acsc(x.x),
-        acsc(x.y),
-        acsc(x.z));
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec4<valType> acsc
-(	
-	detail::tvec4<valType> const & x
-)
-{
-    return detail::tvec4<valType>(
-        acsc(x.x),
-        acsc(x.y),
-        acsc(x.z),
-        acsc(x.w));
-}
-
-// acot
-template <typename genType>
-GLM_FUNC_QUALIFIER genType acot
-(
-	genType const & x
-)
-{
-	GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'acot' only accept floating-point values");
-
-	genType const pi_over_2 = genType(3.1415926535897932384626433832795 / 2.0);
-	return pi_over_2 - atan(x);
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec2<valType> acot
-(
-	detail::tvec2<valType> const & x
-)
-{
-    return detail::tvec2<valType>(
-        acot(x.x),
-        acot(x.y));
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec3<valType> acot
-(
-	detail::tvec3<valType> const & x
-)
-{
-    return detail::tvec3<valType>(
-        acot(x.x),
-        acot(x.y),
-        acot(x.z));
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec4<valType> acot
-(
-	detail::tvec4<valType> const & x
-)
-{
-    return detail::tvec4<valType>(
-        acot(x.x),
-        acot(x.y),
-        acot(x.z),
-        acot(x.w));
-}
-
-// sech
-template <typename genType>
-GLM_FUNC_QUALIFIER genType sech
-(
-	genType const & angle
-)
-{
-	GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'sech' only accept floating-point values");
-
-	return genType(1) / glm::cosh(angle);
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec2<valType> sech
-(
-	detail::tvec2<valType> const & angle
-)
-{
-    return detail::tvec2<valType>(
-        sech(angle.x),
-        sech(angle.y));
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec3<valType> sech
-(
-	detail::tvec3<valType> const & angle
-)
-{
-    return detail::tvec3<valType>(
-        sech(angle.x),
-        sech(angle.y),
-        sech(angle.z));
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec4<valType> sech
-(
-	detail::tvec4<valType> const & angle
-)
-{
-    return detail::tvec4<valType>(
-        sech(angle.x),
-        sech(angle.y),
-        sech(angle.z),
-        sech(angle.w));
-}
-
-// csch
-template <typename genType>
-GLM_FUNC_QUALIFIER genType csch
-(
-	genType const & angle
-)
-{
-	GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'csch' only accept floating-point values");
-
-    return genType(1) / glm::sinh(angle);
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec2<valType> csch
-(
-	detail::tvec2<valType> const & angle
-)
-{
-    return detail::tvec2<valType>(
-        csch(angle.x),
-        csch(angle.y));
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec3<valType> csch
-(
-	detail::tvec3<valType> const & angle
-)
-{
-    return detail::tvec3<valType>(
-        csch(angle.x),
-        csch(angle.y),
-        csch(angle.z));
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec4<valType> csch
-(	
-	detail::tvec4<valType> const & angle
-)
-{
-    return detail::tvec4<valType>(
-        csch(angle.x),
-        csch(angle.y),
-        csch(angle.z),
-        csch(angle.w));
-}
-
-// coth
-template <typename genType>
-GLM_FUNC_QUALIFIER genType coth
-(
-	genType const & angle
-)
-{
-	GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'coth' only accept floating-point values");
-
-	return glm::cosh(angle) / glm::sinh(angle);
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec2<valType> coth
-(
-	detail::tvec2<valType> const & angle
-)
-{
-    return detail::tvec2<valType>(
-        coth(angle.x),
-        coth(angle.y));
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec3<valType> coth
-(
-	detail::tvec3<valType> const & angle
-)
-{
-    return detail::tvec3<valType>(
-        coth(angle.x),
-        coth(angle.y),
-        coth(angle.z));
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec4<valType> coth
-(
-	detail::tvec4<valType> const & angle
-)
-{
-    return detail::tvec4<valType>(
-        coth(angle.x),
-        coth(angle.y),
-        coth(angle.z),
-        coth(angle.w));
-}
-
-// asech
-template <typename genType>
-GLM_FUNC_QUALIFIER genType asech
-(
-	genType const & x
-)
-{
-	GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'asech' only accept floating-point values");
-
-	return acosh(genType(1) / x);
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec2<valType> asech
-(
-	detail::tvec2<valType> const & x
-)
-{
-    return detail::tvec2<valType>(
-        asech(x.x),
-        asech(x.y));
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec3<valType> asech
-(
-	detail::tvec3<valType> const & x
-)
-{
-    return detail::tvec3<valType>(
-        asech(x.x),
-        asech(x.y),
-        asech(x.z));
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec4<valType> asech
-(
-	detail::tvec4<valType> const & x
-)
-{
-    return detail::tvec4<valType>(
-        asech(x.x),
-        asech(x.y),
-        asech(x.z),
-        asech(x.w));
-}
-
-// acsch
-template <typename genType>
-GLM_FUNC_QUALIFIER genType acsch
-(
-	genType const & x
-)
-{
-	GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'acsch' only accept floating-point values");
-
-    return asinh(genType(1) / x);
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec2<valType> acsch
-(
-	detail::tvec2<valType> const & x
-)
-{
-    return detail::tvec2<valType>(
-        acsch(x.x),
-        acsch(x.y));
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec3<valType> acsch
-(
-	detail::tvec3<valType> const & x
-)
-{
-    return detail::tvec3<valType>(
-        acsch(x.x),
-        acsch(x.y),
-        acsch(x.z));
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec4<valType> acsch
-(	
-	detail::tvec4<valType> const & x
-)
-{
-    return detail::tvec4<valType>(
-        acsch(x.x),
-        acsch(x.y),
-        acsch(x.z),
-        acsch(x.w));
-}
-
-// acoth
-template <typename genType>
-GLM_FUNC_QUALIFIER genType acoth
-(
-	genType const & x
-)
-{
-	GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'acoth' only accept floating-point values");
-
-	return atanh(genType(1) / x);
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec2<valType> acoth
-(
-	detail::tvec2<valType> const & x
-)
-{
-    return detail::tvec2<valType>(
-        acoth(x.x),
-        acoth(x.y));
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec3<valType> acoth
-(
-	detail::tvec3<valType> const & x
-)
-{
-    return detail::tvec3<valType>(
-        acoth(x.x),
-        acoth(x.y),
-        acoth(x.z));
-}
-
-template <typename valType>
-GLM_FUNC_QUALIFIER detail::tvec4<valType> acoth
-(
-	detail::tvec4<valType> const & x
-)
-{
-    return detail::tvec4<valType>(
-        acoth(x.x),
-        acoth(x.y),
-        acoth(x.z),
-        acoth(x.w));
-}
-
+		return acos(genType(1) / x);
+	}
+
+	VECTORIZE_VEC(asec)
+
+	// acsc
+	template <typename genType>
+	GLM_FUNC_QUALIFIER genType acsc
+	(
+		genType const & x
+	)
+	{
+		GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'acsc' only accept floating-point values");
+
+		return asin(genType(1) / x);
+	}
+
+	VECTORIZE_VEC(acsc)
+
+	// acot
+	template <typename genType>
+	GLM_FUNC_QUALIFIER genType acot
+	(
+		genType const & x
+	)
+	{
+		GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'acot' only accept floating-point values");
+
+		genType const pi_over_2 = genType(3.1415926535897932384626433832795 / 2.0);
+		return pi_over_2 - atan(x);
+	}
+
+	VECTORIZE_VEC(acot)
+
+	// sech
+	template <typename genType>
+	GLM_FUNC_QUALIFIER genType sech
+	(
+		genType const & angle
+	)
+	{
+		GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'sech' only accept floating-point values");
+
+		return genType(1) / glm::cosh(angle);
+	}
+
+	VECTORIZE_VEC(sech)
+
+	// csch
+	template <typename genType>
+	GLM_FUNC_QUALIFIER genType csch
+	(
+		genType const & angle
+	)
+	{
+		GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'csch' only accept floating-point values");
+
+		return genType(1) / glm::sinh(angle);
+	}
+
+	VECTORIZE_VEC(csch)
+
+	// coth
+	template <typename genType>
+	GLM_FUNC_QUALIFIER genType coth
+	(
+		genType const & angle
+	)
+	{
+		GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'coth' only accept floating-point values");
+
+		return glm::cosh(angle) / glm::sinh(angle);
+	}
+
+	VECTORIZE_VEC(coth)
+
+	// asech
+	template <typename genType>
+	GLM_FUNC_QUALIFIER genType asech
+	(
+		genType const & x
+	)
+	{
+		GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'asech' only accept floating-point values");
+
+		return acosh(genType(1) / x);
+	}
+
+	VECTORIZE_VEC(asech)
+
+	// acsch
+	template <typename genType>
+	GLM_FUNC_QUALIFIER genType acsch
+	(
+		genType const & x
+	)
+	{
+		GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'acsch' only accept floating-point values");
+
+		return asinh(genType(1) / x);
+	}
+
+	VECTORIZE_VEC(acsch)
+
+	// acoth
+	template <typename genType>
+	GLM_FUNC_QUALIFIER genType acoth
+	(
+		genType const & x
+	)
+	{
+		GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'acoth' only accept floating-point values");
+
+		return atanh(genType(1) / x);
+	}
+
+	VECTORIZE_VEC(acoth)
 }//namespace glm
 }//namespace glm

+ 144 - 125
glm/gtx/rotate_vector.inl

@@ -7,139 +7,158 @@
 // File    : glm/gtx/rotate_vector.inl
 // File    : glm/gtx/rotate_vector.inl
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 
-namespace glm{
-
-template <typename T>
-GLM_FUNC_QUALIFIER detail::tvec2<T> rotate(
-    detail::tvec2<T> const & v, 
-	T const & angle)
-{
-	detail::tvec2<T> Result;
-	const T Cos = cos(radians(angle));
-    const T Sin = sin(radians(angle));
-	Result.x = v.x * Cos - v.y * Sin;
-	Result.y = v.x * Sin + v.y * Cos;
-	return Result;
-}
-
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tvec3<T> rotate(
-	const detail::tvec3<T> & v, 
-    T const & angle, 
-	const detail::tvec3<T> & normal)
+namespace glm
 {
 {
-	return detail::tmat3x3<T>(glm::rotate(angle, normal)) * v;
-}
-/*
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tvec3<T> rotateGTX(
-    const detail::tvec3<T>& x, 
-    T angle, 
-    const detail::tvec3<T>& normal)
-{
-    const T Cos = cos(radians(angle));
-    const T Sin = sin(radians(angle));
-    return x * Cos + ((x * normal) * (T(1) - Cos)) * normal + cross(x, normal) * Sin;
-}
-*/
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tvec4<T> rotate(
-    detail::tvec4<T> const & v, 
-	T const & angle, 
-    detail::tvec3<T> const & normal)
-{
-	return rotate(angle, normal) * v;
-}
+	template <typename T>
+	GLM_FUNC_QUALIFIER detail::tvec2<T> rotate
+	(
+		detail::tvec2<T> const & v, 
+		T const & angle
+	)
+	{
+		detail::tvec2<T> Result;
+		T const Cos = cos(radians(angle));
+		T const Sin = sin(radians(angle));
+		Result.x = v.x * Cos - v.y * Sin;
+		Result.y = v.x * Sin + v.y * Cos;
+		return Result;
+	}
 
 
-template <typename T>
-GLM_FUNC_QUALIFIER detail::tvec3<T> rotateX(
-	detail::tvec3<T> const & v, 
-	T const & angle)
-{
-	detail::tvec3<T> Result = v;
-	const T Cos = cos(radians(angle));
-    const T Sin = sin(radians(angle));
-	Result.y = v.y * Cos - v.z * Sin;
-	Result.z = v.y * Sin + v.z * Cos;
-	return Result;
-}
+	template <typename T> 
+	GLM_FUNC_QUALIFIER detail::tvec3<T> rotate
+	(
+		detail::tvec3<T> const & v, 
+		T const & angle, 
+		detail::tvec3<T> const & normal
+	)
+	{
+		return detail::tmat3x3<T>(glm::rotate(angle, normal)) * v;
+	}
+	/*
+	template <typename T> 
+	GLM_FUNC_QUALIFIER detail::tvec3<T> rotateGTX(
+		const detail::tvec3<T>& x, 
+		T angle, 
+		const detail::tvec3<T>& normal)
+	{
+		const T Cos = cos(radians(angle));
+		const T Sin = sin(radians(angle));
+		return x * Cos + ((x * normal) * (T(1) - Cos)) * normal + cross(x, normal) * Sin;
+	}
+	*/
+	template <typename T> 
+	GLM_FUNC_QUALIFIER detail::tvec4<T> rotate
+	(
+		detail::tvec4<T> const & v, 
+		T const & angle, 
+		detail::tvec3<T> const & normal
+	)
+	{
+		return rotate(angle, normal) * v;
+	}
 
 
-template <typename T>
-GLM_FUNC_QUALIFIER detail::tvec3<T> rotateY(
-	detail::tvec3<T> const & v, 
-	T const & angle)
-{
-	detail::tvec3<T> Result = v;
-	const T Cos = cos(radians(angle));
-    const T Sin = sin(radians(angle));
-	Result.x =  v.x * Cos + v.z * Sin;
-	Result.z = -v.x * Sin + v.z * Cos;
-	return Result;
-}
+	template <typename T>
+	GLM_FUNC_QUALIFIER detail::tvec3<T> rotateX
+	(
+		detail::tvec3<T> const & v, 
+		T const & angle
+	)
+	{
+		detail::tvec3<T> Result = v;
+		const T Cos = cos(radians(angle));
+		const T Sin = sin(radians(angle));
+		Result.y = v.y * Cos - v.z * Sin;
+		Result.z = v.y * Sin + v.z * Cos;
+		return Result;
+	}
 
 
-template <typename T>
-GLM_FUNC_QUALIFIER detail::tvec3<T> rotateZ(
-	detail::tvec3<T> const & v, 
-	T const & angle)
-{
-	detail::tvec3<T> Result = v;
-	const T Cos = cos(radians(angle));
-    const T Sin = sin(radians(angle));
-	Result.x = v.x * Cos - v.y * Sin;
-	Result.y = v.x * Sin + v.y * Cos;
-	return Result;
-}
+	template <typename T>
+	GLM_FUNC_QUALIFIER detail::tvec3<T> rotateY
+	(
+		detail::tvec3<T> const & v, 
+		T const & angle
+	)
+	{
+		detail::tvec3<T> Result = v;
+		const T Cos = cos(radians(angle));
+		const T Sin = sin(radians(angle));
+		Result.x =  v.x * Cos + v.z * Sin;
+		Result.z = -v.x * Sin + v.z * Cos;
+		return Result;
+	}
 
 
-template <typename T>
-GLM_FUNC_QUALIFIER detail::tvec4<T> rotateX(
-	detail::tvec4<T> const & v, 
-	T const & angle)
-{
-	detail::tvec4<T> Result = v;
-	const T Cos = cos(radians(angle));
-    const T Sin = sin(radians(angle));
-	Result.y = v.y * Cos - v.z * Sin;
-	Result.z = v.y * Sin + v.z * Cos;
-	return Result;
-}
+	template <typename T>
+	GLM_FUNC_QUALIFIER detail::tvec3<T> rotateZ
+	(
+		detail::tvec3<T> const & v, 
+		T const & angle
+	)
+	{
+		detail::tvec3<T> Result = v;
+		const T Cos = cos(radians(angle));
+		const T Sin = sin(radians(angle));
+		Result.x = v.x * Cos - v.y * Sin;
+		Result.y = v.x * Sin + v.y * Cos;
+		return Result;
+	}
 
 
-template <typename T>
-GLM_FUNC_QUALIFIER detail::tvec4<T> rotateY(
-	detail::tvec4<T> const & v, 
-	T const & angle)
-{
-	detail::tvec4<T> Result = v;
-	const T Cos = cos(radians(angle));
-    const T Sin = sin(radians(angle));
-	Result.x =  v.x * Cos + v.z * Sin;
-	Result.z = -v.x * Sin + v.z * Cos;
-	return Result;
-}
+	template <typename T>
+	GLM_FUNC_QUALIFIER detail::tvec4<T> rotateX
+	(
+		detail::tvec4<T> const & v, 
+		T const & angle
+	)
+	{
+		detail::tvec4<T> Result = v;
+		const T Cos = cos(radians(angle));
+		const T Sin = sin(radians(angle));
+		Result.y = v.y * Cos - v.z * Sin;
+		Result.z = v.y * Sin + v.z * Cos;
+		return Result;
+	}
 
 
-template <typename T>
-GLM_FUNC_QUALIFIER detail::tvec4<T> rotateZ(
-	detail::tvec4<T> const & v, 
-	T const & angle)
-{
-	detail::tvec4<T> Result = v;
-	const T Cos = cos(radians(angle));
-    const T Sin = sin(radians(angle));
-	Result.x = v.x * Cos - v.y * Sin;
-	Result.y = v.x * Sin + v.y * Cos;
-	return Result;
-}
+	template <typename T>
+	GLM_FUNC_QUALIFIER detail::tvec4<T> rotateY
+	(
+		detail::tvec4<T> const & v, 
+		T const & angle
+	)
+	{
+		detail::tvec4<T> Result = v;
+		const T Cos = cos(radians(angle));
+		const T Sin = sin(radians(angle));
+		Result.x =  v.x * Cos + v.z * Sin;
+		Result.z = -v.x * Sin + v.z * Cos;
+		return Result;
+	}
 
 
-template <typename T>
-GLM_FUNC_QUALIFIER detail::tmat4x4<T> orientation(
-	detail::tvec3<T> const & Normal, 
-	detail::tvec3<T> const & Up)
-{
-	if(all(equal(Normal, Up)))
-		return detail::tmat4x4<T>(T(1));
+	template <typename T>
+	GLM_FUNC_QUALIFIER detail::tvec4<T> rotateZ
+	(
+		detail::tvec4<T> const & v, 
+		T const & angle
+	)
+	{
+		detail::tvec4<T> Result = v;
+		const T Cos = cos(radians(angle));
+		const T Sin = sin(radians(angle));
+		Result.x = v.x * Cos - v.y * Sin;
+		Result.y = v.x * Sin + v.y * Cos;
+		return Result;
+	}
 
 
-	detail::tvec3<T> RotationAxis = cross(Up, Normal);
-	T Angle = degrees(acos(dot(Normal, Up)));
-	return rotate(Angle, RotationAxis);
-}
+	template <typename T>
+	GLM_FUNC_QUALIFIER detail::tmat4x4<T> orientation
+	(
+		detail::tvec3<T> const & Normal, 
+		detail::tvec3<T> const & Up
+	)
+	{
+		if(all(equal(Normal, Up)))
+			return detail::tmat4x4<T>(T(1));
 
 
+		detail::tvec3<T> RotationAxis = cross(Up, Normal);
+		T Angle = degrees(acos(dot(Normal, Up)));
+		return rotate(Angle, RotationAxis);
+	}
 }//namespace glm
 }//namespace glm

+ 142 - 143
glm/gtx/transform2.inl

@@ -7,149 +7,148 @@
 // File : glm/gtx/transform2.inl
 // File : glm/gtx/transform2.inl
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 
-namespace glm{
-
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tmat3x3<T> shearX2D(
-	const detail::tmat3x3<T>& m, 
-	T s)
-{
-    detail::tmat3x3<T> r(1);
-    r[0][1] = s;
-    return m * r;
-}
-
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tmat3x3<T> shearY2D(
-	const detail::tmat3x3<T>& m, 
-	T s)
-{
-    detail::tmat3x3<T> r(1);
-    r[1][0] = s;
-    return m * r;
-}
-
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tmat4x4<T> shearX3D(
-	const detail::tmat4x4<T>& m, 
-	T s, 
-	T t)
-{
-    detail::tmat4x4<T> r(1);
-    r[1][0] = s;
-    r[2][0] = t;
-    return m * r;
-}
-
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tmat4x4<T> shearY3D(
-	const detail::tmat4x4<T>& m, 
-	T s, 
-	T t)
-{
-    detail::tmat4x4<T> r(1);
-    r[0][1] = s;
-    r[2][1] = t;
-    return m * r;
-}
-
-template <typename T>     
-GLM_FUNC_QUALIFIER detail::tmat4x4<T> shearZ3D(
-	const detail::tmat4x4<T>& m, 
-	T s, 
-	T t)
-{
-    detail::tmat4x4<T> r(1);
-    r[0][2] = s;
-    r[1][2] = t;
-    return m * r;
-}
-
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tmat3x3<T> reflect2D(
-	const detail::tmat3x3<T>& m, 
-	const detail::tvec3<T>& normal)
-{
-    detail::tmat3x3<T> r(1);
-    r[0][0] = 1 - 2 * normal.x * normal.x;
-    r[0][1] = -2 * normal.x * normal.y;
-    r[1][0] = -2 * normal.x * normal.y;
-    r[1][1] = 1 - 2 * normal.y * normal.y;
-    return m * r;
-}
-
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tmat4x4<T> reflect3D(
-	const detail::tmat4x4<T>& m, 
-	const detail::tvec3<T>& normal)
-{
-    detail::tmat4x4<T> r(1);
-    r[0][0] = 1 - 2 * normal.x * normal.x;
-    r[0][1] = -2 * normal.x * normal.y;
-    r[0][2] = -2 * normal.x * normal.z;
-
-    r[1][0] = -2 * normal.x * normal.y;
-    r[1][1] = 1 - 2 * normal.y * normal.y;
-    r[1][2] = -2 * normal.y * normal.z;
-
-    r[2][0] = -2 * normal.x * normal.z;
-    r[2][1] = -2 * normal.y * normal.z;
-    r[2][2] = 1 - 2 * normal.z * normal.z;
-    return m * r;
-}
-
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tmat3x3<T> proj2D(
-	const detail::tmat3x3<T>& m, 
-	const detail::tvec3<T>& normal)
-{
-    detail::tmat3x3<T> r(1);
-    r[0][0] = 1 - normal.x * normal.x;
-    r[0][1] = - normal.x * normal.y;
-    r[1][0] = - normal.x * normal.y;
-    r[1][1] = 1 - normal.y * normal.y;
-    return m * r;
-}
-
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tmat4x4<T> proj3D(
-	const detail::tmat4x4<T>& m, 
-	const detail::tvec3<T>& normal)
-{
-    detail::tmat4x4<T> r(1);
-    r[0][0] = 1 - normal.x * normal.x;
-    r[0][1] = - normal.x * normal.y;
-    r[0][2] = - normal.x * normal.z;
-    r[1][0] = - normal.x * normal.y;
-    r[1][1] = 1 - normal.y * normal.y;
-    r[1][2] = - normal.y * normal.z;
-    r[2][0] = - normal.x * normal.z;
-    r[2][1] = - normal.y * normal.z;
-    r[2][2] = 1 - normal.z * normal.z;
-    return m * r;
-}
-
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tmat4x4<T> scaleBias(
-	T scale, 
-	T bias)
+namespace glm
 {
 {
-	detail::tmat4x4<T> result;
-	result[3] = detail::tvec4<T>(detail::tvec3<T>(bias), T(1));
-	result[0][0] = scale;
-	result[1][1] = scale;
-	result[2][2] = scale;
-	return result;
-}
-
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tmat4x4<T> scaleBias(
-	const detail::tmat4x4<T>& m, 
-	T scale, 
-	T bias)
-{
-	return m * scaleBias(scale, bias);
-}
-
+	template <typename T> 
+	GLM_FUNC_QUALIFIER detail::tmat3x3<T> shearX2D(
+		const detail::tmat3x3<T>& m, 
+		T s)
+	{
+		detail::tmat3x3<T> r(1);
+		r[0][1] = s;
+		return m * r;
+	}
+
+	template <typename T> 
+	GLM_FUNC_QUALIFIER detail::tmat3x3<T> shearY2D(
+		const detail::tmat3x3<T>& m, 
+		T s)
+	{
+		detail::tmat3x3<T> r(1);
+		r[1][0] = s;
+		return m * r;
+	}
+
+	template <typename T> 
+	GLM_FUNC_QUALIFIER detail::tmat4x4<T> shearX3D(
+		const detail::tmat4x4<T>& m, 
+		T s, 
+		T t)
+	{
+		detail::tmat4x4<T> r(1);
+		r[1][0] = s;
+		r[2][0] = t;
+		return m * r;
+	}
+
+	template <typename T> 
+	GLM_FUNC_QUALIFIER detail::tmat4x4<T> shearY3D(
+		const detail::tmat4x4<T>& m, 
+		T s, 
+		T t)
+	{
+		detail::tmat4x4<T> r(1);
+		r[0][1] = s;
+		r[2][1] = t;
+		return m * r;
+	}
+
+	template <typename T>     
+	GLM_FUNC_QUALIFIER detail::tmat4x4<T> shearZ3D(
+		const detail::tmat4x4<T>& m, 
+		T s, 
+		T t)
+	{
+		detail::tmat4x4<T> r(1);
+		r[0][2] = s;
+		r[1][2] = t;
+		return m * r;
+	}
+
+	template <typename T> 
+	GLM_FUNC_QUALIFIER detail::tmat3x3<T> reflect2D(
+		const detail::tmat3x3<T>& m, 
+		const detail::tvec3<T>& normal)
+	{
+		detail::tmat3x3<T> r(1);
+		r[0][0] = 1 - 2 * normal.x * normal.x;
+		r[0][1] = -2 * normal.x * normal.y;
+		r[1][0] = -2 * normal.x * normal.y;
+		r[1][1] = 1 - 2 * normal.y * normal.y;
+		return m * r;
+	}
+
+	template <typename T> 
+	GLM_FUNC_QUALIFIER detail::tmat4x4<T> reflect3D(
+		const detail::tmat4x4<T>& m, 
+		const detail::tvec3<T>& normal)
+	{
+		detail::tmat4x4<T> r(1);
+		r[0][0] = 1 - 2 * normal.x * normal.x;
+		r[0][1] = -2 * normal.x * normal.y;
+		r[0][2] = -2 * normal.x * normal.z;
+
+		r[1][0] = -2 * normal.x * normal.y;
+		r[1][1] = 1 - 2 * normal.y * normal.y;
+		r[1][2] = -2 * normal.y * normal.z;
+
+		r[2][0] = -2 * normal.x * normal.z;
+		r[2][1] = -2 * normal.y * normal.z;
+		r[2][2] = 1 - 2 * normal.z * normal.z;
+		return m * r;
+	}
+
+	template <typename T> 
+	GLM_FUNC_QUALIFIER detail::tmat3x3<T> proj2D(
+		const detail::tmat3x3<T>& m, 
+		const detail::tvec3<T>& normal)
+	{
+		detail::tmat3x3<T> r(1);
+		r[0][0] = 1 - normal.x * normal.x;
+		r[0][1] = - normal.x * normal.y;
+		r[1][0] = - normal.x * normal.y;
+		r[1][1] = 1 - normal.y * normal.y;
+		return m * r;
+	}
+
+	template <typename T> 
+	GLM_FUNC_QUALIFIER detail::tmat4x4<T> proj3D(
+		const detail::tmat4x4<T>& m, 
+		const detail::tvec3<T>& normal)
+	{
+		detail::tmat4x4<T> r(1);
+		r[0][0] = 1 - normal.x * normal.x;
+		r[0][1] = - normal.x * normal.y;
+		r[0][2] = - normal.x * normal.z;
+		r[1][0] = - normal.x * normal.y;
+		r[1][1] = 1 - normal.y * normal.y;
+		r[1][2] = - normal.y * normal.z;
+		r[2][0] = - normal.x * normal.z;
+		r[2][1] = - normal.y * normal.z;
+		r[2][2] = 1 - normal.z * normal.z;
+		return m * r;
+	}
+
+	template <typename T> 
+	GLM_FUNC_QUALIFIER detail::tmat4x4<T> scaleBias(
+		T scale, 
+		T bias)
+	{
+		detail::tmat4x4<T> result;
+		result[3] = detail::tvec4<T>(detail::tvec3<T>(bias), T(1));
+		result[0][0] = scale;
+		result[1][1] = scale;
+		result[2][2] = scale;
+		return result;
+	}
+
+	template <typename T> 
+	GLM_FUNC_QUALIFIER detail::tmat4x4<T> scaleBias(
+		const detail::tmat4x4<T>& m, 
+		T scale, 
+		T bias)
+	{
+		return m * scaleBias(scale, bias);
+	}
 }//namespace glm
 }//namespace glm
 
 

+ 130 - 229
glm/gtx/ulp.inl

@@ -42,34 +42,34 @@ typedef union
 } ieee_double_shape_type;
 } ieee_double_shape_type;
 
 
 #define GLM_EXTRACT_WORDS(ix0,ix1,d)                                \
 #define GLM_EXTRACT_WORDS(ix0,ix1,d)                                \
-do {                                                            \
-  ieee_double_shape_type ew_u;                                  \
-  ew_u.value = (d);                                             \
-  (ix0) = ew_u.parts.msw;                                       \
-  (ix1) = ew_u.parts.lsw;                                       \
-} while (0)
+	do {                                                            \
+	  ieee_double_shape_type ew_u;                                  \
+	  ew_u.value = (d);                                             \
+	  (ix0) = ew_u.parts.msw;                                       \
+	  (ix1) = ew_u.parts.lsw;                                       \
+	} while (0)
 
 
 #define GLM_GET_FLOAT_WORD(i,d)                                     \
 #define GLM_GET_FLOAT_WORD(i,d)                                     \
-do {                                                            \
-  ieee_float_shape_type gf_u;                                   \
-  gf_u.value = (d);                                             \
-  (i) = gf_u.word;                                              \
-} while (0)
+	do {                                                            \
+	  ieee_float_shape_type gf_u;                                   \
+	  gf_u.value = (d);                                             \
+	  (i) = gf_u.word;                                              \
+	} while (0)
 
 
 #define GLM_SET_FLOAT_WORD(d,i)                                     \
 #define GLM_SET_FLOAT_WORD(d,i)                                     \
-do {                                                            \
-  ieee_float_shape_type sf_u;                                   \
-  sf_u.word = (i);                                              \
-  (d) = sf_u.value;                                             \
-} while (0)
+	do {                                                            \
+	  ieee_float_shape_type sf_u;                                   \
+	  sf_u.word = (i);                                              \
+	  (d) = sf_u.value;                                             \
+	} while (0)
 
 
 #define GLM_INSERT_WORDS(d,ix0,ix1)                                 \
 #define GLM_INSERT_WORDS(d,ix0,ix1)                                 \
-do {                                                            \
-  ieee_double_shape_type iw_u;                                  \
-  iw_u.parts.msw = (ix0);                                       \
-  iw_u.parts.lsw = (ix1);                                       \
-  (d) = iw_u.value;                                             \
-} while (0)
+	do {                                                            \
+	  ieee_double_shape_type iw_u;                                  \
+	  iw_u.parts.msw = (ix0);                                       \
+	  iw_u.parts.lsw = (ix1);                                       \
+	  (d) = iw_u.value;                                             \
+	} while (0)
 
 
 namespace glm{
 namespace glm{
 namespace detail
 namespace detail
@@ -181,218 +181,119 @@ namespace detail
 #   define GLM_NEXT_AFTER_DBL(x, toward) nextafter((x), (toward))
 #   define GLM_NEXT_AFTER_DBL(x, toward) nextafter((x), (toward))
 #endif
 #endif
 
 
-namespace glm{
-
-GLM_FUNC_QUALIFIER float next_float(float const & x)
+namespace glm
 {
 {
-    return GLM_NEXT_AFTER_FLT(x, std::numeric_limits<float>::max());
-}
+	GLM_FUNC_QUALIFIER float next_float(float const & x)
+	{
+		return GLM_NEXT_AFTER_FLT(x, std::numeric_limits<float>::max());
+	}
 
 
-GLM_FUNC_QUALIFIER double next_float(double const & x)
-{
-    return GLM_NEXT_AFTER_DBL(x, std::numeric_limits<double>::max());
-}
+	GLM_FUNC_QUALIFIER double next_float(double const & x)
+	{
+		return GLM_NEXT_AFTER_DBL(x, std::numeric_limits<double>::max());
+	}
 
 
-template<typename T, template<typename> class vecType>
-GLM_FUNC_QUALIFIER vecType<T> next_float(vecType<T> const & x)
-{
-    vecType<T> Result;
-    for(std::size_t i = 0; i < Result.length(); ++i)
-        Result[i] = next_float(x[i]);
-    return Result;
-}
+	template<typename T, template<typename> class vecType>
+	GLM_FUNC_QUALIFIER vecType<T> next_float(vecType<T> const & x)
+	{
+		vecType<T> Result;
+		for(std::size_t i = 0; i < Result.length(); ++i)
+			Result[i] = next_float(x[i]);
+		return Result;
+	}
 
 
-GLM_FUNC_QUALIFIER float prev_float(float const & x)
-{
-    return GLM_NEXT_AFTER_FLT(x, std::numeric_limits<float>::min());
-}
+	GLM_FUNC_QUALIFIER float prev_float(float const & x)
+	{
+		return GLM_NEXT_AFTER_FLT(x, std::numeric_limits<float>::min());
+	}
 
 
-GLM_FUNC_QUALIFIER double prev_float(double const & x)
-{
-    return GLM_NEXT_AFTER_DBL(x, std::numeric_limits<double>::min());
-}
+	GLM_FUNC_QUALIFIER double prev_float(double const & x)
+	{
+		return GLM_NEXT_AFTER_DBL(x, std::numeric_limits<double>::min());
+	}
 
 
-template<typename T, template<typename> class vecType>
-GLM_FUNC_QUALIFIER vecType<T> prev_float(vecType<T> const & x)
-{
-    vecType<T> Result;
-    for(std::size_t i = 0; i < Result.length(); ++i)
-        Result[i] = prev_float(x[i]);
-    return Result;
-}
-
-template <typename T>
-GLM_FUNC_QUALIFIER T next_float(T const & x, uint const & ulps)
-{
-    T temp = x;
-    for(std::size_t i = 0; i < ulps; ++i)
-        temp = next_float(temp);
-    return temp;
-}
-
-template<typename T, template<typename> class vecType>
-GLM_FUNC_QUALIFIER vecType<T> next_float(vecType<T> const & x, vecType<uint> const & ulps)
-{
-    vecType<T> Result;
-    for(std::size_t i = 0; i < Result.length(); ++i)
-        Result[i] = next_float(x[i], ulps[i]);
-    return Result;
-}
-
-template <typename T>
-GLM_FUNC_QUALIFIER T prev_float(T const & x, uint const & ulps)
-{
-    T temp = x;
-    for(std::size_t i = 0; i < ulps; ++i)
-        temp = prev_float(temp);
-    return temp;
-}
-
-template<typename T, template<typename> class vecType>
-GLM_FUNC_QUALIFIER vecType<T> prev_float(vecType<T> const & x, vecType<uint> const & ulps)
-{
-    vecType<T> Result;
-    for(std::size_t i = 0; i < Result.length(); ++i)
-        Result[i] = prev_float(x[i], ulps[i]);
-    return Result;
-}
-
-template <typename T>
-GLM_FUNC_QUALIFIER uint float_distance(T const & x, T const & y)
-{
-    uint ulp = 0;
-
-    if(x < y)
-    {
-        T temp = x;
-        while(temp != y && ulp < std::numeric_limits<std::size_t>::max())
-        {
-            ++ulp;
-            temp = next_float(temp);
-        }
-    }
-    else if(y < x)
-    {
-        T temp = y;
-        while(temp != x && ulp < std::numeric_limits<std::size_t>::max())
-        {
-            ++ulp;
-            temp = next_float(temp);
-        }
-    }
-    else // ==
-    {
-
-    }
-
-    return ulp;
-}
-
-template<typename T, template<typename> class vecType>
-GLM_FUNC_QUALIFIER vecType<uint> float_distance(vecType<T> const & x, vecType<T> const & y)
-{
-    vecType<uint> Result;
-    for(std::size_t i = 0; i < Result.length(); ++i)
-        Result[i] = float_distance(x[i], y[i]);
-    return Result;
-}
-/*
-inline std::size_t ulp
-(
-	detail::thalf const & a,
-	detail::thalf const & b
-)
-{
-	std::size_t Count = 0;
-	float TempA(a);
-	float TempB(b);
-	//while((TempA = _nextafterf(TempA, TempB)) != TempB)
-		++Count;
-	return Count;
-}
-
-inline std::size_t ulp
-(
-	float const & a,
-	float const & b
-)
-{
-	std::size_t Count = 0;
-	float Temp = a;
-	//while((Temp = _nextafterf(Temp, b)) != b)
-    {
-        std::cout << Temp << " " << b << std::endl;
-		++Count;
-    }
-	return Count;
-}
-
-inline std::size_t ulp
-(
-	double const & a,
-	double const & b
-)
-{
-	std::size_t Count = 0;
-	double Temp = a;
-	//while((Temp = _nextafter(Temp, b)) != b)
-    {
-        std::cout << Temp << " " << b << std::endl;
-		++Count;
-    }
-	return Count;
-}
-
-template <typename T>
-inline std::size_t ulp
-(
-	detail::tvec2<T> const & a,
-	detail::tvec2<T> const & b
-)
-{
-    std::size_t ulps[] = 
-    {
-        ulp(a[0], b[0]),
-        ulp(a[1], b[1])
-    };
-
-    return glm::max(ulps[0], ulps[1]);
-}
-
-template <typename T>
-inline std::size_t ulp
-(
-	detail::tvec3<T> const & a,
-	detail::tvec3<T> const & b
-)
-{
-    std::size_t ulps[] = 
-    {
-        ulp(a[0], b[0]),
-        ulp(a[1], b[1]),
-        ulp(a[2], b[2])
-    };
-
-    return glm::max(glm::max(ulps[0], ulps[1]), ulps[2]);
-}
-
-template <typename T>
-inline std::size_t ulp
-(
-	detail::tvec4<T> const & a,
-	detail::tvec4<T> const & b
-)
-{
-    std::size_t ulps[] = 
-    {
-        ulp(a[0], b[0]),
-        ulp(a[1], b[1]),
-        ulp(a[2], b[2]),
-        ulp(a[3], b[3])
-    };
-
-    return glm::max(glm::max(ulps[0], ulps[1]), glm::max(ulps[2], ulps[3]));
-}
-*/
+	template<typename T, template<typename> class vecType>
+	GLM_FUNC_QUALIFIER vecType<T> prev_float(vecType<T> const & x)
+	{
+		vecType<T> Result;
+		for(std::size_t i = 0; i < Result.length(); ++i)
+			Result[i] = prev_float(x[i]);
+		return Result;
+	}
+
+	template <typename T>
+	GLM_FUNC_QUALIFIER T next_float(T const & x, uint const & ulps)
+	{
+		T temp = x;
+		for(std::size_t i = 0; i < ulps; ++i)
+			temp = next_float(temp);
+		return temp;
+	}
+
+	template<typename T, template<typename> class vecType>
+	GLM_FUNC_QUALIFIER vecType<T> next_float(vecType<T> const & x, vecType<uint> const & ulps)
+	{
+		vecType<T> Result;
+		for(std::size_t i = 0; i < Result.length(); ++i)
+			Result[i] = next_float(x[i], ulps[i]);
+		return Result;
+	}
+
+	template <typename T>
+	GLM_FUNC_QUALIFIER T prev_float(T const & x, uint const & ulps)
+	{
+		T temp = x;
+		for(std::size_t i = 0; i < ulps; ++i)
+			temp = prev_float(temp);
+		return temp;
+	}
+
+	template<typename T, template<typename> class vecType>
+	GLM_FUNC_QUALIFIER vecType<T> prev_float(vecType<T> const & x, vecType<uint> const & ulps)
+	{
+		vecType<T> Result;
+		for(std::size_t i = 0; i < Result.length(); ++i)
+			Result[i] = prev_float(x[i], ulps[i]);
+		return Result;
+	}
+
+	template <typename T>
+	GLM_FUNC_QUALIFIER uint float_distance(T const & x, T const & y)
+	{
+		uint ulp = 0;
+
+		if(x < y)
+		{
+			T temp = x;
+			while(temp != y && ulp < std::numeric_limits<std::size_t>::max())
+			{
+				++ulp;
+				temp = next_float(temp);
+			}
+		}
+		else if(y < x)
+		{
+			T temp = y;
+			while(temp != x && ulp < std::numeric_limits<std::size_t>::max())
+			{
+				++ulp;
+				temp = next_float(temp);
+			}
+		}
+		else // ==
+		{
+
+		}
 
 
+		return ulp;
+	}
+
+	template<typename T, template<typename> class vecType>
+	GLM_FUNC_QUALIFIER vecType<uint> float_distance(vecType<T> const & x, vecType<T> const & y)
+	{
+		vecType<uint> Result;
+		for(std::size_t i = 0; i < Result.length(); ++i)
+			Result[i] = float_distance(x[i], y[i]);
+		return Result;
+	}
 }//namespace glm
 }//namespace glm

+ 2 - 2
glm/gtx/unsigned_int.inl

@@ -7,7 +7,7 @@
 // File    : glm/gtx/unsigned_int.inl
 // File    : glm/gtx/unsigned_int.inl
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 
-namespace glm{
-
+namespace glm
+{
 
 
 }//namespace glm
 }//namespace glm

+ 40 - 41
glm/gtx/vector_access.inl

@@ -7,48 +7,47 @@
 // File    : glm/gtx/vector_access.inl
 // File    : glm/gtx/vector_access.inl
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 
-namespace glm{
-
-template <typename valType> 
-GLM_FUNC_QUALIFIER void set
-(
-	detail::tvec2<valType>& v, 
-	valType const & x, 
-	valType const & y
-)
-{
-    v.x = x;
-    v.y = y;
-}
-
-template <typename valType> 
-GLM_FUNC_QUALIFIER void set
-(
-	detail::tvec3<valType>& v, 
-	valType const & x, 
-	valType const & y, 
-	valType const & z
-)
+namespace glm
 {
 {
-    v.x = x;
-    v.y = y;
-    v.z = z;
-}
+	template <typename valType> 
+	GLM_FUNC_QUALIFIER void set
+	(
+		detail::tvec2<valType>& v, 
+		valType const & x, 
+		valType const & y
+	)
+	{
+		v.x = x;
+		v.y = y;
+	}
 
 
-template <typename valType>
-GLM_FUNC_QUALIFIER void set
-(
-	detail::tvec4<valType>& v, 
-	valType const & x, 
-	valType const & y, 
-	valType const & z, 
-	valType const & w
-)
-{
-    v.x = x;
-    v.y = y;
-    v.z = z;
-    v.w = w;
-}
+	template <typename valType> 
+	GLM_FUNC_QUALIFIER void set
+	(
+		detail::tvec3<valType>& v, 
+		valType const & x, 
+		valType const & y, 
+		valType const & z
+	)
+	{
+		v.x = x;
+		v.y = y;
+		v.z = z;
+	}
 
 
+	template <typename valType>
+	GLM_FUNC_QUALIFIER void set
+	(
+		detail::tvec4<valType>& v, 
+		valType const & x, 
+		valType const & y, 
+		valType const & z, 
+		valType const & w
+	)
+	{
+		v.x = x;
+		v.y = y;
+		v.z = z;
+		v.w = w;
+	}
 }//namespace glm
 }//namespace glm

+ 39 - 40
glm/gtx/vector_angle.inl

@@ -7,48 +7,47 @@
 // File    : glm/gtx/vector_angle.inl
 // File    : glm/gtx/vector_angle.inl
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 
-namespace glm{
-
-template <typename genType> 
-GLM_FUNC_QUALIFIER typename genType::value_type angle
-(
-	genType const & x, 
-	genType const & y
-)
-{
-	return degrees(acos(dot(x, y)));
-}
-
-//! \todo epsilon is hard coded to 0.01
-template <typename valType> 
-GLM_FUNC_QUALIFIER valType orientedAngle
-(
-	detail::tvec2<valType> const & x, 
-	detail::tvec2<valType> const & y
-)
+namespace glm
 {
 {
-    valType Angle = glm::degrees(acos(dot(x, y)));
-	detail::tvec2<valType> TransformedVector = glm::rotate(x, Angle);
-    if(all(equalEpsilon(y, TransformedVector, valType(0.01))))
-		return Angle;
-    else
-        return -Angle;
-}
+	template <typename genType> 
+	GLM_FUNC_QUALIFIER typename genType::value_type angle
+	(
+		genType const & x, 
+		genType const & y
+	)
+	{
+		return degrees(acos(dot(x, y)));
+	}
 
 
-template <typename valType>
-GLM_FUNC_QUALIFIER valType orientedAngle
-(
-	detail::tvec3<valType> const & x,
-	detail::tvec3<valType> const & y,
-	detail::tvec3<valType> const & ref
-)
-{
-	valType Angle = glm::degrees(glm::acos(glm::dot(x, y)));
+	//! \todo epsilon is hard coded to 0.01
+	template <typename valType> 
+	GLM_FUNC_QUALIFIER valType orientedAngle
+	(
+		detail::tvec2<valType> const & x, 
+		detail::tvec2<valType> const & y
+	)
+	{
+		valType Angle = glm::degrees(acos(dot(x, y)));
+		detail::tvec2<valType> TransformedVector = glm::rotate(x, Angle);
+		if(all(equalEpsilon(y, TransformedVector, valType(0.01))))
+			return Angle;
+		else
+			return -Angle;
+	}
 
 
-	if(glm::dot(ref, glm::cross(x, y)) < valType(0))
-		return -Angle;
-	else
-		return Angle;
-}
+	template <typename valType>
+	GLM_FUNC_QUALIFIER valType orientedAngle
+	(
+		detail::tvec3<valType> const & x,
+		detail::tvec3<valType> const & y,
+		detail::tvec3<valType> const & ref
+	)
+	{
+		valType Angle = glm::degrees(glm::acos(glm::dot(x, y)));
 
 
+		if(glm::dot(ref, glm::cross(x, y)) < valType(0))
+			return -Angle;
+		else
+			return Angle;
+	}
 }//namespace glm
 }//namespace glm

+ 152 - 153
glm/gtx/vector_query.inl

@@ -12,159 +12,158 @@
 
 
 #include <cassert>
 #include <cassert>
 
 
-namespace glm{
-
-template <typename T>
-GLM_FUNC_QUALIFIER bool areCollinear
-(
-	detail::tvec2<T> const & v0, 
-	detail::tvec2<T> const & v1, 
-	T const & epsilon
-)
-{
-	return length(cross(detail::tvec3<T>(v0, T(0)), detail::tvec3<T>(v1, T(0)))) < epsilon;
-}
-
-template <typename T>
-GLM_FUNC_QUALIFIER bool areCollinear
-(
-	detail::tvec3<T> const & v0, 
-	detail::tvec3<T> const & v1, 
-	T const & epsilon
-)
-{
-	return length(cross(v0, v1)) < epsilon;
-}
-
-template <typename T>
-GLM_FUNC_QUALIFIER bool areCollinear
-(
-	detail::tvec4<T> const & v0, 
-	detail::tvec4<T> const & v1, 
-	T const & epsilon
-)
-{
-	return length(cross(detail::tvec3<T>(v0), detail::tvec3<T>(v1))) < epsilon;
-}
-
-template <typename genType>
-GLM_FUNC_QUALIFIER bool areOpposite
-(
-	genType const & v0, 
-	genType const & v1, 
-	typename genType::value_type const & epsilon
-)
+namespace glm
 {
 {
-	assert(isNormalized(v0) && isNormalized(v1));
-    return((typename genType::value_type(1) + dot(v0, v1)) <= epsilon);
-}
-
-template <typename genType>
-GLM_FUNC_QUALIFIER bool areOrthogonal
-(
-	genType const & v0, 
-	genType const & v1, 
-	typename genType::value_type const & epsilon
-)
-{
-	return abs(dot(v0, v1)) <= max(
-		typename genType::value_type(1), 
-		length(v0)) * max(
+	template <typename T>
+	GLM_FUNC_QUALIFIER bool areCollinear
+	(
+		detail::tvec2<T> const & v0, 
+		detail::tvec2<T> const & v1, 
+		T const & epsilon
+	)
+	{
+		return length(cross(detail::tvec3<T>(v0, T(0)), detail::tvec3<T>(v1, T(0)))) < epsilon;
+	}
+
+	template <typename T>
+	GLM_FUNC_QUALIFIER bool areCollinear
+	(
+		detail::tvec3<T> const & v0, 
+		detail::tvec3<T> const & v1, 
+		T const & epsilon
+	)
+	{
+		return length(cross(v0, v1)) < epsilon;
+	}
+
+	template <typename T>
+	GLM_FUNC_QUALIFIER bool areCollinear
+	(
+		detail::tvec4<T> const & v0, 
+		detail::tvec4<T> const & v1, 
+		T const & epsilon
+	)
+	{
+		return length(cross(detail::tvec3<T>(v0), detail::tvec3<T>(v1))) < epsilon;
+	}
+
+	template <typename genType>
+	GLM_FUNC_QUALIFIER bool areOpposite
+	(
+		genType const & v0, 
+		genType const & v1, 
+		typename genType::value_type const & epsilon
+	)
+	{
+		assert(isNormalized(v0) && isNormalized(v1));
+		return((typename genType::value_type(1) + dot(v0, v1)) <= epsilon);
+	}
+
+	template <typename genType>
+	GLM_FUNC_QUALIFIER bool areOrthogonal
+	(
+		genType const & v0, 
+		genType const & v1, 
+		typename genType::value_type const & epsilon
+	)
+	{
+		return abs(dot(v0, v1)) <= max(
 			typename genType::value_type(1), 
 			typename genType::value_type(1), 
-			length(v1)) * epsilon;
-}
-
-template <typename genType> 
-GLM_FUNC_QUALIFIER bool isNormalized
-(
-	genType const & v, 
-	typename genType::value_type const & epsilon
-)
-{
-	return abs(length(v) - typename genType::value_type(1)) <= typename genType::value_type(2) * epsilon;
-}
-
-template <typename genType> 
-GLM_FUNC_QUALIFIER bool isNull
-(
-	genType const & v, 
-	typename genType::value_type const & epsilon
-)
-{
-	return length(v) <= epsilon;
-}
-
-template <typename T> 
-GLM_FUNC_QUALIFIER bool isCompNull
-(
-	T const & s, 
-	T const & epsilon
-)
-{
-    return abs(s) < epsilon;
-}
-
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tvec2<bool> isCompNull
-(
-	detail::tvec2<T> const & v, 
-	T const & epsilon)
-{
-    return detail::tvec2<bool>(
-        (abs(v.x) < epsilon),
-        (abs(v.y) < epsilon));
-}
-
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tvec3<bool> isCompNull
-(
-	detail::tvec3<T> const & v, 
-	T const & epsilon
-)
-{
-    return detail::tvec3<bool>(
-        abs(v.x) < epsilon,
-        abs(v.y) < epsilon,
-        abs(v.z) < epsilon);
-}
-
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tvec4<bool> isCompNull
-(
-	detail::tvec4<T> const & v, 
-	T const & epsilon
-)
-{
-    return detail::tvec4<bool>(
-        abs(v.x) < epsilon,
-        abs(v.y) < epsilon,
-        abs(v.z) < epsilon,
-        abs(v.w) < epsilon);
-}
-
-template <typename genType>
-GLM_FUNC_QUALIFIER bool areOrthonormal
-(
-	genType const & v0, 
-	genType const & v1, 
-	typename genType::value_type const & epsilon
-)
-{
-	return isNormalized(v0, epsilon) && isNormalized(v1, epsilon) && (abs(dot(v0, v1)) <= epsilon);
-}
-
-template <typename genType>
-GLM_FUNC_QUALIFIER bool areSimilar
-(
-	genType const & v0, 
-	genType const & v1, 
-	typename genType::value_type const & epsilon
-)
-{
-	bool similar = true;
-    for(typename genType::size_type i = 0; similar && i < genType::value_size(); i++)
-		similar = (abs(v0[i] - v1[i]) <= epsilon);
-	return similar;
-}
-
+			length(v0)) * max(
+				typename genType::value_type(1), 
+				length(v1)) * epsilon;
+	}
+
+	template <typename genType> 
+	GLM_FUNC_QUALIFIER bool isNormalized
+	(
+		genType const & v, 
+		typename genType::value_type const & epsilon
+	)
+	{
+		return abs(length(v) - typename genType::value_type(1)) <= typename genType::value_type(2) * epsilon;
+	}
+
+	template <typename genType> 
+	GLM_FUNC_QUALIFIER bool isNull
+	(
+		genType const & v, 
+		typename genType::value_type const & epsilon
+	)
+	{
+		return length(v) <= epsilon;
+	}
+
+	template <typename T> 
+	GLM_FUNC_QUALIFIER bool isCompNull
+	(
+		T const & s, 
+		T const & epsilon
+	)
+	{
+		return abs(s) < epsilon;
+	}
+
+	template <typename T> 
+	GLM_FUNC_QUALIFIER detail::tvec2<bool> isCompNull
+	(
+		detail::tvec2<T> const & v, 
+		T const & epsilon)
+	{
+		return detail::tvec2<bool>(
+			(abs(v.x) < epsilon),
+			(abs(v.y) < epsilon));
+	}
+
+	template <typename T> 
+	GLM_FUNC_QUALIFIER detail::tvec3<bool> isCompNull
+	(
+		detail::tvec3<T> const & v, 
+		T const & epsilon
+	)
+	{
+		return detail::tvec3<bool>(
+			abs(v.x) < epsilon,
+			abs(v.y) < epsilon,
+			abs(v.z) < epsilon);
+	}
+
+	template <typename T> 
+	GLM_FUNC_QUALIFIER detail::tvec4<bool> isCompNull
+	(
+		detail::tvec4<T> const & v, 
+		T const & epsilon
+	)
+	{
+		return detail::tvec4<bool>(
+			abs(v.x) < epsilon,
+			abs(v.y) < epsilon,
+			abs(v.z) < epsilon,
+			abs(v.w) < epsilon);
+	}
+
+	template <typename genType>
+	GLM_FUNC_QUALIFIER bool areOrthonormal
+	(
+		genType const & v0, 
+		genType const & v1, 
+		typename genType::value_type const & epsilon
+	)
+	{
+		return isNormalized(v0, epsilon) && isNormalized(v1, epsilon) && (abs(dot(v0, v1)) <= epsilon);
+	}
+
+	template <typename genType>
+	GLM_FUNC_QUALIFIER bool areSimilar
+	(
+		genType const & v0, 
+		genType const & v1, 
+		typename genType::value_type const & epsilon
+	)
+	{
+		bool similar = true;
+		for(typename genType::size_type i = 0; similar && i < genType::value_size(); i++)
+			similar = (abs(v0[i] - v1[i]) <= epsilon);
+		return similar;
+	}
 }//namespace glm
 }//namespace glm

+ 101 - 102
glm/gtx/verbose_operator.inl

@@ -7,119 +7,118 @@
 // File    : glm/gtx/verbose_operator.inl
 // File    : glm/gtx/verbose_operator.inl
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 
-namespace glm{
-
-template <typename genType>
-GLM_FUNC_QUALIFIER genType add(genType const & a, genType const & b)
+namespace glm
 {
 {
-    return a + b;
-}
+	template <typename genType>
+	GLM_FUNC_QUALIFIER genType add(genType const & a, genType const & b)
+	{
+		return a + b;
+	}
 
 
-template <typename genType>
-GLM_FUNC_QUALIFIER genType sub(genType const & a, genType const & b)
-{
-    return a - b;
-}
+	template <typename genType>
+	GLM_FUNC_QUALIFIER genType sub(genType const & a, genType const & b)
+	{
+		return a - b;
+	}
 
 
-template <typename T>
-GLM_FUNC_QUALIFIER detail::tmat2x2<T> mul
-(
-	detail::tmat2x2<T> const & a, 
-	detail::tmat2x2<T> const & b
-)
-{
-    return a * b;
-}
+	template <typename T>
+	GLM_FUNC_QUALIFIER detail::tmat2x2<T> mul
+	(
+		detail::tmat2x2<T> const & a, 
+		detail::tmat2x2<T> const & b
+	)
+	{
+		return a * b;
+	}
 
 
-template <typename T>
-GLM_FUNC_QUALIFIER detail::tmat3x3<T> mul
-(
-	detail::tmat3x3<T> const & a, 
-	detail::tmat3x3<T> const & b
-)
-{
-    return a * b;
-}
+	template <typename T>
+	GLM_FUNC_QUALIFIER detail::tmat3x3<T> mul
+	(
+		detail::tmat3x3<T> const & a, 
+		detail::tmat3x3<T> const & b
+	)
+	{
+		return a * b;
+	}
 
 
-template <typename T>
-GLM_FUNC_QUALIFIER detail::tmat4x4<T> mul
-(
-	detail::tmat4x4<T> const & a, 
-	detail::tmat4x4<T> const & b
-)
-{
-    return a * b;
-}
-
-template <typename T>
-GLM_FUNC_QUALIFIER detail::tvec2<T> mul
-(
-	detail::tmat2x2<T> const & m, 
-	detail::tvec2<T> const & v
-)
-{
-    return m * v;
-}
+	template <typename T>
+	GLM_FUNC_QUALIFIER detail::tmat4x4<T> mul
+	(
+		detail::tmat4x4<T> const & a, 
+		detail::tmat4x4<T> const & b
+	)
+	{
+		return a * b;
+	}
 
 
-template <typename T>
-GLM_FUNC_QUALIFIER detail::tvec3<T> mul
-(
-	detail::tmat3x3<T> const & m, 
-	detail::tvec3<T> const & v)
-{
-    return m * v;
-}
+	template <typename T>
+	GLM_FUNC_QUALIFIER detail::tvec2<T> mul
+	(
+		detail::tmat2x2<T> const & m, 
+		detail::tvec2<T> const & v
+	)
+	{
+		return m * v;
+	}
 
 
-template <typename T>
-GLM_FUNC_QUALIFIER detail::tvec4<T> mul
-(
-	detail::tmat4x4<T> const & m, 
-	detail::tvec4<T> const & v
-)
-{
-    return m * v;
-}
+	template <typename T>
+	GLM_FUNC_QUALIFIER detail::tvec3<T> mul
+	(
+		detail::tmat3x3<T> const & m, 
+		detail::tvec3<T> const & v)
+	{
+		return m * v;
+	}
 
 
-template <typename T>
-GLM_FUNC_QUALIFIER detail::tvec2<T> mul
-(
-	detail::tvec2<T> const & v, 
-	detail::tmat2x2<T> const & m
-)
-{
-    return v * m;
-}
+	template <typename T>
+	GLM_FUNC_QUALIFIER detail::tvec4<T> mul
+	(
+		detail::tmat4x4<T> const & m, 
+		detail::tvec4<T> const & v
+	)
+	{
+		return m * v;
+	}
 
 
-template <typename T>
-GLM_FUNC_QUALIFIER detail::tvec3<T> mul
-(
-	detail::tvec3<T> const & v, 
-	detail::tmat3x3<T> const & m
-)
-{
-    return v * m;
-}
+	template <typename T>
+	GLM_FUNC_QUALIFIER detail::tvec2<T> mul
+	(
+		detail::tvec2<T> const & v, 
+		detail::tmat2x2<T> const & m
+	)
+	{
+		return v * m;
+	}
 
 
-template <typename T>
-GLM_FUNC_QUALIFIER detail::tvec4<T> mul
-(
-	detail::tvec4<T> const & v, 
-	detail::tmat4x4<T> const & m
-)
-{
-    return v * m;
-}
+	template <typename T>
+	GLM_FUNC_QUALIFIER detail::tvec3<T> mul
+	(
+		detail::tvec3<T> const & v, 
+		detail::tmat3x3<T> const & m
+	)
+	{
+		return v * m;
+	}
 
 
-template <typename genType>
-GLM_FUNC_QUALIFIER genType div(genType const & a, genType const & b)
-{
-    return a / b;
-}
+	template <typename T>
+	GLM_FUNC_QUALIFIER detail::tvec4<T> mul
+	(
+		detail::tvec4<T> const & v, 
+		detail::tmat4x4<T> const & m
+	)
+	{
+		return v * m;
+	}
 
 
-template <typename genTypeT, typename genTypeU, typename genTypeV> 
-GLM_FUNC_QUALIFIER genTypeT mad(genTypeT const & a, genTypeU const & b, genTypeV const & c)
-{
-	return a * b + c;
-}
+	template <typename genType>
+	GLM_FUNC_QUALIFIER genType div(genType const & a, genType const & b)
+	{
+		return a / b;
+	}
 
 
+	template <typename genTypeT, typename genTypeU, typename genTypeV> 
+	GLM_FUNC_QUALIFIER genTypeT mad(genTypeT const & a, genTypeU const & b, genTypeV const & c)
+	{
+		return a * b + c;
+	}
 }//namespace glm
 }//namespace glm

+ 151 - 152
glm/gtx/wrap.inl

@@ -10,157 +10,156 @@
 // - GLM core
 // - GLM core
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 
-namespace glm{
-
-template <typename genType> 
-GLM_FUNC_QUALIFIER genType clamp
-(
-	genType const & Texcoord
-)
-{
-	return glm::clamp(Texcoord, genType(0), genType(1));
-}
-
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tvec2<T> clamp
-(
-	detail::tvec2<T> const & Texcoord
-)
-{
-	detail::tvec2<T> Result;
-	for(typename detail::tvec2<T>::size_type i = 0; i < detail::tvec2<T>::value_size(); ++i)
-		Result[i] = clamp(Texcoord[i]);
-	return Result;
-}
-
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tvec3<T> clamp
-(
-	detail::tvec3<T> const & Texcoord
-)
-{
-	detail::tvec3<T> Result;
-	for(typename detail::tvec3<T>::size_type i = 0; i < detail::tvec3<T>::value_size(); ++i)
-		Result[i] = clamp(Texcoord[i]);
-	return Result;
-}
-
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tvec4<T> clamp
-(
-	detail::tvec4<T> const & Texcoord
-)
-{
-	detail::tvec4<T> Result;
-	for(typename detail::tvec4<T>::size_type i = 0; i < detail::tvec4<T>::value_size(); ++i)
-		Result[i] = clamp(Texcoord[i]);
-	return Result;
-}
-
-////////////////////////
-// repeat
-
-template <typename genType> 
-GLM_FUNC_QUALIFIER genType repeat
-(
-	genType const & Texcoord
-)
-{
-	return glm::fract(Texcoord);
-}
-
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tvec2<T> repeat
-(
-	detail::tvec2<T> const & Texcoord
-)
-{
-	detail::tvec2<T> Result;
-	for(typename detail::tvec2<T>::size_type i = 0; i < detail::tvec2<T>::value_size(); ++i)
-		Result[i] = repeat(Texcoord[i]);
-	return Result;
-}
-
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tvec3<T> repeat
-(
-	detail::tvec3<T> const & Texcoord
-)
+namespace glm
 {
 {
-	detail::tvec3<T> Result;
-	for(typename detail::tvec3<T>::size_type i = 0; i < detail::tvec3<T>::value_size(); ++i)
-		Result[i] = repeat(Texcoord[i]);
-	return Result;
-}
-
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tvec4<T> repeat
-(
-	detail::tvec4<T> const & Texcoord
-)
-{
-	detail::tvec4<T> Result;
-	for(typename detail::tvec4<T>::size_type i = 0; i < detail::tvec4<T>::value_size(); ++i)
-		Result[i] = repeat(Texcoord[i]);
-	return Result;
-}
-
-////////////////////////
-// mirrorRepeat
-
-template <typename genType> 
-GLM_FUNC_QUALIFIER genType mirrorRepeat
-(
-	genType const & Texcoord
-)
-{
-	genType const Clamp = genType(int(glm::floor(Texcoord)) % 2);
-	genType const Floor = glm::floor(Texcoord);
-	genType const Rest = Texcoord - Floor;
-	genType const Mirror = Clamp + Rest;
-
-	genType Out;
-	if(Mirror >= genType(1))
-		Out = genType(1) - Rest;
-	else
-		Out = Rest;
-	return Out;
-}
-
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tvec2<T> mirrorRepeat
-(
-	detail::tvec2<T> const & Texcoord
-)
-{
-	detail::tvec2<T> Result;
-	for(typename detail::tvec2<T>::size_type i = 0; i < detail::tvec2<T>::value_size(); ++i)
-		Result[i] = mirrorRepeat(Texcoord[i]);
-	return Result;
-}
-
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tvec3<T> mirrorRepeat
-(
-	detail::tvec3<T> const & Texcoord
-)
-{
-	detail::tvec3<T> Result;
-	for(typename detail::tvec3<T>::size_type i = 0; i < detail::tvec3<T>::value_size(); ++i)
-		Result[i] = mirrorRepeat(Texcoord[i]);
-	return Result;
-}
-
-template <typename T> 
-GLM_FUNC_QUALIFIER detail::tvec4<T> mirrorRepeat
-(
-	detail::tvec4<T> const & Texcoord
-)
-{
-	detail::tvec4<T> Result;
-	for(typename detail::tvec4<T>::size_type i = 0; i < detail::tvec4<T>::value_size(); ++i)
-		Result[i] = mirrorRepeat(Texcoord[i]);
-	return Result;
-}
-
+	template <typename genType> 
+	GLM_FUNC_QUALIFIER genType clamp
+	(
+		genType const & Texcoord
+	)
+	{
+		return glm::clamp(Texcoord, genType(0), genType(1));
+	}
+
+	template <typename T> 
+	GLM_FUNC_QUALIFIER detail::tvec2<T> clamp
+	(
+		detail::tvec2<T> const & Texcoord
+	)
+	{
+		detail::tvec2<T> Result;
+		for(typename detail::tvec2<T>::size_type i = 0; i < detail::tvec2<T>::value_size(); ++i)
+			Result[i] = clamp(Texcoord[i]);
+		return Result;
+	}
+
+	template <typename T> 
+	GLM_FUNC_QUALIFIER detail::tvec3<T> clamp
+	(
+		detail::tvec3<T> const & Texcoord
+	)
+	{
+		detail::tvec3<T> Result;
+		for(typename detail::tvec3<T>::size_type i = 0; i < detail::tvec3<T>::value_size(); ++i)
+			Result[i] = clamp(Texcoord[i]);
+		return Result;
+	}
+
+	template <typename T> 
+	GLM_FUNC_QUALIFIER detail::tvec4<T> clamp
+	(
+		detail::tvec4<T> const & Texcoord
+	)
+	{
+		detail::tvec4<T> Result;
+		for(typename detail::tvec4<T>::size_type i = 0; i < detail::tvec4<T>::value_size(); ++i)
+			Result[i] = clamp(Texcoord[i]);
+		return Result;
+	}
+
+	////////////////////////
+	// repeat
+
+	template <typename genType> 
+	GLM_FUNC_QUALIFIER genType repeat
+	(
+		genType const & Texcoord
+	)
+	{
+		return glm::fract(Texcoord);
+	}
+
+	template <typename T> 
+	GLM_FUNC_QUALIFIER detail::tvec2<T> repeat
+	(
+		detail::tvec2<T> const & Texcoord
+	)
+	{
+		detail::tvec2<T> Result;
+		for(typename detail::tvec2<T>::size_type i = 0; i < detail::tvec2<T>::value_size(); ++i)
+			Result[i] = repeat(Texcoord[i]);
+		return Result;
+	}
+
+	template <typename T> 
+	GLM_FUNC_QUALIFIER detail::tvec3<T> repeat
+	(
+		detail::tvec3<T> const & Texcoord
+	)
+	{
+		detail::tvec3<T> Result;
+		for(typename detail::tvec3<T>::size_type i = 0; i < detail::tvec3<T>::value_size(); ++i)
+			Result[i] = repeat(Texcoord[i]);
+		return Result;
+	}
+
+	template <typename T> 
+	GLM_FUNC_QUALIFIER detail::tvec4<T> repeat
+	(
+		detail::tvec4<T> const & Texcoord
+	)
+	{
+		detail::tvec4<T> Result;
+		for(typename detail::tvec4<T>::size_type i = 0; i < detail::tvec4<T>::value_size(); ++i)
+			Result[i] = repeat(Texcoord[i]);
+		return Result;
+	}
+
+	////////////////////////
+	// mirrorRepeat
+
+	template <typename genType> 
+	GLM_FUNC_QUALIFIER genType mirrorRepeat
+	(
+		genType const & Texcoord
+	)
+	{
+		genType const Clamp = genType(int(glm::floor(Texcoord)) % 2);
+		genType const Floor = glm::floor(Texcoord);
+		genType const Rest = Texcoord - Floor;
+		genType const Mirror = Clamp + Rest;
+
+		genType Out;
+		if(Mirror >= genType(1))
+			Out = genType(1) - Rest;
+		else
+			Out = Rest;
+		return Out;
+	}
+
+	template <typename T> 
+	GLM_FUNC_QUALIFIER detail::tvec2<T> mirrorRepeat
+	(
+		detail::tvec2<T> const & Texcoord
+	)
+	{
+		detail::tvec2<T> Result;
+		for(typename detail::tvec2<T>::size_type i = 0; i < detail::tvec2<T>::value_size(); ++i)
+			Result[i] = mirrorRepeat(Texcoord[i]);
+		return Result;
+	}
+
+	template <typename T> 
+	GLM_FUNC_QUALIFIER detail::tvec3<T> mirrorRepeat
+	(
+		detail::tvec3<T> const & Texcoord
+	)
+	{
+		detail::tvec3<T> Result;
+		for(typename detail::tvec3<T>::size_type i = 0; i < detail::tvec3<T>::value_size(); ++i)
+			Result[i] = mirrorRepeat(Texcoord[i]);
+		return Result;
+	}
+
+	template <typename T> 
+	GLM_FUNC_QUALIFIER detail::tvec4<T> mirrorRepeat
+	(
+		detail::tvec4<T> const & Texcoord
+	)
+	{
+		detail::tvec4<T> Result;
+		for(typename detail::tvec4<T>::size_type i = 0; i < detail::tvec4<T>::value_size(); ++i)
+			Result[i] = mirrorRepeat(Texcoord[i]);
+		return Result;
+	}
 }//namespace glm
 }//namespace glm