Переглянути джерело

Merge branch 'experimental' of ../ogl-math-experimental

Christophe Riccio 15 роки тому
батько
коміт
490989ba01
100 змінених файлів з 29130 додано та 0 видалено
  1. 4 0
      experimental/half/half.cpp
  2. 119 0
      experimental/half/half.h
  3. 0 0
      experimental/half/half.inl
  4. 39 0
      experimental/half/half_test.cpp
  5. 6 0
      experimental/half/half_test.h
  6. 5 0
      experimental/sign.cpp
  7. 1378 0
      experimental/simd/sse.cpp
  8. 13 0
      experimental/simd/sse.h
  9. 61 0
      experimental/simd/sse_mat4.cpp
  10. 1280 0
      experimental/simd/sse_mat4.h
  11. 1 0
      experimental/simd/sse_mat4array.cpp
  12. 0 0
      experimental/simd/sse_mat4array.h
  13. 53 0
      experimental/simd/sse_vec4.cpp
  14. 290 0
      experimental/simd/sse_vec4.h
  15. 1 0
      experimental/simd/sse_vec4array.cpp
  16. 0 0
      experimental/simd/sse_vec4array.h
  17. 54 0
      experimental/sse/glm/core/_bvec2.h
  18. 159 0
      experimental/sse/glm/core/_bvec2.inl
  19. 67 0
      experimental/sse/glm/core/_bvec3.h
  20. 224 0
      experimental/sse/glm/core/_bvec3.inl
  21. 91 0
      experimental/sse/glm/core/_bvec4.h
  22. 335 0
      experimental/sse/glm/core/_bvec4.inl
  23. 113 0
      experimental/sse/glm/core/_cvec2.h
  24. 253 0
      experimental/sse/glm/core/_cvec2.inl
  25. 217 0
      experimental/sse/glm/core/_cvec3.h
  26. 849 0
      experimental/sse/glm/core/_cvec3.inl
  27. 489 0
      experimental/sse/glm/core/_cvec4.h
  28. 2450 0
      experimental/sse/glm/core/_cvec4.inl
  29. 54 0
      experimental/sse/glm/core/_cvecx.h
  30. 359 0
      experimental/sse/glm/core/_func.h
  31. 2247 0
      experimental/sse/glm/core/_func.inl
  32. 1742 0
      experimental/sse/glm/core/_swizzle.h
  33. 20 0
      experimental/sse/glm/core/_swizzle.inl
  34. 173 0
      experimental/sse/glm/core/_xmat2.h
  35. 416 0
      experimental/sse/glm/core/_xmat2.inl
  36. 143 0
      experimental/sse/glm/core/_xmat2x3.h
  37. 379 0
      experimental/sse/glm/core/_xmat2x3.inl
  38. 144 0
      experimental/sse/glm/core/_xmat2x4.h
  39. 392 0
      experimental/sse/glm/core/_xmat2x4.inl
  40. 176 0
      experimental/sse/glm/core/_xmat3.h
  41. 546 0
      experimental/sse/glm/core/_xmat3.inl
  42. 145 0
      experimental/sse/glm/core/_xmat3x2.h
  43. 451 0
      experimental/sse/glm/core/_xmat3x2.inl
  44. 145 0
      experimental/sse/glm/core/_xmat3x4.h
  45. 434 0
      experimental/sse/glm/core/_xmat3x4.inl
  46. 178 0
      experimental/sse/glm/core/_xmat4.h
  47. 633 0
      experimental/sse/glm/core/_xmat4.inl
  48. 146 0
      experimental/sse/glm/core/_xmat4x2.h
  49. 440 0
      experimental/sse/glm/core/_xmat4x2.inl
  50. 146 0
      experimental/sse/glm/core/_xmat4x3.h
  51. 460 0
      experimental/sse/glm/core/_xmat4x3.inl
  52. 38 0
      experimental/sse/glm/core/_xref2.h
  53. 107 0
      experimental/sse/glm/core/_xref2.inl
  54. 39 0
      experimental/sse/glm/core/_xref3.h
  55. 118 0
      experimental/sse/glm/core/_xref3.inl
  56. 40 0
      experimental/sse/glm/core/_xref4.h
  57. 129 0
      experimental/sse/glm/core/_xref4.inl
  58. 260 0
      experimental/sse/glm/core/_xvec2.h
  59. 802 0
      experimental/sse/glm/core/_xvec2.inl
  60. 283 0
      experimental/sse/glm/core/_xvec3.h
  61. 694 0
      experimental/sse/glm/core/_xvec3.inl
  62. 241 0
      experimental/sse/glm/core/_xvec4.h
  63. 1242 0
      experimental/sse/glm/core/_xvec4.inl
  64. 81 0
      experimental/sse/glm/ext/gtx.h
  65. 518 0
      experimental/sse/glm/ext/gtx/associated_min_max.h
  66. 911 0
      experimental/sse/glm/ext/gtx/associated_min_max.inl
  67. 76 0
      experimental/sse/glm/ext/gtx/bit.h
  68. 242 0
      experimental/sse/glm/ext/gtx/bit.inl
  69. 54 0
      experimental/sse/glm/ext/gtx/closest_point.h
  70. 31 0
      experimental/sse/glm/ext/gtx/closest_point.inl
  71. 165 0
      experimental/sse/glm/ext/gtx/color_cast.h
  72. 737 0
      experimental/sse/glm/ext/gtx/color_cast.inl
  73. 51 0
      experimental/sse/glm/ext/gtx/color_space.h
  74. 149 0
      experimental/sse/glm/ext/gtx/color_space.inl
  75. 298 0
      experimental/sse/glm/ext/gtx/compatibility.h
  76. 132 0
      experimental/sse/glm/ext/gtx/compatibility.inl
  77. 49 0
      experimental/sse/glm/ext/gtx/component_wise.h
  78. 85 0
      experimental/sse/glm/ext/gtx/component_wise.inl
  79. 45 0
      experimental/sse/glm/ext/gtx/determinant.h
  80. 47 0
      experimental/sse/glm/ext/gtx/determinant.inl
  81. 80 0
      experimental/sse/glm/ext/gtx/double.h
  82. 13 0
      experimental/sse/glm/ext/gtx/double.inl
  83. 100 0
      experimental/sse/glm/ext/gtx/epsilon.h
  84. 131 0
      experimental/sse/glm/ext/gtx/epsilon.inl
  85. 54 0
      experimental/sse/glm/ext/gtx/euler_angles.h
  86. 97 0
      experimental/sse/glm/ext/gtx/euler_angles.inl
  87. 41 0
      experimental/sse/glm/ext/gtx/extend.h
  88. 38 0
      experimental/sse/glm/ext/gtx/extend.inl
  89. 105 0
      experimental/sse/glm/ext/gtx/extented_min_max.h
  90. 155 0
      experimental/sse/glm/ext/gtx/extented_min_max.inl
  91. 84 0
      experimental/sse/glm/ext/gtx/fast_exponential.h
  92. 265 0
      experimental/sse/glm/ext/gtx/fast_exponential.inl
  93. 72 0
      experimental/sse/glm/ext/gtx/fast_square_root.h
  94. 165 0
      experimental/sse/glm/ext/gtx/fast_square_root.inl
  95. 80 0
      experimental/sse/glm/ext/gtx/fast_trigonometry.h
  96. 243 0
      experimental/sse/glm/ext/gtx/fast_trigonometry.inl
  97. 47 0
      experimental/sse/glm/ext/gtx/flexible_mix.h
  98. 58 0
      experimental/sse/glm/ext/gtx/flexible_mix.inl
  99. 169 0
      experimental/sse/glm/ext/gtx/gpu_shader4.h
  100. 949 0
      experimental/sse/glm/ext/gtx/gpu_shader4.inl

+ 4 - 0
experimental/half/half.cpp

@@ -0,0 +1,4 @@
+#include "precompiled.h"
+#include "half.h"
+
+

+ 119 - 0
experimental/half/half.h

@@ -0,0 +1,119 @@
+#ifndef __HALF_H__
+#define __HALF_H__
+
+namespace dev
+{
+/*	namespace detail 
+	{
+		class _halfGTX;
+
+		struct hdata
+		{
+			hdata() : data(0) {}
+			hdata(const hdata& value);
+			//hdata(float value);
+
+			hdata& operator=(_halfGTX s);
+			hdata& operator=(float s);
+			hdata& operator=(double s);
+
+			//operator float();
+			//operator const float() const;
+
+			short data;
+		};
+
+		float _toFloat32(hdata value);
+		hdata _toFloat16(float value);
+
+		union uif
+		{
+			int i;
+			float f;
+		};
+
+		class _halfGTX
+		{
+		public:
+			// Constructors
+			_halfGTX();
+			_halfGTX(float s);
+			_halfGTX(double s);
+			_halfGTX(int s);
+			_halfGTX(bool s);
+			_halfGTX(detail::hdata value) :
+				data(value)
+			{}
+
+			operator float() const;
+			operator double() const;
+			operator int() const;
+			operator detail::hdata() const;
+
+			// Operators
+			_halfGTX& operator=(_halfGTX s);
+			_halfGTX& operator=(float s);
+			_halfGTX operator+ (_halfGTX s) const;
+			_halfGTX& operator+= (_halfGTX s);
+			_halfGTX operator+ (float s) const;
+			_halfGTX& operator+= (float s);
+			_halfGTX operator- (_halfGTX s) const;
+			_halfGTX& operator-= (_halfGTX s);
+			_halfGTX operator- (float s) const;
+			_halfGTX& operator-= (float s);
+			_halfGTX operator* (_halfGTX s) const;
+			_halfGTX& operator*= (_halfGTX s);
+			_halfGTX operator* (float s) const;
+			_halfGTX& operator*= (float s);
+			_halfGTX operator/ (_halfGTX s) const;
+			_halfGTX& operator/= (_halfGTX s);
+			_halfGTX operator/ (float s) const;
+			_halfGTX& operator/= (float s);
+			_halfGTX operator- () const;
+			_halfGTX operator++ ();
+			_halfGTX operator++ (int n) const;
+			_halfGTX operator-- ();
+			_halfGTX operator-- (int n) const;
+
+			bool operator< (const _halfGTX& s) const;
+			bool operator> (const _halfGTX& s) const;
+			bool operator<=(const _halfGTX& s) const;
+			bool operator>=(const _halfGTX& s) const;
+			bool operator==(const _halfGTX& s) const;
+			bool operator!=(const _halfGTX& s) const;
+			
+			detail::hdata _data() const{return data;}
+
+		private:
+			detail::hdata data;
+		};
+
+		class _hvec2GTX
+		{
+		public:
+			typedef _halfGTX value_type;
+			typedef int size_type;
+			static const size_type value_size;
+
+			union 
+			{
+				struct{detail::hdata x, y;};
+				struct{detail::hdata r, g;};
+				struct{detail::hdata s, t;};
+			};
+
+			_hvec2GTX()
+			{}
+
+			_hvec2GTX(const _halfGTX x, const _halfGTX y) :
+				x(x._data()),
+				y(y._data())
+			{}
+		};
+	}
+*/
+}
+
+//#include "half.inl"
+
+#endif//__HALF_H__

+ 0 - 0
experimental/half/half.inl


+ 39 - 0
experimental/half/half_test.cpp

@@ -0,0 +1,39 @@
+#include "precompiled.h"
+#include "half_test.h"
+#include "half.h"
+
+void test_hdata()
+{
+	//dev::detail::hdata HdataA(dev::detail::_toFloat16(1.0f));
+	//dev::detail::hdata HdataB(dev::detail::_toFloat16(2.0f));
+	//float FloatA = float(dev::detail::_toFloat32(HdataA) + dev::detail::_toFloat32(HdataB));
+	//float FloatB = _toFloat32(HdataA) + _toFloat32(HdataB);
+	//float FloatC = _toFloat32(HdataA);
+	//float FloatD = _toFloat32(HdataB);
+
+	//dev::detail::_halfGTX HalfA(HdataA);
+	//dev::detail::_halfGTX HalfB(HdataB);
+	//float FloatE = float(HalfA);
+	//float FloatF = float(HalfB);
+	//dev::detail::_halfGTX HalfC(FloatE);
+	//dev::detail::_halfGTX HalfD(FloatF);
+	//float FloatG = float(HalfC);
+	//float FloatH = float(HalfD);
+
+	//dev::detail::_hvec2GTX hvec2A(HalfA, HalfB);
+	//dev::detail::_hvec2GTX hvec2B(HalfC, HalfD);
+
+	//HdataA = HalfA;
+	//HdataB = 4.0f;
+	//HdataB = 4.0;
+
+	//float FloatI = float(dev::detail::_halfGTX(HdataA));
+	//float FloatJ = float(dev::detail::_halfGTX(HdataB));
+
+	int end = 0;
+}
+
+void test_half_full()
+{
+	test_hdata();
+}

+ 6 - 0
experimental/half/half_test.h

@@ -0,0 +1,6 @@
+#ifndef __HALF_TEST_H__
+#define __HALF_TEST_H__
+
+void test_half_full();
+
+#endif//__HALF_TEST_H__

+ 5 - 0
experimental/sign.cpp

@@ -0,0 +1,5 @@
+template <>
+inline bool sign(float const & f)
+{
+	return (*((int *)(&f)) & 0x80000000) == 0;
+}

+ 1378 - 0
experimental/simd/sse.cpp

@@ -0,0 +1,1378 @@
+#include "precompiled.h"
+#include "sse.h"
+
+//namespace sse
+//{
+//	// some defines first
+//	union ieee754_QNAN
+//	{
+//	   const float f;
+//	   struct
+//	   {
+//		  const unsigned int mantissa:23, exp:8, sign:1;
+//	   };
+//	   
+//	   ieee754_QNAN() : f(0.0), mantissa(0x7FFFFF), exp(0xFF), sign(0x0) {}
+//	};
+//
+//	namespace detail
+//	{
+//		union ieee754
+//		{
+//			ieee754() :
+//				f(0.0f)
+//			{}
+//
+//			ieee754(float f) :
+//				f(f)
+//			{}
+//
+//			ieee754(unsigned int mantissa, unsigned int exp, unsigned int sign) :
+//				mantissa(mantissa), exp(exp), sign(sign)
+//			{}
+//
+//			float f;
+//			struct
+//			{
+//				unsigned int mantissa:23, exp:8, sign:1;
+//			};
+//		};
+//
+//		_MM_ALIGN16 const ieee754 qnan(0x7FFFFF, 0xFF, 0x0);
+//	}
+//
+//	float load(unsigned int mantissa, unsigned int exp, unsigned int sign)
+//	{
+//		sse::detail::ieee754 value(mantissa, exp, sign);
+//		return value.f;
+//	}
+//
+//	_MM_ALIGN16 const sse::detail::ieee754 qnan(0x7FFFFF, 0xFF, 0x0);
+//
+//	_MM_ALIGN16 const ieee754_QNAN absMask;
+//	//static const __m128 abs4Mask = _mm_load1_ps( &absMask.f);
+//	static const __m128 abs4Mask = _mm_set_ps1(absMask.f);
+//
+//	__m128 _mm_neg_ps(__m128 v)
+//	{
+//		return _mm_sub_ps(_mm_setzero_ps(), v);
+//	}
+//
+//	__m128 fast_pow(__m128 base, __m128 exponent)
+//	{
+//		__m128 denom = _mm_mul_ps( exponent, base);
+//		denom = _mm_sub_ps( exponent, denom);
+//		denom = _mm_add_ps( base, denom);
+//		return _mm_mul_ps( base, _mm_rcp_ps(denom));
+//	} 
+//
+//	static const __m128 zero = _mm_setzero_ps();
+//	static const __m128 one = _mm_set_ps1(1.0f);
+//	static const __m128 two = _mm_set_ps1(2.0f);
+//	static const __m128 pi = _mm_set_ps1(3.1415926535897932384626433832795f);
+//	static const __m128 hundred_eighty = _mm_set_ps1(180.f);
+//	static const __m128 pi_over_hundred_eighty = _mm_set_ps1(0.017453292519943295769236907684886f);
+//	static const __m128 hundred_eighty_over_pi = _mm_set_ps1(57.295779513082320876798154814105f);
+//
+//    //vec4 radians(vec4 degrees)
+//    //{
+//    //    const float pi = float(3.1415926535897932384626433832795);
+//    //    return degrees * (pi / 180.f);
+//    //}
+//    __m128 radians(__m128 degrees)
+//    {
+//        return _mm_mul_ps(degrees, pi_over_hundred_eighty);
+//    }
+//
+//    __m128 _mm_rad_ss(__m128 degrees)
+//    {
+//        return _mm_mul_ss(degrees, pi_over_hundred_eighty);
+//    }
+//
+//    __m128 _mm_rad_ps(__m128 degrees)
+//    {
+//        return _mm_mul_ps(degrees, pi_over_hundred_eighty);
+//    }
+//
+//	//vec4 degrees(vec4 radians)
+//	//{
+//	//	const float pi = float(3.1415926535897932384626433832795);
+//	//	return radians * (180.f / pi);
+//	//}
+//    __m128 degrees(__m128 radians)
+//    {
+//        return _mm_mul_ps(radians, hundred_eighty_over_pi);
+//    }
+//
+//    __m128 _mm_deg_ss(__m128 radians)
+//    {
+//        return _mm_mul_ss(radians, hundred_eighty_over_pi);
+//    }
+//
+//    __m128 _mm_deg_ps(__m128 radians)
+//    {
+//        return _mm_mul_ps(radians, hundred_eighty_over_pi);
+//    }
+//
+//	//vec4 sqrt(vec4 v)
+//	//{
+//	//	return vec4(sqrt(v.x), sqrt(v.y), sqrt(v.z), sqrt(v.w));
+//	//}
+//    __m128 sqrt(__m128 v)
+//    {
+//        return _mm_sqrt_ps(v);
+//    }
+//
+//	//vec4 inversesqrt(vec4 x)
+//	//{
+//	//	return vec4(1.0f) / sqrt(x);
+//	//}
+//    __m128 inversesqrt(__m128 v)
+//    {
+//        return _mm_rsqrt_ps(v);
+//    }
+//
+//    //vec4 abs(vec4 x)
+//    //{
+//    //    return x >= T(0) ? x : -x;
+//    //}
+//	__m128 abs(__m128 x)
+//	{
+//		return _mm_and_ps(abs4Mask, x);
+//	} 
+//
+//	//__m128 _mm_abs_ss(__m128 x)
+//	//{
+//	//	return _mm_and_ss(abs4Mask, x);
+//	//} 
+//
+//	__m128 _mm_abs_ps(__m128 x)
+//	{
+//		return _mm_and_ps(abs4Mask, x);
+//	} 
+//
+//	//vec4 sign(vec4 x)
+//	//{
+//	//	vec4 result;
+//	//	if(x > vec4(0))
+//	//		result = vec4(1);
+//	//	else if(x < T(0))
+//	//		result = vec4(-1);
+//	//	else
+//	//		result = vec4(0);
+//	//	return result;
+//	//}
+//	__m128 sign(__m128 x)
+//	{
+//		__m128 result;
+//		__m128 cmp0 = _mm_cmpeq_ps(x, zero);
+//		if(_mm_movemask_ps(cmp0) == 0)
+//			result = zero;
+//		else
+//		{
+//			__m128 cmp1 = _mm_cmpge_ps(x, zero);
+//			//__m128 cmp2 = _mm_cmple_ps(x, zero);
+//			if(_mm_movemask_ps(cmp1) > 0)
+//				result = one;
+//			else //if(_mm_movemask_ps(cmp2) > 0)
+//				result = minus_one;
+//		}
+//		return result;
+//	}
+//	
+//	__m128 _mm_sgn_ss(__m128 x)
+//	{
+//		__m128 result;
+//		__m128 cmp0 = _mm_cmpeq_ss(x, zero);
+//		if(_mm_movemask_ss(cmp0) == 0)
+//			result = zero;
+//		else
+//		{
+//			__m128 cmp1 = _mm_cmpge_ss(x, zero);
+//			//__m128 cmp2 = _mm_cmple_ss(x, zero);
+//			if(_mm_movemask_ss(cmp1) > 0)
+//				result = one;
+//			else //if(_mm_movemask_ss(cmp2) > 0)
+//				result = minus_one;
+//		}
+//		return result;
+//	}
+//
+//	__m128 _mm_sgn_ps(__m128 x)
+//	{
+//		__m128 cmp0 = _mm_cmpeq_ps(x, zero);
+//		__m128 cmp1 = _mm_cmple_ps(x, zero);
+//		__m128 cmp2 = _mm_cmpge_ps(x, zero)
+//
+//		__m128 result;
+//		__m128 cmp0 = _mm_cmpeq_ps(x, zero);
+//		if(_mm_movemask_ps(cmp0) == 0)
+//			result = zero;
+//		else
+//		{
+//			__m128 cmp1 = _mm_cmpge_ps(x, zero);
+//			//__m128 cmp2 = _mm_cmple_ps(x, zero);
+//			if(_mm_movemask_ps(cmp1) > 0)
+//				result = one;
+//			else //if(_mm_movemask_ps(cmp2) > 0)
+//				result = minus_one;
+//		}
+//		return result;
+//	}
+//
+//	//vec4 floor(vec4 x)
+//	//{
+//	//	return ::std::floor(x);
+//	//}
+//
+//	__m128 floor(__m128 v)
+//	{
+//
+//	}
+//
+//	__m128 _mm_flr_ss(__m128 v)
+//	{
+//
+//	}
+//
+//	__m128 _mm_flr_ps(__m128 v)
+//	{
+//
+//	}
+//
+//	//vec4 ceil(vec4 x)
+//	//{
+//	//	return ::std::ceil(vec4);
+//	//}
+//
+//	
+//
+//	//vec4 fract(vec4 x)
+//	//{
+//	//	return x - floor(x);
+//	//}
+//	__m128 fract(__m128 x)
+//	{
+//		__m128 flr0 = floor(x);
+//		__m128 sub0 = _mm_sub_ps(x, flr0);
+//		return sub0;
+//	}
+//
+//	__m128 _mm_frc_ss(__m128 x)
+//	{
+//		__m128 flr0 = _mm_flr_ss(x);
+//		__m128 sub0 = _mm_sub_ss(x, flr0);
+//		return sub0;
+//	}
+//
+//	__m128 _mm_frc_ps(__m128 x)
+//	{
+//		__m128 flr0 = _mm_flr_ps(x);
+//		__m128 sub0 = _mm_sub_ps(x, flr0);
+//		return sub0;
+//	}
+//
+//	//vec4 mod(vec4 x, vec4 y)
+//	//{
+//	//	return x - y * floor(x / y);
+//	//}
+//	__m128 mod(__m128 x, __m128 y)
+//	{
+//		__m128 div0 = _mm_div_ps(x, y);
+//		__m128 flr0 = _mm_flr_ps(div0);
+//		__m128 mul0 = _mm_mul_ps(y, flr0);
+//		__m128 sub0 = _mm_sub_ps(x, mul0);
+//		return sub0;
+//	}
+//
+//	__m128 _mm_mod_ss(__m128 x, __m128 y)
+//	{
+//		__m128 div0 = _mm_div_ss(x, y);
+//		__m128 flr0 = _mm_flr_ss(div0);
+//		__m128 mul0 = _mm_mul_ss(y, flr0);
+//		__m128 sub0 = _mm_sub_ss(x, mul0);
+//		return sub0;
+//	}
+//
+//	__m128 _mm_mod_ps(__m128 x, __m128 y)
+//	{
+//		__m128 div0 = _mm_div_ps(x, y);
+//		__m128 flr0 = _mm_flr_ps(div0);
+//		__m128 mul0 = _mm_mul_ps(y, flr0);
+//		__m128 sub0 = _mm_sub_ps(x, mul0);
+//		return sub0;
+//	}
+//
+//	//vec4 min(vec4 x, vec4 y)
+//	//{
+//	//	return x < y ? x : y;
+//	//}
+//	__m128 min(__m128 v1, __m128 v2)
+//	{
+//		return _mm_min_ps(v1, v2);
+//	}
+//
+//	//vec4 max(vec4 x, vec4 y)
+//    //{
+//	//	return x > y ? x : y;
+//    //}
+//	__m128 max(__m128 v1, __m128 v2)
+//	{
+//		return _mm_max_ps(v1, v2);
+//	}
+//
+//    //vec4 clamp(vec4 x, vec4 minVal, vec4 maxVal)
+//    //{
+//	//	return max(min(v, maxVal), minVal);
+//    //}
+//	__m128 clamp(__m128 v, __m128 minVal, __m128 maxVal)
+//	{
+//		return _mm_max_ps(_mm_min_ps(v, maxVal), minVal);
+//	}
+//
+//	__m128 _mm_clp_ss(__m128 v, __m128 minVal, __m128 maxVal)
+//	{
+//		__m128 min0 = _mm_min_ss(v, maxVal);
+//		__m128 max0 = _mm_max_ss(min0, minVal);
+//		return max0;
+//	}
+//
+//	__m128 _mm_clp_ps(__m128 v, __m128 minVal, __m128 maxVal)
+//	{
+//		__m128 min0 = _mm_min_ps(v, maxVal);
+//		__m128 max0 = _mm_max_ps(min0, minVal);
+//		return max0;
+//	}
+//
+//    //vec4 mix(vec4 x, vec4 y, vec4 a)
+//    //{
+//    //    return x * (vec4(1) - a) + y * a;
+//    //}
+//	__m128 mix(__m128 v1, __m128 v2, __m128 a)
+//	{
+//		__m128 sub0 = _mm_sub_ps(one, a);
+//		__m128 mul0 = _mm_mul_ps(v1, sub0);
+//		__m128 mul1 = _mm_mul_ps(v2, a);
+//		__m128 add0 = _mm_add_ps(mul0, mul1);
+//		return add0;
+//	}
+//
+//	__m128 _mm_lerp_ss(__m128 v1, __m128 v2, __m128 a)
+//	{
+//		__m128 sub0 = _mm_sub_ss(one, a);
+//		__m128 mul0 = _mm_mul_ss(v1, sub0);
+//		__m128 mul1 = _mm_mul_ss(v2, a);
+//		__m128 add0 = _mm_add_ss(mul0, mul1);
+//		return add0;
+//	}
+//
+//	__m128 _mm_lerp_ps(__m128 v1, __m128 v2, __m128 a)
+//	{
+//		__m128 sub0 = _mm_sub_ps(one, a);
+//		__m128 mul0 = _mm_mul_ps(v1, sub0);
+//		__m128 mul1 = _mm_mul_ps(v2, a);
+//		__m128 add0 = _mm_add_ps(mul0, mul1);
+//		return add0;
+//	}
+//
+//    //vec4 step(vec4 edge, vec4 x)
+//    //{
+//    //    return x <= edge ? vec4(0) : vec4(1);
+//    //}
+//    __m128 step(__m128 edge, __m128 x)
+//    {
+//		__m128 cmp = _mm_cmple_ps(x, edge);
+//		if(_mm_movemask_ps(cmp) == 0)
+//			return one;
+//		else
+//			return zero;
+//    }
+//
+//    __m128 _mm_step_ss(__m128 edge, __m128 x)
+//    {
+//		__m128 cmp = _mm_cmple_ss(x, edge);
+//		if(_mm_movemask_ss(cmp) == 0)
+//			return one;
+//		else
+//			return zero;
+//    }
+//
+//    __m128 _mm_step_ps(__m128 edge, __m128 x)
+//    {
+//		__m128 cmp = _mm_cmple_ps(x, edge);
+//		if(_mm_movemask_ps(cmp) == 0)
+//			return one;
+//		else
+//			return zero;
+//    }
+//
+//    //vec4 smoothstep(vec4 edge0, vec4 edge1, vec4 x)
+//    //{
+//    //    vec4 tmp = clamp((x - edge0) / (edge1 - edge0), vec4(0), vec4(1));
+//    //    return tmp * tmp * (vec4(3) - vec4(2) * tmp);
+//    //}
+//    __m128 smoothstep(__m128 edge0, __m128 edge1, __m128 x)
+//    {
+//		__m128 sub0 = _mm_sub_ps(x, edge0);
+//		__m128 sub1 = _mm_sub_ps(edge1, edge0);
+//		__m128 div0 = _mm_sub_ps(sub0, sub1);
+//		__m128 clp0 = _mm_clp_ps(div0, zero, one);
+//		__m128 mul0 = _mm_mul_ps(two, clp0);
+//		__m128 sub2 = _mm_sub_ps(three, mul0);
+//		__m128 mul1 = _mm_mul_ps(clp0, clp0);
+//		__m128 mul2 = _mm_mul_ps(mul1, sub2);
+//		return mul2;
+//    }
+//
+//    __m128 _mm_ssp_ss(__m128 edge0, __m128 edge1, __m128 x)
+//    {
+//		__m128 sub0 = _mm_sub_ss(x, edge0);
+//		__m128 sub1 = _mm_sub_ss(edge1, edge0);
+//		__m128 div0 = _mm_sub_ss(sub0, sub1);
+//		__m128 clp0 = _mm_clp_ss(div0, zero, one);
+//		__m128 mul0 = _mm_mul_ss(two, clp0);
+//		__m128 sub2 = _mm_sub_ss(three, mul0);
+//		__m128 mul1 = _mm_mul_ss(clp0, clp0);
+//		__m128 mul2 = _mm_mul_ss(mul1, sub2);
+//		return mul2;
+//    }
+//
+//    __m128 _mm_ssp_ps(__m128 edge0, __m128 edge1, __m128 x)
+//    {
+//		__m128 sub0 = _mm_sub_ps(x, edge0);
+//		__m128 sub1 = _mm_sub_ps(edge1, edge0);
+//		__m128 div0 = _mm_sub_ps(sub0, sub1);
+//		__m128 clp0 = _mm_clp_ps(div0, zero, one);
+//		__m128 mul0 = _mm_mul_ps(two, clp0);
+//		__m128 sub2 = _mm_sub_ps(three, mul0);
+//		__m128 mul1 = _mm_mul_ps(clp0, clp0);
+//		__m128 mul2 = _mm_mul_ps(mul1, sub2);
+//		return mul2;
+//    }
+//
+//    //float length(vec4 x)
+//    //{
+//    //    float sqr = x.x * x.x + x.y * x.y + x.z * x.z + x.w * x.w;
+//    //    return sqrt(sqr);
+//    //}
+//    __m128 length(__m128 x)
+//    {
+//        __m128 dot0 = dot(x, x);
+//		__m128 sqt0 = _mm_sqrt_ps(dot0);
+//        return sqt0;
+//    }
+//
+//    __m128 _mm_len_ss(__m128 x)
+//    {
+//        __m128 dot0 = _mm_dot_ss(x, x);
+//		__m128 sqt0 = _mm_sqrt_ss(dot0);
+//        return sqt0;
+//    }
+//
+//    __m128 _mm_len_ps(__m128 x)
+//    {
+//        __m128 dot0 = _mm_dot_ps(x, x);
+//		__m128 sqt0 = _mm_sqrt_ps(dot0);
+//        return sqt0;
+//    }
+//
+//    //float distance(vec4 p0, vec4 p1)
+//    //{
+//    //    return length(p1 - p0);
+//    //}
+//    __m128 distance(__m128 p0, __m128 p1)
+//    {
+//		__m128 sub0 = _mm_sub_ps(p0, p1);
+//        __m128 len0 = _mm_len_ps(sub0);
+//        return len0;
+//    }
+//
+//    __m128 _mm_dst_ss(__m128 p0, __m128 p1)
+//    {
+//		__m128 sub0 = _mm_sub_ps(p0, p1);
+//        __m128 len0 = _mm_len_ps(sub0);
+//        return len0;
+//    }
+//
+//    __m128 _mm_dst_ps(__m128 p0, __m128 p1)
+//    {
+//		__m128 sub0 = _mm_sub_ps(p0, p1);
+//        __m128 len0 = _mm_len_ps(sub0);
+//        return len0;
+//    }
+//
+//    //vec4 dot(vec4 x, vec4 y)
+//    //{
+//    //    return vec4(x.x * y.x + x.y * y.y + x.z * y.z + x.w * y.w);
+//    //}
+//	__m128 dot(__m128 v1, __m128 v2)
+//	{
+//		__m128 mul0 = _mm_mul_ps(v1, v2);
+//		__m128 swp0 = _mm_shuffle_ps(mul0, mul0, _MM_SHUFFLE(2, 3, 0, 1));
+//		__m128 add0 = _mm_add_ps(mul0, swp0);
+//		__m128 swp1 = _mm_shuffle_ps(add0, add0, _MM_SHUFFLE(0, 1, 2, 3));
+//		__m128 add1 = _mm_add_ps(add0, swp1);
+//		return add1;
+//	}
+//
+//	__m128 _mm_dot_ss(__m128 v1, __m128 v2)
+//	{
+//		__m128 mul0 = _mm_mul_ps(v1, v2);
+//		__m128 swp0 = _mm_shuffle_ps(mul0, mul0, _MM_SHUFFLE(2, 3, 0, 1));
+//		__m128 add0 = _mm_add_ps(mul0, swp0);
+//		__m128 swp1 = _mm_shuffle_ps(add0, add0, _MM_SHUFFLE(0, 1, 2, 3));
+//		__m128 add1 = _mm_add_ps(add0, swp1);
+//		return add1;
+//	}
+//
+//	__m128 _mm_dot_ps(__m128 v1, __m128 v2)
+//	{
+//		__m128 mul0 = _mm_mul_ps(v1, v2);
+//		__m128 swp0 = _mm_shuffle_ps(mul0, mul0, _MM_SHUFFLE(2, 3, 0, 1));
+//		__m128 add0 = _mm_add_ps(mul0, swp0);
+//		__m128 swp1 = _mm_shuffle_ps(add0, add0, _MM_SHUFFLE(0, 1, 2, 3));
+//		__m128 add1 = _mm_add_ps(add0, swp1);
+//		return add1;
+//	}
+//
+//    //vec3 cross(vec3 x, vec3 y)
+//    //{
+//    //    return vec3(
+//    //        x.y * y.z - y.y * x.z,
+//    //        x.z * y.x - y.z * x.x,
+//    //        x.x * y.y - y.x * x.y);
+//    //}
+//    __m128 cross(__m128 v1, __m128 v2)
+//    {
+//		__m128 swp0 = _mm_shuffle_ps(v1, v1, _MM_SHUFFLE(3, 0, 2, 1));
+//		__m128 swp1 = _mm_shuffle_ps(v1, v1, _MM_SHUFFLE(3, 1, 0, 2));
+//		__m128 swp2 = _mm_shuffle_ps(v2, v2, _MM_SHUFFLE(3, 0, 2, 1));
+//		__m128 swp3 = _mm_shuffle_ps(v2, v2, _MM_SHUFFLE(3, 1, 0, 2));
+//		__m128 mul0 = _mm_mul_ps(swp0, swp3);
+//		__m128 mul1 = _mm_mul_ps(swp1, swp2);
+//		__m128 sub0 = _mm_sub_ps(mul0, mul1);
+//		return sub0;
+//    }
+//
+//    __m128 _mm_xpd_ps(__m128 v1, __m128 v2)
+//    {
+//		__m128 swp0 = _mm_shuffle_ps(v1, v1, _MM_SHUFFLE(3, 0, 2, 1));
+//		__m128 swp1 = _mm_shuffle_ps(v1, v1, _MM_SHUFFLE(3, 1, 0, 2));
+//		__m128 swp2 = _mm_shuffle_ps(v2, v2, _MM_SHUFFLE(3, 0, 2, 1));
+//		__m128 swp3 = _mm_shuffle_ps(v2, v2, _MM_SHUFFLE(3, 1, 0, 2));
+//		__m128 mul0 = _mm_mul_ps(swp0, swp3);
+//		__m128 mul1 = _mm_mul_ps(swp1, swp2);
+//		__m128 sub0 = _mm_sub_ps(mul0, mul1);
+//		return sub0;
+//    }
+//
+//    //vec4 normalize(vec4 x)
+//    //{
+//    //    float sqr = x.x * x.x + x.y * x.y + x.z * x.z + x.w * x.w;
+//	   // return x * inversesqrt(sqr);
+//    //}
+//	__m128 normalize(__m128 v)
+//	{
+//		__m128 dot0 = dot(v, v);
+//		__m128 isr0 = _mm_rsqrt_ps(dot0);
+//		__m128 mul0 = _mm_mul_ps(v, isr0);
+//		return mul0;
+//	}
+//
+//	__m128 _mm_nrm_ps(__m128 v)
+//	{
+//		__m128 dot0 = dot(v, v);
+//		__m128 isr0 = _mm_rsqrt_ps(dot0);
+//		__m128 mul0 = _mm_mul_ps(v, isr0);
+//		return mul0;
+//	}
+//
+//	__m128 rcp(__m128 v)
+//	{
+//		return _mm_rcp_ps(v);
+//	}
+//
+//    //vec4 mad(vec4 v0, vec4 v1, vec4 v2)
+//    //{
+//	//	return v0 * v1 + v2;
+//    //}
+//	__m128 mad(__m128 v0, __m128 v1, __m128 v2)
+//	{
+//		__m128 mul0 = _mm_mul_ps(v0, v1);
+//		__m128 add0 = _mm_add_ps(mul0, v2);
+//		return add0;
+//	}
+//
+//	__m128 _mm_mad_ss(__m128 v0, __m128 v1, __m128 v2)
+//	{
+//		__m128 mul0 = _mm_mul_ss(v0, v1);
+//		__m128 add0 = _mm_add_ss(mul0, v2);
+//		return add0;
+//	}
+//
+//	__m128 _mm_mad_ps(__m128 v0, __m128 v1, __m128 v2)
+//	{
+//		__m128 mul0 = _mm_mul_ps(v0, v1);
+//		__m128 add0 = _mm_add_ps(mul0, v2);
+//		return add0;
+//	}
+//
+//	//vec4 reflect(vec4 I, vec4 N)
+//	//{
+//	//	return I - N * dot(N, I) * 2.0f;
+//	//}
+//	__m128 reflect(__m128 I, __m128 N)
+//	{
+//		__m128 dot0 = dot(N, I);
+//		__m128 mul0 = _mm_mul_ps(N, I);
+//		__m128 mul1 = _mm_mul_ps(mul0, two);
+//		__m128 sub0 = _mm_sub_ps(I, mul1);
+//		return sub0;
+//	}
+//
+//	__m128 _mm_rfe_ps(__m128 I, __m128 N)
+//	{
+//		__m128 dot0 = dot(N, I);
+//		__m128 mul0 = _mm_mul_ps(N, I);
+//		__m128 mul1 = _mm_mul_ps(mul0, two);
+//		__m128 sub0 = _mm_sub_ps(I, mul1);
+//		return sub0;
+//	}
+//
+//	//vec4 refract(vec4 I, vec4 N, T eta)
+//	//{
+//	//	float dotValue = dot(N, I);
+//	//	float k = 1.0f - eta * eta * (1.0f - dotValue * dotValue);
+//	//	if(k < 0.0f)
+//	//		return vec4(0.0f);
+//	//	return eta * I - (eta * dotValue + sqrt(k)) * N;
+//	//}
+//	__m128 refract(__m128 I, __m128 N, __m128 eta)
+//	{
+//		__m128 dot0 = dot(N, I);
+//		__m128 mul0 = _mm_mul_ps(eta, eta);
+//		__m128 mul1 = _mm_mul_ps(dot0, dot0);
+//		__m128 sub0 = _mm_sub_ps(one, mul0);
+//		__m128 sub1 = _mm_sub_ps(one, mul1);
+//		__m128 mul2 = _mm_mul_ps(sub0, sub1);
+//		
+//		if(_mm_movemask_ps(_mm_cmplt_ss(mul2, zero)) == 0)
+//			return zero;
+//
+//		__m128 sqt0 = _mm_sqrt_ps(mul2);
+//		__m128 mul3 = _mm_mul_ps(eta, dot0);
+//		__m128 add0 = _mm_add_ps(mul3, sqt0);
+//		__m128 mul4 = _mm_mul_ps(add0, N);
+//		__m128 mul5 = _mm_mul_ps(eta, I);
+//		__m128 sub2 = _mm_sub_ps(mul5, mul4);
+//
+//		return sub2;
+//	}
+//
+//	__m128 _mm_rfa_ps(__m128 I, __m128 N, __m128 eta)
+//	{
+//		__m128 dot0 = dot(N, I);
+//		__m128 mul0 = _mm_mul_ps(eta, eta);
+//		__m128 mul1 = _mm_mul_ps(dot0, dot0);
+//		__m128 sub0 = _mm_sub_ps(one, mul0);
+//		__m128 sub1 = _mm_sub_ps(one, mul1);
+//		__m128 mul2 = _mm_mul_ps(sub0, sub1);
+//		
+//		if(_mm_movemask_ps(_mm_cmplt_ss(mul2, zero)) == 0)
+//			return zero;
+//
+//		__m128 sqt0 = _mm_sqrt_ps(mul2);
+//		__m128 mul3 = _mm_mul_ps(eta, dot0);
+//		__m128 add0 = _mm_add_ps(mul3, sqt0);
+//		__m128 mul4 = _mm_mul_ps(add0, N);
+//		__m128 mul5 = _mm_mul_ps(eta, I);
+//		__m128 sub2 = _mm_sub_ps(mul5, mul4);
+//
+//		return sub2;
+//	}
+//
+//
+//	struct vec4;
+//	typedef const vec4& vec4_param;
+//
+//	template <int N>
+//	class comp
+//	{
+//	public:
+//		comp(int i) :
+//			index(i)
+//		{
+//			assert(i < N && i >= 0);
+//		}
+//
+//		operator const int() const{return index;}
+//
+//	private:
+//		int index;
+//	};
+//
+//	typedef comp<4> comp4_t;
+//
+//	struct vec4
+//	{
+//		vec4();
+//		vec4(float s);
+//		vec4(float x, float y, float z, float w);
+//		vec4(float v[4]);
+//
+//		explicit vec4(__m128 data);
+//		
+//        vec4& operator= (vec4_param v);
+//	    vec4& operator+=(float s);
+//	    vec4& operator+=(vec4_param v);
+//	    vec4& operator-=(float s);
+//	    vec4& operator-=(vec4_param v);
+//	    vec4& operator*=(float s);
+//	    vec4& operator*=(vec4_param v);
+//	    vec4& operator/=(float s);
+//	    vec4& operator/=(vec4_param v);
+//	    vec4& operator++();
+//        vec4& operator--();
+//
+//		union
+//		{
+//			__m128 data;
+//			struct{float x, y, z, w;};
+//			float array[4];
+//		};
+//	};
+//
+//	vec4::vec4() :
+//		data(_mm_setzero_ps())
+//	{}
+//
+//	vec4::vec4(float s) :
+//		data(_mm_load_ps1(&s))
+////		data(_mm_set_ps1(s))
+//	{}
+//
+//	vec4::vec4(float v[4]) :
+//		data(_mm_load_ps(v))
+//	{}
+//
+//	vec4::vec4(float x, float y, float z, float w) :
+////		data(_mm_setr_ps(x, y, z, w))
+//		data(_mm_set_ps(w, z, y, x))
+//	{}
+//
+//	vec4::vec4(__m128 data) :
+//		data(data)
+//	{}
+//
+//    vec4& vec4::operator= (vec4_param v)
+//	{
+//		this->data = v.data;
+//		return *this;
+//	}
+//
+//    vec4& vec4::operator+=(float s)
+//	{
+//		vec4 tmp(s);
+//		this->data = _mm_add_ps(this->data , tmp.data);
+//		return *this;
+//	}
+//
+//    vec4& vec4::operator+=(vec4_param v)
+//	{
+//		this->data = _mm_add_ps(this->data , v.data);
+//		return *this;
+//	}
+//
+//    vec4& vec4::operator-=(float s)
+//	{
+//		vec4 tmp(s);
+//		this->data = _mm_sub_ps(this->data , tmp.data);
+//		return *this;
+//	}
+//
+//    vec4& vec4::operator-=(vec4_param v)
+//	{
+//		this->data = _mm_sub_ps(this->data , v.data);
+//		return *this;
+//	}
+//
+//    vec4& vec4::operator*=(float s)
+//	{
+//		vec4 tmp(s);
+//		this->data = _mm_mul_ps(this->data , tmp.data);
+//		return *this;
+//	}
+//
+//    vec4& vec4::operator*=(vec4_param v)
+//	{
+//		this->data = _mm_mul_ps(this->data , v.data);
+//		return *this;
+//	}
+//
+//    vec4& vec4::operator/=(float s)
+//	{
+//		vec4 tmp(s);
+//		this->data = _mm_div_ps(this->data , tmp.data);
+//		return *this;
+//	}
+//
+//    vec4& vec4::operator/=(vec4_param v)
+//	{
+//		this->data = _mm_div_ps(this->data , v.data);
+//		return *this;
+//	}
+//
+//    vec4& vec4::operator++()
+//	{
+//		static __m128 inc = _mm_set_ps1(1.0f);
+//		this->data = _mm_add_ps(this->data , inc);
+//		return *this;
+//	}
+//
+//    vec4& vec4::operator--()
+//	{
+//		static __m128 inc = _mm_set_ps1(1.0f);
+//		this->data = _mm_sub_ps(this->data , inc);
+//		return *this;
+//	}
+//
+//	vec4 operator+ (const vec4& v1, const vec4& v2)
+//	{
+//		return vec4(_mm_add_ps(v1.data , v2.data));
+//	}
+//
+//	vec4 operator+ (const vec4& v1, const float s)
+//	{
+//		vec4 v2(s);
+//		return vec4(_mm_add_ps(v1.data , v2.data));
+//	}
+//
+//	vec4 operator+ (const float s, const vec4& v2)
+//	{
+//		vec4 v1(s);
+//		return vec4(_mm_add_ps(v1.data , v2.data));
+//	}
+//
+//	vec4 operator- (const vec4& v1, const vec4& v2)
+//	{
+//		return vec4(_mm_sub_ps(v1.data , v2.data));
+//	}
+//
+//	vec4 operator- (const vec4& v1, const float s)
+//	{
+//		vec4 v2(s);
+//		return vec4(_mm_sub_ps(v1.data , v2.data));
+//	}
+//
+//	vec4 operator- (const float s, const vec4& v2)
+//	{
+//		vec4 v1(s);
+//		return vec4(_mm_sub_ps(v1.data , v2.data));
+//	}
+//
+//	vec4 operator* (const vec4& v1, const vec4& v2)
+//	{
+//		return vec4(_mm_mul_ps(v1.data , v2.data));
+//	}
+//
+//	vec4 operator* (const vec4& v1, const float s)
+//	{
+//		vec4 v2(s);
+//		return vec4(_mm_mul_ps(v1.data , v2.data));
+//	}
+//
+//	vec4 operator* (const float s, const vec4& v2)
+//	{
+//		vec4 v1(s);
+//		return vec4(_mm_mul_ps(v1.data , v2.data));
+//	}
+//
+//	vec4 operator/ (const vec4& v1, const vec4& v2)
+//	{
+//		return vec4(_mm_div_ps(v1.data , v2.data));
+//	}
+//
+//	vec4 operator/ (const vec4& v1, const float s)
+//	{
+//		vec4 v2(s);
+//		return vec4(_mm_div_ps(v1.data , v2.data));
+//	}
+//
+//	vec4 operator/ (const float s, const vec4& v2)
+//	{
+//		vec4 v1(s);
+//		return vec4(_mm_div_ps(v1.data , v2.data));
+//	}
+//
+//	vec4 load(const vec4& v, const comp4_t component)
+//	{
+//		switch(component)
+//		{
+//		default:
+//		case 3:
+//			return vec4(_mm_shuffle_ps(v.data, v.data, _MM_SHUFFLE(0, 0, 0, 0)));
+//		case 2:
+//			return vec4(_mm_shuffle_ps(v.data, v.data, _MM_SHUFFLE(1, 1, 1, 1)));
+//		case 1:
+//			return vec4(_mm_shuffle_ps(v.data, v.data, _MM_SHUFFLE(2, 2, 2, 2)));
+//		case 0:
+//			return vec4(_mm_shuffle_ps(v.data, v.data, _MM_SHUFFLE(3, 3, 3, 3)));
+//		}
+//	}
+//
+//	vec4 rcp(vec4_param v)
+//	{
+//		return vec4(_mm_rcp_ps(v.data));
+//	}
+//
+//	vec4 sqrt(vec4_param v)
+//	{
+//		return vec4(_mm_sqrt_ps(v.data));
+//	}
+//
+//	vec4 inversesqrt(vec4_param v)
+//	{
+//		return vec4(_mm_rsqrt_ps(v.data));
+//	}
+//
+//	vec4 min(vec4_param v1, vec4_param v2)
+//	{
+//		return vec4(_mm_min_ps(v1.data, v2.data));
+//	}
+//
+//	vec4 max(vec4_param v1, vec4_param v2)
+//	{
+//		return vec4(_mm_max_ps(v1.data, v2.data));
+//	}
+//
+//	vec4 clamp(vec4_param v, float minVal, float maxVal)
+//	{
+//		vec4 v1(minVal);
+//		vec4 v2(maxVal);
+//		return vec4(_mm_min_ps(_mm_max_ps(v.data, v2.data), v1.data));
+//	}
+//
+//	vec4 clamp(vec4_param v, vec4_param minVal, vec4_param maxVal)
+//	{
+//		return vec4(_mm_min_ps(_mm_max_ps(v.data, maxVal.data), minVal.data));
+//	}
+//
+//	vec4 mix(vec4_param x, vec4_param y, vec4_param a)
+//	{
+//		__m128 one = _mm_set_ps1(1.0f);
+//		__m128 b = _mm_sub_ps(one, a.data);
+//		__m128 mul1 = _mm_mul_ps(x.data, b);
+//		__m128 mul2 = _mm_mul_ps(y.data, a.data);
+//		__m128 addFinal = _mm_add_ps(mul1, mul2);
+//		return vec4(addFinal);
+//
+//
+////		__m128 b = _mm_sub_ps(_mm_set_ps1(1.0f), a.data);
+////		return vec4(_mm_add_ps(_mm_mul_ps(x.data, b), _mm_mul_ps(y.data, a.data)));
+//	}
+//
+//	float dot(vec4_param x, vec4_param y)
+//	{
+//		float result = 0.0f;
+//		_mm_store_ss(&result, dot(x.data, y.data));
+//		return result;
+//	}
+//
+//    vec4 reflect(vec4_param I, vec4_param N)
+//    {
+//		__m128 Normal = N.data;
+//		__m128 Inc = I.data;
+//		__m128 Two = _mm_set_ps1(2.0f);
+//		__m128 Mul = _mm_mul_ps(Normal, dot(Normal, Inc));
+//        return vec4(_mm_sub_ps(Inc, _mm_mul_ps(Mul, Two)));
+//    }
+//
+//    vec4 refract(vec4_param I, vec4_param N, float eta)
+//	{
+//		__m128 zero = _mm_set_ps1(0.0f);
+//		__m128 eta1 = _mm_set_ps1(eta);
+//		__m128 eta2 = _mm_mul_ps(eta1, eta1);
+//		__m128 one = _mm_set_ps1(1.0f);
+//		__m128 dotValue = dot(I.data, N.data);
+//		__m128 dotValue2 = _mm_mul_ps(dotValue, dotValue);
+//		__m128 k = _mm_sub_ps(one, _mm_mul_ps(eta2, _mm_sub_ps(one, dotValue2)));
+//		__m128 isnull = _mm_cmplt_ss(k, zero);
+//		if(_mm_movemask_ps(isnull) == 0)
+//			return vec4(zero);
+//		else
+//		{
+//			__m128 temp0 = _mm_add_ps(_mm_mul_ps(eta1, dotValue), sqrt(k));
+//			__m128 temp1 = _mm_shuffle_ps(temp0, temp0, _MM_SHUFFLE(0, 0, 0, 0));
+//			__m128 temp2 = _mm_mul_ps(temp1, N.data);
+//			__m128 temp3 = _mm_mul_ps(eta1, I.data);
+//			return vec4(_mm_sub_ps(temp3, temp2));
+//		}
+//	}
+//
+//
+//};
+//
+//namespace glm
+//{
+//	glm::vec4 rcp(const glm::vec4& v)
+//	{
+//		return 1.0f / v;
+//	}
+//}
+//
+//namespace cpu
+//{
+//	void sincos(float a, float &s, float &c) 
+//	{
+//		_asm 
+//		{
+//			fld		a
+//			fsincos
+//			mov		ecx, c
+//			mov		edx, s
+//			fstp	dword ptr [ecx]
+//			fstp	dword ptr [edx]
+//		}
+//	}
+//
+//	void sincos(double a, double& s, double& c) 
+//	{
+//		_asm 
+//		{
+//			fld		a
+//			fsincos
+//			mov		ecx, c
+//			mov		edx, s
+//			fstp	qword ptr [ecx]
+//			fstp	qword ptr [edx]
+//		}
+//	}
+//
+//	float sin(float s) 
+//	{
+//		float result = 0.0f;
+//		float* p = &result;
+//		_asm 
+//		{
+//			fld		s
+//			fsin	
+//			mov		ecx, p
+//			fstp	dword ptr [ecx]
+//		}
+//		return result;
+//
+//		//float result = 0.0f;
+//		//_asm 
+//		//{
+//		//	fld		s
+//		//	fsin	
+//		//	mov		ecx, result
+//		//	fstp	dword ptr [ecx]
+//		//}
+//		//return result;
+//	}
+//
+//	float abs(float s) 
+//	{
+//		float result = 0.0f;
+//		float* p = &result;
+//		_asm 
+//		{
+//			fld		s
+//			fabs	
+//			mov		ecx, p
+//			fstp	dword ptr [ecx]
+//		}
+//		return result;
+//
+//		//float result = 0.0f;
+//		//_asm 
+//		//{
+//		//	fld		s
+//		//	fsin	
+//		//	mov		ecx, result
+//		//	fstp	dword ptr [ecx]
+//		//}
+//		//return result;
+//	}
+//
+//	float add(float s1, float s2)
+//	{
+//		float result = 0.0f;
+//		float* p = &result;
+//		_asm 
+//		{
+//			fld		s1
+//			fld		s2
+//			fadd	
+//			mov		ecx, p
+//			fstp	dword ptr [ecx]
+//		}
+//		return result;
+//	}
+//
+//	float sub(float s1, float s2)
+//	{
+//		float result = 0.0f;
+//		float* p = &result;
+//		_asm 
+//		{
+//			fld		s1
+//			fld		s2
+//			fsub	
+//			mov		ecx, p
+//			fstp	dword ptr [ecx]
+//		}
+//		return result;
+//	}
+//
+//	float mul(float s1, float s2)
+//	{
+//		float result = 0.0f;
+//		float* p = &result;
+//		_asm 
+//		{
+//			fld		s1
+//			fld		s2
+//			fmul	
+//			mov		ecx, p
+//			fstp	dword ptr [ecx]
+//		}
+//		return result;
+//	}
+//
+//	float div(float s1, float s2)
+//	{
+//		float result = 0.0f;
+//		float* p = &result;
+//		_asm 
+//		{
+//			fld		s1
+//			fld		s2
+//			fdiv	
+//			mov		ecx, p
+//			fstp	dword ptr [ecx]
+//		}
+//		return result;
+//	}
+//}
+//
+//void test_asm()
+//{
+//	float sin0 = cpu::sin(1.0f);
+//	float sin1 = glm::sin(1.0f);
+//	float add0 = cpu::add(1.0f, 2.0f);
+//	float sub0 = cpu::sub(1.0f, 2.0f);
+//	
+//
+//	float end = 1.0f;
+//}
+//
+//void test_clamp()
+//{
+//	sse::vec4 v(0.5f, 0.5f, 9.5f, 9.5f);
+//	sse::vec4 minVal(1.0f, 2.0f, 3.0f, 4.0f);
+//	sse::vec4 maxVal(5.0f, 6.0f, 7.0f, 8.0f);
+//
+//	__m128 clamp0 = sse::clamp(
+//		v.data, 
+//		minVal.data, 
+//		maxVal.data);
+//
+//	glm::vec4 clamp1 = glm::clamp(
+//		glm::vec4(0.5f, 0.5f, 9.5f, 9.5f),
+//		glm::vec4(1.0f, 2.0f, 3.0f, 4.0f),
+//		glm::vec4(5.0f, 6.0f, 7.0f, 8.0f));
+//
+//	__m128 end = _mm_setzero_ps();
+//}
+//
+//#define DECLARE_EPI32_CONST(name) \
+//  extern const _MM_ALIGN16 int _epi32_##name[4];
+//#define IMPLEMENT_EPI32_CONST(name,x) \
+//  const _MM_ALIGN16 int _epi32_##name[4]={x,x,x,x};
+//#define IMPLEMENT_EPI32_CONST4(name,x,y,z,w)  \
+//  const _MM_ALIGN16 int _epi32_##name[4]={w,z,y,x};
+//
+//#define DECLARE_PS_CONST(name) \
+//  extern const _MM_ALIGN16 float _ps_##name[4];
+//#define IMPLEMENT_PS_CONST(name,x)  \
+//  const _MM_ALIGN16 float _ps_##name[4]={x,x,x,x};
+//#define IMPLEMENT_PS_CONST4(name,x,y,z,w) \
+//  const _MM_ALIGN16 float _ps_##name[4]={w,z,y,x}; 
+//
+////IMPLEMENT_PS_CONST(sincos_p0,  0.15707963267948963959e1f)
+////IMPLEMENT_PS_CONST(sincos_p1, -0.64596409750621907082e0f)
+////IMPLEMENT_PS_CONST(sincos_p2,  0.7969262624561800806e-1f)
+////IMPLEMENT_PS_CONST(sincos_p3, -0.468175413106023168e-2f) 
+//
+//IMPLEMENT_EPI32_CONST(sign_mask,0x80000000)
+//IMPLEMENT_EPI32_CONST(inv_sign_mask,0x7FFFFFFF)
+//IMPLEMENT_EPI32_CONST(mant_mask,0x7F800000)
+//IMPLEMENT_EPI32_CONST(inv_mant_mask,0x807FFFFF)
+//IMPLEMENT_EPI32_CONST(min_norm_pos,0x00800000)
+//IMPLEMENT_EPI32_CONST(1,1)
+//IMPLEMENT_EPI32_CONST(2,2)
+//IMPLEMENT_EPI32_CONST(7,7)
+//IMPLEMENT_EPI32_CONST(127,127)
+//IMPLEMENT_EPI32_CONST(ninf,0xFF800000)
+//IMPLEMENT_EPI32_CONST(pinf,0x7F800000)
+//
+//IMPLEMENT_PS_CONST(1_3,0.33333333333333333333333333333333f)
+//IMPLEMENT_PS_CONST(0p5,0.5f)
+//IMPLEMENT_PS_CONST(1,1.0f)
+//IMPLEMENT_PS_CONST(m1,-1.0f)
+//IMPLEMENT_PS_CONST(2,2.0f)
+//IMPLEMENT_PS_CONST(3,3.0f)
+//IMPLEMENT_PS_CONST(127,127.0f)
+//IMPLEMENT_PS_CONST(255,255.0f)
+//IMPLEMENT_PS_CONST(2pow23,8388608.0f)
+//
+//IMPLEMENT_PS_CONST4(1_0_0_0,1.0f,0.0f,0.0f,0.0f)
+//IMPLEMENT_PS_CONST4(0_1_0_0,0.0f,1.0f,0.0f,0.0f)
+//IMPLEMENT_PS_CONST4(0_0_1_0,0.0f,0.0f,1.0f,0.0f)
+//IMPLEMENT_PS_CONST4(0_0_0_1,0.0f,0.0f,0.0f,1.0f)
+//
+//IMPLEMENT_PS_CONST(pi,    3.1415926535897932384626433832795f)
+//IMPLEMENT_PS_CONST(pi2,   6.283185307179586476925286766560f)
+//IMPLEMENT_PS_CONST(2_pi,  0.63661977236758134307553505349006f)
+//IMPLEMENT_PS_CONST(pi_2,  1.5707963267948966192313216916398f)
+//IMPLEMENT_PS_CONST(4_pi,  1.2732395447351626861510701069801f)
+//IMPLEMENT_PS_CONST(pi_4,  0.78539816339744830961566084581988f)
+//
+//IMPLEMENT_PS_CONST(sincos_p0,  0.15707963267948963959e1f)
+//IMPLEMENT_PS_CONST(sincos_p1, -0.64596409750621907082e0f)
+//IMPLEMENT_PS_CONST(sincos_p2,  0.7969262624561800806e-1f)
+//IMPLEMENT_PS_CONST(sincos_p3, -0.468175413106023168e-2f)
+//IMPLEMENT_PS_CONST(tan_p0,    -1.79565251976484877988e7f)
+//IMPLEMENT_PS_CONST(tan_p1,     1.15351664838587416140e6f)
+//IMPLEMENT_PS_CONST(tan_p2,    -1.30936939181383777646e4f)
+//IMPLEMENT_PS_CONST(tan_q0,    -5.38695755929454629881e7f)
+//IMPLEMENT_PS_CONST(tan_q1,     2.50083801823357915839e7f)
+//IMPLEMENT_PS_CONST(tan_q2,    -1.32089234440210967447e6f)
+//IMPLEMENT_PS_CONST(tan_q3,     1.36812963470692954678e4f)
+//IMPLEMENT_PS_CONST(tan_poleval,3.68935e19f)
+//IMPLEMENT_PS_CONST(atan_t0,   -0.91646118527267623468e-1f)
+//IMPLEMENT_PS_CONST(atan_t1,   -0.13956945682312098640e1f)
+//IMPLEMENT_PS_CONST(atan_t2,   -0.94393926122725531747e2f)
+//IMPLEMENT_PS_CONST(atan_t3,    0.12888383034157279340e2f)
+//IMPLEMENT_PS_CONST(atan_s0,    0.12797564625607904396e1f)
+//IMPLEMENT_PS_CONST(atan_s1,    0.21972168858277355914e1f)
+//IMPLEMENT_PS_CONST(atan_s2,    0.68193064729268275701e1f)
+//IMPLEMENT_PS_CONST(atan_s3,    0.28205206687035841409e2f)
+//
+//IMPLEMENT_PS_CONST(exp_hi,     88.3762626647949f)
+//IMPLEMENT_PS_CONST(exp_lo,    -88.3762626647949f)
+//IMPLEMENT_PS_CONST(exp_rln2,   1.4426950408889634073599f)
+//IMPLEMENT_PS_CONST(exp_p0,     1.26177193074810590878e-4f)
+//IMPLEMENT_PS_CONST(exp_p1,     3.02994407707441961300e-2f)
+//IMPLEMENT_PS_CONST(exp_q0,     3.00198505138664455042e-6f)
+//IMPLEMENT_PS_CONST(exp_q1,     2.52448340349684104192e-3f)
+//IMPLEMENT_PS_CONST(exp_q2,     2.27265548208155028766e-1f)
+//IMPLEMENT_PS_CONST(exp_q3,     2.00000000000000000009e0f)
+//IMPLEMENT_PS_CONST(exp_c1,     6.93145751953125e-1f)
+//IMPLEMENT_PS_CONST(exp_c2,     1.42860682030941723212e-6f)
+//IMPLEMENT_PS_CONST(exp2_hi,    127.4999961853f)
+//IMPLEMENT_PS_CONST(exp2_lo,   -127.4999961853f)
+//IMPLEMENT_PS_CONST(exp2_p0,    2.30933477057345225087e-2f)
+//IMPLEMENT_PS_CONST(exp2_p1,    2.02020656693165307700e1f)
+//IMPLEMENT_PS_CONST(exp2_p2,    1.51390680115615096133e3f)
+//IMPLEMENT_PS_CONST(exp2_q0,    2.33184211722314911771e2f)
+//IMPLEMENT_PS_CONST(exp2_q1,    4.36821166879210612817e3f)
+//IMPLEMENT_PS_CONST(log_p0,    -7.89580278884799154124e-1f)
+//IMPLEMENT_PS_CONST(log_p1,     1.63866645699558079767e1f)
+//IMPLEMENT_PS_CONST(log_p2,    -6.41409952958715622951e1f)
+//IMPLEMENT_PS_CONST(log_q0,    -3.56722798256324312549e1f)
+//IMPLEMENT_PS_CONST(log_q1,     3.12093766372244180303e2f)
+//IMPLEMENT_PS_CONST(log_q2,    -7.69691943550460008604e2f)
+//IMPLEMENT_PS_CONST(log_c0,     0.693147180559945f)
+//IMPLEMENT_PS_CONST(log2_c0,    1.44269504088896340735992f) 
+//
+//#define GLM_NAKED __declspec(naked) __cdecl
+//
+//__m128 GLM_NAKED _mm_cos_ps(__m128 x)
+//{
+//	__asm
+//	{
+//		andps     xmm0, _epi32_inv_sign_mask
+//		addps     xmm0, _ps_pi_2
+//		mulps     xmm0, _ps_2_pi
+//		pxor      xmm3, xmm3
+//		movdqa    xmm5, _epi32_1
+//		movaps    xmm4, _ps_1
+//		cvttps2dq xmm2, xmm0
+//		pand      xmm5, xmm2
+//		pcmpeqd   xmm5, xmm3
+//		cvtdq2ps  xmm6, xmm2
+//		pand      xmm2, _epi32_2
+//		pslld     xmm2, 30
+//		subps     xmm0, xmm6
+//		minps     xmm0, xmm4
+//		subps     xmm4, xmm0
+//		andps     xmm0, xmm5
+//		andnps    xmm5, xmm4
+//		orps      xmm0, xmm5
+//		movaps    xmm1, xmm0
+//		mulps     xmm0, xmm0
+//		orps      xmm1, xmm2
+//		movaps    xmm7, xmm0
+//		mulps     xmm0, _ps_sincos_p3
+//		addps     xmm0, _ps_sincos_p2
+//		mulps     xmm0, xmm7
+//		addps     xmm0, _ps_sincos_p1
+//		mulps     xmm0, xmm7
+//		addps     xmm0, _ps_sincos_p0
+//		mulps     xmm0, xmm1
+//		ret
+//	}
+//} 
+//
+//void test_sse()
+//{
+//	sse::vec4 v1(1.0f, 2.0f, 3.0f, 4.0f);
+//	sse::vec4 v2(5.0f, 6.0f, 7.0f, 8.0f);
+//	sse::vec4 v3(9.0f);
+//	sse::vec4 v4(0.5f, 0.5f, 0.5f, 0.5f);
+//	__m128 v5 = sse::mix(v1.data, v2.data, v4.data);
+//	__m128 dot0 = sse::dot(v1.data, v2.data);
+//	float dot1 = sse::dot(v1, v2);
+//	__m128 rcp0 = sse::rcp(v1.data);
+//	glm::vec4 rcp1 = rcp(glm::vec4(1.0f, 2.0f, 3.0f, 4.0f));
+//
+//	// cross
+//	{
+//		sse::vec4 v1(4.0f, 2.0f, 2.0f, 0.0f);
+//		sse::vec4 v2(1.0f, 2.0f, 3.0f, 0.0f);
+//		__m128 crs0 = sse::cross(v1.data, v2.data);
+//
+//		glm::vec3 v3(4.0f, 2.0f, 2.0f);
+//		glm::vec3 v4(1.0f, 2.0f, 3.0f);
+//		glm::vec3 crs1 = glm::cross(v3, v4);
+//
+//		__m128 end = _mm_set_ps1(1.0f);
+//	}
+//
+//	// ieee754
+//	{
+//		sse::detail::ieee754 one(1.f);
+//		float f = sse::load(one.mantissa, one.exp, one.sign);
+//		
+//		__m128 end = _mm_set_ps1(1.0f);
+//	}
+//
+//	test_clamp();
+//	test_asm();
+//
+//	__m128 cos0 = _mm_cos_ps(_mm_set_ps1(1.0f));
+//	glm::vec4 cos1 = glm::cos(glm::vec4(1.0f));
+//
+//	float f = glm::dot(glm::vec4(1.0f, 2.0f, 3.0f, 4.0f), glm::vec4(5.0f, 6.0f, 7.0f, 8.0f));
+//	sse::vec4 end(9.0f);
+//
+//	//sse::vec4 vComp = sse::load(sse::vec4(1.0f, 2.0f, 3.0f, 4.0f), 1); 
+//	//vComp += sse::vec4(1.0f);
+//	//--vComp;
+//	//sse::vec4 vMixed = sse::mix(vComp, sse::vec4(-0.5f), sse::vec4(0.5f));
+//	//float sDot = sse::dot(sse::vec4(1.0f), sse::vec4(2.0f));
+//	//float cDot = glm::dot(glm::vec4(1.0f), glm::vec4(2.0f));
+//}

+ 13 - 0
experimental/simd/sse.h

@@ -0,0 +1,13 @@
+#ifndef GLM_SSE_H
+#define GLM_SSE_H
+
+#ifdef _WIN32
+#include <xmmintrin.h>
+#endif
+
+#include "../glm/glm.h"
+#include "../glm/glmext.h"
+
+void test_sse();
+
+#endif//GLM_SSE_H

+ 61 - 0
experimental/simd/sse_mat4.cpp

@@ -0,0 +1,61 @@
+#include "precompiled.h"
+#include "sse_mat4.h"
+/*
+void test_sse_mat4()
+{
+	{
+		glm::sse::mat4 m(
+			glm::sse::vec4(0, 1, 2, 3),
+			glm::sse::vec4(4, 5, 6, 7),
+			glm::sse::vec4(8, 9, 10, 11),
+			glm::sse::vec4(12, 13, 14, 15));
+		glm::sse::mat4 n = glm::sse::transpose(m); 
+		m.transpose();
+		glm::sse::mat4 m_end;
+	}
+
+	{
+		glm::sse::mat4 m0;
+		glm::sse::mat4 m1(3.f);
+		glm::sse::mat4 m2(
+			glm::sse::vec4(1),
+			glm::sse::vec4(2),
+			glm::sse::vec4(3),
+			glm::sse::vec4(4));
+		glm::sse::mat4 m3 = m1 + 1.0f;
+		glm::sse::mat4 m4 = 1.0f + m1;
+		glm::sse::mat4 m5 = m2 * m2;
+
+		glm::sse::vec4 v0 = glm::sse::vec4(1.0f, 2.0f, 3.0f, 4.0f);
+		glm::sse::vec4 v1 = glm::sse::vec4(5.0f, 6.0f, 7.0f, 8.0f);
+		glm::sse::vec4 v2 = glm::sse::mat4(v0, v1, v0, v1) * glm::sse::vec4(1.0f, 2.0f, 3.0f, 4.0f);
+		glm::sse::vec4 v3 = glm::sse::vec4(1.0f, 2.0f, 3.0f, 4.0f) * glm::sse::mat4(v0, v1, v0, v1);
+		glm::sse::vec4 v_end;
+	}
+
+	{
+		glm::mat4 m0;
+		glm::mat4 m1(3.f);
+		glm::mat4 m2(
+			glm::vec4(1),
+			glm::vec4(2),
+			glm::vec4(3),
+			glm::vec4(4));
+		glm::mat4 m3 = m1 + 1.0f;
+		glm::mat4 m4 = 1.0f + m1;
+		glm::mat4 m5 = m2 * m2;
+
+		glm::vec4 v0 = glm::vec4(1.0f, 2.0f, 3.0f, 4.0f);
+		glm::vec4 v1 = glm::vec4(5.0f, 6.0f, 7.0f, 8.0f);
+		glm::vec4 v2 = glm::mat4(v0, v1, v0, v1) * glm::vec4(1.0f, 2.0f, 3.0f, 4.0f);
+		glm::vec4 v3 = glm::vec4(1.0f, 2.0f, 3.0f, 4.0f) * glm::mat4(v0, v1, v0, v1);
+		glm::vec4 v_end;
+	}
+
+	{
+		int a[][4] = {{0, 0, 1, 2}, {0, 0, 1, 2}};
+	}
+
+	glm::sse::mat4 m_end;
+}
+*/

+ 1280 - 0
experimental/simd/sse_mat4.h

@@ -0,0 +1,1280 @@
+#ifdef GLM_SSE_MAT4_H
+#define GLM_SSE_MAT4_H
+
+#include <xmmintrin.h>
+#include <emmintrin.h>
+#include "sse_vec4.h"
+
+namespace glm{
+namespace sse{
+
+const __m128i maskX = _mm_set_epi32(0x00000000, 0x00000000, 0x00000000, 0xFFFFFFFF);
+const __m128i maskY = _mm_set_epi32(0x00000000, 0x00000000, 0xFFFFFFFF, 0x00000000);
+const __m128i maskZ = _mm_set_epi32(0x00000000, 0xFFFFFFFF, 0x00000000, 0x00000000);
+const __m128i maskW = _mm_set_epi32(0xFFFFFFFF, 0x00000000, 0x00000000, 0x00000000);
+
+GLM_ALIGN(16) struct mat4
+{
+	enum ENoInit
+	{
+		NO_INIT
+	};
+
+	union
+	{
+		__m128 data[4];
+	};
+
+	mat4();
+	mat4(ENoInit NoInit);
+	mat4(float s);
+	mat4(const vec4& x, const vec4& y, const vec4& z, const vec4& w);
+
+	mat4& operator+=(const float s);
+
+	mat4& operator+=(const mat4& m);
+	mat4& operator*=(const mat4& m);
+
+	void mat4::transpose();
+};
+
+__forceinline mat4::mat4()
+{
+	void* address = this;
+
+	__asm
+	{
+		mov		esi, address
+		xorps	xmm0, xmm0
+		movaps	[esi+0x00], xmm0
+		movaps	[esi+0x10], xmm0
+		movaps	[esi+0x20], xmm0
+		movaps	[esi+0x30], xmm0
+	}
+}
+
+__forceinline mat4::mat4(ENoInit NoInit)
+{}
+
+__forceinline mat4::mat4(float s)
+{
+	void* address = this;
+
+	__asm
+	{
+		mov		esi, address
+		movss	xmm0, s
+		shufps	xmm0, xmm0, 0	
+		xorps	xmm1, xmm1
+		movaps	[esi+0x00], xmm1
+		movaps	[esi+0x10], xmm1
+		movaps	[esi+0x20], xmm1
+		movaps	[esi+0x30], xmm1
+		movss	[esi+0x00], xmm0
+		movss	[esi+0x14], xmm0
+		movss	[esi+0x28], xmm0
+		movss	[esi+0x3C], xmm0
+	}
+}
+
+__forceinline mat4::mat4(const vec4& x, const vec4& y, const vec4& z, const vec4& w)
+{
+	void* address = this;
+
+	__asm
+	{
+		mov		esi, address
+
+		mov		edi, x
+		movaps	xmm0, [edi]
+		movaps	[esi+0x00], xmm0
+
+		mov		edi, y
+		movaps	xmm0, [edi]
+		movaps	[esi+0x10], xmm0
+
+		mov		edi, z
+		movaps	xmm0, [edi]
+		movaps	[esi+0x20], xmm0
+
+		mov		edi, w
+		movaps	xmm0, [edi]
+		movaps	[esi+0x30], xmm0
+	}
+}
+
+__forceinline mat4 operator+(const mat4& m, float s)
+{
+	__asm
+	{
+		movss	xmm1, s
+		shufps	xmm1, xmm1, 0
+		mov		esi, [m]
+
+		movaps	xmm0, [esi+0x00]
+		addps	xmm0, xmm1
+		movaps	[esi+0x00], xmm0
+
+		movaps	xmm0, [esi+0x10]
+		addps	xmm0, xmm1
+		movaps	[esi+0x10], xmm0
+
+		movaps	xmm0, [esi+0x20]
+		addps	xmm0, xmm1
+		movaps	[esi+0x20], xmm0
+
+		movaps	xmm0, [esi+0x30]
+		addps	xmm0, xmm1
+		movaps	[esi+0x30], xmm0
+	}
+}
+
+__forceinline mat4 operator+(float s, const mat4& m)
+{
+	return m + s;
+}
+
+__forceinline mat4 operator-(const mat4& m, float s)
+{
+	__asm
+	{
+		movss	xmm1, s
+		shufps	xmm1, xmm1, 0
+		mov		esi, [m]
+
+		movaps	xmm0, [esi+0x00]
+		subps	xmm0, xmm1
+		movaps	[esi+0x00], xmm0
+
+		movaps	xmm0, [esi+0x10]
+		subps	xmm0, xmm1
+		movaps	[esi+0x10], xmm0
+
+		movaps	xmm0, [esi+0x20]
+		subps	xmm0, xmm1
+		movaps	[esi+0x20], xmm0
+
+		movaps	xmm0, [esi+0x30]
+		subps	xmm0, xmm1
+		movaps	[esi+0x30], xmm0
+	}
+}
+
+__forceinline mat4 operator-(float s, const mat4& m)
+{
+	__asm
+	{
+		movss	xmm2, s
+		shufps	xmm2, xmm2, 0
+		mov		esi, [m]
+
+		movaps	xmm0, [esi+0x00]
+		movaps	xmm1, xmm2
+		subps	xmm1, xmm0
+		movaps	[esi+0x00], xmm1
+
+		movaps	xmm0, [esi+0x10]
+		movaps	xmm1, xmm2
+		subps	xmm1, xmm0
+		movaps	[esi+0x10], xmm1
+
+		movaps	xmm0, [esi+0x20]
+		movaps	xmm1, xmm2
+		subps	xmm1, xmm0
+		movaps	[esi+0x20], xmm1
+
+		movaps	xmm0, [esi+0x30]
+		movaps	xmm1, xmm2
+		subps	xmm1, xmm0
+		movaps	[esi+0x30], xmm1
+	}
+}
+
+__forceinline mat4 operator*(const mat4& m, float s)
+{
+	__asm
+	{
+		movss	xmm1, s
+		shufps	xmm1, xmm1, 0
+		mov		esi, [m]
+
+		movaps	xmm0, [esi+0x00]
+		mulps	xmm0, xmm1
+		movaps	[esi+0x00], xmm0
+
+		movaps	xmm0, [esi+0x10]
+		mulps	xmm0, xmm1
+		movaps	[esi+0x10], xmm0
+
+		movaps	xmm0, [esi+0x20]
+		mulps	xmm0, xmm1
+		movaps	[esi+0x20], xmm0
+
+		movaps	xmm0, [esi+0x30]
+		mulps	xmm0, xmm1
+		movaps	[esi+0x30], xmm0
+	}
+}
+
+__forceinline mat4 operator*(float s, const mat4& m)
+{
+	return m * s;
+}
+
+__forceinline mat4 operator/(const mat4& m, float s)
+{
+	__asm
+	{
+		movss	xmm1, s
+		shufps	xmm1, xmm1, 0
+		mov		esi, [m]
+
+		movaps	xmm0, [esi+0x00]
+		divps	xmm0, xmm1
+		movaps	[esi+0x00], xmm0
+
+		movaps	xmm0, [esi+0x10]
+		divps	xmm0, xmm1
+		movaps	[esi+0x10], xmm0
+
+		movaps	xmm0, [esi+0x20]
+		divps	xmm0, xmm1
+		movaps	[esi+0x20], xmm0
+
+		movaps	xmm0, [esi+0x30]
+		divps	xmm0, xmm1
+		movaps	[esi+0x30], xmm0
+	}
+}
+
+__forceinline mat4 operator/(float s, const mat4& m)
+{
+	__asm
+	{
+		movss	xmm2, s
+		shufps	xmm2, xmm2, 0
+		mov		esi, [m]
+
+		movaps	xmm0, [esi+0x00]
+		movaps	xmm1, xmm2
+		divps	xmm1, xmm0
+		movaps	[esi+0x00], xmm1
+
+		movaps	xmm0, [esi+0x10]
+		movaps	xmm1, xmm2
+		divps	xmm1, xmm0
+		movaps	[esi+0x10], xmm1
+
+		movaps	xmm0, [esi+0x20]
+		movaps	xmm1, xmm2
+		divps	xmm1, xmm0
+		movaps	[esi+0x20], xmm1
+
+		movaps	xmm0, [esi+0x30]
+		movaps	xmm1, xmm2
+		divps	xmm1, xmm0
+		movaps	[esi+0x30], xmm1
+	}
+}
+
+__forceinline vec4 operator*(const mat4& m, const vec4& v)
+{
+	vec4 result(vec4::NO_INIT);
+
+	// SSE2
+	__asm
+	{
+		mov		esi, [m]
+		mov		edi, [v]
+		movaps	xmm4, [edi]
+
+		movaps	xmm0, [esi+0x00]
+		movaps	xmm1, [esi+0x10]
+		movaps	xmm2, [esi+0x20]
+		movaps	xmm3, [esi+0x30]
+
+		pshufd	xmm5, xmm4, _MM_SHUFFLE(0, 0, 0, 0)
+		mulps	xmm0, xmm5
+		pshufd	xmm5, xmm4, _MM_SHUFFLE(1, 1, 1, 1)
+		mulps	xmm1, xmm5
+		pshufd	xmm5, xmm4, _MM_SHUFFLE(2, 2, 2, 2)
+		mulps	xmm2, xmm5
+		pshufd	xmm5, xmm4, _MM_SHUFFLE(3, 3, 3, 3)
+		mulps	xmm3, xmm5
+
+		addps	xmm0, xmm1
+		addps	xmm2, xmm3
+		addps	xmm0, xmm2
+
+		movaps	result, xmm0
+	}
+
+	return result;
+}
+
+__forceinline vec4 operator*(const vec4& v, const mat4& m)
+{
+	vec4 result(vec4::NO_INIT);
+
+	// SSE1
+	__asm
+	{
+		mov		esi, [m]
+		mov		edi, [v]
+		movaps	xmm4, [edi]			// xmm4: v[3], v[2], v[1], v[0]
+
+		movaps	xmm0, [esi+0x00]	// xmm0: m[0][3], m[0][2], m[0][1], m[0][0]
+		movaps	xmm1, [esi+0x10]	// xmm1: m[1][3], m[1][2], m[1][1], m[1][0]
+		movaps	xmm2, [esi+0x20]	// xmm2: m[2][3], m[2][2], m[2][1], m[2][0]
+		movaps	xmm3, [esi+0x30]	// xmm3: m[3][3], m[3][2], m[3][1], m[3][0]
+
+		mulps	xmm0, xmm4			// xmm0: m[0][3]*v[3], m[0][2]*v[2], m[0][1]*v[1], m[0][0]*v[0]
+		mulps	xmm1, xmm4			// xmm1: m[1][3]*v[3], m[1][2]*v[2], m[1][1]*v[1], m[1][0]*v[0]
+		mulps	xmm2, xmm4			// xmm2: m[2][3]*v[3], m[2][2]*v[2], m[2][1]*v[1], m[2][0]*v[0]
+		mulps	xmm3, xmm4			// xmm2: m[3][3]*v[3], m[3][2]*v[2], m[3][1]*v[1], m[3][0]*v[0]
+
+		movaps	xmm4, xmm0			// xmm4: m[0][3]*v[3], m[0][2]*v[2], m[0][1]*v[1], m[0][0]*v[0]
+		movhlps xmm0, xmm1			// xmm0: m[0][3]*v[3], m[0][2]*v[2], m[1][3]*v[3], m[1][2]*v[2]
+		movlhps xmm1, xmm4			// xmm1: m[0][1]*v[1], m[0][0]*v[0], m[1][1]*v[1], m[1][0]*v[0]
+		addps	xmm0, xmm1
+
+		movaps	xmm5, xmm2
+		movhlps xmm2, xmm3
+		movlhps xmm3, xmm5
+		addps	xmm2, xmm3
+
+		movaps	xmm1, xmm0
+		shufps	xmm0, xmm2, _MM_SHUFFLE(0, 2, 0, 2) //_MM_SHUFFLE(2, 0, 2, 0)
+		shufps	xmm1, xmm2, _MM_SHUFFLE(1, 3, 1, 3) //_MM_SHUFFLE(3, 1, 3, 1)
+		addps	xmm0, xmm1
+
+		movaps	result, xmm0
+	}
+
+	return result;
+}
+
+// 289000
+/*
+inline mat4 operator*(const mat4& m, const mat4& n)
+{
+	mat4 result;
+	void* adresse = &result;
+
+	// SSE2
+	__asm
+	{
+		mov		esi, m
+		mov		edi, n
+		mov		eax, adresse
+		mov		ecx, 0x10
+		mov		edx, 0x04
+
+	next:
+		movaps	xmm7, [edi]
+
+		movaps	xmm0, [esi+0x00]
+		movaps	xmm1, [esi+0x10]
+		movaps	xmm2, [esi+0x20]
+		movaps	xmm3, [esi+0x30]
+
+		pshufd	xmm4, xmm7, _MM_SHUFFLE(0, 0, 0, 0)
+		mulps	xmm0, xmm4
+		
+		pshufd	xmm4, xmm7, _MM_SHUFFLE(1, 1, 1, 1)
+		mulps	xmm1, xmm4
+
+		pshufd	xmm4, xmm7, _MM_SHUFFLE(2, 2, 2, 2)
+		mulps	xmm2, xmm4
+
+		pshufd	xmm4, xmm7, _MM_SHUFFLE(3, 3, 3, 3)
+		mulps	xmm3, xmm4
+
+		addps	xmm2, xmm3
+		addps	xmm0, xmm1
+		addps	xmm0, xmm2
+
+		movaps	[eax], xmm0
+
+		add		edi, ecx
+		add		eax, ecx
+		dec		edx
+		jnz		next
+	}
+
+	return result;
+}
+*/
+
+// 288000
+/*
+inline mat4 operator*(const mat4& m, const mat4& n)
+{
+	mat4 result;
+	void* adresse = &result;
+
+	// SSE2
+	__asm
+	{
+		mov		esi, m
+		mov		edi, n
+		mov		eax, adresse
+		mov		ecx, 0x10
+		mov		edx, 0x04
+
+	next:
+		movaps	xmm7, [edi]
+
+		movaps	xmm0, [esi+0x00]
+		pshufd	xmm5, xmm4, _MM_SHUFFLE(0, 0, 0, 0)
+		mulps	xmm0, xmm5
+
+		movaps	xmm1, [esi+0x10]
+		pshufd	xmm5, xmm4, _MM_SHUFFLE(1, 1, 1, 1)
+		mulps	xmm1, xmm5
+
+		movaps	xmm2, [esi+0x20]
+		pshufd	xmm5, xmm4, _MM_SHUFFLE(2, 2, 2, 2)
+		mulps	xmm2, xmm5
+
+		movaps	xmm3, [esi+0x30]
+		pshufd	xmm5, xmm4, _MM_SHUFFLE(3, 3, 3, 3)
+		mulps	xmm3, xmm5
+
+		addps	xmm0, xmm1
+		addps	xmm2, xmm3
+		addps	xmm0, xmm2
+
+		movaps	[eax], xmm0
+
+		add		edi, ecx
+		add		eax, ecx
+		dec		edx
+		jnz		next
+	}
+
+	return result;
+}
+*/
+/*
+// 290000
+inline mat4 operator*(const mat4& m, const mat4& n)
+{
+	mat4 result;
+	void* adresse = &result;
+
+	// SSE2
+	__asm
+	{
+		mov		esi, m
+		mov		edi, n
+		mov		eax, adresse
+		mov		ecx, 0x10
+		mov		edx, 0x04
+
+		movaps	xmm7, [edi]
+
+	next:
+		pshufd	xmm4, xmm7, _MM_SHUFFLE(0, 0, 0, 0)
+		pshufd	xmm5, xmm7, _MM_SHUFFLE(1, 1, 1, 1)
+		movaps	xmm0, [esi+0x00]
+		mulps	xmm0, xmm4
+		movaps	xmm1, [esi+0x10]
+		mulps	xmm1, xmm5
+		addps	xmm0, xmm1
+
+		pshufd	xmm4, xmm7, _MM_SHUFFLE(2, 2, 2, 2)
+		pshufd	xmm5, xmm7, _MM_SHUFFLE(3, 3, 3, 3)
+		movaps	xmm2, [esi+0x20]
+		mulps	xmm2, xmm4
+		movaps	xmm3, [esi+0x30]
+		mulps	xmm3, xmm5
+		addps	xmm2, xmm3
+
+		addps	xmm0, xmm2
+
+		movaps	[eax], xmm0
+
+		add		edi, ecx
+		add		eax, ecx
+		dec		edx
+		jnz		next
+	}
+
+	return result;
+}
+*/
+
+/*
+// 295000
+inline mat4 operator*(const mat4& m, const mat4& n)
+{
+	mat4 result;
+	void* adresse = &result;
+
+	// SSE2
+	__asm
+	{
+		mov		esi, m
+		mov		edi, n
+		mov		eax, adresse
+		mov		ecx, 0x10
+		mov		edx, 0x04
+
+		movaps	xmm7, [edi]
+
+	next:
+		movaps	xmm0, [esi+0x00]
+		movaps	xmm1, [esi+0x10]
+		movaps	xmm2, [esi+0x20]
+		movaps	xmm3, [esi+0x30]
+		
+		pshufd	xmm4, xmm7, _MM_SHUFFLE(0, 0, 0, 0)
+		mulps	xmm0, xmm4
+		pshufd	xmm5, xmm7, _MM_SHUFFLE(1, 1, 1, 1)
+		mulps	xmm1, xmm5
+		addps	xmm0, xmm1
+
+		pshufd	xmm4, xmm7, _MM_SHUFFLE(2, 2, 2, 2)
+		mulps	xmm2, xmm4
+		pshufd	xmm5, xmm7, _MM_SHUFFLE(3, 3, 3, 3)
+		mulps	xmm3, xmm5
+		addps	xmm2, xmm3
+
+		addps	xmm0, xmm2
+
+		movaps	[eax], xmm0
+
+		add		edi, ecx
+		add		eax, ecx
+		dec		edx
+		jnz		next
+	}
+
+	return result;
+}
+*/
+
+/*
+// 290000
+inline mat4 operator*(const mat4& m, const mat4& n)
+{
+	mat4 result;
+	void* adresse = &result;
+
+	// SSE2
+	__asm
+	{
+		mov		esi, m
+		mov		edi, n
+		mov		eax, adresse
+		mov		ecx, 0x10
+		mov		edx, 0x04
+
+		movaps	xmm7, [edi]
+
+	next:
+		movaps	xmm0, [esi+0x00]
+		movaps	xmm1, [esi+0x10]
+		movaps	xmm2, [esi+0x20]
+		movaps	xmm3, [esi+0x30]
+		
+		pshufd	xmm4, xmm7, _MM_SHUFFLE(0, 0, 0, 0)
+		pshufd	xmm5, xmm7, _MM_SHUFFLE(1, 1, 1, 1)
+		mulps	xmm0, xmm4
+		mulps	xmm1, xmm5
+		addps	xmm0, xmm1
+
+		pshufd	xmm4, xmm7, _MM_SHUFFLE(2, 2, 2, 2)
+		pshufd	xmm5, xmm7, _MM_SHUFFLE(3, 3, 3, 3)
+		mulps	xmm2, xmm4
+		mulps	xmm3, xmm5
+		addps	xmm2, xmm3
+
+		addps	xmm0, xmm2
+
+		movaps	[eax], xmm0
+
+		add		edi, ecx
+		add		eax, ecx
+		dec		edx
+		jnz		next
+	}
+
+	return result;
+}
+*/
+
+/*
+// 288000
+inline mat4 operator*(const mat4& m, const mat4& n)
+{
+	mat4 result;
+	void* adresse = &result;
+
+	// SSE2
+	__asm
+	{
+		mov		esi, m
+		mov		edi, n
+		mov		eax, adresse
+		mov		ecx, 0x10
+		mov		edx, 0x04
+
+		movaps	xmm7, [edi]
+
+	next:
+		movaps	xmm0, [esi+0x00]
+		movaps	xmm1, [esi+0x10]
+		movaps	xmm2, [esi+0x20]
+		movaps	xmm3, [esi+0x30]
+		
+		pshufd	xmm4, xmm7, _MM_SHUFFLE(0, 0, 0, 0)
+		pshufd	xmm5, xmm7, _MM_SHUFFLE(1, 1, 1, 1)
+		mulps	xmm0, xmm4
+		mulps	xmm1, xmm5
+		addps	xmm0, xmm1
+
+		pshufd	xmm4, xmm7, _MM_SHUFFLE(2, 2, 2, 2)
+		pshufd	xmm5, xmm7, _MM_SHUFFLE(3, 3, 3, 3)
+		mulps	xmm2, xmm4
+		mulps	xmm3, xmm5
+		addps	xmm2, xmm3
+
+		addps	xmm0, xmm2
+
+		movaps	[eax], xmm0
+
+		add		edi, ecx
+		add		eax, ecx
+		dec		edx
+		jnz		next
+	}
+
+	return result;
+}
+*/
+
+/*
+// 298000
+inline mat4 operator*(const mat4& m, const mat4& n)
+{
+	mat4 result;
+	void* adresse = &result;
+
+	const int int0x10 = 0x10;
+
+	// SSE2
+	__asm
+	{
+		mov		esi, m
+		mov		edi, n
+		mov		eax, adresse
+		mov		edx, int0x10
+
+		// First column
+		movaps	xmm4, [edi]
+
+		pshufd	xmm5, xmm4, _MM_SHUFFLE(0, 0, 0, 0)
+		movaps	xmm0, [esi+0x00]
+		mulps	xmm0, xmm5
+
+		pshufd	xmm5, xmm4, _MM_SHUFFLE(1, 1, 1, 1)
+		movaps	xmm1, [esi+0x10]
+		mulps	xmm1, xmm5
+
+		pshufd	xmm5, xmm4, _MM_SHUFFLE(2, 2, 2, 2)
+		movaps	xmm2, [esi+0x20]
+		mulps	xmm2, xmm5
+
+		pshufd	xmm5, xmm4, _MM_SHUFFLE(3, 3, 3, 3)
+		movaps	xmm3, [esi+0x30]
+		mulps	xmm3, xmm5
+
+		addps	xmm0, xmm1
+		addps	xmm2, xmm3
+		addps	xmm0, xmm2
+
+		movaps	[eax], xmm0
+
+		add		edi, edx
+		add		eax, edx
+
+		// Second column
+		movaps	xmm4, [edi]
+
+		pshufd	xmm5, xmm4, _MM_SHUFFLE(0, 0, 0, 0)
+		movaps	xmm0, [esi+0x00]
+		mulps	xmm0, xmm5
+
+		pshufd	xmm5, xmm4, _MM_SHUFFLE(1, 1, 1, 1)
+		movaps	xmm1, [esi+0x10]
+		mulps	xmm1, xmm5
+
+		pshufd	xmm5, xmm4, _MM_SHUFFLE(2, 2, 2, 2)
+		movaps	xmm2, [esi+0x20]
+		mulps	xmm2, xmm5
+
+		pshufd	xmm5, xmm4, _MM_SHUFFLE(3, 3, 3, 3)
+		movaps	xmm3, [esi+0x30]
+		mulps	xmm3, xmm5
+
+		addps	xmm0, xmm1
+		addps	xmm2, xmm3
+		addps	xmm0, xmm2
+
+		movaps	[eax], xmm0
+
+		add		edi, edx
+		add		eax, edx
+
+		// Third column
+		movaps	xmm4, [edi]
+
+		pshufd	xmm5, xmm4, _MM_SHUFFLE(0, 0, 0, 0)
+		movaps	xmm0, [esi+0x00]
+		mulps	xmm0, xmm5
+
+		pshufd	xmm5, xmm4, _MM_SHUFFLE(1, 1, 1, 1)
+		movaps	xmm1, [esi+0x10]
+		mulps	xmm1, xmm5
+
+		pshufd	xmm5, xmm4, _MM_SHUFFLE(2, 2, 2, 2)
+		movaps	xmm2, [esi+0x20]
+		mulps	xmm2, xmm5
+
+		pshufd	xmm5, xmm4, _MM_SHUFFLE(3, 3, 3, 3)
+		movaps	xmm3, [esi+0x30]
+		mulps	xmm3, xmm5
+
+		addps	xmm0, xmm1
+		addps	xmm2, xmm3
+		addps	xmm0, xmm2
+
+		movaps	[eax], xmm0
+
+		add		edi, edx
+		add		eax, edx
+
+		// Forth column
+		movaps	xmm4, [edi]
+
+		pshufd	xmm5, xmm4, _MM_SHUFFLE(0, 0, 0, 0)
+		movaps	xmm0, [esi+0x00]
+		mulps	xmm0, xmm5
+
+		pshufd	xmm5, xmm4, _MM_SHUFFLE(1, 1, 1, 1)
+		movaps	xmm1, [esi+0x10]
+		mulps	xmm1, xmm5
+
+		pshufd	xmm5, xmm4, _MM_SHUFFLE(2, 2, 2, 2)
+		movaps	xmm2, [esi+0x20]
+		mulps	xmm2, xmm5
+
+		pshufd	xmm5, xmm4, _MM_SHUFFLE(3, 3, 3, 3)
+		movaps	xmm3, [esi+0x30]
+		mulps	xmm3, xmm5
+
+		addps	xmm0, xmm1
+		addps	xmm2, xmm3
+		addps	xmm0, xmm2
+
+		movaps	[eax], xmm0
+	}
+
+	return result;
+}
+*/
+
+// 294000
+__forceinline mat4 operator*(const mat4& m, const mat4& n)
+{
+	mat4 result(mat4::NO_INIT);
+
+	// SSE2
+	__asm
+	{
+		mov		esi, m
+		mov		edi, n
+
+		// First column
+		movaps	xmm4, [edi+0x00]
+
+		movaps	xmm0, [esi+0x00]
+		movaps	xmm1, [esi+0x10]
+		movaps	xmm2, [esi+0x20]
+		movaps	xmm3, [esi+0x30]
+
+		pshufd	xmm5, xmm4, _MM_SHUFFLE(0, 0, 0, 0)
+		mulps	xmm0, xmm5
+		pshufd	xmm5, xmm4, _MM_SHUFFLE(1, 1, 1, 1)
+		mulps	xmm1, xmm5
+		pshufd	xmm5, xmm4, _MM_SHUFFLE(2, 2, 2, 2)
+		mulps	xmm2, xmm5
+		pshufd	xmm5, xmm4, _MM_SHUFFLE(3, 3, 3, 3)
+		mulps	xmm3, xmm5
+
+		addps	xmm0, xmm1
+		addps	xmm2, xmm3
+		addps	xmm0, xmm2
+
+		movaps	result[0x00], xmm0
+
+		// Second column
+		movaps	xmm4, [edi+0x10]
+
+		pshufd	xmm5, xmm4, _MM_SHUFFLE(0, 0, 0, 0)
+		movaps	xmm0, [esi+0x00]
+		mulps	xmm0, xmm5
+
+		pshufd	xmm5, xmm4, _MM_SHUFFLE(1, 1, 1, 1)
+		movaps	xmm1, [esi+0x10]
+		mulps	xmm1, xmm5
+
+		pshufd	xmm5, xmm4, _MM_SHUFFLE(2, 2, 2, 2)
+		movaps	xmm2, [esi+0x20]
+		mulps	xmm2, xmm5
+
+		pshufd	xmm5, xmm4, _MM_SHUFFLE(3, 3, 3, 3)
+		movaps	xmm3, [esi+0x30]
+		mulps	xmm3, xmm5
+
+		addps	xmm0, xmm1
+		addps	xmm2, xmm3
+		addps	xmm0, xmm2
+
+		movaps	result[0x10], xmm0
+
+		// Third column
+		movaps	xmm4, [edi+0x20]
+
+		pshufd	xmm5, xmm4, _MM_SHUFFLE(0, 0, 0, 0)
+		movaps	xmm0, [esi+0x00]
+		mulps	xmm0, xmm5
+
+		pshufd	xmm5, xmm4, _MM_SHUFFLE(1, 1, 1, 1)
+		movaps	xmm1, [esi+0x10]
+		mulps	xmm1, xmm5
+
+		pshufd	xmm5, xmm4, _MM_SHUFFLE(2, 2, 2, 2)
+		movaps	xmm2, [esi+0x20]
+		mulps	xmm2, xmm5
+
+		pshufd	xmm5, xmm4, _MM_SHUFFLE(3, 3, 3, 3)
+		movaps	xmm3, [esi+0x30]
+		mulps	xmm3, xmm5
+
+		addps	xmm0, xmm1
+		addps	xmm2, xmm3
+		addps	xmm0, xmm2
+
+		movaps	result[0x20], xmm0
+
+		// Forth column
+		movaps	xmm4, [edi+0x30]
+
+		pshufd	xmm5, xmm4, _MM_SHUFFLE(0, 0, 0, 0)
+		movaps	xmm0, [esi+0x00]
+		mulps	xmm0, xmm5
+
+		pshufd	xmm5, xmm4, _MM_SHUFFLE(1, 1, 1, 1)
+		movaps	xmm1, [esi+0x10]
+		mulps	xmm1, xmm5
+
+		pshufd	xmm5, xmm4, _MM_SHUFFLE(2, 2, 2, 2)
+		movaps	xmm2, [esi+0x20]
+		mulps	xmm2, xmm5
+
+		pshufd	xmm5, xmm4, _MM_SHUFFLE(3, 3, 3, 3)
+		movaps	xmm3, [esi+0x30]
+		mulps	xmm3, xmm5
+
+		addps	xmm0, xmm1
+		addps	xmm2, xmm3
+		addps	xmm0, xmm2
+
+		movaps	result[0x30], xmm0
+	}
+
+	return result;
+}
+
+static const __m128 sign1010 = _mm_set_ps( 1.0f,-1.0f, 1.0f,-1.0f);
+static const __m128 sign0101 = _mm_set_ps(-1.0f, 1.0f,-1.0f, 1.0f);
+static const __m128i mask1010 = _mm_set_epi32(0x00000000, 0x80000000, 0x00000000, 0x80000000);
+static const __m128i mask0101 = _mm_set_epi32(0x80000000, 0x00000000, 0x80000000, 0x00000000);
+
+__forceinline mat4 inverse(const mat4& m)
+{
+	mat4 result(mat4::NO_INIT);
+
+	vec4 m0a;
+	vec4 m0b;
+	vec4 m0c;
+
+	vec4 m1a;
+	vec4 m1b;
+	vec4 m1c;
+
+	vec4 m2a;
+	vec4 m2b;
+	vec4 m2c;
+
+	vec4 m3a;
+	vec4 m3b;
+	vec4 m3c;
+
+	__asm
+	{
+		mov			esi, m
+
+		//////////////////////////////////////////////////////////////////////////////////////////////
+		//R00 = +1 * m11*(m22*m33 - m32*m23) -1 * m12*(m23*m31 - m33*m21) +1 * m13*(m21*m32 - m31*m22)
+		//R01 = -1 * m12*(m23*m30 - m33*m20) +1 * m13*(m20*m32 - m30*m22) -1 * m10*(m22*m33 - m32*m23)
+		//R02 = +1 * m13*(m20*m31 - m30*m21) -1 * m10*(m21*m33 - m31*m23) +1 * m11*(m23*m30 - m33*m20)
+		//R03 = -1 * m10*(m21*m32 - m31*m22) +1 * m11*(m22*m30 - m32*m20) -1 * m12*(m20*m31 - m30*m21)
+
+		movaps		xmm6, [esi+20] // xmm6: m23, m22, m21, m20
+		movaps		xmm7, [esi+30] // xmm7: m33, m32, m31, m30
+
+		//////////////////////////////////////////////////////////////////////////////////////////////
+
+		pshufd		xmm0, xmm6, _MM_SHUFFLE(1, 0, 3, 2) // xmm0: m21, m20, m23, m22 (movhlps optimization possible)
+		pshufd		xmm1, xmm7, _MM_SHUFFLE(0, 3, 2, 1) // xmm1: m30, m33, m32, m31
+		pshufd		xmm2, xmm6, _MM_SHUFFLE(0, 3, 2, 1) // xmm2: m20, m23, m22, m21
+		pshufd		xmm3, xmm7, _MM_SHUFFLE(1, 0, 3, 2) // xmm3: m31, m30, m33, m32 (movhlps optimization possible)
+
+		mulps		xmm0, xmm1 // xmm0: m21*m30, m20*m33, m23*m32, m22*m31
+		mulps		xmm3, xmm2 // xmm2: m20*m31, m23*m30, m22*m33, m21*m32
+		subps		xmm3, xmm0 // xmm2: m20*m31-m21*m30, m23*m30-m20*m33, m22*m33-m23*m32, m21*m32-m22*m31
+		movaps		xmm4, xmm3 // xmm4: m20*m31-m21*m30, m23*m30-m20*m33, m22*m33-m23*m32, m21*m32-m22*m31
+
+		//////////////////////////////////////////////////////////////////////////////////////////////
+
+		pshufd		xmm0, xmm6, _MM_SHUFFLE(2, 1, 0, 3) // xmm0: m22, m21, m20, m23
+		// Reuse xmm1: pshufd		xmm1, xmm7, _MM_SHUFFLE(0, 3, 2, 1) // xmm1: m30, m33, m32, m31
+		// Reuse xmm2: pshufd		xmm2, xmm6, _MM_SHUFFLE(0, 3, 2, 1) // xmm2: m20, m23, m22, m21
+		pshufd		xmm3, xmm7, _MM_SHUFFLE(2, 1, 0, 3) // xmm3: m32, m31, m30, m33
+
+		mulps		xmm1, xmm0 // xmm1: m30*m22, m33*m21, m32*m20, m31*m23
+		mulps		xmm2, xmm3 // xmm2: m20*m32, m23*m31, m22*m30, m21*m33
+		subps		xmm1, xmm2 // xmm1: m30*m22-m20*m32, m33*m21-m23*m31, m32*m20-m22*m30, m31*m23-m21*m33
+		movaps		xmm5, xmm2 // xmm5: m30*m22-m20*m32, m33*m21-m23*m31, m32*m20-m22*m30, m31*m23-m21*m33
+
+		//////////////////////////////////////////////////////////////////////////////////////////////
+
+		// Reuse xmm0: pshufd		xmm0, xmm6, _MM_SHUFFLE(2, 1, 0, 3) // xmm0: m22, m21, m20, m23
+		pshufd		xmm1, xmm7, _MM_SHUFFLE(1, 0, 3, 2) // xmm1: m31, m30, m33, m32 (movhlps optimization possible)
+		pshufd		xmm2, xmm6, _MM_SHUFFLE(1, 0, 3, 2) // xmm2: m21, m20, m23, m22 (movhlps optimization possible)
+		// Reuse xmm3: pshufd		xmm3, xmm7, _MM_SHUFFLE(2, 1, 0, 3) // xmm3: m32, m31, m30, m33
+
+		mulps		xmm0, xmm1 // xmm1: m22*m31, m21*m30, m20*m33, m23*m32
+		mulps		xmm2, xmm3 // xmm2: m21*m32, m20*m31, m23*m30, m22*m33
+		subps		xmm2, xmm0 // xmm2: m23*m32-m22*m33, m20*m33-m23*m30, m21*m30-m20*m31, m22*m31-m21*m32
+		movaps		xmm6, xmm0 // xmm6: m23*m32-m22*m33, m20*m33-m23*m30, m21*m30-m20*m31, m22*m31-m21*m32
+
+		//////////////////////////////////////////////////////////////////////////////////////////////
+
+		movaps		xmm0, [esi+10] // m13, m12, m11, m10
+
+		pshufd		xmm1, xmm0, _MM_SHUFFLE(2, 1, 0, 3)
+		xorps		xmm1, mask1010 //-m12, m11,-m10, m13
+		mulaps		xmm4, xmm1
+
+		pshufd		xmm1, xmm0, _MM_SHUFFLE(1, 0, 3, 2) // (movhlps optimization possible)
+		xorps		xmm1, mask0101 // m11,-m10, m13,-m12
+		mulaps		xmm5, xmm1
+
+		pshufd		xmm1, xmm0, _MM_SHUFFLE(0, 3, 2, 1)
+		xorps		xmm1, mask1010 //-m10, m13,-m12, m10
+		mulaps		xmm6, xmm1
+
+		mulaps		xmm6, xmm5
+		mulaps		xmm6, xmm4
+		movaps		result[0x00], xmm6
+
+		//////////////////////////////////////////////////////////////////////////////////////////////
+		//R10 = -1 * m21*(m32*m03 – m02*m33) +1 * m22*(m33*m01 – m03*m31) –1 * m23*(m31*m02 – m01*m32)
+		//R11 = +1 * m22*(m33*m00 – m03*m30) –1 * m23*(m30*m02 – m00*m32) +1 * m20*(m32*m03 – m02*m33)
+		//R12 = -1 * m23*(m30*m01 – m00*m31) +1 * m20*(m31*m03 – m01*m33) -1 * m21*(m33*m00 – m03*m30)
+		//R13 = +1 * m20*(m31*m02 – m01*m32) -1 * m21*(m32*m00 – m02*m30) +1 * m22*(m30*m01 – m00*m31)
+
+		movaps		xmm6, [esi+00] // xmm6: m03, m02, m01, m00
+		// Reuse xmm7 movaps		xmm7, [esi+30] // xmm7: m33, m32, m31, m30
+
+		//////////////////////////////////////////////////////////////////////////////////////////////
+
+		pshufd		xmm0, xmm6, _MM_SHUFFLE(0, 3, 2, 1) // xmm0: m00, m03, m02, m01 
+		pshufd		xmm1, xmm7, _MM_SHUFFLE(1, 0, 3, 2) // xmm1: m31, m30, m33, m32 (movhlps optimization possible)
+		pshufd		xmm2, xmm6, _MM_SHUFFLE(1, 0, 3, 2) // xmm2: m01, m00, m03, m02 (movhlps optimization possible)
+		pshufd		xmm3, xmm7, _MM_SHUFFLE(0, 3, 2, 1) // xmm3: m30, m33, m32, m31 
+
+		mulps		xmm0, xmm1 // xmm0: m31*m00, m30*m03, m33*m02, m32*m01
+		mulps		xmm3, xmm2 // xmm3: m30*m01, m33*m00, m32*m03, m31*m02
+		subps		xmm3, xmm0 // xmm3: m30*m01-m31*m00, m33*m00-m30*m03, m32*m03-m33*m02, m31*m02-m32*m01
+		movaps		xmm4, xmm3 // xmm4: m30*m01-m31*m00, m33*m00-m30*m03, m32*m03-m33*m02, m31*m02-m32*m01
+
+		//////////////////////////////////////////////////////////////////////////////////////////////
+
+		// Reuse xmm0 pshufd		xmm0, xmm6, _MM_SHUFFLE(0, 3, 2, 1) // xmm0: m00, m03, m02, m01 
+		pshufd		xmm1, xmm7, _MM_SHUFFLE(2, 1, 0, 3) // xmm1: m32, m31, m30, m33
+		pshufd		xmm2, xmm6, _MM_SHUFFLE(2, 1, 0, 3) // xmm2: m02, m01, m00, m03 
+		// Reuse xmm3 pshufd		xmm3, xmm7, _MM_SHUFFLE(0, 3, 2, 1) // xmm3: m30, m33, m32, m31 
+
+		mulps		xmm0, xmm1 // xmm0: m00*m32, m03*m31, m02*m30, m01*m33 
+		mulps		xmm3, xmm2 // xmm3: m30*m02, m33*m01, m32*m00, m31*m03
+		subps		xmm0, xmm3 // xmm3: m00*m32-m30*m02, m03*m31-m33*m01, m02*m30-m32*m00, m01*m33-m31*m03
+		movaps		xmm5, xmm0 // xmm4: m00*m32-m30*m02, m03*m31-m33*m01, m02*m30-m32*m00, m01*m33-m31*m03
+
+		//////////////////////////////////////////////////////////////////////////////////////////////
+
+		pshufd		xmm0, xmm6, _MM_SHUFFLE(3, 0, 3, 2) // xmm0: m01, m00, m03, m02 (movhlps optimization possible)
+		// Reuse xmm1: pshufd		xmm1, xmm7, _MM_SHUFFLE(2, 1, 0, 3) // xmm1: m32, m31, m30, m33
+		// Reuse xmm2: pshufd		xmm2, xmm6, _MM_SHUFFLE(2, 1, 0, 3) // xmm2: m02, m01, m00, m03 
+		pshufd		xmm3, xmm7, _MM_SHUFFLE(3, 0, 3, 2) // xmm3: m31, m30, m33, m32 (movhlps optimization possible)
+
+		mulps		xmm0, xmm1 // xmm0: m01*m32, m00*m31, m03*m30, m02*m33 
+		mulps		xmm3, xmm2 // xmm3: m02*m31, m01*m30, m00*m33, m03*m32
+		subps		xmm3, xmm0 // xmm3: m02*m31-m01*m32, m01*m30-m00*m31, m00*m33-m03*m30, m03*m32-m02*m33
+		movaps		xmm6, xmm3 // xmm6: m02*m31-m01*m32, m01*m30-m00*m31, m00*m33-m03*m30, m03*m32-m02*m33
+
+		//////////////////////////////////////////////////////////////////////////////////////////////
+
+		movaps		xmm0, [esi+20] // m23, m22, m21, m20
+
+		pshufd		xmm1, xmm0, _MM_SHUFFLE(2, 1, 0, 3)
+		xorps		xmm1, mask0101 //-m22, m21,-m20, m23
+		mulaps		xmm4, xmm1
+
+		pshufd		xmm1, xmm0, _MM_SHUFFLE(1, 0, 3, 2) // (movhlps optimization possible)
+		xorps		xmm1, mask1010 // m21,-m20, m23,-m22
+		mulaps		xmm5, xmm1
+
+		pshufd		xmm1, xmm0, _MM_SHUFFLE(0, 3, 2, 1)
+		xorps		xmm1, mask0101 //-m20, m23,-m22, m21
+		mulaps		xmm6, xmm1
+
+		mulaps		xmm6, xmm5
+		mulaps		xmm6, xmm4
+		movaps		result[0x10], xmm6
+
+		//////////////////////////////////////////////////////////////////////////////////////////////
+
+		//R20 = +1 * m31*(m02*m13 - m12*m03) -1 * m32*(m03*m11 – m13*m01) +1 * m33*(m01*m12 - m11*m02)
+		//R21 = -1 * m32*(m03*m10 - m13*m00) +1 * m33*(m00*m12 – m10*m02) -1 * m30*(m02*m13 - m12*m03)
+		//R22 = +1 * m33*(m00*m11 - m10*m01) -1 * m30*(m01*m13 – m11*m03) +1 * m31*(m03*m10 - m13*m00)
+		//R23 = -1 * m30*(m01*m12 - m11*m02) +1 * m31*(m02*m10 – m12*m00) -1 * m32*(m00*m11 - m10*m01)
+
+		//Reuse xmm6: movaps		xmm6, [esi+00] // xmm6: m03, m02, m01, m00
+		movaps		xmm7, [esi+10] // xmm7: m13, m12, m11, m10
+
+		//////////////////////////////////////////////////////////////////////////////////////////////
+
+		pshufd		xmm0, xmm6, _MM_SHUFFLE(1, 0, 3, 2) // xmm0: m11, m10, m13, m12 (movhlps optimization possible)
+		pshufd		xmm1, xmm7, _MM_SHUFFLE(0, 3, 2, 1) // xmm1: m00, m03, m02, m01 
+		pshufd		xmm2, xmm6, _MM_SHUFFLE(0, 3, 2, 1) // xmm2: m10, m13, m12, m11 
+		pshufd		xmm3, xmm7, _MM_SHUFFLE(1, 0, 3, 2) // xmm3: m01, m00, m03, m02 (movhlps optimization possible)
+
+		mulps		xmm0, xmm1 // xmm0: m11*m00, m10*m03, m13*m02, m12*m01
+		mulps		xmm3, xmm2 // xmm3: m01*m10, m00*m13, m03*m12, m02*m11 
+		subps		xmm3, xmm0 // xmm3: m11*m00-m01*m10, m10*m03-m00*m13, m13*m02-m03*m12, m12*m01-m02*m11
+		movaps		xmm4, xmm3 // xmm4: m11*m00-m01*m10, m10*m03-m00*m13, m13*m02-m03*m12, m12*m01-m02*m11
+
+		//////////////////////////////////////////////////////////////////////////////////////////////
+
+
+
+
+
+
+
+		// Reuse xmm0 pshufd		xmm0, xmm6, _MM_SHUFFLE(0, 3, 2, 1) // xmm0: m00, m03, m02, m01 
+		pshufd		xmm1, xmm7, _MM_SHUFFLE(2, 1, 0, 3) // xmm1: m32, m31, m30, m33
+		pshufd		xmm2, xmm6, _MM_SHUFFLE(2, 1, 0, 3) // xmm2: m02, m01, m00, m03 
+		// Reuse xmm3 pshufd		xmm3, xmm7, _MM_SHUFFLE(0, 3, 2, 1) // xmm3: m30, m33, m32, m31 
+
+		mulps		xmm0, xmm1 // xmm0: m00*m32, m03*m31, m02*m30, m01*m33 
+		mulps		xmm3, xmm2 // xmm3: m30*m02, m33*m01, m32*m00, m31*m03
+		subps		xmm0, xmm3 // xmm3: m00*m32-m30*m02, m03*m31-m33*m01, m02*m30-m32*m00, m01*m33-m31*m03
+		movaps		xmm5, xmm0 // xmm4: m00*m32-m30*m02, m03*m31-m33*m01, m02*m30-m32*m00, m01*m33-m31*m03
+
+		//////////////////////////////////////////////////////////////////////////////////////////////
+
+		pshufd		xmm0, xmm6, _MM_SHUFFLE(3, 0, 3, 2) // xmm0: m01, m00, m03, m02 (movhlps optimization possible)
+		// Reuse xmm1: pshufd		xmm1, xmm7, _MM_SHUFFLE(2, 1, 0, 3) // xmm1: m32, m31, m30, m33
+		// Reuse xmm2: pshufd		xmm2, xmm6, _MM_SHUFFLE(2, 1, 0, 3) // xmm2: m02, m01, m00, m03 
+		pshufd		xmm3, xmm7, _MM_SHUFFLE(3, 0, 3, 2) // xmm3: m31, m30, m33, m32 (movhlps optimization possible)
+
+		mulps		xmm0, xmm1 // xmm0: m01*m32, m00*m31, m03*m30, m02*m33 
+		mulps		xmm3, xmm2 // xmm3: m02*m31, m01*m30, m00*m33, m03*m32
+		subps		xmm3, xmm0 // xmm3: m02*m31-m01*m32, m01*m30-m00*m31, m00*m33-m03*m30, m03*m32-m02*m33
+		movaps		xmm6, xmm3 // xmm6: m02*m31-m01*m32, m01*m30-m00*m31, m00*m33-m03*m30, m03*m32-m02*m33
+
+		//////////////////////////////////////////////////////////////////////////////////////////////
+
+		movaps		xmm0, [esi+20] // m23, m22, m21, m20
+
+		pshufd		xmm1, xmm0, _MM_SHUFFLE(2, 1, 0, 3)
+		xorps		xmm1, mask0101 //-m22, m21,-m20, m23
+		mulaps		xmm4, xmm1
+
+		pshufd		xmm1, xmm0, _MM_SHUFFLE(1, 0, 3, 2) // (movhlps optimization possible)
+		xorps		xmm1, mask1010 // m21,-m20, m23,-m22
+		mulaps		xmm5, xmm1
+
+		pshufd		xmm1, xmm0, _MM_SHUFFLE(0, 3, 2, 1)
+		xorps		xmm1, mask0101 //-m20, m23,-m22, m21
+		mulaps		xmm6, xmm1
+
+		mulaps		xmm6, xmm5
+		mulaps		xmm6, xmm4
+		movaps		result[0x10], xmm6
+
+		//////////////////////////////////////////////////////////////////////////////////////////////
+
+
+	}
+
+	return result;
+}
+
+__forceinline mat4 transpose(const mat4& m)
+{
+	mat4 result(mat4::NO_INIT);
+
+	__asm
+	{
+		mov			esi, m
+
+		movaps		xmm4, [esi+0x00]
+		movaps		xmm5, xmm4
+		movaps		xmm6, [esi+0x10]
+
+		unpcklps	xmm5, xmm6
+		unpckhps	xmm4, xmm6
+			
+		movaps		xmm0, xmm5
+		movhlps		xmm1, xmm5
+
+		movaps		xmm2, xmm4
+		movhlps		xmm3, xmm4
+
+		movaps		xmm4, [esi+0x20]
+		movaps		xmm5, xmm4
+		movaps		xmm6, [esi+0x30]
+
+		unpcklps	xmm5, xmm6
+		unpckhps	xmm4, xmm6
+
+		movlhps		xmm0, xmm5
+		movlhps		xmm2, xmm4
+
+		movhlps		xmm7, xmm5
+		movhlps		xmm6, xmm4
+
+		movlhps		xmm1, xmm7
+		movlhps		xmm3, xmm6
+
+		movaps		result[0x00], xmm0
+		movaps		result[0x10], xmm1
+		movaps		result[0x20], xmm2
+		movaps		result[0x30], xmm3
+	}
+
+	return result;
+}
+
+__forceinline void mat4::transpose()
+{
+	void* address = this;
+
+	__asm
+	{
+		mov			esi, address
+
+		movaps		xmm4, [esi+0x00]
+		movaps		xmm6, [esi+0x10]
+		movaps		xmm5, xmm4
+
+		unpcklps	xmm5, xmm6
+		movaps		xmm0, xmm5
+		movhlps		xmm1, xmm5
+
+		unpckhps	xmm4, xmm6
+		movaps		xmm2, xmm4
+		movhlps		xmm3, xmm4
+
+		movaps		xmm4, [esi+0x20]
+		movaps		xmm6, [esi+0x30]
+		movaps		xmm5, xmm4
+
+		unpcklps	xmm5, xmm6
+		movlhps		xmm0, xmm5
+		movhlps		xmm2, xmm5
+		movlhps		xmm1, xmm5
+
+		unpckhps	xmm4, xmm6
+		movlhps		xmm2, xmm4
+		movhlps		xmm4, xmm4
+		movlhps		xmm3, xmm4
+
+		movaps		[esi+0x00], xmm0
+		movaps		[esi+0x10], xmm1
+		movaps		[esi+0x20], xmm2
+		movaps		[esi+0x30], xmm3
+	}
+}
+
+
+/*
+inline mat4 transpose(const mat4& m)
+{
+	mat4 result;
+
+	__asm
+	{
+		mov			esi, m
+
+		movaps		xmm4, [esi+0x00]
+		movaps		xmm5, xmm4
+		movaps		xmm6, [esi+0x10]
+
+		unpcklps	xmm5, xmm6
+		unpckhps	xmm4, xmm6
+			
+		movaps		xmm0, xmm5
+		movhlps		xmm1, xmm5
+
+		movaps		xmm2, xmm4
+		movhlps		xmm3, xmm4
+
+		movaps		xmm4, [esi+0x20]
+		movaps		xmm5, xmm4
+		movaps		xmm6, [esi+0x30]
+
+		unpcklps	xmm5, xmm6
+		unpckhps	xmm4, xmm6
+
+		movlhps		xmm0, xmm5
+		movhlps		xmm7, xmm5
+		movlhps		xmm1, xmm7
+
+		movlhps		xmm2, xmm4
+		movhlps		xmm6, xmm4
+		movlhps		xmm3, xmm6
+
+		movaps		result[0x00], xmm0
+		movaps		result[0x10], xmm1
+		movaps		result[0x20], xmm2
+		movaps		result[0x30], xmm3
+	}
+
+	return result;
+}
+*/
+}//namespace sse
+}//namespace glm
+
+void test_sse_mat4();
+
+#endif//GLM_SSE_MAT4_H

+ 1 - 0
experimental/simd/sse_mat4array.cpp

@@ -0,0 +1 @@
+#include "precompiled.h"

+ 0 - 0
experimental/simd/sse_mat4array.h


+ 53 - 0
experimental/simd/sse_vec4.cpp

@@ -0,0 +1,53 @@
+#include "precompiled.h"
+#include "sse_vec4.h"
+/*
+void test_shufps(const glm::sse::vec4& v1, const glm::sse::vec4& v2)
+{
+	glm::sse::vec4 Result0;
+	__asm
+	{
+		mov		esi, v1
+		mov		edi, v2
+		movaps	xmm0, [esi]
+		movaps	xmm1, [edi]
+		shufps	xmm0, xmm1, _MM_SHUFFLE(3, 2, 1, 0)
+		movaps	Result0, xmm0
+	}
+
+	glm::sse::vec4 Result1;
+	__asm
+	{
+		mov		esi, v1
+		mov		edi, v2
+		movaps	xmm2, [esi]
+		movaps	xmm3, [edi]
+		pshufd	xmm2, xmm3, _MM_SHUFFLE(3, 2, 1, 0)
+		movaps	Result1, xmm2
+	}
+
+	glm::sse::vec4 end;
+}
+
+void test_sse_vec4()
+{
+	test_shufps(
+		glm::sse::vec4(1.0f, 2.0f, 3.0f, 4.0f),
+		glm::sse::vec4(5.0f, 6.0f, 7.0f, 8.0f));
+
+	glm::sse::vec4 v0;
+	glm::sse::vec4 v1(76.f);
+	glm::sse::vec4 v2(5.f, 1.f, 2.f, 3.f);
+	v2 += v1;
+	glm::sse::vec4 v3 = v2;
+	glm::sse::vec4 v4(1.0f);
+	float dot = glm::sse::dot(v4, v1);
+	++v4;
+	glm::sse::vec4 v5 = -v4;
+	glm::sse::vec4 v6(2.f);
+	glm::sse::vec4 v7 = glm::sse::cross(v2, v6);
+	glm::vec3 v8 = glm::cross(glm::vec3(5.f, 1.f, 2.f), glm::vec3(2.f));
+	//printf("vec4(%f, %f, %f, %f)\n", v4.x, v4.y, v4.z, v4.w);
+	glm::sse::vec4 v9 = glm::sse::normalize(glm::sse::vec4(1.0f, 1.0f, 1.0f, 0.0f));
+	glm::sse::vec4 vx;
+}
+*/

+ 290 - 0
experimental/simd/sse_vec4.h

@@ -0,0 +1,290 @@
+#ifndef GLM_SSE_VEC4_H
+#define GLM_SSE_VEC4_H
+
+#include <xmmintrin.h>
+#include <emmintrin.h>
+
+namespace glm{
+namespace sse{
+
+#define GLM_SHUFFLE(fp3,fp2,fp1,fp0) (((fp3) << 6) | ((fp2) << 4) | ((fp1) << 2) | ((fp0)))
+
+const __m128 zero = _mm_setzero_ps();
+const __m128 one = _mm_set_ps1(1.0f);
+const __m128 two = _mm_set_ps1(2.0f);
+const __m128 three = _mm_set_ps1(3.0f);
+const __m128 pouet = _mm_set_ps(2.0f, 4.0f, 6.0f, 8.0f);
+
+#define GLM_ALIGN(x) __declspec(align(x))
+
+GLM_ALIGN(16) struct vec4
+{
+	enum ENoInit
+	{
+		NO_INIT
+	};
+
+	union
+	{
+		__m128 data;
+		struct s{float x, y, z, w;};
+		float array[4];
+	};
+
+	vec4();
+	vec4(ENoInit NoInit);
+	vec4(float s);
+	vec4(float x, float y, float z, float w);
+	vec4(float v[4]);
+
+	vec4& operator+=(const float s);
+
+	vec4& operator+=(const vec4& v);
+	vec4& operator*=(const vec4& v);
+
+	vec4& operator++();
+};
+
+__forceinline vec4::vec4()
+{
+	void* address = this;
+
+	__asm
+	{
+		mov		eax, [address]
+		xorps	xmm0, xmm0
+		movaps	[eax], xmm0
+	}
+}
+
+__forceinline vec4::vec4(ENoInit NoInit)
+{}
+
+__forceinline vec4::vec4(float s)
+{
+	void* address = this;
+
+	__asm
+	{
+		mov		esi, [address]
+		movss	xmm0, s
+		shufps	xmm0, xmm0, 0	
+		movaps	[esi], xmm0
+	}
+}
+
+__forceinline vec4::vec4(float x, float y, float z, float w)
+{
+	void* address = this;
+
+	__asm
+	{
+		mov			esi, address
+		movss		xmm0, x
+		movss		xmm1, y
+		movss		xmm2, z
+		movss		xmm3, w
+		unpcklps	xmm0, xmm1
+		unpcklps	xmm2, xmm3
+		movlhps		xmm0, xmm2
+		movaps		[esi], xmm0
+	}
+}
+
+__forceinline vec4::vec4(float v[4])
+{
+	void* address = this;
+
+	__asm
+	{
+		mov		eax, [address]
+		mov		ebx, [v]
+		movups	xmm0, [ebx]
+		movaps	[eax], xmm0
+	}
+}
+
+__forceinline vec4& vec4::operator+=(const float s)
+{
+	void* address = this;
+
+	__asm
+	{
+		mov		eax, [address]
+		movss	xmm1, s
+		shufps	xmm1, xmm1, 0
+		movaps	xmm0, [eax]
+		addps	xmm0, xmm1	
+		movaps	[eax], xmm0
+	}
+
+	return *this;	
+}
+
+__forceinline vec4& vec4::operator+=(const vec4& v)
+{
+	void* address = this;
+
+	__asm
+	{
+		mov		eax, [address]
+		mov		ebx, [v]
+		movaps	xmm0, [eax]
+		addps	xmm0, [ebx]	
+		movaps	[eax], xmm0
+	}
+
+	return *this;
+}
+
+__forceinline vec4& vec4::operator*=(const vec4& v)
+{
+	void* address = this;
+
+	__asm
+	{
+		mov		esi, address
+		mov		edi, v
+		movaps	xmm0, esi
+		mulps	xmm0, edi	
+		movaps	[esi], xmm0
+	}
+
+	return *this;
+}
+
+__forceinline vec4& vec4::operator++()
+{
+	void* address = this;
+
+	__asm
+	{
+		mov		eax, [address]
+		movaps	xmm0, [eax]
+		addps	xmm0, one	
+		movaps	[eax], xmm0
+	}
+
+	return *this;
+}
+
+__forceinline const vec4 operator- (const vec4& v)
+{
+	vec4 result(vec4::NO_INIT);
+
+	__asm
+	{
+		mov		esi, v
+		xorps	xmm0, xmm0
+		subps	xmm0, [esi]	
+		movaps	result, xmm0
+	}
+
+	result;
+}
+
+__forceinline vec4 cross(const vec4& v1, const vec4& v2)
+{
+	vec4 result(vec4::NO_INIT);
+
+	__asm
+	{
+		mov		esi, v1
+		mov		edi, v2
+		movaps	xmm0, [esi]
+		movaps	xmm1, [edi]
+		shufps	xmm0, xmm0, _MM_SHUFFLE(3, 0, 2, 1)
+		movaps	xmm2, xmm0
+		shufps	xmm0, xmm0, _MM_SHUFFLE(3, 1, 0, 2)
+		shufps	xmm1, xmm1, _MM_SHUFFLE(3, 0, 2, 1)
+		movaps	xmm3, xmm1
+		shufps	xmm1, xmm1, _MM_SHUFFLE(3, 1, 0, 2)
+		mulps	xmm0, xmm3
+		mulps	xmm1, xmm2
+		subps	xmm0, xmm1
+		movaps	result, xmm0
+	}
+
+	return result;
+}
+
+__forceinline float dot(const vec4& v1, const vec4& v2)
+{
+	float result;
+
+	// All component processed
+	//__asm
+	//{
+	//	mov		esi, v1
+	//	mov		edi, v2
+	//	movaps	xmm0, [esi]
+	//	movaps	xmm1, [edi]
+	//	mulps	xmm0, xmm1
+	//	movaps	xmm1, xmm0
+	//	shufps	xmm0, xmm0, _MM_SHUFFLE(2, 3, 0, 1)
+	//	addps	xmm0, xmm1
+	//	movaps	xmm1, xmm0
+	//	shufps	xmm0, xmm0, _MM_SHUFFLE(0, 1, 2, 3)
+	//	addps	xmm0, xmm1
+	//	movss	result, xmm0
+	//}
+
+	// SSE
+	__asm
+	{
+		mov		esi, v1
+		mov		edi, v2
+		movaps	xmm0, [esi]		// w1, z1, y1, x1
+		mulps	xmm0, [edi]		// w1 * w2, z1 * z2, y1 * y2, x1 * x2
+		movhlps	xmm1, xmm0		// XX, XX, w1 * w2, z1 * z2
+		addps	xmm0, xmm1		// XX, XX, y1 * y2 + w1 * w2, x1 * x2 + z1 * z2
+		pshufd	xmm1, xmm0, 1	// XX, XX, XX, y1 * y2 + w1 * w2
+		addss	xmm0, xmm1		// y1 * y2 + w1 * w2 + x1 * x2 + z1 * z2
+		movss	result, xmm0
+	}
+
+	// SSE 3
+
+	// SSE 4.1
+	//__asm
+	//{
+	//	mov		esi, v1
+	//	mov		edi, v2
+	//	movaps	xmm0, [esi]
+	//	dpps	xmm0, [edi]
+	//	movss	result, xmm0
+	//}
+
+	return result;
+}
+
+__forceinline vec4 normalize(const vec4& v)
+{
+	vec4 result(vec4::NO_INIT);
+
+	__asm
+	{
+		mov		esi, v
+		movaps	xmm2, [esi]
+		movaps	xmm0, xmm2
+		mulps	xmm0, xmm0
+		movaps	xmm1, xmm0
+		shufps	xmm0, xmm0, _MM_SHUFFLE(2, 3, 0, 1)
+		addps	xmm0, xmm1
+		movaps	xmm1, xmm0
+		shufps	xmm0, xmm0, _MM_SHUFFLE(0, 1, 2, 3)
+		addps	xmm0, xmm1
+		rsqrtps	xmm0, xmm0
+		mulps	xmm2, xmm0
+		movaps	result, xmm2
+	}
+
+	return result;
+}
+
+}//namespace sse
+}//namespace glm
+
+void test_sse_vec4();
+
+#endif//GLM_SSE_VEC4_H

+ 1 - 0
experimental/simd/sse_vec4array.cpp

@@ -0,0 +1 @@
+#include "precompiled.h"

+ 0 - 0
experimental/simd/sse_vec4array.h


+ 54 - 0
experimental/sse/glm/core/_bvec2.h

@@ -0,0 +1,54 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2008 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2006-04-27
+// Updated : 2007-01-19
+// Licence : This source is under GNU LGPL licence
+// File    : glm/core/_bvec2.h
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef __glm_core_bvec2__
+#define __glm_core_bvec2__
+
+#include "./_cvec2.inl"
+
+namespace glm{
+namespace detail{
+
+	class _bvec2 : public _cvec2<bool, _bvec2, _bvec3, _bvec4, _xref2<bool> >
+	{
+	public:
+		// Common constructors
+		_bvec2();
+		_bvec2(const _bvec2& v);
+
+		// Swizzle constructors
+		_bvec2(const _xref2<bool>& r);
+
+		// Bool constructors
+		explicit _bvec2(const bool a);
+		explicit _bvec2(const bool a, const bool b);
+		explicit _bvec2(const bool a, const _bvec2& b);
+		explicit _bvec2(const bool a, const _bvec3& b);
+		explicit _bvec2(const bool a, const _bvec4& b);
+		explicit _bvec2(const _bvec3& a);
+		explicit _bvec2(const _bvec4& a);
+
+		// U constructors
+		template <typename U> explicit _bvec2(const U x);
+		template <typename U> explicit _bvec2(const U a, const U b);
+		template <typename U> explicit _bvec2(const U a, const _xvec2<U>& b);
+		template <typename U> explicit _bvec2(const U a, const _xvec3<U>& b);
+		template <typename U> explicit _bvec2(const U a, const _xvec4<U>& b);
+		template <typename U> explicit _bvec2(const _xvec3<U>& a);
+		template <typename U> explicit _bvec2(const _xvec4<U>& a);
+
+		// Operators
+		_bvec2& operator=(const _bvec2& v);
+		//_bvec2 operator! () const;
+	};
+
+} //namespace detail
+} //namespace glm
+
+#endif//__glm_core_bvec2__

+ 159 - 0
experimental/sse/glm/core/_bvec2.inl

@@ -0,0 +1,159 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2008 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2006-04-27
+// Updated : 2007-01-19
+// Licence : This source is under GNU LGPL licence
+// File    : _bvec2.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef __bvec2_inl__
+#define __bvec2_inl__
+
+#include "./_bvec2.h"
+#include "./_bvec3.h"
+#include "./_bvec4.h"
+#include "./_xref2.h"
+#include "./_xref3.h"
+#include "./_xref4.h"
+#include "./_swizzle.inl"
+
+namespace glm{
+namespace detail{
+
+    //////////////////////////////////////////////////////////////
+    // Common constructors
+
+    inline _bvec2::_bvec2() :
+		_cvec2<BVEC2_INST>(false, false)
+    {}
+
+    inline _bvec2::_bvec2(const _bvec2& v) :
+        _cvec2<BVEC2_INST>(v.x, v.y)
+    {}
+
+    //////////////////////////////////////////////////////////////
+    // Swizzle constructors
+    inline _bvec2::_bvec2(const _xref2<bool>& r) :
+        _cvec2<BVEC2_INST>(r.x, r.y)
+    {}
+
+    //////////////////////////////////////////////////////////////
+    // Bool constructors
+
+    inline _bvec2::_bvec2(const bool a) :
+        _cvec2<BVEC2_INST>(a, a)
+    {}
+
+    inline _bvec2::_bvec2(const bool a, const bool b) :
+        _cvec2<BVEC2_INST>(a, b)
+    {}
+
+    inline _bvec2::_bvec2(const bool a, const _bvec2& b) :
+        _cvec2<BVEC2_INST>(a, b.x)
+    {}
+
+    inline _bvec2::_bvec2(const bool a, const _bvec3& b) :
+        _cvec2<BVEC2_INST>(a, b.x)
+    {}
+
+    inline _bvec2::_bvec2(const bool a, const _bvec4& b) :
+        _cvec2<BVEC2_INST>(a, b.x)
+    {}
+
+    inline _bvec2::_bvec2(const _bvec3& a) :
+        _cvec2<BVEC2_INST>(a.x, a.y)
+    {}
+
+    inline _bvec2::_bvec2(const _bvec4& a) :
+        _cvec2<BVEC2_INST>(a.x, a.y)
+    {}
+
+    //////////////////////////////////////////////////////////////
+    // U constructors
+
+    template <typename U> 
+    inline _bvec2::_bvec2(const U a) :
+        _cvec2<BVEC2_INST>(bool(a), bool(a))
+    {}
+
+    template <typename U> 
+    inline _bvec2::_bvec2(const U a, const U b) :
+        _cvec2<BVEC2_INST>(bool(a), bool(b))
+    {}
+
+    template <typename U> 
+    inline _bvec2::_bvec2(const U a, const _xvec2<U>& b) :
+        _cvec2<BVEC2_INST>(bool(a), bool(b.x))
+    {}
+
+    template <typename U> 
+    inline _bvec2::_bvec2(const U a, const _xvec3<U>& b) :
+        _cvec2<BVEC2_INST>(bool(a), bool(b.x))
+    {}
+
+    template <typename U> 
+    inline _bvec2::_bvec2(const U a, const _xvec4<U>& b) :
+        _cvec2<BVEC2_INST>(bool(a), bool(b.x))
+    {}
+
+    template <typename U> 
+    inline _bvec2::_bvec2(const _xvec3<U>& a) :
+        _cvec2<BVEC2_INST>(bool(a.x), bool(a.y))
+    {}
+
+    template <typename U> 
+    inline _bvec2::_bvec2(const _xvec4<U>& a) :
+        _cvec2<BVEC2_INST>(bool(a.x), bool(a.y))
+    {}
+
+    //////////////////////////////////////////////////////////////
+    // bvec2 operators
+
+    // This function shouldn't required but it seems that VC7.1 have an optimisation bug if this operator wasn't declared
+    inline _bvec2& _bvec2::operator=(const _bvec2& x)
+    {
+        this->x = x.x;
+        this->y = x.y;
+        return *this;
+    }
+/*
+    inline _bvec2 _bvec2::operator--()
+    {
+	    x = !x;
+	    y = !y;
+	    return *this;
+    }
+
+    inline _bvec2 _bvec2::operator++()
+    {
+	    x = !x;
+	    y = !y;
+	    return *this;
+    }
+
+    inline const _bvec2 _bvec2::operator--(int n) const 
+    {
+        return _bvec2(
+			!this->x, 
+			!this->y);
+    }
+
+    inline const _bvec2 _bvec2::operator++(int n) const
+    {
+	    return _bvec2(
+			!this->x, 
+			!this->y);
+    }
+*/
+	//inline _bvec2 _bvec2::operator!() const 
+	//{
+	//	return _bvec2(
+	//		!this->x, 
+	//		!this->y);
+	//}
+
+} //namespace detail
+} //namespace glm
+
+#endif //__bvec2_inl__

+ 67 - 0
experimental/sse/glm/core/_bvec3.h

@@ -0,0 +1,67 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2008 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2006-04-27
+// Updated : 2007-01-19
+// Licence : This source is under GNU LGPL licence
+// File    : glm/core/_bvec3.h
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef __glm_core_bvec3__
+#define __glm_core_bvec3__
+
+#include "./_cvec3.inl"
+
+namespace glm{
+namespace detail{
+
+    class _bvec3 : public _cvec3<bool, _bvec2, _bvec3, _bvec4, _xref2<bool>, _xref3<bool> >
+    {
+	public:
+        // Common constructors
+	    _bvec3();
+        _bvec3(const _bvec3& v);
+
+        // Swizzle constructors
+        _bvec3(const _xref3<bool>& r);
+
+        // Bool constructors
+        explicit _bvec3(const bool a);
+        explicit _bvec3(const bool a, const bool b, const bool c);
+        explicit _bvec3(const bool a, const bool b, const _bvec2& c);
+        explicit _bvec3(const bool a, const bool b, const _bvec3& c);
+        explicit _bvec3(const bool a, const bool b, const _bvec4& c);
+        explicit _bvec3(const bool a, const _bvec2& b);
+        explicit _bvec3(const bool a, const _bvec3& b);
+        explicit _bvec3(const bool a, const _bvec4& b);
+        explicit _bvec3(const _bvec2& a, bool b);
+        explicit _bvec3(const _bvec2& a, const _bvec2& b);
+        explicit _bvec3(const _bvec2& a, const _bvec3& b);
+        explicit _bvec3(const _bvec2& a, const _bvec4& b);
+        explicit _bvec3(const _bvec4& a);
+
+        // U constructors
+        template <typename U> explicit _bvec3(const U x);
+        template <typename U> explicit _bvec3(const U a, const U b, const U c);
+        template <typename U> explicit _bvec3(const U a, const U b, const _xvec2<U>& c);
+        template <typename U> explicit _bvec3(const U a, const U b, const _xvec3<U>& c);
+        template <typename U> explicit _bvec3(const U a, const U b, const _xvec4<U>& c);
+        template <typename U> explicit _bvec3(const U a, const _xvec2<U>& b);
+        template <typename U> explicit _bvec3(const U a, const _xvec3<U>& b);
+        template <typename U> explicit _bvec3(const U a, const _xvec4<U>& b);
+        template <typename U> explicit _bvec3(const _xvec2<U>& a, U b);
+        template <typename U> explicit _bvec3(const _xvec2<U>& a, const _xvec2<U>& b);
+        template <typename U> explicit _bvec3(const _xvec2<U>& a, const _xvec3<U>& b);
+        template <typename U> explicit _bvec3(const _xvec2<U>& a, const _xvec4<U>& b);
+        template <typename U> explicit _bvec3(const _xvec3<U>& a);
+        template <typename U> explicit _bvec3(const _xvec4<U>& a);
+
+        // Operators
+        _bvec3& operator=(const _bvec3& x);
+	    //_bvec3 operator! () const;
+    };
+
+} //namespace detail
+} //namespace glm
+
+#endif//__glm_core_bvec3__

+ 224 - 0
experimental/sse/glm/core/_bvec3.inl

@@ -0,0 +1,224 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2008 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2006-04-27
+// Updated : 2007-01-19
+// Licence : This source is under GNU LGPL licence
+// File    : _bvec3.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef __bvec3_inl__
+#define __bvec3_inl__
+
+#include "./_bvec2.h"
+#include "./_bvec3.h"
+#include "./_bvec4.h"
+#include "./_xref2.h"
+#include "./_xref3.h"
+#include "./_xref4.h"
+#include "./_swizzle.inl"
+
+namespace glm{
+namespace detail{
+
+    //////////////////////////////////////////////////////////////
+    // Common constructors
+
+    inline _bvec3::_bvec3() :
+        _cvec3<BVEC3_INST>(false, false, false)
+    {}
+
+    inline _bvec3::_bvec3(const _bvec3& v) : 
+		_cvec3<BVEC3_INST>(v.x, v.y, v.z)
+    {}
+
+    //////////////////////////////////////////////////////////////
+    // Swizzle constructors
+    inline _bvec3::_bvec3(const _xref3<bool>& r) :
+        _cvec3<BVEC3_INST>(r.x, r.y, r.z)
+    {}
+
+    //////////////////////////////////////////////////////////////
+    // Bool constructors
+
+    inline _bvec3::_bvec3(const bool a) :
+        _cvec3<BVEC3_INST>(a, a, a)
+    {}
+
+    inline _bvec3::_bvec3(const bool a, const bool b, const bool c) :
+        _cvec3<BVEC3_INST>(a, b, c)
+    {}
+
+    inline _bvec3::_bvec3(const bool a, const bool b, const _bvec2& c) :
+        _cvec3<BVEC3_INST>(a, b, c.x)
+    {}
+
+    inline _bvec3::_bvec3(const bool a, const bool b, const _bvec3& c) :
+        _cvec3<BVEC3_INST>(a, b, c.x)
+    {}
+
+    inline _bvec3::_bvec3(const bool a, const bool b, const _bvec4& c) :
+        _cvec3<BVEC3_INST>(a, b, c.x)
+    {}
+
+    inline _bvec3::_bvec3(const bool a, const _bvec2& b) :
+        _cvec3<BVEC3_INST>(a, b.x, b.y)
+    {}
+
+    inline _bvec3::_bvec3(const bool a, const _bvec3& b) :
+        _cvec3<BVEC3_INST>(a, b.x, b.y)
+    {}
+
+    inline _bvec3::_bvec3(const bool a, const _bvec4& b) :
+        _cvec3<BVEC3_INST>(a, b.x, b.y)
+    {}
+
+    inline _bvec3::_bvec3(const _bvec2& a, bool b) :
+        _cvec3<BVEC3_INST>(a.x, a.y, b)
+    {}
+
+    inline _bvec3::_bvec3(const _bvec2& a, const _bvec2& b) :
+        _cvec3<BVEC3_INST>(a.x, a.y, b.x)
+    {}
+
+    inline _bvec3::_bvec3(const _bvec2& a, const _bvec3& b) :
+        _cvec3<BVEC3_INST>(a.x, a.y, b.x)
+    {}
+
+    inline _bvec3::_bvec3(const _bvec2& a, const _bvec4& b) :
+        _cvec3<BVEC3_INST>(a.x, a.y, b.x)
+    {}
+
+    inline _bvec3::_bvec3(const _bvec4& a) :
+        _cvec3<BVEC3_INST>(a.x, a.y, a.z)
+    {}
+
+    //////////////////////////////////////////////////////////////
+    // U constructors
+
+    template <typename U> 
+    inline _bvec3::_bvec3(const U a) :
+        _cvec3<BVEC3_INST>(bool(a), bool(a), bool(a))
+    {}
+
+    template <typename U> 
+    inline _bvec3::_bvec3(const U a, const U b, const U c) :
+        _cvec3<BVEC3_INST>(bool(a), bool(b), bool(c))
+    {}
+
+    template <typename U> 
+    inline _bvec3::_bvec3(const U a, const U b, const _xvec2<U>& c) :
+        _cvec3<BVEC3_INST>(bool(a), bool(b), bool(c.x))
+    {}
+
+    template <typename U> 
+    inline _bvec3::_bvec3(const U a, const U b, const _xvec3<U>& c) :
+        _cvec3<BVEC3_INST>(bool(a), bool(b), bool(c.x))
+    {}
+
+    template <typename U> 
+    inline _bvec3::_bvec3(const U a, const U b, const _xvec4<U>& c) :
+        _cvec3<BVEC3_INST>(bool(a), bool(b), bool(c.x))
+    {}
+
+    template <typename U> 
+    inline _bvec3::_bvec3(const U a, const _xvec2<U>& b) :
+		_cvec3<BVEC3_INST>(bool(a), bool(b.x), bool(b.y))
+    {}
+
+    template <typename U> 
+    inline _bvec3::_bvec3(const U a, const _xvec3<U>& b) :
+		_cvec3<BVEC3_INST>(bool(a), bool(b.x), bool(b.y))
+    {}
+
+    template <typename U> 
+    inline _bvec3::_bvec3(const U a, const _xvec4<U>& b) :
+		_cvec3<BVEC3_INST>(bool(a), bool(b.x), bool(b.y))
+    {}
+
+    template <typename U> 
+    inline _bvec3::_bvec3(const _xvec2<U>& a, U b) :
+		_cvec3<BVEC3_INST>(bool(a.x), bool(a.y), bool(b))
+    {}
+
+    template <typename U> 
+    inline _bvec3::_bvec3(const _xvec2<U>& a, const _xvec2<U>& b) :
+		_cvec3<BVEC3_INST>(bool(a.x), bool(a.y), bool(b.x))
+    {}
+
+    template <typename U> 
+    inline _bvec3::_bvec3(const _xvec2<U>& a, const _xvec3<U>& b) :
+		_cvec3<BVEC3_INST>(bool(a.x), bool(a.y), bool(b.x))
+    {}
+
+    template <typename U> 
+    inline _bvec3::_bvec3(const _xvec2<U>& a, const _xvec4<U>& b) :
+		_cvec3<BVEC3_INST>(bool(a.x), bool(a.y), bool(b.x))
+    {}
+
+    template <typename U> 
+    inline _bvec3::_bvec3(const _xvec3<U>& a) :
+		_cvec3<BVEC3_INST>(bool(a.x), bool(a.y), bool(a.z))
+    {}
+
+    template <typename U> 
+    inline _bvec3::_bvec3(const _xvec4<U>& a) :
+		_cvec3<BVEC3_INST>(bool(a.x), bool(a.y), bool(a.z))
+    {}
+
+    //////////////////////////////////////////////////////////////
+    // bvec3 operators
+
+    // This function shouldn't required but it seems that VC7.1 have an optimisation bug if this operator wasn't declared
+    inline _bvec3& _bvec3::operator=(const _bvec3& x)
+    {
+        this->x = x.x;
+        this->y = x.y;
+        this->z = x.z;
+        return *this;
+    }
+/*
+    inline _bvec3 _bvec3::operator--()
+    {
+	    this->x = !x;
+	    this->y = !y;
+        this->z = !z;
+	    return *this;
+    }
+
+    inline _bvec3 _bvec3::operator++()
+    {
+	    this->x = !x;
+	    this->y = !y;
+        this->z = !z;
+	    return *this;
+    }
+
+    inline const _bvec3 _bvec3::operator--(int n) const 
+    {
+		return _bvec3(
+			!this->x, 
+			!this->y, 
+			!this->z);
+    }
+
+    inline const _bvec3 _bvec3::operator++(int n) const
+    {
+		return _bvec3(
+			!this->x, 
+			!this->y, 
+			!this->z);
+    }
+*/
+	//inline _bvec3 _bvec3::operator!() const 
+	//{
+	//	return _bvec3(
+	//		!this->x, 
+	//		!this->y, 
+	//		!this->z);
+	//}
+
+} //namespace detail
+} //namespace glm
+
+#endif//__bvec3_inl__

+ 91 - 0
experimental/sse/glm/core/_bvec4.h

@@ -0,0 +1,91 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2008 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2006-04-27
+// Updated : 2007-01-19
+// Licence : This source is under GNU LGPL licence
+// File    : glm/core/_bvec4.h
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef __glm_core_bvec4__
+#define __glm_core_bvec4__
+
+#include "./_cvec4.inl"
+
+namespace glm{
+namespace detail{
+
+    class _bvec4 : public _cvec4<bool, _bvec2, _bvec3, _bvec4, _xref2<bool>, _xref3<bool>, _xref4<bool> >
+    {
+	public:
+        // Common constructors
+	    _bvec4();
+        _bvec4(const _bvec4& v);
+
+        // Swizzle constructors
+        _bvec4(const _xref4<bool>& r);
+
+        // Bool constructors
+        explicit _bvec4(const bool x);
+        explicit _bvec4(const bool a, const bool b, const bool c, const bool d);
+        explicit _bvec4(const bool a, const bool b, const bool c, const _bvec2& d);
+        explicit _bvec4(const bool a, const bool b, const bool c, const _bvec3& d);
+        explicit _bvec4(const bool a, const bool b, const bool c, const _bvec4& d);
+        explicit _bvec4(const bool a, const bool b, const _bvec2& c);
+        explicit _bvec4(const bool a, const bool b, const _bvec3& c);
+        explicit _bvec4(const bool a, const bool b, const _bvec4& c);
+        explicit _bvec4(const bool a, const _bvec2& b, const bool c);
+        explicit _bvec4(const bool a, const _bvec2& b, const _bvec2& c);
+        explicit _bvec4(const bool a, const _bvec2& b, const _bvec3& c);
+        explicit _bvec4(const bool a, const _bvec2& b, const _bvec4& c);
+        explicit _bvec4(const bool a, const _bvec3& b);
+        explicit _bvec4(const bool a, const _bvec4& b);
+        explicit _bvec4(const _bvec2& a, const bool b, const bool c);
+        explicit _bvec4(const _bvec2& a, const bool b, const _bvec2& c);
+        explicit _bvec4(const _bvec2& a, const bool b, const _bvec3& c);
+        explicit _bvec4(const _bvec2& a, const bool b, const _bvec4& c);
+        explicit _bvec4(const _bvec2& a, const _bvec2& b);
+        explicit _bvec4(const _bvec2& a, const _bvec3& b);
+        explicit _bvec4(const _bvec2& a, const _bvec4& b);
+        explicit _bvec4(const _bvec3& a, const bool b);
+        explicit _bvec4(const _bvec3& a, const _bvec2& b);
+        explicit _bvec4(const _bvec3& a, const _bvec3& b);
+        explicit _bvec4(const _bvec3& a, const _bvec4& b);
+
+        // U constructors
+        template <typename U> explicit _bvec4(const U x);
+        template <typename U> explicit _bvec4(const U a, const U b, const U c, const U d);
+        template <typename U> explicit _bvec4(const U a, const U b, const U c, const _xvec2<U>& d);
+        template <typename U> explicit _bvec4(const U a, const U b, const U c, const _xvec3<U>& d);
+        template <typename U> explicit _bvec4(const U a, const U b, const U c, const _xvec4<U>& d);
+        template <typename U> explicit _bvec4(const U a, const U b, const _xvec2<U>& c);
+        template <typename U> explicit _bvec4(const U a, const U b, const _xvec3<U>& c);
+        template <typename U> explicit _bvec4(const U a, const U b, const _xvec4<U>& c);
+        template <typename U> explicit _bvec4(const U a, const _xvec2<U>& b, const U c);
+        template <typename U> explicit _bvec4(const U a, const _xvec2<U>& b, const _xvec2<U>& c);
+        template <typename U> explicit _bvec4(const U a, const _xvec2<U>& b, const _xvec3<U>& c);
+        template <typename U> explicit _bvec4(const U a, const _xvec2<U>& b, const _xvec4<U>& c);
+        template <typename U> explicit _bvec4(const U a, const _xvec3<U>& b);
+        template <typename U> explicit _bvec4(const U a, const _xvec4<U>& b);
+        template <typename U> explicit _bvec4(const _xvec2<U>& a, const U b, const U c);
+        template <typename U> explicit _bvec4(const _xvec2<U>& a, const U b, const _xvec2<U>& c);
+        template <typename U> explicit _bvec4(const _xvec2<U>& a, const U b, const _xvec3<U>& c);
+        template <typename U> explicit _bvec4(const _xvec2<U>& a, const U b, const _xvec4<U>& c);
+        template <typename U> explicit _bvec4(const _xvec2<U>& a, const _xvec2<U>& b);
+        template <typename U> explicit _bvec4(const _xvec2<U>& a, const _xvec3<U>& b);
+        template <typename U> explicit _bvec4(const _xvec2<U>& a, const _xvec4<U>& b);
+        template <typename U> explicit _bvec4(const _xvec3<U>& a, const U b);
+        template <typename U> explicit _bvec4(const _xvec3<U>& a, const _xvec2<U>& b);
+        template <typename U> explicit _bvec4(const _xvec3<U>& a, const _xvec3<U>& b);
+        template <typename U> explicit _bvec4(const _xvec3<U>& a, const _xvec4<U>& b);
+        template <typename U> explicit _bvec4(const _xvec4<U>& a);
+
+        // Operators
+        _bvec4& operator=(const _bvec4& x);
+		//_bvec4 operator!() const ;
+    };
+
+} //namespace detail
+} //namespace glm
+
+#endif//__glm_core_bvec4__

+ 335 - 0
experimental/sse/glm/core/_bvec4.inl

@@ -0,0 +1,335 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2008 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2006-04-27
+// Updated : 2007-01-19
+// Licence : This source is under GNU LGPL licence
+// File    : _bvec4.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef __bvec4_inl__
+#define __bvec4_inl__
+
+#include "./_bvec2.h"
+#include "./_bvec3.h"
+#include "./_bvec4.h"
+#include "./_xref2.h"
+#include "./_xref3.h"
+#include "./_xref4.h"
+#include "./_swizzle.inl"
+
+namespace glm{
+namespace detail{
+
+    //////////////////////////////////////////////////////////////
+    // bvec4 constructors
+
+    inline _bvec4::_bvec4() :
+		_cvec4<BVEC4_INST>(false, false, false, false)
+    {}
+
+    inline _bvec4::_bvec4(const _bvec4& v) :
+		_cvec4<BVEC4_INST>(v.x, v.y, v.z, v.w)
+    {}
+
+    //////////////////////////////////////////////////////////////
+    // Swizzle constructors
+    inline _bvec4::_bvec4(const _xref4<bool>& r) :
+		_cvec4<BVEC4_INST>(r.x, r.y, r.z, r.w)
+    {}
+
+    // Bool constructors
+    inline _bvec4::_bvec4(const bool a) :
+		_cvec4<BVEC4_INST>(a, a, a, a)
+    {}
+
+    inline _bvec4::_bvec4(const bool a, const bool b, const bool c, const bool d) :
+		_cvec4<BVEC4_INST>(a, b, c, d)
+    {}
+
+    inline _bvec4::_bvec4(const bool a, const bool b, const bool c, const _bvec2& d) :
+		_cvec4<BVEC4_INST>(a, b, c, d.x)
+    {}
+
+    inline _bvec4::_bvec4(const bool a, const bool b, const bool c, const _bvec3& d) :
+		_cvec4<BVEC4_INST>(a, b, c, d.x)
+    {}
+
+    inline _bvec4::_bvec4(const bool a, const bool b, const bool c, const _bvec4& d) :
+		_cvec4<BVEC4_INST>(a, b, c, d.x)
+    {}
+
+    inline _bvec4::_bvec4(const bool a, const bool b, const _bvec2& c) :
+		_cvec4<BVEC4_INST>(a, b, c.x, c.y)
+    {}
+
+    inline _bvec4::_bvec4(const bool a, const bool b, const _bvec3& c) :
+		_cvec4<BVEC4_INST>(a, b, c.x, c.y)
+    {}
+
+    inline _bvec4::_bvec4(const bool a, const bool b, const _bvec4& c) :
+		_cvec4<BVEC4_INST>(a, b, c.x, c.y)
+    {}
+
+    inline _bvec4::_bvec4(const bool a, const _bvec2& b, const bool c) :
+		_cvec4<BVEC4_INST>(a, b.x, b.y, c)
+    {}
+
+    inline _bvec4::_bvec4(const bool a, const _bvec2& b, const _bvec2& c) :
+		_cvec4<BVEC4_INST>(a, b.x, b.y, c.x)
+    {}
+
+    inline _bvec4::_bvec4(const bool a, const _bvec2& b, const _bvec3& c) :
+		_cvec4<BVEC4_INST>(a, b.x, b.y, c.x)
+    {}
+
+    inline _bvec4::_bvec4(const bool a, const _bvec2& b, const _bvec4& c) :
+		_cvec4<BVEC4_INST>(a, b.x, b.y, c.x)
+    {}
+
+    inline _bvec4::_bvec4(const bool a, const _bvec3& b) :
+		_cvec4<BVEC4_INST>(a, b.x, b.y, b.z)
+    {}
+
+    inline _bvec4::_bvec4(const bool a, const _bvec4& b) :
+		_cvec4<BVEC4_INST>(a, b.x, b.y, b.z)
+    {}
+
+    inline _bvec4::_bvec4(const _bvec2& a, const bool b, const bool c) :
+		_cvec4<BVEC4_INST>(a.x, a.y, b, c)
+    {}
+
+    inline _bvec4::_bvec4(const _bvec2& a, const bool b, const _bvec2& c) :
+		_cvec4<BVEC4_INST>(a.x, a.y, b, c.x)
+    {}
+
+    inline _bvec4::_bvec4(const _bvec2& a, const bool b, const _bvec3& c) :
+		_cvec4<BVEC4_INST>(a.x, a.y, b, c.x)
+    {}
+
+    inline _bvec4::_bvec4(const _bvec2& a, const bool b, const _bvec4& c) :
+		_cvec4<BVEC4_INST>(a.x, a.y, b, c.x)
+    {}
+
+    inline _bvec4::_bvec4(const _bvec2& a, const _bvec2& b) :
+		_cvec4<BVEC4_INST>(a.x, a.y, b.x, b.y)
+    {}
+
+    inline _bvec4::_bvec4(const _bvec2& a, const _bvec3& b) :
+		_cvec4<BVEC4_INST>(a.x, a.y, b.x, b.y)
+	{}
+
+    inline _bvec4::_bvec4(const _bvec2& a, const _bvec4& b) :
+		_cvec4<BVEC4_INST>(a.x, a.y, b.x, b.y)
+    {}
+
+    inline _bvec4::_bvec4(const _bvec3& a, const bool b) :
+		_cvec4<BVEC4_INST>(a.x, a.y, a.z, b)
+    {}
+
+    inline _bvec4::_bvec4(const _bvec3& a, const _bvec2& b) :
+		_cvec4<BVEC4_INST>(a.x, a.y, a.z, b.x)
+    {}
+
+    inline _bvec4::_bvec4(const _bvec3& a, const _bvec3& b) :
+		_cvec4<BVEC4_INST>(a.x, a.y, a.z, b.x)
+	{}
+
+    inline _bvec4::_bvec4(const _bvec3& a, const _bvec4& b) :
+        _cvec4<BVEC4_INST>(a.x, a.y, a.z, b.x)
+    {}
+
+    //////////////////////////////////////////////////////////////
+    // U constructors
+    template <typename U> 
+    inline _bvec4::_bvec4(const U a) :
+		_cvec4<BVEC4_INST>(bool(a), bool(a), bool(a), bool(a))
+    {}
+
+    template <typename U> 
+    inline _bvec4::_bvec4(const U a, const U b, const U c, const U d) :
+		_cvec4<BVEC4_INST>(bool(a), bool(b), bool(c), bool(d))
+    {}
+
+    template <typename U> 
+    inline _bvec4::_bvec4(const U a, const U b, const U c, const _xvec2<U>& d) :
+		_cvec4<BVEC4_INST>(bool(a), bool(b), bool(c), bool(d.x))
+    {}
+
+    template <typename U> 
+    inline _bvec4::_bvec4(const U a, const U b, const U c, const _xvec3<U>& d) :
+		_cvec4<BVEC4_INST>(bool(a), bool(b), bool(c), bool(d.x))
+    {}
+
+    template <typename U> 
+    inline _bvec4::_bvec4(const U a, const U b, const U c, const _xvec4<U>& d) :
+		_cvec4<BVEC4_INST>(bool(a), bool(b), bool(c), bool(d.x))
+    {}
+
+    template <typename U> 
+    inline _bvec4::_bvec4(const U a, const U b, const _xvec2<U>& c) :
+		_cvec4<BVEC4_INST>(bool(a), bool(b), bool(c.x), bool(c.y))
+    {}
+
+    template <typename U> 
+    inline _bvec4::_bvec4(const U a, const U b, const _xvec3<U>& c) :
+		_cvec4<BVEC4_INST>(bool(a), bool(b), bool(c.x), bool(c.y))
+    {}
+
+    template <typename U> 
+    inline _bvec4::_bvec4(const U a, const U b, const _xvec4<U>& c) :
+		_cvec4<BVEC4_INST>(bool(a), bool(b), bool(c.x), bool(c.y))
+	{}
+
+    template <typename U> 
+    inline _bvec4::_bvec4(const U a, const _xvec2<U>& b, const U c) :
+		_cvec4<BVEC4_INST>(bool(a), bool(b.x), bool(b.y), bool(c))
+    {}
+
+    template <typename U> 
+    inline _bvec4::_bvec4(const U a, const _xvec2<U>& b, const _xvec2<U>& c) :
+		_cvec4<BVEC4_INST>(bool(a), bool(b.x), bool(b.y), bool(c.x))
+    {}
+
+    template <typename U> 
+    inline _bvec4::_bvec4(const U a, const _xvec2<U>& b, const _xvec3<U>& c) :
+		_cvec4<BVEC4_INST>(bool(a), bool(b.x), bool(b.y), bool(c.x))
+    {}
+
+    template <typename U> 
+    inline _bvec4::_bvec4(const U a, const _xvec2<U>& b, const _xvec4<U>& c) :
+		_cvec4<BVEC4_INST>(bool(a), bool(b.x), bool(b.y), bool(c.x))
+    {}
+
+    template <typename U> 
+    inline _bvec4::_bvec4(const U a, const _xvec3<U>& b) :
+		_cvec4<BVEC4_INST>(bool(a), bool(b.x), bool(b.y), bool(b.z))
+    {}
+
+    template <typename U> 
+    inline _bvec4::_bvec4(const U a, const _xvec4<U>& b) :
+		_cvec4<BVEC4_INST>(bool(a), bool(b.x), bool(b.y), bool(b.z))
+    {}
+
+    template <typename U> 
+    inline _bvec4::_bvec4(const _xvec2<U>& a, const U b, const U c) :
+		_cvec4<BVEC4_INST>(bool(a.x), bool(a.y), bool(b), bool(c))
+    {}
+
+    template <typename U> 
+    inline _bvec4::_bvec4(const _xvec2<U>& a, const U b, const _xvec2<U>& c) :
+		_cvec4<BVEC4_INST>(bool(a.x), bool(a.y), bool(b), bool(c.x))
+	{}
+
+    template <typename U> 
+    inline _bvec4::_bvec4(const _xvec2<U>& a, const U b, const _xvec3<U>& c) :
+		_cvec4<BVEC4_INST>(bool(a.x), bool(a.y), bool(b), bool(c.x))
+    {}
+
+    template <typename U> 
+    inline _bvec4::_bvec4(const _xvec2<U>& a, const U b, const _xvec4<U>& c) :
+        _cvec4<BVEC4_INST>(bool(a.x), bool(a.y), bool(b), bool(c.x))
+    {}
+
+    template <typename U> 
+    inline _bvec4::_bvec4(const _xvec2<U>& a, const _xvec2<U>& b) :
+        _cvec4<BVEC4_INST>(bool(a.x), bool(a.y), bool(b.x), bool(b.y))
+    {}
+
+    template <typename U> 
+    inline _bvec4::_bvec4(const _xvec2<U>& a, const _xvec3<U>& b) :
+        _cvec4<BVEC4_INST>(bool(a.x), bool(a.y), bool(b.x), bool(b.y))
+    {}
+
+    template <typename U> 
+    inline _bvec4::_bvec4(const _xvec2<U>& a, const _xvec4<U>& b) :
+        _cvec4<BVEC4_INST>(bool(a.x), bool(a.y), bool(b.x), bool(b.y))
+    {}
+
+    template <typename U> 
+    inline _bvec4::_bvec4(const _xvec3<U>& a, const U b) :
+        _cvec4<BVEC4_INST>(bool(a.x), bool(a.y), bool(a.z), bool(b))
+    {}
+
+    template <typename U> 
+    inline _bvec4::_bvec4(const _xvec3<U>& a, const _xvec2<U>& b) :
+        _cvec4<BVEC4_INST>(bool(a.x), bool(a.y), bool(a.z), bool(b.x))
+    {}
+
+    template <typename U> 
+    inline _bvec4::_bvec4(const _xvec3<U>& a, const _xvec3<U>& b) :
+        _cvec4<BVEC4_INST>(bool(a.x), bool(a.y), bool(a.z), bool(b.x))
+    {}
+
+    template <typename U> 
+    inline _bvec4::_bvec4(const _xvec3<U>& a, const _xvec4<U>& b) :
+        _cvec4<BVEC4_INST>(bool(a.x), bool(a.y), bool(a.z), bool(b.x))
+    {}
+
+    template <typename U> 
+    inline _bvec4::_bvec4(const _xvec4<U>& a) :
+        _cvec4<BVEC4_INST>(bool(a.x), bool(a.y), bool(a.z), bool(a.w))
+    {}
+
+	//////////////////////////////////////////////////////////////
+    // bvec4 operators
+
+    // This function shouldn't required but it seems that VC7.1 have an optimisation bug if this operator wasn't declared
+    inline _bvec4& _bvec4::operator=(const _bvec4& v)
+    {
+        this->x = v.x;
+        this->y = v.y;
+        this->z = v.z;
+        this->w = v.w;
+        return *this;
+    }
+/*
+    inline _bvec4 _bvec4::operator--()
+    {
+	    this->x = !x;
+	    this->y = !y;
+        this->z = !z;
+        this->w = !w;
+	    return *this;
+    }
+
+    inline _bvec4 _bvec4::operator++()
+    {
+	    this->x = !x;
+	    this->y = !y;
+        this->z = !z;
+        this->w = !w;
+	    return *this;
+    }
+
+    inline const _bvec4 _bvec4::operator--(int n) const 
+    {
+		return _bvec4(
+			!this->x, 
+			!this->y, 
+			!this->z, 
+			!this->w);
+    }
+
+    inline const _bvec4 _bvec4::operator++(int n) const
+    {
+		return _bvec4(
+			!this->x, 
+			!this->y, 
+			!this->z, 
+			!this->w);
+    }
+*/
+	//inline _bvec4 _bvec4::operator!() const 
+	//{
+	//	return _bvec4(
+	//		!this->x, 
+	//		!this->y, 
+	//		!this->z, 
+	//		!this->w);
+	//}
+
+} //namespace detail
+} //namespace glm
+
+#endif//__bvec4_inl__

+ 113 - 0
experimental/sse/glm/core/_cvec2.h

@@ -0,0 +1,113 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2008 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2007-01-12
+// Updated : 2007-03-14
+// Licence : This source is under GNU LGPL licence
+// File    : glm/core/_cvec2.h
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef __glm_core_cvec2__
+#define __glm_core_cvec2__
+
+#include "_cvecx.h"
+
+namespace glm{
+namespace detail{
+
+    template <CVEC2_LIST> 
+    class _cvec2
+    {
+	public:
+		typedef T value_type;
+		typedef int size_type;
+		static const size_type value_size;
+
+        // Data
+        /* ISO C++ version unavailable with VC7.1 ...
+            union{T x, r, s;};
+            union{T y, g, t;};
+        */
+        // Solution away from ISO C++ but available with VC7.1 and GCC without -pedantic
+/*
+        union 
+        {
+            struct{T x, y;};
+            struct{T r, g;};
+            struct{T s, t;};
+        };
+*/
+#ifndef GLM_SINGLE_COMP_NAME
+#ifdef GLM_COMPILER_GCC
+        union {T x, r, s;};
+        union {T y, g, t;};
+#endif//GLM_COMPILER_GCC
+
+#ifdef GLM_COMPILER_VC
+        union 
+        {
+            struct{T x, y;};
+            struct{T r, g;};
+            struct{T s, t;};
+        };
+#endif//GLM_COMPILER_VC
+
+#else
+        T x, y;
+#endif//GLM_SINGLE_COMP_NAME
+
+		// Conclassor
+		_cvec2(){}
+		_cvec2(const T x, const T y);
+
+        // Accesses
+        T& operator[](size_type i);
+        const T operator[](size_type i) const;
+        operator T*();
+	    operator const T*() const;
+
+#if defined(GLM_SWIZZLE)
+        // Left hand side 2 components common swizzle operators
+        REF2 _xy();
+        REF2 _yx();
+
+        // Right hand side 2 components common swizzle operators
+        const VEC2 _xx() const;
+        const VEC2 _yx() const;
+        VEC2 _xy() const;
+        const VEC2 _yy() const;
+
+        // Right hand side 3 components common swizzle operators
+        const VEC3 _xxx() const;
+        const VEC3 _yxx() const;
+        const VEC3 _xyx() const;
+        const VEC3 _yyx() const;
+        const VEC3 _xxy() const;
+        const VEC3 _yxy() const;
+        const VEC3 _xyy() const;
+        const VEC3 _yyy() const;
+
+        // Right hand side 4 components common swizzle operators
+        const VEC4 _xxxx() const;
+        const VEC4 _yxxx() const;
+        const VEC4 _xyxx() const;
+        const VEC4 _yyxx() const;
+        const VEC4 _xxyx() const;
+        const VEC4 _yxyx() const;
+        const VEC4 _xyyx() const;
+        const VEC4 _yyyx() const;
+        const VEC4 _xxxy() const;
+        const VEC4 _yxxy() const;
+        const VEC4 _xyxy() const;
+        const VEC4 _yyxy() const;
+        const VEC4 _xxyy() const;
+        const VEC4 _yxyy() const;
+        const VEC4 _xyyy() const;
+        const VEC4 _yyyy() const;
+#endif// defined(GLM_SWIZZLE)
+    };
+
+} //namespace detail
+} //namespace glm
+
+#endif //__glm_core_cvec2__

+ 253 - 0
experimental/sse/glm/core/_cvec2.inl

@@ -0,0 +1,253 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2008 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2007-01-15
+// Updated : 2007-01-15
+// Licence : This source is under GNU LGPL licence
+// File    : _cvec2.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef __cvec2_inl__
+#define __cvec2_inl__
+
+#include "_cvec2.h"
+
+namespace glm{
+namespace detail{
+
+	template <CVEC2_LIST>
+	const int _cvec2<CVEC2_TYPE>::value_size = 2;
+
+    //////////////////////////////////////////////////////////////
+    // _cvec2 constructor
+
+	template <CVEC2_LIST>  
+	inline _cvec2<CVEC2_TYPE>::_cvec2(const T x, const T y) :
+		x(x), y(y)
+	{}
+
+    //////////////////////////////////////////////////////////////
+    // vec2 and ivec2 accesses
+
+    template <CVEC2_LIST>  
+    inline T& _cvec2<CVEC2_TYPE>::operator [] (int i)
+    {
+        return (&x)[i];
+    }
+
+    template <CVEC2_LIST>  
+    inline const T _cvec2<CVEC2_TYPE>::operator [] (int i) const
+    {
+        return (&x)[i];
+    }
+
+    template <CVEC2_LIST>  
+    inline _cvec2<CVEC2_TYPE>::operator T* ()
+    {
+        return &x;
+    }
+
+    template <CVEC2_LIST>  
+    inline _cvec2<CVEC2_TYPE>::operator const T* () const 
+    {
+        return &x;
+    }
+
+#if defined(GLM_SWIZZLE)
+    //////////////////////////////////////////////////////////////
+    // Left hand side 2 components common swizzle operator
+
+    template <CVEC2_LIST>  
+    inline REF2 _cvec2<CVEC2_TYPE>::_xy()
+    {
+        return REF2(this->x, this->y);
+    }
+
+    template <CVEC2_LIST>  
+    inline REF2 _cvec2<CVEC2_TYPE>::_yx()
+    {
+        return REF2(this->y, this->x);
+    }
+
+    //////////////////////////////////////////////////////////////
+    // Right hand side 2 components common swizzle operators
+
+    template <CVEC2_LIST>  
+    inline const VEC2 _cvec2<CVEC2_TYPE>::_xx() const
+    {
+        return VEC2(this->x, this->x);
+    }
+
+    template <CVEC2_LIST>  
+    inline const VEC2 _cvec2<CVEC2_TYPE>::_yx() const
+    {
+        return VEC2(this->y, this->x);
+    }
+
+    template <CVEC2_LIST>  
+    inline VEC2 _cvec2<CVEC2_TYPE>::_xy() const
+    {
+        return VEC2(this->x, this->y);
+    }
+
+    template <CVEC2_LIST>  
+    inline const VEC2 _cvec2<CVEC2_TYPE>::_yy() const
+    {
+        return VEC2(this->y, this->y);
+    }
+
+    //////////////////////////////////////////////////////////////
+    // Right hand side 3 components common swizzle operators
+
+    template <CVEC2_LIST>  
+    inline const VEC3 _cvec2<CVEC2_TYPE>::_xxx() const
+    {
+        return VEC3(this->x, this->x, this->x);
+    }
+
+    template <CVEC2_LIST>  
+    inline const VEC3 _cvec2<CVEC2_TYPE>::_yxx() const
+    {
+        return VEC3(this->y, this->x, this->x);
+    }
+
+    template <CVEC2_LIST>  
+    inline const VEC3 _cvec2<CVEC2_TYPE>::_xyx() const
+    {
+        return VEC3(this->x, this->y, this->x);
+    }
+
+    template <CVEC2_LIST>  
+    inline const VEC3 _cvec2<CVEC2_TYPE>::_yyx() const
+    {
+        return VEC3(this->y, this->y, this->x);
+    }
+
+    template <CVEC2_LIST>  
+    inline const VEC3 _cvec2<CVEC2_TYPE>::_xxy() const
+    {
+        return VEC3(this->x, this->x, this->y);
+    }
+
+    template <CVEC2_LIST>  
+    inline const VEC3 _cvec2<CVEC2_TYPE>::_yxy() const
+    {
+        return VEC3(this->y, this->x, this->y);
+    }
+
+    template <CVEC2_LIST>  
+    inline const VEC3 _cvec2<CVEC2_TYPE>::_xyy() const
+    {
+        return VEC3(this->x, this->y, this->y);
+    }
+
+    template <CVEC2_LIST>  
+    inline const VEC3 _cvec2<CVEC2_TYPE>::_yyy() const
+    {
+        return VEC3(this->y, this->y, this->y);
+    }
+
+    //////////////////////////////////////////////////////////////
+    // Right hand side 4 components common swizzle operators
+
+    template <CVEC2_LIST>  
+    inline const VEC4 _cvec2<CVEC2_TYPE>::_xxxx() const
+    {
+        return VEC4(this->x, this->x, this->x, this->x);
+    }
+
+    template <CVEC2_LIST>  
+    inline const VEC4 _cvec2<CVEC2_TYPE>::_yxxx() const
+    {
+        return VEC4(this->y, this->x, this->x, this->x);
+    }
+
+    template <CVEC2_LIST>  
+    inline const VEC4 _cvec2<CVEC2_TYPE>::_xyxx() const
+    {
+        return VEC4(this->x, this->y, this->x, this->x);
+    }
+
+    template <CVEC2_LIST>  
+    inline const VEC4 _cvec2<CVEC2_TYPE>::_yyxx() const
+    {
+        return VEC4(this->y, this->y, this->x, this->x);
+    }
+
+    template <CVEC2_LIST>  
+    inline const VEC4 _cvec2<CVEC2_TYPE>::_xxyx() const
+    {
+        return VEC4(this->x, this->x, this->y, this->x);
+    }
+
+    template <CVEC2_LIST>  
+    inline const VEC4 _cvec2<CVEC2_TYPE>::_yxyx() const
+    {
+        return VEC4(this->y, this->x, this->y, this->x);
+    }
+
+    template <CVEC2_LIST>  
+    inline const VEC4 _cvec2<CVEC2_TYPE>::_xyyx() const
+    {
+        return VEC4(this->x, this->y, this->y, this->x);
+    }
+
+    template <CVEC2_LIST>  
+    inline const VEC4 _cvec2<CVEC2_TYPE>::_yyyx() const
+    {
+        return VEC4(this->y, this->y, this->y, this->x);
+    }
+
+    template <CVEC2_LIST>  
+    inline const VEC4 _cvec2<CVEC2_TYPE>::_xxxy() const
+    {
+        return VEC4(this->x, this->x, this->x, this->y);
+    }
+
+    template <CVEC2_LIST>  
+    inline const VEC4 _cvec2<CVEC2_TYPE>::_yxxy() const
+    {
+        return VEC4(this->y, this->x, this->x, this->y);
+    }
+
+    template <CVEC2_LIST>  
+    inline const VEC4 _cvec2<CVEC2_TYPE>::_xyxy() const
+    {
+        return VEC4(this->x, this->y, this->x, this->y);
+    }
+
+    template <CVEC2_LIST>  
+    inline const VEC4 _cvec2<CVEC2_TYPE>::_yyxy() const
+    {
+        return VEC4(this->y, this->y, this->x, this->y);
+    }
+
+    template <CVEC2_LIST>  
+    inline const VEC4 _cvec2<CVEC2_TYPE>::_xxyy() const
+    {
+        return VEC4(this->x, this->x, this->y, this->y);
+    }
+
+    template <CVEC2_LIST>  
+    inline const VEC4 _cvec2<CVEC2_TYPE>::_yxyy() const
+    {
+        return VEC4(this->y, this->x, this->y, this->y);
+    }
+
+    template <CVEC2_LIST>  
+    inline const VEC4 _cvec2<CVEC2_TYPE>::_xyyy() const
+    {
+        return VEC4(this->x, this->y, this->y, this->y);
+    }
+
+    template <CVEC2_LIST>  
+    inline const VEC4 _cvec2<CVEC2_TYPE>::_yyyy() const
+    {
+        return VEC4(this->y, this->y, this->y, this->y);
+    }
+#endif //defined(GLM_SWIZZLE)
+
+} //namespace detail
+} //namespace glm
+
+#endif //__cvec2_inl__

+ 217 - 0
experimental/sse/glm/core/_cvec3.h

@@ -0,0 +1,217 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2008 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2007-01-15
+// Updated : 2007-03-14
+// Licence : This source is under GNU LGPL licence
+// File    : glm/core/_cvec3.h
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef __glm_core_cvec3__
+#define __glm_core_cvec3__
+
+#include "_cvecx.h"
+
+namespace glm{
+namespace detail{
+
+    template <CVEC3_LIST> 
+    class _cvec3
+    {
+	public:
+		typedef T value_type;
+		typedef int size_type;
+		static const size_type value_size;
+
+        // Data
+        /* ISO C++ version unavailable with VC7.1 ...
+            union{T x, r, s;};
+            union{T y, g, t;};
+            union{T z, b, p;};
+        */
+        // Solution away from ISO C++ but available with VC7.1 and GCC without -pedantic
+/*
+        union 
+        {
+            struct{T x, y, z;};
+            struct{T r, g, b;};
+            struct{T s, t, p;};
+        };
+*/
+
+#ifndef GLM_SINGLE_COMP_NAME
+#ifdef GLM_COMPILER_GCC
+        union{T x, r, s;};
+        union{T y, g, t;};
+        union{T z, b, p;};
+#endif//GLM_COMPILER_GCC
+
+#ifdef GLM_COMPILER_VC
+        union 
+        {
+            struct{T x, y, z;};
+            struct{T r, g, b;};
+            struct{T s, t, p;};
+        };
+#endif//GLM_COMPILER_VC
+
+#else
+        T x, y, z;
+#endif//GLM_SINGLE_COMP_NAME
+
+		// Constructor
+		_cvec3(){}
+		_cvec3(const T x, const T y, const T z);
+
+        // Accesses
+        T& operator [] (size_type i);
+        const T operator [] (size_type i) const;
+        operator T* ();
+	    operator const T* () const;
+
+#if defined(GLM_SWIZZLE)
+        // Left hand side 2 components common swizzle operators
+        REF2 _yx();
+        REF2 _zx();
+        REF2 _xy();
+        REF2 _zy();
+        REF2 _xz();
+        REF2 _yz();
+
+        // Right hand side 2 components common swizzle operators
+        const VEC2 _xx() const;
+        const VEC2 _yx() const;
+        const VEC2 _zx() const;
+        const VEC2 _xy() const;
+        const VEC2 _yy() const;
+        const VEC2 _zy() const;
+        const VEC2 _xz() const;
+        const VEC2 _yz() const;
+        const VEC2 _zz() const;
+
+        // Left hand side 3 components common swizzle operators
+        REF3 _zyx();
+        REF3 _yzx();
+        REF3 _zxy();
+        REF3 _xzy();
+        REF3 _yxz();
+        REF3 _xyz();
+
+        // Right hand side 3 components common swizzle operators
+        const VEC3 _xxx() const;
+        const VEC3 _yxx() const;
+        const VEC3 _zxx() const;
+        const VEC3 _xyx() const;
+        const VEC3 _yyx() const;
+        const VEC3 _zyx() const;
+        const VEC3 _xzx() const;
+        const VEC3 _yzx() const;
+        const VEC3 _zzx() const;
+        const VEC3 _xxy() const;
+        const VEC3 _yxy() const;
+        const VEC3 _zxy() const;
+        const VEC3 _xyy() const;
+        const VEC3 _yyy() const;
+        const VEC3 _zyy() const;
+        const VEC3 _xzy() const;
+        const VEC3 _yzy() const;
+        const VEC3 _zzy() const;
+        const VEC3 _xxz() const;
+        const VEC3 _yxz() const;
+        const VEC3 _zxz() const;
+        const VEC3 _xyz() const;
+        const VEC3 _yyz() const;
+        const VEC3 _zyz() const;
+        const VEC3 _xzz() const;
+        const VEC3 _yzz() const;
+        const VEC3 _zzz() const;
+
+        // 4 components common swizzle operators
+        const VEC4 _xxxx() const;
+        const VEC4 _yxxx() const;
+        const VEC4 _zxxx() const;
+        const VEC4 _xyxx() const;
+        const VEC4 _yyxx() const;
+        const VEC4 _zyxx() const;
+        const VEC4 _xzxx() const;
+        const VEC4 _yzxx() const;
+        const VEC4 _zzxx() const;
+        const VEC4 _xxyx() const;
+        const VEC4 _yxyx() const;
+        const VEC4 _zxyx() const;
+        const VEC4 _xyyx() const;
+        const VEC4 _yyyx() const;
+        const VEC4 _zyyx() const;
+        const VEC4 _xzyx() const;
+        const VEC4 _yzyx() const;
+        const VEC4 _zzyx() const;
+        const VEC4 _xxzx() const;
+        const VEC4 _yxzx() const;
+        const VEC4 _zxzx() const;
+        const VEC4 _xyzx() const;
+        const VEC4 _yyzx() const;
+        const VEC4 _zyzx() const;
+        const VEC4 _xzzx() const;
+        const VEC4 _yzzx() const;
+        const VEC4 _zzzx() const;
+        const VEC4 _xxxy() const;
+        const VEC4 _yxxy() const;
+        const VEC4 _zxxy() const;
+        const VEC4 _xyxy() const;
+        const VEC4 _yyxy() const;
+        const VEC4 _zyxy() const;
+        const VEC4 _xzxy() const;
+        const VEC4 _yzxy() const;
+        const VEC4 _zzxy() const;
+        const VEC4 _xxyy() const;
+        const VEC4 _yxyy() const;
+        const VEC4 _zxyy() const;
+        const VEC4 _xyyy() const;
+        const VEC4 _yyyy() const;
+        const VEC4 _zyyy() const;
+        const VEC4 _xzyy() const;
+        const VEC4 _yzyy() const;
+        const VEC4 _zzyy() const;
+        const VEC4 _xxzy() const;
+        const VEC4 _yxzy() const;
+        const VEC4 _zxzy() const;
+        const VEC4 _xyzy() const;
+        const VEC4 _yyzy() const;
+        const VEC4 _zyzy() const;
+        const VEC4 _xzzy() const;
+        const VEC4 _yzzy() const;
+        const VEC4 _zzzy() const;
+        const VEC4 _xxxz() const;
+        const VEC4 _yxxz() const;
+        const VEC4 _zxxz() const;
+        const VEC4 _xyxz() const;
+        const VEC4 _yyxz() const;
+        const VEC4 _zyxz() const;
+        const VEC4 _xzxz() const;
+        const VEC4 _yzxz() const;
+        const VEC4 _zzxz() const;
+        const VEC4 _xxyz() const;
+        const VEC4 _yxyz() const;
+        const VEC4 _zxyz() const;
+        const VEC4 _xyyz() const;
+        const VEC4 _yyyz() const;
+        const VEC4 _zyyz() const;
+        const VEC4 _xzyz() const;
+        const VEC4 _yzyz() const;
+        const VEC4 _zzyz() const;
+        const VEC4 _xxzz() const;
+        const VEC4 _yxzz() const;
+        const VEC4 _zxzz() const;
+        const VEC4 _xyzz() const;
+        const VEC4 _yyzz() const;
+        const VEC4 _zyzz() const;
+        const VEC4 _xzzz() const;
+        const VEC4 _yzzz() const;
+        const VEC4 _zzzz() const;
+#endif// defined(GLM_SWIZZLE)
+	};
+
+} //namespace detail
+} //namespace glm
+
+#endif//__cvec3_h__

+ 849 - 0
experimental/sse/glm/core/_cvec3.inl

@@ -0,0 +1,849 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2008 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2007-01-15
+// Updated : 2007-01-15
+// Licence : This source is under GNU LGPL licence
+// File    : _cvec3.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef __cvec3_inl__
+#define __cvec3_inl__
+
+#include "_cvec3.h"
+
+namespace glm{
+namespace detail{
+
+	template <CVEC3_LIST>
+	const int _cvec3<CVEC3_TYPE>::value_size = 3;
+
+    //////////////////////////////////////////////////////////////
+    // _cvec3 constructor
+
+	template <CVEC3_LIST>  
+	inline _cvec3<CVEC3_TYPE>::_cvec3(const T x, const T y, const T z) :
+		x(x), y(y), z(z)
+	{}
+
+    //////////////////////////////////////////////////////////////
+    // vec3 and ivec3 accesses
+
+    template <CVEC3_LIST>  
+    inline T& _cvec3<CVEC3_TYPE>::operator [] (int i)
+    {
+        return (&x)[i];
+    }
+
+    template <CVEC3_LIST>  
+    inline const T _cvec3<CVEC3_TYPE>::operator [] (int i) const
+    {
+        return (&x)[i];
+    }
+
+    template <CVEC3_LIST>  
+    inline _cvec3<CVEC3_TYPE>::operator T* ()
+    {
+        return &x;
+    }
+
+    template <CVEC3_LIST>  
+    inline _cvec3<CVEC3_TYPE>::operator const T* () const 
+    {
+        return &x;
+    }
+
+#if defined(GLM_SWIZZLE)
+    //////////////////////////////////////////////////////////////
+	// Left hand side 2 components common swizzle operators
+
+    template <CVEC3_LIST> 
+	inline REF2 _cvec3<CVEC3_TYPE>::_yx()
+	{
+		return REF2(this->y, this->x);
+	}
+
+    template <CVEC3_LIST> 
+	inline REF2 _cvec3<CVEC3_TYPE>::_zx()
+	{
+		return REF2(this->z, this->x);
+	}
+
+    template <CVEC3_LIST> 
+	inline REF2 _cvec3<CVEC3_TYPE>::_xy()
+	{
+		return REF2(this->x, this->y);
+	}
+
+    template <CVEC3_LIST> 
+	inline REF2 _cvec3<CVEC3_TYPE>::_zy()
+	{
+		return REF2(this->x, this->y);
+	}
+
+    template <CVEC3_LIST> 
+	inline REF2 _cvec3<CVEC3_TYPE>::_xz()
+	{
+		return REF2(this->x, this->z);
+	}
+
+    template <CVEC3_LIST> 
+	inline REF2 _cvec3<CVEC3_TYPE>::_yz()
+	{
+		return REF2(this->y, this->z);
+	}
+
+    //////////////////////////////////////////////////////////////
+    // Right hand side 2 components swizzles operators
+
+    template <CVEC3_LIST> 
+    inline const VEC2 _cvec3<CVEC3_TYPE>::_xx() const
+    {
+        return VEC2(this->x, this->x);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC2 _cvec3<CVEC3_TYPE>::_yx() const
+    {
+        return VEC2(this->y, this->x);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC2 _cvec3<CVEC3_TYPE>::_zx() const
+    {
+        return VEC2(this->z, this->x);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC2 _cvec3<CVEC3_TYPE>::_xy() const
+    {
+        return VEC2(this->x, this->y);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC2 _cvec3<CVEC3_TYPE>::_yy() const
+    {
+        return VEC2(this->y, this->y);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC2 _cvec3<CVEC3_TYPE>::_zy() const
+    {
+        return VEC2(this->z, this->y);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC2 _cvec3<CVEC3_TYPE>::_xz() const
+    {
+        return VEC2(this->x, this->z);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC2 _cvec3<CVEC3_TYPE>::_yz() const
+    {
+        return VEC2(this->y, this->z);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC2 _cvec3<CVEC3_TYPE>::_zz() const
+    {
+        return VEC2(this->z, this->z);
+    }
+
+    //////////////////////////////////////////////////////////////
+    // Left hand side 3 components common swizzle operator
+
+    template <CVEC3_LIST> 
+    inline REF3 _cvec3<CVEC3_TYPE>::_zyx()
+    {
+        return REF3(this->z, this->y, this->x);
+    }
+
+    template <CVEC3_LIST> 
+    inline REF3 _cvec3<CVEC3_TYPE>::_yzx()
+    {
+        return REF3(this->y, this->z, this->x);
+    }
+
+    template <CVEC3_LIST> 
+    inline REF3 _cvec3<CVEC3_TYPE>::_zxy()
+    {
+        return REF3(this->z, this->x, this->y);
+    }
+
+    template <CVEC3_LIST> 
+    inline REF3 _cvec3<CVEC3_TYPE>::_xzy()
+    {
+        return REF3(this->x, this->z, this->y);
+    }
+
+    template <CVEC3_LIST> 
+    inline REF3 _cvec3<CVEC3_TYPE>::_yxz()
+    {
+        return REF3(this->y, this->x, this->z);
+    }
+
+    template <CVEC3_LIST> 
+    inline REF3 _cvec3<CVEC3_TYPE>::_xyz()
+    {
+        return REF3(this->x, this->y, this->z);
+    }
+
+    //////////////////////////////////////////////////////////////
+    // Right hand side 3 components common swizzle operators
+
+    template <CVEC3_LIST> 
+    inline const VEC3 _cvec3<CVEC3_TYPE>::_xxx() const
+    {
+        return _cvec3<CVEC3_TYPE>(this->x, this->x, this->x);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC3 _cvec3<CVEC3_TYPE>::_yxx() const
+    {
+        return _cvec3<CVEC3_TYPE>(this->y, this->x, this->x);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC3 _cvec3<CVEC3_TYPE>::_zxx() const
+    {
+        return _cvec3<CVEC3_TYPE>(this->z, this->x, this->x);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC3 _cvec3<CVEC3_TYPE>::_xyx() const
+    {
+        return _cvec3<CVEC3_TYPE>(this->x, this->y, this->x);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC3 _cvec3<CVEC3_TYPE>::_yyx() const
+    {
+        return _cvec3<CVEC3_TYPE>(this->y, this->y, this->x);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC3 _cvec3<CVEC3_TYPE>::_zyx() const
+    {
+        return _cvec3<CVEC3_TYPE>(this->z, this->y, this->x);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC3 _cvec3<CVEC3_TYPE>::_xzx() const
+    {
+        return _cvec3<CVEC3_TYPE>(this->x, this->z, this->x);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC3 _cvec3<CVEC3_TYPE>::_yzx() const
+    {
+        return _cvec3<CVEC3_TYPE>(this->y, this->z, this->x);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC3 _cvec3<CVEC3_TYPE>::_zzx() const
+    {
+        return _cvec3<CVEC3_TYPE>(this->z, this->z, this->x);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC3 _cvec3<CVEC3_TYPE>::_xxy() const
+    {
+        return _cvec3<CVEC3_TYPE>(this->x, this->x, this->y);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC3 _cvec3<CVEC3_TYPE>::_yxy() const
+    {
+        return _cvec3<CVEC3_TYPE>(this->y, this->x, this->y);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC3 _cvec3<CVEC3_TYPE>::_zxy() const
+    {
+        return _cvec3<CVEC3_TYPE>(this->z, this->x, this->y);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC3 _cvec3<CVEC3_TYPE>::_xyy() const
+    {
+        return _cvec3<CVEC3_TYPE>(this->x, this->y, this->y);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC3 _cvec3<CVEC3_TYPE>::_yyy() const
+    {
+        return _cvec3<CVEC3_TYPE>(this->y, this->y, this->y);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC3 _cvec3<CVEC3_TYPE>::_zyy() const
+    {
+        return _cvec3<CVEC3_TYPE>(this->z, this->y, this->y);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC3 _cvec3<CVEC3_TYPE>::_xzy() const
+    {
+        return _cvec3<CVEC3_TYPE>(this->x, this->z, this->y);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC3 _cvec3<CVEC3_TYPE>::_yzy() const
+    {
+        return _cvec3<CVEC3_TYPE>(this->y, this->z, this->y);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC3 _cvec3<CVEC3_TYPE>::_zzy() const
+    {
+        return _cvec3<CVEC3_TYPE>(this->z, this->z, this->y);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC3 _cvec3<CVEC3_TYPE>::_xxz() const
+    {
+        return _cvec3<CVEC3_TYPE>(this->x, this->x, this->z);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC3 _cvec3<CVEC3_TYPE>::_yxz() const
+    {
+        return _cvec3<CVEC3_TYPE>(this->y, this->x, this->z);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC3 _cvec3<CVEC3_TYPE>::_zxz() const
+    {
+        return _cvec3<CVEC3_TYPE>(this->z, this->x, this->z);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC3 _cvec3<CVEC3_TYPE>::_xyz() const
+    {
+        return _cvec3<CVEC3_TYPE>(this->x, this->y, this->z);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC3 _cvec3<CVEC3_TYPE>::_yyz() const
+    {
+        return _cvec3<CVEC3_TYPE>(this->y, this->y, this->z);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC3 _cvec3<CVEC3_TYPE>::_zyz() const
+    {
+        return _cvec3<CVEC3_TYPE>(this->z, this->y, this->z);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC3 _cvec3<CVEC3_TYPE>::_xzz() const
+    {
+        return _cvec3<CVEC3_TYPE>(this->x, this->z, this->z);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC3 _cvec3<CVEC3_TYPE>::_yzz() const
+    {
+        return _cvec3<CVEC3_TYPE>(this->y, this->z, this->z);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC3 _cvec3<CVEC3_TYPE>::_zzz() const
+    {
+        return _cvec3<CVEC3_TYPE>(this->z, this->z, this->z);
+    }
+
+    // Right hand side4 components swizzles operators
+    template <CVEC3_LIST> 
+    inline const VEC4 _cvec3<CVEC3_TYPE>::_xxxx() const
+    {
+        return VEC4(this->x, this->x, this->x, this->x);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC4 _cvec3<CVEC3_TYPE>::_yxxx() const
+    {
+        return VEC4(this->y, this->x, this->x, this->x);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC4 _cvec3<CVEC3_TYPE>::_zxxx() const
+    {
+        return VEC4(this->z, this->x, this->x, this->x);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC4 _cvec3<CVEC3_TYPE>::_xyxx() const
+    {
+        return VEC4(this->x, this->y, this->x, this->x);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC4 _cvec3<CVEC3_TYPE>::_yyxx() const
+    {
+        return VEC4(this->y, this->y, this->x, this->x);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC4 _cvec3<CVEC3_TYPE>::_zyxx() const
+    {
+        return VEC4(this->z, this->y, this->x, this->x);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC4 _cvec3<CVEC3_TYPE>::_xzxx() const
+    {
+        return VEC4(this->x, this->z, this->x, this->x);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC4 _cvec3<CVEC3_TYPE>::_yzxx() const
+    {
+        return VEC4(this->y, this->z, this->x, this->x);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC4 _cvec3<CVEC3_TYPE>::_zzxx() const
+    {
+        return VEC4(this->z, this->z, this->x, this->x);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC4 _cvec3<CVEC3_TYPE>::_xxyx() const
+    {
+        return VEC4(this->x, this->x, this->y, this->x);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC4 _cvec3<CVEC3_TYPE>::_yxyx() const
+    {
+        return VEC4(this->y, this->x, this->y, this->x);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC4 _cvec3<CVEC3_TYPE>::_zxyx() const
+    {
+        return VEC4(this->z, this->x, this->y, this->x);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC4 _cvec3<CVEC3_TYPE>::_xyyx() const
+    {
+        return VEC4(this->x, this->y, this->y, this->x);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC4 _cvec3<CVEC3_TYPE>::_yyyx() const
+    {
+        return VEC4(this->y, this->y, this->y, this->x);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC4 _cvec3<CVEC3_TYPE>::_zyyx() const
+    {
+        return VEC4(this->z, this->y, this->y, this->x);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC4 _cvec3<CVEC3_TYPE>::_xzyx() const
+    {
+        return VEC4(this->x, this->z, this->y, this->x);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC4 _cvec3<CVEC3_TYPE>::_yzyx() const
+    {
+        return VEC4(this->y, this->z, this->y, this->x);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC4 _cvec3<CVEC3_TYPE>::_zzyx() const
+    {
+        return VEC4(this->z, this->z, this->y, this->x);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC4 _cvec3<CVEC3_TYPE>::_xxzx() const
+    {
+        return VEC4(this->x, this->x, this->z, this->x);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC4 _cvec3<CVEC3_TYPE>::_yxzx() const
+    {
+        return VEC4(this->y, this->x, this->z, this->x);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC4 _cvec3<CVEC3_TYPE>::_zxzx() const
+    {
+        return VEC4(this->z, this->x, this->z, this->x);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC4 _cvec3<CVEC3_TYPE>::_xyzx() const
+    {
+        return VEC4(this->x, this->y, this->z, this->x);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC4 _cvec3<CVEC3_TYPE>::_yyzx() const
+    {
+        return VEC4(this->y, this->y, this->z, this->x);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC4 _cvec3<CVEC3_TYPE>::_zyzx() const
+    {
+        return VEC4(this->z, this->y, this->z, this->x);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC4 _cvec3<CVEC3_TYPE>::_xzzx() const
+    {
+        return VEC4(this->x, this->z, this->z, this->x);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC4 _cvec3<CVEC3_TYPE>::_yzzx() const
+    {
+        return VEC4(this->y, this->z, this->z, this->x);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC4 _cvec3<CVEC3_TYPE>::_zzzx() const
+    {
+        return VEC4(this->z, this->z, this->z, this->x);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC4 _cvec3<CVEC3_TYPE>::_xxxy() const
+    {
+        return VEC4(this->x, this->x, this->x, this->y);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC4 _cvec3<CVEC3_TYPE>::_yxxy() const
+    {
+        return VEC4(this->y, this->x, this->x, this->y);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC4 _cvec3<CVEC3_TYPE>::_zxxy() const
+    {
+        return VEC4(this->z, this->x, this->x, this->y);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC4 _cvec3<CVEC3_TYPE>::_xyxy() const
+    {
+        return VEC4(this->x, this->y, this->x, this->y);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC4 _cvec3<CVEC3_TYPE>::_yyxy() const
+    {
+        return VEC4(this->y, this->y, this->x, this->y);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC4 _cvec3<CVEC3_TYPE>::_zyxy() const
+    {
+        return VEC4(this->z, this->y, this->x, this->y);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC4 _cvec3<CVEC3_TYPE>::_xzxy() const
+    {
+        return VEC4(this->x, this->z, this->x, this->y);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC4 _cvec3<CVEC3_TYPE>::_yzxy() const
+    {
+        return VEC4(this->y, this->z, this->x, this->y);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC4 _cvec3<CVEC3_TYPE>::_zzxy() const
+    {
+        return VEC4(this->z, this->z, this->x, this->y);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC4 _cvec3<CVEC3_TYPE>::_xxyy() const
+    {
+        return VEC4(this->x, this->x, this->y, this->y);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC4 _cvec3<CVEC3_TYPE>::_yxyy() const
+    {
+        return VEC4(this->y, this->x, this->y, this->y);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC4 _cvec3<CVEC3_TYPE>::_zxyy() const
+    {
+        return VEC4(this->z, this->x, this->y, this->y);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC4 _cvec3<CVEC3_TYPE>::_xyyy() const
+    {
+        return VEC4(this->x, this->y, this->y, this->y);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC4 _cvec3<CVEC3_TYPE>::_yyyy() const
+    {
+        return VEC4(this->y, this->y, this->y, this->y);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC4 _cvec3<CVEC3_TYPE>::_zyyy() const
+    {
+        return VEC4(this->z, this->y, this->y, this->y);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC4 _cvec3<CVEC3_TYPE>::_xzyy() const
+    {
+        return VEC4(this->x, this->z, this->y, this->y);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC4 _cvec3<CVEC3_TYPE>::_yzyy() const
+    {
+        return VEC4(this->y, this->z, this->y, this->y);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC4 _cvec3<CVEC3_TYPE>::_zzyy() const
+    {
+        return VEC4(this->z, this->z, this->y, this->y);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC4 _cvec3<CVEC3_TYPE>::_xxzy() const
+    {
+        return VEC4(this->x, this->x, this->z, this->y);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC4 _cvec3<CVEC3_TYPE>::_yxzy() const
+    {
+        return VEC4(this->y, this->x, this->z, this->y);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC4 _cvec3<CVEC3_TYPE>::_zxzy() const
+    {
+        return VEC4(this->z, this->x, this->z, this->y);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC4 _cvec3<CVEC3_TYPE>::_xyzy() const
+    {
+        return VEC4(this->x, this->y, this->z, this->y);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC4 _cvec3<CVEC3_TYPE>::_yyzy() const
+    {
+        return VEC4(this->y, this->y, this->z, this->y);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC4 _cvec3<CVEC3_TYPE>::_zyzy() const
+    {
+        return VEC4(this->z, this->y, this->z, this->y);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC4 _cvec3<CVEC3_TYPE>::_xzzy() const
+    {
+        return VEC4(this->x, this->z, this->z, this->y);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC4 _cvec3<CVEC3_TYPE>::_yzzy() const
+    {
+        return VEC4(this->y, this->z, this->z, this->y);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC4 _cvec3<CVEC3_TYPE>::_zzzy() const
+    {
+        return VEC4(this->z, this->z, this->z, this->y);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC4 _cvec3<CVEC3_TYPE>::_xxxz() const
+    {
+        return VEC4(this->x, this->x, this->x, this->z);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC4 _cvec3<CVEC3_TYPE>::_yxxz() const
+    {
+        return VEC4(this->y, this->x, this->x, this->z);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC4 _cvec3<CVEC3_TYPE>::_zxxz() const
+    {
+        return VEC4(this->z, this->x, this->x, this->z);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC4 _cvec3<CVEC3_TYPE>::_xyxz() const
+    {
+        return VEC4(this->x, this->y, this->x, this->z);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC4 _cvec3<CVEC3_TYPE>::_yyxz() const
+    {
+        return VEC4(this->y, this->y, this->x, this->z);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC4 _cvec3<CVEC3_TYPE>::_zyxz() const
+    {
+        return VEC4(this->z, this->y, this->x, this->z);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC4 _cvec3<CVEC3_TYPE>::_xzxz() const
+    {
+        return VEC4(this->x, this->z, this->x, this->z);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC4 _cvec3<CVEC3_TYPE>::_yzxz() const
+    {
+        return VEC4(this->y, this->z, this->x, this->z);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC4 _cvec3<CVEC3_TYPE>::_zzxz() const
+    {
+        return VEC4(this->z, this->z, this->x, this->z);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC4 _cvec3<CVEC3_TYPE>::_xxyz() const
+    {
+        return VEC4(this->x, this->x, this->y, this->z);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC4 _cvec3<CVEC3_TYPE>::_yxyz() const
+    {
+        return VEC4(this->y, this->x, this->y, this->z);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC4 _cvec3<CVEC3_TYPE>::_zxyz() const
+    {
+        return VEC4(this->z, this->x, this->y, this->z);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC4 _cvec3<CVEC3_TYPE>::_xyyz() const
+    {
+        return VEC4(this->x, this->y, this->y, this->z);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC4 _cvec3<CVEC3_TYPE>::_yyyz() const
+    {
+        return VEC4(this->y, this->y, this->y, this->z);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC4 _cvec3<CVEC3_TYPE>::_zyyz() const
+    {
+        return VEC4(this->z, this->y, this->y, this->z);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC4 _cvec3<CVEC3_TYPE>::_xzyz() const
+    {
+        return VEC4(this->x, this->z, this->y, this->z);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC4 _cvec3<CVEC3_TYPE>::_yzyz() const
+    {
+        return VEC4(this->y, this->z, this->y, this->z);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC4 _cvec3<CVEC3_TYPE>::_zzyz() const
+    {
+        return VEC4(this->z, this->z, this->y, this->z);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC4 _cvec3<CVEC3_TYPE>::_xxzz() const
+    {
+        return VEC4(this->x, this->x, this->z, this->z);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC4 _cvec3<CVEC3_TYPE>::_yxzz() const
+    {
+        return VEC4(this->y, this->x, this->z, this->z);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC4 _cvec3<CVEC3_TYPE>::_zxzz() const
+    {
+        return VEC4(this->z, this->x, this->z, this->z);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC4 _cvec3<CVEC3_TYPE>::_xyzz() const
+    {
+        return VEC4(this->x, this->y, this->z, this->z);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC4 _cvec3<CVEC3_TYPE>::_yyzz() const
+    {
+        return VEC4(this->y, this->y, this->z, this->z);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC4 _cvec3<CVEC3_TYPE>::_zyzz() const
+    {
+        return VEC4(this->z, this->y, this->z, this->z);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC4 _cvec3<CVEC3_TYPE>::_xzzz() const
+    {
+        return VEC4(this->x, this->z, this->z, this->z);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC4 _cvec3<CVEC3_TYPE>::_yzzz() const
+    {
+        return VEC4(this->y, this->z, this->z, this->z);
+    }
+
+    template <CVEC3_LIST> 
+    inline const VEC4 _cvec3<CVEC3_TYPE>::_zzzz() const
+    {
+        return VEC4(this->z, this->z, this->z, this->z);
+    }
+#endif //defined(GLM_SWIZZLE)
+
+} //namespace detail
+} //namespace glm
+
+#endif//__cvec3_inl__
+

+ 489 - 0
experimental/sse/glm/core/_cvec4.h

@@ -0,0 +1,489 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2008 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2007-01-15
+// Updated : 2007-03-14
+// Licence : This source is under GNU LGPL licence
+// File    : _cvec4.h
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef __cvec4_h__
+#define __cvec4_h__
+
+#include "_cvecx.h"
+
+namespace glm{
+namespace detail{
+
+    template <CVEC4_LIST> 
+    class _cvec4
+    {
+	public:
+		typedef T value_type;
+		typedef int size_type;
+		static const size_type value_size;
+
+        // Data
+        /* ISO C++ version unavailable with VC7.1 ...
+            union{T x, r, s;};
+            union{T y, g, t;};
+            union{T z, b, p;};
+            union{T w, a, q;};
+        */
+/*
+        // Solution away from ISO C++ but available with VC7.1 and GCC without -pedantic
+        union 
+        {
+            struct{T x, y, z, w;};
+            struct{T r, g, b, a;};
+            struct{T s, t, p, q;};
+            //__m128 data;
+        };
+*/
+
+#ifndef GLM_SINGLE_COMP_NAME
+#ifdef GLM_COMPILER_GCC
+        union{T x, r, s;};
+        union{T y, g, t;};
+        union{T z, b, p;};
+        union{T w, a, q;};
+#endif//GLM_COMPILER_GCC
+
+#ifdef GLM_COMPILER_VC
+        union 
+        {
+            struct{T x, y, z, w;};
+            struct{T r, g, b, a;};
+            struct{T s, t, p, q;};
+        };
+#endif//GLM_COMPILER_VC
+
+#else
+        T x, y, z, w;
+#endif//GLM_SINGLE_COMP_NAME
+
+		// Constructor
+		_cvec4(){}
+		_cvec4(const T x, const T y, const T z, const T w);
+
+        // Accesses
+        T& operator[](size_type i);
+        const T operator[](size_type i) const;
+        operator T*();
+	    operator const T*() const;
+
+#if defined(GLM_SWIZZLE)
+        // Left hand side 2 components common swizzle operators
+        REF2 _yx();
+        REF2 _zx();
+        REF2 _wx();
+        REF2 _xy();
+        REF2 _zy();
+        REF2 _wy();
+        REF2 _xz();
+        REF2 _yz();
+        REF2 _wz();
+        REF2 _xw();
+        REF2 _yw();
+        REF2 _zw();
+
+        // Right hand side 2 components common swizzle operators
+        const VEC2 _xx() const;
+        const VEC2 _yx() const;
+        const VEC2 _zx() const;
+        const VEC2 _wx() const;
+        const VEC2 _xy() const;
+        const VEC2 _yy() const;
+        const VEC2 _zy() const;
+        const VEC2 _wy() const;
+        const VEC2 _xz() const;
+        const VEC2 _yz() const;
+        const VEC2 _zz() const;
+        const VEC2 _wz() const;
+        const VEC2 _xw() const;
+        const VEC2 _yw() const;
+        const VEC2 _zw() const;
+        const VEC2 _ww() const;
+
+        // Left hand side 3 components common swizzle operators
+        REF3 _zyx();
+        REF3 _wyx();
+        REF3 _yzx();
+        REF3 _wzx();
+        REF3 _ywx();
+        REF3 _zwx();
+        REF3 _zxy();
+        REF3 _wxy();
+        REF3 _xzy();
+        REF3 _wzy();
+        REF3 _xwy();
+        REF3 _zwy();
+        REF3 _yxz();
+        REF3 _wxz();
+        REF3 _xyz();
+        REF3 _wyz();
+        REF3 _xwz();
+        REF3 _ywz();
+        REF3 _yxw();
+        REF3 _zxw();
+        REF3 _xyw();
+        REF3 _zyw();
+        REF3 _xzw();
+        REF3 _yzw();
+
+        // Right hand side 3 components common swizzle operators
+        const VEC3 _xxx() const;
+        const VEC3 _yxx() const;
+        const VEC3 _zxx() const;
+        const VEC3 _wxx() const;
+        const VEC3 _xyx() const;
+        const VEC3 _yyx() const;
+        const VEC3 _zyx() const;
+        const VEC3 _wyx() const;
+        const VEC3 _xzx() const;
+        const VEC3 _yzx() const;
+        const VEC3 _zzx() const;
+        const VEC3 _wzx() const;
+        const VEC3 _xwx() const;
+        const VEC3 _ywx() const;
+        const VEC3 _zwx() const;
+        const VEC3 _wwx() const;
+        const VEC3 _xxy() const;
+        const VEC3 _yxy() const;
+        const VEC3 _zxy() const;
+        const VEC3 _wxy() const;
+        const VEC3 _xyy() const;
+        const VEC3 _yyy() const;
+        const VEC3 _zyy() const;
+        const VEC3 _wyy() const;
+        const VEC3 _xzy() const;
+        const VEC3 _yzy() const;
+        const VEC3 _zzy() const;
+        const VEC3 _wzy() const;
+        const VEC3 _xwy() const;
+        const VEC3 _ywy() const;
+        const VEC3 _zwy() const;
+        const VEC3 _wwy() const;
+        const VEC3 _xxz() const;
+        const VEC3 _yxz() const;
+        const VEC3 _zxz() const;
+        const VEC3 _wxz() const;
+        const VEC3 _xyz() const;
+        const VEC3 _yyz() const;
+        const VEC3 _zyz() const;
+        const VEC3 _wyz() const;
+        const VEC3 _xzz() const;
+        const VEC3 _yzz() const;
+        const VEC3 _zzz() const;
+        const VEC3 _wzz() const;
+        const VEC3 _xwz() const;
+        const VEC3 _ywz() const;
+        const VEC3 _zwz() const;
+        const VEC3 _wwz() const;
+        const VEC3 _xxw() const;
+        const VEC3 _yxw() const;
+        const VEC3 _zxw() const;
+        const VEC3 _wxw() const;
+        const VEC3 _xyw() const;
+        const VEC3 _yyw() const;
+        const VEC3 _zyw() const;
+        const VEC3 _wyw() const;
+        const VEC3 _xzw() const;
+        const VEC3 _yzw() const;
+        const VEC3 _zzw() const;
+        const VEC3 _wzw() const;
+        const VEC3 _xww() const;
+        const VEC3 _yww() const;
+        const VEC3 _zww() const;
+        const VEC3 _www() const;
+
+        // Left hand side 4 components common swizzle operators
+        REF4 _wzyx();
+        REF4 _zwyx();
+        REF4 _wyzx();
+        REF4 _ywzx();
+        REF4 _zywx();
+        REF4 _yzwx();
+        REF4 _wzxy();
+        REF4 _zwxy();
+        REF4 _wxzy();
+        REF4 _xwzy();
+        REF4 _zxwy();
+        REF4 _xzwy();
+        REF4 _wyxz();
+        REF4 _ywxz();
+        REF4 _wxyz();
+        REF4 _xwyz();
+        REF4 _yxwz();
+        REF4 _xywz();
+        REF4 _zyxw();
+        REF4 _yzxw();
+        REF4 _zxyw();
+        REF4 _xzyw();
+        REF4 _yxzw();
+        REF4 _xyzw();
+
+        // Right hand side 4 components common swizzle operators
+        const VEC4 _xxxx() const;
+        const VEC4 _yxxx() const;
+        const VEC4 _zxxx() const;
+        const VEC4 _wxxx() const;
+        const VEC4 _xyxx() const;
+        const VEC4 _yyxx() const;
+        const VEC4 _zyxx() const;
+        const VEC4 _wyxx() const;
+        const VEC4 _xzxx() const;
+        const VEC4 _yzxx() const;
+        const VEC4 _zzxx() const;
+        const VEC4 _wzxx() const;
+        const VEC4 _xwxx() const;
+        const VEC4 _ywxx() const;
+        const VEC4 _zwxx() const;
+        const VEC4 _wwxx() const;
+        const VEC4 _xxyx() const;
+        const VEC4 _yxyx() const;
+        const VEC4 _zxyx() const;
+        const VEC4 _wxyx() const;
+        const VEC4 _xyyx() const;
+        const VEC4 _yyyx() const;
+        const VEC4 _zyyx() const;
+        const VEC4 _wyyx() const;
+        const VEC4 _xzyx() const;
+        const VEC4 _yzyx() const;
+        const VEC4 _zzyx() const;
+        const VEC4 _wzyx() const;
+        const VEC4 _xwyx() const;
+        const VEC4 _ywyx() const;
+        const VEC4 _zwyx() const;
+        const VEC4 _wwyx() const;
+        const VEC4 _xxzx() const;
+        const VEC4 _yxzx() const;
+        const VEC4 _zxzx() const;
+        const VEC4 _wxzx() const;
+        const VEC4 _xyzx() const;
+        const VEC4 _yyzx() const;
+        const VEC4 _zyzx() const;
+        const VEC4 _wyzx() const;
+        const VEC4 _xzzx() const;
+        const VEC4 _yzzx() const;
+        const VEC4 _zzzx() const;
+        const VEC4 _wzzx() const;
+        const VEC4 _xwzx() const;
+        const VEC4 _ywzx() const;
+        const VEC4 _zwzx() const;
+        const VEC4 _wwzx() const;
+        const VEC4 _xxwx() const;
+        const VEC4 _yxwx() const;
+        const VEC4 _zxwx() const;
+        const VEC4 _wxwx() const;
+        const VEC4 _xywx() const;
+        const VEC4 _yywx() const;
+        const VEC4 _zywx() const;
+        const VEC4 _wywx() const;
+        const VEC4 _xzwx() const;
+        const VEC4 _yzwx() const;
+        const VEC4 _zzwx() const;
+        const VEC4 _wzwx() const;
+        const VEC4 _xwwx() const;
+        const VEC4 _ywwx() const;
+        const VEC4 _zwwx() const;
+        const VEC4 _wwwx() const;
+        const VEC4 _xxxy() const;
+        const VEC4 _yxxy() const;
+        const VEC4 _zxxy() const;
+        const VEC4 _wxxy() const;
+        const VEC4 _xyxy() const;
+        const VEC4 _yyxy() const;
+        const VEC4 _zyxy() const;
+        const VEC4 _wyxy() const;
+        const VEC4 _xzxy() const;
+        const VEC4 _yzxy() const;
+        const VEC4 _zzxy() const;
+        const VEC4 _wzxy() const;
+        const VEC4 _xwxy() const;
+        const VEC4 _ywxy() const;
+        const VEC4 _zwxy() const;
+        const VEC4 _wwxy() const;
+        const VEC4 _xxyy() const;
+        const VEC4 _yxyy() const;
+        const VEC4 _zxyy() const;
+        const VEC4 _wxyy() const;
+        const VEC4 _xyyy() const;
+        const VEC4 _yyyy() const;
+        const VEC4 _zyyy() const;
+        const VEC4 _wyyy() const;
+        const VEC4 _xzyy() const;
+        const VEC4 _yzyy() const;
+        const VEC4 _zzyy() const;
+        const VEC4 _wzyy() const;
+        const VEC4 _xwyy() const;
+        const VEC4 _ywyy() const;
+        const VEC4 _zwyy() const;
+        const VEC4 _wwyy() const;
+        const VEC4 _xxzy() const;
+        const VEC4 _yxzy() const;
+        const VEC4 _zxzy() const;
+        const VEC4 _wxzy() const;
+        const VEC4 _xyzy() const;
+        const VEC4 _yyzy() const;
+        const VEC4 _zyzy() const;
+        const VEC4 _wyzy() const;
+        const VEC4 _xzzy() const;
+        const VEC4 _yzzy() const;
+        const VEC4 _zzzy() const;
+        const VEC4 _wzzy() const;
+        const VEC4 _xwzy() const;
+        const VEC4 _ywzy() const;
+        const VEC4 _zwzy() const;
+        const VEC4 _wwzy() const;
+        const VEC4 _xxwy() const;
+        const VEC4 _yxwy() const;
+        const VEC4 _zxwy() const;
+        const VEC4 _wxwy() const;
+        const VEC4 _xywy() const;
+        const VEC4 _yywy() const;
+        const VEC4 _zywy() const;
+        const VEC4 _wywy() const;
+        const VEC4 _xzwy() const;
+        const VEC4 _yzwy() const;
+        const VEC4 _zzwy() const;
+        const VEC4 _wzwy() const;
+        const VEC4 _xwwy() const;
+        const VEC4 _ywwy() const;
+        const VEC4 _zwwy() const;
+        const VEC4 _wwwy() const;
+        const VEC4 _xxxz() const;
+        const VEC4 _yxxz() const;
+        const VEC4 _zxxz() const;
+        const VEC4 _wxxz() const;
+        const VEC4 _xyxz() const;
+        const VEC4 _yyxz() const;
+        const VEC4 _zyxz() const;
+        const VEC4 _wyxz() const;
+        const VEC4 _xzxz() const;
+        const VEC4 _yzxz() const;
+        const VEC4 _zzxz() const;
+        const VEC4 _wzxz() const;
+        const VEC4 _xwxz() const;
+        const VEC4 _ywxz() const;
+        const VEC4 _zwxz() const;
+        const VEC4 _wwxz() const;
+        const VEC4 _xxyz() const;
+        const VEC4 _yxyz() const;
+        const VEC4 _zxyz() const;
+        const VEC4 _wxyz() const;
+        const VEC4 _xyyz() const;
+        const VEC4 _yyyz() const;
+        const VEC4 _zyyz() const;
+        const VEC4 _wyyz() const;
+        const VEC4 _xzyz() const;
+        const VEC4 _yzyz() const;
+        const VEC4 _zzyz() const;
+        const VEC4 _wzyz() const;
+        const VEC4 _xwyz() const;
+        const VEC4 _ywyz() const;
+        const VEC4 _zwyz() const;
+        const VEC4 _wwyz() const;
+        const VEC4 _xxzz() const;
+        const VEC4 _yxzz() const;
+        const VEC4 _zxzz() const;
+        const VEC4 _wxzz() const;
+        const VEC4 _xyzz() const;
+        const VEC4 _yyzz() const;
+        const VEC4 _zyzz() const;
+        const VEC4 _wyzz() const;
+        const VEC4 _xzzz() const;
+        const VEC4 _yzzz() const;
+        const VEC4 _zzzz() const;
+        const VEC4 _wzzz() const;
+        const VEC4 _xwzz() const;
+        const VEC4 _ywzz() const;
+        const VEC4 _zwzz() const;
+        const VEC4 _wwzz() const;
+        const VEC4 _xxwz() const;
+        const VEC4 _yxwz() const;
+        const VEC4 _zxwz() const;
+        const VEC4 _wxwz() const;
+        const VEC4 _xywz() const;
+        const VEC4 _yywz() const;
+        const VEC4 _zywz() const;
+        const VEC4 _wywz() const;
+        const VEC4 _xzwz() const;
+        const VEC4 _yzwz() const;
+        const VEC4 _zzwz() const;
+        const VEC4 _wzwz() const;
+        const VEC4 _xwwz() const;
+        const VEC4 _ywwz() const;
+        const VEC4 _zwwz() const;
+        const VEC4 _wwwz() const;
+        const VEC4 _xxxw() const;
+        const VEC4 _yxxw() const;
+        const VEC4 _zxxw() const;
+        const VEC4 _wxxw() const;
+        const VEC4 _xyxw() const;
+        const VEC4 _yyxw() const;
+        const VEC4 _zyxw() const;
+        const VEC4 _wyxw() const;
+        const VEC4 _xzxw() const;
+        const VEC4 _yzxw() const;
+        const VEC4 _zzxw() const;
+        const VEC4 _wzxw() const;
+        const VEC4 _xwxw() const;
+        const VEC4 _ywxw() const;
+        const VEC4 _zwxw() const;
+        const VEC4 _wwxw() const;
+        const VEC4 _xxyw() const;
+        const VEC4 _yxyw() const;
+        const VEC4 _zxyw() const;
+        const VEC4 _wxyw() const;
+        const VEC4 _xyyw() const;
+        const VEC4 _yyyw() const;
+        const VEC4 _zyyw() const;
+        const VEC4 _wyyw() const;
+        const VEC4 _xzyw() const;
+        const VEC4 _yzyw() const;
+        const VEC4 _zzyw() const;
+        const VEC4 _wzyw() const;
+        const VEC4 _xwyw() const;
+        const VEC4 _ywyw() const;
+        const VEC4 _zwyw() const;
+        const VEC4 _wwyw() const;
+        const VEC4 _xxzw() const;
+        const VEC4 _yxzw() const;
+        const VEC4 _zxzw() const;
+        const VEC4 _wxzw() const;
+        const VEC4 _xyzw() const;
+        const VEC4 _yyzw() const;
+        const VEC4 _zyzw() const;
+        const VEC4 _wyzw() const;
+        const VEC4 _xzzw() const;
+        const VEC4 _yzzw() const;
+        const VEC4 _zzzw() const;
+        const VEC4 _wzzw() const;
+        const VEC4 _xwzw() const;
+        const VEC4 _ywzw() const;
+        const VEC4 _zwzw() const;
+        const VEC4 _wwzw() const;
+        const VEC4 _xxww() const;
+        const VEC4 _yxww() const;
+        const VEC4 _zxww() const;
+        const VEC4 _wxww() const;
+        const VEC4 _xyww() const;
+        const VEC4 _yyww() const;
+        const VEC4 _zyww() const;
+        const VEC4 _wyww() const;
+        const VEC4 _xzww() const;
+        const VEC4 _yzww() const;
+        const VEC4 _zzww() const;
+        const VEC4 _wzww() const;
+        const VEC4 _xwww() const;
+        const VEC4 _ywww() const;
+        const VEC4 _zwww() const;
+        const VEC4 _wwww() const;
+#endif// defined(GLM_SWIZZLE)
+	};
+
+} //namespace detail
+} //namespace glm
+
+#endif//__cvec4_h__

+ 2450 - 0
experimental/sse/glm/core/_cvec4.inl

@@ -0,0 +1,2450 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2008 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2007-01-15
+// Updated : 2007-01-15
+// Licence : This source is under GNU LGPL licence
+// File    : _cvec4.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef __cvec4_inl__
+#define __cvec4_inl__
+
+#include "_cvec4.h"
+
+namespace glm{
+namespace detail{
+
+	template <CVEC4_LIST>
+	const int _cvec4<CVEC4_TYPE>::value_size = 4;
+	
+	//////////////////////////////////////////////////////////////
+    // _cvec4 constructor
+
+	template <CVEC4_LIST>  
+	inline _cvec4<CVEC4_TYPE>::_cvec4(const T x, const T y, const T z, const T w) :
+		x(x), y(y), z(z), w(w)
+	{}
+
+    //////////////////////////////////////////////////////////////
+	// vec4 and ivec4 accesses
+
+    template <CVEC4_LIST> 
+    inline T& _cvec4<CVEC4_TYPE>::operator[](int i)
+    {
+        return (&x)[i];
+    }
+
+    template <CVEC4_LIST> 
+    inline const T _cvec4<CVEC4_TYPE>::operator[](int i) const
+    {
+        return (&x)[i];
+    }
+
+    template <CVEC4_LIST> 
+    inline _cvec4<CVEC4_TYPE>::operator T*()
+    {
+        return &x;
+    }
+
+    template <CVEC4_LIST> 
+    inline _cvec4<CVEC4_TYPE>::operator const T*() const 
+    {
+        return &x;
+    }
+
+#if defined(GLM_SWIZZLE)
+    //////////////////////////////////////////////////////////////
+    // Left hand side 2 components common swizzle operators
+
+    template <CVEC4_LIST> 
+    inline REF2 _cvec4<CVEC4_TYPE>::_yx()
+    {
+        return REF2(this->y, this->x);
+    }
+
+    template <CVEC4_LIST> 
+    inline REF2 _cvec4<CVEC4_TYPE>::_zx()
+    {
+        return REF2(this->z, this->x);
+    }
+
+    template <CVEC4_LIST> 
+    inline REF2 _cvec4<CVEC4_TYPE>::_wx()
+    {
+        return REF2(this->w, this->x);
+    }
+
+    template <CVEC4_LIST> 
+    inline REF2 _cvec4<CVEC4_TYPE>::_xy()
+    {
+        return REF2(this->x, this->y);
+    }
+
+    template <CVEC4_LIST> 
+    inline REF2 _cvec4<CVEC4_TYPE>::_zy()
+    {
+        return REF2(this->z, this->y);
+    }
+
+    template <CVEC4_LIST> 
+    inline REF2 _cvec4<CVEC4_TYPE>::_wy()
+    {
+        return REF2(this->w, this->y);
+    }
+
+    template <CVEC4_LIST> 
+    inline REF2 _cvec4<CVEC4_TYPE>::_xz()
+    {
+        return REF2(this->x, this->z);
+    }
+
+    template <CVEC4_LIST> 
+    inline REF2 _cvec4<CVEC4_TYPE>::_yz()
+    {
+        return REF2(this->y, this->z);
+    }
+
+    template <CVEC4_LIST> 
+    inline REF2 _cvec4<CVEC4_TYPE>::_wz()
+    {
+        return REF2(this->w, this->z);
+    }
+
+    template <CVEC4_LIST> 
+    inline REF2 _cvec4<CVEC4_TYPE>::_xw()
+    {
+        return REF2(this->x, this->w);
+    }
+
+    template <CVEC4_LIST> 
+    inline REF2 _cvec4<CVEC4_TYPE>::_yw()
+    {
+        return REF2(this->y, this->w);
+    }
+
+    template <CVEC4_LIST> 
+    inline REF2 _cvec4<CVEC4_TYPE>::_zw()
+    {
+        return REF2(this->z, this->w);
+    }
+
+    // Right hand side 2 components swizzles operators
+
+    template <CVEC4_LIST> 
+    inline const VEC2 _cvec4<CVEC4_TYPE>::_xx() const
+    {
+        return VEC2(this->x, this->x);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC2 _cvec4<CVEC4_TYPE>::_yx() const
+    {
+        return VEC2(this->y, this->x);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC2 _cvec4<CVEC4_TYPE>::_zx() const
+    {
+        return VEC2(this->z, this->x);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC2 _cvec4<CVEC4_TYPE>::_wx() const
+    {
+        return VEC2(this->w, this->x);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC2 _cvec4<CVEC4_TYPE>::_xy() const
+    {
+        return VEC2(this->x, this->y);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC2 _cvec4<CVEC4_TYPE>::_yy() const
+    {
+        return VEC2(this->y, this->y);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC2 _cvec4<CVEC4_TYPE>::_zy() const
+    {
+        return VEC2(this->z, this->y);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC2 _cvec4<CVEC4_TYPE>::_wy() const
+    {
+        return VEC2(this->w, this->y);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC2 _cvec4<CVEC4_TYPE>::_xz() const
+    {
+        return VEC2(this->x, this->z);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC2 _cvec4<CVEC4_TYPE>::_yz() const
+    {
+        return VEC2(this->y, this->z);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC2 _cvec4<CVEC4_TYPE>::_zz() const
+    {
+        return VEC2(this->z, this->z);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC2 _cvec4<CVEC4_TYPE>::_wz() const
+    {
+        return VEC2(this->w, this->z);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC2 _cvec4<CVEC4_TYPE>::_xw() const
+    {
+        return VEC2(this->x, this->w);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC2 _cvec4<CVEC4_TYPE>::_yw() const
+    {
+        return VEC2(this->y, this->w);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC2 _cvec4<CVEC4_TYPE>::_zw() const
+    {
+        return VEC2(this->z, this->w);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC2 _cvec4<CVEC4_TYPE>::_ww() const
+    {
+        return VEC2(this->w, this->w);
+    }
+
+    //////////////////////////////////////////////////////////////
+    // Left hand side 3 components swizzles operators
+
+    template <CVEC4_LIST> 
+    inline REF3 _cvec4<CVEC4_TYPE>::_zyx()
+	{
+		return REF3(this->z, this->y, this->x);
+	}
+
+	template <CVEC4_LIST> 
+    inline REF3 _cvec4<CVEC4_TYPE>::_wyx()
+	{
+		return REF3(this->w, this->y, this->x);
+	}
+
+	template <CVEC4_LIST> 
+    inline REF3 _cvec4<CVEC4_TYPE>::_yzx()
+	{
+		return REF3(this->y, this->z, this->x);
+	}
+
+	template <CVEC4_LIST> 
+    inline REF3 _cvec4<CVEC4_TYPE>::_wzx()
+	{
+		return REF3(this->w, this->z, this->x);
+	}
+
+	template <CVEC4_LIST> 
+    inline REF3 _cvec4<CVEC4_TYPE>::_ywx()
+	{
+		return REF3(this->y, this->w, this->x);
+	}
+
+	template <CVEC4_LIST> 
+    inline REF3 _cvec4<CVEC4_TYPE>::_zwx()
+	{
+		return REF3(this->z, this->w, this->x);
+	}
+
+	template <CVEC4_LIST> 
+    inline REF3 _cvec4<CVEC4_TYPE>::_zxy()
+	{
+		return REF3(this->z, this->x, this->y);
+	}
+
+    template <CVEC4_LIST> 
+	inline REF3 _cvec4<CVEC4_TYPE>::_wxy()
+	{
+		return REF3(this->w, this->x, this->y);
+	}
+
+	template <CVEC4_LIST> 
+    inline REF3 _cvec4<CVEC4_TYPE>::_xzy()
+	{
+		return REF3(this->x, this->z, this->y);
+	}
+
+    template <CVEC4_LIST> 
+	inline REF3 _cvec4<CVEC4_TYPE>::_wzy()
+	{
+		return REF3(this->w, this->z, this->y);
+	}
+
+	template <CVEC4_LIST> 
+    inline REF3 _cvec4<CVEC4_TYPE>::_xwy()
+	{
+		return REF3(this->x, this->w, this->y);
+	}
+
+	template <CVEC4_LIST> 
+    inline REF3 _cvec4<CVEC4_TYPE>::_zwy()
+	{
+		return REF3(this->z, this->w, this->y);
+	}
+
+	template <CVEC4_LIST> 
+    inline REF3 _cvec4<CVEC4_TYPE>::_yxz()
+	{
+		return REF3(this->y, this->x, this->z);
+	}
+
+	template <CVEC4_LIST> 
+    inline REF3 _cvec4<CVEC4_TYPE>::_wxz()
+	{
+		return REF3(this->w, this->x, this->z);
+	}
+
+	template <CVEC4_LIST> 
+    inline REF3 _cvec4<CVEC4_TYPE>::_xyz()
+	{
+		return REF3(this->x, this->y, this->z);
+	}
+
+	template <CVEC4_LIST> 
+    inline REF3 _cvec4<CVEC4_TYPE>::_wyz()
+	{
+		return REF3(this->w, this->y, this->z);
+	}
+
+	template <CVEC4_LIST> 
+    inline REF3 _cvec4<CVEC4_TYPE>::_xwz()
+	{
+		return REF3(this->x, this->w, this->z);
+	}
+
+	template <CVEC4_LIST> 
+    inline REF3 _cvec4<CVEC4_TYPE>::_ywz()
+	{
+		return REF3(this->y, this->w, this->z);
+	}
+
+	template <CVEC4_LIST> 
+    inline REF3 _cvec4<CVEC4_TYPE>::_yxw()
+	{
+		return REF3(this->y, this->x, this->w);
+	}
+
+	template <CVEC4_LIST> 
+    inline REF3 _cvec4<CVEC4_TYPE>::_zxw()
+	{
+		return REF3(this->z, this->x, this->w);
+	}
+
+	template <CVEC4_LIST> 
+    inline REF3 _cvec4<CVEC4_TYPE>::_xyw()
+	{
+		return REF3(this->x, this->y, this->w);
+	}
+
+	template <CVEC4_LIST> 
+    inline REF3 _cvec4<CVEC4_TYPE>::_zyw()
+	{
+		return REF3(this->z, this->y, this->w);
+	}
+
+	template <CVEC4_LIST> 
+    inline REF3 _cvec4<CVEC4_TYPE>::_xzw()
+	{
+		return REF3(this->x, this->z, this->w);
+	}
+
+	template <CVEC4_LIST> 
+    inline REF3 _cvec4<CVEC4_TYPE>::_yzw()
+	{
+		return REF3(this->y, this->z, this->w);
+	}
+
+    //////////////////////////////////////////////////////////////
+    // Right hand side 3 components swizzles operators
+
+    template <CVEC4_LIST> 
+    inline const VEC3 _cvec4<CVEC4_TYPE>::_xxx() const
+    {
+        return VEC3(this->x, this->x, this->x);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC3 _cvec4<CVEC4_TYPE>::_yxx() const
+    {
+        return VEC3(this->y, this->x, this->x);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC3 _cvec4<CVEC4_TYPE>::_zxx() const
+    {
+        return VEC3(this->z, this->x, this->x);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC3 _cvec4<CVEC4_TYPE>::_wxx() const
+    {
+        return VEC3(this->w, this->x, this->x);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC3 _cvec4<CVEC4_TYPE>::_xyx() const
+    {
+        return VEC3(this->x, this->y, this->x);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC3 _cvec4<CVEC4_TYPE>::_yyx() const
+    {
+        return VEC3(this->y, this->y, this->x);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC3 _cvec4<CVEC4_TYPE>::_zyx() const
+    {
+        return VEC3(this->z, this->y, this->x);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC3 _cvec4<CVEC4_TYPE>::_wyx() const
+    {
+        return VEC3(this->w, this->y, this->x);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC3 _cvec4<CVEC4_TYPE>::_xzx() const
+    {
+        return VEC3(this->x, this->z, this->x);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC3 _cvec4<CVEC4_TYPE>::_yzx() const
+    {
+        return VEC3(this->y, this->z, this->x);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC3 _cvec4<CVEC4_TYPE>::_zzx() const
+    {
+        return VEC3(this->z, this->z, this->x);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC3 _cvec4<CVEC4_TYPE>::_wzx() const
+    {
+        return VEC3(this->w, this->z, this->x);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC3 _cvec4<CVEC4_TYPE>::_xwx() const
+    {
+        return VEC3(this->x, this->w, this->x);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC3 _cvec4<CVEC4_TYPE>::_ywx() const
+    {
+        return VEC3(this->y, this->w, this->x);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC3 _cvec4<CVEC4_TYPE>::_zwx() const
+    {
+        return VEC3(this->z, this->w, this->x);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC3 _cvec4<CVEC4_TYPE>::_wwx() const
+    {
+        return VEC3(this->w, this->w, this->x);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC3 _cvec4<CVEC4_TYPE>::_xxy() const
+    {
+        return VEC3(this->x, this->x, this->y);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC3 _cvec4<CVEC4_TYPE>::_yxy() const
+    {
+        return VEC3(this->y, this->x, this->y);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC3 _cvec4<CVEC4_TYPE>::_zxy() const
+    {
+        return VEC3(this->z, this->x, this->y);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC3 _cvec4<CVEC4_TYPE>::_wxy() const
+    {
+        return VEC3(this->w, this->x, this->y);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC3 _cvec4<CVEC4_TYPE>::_xyy() const
+    {
+        return VEC3(this->x, this->y, this->y);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC3 _cvec4<CVEC4_TYPE>::_yyy() const
+    {
+        return VEC3(this->y, this->y, this->y);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC3 _cvec4<CVEC4_TYPE>::_zyy() const
+    {
+        return VEC3(this->z, this->y, this->y);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC3 _cvec4<CVEC4_TYPE>::_wyy() const
+    {
+        return VEC3(this->w, this->y, this->y);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC3 _cvec4<CVEC4_TYPE>::_xzy() const
+    {
+        return VEC3(this->x, this->z, this->y);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC3 _cvec4<CVEC4_TYPE>::_yzy() const
+    {
+        return VEC3(this->y, this->z, this->y);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC3 _cvec4<CVEC4_TYPE>::_zzy() const
+    {
+        return VEC3(this->z, this->z, this->y);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC3 _cvec4<CVEC4_TYPE>::_wzy() const
+    {
+        return VEC3(this->w, this->z, this->y);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC3 _cvec4<CVEC4_TYPE>::_xwy() const
+    {
+        return VEC3(this->x, this->w, this->y);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC3 _cvec4<CVEC4_TYPE>::_ywy() const
+    {
+        return VEC3(this->y, this->w, this->y);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC3 _cvec4<CVEC4_TYPE>::_zwy() const
+    {
+        return VEC3(this->z, this->w, this->y);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC3 _cvec4<CVEC4_TYPE>::_wwy() const
+    {
+        return VEC3(this->w, this->w, this->y);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC3 _cvec4<CVEC4_TYPE>::_xxz() const
+    {
+        return VEC3(this->x, this->x, this->z);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC3 _cvec4<CVEC4_TYPE>::_yxz() const
+    {
+        return VEC3(this->y, this->x, this->z);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC3 _cvec4<CVEC4_TYPE>::_zxz() const
+    {
+        return VEC3(this->z, this->x, this->z);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC3 _cvec4<CVEC4_TYPE>::_wxz() const
+    {
+        return VEC3(this->w, this->x, this->z);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC3 _cvec4<CVEC4_TYPE>::_xyz() const
+    {
+        return VEC3(this->x, this->y, this->z);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC3 _cvec4<CVEC4_TYPE>::_yyz() const
+    {
+        return VEC3(this->y, this->y, this->z);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC3 _cvec4<CVEC4_TYPE>::_zyz() const
+    {
+        return VEC3(this->z, this->y, this->z);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC3 _cvec4<CVEC4_TYPE>::_wyz() const
+    {
+        return VEC3(this->w, this->y, this->z);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC3 _cvec4<CVEC4_TYPE>::_xzz() const
+    {
+        return VEC3(this->x, this->z, this->z);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC3 _cvec4<CVEC4_TYPE>::_yzz() const
+    {
+        return VEC3(this->y, this->z, this->z);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC3 _cvec4<CVEC4_TYPE>::_zzz() const
+    {
+        return VEC3(this->z, this->z, this->z);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC3 _cvec4<CVEC4_TYPE>::_wzz() const
+    {
+        return VEC3(this->w, this->z, this->z);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC3 _cvec4<CVEC4_TYPE>::_xwz() const
+    {
+        return VEC3(this->x, this->w, this->z);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC3 _cvec4<CVEC4_TYPE>::_ywz() const
+    {
+        return VEC3(this->y, this->w, this->z);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC3 _cvec4<CVEC4_TYPE>::_zwz() const
+    {
+        return VEC3(this->z, this->w, this->z);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC3 _cvec4<CVEC4_TYPE>::_wwz() const
+    {
+        return VEC3(this->w, this->w, this->z);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC3 _cvec4<CVEC4_TYPE>::_xxw() const
+    {
+        return VEC3(this->x, this->x, this->w);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC3 _cvec4<CVEC4_TYPE>::_yxw() const
+    {
+        return VEC3(this->y, this->x, this->w);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC3 _cvec4<CVEC4_TYPE>::_zxw() const
+    {
+        return VEC3(this->z, this->x, this->w);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC3 _cvec4<CVEC4_TYPE>::_wxw() const
+    {
+        return VEC3(this->w, this->x, this->w);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC3 _cvec4<CVEC4_TYPE>::_xyw() const
+    {
+        return VEC3(this->x, this->y, this->w);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC3 _cvec4<CVEC4_TYPE>::_yyw() const
+    {
+        return VEC3(this->y, this->y, this->w);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC3 _cvec4<CVEC4_TYPE>::_zyw() const
+    {
+        return VEC3(this->z, this->y, this->w);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC3 _cvec4<CVEC4_TYPE>::_wyw() const
+    {
+        return VEC3(this->w, this->y, this->w);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC3 _cvec4<CVEC4_TYPE>::_xzw() const
+    {
+        return VEC3(this->x, this->z, this->w);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC3 _cvec4<CVEC4_TYPE>::_yzw() const
+    {
+        return VEC3(this->y, this->z, this->w);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC3 _cvec4<CVEC4_TYPE>::_zzw() const
+    {
+        return VEC3(this->z, this->z, this->w);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC3 _cvec4<CVEC4_TYPE>::_wzw() const
+    {
+        return VEC3(this->w, this->z, this->w);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC3 _cvec4<CVEC4_TYPE>::_xww() const
+    {
+        return VEC3(this->x, this->w, this->w);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC3 _cvec4<CVEC4_TYPE>::_yww() const
+    {
+        return VEC3(this->y, this->w, this->w);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC3 _cvec4<CVEC4_TYPE>::_zww() const
+    {
+        return VEC3(this->z, this->w, this->w);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC3 _cvec4<CVEC4_TYPE>::_www() const
+    {
+        return VEC3(this->w, this->w, this->w);
+    }
+
+    // Left hand side 4 components swizzles operators
+    template <CVEC4_LIST> 
+    inline REF4 _cvec4<CVEC4_TYPE>::_wzyx()
+    {
+        return REF4(this->w, this->z, this->y, this->x);
+    }
+
+    template <CVEC4_LIST> 
+    inline REF4 _cvec4<CVEC4_TYPE>::_zwyx()
+    {
+        return REF4(this->z, this->w, this->y, this->x);
+    }
+
+    template <CVEC4_LIST> 
+    inline REF4 _cvec4<CVEC4_TYPE>::_wyzx()
+    {
+        return REF4(this->w, this->y, this->z, this->x);
+    }
+
+    template <CVEC4_LIST> 
+    inline REF4 _cvec4<CVEC4_TYPE>::_ywzx()
+    {
+        return REF4(this->y, this->w, this->z, this->x);
+    }
+
+    template <CVEC4_LIST> 
+    inline REF4 _cvec4<CVEC4_TYPE>::_zywx()
+    {
+        return REF4(this->z, this->y, this->w, this->x);
+    }
+
+    template <CVEC4_LIST> 
+    inline REF4 _cvec4<CVEC4_TYPE>::_yzwx()
+    {
+        return REF4(this->y, this->z, this->w, this->x);
+    }
+
+    template <CVEC4_LIST> 
+    inline REF4 _cvec4<CVEC4_TYPE>::_wzxy()
+    {
+        return REF4(this->w, this->z, this->x, this->y);
+    }
+
+    template <CVEC4_LIST> 
+    inline REF4 _cvec4<CVEC4_TYPE>::_zwxy()
+    {
+        return REF4(this->z, this->w, this->x, this->y);
+    }
+
+    template <CVEC4_LIST> 
+    inline REF4 _cvec4<CVEC4_TYPE>::_wxzy()
+    {
+        return REF4(this->w, this->x, this->z, this->y);
+    }
+
+    template <CVEC4_LIST> 
+    inline REF4 _cvec4<CVEC4_TYPE>::_xwzy()
+    {
+        return REF4(this->x, this->w, this->z, this->y);
+    }
+
+    template <CVEC4_LIST> 
+    inline REF4 _cvec4<CVEC4_TYPE>::_zxwy()
+    {
+        return REF4(this->z, this->x, this->w, this->y);
+    }
+
+    template <CVEC4_LIST> 
+    inline REF4 _cvec4<CVEC4_TYPE>::_xzwy()
+    {
+        return REF4(this->x, this->z, this->w, this->y);
+    }
+
+    template <CVEC4_LIST> 
+    inline REF4 _cvec4<CVEC4_TYPE>::_wyxz()
+    {
+        return REF4(this->w, this->y, this->x, this->z);
+    }
+
+    template <CVEC4_LIST> 
+    inline REF4 _cvec4<CVEC4_TYPE>::_ywxz()
+    {
+        return REF4(this->y, this->w, this->x, this->z);
+    }
+
+    template <CVEC4_LIST> 
+    inline REF4 _cvec4<CVEC4_TYPE>::_wxyz()
+    {
+        return REF4(this->w, this->x, this->y, this->z);
+    }
+
+    template <CVEC4_LIST> 
+    inline REF4 _cvec4<CVEC4_TYPE>::_xwyz()
+    {
+        return REF4(this->x, this->w, this->y, this->z);
+    }
+
+    template <CVEC4_LIST> 
+    inline REF4 _cvec4<CVEC4_TYPE>::_yxwz()
+    {
+        return REF4(this->y, this->x, this->w, this->z);
+    }
+
+    template <CVEC4_LIST> 
+    inline REF4 _cvec4<CVEC4_TYPE>::_xywz()
+    {
+        return REF4(this->x, this->y, this->w, this->z);
+    }
+
+    template <CVEC4_LIST> 
+    inline REF4 _cvec4<CVEC4_TYPE>::_zyxw()
+    {
+        return REF4(this->z, this->y, this->x, this->w);
+    }
+
+    template <CVEC4_LIST> 
+    inline REF4 _cvec4<CVEC4_TYPE>::_yzxw()
+    {
+        return REF4(this->y, this->z, this->x, this->w);
+    }
+
+    template <CVEC4_LIST> 
+    inline REF4 _cvec4<CVEC4_TYPE>::_zxyw()
+    {
+        return REF4(this->z, this->x, this->y, this->w);
+    }
+
+    template <CVEC4_LIST> 
+    inline REF4 _cvec4<CVEC4_TYPE>::_xzyw()
+    {
+        return REF4(this->x, this->z, this->y, this->w);
+    }
+
+    template <CVEC4_LIST> 
+    inline REF4 _cvec4<CVEC4_TYPE>::_yxzw()
+    {
+        return REF4(this->y, this->x, this->z, this->w);
+    }
+
+    template <CVEC4_LIST> 
+    inline REF4 _cvec4<CVEC4_TYPE>::_xyzw()
+    {
+        return REF4(this->x, this->y, this->z, this->w);
+    }
+
+    // Right hand side 4 components swizzles operators
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_xxxx() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->x, this->x, this->x, this->x);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_yxxx() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->y, this->x, this->x, this->x);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_zxxx() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->z, this->x, this->x, this->x);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_wxxx() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->w, this->x, this->x, this->x);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_xyxx() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->x, this->y, this->x, this->x);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_yyxx() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->y, this->y, this->x, this->x);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_zyxx() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->z, this->y, this->x, this->x);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_wyxx() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->w, this->y, this->x, this->x);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_xzxx() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->x, this->z, this->x, this->x);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_yzxx() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->y, this->z, this->x, this->x);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_zzxx() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->z, this->z, this->x, this->x);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_wzxx() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->w, this->z, this->x, this->x);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_xwxx() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->x, this->w, this->x, this->x);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_ywxx() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->y, this->w, this->x, this->x);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_zwxx() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->z, this->w, this->x, this->x);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_wwxx() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->w, this->w, this->x, this->x);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_xxyx() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->x, this->x, this->y, this->x);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_yxyx() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->y, this->x, this->y, this->x);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_zxyx() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->z, this->x, this->y, this->x);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_wxyx() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->w, this->x, this->y, this->x);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_xyyx() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->x, this->y, this->y, this->x);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_yyyx() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->y, this->y, this->y, this->x);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_zyyx() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->z, this->y, this->y, this->x);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_wyyx() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->w, this->y, this->y, this->x);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_xzyx() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->x, this->z, this->y, this->x);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_yzyx() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->y, this->z, this->y, this->x);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_zzyx() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->z, this->z, this->y, this->x);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_wzyx() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->w, this->z, this->y, this->x);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_xwyx() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->x, this->w, this->y, this->x);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_ywyx() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->y, this->w, this->y, this->x);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_zwyx() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->z, this->w, this->y, this->x);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_wwyx() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->w, this->w, this->y, this->x);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_xxzx() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->x, this->x, this->z, this->x);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_yxzx() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->y, this->x, this->z, this->x);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_zxzx() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->z, this->x, this->z, this->x);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_wxzx() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->w, this->x, this->z, this->x);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_xyzx() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->x, this->y, this->z, this->x);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_yyzx() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->y, this->y, this->z, this->x);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_zyzx() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->z, this->y, this->z, this->x);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_wyzx() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->w, this->y, this->z, this->x);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_xzzx() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->x, this->z, this->z, this->x);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_yzzx() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->y, this->z, this->z, this->x);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_zzzx() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->z, this->z, this->z, this->x);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_wzzx() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->w, this->z, this->z, this->x);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_xwzx() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->x, this->w, this->z, this->x);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_ywzx() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->y, this->w, this->z, this->x);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_zwzx() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->z, this->w, this->z, this->x);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_wwzx() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->w, this->w, this->z, this->x);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_xxwx() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->x, this->x, this->x, this->x);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_yxwx() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->y, this->x, this->w, this->x);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_zxwx() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->z, this->x, this->w, this->x);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_wxwx() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->w, this->x, this->w, this->x);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_xywx() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->x, this->y, this->w, this->x);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_yywx() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->y, this->y, this->w, this->x);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_zywx() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->z, this->y, this->w, this->x);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_wywx() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->w, this->y, this->w, this->x);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_xzwx() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->x, this->z, this->w, this->x);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_yzwx() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->y, this->z, this->w, this->x);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_zzwx() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->z, this->z, this->w, this->x);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_wzwx() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->w, this->z, this->w, this->x);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_xwwx() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->x, this->w, this->w, this->x);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_ywwx() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->y, this->w, this->w, this->x);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_zwwx() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->z, this->w, this->w, this->x);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_wwwx() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->w, this->w, this->w, this->x);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_xxxy() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->x, this->x, this->x, this->y);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_yxxy() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->y, this->x, this->x, this->y);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_zxxy() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->z, this->x, this->x, this->y);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_wxxy() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->w, this->x, this->x, this->y);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_xyxy() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->x, this->y, this->x, this->y);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_yyxy() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->y, this->y, this->x, this->y);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_zyxy() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->z, this->y, this->x, this->y);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_wyxy() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->w, this->y, this->x, this->y);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_xzxy() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->x, this->z, this->x, this->y);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_yzxy() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->y, this->z, this->x, this->y);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_zzxy() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->z, this->z, this->x, this->y);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_wzxy() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->w, this->z, this->x, this->y);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_xwxy() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->x, this->w, this->x, this->y);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_ywxy() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->y, this->w, this->x, this->y);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_zwxy() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->z, this->w, this->x, this->y);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_wwxy() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->w, this->w, this->x, this->y);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_xxyy() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->x, this->x, this->y, this->y);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_yxyy() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->y, this->x, this->y, this->y);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_zxyy() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->z, this->x, this->y, this->y);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_wxyy() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->w, this->x, this->y, this->y);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_xyyy() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->x, this->y, this->y, this->y);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_yyyy() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->y, this->y, this->y, this->y);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_zyyy() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->z, this->y, this->y, this->y);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_wyyy() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->w, this->y, this->y, this->y);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_xzyy() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->x, this->z, this->y, this->y);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_yzyy() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->y, this->z, this->y, this->y);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_zzyy() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->z, this->z, this->y, this->y);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_wzyy() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->w, this->z, this->y, this->y);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_xwyy() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->x, this->w, this->y, this->y);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_ywyy() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->y, this->w, this->y, this->y);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_zwyy() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->z, this->w, this->y, this->y);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_wwyy() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->w, this->w, this->y, this->y);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_xxzy() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->x, this->x, this->z, this->y);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_yxzy() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->y, this->x, this->z, this->y);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_zxzy() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->z, this->x, this->z, this->y);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_wxzy() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->w, this->x, this->z, this->y);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_xyzy() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->x, this->y, this->z, this->y);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_yyzy() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->y, this->y, this->z, this->y);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_zyzy() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->z, this->y, this->z, this->y);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_wyzy() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->w, this->y, this->z, this->y);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_xzzy() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->x, this->z, this->z, this->y);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_yzzy() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->y, this->z, this->z, this->y);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_zzzy() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->z, this->z, this->z, this->y);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_wzzy() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->w, this->z, this->z, this->y);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_xwzy() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->x, this->w, this->z, this->y);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_ywzy() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->y, this->w, this->z, this->y);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_zwzy() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->z, this->w, this->z, this->y);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_wwzy() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->w, this->w, this->z, this->y);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_xxwy() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->x, this->x, this->x, this->x);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_yxwy() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->y, this->x, this->w, this->y);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_zxwy() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->z, this->x, this->w, this->y);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_wxwy() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->w, this->x, this->w, this->y);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_xywy() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->x, this->y, this->w, this->y);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_yywy() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->y, this->y, this->w, this->y);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_zywy() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->z, this->y, this->w, this->y);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_wywy() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->w, this->y, this->w, this->y);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_xzwy() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->x, this->z, this->w, this->y);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_yzwy() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->y, this->z, this->w, this->y);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_zzwy() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->z, this->z, this->w, this->y);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_wzwy() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->w, this->z, this->w, this->y);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_xwwy() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->x, this->w, this->w, this->y);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_ywwy() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->y, this->w, this->w, this->y);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_zwwy() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->z, this->w, this->w, this->y);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_wwwy() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->w, this->w, this->w, this->y);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_xxxz() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->x, this->x, this->x, this->z);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_yxxz() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->y, this->x, this->x, this->z);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_zxxz() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->z, this->x, this->x, this->z);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_wxxz() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->w, this->x, this->x, this->z);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_xyxz() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->x, this->y, this->x, this->z);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_yyxz() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->y, this->y, this->x, this->z);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_zyxz() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->z, this->y, this->x, this->z);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_wyxz() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->w, this->y, this->x, this->z);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_xzxz() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->x, this->z, this->x, this->z);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_yzxz() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->y, this->z, this->x, this->z);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_zzxz() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->z, this->z, this->x, this->z);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_wzxz() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->w, this->z, this->x, this->z);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_xwxz() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->x, this->w, this->x, this->z);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_ywxz() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->y, this->w, this->x, this->z);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_zwxz() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->z, this->w, this->x, this->z);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_wwxz() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->w, this->w, this->x, this->z);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_xxyz() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->x, this->x, this->y, this->z);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_yxyz() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->y, this->x, this->y, this->z);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_zxyz() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->z, this->x, this->y, this->z);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_wxyz() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->w, this->x, this->y, this->z);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_xyyz() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->x, this->y, this->y, this->z);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_yyyz() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->y, this->y, this->y, this->z);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_zyyz() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->z, this->y, this->y, this->z);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_wyyz() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->w, this->y, this->y, this->z);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_xzyz() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->x, this->z, this->y, this->z);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_yzyz() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->y, this->z, this->y, this->z);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_zzyz() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->z, this->z, this->y, this->z);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_wzyz() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->w, this->z, this->x, this->z);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_xwyz() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->x, this->w, this->y, this->z);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_ywyz() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->y, this->w, this->y, this->z);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_zwyz() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->z, this->w, this->y, this->z);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_wwyz() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->w, this->w, this->y, this->z);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_xxzz() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->x, this->x, this->z, this->z);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_yxzz() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->y, this->x, this->z, this->z);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_zxzz() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->z, this->x, this->z, this->z);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_wxzz() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->w, this->x, this->z, this->z);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_xyzz() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->x, this->y, this->z, this->z);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_yyzz() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->y, this->y, this->z, this->z);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_zyzz() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->z, this->y, this->z, this->z);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_wyzz() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->w, this->y, this->z, this->z);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_xzzz() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->x, this->z, this->z, this->z);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_yzzz() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->y, this->z, this->z, this->z);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_zzzz() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->z, this->z, this->z, this->z);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_wzzz() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->w, this->z, this->z, this->z);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_xwzz() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->x, this->w, this->z, this->z);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_ywzz() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->y, this->w, this->z, this->z);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_zwzz() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->z, this->w, this->z, this->z);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_wwzz() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->w, this->w, this->z, this->z);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_xxwz() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->x, this->x, this->w, this->z);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_yxwz() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->y, this->x, this->w, this->z);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_zxwz() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->z, this->x, this->w, this->z);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_wxwz() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->w, this->x, this->w, this->z);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_xywz() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->x, this->y, this->w, this->z);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_yywz() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->y, this->y, this->w, this->z);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_zywz() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->z, this->y, this->w, this->z);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_wywz() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->w, this->y, this->w, this->z);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_xzwz() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->x, this->z, this->w, this->z);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_yzwz() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->y, this->z, this->w, this->z);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_zzwz() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->z, this->z, this->w, this->z);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_wzwz() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->w, this->z, this->w, this->z);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_xwwz() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->x, this->w, this->w, this->z);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_ywwz() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->y, this->w, this->w, this->z);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_zwwz() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->z, this->w, this->w, this->z);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_wwwz() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->w, this->w, this->w, this->z);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_xxxw() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->x, this->x, this->x, this->w);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_yxxw() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->y, this->x, this->x, this->w);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_zxxw() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->z, this->x, this->x, this->w);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_wxxw() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->w, this->x, this->x, this->w);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_xyxw() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->x, this->y, this->x, this->w);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_yyxw() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->y, this->y, this->x, this->w);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_zyxw() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->z, this->y, this->x, this->w);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_wyxw() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->w, this->y, this->x, this->w);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_xzxw() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->x, this->z, this->x, this->w);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_yzxw() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->y, this->z, this->x, this->w);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_zzxw() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->z, this->z, this->x, this->w);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_wzxw() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->w, this->z, this->x, this->w);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_xwxw() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->x, this->w, this->x, this->w);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_ywxw() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->y, this->w, this->x, this->w);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_zwxw() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->z, this->w, this->x, this->w);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_wwxw() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->w, this->w, this->x, this->w);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_xxyw() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->x, this->x, this->y, this->w);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_yxyw() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->y, this->x, this->y, this->w);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_zxyw() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->z, this->x, this->y, this->w);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_wxyw() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->w, this->x, this->y, this->w);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_xyyw() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->x, this->y, this->y, this->w);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_yyyw() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->y, this->y, this->y, this->w);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_zyyw() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->z, this->y, this->y, this->w);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_wyyw() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->w, this->y, this->y, this->w);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_xzyw() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->x, this->z, this->y, this->w);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_yzyw() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->y, this->z, this->y, this->w);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_zzyw() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->z, this->z, this->y, this->w);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_wzyw() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->w, this->z, this->y, this->w);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_xwyw() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->x, this->w, this->y, this->w);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_ywyw() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->y, this->w, this->y, this->w);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_zwyw() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->z, this->w, this->y, this->w);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_wwyw() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->w, this->w, this->y, this->w);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_xxzw() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->x, this->x, this->z, this->w);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_yxzw() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->y, this->x, this->z, this->w);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_zxzw() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->z, this->x, this->z, this->w);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_wxzw() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->w, this->x, this->z, this->w);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_xyzw() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->x, this->y, this->z, this->w);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_yyzw() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->y, this->y, this->z, this->w);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_zyzw() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->z, this->y, this->z, this->w);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_wyzw() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->w, this->y, this->z, this->w);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_xzzw() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->x, this->z, this->z, this->w);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_yzzw() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->y, this->z, this->z, this->w);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_zzzw() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->z, this->z, this->z, this->w);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_wzzw() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->w, this->z, this->z, this->w);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_xwzw() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->x, this->w, this->z, this->w);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_ywzw() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->y, this->w, this->z, this->w);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_zwzw() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->z, this->w, this->z, this->w);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_wwzw() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->w, this->w, this->z, this->w);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_xxww() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->x, this->x, this->w, this->w);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_yxww() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->y, this->x, this->w, this->w);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_zxww() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->z, this->x, this->w, this->w);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_wxww() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->w, this->x, this->w, this->w);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_xyww() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->x, this->y, this->w, this->w);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_yyww() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->y, this->y, this->w, this->w);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_zyww() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->z, this->y, this->w, this->w);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_wyww() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->w, this->y, this->w, this->w);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_xzww() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->x, this->z, this->w, this->w);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_yzww() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->y, this->z, this->w, this->w);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_zzww() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->z, this->z, this->w, this->w);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_wzww() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->w, this->z, this->w, this->w);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_xwww() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->x, this->w, this->w, this->w);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_ywww() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->y, this->w, this->w, this->w);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_zwww() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->z, this->w, this->w, this->w);
+    }
+
+    template <CVEC4_LIST> 
+    inline const VEC4 _cvec4<CVEC4_TYPE>::_wwww() const
+    {
+        return _cvec4<CVEC4_TYPE>(this->w, this->w, this->w, this->w);
+    }
+#endif //defined(GLM_SWIZZLE)
+
+} //namespace detail
+} //namespace glm
+
+#endif//__cvec4_inl__

+ 54 - 0
experimental/sse/glm/core/_cvecx.h

@@ -0,0 +1,54 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2007 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2007-01-15
+// Updated : 2007-01-19
+// Licence : This source is under GNU LGPL licence
+// File    : glm/core/_cvecx.h
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef __glm_core_cvecx_h__
+#define __glm_core_cvecx_h__
+
+#define CVEC2_TYPE		T, VEC2, VEC3, VEC4, REF2
+#define CVEC3_TYPE		T, VEC2, VEC3, VEC4, REF2, REF3
+#define CVEC4_TYPE		T, VEC2, VEC3, VEC4, REF2, REF3, REF4
+
+#define CVEC2_LIST		typename T, typename VEC2, typename VEC3, typename VEC4, typename REF2
+#define CVEC3_LIST		typename T, typename VEC2, typename VEC3, typename VEC4, typename REF2, typename REF3
+#define CVEC4_LIST		typename T, typename VEC2, typename VEC3, typename VEC4, typename REF2, typename REF3, typename REF4
+
+#define XVEC2_INST		T, _xvec2<T>, _xvec3<T>, _xvec4<T>, _xref2<T>
+#define XVEC3_INST		T, _xvec2<T>, _xvec3<T>, _xvec4<T>, _xref2<T>, _xref3<T>
+#define XVEC4_INST		T, _xvec2<T>, _xvec3<T>, _xvec4<T>, _xref2<T>, _xref3<T>, _xref4<T>
+
+#define BVEC2_INST		bool, _bvec2, _bvec3, _bvec4, _xref2<bool>
+#define BVEC3_INST		bool, _bvec2, _bvec3, _bvec4, _xref2<bool>, _xref3<bool>
+#define BVEC4_INST		bool, _bvec2, _bvec3, _bvec4, _xref2<bool>, _xref3<bool>, _xref4<bool>
+
+#define HVEC2_INST		hdata, _hvec2GTX, _hvec3GTX, _hvec4GTX, _xref2<hdata>
+#define HVEC3_INST		hdata, _hvec2GTX, _hvec3GTX, _hvec4GTX, _xref2<hdata>, _xref3<hdata>
+#define HVEC4_INST		hdata, _hvec2GTX, _hvec3GTX, _hvec4GTX, _xref2<hdata>, _xref3<hdata>, _xref4<hdata>
+
+#define	_xvec2_base(T)	_cvec2<T, _xvec2<T>, _xvec3<T>, _xvec4<T>, _xref2<T> >
+#define	_xvec3_base(T)	_cvec3<T, _xvec2<T>, _xvec3<T>, _xvec4<T>, _xref2<T>, _xref3<T> >
+#define	_xvec4_base(T)	_cvec4<T, _xvec2<T>, _xvec3<T>, _xvec4<T>, _xref2<T>, _xref3<T>, _xref4<T> >
+
+namespace glm{
+namespace detail{
+
+    template <typename T> class _xref2; //!< \dontinclude 
+	template <typename T> class _xref3; //!< \dontinclude 
+	template <typename T> class _xref4; //!< \dontinclude 
+
+	template <typename T> class _xvec2; //!< \dontinclude 
+    template <typename T> class _xvec3; //!< \dontinclude 
+    template <typename T> class _xvec4; //!< \dontinclude 
+
+	class _bvec2; //!< \dontinclude 
+    class _bvec3; //!< \dontinclude 
+    class _bvec4; //!< \dontinclude 
+} //namespace detail
+} //namespace glm
+
+#endif//__glm_core_cvecx_h__

+ 359 - 0
experimental/sse/glm/core/_func.h

@@ -0,0 +1,359 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2008 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2005-01-12
+// Updated : 2007-01-05
+// Licence : This source is under GNU LGPL licence
+// File    : glm/core/_func.h
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef __glm_func__
+#define __glm_func__
+
+#include "./_xvec2.h"
+#include "./_xvec3.h"
+#include "./_xvec4.h"
+#include "./_bvec2.h"
+#include "./_bvec3.h"
+#include "./_bvec4.h"
+#include "./_xmat2.h"
+#include "./_xmat3.h"
+#include "./_xmat4.h"
+#include "./_xmat2x3.h"
+#include "./_xmat3x2.h"
+#include "./_xmat2x4.h"
+#include "./_xmat4x2.h"
+#include "./_xmat3x4.h"
+#include "./_xmat4x3.h"
+/*
+#ifdef WIN32
+#pragma warning (disable : 4244)
+#endif //WIN32
+*/
+namespace glm
+{
+    ////////////////////////////////////////////////////////////////////////
+    // Trigonometric Functions
+
+    template <typename T> T radians(T degrees); //!< \brief Converts degrees to radians and returns the result. (From GLSL 1.10.59 specification)
+	template <typename T> detail::_xvec2<T> radians(const detail::_xvec2<T>& degrees); //!< \brief Converts degrees to radians and returns the result. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec3<T> radians(const detail::_xvec3<T>& degrees); //!< \brief Converts degrees to radians and returns the result. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec4<T> radians(const detail::_xvec4<T>& degrees); //!< \brief Converts degrees to radians and returns the result. (From GLSL 1.10.59 specification)
+
+    template <typename T> T degrees(T radians); //!< \brief Converts radians to degrees and returns the result. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec2<T> degrees(const detail::_xvec2<T>& radians); //!< \brief Converts radians to degrees and returns the result. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec3<T> degrees(const detail::_xvec3<T>& radians); //!< \brief Converts radians to degrees and returns the result. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec4<T> degrees(const detail::_xvec4<T>& radians); //!< \brief Converts radians to degrees and returns the result. (From GLSL 1.10.59 specification)
+
+    template <typename T> T sin(T angle); //!< \brief The standard trigonometric sine function. The values returned by this function will range from [-1, 1]. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec2<T> sin(const detail::_xvec2<T>& angle); //!< \brief The standard trigonometric sine function. The values returned by this function will range from [-1, 1]. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec3<T> sin(const detail::_xvec3<T>& angle); //!< \brief The standard trigonometric sine function. The values returned by this function will range from [-1, 1]. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec4<T> sin(const detail::_xvec4<T>& angle); //!< \brief The standard trigonometric sine function. The values returned by this function will range from [-1, 1]. (From GLSL 1.10.59 specification)
+
+    template <typename T> T cos(T angle); //!< \brief The standard trigonometric cosine function. The values returned by this function will range from [-1, 1]. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec2<T> cos(const detail::_xvec2<T>& angle); //!< \brief The standard trigonometric cosine function. The values returned by this function will range from [-1, 1]. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec3<T> cos(const detail::_xvec3<T>& angle); //!< \brief The standard trigonometric cosine function. The values returned by this function will range from [-1, 1]. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec4<T> cos(const detail::_xvec4<T>& angle); //!< \brief The standard trigonometric cosine function. The values returned by this function will range from [-1, 1]. (From GLSL 1.10.59 specification)
+
+    template <typename T> T tan(T angle); //!< \brief The standard trigonometric tangent function. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec2<T> tan(const detail::_xvec2<T>& angle); //!< \brief The standard trigonometric tangent function. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec3<T> tan(const detail::_xvec3<T>& angle); //!< \brief The standard trigonometric tangent function. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec4<T> tan(const detail::_xvec4<T>& angle); //!< \brief The standard trigonometric tangent function. (From GLSL 1.10.59 specification)
+
+    template <typename T> T asin(T x); //!< \brief 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. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec2<T> asin(const detail::_xvec2<T>& x); //!< \brief 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. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec3<T> asin(const detail::_xvec3<T>& x); //!< \brief 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. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec4<T> asin(const detail::_xvec4<T>& x); //!< \brief 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. (From GLSL 1.10.59 specification)
+
+    template <typename T> T acos(T x); //!< \brief 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. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec2<T> acos(const detail::_xvec2<T>& x); //!< \brief 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. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec3<T> acos(const detail::_xvec3<T>& x); //!< \brief 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. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec4<T> acos(const detail::_xvec4<T>& x); //!< \brief 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. (From GLSL 1.10.59 specification)
+
+    template <typename T> T atan(T y, T x); //!< \brief 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. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec2<T> atan(const detail::_xvec2<T>& y, const detail::_xvec2<T>& x); //!< \brief 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. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec3<T> atan(const detail::_xvec3<T>& y, const detail::_xvec3<T>& x); //!< \brief 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. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec4<T> atan(const detail::_xvec4<T>& y, const detail::_xvec4<T>& x); //!< \brief 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. (From GLSL 1.10.59 specification)
+
+    template <typename T> T atan(T y_over_x); //!< \brief Arc tangent. Returns an angle whose tangent is y_over_x. The range of values returned by this function is [-PI/2, PI/2]. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec2<T> atan(const detail::_xvec2<T>& y_over_x); //!< \brief Arc tangent. Returns an angle whose tangent is y_over_x. The range of values returned by this function is [-PI/2, PI/2]. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec3<T> atan(const detail::_xvec3<T>& y_over_x); //!< \brief Arc tangent. Returns an angle whose tangent is y_over_x. The range of values returned by this function is [-PI/2, PI/2]. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec4<T> atan(const detail::_xvec4<T>& y_over_x); //!< \brief Arc tangent. Returns an angle whose tangent is y_over_x. The range of values returned by this function is [-PI/2, PI/2]. (From GLSL 1.10.59 specification)
+
+    ////////////////////////////////////////////////////////////////////////
+    // Exponential Functions
+
+    template <typename T> T pow(T x, T y); //!< \brief Returns x raised to the y power. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec2<T> pow(const detail::_xvec2<T>& x, const detail::_xvec2<T>& y); //!< \brief Returns x raised to the y power. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec3<T> pow(const detail::_xvec3<T>& x, const detail::_xvec3<T>& y); //!< \brief Returns x raised to the y power. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec4<T> pow(const detail::_xvec4<T>& x, const detail::_xvec4<T>& y); //!< \brief Returns x raised to the y power. (From GLSL 1.10.59 specification)
+
+    template <typename T> T exp(T x); //!< \brief Returns the natural exponentiation of x, i.e., e^x. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec2<T> exp(const detail::_xvec2<T>& x); //!< \brief Returns the natural exponentiation of x, i.e., e^x. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec3<T> exp(const detail::_xvec3<T>& x); //!< \brief Returns the natural exponentiation of x, i.e., e^x. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec4<T> exp(const detail::_xvec4<T>& x); //!< \brief Returns the natural exponentiation of x, i.e., e^x. (From GLSL 1.10.59 specification)
+
+    template <typename T> T log(T x); //!< \brief Returns the natural logarithm of x, i.e., returns the value y which satisfies the equation x = e^y. Results are undefined if x <= 0. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec2<T> log(const detail::_xvec2<T>& x); //!< \brief Returns the natural logarithm of x, i.e., returns the value y which satisfies the equation x = e^y. Results are undefined if x <= 0. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec3<T> log(const detail::_xvec3<T>& x); //!< \brief Returns the natural logarithm of x, i.e., returns the value y which satisfies the equation x = e^y. Results are undefined if x <= 0. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec4<T> log(const detail::_xvec4<T>& x); //!< \brief Returns the natural logarithm of x, i.e., returns the value y which satisfies the equation x = e^y. Results are undefined if x <= 0. (From GLSL 1.10.59 specification)
+
+    template <typename T> T exp2(T x); //!< \brief Returns 2 raised to the x power. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec2<T> exp2(const detail::_xvec2<T>& x); //!< \brief Returns 2 raised to the x power. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec3<T> exp2(const detail::_xvec3<T>& x); //!< \brief Returns 2 raised to the x power. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec4<T> exp2(const detail::_xvec4<T>& x); //!< \brief Returns 2 raised to the x power. (From GLSL 1.10.59 specification)
+
+    template <typename T> T log2(T x); //!< \brief Returns the base 2 log of x, i.e., returns the value y, which satisfies the equation x = 2 ^ y. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec2<T> log2(const detail::_xvec2<T>& x); //!< \brief Returns the base 2 log of x, i.e., returns the value y, which satisfies the equation x = 2 ^ y. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec3<T> log2(const detail::_xvec3<T>& x); //!< \brief Returns the base 2 log of x, i.e., returns the value y, which satisfies the equation x = 2 ^ y. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec4<T> log2(const detail::_xvec4<T>& x); //!< \brief Returns the base 2 log of x, i.e., returns the value y, which satisfies the equation x = 2 ^ y. (From GLSL 1.10.59 specification)
+
+    template <typename T> T sqrt(T x); //!< \brief Returns the positive square root of x. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec2<T> sqrt(const detail::_xvec2<T>& x); //!< \brief Returns the positive square root of x. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec3<T> sqrt(const detail::_xvec3<T>& x); //!< \brief Returns the positive square root of x. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec4<T> sqrt(const detail::_xvec4<T>& x); //!< \brief Returns the positive square root of x. (From GLSL 1.10.59 specification)
+    
+    template <typename T> T inversesqrt(T x); //!< \brief Returns the reciprocal of the positive square root of x. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec2<T> inversesqrt(const detail::_xvec2<T>& x); //!< \brief Returns the reciprocal of the positive square root of x. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec3<T> inversesqrt(const detail::_xvec3<T>& x); //!< \brief Returns the reciprocal of the positive square root of x. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec4<T> inversesqrt(const detail::_xvec4<T>& x); //!< \brief Returns the reciprocal of the positive square root of x. (From GLSL 1.10.59 specification)
+
+    ////////////////////////////////////////////////////////////////////////
+    // Common Functions
+
+    template <typename T> T abs(T x); //!< \brief Returns x if x >= 0; otherwise, it returns -x. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec2<T> abs(const detail::_xvec2<T>& x); //!< \brief Returns x if x >= 0; otherwise, it returns -x. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec3<T> abs(const detail::_xvec3<T>& x); //!< \brief Returns x if x >= 0; otherwise, it returns -x. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec4<T> abs(const detail::_xvec4<T>& x); //!< \brief Returns x if x >= 0; otherwise, it returns -x. (From GLSL 1.10.59 specification)
+
+    template <typename T> T sign(T x); //!< \brief Returns 1.0 if x > 0, 0.0 if x = 0, or -1.0 if x < 0. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec2<T> sign(const detail::_xvec2<T>& x); //!< \brief Returns 1.0 if x > 0, 0.0 if x = 0, or -1.0 if x < 0. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec3<T> sign(const detail::_xvec3<T>& x); //!< \brief Returns 1.0 if x > 0, 0.0 if x = 0, or -1.0 if x < 0. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec4<T> sign(const detail::_xvec4<T>& x); //!< \brief Returns 1.0 if x > 0, 0.0 if x = 0, or -1.0 if x < 0. (From GLSL 1.10.59 specification)
+
+    template <typename T> T floor(T x); //!< \brief Returns a value equal to the nearest integer that is less then or equal to x. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec2<T> floor(const detail::_xvec2<T>& x); //!< \brief Returns a value equal to the nearest integer that is less then or equal to x. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec3<T> floor(const detail::_xvec3<T>& x); //!< \brief Returns a value equal to the nearest integer that is less then or equal to x. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec4<T> floor(const detail::_xvec4<T>& x); //!< \brief Returns a value equal to the nearest integer that is less then or equal to x. (From GLSL 1.10.59 specification)
+
+    template <typename T> T ceil(T x); //!< \brief Returns a value equal to the nearest integer that is greater than or equal to x. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec2<T> ceil(const detail::_xvec2<T>& x); //!< \brief Returns a value equal to the nearest integer that is greater than or equal to x. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec3<T> ceil(const detail::_xvec3<T>& x); //!< \brief Returns a value equal to the nearest integer that is greater than or equal to x. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec4<T> ceil(const detail::_xvec4<T>& x); //!< \brief Returns a value equal to the nearest integer that is greater than or equal to x. (From GLSL 1.10.59 specification)
+
+    template <typename T> T fract(T x); //!< \brief Return x - floor(x). (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec2<T> fract(const detail::_xvec2<T>& x); //!< \brief Return x - floor(x). (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec3<T> fract(const detail::_xvec3<T>& x); //!< \brief Return x - floor(x). (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec4<T> fract(const detail::_xvec4<T>& x); //!< \brief Return x - floor(x). (From GLSL 1.10.59 specification)
+
+    template <typename T> T mod(T x, T y);																	//!< \brief Modulus. Returns x - y * floor(x / y) for each component in x using the floating point value y. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec2<T> mod(const detail::_xvec2<T>& x, T y);							//!< \brief Modulus. Returns x - y * floor(x / y) for each component in x using the floating point value y. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec3<T> mod(const detail::_xvec3<T>& x, T y);							//!< \brief Modulus. Returns x - y * floor(x / y) for each component in x using the floating point value y. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec4<T> mod(const detail::_xvec4<T>& x, T y);							//!< \brief Modulus. Returns x - y * floor(x / y) for each component in x using the floating point value y. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec2<T> mod(const detail::_xvec2<T>& x, const detail::_xvec2<T>& y);	//!< \brief Modulus. Returns x - y * floor(x / y) for each component in x using the corresponding component of y. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec3<T> mod(const detail::_xvec3<T>& x, const detail::_xvec3<T>& y);	//!< \brief Modulus. Returns x - y * floor(x / y) for each component in x using the corresponding component of y. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec4<T> mod(const detail::_xvec4<T>& x, const detail::_xvec4<T>& y);	//!< \brief Modulus. Returns x - y * floor(x / y) for each component in x using the corresponding component of y. (From GLSL 1.10.59 specification)
+
+    template <typename T> T min(T x, T y); //!< \brief Returns y if y < x; otherwise, it returns x. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec2<T> min(const detail::_xvec2<T>& x, T y); //!< \brief Returns y if y < x; otherwise, it returns x. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec3<T> min(const detail::_xvec3<T>& x, T y); //!< \brief Returns y if y < x; otherwise, it returns x. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec4<T> min(const detail::_xvec4<T>& x, T y); //!< \brief Returns y if y < x; otherwise, it returns x. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec2<T> min(const detail::_xvec2<T>& x, const detail::_xvec2<T>& y); //!< \brief Returns minimum of each component of x compared with the floating-point value y. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec3<T> min(const detail::_xvec3<T>& x, const detail::_xvec3<T>& y); //!< \brief Returns minimum of each component of x compared with the floating-point value y. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec4<T> min(const detail::_xvec4<T>& x, const detail::_xvec4<T>& y); //!< \brief Returns minimum of each component of x compared with the floating-point value y. (From GLSL 1.10.59 specification)
+
+    template <typename T> T max(T x, T y); //!< \brief Returns y if x < y; otherwise, it returns x. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec2<T> max(const detail::_xvec2<T>& x, T y); //!< \brief Returns y if x < y; otherwise, it returns x. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec3<T> max(const detail::_xvec3<T>& x, T y); //!< \brief Returns y if x < y; otherwise, it returns x. (From GLSL 1.10.59 specification) 
+    template <typename T> detail::_xvec4<T> max(const detail::_xvec4<T>& x, T y); //!< \brief Returns y if x < y; otherwise, it returns x. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec2<T> max(const detail::_xvec2<T>& x, const detail::_xvec2<T>& y); //!< \brief Returns maximum of each component of x compared with the floating-point value y. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec3<T> max(const detail::_xvec3<T>& x, const detail::_xvec3<T>& y); //!< \brief Returns maximum of each component of x compared with the floating-point value y. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec4<T> max(const detail::_xvec4<T>& x, const detail::_xvec4<T>& y); //!< \brief Returns maximum of each component of x compared with the floating-point value y. (From GLSL 1.10.59 specification)
+
+    template <typename T> T clamp(T x, T minVal, T maxVal); //!< \brief Returns min(max(x, minVal), maxVal) for each component in x using the floating-point values minVal and maxVal. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec2<T> clamp(const detail::_xvec2<T>& x, T minVal, T maxVal); //!< \brief Returns min(max(x, minVal), maxVal) for each component in x using the floating-point values minVal and maxVal. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec3<T> clamp(const detail::_xvec3<T>& x, T minVal, T maxVal); //!< \brief Returns min(max(x, minVal), maxVal) for each component in x using the floating-point values minVal and maxVal. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec4<T> clamp(const detail::_xvec4<T>& x, T minVal, T maxVal); //!< \brief Returns min(max(x, minVal), maxVal) for each component in x using the floating-point values minVal and maxVal. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec2<T> clamp(const detail::_xvec2<T>& x, const detail::_xvec2<T>& minVal, const detail::_xvec2<T>& maxVal); //!< \brief Returns the component-wise result of min(max(x, minVal), maxVal). (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec3<T> clamp(const detail::_xvec3<T>& x, const detail::_xvec3<T>& minVal, const detail::_xvec3<T>& maxVal); //!< \brief Returns the component-wise result of min(max(x, minVal), maxVal). (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec4<T> clamp(const detail::_xvec4<T>& x, const detail::_xvec4<T>& minVal, const detail::_xvec4<T>& maxVal); //!< \brief Returns the component-wise result of min(max(x, minVal), maxVal). (From GLSL 1.10.59 specification)
+
+	template <typename T, typename U> T mix(const T& x, const T& y, const U& a); // Returns x * (1.0 - a) + y * a, i.e., the linear blend of x and y using the floating-point value a. The value for a is not restricted to the range [0, 1]. (From GLSL 1.10.59 specification)
+/*
+    template <typename T> T mix(T x, T y, T a); //!< \brief Returns x * (1.0 - a) + y * a, i.e., the linear blend of x and y using the floating-point value a. The value for a is not restricted to the range [0, 1]. (From GLSL 1.10.59 specification)
+    template <typename T> _xvec2<T> mix(const _xvec2<T>& x, const _xvec2<T>& y, T a); //!< \brief Returns x * (1.0 - a) + y * a, i.e., the linear blend of x and y using the floating-point value a. The value for a is not restricted to the range [0, 1]. (From GLSL 1.10.59 specification)
+    template <typename T> _xvec3<T> mix(const _xvec3<T>& x, const _xvec3<T>& y, T a); //!< \brief Returns x * (1.0 - a) + y * a, i.e., the linear blend of x and y using the floating-point value a. The value for a is not restricted to the range [0, 1]. (From GLSL 1.10.59 specification)
+    template <typename T> _xvec4<T> mix(const _xvec4<T>& x, const _xvec4<T>& y, T a); //!< \brief Returns x * (1.0 - a) + y * a, i.e., the linear blend of x and y using the floating-point value a. The value for a is not restricted to the range [0, 1]. (From GLSL 1.10.59 specification)
+    template <typename T> _xvec2<T> mix(const _xvec2<T>& x, const _xvec2<T>& y, const _xvec2<T>& a); //!< \brief Returns the component-wise result of x * (1.0 - a) + y * a, i.e., the linear blend of x and y using vector a. The value for a is not restricted to the range [0, 1]. (From GLSL 1.10.59 specification)
+    template <typename T> _xvec3<T> mix(const _xvec3<T>& x, const _xvec3<T>& y, const _xvec3<T>& a); //!< \brief Returns the component-wise result of x * (1.0 - a) + y * a, i.e., the linear blend of x and y using vector a. The value for a is not restricted to the range [0, 1]. (From GLSL 1.10.59 specification)
+    template <typename T> _xvec4<T> mix(const _xvec4<T>& x, const _xvec4<T>& y, const _xvec4<T>& a); //!< \brief Returns the component-wise result of x * (1.0 - a) + y * a, i.e., the linear blend of x and y using vector a. The value for a is not restricted to the range [0, 1]. (From GLSL 1.10.59 specification)
+*/
+    template <typename T> T step(T edge, T x); //!< \brief Returns 0.0 if x <= edge; otherwise, it returns 1.0. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec2<T> step(T edge, const detail::_xvec2<T>& x); //!< \brief Returns 0.0 if x <= edge; otherwise, it returns 1.0. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec3<T> step(T edge, const detail::_xvec3<T>& x); //!< \brief Returns 0.0 if x <= edge; otherwise, it returns 1.0. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec4<T> step(T edge, const detail::_xvec4<T>& x); //!< \brief Returns 0.0 if x <= edge; otherwise, it returns 1.0. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec2<T> step(const detail::_xvec2<T>& edge, const detail::_xvec2<T>& x); //!< \brief Returns 0.0 if x <= edge; otherwise, it returns 1.0. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec3<T> step(const detail::_xvec3<T>& edge, const detail::_xvec3<T>& x); //!< \brief Returns 0.0 if x <= edge; otherwise, it returns 1.0. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec4<T> step(const detail::_xvec4<T>& edge, const detail::_xvec4<T>& x); //!< \brief Returns 0.0 if x <= edge; otherwise, it returns 1.0. (From GLSL 1.10.59 specification)
+
+    template <typename T> T smoothstep(T edge0, T edge1, T x); //!< \brief 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. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec2<T> smoothstep(T edge0, T edge1, const detail::_xvec2<T>& x); //!< \brief 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. (From GLSL 1.10.59 specification) 
+    template <typename T> detail::_xvec3<T> smoothstep(T edge0, T edge1, const detail::_xvec3<T>& x); //!< \brief 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. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec4<T> smoothstep(T edge0, T edge1, const detail::_xvec4<T>& x); //!< \brief 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. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec2<T> smoothstep(const detail::_xvec2<T>& edge0, const detail::_xvec2<T>& edge1, const detail::_xvec2<T>& x); //!< \brief 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. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec3<T> smoothstep(const detail::_xvec3<T>& edge0, const detail::_xvec3<T>& edge1, const detail::_xvec3<T>& x); //!< \brief 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. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec4<T> smoothstep(const detail::_xvec4<T>& edge0, const detail::_xvec4<T>& edge1, const detail::_xvec4<T>& x); //!< \brief 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. (From GLSL 1.10.59 specification)
+
+    ////////////////////////////////////////////////////////////////////////
+    // Geometric Functions
+
+    template <typename T> T length(T x); //!< \brief Returns the length of x, i.e., sqrt(x * x). (From GLSL 1.10.59 specification)
+    template <typename T> T length(const detail::_xvec2<T>& x); //!< \brief Returns the length of x, i.e., sqrt(x[0] * x[0] + x[1] * x[1]). (From GLSL 1.10.59 specification)
+    template <typename T> T length(const detail::_xvec3<T>& x); //!< \brief Returns the length of x, i.e., sqrt(x[0] * x[0] + x[1] * x[1] + x[2] * x[2]). (From GLSL 1.10.59 specification)
+    template <typename T> T length(const detail::_xvec4<T>& x); //!< \brief Returns the length of x, i.e., sqrt(x[0] * x[0] + x[1] * x[1] + x[2] * x[2] + x[3] * x[3]). (From GLSL 1.10.59 specification)
+
+    template <typename T> T distance(const T p0, const T p1); //!< \brief Returns the distance betwwen p0 and p1, i.e., length(p0 - p1). (From GLSL 1.10.59 specification)
+    template <typename T> T distance(const detail::_xvec2<T>& p0, const detail::_xvec2<T>& p1); //!< \brief Returns the distance betwwen p0 and p1, i.e., length(p0 - p1). (From GLSL 1.10.59 specification)
+    template <typename T> T distance(const detail::_xvec3<T>& p0, const detail::_xvec3<T>& p1); //!< \brief Returns the distance betwwen p0 and p1, i.e., length(p0 - p1). (From GLSL 1.10.59 specification)
+    template <typename T> T distance(const detail::_xvec4<T>& p0, const detail::_xvec4<T>& p1); //!< \brief Returns the distance betwwen p0 and p1, i.e., length(p0 - p1). (From GLSL 1.10.59 specification)
+	//template <typename genType> valType distance(const genType& p0, const genType& p1); //!< \brief Returns the distance betwwen p0 and p1, i.e., length(p0 - p1). (From GLSL 1.10.59 specification)
+
+    template <typename T> T dot(T v1, T v2); //!< \brief Returns the dot product of x and y, i.e., result = x * y. (From GLSL 1.10.59 specification)
+    template <typename T> T dot(const detail::_xvec2<T>& x, const detail::_xvec2<T>& y); //!< \brief Returns the dot product of x and y, i.e., result = x[0] * y[0] + x[1] * y[1]. (From GLSL 1.10.59 specification)
+    template <typename T> T dot(const detail::_xvec3<T>& x, const detail::_xvec3<T>& y); //!< \brief Returns the dot product of x and y, i.e., result = x[0] * y[0] + x[1] * y[1] + x[2] * y[2]. (From GLSL 1.10.59 specification)
+    template <typename T> T dot(const detail::_xvec4<T>& x, const detail::_xvec4<T>& y); //!< \brief Returns the dot product of x and y, i.e., result = x[0] * y[0] + x[1] * y[1] + x[2] * y[2] + x[3] * y[3]. (From GLSL 1.10.59 specification)
+
+    template <typename T> detail::_xvec3<T> cross(const detail::_xvec3<T>& x, const detail::_xvec3<T>& y); //!< brief Returns the cross product of x and y. (From GLSL 1.10.59 specification)
+
+	template <typename T> T normalize(T x); //!< \brief Returns a vector in the same direction as x but with length of 1. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec2<T> normalize(const detail::_xvec2<T>& x); //!< \brief Returns a vector in the same direction as x but with length of 1. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec3<T> normalize(const detail::_xvec3<T>& x); //!< \brief Returns a vector in the same direction as x but with length of 1. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec4<T> normalize(const detail::_xvec4<T>& x); //!< \brief Returns a vector in the same direction as x but with length of 1. (From GLSL 1.10.59 specification)
+
+	//template <typename T, typename genType> genType faceforward(const genType& N, const genType& I, const genType& Nref); //!< \brief If dot(Nref, I) < 0.0, return N, otherwise, return -N. (From GLSL 1.10.59 specification) 
+    template <typename T> T faceforward(T N, T I, T Nref); //!< \brief If dot(Nref, I) < 0.0, return N, otherwise, return -N. (From GLSL 1.10.59 specification) 
+    template <typename T> detail::_xvec2<T> faceforward(const detail::_xvec2<T>& N, const detail::_xvec2<T>& I, const detail::_xvec2<T>& Nref); //!< \brief If dot(Nref, I) < 0.0, return N, otherwise, return -N. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec3<T> faceforward(const detail::_xvec3<T>& N, const detail::_xvec3<T>& I, const detail::_xvec3<T>& Nref); //!< \brief If dot(Nref, I) < 0.0, return N, otherwise, return -N. (From GLSL 1.10.59 specification) 
+    template <typename T> detail::_xvec4<T> faceforward(const detail::_xvec4<T>& N, const detail::_xvec4<T>& I, const detail::_xvec4<T>& Nref); //!< \brief If dot(Nref, I) < 0.0, return N, otherwise, return -N. (From GLSL 1.10.59 specification) 
+  
+	//template <typename T, typename genType> genType reflect(const genType& I, const genType& N); //!< \brief For the incident vector I and surface orientation N, returns the reflection direction : result = I - 2.0 * dot(N, I) * N. (From GLSL 1.10.59 specification)
+    template <typename T> T reflect(T I, T N); //!< \brief For the incident vector I and surface orientation N, returns the reflection direction : result = I - 2.0 * dot(N, I) * N. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec2<T> reflect(const detail::_xvec2<T>& I, const detail::_xvec2<T>& N); //!< \brief For the incident vector I and surface orientation N, returns the reflection direction : result = I - 2.0 * dot(N, I) * N. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec3<T> reflect(const detail::_xvec3<T>& I, const detail::_xvec3<T>& N); //!< \brief For the incident vector I and surface orientation N, returns the reflection direction : result = I - 2.0 * dot(N, I) * N. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec4<T> reflect(const detail::_xvec4<T>& I, const detail::_xvec4<T>& N); //!< \brief For the incident vector I and surface orientation N, returns the reflection direction : result = I - 2.0 * dot(N, I) * N. (From GLSL 1.10.59 specification)
+  
+    template <typename T> T refract(T I, T N, T eta); //!< \brief For the incident vector I and surface normal N, and the ratio of indices of refraction eta, return the refraction vector. (From GLSL 1.10.59 specification)  
+    template <typename T> detail::_xvec2<T> refract(const detail::_xvec2<T>& I, const detail::_xvec2<T>& N, T eta); //!< \brief For the incident vector I and surface normal N, and the ratio of indices of refraction eta, return the refraction vector. (From GLSL 1.10.59 specification) 
+    template <typename T> detail::_xvec3<T> refract(const detail::_xvec3<T>& I, const detail::_xvec3<T>& N, T eta); //!< \brief For the incident vector I and surface normal N, and the ratio of indices of refraction eta, return the refraction vector. (From GLSL 1.10.59 specification) 
+    template <typename T> detail::_xvec4<T> refract(const detail::_xvec4<T>& I, const detail::_xvec4<T>& N, T eta); //!< \brief For the incident vector I and surface normal N, and the ratio of indices of refraction eta, return the refraction vector. (From GLSL 1.10.59 specification) 
+
+    ////////////////////////////////////////////////////////////////////////
+    // Matrix Functions
+
+    template <typename T> detail::_xmat2<T> matrixCompMult(const detail::_xmat2<T>& x, const detail::_xmat2<T>& y); //!< \brief 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]. (From GLSL 1.10.59 specification)  
+    template <typename T> detail::_xmat3<T> matrixCompMult(const detail::_xmat3<T>& x, const detail::_xmat3<T>& y); //!< \brief 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]. (From GLSL 1.10.59 specification)  
+    template <typename T> detail::_xmat4<T> matrixCompMult(const detail::_xmat4<T>& x, const detail::_xmat4<T>& y); //!< \brief 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]. (From GLSL 1.10.59 specification)  
+    template <typename T> detail::_xmat2x3<T> matrixCompMult(const detail::_xmat2x3<T>& x, const detail::_xmat2x3<T>& y); //!< \brief 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]. (From GLSL 1.20.6 specification)  
+    template <typename T> detail::_xmat3x2<T> matrixCompMult(const detail::_xmat3x2<T>& x, const detail::_xmat3x2<T>& y); //!< \brief 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]. (From GLSL 1.20.6 specification)  
+	template <typename T> detail::_xmat2x4<T> matrixCompMult(const detail::_xmat2x4<T>& x, const detail::_xmat2x4<T>& y); //!< \brief 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]. (From GLSL 1.20.6 specification)  
+    template <typename T> detail::_xmat4x2<T> matrixCompMult(const detail::_xmat4x2<T>& x, const detail::_xmat4x2<T>& y); //!< \brief 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]. (From GLSL 1.20.6 specification)  
+	template <typename T> detail::_xmat3x4<T> matrixCompMult(const detail::_xmat3x4<T>& x, const detail::_xmat3x4<T>& y); //!< \brief 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]. (From GLSL 1.20.6 specification)  
+    template <typename T> detail::_xmat4x3<T> matrixCompMult(const detail::_xmat4x3<T>& x, const detail::_xmat4x3<T>& y); //!< \brief 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]. (From GLSL 1.20.6 specification)  
+
+    template <typename T> detail::_xmat2<T> outerProduct(const detail::_xvec2<T>& c, const detail::_xvec2<T>& r); //!< \brief Treats the first parameter c as a column vector and the second parameter r as a row vector and does a linear algebraic matrix multiply c * r. (From GLSL 1.20.6 specification) 
+    template <typename T> detail::_xmat3<T> outerProduct(const detail::_xvec3<T>& c, const detail::_xvec3<T>& r); //!< \brief Treats the first parameter c as a column vector and the second parameter r as a row vector and does a linear algebraic matrix multiply c * r. (From GLSL 1.20.6 specification) 
+    template <typename T> detail::_xmat4<T> outerProduct(const detail::_xvec4<T>& c, const detail::_xvec4<T>& r); //!< \brief Treats the first parameter c as a column vector and the second parameter r as a row vector and does a linear algebraic matrix multiply c * r. (From GLSL 1.20.6 specification) 
+    template <typename T> detail::_xmat2x3<T> outerProduct(const detail::_xvec3<T>& c, const detail::_xvec2<T>& r); //!< \brief Treats the first parameter c as a column vector and the second parameter r as a row vector and does a linear algebraic matrix multiply c * r. (From GLSL 1.20.6 specification) 
+    template <typename T> detail::_xmat3x2<T> outerProduct(const detail::_xvec2<T>& c, const detail::_xvec3<T>& r); //!< \brief Treats the first parameter c as a column vector and the second parameter r as a row vector and does a linear algebraic matrix multiply c * r. (From GLSL 1.20.6 specification) 
+	template <typename T> detail::_xmat2x4<T> outerProduct(const detail::_xvec2<T>& c, const detail::_xvec4<T>& r); //!< \brief Treats the first parameter c as a column vector and the second parameter r as a row vector and does a linear algebraic matrix multiply c * r. (From GLSL 1.20.6 specification) 
+	template <typename T> detail::_xmat4x2<T> outerProduct(const detail::_xvec4<T>& c, const detail::_xvec2<T>& r); //!< \brief Treats the first parameter c as a column vector and the second parameter r as a row vector and does a linear algebraic matrix multiply c * r. (From GLSL 1.20.6 specification) 
+	template <typename T> detail::_xmat3x4<T> outerProduct(const detail::_xvec4<T>& c, const detail::_xvec3<T>& r); //!< \brief Treats the first parameter c as a column vector and the second parameter r as a row vector and does a linear algebraic matrix multiply c * r. (From GLSL 1.20.6 specification) 
+	template <typename T> detail::_xmat4x3<T> outerProduct(const detail::_xvec3<T>& c, const detail::_xvec4<T>& r); //!< \brief Treats the first parameter c as a column vector and the second parameter r as a row vector and does a linear algebraic matrix multiply c * r. (From GLSL 1.20.6 specification) 
+
+    template <typename T> detail::_xmat2<T> transpose(const detail::_xmat2<T>& x); //!< Returns the transposed matrix of x (From GLSL 1.20.6 specification) 
+    template <typename T> detail::_xmat3<T> transpose(const detail::_xmat3<T>& x); //!< Returns the transposed matrix of x (From GLSL 1.20.6 specification) 
+    template <typename T> detail::_xmat4<T> transpose(const detail::_xmat4<T>& x); //!< Returns the transposed matrix of x (From GLSL 1.20.6 specification) 
+    template <typename T> detail::_xmat2x3<T> transpose(const detail::_xmat3x2<T>& x); //!< Returns the transposed matrix of x (From GLSL 1.20.6 specification) 
+    template <typename T> detail::_xmat3x2<T> transpose(const detail::_xmat2x3<T>& x); //!< Returns the transposed matrix of x (From GLSL 1.20.6 specification) 
+    template <typename T> detail::_xmat2x4<T> transpose(const detail::_xmat4x2<T>& x); //!< Returns the transposed matrix of x (From GLSL 1.20.6 specification) 
+    template <typename T> detail::_xmat4x2<T> transpose(const detail::_xmat2x4<T>& x); //!< Returns the transposed matrix of x (From GLSL 1.20.6 specification) 
+    template <typename T> detail::_xmat3x4<T> transpose(const detail::_xmat4x3<T>& x); //!< Returns the transposed matrix of x (From GLSL 1.20.6 specification) 
+    template <typename T> detail::_xmat4x3<T> transpose(const detail::_xmat3x4<T>& x); //!< Returns the transposed matrix of x (From GLSL 1.20.6 specification) 
+
+    ////////////////////////////////////////////////////////////////////////
+    // Vector Relational Functions
+
+	template <typename T> detail::_bvec2 lessThan(const detail::_xvec2<T>& x, const detail::_xvec2<T>& y); //!< \brief Returns the component-wise compare of x < y. (From GLSL 1.10.59 specification)  
+    template <typename T> detail::_bvec3 lessThan(const detail::_xvec3<T>& x, const detail::_xvec3<T>& y); //!< \brief Returns the component-wise compare of x < y. (From GLSL 1.10.59 specification)  
+    template <typename T> detail::_bvec4 lessThan(const detail::_xvec4<T>& x, const detail::_xvec4<T>& y); //!< \brief Returns the component-wise compare of x < y. (From GLSL 1.10.59 specification)
+
+    template <typename T> detail::_bvec2 lessThanEqual(const detail::_xvec2<T>& x, const detail::_xvec2<T>& y); //!< \brief Returns the component-wise compare of x <= y. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_bvec3 lessThanEqual(const detail::_xvec3<T>& x, const detail::_xvec3<T>& y); //!< \brief Returns the component-wise compare of x <= y. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_bvec4 lessThanEqual(const detail::_xvec4<T>& x, const detail::_xvec4<T>& y); //!< \brief Returns the component-wise compare of x <= y. (From GLSL 1.10.59 specification)
+
+    template <typename T> detail::_bvec2 greaterThan(const detail::_xvec2<T>& x, const detail::_xvec2<T>& y); //!< \brief Returns the component-wise compare of x > y. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_bvec3 greaterThan(const detail::_xvec3<T>& x, const detail::_xvec3<T>& y); //!< \brief Returns the component-wise compare of x > y. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_bvec4 greaterThan(const detail::_xvec4<T>& x, const detail::_xvec4<T>& y); //!< \brief Returns the component-wise compare of x > y. (From GLSL 1.10.59 specification)
+
+    template <typename T> detail::_bvec2 greaterThanEqual(const detail::_xvec2<T>& x, const detail::_xvec2<T>& y); //!< \brief Returns the component-wise compare of x >= y. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_bvec3 greaterThanEqual(const detail::_xvec3<T>& x, const detail::_xvec3<T>& y); //!< \brief Returns the component-wise compare of x >= y. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_bvec4 greaterThanEqual(const detail::_xvec4<T>& x, const detail::_xvec4<T>& y); //!< \brief Returns the component-wise compare of x >= y. (From GLSL 1.10.59 specification)
+
+    detail::_bvec2 equal(const detail::_bvec2& x, const detail::_bvec2& y); //!< \brief Returns the component-wise compare of x == y. (From GLSL 1.10.59 specification)
+    detail::_bvec3 equal(const detail::_bvec3& x, const detail::_bvec3& y); //!< \brief Returns the component-wise compare of x == y. (From GLSL 1.10.59 specification)
+    detail::_bvec4 equal(const detail::_bvec4& x, const detail::_bvec4& y); //!< \brief Returns the component-wise compare of x == y. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_bvec2 equal(const detail::_xvec2<T>& x, const detail::_xvec2<T>& y); //!< \brief Returns the component-wise compare of x == y. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_bvec3 equal(const detail::_xvec3<T>& x, const detail::_xvec3<T>& y); //!< \brief Returns the component-wise compare of x == y. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_bvec4 equal(const detail::_xvec4<T>& x, const detail::_xvec4<T>& y); //!< \brief Returns the component-wise compare of x == y. (From GLSL 1.10.59 specification)
+
+    detail::_bvec2 notEqual(const detail::_bvec2& x, const detail::_bvec2& y); //!< \brief Returns the component-wise compare of x != y. (From GLSL 1.10.59 specification)
+    detail::_bvec3 notEqual(const detail::_bvec3& x, const detail::_bvec3& y); //!< \brief Returns the component-wise compare of x != y. (From GLSL 1.10.59 specification)
+    detail::_bvec4 notEqual(const detail::_bvec4& x, const detail::_bvec4& y); //!< \brief Returns the component-wise compare of x != y. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_bvec2 notEqual(const detail::_xvec2<T>& x, const detail::_xvec2<T>& y); //!< \brief Returns the component-wise compare of x != y. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_bvec3 notEqual(const detail::_xvec3<T>& x, const detail::_xvec3<T>& y); //!< \brief Returns the component-wise compare of x != y. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_bvec4 notEqual(const detail::_xvec4<T>& x, const detail::_xvec4<T>& y); //!< \brief Returns the component-wise compare of x != y. (From GLSL 1.10.59 specification)
+
+    bool any(const detail::_bvec2& x); //!< \brief Returns true if any component of x is true. (From GLSL 1.10.59 specification)
+    bool any(const detail::_bvec3& x); //!< \brief Returns true if any component of x is true. (From GLSL 1.10.59 specification)
+    bool any(const detail::_bvec4& x); //!< \brief Returns true if any component of x is true. (From GLSL 1.10.59 specification)
+
+    bool all(const detail::_bvec2& x); //!< \brief Returns true if all component of x is true. (From GLSL 1.10.59 specification)
+    bool all(const detail::_bvec3& x); //!< \brief Returns true if all component of x is true. (From GLSL 1.10.59 specification)
+    bool all(const detail::_bvec4& x); //!< \brief Returns true if all component of x is true. (From GLSL 1.10.59 specification)
+
+#if (defined(GLM_COMPILER) && GLM_COMPILER & GLM_COMPILER_VC) // VC compiler doesn't support the C++ key word 'not'
+    bool not(bool x); //!< \brief Returns the component-wise logical complement of x. (From GLSL 1.10.59 specification)
+    detail::_bvec2 not(const detail::_bvec2& v); //!< \brief Returns the component-wise logical complement of x. (From GLSL 1.10.59 specification)
+    detail::_bvec3 not(const detail::_bvec3& v); //!< \brief Returns the component-wise logical complement of x. (From GLSL 1.10.59 specification)
+    detail::_bvec4 not(const detail::_bvec4& v); //!< \brief Returns the component-wise logical complement of x. (From GLSL 1.10.59 specification)
+#elif (defined(GLM_COMPILER) && GLM_COMPILER & GLM_COMPILER_GCC) // GCC
+    detail::_bvec2 operator not(const detail::_bvec2& v); //!< \brief Returns the component-wise logical complement of x. (From GLSL 1.10.59 specification)
+    detail::_bvec3 operator not(const detail::_bvec3& v); //!< \brief Returns the component-wise logical complement of x. (From GLSL 1.10.59 specification)
+    detail::_bvec4 operator not(const detail::_bvec4& v); //!< \brief Returns the component-wise logical complement of x. (From GLSL 1.10.59 specification)
+#endif
+
+    ////////////////////////////////////////////////////////////////////////
+    // Noise Functions
+
+    template <typename T> T noise1(T x); //!< \brief Returns a 1D noise value based on the input value x. (From GLSL 1.10.59 specification)
+    template <typename T> T noise1(const detail::_xvec2<T>& x); //!< \brief Returns a 1D noise value based on the input value x. (From GLSL 1.10.59 specification)
+    template <typename T> T noise1(const detail::_xvec3<T>& x); //!< \brief Returns a 1D noise value based on the input value x. (From GLSL 1.10.59 specification)
+    template <typename T> T noise1(const detail::_xvec4<T>& x); //!< \brief Returns a 1D noise value based on the input value x. (From GLSL 1.10.59 specification)
+
+    template <typename T> detail::_xvec2<T> noise2(T x); //!< \brief Returns a 2D noise value based on the input value x. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec2<T> noise2(const detail::_xvec2<T>& x); //!< \brief Returns a 2D noise value based on the input value x. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec2<T> noise2(const detail::_xvec3<T>& x); //!< \brief Returns a 2D noise value based on the input value x. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec2<T> noise2(const detail::_xvec4<T>& x); //!< \brief Returns a 2D noise value based on the input value x. (From GLSL 1.10.59 specification)
+
+    template <typename T> detail::_xvec3<T> noise3(T x); //!< \brief Returns a 3D noise value based on the input value x. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec3<T> noise3(const detail::_xvec2<T>& x); //!< \brief Returns a 3D noise value based on the input value x. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec3<T> noise3(const detail::_xvec3<T>& x); //!< \brief Returns a 3D noise value based on the input value x. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec3<T> noise3(const detail::_xvec4<T>& x); //!< \brief Returns a 3D noise value based on the input value x. (From GLSL 1.10.59 specification)
+
+    template <typename T> detail::_xvec4<T> noise4(T x); //!< \brief Returns a 4D noise value based on the input value x. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec4<T> noise4(const detail::_xvec2<T>& x); //!< \brief Returns a 4D noise value based on the input value x. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec4<T> noise4(const detail::_xvec3<T>& x); //!< \brief Returns a 4D noise value based on the input value x. (From GLSL 1.10.59 specification)
+    template <typename T> detail::_xvec4<T> noise4(const detail::_xvec4<T>& x); //!< \brief Returns a 4D noise value based on the input value x. (From GLSL 1.10.59 specification)
+} //namespace glm
+
+#endif //__glm_func__

+ 2247 - 0
experimental/sse/glm/core/_func.inl

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

+ 1742 - 0
experimental/sse/glm/core/_swizzle.h

@@ -0,0 +1,1742 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2008 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2006-04-20
+// Updated : 2006-12-03
+// Licence : This source is under GNU LGPL licence
+// File    : _swizzle.h
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef __swizzle_h__
+#define __swizzle_h__
+
+namespace glm
+{
+
+}
+
+#if defined(GLM_SWIZZLE) && (GLM_SWIZZLE & GLM_SWIZZLE_XYZW)
+
+// 2 components common swizzle operators
+#define xx _xx()
+#define yx _yx()
+#define zx _zx()
+#define wx _wx()
+#define xy _xy()
+#define yy _yy()
+#define zy _zy()
+#define wy _wy()
+#define xz _xz()
+#define yz _yz()
+#define zz _zz()
+#define wz _wz()
+#define xw _xw()
+#define yw _yw()
+#define zw _zw()
+#define ww _ww()
+
+// 3 components common swizzle operators
+#define xxx _xxx()
+#define yxx _yxx()
+#define zxx _zxx()
+#define wxx _wxx()
+#define xyx _xyx()
+#define yyx _yyx()
+#define zyx _zyx()
+#define wyx _wyx()
+#define xzx _xzx()
+#define yzx _yzx()
+#define zzx _zzx()
+#define wzx _wzx()
+#define xwx _xwx()
+#define ywx _ywx()
+#define zwx _zwx()
+#define wwx _wwx()
+#define xxy _xxy()
+#define yxy _yxy()
+#define zxy _zxy()
+#define wxy _wxy()
+#define xyy _xyy()
+#define yyy _yyy()
+#define zyy _zyy()
+#define wyy _wyy()
+#define xzy _xzy()
+#define yzy _yzy()
+#define zzy _zzy()
+#define wzy _wzy()
+#define xwy _xwy()
+#define ywy _ywy()
+#define zwy _zwy()
+#define wwy _wwy()
+#define xxz _xxz()
+#define yxz _yxz()
+#define zxz _zxz()
+#define wxz _wxz()
+#define xyz _xyz()
+#define yyz _yyz()
+#define zyz _zyz()
+#define wyz _wyz()
+#define xzz _xzz()
+#define yzz _yzz()
+#define zzz _zzz()
+#define wzz _wzz()
+#define xwz _xwz()
+#define ywz _ywz()
+#define zwz _zwz()
+#define wwz _wwz()
+#define xxw _xxw()
+#define yxw _yxw()
+#define zxw _zxw()
+#define wxw _wxw()
+#define xyw _xyw()
+#define yyw _yyw()
+#define zyw _zyw()
+#define wyw _wyw()
+#define xzw _xzw()
+#define yzw _yzw()
+#define zzw _zzw()
+#define wzw _wzw()
+#define xww _xww()
+#define yww _yww()
+#define zww _zww()
+#define www _www()
+
+// 4 components common swizzle operators
+#define xxxx _xxxx()
+#define yxxx _yxxx()
+#define zxxx _zxxx()
+#define wxxx _wxxx()
+#define xyxx _xyxx()
+#define yyxx _yyxx()
+#define zyxx _zyxx()
+#define wyxx _wyxx()
+#define xzxx _xzxx()
+#define yzxx _yzxx()
+#define zzxx _zzxx()
+#define wzxx _wzxx()
+#define xwxx _xwxx()
+#define ywxx _ywxx()
+#define zwxx _zwxx()
+#define wwxx _wwxx()
+#define xxyx _xxyx()
+#define yxyx _yxyx()
+#define zxyx _zxyx()
+#define wxyx _wxyx()
+#define xyyx _xyyx()
+#define yyyx _yyyx()
+#define zyyx _zyyx()
+#define wyyx _wyyx()
+#define xzyx _xzyx()
+#define yzyx _yzyx()
+#define zzyx _zzyx()
+#define wzyx _wzyx()
+#define xwyx _xwyx()
+#define ywyx _ywyx()
+#define zwyx _zwyx()
+#define wwyx _wwyx()
+#define xxzx _xxzx()
+#define yxzx _yxzx()
+#define zxzx _zxzx()
+#define wxzx _wxzx()
+#define xyzx _xyzx()
+#define yyzx _yyzx()
+#define zyzx _zyzx()
+#define wyzx _wyzx()
+#define xzzx _xzzx()
+#define yzzx _yzzx()
+#define zzzx _zzzx()
+#define wzzx _wzzx()
+#define xwzx _xwzx()
+#define ywzx _ywzx()
+#define zwzx _zwzx()
+#define wwzx _wwzx()
+#define xxwx _xxwx()
+#define yxwx _yxwx()
+#define zxwx _zxwx()
+#define wxwx _wxwx()
+#define xywx _xywx()
+#define yywx _yywx()
+#define zywx _zywx()
+#define wywx _wywx()
+#define xzwx _xzwx()
+#define yzwx _yzwx()
+#define zzwx _zzwx()
+#define wzwx _wzwx()
+#define xwwx _xwwx()
+#define ywwx _ywwx()
+#define zwwx _zwwx()
+#define wwwx _wwwx()
+#define xxxy _xxxy()
+#define yxxy _yxxy()
+#define zxxy _zxxy()
+#define wxxy _wxxy()
+#define xyxy _xyxy()
+#define yyxy _yyxy()
+#define zyxy _zyxy()
+#define wyxy _wyxy()
+#define xzxy _xzxy()
+#define yzxy _yzxy()
+#define zzxy _zzxy()
+#define wzxy _wzxy()
+#define xwxy _xwxy()
+#define ywxy _ywxy()
+#define zwxy _zwxy()
+#define wwxy _wwxy()
+#define xxyy _xxyy()
+#define yxyy _yxyy()
+#define zxyy _zxyy()
+#define wxyy _wxyy()
+#define xyyy _xyyy()
+#define yyyy _yyyy()
+#define zyyy _zyyy()
+#define wyyy _wyyy()
+#define xzyy _xzyy()
+#define yzyy _yzyy()
+#define zzyy _zzyy()
+#define wzyy _wzyy()
+#define xwyy _xwyy()
+#define ywyy _ywyy()
+#define zwyy _zwyy()
+#define wwyy _wwyy()
+#define xxzy _xxzy()
+#define yxzy _yxzy()
+#define zxzy _zxzy()
+#define wxzy _wxzy()
+#define xyzy _xyzy()
+#define yyzy _yyzy()
+#define zyzy _zyzy()
+#define wyzy _wyzy()
+#define xzzy _xzzy()
+#define yzzy _yzzy()
+#define zzzy _zzzy()
+#define wzzy _wzzy()
+#define xwzy _xwzy()
+#define ywzy _ywzy()
+#define zwzy _zwzy()
+#define wwzy _wwzy()
+#define xxwy _xxwy()
+#define yxwy _yxwy()
+#define zxwy _zxwy()
+#define wxwy _wxwy()
+#define xywy _xywy()
+#define yywy _yywy()
+#define zywy _zywy()
+#define wywy _wywy()
+#define xzwy _xzwy()
+#define yzwy _yzwy()
+#define zzwy _zzwy()
+#define wzwy _wzwy()
+#define xwwy _xwwy()
+#define ywwy _ywwy()
+#define zwwy _zwwy()
+#define wwwy _wwwy()
+#define xxxz _xxxz()
+#define yxxz _yxxz()
+#define zxxz _zxxz()
+#define wxxz _wxxz()
+#define xyxz _xyxz()
+#define yyxz _yyxz()
+#define zyxz _zyxz()
+#define wyxz _wyxz()
+#define xzxz _xzxz()
+#define yzxz _yzxz()
+#define zzxz _zzxz()
+#define wzxz _wzxz()
+#define xwxz _xwxz()
+#define ywxz _ywxz()
+#define zwxz _zwxz()
+#define wwxz _wwxz()
+#define xxyz _xxyz()
+#define yxyz _yxyz()
+#define zxyz _zxyz()
+#define wxyz _wxyz()
+#define xyyz _xyyz()
+#define yyyz _yyyz()
+#define zyyz _zyyz()
+#define wyyz _wyyz()
+#define xzyz _xzyz()
+#define yzyz _yzyz()
+#define zzyz _zzyz()
+#define wzyz _wzyz()
+#define xwyz _xwyz()
+#define ywyz _ywyz()
+#define zwyz _zwyz()
+#define wwyz _wwyz()
+#define xxzz _xxzz()
+#define yxzz _yxzz()
+#define zxzz _zxzz()
+#define wxzz _wxzz()
+#define xyzz _xyzz()
+#define yyzz _yyzz()
+#define zyzz _zyzz()
+#define wyzz _wyzz()
+#define xzzz _xzzz()
+#define yzzz _yzzz()
+#define zzzz _zzzz()
+#define wzzz _wzzz()
+#define xwzz _xwzz()
+#define ywzz _ywzz()
+#define zwzz _zwzz()
+#define wwzz _wwzz()
+#define xxwz _xxwz()
+#define yxwz _yxwz()
+#define zxwz _zxwz()
+#define wxwz _wxwz()
+#define xywz _xywz()
+#define yywz _yywz()
+#define zywz _zywz()
+#define wywz _wywz()
+#define xzwz _xzwz()
+#define yzwz _yzwz()
+#define zzwz _zzwz()
+#define wzwz _wzwz()
+#define xwwz _xwwz()
+#define ywwz _ywwz()
+#define zwwz _zwwz()
+#define wwwz _wwwz()
+#define xxxw _xxxw()
+#define yxxw _yxxw()
+#define zxxw _zxxw()
+#define wxxw _wxxw()
+#define xyxw _xyxw()
+#define yyxw _yyxw()
+#define zyxw _zyxw()
+#define wyxw _wyxw()
+#define xzxw _xzxw()
+#define yzxw _yzxw()
+#define zzxw _zzxw()
+#define wzxw _wzxw()
+#define xwxw _xwxw()
+#define ywxw _ywxw()
+#define zwxw _zwxw()
+#define wwxw _wwxw()
+#define xxyw _xxyw()
+#define yxyw _yxyw()
+#define zxyw _zxyw()
+#define wxyw _wxyw()
+#define xyyw _xyyw()
+#define yyyw _yyyw()
+#define zyyw _zyyw()
+#define wyyw _wyyw()
+#define xzyw _xzyw()
+#define yzyw _yzyw()
+#define zzyw _zzyw()
+#define wzyw _wzyw()
+#define xwyw _xwyw()
+#define ywyw _ywyw()
+#define zwyw _zwyw()
+#define wwyw _wwyw()
+#define xxzw _xxzw()
+#define yxzw _yxzw()
+#define zxzw _zxzw()
+#define wxzw _wxzw()
+#define xyzw _xyzw()
+#define yyzw _yyzw()
+#define zyzw _zyzw()
+#define wyzw _wyzw()
+#define xzzw _xzzw()
+#define yzzw _yzzw()
+#define zzzw _zzzw()
+#define wzzw _wzzw()
+#define xwzw _xwzw()
+#define ywzw _ywzw()
+#define zwzw _zwzw()
+#define wwzw _wwzw()
+#define xxww _xxww()
+#define yxww _yxww()
+#define zxww _zxww()
+#define wxww _wxww()
+#define xyww _xyww()
+#define yyww _yyww()
+#define zyww _zyww()
+#define wyww _wyww()
+#define xzww _xzww()
+#define yzww _yzww()
+#define zzww _zzww()
+#define wzww _wzww()
+#define xwww _xwww()
+#define ywww _ywww()
+#define zwww _zwww()
+#define wwww _wwww()
+
+#endif//defined(GLM_SWIZZLE) && (GLM_SWIZZLE & GLM_SWIZZLE_XYZW)
+
+#if defined(GLM_SWIZZLE) && (GLM_SWIZZLE & GLM_SWIZZLE_RGBA)
+
+// 2 components color swizzle operators
+#define rr _xx()
+#define gr _yx()
+#define br _zx()
+#define ar _wx()
+#define rg _xy()
+#define gg _yy()
+#define bg _zy()
+#define ag _wy()
+#define rb _xz()
+#define gb _yz()
+#define bb _zz()
+#define ab _wz()
+#define ra _xw()
+#define ga _yw()
+#define ba _zw()
+#define aa _ww()
+
+// 3 components color swizzle operators
+#define rrr _xxx()
+#define grr _yxx()
+#define brr _zxx()
+#define arr _wxx()
+#define rgr _xyx()
+#define ggr _yyx()
+#define bgr _zyx()
+#define agr _wyx()
+#define rbr _xzx()
+#define gbr _yzx()
+#define bbr _zzx()
+#define abr _wzx()
+#define rar _xwx()
+#define gar _ywx()
+#define bar _zwx()
+#define aar _wwx()
+#define rrg _xxy()
+#define grg _yxy()
+#define brg _zxy()
+#define arg _wxy()
+#define rgg _xyy()
+#define ggg _yyy()
+#define bgg _zyy()
+#define agg _wyy()
+#define rbg _xzy()
+#define gbg _yzy()
+#define bbg _zzy()
+#define abg _wzy()
+#define rag _xwy()
+#define gag _ywy()
+#define bag _zwy()
+#define aag _wwy()
+#define rrb _xxz()
+#define grb _yxz()
+#define brb _zxz()
+#define arb _wxz()
+#define rgb _xyz()
+#define ggb _yyz()
+#define bgb _zyz()
+#define agb _wyz()
+#define rbb _xzz()
+#define gbb _yzz()
+#define bbb _zzz()
+#define abb _wzz()
+#define rab _xwz()
+#define gab _ywz()
+#define bab _zwz()
+#define aab _wwz()
+#define rra _xxw()
+#define gra _yxw()
+#define bra _zxw()
+#define ara _wxw()
+#define rga _xyw()
+#define gga _yyw()
+#define bga _zyw()
+#define aga _wyw()
+#define rba _xzw()
+#define gba _yzw()
+#define bba _zzw()
+#define aba _wzw()
+#define raa _xww()
+#define gaa _yww()
+#define baa _zww()
+#define aaa _www()
+
+// 4 components color swizzle operators
+#define rrrr _xxxx()
+#define grrr _yxxx()
+#define brrr _zxxx()
+#define arrr _wxxx()
+#define rgrr _xyxx()
+#define ggrr _yyxx()
+#define bgrr _zyxx()
+#define agrr _wyxx()
+#define rbrr _xzxx()
+#define gbrr _yzxx()
+#define bbrr _zzxx()
+#define abrr _wzxx()
+#define rarr _xwxx()
+#define garr _ywxx()
+#define barr _zwxx()
+#define aarr _wwxx()
+#define rrgr _xxyx()
+#define grgr _yxyx()
+#define brgr _zxyx()
+#define argr _wxyx()
+#define rggr _xyyx()
+#define gggr _yyyx()
+#define bggr _zyyx()
+#define aggr _wyyx()
+#define rbgr _xzyx()
+#define gbgr _yzyx()
+#define bbgr _zzyx()
+#define abgr _wzyx()
+#define ragr _xwyx()
+#define gagr _ywyx()
+#define bagr _zwyx()
+#define aagr _wwyx()
+#define rrbr _xxzx()
+#define grbr _yxzx()
+#define brbr _zxzx()
+#define arbr _wxzx()
+#define rgbr _xyzx()
+#define ggbr _yyzx()
+#define bgbr _zyzx()
+#define agbr _wyzx()
+#define rbbr _xzzx()
+#define gbbr _yzzx()
+#define bbbr _zzzx()
+#define abbr _wzzx()
+#define rabr _xwzx()
+#define gabr _ywzx()
+#define babr _zwzx()
+#define aabr _wwzx()
+#define rrar _xxwx()
+#define grar _yxwx()
+#define brar _zxwx()
+#define arar _wxwx()
+#define rgar _xywx()
+#define ggar _yywx()
+#define bgar _zywx()
+#define agar _wywx()
+#define rbar _xzwx()
+#define gbar _yzwx()
+#define bbar _zzwx()
+#define abar _wzwx()
+#define raar _xwwx()
+#define gaar _ywwx()
+#define baar _zwwx()
+#define aaar _wwwx()
+#define rrrg _xxxy()
+#define grrg _yxxy()
+#define brrg _zxxy()
+#define arrg _wxxy()
+#define rgrg _xyxy()
+#define ggrg _yyxy()
+#define bgrg _zyxy()
+#define agrg _wyxy()
+#define rbrg _xzxy()
+#define gbrg _yzxy()
+#define bbrg _zzxy()
+#define abrg _wzxy()
+#define rarg _xwxy()
+#define garg _ywxy()
+#define barg _zwxy()
+#define aarg _wwxy()
+#define rrgg _xxyy()
+#define grgg _yxyy()
+#define brgg _zxyy()
+#define argg _wxyy()
+#define rggg _xyyy()
+#define gggg _yyyy()
+#define bggg _zyyy()
+#define aggg _wyyy()
+#define rbgg _xzyy()
+#define gbgg _yzyy()
+#define bbgg _zzyy()
+#define abgg _wzyy()
+#define ragg _xwyy()
+#define gagg _ywyy()
+#define bagg _zwyy()
+#define aagg _wwyy()
+#define rrbg _xxzy()
+#define grbg _yxzy()
+#define brbg _zxzy()
+#define arbg _wxzy()
+#define rgbg _xyzy()
+#define ggbg _yyzy()
+#define bgbg _zyzy()
+#define agbg _wyzy()
+#define rbbg _xzzy()
+#define gbbg _yzzy()
+#define bbbg _zzzy()
+#define abbg _wzzy()
+#define rabg _xwzy()
+#define gabg _ywzy()
+#define babg _zwzy()
+#define aabg _wwzy()
+#define rrag _xxwy()
+#define grag _yxwy()
+#define brag _zxwy()
+#define arag _wxwy()
+#define rgag _xywy()
+#define ggag _yywy()
+#define bgag _zywy()
+#define agag _wywy()
+#define rbag _xzwy()
+#define gbag _yzwy()
+#define bbag _zzwy()
+#define abag _wzwy()
+#define raag _xwwy()
+#define gaag _ywwy()
+#define baag _zwwy()
+#define aaag _wwwy()
+#define rrrb _xxxz()
+#define grrb _yxxz()
+#define brrb _zxxz()
+#define arrb _wxxz()
+#define rgrb _xyxz()
+#define ggrb _yyxz()
+#define bgrb _zyxz()
+#define agrb _wyxz()
+#define rbrb _xzxz()
+#define gbrb _yzxz()
+#define bbrb _zzxz()
+#define abrb _wzxz()
+#define rarb _xwxz()
+#define garb _ywxz()
+#define barb _zwxz()
+#define aarb _wwxz()
+#define rrgb _xxyz()
+#define grgb _yxyz()
+#define brgb _zxyz()
+#define argb _wxyz()
+#define rggb _xyyz()
+#define gggb _yyyz()
+#define bggb _zyyz()
+#define aggb _wyyz()
+#define rbgb _xzyz()
+#define gbgb _yzyz()
+#define bbgb _zzyz()
+#define abgb _wzyz()
+#define ragb _xwyz()
+#define gagb _ywyz()
+#define bagb _zwyz()
+#define aagb _wwyz()
+#define rrbb _xxzz()
+#define grbb _yxzz()
+#define brbb _zxzz()
+#define arbb _wxzz()
+#define rgbb _xyzz()
+#define ggbb _yyzz()
+#define bgbb _zyzz()
+#define agbb _wyzz()
+#define rbbb _xzzz()
+#define gbbb _yzzz()
+#define bbbb _zzzz()
+#define abbb _wzzz()
+#define rabb _xwzz()
+#define gabb _ywzz()
+#define babb _zwzz()
+#define aabb _wwzz()
+#define rrab _xxwz()
+#define grab _yxwz()
+#define brab _zxwz()
+#define arab _wxwz()
+#define rgab _xywz()
+#define ggab _yywz()
+#define bgab _zywz()
+#define agab _wywz()
+#define rbab _xzwz()
+#define gbab _yzwz()
+#define bbab _zzwz()
+#define abab _wzwz()
+#define raab _xwwz()
+#define gaab _ywwz()
+#define baab _zwwz()
+#define aaab _wwwz()
+#define rrra _xxxw()
+#define grra _yxxw()
+#define brra _zxxw()
+#define arra _wxxw()
+#define rgra _xyxw()
+#define ggra _yyxw()
+#define bgra _zyxw()
+#define agra _wyxw()
+#define rbra _xzxw()
+#define gbra _yzxw()
+#define bbra _zzxw()
+#define abra _wzxw()
+#define rara _xwxw()
+#define gara _ywxw()
+#define bara _zwxw()
+#define aara _wwxw()
+#define rrga _xxyw()
+#define grga _yxyw()
+#define brga _zxyw()
+#define arga _wxyw()
+#define rgga _xyyw()
+#define ggga _yyyw()
+#define bgga _zyyw()
+#define agga _wyyw()
+#define rbga _xzyw()
+#define gbga _yzyw()
+#define bbga _zzyw()
+#define abga _wzyw()
+#define raga _xwyw()
+#define gaga _ywyw()
+#define baga _zwyw()
+#define aaga _wwyw()
+#define rrba _xxzw()
+#define grba _yxzw()
+#define brba _zxzw()
+#define arba _wxzw()
+#define rgba _xyzw()
+#define ggba _yyzw()
+#define bgba _zyzw()
+#define agba _wyzw()
+#define rbba _xzzw()
+#define gbba _yzzw()
+#define bbba _zzzw()
+#define abba _wzzw()
+#define raba _xwzw()
+#define gaba _ywzw()
+#define baba _zwzw()
+#define aaba _wwzw()
+#define rraa _xxww()
+#define graa _yxww()
+#define braa _zxww()
+#define araa _wxww()
+#define rgaa _xyww()
+#define ggaa _yyww()
+#define bgaa _zyww()
+#define agaa _wyww()
+#define rbaa _xzww()
+#define gbaa _yzww()
+#define bbaa _zzww()
+#define abaa _wzww()
+#define raaa _xwww()
+#define gaaa _ywww()
+#define baaa _zwww()
+#define aaaa _wwww()
+
+#endif//defined(GLM_SWIZZLE) && defined(GLM_SWIZZLE_RGBA)
+
+#if defined(GLM_SWIZZLE) && (GLM_SWIZZLE & GLM_SWIZZLE_STQP)
+
+// 2 components texcoord swizzle operators
+#define ss _xx()
+#define ts _yx()
+#define ps _zx()
+#define qs _wx()
+#define st _xy()
+#define tt _yy()
+#define pt _zy()
+#define qt _qy()
+#define sp _xz()
+#define tp _yz()
+#define pp _zz()
+#define qp _qz()
+#define sq _xq()
+#define tq _yq()
+#define pq _zq()
+#define qq _qq()
+
+// 3 components tescoord swizzle operators
+#define sss _xxx()
+#define tss _yxx()
+#define pss _zxx()
+#define qss _qxx()
+#define sts _xyx()
+#define tts _yyx()
+#define pts _zyx()
+#define qts _qyx()
+#define sps _xzx()
+#define tps _yzx()
+#define pps _zzx()
+#define qps _qzx()
+#define sqs _xqx()
+#define tqs _yqx()
+#define pqs _zqx()
+#define qqs _qqx()
+#define sst _xxy()
+#define tst _yxy()
+#define pst _zxy()
+#define qst _qxy()
+#define stt _xyy()
+#define ttt _yyy()
+#define ptt _zyy()
+#define qtt _qyy()
+#define spt _xzy()
+#define tpt _yzy()
+#define ppt _zzy()
+#define qpt _qzy()
+#define sqt _xqy()
+#define tqt _yqy()
+#define pqt _zqy()
+#define qqt _qqy()
+#define ssp _xxz()
+#define tsp _yxz()
+#define psp _zxz()
+#define qsp _qxz()
+#define stp _xyz()
+#define ttp _yyz()
+#define ptp _zyz()
+#define qtp _qyz()
+#define spp _xzz()
+#define tpp _yzz()
+#define ppp _zzz()
+#define qpp _qzz()
+#define sqp _xqz()
+#define tqp _yqz()
+#define pqp _zqz()
+#define qqp _qqz()
+#define ssq _xxq()
+#define tsq _yxq()
+#define psq _zxq()
+#define qsq _qxq()
+#define stq _xyq()
+#define ttq _yyq()
+#define ptq _zyq()
+#define qtq _qyq()
+#define spq _xzq()
+#define tpq _yzq()
+#define ppq _zzq()
+#define qpq _qzq()
+#define sqq _xqq()
+#define tqq _yqq()
+#define pqq _zqq()
+#define qqq _qqq()
+
+// 4 components tescoord swizzle operators
+#define ssss _xxxx()
+#define tsss _yxxx()
+#define psss _zxxx()
+#define qsss _qxxx()
+#define stss _xyxx()
+#define ttss _yyxx()
+#define ptss _zyxx()
+#define qtss _qyxx()
+#define spss _xzxx()
+#define tpss _yzxx()
+#define ppss _zzxx()
+#define qpss _qzxx()
+#define sqss _xqxx()
+#define tqss _yqxx()
+#define pqss _zqxx()
+#define qqss _qqxx()
+#define ssts _xxyx()
+#define tsts _yxyx()
+#define psts _zxyx()
+#define qsts _qxyx()
+#define stts _xyyx()
+#define ttts _yyyx()
+#define ptts _zyyx()
+#define qtts _qyyx()
+#define spts _xzyx()
+#define tpts _yzyx()
+#define ppts _zzyx()
+#define qpts _qzyx()
+#define sqts _xqyx()
+#define tqts _yqyx()
+#define pqts _zqyx()
+#define qqts _qqyx()
+#define ssps _xxzx()
+#define tsps _yxzx()
+#define psps _zxzx()
+#define qsps _qxzx()
+#define stps _xyzx()
+#define ttps _yyzx()
+#define ptps _zyzx()
+#define qtps _qyzx()
+#define spps _xzzx()
+#define tpps _yzzx()
+#define ppps _zzzx()
+#define qpps _qzzx()
+#define sqps _xqzx()
+#define tqps _yqzx()
+#define pqps _zqzx()
+#define qqps _qqzx()
+#define ssqs _xxqx()
+#define tsqs _yxqx()
+#define psqs _zxqx()
+#define qsqs _qxqx()
+#define stqs _xyqx()
+#define ttqs _yyqx()
+#define ptqs _zyqx()
+#define qtqs _qyqx()
+#define spqs _xzqx()
+#define tpqs _yzqx()
+#define ppqs _zzqx()
+#define qpqs _qzqx()
+#define sqqs _xqqx()
+#define tqqs _yqqx()
+#define pqqs _zqqx()
+#define qqqs _qqqx()
+#define ssst _xxxy()
+#define tsst _yxxy()
+#define psst _zxxy()
+#define qsst _qxxy()
+#define stst _xyxy()
+#define ttst _yyxy()
+#define ptst _zyxy()
+#define qtst _qyxy()
+#define spst _xzxy()
+#define tpst _yzxy()
+#define ppst _zzxy()
+#define qpst _qzxy()
+#define sqst _xqxy()
+#define tqst _yqxy()
+#define pqst _zqxy()
+#define qqst _qqxy()
+#define sstt _xxyy()
+#define tstt _yxyy()
+#define pstt _zxyy()
+#define qstt _qxyy()
+#define sttt _xyyy()
+#define tttt _yyyy()
+#define pttt _zyyy()
+#define qttt _qyyy()
+#define sptt _xzyy()
+#define tptt _yzyy()
+#define pptt _zzyy()
+#define qptt _qzyy()
+#define sqtt _xqyy()
+#define tqtt _yqyy()
+#define pqtt _zqyy()
+#define qqtt _qqyy()
+#define sspt _xxzy()
+#define tspt _yxzy()
+#define pspt _zxzy()
+#define qspt _qxzy()
+#define stpt _xyzy()
+#define ttpt _yyzy()
+#define ptpt _zyzy()
+#define qtpt _qyzy()
+#define sppt _xzzy()
+#define tppt _yzzy()
+#define pppt _zzzy()
+#define qppt _qzzy()
+#define sqpt _xqzy()
+#define tqpt _yqzy()
+#define pqpt _zqzy()
+#define qqpt _qqzy()
+#define ssqt _xxqy()
+#define tsqt _yxqy()
+#define psqt _zxqy()
+#define qsqt _qxqy()
+#define stqt _xyqy()
+#define ttqt _yyqy()
+#define ptqt _zyqy()
+#define qtqt _qyqy()
+#define spqt _xzqy()
+#define tpqt _yzqy()
+#define ppqt _zzqy()
+#define qpqt _qzqy()
+#define sqqt _xqqy()
+#define tqqt _yqqy()
+#define pqqt _zqqy()
+#define qqqt _qqqy()
+#define sssp _xxxz()
+#define tssp _yxxz()
+#define pssp _zxxz()
+#define qssp _qxxz()
+#define stsp _xyxz()
+#define ttsp _yyxz()
+#define ptsp _zyxz()
+#define qtsp _qyxz()
+#define spsp _xzxz()
+#define tpsp _yzxz()
+#define ppsp _zzxz()
+#define qpsp _qzxz()
+#define sqsp _xqxz()
+#define tqsp _yqxz()
+#define pqsp _zqxz()
+#define qqsp _qqxz()
+#define sstp _xxyz()
+#define tstp _yxyz()
+#define pstp _zxyz()
+#define qstp _qxyz()
+#define sttp _xyyz()
+#define tttp _yyyz()
+#define pttp _zyyz()
+#define qttp _qyyz()
+#define sptp _xzyz()
+#define tptp _yzyz()
+#define pptp _zzyz()
+#define qptp _qzyz()
+#define sqtp _xqyz()
+#define tqtp _yqyz()
+#define pqtp _zqyz()
+#define qqtp _qqyz()
+#define sspp _xxzz()
+#define tspp _yxzz()
+#define pspp _zxzz()
+#define qspp _qxzz()
+#define stpp _xyzz()
+#define ttpp _yyzz()
+#define ptpp _zyzz()
+#define qtpp _qyzz()
+#define sppp _xzzz()
+#define tppp _yzzz()
+#define pppp _zzzz()
+#define qppp _qzzz()
+#define sqpp _xqzz()
+#define tqpp _yqzz()
+#define pqpp _zqzz()
+#define qqpp _qqzz()
+#define ssqp _xxqz()
+#define tsqp _yxqz()
+#define psqp _zxqz()
+#define qsqp _qxqz()
+#define stqp _xyqz()
+#define ttqp _yyqz()
+#define ptqp _zyqz()
+#define qtqp _qyqz()
+#define spqp _xzqz()
+#define tpqp _yzqz()
+#define ppqp _zzqz()
+#define qpqp _qzqz()
+#define sqqp _xqqz()
+#define tqqp _yqqz()
+#define pqqp _zqqz()
+#define qqqp _qqqz()
+#define sssq _xxxq()
+#define tssq _yxxq()
+#define pssq _zxxq()
+#define qssq _qxxq()
+#define stsq _xyxq()
+#define ttsq _yyxq()
+#define ptsq _zyxq()
+#define qtsq _qyxq()
+#define spsq _xzxq()
+#define tpsq _yzxq()
+#define ppsq _zzxq()
+#define qpsq _qzxq()
+#define sqsq _xqxq()
+#define tqsq _yqxq()
+#define pqsq _zqxq()
+#define qqsq _qqxq()
+#define sstq _xxyq()
+#define tstq _yxyq()
+#define pstq _zxyq()
+#define qstq _qxyq()
+#define sttq _xyyq()
+#define tttq _yyyq()
+#define pttq _zyyq()
+#define qttq _qyyq()
+#define sptq _xzyq()
+#define tptq _yzyq()
+#define pptq _zzyq()
+#define qptq _qzyq()
+#define sqtq _xqyq()
+#define tqtq _yqyq()
+#define pqtq _zqyq()
+#define qqtq _qqyq()
+#define sspq _xxzq()
+#define tspq _yxzq()
+#define pspq _zxzq()
+#define qspq _qxzq()
+#define stpq _xyzq()
+#define ttpq _yyzq()
+#define ptpq _zyzq()
+#define qtpq _qyzq()
+#define sppq _xzzq()
+#define tppq _yzzq()
+#define pppq _zzzq()
+#define qppq _qzzq()
+#define sqpq _xqzq()
+#define tqpq _yqzq()
+#define pqpq _zqzq()
+#define qqpq _qqzq()
+#define ssqq _xxqq()
+#define tsqq _yxqq()
+#define psqq _zxqq()
+#define qsqq _qxqq()
+#define stqq _xyqq()
+#define ttqq _yyqq()
+#define ptqq _zyqq()
+#define qtqq _qyqq()
+#define spqq _xzqq()
+#define tpqq _yzqq()
+#define ppqq _zzqq()
+#define qpqq _qzqq()
+#define sqqq _xqqq()
+#define tqqq _yqqq()
+#define pqqq _zqqq()
+#define qqqq _qqqq()
+
+#endif//defined(GLM_SWIZZLE) && (GLM_SWIZZLE & GLM_SWIZZLE_STQP)
+
+/*
+// 2 components color swizzle operators
+#define rr _rr()
+#define gr _gr()
+#define br _br()
+#define ar _ar()
+#define rg _rg()
+#define gg _gg()
+#define bg _bg()
+#define ag _ag()
+#define rb _rb()
+#define gb _gb()
+#define bb _bb()
+#define ab _ab()
+#define ra _ra()
+#define ga _ga()
+#define ba _ba()
+#define aa _aa()
+
+// 3 components color swizzle operators
+#define rrr _rrr()
+#define grr _grr()
+#define brr _brr()
+#define arr _arr()
+#define rgr _rgr()
+#define ggr _ggr()
+#define bgr _bgr()
+#define agr _agr()
+#define rbr _rbr()
+#define gbr _gbr()
+#define bbr _bbr()
+#define abr _abr()
+#define rar _rar()
+#define gar _gar()
+#define bar _bar()
+#define aar _aar()
+#define rrg _rrg()
+#define grg _grg()
+#define brg _brg()
+#define arg _arg()
+#define rgg _rgg()
+#define ggg _ggg()
+#define bgg _bgg()
+#define agg _agg()
+#define rbg _rbg()
+#define gbg _gbg()
+#define bbg _bbg()
+#define abg _abg()
+#define rag _rag()
+#define gag _gag()
+#define bag _bag()
+#define aag _aag()
+#define rrb _rrb()
+#define grb _grb()
+#define brb _brb()
+#define arb _arb()
+#define rgb _rgb()
+#define ggb _ggb()
+#define bgb _bgb()
+#define agb _agb()
+#define rbb _rbb()
+#define gbb _gbb()
+#define bbb _bbb()
+#define abb _abb()
+#define rab _rab()
+#define gab _gab()
+#define bab _bab()
+#define aab _aab()
+#define rra _rra()
+#define gra _gra()
+#define bra _bra()
+#define ara _ara()
+#define rga _rga()
+#define gga _gga()
+#define bga _bga()
+#define aga _aga()
+#define rba _rba()
+#define gba _gba()
+#define bba _bba()
+#define aba _aba()
+#define raa _raa()
+#define gaa _gaa()
+#define baa _baa()
+#define aaa _aaa()
+
+// 4 components color swizzle operators
+#define rrrr _rrrr()
+#define grrr _grrr()
+#define brrr _brrr()
+#define arrr _arrr()
+#define rgrr _rgrr()
+#define ggrr _ggrr()
+#define bgrr _bgrr()
+#define agrr _agrr()
+#define rbrr _rbrr()
+#define gbrr _gbrr()
+#define bbrr _bbrr()
+#define abrr _abrr()
+#define rarr _rarr()
+#define garr _garr()
+#define barr _barr()
+#define aarr _aarr()
+#define rrgr _rrgr()
+#define grgr _grgr()
+#define brgr _brgr()
+#define argr _argr()
+#define rggr _rggr()
+#define gggr _gggr()
+#define bggr _bggr()
+#define aggr _aggr()
+#define rbgr _rbgr()
+#define gbgr _gbgr()
+#define bbgr _bbgr()
+#define abgr _abgr()
+#define ragr _ragr()
+#define gagr _gagr()
+#define bagr _bagr()
+#define aagr _aagr()
+#define rrbr _rrbr()
+#define grbr _grbr()
+#define brbr _brbr()
+#define arbr _arbr()
+#define rgbr _rgbr()
+#define ggbr _ggbr()
+#define bgbr _bgbr()
+#define agbr _agbr()
+#define rbbr _rbbr()
+#define gbbr _gbbr()
+#define bbbr _bbbr()
+#define abbr _abbr()
+#define rabr _rabr()
+#define gabr _gabr()
+#define babr _babr()
+#define aabr _aabr()
+#define rrar _rrar()
+#define grar _grar()
+#define brar _brar()
+#define arar _arar()
+#define rgar _rgar()
+#define ggar _ggar()
+#define bgar _bgar()
+#define agar _agar()
+#define rbar _rbar()
+#define gbar _gbar()
+#define bbar _bbar()
+#define abar _abar()
+#define raar _raar()
+#define gaar _gaar()
+#define baar _baar()
+#define aaar _aaar()
+#define rrrg _rrrg()
+#define grrg _grrg()
+#define brrg _brrg()
+#define arrg _arrg()
+#define rgrg _rgrg()
+#define ggrg _ggrg()
+#define bgrg _bgrg()
+#define agrg _agrg()
+#define rbrg _rbrg()
+#define gbrg _gbrg()
+#define bbrg _bbrg()
+#define abrg _abrg()
+#define rarg _rarg()
+#define garg _garg()
+#define barg _barg()
+#define aarg _aarg()
+#define rrgg _rrgg()
+#define grgg _grgg()
+#define brgg _brgg()
+#define argg _argg()
+#define rggg _rggg()
+#define gggg _gggg()
+#define bggg _bggg()
+#define aggg _aggg()
+#define rbgg _rbgg()
+#define gbgg _gbgg()
+#define bbgg _bbgg()
+#define abgg _abgg()
+#define ragg _ragg()
+#define gagg _gagg()
+#define bagg _bagg()
+#define aagg _aagg()
+#define rrbg _rrbg()
+#define grbg _grbg()
+#define brbg _brbg()
+#define arbg _arbg()
+#define rgbg _rgbg()
+#define ggbg _ggbg()
+#define bgbg _bgbg()
+#define agbg _agbg()
+#define rbbg _rbbg()
+#define gbbg _gbbg()
+#define bbbg _bbbg()
+#define abbg _abbg()
+#define rabg _rabg()
+#define gabg _gabg()
+#define babg _babg()
+#define aabg _aabg()
+#define rrag _rrag()
+#define grag _grag()
+#define brag _brag()
+#define arag _arag()
+#define rgag _rgag()
+#define ggag _ggag()
+#define bgag _bgag()
+#define agag _agag()
+#define rbag _rbag()
+#define gbag _gbag()
+#define bbag _bbag()
+#define abag _abag()
+#define raag _raag()
+#define gaag _gaag()
+#define baag _baag()
+#define aaag _aaag()
+#define rrrb _rrrb()
+#define grrb _grrb()
+#define brrb _brrb()
+#define arrb _arrb()
+#define rgrb _rgrb()
+#define ggrb _ggrb()
+#define bgrb _bgrb()
+#define agrb _agrb()
+#define rbrb _rbrb()
+#define gbrb _gbrb()
+#define bbrb _bbrb()
+#define abrb _abrb()
+#define rarb _rarb()
+#define garb _garb()
+#define barb _barb()
+#define aarb _aarb()
+#define rrgb _rrgb()
+#define grgb _grgb()
+#define brgb _brgb()
+#define argb _argb()
+#define rggb _rggb()
+#define gggb _gggb()
+#define bggb _bggb()
+#define aggb _aggb()
+#define rbgb _rbgb()
+#define gbgb _gbgb()
+#define bbgb _bbgb()
+#define abgb _abgb()
+#define ragb _ragb()
+#define gagb _gagb()
+#define bagb _bagb()
+#define aagb _aagb()
+#define rrbb _rrbb()
+#define grbb _grbb()
+#define brbb _brbb()
+#define arbb _arbb()
+#define rgbb _rgbb()
+#define ggbb _ggbb()
+#define bgbb _bgbb()
+#define agbb _agbb()
+#define rbbb _rbbb()
+#define gbbb _gbbb()
+#define bbbb _bbbb()
+#define abbb _abbb()
+#define rabb _rabb()
+#define gabb _gabb()
+#define babb _babb()
+#define aabb _aabb()
+#define rrab _rrab()
+#define grab _grab()
+#define brab _brab()
+#define arab _arab()
+#define rgab _rgab()
+#define ggab _ggab()
+#define bgab _bgab()
+#define agab _agab()
+#define rbab _rbab()
+#define gbab _gbab()
+#define bbab _bbab()
+#define abab _abab()
+#define raab _raab()
+#define gaab _gaab()
+#define baab _baab()
+#define aaab _aaab()
+#define rrra _rrra()
+#define grra _grra()
+#define brra _brra()
+#define arra _arra()
+#define rgra _rgra()
+#define ggra _ggra()
+#define bgra _bgra()
+#define agra _agra()
+#define rbra _rbra()
+#define gbra _gbra()
+#define bbra _bbra()
+#define abra _abra()
+#define rara _rara()
+#define gara _gara()
+#define bara _bara()
+#define aara _aara()
+#define rrga _rrga()
+#define grga _grga()
+#define brga _brga()
+#define arga _arga()
+#define rgga _rgga()
+#define ggga _ggga()
+#define bgga _bgga()
+#define agga _agga()
+#define rbga _rbga()
+#define gbga _gbga()
+#define bbga _bbga()
+#define abga _abga()
+#define raga _raga()
+#define gaga _gaga()
+#define baga _baga()
+#define aaga _aaga()
+#define rrba _rrba()
+#define grba _grba()
+#define brba _brba()
+#define arba _arba()
+#define rgba _rgba()
+#define ggba _ggba()
+#define bgba _bgba()
+#define agba _agba()
+#define rbba _rbba()
+#define gbba _gbba()
+#define bbba _bbba()
+#define abba _abba()
+#define raba _raba()
+#define gaba _gaba()
+#define baba _baba()
+#define aaba _aaba()
+#define rraa _rraa()
+#define graa _graa()
+#define braa _braa()
+#define araa _araa()
+#define rgaa _rgaa()
+#define ggaa _ggaa()
+#define bgaa _bgaa()
+#define agaa _agaa()
+#define rbaa _rbaa()
+#define gbaa _gbaa()
+#define bbaa _bbaa()
+#define abaa _abaa()
+#define raaa _raaa()
+#define gaaa _gaaa()
+#define baaa _baaa()
+#define aaaa _aaaa()
+
+// 2 components texcoord swizzle operators
+#define ss _ss()
+#define ts _ts()
+#define ps _ps()
+#define qs _qs()
+#define st _st()
+#define tt _tt()
+#define pt _pt()
+#define qt _qt()
+#define sp _sp()
+#define tp _tp()
+#define pp _pp()
+#define qp _qp()
+#define sq _sq()
+#define tq _tq()
+#define pq _pq()
+#define qq _qq()
+
+// 3 components tescoord swizzle operators
+#define sss _sss()
+#define tss _tss()
+#define pss _pss()
+#define qss _qss()
+#define sts _sts()
+#define tts _tts()
+#define pts _pts()
+#define qts _qts()
+#define sps _sps()
+#define tps _tps()
+#define pps _pps()
+#define qps _qps()
+#define sqs _sqs()
+#define tqs _tqs()
+#define pqs _pqs()
+#define qqs _qqs()
+#define sst _sst()
+#define tst _tst()
+#define pst _pst()
+#define qst _qst()
+#define stt _stt()
+#define ttt _ttt()
+#define ptt _ptt()
+#define qtt _qtt()
+#define spt _spt()
+#define tpt _tpt()
+#define ppt _ppt()
+#define qpt _qpt()
+#define sqt _sqt()
+#define tqt _tqt()
+#define pqt _pqt()
+#define qqt _qqt()
+#define ssp _ssp()
+#define tsp _tsp()
+#define psp _psp()
+#define qsp _qsp()
+#define stp _stp()
+#define ttp _ttp()
+#define ptp _ptp()
+#define qtp _qtp()
+#define spp _spp()
+#define tpp _tpp()
+#define ppp _ppp()
+#define qpp _qpp()
+#define sqp _sqp()
+#define tqp _tqp()
+#define pqp _pqp()
+#define qqp _qqp()
+#define ssq _ssq()
+#define tsq _tsq()
+#define psq _psq()
+#define qsq _qsq()
+#define stq _stq()
+#define ttq _ttq()
+#define ptq _ptq()
+#define qtq _qtq()
+#define spq _spq()
+#define tpq _tpq()
+#define ppq _ppq()
+#define qpq _qpq()
+#define sqq _sqq()
+#define tqq _tqq()
+#define pqq _pqq()
+#define qqq _qqq()
+
+// 4 components tescoord swizzle operators
+#define ssss _ssss()
+#define tsss _tsss()
+#define psss _psss()
+#define qsss _qsss()
+#define stss _stss()
+#define ttss _ttss()
+#define ptss _ptss()
+#define qtss _qtss()
+#define spss _spss()
+#define tpss _tpss()
+#define ppss _ppss()
+#define qpss _qpss()
+#define sqss _sqss()
+#define tqss _tqss()
+#define pqss _pqss()
+#define qqss _qqss()
+#define ssts _ssts()
+#define tsts _tsts()
+#define psts _psts()
+#define qsts _qsts()
+#define stts _stts()
+#define ttts _ttts()
+#define ptts _ptts()
+#define qtts _qtts()
+#define spts _spts()
+#define tpts _tpts()
+#define ppts _ppts()
+#define qpts _qpts()
+#define sqts _sqts()
+#define tqts _tqts()
+#define pqts _pqts()
+#define qqts _qqts()
+#define ssps _ssps()
+#define tsps _tsps()
+#define psps _psps()
+#define qsps _qsps()
+#define stps _stps()
+#define ttps _ttps()
+#define ptps _ptps()
+#define qtps _qtps()
+#define spps _spps()
+#define tpps _tpps()
+#define ppps _ppps()
+#define qpps _qpps()
+#define sqps _sqps()
+#define tqps _tqps()
+#define pqps _pqps()
+#define qqps _qqps()
+#define ssqs _ssqs()
+#define tsqs _tsqs()
+#define psqs _psqs()
+#define qsqs _qsqs()
+#define stqs _stqs()
+#define ttqs _ttqs()
+#define ptqs _ptqs()
+#define qtqs _qtqs()
+#define spqs _spqs()
+#define tpqs _tpqs()
+#define ppqs _ppqs()
+#define qpqs _qpqs()
+#define sqqs _sqqs()
+#define tqqs _tqqs()
+#define pqqs _pqqs()
+#define qqqs _qqqs()
+#define ssst _ssst()
+#define tsst _tsst()
+#define psst _psst()
+#define qsst _qsst()
+#define stst _stst()
+#define ttst _ttst()
+#define ptst _ptst()
+#define qtst _qtst()
+#define spst _spst()
+#define tpst _tpst()
+#define ppst _ppst()
+#define qpst _qpst()
+#define sqst _sqst()
+#define tqst _tqst()
+#define pqst _pqst()
+#define qqst _qqst()
+#define sstt _sstt()
+#define tstt _tstt()
+#define pstt _pstt()
+#define qstt _qstt()
+#define sttt _sttt()
+#define tttt _tttt()
+#define pttt _pttt()
+#define qttt _qttt()
+#define sptt _sptt()
+#define tptt _tptt()
+#define pptt _pptt()
+#define qptt _qptt()
+#define sqtt _sqtt()
+#define tqtt _tqtt()
+#define pqtt _pqtt()
+#define qqtt _qqtt()
+#define sspt _sspt()
+#define tspt _tspt()
+#define pspt _pspt()
+#define qspt _qspt()
+#define stpt _stpt()
+#define ttpt _ttpt()
+#define ptpt _ptpt()
+#define qtpt _qtpt()
+#define sppt _sppt()
+#define tppt _tppt()
+#define pppt _pppt()
+#define qppt _qppt()
+#define sqpt _sqpt()
+#define tqpt _tqpt()
+#define pqpt _pqpt()
+#define qqpt _qqpt()
+#define ssqt _ssqt()
+#define tsqt _tsqt()
+#define psqt _psqt()
+#define qsqt _qsqt()
+#define stqt _stqt()
+#define ttqt _ttqt()
+#define ptqt _ptqt()
+#define qtqt _qtqt()
+#define spqt _spqt()
+#define tpqt _tpqt()
+#define ppqt _ppqt()
+#define qpqt _qpqt()
+#define sqqt _sqqt()
+#define tqqt _tqqt()
+#define pqqt _pqqt()
+#define qqqt _qqqt()
+#define sssp _sssp()
+#define tssp _tssp()
+#define pssp _pssp()
+#define qssp _qssp()
+#define stsp _stsp()
+#define ttsp _ttsp()
+#define ptsp _ptsp()
+#define qtsp _qtsp()
+#define spsp _spsp()
+#define tpsp _tpsp()
+#define ppsp _ppsp()
+#define qpsp _qpsp()
+#define sqsp _sqsp()
+#define tqsp _tqsp()
+#define pqsp _pqsp()
+#define qqsp _qqsp()
+#define sstp _sstp()
+#define tstp _tstp()
+#define pstp _pstp()
+#define qstp _qstp()
+#define sttp _sttp()
+#define tttp _tttp()
+#define pttp _pttp()
+#define qttp _qttp()
+#define sptp _sptp()
+#define tptp _tptp()
+#define pptp _pptp()
+#define qptp _qptp()
+#define sqtp _sqtp()
+#define tqtp _tqtp()
+#define pqtp _pqtp()
+#define qqtp _qqtp()
+#define sspp _sspp()
+#define tspp _tspp()
+#define pspp _pspp()
+#define qspp _qspp()
+#define stpp _stpp()
+#define ttpp _ttpp()
+#define ptpp _ptpp()
+#define qtpp _qtpp()
+#define sppp _sppp()
+#define tppp _tppp()
+#define pppp _pppp()
+#define qppp _qppp()
+#define sqpp _sqpp()
+#define tqpp _tqpp()
+#define pqpp _pqpp()
+#define qqpp _qqpp()
+#define ssqp _ssqp()
+#define tsqp _tsqp()
+#define psqp _psqp()
+#define qsqp _qsqp()
+#define stqp _stqp()
+#define ttqp _ttqp()
+#define ptqp _ptqp()
+#define qtqp _qtqp()
+#define spqp _spqp()
+#define tpqp _tpqp()
+#define ppqp _ppqp()
+#define qpqp _qpqp()
+#define sqqp _sqqp()
+#define tqqp _tqqp()
+#define pqqp _pqqp()
+#define qqqp _qqqp()
+#define sssq _sssq()
+#define tssq _tssq()
+#define pssq _pssq()
+#define qssq _qssq()
+#define stsq _stsq()
+#define ttsq _ttsq()
+#define ptsq _ptsq()
+#define qtsq _qtsq()
+#define spsq _spsq()
+#define tpsq _tpsq()
+#define ppsq _ppsq()
+#define qpsq _qpsq()
+#define sqsq _sqsq()
+#define tqsq _tqsq()
+#define pqsq _pqsq()
+#define qqsq _qqsq()
+#define sstq _sstq()
+#define tstq _tstq()
+#define pstq _pstq()
+#define qstq _qstq()
+#define sttq _sttq()
+#define tttq _tttq()
+#define pttq _pttq()
+#define qttq _qttq()
+#define sptq _sptq()
+#define tptq _tptq()
+#define pptq _pptq()
+#define qptq _qptq()
+#define sqtq _sqtq()
+#define tqtq _tqtq()
+#define pqtq _pqtq()
+#define qqtq _qqtq()
+#define sspq _sspq()
+#define tspq _tspq()
+#define pspq _pspq()
+#define qspq _qspq()
+#define stpq _stpq()
+#define ttpq _ttpq()
+#define ptpq _ptpq()
+#define qtpq _qtpq()
+#define sppq _sppq()
+#define tppq _tppq()
+#define pppq _pppq()
+#define qppq _qppq()
+#define sqpq _sqpq()
+#define tqpq _tqpq()
+#define pqpq _pqpq()
+#define qqpq _qqpq()
+#define ssqq _ssqq()
+#define tsqq _tsqq()
+#define psqq _psqq()
+#define qsqq _qsqq()
+#define stqq _stqq()
+#define ttqq _ttqq()
+#define ptqq _ptqq()
+#define qtqq _qtqq()
+#define spqq _spqq()
+#define tpqq _tpqq()
+#define ppqq _ppqq()
+#define qpqq _qpqq()
+#define sqqq _sqqq()
+#define tqqq _tqqq()
+#define pqqq _pqqq()
+#define qqqq _qqqq()
+*/
+
+#endif//__swizzle_h__

+ 20 - 0
experimental/sse/glm/core/_swizzle.inl

@@ -0,0 +1,20 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2008 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2006-04-27
+// Updated : 2006-04-27
+// Licence : This source is under GNU LGPL licence
+// File    : _swizzle.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef __swizzle_inl__
+#define __swizzle_inl__
+
+#include "./_swizzle.h"
+
+namespace glm
+{
+
+}
+
+#endif//__swizzle_inl__

+ 173 - 0
experimental/sse/glm/core/_xmat2.h

@@ -0,0 +1,173 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2008 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2005-01-27
+// Updated : 2007-03-01
+// Licence : This source is under GNU LGPL licence
+// File    : _xmat2.h
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef __mat2x2_h__
+#define __mat2x2_h__
+
+namespace glm{
+namespace detail{
+
+    template <typename T> class _xvec2;
+    template <typename T> class _xmat3;
+    template <typename T> class _xmat4;
+    template <typename T> class _xmat2x4;
+	template <typename T> class _xmat2x3;
+    template <typename T> class _xmat3x2;
+    template <typename T> class _xmat3x4;
+    template <typename T> class _xmat4x2;
+    template <typename T> class _xmat4x3;
+
+	//!< \brief Template for 2 * 2 matrix of floating-point numbers.
+    template <typename T> 
+	class _xmat2
+    {
+    private:
+        // Data 
+        _xvec2<T> value[2];
+
+    public:
+        _xmat2<T> _inverse() const;
+
+    public:
+		typedef T value_type;
+		typedef _xvec2<T> col_type;
+		typedef _xvec2<T> row_type;
+		typedef int size_type;
+		static const size_type value_size;
+		static const size_type col_size;
+		static const size_type row_size;
+
+        // Constructors
+	    _xmat2();
+	    _xmat2(const _xmat2<T>& m);
+
+        explicit _xmat2(const T x);
+        explicit _xmat2(const T x1, const T y1, 
+                        const T x2, const T y2);
+	    explicit _xmat2(const _xvec2<T> & v1, 
+                        const _xvec2<T> & v2);
+
+		// Conversions
+		template <typename U> 
+		explicit _xmat2(const _xmat2<U>& m);
+
+		explicit _xmat2(const _xmat3<T>& x);
+        explicit _xmat2(const _xmat4<T>& x);
+        explicit _xmat2(const _xmat2x3<T>& x);
+        explicit _xmat2(const _xmat3x2<T>& x);
+        explicit _xmat2(const _xmat2x4<T>& x);
+        explicit _xmat2(const _xmat4x2<T>& x);
+        explicit _xmat2(const _xmat3x4<T>& x);
+        explicit _xmat2(const _xmat4x3<T>& x);
+
+        //explicit _xmat2(const T* a);
+        // GL_GTX_euler_angles
+        //explicit _xmat2(const _xvec2<T> & angles);
+
+        // Accesses
+        _xvec2<T>& operator[](int i) {return value[i];}
+        const _xvec2<T> & operator[](int i) const {return value[i];}
+		// operator T*() {return &value[0][0];}
+		// operator const T*() const {return &value[0][0];}
+		operator T*() {return (T*)this;}
+        operator const T*() const {return (const T*)this;}
+
+        // Unary updatable operators
+        _xmat2<T>& operator=(const _xmat2<T>& m);
+        _xmat2<T>& operator+=(const T s);
+	    _xmat2<T>& operator+=(const _xmat2<T>& m);
+        _xmat2<T>& operator-=(const T s);
+	    _xmat2<T>& operator-=(const _xmat2<T>& m);
+	    _xmat2<T>& operator*=(const T s);
+	    _xmat2<T>& operator*= (const _xmat2<T>& m);
+        _xmat2<T>& operator/= (const T s);
+	    _xmat2<T>& operator/= (const _xmat2<T>& m);
+        _xmat2<T>& operator++ ();
+	    _xmat2<T>& operator-- ();
+
+        const _xmat2<T> operator- () const;
+        const _xmat2<T> operator++ (int n) const;
+        const _xmat2<T> operator-- (int n) const;
+    };
+
+	// Binary operators
+    template <typename T> 
+    inline _xmat2<T> operator+ (const _xmat2<T>& m, const T s);
+
+    template <typename T> 
+    inline _xmat2<T> operator+ (const T s, const _xmat2<T>& m);
+
+    template <typename T> 
+    inline _xvec2<T> operator+ (const _xmat2<T>& m, const _xvec2<T>& v);
+
+    template <typename T> 
+    inline _xvec2<T> operator+ (const _xvec2<T>& v, const _xmat2<T>& m);
+  
+    template <typename T> 
+    inline _xmat2<T> operator+ (const _xmat2<T>& m1, const _xmat2<T>& m2);
+    
+    template <typename T> 
+    inline _xmat2<T> operator- (const _xmat2<T>& m, const T s);
+
+    template <typename T> 
+    inline _xmat2<T> operator- (const T s, const _xmat2<T>& m);
+
+    template <typename T> 
+    inline _xvec2<T> operator- (const _xmat2<T>& m, const _xvec2<T>& v);
+
+    template <typename T> 
+    inline _xvec2<T> operator- (const _xvec2<T>& v, const _xmat2<T>& m);
+
+    template <typename T> 
+    inline _xmat2<T> operator- (const _xmat2<T>& m1, const _xmat2<T>& m2);
+
+    template <typename T> 
+    inline _xmat2<T> operator* (const _xmat2<T>& m, const T s);
+
+    template <typename T> 
+    inline _xmat2<T> operator* (const T s, const _xmat2<T>& m);
+
+    template <typename T> 
+    inline _xvec2<T> operator* (const _xmat2<T>& m, const _xvec2<T>& v);
+
+    template <typename T> 
+    inline _xvec2<T> operator* (const _xvec2<T>& v, const _xmat2<T>& m);
+
+    template <typename T> 
+    inline _xmat2<T> operator* (const _xmat2<T>& m1, const _xmat2<T>& m2);
+
+    template <typename T> 
+    inline _xmat2<T> operator/ (const _xmat2<T>& m, const T s);
+
+    template <typename T> 
+    inline _xmat2<T> operator/ (const T s, const _xmat2<T>& m);
+
+    template <typename T> 
+    inline _xvec2<T> operator/ (const _xmat2<T>& m, const _xvec2<T>& v);
+
+    template <typename T> 
+    inline _xvec2<T> operator/ (const _xvec2<T>& v, const _xmat2<T>& m);
+
+    template <typename T> 
+    inline _xmat2<T> operator/ (const _xmat2<T>& m1, const _xmat2<T>& m2);
+
+	// Unary constant operators
+    template <typename T> 
+    inline const _xmat2<T> operator- (const _xmat2<T>& m);
+
+    template <typename T> 
+    inline const _xmat2<T> operator-- (const _xmat2<T>& m, int);
+
+    template <typename T> 
+    inline const _xmat2<T> operator++ (const _xmat2<T>& m, int);
+
+} //namespace detail
+} //namespace glm
+
+#endif //__mat2x2_h__

+ 416 - 0
experimental/sse/glm/core/_xmat2.inl

@@ -0,0 +1,416 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2008 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2005-01-16
+// Updated : 2007-03-01
+// Licence : This source is under GNU LGPL licence
+// File    : _xmat2.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef __xmat2x2_inl__
+#define __xmat2x2_inl__
+
+#include "./_xmat2.h"
+
+namespace glm{
+namespace detail{
+
+	template <typename T> const typename _xmat2<T>::size_type _xmat2<T>::value_size = 2;
+	template <typename T> const typename _xmat2<T>::size_type _xmat2<T>::col_size = 2;
+	template <typename T> const typename _xmat2<T>::size_type _xmat2<T>::row_size = 2;
+
+    //////////////////////////////////////////////////////////////
+    // mat2 constructors
+
+    template <typename T> 
+    inline _xmat2<T>::_xmat2()
+    {
+        this->value[0] = _xvec2<T>(1, 0);
+        this->value[1] = _xvec2<T>(0, 1);
+    }
+
+    template <typename T> 
+    inline _xmat2<T>::_xmat2(const _xmat2<T> & m)
+    {
+        this->value[0] = m.value[0];
+        this->value[1] = m.value[1];
+    }
+
+    template <typename T> 
+    inline _xmat2<T>::_xmat2(const T f)
+    {
+        this->value[0] = _xvec2<T>(f, 0);
+        this->value[1] = _xvec2<T>(0, f);
+    }
+
+    template <typename T> 
+    inline _xmat2<T>::_xmat2(const T x0, const T y0, const T x1, const T y1)
+    {
+        this->value[0] = _xvec2<T>(x0, y0);
+        this->value[1] = _xvec2<T>(x1, y1);
+    }
+
+    template <typename T> 
+    inline _xmat2<T>::_xmat2(const _xvec2<T>& v0, const _xvec2<T>& v1)
+    {
+        this->value[0] = v0;
+        this->value[1] = v1;
+    }
+
+    //////////////////////////////////////////////////////////////
+    // mat2 conversions
+
+    template <typename T> 
+    template <typename U> 
+    inline _xmat2<T>::_xmat2(const _xmat2<U>& m)
+    {
+        this->value[0] = _xvec2<T>(m[0]);
+        this->value[1] = _xvec2<T>(m[1]);
+	}
+
+    template <typename T> 
+    inline _xmat2<T>::_xmat2(const _xmat3<T>& m)
+    {
+        this->value[0] = _xvec2<T>(m[0]);
+        this->value[1] = _xvec2<T>(m[1]);
+    }
+
+    template <typename T> 
+    inline _xmat2<T>::_xmat2(const _xmat4<T>& m)
+    {
+        this->value[0] = _xvec2<T>(m[0]);
+        this->value[1] = _xvec2<T>(m[1]);
+    }
+
+	template <typename T> 
+    inline _xmat2<T>::_xmat2(const _xmat2x3<T>& m)
+    {
+        this->value[0] = _xvec2<T>(m[0]);
+        this->value[1] = _xvec2<T>(m[1]);
+    }
+
+    template <typename T> 
+    inline _xmat2<T>::_xmat2(const _xmat3x2<T>& m)
+    {
+        this->value[0] = m[0];
+        this->value[1] = m[1];
+    }
+
+    template <typename T> 
+    inline _xmat2<T>::_xmat2(const _xmat2x4<T>& m)
+    {
+        this->value[0] = _xvec2<T>(m[0]);
+        this->value[1] = _xvec2<T>(m[1]);
+    }
+
+    template <typename T> 
+    inline _xmat2<T>::_xmat2(const _xmat4x2<T>& m)
+    {
+        this->value[0] = m[0];
+        this->value[1] = m[1];
+    }
+
+    template <typename T> 
+    inline _xmat2<T>::_xmat2(const _xmat3x4<T>& m)
+    {
+        this->value[0] = _xvec2<T>(m[0]);
+        this->value[1] = _xvec2<T>(m[1]);
+    }
+
+    template <typename T> 
+    inline _xmat2<T>::_xmat2(const _xmat4x3<T>& m)
+    {
+        this->value[0] = _xvec2<T>(m[0]);
+        this->value[1] = _xvec2<T>(m[1]);
+    }
+
+/*
+    template <typename T> 
+    inline _xmat2<T>::_xmat2(const T* a)
+    {
+        this->value[0] = _xvec2<T>(a[0], a[1]);
+        this->value[1] = _xvec2<T>(a[2], a[3]);
+    }
+*/
+
+    template <typename T> 
+    inline _xmat2<T> _xmat2<T>::_inverse() const
+    {
+        T Determinant = value[0][0] * value[1][1] - value[1][0] * value[0][1];
+
+        _xmat2<T> Inverse(
+            + value[1][1] / Determinant,
+            - value[1][0] / Determinant,
+            - value[0][1] / Determinant, 
+            + value[0][0] / Determinant);
+        return Inverse;
+    }
+
+    //////////////////////////////////////////////////////////////
+    // mat3 operators
+
+    // This function shouldn't required but it seems that VC7.1 have an optimisation bug if this operator wasn't declared
+    template <typename T> 
+    inline _xmat2<T>& _xmat2<T>::operator=(const _xmat2<T>& m)
+    {
+	    this->value[0] = m[0];
+	    this->value[1] = m[1];
+	    return *this;
+    }
+
+    template <typename T> 
+    inline _xmat2<T>& _xmat2<T>::operator+= (const T s)
+    {
+	    this->value[0] += s;
+	    this->value[1] += s;
+	    return *this;
+    }
+
+    template <typename T> 
+    inline _xmat2<T>& _xmat2<T>::operator+= (const _xmat2<T>& m)
+    {
+	    this->value[0] += m[0];
+	    this->value[1] += m[1];
+	    return *this;
+    }
+
+    template <typename T> 
+    inline _xmat2<T>& _xmat2<T>::operator-= (const T s)
+    {
+	    this->value[0] -= s;
+	    this->value[1] -= s;
+	    return *this;
+    }
+
+    template <typename T> 
+    inline _xmat2<T>& _xmat2<T>::operator-= (const _xmat2<T>& m)
+    {
+	    this->value[0] -= m[0];
+	    this->value[1] -= m[1];
+	    return *this;
+    }
+
+    template <typename T> 
+    inline _xmat2<T>& _xmat2<T>::operator*= (const T s)
+    {
+	    this->value[0] *= s;
+	    this->value[1] *= s;
+	    return *this;
+    }
+
+    template <typename T> 
+    inline _xmat2<T>& _xmat2<T>::operator*= (const _xmat2<T>& m)
+    {
+        return (*this = *this * m);
+    }
+
+    template <typename T> 
+    inline _xmat2<T>& _xmat2<T>::operator/= (const T s)
+    {
+	    this->value[0] /= s;
+	    this->value[1] /= s;
+	    return *this;
+    }
+
+    template <typename T> 
+    inline _xmat2<T>& _xmat2<T>::operator/= (const _xmat2<T>& m)
+    {
+        return (*this = *this / m);
+    }
+
+    template <typename T> 
+    inline _xmat2<T>& _xmat2<T>::operator++ ()
+    {
+	    ++this->value[0];
+	    ++this->value[1];
+	    return *this;
+    }
+
+    template <typename T> 
+    inline _xmat2<T>& _xmat2<T>::operator-- ()
+    {
+	    --this->value[0];
+	    --this->value[1];
+	    return *this;
+    }
+
+    //////////////////////////////////////////////////////////////
+	// Binary operators
+
+    template <typename T> 
+    inline _xmat2<T> operator+ (const _xmat2<T>& m, const T s)
+    {
+        return _xmat2<T>(
+            m[0] + s,
+            m[1] + s);
+    }
+
+    template <typename T> 
+    inline _xmat2<T> operator+ (const T s, const _xmat2<T>& m)
+    {
+        return _xmat2<T>(
+            m[0] + s,
+            m[1] + s);
+    }
+
+    template <typename T> 
+    inline _xvec2<T> operator+ (const _xmat2<T>& m, const _xvec2<T>& v)
+    {
+
+    }
+
+    template <typename T> 
+    inline _xvec2<T> operator+ (const _xvec2<T>& v, const _xmat2<T>& m)
+    {
+
+    }
+
+    template <typename T> 
+    inline _xmat2<T> operator+ (const _xmat2<T>& m1, const _xmat2<T>& m2)
+    {
+        return _xmat2<T>(
+            m1[0] + m2[0],
+            m1[1] + m2[1]);
+    }
+
+    template <typename T> 
+    inline _xmat2<T> operator- (const _xmat2<T>& m, const T s)
+    {
+        return _xmat2<T>(
+            m[0] - s,
+            m[1] - s);
+    }
+
+    template <typename T> 
+    inline _xmat2<T> operator- (const T s, const _xmat2<T>& m)
+    {
+        return _xmat2<T>(
+            s - m[0],
+            s - m[1]);
+    }
+
+    template <typename T> 
+    inline _xmat2<T> operator- (const _xmat2<T>& m, const _xvec2<T>& v)
+    {
+
+    }
+
+    template <typename T> 
+    inline _xmat2<T> operator- (const _xvec2<T>& v, const _xmat2<T>& m)
+    {
+
+    }
+
+    template <typename T> 
+    inline _xmat2<T> operator- (const _xmat2<T>& m1, const _xmat2<T>& m2)
+    {
+        return _xmat2<T>(
+            m1[0] - m2[0],
+            m1[1] - m2[1]);
+    }
+
+    template <typename T> 
+    inline _xmat2<T> operator* (const _xmat2<T>& m, const T s)
+    {
+        return _xmat2<T>(
+            m[0] * s,
+            m[1] * s);
+    }
+
+    template <typename T> 
+    inline _xmat2<T> operator* (const T s, const _xmat2<T>& m)
+    {
+        return _xmat2<T>(
+            m[0] * s,
+            m[1] * s);
+    }
+
+    template <typename T> 
+    inline _xvec2<T> operator* (const _xmat2<T>& m, const _xvec2<T>& v)
+    {
+        return _xvec2<T>(
+            m[0][0] * v.x + m[1][0] * v.y,
+            m[0][1] * v.x + m[1][1] * v.y);
+    }
+
+    template <typename T> 
+    inline _xvec2<T> operator* (const _xvec2<T>& v, const _xmat2<T>& m)
+    {
+        return _xvec2<T>(
+            m[0][0] * v.x + m[0][1] * v.y,
+            m[1][0] * v.x + m[1][1] * v.y);
+    }
+
+    template <typename T> 
+    inline _xmat2<T> operator* (const _xmat2<T>& m1, const _xmat2<T>& m2)
+    {
+        return _xmat2<T>(
+            m1[0][0] * m2[0][0] + m1[1][0] * m2[0][1],
+            m1[0][1] * m2[0][0] + m1[1][1] * m2[0][1],
+            m1[0][1] * m2[1][0] + m1[1][1] * m2[1][1],
+            m1[0][0] * m2[1][0] + m1[1][0] * m2[1][1]);
+    }
+
+    template <typename T> 
+    inline _xmat2<T> operator/ (const _xmat2<T>& m, const T s)
+    {
+        return _xmat2<T>(
+            m[0] / s,
+            m[1] / s);
+    }
+
+    template <typename T> 
+    inline _xmat2<T> operator/ (const T s, const _xmat2<T>& m)
+    {
+        return _xmat2<T>(
+            s / m[0],
+            s / m[1]);
+    }
+
+    template <typename T> 
+    inline _xvec2<T> operator/ (const _xmat2<T>& m, const _xvec2<T>& v)
+    {
+        return m._inverse() * v;
+    }
+
+    template <typename T> 
+    inline _xvec2<T> operator/ (const _xvec2<T>& v, const _xmat2<T>& m)
+    {
+        return v * m._inverse();
+    }
+
+    template <typename T> 
+    inline _xmat2<T> operator/ (const _xmat2<T>& m1, const _xmat2<T>& m2)
+    {
+        return m1 * m2._inverse();
+    }
+
+	// Unary constant operators
+    template <typename T> 
+    inline const _xmat2<T> operator- (const _xmat2<T>& m)
+    {
+        return _xmat2<T>(
+            -m.value[0], 
+            -m.value[1]);
+    }
+
+    template <typename T> 
+    inline const _xmat2<T> operator-- (const _xmat2<T>& m, int) 
+    {
+        return _xmat2<T>(
+            m.value[0] - T(1),
+            m.value[1] - T(1));
+    }
+
+    template <typename T> 
+    inline const _xmat2<T> operator++ (const _xmat2<T>& m, int) 
+    {
+        return _xmat2<T>(
+            m.value[0] + T(1),
+            m.value[1] + T(1));
+    }
+
+} //namespace detail
+} //namespace glm
+
+#endif //__xmat2x2_inl__

+ 143 - 0
experimental/sse/glm/core/_xmat2x3.h

@@ -0,0 +1,143 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2008 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2006-10-01
+// Updated : 2006-10-01
+// Licence : This source is under GNU LGPL licence
+// File    : _mat2x3.h
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef __mat2x3_h__
+#define __mat2x3_h__
+
+namespace glm{
+namespace detail{
+
+    template <typename T> class _xvec2;
+    template <typename T> class _xvec3;
+    template <typename T> class _xvec4;
+    template <typename T> class _xmat2;
+    template <typename T> class _xmat3;
+    template <typename T> class _xmat4;
+    template <typename T> class _xmat2x4;
+    template <typename T> class _xmat3x2;
+    template <typename T> class _xmat3x4;
+    template <typename T> class _xmat4x2;
+    template <typename T> class _xmat4x3;
+
+    //!< \brief Template for 2 * 3 matrix of floating-point numbers.
+    template <typename T> 
+	class _xmat2x3
+    {
+    private:
+        // Data
+        _xvec3<T> value[2];
+
+    public:
+		typedef T value_type;
+		typedef _xvec3<T> col_type;
+		typedef _xvec2<T> row_type;
+		typedef int size_type;
+		static const size_type col_size;
+		static const size_type row_size;
+
+        // Constructors
+        _xmat2x3();
+        explicit _xmat2x3(const T x);
+        explicit _xmat2x3(
+            const T x0, const T y0, const T z0,
+            const T x1, const T y1, const T z1);
+        explicit _xmat2x3(
+            const _xvec3<T>& v0, 
+            const _xvec3<T>& v1);
+
+        // Conversion
+		template <typename U> 
+		explicit _xmat2x3(const _xmat2x3<U>& m);
+
+		explicit _xmat2x3(const _xmat2<T>& x);
+        explicit _xmat2x3(const _xmat3<T>& x);
+        explicit _xmat2x3(const _xmat4<T>& x);
+        explicit _xmat2x3(const _xmat2x4<T>& x);
+        explicit _xmat2x3(const _xmat3x2<T>& x);
+        explicit _xmat2x3(const _xmat3x4<T>& x);
+        explicit _xmat2x3(const _xmat4x2<T>& x);
+        explicit _xmat2x3(const _xmat4x3<T>& x);
+
+        // Accesses
+        _xvec3<T>& operator[](int i) {return value[i];}
+        const _xvec3<T> & operator[](int i) const {return value[i];}
+		// operator T*() {return &value[0][0];}
+		// operator const T*() const {return &value[0][0];}
+		operator T*() {return (T*)this;}
+        operator const T*() const {return (const T*)this;}
+
+        // Unary updatable operators
+        _xmat2x3<T>& operator=  (const _xmat2x3<T>& m);
+        _xmat2x3<T>& operator+= (const T s);
+        _xmat2x3<T>& operator+= (const _xmat2x3<T>& m);
+        _xmat2x3<T>& operator-= (const T s);
+        _xmat2x3<T>& operator-= (const _xmat2x3<T>& m);
+        _xmat2x3<T>& operator*= (const T s);
+        _xmat2x3<T>& operator*= (const _xmat3x2<T>& m);
+        _xmat2x3<T>& operator/= (const T s);
+/* ToDo
+        _xmat2x3<T>& operator/= (const _xmat3x2<T>& m);
+*/
+        _xmat2x3<T>& operator++ ();
+        _xmat2x3<T>& operator-- ();
+
+        // Unary constant operators
+        const _xmat2x3<T> operator- () const;
+        const _xmat2x3<T> operator++ (int n) const;
+        const _xmat2x3<T> operator-- (int n) const;
+    };
+
+    // Binary operators
+    template <typename T> 
+    _xmat2x3<T> operator+ (const _xmat2x3<T>& m, const T s);
+    
+    template <typename T> 
+    _xmat2x3<T> operator+ (const _xmat2x3<T>& m1, const _xmat2x3<T>& m2);
+    
+    template <typename T> 
+    _xmat2x3<T> operator- (const _xmat2x3<T>& m, const T s);
+
+    template <typename T> 
+    _xmat2x3<T> operator- (const _xmat2x3<T>& m1, const _xmat2x3<T>& m2);
+
+    template <typename T> 
+    _xmat2x3<T> operator* (const _xmat2x3<T>& m, const T s);
+
+    template <typename T> 
+    _xmat2x3<T> operator* (const T s, const _xmat2x3<T>& m);
+
+    template <typename T>
+    _xvec3<T> operator* (const _xmat2x3<T>& m, const _xvec2<T>& v);
+
+    template <typename T> 
+    _xvec3<T> operator* (const _xvec3<T>& v, const _xmat2x3<T>& m);
+
+    template <typename T>
+    _xmat3<T> operator* (const _xmat2x3<T>& m1, const _xmat3x2<T>& m2);
+
+    template <typename T> 
+    _xmat3x2<T> operator/ (const _xmat2x3<T>& m, const T s);
+
+    template <typename T> 
+    _xmat3x2<T> operator/ (const T s, const _xmat2x3<T>& m);
+/* ToDo
+    template <typename T> 
+    _xvec3<T> operator/ (const _xmat2x3<T>& m, const _xvec2<T>& v);
+
+    template <typename T> 
+    _xvec2<T> operator/ (const _xvec3<T>& v, const _xmat2x3<T>& m);
+
+    template <typename T> 
+    _xmat3<T> operator/ (const _xmat3x2<T>& m1, const _xmat2x3<T>& m2);
+*/
+
+} //namespace detail
+} //namespace glm
+
+#endif //__mat2x3_h__

+ 379 - 0
experimental/sse/glm/core/_xmat2x3.inl

@@ -0,0 +1,379 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2008 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2006-08-05
+// Updated : 2006-10-01
+// Licence : This source is under GNU LGPL licence
+// File    : _mat2x3.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef __mat2x3_inl__
+#define __mat2x3_inl__
+
+#include "./_xmat2x3.h"
+
+namespace glm{
+namespace detail{
+
+	template <typename T> const typename _xmat2x3<T>::size_type _xmat2x3<T>::col_size = 2;
+	template <typename T> const typename _xmat2x3<T>::size_type _xmat2x3<T>::row_size = 3;
+
+    //////////////////////////////////////////////////////////////
+    // Constructors
+
+    template <typename T> 
+    inline _xmat2x3<T>::_xmat2x3()
+    {
+        this->value[0] = _xvec3<T>(T(1), T(0), T(0));
+        this->value[1] = _xvec3<T>(T(0), T(1), T(0));
+    }
+
+    template <typename T> 
+    inline _xmat2x3<T>::_xmat2x3(const T f)
+    {
+        this->value[0] = _xvec3<T>(f, T(0), T(0));
+        this->value[1] = _xvec3<T>(T(0), f, T(0));
+    }
+
+    template <typename T> 
+    inline _xmat2x3<T>::_xmat2x3
+    (
+        const T x0, const T y0, const T z0,
+        const T x1, const T y1, const T z1
+    )
+    {
+        this->value[0] = _xvec3<T>(x0, y0, z0);
+        this->value[1] = _xvec3<T>(x1, y1, z1);
+    }
+
+    template <typename T> 
+    inline _xmat2x3<T>::_xmat2x3
+    (
+        const _xvec3<T> & v0, 
+        const _xvec3<T> & v1
+    )
+    {
+        this->value[0] = v0;
+        this->value[1] = v1;
+    }
+
+    // Conversion
+    template <typename T> 
+    template <typename U> 
+    inline _xmat2x3<T>::_xmat2x3(const _xmat2x3<U>& m)
+    {
+        this->value[0] = _xvec3<T>(m[0]);
+        this->value[1] = _xvec3<T>(m[1]);
+	}
+
+    template <typename T> 
+    inline _xmat2x3<T>::_xmat2x3(const _xmat2<T>& m)
+    {
+        this->value[0] = _xvec3<T>(m[0], T(0));
+        this->value[1] = _xvec3<T>(m[1], T(0));
+    }
+
+    template <typename T> 
+    inline _xmat2x3<T>::_xmat2x3(const _xmat3<T>& m)
+    {
+        this->value[0] = _xvec3<T>(m[0]);
+        this->value[1] = _xvec3<T>(m[1]);
+    }
+
+    template <typename T> 
+    inline _xmat2x3<T>::_xmat2x3(const _xmat4<T>& m)
+    {
+        this->value[0] = _xvec3<T>(m[0]);
+        this->value[1] = _xvec3<T>(m[1]);
+    }
+
+    template <typename T> 
+    inline _xmat2x3<T>::_xmat2x3(const _xmat2x4<T>& m)
+    {
+        this->value[0] = _xvec3<T>(m[0]);
+        this->value[1] = _xvec3<T>(m[1]);
+    }
+
+    template <typename T> 
+    inline _xmat2x3<T>::_xmat2x3(const _xmat3x2<T>& m)
+    {
+        this->value[0] = _xvec3<T>(m[0], T(0));
+        this->value[1] = _xvec3<T>(m[1], T(0));
+    }
+
+    template <typename T> 
+    inline _xmat2x3<T>::_xmat2x3(const _xmat3x4<T>& m)
+    {
+        this->value[0] = _xvec3<T>(m[0]);
+        this->value[1] = _xvec3<T>(m[1]);
+    }
+
+    template <typename T> 
+    inline _xmat2x3<T>::_xmat2x3(const _xmat4x2<T>& m)
+    {
+        this->value[0] = _xvec3<T>(m[0], T(0));
+        this->value[1] = _xvec3<T>(m[1], T(0));
+    }
+
+    template <typename T> 
+    inline _xmat2x3<T>::_xmat2x3(const _xmat4x3<T>& m)
+    {
+        this->value[0] = m[0];
+        this->value[1] = m[1];
+    }
+
+    //////////////////////////////////////////////////////////////
+    // Unary updatable operators
+
+    template <typename T> 
+    inline _xmat2x3<T>& _xmat2x3<T>::operator= (const _xmat2x3<T>& m)
+    {
+        this->value[0] = m[0];
+        this->value[1] = m[1];
+        return *this;
+    }
+
+    template <typename T> 
+    inline _xmat2x3<T>& _xmat2x3<T>::operator+= (const T s)
+    {
+        this->value[0] += s;
+        this->value[1] += s;
+        return *this;
+    }
+
+    template <typename T> 
+    inline _xmat2x3<T>& _xmat2x3<T>::operator+= (const _xmat2x3<T>& m)
+    {
+        this->value[0] += m[0];
+        this->value[1] += m[1];
+        return *this;
+    }
+
+    template <typename T> 
+    inline _xmat2x3<T>& _xmat2x3<T>::operator-= (const T s)
+    {
+        this->value[0] -= s;
+        this->value[1] -= s;
+        return *this;
+    }
+
+    template <typename T> 
+    inline _xmat2x3<T>& _xmat2x3<T>::operator-= (const _xmat2x3<T>& m)
+    {
+        this->value[0] -= m[0];
+        this->value[1] -= m[1];
+        return *this;
+    }
+
+    template <typename T> 
+    inline _xmat2x3<T>& _xmat2x3<T>::operator*= (const T s)
+    {
+        this->value[0] *= s;
+        this->value[1] *= s;
+        return *this;
+    }
+
+    template <typename T> 
+    inline _xmat2x3<T>& _xmat2x3<T>::operator*= (const _xmat3x2<T>& m)
+    {
+        return (*this = _xmat2x3<T>(*this * m));
+    }
+
+    template <typename T> 
+    inline _xmat2x3<T> & _xmat2x3<T>::operator/= (const T s)
+    {
+        this->value[0] /= s;
+        this->value[1] /= s;
+        return *this;
+    }
+/* ToDo
+    template <typename T> 
+    inline _xmat2x3<T>& _xmat2x3<T>::operator/= (const _xmat3x2<T>& m)
+    {
+        return (*this = _xmat2x3<T>(*this / m));
+    }
+*/
+    template <typename T> 
+    inline _xmat2x3<T>& _xmat2x3<T>::operator++ ()
+    {
+        ++this->value[0];
+        ++this->value[1];
+        return *this;
+    }
+
+    template <typename T> 
+    inline _xmat2x3<T>& _xmat2x3<T>::operator-- ()
+    {
+        --this->value[0];
+        --this->value[1];
+        return *this;
+    }
+    
+    //////////////////////////////////////////////////////////////
+    // Unary constant operators
+    template <typename T> 
+    inline const _xmat2x3<T> _xmat2x3<T>::operator- () const
+    {
+        return _xmat2x3<T>(
+            -this->value[0], 
+            -this->value[1]);
+    }
+
+    template <typename T> 
+    inline const _xmat2x3<T> _xmat2x3<T>::operator-- (int n) const 
+    {
+        _xmat2x3<T> m = *this;
+        --m.value[0];
+        --m.value[1];
+        return m;
+    }
+
+    template <typename T> 
+    inline const _xmat2x3<T> _xmat2x3<T>::operator++ (int n) const
+    {
+        _xmat2x3<T> m = *this;
+        ++m.value[0];
+        ++m.value[1];
+        return m;
+    }
+
+    //////////////////////////////////////////////////////////////
+    // Binary operators
+
+    template <typename T> 
+    inline _xmat2x3<T> operator+ (const _xmat2x3<T>& m, const T s)
+    {
+        return _xmat2x3<T>(
+            m[0] + s,
+            m[1] + s);
+    }
+
+    template <typename T> 
+    inline _xmat2x3<T> operator+ (const _xmat2x3<T>& m1, const _xmat2x3<T>& m2)
+    {
+        return _xmat2x3<T>(
+            m1[0] + m2[0],
+            m1[1] + m2[1]);
+    }
+
+    template <typename T> 
+    inline _xmat2x3<T> operator- (const _xmat2x3<T>& m, const T s)
+    {
+        return _xmat2x3<T>(
+            m[0] - s,
+            m[1] - s);
+    }
+
+    template <typename T> 
+    inline _xmat2x3<T> operator- (const _xmat2x3<T>& m1, const _xmat2x3<T>& m2)
+    {
+        return _xmat2x3<T>(
+            m1[0] - m2[0],
+            m1[1] - m2[1]);
+    }
+
+    template <typename T> 
+    inline _xmat2x3<T> operator* (const _xmat2x3<T>& m, const T s)
+    {
+        return _xmat2x3<T>(
+            m[0] * s,
+            m[1] * s);
+    }
+
+    template <typename T> 
+    inline _xmat2x3<T> operator* (const T s, const _xmat2x3<T> & m)
+    {
+        return _xmat2x3<T>(
+            m[0] * s,
+            m[1] * s);
+    }
+   
+    template <typename T>
+    inline _xvec3<T> operator* (const _xmat2x3<T>& m, const _xvec2<T>& v)
+    {
+        return _xvec3<T>(
+            m[0][0] * v.x + m[1][0] * v.y,
+            m[0][1] * v.x + m[1][1] * v.y,
+            m[0][2] * v.x + m[1][2] * v.y,
+            m[0][3] * v.x + m[1][3] * v.y);
+    }
+
+    template <typename T> 
+    inline _xvec2<T> operator* (const _xvec3<T>& v, const _xmat2x3<T>& m) 
+    {
+        return _xvec2<T>(
+            m[0][0] * v.x + m[1][0] * v.y + m[2][0] * v.z + m[3][0] * v.w,
+            m[0][1] * v.x + m[1][1] * v.y + m[2][1] * v.z + m[3][1] * v.w);
+    }
+
+    template <typename T> 
+    inline _xmat3<T> operator* (const _xmat2x3<T>& m1, const _xmat3x2<T>& m2)
+    {
+        const T SrcA00 = m1[0][0];
+        const T SrcA01 = m1[0][1];
+        const T SrcA02 = m1[0][2];
+        const T SrcA10 = m1[1][0];
+        const T SrcA11 = m1[1][1];
+        const T SrcA12 = m1[1][2];
+
+        const T SrcB00 = m2[0][0];
+        const T SrcB01 = m2[0][1];
+        const T SrcB10 = m2[1][0];
+        const T SrcB11 = m2[1][1];
+        const T SrcB20 = m2[2][0];
+        const T SrcB21 = m2[2][1];
+
+        _xmat3<T> Result;
+        Result[0][0] = SrcA00 * SrcB00 + SrcA10 * SrcB01;
+        Result[0][1] = SrcA01 * SrcB00 + SrcA11 * SrcB01;
+        Result[0][2] = SrcA02 * SrcB00 + SrcA12 * SrcB01;
+        Result[1][0] = SrcA00 * SrcB10 + SrcA10 * SrcB11;
+        Result[1][1] = SrcA01 * SrcB10 + SrcA11 * SrcB11;
+        Result[1][2] = SrcA02 * SrcB10 + SrcA12 * SrcB11;
+        Result[2][0] = SrcA00 * SrcB20 + SrcA10 * SrcB21;
+        Result[2][1] = SrcA01 * SrcB20 + SrcA11 * SrcB21;
+        Result[2][2] = SrcA02 * SrcB20 + SrcA12 * SrcB21;
+        return Result;
+    }
+
+    template <typename T> 
+    inline _xmat2x3<T> operator/ (const _xmat2x3<T>& m, const T s)
+    {
+        return _xmat2x3<T>(
+            m.value[0] / s,
+            m.value[1] / s,
+            m.value[2] / s);        
+    }
+
+    template <typename T> 
+    inline _xmat2x3<T> operator/ (const T s, const _xmat2x3<T>& m)
+    {
+        return _xmat2x3<T>(
+            s / m.value[0],
+            s / m.value[1],
+            s / m.value[2]);        
+    }
+/* ToDo
+    template <typename T> 
+    inline _xvec3<T> operator/ (const _xmat2x3<T>& m, const _xvec2<T>& v)
+    {
+      
+    }
+
+    template <typename T> 
+    inline _xvec2<T> operator/ (const _xvec3<T>& v, const _xmat3x2<T>& m)
+    {
+      
+    }
+
+    template <typename T> 
+    inline _xmat3<T> operator/ (const _xmat2x3<T>& m1, const _xmat3x2<T>& m2)
+    {
+
+    }
+*/
+
+} //namespace detail
+} //namespace glm
+
+#endif //__mat2x3_inl__

+ 144 - 0
experimental/sse/glm/core/_xmat2x4.h

@@ -0,0 +1,144 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2008 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2006-08-05
+// Updated : 2006-10-01
+// Licence : This source is under GNU LGPL licence
+// File    : _mat2x4.h
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef __mat2x4_h__
+#define __mat2x4_h__
+
+namespace glm{
+namespace detail{
+
+    template <typename T> class _xvec2;
+    template <typename T> class _xvec3;
+    template <typename T> class _xvec4;
+    template <typename T> class _xmat2;
+    template <typename T> class _xmat3;
+    template <typename T> class _xmat4;
+    template <typename T> class _xmat2x3;
+    template <typename T> class _xmat3x2;
+    template <typename T> class _xmat3x4;
+    template <typename T> class _xmat4x2;
+    template <typename T> class _xmat4x3;
+
+    //!< \brief Template for 2 * 4 matrix of floating-point numbers.
+    template <typename T> 
+	class _xmat2x4
+    {
+    private:
+        // Data
+        _xvec4<T> value[2];
+
+    public:
+		typedef T value_type;
+		typedef _xvec2<T> col_type;
+		typedef _xvec4<T> row_type;
+		typedef int size_type;
+		static const size_type col_size;
+		static const size_type row_size;
+
+        // Constructors
+        _xmat2x4();
+        explicit _xmat2x4(const T x);
+        explicit _xmat2x4(
+            const T x0, const T y0, const T z0, const T w0,
+            const T x1, const T y1, const T z1, const T w1);
+        explicit _xmat2x4(
+            const _xvec4<T>& v0, 
+            const _xvec4<T>& v1);
+
+        // Conversion
+		template <typename U> 
+		explicit _xmat2x4(const _xmat2x4<U>& m);
+
+		explicit _xmat2x4(const _xmat2<T>& x);
+        explicit _xmat2x4(const _xmat3<T>& x);
+        explicit _xmat2x4(const _xmat4<T>& x);
+        explicit _xmat2x4(const _xmat2x3<T>& x);
+        //explicit _xmat2x4(const _xmat2x4<T>& x);
+        explicit _xmat2x4(const _xmat3x2<T>& x);
+        explicit _xmat2x4(const _xmat3x4<T>& x);
+        explicit _xmat2x4(const _xmat4x2<T>& x);
+        explicit _xmat2x4(const _xmat4x3<T>& x);
+
+        // Accesses
+        _xvec4<T>& operator[](int i) {return value[i];}
+        const _xvec4<T> & operator[](int i) const {return value[i];}
+		// operator T*() {return &value[0][0];}
+		// operator const T*() const {return &value[0][0];}
+		operator T*() {return (T*)this;}
+        operator const T*() const {return (const T*)this;}
+
+        // Unary updatable operators
+        _xmat2x4<T>& operator=  (const _xmat2x4<T>& m);
+        _xmat2x4<T>& operator+= (const T s);
+        _xmat2x4<T>& operator+= (const _xmat2x4<T>& m);
+        _xmat2x4<T>& operator-= (const T s);
+        _xmat2x4<T>& operator-= (const _xmat2x4<T>& m);
+        _xmat2x4<T>& operator*= (const T s);
+        _xmat2x4<T>& operator*= (const _xmat4x2<T>& m);
+        _xmat2x4<T>& operator/= (const T s);
+/* ToDo
+        _xmat2x4<T>& operator/= (const _xmat4x2<T>& m);
+*/
+        _xmat2x4<T>& operator++ ();
+        _xmat2x4<T>& operator-- ();
+
+        // Unary constant operators
+        const _xmat2x4<T> operator- () const;
+        const _xmat2x4<T> operator++ (int n) const;
+        const _xmat2x4<T> operator-- (int n) const;
+    };
+
+    // Binary operators
+    template <typename T> 
+    _xmat2x4<T> operator+ (const _xmat2x4<T>& m, const T s);
+    
+    template <typename T> 
+    _xmat2x4<T> operator+ (const _xmat2x4<T>& m1, const _xmat2x4<T>& m2);
+    
+    template <typename T> 
+    _xmat2x4<T> operator- (const _xmat2x4<T>& m, const T s);
+
+    template <typename T> 
+    _xmat2x4<T> operator- (const _xmat2x4<T>& m1, const _xmat2x4<T>& m2);
+
+    template <typename T> 
+    _xmat2x4<T> operator* (const _xmat2x4<T>& m, const T s);
+
+    template <typename T> 
+    _xmat2x4<T> operator* (const T s, const _xmat2x4<T>& m);
+
+    template <typename T>
+    _xvec4<T> operator* (const _xmat2x4<T>& m, const _xvec2<T>& v);
+
+    template <typename T> 
+    _xvec3<T> operator* (const _xvec4<T>& v, const _xmat2x4<T>& m);
+
+    template <typename T>
+    _xmat4<T> operator* (const _xmat2x4<T>& m1, const _xmat4x2<T>& m2);
+
+    template <typename T> 
+    _xmat4x2<T> operator/ (const _xmat2x4<T>& m, const T s);
+
+    template <typename T> 
+    _xmat4x2<T> operator/ (const T s, const _xmat2x4<T>& m);
+/* ToDo
+    template <typename T> 
+    _xvec4<T> operator/ (const _xmat2x4<T>& m, const _xvec2<T>& v);
+
+    template <typename T> 
+    _xvec2<T> operator/ (const _xvec4<T>& v, const _xmat2x4<T>& m);
+
+    template <typename T> 
+    _xmat4<T> operator/ (const _xmat4x2<T>& m1, const _xmat2x4<T>& m2);
+*/
+
+} //namespace detail
+} //namespace glm
+
+#endif //__mat2x4_h__

+ 392 - 0
experimental/sse/glm/core/_xmat2x4.inl

@@ -0,0 +1,392 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2008 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2006-08-05
+// Updated : 2006-10-01
+// Licence : This source is under GNU LGPL licence
+// File    : _mat2x4.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef __mat2x4_inl__
+#define __mat2x4_inl__
+
+#include "./_xmat2x4.h"
+
+namespace glm{
+namespace detail{
+
+	template <typename T> const typename _xmat2x4<T>::size_type _xmat2x4<T>::col_size = 2;
+	template <typename T> const typename _xmat2x4<T>::size_type _xmat2x4<T>::row_size = 4;
+
+    //////////////////////////////////////////////////////////////
+    // Constructors
+
+    template <typename T> 
+    inline _xmat2x4<T>::_xmat2x4()
+    {
+        this->value[0] = _xvec4<T>(1, 0, 0, 0);
+        this->value[1] = _xvec4<T>(0, 1, 0, 0);
+    }
+
+    template <typename T> 
+    inline _xmat2x4<T>::_xmat2x4(const T f)
+    {
+        this->value[0] = _xvec4<T>(f, 0, 0, 0);
+        this->value[1] = _xvec4<T>(0, f, 0, 0);
+    }
+
+    template <typename T> 
+    inline _xmat2x4<T>::_xmat2x4
+    (
+        const T x0, const T y0, const T z0, const T w0,
+        const T x1, const T y1, const T z1, const T w1
+    )
+    {
+        this->value[0] = _xvec4<T>(x0, y0, z0, w0);
+        this->value[1] = _xvec4<T>(x1, y1, z1, w1);
+    }
+
+    template <typename T> 
+    inline _xmat2x4<T>::_xmat2x4
+    (
+        const _xvec4<T> & v0, 
+        const _xvec4<T> & v1
+    )
+    {
+        this->value[0] = v0;
+        this->value[1] = v1;
+    }
+
+    // Conversion
+    template <typename T> 
+    template <typename U> 
+    inline _xmat2x4<T>::_xmat2x4(const _xmat2x4<U>& m)
+    {
+        this->value[0] = _xvec4<T>(m[0]);
+        this->value[1] = _xvec4<T>(m[1]);
+	}
+
+    template <typename T> 
+    inline _xmat2x4<T>::_xmat2x4(const _xmat2<T>& m)
+    {
+        this->value[0] = _xvec4<T>(m[0], _xvec2<T>(0));
+        this->value[1] = _xvec4<T>(m[1], _xvec2<T>(0));
+    }
+
+    template <typename T> 
+    inline _xmat2x4<T>::_xmat2x4(const _xmat3<T>& m)
+    {
+        this->value[0] = _xvec4<T>(m[0], T(0));
+        this->value[1] = _xvec4<T>(m[1], T(0));
+    }
+
+    template <typename T> 
+    inline _xmat2x4<T>::_xmat2x4(const _xmat4<T>& m)
+    {
+        this->value[0] = _xvec4<T>(m[0]);
+        this->value[1] = _xvec4<T>(m[1]);
+    }
+
+    template <typename T> 
+    inline _xmat2x4<T>::_xmat2x4(const _xmat2x3<T>& m)
+    {
+        this->value[0] = _xvec4<T>(m[0], _xvec2<T>(0));
+        this->value[1] = _xvec4<T>(m[1], _xvec2<T>(0));
+    }
+
+    template <typename T> 
+    inline _xmat2x4<T>::_xmat2x4(const _xmat3x2<T>& m)
+    {
+        this->value[0] = _xvec4<T>(m[0], _xvec2<T>(0));
+        this->value[1] = _xvec4<T>(m[1], _xvec2<T>(0));
+    }
+
+    template <typename T> 
+    inline _xmat2x4<T>::_xmat2x4(const _xmat3x4<T>& m)
+    {
+        this->value[0] = m[0];
+        this->value[1] = m[1];
+    }
+
+    template <typename T> 
+    inline _xmat2x4<T>::_xmat2x4(const _xmat4x2<T>& m)
+    {
+        this->value[0] = _xvec4<T>(m[0], _xvec2<T>(T(0)));
+        this->value[1] = _xvec4<T>(m[1], _xvec2<T>(T(0)));
+    }
+
+    template <typename T> 
+    inline _xmat2x4<T>::_xmat2x4(const _xmat4x3<T>& m)
+    {
+        this->value[0] = _xvec4<T>(m[0], T(0));
+        this->value[1] = _xvec4<T>(m[1], T(0));
+    }
+
+    //////////////////////////////////////////////////////////////
+    // Unary updatable operators
+
+    template <typename T> 
+    inline _xmat2x4<T>& _xmat2x4<T>::operator= (const _xmat2x4<T>& m)
+    {
+        this->value[0] = m[0];
+        this->value[1] = m[1];
+        return *this;
+    }
+
+    template <typename T> 
+    inline _xmat2x4<T>& _xmat2x4<T>::operator+= (const T s)
+    {
+        this->value[0] += s;
+        this->value[1] += s;
+        return *this;
+    }
+
+    template <typename T> 
+    inline _xmat2x4<T>& _xmat2x4<T>::operator+= (const _xmat2x4<T>& m)
+    {
+        this->value[0] += m[0];
+        this->value[1] += m[1];
+        return *this;
+    }
+
+    template <typename T> 
+    inline _xmat2x4<T>& _xmat2x4<T>::operator-= (const T s)
+    {
+        this->value[0] -= s;
+        this->value[1] -= s;
+        return *this;
+    }
+
+    template <typename T> 
+    inline _xmat2x4<T>& _xmat2x4<T>::operator-= (const _xmat2x4<T>& m)
+    {
+        this->value[0] -= m[0];
+        this->value[1] -= m[1];
+        return *this;
+    }
+
+    template <typename T> 
+    inline _xmat2x4<T>& _xmat2x4<T>::operator*= (const T s)
+    {
+        this->value[0] *= s;
+        this->value[1] *= s;
+        return *this;
+    }
+
+    template <typename T> 
+    inline _xmat2x4<T>& _xmat2x4<T>::operator*= (const _xmat4x2<T>& m)
+    {
+        return (*this = _xmat2x4<T>(*this * m));
+    }
+
+    template <typename T> 
+    inline _xmat2x4<T> & _xmat2x4<T>::operator/= (const T s)
+    {
+        this->value[0] /= s;
+        this->value[1] /= s;
+        return *this;
+    }
+/* ToDo
+    template <typename T> 
+    inline _xmat2x4<T>& _xmat2x4<T>::operator/= (const _xmat4x2<T>& m)
+    {
+        return (*this = _xmat2x4<T>(*this / m));
+    }
+*/
+    template <typename T> 
+    inline _xmat2x4<T>& _xmat2x4<T>::operator++ ()
+    {
+        ++this->value[0];
+        ++this->value[1];
+        return *this;
+    }
+
+    template <typename T> 
+    inline _xmat2x4<T>& _xmat2x4<T>::operator-- ()
+    {
+        --this->value[0];
+        --this->value[1];
+        return *this;
+    }
+    
+    //////////////////////////////////////////////////////////////
+    // Unary constant operators
+    template <typename T> 
+    inline const _xmat2x4<T> _xmat2x4<T>::operator- () const
+    {
+        return _xmat2x4<T>(
+            -this->value[0], 
+            -this->value[1]);
+    }
+
+    template <typename T> 
+    inline const _xmat2x4<T> _xmat2x4<T>::operator-- (int n) const 
+    {
+        _xmat2x4<T> m = *this;
+        --m.value[0];
+        --m.value[1];
+        return m;
+    }
+
+    template <typename T> 
+    inline const _xmat2x4<T> _xmat2x4<T>::operator++ (int n) const
+    {
+        _xmat2x4<T> m = *this;
+        ++m.value[0];
+        ++m.value[1];
+        return m;
+    }
+
+    //////////////////////////////////////////////////////////////
+    // Binary operators
+
+    template <typename T> 
+    inline _xmat2x4<T> operator+ (const _xmat2x4<T>& m, const T s)
+    {
+        return _xmat2x4<T>(
+            m[0] + s,
+            m[1] + s);
+    }
+
+    template <typename T> 
+    inline _xmat2x4<T> operator+ (const _xmat2x4<T>& m1, const _xmat2x4<T>& m2)
+    {
+        return _xmat2x4<T>(
+            m1[0] + m2[0],
+            m1[1] + m2[1]);
+    }
+
+    template <typename T> 
+    inline _xmat2x4<T> operator- (const _xmat2x4<T>& m, const T s)
+    {
+        return _xmat2x4<T>(
+            m[0] - s,
+            m[1] - s);
+    }
+
+    template <typename T> 
+    inline _xmat2x4<T> operator- (const _xmat2x4<T>& m1, const _xmat2x4<T>& m2)
+    {
+        return _xmat2x4<T>(
+            m1[0] - m2[0],
+            m1[1] - m2[1]);
+    }
+
+    template <typename T> 
+    inline _xmat2x4<T> operator* (const _xmat2x4<T>& m, const T s)
+    {
+        return _xmat2x4<T>(
+            m[0] * s,
+            m[1] * s);
+    }
+
+    template <typename T> 
+    inline _xmat2x4<T> operator* (const T s, const _xmat2x4<T> & m)
+    {
+        return _xmat2x4<T>(
+            m[0] * s,
+            m[1] * s);
+    }
+   
+    template <typename T>
+    inline _xvec4<T> operator* (const _xmat2x4<T>& m, const _xvec2<T>& v)
+    {
+        return _xvec4<T>(
+            m[0][0] * v.x + m[1][0] * v.y,
+            m[0][1] * v.x + m[1][1] * v.y,
+            m[0][2] * v.x + m[1][2] * v.y,
+            m[0][3] * v.x + m[1][3] * v.y);
+    }
+
+    template <typename T> 
+    inline _xvec2<T> operator* (const _xvec4<T>& v, const _xmat2x4<T>& m) 
+    {
+        return _xvec2<T>(
+            m[0][0] * v.x + m[1][0] * v.y + m[2][0] * v.z + m[3][0] * v.w,
+            m[0][1] * v.x + m[1][1] * v.y + m[2][1] * v.z + m[3][1] * v.w);
+    }
+
+    template <typename T> 
+    inline _xmat4<T> operator* (const _xmat2x4<T>& m1, const _xmat4x2<T>& m2)
+    {
+        const T SrcA00 = m1[0][0];
+        const T SrcA01 = m1[0][1];
+        const T SrcA02 = m1[0][2];
+        const T SrcA03 = m1[0][3];
+        const T SrcA10 = m1[1][0];
+        const T SrcA11 = m1[1][1];
+        const T SrcA12 = m1[1][2];
+        const T SrcA13 = m1[1][3];
+
+        const T SrcB00 = m2[0][0];
+        const T SrcB01 = m2[0][1];
+        const T SrcB10 = m2[1][0];
+        const T SrcB11 = m2[1][1];
+        const T SrcB20 = m2[2][0];
+        const T SrcB21 = m2[2][1];
+        const T SrcB30 = m2[3][0];
+        const T SrcB31 = m2[3][1];
+
+        _xmat4<T> Result;
+        Result[0][0] = SrcA00 * SrcB00 + SrcA10 * SrcB01;
+        Result[0][1] = SrcA01 * SrcB00 + SrcA11 * SrcB01;
+        Result[0][2] = SrcA02 * SrcB00 + SrcA12 * SrcB01;
+        Result[0][3] = SrcA03 * SrcB00 + SrcA13 * SrcB01;
+        Result[1][0] = SrcA00 * SrcB10 + SrcA10 * SrcB11;
+        Result[1][1] = SrcA01 * SrcB10 + SrcA11 * SrcB11;
+        Result[1][2] = SrcA02 * SrcB10 + SrcA12 * SrcB11;
+        Result[1][3] = SrcA03 * SrcB10 + SrcA13 * SrcB11;
+        Result[2][0] = SrcA00 * SrcB20 + SrcA10 * SrcB21;
+        Result[2][1] = SrcA01 * SrcB20 + SrcA11 * SrcB21;
+        Result[2][2] = SrcA02 * SrcB20 + SrcA12 * SrcB21;
+        Result[2][3] = SrcA03 * SrcB20 + SrcA13 * SrcB21;
+        Result[3][0] = SrcA00 * SrcB30 + SrcA10 * SrcB31;
+        Result[3][1] = SrcA01 * SrcB30 + SrcA11 * SrcB31;
+        Result[3][2] = SrcA02 * SrcB30 + SrcA12 * SrcB31;
+        Result[3][3] = SrcA03 * SrcB30 + SrcA13 * SrcB31;
+        return Result;
+    }
+
+    template <typename T> 
+    inline _xmat2x4<T> operator/ (const _xmat2x4<T>& m, const T s)
+    {
+        return _xmat2x4<T>(
+            m.value[0] / s,
+            m.value[1] / s,
+            m.value[2] / s,
+            m.value[3] / s);        
+    }
+
+    template <typename T> 
+    inline _xmat2x4<T> operator/ (const T s, const _xmat2x4<T>& m)
+    {
+        return _xmat2x4<T>(
+            s / m.value[0],
+            s / m.value[1],
+            s / m.value[2],
+            s / m.value[3]);        
+    }
+/* ToDo
+    template <typename T> 
+    inline _xvec4<T> operator/ (const _xmat2x4<T>& m, const _xvec2<T>& v)
+    {
+      
+    }
+
+    template <typename T> 
+    inline _xvec2<T> operator/ (const _xvec4<T>& v, const _xmat4x2<T>& m)
+    {
+      
+    }
+
+    template <typename T> 
+    inline _xmat4<T> operator/ (const _xmat2x4<T>& m1, const _xmat4x2<T>& m2)
+    {
+
+    }
+*/
+
+} //namespace detail
+} //namespace glm
+
+#endif //__mat2x4_inl__

+ 176 - 0
experimental/sse/glm/core/_xmat3.h

@@ -0,0 +1,176 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2008 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2005-01-27
+// Updated : 2007-03-01
+// Licence : This source is under GNU LGPL licence
+// File    : _xmat3.h
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef __xmat3_h__
+#define __xmat3_h__
+
+namespace glm{
+namespace detail{
+
+    template <typename T> class _xvec2;
+    template <typename T> class _xvec3;
+    template <typename T> class _xquat;
+
+	template <typename T> class _xmat2;
+    template <typename T> class _xmat4;
+    template <typename T> class _xmat2x4;
+	template <typename T> class _xmat2x3;
+    template <typename T> class _xmat3x2;
+    template <typename T> class _xmat3x4;
+    template <typename T> class _xmat4x2;
+    template <typename T> class _xmat4x3;
+
+	//!< \brief Template for 3 * 3 matrix of floating-point numbers.
+	template <typename T> 
+	class _xmat3
+    {
+    private:
+        // Data 
+        _xvec3<T> value[3];
+
+    public:
+        _xmat3<T> _inverse() const;
+
+    public:
+		typedef T value_type;
+		typedef _xvec3<T> col_type;
+		typedef _xvec3<T> row_type;
+		typedef int size_type;
+		static const size_type value_size;
+		static const size_type col_size;
+		static const size_type row_size;
+
+        // Constructors
+	    _xmat3();
+        explicit _xmat3(const T x);
+        explicit _xmat3(const T x0, const T y0, const T z0,
+                        const T x1, const T y1, const T z1,
+                        const T x2, const T y2, const T z2);
+	    explicit _xmat3(const _xvec3<T> & v0, 
+                        const _xvec3<T> & v1,
+                        const _xvec3<T> & v2);
+
+		// Conversions
+		template <typename U> 
+		explicit _xmat3(const _xmat3<U>& m);
+
+		explicit _xmat3(const _xmat2<T>& x);
+        explicit _xmat3(const _xmat4<T>& x);
+        explicit _xmat3(const _xmat2x3<T>& x);
+        explicit _xmat3(const _xmat3x2<T>& x);
+        explicit _xmat3(const _xmat2x4<T>& x);
+        explicit _xmat3(const _xmat4x2<T>& x);
+        explicit _xmat3(const _xmat3x4<T>& x);
+        explicit _xmat3(const _xmat4x3<T>& x);
+
+        //explicit _xmat3(const T* a);
+        // GL_GTX_euler_angles
+        //explicit _xmat3(const _xvec2<T> & angles);
+        //explicit _xmat3(const _xvec3<T> & angles);
+
+        // Conversions
+        //explicit _xmat3(const glm::_xquat<T> & q);
+
+        // Accesses
+        _xvec3<T>& operator[](int i) {return value[i];}
+        const _xvec3<T> & operator[](int i) const {return value[i];}
+		// operator T*() {return &value[0][0];}
+		// operator const T*() const {return &value[0][0];}
+		operator T*() {return (T*)this;}
+        operator const T*() const {return (const T*)this;}
+
+        // Unary updatable operators
+        _xmat3<T>& operator=(const _xmat3<T>& m);
+	    _xmat3<T>& operator+= (const T s);
+        _xmat3<T>& operator+= (const _xmat3<T>& m);
+        _xmat3<T>& operator-= (const T s);
+	    _xmat3<T>& operator-= (const _xmat3<T>& m);
+	    _xmat3<T>& operator*= (const T s);
+        _xmat3<T>& operator*= (const _xmat3<T>& m);
+	    _xmat3<T>& operator/= (const T s);
+        _xmat3<T>& operator/= (const _xmat3<T>& m);
+        _xmat3<T>& operator++ ();
+	    _xmat3<T>& operator-- ();
+    };
+
+	// Binary operators
+    template <typename T> 
+    inline _xmat3<T> operator+ (const _xmat3<T>& m, const T s);
+
+    template <typename T> 
+    inline _xmat3<T> operator+ (const T s, const _xmat3<T>& m);
+
+    template <typename T> 
+    inline _xvec3<T> operator+ (const _xmat3<T>& m, const _xvec3<T>& v);
+
+    template <typename T> 
+    inline _xvec3<T> operator+ (const _xvec3<T>& v, const _xmat3<T>& m);
+   
+    template <typename T> 
+    inline _xmat3<T> operator+ (const _xmat3<T>& m1, const _xmat3<T>& m2);
+    
+    template <typename T> 
+    inline _xmat3<T> operator- (const _xmat3<T>& m, const T s);
+
+    template <typename T> 
+    inline _xmat3<T> operator- (const T s, const _xmat3<T>& m);
+
+    template <typename T> 
+    inline _xvec3<T> operator- (const _xmat3<T>& m, const _xvec3<T>& v);
+
+    template <typename T> 
+    inline _xvec3<T> operator- (const _xvec3<T>& v, const _xmat3<T>& m);
+
+    template <typename T> 
+    inline _xmat3<T> operator- (const _xmat3<T>& m1, const _xmat3<T>& m2);
+
+    template <typename T> 
+    inline _xmat3<T> operator* (const _xmat3<T>& m, const T s);
+
+    template <typename T> 
+    inline _xmat3<T> operator* (const T s, const _xmat3<T>& m);
+
+    template <typename T> 
+    inline _xvec3<T> operator* (const _xmat3<T>& m, const _xvec3<T>& v);
+
+    template <typename T> 
+    inline _xvec3<T> operator* (const _xvec3<T>& v, const _xmat3<T>& m);
+
+    template <typename T> 
+    inline _xmat3<T> operator* (const _xmat3<T>& m1, const _xmat3<T>& m2);
+
+    template <typename T> 
+    inline _xmat3<T> operator/ (const _xmat3<T>& m, const T s);
+
+    template <typename T> 
+    inline _xmat3<T> operator/ (const T s, const _xmat3<T>& m);
+
+    template <typename T> 
+    inline _xvec3<T> operator/ (const _xmat3<T>& m, const _xvec3<T>& v);
+
+    template <typename T> 
+    inline _xvec3<T> operator/ (const _xvec3<T>& v, const _xmat3<T>& m);
+
+    template <typename T> 
+    inline _xmat3<T> operator/ (const _xmat3<T>& m1, const _xmat3<T>& m2);
+
+	// Unary constant operators
+    template <typename T> 
+    inline const _xmat3<T> operator- (const _xmat3<T>& m);
+
+    template <typename T> 
+    inline const _xmat3<T> operator-- (const _xmat3<T>& m, int);
+
+    template <typename T> 
+    inline const _xmat3<T> operator++ (const _xmat3<T>& m, int);
+
+} //namespace detail
+} //namespace glm
+
+#endif //__xmat3_h__

+ 546 - 0
experimental/sse/glm/core/_xmat3.inl

@@ -0,0 +1,546 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2008 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2005-01-27
+// Updated : 2007-03-01
+// Licence : This source is under GNU LGPL licence
+// File    : _xmat3.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef __xmat3_inl__
+#define __xmat3_inl__
+
+#include "./_xmat3.h"
+#include "./_func.h"
+
+namespace glm{
+namespace detail{
+
+	template <typename T> const typename _xmat3<T>::size_type _xmat3<T>::value_size = 3;
+	template <typename T> const typename _xmat3<T>::size_type _xmat3<T>::col_size = 3;
+	template <typename T> const typename _xmat3<T>::size_type _xmat3<T>::row_size = 3;
+
+    //////////////////////////////////////////////////////////////
+    // mat3 constructors
+
+    template <typename T> 
+    inline _xmat3<T>::_xmat3()
+    {
+        this->value[0] = _xvec3<T>(1, 0, 0);
+        this->value[1] = _xvec3<T>(0, 1, 0);
+        this->value[2] = _xvec3<T>(0, 0, 1);
+    }
+
+    template <typename T> 
+    inline _xmat3<T>::_xmat3(const T f)
+    {
+        this->value[0] = _xvec3<T>(f, 0, 0);
+        this->value[1] = _xvec3<T>(0, f, 0);
+        this->value[2] = _xvec3<T>(0, 0, f);
+    }
+
+    template <typename T> 
+    inline _xmat3<T>::_xmat3
+    (
+        const T x0, const T y0, const T z0, 
+        const T x1, const T y1, const T z1,
+        const T x2, const T y2, const T z2
+    )
+    {
+        this->value[0] = _xvec3<T>(x0, y0, z0);
+        this->value[1] = _xvec3<T>(x1, y1, z1);
+        this->value[2] = _xvec3<T>(x2, y2, z2);
+    }
+
+    template <typename T> 
+    inline _xmat3<T>::_xmat3
+    (
+        const _xvec3<T>& v0, 
+        const _xvec3<T>& v1, 
+        const _xvec3<T>& v2
+    )
+    {
+        this->value[0] = v0;
+        this->value[1] = v1;
+        this->value[2] = v2;
+    }
+
+    //////////////////////////////////////////////////////////////
+    // mat3 conversions
+
+    template <typename T> 
+    template <typename U> 
+    inline _xmat3<T>::_xmat3(const _xmat3<U>& m)
+    {
+        this->value[0] = _xvec3<T>(m[0]);
+        this->value[1] = _xvec3<T>(m[1]);
+        this->value[2] = _xvec3<T>(m[2]);
+	}
+
+    template <typename T> 
+    inline _xmat3<T>::_xmat3(const _xmat2<T>& m)
+    {
+        this->value[0] = _xvec3<T>(m[0], T(0));
+        this->value[1] = _xvec3<T>(m[1], T(0));
+        this->value[2] = _xvec3<T>(_xvec2<T>(0), T(1));
+    }
+
+    template <typename T> 
+    inline _xmat3<T>::_xmat3(const _xmat4<T>& m)
+    {
+        this->value[0] = _xvec3<T>(m[0]);
+        this->value[1] = _xvec3<T>(m[1]);
+        this->value[2] = _xvec3<T>(m[2]);
+    }
+
+	template <typename T> 
+    inline _xmat3<T>::_xmat3(const _xmat2x3<T>& m)
+    {
+        this->value[0] = m[0];
+        this->value[1] = m[1];
+        this->value[2] = _xvec3<T>(_xvec2<T>(0), T(1));
+    }
+
+    template <typename T> 
+    inline _xmat3<T>::_xmat3(const _xmat3x2<T>& m)
+    {
+        this->value[0] = _xvec3<T>(m[0], T(0));
+        this->value[1] = _xvec3<T>(m[1], T(0));
+        this->value[2] = _xvec3<T>(m[2], T(1));
+    }
+
+    template <typename T> 
+    inline _xmat3<T>::_xmat3(const _xmat2x4<T>& m)
+    {
+        this->value[0] = _xvec3<T>(m[0]);
+        this->value[1] = _xvec3<T>(m[1]);
+        this->value[2] = _xvec3<T>(_xvec2<T>(0), T(1));
+    }
+
+    template <typename T> 
+    inline _xmat3<T>::_xmat3(const _xmat4x2<T>& m)
+    {
+        this->value[0] = _xvec3<T>(m[0], T(0));
+        this->value[1] = _xvec3<T>(m[1], T(0));
+        this->value[2] = _xvec3<T>(m[2], T(1));
+    }
+
+    template <typename T> 
+    inline _xmat3<T>::_xmat3(const _xmat3x4<T>& m)
+    {
+        this->value[0] = _xvec3<T>(m[0]);
+        this->value[1] = _xvec3<T>(m[1]);
+        this->value[2] = _xvec3<T>(m[2]);
+    }
+
+    template <typename T> 
+    inline _xmat3<T>::_xmat3(const _xmat4x3<T>& m)
+    {
+        this->value[0] = m[0];
+        this->value[1] = m[1];
+        this->value[2] = m[2];
+    }
+
+/*
+    template <typename T> 
+    inline _xmat3<T>::_xmat3(const T* a)
+    {
+        this->value[0] = _xvec3<T>(a[0], a[1], a[2]);
+        this->value[1] = _xvec3<T>(a[3], a[4], a[5]);
+        this->value[2] = _xvec3<T>(a[6], a[7], a[8]);
+    }
+*/
+    /*
+    // GL_GTX_euler_angles
+    template <typename T> 
+    inline _xmat3<T>::_xmat3(const _xvec3<T> & angles)
+    {
+        T ch = cos(angles.x);
+        T sh = sin(angles.x);
+        T cp = cos(angles.y);
+        T sp = sin(angles.y);
+        T cb = cos(angles.z);
+        T sb = sin(angles.z);
+
+        value[0][0] = ch * cb + sh * sp * sb;
+        value[0][1] = sb * cp;
+        value[0][2] = -sh * cb + ch * sp * sb;
+        value[1][0] = -ch * sb + sh * sp * cb;
+        value[1][1] = cb * cp;
+        value[1][2] = sb * sh + ch * sp * cb;
+        value[2][0] = sh * cp;
+        value[2][1] = -sp;
+        value[2][2] = ch * cp;
+    }
+    */
+    //////////////////////////////////////////////////////////////
+    // mat3 conversions
+    /*
+    template <typename T> 
+    inline _xmat3<T>::_xmat3(const _xquat<T> & q)
+    {
+        this->value[0][0] = 1 - 2 * q.y * q.y - 2 * q.z * q.z;
+        this->value[0][1] = 2 * q.x * q.y + 2 * q.w * q.z;
+        this->value[0][2] = 2 * q.x * q.z - 2 * q.w * q.y;
+
+        this->value[1][0] = 2 * q.x * q.y - 2 * q.w * q.z;
+        this->value[1][1] = 1 - 2 * q.x * q.x - 2 * q.z * q.z;
+        this->value[1][2] = 2 * q.y * q.z + 2 * q.w * q.x;
+
+        this->value[2][0] = 2 * q.x * q.z + 2 * q.w * q.y;
+        this->value[2][1] = 2 * q.y * q.z - 2 * q.w * q.x;
+        this->value[2][2] = 1 - 2 * q.x * q.x - 2 * q.y * q.y;
+    }
+    */
+    //////////////////////////////////////////////////////////////
+    // mat3 operators
+
+    template <typename T> 
+    inline _xmat3<T>& _xmat3<T>::operator=(const _xmat3<T>& m)
+    {
+	    this->value[0] = m[0];
+	    this->value[1] = m[1];
+        this->value[2] = m[2];
+	    return *this;
+    }
+
+    template <typename T> 
+    inline _xmat3<T>& _xmat3<T>::operator+= (const T s)
+    {
+	    this->value[0] += s;
+	    this->value[1] += s;
+        this->value[2] += s;
+	    return *this;
+    }
+
+    template <typename T> 
+    inline _xmat3<T>& _xmat3<T>::operator+= (const _xmat3<T>& m)
+    {
+	    this->value[0] += m[0];
+	    this->value[1] += m[1];
+        this->value[2] += m[2];
+	    return *this;
+    }
+
+    template <typename T> 
+    inline _xmat3<T>& _xmat3<T>::operator-= (const T s)
+    {
+	    this->value[0] -= s;
+	    this->value[1] -= s;
+        this->value[2] -= s;
+	    return *this;
+    }
+
+    template <typename T> 
+    inline _xmat3<T>& _xmat3<T>::operator-= (const _xmat3<T>& m)
+    {
+	    this->value[0] -= m[0];
+	    this->value[1] -= m[1];
+        this->value[2] -= m[2];
+	    return *this;
+    }
+
+    template <typename T> 
+    inline _xmat3<T>& _xmat3<T>::operator*= (const T s)
+    {
+	    this->value[0] *= s;
+	    this->value[1] *= s;
+        this->value[2] *= s;
+	    return *this;
+    }
+
+    template <typename T> 
+    inline _xmat3<T>& _xmat3<T>::operator*= (const _xmat3<T>& m)
+    {
+        return (*this = *this * m);
+    }
+
+    template <typename T> 
+    inline _xmat3<T>& _xmat3<T>::operator/= (const T s)
+    {
+	    this->value[0] /= s;
+	    this->value[1] /= s;
+        this->value[2] /= s;
+	    return *this;
+    }
+
+    template <typename T> 
+    inline _xmat3<T>& _xmat3<T>::operator/= (const _xmat3<T>& m)
+    {
+        return (*this = *this / m);
+    }
+
+    template <typename T> 
+    inline _xmat3<T>& _xmat3<T>::operator++ ()
+    {
+	    this->value[0]++;
+	    this->value[1]++;
+        this->value[2]++;
+	    return *this;
+    }
+
+    template <typename T> 
+    inline _xmat3<T>& _xmat3<T>::operator-- ()
+    {
+	    this->value[0]--;
+	    this->value[1]--;
+        this->value[2]--;
+	    return *this;
+    }
+
+    template <typename T> 
+    inline _xmat3<T> _xmat3<T>::_inverse() const
+    {
+        T S00 = value[0][0];
+        T S01 = value[0][1];
+        T S02 = value[0][2];
+
+        T S10 = value[1][0];
+        T S11 = value[1][1];
+        T S12 = value[1][2];
+
+        T S20 = value[2][0];
+        T S21 = value[2][1];
+        T S22 = value[2][2];
+
+        _xmat3<T> Inverse(
+            + (S11 * S22 - S21 * S12),
+            - (S10 * S22 - S20 * S12),
+            + (S10 * S21 - S20 * S11),
+            - (S01 * S22 - S21 * S02),
+            + (S00 * S22 - S20 * S02),
+            - (S00 * S21 - S20 * S01),
+            + (S01 * S12 - S11 * S02),
+            - (S00 * S12 - S10 * S02),
+            + (S00 * S11 - S10 * S01));
+
+        T Determinant = S00 * (S11 * S22 - S21 * S12)
+                      - S10 * (S01 * S22 - S21 * S02)
+                      + S20 * (S01 * S12 - S11 * S02);
+
+        Inverse /= Determinant;
+        return Inverse;
+    }
+
+    //////////////////////////////////////////////////////////////
+	// Binary operators
+
+    template <typename T> 
+    inline _xmat3<T> operator+ (const _xmat3<T>& m, const T s)
+    {
+        return _xmat3<T>(
+            m[0] + s,
+            m[1] + s,
+            m[2] + s);
+    }
+
+    template <typename T> 
+    inline _xmat3<T> operator+ (const T s, const _xmat3<T>& m)
+    {
+        return _xmat3<T>(
+            m[0] + s,
+            m[1] + s,
+            m[2] + s);
+    }
+
+    template <typename T> 
+    inline _xvec3<T> operator+ (const _xmat3<T>& m, const _xvec3<T>& v)
+    {
+
+    }
+
+    template <typename T> 
+    inline _xvec3<T> operator+ (const _xvec3<T>& v, const _xmat3<T>& m)
+    {
+
+    }
+
+    template <typename T> 
+    inline _xmat3<T> operator+ (const _xmat3<T>& m1, const _xmat3<T>& m2)
+    {
+        return _xmat3<T>(
+            m1[0] + m2[0],
+            m1[1] + m2[1],
+            m1[2] + m2[2]);
+    }
+
+    template <typename T> 
+    inline _xmat3<T> operator- (const _xmat3<T>& m, const T s)
+    {
+        return _xmat3<T>(
+            m[0] - s,
+            m[1] - s,
+            m[2] - s);
+    }
+
+    template <typename T> 
+    inline _xmat3<T> operator- (const T s, const _xmat3<T>& m)
+    {
+        return _xmat3<T>(
+            s - m[0],
+            s - m[1],
+            s - m[2]);
+    }
+
+    template <typename T> 
+    inline _xvec3<T> operator- (const _xmat3<T>& m, const _xvec3<T>& v)
+    {
+
+    }
+
+    template <typename T> 
+    inline _xvec3<T> operator- (const _xvec3<T>& v, const _xmat3<T>& m)
+    {
+
+    }
+
+    template <typename T> 
+    inline _xmat3<T> operator- (const _xmat3<T>& m1, const _xmat3<T>& m2)
+    {
+        return _xmat3<T>(
+            m1[0] - m2[0],
+            m1[1] - m2[1],
+            m1[2] - m2[2]);
+    }
+
+    template <typename T> 
+    inline _xmat3<T> operator* (const _xmat3<T>& m, const T s)
+    {
+        return _xmat3<T>(
+            m[0] * s,
+            m[1] * s,
+            m[2] * s);
+    }
+
+    template <typename T> 
+    inline _xmat3<T> operator* (const T s, const _xmat3<T>& m)
+    {
+        return _xmat3<T>(
+            m[0] * s,
+            m[1] * s,
+            m[2] * s);
+    }
+
+    template <typename T> 
+    inline _xvec3<T> operator* (const _xmat3<T>& m, const _xvec3<T>& v)
+    {
+        return _xvec3<T>(
+            m[0][0] * v.x + m[1][0] * v.y + m[2][0] * v.z,
+            m[0][1] * v.x + m[1][1] * v.y + m[2][1] * v.z,
+            m[0][2] * v.x + m[1][2] * v.y + m[2][2] * v.z);
+    }
+
+    template <typename T> 
+    inline _xvec3<T> operator* (const _xvec3<T>& v, const _xmat3<T>& m)
+    {
+        return _xvec3<T>(
+            m[0][0] * v.x + m[0][1] * v.y + m[0][2] * v.z,
+            m[1][0] * v.x + m[1][1] * v.y + m[1][2] * v.z,
+            m[2][0] * v.x + m[2][1] * v.y + m[2][2] * v.z);
+    }
+
+    template <typename T> 
+    inline _xmat3<T> operator* (const _xmat3<T>& m1, const _xmat3<T>& m2)
+    {
+        const T SrcA00 = m1[0][0];
+        const T SrcA01 = m1[0][1];
+        const T SrcA02 = m1[0][2];
+        const T SrcA10 = m1[1][0];
+        const T SrcA11 = m1[1][1];
+        const T SrcA12 = m1[1][2];
+        const T SrcA20 = m1[2][0];
+        const T SrcA21 = m1[2][1];
+        const T SrcA22 = m1[2][2];
+
+        const T SrcB00 = m2[0][0];
+        const T SrcB01 = m2[0][1];
+        const T SrcB02 = m2[0][2];
+        const T SrcB10 = m2[1][0];
+        const T SrcB11 = m2[1][1];
+        const T SrcB12 = m2[1][2];
+        const T SrcB20 = m2[2][0];
+        const T SrcB21 = m2[2][1];
+        const T SrcB22 = m2[2][2];
+
+        _xmat3<T> Result;
+        Result[0][0] = SrcA00 * SrcB00 + SrcA10 * SrcB01 + SrcA20 * SrcB02;
+        Result[0][1] = SrcA01 * SrcB00 + SrcA11 * SrcB01 + SrcA21 * SrcB02;
+        Result[0][2] = SrcA02 * SrcB00 + SrcA12 * SrcB01 + SrcA22 * SrcB02;
+        Result[1][0] = SrcA00 * SrcB10 + SrcA10 * SrcB11 + SrcA20 * SrcB12;
+        Result[1][1] = SrcA01 * SrcB10 + SrcA11 * SrcB11 + SrcA21 * SrcB12;
+        Result[1][2] = SrcA02 * SrcB10 + SrcA12 * SrcB11 + SrcA22 * SrcB12;
+        Result[2][0] = SrcA00 * SrcB20 + SrcA10 * SrcB21 + SrcA20 * SrcB22;
+        Result[2][1] = SrcA01 * SrcB20 + SrcA11 * SrcB21 + SrcA21 * SrcB22;
+        Result[2][2] = SrcA02 * SrcB20 + SrcA12 * SrcB21 + SrcA22 * SrcB22;
+        return Result;
+    }
+
+
+    template <typename T> 
+    inline _xmat3<T> operator/ (const _xmat3<T>& m, const T s)
+    {
+        return _xmat3<T>(
+            m[0] / s,
+            m[1] / s,
+            m[2] / s);
+    }
+
+    template <typename T> 
+    inline _xmat3<T> operator/ (const T s, const _xmat3<T>& m)
+    {
+        return _xmat3<T>(
+            s / m[0],
+            s / m[1],
+            s / m[2]);
+    }
+
+    template <typename T> 
+    inline _xvec3<T> operator/ (const _xmat3<T>& m, const _xvec3<T>& v)
+    {
+        return m._inverse() * v;
+    }
+
+    template <typename T> 
+    inline _xvec3<T> operator/ (const _xvec3<T>& v, const _xmat3<T>& m)
+    {
+        return v * m._inverse();
+    }
+
+    template <typename T> 
+    inline _xmat3<T> operator/ (const _xmat3<T>& m1, const _xmat3<T>& m2)
+    {
+        return m1 * m2._inverse();
+    }
+
+	// Unary constant operators
+    template <typename T> 
+    inline const _xmat3<T> operator- (const _xmat3<T>& m)
+    {
+        return _xmat3<T>(
+            -m.value[0], 
+            -m.value[1],
+            -m.value[2]);
+    }
+
+    template <typename T> 
+    inline const _xmat3<T> operator-- (const _xmat3<T>& m, int) 
+    {
+        return _xmat3<T>(
+            m.value[0] - T(1),
+            m.value[1] - T(1),
+            m.value[2] - T(1));
+    }
+
+    template <typename T> 
+    inline const _xmat3<T> operator++ (const _xmat3<T>& m, int) 
+    {
+        return _xmat3<T>(
+            m.value[0] + T(1),
+            m.value[1] + T(1),
+            m.value[2] + T(1));
+    }
+
+} //namespace detail
+} //namespace glm
+
+#endif //__xmat3_inl__

+ 145 - 0
experimental/sse/glm/core/_xmat3x2.h

@@ -0,0 +1,145 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2008 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2006-08-05
+// Updated : 2006-10-01
+// Licence : This source is under GNU LGPL licence
+// File    : _mat3x2.h
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef __mat3x2_h__
+#define __mat3x2_h__
+
+namespace glm{
+namespace detail{
+
+    template <typename T> class _xvec2;
+    template <typename T> class _xvec3;
+    template <typename T> class _xvec4;
+    template <typename T> class _xmat2;
+    template <typename T> class _xmat3;
+    template <typename T> class _xmat4;
+    template <typename T> class _xmat2x3;
+    template <typename T> class _xmat2x4;
+    template <typename T> class _xmat3x4;
+    template <typename T> class _xmat4x2;
+    template <typename T> class _xmat4x3;
+
+    //!< \brief Template for 3 * 2 matrix of floating-point numbers.
+    template <typename T> 
+	class _xmat3x2
+    {
+    private:
+        // Data
+        _xvec2<T> value[3];
+
+    public:
+		typedef T value_type;
+		typedef _xvec3<T> col_type;
+		typedef _xvec2<T> row_type;
+		typedef int size_type;
+		static const size_type col_size;
+		static const size_type row_size;
+
+        // Constructors
+        _xmat3x2();
+        explicit _xmat3x2(const T x);
+        explicit _xmat3x2(
+            const T x0, const T y0,
+            const T x1, const T y1,
+            const T x2, const T y2);
+        explicit _xmat3x2(
+            const _xvec2<T>& v0, 
+            const _xvec2<T>& v1,
+            const _xvec2<T>& v2);
+
+        // Conversion
+		template <typename U> 
+		explicit _xmat3x2(const _xmat3x2<U>& m);
+
+		explicit _xmat3x2(const _xmat2<T>& x);
+        explicit _xmat3x2(const _xmat3<T>& x);
+        explicit _xmat3x2(const _xmat4<T>& x);
+        explicit _xmat3x2(const _xmat2x3<T>& x);
+        explicit _xmat3x2(const _xmat2x4<T>& x);
+        explicit _xmat3x2(const _xmat3x4<T>& x);
+        explicit _xmat3x2(const _xmat4x2<T>& x);
+        explicit _xmat3x2(const _xmat4x3<T>& x);
+
+        // Accesses
+        _xvec2<T>& operator[](int i) {return value[i];}
+        const _xvec2<T> & operator[](int i) const {return value[i];}
+		// operator T*() {return &value[0][0];}
+		// operator const T*() const {return &value[0][0];}
+		operator T*() {return (T*)this;}
+        operator const T*() const {return (const T*)this;}
+
+        // Unary updatable operators
+        _xmat3x2<T>& operator=  (const _xmat3x2<T>& m);
+        _xmat3x2<T>& operator+= (const T s);
+        _xmat3x2<T>& operator+= (const _xmat3x2<T>& m);
+        _xmat3x2<T>& operator-= (const T s);
+        _xmat3x2<T>& operator-= (const _xmat3x2<T>& m);
+        _xmat3x2<T>& operator*= (const T s);
+        _xmat3x2<T>& operator*= (const _xmat2x3<T>& m);
+        _xmat3x2<T>& operator/= (const T s);
+/* ToDo
+        _xmat3x2<T>& operator/= (const _xmat2x3<T>& m);
+*/
+        _xmat3x2<T>& operator++ ();
+        _xmat3x2<T>& operator-- ();
+
+        // Unary constant operators
+        const _xmat3x2<T> operator- () const;
+        const _xmat3x2<T> operator++ (int n) const;
+        const _xmat3x2<T> operator-- (int n) const;
+    };
+
+    // Binary operators
+    template <typename T> 
+    _xmat3x2<T> operator+ (const _xmat3x2<T>& m, const T s);
+    
+    template <typename T> 
+    _xmat3x2<T> operator+ (const _xmat3x2<T>& m1, const _xmat3x2<T>& m2);
+    
+    template <typename T> 
+    _xmat3x2<T> operator- (const _xmat3x2<T>& m, const T s);
+
+    template <typename T> 
+    _xmat3x2<T> operator- (const _xmat3x2<T>& m1, const _xmat3x2<T>& m2);
+
+    template <typename T> 
+    _xmat3x2<T> operator* (const _xmat3x2<T>& m, const T s);
+
+    template <typename T> 
+    _xmat3x2<T> operator* (const T s, const _xmat3x4<T>& m);
+
+    template <typename T>
+    _xvec2<T> operator* (const _xmat3x2<T>& m, const _xvec3<T>& v);
+
+    template <typename T> 
+    _xvec3<T> operator* (const _xvec2<T>& v, const _xmat3x2<T>& m);
+
+    template <typename T>
+    _xmat2<T> operator* (const _xmat3x2<T>& m1, const _xmat2x3<T>& m2);
+
+    template <typename T> 
+    _xmat2x3<T> operator/ (const _xmat2x3<T>& m, const T s);
+
+    template <typename T> 
+    _xmat2x3<T> operator/ (const T s, const _xmat2x3<T>& m);
+/* ToDo
+    template <typename T> 
+    _xvec2<T> operator/ (const _xmat3x2<T>& m, const _xvec3<T>& v);
+
+    template <typename T> 
+    _xvec3<T> operator/ (const _xvec2<T>& v, const _xmat3x2<T>& m);
+
+    template <typename T> 
+    _xmat2<T> operator/ (const _xmat2x3<T>& m1, const _xmat3x2<T>& m2);
+*/
+
+} //namespace detail
+} //namespace glm
+
+#endif //__mat3x2_h__

+ 451 - 0
experimental/sse/glm/core/_xmat3x2.inl

@@ -0,0 +1,451 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2008 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2006-08-05
+// Updated : 2006-10-01
+// Licence : This source is under GNU LGPL licence
+// File    : _mat3x2.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef __mat3x2_inl__
+#define __mat3x2_inl__
+
+#include "./_xmat3x2.h"
+
+namespace glm{
+namespace detail{
+
+	template <typename T> const typename _xmat3x2<T>::size_type _xmat3x2<T>::col_size = 3;
+	template <typename T> const typename _xmat3x2<T>::size_type _xmat3x2<T>::row_size = 2;
+
+    //////////////////////////////////////////////////////////////
+    // Constructors
+
+    template <typename T> 
+    inline _xmat3x2<T>::_xmat3x2()
+    {
+        this->value[0] = _xvec2<T>(1, 0);
+        this->value[1] = _xvec2<T>(0, 1);
+        this->value[2] = _xvec2<T>(0, 0);
+    }
+
+    template <typename T> 
+    inline _xmat3x2<T>::_xmat3x2(const T f)
+    {
+        this->value[0] = _xvec2<T>(f, 0);
+        this->value[1] = _xvec2<T>(0, f);
+        this->value[2] = _xvec2<T>(0, 0);
+    }
+
+    template <typename T> 
+    inline _xmat3x2<T>::_xmat3x2
+    (
+        const T x0, const T y0,
+        const T x1, const T y1,
+        const T x2, const T y2
+    )
+    {
+        this->value[0] = _xvec2<T>(x0, y0);
+        this->value[1] = _xvec2<T>(x1, y1);
+        this->value[2] = _xvec2<T>(x2, y2);
+    }
+
+    template <typename T> 
+    inline _xmat3x2<T>::_xmat3x2
+    (
+        const _xvec2<T> & v0, 
+        const _xvec2<T> & v1, 
+        const _xvec2<T> & v2
+    )
+    {
+        this->value[0] = v0;
+        this->value[1] = v1;
+        this->value[2] = v2;
+    }
+
+    // Conversion
+    template <typename T> 
+    template <typename U> 
+    inline _xmat3x2<T>::_xmat3x2(const _xmat3x2<U>& m)
+    {
+        this->value[0] = _xvec2<T>(m[0]);
+        this->value[1] = _xvec2<T>(m[1]);
+        this->value[2] = _xvec2<T>(m[2]);
+	}
+
+    template <typename T> 
+    inline _xmat3x2<T>::_xmat3x2(const _xmat2<T>& m)
+    {
+        this->value[0] = m[0];
+        this->value[1] = m[1];
+        this->value[2] = _xvec2<T>(T(0));
+    }
+
+    template <typename T> 
+    inline _xmat3x2<T>::_xmat3x2(const _xmat3<T>& m)
+    {
+        this->value[0] = _xvec2<T>(m[0]);
+        this->value[1] = _xvec2<T>(m[1]);
+        this->value[2] = _xvec2<T>(m[2]);
+    }
+
+    template <typename T> 
+    inline _xmat3x2<T>::_xmat3x2(const _xmat4<T>& m)
+    {
+        this->value[0] = _xvec2<T>(m[0]);
+        this->value[1] = _xvec2<T>(m[1]);
+        this->value[2] = _xvec2<T>(m[2]);
+    }
+
+    template <typename T> 
+    inline _xmat3x2<T>::_xmat3x2(const _xmat2x3<T>& m)
+    {
+        this->value[0] = _xvec2<T>(m[0]);
+        this->value[1] = _xvec2<T>(m[1]);
+        this->value[2] = _xvec2<T>(T(0));
+    }
+
+    template <typename T> 
+    inline _xmat3x2<T>::_xmat3x2(const _xmat2x4<T>& m)
+    {
+        this->value[0] = _xvec2<T>(m[0]);
+        this->value[1] = _xvec2<T>(m[1]);
+        this->value[2] = _xvec2<T>(T(0));
+    }
+
+    template <typename T> 
+    inline _xmat3x2<T>::_xmat3x2(const _xmat3x4<T>& m)
+    {
+        this->value[0] = _xvec2<T>(m[0]);
+        this->value[1] = _xvec2<T>(m[1]);
+        this->value[2] = _xvec2<T>(m[2]);
+    }
+
+    template <typename T> 
+    inline _xmat3x2<T>::_xmat3x2(const _xmat4x2<T>& m)
+    {
+        this->value[0] = m[0];
+        this->value[1] = m[1];
+        this->value[2] = m[2];
+    }
+
+    template <typename T> 
+    inline _xmat3x2<T>::_xmat3x2(const _xmat4x3<T>& m)
+    {
+        this->value[0] = _xvec2<T>(m[0]);
+        this->value[1] = _xvec2<T>(m[1]);
+        this->value[2] = _xvec2<T>(m[2]);
+    }
+
+    //////////////////////////////////////////////////////////////
+    // Unary updatable operators
+
+    template <typename T> 
+    inline _xmat3x2<T>& _xmat3x2<T>::operator= (const _xmat3x2<T>& m)
+    {
+        this->value[0] = m[0];
+        this->value[1] = m[1];
+        this->value[2] = m[2];
+        return *this;
+    }
+
+    template <typename T> 
+    inline _xmat3x2<T>& _xmat3x2<T>::operator+= (const T s)
+    {
+        this->value[0] += s;
+        this->value[1] += s;
+        this->value[2] += s;
+        return *this;
+    }
+
+    template <typename T> 
+    inline _xmat3x2<T>& _xmat3x2<T>::operator+= (const _xmat3x2<T>& m)
+    {
+        this->value[0] += m[0];
+        this->value[1] += m[1];
+        this->value[2] += m[2];
+        return *this;
+    }
+
+    template <typename T> 
+    inline _xmat3x2<T>& _xmat3x2<T>::operator-= (const T s)
+    {
+        this->value[0] -= s;
+        this->value[1] -= s;
+        this->value[2] -= s;
+        return *this;
+    }
+
+    template <typename T> 
+    inline _xmat3x2<T>& _xmat3x2<T>::operator-= (const _xmat3x2<T>& m)
+    {
+        this->value[0] -= m[0];
+        this->value[1] -= m[1];
+        this->value[2] -= m[2];
+        return *this;
+    }
+
+    template <typename T> 
+    inline _xmat3x2<T>& _xmat3x2<T>::operator*= (const T s)
+    {
+        this->value[0] *= s;
+        this->value[1] *= s;
+        this->value[2] *= s;
+        return *this;
+    }
+
+    template <typename T> 
+    inline _xmat3x2<T>& _xmat3x2<T>::operator*= (const _xmat2x3<T>& m)
+    {
+        return (*this = _xmat3x2<T>(*this * m));
+    }
+
+    template <typename T> 
+    inline _xmat3x2<T> & _xmat3x2<T>::operator/= (const T s)
+    {
+        this->value[0] /= s;
+        this->value[1] /= s;
+        this->value[2] /= s;
+        return *this;
+    }
+/* ToDo
+    template <typename T> 
+    inline _xmat3x2<T>& _xmat3x2<T>::operator/= (const _xmat3x2<T>& m)
+    {
+        return (*this = _xmat3x2<T>(*this / m));
+    }
+*/
+    template <typename T> 
+    inline _xmat3x2<T>& _xmat3x2<T>::operator++ ()
+    {
+        ++this->value[0];
+        ++this->value[1];
+        ++this->value[2];
+        return *this;
+    }
+
+    template <typename T> 
+    inline _xmat3x2<T>& _xmat3x2<T>::operator-- ()
+    {
+        --this->value[0];
+        --this->value[1];
+        --this->value[2];
+        return *this;
+    }
+/*
+    template <typename T> 
+    inline _xmat3x2<T> _xmat3x2<T>::_inverse() const
+    {
+        T S00 = value[0][0];
+        T S01 = value[0][1];
+
+        T S10 = value[1][0];
+        T S11 = value[1][1];
+
+        T S20 = value[2][0];
+        T S21 = value[2][1];
+
+        _xmat3x2<T> Inverse(
+            + (S11 * S22 - S21 * S12),
+            - (S10 * S22 - S20 * S12),
+            + (S10 * S21 - S20 * S11),
+            - (S01 * S22 - S21 * S02),
+            + (S00 * S22 - S20 * S02),
+            - (S00 * S21 - S20 * S01),
+            + (S01 * S12 - S11 * S02),
+            - (S00 * S12 - S10 * S02),
+            + (S00 * S11 - S10 * S01));
+
+        T Determinant = S00 * (S11 * S22 - S21 * S12)
+                      - S10 * (S01 * S22 - S21 * S02)
+                      + S20 * (S01 * S12 - S11 * S02);
+
+        Inverse /= Determinant;
+        return Inverse;
+    }
+
+    template <typename T> 
+    inline _xmat2<T> _xmat2<T>::_inverse() const
+    {
+        T Determinant = value[0][0] * value[1][1] - value[1][0] * value[0][1];
+
+        _xmat2<T> Inverse(
+            + value[1][1] / Determinant,
+            - value[1][0] / Determinant,
+            - value[0][1] / Determinant, 
+            + value[0][0] / Determinant);
+        return Inverse;
+    }
+*/
+    //////////////////////////////////////////////////////////////
+    // Unary constant operators
+    template <typename T> 
+    inline const _xmat3x2<T> _xmat3x2<T>::operator- () const
+    {
+        return _xmat3x2<T>(
+            -this->value[0], 
+            -this->value[1],
+            -this->value[2]);
+    }
+
+    template <typename T> 
+    inline const _xmat3x2<T> _xmat3x2<T>::operator-- (int n) const 
+    {
+        _xmat3x2<T> m = *this;
+        --m.value[0];
+        --m.value[1];
+        --m.value[2];
+        return m;
+    }
+
+    template <typename T> 
+    inline const _xmat3x2<T> _xmat3x2<T>::operator++ (int n) const
+    {
+        _xmat3x2<T> m = *this;
+        ++m.value[0];
+        ++m.value[1];
+        ++m.value[2];
+        return m;
+    }
+
+    //////////////////////////////////////////////////////////////
+    // Binary operators
+
+    template <typename T> 
+    inline _xmat3x2<T> operator+ (const _xmat3x2<T>& m, const T s)
+    {
+        return _xmat3x2<T>(
+            m[0] + s,
+            m[1] + s,
+            m[2] + s);
+    }
+
+    template <typename T> 
+    inline _xmat3x2<T> operator+ (const _xmat3x2<T>& m1, const _xmat3x2<T>& m2)
+    {
+        return _xmat3x2<T>(
+            m1[0] + m2[0],
+            m1[1] + m2[1],
+            m1[2] + m2[2]);
+    }
+
+    template <typename T> 
+    inline _xmat3x2<T> operator- (const _xmat3x2<T>& m, const T s)
+    {
+        return _xmat3x4<T>(
+            m[0] - s,
+            m[1] - s,
+            m[2] - s);
+    }
+
+    template <typename T> 
+    inline _xmat3x2<T> operator- (const _xmat3x2<T>& m1, const _xmat3x2<T>& m2)
+    {
+        return _xmat3x2<T>(
+            m1[0] - m2[0],
+            m1[1] - m2[1],
+            m1[2] - m2[2]);
+    }
+
+    template <typename T> 
+    inline _xmat3x2<T> operator* (const _xmat3x2<T>& m, const T s)
+    {
+        return _xmat3x2<T>(
+            m[0] * s,
+            m[1] * s,
+            m[2] * s);
+    }
+
+    template <typename T> 
+    inline _xmat3x2<T> operator* (const T s, const _xmat3x2<T> & m)
+    {
+        return _xmat3x2<T>(
+            m[0] * s,
+            m[1] * s,
+            m[2] * s);
+    }
+   
+    template <typename T>
+    inline _xvec2<T> operator* (const _xmat3x2<T>& m, const _xvec3<T>& v)
+    {
+        return _xvec2<T>(
+            m[0][0] * v.x + m[1][0] * v.y + m[2][0] * v.z,
+            m[0][1] * v.x + m[1][1] * v.y + m[2][1] * v.z);
+    }
+
+    template <typename T> 
+    inline _xvec3<T> operator* (const _xvec2<T>& v, const _xmat3x2<T>& m) 
+    {
+        return _xvec3<T>(
+            m[0][0] * v.x + m[1][0] * v.y + m[2][0] * v.z + m[3][0] * v.w,
+            m[0][1] * v.x + m[1][1] * v.y + m[2][1] * v.z + m[3][1] * v.w);
+    }
+
+    template <typename T> 
+    inline _xmat2<T> operator* (const _xmat3x2<T>& m1, const _xmat2x3<T>& m2)
+    {
+        const T SrcA00 = m1[0][0];
+        const T SrcA01 = m1[0][1];
+        const T SrcA10 = m1[1][0];
+        const T SrcA11 = m1[1][1];
+        const T SrcA20 = m1[2][0];
+        const T SrcA21 = m1[2][1];
+
+        const T SrcB00 = m2[0][0];
+        const T SrcB01 = m2[0][1];
+        const T SrcB02 = m2[0][2];
+        const T SrcB10 = m2[1][0];
+        const T SrcB11 = m2[1][1];
+        const T SrcB12 = m2[1][2];
+
+        _xmat2<T> Result;
+        Result[0][0] = SrcA00 * SrcB00 + SrcA01 * SrcB01 + SrcA20 * SrcB02;
+        Result[0][1] = SrcA01 * SrcB00 + SrcA11 * SrcB01 + SrcA21 * SrcB02;
+        Result[1][0] = SrcA00 * SrcB10 + SrcA10 * SrcB11 + SrcA20 * SrcB12;
+        Result[1][1] = SrcA01 * SrcB10 + SrcA11 * SrcB11 + SrcA21 * SrcB12;
+        return Result;
+    }
+
+    template <typename T> 
+    inline _xmat3x2<T> operator/ (const _xmat3x2<T>& m, const T s)
+    {
+        return _xmat3x2<T>(
+            m.value[0] / s,
+            m.value[1] / s,
+            m.value[2] / s,
+            m.value[3] / s);        
+    }
+
+    template <typename T> 
+    inline _xmat3x2<T> operator/ (const T s, const _xmat3x2<T>& m)
+    {
+        return _xmat3x2<T>(
+            s / m.value[0],
+            s / m.value[1],
+            s / m.value[2],
+            s / m.value[3]);        
+    }
+/* ToDo
+    template <typename T> 
+    inline _xvec3<T> operator/ (const _xmat3x2<T>& m, const _xvec2<T>& v)
+    {
+      
+    }
+
+    template <typename T> 
+    inline _xvec3<T> operator/ (const _xvec2<T>& v, const _xmat3x2<T>& m)
+    {
+      
+    }
+
+    template <typename T> 
+    inline _xmat2<T> operator/ (const _xmat3x2<T>& m1, const _xmat3x2<T>& m2)
+    {
+
+    }
+*/
+
+} //namespace detail
+} //namespace glm
+
+#endif //__mat3x2_inl__

+ 145 - 0
experimental/sse/glm/core/_xmat3x4.h

@@ -0,0 +1,145 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2008 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2006-08-05
+// Updated : 2006-10-01
+// Licence : This source is under GNU LGPL licence
+// File    : _mat3x4.h
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef __mat3x4_h__
+#define __mat3x4_h__
+
+namespace glm{
+namespace detail{
+
+    template <typename T> class _xvec2;
+    template <typename T> class _xvec3;
+    template <typename T> class _xvec4;
+    template <typename T> class _xmat2;
+    template <typename T> class _xmat3;
+    template <typename T> class _xmat4;
+    template <typename T> class _xmat2x3;
+    template <typename T> class _xmat3x2;
+    template <typename T> class _xmat2x4;
+    template <typename T> class _xmat4x2;
+    template <typename T> class _xmat4x3;
+
+    //!< \brief Template for 3 * 4 matrix of floating-point numbers.
+    template <typename T> 
+	class _xmat3x4
+    {
+    private:
+        // Data
+        _xvec4<T> value[3];
+
+    public:
+		typedef T value_type;
+		typedef _xvec3<T> col_type;
+		typedef _xvec4<T> row_type;
+		typedef int size_type;
+		static const size_type col_size;
+		static const size_type row_size;
+
+        // Constructors
+        _xmat3x4();
+        explicit _xmat3x4(const T x);
+        explicit _xmat3x4(
+            const T x0, const T y0, const T z0, const T w0,
+            const T x1, const T y1, const T z1, const T w1,
+            const T x2, const T y2, const T z2, const T w2);
+        explicit _xmat3x4(
+            const _xvec4<T>& v0, 
+            const _xvec4<T>& v1,
+            const _xvec4<T>& v2);
+
+        // Conversion
+		template <typename U> 
+		explicit _xmat3x4(const _xmat3x4<U>& m);
+
+		explicit _xmat3x4(const _xmat2<T>& x);
+        explicit _xmat3x4(const _xmat3<T>& x);
+        explicit _xmat3x4(const _xmat4<T>& x);
+        explicit _xmat3x4(const _xmat2x3<T>& x);
+        explicit _xmat3x4(const _xmat3x2<T>& x);
+        explicit _xmat3x4(const _xmat2x4<T>& x);
+        explicit _xmat3x4(const _xmat4x2<T>& x);
+        explicit _xmat3x4(const _xmat4x3<T>& x);
+
+        // Accesses
+        _xvec4<T>& operator[](int i) {return value[i];}
+        const _xvec4<T> & operator[](int i) const {return value[i];}
+		// operator T*() {return &value[0][0];}
+		// operator const T*() const {return &value[0][0];}
+		operator T*() {return (T*)this;}
+        operator const T*() const {return (const T*)this;}
+
+        // Unary updatable operators
+        _xmat3x4<T>& operator=  (const _xmat3x4<T>& m);
+        _xmat3x4<T>& operator+= (const T s);
+        _xmat3x4<T>& operator+= (const _xmat3x4<T>& m);
+        _xmat3x4<T>& operator-= (const T s);
+        _xmat3x4<T>& operator-= (const _xmat3x4<T>& m);
+        _xmat3x4<T>& operator*= (const T s);
+        _xmat3x4<T>& operator*= (const _xmat4x3<T>& m);
+        _xmat3x4<T>& operator/= (const T s);
+/* ToDo
+        _xmat3x4<T>& operator/= (const _xmat4x3<T>& m);
+*/
+        _xmat3x4<T>& operator++ ();
+        _xmat3x4<T>& operator-- ();
+
+        // Unary constant operators
+        const _xmat3x4<T> operator- () const;
+        const _xmat3x4<T> operator++ (int n) const;
+        const _xmat3x4<T> operator-- (int n) const;
+    };
+
+    // Binary operators
+    template <typename T> 
+    _xmat3x4<T> operator+ (const _xmat3x4<T>& m, const T s);
+    
+    template <typename T> 
+    _xmat3x4<T> operator+ (const _xmat3x4<T>& m1, const _xmat3x4<T>& m2);
+    
+    template <typename T> 
+    _xmat3x4<T> operator- (const _xmat3x4<T>& m, const T s);
+
+    template <typename T> 
+    _xmat3x4<T> operator- (const _xmat3x4<T>& m1, const _xmat3x4<T>& m2);
+
+    template <typename T> 
+    _xmat3x4<T> operator* (const _xmat3x4<T>& m, const T s);
+
+    template <typename T> 
+    _xmat3x4<T> operator* (const T s, const _xmat3x4<T>& m);
+
+    template <typename T>
+    _xvec4<T> operator* (const _xmat3x4<T>& m, const _xvec3<T>& v);
+
+    template <typename T> 
+    _xvec3<T> operator* (const _xvec4<T>& v, const _xmat3x4<T>& m);
+
+    template <typename T>
+    _xmat4<T> operator* (const _xmat3x4<T>& m1, const _xmat4x3<T>& m2);
+
+    template <typename T> 
+    _xmat4x3<T> operator/ (const _xmat4x3<T>& m, const T s);
+
+    template <typename T> 
+    _xmat4x3<T> operator/ (const T s, const _xmat4x3<T>& m);
+/* ToDo
+    template <typename T> 
+    _xvec4<T> operator/ (const _xmat3x4<T>& m, const _xvec3<T>& v);
+
+    template <typename T> 
+    _xvec3<T> operator/ (const _xvec4<T>& v, const _xmat3x4<T>& m);
+
+    template <typename T> 
+    _xmat4<T> operator/ (const _xmat4x3<T>& m1, const _xmat3x4<T>& m2);
+*/
+
+} //namespace detail
+} //namespace glm
+
+#endif //__mat3x4_h__

+ 434 - 0
experimental/sse/glm/core/_xmat3x4.inl

@@ -0,0 +1,434 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2008 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2006-08-05
+// Updated : 2006-10-01
+// Licence : This source is under GNU LGPL licence
+// File    : _mat3x4.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef __mat3x4_inl__
+#define __mat3x4_inl__
+
+#include "./_xmat3x4.h"
+
+namespace glm{
+namespace detail{
+
+	template <typename T> const typename _xmat3x4<T>::size_type _xmat3x4<T>::col_size = 3;
+	template <typename T> const typename _xmat3x4<T>::size_type _xmat3x4<T>::row_size = 4;
+
+    //////////////////////////////////////////////////////////////
+    // Constructors
+
+    template <typename T> 
+    inline _xmat3x4<T>::_xmat3x4()
+    {
+        this->value[0] = _xvec4<T>(1, 0, 0, 0);
+        this->value[1] = _xvec4<T>(0, 1, 0, 0);
+        this->value[2] = _xvec4<T>(0, 0, 1, 0);
+    }
+
+    template <typename T> 
+    inline _xmat3x4<T>::_xmat3x4(const T f)
+    {
+        this->value[0] = _xvec4<T>(f, 0, 0, 0);
+        this->value[1] = _xvec4<T>(0, f, 0, 0);
+        this->value[2] = _xvec4<T>(0, 0, f, 0);
+    }
+
+    template <typename T> 
+    inline _xmat3x4<T>::_xmat3x4
+    (
+        const T x0, const T y0, const T z0, const T w0,
+        const T x1, const T y1, const T z1, const T w1,
+        const T x2, const T y2, const T z2, const T w2
+    )
+    {
+        this->value[0] = _xvec4<T>(x0, y0, z0, w0);
+        this->value[1] = _xvec4<T>(x1, y1, z1, w1);
+        this->value[2] = _xvec4<T>(x2, y2, z2, w2);
+    }
+
+    template <typename T> 
+    inline _xmat3x4<T>::_xmat3x4
+    (
+        const _xvec4<T> & v0, 
+        const _xvec4<T> & v1, 
+        const _xvec4<T> & v2
+    )
+    {
+        this->value[0] = v0;
+        this->value[1] = v1;
+        this->value[2] = v2;
+    }
+
+    // Conversion
+    template <typename T> 
+    template <typename U> 
+    inline _xmat3x4<T>::_xmat3x4(const _xmat3x4<U>& m)
+    {
+        this->value[0] = _xvec4<T>(m[0]);
+        this->value[1] = _xvec4<T>(m[1]);
+        this->value[2] = _xvec4<T>(m[2]);
+	}
+
+    template <typename T> 
+    inline _xmat3x4<T>::_xmat3x4(const _xmat2<T>& m)
+    {
+        this->value[0] = _xvec4<T>(m[0], _xvec2<T>(0));
+        this->value[1] = _xvec4<T>(m[1], _xvec2<T>(0));
+        this->value[2] = _xvec4<T>(T(0), T(0), T(1), T(0));
+    }
+
+    template <typename T> 
+    inline _xmat3x4<T>::_xmat3x4(const _xmat3<T>& m)
+    {
+        this->value[0] = _xvec4<T>(m[0], T(0));
+        this->value[1] = _xvec4<T>(m[1], T(0));
+        this->value[2] = _xvec4<T>(m[2], T(0));
+    }
+
+    template <typename T> 
+    inline _xmat3x4<T>::_xmat3x4(const _xmat4<T>& m)
+    {
+        this->value[0] = _xvec4<T>(m[0]);
+        this->value[1] = _xvec4<T>(m[1]);
+        this->value[2] = _xvec4<T>(m[2]);
+    }
+
+    template <typename T> 
+    inline _xmat3x4<T>::_xmat3x4(const _xmat2x3<T>& m)
+    {
+        this->value[0] = _xvec4<T>(m[0], T(0));
+        this->value[1] = _xvec4<T>(m[1], T(0));
+        this->value[2] = _xvec4<T>(T(0), T(0), T(1), T(0));
+    }
+
+    template <typename T> 
+    inline _xmat3x4<T>::_xmat3x4(const _xmat3x2<T>& m)
+    {
+        this->value[0] = _xvec4<T>(m[0], _xvec2<T>(0));
+        this->value[1] = _xvec4<T>(m[1], _xvec2<T>(0));
+        this->value[2] = _xvec4<T>(m[2], T(0), T(1));
+    }
+
+    template <typename T> 
+    inline _xmat3x4<T>::_xmat3x4(const _xmat2x4<T>& m)
+    {
+        this->value[0] = _xvec4<T>(m[0]);
+        this->value[1] = _xvec4<T>(m[1]);
+        this->value[2] = _xvec4<T>(T(0), T(0), T(1), T(0));
+    }
+
+    template <typename T> 
+    inline _xmat3x4<T>::_xmat3x4(const _xmat4x2<T>& m)
+    {
+        this->value[0] = _xvec4<T>(m[0], _xvec2<T>(T(0)));
+        this->value[1] = _xvec4<T>(m[1], _xvec2<T>(T(0)));
+        this->value[2] = _xvec4<T>(m[2], _xvec2<T>(T(1), T(0)));
+    }
+
+    template <typename T> 
+    inline _xmat3x4<T>::_xmat3x4(const _xmat4x3<T>& m)
+    {
+        this->value[0] = _xvec4<T>(m[0], T(0));
+        this->value[1] = _xvec4<T>(m[1], T(0));
+        this->value[2] = _xvec4<T>(m[2], T(0));
+    }
+
+    //////////////////////////////////////////////////////////////
+    // Unary updatable operators
+
+    template <typename T> 
+    inline _xmat3x4<T>& _xmat3x4<T>::operator= (const _xmat3x4<T>& m)
+    {
+        this->value[0] = m[0];
+        this->value[1] = m[1];
+        this->value[2] = m[2];
+        return *this;
+    }
+
+    template <typename T> 
+    inline _xmat3x4<T>& _xmat3x4<T>::operator+= (const T s)
+    {
+        this->value[0] += s;
+        this->value[1] += s;
+        this->value[2] += s;
+        return *this;
+    }
+
+    template <typename T> 
+    inline _xmat3x4<T>& _xmat3x4<T>::operator+= (const _xmat3x4<T>& m)
+    {
+        this->value[0] += m[0];
+        this->value[1] += m[1];
+        this->value[2] += m[2];
+        return *this;
+    }
+
+    template <typename T> 
+    inline _xmat3x4<T>& _xmat3x4<T>::operator-= (const T s)
+    {
+        this->value[0] -= s;
+        this->value[1] -= s;
+        this->value[2] -= s;
+        return *this;
+    }
+
+    template <typename T> 
+    inline _xmat3x4<T>& _xmat3x4<T>::operator-= (const _xmat3x4<T>& m)
+    {
+        this->value[0] -= m[0];
+        this->value[1] -= m[1];
+        this->value[2] -= m[2];
+        return *this;
+    }
+
+    template <typename T> 
+    inline _xmat3x4<T>& _xmat3x4<T>::operator*= (const T s)
+    {
+        this->value[0] *= s;
+        this->value[1] *= s;
+        this->value[2] *= s;
+        return *this;
+    }
+
+    template <typename T> 
+    inline _xmat3x4<T>& _xmat3x4<T>::operator*= (const _xmat4x3<T>& m)
+    {
+        return (*this = _xmat3x4<T>(*this * m));
+    }
+
+    template <typename T> 
+    inline _xmat3x4<T> & _xmat3x4<T>::operator/= (const T s)
+    {
+        this->value[0] /= s;
+        this->value[1] /= s;
+        this->value[2] /= s;
+        return *this;
+    }
+/* ToDo
+    template <typename T> 
+    inline _xmat3x4<T>& _xmat3x4<T>::operator/= (const _xmat4x3<T>& m)
+    {
+        return (*this = _xmat3x4<T>(*this / m));
+    }
+*/
+    template <typename T> 
+    inline _xmat3x4<T>& _xmat3x4<T>::operator++ ()
+    {
+        ++this->value[0];
+        ++this->value[1];
+        ++this->value[2];
+        return *this;
+    }
+
+    template <typename T> 
+    inline _xmat3x4<T>& _xmat3x4<T>::operator-- ()
+    {
+        --this->value[0];
+        --this->value[1];
+        --this->value[2];
+        return *this;
+    }
+    
+    //////////////////////////////////////////////////////////////
+    // Unary constant operators
+    template <typename T> 
+    inline const _xmat3x4<T> _xmat3x4<T>::operator- () const
+    {
+        return _xmat3x4<T>(
+            -this->value[0], 
+            -this->value[1],
+            -this->value[2]);
+    }
+
+    template <typename T> 
+    inline const _xmat3x4<T> _xmat3x4<T>::operator-- (int n) const 
+    {
+        _xmat3x4<T> m = *this;
+        --m.value[0];
+        --m.value[1];
+        --m.value[2];
+        return m;
+    }
+
+    template <typename T> 
+    inline const _xmat3x4<T> _xmat3x4<T>::operator++ (int n) const
+    {
+        _xmat3x4<T> m = *this;
+        ++m.value[0];
+        ++m.value[1];
+        ++m.value[2];
+        return m;
+    }
+
+    //////////////////////////////////////////////////////////////
+    // Binary operators
+
+    template <typename T> 
+    inline _xmat3x4<T> operator+ (const _xmat3x4<T>& m, const T s)
+    {
+        return _xmat3x4<T>(
+            m[0] + s,
+            m[1] + s,
+            m[2] + s);
+    }
+
+    template <typename T> 
+    inline _xmat3x4<T> operator+ (const _xmat3x4<T>& m1, const _xmat3x4<T>& m2)
+    {
+        return _xmat3x4<T>(
+            m1[0] + m2[0],
+            m1[1] + m2[1],
+            m1[2] + m2[2]);
+    }
+
+    template <typename T> 
+    inline _xmat3x4<T> operator- (const _xmat3x4<T>& m, const T s)
+    {
+        return _xmat3x4<T>(
+            m[0] - s,
+            m[1] - s,
+            m[2] - s);
+    }
+
+    template <typename T> 
+    inline _xmat3x4<T> operator- (const _xmat3x4<T>& m1, const _xmat3x4<T>& m2)
+    {
+        return _xmat3x4<T>(
+            m1[0] - m2[0],
+            m1[1] - m2[1],
+            m1[2] - m2[2]);
+    }
+
+    template <typename T> 
+    inline _xmat3x4<T> operator* (const _xmat3x4<T>& m, const T s)
+    {
+        return _xmat3x4<T>(
+            m[0] * s,
+            m[1] * s,
+            m[2] * s);
+    }
+
+    template <typename T> 
+    inline _xmat3x4<T> operator* (const T s, const _xmat3x4<T> & m)
+    {
+        return _xmat3x4<T>(
+            m[0] * s,
+            m[1] * s,
+            m[2] * s);
+    }
+   
+    template <typename T>
+    inline _xvec4<T> operator* (const _xmat3x4<T>& m, const _xvec3<T>& v)
+    {
+        return _xvec4<T>(
+            m[0][0] * v.x + m[1][0] * v.y + m[2][0] * v.z,
+            m[0][1] * v.x + m[1][1] * v.y + m[2][1] * v.z,
+            m[0][2] * v.x + m[1][2] * v.y + m[2][2] * v.z,
+            m[0][3] * v.x + m[1][3] * v.y + m[2][3] * v.z);
+    }
+
+    template <typename T> 
+    inline _xvec3<T> operator* (const _xvec4<T>& v, const _xmat3x4<T>& m) 
+    {
+        return _xvec3<T>(
+            m[0][0] * v.x + m[1][0] * v.y + m[2][0] * v.z + m[3][0] * v.w,
+            m[0][1] * v.x + m[1][1] * v.y + m[2][1] * v.z + m[3][1] * v.w,
+            m[0][2] * v.x + m[1][2] * v.y + m[2][2] * v.z + m[3][2] * v.w);
+    }
+
+    template <typename T> 
+    inline _xmat4<T> operator* (const _xmat3x4<T>& m1, const _xmat4x3<T>& m2)
+    {
+        const T SrcA00 = m1[0][0];
+        const T SrcA01 = m1[0][1];
+        const T SrcA02 = m1[0][2];
+        const T SrcA03 = m1[0][3];
+        const T SrcA10 = m1[1][0];
+        const T SrcA11 = m1[1][1];
+        const T SrcA12 = m1[1][2];
+        const T SrcA13 = m1[1][3];
+        const T SrcA20 = m1[2][0];
+        const T SrcA21 = m1[2][1];
+        const T SrcA22 = m1[2][2];
+        const T SrcA23 = m1[2][3];
+
+        const T SrcB00 = m2[0][0];
+        const T SrcB01 = m2[0][1];
+        const T SrcB02 = m2[0][2];
+        const T SrcB10 = m2[1][0];
+        const T SrcB11 = m2[1][1];
+        const T SrcB12 = m2[1][2];
+        const T SrcB20 = m2[2][0];
+        const T SrcB21 = m2[2][1];
+        const T SrcB22 = m2[2][2];
+        const T SrcB30 = m2[3][0];
+        const T SrcB31 = m2[3][1];
+        const T SrcB32 = m2[3][2];
+
+        _xmat4<T> Result;
+        Result[0][0] = SrcA00 * SrcB00 + SrcA10 * SrcB01 + SrcA20 * SrcB02;
+        Result[0][1] = SrcA01 * SrcB00 + SrcA11 * SrcB01 + SrcA21 * SrcB02;
+        Result[0][2] = SrcA02 * SrcB00 + SrcA12 * SrcB01 + SrcA22 * SrcB02;
+        Result[0][3] = SrcA03 * SrcB00 + SrcA13 * SrcB01 + SrcA23 * SrcB02;
+        Result[1][0] = SrcA00 * SrcB10 + SrcA10 * SrcB11 + SrcA20 * SrcB12;
+        Result[1][1] = SrcA01 * SrcB10 + SrcA11 * SrcB11 + SrcA21 * SrcB12;
+        Result[1][2] = SrcA02 * SrcB10 + SrcA12 * SrcB11 + SrcA22 * SrcB12;
+        Result[1][3] = SrcA03 * SrcB10 + SrcA13 * SrcB11 + SrcA23 * SrcB12;
+        Result[2][0] = SrcA00 * SrcB20 + SrcA10 * SrcB21 + SrcA20 * SrcB22;
+        Result[2][1] = SrcA01 * SrcB20 + SrcA11 * SrcB21 + SrcA21 * SrcB22;
+        Result[2][2] = SrcA02 * SrcB20 + SrcA12 * SrcB21 + SrcA22 * SrcB22;
+        Result[2][3] = SrcA03 * SrcB20 + SrcA13 * SrcB21 + SrcA23 * SrcB22;
+        Result[3][0] = SrcA00 * SrcB30 + SrcA10 * SrcB31 + SrcA20 * SrcB32;
+        Result[3][1] = SrcA01 * SrcB30 + SrcA11 * SrcB31 + SrcA21 * SrcB32;
+        Result[3][2] = SrcA02 * SrcB30 + SrcA12 * SrcB31 + SrcA22 * SrcB32;
+        Result[3][3] = SrcA03 * SrcB30 + SrcA13 * SrcB31 + SrcA23 * SrcB32;
+        return Result;
+    }
+
+    template <typename T> 
+    inline _xmat3x4<T> operator/ (const _xmat3x4<T>& m, const T s)
+    {
+        return _xmat3x4<T>(
+            m.value[0] / s,
+            m.value[1] / s,
+            m.value[2] / s,
+            m.value[3] / s);        
+    }
+
+    template <typename T> 
+    inline _xmat3x4<T> operator/ (const T s, const _xmat3x4<T>& m)
+    {
+        return _xmat3x4<T>(
+            s / m.value[0],
+            s / m.value[1],
+            s / m.value[2],
+            s / m.value[3]);        
+    }
+/* ToDo
+    template <typename T> 
+    inline _xvec3<T> operator/ (const _xmat4x3<T>& m, const _xvec4<T>& v)
+    {
+      
+    }
+
+    template <typename T> 
+    inline _xvec3<T> operator/ (const _xvec4<T>& v, const _xmat4x3<T>& m)
+    {
+      
+    }
+
+    template <typename T> 
+    inline _xmat4<T> operator/ (const _xmat3x4<T>& m1, const _xmat4x3<T>& m2)
+    {
+
+    }
+*/
+
+} //namespace detail
+} //namespace glm
+
+#endif //__mat3x4_inl__

+ 178 - 0
experimental/sse/glm/core/_xmat4.h

@@ -0,0 +1,178 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2008 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2005-01-27
+// Updated : 2007-03-01
+// Licence : This source is under GNU LGPL licence
+// File    : _xmat4.h
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef __xmat4_h__
+#define __xmat4_h__
+
+namespace glm{
+namespace detail{
+
+    template <typename T> class _xvec3;
+    template <typename T> class _xvec4;
+    template <typename T> class _xquat;
+
+    template <typename T> class _xmat2;
+    template <typename T> class _xmat3;
+    template <typename T> class _xmat2x4;
+	template <typename T> class _xmat2x3;
+    template <typename T> class _xmat3x2;
+    template <typename T> class _xmat3x4;
+    template <typename T> class _xmat4x2;
+    template <typename T> class _xmat4x3;
+
+	//!< \brief Template for 4 * 4 matrix of floating-point numbers.
+    template <typename T> 
+	class _xmat4
+    {
+    private:
+        // Data
+        _xvec4<T> value[4];
+
+    public:
+		typedef T value_type;
+		typedef _xvec4<T> col_type;
+		typedef _xvec4<T> row_type;
+		typedef int size_type;
+		static const size_type value_size;
+		static const size_type col_size;
+		static const size_type row_size;
+
+        _xmat4<T> _inverse() const;
+
+    public:
+        // Constructors
+        _xmat4();
+        explicit _xmat4(const T x);
+        explicit _xmat4(
+            const T x0, const T y0, const T z0, const T w0,
+            const T x1, const T y1, const T z1, const T w1,
+            const T x2, const T y2, const T z2, const T w2,
+            const T x3, const T y3, const T z3, const T w3);
+        explicit _xmat4(const _xvec4<T> & v0, 
+            const _xvec4<T> & v1,
+            const _xvec4<T> & v2,
+            const _xvec4<T> & v3);
+
+		// Conversions
+		template <typename U> 
+		explicit _xmat4(const _xmat4<U>& m);
+
+		explicit _xmat4(const _xmat2<T>& x);
+        explicit _xmat4(const _xmat3<T>& x);
+        explicit _xmat4(const _xmat2x3<T>& x);
+        explicit _xmat4(const _xmat3x2<T>& x);
+        explicit _xmat4(const _xmat2x4<T>& x);
+        explicit _xmat4(const _xmat4x2<T>& x);
+        explicit _xmat4(const _xmat3x4<T>& x);
+        explicit _xmat4(const _xmat4x3<T>& x);
+
+        //explicit _xmat4(const T* a);
+        // GL_GTX_euler_angles
+        //explicit _xmat4(const _xvec3<T> & angle);
+
+        // Conversion
+        //explicit _xmat4(const glm::_xquat<T> & q);
+
+        // Accesses
+        _xvec4<T>& operator[](int i) {return value[i];}
+        const _xvec4<T> & operator[](int i) const {return value[i];}
+		// operator T*() {return &value[0][0];}
+		// operator const T*() const {return &value[0][0];}
+		operator T*() {return (T*)this;}
+        operator const T*() const {return (const T*)this;}
+
+        // Unary updatable operators
+        _xmat4<T>& operator= (const _xmat4<T>& m);
+        _xmat4<T>& operator+= (const T s);
+        _xmat4<T>& operator+= (const _xmat4<T>& m);
+        _xmat4<T>& operator-= (const T s);
+        _xmat4<T>& operator-= (const _xmat4<T>& m);
+        _xmat4<T>& operator*= (const T s);
+        _xmat4<T>& operator*= (const _xmat4<T>& m);
+        _xmat4<T>& operator/= (const T s);
+        _xmat4<T>& operator/= (const _xmat4<T>& m);
+        _xmat4<T>& operator++ ();
+        _xmat4<T>& operator-- ();
+    };
+
+	// Binary operators
+    template <typename T> 
+    inline _xmat4<T> operator+ (const _xmat4<T>& m, const T s);
+
+    template <typename T> 
+    inline _xmat4<T> operator+ (const T s, const _xmat4<T>& m);
+
+    template <typename T> 
+    inline _xvec4<T> operator+ (const _xmat4<T>& m, const _xvec4<T>& v);
+
+    template <typename T> 
+    inline _xvec4<T> operator+ (const _xvec4<T>& v, const _xmat4<T>& m);
+ 
+    template <typename T> 
+    inline _xmat4<T> operator+ (const _xmat4<T>& m1, const _xmat4<T>& m2);
+    
+    template <typename T> 
+    inline _xmat4<T> operator- (const _xmat4<T>& m, const T s);
+
+    template <typename T> 
+    inline _xmat4<T> operator- (const T s, const _xmat4<T>& m);
+
+    template <typename T> 
+    inline _xvec4<T> operator- (const _xmat4<T>& m, const _xvec4<T>& v);
+
+    template <typename T> 
+    inline _xvec4<T> operator- (const _xvec4<T>& v, const _xmat4<T>& m);
+
+    template <typename T> 
+    inline _xmat4<T> operator- (const _xmat4<T>& m1, const _xmat4<T>& m2);
+
+    template <typename T> 
+    inline _xmat4<T> operator* (const _xmat4<T>& m, const T s);
+
+    template <typename T> 
+    inline _xmat4<T> operator* (const T s, const _xmat4<T>& m);
+
+    template <typename T> 
+    inline _xvec4<T> operator* (const _xmat4<T>& m, const _xvec4<T>& v);
+
+    template <typename T> 
+    inline _xvec4<T> operator* (const _xvec4<T>& v, const _xmat4<T>& m);
+
+    template <typename T> 
+    inline _xmat4<T> operator* (const _xmat4<T>& m1, const _xmat4<T>& m2);
+
+    template <typename T> 
+    inline _xmat4<T> operator/ (const _xmat4<T>& m, const T s);
+
+    template <typename T> 
+    inline _xmat4<T> operator/ (const T s, const _xmat4<T>& m);
+
+    template <typename T> 
+    inline _xvec4<T> operator/ (const _xmat4<T>& m, const _xvec4<T>& v);
+
+    template <typename T> 
+    inline _xvec4<T> operator/ (const _xvec4<T>& v, const _xmat4<T>& m);
+
+    template <typename T> 
+    inline _xmat4<T> operator/ (const _xmat4<T>& m1, const _xmat4<T>& m2);
+
+	// Unary constant operators
+    template <typename T> 
+    inline const _xmat4<T> operator- (const _xmat4<T>& m);
+
+    template <typename T> 
+    inline const _xmat4<T> operator-- (const _xmat4<T>& m, int);
+
+    template <typename T> 
+    inline const _xmat4<T> operator++ (const _xmat4<T>& m, int);
+
+} //namespace detail
+} //namespace glm
+
+#endif //__xmat4_h__

+ 633 - 0
experimental/sse/glm/core/_xmat4.inl

@@ -0,0 +1,633 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2008 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2005-01-27
+// Updated : 2007-03-01
+// Licence : This source is under GNU LGPL licence
+// File    : _xmat4.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef __mat4_inl__
+#define __mat4_inl__
+
+#include "./_xmat4.h"
+#include "./_func.h"
+
+namespace glm{
+namespace detail{
+
+	template <typename T> const typename _xmat4<T>::size_type _xmat4<T>::value_size = 4;
+	template <typename T> const typename _xmat4<T>::size_type _xmat4<T>::col_size = 4;
+	template <typename T> const typename _xmat4<T>::size_type _xmat4<T>::row_size = 4;
+
+    //////////////////////////////////////////////////////////////
+    // mat4 constructors
+
+    template <typename T> 
+    inline _xmat4<T>::_xmat4()
+    {
+        this->value[0] = _xvec4<T>(1, 0, 0, 0);
+        this->value[1] = _xvec4<T>(0, 1, 0, 0);
+        this->value[2] = _xvec4<T>(0, 0, 1, 0);
+        this->value[3] = _xvec4<T>(0, 0, 0, 1);
+    }
+
+    template <typename T> 
+    inline _xmat4<T>::_xmat4(const T f)
+    {
+        this->value[0] = _xvec4<T>(f, 0, 0, 0);
+        this->value[1] = _xvec4<T>(0, f, 0, 0);
+        this->value[2] = _xvec4<T>(0, 0, f, 0);
+        this->value[3] = _xvec4<T>(0, 0, 0, f);
+    }
+
+    template <typename T> 
+    inline _xmat4<T>::_xmat4
+    (
+        const T x0, const T y0, const T z0, const T w0,
+        const T x1, const T y1, const T z1, const T w1,
+        const T x2, const T y2, const T z2, const T w2,
+        const T x3, const T y3, const T z3, const T w3
+    )
+    {
+        this->value[0] = _xvec4<T>(x0, y0, z0, w0);
+        this->value[1] = _xvec4<T>(x1, y1, z1, w1);
+        this->value[2] = _xvec4<T>(x2, y2, z2, w2);
+        this->value[3] = _xvec4<T>(x3, y3, z3, w3);
+    }
+
+    template <typename T> 
+    inline _xmat4<T>::_xmat4
+    (
+        const _xvec4<T>& v0, 
+        const _xvec4<T>& v1, 
+        const _xvec4<T>& v2,
+        const _xvec4<T>& v3
+    )
+    {
+        this->value[0] = v0;
+        this->value[1] = v1;
+        this->value[2] = v2;
+        this->value[3] = v3;
+    }
+
+    template <typename T> 
+    template <typename U> 
+    inline _xmat4<T>::_xmat4(const _xmat4<U>& m)
+    {
+        this->value[0] = _xvec4<T>(m[0]);
+        this->value[1] = _xvec4<T>(m[1]);
+        this->value[2] = _xvec4<T>(m[2]);
+        this->value[3] = _xvec4<T>(m[3]);
+	}
+
+    template <typename T> 
+    inline _xmat4<T>::_xmat4(const _xmat2<T>& m)
+    {
+        this->value[0] = _xvec4<T>(m[0], _xvec2<T>(0));
+        this->value[1] = _xvec4<T>(m[1], _xvec2<T>(0));
+        this->value[2] = _xvec4<T>(_xvec3<T>(0), T(0));
+        this->value[3] = _xvec4<T>(_xvec3<T>(0), T(1));
+    }
+
+    template <typename T> 
+    inline _xmat4<T>::_xmat4(const _xmat3<T>& m)
+    {
+        this->value[0] = _xvec4<T>(m[0], T(0));
+        this->value[1] = _xvec4<T>(m[1], T(0));
+        this->value[2] = _xvec4<T>(m[2], T(0));
+        this->value[3] = _xvec4<T>(_xvec3<T>(0), T(1));
+    }
+
+	template <typename T> 
+    inline _xmat4<T>::_xmat4(const _xmat2x3<T>& m)
+    {
+        this->value[0] = _xvec4<T>(m[0], T(0));
+        this->value[1] = _xvec4<T>(m[1], T(0));
+        this->value[2] = _xvec4<T>(T(0));
+        this->value[3] = _xvec4<T>(_xvec3<T>(0), T(1));
+    }
+
+    template <typename T> 
+    inline _xmat4<T>::_xmat4(const _xmat3x2<T>& m)
+    {
+        this->value[0] = _xvec4<T>(m[0], _xvec2<T>(0));
+        this->value[1] = _xvec4<T>(m[1], _xvec2<T>(0));
+        this->value[2] = _xvec4<T>(m[2], _xvec2<T>(0));
+        this->value[3] = _xvec4<T>(_xvec3<T>(0), T(1));
+    }
+
+    template <typename T> 
+    inline _xmat4<T>::_xmat4(const _xmat2x4<T>& m)
+    {
+        this->value[0] = m[0];
+        this->value[1] = m[1];
+        this->value[2] = _xvec4<T>(T(0));
+        this->value[3] = _xvec4<T>(_xvec3<T>(0), T(1));
+    }
+
+    template <typename T> 
+    inline _xmat4<T>::_xmat4(const _xmat4x2<T>& m)
+    {
+        this->value[0] = _xvec4<T>(m[0], _xvec2<T>(0));
+        this->value[1] = _xvec4<T>(m[1], _xvec2<T>(0));
+        this->value[2] = _xvec4<T>(T(0));
+        this->value[3] = _xvec4<T>(_xvec3<T>(0), T(1));
+    }
+
+    template <typename T> 
+    inline _xmat4<T>::_xmat4(const _xmat3x4<T>& m)
+    {
+        this->value[0] = m[0];
+        this->value[1] = m[1];
+        this->value[2] = m[2];
+        this->value[3] = _xvec4<T>(_xvec3<T>(0), T(1));
+    }
+
+    template <typename T> 
+    inline _xmat4<T>::_xmat4(const _xmat4x3<T>& m)
+    {
+        this->value[0] = _xvec4<T>(m[0], T(0));
+        this->value[1] = _xvec4<T>(m[1], T(0));
+        this->value[2] = _xvec4<T>(m[2], T(0));
+        this->value[3] = _xvec4<T>(m[3], T(1));
+    }
+
+/*
+    template <typename T> 
+    inline _xmat4<T>::_xmat4(const T* a)
+    {
+        this->value[0] = _xvec4<T>(a[0], a[1], a[2], a[3]);
+        this->value[1] = _xvec4<T>(a[4], a[5], a[6], a[7]);
+        this->value[2] = _xvec4<T>(a[8], a[9], a[10], a[11]);
+        this->value[4] = _xvec4<T>(a[12], a[13], a[14], a[15]);
+    }
+*/
+    /*
+    // GL_GTX_euler_angles
+    template <typename T> 
+    inline _xmat4<T>::_xmat4(const _xvec3<T> & angles)
+    {
+        T ch = cos(angles.x);
+        T sh = sin(angles.x);
+        T cp = cos(angles.y);
+        T sp = sin(angles.y);
+        T cb = cos(angles.z);
+        T sb = sin(angles.z);
+
+        value[0][0] = ch * cb + sh * sp * sb;
+        value[0][1] = sb * cp;
+        value[0][2] = -sh * cb + ch * sp * sb;
+        value[0][3] = 0.0f;
+        value[1][0] = -ch * sb + sh * sp * cb;
+        value[1][1] = cb * cp;
+        value[1][2] = sb * sh + ch * sp * cb;
+        value[1][3] = 0.0f;
+        value[2][0] = sh * cp;
+        value[2][1] = -sp;
+        value[2][2] = ch * cp;
+        value[2][3] = 0.0f;
+        value[3][0] = 0.0f;
+        value[3][1] = 0.0f;
+        value[3][2] = 0.0f;
+        value[3][3] = 1.0f;
+    }
+    */
+    //////////////////////////////////////////////////////////////
+    // mat4 conversion
+    /*
+    template <typename T> 
+    inline _xmat4<T>::_xmat4(const _xquat<T> & q)
+    {
+        *this = _xmat4<T>(1);
+        this->value[0][0] = 1 - 2 * q.y * q.y - 2 * q.z * q.z;
+        this->value[0][1] = 2 * q.x * q.y + 2 * q.w * q.z;
+        this->value[0][2] = 2 * q.x * q.z - 2 * q.w * q.y;
+
+        this->value[1][0] = 2 * q.x * q.y - 2 * q.w * q.z;
+        this->value[1][1] = 1 - 2 * q.x * q.x - 2 * q.z * q.z;
+        this->value[1][2] = 2 * q.y * q.z + 2 * q.w * q.x;
+
+        this->value[2][0] = 2 * q.x * q.z + 2 * q.w * q.y;
+        this->value[2][1] = 2 * q.y * q.z - 2 * q.w * q.x;
+        this->value[2][2] = 1 - 2 * q.x * q.x - 2 * q.y * q.y;
+    }
+    */
+    //////////////////////////////////////////////////////////////
+    // mat4 operators
+
+    // This function shouldn't required but it seems that VC7.1 have an optimisation bug if this operator wasn't declared
+    template <typename T> 
+    inline _xmat4<T>& _xmat4<T>::operator= (const _xmat4<T>& m)
+    {
+        //memcpy could be faster
+        //memcpy(&this->value, &m.value, 16 * sizeof(T));
+        this->value[0] = m[0];
+        this->value[1] = m[1];
+        this->value[2] = m[2];
+        this->value[3] = m[3];
+        return *this;
+    }
+
+    template <typename T> 
+    inline _xmat4<T>& _xmat4<T>::operator+= (const T s)
+    {
+        this->value[0] += s;
+        this->value[1] += s;
+        this->value[2] += s;
+        this->value[3] += s;
+        return *this;
+    }
+
+    template <typename T> 
+    inline _xmat4<T>& _xmat4<T>::operator+= (const _xmat4<T>& m)
+    {
+        this->value[0] += m[0];
+        this->value[1] += m[1];
+        this->value[2] += m[2];
+        this->value[3] += m[3];
+        return *this;
+    }
+
+    template <typename T> 
+    inline _xmat4<T>& _xmat4<T>::operator-= (const T s)
+    {
+        this->value[0] -= s;
+        this->value[1] -= s;
+        this->value[2] -= s;
+        this->value[3] -= s;
+        return *this;
+    }
+
+    template <typename T> 
+    inline _xmat4<T>& _xmat4<T>::operator-= (const _xmat4<T>& m)
+    {
+        this->value[0] -= m[0];
+        this->value[1] -= m[1];
+        this->value[2] -= m[2];
+        this->value[3] -= m[3];
+        return *this;
+    }
+
+    template <typename T> 
+    inline _xmat4<T>& _xmat4<T>::operator*= (const T s)
+    {
+        this->value[0] *= s;
+        this->value[1] *= s;
+        this->value[2] *= s;
+        this->value[3] *= s;
+        return *this;
+    }
+
+    template <typename T> 
+    inline _xmat4<T>& _xmat4<T>::operator*= (const _xmat4<T>& m)
+    {
+        return (*this = *this * m);
+    }
+
+    template <typename T> 
+    inline _xmat4<T> & _xmat4<T>::operator/= (const T s)
+    {
+        this->value[0] /= s;
+        this->value[1] /= s;
+        this->value[2] /= s;
+        this->value[3] /= s;
+        return *this;
+    }
+
+    template <typename T> 
+    inline _xmat4<T>& _xmat4<T>::operator/= (const _xmat4<T>& m)
+    {
+        return (*this = *this / m);
+    }
+
+    template <typename T> 
+    inline _xmat4<T>& _xmat4<T>::operator-- ()
+    {
+        --this->value[0];
+        --this->value[1];
+        --this->value[2];
+        --this->value[3];
+        return *this;
+    }
+
+    template <typename T> 
+    inline _xmat4<T>& _xmat4<T>::operator++ ()
+    {
+        ++this->value[0];
+        ++this->value[1];
+        ++this->value[2];
+        ++this->value[3];
+        return *this;
+    }
+
+    // Private functions
+    template <typename T> 
+    inline _xmat4<T> _xmat4<T>::_inverse() const
+    {
+        // Calculate all mat2 determinants
+        T SubFactor00 = this->value[2][2] * this->value[3][3] - this->value[3][2] * this->value[2][3];
+        T SubFactor01 = this->value[2][1] * this->value[3][3] - this->value[3][1] * this->value[2][3];
+        T SubFactor02 = this->value[2][1] * this->value[3][2] - this->value[3][1] * this->value[2][2];
+        T SubFactor03 = this->value[2][0] * this->value[3][3] - this->value[3][0] * this->value[2][3];
+        T SubFactor04 = this->value[2][0] * this->value[3][2] - this->value[3][0] * this->value[2][2];
+        T SubFactor05 = this->value[2][0] * this->value[3][1] - this->value[3][0] * this->value[2][1];
+        T SubFactor06 = this->value[1][2] * this->value[3][3] - this->value[3][2] * this->value[1][3];
+        T SubFactor07 = this->value[1][1] * this->value[3][3] - this->value[3][1] * this->value[1][3];
+        T SubFactor08 = this->value[1][1] * this->value[3][2] - this->value[3][1] * this->value[1][2];
+        T SubFactor09 = this->value[1][0] * this->value[3][3] - this->value[3][0] * this->value[1][3];
+        T SubFactor10 = this->value[1][0] * this->value[3][2] - this->value[3][0] * this->value[1][2];
+        T SubFactor11 = this->value[1][1] * this->value[3][3] - this->value[3][1] * this->value[1][3];
+        T SubFactor12 = this->value[1][0] * this->value[3][1] - this->value[3][0] * this->value[1][1];
+        T SubFactor13 = this->value[1][2] * this->value[2][3] - this->value[2][2] * this->value[1][3];
+        T SubFactor14 = this->value[1][1] * this->value[2][3] - this->value[2][1] * this->value[1][3];
+        T SubFactor15 = this->value[1][1] * this->value[2][2] - this->value[2][1] * this->value[1][2];
+        T SubFactor16 = this->value[1][0] * this->value[2][3] - this->value[2][0] * this->value[1][3];
+        T SubFactor17 = this->value[1][0] * this->value[2][2] - this->value[2][0] * this->value[1][2];
+        T SubFactor18 = this->value[1][0] * this->value[2][1] - this->value[2][0] * this->value[1][1];
+
+        _xmat4<T> Inverse(
+            + (this->value[1][1] * SubFactor00 - this->value[1][2] * SubFactor01 + this->value[1][3] * SubFactor02),
+            - (this->value[1][0] * SubFactor00 - this->value[1][2] * SubFactor03 + this->value[1][3] * SubFactor04),
+            + (this->value[1][0] * SubFactor01 - this->value[1][1] * SubFactor03 + this->value[1][3] * SubFactor05),
+            - (this->value[1][0] * SubFactor02 - this->value[1][1] * SubFactor04 + this->value[1][2] * SubFactor05),
+
+            - (this->value[0][1] * SubFactor00 - this->value[0][2] * SubFactor01 + this->value[0][3] * SubFactor02),
+            + (this->value[0][0] * SubFactor00 - this->value[0][2] * SubFactor03 + this->value[0][3] * SubFactor04),
+            - (this->value[0][0] * SubFactor01 - this->value[0][1] * SubFactor03 + this->value[0][3] * SubFactor05),
+            + (this->value[0][0] * SubFactor02 - this->value[0][1] * SubFactor04 + this->value[0][2] * SubFactor05),
+
+            + (this->value[0][1] * SubFactor06 - this->value[0][2] * SubFactor07 + this->value[0][3] * SubFactor08),
+            - (this->value[0][0] * SubFactor06 - this->value[0][2] * SubFactor09 + this->value[0][3] * SubFactor10),
+            + (this->value[0][0] * SubFactor11 - this->value[0][1] * SubFactor09 + this->value[0][3] * SubFactor12),
+            - (this->value[0][0] * SubFactor08 - this->value[0][1] * SubFactor10 + this->value[0][2] * SubFactor12),
+
+            - (this->value[0][1] * SubFactor13 - this->value[0][2] * SubFactor14 + this->value[0][3] * SubFactor15),
+            + (this->value[0][0] * SubFactor13 - this->value[0][2] * SubFactor16 + this->value[0][3] * SubFactor17),
+            - (this->value[0][0] * SubFactor14 - this->value[0][1] * SubFactor16 + this->value[0][3] * SubFactor18),
+            + (this->value[0][0] * SubFactor15 - this->value[0][1] * SubFactor17 + this->value[0][2] * SubFactor18));
+
+        T Determinant = this->value[0][0] * Inverse[0][0] 
+                      + this->value[0][1] * Inverse[1][0] 
+                      + this->value[0][2] * Inverse[2][0] 
+                      + this->value[0][3] * Inverse[3][0];
+
+        Inverse /= Determinant;
+        return Inverse;
+    }
+
+	// Binary operators
+    template <typename T> 
+    inline _xmat4<T> operator+ (const _xmat4<T>& m, const T s)
+    {
+        return _xmat4<T>(
+            m[0] + s,
+            m[1] + s,
+            m[2] + s,
+            m[3] + s);
+    }
+
+    template <typename T> 
+    inline _xmat4<T> operator+ (const T s, const _xmat4<T>& m)
+    {
+        return _xmat4<T>(
+            m[0] + s,
+            m[1] + s,
+            m[2] + s,
+            m[3] + s);
+    }
+
+    template <typename T> 
+    inline _xvec4<T> operator+ (const _xmat4<T>& m, const _xvec4<T>& v)
+    {
+
+    }
+
+    template <typename T> 
+    inline _xvec4<T> operator+ (const _xvec4<T>& v, const _xmat4<T>& m)
+    {
+
+    }
+
+    template <typename T> 
+    inline _xmat4<T> operator+ (const _xmat4<T>& m1, const _xmat4<T>& m2)
+    {
+        return _xmat4<T>(
+            m1[0] + m2[0],
+            m1[1] + m2[1],
+            m1[2] + m2[2],
+            m1[3] + m2[3]);
+    }
+    
+    template <typename T> 
+    inline _xmat4<T> operator- (const _xmat4<T>& m, const T s)
+    {
+        return _xmat4<T>(
+            m[0] - s,
+            m[1] - s,
+            m[2] - s,
+            m[3] - s);
+    }
+
+    template <typename T> 
+    inline _xmat4<T> operator- (const T s, const _xmat4<T>& m)
+    {
+        return _xmat4<T>(
+            s - m[0],
+            s - m[1],
+            s - m[2],
+            s - m[3]);
+    }
+
+    template <typename T> 
+    inline _xvec4<T> operator- (const _xmat4<T>& m, const _xvec4<T>& v)
+    {
+
+    }
+
+    template <typename T> 
+    inline _xvec4<T> operator- (const _xvec4<T>& v, const _xmat4<T>& m)
+    {
+
+    }
+
+    template <typename T> 
+    inline _xmat4<T> operator- (const _xmat4<T>& m1, const _xmat4<T>& m2)
+    {
+        return _xmat4<T>(
+            m1[0] - m2[0],
+            m1[1] - m2[1],
+            m1[2] - m2[2],
+            m1[3] - m2[3]);
+    }
+
+    template <typename T> 
+    inline _xmat4<T> operator* (const _xmat4<T>& m, const T s)
+    {
+        return _xmat4<T>(
+            m[0] * s,
+            m[1] * s,
+            m[2] * s,
+            m[3] * s);
+    }
+
+    template <typename T> 
+    inline _xmat4<T> operator* (const T s, const _xmat4<T>& m)
+    {
+        return _xmat4<T>(
+            m[0] * s,
+            m[1] * s,
+            m[2] * s,
+            m[3] * s);
+    }
+
+    template <typename T> 
+    inline _xvec4<T> operator* (const _xmat4<T>& m, const _xvec4<T>& v)
+    {
+        return _xvec4<T>(
+            m[0][0] * v.x + m[1][0] * v.y + m[2][0] * v.z + m[3][0] * v.w,
+            m[0][1] * v.x + m[1][1] * v.y + m[2][1] * v.z + m[3][1] * v.w,
+            m[0][2] * v.x + m[1][2] * v.y + m[2][2] * v.z + m[3][2] * v.w,
+            m[0][3] * v.x + m[1][3] * v.y + m[2][3] * v.z + m[3][3] * v.w);
+    }
+
+    template <typename T> 
+    inline _xvec4<T> operator* (const _xvec4<T>& v, const _xmat4<T>& m)
+    {
+        return _xvec4<T>(
+            m[0][0] * v.x + m[0][1] * v.y + m[0][2] * v.z + m[0][3] * v.w,
+            m[1][0] * v.x + m[1][1] * v.y + m[1][2] * v.z + m[1][3] * v.w,
+            m[2][0] * v.x + m[2][1] * v.y + m[2][2] * v.z + m[2][3] * v.w,
+            m[3][0] * v.x + m[3][1] * v.y + m[3][2] * v.z + m[3][3] * v.w);
+    }
+
+    template <typename T> 
+    inline _xmat4<T> operator* (const _xmat4<T>& m1, const _xmat4<T>& m2)
+    {
+        const T SrcA00 = m1[0][0];
+        const T SrcA01 = m1[0][1];
+        const T SrcA02 = m1[0][2];
+        const T SrcA03 = m1[0][3];
+        const T SrcA10 = m1[1][0];
+        const T SrcA11 = m1[1][1];
+        const T SrcA12 = m1[1][2];
+        const T SrcA13 = m1[1][3];
+        const T SrcA20 = m1[2][0];
+        const T SrcA21 = m1[2][1];
+        const T SrcA22 = m1[2][2];
+        const T SrcA23 = m1[2][3];
+        const T SrcA30 = m1[3][0];
+        const T SrcA31 = m1[3][1];
+        const T SrcA32 = m1[3][2];
+        const T SrcA33 = m1[3][3];
+
+        const T SrcB00 = m2[0][0];
+        const T SrcB01 = m2[0][1];
+        const T SrcB02 = m2[0][2];
+        const T SrcB03 = m2[0][3];
+        const T SrcB10 = m2[1][0];
+        const T SrcB11 = m2[1][1];
+        const T SrcB12 = m2[1][2];
+        const T SrcB13 = m2[1][3];
+        const T SrcB20 = m2[2][0];
+        const T SrcB21 = m2[2][1];
+        const T SrcB22 = m2[2][2];
+        const T SrcB23 = m2[2][3];
+        const T SrcB30 = m2[3][0];
+        const T SrcB31 = m2[3][1];
+        const T SrcB32 = m2[3][2];
+        const T SrcB33 = m2[3][3];
+
+        _xmat4<T> Result;
+        Result[0][0] = SrcA00 * SrcB00 + SrcA10 * SrcB01 + SrcA20 * SrcB02 + SrcA30 * SrcB03;
+        Result[0][1] = SrcA01 * SrcB00 + SrcA11 * SrcB01 + SrcA21 * SrcB02 + SrcA31 * SrcB03;
+        Result[0][2] = SrcA02 * SrcB00 + SrcA12 * SrcB01 + SrcA22 * SrcB02 + SrcA32 * SrcB03;
+        Result[0][3] = SrcA03 * SrcB00 + SrcA13 * SrcB01 + SrcA23 * SrcB02 + SrcA33 * SrcB03;
+        Result[1][0] = SrcA00 * SrcB10 + SrcA10 * SrcB11 + SrcA20 * SrcB12 + SrcA30 * SrcB13;
+        Result[1][1] = SrcA01 * SrcB10 + SrcA11 * SrcB11 + SrcA21 * SrcB12 + SrcA31 * SrcB13;
+        Result[1][2] = SrcA02 * SrcB10 + SrcA12 * SrcB11 + SrcA22 * SrcB12 + SrcA32 * SrcB13;
+        Result[1][3] = SrcA03 * SrcB10 + SrcA13 * SrcB11 + SrcA23 * SrcB12 + SrcA33 * SrcB13;
+        Result[2][0] = SrcA00 * SrcB20 + SrcA10 * SrcB21 + SrcA20 * SrcB22 + SrcA30 * SrcB23;
+        Result[2][1] = SrcA01 * SrcB20 + SrcA11 * SrcB21 + SrcA21 * SrcB22 + SrcA31 * SrcB23;
+        Result[2][2] = SrcA02 * SrcB20 + SrcA12 * SrcB21 + SrcA22 * SrcB22 + SrcA32 * SrcB23;
+        Result[2][3] = SrcA03 * SrcB20 + SrcA13 * SrcB21 + SrcA23 * SrcB22 + SrcA33 * SrcB23;
+        Result[3][0] = SrcA00 * SrcB30 + SrcA10 * SrcB31 + SrcA20 * SrcB32 + SrcA30 * SrcB33;
+        Result[3][1] = SrcA01 * SrcB30 + SrcA11 * SrcB31 + SrcA21 * SrcB32 + SrcA31 * SrcB33;
+        Result[3][2] = SrcA02 * SrcB30 + SrcA12 * SrcB31 + SrcA22 * SrcB32 + SrcA32 * SrcB33;
+        Result[3][3] = SrcA03 * SrcB30 + SrcA13 * SrcB31 + SrcA23 * SrcB32 + SrcA33 * SrcB33;
+        return Result;
+    }
+
+    template <typename T> 
+    inline _xmat4<T> operator/ (const _xmat4<T>& m, const T s)
+    {
+        return _xmat4<T>(
+            m[0] / s,
+            m[1] / s,
+            m[2] / s,
+            m[3] / s);
+    }
+
+    template <typename T> 
+    inline _xmat4<T> operator/ (const T s, const _xmat4<T>& m)
+    {
+        return _xmat4<T>(
+            s / m[0],
+            s / m[1],
+            s / m[2],
+            s / m[3]);
+    }
+
+    template <typename T> 
+    inline _xvec4<T> operator/ (const _xmat4<T>& m, const _xvec4<T>& v)
+    {
+        return m._inverse() * v;
+    }
+
+    template <typename T> 
+    inline _xvec4<T> operator/ (const _xvec4<T>& v, const _xmat4<T>& m)
+    {
+        return v * m._inverse();
+    }
+ 
+    template <typename T> 
+    inline _xmat4<T> operator/ (const _xmat4<T>& m1, const _xmat4<T>& m2)
+    {
+        return m1 * m2._inverse();
+    }
+
+	// Unary constant operators
+    template <typename T> 
+    inline const _xmat4<T> operator- (const _xmat4<T>& m)
+    {
+        return _xmat4<T>(
+            -m.value[0], 
+            -m.value[1],
+            -m.value[2],
+            -m.value[3]);
+    }
+
+    template <typename T> 
+    inline const _xmat4<T> operator++ (const _xmat4<T>& m, int) 
+    {
+        return _xmat4<T>(
+            m.value[0] + 1,
+            m.value[1] + 1,
+            m.value[2] + 1,
+            m.value[3] + 1);
+    }
+
+    template <typename T> 
+    inline const _xmat4<T> operator-- (const _xmat4<T>& m, int) 
+    {
+        return _xmat4<T>(
+            m.value[0] - 1,
+            m.value[1] - 1,
+            m.value[2] - 1,
+            m.value[3] - 1);
+    }
+
+} //namespace detail
+} //namespace glm
+
+#endif //__mat4_inl__

+ 146 - 0
experimental/sse/glm/core/_xmat4x2.h

@@ -0,0 +1,146 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2008 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2006-10-01
+// Updated : 2006-10-01
+// Licence : This source is under GNU LGPL licence
+// File    : _mat4x2.h
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef __mat4x2_h__
+#define __mat4x2_h__
+
+namespace glm{
+namespace detail{
+
+    template <typename T> class _xvec3;
+    template <typename T> class _xvec4;
+    template <typename T> class _xmat2;
+    template <typename T> class _xmat3;
+    template <typename T> class _xmat4;
+    template <typename T> class _xmat2x3;
+    template <typename T> class _xmat3x2;
+    template <typename T> class _xmat2x4;
+    template <typename T> class _xmat3x4;
+    template <typename T> class _xmat4x3;
+
+    //!< \brief Template for 4 * 2 matrix of floating-point numbers.
+    template <typename T> 
+    class _xmat4x2
+    {
+    private:
+        // Data
+        _xvec2<T> value[4];
+
+    public:
+		typedef T value_type;
+		typedef _xvec4<T> col_type;
+		typedef _xvec2<T> row_type;
+		typedef int size_type;
+		static const size_type col_size;
+		static const size_type row_size;
+
+        // Constructors
+        _xmat4x2();
+        explicit _xmat4x2(const T x);
+        explicit _xmat4x2(
+            const T x0, const T y0,
+            const T x1, const T y1,
+            const T x2, const T y2,
+            const T x3, const T y3);
+        explicit _xmat4x2(
+            const _xvec2<T>& v0, 
+            const _xvec2<T>& v1,
+            const _xvec2<T>& v2,
+            const _xvec2<T>& v3);
+
+        // Conversions
+		template <typename U> 
+		explicit _xmat4x2(const _xmat4x2<U>& m);
+		
+		explicit _xmat4x2(const _xmat2<T>& x);
+        explicit _xmat4x2(const _xmat3<T>& x);
+        explicit _xmat4x2(const _xmat4<T>& x);
+        explicit _xmat4x2(const _xmat2x3<T>& x);
+        explicit _xmat4x2(const _xmat3x2<T>& x);
+        explicit _xmat4x2(const _xmat2x4<T>& x);
+        explicit _xmat4x2(const _xmat4x3<T>& x);
+        explicit _xmat4x2(const _xmat3x4<T>& x);
+
+        // Accesses
+        _xvec2<T>& operator[](int i) {return value[i];}
+        const _xvec2<T> & operator[](int i) const {return value[i];}
+		// operator T*() {return &value[0][0];}
+		// operator const T*() const {return &value[0][0];}
+		operator T*() {return (T*)this;}
+        operator const T*() const {return (const T*)this;}
+
+        // Unary updatable operators
+        _xmat4x2<T>& operator= (const _xmat4x2<T>& m);
+        _xmat4x2<T>& operator+= (const T s);
+        _xmat4x2<T>& operator+= (const _xmat4x2<T>& m);
+        _xmat4x2<T>& operator-= (const T s);
+        _xmat4x2<T>& operator-= (const _xmat4x2<T>& m);
+        _xmat4x2<T>& operator*= (const T s);
+        _xmat4x2<T>& operator*= (const _xmat2x4<T>& m);
+        _xmat4x2<T>& operator/= (const T s);
+/* ToDo
+        _xmat4x2<T>& operator/= (const _xmat2x4<T>& m);
+*/
+        _xmat4x2<T>& operator++ ();
+        _xmat4x2<T>& operator-- ();
+
+        // Unary constant operators
+        const _xmat4x2<T> operator- () const;
+        const _xmat4x2<T> operator++ (int n) const;
+        const _xmat4x2<T> operator-- (int n) const;
+    };
+
+    // Binary operators
+    template <typename T> 
+    _xmat4x2<T> operator+ (const _xmat4x2<T>& m, const T s);
+    
+    template <typename T> 
+    _xmat4x2<T> operator+ (const _xmat4x2<T>& m1, const _xmat4x2<T>& m2);
+    
+    template <typename T> 
+    _xmat4x2<T> operator- (const _xmat4x2<T>& m, const T s);
+
+    template <typename T> 
+    _xmat4x2<T> operator- (const _xmat4x2<T>& m1, const _xmat4x2<T>& m2);
+
+    template <typename T> 
+    _xmat4x2<T> operator* (const _xmat4x2<T>& m, const T s);
+
+    template <typename T> 
+    _xmat4x2<T> operator* (const T s, const _xmat4x2<T>& m);
+
+    template <typename T>
+    _xvec2<T> operator* (const _xmat4x2<T>& m, const _xvec4<T>& v);
+
+    template <typename T> 
+    _xmat4<T> operator* (const _xvec2<T>& v, const _xmat4x2<T>& m);
+/* ToDo
+    template <typename T> 
+    _xmat2<T> operator* (const _xmat4x2<T>& m1, const _xmat2x4<T>& m2);
+*/
+    template <typename T> 
+    _xmat4x2<T> operator/ (const _xmat4x2<T>& m, const T s);
+
+    template <typename T> 
+    _xmat4x2<T> operator/ (const T s, const _xmat4x2<T>& m);
+/* ToDo
+    template <typename T> 
+    _xvec2<T> operator/ (const _xmat4x2<T>& m, const _xvec4<T>& v);
+
+    template <typename T> 
+    _xvec4<T> operator/ (const _xvec2<T>& v, const _xmat4x2<T>& m);
+
+    template <typename T> 
+    _xmat2<T> operator/ (const _xmat4x2<T>& m1, const _xmat2x4<T>& m2);
+*/
+
+} //namespace detail
+} //namespace glm
+
+#endif //__mat4x2_h__

+ 440 - 0
experimental/sse/glm/core/_xmat4x2.inl

@@ -0,0 +1,440 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2008 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2006-10-01
+// Updated : 2006-10-01
+// Licence : This source is under GNU LGPL licence
+// File    : _mat4x2.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef __mat4x2_inl__
+#define __mat4x2_inl__
+
+#include "./_xmat4x2.h"
+
+namespace glm{
+namespace detail{
+
+	template <typename T> const typename _xmat4x2<T>::size_type _xmat4x2<T>::col_size = 4;
+	template <typename T> const typename _xmat4x2<T>::size_type _xmat4x2<T>::row_size = 2;
+
+    //////////////////////////////////////////////////////////////
+    // Constructors
+
+    template <typename T> 
+    inline _xmat4x2<T>::_xmat4x2()
+    {
+        this->value[0] = _xvec2<T>(1, 0);
+        this->value[1] = _xvec2<T>(0, 1);
+        this->value[2] = _xvec2<T>(0, 0);
+        this->value[3] = _xvec2<T>(0, 0);
+    }
+
+    template <typename T> 
+    inline _xmat4x2<T>::_xmat4x2(const T f)
+    {
+        this->value[0] = _xvec2<T>(f, 0);
+        this->value[1] = _xvec2<T>(0, f);
+        this->value[2] = _xvec2<T>(0, 0);
+        this->value[3] = _xvec2<T>(0, 0);
+    }
+
+    template <typename T> 
+    inline _xmat4x2<T>::_xmat4x2
+    (
+        const T x0, const T y0,
+        const T x1, const T y1,
+        const T x2, const T y2,
+        const T x3, const T y3
+    )
+    {
+        this->value[0] = _xvec2<T>(x0, y0);
+        this->value[1] = _xvec2<T>(x1, y1);
+        this->value[2] = _xvec2<T>(x2, y2);
+        this->value[3] = _xvec2<T>(x3, y3);
+    }
+
+    template <typename T> 
+    inline _xmat4x2<T>::_xmat4x2
+    (
+        const _xvec2<T> & v0, 
+        const _xvec2<T> & v1, 
+        const _xvec2<T> & v2,
+        const _xvec2<T> & v3
+    )
+    {
+        this->value[0] = v0;
+        this->value[1] = v1;
+        this->value[2] = v2;
+        this->value[3] = v3;
+    }
+
+    // Conversion
+    template <typename T> 
+    template <typename U> 
+    inline _xmat4x2<T>::_xmat4x2(const _xmat4x2<U>& m)
+    {
+        this->value[0] = _xvec2<T>(m[0]);
+        this->value[1] = _xvec2<T>(m[1]);
+        this->value[2] = _xvec2<T>(m[2]);
+        this->value[3] = _xvec2<T>(m[3]);
+	}
+
+    template <typename T> 
+    inline _xmat4x2<T>::_xmat4x2(const _xmat2<T>& m)
+    {
+        this->value[0] = _xvec2<T>(m[0]);
+        this->value[1] = _xvec2<T>(m[1]);
+        this->value[2] = _xvec2<T>(m[2]);
+        this->value[3] = _xvec2<T>(T(0));
+    }
+
+    template <typename T> 
+    inline _xmat4x2<T>::_xmat4x2(const _xmat3<T>& m)
+    {
+        this->value[0] = _xvec2<T>(m[0]);
+        this->value[1] = _xvec2<T>(m[1]);
+        this->value[2] = _xvec2<T>(m[2]);
+        this->value[3] = _xvec2<T>(T(0));
+    }
+
+    template <typename T> 
+    inline _xmat4x2<T>::_xmat4x2(const _xmat4<T>& m)
+    {
+        this->value[0] = _xvec2<T>(m[0]);
+        this->value[1] = _xvec2<T>(m[1]);
+        this->value[2] = _xvec2<T>(m[2]);
+        this->value[3] = _xvec2<T>(m[3]);
+    }
+
+    template <typename T> 
+    inline _xmat4x2<T>::_xmat4x2(const _xmat2x3<T>& m)
+    {
+        this->value[0] = _xvec2<T>(m[0]);
+        this->value[1] = _xvec2<T>(m[1]);
+        this->value[2] = _xvec2<T>(T(0));
+        this->value[3] = _xvec2<T>(T(0));
+    }
+
+    template <typename T> 
+    inline _xmat4x2<T>::_xmat4x2(const _xmat3x2<T>& m)
+    {
+        this->value[0] = _xvec2<T>(m[0]);
+        this->value[1] = _xvec2<T>(m[1]);
+        this->value[2] = _xvec2<T>(m[2]);
+        this->value[3] = _xvec2<T>(T(0));
+    }
+
+    template <typename T> 
+    inline _xmat4x2<T>::_xmat4x2(const _xmat2x4<T>& m)
+    {
+        this->value[0] = _xvec2<T>(m[0]);
+        this->value[1] = _xvec2<T>(m[1]);
+        this->value[2] = _xvec2<T>(T(0));
+        this->value[3] = _xvec2<T>(T(0));
+    }
+
+    template <typename T> 
+    inline _xmat4x2<T>::_xmat4x2(const _xmat4x3<T>& m)
+    {
+        this->value[0] = _xvec2<T>(m[0]);
+        this->value[1] = _xvec2<T>(m[1]);
+        this->value[2] = _xvec2<T>(m[2]);
+        this->value[3] = _xvec2<T>(m[3]);
+    }
+
+    template <typename T> 
+    inline _xmat4x2<T>::_xmat4x2(const _xmat3x4<T>& m)
+    {
+        this->value[0] = _xvec2<T>(m[0]);
+        this->value[1] = _xvec2<T>(m[1]);
+        this->value[2] = _xvec2<T>(m[2]);
+        this->value[3] = _xvec2<T>(T(0));
+    }
+
+    //////////////////////////////////////////////////////////////
+    // Unary updatable operators
+
+    template <typename T> 
+    inline _xmat4x2<T>& _xmat4x2<T>::operator= (const _xmat4x2<T>& m)
+    {
+        this->value[0] = m[0];
+        this->value[1] = m[1];
+        this->value[2] = m[2];
+        this->value[3] = m[3];
+        return *this;
+    }
+
+    template <typename T> 
+    inline _xmat4x2<T>& _xmat4x2<T>::operator+= (const T s)
+    {
+        this->value[0] += s;
+        this->value[1] += s;
+        this->value[2] += s;
+        this->value[3] += s;
+        return *this;
+    }
+
+    template <typename T> 
+    inline _xmat4x2<T>& _xmat4x2<T>::operator+= (const _xmat4x2<T>& m)
+    {
+        this->value[0] += m[0];
+        this->value[1] += m[1];
+        this->value[2] += m[2];
+        this->value[3] += m[3];
+        return *this;
+    }
+
+    template <typename T> 
+    inline _xmat4x2<T>& _xmat4x2<T>::operator-= (const T s)
+    {
+        this->value[0] -= s;
+        this->value[1] -= s;
+        this->value[2] -= s;
+        this->value[3] -= s;
+        return *this;
+    }
+
+    template <typename T> 
+    inline _xmat4x2<T>& _xmat4x2<T>::operator-= (const _xmat4x2<T>& m)
+    {
+        this->value[0] -= m[0];
+        this->value[1] -= m[1];
+        this->value[2] -= m[2];
+        this->value[3] -= m[3];
+        return *this;
+    }
+
+    template <typename T> 
+    inline _xmat4x2<T>& _xmat4x2<T>::operator*= (const T s)
+    {
+        this->value[0] *= s;
+        this->value[1] *= s;
+        this->value[2] *= s;
+        this->value[3] *= s;
+        return *this;
+    }
+
+    template <typename T> 
+    inline _xmat4x2<T>& _xmat4x2<T>::operator*= (const _xmat2x4<T>& m)
+    {
+        return (*this = _xmat4x2<T>(*this * m));
+    }
+
+    template <typename T> 
+    inline _xmat4x2<T> & _xmat4x2<T>::operator/= (const T s)
+    {
+        this->value[0] /= s;
+        this->value[1] /= s;
+        this->value[2] /= s;
+        this->value[3] /= s;
+        return *this;
+    }
+/* ToDo
+    template <typename T> 
+    inline _xmat4x2<T>& _xmat4x2<T>::operator/= (const _xmat2x4<T>& m)
+    {
+        return (*this = *this / m);
+    }
+*/
+    template <typename T> 
+    inline _xmat4x2<T>& _xmat4x2<T>::operator++ ()
+    {
+        ++this->value[0];
+        ++this->value[1];
+        ++this->value[2];
+        ++this->value[3];
+        return *this;
+    }
+
+    template <typename T> 
+    inline _xmat4x2<T>& _xmat4x2<T>::operator-- ()
+    {
+        --this->value[0];
+        --this->value[1];
+        --this->value[2];
+        --this->value[3];
+        return *this;
+    }
+    
+    //////////////////////////////////////////////////////////////
+    // Unary constant operators
+    template <typename T> 
+    inline const _xmat4x2<T> _xmat4x2<T>::operator- () const
+    {
+        return _xmat4x2<T>(
+            -this->value[0], 
+            -this->value[1],
+            -this->value[2],
+            -this->value[3]);
+    }
+
+    template <typename T> 
+    inline const _xmat4x2<T> _xmat4x2<T>::operator-- (int n) const 
+    {
+        _xmat4x2<T> m = *this;
+        --m.value[0];
+        --m.value[1];
+        --m.value[2];
+        --m.value[3];
+        return m;
+    }
+
+    template <typename T> 
+    inline const _xmat4x2<T> _xmat4x2<T>::operator++ (int n) const
+    {
+        _xmat4x2<T> m = *this;
+        ++m.value[0];
+        ++m.value[1];
+        ++m.value[2];
+        ++m.value[3];
+        return m;
+    }
+
+    //////////////////////////////////////////////////////////////
+    // Binary operators
+
+    template <typename T> 
+    inline _xmat4x2<T> operator+ (const _xmat4x2<T>& m, const T s)
+    {
+        return _xmat4x2<T>(
+            m[0] + s,
+            m[1] + s,
+            m[2] + s,
+            m[3] + s);
+    }
+
+    template <typename T> 
+    inline _xmat4x2<T> operator+ (const _xmat4x2<T>& m1, const _xmat4x2<T>& m2)
+    {
+        return _xmat4x2<T>(
+            m1[0] + m2[0],
+            m1[1] + m2[1],
+            m1[2] + m2[2],
+            m1[3] + m2[3]);
+    }
+
+    template <typename T> 
+    inline _xmat4x2<T> operator- (const _xmat4x2<T>& m, const T s)
+    {
+        return _xmat4x2<T>(
+            m[0] - s,
+            m[1] - s,
+            m[2] - s,
+            m[3] - s);
+    }
+
+    template <typename T> 
+    inline _xmat4x2<T> operator- (const _xmat4x2<T>& m1, const _xmat4x2<T>& m2)
+    {
+        return _xmat4x2<T>(
+            m1[0] - m2[0],
+            m1[1] - m2[1],
+            m1[2] - m2[2],
+            m1[3] - m2[3]);
+    }
+
+    template <typename T> 
+    inline _xmat4x2<T> operator* (const _xmat4x2<T>& m, const T s)
+    {
+        return _xmat4x2<T>(
+            m[0] * s,
+            m[1] * s,
+            m[2] * s,
+            m[3] * s);
+    }
+
+    template <typename T> 
+    inline _xmat4x2<T> operator* (const T s, const _xmat4x2<T> & m)
+    {
+        return _xmat4x2<T>(
+            m[0] * s,
+            m[1] * s,
+            m[2] * s,
+            m[3] * s);
+    }
+   
+    template <typename T>
+    inline _xvec2<T> operator* (const _xmat4x2<T>& m, const _xvec4<T>& v)
+    {
+        return _xvec2<T>(
+            m[0][0] * v.x + m[1][0] * v.y + m[2][0] * v.z + m[3][0] * v.w,
+            m[0][1] * v.x + m[1][1] * v.y + m[2][1] * v.z + m[3][1] * v.w);
+    }
+
+    template <typename T> 
+    inline _xvec4<T> operator* (const _xvec2<T>& v, const _xmat4x2<T>& m) 
+    {
+        return _xvec4<T>(
+            v.x * m[0][0] + v.y * m[0][1],
+            v.x * m[1][0] + v.y * m[1][1],
+            v.x * m[2][0] + v.y * m[2][1],
+            v.x * m[3][0] + v.y * m[3][1]);
+    }
+
+    template <typename T> 
+    inline _xmat2<T> operator* (const _xmat4x2<T>& m1, const _xmat2x4<T>& m2)
+    {
+        const T SrcA00 = m1[0][0];
+        const T SrcA01 = m1[0][1];
+        const T SrcA10 = m1[1][0];
+        const T SrcA11 = m1[1][1];
+        const T SrcA20 = m1[2][0];
+        const T SrcA21 = m1[2][1];
+        const T SrcA30 = m1[3][0];
+        const T SrcA31 = m1[3][1];
+
+        const T SrcB00 = m2[0][0];
+        const T SrcB01 = m2[0][1];
+        const T SrcB02 = m2[0][2];
+        const T SrcB03 = m2[0][3];
+        const T SrcB10 = m2[1][0];
+        const T SrcB11 = m2[1][1];
+        const T SrcB12 = m2[1][2];
+        const T SrcB13 = m2[1][3];
+
+        _xmat2<T> Result;
+        Result[0][0] = SrcA00 * SrcB00 + SrcA01 * SrcB01 + SrcA20 * SrcB02 + SrcA30 * SrcB03;
+        Result[0][1] = SrcA01 * SrcB00 + SrcA11 * SrcB01 + SrcA21 * SrcB02 + SrcA31 * SrcB03;
+        Result[1][0] = SrcA00 * SrcB10 + SrcA10 * SrcB11 + SrcA20 * SrcB12 + SrcA30 * SrcB13;
+        Result[1][1] = SrcA01 * SrcB10 + SrcA11 * SrcB11 + SrcA21 * SrcB12 + SrcA31 * SrcB13;
+        return Result;
+    }
+
+    template <typename T> 
+    inline _xmat4x2<T> operator/ (const _xmat4x2<T>& m, const T s)
+    {
+        return _xmat4x2<T>(
+            m.value[0] / s,
+            m.value[1] / s,
+            m.value[2] / s,
+            m.value[3] / s);        
+    }
+
+    template <typename T> 
+    inline _xmat4x2<T> operator/ (const T s, const _xmat4x2<T>& m)
+    {
+        return _xmat4x2<T>(
+            s / m.value[0],
+            s / m.value[1],
+            s / m.value[2],
+            s / m.value[3]);        
+    }
+/* ToDo
+    template <typename T> 
+    inline _xmat4x2<T> operator/ (const _xmat4x2<T>& m1, const _xmat2x4<T>& m2)
+    {
+
+    }
+
+    template <typename T> 
+    inline _xmat4x2<T> operator/ (const _xmat2x4<T>& m1, const _xmat4x2<T>& m2)
+    {
+
+    }
+*/
+
+} //namespace detail
+} //namespace glm
+
+#endif //__mat4x2_inl__

+ 146 - 0
experimental/sse/glm/core/_xmat4x3.h

@@ -0,0 +1,146 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2008 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2006-08-04
+// Updated : 2006-10-01
+// Licence : This source is under GNU LGPL licence
+// File    : _mat4x3.h
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef __mat4x3_h__
+#define __mat4x3_h__
+
+namespace glm{
+namespace detail{
+
+    template <typename T> class _xvec3;
+    template <typename T> class _xvec4;
+    template <typename T> class _xmat2;
+    template <typename T> class _xmat3;
+    template <typename T> class _xmat4;
+    template <typename T> class _xmat2x3;
+    template <typename T> class _xmat3x2;
+    template <typename T> class _xmat2x4;
+    template <typename T> class _xmat4x2;
+    template <typename T> class _xmat3x4;
+
+    //!< \brief Template for 4 * 3 matrix of floating-point numbers.
+    template <typename T> 
+    class _xmat4x3
+    {
+    private:
+        // Data
+        _xvec3<T> value[4];
+
+    public:
+		typedef T value_type;
+		typedef _xvec4<T> col_type;
+		typedef _xvec3<T> row_type;
+		typedef int size_type;
+		static const size_type col_size;
+		static const size_type row_size;
+
+        // Constructors
+        _xmat4x3();
+        explicit _xmat4x3(const T x);
+        explicit _xmat4x3(
+            const T x0, const T y0, const T z0,
+            const T x1, const T y1, const T z1,
+            const T x2, const T y2, const T z2,
+            const T x3, const T y3, const T z3);
+        explicit _xmat4x3(
+            const _xvec3<T>& v0, 
+            const _xvec3<T>& v1,
+            const _xvec3<T>& v2,
+            const _xvec3<T>& v3);
+
+        // Conversion
+		template <typename U> 
+		explicit _xmat4x3(const _xmat4x3<U>& m);
+		
+		explicit _xmat4x3(const _xmat2<T>& x);
+        explicit _xmat4x3(const _xmat3<T>& x);
+        explicit _xmat4x3(const _xmat4<T>& x);
+        explicit _xmat4x3(const _xmat2x3<T>& x);
+        explicit _xmat4x3(const _xmat3x2<T>& x);
+        explicit _xmat4x3(const _xmat2x4<T>& x);
+        explicit _xmat4x3(const _xmat4x2<T>& x);
+        explicit _xmat4x3(const _xmat3x4<T>& x);
+
+        // Accesses
+        _xvec3<T>& operator[](int i) {return value[i];}
+        const _xvec3<T> & operator[](int i) const {return value[i];}
+		// operator T*() {return &value[0][0];}
+		// operator const T*() const {return &value[0][0];}
+		operator T*() {return (T*)this;}
+        operator const T*() const {return (const T*)this;}
+
+        // Unary updatable operators
+        _xmat4x3<T>& operator= (const _xmat4x3<T>& m);
+        _xmat4x3<T>& operator+= (const T s);
+        _xmat4x3<T>& operator+= (const _xmat4x3<T>& m);
+        _xmat4x3<T>& operator-= (const T s);
+        _xmat4x3<T>& operator-= (const _xmat4x3<T>& m);
+        _xmat4x3<T>& operator*= (const T s);
+        _xmat4x3<T>& operator*= (const _xmat3x4<T>& m);
+        _xmat4x3<T>& operator/= (const T s);
+/* ToDo
+        _xmat4x3<T>& operator/= (const _xmat3x4<T>& m);
+*/
+        _xmat4x3<T>& operator++ ();
+        _xmat4x3<T>& operator-- ();
+
+        // Unary constant operators
+        const _xmat4x3<T> operator- () const;
+        const _xmat4x3<T> operator++ (int n) const;
+        const _xmat4x3<T> operator-- (int n) const;
+    };
+
+    // Binary operators
+    template <typename T> 
+    _xmat4x3<T> operator+ (const _xmat4x3<T>& m, const T s);
+    
+    template <typename T> 
+    _xmat4x3<T> operator+ (const _xmat4x3<T>& m1, const _xmat4x3<T>& m2);
+    
+    template <typename T> 
+    _xmat4x3<T> operator- (const _xmat4x3<T>& m, const T s);
+
+    template <typename T> 
+    _xmat4x3<T> operator- (const _xmat4x3<T>& m1, const _xmat4x3<T>& m2);
+
+    template <typename T> 
+    _xmat4x3<T> operator* (const _xmat4x3<T>& m, const T s);
+
+    template <typename T> 
+    _xmat4x3<T> operator* (const T s, const _xmat4x3<T>& m);
+
+    template <typename T>
+    _xvec3<T> operator* (const _xmat4x3<T>& m, const _xvec4<T>& v);
+
+    template <typename T> 
+    _xvec4<T> operator* (const _xvec3<T>& v, const _xmat4x3<T>& m);
+
+    template <typename T> 
+    _xmat3<T> operator* (const _xmat4x3<T>& m1, const _xmat3x4<T>& m2);
+
+    template <typename T> 
+    _xmat4x3<T> operator/ (const _xmat4x3<T>& m, const T s);
+
+    template <typename T> 
+    _xmat4x3<T> operator/ (const T s, const _xmat4x3<T>& m);
+/* ToDo
+    template <typename T> 
+    _xvec3<T> operator/ (const _xmat4x3<T>& m, const _xvec4<T>& v);
+
+    template <typename T> 
+    _xvec4<T> operator/ (const _xvec3<T>& v, const _xmat4x3<T>& m);
+
+    template <typename T> 
+    _xmat3<T> operator/ (const _xmat4x3<T>& m1, const _xmat3x4<T>& m2);
+*/
+
+} //namespace detail
+} //namespace glm
+
+#endif //__mat4x3_h__

+ 460 - 0
experimental/sse/glm/core/_xmat4x3.inl

@@ -0,0 +1,460 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2008 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2006-04-17
+// Updated : 2006-04-17
+// Licence : This source is under GNU LGPL licence
+// File    : _mat4x3.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef __mat4x3_inl__
+#define __mat4x3_inl__
+
+#include "./_xmat4x3.h"
+
+namespace glm{
+namespace detail{
+
+	template <typename T> const typename _xmat4x3<T>::size_type _xmat4x3<T>::col_size = 4;
+	template <typename T> const typename _xmat4x3<T>::size_type _xmat4x3<T>::row_size = 3;
+
+    //////////////////////////////////////////////////////////////
+    // Constructors
+
+    template <typename T> 
+    inline _xmat4x3<T>::_xmat4x3()
+    {
+        this->value[0] = _xvec3<T>(1, 0, 0);
+        this->value[1] = _xvec3<T>(0, 1, 0);
+        this->value[2] = _xvec3<T>(0, 0, 1);
+        this->value[3] = _xvec3<T>(0, 0, 0);
+    }
+
+    template <typename T> 
+    inline _xmat4x3<T>::_xmat4x3(const T f)
+    {
+        this->value[0] = _xvec3<T>(f, 0, 0);
+        this->value[1] = _xvec3<T>(0, f, 0);
+        this->value[2] = _xvec3<T>(0, 0, f);
+        this->value[3] = _xvec3<T>(0, 0, 0);
+    }
+
+    template <typename T> 
+    inline _xmat4x3<T>::_xmat4x3
+    (
+        const T x0, const T y0, const T z0,
+        const T x1, const T y1, const T z1,
+        const T x2, const T y2, const T z2,
+        const T x3, const T y3, const T z3
+    )
+    {
+        this->value[0] = _xvec3<T>(x0, y0, z0);
+        this->value[1] = _xvec3<T>(x1, y1, z1);
+        this->value[2] = _xvec3<T>(x2, y2, z2);
+        this->value[3] = _xvec3<T>(x3, y3, z3);
+    }
+
+    template <typename T> 
+    inline _xmat4x3<T>::_xmat4x3
+    (
+        const _xvec3<T> & v0, 
+        const _xvec3<T> & v1, 
+        const _xvec3<T> & v2,
+        const _xvec3<T> & v3
+    )
+    {
+        this->value[0] = v0;
+        this->value[1] = v1;
+        this->value[2] = v2;
+        this->value[3] = v3;
+    }
+
+    // Conversion
+    template <typename T> 
+    template <typename U> 
+    inline _xmat4x3<T>::_xmat4x3(const _xmat4x3<U>& m)
+    {
+        this->value[0] = _xvec3<T>(m[0]);
+        this->value[1] = _xvec3<T>(m[1]);
+        this->value[2] = _xvec3<T>(m[2]);
+        this->value[3] = _xvec3<T>(m[3]);
+	}
+
+    template <typename T> 
+    inline _xmat4x3<T>::_xmat4x3(const _xmat2<T>& m)
+    {
+        this->value[0] = _xvec3<T>(m[0], T(0));
+        this->value[1] = _xvec3<T>(m[1], T(0));
+        this->value[2] = _xvec3<T>(m[2], T(1));
+        this->value[3] = _xvec3<T>(T(0));
+    }
+
+    template <typename T> 
+    inline _xmat4x3<T>::_xmat4x3(const _xmat3<T>& m)
+    {
+        this->value[0] = _xvec3<T>(m[0]);
+        this->value[1] = _xvec3<T>(m[1]);
+        this->value[2] = _xvec3<T>(m[2]);
+        this->value[3] = _xvec3<T>(T(0));
+    }
+
+    template <typename T> 
+    inline _xmat4x3<T>::_xmat4x3(const _xmat4<T>& m)
+    {
+        this->value[0] = _xvec3<T>(m[0]);
+        this->value[1] = _xvec3<T>(m[1]);
+        this->value[2] = _xvec3<T>(m[2]);
+        this->value[3] = _xvec3<T>(m[3]);
+    }
+
+    template <typename T> 
+    inline _xmat4x3<T>::_xmat4x3(const _xmat2x3<T>& m)
+    {
+        this->value[0] = _xvec3<T>(m[0]);
+        this->value[1] = _xvec3<T>(m[1]);
+        this->value[2] = _xvec3<T>(T(0), T(0), T(1));
+        this->value[3] = _xvec3<T>(T(0));
+    }
+
+    template <typename T> 
+    inline _xmat4x3<T>::_xmat4x3(const _xmat3x2<T>& m)
+    {
+        this->value[0] = _xvec3<T>(m[0], T(0));
+        this->value[1] = _xvec3<T>(m[1], T(0));
+        this->value[2] = _xvec3<T>(m[2], T(1));
+        this->value[3] = _xvec3<T>(T(0));
+    }
+
+    template <typename T> 
+    inline _xmat4x3<T>::_xmat4x3(const _xmat2x4<T>& m)
+    {
+        this->value[0] = _xvec3<T>(m[0]);
+        this->value[1] = _xvec3<T>(m[1]);
+        this->value[2] = _xvec3<T>(T(0), T(0), T(1));
+        this->value[3] = _xvec3<T>(T(0));
+    }
+
+    template <typename T> 
+    inline _xmat4x3<T>::_xmat4x3(const _xmat4x2<T>& m)
+    {
+        this->value[0] = _xvec3<T>(m[0], T(0));
+        this->value[1] = _xvec3<T>(m[1], T(0));
+        this->value[2] = _xvec3<T>(m[2], T(1));
+        this->value[3] = _xvec3<T>(m[3], T(0));
+    }
+
+    template <typename T> 
+    inline _xmat4x3<T>::_xmat4x3(const _xmat3x4<T>& m)
+    {
+        this->value[0] = _xvec3<T>(m[0]);
+        this->value[1] = _xvec3<T>(m[1]);
+        this->value[2] = _xvec3<T>(m[2]);
+        this->value[3] = _xvec3<T>(T(0));
+    }
+
+    //////////////////////////////////////////////////////////////
+    // Unary updatable operators
+
+    template <typename T> 
+    inline _xmat4x3<T>& _xmat4x3<T>::operator= (const _xmat4x3<T>& m)
+    {
+        this->value[0] = m[0];
+        this->value[1] = m[1];
+        this->value[2] = m[2];
+        this->value[3] = m[3];
+        return *this;
+    }
+
+    template <typename T> 
+    inline _xmat4x3<T>& _xmat4x3<T>::operator+= (const T s)
+    {
+        this->value[0] += s;
+        this->value[1] += s;
+        this->value[2] += s;
+        this->value[3] += s;
+        return *this;
+    }
+
+    template <typename T> 
+    inline _xmat4x3<T>& _xmat4x3<T>::operator+= (const _xmat4x3<T>& m)
+    {
+        this->value[0] += m[0];
+        this->value[1] += m[1];
+        this->value[2] += m[2];
+        this->value[3] += m[3];
+        return *this;
+    }
+
+    template <typename T> 
+    inline _xmat4x3<T>& _xmat4x3<T>::operator-= (const T s)
+    {
+        this->value[0] -= s;
+        this->value[1] -= s;
+        this->value[2] -= s;
+        this->value[3] -= s;
+        return *this;
+    }
+
+    template <typename T> 
+    inline _xmat4x3<T>& _xmat4x3<T>::operator-= (const _xmat4x3<T>& m)
+    {
+        this->value[0] -= m[0];
+        this->value[1] -= m[1];
+        this->value[2] -= m[2];
+        this->value[3] -= m[3];
+        return *this;
+    }
+
+    template <typename T> 
+    inline _xmat4x3<T>& _xmat4x3<T>::operator*= (const T s)
+    {
+        this->value[0] *= s;
+        this->value[1] *= s;
+        this->value[2] *= s;
+        this->value[3] *= s;
+        return *this;
+    }
+
+    template <typename T> 
+    inline _xmat4x3<T>& _xmat4x3<T>::operator*= (const _xmat3x4<T>& m)
+    {
+        return (*this = _xmat4x3<T>(*this * m));
+    }
+
+    template <typename T> 
+    inline _xmat4x3<T> & _xmat4x3<T>::operator/= (const T s)
+    {
+        this->value[0] /= s;
+        this->value[1] /= s;
+        this->value[2] /= s;
+        this->value[3] /= s;
+        return *this;
+    }
+/* ToDo
+    template <typename T> 
+    inline _xmat4x3<T>& _xmat4x3<T>::operator/= (const _xmat3x4<T>& m)
+    {
+        return (*this = *this / m);
+    }
+*/
+    template <typename T> 
+    inline _xmat4x3<T>& _xmat4x3<T>::operator++ ()
+    {
+        ++this->value[0];
+        ++this->value[1];
+        ++this->value[2];
+        ++this->value[3];
+        return *this;
+    }
+
+    template <typename T> 
+    inline _xmat4x3<T>& _xmat4x3<T>::operator-- ()
+    {
+        --this->value[0];
+        --this->value[1];
+        --this->value[2];
+        --this->value[3];
+        return *this;
+    }
+    
+    //////////////////////////////////////////////////////////////
+    // Unary constant operators
+    template <typename T> 
+    inline const _xmat4x3<T> _xmat4x3<T>::operator- () const
+    {
+        return _xmat4x3<T>(
+            -this->value[0], 
+            -this->value[1],
+            -this->value[2],
+            -this->value[3]);
+    }
+
+    template <typename T> 
+    inline const _xmat4x3<T> _xmat4x3<T>::operator-- (int n) const 
+    {
+        _xmat4x3<T> m = *this;
+        --m.value[0];
+        --m.value[1];
+        --m.value[2];
+        --m.value[3];
+        return m;
+    }
+
+    template <typename T> 
+    inline const _xmat4x3<T> _xmat4x3<T>::operator++ (int n) const
+    {
+        _xmat4<T> m = *this;
+        ++m.value[0];
+        ++m.value[1];
+        ++m.value[2];
+        ++m.value[3];
+        return m;
+    }
+
+    //////////////////////////////////////////////////////////////
+    // Binary operators
+
+    template <typename T> 
+    inline _xmat4x3<T> operator+ (const _xmat4x3<T>& m, const T s)
+    {
+        return _xmat4x3<T>(
+            m[0] + s,
+            m[1] + s,
+            m[2] + s,
+            m[3] + s);
+    }
+
+    template <typename T> 
+    inline _xmat4x3<T> operator+ (const _xmat4x3<T>& m1, const _xmat4x3<T>& m2)
+    {
+        return _xmat4x3<T>(
+            m1[0] + m2[0],
+            m1[1] + m2[1],
+            m1[2] + m2[2],
+            m1[3] + m2[3]);
+    }
+
+    template <typename T> 
+    inline _xmat4x3<T> operator- (const _xmat4x3<T>& m, const T s)
+    {
+        return _xmat4x3<T>(
+            m[0] - s,
+            m[1] - s,
+            m[2] - s,
+            m[3] - s);
+    }
+
+    template <typename T> 
+    inline _xmat4x3<T> operator- (const _xmat4x3<T>& m1, const _xmat4x3<T>& m2)
+    {
+        return _xmat4x3<T>(
+            m1[0] - m2[0],
+            m1[1] - m2[1],
+            m1[2] - m2[2],
+            m1[3] - m2[3]);
+    }
+
+    template <typename T> 
+    inline _xmat4x3<T> operator* (const _xmat4x3<T>& m, const T s)
+    {
+        return _xmat4x3<T>(
+            m[0] * s,
+            m[1] * s,
+            m[2] * s,
+            m[3] * s);
+    }
+
+    template <typename T> 
+    inline _xmat4x3<T> operator* (const T s, const _xmat4x3<T> & m)
+    {
+        return _xmat4x3<T>(
+            m[0] * s,
+            m[1] * s,
+            m[2] * s,
+            m[3] * s);
+    }
+   
+    template <typename T>
+    inline _xvec3<T> operator* (const _xmat4x3<T>& m, const _xvec4<T>& v)
+    {
+        return _xvec3<T>(
+            m[0][0] * v.x + m[1][0] * v.y + m[2][0] * v.z + m[3][0] * v.w,
+            m[0][1] * v.x + m[1][1] * v.y + m[2][1] * v.z + m[3][1] * v.w,
+            m[0][2] * v.x + m[1][2] * v.y + m[2][2] * v.z + m[3][2] * v.w);
+    }
+
+    template <typename T> 
+    inline _xvec4<T> operator* (const _xvec3<T>& v, const _xmat4x3<T>& m) 
+    {
+        return _xvec4<T>(
+            v.x * m[0][0] + v.y * m[0][1] + v.z * m[0][2],
+            v.x * m[1][0] + v.y * m[1][1] + v.z * m[1][2],
+            v.x * m[2][0] + v.y * m[2][1] + v.z * m[2][2],
+            v.x * m[3][0] + v.y * m[3][1] + v.z * m[3][2]);
+    }
+
+    template <typename T> 
+    inline _xmat3<T> operator* (const _xmat4x3<T>& m1, const _xmat3x4<T>& m2)
+    {
+        const T SrcA00 = m1[0][0];
+        const T SrcA01 = m1[0][1];
+        const T SrcA02 = m1[0][2];
+        const T SrcA10 = m1[1][0];
+        const T SrcA11 = m1[1][1];
+        const T SrcA12 = m1[1][2];
+        const T SrcA20 = m1[2][0];
+        const T SrcA21 = m1[2][1];
+        const T SrcA22 = m1[2][2];
+        const T SrcA30 = m1[3][0];
+        const T SrcA31 = m1[3][1];
+        const T SrcA32 = m1[3][2];
+
+        const T SrcB00 = m2[0][0];
+        const T SrcB01 = m2[0][1];
+        const T SrcB02 = m2[0][2];
+        const T SrcB03 = m2[0][3];
+        const T SrcB10 = m2[1][0];
+        const T SrcB11 = m2[1][1];
+        const T SrcB12 = m2[1][2];
+        const T SrcB13 = m2[1][3];
+        const T SrcB20 = m2[2][0];
+        const T SrcB21 = m2[2][1];
+        const T SrcB22 = m2[2][2];
+        const T SrcB23 = m2[2][3];
+
+        _xmat3<T> Result;
+        Result[0][0] = SrcA00 * SrcB00 + SrcA10 * SrcB01 + SrcA20 * SrcB02 + SrcA30 * SrcB03;
+        Result[0][1] = SrcA01 * SrcB00 + SrcA11 * SrcB01 + SrcA21 * SrcB02 + SrcA31 * SrcB03;
+        Result[0][2] = SrcA02 * SrcB00 + SrcA12 * SrcB01 + SrcA22 * SrcB02 + SrcA32 * SrcB03;
+        Result[1][0] = SrcA00 * SrcB10 + SrcA10 * SrcB11 + SrcA20 * SrcB12 + SrcA30 * SrcB13;
+        Result[1][1] = SrcA01 * SrcB10 + SrcA11 * SrcB11 + SrcA21 * SrcB12 + SrcA31 * SrcB13;
+        Result[1][2] = SrcA02 * SrcB10 + SrcA12 * SrcB11 + SrcA22 * SrcB12 + SrcA32 * SrcB13;
+        Result[2][0] = SrcA00 * SrcB20 + SrcA10 * SrcB21 + SrcA20 * SrcB22 + SrcA30 * SrcB23;
+        Result[2][1] = SrcA01 * SrcB20 + SrcA11 * SrcB21 + SrcA21 * SrcB22 + SrcA31 * SrcB23;
+        Result[2][2] = SrcA02 * SrcB20 + SrcA12 * SrcB21 + SrcA22 * SrcB22 + SrcA32 * SrcB23;
+        return Result;
+    }
+
+    template <typename T> 
+    inline _xmat4x3<T> operator/ (const _xmat4x3<T>& m, const T s)
+    {
+        return _xmat4x3<T>(
+            m.value[0] / s,
+            m.value[1] / s,
+            m.value[2] / s,
+            m.value[3] / s);        
+    }
+
+    template <typename T> 
+    inline _xmat4x3<T> operator/ (const T s, const _xmat4x3<T>& m)
+    {
+        return _xmat4x3<T>(
+            s / m.value[0],
+            s / m.value[1],
+            s / m.value[2],
+            s / m.value[3]);        
+    }
+/* ToDo
+    template <typename T> 
+    _xvec3<T> operator/ (const _xmat4x3<T>& m, const _xvec4<T>& v)
+    {
+      
+    }
+
+    template <typename T> 
+    _xvec4<T> operator/ (const _xvec3<T>& v, const _xmat4x3<T>& m)
+    {
+      
+    }
+
+    template <typename T> 
+    inline _xmat4x3<T> operator/ (const _xmat4x3<T>& m1, const _xmat4x3<T>& m2)
+    {
+
+    }
+*/
+
+} //namespace detail
+} //namespace glm
+
+#endif //__mat4x3_inl__

+ 38 - 0
experimental/sse/glm/core/_xref2.h

@@ -0,0 +1,38 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2008 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2006-05-29
+// Updated : 2008-01-04
+// Licence : This source is under GNU LGPL licence
+// File    : _xref2.h
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef __xref2_h__
+#define __xref2_h__
+
+namespace glm{
+namespace detail{
+
+	template <typename T>
+	class _xref2
+	{
+	public:
+		_xref2(T& x, T& y);
+		_xref2<T>& operator= (const _xref2<T>& r);
+		_xref2<T>& operator+=(const _xref2<T>& r);
+		_xref2<T>& operator-=(const _xref2<T>& r);
+		_xref2<T>& operator*=(const _xref2<T>& r);
+		_xref2<T>& operator/=(const _xref2<T>& r);
+		_xref2<T>& operator= (const _xvec2<T>& v);
+		_xref2<T>& operator+=(const _xvec2<T>& v);
+		_xref2<T>& operator-=(const _xvec2<T>& v);
+		_xref2<T>& operator*=(const _xvec2<T>& v);
+		_xref2<T>& operator/=(const _xvec2<T>& v);
+		T& x;
+		T& y;
+	};
+
+} //namespace detail
+} //namespace glm
+
+#endif//__xref2_h__

+ 107 - 0
experimental/sse/glm/core/_xref2.inl

@@ -0,0 +1,107 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2008 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2006-05-29
+// Updated : 2006-05-29
+// Licence : This source is under GNU LGPL licence
+// File    : _xref2.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef __xref2_inl__
+#define __xref2_inl__
+
+#include "./_xref2.h"
+
+namespace glm{
+namespace detail{
+
+    template <typename T>
+    inline _xref2<T>::_xref2(T& x, T& y) :
+        x(x),
+        y(y)
+    {}
+
+    template <typename T>
+    inline _xref2<T>& _xref2<T>::operator=(const _xref2<T>& r)
+    {
+        x = r.x;
+        y = r.y;
+        return *this;
+    }
+
+    template <typename T>
+    inline _xref2<T>& _xref2<T>::operator+=(const _xref2<T>& r)
+    {
+        x += r.x;
+        y += r.y;
+        return *this;
+    }
+
+    template <typename T>
+	inline _xref2<T>& _xref2<T>::operator-=(const _xref2<T>& r)
+    {
+        x -= r.x;
+        y -= r.y;
+        return *this;
+    }
+
+    template <typename T>
+	inline _xref2<T>& _xref2<T>::operator*=(const _xref2<T>& r)
+    {
+        x *= r.x;
+        y *= r.y;
+        return *this;
+    }
+
+    template <typename T>
+	inline _xref2<T>& _xref2<T>::operator/=(const _xref2<T>& r)
+    {
+        x /= r.x;
+        y /= r.y;
+        return *this;
+    }
+
+    template <typename T>
+    inline _xref2<T>& _xref2<T>::operator=(const _xvec2<T>& v)
+    {
+        x = v.x;
+        y = v.y;
+        return *this;
+    }
+
+    template <typename T>
+    inline _xref2<T>& _xref2<T>::operator+=(const _xvec2<T>& v)
+    {
+        x += v.x;
+        y += v.y;
+        return *this;
+    }
+
+    template <typename T>
+	inline _xref2<T>& _xref2<T>::operator-=(const _xvec2<T>& v)
+    {
+        x -= v.x;
+        y -= v.y;
+        return *this;
+    }
+
+    template <typename T>
+	inline _xref2<T>& _xref2<T>::operator*=(const _xvec2<T>& v)
+    {
+        x *= v.x;
+        y *= v.y;
+        return *this;
+    }
+
+    template <typename T>
+	inline _xref2<T>& _xref2<T>::operator/=(const _xvec2<T>& v)
+    {
+        x /= v.x;
+        y /= v.y;
+        return *this;
+    }
+
+} //namespace detail
+} //namespace glm
+
+#endif//__xref2_inl__

+ 39 - 0
experimental/sse/glm/core/_xref3.h

@@ -0,0 +1,39 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2008 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2006-05-29
+// Updated : 2006-05-29
+// Licence : This source is under GNU LGPL licence
+// File    : _xref3.h
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef __xref3_h__
+#define __xref3_h__
+
+namespace glm{
+namespace detail{
+
+    template <typename T>
+    class _xref3
+    {
+	public:
+        _xref3(T& x, T& y, T& z);
+        _xref3<T>& operator= (const _xref3<T>& r);
+        _xref3<T>& operator+=(const _xref3<T>& r);
+	    _xref3<T>& operator-=(const _xref3<T>& r);
+	    _xref3<T>& operator*=(const _xref3<T>& r);
+	    _xref3<T>& operator/=(const _xref3<T>& r);
+        _xref3<T>& operator= (const _xvec3<T>& v);
+        _xref3<T>& operator+=(const _xvec3<T>& v);
+	    _xref3<T>& operator-=(const _xvec3<T>& v);
+	    _xref3<T>& operator*=(const _xvec3<T>& v);
+	    _xref3<T>& operator/=(const _xvec3<T>& v);
+        T& x;
+        T& y;
+        T& z;
+    };
+
+} //namespace detail
+} //namespace glm
+
+#endif//__xref3_h__

+ 118 - 0
experimental/sse/glm/core/_xref3.inl

@@ -0,0 +1,118 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2008 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2006-05-29
+// Updated : 2006-05-29
+// Licence : This source is under GNU LGPL licence
+// File    : _xref3.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef __xref3_inl__
+#define __xref3_inl__
+
+#include "./_xref3.h"
+
+namespace glm{
+namespace detail{
+
+    template <typename T>
+    inline _xref3<T>::_xref3(T& x, T& y, T& z) :
+        x(x),
+        y(y),
+        z(z)
+    {}
+
+    template <typename T>
+    inline _xref3<T>& _xref3<T>::operator=(const _xref3<T>& r)
+    {
+        x = r.x;
+        y = r.y;
+        z = r.z;
+        return *this;
+    }
+
+    template <typename T>
+    inline _xref3<T>& _xref3<T>::operator+=(const _xref3<T>& r)
+    {
+        x += r.x;
+        y += r.y;
+        z += r.z;
+        return *this;
+    }
+
+    template <typename T>
+	inline _xref3<T>& _xref3<T>::operator-=(const _xref3<T>& r)
+    {
+        x -= r.x;
+        y -= r.y;
+        z -= r.z;
+        return *this;
+    }
+
+    template <typename T>
+	inline _xref3<T>& _xref3<T>::operator*=(const _xref3<T>& r)
+    {
+        x *= r.x;
+        y *= r.y;
+        z *= r.z;
+        return *this;
+    }
+
+    template <typename T>
+	inline _xref3<T>& _xref3<T>::operator/=(const _xref3<T>& r)
+    {
+        x /= r.x;
+        y /= r.y;
+        z /= r.z;
+        return *this;
+    }
+
+    template <typename T>
+    inline _xref3<T>& _xref3<T>::operator=(const _xvec3<T>& v)
+    {
+        x = v.x;
+        y = v.y;
+        z = v.z;
+        return *this;
+    }
+
+    template <typename T>
+    inline _xref3<T>& _xref3<T>::operator+=(const _xvec3<T>& v)
+    {
+        x += v.x;
+        y += v.y;
+        z += v.z;
+        return *this;
+    }
+
+    template <typename T>
+	inline _xref3<T>& _xref3<T>::operator-=(const _xvec3<T>& v)
+    {
+        x -= v.x;
+        y -= v.y;
+        z -= v.z;
+        return *this;
+    }
+
+    template <typename T>
+	inline _xref3<T>& _xref3<T>::operator*=(const _xvec3<T>& v)
+    {
+        x *= v.x;
+        y *= v.y;
+        z *= v.z;
+        return *this;
+    }
+
+    template <typename T>
+	inline _xref3<T>& _xref3<T>::operator/=(const _xvec3<T>& v)
+    {
+        x /= v.x;
+        y /= v.y;
+        z /= v.z;
+        return *this;
+    }
+
+} //namespace detail
+} //namespace glm
+
+#endif//__xref3_inl__

+ 40 - 0
experimental/sse/glm/core/_xref4.h

@@ -0,0 +1,40 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2008 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2006-05-29
+// Updated : 2006-05-29
+// Licence : This source is under GNU LGPL licence
+// File    : _xref4.h
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef __xref4_h__
+#define __xref4_h__
+
+namespace glm{
+namespace detail{
+
+    template <typename T>
+    class _xref4
+    {
+	public:
+        _xref4(T& x, T& y, T& z, T& w);
+        _xref4<T>& operator= (const _xref4<T>& r);
+        _xref4<T>& operator+=(const _xref4<T>& r);
+	    _xref4<T>& operator-=(const _xref4<T>& r);
+	    _xref4<T>& operator*=(const _xref4<T>& r);
+	    _xref4<T>& operator/=(const _xref4<T>& r);
+        _xref4<T>& operator= (const _xvec4<T>& v);
+        _xref4<T>& operator+=(const _xvec4<T>& v);
+	    _xref4<T>& operator-=(const _xvec4<T>& v);
+	    _xref4<T>& operator*=(const _xvec4<T>& v);
+	    _xref4<T>& operator/=(const _xvec4<T>& v);
+        T& x;
+        T& y;
+        T& z;
+        T& w;
+    };
+
+} //namespace detail
+} //namespace glm
+
+#endif//__xref4_h__

+ 129 - 0
experimental/sse/glm/core/_xref4.inl

@@ -0,0 +1,129 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2008 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2006-05-29
+// Updated : 2006-05-29
+// Licence : This source is under GNU LGPL licence
+// File    : _xref4.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef __xref4_inl__
+#define __xref4_inl__
+
+#include "./_xref4.h"
+
+namespace glm{
+namespace detail{
+
+    template <typename T>
+    inline _xref4<T>::_xref4(T& x, T& y, T& z, T& w) :
+        x(x),
+        y(y),
+        z(z),
+        w(w)
+    {}
+
+    template <typename T>
+    inline _xref4<T>& _xref4<T>::operator=(const _xref4<T>& r)
+    {
+        x = r.x;
+        y = r.y;
+        z = r.z;
+        w = r.w;
+        return *this;
+    }
+
+    template <typename T>
+    inline _xref4<T>& _xref4<T>::operator+=(const _xref4<T>& r)
+    {
+        x += r.x;
+        y += r.y;
+        z += r.z;
+        w += r.w;
+        return *this;
+    }
+
+    template <typename T>
+	inline _xref4<T>& _xref4<T>::operator-=(const _xref4<T>& r)
+    {
+        x -= r.x;
+        y -= r.y;
+        z -= r.z;
+        w -= r.w;
+        return *this;
+    }
+
+    template <typename T>
+	inline _xref4<T>& _xref4<T>::operator*=(const _xref4<T>& r)
+    {
+        x *= r.x;
+        y *= r.y;
+        z *= r.z;
+        w *= r.w;
+        return *this;
+    }
+
+    template <typename T>
+	inline _xref4<T>& _xref4<T>::operator/=(const _xref4<T>& r)
+    {
+        x /= r.x;
+        y /= r.y;
+        z /= r.z;
+        w /= r.w;
+        return *this;
+    }
+
+    template <typename T>
+    _xref4<T>& _xref4<T>::operator=(const _xvec4<T>& v)
+    {
+        x = v.x;
+        y = v.y;
+        z = v.z;
+        w = v.w;
+        return *this;
+    }
+
+    template <typename T>
+    inline _xref4<T>& _xref4<T>::operator+=(const _xvec4<T>& v)
+    {
+        x += v.x;
+        y += v.y;
+        z += v.z;
+        w += v.w;
+        return *this;
+    }
+
+    template <typename T>
+	inline _xref4<T>& _xref4<T>::operator-=(const _xvec4<T>& v)
+    {
+        x -= v.x;
+        y -= v.y;
+        z -= v.z;
+        w -= v.w;
+        return *this;
+    }
+
+    template <typename T>
+	inline _xref4<T>& _xref4<T>::operator*=(const _xvec4<T>& v)
+    {
+        x *= v.x;
+        y *= v.y;
+        z *= v.z;
+        w *= v.w;
+        return *this;
+    }
+
+    template <typename T>
+	inline _xref4<T>& _xref4<T>::operator/=(const _xvec4<T>& v)
+    {
+        x /= v.x;
+        y /= v.y;
+        z /= v.z;
+        w /= v.w;
+        return *this;
+    }
+
+} //namespace detail
+} //namespace glm
+
+#endif//__xref4_inl__

+ 260 - 0
experimental/sse/glm/core/_xvec2.h

@@ -0,0 +1,260 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2008 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2006-04-27
+// Updated : 2007-01-15
+// Licence : This source is under GNU LGPL licence
+// File    : _xvec2.h
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef __xvec2_h__
+#define __xvec2_h__
+
+#include "./_cvec2.inl"
+
+namespace glm{
+namespace detail{
+
+    template <typename T> 
+	class _xvec2 : public _xvec2_base(T)
+    {
+	public:
+        // Common constructors
+	    _xvec2();
+        _xvec2(const _xvec2<T>& v);
+
+        // Swizzle constructors
+        _xvec2(const _xref2<T>& r);
+		_xvec2(const _xvec2_base(T)& b);
+
+        // T constructors
+        explicit _xvec2(const T x);
+        explicit _xvec2(const T a, const T b);
+        explicit _xvec2(const T a, const _xvec2<T>& b);
+        explicit _xvec2(const T a, const _xvec3<T>& b);
+        explicit _xvec2(const T a, const _xvec4<T>& b);
+        explicit _xvec2(const _xvec3<T>& a);
+        explicit _xvec2(const _xvec4<T>& a);
+
+        // U constructors
+        template <typename U> explicit _xvec2(const U x);
+        template <typename U> explicit _xvec2(const U a, const U b);
+        template <typename U> explicit _xvec2(const U a, const _xvec2<U>& b);
+        template <typename U> explicit _xvec2(const U a, const _xvec3<U>& b);
+        template <typename U> explicit _xvec2(const U a, const _xvec4<U>& b);
+        template <typename U> explicit _xvec2(const _xvec2<U>& a);
+        template <typename U> explicit _xvec2(const _xvec3<U>& a);
+        template <typename U> explicit _xvec2(const _xvec4<U>& a);
+
+        // Bool constructors
+        explicit _xvec2(const bool x);
+        explicit _xvec2(const bool a, const bool b);
+        explicit _xvec2(const bool a, const _bvec2& b);
+        explicit _xvec2(const bool a, const _bvec3& b);
+        explicit _xvec2(const bool a, const _bvec4& b);
+        explicit _xvec2(const _bvec2& a);
+        explicit _xvec2(const _bvec3& a);
+        explicit _xvec2(const _bvec4& a);
+
+        // Unary updatable operators
+        _xvec2<T>& operator= (const _xvec2<T>& v);
+	    _xvec2<T>& operator+=(const T s);
+	    _xvec2<T>& operator+=(const _xvec2<T>& v);
+	    _xvec2<T>& operator-=(const T s);
+	    _xvec2<T>& operator-=(const _xvec2<T>& v);
+	    _xvec2<T>& operator*=(const T s);
+	    _xvec2<T>& operator*=(const _xvec2<T>& v);
+	    _xvec2<T>& operator/=(const T s);
+	    _xvec2<T>& operator/=(const _xvec2<T>& v);
+        _xvec2<T>& operator++();
+	    _xvec2<T>& operator--();
+/*
+		// Bit operators
+	    _xvec2<T>& operator%=(const T s);
+	    _xvec2<T>& operator%=(const _xvec2<T>& v);
+		_xvec2<T>& operator&=(const T s);
+	    _xvec2<T>& operator&=(const _xvec2<T>& v);
+	    _xvec2<T>& operator|=(const T s);
+	    _xvec2<T>& operator|=(const _xvec2<T>& v);
+	    _xvec2<T>& operator^=(const T s);
+	    _xvec2<T>& operator^=(const _xvec2<T>& v);
+	    _xvec2<T>& operator<<=(const T s);
+	    _xvec2<T>& operator<<=(const _xvec2<T>& v);
+	    _xvec2<T>& operator>>=(const T s);
+	    _xvec2<T>& operator>>=(const _xvec2<T>& v);
+*/
+    };
+/*
+	// Bit operators
+    template <typename T>
+	_xvec2<T> operator% (const _xvec2<T>& v, const T s);
+
+    template <typename T>
+    _xvec2<T> operator% (const T s, const _xvec2<T>& v);
+
+    template <typename T>
+    _xvec2<T> operator% (const _xvec2<T>& v1, const _xvec2<T>& v2);
+
+    template <typename T>
+	_xvec2<T> operator& (const _xvec2<T>& v, const T s);
+
+    template <typename T>
+    _xvec2<T> operator& (const T s, const _xvec2<T>& v);
+
+    template <typename T>
+    _xvec2<T> operator& (const _xvec2<T>& v1, const _xvec2<T>& v2);
+
+    template <typename T>
+	_xvec2<T> operator| (const _xvec2<T>& v, const T s);
+
+    template <typename T>
+    _xvec2<T> operator| (const T s, const _xvec2<T>& v);
+
+    template <typename T>
+    _xvec2<T> operator| (const _xvec2<T>& v1, const _xvec2<T>& v2);
+
+    template <typename T>
+	_xvec2<T> operator^ (const _xvec2<T>& v, const T s);
+
+    template <typename T>
+    _xvec2<T> operator^ (const T s, const _xvec2<T>& v);
+
+    template <typename T>
+    _xvec2<T> operator^ (const _xvec2<T>& v1, const _xvec2<T>& v2);
+
+    template <typename T>
+	_xvec2<T> operator<< (const _xvec2<T>& v, const T s);
+
+    template <typename T>
+    _xvec2<T> operator<< (const T s, const _xvec2<T>& v);
+
+    template <typename T>
+    _xvec2<T> operator<< (const _xvec2<T>& v1, const _xvec2<T>& v2);
+
+	template <typename T>
+	_xvec2<T> operator>> (const _xvec2<T>& v, const T s);
+
+    template <typename T>
+    _xvec2<T> operator>> (const T s, const _xvec2<T>& v);
+
+    template <typename T>
+    _xvec2<T> operator>> (const _xvec2<T>& v1, const _xvec2<T>& v2);
+
+    template <typename T> 
+    const _xvec2<T> operator~ (const _xvec2<T>& v);
+*/
+    // Binary operators
+	// operator+
+    template <typename T>
+	_xvec2<T> operator+ (const _xvec2<T>& v, const T s);
+
+    template <typename T>
+    _xvec2<T> operator+ (const T s, const _xvec2<T>& v);
+
+    template <typename T>
+    _xvec2<T> operator+ (const _xvec2<T>& v1, const _xvec2<T>& v2);
+    
+    template <typename T>
+	_xvec2<T> operator+ (const _xref2<T>& v, const T s);
+
+    template <typename T>
+    _xvec2<T> operator+ (const T s, const _xref2<T>& v);
+    
+	template <typename T>
+    _xvec2<T> operator+ (const _xref2<T>& v1, const _xref2<T>& v2);
+
+	template <typename T>
+    _xvec2<T> operator+ (const _xvec2<T>& v1, const _xref2<T>& v2);
+
+	template <typename T>
+    _xvec2<T> operator+ (const _xref2<T>& v1, const _xvec2<T>& v2);
+
+	// operator-
+    template <typename T>
+	_xvec2<T> operator- (const _xvec2<T>& v, const T s);
+
+    template <typename T>
+    _xvec2<T> operator- (const T s, const _xvec2<T>& v);
+
+    template <typename T>
+    _xvec2<T> operator- (const _xvec2<T>& v1, const _xvec2<T>& v2);
+
+    template <typename T>
+	_xvec2<T> operator- (const _xref2<T>& v, const T s);
+
+    template <typename T>
+    _xvec2<T> operator- (const T s, const _xref2<T>& v);
+    
+	template <typename T>
+    _xvec2<T> operator- (const _xref2<T>& v1, const _xref2<T>& v2);
+
+	template <typename T>
+    _xvec2<T> operator- (const _xvec2<T>& v1, const _xref2<T>& v2);
+
+	template <typename T>
+    _xvec2<T> operator- (const _xref2<T>& v1, const _xvec2<T>& v2);
+
+	// operator*
+    template <typename T>
+    _xvec2<T> operator* (const _xvec2<T>& v, const T s);
+
+    template <typename T>
+    _xvec2<T> operator* (const T s, const _xvec2<T>& v);
+
+    template <typename T>
+    _xvec2<T> operator* (const _xvec2<T>& v1, const _xvec2<T>& v2);
+
+    template <typename T>
+	_xvec2<T> operator* (const _xref2<T>& v, const T s);
+
+    template <typename T>
+    _xvec2<T> operator* (const T s, const _xref2<T>& v);
+    
+	template <typename T>
+    _xvec2<T> operator* (const _xref2<T>& v1, const _xref2<T>& v2);
+
+	template <typename T>
+    _xvec2<T> operator* (const _xvec2<T>& v1, const _xref2<T>& v2);
+
+	template <typename T>
+    _xvec2<T> operator* (const _xref2<T>& v1, const _xvec2<T>& v2);
+
+	// operator/
+    template <typename T>
+    _xvec2<T> operator/ (const _xvec2<T>& v, const T s);
+
+    template <typename T>
+    _xvec2<T> operator/ (const T s, const _xvec2<T>& v);
+
+    template <typename T>
+    _xvec2<T> operator/ (const _xvec2<T>& v1, const _xvec2<T>& v2);
+
+    template <typename T>
+	_xvec2<T> operator/ (const _xref2<T>& v, const T s);
+
+    template <typename T>
+    _xvec2<T> operator/ (const T s, const _xref2<T>& v);
+    
+	template <typename T>
+    _xvec2<T> operator/ (const _xref2<T>& v1, const _xref2<T>& v2);
+
+	template <typename T>
+    _xvec2<T> operator/ (const _xvec2<T>& v1, const _xref2<T>& v2);
+
+	template <typename T>
+    _xvec2<T> operator/ (const _xref2<T>& v1, const _xvec2<T>& v2);
+
+    // Unary constant operators
+    template <typename T> 
+    const _xvec2<T> operator- (const _xvec2<T>& v);
+
+    template <typename T> 
+    const _xvec2<T> operator--(const _xvec2<T>& v, int);
+
+    template <typename T> 
+    const _xvec2<T> operator++(const _xvec2<T>& v, int);
+
+} //namespace detail
+} //namespace glm
+
+#endif //__xvec2_h__

+ 802 - 0
experimental/sse/glm/core/_xvec2.inl

@@ -0,0 +1,802 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2008 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2006-04-27
+// Updated : 2007-01-19
+// Licence : This source is under GNU LGPL licence
+// File    : _xvec2.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef __xvec2_inl__
+#define __xvec2_inl__
+
+#include "./_cvec2.h"
+#include "./_xvec2.h"
+#include "./_bvec2.h"
+#include "./_xvec3.h"
+#include "./_bvec3.h"
+#include "./_xvec4.h"
+#include "./_bvec4.h"
+#include "./_swizzle.inl"
+
+namespace glm{
+namespace detail{
+
+    // Common constructors
+    template <typename T> 
+    inline _xvec2<T>::_xvec2() : 
+        _cvec2<XVEC2_INST>(T(0), T(0))
+    {}
+
+    template <typename T> 
+    inline _xvec2<T>::_xvec2(const _xvec2<T>& v) :
+        _cvec2<XVEC2_INST>(v.x, v.y)
+    {}
+
+    // Swizzle conclassor
+    template <typename T> 
+    inline _xvec2<T>::_xvec2(const _xref2<T>& r) :
+        _cvec2<XVEC2_INST>(r.x, r.y)
+    {}
+
+    template <typename T> 
+    inline _xvec2<T>::_xvec2(const _xvec2_base(T)& b) :
+		_cvec2<XVEC2_INST>(b.x, b.y)
+    {}
+
+    // T constructors
+    template <typename T> 
+    inline _xvec2<T>::_xvec2(const T x) :
+        _cvec2<XVEC2_INST>(x, x)
+    {}
+
+    template <typename T> 
+    inline _xvec2<T>::_xvec2(const T a, const T b) :
+        _cvec2<XVEC2_INST>(a, b)
+    {}
+
+    template <typename T> 
+    inline _xvec2<T>::_xvec2(const T a, const _xvec2<T>& b) :
+        _cvec2<XVEC2_INST>(a, b.x)
+    {}
+
+    template <typename T> 
+    inline _xvec2<T>::_xvec2(const T a, const _xvec3<T>& b) :
+        _cvec2<XVEC2_INST>(a, b.x)
+    {}
+
+    template <typename T> 
+    inline _xvec2<T>::_xvec2(const T a, const _xvec4<T>& b) :
+        _cvec2<XVEC2_INST>(a, b.x)
+    {}
+
+    template <typename T> 
+    inline _xvec2<T>::_xvec2(const _xvec3<T>& a) :
+        _cvec2<XVEC2_INST>(a.x, a.y)
+    {}
+
+    template <typename T> 
+    inline _xvec2<T>::_xvec2(const _xvec4<T>& a) :
+        _cvec2<XVEC2_INST>(a.x, a.y)
+    {}
+
+    // U constructors
+    template <typename T> 
+    template <typename U> 
+    inline _xvec2<T>::_xvec2(const U x) :
+        _cvec2<XVEC2_INST>(T(x), T(x))
+    {}
+
+    template <typename T> 
+    template <typename U> 
+    inline _xvec2<T>::_xvec2(const U a, const U b) :
+        _cvec2<XVEC2_INST>(T(a), T(b))
+    {}
+
+    template <typename T> 
+    template <typename U> 
+    inline _xvec2<T>::_xvec2(const U a, const _xvec2<U>& b) :
+		_cvec2<XVEC2_INST>(T(a), T(b.x))
+    {}
+
+    template <typename T> 
+    template <typename U> 
+    inline _xvec2<T>::_xvec2(const U a, const _xvec3<U>& b) :
+		_cvec2<XVEC2_INST>(T(a), T(b.x))
+    {}
+
+    template <typename T> 
+    template <typename U> 
+    inline _xvec2<T>::_xvec2(const U a, const _xvec4<U>& b) :
+		_cvec2<XVEC2_INST>(T(a), T(b.x))
+    {}
+
+    template <typename T> 
+    template <typename U> 
+    inline _xvec2<T>::_xvec2(const _xvec2<U>& a) :
+        _cvec2<XVEC2_INST>(T(a.x), T(a.y))
+    {}
+
+    template <typename T> 
+    template <typename U> 
+    inline _xvec2<T>::_xvec2(const _xvec3<U>& a) :
+        _cvec2<XVEC2_INST>(T(a.x), T(a.y))
+    {}
+
+    template <typename T> 
+    template <typename U> 
+    inline _xvec2<T>::_xvec2(const _xvec4<U>& a) :
+        _cvec2<XVEC2_INST>(T(a.x), T(a.y))
+    {}
+
+    // Bool constructors
+    template <typename T> 
+    inline _xvec2<T>::_xvec2(const bool x) :
+        _cvec2<XVEC2_INST>(T(x), T(x))
+    {}
+
+    template <typename T> 
+    inline _xvec2<T>::_xvec2(const bool a, const bool b) :
+        _cvec2<XVEC2_INST>(T(a), T(b))
+    {}
+
+    template <typename T> 
+    inline _xvec2<T>::_xvec2(const bool a, const _bvec2& b) :
+        _cvec2<XVEC2_INST>(T(a), T(b.x))
+    {}
+
+    template <typename T> 
+    inline _xvec2<T>::_xvec2(const bool a, const _bvec3& b) :
+        _cvec2<XVEC2_INST>(T(a), T(b.x))
+    {}
+
+    template <typename T> 
+    inline _xvec2<T>::_xvec2(const bool a, const _bvec4& b) :
+        _cvec2<XVEC2_INST>(T(a), T(b.x))
+    {}
+
+    template <typename T> 
+    inline _xvec2<T>::_xvec2(const _bvec3& a) :
+        _cvec2<XVEC2_INST>(T(a.x), T(a.y))
+    {}
+
+    template <typename T> 
+    inline _xvec2<T>::_xvec2(const _bvec4& a) :
+        _cvec2<XVEC2_INST>(T(a.x), T(a.y))
+    {}
+
+    template <typename T> 
+    inline _xvec2<T>::_xvec2(const _bvec2& a) :
+        _cvec2<XVEC2_INST>(T(a.x), T(a.y))
+    {}
+
+    //////////////////////////////////////////////////////////////
+    // vec2 and ivec2 operators
+
+    template <typename T> 
+    inline _xvec2<T>& _xvec2<T>::operator=(const _xvec2<T>& v)
+    {
+        this->x = v.x;
+        this->y = v.y;
+        return *this;
+    }
+
+    template <typename T> 
+    inline _xvec2<T>& _xvec2<T>::operator+= (const T s)
+    {
+	    this->x += s;
+	    this->y += s;
+	    return *this;
+    }
+
+    template <typename T> 
+    inline _xvec2<T>& _xvec2<T>::operator+= (const _xvec2<T>& v)
+    {
+	    this->x += v.x;
+	    this->y += v.y;
+	    return *this;
+    }
+
+    template <typename T> 
+    inline _xvec2<T>& _xvec2<T>::operator-= (const T s)
+    {
+	    this->x -= s;
+	    this->y -= s;
+	    return *this;
+    }
+
+    template <typename T> 
+    inline _xvec2<T>& _xvec2<T>::operator-= (const _xvec2<T>& v)
+    {
+	    this->x -= v.x;
+	    this->y -= v.y;
+	    return *this;
+    }
+
+    template <typename T> 
+    inline _xvec2<T>& _xvec2<T>::operator*= (const T s)
+    {
+	    this->x *= s;
+	    this->y *= s;
+	    return *this;
+    }
+
+    template <typename T> 
+    inline _xvec2<T>& _xvec2<T>::operator*= (const _xvec2<T>& v)
+    {
+	    this->x *= v.x;
+	    this->y *= v.y;
+	    return *this;
+    }
+
+    template <typename T> 
+    inline _xvec2<T>& _xvec2<T>::operator/= (const T s)
+    {
+	    this->x /= s;
+	    this->y /= s;
+	    return *this;
+    }
+
+    template <typename T> 
+    inline _xvec2<T>& _xvec2<T>::operator/= (const _xvec2<T>& v)
+    {
+	    this->x /= v.x;
+	    this->y /= v.y;
+	    return *this;
+    }
+
+    template <typename T> 
+    inline _xvec2<T>& _xvec2<T>::operator++ ()
+    {
+	    ++this->x;
+	    ++this->y;
+	    return *this;
+    }
+
+    template <typename T> 
+    inline _xvec2<T>& _xvec2<T>::operator-- ()
+    {
+	    --this->x;
+	    --this->y;
+	    return *this;
+    }
+/*
+	template <typename T> 
+    inline _xvec2<T>& operator%=(const T s)
+	{
+	    this->x %= s;
+	    this->y %= s;
+	    return *this;
+	}
+
+	template <typename T> 
+    inline _xvec2<T>& operator%=(const _xvec2<T>& v)
+	{
+	    this->x %= v.x;
+	    this->y %= v.y;
+	    return *this;
+	}
+
+	template <typename T> 
+	inline _xvec2<T>& operator&=(const T s)
+	{
+	    this->x &= s;
+	    this->y &= s;
+	    return *this;
+	}
+
+    template <typename T> 
+	inline _xvec2<T>& operator&=(const _xvec2<T>& v)
+	{
+	    this->x &= v.x;
+	    this->y &= v.y;
+	    return *this;
+	}
+    
+    template <typename T> 
+	inline _xvec2<T>& operator|=(const T s)
+	{
+	    this->x |= s;
+	    this->y |= s;
+	    return *this;
+	}
+    
+    template <typename T> 
+	inline _xvec2<T>& operator|=(const _xvec2<T>& v)
+	{
+	    this->x |= v.x;
+	    this->y |= v.y;
+	    return *this;
+	}
+    
+    template <typename T> 
+	inline _xvec2<T>& operator^=(const T s)
+	{
+	    this->x ^= s;
+	    this->y ^= s;
+	    return *this;
+	}
+    
+    template <typename T> 
+	inline _xvec2<T>& operator^=(const _xvec2<T>& v)
+	{
+	    this->x ^= v.x;
+	    this->y ^= v.y;
+	    return *this;
+	}
+    
+    template <typename T> 
+	inline _xvec2<T>& operator<<=(const T s)
+	{
+	    this->x <<= s;
+	    this->y <<= s;
+	    return *this;
+	}
+    
+    template <typename T> 
+	inline _xvec2<T>& operator<<=(const _xvec2<T>& v)
+	{
+	    this->x <<= v.x;
+	    this->y <<= v.y;
+	    return *this;
+	}
+    
+    template <typename T> 
+	inline _xvec2<T>& operator>>=(const T s)
+	{
+	    this->x >>= s;
+	    this->y >>= s;
+	    return *this;
+	}
+    
+    template <typename T> 
+	inline _xvec2<T>& operator>>=(const _xvec2<T>& v)
+	{
+	    this->x >>= v.x;
+	    this->y >>= v.y;
+	    return *this;
+	}
+
+	// Bit operators
+    template <typename T>
+	inline _xvec2<T> operator% (const _xvec2<T>& v, const T s)
+	{
+	    return _xvec2<T>(
+		    v.x % s,
+		    v.y % s);
+	}
+
+    template <typename T>
+    inline _xvec2<T> operator% (const T s, const _xvec2<T>& v)
+	{
+	    return _xvec2<T>(
+		    s % v.x,
+		    s % v.y);
+	}
+
+    template <typename T>
+    inline _xvec2<T> operator% (const _xvec2<T>& v1, const _xvec2<T>& v2)
+	{
+	    return _xvec2<T>(
+		    v1.x % v2.x,
+		    v1.y % v2.y);
+	}
+
+    template <typename T>
+	inline _xvec2<T> operator& (const _xvec2<T>& v, const T s)
+	{
+	    return _xvec2<T>(
+		    v.x & s,
+		    v.y & s);
+	}
+
+    template <typename T>
+    inline _xvec2<T> operator& (const T s, const _xvec2<T>& v)
+	{
+	    return _xvec2<T>(
+		    s & v.x,
+		    s & v.y);
+	}
+
+    template <typename T>
+    inline _xvec2<T> operator& (const _xvec2<T>& v1, const _xvec2<T>& v2)
+	{
+	    return _xvec2<T>(
+		    v1.x & v2.x,
+		    v1.y & v2.y);
+	}
+
+    template <typename T>
+	inline _xvec2<T> operator| (const _xvec2<T>& v, const T s)
+	{
+	    return _xvec2<T>(
+		    v.x | s,
+		    v.y | s);
+	}
+
+    template <typename T>
+    inline _xvec2<T> operator| (const T s, const _xvec2<T>& v)
+	{
+	    return _xvec2<T>(
+		    s | v.x,
+		    s | v.y);
+	}
+
+    template <typename T>
+    inline _xvec2<T> operator| (const _xvec2<T>& v1, const _xvec2<T>& v2)
+	{
+	    return _xvec2<T>(
+		    v1.x | v2.x,
+		    v1.y | v2.y);
+	}
+	
+    template <typename T>
+	inline _xvec2<T> operator^ (const _xvec2<T>& v, const T s)
+	{
+	    return _xvec2<T>(
+		    v.x ^ s,
+		    v.y ^ s);
+	}
+
+    template <typename T>
+    inline _xvec2<T> operator^ (const T s, const _xvec2<T>& v)
+	{
+	    return _xvec2<T>(
+		    s ^ v.x,
+		    s ^ v.y);
+	}
+
+    template <typename T>
+    inline _xvec2<T> operator^ (const _xvec2<T>& v1, const _xvec2<T>& v2)
+	{
+	    return _xvec2<T>(
+		    v1.x ^ v2.x,
+		    v1.y ^ v2.y);
+	}
+
+    template <typename T>
+	inline _xvec2<T> operator<< (const _xvec2<T>& v, const T s)
+	{
+	    return _xvec2<T>(
+		    v.x << s,
+		    v.y << s);
+	}
+
+    template <typename T>
+    inline _xvec2<T> operator<< (const T s, const _xvec2<T>& v)
+	{
+	    return _xvec2<T>(
+		    s << v.x,
+		    s << v.y);
+	}
+
+    template <typename T>
+    inline _xvec2<T> operator<< (const _xvec2<T>& v1, const _xvec2<T>& v2)
+	{
+	    return _xvec2<T>(
+		    v1.x << v2.x,
+		    v1.y << v2.y);
+	}
+
+	template <typename T>
+	inline _xvec2<T> operator>> (const _xvec2<T>& v, const T s)
+	{
+	    return _xvec2<T>(
+		    v.x >> s,
+		    v.y >> s);
+	}
+
+    template <typename T>
+    inline _xvec2<T> operator>> (const T s, const _xvec2<T>& v)
+	{
+	    return _xvec2<T>(
+		    s >> v.x,
+		    s >> v.y);
+	}
+
+    template <typename T>
+    inline _xvec2<T> operator>> (const _xvec2<T>& v1, const _xvec2<T>& v2)
+	{
+	    return _xvec2<T>(
+		    v1.x >> v2.x,
+		    v1.y >> v2.y);
+	}
+
+    template <typename T> 
+    inline const _xvec2<T> operator~ (const _xvec2<T>& v)
+	{
+	    return _xvec2<T>(
+		    ~v.x,
+		    ~v.y);
+	}
+*/
+    // Binary operators
+	//operator+
+    template <typename T> 
+    inline _xvec2<T> operator+ (const _xvec2<T>& v, const T s)
+    {
+	    return _xvec2<T>(
+		    v.x + s,
+		    v.y + s);
+    }
+
+    template <typename T> 
+    inline _xvec2<T> operator+ (const T s, const _xvec2<T>& v)
+    {
+	    return _xvec2<T>(
+		    s + v.x,
+		    s + v.y);
+    }
+
+    template <typename T> 
+    inline _xvec2<T> operator+ (const _xvec2<T>& v1, const _xvec2<T>& v2)
+    {
+	    return _xvec2<T>(
+		    v1.x + v2.x,
+		    v1.y + v2.y);
+    }
+
+    template <typename T>
+	inline _xvec2<T> operator+ (const _xref2<T>& v, const T s)
+	{
+	    return _xvec2<T>(
+		    v.x + s,
+		    v.y + s);
+	}
+
+    template <typename T>
+    inline _xvec2<T> operator+ (const T s, const _xref2<T>& v)
+	{
+	    return _xvec2<T>(
+		    s + v.x,
+		    s + v.y);
+	}
+    
+	template <typename T>
+    inline _xvec2<T> operator+ (const _xref2<T>& v1, const _xref2<T>& v2)
+	{
+	    return _xvec2<T>(
+		    v1.x + v2.x,
+		    v1.y + v2.y);
+	}
+
+	template <typename T>
+    inline _xvec2<T> operator+ (const _xvec2<T>& v1, const _xref2<T>& v2)
+	{
+	    return _xvec2<T>(
+		    v1.x + v2.x,
+		    v1.y + v2.y);
+	}
+
+	template <typename T>
+    inline _xvec2<T> operator+ (const _xref2<T>& v1, const _xvec2<T>& v2)
+	{
+	    return _xvec2<T>(
+		    v1.x + v2.x,
+		    v1.y + v2.y);
+	}
+
+	//operator-
+    template <typename T> 
+    inline _xvec2<T> operator- (const _xvec2<T>& v, const T s)
+    {
+	    return _xvec2<T>(
+		    v.x - s,
+		    v.y - s);
+    }
+
+    template <typename T> 
+    inline _xvec2<T> operator- (const T s, const _xvec2<T>& v)
+    {
+	    return _xvec2<T>(
+		    s - v.x,
+		    s - v.y);
+    }
+
+    template <typename T> 
+    inline _xvec2<T> operator- (const _xvec2<T>& v1, const _xvec2<T>& v2)
+    {
+	    return _xvec2<T>(
+		    v1.x - v2.x,
+		    v1.y - v2.y);
+    }
+
+    template <typename T>
+	inline _xvec2<T> operator- (const _xref2<T>& v, const T s)
+	{
+	    return _xvec2<T>(
+		    v.x - s,
+		    v.y - s);
+	}
+
+    template <typename T>
+    inline _xvec2<T> operator- (const T s, const _xref2<T>& v)
+	{
+	    return _xvec2<T>(
+		    s - v.x,
+		    s - v.y);
+	}
+    
+	template <typename T>
+    inline _xvec2<T> operator- (const _xref2<T>& v1, const _xref2<T>& v2)
+	{
+	    return _xvec2<T>(
+		    v1.x - v2.x,
+		    v1.y - v2.y);
+	}
+
+	template <typename T>
+    inline _xvec2<T> operator- (const _xvec2<T>& v1, const _xref2<T>& v2)
+	{
+	    return _xvec2<T>(
+		    v1.x - v2.x,
+		    v1.y - v2.y);
+	}
+
+	template <typename T>
+    inline _xvec2<T> operator- (const _xref2<T>& v1, const _xvec2<T>& v2)
+	{
+	    return _xvec2<T>(
+		    v1.x - v2.x,
+		    v1.y - v2.y);
+	}
+
+	//operator*
+    template <typename T> 
+    inline _xvec2<T> operator* (const _xvec2<T>& v, const T s)
+    {
+	    return _xvec2<T>(
+		    v.x * s,
+		    v.y * s);
+    }
+
+    template <typename T> 
+    inline _xvec2<T> operator* (const T s, const _xvec2<T>& v)
+    {
+	    return _xvec2<T>(
+		    s * v.x,
+		    s * v.y);
+    }
+
+    template <typename T> 
+    inline _xvec2<T> operator* (const _xvec2<T>& v1, const _xvec2<T> & v2)
+    {
+	    return _xvec2<T>(
+		    v1.x * v2.x,
+		    v1.y * v2.y);
+    }
+
+    template <typename T>
+	inline _xvec2<T> operator* (const _xref2<T>& v, const T s)
+	{
+	    return _xvec2<T>(
+		    v.x * s,
+		    v.y * s);
+	}
+
+    template <typename T>
+    inline _xvec2<T> operator* (const T s, const _xref2<T>& v)
+	{
+	    return _xvec2<T>(
+		    s * v.x,
+		    s * v.y);
+	}
+    
+	template <typename T>
+    inline _xvec2<T> operator* (const _xref2<T>& v1, const _xref2<T>& v2)
+	{
+	    return _xvec2<T>(
+		    v1.x * v2.x,
+		    v1.y * v2.y);
+	}
+
+	template <typename T>
+    inline _xvec2<T> operator* (const _xvec2<T>& v1, const _xref2<T>& v2)
+	{
+	    return _xvec2<T>(
+		    v1.x * v2.x,
+		    v1.y * v2.y);
+	}
+
+	template <typename T>
+    inline _xvec2<T> operator* (const _xref2<T>& v1, const _xvec2<T>& v2)
+	{
+	    return _xvec2<T>(
+		    v1.x * v2.x,
+		    v1.y * v2.y);
+	}
+
+	//operator/
+    template <typename T> 
+    inline _xvec2<T> operator/ (const _xvec2<T>& v, const T s)
+    {
+	    return _xvec2<T>(
+		    v.x / s,
+		    v.y / s);
+    }
+
+    template <typename T> 
+    inline _xvec2<T> operator/ (const T s, const _xvec2<T>& v)
+    {
+	    return _xvec2<T>(
+		    s / v.x,
+		    s / v.y);
+    }
+
+    template <typename T> 
+    inline _xvec2<T> operator/ (const _xvec2<T>& v1, const _xvec2<T>& v2)
+    {
+	    return _xvec2<T>(
+		    v1.x / v2.x,
+		    v1.y / v2.y);
+    }
+
+    template <typename T>
+	inline _xvec2<T> operator/ (const _xref2<T>& v, const T s)
+	{
+	    return _xvec2<T>(
+		    v.x / s,
+		    v.y / s);
+	}
+
+    template <typename T>
+    inline _xvec2<T> operator/ (const T s, const _xref2<T>& v)
+	{
+	    return _xvec2<T>(
+		    s / v.x,
+		    s / v.y);
+	}
+    
+	template <typename T>
+    inline _xvec2<T> operator/ (const _xref2<T>& v1, const _xref2<T>& v2)
+	{
+	    return _xvec2<T>(
+		    v1.x / v2.x,
+		    v1.y / v2.y);
+	}
+
+	template <typename T>
+    inline _xvec2<T> operator/ (const _xvec2<T>& v1, const _xref2<T>& v2)
+	{
+	    return _xvec2<T>(
+		    v1.x / v2.x,
+		    v1.y / v2.y);
+	}
+
+	template <typename T>
+    inline _xvec2<T> operator/ (const _xref2<T>& v1, const _xvec2<T>& v2)
+	{
+	    return _xvec2<T>(
+		    v1.x / v2.x,
+		    v1.y / v2.y);
+	}
+
+    // Unary constant operators
+    template <typename T> 
+    inline const _xvec2<T> operator- (const _xvec2<T>& v)
+    {
+        return _xvec2<T>(
+            -v.x, 
+            -v.y);
+    }
+
+    template <typename T> 
+    inline const _xvec2<T> operator++ (const _xvec2<T>& v, int)
+    {
+        return _xvec2<T>(
+            v.x + T(1), 
+            v.y + T(1));
+    }
+
+    template <typename T> 
+    inline const _xvec2<T> operator-- (const _xvec2<T>& v, int)
+    {
+        return _xvec2<T>(
+            v.x - T(1), 
+            v.y - T(1));
+    }
+
+} //namespace detail
+} //namespace glm
+
+#endif //__xvec2_inl__

+ 283 - 0
experimental/sse/glm/core/_xvec3.h

@@ -0,0 +1,283 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2008 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2006-04-27
+// Updated : 2007-01-15
+// Licence : This source is under GNU LGPL licence
+// File    : glm/core/_xvec3.h
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Optimisation note: Don't use vec3 class instead of vec4 because you think it 
+// whould be faster. It whouldn't be the case especially if you use SSE 
+// intructions set in your compiler option and/or mat4 transformations.
+// An advide: test your code speed with vec3 and vec4 to select the faster.
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef __glm_core_xvec3_h__
+#define __glm_core_xvec3_h__
+
+#include "./_cvec3.inl"
+
+namespace glm{
+namespace detail{
+
+    template <typename T> 
+    class _xvec3 : public _xvec3_base(T)
+    {
+	public:
+        // Common constructors
+	    _xvec3();
+        _xvec3(const _xvec3<T>& v);
+
+        // Swizzle constructors
+        _xvec3(const _xref3<T>& r);
+		_xvec3(const _xvec3_base(T)& b);
+
+        // T constructors
+        explicit _xvec3(const T x);
+        explicit _xvec3(const T a, const T b, const T c);
+        explicit _xvec3(const T a, const T b, const _xvec2<T>& c);
+        explicit _xvec3(const T a, const T b, const _xvec3<T>& c);
+        explicit _xvec3(const T a, const T b, const _xvec4<T>& c);
+        explicit _xvec3(const T a, const _xvec2<T>& b);
+        explicit _xvec3(const T a, const _xvec3<T>& b);
+        explicit _xvec3(const T a, const _xvec4<T>& b);
+        explicit _xvec3(const _xvec2<T>& a, T b);
+        explicit _xvec3(const _xvec2<T>& a, const _xvec2<T>& b);
+        explicit _xvec3(const _xvec2<T>& a, const _xvec3<T>& b);
+        explicit _xvec3(const _xvec2<T>& a, const _xvec4<T>& b);
+        explicit _xvec3(const _xvec4<T>& a);
+
+        // U constructors
+        template <typename U> explicit _xvec3(const U x);
+        template <typename U> explicit _xvec3(const U a, const U b, const U c);
+        template <typename U> explicit _xvec3(const U a, const U b, const _xvec2<U>& c);
+        template <typename U> explicit _xvec3(const U a, const U b, const _xvec3<U>& c);
+        template <typename U> explicit _xvec3(const U a, const U b, const _xvec4<U>& c);
+        template <typename U> explicit _xvec3(const U a, const _xvec2<U>& b);
+        template <typename U> explicit _xvec3(const U a, const _xvec3<U>& b);
+        template <typename U> explicit _xvec3(const U a, const _xvec4<U>& b);
+        template <typename U> explicit _xvec3(const _xvec2<U>& a, U b);
+        template <typename U> explicit _xvec3(const _xvec2<U>& a, const _xvec2<U>& b);
+        template <typename U> explicit _xvec3(const _xvec2<U>& a, const _xvec3<U>& b);
+        template <typename U> explicit _xvec3(const _xvec2<U>& a, const _xvec4<U>& b);
+        template <typename U> explicit _xvec3(const _xvec3<U>& a);
+        template <typename U> explicit _xvec3(const _xvec4<U>& a);
+
+        // Bool constructors
+        explicit _xvec3(const bool x);
+        explicit _xvec3(const bool a, const bool b, const bool c);
+        explicit _xvec3(const bool a, const bool b, const _bvec2& c);
+        explicit _xvec3(const bool a, const bool b, const _bvec3& c);
+        explicit _xvec3(const bool a, const bool b, const _bvec4& c);
+        explicit _xvec3(const bool a, const _bvec2& b);
+        explicit _xvec3(const bool a, const _bvec3& b);
+        explicit _xvec3(const bool a, const _bvec4& b);
+        explicit _xvec3(const _bvec2& a, bool b);
+        explicit _xvec3(const _bvec2& a, const _bvec2& b);
+        explicit _xvec3(const _bvec2& a, const _bvec3& b);
+        explicit _xvec3(const _bvec2& a, const _bvec4& b);
+        explicit _xvec3(const _bvec3& a);
+        explicit _xvec3(const _bvec4& a);
+
+        // Unary updatable operators
+        _xvec3<T>& operator= (const _xvec3<T>& v);
+	    _xvec3<T>& operator+=(const T s);
+	    _xvec3<T>& operator+=(const _xvec3<T>& v);
+	    _xvec3<T>& operator-=(const T s);
+	    _xvec3<T>& operator-=(const _xvec3<T>& v);
+	    _xvec3<T>& operator*=(const T s);
+	    _xvec3<T>& operator*=(const _xvec3<T>& v);
+	    _xvec3<T>& operator/=(const T s);
+	    _xvec3<T>& operator/=(const _xvec3<T>& v);
+        _xvec3<T>& operator++();
+	    _xvec3<T>& operator--();
+/*
+		// Bit operators
+	    _xvec3<T>& operator%=(const T s);
+	    _xvec3<T>& operator%=(const _xvec3<T>& v);
+		_xvec3<T>& operator&=(const T s);
+	    _xvec3<T>& operator&=(const _xvec3<T>& v);
+	    _xvec3<T>& operator|=(const T s);
+	    _xvec3<T>& operator|=(const _xvec3<T>& v);
+	    _xvec3<T>& operator^=(const T s);
+	    _xvec3<T>& operator^=(const _xvec3<T>& v);
+	    _xvec3<T>& operator<<=(const T s);
+	    _xvec3<T>& operator<<=(const _xvec3<T>& v);
+	    _xvec3<T>& operator>>=(const T s);
+	    _xvec3<T>& operator>>=(const _xvec3<T>& v);
+*/
+    };
+/*
+	// Bit operators
+    template <typename T>
+	_xvec3<T> operator% (const _xvec3<T>& v, const T s);
+
+    template <typename T>
+    _xvec3<T> operator% (const T s, const _xvec3<T>& v);
+
+    template <typename T>
+    _xvec3<T> operator% (const _xvec3<T>& v1, const _xvec3<T>& v2);
+
+    template <typename T>
+	_xvec3<T> operator& (const _xvec3<T>& v, const T s);
+
+    template <typename T>
+    _xvec3<T> operator& (const T s, const _xvec3<T>& v);
+
+    template <typename T>
+    _xvec3<T> operator& (const _xvec3<T>& v1, const _xvec3<T>& v2);
+
+    template <typename T>
+	_xvec3<T> operator| (const _xvec3<T>& v, const T s);
+
+    template <typename T>
+    _xvec3<T> operator| (const T s, const _xvec3<T>& v);
+
+    template <typename T>
+    _xvec3<T> operator| (const _xvec3<T>& v1, const _xvec3<T>& v2);
+
+    template <typename T>
+	_xvec3<T> operator^ (const _xvec3<T>& v, const T s);
+
+    template <typename T>
+    _xvec3<T> operator^ (const T s, const _xvec3<T>& v);
+
+    template <typename T>
+    _xvec3<T> operator^ (const _xvec3<T>& v1, const _xvec3<T>& v2);
+
+    template <typename T>
+	_xvec3<T> operator<< (const _xvec3<T>& v, const T s);
+
+    template <typename T>
+    _xvec3<T> operator<< (const T s, const _xvec3<T>& v);
+
+    template <typename T>
+    _xvec3<T> operator<< (const _xvec3<T>& v1, const _xvec3<T>& v2);
+
+	template <typename T>
+	_xvec3<T> operator>> (const _xvec3<T>& v, const T s);
+
+    template <typename T>
+    _xvec3<T> operator>> (const T s, const _xvec3<T>& v);
+
+    template <typename T>
+    _xvec3<T> operator>> (const _xvec3<T>& v1, const _xvec3<T>& v2);
+
+    template <typename T> 
+    const _xvec3<T> operator~ (const _xvec2<T>& v);
+*/
+    // Binasy opesators
+	// operator+
+    template <typename T>
+	_xvec3<T> operator+ (const _xvec3<T>& v, const T s);
+
+    template <typename T>
+    _xvec3<T> operator+ (const T s, const _xvec3<T>& v);
+
+    template <typename T>
+    _xvec3<T> operator+ (const _xvec3<T>& v1, const _xvec3<T>& v2);
+    
+    template <typename T>
+	_xvec3<T> operator+ (const _xref3<T>& v, const T s);
+
+    template <typename T>
+    _xvec3<T> operator+ (const T s, const _xref3<T>& v);
+    
+	template <typename T>
+    _xvec3<T> operator+ (const _xref3<T>& v1, const _xref3<T>& v2);
+
+	template <typename T>
+    _xvec3<T> operator+ (const _xvec3<T>& v1, const _xref3<T>& v2);
+
+	template <typename T>
+    _xvec3<T> operator+ (const _xref3<T>& v1, const _xvec3<T>& v2);
+
+	// operator-
+    template <typename T>
+	_xvec3<T> operator- (const _xvec3<T>& v, const T s);
+
+    template <typename T>
+    _xvec3<T> operator- (const T s, const _xvec3<T>& v);
+
+    template <typename T>
+    _xvec3<T> operator- (const _xvec3<T>& v1, const _xvec3<T>& v2);
+
+    template <typename T>
+	_xvec3<T> operator- (const _xref3<T>& v, const T s);
+
+    template <typename T>
+    _xvec3<T> operator- (const T s, const _xref3<T>& v);
+    
+	template <typename T>
+    _xvec3<T> operator- (const _xref3<T>& v1, const _xref3<T>& v2);
+
+	template <typename T>
+    _xvec3<T> operator- (const _xvec3<T>& v1, const _xref3<T>& v2);
+
+	template <typename T>
+    _xvec3<T> operator- (const _xref3<T>& v1, const _xvec3<T>& v2);
+
+	// operator*
+    template <typename T>
+    _xvec3<T> operator* (const _xvec3<T>& v, const T s);
+
+    template <typename T>
+    _xvec3<T> operator* (const T s, const _xvec3<T>& v);
+
+    template <typename T>
+    _xvec3<T> operator* (const _xvec3<T>& v1, const _xvec3<T>& v2);
+
+    template <typename T>
+	_xvec3<T> operator* (const _xref3<T>& v, const T s);
+
+    template <typename T>
+    _xvec3<T> operator* (const T s, const _xref3<T>& v);
+    
+	template <typename T>
+    _xvec3<T> operator* (const _xref3<T>& v1, const _xref3<T>& v2);
+
+	template <typename T>
+    _xvec3<T> operator* (const _xvec3<T>& v1, const _xref3<T>& v2);
+
+	template <typename T>
+    _xvec3<T> operator* (const _xref3<T>& v1, const _xvec3<T>& v2);
+
+	// operator/
+    template <typename T>
+    _xvec3<T> operator/ (const _xvec3<T>& v, const T s);
+
+    template <typename T>
+    _xvec3<T> operator/ (const T s, const _xvec3<T>& v);
+
+    template <typename T>
+    _xvec3<T> operator/ (const _xvec3<T>& v1, const _xvec3<T>& v2);
+
+    template <typename T>
+	_xvec3<T> operator/ (const _xref3<T>& v, const T s);
+
+    template <typename T>
+    _xvec3<T> operator/ (const T s, const _xref3<T>& v);
+    
+	template <typename T>
+    _xvec3<T> operator/ (const _xref3<T>& v1, const _xref3<T>& v2);
+
+	template <typename T>
+    _xvec3<T> operator/ (const _xvec3<T>& v1, const _xref3<T>& v2);
+
+	template <typename T>
+    _xvec3<T> operator/ (const _xref3<T>& v1, const _xvec3<T>& v2);
+
+    // Unary constant operators
+    template <typename T> 
+    const _xvec3<T> operator- (const _xvec3<T>& v);
+
+    template <typename T> 
+    const _xvec3<T> operator-- (const _xvec3<T>& v, int);
+
+    template <typename T> 
+    const _xvec3<T> operator++ (const _xvec3<T>& v, int);
+
+} //namespace detail
+} //namespace glm
+
+#endif//__glm_core_xvec3_h__

+ 694 - 0
experimental/sse/glm/core/_xvec3.inl

@@ -0,0 +1,694 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2008 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2006-04-27
+// Updated : 2007-01-19
+// Licence : This source is under GNU LGPL licence
+// File    : glm/core/_xvec3.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef __glm_core_xvec3_inl__
+#define __glm_core_xvec3_inl__
+
+#include "./_xvec2.h"
+#include "./_bvec2.h"
+#include "./_xvec3.h"
+#include "./_bvec3.h"
+#include "./_xvec4.h"
+#include "./_bvec4.h"
+#include "./_swizzle.inl"
+
+namespace glm{
+namespace detail{
+
+    // Common constructors
+    template <typename T> 
+    inline _xvec3<T>::_xvec3() :
+        _cvec3<XVEC3_INST>(T(0), T(0), T(0))
+    {}
+
+    template <typename T> 
+    inline _xvec3<T>::_xvec3(const _xvec3<T>& v) :
+        _cvec3<XVEC3_INST>(v.x, v.y, v.z)
+    {}
+
+    // Swizzle constructors
+    template <typename T> 
+    inline _xvec3<T>::_xvec3(const _xref3<T>& r) :
+        _cvec3<XVEC3_INST>(r.x, r.y, r.z)
+    {}
+
+    template <typename T> 
+    inline _xvec3<T>::_xvec3(const _xvec3_base(T)& b) :
+		_cvec3<XVEC3_INST>(b.x, b.y, b.z)
+    {}
+
+    // T constructors
+    template <typename T> 
+    inline _xvec3<T>::_xvec3(const T x) :
+        _cvec3<XVEC3_INST>(x, x, x)
+    {}
+
+    template <typename T> 
+    inline _xvec3<T>::_xvec3(const T a, const T b, const T c) :
+        _cvec3<XVEC3_INST>(a, b, c)
+    {}
+
+    template <typename T> 
+    inline _xvec3<T>::_xvec3(const T a, const T b, const _xvec2<T>& c) :
+        _cvec3<XVEC3_INST>(a, b, c.x)
+    {}
+
+    template <typename T> 
+    inline _xvec3<T>::_xvec3(const T a, const T b, const _xvec3<T>& c) :
+        _cvec3<XVEC3_INST>(a, b, c.x)
+    {}
+
+    template <typename T> 
+    inline _xvec3<T>::_xvec3(const T a, const T b, const _xvec4<T>& c) :
+		_cvec3<XVEC3_INST>(a, b, c.x)
+    {}
+
+    template <typename T> 
+    inline _xvec3<T>::_xvec3(const T a, const _xvec2<T>& b) :
+		_cvec3<XVEC3_INST>(a, b.x, b.y)
+    {}
+
+    template <typename T> 
+    inline _xvec3<T>::_xvec3(const T a, const _xvec3<T>& b) :
+		_cvec3<XVEC3_INST>(a, b.x, b.y)
+    {}
+
+    template <typename T> 
+    inline _xvec3<T>::_xvec3(const T a, const _xvec4<T>& b) :
+		_cvec3<XVEC3_INST>(a, b.x, b.y)
+    {}
+
+    template <typename T> 
+    inline _xvec3<T>::_xvec3(const _xvec2<T>& a, T b) :
+		_cvec3<XVEC3_INST>(a.x, a.y, b)
+    {}
+
+    template <typename T> 
+    inline _xvec3<T>::_xvec3(const _xvec2<T>& a, const _xvec2<T>& b) :
+        _cvec3<XVEC3_INST>(a.x, a.y, b.x)
+    {}
+
+    template <typename T> 
+    inline _xvec3<T>::_xvec3(const _xvec2<T>& a, const _xvec3<T>& b) :
+        _cvec3<XVEC3_INST>(a.x, a.y, b.x)
+    {}
+
+    template <typename T> 
+    inline _xvec3<T>::_xvec3(const _xvec2<T>& a, const _xvec4<T>& b) :
+        _cvec3<XVEC3_INST>(a.x, a.y, b.x)
+    {}
+
+    template <typename T> 
+    inline _xvec3<T>::_xvec3(const _xvec4<T>& a) :
+        _cvec3<XVEC3_INST>(a.x, a.y, a.z)
+    {}
+
+    // U constructors
+    template <typename T> 
+    template <typename U> 
+    inline _xvec3<T>::_xvec3(const U x) :
+        _cvec3<XVEC3_INST>(T(x), T(x), T(x))
+    {}
+
+    template <typename T> 
+    template <typename U> 
+    inline _xvec3<T>::_xvec3(const U a, const U b, const U c) :
+        _cvec3<XVEC3_INST>(T(a), T(b), T(c))
+    {}
+
+    template <typename T> 
+    template <typename U> 
+    inline _xvec3<T>::_xvec3(const U a, const U b, const _xvec2<U>& c) :
+		_cvec3<XVEC3_INST>(T(a), T(b), T(c.x))
+    {}
+
+    template <typename T> 
+    template <typename U> 
+    inline _xvec3<T>::_xvec3(const U a, const U b, const _xvec3<U>& c) :
+		_cvec3<XVEC3_INST>(T(a), T(b), T(c.x))
+    {}
+
+    template <typename T> 
+    template <typename U> 
+    inline _xvec3<T>::_xvec3(const U a, const U b, const _xvec4<U>& c) :
+        _cvec3<XVEC3_INST>(T(a), T(b), T(c.x))
+    {}
+
+    template <typename T> 
+    template <typename U> 
+    inline _xvec3<T>::_xvec3(const U a, const _xvec2<U>& b) :
+        _cvec3<XVEC3_INST>(T(a), T(b.x), T(b.y))
+    {}
+
+    template <typename T> 
+    template <typename U> 
+    inline _xvec3<T>::_xvec3(const U a, const _xvec3<U>& b) :
+        _cvec3<XVEC3_INST>(T(a), T(b.x), T(b.y))
+    {}
+
+    template <typename T> 
+    template <typename U> 
+    inline _xvec3<T>::_xvec3(const U a, const _xvec4<U>& b) :
+        _cvec3<XVEC3_INST>(T(a), T(b.x), T(b.y))
+    {}
+
+    template <typename T> 
+    template <typename U> 
+    inline _xvec3<T>::_xvec3(const _xvec2<U>& a, U b) :
+        _cvec3<XVEC3_INST>(T(a.x), T(a.y), T(b))
+    {}
+
+    template <typename T> 
+    template <typename U> 
+    inline _xvec3<T>::_xvec3(const _xvec2<U>& a, const _xvec2<U>& b) :
+        _cvec3<XVEC3_INST>(T(a.x), T(a.y), T(b.x))
+    {}
+
+    template <typename T> 
+    template <typename U> 
+    inline _xvec3<T>::_xvec3(const _xvec2<U>& a, const _xvec3<U>& b) :
+        _cvec3<XVEC3_INST>(T(a.x), T(a.y), T(b.x))
+    {}
+
+    template <typename T> 
+    template <typename U> 
+    inline _xvec3<T>::_xvec3(const _xvec2<U>& a, const _xvec4<U>& b) :
+        _cvec3<XVEC3_INST>(T(a.x), T(a.y), T(b.x))
+    {}
+
+    template <typename T> 
+    template <typename U> 
+    inline _xvec3<T>::_xvec3(const _xvec3<U>& a) :
+        _cvec3<XVEC3_INST>(T(a.x), T(a.y), T(a.z))
+    {}
+
+    template <typename T> 
+    template <typename U> 
+    inline _xvec3<T>::_xvec3(const _xvec4<U>& a) :
+        _cvec3<XVEC3_INST>(T(a.x), T(a.y), T(a.z))
+    {}
+
+    // Bool constructors
+    template <typename T> 
+    inline _xvec3<T>::_xvec3(const bool x) :
+        _cvec3<XVEC3_INST>(T(x), T(x), T(x))
+    {}
+
+    template <typename T> 
+    inline _xvec3<T>::_xvec3(const bool a, const bool b, const bool c) :
+        _cvec3<XVEC3_INST>(T(a), T(b), T(c))
+    {}
+
+    template <typename T> 
+    inline _xvec3<T>::_xvec3(const bool a, const bool b, const _bvec2& c) :
+        _cvec3<XVEC3_INST>(T(a), T(b), T(c.x))
+    {}
+
+    template <typename T> 
+    inline _xvec3<T>::_xvec3(const bool a, const bool b, const _bvec3& c) :
+        _cvec3<XVEC3_INST>(T(a), T(b), T(c.x))
+    {}
+
+    template <typename T> 
+    inline _xvec3<T>::_xvec3(const bool a, const bool b, const _bvec4& c) :
+        _cvec3<XVEC3_INST>(T(a), T(b), T(c.x))
+    {}
+
+    template <typename T> 
+    inline _xvec3<T>::_xvec3(const bool a, const _bvec2& b) :
+        _cvec3<XVEC3_INST>(T(a), T(b.x), T(b.y))
+    {}
+
+    template <typename T> 
+    inline _xvec3<T>::_xvec3(const bool a, const _bvec3& b) :
+        _cvec3<XVEC3_INST>(T(a), T(b.x), T(b.y))
+    {}
+
+    template <typename T> 
+    inline _xvec3<T>::_xvec3(const bool a, const _bvec4& b) :
+        _cvec3<XVEC3_INST>(T(a), T(b.x), T(b.y))
+    {}
+
+    template <typename T> 
+    inline _xvec3<T>::_xvec3(const _bvec2& a, bool b) :
+        _cvec3<XVEC3_INST>(T(a.x), T(a.y), T(b))
+    {}
+
+    template <typename T> 
+    inline _xvec3<T>::_xvec3(const _bvec2& a, const _bvec2& b) :
+        _cvec3<XVEC3_INST>(T(a.x), T(a.y), T(b.x))
+    {}
+
+    template <typename T> 
+    inline _xvec3<T>::_xvec3(const _bvec2& a, const _bvec3& b) :
+        _cvec3<XVEC3_INST>(T(a.x), T(a.y), T(b.x))
+    {}
+
+    template <typename T> 
+    inline _xvec3<T>::_xvec3(const _bvec2& a, const _bvec4& b) :
+        _cvec3<XVEC3_INST>(T(a.x), T(a.y), T(b.x))
+    {}
+
+    template <typename T> 
+    inline _xvec3<T>::_xvec3(const _bvec3& a) :
+        _cvec3<XVEC3_INST>(T(a.x), T(a.y), T(a.z))
+    {}
+
+    template <typename T> 
+    inline _xvec3<T>::_xvec3(const _bvec4& a) :
+        _cvec3<XVEC3_INST>(T(a.x), T(a.y), T(a.z))
+    {}
+
+    //////////////////////////////////////////////////////////////
+    // vec3 and ivec3 operators
+
+    // This function shouldn't required but it seems that VC7.1 have an optimisation bug if this operator wasn't declared
+    template <typename T> 
+    inline _xvec3<T>& _xvec3<T>::operator=(const _xvec3<T>& v)
+    {
+        this->x = v.x;
+        this->y = v.y;
+        this->z = v.z;
+        return *this;
+    }
+
+    template <typename T> 
+    inline _xvec3<T>& _xvec3<T>::operator+= (const T s)
+    {
+	    this->x += s;
+	    this->y += s;
+        this->z += s;
+	    return *this;
+    }
+
+    template <typename T> 
+    inline _xvec3<T>& _xvec3<T>::operator+= (const _xvec3<T>& v)
+    {
+	    this->x += v.x;
+	    this->y += v.y;
+        this->z += v.z;
+	    return *this;
+    }
+
+    template <typename T> 
+    inline _xvec3<T>& _xvec3<T>::operator-= (const T s)
+    {
+	    this->x -= s;
+	    this->y -= s;
+        this->z -= s;
+	    return *this;
+    }
+
+    template <typename T> 
+    inline _xvec3<T>& _xvec3<T>::operator-= (const _xvec3<T>& v)
+    {
+	    this->x -= v.x;
+	    this->y -= v.y;
+        this->z -= v.z;
+	    return *this;
+    }
+
+    template <typename T> 
+    inline _xvec3<T>& _xvec3<T>::operator*= (const T s)
+    {
+	    this->x *= s;
+	    this->y *= s;
+        this->z *= s;
+	    return *this;
+    }
+
+    template <typename T> 
+    inline _xvec3<T>& _xvec3<T>::operator*= (const _xvec3<T>& v)
+    {
+	    this->x *= v.x;
+	    this->y *= v.y;
+        this->z *= v.z;
+	    return *this;
+    }
+
+    template <typename T> 
+    inline _xvec3<T>& _xvec3<T>::operator/= (const T s)
+    {
+	    this->x /= s;
+	    this->y /= s;
+        this->z /= s;
+	    return *this;
+    }
+
+    template <typename T> 
+    inline _xvec3<T>& _xvec3<T>::operator/= (const _xvec3<T>& v)
+    {
+	    this->x /= v.x;
+	    this->y /= v.y;
+        this->z /= v.z;
+	    return *this;
+    }
+
+    template <typename T> 
+    inline _xvec3<T>& _xvec3<T>::operator++ ()
+    {
+	    this->x++;
+	    this->y++;
+        this->z++;
+	    return *this;
+    }
+
+    template <typename T> 
+    inline _xvec3<T>& _xvec3<T>::operator-- ()
+    {
+	    this->x--;
+	    this->y--;
+        this->z--;
+	    return *this;
+    }
+
+    // Unary constant operators
+    template <typename T> 
+    inline const _xvec3<T> operator- (const _xvec3<T>& v)
+    {
+        return _xvec3<T>(
+            -v.x, 
+            -v.y,
+            -v.z);
+    }
+
+    template <typename T> 
+    inline const _xvec3<T> operator++ (const _xvec3<T>& v, int)
+    {
+        return _xvec3<T>(
+            v.x + T(1), 
+            v.y + T(1),
+            v.z + T(1));
+    }
+
+    template <typename T> 
+    inline const _xvec3<T> operator-- (const _xvec3<T>& v, int)
+    {
+        return _xvec3<T>(
+            v.x - T(1), 
+            v.y - T(1),
+            v.z - T(1));
+    }
+
+    // Binary operators
+	// operator+
+    template <typename T> 
+    inline _xvec3<T> operator+ (const _xvec3<T>& v, const T s)
+    {
+	    return _xvec3<T>(
+		    v.x + s,
+		    v.y + s,
+            v.z + s);
+    }
+
+    template <typename T> 
+    inline _xvec3<T> operator+ (const T s, const _xvec3<T>& v)
+    {
+	    return _xvec3<T>(
+		    s + v.x,
+		    s + v.y,
+            s + v.z);
+    }
+
+    template <typename T> 
+    inline _xvec3<T> operator+ (const _xvec3<T>& v1, const _xvec3<T>& v2)
+    {
+	    return _xvec3<T>(
+		    v1.x + v2.x,
+		    v1.y + v2.y,
+            v1.z + v2.z);
+    }
+
+    template <typename T>
+	inline _xvec3<T> operator+ (const _xref3<T>& v, const T s)
+	{
+	    return _xvec3<T>(
+		    v.x + s,
+		    v.y + s,
+			v.z + s);
+	}
+
+    template <typename T>
+    inline _xvec3<T> operator+ (const T s, const _xref3<T>& v)
+	{
+	    return _xvec3<T>(
+		    s + v.x,
+		    s + v.y,
+			s + v.z);
+	}
+    
+	template <typename T>
+    inline _xvec3<T> operator+ (const _xref3<T>& v1, const _xref3<T>& v2)
+	{
+	    return _xvec3<T>(
+		    v1.x + v2.x,
+		    v1.y + v2.y,
+			v1.z + v2.z);
+	}
+
+	template <typename T>
+    inline _xvec3<T> operator+ (const _xvec3<T>& v1, const _xref3<T>& v2)
+	{
+	    return _xvec3<T>(
+		    v1.x + v2.x,
+		    v1.y + v2.y,
+			v1.z + v2.z);
+	}
+
+	template <typename T>
+    inline _xvec3<T> operator+ (const _xref3<T>& v1, const _xvec3<T>& v2)
+	{
+	    return _xvec3<T>(
+		    v1.x + v2.x,
+		    v1.y + v2.y,
+			v1.z + v2.z);
+	}
+
+	// operator-
+    template <typename T> 
+    inline _xvec3<T> operator- (const _xvec3<T>& v, const T s)
+    {
+	    return _xvec3<T>(
+		    v.x - s,
+		    v.y - s,
+            v.z - s);
+    }
+
+    template <typename T> 
+    inline _xvec3<T> operator- (const T s, const _xvec3<T>& v)
+    {
+	    return _xvec3<T>(
+		    s - v.x,
+		    s - v.y,
+            s - v.z);
+    }
+
+    template <typename T> 
+    inline _xvec3<T> operator- (const _xvec3<T>& v1, const _xvec3<T>& v2)
+    {
+	    return _xvec3<T>(
+		    v1.x - v2.x,
+		    v1.y - v2.y,
+            v1.z - v2.z);
+    }
+
+    template <typename T>
+	inline _xvec3<T> operator- (const _xref3<T>& v, const T s)
+	{
+	    return _xvec3<T>(
+		    v.x - s,
+		    v.y - s,
+			v.z - s);
+	}
+
+    template <typename T>
+    inline _xvec3<T> operator- (const T s, const _xref3<T>& v)
+	{
+	    return _xvec3<T>(
+		    s - v.x,
+		    s - v.y,
+			s - v.z);
+	}
+    
+	template <typename T>
+    inline _xvec3<T> operator- (const _xref3<T>& v1, const _xref3<T>& v2)
+	{
+	    return _xvec3<T>(
+		    v1.x - v2.x,
+		    v1.y - v2.y,
+			v1.z - v2.z);
+	}
+
+	template <typename T>
+    inline _xvec3<T> operator- (const _xvec3<T>& v1, const _xref3<T>& v2)
+	{
+	    return _xvec3<T>(
+		    v1.x - v2.x,
+		    v1.y - v2.y,
+			v1.z - v2.z);
+	}
+
+	template <typename T>
+    inline _xvec3<T> operator- (const _xref3<T>& v1, const _xvec3<T>& v2)
+	{
+	    return _xvec3<T>(
+		    v1.x - v2.x,
+		    v1.y - v2.y,
+			v1.z - v2.z);
+	}
+
+	// operator*
+    template <typename T> 
+    inline _xvec3<T> operator* (const _xvec3<T>& v, const T s)
+    {
+	    return _xvec3<T>(
+		    v.x * s,
+		    v.y * s,
+            v.z * s);
+    }
+
+    template <typename T> 
+    inline _xvec3<T> operator* (const T s, const _xvec3<T>& v)
+    {
+	    return _xvec3<T>(
+		    s * v.x,
+		    s * v.y,
+            s * v.z);
+    }
+
+    template <typename T> 
+    inline _xvec3<T> operator* (const _xvec3<T>& v1, const _xvec3<T> & v2)
+    {
+	    return _xvec3<T>(
+		    v1.x * v2.x,
+		    v1.y * v2.y,
+            v1.z * v2.z);
+    }
+
+    template <typename T>
+	inline _xvec3<T> operator* (const _xref3<T>& v, const T s)
+	{
+	    return _xvec3<T>(
+		    v.x * s,
+		    v.y * s,
+			v.z * s);
+	}
+
+    template <typename T>
+    inline _xvec3<T> operator* (const T s, const _xref3<T>& v)
+	{
+	    return _xvec3<T>(
+		    s * v.x,
+		    s * v.y,
+			s * v.z);
+	}
+    
+	template <typename T>
+    inline _xvec3<T> operator* (const _xref3<T>& v1, const _xref3<T>& v2)
+	{
+	    return _xvec3<T>(
+		    v1.x * v2.x,
+		    v1.y * v2.y,
+			v1.z * v2.z);
+	}
+
+	template <typename T>
+    inline _xvec3<T> operator* (const _xvec3<T>& v1, const _xref3<T>& v2)
+	{
+	    return _xvec3<T>(
+		    v1.x * v2.x,
+		    v1.y * v2.y,
+			v1.z * v2.z);
+	}
+
+	template <typename T>
+    inline _xvec3<T> operator* (const _xref3<T>& v1, const _xvec3<T>& v2)
+	{
+	    return _xvec3<T>(
+		    v1.x * v2.x,
+		    v1.y * v2.y,
+			v1.z * v2.z);
+	}
+
+	// operator/
+    template <typename T> 
+    inline _xvec3<T> operator/ (const _xvec3<T>& v, const T s)
+    {
+	    return _xvec3<T>(
+		    v.x / s,
+		    v.y / s,
+            v.z / s);
+    }
+
+    template <typename T> 
+    inline _xvec3<T> operator/ (const T s, const _xvec3<T>& v)
+    {
+	    return _xvec3<T>(
+		    s / v.x,
+		    s / v.y,
+            s / v.z);
+    }
+
+    template <typename T> 
+    inline _xvec3<T> operator/ (const _xvec3<T>& v1, const _xvec3<T>& v2)
+    {
+	    return _xvec3<T>(
+		    v1.x / v2.x,
+		    v1.y / v2.y,
+            v1.z / v2.z);
+    }
+
+    template <typename T>
+	inline _xvec3<T> operator/ (const _xref3<T>& v, const T s)
+	{
+	    return _xvec3<T>(
+		    v.x / s,
+		    v.y / s,
+			v.z / s);
+	}
+
+    template <typename T>
+    inline _xvec3<T> operator/ (const T s, const _xref3<T>& v)
+	{
+	    return _xvec3<T>(
+		    s / v.x,
+		    s / v.y,
+			s / v.z);
+	}
+    
+	template <typename T>
+    inline _xvec3<T> operator/ (const _xref3<T>& v1, const _xref3<T>& v2)
+	{
+	    return _xvec3<T>(
+		    v1.x / v2.x,
+		    v1.y / v2.y,
+			v1.z / v2.z);
+	}
+
+	template <typename T>
+    inline _xvec3<T> operator/ (const _xvec3<T>& v1, const _xref3<T>& v2)
+	{
+	    return _xvec3<T>(
+		    v1.x / v2.x,
+		    v1.y / v2.y,
+			v1.z / v2.z);
+	}
+
+	template <typename T>
+    inline _xvec3<T> operator/ (const _xref3<T>& v1, const _xvec3<T>& v2)
+	{
+	    return _xvec3<T>(
+		    v1.x / v2.x,
+		    v1.y / v2.y,
+			v1.z / v2.z);
+	}
+} //namespace detail
+} //namespace glm
+
+#endif//__glm_core_xvec3_inl__

+ 241 - 0
experimental/sse/glm/core/_xvec4.h

@@ -0,0 +1,241 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2008 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2006-04-27
+// Updated : 2007-01-15
+// Licence : This source is under GNU LGPL licence
+// File    : glm/core/_xvec4.h
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef __glm_core_xvec4_h__
+#define __glm_core_xvec4_h__
+
+#include "./_cvec4.inl"
+
+namespace glm{
+namespace detail{
+
+    template <typename T> 
+    class _xvec4 : public _xvec4_base(T)
+    {
+	public:
+        // Common constructors
+	    _xvec4();
+        _xvec4(const _xvec4<T>& v);
+
+        // Swizzle constructors
+        _xvec4(const _xref4<T>& r);
+		_xvec4(const _xvec4_base(T)& b);
+
+        // T constructors
+        explicit _xvec4(const T x);
+        explicit _xvec4(const T a, const T b, const T c, const T d);
+        explicit _xvec4(const T a, const T b, const T c, const _xvec2<T>& d);
+        explicit _xvec4(const T a, const T b, const T c, const _xvec3<T>& d);
+        explicit _xvec4(const T a, const T b, const T c, const _xvec4<T>& d);
+        explicit _xvec4(const T a, const T b, const _xvec2<T>& c);
+        explicit _xvec4(const T a, const T b, const _xvec3<T>& c);
+        explicit _xvec4(const T a, const T b, const _xvec4<T>& c);
+        explicit _xvec4(const T a, const _xvec2<T>& b, const T c);
+        explicit _xvec4(const T a, const _xvec2<T>& b, const _xvec2<T>& c);
+        explicit _xvec4(const T a, const _xvec2<T>& b, const _xvec3<T>& c);
+        explicit _xvec4(const T a, const _xvec2<T>& b, const _xvec4<T>& c);
+        explicit _xvec4(const T a, const _xvec3<T>& b);
+        explicit _xvec4(const T a, const _xvec4<T>& b);
+        explicit _xvec4(const _xvec2<T>& a, const T b, const T c);
+        explicit _xvec4(const _xvec2<T>& a, const T b, const _xvec2<T>& c);
+        explicit _xvec4(const _xvec2<T>& a, const T b, const _xvec3<T>& c);
+        explicit _xvec4(const _xvec2<T>& a, const T b, const _xvec4<T>& c);
+        explicit _xvec4(const _xvec2<T>& a, const _xvec2<T>& b);
+        explicit _xvec4(const _xvec2<T>& a, const _xvec3<T>& b);
+        explicit _xvec4(const _xvec2<T>& a, const _xvec4<T>& b);
+        explicit _xvec4(const _xvec3<T>& a, const T b);
+        explicit _xvec4(const _xvec3<T>& a, const _xvec2<T>& b);
+        explicit _xvec4(const _xvec3<T>& a, const _xvec3<T>& b);
+        explicit _xvec4(const _xvec3<T>& a, const _xvec4<T>& b);
+
+        // U constructors
+        template <typename U> explicit _xvec4(const U x);
+        template <typename U> explicit _xvec4(const U a, const U b, const U c, const U d);
+        template <typename U> explicit _xvec4(const U a, const U b, const U c, const _xvec2<U>& d);
+        template <typename U> explicit _xvec4(const U a, const U b, const U c, const _xvec3<U>& d);
+        template <typename U> explicit _xvec4(const U a, const U b, const U c, const _xvec4<U>& d);
+        template <typename U> explicit _xvec4(const U a, const U b, const _xvec2<U>& c);
+        template <typename U> explicit _xvec4(const U a, const U b, const _xvec3<U>& c);
+        template <typename U> explicit _xvec4(const U a, const U b, const _xvec4<U>& c);
+        template <typename U> explicit _xvec4(const U a, const _xvec2<U>& b, const U c);
+        template <typename U> explicit _xvec4(const U a, const _xvec2<U>& b, const _xvec2<U>& c);
+        template <typename U> explicit _xvec4(const U a, const _xvec2<U>& b, const _xvec3<U>& c);
+        template <typename U> explicit _xvec4(const U a, const _xvec2<U>& b, const _xvec4<U>& c);
+        template <typename U> explicit _xvec4(const U a, const _xvec3<U>& b);
+        template <typename U> explicit _xvec4(const U a, const _xvec4<U>& b);
+        template <typename U> explicit _xvec4(const _xvec2<U>& a, const U b, const U c);
+        template <typename U> explicit _xvec4(const _xvec2<U>& a, const U b, const _xvec2<U>& c);
+        template <typename U> explicit _xvec4(const _xvec2<U>& a, const U b, const _xvec3<U>& c);
+        template <typename U> explicit _xvec4(const _xvec2<U>& a, const U b, const _xvec4<U>& c);
+        template <typename U> explicit _xvec4(const _xvec2<U>& a, const _xvec2<U>& b);
+        template <typename U> explicit _xvec4(const _xvec2<U>& a, const _xvec3<U>& b);
+        template <typename U> explicit _xvec4(const _xvec2<U>& a, const _xvec4<U>& b);
+        template <typename U> explicit _xvec4(const _xvec3<U>& a, const U b);
+        template <typename U> explicit _xvec4(const _xvec3<U>& a, const _xvec2<U>& b);
+        template <typename U> explicit _xvec4(const _xvec3<U>& a, const _xvec3<U>& b);
+        template <typename U> explicit _xvec4(const _xvec3<U>& a, const _xvec4<U>& b);
+        template <typename U> explicit _xvec4(const _xvec4<U>& a);
+
+        // Bool constructors
+        explicit _xvec4(const bool x);
+        explicit _xvec4(const bool a, const bool b, const bool c, const bool d);
+        explicit _xvec4(const bool a, const bool b, const bool c, const _bvec2& d);
+        explicit _xvec4(const bool a, const bool b, const bool c, const _bvec3& d);
+        explicit _xvec4(const bool a, const bool b, const bool c, const _bvec4& d);
+        explicit _xvec4(const bool a, const bool b, const _bvec2& c);
+        explicit _xvec4(const bool a, const bool b, const _bvec3& c);
+        explicit _xvec4(const bool a, const bool b, const _bvec4& c);
+        explicit _xvec4(const bool a, const _bvec2& b, const bool c);
+        explicit _xvec4(const bool a, const _bvec2& b, const _bvec2& c);
+        explicit _xvec4(const bool a, const _bvec2& b, const _bvec3& c);
+        explicit _xvec4(const bool a, const _bvec2& b, const _bvec4& c);
+        explicit _xvec4(const bool a, const _bvec3& b);
+        explicit _xvec4(const bool a, const _bvec4& b);
+        explicit _xvec4(const _bvec2& a, const bool b, const bool c);
+        explicit _xvec4(const _bvec2& a, const bool b, const _bvec2& c);
+        explicit _xvec4(const _bvec2& a, const bool b, const _bvec3& c);
+        explicit _xvec4(const _bvec2& a, const bool b, const _bvec4& c);
+        explicit _xvec4(const _bvec2& a, const _bvec2& b);
+        explicit _xvec4(const _bvec2& a, const _bvec3& b);
+        explicit _xvec4(const _bvec2& a, const _bvec4& b);
+        explicit _xvec4(const _bvec3& a, const bool b);
+        explicit _xvec4(const _bvec3& a, const _bvec2& b);
+        explicit _xvec4(const _bvec3& a, const _bvec3& b);
+        explicit _xvec4(const _bvec3& a, const _bvec4& b);
+        explicit _xvec4(const _bvec4& a);
+
+        // Unary updatable operators
+        _xvec4<T>& operator= (const _xvec4<T>& x);
+	    _xvec4<T>& operator+=(const T s);
+	    _xvec4<T>& operator+=(const _xvec4<T>& v);
+	    _xvec4<T>& operator-=(const T s);
+	    _xvec4<T>& operator-=(const _xvec4<T>& v);
+	    _xvec4<T>& operator*=(const T s);
+	    _xvec4<T>& operator*=(const _xvec4<T>& v);
+	    _xvec4<T>& operator/=(const T s);
+	    _xvec4<T>& operator/=(const _xvec4<T>& v);
+	    _xvec4<T>& operator++();
+        _xvec4<T>& operator--();
+    };
+
+    // Binary operators
+	// operator+
+    template <typename T>
+	_xvec4<T> operator+ (const _xvec4<T>& v, const T s);
+
+    template <typename T>
+    _xvec4<T> operator+ (const T s, const _xvec4<T>& v);
+
+    template <typename T>
+    _xvec4<T> operator+ (const _xvec4<T>& v1, const _xvec4<T>& v2);
+    
+    template <typename T>
+	_xvec4<T> operator+ (const _xref4<T>& v, const T s);
+
+    template <typename T>
+    _xvec4<T> operator+ (const T s, const _xref4<T>& v);
+    
+	template <typename T>
+    _xvec4<T> operator+ (const _xref4<T>& v1, const _xref4<T>& v2);
+
+	template <typename T>
+    _xvec4<T> operator+ (const _xvec4<T>& v1, const _xref4<T>& v2);
+
+	template <typename T>
+    _xvec4<T> operator+ (const _xref4<T>& v1, const _xvec4<T>& v2);
+
+	// operator-
+    template <typename T>
+	_xvec4<T> operator- (const _xvec4<T>& v, const T s);
+
+    template <typename T>
+    _xvec4<T> operator- (const T s, const _xvec4<T>& v);
+
+    template <typename T>
+    _xvec4<T> operator- (const _xvec4<T>& v1, const _xvec4<T>& v2);
+
+    template <typename T>
+	_xvec4<T> operator- (const _xref4<T>& v, const T s);
+
+    template <typename T>
+    _xvec4<T> operator- (const T s, const _xref4<T>& v);
+    
+	template <typename T>
+    _xvec4<T> operator- (const _xref4<T>& v1, const _xref4<T>& v2);
+
+	template <typename T>
+    _xvec4<T> operator- (const _xvec4<T>& v1, const _xref4<T>& v2);
+
+	template <typename T>
+    _xvec4<T> operator- (const _xref4<T>& v1, const _xvec4<T>& v2);
+
+	// operator*
+    template <typename T>
+    _xvec4<T> operator* (const _xvec4<T>& v, const T s);
+
+    template <typename T>
+    _xvec4<T> operator* (const T s, const _xvec4<T>& v);
+
+    template <typename T>
+    _xvec4<T> operator* (const _xvec4<T>& v1, const _xvec4<T>& v2);
+
+    template <typename T>
+	_xvec4<T> operator* (const _xref4<T>& v, const T s);
+
+    template <typename T>
+    _xvec4<T> operator* (const T s, const _xref4<T>& v);
+    
+	template <typename T>
+    _xvec4<T> operator* (const _xref4<T>& v1, const _xref4<T>& v2);
+
+	template <typename T>
+    _xvec4<T> operator* (const _xvec4<T>& v1, const _xref4<T>& v2);
+
+	template <typename T>
+    _xvec4<T> operator* (const _xref4<T>& v1, const _xvec4<T>& v2);
+
+	// operator/
+    template <typename T>
+    _xvec4<T> operator/ (const _xvec4<T>& v, const T s);
+
+    template <typename T>
+    _xvec4<T> operator/ (const T s, const _xvec4<T>& v);
+
+    template <typename T>
+    _xvec4<T> operator/ (const _xvec4<T>& v1, const _xvec4<T>& v2);
+
+    template <typename T>
+	_xvec4<T> operator/ (const _xref4<T>& v, const T s);
+
+    template <typename T>
+    _xvec4<T> operator/ (const T s, const _xref4<T>& v);
+    
+	template <typename T>
+    _xvec4<T> operator/ (const _xref4<T>& v1, const _xref4<T>& v2);
+
+	template <typename T>
+    _xvec4<T> operator/ (const _xvec4<T>& v1, const _xref4<T>& v2);
+
+	template <typename T>
+    _xvec4<T> operator/ (const _xref4<T>& v1, const _xvec4<T>& v2);
+
+    // Unary constant operators
+    template <typename T> 
+    const _xvec4<T> operator- (const _xvec4<T>& v);
+
+    template <typename T> 
+    const _xvec4<T> operator-- (const _xvec4<T>& v, int);
+
+    template <typename T> 
+    const _xvec4<T> operator++ (const _xvec4<T>& v, int);
+
+} //namespace detail
+} //namespace glm
+
+#endif//__glm_core_xvec4_h__

+ 1242 - 0
experimental/sse/glm/core/_xvec4.inl

@@ -0,0 +1,1242 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2008 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2006-04-27
+// Updated : 2007-01-19
+// Licence : This source is under GNU LGPL licence
+// File    : glm/core/_xvec4.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef __glm_core_xvec4_inl__
+#define __glm_core_xvec4_inl__
+
+#include "./_xvec2.h"
+#include "./_bvec2.h"
+#include "./_xvec3.h"
+#include "./_bvec3.h"
+#include "./_xvec4.h"
+#include "./_bvec4.h"
+#include "./_swizzle.inl"
+
+namespace glm{
+namespace detail{
+
+    // Common constructors
+    template <typename T> 
+    inline _xvec4<T>::_xvec4() :
+		_cvec4<XVEC4_INST>(T(0), T(0), T(0), T(0))
+    {}
+
+    template <typename T> 
+    inline _xvec4<T>::_xvec4(const _xvec4<T>& v) :
+		_cvec4<XVEC4_INST>(v.x, v.y, v.z, v.w)
+    {}
+
+    // Swizzle constructors
+    template <typename T> 
+    inline _xvec4<T>::_xvec4(const _xref4<T>& r) :
+		_cvec4<XVEC4_INST>(r.x, r.y, r.z, r.w)
+    {}
+
+    template <typename T> 
+    inline _xvec4<T>::_xvec4(const _xvec4_base(T)& b) :
+		_cvec4<XVEC4_INST>(b.x, b.y, b.z, b.w)
+    {}
+
+    // T constructors
+    template <typename T> 
+    inline _xvec4<T>::_xvec4(const T s) :
+		_cvec4<XVEC4_INST>(s, s, s, s)
+    {}
+
+    template <typename T> 
+    inline _xvec4<T>::_xvec4(const T x, const T y, const T z, const T w) :
+		_cvec4<XVEC4_INST>(x, y, z, w)
+    {}
+
+    template <typename T> 
+    inline _xvec4<T>::_xvec4(const T s1, const T s2, const T s3, const _xvec2<T>& v) :
+		_cvec4<XVEC4_INST>(s1, s2, s3, v.x)
+    {}
+
+    template <typename T> 
+    inline _xvec4<T>::_xvec4(const T s1, const T s2, const T s3, const _xvec3<T>& v) :
+		_cvec4<XVEC4_INST>(s1, s2, s3, v.x)
+    {}
+
+    template <typename T> 
+    inline _xvec4<T>::_xvec4(const T s1, const T s2, const T s3, const _xvec4<T>& v) :
+		_cvec4<XVEC4_INST>(s1, s2, s3, v.x)
+    {}
+
+    template <typename T> 
+    inline _xvec4<T>::_xvec4(const T s1, const T s2, const _xvec2<T>& v) :
+		_cvec4<XVEC4_INST>(s1, s2, v.x, v.y)
+    {}
+
+    template <typename T> 
+    inline _xvec4<T>::_xvec4(const T s1, const T s2, const _xvec3<T>& v) :
+		_cvec4<XVEC4_INST>(s1, s2, v.x, v.y)
+    {}
+
+    template <typename T> 
+    inline _xvec4<T>::_xvec4(const T s1, const T s2, const _xvec4<T>& v) :
+		_cvec4<XVEC4_INST>(s1, s2, v.x, v.y)
+    {}
+
+    template <typename T> 
+    inline _xvec4<T>::_xvec4(const T s1, const _xvec2<T>& v, const T s2) :
+		_cvec4<XVEC4_INST>(s1, v.x, v.y, s2)
+    {}
+
+    template <typename T> 
+    inline _xvec4<T>::_xvec4(const T s, const _xvec2<T>& v1, const _xvec2<T>& v2) :
+		_cvec4<XVEC4_INST>(s, v1.x, v1.y, v2.x)
+    {}
+
+    template <typename T> 
+    inline _xvec4<T>::_xvec4(const T s, const _xvec2<T>& v1, const _xvec3<T>& v2) :
+		_cvec4<XVEC4_INST>(s, v1.x, v1.y, v2.x)
+    {}
+
+    template <typename T> 
+    inline _xvec4<T>::_xvec4(const T s, const _xvec2<T>& v1, const _xvec4<T>& v2) :
+		_cvec4<XVEC4_INST>(s, v1.x, v1.y, v2.x)
+    {}
+
+    template <typename T> 
+    inline _xvec4<T>::_xvec4(const T s, const _xvec3<T>& v) :
+		_cvec4<XVEC4_INST>(s, v.x, v.y, v.z)
+    {}
+
+    template <typename T> 
+    inline _xvec4<T>::_xvec4(const T s, const _xvec4<T>& v) :
+		_cvec4<XVEC4_INST>(s, v.x, v.y, v.z)
+    {}
+
+    template <typename T> 
+    inline _xvec4<T>::_xvec4(const _xvec2<T>& v, const T s1, const T s2) :
+		_cvec4<XVEC4_INST>(v.x, v.y, s1, s2)
+    {}
+
+    template <typename T> 
+    inline _xvec4<T>::_xvec4(const _xvec2<T>& v1, const T s, const _xvec2<T>& v2) :
+		_cvec4<XVEC4_INST>(v1.x, v1.y, s, v2.x)
+    {}
+
+    template <typename T> 
+    inline _xvec4<T>::_xvec4(const _xvec2<T>& v1, const T s, const _xvec3<T>& v2) :
+		_cvec4<XVEC4_INST>(v1.x, v1.y, s, v2.x)
+    {}
+
+    template <typename T> 
+    inline _xvec4<T>::_xvec4(const _xvec2<T>& v1, const T s, const _xvec4<T>& v2) :
+		_cvec4<XVEC4_INST>(v1.x, v1.y, s, v2.x)
+    {}
+
+    template <typename T> 
+    inline _xvec4<T>::_xvec4(const _xvec2<T>& v1, const _xvec2<T>& v2) :
+		_cvec4<XVEC4_INST>(v1.x, v1.y, v2.x, v2.y)
+    {}
+
+    template <typename T> 
+    inline _xvec4<T>::_xvec4(const _xvec2<T>& v1, const _xvec3<T>& v2) :
+		_cvec4<XVEC4_INST>(v1.x, v1.y, v2.x, v2.y)
+    {}
+
+    template <typename T> 
+    inline _xvec4<T>::_xvec4(const _xvec2<T>& v1, const _xvec4<T>& v2) :
+		_cvec4<XVEC4_INST>(v1.x, v1.y, v2.x, v2.y)
+    {}
+
+    template <typename T> 
+    inline _xvec4<T>::_xvec4(const _xvec3<T>& v, const T s) :
+		_cvec4<XVEC4_INST>(v.x, v.y, v.z, s)
+    {}
+
+    template <typename T> 
+    inline _xvec4<T>::_xvec4(const _xvec3<T>& v1, const _xvec2<T>& v2) :
+		_cvec4<XVEC4_INST>(v1.x, v1.y, v1.z, v2.x)
+    {}
+
+    template <typename T> 
+    inline _xvec4<T>::_xvec4(const _xvec3<T>& v1, const _xvec3<T>& v2) :
+		_cvec4<XVEC4_INST>(v1.x, v1.y, v1.z, v2.x)
+    {}
+
+    template <typename T> 
+    inline _xvec4<T>::_xvec4(const _xvec3<T>& v1, const _xvec4<T>& v2) :
+		_cvec4<XVEC4_INST>(v1.x, v1.y, v1.z, v2.x)
+    {}
+
+    // U constructors
+    template <typename T> 
+    template <typename U> 
+    inline _xvec4<T>::_xvec4(const U s) :
+		_cvec4<XVEC4_INST>(T(s), T(s), T(s), T(s))
+    {}
+
+    template <typename T> 
+    template <typename U> 
+    inline _xvec4<T>::_xvec4(const U s1, const U s2, const U s3, const U s4) :
+		_cvec4<XVEC4_INST>(T(s1), T(s2), T(s3), T(s4))
+    {}
+
+    template <typename T> 
+    template <typename U> 
+    inline _xvec4<T>::_xvec4(const U s1, const U s2, const U s3, const _xvec2<U>& v) :
+		_cvec4<XVEC4_INST>(T(s1), T(s2), T(s3), T(v.x))
+    {}
+
+    template <typename T> 
+    template <typename U> 
+    inline _xvec4<T>::_xvec4(const U s1, const U s2, const U s3, const _xvec3<U>& v) :
+		_cvec4<XVEC4_INST>(T(s1), T(s2), T(s3), T(v.x))
+    {}
+
+    template <typename T> 
+    template <typename U> 
+    inline _xvec4<T>::_xvec4(const U s1, const U s2, const U s3, const _xvec4<U>& v) :
+		_cvec4<XVEC4_INST>(T(s1), T(s2), T(s3), T(v.x))
+    {}
+
+    template <typename T> 
+    template <typename U> 
+    inline _xvec4<T>::_xvec4(const U s1, const U s2, const _xvec2<U>& v) :
+		_cvec4<XVEC4_INST>(T(s1), T(s2), T(v.x), T(v.y))
+    {}
+
+    template <typename T> 
+    template <typename U> 
+    inline _xvec4<T>::_xvec4(const U s1, const U s2, const _xvec3<U>& v) :
+		_cvec4<XVEC4_INST>(T(s1), T(s2), T(v.x), T(v.y))
+    {}
+
+    template <typename T> 
+    template <typename U> 
+    inline _xvec4<T>::_xvec4(const U s1, const U s2, const _xvec4<U>& v) :
+		_cvec4<XVEC4_INST>(T(s1), T(s2), T(v.x), T(v.y))
+    {}
+
+    template <typename T> 
+    template <typename U> 
+    inline _xvec4<T>::_xvec4(const U s1, const _xvec2<U>& v, const U s2) :
+		_cvec4<XVEC4_INST>(T(s1), T(v.x), T(v.y), T(s2))
+    {}
+
+    template <typename T> 
+    template <typename U> 
+    inline _xvec4<T>::_xvec4(const U s, const _xvec2<U>& v1, const _xvec2<U>& v2) :
+		_cvec4<XVEC4_INST>(T(s), T(v1.x), T(v1.y), T(v2.x))
+    {}
+
+    template <typename T> 
+    template <typename U> 
+    inline _xvec4<T>::_xvec4(const U s, const _xvec2<U>& v1, const _xvec3<U>& v2) :
+		_cvec4<XVEC4_INST>(T(s), T(v1.x), T(v1.y), T(v2.x))
+    {}
+
+    template <typename T> 
+    template <typename U> 
+    inline _xvec4<T>::_xvec4(const U s, const _xvec2<U>& v1, const _xvec4<U>& v2) :
+		_cvec4<XVEC4_INST>(T(s), T(v1.x), T(v1.y), T(v2.x))
+    {}
+
+    template <typename T> 
+    template <typename U> 
+    inline _xvec4<T>::_xvec4(const U s, const _xvec3<U>& v) :
+		_cvec4<XVEC4_INST>(T(s), T(v.x), T(v.y), T(v.z))
+    {}
+
+    template <typename T> 
+    template <typename U> 
+    inline _xvec4<T>::_xvec4(const U s, const _xvec4<U>& v) :
+		_cvec4<XVEC4_INST>(T(s), T(v.x), T(v.y), T(v.z))
+    {}
+
+    template <typename T> 
+    template <typename U> 
+    inline _xvec4<T>::_xvec4(const _xvec2<U>& v, const U s1, const U s2) :
+		_cvec4<XVEC4_INST>(T(v.x), T(v.y), T(s1), T(s2))
+    {}
+
+    template <typename T> 
+    template <typename U> 
+    inline _xvec4<T>::_xvec4(const _xvec2<U>& v1, const U s, const _xvec2<U>& v2) :
+		_cvec4<XVEC4_INST>(T(v1.x), T(v1.y), T(s), T(v2.x))
+    {}
+
+    template <typename T> 
+    template <typename U> 
+    inline _xvec4<T>::_xvec4(const _xvec2<U>& v1, const U s, const _xvec3<U>& v2) :
+		_cvec4<XVEC4_INST>(T(v1.x), T(v1.y), T(s), T(v2.x))
+    {}
+
+    template <typename T> 
+    template <typename U> 
+    inline _xvec4<T>::_xvec4(const _xvec2<U>& v1, const U s, const _xvec4<U>& v2) :
+		_cvec4<XVEC4_INST>(T(v1.x), T(v1.y), T(s), T(v2.x))
+    {}
+
+    template <typename T> 
+    template <typename U> 
+    inline _xvec4<T>::_xvec4(const _xvec2<U>& v1, const _xvec2<U>& v2) :
+		_cvec4<XVEC4_INST>(T(v1.x), T(v1.y), T(v2.x), T(v2.y))
+    {}
+
+    template <typename T> 
+    template <typename U> 
+    inline _xvec4<T>::_xvec4(const _xvec2<U>& v1, const _xvec3<U>& v2) :
+		_cvec4<XVEC4_INST>(T(v1.x), T(v1.y), T(v2.x), T(v2.y))
+    {}
+
+    template <typename T> 
+    template <typename U> 
+    inline _xvec4<T>::_xvec4(const _xvec2<U>& v1, const _xvec4<U>& v2) :
+		_cvec4<XVEC4_INST>(T(v1.x), T(v1.y), T(v2.x), T(v2.y))
+    {}
+
+    template <typename T> 
+    template <typename U> 
+    inline _xvec4<T>::_xvec4(const _xvec3<U>& v, const U s) :
+		_cvec4<XVEC4_INST>(T(v.x), T(v.y), T(v.z), T(s))
+    {}
+
+    template <typename T> 
+    template <typename U> 
+    inline _xvec4<T>::_xvec4(const _xvec3<U>& v1, const _xvec2<U>& v2) :
+		_cvec4<XVEC4_INST>(T(v1.x), T(v1.y), T(v1.z), T(v2.x))
+    {}
+
+    template <typename T> 
+    template <typename U> 
+    inline _xvec4<T>::_xvec4(const _xvec3<U>& v1, const _xvec3<U>& v2) :
+		_cvec4<XVEC4_INST>(T(v1.x), T(v1.y), T(v1.z), T(v2.x))
+    {}
+
+    template <typename T> 
+    template <typename U> 
+    inline _xvec4<T>::_xvec4(const _xvec3<U>& v1, const _xvec4<U>& v2) :
+		_cvec4<XVEC4_INST>(T(v1.x), T(v1.y), T(v1.z), T(v2.x))
+    {}
+
+    template <typename T> 
+    template <typename U> 
+    inline _xvec4<T>::_xvec4(const _xvec4<U>& v) :
+		_cvec4<XVEC4_INST>(T(v.x), T(v.y), T(v.z), T(v.w))
+    {}
+
+    // Bool constructors
+	template <typename T>
+	inline _xvec4<T>::_xvec4(const bool x) :
+	   _cvec4<XVEC4_INST>(T(x), T(x), T(x), T(x))
+	{}
+
+    template <typename T> 
+    inline _xvec4<T>::_xvec4(const bool x, const bool y, const bool z, const bool w) :
+        _cvec4<XVEC4_INST>(T(x), T(y), T(z), T(w))
+    {}
+
+    template <typename T> 
+    inline _xvec4<T>::_xvec4(const bool s1, const bool s2, const bool s3, const _bvec2& v) :
+		_cvec4<XVEC4_INST>(T(s1), T(s2), T(s3), T(v.x))
+    {}
+
+    template <typename T> 
+    inline _xvec4<T>::_xvec4(const bool s1, const bool s2, const bool s3, const _bvec3& v) :
+		_cvec4<XVEC4_INST>(T(s1), T(s2), T(s3), T(v.x))
+    {}
+
+    template <typename T> 
+    inline _xvec4<T>::_xvec4(const bool s1, const bool s2, const bool s3, const _bvec4& v) :
+		_cvec4<XVEC4_INST>(T(s1), T(s2), T(s3), T(v.x))
+    {}
+
+    template <typename T> 
+    inline _xvec4<T>::_xvec4(const bool s1, const bool s2, const _bvec2& v) :
+		_cvec4<XVEC4_INST>(T(s1), T(s2), T(v.x), T(v.y))
+    {}
+
+    template <typename T> 
+    inline _xvec4<T>::_xvec4(const bool s1, const bool s2, const _bvec3& v) :
+		_cvec4<XVEC4_INST>(T(s1), T(s2), T(v.x), T(v.y))
+    {}
+
+    template <typename T> 
+    inline _xvec4<T>::_xvec4(const bool s1, const bool s2, const _bvec4& v) :
+		_cvec4<XVEC4_INST>(T(s1), T(s2), T(v.x), T(v.y))
+    {}
+
+    template <typename T> 
+    inline _xvec4<T>::_xvec4(const bool s1, const _bvec2& v, const bool s2) :
+		_cvec4<XVEC4_INST>(T(s1), T(v.x), T(v.y), T(s2))
+    {}
+
+    template <typename T> 
+    inline _xvec4<T>::_xvec4(const bool s, const _bvec2& v1, const _bvec2& v2) :
+		_cvec4<XVEC4_INST>(T(s), T(v1.x), T(v1.y), T(v2.x))
+    {}
+
+    template <typename T> 
+    inline _xvec4<T>::_xvec4(const bool s, const _bvec2& v1, const _bvec3& v2) :
+		_cvec4<XVEC4_INST>(T(s), T(v1.x), T(v1.y), T(v2.x))
+    {}
+
+    template <typename T> 
+    inline _xvec4<T>::_xvec4(const bool s, const _bvec2& v1, const _bvec4& v2) :
+		_cvec4<XVEC4_INST>(T(s), T(v1.x), T(v1.y), T(v2.x))
+    {}
+
+    template <typename T> 
+    inline _xvec4<T>::_xvec4(const bool s, const _bvec3& v) :
+		_cvec4<XVEC4_INST>(T(s), T(v.x), T(v.y), T(v.z))
+    {}
+
+    template <typename T> 
+    inline _xvec4<T>::_xvec4(const bool s, const _bvec4& v) :
+		_cvec4<XVEC4_INST>(T(s), T(v.x), T(v.y), T(v.z))
+    {}
+
+    template <typename T> 
+    inline _xvec4<T>::_xvec4(const _bvec2& v, const bool s1, const bool s2) :
+		_cvec4<XVEC4_INST>(T(v.x), T(v.y), T(s1), T(s2))
+    {}
+
+    template <typename T> 
+    inline _xvec4<T>::_xvec4(const _bvec2& v1, const bool s, const _bvec2& v2) :
+		_cvec4<XVEC4_INST>(T(v1.x), T(v1.y), T(s), T(v2.x))
+    {}
+
+    template <typename T> 
+    inline _xvec4<T>::_xvec4(const _bvec2& v1, const bool s, const _bvec3& v2) :
+		_cvec4<XVEC4_INST>(T(v1.x), T(v1.y), T(s), T(v2.x))
+    {}
+
+    template <typename T> 
+    inline _xvec4<T>::_xvec4(const _bvec2& v1, const bool s, const _bvec4& v2) :
+		_cvec4<XVEC4_INST>(T(v1.x), T(v1.y), T(s), T(v2.x))
+    {}
+
+    template <typename T> 
+    inline _xvec4<T>::_xvec4(const _bvec2& v1, const _bvec2& v2) :
+		_cvec4<XVEC4_INST>(T(v1.x), T(v1.y), T(v2.x), T(v2.y))
+    {}
+
+    template <typename T> 
+    inline _xvec4<T>::_xvec4(const _bvec2& v1, const _bvec3& v2) :
+		_cvec4<XVEC4_INST>(T(v1.x), T(v1.y), T(v2.x), T(v2.y))
+    {}
+
+    template <typename T> 
+    inline _xvec4<T>::_xvec4(const _bvec2& v1, const _bvec4& v2) :
+		_cvec4<XVEC4_INST>(T(v1.x), T(v1.y), T(v2.x), T(v2.y))
+    {}
+
+    template <typename T> 
+    inline _xvec4<T>::_xvec4(const _bvec3& v, const bool s) :
+		_cvec4<XVEC4_INST>(T(v.x), T(v.y), T(v.z), T(s))
+    {}
+
+    template <typename T> 
+    inline _xvec4<T>::_xvec4(const _bvec3& v1, const _bvec2& v2) :
+		_cvec4<XVEC4_INST>(T(v1.x), T(v1.y), T(v1.z), T(v2.x))
+    {}
+
+    template <typename T> 
+    inline _xvec4<T>::_xvec4(const _bvec3& v1, const _bvec3& v2) :
+		_cvec4<XVEC4_INST>(T(v1.x), T(v1.y), T(v1.z), T(v2.x))
+    {}
+
+    template <typename T> 
+    inline _xvec4<T>::_xvec4(const _bvec3& v1, const _bvec4& v2) :
+		_cvec4<XVEC4_INST>(T(v1.x), T(v1.y), T(v1.z), T(v2.x))
+    {}
+
+    template <typename T> 
+    inline _xvec4<T>::_xvec4(const _bvec4& v) :
+		_cvec4<XVEC4_INST>(T(v.x), T(v.y), T(v.z), T(v.w))
+    {}
+
+    // vec4 and ivec4 operators definitions
+
+    // This function shouldn't required but it seems that VC7.1 have an optimisation bug if this operator wasn't declared
+    template <typename T> 
+    inline _xvec4<T>& _xvec4<T>::operator=(const _xvec4<T>& x)
+    {
+        this->x = x.x;
+        this->y = x.y;
+        this->z = x.z;
+        this->w = x.w;
+        return *this;
+    }
+
+    template <typename T> 
+    inline _xvec4<T>& _xvec4<T>::operator+= (const T s)
+    {
+	    this->x += s;
+	    this->y += s;
+        this->z += s;
+        this->w += s;
+	    return *this;
+    }
+
+    template <typename T> 
+    inline _xvec4<T>& _xvec4<T>::operator+=(const _xvec4<T> & v)
+    {
+	    this->x += v.x;
+	    this->y += v.y;
+        this->z += v.z;
+        this->w += v.w;
+	    return *this;
+    }
+
+    template <typename T> 
+    inline _xvec4<T>& _xvec4<T>::operator-= (const T s)
+    {
+	    this->x -= s;
+	    this->y -= s;
+        this->z -= s;
+        this->w -= s;
+	    return *this;
+    }
+
+    template <typename T> 
+    inline _xvec4<T>& _xvec4<T>::operator-=(const _xvec4<T> & v)
+    {
+	    this->x -= v.x;
+	    this->y -= v.y;
+        this->z -= v.z;
+        this->w -= v.w;
+	    return *this;
+    }
+
+    template <typename T> 
+    inline _xvec4<T>& _xvec4<T>::operator*=(const T s)
+    {
+	    this->x *= s;
+	    this->y *= s;
+        this->z *= s;
+        this->w *= s;
+	    return *this;
+    }
+
+    template <typename T> 
+    inline _xvec4<T>& _xvec4<T>::operator*= (const _xvec4<T> & v)
+    {
+	    this->x *= v.x;
+	    this->y *= v.y;
+        this->z *= v.z;
+        this->w *= v.w;
+	    return *this;
+    }
+
+    template <typename T> 
+    inline _xvec4<T>& _xvec4<T>::operator/=(const T s)
+    {
+	    this->x /= s;
+	    this->y /= s;
+        this->z /= s;
+        this->w /= s;
+	    return *this;
+    }
+
+    template <typename T> 
+    inline _xvec4<T>& _xvec4<T>::operator/= (const _xvec4<T> & v)
+    {
+	    this->x /= v.x;
+	    this->y /= v.y;
+        this->z /= v.z;
+        this->w /= v.w;
+	    return *this;
+    }
+
+    template <typename T> 
+    inline _xvec4<T>& _xvec4<T>::operator++ ()
+    {
+	    ++this->x;
+	    ++this->y;
+        ++this->z;
+		++this->w;
+	    return *this;
+    }
+
+    template <typename T> 
+    inline _xvec4<T>& _xvec4<T>::operator-- ()
+    {
+	    --this->x;
+	    --this->y;
+        --this->z;
+		--this->w;
+	    return *this;
+    }
+
+    // Unary constant operators
+    template <typename T> 
+    inline const _xvec4<T> operator- (const _xvec4<T>& v)
+    {
+        return _xvec4<T>(
+            -v.x, 
+            -v.y,
+            -v.z,
+            -v.w);
+    }
+
+    template <typename T> 
+    inline const _xvec4<T> operator++ (const _xvec4<T>& v, int)
+    {
+        return _xvec4<T>(
+            v.x + T(1), 
+            v.y + T(1),
+            v.z + T(1),
+            v.w + T(1));
+    }
+
+    template <typename T> 
+    inline const _xvec4<T> operator-- (const _xvec4<T>& v, int)
+    {
+        return _xvec4<T>(
+            v.x - T(1), 
+            v.y - T(1),
+            v.z - T(1),
+            v.w - T(1));
+    }
+/*
+	template <typename T> 
+    inline _xvec4<T>& operator%=(const T s)
+	{
+	    this->x %= s;
+	    this->y %= s;
+		this->z %= s;
+		this->w %= s;
+	    return *this;
+	}
+
+	template <typename T> 
+    inline _xvec4<T>& operator%=(const _xvec4<T>& v)
+	{
+	    this->x %= v.x;
+	    this->y %= v.y;
+		this->z %= v.z;
+		this->w %= v.w;
+	    return *this;
+	}
+
+	template <typename T> 
+	inline _xvec4<T>& operator&=(const T s)
+	{
+	    this->x &= s;
+	    this->y &= s;
+		this->z &= s;
+		this->w &= s;
+	    return *this;
+	}
+
+    template <typename T> 
+	inline _xvec4<T>& operator&=(const _xvec4<T>& v)
+	{
+	    this->x &= v.x;
+	    this->y &= v.y;
+		this->z &= v.z;
+		this->w &= v.w;
+	    return *this;
+	}
+    
+    template <typename T> 
+	inline _xvec4<T>& operator|=(const T s)
+	{
+	    this->x |= s;
+	    this->y |= s;
+		this->z |= s;
+		this->w |= s;
+	    return *this;
+	}
+    
+    template <typename T> 
+	inline _xvec4<T>& operator|=(const _xvec4<T>& v)
+	{
+	    this->x |= v.x;
+	    this->y |= v.y;
+		this->z |= v.z;
+		this->w |= v.w;
+	    return *this;
+	}
+    
+    template <typename T> 
+	inline _xvec4<T>& operator^=(const T s)
+	{
+	    this->x ^= s;
+	    this->y ^= s;
+		this->z ^= s;
+		this->w ^= s;
+	    return *this;
+	}
+    
+    template <typename T> 
+	inline _xvec4<T>& operator^=(const _xvec4<T>& v)
+	{
+	    this->x ^= v.x;
+	    this->y ^= v.y;
+		this->z ^= v.z;
+		this->w ^= v.w;
+	    return *this;
+	}
+    
+    template <typename T> 
+	inline _xvec4<T>& operator<<=(const T s)
+	{
+	    this->x <<= s;
+	    this->y <<= s;
+		this->z <<= s;
+		this->w <<= s;
+	    return *this;
+	}
+    
+    template <typename T> 
+	inline _xvec4<T>& operator<<=(const _xvec4<T>& v)
+	{
+	    this->x <<= v.x;
+	    this->y <<= v.y;
+		this->z <<= v.z;
+		this->w <<= v.w;
+	    return *this;
+	}
+    
+    template <typename T> 
+	inline _xvec4<T>& operator>>=(const T s)
+	{
+	    this->x >>= s;
+	    this->y >>= s;
+		this->z >>= s;
+		this->w >>= s;
+	    return *this;
+	}
+    
+    template <typename T> 
+	inline _xvec4<T>& operator>>=(const _xvec4<T>& v)
+	{
+	    this->x >>= v.x;
+	    this->y >>= v.y;
+		this->z >>= v.z;
+		this->w >>= v.w;
+	    return *this;
+	}
+
+	// Bit operators
+    template <typename T>
+	inline _xvec4<T> operator% (const _xvec4<T>& v, const T s)
+	{
+	    return _xvec4<T>(
+		    v.x % s,
+		    v.y % s,
+			v.z % s,
+			v.w % s);
+	}
+
+    template <typename T>
+    inline _xvec4<T> operator% (const T s, const _xvec4<T>& v)
+	{
+	    return _xvec4<T>(
+		    s % v.x,
+		    s % v.y,
+			s % v.z,
+			s % v.w);
+	}
+
+    template <typename T>
+    inline _xvec4<T> operator% (const _xvec4<T>& v1, const _xvec4<T>& v2)
+	{
+	    return _xvec4<T>(
+		    v1.x % v2.x,
+		    v1.y % v2.y,
+			v1.z % v2.z,
+			v1.w % v2.w);
+	}
+
+    template <typename T>
+	inline _xvec4<T> operator& (const _xvec4<T>& v, const T s)
+	{
+	    return _xvec4<T>(
+		    v.x & s,
+		    v.y & s,
+			v.z & s,
+			v.w & s);
+	}
+
+    template <typename T>
+    inline _xvec4<T> operator& (const T s, const _xvec4<T>& v)
+	{
+	    return _xvec4<T>(
+		    s & v.x,
+		    s & v.y,
+			s & v.z,
+			s & v.w);
+	}
+
+    template <typename T>
+    inline _xvec4<T> operator& (const _xvec4<T>& v1, const _xvec4<T>& v2)
+	{
+	    return _xvec2<T>(
+		    v1.x & v2.x,
+		    v1.y & v2.y,
+			v1.z & v2.z,
+			v1.w & v2.w);
+	}
+
+    template <typename T>
+	inline _xvec4<T> operator| (const _xvec4<T>& v, const T s)
+	{
+	    return _xvec4<T>(
+		    v.x | s,
+		    v.y | s,
+			v.z | s,
+			v.w | s);
+	}
+
+    template <typename T>
+    inline _xvec4<T> operator| (const T s, const _xvec4<T>& v)
+	{
+	    return _xvec4<T>(
+		    s | v.x,
+		    s | v.y,
+			s | v.z,
+			s | v.w);
+	}
+
+    template <typename T>
+    inline _xvec4<T> operator| (const _xvec4<T>& v1, const _xvec4<T>& v2)
+	{
+	    return _xvec4<T>(
+		    v1.x | v2.x,
+		    v1.y | v2.y,
+			v1.z | v2.z,
+			v1.w | v2.w);
+	}
+	
+    template <typename T>
+	inline _xvec4<T> operator^ (const _xvec4<T>& v, const T s)
+	{
+	    return _xvec4<T>(
+		    v.x ^ s,
+		    v.y ^ s,
+			v.z ^ s,
+			v.w ^ s);
+	}
+
+    template <typename T>
+    inline _xvec4<T> operator^ (const T s, const _xvec4<T>& v)
+	{
+	    return _xvec4<T>(
+		    s ^ v.x,
+		    s ^ v.y,
+			s ^ v.z,
+			s ^ v.w);
+	}
+
+    template <typename T>
+    inline _xvec4<T> operator^ (const _xvec4<T>& v1, const _xvec4<T>& v2)
+	{
+	    return _xvec4<T>(
+		    v1.x ^ v2.x,
+		    v1.y ^ v2.y,
+			v1.z ^ v2.z,
+			v1.w ^ v2.w);
+	}
+
+    template <typename T>
+	inline _xvec4<T> operator<< (const _xvec4<T>& v, const T s)
+	{
+	    return _xvec4<T>(
+		    v.x << s,
+		    v.y << s,
+			v.z << s,
+			v.w << s);
+	}
+
+    template <typename T>
+    inline _xvec4<T> operator<< (const T s, const _xvec4<T>& v)
+	{
+	    return _xvec4<T>(
+		    s << v.x,
+		    s << v.y,
+			s << v.z,
+			s << v.w);
+	}
+
+    template <typename T>
+    inline _xvec4<T> operator<< (const _xvec4<T>& v1, const _xvec4<T>& v2)
+	{
+	    return _xvec4<T>(
+		    v1.x << v2.x,
+		    v1.y << v2.y,
+			v1.z << v2.z,
+			v1.w << v2.w);
+	}
+
+	template <typename T>
+	inline _xvec4<T> operator>> (const _xvec4<T>& v, const T s)
+	{
+	    return _xvec4<T>(
+		    v.x >> s,
+		    v.y >> s,
+			v.z >> s,
+			v.w >> s);
+	}
+
+    template <typename T>
+    inline _xvec4<T> operator>> (const T s, const _xvec4<T>& v)
+	{
+	    return _xvec4<T>(
+		    s >> v.x,
+		    s >> v.y,
+			s >> v.z,
+			s >> v.w);
+	}
+
+    template <typename T>
+    inline _xvec4<T> operator>> (const _xvec4<T>& v1, const _xvec4<T>& v2)
+	{
+	    return _xvec4<T>(
+		    v1.x >> v2.x,
+		    v1.y >> v2.y,
+			v1.z >> v2.z,
+			v1.w >> v2.w);
+	}
+
+    template <typename T> 
+    inline const _xvec4<T> operator~ (const _xvec4<T>& v)
+	{
+	    return _xvec4<T>(
+		    ~v.x,
+		    ~v.y,
+			~v.z,
+			~v.w);
+	}
+*/
+    // Binary operators
+	//operator+
+    template <typename T>
+	inline _xvec4<T> operator+ (const _xvec4<T>& v, const T s)
+    {
+	    return _xvec4<T>(
+		    v.x + s,
+		    v.y + s,
+            v.z + s,
+            v.w + s);
+    }
+
+    template <typename T>
+    inline _xvec4<T> operator+ (const T s, const _xvec4<T>& v)
+    {
+	    return _xvec4<T>(
+		    v.x + s,
+		    v.y + s,
+            v.z + s,
+            v.w + s);
+    }
+
+    template <typename T>
+    inline _xvec4<T> operator+ (const _xvec4<T>& v1, const _xvec4<T>& v2)
+    {
+	    return _xvec4<T>(
+		    v1.x + v2.x,
+		    v1.y + v2.y,
+            v1.z + v2.z,
+            v1.w + v2.w);
+    }
+    
+    template <typename T>
+	inline _xvec4<T> operator+ (const _xref4<T>& v, const T s)
+	{
+	    return _xvec4<T>(
+		    v.x + s,
+		    v.y + s,
+			v.z + s,
+			v.w + s);
+	}
+
+    template <typename T>
+    inline _xvec4<T> operator+ (const T s, const _xref4<T>& v)
+	{
+	    return _xvec4<T>(
+		    s + v.x,
+		    s + v.y,
+			s + v.z,
+			s + v.w);
+	}
+    
+	template <typename T>
+    inline _xvec4<T> operator+ (const _xref4<T>& v1, const _xref4<T>& v2)
+	{
+	    return _xvec4<T>(
+		    v1.x + v2.x,
+		    v1.y + v2.y,
+			v1.z + v2.z,
+			v1.w + v2.w);
+	}
+
+	template <typename T>
+    inline _xvec4<T> operator+ (const _xvec4<T>& v1, const _xref4<T>& v2)
+	{
+	    return _xvec4<T>(
+		    v1.x + v2.x,
+		    v1.y + v2.y,
+			v1.z + v2.z,
+			v1.w + v2.w);
+	}
+
+	template <typename T>
+    inline _xvec4<T> operator+ (const _xref4<T>& v1, const _xvec4<T>& v2)
+	{
+	    return _xvec4<T>(
+		    v1.x + v2.x,
+		    v1.y + v2.y,
+			v1.z + v2.z,
+			v1.w + v2.w);
+	}
+
+	//operator-
+    template <typename T>
+	inline _xvec4<T> operator- (const _xvec4<T>& v, const T s)
+    {
+	    return _xvec4<T>(
+		    v.x - s,
+		    v.y - s,
+            v.z - s,
+            v.w - s);
+    }
+
+    template <typename T>
+    inline _xvec4<T> operator- (const T s, const _xvec4<T>& v)
+    {
+	    return _xvec4<T>(
+		    s - v.x,
+		    s - v.y,
+            s - v.z,
+            s - v.w);
+    }
+
+    template <typename T>
+    inline _xvec4<T> operator- (const _xvec4<T>& v1, const _xvec4<T>& v2)
+    {
+	    return _xvec4<T>(
+		    v1.x - v2.x,
+		    v1.y - v2.y,
+            v1.z - v2.z,
+            v1.w - v2.w);
+    }
+
+    template <typename T>
+	inline _xvec4<T> operator- (const _xref4<T>& v, const T s)
+	{
+	    return _xvec4<T>(
+		    v.x - s,
+		    v.y - s,
+			v.z - s,
+			v.w - s);
+	}
+
+    template <typename T>
+    inline _xvec4<T> operator- (const T s, const _xref4<T>& v)
+	{
+	    return _xvec4<T>(
+		    s - v.x,
+		    s - v.y,
+			s - v.z,
+			s - v.w);
+	}
+    
+	template <typename T>
+    inline _xvec4<T> operator- (const _xref4<T>& v1, const _xref4<T>& v2)
+	{
+	    return _xvec4<T>(
+		    v1.x - v2.x,
+		    v1.y - v2.y,
+			v1.z - v2.z,
+			v1.w - v2.w);
+	}
+
+	template <typename T>
+    inline _xvec4<T> operator- (const _xvec4<T>& v1, const _xref4<T>& v2)
+	{
+	    return _xvec4<T>(
+		    v1.x - v2.x,
+		    v1.y - v2.y,
+			v1.z - v2.z,
+			v1.w - v2.w);
+	}
+
+	template <typename T>
+    inline _xvec4<T> operator- (const _xref4<T>& v1, const _xvec4<T>& v2)
+	{
+	    return _xvec4<T>(
+		    v1.x - v2.x,
+		    v1.y - v2.y,
+			v1.z - v2.z,
+			v1.w - v2.w);
+	}
+
+	//operator*
+    template <typename T>
+    inline _xvec4<T> operator* (const _xvec4<T>& v, const T s)
+    {
+	    return _xvec4<T>(
+		    v.x * s,
+		    v.y * s,
+            v.z * s,
+            v.w * s);
+    }
+
+    template <typename T>
+    inline _xvec4<T> operator* (const T s, const _xvec4<T>& v)
+    {
+	    return _xvec4<T>(
+		    s * v.x,
+		    s * v.y,
+            s * v.z,
+            s * v.w);
+    }
+
+    template <typename T>
+    inline _xvec4<T> operator* (const _xvec4<T>& v1, const _xvec4<T>& v2)
+    {
+	    return _xvec4<T>(
+		    v1.x * v2.x,
+		    v1.y * v2.y,
+            v1.z * v2.z,
+            v1.w * v2.w);
+    }
+
+    template <typename T>
+	inline _xvec4<T> operator* (const _xref4<T>& v, const T s)
+	{
+	    return _xvec4<T>(
+		    v.x * s,
+		    v.y * s,
+			v.z * s,
+			v.w * s);
+	}
+
+    template <typename T>
+    inline _xvec4<T> operator* (const T s, const _xref4<T>& v)
+	{
+	    return _xvec4<T>(
+		    s * v.x,
+		    s * v.y,
+			s * v.z,
+			s * v.w);
+	}
+    
+	template <typename T>
+    inline _xvec4<T> operator* (const _xref4<T>& v1, const _xref4<T>& v2)
+	{
+	    return _xvec4<T>(
+		    v1.x * v2.x,
+		    v1.y * v2.y,
+			v1.z * v2.z,
+			v1.w * v2.w);
+	}
+
+	template <typename T>
+    inline _xvec4<T> operator* (const _xvec4<T>& v1, const _xref4<T>& v2)
+	{
+	    return _xvec4<T>(
+		    v1.x * v2.x,
+		    v1.y * v2.y,
+			v1.z * v2.z,
+			v1.w * v2.w);
+	}
+
+	template <typename T>
+    inline _xvec4<T> operator* (const _xref4<T>& v1, const _xvec4<T>& v2)
+	{
+	    return _xvec4<T>(
+		    v1.x * v2.x,
+		    v1.y * v2.y,
+			v1.z * v2.z,
+			v1.w * v2.w);
+	}
+
+	// operator/
+    template <typename T>
+    inline _xvec4<T> operator/ (const _xvec4<T>& v, const T s)
+    {
+	    return _xvec4<T>(
+		    v.x / s,
+		    v.y / s,
+            v.z / s,
+            v.w / s);
+    }
+
+    template <typename T>
+    inline _xvec4<T> operator/ (const T s, const _xvec4<T>& v)
+    {
+	    return _xvec4<T>(
+		    s / v.x,
+		    s / v.y,
+            s / v.z,
+            s / v.w);
+    }
+
+    template <typename T>
+    inline _xvec4<T> operator/ (const _xvec4<T>& v1, const _xvec4<T>& v2)
+    {
+	    return _xvec4<T>(
+		    v1.x / v2.x,
+		    v1.y / v2.y,
+            v1.z / v2.z,
+            v1.w / v2.w);
+    }
+
+    template <typename T>
+	inline _xvec4<T> operator/ (const _xref4<T>& v, const T s)
+	{
+	    return _xvec4<T>(
+		    v.x / s,
+		    v.y / s,
+			v.z / s,
+			v.w / s);
+	}
+
+    template <typename T>
+    inline _xvec4<T> operator/ (const T s, const _xref4<T>& v)
+	{
+	    return _xvec4<T>(
+		    s / v.x,
+		    s / v.y,
+			s / v.z,
+			s / v.w);
+	}
+    
+	template <typename T>
+    inline _xvec4<T> operator/ (const _xref4<T>& v1, const _xref4<T>& v2)
+	{
+	    return _xvec4<T>(
+		    v1.x / v2.x,
+		    v1.y / v2.y,
+			v1.z / v2.z,
+			v1.w / v2.w);
+	}
+
+	template <typename T>
+    inline _xvec4<T> operator/ (const _xvec4<T>& v1, const _xref4<T>& v2)
+	{
+	    return _xvec4<T>(
+		    v1.x / v2.x,
+		    v1.y / v2.y,
+			v1.z / v2.z,
+			v1.w / v2.w);
+	}
+
+	template <typename T>
+    inline _xvec4<T> operator/ (const _xref4<T>& v1, const _xvec4<T>& v2)
+	{
+	    return _xvec4<T>(
+		    v1.x / v2.x,
+		    v1.y / v2.y,
+			v1.z / v2.z,
+			v1.w / v2.w);
+	}
+} //namespace detail
+} //namespace glm
+
+#endif//__glm_core_xvec4_inl__

+ 81 - 0
experimental/sse/glm/ext/gtx.h

@@ -0,0 +1,81 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2008 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2005-04-03
+// Updated : 2007-08-03
+// Licence : This source is under GNU LGPL licence
+// File    : glm/gtx.h
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Note:
+// GTX extensions are experimental extensions
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef __glm_glx__
+#define __glm_glx__
+
+//#include "./gtx/array_range.h"
+#include "./gtx/associated_min_max.h"
+#include "./gtx/bit.h"
+#include "./gtx/closest_point.h"
+#include "./gtx/color_cast.h"
+#include "./gtx/color_space.h"
+#include "./gtx/compatibility.h"
+#include "./gtx/component_wise.h"
+//#include "./gtx/complex.h"
+#include "./gtx/determinant.h"
+#include "./gtx/double.h"
+#include "./gtx/epsilon.h"
+#include "./gtx/euler_angles.h"
+#include "./gtx/extend.h"
+#include "./gtx/extented_min_max.h"
+#include "./gtx/fast_exponential.h"
+#include "./gtx/fast_square_root.h"
+#include "./gtx/fast_trigonometry.h"
+#include "./gtx/flexible_mix.h"
+#include "./gtx/gpu_shader4.h"
+#include "./gtx/half.h"
+#include "./gtx/handed_coordinate_space.h"
+#include "./gtx/hyperbolic.h"
+#include "./gtx/inertia.h"
+#include "./gtx/integer.h"
+#include "./gtx/intersect.h"
+#include "./gtx/inverse.h"
+#include "./gtx/inverse_transpose.h"
+#include "./gtx/mat4x3.h"
+//#include "./gtx/mat_mn.h"
+#include "./gtx/matrix_access.h"
+#include "./gtx/matrix_cross_product.h"
+#include "./gtx/matrix_major_storage.h"
+#include "./gtx/matrix_projection.h"
+#include "./gtx/matrix_query.h"
+#include "./gtx/matrix_selection.h"
+#include "./gtx/matx.h"
+#include "./gtx/mixed_product.h"
+#include "./gtx/mul.h"
+#include "./gtx/norm.h"
+#include "./gtx/normal.h"
+#include "./gtx/normalize_dot.h"
+#include "./gtx/number_precision.h"
+#include "./gtx/optimum_pow.h"
+#include "./gtx/orthonormalize.h"
+#include "./gtx/outer_product.h"
+#include "./gtx/perpendicular.h"
+#include "./gtx/polar_coordinates.h"
+#include "./gtx/projection.h"
+#include "./gtx/quaternion.h"
+#include "./gtx/random.h"
+#include "./gtx/rotate_vector.h"
+#include "./gtx/round.h"
+#include "./gtx/spline.h"
+#include "./gtx/transform.h"
+#include "./gtx/transform2.h"
+#include "./gtx/transpose.h"
+#include "./gtx/unsigned_int.h"
+#include "./gtx/vector_access.h"
+#include "./gtx/vector_angle.h"
+#include "./gtx/vector_comp_mult.h"
+#include "./gtx/vector_query.h"
+#include "./gtx/vecx.h"
+#include "./gtx/verbose_operator.h"
+
+#endif //__glm_glx__

+ 518 - 0
experimental/sse/glm/ext/gtx/associated_min_max.h

@@ -0,0 +1,518 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2008 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2008-03-10
+// Updated : 2008-03-15
+// Licence : This source is under GNU LGPL licence
+// File    : gtx_associated_min_max.h
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Dependency:
+// - GLM core
+// - GLM_GTX_extented_min_max
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef __glm_gtx_associated_min_max__
+#define __glm_gtx_associated_min_max__
+
+// Dependency:
+#include "../../glm.h"
+
+namespace glm
+{
+	//! Min comparison between 2 variables
+	template<typename T, typename U> 
+	U associatedMinGTX(
+		T x, U a, 
+		T y, U b);
+
+	//! Min comparison between 2 variables
+	template<typename T, typename U> 
+	detail::_xvec2<U> associatedMinGTX(
+		const detail::_xvec2<T>& x, const detail::_xvec2<U>& a, 
+		const detail::_xvec2<T>& y, const detail::_xvec2<U>& b);
+
+	//! Min comparison between 2 variables
+	template<typename T, typename U> 
+	detail::_xvec3<U> associatedMinGTX(
+		const detail::_xvec3<T>& x, const detail::_xvec3<U>& a, 
+		const detail::_xvec3<T>& y, const detail::_xvec3<U>& b);
+
+	//! Min comparison between 2 variables
+	template<typename T, typename U> 
+	detail::_xvec4<U> associatedMinGTX(
+		const detail::_xvec4<T>& x, const detail::_xvec4<U>& a, 
+		const detail::_xvec4<T>& y, const detail::_xvec4<U>& b);
+
+	//! Min comparison between 2 variables
+	template<typename T, typename U> 
+	detail::_xvec2<U> associatedMinGTX(
+		T x, const detail::_xvec2<U>& a, 
+		T y, const detail::_xvec2<U>& b);
+
+	//! Min comparison between 2 variables
+	template<typename T, typename U> 
+	detail::_xvec3<U> associatedMinGTX(
+		T x, const detail::_xvec3<U>& a, 
+		T y, const detail::_xvec3<U>& b);
+
+	//! Min comparison between 2 variables
+	template<typename T, typename U> 
+	detail::_xvec4<U> associatedMinGTX(
+		T x, const detail::_xvec4<U>& a, 
+		T y, const detail::_xvec4<U>& b);
+
+	//! Min comparison between 2 variables
+	template<typename T, typename U> 
+	detail::_xvec2<U> associatedMinGTX(
+		const detail::_xvec2<T>& x, U a, 
+		const detail::_xvec2<T>& y, U b);
+
+	//! Min comparison between 2 variables
+	template<typename T, typename U> 
+	detail::_xvec3<U> associatedMinGTX(
+		const detail::_xvec3<T>& x, U a, 
+		const detail::_xvec3<T>& y, U b);
+
+	//! Min comparison between 2 variables
+	template<typename T, typename U> 
+	detail::_xvec4<U> associatedMinGTX(
+		const detail::_xvec4<T>& x, U a, 
+		const detail::_xvec4<T>& y, U b);
+
+	//! Min comparison between 3 variables
+	template<typename T, typename U> 
+	U associatedMinGTX(
+		T x, U a, 
+		T y, U b,
+		T z, U c);
+
+	//! Min comparison between 3 variables
+	template<typename T, typename U> 
+	detail::_xvec2<U> associatedMinGTX(
+		const detail::_xvec2<T>& x, const detail::_xvec2<U>& a, 
+		const detail::_xvec2<T>& y, const detail::_xvec2<U>& b,
+		const detail::_xvec2<T>& z, const detail::_xvec2<U>& c);
+
+	//! Min comparison between 3 variables
+	template<typename T, typename U> 
+	detail::_xvec3<U> associatedMinGTX(
+		const detail::_xvec3<T>& x, const detail::_xvec3<U>& a, 
+		const detail::_xvec3<T>& y, const detail::_xvec3<U>& b,
+		const detail::_xvec3<T>& z, const detail::_xvec3<U>& c);
+
+	//! Min comparison between 3 variables
+	template<typename T, typename U> 
+	detail::_xvec4<U> associatedMinGTX(
+		const detail::_xvec4<T>& x, const detail::_xvec4<U>& a, 
+		const detail::_xvec4<T>& y, const detail::_xvec4<U>& b,
+		const detail::_xvec4<T>& z, const detail::_xvec4<U>& c);
+
+	//! Min comparison between 3 variables
+	template<typename T, typename U> 
+	detail::_xvec2<U> associatedMinGTX(
+		T x, const detail::_xvec2<U>& a, 
+		T y, const detail::_xvec2<U>& b,
+		T z, const detail::_xvec2<U>& c);
+
+	//! Min comparison between 3 variables
+	template<typename T, typename U> 
+	detail::_xvec3<U> associatedMinGTX(
+		T x, const detail::_xvec3<U>& a, 
+		T y, const detail::_xvec3<U>& b,
+		T z, const detail::_xvec3<U>& c);
+
+	//! Min comparison between 3 variables
+	template<typename T, typename U> 
+	detail::_xvec4<U> associatedMinGTX(
+		T x, const detail::_xvec4<U>& a, 
+		T y, const detail::_xvec4<U>& b,
+		T z, const detail::_xvec4<U>& c);
+
+	//! Min comparison between 3 variables
+	template<typename T, typename U> 
+	detail::_xvec2<U> associatedMinGTX(
+		const detail::_xvec2<T>& x, U a, 
+		const detail::_xvec2<T>& y, U b,
+		const detail::_xvec2<T>& z, U c);
+
+	//! Min comparison between 3 variables
+	template<typename T, typename U> 
+	detail::_xvec3<U> associatedMinGTX(
+		const detail::_xvec3<T>& x, U a, 
+		const detail::_xvec3<T>& y, U b,
+		const detail::_xvec3<T>& z, U c);
+
+	//! Min comparison between 3 variables
+	template<typename T, typename U> 
+	detail::_xvec4<U> associatedMinGTX(
+		const detail::_xvec4<T>& x, U a, 
+		const detail::_xvec4<T>& y, U b,
+		const detail::_xvec4<T>& z, U c);
+
+	//! Min comparison between 4 variables
+	template<typename T, typename U> 
+	U associatedMinGTX(
+		T x, U a, 
+		T y, U b,
+		T z, U c,
+		T w, U d);
+
+	//! Min comparison between 4 variables
+	template<typename T, typename U> 
+	detail::_xvec2<U> associatedMinGTX(
+		const detail::_xvec2<T>& x, const detail::_xvec2<U>& a, 
+		const detail::_xvec2<T>& y, const detail::_xvec2<U>& b,
+		const detail::_xvec2<T>& z, const detail::_xvec2<U>& c,
+		const detail::_xvec2<T>& w, const detail::_xvec2<U>& d);
+
+	//! Min comparison between 4 variables
+	template<typename T, typename U> 
+	detail::_xvec3<U> associatedMinGTX(
+		const detail::_xvec3<T>& x, const detail::_xvec3<U>& a, 
+		const detail::_xvec3<T>& y, const detail::_xvec3<U>& b,
+		const detail::_xvec3<T>& z, const detail::_xvec3<U>& c,
+		const detail::_xvec3<T>& w, const detail::_xvec3<U>& d);
+
+	//! Min comparison between 4 variables
+	template<typename T, typename U> 
+	detail::_xvec4<U> associatedMinGTX(
+		const detail::_xvec4<T>& x, const detail::_xvec4<U>& a, 
+		const detail::_xvec4<T>& y, const detail::_xvec4<U>& b,
+		const detail::_xvec4<T>& z, const detail::_xvec4<U>& c,
+		const detail::_xvec4<T>& w, const detail::_xvec4<U>& d);
+
+	//! Min comparison between 4 variables
+	template<typename T, typename U> 
+	detail::_xvec2<U> associatedMinGTX(
+		T x, const detail::_xvec2<U>& a, 
+		T y, const detail::_xvec2<U>& b,
+		T z, const detail::_xvec2<U>& c,
+		T w, const detail::_xvec2<U>& d);
+
+	//! Min comparison between 4 variables
+	template<typename T, typename U> 
+	detail::_xvec3<U> associatedMinGTX(
+		T x, const detail::_xvec3<U>& a, 
+		T y, const detail::_xvec3<U>& b,
+		T z, const detail::_xvec3<U>& c,
+		T w, const detail::_xvec3<U>& d);
+
+	//! Min comparison between 4 variables
+	template<typename T, typename U> 
+	detail::_xvec4<U> associatedMinGTX(
+		T x, const detail::_xvec4<U>& a, 
+		T y, const detail::_xvec4<U>& b,
+		T z, const detail::_xvec4<U>& c,
+		T w, const detail::_xvec4<U>& d);
+
+	//! Min comparison between 4 variables
+	template<typename T, typename U> 
+	detail::_xvec2<U> associatedMinGTX(
+		const detail::_xvec2<T>& x, U a, 
+		const detail::_xvec2<T>& y, U b,
+		const detail::_xvec2<T>& z, U c,
+		const detail::_xvec2<T>& w, U d);
+
+	//! Min comparison between 4 variables
+	template<typename T, typename U> 
+	detail::_xvec3<U> associatedMinGTX(
+		const detail::_xvec3<T>& x, U a, 
+		const detail::_xvec3<T>& y, U b,
+		const detail::_xvec3<T>& z, U c,
+		const detail::_xvec3<T>& w, U d);
+
+	//! Min comparison between 4 variables
+	template<typename T, typename U> 
+	detail::_xvec4<U> associatedMinGTX(
+		const detail::_xvec4<T>& x, U a, 
+		const detail::_xvec4<T>& y, U b,
+		const detail::_xvec4<T>& z, U c,
+		const detail::_xvec4<T>& w, U d);
+
+	//! Max comparison between 2 variables
+	template<typename T, typename U> 
+	U associatedMaxGTX(
+		T x, U a, 
+		T y, U b);
+
+	//! Max comparison between 2 variables
+	template<typename T, typename U> 
+	detail::_xvec2<U> associatedMaxGTX(
+		const detail::_xvec2<T>& x, const detail::_xvec2<U>& a, 
+		const detail::_xvec2<T>& y, const detail::_xvec2<U>& b);
+
+	//! Max comparison between 2 variables
+	template<typename T, typename U> 
+	detail::_xvec3<U> associatedMaxGTX(
+		const detail::_xvec3<T>& x, const detail::_xvec3<U>& a, 
+		const detail::_xvec3<T>& y, const detail::_xvec3<U>& b);
+
+	//! Max comparison between 2 variables
+	template<typename T, typename U> 
+	detail::_xvec4<U> associatedMaxGTX(
+		const detail::_xvec4<T>& x, const detail::_xvec4<U>& a, 
+		const detail::_xvec4<T>& y, const detail::_xvec4<U>& b);
+
+	//! Max comparison between 2 variables
+	template<typename T, typename U> 
+	detail::_xvec2<U> associatedMaxGTX(
+		T x, const detail::_xvec2<U>& a, 
+		T y, const detail::_xvec2<U>& b);
+
+	//! Max comparison between 2 variables
+	template<typename T, typename U> 
+	detail::_xvec3<U> associatedMaxGTX(
+		T x, const detail::_xvec3<U>& a, 
+		T y, const detail::_xvec3<U>& b);
+
+	//! Max comparison between 2 variables
+	template<typename T, typename U> 
+	detail::_xvec4<U> associatedMaxGTX(
+		T x, const detail::_xvec4<U>& a, 
+		T y, const detail::_xvec4<U>& b);
+
+	//! Max comparison between 2 variables
+	template<typename T, typename U> 
+	detail::_xvec2<U> associatedMaxGTX(
+		const detail::_xvec2<T>& x, U a, 
+		const detail::_xvec2<T>& y, U b);
+
+	//! Max comparison between 2 variables
+	template<typename T, typename U> 
+	detail::_xvec3<U> associatedMaxGTX(
+		const detail::_xvec3<T>& x, U a, 
+		const detail::_xvec3<T>& y, U b);
+
+	//! Max comparison between 2 variables
+	template<typename T, typename U> 
+	detail::_xvec4<U> associatedMaxGTX(
+		const detail::_xvec4<T>& x, U a, 
+		const detail::_xvec4<T>& y, U b);
+
+	//! Max comparison between 3 variables
+	template<typename T, typename U> 
+	U associatedMaxGTX(
+		T x, U a, 
+		T y, U b,
+		T z, U c);
+
+	//! Max comparison between 3 variables
+	template<typename T, typename U> 
+	detail::_xvec2<U> associatedMaxGTX(
+		const detail::_xvec2<T>& x, const detail::_xvec2<U>& a, 
+		const detail::_xvec2<T>& y, const detail::_xvec2<U>& b,
+		const detail::_xvec2<T>& z, const detail::_xvec2<U>& c);
+
+	//! Max comparison between 3 variables
+	template<typename T, typename U> 
+	detail::_xvec3<U> associatedMaxGTX(
+		const detail::_xvec3<T>& x, const detail::_xvec3<U>& a, 
+		const detail::_xvec3<T>& y, const detail::_xvec3<U>& b,
+		const detail::_xvec3<T>& z, const detail::_xvec3<U>& c);
+
+	//! Max comparison between 3 variables
+	template<typename T, typename U> 
+	detail::_xvec4<U> associatedMaxGTX(
+		const detail::_xvec4<T>& x, const detail::_xvec4<U>& a, 
+		const detail::_xvec4<T>& y, const detail::_xvec4<U>& b,
+		const detail::_xvec4<T>& z, const detail::_xvec4<U>& c);
+
+	//! Max comparison between 3 variables
+	template<typename T, typename U> 
+	detail::_xvec2<U> associatedMaxGTX(
+		T x, const detail::_xvec2<U>& a, 
+		T y, const detail::_xvec2<U>& b,
+		T z, const detail::_xvec2<U>& c);
+
+	//! Max comparison between 3 variables
+	template<typename T, typename U> 
+	detail::_xvec3<U> associatedMaxGTX(
+		T x, const detail::_xvec3<U>& a, 
+		T y, const detail::_xvec3<U>& b,
+		T z, const detail::_xvec3<U>& c);
+
+	//! Max comparison between 3 variables
+	template<typename T, typename U> 
+	detail::_xvec4<U> associatedMaxGTX(
+		T x, const detail::_xvec4<U>& a, 
+		T y, const detail::_xvec4<U>& b,
+		T z, const detail::_xvec4<U>& c);
+
+	//! Max comparison between 3 variables
+	template<typename T, typename U> 
+	detail::_xvec2<U> associatedMaxGTX(
+		const detail::_xvec2<T>& x, U a, 
+		const detail::_xvec2<T>& y, U b,
+		const detail::_xvec2<T>& z, U c);
+
+	//! Max comparison between 3 variables
+	template<typename T, typename U> 
+	detail::_xvec3<U> associatedMaxGTX(
+		const detail::_xvec3<T>& x, U a, 
+		const detail::_xvec3<T>& y, U b,
+		const detail::_xvec3<T>& z, U c);
+
+	//! Max comparison between 3 variables
+	template<typename T, typename U> 
+	detail::_xvec4<U> associatedMaxGTX(
+		const detail::_xvec4<T>& x, U a, 
+		const detail::_xvec4<T>& y, U b,
+		const detail::_xvec4<T>& z, U c);
+
+	//! Max comparison between 4 variables
+	template<typename T, typename U> 
+	U associatedMaxGTX(
+		T x, U a, 
+		T y, U b,
+		T z, U c,
+		T w, U d);
+
+	//! Max comparison between 4 variables
+	template<typename T, typename U> 
+	detail::_xvec2<U> associatedMaxGTX(
+		const detail::_xvec2<T>& x, const detail::_xvec2<U>& a, 
+		const detail::_xvec2<T>& y, const detail::_xvec2<U>& b,
+		const detail::_xvec2<T>& z, const detail::_xvec2<U>& c,
+		const detail::_xvec2<T>& w, const detail::_xvec2<U>& d);
+
+	//! Max comparison between 4 variables
+	template<typename T, typename U> 
+	detail::_xvec3<U> associatedMaxGTX(
+		const detail::_xvec3<T>& x, const detail::_xvec3<U>& a, 
+		const detail::_xvec3<T>& y, const detail::_xvec3<U>& b,
+		const detail::_xvec3<T>& z, const detail::_xvec3<U>& c,
+		const detail::_xvec3<T>& w, const detail::_xvec3<U>& d);
+
+	//! Max comparison between 4 variables
+	template<typename T, typename U> 
+	detail::_xvec4<U> associatedMaxGTX(
+		const detail::_xvec4<T>& x, const detail::_xvec4<U>& a, 
+		const detail::_xvec4<T>& y, const detail::_xvec4<U>& b,
+		const detail::_xvec4<T>& z, const detail::_xvec4<U>& c,
+		const detail::_xvec4<T>& w, const detail::_xvec4<U>& d);
+
+	//! Max comparison between 4 variables
+	template<typename T, typename U> 
+	detail::_xvec2<U> associatedMaxGTX(
+		T x, const detail::_xvec2<U>& a, 
+		T y, const detail::_xvec2<U>& b,
+		T z, const detail::_xvec2<U>& c,
+		T w, const detail::_xvec2<U>& d);
+
+	//! Max comparison between 4 variables
+	template<typename T, typename U> 
+	detail::_xvec3<U> associatedMaxGTX(
+		T x, const detail::_xvec3<U>& a, 
+		T y, const detail::_xvec3<U>& b,
+		T z, const detail::_xvec3<U>& c,
+		T w, const detail::_xvec3<U>& d);
+
+	//! Max comparison between 4 variables
+	template<typename T, typename U> 
+	detail::_xvec4<U> associatedMaxGTX(
+		T x, const detail::_xvec4<U>& a, 
+		T y, const detail::_xvec4<U>& b,
+		T z, const detail::_xvec4<U>& c,
+		T w, const detail::_xvec4<U>& d);
+
+	//! Max comparison between 4 variables
+	template<typename T, typename U> 
+	detail::_xvec2<U> associatedMaxGTX(
+		const detail::_xvec2<T>& x, U a, 
+		const detail::_xvec2<T>& y, U b,
+		const detail::_xvec2<T>& z, U c,
+		const detail::_xvec2<T>& w, U d);
+
+	//! Max comparison between 4 variables
+	template<typename T, typename U> 
+	detail::_xvec3<U> associatedMaxGTX(
+		const detail::_xvec3<T>& x, U a, 
+		const detail::_xvec3<T>& y, U b,
+		const detail::_xvec3<T>& z, U c,
+		const detail::_xvec3<T>& w, U d);
+
+	//! Max comparison between 4 variables
+	template<typename T, typename U> 
+	detail::_xvec4<U> associatedMaxGTX(
+		const detail::_xvec4<T>& x, U a, 
+		const detail::_xvec4<T>& y, U b,
+		const detail::_xvec4<T>& z, U c,
+		const detail::_xvec4<T>& w, U d);
+
+	namespace gtx
+	{
+		//! GLM_GTX_associated_min_max extension: Min and max functions that return associated values not the compared onces.
+		namespace associated_min_max
+		{
+			//! Min comparison between 2 variables
+			template<typename genTypeT, typename genTypeU>
+			inline genTypeU associatedMin(
+				const genTypeT& x, const genTypeU& a, 
+				const genTypeT& y, const genTypeU& b)
+			{
+				return associatedMinGTX(x, a, y, b);
+			}
+
+			//! Min comparison between 3 variables
+			template<typename genTypeT, typename genTypeU>
+			inline genTypeU associatedMin(
+				const genTypeT& x, const genTypeU& a, 
+				const genTypeT& y, const genTypeU& b, 
+				const genTypeT& z, const genTypeU& c)
+			{
+				return associatedMinGTX(x, a, y, b, z, c);
+			}
+
+			//! Min comparison between 4 variables
+			template<typename genTypeT, typename genTypeU>
+			inline genTypeU associatedMin(
+				const genTypeT& x, const genTypeU& a, 
+				const genTypeT& y, const genTypeU& b, 
+				const genTypeT& z, const genTypeU& c, 
+				const genTypeT& w, const genTypeU& d)
+			{
+				return associatedMinGTX(x, a, y, b, z, c, w, d);
+			}
+
+			//! Max comparison between 2 variables
+			template<typename genTypeT, typename genTypeU>
+			inline genTypeU associatedMax(
+				const genTypeT& x, const genTypeU& a, 
+				const genTypeT& y, const genTypeU& b)
+			{
+				return associatedMaxGTX(x, a, y, b);
+			}
+
+			//! Max comparison between 3 variables
+			template<typename genTypeT, typename genTypeU>
+			inline genTypeU associatedMax(
+				const genTypeT& x, const genTypeU& a, 
+				const genTypeT& y, const genTypeU& b, 
+				const genTypeT& z, const genTypeU& c)
+			{
+				return associatedMaxGTX(x, a, y, b, z, c);
+			}
+
+			//! Max comparison between 4 variables
+			template<typename genTypeT, typename genTypeU>
+			inline genTypeU associatedMax(
+				const genTypeT& x, const genTypeU& a, 
+				const genTypeT& y, const genTypeU& b, 
+				const genTypeT& z, const genTypeU& c, 
+				const genTypeT& w, const genTypeU& d)
+			{
+				return associatedMaxGTX(x, a, y, b, z, c, w, d);
+			}
+		}
+	}
+}
+
+#define GLM_GTX_associated_min_max namespace gtx::associated_min_max
+
+#include "associated_min_max.inl"
+
+#ifdef GLM_GTX_INCLUDED
+namespace glm{using GLM_GTX_associated_min_max;}
+#endif//GLM_GTX_INCLUDED
+
+#endif//__glm_gtx_associated_min_max__

+ 911 - 0
experimental/sse/glm/ext/gtx/associated_min_max.inl

@@ -0,0 +1,911 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2008 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2008-03-10
+// Updated : 2008-03-15
+// Licence : This source is under GNU LGPL licence
+// File    : gtx_associated_min_max.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace glm
+{
+	// Min comparison between 2 variables
+	template<typename T, typename U> 
+	inline U associatedMinGTX(T x, U a, T y, U b)
+	{
+		return x < y ? a : b;
+	}
+
+	template<typename T, typename U> 
+	inline detail::_xvec2<U> associatedMinGTX
+	(
+		const detail::_xvec2<T>& x, const detail::_xvec2<U>& a, 
+		const detail::_xvec2<T>& y, const detail::_xvec2<U>& b
+	)
+	{
+		detail::_xvec2<U> Result;
+		//Result.x = x[0] < y[0] ? a[0] : b[0];
+		//Result.y = x[1] < y[1] ? a[1] : b[1];
+		for(detail::_xvec2<U>::size_type i = 0; i < detail::_xvec2<U>::value_size; ++i)
+			Result[i] = x[i] < y[i] ? a[i] : b[i];
+		return Result;
+	}
+
+	template<typename T, typename U> 
+	inline detail::_xvec3<U> associatedMinGTX
+	(
+		const detail::_xvec3<T>& x, const detail::_xvec3<U>& a, 
+		const detail::_xvec3<T>& y, const detail::_xvec3<U>& b
+	)
+	{
+		detail::_xvec3<U> Result;
+		for(detail::_xvec3<U>::size_type i = 0; i < detail::_xvec3<U>::value_size; ++i)
+			Result[i] = x[i] < y[i] ? a[i] : b[i];
+		return Result;
+	}
+
+	template<typename T, typename U> 
+	inline detail::_xvec4<U> associatedMinGTX
+	(
+		const detail::_xvec4<T>& x, const detail::_xvec4<U>& a, 
+		const detail::_xvec4<T>& y, const detail::_xvec4<U>& b
+	)
+	{
+		detail::_xvec4<U> Result;
+		for(detail::_xvec4<U>::size_type i = 0; i < detail::_xvec4<U>::value_size; ++i)
+			Result[i] = x[i] < y[i] ? a[i] : b[i];
+		return Result;
+	}
+
+	template<typename T, typename U> 
+	inline detail::_xvec2<U> associatedMinGTX
+	(
+		T x, const detail::_xvec2<U>& a, 
+		T y, const detail::_xvec2<U>& b
+	)
+	{
+		detail::_xvec2<U> Result;
+		for(detail::_xvec2<U>::size_type i = 0; i < detail::_xvec2<U>::value_size; ++i)
+			Result[i] = x < y ? a[i] : b[i];
+		return Result;
+	}
+
+	template<typename T, typename U> 
+	inline detail::_xvec3<U> associatedMinGTX
+	(
+		T x, const detail::_xvec3<U>& a, 
+		T y, const detail::_xvec3<U>& b
+	)
+	{
+		detail::_xvec3<U> Result;
+		for(detail::_xvec3<U>::size_type i = 0; i < detail::_xvec3<U>::value_size; ++i)
+			Result[i] = x < y ? a[i] : b[i];
+		return Result;
+	}
+
+	template<typename T, typename U> 
+	inline detail::_xvec4<U> associatedMinGTX
+	(
+		T x, const detail::_xvec4<U>& a, 
+		T y, const detail::_xvec4<U>& b
+	)
+	{
+		detail::_xvec4<U> Result;
+		for(detail::_xvec4<U>::size_type i = 0; i < detail::_xvec4<U>::value_size; ++i)
+			Result[i] = x < y ? a[i] : b[i];
+		return Result;
+	}
+
+	template<typename T, typename U> 
+	inline detail::_xvec2<U> associatedMinGTX
+	(
+		const detail::_xvec2<T>& x, U a, 
+		const detail::_xvec2<T>& y, U b
+	)
+	{
+		detail::_xvec2<U> Result;
+		for(detail::_xvec2<U>::size_type i = 0; i < detail::_xvec2<T>::value_size; ++i)
+			Result[i] = x[i] < y[i] ? a : b;
+		return Result;
+	}
+
+	template<typename T, typename U> 
+	inline detail::_xvec3<U> associatedMinGTX
+	(
+		const detail::_xvec3<T>& x, U a, 
+		const detail::_xvec3<T>& y, U b
+	)
+	{
+		detail::_xvec3<U> Result;
+		for(detail::_xvec3<U>::size_type i = 0; i < detail::_xvec3<T>::value_size; ++i)
+			Result[i] = x[i] < y[i] ? a : b;
+		return Result;
+	}
+
+	template<typename T, typename U> 
+	inline detail::_xvec4<U> associatedMinGTX
+	(
+		const detail::_xvec4<T>& x, U a, 
+		const detail::_xvec4<T>& y, U b
+	)
+	{
+		detail::_xvec4<U> Result;
+		for(detail::_xvec4<U>::size_type i = 0; i < detail::_xvec4<T>::value_size; ++i)
+			Result[i] = x[i] < y[i] ? a : b;
+		return Result;
+	}
+
+	// Min comparison between 3 variables
+	template<typename T, typename U> 
+	inline U associatedMinGTX
+	(
+		T x, U a, 
+		T y, U b,
+		T z, U c
+	)
+	{
+		U Result = x < y ? (x < z ? a : c) : (y < z ? b : c);
+		return Result;
+	}
+
+	template<typename T, typename U> 
+	inline detail::_xvec2<U> associatedMinGTX
+	(
+		const detail::_xvec2<T>& x, const detail::_xvec2<U>& a, 
+		const detail::_xvec2<T>& y, const detail::_xvec2<U>& b,
+		const detail::_xvec2<T>& z, const detail::_xvec2<U>& c
+	)
+	{
+		detail::_xvec2<U> Result;
+		for(detail::_xvec2<U>::size_type i = 0; i < detail::_xvec2<U>::value_size; ++i)
+			Result[i] = x[i] < y[i] ? (x[i] < z[i] ? a[i] : c[i]) : (y[i] < z[i] ? b[i] : c[i]);
+		return Result;
+	}
+
+	template<typename T, typename U> 
+	inline detail::_xvec3<U> associatedMinGTX
+	(
+		const detail::_xvec3<T>& x, const detail::_xvec3<U>& a, 
+		const detail::_xvec3<T>& y, const detail::_xvec3<U>& b,
+		const detail::_xvec3<T>& z, const detail::_xvec3<U>& c
+	)
+	{
+		detail::_xvec3<U> Result;
+		for(detail::_xvec3<U>::size_type i = 0; i < detail::_xvec3<U>::value_size; ++i)
+			Result[i] = x[i] < y[i] ? (x[i] < z[i] ? a[i] : c[i]) : (y[i] < z[i] ? b[i] : c[i]);
+		return Result;
+	}
+
+	template<typename T, typename U> 
+	inline detail::_xvec4<U> associatedMinGTX
+	(
+		const detail::_xvec4<T>& x, const detail::_xvec4<U>& a, 
+		const detail::_xvec4<T>& y, const detail::_xvec4<U>& b,
+		const detail::_xvec4<T>& z, const detail::_xvec4<U>& c
+	)
+	{
+		detail::_xvec4<U> Result;
+		for(detail::_xvec4<U>::size_type i = 0; i < detail::_xvec4<U>::value_size; ++i)
+			Result[i] = x[i] < y[i] ? (x[i] < z[i] ? a[i] : c[i]) : (y[i] < z[i] ? b[i] : c[i]);
+		return Result;
+	}
+
+	// Min comparison between 4 variables
+	template<typename T, typename U> 
+	inline U associatedMinGTX
+	(
+		T x, U a, 
+		T y, U b,
+		T z, U c,
+		T w, U d
+	)
+	{
+		T Test1 = min(x, y);
+		T Test2 = min(z, w);;
+		U Result1 = x < y ? a : b;
+		U Result2 = z < w ? c : d;
+		U Result = Test1 < Test2 ? Result1 : Result2;
+		return Result;
+	}
+
+	// Min comparison between 4 variables
+	template<typename T, typename U> 
+	inline detail::_xvec2<U> associatedMinGTX
+	(
+		const detail::_xvec2<T>& x, const detail::_xvec2<U>& a, 
+		const detail::_xvec2<T>& y, const detail::_xvec2<U>& b,
+		const detail::_xvec2<T>& z, const detail::_xvec2<U>& c,
+		const detail::_xvec2<T>& w, const detail::_xvec2<U>& d
+	)
+	{
+		detail::_xvec2<U> Result;
+		for(detail::_xvec2<U>::size_type i = 0; i < detail::_xvec2<U>::value_size; ++i)
+		{
+			T Test1 = min(x[i], y[i]);
+			T Test2 = min(z[i], w[i]);
+			U Result1 = x[i] < y[i] ? a[i] : b[i];
+			U Result2 = z[i] < w[i] ? c[i] : d[i];
+			Result[i] = Test1 < Test2 ? Result1 : Result2;
+		}
+		return Result;
+	}
+
+	// Min comparison between 4 variables
+	template<typename T, typename U> 
+	inline detail::_xvec3<U> associatedMinGTX
+	(
+		const detail::_xvec3<T>& x, const detail::_xvec3<U>& a, 
+		const detail::_xvec3<T>& y, const detail::_xvec3<U>& b,
+		const detail::_xvec3<T>& z, const detail::_xvec3<U>& c,
+		const detail::_xvec3<T>& w, const detail::_xvec3<U>& d
+	)
+	{
+		detail::_xvec3<U> Result;
+		for(detail::_xvec3<U>::size_type i = 0; i < detail::_xvec3<U>::value_size; ++i)
+		{
+			T Test1 = min(x[i], y[i]);
+			T Test2 = min(z[i], w[i]);
+			U Result1 = x[i] < y[i] ? a[i] : b[i];
+			U Result2 = z[i] < w[i] ? c[i] : d[i];
+			Result[i] = Test1 < Test2 ? Result1 : Result2;
+		}
+		return Result;
+	}
+
+	// Min comparison between 4 variables
+	template<typename T, typename U> 
+	inline detail::_xvec4<U> associatedMinGTX
+	(
+		const detail::_xvec4<T>& x, const detail::_xvec4<U>& a, 
+		const detail::_xvec4<T>& y, const detail::_xvec4<U>& b,
+		const detail::_xvec4<T>& z, const detail::_xvec4<U>& c,
+		const detail::_xvec4<T>& w, const detail::_xvec4<U>& d
+	)
+	{
+		detail::_xvec4<U> Result;
+		for(detail::_xvec4<U>::size_type i = 0; i < detail::_xvec4<U>::value_size; ++i)
+		{
+			T Test1 = min(x[i], y[i]);
+			T Test2 = min(z[i], w[i]);
+			U Result1 = x[i] < y[i] ? a[i] : b[i];
+			U Result2 = z[i] < w[i] ? c[i] : d[i];
+			Result[i] = Test1 < Test2 ? Result1 : Result2;
+		}
+		return Result;
+	}
+
+	// Min comparison between 4 variables
+	template<typename T, typename U> 
+	inline detail::_xvec2<U> associatedMinGTX
+	(
+		T x, const detail::_xvec2<U>& a, 
+		T y, const detail::_xvec2<U>& b,
+		T z, const detail::_xvec2<U>& c,
+		T w, const detail::_xvec2<U>& d
+	)
+	{
+		T Test1 = min(x, y);
+		T Test2 = min(z, w);
+
+		detail::_xvec2<U> Result;
+		for(detail::_xvec2<U>::size_type i = 0; i < detail::_xvec2<U>::value_size; ++i)
+		{
+			U Result1 = x < y ? a[i] : b[i];
+			U Result2 = z < w ? c[i] : d[i];
+			Result[i] = Test1 < Test2 ? Result1 : Result2;
+		}
+		return Result;
+	}
+
+	// Min comparison between 4 variables
+	template<typename T, typename U> 
+	inline detail::_xvec3<U> associatedMinGTX
+	(
+		T x, const detail::_xvec3<U>& a, 
+		T y, const detail::_xvec3<U>& b,
+		T z, const detail::_xvec3<U>& c,
+		T w, const detail::_xvec3<U>& d
+	)
+	{
+		T Test1 = min(x, y);
+		T Test2 = min(z, w);
+
+		detail::_xvec3<U> Result;
+		for(detail::_xvec3<U>::size_type i = 0; i < detail::_xvec3<U>::value_size; ++i)
+		{
+			U Result1 = x < y ? a[i] : b[i];
+			U Result2 = z < w ? c[i] : d[i];
+			Result[i] = Test1 < Test2 ? Result1 : Result2;
+		}
+		return Result;
+	}
+
+	// Min comparison between 4 variables
+	template<typename T, typename U> 
+	inline detail::_xvec4<U> associatedMinGTX
+	(
+		T x, const detail::_xvec4<U>& a, 
+		T y, const detail::_xvec4<U>& b,
+		T z, const detail::_xvec4<U>& c,
+		T w, const detail::_xvec4<U>& d
+	)
+	{
+		T Test1 = min(x, y);
+		T Test2 = min(z, w);
+
+		detail::_xvec4<U> Result;
+		for(detail::_xvec4<U>::size_type i = 0; i < detail::_xvec4<U>::value_size; ++i)
+		{
+			U Result1 = x < y ? a[i] : b[i];
+			U Result2 = z < w ? c[i] : d[i];
+			Result[i] = Test1 < Test2 ? Result1 : Result2;
+		}
+		return Result;
+	}
+
+	// Min comparison between 4 variables
+	template<typename T, typename U> 
+	inline detail::_xvec2<U> associatedMinGTX
+	(
+		const detail::_xvec2<T>& x, U a, 
+		const detail::_xvec2<T>& y, U b,
+		const detail::_xvec2<T>& z, U c,
+		const detail::_xvec2<T>& w, U d
+	)
+	{
+		detail::_xvec2<U> Result;
+		for(detail::_xvec2<T>::size_type i = 0; i < detail::_xvec2<T>::value_size; ++i)
+		{
+			T Test1 = min(x[i], y[i]);
+			T Test2 = min(z[i], w[i]);;
+			U Result1 = x[i] < y[i] ? a : b;
+			U Result2 = z[i] < w[i] ? c : d;
+			Result[i] = Test1 < Test2 ? Result1 : Result2;
+		}
+		return Result;
+	}
+
+	// Min comparison between 4 variables
+	template<typename T, typename U> 
+	inline detail::_xvec3<U> associatedMinGTX
+	(
+		const detail::_xvec3<T>& x, U a, 
+		const detail::_xvec3<T>& y, U b,
+		const detail::_xvec3<T>& z, U c,
+		const detail::_xvec3<T>& w, U d
+	)
+	{
+		detail::_xvec3<U> Result;
+		for(detail::_xvec3<T>::size_type i = 0; i < detail::_xvec3<T>::value_size; ++i)
+		{
+			T Test1 = min(x[i], y[i]);
+			T Test2 = min(z[i], w[i]);;
+			U Result1 = x[i] < y[i] ? a : b;
+			U Result2 = z[i] < w[i] ? c : d;
+			Result[i] = Test1 < Test2 ? Result1 : Result2;
+		}
+		return Result;
+	}
+
+	// Min comparison between 4 variables
+	template<typename T, typename U> 
+	inline detail::_xvec4<U> associatedMinGTX
+	(
+		const detail::_xvec4<T>& x, U a, 
+		const detail::_xvec4<T>& y, U b,
+		const detail::_xvec4<T>& z, U c,
+		const detail::_xvec4<T>& w, U d
+	)
+	{
+		detail::_xvec4<U> Result;
+		for(detail::_xvec4<T>::size_type i = 0; i < detail::_xvec4<T>::value_size; ++i)
+		{
+			T Test1 = min(x[i], y[i]);
+			T Test2 = min(z[i], w[i]);;
+			U Result1 = x[i] < y[i] ? a : b;
+			U Result2 = z[i] < w[i] ? c : d;
+			Result[i] = Test1 < Test2 ? Result1 : Result2;
+		}
+		return Result;
+	}
+
+	// Max comparison between 2 variables
+	template<typename T, typename U> 
+	inline U associatedMaxGTX(T x, U a, T y, U b)
+	{
+		return x > y ? a : b;
+	}
+
+	// Max comparison between 2 variables
+	template<typename T, typename U> 
+	inline detail::_xvec2<U> associatedMaxGTX
+	(
+		const detail::_xvec2<T>& x, const detail::_xvec2<U>& a, 
+		const detail::_xvec2<T>& y, const detail::_xvec2<U>& b
+	)
+	{
+		detail::_xvec2<U> Result;
+		for(detail::_xvec2<U>::size_type i = 0; i < detail::_xvec2<U>::value_size; ++i)
+			Result[i] = x[i] > y[i] ? a[i] : b[i];
+		return Result;
+	}
+
+	// Max comparison between 2 variables
+	template<typename T, typename U> 
+	inline detail::_xvec3<U> associatedMaxGTX
+	(
+		const detail::_xvec3<T>& x, const detail::_xvec3<U>& a, 
+		const detail::_xvec3<T>& y, const detail::_xvec3<U>& b
+	)
+	{
+		detail::_xvec3<U> Result;
+		for(detail::_xvec3<U>::size_type i = 0; i < detail::_xvec3<U>::value_size; ++i)
+			Result[i] = x[i] > y[i] ? a[i] : b[i];
+		return Result;
+	}
+
+	// Max comparison between 2 variables
+	template<typename T, typename U> 
+	inline detail::_xvec4<U> associatedMaxGTX
+	(
+		const detail::_xvec4<T>& x, const detail::_xvec4<U>& a, 
+		const detail::_xvec4<T>& y, const detail::_xvec4<U>& b
+	)
+	{
+		detail::_xvec4<U> Result;
+		for(detail::_xvec4<U>::size_type i = 0; i < detail::_xvec4<U>::value_size; ++i)
+			Result[i] = x[i] > y[i] ? a[i] : b[i];
+		return Result;
+	}
+
+	// Max comparison between 2 variables
+	template<typename T, typename U> 
+	inline detail::_xvec2<U> associatedMaxGTX
+	(
+		T x, const detail::_xvec2<U>& a, 
+		T y, const detail::_xvec2<U>& b
+	)
+	{
+		detail::_xvec2<U> Result;
+		for(detail::_xvec2<U>::size_type i = 0; i < detail::_xvec2<U>::value_size; ++i)
+			Result[i] = x > y ? a[i] : b[i];
+		return Result;
+	}
+
+	// Max comparison between 2 variables
+	template<typename T, typename U> 
+	inline detail::_xvec3<U> associatedMaxGTX
+	(
+		T x, const detail::_xvec3<U>& a, 
+		T y, const detail::_xvec3<U>& b
+	)
+	{
+		detail::_xvec3<U> Result;
+		for(detail::_xvec3<U>::size_type i = 0; i < detail::_xvec3<U>::value_size; ++i)
+			Result[i] = x > y ? a[i] : b[i];
+		return Result;
+	}
+
+	// Max comparison between 2 variables
+	template<typename T, typename U> 
+	inline detail::_xvec4<U> associatedMaxGTX
+	(
+		T x, const detail::_xvec4<U>& a, 
+		T y, const detail::_xvec4<U>& b
+	)
+	{
+		detail::_xvec4<U> Result;
+		for(detail::_xvec4<U>::size_type i = 0; i < detail::_xvec4<U>::value_size; ++i)
+			Result[i] = x > y ? a[i] : b[i];
+		return Result;
+	}
+
+	// Max comparison between 2 variables
+	template<typename T, typename U> 
+	inline detail::_xvec2<U> associatedMaxGTX
+	(
+		const detail::_xvec2<T>& x, U a, 
+		const detail::_xvec2<T>& y, U b
+	)
+	{
+		detail::_xvec2<U> Result;
+		for(detail::_xvec2<T>::size_type i = 0; i < detail::_xvec2<T>::value_size; ++i)
+			Result[i] = x[i] > y[i] ? a : b;
+		return Result;
+	}
+
+	// Max comparison between 2 variables
+	template<typename T, typename U> 
+	inline detail::_xvec3<U> associatedMaxGTX
+	(
+		const detail::_xvec3<T>& x, U a, 
+		const detail::_xvec3<T>& y, U b
+	)
+	{
+		detail::_xvec3<U> Result;
+		for(detail::_xvec3<T>::size_type i = 0; i < detail::_xvec3<T>::value_size; ++i)
+			Result[i] = x[i] > y[i] ? a : b;
+		return Result;
+	}
+
+	// Max comparison between 2 variables
+	template<typename T, typename U> 
+	inline detail::_xvec4<U> associatedMaxGTX
+	(
+		const detail::_xvec4<T>& x, U a, 
+		const detail::_xvec4<T>& y, U b
+	)
+	{
+		detail::_xvec4<U> Result;
+		for(detail::_xvec4<T>::size_type i = 0; i < detail::_xvec4<T>::value_size; ++i)
+			Result[i] = x[i] > y[i] ? a : b;
+		return Result;
+	}
+
+	// Max comparison between 3 variables
+	template<typename T, typename U> 
+	inline U associatedMaxGTX
+	(
+		T x, U a, 
+		T y, U b,
+		T z, U c
+	)
+	{
+		U Result = x > y ? (x > z ? a : c) : (y > z ? b : c);
+		return Result;
+	}
+
+	// Max comparison between 3 variables
+	template<typename T, typename U> 
+	inline detail::_xvec2<U> associatedMaxGTX
+	(
+		const detail::_xvec2<T>& x, const detail::_xvec2<U>& a, 
+		const detail::_xvec2<T>& y, const detail::_xvec2<U>& b,
+		const detail::_xvec2<T>& z, const detail::_xvec2<U>& c
+	)
+	{
+		detail::_xvec2<U> Result;
+		for(detail::_xvec2<U>::size_type i = 0; i < detail::_xvec2<U>::value_size; ++i)
+			Result[i] = x[i] > y[i] ? (x[i] > z[i] ? a[i] : c[i]) : (y[i] > z[i] ? b[i] : c[i]);
+		return Result;
+	}
+
+	// Max comparison between 3 variables
+	template<typename T, typename U> 
+	inline detail::_xvec3<U> associatedMaxGTX
+	(
+		const detail::_xvec3<T>& x, const detail::_xvec3<U>& a, 
+		const detail::_xvec3<T>& y, const detail::_xvec3<U>& b,
+		const detail::_xvec3<T>& z, const detail::_xvec3<U>& c
+	)
+	{
+		detail::_xvec3<U> Result;
+		for(detail::_xvec3<U>::size_type i = 0; i < detail::_xvec3<U>::value_size; ++i)
+			Result[i] = x[i] > y[i] ? (x[i] > z[i] ? a[i] : c[i]) : (y[i] > z[i] ? b[i] : c[i]);
+		return Result;
+	}
+
+	// Max comparison between 3 variables
+	template<typename T, typename U> 
+	inline detail::_xvec4<U> associatedMaxGTX
+	(
+		const detail::_xvec4<T>& x, const detail::_xvec4<U>& a, 
+		const detail::_xvec4<T>& y, const detail::_xvec4<U>& b,
+		const detail::_xvec4<T>& z, const detail::_xvec4<U>& c
+	)
+	{
+		detail::_xvec4<U> Result;
+		for(detail::_xvec4<U>::size_type i = 0; i < detail::_xvec4<U>::value_size; ++i)
+			Result[i] = x[i] > y[i] ? (x[i] > z[i] ? a[i] : c[i]) : (y[i] > z[i] ? b[i] : c[i]);
+		return Result;
+	}
+
+	// Max comparison between 3 variables
+	template<typename T, typename U> 
+	inline detail::_xvec2<U> associatedMaxGTX
+	(
+		T x, const detail::_xvec2<U>& a, 
+		T y, const detail::_xvec2<U>& b,
+		T z, const detail::_xvec2<U>& c
+	)
+	{
+		detail::_xvec2<U> Result;
+		for(detail::_xvec2<U>::size_type i = 0; i < detail::_xvec2<U>::value_size; ++i)
+			Result[i] = x > y ? (x > z ? a[i] : c[i]) : (y > z ? b[i] : c[i]);
+		return Result;
+	}
+
+	// Max comparison between 3 variables
+	template<typename T, typename U> 
+	inline detail::_xvec3<U> associatedMaxGTX
+	(
+		T x, const detail::_xvec3<U>& a, 
+		T y, const detail::_xvec3<U>& b,
+		T z, const detail::_xvec3<U>& c
+	)
+	{
+		detail::_xvec3<U> Result;
+		for(detail::_xvec3<U>::size_type i = 0; i < detail::_xvec3<U>::value_size; ++i)
+			Result[i] = x > y ? (x > z ? a[i] : c[i]) : (y > z ? b[i] : c[i]);
+		return Result;
+	}
+
+	// Max comparison between 3 variables
+	template<typename T, typename U> 
+	inline detail::_xvec4<U> associatedMaxGTX
+	(
+		T x, const detail::_xvec4<U>& a, 
+		T y, const detail::_xvec4<U>& b,
+		T z, const detail::_xvec4<U>& c
+	)
+	{
+		detail::_xvec4<U> Result;
+		for(detail::_xvec4<U>::size_type i = 0; i < detail::_xvec4<U>::value_size; ++i)
+			Result[i] = x > y ? (x > z ? a[i] : c[i]) : (y > z ? b[i] : c[i]);
+		return Result;
+	}
+
+	// Max comparison between 3 variables
+	template<typename T, typename U> 
+	inline detail::_xvec2<U> associatedMaxGTX
+	(
+		const detail::_xvec2<T>& x, U a, 
+		const detail::_xvec2<T>& y, U b,
+		const detail::_xvec2<T>& z, U c
+	)
+	{
+		detail::_xvec2<U> Result;
+		for(detail::_xvec2<T>::size_type i = 0; i < detail::_xvec2<T>::value_size; ++i)
+			Result[i] = x[i] > y[i] ? (x[i] > z[i] ? a : c) : (y[i] > z[i] ? b : c);
+		return Result;
+	}
+
+	// Max comparison between 3 variables
+	template<typename T, typename U> 
+	inline detail::_xvec3<U> associatedMaxGTX
+	(
+		const detail::_xvec3<T>& x, U a, 
+		const detail::_xvec3<T>& y, U b,
+		const detail::_xvec3<T>& z, U c
+	)
+	{
+		detail::_xvec3<U> Result;
+		for(detail::_xvec3<T>::size_type i = 0; i < detail::_xvec3<T>::value_size; ++i)
+			Result[i] = x[i] > y[i] ? (x[i] > z[i] ? a : c) : (y[i] > z[i] ? b : c);
+		return Result;
+	}
+
+	// Max comparison between 3 variables
+	template<typename T, typename U> 
+	inline detail::_xvec4<U> associatedMaxGTX
+	(
+		const detail::_xvec4<T>& x, U a, 
+		const detail::_xvec4<T>& y, U b,
+		const detail::_xvec4<T>& z, U c
+	)
+	{
+		detail::_xvec4<U> Result;
+		for(detail::_xvec4<T>::size_type i = 0; i < detail::_xvec4<T>::value_size; ++i)
+			Result[i] = x[i] > y[i] ? (x[i] > z[i] ? a : c) : (y[i] > z[i] ? b : c);
+		return Result;
+	}
+
+	// Max comparison between 4 variables
+	template<typename T, typename U> 
+	inline U associatedMaxGTX
+	(
+		T x, U a, 
+		T y, U b,
+		T z, U c,
+		T w, U d
+	)
+	{
+		T Test1 = max(x, y);
+		T Test2 = max(z, w);;
+		U Result1 = x > y ? a : b;
+		U Result2 = z > w ? c : d;
+		U Result = Test1 > Test2 ? Result1 : Result2;
+		return Result;
+	}
+
+	// Max comparison between 4 variables
+	template<typename T, typename U> 
+	inline detail::_xvec2<U> associatedMaxGTX
+	(
+		const detail::_xvec2<T>& x, const detail::_xvec2<U>& a, 
+		const detail::_xvec2<T>& y, const detail::_xvec2<U>& b,
+		const detail::_xvec2<T>& z, const detail::_xvec2<U>& c,
+		const detail::_xvec2<T>& w, const detail::_xvec2<U>& d
+	)
+	{
+		detail::_xvec2<U> Result;
+		for(detail::_xvec2<U>::size_type i = 0; i < detail::_xvec2<U>::value_size; ++i)
+		{
+			T Test1 = max(x[i], y[i]);
+			T Test2 = max(z[i], w[i]);
+			U Result1 = x[i] > y[i] ? a[i] : b[i];
+			U Result2 = z[i] > w[i] ? c[i] : d[i];
+			Result[i] = Test1 > Test2 ? Result1 : Result2;
+		}
+		return Result;
+	}
+
+	// Max comparison between 4 variables
+	template<typename T, typename U> 
+	inline detail::_xvec3<U> associatedMaxGTX
+	(
+		const detail::_xvec3<T>& x, const detail::_xvec3<U>& a, 
+		const detail::_xvec3<T>& y, const detail::_xvec3<U>& b,
+		const detail::_xvec3<T>& z, const detail::_xvec3<U>& c,
+		const detail::_xvec3<T>& w, const detail::_xvec3<U>& d
+	)
+	{
+		detail::_xvec3<U> Result;
+		for(detail::_xvec3<U>::size_type i = 0; i < detail::_xvec3<U>::value_size; ++i)
+		{
+			T Test1 = max(x[i], y[i]);
+			T Test2 = max(z[i], w[i]);
+			U Result1 = x[i] > y[i] ? a[i] : b[i];
+			U Result2 = z[i] > w[i] ? c[i] : d[i];
+			Result[i] = Test1 > Test2 ? Result1 : Result2;
+		}
+		return Result;
+	}
+
+	// Max comparison between 4 variables
+	template<typename T, typename U> 
+	inline detail::_xvec4<U> associatedMaxGTX
+	(
+		const detail::_xvec4<T>& x, const detail::_xvec4<U>& a, 
+		const detail::_xvec4<T>& y, const detail::_xvec4<U>& b,
+		const detail::_xvec4<T>& z, const detail::_xvec4<U>& c,
+		const detail::_xvec4<T>& w, const detail::_xvec4<U>& d
+	)
+	{
+		detail::_xvec4<U> Result;
+		for(detail::_xvec4<U>::size_type i = 0; i < detail::_xvec4<U>::value_size; ++i)
+		{
+			T Test1 = max(x[i], y[i]);
+			T Test2 = max(z[i], w[i]);
+			U Result1 = x[i] > y[i] ? a[i] : b[i];
+			U Result2 = z[i] > w[i] ? c[i] : d[i];
+			Result[i] = Test1 > Test2 ? Result1 : Result2;
+		}
+		return Result;
+	}
+
+	// Max comparison between 4 variables
+	template<typename T, typename U> 
+	inline detail::_xvec2<U> associatedMaxGTX
+	(
+		T x, const detail::_xvec2<U>& a, 
+		T y, const detail::_xvec2<U>& b,
+		T z, const detail::_xvec2<U>& c,
+		T w, const detail::_xvec2<U>& d
+	)
+	{
+		T Test1 = max(x, y);
+		T Test2 = max(z, w);
+
+		detail::_xvec2<U> Result;
+		for(detail::_xvec2<U>::size_type i = 0; i < detail::_xvec2<U>::value_size; ++i)
+		{
+			U Result1 = x > y ? a[i] : b[i];
+			U Result2 = z > w ? c[i] : d[i];
+			Result[i] = Test1 > Test2 ? Result1 : Result2;
+		}
+		return Result;
+	}
+
+	// Max comparison between 4 variables
+	template<typename T, typename U> 
+	inline detail::_xvec3<U> associatedMaxGTX
+	(
+		T x, const detail::_xvec3<U>& a, 
+		T y, const detail::_xvec3<U>& b,
+		T z, const detail::_xvec3<U>& c,
+		T w, const detail::_xvec3<U>& d
+	)
+	{
+		T Test1 = max(x, y);
+		T Test2 = max(z, w);
+
+		detail::_xvec3<U> Result;
+		for(detail::_xvec3<U>::size_type i = 0; i < detail::_xvec3<U>::value_size; ++i)
+		{
+			U Result1 = x > y ? a[i] : b[i];
+			U Result2 = z > w ? c[i] : d[i];
+			Result[i] = Test1 > Test2 ? Result1 : Result2;
+		}
+		return Result;
+	}
+
+	// Max comparison between 4 variables
+	template<typename T, typename U> 
+	inline detail::_xvec4<U> associatedMaxGTX
+	(
+		T x, const detail::_xvec4<U>& a, 
+		T y, const detail::_xvec4<U>& b,
+		T z, const detail::_xvec4<U>& c,
+		T w, const detail::_xvec4<U>& d
+	)
+	{
+		T Test1 = max(x, y);
+		T Test2 = max(z, w);
+
+		detail::_xvec4<U> Result;
+		for(detail::_xvec4<U>::size_type i = 0; i < detail::_xvec4<U>::value_size; ++i)
+		{
+			U Result1 = x > y ? a[i] : b[i];
+			U Result2 = z > w ? c[i] : d[i];
+			Result[i] = Test1 > Test2 ? Result1 : Result2;
+		}
+		return Result;
+	}
+
+	// Max comparison between 4 variables
+	template<typename T, typename U> 
+	inline detail::_xvec2<U> associatedMaxGTX
+	(
+		const detail::_xvec2<T>& x, U a, 
+		const detail::_xvec2<T>& y, U b,
+		const detail::_xvec2<T>& z, U c,
+		const detail::_xvec2<T>& w, U d
+	)
+	{
+		detail::_xvec2<U> Result;
+		for(detail::_xvec2<T>::size_type i = 0; i < detail::_xvec2<T>::value_size; ++i)
+		{
+			T Test1 = max(x[i], y[i]);
+			T Test2 = max(z[i], w[i]);;
+			U Result1 = x[i] > y[i] ? a : b;
+			U Result2 = z[i] > w[i] ? c : d;
+			Result[i] = Test1 > Test2 ? Result1 : Result2;
+		}
+		return Result;
+	}
+
+	// Max comparison between 4 variables
+	template<typename T, typename U> 
+	inline detail::_xvec3<U> associatedMaxGTX
+	(
+		const detail::_xvec3<T>& x, U a, 
+		const detail::_xvec3<T>& y, U b,
+		const detail::_xvec3<T>& z, U c,
+		const detail::_xvec3<T>& w, U d
+	)
+	{
+		detail::_xvec3<U> Result;
+		for(detail::_xvec3<T>::size_type i = 0; i < detail::_xvec3<T>::value_size; ++i)
+		{
+			T Test1 = max(x[i], y[i]);
+			T Test2 = max(z[i], w[i]);;
+			U Result1 = x[i] > y[i] ? a : b;
+			U Result2 = z[i] > w[i] ? c : d;
+			Result[i] = Test1 > Test2 ? Result1 : Result2;
+		}
+		return Result;
+	}
+
+	// Max comparison between 4 variables
+	template<typename T, typename U> 
+	inline detail::_xvec4<U> associatedMaxGTX
+	(
+		const detail::_xvec4<T>& x, U a, 
+		const detail::_xvec4<T>& y, U b,
+		const detail::_xvec4<T>& z, U c,
+		const detail::_xvec4<T>& w, U d
+	)
+	{
+		detail::_xvec4<U> Result;
+		for(detail::_xvec4<T>::size_type i = 0; i < detail::_xvec4<T>::value_size; ++i)
+		{
+			T Test1 = max(x[i], y[i]);
+			T Test2 = max(z[i], w[i]);;
+			U Result1 = x[i] > y[i] ? a : b;
+			U Result2 = z[i] > w[i] ? c : d;
+			Result[i] = Test1 > Test2 ? Result1 : Result2;
+		}
+		return Result;
+	}
+}

+ 76 - 0
experimental/sse/glm/ext/gtx/bit.h

@@ -0,0 +1,76 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2008 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2007-03-14
+// Updated : 2007-03-14
+// Licence : This source is under GNU LGPL licence
+// File    : glm/gtx/bit.h
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Dependency:
+// - GLM core
+// - GLM_GTX_gpu_shader4
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef __glm_gtx_bit__
+#define __glm_gtx_bit__
+
+// Dependency:
+#include "../../glm.h"
+#include "../../ext/gtx/gpu_shader4.h"
+
+namespace glm
+{
+	template <typename T> int highestBitGTX(const T value);                                             //!< \brief Find the highest bit set to 1 in a integer variable. (From GLM_GTX_bit extension) 
+	template <typename T> detail::_xvec2<int> highestBitGTX(const detail::_xvec2<T>& value);			//!< \brief Find the highest bit set to 1 in a integer variable. (From GLM_GTX_bit extension) 
+	template <typename T> detail::_xvec3<int> highestBitGTX(const detail::_xvec3<T>& value);			//!< \brief Find the highest bit set to 1 in a integer variable. (From GLM_GTX_bit extension) 
+	template <typename T> detail::_xvec4<int> highestBitGTX(const detail::_xvec4<T>& value);			//!< \brief Find the highest bit set to 1 in a integer variable. (From GLM_GTX_bit extension) 
+
+	template <typename T> T highestBitValueGTX(const T value);											//!< \brief Find the highest bit set to 1 in a integer variable and return its value. (From GLM_GTX_bit extension)
+	template <typename T> detail::_xvec2<int> highestBitValueGTX(const detail::_xvec2<T>& value);		//!< \brief Find the highest bit set to 1 in a integer variable and return its value. (From GLM_GTX_bit extension)
+	template <typename T> detail::_xvec3<int> highestBitValueGTX(const detail::_xvec3<T>& value);		//!< \brief Find the highest bit set to 1 in a integer variable and return its value. (From GLM_GTX_bit extension)
+	template <typename T> detail::_xvec4<int> highestBitValueGTX(const detail::_xvec4<T>& value);		//!< \brief Find the highest bit set to 1 in a integer variable and return its value. (From GLM_GTX_bit extension)
+
+	template <typename T> bool isPowerOfTwoGTX(const T value);											//!< \brief Return true if the value is a power of two number. (From GLM_GTX_bit extension) 
+	template <typename T> detail::_bvec2 isPowerOfTwoGTX(const detail::_xvec2<T>& value);				//!< \brief Return true if the value is a power of two number. (From GLM_GTX_bit extension) 
+	template <typename T> detail::_bvec3 isPowerOfTwoGTX(const detail::_xvec3<T>& value);				//!< \brief Return true if the value is a power of two number. (From GLM_GTX_bit extension) 
+	template <typename T> detail::_bvec4 isPowerOfTwoGTX(const detail::_xvec4<T>& value);				//!< \brief Return true if the value is a power of two number. (From GLM_GTX_bit extension) 
+
+	template <typename T> T powerOfTwoAboveGTX(const T value);											//!< \brief Return the power of two number which value is just higher the input value. (From GLM_GTX_bit extension) 
+	template <typename T> detail::_xvec2<T> powerOfTwoAboveGTX(const detail::_xvec2<T>& value);			//!< \brief Return the power of two number which value is just higher the input value. (From GLM_GTX_bit extension) 
+	template <typename T> detail::_xvec3<T> powerOfTwoAboveGTX(const detail::_xvec3<T>& value);			//!< \brief Return the power of two number which value is just higher the input value. (From GLM_GTX_bit extension) 
+	template <typename T> detail::_xvec4<T> powerOfTwoAboveGTX(const detail::_xvec4<T>& value);			//!< \brief Return the power of two number which value is just higher the input value. (From GLM_GTX_bit extension) 
+
+	template <typename T> T powerOfTwoBelowGTX(const T value);											//!< \brief Return the power of two number which value is just lower the input value. (From GLM_GTX_bit extension) 
+	template <typename T> detail::_xvec2<T> powerOfTwoBelowGTX(const detail::_xvec2<T>& value);			//!< \brief Return the power of two number which value is just lower the input value. (From GLM_GTX_bit extension) 
+	template <typename T> detail::_xvec3<T> powerOfTwoBelowGTX(const detail::_xvec3<T>& value);			//!< \brief Return the power of two number which value is just lower the input value. (From GLM_GTX_bit extension) 
+	template <typename T> detail::_xvec4<T> powerOfTwoBelowGTX(const detail::_xvec4<T>& value);			//!< \brief Return the power of two number which value is just lower the input value. (From GLM_GTX_bit extension) 
+
+	template <typename T> T powerOfTwoNearestGTX(const T value);										//!< \brief Return the power of two number which value is the closet to the input value. (From GLM_GTX_bit extension) 
+	template <typename T> detail::_xvec2<T> powerOfTwoNearestGTX(const detail::_xvec2<T>& value);		//!< \brief Return the power of two number which value is the closet to the input value. (From GLM_GTX_bit extension) 
+	template <typename T> detail::_xvec3<T> powerOfTwoNearestGTX(const detail::_xvec3<T>& value);		//!< \brief Return the power of two number which value is the closet to the input value. (From GLM_GTX_bit extension) 
+	template <typename T> detail::_xvec4<T> powerOfTwoNearestGTX(const detail::_xvec4<T>& value);		//!< \brief Return the power of two number which value is the closet to the input value. (From GLM_GTX_bit extension) 
+
+	namespace gtx 
+	{
+		//! GLM_GTX_bit extension: Allow to perform bit operations on integer values
+		namespace bit 
+		{
+			template <typename T> inline int highestBit(const T& value){return highestBitGTX(value);}				//!< \brief Find the highest bit set to 1 in a integer variable. (From GLM_GTX_bit extension) 
+			template <typename T> inline T highestBitValue(const T& value){return highestBitValueGTX(value);}		//!< \brief Find the highest bit set to 1 in a integer variable and return its value. (From GLM_GTX_bit extension)
+			template <typename T> inline bool isPowerOfTwo(const T& value){return isPowerOfTwoGTX(value);}			//!< \brief Return true if the value is a power of two number. (From GLM_GTX_bit extension) 
+			template <typename T> inline T powerOfTwoAbove(const T& value){return powerOfTwoAboveGTX(value);}		//!< \brief Return the power of two number which value is just higher the input value. (From GLM_GTX_bit extension) 
+			template <typename T> inline T powerOfTwoBelow(const T& value){return powerOfTwoBelowGTX(value);}		//!< \brief Return the power of two number which value is just lower the input value. (From GLM_GTX_bit extension) 
+			template <typename T> inline T powerOfTwoNearest(const T& value){return powerOfTwoNearestGTX(value);}	//!< \brief Return the power of two number which value is the closet to the input value. (From GLM_GTX_bit extension) 
+		}
+	}
+}
+
+#define GLM_GTX_bit namespace gtx::bit
+
+#include "bit.inl"
+
+#ifdef GLM_GTX_INCLUDED
+namespace glm{using GLM_GTX_bit;}
+#endif//GLM_GTX_INCLUDED
+
+#endif//__glm_gtx_bit__

+ 242 - 0
experimental/sse/glm/ext/gtx/bit.inl

@@ -0,0 +1,242 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2008 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2007-03-14
+// Updated : 2007-03-14
+// Licence : This source is under GNU LGPL licence
+// File    : glm/gtx/bit.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef __glm_gtx_bit_inl__
+#define __glm_gtx_bit_inl__
+
+namespace glm
+{
+	// highestBitGTX
+	template <typename T>
+	inline int highestBitGTX(const T value)
+	{
+		T bit = -1;
+		for(T tmp = value; tmp; tmp >>= 1, ++bit);
+		return bit;
+	}
+
+	template <> 
+	inline int highestBitGTX<int>(const int value)
+	{
+		int bit = -1;
+		for(int tmp = value; tmp; tmp >>= 1, ++bit);
+		return bit;
+	}
+
+	template <typename T>
+	inline detail::_xvec2<int> highestBitGTX(const detail::_xvec2<T>& value)
+	{
+		return detail::_xvec2<int>(
+			highestBitGTX(value[0]),
+			highestBitGTX(value[1]));
+	}
+
+	template <typename T>
+	inline detail::_xvec3<int> highestBitGTX(const detail::_xvec3<T>& value)
+	{
+		return detail::_xvec3<int>(
+			highestBitGTX(value[0]),
+			highestBitGTX(value[1]),
+			highestBitGTX(value[2]));
+	}
+
+	template <typename T>
+	inline detail::_xvec4<int> highestBitGTX(const detail::_xvec4<T>& value)
+	{
+		return detail::_xvec4<int>(
+			highestBitGTX(value[0]),
+			highestBitGTX(value[1]),
+			highestBitGTX(value[2]),
+			highestBitGTX(value[3]));
+	}
+
+	// highestBitValueGTX
+	template <typename T>
+	inline T highestBitValueGTX(const T value)
+	{
+		T tmp = value;
+		T result = T(0);
+		while(tmp)
+		{
+			result = (tmp & (~tmp + 1)); // grab lowest bit
+			tmp &= ~result; // clear lowest bit
+		}
+		return result;
+	}
+
+	template <typename T>
+	inline detail::_xvec2<int> highestBitValueGTX(const detail::_xvec2<T>& value)
+	{
+		return detail::_xvec2<int>(
+			highestBitValueGTX(value[0]),
+			highestBitValueGTX(value[1]));
+	}
+
+	template <typename T>
+	inline detail::_xvec3<int> highestBitValueGTX(const detail::_xvec3<T>& value)
+	{
+		return detail::_xvec3<int>(
+			highestBitValueGTX(value[0]),
+			highestBitValueGTX(value[1]),
+			highestBitValueGTX(value[2]));
+	}
+
+	template <typename T>
+	inline detail::_xvec4<int> highestBitValueGTX(const detail::_xvec4<T>& value)
+	{
+		return detail::_xvec4<int>(
+			highestBitValueGTX(value[0]),
+			highestBitValueGTX(value[1]),
+			highestBitValueGTX(value[2]),
+			highestBitValueGTX(value[3]));
+	}
+
+	// isPowerOfTwoGTX
+	template <typename T>
+	inline bool isPowerOfTwoGTX(const T value)
+	{
+		return !(value & (value - 1));
+	}
+
+	template <typename T>
+	inline detail::_bvec2 isPowerOfTwoGTX(const detail::_xvec2<T>& value)
+	{
+		return detail::_bvec2(
+			isPowerOfTwoGTX(value[0]),
+			isPowerOfTwoGTX(value[1]));
+	}
+
+	template <typename T>
+	inline detail::_bvec3 isPowerOfTwoGTX(const detail::_xvec3<T>& value)
+	{
+		return detail::_bvec3(
+			isPowerOfTwoGTX(value[0]),
+			isPowerOfTwoGTX(value[1]),
+			isPowerOfTwoGTX(value[2]));
+	}
+
+	template <typename T>
+	inline detail::_bvec4 isPowerOfTwoGTX(const detail::_xvec4<T>& value)
+	{
+		return detail::_bvec4(
+			isPowerOfTwoGTX(value[0]),
+			isPowerOfTwoGTX(value[1]),
+			isPowerOfTwoGTX(value[2]),
+			isPowerOfTwoGTX(value[3]));
+	}
+
+	// powerOfTwoAboveGTX
+	template <typename T>
+	inline T powerOfTwoAboveGTX(const T value)
+	{
+		return isPowerOfTwoGTX(value) ? value : highestBitValueGTX(value) << 1;
+	}
+
+	template <typename T>
+	inline detail::_xvec2<T> powerOfTwoAboveGTX(const detail::_xvec2<T>& value)
+	{
+		return detail::_xvec2<T>(
+			powerOfTwoAboveGTX(value[0]),
+			powerOfTwoAboveGTX(value[1]));
+	}
+
+	template <typename T>
+	inline detail::_xvec3<T> powerOfTwoAboveGTX(const detail::_xvec3<T>& value)
+	{
+		return detail::_xvec3<T>(
+			powerOfTwoAboveGTX(value[0]),
+			powerOfTwoAboveGTX(value[1]),
+			powerOfTwoAboveGTX(value[2]));
+	}
+
+	template <typename T>
+	inline detail::_xvec4<T> powerOfTwoAboveGTX(const detail::_xvec4<T>& value)
+	{
+		return detail::_xvec4<T>(
+			powerOfTwoAboveGTX(value[0]),
+			powerOfTwoAboveGTX(value[1]),
+			powerOfTwoAboveGTX(value[2]),
+			powerOfTwoAboveGTX(value[3]));
+	}
+
+	// powerOfTwoBelowGTX
+	template <typename T>
+	inline T powerOfTwoBelowGTX(const T value)
+	{
+		return isPowerOfTwoGTX(value) ? value : highestBitValueGTX(value);
+	}
+
+	template <typename T>
+	inline detail::_xvec2<T> powerOfTwoBelowGTX(const detail::_xvec2<T>& value)
+	{
+		return detail::_xvec2<T>(
+			powerOfTwoBelowGTX(value[0]),
+			powerOfTwoBelowGTX(value[1]));
+	}
+
+	template <typename T>
+	inline detail::_xvec3<T> powerOfTwoBelowGTX(const detail::_xvec3<T>& value)
+	{
+		return detail::_xvec3<T>(
+			powerOfTwoBelowGTX(value[0]),
+			powerOfTwoBelowGTX(value[1]),
+			powerOfTwoBelowGTX(value[2]));
+	}
+
+	template <typename T>
+	inline detail::_xvec4<T> powerOfTwoBelowGTX(const detail::_xvec4<T>& value)
+	{
+		return detail::_xvec4<T>(
+			powerOfTwoBelowGTX(value[0]),
+			powerOfTwoBelowGTX(value[1]),
+			powerOfTwoBelowGTX(value[2]),
+			powerOfTwoBelowGTX(value[3]));
+	}
+
+	// powerOfTwoNearestGTX
+	template <typename T>
+	inline T powerOfTwoNearestGTX(const T value)
+	{
+		if(isPowerOfTwoGTX(value)) 
+			return value;
+
+		T prev = highestBitValueGTX(value);
+		T next = prev << 1;
+		return (next - value) < (value - prev) ? next : prev;
+	}
+
+	template <typename T>
+	inline detail::_xvec2<T> powerOfTwoNearestGTX(const detail::_xvec2<T>& value)
+	{
+		return detail::_xvec2<T>(
+			powerOfTwoNearestGTX(value[0]),
+			powerOfTwoNearestGTX(value[1]));
+	}
+
+	template <typename T>
+	inline detail::_xvec3<T> powerOfTwoNearestGTX(const detail::_xvec3<T>& value)
+	{
+		return detail::_xvec3<T>(
+			powerOfTwoNearestGTX(value[0]),
+			powerOfTwoNearestGTX(value[1]),
+			powerOfTwoNearestGTX(value[2]));
+	}
+
+	template <typename T>
+	inline detail::_xvec4<T> powerOfTwoNearestGTX(const detail::_xvec4<T>& value)
+	{
+		return detail::_xvec4<T>(
+			powerOfTwoNearestGTX(value[0]),
+			powerOfTwoNearestGTX(value[1]),
+			powerOfTwoNearestGTX(value[2]),
+			powerOfTwoNearestGTX(value[3]));
+	}
+}
+
+#endif//__glm_gtx_bit_inl__

+ 54 - 0
experimental/sse/glm/ext/gtx/closest_point.h

@@ -0,0 +1,54 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2008 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2005-12-30
+// Updated : 2006-11-13
+// Licence : This source is under GNU LGPL licence
+// File    : glm/gtx/closest_point.h
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Dependency:
+// - GLM core
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef __glm_gtx_closest_point__
+#define __glm_gtx_closest_point__
+
+// Dependency:
+#include "../../glm.h"
+
+namespace glm
+{
+	//! Find the point on a straight line which is the closet of a point. (from GLM_GTX_closest_point extension) 
+    template <typename T> 
+	detail::_xvec3<T> closestPointOnLineGTX(
+		const detail::_xvec3<T>& point, 
+		const detail::_xvec3<T>& a, 
+		const detail::_xvec3<T>& b); 
+
+	namespace gtx
+	{
+		//! GLM_GTX_closest_point extension: Find the point on a straight line which is the closet of a point.
+		namespace closest_point
+		{
+			//! Find the point on a straight line which is the closet of a point. (from GLM_GTX_closest_point extension) 		
+			template <typename T> 
+			inline detail::_xvec3<T> closestPointOnLine(
+				const detail::_xvec3<T>& point, 
+				const detail::_xvec3<T>& a, 
+				const detail::_xvec3<T>& b)
+			{
+				return closestPointOnLineGTX(point, a, b);
+			}
+		}
+	}
+}
+
+#define GLM_GTX_closest_point namespace gtx::closest_point
+
+#include "closest_point.inl"
+
+#ifdef GLM_GTX_INCLUDED
+namespace glm{using GLM_GTX_closest_point;}
+#endif//GLM_GTX_INCLUDED
+
+#endif//__glm_gtx_closest_point__

+ 31 - 0
experimental/sse/glm/ext/gtx/closest_point.inl

@@ -0,0 +1,31 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2008 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2005-12-30
+// Updated : 2006-01-04
+// Licence : This source is under GNU LGPL licence
+// File    : glm/gtx/closest_point.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef __glm_gtx_closest_point_inl__
+#define __glm_gtx_closest_point_inl__
+
+namespace glm
+{
+    template <typename T> 
+    inline detail::_xvec3<T> closestPointOnLineGTX(const detail::_xvec3<T>& point, const detail::_xvec3<T>& a, const detail::_xvec3<T>& b)
+    {
+        T LineLength = distance(a, b);
+        detail::_xvec3<T> Vector = point - a;
+        detail::_xvec3<T> LineDirection = (b - a) / LineLength;
+
+        // Project Vector to LineDirection to get the distance of point from a
+        T Distance = dot(Vector, LineDirection);
+
+        if(Distance <= 0) return a;
+        if(Distance >= LineLength) return b;
+        return a + LineDirection * Distance;
+    }
+}
+
+#endif//__glm_gtx_closest_point_inl__

+ 165 - 0
experimental/sse/glm/ext/gtx/color_cast.h

@@ -0,0 +1,165 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2008 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2007-06-21
+// Updated : 2007-08-03
+// Licence : This source is under GNU LGPL licence
+// File    : glm/gtx/color_cast.h
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Dependency:
+// - GLM core
+// - GLM_GTX_half
+// - GLM_GTX_double
+// - GLM_GTX_int
+// - GLM_GTX_unsigned_int
+// - GLM_GTX_number_precision
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef __glm_gtx_color_cast__
+#define __glm_gtx_color_cast__
+
+// Dependency:
+#include "../../glm.h"
+#include "../gtx/half.h"
+#include "../gtx/double.h"
+#include "../gtx/integer.h"
+#include "../gtx/unsigned_int.h"
+#include "../gtx/number_precision.h"
+
+namespace glm
+{
+	template <typename T> __uint8GTX u8channel_castGTX(T a);							//!< Conversion of a floating value into a 8bit unsigned int value. (From GLM_GTX_color_cast extension)
+	template <typename T> __uint16GTX u16channel_castGTX(T a);							//!< Conversion of a floating value into a 16bit unsigned int value. (From GLM_GTX_color_cast extension)
+
+	template <typename T> __uint32GTX u32_rgbx_castGTX(const detail::_xvec3<T>& c);     //!< Conversion of a 3 components color into an 32bit unsigned int value. (From GLM_GTX_color_cast extension)
+	template <typename T> __uint32GTX u32_xrgb_castGTX(const detail::_xvec3<T>& c);     //!< Conversion of a 3 components color into an 32bit unsigned int value. (From GLM_GTX_color_cast extension)
+	template <typename T> __uint32GTX u32_bgrx_castGTX(const detail::_xvec3<T>& c);     //!< Conversion of a 3 components color into an 32bit unsigned int value. (From GLM_GTX_color_cast extension)
+	template <typename T> __uint32GTX u32_xbgr_castGTX(const detail::_xvec3<T>& c);     //!< Conversion of a 3 components color into an 32bit unsigned int value. (From GLM_GTX_color_cast extension)
+
+	template <typename T> __uint32GTX u32_rgba_castGTX(const detail::_xvec4<T>& c);     //!< Conversion of a 4 components color into an 32bit unsigned int value. (From GLM_GTX_color_cast extension)
+	template <typename T> __uint32GTX u32_argb_castGTX(const detail::_xvec4<T>& c);     //!< Conversion of a 4 components color into an 32bit unsigned int value. (From GLM_GTX_color_cast extension)
+	template <typename T> __uint32GTX u32_bgra_castGTX(const detail::_xvec4<T>& c);     //!< Conversion of a 4 components color into an 32bit unsigned int value. (From GLM_GTX_color_cast extension)
+	template <typename T> __uint32GTX u32_abgr_castGTX(const detail::_xvec4<T>& c);     //!< Conversion of a 4 components color into an 32bit unsigned int value. (From GLM_GTX_color_cast extension)
+
+	template <typename T> __uint64GTX u64_rgbx_castGTX(const detail::_xvec3<T>& c);     //!< Conversion of a 3 components color into an 64bit unsigned int value. (From GLM_GTX_color_cast extension)
+	template <typename T> __uint64GTX u64_xrgb_castGTX(const detail::_xvec3<T>& c);     //!< Conversion of a 3 components color into an 64bit unsigned int value. (From GLM_GTX_color_cast extension)
+	template <typename T> __uint64GTX u64_bgrx_castGTX(const detail::_xvec3<T>& c);     //!< Conversion of a 3 components color into an 64bit unsigned int value. (From GLM_GTX_color_cast extension)
+	template <typename T> __uint64GTX u64_xbgr_castGTX(const detail::_xvec3<T>& c);     //!< Conversion of a 3 components color into an 64bit unsigned int value. (From GLM_GTX_color_cast extension)
+
+	template <typename T> __uint64GTX u64_rgba_castGTX(const detail::_xvec4<T>& c);     //!< Conversion of a 4 components color into an 64bit unsigned int value. (From GLM_GTX_color_cast extension)
+	template <typename T> __uint64GTX u64_argb_castGTX(const detail::_xvec4<T>& c);     //!< Conversion of a 4 components color into an 64bit unsigned int value. (From GLM_GTX_color_cast extension)
+	template <typename T> __uint64GTX u64_bgra_castGTX(const detail::_xvec4<T>& c);     //!< Conversion of a 4 components color into an 64bit unsigned int value. (From GLM_GTX_color_cast extension)
+	template <typename T> __uint64GTX u64_abgr_castGTX(const detail::_xvec4<T>& c);     //!< Conversion of a 4 components color into an 64bit unsigned int value. (From GLM_GTX_color_cast extension)
+
+	template <typename T> __halfGTX f16_channel_castGTX(T a);							//!< Conversion of a u8 or u16 value to a single channel floating value. (From GLM_GTX_color_cast extension)
+
+	template <typename T> detail::_xvec3<__halfGTX> f16_rgbx_castGTX(T color);          //!< Conversion of a u32 or u64 color into 3 components floating color. (From GLM_GTX_color_cast extension)
+	template <typename T> detail::_xvec3<__halfGTX> f16_xrgb_castGTX(T color);          //!< Conversion of a u32 or u64 color into 3 components floating color. (From GLM_GTX_color_cast extension)
+	template <typename T> detail::_xvec3<__halfGTX> f16_bgrx_castGTX(T color);          //!< Conversion of a u32 or u64 color into 3 components floating color. (From GLM_GTX_color_cast extension)
+	template <typename T> detail::_xvec3<__halfGTX> f16_xbgr_castGTX(T color);          //!< Conversion of a u32 or u64 color into 3 components floating color. (From GLM_GTX_color_cast extension)
+
+	template <typename T> detail::_xvec4<__halfGTX> f16_rgba_castGTX(T color);          //!< Conversion of a u32 or u64 color into 4 components floating color. (From GLM_GTX_color_cast extension)
+	template <typename T> detail::_xvec4<__halfGTX> f16_argb_castGTX(T color);          //!< Conversion of a u32 or u64 color into 4 components floating color. (From GLM_GTX_color_cast extension)
+	template <typename T> detail::_xvec4<__halfGTX> f16_bgra_castGTX(T color);          //!< Conversion of a u32 or u64 color into 4 components floating color. (From GLM_GTX_color_cast extension)
+	template <typename T> detail::_xvec4<__halfGTX> f16_abgr_castGTX(T color);          //!< Conversion of a u32 or u64 color into 4 components floating color. (From GLM_GTX_color_cast extension)
+
+	template <typename T> float f32_channel_castGTX(T a);								//!< Conversion of a u8 or u16 value to a single channel floating value. (From GLM_GTX_color_cast extension)
+
+	template <typename T> detail::_xvec3<float> f32_rgbx_castGTX(T color);              //!< Conversion of a u32 or u64 color into 3 components floating color. (From GLM_GTX_color_cast extension)
+	template <typename T> detail::_xvec3<float> f32_xrgb_castGTX(T color);              //!< Conversion of a u32 or u64 color into 3 components floating color. (From GLM_GTX_color_cast extension)
+	template <typename T> detail::_xvec3<float> f32_bgrx_castGTX(T color);              //!< Conversion of a u32 or u64 color into 3 components floating color. (From GLM_GTX_color_cast extension)
+	template <typename T> detail::_xvec3<float> f32_xbgr_castGTX(T color);              //!< Conversion of a u32 or u64 color into 3 components floating color. (From GLM_GTX_color_cast extension)
+
+	template <typename T> detail::_xvec4<float> f32_rgba_castGTX(T color);              //!< Conversion of a u32 or u64 color into 4 components floating color. (From GLM_GTX_color_cast extension)
+	template <typename T> detail::_xvec4<float> f32_argb_castGTX(T color);              //!< Conversion of a u32 or u64 color into 4 components floating color. (From GLM_GTX_color_cast extension)
+	template <typename T> detail::_xvec4<float> f32_bgra_castGTX(T color);              //!< Conversion of a u32 or u64 color into 4 components floating color. (From GLM_GTX_color_cast extension)
+	template <typename T> detail::_xvec4<float> f32_abgr_castGTX(T color);              //!< Conversion of a u32 or u64 color into 4 components floating color. (From GLM_GTX_color_cast extension)
+
+	template <typename T> double f64_channel_castGTX(T a);								//!< Conversion of a u8 or u16 value to a single channel floating value. (From GLM_GTX_color_cast extension)
+
+	template <typename T> detail::_xvec3<double> f64_rgbx_castGTX(T color);             //!< Conversion of a u32 or u64 color into 3 components floating color. (From GLM_GTX_color_cast extension)
+	template <typename T> detail::_xvec3<double> f64_xrgb_castGTX(T color);             //!< Conversion of a u32 or u64 color into 3 components floating color. (From GLM_GTX_color_cast extension)
+	template <typename T> detail::_xvec3<double> f64_bgrx_castGTX(T color);             //!< Conversion of a u32 or u64 color into 3 components floating color. (From GLM_GTX_color_cast extension)
+	template <typename T> detail::_xvec3<double> f64_xbgr_castGTX(T color);             //!< Conversion of a u32 or u64 color into 3 components floating color. (From GLM_GTX_color_cast extension)
+
+	template <typename T> detail::_xvec4<double> f64_rgba_castGTX(T color);             //!< Conversion of a u32 or u64 color into 4 components floating color. (From GLM_GTX_color_cast extension)
+	template <typename T> detail::_xvec4<double> f64_argb_castGTX(T color);             //!< Conversion of a u32 or u64 color into 4 components floating color. (From GLM_GTX_color_cast extension)
+	template <typename T> detail::_xvec4<double> f64_bgra_castGTX(T color);             //!< Conversion of a u32 or u64 color into 4 components floating color. (From GLM_GTX_color_cast extension)
+	template <typename T> detail::_xvec4<double> f64_abgr_castGTX(T color);             //!< Conversion of a u32 or u64 color into 4 components floating color. (From GLM_GTX_color_cast extension)
+
+	namespace gtx
+	{
+		//! GLM_GTX_color_cast extension: Conversion between two color types
+		namespace color_cast
+		{
+			template <typename T> inline __uint8GTX u8channel_cast(T a){return u8channel_castGTX(a);}							//!< Conversion of a floating value into a 8bit unsigned int value. (From GLM_GTX_color_cast extension)
+			template <typename T> inline __uint16GTX u16channel_cast(T a){return u16channel_castGTX(a);}						//!< Conversion of a floating value into a 16bit unsigned int value. (From GLM_GTX_color_cast extension)
+
+			template <typename T> inline __uint32GTX u32_rgbx_cast(const detail::_xvec3<T>& c){return u32_rgbx_castGTX(c);}     //!< Conversion of a 3 components color into an 32bit unsigned int value. (From GLM_GTX_color_cast extension)
+			template <typename T> inline __uint32GTX u32_xrgb_cast(const detail::_xvec3<T>& c){return u32_xrgb_castGTX(c);}     //!< Conversion of a 3 components color into an 32bit unsigned int value. (From GLM_GTX_color_cast extension)
+			template <typename T> inline __uint32GTX u32_bgrx_cast(const detail::_xvec3<T>& c){return u32_bgrx_castGTX(c);}     //!< Conversion of a 3 components color into an 32bit unsigned int value. (From GLM_GTX_color_cast extension)
+			template <typename T> inline __uint32GTX u32_xbgr_cast(const detail::_xvec3<T>& c){return u32_xbgr_castGTX(c);}     //!< Conversion of a 3 components color into an 32bit unsigned int value. (From GLM_GTX_color_cast extension)
+
+			template <typename T> inline __uint32GTX u32_rgba_cast(const detail::_xvec4<T>& c){return u32_rgba_castGTX(c);}     //!< Conversion of a 4 components color into an 32bit unsigned int value. (From GLM_GTX_color_cast extension)
+			template <typename T> inline __uint32GTX u32_argb_cast(const detail::_xvec4<T>& c){return u32_argb_castGTX(c);}     //!< Conversion of a 4 components color into an 32bit unsigned int value. (From GLM_GTX_color_cast extension)
+			template <typename T> inline __uint32GTX u32_bgra_cast(const detail::_xvec4<T>& c){return u32_bgra_castGTX(c);}     //!< Conversion of a 4 components color into an 32bit unsigned int value. (From GLM_GTX_color_cast extension)
+			template <typename T> inline __uint32GTX u32_abgr_cast(const detail::_xvec4<T>& c){return u32_abgr_castGTX(c);}     //!< Conversion of a 4 components color into an 32bit unsigned int value. (From GLM_GTX_color_cast extension)
+
+			template <typename T> inline __uint64GTX u64_rgbx_cast(const detail::_xvec3<T>& c){return u32_rgbx_castGTX(c);}     //!< Conversion of a 3 components color into an 64bit unsigned int value. (From GLM_GTX_color_cast extension)
+			template <typename T> inline __uint64GTX u64_xrgb_cast(const detail::_xvec3<T>& c){return u32_xrgb_castGTX(c);}     //!< Conversion of a 3 components color into an 64bit unsigned int value. (From GLM_GTX_color_cast extension)
+			template <typename T> inline __uint64GTX u64_bgrx_cast(const detail::_xvec3<T>& c){return u32_bgrx_castGTX(c);}     //!< Conversion of a 3 components color into an 64bit unsigned int value. (From GLM_GTX_color_cast extension)
+			template <typename T> inline __uint64GTX u64_xbgr_cast(const detail::_xvec3<T>& c){return u32_xbgr_castGTX(c);}     //!< Conversion of a 3 components color into an 64bit unsigned int value. (From GLM_GTX_color_cast extension)
+
+			template <typename T> inline __uint64GTX u64_rgba_cast(const detail::_xvec4<T>& c){return u32_rgba_castGTX(c);}     //!< Conversion of a 4 components color into an 64bit unsigned int value. (From GLM_GTX_color_cast extension)
+			template <typename T> inline __uint64GTX u64_argb_cast(const detail::_xvec4<T>& c){return u32_argb_castGTX(c);}     //!< Conversion of a 4 components color into an 64bit unsigned int value. (From GLM_GTX_color_cast extension)
+			template <typename T> inline __uint64GTX u64_bgra_cast(const detail::_xvec4<T>& c){return u32_bgra_castGTX(c);}     //!< Conversion of a 4 components color into an 64bit unsigned int value. (From GLM_GTX_color_cast extension)
+			template <typename T> inline __uint64GTX u64_abgr_cast(const detail::_xvec4<T>& c){return u32_abgr_castGTX(c);}     //!< Conversion of a 4 components color into an 64bit unsigned int value. (From GLM_GTX_color_cast extension)
+
+			template <typename T> inline __halfGTX f16_channel_cast(T a){return f16_channel_castGTX(a);}						//!< Conversion of a u8 or u16 value to a single channel floating value. (From GLM_GTX_color_cast extension)
+
+			template <typename T> inline detail::_xvec3<__halfGTX> f16_rgbx_cast(T c){return f16_rgbx_castGTX(c);}              //!< Conversion of a u32 or u64 color into 3 components floating color. (From GLM_GTX_color_cast extension)
+			template <typename T> inline detail::_xvec3<__halfGTX> f16_xrgb_cast(T c){return f16_xrgb_castGTX(c);}              //!< Conversion of a u32 or u64 color into 3 components floating color. (From GLM_GTX_color_cast extension)
+			template <typename T> inline detail::_xvec3<__halfGTX> f16_bgrx_cast(T c){return f16_bgrx_castGTX(c);}              //!< Conversion of a u32 or u64 color into 3 components floating color. (From GLM_GTX_color_cast extension)
+			template <typename T> inline detail::_xvec3<__halfGTX> f16_xbgr_cast(T c){return f16_xbgr_castGTX(c);}              //!< Conversion of a u32 or u64 color into 3 components floating color. (From GLM_GTX_color_cast extension)
+
+			template <typename T> inline detail::_xvec4<__halfGTX> f16_rgba_cast(T c){return f16_rgba_castGTX(c);}              //!< Conversion of a u32 or u64 color into 4 components floating color. (From GLM_GTX_color_cast extension)
+			template <typename T> inline detail::_xvec4<__halfGTX> f16_argb_cast(T c){return f16_argb_castGTX(c);}              //!< Conversion of a u32 or u64 color into 4 components floating color. (From GLM_GTX_color_cast extension)
+			template <typename T> inline detail::_xvec4<__halfGTX> f16_bgra_cast(T c){return f16_bgra_castGTX(c);}              //!< Conversion of a u32 or u64 color into 4 components floating color. (From GLM_GTX_color_cast extension)
+			template <typename T> inline detail::_xvec4<__halfGTX> f16_abgr_cast(T c){return f16_abgr_castGTX(c);}              //!< Conversion of a u32 or u64 color into 4 components floating color. (From GLM_GTX_color_cast extension)
+
+			template <typename T> inline float f32_channel_cast(T a){return f32_channel_castGTX(a);}							//!< Conversion of a u8 or u16 value to a single channel floating value. (From GLM_GTX_color_cast extension)
+
+			template <typename T> inline detail::_xvec3<float> f32_rgbx_cast(T c){return f32_rgbx_castGTX(c);}                  //!< Conversion of a u32 or u64 color into 3 components floating color. (From GLM_GTX_color_cast extension)
+			template <typename T> inline detail::_xvec3<float> f32_xrgb_cast(T c){return f32_xrgb_castGTX(c);}                  //!< Conversion of a u32 or u64 color into 3 components floating color. (From GLM_GTX_color_cast extension)
+			template <typename T> inline detail::_xvec3<float> f32_bgrx_cast(T c){return f32_bgrx_castGTX(c);}                  //!< Conversion of a u32 or u64 color into 3 components floating color. (From GLM_GTX_color_cast extension)
+			template <typename T> inline detail::_xvec3<float> f32_xbgr_cast(T c){return f32_xbgr_castGTX(c);}                  //!< Conversion of a u32 or u64 color into 3 components floating color. (From GLM_GTX_color_cast extension)
+
+			template <typename T> inline detail::_xvec4<float> f32_rgba_cast(T c){return f32_rgba_castGTX(c);}                  //!< Conversion of a u32 or u64 color into 4 components floating color. (From GLM_GTX_color_cast extension)
+			template <typename T> inline detail::_xvec4<float> f32_argb_cast(T c){return f32_argb_castGTX(c);}                  //!< Conversion of a u32 or u64 color into 4 components floating color. (From GLM_GTX_color_cast extension)
+			template <typename T> inline detail::_xvec4<float> f32_bgra_cast(T c){return f32_bgra_castGTX(c);}                  //!< Conversion of a u32 or u64 color into 4 components floating color. (From GLM_GTX_color_cast extension)
+			template <typename T> inline detail::_xvec4<float> f32_abgr_cast(T c){return f32_abgr_castGTX(c);}                  //!< Conversion of a u32 or u64 color into 4 components floating color. (From GLM_GTX_color_cast extension)
+
+			template <typename T> inline double f64_channel_cast(T a){return f64_channel_castGTX(a);}							//!< Conversion of a u8 or u16 value to a single channel floating value. (From GLM_GTX_color_cast extension)
+
+			template <typename T> inline detail::_xvec3<double> f64_rgbx_cast(T c){return f64_rgbx_castGTX(c);}                 //!< Conversion of a u32 or u64 color into 3 components floating color. (From GLM_GTX_color_cast extension)
+			template <typename T> inline detail::_xvec3<double> f64_xrgb_cast(T c){return f64_xrgb_castGTX(c);}                 //!< Conversion of a u32 or u64 color into 3 components floating color. (From GLM_GTX_color_cast extension)
+			template <typename T> inline detail::_xvec3<double> f64_bgrx_cast(T c){return f64_bgrx_castGTX(c);}                 //!< Conversion of a u32 or u64 color into 3 components floating color. (From GLM_GTX_color_cast extension)
+			template <typename T> inline detail::_xvec3<double> f64_xbgr_cast(T c){return f64_xbgr_castGTX(c);}                 //!< Conversion of a u32 or u64 color into 3 components floating color. (From GLM_GTX_color_cast extension)
+
+			template <typename T> inline detail::_xvec4<double> f64_rgba_cast(T c){return f64_rgba_castGTX(c);}                 //!< Conversion of a u32 or u64 color into 4 components floating color. (From GLM_GTX_color_cast extension)
+			template <typename T> inline detail::_xvec4<double> f64_argb_cast(T c){return f64_argb_castGTX(c);}                 //!< Conversion of a u32 or u64 color into 4 components floating color. (From GLM_GTX_color_cast extension)
+			template <typename T> inline detail::_xvec4<double> f64_bgra_cast(T c){return f64_bgra_castGTX(c);}                 //!< Conversion of a u32 or u64 color into 4 components floating color. (From GLM_GTX_color_cast extension)
+			template <typename T> inline detail::_xvec4<double> f64_abgr_cast(T c){return f64_abgr_castGTX(c);}                 //!< Conversion of a u32 or u64 color into 4 components floating color. (From GLM_GTX_color_cast extension)
+		}
+	}
+}
+
+#define GLM_GTX_color_cast namespace gtx::color_cast
+
+#include "color_cast.inl"
+
+#ifdef GLM_GTX_INCLUDED
+namespace glm{using GLM_GTX_color_cast;}
+#endif//GLM_GTX_INCLUDED
+
+#endif//__glm_gtx_color_cast__

+ 737 - 0
experimental/sse/glm/ext/gtx/color_cast.inl

@@ -0,0 +1,737 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2008 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2007-06-21
+// Updated : 2007-08-03
+// Licence : This source is under GNU LGPL licence
+// File    : glm/gtx/color_cast.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace glm
+{
+	template <typename T> 
+	inline __uint8GTX u8channel_castGTX(T a)
+	{
+		return static_cast<__uint8GTX>(a * T(255));
+	}
+
+	template <typename T> 
+	inline __uint16GTX u16channel_castGTX(T a)
+	{
+		return static_cast<__uint16GTX>(a * T(65535));
+	}
+
+	template <typename T>
+	inline __uint32GTX u32_rgbx_castGTX(const detail::_xvec3<T>& c)
+	{
+		__uint32GTX result = 0;
+		result += static_cast<__uint32GTX>(c.x * detail::_xvec3<T>::value_type(255)) <<  0;
+		result += static_cast<__uint32GTX>(c.y * detail::_xvec3<T>::value_type(255)) <<  8;
+		result += static_cast<__uint32GTX>(c.z * detail::_xvec3<T>::value_type(255)) << 16;
+		return result;
+	}
+
+	template <typename T>
+	inline __uint32GTX u32_xrgb_castGTX(const detail::_xvec3<T>& c)
+	{
+		__uint32GTX result = 0;
+        result += static_cast<__uint32GTX>(c.x * detail::_xvec3<T>::value_type(255)) <<  8;
+		result += static_cast<__uint32GTX>(c.y * detail::_xvec3<T>::value_type(255)) << 16;
+		result += static_cast<__uint32GTX>(c.z * detail::_xvec3<T>::value_type(255)) << 24;
+		return result;
+	}
+
+	template <typename T>
+	inline __uint32GTX u32_bgrx_castGTX(const detail::_xvec3<T>& c)
+	{
+		__uint32GTX result = 0;
+		result += static_cast<__uint32GTX>(c.x * detail::_xvec3<T>::value_type(255)) << 16;
+		result += static_cast<__uint32GTX>(c.y * detail::_xvec3<T>::value_type(255)) <<  8;
+		result += static_cast<__uint32GTX>(c.z * detail::_xvec3<T>::value_type(255)) <<  0;
+		return result;
+	}
+
+	template <typename T>
+	inline __uint32GTX u32_xbgr_castGTX(const detail::_xvec3<T>& c)
+	{
+		__uint32GTX result = 0;
+		result += static_cast<__uint32GTX>(c.x * detail::_xvec3<T>::value_type(255)) << 24;
+		result += static_cast<__uint32GTX>(c.y * detail::_xvec3<T>::value_type(255)) << 16;
+		result += static_cast<__uint32GTX>(c.z * detail::_xvec3<T>::value_type(255)) <<  8;
+		result += static_cast<__uint32GTX>(c.w * detail::_xvec3<T>::value_type(255)) <<  0;
+		return result;
+	}
+
+	template <typename T>
+	inline __uint32GTX u32_rgba_castGTX(const detail::_xvec4<T>& c)
+	{
+		__uint32GTX result = 0;
+		result += static_cast<__uint32GTX>(c.x * detail::_xvec4<T>::value_type(255)) <<  0;
+		result += static_cast<__uint32GTX>(c.y * detail::_xvec4<T>::value_type(255)) <<  8;
+		result += static_cast<__uint32GTX>(c.z * detail::_xvec4<T>::value_type(255)) << 16;
+		result += static_cast<__uint32GTX>(c.w * detail::_xvec4<T>::value_type(255)) << 24;
+		return result;
+	}
+
+	template <typename T>
+	inline __uint32GTX u32_argb_castGTX(const detail::_xvec4<T>& c)
+	{
+		__uint32GTX result = 0;
+		result += static_cast<__uint32GTX>(c.x * detail::_xvec4<T>::value_type(255)) <<  8;
+		result += static_cast<__uint32GTX>(c.y * detail::_xvec4<T>::value_type(255)) << 16;
+		result += static_cast<__uint32GTX>(c.z * detail::_xvec4<T>::value_type(255)) << 24;
+		result += static_cast<__uint32GTX>(c.w * detail::_xvec4<T>::value_type(255)) <<  0;
+		return result;
+	}
+
+	template <typename T>
+	inline __uint32GTX u32_bgra_castGTX(const detail::_xvec4<T>& c)
+	{
+		__uint32GTX result = 0;
+		result += static_cast<__uint32GTX>(c.x * detail::_xvec4<T>::value_type(255)) << 16;
+		result += static_cast<__uint32GTX>(c.y * detail::_xvec4<T>::value_type(255)) <<  8;
+		result += static_cast<__uint32GTX>(c.z * detail::_xvec4<T>::value_type(255)) <<  0;
+		result += static_cast<__uint32GTX>(c.w * detail::_xvec4<T>::value_type(255)) << 24;
+		return result;
+	}
+
+	template <typename T>
+	inline __uint32GTX u32_abgr_castGTX(const detail::_xvec4<T>& c)
+	{
+		__uint32GTX result = 0;
+		result += static_cast<__uint32GTX>(c.x * detail::_xvec4<T>::value_type(255)) << 24;
+		result += static_cast<__uint32GTX>(c.y * detail::_xvec4<T>::value_type(255)) << 16;
+		result += static_cast<__uint32GTX>(c.z * detail::_xvec4<T>::value_type(255)) <<  8;
+		result += static_cast<__uint32GTX>(c.w * detail::_xvec4<T>::value_type(255)) <<  0;
+		return result;
+	}
+
+	template <typename T>
+	inline __uint64GTX u64_rgbx_castGTX(const detail::_xvec3<T>& c)
+	{
+		__uint64GTX result = 0;
+		result += static_cast<__uint64GTX>(c.x * detail::_xvec3<T>::value_type(65535)) <<  0;
+		result += static_cast<__uint64GTX>(c.y * detail::_xvec3<T>::value_type(65535)) << 16;
+		result += static_cast<__uint64GTX>(c.z * detail::_xvec3<T>::value_type(65535)) << 32;
+		return result;
+	}
+
+	template <typename T>
+	inline __uint64GTX u32_xrgb_castGTX(const detail::_xvec3<T>& c)
+	{
+		__uint64GTX result = 0;
+		result += static_cast<__uint64GTX>(c.x * detail::_xvec3<T>::value_type(65535)) << 16;
+		result += static_cast<__uint64GTX>(c.y * detail::_xvec3<T>::value_type(65535)) << 32;
+		result += static_cast<__uint64GTX>(c.z * detail::_xvec3<T>::value_type(65535)) << 48;
+		return result;
+	}
+
+	template <typename T>
+	inline __uint64GTX u32_bgrx_castGTX(const detail::_xvec3<T>& c)
+	{
+		__uint64GTX result = 0;
+		result += static_cast<__uint64GTX>(c.x * detail::_xvec3<T>::value_type(65535)) << 32;
+		result += static_cast<__uint64GTX>(c.y * detail::_xvec3<T>::value_type(65535)) << 16;
+		result += static_cast<__uint64GTX>(c.z * detail::_xvec3<T>::value_type(65535)) <<  0;
+		return result;
+	}
+
+	template <typename T>
+	inline __uint64GTX u32_xbgr_castGTX(const detail::_xvec3<T>& c)
+	{
+		__uint64GTX result = 0;
+		result += static_cast<__uint64GTX>(c.x * detail::_xvec3<T>::value_type(65535)) << 48;
+		result += static_cast<__uint64GTX>(c.y * detail::_xvec3<T>::value_type(65535)) << 32;
+		result += static_cast<__uint64GTX>(c.z * detail::_xvec3<T>::value_type(65535)) << 16;
+		result += static_cast<__uint64GTX>(c.w * detail::_xvec3<T>::value_type(65535)) <<  0;
+		return result;
+	}
+
+	template <typename T>
+	inline __uint64GTX u64_rgba_castGTX(const detail::_xvec4<T>& c)
+	{
+		__uint64GTX result = 0;
+		result += static_cast<__uint64GTX>(c.x * detail::_xvec4<T>::value_type(65535)) <<  0;
+		result += static_cast<__uint64GTX>(c.y * detail::_xvec4<T>::value_type(65535)) << 16;
+		result += static_cast<__uint64GTX>(c.z * detail::_xvec4<T>::value_type(65535)) << 32;
+		result += static_cast<__uint64GTX>(c.w * detail::_xvec4<T>::value_type(65535)) << 48;
+		return result;
+	}
+
+	template <typename T>
+	inline __uint64GTX u64_argb_castGTX(const detail::_xvec4<T>& c)
+	{
+		__uint64GTX result = 0;
+		result += static_cast<__uint64GTX>(c.x * detail::_xvec4<T>::value_type(65535)) << 16;
+		result += static_cast<__uint64GTX>(c.y * detail::_xvec4<T>::value_type(65535)) << 32;
+		result += static_cast<__uint64GTX>(c.z * detail::_xvec4<T>::value_type(65535)) << 48;
+		result += static_cast<__uint64GTX>(c.w * detail::_xvec4<T>::value_type(65535)) <<  0;
+		return result;
+	}
+
+	template <typename T>
+	inline __uint64GTX u64_bgra_castGTX(const detail::_xvec4<T>& c)
+	{
+		__uint64GTX result = 0;
+		result += static_cast<__uint64GTX>(c.x * detail::_xvec4<T>::value_type(65535)) << 32;
+		result += static_cast<__uint64GTX>(c.y * detail::_xvec4<T>::value_type(65535)) << 16;
+		result += static_cast<__uint64GTX>(c.z * detail::_xvec4<T>::value_type(65535)) <<  0;
+		result += static_cast<__uint64GTX>(c.w * detail::_xvec4<T>::value_type(65535)) << 48;
+		return result;
+	}
+
+	template <typename T>
+	inline __uint64GTX u64_abgr_castGTX(const detail::_xvec4<T>& c)
+	{
+		__uint64GTX result = 0;
+		result += static_cast<__uint64GTX>(c.x * detail::_xvec4<T>::value_type(65535)) << 48;
+		result += static_cast<__uint64GTX>(c.y * detail::_xvec4<T>::value_type(65535)) << 32;
+		result += static_cast<__uint64GTX>(c.z * detail::_xvec4<T>::value_type(65535)) << 16;
+		result += static_cast<__uint64GTX>(c.w * detail::_xvec4<T>::value_type(65535)) <<  0;
+		return result;
+	}
+
+	template <>
+	inline __halfGTX f16_channel_castGTX<__uint32GTX>(__uint32GTX color)
+	{
+		return __halfGTX(static_cast<float>(color >>  0) / static_cast<float>(255));
+	}
+
+#ifdef GLM_COMPILER_VC
+	template <>
+	inline detail::_xvec3<__halfGTX> f16_rgbx_castGTX<__uint32GTX>(__uint32GTX color)
+	{
+		detail::_xvec3<__halfGTX> result;
+		result.x = __halfGTX(static_cast<float>(color >>  0) / static_cast<float>(255));
+		result.y = __halfGTX(static_cast<float>(color >>  8) / static_cast<float>(255));
+		result.z = __halfGTX(static_cast<float>(color >> 16) / static_cast<float>(255));
+		return result;
+	}
+
+	template <>
+	inline detail::_xvec3<__halfGTX> f16_xrgb_castGTX<__uint32GTX>(__uint32GTX color)
+	{
+		detail::_xvec3<__halfGTX> result;
+		result.x = __halfGTX(static_cast<float>(color >>  8) / static_cast<float>(255));
+		result.y = __halfGTX(static_cast<float>(color >> 16) / static_cast<float>(255));
+		result.z = __halfGTX(static_cast<float>(color >> 24) / static_cast<float>(255));
+		return result;
+	}
+
+	template <>
+	inline detail::_xvec3<__halfGTX> f16_bgrx_castGTX<__uint32GTX>(__uint32GTX color)
+	{
+		detail::_xvec3<__halfGTX> result;
+		result.x = __halfGTX(static_cast<float>(color >> 16) / static_cast<float>(255));
+		result.y = __halfGTX(static_cast<float>(color >>  8) / static_cast<float>(255));
+		result.z = __halfGTX(static_cast<float>(color >>  0) / static_cast<float>(255));
+		return result;
+	}
+
+	template <>
+	inline detail::_xvec3<__halfGTX> f16_xbgr_castGTX<__uint32GTX>(__uint32GTX color)
+	{
+		detail::_xvec3<__halfGTX> result;
+		result.x = __halfGTX(static_cast<float>(color >> 24) / static_cast<float>(255));
+		result.y = __halfGTX(static_cast<float>(color >> 16) / static_cast<float>(255));
+		result.z = __halfGTX(static_cast<float>(color >>  8) / static_cast<float>(255));
+		return result;
+	}
+
+	template <>
+	inline detail::_xvec4<__halfGTX> f16_rgba_castGTX<__uint32GTX>(__uint32GTX color)
+	{
+		detail::_xvec4<__halfGTX> result;
+		result.x = __halfGTX(static_cast<float>(color >>  0) / static_cast<float>(255));
+		result.y = __halfGTX(static_cast<float>(color >>  8) / static_cast<float>(255));
+		result.z = __halfGTX(static_cast<float>(color >> 16) / static_cast<float>(255));
+		result.w = __halfGTX(static_cast<float>(color >> 24) / static_cast<float>(255));
+		return result;
+	}
+
+	template <>
+	inline detail::_xvec4<__halfGTX> f16_argb_castGTX<__uint32GTX>(__uint32GTX color)
+	{
+		detail::_xvec4<__halfGTX> result;
+		result.x = __halfGTX(static_cast<float>(color >>  8) / static_cast<float>(255));
+		result.y = __halfGTX(static_cast<float>(color >> 16) / static_cast<float>(255));
+		result.z = __halfGTX(static_cast<float>(color >> 24) / static_cast<float>(255));
+		result.w = __halfGTX(static_cast<float>(color >>  0) / static_cast<float>(255));
+		return result;
+	}
+
+	template <>
+	inline detail::_xvec4<__halfGTX> f16_bgra_castGTX<__uint32GTX>(__uint32GTX color)
+	{
+		detail::_xvec4<__halfGTX> result;
+		result.x = __halfGTX(static_cast<float>(color >> 16) / static_cast<float>(255));
+		result.y = __halfGTX(static_cast<float>(color >>  8) / static_cast<float>(255));
+		result.z = __halfGTX(static_cast<float>(color >>  0) / static_cast<float>(255));
+		result.w = __halfGTX(static_cast<float>(color >> 24) / static_cast<float>(255));
+		return result;
+	}
+
+	template <>
+	inline detail::_xvec4<__halfGTX> f16_abgr_castGTX<__uint32GTX>(__uint32GTX color)
+	{
+		detail::_xvec4<__halfGTX> result;
+		result.x = __halfGTX(static_cast<float>(color >> 24) / static_cast<float>(255));
+		result.y = __halfGTX(static_cast<float>(color >> 16) / static_cast<float>(255));
+		result.z = __halfGTX(static_cast<float>(color >>  8) / static_cast<float>(255));
+		result.w = __halfGTX(static_cast<float>(color >>  0) / static_cast<float>(255));
+		return result;
+	}
+#endif//GLM_COMPILER_VC
+
+	template <>
+	inline float f32_channel_castGTX<__uint8GTX>(__uint8GTX color)
+	{
+		return static_cast<float>(color >>  0) / static_cast<float>(255);
+	}
+
+	template <>
+	inline detail::_xvec3<float> f32_rgbx_castGTX<__uint32GTX>(__uint32GTX color)
+	{
+		detail::_xvec3<float> result;
+		result.x = static_cast<float>(color >>  0) / static_cast<float>(255);
+		result.y = static_cast<float>(color >>  8) / static_cast<float>(255);
+		result.z = static_cast<float>(color >> 16) / static_cast<float>(255);
+		return result;
+	}
+
+	template <>
+	inline detail::_xvec3<float> f32_xrgb_castGTX<__uint32GTX>(__uint32GTX color)
+	{
+		detail::_xvec3<float> result;
+		result.x = static_cast<float>(color >>  8) / static_cast<float>(255);
+		result.y = static_cast<float>(color >> 16) / static_cast<float>(255);
+		result.z = static_cast<float>(color >> 24) / static_cast<float>(255);
+		return result;
+	}
+
+	template <>
+	inline detail::_xvec3<float> f32_bgrx_castGTX<__uint32GTX>(__uint32GTX color)
+	{
+		detail::_xvec3<float> result;
+		result.x = static_cast<float>(color >> 16) / static_cast<float>(255);
+		result.y = static_cast<float>(color >>  8) / static_cast<float>(255);
+		result.z = static_cast<float>(color >>  0) / static_cast<float>(255);
+		return result;
+	}
+
+	template <>
+	inline detail::_xvec3<float> f32_xbgr_castGTX<__uint32GTX>(__uint32GTX color)
+	{
+		detail::_xvec3<float> result;
+		result.x = static_cast<float>(color >> 24) / static_cast<float>(255);
+		result.y = static_cast<float>(color >> 16) / static_cast<float>(255);
+		result.z = static_cast<float>(color >>  8) / static_cast<float>(255);
+		return result;
+	}
+
+	template <>
+	inline detail::_xvec4<float> f32_rgba_castGTX<__uint32GTX>(__uint32GTX color)
+	{
+		detail::_xvec4<float> result;
+		result.x = static_cast<float>(color >>  0) / static_cast<float>(255);
+		result.y = static_cast<float>(color >>  8) / static_cast<float>(255);
+		result.z = static_cast<float>(color >> 16) / static_cast<float>(255);
+		result.w = static_cast<float>(color >> 24) / static_cast<float>(255);
+		return result;
+	}
+
+	template <>
+	inline detail::_xvec4<float> f32_argb_castGTX<__uint32GTX>(__uint32GTX color)
+	{
+		detail::_xvec4<float> result;
+		result.x = static_cast<float>(color >>  8) / static_cast<float>(255);
+		result.y = static_cast<float>(color >> 16) / static_cast<float>(255);
+		result.z = static_cast<float>(color >> 24) / static_cast<float>(255);
+		result.w = static_cast<float>(color >>  0) / static_cast<float>(255);
+		return result;
+	}
+
+	template <>
+	inline detail::_xvec4<float> f32_bgra_castGTX<__uint32GTX>(__uint32GTX color)
+	{
+		detail::_xvec4<float> result;
+		result.x = static_cast<float>(color >> 16) / static_cast<float>(255);
+		result.y = static_cast<float>(color >>  8) / static_cast<float>(255);
+		result.z = static_cast<float>(color >>  0) / static_cast<float>(255);
+		result.w = static_cast<float>(color >> 24) / static_cast<float>(255);
+		return result;
+	}
+
+	template <>
+	inline detail::_xvec4<float> f32_abgr_castGTX<__uint32GTX>(__uint32GTX color)
+	{
+		detail::_xvec4<float> result;
+		result.x = static_cast<float>(color >> 24) / static_cast<float>(255);
+		result.y = static_cast<float>(color >> 16) / static_cast<float>(255);
+		result.z = static_cast<float>(color >>  8) / static_cast<float>(255);
+		result.w = static_cast<float>(color >>  0) / static_cast<float>(255);
+		return result;
+	}
+
+	template <>
+	inline double f64_channel_castGTX<__uint8GTX>(__uint8GTX color)
+	{
+		return static_cast<double>(color >>  0) / static_cast<double>(255);
+	}
+
+	template <>
+	inline detail::_xvec3<double> f64_rgbx_castGTX<__uint32GTX>(__uint32GTX color)
+	{
+		detail::_xvec3<double> result;
+		result.x = static_cast<double>(color >>  0) / static_cast<double>(255);
+		result.y = static_cast<double>(color >>  8) / static_cast<double>(255);
+		result.z = static_cast<double>(color >> 16) / static_cast<double>(255);
+		return result;
+	}
+
+	template <>
+	inline detail::_xvec3<double> f64_xrgb_castGTX<__uint32GTX>(__uint32GTX color)
+	{
+		detail::_xvec3<double> result;
+		result.x = static_cast<double>(color >>  8) / static_cast<double>(255);
+		result.y = static_cast<double>(color >> 16) / static_cast<double>(255);
+		result.z = static_cast<double>(color >> 24) / static_cast<double>(255);
+		return result;
+	}
+
+	template <>
+	inline detail::_xvec3<double> f64_bgrx_castGTX<__uint32GTX>(__uint32GTX color)
+	{
+		detail::_xvec3<double> result;
+		result.x = static_cast<double>(color >> 16) / static_cast<double>(255);
+		result.y = static_cast<double>(color >>  8) / static_cast<double>(255);
+		result.z = static_cast<double>(color >>  0) / static_cast<double>(255);
+		return result;
+	}
+
+	template <>
+	inline detail::_xvec3<double> f64_xbgr_castGTX<__uint32GTX>(__uint32GTX color)
+	{
+		detail::_xvec3<double> result;
+		result.x = static_cast<double>(color >> 24) / static_cast<double>(255);
+		result.y = static_cast<double>(color >> 16) / static_cast<double>(255);
+		result.z = static_cast<double>(color >>  8) / static_cast<double>(255);
+		return result;
+	}
+
+	template <>
+	inline detail::_xvec4<double> f64_rgba_castGTX<__uint32GTX>(__uint32GTX color)
+	{
+		detail::_xvec4<double> result;
+		result.x = static_cast<double>(color >>  0) / static_cast<double>(255);
+		result.y = static_cast<double>(color >>  8) / static_cast<double>(255);
+		result.z = static_cast<double>(color >> 16) / static_cast<double>(255);
+		result.w = static_cast<double>(color >> 24) / static_cast<double>(255);
+		return result;
+	}
+
+	template <>
+	inline detail::_xvec4<double> f64_argb_castGTX<__uint32GTX>(__uint32GTX color)
+	{
+		detail::_xvec4<double> result;
+		result.x = static_cast<double>(color >>  8) / static_cast<double>(255);
+		result.y = static_cast<double>(color >> 16) / static_cast<double>(255);
+		result.z = static_cast<double>(color >> 24) / static_cast<double>(255);
+		result.w = static_cast<double>(color >>  0) / static_cast<double>(255);
+		return result;
+	}
+
+	template <>
+	inline detail::_xvec4<double> f64_bgra_castGTX<__uint32GTX>(__uint32GTX color)
+	{
+		detail::_xvec4<double> result;
+		result.x = static_cast<double>(color >> 16) / static_cast<double>(255);
+		result.y = static_cast<double>(color >>  8) / static_cast<double>(255);
+		result.z = static_cast<double>(color >>  0) / static_cast<double>(255);
+		result.w = static_cast<double>(color >> 24) / static_cast<double>(255);
+		return result;
+	}
+
+	template <>
+	inline detail::_xvec4<double> f64_abgr_castGTX<__uint32GTX>(__uint32GTX color)
+	{
+		detail::_xvec4<double> result;
+		result.x = static_cast<double>(color >> 24) / static_cast<double>(255);
+		result.y = static_cast<double>(color >> 16) / static_cast<double>(255);
+		result.z = static_cast<double>(color >>  8) / static_cast<double>(255);
+		result.w = static_cast<double>(color >>  0) / static_cast<double>(255);
+		return result;
+	}
+
+	template <>
+	inline __halfGTX f16_channel_castGTX<__uint16GTX>(__uint16GTX color)
+	{
+		return __halfGTX(static_cast<float>(color >>  0) / static_cast<float>(65535));
+	}
+
+#ifdef GLM_COMPILER_VC
+	template <>
+	inline detail::_xvec3<__halfGTX> f16_rgbx_castGTX<__uint64GTX>(__uint64GTX color)
+	{
+		detail::_xvec3<__halfGTX> result;
+		result.x = __halfGTX(static_cast<float>(color >>  0) / static_cast<float>(65535));
+		result.y = __halfGTX(static_cast<float>(color >> 16) / static_cast<float>(65535));
+		result.z = __halfGTX(static_cast<float>(color >> 32) / static_cast<float>(65535));
+		return result;
+	}
+
+	template <>
+	inline detail::_xvec3<__halfGTX> f16_xrgb_castGTX<__uint64GTX>(__uint64GTX color)
+	{
+		detail::_xvec3<__halfGTX> result;
+		result.x = __halfGTX(static_cast<float>(color >> 16) / static_cast<float>(65535));
+		result.y = __halfGTX(static_cast<float>(color >> 32) / static_cast<float>(65535));
+		result.z = __halfGTX(static_cast<float>(color >> 48) / static_cast<float>(65535));
+		return result;
+	}
+
+	template <>
+	inline detail::_xvec3<__halfGTX> f16_bgrx_castGTX<__uint64GTX>(__uint64GTX color)
+	{
+		detail::_xvec3<__halfGTX> result;
+		result.x = __halfGTX(static_cast<float>(color >> 32) / static_cast<float>(65535));
+		result.y = __halfGTX(static_cast<float>(color >> 16) / static_cast<float>(65535));
+		result.z = __halfGTX(static_cast<float>(color >>  0) / static_cast<float>(65535));
+		return result;
+	}
+
+	template <>
+	inline detail::_xvec3<__halfGTX> f16_xbgr_castGTX<__uint64GTX>(__uint64GTX color)
+	{
+		detail::_xvec3<__halfGTX> result;
+		result.x = __halfGTX(static_cast<float>(color >> 48) / static_cast<float>(65535));
+		result.y = __halfGTX(static_cast<float>(color >> 32) / static_cast<float>(65535));
+		result.z = __halfGTX(static_cast<float>(color >> 16) / static_cast<float>(65535));
+		return result;
+	}
+
+	template <>
+	inline detail::_xvec4<__halfGTX> f16_rgba_castGTX<__uint64GTX>(__uint64GTX color)
+	{
+		detail::_xvec4<__halfGTX> result;
+		result.x = __halfGTX(static_cast<float>(color >>  0) / static_cast<float>(65535));
+		result.y = __halfGTX(static_cast<float>(color >> 16) / static_cast<float>(65535));
+		result.z = __halfGTX(static_cast<float>(color >> 32) / static_cast<float>(65535));
+		result.w = __halfGTX(static_cast<float>(color >> 48) / static_cast<float>(65535));
+		return result;
+	}
+
+	template <>
+	inline detail::_xvec4<__halfGTX> f16_argb_castGTX<__uint64GTX>(__uint64GTX color)
+	{
+		detail::_xvec4<__halfGTX> result;
+		result.x = __halfGTX(static_cast<float>(color >> 16) / static_cast<float>(65535));
+		result.y = __halfGTX(static_cast<float>(color >> 32) / static_cast<float>(65535));
+		result.z = __halfGTX(static_cast<float>(color >> 48) / static_cast<float>(65535));
+		result.w = __halfGTX(static_cast<float>(color >>  0) / static_cast<float>(65535));
+		return result;
+	}
+
+	template <>
+	inline detail::_xvec4<__halfGTX> f16_bgra_castGTX<__uint64GTX>(__uint64GTX color)
+	{
+		detail::_xvec4<__halfGTX> result;
+		result.x = __halfGTX(static_cast<float>(color >> 32) / static_cast<float>(65535));
+		result.y = __halfGTX(static_cast<float>(color >> 16) / static_cast<float>(65535));
+		result.z = __halfGTX(static_cast<float>(color >>  0) / static_cast<float>(65535));
+		result.w = __halfGTX(static_cast<float>(color >> 48) / static_cast<float>(65535));
+		return result;
+	}
+
+	template <>
+	inline detail::_xvec4<__halfGTX> f16_abgr_castGTX<__uint64GTX>(__uint64GTX color)
+	{
+		detail::_xvec4<__halfGTX> result;
+		result.x = __halfGTX(static_cast<float>(color >> 48) / static_cast<float>(65535));
+		result.y = __halfGTX(static_cast<float>(color >> 32) / static_cast<float>(65535));
+		result.z = __halfGTX(static_cast<float>(color >> 16) / static_cast<float>(65535));
+		result.w = __halfGTX(static_cast<float>(color >>  0) / static_cast<float>(65535));
+		return result;
+	}
+#endif//GLM_COMPILER_VC
+
+	template <>
+	inline float f32_channel_castGTX<__uint16GTX>(__uint16GTX color)
+	{
+		return static_cast<float>(color >>  0) / static_cast<float>(65535);
+	}
+
+	template <>
+	inline detail::_xvec3<float> f32_rgbx_castGTX<__uint64GTX>(__uint64GTX color)
+	{
+		detail::_xvec3<float> result;
+		result.x = static_cast<float>(color >>  0) / static_cast<float>(65535);
+		result.y = static_cast<float>(color >> 16) / static_cast<float>(65535);
+		result.z = static_cast<float>(color >> 32) / static_cast<float>(65535);
+		return result;
+	}
+
+	template <>
+	inline detail::_xvec3<float> f32_xrgb_castGTX<__uint64GTX>(__uint64GTX color)
+	{
+		detail::_xvec3<float> result;
+		result.x = static_cast<float>(color >> 16) / static_cast<float>(65535);
+		result.y = static_cast<float>(color >> 32) / static_cast<float>(65535);
+		result.z = static_cast<float>(color >> 48) / static_cast<float>(65535);
+		return result;
+	}
+
+	template <>
+	inline detail::_xvec3<float> f32_bgrx_castGTX<__uint64GTX>(__uint64GTX color)
+	{
+		detail::_xvec3<float> result;
+		result.x = static_cast<float>(color >> 32) / static_cast<float>(65535);
+		result.y = static_cast<float>(color >> 16) / static_cast<float>(65535);
+		result.z = static_cast<float>(color >>  0) / static_cast<float>(65535);
+		return result;
+	}
+
+	template <>
+	inline detail::_xvec3<float> f32_xbgr_castGTX<__uint64GTX>(__uint64GTX color)
+	{
+		detail::_xvec3<float> result;
+		result.x = static_cast<float>(color >> 48) / static_cast<float>(65535);
+		result.y = static_cast<float>(color >> 32) / static_cast<float>(65535);
+		result.z = static_cast<float>(color >> 16) / static_cast<float>(65535);
+		return result;
+	}
+
+	template <>
+	inline detail::_xvec4<float> f32_rgba_castGTX<__uint64GTX>(__uint64GTX color)
+	{
+		detail::_xvec4<float> result;
+		result.x = static_cast<float>(color >>  0) / static_cast<float>(65535);
+		result.y = static_cast<float>(color >> 16) / static_cast<float>(65535);
+		result.z = static_cast<float>(color >> 32) / static_cast<float>(65535);
+		result.w = static_cast<float>(color >> 48) / static_cast<float>(65535);
+		return result;
+	}
+
+	template <>
+	inline detail::_xvec4<float> f32_argb_castGTX<__uint64GTX>(__uint64GTX color)
+	{
+		detail::_xvec4<float> result;
+		result.x = static_cast<float>(color >> 16) / static_cast<float>(65535);
+		result.y = static_cast<float>(color >> 32) / static_cast<float>(65535);
+		result.z = static_cast<float>(color >> 48) / static_cast<float>(65535);
+		result.w = static_cast<float>(color >>  0) / static_cast<float>(65535);
+		return result;
+	}
+
+	template <>
+	inline detail::_xvec4<float> f32_bgra_castGTX<__uint64GTX>(__uint64GTX color)
+	{
+		detail::_xvec4<float> result;
+		result.x = static_cast<float>(color >> 32) / static_cast<float>(65535);
+		result.y = static_cast<float>(color >> 16) / static_cast<float>(65535);
+		result.z = static_cast<float>(color >>  0) / static_cast<float>(65535);
+		result.w = static_cast<float>(color >> 48) / static_cast<float>(65535);
+		return result;
+	}
+
+	template <>
+	inline detail::_xvec4<float> f32_abgr_castGTX<__uint64GTX>(__uint64GTX color)
+	{
+		detail::_xvec4<float> result;
+		result.x = static_cast<float>(color >> 48) / static_cast<float>(65535);
+		result.y = static_cast<float>(color >> 32) / static_cast<float>(65535);
+		result.z = static_cast<float>(color >> 16) / static_cast<float>(65535);
+		result.w = static_cast<float>(color >>  0) / static_cast<float>(65535);
+		return result;
+	}
+
+	template <>
+	inline double f64_channel_castGTX<__uint16GTX>(__uint16GTX color)
+	{
+		return static_cast<double>(color >>  0) / static_cast<double>(65535);
+	}
+
+	template <>
+	inline detail::_xvec3<double> f64_rgbx_castGTX<__uint64GTX>(__uint64GTX color)
+	{
+		detail::_xvec3<double> result;
+		result.x = static_cast<double>(color >>  0) / static_cast<double>(65535);
+		result.y = static_cast<double>(color >> 16) / static_cast<double>(65535);
+		result.z = static_cast<double>(color >> 32) / static_cast<double>(65535);
+		return result;
+	}
+
+	template <>
+	inline detail::_xvec3<double> f64_xrgb_castGTX<__uint64GTX>(__uint64GTX color)
+	{
+		detail::_xvec3<double> result;
+		result.x = static_cast<double>(color >> 16) / static_cast<double>(65535);
+		result.y = static_cast<double>(color >> 32) / static_cast<double>(65535);
+		result.z = static_cast<double>(color >> 48) / static_cast<double>(65535);
+		return result;
+	}
+
+	template <>
+	inline detail::_xvec3<double> f64_bgrx_castGTX<__uint64GTX>(__uint64GTX color)
+	{
+		detail::_xvec3<double> result;
+		result.x = static_cast<double>(color >> 32) / static_cast<double>(65535);
+		result.y = static_cast<double>(color >> 16) / static_cast<double>(65535);
+		result.z = static_cast<double>(color >>  0) / static_cast<double>(65535);
+		return result;
+	}
+
+	template <>
+	inline detail::_xvec3<double> f64_xbgr_castGTX<__uint64GTX>(__uint64GTX color)
+	{
+		detail::_xvec3<double> result;
+		result.x = static_cast<double>(color >> 48) / static_cast<double>(65535);
+		result.y = static_cast<double>(color >> 32) / static_cast<double>(65535);
+		result.z = static_cast<double>(color >> 16) / static_cast<double>(65535);
+		return result;
+	}
+
+	template <>
+	inline detail::_xvec4<double> f64_rgba_castGTX<__uint64GTX>(__uint64GTX color)
+	{
+		detail::_xvec4<double> result;
+		result.x = static_cast<double>(color >>  0) / static_cast<double>(65535);
+		result.y = static_cast<double>(color >> 16) / static_cast<double>(65535);
+		result.z = static_cast<double>(color >> 32) / static_cast<double>(65535);
+		result.w = static_cast<double>(color >> 48) / static_cast<double>(65535);
+		return result;
+	}
+
+	template <>
+	inline detail::_xvec4<double> f64_argb_castGTX<__uint64GTX>(__uint64GTX color)
+	{
+		detail::_xvec4<double> result;
+		result.x = static_cast<double>(color >> 16) / static_cast<double>(65535);
+		result.y = static_cast<double>(color >> 32) / static_cast<double>(65535);
+		result.z = static_cast<double>(color >> 48) / static_cast<double>(65535);
+		result.w = static_cast<double>(color >>  0) / static_cast<double>(65535);
+		return result;
+	}
+
+	template <>
+	inline detail::_xvec4<double> f64_bgra_castGTX<__uint64GTX>(__uint64GTX color)
+	{
+		detail::_xvec4<double> result;
+		result.x = static_cast<double>(color >> 32) / static_cast<double>(65535);
+		result.y = static_cast<double>(color >> 16) / static_cast<double>(65535);
+		result.z = static_cast<double>(color >>  0) / static_cast<double>(65535);
+		result.w = static_cast<double>(color >> 48) / static_cast<double>(65535);
+		return result;
+	}
+
+	template <>
+	inline detail::_xvec4<double> f64_abgr_castGTX<__uint64GTX>(__uint64GTX color)
+	{
+		detail::_xvec4<double> result;
+		result.x = static_cast<double>(color >> 48) / static_cast<double>(65535);
+		result.y = static_cast<double>(color >> 32) / static_cast<double>(65535);
+		result.z = static_cast<double>(color >> 16) / static_cast<double>(65535);
+		result.w = static_cast<double>(color >>  0) / static_cast<double>(65535);
+		return result;
+	}
+}

+ 51 - 0
experimental/sse/glm/ext/gtx/color_space.h

@@ -0,0 +1,51 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2008 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2005-12-21
+// Updated : 2007-02-22
+// Licence : This source is under GNU LGPL licence
+// File    : glm/gtx/color_space.h
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Dependency:
+// - GLM core
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef __glm_gtx_color_space__
+#define __glm_gtx_color_space__
+
+// Dependency:
+#include "../../glm.h"
+
+namespace glm
+{
+    template <typename T> detail::_xvec3<T> rgbColorGTX(const detail::_xvec3<T>& hsvValue);				//!< \brief Converts a color from HSV color space to its color in RGB color space (from GLM_GTX_color_space extension)
+    template <typename T> detail::_xvec3<T> hsvColorGTX(const detail::_xvec3<T>& rgbValue);				//!< \brief Converts a color from RGB color space to its color in HSV color space (from GLM_GTX_color_space extension)
+	template <typename T> detail::_xmat4<T> saturationGTX(const T s);									//!< Build a saturation matrix (from GLM_GTX_color_space extension)
+	template <typename T> detail::_xvec3<T> saturationGTX(const T s, const detail::_xvec3<T>& color);	//!< Modify the saturation of a color (from GLM_GTX_color_space extension)
+	template <typename T> detail::_xvec4<T> saturationGTX(const T s, const detail::_xvec4<T>& color);	//!< Modify the saturation of a color (from GLM_GTX_color_space extension)
+	template <typename T> T luminosityGTX(const detail::_xvec3<T>& cColor);								//!< Compute color luminosity associating ratios (0.33, 0.59, 0.11) to RGB canals (from GLM_GTX_color_space extension)
+
+    namespace gtx
+    {
+		//! GLM_GTX_color_space extension: Related to RVB to HSV conversions and operations
+        namespace color_space
+        {
+            template <typename T> inline detail::_xvec3<T> rgbColor(const detail::_xvec3<T>& hsvValue){return rgbColorGTX(hsvValue);}				//!< \brief Converts a color from HSV color space to its color in RGB color space (from GLM_GTX_color_space extension)
+            template <typename T> inline detail::_xvec3<T> hsvColor(const detail::_xvec3<T>& rgbValue){return hsvColorGTX(rgbValue);}				//!< \brief Converts a color from RGB color space to its color in HSV color space (from GLM_GTX_color_space extension)
+	        template <typename T> inline detail::_xmat4<T> saturation(const T s){return saturationGTX(s);}											//!< Build a saturation matrix (from GLM_GTX_color_space extension)
+	        template <typename T> inline detail::_xvec3<T> saturation(const T s, const detail::_xvec3<T>& color){return saturationGTX(s, color);}	//!< Modify the saturation of a color (from GLM_GTX_color_space extension)
+	        template <typename T> inline detail::_xvec4<T> saturation(const T s, const detail::_xvec4<T>& color){return saturationGTX(s, color);}	//!< Modify the saturation of a color (from GLM_GTX_color_space extension)
+			template <typename T> inline T luminosity(const detail::_xvec3<T>& color){return luminosityGTX(color);}									//!< Compute color luminosity associating ratios (0.33, 0.59, 0.11) to RGB canals (from GLM_GTX_color_space extension)
+        }
+    }
+}
+
+#define GLM_GTX_color_space namespace gtx::color_space
+
+#include "color_space.inl"
+
+#ifdef GLM_GTX_INCLUDED
+namespace glm{using GLM_GTX_color_space;}
+#endif//GLM_GTX_INCLUDED
+
+#endif//__glm_gtx_color_space__

+ 149 - 0
experimental/sse/glm/ext/gtx/color_space.inl

@@ -0,0 +1,149 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2008 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2005-12-21
+// Updated : 2007-02-22
+// Licence : This source is under GNU LGPL licence
+// File    : glm/gtx/color_space.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace glm
+{
+    template <typename T> 
+    inline detail::_xvec3<T> rgbColorGTX(const detail::_xvec3<T>& color)
+    {
+		detail::_xvec3<T> hsv = color;
+        detail::_xvec3<T> rgb;
+
+	    if(hsv.y == T(0))
+		    // achromatic (grey)
+            rgb = detail::_xvec3<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:
+                rgb.r = hsv.z;
+                rgb.g = q;
+                rgb.b = o;
+                break;
+            case 1:
+                rgb.r = p;
+                rgb.g = hsv.z;
+                rgb.b = o;
+                break;
+            case 2:
+                rgb.r = o;
+                rgb.g = hsv.z;
+                rgb.b = q;
+                break;
+            case 3:
+                rgb.r = o;
+                rgb.g = p;
+                rgb.b = hsv.z;
+                break;
+            case 4:
+                rgb.r = q; 
+                rgb.g = o; 
+                rgb.b = hsv.z;
+                break;
+			case 5:
+                rgb.r = hsv.z; 
+                rgb.g = o; 
+                rgb.b = p;
+                break;
+            }
+	    }
+
+		return rgb;
+    }
+
+    template <typename T> 
+    inline detail::_xvec3<T> hsvColorGTX(const detail::_xvec3<T>& rgb)
+    {
+        detail::_xvec3<T> hsv = rgb;
+	    float Min   = min(min(rgb.r, rgb.g), rgb.b);
+	    float Max   = max(max(rgb.r, rgb.g), rgb.b);
+	    float Delta = Max - Min;
+
+	    hsv.z = Max;                               
+    	
+	    if(Max != T(0))
+	    {
+		    hsv.y = Delta / hsv.z;    
+			T h = T(0);
+
+		    if(rgb.r == Max)
+			    // between yellow & magenta
+			    h = T(0) + T(60) * (rgb.g - rgb.b) / Delta;
+		    else if(rgb.g == Max)
+			    // between cyan & yellow
+			    h = T(120) + T(60) * (rgb.b - rgb.r) / Delta;
+		    else
+			    // between magenta & cyan
+			    h = T(240) + T(60) * (rgb.r - rgb.g) / Delta;
+            
+		    if(h < T(0)) 
+                hsv.x = h + T(360);
+			else
+				hsv.x = h;
+	    }
+	    else
+	    {
+		    // If r = g = b = 0 then s = 0, h is undefined
+		    hsv.y = T(0);
+		    hsv.x = T(0);
+	    }
+
+		return hsv;
+    }
+
+	template <typename T> 
+	inline detail::_xmat4<T> saturationGTX(const T s)
+	{
+		detail::_xvec3<T> rgbw = detail::_xvec3<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::_xmat4<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> 
+	inline detail::_xvec3<T> saturationGTX(const T s, const detail::_xvec3<T>& color)
+	{
+		return detail::_xvec3<T>(saturationGTX(s) * detail::_xvec4<T>(color, T(0)));
+	}
+
+	template <typename T> 
+	inline detail::_xvec4<T> saturationGTX(const T s, const detail::_xvec4<T>& color)
+	{
+		return saturationGTX(s) * color;
+	}
+
+	template <typename T> 
+	inline T luminosityGTX(const detail::_xvec3<T>& color)
+	{
+		const detail::_xvec3<T> tmp = detail::_xvec3<T>(0.33, 0.59, 0.11);
+		return dot(color, tmp);
+	}
+}

+ 298 - 0
experimental/sse/glm/ext/gtx/compatibility.h

@@ -0,0 +1,298 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2008 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2007-01-24
+// Updated : 2007-09-06
+// Licence : This source is under GNU LGPL licence
+// File    : glm/gtx/compatibility.h
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Dependency:
+// - GLM core
+// - GLM_GTX_mul
+// - GLM_GTX_half
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef __glm_gtx_compatibility__
+#define __glm_gtx_compatibility__
+
+// Dependency:
+#include "../../glm.h"  
+#include "../../glmsetup.h"  
+#include "../gtx/mul.h"
+#include "../gtx/half.h"
+
+#ifdef GLM_COMPILER_VC
+#include <cfloat>
+#endif
+#ifdef GLM_COMPILER_GCC
+#include <cmath>
+#endif
+
+namespace glm
+{
+	template <typename T> inline T lerpGTX(T x, T y, T a){return mix(x, y, a);} //!< \brief Returns x * (1.0 - a) + y * a, i.e., the linear blend of x and y using the floating-point value a. The value for a is not restricted to the range [0, 1]. (From GLM_GTX_compatibility extension)
+
+	template <typename T> inline detail::_xvec2<T> lerpGTX(const detail::_xvec2<T>& x, const detail::_xvec2<T>& y, T a){return mix(x, y, a);} //!< \brief Returns x * (1.0 - a) + y * a, i.e., the linear blend of x and y using the floating-point value a. The value for a is not restricted to the range [0, 1]. (From GLM_GTX_compatibility extension)
+    template <typename T> inline detail::_xvec3<T> lerpGTX(const detail::_xvec3<T>& x, const detail::_xvec3<T>& y, T a){return mix(x, y, a);} //!< \brief Returns x * (1.0 - a) + y * a, i.e., the linear blend of x and y using the floating-point value a. The value for a is not restricted to the range [0, 1]. (From GLM_GTX_compatibility extension)
+    template <typename T> inline detail::_xvec4<T> lerpGTX(const detail::_xvec4<T>& x, const detail::_xvec4<T>& y, T a){return mix(x, y, a);} //!< \brief Returns x * (1.0 - a) + y * a, i.e., the linear blend of x and y using the floating-point value a. The value for a is not restricted to the range [0, 1]. (From GLM_GTX_compatibility extension)
+
+	template <typename T> inline detail::_xvec2<T> lerpGTX(const detail::_xvec2<T>& x, const detail::_xvec2<T>& y, const detail::_xvec2<T>& a){return mix(x, y, a);} //!< \brief Returns the component-wise result of x * (1.0 - a) + y * a, i.e., the linear blend of x and y using vector a. The value for a is not restricted to the range [0, 1]. (From GLM_GTX_compatibility extension)
+    template <typename T> inline detail::_xvec3<T> lerpGTX(const detail::_xvec3<T>& x, const detail::_xvec3<T>& y, const detail::_xvec3<T>& a){return mix(x, y, a);} //!< \brief Returns the component-wise result of x * (1.0 - a) + y * a, i.e., the linear blend of x and y using vector a. The value for a is not restricted to the range [0, 1]. (From GLM_GTX_compatibility extension)
+    template <typename T> inline detail::_xvec4<T> lerpGTX(const detail::_xvec4<T>& x, const detail::_xvec4<T>& y, const detail::_xvec4<T>& a){return mix(x, y, a);} //!< \brief Returns the component-wise result of x * (1.0 - a) + y * a, i.e., the linear blend of x and y using vector a. The value for a is not restricted to the range [0, 1]. (From GLM_GTX_compatibility extension)
+
+	template <typename T> inline T saturateGTX(T x){clamp(x, T(0), T(1));} //!< \brief Returns clamp(x, 0, 1) for each component in x. (From GLM_GTX_compatibility extension)
+    template <typename T> inline detail::_xvec2<T> saturateGTX(const detail::_xvec2<T>& x){clamp(x, T(0), T(1));} //!< \brief Returns clamp(x, 0, 1) for each component in x. (From GLM_GTX_compatibility extension)
+    template <typename T> inline detail::_xvec3<T> saturateGTX(const detail::_xvec3<T>& x){clamp(x, T(0), T(1));} //!< \brief Returns clamp(x, 0, 1) for each component in x. (From GLM_GTX_compatibility extension)
+    template <typename T> inline detail::_xvec4<T> saturateGTX(const detail::_xvec4<T>& x){clamp(x, T(0), T(1));} //!< \brief Returns clamp(x, 0, 1) for each component in x. (From GLM_GTX_compatibility extension)
+
+	template <typename T> inline T atan2GTX(T x, T y){atan(x, y);}  //!< \brief 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. (From GLM_GTX_compatibility extension)
+	template <typename T> inline detail::_xvec2<T> atan2GTX(const detail::_xvec2<T>& x, const detail::_xvec2<T>& y){atan(x, y);} //!< \brief 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. (From GLM_GTX_compatibility extension)
+    template <typename T> inline detail::_xvec3<T> atan2GTX(const detail::_xvec3<T>& x, const detail::_xvec3<T>& y){atan(x, y);} //!< \brief 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. (From GLM_GTX_compatibility extension)
+    template <typename T> inline detail::_xvec4<T> atan2GTX(const detail::_xvec4<T>& x, const detail::_xvec4<T>& y){atan(x, y);} //!< \brief 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. (From GLM_GTX_compatibility extension)
+
+	template <typename T> bool isfiniteGTX(T x); //!< \brief Determines whether the given floating-point value is finite. (From GLM_GTX_compatibility extension) 
+	template <typename T> detail::_bvec2 isfiniteGTX(const detail::_xvec2<T>& x); //!< \brief Determines whether the given floating-point values is finite. (From GLM_GTX_compatibility extension)
+    template <typename T> detail::_bvec3 isfiniteGTX(const detail::_xvec3<T>& x); //!< \brief Determines whether the given floating-point values is finite. (From GLM_GTX_compatibility extension)
+    template <typename T> detail::_bvec4 isfiniteGTX(const detail::_xvec4<T>& x); //!< \brief Determines whether the given floating-point values is finite. (From GLM_GTX_compatibility extension)
+
+	template <typename T> bool isinfGTX(T x); //!< \brief Determines whether the given floating-point value is infinite. (From GLM_GTX_compatibility extension) 
+	template <typename T> detail::_bvec2 isinfGTX(const detail::_xvec2<T>& x); //!< \brief Determines whether the given floating-point values is infinite. (From GLM_GTX_compatibility extension) 
+    template <typename T> detail::_bvec3 isinfGTX(const detail::_xvec3<T>& x); //!< \brief Determines whether the given floating-point values is infinite. (From GLM_GTX_compatibility extension) 
+    template <typename T> detail::_bvec4 isinfGTX(const detail::_xvec4<T>& x); //!< \brief Determines whether the given floating-point values is infinite. (From GLM_GTX_compatibility extension) 
+
+	template <typename T> bool isnanGTX(T x); //!< \brief Checks given floating-point value for not a number (NAN) (From GLM_GTX_compatibility extension)
+	template <typename T> detail::_bvec2 isnanGTX(const detail::_xvec2<T>& x); //!< \brief Checks given floating-point values for not a number (NAN) (From GLM_GTX_compatibility extension)
+    template <typename T> detail::_bvec3 isnanGTX(const detail::_xvec3<T>& x); //!< \brief Checks given floating-point values for not a number (NAN) (From GLM_GTX_compatibility extension)
+    template <typename T> detail::_bvec4 isnanGTX(const detail::_xvec4<T>& x); //!< \brief Checks given floating-point values for not a number (NAN) (From GLM_GTX_compatibility extension)
+
+	typedef bool bool1GTX;
+	typedef detail::_bvec2 bool2GTX;
+	typedef detail::_bvec3 bool3GTX;
+	typedef detail::_bvec4 bool4GTX;
+/*
+	typedef bool bool1x1GTX;
+	typedef detail::_xmat2<bool> bool2x2GTX;
+	typedef detail::_xmat3<bool> bool3x3GTX;
+	typedef detail::_xmat4<bool> bool4x4GTX;
+
+	typedef detail::_xmat2x3<bool> bool2x3GTX;
+	typedef detail::_xmat2x4<bool> bool2x4GTX;
+	typedef detail::_xmat3x2<bool> bool3x2GTX;
+	typedef detail::_xmat3x4<bool> bool3x4GTX;
+	typedef detail::_xmat4x2<bool> bool4x2GTX;
+	typedef detail::_xmat4x3<bool> bool4x3GTX;
+*/
+	typedef int __int1GTX;
+	typedef detail::_xvec2<int> __int2GTX;
+	typedef detail::_xvec3<int> __int3GTX;
+	typedef detail::_xvec4<int> __int4GTX;
+
+	typedef int __int1x1GTX;
+	typedef detail::_xmat2<int> __int2x2GTX;
+	typedef detail::_xmat3<int> __int3x3GTX;
+	typedef detail::_xmat4<int> __int4x4GTX;
+
+	typedef detail::_xmat2x3<int> __int2x3GTX;
+	typedef detail::_xmat2x4<int> __int2x4GTX;
+	typedef detail::_xmat3x2<int> __int3x2GTX;
+	typedef detail::_xmat3x4<int> __int3x4GTX;
+	typedef detail::_xmat4x2<int> __int4x2GTX;
+	typedef detail::_xmat4x3<int> __int4x3GTX;
+
+	typedef __halfGTX __half1GTX;
+	typedef detail::_xvec2<__halfGTX> __half2GTX;
+	typedef detail::_xvec3<__halfGTX> __half3GTX;
+	typedef detail::_xvec4<__halfGTX> __half4GTX;
+
+	typedef __halfGTX __half1x1GTX;
+	typedef detail::_xmat2<__halfGTX> __half2x2GTX;
+	typedef detail::_xmat3<__halfGTX> __half3x3GTX;
+	typedef detail::_xmat4<__halfGTX> __half4x4GTX;
+
+	typedef detail::_xmat2x3<__halfGTX> __half2x3GTX;
+	typedef detail::_xmat2x4<__halfGTX> __half2x4GTX;
+	typedef detail::_xmat3x2<__halfGTX> __half3x2GTX;
+	typedef detail::_xmat3x4<__halfGTX> __half3x4GTX;
+	typedef detail::_xmat4x2<__halfGTX> __half4x2GTX;
+	typedef detail::_xmat4x3<__halfGTX> __half4x3GTX;
+
+	typedef float __float1GTX;
+	typedef detail::_xvec2<float> __float2GTX;
+	typedef detail::_xvec3<float> __float3GTX;
+	typedef detail::_xvec4<float> __float4GTX;
+
+	typedef float __float1x1GTX;
+	typedef detail::_xmat2<float> __float2x2GTX;
+	typedef detail::_xmat3<float> __float3x3GTX;
+	typedef detail::_xmat4<float> __float4x4GTX;
+
+	typedef detail::_xmat2x3<float> __float2x3GTX;
+	typedef detail::_xmat2x4<float> __float2x4GTX;
+	typedef detail::_xmat3x2<float> __float3x2GTX;
+	typedef detail::_xmat3x4<float> __float3x4GTX;
+	typedef detail::_xmat4x2<float> __float4x2GTX;
+	typedef detail::_xmat4x3<float> __float4x3GTX;
+
+	typedef double __double1GTX;
+	typedef detail::_xvec2<double> __double2GTX;
+	typedef detail::_xvec3<double> __double3GTX;
+	typedef detail::_xvec4<double> __double4GTX;
+
+	typedef double __double1x1GTX;
+	typedef detail::_xmat2<double> __double2x2GTX;
+	typedef detail::_xmat3<double> __double3x3GTX;
+	typedef detail::_xmat4<double> __double4x4GTX;
+
+	typedef detail::_xmat2x3<double> __double2x3GTX;
+	typedef detail::_xmat2x4<double> __double2x4GTX;
+	typedef detail::_xmat3x2<double> __double3x2GTX;
+	typedef detail::_xmat3x4<double> __double3x4GTX;
+	typedef detail::_xmat4x2<double> __double4x2GTX;
+	typedef detail::_xmat4x3<double> __double4x3GTX;
+
+	namespace gtx
+	{
+		//! GLM_GTX_compatibility extension: Provide functions to increase the compatibility with Cg and HLSL languages
+		namespace compatibility
+		{
+			template <typename T> inline T lerp(T x, T y, T a){return mix(x, y, a);} //!< \brief Returns x * (1.0 - a) + y * a, i.e., the linear blend of x and y using the floating-point value a. The value for a is not restricted to the range [0, 1]. (From GLM_GTX_compatibility)
+
+			template <typename T> inline detail::_xvec2<T> lerp(const detail::_xvec2<T>& x, const detail::_xvec2<T>& y, T a){return mix(x, y, a);} //!< \brief Returns x * (1.0 - a) + y * a, i.e., the linear blend of x and y using the floating-point value a. The value for a is not restricted to the range [0, 1]. (From GLM_GTX_compatibility)
+			template <typename T> inline detail::_xvec3<T> lerp(const detail::_xvec3<T>& x, const detail::_xvec3<T>& y, T a){return mix(x, y, a);} //!< \brief Returns x * (1.0 - a) + y * a, i.e., the linear blend of x and y using the floating-point value a. The value for a is not restricted to the range [0, 1]. (From GLM_GTX_compatibility)
+			template <typename T> inline detail::_xvec4<T> lerp(const detail::_xvec4<T>& x, const detail::_xvec4<T>& y, T a){return mix(x, y, a);} //!< \brief Returns x * (1.0 - a) + y * a, i.e., the linear blend of x and y using the floating-point value a. The value for a is not restricted to the range [0, 1]. (From GLM_GTX_compatibility)
+
+			template <typename T> inline detail::_xvec2<T> lerp(const detail::_xvec2<T>& x, const detail::_xvec2<T>& y, const detail::_xvec2<T>& a){return mix(x, y, a);} //!< \brief Returns the component-wise result of x * (1.0 - a) + y * a, i.e., the linear blend of x and y using vector a. The value for a is not restricted to the range [0, 1]. (From GLM_GTX_compatibility)
+			template <typename T> inline detail::_xvec3<T> lerp(const detail::_xvec3<T>& x, const detail::_xvec3<T>& y, const detail::_xvec3<T>& a){return mix(x, y, a);} //!< \brief Returns the component-wise result of x * (1.0 - a) + y * a, i.e., the linear blend of x and y using vector a. The value for a is not restricted to the range [0, 1]. (From GLM_GTX_compatibility)
+			template <typename T> inline detail::_xvec4<T> lerp(const detail::_xvec4<T>& x, const detail::_xvec4<T>& y, const detail::_xvec4<T>& a){return mix(x, y, a);} //!< \brief Returns the component-wise result of x * (1.0 - a) + y * a, i.e., the linear blend of x and y using vector a. The value for a is not restricted to the range [0, 1]. (From GLM_GTX_compatibility)
+
+			template <typename T> inline T saturate(T x){saturateGTX(x);} //!< \brief Returns clamp(x, 0, 1) for each component in x. (From GLM_GTX_compatibility)
+			template <typename T> inline detail::_xvec2<T> saturate(const detail::_xvec2<T>& x){saturateGTX(x);} //!< \brief Returns clamp(x, 0, 1) for each component in x. (From GLM_GTX_compatibility)
+			template <typename T> inline detail::_xvec3<T> saturate(const detail::_xvec3<T>& x){saturateGTX(x);} //!< \brief Returns clamp(x, 0, 1) for each component in x. (From GLM_GTX_compatibility)
+			template <typename T> inline detail::_xvec4<T> saturate(const detail::_xvec4<T>& x){saturateGTX(x);} //!< \brief Returns clamp(x, 0, 1) for each component in x. (From GLM_GTX_compatibility)
+
+			template <typename T> inline T atan2(T x, T y){atan(x, y);}
+			template <typename T> inline detail::_xvec2<T> atan2(const detail::_xvec2<T>& x, const detail::_xvec2<T>& y){atan(x, y);}
+			template <typename T> inline detail::_xvec3<T> atan2(const detail::_xvec3<T>& x, const detail::_xvec3<T>& y){atan(x, y);}
+			template <typename T> inline detail::_xvec4<T> atan2(const detail::_xvec4<T>& x, const detail::_xvec4<T>& y){atan(x, y);}
+
+			template <typename T> inline bool isfinite(T x){return isfiniteGTX(x);}
+			template <typename T> inline detail::_bvec2 isfinite(const detail::_xvec2<T>& x){return isfiniteGTX(x);}
+			template <typename T> inline detail::_bvec3 isfinite(const detail::_xvec3<T>& x){return isfiniteGTX(x);}
+			template <typename T> inline detail::_bvec4 isfinite(const detail::_xvec4<T>& x){return isfiniteGTX(x);}
+
+			template <typename T> inline bool isinf(T x){return isinfGTX(x);}
+			template <typename T> inline detail::_bvec2 isinf(const detail::_xvec2<T>& x){return isinfGTX(x);}
+			template <typename T> inline detail::_bvec3 isinf(const detail::_xvec3<T>& x){return isinfGTX(x);}
+			template <typename T> inline detail::_bvec4 isinf(const detail::_xvec4<T>& x){return isinfGTX(x);}
+
+			template <typename T> inline bool isnan(T x){return isnanGTX(x);}
+			template <typename T> inline detail::_bvec2 isnan(const detail::_xvec2<T>& x){return isnanGTX(x);}
+			template <typename T> inline detail::_bvec3 isnan(const detail::_xvec3<T>& x){return isnanGTX(x);}
+			template <typename T> inline detail::_bvec4 isnan(const detail::_xvec4<T>& x){return isnanGTX(x);}
+
+			typedef bool bool1;
+			typedef detail::_bvec2 bool2;
+			typedef detail::_bvec3 bool3;
+			typedef detail::_bvec4 bool4;
+/*
+			typedef bool bool1x1;
+			typedef detail::_xmat2<bool> bool2x2;
+			typedef detail::_xmat3<bool> bool3x3;
+			typedef detail::_xmat4<bool> bool4x4;
+
+			typedef detail::_xmat2x3<bool> bool2x3;
+			typedef detail::_xmat2x4<bool> bool2x4;
+			typedef detail::_xmat3x2<bool> bool3x2;
+			typedef detail::_xmat3x4<bool> bool3x4;
+			typedef detail::_xmat4x2<bool> bool4x2;
+			typedef detail::_xmat4x3<bool> bool4x3;
+*/
+			typedef int int1;
+			typedef detail::_xvec2<int> int2;
+			typedef detail::_xvec3<int> int3;
+			typedef detail::_xvec4<int> int4;
+
+			typedef int int1x1;
+			typedef detail::_xmat2<int> int2x2;
+			typedef detail::_xmat3<int> int3x3;
+			typedef detail::_xmat4<int> int4x4;
+
+			typedef detail::_xmat2x3<int> int2x3;
+			typedef detail::_xmat2x4<int> int2x4;
+			typedef detail::_xmat3x2<int> int3x2;
+			typedef detail::_xmat3x4<int> int3x4;
+			typedef detail::_xmat4x2<int> int4x2;
+			typedef detail::_xmat4x3<int> int4x3;
+
+			typedef __halfGTX half1;
+			typedef detail::_xvec2<__halfGTX> half2;
+			typedef detail::_xvec3<__halfGTX> half3;
+			typedef detail::_xvec4<__halfGTX> half4;
+
+			typedef detail::_xmat2<__halfGTX> half2x2;
+			typedef detail::_xmat3<__halfGTX> half3x3;
+			typedef detail::_xmat4<__halfGTX> half4x4;
+
+			typedef detail::_xmat2x3<__halfGTX> half2x3;
+			typedef detail::_xmat2x4<__halfGTX> half2x4;
+			typedef detail::_xmat3x2<__halfGTX> half3x2;
+			typedef detail::_xmat3x4<__halfGTX> half3x4;
+			typedef detail::_xmat4x2<__halfGTX> half4x2;
+			typedef detail::_xmat4x3<__halfGTX> half4x3;
+
+			typedef float float1;
+			typedef detail::_xvec2<float> float2;
+			typedef detail::_xvec3<float> float3;
+			typedef detail::_xvec4<float> float4;
+
+			typedef float float1x1;
+			typedef detail::_xmat2<float> float2x2;
+			typedef detail::_xmat3<float> float3x3;
+			typedef detail::_xmat4<float> float4x4;
+
+			typedef detail::_xmat2x3<float> float2x3;
+			typedef detail::_xmat2x4<float> float2x4;
+			typedef detail::_xmat3x2<float> float3x2;
+			typedef detail::_xmat3x4<float> float3x4;
+			typedef detail::_xmat4x2<float> float4x2;
+			typedef detail::_xmat4x3<float> float4x3;
+
+			typedef double double1;
+			typedef detail::_xvec2<double> double2;
+			typedef detail::_xvec3<double> double3;
+			typedef detail::_xvec4<double> double4;
+
+			typedef double double1x1;
+			typedef detail::_xmat2<double> double2x2;
+			typedef detail::_xmat3<double> double3x3;
+			typedef detail::_xmat4<double> double4x4;
+
+			typedef detail::_xmat2x3<double> double2x3;
+			typedef detail::_xmat2x4<double> double2x4;
+			typedef detail::_xmat3x2<double> double3x2;
+			typedef detail::_xmat3x4<double> double3x4;
+			typedef detail::_xmat4x2<double> double4x2;
+			typedef detail::_xmat4x3<double> double4x3;
+		}
+	}
+}
+
+#define GLM_GTX_compatibility namespace gtx::compatibility
+
+#include "compatibility.inl"
+
+#ifdef GLM_GTX_INCLUDED
+namespace glm{using GLM_GTX_compatibility;}
+#endif//GLM_GTX_INCLUDED
+
+#endif//__glm_gtx_compatibility__
+
+
+
+
+
+
+
+
+
+

+ 132 - 0
experimental/sse/glm/ext/gtx/compatibility.inl

@@ -0,0 +1,132 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2008 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2007-03-16
+// Updated : 2007-09-06
+// Licence : This source is under GNU LGPL licence
+// File    : glm/gtx/compatibility.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace glm
+{
+	// isfiniteGTX
+	template <typename T> 
+	inline bool isfiniteGTX(T x)
+	{
+#ifdef GLM_COMPILER_VC
+		return _finite(x);
+#endif
+
+#ifdef GLM_COMPILER_GCC
+		return std::isfinite(x);
+#endif
+	}
+
+	template <typename T> 
+	inline detail::_bvec2 isfiniteGTX(const detail::_xvec2<T>& x)
+	{
+		return detail::_bvec2(
+			isfiniteGTX(x.x),
+			isfiniteGTX(x.y));
+	}
+
+    template <typename T> 
+	inline detail::_bvec3 isfiniteGTX(const detail::_xvec3<T>& x)
+	{
+		return detail::_bvec3(
+			isfiniteGTX(x.x),
+			isfiniteGTX(x.y),
+			isfiniteGTX(x.z));
+	}
+
+    template <typename T> 
+	inline detail::_bvec4 isfiniteGTX(const detail::_xvec4<T>& x)
+	{
+		return detail::_bvec4(
+			isfiniteGTX(x.x),
+			isfiniteGTX(x.y),
+			isfiniteGTX(x.z),
+			isfiniteGTX(x.w));
+	}
+
+	// isinfGTX
+	template <typename T> 
+	inline bool isinfGTX(T x)
+	{
+#ifdef GLM_COMPILER_VC
+		return _fpclass(x) == _FPCLASS_NINF || _fpclass(x) == _FPCLASS_PINF;
+#endif
+
+#ifdef GLM_COMPILER_GCC
+		return std::isinf(x);
+#endif
+	}
+
+	template <typename T> 
+	inline detail::_bvec2 isinfGTX(const detail::_xvec2<T>& x)
+	{
+		return detail::_bvec2(
+			isinfGTX(x.x),
+			isinfGTX(x.y));
+	}
+
+    template <typename T> 
+	inline detail::_bvec3 isinfGTX(const detail::_xvec3<T>& x)
+	{
+		return detail::_bvec3(
+			isinfGTX(x.x),
+			isinfGTX(x.y),
+			isinfGTX(x.z));
+	}
+
+    template <typename T> 
+	inline detail::_bvec4 isinfGTX(const detail::_xvec4<T>& x)
+	{
+		return detail::_bvec4(
+			isinfGTX(x.x),
+			isinfGTX(x.y),
+			isinfGTX(x.z),
+			isinfGTX(x.w));
+	}
+
+	// isnanGTX
+	template <typename T> 
+	inline bool isnanGTX(T x)
+	{
+#ifdef GLM_COMPILER_VC
+		return _isnan(x);
+#endif
+
+#ifdef GLM_COMPILER_GCC
+		return std::isnan(x);
+#endif
+	}
+
+	template <typename T> 
+	inline detail::_bvec2 isnanGTX(const detail::_xvec2<T>& x)
+	{
+		return detail::_bvec2(
+			isnanGTX(x.x),
+			isnanGTX(x.y));
+	}
+
+    template <typename T> 
+	inline detail::_bvec3 isnanGTX(const detail::_xvec3<T>& x)
+	{
+		return detail::_bvec3(
+			isnanGTX(x.x),
+			isnanGTX(x.y),
+			isnanGTX(x.z));
+	}
+
+    template <typename T> 
+	inline detail::_bvec4 isnanGTX(const detail::_xvec4<T>& x)
+	{
+		return detail::_bvec4(
+			isnanGTX(x.x),
+			isnanGTX(x.y),
+			isnanGTX(x.z),
+			isnanGTX(x.w));
+	}
+}
+

+ 49 - 0
experimental/sse/glm/ext/gtx/component_wise.h

@@ -0,0 +1,49 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2008 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2007-05-21
+// Updated : 2007-05-21
+// Licence : This source is under GNU LGPL licence
+// File    : glm/gtx/component_wise.h
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Dependency:
+// - GLM core
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef __glm_gtx_component_wise__
+#define __glm_gtx_component_wise__
+
+// Dependency:
+#include "../../glm.h"
+
+namespace glm
+{
+	template <typename genType> GLMvalType compAddGTX(const genType& v); //!< Add all vector components together. (From GLM_GTX_component_wise extension)
+	template <typename genType> GLMvalType compMulGTX(const genType& v); //!< Multiply all vector components together. (From GLM_GTX_component_wise extension)
+
+	template <typename genType> GLMvalType compMinGTX(const genType& v); //!< Find the minimum value between single vector components. (From GLM_GTX_component_wise extension)
+	template <typename genType> GLMvalType compMaxGTX(const genType& v); //!< Find the maximum value between single vector components. (From GLM_GTX_component_wise extension)
+
+	namespace gtx
+	{
+		//! GLM_GTX_component_wise extension: Operations between components of a type
+		namespace component_wise
+		{
+			template <typename genType> inline GLMvalType compAdd(const genType& v){return compAddGTX(v);} //!< Add all vector components together. (From GLM_GTX_component_wise extension)
+			template <typename genType> inline GLMvalType compMul(const genType& v){return compMulGTX(v);} //!< Multiply all vector components together. (From GLM_GTX_component_wise extension)
+
+			template <typename genType> inline GLMvalType compMin(const genType& v){return compMinGTX(v);} //!< Find the minimum value between single vector components. (From GLM_GTX_component_wise extension)
+			template <typename genType> inline GLMvalType compMax(const genType& v){return compMaxGTX(v);} //!< Find the maximum value between single vector components. (From GLM_GTX_component_wise extension)
+		}
+	}
+}
+
+#define GLM_GTX_component_wise namespace gtx::component_wise
+
+#include "component_wise.inl"
+
+#ifdef GLM_GTX_INCLUDED
+namespace glm{using GLM_GTX_component_wise;}
+#endif//GLM_GTX_INCLUDED
+
+#endif//__glm_gtx_component_wise__

+ 85 - 0
experimental/sse/glm/ext/gtx/component_wise.inl

@@ -0,0 +1,85 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2008 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2007-05-21
+// Updated : 2007-05-21
+// Licence : This source is under GNU LGPL licence
+// File    : gtx_component_wise.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace glm
+{
+	template <typename genType>
+	inline GLMvalType compAddGTX(const genType& 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>
+	inline valType compAddGTX(const genType& v)
+	{
+		valType result = valType(0);
+		for(sizeType i = 0; i < valSize; ++i)
+			result += v[i];
+		return result;
+	}
+*/
+	template <typename genType>
+	inline GLMvalType compMulGTX(const genType& 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>
+	inline GLMvalType compMulGTX(const genType& v)
+	{
+		valType result = valType(0);
+		for(GLMsizeType i = 0; i < valSize; ++i)
+			result *= v[i];
+		return result;
+	}
+*/
+	template <typename genType>
+	inline GLMvalType compMinGTX(const genType& v)
+	{
+        typename genType::size_type result = typename genType::value_type(0);
+		for(typename genType::size_type i = 0; i < genType::value_size; ++i)
+			result = min(result, v[i]);
+		return result;
+	}
+/*
+	template <typename genType>
+	inline GLMvalType compMinGTX(const genType& v)
+	{
+		valType result = valType(0);
+		for(GLMsizeType i = 0; i < valSize; ++i)
+			result = min(result, v[i]);
+		return result;
+	}
+*/
+	template <typename genType>
+	inline GLMvalType compMaxGTX(const genType& v)
+	{
+        typename genType::size_type result = typename genType::value_type(0);
+		for(typename genType::size_type i = 0; i < genType::value_size; ++i)
+			result = max(result, v[i]);
+		return result;
+	}
+/*
+	template <typename genType>
+	inline GLMvalType compMaxGTX(const genType& v)
+	{
+		GLMvalType result = GLMvalType(0);
+		for(GLMsizeType i = 0; i < GLMvalSize; ++i)
+			result = max(result, v[i]);
+		return result;
+	}
+*/
+}
+

+ 45 - 0
experimental/sse/glm/ext/gtx/determinant.h

@@ -0,0 +1,45 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2008 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2005-12-21
+// Updated : 2006-11-13
+// Licence : This source is under GNU LGPL licence
+// File    : glm/gtx/determinant.h
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Dependency:
+// - GLM core
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef __glm_gtx_determinant__
+#define __glm_gtx_determinant__
+
+// Dependency:
+#include "../../glm.h"
+
+namespace glm
+{
+    template <typename T> T determinantGTX(const detail::_xmat2<T>& m); //!< \brief Returns the determinant of a 2 * 2 matrix. (From GLM_GTX_determinant extension)
+    template <typename T> T determinantGTX(const detail::_xmat3<T>& m); //!< \brief Returns the determinant of a 3 * 3 matrix. (From GLM_GTX_determinant extension)
+    template <typename T> T determinantGTX(const detail::_xmat4<T>& m); //!< \brief Returns the determinant of a 4 * 4 matrix. (From GLM_GTX_determinant extension)
+
+	namespace gtx
+	{
+		//! GLM_GTX_determinant extension: Compute the determinant of a matrix
+		namespace determinant
+		{
+			template <typename T> inline T determinant(const detail::_xmat2<T>& m){return determinantGTX(m);} //!< \brief Returns the determinant of a 2 * 2 matrix. (From GLM_GTX_determinant extension)
+			template <typename T> inline T determinant(const detail::_xmat3<T>& m){return determinantGTX(m);} //!< \brief Returns the determinant of a 3 * 3 matrix. (From GLM_GTX_determinant extension)
+			template <typename T> inline T determinant(const detail::_xmat4<T>& m){return determinantGTX(m);} //!< \brief Returns the determinant of a 4 * 4 matrix. (From GLM_GTX_determinant extension)
+		}
+	}
+}
+
+#define GLM_GTX_determinant namespace gtx::determinant
+
+#include "determinant.inl"
+
+#ifdef GLM_GTX_INCLUDED
+namespace glm{using GLM_GTX_determinant;}
+#endif//GLM_GTX_INCLUDED
+
+#endif//__glm_gtx_determinant__

+ 47 - 0
experimental/sse/glm/ext/gtx/determinant.inl

@@ -0,0 +1,47 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2008 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2005-12-21
+// Updated : 2005-12-21
+// Licence : This source is under GNU LGPL licence
+// File    : glm/gtx/determinant.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace glm
+{
+    template <typename T>
+    inline T determinantGTX(const detail::_xmat2<T>& m)
+    {
+        return m[0][0] * m[1][1] - m[1][0] * m[0][1];
+    }
+
+    template <typename T>
+    inline T determinantGTX(const detail::_xmat3<T>& m)
+    {
+        return m[0][0] * (m[1][1] * m[2][2] - m[2][1] * m[1][2])
+            - m[1][0] * (m[0][1] * m[2][2] - m[2][1] * m[0][2])
+            + m[2][0] * (m[0][1] * m[1][2] - m[1][1] * m[0][2]);
+    }
+
+    template <typename T>
+    inline T determinantGTX(const detail::_xmat4<T>& m)
+    {
+        T SubFactor00 = m[2][2] * m[3][3] - m[3][2] * m[2][3];
+        T SubFactor01 = m[2][1] * m[3][3] - m[3][1] * m[2][3];
+        T SubFactor02 = m[2][1] * m[3][2] - m[3][1] * m[2][2];
+        T SubFactor03 = m[2][0] * m[3][3] - m[3][0] * m[2][3];
+        T SubFactor04 = m[2][0] * m[3][2] - m[3][0] * m[2][2];
+        T SubFactor05 = m[2][0] * m[3][1] - m[3][0] * m[2][1];
+
+        detail::_xvec4<T> DetCof(
+            + (m[1][1] * SubFactor00 - m[1][2] * SubFactor01 + m[1][3] * SubFactor02),
+            - (m[1][0] * SubFactor00 - m[1][2] * SubFactor03 + m[1][3] * SubFactor04),
+            + (m[1][0] * SubFactor01 - m[1][1] * SubFactor03 + m[1][3] * SubFactor05),
+            - (m[1][0] * SubFactor02 - m[1][1] * SubFactor04 + m[1][2] * SubFactor05));
+
+        return m[0][0] * DetCof[0]
+             + m[0][1] * DetCof[1]
+             + m[0][2] * DetCof[2]
+             + m[0][3] * DetCof[3];
+    }
+}

+ 80 - 0
experimental/sse/glm/ext/gtx/double.h

@@ -0,0 +1,80 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2008 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2005-12-21
+// Updated : 2006-03-20
+// Licence : This source is under GNU LGPL licence
+// File    : glm/gtx/double.h
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Dependency:
+// - GLM core
+// - GLM_GTX_quaternion
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// ToDo:
+// - Finish to declare extension functions
+// - Nothing define
+// - Study extension dependencies
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Note:
+// - This implementation doesn't need to redefine all build-in functions to
+// support double based type.
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef __glm_gtx_double__
+#define __glm_gtx_double__
+
+// Dependency:
+#include "../../glm.h"
+#include "../gtx/quaternion.h"
+
+namespace glm
+{
+    typedef detail::_xvec2<float> __fvec2GTX;	//!< \brief Vector of 2 single-precision floating-point numbers. (from GLM_GTX_double extension)
+    typedef detail::_xvec3<float> __fvec3GTX;	//!< \brief Vector of 3 single-precision floating-point numbers. (from GLM_GTX_double extension)
+    typedef detail::_xvec4<float> __fvec4GTX;	//!< \brief Vector of 4 single-precision floating-point numbers. (from GLM_GTX_double extension)
+    typedef detail::_xmat2<float> __fmat2GTX;	//!< \brief 2 * 2 matrix of single-precision floating-point numbers. (from GLM_GTX_double extension)
+    typedef detail::_xmat3<float> __fmat3GTX;	//!< \brief 3 * 3 matrix of single-precision floating-point numbers. (from GLM_GTX_double extension)
+    typedef detail::_xmat4<float> __fmat4GTX;	//!< \brief 4 * 4 matrix of single-precision floating-point numbers. (from GLM_GTX_double extension)
+    typedef detail::_xquat<float> __fquatGTX;	//!< \brief quaternion of single-precision floating-point numbers. (from GLM_GTX_double extension)
+
+    typedef detail::_xvec2<double> __dvec2GTX;	//!< \brief Vector of 2 double-precision floating-point numbers. (from GLM_GTX_double extension)
+    typedef detail::_xvec3<double> __dvec3GTX;	//!< \brief Vector of 3 double-precision floating-point numbers. (from GLM_GTX_double extension)
+    typedef detail::_xvec4<double> __dvec4GTX;	//!< \brief Vector of 4 double-precision floating-point numbers. (from GLM_GTX_double extension)
+    typedef detail::_xmat2<double> __dmat2GTX;	//!< \brief 2 * 2 matrix of double-precision floating-point numbers. (from GLM_GTX_double extension)
+    typedef detail::_xmat3<double> __dmat3GTX;	//!< \brief 3 * 3 matrix of double-precision floating-point numbers. (from GLM_GTX_double extension)
+    typedef detail::_xmat4<double> __dmat4GTX;	//!< \brief 4 * 4 matrix of double-precision floating-point numbers. (from GLM_GTX_double extension)
+    typedef detail::_xquat<double> __dquatGTX;	//!< \brief quaternion of double-precision floating-point numbers. (from GLM_GTX_double extension)
+
+	namespace gtx
+	{
+		//! GLM_GTX_double_float extension: Add support for double precision flotting-point types
+		namespace double_float
+		{
+			typedef detail::_xvec2<float> fvec2;	//!< \brief Vector of 2 single-precision floating-point numbers. (from GLM_GTX_double extension)
+			typedef detail::_xvec3<float> fvec3;	//!< \brief Vector of 3 single-precision floating-point numbers. (from GLM_GTX_double extension)
+			typedef detail::_xvec4<float> fvec4;	//!< \brief Vector of 4 single-precision floating-point numbers. (from GLM_GTX_double extension)
+			typedef detail::_xmat2<float> fmat2;	//!< \brief 2 * 2 matrix of single-precision floating-point numbers. (from GLM_GTX_double extension)
+			typedef detail::_xmat3<float> fmat3;	//!< \brief 3 * 3 matrix of single-precision floating-point numbers. (from GLM_GTX_double extension)
+			typedef detail::_xmat4<float> fmat4;	//!< \brief 4 * 4 matrix of single-precision floating-point numbers. (from GLM_GTX_double extension)
+			typedef detail::_xquat<float> fquat;	//!< \brief quaternion of single-precision floating-point numbers. (from GLM_GTX_double extension)
+
+			typedef detail::_xvec2<double> dvec2;	//!< \brief Vector of 2 double-precision floating-point numbers. (from GLM_GTX_double extension)
+			typedef detail::_xvec3<double> dvec3;	//!< \brief Vector of 3 double-precision floating-point numbers. (from GLM_GTX_double extension)
+			typedef detail::_xvec4<double> dvec4;	//!< \brief Vector of 4 double-precision floating-point numbers. (from GLM_GTX_double extension)
+			typedef detail::_xmat2<double> dmat2;	//!< \brief 2 * 2 matrix of double-precision floating-point numbers. (from GLM_GTX_double extension)
+			typedef detail::_xmat3<double> dmat3;	//!< \brief 3 * 3 matrix of double-precision floating-point numbers. (from GLM_GTX_double extension)
+			typedef detail::_xmat4<double> dmat4;	//!< \brief 4 * 4 matrix of double-precision floating-point numbers. (from GLM_GTX_double extension)
+			typedef detail::_xquat<double> dquat;	//!< \brief quaternion of double-precision floating-point numbers. (from GLM_GTX_double extension)
+		}
+	}
+}
+
+#define GLM_GTX_double namespace gtx::double_float
+
+#include "double.inl"
+
+#ifdef GLM_GTX_INCLUDED
+namespace glm{using GLM_GTX_double;}
+#endif//GLM_GTX_INCLUDED
+
+#endif//__glm_gtx_double__

+ 13 - 0
experimental/sse/glm/ext/gtx/double.inl

@@ -0,0 +1,13 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2008 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2005-12-21
+// Updated : 2005-12-21
+// Licence : This source is under GNU LGPL licence
+// File    : glm/gtx/double.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace glm
+{
+
+}

+ 100 - 0
experimental/sse/glm/ext/gtx/epsilon.h

@@ -0,0 +1,100 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2008 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2005-12-21
+// Updated : 2006-11-13
+// Licence : This source is under GNU LGPL licence
+// File    : glm/gtx/epsilon.h
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Dependency:
+// - GLM core
+// - GLM_GTX_double
+// - GLM_GTX_half
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef __glm_gtx_epsilon__
+#define __glm_gtx_epsilon__
+
+// Dependency:
+#include "../../glm.h"
+#include "../gtx/double.h"
+#include "../gtx/half.h"
+
+namespace glm
+{
+    template <typename T> bool equalEpsilonGTX(const T x, const T y, const T epsilon);																			//!< \brief Returns the component-wise compare of |x - y| < epsilon (from GLM_GTX_epsilon extension)
+    template <typename T> bool notEqualEpsilonGTX(const T x, const T y, const T epsilon);																		//!< \brief Returns the component-wise compare of |x - y| >= epsilon (from GLM_GTX_epsilon extension)
+
+    template <typename T> detail::_bvec2 equalEpsilonGTX(const detail::_xvec2<T>& x, const detail::_xvec2<T>& y, const T epsilon);								//!< \brief Returns the component-wise compare of |x - y| < epsilon (from GLM_GTX_epsilon extension)
+    template <typename T> detail::_bvec3 equalEpsilonGTX(const detail::_xvec3<T>& x, const detail::_xvec3<T>& y, const T epsilon);								//!< \brief Returns the component-wise compare of |x - y| < epsilon (from GLM_GTX_epsilon extension)
+    template <typename T> detail::_bvec4 equalEpsilonGTX(const detail::_xvec4<T>& x, const detail::_xvec4<T>& y, const T epsilon);								//!< \brief Returns the component-wise compare of |x - y| < epsilon (from GLM_GTX_epsilon extension)
+    template <typename T> detail::_bvec2 notEqualEpsilonGTX(const detail::_xvec2<T>& x, const detail::_xvec2<T>& y, const T epsilon);							//!< \brief Returns the component-wise compare of |x - y| >= epsilon (from GLM_GTX_epsilon extension)
+    template <typename T> detail::_bvec3 notEqualEpsilonGTX(const detail::_xvec3<T>& x, const detail::_xvec3<T>& y, const T epsilon);							//!< \brief Returns the component-wise compare of |x - y| >= epsilon (from GLM_GTX_epsilon extension)
+    template <typename T> detail::_bvec4 notEqualEpsilonGTX(const detail::_xvec4<T>& x, const detail::_xvec4<T>& y, const T epsilon);							//!< \brief Returns the component-wise compare of |x - y| >= epsilon (from GLM_GTX_epsilon extension)
+
+    template <typename T> detail::_bvec2 equalEpsilonGTX(const detail::_xvec2<T>& x, const detail::_xvec2<T>& y, const detail::_xvec2<T>& epsilon);				//!< \brief Returns the component-wise compare of |x - y| < epsilon (from GLM_GTX_epsilon extension)
+    template <typename T> detail::_bvec3 equalEpsilonGTX(const detail::_xvec3<T>& x, const detail::_xvec3<T>& y, const detail::_xvec3<T>& epsilon);				//!< \brief Returns the component-wise compare of |x - y| < epsilon (from GLM_GTX_epsilon extension)
+    template <typename T> detail::_bvec4 equalEpsilonGTX(const detail::_xvec4<T>& x, const detail::_xvec4<T>& y, const detail::_xvec4<T>& epsilon);				//!< \brief Returns the component-wise compare of |x - y| < epsilon (from GLM_GTX_epsilon extension)
+    template <typename T> detail::_bvec2 notEqualEpsilonGTX(const detail::_xvec2<T>& x, const detail::_xvec2<T>& y, const detail::_xvec2<T>& epsilon);			//!< \brief Returns the component-wise compare of |x - y| >= epsilon (from GLM_GTX_epsilon extension)
+    template <typename T> detail::_bvec3 notEqualEpsilonGTX(const detail::_xvec3<T>& x, const detail::_xvec3<T>& y, const detail::_xvec3<T>& epsilon);			//!< \brief Returns the component-wise compare of |x - y| >= epsilon (from GLM_GTX_epsilon extension)
+    template <typename T> detail::_bvec4 notEqualEpsilonGTX(const detail::_xvec4<T>& x, const detail::_xvec4<T>& y, const detail::_xvec4<T>& epsilon);			//!< \brief Returns the component-wise compare of |x - y| >= epsilon (from GLM_GTX_epsilon extension)
+/*
+	template <typename T>
+	class epsilonGTX
+	{
+	public:
+		epsilonGTX() : value(std::EPSILON){}
+		epsilonGTX(const T& value) : value(value){}
+
+	private:
+		T value;
+	};
+*/
+	namespace gtx
+	{
+		//! GLM_GTX_epsilon extension: Comparaison functions for a user defined epsilon values.
+		namespace epsilon
+		{
+			//! \brief Returns the component-wise compare of |x - y| < epsilon (from GLM_GTX_epsilon extension)
+			template <typename T> inline bool equalEpsilon(const T x, const T y, const T epsilon){return equalEpsilonGTX(x, y, epsilon);}
+			//! \brief Returns the component-wise compare of |x - y| >= epsilon (from GLM_GTX_epsilon extension)
+			template <typename T> inline bool notEqualEpsilon(const T x, const T y, const T epsilon){return notEqualEpsilonGTX(x, y, epsilon);}
+
+			//! \brief Returns the component-wise compare of |x - y| < epsilon (from GLM_GTX_epsilon extension)
+			template <typename T> inline detail::_bvec2 equalEpsilon(const detail::_xvec2<T>& x, const detail::_xvec2<T>& y, const T epsilon){return equalEpsilonGTX(x, y, epsilon);}
+			//! \brief Returns the component-wise compare of |x - y| < epsilon (from GLM_GTX_epsilon extension)
+			template <typename T> inline detail::_bvec3 equalEpsilon(const detail::_xvec3<T>& x, const detail::_xvec3<T>& y, const T epsilon){return equalEpsilonGTX(x, y, epsilon);}
+			//! \brief Returns the component-wise compare of |x - y| < epsilon (from GLM_GTX_epsilon extension)
+			template <typename T> inline detail::_bvec4 equalEpsilon(const detail::_xvec4<T>& x, const detail::_xvec4<T>& y, const T epsilon){return equalEpsilonGTX(x, y, epsilon);}
+			//! \brief Returns the component-wise compare of |x - y| >= epsilon (from GLM_GTX_epsilon extension)
+			template <typename T> inline detail::_bvec2 notEqualEpsilon(const detail::_xvec2<T>& x, const detail::_xvec2<T>& y, const T epsilon){return notEqualEpsilonGTX(x, y, epsilon);}
+			//! \brief Returns the component-wise compare of |x - y| >= epsilon (from GLM_GTX_epsilon extension)
+			template <typename T> inline detail::_bvec3 notEqualEpsilon(const detail::_xvec3<T>& x, const detail::_xvec3<T>& y, const T epsilon){return notEqualEpsilonGTX(x, y, epsilon);}
+			//! \brief Returns the component-wise compare of |x - y| >= epsilon (from GLM_GTX_epsilon extension)
+			template <typename T> inline detail::_bvec4 notEqualEpsilon(const detail::_xvec4<T>& x, const detail::_xvec4<T>& y, const T epsilon){return notEqualEpsilonGTX(x, y, epsilon);}
+
+			//! \brief Returns the component-wise compare of |x - y| < epsilon (from GLM_GTX_epsilon extension)
+			template <typename T> inline detail::_bvec2 equalEpsilon(const detail::_xvec2<T>& x, const detail::_xvec2<T>& y, const detail::_xvec2<T>& epsilon){return equalEpsilonGTX(x, y, epsilon);}
+			//! \brief Returns the component-wise compare of |x - y| < epsilon (from GLM_GTX_epsilon extension)
+			template <typename T> inline detail::_bvec3 equalEpsilon(const detail::_xvec3<T>& x, const detail::_xvec3<T>& y, const detail::_xvec3<T>& epsilon){return equalEpsilonGTX(x, y, epsilon);}
+			//! \brief Returns the component-wise compare of |x - y| < epsilon (from GLM_GTX_epsilon extension)
+			template <typename T> inline detail::_bvec4 equalEpsilon(const detail::_xvec4<T>& x, const detail::_xvec4<T>& y, const detail::_xvec4<T>& epsilon){return equalEpsilonGTX(x, y, epsilon);}
+			//! \brief Returns the component-wise compare of |x - y| >= epsilon (from GLM_GTX_epsilon extension)
+			template <typename T> inline detail::_bvec2 notEqualEpsilon(const detail::_xvec2<T>& x, const detail::_xvec2<T>& y, const detail::_xvec2<T>& epsilon){return notEqualEpsilonGTX(x, y, epsilon);}
+			//! \brief Returns the component-wise compare of |x - y| >= epsilon (from GLM_GTX_epsilon extension)
+			template <typename T> inline detail::_bvec3 notEqualEpsilon(const detail::_xvec3<T>& x, const detail::_xvec3<T>& y, const detail::_xvec3<T>& epsilon){return notEqualEpsilonGTX(x, y, epsilon);}
+			//! \brief Returns the component-wise compare of |x - y| >= epsilon (from GLM_GTX_epsilon extension)
+			template <typename T> inline detail::_bvec4 notEqualEpsilon(const detail::_xvec4<T>& x, const detail::_xvec4<T>& y, const detail::_xvec4<T>& epsilon){return notEqualEpsilonGTX(x, y, epsilon);}
+		}
+	}
+}
+
+#define GLM_GTX_epsilon namespace gtx::epsilon
+
+#include "epsilon.inl"
+
+#ifdef GLM_GTX_INCLUDED
+namespace glm{using GLM_GTX_epsilon;}
+#endif//GLM_GTX_INCLUDED
+
+#endif//__glm_gtx_epsilon__

+ 131 - 0
experimental/sse/glm/ext/gtx/epsilon.inl

@@ -0,0 +1,131 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2008 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2005-12-21
+// Updated : 2006-01-16
+// Licence : This source is under GNU LGPL licence
+// File    : glm/gtx/epsilon.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace glm
+{
+    template <typename T>
+    inline bool equalEpsilonGTX(T x, T y, T epsilon)
+    {
+        return abs(x - y) < epsilon;
+    }
+
+    template <typename T>
+    inline bool notEqualEpsilonGTX(T x, T y, T epsilon)
+    {
+        return abs(x - y) >= epsilon;
+    }
+
+    template <typename T>
+    inline detail::_bvec2 equalEpsilonGTX(const detail::_xvec2<T>& x, const detail::_xvec2<T>& y, const T epsilon)
+    {
+        return detail::_bvec2(
+            abs(x.x - y.x) < epsilon,
+            abs(y.y - y.y) < epsilon);
+    }
+
+    template <typename T>
+    inline detail::_bvec3 equalEpsilonGTX(const detail::_xvec3<T>& x, const detail::_xvec3<T>& y, const T epsilon)
+    {
+        return detail::_bvec3(
+            abs(x.x - y.x) < epsilon,
+            abs(y.y - y.y) < epsilon,
+            abs(y.z - y.z) < epsilon);
+    }
+
+    template <typename T>
+    inline detail::_bvec4 equalEpsilonGTX(const detail::_xvec4<T>& x, const detail::_xvec4<T>& y, const T epsilon)
+    {
+        return detail::_bvec4(
+            abs(x.x - y.x) < epsilon,
+            abs(y.y - y.y) < epsilon,
+            abs(y.z - y.z) < epsilon,
+            abs(y.w - y.w) < epsilon);
+    }
+
+    template <typename T>
+    inline detail::_bvec2 notEqualEpsilonGTX(const detail::_xvec2<T>& x, const detail::_xvec2<T>& y, const T epsilon)
+    {
+        return detail::_bvec2(
+            abs(x.x - y.x) >= epsilon,
+            abs(y.y - y.y) >= epsilon);
+    }
+
+    template <typename T>
+    inline detail::_bvec3 notEqualEpsilonGTX(const detail::_xvec3<T>& x, const detail::_xvec3<T>& y, const T epsilon)
+    {
+        return detail::_bvec3(
+            abs(x.x - y.x) >= epsilon,
+            abs(y.y - y.y) >= epsilon,
+            abs(y.z - y.z) >= epsilon);
+    }
+
+    template <typename T>
+    inline detail::_bvec4 notEqualEpsilonGTX(const detail::_xvec4<T>& x, const detail::_xvec4<T>& y, const T epsilon)
+    {
+        return detail::_bvec4(
+            abs(x.x - y.x) >= epsilon,
+            abs(y.y - y.y) >= epsilon,
+            abs(y.z - y.z) >= epsilon,
+            abs(y.w - y.w) >= epsilon);
+    }
+
+    template <typename T>
+    inline detail::_bvec2 equalEpsilonGTX(const detail::_xvec2<T>& x, const detail::_xvec2<T>& y, const detail::_xvec2<T>& epsilon)
+    {
+        return detail::_bvec2(
+            abs(x.x - y.x) < epsilon.x,
+            abs(y.y - y.y) < epsilon.y);
+    }
+
+    template <typename T>
+    inline detail::_bvec3 equalEpsilonGTX(const detail::_xvec3<T>& x, const detail::_xvec3<T>& y, const detail::_xvec3<T>& epsilon)
+    {
+        return detail::_bvec3(
+            abs(x.x - y.x) < epsilon.x,
+            abs(y.y - y.y) < epsilon.y,
+            abs(y.z - y.z) < epsilon.z);
+    }
+
+    template <typename T>
+    inline detail::_bvec4 equalEpsilonGTX(const detail::_xvec4<T>& x, const detail::_xvec4<T>& y, const detail::_xvec4<T>& epsilon)
+    {
+        return detail::_bvec4(
+            abs(x.x - y.x) < epsilon.x,
+            abs(y.y - y.y) < epsilon.y,
+            abs(y.z - y.z) < epsilon.z,
+            abs(y.w - y.w) < epsilon.w);
+    }
+
+    template <typename T>
+    inline detail::_bvec2 notEqualEpsilonGTX(const detail::_xvec2<T>& x, const detail::_xvec2<T>& y, const detail::_xvec2<T>& epsilon)
+    {
+        return detail::_bvec2(
+            abs(x.x - y.x) >= epsilon.x,
+            abs(y.y - y.y) >= epsilon.y);
+    }
+
+    template <typename T>
+    inline detail::_bvec3 notEqualEpsilonGTX(const detail::_xvec3<T>& x, const detail::_xvec3<T>& y, const detail::_xvec3<T>& epsilon)
+    {
+        return detail::_bvec3(
+            abs(x.x - y.x) >= epsilon.x,
+            abs(y.y - y.y) >= epsilon.y,
+            abs(y.z - y.z) >= epsilon.z);
+    }
+
+    template <typename T>
+    inline detail::_bvec4 notEqualEpsilonGTX(const detail::_xvec4<T>& x, const detail::_xvec4<T>& y, const detail::_xvec4<T>& epsilon)
+    {
+        return detail::_bvec4(
+            abs(x.x - y.x) >= epsilon.x,
+            abs(y.y - y.y) >= epsilon.y,
+            abs(y.z - y.z) >= epsilon.z,
+            abs(y.w - y.w) >= epsilon.w);
+    }
+}

+ 54 - 0
experimental/sse/glm/ext/gtx/euler_angles.h

@@ -0,0 +1,54 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2008 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2005-12-21
+// Updated : 2007-08-14
+// Licence : This source is under GNU LGPL licence
+// File    : glm/gtx/euler_angles.h
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Dependency:
+// - GLM core
+// - GLM_GTX_double
+// - GLM_GTX_half
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// ToDo:
+// - mat2 mat2GTX(const vec2& angles) undefined
+// - mat3 mat3GTX(const vec2& angles) undefined
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef __glm_gtx_euler_angles__
+#define __glm_gtx_euler_angles__
+
+// Dependency:
+#include "../../glm.h"
+#include "../gtx/double.h"
+
+namespace glm
+{
+    template <typename T> detail::_xmat2<T> orientate2GTX(const T angle);						//!< \brief Creates a 2 * 2 rotation matrix from angle (from GLM_GTX_euler_angles extension)
+    template <typename T> detail::_xmat3<T> orientate3GTX(const T angle);						//!< \brief Creates a 3 * 3 rotation matrix from angle (from GLM_GTX_euler_angles extension)
+    template <typename T> detail::_xmat3<T> orientate3GTX(const detail::_xvec3<T>& angles);     //!< \brief Creates a 3 * 3 rotation matrix from angles (from GLM_GTX_euler_angles extension)
+    template <typename T> detail::_xmat4<T> orientate4GTX(const detail::_xvec3<T>& angles);     //!< \brief Creates a 4 * 4 rotation matrix from angles (from GLM_GTX_euler_angles extension)
+
+    namespace gtx
+    {
+		//! GLM_GTX_euler_angles extension: Build matrices from euler angles.
+		namespace euler_angles
+		{
+			template <typename T> inline detail::_xmat2<T> orientate2(const T angle){return orientate2GTX(angle);}						//!< \brief Creates a 2 * 2 rotation matrix from angle (from GLM_GTX_euler_angles extension)
+			template <typename T> inline detail::_xmat3<T> orientate3(const T angle){return orientate3GTX(angle);}						//!< \brief Creates a 3 * 3 rotation matrix from angle (from GLM_GTX_euler_angles extension)
+			template <typename T> inline detail::_xmat3<T> orientate3(const detail::_xvec3<T>& angles){return orientate3GTX(angles);}   //!< \brief Creates a 3 * 3 rotation matrix from angles (from GLM_GTX_euler_angles extension)
+			template <typename T> inline detail::_xmat4<T> orientate4(const detail::_xvec3<T>& angles){return orientate4GTX(angles);}   //!< \brief Creates a 4 * 4 rotation matrix from angles (from GLM_GTX_euler_angles extension)
+		}
+    }
+}
+
+#define GLM_GTX_euler_angles namespace gtx::euler_angles
+
+#include "euler_angles.inl"
+
+#ifdef GLM_GTX_INCLUDED
+namespace glm{using GLM_GTX_euler_angles;}
+#endif//GLM_GTX_INCLUDED
+
+#endif//__glm_gtx_euler_angles__

+ 97 - 0
experimental/sse/glm/ext/gtx/euler_angles.inl

@@ -0,0 +1,97 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2008 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2005-12-21
+// Updated : 2007-08-14
+// Licence : This source is under GNU LGPL licence
+// File    : glm/gtx/euler_angles.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace glm
+{
+    template <typename T>
+	inline detail::_xmat2<T> orientate2GTX(const T angle)
+	{
+        T c = cos(angle);
+        T s = sin(angle);
+
+		detail::_xmat2<T> Result;
+        Result[0][0] = c;
+        Result[0][1] = s;
+        Result[1][0] = -s;
+        Result[1][1] = c;
+		return Result;
+	}
+
+    template <typename T>
+	inline detail::_xmat3<T> orientate3GTX(const T angle)
+	{
+        T c = cos(angle);
+        T s = sin(angle);
+
+		detail::_xmat3<T> 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 T>
+    inline detail::_xmat3<T> orientate3GTX(const detail::_xvec3<T>& angles)
+    {
+        T tmp_ch = cos(angles.x);
+        T tmp_sh = sin(angles.x);
+        T tmp_cp = cos(angles.y);
+        T tmp_sp = sin(angles.y);
+        T tmp_cb = cos(angles.z);
+        T tmp_sb = sin(angles.z);
+
+        detail::_xmat3<T> 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[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[2][0] = tmp_sh * tmp_cp;
+        Result[2][1] = -tmp_sp;
+        Result[2][2] = tmp_ch * tmp_cp;
+        return Result;
+    }
+
+	template <typename T>
+    inline detail::_xmat4<T> orientate4GTX(const detail::_xvec3<T>& angles)
+    {
+        T tmp_ch = cos(angles.x);
+        T tmp_sh = sin(angles.x);
+        T tmp_cp = cos(angles.y);
+        T tmp_sp = sin(angles.y);
+        T tmp_cb = cos(angles.z);
+        T tmp_sb = sin(angles.z);
+
+        detail::_xmat4<T> 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] = T(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] = T(0);
+        Result[2][0] = tmp_sh * tmp_cp;
+        Result[2][1] = -tmp_sp;
+        Result[2][2] = tmp_ch * tmp_cp;
+        Result[2][3] = T(0);
+        Result[3][0] = T(0);
+        Result[3][1] = T(0);
+        Result[3][2] = T(0);
+        Result[3][3] = T(1);
+        return Result;
+    }
+}

+ 41 - 0
experimental/sse/glm/ext/gtx/extend.h

@@ -0,0 +1,41 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2008 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2006-01-07
+// Updated : 2006-11-13
+// Licence : This source is under GNU LGPL licence
+// File    : glm/gtx/extend.h
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Dependency:
+// - GLM core
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef __glm_gtx_extend__
+#define __glm_gtx_extend__
+
+// Dependency:
+#include "../../glm.h"
+
+namespace glm
+{
+	template <typename genType, typename T> genType extendGTX(const genType& Origin, const genType& Source, const T Length); //!< \brief Extends of Length the Origin position using the (Source - Origin) direction (from GLM_GTX_extend extension)
+
+	namespace gtx
+	{
+		//! GLM_GTX_extend extension: Extend a position from a source to a position at a defined length.
+		namespace extend
+		{
+			template <typename genType, typename T> inline genType extend(const genType& Origin, const genType& Source, const T Length){return extendGTX(Origin, Source, Length);} //!< \brief Extends of Length the Origin position using the (Source - Origin) direction (from GLM_GTX_extend extension)
+		}
+	}
+}
+
+#define GLM_GTX_extend namespace gtx::extend
+
+#include "extend.inl"
+
+#ifdef GLM_GTX_INCLUDED
+namespace glm{using GLM_GTX_extend;}
+#endif//GLM_GTX_INCLUDED
+
+#endif//__glm_gtx_extend__

+ 38 - 0
experimental/sse/glm/ext/gtx/extend.inl

@@ -0,0 +1,38 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2008 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2006-01-07
+// Updated : 2006-01-07
+// Licence : This source is under GNU LGPL licence
+// File    : gtx_extend.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Dependency:
+// - GLM version 1.0
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace glm
+{
+	template <typename T>
+    T extendGTX(const T Origin, const T Source, const T Distance)
+    {
+        return Origin + (Source - Origin) * Distance;
+    }
+
+	template <typename T>
+    detail::_xvec2<T> extendGTX(const detail::_xvec2<T>& Origin, const detail::_xvec2<T>& Source, const T Distance)
+    {
+        return Origin + (Source - Origin) * Distance;
+    }
+
+	template <typename T>
+    detail::_xvec3<T> extendGTX(const detail::_xvec3<T>& Origin, const detail::_xvec3<T>& Source, const T Distance)
+    {
+        return Origin + (Source - Origin) * Distance;
+    }
+
+	template <typename T>
+    detail::_xvec4<T> extendGTX(const detail::_xvec4<T>& Origin, const detail::_xvec4<T>& Source, const T Distance)
+    {
+        return Origin + (Source - Origin) * Distance;
+    }
+}

+ 105 - 0
experimental/sse/glm/ext/gtx/extented_min_max.h

@@ -0,0 +1,105 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2008 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2007-03-14
+// Updated : 2007-08-14
+// Licence : This source is under GNU LGPL licence
+// File    : gtx_extented_min_max.h
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Dependency:
+// - GLM core
+// - GLM_GTX_half
+// - GLM_GTX_double
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef __glm_gtx_extented_min_max__
+#define __glm_gtx_extented_min_max__
+
+// Dependency:
+#include "../../glm.h"
+#include "../gtx/half.h"
+#include "../gtx/double.h"
+
+namespace glm
+{
+	template <typename T> detail::_xvec2<T> minGTX(const detail::_xvec2<T>& x, const T y, const T z); //!< Return the minimum component-wise values of 3 imputs (From GLM_GTX_extented_min_max extension)
+    template <typename T> detail::_xvec3<T> minGTX(const detail::_xvec3<T>& x, const T y, const T z); //!< Return the minimum component-wise values of 3 imputs (From GLM_GTX_extented_min_max extension)
+    template <typename T> detail::_xvec4<T> minGTX(const detail::_xvec4<T>& x, const T y, const T z); //!< Return the minimum component-wise values of 3 imputs (From GLM_GTX_extented_min_max extension)
+
+    template <typename T> detail::_xvec2<T> minGTX(const detail::_xvec2<T>& x, const T y, const T z, const T w); //!< Return the minimum component-wise values of 4 imputs (From GLM_GTX_extented_min_max extension)
+    template <typename T> detail::_xvec3<T> minGTX(const detail::_xvec3<T>& x, const T y, const T z, const T w); //!< Return the minimum component-wise values of 4 imputs (From GLM_GTX_extented_min_max extension)
+    template <typename T> detail::_xvec4<T> minGTX(const detail::_xvec4<T>& x, const T y, const T z, const T w); //!< Return the minimum component-wise values of 4 imputs (From GLM_GTX_extented_min_max extension)
+
+    template <typename T> detail::_xvec2<T> minGTX(const detail::_xvec2<T>& x, const detail::_xvec2<T>& y, const detail::_xvec2<T>& z); //!< Return the minimum component-wise values of 3 imputs (From GLM_GTX_extented_min_max extension)
+    template <typename T> detail::_xvec3<T> minGTX(const detail::_xvec3<T>& x, const detail::_xvec3<T>& y, const detail::_xvec3<T>& z); //!< Return the minimum component-wise values of 3 imputs (From GLM_GTX_extented_min_max extension)
+    template <typename T> detail::_xvec4<T> minGTX(const detail::_xvec4<T>& x, const detail::_xvec4<T>& y, const detail::_xvec4<T>& z); //!< Return the minimum component-wise values of 3 imputs (From GLM_GTX_extented_min_max extension)
+
+    template <typename T> detail::_xvec2<T> minGTX(const detail::_xvec2<T>& x, const detail::_xvec2<T>& y, const detail::_xvec2<T>& z, const detail::_xvec2<T>& w); //!< Return the minimum component-wise values of 4 imputs (From GLM_GTX_extented_min_max extension)
+    template <typename T> detail::_xvec3<T> minGTX(const detail::_xvec3<T>& x, const detail::_xvec3<T>& y, const detail::_xvec3<T>& z, const detail::_xvec3<T>& w); //!< Return the minimum component-wise values of 4 imputs (From GLM_GTX_extented_min_max extension)
+    template <typename T> detail::_xvec4<T> minGTX(const detail::_xvec4<T>& x, const detail::_xvec4<T>& y, const detail::_xvec4<T>& z, const detail::_xvec4<T>& w); //!< Return the minimum component-wise values of 4 imputs (From GLM_GTX_extented_min_max extension)
+
+	template <typename T> detail::_xvec2<T> maxGTX(const detail::_xvec2<T>& x, const T y, const T z); //!< Return the maximum component-wise values of 3 imputs (From GLM_GTX_extented_min_max extension)
+    template <typename T> detail::_xvec3<T> maxGTX(const detail::_xvec3<T>& x, const T y, const T z); //!< Return the maximum component-wise values of 3 imputs (From GLM_GTX_extented_min_max extension)
+    template <typename T> detail::_xvec4<T> maxGTX(const detail::_xvec4<T>& x, const T y, const T z); //!< Return the maximum component-wise values of 3 imputs (From GLM_GTX_extented_min_max extension)
+
+    template <typename T> detail::_xvec2<T> maxGTX(const detail::_xvec2<T>& x, const T y, const T z, const T w); //!< Return the maximum component-wise values of 4 imputs (From GLM_GTX_extented_min_max extension)
+    template <typename T> detail::_xvec3<T> maxGTX(const detail::_xvec3<T>& x, const T y, const T z, const T w); //!< Return the maximum component-wise values of 4 imputs (From GLM_GTX_extented_min_max extension)
+    template <typename T> detail::_xvec4<T> maxGTX(const detail::_xvec4<T>& x, const T y, const T z, const T w); //!< Return the maximum component-wise values of 4 imputs (From GLM_GTX_extented_min_max extension)
+
+    template <typename T> detail::_xvec2<T> maxGTX(const detail::_xvec2<T>& x, const detail::_xvec2<T>& y, const detail::_xvec2<T>& z); //!< Return the maximum component-wise values of 3 imputs (From GLM_GTX_extented_min_max extension)
+    template <typename T> detail::_xvec3<T> maxGTX(const detail::_xvec3<T>& x, const detail::_xvec3<T>& y, const detail::_xvec3<T>& z); //!< Return the maximum component-wise values of 3 imputs (From GLM_GTX_extented_min_max extension)
+    template <typename T> detail::_xvec4<T> maxGTX(const detail::_xvec4<T>& x, const detail::_xvec4<T>& y, const detail::_xvec4<T>& z); //!< Return the maximum component-wise values of 3 imputs (From GLM_GTX_extented_min_max extension)
+
+    template <typename T> detail::_xvec2<T> maxGTX(const detail::_xvec2<T>& x, const detail::_xvec2<T>& y, const detail::_xvec2<T>& z, const detail::_xvec2<T>& w); //!< Return the maximum component-wise values of 4 imputs (From GLM_GTX_extented_min_max extension)
+    template <typename T> detail::_xvec3<T> maxGTX(const detail::_xvec3<T>& x, const detail::_xvec3<T>& y, const detail::_xvec3<T>& z, const detail::_xvec3<T>& w); //!< Return the maximum component-wise values of 4 imputs (From GLM_GTX_extented_min_max extension)
+    template <typename T> detail::_xvec4<T> maxGTX(const detail::_xvec4<T>& x, const detail::_xvec4<T>& y, const detail::_xvec4<T>& z, const detail::_xvec4<T>& w); //!< Return the maximum component-wise values of 4 imputs (From GLM_GTX_extented_min_max extension)
+
+	namespace gtx
+	{
+		//! GLM_GTX_extented_min_max extension: Min and max functions for 3 to 4 parameters.
+		namespace extented_min_max
+		{
+			template <typename T> inline detail::_xvec2<T> min(const detail::_xvec2<T>& x, const T y, const T z){return minGTX(x, y, z);} //!< Return the minimum component-wise values of 3 imputs (From GLM_GTX_extented_min_max extension)
+			template <typename T> inline detail::_xvec3<T> min(const detail::_xvec3<T>& x, const T y, const T z){return minGTX(x, y, z);} //!< Return the minimum component-wise values of 3 imputs (From GLM_GTX_extented_min_max extension)
+			template <typename T> inline detail::_xvec4<T> min(const detail::_xvec4<T>& x, const T y, const T z){return minGTX(x, y, z);} //!< Return the minimum component-wise values of 3 imputs (From GLM_GTX_extented_min_max extension)
+
+			template <typename T> inline detail::_xvec2<T> min(const detail::_xvec2<T>& x, const T y, const T z, const T w){return minGTX(x, y, z, w);} //!< Return the minimum component-wise values of 4 imputs (From GLM_GTX_extented_min_max extension)
+			template <typename T> inline detail::_xvec3<T> min(const detail::_xvec3<T>& x, const T y, const T z, const T w){return minGTX(x, y, z, w);} //!< Return the minimum component-wise values of 4 imputs (From GLM_GTX_extented_min_max extension)
+			template <typename T> inline detail::_xvec4<T> min(const detail::_xvec4<T>& x, const T y, const T z, const T w){return minGTX(x, y, z, w);} //!< Return the minimum component-wise values of 4 imputs (From GLM_GTX_extented_min_max extension)
+
+			template <typename T> inline detail::_xvec2<T> min(const detail::_xvec2<T>& x, const detail::_xvec2<T>& y, const detail::_xvec2<T>& z){return minGTX(x, y, z);} //!< Return the minimum component-wise values of 3 imputs (From GLM_GTX_extented_min_max extension)
+			template <typename T> inline detail::_xvec3<T> min(const detail::_xvec3<T>& x, const detail::_xvec3<T>& y, const detail::_xvec3<T>& z){return minGTX(x, y, z);} //!< Return the minimum component-wise values of 3 imputs (From GLM_GTX_extented_min_max extension)
+			template <typename T> inline detail::_xvec4<T> min(const detail::_xvec4<T>& x, const detail::_xvec4<T>& y, const detail::_xvec4<T>& z){return minGTX(x, y, z);} //!< Return the minimum component-wise values of 3 imputs (From GLM_GTX_extented_min_max extension)
+
+			template <typename T> inline detail::_xvec2<T> min(const detail::_xvec2<T>& x, const detail::_xvec2<T>& y, const detail::_xvec2<T>& z, const detail::_xvec2<T>& w){return minGTX(x, y, z, w);} //!< Return the minimum component-wise values of 4 imputs (From GLM_GTX_extented_min_max extension)
+			template <typename T> inline detail::_xvec3<T> min(const detail::_xvec3<T>& x, const detail::_xvec3<T>& y, const detail::_xvec3<T>& z, const detail::_xvec3<T>& w){return minGTX(x, y, z, w);} //!< Return the minimum component-wise values of 4 imputs (From GLM_GTX_extented_min_max extension)
+			template <typename T> inline detail::_xvec4<T> min(const detail::_xvec4<T>& x, const detail::_xvec4<T>& y, const detail::_xvec4<T>& z, const detail::_xvec4<T>& w){return minGTX(x, y, z, w);} //!< Return the minimum component-wise values of 4 imputs (From GLM_GTX_extented_min_max extension)
+
+			template <typename T> inline detail::_xvec2<T> max(const detail::_xvec2<T>& x, const T y, const T z){return maxGTX(x, y, z);} //!< Return the maximum component-wise values of 3 imputs (From GLM_GTX_extented_min_max extension)
+			template <typename T> inline detail::_xvec3<T> max(const detail::_xvec3<T>& x, const T y, const T z){return maxGTX(x, y, z);} //!< Return the maximum component-wise values of 3 imputs (From GLM_GTX_extented_min_max extension)
+			template <typename T> inline detail::_xvec4<T> max(const detail::_xvec4<T>& x, const T y, const T z){return maxGTX(x, y, z);} //!< Return the maximum component-wise values of 3 imputs (From GLM_GTX_extented_min_max extension)
+
+			template <typename T> inline detail::_xvec2<T> max(const detail::_xvec2<T>& x, const T y, const T z, const T w){return maxGTX(x, y, z, w);} //!< Return the maximum component-wise values of 4 imputs (From GLM_GTX_extented_min_max extension)
+			template <typename T> inline detail::_xvec3<T> max(const detail::_xvec3<T>& x, const T y, const T z, const T w){return maxGTX(x, y, z, w);} //!< Return the maximum component-wise values of 4 imputs (From GLM_GTX_extented_min_max extension)
+			template <typename T> inline detail::_xvec4<T> max(const detail::_xvec4<T>& x, const T y, const T z, const T w){return maxGTX(x, y, z, w);} //!< Return the maximum component-wise values of 4 imputs (From GLM_GTX_extented_min_max extension)
+
+			template <typename T> inline detail::_xvec2<T> max(const detail::_xvec2<T>& x, const detail::_xvec2<T>& y, const detail::_xvec2<T>& z){return maxGTX(x, y, z);} //!< Return the maximum component-wise values of 3 imputs (From GLM_GTX_extented_min_max extension)
+			template <typename T> inline detail::_xvec3<T> max(const detail::_xvec3<T>& x, const detail::_xvec3<T>& y, const detail::_xvec3<T>& z){return maxGTX(x, y, z);} //!< Return the maximum component-wise values of 3 imputs (From GLM_GTX_extented_min_max extension)
+			template <typename T> inline detail::_xvec4<T> max(const detail::_xvec4<T>& x, const detail::_xvec4<T>& y, const detail::_xvec4<T>& z){return maxGTX(x, y, z);} //!< Return the maximum component-wise values of 3 imputs (From GLM_GTX_extented_min_max extension)
+
+			template <typename T> inline detail::_xvec2<T> max(const detail::_xvec2<T>& x, const detail::_xvec2<T>& y, const detail::_xvec2<T>& z, const detail::_xvec2<T>& w){return maxGTX(x, y, z, w);} //!< Return the maximum component-wise values of 4 imputs (From GLM_GTX_extented_min_max extension)
+			template <typename T> inline detail::_xvec3<T> max(const detail::_xvec3<T>& x, const detail::_xvec3<T>& y, const detail::_xvec3<T>& z, const detail::_xvec3<T>& w){return maxGTX(x, y, z, w);} //!< Return the maximum component-wise values of 4 imputs (From GLM_GTX_extented_min_max extension)
+			template <typename T> inline detail::_xvec4<T> max(const detail::_xvec4<T>& x, const detail::_xvec4<T>& y, const detail::_xvec4<T>& z, const detail::_xvec4<T>& w){return maxGTX(x, y, z, w);} //!< Return the maximum component-wise values of 4 imputs (From GLM_GTX_extented_min_max extension)
+		}
+	}
+}
+
+#define GLM_GTX_extented_min_max namespace gtx::extented_min_max
+
+#include "extented_min_max.inl"
+
+#ifdef GLM_GTX_INCLUDED
+namespace glm{using GLM_GTX_extented_min_max;}
+#endif//GLM_GTX_INCLUDED
+
+#endif//__glm_gtx_extented_min_max__

+ 155 - 0
experimental/sse/glm/ext/gtx/extented_min_max.inl

@@ -0,0 +1,155 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2008 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2007-03-14
+// Updated : 2007-03-14
+// Licence : This source is under GNU LGPL licence
+// File    : gtx_extented_min_max.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace glm
+{
+	template <typename T> 
+	inline detail::_xvec2<T> minGTX(const detail::_xvec2<T>& x, const T y, const T z)
+	{
+		return min(x, min(y, z));
+	}
+
+    template <typename T> 
+	inline detail::_xvec3<T> minGTX(const detail::_xvec3<T>& x, const T y, const T z)
+	{
+		return min(x, min(y, z));
+	}
+
+    template <typename T> 
+	inline detail::_xvec4<T> minGTX(const detail::_xvec4<T>& x, const T y, const T z)
+	{
+		return min(x, min(y, z));
+	}
+
+    template <typename T> 
+	inline detail::_xvec2<T> minGTX(const detail::_xvec2<T>& x, const T y, const T z, const T w)
+	{
+		return min(x, min(y, min(z, w)));
+	}
+
+    template <typename T> 
+	inline detail::_xvec3<T> minGTX(const detail::_xvec3<T>& x, const T y, const T z, const T w)
+	{
+		return min(x, min(y, min(z, w)));
+	}
+
+    template <typename T> 
+	inline detail::_xvec4<T> minGTX(const detail::_xvec4<T>& x, const T y, const T z, const T w)
+	{
+		return min(x, min(y, min(z, w)));
+	}
+
+    template <typename T> 
+	inline detail::_xvec2<T> minGTX(const detail::_xvec2<T>& x, const detail::_xvec2<T>& y, const detail::_xvec2<T>& z)
+	{
+		return min(x, min(y, z));
+	}
+
+    template <typename T> 
+	inline detail::_xvec3<T> minGTX(const detail::_xvec3<T>& x, const detail::_xvec3<T>& y, const detail::_xvec3<T>& z)
+	{
+		return min(x, min(y, z));
+	}
+
+    template <typename T> 
+	inline detail::_xvec4<T> minGTX(const detail::_xvec4<T>& x, const detail::_xvec4<T>& y, const detail::_xvec4<T>& z)
+	{
+		return min(x, min(y, z));
+	}
+	
+    template <typename T> 
+	inline detail::_xvec2<T> minGTX(const detail::_xvec2<T>& x, const detail::_xvec2<T>& y, const detail::_xvec2<T>& z, const detail::_xvec2<T>& w)
+	{
+		return min(min(x, y), min(z, w));
+	}
+
+    template <typename T> 
+	inline detail::_xvec3<T> minGTX(const detail::_xvec3<T>& x, const detail::_xvec3<T>& y, const detail::_xvec3<T>& z, const detail::_xvec3<T>& w)
+	{
+		return min(min(x, y), min(z, w));
+	}
+
+    template <typename T> 
+	inline detail::_xvec4<T> minGTX(const detail::_xvec4<T>& x, const detail::_xvec4<T>& y, const detail::_xvec4<T>& z, const detail::_xvec4<T>& w)
+	{
+		return min(min(x, y), min(z, w));
+	}
+
+	template <typename T> 
+	inline detail::_xvec2<T> maxGTX(const detail::_xvec2<T>& x, const T y, const T z)
+	{
+		return max(x, max(y, z));
+	}
+
+    template <typename T> 
+	inline detail::_xvec3<T> maxGTX(const detail::_xvec3<T>& x, const T y, const T z)
+	{
+		return max(x, max(y, z));
+	}
+
+    template <typename T> 
+	inline detail::_xvec4<T> maxGTX(const detail::_xvec4<T>& x, const T y, const T z)
+	{
+		return max(x, max(y, z));
+	}
+
+    template <typename T> 
+	inline detail::_xvec2<T> maxGTX(const detail::_xvec2<T>& x, const T y, const T z, const T w)
+	{
+		return max(max(x, y), max(z, w));
+	}
+
+    template <typename T> 
+	inline detail::_xvec3<T> maxGTX(const detail::_xvec3<T>& x, const T y, const T z, const T w)
+	{
+		return max(max(x, y), max(z, w));
+	}
+
+    template <typename T> 
+	inline detail::_xvec4<T> maxGTX(const detail::_xvec4<T>& x, const T y, const T z, const T w)
+	{
+		return max(max(x, y), max(z, w));
+	}
+	
+    template <typename T> 
+	inline detail::_xvec2<T> maxGTX(const detail::_xvec2<T>& x, const detail::_xvec2<T>& y, const detail::_xvec2<T>& z)
+	{
+		return max(max(x, y), z);
+	}
+
+    template <typename T> 
+	inline detail::_xvec3<T> maxGTX(const detail::_xvec3<T>& x, const detail::_xvec3<T>& y, const detail::_xvec3<T>& z)
+	{
+		return max(max(x, y), z);
+	}
+
+    template <typename T> 
+	inline detail::_xvec4<T> maxGTX(const detail::_xvec4<T>& x, const detail::_xvec4<T>& y, const detail::_xvec4<T>& z)
+	{
+		return max(max(x, y), z);
+	}
+
+    template <typename T> 
+	inline detail::_xvec2<T> maxGTX(const detail::_xvec2<T>& x, const detail::_xvec2<T>& y, const detail::_xvec2<T>& z, const detail::_xvec2<T>& w)
+	{
+		return max(max(x, y), max(z, w));
+	}
+
+    template <typename T> 
+	inline detail::_xvec3<T> maxGTX(const detail::_xvec3<T>& x, const detail::_xvec3<T>& y, const detail::_xvec3<T>& z, const detail::_xvec3<T>& w)
+	{
+		return max(max(x, y), max(z, w));
+	}
+
+    template <typename T> 
+	inline detail::_xvec4<T> maxGTX(const detail::_xvec4<T>& x, const detail::_xvec4<T>& y, const detail::_xvec4<T>& z, const detail::_xvec4<T>& w)
+	{
+		return max(max(x, y), max(z, w));
+	}
+}

+ 84 - 0
experimental/sse/glm/ext/gtx/fast_exponential.h

@@ -0,0 +1,84 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2008 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2006-01-09
+// Updated : 2006-11-13
+// Licence : This source is under GNU LGPL licence
+// File    : glm/gtx/fast_exponential.h
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Dependency:
+// - GLM core
+// - GLM_GTX_half
+// - GLM_GTX_double
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef __glm_gtx_fast_exponential__
+#define __glm_gtx_fast_exponential__
+
+// Dependency:
+#include "../../glm.h"
+#include "../gtx/half.h"
+#include "../gtx/double.h"
+
+namespace glm
+{
+	template <typename T> T fastPowGTX(const T x, const T y); //!< Faster than the common pow function but less accurate (From GLM_GTX_fast_exponential extension)
+    template <typename T> detail::_xvec2<T> fastPowGTX(const detail::_xvec2<T>& x, const detail::_xvec2<T>& y); //!< Faster than the common pow function but less accurate (From GLM_GTX_fast_exponential extension)
+    template <typename T> detail::_xvec3<T> fastPowGTX(const detail::_xvec3<T>& x, const detail::_xvec3<T>& y); //!< Faster than the common pow function but less accurate (From GLM_GTX_fast_exponential extension)
+    template <typename T> detail::_xvec4<T> fastPowGTX(const detail::_xvec4<T>& x, const detail::_xvec4<T>& y); //!< Faster than the common pow function but less accurate (From GLM_GTX_fast_exponential extension)
+
+    template <typename T> T fastPowGTX(const T x, int y); //!< Faster than the common pow function but less accurate (From GLM_GTX_fast_exponential extension)
+    template <typename T> detail::_xvec2<T> fastPowGTX(const detail::_xvec2<T>& x, const detail::_xvec2<int>& y); //!< Faster than the common pow function but less accurate (From GLM_GTX_fast_exponential extension)
+    template <typename T> detail::_xvec3<T> fastPowGTX(const detail::_xvec3<T>& x, const detail::_xvec3<int>& y); //!< Faster than the common pow function but less accurate (From GLM_GTX_fast_exponential extension)
+    template <typename T> detail::_xvec4<T> fastPowGTX(const detail::_xvec4<T>& x, const detail::_xvec4<int>& y); //!< Faster than the common pow function but less accurate (From GLM_GTX_fast_exponential extension)
+
+    template <typename T> T fastExpGTX(const T x); //!< Faster than the common exp function but less accurate (From GLM_GTX_fast_exponential extension)
+    template <typename T> detail::_xvec2<T> fastExpGTX(const detail::_xvec2<T>& x); //!< Faster than the common exp function but less accurate (From GLM_GTX_fast_exponential extension)
+    template <typename T> detail::_xvec3<T> fastExpGTX(const detail::_xvec3<T>& x); //!< Faster than the common exp function but less accurate (From GLM_GTX_fast_exponential extension)
+    template <typename T> detail::_xvec4<T> fastExpGTX(const detail::_xvec4<T>& x); //!< Faster than the common exp function but less accurate (From GLM_GTX_fast_exponential extension)
+
+    template <typename T> T fastLogGTX(const T x); //!< Faster than the common log function but less accurate (From GLM_GTX_fast_exponential extension)
+    template <typename T> detail::_xvec2<T> fastLogGTX(const detail::_xvec2<T>& x); //!< Faster than the common log function but less accurate (From GLM_GTX_fast_exponential extension)
+    template <typename T> detail::_xvec3<T> fastLogGTX(const detail::_xvec3<T>& x); //!< Faster than the common log function but less accurate (From GLM_GTX_fast_exponential extension)
+    template <typename T> detail::_xvec4<T> fastLogGTX(const detail::_xvec4<T>& x); //!< Faster than the common log function but less accurate (From GLM_GTX_fast_exponential extension)
+
+    template <typename T> T fastExp2GTX(const T x); //!< Faster than the common exp2 function but less accurate (From GLM_GTX_fast_exponential extension)
+    template <typename T> detail::_xvec2<T> fastExp2GTX(const detail::_xvec2<T>& x); //!< Faster than the common exp2 function but less accurate (From GLM_GTX_fast_exponential extension)
+    template <typename T> detail::_xvec3<T> fastExp2GTX(const detail::_xvec3<T>& x); //!< Faster than the common exp2 function but less accurate (From GLM_GTX_fast_exponential extension)
+    template <typename T> detail::_xvec4<T> fastExp2GTX(const detail::_xvec4<T>& x); //!< Faster than the common exp2 function but less accurate (From GLM_GTX_fast_exponential extension)
+
+	template <typename T> T fastLog2GTX(const T x); //!< Faster than the common log2 function but less accurate (From GLM_GTX_fast_exponential extension)
+    template <typename T> detail::_xvec2<T> fastLog2GTX(const detail::_xvec2<T>& x); //!< Faster than the common log2 function but less accurate (From GLM_GTX_fast_exponential extension)
+    template <typename T> detail::_xvec3<T> fastLog2GTX(const detail::_xvec3<T>& x); //!< Faster than the common log2 function but less accurate (From GLM_GTX_fast_exponential extension)
+    template <typename T> detail::_xvec4<T> fastLog2GTX(const detail::_xvec4<T>& x); //!< Faster than the common log2 function but less accurate (From GLM_GTX_fast_exponential extension)
+
+	template <typename T> T fastLnGTX(const T x); //!< Faster than the common ln function but less accurate (From GLM_GTX_fast_exponential extension)
+    template <typename T> detail::_xvec2<T> fastLnGTX(const detail::_xvec2<T>& x); //!< Faster than the common ln function but less accurate (From GLM_GTX_fast_exponential extension)
+    template <typename T> detail::_xvec3<T> fastLnGTX(const detail::_xvec3<T>& x); //!< Faster than the common ln function but less accurate (From GLM_GTX_fast_exponential extension)
+    template <typename T> detail::_xvec4<T> fastLnGTX(const detail::_xvec4<T>& x); //!< Faster than the common ln function but less accurate (From GLM_GTX_fast_exponential extension)
+
+	namespace gtx
+	{
+		//! GLM_GTX_fast_exponential extension: Fast but less accurate implementations of exponential based functions.
+		namespace fast_exponential
+		{
+			template <typename T> inline T fastPow(const T& x, const T& y){return fastPowGTX(x, y);} //!< Faster than the common pow function but less accurate (From GLM_GTX_fast_exponential extension)
+			template <typename T, typename U> inline T fastPow(const T& x, const U& y){return fastPowGTX(x, y);} //!< Faster than the common pow function but less accurate (From GLM_GTX_fast_exponential extension)
+			template <typename T> inline T fastExp(const T& x){return fastExpGTX(x);} //!< Faster than the common exp function but less accurate (From GLM_GTX_fast_exponential extension)
+			template <typename T> inline T fastLog(const T& x){return fastLogGTX(x);} //!< Faster than the common log function but less accurate (From GLM_GTX_fast_exponential extension)
+			template <typename T> inline T fastExp2(const T& x){return fastExp2GTX(x);} //!< Faster than the common exp2 function but less accurate (From GLM_GTX_fast_exponential extension)
+			template <typename T> inline T fastLog2(const T& x){return fastLog2GTX(x);} //!< Faster than the common log2 function but less accurate (From GLM_GTX_fast_exponential extension)
+			template <typename T> inline T fastLn(const T& x){return fastLnGTX(x);} //!< Faster than the common ln function but less accurate (From GLM_GTX_fast_exponential extension)
+		}
+	}
+}
+
+#define GLM_GTX_fast_exponential namespace gtx::fast_exponential
+
+#include "fast_exponential.inl"
+
+#ifdef GLM_GTX_INCLUDED
+namespace glm{using GLM_GTX_fast_exponential;}
+#endif//GLM_GTX_INCLUDED
+
+#endif//__glm_gtx_fast_exponential__

+ 265 - 0
experimental/sse/glm/ext/gtx/fast_exponential.inl

@@ -0,0 +1,265 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2008 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2006-01-09
+// Updated : 2006-01-09
+// Licence : This source is under GNU LGPL licence
+// File    : glm/gtx/fast_exponential.h
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace glm
+{
+    // fastPowGTX:
+	template <typename T>
+    inline T fastPowGTX(const T x, const T y)
+    {
+        return exp(y * log(x));
+    }
+
+    template <typename T>
+    inline detail::_xvec2<T> fastPowGTX(const detail::_xvec2<T>& x, const detail::_xvec2<T>& y)
+    {
+        return detail::_xvec2<T>(
+            fastPowGTX(x.x, y.x),
+            fastPowGTX(x.y, y.y));
+    }
+
+    template <typename T>
+    inline detail::_xvec3<T> fastPowGTX(const detail::_xvec3<T>& x, const detail::_xvec3<T>& y)
+    {
+        return detail::_xvec3<T>(
+            fastPowGTX(x.x, y.x),
+            fastPowGTX(x.y, y.y),
+            fastPowGTX(x.z, y.z));
+    }
+
+    template <typename T>
+    inline detail::_xvec4<T> fastPowGTX(const detail::_xvec4<T>& x, const detail::_xvec4<T>& y)
+    {
+        return detail::_xvec4<T>(
+            fastPowGTX(x.x, y.x),
+            fastPowGTX(x.y, y.y),
+            fastPowGTX(x.z, y.z),
+            fastPowGTX(x.w, y.w));
+    }
+
+	template <typename T>
+	inline T fastPowGTX(const T x, int y)
+    {
+        T f = T(1);
+        for(int i = 0; i < y; ++i)
+            f *= x;
+        return f;
+    }
+
+    template <typename T>
+    inline detail::_xvec2<T> fastPowGTX(const detail::_xvec2<T>& x, const detail::_xvec2<int>& y)
+    {
+        return detail::_xvec2<T>(
+            fastPowGTX(x.x, y.x),
+            fastPowGTX(x.y, y.y));
+    }
+
+    template <typename T>
+    inline detail::_xvec3<T> fastPowGTX(const detail::_xvec3<T>& x, const detail::_xvec3<int>& y)
+    {
+        return detail::_xvec3<T>(
+            fastPowGTX(x.x, y.x),
+            fastPowGTX(x.y, y.y),
+            fastPowGTX(x.z, y.z));
+    }
+
+    template <typename T>
+    inline detail::_xvec4<T> fastPowGTX(const detail::_xvec4<T>& x, const detail::_xvec4<int>& y)
+    {
+        return detail::_xvec4<T>(
+            fastPowGTX(x.x, y.x),
+            fastPowGTX(x.y, y.y),
+            fastPowGTX(x.z, y.z),
+            fastPowGTX(x.w, y.w));
+    }
+
+    // fastExpGTX
+    // Note: This function provides accurate results only for value between -1 and 1, else avoid it.
+	template <typename T>
+    inline T fastExpGTX(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
+    inline float fastExpGTX(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
+    inline float fastExpGTX(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>
+    inline detail::_xvec2<T> fastExpGTX(const detail::_xvec2<T>& x)
+    {
+        return detail::_xvec2<T>(
+            fastExpGTX(x.x),
+            fastExpGTX(x.y));
+    }
+
+    template <typename T>
+    inline detail::_xvec3<T> fastExpGTX(const detail::_xvec3<T>& x)
+    {
+        return detail::_xvec3<T>(
+            fastExpGTX(x.x),
+            fastExpGTX(x.y),
+            fastExpGTX(x.z));
+    }
+
+    template <typename T>
+    inline detail::_xvec4<T> fastExpGTX(const detail::_xvec4<T>& x)
+    {
+        return detail::_xvec4<T>(
+            fastExpGTX(x.x),
+            fastExpGTX(x.y),
+            fastExpGTX(x.z),
+            fastExpGTX(x.w));
+    }
+
+    // fastLogGTX
+	template <typename T>
+    inline T fastLogGTX(const T x)
+    {
+        return std::log(x);
+    }
+
+    /* Slower than the VC7.1 function...
+    inline float fastLogGTX(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>
+    inline detail::_xvec2<T> fastLogGTX(const detail::_xvec2<T>& x)
+    {
+        return detail::_xvec2<T>(
+            fastLnGTX(x.x),
+            fastLnGTX(x.y));
+    }
+
+    template <typename T>
+    inline detail::_xvec3<T> fastLogGTX(const detail::_xvec3<T>& x)
+    {
+        return detail::_xvec3<T>(
+            fastLnGTX(x.x),
+            fastLnGTX(x.y),
+            fastLnGTX(x.z));
+    }
+
+    template <typename T>
+    inline detail::_xvec4<T> fastLogGTX(const detail::_xvec4<T>& x)
+    {
+        return detail::_xvec4<T>(
+            fastLnGTX(x.x),
+            fastLnGTX(x.y),
+            fastLnGTX(x.z),
+            fastLnGTX(x.w));
+    }
+
+    //fastExp2GTX, ln2 = 0.69314718055994530941723212145818f
+	template <typename T>
+    inline T fastExp2GTX(const T x)
+    {
+        return fastExpGTX(0.69314718055994530941723212145818f * x);
+    }
+
+    template <typename T>
+    inline detail::_xvec2<T> fastExp2GTX(const detail::_xvec2<T>& x)
+    {
+        return detail::_xvec2<T>(
+            fastExp2GTX(x.x),
+            fastExp2GTX(x.y));
+    }
+
+    template <typename T>
+    inline detail::_xvec3<T> fastExp2GTX(const detail::_xvec3<T>& x)
+    {
+        return detail::_xvec3<T>(
+            fastExp2GTX(x.x),
+            fastExp2GTX(x.y),
+            fastExp2GTX(x.z));
+    }
+
+    template <typename T>
+    inline detail::_xvec4<T> fastExp2GTX(const detail::_xvec4<T>& x)
+    {
+        return detail::_xvec4<T>(
+            fastExp2GTX(x.x),
+            fastExp2GTX(x.y),
+            fastExp2GTX(x.z),
+            fastExp2GTX(x.w));
+    }
+
+    // fastLog2GTX, ln2 = 0.69314718055994530941723212145818f
+	template <typename T>
+    inline T fastLog2GTX(const T x)
+    {
+        return fastLogGTX(x) / 0.69314718055994530941723212145818f;
+    }
+
+    template <typename T>
+    inline detail::_xvec2<T> fastLog2GTX(const detail::_xvec2<T>& x)
+    {
+        return detail::_xvec2<T>(
+            fastLog2GTX(x.x),
+            fastLog2GTX(x.y));
+    }
+
+    template <typename T>
+    inline detail::_xvec3<T> fastLog2GTX(const detail::_xvec3<T>& x)
+    {
+        return detail::_xvec3<T>(
+            fastLog2GTX(x.x),
+            fastLog2GTX(x.y),
+            fastLog2GTX(x.z));
+    }
+
+    template <typename T>
+    inline detail::_xvec4<T> fastLog2GTX(const detail::_xvec4<T>& x)
+    {
+        return detail::_xvec4<T>(
+            fastLog2GTX(x.x),
+            fastLog2GTX(x.y),
+            fastLog2GTX(x.z),
+            fastLog2GTX(x.w));
+    }
+}

+ 72 - 0
experimental/sse/glm/ext/gtx/fast_square_root.h

@@ -0,0 +1,72 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2008 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2006-01-04
+// Updated : 2006-11-13
+// Licence : This source is under GNU LGPL licence
+// File    : glm/gtx/fast_square_root.h
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Dependency:
+// - GLM core
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Note:
+// - Sqrt optimisation based on Newton's method, 
+// www.gamedev.net/community/forums/topic.asp?topic id=139956
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef __glm_gtx_fast_square_root__
+#define __glm_gtx_fast_square_root__
+
+// Dependency:
+#include "../../glm.h"
+
+namespace glm
+{
+    template <typename T> T fastSqrtGTX(const T x);										//!< Faster than the common sqrt function but less accurate (From GLM_GTX_fast_square_root extension)
+    template <typename T> detail::_xvec2<T> fastSqrtGTX(const detail::_xvec2<T>& x);	//!< Faster than the common sqrt function but less accurate (From GLM_GTX_fast_square_root extension)
+    template <typename T> detail::_xvec3<T> fastSqrtGTX(const detail::_xvec3<T>& x);	//!< Faster than the common sqrt function but less accurate (From GLM_GTX_fast_square_root extension)
+    template <typename T> detail::_xvec4<T> fastSqrtGTX(const detail::_xvec4<T>& x);	//!< Faster than the common sqrt function but less accurate (From GLM_GTX_fast_square_root extension)
+
+    template <typename T> T fastInverseSqrtGTX(const T x);										//!< Faster than the common inversesqrt function but less accurate (From GLM_GTX_fast_square_root extension)
+    template <typename T> detail::_xvec2<T> fastInverseSqrtGTX(const detail::_xvec2<T>& x);		//!< Faster than the common inversesqrt function but less accurate (From GLM_GTX_fast_square_root extension)
+    template <typename T> detail::_xvec3<T> fastInverseSqrtGTX(const detail::_xvec3<T>& x);		//!< Faster than the common inversesqrt function but less accurate (From GLM_GTX_fast_square_root extension)
+    template <typename T> detail::_xvec4<T> fastInverseSqrtGTX(const detail::_xvec4<T>& x);		//!< Faster than the common inversesqrt function but less accurate (From GLM_GTX_fast_square_root extension)
+
+    template <typename T> T fastLengthGTX(const T x);						//!< Faster than the common length function but less accurate (From GLM_GTX_fast_square_root extension)
+    template <typename T> T fastLengthGTX(const detail::_xvec2<T>& x);		//!< Faster than the common length function but less accurate (From GLM_GTX_fast_square_root extension)
+	template <typename T> T fastLengthGTX(const detail::_xvec3<T>& x);		//!< Faster than the common length function but less accurate (From GLM_GTX_fast_square_root extension)
+    template <typename T> T fastLengthGTX(const detail::_xvec4<T>& x);		//!< Faster than the common length function but less accurate (From GLM_GTX_fast_square_root extension)
+
+    template <typename T> T fastDistanceGTX(const T x, const T y);										//!< Faster than the common distance function but less accurate (From GLM_GTX_fast_square_root extension)
+    template <typename T> T fastDistanceGTX(const detail::_xvec2<T>& x, const detail::_xvec2<T>& y);	//!< Faster than the common distance function but less accurate (From GLM_GTX_fast_square_root extension)
+    template <typename T> T fastDistanceGTX(const detail::_xvec3<T>& x, const detail::_xvec3<T>& y);	//!< Faster than the common distance function but less accurate (From GLM_GTX_fast_square_root extension)
+    template <typename T> T fastDistanceGTX(const detail::_xvec4<T>& x, const detail::_xvec4<T>& y);	//!< Faster than the common distance function but less accurate (From GLM_GTX_fast_square_root extension)
+
+	template <typename T> T fastNormalizeGTX(const T x);												//!< Faster than the common normalize function but less accurate (From GLM_GTX_fast_square_root extension)
+	template <typename T> detail::_xvec2<T> fastNormalizeGTX(const detail::_xvec2<T>& x);				//!< Faster than the common normalize function but less accurate (From GLM_GTX_fast_square_root extension)
+	template <typename T> detail::_xvec3<T> fastNormalizeGTX(const detail::_xvec3<T>& x);				//!< Faster than the common normalize function but less accurate (From GLM_GTX_fast_square_root extension)
+	template <typename T> detail::_xvec4<T> fastNormalizeGTX(const detail::_xvec4<T>& x);				//!< Faster than the common normalize function but less accurate (From GLM_GTX_fast_square_root extension)
+
+	namespace gtx
+	{
+		//! GLM_GTX_fast_square_root extension: Fast but less accurate implementations of square root based functions.
+		namespace fast_square_root
+		{
+			template <typename T> inline T fastSqrt(const T& x){return fastSqrtGTX(x);}								//!< Faster than the common sqrt function but less accurate (From GLM_GTX_fast_square_root extension)
+			template <typename T> inline T fastInverseSqrt(const T& x){return fastInverseSqrtGTX(x);}				//!< Faster than the common inversesqrt function but less accurate (From GLM_GTX_fast_square_root extension)
+			template <typename T> inline T fastLength(const T& x){return fastLengthGTX(x);}							//!< Faster than the common length function but less accurate (From GLM_GTX_fast_square_root extension)
+			template <typename T> inline T fastDistance(const T& x, const T& y){return fastDistanceGTX(x, y);}		//!< Faster than the common distance function but less accurate (From GLM_GTX_fast_square_root extension)
+			template <typename T> inline T fastNormalize(const T& x){return fastNormalizeGTX(x);}					//!< Faster than the common normalize function but less accurate (From GLM_GTX_fast_square_root extension)
+		}
+	}	
+}
+
+#define GLM_GTX_fast_square_root namespace gtx::fast_square_root
+
+#include "fast_square_root.inl"
+
+#ifdef GLM_GTX_INCLUDED
+namespace glm{using GLM_GTX_fast_square_root;}
+#endif//GLM_GTX_INCLUDED
+
+#endif//__glm_gtx_fast_square_root__

+ 165 - 0
experimental/sse/glm/ext/gtx/fast_square_root.inl

@@ -0,0 +1,165 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2008 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2006-01-04
+// Updated : 2006-12-06
+// Licence : This source is under GNU LGPL licence
+// File    : glm/gtx/fast_square_root.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace glm
+{
+    // fastSqrtGTX
+	template <typename T>
+    inline T fastSqrtGTX(const T x)
+    {
+        return 1.0f / fastInverseSqrtGTX(x);
+    }
+
+	template <typename T>
+    inline detail::_xvec2<T> fastSqrtGTX(const detail::_xvec2<T>& x)
+    {
+        return detail::_xvec2<T>(
+            fastSqrtGTX(x.x), 
+            fastSqrtGTX(x.y));
+    }
+
+	template <typename T>
+    inline detail::_xvec3<T> fastSqrtGTX(const detail::_xvec3<T>& x)
+    {
+        return detail::_xvec3<T>(
+            fastSqrtGTX(x.x), 
+            fastSqrtGTX(x.y), 
+            fastSqrtGTX(x.z));
+    }
+
+	template <typename T>
+    inline detail::_xvec4<T> fastSqrtGTX(const detail::_xvec4<T>& x)
+    {
+        return detail::_xvec4<T>(
+            fastSqrtGTX(x.x), 
+            fastSqrtGTX(x.y), 
+            fastSqrtGTX(x.z), 
+            fastSqrtGTX(x.w));
+    }
+
+    // fastInversesqrtGTX
+	template <typename T>
+    inline T fastInverseSqrtGTX(const T x)
+    {
+        float xhalf = 0.5f * x;
+        int i = *(int*)&x;
+        i = 0x5f375a86 - (i >> 1);
+        x = *(float*)&i;
+        x = x * (1.5f - xhalf * x * x);
+        return T(x);
+    }
+
+	template <typename T>
+    inline detail::_xvec2<T> fastInverseSqrtGTX(const detail::_xvec2<T>& x)
+    {
+        return detail::_xvec2<T>(
+            fastInverseSqrtGTX(x.x), 
+            fastInverseSqrtGTX(x.y));
+    }
+
+	template <typename T>
+    inline detail::_xvec3<T> fastInverseSqrtGTX(const detail::_xvec3<T>& x)
+    {
+        return detail::_xvec3<T>(
+            fastInverseSqrtGTX(x.x), 
+            fastInverseSqrtGTX(x.y), 
+            fastInverseSqrtGTX(x.z));
+    }
+
+	template <typename T>
+    inline detail::_xvec4<T> fastInverseSqrtGTX(const detail::_xvec4<T>& x)
+    {
+        return detail::_xvec4<T>(
+            fastInverseSqrtGTX(x.x), 
+            fastInverseSqrtGTX(x.y), 
+            fastInverseSqrtGTX(x.z), 
+            fastInverseSqrtGTX(x.w));
+    }
+
+    // fastLengthGTX
+	template <typename T>
+    inline T fastLengthGTX(const T x)
+    {
+        return abs(x);
+    }
+
+	template <typename T>
+    inline T fastLengthGTX(const detail::_xvec2<T>& x)
+    {
+        T sqr = x.x * x.x + x.y * x.y;
+        return fastSqrtGTX(sqr);
+    }
+
+	template <typename T>
+    inline T fastLengthGTX(const detail::_xvec3<T>& x)
+    {
+        T sqr = x.x * x.x + x.y * x.y + x.z * x.z;
+        return fastSqrtGTX(sqr);
+    }
+
+	template <typename T>
+    inline T fastLengthGTX(const detail::_xvec4<T>& x)
+    {
+        T sqr = x.x * x.x + x.y * x.y + x.z * x.z + x.w * x.w;
+        return fastSqrtGTX(sqr);
+    }
+
+    // fastDistanceGTX
+	template <typename T>
+    inline T fastDistanceGTX(const T x, const T y)
+    {
+        return fastLengthGTX(y - x);
+    }
+
+	template <typename T>
+    inline T fastDistanceGTX(const detail::_xvec2<T>& x, const detail::_xvec2<T>& y)
+    {
+        return fastLengthGTX(y - x);
+    }
+
+	template <typename T>
+    inline T fastDistanceGTX(const detail::_xvec3<T>& x, const detail::_xvec3<T>& y)
+    {
+        return fastLengthGTX(y - x);
+    }
+
+	template <typename T>
+    inline T fastDistanceGTX(const detail::_xvec4<T>& x, const detail::_xvec4<T>& y)
+    {
+        return fastLengthGTX(y - x);
+    }
+
+    // fastNormalizeGTX
+	template <typename T>
+    inline T fastNormalizeGTX(const T x)
+    {
+        return x > 0.0f ? 1.0f : -1.0f;
+    }
+
+	template <typename T>
+    inline detail::_xvec2<T> fastNormalizeGTX(const detail::_xvec2<T>& x)
+    {
+        T sqr = x.x * x.x + x.y * x.y;
+	    return x * fastInverseSqrtGTX(sqr);
+    }
+
+	template <typename T>
+    inline detail::_xvec3<T> fastNormalizeGTX(const detail::_xvec3<T>& x)
+    {
+        T sqr = x.x * x.x + x.y * x.y + x.z * x.z;
+	    return x * fastInverseSqrtGTX(sqr);
+    }
+
+	template <typename T>
+    inline detail::_xvec4<T> fastNormalizeGTX(const detail::_xvec4<T>& x)
+    {
+        T sqr = x.x * x.x + x.y * x.y + x.z * x.z + x.w * x.w;
+	    return x * fastInverseSqrtGTX(sqr);
+    }
+}

+ 80 - 0
experimental/sse/glm/ext/gtx/fast_trigonometry.h

@@ -0,0 +1,80 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2008 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2006-01-08
+// Updated : 2006-11-13
+// Licence : This source is under GNU LGPL licence
+// File    : glm/gtx/fast_trigonometry.h
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Dependency:
+// - GLM core
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef __glm_gtx_fast_trigonometry__
+#define __glm_gtx_fast_trigonometry__
+
+// Dependency:
+#include "../../glm.h"
+
+namespace glm
+{
+    template <typename T> T fastSinGTX(const T angle);										//!< Faster than the common sin function but less accurate. Defined between -2pi and 2pi. (From GLM_GTX_fast_trigonometry extension)
+    template <typename T> detail::_xvec2<T> fastSinGTX(const detail::_xvec2<T>& angle);		//!< Faster than the common sin function but less accurate. Defined between -2pi and 2pi. (From GLM_GTX_fast_trigonometry extension)
+    template <typename T> detail::_xvec3<T> fastSinGTX(const detail::_xvec3<T>& angle);		//!< Faster than the common sin function but less accurate. Defined between -2pi and 2pi. (From GLM_GTX_fast_trigonometry extension)
+    template <typename T> detail::_xvec4<T> fastSinGTX(const detail::_xvec4<T>& angle);		//!< Faster than the common sin function but less accurate. Defined between -2pi and 2pi. (From GLM_GTX_fast_trigonometry extension)
+
+    template <typename T> T fastCosGTX(const T angle);										//!< Faster than the common cos function but less accurate. Defined between -2pi and 2pi. (From GLM_GTX_fast_trigonometry extension)
+    template <typename T> detail::_xvec2<T> fastCosGTX(const detail::_xvec2<T>& angle);		//!< Faster than the common cos function but less accurate. Defined between -2pi and 2pi. (From GLM_GTX_fast_trigonometry extension)
+    template <typename T> detail::_xvec3<T> fastCosGTX(const detail::_xvec3<T>& angle);		//!< Faster than the common cos function but less accurate. Defined between -2pi and 2pi. (From GLM_GTX_fast_trigonometry extension)
+    template <typename T> detail::_xvec4<T> fastCosGTX(const detail::_xvec4<T>& angle);		//!< Faster than the common cos function but less accurate. Defined between -2pi and 2pi. (From GLM_GTX_fast_trigonometry extension)
+
+    template <typename T> T fastTanGTX(const T angle);										//!< Faster than the common tan function but less accurate. Defined between -2pi and 2pi. (From GLM_GTX_fast_trigonometry extension)
+    template <typename T> detail::_xvec2<T> fastTanGTX(const detail::_xvec2<T>& angle);		//!< Faster than the common tan function but less accurate. Defined between -2pi and 2pi. (From GLM_GTX_fast_trigonometry extension)
+    template <typename T> detail::_xvec3<T> fastTanGTX(const detail::_xvec3<T>& angle);		//!< Faster than the common tan function but less accurate. Defined between -2pi and 2pi. (From GLM_GTX_fast_trigonometry extension)
+    template <typename T> detail::_xvec4<T> fastTanGTX(const detail::_xvec4<T>& angle);		//!< Faster than the common tan function but less accurate. Defined between -2pi and 2pi. (From GLM_GTX_fast_trigonometry extension)
+
+    template <typename T> T fastAsinGTX(const T x);											//!< Faster than the common asin function but less accurate. Defined between -2pi and 2pi. (From GLM_GTX_fast_trigonometry extension)
+    template <typename T> detail::_xvec2<T> fastAsinGTX(const detail::_xvec2<T>& x);		//!< Faster than the common asin function but less accurate. Defined between -2pi and 2pi. (From GLM_GTX_fast_trigonometry extension)
+    template <typename T> detail::_xvec3<T> fastAsinGTX(const detail::_xvec3<T>& x);		//!< Faster than the common asin function but less accurate. Defined between -2pi and 2pi. (From GLM_GTX_fast_trigonometry extension)
+    template <typename T> detail::_xvec4<T> fastAsinGTX(const detail::_xvec4<T>& x);		//!< Faster than the common asin function but less accurate. Defined between -2pi and 2pi. (From GLM_GTX_fast_trigonometry extension)
+
+    template <typename T> T fastAcosGTX(const T x);											//!< Faster than the common acos function but less accurate. Defined between -2pi and 2pi. (From GLM_GTX_fast_trigonometry extension)
+    template <typename T> detail::_xvec2<T> fastAcosGTX(const detail::_xvec2<T>& x);		//!< Faster than the common acos function but less accurate. Defined between -2pi and 2pi. (From GLM_GTX_fast_trigonometry extension)
+    template <typename T> detail::_xvec3<T> fastAcosGTX(const detail::_xvec3<T>& x);		//!< Faster than the common acos function but less accurate. Defined between -2pi and 2pi. (From GLM_GTX_fast_trigonometry extension)
+    template <typename T> detail::_xvec4<T> fastAcosGTX(const detail::_xvec4<T>& x);		//!< Faster than the common acos function but less accurate. Defined between -2pi and 2pi. (From GLM_GTX_fast_trigonometry extension)
+
+    template <typename T> T fastAtanGTX(const T y, const T x);														//!< Faster than the common atan function but less accurate. Defined between -2pi and 2pi. (From GLM_GTX_fast_trigonometry extension)
+    template <typename T> detail::_xvec2<T> fastAtanGTX(const detail::_xvec2<T>& y, const detail::_xvec2<T>& x);	//!< Faster than the common atan function but less accurate. Defined between -2pi and 2pi. (From GLM_GTX_fast_trigonometry extension)
+    template <typename T> detail::_xvec3<T> fastAtanGTX(const detail::_xvec3<T>& y, const detail::_xvec3<T>& x);	//!< Faster than the common atan function but less accurate. Defined between -2pi and 2pi. (From GLM_GTX_fast_trigonometry extension)
+    template <typename T> detail::_xvec4<T> fastAtanGTX(const detail::_xvec4<T>& y, const detail::_xvec4<T>& x);	//!< Faster than the common atan function but less accurate. Defined between -2pi and 2pi. (From GLM_GTX_fast_trigonometry extension)
+
+    template <typename T> T fastAtanGTX(const T y_over_x);									//!< Faster than the common atan function but less accurate. Defined between -2pi and 2pi. (From GLM_GTX_fast_trigonometry extension)
+    template <typename T> detail::_xvec2<T> fastAtanGTX(const detail::_xvec2<T>& y_over_x); //!< Faster than the common atan function but less accurate. Defined between -2pi and 2pi. (From GLM_GTX_fast_trigonometry extension)
+    template <typename T> detail::_xvec3<T> fastAtanGTX(const detail::_xvec3<T>& y_over_x); //!< Faster than the common atan function but less accurate. Defined between -2pi and 2pi. (From GLM_GTX_fast_trigonometry extension)
+    template <typename T> detail::_xvec4<T> fastAtanGTX(const detail::_xvec4<T>& y_over_x); //!< Faster than the common atan function but less accurate. Defined between -2pi and 2pi. (From GLM_GTX_fast_trigonometry extension)
+
+    namespace gtx
+    {
+		//! GLM_GTX_fast_trigonometry extension: Fast but less accurate implementations of trigonometric functions.
+        namespace fast_trigonometry
+        {
+            template <typename T> inline T fastSin(const T& angle){return fastSinGTX(angle);}			//!< Faster than the common sin function but less accurate. Defined between -2pi and 2pi. (From GLM_GTX_fast_trigonometry extension)
+            template <typename T> inline T fastCos(const T& angle){return fastCosGTX(angle);}			//!< Faster than the common cos function but less accurate. Defined between -2pi and 2pi. (From GLM_GTX_fast_trigonometry extension)
+            template <typename T> inline T fastTan(const T& angle){return fastTanGTX(angle);}			//!< Faster than the common tan function but less accurate. Defined between -2pi and 2pi. (From GLM_GTX_fast_trigonometry extension)
+            template <typename T> inline T fastAsin(const T& angle){return fastAsinGTX(angle);}			//!< Faster than the common asin function but less accurate. Defined between -2pi and 2pi. (From GLM_GTX_fast_trigonometry extension)
+            template <typename T> inline T fastAcos(const T& angle){return fastAcosGTX(angle);}			//!< Faster than the common acos function but less accurate. Defined between -2pi and 2pi. (From GLM_GTX_fast_trigonometry extension)
+            template <typename T> inline T fastAtan(const T& y, const T& x){return fastAtanGTX(y, x);}	//!< Faster than the common atan function but less accurate. Defined between -2pi and 2pi. (From GLM_GTX_fast_trigonometry extension)
+            template <typename T> inline T fastAtan(const T& angle){return fastAtanGTX(angle);}			//!< Faster than the common atan function but less accurate. Defined between -2pi and 2pi. (From GLM_GTX_fast_trigonometry extension)
+        }
+    }
+}
+
+#define GLM_GTX_fast_trigonometry namespace gtx::fast_trigonometry
+
+#include "fast_trigonometry.inl"
+
+#ifdef GLM_GTX_INCLUDED
+namespace glm{using GLM_GTX_fast_trigonometry;}
+#endif//GLM_GTX_INCLUDED
+
+#endif//__glm_gtx_fast_trigonometry__

+ 243 - 0
experimental/sse/glm/ext/gtx/fast_trigonometry.inl

@@ -0,0 +1,243 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2008 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2006-01-08
+// Updated : 2006-01-08
+// Licence : This source is under GNU LGPL licence
+// File    : glm/gtx/fast_trigonometry.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace glm
+{
+    // sin
+    template <typename T> 
+    inline T fastSinGTX(const T 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> 
+    inline detail::_xvec2<T> fastSinGTX(const detail::_xvec2<T>& x)
+    {
+        return detail::_xvec2<T>(
+            fastSinGTX(x.x),
+            fastSinGTX(x.y));
+    }
+
+    template <typename T> 
+    inline detail::_xvec3<T> fastSinGTX(const detail::_xvec3<T>& x)
+    {
+        return detail::_xvec3<T>(
+            fastSinGTX(x.x),
+            fastSinGTX(x.y),
+            fastSinGTX(x.z));
+    }
+
+    template <typename T> 
+    inline detail::_xvec4<T> fastSinGTX(const detail::_xvec4<T>& x)
+    {
+        return detail::_xvec4<T>(
+            fastSinGTX(x.x),
+            fastSinGTX(x.y),
+            fastSinGTX(x.z),
+            fastSinGTX(x.w));
+    }
+
+    // cos
+    template <typename T> 
+    inline T fastCosGTX(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));
+    }
+
+    template <typename T> 
+    inline detail::_xvec2<T> fastCosGTX(const detail::_xvec2<T>& x)
+    {
+        return detail::_xvec2<T>(
+            fastCosGTX(x.x),
+            fastCosGTX(x.y));
+    }
+
+    template <typename T> 
+    inline detail::_xvec3<T> fastCosGTX(const detail::_xvec3<T>& x)
+    {
+        return detail::_xvec3<T>(
+            fastCosGTX(x.x),
+            fastCosGTX(x.y),
+            fastCosGTX(x.z));
+    }
+
+    template <typename T> 
+    inline detail::_xvec4<T> fastCosGTX(const detail::_xvec4<T>& x)
+    {
+        return detail::_xvec4<T>(
+            fastCosGTX(x.x),
+            fastCosGTX(x.y),
+            fastCosGTX(x.z),
+            fastCosGTX(x.w));
+    }
+
+    // tan
+    template <typename T> 
+    inline T fastTanGTX(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));
+    }
+
+    template <typename T> 
+    inline detail::_xvec2<T> fastTanGTX(const detail::_xvec2<T>& x)
+    {
+        return detail::_xvec2<T>(
+            fastTanGTX(x.x),
+            fastTanGTX(x.y));
+    }
+
+    template <typename T> 
+    inline detail::_xvec3<T> fastTanGTX(const detail::_xvec3<T>& x)
+    {
+        return detail::_xvec3<T>(
+            fastTanGTX(x.x),
+            fastTanGTX(x.y),
+            fastTanGTX(x.z));
+    }
+
+    template <typename T> 
+    inline detail::_xvec4<T> fastTanGTX(const detail::_xvec4<T>& x)
+    {
+        return detail::_xvec4<T>(
+            fastTanGTX(x.x),
+            fastTanGTX(x.y),
+            fastTanGTX(x.z),
+            fastTanGTX(x.w));
+    }
+
+    // asin
+    template <typename T> 
+    inline T fastAsinGTX(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::_xvec2<T> fastAsinGTX(const detail::_xvec2<T>& x)
+    {
+        return detail::_xvec2<T>(
+            fastAsinGTX(x.x),
+            fastAsinGTX(x.y));
+    }
+
+    template <typename T> detail::_xvec3<T> fastAsinGTX(const detail::_xvec3<T>& x)
+    {
+        return detail::_xvec3<T>(
+            fastAsinGTX(x.x),
+            fastAsinGTX(x.y),
+            fastAsinGTX(x.z));
+    }
+
+    template <typename T> detail::_xvec4<T> fastAsinGTX(const detail::_xvec4<T>& x)
+    {
+        return detail::_xvec4<T>(
+            fastAsinGTX(x.x),
+            fastAsinGTX(x.y),
+            fastAsinGTX(x.z),
+            fastAsinGTX(x.w));
+    }
+
+    // acos
+    template <typename T> 
+    inline T fastAcosGTX(const T x)
+    {
+        return T(1.5707963267948966192313216916398) - fastAsinGTX(x); //(PI / 2)
+    }
+
+    template <typename T> detail::_xvec2<T> fastAcosGTX(const detail::_xvec2<T>& x)
+    {
+        return detail::_xvec2<T>(
+            fastAcosGTX(x.x),
+            fastAcosGTX(x.y));
+    }
+
+    template <typename T> detail::_xvec3<T> fastAcosGTX(const detail::_xvec3<T>& x)
+    {
+        return detail::_xvec3<T>(
+            fastAcosGTX(x.x),
+            fastAcosGTX(x.y),
+            fastAcosGTX(x.z));
+    }
+
+    template <typename T> detail::_xvec4<T> fastAcosGTX(const detail::_xvec4<T>& x)
+    {
+        return detail::_xvec4<T>(
+            fastAcosGTX(x.x),
+            fastAcosGTX(x.y),
+            fastAcosGTX(x.z),
+            fastAcosGTX(x.w));
+    }
+
+    // atan
+    template <typename T> 
+    inline T fastAtanGTX(const T y, const T x)
+    {
+        T sgn = sign(y) * sign(x);
+        return abs(fastAtanGTX(y / x)) * sgn;
+    }
+
+    template <typename T> 
+    inline detail::_xvec2<T> fastAtanGTX(const detail::_xvec2<T>& y, const detail::_xvec2<T>& x)
+    {
+        return detail::_xvec2<T>(
+            fastAtanGTX(y.x, x.x),
+            fastAtanGTX(y.y, x.y));
+    }
+
+    template <typename T> 
+    inline detail::_xvec3<T> fastAtanGTX(const detail::_xvec3<T>& y, const detail::_xvec3<T>& x)
+    {
+        return detail::_xvec3<T>(
+            fastAtanGTX(y.x, x.x),
+            fastAtanGTX(y.y, x.y),
+            fastAtanGTX(y.z, x.z));
+    }
+
+    template <typename T> 
+    inline detail::_xvec4<T> fastAtanGTX(const detail::_xvec4<T>& y, const detail::_xvec4<T>& x)
+    {
+        return detail::_xvec4<T>(
+            fastAtanGTX(y.x, x.x),
+            fastAtanGTX(y.y, x.y),
+            fastAtanGTX(y.z, x.z),
+            fastAtanGTX(y.w, x.w));
+    }
+
+    template <typename T> 
+    inline T fastAtanGTX(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> 
+    inline detail::_xvec2<T> fastAtanGTX(const detail::_xvec2<T>& x)
+    {
+        return detail::_xvec2<T>(
+            fastAtanGTX(x.x),
+            fastAtanGTX(x.y));
+    }
+
+    template <typename T> 
+    inline detail::_xvec3<T> fastAtanGTX(const detail::_xvec3<T>& x)
+    {
+        return detail::_xvec3<T>(
+            fastAtanGTX(x.x),
+            fastAtanGTX(x.y),
+            fastAtanGTX(x.z));
+    }
+
+    template <typename T> 
+    inline detail::_xvec4<T> fastAtanGTX(const detail::_xvec4<T>& x)
+    {
+        return detail::_xvec4<T>(
+            fastAtanGTX(x.x),
+            fastAtanGTX(x.y),
+            fastAtanGTX(x.z),
+            fastAtanGTX(x.w));
+    }
+}

+ 47 - 0
experimental/sse/glm/ext/gtx/flexible_mix.h

@@ -0,0 +1,47 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2008 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2007-09-21
+// Updated : 2007-09-21
+// Licence : This source is under GNU LGPL licence
+// File    : glm/gtx/flexible_mix.h
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Dependency:
+// - GLM core
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef __glm_gtx_flexible_mix__
+#define __glm_gtx_flexible_mix__
+
+// Dependency:
+#include "../../glm.h"
+
+namespace glm
+{
+    template <typename T, typename U> T mixGTX(T x, T y, U a);																							//!< \brief Returns the component-wise result of x * (1.0 - a) + y * a, i.e., the linear blend of x and y using a values. The value for a is not restricted to the range [0, 1]. (From GLM_GTX_flexible_mix extension)
+    template <typename T, typename U> detail::_xvec2<T> mixGTX(const detail::_xvec2<T>& x, const detail::_xvec2<T>& y, U a);							//!< \brief Returns the component-wise result of x * (1.0 - a) + y * a, i.e., the linear blend of x and y using a values. The value for a is not restricted to the range [0, 1]. (From GLM_GTX_flexible_mix extension)
+    template <typename T, typename U> detail::_xvec3<T> mixGTX(const detail::_xvec3<T>& x, const detail::_xvec3<T>& y, U a);							//!< \brief Returns the component-wise result of x * (1.0 - a) + y * a, i.e., the linear blend of x and y using a values. The value for a is not restricted to the range [0, 1]. (From GLM_GTX_flexible_mix extension)
+    template <typename T, typename U> detail::_xvec4<T> mixGTX(const detail::_xvec4<T>& x, const detail::_xvec4<T>& y, U a);							//!< \brief Returns the component-wise result of x * (1.0 - a) + y * a, i.e., the linear blend of x and y using a values. The value for a is not restricted to the range [0, 1]. (From GLM_GTX_flexible_mix extension)
+    template <typename T, typename U> detail::_xvec2<T> mixGTX(const detail::_xvec2<T>& x, const detail::_xvec2<T>& y, const detail::_xvec2<U>& a);		//!< \brief Returns the component-wise result of x * (1.0 - a) + y * a, i.e., the linear blend of x and y using a values. The value for a is not restricted to the range [0, 1]. (From GLM_GTX_flexible_mix extension)
+    template <typename T, typename U> detail::_xvec3<T> mixGTX(const detail::_xvec3<T>& x, const detail::_xvec3<T>& y, const detail::_xvec3<U>& a);		//!< \brief Returns the component-wise result of x * (1.0 - a) + y * a, i.e., the linear blend of x and y using a values. The value for a is not restricted to the range [0, 1]. (From GLM_GTX_flexible_mix extension)
+    template <typename T, typename U> detail::_xvec4<T> mixGTX(const detail::_xvec4<T>& x, const detail::_xvec4<T>& y, const detail::_xvec4<U>& a);		//!< \brief Returns the component-wise result of x * (1.0 - a) + y * a, i.e., the linear blend of x and y using a values. The value for a is not restricted to the range [0, 1]. (From GLM_GTX_flexible_mix extension)
+
+    namespace gtx
+    {
+		//! GLM_GTX_flexible_mix extension: More flexible functions for linear interpolations
+        namespace flexible_mix
+        {
+            template <typename T, typename U> T mix(T x, T y, U a){return mixGTX(x, y, a);}																//!< \brief Returns the component-wise result of x * (1.0 - a) + y * a, i.e., the linear blend of x and y using a values. The value for a is not restricted to the range [0, 1]. (From GLM_GTX_flexible_mix extension)
+        }
+    }
+}
+
+#define GLM_GTX_flexible_mix namespace gtx::flexible_mix
+
+#include "flexible_mix.inl"
+
+#ifdef GLM_GTX_INCLUDED
+namespace glm{using GLM_GTX_flexible_mix;}
+#endif//GLM_GTX_INCLUDED
+
+#endif//__glm_gtx_flexible_mix__

+ 58 - 0
experimental/sse/glm/ext/gtx/flexible_mix.inl

@@ -0,0 +1,58 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2008 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2007-09-21
+// Updated : 2007-09-21
+// Licence : This source is under GNU LGPL licence
+// File    : glm/gtx/flexible_mix.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace glm
+{
+    // mix
+    template <typename T, typename U>
+    inline T mixGTX(T x, T y, T a)
+    {
+        return T(x * (U(1) - a) + y * a);
+    }
+
+    template <typename T, typename U>
+    inline detail::_xvec2<T> mixGTX(const detail::_xvec2<T>& x, const detail::_xvec2<T>& y, U a)
+    {
+		return detail::_xvec2<T>(detail::_xvec2<U>(x) * (U(1) - a) + detail::_xvec2<U>(y) * a);
+        //return x * (U(1) - a) + y * a;
+    }
+
+    template <typename T, typename U>
+    inline detail::_xvec3<T> mixGTX(const detail::_xvec3<T>& x, const detail::_xvec3<T>& y, U a)
+    {
+		return detail::_xvec3<T>(detail::_xvec3<U>(x) * (U(1) - a) + detail::_xvec3<U>(y) * a);
+        //return x * (U(1) - a) + y * a;
+		//return mix(x, y, _xvec3<U>(a));
+    }
+
+    template <typename T, typename U>
+    inline detail::_xvec4<T> mixGTX(const detail::_xvec4<T>& x, const detail::_xvec4<T>& y, U a)
+    {
+		return detail::_xvec4<T>(detail::_xvec4<U>(x) * (U(1) - a) + detail::_xvec4<U>(y) * a);
+        //return x * (U(1) - a) + y * a;
+    }
+
+    template <typename T, typename U>
+    inline detail::_xvec2<T> mixGTX(const detail::_xvec2<T>& x, const detail::_xvec2<T>& y, const detail::_xvec2<U>& a)
+    {
+		return detail::_xvec2<T>(detail::_xvec2<U>(x) * (U(1) - a) + detail::_xvec2<U>(y) * a);
+    }
+
+    template <typename T, typename U>
+    inline detail::_xvec3<T> mixGTX(const detail::_xvec3<T>& x, const detail::_xvec3<T>& y, const detail::_xvec3<U>& a)
+    {
+        return detail::_xvec3<T>(detail::_xvec3<U>(x) * (U(1) - a) + detail::_xvec3<U>(y) * a);
+    }
+
+    template <typename T, typename U>
+    inline detail::_xvec4<T> mixGTX(const detail::_xvec4<T>& x, const detail::_xvec4<T>& y, const detail::_xvec4<U>& a)
+    {
+		return detail::_xvec4<T>(detail::_xvec4<U>(x) * (U(1) - a) + detail::_xvec4<U>(y) * a);
+    }
+}

+ 169 - 0
experimental/sse/glm/ext/gtx/gpu_shader4.h

@@ -0,0 +1,169 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2008 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2006-11-13
+// Updated : 2007-08-20
+// Licence : This source is under GNU LGPL licence
+// File    : glm/gtx/gpu_shader4.h
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Dependency:
+// - GLM core
+// - GLM_GTX_round
+// - GLM_GTX_half
+// - GLM_GTX_double
+// - GLM_GTX_integer
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// ToDo:
+// - Defined all the extensions
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Comment:
+// This extension is based on GL_EXT_gpu_shader4 extension
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef __glm_gtx_gpu_shader4__
+#define __glm_gtx_gpu_shader4__
+
+// Dependency:
+#include "../../glm.h"
+#include "../../ext/gtx/round.h"
+#include "../../ext/gtx/half.h"
+
+namespace glm
+{
+    __halfGTX truncateGTX(__halfGTX x);										//!< \brief Computes the truncate value of x (from GLM_GTX_gpu_shader4 extension) 
+    float truncateGTX(float x);												//!< \brief Computes the truncate value of x (from GLM_GTX_gpu_shader4 extension)
+    double truncateGTX(double x);											//!< \brief Computes the truncate value of x (from GLM_GTX_gpu_shader4 extension)
+    template <typename genType> genType truncateGTX(const genType& x);		//!< \brief Computes the component-wise truncate value of x (from GLM_GTX_gpu_shader4 extension)
+
+    unsigned int powGTX(unsigned int x, unsigned int y);					//!< \brief Returns x raised to the y power. (from GLM_GTX_gpu_shader4 extension)
+    unsigned int sqrtGTX(unsigned int x);									//!< \brief Returns the positive square root of x. (from GLM_GTX_gpu_shader4 extension)
+
+	typedef detail::_xvec2<unsigned int>		__uvec2GTX;					//!< \brief Vector of 2 half-precision floating-point numbers. (From GLM_GTX_gpu_shader4 extension)
+    typedef detail::_xvec3<unsigned int>		__uvec3GTX;					//!< \brief Vector of 3 half-precision floating-point numbers. (From GLM_GTX_gpu_shader4 extension)
+    typedef detail::_xvec4<unsigned int>		__uvec4GTX;					//!< \brief Vector of 4 half-precision floating-point numbers. (From GLM_GTX_gpu_shader4 extension)
+
+	namespace gtx
+	{
+		//! GLM_GTX_gpu_shader4 extension: Implementation of GL_EXT_gpu_shader4 for GLM
+		namespace gpu_shader4
+		{
+			template <typename genType> genType truncate(const genType& x){return truncateGTX(x);}  //!< \brief Computes the component-wise truncate value of x (from GLM_GTX_gpu_shader4 extension)
+
+			typedef detail::_xvec2<unsigned int>		uvec2;                                              //!< \brief Vector of 2 half-precision floating-point numbers. (From GLM_GTX_gpu_shader4 extension)
+			typedef detail::_xvec3<unsigned int>		uvec3;                                              //!< \brief Vector of 3 half-precision floating-point numbers. (From GLM_GTX_gpu_shader4 extension)
+			typedef detail::_xvec4<unsigned int>		uvec4;                                              //!< \brief Vector of 4 half-precision floating-point numbers. (From GLM_GTX_gpu_shader4 extension)
+
+			// vec2 bit operators
+			template <typename T> detail::_xvec2<T>& operator%=(detail::_xvec2<T>& r, const T s);							//!< \brief Modulus operator for integer vectors. (From GLM_GTX_gpu_shader4 extension)
+			template <typename T> detail::_xvec2<T>& operator%=(detail::_xvec2<T>& r, const detail::_xvec2<T>& v);          //!< \brief Modulus operator for integer vectors. (From GLM_GTX_gpu_shader4 extension)
+			template <typename T> detail::_xvec2<T>& operator&=(detail::_xvec2<T>& r, const T s);							//!< \brief bitwise AND operator for integer vectors. (From GLM_GTX_gpu_shader4 extension) 
+			template <typename T> detail::_xvec2<T>& operator&=(detail::_xvec2<T>& r, const detail::_xvec2<T>& v);          //!< \brief bitwise AND operator for integer vectors. (From GLM_GTX_gpu_shader4 extension) 
+			template <typename T> detail::_xvec2<T>& operator|=(detail::_xvec2<T>& r, const T s);							//!< \brief bitwise inclusive OR operator for integer vectors. (From GLM_GTX_gpu_shader4 extension) 
+			template <typename T> detail::_xvec2<T>& operator|=(detail::_xvec2<T>& r, const detail::_xvec2<T>& v);          //!< \brief bitwise inclusive OR operator for integer vectors. (From GLM_GTX_gpu_shader4 extension) 
+			template <typename T> detail::_xvec2<T>& operator^=(detail::_xvec2<T>& r, const T s);							//!< \brief bitwise exclusive OR operator for integer vectors. (From GLM_GTX_gpu_shader4 extension) 
+			template <typename T> detail::_xvec2<T>& operator^=(detail::_xvec2<T>& r, const detail::_xvec2<T>& v);          //!< \brief bitwise exclusive OR operator for integer vectors. (From GLM_GTX_gpu_shader4 extension) 
+			template <typename T> detail::_xvec2<T>& operator<<=(detail::_xvec2<T>& r, const T s);							//!< \brief bitwise left shift operator for integer vectors. (From GLM_GTX_gpu_shader4 extension) 
+			template <typename T> detail::_xvec2<T>& operator<<=(detail::_xvec2<T>& r, const detail::_xvec2<T>& v);         //!< \brief bitwise left shift operator for integer vectors. (From GLM_GTX_gpu_shader4 extension) 
+			template <typename T> detail::_xvec2<T>& operator>>=(detail::_xvec2<T>& r, const T s);							//!< \brief bitwise right shift operator for integer vectors. (From GLM_GTX_gpu_shader4 extension) 
+			template <typename T> detail::_xvec2<T>& operator>>=(detail::_xvec2<T>& r, const detail::_xvec2<T>& v);         //!< \brief bitwise right shift operator for integer vectors. (From GLM_GTX_gpu_shader4 extension)
+
+			template <typename T> detail::_xvec2<T> operator% (const detail::_xvec2<T>& v, const T s);						//!< \brief Modulus operator for integer vectors. (From GLM_GTX_gpu_shader4 extension)
+			template <typename T> detail::_xvec2<T> operator% (const T s, const detail::_xvec2<T>& v);						//!< \brief Modulus operator for integer vectors. (From GLM_GTX_gpu_shader4 extension)
+			template <typename T> detail::_xvec2<T> operator% (const detail::_xvec2<T>& v1, const detail::_xvec2<T>& v2);   //!< \brief Modulus operator for integer vectors. (From GLM_GTX_gpu_shader4 extension)
+			template <typename T> detail::_xvec2<T> operator& (const detail::_xvec2<T>& v, const T s);						//!< \brief bitwise AND operator for integer vectors. (From GLM_GTX_gpu_shader4 extension) 
+			template <typename T> detail::_xvec2<T> operator& (const T s, const detail::_xvec2<T>& v);						//!< \brief bitwise AND operator for integer vectors. (From GLM_GTX_gpu_shader4 extension) 
+			template <typename T> detail::_xvec2<T> operator& (const detail::_xvec2<T>& v1, const detail::_xvec2<T>& v2);   //!< \brief bitwise AND operator for integer vectors. (From GLM_GTX_gpu_shader4 extension) 
+ 			template <typename T> detail::_xvec2<T> operator| (const detail::_xvec2<T>& v, const T s);						//!< \brief bitwise inclusive OR operator for integer vectors. (From GLM_GTX_gpu_shader4 extension) 
+			template <typename T> detail::_xvec2<T> operator| (const T s, const detail::_xvec2<T>& v);						//!< \brief bitwise inclusive OR operator for integer vectors. (From GLM_GTX_gpu_shader4 extension) 
+ 			template <typename T> detail::_xvec2<T> operator| (const detail::_xvec2<T>& v1, const detail::_xvec2<T>& v2);   //!< \brief bitwise inclusive OR operator for integer vectors. (From GLM_GTX_gpu_shader4 extension) 
+			template <typename T> detail::_xvec2<T> operator^ (const detail::_xvec2<T>& v, const T s);						//!< \brief bitwise exclusive OR operator for integer vectors. (From GLM_GTX_gpu_shader4 extension) 
+			template <typename T> detail::_xvec2<T> operator^ (const T s, const detail::_xvec2<T>& v);						//!< \brief bitwise exclusive OR operator for integer vectors. (From GLM_GTX_gpu_shader4 extension) 
+			template <typename T> detail::_xvec2<T> operator^ (const detail::_xvec2<T>& v1, const detail::_xvec2<T>& v2);   //!< \brief bitwise exclusive OR operator for integer vectors. (From GLM_GTX_gpu_shader4 extension) 
+			template <typename T> detail::_xvec2<T> operator<< (const detail::_xvec2<T>& v, const T s);						//!< \brief bitwise left shift operator for integer vectors. (From GLM_GTX_gpu_shader4 extension) 
+			template <typename T> detail::_xvec2<T> operator<< (const T s, const detail::_xvec2<T>& v);						//!< \brief bitwise left shift operator for integer vectors. (From GLM_GTX_gpu_shader4 extension) 
+			template <typename T> detail::_xvec2<T> operator<< (const detail::_xvec2<T>& v1, const detail::_xvec2<T>& v2);  //!< \brief bitwise left shift operator for integer vectors. (From GLM_GTX_gpu_shader4 extension) 
+			template <typename T> detail::_xvec2<T> operator>> (const detail::_xvec2<T>& v, const T s);						//!< \brief bitwise right shift operator for integer vectors. (From GLM_GTX_gpu_shader4 extension)
+			template <typename T> detail::_xvec2<T> operator>> (const T s, const detail::_xvec2<T>& v);						//!< \brief bitwise right shift operator for integer vectors. (From GLM_GTX_gpu_shader4 extension)
+			template <typename T> detail::_xvec2<T> operator>> (const detail::_xvec2<T>& v1, const detail::_xvec2<T>& v2);  //!< \brief bitwise right shift operator for integer vectors. (From GLM_GTX_gpu_shader4 extension)
+			template <typename T> const detail::_xvec2<T> operator~ (const detail::_xvec2<T>& v);
+
+			// vec3 bit operators
+			template <typename T> detail::_xvec3<T>& operator%=(detail::_xvec3<T>& r, const T s);							//!< \brief Modulus operator for integer vectors. (From GLM_GTX_gpu_shader4 extension)
+			template <typename T> detail::_xvec3<T>& operator%=(detail::_xvec3<T>& r, const detail::_xvec3<T>& v);          //!< \brief Modulus operator for integer vectors. (From GLM_GTX_gpu_shader4 extension)
+			template <typename T> detail::_xvec3<T>& operator&=(detail::_xvec3<T>& r, const T s);							//!< \brief bitwise AND operator for integer vectors. (From GLM_GTX_gpu_shader4 extension) 
+			template <typename T> detail::_xvec3<T>& operator&=(detail::_xvec3<T>& r, const detail::_xvec3<T>& v);          //!< \brief bitwise AND operator for integer vectors. (From GLM_GTX_gpu_shader4 extension) 
+			template <typename T> detail::_xvec3<T>& operator|=(detail::_xvec3<T>& r, const T s);							//!< \brief bitwise inclusive OR operator for integer vectors. (From GLM_GTX_gpu_shader4 extension) 
+			template <typename T> detail::_xvec3<T>& operator|=(detail::_xvec3<T>& r, const detail::_xvec3<T>& v);          //!< \brief bitwise inclusive OR operator for integer vectors. (From GLM_GTX_gpu_shader4 extension) 
+			template <typename T> detail::_xvec3<T>& operator^=(detail::_xvec3<T>& r, const T s);							//!< \brief bitwise exclusive OR operator for integer vectors. (From GLM_GTX_gpu_shader4 extension) 
+			template <typename T> detail::_xvec3<T>& operator^=(detail::_xvec3<T>& r, const detail::_xvec3<T>& v);          //!< \brief bitwise exclusive OR operator for integer vectors. (From GLM_GTX_gpu_shader4 extension) 
+			template <typename T> detail::_xvec3<T>& operator<<=(detail::_xvec3<T>& r, const T s);							//!< \brief bitwise left shift operator for integer vectors. (From GLM_GTX_gpu_shader4 extension) 
+			template <typename T> detail::_xvec3<T>& operator<<=(detail::_xvec3<T>& r, const detail::_xvec3<T>& v);         //!< \brief bitwise left shift operator for integer vectors. (From GLM_GTX_gpu_shader4 extension) 
+			template <typename T> detail::_xvec3<T>& operator>>=(detail::_xvec3<T>& r, const T s);							//!< \brief bitwise right shift operator for integer vectors. (From GLM_GTX_gpu_shader4 extension)
+			template <typename T> detail::_xvec3<T>& operator>>=(detail::_xvec3<T>& r, const detail::_xvec3<T>& v);         //!< \brief bitwise right shift operator for integer vectors. (From GLM_GTX_gpu_shader4 extension)
+
+			template <typename T> detail::_xvec3<T> operator% (const detail::_xvec3<T>& v, const T s);						//!< \brief Modulus operator for integer vectors. (From GLM_GTX_gpu_shader4 extension)
+			template <typename T> detail::_xvec3<T> operator% (const T s, const detail::_xvec3<T>& v);						//!< \brief Modulus operator for integer vectors. (From GLM_GTX_gpu_shader4 extension)
+			template <typename T> detail::_xvec3<T> operator% (const detail::_xvec3<T>& v1, const detail::_xvec3<T>& v2);   //!< \brief Modulus operator for integer vectors. (From GLM_GTX_gpu_shader4 extension)
+			template <typename T> detail::_xvec3<T> operator& (const detail::_xvec3<T>& v, const T s);						//!< \brief bitwise AND operator for integer vectors. (From GLM_GTX_gpu_shader4 extension) 
+			template <typename T> detail::_xvec3<T> operator& (const T s, const detail::_xvec3<T>& v);						//!< \brief bitwise AND operator for integer vectors. (From GLM_GTX_gpu_shader4 extension) 
+			template <typename T> detail::_xvec3<T> operator& (const detail::_xvec3<T>& v1, const detail::_xvec3<T>& v2);   //!< \brief bitwise AND operator for integer vectors. (From GLM_GTX_gpu_shader4 extension) 
+			template <typename T> detail::_xvec3<T> operator| (const detail::_xvec3<T>& v, const T s);						//!< \brief bitwise inclusive OR operator for integer vectors. (From GLM_GTX_gpu_shader4 extension) 
+			template <typename T> detail::_xvec3<T> operator| (const T s, const detail::_xvec3<T>& v);						//!< \brief bitwise inclusive OR operator for integer vectors. (From GLM_GTX_gpu_shader4 extension) 
+			template <typename T> detail::_xvec3<T> operator| (const detail::_xvec3<T>& v1, const detail::_xvec3<T>& v2);   //!< \brief bitwise inclusive OR operator for integer vectors. (From GLM_GTX_gpu_shader4 extension) 
+			template <typename T> detail::_xvec3<T> operator^ (const detail::_xvec3<T>& v, const T s);						//!< \brief bitwise exclusive OR operator for integer vectors. (From GLM_GTX_gpu_shader4 extension) 
+			template <typename T> detail::_xvec3<T> operator^ (const T s, const detail::_xvec3<T>& v);						//!< \brief bitwise exclusive OR operator for integer vectors. (From GLM_GTX_gpu_shader4 extension) 
+			template <typename T> detail::_xvec3<T> operator^ (const detail::_xvec3<T>& v1, const detail::_xvec3<T>& v2);   //!< \brief bitwise exclusive OR operator for integer vectors. (From GLM_GTX_gpu_shader4 extension) 
+			template <typename T> detail::_xvec3<T> operator<< (const detail::_xvec3<T>& v, const T s);						//!< \brief bitwise left shift operator for integer vectors. (From GLM_GTX_gpu_shader4 extension) 
+			template <typename T> detail::_xvec3<T> operator<< (const T s, const detail::_xvec3<T>& v);						//!< \brief bitwise left shift operator for integer vectors. (From GLM_GTX_gpu_shader4 extension) 
+			template <typename T> detail::_xvec3<T> operator<< (const detail::_xvec3<T>& v1, const detail::_xvec3<T>& v2);  //!< \brief bitwise left shift operator for integer vectors. (From GLM_GTX_gpu_shader4 extension) 
+			template <typename T> detail::_xvec3<T> operator>> (const detail::_xvec3<T>& v, const T s);						//!< \brief bitwise right shift operator for integer vectors. (From GLM_GTX_gpu_shader4 extension)
+			template <typename T> detail::_xvec3<T> operator>> (const T s, const detail::_xvec3<T>& v);						//!< \brief bitwise right shift operator for integer vectors. (From GLM_GTX_gpu_shader4 extension)
+			template <typename T> detail::_xvec3<T> operator>> (const detail::_xvec3<T>& v1, const detail::_xvec3<T>& v2);  //!< \brief bitwise right shift operator for integer vectors. (From GLM_GTX_gpu_shader4 extension)
+			template <typename T> const detail::_xvec3<T> operator~ (const detail::_xvec3<T>& v);							//!< \brief bitwise negation operator for integer vectors. (From GLM_GTX_gpu_shader4 extension)
+
+			// vec4 bit operators
+			template <typename T> detail::_xvec4<T>& operator%=(detail::_xvec4<T>& r, const T s);							//!< \brief Modulus operator for integer vectors. (From GLM_GTX_gpu_shader4 extension)
+			template <typename T> detail::_xvec4<T>& operator%=(detail::_xvec4<T>& r, const detail::_xvec4<T>& v);			//!< \brief Modulus operator for integer vectors. (From GLM_GTX_gpu_shader4 extension)
+			template <typename T> detail::_xvec4<T>& operator&=(detail::_xvec4<T>& r, const T s);							//!< \brief bitwise AND operator for integer vectors. (From GLM_GTX_gpu_shader4 extension) 
+			template <typename T> detail::_xvec4<T>& operator&=(detail::_xvec4<T>& r, const detail::_xvec4<T>& v);          //!< \brief bitwise AND operator for integer vectors. (From GLM_GTX_gpu_shader4 extension) 
+			template <typename T> detail::_xvec4<T>& operator|=(detail::_xvec4<T>& r, const T s);							//!< \brief bitwise inclusive OR operator for integer vectors. (From GLM_GTX_gpu_shader4 extension) 
+			template <typename T> detail::_xvec4<T>& operator|=(detail::_xvec4<T>& r, const detail::_xvec4<T>& v);          //!< \brief bitwise inclusive OR operator for integer vectors. (From GLM_GTX_gpu_shader4 extension) 
+			template <typename T> detail::_xvec4<T>& operator^=(detail::_xvec4<T>& r, const T s);							//!< \brief bitwise exclusive OR operator for integer vectors. (From GLM_GTX_gpu_shader4 extension) 
+			template <typename T> detail::_xvec4<T>& operator^=(detail::_xvec4<T>& r, const detail::_xvec4<T>& v);          //!< \brief bitwise exclusive OR operator for integer vectors. (From GLM_GTX_gpu_shader4 extension) 
+			template <typename T> detail::_xvec4<T>& operator<<=(detail::_xvec4<T>& r, const T s);							//!< \brief bitwise left shift operator for integer vectors. (From GLM_GTX_gpu_shader4 extension) 
+			template <typename T> detail::_xvec4<T>& operator<<=(detail::_xvec4<T>& r, const detail::_xvec4<T>& v);         //!< \brief bitwise left shift operator for integer vectors. (From GLM_GTX_gpu_shader4 extension) 
+			template <typename T> detail::_xvec4<T>& operator>>=(detail::_xvec4<T>& r, const T s);							//!< \brief bitwise right shift operator for integer vectors. (From GLM_GTX_gpu_shader4 extension)
+			template <typename T> detail::_xvec4<T>& operator>>=(detail::_xvec4<T>& r, const detail::_xvec4<T>& v);         //!< \brief bitwise right shift operator for integer vectors. (From GLM_GTX_gpu_shader4 extension)
+
+			template <typename T> detail::_xvec4<T> operator% (const detail::_xvec4<T>& v, const T s);						//!< \brief Modulus operator for integer vectors. (From GLM_GTX_gpu_shader4 extension)
+			template <typename T> detail::_xvec4<T> operator% (const T s, const detail::_xvec4<T>& v);						//!< \brief Modulus operator for integer vectors. (From GLM_GTX_gpu_shader4 extension)
+			template <typename T> detail::_xvec4<T> operator% (const detail::_xvec4<T>& v1, const detail::_xvec4<T>& v2);   //!< \brief Modulus operator for integer vectors. (From GLM_GTX_gpu_shader4 extension)
+			template <typename T> detail::_xvec4<T> operator& (const detail::_xvec4<T>& v, const T s);						//!< \brief bitwise AND operator for integer vectors. (From GLM_GTX_gpu_shader4 extension) 
+			template <typename T> detail::_xvec4<T> operator& (const T s, const detail::_xvec4<T>& v);						//!< \brief bitwise AND operator for integer vectors. (From GLM_GTX_gpu_shader4 extension) 
+			template <typename T> detail::_xvec4<T> operator& (const detail::_xvec4<T>& v1, const detail::_xvec4<T>& v2);   //!< \brief bitwise AND operator for integer vectors. (From GLM_GTX_gpu_shader4 extension) 
+			template <typename T> detail::_xvec4<T> operator| (const detail::_xvec4<T>& v, const T s);						//!< \brief bitwise inclusive OR operator for integer vectors. (From GLM_GTX_gpu_shader4 extension) 
+			template <typename T> detail::_xvec4<T> operator| (const T s, const detail::_xvec4<T>& v);						//!< \brief bitwise inclusive OR operator for integer vectors. (From GLM_GTX_gpu_shader4 extension) 
+			template <typename T> detail::_xvec4<T> operator| (const detail::_xvec4<T>& v1, const detail::_xvec4<T>& v2);   //!< \brief bitwise inclusive OR operator for integer vectors. (From GLM_GTX_gpu_shader4 extension) 
+			template <typename T> detail::_xvec4<T> operator^ (const detail::_xvec4<T>& v, const T s);						//!< \brief bitwise exclusive OR operator for integer vectors. (From GLM_GTX_gpu_shader4 extension) 
+			template <typename T> detail::_xvec4<T> operator^ (const T s, const detail::_xvec4<T>& v);						//!< \brief bitwise exclusive OR operator for integer vectors. (From GLM_GTX_gpu_shader4 extension) 
+			template <typename T> detail::_xvec4<T> operator^ (const detail::_xvec4<T>& v1, const detail::_xvec4<T>& v2);   //!< \brief bitwise exclusive OR operator for integer vectors. (From GLM_GTX_gpu_shader4 extension) 
+			template <typename T> detail::_xvec4<T> operator<< (const detail::_xvec4<T>& v, const T s);						//!< \brief bitwise left shift operator for integer vectors. (From GLM_GTX_gpu_shader4 extension) 
+			template <typename T> detail::_xvec4<T> operator<< (const T s, const detail::_xvec4<T>& v);						//!< \brief bitwise left shift operator for integer vectors. (From GLM_GTX_gpu_shader4 extension) 
+			template <typename T> detail::_xvec4<T> operator<< (const detail::_xvec4<T>& v1, const detail::_xvec4<T>& v2);  //!< \brief bitwise left shift operator for integer vectors. (From GLM_GTX_gpu_shader4 extension) 
+			template <typename T> detail::_xvec4<T> operator>> (const detail::_xvec4<T>& v, const T s);						//!< \brief bitwise right shift operator for integer vectors. (From GLM_GTX_gpu_shader4 extension)
+			template <typename T> detail::_xvec4<T> operator>> (const T s, const detail::_xvec4<T>& v);						//!< \brief bitwise right shift operator for integer vectors. (From GLM_GTX_gpu_shader4 extension)
+			template <typename T> detail::_xvec4<T> operator>> (const detail::_xvec4<T>& v1, const detail::_xvec4<T>& v2);  //!< \brief bitwise right shift operator for integer vectors. (From GLM_GTX_gpu_shader4 extension)
+			template <typename T> const detail::_xvec4<T> operator~ (const detail::_xvec4<T>& v);							//!< \brief bitwise negation operator for integer vectors. (From GLM_GTX_gpu_shader4 extension)
+		}
+	}
+}
+
+#define GLM_GTX_gpu_shader4 namespace gtx::gpu_shader4
+
+#include "gpu_shader4.inl"
+
+#ifdef GLM_GTX_INCLUDED
+namespace glm{using GLM_GTX_gpu_shader4;}
+#endif//GLM_GTX_INCLUDED
+
+#endif//__glm_gtx_gpu_shader4__

+ 949 - 0
experimental/sse/glm/ext/gtx/gpu_shader4.inl

@@ -0,0 +1,949 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2008 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2006-11-13
+// Updated : 2007-08-20
+// Licence : This source is under GNU LGPL licence
+// File    : glm/gtx/gpu_shader4.inl
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace glm
+{
+    inline __halfGTX truncateGTX(__halfGTX x)
+    {
+        return __halfGTX(float(int(x + __halfGTX(0.5))));
+    }
+
+    inline float truncateGTX(float x)
+    {
+        return float(int(x + float(0.5)));
+    }
+
+    inline double truncateGTX(double x)
+    {
+        return double(int(x + double(0.5)));
+    }
+
+    template <typename T>
+    inline detail::_xvec2<T> truncateGTX(const detail::_xvec2<T>& x)
+    {
+		detail::_xvec2<T> result;
+		result[1] = T(int(x[1] + T(0.5)));
+		result[2] = T(int(x[2] + T(0.5)));
+		return result;
+    }
+
+    template <typename T>
+    inline detail::_xvec3<T> truncateGTX(const detail::_xvec3<T>& x)
+    {
+		detail::_xvec3<T> result;
+		result[0] = T(int(x[0] + T(0.5)));
+		result[1] = T(int(x[1] + T(0.5)));
+		result[2] = T(int(x[2] + T(0.5)));
+		return result;
+    }
+
+    template <typename T>
+    inline detail::_xvec4<T> truncateGTX(const detail::_xvec4<T>& x)
+    {
+		detail::_xvec4<T> result;
+		result[0] = T(int(x[0] + T(0.5)));
+		result[1] = T(int(x[1] + T(0.5)));
+		result[2] = T(int(x[2] + T(0.5)));
+		result[3] = T(int(x[3] + T(0.5)));
+		return result;
+    }
+
+	namespace gtx
+	{
+		namespace gpu_shader4
+		{
+			// vec2 bit operators
+			template <typename T> 
+			inline detail::_xvec2<T>& operator%=(detail::_xvec2<T>& r, const T s)
+			{
+				r.x %= s;
+				r.y %= s;
+				return r;
+			}
+
+			template <typename T> 
+			inline detail::_xvec2<T>& operator%=(detail::_xvec2<T>& r, const detail::_xvec2<T>& v)
+			{
+				r.x %= v.x;
+				r.y %= v.y;
+				return r;
+			}
+
+			template <typename T> 
+			inline detail::_xvec2<T>& operator&=(detail::_xvec2<T>& r, const T s)
+			{
+				r.x &= s;
+				r.y &= s;
+				return r;
+			}
+
+			template <typename T> 
+			inline detail::_xvec2<T>& operator&=(detail::_xvec2<T>& r, const detail::_xvec2<T>& v)
+			{
+				r.x &= v.x;
+				r.y &= v.y;
+				return r;
+			}
+		    
+			template <typename T> 
+			inline detail::_xvec2<T>& operator|=(detail::_xvec2<T>& r, const T s)
+			{
+				r.x |= s;
+				r.y |= s;
+				return r;
+			}
+		    
+			template <typename T> 
+			inline detail::_xvec2<T>& operator|=(detail::_xvec2<T>& r, const detail::_xvec2<T>& v)
+			{
+				r.x |= v.x;
+				r.y |= v.y;
+				return r;
+			}
+		    
+			template <typename T> 
+			inline detail::_xvec2<T>& operator^=(detail::_xvec2<T>& r, const T s)
+			{
+				r.x ^= s;
+				r.y ^= s;
+				return r;
+			}
+		    
+			template <typename T> 
+			inline detail::_xvec2<T>& operator^=(detail::_xvec2<T>& r, const detail::_xvec2<T>& v)
+			{
+				r.x ^= v.x;
+				r.y ^= v.y;
+				return r;
+			}
+		    
+			template <typename T> 
+			inline detail::_xvec2<T>& operator<<=(detail::_xvec2<T>& r, const T s)
+			{
+				r.x <<= s;
+				r.y <<= s;
+				return r;
+			}
+		    
+			template <typename T> 
+			inline detail::_xvec2<T>& operator<<=(detail::_xvec2<T>& r, const detail::_xvec2<T>& v)
+			{
+				r.x <<= v.x;
+				r.y <<= v.y;
+				return r;
+			}
+		    
+			template <typename T> 
+			inline detail::_xvec2<T>& operator>>=(detail::_xvec2<T>& r, const T s)
+			{
+				r.x >>= s;
+				r.y >>= s;
+				return r;
+			}
+		    
+			template <typename T> 
+			inline detail::_xvec2<T>& operator>>=(detail::_xvec2<T>& r, const detail::_xvec2<T>& v)
+			{
+				r.x >>= v.x;
+				r.y >>= v.y;
+				return r;
+			}
+
+			template <typename T>
+			inline detail::_xvec2<T> operator% (const detail::_xvec2<T>& v, const T s)
+			{
+				return detail::_xvec2<T>(
+					v.x % s,
+					v.y % s);
+			}
+
+			template <typename T>
+			inline detail::_xvec2<T> operator% (const T s, const detail::_xvec2<T>& v)
+			{
+				return detail::_xvec2<T>(
+					s % v.x,
+					s % v.y);
+			}
+
+			template <typename T>
+			inline detail::_xvec2<T> operator% (const detail::_xvec2<T>& v1, const detail::_xvec2<T>& v2)
+			{
+				return detail::_xvec2<T>(
+					v1.x % v2.x,
+					v1.y % v2.y);
+			}
+
+			template <typename T>
+			inline detail::_xvec2<T> operator& (const detail::_xvec2<T>& v, const T s)
+			{
+				return detail::_xvec2<T>(
+					v.x & s,
+					v.y & s);
+			}
+
+			template <typename T>
+			inline detail::_xvec2<T> operator& (const T s, const detail::_xvec2<T>& v)
+			{
+				return detail::_xvec2<T>(
+					s & v.x,
+					s & v.y);
+			}
+
+			template <typename T>
+			inline detail::_xvec2<T> operator& (const detail::_xvec2<T>& v1, const detail::_xvec2<T>& v2)
+			{
+				return detail::_xvec2<T>(
+					v1.x & v2.x,
+					v1.y & v2.y);
+			}
+
+			template <typename T>
+			inline detail::_xvec2<T> operator| (const detail::_xvec2<T>& v, const T s)
+			{
+				return detail::_xvec2<T>(
+					v.x | s,
+					v.y | s);
+			}
+
+			template <typename T>
+			inline detail::_xvec2<T> operator| (const T s, const detail::_xvec2<T>& v)
+			{
+				return detail::_xvec2<T>(
+					s | v.x,
+					s | v.y);
+			}
+
+			template <typename T>
+			inline detail::_xvec2<T> operator| (const detail::_xvec2<T>& v1, const detail::_xvec2<T>& v2)
+			{
+				return detail::_xvec2<T>(
+					v1.x | v2.x,
+					v1.y | v2.y);
+			}
+			
+			template <typename T>
+			inline detail::_xvec2<T> operator^ (const detail::_xvec2<T>& v, const T s)
+			{
+				return detail::_xvec2<T>(
+					v.x ^ s,
+					v.y ^ s);
+			}
+
+			template <typename T>
+			inline detail::_xvec2<T> operator^ (const T s, const detail::_xvec2<T>& v)
+			{
+				return detail::_xvec2<T>(
+					s ^ v.x,
+					s ^ v.y);
+			}
+
+			template <typename T>
+			inline detail::_xvec2<T> operator^ (const detail::_xvec2<T>& v1, const detail::_xvec2<T>& v2)
+			{
+				return detail::_xvec2<T>(
+					v1.x ^ v2.x,
+					v1.y ^ v2.y);
+			}
+
+			template <typename T>
+			inline detail::_xvec2<T> operator<< (const detail::_xvec2<T>& v, const T s)
+			{
+				return detail::_xvec2<T>(
+					v.x << s,
+					v.y << s);
+			}
+
+			template <typename T>
+			inline detail::_xvec2<T> operator<< (const T s, const detail::_xvec2<T>& v)
+			{
+				return detail::_xvec2<T>(
+					s << v.x,
+					s << v.y);
+			}
+
+			template <typename T>
+			inline detail::_xvec2<T> operator<< (const detail::_xvec2<T>& v1, const detail::_xvec2<T>& v2)
+			{
+				return detail::_xvec2<T>(
+					v1.x << v2.x,
+					v1.y << v2.y);
+			}
+
+			template <typename T>
+			inline detail::_xvec2<T> operator>> (const detail::_xvec2<T>& v, const T s)
+			{
+				return detail::_xvec2<T>(
+					v.x >> s,
+					v.y >> s);
+			}
+
+			template <typename T>
+			inline detail::_xvec2<T> operator>> (const T s, const detail::_xvec2<T>& v)
+			{
+				return detail::_xvec2<T>(
+					s >> v.x,
+					s >> v.y);
+			}
+
+			template <typename T>
+			inline detail::_xvec2<T> operator>> (const detail::_xvec2<T>& v1, const detail::_xvec2<T>& v2)
+			{
+				return detail::_xvec2<T>(
+					v1.x >> v2.x,
+					v1.y >> v2.y);
+			}
+
+			template <typename T> 
+			inline const detail::_xvec2<T> operator~ (const detail::_xvec2<T>& v)
+			{
+				return detail::_xvec2<T>(
+					~v.x,
+					~v.y);
+			}
+
+			// vec3 bit operators
+			template <typename T>
+			inline detail::_xvec3<T>& operator%=(detail::_xvec3<T>& r, const T s)
+			{
+				r.x &= s;
+				r.y &= s;
+				r.z &= s;
+				return r;
+			}
+
+			template <typename T>
+			inline detail::_xvec3<T>& operator%=(detail::_xvec3<T>& r, const detail::_xvec3<T>& v)
+			{
+				r.x &= v.x;
+				r.y &= v.y;
+				r.z &= v.z;
+				return r;
+			}
+
+			template <typename T>
+			inline detail::_xvec3<T>& operator&=(detail::_xvec3<T>& r, const T s)
+			{
+				r.x &= s;
+				r.y &= s;
+				r.z &= s;
+				return r;
+			}
+
+			template <typename T> 
+			inline detail::_xvec3<T>& operator&=(detail::_xvec3<T>& r, const detail::_xvec3<T>& v)
+			{
+				r.x &= v.x;
+				r.y &= v.y;
+				r.z &= v.z;
+				return r;
+			}
+		    
+			template <typename T> 
+			inline detail::_xvec3<T>& operator|=(detail::_xvec3<T>& r, const T s)
+			{
+				r.x |= s;
+				r.y |= s;
+				r.z |= s;
+				return r;
+			}
+		    
+			template <typename T> 
+			inline detail::_xvec3<T>& operator|=(detail::_xvec3<T>& r, const detail::_xvec3<T>& v)
+			{
+				r.x |= v.x;
+				r.y |= v.y;
+				r.z |= v.z;
+				return r;
+			}
+		    
+			template <typename T> 
+			inline detail::_xvec3<T>& operator^=(detail::_xvec3<T>& r, const T s)
+			{
+				r.x ^= s;
+				r.y ^= s;
+				r.z ^= s;
+				return r;
+			}
+		    
+			template <typename T> 
+			inline detail::_xvec3<T>& operator^=(detail::_xvec3<T>& r, const detail::_xvec3<T>& v)
+			{
+				r.x ^= v.x;
+				r.y ^= v.y;
+				r.z ^= v.z;
+				return r;
+			}
+		    
+			template <typename T> 
+			inline detail::_xvec3<T>& operator<<=(detail::_xvec3<T>& r, const T s)
+			{
+				r.x <<= s;
+				r.y <<= s;
+				r.z <<= s;
+				return r;
+			}
+		    
+			template <typename T> 
+			inline detail::_xvec3<T>& operator<<=(detail::_xvec3<T>& r, const detail::_xvec3<T>& v)
+			{
+				r.x <<= v.x;
+				r.y <<= v.y;
+				r.z <<= v.z;
+				return r;
+			}
+		    
+			template <typename T> 
+			inline detail::_xvec3<T>& operator>>=(detail::_xvec3<T>& r, const T s)
+			{
+				r.x >>= s;
+				r.y >>= s;
+				r.z >>= s;
+				return r;
+			}
+		    
+			template <typename T> 
+			inline detail::_xvec3<T>& operator>>=(detail::_xvec3<T>& r, const detail::_xvec3<T>& v)
+			{
+				r.x >>= v.x;
+				r.y >>= v.y;
+				r.z >>= v.z;
+				return r;
+			}
+
+			template <typename T>
+			inline detail::_xvec3<T> operator% (const detail::_xvec3<T>& v, const T s)
+			{
+				return detail::_xvec3<T>(
+					v.x % s,
+					v.y % s,
+					v.z % s);
+			}
+
+			template <typename T>
+			inline detail::_xvec3<T> operator% (const T s, const detail::_xvec3<T>& v)
+			{
+				return detail::_xvec3<T>(
+					s % v.x,
+					s % v.y,
+					s % v.z);
+			}
+
+			template <typename T>
+			inline detail::_xvec3<T> operator% (const detail::_xvec3<T>& v1, const detail::_xvec3<T>& v2)
+			{
+				return detail::_xvec3<T>(
+					v1.x % v2.x,
+					v1.y % v2.y,
+					v1.z % v2.z);
+			}
+
+			template <typename T>
+			inline detail::_xvec3<T> operator& (const detail::_xvec3<T>& v, const T s)
+			{
+				return detail::_xvec3<T>(
+					v.x & s,
+					v.y & s,
+					v.z & s);
+			}
+
+			template <typename T>
+			inline detail::_xvec3<T> operator& (const T s, const detail::_xvec3<T>& v)
+			{
+				return detail::_xvec3<T>(
+					s & v.x,
+					s & v.y,
+					s & v.z);
+			}
+
+			template <typename T>
+			inline detail::_xvec3<T> operator& (const detail::_xvec3<T>& v1, const detail::_xvec3<T>& v2)
+			{
+				return detail::_xvec2<T>(
+					v1.x & v2.x,
+					v1.y & v2.y,
+					v1.z & v2.z);
+			}
+
+			template <typename T>
+			inline detail::_xvec3<T> operator| (const detail::_xvec3<T>& v, const T s)
+			{
+				return detail::_xvec3<T>(
+					v.x | s,
+					v.y | s,
+					v.z | s);
+			}
+
+			template <typename T>
+			inline detail::_xvec3<T> operator| (const T s, const detail::_xvec3<T>& v)
+			{
+				return detail::_xvec3<T>(
+					s | v.x,
+					s | v.y,
+					s | v.z);
+			}
+
+			template <typename T>
+			inline detail::_xvec3<T> operator| (const detail::_xvec3<T>& v1, const detail::_xvec3<T>& v2)
+			{
+				return detail::_xvec3<T>(
+					v1.x | v2.x,
+					v1.y | v2.y,
+					v1.z | v2.z);
+			}
+			
+			template <typename T>
+			inline detail::_xvec3<T> operator^ (const detail::_xvec3<T>& v, const T s)
+			{
+				return detail::_xvec3<T>(
+					v.x ^ s,
+					v.y ^ s,
+					v.z ^ s);
+			}
+
+			template <typename T>
+			inline detail::_xvec3<T> operator^ (const T s, const detail::_xvec3<T>& v)
+			{
+				return detail::_xvec3<T>(
+					s ^ v.x,
+					s ^ v.y,
+					s ^ v.z);
+			}
+
+			template <typename T>
+			inline detail::_xvec3<T> operator^ (const detail::_xvec3<T>& v1, const detail::_xvec3<T>& v2)
+			{
+				return detail::_xvec3<T>(
+					v1.x ^ v2.x,
+					v1.y ^ v2.y,
+					v1.z ^ v2.z);
+			}
+
+			template <typename T>
+			inline detail::_xvec3<T> operator<< (const detail::_xvec3<T>& v, const T s)
+			{
+				return detail::_xvec3<T>(
+					v.x << s,
+					v.y << s,
+					v.z << s);
+			}
+
+			template <typename T>
+			inline detail::_xvec3<T> operator<< (const T s, const detail::_xvec3<T>& v)
+			{
+				return detail::_xvec3<T>(
+					s << v.x,
+					s << v.y,
+					s << v.z);
+			}
+
+			template <typename T>
+			inline detail::_xvec3<T> operator<< (const detail::_xvec3<T>& v1, const detail::_xvec3<T>& v2)
+			{
+				return detail::_xvec3<T>(
+					v1.x << v2.x,
+					v1.y << v2.y,
+					v1.z << v2.z);
+			}
+
+			template <typename T>
+			inline detail::_xvec3<T> operator>> (const detail::_xvec3<T>& v, const T s)
+			{
+				return detail::_xvec3<T>(
+					v.x >> s,
+					v.y >> s,
+					v.z >> s);
+			}
+
+			template <typename T>
+			inline detail::_xvec3<T> operator>> (const T s, const detail::_xvec3<T>& v)
+			{
+				return detail::_xvec3<T>(
+					s >> v.x,
+					s >> v.y,
+					s >> v.z);
+			}
+
+			template <typename T>
+			inline detail::_xvec3<T> operator>> (const detail::_xvec3<T>& v1, const detail::_xvec3<T>& v2)
+			{
+				return detail::_xvec3<T>(
+					v1.x >> v2.x,
+					v1.y >> v2.y,
+					v1.z >> v2.z);
+			}
+
+			template <typename T> 
+			inline const detail::_xvec3<T> operator~ (const detail::_xvec3<T>& v)
+			{
+				return detail::_xvec3<T>(
+					~v.x,
+					~v.y,
+					~v.z);
+			}
+
+			// vec4 bit operators
+			template <typename T> 
+			inline detail::_xvec4<T>& operator%=(detail::_xvec4<T>& r, const T s)
+			{
+				r.x %= s;
+				r.y %= s;
+				r.z %= s;
+				r.w %= s;
+				return r;
+			}
+
+			template <typename T> 
+			inline detail::_xvec4<T>& operator%=(detail::_xvec4<T>& r, const detail::_xvec4<T>& v)
+			{
+				r.x %= v.x;
+				r.y %= v.y;
+				r.z %= v.z;
+				r.w %= v.w;
+				return r;
+			}
+
+			template <typename T> 
+			inline detail::_xvec4<T>& operator&=(detail::_xvec4<T>& r, const T s)
+			{
+				r.x &= s;
+				r.y &= s;
+				r.z &= s;
+				r.w &= s;
+				return r;
+			}
+
+			template <typename T> 
+			inline detail::_xvec4<T>& operator&=(detail::_xvec4<T>& r, const detail::_xvec4<T>& v)
+			{
+				r.x &= v.x;
+				r.y &= v.y;
+				r.z &= v.z;
+				r.w &= v.w;
+				return r;
+			}
+		    
+			template <typename T> 
+			inline detail::_xvec4<T>& operator|=(detail::_xvec4<T>& r, const T s)
+			{
+				r.x |= s;
+				r.y |= s;
+				r.z |= s;
+				r.w |= s;
+				return r;
+			}
+		    
+			template <typename T> 
+			inline detail::_xvec4<T>& operator|=(detail::_xvec4<T>& r, const detail::_xvec4<T>& v)
+			{
+				r.x |= v.x;
+				r.y |= v.y;
+				r.z |= v.z;
+				r.w |= v.w;
+				return r;
+			}
+		    
+			template <typename T> 
+			inline detail::_xvec4<T>& operator^=(detail::_xvec4<T>& r, const T s)
+			{
+				r.x ^= s;
+				r.y ^= s;
+				r.z ^= s;
+				r.w ^= s;
+				return r;
+			}
+		    
+			template <typename T> 
+			inline detail::_xvec4<T>& operator^=(detail::_xvec4<T>& r, const detail::_xvec4<T>& v)
+			{
+				r.x ^= v.x;
+				r.y ^= v.y;
+				r.z ^= v.z;
+				r.w ^= v.w;
+				return r;
+			}
+		    
+			template <typename T> 
+			inline detail::_xvec4<T>& operator<<=(detail::_xvec4<T>& r, const T s)
+			{
+				r.x <<= s;
+				r.y <<= s;
+				r.z <<= s;
+				r.w <<= s;
+				return r;
+			}
+		    
+			template <typename T> 
+			inline detail::_xvec4<T>& operator<<=(detail::_xvec4<T>& r, const detail::_xvec4<T>& v)
+			{
+				r.x <<= v.x;
+				r.y <<= v.y;
+				r.z <<= v.z;
+				r.w <<= v.w;
+				return r;
+			}
+		    
+			template <typename T> 
+			inline detail::_xvec4<T>& operator>>=(detail::_xvec4<T>& r, const T s)
+			{
+				r.x >>= s;
+				r.y >>= s;
+				r.z >>= s;
+				r.w >>= s;
+				return r;
+			}
+		    
+			template <typename T> 
+			inline detail::_xvec4<T>& operator>>=(detail::_xvec4<T>& r, const detail::_xvec4<T>& v)
+			{
+				r.x >>= v.x;
+				r.y >>= v.y;
+				r.z >>= v.z;
+				r.w >>= v.w;
+				return r;
+			}
+
+			template <typename T>
+			inline detail::_xvec4<T> operator% (const detail::_xvec4<T>& v, const T s)
+			{
+				return detail::_xvec4<T>(
+					v.x % s,
+					v.y % s,
+					v.z % s,
+					v.w % s);
+			}
+
+			template <typename T>
+			inline detail::_xvec4<T> operator% (const T s, const detail::_xvec4<T>& v)
+			{
+				return detail::_xvec4<T>(
+					s % v.x,
+					s % v.y,
+					s % v.z,
+					s % v.w);
+			}
+
+			template <typename T>
+			inline detail::_xvec4<T> operator% (const detail::_xvec4<T>& v1, const detail::_xvec4<T>& v2)
+			{
+				return detail::_xvec4<T>(
+					v1.x % v2.x,
+					v1.y % v2.y,
+					v1.z % v2.z,
+					v1.w % v2.w);
+			}
+
+			template <typename T>
+			inline detail::_xvec4<T> operator& (const detail::_xvec4<T>& v, const T s)
+			{
+				return detail::_xvec4<T>(
+					v.x & s,
+					v.y & s,
+					v.z & s,
+					v.w & s);
+			}
+
+			template <typename T>
+			inline detail::_xvec4<T> operator& (const T s, const detail::_xvec4<T>& v)
+			{
+				return detail::_xvec4<T>(
+					s & v.x,
+					s & v.y,
+					s & v.z,
+					s & v.w);
+			}
+
+			template <typename T>
+			inline detail::_xvec4<T> operator& (const detail::_xvec4<T>& v1, const detail::_xvec4<T>& v2)
+			{
+				return detail::_xvec4<T>(
+					v1.x & v2.x,
+					v1.y & v2.y,
+					v1.z & v2.z,
+					v1.w & v2.w);
+			}
+
+			template <typename T>
+			inline detail::_xvec4<T> operator| (const detail::_xvec4<T>& v, const T s)
+			{
+				return detail::_xvec4<T>(
+					v.x | s,
+					v.y | s,
+					v.z | s,
+					v.w | s);
+			}
+
+			template <typename T>
+			inline detail::_xvec4<T> operator| (const T s, const detail::_xvec4<T>& v)
+			{
+				return detail::_xvec4<T>(
+					s | v.x,
+					s | v.y,
+					s | v.z,
+					s | v.w);
+			}
+
+			template <typename T>
+			inline detail::_xvec4<T> operator| (const detail::_xvec4<T>& v1, const detail::_xvec4<T>& v2)
+			{
+				return detail::_xvec4<T>(
+					v1.x | v2.x,
+					v1.y | v2.y,
+					v1.z | v2.z,
+					v1.w | v2.w);
+			}
+			
+			template <typename T>
+			inline detail::_xvec4<T> operator^ (const detail::_xvec4<T>& v, const T s)
+			{
+				return detail::_xvec4<T>(
+					v.x ^ s,
+					v.y ^ s,
+					v.z ^ s,
+					v.w ^ s);
+			}
+
+			template <typename T>
+			inline detail::_xvec4<T> operator^ (const T s, const detail::_xvec4<T>& v)
+			{
+				return detail::_xvec4<T>(
+					s ^ v.x,
+					s ^ v.y,
+					s ^ v.z,
+					s ^ v.w);
+			}
+
+			template <typename T>
+			inline detail::_xvec4<T> operator^ (const detail::_xvec4<T>& v1, const detail::_xvec4<T>& v2)
+			{
+				return detail::_xvec4<T>(
+					v1.x ^ v2.x,
+					v1.y ^ v2.y,
+					v1.z ^ v2.z,
+					v1.w ^ v2.w);
+			}
+
+			template <typename T>
+			inline detail::_xvec4<T> operator<< (const detail::_xvec4<T>& v, const T s)
+			{
+				return detail::_xvec4<T>(
+					v.x << s,
+					v.y << s,
+					v.z << s,
+					v.w << s);
+			}
+
+			template <typename T>
+			inline detail::_xvec4<T> operator<< (const T s, const detail::_xvec4<T>& v)
+			{
+				return detail::_xvec4<T>(
+					s << v.x,
+					s << v.y,
+					s << v.z,
+					s << v.w);
+			}
+
+			template <typename T>
+			inline detail::_xvec4<T> operator<< (const detail::_xvec4<T>& v1, const detail::_xvec4<T>& v2)
+			{
+				return detail::_xvec4<T>(
+					v1.x << v2.x,
+					v1.y << v2.y,
+					v1.z << v2.z,
+					v1.w << v2.w);
+			}
+
+			template <typename T>
+			inline detail::_xvec4<T> operator>> (const detail::_xvec4<T>& v, const T s)
+			{
+				return detail::_xvec4<T>(
+					v.x >> s,
+					v.y >> s,
+					v.z >> s,
+					v.w >> s);
+			}
+
+			template <typename T>
+			inline detail::_xvec4<T> operator>> (const T s, const detail::_xvec4<T>& v)
+			{
+				return detail::_xvec4<T>(
+					s >> v.x,
+					s >> v.y,
+					s >> v.z,
+					s >> v.w);
+			}
+
+			template <typename T>
+			inline detail::_xvec4<T> operator>> (const detail::_xvec4<T>& v1, const detail::_xvec4<T>& v2)
+			{
+				return detail::_xvec4<T>(
+					v1.x >> v2.x,
+					v1.y >> v2.y,
+					v1.z >> v2.z,
+					v1.w >> v2.w);
+			}
+
+			template <typename T> 
+			inline const detail::_xvec4<T> operator~ (const detail::_xvec4<T>& v)
+			{
+				return detail::_xvec4<T>(
+					~v.x,
+					~v.y,
+					~v.z,
+					~v.w);
+			}
+		}
+	}
+
+/*
+	inline half truncate(half x)
+    {
+        return half(float(int(x + half(0.5))));
+    }
+
+    inline float truncate(float x)
+    {
+        return float(int(x + float(0.5)));
+    }
+
+    inline double truncate(double x)
+    {
+        return double(int(x + double(0.5)));
+    }
+
+    template <typename T>
+    inline detail::_xvec2<T> truncate(const detail::_xvec2<T>& x)
+    {
+		detail::_xvec2<T> result;
+		result[1] = T(int(x[1] + T(0.5)));
+		result[2] = T(int(x[2] + T(0.5)));
+		return result;
+    }
+
+    template <typename T>
+    inline detail::_xvec3<T> truncate(const detail::_xvec3<T>& x)
+    {
+		detail::_xvec3<T> result;
+		result[0] = T(int(x[0] + T(0.5)));
+		result[1] = T(int(x[1] + T(0.5)));
+		result[2] = T(int(x[2] + T(0.5)));
+		return result;
+    }
+
+    template <typename T>
+    inline detail::_xvec4<T> truncate(const detail::_xvec4<T>& x)
+    {
+		detail::_xvec4<T> result;
+		result[0] = T(int(x[0] + T(0.5)));
+		result[1] = T(int(x[1] + T(0.5)));
+		result[2] = T(int(x[2] + T(0.5)));
+		result[3] = T(int(x[3] + T(0.5)));
+		return result;
+    }
+*/
+}

Деякі файли не було показано, через те що забагато файлів було змінено