Explorar o código

Merge remote-tracking branch 'upstream/master'

dimitri %!s(int64=8) %!d(string=hai) anos
pai
achega
5d9bdbaded
Modificáronse 60 ficheiros con 1074 adicións e 288 borrados
  1. 2 0
      .gitignore
  2. 36 4
      glm/detail/func_common.inl
  3. 1 1
      glm/detail/func_common_simd.inl
  4. 6 6
      glm/detail/func_integer.inl
  5. 4 4
      glm/detail/func_integer_simd.inl
  6. 5 5
      glm/detail/func_matrix_simd.inl
  7. 0 10
      glm/detail/setup.hpp
  8. 6 6
      glm/detail/type_half.inl
  9. 9 9
      glm/detail/type_mat2x2.hpp
  10. 2 7
      glm/detail/type_mat2x2.inl
  11. 9 9
      glm/detail/type_mat2x3.hpp
  12. 3 8
      glm/detail/type_mat2x3.inl
  13. 9 9
      glm/detail/type_mat2x4.hpp
  14. 2 7
      glm/detail/type_mat2x4.inl
  15. 9 9
      glm/detail/type_mat3x2.hpp
  16. 2 8
      glm/detail/type_mat3x2.inl
  17. 9 9
      glm/detail/type_mat3x3.hpp
  18. 2 8
      glm/detail/type_mat3x3.inl
  19. 9 9
      glm/detail/type_mat3x4.hpp
  20. 2 8
      glm/detail/type_mat3x4.inl
  21. 9 9
      glm/detail/type_mat4x2.hpp
  22. 2 9
      glm/detail/type_mat4x2.inl
  23. 9 9
      glm/detail/type_mat4x3.hpp
  24. 2 9
      glm/detail/type_mat4x3.inl
  25. 2 2
      glm/detail/type_mat4x4.hpp
  26. 2 9
      glm/detail/type_mat4x4.inl
  27. 2 2
      glm/detail/type_vec1.hpp
  28. 1 4
      glm/detail/type_vec1.inl
  29. 2 2
      glm/detail/type_vec2.hpp
  30. 1 4
      glm/detail/type_vec2.inl
  31. 2 2
      glm/detail/type_vec3.hpp
  32. 1 4
      glm/detail/type_vec3.inl
  33. 2 2
      glm/detail/type_vec4.hpp
  34. 1 4
      glm/detail/type_vec4.inl
  35. 131 7
      glm/gtc/packing.hpp
  36. 140 0
      glm/gtc/packing.inl
  37. 2 2
      glm/gtc/quaternion.hpp
  38. 5 8
      glm/gtc/quaternion.inl
  39. 2 2
      glm/gtx/dual_quaternion.hpp
  40. 1 5
      glm/gtx/dual_quaternion.inl
  41. 1 1
      glm/gtx/integer.hpp
  42. 6 2
      glm/gtx/integer.inl
  43. 65 0
      glm/gtx/matrix_factorisation.hpp
  44. 85 0
      glm/gtx/matrix_factorisation.inl
  45. 7 1
      glm/gtx/matrix_interpolation.inl
  46. 28 0
      glm/gtx/quaternion.hpp
  47. 34 0
      glm/gtx/quaternion.inl
  48. 4 4
      glm/simd/common.h
  49. 4 47
      manual.md
  50. 12 1
      readme.md
  51. 5 0
      test/core/core_type_vec1.cpp
  52. 5 0
      test/core/core_type_vec2.cpp
  53. 5 0
      test/core/core_type_vec3.cpp
  54. 5 0
      test/core/core_type_vec4.cpp
  55. 162 0
      test/gtc/gtc_packing.cpp
  56. 1 0
      test/gtx/CMakeLists.txt
  57. 43 0
      test/gtx/gtx_integer.cpp
  58. 101 0
      test/gtx/gtx_matrix_factorisation.cpp
  59. 37 1
      test/gtx/gtx_matrix_interpolation.cpp
  60. 18 0
      test/gtx/gtx_quaternion.cpp

+ 2 - 0
.gitignore

@@ -52,3 +52,5 @@ Makefile
 # local build(s)
 build*
 
+/.vs
+/CMakeSettings.json

+ 36 - 4
glm/detail/func_common.inl

@@ -696,7 +696,15 @@ namespace detail
 
 	GLM_FUNC_QUALIFIER int floatBitsToInt(float const & v)
 	{
-		return reinterpret_cast<int&>(const_cast<float&>(v));
+		union
+		{
+			float in;
+			int out;
+		} u;
+
+		u.in = v;
+
+		return u.out;
 	}
 
 	template<template<length_t, typename, precision> class vecType, length_t L, precision P>
@@ -707,7 +715,15 @@ namespace detail
 
 	GLM_FUNC_QUALIFIER uint floatBitsToUint(float const & v)
 	{
-		return reinterpret_cast<uint&>(const_cast<float&>(v));
+		union
+		{
+			float in;
+			uint out;
+		} u;
+
+		u.in = v;
+
+		return u.out;
 	}
 
 	template<template<length_t, typename, precision> class vecType, length_t L, precision P>
@@ -718,7 +734,15 @@ namespace detail
 
 	GLM_FUNC_QUALIFIER float intBitsToFloat(int const & v)
 	{
-		return reinterpret_cast<float&>(const_cast<int&>(v));
+		union
+		{
+			int in;
+			float out;
+		} u;
+
+		u.in = v;
+
+		return u.out;
 	}
 
 	template<template<length_t, typename, precision> class vecType, length_t L, precision P>
@@ -729,7 +753,15 @@ namespace detail
 
 	GLM_FUNC_QUALIFIER float uintBitsToFloat(uint const & v)
 	{
-		return reinterpret_cast<float&>(const_cast<uint&>(v));
+		union
+		{
+			uint in;
+			float out;
+		} u;
+
+		u.in = v;
+
+		return u.out;
 	}
 
 	template<template<length_t, typename, precision> class vecType, length_t L, precision P>

+ 1 - 1
glm/detail/func_common_simd.inl

@@ -191,7 +191,7 @@ namespace detail
 	{
 		GLM_FUNC_QUALIFIER static vec<4, float, P> call(vec<4, float, P> const & x, vec<4, float, P> const & y, vec<4, bool, P> const & a)
 		{
-			__m128i const Load = _mm_set_epi32(-(int)a.w, -(int)a.z, -(int)a.y, -(int)a.x);
+			__m128i const Load = _mm_set_epi32(-static_cast<int>(a.w), -static_cast<int>(a.z), -static_cast<int>(a.y), -static_cast<int>(a.x));
 			__m128 const Mask = _mm_castsi128_ps(Load);
 
 			vec<4, float, P> Result(uninitialize);

+ 6 - 6
glm/detail/func_integer.inl

@@ -298,12 +298,12 @@ namespace detail
 	GLM_FUNC_QUALIFIER vecType<L, T, P> bitfieldReverse(vecType<L, T, P> const& v)
 	{
 		vecType<L, T, P> x(v);
-		x = detail::compute_bitfieldReverseStep<L, T, P, vecType, detail::is_aligned<P>::value, sizeof(T) * 8>=  2>::call(x, T(0x5555555555555555ull), static_cast<T>( 1));
-		x = detail::compute_bitfieldReverseStep<L, T, P, vecType, detail::is_aligned<P>::value, sizeof(T) * 8>=  4>::call(x, T(0x3333333333333333ull), static_cast<T>( 2));
-		x = detail::compute_bitfieldReverseStep<L, T, P, vecType, detail::is_aligned<P>::value, sizeof(T) * 8>=  8>::call(x, T(0x0F0F0F0F0F0F0F0Full), static_cast<T>( 4));
-		x = detail::compute_bitfieldReverseStep<L, T, P, vecType, detail::is_aligned<P>::value, sizeof(T) * 8>= 16>::call(x, T(0x00FF00FF00FF00FFull), static_cast<T>( 8));
-		x = detail::compute_bitfieldReverseStep<L, T, P, vecType, detail::is_aligned<P>::value, sizeof(T) * 8>= 32>::call(x, T(0x0000FFFF0000FFFFull), static_cast<T>(16));
-		x = detail::compute_bitfieldReverseStep<L, T, P, vecType, detail::is_aligned<P>::value, sizeof(T) * 8>= 64>::call(x, T(0x00000000FFFFFFFFull), static_cast<T>(32));
+		x = detail::compute_bitfieldReverseStep<L, T, P, vecType, detail::is_aligned<P>::value, sizeof(T) * 8>=  2>::call(x, static_cast<T>(0x5555555555555555ull), static_cast<T>( 1));
+		x = detail::compute_bitfieldReverseStep<L, T, P, vecType, detail::is_aligned<P>::value, sizeof(T) * 8>=  4>::call(x, static_cast<T>(0x3333333333333333ull), static_cast<T>( 2));
+		x = detail::compute_bitfieldReverseStep<L, T, P, vecType, detail::is_aligned<P>::value, sizeof(T) * 8>=  8>::call(x, static_cast<T>(0x0F0F0F0F0F0F0F0Full), static_cast<T>( 4));
+		x = detail::compute_bitfieldReverseStep<L, T, P, vecType, detail::is_aligned<P>::value, sizeof(T) * 8>= 16>::call(x, static_cast<T>(0x00FF00FF00FF00FFull), static_cast<T>( 8));
+		x = detail::compute_bitfieldReverseStep<L, T, P, vecType, detail::is_aligned<P>::value, sizeof(T) * 8>= 32>::call(x, static_cast<T>(0x0000FFFF0000FFFFull), static_cast<T>(16));
+		x = detail::compute_bitfieldReverseStep<L, T, P, vecType, detail::is_aligned<P>::value, sizeof(T) * 8>= 64>::call(x, static_cast<T>(0x00000000FFFFFFFFull), static_cast<T>(32));
 		return x;
 	}
 

+ 4 - 4
glm/detail/func_integer_simd.inl

@@ -11,11 +11,11 @@ namespace detail
 	template<glm::precision P>
 	struct compute_bitfieldReverseStep<4, uint32, P, vec, true, true>
 	{
-		GLM_FUNC_QUALIFIER static vec<4, uint32, P> call(vec<4, uint32, P> const & v, uint32 Mask, uint32 Shift)
+		GLM_FUNC_QUALIFIER static vec<4, uint32, P> call(vec<4, uint32, P> const& v, uint32 Mask, uint32 Shift)
 		{
 			__m128i const set0 = v.data;
 
-			__m128i const set1 = _mm_set1_epi32(Mask);
+			__m128i const set1 = _mm_set1_epi32(static_cast<int>(Mask));
 			__m128i const and1 = _mm_and_si128(set0, set1);
 			__m128i const sft1 = _mm_slli_epi32(and1, Shift);
 
@@ -32,11 +32,11 @@ namespace detail
 	template<glm::precision P>
 	struct compute_bitfieldBitCountStep<4, uint32, P, vec, true, true>
 	{
-		GLM_FUNC_QUALIFIER static vec<4, uint32, P> call(vec<4, uint32, P> const & v, uint32 Mask, uint32 Shift)
+		GLM_FUNC_QUALIFIER static vec<4, uint32, P> call(vec<4, uint32, P> const& v, uint32 Mask, uint32 Shift)
 		{
 			__m128i const set0 = v.data;
 
-			__m128i const set1 = _mm_set1_epi32(Mask);
+			__m128i const set1 = _mm_set1_epi32(static_cast<int>(Mask));
 			__m128i const and0 = _mm_and_si128(set0, set1);
 			__m128i const sft0 = _mm_slli_epi32(set0, Shift);
 			__m128i const and1 = _mm_and_si128(sft0, set1);

+ 5 - 5
glm/detail/func_matrix_simd.inl

@@ -19,9 +19,9 @@ namespace detail
 		{
 			mat<4, 4, float, P> result(uninitialize);
 			glm_mat4_matrixCompMult(
-				*(glm_vec4 const (*)[4])&x[0].data,
-				*(glm_vec4 const (*)[4])&y[0].data,
-				*(glm_vec4(*)[4])&result[0].data);
+				*static_cast<glm_vec4 const (*)[4]>(&x[0].data),
+				*static_cast<glm_vec4 const (*)[4]>(&y[0].data),
+				*static_cast<glm_vec4(*)[4]>(&result[0].data));
 			return result;
 		}
 	};
@@ -33,8 +33,8 @@ namespace detail
 		{
 			mat<4, 4, float, P> result(uninitialize);
 			glm_mat4_transpose(
-				*(glm_vec4 const (*)[4])&m[0].data,
-				*(glm_vec4(*)[4])&result[0].data);
+				*static_cast<glm_vec4 const (*)[4]>(&m[0].data),
+				*static_cast<glm_vec4(*)[4]>(&result[0].data));
 			return result;
 		}
 	};

+ 0 - 10
glm/detail/setup.hpp

@@ -692,14 +692,8 @@
 
 #if GLM_HAS_DEFAULTED_FUNCTIONS
 #	define GLM_DEFAULT = default
-#	ifdef GLM_FORCE_NO_CTOR_INIT
-#		define GLM_DEFAULT_CTOR = default
-#	else
-#		define GLM_DEFAULT_CTOR
-#	endif
 #else
 #	define GLM_DEFAULT
-#	define GLM_DEFAULT_CTOR
 #endif
 
 #if GLM_HAS_CONSTEXPR || GLM_HAS_CONSTEXPR_PARTIAL
@@ -765,10 +759,6 @@ namespace glm
 ///////////////////////////////////////////////////////////////////////////////////
 // countof
 
-#ifndef __has_feature
-#	define __has_feature(x) 0 // Compatibility with non-clang compilers.
-#endif
-
 #if GLM_HAS_CONSTEXPR_PARTIAL
 	namespace glm
 	{

+ 6 - 6
glm/detail/type_half.inl

@@ -46,7 +46,7 @@ namespace detail
 				//
 
 				detail::uif32 result;
-				result.i = (unsigned int)(s << 31);
+				result.i = static_cast<unsigned int>(s << 31);
 				return result.f;
 			}
 			else
@@ -74,7 +74,7 @@ namespace detail
 				//
 
 				uif32 result;
-				result.i = (unsigned int)((s << 31) | 0x7f800000);
+				result.i = static_cast<unsigned int>((s << 31) | 0x7f800000);
 				return result.f;
 			}
 			else
@@ -84,7 +84,7 @@ namespace detail
 				//
 
 				uif32 result;
-				result.i = (unsigned int)((s << 31) | 0x7f800000 | (m << 13));
+				result.i = static_cast<unsigned int>((s << 31) | 0x7f800000 | (m << 13));
 				return result.f;
 			}
 		}
@@ -101,15 +101,15 @@ namespace detail
 		//
 
 		uif32 Result;
-		Result.i = (unsigned int)((s << 31) | (e << 23) | m);
+		Result.i = static_cast<unsigned int>((s << 31) | (e << 23) | m);
 		return Result.f;
 	}
 
-	GLM_FUNC_QUALIFIER hdata toFloat16(float const & f)
+	GLM_FUNC_QUALIFIER hdata toFloat16(float const& f)
 	{
 		uif32 Entry;
 		Entry.f = f;
-		int i = (int)Entry.i;
+		int i = static_cast<int>(Entry.i);
 
 		//
 		// Our floating point number, f, is represented by the bit

+ 9 - 9
glm/detail/type_mat2x2.hpp

@@ -24,9 +24,17 @@ namespace glm
 		col_type value[2];
 
 	public:
+		// -- Accesses --
+
+		typedef length_t length_type;
+		GLM_FUNC_DECL static GLM_CONSTEXPR length_type length() { return 2; }
+
+		GLM_FUNC_DECL col_type & operator[](length_type i);
+		GLM_FUNC_DECL col_type const & operator[](length_type i) const;
+
 		// -- Constructors --
 
-		GLM_FUNC_DECL mat() GLM_DEFAULT_CTOR;
+		GLM_FUNC_DECL mat() GLM_DEFAULT;
 		GLM_FUNC_DECL mat(mat<2, 2, T, P> const & m) GLM_DEFAULT;
 		template<precision Q>
 		GLM_FUNC_DECL mat(mat<2, 2, T, Q> const & m);
@@ -66,14 +74,6 @@ namespace glm
 		GLM_FUNC_DECL GLM_EXPLICIT mat(mat<3, 4, T, P> const & x);
 		GLM_FUNC_DECL GLM_EXPLICIT mat(mat<4, 3, T, P> const & x);
 
-		// -- Accesses --
-
-		typedef length_t length_type;
-		GLM_FUNC_DECL static length_type length(){return 2;}
-
-		GLM_FUNC_DECL col_type & operator[](length_type i);
-		GLM_FUNC_DECL col_type const & operator[](length_type i) const;
-
 		// -- Unary arithmetic operators --
 
 		GLM_FUNC_DECL mat<2, 2, T, P> & operator=(mat<2, 2, T, P> const & v) GLM_DEFAULT;

+ 2 - 7
glm/detail/type_mat2x2.inl

@@ -7,15 +7,10 @@ namespace glm
 {
 	// -- Constructors --
 
-#	if !GLM_HAS_DEFAULTED_FUNCTIONS || !defined(GLM_FORCE_NO_CTOR_INIT)
+#	if !GLM_HAS_DEFAULTED_FUNCTIONS
 		template<typename T, precision P>
 		GLM_FUNC_QUALIFIER mat<2, 2, T, P>::mat()
-		{
-#			ifndef GLM_FORCE_NO_CTOR_INIT 
-				this->value[0] = col_type(1, 0);
-				this->value[1] = col_type(0, 1);
-#			endif
-		}
+		{}
 #	endif
 
 #	if !GLM_HAS_DEFAULTED_FUNCTIONS

+ 9 - 9
glm/detail/type_mat2x3.hpp

@@ -25,9 +25,17 @@ namespace glm
 		col_type value[2];
 
 	public:
+		// -- Accesses --
+
+		typedef length_t length_type;
+		GLM_FUNC_DECL static GLM_CONSTEXPR length_type length() { return 2; }
+
+		GLM_FUNC_DECL col_type & operator[](length_type i);
+		GLM_FUNC_DECL col_type const & operator[](length_type i) const;
+
 		// -- Constructors --
 
-		GLM_FUNC_DECL mat() GLM_DEFAULT_CTOR;
+		GLM_FUNC_DECL mat() GLM_DEFAULT;
 		GLM_FUNC_DECL mat(mat<2, 3, T, P> const & m) GLM_DEFAULT;
 		template<precision Q>
 		GLM_FUNC_DECL mat(mat<2, 3, T, Q> const & m);
@@ -67,14 +75,6 @@ namespace glm
 		GLM_FUNC_DECL GLM_EXPLICIT mat(mat<4, 2, T, P> const & x);
 		GLM_FUNC_DECL GLM_EXPLICIT mat(mat<4, 3, T, P> const & x);
 
-		// -- Accesses --
-
-		typedef length_t length_type;
-		GLM_FUNC_DECL static length_type length(){return 2;}
-
-		GLM_FUNC_DECL col_type & operator[](length_type i);
-		GLM_FUNC_DECL col_type const & operator[](length_type i) const;
-
 		// -- Unary arithmetic operators --
 
 		GLM_FUNC_DECL mat<2, 3, T, P> & operator=(mat<2, 3, T, P> const & m) GLM_DEFAULT;

+ 3 - 8
glm/detail/type_mat2x3.inl

@@ -5,15 +5,10 @@ namespace glm
 {
 	// -- Constructors --
 
-#	if !GLM_HAS_DEFAULTED_FUNCTIONS || !defined(GLM_FORCE_NO_CTOR_INIT)
-		template<typename T, precision P> 
+#	if !GLM_HAS_DEFAULTED_FUNCTIONS
+		template<typename T, precision P>
 		GLM_FUNC_QUALIFIER mat<2, 3, T, P>::mat()
-		{
-#			ifndef GLM_FORCE_NO_CTOR_INIT 
-				this->value[0] = col_type(1, 0, 0);
-				this->value[1] = col_type(0, 1, 0);
-#			endif
-		}
+		{}
 #	endif
 
 #	if !GLM_HAS_DEFAULTED_FUNCTIONS

+ 9 - 9
glm/detail/type_mat2x4.hpp

@@ -25,9 +25,17 @@ namespace glm
 		col_type value[2];
 
 	public:
+		// -- Accesses --
+
+		typedef length_t length_type;
+		GLM_FUNC_DECL static GLM_CONSTEXPR length_type length() { return 2; }
+
+		GLM_FUNC_DECL col_type & operator[](length_type i);
+		GLM_FUNC_DECL col_type const & operator[](length_type i) const;
+
 		// -- Constructors --
 
-		GLM_FUNC_DECL mat() GLM_DEFAULT_CTOR;
+		GLM_FUNC_DECL mat() GLM_DEFAULT;
 		GLM_FUNC_DECL mat(mat<2, 4, T, P> const & m) GLM_DEFAULT;
 		template<precision Q>
 		GLM_FUNC_DECL mat(mat<2, 4, T, Q> const & m);
@@ -69,14 +77,6 @@ namespace glm
 		GLM_FUNC_DECL GLM_EXPLICIT mat(mat<4, 2, T, P> const & x);
 		GLM_FUNC_DECL GLM_EXPLICIT mat(mat<4, 3, T, P> const & x);
 
-		// -- Accesses --
-
-		typedef length_t length_type;
-		GLM_FUNC_DECL static length_type length(){return 2;}
-
-		GLM_FUNC_DECL col_type & operator[](length_type i);
-		GLM_FUNC_DECL col_type const & operator[](length_type i) const;
-
 		// -- Unary arithmetic operators --
 
 		GLM_FUNC_DECL mat<2, 4, T, P> & operator=(mat<2, 4, T, P> const & m) GLM_DEFAULT;

+ 2 - 7
glm/detail/type_mat2x4.inl

@@ -5,15 +5,10 @@ namespace glm
 {
 	// -- Constructors --
 
-#	if !GLM_HAS_DEFAULTED_FUNCTIONS || !defined(GLM_FORCE_NO_CTOR_INIT)
+#	if !GLM_HAS_DEFAULTED_FUNCTIONS
 		template<typename T, precision P>
 		GLM_FUNC_QUALIFIER mat<2, 4, T, P>::mat()
-		{
-#			ifndef GLM_FORCE_NO_CTOR_INIT 
-				this->value[0] = col_type(1, 0, 0, 0);
-				this->value[1] = col_type(0, 1, 0, 0);
-#			endif
-		}
+		{}
 #	endif
 
 #	if !GLM_HAS_DEFAULTED_FUNCTIONS

+ 9 - 9
glm/detail/type_mat3x2.hpp

@@ -25,9 +25,17 @@ namespace glm
 		col_type value[3];
 
 	public:
+		// -- Accesses --
+
+		typedef length_t length_type;
+		GLM_FUNC_DECL static GLM_CONSTEXPR length_type length() { return 3; }
+
+		GLM_FUNC_DECL col_type & operator[](length_type i);
+		GLM_FUNC_DECL col_type const & operator[](length_type i) const;
+
 		// -- Constructors --
 
-		GLM_FUNC_DECL mat() GLM_DEFAULT_CTOR;
+		GLM_FUNC_DECL mat() GLM_DEFAULT;
 		GLM_FUNC_DECL mat(mat<3, 2, T, P> const & m) GLM_DEFAULT;
 		template<precision Q>
 		GLM_FUNC_DECL mat(mat<3, 2, T, Q> const & m);
@@ -74,14 +82,6 @@ namespace glm
 		GLM_FUNC_DECL GLM_EXPLICIT mat(mat<4, 2, T, P> const & x);
 		GLM_FUNC_DECL GLM_EXPLICIT mat(mat<4, 3, T, P> const & x);
 
-		// -- Accesses --
-
-		typedef length_t length_type;
-		GLM_FUNC_DECL static length_type length(){return 3;}
-
-		GLM_FUNC_DECL col_type & operator[](length_type i);
-		GLM_FUNC_DECL col_type const & operator[](length_type i) const;
-
 		// -- Unary arithmetic operators --
 
 		GLM_FUNC_DECL mat<3, 2, T, P> & operator=(mat<3, 2, T, P> const & m) GLM_DEFAULT;

+ 2 - 8
glm/detail/type_mat3x2.inl

@@ -5,16 +5,10 @@ namespace glm
 {
 	// -- Constructors --
 
-#	if !GLM_HAS_DEFAULTED_FUNCTIONS || !defined(GLM_FORCE_NO_CTOR_INIT)
+#	if !GLM_HAS_DEFAULTED_FUNCTIONS
 		template<typename T, precision P> 
 		GLM_FUNC_QUALIFIER mat<3, 2, T, P>::mat()
-		{
-#			ifndef GLM_FORCE_NO_CTOR_INIT 
-				this->value[0] = col_type(1, 0);
-				this->value[1] = col_type(0, 1);
-				this->value[2] = col_type(0, 0);
-#			endif
-		}
+		{}
 #	endif
 
 #	if !GLM_HAS_DEFAULTED_FUNCTIONS

+ 9 - 9
glm/detail/type_mat3x3.hpp

@@ -24,9 +24,17 @@ namespace glm
 		col_type value[3];
 
 	public:
+		// -- Accesses --
+
+		typedef length_t length_type;
+		GLM_FUNC_DECL static GLM_CONSTEXPR length_type length() { return 3; }
+
+		GLM_FUNC_DECL col_type & operator[](length_type i);
+		GLM_FUNC_DECL col_type const & operator[](length_type i) const;
+
 		// -- Constructors --
 
-		GLM_FUNC_DECL mat() GLM_DEFAULT_CTOR;
+		GLM_FUNC_DECL mat() GLM_DEFAULT;
 		GLM_FUNC_DECL mat(mat<3, 3, T, P> const & m) GLM_DEFAULT;
 		template<precision Q>
 		GLM_FUNC_DECL mat(mat<3, 3, T, Q> const & m);
@@ -73,14 +81,6 @@ namespace glm
 		GLM_FUNC_DECL GLM_EXPLICIT mat(mat<3, 4, T, P> const & x);
 		GLM_FUNC_DECL GLM_EXPLICIT mat(mat<4, 3, T, P> const & x);
 
-		// -- Accesses --
-
-		typedef length_t length_type;
-		GLM_FUNC_DECL static length_type length(){return 3;}
-
-		GLM_FUNC_DECL col_type & operator[](length_type i);
-		GLM_FUNC_DECL col_type const & operator[](length_type i) const;
-
 		// -- Unary arithmetic operators --
 
 		GLM_FUNC_DECL mat<3, 3, T, P> & operator=(mat<3, 3, T, P> const & m) GLM_DEFAULT;

+ 2 - 8
glm/detail/type_mat3x3.inl

@@ -7,16 +7,10 @@ namespace glm
 {
 	// -- Constructors --
 
-#	if !GLM_HAS_DEFAULTED_FUNCTIONS || !defined(GLM_FORCE_NO_CTOR_INIT)
+#	if !GLM_HAS_DEFAULTED_FUNCTIONS
 		template<typename T, precision P>
 		GLM_FUNC_QUALIFIER mat<3, 3, T, P>::mat()
-		{
-#			ifndef GLM_FORCE_NO_CTOR_INIT 
-				this->value[0] = col_type(1, 0, 0);
-				this->value[1] = col_type(0, 1, 0);
-				this->value[2] = col_type(0, 0, 1);
-#			endif
-		}
+		{}
 #	endif
 
 #	if !GLM_HAS_DEFAULTED_FUNCTIONS

+ 9 - 9
glm/detail/type_mat3x4.hpp

@@ -25,9 +25,17 @@ namespace glm
 		col_type value[3];
 
 	public:
+		// -- Accesses --
+
+		typedef length_t length_type;
+		GLM_FUNC_DECL static GLM_CONSTEXPR length_type length() { return 3; }
+
+		GLM_FUNC_DECL col_type & operator[](length_type i);
+		GLM_FUNC_DECL col_type const & operator[](length_type i) const;
+
 		// -- Constructors --
 
-		GLM_FUNC_DECL mat() GLM_DEFAULT_CTOR;
+		GLM_FUNC_DECL mat() GLM_DEFAULT;
 		GLM_FUNC_DECL mat(mat<3, 4, T, P> const & m) GLM_DEFAULT;
 		template<precision Q>
 		GLM_FUNC_DECL mat(mat<3, 4, T, Q> const & m);
@@ -74,14 +82,6 @@ namespace glm
 		GLM_FUNC_DECL GLM_EXPLICIT mat(mat<4, 2, T, P> const & x);
 		GLM_FUNC_DECL GLM_EXPLICIT mat(mat<4, 3, T, P> const & x);
 
-		// -- Accesses --
-
-		typedef length_t length_type;
-		GLM_FUNC_DECL static length_type length(){return 3;}
-
-		GLM_FUNC_DECL col_type & operator[](length_type i);
-		GLM_FUNC_DECL col_type const & operator[](length_type i) const;
-
 		// -- Unary arithmetic operators --
 
 		GLM_FUNC_DECL mat<3, 4, T, P> & operator=(mat<3, 4, T, P> const & m) GLM_DEFAULT;

+ 2 - 8
glm/detail/type_mat3x4.inl

@@ -5,16 +5,10 @@ namespace glm
 {
 	// -- Constructors --
 
-#	if !GLM_HAS_DEFAULTED_FUNCTIONS || !defined(GLM_FORCE_NO_CTOR_INIT)
+#	if !GLM_HAS_DEFAULTED_FUNCTIONS
 		template<typename T, precision P>
 		GLM_FUNC_QUALIFIER mat<3, 4, T, P>::mat()
-		{
-#			ifndef GLM_FORCE_NO_CTOR_INIT 
-				this->value[0] = col_type(1, 0, 0, 0);
-				this->value[1] = col_type(0, 1, 0, 0);
-				this->value[2] = col_type(0, 0, 1, 0);
-#			endif
-		}
+		{}
 #	endif
 
 #	if !GLM_HAS_DEFAULTED_FUNCTIONS

+ 9 - 9
glm/detail/type_mat4x2.hpp

@@ -25,9 +25,17 @@ namespace glm
 		col_type value[4];
 
 	public:
+		// -- Accesses --
+
+		typedef length_t length_type;
+		GLM_FUNC_DECL static GLM_CONSTEXPR length_type length() { return 4; }
+
+		GLM_FUNC_DECL col_type & operator[](length_type i);
+		GLM_FUNC_DECL col_type const & operator[](length_type i) const;
+
 		// -- Constructors --
 
-		GLM_FUNC_DECL mat() GLM_DEFAULT_CTOR;
+		GLM_FUNC_DECL mat() GLM_DEFAULT;
 		GLM_FUNC_DECL mat(mat<4, 2, T, P> const & m) GLM_DEFAULT;
 		template<precision Q>
 		GLM_FUNC_DECL mat(mat<4, 2, T, Q> const & m);
@@ -79,14 +87,6 @@ namespace glm
 		GLM_FUNC_DECL GLM_EXPLICIT mat(mat<4, 3, T, P> const & x);
 		GLM_FUNC_DECL GLM_EXPLICIT mat(mat<3, 4, T, P> const & x);
 
-		// -- Accesses --
-
-		typedef length_t length_type;
-		GLM_FUNC_DECL static length_type length(){return 4;}
-
-		GLM_FUNC_DECL col_type & operator[](length_type i);
-		GLM_FUNC_DECL col_type const & operator[](length_type i) const;
-
 		// -- Unary arithmetic operators --
 
 		GLM_FUNC_DECL mat<4, 2, T, P> & operator=(mat<4, 2, T, P> const & m) GLM_DEFAULT;

+ 2 - 9
glm/detail/type_mat4x2.inl

@@ -5,17 +5,10 @@ namespace glm
 {
 	// -- Constructors --
 
-#	if !GLM_HAS_DEFAULTED_FUNCTIONS || !defined(GLM_FORCE_NO_CTOR_INIT)
+#	if !GLM_HAS_DEFAULTED_FUNCTIONS
 		template<typename T, precision P> 
 		GLM_FUNC_QUALIFIER mat<4, 2, T, P>::mat()
-		{
-#			ifndef GLM_FORCE_NO_CTOR_INIT 
-				this->value[0] = col_type(1, 0);
-				this->value[1] = col_type(0, 1);
-				this->value[2] = col_type(0, 0);
-				this->value[3] = col_type(0, 0);
-#			endif
-		}
+		{}
 #	endif
 
 #	if !GLM_HAS_DEFAULTED_FUNCTIONS

+ 9 - 9
glm/detail/type_mat4x3.hpp

@@ -25,9 +25,17 @@ namespace glm
 		col_type value[4];
 
 	public:
+		// -- Accesses --
+
+		typedef length_t length_type;
+		GLM_FUNC_DECL static GLM_CONSTEXPR length_type length() { return 4; }
+
+		GLM_FUNC_DECL col_type & operator[](length_type i);
+		GLM_FUNC_DECL col_type const & operator[](length_type i) const;
+
 		// -- Constructors --
 
-		GLM_FUNC_DECL mat() GLM_DEFAULT_CTOR;
+		GLM_FUNC_DECL mat() GLM_DEFAULT;
 		GLM_FUNC_DECL mat(mat<4, 3, T, P> const & m) GLM_DEFAULT;
 		template<precision Q>
 		GLM_FUNC_DECL mat(mat<4, 3, T, Q> const & m);
@@ -79,14 +87,6 @@ namespace glm
 		GLM_FUNC_DECL GLM_EXPLICIT mat(mat<4, 2, T, P> const & x);
 		GLM_FUNC_DECL GLM_EXPLICIT mat(mat<3, 4, T, P> const & x);
 
-		// -- Accesses --
-
-		typedef length_t length_type;
-		GLM_FUNC_DECL static length_type length(){return 4;}
-
-		GLM_FUNC_DECL col_type & operator[](length_type i);
-		GLM_FUNC_DECL col_type const & operator[](length_type i) const;
-
 		// -- Unary arithmetic operators --
 
 		GLM_FUNC_DECL mat<4, 3, T, P> & operator=(mat<4, 3, T, P> const & m) GLM_DEFAULT;

+ 2 - 9
glm/detail/type_mat4x3.inl

@@ -5,17 +5,10 @@ namespace glm
 {
 	// -- Constructors --
 
-#	if !GLM_HAS_DEFAULTED_FUNCTIONS || !defined(GLM_FORCE_NO_CTOR_INIT)
+#	if !GLM_HAS_DEFAULTED_FUNCTIONS
 		template<typename T, precision P>
 		GLM_FUNC_QUALIFIER mat<4, 3, T, P>::mat()
-		{
-#			ifndef GLM_FORCE_NO_CTOR_INIT 
-				this->value[0] = col_type(1, 0, 0);
-				this->value[1] = col_type(0, 1, 0);
-				this->value[2] = col_type(0, 0, 1);
-				this->value[3] = col_type(0, 0, 0);
-#			endif
-		}
+		{}
 #	endif
 
 #	if !GLM_HAS_DEFAULTED_FUNCTIONS

+ 2 - 2
glm/detail/type_mat4x4.hpp

@@ -27,14 +27,14 @@ namespace glm
 		// -- Accesses --
 
 		typedef length_t length_type;
-		GLM_FUNC_DECL static length_type length(){return 4;}
+		GLM_FUNC_DECL static GLM_CONSTEXPR length_type length(){return 4;}
 
 		GLM_FUNC_DECL col_type & operator[](length_type i);
 		GLM_FUNC_DECL col_type const & operator[](length_type i) const;
 
 		// -- Constructors --
 
-		GLM_FUNC_DECL mat() GLM_DEFAULT_CTOR;
+		GLM_FUNC_DECL mat() GLM_DEFAULT;
 		GLM_FUNC_DECL mat(mat<4, 4, T, P> const& m) GLM_DEFAULT;
 		template<precision Q>
 		GLM_FUNC_DECL mat(mat<4, 4, T, Q> const& m);

+ 2 - 9
glm/detail/type_mat4x4.inl

@@ -7,17 +7,10 @@ namespace glm
 {
 	// -- Constructors --
 
-#	if !GLM_HAS_DEFAULTED_FUNCTIONS || !defined(GLM_FORCE_NO_CTOR_INIT)
+#	if !GLM_HAS_DEFAULTED_FUNCTIONS
 		template<typename T, precision P>
 		GLM_FUNC_QUALIFIER mat<4, 4, T, P>::mat()
-		{
-#			ifndef GLM_FORCE_NO_CTOR_INIT 
-				this->value[0] = col_type(1, 0, 0, 0);
-				this->value[1] = col_type(0, 1, 0, 0);
-				this->value[2] = col_type(0, 0, 1, 0);
-				this->value[3] = col_type(0, 0, 0, 1);
-#			endif
-		}
+		{}
 #	endif
 
 #	if !GLM_HAS_DEFAULTED_FUNCTIONS

+ 2 - 2
glm/detail/type_vec1.hpp

@@ -78,14 +78,14 @@ namespace glm
 
 		/// Return the count of components of the vector
 		typedef length_t length_type;
-		GLM_FUNC_DECL static length_type length(){return 1;}
+		GLM_FUNC_DECL static GLM_CONSTEXPR length_type length(){return 1;}
 
 		GLM_FUNC_DECL T & operator[](length_type i);
 		GLM_FUNC_DECL T const & operator[](length_type i) const;
 
 		// -- Implicit basic constructors --
 
-		GLM_FUNC_DECL GLM_CONSTEXPR_CTOR vec() GLM_DEFAULT_CTOR;
+		GLM_FUNC_DECL GLM_CONSTEXPR_CTOR vec() GLM_DEFAULT;
 		GLM_FUNC_DECL GLM_CONSTEXPR_CTOR vec(vec const& v) GLM_DEFAULT;
 		template<precision Q>
 		GLM_FUNC_DECL GLM_CONSTEXPR_CTOR vec(vec<1, T, Q> const& v);

+ 1 - 4
glm/detail/type_vec1.inl

@@ -5,12 +5,9 @@ namespace glm
 {
 	// -- Implicit basic constructors --
 
-#	if !GLM_HAS_DEFAULTED_FUNCTIONS || !defined(GLM_FORCE_NO_CTOR_INIT)
+#	if !GLM_HAS_DEFAULTED_FUNCTIONS
 		template<typename T, precision P>
 		GLM_FUNC_QUALIFIER GLM_CONSTEXPR_CTOR vec<1, T, P>::vec()
-#			ifndef GLM_FORCE_NO_CTOR_INIT
-				: x(0)
-#			endif
 		{}
 #	endif//!GLM_HAS_DEFAULTED_FUNCTIONS
 

+ 2 - 2
glm/detail/type_vec2.hpp

@@ -79,14 +79,14 @@ namespace glm
 
 		/// Return the count of components of the vector
 		typedef length_t length_type;
-		GLM_FUNC_DECL static length_type length(){return 2;}
+		GLM_FUNC_DECL static GLM_CONSTEXPR length_type length(){return 2;}
 
 		GLM_FUNC_DECL T& operator[](length_type i);
 		GLM_FUNC_DECL T const& operator[](length_type i) const;
 
 		// -- Implicit basic constructors --
 
-		GLM_FUNC_DECL GLM_CONSTEXPR_CTOR vec() GLM_DEFAULT_CTOR;
+		GLM_FUNC_DECL GLM_CONSTEXPR_CTOR vec() GLM_DEFAULT;
 		GLM_FUNC_DECL GLM_CONSTEXPR_CTOR vec(vec const& v) GLM_DEFAULT;
 		template<precision Q>
 		GLM_FUNC_DECL GLM_CONSTEXPR_CTOR vec(vec<2, T, Q> const& v);

+ 1 - 4
glm/detail/type_vec2.inl

@@ -5,12 +5,9 @@ namespace glm
 {
 	// -- Implicit basic constructors --
 
-#	if !GLM_HAS_DEFAULTED_FUNCTIONS || !defined(GLM_FORCE_NO_CTOR_INIT)
+#	if !GLM_HAS_DEFAULTED_FUNCTIONS
 		template<typename T, precision P>
 		GLM_FUNC_QUALIFIER GLM_CONSTEXPR_CTOR vec<2, T, P>::vec()
-#			ifndef GLM_FORCE_NO_CTOR_INIT
-				: x(0), y(0)
-#			endif
 		{}
 #	endif//!GLM_HAS_DEFAULTED_FUNCTIONS
 

+ 2 - 2
glm/detail/type_vec3.hpp

@@ -79,14 +79,14 @@ namespace glm
 
 		/// Return the count of components of the vector
 		typedef length_t length_type;
-		GLM_FUNC_DECL static length_type length(){return 3;}
+		GLM_FUNC_DECL static GLM_CONSTEXPR length_type length(){return 3;}
 
 		GLM_FUNC_DECL T & operator[](length_type i);
 		GLM_FUNC_DECL T const & operator[](length_type i) const;
 
 		// -- Implicit basic constructors --
 
-		GLM_FUNC_DECL GLM_CONSTEXPR_CTOR vec() GLM_DEFAULT_CTOR;
+		GLM_FUNC_DECL GLM_CONSTEXPR_CTOR vec() GLM_DEFAULT;
 		GLM_FUNC_DECL GLM_CONSTEXPR_CTOR vec(vec const & v) GLM_DEFAULT;
 		template<precision Q>
 		GLM_FUNC_DECL GLM_CONSTEXPR_CTOR vec(vec<3, T, Q> const & v);

+ 1 - 4
glm/detail/type_vec3.inl

@@ -5,12 +5,9 @@ namespace glm
 {
 	// -- Implicit basic constructors --
 
-#	if !GLM_HAS_DEFAULTED_FUNCTIONS || !defined(GLM_FORCE_NO_CTOR_INIT)
+#	if !GLM_HAS_DEFAULTED_FUNCTIONS
 		template<typename T, precision P>
 		GLM_FUNC_QUALIFIER GLM_CONSTEXPR_CTOR vec<3, T, P>::vec()
-#			ifndef GLM_FORCE_NO_CTOR_INIT 
-				: x(0), y(0), z(0)
-#			endif
 		{}
 #	endif//!GLM_HAS_DEFAULTED_FUNCTIONS
 

+ 2 - 2
glm/detail/type_vec4.hpp

@@ -82,14 +82,14 @@ namespace glm
 
 		/// Return the count of components of the vector
 		typedef length_t length_type;
-		GLM_FUNC_DECL static length_type length(){return 4;}
+		GLM_FUNC_DECL static GLM_CONSTEXPR length_type length(){return 4;}
 
 		GLM_FUNC_DECL T & operator[](length_type i);
 		GLM_FUNC_DECL T const & operator[](length_type i) const;
 
 		// -- Implicit basic constructors --
 
-		GLM_FUNC_DECL GLM_CONSTEXPR_SIMD vec() GLM_DEFAULT_CTOR;
+		GLM_FUNC_DECL GLM_CONSTEXPR_SIMD vec() GLM_DEFAULT;
 		GLM_FUNC_DECL GLM_CONSTEXPR_SIMD vec(vec<4, T, P> const& v) GLM_DEFAULT;
 		template<precision Q>
 		GLM_FUNC_DECL GLM_CONSTEXPR_SIMD vec(vec<4, T, Q> const& v);

+ 1 - 4
glm/detail/type_vec4.inl

@@ -154,12 +154,9 @@ namespace detail
 
 	// -- Implicit basic constructors --
 
-#	if !GLM_HAS_DEFAULTED_FUNCTIONS || !defined(GLM_FORCE_NO_CTOR_INIT)
+#	if !GLM_HAS_DEFAULTED_FUNCTIONS
 		template<typename T, precision P>
 		GLM_FUNC_QUALIFIER GLM_CONSTEXPR_SIMD vec<4, T, P>::vec()
-#			ifndef GLM_FORCE_NO_CTOR_INIT
-				: x(0), y(0), z(0), w(0)
-#			endif
 		{}
 #	endif//!GLM_HAS_DEFAULTED_FUNCTIONS
 

+ 131 - 7
glm/gtc/packing.hpp

@@ -518,7 +518,7 @@ namespace glm
 	template<typename uintType, length_t L, typename floatType, precision P>
 	GLM_FUNC_DECL vec<L, uintType, P> packUnorm(vec<L, floatType, P> const & v);
 
-	/// Convert each unsigned integer components of a vector to normalized floating-point values.
+	/// Convert a packed integer to a normalized floating-point vector.
 	/// 
 	/// @see gtc_packing
 	/// @see vecType<L, intType, P> packUnorm(vecType<L, floatType, P> const & v)
@@ -532,7 +532,7 @@ namespace glm
 	template<typename intType, length_t L, typename floatType, precision P>
 	GLM_FUNC_DECL vec<L, intType, P> packSnorm(vec<L, floatType, P> const & v);
 
-	/// Convert each signed integer components of a vector to normalized floating-point values.
+	/// Convert a packed integer to a normalized floating-point vector.
 	/// 
 	/// @see gtc_packing
 	/// @see vecType<L, intType, P> packSnorm(vecType<L, floatType, P> const & v)
@@ -545,7 +545,7 @@ namespace glm
 	/// @see vec2 unpackUnorm2x4(uint8 p)
 	GLM_FUNC_DECL uint8 packUnorm2x4(vec2 const & v);
 
-	/// Convert each unsigned integer components of a vector to normalized floating-point values.
+	/// Convert a packed integer to a normalized floating-point vector.
 	/// 
 	/// @see gtc_packing
 	/// @see uint8 packUnorm2x4(vec2 const & v)
@@ -557,7 +557,7 @@ namespace glm
 	/// @see vec4 unpackUnorm4x4(uint16 p)
 	GLM_FUNC_DECL uint16 packUnorm4x4(vec4 const & v);
 
-	/// Convert each unsigned integer components of a vector to normalized floating-point values.
+	/// Convert a packed integer to a normalized floating-point vector.
 	/// 
 	/// @see gtc_packing
 	/// @see uint16 packUnorm4x4(vec4 const & v)
@@ -569,7 +569,7 @@ namespace glm
 	/// @see vec3 unpackUnorm1x5_1x6_1x5(uint16 p)
 	GLM_FUNC_DECL uint16 packUnorm1x5_1x6_1x5(vec3 const & v);
 
-	/// Convert each unsigned integer components of a vector to normalized floating-point values.
+	/// Convert a packed integer to a normalized floating-point vector.
 	/// 
 	/// @see gtc_packing
 	/// @see uint16 packUnorm1x5_1x6_1x5(vec3 const & v)
@@ -581,7 +581,7 @@ namespace glm
 	/// @see vec4 unpackUnorm3x5_1x1(uint16 p)
 	GLM_FUNC_DECL uint16 packUnorm3x5_1x1(vec4 const & v);
 
-	/// Convert each unsigned integer components of a vector to normalized floating-point values.
+	/// Convert a packed integer to a normalized floating-point vector.
 	/// 
 	/// @see gtc_packing
 	/// @see uint16 packUnorm3x5_1x1(vec4 const & v)
@@ -593,11 +593,135 @@ namespace glm
 	/// @see vec3 unpackUnorm2x3_1x2(uint8 p)
 	GLM_FUNC_DECL uint8 packUnorm2x3_1x2(vec3 const & v);
 
-	/// Convert each unsigned integer components of a vector to normalized floating-point values.
+	/// Convert a packed integer to a normalized floating-point vector.
 	/// 
 	/// @see gtc_packing
 	/// @see uint8 packUnorm2x3_1x2(vec3 const & v)
 	GLM_FUNC_DECL vec3 unpackUnorm2x3_1x2(uint8 p);
+
+
+
+	/// Convert each component from an integer vector into a packed unsigned integer.
+	///
+	/// @see gtc_packing
+	/// @see i8vec2 unpackInt2x8(int16 p)
+	GLM_FUNC_DECL int16 packInt2x8(i8vec2 const& v);
+
+	/// Convert a packed integer into an integer vector.
+	/// 
+	/// @see gtc_packing
+	/// @see int16 packInt2x8(i8vec2 const& v)
+	GLM_FUNC_DECL i8vec2 unpackInt2x8(int16 p);
+
+	/// Convert each component from an integer vector into a packed unsigned integer.
+	///
+	/// @see gtc_packing
+	/// @see u8vec2 unpackInt2x8(uint16 p)
+	GLM_FUNC_DECL uint16 packUint2x8(u8vec2 const& v);
+
+	/// Convert a packed integer into an integer vector.
+	/// 
+	/// @see gtc_packing
+	/// @see uint16 packInt2x8(u8vec2 const& v)
+	GLM_FUNC_DECL u8vec2 unpackUint2x8(uint16 p);
+
+	/// Convert each component from an integer vector into a packed unsigned integer.
+	///
+	/// @see gtc_packing
+	/// @see i8vec4 unpackInt4x8(int32 p)
+	GLM_FUNC_DECL int32 packInt4x8(i8vec4 const& v);
+
+	/// Convert a packed integer into an integer vector.
+	/// 
+	/// @see gtc_packing
+	/// @see int32 packInt2x8(i8vec4 const& v)
+	GLM_FUNC_DECL i8vec4 unpackInt4x8(int32 p);
+
+	/// Convert each component from an integer vector into a packed unsigned integer.
+	///
+	/// @see gtc_packing
+	/// @see u8vec4 unpackUint4x8(uint32 p)
+	GLM_FUNC_DECL uint32 packUint4x8(u8vec4 const& v);
+
+	/// Convert a packed integer into an integer vector.
+	/// 
+	/// @see gtc_packing
+	/// @see uint32 packUint4x8(u8vec2 const& v)
+	GLM_FUNC_DECL u8vec4 unpackUint4x8(uint32 p);
+
+	/// Convert each component from an integer vector into a packed unsigned integer.
+	///
+	/// @see gtc_packing
+	/// @see i16vec2 unpackInt2x16(int p)
+	GLM_FUNC_DECL int packInt2x16(i16vec2 const& v);
+
+	/// Convert a packed integer into an integer vector.
+	/// 
+	/// @see gtc_packing
+	/// @see int packInt2x16(i16vec2 const& v)
+	GLM_FUNC_DECL i16vec2 unpackInt2x16(int p);
+
+	/// Convert each component from an integer vector into a packed unsigned integer.
+	///
+	/// @see gtc_packing
+	/// @see i16vec4 unpackInt4x16(int64 p)
+	GLM_FUNC_DECL int64 packInt4x16(i16vec4 const& v);
+
+	/// Convert a packed integer into an integer vector.
+	/// 
+	/// @see gtc_packing
+	/// @see int64 packInt4x16(i16vec4 const& v)
+	GLM_FUNC_DECL i16vec4 unpackInt4x16(int64 p);
+
+	/// Convert each component from an integer vector into a packed unsigned integer.
+	///
+	/// @see gtc_packing
+	/// @see u16vec2 unpackUint2x16(uint p)
+	GLM_FUNC_DECL uint packUint2x16(u16vec2 const& v);
+
+	/// Convert a packed integer into an integer vector.
+	/// 
+	/// @see gtc_packing
+	/// @see uint packUint2x16(u16vec2 const& v)
+	GLM_FUNC_DECL u16vec2 unpackUint2x16(uint p);
+
+	/// Convert each component from an integer vector into a packed unsigned integer.
+	///
+	/// @see gtc_packing
+	/// @see u16vec4 unpackUint4x16(uint64 p)
+	GLM_FUNC_DECL uint64 packUint4x16(u16vec4 const& v);
+
+	/// Convert a packed integer into an integer vector.
+	/// 
+	/// @see gtc_packing
+	/// @see uint64 packUint4x16(u16vec4 const& v)
+	GLM_FUNC_DECL u16vec4 unpackUint4x16(uint64 p);
+
+	/// Convert each component from an integer vector into a packed unsigned integer.
+	///
+	/// @see gtc_packing
+	/// @see i32vec2 unpackInt2x32(int p)
+	GLM_FUNC_DECL int64 packInt2x32(i32vec2 const& v);
+
+	/// Convert a packed integer into an integer vector.
+	/// 
+	/// @see gtc_packing
+	/// @see int packInt2x16(i32vec2 const& v)
+	GLM_FUNC_DECL i32vec2 unpackInt2x32(int64 p);
+
+	/// Convert each component from an integer vector into a packed unsigned integer.
+	///
+	/// @see gtc_packing
+	/// @see u32vec2 unpackUint2x32(int p)
+	GLM_FUNC_DECL uint64 packUint2x32(u32vec2 const& v);
+
+	/// Convert a packed integer into an integer vector.
+	/// 
+	/// @see gtc_packing
+	/// @see int packUint2x16(u32vec2 const& v)
+	GLM_FUNC_DECL u32vec2 unpackUint2x32(uint64 p);
+
+
 	/// @}
 }// namespace glm
 

+ 140 - 0
glm/gtc/packing.inl

@@ -793,5 +793,145 @@ namespace detail
 		Unpack.pack = v;
 		return vec3(Unpack.data.x, Unpack.data.y, Unpack.data.z) * ScaleFactor;
 	}
+
+	GLM_FUNC_QUALIFIER int16 packInt2x8(i8vec2 const& v)
+	{
+		int16 Pack = 0;
+		memcpy(&Pack, &v, sizeof(Pack));
+		return Pack;
+	}
+
+	GLM_FUNC_QUALIFIER i8vec2 unpackInt2x8(int16 p)
+	{
+		i8vec2 Unpack(uninitialize);
+		memcpy(&Unpack, &p, sizeof(Unpack));
+		return Unpack;
+	}
+
+	GLM_FUNC_QUALIFIER uint16 packUint2x8(u8vec2 const& v)
+	{
+		uint16 Pack = 0;
+		memcpy(&Pack, &v, sizeof(Pack));
+		return Pack;
+	}
+
+	GLM_FUNC_QUALIFIER u8vec2 unpackUint2x8(uint16 p)
+	{
+		u8vec2 Unpack(uninitialize);
+		memcpy(&Unpack, &p, sizeof(Unpack));
+		return Unpack;
+	}
+
+	GLM_FUNC_QUALIFIER int32 packInt4x8(i8vec4 const& v)
+	{
+		int32 Pack = 0;
+		memcpy(&Pack, &v, sizeof(Pack));
+		return Pack;
+	}
+
+	GLM_FUNC_QUALIFIER i8vec4 unpackInt4x8(int32 p)
+	{
+		i8vec4 Unpack(uninitialize);
+		memcpy(&Unpack, &p, sizeof(Unpack));
+		return Unpack;
+	}
+
+	GLM_FUNC_QUALIFIER uint32 packUint4x8(u8vec4 const& v)
+	{
+		uint32 Pack = 0;
+		memcpy(&Pack, &v, sizeof(Pack));
+		return Pack;
+	}
+
+	GLM_FUNC_QUALIFIER u8vec4 unpackUint4x8(uint32 p)
+	{
+		u8vec4 Unpack(uninitialize);
+		memcpy(&Unpack, &p, sizeof(Unpack));
+		return Unpack;
+	}
+
+	GLM_FUNC_QUALIFIER int packInt2x16(i16vec2 const& v)
+	{
+		int Pack = 0;
+		memcpy(&Pack, &v, sizeof(Pack));
+		return Pack;
+	}
+
+	GLM_FUNC_QUALIFIER i16vec2 unpackInt2x16(int p)
+	{
+		i16vec2 Unpack(uninitialize);
+		memcpy(&Unpack, &p, sizeof(Unpack));
+		return Unpack;
+	}
+
+	GLM_FUNC_QUALIFIER int64 packInt4x16(i16vec4 const& v)
+	{
+		int64 Pack = 0;
+		memcpy(&Pack, &v, sizeof(Pack));
+		return Pack;
+	}
+
+	GLM_FUNC_QUALIFIER i16vec4 unpackInt4x16(int64 p)
+	{
+		i16vec4 Unpack(uninitialize);
+		memcpy(&Unpack, &p, sizeof(Unpack));
+		return Unpack;
+	}
+
+	GLM_FUNC_QUALIFIER uint packUint2x16(u16vec2 const& v)
+	{
+		uint Pack = 0;
+		memcpy(&Pack, &v, sizeof(Pack));
+		return Pack;
+	}
+
+	GLM_FUNC_QUALIFIER u16vec2 unpackUint2x16(uint p)
+	{
+		u16vec2 Unpack(uninitialize);
+		memcpy(&Unpack, &p, sizeof(Unpack));
+		return Unpack;
+	}
+
+	GLM_FUNC_QUALIFIER uint64 packUint4x16(u16vec4 const& v)
+	{
+		uint64 Pack = 0;
+		memcpy(&Pack, &v, sizeof(Pack));
+		return Pack;
+	}
+
+	GLM_FUNC_QUALIFIER u16vec4 unpackUint4x16(uint64 p)
+	{
+		u16vec4 Unpack(uninitialize);
+		memcpy(&Unpack, &p, sizeof(Unpack));
+		return Unpack;
+	}
+
+	GLM_FUNC_QUALIFIER int64 packInt2x32(i32vec2 const& v)
+	{
+		int64 Pack = 0;
+		memcpy(&Pack, &v, sizeof(Pack));
+		return Pack;
+	}
+
+	GLM_FUNC_QUALIFIER i32vec2 unpackInt2x32(int64 p)
+	{
+		i32vec2 Unpack(uninitialize);
+		memcpy(&Unpack, &p, sizeof(Unpack));
+		return Unpack;
+	}
+
+	GLM_FUNC_QUALIFIER uint64 packUint2x32(u32vec2 const& v)
+	{
+		uint64 Pack = 0;
+		memcpy(&Pack, &v, sizeof(Pack));
+		return Pack;
+	}
+
+	GLM_FUNC_QUALIFIER u32vec2 unpackUint2x32(uint64 p)
+	{
+		u32vec2 Unpack(uninitialize);
+		memcpy(&Unpack, &p, sizeof(Unpack));
+		return Unpack;
+	}
 }//namespace glm
 

+ 2 - 2
glm/gtc/quaternion.hpp

@@ -70,14 +70,14 @@ namespace glm
 
 		typedef length_t length_type;
 		/// Return the count of components of a quaternion
-		GLM_FUNC_DECL static length_type length(){return 4;}
+		GLM_FUNC_DECL static GLM_CONSTEXPR length_type length(){return 4;}
 
 		GLM_FUNC_DECL T & operator[](length_type i);
 		GLM_FUNC_DECL T const & operator[](length_type i) const;
 
 		// -- Implicit basic constructors --
 
-		GLM_FUNC_DECL GLM_CONSTEXPR tquat() GLM_DEFAULT_CTOR;
+		GLM_FUNC_DECL GLM_CONSTEXPR tquat() GLM_DEFAULT;
 		GLM_FUNC_DECL GLM_CONSTEXPR tquat(tquat<T, P> const& q) GLM_DEFAULT;
 		template<precision Q>
 		GLM_FUNC_DECL GLM_CONSTEXPR tquat(tquat<T, Q> const& q);

+ 5 - 8
glm/gtc/quaternion.inl

@@ -83,12 +83,9 @@ namespace detail
 
 	// -- Implicit basic constructors --
 
-#	if !GLM_HAS_DEFAULTED_FUNCTIONS || !defined(GLM_FORCE_NO_CTOR_INIT)
+#	if !GLM_HAS_DEFAULTED_FUNCTIONS
 		template<typename T, precision P>
 		GLM_FUNC_QUALIFIER GLM_CONSTEXPR tquat<T, P>::tquat()
-#			ifndef GLM_FORCE_NO_CTOR_INIT
-				: x(0), y(0), z(0), w(1)
-#			endif
 		{}
 #	endif
 
@@ -294,19 +291,19 @@ namespace detail
 	// -- Binary operators --
 
 	template<typename T, precision P>
-	GLM_FUNC_QUALIFIER tquat<T, P> operator+(tquat<T, P> const & q,	tquat<T, P> const & p)
+	GLM_FUNC_QUALIFIER tquat<T, P> operator+(tquat<T, P> const & q, tquat<T, P> const & p)
 	{
 		return tquat<T, P>(q) += p;
 	}
 
 	template<typename T, precision P>
-	GLM_FUNC_QUALIFIER tquat<T, P> operator*(tquat<T, P> const & q,	tquat<T, P> const & p)
+	GLM_FUNC_QUALIFIER tquat<T, P> operator*(tquat<T, P> const & q, tquat<T, P> const & p)
 	{
 		return tquat<T, P>(q) *= p;
 	}
 
 	template<typename T, precision P>
-	GLM_FUNC_QUALIFIER vec<3, T, P> operator*(tquat<T, P> const & q,	vec<3, T, P> const & v)
+	GLM_FUNC_QUALIFIER vec<3, T, P> operator*(tquat<T, P> const & q, vec<3, T, P> const & v)
 	{
 		vec<3, T, P> const QuatVector(q.x, q.y, q.z);
 		vec<3, T, P> const uv(glm::cross(QuatVector, v));
@@ -380,7 +377,7 @@ namespace detail
 	{
 		T len = length(q);
 		if(len <= T(0)) // Problem
-			return tquat<T, P>(1, 0, 0, 0);
+			return tquat<T, P>(static_cast<T>(1), static_cast<T>(0), static_cast<T>(0), static_cast<T>(0));
 		T oneOverLen = T(1) / len;
 		return tquat<T, P>(q.w * oneOverLen, q.x * oneOverLen, q.y * oneOverLen, q.z * oneOverLen);
 	}

+ 2 - 2
glm/gtx/dual_quaternion.hpp

@@ -49,14 +49,14 @@ namespace glm
 
 		typedef length_t length_type;
 		/// Return the count of components of a dual quaternion
-		GLM_FUNC_DECL static length_type length(){return 2;}
+		GLM_FUNC_DECL static GLM_CONSTEXPR length_type length(){return 2;}
 
 		GLM_FUNC_DECL part_type & operator[](length_type i);
 		GLM_FUNC_DECL part_type const & operator[](length_type i) const;
 
 		// -- Implicit basic constructors --
 
-		GLM_FUNC_DECL GLM_CONSTEXPR tdualquat() GLM_DEFAULT_CTOR;
+		GLM_FUNC_DECL GLM_CONSTEXPR tdualquat() GLM_DEFAULT;
 		GLM_FUNC_DECL GLM_CONSTEXPR tdualquat(tdualquat<T, P> const & d) GLM_DEFAULT;
 		template<precision Q>
 		GLM_FUNC_DECL GLM_CONSTEXPR tdualquat(tdualquat<T, Q> const & d);

+ 1 - 5
glm/gtx/dual_quaternion.inl

@@ -24,13 +24,9 @@ namespace glm
 
 	// -- Implicit basic constructors --
 
-#	if !GLM_HAS_DEFAULTED_FUNCTIONS || !defined(GLM_FORCE_NO_CTOR_INIT)
+#	if !GLM_HAS_DEFAULTED_FUNCTIONS
 		template<typename T, precision P>
 		GLM_FUNC_QUALIFIER GLM_CONSTEXPR tdualquat<T, P>::tdualquat()
-#			ifndef GLM_FORCE_NO_CTOR_INIT 
-				: real(tquat<T, P>())
-				, dual(tquat<T, P>(0, 0, 0, 0))
-#			endif
 		{}
 #	endif
 

+ 1 - 1
glm/gtx/integer.hpp

@@ -31,7 +31,7 @@ namespace glm
 
 	//! Returns x raised to the y power. 
 	//! From GLM_GTX_integer extension.
-	GLM_FUNC_DECL int pow(int x, int y);
+	GLM_FUNC_DECL int pow(int x, uint y);
 
 	//! Returns the positive square root of x.
 	//! From GLM_GTX_integer extension.

+ 6 - 2
glm/gtx/integer.inl

@@ -4,10 +4,11 @@
 namespace glm
 {
 	// pow
-	GLM_FUNC_QUALIFIER int pow(int x, int y)
+	GLM_FUNC_QUALIFIER int pow(int x, uint y)
 	{
 		if(y == 0)
-			return 1;
+			return x >= 0 ? 1 : -1;
+
 		int result = x;
 		for(int i = 1; i < y; ++i)
 			result *= x;
@@ -111,6 +112,9 @@ namespace detail
 
 	GLM_FUNC_QUALIFIER uint pow(uint x, uint y)
 	{
+		if (y == 0)
+			return 1u;
+
 		uint result = x;
 		for(uint i = 1; i < y; ++i)
 			result *= x;

+ 65 - 0
glm/gtx/matrix_factorisation.hpp

@@ -0,0 +1,65 @@
+/// @ref gtx_matrix_factorisation
+/// @file glm/gtx/matrix_factorisation.hpp
+///
+/// @see core (dependence)
+///
+/// @defgroup gtx_matrix_factorisation GLM_GTX_matrix_factorisation
+/// @ingroup gtx
+///
+/// @brief Functions to factor matrices in various forms
+///
+/// <glm/gtx/matrix_factorisation.hpp> need to be included to use these functionalities.
+
+#pragma once
+
+// Dependency:
+#include "../glm.hpp"
+
+#ifndef GLM_ENABLE_EXPERIMENTAL
+#	error "GLM: GLM_GTX_matrix_factorisation is an experimental extension and may change in the future. Use #define GLM_ENABLE_EXPERIMENTAL before including it, if you really want to use it."
+#endif
+
+#if GLM_MESSAGES == GLM_MESSAGES_ENABLED && !defined(GLM_EXT_INCLUDED)
+#	pragma message("GLM: GLM_GTX_matrix_factorisation extension included")
+#endif
+
+/*
+Suggestions:
+ - Move helper functions flipud and fliplr to another file: They may be helpful in more general circumstances.
+ - Implement other types of matrix factorisation, such as: QL and LQ, L(D)U, eigendecompositions, etc...
+*/
+
+namespace glm
+{
+	/// @addtogroup gtx_matrix_factorisation
+	/// @{
+
+	/// Flips the matrix rows up and down.
+	/// From GLM_GTX_matrix_factorisation extension.
+	template <length_t C, length_t R, typename T, precision P, template<length_t, length_t, typename, precision> class matType>
+	GLM_FUNC_DECL matType<C, R, T, P> flipud(matType<C, R, T, P> const& in);
+
+	/// Flips the matrix columns right and left.
+	/// From GLM_GTX_matrix_factorisation extension.
+	template <length_t C, length_t R, typename T, precision P, template<length_t, length_t, typename, precision> class matType>
+	GLM_FUNC_DECL matType<C, R, T, P> fliplr(matType<C, R, T, P> const& in);
+
+	/// Performs QR factorisation of a matrix.
+	/// Returns 2 matrices, q and r, such that the columns of q are orthonormal and span the same subspace than those of the input matrix, r is an upper triangular matrix, and q*r=in.
+	/// Given an n-by-m input matrix, q has dimensions min(n,m)-by-m, and r has dimensions n-by-min(n,m).
+	/// From GLM_GTX_matrix_factorisation extension.
+	template <length_t C, length_t R, typename T, precision P, template<length_t, length_t, typename, precision> class matType>
+	GLM_FUNC_DECL void qr_decompose(matType<C, R, T, P> const& in, matType<(C < R ? C : R), R, T, P>& q, matType<C, (C < R ? C : R), T, P>& r);
+
+	/// Performs RQ factorisation of a matrix.
+	/// Returns 2 matrices, r and q, such that r is an upper triangular matrix, the rows of q are orthonormal and span the same subspace than those of the input matrix, and r*q=in.
+	/// Note that in the context of RQ factorisation, the diagonal is seen as starting in the lower-right corner of the matrix, instead of the usual upper-left.
+	/// Given an n-by-m input matrix, r has dimensions min(n,m)-by-m, and q has dimensions n-by-min(n,m).
+	/// From GLM_GTX_matrix_factorisation extension.
+	template <length_t C, length_t R, typename T, precision P, template<length_t, length_t, typename, precision> class matType>
+	GLM_FUNC_DECL void rq_decompose(matType<C, R, T, P> const& in, matType<(C < R ? C : R), R, T, P>& r, matType<C, (C < R ? C : R), T, P>& q);
+
+	/// @}
+}
+
+#include "matrix_factorisation.inl"

+ 85 - 0
glm/gtx/matrix_factorisation.inl

@@ -0,0 +1,85 @@
+/// @ref gtx_matrix_factorisation
+/// @file glm/gtx/matrix_factorisation.inl
+
+namespace glm
+{
+	template <length_t C, length_t R, typename T, precision P, template<length_t, length_t, typename, precision> class matType>
+	GLM_FUNC_QUALIFIER matType<C, R, T, P> flipud(matType<C, R, T, P> const& in)
+	{
+		matType<R, C, T, P> tin = transpose(in);
+		tin = fliplr(tin);
+		matType<C, R, T, P> out = transpose(tin);
+
+		return out;
+	}
+
+	template <length_t C, length_t R, typename T, precision P, template<length_t, length_t, typename, precision> class matType>
+	GLM_FUNC_QUALIFIER matType<C, R, T, P> fliplr(matType<C, R, T, P> const& in)
+	{
+		matType<C, R, T, P> out(uninitialize);
+		for (length_t i = 0; i < C; i++)
+		{
+			out[i] = in[(C - i) - 1];
+		}
+
+		return out;
+	}
+
+	template <length_t C, length_t R, typename T, precision P, template<length_t, length_t, typename, precision> class matType>
+	GLM_FUNC_QUALIFIER void qr_decompose(matType<C, R, T, P> const& in, matType<(C < R ? C : R), R, T, P>& q, matType<C, (C < R ? C : R), T, P>& r)
+	{
+		// Uses modified Gram-Schmidt method
+		// Source: https://en.wikipedia.org/wiki/Gram–Schmidt_process
+		// And https://en.wikipedia.org/wiki/QR_decomposition
+
+		//For all the linearly independs columns of the input...
+		// (there can be no more linearly independents columns than there are rows.)
+		for (length_t i = 0; i < (C < R ? C : R); i++)
+		{
+			//Copy in Q the input's i-th column.
+			q[i] = in[i];
+
+			//j = [0,i[
+			// Make that column orthogonal to all the previous ones by substracting to it the non-orthogonal projection of all the previous columns.
+			// Also: Fill the zero elements of R
+			for (length_t j = 0; j < i; j++)
+			{
+				q[i] -= dot(q[i], q[j])*q[j];
+				r[j][i] = 0;
+			}
+
+			//Now, Q i-th column is orthogonal to all the previous columns. Normalize it.
+			q[i] = normalize(q[i]);
+
+			//j = [i,C[
+			//Finally, compute the corresponding coefficients of R by computing the projection of the resulting column on the other columns of the input.
+			for (length_t j = i; j < C; j++)
+			{
+				r[j][i] = dot(in[j], q[i]);
+			}
+		}
+	}
+
+	template <length_t C, length_t R, typename T, precision P, template<length_t, length_t, typename, precision> class matType>
+	GLM_FUNC_QUALIFIER void rq_decompose(matType<C, R, T, P> const& in, matType<(C < R ? C : R), R, T, P>& r, matType<C, (C < R ? C : R), T, P>& q)
+	{
+		// From https://en.wikipedia.org/wiki/QR_decomposition:
+		// The RQ decomposition transforms a matrix A into the product of an upper triangular matrix R (also known as right-triangular) and an orthogonal matrix Q. The only difference from QR decomposition is the order of these matrices.
+		// QR decomposition is Gram–Schmidt orthogonalization of columns of A, started from the first column.
+		// RQ decomposition is Gram–Schmidt orthogonalization of rows of A, started from the last row.
+
+		matType<R, C, T, P> tin = transpose(in);
+		tin = fliplr(tin);
+
+		matType<R, (C < R ? C : R), T, P> tr;
+		matType<(C < R ? C : R), C, T, P> tq;
+		qr_decompose(tin, tq, tr);
+
+		tr = fliplr(tr);
+		r = transpose(tr);
+		r = fliplr(r);
+
+		tq = fliplr(tq);
+		q = transpose(tq);
+	}
+} //namespace glm

+ 7 - 1
glm/gtx/matrix_interpolation.inl

@@ -1,6 +1,8 @@
 /// @ref gtx_matrix_interpolation
 /// @file glm/gtx/matrix_interpolation.hpp
 
+#include "../gtc/constants.hpp"
+
 namespace glm
 {
 	template<typename T, precision P>
@@ -72,7 +74,11 @@ namespace glm
 		T s = sqrt((mat[2][1] - mat[1][2]) * (mat[2][1] - mat[1][2]) + (mat[2][0] - mat[0][2]) * (mat[2][0] - mat[0][2]) + (mat[1][0] - mat[0][1]) * (mat[1][0] - mat[0][1]));
 		if (glm::abs(s) < T(0.001))
 			s = (T)1.0;
-		angle = acos((mat[0][0] + mat[1][1] + mat[2][2] - (T)1.0) * (T)0.5);
+		T const angleCos = (mat[0][0] + mat[1][1] + mat[2][2] - (T)1.0) * (T)0.5;
+		if (angleCos - static_cast<T>(1) < epsilon)
+			angle = pi<T>() * static_cast<T>(0.25);
+		else
+			angle = acos(angleCos);
 		axis.x = (mat[1][2] - mat[2][1]) / s;
 		axis.y = (mat[2][0] - mat[0][2]) / s;
 		axis.z = (mat[0][1] - mat[1][0]) / s;

+ 28 - 0
glm/gtx/quaternion.hpp

@@ -177,6 +177,34 @@ namespace glm
 		vec<3, T, P> const & orig, 
 		vec<3, T, P> const & dest);
 
+	/// Build a look at quaternion based on the default handedness.
+	///
+	/// @param direction Desired direction of the camera.
+	/// @param up Up vector, how the camera is oriented. Typically (0, 1, 0).
+	template<typename T, precision P>
+	GLM_FUNC_DECL tquat<T, P> quatLookAt(
+		tvec3<T, P> const & direction,
+		tvec3<T, P> const & up);
+
+	/// Build a right-handed look at quaternion.
+	///
+	/// @param direction Desired direction of the camera.
+	/// @param up Up vector, how the camera is oriented. Typically (0, 1, 0).
+	template<typename T, precision P>
+	GLM_FUNC_DECL tquat<T, P> quatLookAtRH(
+		tvec3<T, P> const & direction,
+		tvec3<T, P> const & up);
+
+	/// Build a left-handed look at quaternion.
+	///
+	/// @param eye Position of the camera
+	/// @param direction Desired direction onto which the +z-axis gets mapped
+	/// @param up Up vector, how the camera is oriented. Typically (0, 1, 0).
+	template<typename T, precision P>
+	GLM_FUNC_DECL tquat<T, P> quatLookAtLH(
+		tvec3<T, P> const & direction,
+		tvec3<T, P> const & up);
+	
 	/// Returns the squared length of x.
 	/// 
 	/// @see gtx_quaternion

+ 34 - 0
glm/gtx/quaternion.inl

@@ -208,5 +208,39 @@ namespace glm
 			rotationAxis.y * invs,
 			rotationAxis.z * invs);
 	}
+	
+	template<typename T, precision P>
+	GLM_FUNC_QUALIFIER tquat<T, P> quatLookAt(tvec3<T, P> const& direction, tvec3<T, P> const& up)
+	{
+#		if GLM_COORDINATE_SYSTEM == GLM_LEFT_HANDED
+			return quatLookAtLH(direction, up);
+#		else
+			return quatLookAtRH(direction, up);
+# 		endif
+	}
+
+	template<typename T, precision P>
+	GLM_FUNC_QUALIFIER tquat<T, P> quatLookAtRH(tvec3<T, P> const& direction, tvec3<T, P> const& up)
+	{
+		tmat3x3<T, P> Result(uninitialize);
+
+		Result[2] = -normalize(direction);
+		Result[0] = normalize(cross(up, Result[2]));
+		Result[1] = cross(Result[2], Result[0]);
+
+		return quat_cast(Result);
+	}
+
+	template<typename T, precision P>
+	GLM_FUNC_QUALIFIER tquat<T, P> quatLookAtLH(tvec3<T, P> const& direction, tvec3<T, P> const& up)
+	{
+		tmat3x3<T, P> Result(uninitialize);
+
+		Result[2] = normalize(direction);
+		Result[0] = normalize(cross(up, Result[2]));
+		Result[1] = cross(Result[2], Result[0]);
+
+		return quat_cast(Result);
+	}
 
 }//namespace glm

+ 4 - 4
glm/simd/common.h

@@ -112,7 +112,7 @@ GLM_FUNC_QUALIFIER glm_vec4 glm_vec4_round(glm_vec4 x)
 #	if GLM_ARCH & GLM_ARCH_SSE41_BIT
 		return _mm_round_ps(x, _MM_FROUND_TO_NEAREST_INT);
 #	else
-		glm_vec4 const sgn0 = _mm_castsi128_ps(_mm_set1_epi32(0x80000000));
+		glm_vec4 const sgn0 = _mm_castsi128_ps(_mm_set1_epi32(int(0x80000000)));
 		glm_vec4 const and0 = _mm_and_ps(sgn0, x);
 		glm_vec4 const or0 = _mm_or_ps(and0, _mm_set_ps1(8388608.0f));
 		glm_vec4 const add0 = glm_vec4_add(x, or0);
@@ -144,7 +144,7 @@ GLM_FUNC_QUALIFIER glm_vec4 glm_vec4_trunc(glm_vec4 x)
 //roundEven
 GLM_FUNC_QUALIFIER glm_vec4 glm_vec4_roundEven(glm_vec4 x)
 {
-	glm_vec4 const sgn0 = _mm_castsi128_ps(_mm_set1_epi32(0x80000000));
+	glm_vec4 const sgn0 = _mm_castsi128_ps(_mm_set1_epi32(int(0x80000000)));
 	glm_vec4 const and0 = _mm_and_ps(sgn0, x);
 	glm_vec4 const or0 = _mm_or_ps(and0, _mm_set_ps1(8388608.0f));
 	glm_vec4 const add0 = glm_vec4_add(x, or0);
@@ -220,7 +220,7 @@ GLM_FUNC_QUALIFIER glm_vec4 glm_vec4_nan(glm_vec4 x)
 {
 	glm_ivec4 const t1 = _mm_castps_si128(x);						// reinterpret as 32-bit integer
 	glm_ivec4 const t2 = _mm_sll_epi32(t1, _mm_cvtsi32_si128(1));	// shift out sign bit
-	glm_ivec4 const t3 = _mm_set1_epi32(0xFF000000);				// exponent mask
+	glm_ivec4 const t3 = _mm_set1_epi32(int(0xFF000000));				// exponent mask
 	glm_ivec4 const t4 = _mm_and_si128(t2, t3);						// exponent
 	glm_ivec4 const t5 = _mm_andnot_si128(t3, t2);					// fraction
 	glm_ivec4 const Equal = _mm_cmpeq_epi32(t3, t4);
@@ -234,7 +234,7 @@ GLM_FUNC_QUALIFIER glm_vec4 glm_vec4_inf(glm_vec4 x)
 {
 	glm_ivec4 const t1 = _mm_castps_si128(x);										// reinterpret as 32-bit integer
 	glm_ivec4 const t2 = _mm_sll_epi32(t1, _mm_cvtsi32_si128(1));					// shift out sign bit
-	return _mm_castsi128_ps(_mm_cmpeq_epi32(t2, _mm_set1_epi32(0xFF000000)));		// exponent is all 1s, fraction is 0
+	return _mm_castsi128_ps(_mm_cmpeq_epi32(t2, _mm_set1_epi32(int(0xFF000000))));		// exponent is all 1s, fraction is 0
 }
 
 #endif//GLM_ARCH & GLM_ARCH_SSE2_BIT

+ 4 - 47
manual.md

@@ -22,9 +22,8 @@
 + [3.4. SIMD support](#section3_4)
 + [3.5. Force inline](#section3_5)
 + [3.6. Vector and matrix static size](#section3_6)
-+ [3.7. Disabling default constructor initialization](#section3_7)
-+ [3.8. Requiring explicit conversions](#section3_8)
-+ [3.9. Removing genType restriction](#section3_9)
++ [3.7. Requiring explicit conversions](#section3_7)
++ [3.8. Removing genType restriction](#section3_8)
 + [4. Stable extensions](#section4)
 + [4.1. GLM_GTC_bitfield](#section4_1)
 + [4.2. GLM_GTC_color_space](#section4_2)
@@ -469,49 +468,7 @@ void foo(vec4 const & v)
 }
 ```
 
-### <a name="section3_7"></a> 3.7. Disabling default constructor initialization
-
-By default and following GLSL specifications, vector and matrix default constructors initialize the components to zero. This is a reliable behavior but initialization has a cost and it’s not always necessary.
-This behavior can be disabled at compilation time by define GLM\_FORCE\_NO\_CTOR\_INIT before any inclusion of &lt;glm/glm.hpp&gt; or other GLM include.
-
-GLM default behavior:
-
-```cpp
-#include <glm/glm.hpp>
-
-void foo()
-{
-    glm::vec4 v; // v is (0.0f, 0.0f, 0.0f, 0.0f)
-    ...
-}
-```
-
-GLM behavior using GLM\_FORCE\_NO\_CTOR\_INIT:
-
-```cpp
-#define GLM_FORCE_NO_CTOR_INIT
-#include <glm/glm.hpp>
-
-void foo()
-{
-    glm::vec4 v; // v is filled with garbage
-    ...
-}
-```
-
-Alternatively, GLM allows to explicitly not initialize a variable:
-
-```cpp
-#include <glm/glm.hpp>
-
-void foo()
-{
-    glm::vec4 v(glm::uninitialize);
-    ...
-}
-```
-
-### <a name="section3_8"></a> 3.8. Require explicit conversions
+### <a name="section3_7"></a> 3.7. Requiring explicit conversions
 
 GLSL supports implicit conversions of vector and matrix types. For example, an ivec4 can be implicitly converted into vec4.
 
@@ -548,7 +505,7 @@ void foo()
 }
 ```
 
-### <a name="section3_9"></a> 3.9. Removing genType restriction
+### <a name="section3_8"></a> 3.8. Removing genType restriction
 
 By default GLM only supports basic types as genType for vector, matrix and quaternion types:
 

+ 12 - 1
readme.md

@@ -57,9 +57,14 @@ glm::mat4 camera(float Translate, glm::vec2 const & Rotate)
 - Added GTX_color_encoding extension
 - Added GTX_vec_swizzle, faster compile time swizzling then swizzle operator #558
 - Added GTX_exterior_product with a vec2 cross implementation #621
+- Added GTX_matrix_factorisation to factor matrices in various forms #654
 - Added [GLM_ENABLE_EXPERIMENTAL](manual.md#section7_4) to enable experimental features.
+- Added packing functions for integer vectors #639
+- Added conan packaging configuration #643 #641
+- Added quatLookAt to GTX_quaternion #659
 
 #### Improvements:
+- No more default initialization of vector, matrix and quaternion types
 - Added lowp variant of GTC_color_space convertLinearToSRGB #419
 - Replaced the manual by a markdown version #458
 - Optimized GTC_packing implementation
@@ -70,7 +75,9 @@ glm::mat4 camera(float Translate, glm::vec2 const & Rotate)
 - Added FAQ 12: Windows headers cause build errors... #557
 - Removed GCC shadow warnings #595
 - Added error for including of different versions of GLM #619
-- Added GLM_FORCE_IGNORE_VERSION to ignore error caused by including different version of GLM #619 
+- Added GLM_FORCE_IGNORE_VERSION to ignore error caused by including different version of GLM #619
+- Reduced warnings when using very strict compilation flags #646
+- length() member functions are constexpr #657
 
 #### Fixes:
 - Removed doxygen references to GTC_half_float which was removed in 0.9.4
@@ -80,6 +87,10 @@ glm::mat4 camera(float Translate, glm::vec2 const & Rotate)
 - Fixed usused variable warning in GTX_spline #618
 - Fixed references to GLM_FORCE_RADIANS which was removed #642
 - Fixed glm::fastInverseSqrt to use fast inverse square #640
+- Fixed axisAngle NaN #638
+- Fixed integer pow from GTX_integer with null exponent #658
+- Fixed quat normalize build error #656
+- Fixed Visual C++ 2017.2 warning regarding __has_feature definision #655
 
 #### Deprecation:
 - Requires Visual Studio 2013, GCC 4.7, Clang 3.4, Cuda 7, ICC 2013 or a C++11 compiler

+ 5 - 0
test/core/core_type_vec1.cpp

@@ -106,6 +106,11 @@ int test_vec1_size()
 	Error += glm::vec1::length() == 1 ? 0 : 1;
 	Error += glm::dvec1::length() == 1 ? 0 : 1;
 
+#	if GLM_HAS_CONSTEXPR_PARTIAL
+	constexpr std::size_t Length = glm::vec2::length();
+	Error += Length == 1 ? 0 : 1;
+#	endif
+
 	return Error;
 }
 

+ 5 - 0
test/core/core_type_vec2.cpp

@@ -272,6 +272,11 @@ int test_vec2_size()
 	Error += glm::vec2::length() == 2 ? 0 : 1;
 	Error += glm::dvec2::length() == 2 ? 0 : 1;
 
+#	if GLM_HAS_CONSTEXPR_PARTIAL
+		constexpr std::size_t Length = glm::vec2::length();
+		Error += Length == 2 ? 0 : 1;
+#	endif
+
 	return Error;
 }
 

+ 5 - 0
test/core/core_type_vec3.cpp

@@ -246,6 +246,11 @@ int test_vec3_size()
 	Error += glm::vec3::length() == 3 ? 0 : 1;
 	Error += glm::dvec3::length() == 3 ? 0 : 1;
 
+#	if GLM_HAS_CONSTEXPR_PARTIAL
+	constexpr std::size_t Length = glm::vec3::length();
+	Error += Length == 3 ? 0 : 1;
+#	endif
+
 	return Error;
 }
 

+ 5 - 0
test/core/core_type_vec4.cpp

@@ -322,6 +322,11 @@ int test_vec4_size()
 	Error += glm::vec4::length() == 4 ? 0 : 1;
 	Error += glm::dvec4::length() == 4 ? 0 : 1;
 
+#	if GLM_HAS_CONSTEXPR_PARTIAL
+	constexpr std::size_t Length = glm::vec4::length();
+	Error += Length == 4 ? 0 : 1;
+#	endif
+
 	return Error;
 }
 

+ 162 - 0
test/gtc/gtc_packing.cpp

@@ -670,6 +670,156 @@ int test_packUnorm2x3_1x2()
 	return Error;
 }
 
+int test_packUint2x8()
+{
+	int Error = 0;
+
+	glm::u8vec2 const Source(1, 2);
+
+	glm::uint16 const Packed = glm::packUint2x8(Source);
+	Error += Packed != 0 ? 0 : 1;
+
+	glm::u8vec2 const Unpacked = glm::unpackUint2x8(Packed);
+	Error += Source == Unpacked ? 0 : 1;
+
+	return Error;
+}
+
+int test_packUint4x8()
+{
+	int Error = 0;
+
+	glm::u8vec4 const Source(1, 2, 3, 4);
+
+	glm::uint32 const Packed = glm::packUint4x8(Source);
+	Error += Packed != 0 ? 0 : 1;
+
+	glm::u8vec4 const Unpacked = glm::unpackUint4x8(Packed);
+	Error += Source == Unpacked ? 0 : 1;
+
+	return Error;
+}
+
+int test_packUint2x16()
+{
+	int Error = 0;
+
+	glm::u16vec2 const Source(1, 2);
+
+	glm::uint32 const Packed = glm::packUint2x16(Source);
+	Error += Packed != 0 ? 0 : 1;
+
+	glm::u16vec2 const Unpacked = glm::unpackUint2x16(Packed);
+	Error += Source == Unpacked ? 0 : 1;
+
+	return Error;
+}
+
+int test_packUint4x16()
+{
+	int Error = 0;
+
+	glm::u16vec4 const Source(1, 2, 3, 4);
+
+	glm::uint64 const Packed = glm::packUint4x16(Source);
+	Error += Packed != 0 ? 0 : 1;
+
+	glm::u16vec4 const Unpacked = glm::unpackUint4x16(Packed);
+	Error += Source == Unpacked ? 0 : 1;
+
+	return Error;
+}
+
+int test_packUint2x32()
+{
+	int Error = 0;
+
+	glm::u32vec2 const Source(1, 2);
+
+	glm::uint64 const Packed = glm::packUint2x32(Source);
+	Error += Packed != 0 ? 0 : 1;
+
+	glm::u32vec2 const Unpacked = glm::unpackUint2x32(Packed);
+	Error += Source == Unpacked ? 0 : 1;
+
+	return Error;
+}
+
+int test_packInt2x8()
+{
+	int Error = 0;
+
+	glm::i8vec2 const Source(1, 2);
+
+	glm::int16 const Packed = glm::packInt2x8(Source);
+	Error += Packed != 0 ? 0 : 1;
+
+	glm::i8vec2 const Unpacked = glm::unpackInt2x8(Packed);
+	Error += Source == Unpacked ? 0 : 1;
+
+	return Error;
+}
+
+int test_packInt4x8()
+{
+	int Error = 0;
+
+	glm::i8vec4 const Source(1, 2, 3, 4);
+
+	glm::int32 const Packed = glm::packInt4x8(Source);
+	Error += Packed != 0 ? 0 : 1;
+
+	glm::i8vec4 const Unpacked = glm::unpackInt4x8(Packed);
+	Error += Source == Unpacked ? 0 : 1;
+
+	return Error;
+}
+
+int test_packInt2x16()
+{
+	int Error = 0;
+
+	glm::i16vec2 const Source(1, 2);
+
+	glm::int32 const Packed = glm::packInt2x16(Source);
+	Error += Packed != 0 ? 0 : 1;
+
+	glm::i16vec2 const Unpacked = glm::unpackInt2x16(Packed);
+	Error += Source == Unpacked ? 0 : 1;
+
+	return Error;
+}
+
+int test_packInt4x16()
+{
+	int Error = 0;
+
+	glm::i16vec4 const Source(1, 2, 3, 4);
+
+	glm::int64 const Packed = glm::packInt4x16(Source);
+	Error += Packed != 0 ? 0 : 1;
+
+	glm::i16vec4 const Unpacked = glm::unpackInt4x16(Packed);
+	Error += Source == Unpacked ? 0 : 1;
+
+	return Error;
+}
+
+int test_packInt2x32()
+{
+	int Error = 0;
+
+	glm::i32vec2 const Source(1, 2);
+
+	glm::int64 const Packed = glm::packInt2x32(Source);
+	Error += Packed != 0 ? 0 : 1;
+
+	glm::i32vec2 const Unpacked = glm::unpackInt2x32(Packed);
+	Error += Source == Unpacked ? 0 : 1;
+
+	return Error;
+}
+
 int main()
 {
 	int Error = 0;
@@ -699,6 +849,18 @@ int main()
 	Error += test_packUnorm1x5_1x6_1x5();
 	Error += test_packUnorm2x3_1x2();
 
+	Error += test_packUint2x8();
+	Error += test_packUint4x8();
+	Error += test_packUint2x16();
+	Error += test_packUint4x16();
+	Error += test_packUint2x32();
+
+	Error += test_packInt2x8();
+	Error += test_packInt4x8();
+	Error += test_packInt2x16();
+	Error += test_packInt4x16();
+	Error += test_packInt2x32();
+
 	Error += test_F2x11_1x10();
 	Error += test_F3x9_E1x5();
 	Error += test_RGBM();

+ 1 - 0
test/gtx/CMakeLists.txt

@@ -21,6 +21,7 @@ glmCreateTestGTC(gtx_io)
 glmCreateTestGTC(gtx_log_base)
 glmCreateTestGTC(gtx_matrix_cross_product)
 glmCreateTestGTC(gtx_matrix_decompose)
+glmCreateTestGTC(gtx_matrix_factorisation)
 glmCreateTestGTC(gtx_matrix_interpolation)
 glmCreateTestGTC(gtx_matrix_major_storage)
 glmCreateTestGTC(gtx_matrix_operation)

+ 43 - 0
test/gtx/gtx_integer.cpp

@@ -52,6 +52,47 @@ int test_nlz()
 	return Error;
 }
 
+int test_pow_uint()
+{
+	int Error = 0;
+
+	glm::uint const p0 = glm::pow(2u, 0u);
+	Error += p0 == 1u ? 0 : 1;
+
+	glm::uint const p1 = glm::pow(2u, 1u);
+	Error += p1 == 2u ? 0 : 1;
+
+	glm::uint const p2 = glm::pow(2u, 2u);
+	Error += p2 == 4u ? 0 : 1;
+
+	return Error;
+}
+
+int test_pow_int()
+{
+	int Error = 0;
+
+	int const p0 = glm::pow(2, 0u);
+	Error += p0 == 1 ? 0 : 1;
+
+	int const p1 = glm::pow(2, 1u);
+	Error += p1 == 2 ? 0 : 1;
+
+	int const p2 = glm::pow(2, 2u);
+	Error += p2 == 4 ? 0 : 1;
+
+	int const p0n = glm::pow(-2, 0u);
+	Error += p0n == -1 ? 0 : 1;
+
+	int const p1n = glm::pow(-2, 1u);
+	Error += p1n == -2 ? 0 : 1;
+
+	int const p2n = glm::pow(-2, 2u);
+	Error += p2n == 4 ? 0 : 1;
+
+	return Error;
+}
+
 int main()
 {
 	int Error = 0;
@@ -59,6 +100,8 @@ int main()
 	Error += test_nlz();
 //	Error += test_floor_log2();
 	Error += test_log2();
+	Error += test_pow_uint();
+	Error += test_pow_int();
 
 	return Error;
 }

+ 101 - 0
test/gtx/gtx_matrix_factorisation.cpp

@@ -0,0 +1,101 @@
+#define GLM_ENABLE_EXPERIMENTAL
+#include <glm/gtx/matrix_factorisation.hpp>
+
+float const epsilon = 1e-10f;
+
+template <glm::length_t C, glm::length_t R, typename T, glm::precision P, template<glm::length_t, glm::length_t, typename, glm::precision> class matType>
+int test_qr(matType<C, R, T, P> m)
+{
+	int Error = 0;
+
+	matType<(C < R ? C : R), R, T, P> q(-999);
+	matType<C, (C < R ? C : R), T, P> r(-999);
+
+	glm::qr_decompose(m, q, r);
+
+	//Test if q*r really equals the input matrix
+	matType<C, R, T, P> tm = q*r;
+	matType<C, R, T, P> err = tm - m;
+
+	for (glm::length_t i = 0; i < C; i++)
+	for (glm::length_t j = 0; j < R; j++)
+		Error += std::abs(err[i][j]) > epsilon ? 1 : 0;
+
+	//Test if the columns of q are orthonormal
+	for (glm::length_t i = 0; i < (C < R ? C : R); i++)
+	{
+		Error += (length(q[i]) - 1) > epsilon ? 1 : 0;
+
+		for (glm::length_t j = 0; j<i; j++)
+			Error += std::abs(dot(q[i], q[j])) > epsilon ? 1 : 0;
+	}
+
+	//Test if the matrix r is upper triangular
+	for (glm::length_t i = 0; i < C; i++)
+	for (glm::length_t j = i + 1; j < (C < R ? C : R); j++)
+			Error += r[i][j] != 0 ? 1 : 0;
+
+	return Error;
+}
+
+template <glm::length_t C, glm::length_t R, typename T, glm::precision P, template<glm::length_t, glm::length_t, typename, glm::precision> class matType>
+int test_rq(matType<C, R, T, P> m)
+{
+	int Error = 0;
+
+	matType<C, (C < R ? C : R), T, P> q(-999);
+	matType<(C < R ? C : R), R, T, P> r(-999);
+
+	glm::rq_decompose(m, r, q);
+
+	//Test if q*r really equals the input matrix
+	matType<C, R, T, P> tm = r*q;
+	matType<C, R, T, P> err = tm - m;
+
+	for (glm::length_t i = 0; i < C; i++)
+	for (glm::length_t j = 0; j < R; j++)
+		Error += std::abs(err[i][j]) > epsilon ? 1 : 0;
+
+	//Test if the rows of q are orthonormal
+	matType<(C < R ? C : R), C, T, P> tq = transpose(q);
+
+	for (glm::length_t i = 0; i < (C < R ? C : R); i++)
+	{
+		Error += (length(tq[i]) - 1) > epsilon ? 1 : 0;
+
+		for (glm::length_t j = 0; j<i; j++)
+			Error += std::abs(dot(tq[i], tq[j])) > epsilon ? 1 : 0;
+	}
+
+	//Test if the matrix r is upper triangular
+	for (glm::length_t i = 0; i < (C < R ? C : R); i++)
+	for (glm::length_t j = R - (C < R ? C : R) + i + 1; j < R; j++)
+		Error += r[i][j] != 0 ? 1 : 0;
+
+	return Error;
+}
+
+int main()
+{
+	int Error = 0;
+
+	//Test QR square
+	Error += test_qr(glm::dmat3(12, 6, -4, -51, 167, 24, 4, -68, -41)) ? 1 : 0;
+
+	//Test RQ square
+	Error += test_rq(glm::dmat3(12, 6, -4, -51, 167, 24, 4, -68, -41)) ? 1 : 0;
+
+	//Test QR triangular 1
+	Error += test_qr(glm::dmat3x4(12, 6, -4, -51, 167, 24, 4, -68, -41, 7, 2, 15)) ? 1 : 0;
+
+	//Test QR triangular 2
+	Error += test_qr(glm::dmat4x3(12, 6, -4, -51, 167, 24, 4, -68, -41, 7, 2, 15)) ? 1 : 0;
+
+	//Test RQ triangular 1 : Fails at the triangular test
+	Error += test_rq(glm::dmat3x4(12, 6, -4, -51, 167, 24, 4, -68, -41, 7, 2, 15)) ? 1 : 0;
+
+	//Test QR triangular 2
+	Error += test_rq(glm::dmat4x3(12, 6, -4, -51, 167, 24, 4, -68, -41, 7, 2, 15)) ? 1 : 0;
+
+	return Error;
+}

+ 37 - 1
test/gtx/gtx_matrix_interpolation.cpp

@@ -1,9 +1,45 @@
 #define GLM_ENABLE_EXPERIMENTAL
+#include <glm/gtc/quaternion.hpp>
 #include <glm/gtx/matrix_interpolation.hpp>
 
+#include <iostream>
+
+int test_axisAngle()
+{
+	int Error = 0;
+
+	float p = 0.171654f;
+	glm::mat4 m1(-0.9946f, 0.0f, -0.104531f, 0.0f,
+		0.0f, 1.0f, 0.0f, 0.0f,
+		0.104531f, 0.0f, -0.9946f, 0.0f,
+		0.0f, 0.0f, 0.0f, 1.0f);
+	glm::mat4 m2(-0.992624f, 0.0f, -0.121874f, 0.0f,
+		0.0f, 1.0f, 0.0f, 0.0f,
+		0.121874f, 0.0f, -0.992624f, 0.0f,
+		0.0f, 0.0f, 0.0f, 1.0f);
+
+	glm::mat4 const m1rot = glm::extractMatrixRotation(m1);
+	glm::mat4 const dltRotation = m2 * glm::transpose(m1rot);
+
+	glm::vec3 dltAxis(0.0f);
+	float dltAngle = 0.0f;
+	glm::axisAngle(dltRotation, dltAxis, dltAngle);
+
+	std::cout << "dltAngle: (" << dltAxis.x << ", " << dltAxis.y << ", " << dltAxis.z << "), dltAngle: " << dltAngle << std::endl;
+
+	glm::fquat q = glm::quat_cast(dltRotation);
+	std::cout << "q: (" << q.x << ", " << q.y << ", " << q.z << ", " << q.w << ")" << std::endl;
+	float yaw = glm::yaw(q);
+	std::cout << "Yaw: " << yaw << std::endl;
+
+	return Error;
+}
+
 int main()
 {
-	int Error(0);
+	int Error = 0;
+
+	Error += test_axisAngle();
 
 	return Error;
 }

+ 18 - 0
test/gtx/gtx_quaternion.cpp

@@ -90,6 +90,23 @@ int test_log()
 	return Error;
 }
 
+int test_quat_lookAt()
+{
+	int Error(0);
+
+	glm::vec3 eye(0.0f);
+	glm::vec3 center(1.1f, -2.0f, 3.1416f);
+	glm::vec3 up = glm::vec3(-0.17f, 7.23f, -1.744f);
+
+	glm::quat test_quat = glm::quatLookAt(center - eye, up);
+	glm::quat test_mat = glm::conjugate(glm::quat_cast(glm::lookAt(eye, center, up)));
+
+	Error += static_cast<int>(glm::abs(glm::length(test_quat) - 1.0f) > glm::epsilon<float>());
+	Error += static_cast<int>(glm::min(glm::length(test_quat + (-test_mat)), glm::length(test_quat + test_mat)) > glm::epsilon<float>());
+
+	return Error;
+}
+
 int main()
 {
 	int Error = 0;
@@ -98,6 +115,7 @@ int main()
 	Error += test_rotation();
 	Error += test_quat_fastMix();
 	Error += test_quat_shortMix();
+	Error += test_quat_lookAt();
 
 	return Error;
 }