Browse Source

Added uint log2 and deprecate GTX_unsigned_int

Christophe Riccio 14 years ago
parent
commit
09ee14ad4c

+ 1 - 0
glm/core/func_common.inl

@@ -42,6 +42,7 @@ namespace detail
                 detail::type<genFIType>::is_float || 
                 detail::type<genFIType>::is_int, "'abs' only accept floating-point and integer inputs");
             return x >= genFIType(0) ? x : -x;
+			// TODO, perf comp with: *(((int *) &x) + 1) &= 0x7fffffff;
         }
     };
 

+ 0 - 1
glm/ext.hpp

@@ -124,7 +124,6 @@
 #include "./gtx/transform.hpp"
 #include "./gtx/transform2.hpp"
 #include "./gtx/ulp.hpp"
-#include "./gtx/unsigned_int.hpp"
 #include "./gtx/vec1.hpp"
 #include "./gtx/vector_access.hpp"
 #include "./gtx/vector_angle.hpp"

+ 20 - 0
glm/gtx/integer.hpp

@@ -58,6 +58,10 @@ namespace glm
 	//! From GLM_GTX_integer extension.
 	int sqrt(int x);
 
+	//! Returns the log2 of x.
+	//! From GLM_GTX_integer extension.
+	unsigned int log2(unsigned int x);
+
 	//! Modulus. Returns x - y * floor(x / y) for each component in x using the floating point value y.
 	//! From GLM_GTX_integer extension.
 	int mod(int x, int y);
@@ -67,6 +71,22 @@ namespace glm
 	template <typename genType> 
 	genType factorial(genType const & x);
 
+	//! 32bit signed integer. 
+	//! From GLM_GTX_unsigned_int extension.
+	typedef signed int					sint;
+
+	//! Returns x raised to the y power.
+	//! From GLM_GTX_unsigned_int extension.
+	uint pow(uint x, uint y);
+
+	//! Returns the positive square root of x. 
+	//! From GLM_GTX_unsigned_int extension.
+	uint sqrt(uint x);
+
+	//! Modulus. Returns x - y * floor(x / y) for each component in x using the floating point value y.
+	//! From GLM_GTX_unsigned_int extension.
+	uint mod(uint x, uint y);
+
 	/// @}
 }//namespace glm
 

+ 75 - 0
glm/gtx/integer.inl

@@ -37,6 +37,52 @@ GLM_FUNC_QUALIFIER int sqrt(int x)
     return CurrentAnswer;
 }
 
+// Henry Gordon Dietz: http://aggregate.org/MAGIC/
+namespace detail
+{
+	GLM_FUNC_QUALIFIER unsigned int ones32(unsigned int x)
+	{
+		/* 32-bit recursive reduction using SWAR...
+		but first step is mapping 2-bit values
+		into sum of 2 1-bit values in sneaky way
+		*/
+		x -= ((x >> 1) & 0x55555555);
+		x = (((x >> 2) & 0x33333333) + (x & 0x33333333));
+		x = (((x >> 4) + x) & 0x0f0f0f0f);
+		x += (x >> 8);
+		x += (x >> 16);
+		return(x & 0x0000003f);
+	}
+}//namespace detail
+/*
+// Henry Gordon Dietz: http://aggregate.org/MAGIC/
+GLM_FUNC_QUALIFIER unsigned int log2(unsigned int x)
+{
+	register int y = (x & (x - 1));
+
+	y |= -y;
+	y >>= (WORDBITS - 1);
+	x |= (x >> 1);
+	x |= (x >> 2);
+	x |= (x >> 4);
+	x |= (x >> 8);
+	x |= (x >> 16);
+	
+	return detail::ones32(x) - 1 - y;
+}
+*/
+// Henry Gordon Dietz: http://aggregate.org/MAGIC/
+unsigned int log2(unsigned int x)
+{
+	x |= (x >> 1);
+	x |= (x >> 2);
+	x |= (x >> 4);
+	x |= (x >> 8);
+	x |= (x >> 16);
+
+	return(detail::ones32(x) - 1);
+}
+
 // mod
 GLM_FUNC_QUALIFIER int mod(int x, int y)
 {
@@ -84,4 +130,33 @@ GLM_FUNC_QUALIFIER detail::tvec4<valType> factorial(
         factorial(x.w));
 }
 
+GLM_FUNC_QUALIFIER uint pow(uint x, uint y)
+{
+    uint result = x;
+    for(uint i = 1; i < y; ++i)
+        result *= x;
+    return result;
+}
+
+GLM_FUNC_QUALIFIER uint sqrt(uint x)
+{
+    if(x <= 1) return x;
+
+    uint NextTrial = x >> 1;
+    uint CurrentAnswer;
+
+    do
+    {
+        CurrentAnswer = NextTrial;
+        NextTrial = (NextTrial + x / NextTrial) >> 1;
+    } while(NextTrial < CurrentAnswer);
+
+    return CurrentAnswer;
+}
+
+GLM_FUNC_QUALIFIER uint mod(uint x, uint y)
+{
+	return x - y * (x / y);
+}
+
 }//namespace glm

+ 2 - 52
glm/gtx/unsigned_int.hpp

@@ -19,58 +19,8 @@
 /// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 /// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 /// THE SOFTWARE.
-///
-/// @ref gtx_unsigned_int
-/// @file glm/gtx/unsigned_int.hpp
-/// @date 2005-12-24 / 2011-06-07
-/// @author Christophe Riccio
-///
-/// @see core (dependence)
-/// @see gtx_integer (dependence)
-///
-/// @defgroup gtx_unsigned_int GLM_GTX_unsigned_int: Unsigned int
-/// @ingroup gtx
-/// 
-/// @brief Add support for unsigned integer for core functions
-/// 
-/// <glm/gtx/unsigned_int.hpp> need to be included to use these functionalities.
 ///////////////////////////////////////////////////////////////////////////////////
 
-#ifndef GLM_GTX_unsigned_int
-#define GLM_GTX_unsigned_int GLM_VERSION
-
-// Dependency:
-#include "../glm.hpp"
-#include "../gtx/integer.hpp"
-
-#if(defined(GLM_MESSAGES) && !defined(glm_ext))
-#	pragma message("GLM: GLM_GTX_unsigned_int extension included")
+#if(defined(GLM_MESSAGES))
+#	pragma message("GLM: GLM_GTX_unsigned_int extension is deprecated, include GLM_GTX_integer instead")
 #endif
-
-namespace glm
-{
-	/// @addtogroup gtx_unsigned_int
-	/// @{
-
-	//! 32bit signed integer. 
-	//! From GLM_GTX_unsigned_int extension.
-	typedef signed int					sint;
-
-	//! Returns x raised to the y power.
-	//! From GLM_GTX_unsigned_int extension.
-	uint pow(uint x, uint y);
-
-	//! Returns the positive square root of x. 
-	//! From GLM_GTX_unsigned_int extension.
-	uint sqrt(uint x);
-
-	//! Modulus. Returns x - y * floor(x / y) for each component in x using the floating point value y.
-	//! From GLM_GTX_unsigned_int extension.
-	uint mod(uint x, uint y);
-
-	/// @}
-}//namespace glm
-
-#include "unsigned_int.inl"
-
-#endif//GLM_GTX_unsigned_int

+ 0 - 28
glm/gtx/unsigned_int.inl

@@ -9,33 +9,5 @@
 
 namespace glm{
 
-GLM_FUNC_QUALIFIER uint pow(uint x, uint y)
-{
-    uint result = x;
-    for(uint i = 1; i < y; ++i)
-        result *= x;
-    return result;
-}
-
-GLM_FUNC_QUALIFIER uint sqrt(uint x)
-{
-    if(x <= 1) return x;
-
-    uint NextTrial = x >> 1;
-    uint CurrentAnswer;
-
-    do
-    {
-        CurrentAnswer = NextTrial;
-        NextTrial = (NextTrial + x / NextTrial) >> 1;
-    } while(NextTrial < CurrentAnswer);
-
-    return CurrentAnswer;
-}
-
-GLM_FUNC_QUALIFIER uint mod(uint x, uint y)
-{
-	return x - y * (x / y);
-}
 
 }//namespace glm

+ 1 - 0
test/gtx/CMakeLists.txt

@@ -1,4 +1,5 @@
 glmCreateTestGTC(gtx_bit)
+glmCreateTestGTC(gtx_integer)
 glmCreateTestGTC(gtx_noise)
 glmCreateTestGTC(gtx_quaternion)
 glmCreateTestGTC(gtx_random)

+ 136 - 0
test/gtx/gtx_integer.cpp

@@ -0,0 +1,136 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// OpenGL Mathematics Copyright (c) 2005 - 2011 G-Truc Creation (www.g-truc.net)
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Created : 2010-09-16
+// Updated : 2010-09-16
+// Licence : This source is under MIT licence
+// File    : test/gtx/bit.cpp
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#include <glm/glm.hpp>
+#include <glm/gtx/number_precision.hpp>
+#include <glm/gtx/bit.hpp>
+#include <iostream>
+
+enum result
+{
+	SUCCESS,
+	FAIL,
+	ASSERT,
+	STATIC_ASSERT
+};
+
+namespace extractField
+{
+	template <typename genType, typename sizeType>
+	struct type
+	{
+		genType		Value;
+		sizeType	BitFirst;
+		sizeType	BitCount;
+		genType		Return;
+		result		Result;
+	};
+
+	typedef type<glm::uint64, glm::uint> typeU64;
+
+	typeU64 const Data64[] =
+	{
+		{0xffffffffffffffff, 8, 0, 0x0000000000000000, SUCCESS},
+		{0x0000000000000000, 0,64, 0x0000000000000000, SUCCESS},
+		{0xffffffffffffffff, 0,64, 0xffffffffffffffff, SUCCESS},
+		{0x0f0f0f0f0f0f0f0f, 0,64, 0x0f0f0f0f0f0f0f0f, SUCCESS},
+		{0x0000000000000000, 8, 0, 0x0000000000000000, SUCCESS},
+		{0x8000000000000000,63, 1, 0x0000000000000001, SUCCESS},
+		{0x7fffffffffffffff,63, 1, 0x0000000000000000, SUCCESS},
+		{0x0000000000000300, 8, 8, 0x0000000000000003, SUCCESS},
+		{0x000000000000ff00, 8, 8, 0x00000000000000ff, SUCCESS},
+		{0xfffffffffffffff0, 0, 5, 0x0000000000000010, SUCCESS},
+		{0x00000000000000ff, 1, 3, 0x0000000000000007, SUCCESS},
+		{0x00000000000000ff, 0, 3, 0x0000000000000007, SUCCESS},
+		{0x0000000000000000, 0, 2, 0x0000000000000000, SUCCESS},
+		{0xffffffffffffffff, 0, 8, 0x00000000000000ff, SUCCESS},
+		{0xffffffff00000000,32,32, 0x00000000ffffffff, SUCCESS},
+		{0xfffffffffffffff0, 0, 8, 0x0000000000000000, FAIL},
+		{0xffffffffffffffff,32,32, 0x0000000000000000, FAIL},
+		//{0xffffffffffffffff,64, 1, 0x0000000000000000, ASSERT}, // Throw an assert 
+		//{0xffffffffffffffff, 0,65, 0x0000000000000000, ASSERT}, // Throw an assert 
+		//{0xffffffffffffffff,33,32, 0x0000000000000000, ASSERT}, // Throw an assert 
+	};
+
+	int test()
+	{
+		glm::uint32 count = sizeof(Data64) / sizeof(typeU64);
+		
+		for(glm::uint32 i = 0; i < count; ++i)
+		{
+			glm::uint64 Return = glm::extractField(
+				Data64[i].Value, 
+				Data64[i].BitFirst, 
+				Data64[i].BitCount);
+			
+			bool Compare = Data64[i].Return == Return;
+			
+			if(Data64[i].Result == SUCCESS && Compare)
+				continue;
+			else if(Data64[i].Result == FAIL && !Compare)
+				continue;
+			
+			std::cout << "glm::extractfield test fail on test " << i << std::endl;
+			return 1;
+		}
+		
+		return 0;
+	}
+}//extractField
+
+namespace bitRevert
+{
+	template <typename genType>
+	struct type
+	{
+		genType		Value;
+		genType		Return;
+		result		Result;
+	};
+
+	typedef type<glm::uint64> typeU64;
+
+	typeU64 const Data64[] =
+	{
+		{0xffffffffffffffff, 0xffffffffffffffff, SUCCESS},
+		{0x0000000000000000, 0x0000000000000000, SUCCESS},
+		{0xf000000000000000, 0x000000000000000f, SUCCESS},
+	};
+
+	int test()
+	{
+		glm::uint32 count = sizeof(Data64) / sizeof(typeU64);
+		
+		for(glm::uint32 i = 0; i < count; ++i)
+		{
+			glm::uint64 Return = glm::bitRevert(
+				Data64[i].Value);
+			
+			bool Compare = Data64[i].Return == Return;
+			
+			if(Data64[i].Result == SUCCESS && Compare)
+				continue;
+			else if(Data64[i].Result == FAIL && !Compare)
+				continue;
+			
+			std::cout << "glm::extractfield test fail on test " << i << std::endl;
+			return 1;
+		}
+		
+		return 0;
+	}
+}//bitRevert
+
+int main()
+{
+	int Error = 0;
+	Error += ::extractField::test();
+	Error += ::bitRevert::test();
+	return Error;
+}