Browse Source

Fixed undefined reference to fastInverseSqrt (#161)

Christophe Riccio 12 years ago
parent
commit
a310855d23

+ 24 - 0
glm/detail/_vectorize.hpp

@@ -29,10 +29,20 @@
 #ifndef GLM_CORE_DETAIL_INCLUDED
 #define GLM_CORE_DETAIL_INCLUDED
 
+#include "type_vec1.hpp"
 #include "type_vec2.hpp"
 #include "type_vec3.hpp"
 #include "type_vec4.hpp"
 
+#define VECTORIZE1_VEC(func)						\
+	template <typename T, precision P>				\
+	GLM_FUNC_QUALIFIER detail::tvec1<T, P> func(	\
+		detail::tvec1<T, P> const & v)				\
+	{												\
+		return detail::tvec1<T, P>(					\
+			func(v.x));								\
+	}
+
 #define VECTORIZE2_VEC(func)						\
 	template <typename T, precision P>				\
 	GLM_FUNC_QUALIFIER detail::tvec2<T, P> func(	\
@@ -67,10 +77,23 @@
 	}
 
 #define VECTORIZE_VEC(func)		\
+	VECTORIZE1_VEC(func)		\
 	VECTORIZE2_VEC(func)		\
 	VECTORIZE3_VEC(func)		\
 	VECTORIZE4_VEC(func)
 
+#define VECTORIZE1_VEC_SCA(func)							\
+	template <typename T, precision P>						\
+	GLM_FUNC_QUALIFIER detail::tvec1<T, P> func				\
+	(														\
+		detail::tvec1<T, P> const & x,						\
+		T const & y											\
+	)														\
+	{														\
+		return detail::tvec1<T, P>(							\
+			func(x.x, y));									\
+	}
+
 #define VECTORIZE2_VEC_SCA(func)							\
 	template <typename T, precision P>						\
 	GLM_FUNC_QUALIFIER detail::tvec2<T, P> func				\
@@ -114,6 +137,7 @@
 	}
 
 #define VECTORIZE_VEC_SCA(func)		\
+	VECTORIZE1_VEC_SCA(func)		\
 	VECTORIZE2_VEC_SCA(func)		\
 	VECTORIZE3_VEC_SCA(func)		\
 	VECTORIZE4_VEC_SCA(func)

+ 45 - 52
glm/detail/func_exponential.inl

@@ -31,8 +31,51 @@
 #include <limits>
 #include <cassert>
 
-namespace glm
+namespace glm{
+namespace detail
 {
+	template <bool isFloat>
+	struct compute_log2
+	{
+		template <typename T>
+		T operator() (T const & Value) const;
+	};
+
+	template <>
+	struct compute_log2<true>
+	{
+		template <typename T>
+		T operator() (T const & Value) const
+		{
+			return static_cast<T>(::std::log(Value)) * static_cast<T>(1.4426950408889634073599246810019);
+		}
+	};
+
+	template <template <class, precision> class vecType, typename T, precision P>
+	struct compute_inversesqrt
+	{
+		static vecType<T, P> call(vecType<T, P> const & x)
+		{
+			return static_cast<T>(1) / sqrt(x);
+		}
+	};
+		
+	template <template <class, precision> class vecType>
+	struct compute_inversesqrt<vecType, float, lowp>
+	{
+		static vecType<float, lowp> call(vecType<float, lowp> const & x)
+		{
+			vecType<float, lowp> tmp(x);
+			vecType<float, lowp> xhalf(tmp * 0.5f);
+			vecType<uint, lowp> i = *reinterpret_cast<vecType<uint, lowp>*>(const_cast<vecType<float, lowp>*>(&x));
+			i = vecType<uint, lowp>(0x5f375a86) - (i >> vecType<uint, lowp>(1));
+			tmp = *reinterpret_cast<vecType<float, lowp>*>(&i);
+			tmp = tmp * (1.5f - xhalf * tmp * tmp);
+			return tmp;
+		}
+	};
+}//namespace detail
+
 	// pow
 	template <typename genType>
 	GLM_FUNC_QUALIFIER genType pow
@@ -98,27 +141,6 @@ namespace glm
 
 	VECTORIZE_VEC(exp2)
 
-namespace detail
-{
-	template <bool isFloat>
-	struct compute_log2
-	{
-		template <typename T>
-		T operator() (T const & Value) const;
-	};
-
-	template <>
-	struct compute_log2<true>
-	{
-		template <typename T>
-		T operator() (T const & Value) const
-		{
-			return static_cast<T>(::std::log(Value)) * static_cast<T>(1.4426950408889634073599246810019);
-		}
-	};
-
-}//namespace detail
-
 	// log2, ln2 = 0.69314718055994530941723212145818f
 	template <typename genType>
 	GLM_FUNC_QUALIFIER genType log2
@@ -142,9 +164,7 @@ namespace detail
 		genType const & x
 	)
 	{
-		GLM_STATIC_ASSERT(
-			std::numeric_limits<genType>::is_iec559,
-			"'sqrt' only accept floating-point inputs");
+		GLM_STATIC_ASSERT(std::numeric_limits<genType>::is_iec559, "'sqrt' only accept floating-point inputs");
 
 		assert(x >= genType(0));
 
@@ -153,33 +173,6 @@ namespace detail
 
 	VECTORIZE_VEC(sqrt)
 
-	namespace detail
-	{
-		template <template <class, precision> class vecType, typename T, precision P>
-		struct compute_inversesqrt
-		{
-			static vecType<T, P> call(vecType<T, P> const & x)
-			{
-				return static_cast<T>(1) / sqrt(x);
-			}
-		};
-		
-		template <template <class, precision> class vecType>
-		struct compute_inversesqrt<vecType, float, lowp>
-		{
-			static vecType<float, lowp> call(vecType<float, lowp> const & x)
-			{
-				vecType<float, lowp> tmp(x);
-				vecType<float, lowp> xhalf(tmp * 0.5f);
-				vecType<uint, lowp> i = *reinterpret_cast<vecType<uint, lowp>*>(const_cast<vecType<float, lowp>*>(&x));
-				i = vecType<uint, lowp>(0x5f375a86) - (i >> vecType<uint, lowp>(1));
-				tmp = *reinterpret_cast<vecType<float, lowp>*>(&i);
-				tmp = tmp * (1.5f - xhalf * tmp * tmp);
-				return tmp;
-			}
-		};
-	}//namespace detail
-	
 	// inversesqrt
 	GLM_FUNC_QUALIFIER float inversesqrt(float const & x)
 	{

+ 11 - 6
glm/gtx/fast_square_root.hpp

@@ -55,27 +55,32 @@ namespace glm
 	//! Faster than the common sqrt function but less accurate.
 	//! From GLM_GTX_fast_square_root extension.
 	template <typename genType> 
-	genType fastSqrt(genType const & x);
+	GLM_FUNC_DECL genType fastSqrt(genType const & x);
 
 	//! Faster than the common inversesqrt function but less accurate.
 	//! From GLM_GTX_fast_square_root extension.
 	template <typename genType> 
-	genType fastInverseSqrt(genType const & x);
-		
+	GLM_FUNC_DECL genType fastInverseSqrt(genType const & x);
+
+	//! Faster than the common inversesqrt function but less accurate.
+	//! From GLM_GTX_fast_square_root extension.
+	template <typename T, precision P, template <typename, precision> class vecType>
+	GLM_FUNC_DECL vecType<T, P> fastInverseSqrt(vecType<T, P> const & x);
+
 	//! Faster than the common length function but less accurate.
 	//! From GLM_GTX_fast_square_root extension.
 	template <typename genType> 
-	typename genType::value_type fastLength(genType const & x);
+	GLM_FUNC_DECL typename genType::value_type fastLength(genType const & x);
 
 	//! Faster than the common distance function but less accurate.
 	//! From GLM_GTX_fast_square_root extension.
 	template <typename genType> 
-	typename genType::value_type fastDistance(genType const & x, genType const & y);
+	GLM_FUNC_DECL typename genType::value_type fastDistance(genType const & x, genType const & y);
 
 	//! Faster than the common normalize function but less accurate.
 	//! From GLM_GTX_fast_square_root extension.
 	template <typename genType> 
-	genType fastNormalize(genType const & x);
+	GLM_FUNC_DECL genType fastNormalize(genType const & x);
 
 	/// @}
 }// namespace glm

+ 9 - 2
glm/gtx/fast_square_root.inl

@@ -24,11 +24,18 @@ namespace glm
 	VECTORIZE_VEC(fastSqrt)
 
 	// fastInversesqrt
-	GLM_FUNC_QUALIFIER float fastInverseSqrt(float x)
+	template <>
+	GLM_FUNC_QUALIFIER float fastInverseSqrt<float>(float const & x)
 	{
 		return detail::compute_inversesqrt<detail::tvec1, float, lowp>::call(detail::tvec1<float, lowp>(x)).x;
 	}
-	
+
+	template <>
+	GLM_FUNC_QUALIFIER double fastInverseSqrt<double>(double const & x)
+	{
+		return detail::compute_inversesqrt<detail::tvec1, double, lowp>::call(detail::tvec1<double, lowp>(x)).x;
+	}
+
 	template <template <class, precision> class vecType, typename T, precision P>
 	GLM_FUNC_QUALIFIER vecType<T, P> fastInverseSqrt
 	(

+ 1 - 0
readme.txt

@@ -44,6 +44,7 @@ GLM 0.9.5.2: 2014-02-08
 - Fixed non power of two matrix products
 - Fixed mix function link error
 - Fixed SSE code included in GLM tests on "pure" platforms
+- Fixed undefined reference to fastInverseSqrt (#161)
 
 ================================================================================
 GLM 0.9.5.1: 2014-01-11

+ 19 - 1
test/gtx/gtx_fast_square_root.cpp

@@ -8,12 +8,30 @@
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 #define GLM_FORCE_RADIANS
-#include <glm/gtc/type_precision.hpp>
 #include <glm/gtx/fast_square_root.hpp>
+#include <glm/gtc/type_precision.hpp>
+#include <glm/gtc/epsilon.hpp>
+#include <glm/vector_relational.hpp>
+
+int test_fastInverseSqrt()
+{
+	int Error(0);
+
+	Error += glm::epsilonEqual(glm::fastInverseSqrt(1.0f), 1.0f, 0.01f) ? 0 : 1;
+	Error += glm::epsilonEqual(glm::fastInverseSqrt(1.0), 1.0, 0.01) ? 0 : 1;
+	Error += glm::all(glm::epsilonEqual(glm::fastInverseSqrt(glm::vec2(1.0f)), glm::vec2(1.0f), 0.01f)) ? 0 : 1;
+	Error += glm::all(glm::epsilonEqual(glm::fastInverseSqrt(glm::dvec3(1.0)), glm::dvec3(1.0), 0.01)) ? 0 : 1;
+	Error += glm::all(glm::epsilonEqual(glm::fastInverseSqrt(glm::dvec4(1.0)), glm::dvec4(1.0), 0.01)) ? 0 : 1;
+
+	
+	return 0;
+}
 
 int main()
 {
 	int Error(0);
 
+	Error += test_fastInverseSqrt();
+
 	return Error;
 }