瀏覽代碼

Factorized fastInversesqrt code

Christophe Riccio 12 年之前
父節點
當前提交
6838815f9f
共有 3 個文件被更改,包括 21 次插入38 次删除
  1. 1 1
      glm/core/func_exponential.hpp
  2. 19 28
      glm/core/func_exponential.inl
  3. 1 9
      glm/gtx/fast_square_root.inl

+ 1 - 1
glm/core/func_exponential.hpp

@@ -104,7 +104,7 @@ namespace glm
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.2 Exponential Functions</a>
 	template <typename genType> 
 	GLM_FUNC_DECL genType sqrt(genType const & x);
-    
+
 	/// Returns the reciprocal of the positive square root of x.
 	/// 
 	/// @param x inversesqrt function is defined for input values of x defined in the range [0, inf+) in the limit of the type precision.

+ 19 - 28
glm/core/func_exponential.inl

@@ -153,52 +153,43 @@ namespace _detail
 
 	VECTORIZE_VEC(inversesqrt)
 
+	namespace detail
+	{
+		template <typename genType, typename genUType>
+		genType fastInversesqrt(genType const & v)
+		{
+			genType tmp(v);
+			genType xhalf(tmp * genType(0.5f));
+			genUType i = *reinterpret_cast<genUType*>(const_cast<genType*>(&v));
+			i = genUType(0x5f375a86) - (i >> genUType(1));
+			tmp = *reinterpret_cast<genType*>(&i);
+			tmp = tmp * (genType(1.5f) - xhalf * tmp * tmp);
+			return tmp;
+		}
+	}
+
 	template <>
 	GLM_FUNC_QUALIFIER lowp_vec1 inversesqrt(lowp_vec1 const & v)
 	{
-		float tmp(v.x);
-		float xhalf(0.5f * tmp);
-		uint i = *reinterpret_cast<uint*>(const_cast<lowp_vec1*>(&v));
-		i = 0x5f375a86 - (i >> 1);
-		tmp = *reinterpret_cast<float*>(i);
-		tmp = tmp * (1.5f - xhalf * tmp * tmp);
-		return lowp_vec1(tmp);
+		return detail::fastInversesqrt<lowp_vec1, uint>(v);
 	}
 
 	template <>
 	GLM_FUNC_QUALIFIER lowp_vec2 inversesqrt(lowp_vec2 const & v)
 	{
-		lowp_vec2 tmp(v);
-		lowp_vec2 xhalf(0.5f * tmp);
-		lowp_uvec2 i = *reinterpret_cast<lowp_uvec2*>(const_cast<lowp_vec2*>(&v));
-		i = lowp_uvec2(0x5f375a86) - (i >> lowp_uvec2(1));
-		tmp = *reinterpret_cast<lowp_vec2*>(&i);
-		tmp = tmp * (1.5f - xhalf * tmp * tmp);
-		return tmp;
+		return detail::fastInversesqrt<lowp_vec2, lowp_uvec2>(v);
 	}
 
 	template <>
 	GLM_FUNC_QUALIFIER lowp_vec3 inversesqrt(lowp_vec3 const & v)
 	{
-		lowp_vec3 tmp(v);
-		lowp_vec3 xhalf(0.5f * tmp);
-		lowp_uvec3 i = *reinterpret_cast<lowp_uvec3*>(const_cast<lowp_vec3*>(&v));
-		i = lowp_uvec3(0x5f375a86) - (i >> lowp_uvec3(1));
-		tmp = *reinterpret_cast<lowp_vec3*>(&i);
-		tmp = tmp * (1.5f - xhalf * tmp * tmp);
-		return tmp;
+		return detail::fastInversesqrt<lowp_vec3, lowp_uvec3>(v);
 	}
 
 	template <>
 	GLM_FUNC_QUALIFIER lowp_vec4 inversesqrt(lowp_vec4 const & v)
 	{
-		lowp_vec4 tmp(v);
-		lowp_vec4 xhalf(0.5f * tmp);
-		lowp_uvec4 i = *reinterpret_cast<lowp_uvec4*>(const_cast<lowp_vec4*>(&v));
-		i = lowp_uvec4(0x5f375a86) - (i >> lowp_uvec4(1));
-		tmp = *reinterpret_cast<lowp_vec4*>(&i);
-		tmp = tmp * (1.5f - xhalf * tmp * tmp);
-		return tmp;
+		return detail::fastInversesqrt<lowp_vec4, lowp_uvec4>(v);
 	}
 
 }//namespace glm

+ 1 - 9
glm/gtx/fast_square_root.inl

@@ -30,15 +30,7 @@ namespace glm
 		genType const & x
 	)
 	{
-		genType tmp = x;
-		float xhalf = 0.5f * float(tmp);
-		uint i = *(uint*)&x;
-		i = 0x5f375a86 - (i >> 1);
-		//x = *(float*)&i;
-		//x = *((float*)(char*)&i);
-		tmp = detail::uif32(i).f;
-		tmp = tmp * (1.5f - xhalf * tmp * tmp);
-		return genType(tmp);
+		return detail::fastInversesqrt<genType, uint>(x);
 	}
 
 	VECTORIZE_VEC(fastInverseSqrt)