Index: code/branches/kicklib2/src/external/bullet/LinearMath/btHashMap.h
===================================================================
--- code/branches/kicklib2/src/external/bullet/LinearMath/btHashMap.h	(revision 8282)
+++ code/branches/kicklib2/src/external/bullet/LinearMath/btHashMap.h	(revision 8284)
@@ -4,5 +4,168 @@
 #include "btAlignedObjectArray.h"
 
+///very basic hashable string implementation, compatible with btHashMap
+struct btHashString
+{
+	const char* m_string;
+	unsigned int	m_hash;
+
+	SIMD_FORCE_INLINE	unsigned int getHash()const
+	{
+		return m_hash;
+	}
+
+	btHashString(const char* name)
+		:m_string(name)
+	{
+		/* magic numbers from http://www.isthe.com/chongo/tech/comp/fnv/ */
+		static const unsigned int  InitialFNV = 2166136261u;
+		static const unsigned int FNVMultiple = 16777619u;
+
+		/* Fowler / Noll / Vo (FNV) Hash */
+		unsigned int hash = InitialFNV;
+		
+		for(int i = 0; m_string[i]; i++)
+		{
+			hash = hash ^ (m_string[i]);       /* xor  the low 8 bits */
+			hash = hash * FNVMultiple;  /* multiply by the magic number */
+		}
+		m_hash = hash;
+	}
+
+	int portableStringCompare(const char* src,	const char* dst) const
+	{
+			int ret = 0 ;
+
+			while( ! (ret = *(unsigned char *)src - *(unsigned char *)dst) && *dst)
+					++src, ++dst;
+
+			if ( ret < 0 )
+					ret = -1 ;
+			else if ( ret > 0 )
+					ret = 1 ;
+
+			return( ret );
+	}
+
+	bool equals(const btHashString& other) const
+	{
+		return (m_string == other.m_string) ||
+			(0==portableStringCompare(m_string,other.m_string));
+
+	}
+
+};
+
 const int BT_HASH_NULL=0xffffffff;
+
+
+class btHashInt
+{
+	int	m_uid;
+public:
+	btHashInt(int uid)	:m_uid(uid)
+	{
+	}
+
+	int	getUid1() const
+	{
+		return m_uid;
+	}
+
+	void	setUid1(int uid)
+	{
+		m_uid = uid;
+	}
+
+	bool equals(const btHashInt& other) const
+	{
+		return getUid1() == other.getUid1();
+	}
+	//to our success
+	SIMD_FORCE_INLINE	unsigned int getHash()const
+	{
+		int key = m_uid;
+		// Thomas Wang's hash
+		key += ~(key << 15);	key ^=  (key >> 10);	key +=  (key << 3);	key ^=  (key >> 6);	key += ~(key << 11);	key ^=  (key >> 16);
+		return key;
+	}
+};
+
+
+
+class btHashPtr
+{
+
+	union
+	{
+		const void*	m_pointer;
+		int	m_hashValues[2];
+	};
+
+public:
+
+	btHashPtr(const void* ptr)
+		:m_pointer(ptr)
+	{
+	}
+
+	const void*	getPointer() const
+	{
+		return m_pointer;
+	}
+
+	bool equals(const btHashPtr& other) const
+	{
+		return getPointer() == other.getPointer();
+	}
+
+	//to our success
+	SIMD_FORCE_INLINE	unsigned int getHash()const
+	{
+		const bool VOID_IS_8 = ((sizeof(void*)==8));
+		
+		int key = VOID_IS_8? m_hashValues[0]+m_hashValues[1] : m_hashValues[0];
+	
+		// Thomas Wang's hash
+		key += ~(key << 15);	key ^=  (key >> 10);	key +=  (key << 3);	key ^=  (key >> 6);	key += ~(key << 11);	key ^=  (key >> 16);
+		return key;
+	}
+
+	
+};
+
+
+template <class Value>
+class btHashKeyPtr
+{
+        int     m_uid;
+public:
+
+        btHashKeyPtr(int uid)    :m_uid(uid)
+        {
+        }
+
+        int     getUid1() const
+        {
+                return m_uid;
+        }
+
+        bool equals(const btHashKeyPtr<Value>& other) const
+        {
+                return getUid1() == other.getUid1();
+        }
+
+        //to our success
+        SIMD_FORCE_INLINE       unsigned int getHash()const
+        {
+                int key = m_uid;
+                // Thomas Wang's hash
+                key += ~(key << 15);	key ^=  (key >> 10);	key +=  (key << 3);	key ^=  (key >> 6);	key += ~(key << 11);	key ^=  (key >> 16);
+                return key;
+        }
+
+        
+};
+
 
 template <class Value>
@@ -12,14 +175,17 @@
 public:
 
-	btHashKey(int uid)
-		:m_uid(uid)
-	{
-	}
-
-	int	getUid() const
+	btHashKey(int uid)	:m_uid(uid)
+	{
+	}
+
+	int	getUid1() const
 	{
 		return m_uid;
 	}
 
+	bool equals(const btHashKey<Value>& other) const
+	{
+		return getUid1() == other.getUid1();
+	}
 	//to our success
 	SIMD_FORCE_INLINE	unsigned int getHash()const
@@ -27,55 +193,9 @@
 		int key = m_uid;
 		// Thomas Wang's hash
-		key += ~(key << 15);
-		key ^=  (key >> 10);
-		key +=  (key << 3);
-		key ^=  (key >> 6);
-		key += ~(key << 11);
-		key ^=  (key >> 16);
+		key += ~(key << 15);	key ^=  (key >> 10);	key +=  (key << 3);	key ^=  (key >> 6);	key += ~(key << 11);	key ^=  (key >> 16);
 		return key;
 	}
-
-	btHashKey	getKey(const Value& value) const
-	{
-		return btHashKey(value.getUid());
-	}
-};
-
-
-template <class Value>
-class btHashKeyPtr
-{
-	int	m_uid;
-public:
-
-	btHashKeyPtr(int uid)
-		:m_uid(uid)
-	{
-	}
-
-	int	getUid() const
-	{
-		return m_uid;
-	}
-
-	//to our success
-	SIMD_FORCE_INLINE	unsigned int getHash()const
-	{
-		int key = m_uid;
-		// Thomas Wang's hash
-		key += ~(key << 15);
-		key ^=  (key >> 10);
-		key +=  (key << 3);
-		key ^=  (key >> 6);
-		key += ~(key << 11);
-		key ^=  (key >> 16);
-		return key;
-	}
-
-	btHashKeyPtr	getKey(const Value& value) const
-	{
-		return btHashKeyPtr(value->getUid());
-	}
-};
+};
+
 
 ///The btHashMap template class implements a generic and lightweight hashmap.
@@ -85,11 +205,12 @@
 {
 
+protected:
 	btAlignedObjectArray<int>		m_hashTable;
 	btAlignedObjectArray<int>		m_next;
+	
 	btAlignedObjectArray<Value>		m_valueArray;
-
-
-
-	void	growTables(const Key& key)
+	btAlignedObjectArray<Key>		m_keyArray;
+
+	void	growTables(const Key& /*key*/)
 	{
 		int newCapacity = m_valueArray.capacity();
@@ -116,7 +237,8 @@
 			for(i=0;i<curHashtableSize;i++)
 			{
-				const Value& value = m_valueArray[i];
-
-				int	hashValue = key.getKey(value).getHash() & (m_valueArray.capacity()-1);	// New hash value with new mask
+				//const Value& value = m_valueArray[i];
+				//const Key& key = m_keyArray[i];
+
+				int	hashValue = m_keyArray[i].getHash() & (m_valueArray.capacity()-1);	// New hash value with new mask
 				m_next[i] = m_hashTable[hashValue];
 				m_hashTable[hashValue] = i;
@@ -131,12 +253,18 @@
 	void insert(const Key& key, const Value& value) {
 		int hash = key.getHash() & (m_valueArray.capacity()-1);
-		//don't add it if it is already there
-		if (find(key))
-		{
+
+		//replace value if the key is already there
+		int index = findIndex(key);
+		if (index != BT_HASH_NULL)
+		{
+			m_valueArray[index]=value;
 			return;
 		}
+
 		int count = m_valueArray.size();
 		int oldCapacity = m_valueArray.capacity();
 		m_valueArray.push_back(value);
+		m_keyArray.push_back(key);
+
 		int newCapacity = m_valueArray.capacity();
 		if (oldCapacity < newCapacity)
@@ -192,10 +320,10 @@
 		{
 			m_valueArray.pop_back();
+			m_keyArray.pop_back();
 			return;
 		}
 
 		// Remove the last pair from the hash table.
-		const Value* lastValue = &m_valueArray[lastPairIndex];
-		int lastHash = key.getKey(*lastValue).getHash() & (m_valueArray.capacity()-1);
+		int lastHash = m_keyArray[lastPairIndex].getHash() & (m_valueArray.capacity()-1);
 
 		index = m_hashTable[lastHash];
@@ -221,4 +349,5 @@
 		// Copy the last pair into the remove pair's spot.
 		m_valueArray[pairIndex] = m_valueArray[lastPairIndex];
+		m_keyArray[pairIndex] = m_keyArray[lastPairIndex];
 
 		// Insert the last pair into the hash table
@@ -227,4 +356,5 @@
 
 		m_valueArray.pop_back();
+		m_keyArray.pop_back();
 
 	}
@@ -277,7 +407,7 @@
 	int	findIndex(const Key& key) const
 	{
-		int hash = key.getHash() & (m_valueArray.capacity()-1);
-
-		if (hash >= m_hashTable.size())
+		unsigned int hash = key.getHash() & (m_valueArray.capacity()-1);
+
+		if (hash >= (unsigned int)m_hashTable.size())
 		{
 			return BT_HASH_NULL;
@@ -285,5 +415,5 @@
 
 		int index = m_hashTable[hash];
-		while ((index != BT_HASH_NULL) && (key.getUid() == key.getKey(m_valueArray[index]).getUid()) == false)
+		while ((index != BT_HASH_NULL) && key.equals(m_keyArray[index]) == false)
 		{
 			index = m_next[index];
@@ -297,4 +427,5 @@
 		m_next.clear();
 		m_valueArray.clear();
+		m_keyArray.clear();
 	}
 
