Browse Source

Added component wise comparison operators for quaternion

Christophe Riccio 12 years ago
parent
commit
abbb0fc7cb
7 changed files with 474 additions and 91 deletions
  1. 2 2
      glm/core/type_vec2.hpp
  2. 31 34
      glm/gtc/half_float.hpp
  3. 29 44
      glm/gtc/half_float.inl
  4. 61 9
      glm/gtc/quaternion.hpp
  5. 122 0
      glm/gtc/quaternion.inl
  6. 2 0
      readme.txt
  7. 227 2
      test/gtc/gtc_type_precision.cpp

+ 2 - 2
glm/core/type_vec2.hpp

@@ -109,7 +109,7 @@ namespace detail
 		GLM_FUNC_DECL explicit tvec2(
 			value_type const & s);
 		GLM_FUNC_DECL explicit tvec2(
-			value_type const & s1, 
+			value_type const & s1,
 			value_type const & s2);
 
 		//////////////////////////////////////
@@ -127,7 +127,7 @@ namespace detail
 		// Convertion constructors
 
 		//! Explicit converions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
-		template <typename U> 
+		template <typename U>
 		GLM_FUNC_DECL explicit tvec2(
 			U const & x);
 		//! Explicit converions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)

+ 31 - 34
glm/gtc/half_float.hpp

@@ -56,7 +56,6 @@ namespace detail
 		typedef std::size_t size_type;
 
 		GLM_FUNC_DECL size_type length() const;
-		static GLM_FUNC_DECL size_type value_size();
 
 		typedef tvec2<half, P> type;
 		typedef tvec2<bool, P> bool_type;
@@ -107,14 +106,14 @@ namespace detail
 		// Convertion vector constructors
 
 		//! Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
-		template <typename U> 
-		explicit tvec2(tvec2<U, P> const & v);
+		template <typename U, precision Q>
+		explicit tvec2(tvec2<U, Q> const & v);
 		//! Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
-		template <typename U> 
-		explicit tvec2(tvec3<U, P> const & v);
+		template <typename U, precision Q>
+		explicit tvec2(tvec3<U, Q> const & v);
 		//! Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
-		template <typename U> 
-		explicit tvec2(tvec4<U, P> const & v);
+		template <typename U, precision Q>
+		explicit tvec2(tvec4<U, Q> const & v);
 
 		//////////////////////////////////////
 		// Unary arithmetic operators
@@ -149,7 +148,6 @@ namespace detail
 		typedef half value_type;
 		typedef std::size_t size_type;
 		GLM_FUNC_DECL size_type length() const;
-		static GLM_FUNC_DECL size_type value_size();
 
 		typedef tvec3<half, P> type;
 		typedef tvec3<bool, P> bool_type;
@@ -191,7 +189,7 @@ namespace detail
 		// Convertion scalar constructors
 
 		//! Explicit converions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
-		template <typename U> 
+		template <typename U>
 		explicit tvec3(U const & x);
 		//! Explicit converions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
 		template <typename U, typename V, typename W> 
@@ -201,17 +199,17 @@ namespace detail
 		// Convertion vector constructors
 
 		//! Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
-		template <typename A, typename B> 
-		explicit tvec3(tvec2<A, P> const & v, B const & s);
+		template <typename A, typename B, precision Q>
+		explicit tvec3(tvec2<A, Q> const & v, B const & s);
 		//! Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
-		template <typename A, typename B> 
-		explicit tvec3(A const & s, tvec2<B, P> const & v);
+		template <typename A, typename B, precision Q>
+		explicit tvec3(A const & s, tvec2<B, Q> const & v);
 		//! Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
-		template <typename U> 
-		explicit tvec3(tvec3<U, P> const & v);
+		template <typename U, precision Q>
+		explicit tvec3(tvec3<U, Q> const & v);
 		//! Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
-		template <typename U> 
-		explicit tvec3(tvec4<U, P> const & v);
+		template <typename U, precision Q>
+		explicit tvec3(tvec4<U, Q> const & v);
 
 		//////////////////////////////////////
 		// Unary arithmetic operators
@@ -246,7 +244,6 @@ namespace detail
 		typedef half value_type;
 		typedef std::size_t size_type;
 		GLM_FUNC_DECL size_type length() const;
-		static GLM_FUNC_DECL size_type value_size();
 
 		typedef tvec4<half, P> type;
 		typedef tvec4<bool, P> bool_type;
@@ -289,36 +286,36 @@ namespace detail
 		// Convertion scalar constructors
 
 		//! Explicit converions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
-		template <typename U> 
+		template <typename U>
 		explicit tvec4(U const & x);
 		//! Explicit converions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
-		template <typename A, typename B, typename C, typename D> 
+		template <typename A, typename B, typename C, typename D>
 		explicit tvec4(A const & x, B const & y, C const & z, D const & w);			
 
 		//////////////////////////////////////
 		// Convertion vector constructors
 
 		//! Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
-		template <typename A, typename B, typename C> 
-		explicit tvec4(tvec2<A, P> const & v, B const & s1, C const & s2);
+		template <typename A, typename B, typename C, precision Q>
+		explicit tvec4(tvec2<A, Q> const & v, B const & s1, C const & s2);
 		//! Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
-		template <typename A, typename B, typename C> 
-		explicit tvec4(A const & s1, tvec2<B, P> const & v, C const & s2);
+		template <typename A, typename B, typename C, precision Q>
+		explicit tvec4(A const & s1, tvec2<B, Q> const & v, C const & s2);
 		//! Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
-		template <typename A, typename B, typename C> 
-		explicit tvec4(A const & s1, B const & s2, tvec2<C, P> const & v);
+		template <typename A, typename B, typename C, precision Q>
+		explicit tvec4(A const & s1, B const & s2, tvec2<C, Q> const & v);
 		//! Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
-		template <typename A, typename B> 
-		explicit tvec4(tvec3<A, P> const & v, B const & s);
+		template <typename A, typename B, precision Q>
+		explicit tvec4(tvec3<A, Q> const & v, B const & s);
 		//! Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
-		template <typename A, typename B> 
-		explicit tvec4(A const & s, tvec3<B, P> const & v);
+		template <typename A, typename B, precision Q>
+		explicit tvec4(A const & s, tvec3<B, Q> const & v);
 		//! Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
-		template <typename A, typename B> 
-		explicit tvec4(tvec2<A, P> const & v1, tvec2<B, P> const & v2);
+		template <typename A, typename B, precision Q>
+		explicit tvec4(tvec2<A, Q> const & v1, tvec2<B, Q> const & v2);
 		//! Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
-		template <typename U> 
-		explicit tvec4(tvec4<U, P> const & v);
+		template <typename U, precision Q>
+		explicit tvec4(tvec4<U, Q> const & v);
 
 		//////////////////////////////////////
 		// Unary arithmetic operators

+ 29 - 44
glm/gtc/half_float.inl

@@ -36,9 +36,6 @@ namespace detail
 	template <precision P>
 	GLM_FUNC_QUALIFIER typename tvec2<half, P>::size_type tvec2<half, P>::length() const{return 2;}
 
-	template <precision P>
-	GLM_FUNC_QUALIFIER typename tvec2<half, P>::size_type tvec2<half, P>::value_size(){return 2;}
-
 	//////////////////////////////////////
 	// Accesses
 
@@ -136,30 +133,30 @@ namespace detail
 	// Convertion vector constructors
 
 	template <precision P>
-	template <typename U>
+	template <typename U, precision Q>
 	GLM_FUNC_QUALIFIER tvec2<half, P>::tvec2
 	(
-		tvec2<U, P> const & v
+		tvec2<U, Q> const & v
 	) :
 		x(half(v.x)),
 		y(half(v.y))
 	{}
 
 	template <precision P>
-	template <typename U>
+	template <typename U, precision Q>
 	GLM_FUNC_QUALIFIER tvec2<half, P>::tvec2
 	(	
-		tvec3<U, P> const & v
+		tvec3<U, Q> const & v
 	) :
 		x(half(v.x)),
 		y(half(v.y))
 	{}
 
 	template <precision P>
-	template <typename U>
+	template <typename U, precision Q>
 	GLM_FUNC_QUALIFIER tvec2<half, P>::tvec2
 	(
-		tvec4<U, P> const & v
+		tvec4<U, Q> const & v
 	) :
 		x(half(v.x)),
 		y(half(v.y))
@@ -336,12 +333,6 @@ namespace detail
 		return 3;
 	}
 
-	template <precision P>
-	GLM_FUNC_QUALIFIER typename tvec3<half, P>::size_type tvec3<half, P>::value_size()
-	{
-		return 3;
-	}
-
 	//////////////////////////////////////
 	// Accesses
 
@@ -456,10 +447,10 @@ namespace detail
 	// Convertion vector constructors
 
 	template <precision P>
-	template <typename A, typename B>
+	template <typename A, typename B, precision Q>
 	GLM_FUNC_QUALIFIER tvec3<half, P>::tvec3
 	(
-		tvec2<A, P> const & v,
+		tvec2<A, Q> const & v,
 		B const & s
 	) :
 		x(half(v.x)),
@@ -468,11 +459,11 @@ namespace detail
 	{}
 
 	template <precision P>
-	template <typename A, typename B>
+	template <typename A, typename B, precision Q>
 	GLM_FUNC_QUALIFIER tvec3<half, P>::tvec3
 	(
 		A const & s,
-		tvec2<B, P> const & v
+		tvec2<B, Q> const & v
 	) :
 		x(half(s)),
 		y(half(v.x)),
@@ -480,10 +471,10 @@ namespace detail
 	{}
 
 	template <precision P>
-	template <typename U>
+	template <typename U, precision Q>
 	GLM_FUNC_QUALIFIER tvec3<half, P>::tvec3
 	(
-		tvec3<U, P> const & v
+		tvec3<U, Q> const & v
 	) :
 		x(half(v.x)),
 		y(half(v.y)),
@@ -491,10 +482,10 @@ namespace detail
 	{}
 
 	template <precision P>
-	template <typename U>
+	template <typename U, precision Q>
 	GLM_FUNC_QUALIFIER tvec3<half, P>::tvec3
 	(
-		tvec4<U, P> const & v
+		tvec4<U, Q> const & v
 	) :
 		x(half(v.x)),
 		y(half(v.y)),
@@ -683,12 +674,6 @@ namespace detail
 	{
 		return 4;
 	}
-
-	template <precision P>
-	GLM_FUNC_QUALIFIER typename tvec4<half, P>::size_type tvec4<half, P>::value_size()
-	{
-		return 4;
-	}
 	
 	//////////////////////////////////////
 	// Accesses
@@ -813,10 +798,10 @@ namespace detail
 	// Convertion vector constructors
 
 	template <precision P>
-	template <typename A, typename B, typename C>
+	template <typename A, typename B, typename C, precision Q>
 	GLM_FUNC_QUALIFIER tvec4<half, P>::tvec4
 	(
-		tvec2<A, P> const & v,
+		tvec2<A, Q> const & v,
 		B const & s1,
 		C const & s2
 	) :
@@ -827,11 +812,11 @@ namespace detail
 	{}
 
 	template <precision P>
-	template <typename A, typename B, typename C>
+	template <typename A, typename B, typename C, precision Q>
 	GLM_FUNC_QUALIFIER tvec4<half, P>::tvec4
 	(
 		A const & s1,
-		tvec2<B, P> const & v,
+		tvec2<B, Q> const & v,
 		C const & s2
 	) :
 		x(half(s1)),
@@ -841,12 +826,12 @@ namespace detail
 	{}
 
 	template <precision P>
-	template <typename A, typename B, typename C>
+	template <typename A, typename B, typename C, precision Q>
 	GLM_FUNC_QUALIFIER tvec4<half, P>::tvec4
 	(
 		A const & s1,
 		B const & s2,
-		tvec2<C, P> const & v
+		tvec2<C, Q> const & v
 	) :
 		x(half(s1)),
 		y(half(s2)),
@@ -855,10 +840,10 @@ namespace detail
 	{}
 
 	template <precision P>
-	template <typename A, typename B>
+	template <typename A, typename B, precision Q>
 	GLM_FUNC_QUALIFIER tvec4<half, P>::tvec4
 	(
-		tvec3<A, P> const & v,
+		tvec3<A, Q> const & v,
 		B const & s
 	) :
 		x(half(v.x)),
@@ -868,11 +853,11 @@ namespace detail
 	{}
 
 	template <precision P>
-	template <typename A, typename B>
+	template <typename A, typename B, precision Q>
 	GLM_FUNC_QUALIFIER tvec4<half, P>::tvec4
 	(
 		A const & s,
-		tvec3<B, P> const & v
+		tvec3<B, Q> const & v
 	) :
 		x(half(s)),
 		y(half(v.x)),
@@ -881,11 +866,11 @@ namespace detail
 	{}
 
 	template <precision P>
-	template <typename A, typename B>
+	template <typename A, typename B, precision Q>
 	GLM_FUNC_QUALIFIER tvec4<half, P>::tvec4
 	(
-		tvec2<A, P> const & v1,
-		tvec2<B, P> const & v2
+		tvec2<A, Q> const & v1,
+		tvec2<B, Q> const & v2
 	) :
 		x(half(v1.x)),
 		y(half(v1.y)),
@@ -894,10 +879,10 @@ namespace detail
 	{}
 
 	template <precision P>
-	template <typename U>
+	template <typename U, precision Q>
 	GLM_FUNC_QUALIFIER tvec4<half, P>::tvec4
 	(
-		tvec4<U, P> const & v
+		tvec4<U, Q> const & v
 	) :
 		x(half(v.x)),
 		y(half(v.y)),

+ 61 - 9
glm/gtc/quaternion.hpp

@@ -59,6 +59,7 @@ namespace detail
 
 		typedef T value_type;
 		typedef std::size_t size_type;
+		typedef tvec4<bool, P> bool_type;
 
 	public:
 		value_type x, y, z, w;
@@ -67,10 +68,13 @@ namespace detail
 
 		// Constructors
 		tquat();
-		explicit tquat(
+		template <typename U, precision Q>
+		GLM_FUNC_DECL explicit tquat(
+			tquat<U, Q> const & q);
+		GLM_FUNC_DECL explicit tquat(
 			value_type const & s,
 			glm::detail::tvec3<T, P> const & v);
-		explicit tquat(
+		GLM_FUNC_DECL explicit tquat(
 			value_type const & w,
 			value_type const & x,
 			value_type const & y,
@@ -79,20 +83,20 @@ namespace detail
 		// Convertions
 
 		/// Build a quaternion from euler angles (pitch, yaw, roll), in radians.
-		explicit tquat(
+		GLM_FUNC_DECL explicit tquat(
 			tvec3<T, P> const & eulerAngles);
-		explicit tquat(
+		GLM_FUNC_DECL explicit tquat(
 			tmat3x3<T, P> const & m);
-		explicit tquat(
+		GLM_FUNC_DECL explicit tquat(
 			tmat4x4<T, P> const & m);
 
 		// Accesses
-		value_type & operator[](int i);
-		value_type const & operator[](int i) const;
+		GLM_FUNC_DECL value_type & operator[](int i);
+		GLM_FUNC_DECL value_type const & operator[](int i) const;
 
 		// Operators
-		tquat<T, P> & operator*=(value_type const & s);
-		tquat<T, P> & operator/=(value_type const & s);
+		GLM_FUNC_DECL tquat<T, P> & operator*=(value_type const & s);
+		GLM_FUNC_DECL tquat<T, P> & operator/=(value_type const & s);
 	};
 
 	template <typename T, precision P>
@@ -319,6 +323,54 @@ namespace detail
 		T const & angle,
 		detail::tvec3<T, P> const & axis);
 
+	/// Returns the component-wise comparison result of x < y.
+	/// 
+	/// @tparam quatType Floating-point quaternion types.
+	///
+	/// @see gtc_quaternion
+	template <typename quatType>
+	typename quatType::bool_type lessThan(quatType const & x, quatType const & y);
+
+	/// Returns the component-wise comparison of result x <= y.
+	///
+	/// @tparam quatType Floating-point quaternion types.
+	///
+	/// @see gtc_quaternion
+	template <typename quatType>
+	typename quatType::bool_type lessThanEqual(quatType const & x, quatType const & y);
+
+	/// Returns the component-wise comparison of result x > y.
+	///
+	/// @tparam quatType Floating-point quaternion types.
+	///
+	/// @see gtc_quaternion
+	template <typename quatType>
+	typename quatType::bool_type greaterThan(quatType const & x, quatType const & y);
+
+	/// Returns the component-wise comparison of result x >= y.
+	///
+	/// @tparam quatType Floating-point quaternion types.
+	///
+	/// @see gtc_quaternion
+	template <typename quatType>
+	typename quatType::bool_type greaterThanEqual(quatType const & x, quatType const & y);
+
+	/// Returns the component-wise comparison of result x == y.
+	///
+	/// @tparam quatType Floating-point quaternion types.
+	///
+	/// @see gtc_quaternion
+	template <typename quatType>
+	typename quatType::bool_type equal(quatType const & x, quatType const & y);
+
+	/// Returns the component-wise comparison of result x != y.
+	/// 
+	/// @tparam quatType Floating-point quaternion types.
+	///
+	/// @see gtc_quaternion
+	template <typename quatType>
+	typename quatType::bool_type notEqual(quatType const & x, quatType const & y);
+
 	/// @}
 } //namespace glm
 

+ 122 - 0
glm/gtc/quaternion.inl

@@ -45,6 +45,18 @@ namespace detail
 		w(1)
 	{}
 
+	template <typename T, precision P>
+	template <typename U, precision Q>
+	GLM_FUNC_QUALIFIER tquat<T, P>::tquat
+	(
+		tquat<U, Q> const & q
+	) :
+		x(q.x),
+		y(q.y),
+		z(q.z),
+		w(q.w)
+	{}
+
 	template <typename T, precision P>
 	GLM_FUNC_QUALIFIER tquat<T, P>::tquat
 	(
@@ -777,4 +789,114 @@ namespace detail
 		return result;
 	}
 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER typename detail::tquat<T, P>::bool_type lessThan
+	(
+		detail::tquat<T, P> const & x,
+		detail::tquat<T, P> const & y
+	)
+	{
+		//GLM_STATIC_ASSERT(detail::is_vector<vecType<T, P> >::_YES,
+		//	"Invalid template instantiation of 'lessThan', GLM vector types required");
+		GLM_STATIC_ASSERT(detail::is_bool<T>::_NO,
+			"Invalid template instantiation of 'lessThan', GLM vector types required floating-point or integer value types vectors");
+		assert(x.length() == y.length());
+
+		typename detail::tquat<T, P>::bool_type Result(detail::tquat<T, P>::null);
+		for(typename detail::tquat<T, P>::size_type i = 0; i < x.length(); ++i)
+			Result[i] = x[i] < y[i];
+
+		return Result;
+	}
+
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER typename detail::tquat<T, P>::bool_type lessThanEqual
+	(
+		detail::tquat<T, P> const & x,
+		detail::tquat<T, P> const & y
+	)
+	{
+		//GLM_STATIC_ASSERT(detail::is_vector<vecType<T, P> >::_YES,
+		//	"Invalid template instantiation of 'lessThanEqual', GLM vector types required");
+		GLM_STATIC_ASSERT(detail::is_bool<T>::_NO,
+			"Invalid template instantiation of 'lessThanEqual', GLM vector types required floating-point or integer value types vectors");
+		assert(x.length() == y.length());
+
+		typename detail::tquat<T, P>::bool_type Result(detail::tquat<T, P>::null);
+		for(typename detail::tquat<T, P>::size_type i = 0; i < x.length(); ++i)
+			Result[i] = x[i] <= y[i];
+		return Result;
+	}
+
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER typename detail::tquat<T, P>::bool_type greaterThan
+	(
+		detail::tquat<T, P> const & x,
+		detail::tquat<T, P> const & y
+	)
+	{
+		//GLM_STATIC_ASSERT(detail::is_vector<vecType<T, P> >::_YES,
+		//	"Invalid template instantiation of 'greaterThan', GLM vector types required");
+		GLM_STATIC_ASSERT(detail::is_bool<T>::_NO,
+			"Invalid template instantiation of 'greaterThan', GLM vector types required floating-point or integer value types vectors");
+		assert(x.length() == y.length());
+
+		typename detail::tquat<T, P>::bool_type Result(detail::tquat<T, P>::null);
+		for(typename detail::tquat<T, P>::size_type i = 0; i < x.length(); ++i)
+			Result[i] = x[i] > y[i];
+		return Result;
+	}
+
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER typename detail::tquat<T, P>::bool_type greaterThanEqual
+	(
+		detail::tquat<T, P> const & x,
+		detail::tquat<T, P> const & y
+	)
+	{
+		//GLM_STATIC_ASSERT(detail::is_vector<vecType<T, P> >::_YES,
+		//	"Invalid template instantiation of 'greaterThanEqual', GLM vector types required");
+		GLM_STATIC_ASSERT(detail::is_bool<T>::_NO,
+			"Invalid template instantiation of 'greaterThanEqual', GLM vector types required floating-point or integer value types vectors");
+		assert(x.length() == y.length());
+
+		typename detail::tquat<T, P>::bool_type Result(detail::tquat<T, P>::null);
+		for(typename detail::tquat<T, P>::size_type i = 0; i < x.length(); ++i)
+			Result[i] = x[i] >= y[i];
+		return Result;
+	}
+
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER typename detail::tquat<T, P>::bool_type equal
+	(
+		detail::tquat<T, P> const & x,
+		detail::tquat<T, P> const & y
+	)
+	{
+		//GLM_STATIC_ASSERT(detail::is_vector<vecType<T, P> >::_YES,
+		//	"Invalid template instantiation of 'equal', GLM vector types required");
+		assert(x.length() == y.length());
+
+		typename detail::tquat<T, P>::bool_type Result(detail::tquat<T, P>::null);
+		for(typename detail::tquat<T, P>::size_type i = 0; i < x.length(); ++i)
+			Result[i] = x[i] == y[i];
+		return Result;
+	}
+
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER typename detail::tquat<T, P>::bool_type notEqual
+	(
+		detail::tquat<T, P> const & x,
+		detail::tquat<T, P> const & y
+	)
+	{
+		//GLM_STATIC_ASSERT(detail::is_vector<vecType<T, P> >::_YES,
+		//	"Invalid template instantiation of 'notEqual', GLM vector types required");
+		assert(x.length() == y.length());
+
+		typename detail::tquat<T, P>::bool_type Result(detail::tquat<T, P>::null);
+		for(typename detail::tquat<T, P>::size_type i = 0; i < x.length(); ++i)
+			Result[i] = x[i] != y[i];
+		return Result;
+	}
 }//namespace glm

+ 2 - 0
readme.txt

@@ -45,6 +45,8 @@ GLM 0.9.5.0: 2013-XX-XX
 - Added GTX_scalar_relational
 - Added GTX_dual_quaternion
 - Added rotation function to GTX_quaternion (#22)
+- Added precision variation of each type
+- Added quaternion comparison functions
 
 ================================================================================
 GLM 0.9.4.3: 2013-03-20

+ 227 - 2
test/gtc/gtc_type_precision.cpp

@@ -9,6 +9,7 @@
 
 #include <glm/glm.hpp>
 #include <glm/gtc/type_precision.hpp>
+#include <glm/gtc/quaternion.hpp>
 
 static int test_scalar_size()
 {
@@ -108,6 +109,126 @@ static int test_fvec_size()
 	return Error;
 }
 
+static int test_hvec_precision()
+{
+	int Error(0);
+
+	{
+		glm::f16vec2 v1;
+		glm::lowp_f16vec2 v2(v1);
+		glm::mediump_f16vec2 v3(v1);
+		glm::highp_f16vec2 v4(v1);
+
+		Error += glm::all(glm::equal(v1, glm::f16vec2(v2))) ? 0 : 1;
+		Error += glm::all(glm::equal(v1, glm::f16vec2(v3))) ? 0 : 1;
+		Error += glm::all(glm::equal(v1, glm::f16vec2(v4))) ? 0 : 1;
+	}
+
+	{
+		glm::f16vec3 v1;
+		glm::lowp_f16vec3 v2(v1);
+		glm::mediump_f16vec3 v3(v1);
+		glm::highp_f16vec3 v4(v1);
+
+		Error += glm::all(glm::equal(v1, glm::f16vec3(v2))) ? 0 : 1;
+		Error += glm::all(glm::equal(v1, glm::f16vec3(v3))) ? 0 : 1;
+		Error += glm::all(glm::equal(v1, glm::f16vec3(v4))) ? 0 : 1;
+	}
+	
+	{
+		glm::f16vec4 v1;
+		glm::lowp_f16vec4 v2(v1);
+		glm::mediump_f16vec4 v3(v1);
+		glm::highp_f16vec4 v4(v1);
+
+		Error += glm::all(glm::equal(v1, glm::f16vec4(v2))) ? 0 : 1;
+		Error += glm::all(glm::equal(v1, glm::f16vec4(v3))) ? 0 : 1;
+		Error += glm::all(glm::equal(v1, glm::f16vec4(v4))) ? 0 : 1;
+	}
+	
+	return Error;
+}
+
+static int test_fvec_precision()
+{
+	int Error(0);
+	
+	{
+		glm::f32vec2 v1;
+		glm::lowp_f32vec2 v2(v1);
+		glm::mediump_f32vec2 v3(v1);
+		glm::highp_f32vec2 v4(v1);
+
+		Error += glm::all(glm::equal(v1, glm::f32vec2(v2))) ? 0 : 1;
+		Error += glm::all(glm::equal(v1, glm::f32vec2(v3))) ? 0 : 1;
+		Error += glm::all(glm::equal(v1, glm::f32vec2(v4))) ? 0 : 1;
+	}
+
+	{
+		glm::f32vec3 v1;
+		glm::lowp_f32vec3 v2(v1);
+		glm::mediump_f32vec3 v3(v1);
+		glm::highp_f32vec3 v4(v1);
+
+		Error += glm::all(glm::equal(v1, glm::f32vec3(v2))) ? 0 : 1;
+		Error += glm::all(glm::equal(v1, glm::f32vec3(v3))) ? 0 : 1;
+		Error += glm::all(glm::equal(v1, glm::f32vec3(v4))) ? 0 : 1;
+	}
+	
+	{
+		glm::f32vec4 v1;
+		glm::lowp_f32vec4 v2(v1);
+		glm::mediump_f32vec4 v3(v1);
+		glm::highp_f32vec4 v4(v1);
+
+		Error += glm::all(glm::equal(v1, glm::f32vec4(v2))) ? 0 : 1;
+		Error += glm::all(glm::equal(v1, glm::f32vec4(v3))) ? 0 : 1;
+		Error += glm::all(glm::equal(v1, glm::f32vec4(v4))) ? 0 : 1;
+	}
+	
+	return Error;
+}
+
+static int test_dvec_precision()
+{
+	int Error(0);
+	
+	{
+		glm::f64vec2 v1;
+		glm::lowp_f64vec2 v2(v1);
+		glm::mediump_f64vec2 v3(v1);
+		glm::highp_f64vec2 v4(v1);
+
+		Error += glm::all(glm::equal(v1, glm::f64vec2(v2))) ? 0 : 1;
+		Error += glm::all(glm::equal(v1, glm::f64vec2(v3))) ? 0 : 1;
+		Error += glm::all(glm::equal(v1, glm::f64vec2(v4))) ? 0 : 1;
+	}
+
+	{
+		glm::f64vec3 v1;
+		glm::lowp_f64vec3 v2(v1);
+		glm::mediump_f64vec3 v3(v1);
+		glm::highp_f64vec3 v4(v1);
+
+		Error += glm::all(glm::equal(v1, glm::f64vec3(v2))) ? 0 : 1;
+		Error += glm::all(glm::equal(v1, glm::f64vec3(v3))) ? 0 : 1;
+		Error += glm::all(glm::equal(v1, glm::f64vec3(v4))) ? 0 : 1;
+	}
+	
+	{
+		glm::f64vec4 v1;
+		glm::lowp_f64vec4 v2(v1);
+		glm::mediump_f64vec4 v3(v1);
+		glm::highp_f64vec4 v4(v1);
+
+		Error += glm::all(glm::equal(v1, glm::f64vec4(v2))) ? 0 : 1;
+		Error += glm::all(glm::equal(v1, glm::f64vec4(v3))) ? 0 : 1;
+		Error += glm::all(glm::equal(v1, glm::f64vec4(v4))) ? 0 : 1;
+	}
+	
+	return Error;
+}
+
 static int test_ivec_size()
 {
 	int Error(0);
@@ -165,6 +286,46 @@ static int test_ivec_size()
 	return Error;
 }
 
+static int test_ivec_precision()
+{
+	int Error(0);
+	
+	{
+		glm::i64vec2 v1;
+		glm::lowp_i64vec2 v2(v1);
+		glm::mediump_i64vec2 v3(v1);
+		glm::highp_i64vec2 v4(v1);
+
+		Error += glm::all(glm::equal(v1, glm::i64vec2(v2))) ? 0 : 1;
+		Error += glm::all(glm::equal(v1, glm::i64vec2(v3))) ? 0 : 1;
+		Error += glm::all(glm::equal(v1, glm::i64vec2(v4))) ? 0 : 1;
+	}
+
+	{
+		glm::i64vec3 v1;
+		glm::lowp_i64vec3 v2(v1);
+		glm::mediump_i64vec3 v3(v1);
+		glm::highp_i64vec3 v4(v1);
+
+		Error += glm::all(glm::equal(v1, glm::i64vec3(v2))) ? 0 : 1;
+		Error += glm::all(glm::equal(v1, glm::i64vec3(v3))) ? 0 : 1;
+		Error += glm::all(glm::equal(v1, glm::i64vec3(v4))) ? 0 : 1;
+	}
+	
+	{
+		glm::i64vec4 v1;
+		glm::lowp_i64vec4 v2(v1);
+		glm::mediump_i64vec4 v3(v1);
+		glm::highp_i64vec4 v4(v1);
+
+		Error += glm::all(glm::equal(v1, glm::i64vec4(v2))) ? 0 : 1;
+		Error += glm::all(glm::equal(v1, glm::i64vec4(v3))) ? 0 : 1;
+		Error += glm::all(glm::equal(v1, glm::i64vec4(v4))) ? 0 : 1;
+	}
+	
+	return Error;
+}
+
 static int test_uvec_size()
 {
 	int Error(0);
@@ -222,6 +383,46 @@ static int test_uvec_size()
 	return Error;
 }
 
+static int test_uvec_precision()
+{
+	int Error(0);
+	
+	{
+		glm::u64vec2 v1;
+		glm::lowp_u64vec2 v2(v1);
+		glm::mediump_u64vec2 v3(v1);
+		glm::highp_u64vec2 v4(v1);
+
+		Error += glm::all(glm::equal(v1, glm::u64vec2(v2))) ? 0 : 1;
+		Error += glm::all(glm::equal(v1, glm::u64vec2(v3))) ? 0 : 1;
+		Error += glm::all(glm::equal(v1, glm::u64vec2(v4))) ? 0 : 1;
+	}
+
+	{
+		glm::u64vec3 v1;
+		glm::lowp_u64vec3 v2(v1);
+		glm::mediump_u64vec3 v3(v1);
+		glm::highp_u64vec3 v4(v1);
+
+		Error += glm::all(glm::equal(v1, glm::u64vec3(v2))) ? 0 : 1;
+		Error += glm::all(glm::equal(v1, glm::u64vec3(v3))) ? 0 : 1;
+		Error += glm::all(glm::equal(v1, glm::u64vec3(v4))) ? 0 : 1;
+	}
+	
+	{
+		glm::u64vec4 v1;
+		glm::lowp_u64vec4 v2(v1);
+		glm::mediump_u64vec4 v3(v1);
+		glm::highp_u64vec4 v4(v1);
+
+		Error += glm::all(glm::equal(v1, glm::u64vec4(v2))) ? 0 : 1;
+		Error += glm::all(glm::equal(v1, glm::u64vec4(v3))) ? 0 : 1;
+		Error += glm::all(glm::equal(v1, glm::u64vec4(v4))) ? 0 : 1;
+	}
+	
+	return Error;
+}
+
 static int test_hmat_size()
 {
 	int Error(0);
@@ -504,7 +705,7 @@ static int test_dmat_size()
 static int test_quat_size()
 {
 	int Error = 0;
-	Error += sizeof(glm::lowp_f16quat) != 8;
+	Error += sizeof(glm::f16quat) != 8;
 	Error += sizeof(glm::f32quat) != 16;
 	Error += sizeof(glm::f64quat) != 32;
 	
@@ -522,16 +723,40 @@ static int test_quat_size()
 	return Error;
 }
 
+static int test_quat_precision()
+{
+	int Error(0);
+	
+	{
+		glm::f32quat q1;
+		glm::f32quat q2(glm::lowp_f32quat(q1));
+		glm::f32quat q3(glm::mediump_f32quat(q1));
+		glm::f32quat q4(glm::highp_f32quat(q1));
+		
+		//Error += glm::all(glm::equal(q1, q2)) ? 0 : 1;
+		//Error += glm::all(glm::equal(q1, q3)) ? 0 : 1;
+		//Error += glm::all(glm::equal(q1, q4)) ? 0 : 1;
+	}
+	
+	return Error;
+}
+
 int main()
 {
-	int Error = 0;
+	int Error(0);
 	Error += test_scalar_size();
 	Error += test_fvec_size();
+	Error += test_hvec_precision();
+	Error += test_fvec_precision();
+	Error += test_dvec_precision();
 	Error += test_ivec_size();
+	Error += test_ivec_precision();
 	Error += test_uvec_size();
+	Error += test_uvec_precision();
 	Error += test_hmat_size();
 	Error += test_fmat_size();
 	Error += test_dmat_size();
 	Error += test_quat_size();
+	Error += test_quat_precision();
 	return Error;
 }