Index: code/trunk/src/external/bullet/LinearMath/btVector3.h
===================================================================
--- code/trunk/src/external/bullet/LinearMath/btVector3.h	(revision 5781)
+++ code/trunk/src/external/bullet/LinearMath/btVector3.h	(revision 8351)
@@ -20,11 +20,21 @@
 
 #include "btScalar.h"
-#include "btScalar.h"
 #include "btMinMax.h"
+
+#ifdef BT_USE_DOUBLE_PRECISION
+#define btVector3Data btVector3DoubleData
+#define btVector3DataName "btVector3DoubleData"
+#else
+#define btVector3Data btVector3FloatData
+#define btVector3DataName "btVector3FloatData"
+#endif //BT_USE_DOUBLE_PRECISION
+
+
+
+
 /**@brief btVector3 can be used to represent 3D points and vectors.
  * It has an un-used w component to suit 16-byte alignment when btVector3 is stored in containers. This extra component can be used by derived classes (Quaternion?) or by user
  * Ideally, this class should be replaced by a platform optimized SIMD version that keeps the data in registers
  */
-
 ATTRIBUTE_ALIGNED16(class) btVector3
 {
@@ -32,16 +42,13 @@
 
 #if defined (__SPU__) && defined (__CELLOS_LV2__)
-	union {
-		vec_float4 mVec128;
 		btScalar	m_floats[4];
-	};
 public:
-	vec_float4	get128() const
-	{
-		return mVec128;
+	SIMD_FORCE_INLINE const vec_float4&	get128() const
+	{
+		return *((const vec_float4*)&m_floats[0]);
 	}
 public:
 #else //__CELLOS_LV2__ __SPU__
-#ifdef BT_USE_SSE // WIN32
+#ifdef BT_USE_SSE // _WIN32
 	union {
 		__m128 mVec128;
@@ -142,4 +149,17 @@
 	SIMD_FORCE_INLINE btScalar distance(const btVector3& v) const;
 
+	SIMD_FORCE_INLINE btVector3& safeNormalize() 
+	{
+		btVector3 absVec = this->absolute();
+		int maxIndex = absVec.maxAxis();
+		if (absVec[maxIndex]>0)
+		{
+			*this /= absVec[maxIndex];
+			return *this /= length();
+		}
+		setValue(1,0,0);
+		return *this;
+	}
+
   /**@brief Normalize this vector 
    * x^2 + y^2 + z^2 = 1 */
@@ -152,8 +172,8 @@
 	SIMD_FORCE_INLINE btVector3 normalized() const;
 
-  /**@brief Rotate this vector 
+  /**@brief Return a rotated version of this vector
    * @param wAxis The axis to rotate about 
    * @param angle The angle to rotate by */
-	SIMD_FORCE_INLINE btVector3 rotate( const btVector3& wAxis, const btScalar angle );
+	SIMD_FORCE_INLINE btVector3 rotate( const btVector3& wAxis, const btScalar angle ) const;
 
   /**@brief Return the angle between this and another vector
@@ -307,5 +327,5 @@
 			m_floats[1]=y;
 			m_floats[2]=z;
-			m_floats[3] = 0.f;
+			m_floats[3] = btScalar(0.);
 		}
 
@@ -316,4 +336,31 @@
 			v2->setValue(-y()	,x()	,0.);
 		}
+
+		void	setZero()
+		{
+			setValue(btScalar(0.),btScalar(0.),btScalar(0.));
+		}
+
+		SIMD_FORCE_INLINE bool isZero() const 
+		{
+			return m_floats[0] == btScalar(0) && m_floats[1] == btScalar(0) && m_floats[2] == btScalar(0);
+		}
+
+		SIMD_FORCE_INLINE bool fuzzyZero() const 
+		{
+			return length2() < SIMD_EPSILON;
+		}
+
+		SIMD_FORCE_INLINE	void	serialize(struct	btVector3Data& dataOut) const;
+
+		SIMD_FORCE_INLINE	void	deSerialize(const struct	btVector3Data& dataIn);
+
+		SIMD_FORCE_INLINE	void	serializeFloat(struct	btVector3FloatData& dataOut) const;
+
+		SIMD_FORCE_INLINE	void	deSerializeFloat(const struct	btVector3FloatData& dataIn);
+
+		SIMD_FORCE_INLINE	void	serializeDouble(struct	btVector3DoubleData& dataOut) const;
+
+		SIMD_FORCE_INLINE	void	deSerializeDouble(const struct	btVector3DoubleData& dataIn);
 
 };
@@ -377,5 +424,5 @@
 /**@brief Return the dot product between two vectors */
 SIMD_FORCE_INLINE btScalar 
-dot(const btVector3& v1, const btVector3& v2) 
+btDot(const btVector3& v1, const btVector3& v2) 
 { 
 	return v1.dot(v2); 
@@ -385,5 +432,5 @@
 /**@brief Return the distance squared between two vectors */
 SIMD_FORCE_INLINE btScalar
-distance2(const btVector3& v1, const btVector3& v2) 
+btDistance2(const btVector3& v1, const btVector3& v2) 
 { 
 	return v1.distance2(v2); 
@@ -393,5 +440,5 @@
 /**@brief Return the distance between two vectors */
 SIMD_FORCE_INLINE btScalar
-distance(const btVector3& v1, const btVector3& v2) 
+btDistance(const btVector3& v1, const btVector3& v2) 
 { 
 	return v1.distance(v2); 
@@ -400,5 +447,5 @@
 /**@brief Return the angle between two vectors */
 SIMD_FORCE_INLINE btScalar
-angle(const btVector3& v1, const btVector3& v2) 
+btAngle(const btVector3& v1, const btVector3& v2) 
 { 
 	return v1.angle(v2); 
@@ -407,5 +454,5 @@
 /**@brief Return the cross product of two vectors */
 SIMD_FORCE_INLINE btVector3 
-cross(const btVector3& v1, const btVector3& v2) 
+btCross(const btVector3& v1, const btVector3& v2) 
 { 
 	return v1.cross(v2); 
@@ -413,5 +460,5 @@
 
 SIMD_FORCE_INLINE btScalar
-triple(const btVector3& v1, const btVector3& v2, const btVector3& v3)
+btTriple(const btVector3& v1, const btVector3& v2, const btVector3& v3)
 {
 	return v1.triple(v2, v3);
@@ -445,5 +492,5 @@
 } 
 
-SIMD_FORCE_INLINE btVector3 btVector3::rotate( const btVector3& wAxis, const btScalar angle )
+SIMD_FORCE_INLINE btVector3 btVector3::rotate( const btVector3& wAxis, const btScalar angle ) const
 {
 	// wAxis must be a unit lenght vector
@@ -489,5 +536,5 @@
 	{
 		int maxIndex = -1;
-		btScalar maxVal = btScalar(-1e30);
+		btScalar maxVal = btScalar(-BT_LARGE_FLOAT);
 		if (m_floats[0] > maxVal)
 		{
@@ -522,5 +569,5 @@
 	{
 		int minIndex = -1;
-		btScalar minVal = btScalar(1e30);
+		btScalar minVal = btScalar(BT_LARGE_FLOAT);
 		if (m_floats[0] < minVal)
 		{
@@ -585,6 +632,4 @@
 		}
 
-
- 
 
 };
@@ -636,3 +681,86 @@
 }
 
+template <class T>
+SIMD_FORCE_INLINE void btPlaneSpace1 (const T& n, T& p, T& q)
+{
+  if (btFabs(n[2]) > SIMDSQRT12) {
+    // choose p in y-z plane
+    btScalar a = n[1]*n[1] + n[2]*n[2];
+    btScalar k = btRecipSqrt (a);
+    p[0] = 0;
+	p[1] = -n[2]*k;
+	p[2] = n[1]*k;
+    // set q = n x p
+    q[0] = a*k;
+	q[1] = -n[0]*p[2];
+	q[2] = n[0]*p[1];
+  }
+  else {
+    // choose p in x-y plane
+    btScalar a = n[0]*n[0] + n[1]*n[1];
+    btScalar k = btRecipSqrt (a);
+    p[0] = -n[1]*k;
+	p[1] = n[0]*k;
+	p[2] = 0;
+    // set q = n x p
+    q[0] = -n[2]*p[1];
+	q[1] = n[2]*p[0];
+	q[2] = a*k;
+  }
+}
+
+
+struct	btVector3FloatData
+{
+	float	m_floats[4];
+};
+
+struct	btVector3DoubleData
+{
+	double	m_floats[4];
+
+};
+
+SIMD_FORCE_INLINE	void	btVector3::serializeFloat(struct	btVector3FloatData& dataOut) const
+{
+	///could also do a memcpy, check if it is worth it
+	for (int i=0;i<4;i++)
+		dataOut.m_floats[i] = float(m_floats[i]);
+}
+
+SIMD_FORCE_INLINE void	btVector3::deSerializeFloat(const struct	btVector3FloatData& dataIn)
+{
+	for (int i=0;i<4;i++)
+		m_floats[i] = btScalar(dataIn.m_floats[i]);
+}
+
+
+SIMD_FORCE_INLINE	void	btVector3::serializeDouble(struct	btVector3DoubleData& dataOut) const
+{
+	///could also do a memcpy, check if it is worth it
+	for (int i=0;i<4;i++)
+		dataOut.m_floats[i] = double(m_floats[i]);
+}
+
+SIMD_FORCE_INLINE void	btVector3::deSerializeDouble(const struct	btVector3DoubleData& dataIn)
+{
+	for (int i=0;i<4;i++)
+		m_floats[i] = btScalar(dataIn.m_floats[i]);
+}
+
+
+SIMD_FORCE_INLINE	void	btVector3::serialize(struct	btVector3Data& dataOut) const
+{
+	///could also do a memcpy, check if it is worth it
+	for (int i=0;i<4;i++)
+		dataOut.m_floats[i] = m_floats[i];
+}
+
+SIMD_FORCE_INLINE void	btVector3::deSerialize(const struct	btVector3Data& dataIn)
+{
+	for (int i=0;i<4;i++)
+		m_floats[i] = dataIn.m_floats[i];
+}
+
+
 #endif //SIMD__VECTOR3_H
