Index: code/branches/physics/src/bullet/Bullet-C-Api.h
===================================================================
--- code/branches/physics/src/bullet/Bullet-C-Api.h	(revision 2192)
+++ code/branches/physics/src/bullet/Bullet-C-Api.h	(revision 2430)
@@ -39,28 +39,28 @@
 #endif
 
-/*	Particular physics SDK */
+/**	Particular physics SDK (C-API) */
 	PL_DECLARE_HANDLE(plPhysicsSdkHandle);
 
-/* 	Dynamics world, belonging to some physics SDK */
+/** 	Dynamics world, belonging to some physics SDK (C-API)*/
 	PL_DECLARE_HANDLE(plDynamicsWorldHandle);
 
-/* Rigid Body that can be part of a Dynamics World */	
+/** Rigid Body that can be part of a Dynamics World (C-API)*/	
 	PL_DECLARE_HANDLE(plRigidBodyHandle);
 
-/* 	Collision Shape/Geometry, property of a Rigid Body */
+/** 	Collision Shape/Geometry, property of a Rigid Body (C-API)*/
 	PL_DECLARE_HANDLE(plCollisionShapeHandle);
 
-/* Constraint for Rigid Bodies */
+/** Constraint for Rigid Bodies (C-API)*/
 	PL_DECLARE_HANDLE(plConstraintHandle);
 
-/* Triangle Mesh interface */
+/** Triangle Mesh interface (C-API)*/
 	PL_DECLARE_HANDLE(plMeshInterfaceHandle);
 
-/* Broadphase Scene/Proxy Handles */
+/** Broadphase Scene/Proxy Handles (C-API)*/
 	PL_DECLARE_HANDLE(plCollisionBroadphaseHandle);
 	PL_DECLARE_HANDLE(plBroadphaseProxyHandle);
 	PL_DECLARE_HANDLE(plCollisionWorldHandle);
 
-/*
+/**
 	Create and Delete a Physics SDK	
 */
@@ -69,5 +69,5 @@
 	extern	void		plDeletePhysicsSdk(plPhysicsSdkHandle	physicsSdk);
 
-/* Collision World, not strictly necessary, you can also just create a Dynamics World with Rigid Bodies which internally manages the Collision World with Collision Objects */
+/** Collision World, not strictly necessary, you can also just create a Dynamics World with Rigid Bodies which internally manages the Collision World with Collision Objects */
 
 	typedef void(*btBroadphaseCallback)(void* clientData, void* object1,void* object2);
Index: code/branches/physics/src/bullet/BulletCollision/BroadphaseCollision/btAxisSweep3.cpp
===================================================================
--- code/branches/physics/src/bullet/BulletCollision/BroadphaseCollision/btAxisSweep3.cpp	(revision 2192)
+++ code/branches/physics/src/bullet/BulletCollision/BroadphaseCollision/btAxisSweep3.cpp	(revision 2430)
@@ -22,6 +22,6 @@
 #include <assert.h>
 
-btAxisSweep3::btAxisSweep3(const btPoint3& worldAabbMin,const btPoint3& worldAabbMax, unsigned short int maxHandles, btOverlappingPairCache* pairCache)
-:btAxisSweep3Internal<unsigned short int>(worldAabbMin,worldAabbMax,0xfffe,0xffff,maxHandles,pairCache)
+btAxisSweep3::btAxisSweep3(const btVector3& worldAabbMin,const btVector3& worldAabbMax, unsigned short int maxHandles, btOverlappingPairCache* pairCache, bool disableRaycastAccelerator)
+:btAxisSweep3Internal<unsigned short int>(worldAabbMin,worldAabbMax,0xfffe,0xffff,maxHandles,pairCache,disableRaycastAccelerator)
 {
 	// 1 handle is reserved as sentinel
@@ -31,6 +31,6 @@
 
 
-bt32BitAxisSweep3::bt32BitAxisSweep3(const btPoint3& worldAabbMin,const btPoint3& worldAabbMax, unsigned int maxHandles , btOverlappingPairCache* pairCache )
-:btAxisSweep3Internal<unsigned int>(worldAabbMin,worldAabbMax,0xfffffffe,0x7fffffff,maxHandles,pairCache)
+bt32BitAxisSweep3::bt32BitAxisSweep3(const btVector3& worldAabbMin,const btVector3& worldAabbMax, unsigned int maxHandles , btOverlappingPairCache* pairCache , bool disableRaycastAccelerator)
+:btAxisSweep3Internal<unsigned int>(worldAabbMin,worldAabbMax,0xfffffffe,0x7fffffff,maxHandles,pairCache,disableRaycastAccelerator)
 {
 	// 1 handle is reserved as sentinel
Index: code/branches/physics/src/bullet/BulletCollision/BroadphaseCollision/btAxisSweep3.h
===================================================================
--- code/branches/physics/src/bullet/BulletCollision/BroadphaseCollision/btAxisSweep3.h	(revision 2192)
+++ code/branches/physics/src/bullet/BulletCollision/BroadphaseCollision/btAxisSweep3.h	(revision 2430)
@@ -20,5 +20,4 @@
 #define AXIS_SWEEP_3_H
 
-#include "LinearMath/btPoint3.h"
 #include "LinearMath/btVector3.h"
 #include "btOverlappingPairCache.h"
@@ -26,4 +25,5 @@
 #include "btBroadphaseProxy.h"
 #include "btOverlappingPairCallback.h"
+#include "btDbvtBroadphase.h"
 
 //#define DEBUG_BROADPHASE 1
@@ -62,6 +62,5 @@
 		BP_FP_INT_TYPE m_minEdges[3], m_maxEdges[3];		// 6 * 2 = 12
 //		BP_FP_INT_TYPE m_uniqueId;
-		BP_FP_INT_TYPE m_pad;
-		
+		btBroadphaseProxy*	m_dbvtProxy;//for faster raycast
 		//void* m_pOwner; this is now in btBroadphaseProxy.m_clientObject
 	
@@ -72,6 +71,6 @@
 	
 protected:
-	btPoint3 m_worldAabbMin;						// overall system bounds
-	btPoint3 m_worldAabbMax;						// overall system bounds
+	btVector3 m_worldAabbMin;						// overall system bounds
+	btVector3 m_worldAabbMax;						// overall system bounds
 
 	btVector3 m_quantize;						// scaling factor for quantization
@@ -95,4 +94,10 @@
 	int	m_invalidPair;
 
+	///additional dynamic aabb structure, used to accelerate ray cast queries.
+	///can be disabled using a optional argument in the constructor
+	btDbvtBroadphase*	m_raycastAccelerator;
+	btOverlappingPairCache*	m_nullPairCache;
+
+
 	// allocation/deallocation
 	BP_FP_INT_TYPE allocHandle();
@@ -109,5 +114,5 @@
 	//void RemoveOverlap(BP_FP_INT_TYPE handleA, BP_FP_INT_TYPE handleB);
 
-	void quantize(BP_FP_INT_TYPE* out, const btPoint3& point, int isMax) const;
+	
 
 	void sortMinDown(int axis, BP_FP_INT_TYPE edge, btDispatcher* dispatcher, bool updateOverlaps );
@@ -118,5 +123,5 @@
 public:
 
-	btAxisSweep3Internal(const btPoint3& worldAabbMin,const btPoint3& worldAabbMax, BP_FP_INT_TYPE handleMask, BP_FP_INT_TYPE handleSentinel, BP_FP_INT_TYPE maxHandles = 16384, btOverlappingPairCache* pairCache=0);
+	btAxisSweep3Internal(const btVector3& worldAabbMin,const btVector3& worldAabbMax, BP_FP_INT_TYPE handleMask, BP_FP_INT_TYPE handleSentinel, BP_FP_INT_TYPE maxHandles = 16384, btOverlappingPairCache* pairCache=0,bool disableRaycastAccelerator = false);
 
 	virtual	~btAxisSweep3Internal();
@@ -129,8 +134,10 @@
 	virtual void	calculateOverlappingPairs(btDispatcher* dispatcher);
 	
-	BP_FP_INT_TYPE addHandle(const btPoint3& aabbMin,const btPoint3& aabbMax, void* pOwner,short int collisionFilterGroup,short int collisionFilterMask,btDispatcher* dispatcher,void* multiSapProxy);
+	BP_FP_INT_TYPE addHandle(const btVector3& aabbMin,const btVector3& aabbMax, void* pOwner,short int collisionFilterGroup,short int collisionFilterMask,btDispatcher* dispatcher,void* multiSapProxy);
 	void removeHandle(BP_FP_INT_TYPE handle,btDispatcher* dispatcher);
-	void updateHandle(BP_FP_INT_TYPE handle, const btPoint3& aabbMin,const btPoint3& aabbMax,btDispatcher* dispatcher);
+	void updateHandle(BP_FP_INT_TYPE handle, const btVector3& aabbMin,const btVector3& aabbMax,btDispatcher* dispatcher);
 	SIMD_FORCE_INLINE Handle* getHandle(BP_FP_INT_TYPE index) const {return m_pHandles + index;}
+
+	void resetPool();
 
 	void	processAllOverlappingPairs(btOverlapCallback* callback);
@@ -140,4 +147,11 @@
 	virtual void	destroyProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher);
 	virtual void	setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax,btDispatcher* dispatcher);
+	virtual void  getAabb(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const;
+	
+	virtual void	rayTest(const btVector3& rayFrom,const btVector3& rayTo, btBroadphaseRayCallback& rayCallback, const btVector3& aabbMin=btVector3(0,0,0), const btVector3& aabbMax = btVector3(0,0,0));
+	
+	void quantize(BP_FP_INT_TYPE* out, const btVector3& point, int isMax) const;
+	///unQuantize should be conservative: aabbMin/aabbMax should be larger then 'getAabb' result
+	void unQuantize(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const;
 	
 	bool	testAabbOverlap(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1);
@@ -218,5 +232,10 @@
 		
 		Handle* handle = getHandle(handleId);
-				
+		
+		if (m_raycastAccelerator)
+		{
+			btBroadphaseProxy* rayProxy = m_raycastAccelerator->createProxy(aabbMin,aabbMax,shapeType,userPtr,collisionFilterGroup,collisionFilterMask,dispatcher,0);
+			handle->m_dbvtProxy = rayProxy;
+		}
 		return handle;
 }
@@ -228,4 +247,6 @@
 {
 	Handle* handle = static_cast<Handle*>(proxy);
+	if (m_raycastAccelerator)
+		m_raycastAccelerator->destroyProxy(handle->m_dbvtProxy,dispatcher);
 	removeHandle(static_cast<BP_FP_INT_TYPE>(handle->m_uniqueId), dispatcher);
 }
@@ -235,14 +256,71 @@
 {
 	Handle* handle = static_cast<Handle*>(proxy);
+	handle->m_aabbMin = aabbMin;
+	handle->m_aabbMax = aabbMax;
 	updateHandle(static_cast<BP_FP_INT_TYPE>(handle->m_uniqueId), aabbMin, aabbMax,dispatcher);
-
-}
-
-
-
-
-
-template <typename BP_FP_INT_TYPE>
-btAxisSweep3Internal<BP_FP_INT_TYPE>::btAxisSweep3Internal(const btPoint3& worldAabbMin,const btPoint3& worldAabbMax, BP_FP_INT_TYPE handleMask, BP_FP_INT_TYPE handleSentinel,BP_FP_INT_TYPE userMaxHandles, btOverlappingPairCache* pairCache )
+	if (m_raycastAccelerator)
+		m_raycastAccelerator->setAabb(handle->m_dbvtProxy,aabbMin,aabbMax,dispatcher);
+
+}
+
+template <typename BP_FP_INT_TYPE>
+void	btAxisSweep3Internal<BP_FP_INT_TYPE>::rayTest(const btVector3& rayFrom,const btVector3& rayTo, btBroadphaseRayCallback& rayCallback,const btVector3& aabbMin,const btVector3& aabbMax)
+{
+	if (m_raycastAccelerator)
+	{
+		m_raycastAccelerator->rayTest(rayFrom,rayTo,rayCallback,aabbMin,aabbMax);
+	} else
+	{
+		//choose axis?
+		BP_FP_INT_TYPE axis = 0;
+		//for each proxy
+		for (BP_FP_INT_TYPE i=1;i<m_numHandles*2+1;i++)
+		{
+			if (m_pEdges[axis][i].IsMax())
+			{
+				rayCallback.process(getHandle(m_pEdges[axis][i].m_handle));
+			}
+		}
+	}
+}
+
+
+
+template <typename BP_FP_INT_TYPE>
+void btAxisSweep3Internal<BP_FP_INT_TYPE>::getAabb(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const
+{
+	Handle* pHandle = static_cast<Handle*>(proxy);
+	aabbMin = pHandle->m_aabbMin;
+	aabbMax = pHandle->m_aabbMax;
+}
+
+
+template <typename BP_FP_INT_TYPE>
+void btAxisSweep3Internal<BP_FP_INT_TYPE>::unQuantize(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const
+{
+	Handle* pHandle = static_cast<Handle*>(proxy);
+
+	unsigned short vecInMin[3];
+	unsigned short vecInMax[3];
+
+	vecInMin[0] = m_pEdges[0][pHandle->m_minEdges[0]].m_pos ;
+	vecInMax[0] = m_pEdges[0][pHandle->m_maxEdges[0]].m_pos +1 ;
+	vecInMin[1] = m_pEdges[1][pHandle->m_minEdges[1]].m_pos ;
+	vecInMax[1] = m_pEdges[1][pHandle->m_maxEdges[1]].m_pos +1 ;
+	vecInMin[2] = m_pEdges[2][pHandle->m_minEdges[2]].m_pos ;
+	vecInMax[2] = m_pEdges[2][pHandle->m_maxEdges[2]].m_pos +1 ;
+	
+	aabbMin.setValue((btScalar)(vecInMin[0]) / (m_quantize.getX()),(btScalar)(vecInMin[1]) / (m_quantize.getY()),(btScalar)(vecInMin[2]) / (m_quantize.getZ()));
+	aabbMin += m_worldAabbMin;
+	
+	aabbMax.setValue((btScalar)(vecInMax[0]) / (m_quantize.getX()),(btScalar)(vecInMax[1]) / (m_quantize.getY()),(btScalar)(vecInMax[2]) / (m_quantize.getZ()));
+	aabbMax += m_worldAabbMin;
+}
+
+
+
+
+template <typename BP_FP_INT_TYPE>
+btAxisSweep3Internal<BP_FP_INT_TYPE>::btAxisSweep3Internal(const btVector3& worldAabbMin,const btVector3& worldAabbMax, BP_FP_INT_TYPE handleMask, BP_FP_INT_TYPE handleSentinel,BP_FP_INT_TYPE userMaxHandles, btOverlappingPairCache* pairCache , bool disableRaycastAccelerator)
 :m_bpHandleMask(handleMask),
 m_handleSentinel(handleSentinel),
@@ -250,5 +328,6 @@
 m_userPairCallback(0),
 m_ownsPairCache(false),
-m_invalidPair(0)
+m_invalidPair(0),
+m_raycastAccelerator(0)
 {
 	BP_FP_INT_TYPE maxHandles = static_cast<BP_FP_INT_TYPE>(userMaxHandles+1);//need to add one sentinel handle
@@ -259,4 +338,11 @@
 		m_pairCache = new(ptr) btHashedOverlappingPairCache();
 		m_ownsPairCache = true;
+	}
+
+	if (!disableRaycastAccelerator)
+	{
+		m_nullPairCache = new (btAlignedAlloc(sizeof(btNullPairCache),16)) btNullPairCache();
+		m_raycastAccelerator = new (btAlignedAlloc(sizeof(btDbvtBroadphase),16)) btDbvtBroadphase(m_nullPairCache);//m_pairCache);
+		m_raycastAccelerator->m_deferedcollide = true;//don't add/remove pairs
 	}
 
@@ -321,5 +407,12 @@
 btAxisSweep3Internal<BP_FP_INT_TYPE>::~btAxisSweep3Internal()
 {
-	
+	if (m_raycastAccelerator)
+	{
+		m_nullPairCache->~btOverlappingPairCache();
+		btAlignedFree(m_nullPairCache);
+		m_raycastAccelerator->~btDbvtBroadphase();
+		btAlignedFree (m_raycastAccelerator);
+	}
+
 	for (int i = 2; i >= 0; i--)
 	{
@@ -336,10 +429,10 @@
 
 template <typename BP_FP_INT_TYPE>
-void btAxisSweep3Internal<BP_FP_INT_TYPE>::quantize(BP_FP_INT_TYPE* out, const btPoint3& point, int isMax) const
+void btAxisSweep3Internal<BP_FP_INT_TYPE>::quantize(BP_FP_INT_TYPE* out, const btVector3& point, int isMax) const
 {
 #ifdef OLD_CLAMPING_METHOD
 	///problem with this clamping method is that the floating point during quantization might still go outside the range [(0|isMax) .. (m_handleSentinel&m_bpHandleMask]|isMax]
 	///see http://code.google.com/p/bullet/issues/detail?id=87
-	btPoint3 clampedPoint(point);
+	btVector3 clampedPoint(point);
 	clampedPoint.setMax(m_worldAabbMin);
 	clampedPoint.setMin(m_worldAabbMax);
@@ -382,5 +475,5 @@
 
 template <typename BP_FP_INT_TYPE>
-BP_FP_INT_TYPE btAxisSweep3Internal<BP_FP_INT_TYPE>::addHandle(const btPoint3& aabbMin,const btPoint3& aabbMax, void* pOwner,short int collisionFilterGroup,short int collisionFilterMask,btDispatcher* dispatcher,void* multiSapProxy)
+BP_FP_INT_TYPE btAxisSweep3Internal<BP_FP_INT_TYPE>::addHandle(const btVector3& aabbMin,const btVector3& aabbMax, void* pOwner,short int collisionFilterGroup,short int collisionFilterMask,btDispatcher* dispatcher,void* multiSapProxy)
 {
 	// quantize the bounds
@@ -445,5 +538,5 @@
 	//explicitly remove the pairs containing the proxy
 	//we could do it also in the sortMinUp (passing true)
-	//todo: compare performance
+	///@todo: compare performance
 	if (!m_pairCache->hasDeferredRemoval())
 	{
@@ -493,4 +586,19 @@
 	
 }
+
+template <typename BP_FP_INT_TYPE>
+void btAxisSweep3Internal<BP_FP_INT_TYPE>::resetPool()
+{
+	if (m_numHandles == 0)
+	{
+		m_firstFreeHandle = 1;
+		{
+			for (BP_FP_INT_TYPE i = m_firstFreeHandle; i < m_maxHandles; i++)
+				m_pHandles[i].SetNextFree(static_cast<BP_FP_INT_TYPE>(i + 1));
+			m_pHandles[m_maxHandles - 1].SetNextFree(0);
+		}
+	}
+}       
+
 
 extern int gOverlappingPairs;
@@ -621,5 +729,5 @@
 
 template <typename BP_FP_INT_TYPE>
-void btAxisSweep3Internal<BP_FP_INT_TYPE>::updateHandle(BP_FP_INT_TYPE handle, const btPoint3& aabbMin,const btPoint3& aabbMax,btDispatcher* dispatcher)
+void btAxisSweep3Internal<BP_FP_INT_TYPE>::updateHandle(BP_FP_INT_TYPE handle, const btVector3& aabbMin,const btVector3& aabbMax,btDispatcher* dispatcher)
 {
 //	assert(bounds.IsFinite());
@@ -900,5 +1008,5 @@
 public:
 
-	btAxisSweep3(const btPoint3& worldAabbMin,const btPoint3& worldAabbMax, unsigned short int maxHandles = 16384, btOverlappingPairCache* pairCache = 0);
+	btAxisSweep3(const btVector3& worldAabbMin,const btVector3& worldAabbMax, unsigned short int maxHandles = 16384, btOverlappingPairCache* pairCache = 0, bool disableRaycastAccelerator = false);
 
 };
@@ -911,5 +1019,5 @@
 public:
 
-	bt32BitAxisSweep3(const btPoint3& worldAabbMin,const btPoint3& worldAabbMax, unsigned int maxHandles = 1500000, btOverlappingPairCache* pairCache = 0);
+	bt32BitAxisSweep3(const btVector3& worldAabbMin,const btVector3& worldAabbMax, unsigned int maxHandles = 1500000, btOverlappingPairCache* pairCache = 0, bool disableRaycastAccelerator = false);
 
 };
Index: code/branches/physics/src/bullet/BulletCollision/BroadphaseCollision/btBroadphaseInterface.h
===================================================================
--- code/branches/physics/src/bullet/BulletCollision/BroadphaseCollision/btBroadphaseInterface.h	(revision 2192)
+++ code/branches/physics/src/bullet/BulletCollision/BroadphaseCollision/btBroadphaseInterface.h	(revision 2430)
@@ -22,5 +22,19 @@
 class btDispatcher;
 #include "btBroadphaseProxy.h"
+
 class btOverlappingPairCache;
+
+
+
+struct	btBroadphaseRayCallback
+{
+	///added some cached data to accelerate ray-AABB tests
+	btVector3		m_rayDirectionInverse;
+	unsigned int	m_signs[3];
+	btScalar		m_lambda_max;
+
+	virtual ~btBroadphaseRayCallback() {}
+	virtual bool	process(const btBroadphaseProxy* proxy) = 0;
+};
 
 #include "LinearMath/btVector3.h"
@@ -37,5 +51,8 @@
 	virtual void	destroyProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher)=0;
 	virtual void	setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax, btDispatcher* dispatcher)=0;
-	
+	virtual void	getAabb(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const =0;
+
+	virtual void	rayTest(const btVector3& rayFrom,const btVector3& rayTo, btBroadphaseRayCallback& rayCallback, const btVector3& aabbMin=btVector3(0,0,0), const btVector3& aabbMax = btVector3(0,0,0)) = 0;
+
 	///calculateOverlappingPairs is optional: incremental algorithms (sweep and prune) might do it during the set aabb
 	virtual void	calculateOverlappingPairs(btDispatcher* dispatcher)=0;
Index: code/branches/physics/src/bullet/BulletCollision/BroadphaseCollision/btBroadphaseProxy.h
===================================================================
--- code/branches/physics/src/bullet/BulletCollision/BroadphaseCollision/btBroadphaseProxy.h	(revision 2192)
+++ code/branches/physics/src/bullet/BulletCollision/BroadphaseCollision/btBroadphaseProxy.h	(revision 2430)
@@ -18,4 +18,5 @@
 
 #include "LinearMath/btScalar.h" //for SIMD_FORCE_INLINE
+#include "LinearMath/btVector3.h"
 #include "LinearMath/btAlignedAllocator.h"
 
@@ -24,4 +25,5 @@
 /// IMPORTANT NOTE:The types are ordered polyhedral, implicit convex and concave
 /// to facilitate type checking
+/// CUSTOM_POLYHEDRAL_SHAPE_TYPE,CUSTOM_CONVEX_SHAPE_TYPE and CUSTOM_CONCAVE_SHAPE_TYPE can be used to extend Bullet without modifying source code
 enum BroadphaseNativeTypes
 {
@@ -33,4 +35,5 @@
 	CONVEX_HULL_SHAPE_PROXYTYPE,
 	CONVEX_POINT_CLOUD_SHAPE_PROXYTYPE,
+	CUSTOM_POLYHEDRAL_SHAPE_TYPE,
 //implicit convex shapes
 IMPLICIT_CONVEX_SHAPES_START_HERE,
@@ -44,4 +47,5 @@
 	MINKOWSKI_SUM_SHAPE_PROXYTYPE,
 	MINKOWSKI_DIFFERENCE_SHAPE_PROXYTYPE,
+	CUSTOM_CONVEX_SHAPE_TYPE,
 //concave shapes
 CONCAVE_SHAPES_START_HERE,
@@ -60,4 +64,5 @@
 	EMPTY_SHAPE_PROXYTYPE,
 	STATIC_PLANE_PROXYTYPE,
+	CUSTOM_CONCAVE_SHAPE_TYPE,
 CONCAVE_SHAPES_END_HERE,
 
@@ -88,4 +93,5 @@
 	        DebrisFilter = 8,
 			SensorTrigger = 16,
+			CharacterFilter = 32,
 	        AllFilter = -1 //all bits sets: DefaultFilter | StaticFilter | KinematicFilter | DebrisFilter | SensorTrigger
 	};
@@ -93,12 +99,11 @@
 	//Usually the client btCollisionObject or Rigidbody class
 	void*	m_clientObject;
-
 	short int m_collisionFilterGroup;
 	short int m_collisionFilterMask;
-
 	void*	m_multiSapParentProxy;		
-
-
 	int			m_uniqueId;//m_uniqueId is introduced for paircache. could get rid of this, by calculating the address offset etc.
+
+	btVector3	m_aabbMin;
+	btVector3	m_aabbMax;
 
 	SIMD_FORCE_INLINE int getUid() const
@@ -112,8 +117,10 @@
 	}
 
-	btBroadphaseProxy(void* userPtr,short int collisionFilterGroup, short int collisionFilterMask,void* multiSapParentProxy=0)
+	btBroadphaseProxy(const btVector3& aabbMin,const btVector3& aabbMax,void* userPtr,short int collisionFilterGroup, short int collisionFilterMask,void* multiSapParentProxy=0)
 		:m_clientObject(userPtr),
 		m_collisionFilterGroup(collisionFilterGroup),
-		m_collisionFilterMask(collisionFilterMask)
+		m_collisionFilterMask(collisionFilterMask),
+		m_aabbMin(aabbMin),
+		m_aabbMax(aabbMax)
 	{
 		m_multiSapParentProxy = multiSapParentProxy;
@@ -164,5 +171,5 @@
 		m_pProxy1(0),
 		m_algorithm(0),
-		m_userInfo(0)
+		m_internalInfo1(0)
 	{
 	}
@@ -174,5 +181,5 @@
 				m_pProxy1(other.m_pProxy1),
 				m_algorithm(other.m_algorithm),
-				m_userInfo(other.m_userInfo)
+				m_internalInfo1(other.m_internalInfo1)
 	{
 	}
@@ -193,5 +200,5 @@
 
 		m_algorithm = 0;
-		m_userInfo = 0;
+		m_internalInfo1 = 0;
 
 	}
@@ -201,5 +208,5 @@
 	
 	mutable btCollisionAlgorithm* m_algorithm;
-	mutable void* m_userInfo;
+	union { void* m_internalInfo1; int m_internalTmpValue;};//don't use this data, it will be removed in future version.
 
 };
Index: code/branches/physics/src/bullet/BulletCollision/BroadphaseCollision/btDbvt.cpp
===================================================================
--- code/branches/physics/src/bullet/BulletCollision/BroadphaseCollision/btDbvt.cpp	(revision 2192)
+++ code/branches/physics/src/bullet/BulletCollision/BroadphaseCollision/btDbvt.cpp	(revision 2430)
@@ -24,6 +24,6 @@
 struct btDbvtNodeEnumerator : btDbvt::ICollide
 {
-tConstNodeArray	nodes;
-void Process(const btDbvtNode* n) { nodes.push_back(n); }
+	tConstNodeArray	nodes;
+	void Process(const btDbvtNode* n) { nodes.push_back(n); }
 };
 
@@ -31,19 +31,19 @@
 static DBVT_INLINE int			indexof(const btDbvtNode* node)
 {
-return(node->parent->childs[1]==node);
+	return(node->parent->childs[1]==node);
 }
 
 //
 static DBVT_INLINE btDbvtVolume	merge(	const btDbvtVolume& a,
-										const btDbvtVolume& b)
-{
-#if DBVT_MERGE_IMPL==DBVT_IMPL_SSE
-DBVT_ALIGN char locals[sizeof(btDbvtAabbMm)];
-btDbvtVolume&	res=*(btDbvtVolume*)locals;
+									  const btDbvtVolume& b)
+{
+#if (DBVT_MERGE_IMPL==DBVT_IMPL_SSE)
+	ATTRIBUTE_ALIGNED16(char locals[sizeof(btDbvtAabbMm)]);
+	btDbvtVolume&	res=*(btDbvtVolume*)locals;
 #else
-btDbvtVolume	res;
+		btDbvtVolume	res;
 #endif
-Merge(a,b,res);
-return(res);
+	Merge(a,b,res);
+	return(res);
 }
 
@@ -51,6 +51,6 @@
 static DBVT_INLINE btScalar		size(const btDbvtVolume& a)
 {
-const btVector3	edges=a.Lengths();
-return(	edges.x()*edges.y()*edges.z()+
+	const btVector3	edges=a.Lengths();
+	return(	edges.x()*edges.y()*edges.z()+
 		edges.x()+edges.y()+edges.z());
 }
@@ -59,8 +59,8 @@
 static void						getmaxdepth(const btDbvtNode* node,int depth,int& maxdepth)
 {
-if(node->isinternal())
-	{
-	getmaxdepth(node->childs[0],depth+1,maxdepth);
-	getmaxdepth(node->childs[0],depth+1,maxdepth);
+	if(node->isinternal())
+	{
+		getmaxdepth(node->childs[0],depth+1,maxdepth);
+		getmaxdepth(node->childs[0],depth+1,maxdepth);
 	} else maxdepth=btMax(maxdepth,depth);
 }
@@ -68,142 +68,142 @@
 //
 static DBVT_INLINE void			deletenode(	btDbvt* pdbvt,
-											btDbvtNode* node)
-{
-btAlignedFree(pdbvt->m_free);
-pdbvt->m_free=node;
-}
-	
+										   btDbvtNode* node)
+{
+	btAlignedFree(pdbvt->m_free);
+	pdbvt->m_free=node;
+}
+
 //
 static void						recursedeletenode(	btDbvt* pdbvt,
-													btDbvtNode* node)
-{
-if(!node->isleaf())
-	{
-	recursedeletenode(pdbvt,node->childs[0]);
-	recursedeletenode(pdbvt,node->childs[1]);
-	}
-if(node==pdbvt->m_root) pdbvt->m_root=0;
-deletenode(pdbvt,node);
+												  btDbvtNode* node)
+{
+	if(!node->isleaf())
+	{
+		recursedeletenode(pdbvt,node->childs[0]);
+		recursedeletenode(pdbvt,node->childs[1]);
+	}
+	if(node==pdbvt->m_root) pdbvt->m_root=0;
+	deletenode(pdbvt,node);
 }
 
 //
 static DBVT_INLINE btDbvtNode*	createnode(	btDbvt* pdbvt,
-											btDbvtNode* parent,
-											void* data)
-{
-btDbvtNode*	node;
-if(pdbvt->m_free)
+										   btDbvtNode* parent,
+										   void* data)
+{
+	btDbvtNode*	node;
+	if(pdbvt->m_free)
 	{ node=pdbvt->m_free;pdbvt->m_free=0; }
 	else
 	{ node=new(btAlignedAlloc(sizeof(btDbvtNode),16)) btDbvtNode(); }
-node->parent	=	parent;
-node->data		=	data;
-node->childs[1]	=	0;
-return(node);
+	node->parent	=	parent;
+	node->data		=	data;
+	node->childs[1]	=	0;
+	return(node);
 }
 
 //
 static DBVT_INLINE btDbvtNode*	createnode(	btDbvt* pdbvt,
-											btDbvtNode* parent,
-											const btDbvtVolume& volume,
-											void* data)
-{
-btDbvtNode*	node=createnode(pdbvt,parent,data);
-node->volume=volume;
-return(node);
+										   btDbvtNode* parent,
+										   const btDbvtVolume& volume,
+										   void* data)
+{
+	btDbvtNode*	node=createnode(pdbvt,parent,data);
+	node->volume=volume;
+	return(node);
 }
 
 //
 static DBVT_INLINE btDbvtNode*	createnode(	btDbvt* pdbvt,
-											btDbvtNode* parent,
-											const btDbvtVolume& volume0,
-											const btDbvtVolume& volume1,
-											void* data)
-{
-btDbvtNode*	node=createnode(pdbvt,parent,data);
-Merge(volume0,volume1,node->volume);
-return(node);
+										   btDbvtNode* parent,
+										   const btDbvtVolume& volume0,
+										   const btDbvtVolume& volume1,
+										   void* data)
+{
+	btDbvtNode*	node=createnode(pdbvt,parent,data);
+	Merge(volume0,volume1,node->volume);
+	return(node);
 }
 
 //
 static void						insertleaf(	btDbvt* pdbvt,
-											btDbvtNode* root,
-											btDbvtNode* leaf)
-{
-if(!pdbvt->m_root)
-	{
-	pdbvt->m_root	=	leaf;
-	leaf->parent	=	0;
+										   btDbvtNode* root,
+										   btDbvtNode* leaf)
+{
+	if(!pdbvt->m_root)
+	{
+		pdbvt->m_root	=	leaf;
+		leaf->parent	=	0;
 	}
 	else
 	{
-	if(!root->isleaf())
-		{
-		do	{
-			root=root->childs[Select(	leaf->volume,
-										root->childs[0]->volume,
-										root->childs[1]->volume)];
+		if(!root->isleaf())
+		{
+			do	{
+				root=root->childs[Select(	leaf->volume,
+					root->childs[0]->volume,
+					root->childs[1]->volume)];
 			} while(!root->isleaf());
 		}
-	btDbvtNode*	prev=root->parent;
-	btDbvtNode*	node=createnode(pdbvt,prev,leaf->volume,root->volume,0);
-	if(prev)
-		{
-		prev->childs[indexof(root)]	=	node;
-		node->childs[0]				=	root;root->parent=node;
-		node->childs[1]				=	leaf;leaf->parent=node;
-		do	{
-			if(!prev->volume.Contain(node->volume))
+		btDbvtNode*	prev=root->parent;
+		btDbvtNode*	node=createnode(pdbvt,prev,leaf->volume,root->volume,0);
+		if(prev)
+		{
+			prev->childs[indexof(root)]	=	node;
+			node->childs[0]				=	root;root->parent=node;
+			node->childs[1]				=	leaf;leaf->parent=node;
+			do	{
+				if(!prev->volume.Contain(node->volume))
+					Merge(prev->childs[0]->volume,prev->childs[1]->volume,prev->volume);
+				else
+					break;
+				node=prev;
+			} while(0!=(prev=node->parent));
+		}
+		else
+		{
+			node->childs[0]	=	root;root->parent=node;
+			node->childs[1]	=	leaf;leaf->parent=node;
+			pdbvt->m_root	=	node;
+		}
+	}
+}
+
+//
+static btDbvtNode*				removeleaf(	btDbvt* pdbvt,
+										   btDbvtNode* leaf)
+{
+	if(leaf==pdbvt->m_root)
+	{
+		pdbvt->m_root=0;
+		return(0);
+	}
+	else
+	{
+		btDbvtNode*	parent=leaf->parent;
+		btDbvtNode*	prev=parent->parent;
+		btDbvtNode*	sibling=parent->childs[1-indexof(leaf)];			
+		if(prev)
+		{
+			prev->childs[indexof(parent)]=sibling;
+			sibling->parent=prev;
+			deletenode(pdbvt,parent);
+			while(prev)
+			{
+				const btDbvtVolume	pb=prev->volume;
 				Merge(prev->childs[0]->volume,prev->childs[1]->volume,prev->volume);
-				else
-				break;
-			node=prev;
-			} while(0!=(prev=node->parent));
-		}
-		else
-		{
-		node->childs[0]	=	root;root->parent=node;
-		node->childs[1]	=	leaf;leaf->parent=node;
-		pdbvt->m_root	=	node;
-		}
-	}
-}
-	
-//
-static btDbvtNode*				removeleaf(	btDbvt* pdbvt,
-											btDbvtNode* leaf)
-{
-if(leaf==pdbvt->m_root)
-	{
-	pdbvt->m_root=0;
-	return(0);
-	}
-	else
-	{
-	btDbvtNode*	parent=leaf->parent;
-	btDbvtNode*	prev=parent->parent;
-	btDbvtNode*	sibling=parent->childs[1-indexof(leaf)];			
-	if(prev)
-		{
-		prev->childs[indexof(parent)]=sibling;
-		sibling->parent=prev;
-		deletenode(pdbvt,parent);
-		while(prev)
-			{
-			const btDbvtVolume	pb=prev->volume;
-			Merge(prev->childs[0]->volume,prev->childs[1]->volume,prev->volume);
-			if(NotEqual(pb,prev->volume))
+				if(NotEqual(pb,prev->volume))
 				{
-				prev=prev->parent;
+					prev=prev->parent;
 				} else break;
 			}
-		return(prev?prev:pdbvt->m_root);
+			return(prev?prev:pdbvt->m_root);
 		}
 		else
 		{								
-		pdbvt->m_root=sibling;
-		sibling->parent=0;
-		deletenode(pdbvt,parent);
-		return(pdbvt->m_root);
+			pdbvt->m_root=sibling;
+			sibling->parent=0;
+			deletenode(pdbvt,parent);
+			return(pdbvt->m_root);
 		}			
 	}
@@ -216,13 +216,13 @@
 											int depth=-1)
 {
-if(root->isinternal()&&depth)
-	{
-	fetchleaves(pdbvt,root->childs[0],leaves,depth-1);
-	fetchleaves(pdbvt,root->childs[1],leaves,depth-1);
-	deletenode(pdbvt,root);
+	if(root->isinternal()&&depth)
+	{
+		fetchleaves(pdbvt,root->childs[0],leaves,depth-1);
+		fetchleaves(pdbvt,root->childs[1],leaves,depth-1);
+		deletenode(pdbvt,root);
 	}
 	else
 	{
-	leaves.push_back(root);
+		leaves.push_back(root);
 	}
 }
@@ -230,17 +230,17 @@
 //
 static void						split(	const tNodeArray& leaves,
-										tNodeArray& left,
-										tNodeArray& right,
-										const btVector3& org,
-										const btVector3& axis)
-{
-left.resize(0);
-right.resize(0);
-for(int i=0,ni=leaves.size();i<ni;++i)
-	{
-	if(dot(axis,leaves[i]->volume.Center()-org)<0)
-		left.push_back(leaves[i]);
+									  tNodeArray& left,
+									  tNodeArray& right,
+									  const btVector3& org,
+									  const btVector3& axis)
+{
+	left.resize(0);
+	right.resize(0);
+	for(int i=0,ni=leaves.size();i<ni;++i)
+	{
+		if(dot(axis,leaves[i]->volume.Center()-org)<0)
+			left.push_back(leaves[i]);
 		else
-		right.push_back(leaves[i]);
+			right.push_back(leaves[i]);
 	}
 }
@@ -250,47 +250,47 @@
 {
 #if DBVT_MERGE_IMPL==DBVT_IMPL_SSE
-DBVT_ALIGN char	locals[sizeof(btDbvtVolume)];
-btDbvtVolume&	volume=*(btDbvtVolume*)locals;
-volume=leaves[0]->volume;
+	ATTRIBUTE_ALIGNED16(char	locals[sizeof(btDbvtVolume)]);
+	btDbvtVolume&	volume=*(btDbvtVolume*)locals;
+	volume=leaves[0]->volume;
 #else
-btDbvtVolume volume=leaves[0]->volume;
+	btDbvtVolume volume=leaves[0]->volume;
 #endif
-for(int i=1,ni=leaves.size();i<ni;++i)
-	{
-	Merge(volume,leaves[i]->volume,volume);
-	}
-return(volume);
+	for(int i=1,ni=leaves.size();i<ni;++i)
+	{
+		Merge(volume,leaves[i]->volume,volume);
+	}
+	return(volume);
 }
 
 //
 static void						bottomup(	btDbvt* pdbvt,
-											tNodeArray& leaves)
-{
-while(leaves.size()>1)
-	{
-	btScalar	minsize=SIMD_INFINITY;
-	int			minidx[2]={-1,-1};
-	for(int i=0;i<leaves.size();++i)
-		{
-		for(int j=i+1;j<leaves.size();++j)
-			{
-			const btScalar	sz=size(merge(leaves[i]->volume,leaves[j]->volume));
-			if(sz<minsize)
+										 tNodeArray& leaves)
+{
+	while(leaves.size()>1)
+	{
+		btScalar	minsize=SIMD_INFINITY;
+		int			minidx[2]={-1,-1};
+		for(int i=0;i<leaves.size();++i)
+		{
+			for(int j=i+1;j<leaves.size();++j)
+			{
+				const btScalar	sz=size(merge(leaves[i]->volume,leaves[j]->volume));
+				if(sz<minsize)
 				{
-				minsize		=	sz;
-				minidx[0]	=	i;
-				minidx[1]	=	j;
+					minsize		=	sz;
+					minidx[0]	=	i;
+					minidx[1]	=	j;
 				}
 			}
 		}
-	btDbvtNode*	n[]	=	{leaves[minidx[0]],leaves[minidx[1]]};
-	btDbvtNode*	p	=	createnode(pdbvt,0,n[0]->volume,n[1]->volume,0);
-	p->childs[0]		=	n[0];
-	p->childs[1]		=	n[1];
-	n[0]->parent		=	p;
-	n[1]->parent		=	p;
-	leaves[minidx[0]]	=	p;
-	leaves.swap(minidx[1],leaves.size()-1);
-	leaves.pop_back();
+		btDbvtNode*	n[]	=	{leaves[minidx[0]],leaves[minidx[1]]};
+		btDbvtNode*	p	=	createnode(pdbvt,0,n[0]->volume,n[1]->volume,0);
+		p->childs[0]		=	n[0];
+		p->childs[1]		=	n[1];
+		n[0]->parent		=	p;
+		n[1]->parent		=	p;
+		leaves[minidx[0]]	=	p;
+		leaves.swap(minidx[1],leaves.size()-1);
+		leaves.pop_back();
 	}
 }
@@ -301,67 +301,67 @@
 									int bu_treshold)
 {
-static const btVector3	axis[]={btVector3(1,0,0),
-								btVector3(0,1,0),
-								btVector3(0,0,1)};
-if(leaves.size()>1)
-	{
-	if(leaves.size()>bu_treshold)
-		{
-		const btDbvtVolume	vol=bounds(leaves);
-		const btVector3			org=vol.Center();
-		tNodeArray				sets[2];
-		int						bestaxis=-1;
-		int						bestmidp=leaves.size();
-		int						splitcount[3][2]={{0,0},{0,0},{0,0}};
-		int i;
-		for( i=0;i<leaves.size();++i)
-			{
-			const btVector3	x=leaves[i]->volume.Center()-org;
-			for(int j=0;j<3;++j)
+	static const btVector3	axis[]={btVector3(1,0,0),
+		btVector3(0,1,0),
+		btVector3(0,0,1)};
+	if(leaves.size()>1)
+	{
+		if(leaves.size()>bu_treshold)
+		{
+			const btDbvtVolume	vol=bounds(leaves);
+			const btVector3			org=vol.Center();
+			tNodeArray				sets[2];
+			int						bestaxis=-1;
+			int						bestmidp=leaves.size();
+			int						splitcount[3][2]={{0,0},{0,0},{0,0}};
+			int i;
+			for( i=0;i<leaves.size();++i)
+			{
+				const btVector3	x=leaves[i]->volume.Center()-org;
+				for(int j=0;j<3;++j)
 				{
-				++splitcount[j][dot(x,axis[j])>0?1:0];
+					++splitcount[j][dot(x,axis[j])>0?1:0];
 				}
 			}
-		for( i=0;i<3;++i)
-			{
-			if((splitcount[i][0]>0)&&(splitcount[i][1]>0))
+			for( i=0;i<3;++i)
+			{
+				if((splitcount[i][0]>0)&&(splitcount[i][1]>0))
 				{
-				const int	midp=(int)btFabs(btScalar(splitcount[i][0]-splitcount[i][1]));
-				if(midp<bestmidp)
+					const int	midp=(int)btFabs(btScalar(splitcount[i][0]-splitcount[i][1]));
+					if(midp<bestmidp)
 					{
-					bestaxis=i;
-					bestmidp=midp;
+						bestaxis=i;
+						bestmidp=midp;
 					}
 				}
 			}
-		if(bestaxis>=0)
-			{
-			sets[0].reserve(splitcount[bestaxis][0]);
-			sets[1].reserve(splitcount[bestaxis][1]);
-			split(leaves,sets[0],sets[1],org,axis[bestaxis]);
+			if(bestaxis>=0)
+			{
+				sets[0].reserve(splitcount[bestaxis][0]);
+				sets[1].reserve(splitcount[bestaxis][1]);
+				split(leaves,sets[0],sets[1],org,axis[bestaxis]);
 			}
 			else
 			{
-			sets[0].reserve(leaves.size()/2+1);
-			sets[1].reserve(leaves.size()/2);
-			for(int i=0,ni=leaves.size();i<ni;++i)
+				sets[0].reserve(leaves.size()/2+1);
+				sets[1].reserve(leaves.size()/2);
+				for(int i=0,ni=leaves.size();i<ni;++i)
 				{
-				sets[i&1].push_back(leaves[i]);
+					sets[i&1].push_back(leaves[i]);
 				}
 			}
-		btDbvtNode*	node=createnode(pdbvt,0,vol,0);
-		node->childs[0]=topdown(pdbvt,sets[0],bu_treshold);
-		node->childs[1]=topdown(pdbvt,sets[1],bu_treshold);
-		node->childs[0]->parent=node;
-		node->childs[1]->parent=node;
-		return(node);
+			btDbvtNode*	node=createnode(pdbvt,0,vol,0);
+			node->childs[0]=topdown(pdbvt,sets[0],bu_treshold);
+			node->childs[1]=topdown(pdbvt,sets[1],bu_treshold);
+			node->childs[0]->parent=node;
+			node->childs[1]->parent=node;
+			return(node);
 		}
 		else
 		{
-		bottomup(pdbvt,leaves);
-		return(leaves[0]);
-		}
-	}
-return(leaves[0]);
+			bottomup(pdbvt,leaves);
+			return(leaves[0]);
+		}
+	}
+	return(leaves[0]);
 }
 
@@ -369,27 +369,27 @@
 static DBVT_INLINE btDbvtNode*	sort(btDbvtNode* n,btDbvtNode*& r)
 {
-btDbvtNode*	p=n->parent;
-btAssert(n->isinternal());
-if(p>n)
-	{
-	const int		i=indexof(n);
-	const int		j=1-i;
-	btDbvtNode*	s=p->childs[j];
-	btDbvtNode*	q=p->parent;
-	btAssert(n==p->childs[i]);
-	if(q) q->childs[indexof(p)]=n; else r=n;
-	s->parent=n;
-	p->parent=n;
-	n->parent=q;
-	p->childs[0]=n->childs[0];
-	p->childs[1]=n->childs[1];
-	n->childs[0]->parent=p;
-	n->childs[1]->parent=p;
-	n->childs[i]=p;
-	n->childs[j]=s;
-	btSwap(p->volume,n->volume);
-	return(p);
-	}
-return(n);
+	btDbvtNode*	p=n->parent;
+	btAssert(n->isinternal());
+	if(p>n)
+	{
+		const int		i=indexof(n);
+		const int		j=1-i;
+		btDbvtNode*	s=p->childs[j];
+		btDbvtNode*	q=p->parent;
+		btAssert(n==p->childs[i]);
+		if(q) q->childs[indexof(p)]=n; else r=n;
+		s->parent=n;
+		p->parent=n;
+		n->parent=q;
+		p->childs[0]=n->childs[0];
+		p->childs[1]=n->childs[1];
+		n->childs[0]->parent=p;
+		n->childs[1]->parent=p;
+		n->childs[i]=p;
+		n->childs[j]=s;
+		btSwap(p->volume,n->volume);
+		return(p);
+	}
+	return(n);
 }
 
@@ -397,6 +397,6 @@
 static DBVT_INLINE btDbvtNode*	walkup(btDbvtNode* n,int count)
 {
-while(n&&(count--)) n=n->parent;
-return(n);
+	while(n&&(count--)) n=n->parent;
+	return(n);
 }
 
@@ -406,17 +406,17 @@
 
 //
-				btDbvt::btDbvt()
-{
-m_root		=	0;
-m_free		=	0;
-m_lkhd		=	-1;
-m_leaves	=	0;
-m_opath		=	0;
-}
-
-//
-				btDbvt::~btDbvt()
-{
-clear();
+btDbvt::btDbvt()
+{
+	m_root		=	0;
+	m_free		=	0;
+	m_lkhd		=	-1;
+	m_leaves	=	0;
+	m_opath		=	0;
+}
+
+//
+btDbvt::~btDbvt()
+{
+	clear();
 }
 
@@ -424,7 +424,7 @@
 void			btDbvt::clear()
 {
-if(m_root)	recursedeletenode(this,m_root);
-btAlignedFree(m_free);
-m_free=0;
+	if(m_root)	recursedeletenode(this,m_root);
+	btAlignedFree(m_free);
+	m_free=0;
 }
 
@@ -432,11 +432,11 @@
 void			btDbvt::optimizeBottomUp()
 {
-if(m_root)
-	{
-	tNodeArray leaves;
-	leaves.reserve(m_leaves);
-	fetchleaves(this,m_root,leaves);
-	bottomup(this,leaves);
-	m_root=leaves[0];
+	if(m_root)
+	{
+		tNodeArray leaves;
+		leaves.reserve(m_leaves);
+		fetchleaves(this,m_root,leaves);
+		bottomup(this,leaves);
+		m_root=leaves[0];
 	}
 }
@@ -445,10 +445,10 @@
 void			btDbvt::optimizeTopDown(int bu_treshold)
 {
-if(m_root)
-	{
-	tNodeArray	leaves;
-	leaves.reserve(m_leaves);
-	fetchleaves(this,m_root,leaves);
-	m_root=topdown(this,leaves,bu_treshold);
+	if(m_root)
+	{
+		tNodeArray	leaves;
+		leaves.reserve(m_leaves);
+		fetchleaves(this,m_root,leaves);
+		m_root=topdown(this,leaves,bu_treshold);
 	}
 }
@@ -457,17 +457,17 @@
 void			btDbvt::optimizeIncremental(int passes)
 {
-if(passes<0) passes=m_leaves;
-if(m_root&&(passes>0))
-	{
-	do	{
-		btDbvtNode*		node=m_root;
-		unsigned	bit=0;
-		while(node->isinternal())
-			{
-			node=sort(node,m_root)->childs[(m_opath>>bit)&1];
-			bit=(bit+1)&(sizeof(unsigned)*8-1);
-			}
-		update(node);
-		++m_opath;
+	if(passes<0) passes=m_leaves;
+	if(m_root&&(passes>0))
+	{
+		do	{
+			btDbvtNode*		node=m_root;
+			unsigned	bit=0;
+			while(node->isinternal())
+			{
+				node=sort(node,m_root)->childs[(m_opath>>bit)&1];
+				bit=(bit+1)&(sizeof(unsigned)*8-1);
+			}
+			update(node);
+			++m_opath;
 		} while(--passes);
 	}
@@ -477,8 +477,8 @@
 btDbvtNode*	btDbvt::insert(const btDbvtVolume& volume,void* data)
 {
-btDbvtNode*	leaf=createnode(this,0,volume,data);
-insertleaf(this,m_root,leaf);
-++m_leaves;
-return(leaf);
+	btDbvtNode*	leaf=createnode(this,0,volume,data);
+	insertleaf(this,m_root,leaf);
+	++m_leaves;
+	return(leaf);
 }
 
@@ -486,62 +486,62 @@
 void			btDbvt::update(btDbvtNode* leaf,int lookahead)
 {
-btDbvtNode*	root=removeleaf(this,leaf);
-if(root)
-	{
-	if(lookahead>=0)
-		{
-		for(int i=0;(i<lookahead)&&root->parent;++i)
-			{
-			root=root->parent;
+	btDbvtNode*	root=removeleaf(this,leaf);
+	if(root)
+	{
+		if(lookahead>=0)
+		{
+			for(int i=0;(i<lookahead)&&root->parent;++i)
+			{
+				root=root->parent;
 			}
 		} else root=m_root;
 	}
-insertleaf(this,root,leaf);
-}
-
-//
-void			btDbvt::update(btDbvtNode* leaf,const btDbvtVolume& volume)
-{
-btDbvtNode*	root=removeleaf(this,leaf);
-if(root)
-	{
-	if(m_lkhd>=0)
-		{
-		for(int i=0;(i<m_lkhd)&&root->parent;++i)
-			{
-			root=root->parent;
+	insertleaf(this,root,leaf);
+}
+
+//
+void			btDbvt::update(btDbvtNode* leaf,btDbvtVolume& volume)
+{
+	btDbvtNode*	root=removeleaf(this,leaf);
+	if(root)
+	{
+		if(m_lkhd>=0)
+		{
+			for(int i=0;(i<m_lkhd)&&root->parent;++i)
+			{
+				root=root->parent;
 			}
 		} else root=m_root;
 	}
-leaf->volume=volume;
-insertleaf(this,root,leaf);
-}
-
-//
-bool			btDbvt::update(btDbvtNode* leaf,btDbvtVolume volume,const btVector3& velocity,btScalar margin)
-{
-if(leaf->volume.Contain(volume)) return(false);
-volume.Expand(btVector3(margin,margin,margin));
-volume.SignedExpand(velocity);
-update(leaf,volume);
-return(true);
-}
-
-//
-bool			btDbvt::update(btDbvtNode* leaf,btDbvtVolume volume,const btVector3& velocity)
-{
-if(leaf->volume.Contain(volume)) return(false);
-volume.SignedExpand(velocity);
-update(leaf,volume);
-return(true);
-}
-
-//
-bool			btDbvt::update(btDbvtNode* leaf,btDbvtVolume volume,btScalar margin)
-{
-if(leaf->volume.Contain(volume)) return(false);
-volume.Expand(btVector3(margin,margin,margin));
-update(leaf,volume);
-return(true);
+	leaf->volume=volume;
+	insertleaf(this,root,leaf);
+}
+
+//
+bool			btDbvt::update(btDbvtNode* leaf,btDbvtVolume& volume,const btVector3& velocity,btScalar margin)
+{
+	if(leaf->volume.Contain(volume)) return(false);
+	volume.Expand(btVector3(margin,margin,margin));
+	volume.SignedExpand(velocity);
+	update(leaf,volume);
+	return(true);
+}
+
+//
+bool			btDbvt::update(btDbvtNode* leaf,btDbvtVolume& volume,const btVector3& velocity)
+{
+	if(leaf->volume.Contain(volume)) return(false);
+	volume.SignedExpand(velocity);
+	update(leaf,volume);
+	return(true);
+}
+
+//
+bool			btDbvt::update(btDbvtNode* leaf,btDbvtVolume& volume,btScalar margin)
+{
+	if(leaf->volume.Contain(volume)) return(false);
+	volume.Expand(btVector3(margin,margin,margin));
+	update(leaf,volume);
+	return(true);
 }
 
@@ -549,7 +549,7 @@
 void			btDbvt::remove(btDbvtNode* leaf)
 {
-removeleaf(this,leaf);
-deletenode(this,leaf);
---m_leaves;
+	removeleaf(this,leaf);
+	deletenode(this,leaf);
+	--m_leaves;
 }
 
@@ -557,22 +557,22 @@
 void			btDbvt::write(IWriter* iwriter) const
 {
-btDbvtNodeEnumerator	nodes;
-nodes.nodes.reserve(m_leaves*2);
-enumNodes(m_root,nodes);
-iwriter->Prepare(m_root,nodes.nodes.size());
-for(int i=0;i<nodes.nodes.size();++i)
-	{
-	const btDbvtNode* n=nodes.nodes[i];
-	int			p=-1;
-	if(n->parent) p=nodes.nodes.findLinearSearch(n->parent);
-	if(n->isinternal())
-		{
-		const int	c0=nodes.nodes.findLinearSearch(n->childs[0]);
-		const int	c1=nodes.nodes.findLinearSearch(n->childs[1]);
-		iwriter->WriteNode(n,i,p,c0,c1);
+	btDbvtNodeEnumerator	nodes;
+	nodes.nodes.reserve(m_leaves*2);
+	enumNodes(m_root,nodes);
+	iwriter->Prepare(m_root,nodes.nodes.size());
+	for(int i=0;i<nodes.nodes.size();++i)
+	{
+		const btDbvtNode* n=nodes.nodes[i];
+		int			p=-1;
+		if(n->parent) p=nodes.nodes.findLinearSearch(n->parent);
+		if(n->isinternal())
+		{
+			const int	c0=nodes.nodes.findLinearSearch(n->childs[0]);
+			const int	c1=nodes.nodes.findLinearSearch(n->childs[1]);
+			iwriter->WriteNode(n,i,p,c0,c1);
 		}
 		else
 		{
-		iwriter->WriteLeaf(n,i,p);
+			iwriter->WriteLeaf(n,i,p);
 		}	
 	}
@@ -582,27 +582,27 @@
 void			btDbvt::clone(btDbvt& dest,IClone* iclone) const
 {
-dest.clear();
-if(m_root!=0)
+	dest.clear();
+	if(m_root!=0)
 	{	
-	btAlignedObjectArray<sStkCLN>	stack;
-	stack.reserve(m_leaves);
-	stack.push_back(sStkCLN(m_root,0));
-	do	{
-		const int		i=stack.size()-1;
-		const sStkCLN	e=stack[i];
-		btDbvtNode*			n=createnode(&dest,e.parent,e.node->volume,e.node->data);
-		stack.pop_back();
-		if(e.parent!=0)
-			e.parent->childs[i&1]=n;
+		btAlignedObjectArray<sStkCLN>	stack;
+		stack.reserve(m_leaves);
+		stack.push_back(sStkCLN(m_root,0));
+		do	{
+			const int		i=stack.size()-1;
+			const sStkCLN	e=stack[i];
+			btDbvtNode*			n=createnode(&dest,e.parent,e.node->volume,e.node->data);
+			stack.pop_back();
+			if(e.parent!=0)
+				e.parent->childs[i&1]=n;
 			else
-			dest.m_root=n;
-		if(e.node->isinternal())
-			{
-			stack.push_back(sStkCLN(e.node->childs[0],n));
-			stack.push_back(sStkCLN(e.node->childs[1],n));
+				dest.m_root=n;
+			if(e.node->isinternal())
+			{
+				stack.push_back(sStkCLN(e.node->childs[0],n));
+				stack.push_back(sStkCLN(e.node->childs[1],n));
 			}
 			else
 			{
-			iclone->CloneLeaf(n);
+				iclone->CloneLeaf(n);
 			}
 		} while(stack.size()>0);
@@ -613,7 +613,7 @@
 int				btDbvt::maxdepth(const btDbvtNode* node)
 {
-int	depth=0;
-if(node) getmaxdepth(node,1,depth);
-return(depth);
+	int	depth=0;
+	if(node) getmaxdepth(node,1,depth);
+	return(depth);
 }
 
@@ -621,8 +621,8 @@
 int				btDbvt::countLeaves(const btDbvtNode* node)
 {
-if(node->isinternal())
-	return(countLeaves(node->childs[0])+countLeaves(node->childs[1]));
+	if(node->isinternal())
+		return(countLeaves(node->childs[0])+countLeaves(node->childs[1]));
 	else
-	return(1);
+		return(1);
 }
 
@@ -630,12 +630,12 @@
 void			btDbvt::extractLeaves(const btDbvtNode* node,btAlignedObjectArray<const btDbvtNode*>& leaves)
 {
-if(node->isinternal())
-	{
-	extractLeaves(node->childs[0],leaves);
-	extractLeaves(node->childs[1],leaves);
+	if(node->isinternal())
+	{
+		extractLeaves(node->childs[0],leaves);
+		extractLeaves(node->childs[1],leaves);
 	}
 	else
 	{
-	leaves.push_back(node);
+		leaves.push_back(node);
 	}	
 }
@@ -658,10 +658,10 @@
 
 Benchmarking dbvt...
-        World scale: 100.000000
-        Extents base: 1.000000
-        Extents range: 4.000000
-        Leaves: 8192
-        sizeof(btDbvtVolume): 32 bytes
-        sizeof(btDbvtNode):   44 bytes
+World scale: 100.000000
+Extents base: 1.000000
+Extents range: 4.000000
+Leaves: 8192
+sizeof(btDbvtVolume): 32 bytes
+sizeof(btDbvtNode):   44 bytes
 [1] btDbvtVolume intersections: 3499 ms (-1%)
 [2] btDbvtVolume merges: 1934 ms (0%)
@@ -670,5 +670,5 @@
 [5] btDbvt::collideTT xform: 7379 ms (-1%)
 [6] btDbvt::collideTT xform,self: 7270 ms (-2%)
-[7] btDbvt::collideRAY: 6314 ms (0%),(332143 r/s)
+[7] btDbvt::rayTest: 6314 ms (0%),(332143 r/s)
 [8] insert/remove: 2093 ms (0%),(1001983 ir/s)
 [9] updates (teleport): 1879 ms (-3%),(1116100 u/s)
@@ -685,91 +685,91 @@
 struct btDbvtBenchmark
 {
-struct NilPolicy : btDbvt::ICollide
-	{
-	NilPolicy() : m_pcount(0),m_depth(-SIMD_INFINITY),m_checksort(true)		{}
-	void	Process(const btDbvtNode*,const btDbvtNode*)				{ ++m_pcount; }
-	void	Process(const btDbvtNode*)									{ ++m_pcount; }
-	void	Process(const btDbvtNode*,btScalar depth)
-		{
-		++m_pcount;
-		if(m_checksort)
+	struct NilPolicy : btDbvt::ICollide
+	{
+		NilPolicy() : m_pcount(0),m_depth(-SIMD_INFINITY),m_checksort(true)		{}
+		void	Process(const btDbvtNode*,const btDbvtNode*)				{ ++m_pcount; }
+		void	Process(const btDbvtNode*)									{ ++m_pcount; }
+		void	Process(const btDbvtNode*,btScalar depth)
+		{
+			++m_pcount;
+			if(m_checksort)
 			{ if(depth>=m_depth) m_depth=depth; else printf("wrong depth: %f (should be >= %f)\r\n",depth,m_depth); }
 		}
-	int			m_pcount;
-	btScalar	m_depth;
-	bool		m_checksort;
+		int			m_pcount;
+		btScalar	m_depth;
+		bool		m_checksort;
 	};
-struct P14 : btDbvt::ICollide
-	{
-	struct Node
-		{
-		const btDbvtNode*	leaf;
-		btScalar			depth;
+	struct P14 : btDbvt::ICollide
+	{
+		struct Node
+		{
+			const btDbvtNode*	leaf;
+			btScalar			depth;
 		};
-	void Process(const btDbvtNode* leaf,btScalar depth)
-		{
-		Node	n;
-		n.leaf	=	leaf;
-		n.depth	=	depth;
-		}
-	static int sortfnc(const Node& a,const Node& b)
-		{
-		if(a.depth<b.depth) return(+1);
-		if(a.depth>b.depth) return(-1);
-		return(0);
-		}
-	btAlignedObjectArray<Node>		m_nodes;
+		void Process(const btDbvtNode* leaf,btScalar depth)
+		{
+			Node	n;
+			n.leaf	=	leaf;
+			n.depth	=	depth;
+		}
+		static int sortfnc(const Node& a,const Node& b)
+		{
+			if(a.depth<b.depth) return(+1);
+			if(a.depth>b.depth) return(-1);
+			return(0);
+		}
+		btAlignedObjectArray<Node>		m_nodes;
 	};
-struct P15 : btDbvt::ICollide
-	{
-	struct Node
-		{
-		const btDbvtNode*	leaf;
-		btScalar			depth;
+	struct P15 : btDbvt::ICollide
+	{
+		struct Node
+		{
+			const btDbvtNode*	leaf;
+			btScalar			depth;
 		};
-	void Process(const btDbvtNode* leaf)
-		{
-		Node	n;
-		n.leaf	=	leaf;
-		n.depth	=	dot(leaf->volume.Center(),m_axis);
-		}
-	static int sortfnc(const Node& a,const Node& b)
-		{
-		if(a.depth<b.depth) return(+1);
-		if(a.depth>b.depth) return(-1);
-		return(0);
-		}
-	btAlignedObjectArray<Node>		m_nodes;
-	btVector3						m_axis;
+		void Process(const btDbvtNode* leaf)
+		{
+			Node	n;
+			n.leaf	=	leaf;
+			n.depth	=	dot(leaf->volume.Center(),m_axis);
+		}
+		static int sortfnc(const Node& a,const Node& b)
+		{
+			if(a.depth<b.depth) return(+1);
+			if(a.depth>b.depth) return(-1);
+			return(0);
+		}
+		btAlignedObjectArray<Node>		m_nodes;
+		btVector3						m_axis;
 	};
-static btScalar			RandUnit()
-	{
-	return(rand()/(btScalar)RAND_MAX);
-	}
-static btVector3		RandVector3()
-	{
-	return(btVector3(RandUnit(),RandUnit(),RandUnit()));
-	}
-static btVector3		RandVector3(btScalar cs)
-	{
-	return(RandVector3()*cs-btVector3(cs,cs,cs)/2);
-	}
-static btDbvtVolume	RandVolume(btScalar cs,btScalar eb,btScalar es)
-	{
-	return(btDbvtVolume::FromCE(RandVector3(cs),btVector3(eb,eb,eb)+RandVector3()*es));
-	}
-static btTransform		RandTransform(btScalar cs)
-	{
-	btTransform	t;
-	t.setOrigin(RandVector3(cs));
-	t.setRotation(btQuaternion(RandUnit()*SIMD_PI*2,RandUnit()*SIMD_PI*2,RandUnit()*SIMD_PI*2).normalized());
-	return(t);
-	}
-static void				RandTree(btScalar cs,btScalar eb,btScalar es,int leaves,btDbvt& dbvt)
-	{
-	dbvt.clear();
-	for(int i=0;i<leaves;++i)
-		{
-		dbvt.insert(RandVolume(cs,eb,es),0);
+	static btScalar			RandUnit()
+	{
+		return(rand()/(btScalar)RAND_MAX);
+	}
+	static btVector3		RandVector3()
+	{
+		return(btVector3(RandUnit(),RandUnit(),RandUnit()));
+	}
+	static btVector3		RandVector3(btScalar cs)
+	{
+		return(RandVector3()*cs-btVector3(cs,cs,cs)/2);
+	}
+	static btDbvtVolume	RandVolume(btScalar cs,btScalar eb,btScalar es)
+	{
+		return(btDbvtVolume::FromCE(RandVector3(cs),btVector3(eb,eb,eb)+RandVector3()*es));
+	}
+	static btTransform		RandTransform(btScalar cs)
+	{
+		btTransform	t;
+		t.setOrigin(RandVector3(cs));
+		t.setRotation(btQuaternion(RandUnit()*SIMD_PI*2,RandUnit()*SIMD_PI*2,RandUnit()*SIMD_PI*2).normalized());
+		return(t);
+	}
+	static void				RandTree(btScalar cs,btScalar eb,btScalar es,int leaves,btDbvt& dbvt)
+	{
+		dbvt.clear();
+		for(int i=0;i<leaves;++i)
+		{
+			dbvt.insert(RandVolume(cs,eb,es),0);
 		}
 	}
@@ -778,512 +778,512 @@
 void			btDbvt::benchmark()
 {
-static const btScalar	cfgVolumeCenterScale		=	100;
-static const btScalar	cfgVolumeExentsBase			=	1;
-static const btScalar	cfgVolumeExentsScale		=	4;
-static const int		cfgLeaves					=	8192;
-static const bool		cfgEnable					=	true;
-
-//[1] btDbvtVolume intersections
-bool					cfgBenchmark1_Enable		=	cfgEnable;
-static const int		cfgBenchmark1_Iterations	=	8;
-static const int		cfgBenchmark1_Reference		=	3499;
-//[2] btDbvtVolume merges
-bool					cfgBenchmark2_Enable		=	cfgEnable;
-static const int		cfgBenchmark2_Iterations	=	4;
-static const int		cfgBenchmark2_Reference		=	1945;
-//[3] btDbvt::collideTT
-bool					cfgBenchmark3_Enable		=	cfgEnable;
-static const int		cfgBenchmark3_Iterations	=	512;
-static const int		cfgBenchmark3_Reference		=	5485;
-//[4] btDbvt::collideTT self
-bool					cfgBenchmark4_Enable		=	cfgEnable;
-static const int		cfgBenchmark4_Iterations	=	512;
-static const int		cfgBenchmark4_Reference		=	2814;
-//[5] btDbvt::collideTT xform
-bool					cfgBenchmark5_Enable		=	cfgEnable;
-static const int		cfgBenchmark5_Iterations	=	512;
-static const btScalar	cfgBenchmark5_OffsetScale	=	2;
-static const int		cfgBenchmark5_Reference		=	7379;
-//[6] btDbvt::collideTT xform,self
-bool					cfgBenchmark6_Enable		=	cfgEnable;
-static const int		cfgBenchmark6_Iterations	=	512;
-static const btScalar	cfgBenchmark6_OffsetScale	=	2;
-static const int		cfgBenchmark6_Reference		=	7270;
-//[7] btDbvt::collideRAY
-bool					cfgBenchmark7_Enable		=	cfgEnable;
-static const int		cfgBenchmark7_Passes		=	32;
-static const int		cfgBenchmark7_Iterations	=	65536;
-static const int		cfgBenchmark7_Reference		=	6307;
-//[8] insert/remove
-bool					cfgBenchmark8_Enable		=	cfgEnable;
-static const int		cfgBenchmark8_Passes		=	32;
-static const int		cfgBenchmark8_Iterations	=	65536;
-static const int		cfgBenchmark8_Reference		=	2105;
-//[9] updates (teleport)
-bool					cfgBenchmark9_Enable		=	cfgEnable;
-static const int		cfgBenchmark9_Passes		=	32;
-static const int		cfgBenchmark9_Iterations	=	65536;
-static const int		cfgBenchmark9_Reference		=	1879;
-//[10] updates (jitter)
-bool					cfgBenchmark10_Enable		=	cfgEnable;
-static const btScalar	cfgBenchmark10_Scale		=	cfgVolumeCenterScale/10000;
-static const int		cfgBenchmark10_Passes		=	32;
-static const int		cfgBenchmark10_Iterations	=	65536;
-static const int		cfgBenchmark10_Reference	=	1244;
-//[11] optimize (incremental)
-bool					cfgBenchmark11_Enable		=	cfgEnable;
-static const int		cfgBenchmark11_Passes		=	64;
-static const int		cfgBenchmark11_Iterations	=	65536;
-static const int		cfgBenchmark11_Reference	=	2510;
-//[12] btDbvtVolume notequal
-bool					cfgBenchmark12_Enable		=	cfgEnable;
-static const int		cfgBenchmark12_Iterations	=	32;
-static const int		cfgBenchmark12_Reference	=	3677;
-//[13] culling(OCL+fullsort)
-bool					cfgBenchmark13_Enable		=	cfgEnable;
-static const int		cfgBenchmark13_Iterations	=	1024;
-static const int		cfgBenchmark13_Reference	=	2231;
-//[14] culling(OCL+qsort)
-bool					cfgBenchmark14_Enable		=	cfgEnable;
-static const int		cfgBenchmark14_Iterations	=	8192;
-static const int		cfgBenchmark14_Reference	=	3500;
-//[15] culling(KDOP+qsort)
-bool					cfgBenchmark15_Enable		=	cfgEnable;
-static const int		cfgBenchmark15_Iterations	=	8192;
-static const int		cfgBenchmark15_Reference	=	1151;
-//[16] insert/remove batch
-bool					cfgBenchmark16_Enable		=	cfgEnable;
-static const int		cfgBenchmark16_BatchCount	=	256;
-static const int		cfgBenchmark16_Passes		=	16384;
-static const int		cfgBenchmark16_Reference	=	5138;
-//[17] select
-bool					cfgBenchmark17_Enable		=	cfgEnable;
-static const int		cfgBenchmark17_Iterations	=	4;
-static const int		cfgBenchmark17_Reference	=	3390;
-
-btClock					wallclock;
-printf("Benchmarking dbvt...\r\n");
-printf("\tWorld scale: %f\r\n",cfgVolumeCenterScale);
-printf("\tExtents base: %f\r\n",cfgVolumeExentsBase);
-printf("\tExtents range: %f\r\n",cfgVolumeExentsScale);
-printf("\tLeaves: %u\r\n",cfgLeaves);
-printf("\tsizeof(btDbvtVolume): %u bytes\r\n",sizeof(btDbvtVolume));
-printf("\tsizeof(btDbvtNode):   %u bytes\r\n",sizeof(btDbvtNode));
-if(cfgBenchmark1_Enable)
+	static const btScalar	cfgVolumeCenterScale		=	100;
+	static const btScalar	cfgVolumeExentsBase			=	1;
+	static const btScalar	cfgVolumeExentsScale		=	4;
+	static const int		cfgLeaves					=	8192;
+	static const bool		cfgEnable					=	true;
+
+	//[1] btDbvtVolume intersections
+	bool					cfgBenchmark1_Enable		=	cfgEnable;
+	static const int		cfgBenchmark1_Iterations	=	8;
+	static const int		cfgBenchmark1_Reference		=	3499;
+	//[2] btDbvtVolume merges
+	bool					cfgBenchmark2_Enable		=	cfgEnable;
+	static const int		cfgBenchmark2_Iterations	=	4;
+	static const int		cfgBenchmark2_Reference		=	1945;
+	//[3] btDbvt::collideTT
+	bool					cfgBenchmark3_Enable		=	cfgEnable;
+	static const int		cfgBenchmark3_Iterations	=	512;
+	static const int		cfgBenchmark3_Reference		=	5485;
+	//[4] btDbvt::collideTT self
+	bool					cfgBenchmark4_Enable		=	cfgEnable;
+	static const int		cfgBenchmark4_Iterations	=	512;
+	static const int		cfgBenchmark4_Reference		=	2814;
+	//[5] btDbvt::collideTT xform
+	bool					cfgBenchmark5_Enable		=	cfgEnable;
+	static const int		cfgBenchmark5_Iterations	=	512;
+	static const btScalar	cfgBenchmark5_OffsetScale	=	2;
+	static const int		cfgBenchmark5_Reference		=	7379;
+	//[6] btDbvt::collideTT xform,self
+	bool					cfgBenchmark6_Enable		=	cfgEnable;
+	static const int		cfgBenchmark6_Iterations	=	512;
+	static const btScalar	cfgBenchmark6_OffsetScale	=	2;
+	static const int		cfgBenchmark6_Reference		=	7270;
+	//[7] btDbvt::rayTest
+	bool					cfgBenchmark7_Enable		=	cfgEnable;
+	static const int		cfgBenchmark7_Passes		=	32;
+	static const int		cfgBenchmark7_Iterations	=	65536;
+	static const int		cfgBenchmark7_Reference		=	6307;
+	//[8] insert/remove
+	bool					cfgBenchmark8_Enable		=	cfgEnable;
+	static const int		cfgBenchmark8_Passes		=	32;
+	static const int		cfgBenchmark8_Iterations	=	65536;
+	static const int		cfgBenchmark8_Reference		=	2105;
+	//[9] updates (teleport)
+	bool					cfgBenchmark9_Enable		=	cfgEnable;
+	static const int		cfgBenchmark9_Passes		=	32;
+	static const int		cfgBenchmark9_Iterations	=	65536;
+	static const int		cfgBenchmark9_Reference		=	1879;
+	//[10] updates (jitter)
+	bool					cfgBenchmark10_Enable		=	cfgEnable;
+	static const btScalar	cfgBenchmark10_Scale		=	cfgVolumeCenterScale/10000;
+	static const int		cfgBenchmark10_Passes		=	32;
+	static const int		cfgBenchmark10_Iterations	=	65536;
+	static const int		cfgBenchmark10_Reference	=	1244;
+	//[11] optimize (incremental)
+	bool					cfgBenchmark11_Enable		=	cfgEnable;
+	static const int		cfgBenchmark11_Passes		=	64;
+	static const int		cfgBenchmark11_Iterations	=	65536;
+	static const int		cfgBenchmark11_Reference	=	2510;
+	//[12] btDbvtVolume notequal
+	bool					cfgBenchmark12_Enable		=	cfgEnable;
+	static const int		cfgBenchmark12_Iterations	=	32;
+	static const int		cfgBenchmark12_Reference	=	3677;
+	//[13] culling(OCL+fullsort)
+	bool					cfgBenchmark13_Enable		=	cfgEnable;
+	static const int		cfgBenchmark13_Iterations	=	1024;
+	static const int		cfgBenchmark13_Reference	=	2231;
+	//[14] culling(OCL+qsort)
+	bool					cfgBenchmark14_Enable		=	cfgEnable;
+	static const int		cfgBenchmark14_Iterations	=	8192;
+	static const int		cfgBenchmark14_Reference	=	3500;
+	//[15] culling(KDOP+qsort)
+	bool					cfgBenchmark15_Enable		=	cfgEnable;
+	static const int		cfgBenchmark15_Iterations	=	8192;
+	static const int		cfgBenchmark15_Reference	=	1151;
+	//[16] insert/remove batch
+	bool					cfgBenchmark16_Enable		=	cfgEnable;
+	static const int		cfgBenchmark16_BatchCount	=	256;
+	static const int		cfgBenchmark16_Passes		=	16384;
+	static const int		cfgBenchmark16_Reference	=	5138;
+	//[17] select
+	bool					cfgBenchmark17_Enable		=	cfgEnable;
+	static const int		cfgBenchmark17_Iterations	=	4;
+	static const int		cfgBenchmark17_Reference	=	3390;
+
+	btClock					wallclock;
+	printf("Benchmarking dbvt...\r\n");
+	printf("\tWorld scale: %f\r\n",cfgVolumeCenterScale);
+	printf("\tExtents base: %f\r\n",cfgVolumeExentsBase);
+	printf("\tExtents range: %f\r\n",cfgVolumeExentsScale);
+	printf("\tLeaves: %u\r\n",cfgLeaves);
+	printf("\tsizeof(btDbvtVolume): %u bytes\r\n",sizeof(btDbvtVolume));
+	printf("\tsizeof(btDbvtNode):   %u bytes\r\n",sizeof(btDbvtNode));
+	if(cfgBenchmark1_Enable)
 	{// Benchmark 1	
-	srand(380843);
-	btAlignedObjectArray<btDbvtVolume>	volumes;
-	btAlignedObjectArray<bool>			results;
-	volumes.resize(cfgLeaves);
-	results.resize(cfgLeaves);
-	for(int i=0;i<cfgLeaves;++i)
-		{
-		volumes[i]=btDbvtBenchmark::RandVolume(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale);
-		}
-	printf("[1] btDbvtVolume intersections: ");
-	wallclock.reset();
-	for(int i=0;i<cfgBenchmark1_Iterations;++i)
-		{
-		for(int j=0;j<cfgLeaves;++j)
-			{
-			for(int k=0;k<cfgLeaves;++k)
+		srand(380843);
+		btAlignedObjectArray<btDbvtVolume>	volumes;
+		btAlignedObjectArray<bool>			results;
+		volumes.resize(cfgLeaves);
+		results.resize(cfgLeaves);
+		for(int i=0;i<cfgLeaves;++i)
+		{
+			volumes[i]=btDbvtBenchmark::RandVolume(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale);
+		}
+		printf("[1] btDbvtVolume intersections: ");
+		wallclock.reset();
+		for(int i=0;i<cfgBenchmark1_Iterations;++i)
+		{
+			for(int j=0;j<cfgLeaves;++j)
+			{
+				for(int k=0;k<cfgLeaves;++k)
 				{
-				results[k]=Intersect(volumes[j],volumes[k]);
+					results[k]=Intersect(volumes[j],volumes[k]);
 				}
 			}
 		}
-	const int time=(int)wallclock.getTimeMilliseconds();
-	printf("%u ms (%i%%)\r\n",time,(time-cfgBenchmark1_Reference)*100/time);
-	}
-if(cfgBenchmark2_Enable)
+		const int time=(int)wallclock.getTimeMilliseconds();
+		printf("%u ms (%i%%)\r\n",time,(time-cfgBenchmark1_Reference)*100/time);
+	}
+	if(cfgBenchmark2_Enable)
 	{// Benchmark 2	
-	srand(380843);
-	btAlignedObjectArray<btDbvtVolume>	volumes;
-	btAlignedObjectArray<btDbvtVolume>	results;
-	volumes.resize(cfgLeaves);
-	results.resize(cfgLeaves);
-	for(int i=0;i<cfgLeaves;++i)
-		{
-		volumes[i]=btDbvtBenchmark::RandVolume(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale);
-		}
-	printf("[2] btDbvtVolume merges: ");
-	wallclock.reset();
-	for(int i=0;i<cfgBenchmark2_Iterations;++i)
-		{
-		for(int j=0;j<cfgLeaves;++j)
-			{
-			for(int k=0;k<cfgLeaves;++k)
+		srand(380843);
+		btAlignedObjectArray<btDbvtVolume>	volumes;
+		btAlignedObjectArray<btDbvtVolume>	results;
+		volumes.resize(cfgLeaves);
+		results.resize(cfgLeaves);
+		for(int i=0;i<cfgLeaves;++i)
+		{
+			volumes[i]=btDbvtBenchmark::RandVolume(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale);
+		}
+		printf("[2] btDbvtVolume merges: ");
+		wallclock.reset();
+		for(int i=0;i<cfgBenchmark2_Iterations;++i)
+		{
+			for(int j=0;j<cfgLeaves;++j)
+			{
+				for(int k=0;k<cfgLeaves;++k)
 				{
-				Merge(volumes[j],volumes[k],results[k]);
+					Merge(volumes[j],volumes[k],results[k]);
 				}
 			}
 		}
-	const int time=(int)wallclock.getTimeMilliseconds();
-	printf("%u ms (%i%%)\r\n",time,(time-cfgBenchmark2_Reference)*100/time);
-	}
-if(cfgBenchmark3_Enable)
+		const int time=(int)wallclock.getTimeMilliseconds();
+		printf("%u ms (%i%%)\r\n",time,(time-cfgBenchmark2_Reference)*100/time);
+	}
+	if(cfgBenchmark3_Enable)
 	{// Benchmark 3	
-	srand(380843);
-	btDbvt						dbvt[2];
-	btDbvtBenchmark::NilPolicy	policy;
-	btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt[0]);
-	btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt[1]);
-	dbvt[0].optimizeTopDown();
-	dbvt[1].optimizeTopDown();
-	printf("[3] btDbvt::collideTT: ");
-	wallclock.reset();
-	for(int i=0;i<cfgBenchmark3_Iterations;++i)
-		{
-		btDbvt::collideTT(dbvt[0].m_root,dbvt[1].m_root,policy);
-		}
-	const int time=(int)wallclock.getTimeMilliseconds();
-	printf("%u ms (%i%%)\r\n",time,(time-cfgBenchmark3_Reference)*100/time);
-	}
-if(cfgBenchmark4_Enable)
+		srand(380843);
+		btDbvt						dbvt[2];
+		btDbvtBenchmark::NilPolicy	policy;
+		btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt[0]);
+		btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt[1]);
+		dbvt[0].optimizeTopDown();
+		dbvt[1].optimizeTopDown();
+		printf("[3] btDbvt::collideTT: ");
+		wallclock.reset();
+		for(int i=0;i<cfgBenchmark3_Iterations;++i)
+		{
+			btDbvt::collideTT(dbvt[0].m_root,dbvt[1].m_root,policy);
+		}
+		const int time=(int)wallclock.getTimeMilliseconds();
+		printf("%u ms (%i%%)\r\n",time,(time-cfgBenchmark3_Reference)*100/time);
+	}
+	if(cfgBenchmark4_Enable)
 	{// Benchmark 4
-	srand(380843);
-	btDbvt						dbvt;
-	btDbvtBenchmark::NilPolicy	policy;
-	btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt);
-	dbvt.optimizeTopDown();
-	printf("[4] btDbvt::collideTT self: ");
-	wallclock.reset();
-	for(int i=0;i<cfgBenchmark4_Iterations;++i)
-		{
-		btDbvt::collideTT(dbvt.m_root,dbvt.m_root,policy);
-		}
-	const int time=(int)wallclock.getTimeMilliseconds();
-	printf("%u ms (%i%%)\r\n",time,(time-cfgBenchmark4_Reference)*100/time);
-	}
-if(cfgBenchmark5_Enable)
+		srand(380843);
+		btDbvt						dbvt;
+		btDbvtBenchmark::NilPolicy	policy;
+		btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt);
+		dbvt.optimizeTopDown();
+		printf("[4] btDbvt::collideTT self: ");
+		wallclock.reset();
+		for(int i=0;i<cfgBenchmark4_Iterations;++i)
+		{
+			btDbvt::collideTT(dbvt.m_root,dbvt.m_root,policy);
+		}
+		const int time=(int)wallclock.getTimeMilliseconds();
+		printf("%u ms (%i%%)\r\n",time,(time-cfgBenchmark4_Reference)*100/time);
+	}
+	if(cfgBenchmark5_Enable)
 	{// Benchmark 5	
-	srand(380843);
-	btDbvt								dbvt[2];
-	btAlignedObjectArray<btTransform>	transforms;
-	btDbvtBenchmark::NilPolicy			policy;
-	transforms.resize(cfgBenchmark5_Iterations);
-	for(int i=0;i<transforms.size();++i)
-		{
-		transforms[i]=btDbvtBenchmark::RandTransform(cfgVolumeCenterScale*cfgBenchmark5_OffsetScale);
-		}
-	btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt[0]);
-	btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt[1]);
-	dbvt[0].optimizeTopDown();
-	dbvt[1].optimizeTopDown();
-	printf("[5] btDbvt::collideTT xform: ");
-	wallclock.reset();
-	for(int i=0;i<cfgBenchmark5_Iterations;++i)
-		{
-		btDbvt::collideTT(dbvt[0].m_root,dbvt[1].m_root,transforms[i],policy);
-		}
-	const int time=(int)wallclock.getTimeMilliseconds();
-	printf("%u ms (%i%%)\r\n",time,(time-cfgBenchmark5_Reference)*100/time);
-	}
-if(cfgBenchmark6_Enable)
+		srand(380843);
+		btDbvt								dbvt[2];
+		btAlignedObjectArray<btTransform>	transforms;
+		btDbvtBenchmark::NilPolicy			policy;
+		transforms.resize(cfgBenchmark5_Iterations);
+		for(int i=0;i<transforms.size();++i)
+		{
+			transforms[i]=btDbvtBenchmark::RandTransform(cfgVolumeCenterScale*cfgBenchmark5_OffsetScale);
+		}
+		btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt[0]);
+		btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt[1]);
+		dbvt[0].optimizeTopDown();
+		dbvt[1].optimizeTopDown();
+		printf("[5] btDbvt::collideTT xform: ");
+		wallclock.reset();
+		for(int i=0;i<cfgBenchmark5_Iterations;++i)
+		{
+			btDbvt::collideTT(dbvt[0].m_root,dbvt[1].m_root,transforms[i],policy);
+		}
+		const int time=(int)wallclock.getTimeMilliseconds();
+		printf("%u ms (%i%%)\r\n",time,(time-cfgBenchmark5_Reference)*100/time);
+	}
+	if(cfgBenchmark6_Enable)
 	{// Benchmark 6	
-	srand(380843);
-	btDbvt								dbvt;
-	btAlignedObjectArray<btTransform>	transforms;
-	btDbvtBenchmark::NilPolicy			policy;
-	transforms.resize(cfgBenchmark6_Iterations);
-	for(int i=0;i<transforms.size();++i)
-		{
-		transforms[i]=btDbvtBenchmark::RandTransform(cfgVolumeCenterScale*cfgBenchmark6_OffsetScale);
-		}
-	btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt);
-	dbvt.optimizeTopDown();
-	printf("[6] btDbvt::collideTT xform,self: ");
-	wallclock.reset();
-	for(int i=0;i<cfgBenchmark6_Iterations;++i)
-		{
-		btDbvt::collideTT(dbvt.m_root,dbvt.m_root,transforms[i],policy);		
-		}
-	const int time=(int)wallclock.getTimeMilliseconds();
-	printf("%u ms (%i%%)\r\n",time,(time-cfgBenchmark6_Reference)*100/time);
-	}
-if(cfgBenchmark7_Enable)
+		srand(380843);
+		btDbvt								dbvt;
+		btAlignedObjectArray<btTransform>	transforms;
+		btDbvtBenchmark::NilPolicy			policy;
+		transforms.resize(cfgBenchmark6_Iterations);
+		for(int i=0;i<transforms.size();++i)
+		{
+			transforms[i]=btDbvtBenchmark::RandTransform(cfgVolumeCenterScale*cfgBenchmark6_OffsetScale);
+		}
+		btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt);
+		dbvt.optimizeTopDown();
+		printf("[6] btDbvt::collideTT xform,self: ");
+		wallclock.reset();
+		for(int i=0;i<cfgBenchmark6_Iterations;++i)
+		{
+			btDbvt::collideTT(dbvt.m_root,dbvt.m_root,transforms[i],policy);		
+		}
+		const int time=(int)wallclock.getTimeMilliseconds();
+		printf("%u ms (%i%%)\r\n",time,(time-cfgBenchmark6_Reference)*100/time);
+	}
+	if(cfgBenchmark7_Enable)
 	{// Benchmark 7	
-	srand(380843);
-	btDbvt								dbvt;
-	btAlignedObjectArray<btVector3>		rayorg;
-	btAlignedObjectArray<btVector3>		raydir;
-	btDbvtBenchmark::NilPolicy			policy;
-	rayorg.resize(cfgBenchmark7_Iterations);
-	raydir.resize(cfgBenchmark7_Iterations);
-	for(int i=0;i<rayorg.size();++i)
-		{
-		rayorg[i]=btDbvtBenchmark::RandVector3(cfgVolumeCenterScale*2);
-		raydir[i]=btDbvtBenchmark::RandVector3(cfgVolumeCenterScale*2);
-		}
-	btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt);
-	dbvt.optimizeTopDown();
-	printf("[7] btDbvt::collideRAY: ");
-	wallclock.reset();
-	for(int i=0;i<cfgBenchmark7_Passes;++i)
-		{
-		for(int j=0;j<cfgBenchmark7_Iterations;++j)
-			{
-			btDbvt::collideRAY(dbvt.m_root,rayorg[j],raydir[j],policy);
-			}
-		}
-	const int	time=(int)wallclock.getTimeMilliseconds();
-	unsigned	rays=cfgBenchmark7_Passes*cfgBenchmark7_Iterations;
-	printf("%u ms (%i%%),(%u r/s)\r\n",time,(time-cfgBenchmark7_Reference)*100/time,(rays*1000)/time);
-	}
-if(cfgBenchmark8_Enable)
+		srand(380843);
+		btDbvt								dbvt;
+		btAlignedObjectArray<btVector3>		rayorg;
+		btAlignedObjectArray<btVector3>		raydir;
+		btDbvtBenchmark::NilPolicy			policy;
+		rayorg.resize(cfgBenchmark7_Iterations);
+		raydir.resize(cfgBenchmark7_Iterations);
+		for(int i=0;i<rayorg.size();++i)
+		{
+			rayorg[i]=btDbvtBenchmark::RandVector3(cfgVolumeCenterScale*2);
+			raydir[i]=btDbvtBenchmark::RandVector3(cfgVolumeCenterScale*2);
+		}
+		btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt);
+		dbvt.optimizeTopDown();
+		printf("[7] btDbvt::rayTest: ");
+		wallclock.reset();
+		for(int i=0;i<cfgBenchmark7_Passes;++i)
+		{
+			for(int j=0;j<cfgBenchmark7_Iterations;++j)
+			{
+				btDbvt::rayTest(dbvt.m_root,rayorg[j],rayorg[j]+raydir[j],policy);
+			}
+		}
+		const int	time=(int)wallclock.getTimeMilliseconds();
+		unsigned	rays=cfgBenchmark7_Passes*cfgBenchmark7_Iterations;
+		printf("%u ms (%i%%),(%u r/s)\r\n",time,(time-cfgBenchmark7_Reference)*100/time,(rays*1000)/time);
+	}
+	if(cfgBenchmark8_Enable)
 	{// Benchmark 8	
-	srand(380843);
-	btDbvt								dbvt;
-	btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt);
-	dbvt.optimizeTopDown();
-	printf("[8] insert/remove: ");
-	wallclock.reset();
-	for(int i=0;i<cfgBenchmark8_Passes;++i)
-		{
-		for(int j=0;j<cfgBenchmark8_Iterations;++j)
-			{
-			dbvt.remove(dbvt.insert(btDbvtBenchmark::RandVolume(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale),0));
-			}
-		}
-	const int	time=(int)wallclock.getTimeMilliseconds();
-	const int	ir=cfgBenchmark8_Passes*cfgBenchmark8_Iterations;
-	printf("%u ms (%i%%),(%u ir/s)\r\n",time,(time-cfgBenchmark8_Reference)*100/time,ir*1000/time);
-	}
-if(cfgBenchmark9_Enable)
+		srand(380843);
+		btDbvt								dbvt;
+		btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt);
+		dbvt.optimizeTopDown();
+		printf("[8] insert/remove: ");
+		wallclock.reset();
+		for(int i=0;i<cfgBenchmark8_Passes;++i)
+		{
+			for(int j=0;j<cfgBenchmark8_Iterations;++j)
+			{
+				dbvt.remove(dbvt.insert(btDbvtBenchmark::RandVolume(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale),0));
+			}
+		}
+		const int	time=(int)wallclock.getTimeMilliseconds();
+		const int	ir=cfgBenchmark8_Passes*cfgBenchmark8_Iterations;
+		printf("%u ms (%i%%),(%u ir/s)\r\n",time,(time-cfgBenchmark8_Reference)*100/time,ir*1000/time);
+	}
+	if(cfgBenchmark9_Enable)
 	{// Benchmark 9	
-	srand(380843);
-	btDbvt										dbvt;
-	btAlignedObjectArray<const btDbvtNode*>	leaves;
-	btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt);
-	dbvt.optimizeTopDown();
-	dbvt.extractLeaves(dbvt.m_root,leaves);
-	printf("[9] updates (teleport): ");
-	wallclock.reset();
-	for(int i=0;i<cfgBenchmark9_Passes;++i)
-		{
-		for(int j=0;j<cfgBenchmark9_Iterations;++j)
-			{
-			dbvt.update(const_cast<btDbvtNode*>(leaves[rand()%cfgLeaves]),
-						btDbvtBenchmark::RandVolume(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale));
-			}
-		}
-	const int	time=(int)wallclock.getTimeMilliseconds();
-	const int	up=cfgBenchmark9_Passes*cfgBenchmark9_Iterations;
-	printf("%u ms (%i%%),(%u u/s)\r\n",time,(time-cfgBenchmark9_Reference)*100/time,up*1000/time);
-	}
-if(cfgBenchmark10_Enable)
+		srand(380843);
+		btDbvt										dbvt;
+		btAlignedObjectArray<const btDbvtNode*>	leaves;
+		btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt);
+		dbvt.optimizeTopDown();
+		dbvt.extractLeaves(dbvt.m_root,leaves);
+		printf("[9] updates (teleport): ");
+		wallclock.reset();
+		for(int i=0;i<cfgBenchmark9_Passes;++i)
+		{
+			for(int j=0;j<cfgBenchmark9_Iterations;++j)
+			{
+				dbvt.update(const_cast<btDbvtNode*>(leaves[rand()%cfgLeaves]),
+					btDbvtBenchmark::RandVolume(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale));
+			}
+		}
+		const int	time=(int)wallclock.getTimeMilliseconds();
+		const int	up=cfgBenchmark9_Passes*cfgBenchmark9_Iterations;
+		printf("%u ms (%i%%),(%u u/s)\r\n",time,(time-cfgBenchmark9_Reference)*100/time,up*1000/time);
+	}
+	if(cfgBenchmark10_Enable)
 	{// Benchmark 10	
-	srand(380843);
-	btDbvt										dbvt;
-	btAlignedObjectArray<const btDbvtNode*>	leaves;
-	btAlignedObjectArray<btVector3>				vectors;
-	vectors.resize(cfgBenchmark10_Iterations);
-	for(int i=0;i<vectors.size();++i)
-		{
-		vectors[i]=(btDbvtBenchmark::RandVector3()*2-btVector3(1,1,1))*cfgBenchmark10_Scale;
-		}
-	btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt);
-	dbvt.optimizeTopDown();
-	dbvt.extractLeaves(dbvt.m_root,leaves);
-	printf("[10] updates (jitter): ");
-	wallclock.reset();
-	
-	for(int i=0;i<cfgBenchmark10_Passes;++i)
-		{
-		for(int j=0;j<cfgBenchmark10_Iterations;++j)
+		srand(380843);
+		btDbvt										dbvt;
+		btAlignedObjectArray<const btDbvtNode*>	leaves;
+		btAlignedObjectArray<btVector3>				vectors;
+		vectors.resize(cfgBenchmark10_Iterations);
+		for(int i=0;i<vectors.size();++i)
+		{
+			vectors[i]=(btDbvtBenchmark::RandVector3()*2-btVector3(1,1,1))*cfgBenchmark10_Scale;
+		}
+		btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt);
+		dbvt.optimizeTopDown();
+		dbvt.extractLeaves(dbvt.m_root,leaves);
+		printf("[10] updates (jitter): ");
+		wallclock.reset();
+
+		for(int i=0;i<cfgBenchmark10_Passes;++i)
+		{
+			for(int j=0;j<cfgBenchmark10_Iterations;++j)
 			{			
-			const btVector3&	d=vectors[j];
-			btDbvtNode*		l=const_cast<btDbvtNode*>(leaves[rand()%cfgLeaves]);
-			btDbvtVolume		v=btDbvtVolume::FromMM(l->volume.Mins()+d,l->volume.Maxs()+d);
-			dbvt.update(l,v);
-			}
-		}
-	const int	time=(int)wallclock.getTimeMilliseconds();
-	const int	up=cfgBenchmark10_Passes*cfgBenchmark10_Iterations;
-	printf("%u ms (%i%%),(%u u/s)\r\n",time,(time-cfgBenchmark10_Reference)*100/time,up*1000/time);
-	}
-if(cfgBenchmark11_Enable)
+				const btVector3&	d=vectors[j];
+				btDbvtNode*		l=const_cast<btDbvtNode*>(leaves[rand()%cfgLeaves]);
+				btDbvtVolume		v=btDbvtVolume::FromMM(l->volume.Mins()+d,l->volume.Maxs()+d);
+				dbvt.update(l,v);
+			}
+		}
+		const int	time=(int)wallclock.getTimeMilliseconds();
+		const int	up=cfgBenchmark10_Passes*cfgBenchmark10_Iterations;
+		printf("%u ms (%i%%),(%u u/s)\r\n",time,(time-cfgBenchmark10_Reference)*100/time,up*1000/time);
+	}
+	if(cfgBenchmark11_Enable)
 	{// Benchmark 11	
-	srand(380843);
-	btDbvt										dbvt;
-	btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt);
-	dbvt.optimizeTopDown();
-	printf("[11] optimize (incremental): ");
-	wallclock.reset();	
-	for(int i=0;i<cfgBenchmark11_Passes;++i)
-		{
-		dbvt.optimizeIncremental(cfgBenchmark11_Iterations);
-		}
-	const int	time=(int)wallclock.getTimeMilliseconds();
-	const int	op=cfgBenchmark11_Passes*cfgBenchmark11_Iterations;
-	printf("%u ms (%i%%),(%u o/s)\r\n",time,(time-cfgBenchmark11_Reference)*100/time,op/time*1000);
-	}
-if(cfgBenchmark12_Enable)
+		srand(380843);
+		btDbvt										dbvt;
+		btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt);
+		dbvt.optimizeTopDown();
+		printf("[11] optimize (incremental): ");
+		wallclock.reset();	
+		for(int i=0;i<cfgBenchmark11_Passes;++i)
+		{
+			dbvt.optimizeIncremental(cfgBenchmark11_Iterations);
+		}
+		const int	time=(int)wallclock.getTimeMilliseconds();
+		const int	op=cfgBenchmark11_Passes*cfgBenchmark11_Iterations;
+		printf("%u ms (%i%%),(%u o/s)\r\n",time,(time-cfgBenchmark11_Reference)*100/time,op/time*1000);
+	}
+	if(cfgBenchmark12_Enable)
 	{// Benchmark 12	
-	srand(380843);
-	btAlignedObjectArray<btDbvtVolume>	volumes;
-	btAlignedObjectArray<bool>				results;
-	volumes.resize(cfgLeaves);
-	results.resize(cfgLeaves);
-	for(int i=0;i<cfgLeaves;++i)
-		{
-		volumes[i]=btDbvtBenchmark::RandVolume(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale);
-		}
-	printf("[12] btDbvtVolume notequal: ");
-	wallclock.reset();
-	for(int i=0;i<cfgBenchmark12_Iterations;++i)
-		{
-		for(int j=0;j<cfgLeaves;++j)
-			{
-			for(int k=0;k<cfgLeaves;++k)
+		srand(380843);
+		btAlignedObjectArray<btDbvtVolume>	volumes;
+		btAlignedObjectArray<bool>				results;
+		volumes.resize(cfgLeaves);
+		results.resize(cfgLeaves);
+		for(int i=0;i<cfgLeaves;++i)
+		{
+			volumes[i]=btDbvtBenchmark::RandVolume(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale);
+		}
+		printf("[12] btDbvtVolume notequal: ");
+		wallclock.reset();
+		for(int i=0;i<cfgBenchmark12_Iterations;++i)
+		{
+			for(int j=0;j<cfgLeaves;++j)
+			{
+				for(int k=0;k<cfgLeaves;++k)
 				{
-				results[k]=NotEqual(volumes[j],volumes[k]);
+					results[k]=NotEqual(volumes[j],volumes[k]);
 				}
 			}
 		}
-	const int time=(int)wallclock.getTimeMilliseconds();
-	printf("%u ms (%i%%)\r\n",time,(time-cfgBenchmark12_Reference)*100/time);
-	}
-if(cfgBenchmark13_Enable)
+		const int time=(int)wallclock.getTimeMilliseconds();
+		printf("%u ms (%i%%)\r\n",time,(time-cfgBenchmark12_Reference)*100/time);
+	}
+	if(cfgBenchmark13_Enable)
 	{// Benchmark 13	
-	srand(380843);
-	btDbvt								dbvt;
-	btAlignedObjectArray<btVector3>		vectors;
-	btDbvtBenchmark::NilPolicy			policy;
-	vectors.resize(cfgBenchmark13_Iterations);
-	for(int i=0;i<vectors.size();++i)
-		{
-		vectors[i]=(btDbvtBenchmark::RandVector3()*2-btVector3(1,1,1)).normalized();
-		}
-	btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt);
-	dbvt.optimizeTopDown();
-	printf("[13] culling(OCL+fullsort): ");
-	wallclock.reset();	
-	for(int i=0;i<cfgBenchmark13_Iterations;++i)
-		{
-		static const btScalar	offset=0;
-		policy.m_depth=-SIMD_INFINITY;
-		dbvt.collideOCL(dbvt.m_root,&vectors[i],&offset,vectors[i],1,policy);
-		}
-	const int	time=(int)wallclock.getTimeMilliseconds();
-	const int	t=cfgBenchmark13_Iterations;
-	printf("%u ms (%i%%),(%u t/s)\r\n",time,(time-cfgBenchmark13_Reference)*100/time,(t*1000)/time);
-	}
-if(cfgBenchmark14_Enable)
+		srand(380843);
+		btDbvt								dbvt;
+		btAlignedObjectArray<btVector3>		vectors;
+		btDbvtBenchmark::NilPolicy			policy;
+		vectors.resize(cfgBenchmark13_Iterations);
+		for(int i=0;i<vectors.size();++i)
+		{
+			vectors[i]=(btDbvtBenchmark::RandVector3()*2-btVector3(1,1,1)).normalized();
+		}
+		btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt);
+		dbvt.optimizeTopDown();
+		printf("[13] culling(OCL+fullsort): ");
+		wallclock.reset();	
+		for(int i=0;i<cfgBenchmark13_Iterations;++i)
+		{
+			static const btScalar	offset=0;
+			policy.m_depth=-SIMD_INFINITY;
+			dbvt.collideOCL(dbvt.m_root,&vectors[i],&offset,vectors[i],1,policy);
+		}
+		const int	time=(int)wallclock.getTimeMilliseconds();
+		const int	t=cfgBenchmark13_Iterations;
+		printf("%u ms (%i%%),(%u t/s)\r\n",time,(time-cfgBenchmark13_Reference)*100/time,(t*1000)/time);
+	}
+	if(cfgBenchmark14_Enable)
 	{// Benchmark 14	
-	srand(380843);
-	btDbvt								dbvt;
-	btAlignedObjectArray<btVector3>		vectors;
-	btDbvtBenchmark::P14				policy;
-	vectors.resize(cfgBenchmark14_Iterations);
-	for(int i=0;i<vectors.size();++i)
-		{
-		vectors[i]=(btDbvtBenchmark::RandVector3()*2-btVector3(1,1,1)).normalized();
-		}
-	btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt);
-	dbvt.optimizeTopDown();
-	policy.m_nodes.reserve(cfgLeaves);
-	printf("[14] culling(OCL+qsort): ");
-	wallclock.reset();	
-	for(int i=0;i<cfgBenchmark14_Iterations;++i)
-		{
-		static const btScalar	offset=0;
-		policy.m_nodes.resize(0);
-		dbvt.collideOCL(dbvt.m_root,&vectors[i],&offset,vectors[i],1,policy,false);
-		policy.m_nodes.quickSort(btDbvtBenchmark::P14::sortfnc);
-		}
-	const int	time=(int)wallclock.getTimeMilliseconds();
-	const int	t=cfgBenchmark14_Iterations;
-	printf("%u ms (%i%%),(%u t/s)\r\n",time,(time-cfgBenchmark14_Reference)*100/time,(t*1000)/time);
-	}
-if(cfgBenchmark15_Enable)
+		srand(380843);
+		btDbvt								dbvt;
+		btAlignedObjectArray<btVector3>		vectors;
+		btDbvtBenchmark::P14				policy;
+		vectors.resize(cfgBenchmark14_Iterations);
+		for(int i=0;i<vectors.size();++i)
+		{
+			vectors[i]=(btDbvtBenchmark::RandVector3()*2-btVector3(1,1,1)).normalized();
+		}
+		btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt);
+		dbvt.optimizeTopDown();
+		policy.m_nodes.reserve(cfgLeaves);
+		printf("[14] culling(OCL+qsort): ");
+		wallclock.reset();	
+		for(int i=0;i<cfgBenchmark14_Iterations;++i)
+		{
+			static const btScalar	offset=0;
+			policy.m_nodes.resize(0);
+			dbvt.collideOCL(dbvt.m_root,&vectors[i],&offset,vectors[i],1,policy,false);
+			policy.m_nodes.quickSort(btDbvtBenchmark::P14::sortfnc);
+		}
+		const int	time=(int)wallclock.getTimeMilliseconds();
+		const int	t=cfgBenchmark14_Iterations;
+		printf("%u ms (%i%%),(%u t/s)\r\n",time,(time-cfgBenchmark14_Reference)*100/time,(t*1000)/time);
+	}
+	if(cfgBenchmark15_Enable)
 	{// Benchmark 15	
-	srand(380843);
-	btDbvt								dbvt;
-	btAlignedObjectArray<btVector3>		vectors;
-	btDbvtBenchmark::P15				policy;
-	vectors.resize(cfgBenchmark15_Iterations);
-	for(int i=0;i<vectors.size();++i)
-		{
-		vectors[i]=(btDbvtBenchmark::RandVector3()*2-btVector3(1,1,1)).normalized();
-		}
-	btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt);
-	dbvt.optimizeTopDown();
-	policy.m_nodes.reserve(cfgLeaves);
-	printf("[15] culling(KDOP+qsort): ");
-	wallclock.reset();	
-	for(int i=0;i<cfgBenchmark15_Iterations;++i)
-		{
-		static const btScalar	offset=0;
-		policy.m_nodes.resize(0);
-		policy.m_axis=vectors[i];
-		dbvt.collideKDOP(dbvt.m_root,&vectors[i],&offset,1,policy);
-		policy.m_nodes.quickSort(btDbvtBenchmark::P15::sortfnc);
-		}
-	const int	time=(int)wallclock.getTimeMilliseconds();
-	const int	t=cfgBenchmark15_Iterations;
-	printf("%u ms (%i%%),(%u t/s)\r\n",time,(time-cfgBenchmark15_Reference)*100/time,(t*1000)/time);
-	}
-if(cfgBenchmark16_Enable)
+		srand(380843);
+		btDbvt								dbvt;
+		btAlignedObjectArray<btVector3>		vectors;
+		btDbvtBenchmark::P15				policy;
+		vectors.resize(cfgBenchmark15_Iterations);
+		for(int i=0;i<vectors.size();++i)
+		{
+			vectors[i]=(btDbvtBenchmark::RandVector3()*2-btVector3(1,1,1)).normalized();
+		}
+		btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt);
+		dbvt.optimizeTopDown();
+		policy.m_nodes.reserve(cfgLeaves);
+		printf("[15] culling(KDOP+qsort): ");
+		wallclock.reset();	
+		for(int i=0;i<cfgBenchmark15_Iterations;++i)
+		{
+			static const btScalar	offset=0;
+			policy.m_nodes.resize(0);
+			policy.m_axis=vectors[i];
+			dbvt.collideKDOP(dbvt.m_root,&vectors[i],&offset,1,policy);
+			policy.m_nodes.quickSort(btDbvtBenchmark::P15::sortfnc);
+		}
+		const int	time=(int)wallclock.getTimeMilliseconds();
+		const int	t=cfgBenchmark15_Iterations;
+		printf("%u ms (%i%%),(%u t/s)\r\n",time,(time-cfgBenchmark15_Reference)*100/time,(t*1000)/time);
+	}
+	if(cfgBenchmark16_Enable)
 	{// Benchmark 16	
-	srand(380843);
-	btDbvt								dbvt;
-	btAlignedObjectArray<btDbvtNode*>	batch;
-	btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt);
-	dbvt.optimizeTopDown();
-	batch.reserve(cfgBenchmark16_BatchCount);
-	printf("[16] insert/remove batch(%u): ",cfgBenchmark16_BatchCount);
-	wallclock.reset();
-	for(int i=0;i<cfgBenchmark16_Passes;++i)
-		{
-		for(int j=0;j<cfgBenchmark16_BatchCount;++j)
-			{
-			batch.push_back(dbvt.insert(btDbvtBenchmark::RandVolume(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale),0));
-			}
-		for(int j=0;j<cfgBenchmark16_BatchCount;++j)
-			{
-			dbvt.remove(batch[j]);
-			}
-		batch.resize(0);
-		}
-	const int	time=(int)wallclock.getTimeMilliseconds();
-	const int	ir=cfgBenchmark16_Passes*cfgBenchmark16_BatchCount;
-	printf("%u ms (%i%%),(%u bir/s)\r\n",time,(time-cfgBenchmark16_Reference)*100/time,int(ir*1000.0/time));
-	}
-if(cfgBenchmark17_Enable)
+		srand(380843);
+		btDbvt								dbvt;
+		btAlignedObjectArray<btDbvtNode*>	batch;
+		btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt);
+		dbvt.optimizeTopDown();
+		batch.reserve(cfgBenchmark16_BatchCount);
+		printf("[16] insert/remove batch(%u): ",cfgBenchmark16_BatchCount);
+		wallclock.reset();
+		for(int i=0;i<cfgBenchmark16_Passes;++i)
+		{
+			for(int j=0;j<cfgBenchmark16_BatchCount;++j)
+			{
+				batch.push_back(dbvt.insert(btDbvtBenchmark::RandVolume(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale),0));
+			}
+			for(int j=0;j<cfgBenchmark16_BatchCount;++j)
+			{
+				dbvt.remove(batch[j]);
+			}
+			batch.resize(0);
+		}
+		const int	time=(int)wallclock.getTimeMilliseconds();
+		const int	ir=cfgBenchmark16_Passes*cfgBenchmark16_BatchCount;
+		printf("%u ms (%i%%),(%u bir/s)\r\n",time,(time-cfgBenchmark16_Reference)*100/time,int(ir*1000.0/time));
+	}
+	if(cfgBenchmark17_Enable)
 	{// Benchmark 17
-	srand(380843);
-	btAlignedObjectArray<btDbvtVolume>	volumes;
-	btAlignedObjectArray<int>			results;
-	btAlignedObjectArray<int>			indices;
-	volumes.resize(cfgLeaves);
-	results.resize(cfgLeaves);
-	indices.resize(cfgLeaves);
-	for(int i=0;i<cfgLeaves;++i)
-		{
-		indices[i]=i;
-		volumes[i]=btDbvtBenchmark::RandVolume(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale);
-		}
-	for(int i=0;i<cfgLeaves;++i)
-		{
-		btSwap(indices[i],indices[rand()%cfgLeaves]);
-		}
-	printf("[17] btDbvtVolume select: ");
-	wallclock.reset();
-	for(int i=0;i<cfgBenchmark17_Iterations;++i)
-		{
-		for(int j=0;j<cfgLeaves;++j)
-			{
-			for(int k=0;k<cfgLeaves;++k)
+		srand(380843);
+		btAlignedObjectArray<btDbvtVolume>	volumes;
+		btAlignedObjectArray<int>			results;
+		btAlignedObjectArray<int>			indices;
+		volumes.resize(cfgLeaves);
+		results.resize(cfgLeaves);
+		indices.resize(cfgLeaves);
+		for(int i=0;i<cfgLeaves;++i)
+		{
+			indices[i]=i;
+			volumes[i]=btDbvtBenchmark::RandVolume(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale);
+		}
+		for(int i=0;i<cfgLeaves;++i)
+		{
+			btSwap(indices[i],indices[rand()%cfgLeaves]);
+		}
+		printf("[17] btDbvtVolume select: ");
+		wallclock.reset();
+		for(int i=0;i<cfgBenchmark17_Iterations;++i)
+		{
+			for(int j=0;j<cfgLeaves;++j)
+			{
+				for(int k=0;k<cfgLeaves;++k)
 				{
-				const int idx=indices[k];
-				results[idx]=Select(volumes[idx],volumes[j],volumes[k]);
+					const int idx=indices[k];
+					results[idx]=Select(volumes[idx],volumes[j],volumes[k]);
 				}
 			}
 		}
-	const int time=(int)wallclock.getTimeMilliseconds();
-	printf("%u ms (%i%%)\r\n",time,(time-cfgBenchmark17_Reference)*100/time);
-	}
-printf("\r\n\r\n");
+		const int time=(int)wallclock.getTimeMilliseconds();
+		printf("%u ms (%i%%)\r\n",time,(time-cfgBenchmark17_Reference)*100/time);
+	}
+	printf("\r\n\r\n");
 }
 #endif
Index: code/branches/physics/src/bullet/BulletCollision/BroadphaseCollision/btDbvt.h
===================================================================
--- code/branches/physics/src/bullet/BulletCollision/BroadphaseCollision/btDbvt.h	(revision 2192)
+++ code/branches/physics/src/bullet/BulletCollision/BroadphaseCollision/btDbvt.h	(revision 2430)
@@ -21,4 +21,5 @@
 #include "LinearMath/btVector3.h"
 #include "LinearMath/btTransform.h"
+#include "LinearMath/btAabbUtil2.h"
 
 //
@@ -33,12 +34,12 @@
 // Template implementation of ICollide
 #ifdef WIN32
-	#if (defined (_MSC_VER) && _MSC_VER >= 1400)
-	#define	DBVT_USE_TEMPLATE		1
-	#else
-	#define	DBVT_USE_TEMPLATE		0
-#endif
+#if (defined (_MSC_VER) && _MSC_VER >= 1400)
+#define	DBVT_USE_TEMPLATE		1
 #else
 #define	DBVT_USE_TEMPLATE		0
 #endif
+#else
+#define	DBVT_USE_TEMPLATE		0
+#endif
 
 // Use only intrinsics instead of inline asm
@@ -53,10 +54,4 @@
 // Inlining
 #define DBVT_INLINE				SIMD_FORCE_INLINE
-// Align
-#ifdef WIN32
-#define DBVT_ALIGN				__declspec(align(16))
-#else
-#define DBVT_ALIGN
-#endif
 
 // Specific methods implementation
@@ -135,44 +130,41 @@
 struct	btDbvtAabbMm
 {
-DBVT_INLINE btVector3			Center() const	{ return((mi+mx)/2); }
-DBVT_INLINE btVector3			Lengths() const	{ return(mx-mi); }
-DBVT_INLINE btVector3			Extents() const	{ return((mx-mi)/2); }
-DBVT_INLINE const btVector3&	Mins() const	{ return(mi); }
-DBVT_INLINE const btVector3&	Maxs() const	{ return(mx); }
-static inline btDbvtAabbMm		FromCE(const btVector3& c,const btVector3& e);
-static inline btDbvtAabbMm		FromCR(const btVector3& c,btScalar r);
-static inline btDbvtAabbMm		FromMM(const btVector3& mi,const btVector3& mx);
-static inline btDbvtAabbMm		FromPoints(const btVector3* pts,int n);
-static inline btDbvtAabbMm		FromPoints(const btVector3** ppts,int n);
-DBVT_INLINE void				Expand(const btVector3& e);
-DBVT_INLINE void				SignedExpand(const btVector3& e);
-DBVT_INLINE bool				Contain(const btDbvtAabbMm& a) const;
-DBVT_INLINE int					Classify(const btVector3& n,btScalar o,int s) const;
-DBVT_INLINE btScalar			ProjectMinimum(const btVector3& v,unsigned signs) const;
-DBVT_INLINE friend bool			Intersect(	const btDbvtAabbMm& a,
-											const btDbvtAabbMm& b);
-DBVT_INLINE friend bool			Intersect(	const btDbvtAabbMm& a,
-											const btDbvtAabbMm& b,
-											const btTransform& xform);
-DBVT_INLINE friend bool			Intersect(	const btDbvtAabbMm& a,
-											const btVector3& b);
-DBVT_INLINE friend bool			Intersect(	const btDbvtAabbMm& a,
-											const btVector3& org,
-											const btVector3& invdir,
-											const unsigned* signs);
-DBVT_INLINE friend btScalar		Proximity(	const btDbvtAabbMm& a,
-											const btDbvtAabbMm& b);
-DBVT_INLINE friend int			Select(		const btDbvtAabbMm& o,
-											const btDbvtAabbMm& a,
-											const btDbvtAabbMm& b);
-DBVT_INLINE friend void			Merge(		const btDbvtAabbMm& a,
-											const btDbvtAabbMm& b,
-											btDbvtAabbMm& r);
-DBVT_INLINE friend bool			NotEqual(	const btDbvtAabbMm& a,
-											const btDbvtAabbMm& b);
+	DBVT_INLINE btVector3			Center() const	{ return((mi+mx)/2); }
+	DBVT_INLINE btVector3			Lengths() const	{ return(mx-mi); }
+	DBVT_INLINE btVector3			Extents() const	{ return((mx-mi)/2); }
+	DBVT_INLINE const btVector3&	Mins() const	{ return(mi); }
+	DBVT_INLINE const btVector3&	Maxs() const	{ return(mx); }
+	static inline btDbvtAabbMm		FromCE(const btVector3& c,const btVector3& e);
+	static inline btDbvtAabbMm		FromCR(const btVector3& c,btScalar r);
+	static inline btDbvtAabbMm		FromMM(const btVector3& mi,const btVector3& mx);
+	static inline btDbvtAabbMm		FromPoints(const btVector3* pts,int n);
+	static inline btDbvtAabbMm		FromPoints(const btVector3** ppts,int n);
+	DBVT_INLINE void				Expand(const btVector3& e);
+	DBVT_INLINE void				SignedExpand(const btVector3& e);
+	DBVT_INLINE bool				Contain(const btDbvtAabbMm& a) const;
+	DBVT_INLINE int					Classify(const btVector3& n,btScalar o,int s) const;
+	DBVT_INLINE btScalar			ProjectMinimum(const btVector3& v,unsigned signs) const;
+	DBVT_INLINE friend bool			Intersect(	const btDbvtAabbMm& a,
+		const btDbvtAabbMm& b);
+	DBVT_INLINE friend bool			Intersect(	const btDbvtAabbMm& a,
+		const btDbvtAabbMm& b,
+		const btTransform& xform);
+	DBVT_INLINE friend bool			Intersect(	const btDbvtAabbMm& a,
+		const btVector3& b);
+
+	DBVT_INLINE friend btScalar		Proximity(	const btDbvtAabbMm& a,
+		const btDbvtAabbMm& b);
+	DBVT_INLINE friend int			Select(		const btDbvtAabbMm& o,
+		const btDbvtAabbMm& a,
+		const btDbvtAabbMm& b);
+	DBVT_INLINE friend void			Merge(		const btDbvtAabbMm& a,
+		const btDbvtAabbMm& b,
+		btDbvtAabbMm& r);
+	DBVT_INLINE friend bool			NotEqual(	const btDbvtAabbMm& a,
+		const btDbvtAabbMm& b);
 private:
-DBVT_INLINE void				AddSpan(const btVector3& d,btScalar& smi,btScalar& smx) const;
+	DBVT_INLINE void				AddSpan(const btVector3& d,btScalar& smi,btScalar& smx) const;
 private:
-btVector3	mi,mx;
+	btVector3	mi,mx;
 };
 
@@ -187,9 +179,10 @@
 	DBVT_INLINE bool	isleaf() const		{ return(childs[1]==0); }
 	DBVT_INLINE bool	isinternal() const	{ return(!isleaf()); }
-	union	{
-			btDbvtNode*	childs[2];
-			void*	data;
-			int		dataAsInt;
-			};
+	union
+	{
+		btDbvtNode*	childs[2];
+		void*	data;
+		int		dataAsInt;
+	};
 };
 
@@ -198,21 +191,21 @@
 ///Unlike the btQuantizedBvh, nodes can be dynamically moved around, which allows for change in topology of the underlying data structure.
 struct	btDbvt
-	{
+{
 	/* Stack element	*/ 
 	struct	sStkNN
-		{
+	{
 		const btDbvtNode*	a;
 		const btDbvtNode*	b;
 		sStkNN() {}
 		sStkNN(const btDbvtNode* na,const btDbvtNode* nb) : a(na),b(nb) {}
-		};
+	};
 	struct	sStkNP
-		{
+	{
 		const btDbvtNode*	node;
 		int			mask;
 		sStkNP(const btDbvtNode* n,unsigned m) : node(n),mask(m) {}
-		};
+	};
 	struct	sStkNPS
-		{
+	{
 		const btDbvtNode*	node;
 		int			mask;
@@ -220,44 +213,44 @@
 		sStkNPS() {}
 		sStkNPS(const btDbvtNode* n,unsigned m,btScalar v) : node(n),mask(m),value(v) {}
-		};
+	};
 	struct	sStkCLN
-		{
+	{
 		const btDbvtNode*	node;
 		btDbvtNode*		parent;
 		sStkCLN(const btDbvtNode* n,btDbvtNode* p) : node(n),parent(p) {}
-		};
+	};
 	// Policies/Interfaces
-			
+
 	/* ICollide	*/ 
 	struct	ICollide
-		{		
+	{		
 		DBVT_VIRTUAL_DTOR(ICollide)
-		DBVT_VIRTUAL void	Process(const btDbvtNode*,const btDbvtNode*)		{}
+			DBVT_VIRTUAL void	Process(const btDbvtNode*,const btDbvtNode*)		{}
 		DBVT_VIRTUAL void	Process(const btDbvtNode*)					{}
 		DBVT_VIRTUAL void	Process(const btDbvtNode* n,btScalar)			{ Process(n); }
 		DBVT_VIRTUAL bool	Descent(const btDbvtNode*)					{ return(true); }
 		DBVT_VIRTUAL bool	AllLeaves(const btDbvtNode*)					{ return(true); }
-		};
+	};
 	/* IWriter	*/ 
 	struct	IWriter
-		{
+	{
 		virtual ~IWriter() {}
 		virtual void		Prepare(const btDbvtNode* root,int numnodes)=0;
 		virtual void		WriteNode(const btDbvtNode*,int index,int parent,int child0,int child1)=0;
 		virtual void		WriteLeaf(const btDbvtNode*,int index,int parent)=0;
-		};
+	};
 	/* IClone	*/ 
 	struct	IClone
-		{
+	{
 		virtual ~IClone()	{}
 		virtual void		CloneLeaf(btDbvtNode*) {}
-		};
-		
+	};
+
 	// Constants
 	enum	{
-			SIMPLE_STACKSIZE	=	64,
-			DOUBLE_STACKSIZE	=	SIMPLE_STACKSIZE*2
-			};
-		
+		SIMPLE_STACKSIZE	=	64,
+		DOUBLE_STACKSIZE	=	SIMPLE_STACKSIZE*2
+	};
+
 	// Fields
 	btDbvtNode*		m_root;
@@ -266,7 +259,12 @@
 	int				m_leaves;
 	unsigned		m_opath;
+
+	
+	btAlignedObjectArray<sStkNN>	m_stkStack;
+
+
 	// Methods
-					btDbvt();
-					~btDbvt();
+	btDbvt();
+	~btDbvt();
 	void			clear();
 	bool			empty() const { return(0==m_root); }
@@ -276,8 +274,8 @@
 	btDbvtNode*		insert(const btDbvtVolume& box,void* data);
 	void			update(btDbvtNode* leaf,int lookahead=-1);
-	void			update(btDbvtNode* leaf,const btDbvtVolume& volume);
-	bool			update(btDbvtNode* leaf,btDbvtVolume volume,const btVector3& velocity,btScalar margin);
-	bool			update(btDbvtNode* leaf,btDbvtVolume volume,const btVector3& velocity);
-	bool			update(btDbvtNode* leaf,btDbvtVolume volume,btScalar margin);	
+	void			update(btDbvtNode* leaf,btDbvtVolume& volume);
+	bool			update(btDbvtNode* leaf,btDbvtVolume& volume,const btVector3& velocity,btScalar margin);
+	bool			update(btDbvtNode* leaf,btDbvtVolume& volume,const btVector3& velocity);
+	bool			update(btDbvtNode* leaf,btDbvtVolume& volume,btScalar margin);	
 	void			remove(btDbvtNode* leaf);
 	void			write(IWriter* iwriter) const;
@@ -286,83 +284,104 @@
 	static int		countLeaves(const btDbvtNode* node);
 	static void		extractLeaves(const btDbvtNode* node,btAlignedObjectArray<const btDbvtNode*>& leaves);
-	#if DBVT_ENABLE_BENCHMARK
+#if DBVT_ENABLE_BENCHMARK
 	static void		benchmark();
-	#else
+#else
 	static void		benchmark(){}
-	#endif
+#endif
 	// DBVT_IPOLICY must support ICollide policy/interface
 	DBVT_PREFIX
-	static void		enumNodes(	const btDbvtNode* root,
-								DBVT_IPOLICY);
+		static void		enumNodes(	const btDbvtNode* root,
+		DBVT_IPOLICY);
 	DBVT_PREFIX
-	static void		enumLeaves(	const btDbvtNode* root,
-								DBVT_IPOLICY);
+		static void		enumLeaves(	const btDbvtNode* root,
+		DBVT_IPOLICY);
 	DBVT_PREFIX
-	static void		collideTT(	const btDbvtNode* root0,
-								const btDbvtNode* root1,
-								DBVT_IPOLICY);
+		void		collideTT(	const btDbvtNode* root0,
+		const btDbvtNode* root1,
+		DBVT_IPOLICY);
+
 	DBVT_PREFIX
-	static void		collideTT(	const btDbvtNode* root0,
-								const btDbvtNode* root1,
-								const btTransform& xform,
-								DBVT_IPOLICY);
+		void		collideTTpersistentStack(	const btDbvtNode* root0,
+		  const btDbvtNode* root1,
+		  DBVT_IPOLICY);
+
 	DBVT_PREFIX
-	static void		collideTT(	const btDbvtNode* root0,
-								const btTransform& xform0,
-								const btDbvtNode* root1,
-								const btTransform& xform1,
-								DBVT_IPOLICY);
+		void		collideTT(	const btDbvtNode* root0,
+		const btDbvtNode* root1,
+		const btTransform& xform,
+		DBVT_IPOLICY);
 	DBVT_PREFIX
-	static void		collideTV(	const btDbvtNode* root,
-								const btDbvtVolume& volume,
-								DBVT_IPOLICY);
+		void		collideTT(	const btDbvtNode* root0,
+		const btTransform& xform0,
+		const btDbvtNode* root1,
+		const btTransform& xform1,
+		DBVT_IPOLICY);
 	DBVT_PREFIX
-	static void		collideRAY(	const btDbvtNode* root,
-								const btVector3& origin,
-								const btVector3& direction,
-								DBVT_IPOLICY);
+		void		collideTV(	const btDbvtNode* root,
+		const btDbvtVolume& volume,
+		DBVT_IPOLICY);
+	///rayTest is a re-entrant ray test, and can be called in parallel as long as the btAlignedAlloc is thread-safe (uses locking etc)
+	///rayTest is slower than rayTestInternal, because it builds a local stack, using memory allocations, and it recomputes signs/rayDirectionInverses each time
 	DBVT_PREFIX
-	static void		collideKDOP(const btDbvtNode* root,
-								const btVector3* normals,
-								const btScalar* offsets,
-								int count,
-								DBVT_IPOLICY);
+		static void		rayTest(	const btDbvtNode* root,
+		const btVector3& rayFrom,
+		const btVector3& rayTo,
+		DBVT_IPOLICY);
+	///rayTestInternal is faster than rayTest, because it uses a persistent stack (to reduce dynamic memory allocations to a minimum) and it uses precomputed signs/rayInverseDirections
+	///rayTestInternal is used by btDbvtBroadphase to accelerate world ray casts
 	DBVT_PREFIX
-	static void		collideOCL(	const btDbvtNode* root,
-								const btVector3* normals,
-								const btScalar* offsets,
-								const btVector3& sortaxis,
-								int count,								
-								DBVT_IPOLICY,
-								bool fullsort=true);
+		void		rayTestInternal(	const btDbvtNode* root,
+								const btVector3& rayFrom,
+								const btVector3& rayTo,
+								const btVector3& rayDirectionInverse,
+								unsigned int signs[3],
+								btScalar lambda_max,
+								const btVector3& aabbMin,
+								const btVector3& aabbMax,
+								DBVT_IPOLICY) const;
+
 	DBVT_PREFIX
-	static void		collideTU(	const btDbvtNode* root,
-								DBVT_IPOLICY);
+		static void		collideKDOP(const btDbvtNode* root,
+		const btVector3* normals,
+		const btScalar* offsets,
+		int count,
+		DBVT_IPOLICY);
+	DBVT_PREFIX
+		static void		collideOCL(	const btDbvtNode* root,
+		const btVector3* normals,
+		const btScalar* offsets,
+		const btVector3& sortaxis,
+		int count,								
+		DBVT_IPOLICY,
+		bool fullsort=true);
+	DBVT_PREFIX
+		static void		collideTU(	const btDbvtNode* root,
+		DBVT_IPOLICY);
 	// Helpers	
 	static DBVT_INLINE int	nearest(const int* i,const btDbvt::sStkNPS* a,btScalar v,int l,int h)
-		{
+	{
 		int	m=0;
 		while(l<h)
-			{
+		{
 			m=(l+h)>>1;
 			if(a[i[m]].value>=v) l=m+1; else h=m;
-			}
+		}
 		return(h);
-		}
+	}
 	static DBVT_INLINE int	allocate(	btAlignedObjectArray<int>& ifree,
-										btAlignedObjectArray<sStkNPS>& stock,
-										const sStkNPS& value)
-		{
+		btAlignedObjectArray<sStkNPS>& stock,
+		const sStkNPS& value)
+	{
 		int	i;
 		if(ifree.size()>0)
-			{ i=ifree[ifree.size()-1];ifree.pop_back();stock[i]=value; }
-			else
-			{ i=stock.size();stock.push_back(value); }
+		{ i=ifree[ifree.size()-1];ifree.pop_back();stock[i]=value; }
+		else
+		{ i=stock.size();stock.push_back(value); }
 		return(i); 
-		}
+	}
 	//
-	private:
-					btDbvt(const btDbvt&)	{}	
-	};
+private:
+	btDbvt(const btDbvt&)	{}	
+};
 
 //
@@ -373,34 +392,34 @@
 inline btDbvtAabbMm			btDbvtAabbMm::FromCE(const btVector3& c,const btVector3& e)
 {
-btDbvtAabbMm box;
-box.mi=c-e;box.mx=c+e;
-return(box);
-}
-	
+	btDbvtAabbMm box;
+	box.mi=c-e;box.mx=c+e;
+	return(box);
+}
+
 //
 inline btDbvtAabbMm			btDbvtAabbMm::FromCR(const btVector3& c,btScalar r)
 {
-return(FromCE(c,btVector3(r,r,r)));
-}
-	
+	return(FromCE(c,btVector3(r,r,r)));
+}
+
 //
 inline btDbvtAabbMm			btDbvtAabbMm::FromMM(const btVector3& mi,const btVector3& mx)
 {
-btDbvtAabbMm box;
-box.mi=mi;box.mx=mx;
-return(box);
-}
-	
+	btDbvtAabbMm box;
+	box.mi=mi;box.mx=mx;
+	return(box);
+}
+
 //
 inline btDbvtAabbMm			btDbvtAabbMm::FromPoints(const btVector3* pts,int n)
 {
-btDbvtAabbMm box;
-box.mi=box.mx=pts[0];
-for(int i=1;i<n;++i)
-	{
-	box.mi.setMin(pts[i]);
-	box.mx.setMax(pts[i]);
+	btDbvtAabbMm box;
+	box.mi=box.mx=pts[0];
+	for(int i=1;i<n;++i)
+	{
+		box.mi.setMin(pts[i]);
+		box.mx.setMax(pts[i]);
 	}
-return(box);
+	return(box);
 }
 
@@ -408,12 +427,12 @@
 inline btDbvtAabbMm			btDbvtAabbMm::FromPoints(const btVector3** ppts,int n)
 {
-btDbvtAabbMm box;
-box.mi=box.mx=*ppts[0];
-for(int i=1;i<n;++i)
-	{
-	box.mi.setMin(*ppts[i]);
-	box.mx.setMax(*ppts[i]);
+	btDbvtAabbMm box;
+	box.mi=box.mx=*ppts[0];
+	for(int i=1;i<n;++i)
+	{
+		box.mi.setMin(*ppts[i]);
+		box.mx.setMax(*ppts[i]);
 	}
-return(box);
+	return(box);
 }
 
@@ -421,19 +440,19 @@
 DBVT_INLINE void		btDbvtAabbMm::Expand(const btVector3& e)
 {
-mi-=e;mx+=e;
-}
-	
+	mi-=e;mx+=e;
+}
+
 //
 DBVT_INLINE void		btDbvtAabbMm::SignedExpand(const btVector3& e)
 {
-if(e.x()>0) mx.setX(mx.x()+e[0]); else mi.setX(mi.x()+e[0]);
-if(e.y()>0) mx.setY(mx.y()+e[1]); else mi.setY(mi.y()+e[1]);
-if(e.z()>0) mx.setZ(mx.z()+e[2]); else mi.setZ(mi.z()+e[2]);
-}
-	
+	if(e.x()>0) mx.setX(mx.x()+e[0]); else mi.setX(mi.x()+e[0]);
+	if(e.y()>0) mx.setY(mx.y()+e[1]); else mi.setY(mi.y()+e[1]);
+	if(e.z()>0) mx.setZ(mx.z()+e[2]); else mi.setZ(mi.z()+e[2]);
+}
+
 //
 DBVT_INLINE bool		btDbvtAabbMm::Contain(const btDbvtAabbMm& a) const
 {
-return(	(mi.x()<=a.mi.x())&&
+	return(	(mi.x()<=a.mi.x())&&
 		(mi.y()<=a.mi.y())&&
 		(mi.z()<=a.mi.z())&&
@@ -446,27 +465,27 @@
 DBVT_INLINE int		btDbvtAabbMm::Classify(const btVector3& n,btScalar o,int s) const
 {
-btVector3			pi,px;
-switch(s)
+	btVector3			pi,px;
+	switch(s)
 	{
 	case	(0+0+0):	px=btVector3(mi.x(),mi.y(),mi.z());
-						pi=btVector3(mx.x(),mx.y(),mx.z());break;
+		pi=btVector3(mx.x(),mx.y(),mx.z());break;
 	case	(1+0+0):	px=btVector3(mx.x(),mi.y(),mi.z());
-						pi=btVector3(mi.x(),mx.y(),mx.z());break;
+		pi=btVector3(mi.x(),mx.y(),mx.z());break;
 	case	(0+2+0):	px=btVector3(mi.x(),mx.y(),mi.z());
-						pi=btVector3(mx.x(),mi.y(),mx.z());break;
+		pi=btVector3(mx.x(),mi.y(),mx.z());break;
 	case	(1+2+0):	px=btVector3(mx.x(),mx.y(),mi.z());
-						pi=btVector3(mi.x(),mi.y(),mx.z());break;
+		pi=btVector3(mi.x(),mi.y(),mx.z());break;
 	case	(0+0+4):	px=btVector3(mi.x(),mi.y(),mx.z());
-						pi=btVector3(mx.x(),mx.y(),mi.z());break;
+		pi=btVector3(mx.x(),mx.y(),mi.z());break;
 	case	(1+0+4):	px=btVector3(mx.x(),mi.y(),mx.z());
-						pi=btVector3(mi.x(),mx.y(),mi.z());break;
+		pi=btVector3(mi.x(),mx.y(),mi.z());break;
 	case	(0+2+4):	px=btVector3(mi.x(),mx.y(),mx.z());
-						pi=btVector3(mx.x(),mi.y(),mi.z());break;
+		pi=btVector3(mx.x(),mi.y(),mi.z());break;
 	case	(1+2+4):	px=btVector3(mx.x(),mx.y(),mx.z());
-						pi=btVector3(mi.x(),mi.y(),mi.z());break;
+		pi=btVector3(mi.x(),mi.y(),mi.z());break;
 	}
-if((dot(n,px)+o)<0)		return(-1);
-if((dot(n,pi)+o)>=0)	return(+1);
-return(0);
+	if((dot(n,px)+o)<0)		return(-1);
+	if((dot(n,pi)+o)>=0)	return(+1);
+	return(0);
 }
 
@@ -474,9 +493,9 @@
 DBVT_INLINE btScalar	btDbvtAabbMm::ProjectMinimum(const btVector3& v,unsigned signs) const
 {
-const btVector3*	b[]={&mx,&mi};
-const btVector3		p(	b[(signs>>0)&1]->x(),
-						b[(signs>>1)&1]->y(),
-						b[(signs>>2)&1]->z());
-return(dot(p,v));
+	const btVector3*	b[]={&mx,&mi};
+	const btVector3		p(	b[(signs>>0)&1]->x(),
+		b[(signs>>1)&1]->y(),
+		b[(signs>>2)&1]->z());
+	return(dot(p,v));
 }
 
@@ -484,7 +503,7 @@
 DBVT_INLINE void		btDbvtAabbMm::AddSpan(const btVector3& d,btScalar& smi,btScalar& smx) const
 {
-for(int i=0;i<3;++i)
-	{
-	if(d[i]<0)
+	for(int i=0;i<3;++i)
+	{
+		if(d[i]<0)
 		{ smi+=mx[i]*d[i];smx+=mi[i]*d[i]; }
 		else
@@ -492,16 +511,16 @@
 	}
 }
-	
+
 //
 DBVT_INLINE bool		Intersect(	const btDbvtAabbMm& a,
-									const btDbvtAabbMm& b)
+								  const btDbvtAabbMm& b)
 {
 #if	DBVT_INT0_IMPL == DBVT_IMPL_SSE
-const __m128	rt(_mm_or_ps(	_mm_cmplt_ps(_mm_load_ps(b.mx),_mm_load_ps(a.mi)),
-								_mm_cmplt_ps(_mm_load_ps(a.mx),_mm_load_ps(b.mi))));
-const __int32*	pu((const __int32*)&rt);
-return((pu[0]|pu[1]|pu[2])==0);
+	const __m128	rt(_mm_or_ps(	_mm_cmplt_ps(_mm_load_ps(b.mx),_mm_load_ps(a.mi)),
+		_mm_cmplt_ps(_mm_load_ps(a.mx),_mm_load_ps(b.mi))));
+	const __int32*	pu((const __int32*)&rt);
+	return((pu[0]|pu[1]|pu[2])==0);
 #else
-return(	(a.mi.x()<=b.mx.x())&&
+	return(	(a.mi.x()<=b.mx.x())&&
 		(a.mx.x()>=b.mi.x())&&
 		(a.mi.y()<=b.mx.y())&&
@@ -514,23 +533,23 @@
 //
 DBVT_INLINE bool		Intersect(	const btDbvtAabbMm& a,
-									const btDbvtAabbMm& b,
-									const btTransform& xform)
-{
-const btVector3		d0=xform*b.Center()-a.Center();
-const btVector3		d1=d0*xform.getBasis();
-btScalar			s0[2]={0,0};
-btScalar			s1[2]={dot(xform.getOrigin(),d0),s1[0]};
-a.AddSpan(d0,s0[0],s0[1]);
-b.AddSpan(d1,s1[0],s1[1]);
-if(s0[0]>(s1[1])) return(false);
-if(s0[1]<(s1[0])) return(false);
-return(true);
+								  const btDbvtAabbMm& b,
+								  const btTransform& xform)
+{
+	const btVector3		d0=xform*b.Center()-a.Center();
+	const btVector3		d1=d0*xform.getBasis();
+	btScalar			s0[2]={0,0};
+	btScalar			s1[2]={dot(xform.getOrigin(),d0),s1[0]};
+	a.AddSpan(d0,s0[0],s0[1]);
+	b.AddSpan(d1,s1[0],s1[1]);
+	if(s0[0]>(s1[1])) return(false);
+	if(s0[1]<(s1[0])) return(false);
+	return(true);
 }
 
 //
 DBVT_INLINE bool		Intersect(	const btDbvtAabbMm& a,
-									const btVector3& b)
-{
-return(	(b.x()>=a.mi.x())&&
+								  const btVector3& b)
+{
+	return(	(b.x()>=a.mi.x())&&
 		(b.y()>=a.mi.y())&&
 		(b.z()>=a.mi.z())&&
@@ -540,53 +559,38 @@
 }
 
-//
-DBVT_INLINE bool		Intersect(	const btDbvtAabbMm& a,
-									const btVector3& org,
-									const btVector3& invdir,
-									const unsigned* signs)
-{
-#if 0
-const btVector3		b0((a.mi-org)*invdir);
-const btVector3		b1((a.mx-org)*invdir);
-const btVector3		tmin(btMin(b0[0],b1[0]),btMin(b0[1],b1[1]),btMin(b0[2],b1[2]));
-const btVector3		tmax(btMax(b0[0],b1[0]),btMax(b0[1],b1[1]),btMax(b0[2],b1[2]));
-const btScalar		tin=btMax(tmin[0],btMax(tmin[1],tmin[2]));
-const btScalar		tout=btMin(tmax[0],btMin(tmax[1],tmax[2]));
-return(tin<tout);
-#else
-const btVector3*	bounds[2]={&a.mi,&a.mx};
-btScalar			txmin=(bounds[  signs[0]]->x()-org[0])*invdir[0];
-btScalar			txmax=(bounds[1-signs[0]]->x()-org[0])*invdir[0];
-const btScalar		tymin=(bounds[  signs[1]]->y()-org[1])*invdir[1];
-const btScalar		tymax=(bounds[1-signs[1]]->y()-org[1])*invdir[1];
-if((txmin>tymax)||(tymin>txmax)) return(false);
-if(tymin>txmin) txmin=tymin;
-if(tymax<txmax) txmax=tymax;
-const btScalar		tzmin=(bounds[  signs[2]]->z()-org[2])*invdir[2];
-const btScalar		tzmax=(bounds[1-signs[2]]->z()-org[2])*invdir[2];
-if((txmin>tzmax)||(tzmin>txmax)) return(false);
-if(tzmin>txmin) txmin=tzmin;
-if(tzmax<txmax) txmax=tzmax;
-return(txmax>0);
-#endif
-}
-	
+
+
+
+
+//////////////////////////////////////
+
+
 //
 DBVT_INLINE btScalar	Proximity(	const btDbvtAabbMm& a,
-									const btDbvtAabbMm& b)
-{
-const btVector3	d=(a.mi+a.mx)-(b.mi+b.mx);
-return(btFabs(d.x())+btFabs(d.y())+btFabs(d.z()));
-}
+								  const btDbvtAabbMm& b)
+{
+	const btVector3	d=(a.mi+a.mx)-(b.mi+b.mx);
+	return(btFabs(d.x())+btFabs(d.y())+btFabs(d.z()));
+}
+
+
 
 //
 DBVT_INLINE int			Select(	const btDbvtAabbMm& o,
-								const btDbvtAabbMm& a,
-								const btDbvtAabbMm& b)
+							   const btDbvtAabbMm& a,
+							   const btDbvtAabbMm& b)
 {
 #if	DBVT_SELECT_IMPL == DBVT_IMPL_SSE
-static DBVT_ALIGN const unsigned __int32	mask[]={0x7fffffff,0x7fffffff,0x7fffffff,0x7fffffff};
-	// TODO: the intrinsic version is 11% slower
-	#if DBVT_USE_INTRINSIC_SSE
+	static ATTRIBUTE_ALIGNED16(const unsigned __int32)	mask[]={0x7fffffff,0x7fffffff,0x7fffffff,0x7fffffff};
+	///@todo: the intrinsic version is 11% slower
+#if DBVT_USE_INTRINSIC_SSE
+
+	union btSSEUnion ///NOTE: if we use more intrinsics, move btSSEUnion into the LinearMath directory
+	{
+	   __m128		ssereg;
+	   float		floats[4];
+	   int			ints[4];
+	};
+
 	__m128	omi(_mm_load_ps(o.mi));
 	omi=_mm_add_ps(omi,_mm_load_ps(o.mx));
@@ -602,18 +606,22 @@
 	ami=_mm_add_ps(ami,t0);
 	ami=_mm_add_ss(ami,_mm_shuffle_ps(ami,ami,1));
-	__m128	t1(_mm_movehl_ps(bmi,bmi));
+	__m128 t1(_mm_movehl_ps(bmi,bmi));
 	bmi=_mm_add_ps(bmi,t1);
 	bmi=_mm_add_ss(bmi,_mm_shuffle_ps(bmi,bmi,1));
-	return(_mm_cmple_ss(bmi,ami).m128_u32[0]&1);
-	#else
-	DBVT_ALIGN __int32	r[1];
+	
+	btSSEUnion tmp;
+	tmp.ssereg = _mm_cmple_ss(bmi,ami);
+	return tmp.ints[0]&1;
+
+#else
+	ATTRIBUTE_ALIGNED16(__int32	r[1]);
 	__asm
-		{
+	{
 		mov		eax,o
-		mov		ecx,a
-		mov		edx,b
-		movaps	xmm0,[eax]
+			mov		ecx,a
+			mov		edx,b
+			movaps	xmm0,[eax]
 		movaps	xmm5,mask
-		addps	xmm0,[eax+16]	
+			addps	xmm0,[eax+16]	
 		movaps	xmm1,[ecx]
 		movaps	xmm2,[edx]
@@ -621,22 +629,22 @@
 		addps	xmm2,[edx+16]
 		subps	xmm1,xmm0
-		subps	xmm2,xmm0
-		andps	xmm1,xmm5
-		andps	xmm2,xmm5
-		movhlps	xmm3,xmm1
-		movhlps	xmm4,xmm2
-		addps	xmm1,xmm3
-		addps	xmm2,xmm4
-		pshufd	xmm3,xmm1,1
-		pshufd	xmm4,xmm2,1
-		addss	xmm1,xmm3
-		addss	xmm2,xmm4
-		cmpless	xmm2,xmm1
-		movss	r,xmm2
-		}
+			subps	xmm2,xmm0
+			andps	xmm1,xmm5
+			andps	xmm2,xmm5
+			movhlps	xmm3,xmm1
+			movhlps	xmm4,xmm2
+			addps	xmm1,xmm3
+			addps	xmm2,xmm4
+			pshufd	xmm3,xmm1,1
+			pshufd	xmm4,xmm2,1
+			addss	xmm1,xmm3
+			addss	xmm2,xmm4
+			cmpless	xmm2,xmm1
+			movss	r,xmm2
+	}
 	return(r[0]&1);
-	#endif
+#endif
 #else
-return(Proximity(o,a)<Proximity(o,b)?0:1);
+	return(Proximity(o,a)<Proximity(o,b)?0:1);
 #endif
 }
@@ -644,21 +652,21 @@
 //
 DBVT_INLINE void		Merge(	const btDbvtAabbMm& a,
-								const btDbvtAabbMm& b,
-								btDbvtAabbMm& r)
+							  const btDbvtAabbMm& b,
+							  btDbvtAabbMm& r)
 {
 #if DBVT_MERGE_IMPL==DBVT_IMPL_SSE
-__m128	ami(_mm_load_ps(a.mi));
-__m128	amx(_mm_load_ps(a.mx));
-__m128	bmi(_mm_load_ps(b.mi));
-__m128	bmx(_mm_load_ps(b.mx));
-ami=_mm_min_ps(ami,bmi);
-amx=_mm_max_ps(amx,bmx);
-_mm_store_ps(r.mi,ami);
-_mm_store_ps(r.mx,amx);
+	__m128	ami(_mm_load_ps(a.mi));
+	__m128	amx(_mm_load_ps(a.mx));
+	__m128	bmi(_mm_load_ps(b.mi));
+	__m128	bmx(_mm_load_ps(b.mx));
+	ami=_mm_min_ps(ami,bmi);
+	amx=_mm_max_ps(amx,bmx);
+	_mm_store_ps(r.mi,ami);
+	_mm_store_ps(r.mx,amx);
 #else
-for(int i=0;i<3;++i)
-	{
-	if(a.mi[i]<b.mi[i]) r.mi[i]=a.mi[i]; else r.mi[i]=b.mi[i];
-	if(a.mx[i]>b.mx[i]) r.mx[i]=a.mx[i]; else r.mx[i]=b.mx[i];
+	for(int i=0;i<3;++i)
+	{
+		if(a.mi[i]<b.mi[i]) r.mi[i]=a.mi[i]; else r.mi[i]=b.mi[i];
+		if(a.mx[i]>b.mx[i]) r.mx[i]=a.mx[i]; else r.mx[i]=b.mx[i];
 	}
 #endif
@@ -667,7 +675,7 @@
 //
 DBVT_INLINE bool		NotEqual(	const btDbvtAabbMm& a,
-									const btDbvtAabbMm& b)
-{
-return(	(a.mi.x()!=b.mi.x())||
+								 const btDbvtAabbMm& b)
+{
+	return(	(a.mi.x()!=b.mi.x())||
 		(a.mi.y()!=b.mi.y())||
 		(a.mi.z()!=b.mi.z())||
@@ -684,12 +692,12 @@
 DBVT_PREFIX
 inline void		btDbvt::enumNodes(	const btDbvtNode* root,
-									DBVT_IPOLICY)
-{
-DBVT_CHECKTYPE
-policy.Process(root);
-if(root->isinternal())
-	{
-	enumNodes(root->childs[0],policy);
-	enumNodes(root->childs[1],policy);
+								  DBVT_IPOLICY)
+{
+	DBVT_CHECKTYPE
+		policy.Process(root);
+	if(root->isinternal())
+	{
+		enumNodes(root->childs[0],policy);
+		enumNodes(root->childs[1],policy);
 	}
 }
@@ -698,16 +706,16 @@
 DBVT_PREFIX
 inline void		btDbvt::enumLeaves(	const btDbvtNode* root,
-									DBVT_IPOLICY)
-{
-DBVT_CHECKTYPE
-if(root->isinternal())
-	{
-	enumLeaves(root->childs[0],policy);
-	enumLeaves(root->childs[1],policy);
-	}
-	else
-	{
-	policy.Process(root);
-	}
+								   DBVT_IPOLICY)
+{
+	DBVT_CHECKTYPE
+		if(root->isinternal())
+		{
+			enumLeaves(root->childs[0],policy);
+			enumLeaves(root->childs[1],policy);
+		}
+		else
+		{
+			policy.Process(root);
+		}
 }
 
@@ -715,59 +723,277 @@
 DBVT_PREFIX
 inline void		btDbvt::collideTT(	const btDbvtNode* root0,
-									const btDbvtNode* root1,
-									DBVT_IPOLICY)
-{
-DBVT_CHECKTYPE
-if(root0&&root1)
-	{
-	btAlignedObjectArray<sStkNN>	stack;
-	int								depth=1;
-	int								treshold=DOUBLE_STACKSIZE-4;
-	stack.resize(DOUBLE_STACKSIZE);
-	stack[0]=sStkNN(root0,root1);
-	do	{		
-		sStkNN	p=stack[--depth];
-		if(depth>treshold)
+								  const btDbvtNode* root1,
+								  DBVT_IPOLICY)
+{
+	DBVT_CHECKTYPE
+		if(root0&&root1)
+		{
+			int								depth=1;
+			int								treshold=DOUBLE_STACKSIZE-4;
+			btAlignedObjectArray<sStkNN>	stkStack;
+			stkStack.resize(DOUBLE_STACKSIZE);
+			stkStack[0]=sStkNN(root0,root1);
+			do	{		
+				sStkNN	p=stkStack[--depth];
+				if(depth>treshold)
+				{
+					stkStack.resize(stkStack.size()*2);
+					treshold=stkStack.size()-4;
+				}
+				if(p.a==p.b)
+				{
+					if(p.a->isinternal())
+					{
+						stkStack[depth++]=sStkNN(p.a->childs[0],p.a->childs[0]);
+						stkStack[depth++]=sStkNN(p.a->childs[1],p.a->childs[1]);
+						stkStack[depth++]=sStkNN(p.a->childs[0],p.a->childs[1]);
+					}
+				}
+				else if(Intersect(p.a->volume,p.b->volume))
+				{
+					if(p.a->isinternal())
+					{
+						if(p.b->isinternal())
+						{
+							stkStack[depth++]=sStkNN(p.a->childs[0],p.b->childs[0]);
+							stkStack[depth++]=sStkNN(p.a->childs[1],p.b->childs[0]);
+							stkStack[depth++]=sStkNN(p.a->childs[0],p.b->childs[1]);
+							stkStack[depth++]=sStkNN(p.a->childs[1],p.b->childs[1]);
+						}
+						else
+						{
+							stkStack[depth++]=sStkNN(p.a->childs[0],p.b);
+							stkStack[depth++]=sStkNN(p.a->childs[1],p.b);
+						}
+					}
+					else
+					{
+						if(p.b->isinternal())
+						{
+							stkStack[depth++]=sStkNN(p.a,p.b->childs[0]);
+							stkStack[depth++]=sStkNN(p.a,p.b->childs[1]);
+						}
+						else
+						{
+							policy.Process(p.a,p.b);
+						}
+					}
+				}
+			} while(depth);
+		}
+}
+
+
+
+DBVT_PREFIX
+inline void		btDbvt::collideTTpersistentStack(	const btDbvtNode* root0,
+								  const btDbvtNode* root1,
+								  DBVT_IPOLICY)
+{
+	DBVT_CHECKTYPE
+		if(root0&&root1)
+		{
+			int								depth=1;
+			int								treshold=DOUBLE_STACKSIZE-4;
+			
+			m_stkStack.resize(DOUBLE_STACKSIZE);
+			m_stkStack[0]=sStkNN(root0,root1);
+			do	{		
+				sStkNN	p=m_stkStack[--depth];
+				if(depth>treshold)
+				{
+					m_stkStack.resize(m_stkStack.size()*2);
+					treshold=m_stkStack.size()-4;
+				}
+				if(p.a==p.b)
+				{
+					if(p.a->isinternal())
+					{
+						m_stkStack[depth++]=sStkNN(p.a->childs[0],p.a->childs[0]);
+						m_stkStack[depth++]=sStkNN(p.a->childs[1],p.a->childs[1]);
+						m_stkStack[depth++]=sStkNN(p.a->childs[0],p.a->childs[1]);
+					}
+				}
+				else if(Intersect(p.a->volume,p.b->volume))
+				{
+					if(p.a->isinternal())
+					{
+						if(p.b->isinternal())
+						{
+							m_stkStack[depth++]=sStkNN(p.a->childs[0],p.b->childs[0]);
+							m_stkStack[depth++]=sStkNN(p.a->childs[1],p.b->childs[0]);
+							m_stkStack[depth++]=sStkNN(p.a->childs[0],p.b->childs[1]);
+							m_stkStack[depth++]=sStkNN(p.a->childs[1],p.b->childs[1]);
+						}
+						else
+						{
+							m_stkStack[depth++]=sStkNN(p.a->childs[0],p.b);
+							m_stkStack[depth++]=sStkNN(p.a->childs[1],p.b);
+						}
+					}
+					else
+					{
+						if(p.b->isinternal())
+						{
+							m_stkStack[depth++]=sStkNN(p.a,p.b->childs[0]);
+							m_stkStack[depth++]=sStkNN(p.a,p.b->childs[1]);
+						}
+						else
+						{
+							policy.Process(p.a,p.b);
+						}
+					}
+				}
+			} while(depth);
+		}
+}
+
+
+//
+DBVT_PREFIX
+inline void		btDbvt::collideTT(	const btDbvtNode* root0,
+								  const btDbvtNode* root1,
+								  const btTransform& xform,
+								  DBVT_IPOLICY)
+{
+	DBVT_CHECKTYPE
+		if(root0&&root1)
+		{
+			int								depth=1;
+			int								treshold=DOUBLE_STACKSIZE-4;
+			btAlignedObjectArray<sStkNN>	stkStack;
+			stkStack.resize(DOUBLE_STACKSIZE);
+			stkStack[0]=sStkNN(root0,root1);
+			do	{
+				sStkNN	p=stkStack[--depth];
+				if(Intersect(p.a->volume,p.b->volume,xform))
+				{
+					if(depth>treshold)
+					{
+						stkStack.resize(stkStack.size()*2);
+						treshold=stkStack.size()-4;
+					}
+					if(p.a->isinternal())
+					{
+						if(p.b->isinternal())
+						{					
+							stkStack[depth++]=sStkNN(p.a->childs[0],p.b->childs[0]);
+							stkStack[depth++]=sStkNN(p.a->childs[1],p.b->childs[0]);
+							stkStack[depth++]=sStkNN(p.a->childs[0],p.b->childs[1]);
+							stkStack[depth++]=sStkNN(p.a->childs[1],p.b->childs[1]);
+						}
+						else
+						{
+							stkStack[depth++]=sStkNN(p.a->childs[0],p.b);
+							stkStack[depth++]=sStkNN(p.a->childs[1],p.b);
+						}
+					}
+					else
+					{
+						if(p.b->isinternal())
+						{
+							stkStack[depth++]=sStkNN(p.a,p.b->childs[0]);
+							stkStack[depth++]=sStkNN(p.a,p.b->childs[1]);
+						}
+						else
+						{
+							policy.Process(p.a,p.b);
+						}
+					}
+				}
+			} while(depth);
+		}
+}
+
+//
+DBVT_PREFIX
+inline void		btDbvt::collideTT(	const btDbvtNode* root0,
+								  const btTransform& xform0,
+								  const btDbvtNode* root1,
+								  const btTransform& xform1,
+								  DBVT_IPOLICY)
+{
+	const btTransform	xform=xform0.inverse()*xform1;
+	collideTT(root0,root1,xform,policy);
+}
+
+//
+DBVT_PREFIX
+inline void		btDbvt::collideTV(	const btDbvtNode* root,
+								  const btDbvtVolume& vol,
+								  DBVT_IPOLICY)
+{
+	DBVT_CHECKTYPE
+		if(root)
+		{
+			ATTRIBUTE_ALIGNED16(btDbvtVolume)		volume(vol);
+			btAlignedObjectArray<const btDbvtNode*>	stack;
+			stack.resize(0);
+			stack.reserve(SIMPLE_STACKSIZE);
+			stack.push_back(root);
+			do	{
+				const btDbvtNode*	n=stack[stack.size()-1];
+				stack.pop_back();
+				if(Intersect(n->volume,volume))
+				{
+					if(n->isinternal())
+					{
+						stack.push_back(n->childs[0]);
+						stack.push_back(n->childs[1]);
+					}
+					else
+					{
+						policy.Process(n);
+					}
+				}
+			} while(stack.size()>0);
+		}
+}
+
+DBVT_PREFIX
+inline void		btDbvt::rayTestInternal(	const btDbvtNode* root,
+								const btVector3& rayFrom,
+								const btVector3& rayTo,
+								const btVector3& rayDirectionInverse,
+								unsigned int signs[3],
+								btScalar lambda_max,
+								const btVector3& aabbMin,
+								const btVector3& aabbMax,
+								DBVT_IPOLICY) const
+{
+	DBVT_CHECKTYPE
+	if(root)
+	{
+		btVector3 resultNormal;
+
+		int								depth=1;
+		int								treshold=DOUBLE_STACKSIZE-2;
+		btAlignedObjectArray<const btDbvtNode*>	stack;
+		stack.resize(DOUBLE_STACKSIZE);
+		stack[0]=root;
+		btVector3 bounds[2];
+		do	
+		{
+			const btDbvtNode*	node=stack[--depth];
+			bounds[0] = node->volume.Mins()+aabbMin;
+			bounds[1] = node->volume.Maxs()+aabbMax;
+			btScalar tmin=1.f,lambda_min=0.f;
+			unsigned int result1=false;
+			result1 = btRayAabb2(rayFrom,rayDirectionInverse,signs,bounds,tmin,lambda_min,lambda_max);
+			if(result1)
 			{
-			stack.resize(stack.size()*2);
-			treshold=stack.size()-4;
-			}
-		if(p.a==p.b)
-			{
-			if(p.a->isinternal())
-				{
-				stack[depth++]=sStkNN(p.a->childs[0],p.a->childs[0]);
-				stack[depth++]=sStkNN(p.a->childs[1],p.a->childs[1]);
-				stack[depth++]=sStkNN(p.a->childs[0],p.a->childs[1]);
-				}
-			}
-		else if(Intersect(p.a->volume,p.b->volume))
-			{
-			if(p.a->isinternal())
-				{
-				if(p.b->isinternal())
-					{
-					stack[depth++]=sStkNN(p.a->childs[0],p.b->childs[0]);
-					stack[depth++]=sStkNN(p.a->childs[1],p.b->childs[0]);
-					stack[depth++]=sStkNN(p.a->childs[0],p.b->childs[1]);
-					stack[depth++]=sStkNN(p.a->childs[1],p.b->childs[1]);
-					}
-					else
-					{
-					stack[depth++]=sStkNN(p.a->childs[0],p.b);
-					stack[depth++]=sStkNN(p.a->childs[1],p.b);
-					}
+				if(node->isinternal())
+				{
+					if(depth>treshold)
+					{
+						stack.resize(stack.size()*2);
+						treshold=stack.size()-2;
+					}
+					stack[depth++]=node->childs[0];
+					stack[depth++]=node->childs[1];
 				}
 				else
 				{
-				if(p.b->isinternal())
-					{
-					stack[depth++]=sStkNN(p.a,p.b->childs[0]);
-					stack[depth++]=sStkNN(p.a,p.b->childs[1]);
-					}
-					else
-					{
-					policy.Process(p.a,p.b);
-					}
+					policy.Process(node);
 				}
 			}
@@ -778,139 +1004,69 @@
 //
 DBVT_PREFIX
-inline void		btDbvt::collideTT(	const btDbvtNode* root0,
-									const btDbvtNode* root1,
-									const btTransform& xform,
-									DBVT_IPOLICY)
-{
-DBVT_CHECKTYPE
-if(root0&&root1)
-	{
-	btAlignedObjectArray<sStkNN>	stack;
-	int								depth=1;
-	int								treshold=DOUBLE_STACKSIZE-4;
-	stack.resize(DOUBLE_STACKSIZE);
-	stack[0]=sStkNN(root0,root1);
-	do	{
-		sStkNN	p=stack[--depth];
-		if(Intersect(p.a->volume,p.b->volume,xform))
-			{
-			if(depth>treshold)
-				{
-				stack.resize(stack.size()*2);
-				treshold=stack.size()-4;
-				}
-			if(p.a->isinternal())
-				{
-				if(p.b->isinternal())
-					{					
-					stack[depth++]=sStkNN(p.a->childs[0],p.b->childs[0]);
-					stack[depth++]=sStkNN(p.a->childs[1],p.b->childs[0]);
-					stack[depth++]=sStkNN(p.a->childs[0],p.b->childs[1]);
-					stack[depth++]=sStkNN(p.a->childs[1],p.b->childs[1]);
+inline void		btDbvt::rayTest(	const btDbvtNode* root,
+								const btVector3& rayFrom,
+								const btVector3& rayTo,
+								DBVT_IPOLICY)
+{
+	DBVT_CHECKTYPE
+		if(root)
+		{
+			btVector3 rayDir = (rayTo-rayFrom);
+			rayDir.normalize ();
+
+			///what about division by zero? --> just set rayDirection[i] to INF/1e30
+			btVector3 rayDirectionInverse;
+			rayDirectionInverse[0] = rayDir[0] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[0];
+			rayDirectionInverse[1] = rayDir[1] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[1];
+			rayDirectionInverse[2] = rayDir[2] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[2];
+			unsigned int signs[3] = { rayDirectionInverse[0] < 0.0, rayDirectionInverse[1] < 0.0, rayDirectionInverse[2] < 0.0};
+
+			btScalar lambda_max = rayDir.dot(rayTo-rayFrom);
+
+			btVector3 resultNormal;
+
+			btAlignedObjectArray<const btDbvtNode*>	stack;
+
+			int								depth=1;
+			int								treshold=DOUBLE_STACKSIZE-2;
+
+			stack.resize(DOUBLE_STACKSIZE);
+			stack[0]=root;
+			btVector3 bounds[2];
+			do	{
+				const btDbvtNode*	node=stack[--depth];
+
+				bounds[0] = node->volume.Mins();
+				bounds[1] = node->volume.Maxs();
+				
+				btScalar tmin=1.f,lambda_min=0.f;
+				unsigned int result1 = btRayAabb2(rayFrom,rayDirectionInverse,signs,bounds,tmin,lambda_min,lambda_max);
+
+#ifdef COMPARE_BTRAY_AABB2
+				btScalar param=1.f;
+				bool result2 = btRayAabb(rayFrom,rayTo,node->volume.Mins(),node->volume.Maxs(),param,resultNormal);
+				btAssert(result1 == result2);
+#endif //TEST_BTRAY_AABB2
+
+				if(result1)
+				{
+					if(node->isinternal())
+					{
+						if(depth>treshold)
+						{
+							stack.resize(stack.size()*2);
+							treshold=stack.size()-2;
+						}
+						stack[depth++]=node->childs[0];
+						stack[depth++]=node->childs[1];
 					}
 					else
 					{
-					stack[depth++]=sStkNN(p.a->childs[0],p.b);
-					stack[depth++]=sStkNN(p.a->childs[1],p.b);
-					}
-				}
-				else
-				{
-				if(p.b->isinternal())
-					{
-					stack[depth++]=sStkNN(p.a,p.b->childs[0]);
-					stack[depth++]=sStkNN(p.a,p.b->childs[1]);
-					}
-					else
-					{
-					policy.Process(p.a,p.b);
-					}
-				}
-			}
-		} while(depth);
-	}
-}
-
-//
-DBVT_PREFIX
-inline void		btDbvt::collideTT(	const btDbvtNode* root0,
-									const btTransform& xform0,
-									const btDbvtNode* root1,
-									const btTransform& xform1,
-									DBVT_IPOLICY)
-{
-const btTransform	xform=xform0.inverse()*xform1;
-collideTT(root0,root1,xform,policy);
-}
-
-//
-DBVT_PREFIX
-inline void		btDbvt::collideTV(	const btDbvtNode* root,
-									const btDbvtVolume& vol,
-									DBVT_IPOLICY)
-{
-DBVT_CHECKTYPE
-if(root)
-	{
-	ATTRIBUTE_ALIGNED16(btDbvtVolume)		volume(vol);
-	btAlignedObjectArray<const btDbvtNode*>	stack;
-	stack.reserve(SIMPLE_STACKSIZE);
-	stack.push_back(root);
-	do	{
-		const btDbvtNode*	n=stack[stack.size()-1];
-		stack.pop_back();
-		if(Intersect(n->volume,volume))
-			{
-			if(n->isinternal())
-				{
-				stack.push_back(n->childs[0]);
-				stack.push_back(n->childs[1]);
-				}
-				else
-				{
-				policy.Process(n);
-				}
-			}
-		} while(stack.size()>0);
-	}
-}
-
-//
-DBVT_PREFIX
-inline void		btDbvt::collideRAY(	const btDbvtNode* root,
-									const btVector3& origin,
-									const btVector3& direction,
-									DBVT_IPOLICY)
-{
-DBVT_CHECKTYPE
-if(root)
-	{
-	const btVector3	normal=direction.normalized();
-	const btVector3	invdir(	1/normal.x(),
-							1/normal.y(),
-							1/normal.z());
-	const unsigned	signs[]={	direction.x()<0,
-								direction.y()<0,
-								direction.z()<0};
-	btAlignedObjectArray<const btDbvtNode*>	stack;
-	stack.reserve(SIMPLE_STACKSIZE);
-	stack.push_back(root);
-	do	{
-		const btDbvtNode*	node=stack[stack.size()-1];
-		stack.pop_back();
-		if(Intersect(node->volume,origin,invdir,signs))
-			{
-			if(node->isinternal())
-				{
-				stack.push_back(node->childs[0]);
-				stack.push_back(node->childs[1]);
-				}
-				else
-				{
-				policy.Process(node);
-				}
-			}
-		} while(stack.size());
-	}
+						policy.Process(node);
+					}
+				}
+			} while(depth);
+
+		}
 }
 
@@ -923,49 +1079,49 @@
 									DBVT_IPOLICY)
 {
-DBVT_CHECKTYPE
-if(root)
-	{
-	const int						inside=(1<<count)-1;
-	btAlignedObjectArray<sStkNP>	stack;
-	int								signs[sizeof(unsigned)*8];
-	btAssert(count<int (sizeof(signs)/sizeof(signs[0])));
-	for(int i=0;i<count;++i)
+	DBVT_CHECKTYPE
+		if(root)
 		{
-		signs[i]=	((normals[i].x()>=0)?1:0)+
+			const int						inside=(1<<count)-1;
+			btAlignedObjectArray<sStkNP>	stack;
+			int								signs[sizeof(unsigned)*8];
+			btAssert(count<int (sizeof(signs)/sizeof(signs[0])));
+			for(int i=0;i<count;++i)
+			{
+				signs[i]=	((normals[i].x()>=0)?1:0)+
 					((normals[i].y()>=0)?2:0)+
 					((normals[i].z()>=0)?4:0);
+			}
+			stack.reserve(SIMPLE_STACKSIZE);
+			stack.push_back(sStkNP(root,0));
+			do	{
+				sStkNP	se=stack[stack.size()-1];
+				bool	out=false;
+				stack.pop_back();
+				for(int i=0,j=1;(!out)&&(i<count);++i,j<<=1)
+				{
+					if(0==(se.mask&j))
+					{
+						const int	side=se.node->volume.Classify(normals[i],offsets[i],signs[i]);
+						switch(side)
+						{
+						case	-1:	out=true;break;
+						case	+1:	se.mask|=j;break;
+						}
+					}
+				}
+				if(!out)
+				{
+					if((se.mask!=inside)&&(se.node->isinternal()))
+					{
+						stack.push_back(sStkNP(se.node->childs[0],se.mask));
+						stack.push_back(sStkNP(se.node->childs[1],se.mask));
+					}
+					else
+					{
+						if(policy.AllLeaves(se.node)) enumLeaves(se.node,policy);
+					}
+				}
+			} while(stack.size());
 		}
-	stack.reserve(SIMPLE_STACKSIZE);
-	stack.push_back(sStkNP(root,0));
-	do	{
-		sStkNP	se=stack[stack.size()-1];
-		bool	out=false;
-		stack.pop_back();
-		for(int i=0,j=1;(!out)&&(i<count);++i,j<<=1)
-			{
-			if(0==(se.mask&j))
-				{
-				const int	side=se.node->volume.Classify(normals[i],offsets[i],signs[i]);
-				switch(side)
-					{
-					case	-1:	out=true;break;
-					case	+1:	se.mask|=j;break;
-					}
-				}
-			}
-		if(!out)
-			{
-			if((se.mask!=inside)&&(se.node->isinternal()))
-				{
-				stack.push_back(sStkNP(se.node->childs[0],se.mask));
-				stack.push_back(sStkNP(se.node->childs[1],se.mask));
-				}
-				else
-				{
-				if(policy.AllLeaves(se.node)) enumLeaves(se.node,policy);
-				}
-			}
-		} while(stack.size());
-	}
 }
 
@@ -973,97 +1129,97 @@
 DBVT_PREFIX
 inline void		btDbvt::collideOCL(	const btDbvtNode* root,
-									const btVector3* normals,
-									const btScalar* offsets,
-									const btVector3& sortaxis,
-									int count,
-									DBVT_IPOLICY,
-									bool fsort)
-{
-DBVT_CHECKTYPE
-if(root)
-	{
-	const unsigned					srtsgns=(sortaxis[0]>=0?1:0)+
-											(sortaxis[1]>=0?2:0)+
-											(sortaxis[2]>=0?4:0);
-	const int						inside=(1<<count)-1;
-	btAlignedObjectArray<sStkNPS>	stock;
-	btAlignedObjectArray<int>		ifree;
-	btAlignedObjectArray<int>		stack;
-	int								signs[sizeof(unsigned)*8];
-	btAssert(count<int (sizeof(signs)/sizeof(signs[0])));
-	for(int i=0;i<count;++i)
+								   const btVector3* normals,
+								   const btScalar* offsets,
+								   const btVector3& sortaxis,
+								   int count,
+								   DBVT_IPOLICY,
+								   bool fsort)
+{
+	DBVT_CHECKTYPE
+		if(root)
 		{
-		signs[i]=	((normals[i].x()>=0)?1:0)+
+			const unsigned					srtsgns=(sortaxis[0]>=0?1:0)+
+				(sortaxis[1]>=0?2:0)+
+				(sortaxis[2]>=0?4:0);
+			const int						inside=(1<<count)-1;
+			btAlignedObjectArray<sStkNPS>	stock;
+			btAlignedObjectArray<int>		ifree;
+			btAlignedObjectArray<int>		stack;
+			int								signs[sizeof(unsigned)*8];
+			btAssert(count<int (sizeof(signs)/sizeof(signs[0])));
+			for(int i=0;i<count;++i)
+			{
+				signs[i]=	((normals[i].x()>=0)?1:0)+
 					((normals[i].y()>=0)?2:0)+
 					((normals[i].z()>=0)?4:0);
+			}
+			stock.reserve(SIMPLE_STACKSIZE);
+			stack.reserve(SIMPLE_STACKSIZE);
+			ifree.reserve(SIMPLE_STACKSIZE);
+			stack.push_back(allocate(ifree,stock,sStkNPS(root,0,root->volume.ProjectMinimum(sortaxis,srtsgns))));
+			do	{
+				const int	id=stack[stack.size()-1];
+				sStkNPS		se=stock[id];
+				stack.pop_back();ifree.push_back(id);
+				if(se.mask!=inside)
+				{
+					bool	out=false;
+					for(int i=0,j=1;(!out)&&(i<count);++i,j<<=1)
+					{
+						if(0==(se.mask&j))
+						{
+							const int	side=se.node->volume.Classify(normals[i],offsets[i],signs[i]);
+							switch(side)
+							{
+							case	-1:	out=true;break;
+							case	+1:	se.mask|=j;break;
+							}
+						}
+					}
+					if(out) continue;
+				}
+				if(policy.Descent(se.node))
+				{
+					if(se.node->isinternal())
+					{
+						const btDbvtNode* pns[]={	se.node->childs[0],se.node->childs[1]};
+						sStkNPS		nes[]={	sStkNPS(pns[0],se.mask,pns[0]->volume.ProjectMinimum(sortaxis,srtsgns)),
+							sStkNPS(pns[1],se.mask,pns[1]->volume.ProjectMinimum(sortaxis,srtsgns))};
+						const int	q=nes[0].value<nes[1].value?1:0;				
+						int			j=stack.size();
+						if(fsort&&(j>0))
+						{
+							/* Insert 0	*/ 
+							j=nearest(&stack[0],&stock[0],nes[q].value,0,stack.size());
+							stack.push_back(0);
+#if DBVT_USE_MEMMOVE
+							memmove(&stack[j+1],&stack[j],sizeof(int)*(stack.size()-j-1));
+#else
+							for(int k=stack.size()-1;k>j;--k) stack[k]=stack[k-1];
+#endif
+							stack[j]=allocate(ifree,stock,nes[q]);
+							/* Insert 1	*/ 
+							j=nearest(&stack[0],&stock[0],nes[1-q].value,j,stack.size());
+							stack.push_back(0);
+#if DBVT_USE_MEMMOVE
+							memmove(&stack[j+1],&stack[j],sizeof(int)*(stack.size()-j-1));
+#else
+							for(int k=stack.size()-1;k>j;--k) stack[k]=stack[k-1];
+#endif
+							stack[j]=allocate(ifree,stock,nes[1-q]);
+						}
+						else
+						{
+							stack.push_back(allocate(ifree,stock,nes[q]));
+							stack.push_back(allocate(ifree,stock,nes[1-q]));
+						}
+					}
+					else
+					{
+						policy.Process(se.node,se.value);
+					}
+				}
+			} while(stack.size());
 		}
-	stock.reserve(SIMPLE_STACKSIZE);
-	stack.reserve(SIMPLE_STACKSIZE);
-	ifree.reserve(SIMPLE_STACKSIZE);
-	stack.push_back(allocate(ifree,stock,sStkNPS(root,0,root->volume.ProjectMinimum(sortaxis,srtsgns))));
-	do	{
-		const int	id=stack[stack.size()-1];
-		sStkNPS		se=stock[id];
-		stack.pop_back();ifree.push_back(id);
-		if(se.mask!=inside)
-			{
-			bool	out=false;
-			for(int i=0,j=1;(!out)&&(i<count);++i,j<<=1)
-				{
-				if(0==(se.mask&j))
-					{
-					const int	side=se.node->volume.Classify(normals[i],offsets[i],signs[i]);
-					switch(side)
-						{
-						case	-1:	out=true;break;
-						case	+1:	se.mask|=j;break;
-						}
-					}
-				}
-			if(out) continue;
-			}
-		if(policy.Descent(se.node))
-			{
-			if(se.node->isinternal())
-				{
-				const btDbvtNode* pns[]={	se.node->childs[0],se.node->childs[1]};
-				sStkNPS		nes[]={	sStkNPS(pns[0],se.mask,pns[0]->volume.ProjectMinimum(sortaxis,srtsgns)),
-									sStkNPS(pns[1],se.mask,pns[1]->volume.ProjectMinimum(sortaxis,srtsgns))};
-				const int	q=nes[0].value<nes[1].value?1:0;				
-				int			j=stack.size();
-				if(fsort&&(j>0))
-					{
-					/* Insert 0	*/ 
-					j=nearest(&stack[0],&stock[0],nes[q].value,0,stack.size());
-					stack.push_back(0);
-					#if DBVT_USE_MEMMOVE
-					memmove(&stack[j+1],&stack[j],sizeof(int)*(stack.size()-j-1));
-					#else
-					for(int k=stack.size()-1;k>j;--k) stack[k]=stack[k-1];
-					#endif
-					stack[j]=allocate(ifree,stock,nes[q]);
-					/* Insert 1	*/ 
-					j=nearest(&stack[0],&stock[0],nes[1-q].value,j,stack.size());
-					stack.push_back(0);
-					#if DBVT_USE_MEMMOVE
-					memmove(&stack[j+1],&stack[j],sizeof(int)*(stack.size()-j-1));
-					#else
-					for(int k=stack.size()-1;k>j;--k) stack[k]=stack[k-1];
-					#endif
-					stack[j]=allocate(ifree,stock,nes[1-q]);
-					}
-					else
-					{
-					stack.push_back(allocate(ifree,stock,nes[q]));
-					stack.push_back(allocate(ifree,stock,nes[1-q]));
-					}
-				}
-				else
-				{
-				policy.Process(se.node,se.value);
-				}
-			}
-		} while(stack.size());
-	}
 }
 
@@ -1071,24 +1227,24 @@
 DBVT_PREFIX
 inline void		btDbvt::collideTU(	const btDbvtNode* root,
-									DBVT_IPOLICY)
-{
-DBVT_CHECKTYPE
-if(root)
-	{
-	btAlignedObjectArray<const btDbvtNode*>	stack;
-	stack.reserve(SIMPLE_STACKSIZE);
-	stack.push_back(root);
-	do	{
-		const btDbvtNode*	n=stack[stack.size()-1];
-		stack.pop_back();
-		if(policy.Descent(n))
-			{
-			if(n->isinternal())
-				{ stack.push_back(n->childs[0]);stack.push_back(n->childs[1]); }
-				else
-				{ policy.Process(n); }
-			}
-		} while(stack.size()>0);
-	}
+								  DBVT_IPOLICY)
+{
+	DBVT_CHECKTYPE
+		if(root)
+		{
+			btAlignedObjectArray<const btDbvtNode*>	stack;
+			stack.reserve(SIMPLE_STACKSIZE);
+			stack.push_back(root);
+			do	{
+				const btDbvtNode*	n=stack[stack.size()-1];
+				stack.pop_back();
+				if(policy.Descent(n))
+				{
+					if(n->isinternal())
+					{ stack.push_back(n->childs[0]);stack.push_back(n->childs[1]); }
+					else
+					{ policy.Process(n); }
+				}
+			} while(stack.size()>0);
+		}
 }
 
Index: code/branches/physics/src/bullet/BulletCollision/BroadphaseCollision/btDbvtBroadphase.cpp
===================================================================
--- code/branches/physics/src/bullet/BulletCollision/BroadphaseCollision/btDbvtBroadphase.cpp	(revision 2192)
+++ code/branches/physics/src/bullet/BulletCollision/BroadphaseCollision/btDbvtBroadphase.cpp	(revision 2430)
@@ -27,17 +27,17 @@
 #if DBVT_BP_PROFILE
 struct	ProfileScope
-	{
+{
 	__forceinline ProfileScope(btClock& clock,unsigned long& value) :
-		m_clock(&clock),m_value(&value),m_base(clock.getTimeMicroseconds())
-		{
-		}
+	m_clock(&clock),m_value(&value),m_base(clock.getTimeMicroseconds())
+	{
+	}
 	__forceinline ~ProfileScope()
-		{
+	{
 		(*m_value)+=m_clock->getTimeMicroseconds()-m_base;
-		}
+	}
 	btClock*		m_clock;
 	unsigned long*	m_value;
 	unsigned long	m_base;
-	};
+};
 #define	SPC(_value_)	ProfileScope	spc_scope(m_clock,_value_)
 #else
@@ -53,8 +53,8 @@
 static inline void	listappend(T* item,T*& list)
 {
-item->links[0]=0;
-item->links[1]=list;
-if(list) list->links[0]=item;
-list=item;
+	item->links[0]=0;
+	item->links[1]=list;
+	if(list) list->links[0]=item;
+	list=item;
 }
 
@@ -63,6 +63,6 @@
 static inline void	listremove(T* item,T*& list)
 {
-if(item->links[0]) item->links[0]->links[1]=item->links[1]; else list=item->links[1];
-if(item->links[1]) item->links[1]->links[0]=item->links[0];
+	if(item->links[0]) item->links[0]->links[1]=item->links[1]; else list=item->links[1];
+	if(item->links[1]) item->links[1]->links[0]=item->links[0];
 }
 
@@ -71,7 +71,7 @@
 static inline int	listcount(T* root)
 {
-int	n=0;
-while(root) { ++n;root=root->links[1]; }
-return(n);
+	int	n=0;
+	while(root) { ++n;root=root->links[1]; }
+	return(n);
 }
 
@@ -80,6 +80,6 @@
 static inline void	clear(T& value)
 {
-static const struct ZeroDummy : T {} zerodummy;
-value=zerodummy;
+	static const struct ZeroDummy : T {} zerodummy;
+	value=zerodummy;
 }
 
@@ -91,23 +91,23 @@
 struct	btDbvtTreeCollider : btDbvt::ICollide
 {
-btDbvtBroadphase*	pbp;
-btDbvtProxy*		proxy;
-		btDbvtTreeCollider(btDbvtBroadphase* p) : pbp(p) {}
-void	Process(const btDbvtNode* na,const btDbvtNode* nb)
-	{
-	if(na!=nb)
-		{
-		btDbvtProxy*	pa=(btDbvtProxy*)na->data;
-		btDbvtProxy*	pb=(btDbvtProxy*)nb->data;
-		#if DBVT_BP_SORTPAIRS
-		if(pa>pb) btSwap(pa,pb);
-		#endif
-		pbp->m_paircache->addOverlappingPair(pa,pb);
-		++pbp->m_newpairs;
-		}
-	}
-void	Process(const btDbvtNode* n)
-	{
-	Process(n,proxy->leaf);
+	btDbvtBroadphase*	pbp;
+	btDbvtProxy*		proxy;
+	btDbvtTreeCollider(btDbvtBroadphase* p) : pbp(p) {}
+	void	Process(const btDbvtNode* na,const btDbvtNode* nb)
+	{
+		if(na!=nb)
+		{
+			btDbvtProxy*	pa=(btDbvtProxy*)na->data;
+			btDbvtProxy*	pb=(btDbvtProxy*)nb->data;
+#if DBVT_BP_SORTPAIRS
+			if(pa>pb) btSwap(pa,pb);
+#endif
+			pbp->m_paircache->addOverlappingPair(pa,pb);
+			++pbp->m_newpairs;
+		}
+	}
+	void	Process(const btDbvtNode* n)
+	{
+		Process(n,proxy->leaf);
 	}
 };
@@ -120,29 +120,29 @@
 btDbvtBroadphase::btDbvtBroadphase(btOverlappingPairCache* paircache)
 {
-m_deferedcollide	=	false;
-m_needcleanup		=	true;
-m_releasepaircache	=	(paircache!=0)?false:true;
-m_prediction		=	1/(btScalar)2;
-m_stageCurrent		=	0;
-m_fixedleft			=	0;
-m_fupdates			=	1;
-m_dupdates			=	0;
-m_cupdates			=	10;
-m_newpairs			=	1;
-m_updates_call		=	0;
-m_updates_done		=	0;
-m_updates_ratio		=	0;
-m_paircache			=	paircache?
-						paircache	:
-						new(btAlignedAlloc(sizeof(btHashedOverlappingPairCache),16)) btHashedOverlappingPairCache();
-m_gid				=	0;
-m_pid				=	0;
-m_cid				=	0;
-for(int i=0;i<=STAGECOUNT;++i)
-	{
-	m_stageRoots[i]=0;
+	m_deferedcollide	=	false;
+	m_needcleanup		=	true;
+	m_releasepaircache	=	(paircache!=0)?false:true;
+	m_prediction		=	1/(btScalar)2;
+	m_stageCurrent		=	0;
+	m_fixedleft			=	0;
+	m_fupdates			=	1;
+	m_dupdates			=	0;
+	m_cupdates			=	10;
+	m_newpairs			=	1;
+	m_updates_call		=	0;
+	m_updates_done		=	0;
+	m_updates_ratio		=	0;
+	m_paircache			=	paircache?
+paircache	:
+	new(btAlignedAlloc(sizeof(btHashedOverlappingPairCache),16)) btHashedOverlappingPairCache();
+	m_gid				=	0;
+	m_pid				=	0;
+	m_cid				=	0;
+	for(int i=0;i<=STAGECOUNT;++i)
+	{
+		m_stageRoots[i]=0;
 	}
 #if DBVT_BP_PROFILE
-clear(m_profiling);
+	clear(m_profiling);
 #endif
 }
@@ -151,114 +151,167 @@
 btDbvtBroadphase::~btDbvtBroadphase()
 {
-if(m_releasepaircache) 
-{
-	m_paircache->~btOverlappingPairCache();
-	btAlignedFree(m_paircache);
-}
+	if(m_releasepaircache) 
+	{
+		m_paircache->~btOverlappingPairCache();
+		btAlignedFree(m_paircache);
+	}
 }
 
 //
 btBroadphaseProxy*				btDbvtBroadphase::createProxy(	const btVector3& aabbMin,
-																const btVector3& aabbMax,
-																int /*shapeType*/,
-																void* userPtr,
-																short int collisionFilterGroup,
-																short int collisionFilterMask,
-																btDispatcher* /*dispatcher*/,
-																void* /*multiSapProxy*/)
-{
-btDbvtProxy*		proxy=new(btAlignedAlloc(sizeof(btDbvtProxy),16)) btDbvtProxy(	userPtr,
-																					collisionFilterGroup,
-																					collisionFilterMask);
-proxy->aabb			=	btDbvtVolume::FromMM(aabbMin,aabbMax);
-proxy->stage		=	m_stageCurrent;
-proxy->m_uniqueId	=	++m_gid;
-proxy->leaf			=	m_sets[0].insert(proxy->aabb,proxy);
-listappend(proxy,m_stageRoots[m_stageCurrent]);
-if(!m_deferedcollide)
-	{
-	btDbvtTreeCollider	collider(this);
-	collider.proxy=proxy;
-	btDbvt::collideTV(m_sets[0].m_root,proxy->aabb,collider);
-	btDbvt::collideTV(m_sets[1].m_root,proxy->aabb,collider);
-	}
-return(proxy);
+															  const btVector3& aabbMax,
+															  int /*shapeType*/,
+															  void* userPtr,
+															  short int collisionFilterGroup,
+															  short int collisionFilterMask,
+															  btDispatcher* /*dispatcher*/,
+															  void* /*multiSapProxy*/)
+{
+	btDbvtProxy*		proxy=new(btAlignedAlloc(sizeof(btDbvtProxy),16)) btDbvtProxy(	aabbMin,aabbMax,userPtr,
+		collisionFilterGroup,
+		collisionFilterMask);
+
+	btDbvtAabbMm aabb = btDbvtVolume::FromMM(aabbMin,aabbMax);
+
+	//bproxy->aabb			=	btDbvtVolume::FromMM(aabbMin,aabbMax);
+	proxy->stage		=	m_stageCurrent;
+	proxy->m_uniqueId	=	++m_gid;
+	proxy->leaf			=	m_sets[0].insert(aabb,proxy);
+	listappend(proxy,m_stageRoots[m_stageCurrent]);
+	if(!m_deferedcollide)
+	{
+		btDbvtTreeCollider	collider(this);
+		collider.proxy=proxy;
+		m_sets[0].collideTV(m_sets[0].m_root,aabb,collider);
+		m_sets[1].collideTV(m_sets[1].m_root,aabb,collider);
+	}
+	return(proxy);
 }
 
 //
 void							btDbvtBroadphase::destroyProxy(	btBroadphaseProxy* absproxy,
-																btDispatcher* dispatcher)
-{
-btDbvtProxy*	proxy=(btDbvtProxy*)absproxy;
-if(proxy->stage==STAGECOUNT)
-	m_sets[1].remove(proxy->leaf);
+															   btDispatcher* dispatcher)
+{
+	btDbvtProxy*	proxy=(btDbvtProxy*)absproxy;
+	if(proxy->stage==STAGECOUNT)
+		m_sets[1].remove(proxy->leaf);
 	else
-	m_sets[0].remove(proxy->leaf);
-listremove(proxy,m_stageRoots[proxy->stage]);
-m_paircache->removeOverlappingPairsContainingProxy(proxy,dispatcher);
-btAlignedFree(proxy);
-m_needcleanup=true;
+		m_sets[0].remove(proxy->leaf);
+	listremove(proxy,m_stageRoots[proxy->stage]);
+	m_paircache->removeOverlappingPairsContainingProxy(proxy,dispatcher);
+	btAlignedFree(proxy);
+	m_needcleanup=true;
+}
+
+void	btDbvtBroadphase::getAabb(btBroadphaseProxy* absproxy,btVector3& aabbMin, btVector3& aabbMax ) const
+{
+	btDbvtProxy*						proxy=(btDbvtProxy*)absproxy;
+	aabbMin = proxy->m_aabbMin;
+	aabbMax = proxy->m_aabbMax;
+}
+
+void	btDbvtBroadphase::rayTest(const btVector3& rayFrom,const btVector3& rayTo, btBroadphaseRayCallback& rayCallback,const btVector3& aabbMin,const btVector3& aabbMax)
+{
+
+	struct	BroadphaseRayTester : btDbvt::ICollide
+	{
+		btBroadphaseRayCallback& m_rayCallback;
+		BroadphaseRayTester(btBroadphaseRayCallback& orgCallback)
+			:m_rayCallback(orgCallback)
+		{
+		}
+		void					Process(const btDbvtNode* leaf)
+		{
+			btDbvtProxy*	proxy=(btDbvtProxy*)leaf->data;
+			m_rayCallback.process(proxy);
+		}
+	};	
+
+	BroadphaseRayTester callback(rayCallback);
+
+	m_sets[0].rayTestInternal(	m_sets[0].m_root,
+		rayFrom,
+		rayTo,
+		rayCallback.m_rayDirectionInverse,
+		rayCallback.m_signs,
+		rayCallback.m_lambda_max,
+		aabbMin,
+		aabbMax,
+		callback);
+
+	m_sets[1].rayTestInternal(	m_sets[1].m_root,
+		rayFrom,
+		rayTo,
+		rayCallback.m_rayDirectionInverse,
+		rayCallback.m_signs,
+		rayCallback.m_lambda_max,
+		aabbMin,
+		aabbMax,
+		callback);
+
 }
 
 //
 void							btDbvtBroadphase::setAabb(		btBroadphaseProxy* absproxy,
-																const btVector3& aabbMin,
-																const btVector3& aabbMax,
-																btDispatcher* /*dispatcher*/)
-{
-btDbvtProxy*						proxy=(btDbvtProxy*)absproxy;
-ATTRIBUTE_ALIGNED16(btDbvtVolume)	aabb=btDbvtVolume::FromMM(aabbMin,aabbMax);
+														  const btVector3& aabbMin,
+														  const btVector3& aabbMax,
+														  btDispatcher* /*dispatcher*/)
+{
+	btDbvtProxy*						proxy=(btDbvtProxy*)absproxy;
+	ATTRIBUTE_ALIGNED16(btDbvtVolume)	aabb=btDbvtVolume::FromMM(aabbMin,aabbMax);
 #if DBVT_BP_PREVENTFALSEUPDATE
-if(NotEqual(aabb,proxy->leaf->volume))
-#endif
-	{
-	bool	docollide=false;
-	if(proxy->stage==STAGECOUNT)
+	if(NotEqual(aabb,proxy->leaf->volume))
+#endif
+	{
+		bool	docollide=false;
+		if(proxy->stage==STAGECOUNT)
 		{/* fixed -> dynamic set	*/ 
-		m_sets[1].remove(proxy->leaf);
-		proxy->leaf=m_sets[0].insert(aabb,proxy);
-		docollide=true;
+			m_sets[1].remove(proxy->leaf);
+			proxy->leaf=m_sets[0].insert(aabb,proxy);
+			docollide=true;
 		}
 		else
 		{/* dynamic set				*/ 
-		++m_updates_call;
-		if(Intersect(proxy->leaf->volume,aabb))
+			++m_updates_call;
+			if(Intersect(proxy->leaf->volume,aabb))
 			{/* Moving				*/ 
-			const btVector3	delta=aabbMin-proxy->aabb.Mins();
-			btVector3		velocity(aabb.Extents()*m_prediction);
-			if(delta[0]<0) velocity[0]=-velocity[0];
-			if(delta[1]<0) velocity[1]=-velocity[1];
-			if(delta[2]<0) velocity[2]=-velocity[2];
-			if	(
-				#ifdef DBVT_BP_MARGIN				
-				m_sets[0].update(proxy->leaf,aabb,velocity,DBVT_BP_MARGIN)
-				#else
-				m_sets[0].update(proxy->leaf,aabb,velocity)
-				#endif
-				)
+
+				const btVector3	delta=aabbMin-proxy->m_aabbMin;
+				btVector3		velocity(((proxy->m_aabbMax-proxy->m_aabbMin)/2)*m_prediction);
+				if(delta[0]<0) velocity[0]=-velocity[0];
+				if(delta[1]<0) velocity[1]=-velocity[1];
+				if(delta[2]<0) velocity[2]=-velocity[2];
+				if	(
+#ifdef DBVT_BP_MARGIN				
+					m_sets[0].update(proxy->leaf,aabb,velocity,DBVT_BP_MARGIN)
+#else
+					m_sets[0].update(proxy->leaf,aabb,velocity)
+#endif
+					)
 				{
-				++m_updates_done;
-				docollide=true;
+					++m_updates_done;
+					docollide=true;
 				}
 			}
 			else
 			{/* Teleporting			*/ 
-			m_sets[0].update(proxy->leaf,aabb);
-			++m_updates_done;
-			docollide=true;
+				m_sets[0].update(proxy->leaf,aabb);
+				++m_updates_done;
+				docollide=true;
 			}	
 		}
-	listremove(proxy,m_stageRoots[proxy->stage]);
-	proxy->aabb		=	aabb;
-	proxy->stage	=	m_stageCurrent;
-	listappend(proxy,m_stageRoots[m_stageCurrent]);
-	if(docollide)
-		{
-		m_needcleanup=true;
-		if(!m_deferedcollide)
+		listremove(proxy,m_stageRoots[proxy->stage]);
+		proxy->m_aabbMin = aabbMin;
+		proxy->m_aabbMax = aabbMax;
+		proxy->stage	=	m_stageCurrent;
+		listappend(proxy,m_stageRoots[m_stageCurrent]);
+		if(docollide)
+		{
+			m_needcleanup=true;
+			if(!m_deferedcollide)
 			{
-			btDbvtTreeCollider	collider(this);
-			btDbvt::collideTT(m_sets[1].m_root,proxy->leaf,collider);
-			btDbvt::collideTT(m_sets[0].m_root,proxy->leaf,collider);
+				btDbvtTreeCollider	collider(this);
+				m_sets[1].collideTTpersistentStack(m_sets[1].m_root,proxy->leaf,collider);
+				m_sets[0].collideTTpersistentStack(m_sets[0].m_root,proxy->leaf,collider);
 			}
 		}	
@@ -269,22 +322,22 @@
 void							btDbvtBroadphase::calculateOverlappingPairs(btDispatcher* dispatcher)
 {
-collide(dispatcher);
+	collide(dispatcher);
 #if DBVT_BP_PROFILE
-if(0==(m_pid%DBVT_BP_PROFILING_RATE))
+	if(0==(m_pid%DBVT_BP_PROFILING_RATE))
 	{	
-	printf("fixed(%u) dynamics(%u) pairs(%u)\r\n",m_sets[1].m_leaves,m_sets[0].m_leaves,m_paircache->getNumOverlappingPairs());
-	unsigned int	total=m_profiling.m_total;
-	if(total<=0) total=1;
-	printf("ddcollide: %u%% (%uus)\r\n",(50+m_profiling.m_ddcollide*100)/total,m_profiling.m_ddcollide/DBVT_BP_PROFILING_RATE);
-	printf("fdcollide: %u%% (%uus)\r\n",(50+m_profiling.m_fdcollide*100)/total,m_profiling.m_fdcollide/DBVT_BP_PROFILING_RATE);
-	printf("cleanup:   %u%% (%uus)\r\n",(50+m_profiling.m_cleanup*100)/total,m_profiling.m_cleanup/DBVT_BP_PROFILING_RATE);
-	printf("total:     %uus\r\n",total/DBVT_BP_PROFILING_RATE);
-	const unsigned long	sum=m_profiling.m_ddcollide+
-							m_profiling.m_fdcollide+
-							m_profiling.m_cleanup;
-	printf("leaked: %u%% (%uus)\r\n",100-((50+sum*100)/total),(total-sum)/DBVT_BP_PROFILING_RATE);
-	printf("job counts: %u%%\r\n",(m_profiling.m_jobcount*100)/((m_sets[0].m_leaves+m_sets[1].m_leaves)*DBVT_BP_PROFILING_RATE));
-	clear(m_profiling);
-	m_clock.reset();
+		printf("fixed(%u) dynamics(%u) pairs(%u)\r\n",m_sets[1].m_leaves,m_sets[0].m_leaves,m_paircache->getNumOverlappingPairs());
+		unsigned int	total=m_profiling.m_total;
+		if(total<=0) total=1;
+		printf("ddcollide: %u%% (%uus)\r\n",(50+m_profiling.m_ddcollide*100)/total,m_profiling.m_ddcollide/DBVT_BP_PROFILING_RATE);
+		printf("fdcollide: %u%% (%uus)\r\n",(50+m_profiling.m_fdcollide*100)/total,m_profiling.m_fdcollide/DBVT_BP_PROFILING_RATE);
+		printf("cleanup:   %u%% (%uus)\r\n",(50+m_profiling.m_cleanup*100)/total,m_profiling.m_cleanup/DBVT_BP_PROFILING_RATE);
+		printf("total:     %uus\r\n",total/DBVT_BP_PROFILING_RATE);
+		const unsigned long	sum=m_profiling.m_ddcollide+
+			m_profiling.m_fdcollide+
+			m_profiling.m_cleanup;
+		printf("leaked: %u%% (%uus)\r\n",100-((50+sum*100)/total),(total-sum)/DBVT_BP_PROFILING_RATE);
+		printf("job counts: %u%%\r\n",(m_profiling.m_jobcount*100)/((m_sets[0].m_leaves+m_sets[1].m_leaves)*DBVT_BP_PROFILING_RATE));
+		clear(m_profiling);
+		m_clock.reset();
 	}
 #endif
@@ -294,86 +347,87 @@
 void							btDbvtBroadphase::collide(btDispatcher* dispatcher)
 {
-SPC(m_profiling.m_total);
-/* optimize				*/ 
-m_sets[0].optimizeIncremental(1+(m_sets[0].m_leaves*m_dupdates)/100);
-if(m_fixedleft)
-	{
-	const int count=1+(m_sets[1].m_leaves*m_fupdates)/100;
-	m_sets[1].optimizeIncremental(1+(m_sets[1].m_leaves*m_fupdates)/100);
-	m_fixedleft=btMax<int>(0,m_fixedleft-count);
-	}
-/* dynamic -> fixed set	*/ 
-m_stageCurrent=(m_stageCurrent+1)%STAGECOUNT;
-btDbvtProxy*	current=m_stageRoots[m_stageCurrent];
-if(current)
-	{
-	btDbvtTreeCollider	collider(this);
-	do	{
-		btDbvtProxy*	next=current->links[1];
-		listremove(current,m_stageRoots[current->stage]);
-		listappend(current,m_stageRoots[STAGECOUNT]);
-		#if DBVT_BP_ACCURATESLEEPING
-		m_paircache->removeOverlappingPairsContainingProxy(current,dispatcher);
-		collider.proxy=current;
-		btDbvt::collideTV(m_sets[0].m_root,current->aabb,collider);
-		btDbvt::collideTV(m_sets[1].m_root,current->aabb,collider);
-		#endif
-		m_sets[0].remove(current->leaf);
-		current->leaf	=	m_sets[1].insert(current->aabb,current);
-		current->stage	=	STAGECOUNT;	
-		current			=	next;
+	SPC(m_profiling.m_total);
+	/* optimize				*/ 
+	m_sets[0].optimizeIncremental(1+(m_sets[0].m_leaves*m_dupdates)/100);
+	if(m_fixedleft)
+	{
+		const int count=1+(m_sets[1].m_leaves*m_fupdates)/100;
+		m_sets[1].optimizeIncremental(1+(m_sets[1].m_leaves*m_fupdates)/100);
+		m_fixedleft=btMax<int>(0,m_fixedleft-count);
+	}
+	/* dynamic -> fixed set	*/ 
+	m_stageCurrent=(m_stageCurrent+1)%STAGECOUNT;
+	btDbvtProxy*	current=m_stageRoots[m_stageCurrent];
+	if(current)
+	{
+		btDbvtTreeCollider	collider(this);
+		do	{
+			btDbvtProxy*	next=current->links[1];
+			listremove(current,m_stageRoots[current->stage]);
+			listappend(current,m_stageRoots[STAGECOUNT]);
+#if DBVT_BP_ACCURATESLEEPING
+			m_paircache->removeOverlappingPairsContainingProxy(current,dispatcher);
+			collider.proxy=current;
+			btDbvt::collideTV(m_sets[0].m_root,current->aabb,collider);
+			btDbvt::collideTV(m_sets[1].m_root,current->aabb,collider);
+#endif
+			m_sets[0].remove(current->leaf);
+			ATTRIBUTE_ALIGNED16(btDbvtVolume)	curAabb=btDbvtVolume::FromMM(current->m_aabbMin,current->m_aabbMax);
+			current->leaf	=	m_sets[1].insert(curAabb,current);
+			current->stage	=	STAGECOUNT;	
+			current			=	next;
 		} while(current);
-	m_fixedleft=m_sets[1].m_leaves;
-	m_needcleanup=true;
-	}
-/* collide dynamics		*/ 
-	{
-	btDbvtTreeCollider	collider(this);
-	if(m_deferedcollide)
-		{
-		SPC(m_profiling.m_fdcollide);
-		btDbvt::collideTT(m_sets[0].m_root,m_sets[1].m_root,collider);
-		}
-	if(m_deferedcollide)
-		{
-		SPC(m_profiling.m_ddcollide);
-		btDbvt::collideTT(m_sets[0].m_root,m_sets[0].m_root,collider);
-		}
-	}
-/* clean up				*/ 
-if(m_needcleanup)
-	{
-	SPC(m_profiling.m_cleanup);
-	btBroadphasePairArray&	pairs=m_paircache->getOverlappingPairArray();
-	if(pairs.size()>0)
-		{
-		const int	ci=pairs.size();
-		int			ni=btMin(ci,btMax<int>(m_newpairs,(ci*m_cupdates)/100));
-		for(int i=0;i<ni;++i)
+		m_fixedleft=m_sets[1].m_leaves;
+		m_needcleanup=true;
+	}
+	/* collide dynamics		*/ 
+	{
+		btDbvtTreeCollider	collider(this);
+		if(m_deferedcollide)
+		{
+			SPC(m_profiling.m_fdcollide);
+			m_sets[0].collideTTpersistentStack(m_sets[0].m_root,m_sets[1].m_root,collider);
+		}
+		if(m_deferedcollide)
+		{
+			SPC(m_profiling.m_ddcollide);
+			m_sets[0].collideTTpersistentStack(m_sets[0].m_root,m_sets[0].m_root,collider);
+		}
+	}
+	/* clean up				*/ 
+	if(m_needcleanup)
+	{
+		SPC(m_profiling.m_cleanup);
+		btBroadphasePairArray&	pairs=m_paircache->getOverlappingPairArray();
+		if(pairs.size()>0)
+		{
+			const int	ci=pairs.size();
+			int			ni=btMin(ci,btMax<int>(m_newpairs,(ci*m_cupdates)/100));
+			for(int i=0;i<ni;++i)
 			{
-			btBroadphasePair&	p=pairs[(m_cid+i)%ci];
-			btDbvtProxy*		pa=(btDbvtProxy*)p.m_pProxy0;
-			btDbvtProxy*		pb=(btDbvtProxy*)p.m_pProxy1;
-			if(!Intersect(pa->leaf->volume,pb->leaf->volume))
+				btBroadphasePair&	p=pairs[(m_cid+i)%ci];
+				btDbvtProxy*		pa=(btDbvtProxy*)p.m_pProxy0;
+				btDbvtProxy*		pb=(btDbvtProxy*)p.m_pProxy1;
+				if(!Intersect(pa->leaf->volume,pb->leaf->volume))
 				{
-				#if DBVT_BP_SORTPAIRS
-				if(pa>pb) btSwap(pa,pb);
-				#endif
-				m_paircache->removeOverlappingPair(pa,pb,dispatcher);
-				--ni;--i;
+#if DBVT_BP_SORTPAIRS
+					if(pa>pb) btSwap(pa,pb);
+#endif
+					m_paircache->removeOverlappingPair(pa,pb,dispatcher);
+					--ni;--i;
 				}
 			}
-		if(pairs.size()>0) m_cid=(m_cid+ni)%pairs.size(); else m_cid=0;
-		}
-	}
-++m_pid;
-m_newpairs=1;
-m_needcleanup=false;
-if(m_updates_call>0)
+			if(pairs.size()>0) m_cid=(m_cid+ni)%pairs.size(); else m_cid=0;
+		}
+	}
+	++m_pid;
+	m_newpairs=1;
+	m_needcleanup=false;
+	if(m_updates_call>0)
 	{ m_updates_ratio=m_updates_done/(btScalar)m_updates_call; }
 	else
 	{ m_updates_ratio=0; }
-m_updates_done/=2;
-m_updates_call/=2;
+	m_updates_done/=2;
+	m_updates_call/=2;
 }
 
@@ -381,6 +435,6 @@
 void							btDbvtBroadphase::optimize()
 {
-m_sets[0].optimizeTopDown();
-m_sets[1].optimizeTopDown();
+	m_sets[0].optimizeTopDown();
+	m_sets[1].optimizeTopDown();
 }
 
@@ -388,5 +442,5 @@
 btOverlappingPairCache*			btDbvtBroadphase::getOverlappingPairCache()
 {
-return(m_paircache);
+	return(m_paircache);
 }
 
@@ -394,5 +448,5 @@
 const btOverlappingPairCache*	btDbvtBroadphase::getOverlappingPairCache() const
 {
-return(m_paircache);
+	return(m_paircache);
 }
 
@@ -403,14 +457,14 @@
 	ATTRIBUTE_ALIGNED16(btDbvtVolume)	bounds;
 
-if(!m_sets[0].empty())
-	if(!m_sets[1].empty())	Merge(	m_sets[0].m_root->volume,
-									m_sets[1].m_root->volume,bounds);
-							else
-							bounds=m_sets[0].m_root->volume;
-else if(!m_sets[1].empty())	bounds=m_sets[1].m_root->volume;
-							else
-							bounds=btDbvtVolume::FromCR(btVector3(0,0,0),0);
-aabbMin=bounds.Mins();
-aabbMax=bounds.Maxs();
+	if(!m_sets[0].empty())
+		if(!m_sets[1].empty())	Merge(	m_sets[0].m_root->volume,
+			m_sets[1].m_root->volume,bounds);
+		else
+			bounds=m_sets[0].m_root->volume;
+	else if(!m_sets[1].empty())	bounds=m_sets[1].m_root->volume;
+	else
+		bounds=btDbvtVolume::FromCR(btVector3(0,0,0),0);
+	aabbMin=bounds.Mins();
+	aabbMax=bounds.Maxs();
 }
 
@@ -423,7 +477,7 @@
 
 struct	btBroadphaseBenchmark
-	{
+{
 	struct	Experiment
-		{
+	{
 		const char*			name;
 		int					object_count;
@@ -433,7 +487,7 @@
 		btScalar			speed;
 		btScalar			amplitude;
-		};
+	};
 	struct	Object
-		{
+	{
 		btVector3			center;
 		btVector3			extents;
@@ -441,18 +495,18 @@
 		btScalar			time;
 		void				update(btScalar speed,btScalar amplitude,btBroadphaseInterface* pbi)
-			{
+		{
 			time		+=	speed;
 			center[0]	=	btCos(time*(btScalar)2.17)*amplitude+
-							btSin(time)*amplitude/2;
+				btSin(time)*amplitude/2;
 			center[1]	=	btCos(time*(btScalar)1.38)*amplitude+
-							btSin(time)*amplitude;
+				btSin(time)*amplitude;
 			center[2]	=	btSin(time*(btScalar)0.777)*amplitude;
 			pbi->setAabb(proxy,center-extents,center+extents,0);
-			}
-		};
+		}
+	};
 	static int		UnsignedRand(int range=RAND_MAX-1)	{ return(rand()%(range+1)); }
 	static btScalar	UnitRand()							{ return(UnsignedRand(16384)/(btScalar)16384); }
 	static void		OutputTime(const char* name,btClock& c,unsigned count=0)
-		{
+	{
 		const unsigned long	us=c.getTimeMicroseconds();
 		const unsigned long	ms=(us+500)/1000;
@@ -460,80 +514,80 @@
 		if(count>0)
 			printf("%s : %u us (%u ms), %.2f/s\r\n",name,us,ms,count/sec);
-			else
+		else
 			printf("%s : %u us (%u ms)\r\n",name,us,ms);
-		}
+	}
+};
+
+void							btDbvtBroadphase::benchmark(btBroadphaseInterface* pbi)
+{
+	static const btBroadphaseBenchmark::Experiment		experiments[]=
+	{
+		{"1024o.10%",1024,10,0,8192,(btScalar)0.005,(btScalar)100},
+		/*{"4096o.10%",4096,10,0,8192,(btScalar)0.005,(btScalar)100},
+		{"8192o.10%",8192,10,0,8192,(btScalar)0.005,(btScalar)100},*/
 	};
-
-void							btDbvtBroadphase::benchmark(btBroadphaseInterface* pbi)
-{
-static const btBroadphaseBenchmark::Experiment		experiments[]=
-	{
-	{"1024o.10%",1024,10,0,8192,(btScalar)0.005,(btScalar)100},
-	/*{"4096o.10%",4096,10,0,8192,(btScalar)0.005,(btScalar)100},
-	{"8192o.10%",8192,10,0,8192,(btScalar)0.005,(btScalar)100},*/
-	};
-static const int										nexperiments=sizeof(experiments)/sizeof(experiments[0]);
-btAlignedObjectArray<btBroadphaseBenchmark::Object*>	objects;
-btClock													wallclock;
-/* Begin			*/ 
-for(int iexp=0;iexp<nexperiments;++iexp)
-	{
-	const btBroadphaseBenchmark::Experiment&	experiment=experiments[iexp];
-	const int									object_count=experiment.object_count;
-	const int									update_count=(object_count*experiment.update_count)/100;
-	const int									spawn_count=(object_count*experiment.spawn_count)/100;
-	const btScalar								speed=experiment.speed;	
-	const btScalar								amplitude=experiment.amplitude;
-	printf("Experiment #%u '%s':\r\n",iexp,experiment.name);
-	printf("\tObjects: %u\r\n",object_count);
-	printf("\tUpdate: %u\r\n",update_count);
-	printf("\tSpawn: %u\r\n",spawn_count);
-	printf("\tSpeed: %f\r\n",speed);
-	printf("\tAmplitude: %f\r\n",amplitude);
-	srand(180673);
-	/* Create objects	*/ 
-	wallclock.reset();
-	objects.reserve(object_count);
-	for(int i=0;i<object_count;++i)
-		{
-		btBroadphaseBenchmark::Object*	po=new btBroadphaseBenchmark::Object();
-		po->center[0]=btBroadphaseBenchmark::UnitRand()*50;
-		po->center[1]=btBroadphaseBenchmark::UnitRand()*50;
-		po->center[2]=btBroadphaseBenchmark::UnitRand()*50;
-		po->extents[0]=btBroadphaseBenchmark::UnitRand()*2+2;
-		po->extents[1]=btBroadphaseBenchmark::UnitRand()*2+2;
-		po->extents[2]=btBroadphaseBenchmark::UnitRand()*2+2;
-		po->time=btBroadphaseBenchmark::UnitRand()*2000;
-		po->proxy=pbi->createProxy(po->center-po->extents,po->center+po->extents,0,po,1,1,0,0);
-		objects.push_back(po);
-		}
-	btBroadphaseBenchmark::OutputTime("\tInitialization",wallclock);
-	/* First update		*/ 
-	wallclock.reset();
-	for(int i=0;i<objects.size();++i)
-		{
-		objects[i]->update(speed,amplitude,pbi);
-		}
-	btBroadphaseBenchmark::OutputTime("\tFirst update",wallclock);
-	/* Updates			*/ 
-	wallclock.reset();
-	for(int i=0;i<experiment.iterations;++i)
-		{
-		for(int j=0;j<update_count;++j)
+	static const int										nexperiments=sizeof(experiments)/sizeof(experiments[0]);
+	btAlignedObjectArray<btBroadphaseBenchmark::Object*>	objects;
+	btClock													wallclock;
+	/* Begin			*/ 
+	for(int iexp=0;iexp<nexperiments;++iexp)
+	{
+		const btBroadphaseBenchmark::Experiment&	experiment=experiments[iexp];
+		const int									object_count=experiment.object_count;
+		const int									update_count=(object_count*experiment.update_count)/100;
+		const int									spawn_count=(object_count*experiment.spawn_count)/100;
+		const btScalar								speed=experiment.speed;	
+		const btScalar								amplitude=experiment.amplitude;
+		printf("Experiment #%u '%s':\r\n",iexp,experiment.name);
+		printf("\tObjects: %u\r\n",object_count);
+		printf("\tUpdate: %u\r\n",update_count);
+		printf("\tSpawn: %u\r\n",spawn_count);
+		printf("\tSpeed: %f\r\n",speed);
+		printf("\tAmplitude: %f\r\n",amplitude);
+		srand(180673);
+		/* Create objects	*/ 
+		wallclock.reset();
+		objects.reserve(object_count);
+		for(int i=0;i<object_count;++i)
+		{
+			btBroadphaseBenchmark::Object*	po=new btBroadphaseBenchmark::Object();
+			po->center[0]=btBroadphaseBenchmark::UnitRand()*50;
+			po->center[1]=btBroadphaseBenchmark::UnitRand()*50;
+			po->center[2]=btBroadphaseBenchmark::UnitRand()*50;
+			po->extents[0]=btBroadphaseBenchmark::UnitRand()*2+2;
+			po->extents[1]=btBroadphaseBenchmark::UnitRand()*2+2;
+			po->extents[2]=btBroadphaseBenchmark::UnitRand()*2+2;
+			po->time=btBroadphaseBenchmark::UnitRand()*2000;
+			po->proxy=pbi->createProxy(po->center-po->extents,po->center+po->extents,0,po,1,1,0,0);
+			objects.push_back(po);
+		}
+		btBroadphaseBenchmark::OutputTime("\tInitialization",wallclock);
+		/* First update		*/ 
+		wallclock.reset();
+		for(int i=0;i<objects.size();++i)
+		{
+			objects[i]->update(speed,amplitude,pbi);
+		}
+		btBroadphaseBenchmark::OutputTime("\tFirst update",wallclock);
+		/* Updates			*/ 
+		wallclock.reset();
+		for(int i=0;i<experiment.iterations;++i)
+		{
+			for(int j=0;j<update_count;++j)
 			{				
-			objects[j]->update(speed,amplitude,pbi);
+				objects[j]->update(speed,amplitude,pbi);
 			}
-		pbi->calculateOverlappingPairs(0);
-		}
-	btBroadphaseBenchmark::OutputTime("\tUpdate",wallclock,experiment.iterations);
-	/* Clean up			*/ 
-	wallclock.reset();
-	for(int i=0;i<objects.size();++i)
-		{
-		pbi->destroyProxy(objects[i]->proxy,0);
-		delete objects[i];
-		}
-	objects.resize(0);
-	btBroadphaseBenchmark::OutputTime("\tRelease",wallclock);
+			pbi->calculateOverlappingPairs(0);
+		}
+		btBroadphaseBenchmark::OutputTime("\tUpdate",wallclock,experiment.iterations);
+		/* Clean up			*/ 
+		wallclock.reset();
+		for(int i=0;i<objects.size();++i)
+		{
+			pbi->destroyProxy(objects[i]->proxy,0);
+			delete objects[i];
+		}
+		objects.resize(0);
+		btBroadphaseBenchmark::OutputTime("\tRelease",wallclock);
 	}
 
Index: code/branches/physics/src/bullet/BulletCollision/BroadphaseCollision/btDbvtBroadphase.h
===================================================================
--- code/branches/physics/src/bullet/BulletCollision/BroadphaseCollision/btDbvtBroadphase.h	(revision 2192)
+++ code/branches/physics/src/bullet/BulletCollision/BroadphaseCollision/btDbvtBroadphase.h	(revision 2430)
@@ -32,6 +32,6 @@
 
 #if DBVT_BP_PROFILE
-	#define	DBVT_BP_PROFILING_RATE	256
-	#include "LinearMath/btQuickprof.h"
+#define	DBVT_BP_PROFILING_RATE	256
+#include "LinearMath/btQuickprof.h"
 #endif
 
@@ -41,14 +41,14 @@
 struct btDbvtProxy : btBroadphaseProxy
 {
-/* Fields		*/ 
-btDbvtAabbMm	aabb;
-btDbvtNode*		leaf;
-btDbvtProxy*	links[2];
-int				stage;
-/* ctor			*/ 
-btDbvtProxy(void* userPtr,short int collisionFilterGroup, short int collisionFilterMask) :
-	btBroadphaseProxy(userPtr,collisionFilterGroup,collisionFilterMask)
+	/* Fields		*/ 
+	//btDbvtAabbMm	aabb;
+	btDbvtNode*		leaf;
+	btDbvtProxy*	links[2];
+	int				stage;
+	/* ctor			*/ 
+	btDbvtProxy(const btVector3& aabbMin,const btVector3& aabbMax,void* userPtr,short int collisionFilterGroup, short int collisionFilterMask) :
+	btBroadphaseProxy(aabbMin,aabbMax,userPtr,collisionFilterGroup,collisionFilterMask)
 	{
-	links[0]=links[1]=0;
+		links[0]=links[1]=0;
 	}
 };
@@ -61,33 +61,33 @@
 struct	btDbvtBroadphase : btBroadphaseInterface
 {
-/* Config		*/ 
-enum	{
+	/* Config		*/ 
+	enum	{
 		DYNAMIC_SET			=	0,	/* Dynamic set index	*/ 
 		FIXED_SET			=	1,	/* Fixed set index		*/ 
 		STAGECOUNT			=	2	/* Number of stages		*/ 
-		};
-/* Fields		*/ 
-btDbvt					m_sets[2];					// Dbvt sets
-btDbvtProxy*			m_stageRoots[STAGECOUNT+1];	// Stages list
-btOverlappingPairCache*	m_paircache;				// Pair cache
-btScalar				m_prediction;				// Velocity prediction
-int						m_stageCurrent;				// Current stage
-int						m_fupdates;					// % of fixed updates per frame
-int						m_dupdates;					// % of dynamic updates per frame
-int						m_cupdates;					// % of cleanup updates per frame
-int						m_newpairs;					// Number of pairs created
-int						m_fixedleft;				// Fixed optimization left
-unsigned				m_updates_call;				// Number of updates call
-unsigned				m_updates_done;				// Number of updates done
-btScalar				m_updates_ratio;			// m_updates_done/m_updates_call
-int						m_pid;						// Parse id
-int						m_cid;						// Cleanup index
-int						m_gid;						// Gen id
-bool					m_releasepaircache;			// Release pair cache on delete
-bool					m_deferedcollide;			// Defere dynamic/static collision to collide call
-bool					m_needcleanup;				// Need to run cleanup?
+	};
+	/* Fields		*/ 
+	btDbvt					m_sets[2];					// Dbvt sets
+	btDbvtProxy*			m_stageRoots[STAGECOUNT+1];	// Stages list
+	btOverlappingPairCache*	m_paircache;				// Pair cache
+	btScalar				m_prediction;				// Velocity prediction
+	int						m_stageCurrent;				// Current stage
+	int						m_fupdates;					// % of fixed updates per frame
+	int						m_dupdates;					// % of dynamic updates per frame
+	int						m_cupdates;					// % of cleanup updates per frame
+	int						m_newpairs;					// Number of pairs created
+	int						m_fixedleft;				// Fixed optimization left
+	unsigned				m_updates_call;				// Number of updates call
+	unsigned				m_updates_done;				// Number of updates done
+	btScalar				m_updates_ratio;			// m_updates_done/m_updates_call
+	int						m_pid;						// Parse id
+	int						m_cid;						// Cleanup index
+	int						m_gid;						// Gen id
+	bool					m_releasepaircache;			// Release pair cache on delete
+	bool					m_deferedcollide;			// Defere dynamic/static collision to collide call
+	bool					m_needcleanup;				// Need to run cleanup?
 #if DBVT_BP_PROFILE
-btClock					m_clock;
-struct	{
+	btClock					m_clock;
+	struct	{
 		unsigned long		m_total;
 		unsigned long		m_ddcollide;
@@ -95,21 +95,24 @@
 		unsigned long		m_cleanup;
 		unsigned long		m_jobcount;
-		}				m_profiling;
+	}				m_profiling;
 #endif
-/* Methods		*/ 
-btDbvtBroadphase(btOverlappingPairCache* paircache=0);
-~btDbvtBroadphase();
-void							collide(btDispatcher* dispatcher);
-void							optimize();
-/* btBroadphaseInterface Implementation	*/ 
-btBroadphaseProxy*				createProxy(const btVector3& aabbMin,const btVector3& aabbMax,int shapeType,void* userPtr,short int collisionFilterGroup,short int collisionFilterMask,btDispatcher* dispatcher,void* multiSapProxy);
-void							destroyProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher);
-void							setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax,btDispatcher* dispatcher);
-void							calculateOverlappingPairs(btDispatcher* dispatcher);
-btOverlappingPairCache*			getOverlappingPairCache();
-const btOverlappingPairCache*	getOverlappingPairCache() const;
-void							getBroadphaseAabb(btVector3& aabbMin,btVector3& aabbMax) const;
-void							printStats();
-static void						benchmark(btBroadphaseInterface*);
+	/* Methods		*/ 
+	btDbvtBroadphase(btOverlappingPairCache* paircache=0);
+	~btDbvtBroadphase();
+	void							collide(btDispatcher* dispatcher);
+	void							optimize();
+	/* btBroadphaseInterface Implementation	*/ 
+	btBroadphaseProxy*				createProxy(const btVector3& aabbMin,const btVector3& aabbMax,int shapeType,void* userPtr,short int collisionFilterGroup,short int collisionFilterMask,btDispatcher* dispatcher,void* multiSapProxy);
+	void							destroyProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher);
+	void							setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax,btDispatcher* dispatcher);
+	virtual void	rayTest(const btVector3& rayFrom,const btVector3& rayTo, btBroadphaseRayCallback& rayCallback, const btVector3& aabbMin=btVector3(0,0,0), const btVector3& aabbMax = btVector3(0,0,0));
+
+	virtual void	getAabb(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const;
+	void							calculateOverlappingPairs(btDispatcher* dispatcher);
+	btOverlappingPairCache*			getOverlappingPairCache();
+	const btOverlappingPairCache*	getOverlappingPairCache() const;
+	void							getBroadphaseAabb(btVector3& aabbMin,btVector3& aabbMax) const;
+	void							printStats();
+	static void						benchmark(btBroadphaseInterface*);
 };
 
Index: code/branches/physics/src/bullet/BulletCollision/BroadphaseCollision/btDispatcher.h
===================================================================
--- code/branches/physics/src/bullet/BulletCollision/BroadphaseCollision/btDispatcher.h	(revision 2192)
+++ code/branches/physics/src/bullet/BulletCollision/BroadphaseCollision/btDispatcher.h	(revision 2430)
@@ -47,4 +47,6 @@
 		m_useEpa(true),
 		m_allowedCcdPenetration(btScalar(0.04)),
+		m_useConvexConservativeDistanceUtil(true),
+		m_convexConservativeDistanceThreshold(0.0f),
 		m_stackAllocator(0)
 	{
@@ -52,15 +54,16 @@
 	}
 	btScalar	m_timeStep;
-	int		m_stepCount;
-	int		m_dispatchFunc;
+	int			m_stepCount;
+	int			m_dispatchFunc;
 	mutable btScalar	m_timeOfImpact;
-	bool	m_useContinuous;
+	bool		m_useContinuous;
 	class btIDebugDraw*	m_debugDraw;
-	bool	m_enableSatConvex;
-	bool	m_enableSPU;
-	bool	m_useEpa;
+	bool		m_enableSatConvex;
+	bool		m_enableSPU;
+	bool		m_useEpa;
 	btScalar	m_allowedCcdPenetration;
+	bool		m_useConvexConservativeDistanceUtil;
+	btScalar	m_convexConservativeDistanceThreshold;
 	btStackAlloc*	m_stackAllocator;
-	
 };
 
Index: code/branches/physics/src/bullet/BulletCollision/BroadphaseCollision/btMultiSapBroadphase.cpp
===================================================================
--- code/branches/physics/src/bullet/BulletCollision/BroadphaseCollision/btMultiSapBroadphase.cpp	(revision 2192)
+++ code/branches/physics/src/bullet/BulletCollision/BroadphaseCollision/btMultiSapBroadphase.cpp	(revision 2430)
@@ -150,4 +150,20 @@
 
 
+void	btMultiSapBroadphase::getAabb(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const
+{
+	btMultiSapProxy* multiProxy = static_cast<btMultiSapProxy*>(proxy);
+	aabbMin = multiProxy->m_aabbMin;
+	aabbMax = multiProxy->m_aabbMax;
+}
+
+void	btMultiSapBroadphase::rayTest(const btVector3& rayFrom,const btVector3& rayTo, btBroadphaseRayCallback& rayCallback, const btVector3& aabbMin,const btVector3& aabbMax)
+{
+	for (int i=0;i<m_multiSapProxies.size();i++)
+	{
+		rayCallback.process(m_multiSapProxies[i]);
+	}
+}
+
+
 //#include <stdio.h>
 
@@ -209,5 +225,7 @@
 
 	
-	m_optimizedAabbTree->reportAabbOverlappingNodex(&myNodeCallback,aabbMin,aabbMax);
+	if (m_optimizedAabbTree)
+		m_optimizedAabbTree->reportAabbOverlappingNodex(&myNodeCallback,aabbMin,aabbMax);
+
 	int i;
 
Index: code/branches/physics/src/bullet/BulletCollision/BroadphaseCollision/btMultiSapBroadphase.h
===================================================================
--- code/branches/physics/src/bullet/BulletCollision/BroadphaseCollision/btMultiSapBroadphase.h	(revision 2192)
+++ code/branches/physics/src/bullet/BulletCollision/BroadphaseCollision/btMultiSapBroadphase.h	(revision 2430)
@@ -27,4 +27,5 @@
 typedef btAlignedObjectArray<btBroadphaseInterface*> btSapBroadphaseArray;
 
+///The btMultiSapBroadphase is a research project, not recommended to use in production. Use btAxisSweep3 or btDbvtBroadphase instead.
 ///The btMultiSapBroadphase is a broadphase that contains multiple SAP broadphases.
 ///The user can add SAP broadphases that cover the world. A btBroadphaseProxy can be in multiple child broadphases at the same time.
@@ -73,5 +74,5 @@
 */
 		btMultiSapProxy(const btVector3& aabbMin,  const btVector3& aabbMax,int shapeType,void* userPtr, short int collisionFilterGroup,short int collisionFilterMask)
-			:btBroadphaseProxy(userPtr,collisionFilterGroup,collisionFilterMask),
+			:btBroadphaseProxy(aabbMin,aabbMax,userPtr,collisionFilterGroup,collisionFilterMask),
 			m_aabbMin(aabbMin),
 			m_aabbMax(aabbMax),
@@ -109,4 +110,7 @@
 	virtual void	destroyProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher);
 	virtual void	setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax, btDispatcher* dispatcher);
+	virtual void	getAabb(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const;
+
+	virtual void	rayTest(const btVector3& rayFrom,const btVector3& rayTo, btBroadphaseRayCallback& rayCallback,const btVector3& aabbMin=btVector3(0,0,0),const btVector3& aabbMax=btVector3(0,0,0));
 
 	void	addToChildBroadphase(btMultiSapProxy* parentMultiSapProxy, btBroadphaseProxy* childProxy, btBroadphaseInterface*	childBroadphase);
Index: code/branches/physics/src/bullet/BulletCollision/BroadphaseCollision/btOverlappingPairCache.cpp
===================================================================
--- code/branches/physics/src/bullet/BulletCollision/BroadphaseCollision/btOverlappingPairCache.cpp	(revision 2192)
+++ code/branches/physics/src/bullet/BulletCollision/BroadphaseCollision/btOverlappingPairCache.cpp	(revision 2430)
@@ -34,5 +34,6 @@
 btHashedOverlappingPairCache::btHashedOverlappingPairCache():
 	m_overlapFilterCallback(0),
-	m_blockedForChanges(false)
+	m_blockedForChanges(false),
+	m_ghostPairCallback(0)
 {
 	int initialAllocatedSize= 2;
@@ -46,5 +47,4 @@
 btHashedOverlappingPairCache::~btHashedOverlappingPairCache()
 {
-	//todo/test: show we erase/delete data, or is it automatic
 }
 
@@ -239,4 +239,9 @@
 	int oldCapacity = m_overlappingPairArray.capacity();
 	void* mem = &m_overlappingPairArray.expand();
+
+	//this is where we add an actual pair, so also call the 'ghost'
+	if (m_ghostPairCallback)
+		m_ghostPairCallback->addOverlappingPair(proxy0,proxy1);
+
 	int newCapacity = m_overlappingPairArray.capacity();
 
@@ -252,5 +257,5 @@
 //	pair->m_pProxy1 = proxy1;
 	pair->m_algorithm = 0;
-	pair->m_userInfo = 0;
+	pair->m_internalTmpValue = 0;
 	
 
@@ -283,5 +288,5 @@
 	cleanOverlappingPair(*pair,dispatcher);
 
-	void* userData = pair->m_userInfo;
+	void* userData = pair->m_internalInfo1;
 
 	btAssert(pair->m_pProxy0->getUid() == proxyId1);
@@ -317,4 +322,7 @@
 
 	int lastPairIndex = m_overlappingPairArray.size() - 1;
+
+	if (m_ghostPairCallback)
+		m_ghostPairCallback->removeOverlappingPair(proxy0, proxy1,dispatcher);
 
 	// If the removed pair is the last pair, we are done.
@@ -398,6 +406,8 @@
 			gOverlappingPairs--;
 			btBroadphasePair& pair = m_overlappingPairArray[findIndex];
-			void* userData = pair.m_userInfo;
+			void* userData = pair.m_internalInfo1;
 			cleanOverlappingPair(pair,dispatcher);
+			if (m_ghostPairCallback)
+				m_ghostPairCallback->removeOverlappingPair(proxy0, proxy1,dispatcher);
 			
 			m_overlappingPairArray.swap(findIndex,m_overlappingPairArray.capacity()-1);
@@ -427,6 +437,10 @@
 	void* mem = &m_overlappingPairArray.expand();
 	btBroadphasePair* pair = new (mem) btBroadphasePair(*proxy0,*proxy1);
+	
 	gOverlappingPairs++;
 	gAddedPairs++;
+	
+	if (m_ghostPairCallback)
+		m_ghostPairCallback->addOverlappingPair(proxy0, proxy1);
 	return pair;
 	
@@ -494,5 +508,6 @@
 	m_blockedForChanges(false),
 	m_hasDeferredRemoval(true),
-	m_overlapFilterCallback(0)
+	m_overlapFilterCallback(0),
+	m_ghostPairCallback(0)
 {
 	int initialAllocatedSize= 2;
@@ -502,5 +517,4 @@
 btSortedOverlappingPairCache::~btSortedOverlappingPairCache()
 {
-	//todo/test: show we erase/delete data, or is it automatic
 }
 
Index: code/branches/physics/src/bullet/BulletCollision/BroadphaseCollision/btOverlappingPairCache.h
===================================================================
--- code/branches/physics/src/bullet/BulletCollision/BroadphaseCollision/btOverlappingPairCache.h	(revision 2192)
+++ code/branches/physics/src/bullet/BulletCollision/BroadphaseCollision/btOverlappingPairCache.h	(revision 2430)
@@ -22,5 +22,4 @@
 #include "btOverlappingPairCallback.h"
 
-#include "LinearMath/btPoint3.h"
 #include "LinearMath/btAlignedObjectArray.h"
 class btDispatcher;
@@ -83,4 +82,6 @@
 
 	virtual bool	hasDeferredRemoval() = 0;
+
+	virtual	void	setInternalGhostPairCallback(btOverlappingPairCallback* ghostPairCallback)=0;
 
 };
@@ -254,8 +255,14 @@
 	}
 
+	virtual	void	setInternalGhostPairCallback(btOverlappingPairCallback* ghostPairCallback)
+	{
+		m_ghostPairCallback = ghostPairCallback;
+	}
+
 public:
 	
 	btAlignedObjectArray<int>	m_hashTable;
 	btAlignedObjectArray<int>	m_next;
+	btOverlappingPairCallback*	m_ghostPairCallback;
 	
 };
@@ -280,4 +287,6 @@
 		//if set, use the callback instead of the built in filter in needBroadphaseCollision
 		btOverlapFilterCallback* m_overlapFilterCallback;
+
+		btOverlappingPairCallback*	m_ghostPairCallback;
 
 	public:
@@ -356,10 +365,15 @@
 		}
 
-
-};
-
-
-
-///btNullPairCache skips add/removal of overlapping pairs. Userful for benchmarking and testing.
+		virtual	void	setInternalGhostPairCallback(btOverlappingPairCallback* ghostPairCallback)
+		{
+			m_ghostPairCallback = ghostPairCallback;
+		}
+
+
+};
+
+
+
+///btNullPairCache skips add/removal of overlapping pairs. Userful for benchmarking and unit testing.
 class btNullPairCache : public btOverlappingPairCache
 {
@@ -415,4 +429,9 @@
 	}
 
+	virtual	void	setInternalGhostPairCallback(btOverlappingPairCallback* /* ghostPairCallback */)
+	{
+
+	}
+
 	virtual btBroadphasePair*	addOverlappingPair(btBroadphaseProxy* /*proxy0*/,btBroadphaseProxy* /*proxy1*/)
 	{
@@ -428,4 +447,5 @@
 	{
 	}
+	
 
 
Index: code/branches/physics/src/bullet/BulletCollision/BroadphaseCollision/btQuantizedBvh.cpp
===================================================================
--- code/branches/physics/src/bullet/BulletCollision/BroadphaseCollision/btQuantizedBvh.cpp	(revision 2192)
+++ code/branches/physics/src/bullet/BulletCollision/BroadphaseCollision/btQuantizedBvh.cpp	(revision 2430)
@@ -19,12 +19,16 @@
 #include "LinearMath/btIDebugDraw.h"
 
-
-btQuantizedBvh::btQuantizedBvh() : m_useQuantization(false), 
+#define RAYAABB2
+
+btQuantizedBvh::btQuantizedBvh() : 
+					m_bulletVersion(BT_BULLET_VERSION),
+					m_useQuantization(false), 
 					//m_traversalMode(TRAVERSAL_STACKLESS_CACHE_FRIENDLY)
 					m_traversalMode(TRAVERSAL_STACKLESS)
 					//m_traversalMode(TRAVERSAL_RECURSIVE)
 					,m_subtreeHeaderCount(0) //PCK: add this line
-{ 
-
+{
+	m_bvhAabbMin.setValue(-SIMD_INFINITY,-SIMD_INFINITY,-SIMD_INFINITY);
+	m_bvhAabbMax.setValue(SIMD_INFINITY,SIMD_INFINITY,SIMD_INFINITY);
 }
 
@@ -120,5 +124,5 @@
 	int curIndex = m_curNodeIndex;
 
-	assert(numIndices>0);
+	btAssert(numIndices>0);
 
 	if (numIndices==1)
@@ -141,6 +145,9 @@
 	int internalNodeIndex = m_curNodeIndex;
 	
-	setInternalNodeAabbMax(m_curNodeIndex,m_bvhAabbMin);
-	setInternalNodeAabbMin(m_curNodeIndex,m_bvhAabbMax);
+	//set the min aabb to 'inf' or a max value, and set the max aabb to a -inf/minimum value.
+	//the aabb will be expanded during buildTree/mergeInternalNodeAabb with actual node values
+	setInternalNodeAabbMin(m_curNodeIndex,m_bvhAabbMax);//can't use btVector3(SIMD_INFINITY,SIMD_INFINITY,SIMD_INFINITY)) because of quantization
+	setInternalNodeAabbMax(m_curNodeIndex,m_bvhAabbMin);//can't use btVector3(-SIMD_INFINITY,-SIMD_INFINITY,-SIMD_INFINITY)) because of quantization
+	
 	
 	for (i=startIndex;i<endIndex;i++)
@@ -178,4 +185,7 @@
 			updateSubtreeHeaders(leftChildNodexIndex,rightChildNodexIndex);
 		}
+	} else
+	{
+
 	}
 
@@ -339,4 +349,5 @@
 int maxIterations = 0;
 
+
 void	btQuantizedBvh::walkStacklessTree(btNodeOverlapCallback* nodeCallback,const btVector3& aabbMin,const btVector3& aabbMax) const
 {
@@ -353,5 +364,5 @@
 	{
 		//catch bugs in tree data
-		assert (walkIterations < m_curNodeIndex);
+		btAssert (walkIterations < m_curNodeIndex);
 
 		walkIterations++;
@@ -435,4 +446,95 @@
 
 
+void	btQuantizedBvh::walkStacklessTreeAgainstRay(btNodeOverlapCallback* nodeCallback, const btVector3& raySource, const btVector3& rayTarget, const btVector3& aabbMin, const btVector3& aabbMax, int startNodeIndex,int endNodeIndex) const
+{
+	btAssert(!m_useQuantization);
+
+	const btOptimizedBvhNode* rootNode = &m_contiguousNodes[0];
+	int escapeIndex, curIndex = 0;
+	int walkIterations = 0;
+	bool isLeafNode;
+	//PCK: unsigned instead of bool
+	unsigned aabbOverlap=0;
+	unsigned rayBoxOverlap=0;
+	btScalar lambda_max = 1.0;
+	
+		/* Quick pruning by quantized box */
+	btVector3 rayAabbMin = raySource;
+	btVector3 rayAabbMax = raySource;
+	rayAabbMin.setMin(rayTarget);
+	rayAabbMax.setMax(rayTarget);
+
+	/* Add box cast extents to bounding box */
+	rayAabbMin += aabbMin;
+	rayAabbMax += aabbMax;
+
+#ifdef RAYAABB2
+	btVector3 rayFrom = raySource;
+	btVector3 rayDir = (rayTarget-raySource);
+	rayDir.normalize ();
+	lambda_max = rayDir.dot(rayTarget-raySource);
+	///what about division by zero? --> just set rayDirection[i] to 1.0
+	btVector3 rayDirectionInverse;
+	rayDirectionInverse[0] = rayDir[0] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[0];
+	rayDirectionInverse[1] = rayDir[1] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[1];
+	rayDirectionInverse[2] = rayDir[2] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[2];
+	unsigned int sign[3] = { rayDirectionInverse[0] < 0.0, rayDirectionInverse[1] < 0.0, rayDirectionInverse[2] < 0.0};
+#endif
+
+	btVector3 bounds[2];
+
+	while (curIndex < m_curNodeIndex)
+	{
+		btScalar param = 1.0;
+		//catch bugs in tree data
+		btAssert (walkIterations < m_curNodeIndex);
+
+		walkIterations++;
+
+		bounds[0] = rootNode->m_aabbMinOrg;
+		bounds[1] = rootNode->m_aabbMaxOrg;
+		/* Add box cast extents */
+		bounds[0] += aabbMin;
+		bounds[1] += aabbMax;
+
+		aabbOverlap = TestAabbAgainstAabb2(rayAabbMin,rayAabbMax,rootNode->m_aabbMinOrg,rootNode->m_aabbMaxOrg);
+		//perhaps profile if it is worth doing the aabbOverlap test first
+
+#ifdef RAYAABB2
+			///careful with this check: need to check division by zero (above) and fix the unQuantize method
+			///thanks Joerg/hiker for the reproduction case!
+			///http://www.bulletphysics.com/Bullet/phpBB3/viewtopic.php?f=9&t=1858
+		rayBoxOverlap = aabbOverlap ? btRayAabb2 (raySource, rayDirectionInverse, sign, bounds, param, 0.0f, lambda_max) : false;
+
+#else
+		btVector3 normal;
+		rayBoxOverlap = btRayAabb(raySource, rayTarget,bounds[0],bounds[1],param, normal);
+#endif
+
+		isLeafNode = rootNode->m_escapeIndex == -1;
+		
+		//PCK: unsigned instead of bool
+		if (isLeafNode && (rayBoxOverlap != 0))
+		{
+			nodeCallback->processNode(rootNode->m_subPart,rootNode->m_triangleIndex);
+		} 
+		
+		//PCK: unsigned instead of bool
+		if ((rayBoxOverlap != 0) || isLeafNode)
+		{
+			rootNode++;
+			curIndex++;
+		} else
+		{
+			escapeIndex = rootNode->m_escapeIndex;
+			rootNode += escapeIndex;
+			curIndex += escapeIndex;
+		}
+	}
+	if (maxIterations < walkIterations)
+		maxIterations = walkIterations;
+
+}
+
 
 
@@ -455,5 +557,5 @@
 
 	btScalar lambda_max = 1.0;
-#define RAYAABB2
+
 #ifdef RAYAABB2
 	btVector3 rayFrom = raySource;
@@ -503,5 +605,5 @@
 
 		//catch bugs in tree data
-		assert (walkIterations < subTreeSize);
+		btAssert (walkIterations < subTreeSize);
 
 		walkIterations++;
@@ -534,5 +636,7 @@
 			///http://www.bulletphysics.com/Bullet/phpBB3/viewtopic.php?f=9&t=1858
 
+			//BT_PROFILE("btRayAabb2");
 			rayBoxOverlap = btRayAabb2 (raySource, rayDirection, sign, bounds, param, 0.0f, lambda_max);
+			
 #else
 			rayBoxOverlap = true;//btRayAabb(raySource, rayTarget, bounds[0], bounds[1], param, normal);
@@ -598,5 +702,5 @@
 
 		//catch bugs in tree data
-		assert (walkIterations < subTreeSize);
+		btAssert (walkIterations < subTreeSize);
 
 		walkIterations++;
@@ -653,16 +757,5 @@
 void	btQuantizedBvh::reportRayOverlappingNodex (btNodeOverlapCallback* nodeCallback, const btVector3& raySource, const btVector3& rayTarget) const
 {
-	bool fast_path = m_useQuantization && m_traversalMode == TRAVERSAL_STACKLESS;
-	if (fast_path)
-	{
-		walkStacklessQuantizedTreeAgainstRay(nodeCallback, raySource, rayTarget, btVector3(0, 0, 0), btVector3(0, 0, 0), 0, m_curNodeIndex);
-	} else {
-		/* Otherwise fallback to AABB overlap test */
-		btVector3 aabbMin = raySource;
-		btVector3 aabbMax = raySource;
-		aabbMin.setMin(rayTarget);
-		aabbMax.setMax(rayTarget);
-		reportAabbOverlappingNodex(nodeCallback,aabbMin,aabbMax);
-	}
+	reportBoxCastOverlappingNodex(nodeCallback,raySource,rayTarget,btVector3(0,0,0),btVector3(0,0,0));
 }
 
@@ -670,11 +763,17 @@
 void	btQuantizedBvh::reportBoxCastOverlappingNodex(btNodeOverlapCallback* nodeCallback, const btVector3& raySource, const btVector3& rayTarget, const btVector3& aabbMin,const btVector3& aabbMax) const
 {
-	bool fast_path = m_useQuantization && m_traversalMode == TRAVERSAL_STACKLESS;
-	if (fast_path)
+	//always use stackless
+
+	if (m_useQuantization)
 	{
 		walkStacklessQuantizedTreeAgainstRay(nodeCallback, raySource, rayTarget, aabbMin, aabbMax, 0, m_curNodeIndex);
-	} else {
-		/* Slow path:
-		   Construct the bounding box for the entire box cast and send that down the tree */
+	}
+	else
+	{
+		walkStacklessTreeAgainstRay(nodeCallback, raySource, rayTarget, aabbMin, aabbMax, 0, m_curNodeIndex);
+	}
+	/*
+	{
+		//recursive traversal
 		btVector3 qaabbMin = raySource;
 		btVector3 qaabbMax = raySource;
@@ -685,4 +784,6 @@
 		reportAabbOverlappingNodex(nodeCallback,qaabbMin,qaabbMax);
 	}
+	*/
+
 }
 
@@ -744,5 +845,5 @@
 bool btQuantizedBvh::serialize(void *o_alignedDataBuffer, unsigned /*i_dataBufferSize */, bool i_swapEndian)
 {
-	assert(m_subtreeHeaderCount == m_SubtreeHeaders.size());
+	btAssert(m_subtreeHeaderCount == m_SubtreeHeaders.size());
 	m_subtreeHeaderCount = m_SubtreeHeaders.size();
 
@@ -1038,10 +1139,10 @@
 m_bvhAabbMin(self.m_bvhAabbMin),
 m_bvhAabbMax(self.m_bvhAabbMax),
-m_bvhQuantization(self.m_bvhQuantization)
-{
-
-
-}
-
-
-
+m_bvhQuantization(self.m_bvhQuantization),
+m_bulletVersion(BT_BULLET_VERSION)
+{
+
+}
+
+
+
Index: code/branches/physics/src/bullet/BulletCollision/BroadphaseCollision/btQuantizedBvh.h
===================================================================
--- code/branches/physics/src/bullet/BulletCollision/BroadphaseCollision/btQuantizedBvh.h	(revision 2192)
+++ code/branches/physics/src/bullet/BulletCollision/BroadphaseCollision/btQuantizedBvh.h	(revision 2430)
@@ -159,24 +159,5 @@
 ATTRIBUTE_ALIGNED16(class) btQuantizedBvh
 {
-protected:
-
-	NodeArray			m_leafNodes;
-	NodeArray			m_contiguousNodes;
-
-	QuantizedNodeArray	m_quantizedLeafNodes;
-	
-	QuantizedNodeArray	m_quantizedContiguousNodes;
-	
-	int					m_curNodeIndex;
-
-
-	//quantization data
-	bool				m_useQuantization;
-	btVector3			m_bvhAabbMin;
-	btVector3			m_bvhAabbMax;
-	btVector3			m_bvhQuantization;
 public:
-	BT_DECLARE_ALIGNED_ALLOCATOR();
-
 	enum btTraversalMode
 	{
@@ -185,12 +166,33 @@
 		TRAVERSAL_RECURSIVE
 	};
+
 protected:
 
+
+	btVector3			m_bvhAabbMin;
+	btVector3			m_bvhAabbMax;
+	btVector3			m_bvhQuantization;
+
+	int					m_bulletVersion;	//for serialization versioning. It could also be used to detect endianess.
+
+	int					m_curNodeIndex;
+	//quantization data
+	bool				m_useQuantization;
+
+
+
+	NodeArray			m_leafNodes;
+	NodeArray			m_contiguousNodes;
+	QuantizedNodeArray	m_quantizedLeafNodes;
+	QuantizedNodeArray	m_quantizedContiguousNodes;
+	
 	btTraversalMode	m_traversalMode;
-	
 	BvhSubtreeInfoArray		m_SubtreeHeaders;
 
 	//This is only used for serialization so we don't have to add serialization directly to btAlignedObjectArray
 	int m_subtreeHeaderCount;
+
+	
+
 
 
@@ -297,4 +299,5 @@
 	void	walkStacklessQuantizedTreeAgainstRay(btNodeOverlapCallback* nodeCallback, const btVector3& raySource, const btVector3& rayTarget, const btVector3& aabbMin, const btVector3& aabbMax, int startNodeIndex,int endNodeIndex) const;
 	void	walkStacklessQuantizedTree(btNodeOverlapCallback* nodeCallback,unsigned short int* quantizedQueryAabbMin,unsigned short int* quantizedQueryAabbMax,int startNodeIndex,int endNodeIndex) const;
+	void	walkStacklessTreeAgainstRay(btNodeOverlapCallback* nodeCallback, const btVector3& raySource, const btVector3& rayTarget, const btVector3& aabbMin, const btVector3& aabbMax, int startNodeIndex,int endNodeIndex) const;
 
 	///tree traversal designed for small-memory processors like PS3 SPU
@@ -308,28 +311,12 @@
 	
 
-#define USE_BANCHLESS 1
-#ifdef USE_BANCHLESS
-	//This block replaces the block below and uses no branches, and replaces the 8 bit return with a 32 bit return for improved performance (~3x on XBox 360)
-	SIMD_FORCE_INLINE unsigned testQuantizedAabbAgainstQuantizedAabb(unsigned short int* aabbMin1,unsigned short int* aabbMax1,const unsigned short int* aabbMin2,const unsigned short int* aabbMax2) const
-	{		
-		return static_cast<unsigned int>(btSelect((unsigned)((aabbMin1[0] <= aabbMax2[0]) & (aabbMax1[0] >= aabbMin2[0])
-			& (aabbMin1[2] <= aabbMax2[2]) & (aabbMax1[2] >= aabbMin2[2])
-			& (aabbMin1[1] <= aabbMax2[1]) & (aabbMax1[1] >= aabbMin2[1])),
-			1, 0));
-	}
-#else
-	SIMD_FORCE_INLINE bool testQuantizedAabbAgainstQuantizedAabb(unsigned short int* aabbMin1,unsigned short int* aabbMax1,const unsigned short int* aabbMin2,const unsigned short int* aabbMax2) const
-	{
-		bool overlap = true;
-		overlap = (aabbMin1[0] > aabbMax2[0] || aabbMax1[0] < aabbMin2[0]) ? false : overlap;
-		overlap = (aabbMin1[2] > aabbMax2[2] || aabbMax1[2] < aabbMin2[2]) ? false : overlap;
-		overlap = (aabbMin1[1] > aabbMax2[1] || aabbMax1[1] < aabbMin2[1]) ? false : overlap;
-		return overlap;
-	}
-#endif //USE_BANCHLESS
+
 
 	void	updateSubtreeHeaders(int leftChildNodexIndex,int rightChildNodexIndex);
 
 public:
+	
+	BT_DECLARE_ALIGNED_ALLOCATOR();
+
 	btQuantizedBvh();
 
@@ -364,5 +351,5 @@
 		///Make sure rounding is done in a way that unQuantize(quantizeWithClamp(...)) is conservative
 		///end-points always set the first bit, so that they are sorted properly (so that neighbouring AABBs overlap properly)
-		///todo: double-check this
+		///@todo: double-check this
 		if (isMax)
 		{
Index: code/branches/physics/src/bullet/BulletCollision/BroadphaseCollision/btSimpleBroadphase.cpp
===================================================================
--- code/branches/physics/src/bullet/BulletCollision/BroadphaseCollision/btSimpleBroadphase.cpp	(revision 2192)
+++ code/branches/physics/src/bullet/BulletCollision/BroadphaseCollision/btSimpleBroadphase.cpp	(revision 2430)
@@ -56,4 +56,5 @@
 	m_numHandles = 0;
 	m_firstFreeHandle = 0;
+	m_LastHandleIndex = -1;
 	
 
@@ -89,5 +90,5 @@
 		return 0; //should never happen, but don't let the game crash ;-)
 	}
-	assert(aabbMin[0]<= aabbMax[0] && aabbMin[1]<= aabbMax[1] && aabbMin[2]<= aabbMax[2]);
+	btAssert(aabbMin[0]<= aabbMax[0] && aabbMin[1]<= aabbMax[1] && aabbMin[2]<= aabbMax[2]);
 
 	int newHandleIndex = allocHandle();
@@ -138,12 +139,30 @@
 }
 
+void	btSimpleBroadphase::getAabb(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const
+{
+	const btSimpleBroadphaseProxy* sbp = getSimpleProxyFromProxy(proxy);
+	aabbMin = sbp->m_aabbMin;
+	aabbMax = sbp->m_aabbMax;
+}
+
 void	btSimpleBroadphase::setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax, btDispatcher* /*dispatcher*/)
 {
 	btSimpleBroadphaseProxy* sbp = getSimpleProxyFromProxy(proxy);
-	sbp->m_min = aabbMin;
-	sbp->m_max = aabbMax;
-}
-
-
+	sbp->m_aabbMin = aabbMin;
+	sbp->m_aabbMax = aabbMax;
+}
+
+void	btSimpleBroadphase::rayTest(const btVector3& rayFrom,const btVector3& rayTo, btBroadphaseRayCallback& rayCallback, const btVector3& aabbMin,const btVector3& aabbMax)
+{
+	for (int i=0; i <= m_LastHandleIndex; i++)
+	{
+		btSimpleBroadphaseProxy* proxy = &m_pHandles[i];
+		if(!proxy->m_clientObject)
+		{
+			continue;
+		}
+		rayCallback.process(proxy);
+	}
+}
 
 
@@ -155,7 +174,7 @@
 bool	btSimpleBroadphase::aabbOverlap(btSimpleBroadphaseProxy* proxy0,btSimpleBroadphaseProxy* proxy1)
 {
-	return proxy0->m_min[0] <= proxy1->m_max[0] && proxy1->m_min[0] <= proxy0->m_max[0] && 
-		   proxy0->m_min[1] <= proxy1->m_max[1] && proxy1->m_min[1] <= proxy0->m_max[1] &&
-		   proxy0->m_min[2] <= proxy1->m_max[2] && proxy1->m_min[2] <= proxy0->m_max[2];
+	return proxy0->m_aabbMin[0] <= proxy1->m_aabbMax[0] && proxy1->m_aabbMin[0] <= proxy0->m_aabbMax[0] && 
+		   proxy0->m_aabbMin[1] <= proxy1->m_aabbMax[1] && proxy1->m_aabbMin[1] <= proxy0->m_aabbMax[1] &&
+		   proxy0->m_aabbMin[2] <= proxy1->m_aabbMax[2] && proxy1->m_aabbMin[2] <= proxy0->m_aabbMax[2];
 
 }
@@ -177,16 +196,23 @@
 	//first check for new overlapping pairs
 	int i,j;
-
 	if (m_numHandles >= 0)
 	{
-
-		for (i=0;i<m_numHandles;i++)
+		int new_largest_index = -1;
+		for (i=0; i <= m_LastHandleIndex; i++)
 		{
 			btSimpleBroadphaseProxy* proxy0 = &m_pHandles[i];
-
-			for (j=i+1;j<m_numHandles;j++)
+			if(!proxy0->m_clientObject)
+			{
+				continue;
+			}
+			new_largest_index = i;
+			for (j=i+1; j <= m_LastHandleIndex; j++)
 			{
 				btSimpleBroadphaseProxy* proxy1 = &m_pHandles[j];
 				btAssert(proxy0 != proxy1);
+				if(!proxy1->m_clientObject)
+				{
+					continue;
+				}
 
 				btSimpleBroadphaseProxy* p0 = getSimpleProxyFromProxy(proxy0);
@@ -212,4 +238,6 @@
 		}
 
+		m_LastHandleIndex = new_largest_index;
+
 		if (m_ownsPairCache && m_pairCache->hasDeferredRemoval())
 		{
Index: code/branches/physics/src/bullet/BulletCollision/BroadphaseCollision/btSimpleBroadphase.h
===================================================================
--- code/branches/physics/src/bullet/BulletCollision/BroadphaseCollision/btSimpleBroadphase.h	(revision 2192)
+++ code/branches/physics/src/bullet/BulletCollision/BroadphaseCollision/btSimpleBroadphase.h	(revision 2430)
@@ -23,6 +23,4 @@
 struct btSimpleBroadphaseProxy : public btBroadphaseProxy
 {
-	btVector3	m_min;
-	btVector3	m_max;
 	int			m_nextFree;
 	
@@ -32,7 +30,6 @@
 	btSimpleBroadphaseProxy() {};
 
-	btSimpleBroadphaseProxy(const btPoint3& minpt,const btPoint3& maxpt,int shapeType,void* userPtr,short int collisionFilterGroup,short int collisionFilterMask,void* multiSapProxy)
-	:btBroadphaseProxy(userPtr,collisionFilterGroup,collisionFilterMask,multiSapProxy),
-	m_min(minpt),m_max(maxpt)		
+	btSimpleBroadphaseProxy(const btVector3& minpt,const btVector3& maxpt,int shapeType,void* userPtr,short int collisionFilterGroup,short int collisionFilterMask,void* multiSapProxy)
+	:btBroadphaseProxy(minpt,maxpt,userPtr,collisionFilterGroup,collisionFilterMask,multiSapProxy)
 	{
 		(void)shapeType;
@@ -57,4 +54,5 @@
 	int		m_numHandles;						// number of active handles
 	int		m_maxHandles;						// max number of handles
+	int		m_LastHandleIndex;							
 	
 	btSimpleBroadphaseProxy* m_pHandles;						// handles pool
@@ -69,4 +67,8 @@
 		m_firstFreeHandle = m_pHandles[freeHandle].GetNextFree();
 		m_numHandles++;
+		if(freeHandle > m_LastHandleIndex)
+		{
+			m_LastHandleIndex = freeHandle;
+		}
 		return freeHandle;
 	}
@@ -76,7 +78,12 @@
 		int handle = int(proxy-m_pHandles);
 		btAssert(handle >= 0 && handle < m_maxHandles);
-
+		if(handle == m_LastHandleIndex)
+		{
+			m_LastHandleIndex--;
+		}
 		proxy->SetNextFree(m_firstFreeHandle);
 		m_firstFreeHandle = handle;
+
+		proxy->m_clientObject = 0;
 
 		m_numHandles--;
@@ -93,4 +100,10 @@
 	{
 		btSimpleBroadphaseProxy* proxy0 = static_cast<btSimpleBroadphaseProxy*>(proxy);
+		return proxy0;
+	}
+
+	inline const btSimpleBroadphaseProxy*	getSimpleProxyFromProxy(btBroadphaseProxy* proxy) const
+	{
+		const btSimpleBroadphaseProxy* proxy0 = static_cast<const btSimpleBroadphaseProxy*>(proxy);
 		return proxy0;
 	}
@@ -118,4 +131,7 @@
 	virtual void	destroyProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher);
 	virtual void	setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax, btDispatcher* dispatcher);
+	virtual void	getAabb(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const;
+
+	virtual void	rayTest(const btVector3& rayFrom,const btVector3& rayTo, btBroadphaseRayCallback& rayCallback, const btVector3& aabbMin=btVector3(0,0,0),const btVector3& aabbMax=btVector3(0,0,0));
 		
 	btOverlappingPairCache*	getOverlappingPairCache()
Index: code/branches/physics/src/bullet/BulletCollision/CMakeLists.txt
===================================================================
--- code/branches/physics/src/bullet/BulletCollision/CMakeLists.txt	(revision 2192)
+++ code/branches/physics/src/bullet/BulletCollision/CMakeLists.txt	(revision 2430)
@@ -1,150 +1,89 @@
-ADD_LIBRARY(LibBulletCollision
-				BroadphaseCollision/btAxisSweep3.cpp
-				BroadphaseCollision/btAxisSweep3.h
-				BroadphaseCollision/btBroadphaseProxy.cpp
-				BroadphaseCollision/btBroadphaseProxy.h
-				BroadphaseCollision/btCollisionAlgorithm.cpp
-				BroadphaseCollision/btCollisionAlgorithm.h
-				BroadphaseCollision/btDispatcher.cpp
-				BroadphaseCollision/btDispatcher.h
-				BroadphaseCollision/btDbvtBroadphase.cpp
-				BroadphaseCollision/btDbvtBroadphase.h
-				BroadphaseCollision/btDbvt.cpp
-				BroadphaseCollision/btDbvt.h
-				BroadphaseCollision/btMultiSapBroadphase.cpp
-				BroadphaseCollision/btMultiSapBroadphase.h
-				BroadphaseCollision/btOverlappingPairCache.cpp
-				BroadphaseCollision/btOverlappingPairCache.h
-				BroadphaseCollision/btOverlappingPairCallback.h
-				BroadphaseCollision/btQuantizedBvh.cpp
-				BroadphaseCollision/btQuantizedBvh.h
-				BroadphaseCollision/btSimpleBroadphase.cpp
-				BroadphaseCollision/btSimpleBroadphase.h
-				CollisionDispatch/btCollisionDispatcher.cpp
-				CollisionDispatch/btCollisionDispatcher.h
-				CollisionDispatch/btCollisionObject.cpp
-				CollisionDispatch/btCollisionObject.h
-				CollisionDispatch/btCollisionWorld.cpp
-				CollisionDispatch/btCollisionWorld.h
-				CollisionDispatch/btCompoundCollisionAlgorithm.cpp
-				CollisionDispatch/btCompoundCollisionAlgorithm.h
-				CollisionDispatch/btConvexConcaveCollisionAlgorithm.cpp
-				CollisionDispatch/btConvexConcaveCollisionAlgorithm.h
-				CollisionDispatch/btDefaultCollisionConfiguration.cpp
-				CollisionDispatch/btDefaultCollisionConfiguration.h
-				CollisionDispatch/btSphereSphereCollisionAlgorithm.cpp
-				CollisionDispatch/btSphereSphereCollisionAlgorithm.h
-				CollisionDispatch/btBoxBoxCollisionAlgorithm.cpp
-				CollisionDispatch/btBoxBoxCollisionAlgorithm.h
-				CollisionDispatch/btBoxBoxDetector.cpp
-				CollisionDispatch/btBoxBoxDetector.h
-				CollisionDispatch/btSphereBoxCollisionAlgorithm.cpp
-				CollisionDispatch/btSphereBoxCollisionAlgorithm.h
-				CollisionDispatch/btConvexPlaneCollisionAlgorithm.cpp
-				CollisionDispatch/btConvexPlaneCollisionAlgorithm.h
-				CollisionDispatch/btSphereTriangleCollisionAlgorithm.cpp
-				CollisionDispatch/btSphereTriangleCollisionAlgorithm.h
-				CollisionDispatch/btConvexConvexAlgorithm.cpp
-				CollisionDispatch/btConvexConvexAlgorithm.h
-				CollisionDispatch/btEmptyCollisionAlgorithm.cpp
-				CollisionDispatch/btEmptyCollisionAlgorithm.h
-				CollisionDispatch/btManifoldResult.cpp
-				CollisionDispatch/btManifoldResult.h
-				CollisionDispatch/btSimulationIslandManager.cpp
-				CollisionDispatch/btSimulationIslandManager.h
-				CollisionDispatch/btUnionFind.cpp
-				CollisionDispatch/btUnionFind.h
-				CollisionDispatch/SphereTriangleDetector.cpp
-				CollisionDispatch/SphereTriangleDetector.h
-				CollisionShapes/btBoxShape.cpp
-				CollisionShapes/btBoxShape.h
-				CollisionShapes/btBvhTriangleMeshShape.cpp
-				CollisionShapes/btBvhTriangleMeshShape.h
-				CollisionShapes/btCapsuleShape.cpp
-				CollisionShapes/btCapsuleShape.h
-				CollisionShapes/btCollisionShape.cpp
-				CollisionShapes/btCollisionShape.h
-				CollisionShapes/btCompoundShape.cpp
-				CollisionShapes/btCompoundShape.h
-				CollisionShapes/btConcaveShape.cpp
-				CollisionShapes/btConcaveShape.h
-				CollisionShapes/btConeShape.cpp
-				CollisionShapes/btConeShape.h
-				CollisionShapes/btConvexHullShape.cpp
-				CollisionShapes/btConvexHullShape.h
-				CollisionShapes/btConvexPointCloudShape.cpp
-				CollisionShapes/btConvexPointCloudShape.h
-				CollisionShapes/btConvexShape.cpp
-				CollisionShapes/btConvexShape.h
-				CollisionShapes/btConvexInternalShape.cpp
-				CollisionShapes/btConvexInternalShape.h
-				CollisionShapes/btConvexTriangleMeshShape.cpp
-				CollisionShapes/btConvexTriangleMeshShape.h
-				CollisionShapes/btCylinderShape.cpp
-				CollisionShapes/btCylinderShape.h
-				CollisionShapes/btEmptyShape.cpp
-				CollisionShapes/btEmptyShape.h
-				CollisionShapes/btHeightfieldTerrainShape.cpp
-				CollisionShapes/btHeightfieldTerrainShape.h
-				CollisionShapes/btMinkowskiSumShape.cpp
-				CollisionShapes/btMinkowskiSumShape.h
-				CollisionShapes/btMaterial.h
-				CollisionShapes/btMultimaterialTriangleMeshShape.cpp
-				CollisionShapes/btMultimaterialTriangleMeshShape.h
-				CollisionShapes/btMultiSphereShape.cpp
-				CollisionShapes/btMultiSphereShape.h
-				CollisionShapes/btOptimizedBvh.cpp
-				CollisionShapes/btOptimizedBvh.h
-				CollisionShapes/btPolyhedralConvexShape.cpp
-				CollisionShapes/btPolyhedralConvexShape.h
-				CollisionShapes/btScaledBvhTriangleMeshShape.cpp
-				CollisionShapes/btScaledBvhTriangleMeshShape.h
-				CollisionShapes/btTetrahedronShape.cpp
-				CollisionShapes/btTetrahedronShape.h
-				CollisionShapes/btSphereShape.cpp
-				CollisionShapes/btSphereShape.h
-				CollisionShapes/btShapeHull.h
-				CollisionShapes/btShapeHull.cpp
-				CollisionShapes/btStaticPlaneShape.cpp
-				CollisionShapes/btStaticPlaneShape.h
-				CollisionShapes/btStridingMeshInterface.cpp
-				CollisionShapes/btStridingMeshInterface.h
-				CollisionShapes/btTriangleCallback.cpp
-				CollisionShapes/btTriangleCallback.h
-				CollisionShapes/btTriangleBuffer.cpp
-				CollisionShapes/btTriangleBuffer.h
-				CollisionShapes/btTriangleIndexVertexArray.cpp
-				CollisionShapes/btTriangleIndexVertexArray.h
-				CollisionShapes/btTriangleIndexVertexMaterialArray.h
-				CollisionShapes/btTriangleIndexVertexMaterialArray.cpp
-				CollisionShapes/btTriangleMesh.cpp
-				CollisionShapes/btTriangleMesh.h
-				CollisionShapes/btTriangleMeshShape.cpp
-				CollisionShapes/btTriangleMeshShape.h
-				CollisionShapes/btUniformScalingShape.cpp
-				CollisionShapes/btUniformScalingShape.h
-				NarrowPhaseCollision/btContinuousConvexCollision.cpp
-				NarrowPhaseCollision/btContinuousConvexCollision.h
-				NarrowPhaseCollision/btGjkEpa.cpp
-				NarrowPhaseCollision/btGjkEpa.h
-				NarrowPhaseCollision/btGjkEpa2.cpp
-				NarrowPhaseCollision/btGjkEpa2.h
-				NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.cpp
-				NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h
-				NarrowPhaseCollision/btConvexCast.cpp
-				NarrowPhaseCollision/btConvexCast.h
-				NarrowPhaseCollision/btGjkConvexCast.cpp
-				NarrowPhaseCollision/btGjkConvexCast.h
-				NarrowPhaseCollision/btGjkPairDetector.cpp
-				NarrowPhaseCollision/btGjkPairDetector.h
-				NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.cpp
-				NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.h
-				NarrowPhaseCollision/btPersistentManifold.cpp
-				NarrowPhaseCollision/btPersistentManifold.h
-				NarrowPhaseCollision/btRaycastCallback.cpp
-				NarrowPhaseCollision/btRaycastCallback.h
-				NarrowPhaseCollision/btSubSimplexConvexCast.cpp
-				NarrowPhaseCollision/btSubSimplexConvexCast.h
-				NarrowPhaseCollision/btVoronoiSimplexSolver.cpp
-				NarrowPhaseCollision/btVoronoiSimplexSolver.h
+SET(BulletCollision_SRCS
+	BroadphaseCollision/btAxisSweep3.cpp
+	BroadphaseCollision/btBroadphaseProxy.cpp
+	BroadphaseCollision/btCollisionAlgorithm.cpp
+	BroadphaseCollision/btDispatcher.cpp
+	BroadphaseCollision/btDbvtBroadphase.cpp
+	BroadphaseCollision/btDbvt.cpp
+	BroadphaseCollision/btMultiSapBroadphase.cpp
+	BroadphaseCollision/btOverlappingPairCache.cpp
+	BroadphaseCollision/btQuantizedBvh.cpp
+	BroadphaseCollision/btSimpleBroadphase.cpp
+	CollisionDispatch/btActivatingCollisionAlgorithm.cpp
+	CollisionDispatch/btCollisionDispatcher.cpp
+	CollisionDispatch/btCollisionObject.cpp
+	CollisionDispatch/btCollisionWorld.cpp
+	CollisionDispatch/btCompoundCollisionAlgorithm.cpp
+	CollisionDispatch/btConvexConcaveCollisionAlgorithm.cpp
+	CollisionDispatch/btDefaultCollisionConfiguration.cpp
+	CollisionDispatch/btSphereSphereCollisionAlgorithm.cpp
+	CollisionDispatch/btBoxBoxCollisionAlgorithm.cpp
+	CollisionDispatch/btBoxBoxDetector.cpp
+	CollisionDispatch/btGhostObject.cpp
+	CollisionDispatch/btSphereBoxCollisionAlgorithm.cpp
+	CollisionDispatch/btConvexPlaneCollisionAlgorithm.cpp
+	CollisionDispatch/btSphereTriangleCollisionAlgorithm.cpp
+	CollisionDispatch/btConvexConvexAlgorithm.cpp
+	CollisionDispatch/btEmptyCollisionAlgorithm.cpp
+	CollisionDispatch/btManifoldResult.cpp
+	CollisionDispatch/btSimulationIslandManager.cpp
+	CollisionDispatch/btUnionFind.cpp
+	CollisionDispatch/SphereTriangleDetector.cpp
+	CollisionShapes/btBoxShape.cpp
+	CollisionShapes/btBvhTriangleMeshShape.cpp
+	CollisionShapes/btCapsuleShape.cpp
+	CollisionShapes/btCollisionShape.cpp
+	CollisionShapes/btCompoundShape.cpp
+	CollisionShapes/btConcaveShape.cpp
+	CollisionShapes/btConeShape.cpp
+	CollisionShapes/btConvexHullShape.cpp
+	CollisionShapes/btConvexPointCloudShape.cpp
+	CollisionShapes/btConvexShape.cpp
+	CollisionShapes/btConvexInternalShape.cpp
+	CollisionShapes/btConvexTriangleMeshShape.cpp
+	CollisionShapes/btCylinderShape.cpp
+	CollisionShapes/btEmptyShape.cpp
+	CollisionShapes/btHeightfieldTerrainShape.cpp
+	CollisionShapes/btMinkowskiSumShape.cpp
+	CollisionShapes/btMultimaterialTriangleMeshShape.cpp
+	CollisionShapes/btMultiSphereShape.cpp
+	CollisionShapes/btOptimizedBvh.cpp
+	CollisionShapes/btPolyhedralConvexShape.cpp
+	CollisionShapes/btScaledBvhTriangleMeshShape.cpp
+	CollisionShapes/btTetrahedronShape.cpp
+	CollisionShapes/btSphereShape.cpp
+	CollisionShapes/btShapeHull.cpp
+	CollisionShapes/btStaticPlaneShape.cpp
+	CollisionShapes/btStridingMeshInterface.cpp
+	CollisionShapes/btTriangleCallback.cpp
+	CollisionShapes/btTriangleBuffer.cpp
+	CollisionShapes/btTriangleIndexVertexArray.cpp
+	CollisionShapes/btTriangleIndexVertexMaterialArray.cpp
+	CollisionShapes/btTriangleMesh.cpp
+	CollisionShapes/btTriangleMeshShape.cpp
+	CollisionShapes/btUniformScalingShape.cpp
+	Gimpact/btContactProcessing.cpp
+	Gimpact/btGImpactShape.cpp
+	Gimpact/gim_contact.cpp
+	Gimpact/btGImpactBvh.cpp
+	Gimpact/btGenericPoolAllocator.cpp
+	Gimpact/gim_memory.cpp
+	Gimpact/btGImpactCollisionAlgorithm.cpp
+	Gimpact/btTriangleShapeEx.cpp
+	Gimpact/gim_tri_collision.cpp
+	Gimpact/btGImpactQuantizedBvh.cpp
+	Gimpact/gim_box_set.cpp
+	NarrowPhaseCollision/btContinuousConvexCollision.cpp
+	NarrowPhaseCollision/btGjkEpa2.cpp
+	NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.cpp
+	NarrowPhaseCollision/btConvexCast.cpp
+	NarrowPhaseCollision/btGjkConvexCast.cpp
+	NarrowPhaseCollision/btGjkPairDetector.cpp
+	NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.cpp
+	NarrowPhaseCollision/btPersistentManifold.cpp
+	NarrowPhaseCollision/btRaycastCallback.cpp
+	NarrowPhaseCollision/btSubSimplexConvexCast.cpp
+	NarrowPhaseCollision/btVoronoiSimplexSolver.cpp
 )
+
+ADD_LIBRARY(BulletCollision ${BulletCollision_SRCS})
Index: code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/SphereTriangleDetector.cpp
===================================================================
--- code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/SphereTriangleDetector.cpp	(revision 2192)
+++ code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/SphereTriangleDetector.cpp	(revision 2430)
@@ -20,7 +20,8 @@
 
 
-SphereTriangleDetector::SphereTriangleDetector(btSphereShape* sphere,btTriangleShape* triangle)
+SphereTriangleDetector::SphereTriangleDetector(btSphereShape* sphere,btTriangleShape* triangle,btScalar contactBreakingThreshold)
 :m_sphere(sphere),
-m_triangle(triangle)
+m_triangle(triangle),
+m_contactBreakingThreshold(contactBreakingThreshold)
 {
 
@@ -41,5 +42,5 @@
 	btTransform	sphereInTr = transformB.inverseTimes(transformA);
 
-	if (collide(sphereInTr.getOrigin(),point,normal,depth,timeOfImpact))
+	if (collide(sphereInTr.getOrigin(),point,normal,depth,timeOfImpact,m_contactBreakingThreshold))
 	{
 		if (swapResults)
@@ -94,5 +95,5 @@
 
 ///combined discrete/continuous sphere-triangle
-bool SphereTriangleDetector::collide(const btVector3& sphereCenter,btVector3 &point, btVector3& resultNormal, btScalar& depth, btScalar &timeOfImpact)
+bool SphereTriangleDetector::collide(const btVector3& sphereCenter,btVector3 &point, btVector3& resultNormal, btScalar& depth, btScalar &timeOfImpact, btScalar contactBreakingThreshold)
 {
 
@@ -116,8 +117,5 @@
 	}
 
-	///todo: move this gContactBreakingThreshold into a proper structure
-	extern btScalar gContactBreakingThreshold;
-
-	btScalar contactMargin = gContactBreakingThreshold;
+	btScalar contactMargin = contactBreakingThreshold;
 	bool isInsideContactPlane = distanceFromPlane < r + contactMargin;
 	bool isInsideShellPlane = distanceFromPlane < r;
@@ -141,6 +139,6 @@
 			for (int i = 0; i < m_triangle->getNumEdges(); i++) {
 				
-				btPoint3 pa;
-				btPoint3 pb;
+				btVector3 pa;
+				btVector3 pb;
 				
 				m_triangle->getEdge(i,pa,pb);
Index: code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/SphereTriangleDetector.h
===================================================================
--- code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/SphereTriangleDetector.h	(revision 2192)
+++ code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/SphereTriangleDetector.h	(revision 2430)
@@ -18,5 +18,5 @@
 
 #include "BulletCollision/NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h"
-#include "LinearMath/btPoint3.h"
+
 
 
@@ -31,5 +31,5 @@
 	virtual void	getClosestPoints(const ClosestPointInput& input,Result& output,class btIDebugDraw* debugDraw,bool swapResults=false);
 
-	SphereTriangleDetector(btSphereShape* sphere,btTriangleShape* triangle);
+	SphereTriangleDetector(btSphereShape* sphere,btTriangleShape* triangle, btScalar contactBreakingThreshold);
 
 	virtual ~SphereTriangleDetector() {};
@@ -37,5 +37,5 @@
 private:
 
-	bool collide(const btVector3& sphereCenter,btVector3 &point, btVector3& resultNormal, btScalar& depth, btScalar &timeOfImpact);
+	bool collide(const btVector3& sphereCenter,btVector3 &point, btVector3& resultNormal, btScalar& depth, btScalar &timeOfImpact, btScalar	contactBreakingThreshold);
 	bool pointInTriangle(const btVector3 vertices[], const btVector3 &normal, btVector3 *p );
 	bool facecontains(const btVector3 &p,const btVector3* vertices,btVector3& normal);
@@ -43,5 +43,5 @@
 	btSphereShape* m_sphere;
 	btTriangleShape* m_triangle;
-
+	btScalar	m_contactBreakingThreshold;
 	
 };
Index: code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btActivatingCollisionAlgorithm.cpp
===================================================================
--- code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btActivatingCollisionAlgorithm.cpp	(revision 2430)
+++ code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btActivatingCollisionAlgorithm.cpp	(revision 2430)
@@ -0,0 +1,47 @@
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2008 Erwin Coumans  http://bulletphysics.com
+
+This software is provided 'as-is', without any express or implied warranty.
+In no event will the authors be held liable for any damages arising from the use of this software.
+Permission is granted to anyone to use this software for any purpose, 
+including commercial applications, and to alter it and redistribute it freely, 
+subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+*/
+
+#include "btActivatingCollisionAlgorithm.h"
+#include "btCollisionDispatcher.h"
+#include "btCollisionObject.h"
+
+btActivatingCollisionAlgorithm::btActivatingCollisionAlgorithm (const btCollisionAlgorithmConstructionInfo& ci)
+:btCollisionAlgorithm(ci)
+//,
+//m_colObj0(0),
+//m_colObj1(0)
+{
+}
+btActivatingCollisionAlgorithm::btActivatingCollisionAlgorithm (const btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* colObj0,btCollisionObject* colObj1)
+:btCollisionAlgorithm(ci)
+//,
+//m_colObj0(0),
+//m_colObj1(0)
+{
+//	if (ci.m_dispatcher1->needsCollision(colObj0,colObj1))
+//	{
+//		m_colObj0 = colObj0;
+//		m_colObj1 = colObj1;
+//		
+//		m_colObj0->activate();
+//		m_colObj1->activate();
+//	}
+}
+
+btActivatingCollisionAlgorithm::~btActivatingCollisionAlgorithm()
+{
+//		m_colObj0->activate();
+//		m_colObj1->activate();
+}
Index: code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btActivatingCollisionAlgorithm.h
===================================================================
--- code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btActivatingCollisionAlgorithm.h	(revision 2430)
+++ code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btActivatingCollisionAlgorithm.h	(revision 2430)
@@ -0,0 +1,36 @@
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2008 Erwin Coumans  http://bulletphysics.com
+
+This software is provided 'as-is', without any express or implied warranty.
+In no event will the authors be held liable for any damages arising from the use of this software.
+Permission is granted to anyone to use this software for any purpose, 
+including commercial applications, and to alter it and redistribute it freely, 
+subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef __BT_ACTIVATING_COLLISION_ALGORITHM_H
+#define __BT_ACTIVATING_COLLISION_ALGORITHM_H
+
+#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"
+
+///This class is not enabled yet (work-in-progress) to more aggressively activate objects.
+class btActivatingCollisionAlgorithm : public btCollisionAlgorithm
+{
+//	btCollisionObject* m_colObj0;
+//	btCollisionObject* m_colObj1;
+
+public:
+
+	btActivatingCollisionAlgorithm (const btCollisionAlgorithmConstructionInfo& ci);
+
+	btActivatingCollisionAlgorithm (const btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* colObj0,btCollisionObject* colObj1);
+
+	virtual ~btActivatingCollisionAlgorithm();
+
+};
+#endif //__BT_ACTIVATING_COLLISION_ALGORITHM_H
Index: code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btBoxBoxCollisionAlgorithm.cpp
===================================================================
--- code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btBoxBoxCollisionAlgorithm.cpp	(revision 2192)
+++ code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btBoxBoxCollisionAlgorithm.cpp	(revision 2430)
@@ -23,5 +23,5 @@
 
 btBoxBoxCollisionAlgorithm::btBoxBoxCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* obj0,btCollisionObject* obj1)
-: btCollisionAlgorithm(ci),
+: btActivatingCollisionAlgorithm(ci,obj0,obj1),
 m_ownManifold(false),
 m_manifoldPtr(mf)
Index: code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btBoxBoxCollisionAlgorithm.h
===================================================================
--- code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btBoxBoxCollisionAlgorithm.h	(revision 2192)
+++ code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btBoxBoxCollisionAlgorithm.h	(revision 2430)
@@ -17,5 +17,5 @@
 #define BOX_BOX__COLLISION_ALGORITHM_H
 
-#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"
+#include "btActivatingCollisionAlgorithm.h"
 #include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
 #include "BulletCollision/BroadphaseCollision/btDispatcher.h"
@@ -25,5 +25,5 @@
 
 ///box-box collision detection
-class btBoxBoxCollisionAlgorithm : public btCollisionAlgorithm
+class btBoxBoxCollisionAlgorithm : public btActivatingCollisionAlgorithm
 {
 	bool	m_ownManifold;
@@ -32,5 +32,5 @@
 public:
 	btBoxBoxCollisionAlgorithm(const btCollisionAlgorithmConstructionInfo& ci)
-		: btCollisionAlgorithm(ci) {}
+		: btActivatingCollisionAlgorithm(ci) {}
 
 	virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
Index: code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btBoxBoxDetector.cpp
===================================================================
--- code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btBoxBoxDetector.cpp	(revision 2192)
+++ code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btBoxBoxDetector.cpp	(revision 2430)
@@ -208,5 +208,11 @@
     }
     q = p[n*2-2]*p[1] - p[0]*p[n*2-1];
-    a = 1.f/(btScalar(3.0)*(a+q));
+	if (btFabs(a+q) > SIMD_EPSILON)
+	{
+		a = 1.f/(btScalar(3.0)*(a+q));
+	} else
+	{
+		a=1e30f;
+	}
     cx = a*(cx + q*(p[n*2-2]+p[0]));
     cy = a*(cy + q*(p[n*2-1]+p[1]));
Index: code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btCollisionConfiguration.h
===================================================================
--- code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btCollisionConfiguration.h	(revision 2192)
+++ code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btCollisionConfiguration.h	(revision 2430)
@@ -23,5 +23,5 @@
 ///btCollisionConfiguration allows to configure Bullet collision detection
 ///stack allocator size, default collision algorithms and persistent manifold pool size
-///todo: describe the meaning
+///@todo: describe the meaning
 class	btCollisionConfiguration
 {
Index: code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btCollisionCreateFunc.h
===================================================================
--- code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btCollisionCreateFunc.h	(revision 2192)
+++ code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btCollisionCreateFunc.h	(revision 2430)
@@ -18,5 +18,4 @@
 
 #include "LinearMath/btAlignedObjectArray.h"
-typedef btAlignedObjectArray<class btCollisionObject*> btCollisionObjectArray;
 class btCollisionAlgorithm;
 class btCollisionObject;
Index: code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btCollisionDispatcher.cpp
===================================================================
--- code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btCollisionDispatcher.cpp	(revision 2192)
+++ code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btCollisionDispatcher.cpp	(revision 2430)
@@ -58,5 +58,5 @@
 	
 	
-};
+}
 
 
@@ -79,4 +79,6 @@
 	btCollisionObject* body0 = (btCollisionObject*)b0;
 	btCollisionObject* body1 = (btCollisionObject*)b1;
+
+	btScalar contactBreakingThreshold = btMin(gContactBreakingThreshold,btMin(body0->getCollisionShape()->getContactBreakingThreshold(),body1->getCollisionShape()->getContactBreakingThreshold()));
 	
 	void* mem = 0;
@@ -90,5 +92,5 @@
 
 	}
-	btPersistentManifold* manifold = new(mem) btPersistentManifold (body0,body1,0);
+	btPersistentManifold* manifold = new(mem) btPersistentManifold (body0,body1,0,contactBreakingThreshold);
 	manifold->m_index1a = m_manifoldsPtr.size();
 	m_manifoldsPtr.push_back(manifold);
Index: code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btCollisionObject.h
===================================================================
--- code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btCollisionObject.h	(revision 2192)
+++ code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btCollisionObject.h	(revision 2430)
@@ -30,5 +30,8 @@
 #include "LinearMath/btMotionState.h"
 #include "LinearMath/btAlignedAllocator.h"
-
+#include "LinearMath/btAlignedObjectArray.h"
+
+
+typedef btAlignedObjectArray<class btCollisionObject*> btCollisionObjectArray;
 
 
@@ -72,5 +75,5 @@
 	void*			m_userObjectPointer;
 
-	///m_internalType is reserved to distinguish Bullet's btCollisionObject, btRigidBody, btSoftBody etc.
+	///m_internalType is reserved to distinguish Bullet's btCollisionObject, btRigidBody, btSoftBody, btGhostObject etc.
 	///do not assign your own m_internalType unless you write a new dynamics object class.
 	int				m_internalType;
@@ -104,5 +107,6 @@
 		CF_KINEMATIC_OBJECT= 2,
 		CF_NO_CONTACT_RESPONSE = 4,
-		CF_CUSTOM_MATERIAL_CALLBACK = 8//this allows per-triangle material (friction/restitution)
+		CF_CUSTOM_MATERIAL_CALLBACK = 8,//this allows per-triangle material (friction/restitution)
+		CF_CHARACTER_OBJECT = 16
 	};
 
@@ -111,5 +115,8 @@
 		CO_COLLISION_OBJECT =1,
 		CO_RIGID_BODY,
-		CO_SOFT_BODY
+		CO_SOFT_BODY,
+		///CO_GHOST_OBJECT keeps track of all objects overlapping its AABB and that pass its collision filter
+		///It is useful for collision sensors, explosion objects, character controller etc.
+		CO_GHOST_OBJECT
 	};
 
@@ -177,5 +184,5 @@
 	}
 
-	int	getActivationState() const { return m_activationState1;}
+	SIMD_FORCE_INLINE	int	getActivationState() const { return m_activationState1;}
 	
 	void setActivationState(int newState);
@@ -194,5 +201,5 @@
 	void	activate(bool forceActivation = false);
 
-	inline bool isActive() const
+	SIMD_FORCE_INLINE bool isActive() const
 	{
 		return ((getActivationState() != ISLAND_SLEEPING) && (getActivationState() != DISABLE_SIMULATION));
@@ -238,10 +245,10 @@
 
 
-	btBroadphaseProxy*	getBroadphaseHandle()
+	SIMD_FORCE_INLINE btBroadphaseProxy*	getBroadphaseHandle()
 	{
 		return m_broadphaseHandle;
 	}
 
-	const btBroadphaseProxy*	getBroadphaseHandle() const
+	SIMD_FORCE_INLINE const btBroadphaseProxy*	getBroadphaseHandle() const
 	{
 		return m_broadphaseHandle;
@@ -289,5 +296,5 @@
 	}
 
-	const int getIslandTag() const
+	SIMD_FORCE_INLINE int getIslandTag() const
 	{
 		return	m_islandTag1;
@@ -299,5 +306,5 @@
 	}
 
-	const int getCompanionId() const
+	SIMD_FORCE_INLINE int getCompanionId() const
 	{
 		return	m_companionId;
@@ -309,5 +316,5 @@
 	}
 
-	const btScalar			getHitFraction() const
+	SIMD_FORCE_INLINE btScalar			getHitFraction() const
 	{
 		return m_hitFraction; 
@@ -320,5 +327,5 @@
 
 	
-	const int	getCollisionFlags() const
+	SIMD_FORCE_INLINE int	getCollisionFlags() const
 	{
 		return m_collisionFlags;
Index: code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btCollisionWorld.cpp
===================================================================
--- code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btCollisionWorld.cpp	(revision 2192)
+++ code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btCollisionWorld.cpp	(revision 2430)
@@ -33,4 +33,7 @@
 #include "LinearMath/btStackAlloc.h"
 
+//#define USE_BRUTEFORCE_RAYBROADPHASE 1
+//RECALCULATE_AABB is slower, but benefit is that you don't need to call 'stepSimulation'  or 'updateAabbs' before using a rayTest
+//#define RECALCULATE_AABB_RAYCAST 1
 
 //When the user doesn't provide dispatcher or broadphase, create basic versions (and delete them in destructor)
@@ -114,4 +117,6 @@
 }
 
+
+
 void	btCollisionWorld::updateAabbs()
 {
@@ -126,5 +131,5 @@
 		if (colObj->isActive())
 		{
-			btPoint3 minAabb,maxAabb;
+			btVector3 minAabb,maxAabb;
 			colObj->getCollisionShape()->getAabb(colObj->getWorldTransform(), minAabb,maxAabb);
 			//need to increase the aabb for contact thresholds
@@ -227,4 +232,5 @@
 	if (collisionShape->isConvex())
 	{
+//		BT_PROFILE("rayTestConvex");
 		btConvexCast::CastResult castResult;
 		castResult.m_fraction = resultCallback.m_closestHitFraction;
@@ -270,4 +276,5 @@
 		if (collisionShape->isConcave())
 		{
+//			BT_PROFILE("rayTestConcave");
 			if (collisionShape->getShapeType()==TRIANGLE_MESH_SHAPE_PROXYTYPE)
 			{
@@ -318,5 +325,6 @@
 			} else
 			{
-				btTriangleMeshShape* triangleMesh = (btTriangleMeshShape*)collisionShape;
+				//generic (slower) case
+				btConcaveShape* concaveShape = (btConcaveShape*)collisionShape;
 
 				btTransform worldTocollisionObject = colObjWorldTransform.inverse();
@@ -331,8 +339,8 @@
 					btCollisionWorld::RayResultCallback* m_resultCallback;
 					btCollisionObject*	m_collisionObject;
-					btTriangleMeshShape*	m_triangleMesh;
+					btConcaveShape*	m_triangleMesh;
 
 					BridgeTriangleRaycastCallback( const btVector3& from,const btVector3& to,
-						btCollisionWorld::RayResultCallback* resultCallback, btCollisionObject* collisionObject,btTriangleMeshShape*	triangleMesh):
+						btCollisionWorld::RayResultCallback* resultCallback, btCollisionObject* collisionObject,btConcaveShape*	triangleMesh):
 						btTriangleRaycastCallback(from,to),
 							m_resultCallback(resultCallback),
@@ -364,5 +372,5 @@
 
 
-				BridgeTriangleRaycastCallback	rcb(rayFromLocal,rayToLocal,&resultCallback,collisionObject,triangleMesh);
+				BridgeTriangleRaycastCallback	rcb(rayFromLocal,rayToLocal,&resultCallback,collisionObject,concaveShape);
 				rcb.m_hitFraction = resultCallback.m_closestHitFraction;
 
@@ -372,8 +380,9 @@
 				rayAabbMaxLocal.setMax(rayToLocal);
 
-				triangleMesh->processAllTriangles(&rcb,rayAabbMinLocal,rayAabbMaxLocal);
+				concaveShape->processAllTriangles(&rcb,rayAabbMinLocal,rayAabbMaxLocal);
 			}
 		} else {
-			//todo: use AABB tree or other BVH acceleration structure!
+//			BT_PROFILE("rayTestCompound");
+			///@todo: use AABB tree or other BVH acceleration structure, see btDbvt
 			if (collisionShape->isCompound())
 			{
@@ -409,7 +418,8 @@
 	if (collisionShape->isConvex())
 	{
+		//BT_PROFILE("convexSweepConvex");
 		btConvexCast::CastResult castResult;
 		castResult.m_allowedPenetration = allowedPenetration;
-		castResult.m_fraction = btScalar(1.);//??
+		castResult.m_fraction = resultCallback.m_closestHitFraction;//btScalar(1.);//??
 
 		btConvexShape* convexShape = (btConvexShape*) collisionShape;
@@ -453,4 +463,5 @@
 			if (collisionShape->getShapeType()==TRIANGLE_MESH_SHAPE_PROXYTYPE)
 			{
+				//BT_PROFILE("convexSweepbtBvhTriangleMesh");
 				btBvhTriangleMeshShape* triangleMesh = (btBvhTriangleMeshShape*)collisionShape;
 				btTransform worldTocollisionObject = colObjWorldTransform.inverse();
@@ -509,5 +520,6 @@
 			} else
 			{
-				btBvhTriangleMeshShape* triangleMesh = (btBvhTriangleMeshShape*)collisionShape;
+				//BT_PROFILE("convexSweepConcave");
+				btConcaveShape* concaveShape = (btConcaveShape*)collisionShape;
 				btTransform worldTocollisionObject = colObjWorldTransform.inverse();
 				btVector3 convexFromLocal = worldTocollisionObject * convexFromTrans.getOrigin();
@@ -521,8 +533,8 @@
 					btCollisionWorld::ConvexResultCallback* m_resultCallback;
 					btCollisionObject*	m_collisionObject;
-					btTriangleMeshShape*	m_triangleMesh;
+					btConcaveShape*	m_triangleMesh;
 
 					BridgeTriangleConvexcastCallback(const btConvexShape* castShape, const btTransform& from,const btTransform& to,
-						btCollisionWorld::ConvexResultCallback* resultCallback, btCollisionObject* collisionObject,btTriangleMeshShape*	triangleMesh, const btTransform& triangleToWorld):
+						btCollisionWorld::ConvexResultCallback* resultCallback, btCollisionObject* collisionObject,btConcaveShape*	triangleMesh, const btTransform& triangleToWorld):
 						btTriangleConvexcastCallback(castShape, from,to, triangleToWorld, triangleMesh->getMargin()),
 							m_resultCallback(resultCallback),
@@ -557,5 +569,5 @@
 				};
 
-				BridgeTriangleConvexcastCallback tccb(castShape, convexFromTrans,convexToTrans,&resultCallback,collisionObject,triangleMesh, colObjWorldTransform);
+				BridgeTriangleConvexcastCallback tccb(castShape, convexFromTrans,convexToTrans,&resultCallback,collisionObject,concaveShape, colObjWorldTransform);
 				tccb.m_hitFraction = resultCallback.m_closestHitFraction;
 				btVector3 boxMinLocal, boxMaxLocal;
@@ -568,10 +580,11 @@
 				rayAabbMinLocal += boxMinLocal;
 				rayAabbMaxLocal += boxMaxLocal;
-				triangleMesh->processAllTriangles(&tccb,rayAabbMinLocal,rayAabbMaxLocal);
+				concaveShape->processAllTriangles(&tccb,rayAabbMinLocal,rayAabbMaxLocal);
 			}
 		} else {
-			//todo: use AABB tree or other BVH acceleration structure!
+			///@todo : use AABB tree or other BVH acceleration structure!
 			if (collisionShape->isCompound())
 			{
+				BT_PROFILE("convexSweepCompound");
 				const btCompoundShape* compoundShape = static_cast<const btCompoundShape*>(collisionShape);
 				int i=0;
@@ -597,49 +610,170 @@
 }
 
-void	btCollisionWorld::rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, RayResultCallback& resultCallback) const
-{
-
-
-	btTransform	rayFromTrans,rayToTrans;
-	rayFromTrans.setIdentity();
-	rayFromTrans.setOrigin(rayFromWorld);
-	rayToTrans.setIdentity();
-
-	rayToTrans.setOrigin(rayToWorld);
-
-	/// go over all objects, and if the ray intersects their aabb, do a ray-shape query using convexCaster (CCD)
-
-	int i;
-	for (i=0;i<m_collisionObjects.size();i++)
+
+struct btSingleRayCallback : public btBroadphaseRayCallback
+{
+
+	btVector3	m_rayFromWorld;
+	btVector3	m_rayToWorld;
+	btTransform	m_rayFromTrans;
+	btTransform	m_rayToTrans;
+	btVector3	m_hitNormal;
+
+	const btCollisionWorld*	m_world;
+	btCollisionWorld::RayResultCallback&	m_resultCallback;
+
+	btSingleRayCallback(const btVector3& rayFromWorld,const btVector3& rayToWorld,const btCollisionWorld* world,btCollisionWorld::RayResultCallback& resultCallback)
+	:m_rayFromWorld(rayFromWorld),
+	m_rayToWorld(rayToWorld),
+	m_world(world),
+	m_resultCallback(resultCallback)
+	{
+		m_rayFromTrans.setIdentity();
+		m_rayFromTrans.setOrigin(m_rayFromWorld);
+		m_rayToTrans.setIdentity();
+		m_rayToTrans.setOrigin(m_rayToWorld);
+
+		btVector3 rayDir = (rayToWorld-rayFromWorld);
+
+		rayDir.normalize ();
+		///what about division by zero? --> just set rayDirection[i] to INF/1e30
+		m_rayDirectionInverse[0] = rayDir[0] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[0];
+		m_rayDirectionInverse[1] = rayDir[1] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[1];
+		m_rayDirectionInverse[2] = rayDir[2] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[2];
+		m_signs[0] = m_rayDirectionInverse[0] < 0.0;
+		m_signs[1] = m_rayDirectionInverse[1] < 0.0;
+		m_signs[2] = m_rayDirectionInverse[2] < 0.0;
+
+		m_lambda_max = rayDir.dot(m_rayToWorld-m_rayFromWorld);
+
+	}
+
+	
+
+	virtual bool	process(const btBroadphaseProxy* proxy)
 	{
 		///terminate further ray tests, once the closestHitFraction reached zero
-		if (resultCallback.m_closestHitFraction == btScalar(0.f))
-			break;
-
-		btCollisionObject*	collisionObject= m_collisionObjects[i];
+		if (m_resultCallback.m_closestHitFraction == btScalar(0.f))
+			return false;
+
+		btCollisionObject*	collisionObject = (btCollisionObject*)proxy->m_clientObject;
+
 		//only perform raycast if filterMask matches
-		if(resultCallback.needsCollision(collisionObject->getBroadphaseHandle())) {
+		if(m_resultCallback.needsCollision(collisionObject->getBroadphaseHandle())) 
+		{
 			//RigidcollisionObject* collisionObject = ctrl->GetRigidcollisionObject();
+			//btVector3 collisionObjectAabbMin,collisionObjectAabbMax;
+			
+#ifdef RECALCULATE_AABB
 			btVector3 collisionObjectAabbMin,collisionObjectAabbMax;
 			collisionObject->getCollisionShape()->getAabb(collisionObject->getWorldTransform(),collisionObjectAabbMin,collisionObjectAabbMax);
-
-			btScalar hitLambda = resultCallback.m_closestHitFraction;
-			btVector3 hitNormal;
-			if (btRayAabb(rayFromWorld,rayToWorld,collisionObjectAabbMin,collisionObjectAabbMax,hitLambda,hitNormal))
-			{
-				rayTestSingle(rayFromTrans,rayToTrans,
+#else
+			//getBroadphase()->getAabb(collisionObject->getBroadphaseHandle(),collisionObjectAabbMin,collisionObjectAabbMax);
+			const btVector3& collisionObjectAabbMin = collisionObject->getBroadphaseHandle()->m_aabbMin;
+			const btVector3& collisionObjectAabbMax = collisionObject->getBroadphaseHandle()->m_aabbMax;
+#endif
+			//btScalar hitLambda = m_resultCallback.m_closestHitFraction;
+			//culling already done by broadphase
+			//if (btRayAabb(m_rayFromWorld,m_rayToWorld,collisionObjectAabbMin,collisionObjectAabbMax,hitLambda,m_hitNormal))
+			{
+				m_world->rayTestSingle(m_rayFromTrans,m_rayToTrans,
 					collisionObject,
 						collisionObject->getCollisionShape(),
 						collisionObject->getWorldTransform(),
-						resultCallback);
+						m_resultCallback);
 			}
 		}
-
-	}
-
-}
-
-void	btCollisionWorld::convexSweepTest(const btConvexShape* castShape, const btTransform& convexFromWorld, const btTransform& convexToWorld, ConvexResultCallback& resultCallback) const
-{
+		return true;
+	}
+};
+
+void	btCollisionWorld::rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, RayResultCallback& resultCallback) const
+{
+	BT_PROFILE("rayTest");
+	/// use the broadphase to accelerate the search for objects, based on their aabb
+	/// and for each object with ray-aabb overlap, perform an exact ray test
+	btSingleRayCallback rayCB(rayFromWorld,rayToWorld,this,resultCallback);
+
+#ifndef USE_BRUTEFORCE_RAYBROADPHASE
+	m_broadphasePairCache->rayTest(rayFromWorld,rayToWorld,rayCB);
+#else
+	for (int i=0;i<this->getNumCollisionObjects();i++)
+	{
+		rayCB.process(m_collisionObjects[i]->getBroadphaseHandle());
+	}	
+#endif //USE_BRUTEFORCE_RAYBROADPHASE
+
+}
+
+
+struct btSingleSweepCallback : public btBroadphaseRayCallback
+{
+
+	btTransform	m_convexFromTrans;
+	btTransform	m_convexToTrans;
+	btVector3	m_hitNormal;
+	const btCollisionWorld*	m_world;
+	btCollisionWorld::ConvexResultCallback&	m_resultCallback;
+	btScalar	m_allowedCcdPenetration;
+	const btConvexShape* m_castShape;
+
+
+	btSingleSweepCallback(const btConvexShape* castShape, const btTransform& convexFromTrans,const btTransform& convexToTrans,const btCollisionWorld* world,btCollisionWorld::ConvexResultCallback& resultCallback,btScalar allowedPenetration)
+		:m_convexFromTrans(convexFromTrans),
+		m_convexToTrans(convexToTrans),
+		m_world(world),
+		m_resultCallback(resultCallback),
+		m_allowedCcdPenetration(allowedPenetration),
+		m_castShape(castShape)
+	{
+		btVector3 unnormalizedRayDir = (m_convexToTrans.getOrigin()-m_convexFromTrans.getOrigin());
+		btVector3 rayDir = unnormalizedRayDir.normalized();
+		///what about division by zero? --> just set rayDirection[i] to INF/1e30
+		m_rayDirectionInverse[0] = rayDir[0] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[0];
+		m_rayDirectionInverse[1] = rayDir[1] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[1];
+		m_rayDirectionInverse[2] = rayDir[2] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[2];
+		m_signs[0] = m_rayDirectionInverse[0] < 0.0;
+		m_signs[1] = m_rayDirectionInverse[1] < 0.0;
+		m_signs[2] = m_rayDirectionInverse[2] < 0.0;
+
+		m_lambda_max = rayDir.dot(unnormalizedRayDir);
+
+	}
+
+	virtual bool	process(const btBroadphaseProxy* proxy)
+	{
+		///terminate further convex sweep tests, once the closestHitFraction reached zero
+		if (m_resultCallback.m_closestHitFraction == btScalar(0.f))
+			return false;
+
+		btCollisionObject*	collisionObject = (btCollisionObject*)proxy->m_clientObject;
+
+		//only perform raycast if filterMask matches
+		if(m_resultCallback.needsCollision(collisionObject->getBroadphaseHandle())) {
+			//RigidcollisionObject* collisionObject = ctrl->GetRigidcollisionObject();
+			m_world->objectQuerySingle(m_castShape, m_convexFromTrans,m_convexToTrans,
+					collisionObject,
+						collisionObject->getCollisionShape(),
+						collisionObject->getWorldTransform(),
+						m_resultCallback,
+						m_allowedCcdPenetration);
+		}
+		
+		return true;
+	}
+};
+
+
+
+void	btCollisionWorld::convexSweepTest(const btConvexShape* castShape, const btTransform& convexFromWorld, const btTransform& convexToWorld, ConvexResultCallback& resultCallback, btScalar allowedCcdPenetration) const
+{
+
+	BT_PROFILE("convexSweepTest");
+	/// use the broadphase to accelerate the search for objects, based on their aabb
+	/// and for each object with ray-aabb overlap, perform an exact ray test
+	/// unfortunately the implementation for rayTest and convexSweepTest duplicated, albeit practically identical
+
+	
+
 	btTransform	convexFromTrans,convexToTrans;
 	convexFromTrans = convexFromWorld;
@@ -650,10 +784,19 @@
 		btVector3 linVel, angVel;
 		btTransformUtil::calculateVelocity (convexFromTrans, convexToTrans, 1.0, linVel, angVel);
+		btVector3 zeroLinVel;
+		zeroLinVel.setValue(0,0,0);
 		btTransform R;
 		R.setIdentity ();
 		R.setRotation (convexFromTrans.getRotation());
-		castShape->calculateTemporalAabb (R, linVel, angVel, 1.0, castShapeAabbMin, castShapeAabbMax);
-	}
-
+		castShape->calculateTemporalAabb (R, zeroLinVel, angVel, 1.0, castShapeAabbMin, castShapeAabbMax);
+	}
+
+#ifndef USE_BRUTEFORCE_RAYBROADPHASE
+
+	btSingleSweepCallback	convexCB(castShape,convexFromWorld,convexToWorld,this,resultCallback,allowedCcdPenetration);
+
+	m_broadphasePairCache->rayTest(convexFromTrans.getOrigin(),convexToTrans.getOrigin(),convexCB,castShapeAabbMin,castShapeAabbMax);
+
+#else
 	/// go over all objects, and if the ray intersects their aabb + cast shape aabb,
 	// do a ray-shape query using convexCaster (CCD)
@@ -677,8 +820,8 @@
 						collisionObject->getWorldTransform(),
 						resultCallback,
-						getDispatchInfo().m_allowedCcdPenetration);
+						allowedCcdPenetration);
 			}
 		}
 	}
-
-}
+#endif //USE_BRUTEFORCE_RAYBROADPHASE
+}
Index: code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btCollisionWorld.h
===================================================================
--- code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btCollisionWorld.h	(revision 2192)
+++ code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btCollisionWorld.h	(revision 2430)
@@ -1,5 +1,5 @@
 /*
 Bullet Continuous Collision Detection and Physics Library
-Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
+Copyright (c) 2003-2006 Erwin Coumans  http://bulletphysics.com/Bullet/
 
 This software is provided 'as-is', without any express or implied warranty.
@@ -23,19 +23,19 @@
  * Bullet is a Collision Detection and Rigid Body Dynamics Library. The Library is Open Source and free for commercial use, under the ZLib license ( http://opensource.org/licenses/zlib-license.php ).
  *
- * There is the Physics Forum for Feedback and bteral Collision Detection and Physics discussions.
- * Please visit http://www.continuousphysics.com/Bullet/phpBB2/index.php
+ * There is the Physics Forum for feedback and general Collision Detection and Physics discussions.
+ * Please visit http://www.bulletphysics.com
  *
  * @section install_sec Installation
  *
  * @subsection step1 Step 1: Download
- * You can download the Bullet Physics Library from our website: http://www.continuousphysics.com/Bullet/
+ * You can download the Bullet Physics Library from the Google Code repository: http://code.google.com/p/bullet/downloads/list
  * @subsection step2 Step 2: Building
  * Bullet comes with autogenerated Project Files for Microsoft Visual Studio 6, 7, 7.1 and 8.
  * The main Workspace/Solution is located in Bullet/msvc/8/wksbullet.sln (replace 8 with your version).
  * 
- * Under other platforms, like Linux or Mac OS-X, Bullet can be build using either using make, cmake, http://www.cmake.org, or jam, http://www.perforce.com/jam/jam.html . cmake can autogenerate Xcode, KDevelop, MSVC and other build systems. just run cmake . in the root of Bullet.
+ * Under other platforms, like Linux or Mac OS-X, Bullet can be build using either using make, cmake, http://www.cmake.org , or jam, http://www.perforce.com/jam/jam.html . cmake can autogenerate Xcode, KDevelop, MSVC and other build systems. just run cmake . in the root of Bullet.
  * So if you are not using MSVC or cmake, you can run ./autogen.sh ./configure to create both Makefile and Jamfile and then run make or jam.
  * Jam is a build system that can build the library, demos and also autogenerate the MSVC Project Files.
- * If you don't have jam installed, you can make jam from the included jam-2.5 sources, or download jam from ftp://ftp.perforce.com/pub/jam/
+ * If you don't have jam installed, you can make jam from the included jam-2.5 sources, or download jam from ftp://ftp.perforce.com/jam
  * 
  * @subsection step3 Step 3: Testing demos
@@ -72,5 +72,5 @@
 #include "LinearMath/btTransform.h"
 #include "btCollisionObject.h"
-#include "btCollisionDispatcher.h" //for definition of btCollisionObjectArray
+#include "btCollisionDispatcher.h"
 #include "BulletCollision/BroadphaseCollision/btOverlappingPairCache.h"
 #include "LinearMath/btAlignedObjectArray.h"
@@ -108,4 +108,9 @@
 	}
 
+	const btBroadphaseInterface*	getBroadphase() const
+	{
+		return m_broadphasePairCache;
+	}
+
 	btBroadphaseInterface*	getBroadphase()
 	{
@@ -131,4 +136,5 @@
 	virtual void	updateAabbs();
 
+	
 	virtual void	setDebugDrawer(btIDebugDraw*	debugDrawer)
 	{
@@ -348,5 +354,5 @@
 	// convexTest performs a swept convex cast on all objects in the btCollisionWorld, and calls the resultCallback
 	// This allows for several queries: first hit, all hits, any hit, dependent on the value return by the callback.
-	void    convexSweepTest (const btConvexShape* castShape, const btTransform& from, const btTransform& to, ConvexResultCallback& resultCallback) const;
+	void    convexSweepTest (const btConvexShape* castShape, const btTransform& from, const btTransform& to, ConvexResultCallback& resultCallback,  btScalar allowedCcdPenetration = btScalar(0.)) const;
 
 
Index: code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.cpp
===================================================================
--- code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.cpp	(revision 2192)
+++ code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.cpp	(revision 2430)
@@ -22,5 +22,5 @@
 
 btCompoundCollisionAlgorithm::btCompoundCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1,bool isSwapped)
-:btCollisionAlgorithm(ci),
+:btActivatingCollisionAlgorithm(ci,body0,body1),
 m_isSwapped(isSwapped),
 m_sharedManifold(ci.m_manifold)
Index: code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.h
===================================================================
--- code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.h	(revision 2192)
+++ code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.h	(revision 2430)
@@ -17,5 +17,5 @@
 #define COMPOUND_COLLISION_ALGORITHM_H
 
-#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"
+#include "btActivatingCollisionAlgorithm.h"
 #include "BulletCollision/BroadphaseCollision/btDispatcher.h"
 #include "BulletCollision/BroadphaseCollision/btBroadphaseInterface.h"
@@ -29,5 +29,5 @@
 
 /// btCompoundCollisionAlgorithm  supports collision between CompoundCollisionShapes and other collision shapes
-class btCompoundCollisionAlgorithm  : public btCollisionAlgorithm
+class btCompoundCollisionAlgorithm  : public btActivatingCollisionAlgorithm
 {
 	btAlignedObjectArray<btCollisionAlgorithm*> m_childCollisionAlgorithms;
Index: code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.cpp
===================================================================
--- code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.cpp	(revision 2192)
+++ code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.cpp	(revision 2430)
@@ -28,5 +28,5 @@
 
 btConvexConcaveCollisionAlgorithm::btConvexConcaveCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1,bool isSwapped)
-: btCollisionAlgorithm(ci),
+: btActivatingCollisionAlgorithm(ci,body0,body1),
 m_isSwapped(isSwapped),
 m_btConvexTriangleCallback(ci.m_dispatcher1,body0,body1,isSwapped)
@@ -73,5 +73,5 @@
 {
 	m_dispatcher->clearManifold(m_manifoldPtr);
-};
+}
 
 
@@ -94,5 +94,5 @@
 	
 	///debug drawing of the overlapping triangles
-	if (m_dispatchInfoPtr && m_dispatchInfoPtr->m_debugDraw && m_dispatchInfoPtr->m_debugDraw->getDebugMode() > 0)
+	if (m_dispatchInfoPtr && m_dispatchInfoPtr->m_debugDraw && (m_dispatchInfoPtr->m_debugDraw->getDebugMode() &btIDebugDraw::DBG_DrawWireframe ))
 	{
 		btVector3 color(255,255,0);
Index: code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.h
===================================================================
--- code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.h	(revision 2192)
+++ code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.h	(revision 2430)
@@ -17,5 +17,5 @@
 #define CONVEX_CONCAVE_COLLISION_ALGORITHM_H
 
-#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"
+#include "btActivatingCollisionAlgorithm.h"
 #include "BulletCollision/BroadphaseCollision/btDispatcher.h"
 #include "BulletCollision/BroadphaseCollision/btBroadphaseInterface.h"
@@ -35,6 +35,6 @@
 	btVector3	m_aabbMax ;
 
+
 	btManifoldResult* m_resultOut;
-
 	btDispatcher*	m_dispatcher;
 	const btDispatcherInfo* m_dispatchInfoPtr;
@@ -71,5 +71,5 @@
 
 /// btConvexConcaveCollisionAlgorithm  supports collision between convex shapes and (concave) trianges meshes.
-class btConvexConcaveCollisionAlgorithm  : public btCollisionAlgorithm
+class btConvexConcaveCollisionAlgorithm  : public btActivatingCollisionAlgorithm
 {
 
@@ -77,4 +77,5 @@
 
 	btConvexTriangleCallback m_btConvexTriangleCallback;
+
 
 
Index: code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.cpp
===================================================================
--- code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.cpp	(revision 2192)
+++ code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.cpp	(revision 2430)
@@ -39,5 +39,5 @@
 #include "BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.h"
 
-#include "BulletCollision/NarrowPhaseCollision/btGjkEpa.h"
+#include "BulletCollision/NarrowPhaseCollision/btGjkEpa2.h"
 #include "BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h"
 
@@ -61,14 +61,17 @@
 
 btConvexConvexAlgorithm::btConvexConvexAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1,btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* pdSolver)
-: btCollisionAlgorithm(ci),
-m_gjkPairDetector(0,0,simplexSolver,pdSolver),
+: btActivatingCollisionAlgorithm(ci,body0,body1),
+m_simplexSolver(simplexSolver),
+m_pdSolver(pdSolver),
 m_ownManifold (false),
 m_manifoldPtr(mf),
 m_lowLevelOfDetail(false)
+#ifdef USE_SEPDISTANCE_UTIL2
+,m_sepDistance((static_cast<btConvexShape*>(body0->getCollisionShape()))->getAngularMotionDisc(),
+			  (static_cast<btConvexShape*>(body1->getCollisionShape()))->getAngularMotionDisc())
+#endif
 {
 	(void)body0;
 	(void)body1;
-
-
 }
 
@@ -108,37 +111,52 @@
 	resultOut->setPersistentManifold(m_manifoldPtr);
 
-#ifdef USE_BT_GJKEPA
-	btConvexShape*				shape0(static_cast<btConvexShape*>(body0->getCollisionShape()));
-	btConvexShape*				shape1(static_cast<btConvexShape*>(body1->getCollisionShape()));
-	const btScalar				radialmargin(0/*shape0->getMargin()+shape1->getMargin()*/);
-	btGjkEpaSolver::sResults	results;
-	if(btGjkEpaSolver::Collide(	shape0,body0->getWorldTransform(),
-								shape1,body1->getWorldTransform(),
-								radialmargin,results))
-		{
-		dispatchInfo.m_debugDraw->drawLine(results.witnesses[1],results.witnesses[1]+results.normal,btVector3(255,0,0));
-		resultOut->addContactPoint(results.normal,results.witnesses[1],-results.depth);
-		}
-#else
+	
 
 	btConvexShape* min0 = static_cast<btConvexShape*>(body0->getCollisionShape());
 	btConvexShape* min1 = static_cast<btConvexShape*>(body1->getCollisionShape());
+
+#ifdef USE_SEPDISTANCE_UTIL2
+	m_sepDistance.updateSeparatingDistance(body0->getWorldTransform(),body1->getWorldTransform());
+	if (!dispatchInfo.m_useConvexConservativeDistanceUtil || m_sepDistance.getConservativeSeparatingDistance()<=0.f)
+#endif //USE_SEPDISTANCE_UTIL2
+
+	{
+
 	
 	btGjkPairDetector::ClosestPointInput input;
 
+	btGjkPairDetector	gjkPairDetector(min0,min1,m_simplexSolver,m_pdSolver);
 	//TODO: if (dispatchInfo.m_useContinuous)
-	m_gjkPairDetector.setMinkowskiA(min0);
-	m_gjkPairDetector.setMinkowskiB(min1);
-	input.m_maximumDistanceSquared = min0->getMargin() + min1->getMargin() + m_manifoldPtr->getContactBreakingThreshold();
-	input.m_maximumDistanceSquared*= input.m_maximumDistanceSquared;
+	gjkPairDetector.setMinkowskiA(min0);
+	gjkPairDetector.setMinkowskiB(min1);
+
+#ifdef USE_SEPDISTANCE_UTIL2
+	if (dispatchInfo.m_useConvexConservativeDistanceUtil)
+	{
+		input.m_maximumDistanceSquared = 1e30f;
+	} else
+#endif //USE_SEPDISTANCE_UTIL2
+	{
+		input.m_maximumDistanceSquared = min0->getMargin() + min1->getMargin() + m_manifoldPtr->getContactBreakingThreshold();
+		input.m_maximumDistanceSquared*= input.m_maximumDistanceSquared;
+	}
+
 	input.m_stackAlloc = dispatchInfo.m_stackAllocator;
-
-//	input.m_maximumDistanceSquared = btScalar(1e30);
-	
 	input.m_transformA = body0->getWorldTransform();
 	input.m_transformB = body1->getWorldTransform();
-	
-	m_gjkPairDetector.getClosestPoints(input,*resultOut,dispatchInfo.m_debugDraw);
-#endif
+
+	gjkPairDetector.getClosestPoints(input,*resultOut,dispatchInfo.m_debugDraw);
+
+	btScalar sepDist = gjkPairDetector.getCachedSeparatingDistance()+dispatchInfo.m_convexConservativeDistanceThreshold;
+
+#ifdef USE_SEPDISTANCE_UTIL2
+	if (dispatchInfo.m_useConvexConservativeDistanceUtil)
+	{
+		m_sepDistance.initSeparatingDistance(gjkPairDetector.getCachedSeparatingAxis(),sepDist,body0->getWorldTransform(),body1->getWorldTransform());
+	}
+#endif //USE_SEPDISTANCE_UTIL2
+
+
+	}
 
 	if (m_ownManifold)
Index: code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.h
===================================================================
--- code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.h	(revision 2192)
+++ code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.h	(revision 2430)
@@ -17,5 +17,5 @@
 #define CONVEX_CONVEX_ALGORITHM_H
 
-#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"
+#include "btActivatingCollisionAlgorithm.h"
 #include "BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h"
 #include "BulletCollision/NarrowPhaseCollision/btPersistentManifold.h"
@@ -24,16 +24,29 @@
 #include "btCollisionCreateFunc.h"
 #include "btCollisionDispatcher.h"
+#include "LinearMath/btTransformUtil.h" //for btConvexSeparatingDistanceUtil
 
 class btConvexPenetrationDepthSolver;
 
+///Enabling USE_SEPDISTANCE_UTIL2 requires 100% reliable distance computation. However, when using large size ratios GJK can be imprecise
+///so the distance is not conservative. In that case, enabling this USE_SEPDISTANCE_UTIL2 would result in failing/missing collisions.
+///Either improve GJK for large size ratios (testing a 100 units versus a 0.1 unit object) or only enable the util
+///for certain pairs that have a small size ratio
+///#define USE_SEPDISTANCE_UTIL2 1
+
 ///ConvexConvexAlgorithm collision algorithm implements time of impact, convex closest points and penetration depth calculations.
-class btConvexConvexAlgorithm : public btCollisionAlgorithm
+class btConvexConvexAlgorithm : public btActivatingCollisionAlgorithm
 {
-	btGjkPairDetector m_gjkPairDetector;
-public:
+#ifdef USE_SEPDISTANCE_UTIL2
+	btConvexSeparatingDistanceUtil	m_sepDistance;
+#endif
+	btSimplexSolverInterface*		m_simplexSolver;
+	btConvexPenetrationDepthSolver* m_pdSolver;
 
+	
 	bool	m_ownManifold;
 	btPersistentManifold*	m_manifoldPtr;
 	bool			m_lowLevelOfDetail;
+	
+	///cache separating vector to speedup collision detection
 	
 
Index: code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.cpp
===================================================================
--- code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.cpp	(revision 2192)
+++ code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.cpp	(revision 2430)
@@ -101,9 +101,8 @@
 	int maxSize2 = sizeof(btConvexConcaveCollisionAlgorithm);
 	int maxSize3 = sizeof(btCompoundCollisionAlgorithm);
-	int maxSize4 = sizeof(btEmptyAlgorithm);
-	
+	int sl = sizeof(btConvexSeparatingDistanceUtil);
+	sl = sizeof(btGjkPairDetector);
 	int	collisionAlgorithmMaxElementSize = btMax(maxSize,maxSize2);
 	collisionAlgorithmMaxElementSize = btMax(collisionAlgorithmMaxElementSize,maxSize3);
-	collisionAlgorithmMaxElementSize = btMax(collisionAlgorithmMaxElementSize,maxSize4);
 
 	if (constructionInfo.m_stackAlloc)
Index: code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.h
===================================================================
--- code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.h	(revision 2192)
+++ code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.h	(revision 2430)
@@ -34,7 +34,7 @@
 		m_persistentManifoldPool(0),
 		m_collisionAlgorithmPool(0),
-		m_defaultMaxPersistentManifoldPoolSize(65535),
-		m_defaultMaxCollisionAlgorithmPoolSize(65535),
-		m_defaultStackAllocatorSize(5*1024*1024)
+		m_defaultMaxPersistentManifoldPoolSize(4096),
+		m_defaultMaxCollisionAlgorithmPoolSize(4096),
+		m_defaultStackAllocatorSize(0)
 	{
 	}
@@ -45,5 +45,5 @@
 ///btCollisionConfiguration allows to configure Bullet collision detection
 ///stack allocator, pool memory allocators
-///todo: describe the meaning
+///@todo: describe the meaning
 class	btDefaultCollisionConfiguration : public btCollisionConfiguration
 {
Index: code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btGhostObject.cpp
===================================================================
--- code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btGhostObject.cpp	(revision 2430)
+++ code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btGhostObject.cpp	(revision 2430)
@@ -0,0 +1,170 @@
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2008 Erwin Coumans  http://bulletphysics.com
+
+This software is provided 'as-is', without any express or implied warranty.
+In no event will the authors be held liable for any damages arising from the use of this software.
+Permission is granted to anyone to use this software for any purpose, 
+including commercial applications, and to alter it and redistribute it freely, 
+subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+*/
+
+#include "btGhostObject.h"
+#include "btCollisionWorld.h"
+#include "BulletCollision/CollisionShapes/btConvexShape.h"
+#include "LinearMath/btAabbUtil2.h"
+
+btGhostObject::btGhostObject()
+{
+	m_internalType = CO_GHOST_OBJECT;
+}
+
+btGhostObject::~btGhostObject()
+{
+	///btGhostObject should have been removed from the world, so no overlapping objects
+	btAssert(!m_overlappingObjects.size());
+}
+
+
+void btGhostObject::addOverlappingObjectInternal(btBroadphaseProxy* otherProxy,btBroadphaseProxy* thisProxy)
+{
+	btCollisionObject* otherObject = (btCollisionObject*)otherProxy->m_clientObject;
+	btAssert(otherObject);
+	///if this linearSearch becomes too slow (too many overlapping objects) we should add a more appropriate data structure
+	int index = m_overlappingObjects.findLinearSearch(otherObject);
+	if (index==m_overlappingObjects.size())
+	{
+		//not found
+		m_overlappingObjects.push_back(otherObject);
+	}
+}
+
+void btGhostObject::removeOverlappingObjectInternal(btBroadphaseProxy* otherProxy,btDispatcher* dispatcher,btBroadphaseProxy* thisProxy)
+{
+	btCollisionObject* otherObject = (btCollisionObject*)otherProxy->m_clientObject;
+	btAssert(otherObject);
+	int index = m_overlappingObjects.findLinearSearch(otherObject);
+	if (index<m_overlappingObjects.size())
+	{
+		m_overlappingObjects[index] = m_overlappingObjects[m_overlappingObjects.size()-1];
+		m_overlappingObjects.pop_back();
+	}
+}
+
+
+btPairCachingGhostObject::btPairCachingGhostObject()
+{
+	m_hashPairCache = new (btAlignedAlloc(sizeof(btHashedOverlappingPairCache),16)) btHashedOverlappingPairCache();
+}
+
+btPairCachingGhostObject::~btPairCachingGhostObject()
+{
+	btAlignedFree( m_hashPairCache );
+}
+
+void btPairCachingGhostObject::addOverlappingObjectInternal(btBroadphaseProxy* otherProxy,btBroadphaseProxy* thisProxy)
+{
+	btBroadphaseProxy*actualThisProxy = thisProxy ? thisProxy : getBroadphaseHandle();
+	btAssert(actualThisProxy);
+
+	btCollisionObject* otherObject = (btCollisionObject*)otherProxy->m_clientObject;
+	btAssert(otherObject);
+	int index = m_overlappingObjects.findLinearSearch(otherObject);
+	if (index==m_overlappingObjects.size())
+	{
+		m_overlappingObjects.push_back(otherObject);
+		m_hashPairCache->addOverlappingPair(actualThisProxy,otherProxy);
+	}
+}
+
+void btPairCachingGhostObject::removeOverlappingObjectInternal(btBroadphaseProxy* otherProxy,btDispatcher* dispatcher,btBroadphaseProxy* thisProxy1)
+{
+	btCollisionObject* otherObject = (btCollisionObject*)otherProxy->m_clientObject;
+	btBroadphaseProxy* actualThisProxy = thisProxy1 ? thisProxy1 : getBroadphaseHandle();
+	btAssert(actualThisProxy);
+
+	btAssert(otherObject);
+	int index = m_overlappingObjects.findLinearSearch(otherObject);
+	if (index<m_overlappingObjects.size())
+	{
+		m_overlappingObjects[index] = m_overlappingObjects[m_overlappingObjects.size()-1];
+		m_overlappingObjects.pop_back();
+		m_hashPairCache->removeOverlappingPair(actualThisProxy,otherProxy,dispatcher);
+	}
+}
+
+
+void	btGhostObject::convexSweepTest(const btConvexShape* castShape, const btTransform& convexFromWorld, const btTransform& convexToWorld, btCollisionWorld::ConvexResultCallback& resultCallback, btScalar allowedCcdPenetration) const
+{
+	btTransform	convexFromTrans,convexToTrans;
+	convexFromTrans = convexFromWorld;
+	convexToTrans = convexToWorld;
+	btVector3 castShapeAabbMin, castShapeAabbMax;
+	/* Compute AABB that encompasses angular movement */
+	{
+		btVector3 linVel, angVel;
+		btTransformUtil::calculateVelocity (convexFromTrans, convexToTrans, 1.0, linVel, angVel);
+		btTransform R;
+		R.setIdentity ();
+		R.setRotation (convexFromTrans.getRotation());
+		castShape->calculateTemporalAabb (R, linVel, angVel, 1.0, castShapeAabbMin, castShapeAabbMax);
+	}
+
+	/// go over all objects, and if the ray intersects their aabb + cast shape aabb,
+	// do a ray-shape query using convexCaster (CCD)
+	int i;
+	for (i=0;i<m_overlappingObjects.size();i++)
+	{
+		btCollisionObject*	collisionObject= m_overlappingObjects[i];
+		//only perform raycast if filterMask matches
+		if(resultCallback.needsCollision(collisionObject->getBroadphaseHandle())) {
+			//RigidcollisionObject* collisionObject = ctrl->GetRigidcollisionObject();
+			btVector3 collisionObjectAabbMin,collisionObjectAabbMax;
+			collisionObject->getCollisionShape()->getAabb(collisionObject->getWorldTransform(),collisionObjectAabbMin,collisionObjectAabbMax);
+			AabbExpand (collisionObjectAabbMin, collisionObjectAabbMax, castShapeAabbMin, castShapeAabbMax);
+			btScalar hitLambda = btScalar(1.); //could use resultCallback.m_closestHitFraction, but needs testing
+			btVector3 hitNormal;
+			if (btRayAabb(convexFromWorld.getOrigin(),convexToWorld.getOrigin(),collisionObjectAabbMin,collisionObjectAabbMax,hitLambda,hitNormal))
+			{
+				btCollisionWorld::objectQuerySingle(castShape, convexFromTrans,convexToTrans,
+					collisionObject,
+						collisionObject->getCollisionShape(),
+						collisionObject->getWorldTransform(),
+						resultCallback,
+						allowedCcdPenetration);
+			}
+		}
+	}
+
+}
+
+void	btGhostObject::rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, btCollisionWorld::RayResultCallback& resultCallback) const
+{
+	btTransform rayFromTrans;
+	rayFromTrans.setIdentity();
+	rayFromTrans.setOrigin(rayFromWorld);
+	btTransform  rayToTrans;
+	rayToTrans.setIdentity();
+	rayToTrans.setOrigin(rayToWorld);
+
+
+	int i;
+	for (i=0;i<m_overlappingObjects.size();i++)
+	{
+		btCollisionObject*	collisionObject= m_overlappingObjects[i];
+		//only perform raycast if filterMask matches
+		if(resultCallback.needsCollision(collisionObject->getBroadphaseHandle())) 
+		{
+			btCollisionWorld::rayTestSingle(rayFromTrans,rayToTrans,
+							collisionObject,
+								collisionObject->getCollisionShape(),
+								collisionObject->getWorldTransform(),
+								resultCallback);
+		}
+	}
+}
+
Index: code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btGhostObject.h
===================================================================
--- code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btGhostObject.h	(revision 2430)
+++ code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btGhostObject.h	(revision 2430)
@@ -0,0 +1,174 @@
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2008 Erwin Coumans  http://bulletphysics.com
+
+This software is provided 'as-is', without any express or implied warranty.
+In no event will the authors be held liable for any damages arising from the use of this software.
+Permission is granted to anyone to use this software for any purpose, 
+including commercial applications, and to alter it and redistribute it freely, 
+subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef BT_GHOST_OBJECT_H
+#define BT_GHOST_OBJECT_H
+
+
+#include "btCollisionObject.h"
+#include "BulletCollision/BroadphaseCollision/btOverlappingPairCallback.h"
+#include "LinearMath/btAlignedAllocator.h"
+#include "BulletCollision/BroadphaseCollision/btOverlappingPairCache.h"
+#include "btCollisionWorld.h"
+
+class btConvexShape;
+
+class btDispatcher;
+
+///The btGhostObject can keep track of all objects that are overlapping
+///By default, this overlap is based on the AABB
+///This is useful for creating a character controller, collision sensors/triggers, explosions etc.
+///We plan on adding rayTest and other queries for the btGhostObject
+ATTRIBUTE_ALIGNED16(class) btGhostObject : public btCollisionObject
+{
+protected:
+
+	btAlignedObjectArray<btCollisionObject*> m_overlappingObjects;
+
+public:
+
+	btGhostObject();
+
+	virtual ~btGhostObject();
+
+	void	convexSweepTest(const class btConvexShape* castShape, const btTransform& convexFromWorld, const btTransform& convexToWorld, btCollisionWorld::ConvexResultCallback& resultCallback, btScalar allowedCcdPenetration = 0.f) const;
+
+	void	rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, btCollisionWorld::RayResultCallback& resultCallback) const; 
+
+	///this method is mainly for expert/internal use only.
+	virtual void	addOverlappingObjectInternal(btBroadphaseProxy* otherProxy, btBroadphaseProxy* thisProxy=0);
+	///this method is mainly for expert/internal use only.
+	virtual void	removeOverlappingObjectInternal(btBroadphaseProxy* otherProxy,btDispatcher* dispatcher,btBroadphaseProxy* thisProxy=0);
+
+	int	getNumOverlappingObjects() const
+	{
+		return m_overlappingObjects.size();
+	}
+
+	btCollisionObject*	getOverlappingObject(int index)
+	{
+		return m_overlappingObjects[index];
+	}
+
+	const btCollisionObject*	getOverlappingObject(int index) const
+	{
+		return m_overlappingObjects[index];
+	}
+
+	btAlignedObjectArray<btCollisionObject*>&	getOverlappingPairs()
+	{
+		return m_overlappingObjects;
+	}
+
+	const btAlignedObjectArray<btCollisionObject*>	getOverlappingPairs() const
+	{
+		return m_overlappingObjects;
+	}
+
+	//
+	// internal cast
+	//
+
+	static const btGhostObject*	upcast(const btCollisionObject* colObj)
+	{
+		if (colObj->getInternalType()==CO_GHOST_OBJECT)
+			return (const btGhostObject*)colObj;
+		return 0;
+	}
+	static btGhostObject*			upcast(btCollisionObject* colObj)
+	{
+		if (colObj->getInternalType()==CO_GHOST_OBJECT)
+			return (btGhostObject*)colObj;
+		return 0;
+	}
+
+};
+
+class	btPairCachingGhostObject : public btGhostObject
+{
+	btHashedOverlappingPairCache*	m_hashPairCache;
+
+public:
+
+	btPairCachingGhostObject();
+
+	virtual ~btPairCachingGhostObject();
+
+	///this method is mainly for expert/internal use only.
+	virtual void	addOverlappingObjectInternal(btBroadphaseProxy* otherProxy, btBroadphaseProxy* thisProxy=0);
+
+	virtual void	removeOverlappingObjectInternal(btBroadphaseProxy* otherProxy,btDispatcher* dispatcher,btBroadphaseProxy* thisProxy=0);
+
+	btHashedOverlappingPairCache*	getOverlappingPairCache()
+	{
+		return m_hashPairCache;
+	}
+
+};
+
+
+
+///The btGhostPairCallback interfaces and forwards adding and removal of overlapping pairs from the btBroadphaseInterface to btGhostObject.
+class btGhostPairCallback : public btOverlappingPairCallback
+{
+	
+public:
+	btGhostPairCallback()
+	{
+	}
+
+	virtual ~btGhostPairCallback()
+	{
+		
+	}
+
+	virtual btBroadphasePair*	addOverlappingPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1)
+	{
+		btCollisionObject* colObj0 = (btCollisionObject*) proxy0->m_clientObject;
+		btCollisionObject* colObj1 = (btCollisionObject*) proxy1->m_clientObject;
+		btGhostObject* ghost0 = 		btGhostObject::upcast(colObj0);
+		btGhostObject* ghost1 = 		btGhostObject::upcast(colObj1);
+		if (ghost0)
+			ghost0->addOverlappingObjectInternal(proxy1, proxy0);
+		if (ghost1)
+			ghost1->addOverlappingObjectInternal(proxy0, proxy1);
+		return 0;
+	}
+
+	virtual void*	removeOverlappingPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1,btDispatcher* dispatcher)
+	{
+		btCollisionObject* colObj0 = (btCollisionObject*) proxy0->m_clientObject;
+		btCollisionObject* colObj1 = (btCollisionObject*) proxy1->m_clientObject;
+		btGhostObject* ghost0 = 		btGhostObject::upcast(colObj0);
+		btGhostObject* ghost1 = 		btGhostObject::upcast(colObj1);
+		if (ghost0)
+			ghost0->removeOverlappingObjectInternal(proxy1,dispatcher,proxy0);
+		if (ghost1)
+			ghost1->removeOverlappingObjectInternal(proxy0,dispatcher,proxy1);
+		return 0;
+	}
+
+	virtual void	removeOverlappingPairsContainingProxy(btBroadphaseProxy* proxy0,btDispatcher* dispatcher)
+	{
+		btAssert(0);
+		//need to keep track of all ghost objects and call them here
+		//m_hashPairCache->removeOverlappingPairsContainingProxy(proxy0,dispatcher);
+	}
+
+	
+
+};
+
+#endif
Index: code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btManifoldResult.cpp
===================================================================
--- code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btManifoldResult.cpp	(revision 2192)
+++ code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btManifoldResult.cpp	(revision 2430)
@@ -94,5 +94,5 @@
    newPt.m_index1  = m_index1;
 	
-	///todo, check this for any side effects
+	///@todo, check this for any side effects
 	if (insertIndex >= 0)
 	{
Index: code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btSimulationIslandManager.cpp
===================================================================
--- code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btSimulationIslandManager.cpp	(revision 2192)
+++ code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btSimulationIslandManager.cpp	(revision 2430)
@@ -144,9 +144,11 @@
 
 
-void btSimulationIslandManager::buildIslands(btDispatcher* dispatcher,btCollisionObjectArray& collisionObjects)
+void btSimulationIslandManager::buildIslands(btDispatcher* dispatcher,btCollisionWorld* collisionWorld)
 {
 
 	BT_PROFILE("islandUnionFindAndQuickSort");
 	
+	btCollisionObjectArray& collisionObjects = collisionWorld->getCollisionObjectArray();
+
 	m_islandmanifold.resize(0);
 
@@ -239,4 +241,5 @@
 					{
 						colObj0->setActivationState( WANTS_DEACTIVATION);
+						colObj0->setDeactivationTime(0.f);
 					}
 				}
@@ -263,5 +266,5 @@
 		 btCollisionObject* colObj1 = static_cast<btCollisionObject*>(manifold->getBody1());
 		
-		 //todo: check sleeping conditions!
+		 ///@todo: check sleeping conditions!
 		 if (((colObj0) && colObj0->getActivationState() != ISLAND_SLEEPING) ||
 			((colObj1) && colObj1->getActivationState() != ISLAND_SLEEPING))
@@ -288,11 +291,10 @@
 
 
-//
-// todo: this is random access, it can be walked 'cache friendly'!
-//
-void btSimulationIslandManager::buildAndProcessIslands(btDispatcher* dispatcher,btCollisionObjectArray& collisionObjects, IslandCallback* callback)
-{
-
-	buildIslands(dispatcher,collisionObjects);
+///@todo: this is random access, it can be walked 'cache friendly'!
+void btSimulationIslandManager::buildAndProcessIslands(btDispatcher* dispatcher,btCollisionWorld* collisionWorld, IslandCallback* callback)
+{
+	btCollisionObjectArray& collisionObjects = collisionWorld->getCollisionObjectArray();
+
+	buildIslands(dispatcher,collisionWorld);
 
 	int endIslandIndex=1;
Index: code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btSimulationIslandManager.h
===================================================================
--- code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btSimulationIslandManager.h	(revision 2192)
+++ code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btSimulationIslandManager.h	(revision 2430)
@@ -20,5 +20,5 @@
 #include "btCollisionCreateFunc.h"
 #include "LinearMath/btAlignedObjectArray.h"
-
+#include "btCollisionObject.h"
 
 class btCollisionObject;
@@ -62,7 +62,7 @@
 	};
 
-	void	buildAndProcessIslands(btDispatcher* dispatcher,btCollisionObjectArray& collisionObjects, IslandCallback* callback);
+	void	buildAndProcessIslands(btDispatcher* dispatcher,btCollisionWorld* collisionWorld, IslandCallback* callback);
 
-	void buildIslands(btDispatcher* dispatcher,btCollisionObjectArray& collisionObjects);
+	void buildIslands(btDispatcher* dispatcher,btCollisionWorld* colWorld);
 
 };
Index: code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.cpp
===================================================================
--- code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.cpp	(revision 2192)
+++ code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.cpp	(revision 2430)
@@ -22,5 +22,5 @@
 
 btSphereBoxCollisionAlgorithm::btSphereBoxCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* col0,btCollisionObject* col1, bool isSwapped)
-: btCollisionAlgorithm(ci),
+: btActivatingCollisionAlgorithm(ci,col0,col1),
 m_ownManifold(false),
 m_manifoldPtr(mf),
Index: code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.h
===================================================================
--- code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.h	(revision 2192)
+++ code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.h	(revision 2430)
@@ -17,5 +17,5 @@
 #define SPHERE_BOX_COLLISION_ALGORITHM_H
 
-#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"
+#include "btActivatingCollisionAlgorithm.h"
 #include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
 #include "BulletCollision/CollisionDispatch/btCollisionCreateFunc.h"
@@ -27,5 +27,5 @@
 /// btSphereBoxCollisionAlgorithm  provides sphere-box collision detection.
 /// Other features are frame-coherency (persistent data) and collision response.
-class btSphereBoxCollisionAlgorithm : public btCollisionAlgorithm
+class btSphereBoxCollisionAlgorithm : public btActivatingCollisionAlgorithm
 {
 	bool	m_ownManifold;
Index: code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.cpp
===================================================================
--- code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.cpp	(revision 2192)
+++ code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.cpp	(revision 2430)
@@ -20,5 +20,5 @@
 
 btSphereSphereCollisionAlgorithm::btSphereSphereCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* col0,btCollisionObject* col1)
-: btCollisionAlgorithm(ci),
+: btActivatingCollisionAlgorithm(ci,col0,col1),
 m_ownManifold(false),
 m_manifoldPtr(mf)
Index: code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.h
===================================================================
--- code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.h	(revision 2192)
+++ code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.h	(revision 2430)
@@ -17,5 +17,5 @@
 #define SPHERE_SPHERE_COLLISION_ALGORITHM_H
 
-#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"
+#include "btActivatingCollisionAlgorithm.h"
 #include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
 #include "BulletCollision/CollisionDispatch/btCollisionCreateFunc.h"
@@ -27,5 +27,5 @@
 /// Other features are frame-coherency (persistent data) and collision response.
 /// Also provides the most basic sample for custom/user btCollisionAlgorithm
-class btSphereSphereCollisionAlgorithm : public btCollisionAlgorithm
+class btSphereSphereCollisionAlgorithm : public btActivatingCollisionAlgorithm
 {
 	bool	m_ownManifold;
@@ -36,5 +36,5 @@
 
 	btSphereSphereCollisionAlgorithm(const btCollisionAlgorithmConstructionInfo& ci)
-		: btCollisionAlgorithm(ci) {}
+		: btActivatingCollisionAlgorithm(ci) {}
 
 	virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
Index: code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.cpp
===================================================================
--- code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.cpp	(revision 2192)
+++ code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.cpp	(revision 2430)
@@ -23,5 +23,5 @@
 
 btSphereTriangleCollisionAlgorithm::btSphereTriangleCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* col0,btCollisionObject* col1,bool swapped)
-: btCollisionAlgorithm(ci),
+: btActivatingCollisionAlgorithm(ci,col0,col1),
 m_ownManifold(false),
 m_manifoldPtr(mf),
@@ -57,8 +57,8 @@
 	/// report a contact. internally this will be kept persistent, and contact reduction is done
 	resultOut->setPersistentManifold(m_manifoldPtr);
-	SphereTriangleDetector detector(sphere,triangle);
+	SphereTriangleDetector detector(sphere,triangle, m_manifoldPtr->getContactBreakingThreshold());
 	
 	btDiscreteCollisionDetectorInterface::ClosestPointInput input;
-	input.m_maximumDistanceSquared = btScalar(1e30);//todo: tighter bounds
+	input.m_maximumDistanceSquared = btScalar(1e30);///@todo: tighter bounds
 	input.m_transformA = sphereObj->getWorldTransform();
 	input.m_transformB = triObj->getWorldTransform();
Index: code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.h
===================================================================
--- code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.h	(revision 2192)
+++ code/branches/physics/src/bullet/BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.h	(revision 2430)
@@ -17,5 +17,5 @@
 #define SPHERE_TRIANGLE_COLLISION_ALGORITHM_H
 
-#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"
+#include "btActivatingCollisionAlgorithm.h"
 #include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
 #include "BulletCollision/CollisionDispatch/btCollisionCreateFunc.h"
@@ -26,5 +26,5 @@
 /// Other features are frame-coherency (persistent data) and collision response.
 /// Also provides the most basic sample for custom/user btCollisionAlgorithm
-class btSphereTriangleCollisionAlgorithm : public btCollisionAlgorithm
+class btSphereTriangleCollisionAlgorithm : public btActivatingCollisionAlgorithm
 {
 	bool	m_ownManifold;
@@ -36,5 +36,5 @@
 
 	btSphereTriangleCollisionAlgorithm(const btCollisionAlgorithmConstructionInfo& ci)
-		: btCollisionAlgorithm(ci) {}
+		: btActivatingCollisionAlgorithm(ci) {}
 
 	virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
Index: code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btBoxShape.h
===================================================================
--- code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btBoxShape.h	(revision 2192)
+++ code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btBoxShape.h	(revision 2430)
@@ -20,5 +20,5 @@
 #include "btCollisionMargin.h"
 #include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
-#include "LinearMath/btPoint3.h"
+#include "LinearMath/btVector3.h"
 #include "LinearMath/btMinMax.h"
 
@@ -118,5 +118,5 @@
 	virtual void	calculateLocalInertia(btScalar mass,btVector3& inertia) const;
 
-	virtual void getPlane(btVector3& planeNormal,btPoint3& planeSupport,int i ) const
+	virtual void getPlane(btVector3& planeNormal,btVector3& planeSupport,int i ) const
 	{
 		//this plane might not be aligned...
@@ -191,5 +191,5 @@
 
 	
-	virtual void getEdge(int i,btPoint3& pa,btPoint3& pb) const
+	virtual void getEdge(int i,btVector3& pa,btVector3& pb) const
 	//virtual void getEdge(int i,Edge& edge) const
 	{
@@ -262,5 +262,5 @@
 
 	
-	virtual	bool isInside(const btPoint3& pt,btScalar tolerance) const
+	virtual	bool isInside(const btVector3& pt,btScalar tolerance) const
 	{
 		btVector3 halfExtents = getHalfExtentsWithoutMargin();
Index: code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.cpp
===================================================================
--- code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.cpp	(revision 2192)
+++ code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.cpp	(revision 2430)
@@ -144,8 +144,17 @@
 			{
 				int graphicsindex = indicestype==PHY_SHORT?((unsigned short*)gfxbase)[j]:gfxbase[j];
-
-				btScalar* graphicsbase = (btScalar*)(vertexbase+graphicsindex*stride);
-
-				m_triangle[j] = btVector3(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(),graphicsbase[2]*meshScaling.getZ());		
+				
+				if (type == PHY_FLOAT)
+				{
+					float* graphicsbase = (float*)(vertexbase+graphicsindex*stride);
+					
+					m_triangle[j] = btVector3(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(),graphicsbase[2]*meshScaling.getZ());		
+				}
+				else
+				{
+					double* graphicsbase = (double*)(vertexbase+graphicsindex*stride);
+					
+					m_triangle[j] = btVector3(btScalar(graphicsbase[0])*meshScaling.getX(),btScalar(graphicsbase[1])*meshScaling.getY(),btScalar(graphicsbase[2])*meshScaling.getZ());		
+				}
 			}
 
@@ -205,7 +214,16 @@
 				int graphicsindex = indicestype==PHY_SHORT?((unsigned short*)gfxbase)[j]:gfxbase[j];
 
-				btScalar* graphicsbase = (btScalar*)(vertexbase+graphicsindex*stride);
-
-				m_triangle[j] = btVector3(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(),graphicsbase[2]*meshScaling.getZ());		
+				if (type == PHY_FLOAT)
+				{
+					float* graphicsbase = (float*)(vertexbase+graphicsindex*stride);
+
+					m_triangle[j] = btVector3(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(),graphicsbase[2]*meshScaling.getZ());		
+				}
+				else
+				{
+					double* graphicsbase = (double*)(vertexbase+graphicsindex*stride);
+					
+					m_triangle[j] = btVector3(btScalar(graphicsbase[0])*meshScaling.getX(),btScalar(graphicsbase[1])*meshScaling.getY(),btScalar(graphicsbase[2])*meshScaling.getZ());		
+				}
 			}
 
@@ -282,10 +300,22 @@
 				printf("%d ,",graphicsindex);
 #endif //DEBUG_TRIANGLE_MESH
-				btScalar* graphicsbase = (btScalar*)(vertexbase+graphicsindex*stride);
-
-				m_triangle[j] = btVector3(
-					graphicsbase[0]*meshScaling.getX(),
-					graphicsbase[1]*meshScaling.getY(),
-					graphicsbase[2]*meshScaling.getZ());
+				if (type == PHY_FLOAT)
+				{
+					float* graphicsbase = (float*)(vertexbase+graphicsindex*stride);
+					
+					m_triangle[j] = btVector3(
+																		graphicsbase[0]*meshScaling.getX(),
+																		graphicsbase[1]*meshScaling.getY(),
+																		graphicsbase[2]*meshScaling.getZ());
+				}
+				else
+				{
+					double* graphicsbase = (double*)(vertexbase+graphicsindex*stride);
+
+					m_triangle[j] = btVector3(
+						btScalar(graphicsbase[0])*meshScaling.getX(),
+						btScalar(graphicsbase[1])*meshScaling.getY(),
+						btScalar(graphicsbase[2])*meshScaling.getZ());
+				}
 #ifdef DEBUG_TRIANGLE_MESH
 				printf("triangle vertices:%f,%f,%f\n",triangle[j].x(),triangle[j].y(),triangle[j].z());
Index: code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btCapsuleShape.h
===================================================================
--- code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btCapsuleShape.h	(revision 2192)
+++ code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btCapsuleShape.h	(revision 2430)
@@ -50,5 +50,5 @@
 			halfExtents += btVector3(getMargin(),getMargin(),getMargin());
 			btMatrix3x3 abs_b = t.getBasis().absolute();  
-			btPoint3 center = t.getOrigin();
+			btVector3 center = t.getOrigin();
 			btVector3 extent = btVector3(abs_b[0].dot(halfExtents),abs_b[1].dot(halfExtents),abs_b[2].dot(halfExtents));		  
 			
Index: code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btCollisionShape.cpp
===================================================================
--- code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btCollisionShape.cpp	(revision 2192)
+++ code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btCollisionShape.cpp	(revision 2430)
@@ -43,6 +43,12 @@
 }
 
+btScalar	btCollisionShape::getContactBreakingThreshold() const
+{
+	///@todo make this 0.1 configurable
+	return getAngularMotionDisc() * btScalar(0.1);
+}
 btScalar	btCollisionShape::getAngularMotionDisc() const
 {
+	///@todo cache this value, to improve performance
 	btVector3	center;
 	btScalar disc;
@@ -66,5 +72,5 @@
 	// add linear motion
 	btVector3 linMotion = linvel*timeStep;
-	//todo: simd would have a vector max/min operation, instead of per-element access
+	///@todo: simd would have a vector max/min operation, instead of per-element access
 	if (linMotion.x() > btScalar(0.))
 		temporalAabbMaxx += linMotion.x(); 
Index: code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btCollisionShape.h
===================================================================
--- code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btCollisionShape.h	(revision 2192)
+++ code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btCollisionShape.h	(revision 2430)
@@ -20,5 +20,4 @@
 #include "LinearMath/btVector3.h"
 #include "LinearMath/btMatrix3x3.h"
-#include "LinearMath/btPoint3.h"
 #include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" //for the shape types
 
@@ -47,4 +46,6 @@
 	///getAngularMotionDisc returns the maximus radius needed for Conservative Advancement to handle time-of-impact with rotations.
 	virtual btScalar	getAngularMotionDisc() const;
+
+	virtual btScalar	getContactBreakingThreshold() const;
 
 
Index: code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btCompoundShape.cpp
===================================================================
--- code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btCompoundShape.cpp	(revision 2192)
+++ code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btCompoundShape.cpp	(revision 2430)
@@ -18,5 +18,5 @@
 #include "BulletCollision/BroadphaseCollision/btDbvt.h"
 
-btCompoundShape::btCompoundShape()
+btCompoundShape::btCompoundShape(bool enableDynamicAabbTree)
 : m_localAabbMin(btScalar(1e30),btScalar(1e30),btScalar(1e30)),
 m_localAabbMax(btScalar(-1e30),btScalar(-1e30),btScalar(-1e30)),
@@ -26,7 +26,11 @@
 {
 	m_shapeType = COMPOUND_SHAPE_PROXYTYPE;
-	void* mem = btAlignedAlloc(sizeof(btDbvt),16);
-	m_dynamicAabbTree = new(mem) btDbvt();
-	btAssert(mem==m_dynamicAabbTree);
+
+	if (enableDynamicAabbTree)
+	{
+		void* mem = btAlignedAlloc(sizeof(btDbvt),16);
+		m_dynamicAabbTree = new(mem) btDbvt();
+		btAssert(mem==m_dynamicAabbTree);
+	}
 }
 
@@ -77,4 +81,21 @@
 }
 
+void	btCompoundShape::updateChildTransform(int childIndex, const btTransform& newChildTransform)
+{
+	m_children[childIndex].m_transform = newChildTransform;
+
+	if (m_dynamicAabbTree)
+	{
+		///update the dynamic aabb tree
+		btVector3 localAabbMin,localAabbMax;
+		m_children[childIndex].m_childShape->getAabb(newChildTransform,localAabbMin,localAabbMax);
+		ATTRIBUTE_ALIGNED16(btDbvtVolume)	bounds=btDbvtVolume::FromMM(localAabbMin,localAabbMax);
+		int index = m_children.size()-1;
+		m_dynamicAabbTree->update(m_children[childIndex].m_node,bounds);
+	}
+
+	recalculateLocalAabb();
+}
+
 void btCompoundShape::removeChildShapeByIndex(int childShapeIndex)
 {
@@ -88,4 +109,6 @@
 
 }
+
+
 
 void btCompoundShape::removeChildShape(btCollisionShape* shape)
@@ -100,4 +123,6 @@
 			m_children.pop_back();
 			//remove it from the m_dynamicAabbTree too
+			//@todo: this leads to problems due to caching in the btCompoundCollisionAlgorithm
+			//so effectively, removeChildShape is broken at the moment
 			//m_dynamicAabbTree->remove(m_aabbProxies[i]);
 			//m_aabbProxies.swap(i,m_children.size()-1);
@@ -142,5 +167,5 @@
 	btMatrix3x3 abs_b = trans.getBasis().absolute();  
 
-	btPoint3 center = trans(localCenter);
+	btVector3 center = trans(localCenter);
 
 	btVector3 extent = btVector3(abs_b[0].dot(localHalfExtents),
@@ -181,5 +206,7 @@
 	btScalar totalMass = 0;
 	btVector3 center(0, 0, 0);
-	for (int k = 0; k < n; k++)
+	int k;
+
+	for (k = 0; k < n; k++)
 	{
 		center += m_children[k].m_transform.getOrigin() * masses[k];
@@ -190,5 +217,5 @@
 
 	btMatrix3x3 tensor(0, 0, 0, 0, 0, 0, 0, 0, 0);
-	for (int k = 0; k < n; k++)
+	for ( k = 0; k < n; k++)
 	{
 		btVector3 i;
Index: code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btCompoundShape.h
===================================================================
--- code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btCompoundShape.h	(revision 2192)
+++ code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btCompoundShape.h	(revision 2430)
@@ -47,15 +47,15 @@
 }
 
-/// btCompoundShape allows to store multiple other btCollisionShapes
+/// The btCompoundShape allows to store multiple other btCollisionShapes
 /// This allows for moving concave collision objects. This is more general then the static concave btBvhTriangleMeshShape.
+/// It has an (optional) dynamic aabb tree to accelerate early rejection tests. 
+/// @todo: This aabb tree can also be use to speed up ray tests on btCompoundShape, see http://code.google.com/p/bullet/issues/detail?id=25
+/// Currently, removal of child shapes is only supported when disabling the aabb tree (pass 'false' in the constructor of btCompoundShape)
 ATTRIBUTE_ALIGNED16(class) btCompoundShape	: public btCollisionShape
 {
-	//btAlignedObjectArray<btTransform>		m_childTransforms;
-	//btAlignedObjectArray<btCollisionShape*>	m_childShapes;
 	btAlignedObjectArray<btCompoundShapeChild> m_children;
 	btVector3						m_localAabbMin;
 	btVector3						m_localAabbMax;
 
-	//btOptimizedBvh*					m_aabbTree;
 	btDbvt*							m_dynamicAabbTree;
 
@@ -63,5 +63,5 @@
 	BT_DECLARE_ALIGNED_ALLOCATOR();
 
-	btCompoundShape();
+	btCompoundShape(bool enableDynamicAabbTree = true);
 
 	virtual ~btCompoundShape();
@@ -89,12 +89,15 @@
 	}
 
-	btTransform	getChildTransform(int index)
+	btTransform&	getChildTransform(int index)
 	{
 		return m_children[index].m_transform;
 	}
-	const btTransform	getChildTransform(int index) const
+	const btTransform&	getChildTransform(int index) const
 	{
 		return m_children[index].m_transform;
 	}
+
+	///set a new transform for a child, and update internal data structures (local aabb and dynamic tree)
+	void	updateChildTransform(int childIndex, const btTransform& newChildTransform);
 
 
Index: code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btConcaveShape.h
===================================================================
--- code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btConcaveShape.h	(revision 2192)
+++ code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btConcaveShape.h	(revision 2430)
@@ -21,4 +21,14 @@
 #include "btTriangleCallback.h"
 
+/// PHY_ScalarType enumerates possible scalar types.
+/// See the btStridingMeshInterface or btHeightfieldTerrainShape for its use
+typedef enum PHY_ScalarType {
+	PHY_FLOAT,
+	PHY_DOUBLE,
+	PHY_INTEGER,
+	PHY_SHORT,
+	PHY_FIXEDPOINT88,
+	PHY_UCHAR
+} PHY_ScalarType;
 
 ///The btConcaveShape class provides an interface for non-moving (static) concave shapes.
Index: code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btConeShape.cpp
===================================================================
--- code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btConeShape.cpp	(revision 2192)
+++ code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btConeShape.cpp	(revision 2430)
@@ -15,5 +15,4 @@
 
 #include "btConeShape.h"
-#include "LinearMath/btPoint3.h"
 
 
Index: code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btConvexHullShape.cpp
===================================================================
--- code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btConvexHullShape.cpp	(revision 2192)
+++ code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btConvexHullShape.cpp	(revision 2430)
@@ -23,5 +23,5 @@
 {
 	m_shapeType = CONVEX_HULL_SHAPE_PROXYTYPE;
-	m_points.resize(numPoints);
+	m_unscaledPoints.resize(numPoints);
 
 	unsigned char* pointsBaseAddress = (unsigned char*)points;
@@ -29,6 +29,6 @@
 	for (int i=0;i<numPoints;i++)
 	{
-		btPoint3* point = (btPoint3*)(pointsBaseAddress + i*stride);
-		m_points[i] = point[0];
+		btVector3* point = (btVector3*)(pointsBaseAddress + i*stride);
+		m_unscaledPoints[i] = point[0];
 	}
 
@@ -45,7 +45,7 @@
 }
 
-void btConvexHullShape::addPoint(const btPoint3& point)
+void btConvexHullShape::addPoint(const btVector3& point)
 {
-	m_points.push_back(point);
+	m_unscaledPoints.push_back(point);
 	recalcLocalAabb();
 
@@ -69,7 +69,7 @@
 
 
-	for (int i=0;i<m_points.size();i++)
+	for (int i=0;i<m_unscaledPoints.size();i++)
 	{
-		btPoint3 vtx = m_points[i] * m_localScaling;
+		btVector3 vtx = m_unscaledPoints[i] * m_localScaling;
 
 		newDot = vec.dot(vtx);
@@ -93,7 +93,7 @@
 		}
 	}
-	for (int i=0;i<m_points.size();i++)
+	for (int i=0;i<m_unscaledPoints.size();i++)
 	{
-		btPoint3 vtx = m_points[i] * m_localScaling;
+		btVector3 vtx = getScaledPoint(i);
 
 		for (int j=0;j<numVectors;j++)
@@ -146,24 +146,24 @@
 int	btConvexHullShape::getNumVertices() const
 {
-	return m_points.size();
+	return m_unscaledPoints.size();
 }
 
 int btConvexHullShape::getNumEdges() const
 {
-	return m_points.size();
+	return m_unscaledPoints.size();
 }
 
-void btConvexHullShape::getEdge(int i,btPoint3& pa,btPoint3& pb) const
+void btConvexHullShape::getEdge(int i,btVector3& pa,btVector3& pb) const
 {
 
-	int index0 = i%m_points.size();
-	int index1 = (i+1)%m_points.size();
-	pa = m_points[index0]*m_localScaling;
-	pb = m_points[index1]*m_localScaling;
+	int index0 = i%m_unscaledPoints.size();
+	int index1 = (i+1)%m_unscaledPoints.size();
+	pa = getScaledPoint(index0);
+	pb = getScaledPoint(index1);
 }
 
-void btConvexHullShape::getVertex(int i,btPoint3& vtx) const
+void btConvexHullShape::getVertex(int i,btVector3& vtx) const
 {
-	vtx = m_points[i]*m_localScaling;
+	vtx = getScaledPoint(i);
 }
 
@@ -173,5 +173,5 @@
 }
 
-void btConvexHullShape::getPlane(btVector3& ,btPoint3& ,int ) const
+void btConvexHullShape::getPlane(btVector3& ,btVector3& ,int ) const
 {
 
@@ -180,5 +180,5 @@
 
 //not yet
-bool btConvexHullShape::isInside(const btPoint3& ,btScalar ) const
+bool btConvexHullShape::isInside(const btVector3& ,btScalar ) const
 {
 	assert(0);
Index: code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btConvexHullShape.h
===================================================================
--- code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btConvexHullShape.h	(revision 2192)
+++ code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btConvexHullShape.h	(revision 2430)
@@ -25,5 +25,5 @@
 ATTRIBUTE_ALIGNED16(class) btConvexHullShape : public btPolyhedralConvexShape
 {
-	btAlignedObjectArray<btPoint3>	m_points;
+	btAlignedObjectArray<btVector3>	m_unscaledPoints;
 
 public:
@@ -34,21 +34,36 @@
 	///It is easier to not pass any points in the constructor, and just add one point at a time, using addPoint.
 	///btConvexHullShape make an internal copy of the points.
-	btConvexHullShape(const btScalar* points=0,int numPoints=0, int stride=sizeof(btPoint3));
+	btConvexHullShape(const btScalar* points=0,int numPoints=0, int stride=sizeof(btVector3));
 
-	void addPoint(const btPoint3& point);
+	void addPoint(const btVector3& point);
 
-	btPoint3* getPoints()
+	
+	btVector3* getUnscaledPoints()
 	{
-		return &m_points[0];
+		return &m_unscaledPoints[0];
 	}
 
-	const btPoint3* getPoints() const
+	const btVector3* getUnscaledPoints() const
 	{
-		return &m_points[0];
+		return &m_unscaledPoints[0];
 	}
 
-	int getNumPoints() const 
+	///getPoints is obsolete, please use getUnscaledPoints
+	const btVector3* getPoints() const
 	{
-		return m_points.size();
+		return getUnscaledPoints();
+	}
+
+	
+
+
+	SIMD_FORCE_INLINE	btVector3 getScaledPoint(int i) const
+	{
+		return m_unscaledPoints[i] * m_localScaling;
+	}
+
+	SIMD_FORCE_INLINE	int getNumPoints() const 
+	{
+		return m_unscaledPoints.size();
 	}
 
@@ -65,9 +80,9 @@
 	virtual int	getNumVertices() const;
 	virtual int getNumEdges() const;
-	virtual void getEdge(int i,btPoint3& pa,btPoint3& pb) const;
-	virtual void getVertex(int i,btPoint3& vtx) const;
+	virtual void getEdge(int i,btVector3& pa,btVector3& pb) const;
+	virtual void getVertex(int i,btVector3& vtx) const;
 	virtual int	getNumPlanes() const;
-	virtual void getPlane(btVector3& planeNormal,btPoint3& planeSupport,int i ) const;
-	virtual	bool isInside(const btPoint3& pt,btScalar tolerance) const;
+	virtual void getPlane(btVector3& planeNormal,btVector3& planeSupport,int i ) const;
+	virtual	bool isInside(const btVector3& pt,btScalar tolerance) const;
 
 	///in case we receive negative scaling
Index: code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btConvexInternalShape.cpp
===================================================================
--- code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btConvexInternalShape.cpp	(revision 2192)
+++ code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btConvexInternalShape.cpp	(revision 2430)
@@ -18,6 +18,7 @@
 
 
+
 btConvexInternalShape::btConvexInternalShape()
-: btConvexShape (), m_localScaling(btScalar(1.),btScalar(1.),btScalar(1.)),
+: m_localScaling(btScalar(1.),btScalar(1.),btScalar(1.)),
 m_collisionMargin(CONVEX_DISTANCE_MARGIN)
 {
@@ -49,5 +50,6 @@
 		minAabb[i] = tmp[i]-margin;
 	}
-};
+}
+
 
 
@@ -71,4 +73,5 @@
 
 #else
+	btAssert(0);
 	return btVector3(0,0,0);
 #endif //__SPU__
Index: code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btConvexInternalShape.h
===================================================================
--- code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btConvexInternalShape.h	(revision 2192)
+++ code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btConvexInternalShape.h	(revision 2430)
@@ -31,12 +31,5 @@
 	}
 
-
 	virtual btVector3	localGetSupportingVertex(const btVector3& vec)const;
-#ifndef __SPU__
-	virtual btVector3	localGetSupportingVertexWithoutMargin(const btVector3& vec) const= 0;
-	
-	//notice that the vectors should be unit length
-	virtual void	batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const= 0;
-#endif //#ifndef __SPU__
 
 	const btVector3& getImplicitShapeDimensions() const
Index: code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btConvexPointCloudShape.cpp
===================================================================
--- code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btConvexPointCloudShape.cpp	(revision 2192)
+++ code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btConvexPointCloudShape.cpp	(revision 2430)
@@ -18,22 +18,4 @@
 #include "LinearMath/btQuaternion.h"
 
-btConvexPointCloudShape::btConvexPointCloudShape (btVector3* points,int numPoints) : btPolyhedralConvexShape ()
-{
-	m_shapeType = CONVEX_POINT_CLOUD_SHAPE_PROXYTYPE;
-	m_points = points;
-	m_numPoints = numPoints;
-
-	recalcLocalAabb();
-}
-
-void btConvexPointCloudShape::setPoints (btVector3* points, int numPoints)
-{
-	m_points = points;
-	m_numPoints = numPoints;
-
-	recalcLocalAabb();
-}
-
-
 void btConvexPointCloudShape::setLocalScaling(const btVector3& scaling)
 {
@@ -42,4 +24,5 @@
 }
 
+#ifndef __SPU__
 btVector3	btConvexPointCloudShape::localGetSupportingVertexWithoutMargin(const btVector3& vec0)const
 {
@@ -61,5 +44,5 @@
 	for (int i=0;i<m_numPoints;i++)
 	{
-		btPoint3 vtx = m_points[i] * m_localScaling;
+		btVector3 vtx = getScaledPoint(i);
 
 		newDot = vec.dot(vtx);
@@ -85,5 +68,5 @@
 	for (int i=0;i<m_numPoints;i++)
 	{
-		btPoint3 vtx = m_points[i] * m_localScaling;
+		btVector3 vtx = getScaledPoint(i);
 
 		for (int j=0;j<numVectors;j++)
@@ -125,5 +108,5 @@
 
 
-
+#endif
 
 
@@ -144,12 +127,12 @@
 }
 
-void btConvexPointCloudShape::getEdge(int i,btPoint3& pa,btPoint3& pb) const
+void btConvexPointCloudShape::getEdge(int i,btVector3& pa,btVector3& pb) const
 {
 	btAssert (0);
 }
 
-void btConvexPointCloudShape::getVertex(int i,btPoint3& vtx) const
+void btConvexPointCloudShape::getVertex(int i,btVector3& vtx) const
 {
-	vtx = m_points[i]*m_localScaling;
+	vtx = m_unscaledPoints[i]*m_localScaling;
 }
 
@@ -159,5 +142,5 @@
 }
 
-void btConvexPointCloudShape::getPlane(btVector3& ,btPoint3& ,int ) const
+void btConvexPointCloudShape::getPlane(btVector3& ,btVector3& ,int ) const
 {
 
@@ -166,5 +149,5 @@
 
 //not yet
-bool btConvexPointCloudShape::isInside(const btPoint3& ,btScalar ) const
+bool btConvexPointCloudShape::isInside(const btVector3& ,btScalar ) const
 {
 	assert(0);
Index: code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btConvexPointCloudShape.h
===================================================================
--- code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btConvexPointCloudShape.h	(revision 2192)
+++ code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btConvexPointCloudShape.h	(revision 2430)
@@ -24,31 +24,55 @@
 ATTRIBUTE_ALIGNED16(class) btConvexPointCloudShape : public btPolyhedralConvexShape
 {
-	btVector3* m_points;
+	btVector3* m_unscaledPoints;
 	int m_numPoints;
+
 public:
 	BT_DECLARE_ALIGNED_ALLOCATOR();
 
-	btConvexPointCloudShape(btVector3* points,int numPoints);
+	btConvexPointCloudShape(btVector3* points,int numPoints, const btVector3& localScaling,bool computeAabb = true)
+	{
+		m_localScaling = localScaling;
+		m_shapeType = CONVEX_POINT_CLOUD_SHAPE_PROXYTYPE;
+		m_unscaledPoints = points;
+		m_numPoints = numPoints;
 
-	void setPoints (btVector3* points, int numPoints);
-
-	btPoint3* getPoints()
-	{
-		return m_points;
+		if (computeAabb)
+			recalcLocalAabb();
 	}
 
-	const btPoint3* getPoints() const
+	void setPoints (btVector3* points, int numPoints, bool computeAabb = true)
 	{
-		return m_points;
+		m_unscaledPoints = points;
+		m_numPoints = numPoints;
+
+		if (computeAabb)
+			recalcLocalAabb();
 	}
 
-	int getNumPoints() const 
+	SIMD_FORCE_INLINE	btVector3* getUnscaledPoints()
+	{
+		return m_unscaledPoints;
+	}
+
+	SIMD_FORCE_INLINE	const btVector3* getUnscaledPoints() const
+	{
+		return m_unscaledPoints;
+	}
+
+	SIMD_FORCE_INLINE	int getNumPoints() const 
 	{
 		return m_numPoints;
 	}
 
+	SIMD_FORCE_INLINE	btVector3	getScaledPoint( int index) const
+	{
+		return m_unscaledPoints[index] * m_localScaling;
+	}
+
+#ifndef __SPU__
 	virtual btVector3	localGetSupportingVertex(const btVector3& vec)const;
 	virtual btVector3	localGetSupportingVertexWithoutMargin(const btVector3& vec)const;
 	virtual void	batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const;
+#endif
 
 
@@ -58,9 +82,9 @@
 	virtual int	getNumVertices() const;
 	virtual int getNumEdges() const;
-	virtual void getEdge(int i,btPoint3& pa,btPoint3& pb) const;
-	virtual void getVertex(int i,btPoint3& vtx) const;
+	virtual void getEdge(int i,btVector3& pa,btVector3& pb) const;
+	virtual void getVertex(int i,btVector3& vtx) const;
 	virtual int	getNumPlanes() const;
-	virtual void getPlane(btVector3& planeNormal,btPoint3& planeSupport,int i ) const;
-	virtual	bool isInside(const btPoint3& pt,btScalar tolerance) const;
+	virtual void getPlane(btVector3& planeNormal,btVector3& planeSupport,int i ) const;
+	virtual	bool isInside(const btVector3& pt,btScalar tolerance) const;
 
 	///in case we receive negative scaling
Index: code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btConvexShape.cpp
===================================================================
--- code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btConvexShape.cpp	(revision 2192)
+++ code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btConvexShape.cpp	(revision 2430)
@@ -15,5 +15,4 @@
 
 #include "btConvexShape.h"
-#include "btConvexInternalShape.h"
 #include "btTriangleShape.h"
 #include "btSphereShape.h"
@@ -23,5 +22,16 @@
 #include "btConvexPointCloudShape.h"
 
-static btVector3 convexHullSupport (const btVector3& localDir, const btVector3* points, int numPoints)
+btConvexShape::btConvexShape ()
+{
+}
+
+btConvexShape::~btConvexShape()
+{
+
+}
+
+
+
+static btVector3 convexHullSupport (const btVector3& localDir, const btVector3* points, int numPoints, const btVector3& localScaling)
 {
 	btVector3 supVec(btScalar(0.),btScalar(0.),btScalar(0.));
@@ -42,5 +52,5 @@
 	for (int i=0;i<numPoints;i++)
 	{
-		btPoint3 vtx = points[i];// * m_localScaling;
+		btVector3 vtx = points[i] * localScaling;
 
 		newDot = vec.dot(vtx);
@@ -62,8 +72,7 @@
 		return btVector3(0,0,0);
     }
-	break;
 	case BOX_SHAPE_PROXYTYPE:
 	{
-		btConvexInternalShape* convexShape = (btConvexInternalShape*)this;
+		btBoxShape* convexShape = (btBoxShape*)this;
 		const btVector3& halfExtents = convexShape->getImplicitShapeDimensions();
 
@@ -72,5 +81,4 @@
 			btFsels(localDir.z(), halfExtents.z(), -halfExtents.z()));
 	}
-	break;
 	case TRIANGLE_SHAPE_PROXYTYPE:
 	{
@@ -82,5 +90,4 @@
 		return btVector3(sup.getX(),sup.getY(),sup.getZ());
 	}
-	break;
 	case CYLINDER_SHAPE_PROXYTYPE:
 	{
@@ -143,5 +150,4 @@
 		}
 	}
-	break;
 	case CAPSULE_SHAPE_PROXYTYPE:
 	{
@@ -200,20 +206,18 @@
 		return btVector3(supVec.getX(),supVec.getY(),supVec.getZ());	
 	}
-	break;
 	case CONVEX_POINT_CLOUD_SHAPE_PROXYTYPE:
 	{
 		btConvexPointCloudShape* convexPointCloudShape = (btConvexPointCloudShape*)this;
-		btVector3* points = convexPointCloudShape->getPoints ();
+		btVector3* points = convexPointCloudShape->getUnscaledPoints ();
 		int numPoints = convexPointCloudShape->getNumPoints ();
-		return convexHullSupport (localDir, points, numPoints);
+		return convexHullSupport (localDir, points, numPoints,convexPointCloudShape->getLocalScalingNV());
 	}
 	case CONVEX_HULL_SHAPE_PROXYTYPE:
 	{
 		btConvexHullShape* convexHullShape = (btConvexHullShape*)this;
-		btPoint3* points = convexHullShape->getPoints ();
+		btVector3* points = convexHullShape->getUnscaledPoints();
 		int numPoints = convexHullShape->getNumPoints ();
-		return convexHullSupport (localDir, points, numPoints);
-	}
-	break;
+		return convexHullSupport (localDir, points, numPoints,convexHullShape->getLocalScalingNV());
+	}
     default:
 #ifndef __SPU__
@@ -222,10 +226,9 @@
 		btAssert (0);
 #endif
-	break;
 	}
 
 	// should never reach here
 	btAssert (0);
-	return btPoint3 (btScalar(0.0f), btScalar(0.0f), btScalar(0.0f));
+	return btVector3 (btScalar(0.0f), btScalar(0.0f), btScalar(0.0f));
 }
 
@@ -238,172 +241,6 @@
 	}
 	localDirNorm.normalize ();
-	switch (m_shapeType)
-	{
-    case SPHERE_SHAPE_PROXYTYPE:
-	{
-		return btVector3(0,0,0) + getMarginNonVirtual() * localDirNorm;
-    }
-	break;
-	case BOX_SHAPE_PROXYTYPE:
-	{
-		btConvexInternalShape* convexShape = (btConvexInternalShape*)this;
-		const btVector3& halfExtents = convexShape->getImplicitShapeDimensions();
-
-		return btVector3(localDir.getX() < 0.0f ? -halfExtents.x() : halfExtents.x(),
-						localDir.getY() < 0.0f ? -halfExtents.y() : halfExtents.y(),
-						localDir.getZ() < 0.0f ? -halfExtents.z() : halfExtents.z()) + getMarginNonVirtual() * localDirNorm;
-	}
-	break;
-	case TRIANGLE_SHAPE_PROXYTYPE:
-	{
-		btTriangleShape* triangleShape = (btTriangleShape*)this;
-		btVector3 dir(localDir.getX(),localDir.getY(),localDir.getZ());
-		btVector3* vertices = &triangleShape->m_vertices1[0];
-		btVector3 dots(dir.dot(vertices[0]), dir.dot(vertices[1]), dir.dot(vertices[2]));
-		btVector3 sup = vertices[dots.maxAxis()];
-		return btVector3(sup.getX(),sup.getY(),sup.getZ()) + getMarginNonVirtual() * localDirNorm;
-	}
-	break;
-	case CYLINDER_SHAPE_PROXYTYPE:
-	{
-		btCylinderShape* cylShape = (btCylinderShape*)this;
-		//mapping of halfextents/dimension onto radius/height depends on how cylinder local orientation is (upAxis)
-
-		btVector3 halfExtents = cylShape->getImplicitShapeDimensions();
-		btVector3 v(localDir.getX(),localDir.getY(),localDir.getZ());
-		int cylinderUpAxis = cylShape->getUpAxis();
-		int XX(1),YY(0),ZZ(2);
-
-		switch (cylinderUpAxis)
-		{
-		case 0:
-		{
-			XX = 1;
-			YY = 0;
-			ZZ = 2;
-		}
-		break;
-		case 1:
-		{
-			XX = 0;
-			YY = 1;
-			ZZ = 2;	
-		}
-		break;
-		case 2:
-		{
-			XX = 0;
-			YY = 2;
-			ZZ = 1;
-			
-		}
-		break;
-		default:
-			btAssert(0);
-		break;
-		};
-
-		btScalar radius = halfExtents[XX];
-		btScalar halfHeight = halfExtents[cylinderUpAxis];
-
-		btVector3 tmp;
-		btScalar d ;
-
-		btScalar s = btSqrt(v[XX] * v[XX] + v[ZZ] * v[ZZ]);
-		if (s != btScalar(0.0))
-		{
-			d = radius / s;  
-			tmp[XX] = v[XX] * d;
-			tmp[YY] = v[YY] < 0.0 ? -halfHeight : halfHeight;
-			tmp[ZZ] = v[ZZ] * d;
-			return btVector3(tmp.getX(),tmp.getY(),tmp.getZ()) + getMarginNonVirtual() * localDirNorm;
-		} else {
-			tmp[XX] = radius;
-			tmp[YY] = v[YY] < 0.0 ? -halfHeight : halfHeight;
-			tmp[ZZ] = btScalar(0.0);
-			return btVector3(tmp.getX(),tmp.getY(),tmp.getZ()) + getMarginNonVirtual() * localDirNorm;
-		}
-	}
-	break;
-	case CAPSULE_SHAPE_PROXYTYPE:
-	{
-		btVector3 vec0(localDir.getX(),localDir.getY(),localDir.getZ());
-
-		btCapsuleShape* capsuleShape = (btCapsuleShape*)this;
-		btVector3 halfExtents = capsuleShape->getImplicitShapeDimensions();
-		btScalar halfHeight = capsuleShape->getHalfHeight();
-		int capsuleUpAxis = capsuleShape->getUpAxis();
-
-		btScalar radius = capsuleShape->getRadius();
-		btVector3 supVec(0,0,0);
-
-		btScalar maxDot(btScalar(-1e30));
-
-		btVector3 vec = vec0;
-		btScalar lenSqr = vec.length2();
-		if (lenSqr < btScalar(0.0001))
-		{
-			vec.setValue(1,0,0);
-		} else
-		{
-			btScalar rlen = btScalar(1.) / btSqrt(lenSqr );
-			vec *= rlen;
-		}
-		btVector3 vtx;
-		btScalar newDot;
-		{
-			btVector3 pos(0,0,0);
-			pos[capsuleUpAxis] = halfHeight;
-
-			vtx = pos +vec*(radius);
-			newDot = vec.dot(vtx);
-			if (newDot > maxDot)
-			{
-				maxDot = newDot;
-				supVec = vtx;
-			}
-		}
-		{
-			btVector3 pos(0,0,0);
-			pos[capsuleUpAxis] = -halfHeight;
-
-			vtx = pos +vec*(radius);
-			newDot = vec.dot(vtx);
-			if (newDot > maxDot)
-			{
-				maxDot = newDot;
-				supVec = vtx;
-			}
-		}
-		return btVector3(supVec.getX(),supVec.getY(),supVec.getZ()) + getMarginNonVirtual() * localDirNorm;
-	}
-	break;
-	case CONVEX_POINT_CLOUD_SHAPE_PROXYTYPE:
-	{
-		btConvexPointCloudShape* convexPointCloudShape = (btConvexPointCloudShape*)this;
-		btVector3* points = convexPointCloudShape->getPoints ();
-		int numPoints = convexPointCloudShape->getNumPoints ();
-		return convexHullSupport (localDir, points, numPoints) + getMarginNonVirtual() * localDirNorm;
-	}
-	case CONVEX_HULL_SHAPE_PROXYTYPE:
-	{
-		btConvexHullShape* convexHullShape = (btConvexHullShape*)this;
-		btPoint3* points = convexHullShape->getPoints ();
-		int numPoints = convexHullShape->getNumPoints ();
-		return convexHullSupport (localDir, points, numPoints) + getMarginNonVirtual() * localDirNorm;
-	}
-	break;
-    default:
-#ifndef __SPU__
-		return this->localGetSupportingVertex (localDir);
-#else
-		btAssert (0);
-#endif
-	break;
-	}
-
-	// should never reach here
-	btAssert (0);
-	return btPoint3 (btScalar(0.0f), btScalar(0.0f), btScalar(0.0f));
+
+	return localGetSupportVertexWithoutMarginNonVirtual(localDirNorm)+ getMarginNonVirtual() * localDirNorm;
 }
 
@@ -418,11 +255,9 @@
 		return sphereShape->getRadius ();
 	}
-	break;
 	case BOX_SHAPE_PROXYTYPE:
 	{
-		btConvexInternalShape* convexShape = (btConvexInternalShape*)this;
+		btBoxShape* convexShape = (btBoxShape*)this;
 		return convexShape->getMarginNV ();
 	}
-	break;
 	case TRIANGLE_SHAPE_PROXYTYPE:
 	{
@@ -430,5 +265,4 @@
 		return triangleShape->getMarginNV ();
 	}
-	break;
 	case CYLINDER_SHAPE_PROXYTYPE:
 	{
@@ -436,5 +270,4 @@
 		return cylShape->getMarginNV();
 	}
-	break;
 	case CAPSULE_SHAPE_PROXYTYPE:
 	{
@@ -442,5 +275,4 @@
 		return capsuleShape->getMarginNV();
 	}
-	break;
 	case CONVEX_POINT_CLOUD_SHAPE_PROXYTYPE:
 	/* fall through */
@@ -450,5 +282,4 @@
 		return convexHullShape->getMarginNV();
 	}
-	break;
     default:
 #ifndef __SPU__
@@ -457,5 +288,4 @@
 		btAssert (0);
 #endif
-	break;
 	}
 
@@ -484,10 +314,10 @@
 	case BOX_SHAPE_PROXYTYPE:
 	{
-		btConvexInternalShape* convexShape = (btConvexInternalShape*)this;
+		btBoxShape* convexShape = (btBoxShape*)this;
 		float margin=convexShape->getMarginNonVirtual();
 		btVector3 halfExtents = convexShape->getImplicitShapeDimensions();
 		halfExtents += btVector3(margin,margin,margin);
 		btMatrix3x3 abs_b = t.getBasis().absolute();  
-		btPoint3 center = t.getOrigin();
+		btVector3 center = t.getOrigin();
 		btVector3 extent = btVector3(abs_b[0].dot(halfExtents),abs_b[1].dot(halfExtents),abs_b[2].dot(halfExtents));
 		
@@ -496,5 +326,4 @@
 		break;
 	}
-	break;
 	case TRIANGLE_SHAPE_PROXYTYPE:
 	{
@@ -524,5 +353,5 @@
 		halfExtents += btVector3(capsuleShape->getMarginNonVirtual(),capsuleShape->getMarginNonVirtual(),capsuleShape->getMarginNonVirtual());
 		btMatrix3x3 abs_b = t.getBasis().absolute();  
-		btPoint3 center = t.getOrigin();
+		btVector3 center = t.getOrigin();
 		btVector3 extent = btVector3(abs_b[0].dot(halfExtents),abs_b[1].dot(halfExtents),abs_b[2].dot(halfExtents));		  	
 		aabbMin = center - extent;
Index: code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btConvexShape.h
===================================================================
--- code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btConvexShape.h	(revision 2192)
+++ code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btConvexShape.h	(revision 2430)
@@ -25,6 +25,4 @@
 #include "LinearMath/btAlignedAllocator.h"
 
-//todo: get rid of this btConvexCastResult thing!
-struct btConvexCastResult;
 #define MAX_PREFERRED_PENETRATION_DIRECTIONS 10
 
@@ -39,21 +37,14 @@
 	BT_DECLARE_ALIGNED_ALLOCATOR();
 
-	btConvexShape ()
-	{
-	}
+	btConvexShape ();
 
-	virtual ~btConvexShape()
-	{
+	virtual ~btConvexShape();
 
-	}
+	virtual btVector3	localGetSupportingVertex(const btVector3& vec)const = 0;
 
-
-	virtual btVector3	localGetSupportingVertex(const btVector3& vec)const =0;
-#ifndef __SPU__
-	virtual btVector3	localGetSupportingVertexWithoutMargin(const btVector3& vec) const= 0;
-	
-	//notice that the vectors should be unit length
-	virtual void	batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const= 0;
-#endif //#ifndef __SPU__
+	////////
+	#ifndef __SPU__
+	virtual btVector3	localGetSupportingVertexWithoutMargin(const btVector3& vec) const=0;
+	#endif //#ifndef __SPU__
 
 	btVector3 localGetSupportVertexWithoutMarginNonVirtual (const btVector3& vec) const;
@@ -61,4 +52,8 @@
 	btScalar getMarginNonVirtual () const;
 	void getAabbNonVirtual (const btTransform& t, btVector3& aabbMin, btVector3& aabbMax) const;
+
+	
+	//notice that the vectors should be unit length
+	virtual void	batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const= 0;
 
 	///getAabb's default implementation is brute force, expected derived classes to implement a fast dedicated version
@@ -78,4 +73,7 @@
 	virtual void	getPreferredPenetrationDirection(int index, btVector3& penetrationVector) const=0;
 
+
+	
+	
 };
 
Index: code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btConvexTriangleMeshShape.cpp
===================================================================
--- code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btConvexTriangleMeshShape.cpp	(revision 2192)
+++ code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btConvexTriangleMeshShape.cpp	(revision 2430)
@@ -109,5 +109,5 @@
 	}
 	
-	//todo: could do the batch inside the callback!
+	///@todo: could do the batch inside the callback!
 
 
@@ -164,10 +164,10 @@
 }
 
-void btConvexTriangleMeshShape::getEdge(int ,btPoint3& ,btPoint3& ) const
+void btConvexTriangleMeshShape::getEdge(int ,btVector3& ,btVector3& ) const
 {
 	btAssert(0);	
 }
 
-void btConvexTriangleMeshShape::getVertex(int ,btPoint3& ) const
+void btConvexTriangleMeshShape::getVertex(int ,btVector3& ) const
 {
 	btAssert(0);
@@ -179,5 +179,5 @@
 }
 
-void btConvexTriangleMeshShape::getPlane(btVector3& ,btPoint3& ,int  ) const
+void btConvexTriangleMeshShape::getPlane(btVector3& ,btVector3& ,int  ) const
 {
 	btAssert(0);
@@ -185,5 +185,5 @@
 
 //not yet
-bool btConvexTriangleMeshShape::isInside(const btPoint3& ,btScalar ) const
+bool btConvexTriangleMeshShape::isInside(const btVector3& ,btScalar ) const
 {
 	btAssert(0);
@@ -270,5 +270,4 @@
          btVector3 b = triangle[1] - center;
          btVector3 c = triangle[2] - center;
-         btVector3 abc = a + b + c;
          btScalar volNeg = -btFabs(a.triple(b, c)) * btScalar(1. / 6);
          for (int j = 0; j < 3; j++)
@@ -276,7 +275,5 @@
             for (int k = 0; k <= j; k++)
             {
-               i[j][k] = i[k][j] = volNeg * (center[j] * center[k]
-                 + btScalar(0.25) * (center[j] * abc[k] + center[k] * abc[j])
-                  + btScalar(0.1) * (a[j] * a[k] + b[j] * b[k] + c[j] * c[k])
+               i[j][k] = i[k][j] = volNeg * (btScalar(0.1) * (a[j] * a[k] + b[j] * b[k] + c[j] * c[k])
                   + btScalar(0.05) * (a[j] * b[k] + a[k] * b[j] + a[j] * c[k] + a[k] * c[j] + b[j] * c[k] + b[k] * c[j]));
             }
Index: code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btConvexTriangleMeshShape.h
===================================================================
--- code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btConvexTriangleMeshShape.h	(revision 2192)
+++ code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btConvexTriangleMeshShape.h	(revision 2430)
@@ -35,9 +35,9 @@
 	virtual int	getNumVertices() const;
 	virtual int getNumEdges() const;
-	virtual void getEdge(int i,btPoint3& pa,btPoint3& pb) const;
-	virtual void getVertex(int i,btPoint3& vtx) const;
+	virtual void getEdge(int i,btVector3& pa,btVector3& pb) const;
+	virtual void getVertex(int i,btVector3& vtx) const;
 	virtual int	getNumPlanes() const;
-	virtual void getPlane(btVector3& planeNormal,btPoint3& planeSupport,int i ) const;
-	virtual	bool isInside(const btPoint3& pt,btScalar tolerance) const;
+	virtual void getPlane(btVector3& planeNormal,btVector3& planeSupport,int i ) const;
+	virtual	bool isInside(const btVector3& pt,btScalar tolerance) const;
 
 	
Index: code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btCylinderShape.cpp
===================================================================
--- code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btCylinderShape.cpp	(revision 2192)
+++ code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btCylinderShape.cpp	(revision 2430)
@@ -14,5 +14,4 @@
 */
 #include "btCylinderShape.h"
-#include "LinearMath/btPoint3.h"
 
 btCylinderShape::btCylinderShape (const btVector3& halfExtents)
Index: code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btEmptyShape.h
===================================================================
--- code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btEmptyShape.h	(revision 2192)
+++ code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btEmptyShape.h	(revision 2430)
@@ -57,4 +57,7 @@
 	}
 
+	virtual void processAllTriangles(btTriangleCallback* ,const btVector3& ,const btVector3& ) const
+	{
+	}
 
 protected:
Index: code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.cpp
===================================================================
--- code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.cpp	(revision 2192)
+++ code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.cpp	(revision 2430)
@@ -19,51 +19,90 @@
 
 
+
+btHeightfieldTerrainShape::btHeightfieldTerrainShape
+(
+int heightStickWidth, int heightStickLength, void* heightfieldData,
+btScalar heightScale, btScalar minHeight, btScalar maxHeight,int upAxis,
+PHY_ScalarType hdt, bool flipQuadEdges
+)
+{
+	initialize(heightStickWidth, heightStickLength, heightfieldData,
+	           heightScale, minHeight, maxHeight, upAxis, hdt,
+	           flipQuadEdges);
+}
+
+
+
 btHeightfieldTerrainShape::btHeightfieldTerrainShape(int heightStickWidth, int heightStickLength,void* heightfieldData,btScalar maxHeight,int upAxis,bool useFloatData,bool flipQuadEdges)
-: btConcaveShape (), m_heightStickWidth(heightStickWidth),
-m_heightStickLength(heightStickLength),
-m_maxHeight(maxHeight),
-m_width((btScalar)heightStickWidth-1),
-m_length((btScalar)heightStickLength-1),
-m_heightfieldDataUnknown(heightfieldData),
-m_useFloatData(useFloatData),
-m_flipQuadEdges(flipQuadEdges),
-m_useDiamondSubdivision(false),
-m_upAxis(upAxis),
-m_localScaling(btScalar(1.),btScalar(1.),btScalar(1.))
-{
+{
+	// legacy constructor: support only float or unsigned char,
+	// 	and min height is zero
+	PHY_ScalarType hdt = (useFloatData) ? PHY_FLOAT : PHY_UCHAR;
+	btScalar minHeight = 0.0;
+
+	// previously, height = uchar * maxHeight / 65535.
+	// So to preserve legacy behavior, heightScale = maxHeight / 65535
+	btScalar heightScale = maxHeight / 65535;
+
+	initialize(heightStickWidth, heightStickLength, heightfieldData,
+	           heightScale, minHeight, maxHeight, upAxis, hdt,
+	           flipQuadEdges);
+}
+
+
+
+void btHeightfieldTerrainShape::initialize
+(
+int heightStickWidth, int heightStickLength, void* heightfieldData,
+btScalar heightScale, btScalar minHeight, btScalar maxHeight, int upAxis,
+PHY_ScalarType hdt, bool flipQuadEdges
+)
+{
+	// validation
+	btAssert(heightStickWidth > 1 && "bad width");
+	btAssert(heightStickLength > 1 && "bad length");
+	btAssert(heightfieldData && "null heightfield data");
+	// btAssert(heightScale) -- do we care?  Trust caller here
+	btAssert(minHeight <= maxHeight && "bad min/max height");
+	btAssert(upAxis >= 0 && upAxis < 3 &&
+	    "bad upAxis--should be in range [0,2]");
+	btAssert(hdt != PHY_UCHAR || hdt != PHY_FLOAT || hdt != PHY_SHORT &&
+	    "Bad height data type enum");
+
+	// initialize member variables
 	m_shapeType = TERRAIN_SHAPE_PROXYTYPE;
-
-	btScalar	quantizationMargin = 1.f;
-
-	//enlarge the AABB to avoid division by zero when initializing the quantization values
-	btVector3 clampValue(quantizationMargin,quantizationMargin,quantizationMargin);
-
-	btVector3	halfExtents(0,0,0);
-
+	m_heightStickWidth = heightStickWidth;
+	m_heightStickLength = heightStickLength;
+	m_minHeight = minHeight;
+	m_maxHeight = maxHeight;
+	m_width = (btScalar) (heightStickWidth - 1);
+	m_length = (btScalar) (heightStickLength - 1);
+	m_heightScale = heightScale;
+	m_heightfieldDataUnknown = heightfieldData;
+	m_heightDataType = hdt;
+	m_flipQuadEdges = flipQuadEdges;
+	m_useDiamondSubdivision = false;
+	m_upAxis = upAxis;
+	m_localScaling.setValue(btScalar(1.), btScalar(1.), btScalar(1.));
+
+	// determine min/max axis-aligned bounding box (aabb) values
 	switch (m_upAxis)
 	{
 	case 0:
 		{
-			halfExtents.setValue(
-				btScalar(m_maxHeight),
-				btScalar(m_width), //?? don't know if this should change
-				btScalar(m_length));
+			m_localAabbMin.setValue(m_minHeight, 0, 0);
+			m_localAabbMax.setValue(m_maxHeight, m_width, m_length);
 			break;
 		}
 	case 1:
 		{
-			halfExtents.setValue(
-				btScalar(m_width),
-				btScalar(m_maxHeight),
-				btScalar(m_length));
+			m_localAabbMin.setValue(0, m_minHeight, 0);
+			m_localAabbMax.setValue(m_width, m_maxHeight, m_length);
 			break;
 		};
 	case 2:
 		{
-			halfExtents.setValue(
-				btScalar(m_width),
-				btScalar(m_length),
-				btScalar(m_maxHeight)
-			);
+			m_localAabbMin.setValue(0, 0, m_minHeight);
+			m_localAabbMax.setValue(m_width, m_length, m_maxHeight);
 			break;
 		}
@@ -71,15 +110,12 @@
 		{
 			//need to get valid m_upAxis
-			btAssert(0);
-		}
-	}
-
-	halfExtents*= btScalar(0.5);
-	
-	m_localAabbMin = -halfExtents - clampValue;
-	m_localAabbMax = halfExtents + clampValue;
-	btVector3 aabbSize = m_localAabbMax - m_localAabbMin;
-
-}
+			btAssert(0 && "Bad m_upAxis");
+		}
+	}
+
+	// remember origin (defined as exact middle of aabb)
+	m_localOrigin = btScalar(0.5) * (m_localAabbMin + m_localAabbMax);
+}
+
 
 
@@ -93,17 +129,18 @@
 {
 	btVector3 halfExtents = (m_localAabbMax-m_localAabbMin)* m_localScaling * btScalar(0.5);
-	halfExtents += btVector3(getMargin(),getMargin(),getMargin());
+
+	btVector3 localOrigin(0, 0, 0);
+	localOrigin[m_upAxis] = (m_minHeight + m_maxHeight) * btScalar(0.5);
+	localOrigin *= m_localScaling;
 
 	btMatrix3x3 abs_b = t.getBasis().absolute();  
-	btPoint3 center = t.getOrigin();
+	btVector3 center = t.getOrigin();
 	btVector3 extent = btVector3(abs_b[0].dot(halfExtents),
 		   abs_b[1].dot(halfExtents),
 		  abs_b[2].dot(halfExtents));
-	
+	extent += btVector3(getMargin(),getMargin(),getMargin());
 
 	aabbMin = center - extent;
 	aabbMax = center + extent;
-
-
 }
 
@@ -111,13 +148,32 @@
 {
 	btScalar val = 0.f;
-	if (m_useFloatData)
+	switch (m_heightDataType)
 	{
-		val = m_heightfieldDataFloat[(y*m_heightStickWidth)+x];
-	} else
-	{
-		//assume unsigned short int
-		unsigned char heightFieldValue = m_heightfieldDataUnsignedChar[(y*m_heightStickWidth)+x];
-		val = heightFieldValue* (m_maxHeight/btScalar(65535));
-	}
+	case PHY_FLOAT:
+		{
+			val = m_heightfieldDataFloat[(y*m_heightStickWidth)+x];
+			break;
+		}
+
+	case PHY_UCHAR:
+		{
+			unsigned char heightFieldValue = m_heightfieldDataUnsignedChar[(y*m_heightStickWidth)+x];
+			val = heightFieldValue * m_heightScale;
+			break;
+		}
+
+	case PHY_SHORT:
+		{
+			short hfValue = m_heightfieldDataShort[(y * m_heightStickWidth) + x];
+			val = hfValue * m_heightScale;
+			break;
+		}
+
+	default:
+		{
+			btAssert(!"Bad m_heightDataType");
+		}
+	}
+
 	return val;
 }
@@ -179,4 +235,28 @@
 
 
+
+static inline int
+getQuantized
+(
+float x
+)
+{
+	if (x < 0.0) {
+		return (int) (x - 0.5);
+	}
+	return (int) (x + 0.5);
+}
+
+
+
+/// given input vector, return quantized version
+/**
+  This routine is basically determining the gridpoint indices for a given
+  input vector, answering the question: "which gridpoint is closest to the
+  provided point?".
+
+  "with clamp" means that we restrict the point to be in the heightfield's
+  axis-aligned bounding box.
+ */
 void btHeightfieldTerrainShape::quantizeWithClamp(int* out, const btVector3& point,int /*isMax*/) const
 {
@@ -185,33 +265,41 @@
 	clampedPoint.setMin(m_localAabbMax);
 
-	btVector3 v = (clampedPoint);// - m_bvhAabbMin) * m_bvhQuantization;
-
-	//TODO: optimization: check out how to removed this btFabs
+	out[0] = getQuantized(clampedPoint.getX());
+	out[1] = getQuantized(clampedPoint.getY());
+	out[2] = getQuantized(clampedPoint.getZ());
 		
-	out[0] = (int)(v.getX() + v.getX() / btFabs(v.getX())* btScalar(0.5) );
-	out[1] = (int)(v.getY() + v.getY() / btFabs(v.getY())* btScalar(0.5) );
-	out[2] = (int)(v.getZ() + v.getZ() / btFabs(v.getZ())* btScalar(0.5) );
-	
-}
-
-
+}
+
+
+
+/// process all triangles within the provided axis-aligned bounding box
+/**
+  basic algorithm:
+    - convert input aabb to local coordinates (scale down and shift for local origin)
+    - convert input aabb to a range of heightfield grid points (quantize)
+    - iterate over all triangles in that subset of the grid
+ */
 void	btHeightfieldTerrainShape::processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const
 {
-	(void)callback;
-	(void)aabbMax;
-	(void)aabbMin;
+	// scale down the input aabb's so they are in local (non-scaled) coordinates
+	btVector3	localAabbMin = aabbMin*btVector3(1.f/m_localScaling[0],1.f/m_localScaling[1],1.f/m_localScaling[2]);
+	btVector3	localAabbMax = aabbMax*btVector3(1.f/m_localScaling[0],1.f/m_localScaling[1],1.f/m_localScaling[2]);
+
+	// account for local origin
+	localAabbMin += m_localOrigin;
+	localAabbMax += m_localOrigin;
 
 	//quantize the aabbMin and aabbMax, and adjust the start/end ranges
-
 	int	quantizedAabbMin[3];
 	int	quantizedAabbMax[3];
-
-	btVector3	localAabbMin = aabbMin*btVector3(1.f/m_localScaling[0],1.f/m_localScaling[1],1.f/m_localScaling[2]);
-	btVector3	localAabbMax = aabbMax*btVector3(1.f/m_localScaling[0],1.f/m_localScaling[1],1.f/m_localScaling[2]);
-	
 	quantizeWithClamp(quantizedAabbMin, localAabbMin,0);
 	quantizeWithClamp(quantizedAabbMax, localAabbMax,1);
 	
-	
+	// expand the min/max quantized values
+	// this is to catch the case where the input aabb falls between grid points!
+	for (int i = 0; i < 3; ++i) {
+		quantizedAabbMin[i]--;
+		quantizedAabbMax[i]++;
+	}	
 
 	int startX=0;
@@ -224,9 +312,4 @@
 	case 0:
 		{
-			quantizedAabbMin[1]+=m_heightStickWidth/2-1;
-			quantizedAabbMax[1]+=m_heightStickWidth/2+1;
-			quantizedAabbMin[2]+=m_heightStickLength/2-1;
-			quantizedAabbMax[2]+=m_heightStickLength/2+1;
-
 			if (quantizedAabbMin[1]>startX)
 				startX = quantizedAabbMin[1];
@@ -241,9 +324,4 @@
 	case 1:
 		{
-			quantizedAabbMin[0]+=m_heightStickWidth/2-1;
-			quantizedAabbMax[0]+=m_heightStickWidth/2+1;
-			quantizedAabbMin[2]+=m_heightStickLength/2-1;
-			quantizedAabbMax[2]+=m_heightStickLength/2+1;
-
 			if (quantizedAabbMin[0]>startX)
 				startX = quantizedAabbMin[0];
@@ -258,9 +336,4 @@
 	case 2:
 		{
-			quantizedAabbMin[0]+=m_heightStickWidth/2-1;
-			quantizedAabbMax[0]+=m_heightStickWidth/2+1;
-			quantizedAabbMin[1]+=m_heightStickLength/2-1;
-			quantizedAabbMax[1]+=m_heightStickLength/2+1;
-
 			if (quantizedAabbMin[0]>startX)
 				startX = quantizedAabbMin[0];
Index: code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h
===================================================================
--- code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h	(revision 2192)
+++ code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h	(revision 2430)
@@ -19,6 +19,43 @@
 #include "btConcaveShape.h"
 
-///The btHeightfieldTerrainShape simulates a 2D heightfield terrain collision shape. You can also use the more general btBvhTriangleMeshShape instead.
-///An example implementation of btHeightfieldTerrainShape is provided in Demos/VehicleDemo/VehicleDemo.cpp
+///btHeightfieldTerrainShape simulates a 2D heightfield terrain
+/**
+  The caller is responsible for maintaining the heightfield array; this
+  class does not make a copy.
+
+  The heightfield can be dynamic so long as the min/max height values
+  capture the extremes (heights must always be in that range).
+
+  The local origin of the heightfield is assumed to be the exact
+  center (as determined by width and length and height, with each
+  axis multiplied by the localScaling).
+
+  Most (but not all) rendering and heightfield libraries assume upAxis = 1
+  (that is, the y-axis is "up").  This class allows any of the 3 coordinates
+  to be "up".  Make sure your choice of axis is consistent with your rendering
+  system.
+
+  The heightfield heights are determined from the data type used for the
+  heightfieldData array.  
+
+   - PHY_UCHAR: height at a point is the uchar value at the
+       grid point, multipled by heightScale.  uchar isn't recommended
+       because of its inability to deal with negative values, and
+       low resolution (8-bit).
+
+   - PHY_SHORT: height at a point is the short int value at that grid
+       point, multipled by heightScale.
+
+   - PHY_FLOAT: height at a point is the float value at that grid
+       point.  heightScale is ignored when using the float heightfield
+       data type.
+
+  Whatever the caller specifies as minHeight and maxHeight will be honored.
+  The class will not inspect the heightfield to discover the actual minimum
+  or maximum heights.  These values are used to determine the heightfield's
+  axis-aligned bounding box, multiplied by localScaling.
+
+  For usage and testing see the TerrainDemo.
+ */
 class btHeightfieldTerrainShape : public btConcaveShape
 {
@@ -26,19 +63,23 @@
 	btVector3	m_localAabbMin;
 	btVector3	m_localAabbMax;
-	
+	btVector3	m_localOrigin;
+
 	///terrain data
 	int	m_heightStickWidth;
 	int m_heightStickLength;
+	btScalar	m_minHeight;
 	btScalar	m_maxHeight;
 	btScalar m_width;
 	btScalar m_length;
+	btScalar m_heightScale;
 	union
 	{
 		unsigned char*	m_heightfieldDataUnsignedChar;
+		short*		m_heightfieldDataShort;
 		btScalar*			m_heightfieldDataFloat;
 		void*			m_heightfieldDataUnknown;
 	};
-	
-	bool	m_useFloatData;
+
+	PHY_ScalarType	m_heightDataType;	
 	bool	m_flipQuadEdges;
   bool  m_useDiamondSubdivision;
@@ -52,15 +93,37 @@
 	void		getVertex(int x,int y,btVector3& vertex) const;
 
-	inline bool testQuantizedAabbAgainstQuantizedAabb(int* aabbMin1, int* aabbMax1,const  int* aabbMin2,const  int* aabbMax2) const
-	{
-		bool overlap = true;
-		overlap = (aabbMin1[0] > aabbMax2[0] || aabbMax1[0] < aabbMin2[0]) ? false : overlap;
-		overlap = (aabbMin1[2] > aabbMax2[2] || aabbMax1[2] < aabbMin2[2]) ? false : overlap;
-		overlap = (aabbMin1[1] > aabbMax2[1] || aabbMax1[1] < aabbMin2[1]) ? false : overlap;
-		return overlap;
-	}
+
+
+	/// protected initialization
+	/**
+	  Handles the work of constructors so that public constructors can be
+	  backwards-compatible without a lot of copy/paste.
+	 */
+	void initialize(int heightStickWidth, int heightStickLength,
+	                void* heightfieldData, btScalar heightScale,
+	                btScalar minHeight, btScalar maxHeight, int upAxis,
+	                PHY_ScalarType heightDataType, bool flipQuadEdges);
 
 public:
-	btHeightfieldTerrainShape(int heightStickWidth,int heightStickHeight,void* heightfieldData, btScalar maxHeight,int upAxis,bool useFloatData,bool flipQuadEdges);
+	/// preferred constructor
+	/**
+	  This constructor supports a range of heightfield
+	  data types, and allows for a non-zero minimum height value.
+	  heightScale is needed for any integer-based heightfield data types.
+	 */
+	btHeightfieldTerrainShape(int heightStickWidth,int heightStickLength,
+	                          void* heightfieldData, btScalar heightScale,
+	                          btScalar minHeight, btScalar maxHeight,
+	                          int upAxis, PHY_ScalarType heightDataType,
+	                          bool flipQuadEdges);
+
+	/// legacy constructor
+	/**
+	  The legacy constructor assumes the heightfield has a minimum height
+	  of zero.  Only unsigned char or floats are supported.  For legacy
+	  compatibility reasons, heightScale is calculated as maxHeight / 65535 
+	  (and is only used when useFloatData = false).
+ 	 */
+	btHeightfieldTerrainShape(int heightStickWidth,int heightStickLength,void* heightfieldData, btScalar maxHeight,int upAxis,bool useFloatData,bool flipQuadEdges);
 
 	virtual ~btHeightfieldTerrainShape();
Index: code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btMinkowskiSumShape.cpp
===================================================================
--- code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btMinkowskiSumShape.cpp	(revision 2192)
+++ code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btMinkowskiSumShape.cpp	(revision 2430)
@@ -36,5 +36,5 @@
 void	btMinkowskiSumShape::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const
 {
-	//todo: could make recursive use of batching. probably this shape is not used frequently.
+	///@todo: could make recursive use of batching. probably this shape is not used frequently.
 	for (int i=0;i<numVectors;i++)
 	{
Index: code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btOptimizedBvh.cpp
===================================================================
--- code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btOptimizedBvh.cpp	(revision 2192)
+++ code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btOptimizedBvh.cpp	(revision 2430)
@@ -320,17 +320,17 @@
 					
 					int graphicsindex = indicestype==PHY_SHORT?((unsigned short*)gfxbase)[j]:gfxbase[j];
-					btScalar* graphicsbase = (btScalar*)(vertexbase+graphicsindex*stride);
-#ifdef DEBUG_PATCH_COLORS
-					btVector3 mycolor = color[index&3];
-					graphicsbase[8] = mycolor.getX();
-					graphicsbase[9] = mycolor.getY();
-					graphicsbase[10] = mycolor.getZ();
-#endif //DEBUG_PATCH_COLORS
-
-
-					triangleVerts[j] = btVector3(
-						graphicsbase[0]*meshScaling.getX(),
-						graphicsbase[1]*meshScaling.getY(),
-						graphicsbase[2]*meshScaling.getZ());
+					if (type == PHY_FLOAT)
+					{
+						float* graphicsbase = (float*)(vertexbase+graphicsindex*stride);
+						triangleVerts[j] = btVector3(
+							graphicsbase[0]*meshScaling.getX(),
+							graphicsbase[1]*meshScaling.getY(),
+							graphicsbase[2]*meshScaling.getZ());
+					}
+					else
+					{
+						double* graphicsbase = (double*)(vertexbase+graphicsindex*stride);
+						triangleVerts[j] = btVector3( btScalar(graphicsbase[0]*meshScaling.getX()), btScalar(graphicsbase[1]*meshScaling.getY()), btScalar(graphicsbase[2]*meshScaling.getZ()));
+					}
 				}
 
Index: code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btPolyhedralConvexShape.cpp
===================================================================
--- code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btPolyhedralConvexShape.cpp	(revision 2192)
+++ code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btPolyhedralConvexShape.cpp	(revision 2430)
@@ -16,6 +16,5 @@
 #include "BulletCollision/CollisionShapes/btPolyhedralConvexShape.h"
 
-btPolyhedralConvexShape::btPolyhedralConvexShape()
-:btConvexInternalShape(),
+btPolyhedralConvexShape::btPolyhedralConvexShape() :btConvexInternalShape(),
 m_localAabbMin(1,1,1),
 m_localAabbMax(-1,-1,-1),
@@ -25,5 +24,4 @@
 
 }
-
 
 
Index: code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btPolyhedralConvexShape.h
===================================================================
--- code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btPolyhedralConvexShape.h	(revision 2192)
+++ code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btPolyhedralConvexShape.h	(revision 2430)
@@ -17,5 +17,4 @@
 #define BU_SHAPE
 
-#include "LinearMath/btPoint3.h"
 #include "LinearMath/btMatrix3x3.h"
 #include "LinearMath/btAabbUtil2.h"
@@ -32,15 +31,30 @@
 	bool		m_isLocalAabbValid;
 
-	btPolyhedralConvexShape();
 public:
 
-	
+	btPolyhedralConvexShape();
 
 	//brute force implementations
+
 	virtual btVector3	localGetSupportingVertexWithoutMargin(const btVector3& vec)const;
 	virtual void	batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const;
+
 	
 	virtual void	calculateLocalInertia(btScalar mass,btVector3& inertia) const;
 
+
+	void setCachedLocalAabb (const btVector3& aabbMin, const btVector3& aabbMax)
+	{
+		m_isLocalAabbValid = true;
+		m_localAabbMin = aabbMin;
+		m_localAabbMax = aabbMax;
+	}
+
+	inline void getCachedLocalAabb (btVector3& aabbMin, btVector3& aabbMax) const
+	{
+		btAssert(m_isLocalAabbValid);
+		aabbMin = m_localAabbMin;
+		aabbMax = m_localAabbMax;
+	}
 
 	inline void getNonvirtualAabb(const btTransform& trans,btVector3& aabbMin,btVector3& aabbMax, btScalar margin) const
@@ -61,11 +75,11 @@
 	virtual int	getNumVertices() const = 0 ;
 	virtual int getNumEdges() const = 0;
-	virtual void getEdge(int i,btPoint3& pa,btPoint3& pb) const = 0;
-	virtual void getVertex(int i,btPoint3& vtx) const = 0;
+	virtual void getEdge(int i,btVector3& pa,btVector3& pb) const = 0;
+	virtual void getVertex(int i,btVector3& vtx) const = 0;
 	virtual int	getNumPlanes() const = 0;
-	virtual void getPlane(btVector3& planeNormal,btPoint3& planeSupport,int i ) const = 0;
+	virtual void getPlane(btVector3& planeNormal,btVector3& planeSupport,int i ) const = 0;
 //	virtual int getIndex(int i) const = 0 ; 
 
-	virtual	bool isInside(const btPoint3& pt,btScalar tolerance) const = 0;
+	virtual	bool isInside(const btVector3& pt,btScalar tolerance) const = 0;
 	
 	/// optional Hull is for optional Separating Axis Test Hull collision detection, see Hull.cpp
Index: code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.cpp
===================================================================
--- code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.cpp	(revision 2192)
+++ code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.cpp	(revision 2430)
@@ -16,5 +16,5 @@
 #include "btScaledBvhTriangleMeshShape.h"
 
-btScaledBvhTriangleMeshShape::btScaledBvhTriangleMeshShape(btBvhTriangleMeshShape* childShape,btVector3 localScaling)
+btScaledBvhTriangleMeshShape::btScaledBvhTriangleMeshShape(btBvhTriangleMeshShape* childShape,const btVector3& localScaling)
 :m_localScaling(localScaling),m_bvhTriMeshShape(childShape)
 {
@@ -35,5 +35,5 @@
 public:
 
-	btScaledTriangleCallback(btTriangleCallback* originalCallback,btVector3 localScaling)
+	btScaledTriangleCallback(btTriangleCallback* originalCallback,const btVector3& localScaling)
 		:m_originalCallback(originalCallback),
 		m_localScaling(localScaling)
@@ -94,5 +94,5 @@
 	btMatrix3x3 abs_b = trans.getBasis().absolute();  
 
-	btPoint3 center = trans(localCenter);
+	btVector3 center = trans(localCenter);
 
 	btVector3 extent = btVector3(abs_b[0].dot(localHalfExtents),
Index: code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.h
===================================================================
--- code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.h	(revision 2192)
+++ code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.h	(revision 2430)
@@ -33,5 +33,5 @@
 
 
-	btScaledBvhTriangleMeshShape(btBvhTriangleMeshShape* childShape,btVector3 localScaling);
+	btScaledBvhTriangleMeshShape(btBvhTriangleMeshShape* childShape,const btVector3& localScaling);
 
 	virtual ~btScaledBvhTriangleMeshShape();
Index: code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btSphereShape.cpp
===================================================================
--- code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btSphereShape.cpp	(revision 2192)
+++ code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btSphereShape.cpp	(revision 2430)
@@ -18,12 +18,4 @@
 
 #include "LinearMath/btQuaternion.h"
-
-
-btSphereShape ::btSphereShape (btScalar radius) : btConvexInternalShape ()
-{
-	m_shapeType = SPHERE_SHAPE_PROXYTYPE;
-	m_implicitShapeDimensions.setX(radius);
-	m_collisionMargin = radius;
-}
 
 btVector3	btSphereShape::localGetSupportingVertexWithoutMargin(const btVector3& vec)const
Index: code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btSphereShape.h
===================================================================
--- code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btSphereShape.h	(revision 2192)
+++ code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btSphereShape.h	(revision 2430)
@@ -28,6 +28,10 @@
 	BT_DECLARE_ALIGNED_ALLOCATOR();
 
-	btSphereShape (btScalar radius);
-	
+	btSphereShape (btScalar radius) : btConvexInternalShape ()
+	{
+		m_shapeType = SPHERE_SHAPE_PROXYTYPE;
+		m_implicitShapeDimensions.setX(radius);
+		m_collisionMargin = radius;
+	}
 	
 	virtual btVector3	localGetSupportingVertex(const btVector3& vec)const;
Index: code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btStridingMeshInterface.h
===================================================================
--- code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btStridingMeshInterface.h	(revision 2192)
+++ code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btStridingMeshInterface.h	(revision 2430)
@@ -19,14 +19,7 @@
 #include "LinearMath/btVector3.h"
 #include "btTriangleCallback.h"
+#include "btConcaveShape.h"
 
-/// PHY_ScalarType enumerates possible scalar types.
-/// See the btStridingMeshInterface for its use
-typedef enum PHY_ScalarType {
-	PHY_FLOAT,
-	PHY_DOUBLE,
-	PHY_INTEGER,
-	PHY_SHORT,
-	PHY_FIXEDPOINT88
-} PHY_ScalarType;
+
 
 ///	The btStridingMeshInterface is the interface class for high performance generic access to triangle meshes, used in combination with btBvhTriangleMeshShape and some other collision shapes.
@@ -78,6 +71,14 @@
 
 		virtual bool	hasPremadeAabb() const { return false; }
-		virtual void	setPremadeAabb(const btVector3& aabbMin, const btVector3& aabbMax ) const {}
-		virtual void	getPremadeAabb(btVector3* aabbMin, btVector3* aabbMax ) const {}
+		virtual void	setPremadeAabb(const btVector3& aabbMin, const btVector3& aabbMax ) const
+                {
+                        (void) aabbMin;
+                        (void) aabbMax;
+                }
+		virtual void	getPremadeAabb(btVector3* aabbMin, btVector3* aabbMax ) const
+        {
+            (void) aabbMin;
+            (void) aabbMax;
+        }
 
 		const btVector3&	getScaling() const {
Index: code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btTetrahedronShape.cpp
===================================================================
--- code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btTetrahedronShape.cpp	(revision 2192)
+++ code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btTetrahedronShape.cpp	(revision 2430)
@@ -23,12 +23,12 @@
 }
 
-btBU_Simplex1to4::btBU_Simplex1to4(const btPoint3& pt0) : btPolyhedralConvexShape (),
-m_numVertices(0)
-{
-	m_shapeType = TETRAHEDRAL_SHAPE_PROXYTYPE;
-	addVertex(pt0);
-}
-
-btBU_Simplex1to4::btBU_Simplex1to4(const btPoint3& pt0,const btPoint3& pt1) : btPolyhedralConvexShape (),
+btBU_Simplex1to4::btBU_Simplex1to4(const btVector3& pt0) : btPolyhedralConvexShape (),
+m_numVertices(0)
+{
+	m_shapeType = TETRAHEDRAL_SHAPE_PROXYTYPE;
+	addVertex(pt0);
+}
+
+btBU_Simplex1to4::btBU_Simplex1to4(const btVector3& pt0,const btVector3& pt1) : btPolyhedralConvexShape (),
 m_numVertices(0)
 {
@@ -38,5 +38,5 @@
 }
 
-btBU_Simplex1to4::btBU_Simplex1to4(const btPoint3& pt0,const btPoint3& pt1,const btPoint3& pt2) : btPolyhedralConvexShape (),
+btBU_Simplex1to4::btBU_Simplex1to4(const btVector3& pt0,const btVector3& pt1,const btVector3& pt2) : btPolyhedralConvexShape (),
 m_numVertices(0)
 {
@@ -47,5 +47,5 @@
 }
 
-btBU_Simplex1to4::btBU_Simplex1to4(const btPoint3& pt0,const btPoint3& pt1,const btPoint3& pt2,const btPoint3& pt3) : btPolyhedralConvexShape (),
+btBU_Simplex1to4::btBU_Simplex1to4(const btVector3& pt0,const btVector3& pt1,const btVector3& pt2,const btVector3& pt3) : btPolyhedralConvexShape (),
 m_numVertices(0)
 {
@@ -61,5 +61,5 @@
 
 
-void btBU_Simplex1to4::addVertex(const btPoint3& pt)
+void btBU_Simplex1to4::addVertex(const btVector3& pt)
 {
 	m_vertices[m_numVertices++] = pt;
@@ -93,5 +93,5 @@
 }
 
-void btBU_Simplex1to4::getEdge(int i,btPoint3& pa,btPoint3& pb) const
+void btBU_Simplex1to4::getEdge(int i,btVector3& pa,btVector3& pb) const
 {
 	
@@ -157,5 +157,5 @@
 }
 
-void btBU_Simplex1to4::getVertex(int i,btPoint3& vtx) const
+void btBU_Simplex1to4::getVertex(int i,btVector3& vtx) const
 {
 	vtx = m_vertices[i];
@@ -184,5 +184,5 @@
 
 
-void btBU_Simplex1to4::getPlane(btVector3&, btPoint3& ,int ) const
+void btBU_Simplex1to4::getPlane(btVector3&, btVector3& ,int ) const
 {
 	
@@ -194,5 +194,5 @@
 }
 
-bool btBU_Simplex1to4::isInside(const btPoint3& ,btScalar ) const
+bool btBU_Simplex1to4::isInside(const btVector3& ,btScalar ) const
 {
 	return false;
Index: code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btTetrahedronShape.h
===================================================================
--- code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btTetrahedronShape.h	(revision 2192)
+++ code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btTetrahedronShape.h	(revision 2430)
@@ -28,13 +28,13 @@
 
 	int	m_numVertices;
-	btPoint3	m_vertices[4];
+	btVector3	m_vertices[4];
 
 public:
 	btBU_Simplex1to4();
 
-	btBU_Simplex1to4(const btPoint3& pt0);
-	btBU_Simplex1to4(const btPoint3& pt0,const btPoint3& pt1);
-	btBU_Simplex1to4(const btPoint3& pt0,const btPoint3& pt1,const btPoint3& pt2);
-	btBU_Simplex1to4(const btPoint3& pt0,const btPoint3& pt1,const btPoint3& pt2,const btPoint3& pt3);
+	btBU_Simplex1to4(const btVector3& pt0);
+	btBU_Simplex1to4(const btVector3& pt0,const btVector3& pt1);
+	btBU_Simplex1to4(const btVector3& pt0,const btVector3& pt1,const btVector3& pt2);
+	btBU_Simplex1to4(const btVector3& pt0,const btVector3& pt1,const btVector3& pt2,const btVector3& pt3);
 
     
@@ -46,5 +46,5 @@
 
 
-	void addVertex(const btPoint3& pt);
+	void addVertex(const btVector3& pt);
 
 	//PolyhedralConvexShape interface
@@ -54,15 +54,15 @@
 	virtual int getNumEdges() const;
 
-	virtual void getEdge(int i,btPoint3& pa,btPoint3& pb) const;
+	virtual void getEdge(int i,btVector3& pa,btVector3& pb) const;
 	
-	virtual void getVertex(int i,btPoint3& vtx) const;
+	virtual void getVertex(int i,btVector3& vtx) const;
 
 	virtual int	getNumPlanes() const;
 
-	virtual void getPlane(btVector3& planeNormal,btPoint3& planeSupport,int i) const;
+	virtual void getPlane(btVector3& planeNormal,btVector3& planeSupport,int i) const;
 
 	virtual int getIndex(int i) const;
 
-	virtual	bool isInside(const btPoint3& pt,btScalar tolerance) const;
+	virtual	bool isInside(const btVector3& pt,btScalar tolerance) const;
 
 
Index: code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btTriangleBuffer.h
===================================================================
--- code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btTriangleBuffer.h	(revision 2192)
+++ code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btTriangleBuffer.h	(revision 2430)
@@ -29,5 +29,5 @@
 };
 
-///btTriangleBuffer can be useful to collect and store overlapping triangles between AABB and concave objects that support 'processAllTriangles'
+///The btTriangleBuffer callback can be useful to collect and store overlapping triangles between AABB and concave objects that support 'processAllTriangles'
 ///Example usage of this class:
 ///			btTriangleBuffer	triBuf;
Index: code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btTriangleMesh.cpp
===================================================================
--- code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btTriangleMesh.cpp	(revision 2192)
+++ code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btTriangleMesh.cpp	(revision 2430)
@@ -75,15 +75,19 @@
 }
 
-int	btTriangleMesh::findOrAddVertex(const btVector3& vertex)
+
+int	btTriangleMesh::findOrAddVertex(const btVector3& vertex, bool removeDuplicateVertices)
 {
 	//return index of new/existing vertex
-	//todo: could use acceleration structure for this
+	///@todo: could use acceleration structure for this
 	if (m_use4componentVertices)
 	{
-		for (int i=0;i< m_4componentVertices.size();i++)
-		{
-			if ((m_4componentVertices[i]-vertex).length2() <= m_weldingThreshold)
+		if (removeDuplicateVertices)
 			{
-				return i;
+			for (int i=0;i< m_4componentVertices.size();i++)
+			{
+				if ((m_4componentVertices[i]-vertex).length2() <= m_weldingThreshold)
+				{
+					return i;
+				}
 			}
 		}
@@ -97,12 +101,15 @@
 	{
 		
-		for (int i=0;i< m_3componentVertices.size();i+=3)
+		if (removeDuplicateVertices)
 		{
-			btVector3 vtx(m_3componentVertices[i],m_3componentVertices[i+1],m_3componentVertices[i+2]);
-			if ((vtx-vertex).length2() <= m_weldingThreshold)
+			for (int i=0;i< m_3componentVertices.size();i+=3)
 			{
-				return i/3;
+				btVector3 vtx(m_3componentVertices[i],m_3componentVertices[i+1],m_3componentVertices[i+2]);
+				if ((vtx-vertex).length2() <= m_weldingThreshold)
+				{
+					return i/3;
+				}
 			}
-		}
+	}
 		m_3componentVertices.push_back(vertex.getX());
 		m_3componentVertices.push_back(vertex.getY());
@@ -115,11 +122,10 @@
 }
 		
-void	btTriangleMesh::addTriangle(const btVector3& vertex0,const btVector3& vertex1,const btVector3& vertex2)
+void	btTriangleMesh::addTriangle(const btVector3& vertex0,const btVector3& vertex1,const btVector3& vertex2,bool removeDuplicateVertices)
 {
 	m_indexedMeshes[0].m_numTriangles++;
-		
-	addIndex(findOrAddVertex(vertex0));
-	addIndex(findOrAddVertex(vertex1));
-	addIndex(findOrAddVertex(vertex2));
+	addIndex(findOrAddVertex(vertex0,removeDuplicateVertices));
+	addIndex(findOrAddVertex(vertex1,removeDuplicateVertices));
+	addIndex(findOrAddVertex(vertex2,removeDuplicateVertices));
 }
 
Index: code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btTriangleMesh.h
===================================================================
--- code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btTriangleMesh.h	(revision 2192)
+++ code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btTriangleMesh.h	(revision 2430)
@@ -26,5 +26,4 @@
 ///If you want to share triangle/index data between graphics mesh and collision mesh (btBvhTriangleMeshShape), you can directly use btTriangleIndexVertexArray or derive your own class from btStridingMeshInterface.
 ///Performance of btTriangleMesh and btTriangleIndexVertexArray used in a btBvhTriangleMeshShape is the same.
-///It has a brute-force option to weld together closeby vertices.
 class btTriangleMesh : public btTriangleIndexVertexArray
 {
@@ -43,5 +42,5 @@
 		btTriangleMesh (bool use32bitIndices=true,bool use4componentVertices=true);
 
-		int		findOrAddVertex(const btVector3& vertex);
+		int		findOrAddVertex(const btVector3& vertex, bool removeDuplicateVertices);
 		void	addIndex(int index);
 
@@ -55,6 +54,7 @@
 			return m_use4componentVertices;
 		}
-		
-		void	addTriangle(const btVector3& vertex0,const btVector3& vertex1,const btVector3& vertex2);
+		///By default addTriangle won't search for duplicate vertices, because the search is very slow for large triangle meshes.
+		///In general it is better to directly use btTriangleIndexVertexArray instead.
+		void	addTriangle(const btVector3& vertex0,const btVector3& vertex1,const btVector3& vertex2, bool removeDuplicateVertices=false);
 		
 		int getNumTriangles() const;
Index: code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btTriangleMeshShape.cpp
===================================================================
--- code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btTriangleMeshShape.cpp	(revision 2192)
+++ code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btTriangleMeshShape.cpp	(revision 2430)
@@ -54,5 +54,5 @@
 	btMatrix3x3 abs_b = trans.getBasis().absolute();  
 
-	btPoint3 center = trans(localCenter);
+	btVector3 center = trans(localCenter);
 
 	btVector3 extent = btVector3(abs_b[0].dot(localHalfExtents),
Index: code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btTriangleShape.h
===================================================================
--- code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btTriangleShape.h	(revision 2192)
+++ code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btTriangleShape.h	(revision 2430)
@@ -47,5 +47,5 @@
 	}
 	
-	virtual void getEdge(int i,btPoint3& pa,btPoint3& pb) const
+	virtual void getEdge(int i,btVector3& pa,btVector3& pb) const
 	{
 		getVertex(i,pa);
@@ -89,5 +89,5 @@
 
 
-	virtual void getPlane(btVector3& planeNormal,btPoint3& planeSupport,int i) const
+	virtual void getPlane(btVector3& planeNormal,btVector3& planeSupport,int i) const
 	{
 		getPlaneEquation(i,planeNormal,planeSupport);
@@ -105,5 +105,5 @@
 	}
 
-	virtual void getPlaneEquation(int i, btVector3& planeNormal,btPoint3& planeSupport) const
+	virtual void getPlaneEquation(int i, btVector3& planeNormal,btVector3& planeSupport) const
 	{
 		(void)i;
@@ -119,5 +119,5 @@
 	}
 
-		virtual	bool isInside(const btPoint3& pt,btScalar tolerance) const
+		virtual	bool isInside(const btVector3& pt,btScalar tolerance) const
 	{
 		btVector3 normal;
@@ -133,5 +133,5 @@
 			for (i=0;i<3;i++)
 			{
-				btPoint3 pa,pb;
+				btVector3 pa,pb;
 				getEdge(i,pa,pb);
 				btVector3 edge = pb-pa;
Index: code/branches/physics/src/bullet/BulletCollision/NarrowPhaseCollision/btConvexPenetrationDepthSolver.h
===================================================================
--- code/branches/physics/src/bullet/BulletCollision/NarrowPhaseCollision/btConvexPenetrationDepthSolver.h	(revision 2192)
+++ code/branches/physics/src/bullet/BulletCollision/NarrowPhaseCollision/btConvexPenetrationDepthSolver.h	(revision 2430)
@@ -22,5 +22,4 @@
 #include "btSimplexSolverInterface.h"
 class btConvexShape;
-#include "LinearMath/btPoint3.h"
 class btTransform;
 
@@ -34,5 +33,5 @@
 		const btConvexShape* convexA,const btConvexShape* convexB,
 					const btTransform& transA,const btTransform& transB,
-				btVector3& v, btPoint3& pa, btPoint3& pb,
+				btVector3& v, btVector3& pa, btVector3& pb,
 				class btIDebugDraw* debugDraw,btStackAlloc* stackAlloc
 				) = 0;
Index: code/branches/physics/src/bullet/BulletCollision/NarrowPhaseCollision/btGjkEpa.cpp
===================================================================
--- code/branches/physics/src/bullet/BulletCollision/NarrowPhaseCollision/btGjkEpa.cpp	(revision 2192)
+++ 	(revision )
@@ -1,628 +1,0 @@
-/*
-Bullet Continuous Collision Detection and Physics Library
-Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
-
-This software is provided 'as-is', without any express or implied warranty.
-In no event will the authors be held liable for any damages arising from the
-use of this software.
-Permission is granted to anyone to use this software for any purpose,
-including commercial applications, and to alter it and redistribute it
-freely,
-subject to the following restrictions:
-
-1. The origin of this software must not be misrepresented; you must not
-claim that you wrote the original software. If you use this software in a
-product, an acknowledgment in the product documentation would be appreciated
-but is not required.
-2. Altered source versions must be plainly marked as such, and must not be
-misrepresented as being the original software.
-3. This notice may not be removed or altered from any source distribution.
-*/
-
-/*
-GJK-EPA collision solver by Nathanael Presson
-Nov.2006
-*/
-
-#include "btGjkEpa.h"
-#include <string.h> //for memset
-#include "LinearMath/btStackAlloc.h"
-
-#if defined(DEBUG) || defined (_DEBUG)
-#include <stdio.h> //for debug printf
-#ifdef __SPU__
-#include <spu_printf.h>
-#define printf spu_printf
-#endif //__SPU__
-#endif
-
-namespace gjkepa_impl
-{
-
-//
-// Port. typedefs
-//
-
-typedef	btScalar		F;
-typedef bool			Z;
-typedef int				I;
-typedef unsigned int	U;
-typedef unsigned char	U1;
-typedef unsigned short	U2;
-
-typedef btVector3		Vector3;
-typedef btMatrix3x3		Rotation;
-
-//
-// Config
-//
-
-#if 0
-#define BTLOCALSUPPORT	localGetSupportingVertexWithoutMargin
-#else
-#define BTLOCALSUPPORT	localGetSupportingVertex
-#endif
-
-//
-// Const
-//
-
-
-#define cstInf				SIMD_INFINITY
-#define cstPi				SIMD_PI
-#define	cst2Pi				SIMD_2_PI
-#define GJK_maxiterations	(128)
-#define GJK_hashsize		(1<<6)
-#define GJK_hashmask		(GJK_hashsize-1)
-#define GJK_insimplex_eps	F(0.0001)
-#define GJK_sqinsimplex_eps	(GJK_insimplex_eps*GJK_insimplex_eps)
-#define EPA_maxiterations	256
-#define	EPA_inface_eps		F(0.01)
-#define EPA_accuracy		F(0.001)
-
-//
-// Utils
-//
-
-static inline F								Abs(F v)					{ return(v<0?-v:v); }
-static inline F								Sign(F v)					{ return(F(v<0?-1:1)); }
-template <typename T> static inline void	Swap(T& a,T& b)				{ T 
-t(a);a=b;b=t; }
-template <typename T> static inline T		Min(const T& a,const T& b)	{ 
-return(a<b?a:b); }
-template <typename T> static inline T		Max(const T& a,const T& b)	{ 
-return(a>b?a:b); }
-static inline void							ClearMemory(void* p,U sz)	{ memset(p,0,(size_t)sz); 
-}
-#if 0
-template <typename T> static inline void	Raise(const T& object)		{
-throw(object); }
-#else
-template <typename T> static inline void	Raise(const T&)				{}
-#endif
-
-
-
-//
-// GJK
-//
-struct	GJK
-	{
-	struct Mkv
-		{
-		Vector3	w;		/* Minkowski vertice	*/
-		Vector3	r;		/* Ray					*/
-		};
-	struct He
-		{
-		Vector3	v;
-		He*		n;
-		};
-	btStackAlloc*				sa;
-	btBlock*		sablock;
-	He*						table[GJK_hashsize];
-	Rotation				wrotations[2];
-	Vector3					positions[2];
-	const btConvexShape*	shapes[2];
-	Mkv						simplex[5];
-	Vector3					ray;
-	U						order;
-	U						iterations;
-	F						margin;
-	Z						failed;
-	//
-					GJK(btStackAlloc* psa,
-						const Rotation& wrot0,const Vector3& pos0,const btConvexShape* shape0,
-						const Rotation& wrot1,const Vector3& pos1,const btConvexShape* shape1,
-						F pmargin=0)
-		{
-		wrotations[0]=wrot0;positions[0]=pos0;shapes[0]=shape0;
-		wrotations[1]=wrot1;positions[1]=pos1;shapes[1]=shape1;
-		sa		=psa;
-		sablock	=sa->beginBlock();
-		margin	=pmargin;
-		failed	=false;
-		}
-	//
-					~GJK()
-		{
-		sa->endBlock(sablock);
-		}
-	// vdh : very dumm hash
-	static inline U	Hash(const Vector3& v)
-		{
-		//this doesn't compile under GCC 3.3.5, so add the ()...
-		//const U	h(U(v[0]*15461)^U(v[1]*83003)^U(v[2]*15473));
-		//return(((*((const U*)&h))*169639)&GJK_hashmask);
-	    const U h((U)(v[0]*15461)^(U)(v[1]*83003)^(U)(v[2]*15473));
-	    return(((*((const U*)&h))*169639)&GJK_hashmask);
-		}
-	//
-	inline Vector3	LocalSupport(const Vector3& d,U i) const
-		{
-		return(wrotations[i]*shapes[i]->BTLOCALSUPPORT(d*wrotations[i])+positions[i]);
-		}
-	//
-	inline void		Support(const Vector3& d,Mkv& v) const
-		{
-		v.r	=	d;
-		v.w	=	LocalSupport(d,0)-LocalSupport(-d,1)+d*margin;
-		}
-	#define SPX(_i_)	simplex[_i_]
-	#define SPXW(_i_)	simplex[_i_].w
-	//
-	inline Z		FetchSupport()
-		{
-		const U			h(Hash(ray));
-		He*				e = (He*)(table[h]);
-		while(e) { if(e->v==ray) { --order;return(false); } else e=e->n; }
-		e=(He*)sa->allocate(sizeof(He));e->v=ray;e->n=table[h];table[h]=e;
-		Support(ray,simplex[++order]);
-		return(ray.dot(SPXW(order))>0);
-		}
-	//
-	inline Z		SolveSimplex2(const Vector3& ao,const Vector3& ab)
-		{
-		if(ab.dot(ao)>=0)
-			{
-			const Vector3	cabo(cross(ab,ao));
-			if(cabo.length2()>GJK_sqinsimplex_eps)
-				{ ray=cross(cabo,ab); }
-				else
-				{ return(true); }
-			}
-			else
-			{ order=0;SPX(0)=SPX(1);ray=ao;	}
-		return(false);
-		}
-	//
-	inline Z		SolveSimplex3(const Vector3& ao,const Vector3& ab,const Vector3& 
-ac)
-		{
-		return(SolveSimplex3a(ao,ab,ac,cross(ab,ac)));
-		}
-	//
-	inline Z		SolveSimplex3a(const Vector3& ao,const Vector3& ab,const Vector3& 
-ac,const Vector3& cabc)
-		{
-				if((cross(cabc,ab)).dot(ao)<-GJK_insimplex_eps)
-			{ order=1;SPX(0)=SPX(1);SPX(1)=SPX(2);return(SolveSimplex2(ao,ab));	}
-		else	if((cross(cabc,ac)).dot(ao)>+GJK_insimplex_eps)
-			{ order=1;SPX(1)=SPX(2);return(SolveSimplex2(ao,ac)); }
-		else
-			{
-			const F			d(cabc.dot(ao));
-			if(Abs(d)>GJK_insimplex_eps)
-				{
-				if(d>0)
-					{ ray=cabc; }
-					else
-					{ ray=-cabc;Swap(SPX(0),SPX(1)); }
-				return(false);
-				} else return(true);
-			}
-		}
-	//
-	inline Z		SolveSimplex4(const Vector3& ao,const Vector3& ab,const Vector3& 
-ac,const Vector3& ad)
-		{
-		Vector3			crs;
-				if((crs=cross(ab,ac)).dot(ao)>GJK_insimplex_eps)
-			{ 
-order=2;SPX(0)=SPX(1);SPX(1)=SPX(2);SPX(2)=SPX(3);return(SolveSimplex3a(ao,ab,ac,crs)); 
-}
-		else	if((crs=cross(ac,ad)).dot(ao)>GJK_insimplex_eps)
-			{ order=2;SPX(2)=SPX(3);return(SolveSimplex3a(ao,ac,ad,crs)); }
-		else	if((crs=cross(ad,ab)).dot(ao)>GJK_insimplex_eps)
-			{ 
-order=2;SPX(1)=SPX(0);SPX(0)=SPX(2);SPX(2)=SPX(3);return(SolveSimplex3a(ao,ad,ab,crs)); 
-}
-		else	return(true);
-		}
-	//
-	inline Z		SearchOrigin(const Vector3& initray=Vector3(1,0,0))
-		{
-		iterations	=	0;
-		order		=	(U)-1;
-		failed		=	false;
-		ray			=	initray.normalized();
-		ClearMemory(table,sizeof(void*)*GJK_hashsize);
-		FetchSupport();
-		ray			=	-SPXW(0);
-		for(;iterations<GJK_maxiterations;++iterations)
-			{
-			const F		rl(ray.length());
-			ray/=rl>0?rl:1;
-			if(FetchSupport())
-				{
-				Z	found(false);
-				switch(order)
-					{
-					case	1:	found=SolveSimplex2(-SPXW(1),SPXW(0)-SPXW(1));break;
-					case	2:	found=SolveSimplex3(-SPXW(2),SPXW(1)-SPXW(2),SPXW(0)-SPXW(2));break;
-					case	3:	found=SolveSimplex4(-SPXW(3),SPXW(2)-SPXW(3),SPXW(1)-SPXW(3),SPXW(0)-SPXW(3));break;
-					}
-				if(found) return(true);
-				} else return(false);
-			}
-		failed=true;
-		return(false);
-		}
-	//
-	inline Z		EncloseOrigin()
-		{
-		switch(order)
-			{
-			/* Point		*/
-			case	0:	break;
-			/* Line			*/
-			case	1:
-				{
-				const Vector3	ab(SPXW(1)-SPXW(0));
-				const Vector3	b[]={	cross(ab,Vector3(1,0,0)),
-										cross(ab,Vector3(0,1,0)),
-										cross(ab,Vector3(0,0,1))};
-				const F			m[]={b[0].length2(),b[1].length2(),b[2].length2()};
-				const Rotation	r(btQuaternion(ab.normalized(),cst2Pi/3));
-				Vector3			w(b[m[0]>m[1]?m[0]>m[2]?0:2:m[1]>m[2]?1:2]);
-				Support(w.normalized(),simplex[4]);w=r*w;
-				Support(w.normalized(),simplex[2]);w=r*w;
-				Support(w.normalized(),simplex[3]);w=r*w;
-				order=4;
-				return(true);
-				}
-			break;
-			/* Triangle		*/
-			case	2:
-				{
-				const 
-Vector3	n(cross((SPXW(1)-SPXW(0)),(SPXW(2)-SPXW(0))).normalized());
-				Support( n,simplex[3]);
-				Support(-n,simplex[4]);
-				order=4;
-				return(true);
-				}
-			break;
-			/* Tetrahedron	*/
-			case	3:	return(true);
-			/* Hexahedron	*/
-			case	4:	return(true);
-			}
-		return(false);
-		}
-	#undef SPX
-	#undef SPXW
-	};
-
-//
-// EPA
-//
-struct	EPA
-	{
-	//
-	struct Face
-		{
-		const GJK::Mkv*	v[3];
-		Face*			f[3];
-		U				e[3];
-		Vector3			n;
-		F				d;
-		U				mark;
-		Face*			prev;
-		Face*			next;
-		Face()			{}
-		};
-	//
-	GJK*			gjk;
-	btStackAlloc*		sa;
-	Face*			root;
-	U				nfaces;
-	U				iterations;
-	Vector3			features[2][3];
-	Vector3			nearest[2];
-	Vector3			normal;
-	F				depth;
-	Z				failed;
-	//
-					EPA(GJK* pgjk)
-		{
-		gjk		=	pgjk;
-		sa		=	pgjk->sa;
-		}
-	//
-					~EPA()
-		{
-		}
-	//
-	inline Vector3	GetCoordinates(const Face* face) const
-		{
-		const Vector3	o(face->n*-face->d);
-		const F			a[]={	cross(face->v[0]->w-o,face->v[1]->w-o).length(),
-								cross(face->v[1]->w-o,face->v[2]->w-o).length(),
-								cross(face->v[2]->w-o,face->v[0]->w-o).length()};
-		const F			sm(a[0]+a[1]+a[2]);
-		return(Vector3(a[1],a[2],a[0])/(sm>0?sm:1));
-		}
-	//
-	inline Face*	FindBest() const
-		{
-		Face*	bf = 0;
-		if(root)
-			{
-			Face*	cf = root;
-			F		bd(cstInf);
-			do	{
-				if(cf->d<bd) { bd=cf->d;bf=cf; }
-				} while(0!=(cf=cf->next));
-			}
-		return(bf);
-		}
-	//
-	inline Z		Set(Face* f,const GJK::Mkv* a,const GJK::Mkv* b,const GJK::Mkv*
-c) const
-		{
-		const Vector3	nrm(cross(b->w-a->w,c->w-a->w));
-		const F			len(nrm.length());
-		const Z			valid(	(cross(a->w,b->w).dot(nrm)>=-EPA_inface_eps)&&
-								(cross(b->w,c->w).dot(nrm)>=-EPA_inface_eps)&&
-								(cross(c->w,a->w).dot(nrm)>=-EPA_inface_eps));
-		f->v[0]	=	a;
-		f->v[1]	=	b;
-		f->v[2]	=	c;
-		f->mark	=	0;
-		f->n	=	nrm/(len>0?len:cstInf);
-		f->d	=	Max<F>(0,-f->n.dot(a->w));
-		return(valid);
-		}
-	//
-	inline Face*	NewFace(const GJK::Mkv* a,const GJK::Mkv* b,const GJK::Mkv* c)
-		{
-		Face*	pf = (Face*)sa->allocate(sizeof(Face));
-		if(Set(pf,a,b,c))
-			{
-			if(root) root->prev=pf;
-			pf->prev=0;
-			pf->next=root;
-			root	=pf;
-			++nfaces;
-			}
-			else
-			{
-			pf->prev=pf->next=0;
-			}
-		return(pf);
-		}
-	//
-	inline void		Detach(Face* face)
-		{
-		if(face->prev||face->next)
-			{
-			--nfaces;
-			if(face==root)
-				{ root=face->next;root->prev=0; }
-				else
-				{
-				if(face->next==0)
-					{ face->prev->next=0; }
-					else
-					{ face->prev->next=face->next;face->next->prev=face->prev; }
-				}
-			face->prev=face->next=0;
-			}
-		}
-	//
-	inline void		Link(Face* f0,U e0,Face* f1,U e1) const
-		{
-		f0->f[e0]=f1;f1->e[e1]=e0;
-		f1->f[e1]=f0;f0->e[e0]=e1;
-		}
-	//
-	GJK::Mkv*		Support(const Vector3& w) const
-		{
-		GJK::Mkv*		v =(GJK::Mkv*)sa->allocate(sizeof(GJK::Mkv));
-		gjk->Support(w,*v);
-		return(v);
-		}
-	//
-	U				BuildHorizon(U markid,const GJK::Mkv* w,Face& f,U e,Face*& cf,Face*& 
-ff)
-		{
-		static const U	mod3[]={0,1,2,0,1};
-		U				ne(0);
-		if(f.mark!=markid)
-			{
-			const U	e1(mod3[e+1]);
-			if((f.n.dot(w->w)+f.d)>0)
-				{
-				Face*	nf = NewFace(f.v[e1],f.v[e],w);
-				Link(nf,0,&f,e);
-				if(cf) Link(cf,1,nf,2); else ff=nf;
-				cf=nf;ne=1;
-				}
-				else
-				{
-				const U	e2(mod3[e+2]);
-				Detach(&f);
-				f.mark	=	markid;
-				ne		+=	BuildHorizon(markid,w,*f.f[e1],f.e[e1],cf,ff);
-				ne		+=	BuildHorizon(markid,w,*f.f[e2],f.e[e2],cf,ff);
-				}
-			}
-		return(ne);
-		}
-	//
-	inline F		EvaluatePD(F accuracy=EPA_accuracy)
-		{
-		btBlock*	sablock = sa->beginBlock();
-		Face*				bestface = 0;
-		U					markid(1);
-		depth		=	-cstInf;
-		normal		=	Vector3(0,0,0);
-		root		=	0;
-		nfaces		=	0;
-		iterations	=	0;
-		failed		=	false;
-		/* Prepare hull		*/
-		if(gjk->EncloseOrigin())
-			{
-			const U*		pfidx = 0;
-			U				nfidx= 0;
-			const U*		peidx = 0;
-			U				neidx = 0;
-			GJK::Mkv*		basemkv[5];
-			Face*			basefaces[6];
-			switch(gjk->order)
-				{
-				/* Tetrahedron		*/
-				case	3:	{
-							static const U	fidx[4][3]={{2,1,0},{3,0,1},{3,1,2},{3,2,0}};
-							static const 
-U	eidx[6][4]={{0,0,2,1},{0,1,1,1},{0,2,3,1},{1,0,3,2},{2,0,1,2},{3,0,2,2}};
-							pfidx=(const U*)fidx;nfidx=4;peidx=(const U*)eidx;neidx=6;
-							}	break;
-				/* Hexahedron		*/
-				case	4:	{
-							static const 
-U	fidx[6][3]={{2,0,4},{4,1,2},{1,4,0},{0,3,1},{0,2,3},{1,3,2}};
-							static const 
-U	eidx[9][4]={{0,0,4,0},{0,1,2,1},{0,2,1,2},{1,1,5,2},{1,0,2,0},{2,2,3,2},{3,1,5,0},{3,0,4,2},{5,1,4,1}};
-							pfidx=(const U*)fidx;nfidx=6;peidx=(const U*)eidx;neidx=9;
-							}	break;
-				}
-			U i;
-
-			for( i=0;i<=gjk->order;++i)		{ 
-basemkv[i]=(GJK::Mkv*)sa->allocate(sizeof(GJK::Mkv));*basemkv[i]=gjk->simplex[i]; 
-}
-			for( i=0;i<nfidx;++i,pfidx+=3)		{ 
-basefaces[i]=NewFace(basemkv[pfidx[0]],basemkv[pfidx[1]],basemkv[pfidx[2]]); 
-}
-			for( i=0;i<neidx;++i,peidx+=4)		{ 
-Link(basefaces[peidx[0]],peidx[1],basefaces[peidx[2]],peidx[3]); }
-			}
-		if(0==nfaces)
-			{
-			sa->endBlock(sablock);
-			return(depth);
-			}
-		/* Expand hull		*/
-		for(;iterations<EPA_maxiterations;++iterations)
-			{
-			Face*		bf = FindBest();
-			if(bf)
-				{
-				GJK::Mkv*	w = Support(-bf->n);
-				const F		d(bf->n.dot(w->w)+bf->d);
-				bestface	=	bf;
-				if(d<-accuracy)
-					{
-					Face*	cf =0;
-					Face*	ff =0;
-					U		nf = 0;
-					Detach(bf);
-					bf->mark=++markid;
-					for(U i=0;i<3;++i)	{ 
-nf+=BuildHorizon(markid,w,*bf->f[i],bf->e[i],cf,ff); }
-					if(nf<=2)			{ break; }
-					Link(cf,1,ff,2);
-					} else break;
-				} else break;
-			}
-		/* Extract contact	*/
-		if(bestface)
-			{
-			const Vector3	b(GetCoordinates(bestface));
-			normal			=	bestface->n;
-			depth			=	Max<F>(0,bestface->d);
-			for(U i=0;i<2;++i)
-				{
-				const F	s(F(i?-1:1));
-				for(U j=0;j<3;++j)
-					{
-					features[i][j]=gjk->LocalSupport(s*bestface->v[j]->r,i);
-					}
-				}
-			nearest[0]		=	features[0][0]*b.x()+features[0][1]*b.y()+features[0][2]*b.z();
-			nearest[1]		=	features[1][0]*b.x()+features[1][1]*b.y()+features[1][2]*b.z();
-			} else failed=true;
-		sa->endBlock(sablock);
-		return(depth);
-		}
-	};
-}
-
-//
-// Api
-//
-
-using namespace	gjkepa_impl;
-
-
-
-//
-bool	btGjkEpaSolver::Collide(const btConvexShape *shape0,const btTransform &wtrs0,
-								const btConvexShape *shape1,const btTransform &wtrs1,
-								btScalar	radialmargin,
-								btStackAlloc* stackAlloc,
-								sResults&	results)
-{
-	
-
-/* Initialize					*/
-results.witnesses[0]	=
-results.witnesses[1]	=
-results.normal			=	Vector3(0,0,0);
-results.depth			=	0;
-results.status			=	sResults::Separated;
-results.epa_iterations	=	0;
-results.gjk_iterations	=	0;
-/* Use GJK to locate origin		*/
-GJK			gjk(stackAlloc,
-				wtrs0.getBasis(),wtrs0.getOrigin(),shape0,
-				wtrs1.getBasis(),wtrs1.getOrigin(),shape1,
-				radialmargin+EPA_accuracy);
-const Z		collide(gjk.SearchOrigin());
-results.gjk_iterations	=	static_cast<int>(gjk.iterations+1);
-if(collide)
-	{
-	/* Then EPA for penetration depth	*/
-	EPA			epa(&gjk);
-	const F		pd(epa.EvaluatePD());
-	results.epa_iterations	=	static_cast<int>(epa.iterations+1);
-	if(pd>0)
-		{
-		results.status			=	sResults::Penetrating;
-		results.normal			=	epa.normal;
-		results.depth			=	pd;
-		results.witnesses[0]	=	epa.nearest[0];
-		results.witnesses[1]	=	epa.nearest[1];
-		return(true);
-		} else { if(epa.failed) results.status=sResults::EPA_Failed; }
-	} else { if(gjk.failed) results.status=sResults::GJK_Failed; }
-return(false);
-}
-
-
-
-
-
Index: code/branches/physics/src/bullet/BulletCollision/NarrowPhaseCollision/btGjkEpa.h
===================================================================
--- code/branches/physics/src/bullet/BulletCollision/NarrowPhaseCollision/btGjkEpa.h	(revision 2192)
+++ 	(revision )
@@ -1,53 +1,0 @@
-/*
-Bullet Continuous Collision Detection and Physics Library
-Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
-
-This software is provided 'as-is', without any express or implied warranty.
-In no event will the authors be held liable for any damages arising from the use of this software.
-Permission is granted to anyone to use this software for any purpose, 
-including commercial applications, and to alter it and redistribute it freely, 
-subject to the following restrictions:
-
-1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
-2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
-3. This notice may not be removed or altered from any source distribution.
-*/
-
-/*
-GJK-EPA collision solver by Nathanael Presson
-Nov.2006
-*/
-
-
-#ifndef _05E48D53_04E0_49ad_BB0A_D74FE62E7366_
-#define _05E48D53_04E0_49ad_BB0A_D74FE62E7366_
-#include "BulletCollision/CollisionShapes/btConvexShape.h"
-
-class btStackAlloc;
-
-///btGjkEpaSolver contributed under zlib by Nathanael Presson
-struct	btGjkEpaSolver
-{
-struct	sResults
-	{
-	enum eStatus
-		{
-		Separated,		/* Shapes doesnt penetrate												*/ 
-		Penetrating,	/* Shapes are penetrating												*/ 
-		GJK_Failed,		/* GJK phase fail, no big issue, shapes are probably just 'touching'	*/ 
-		EPA_Failed		/* EPA phase fail, bigger problem, need to save parameters, and debug	*/ 
-		}		status;
-	btVector3	witnesses[2];
-	btVector3	normal;
-	btScalar	depth;
-	int	epa_iterations;
-	int	gjk_iterations;
-	};
-static bool	Collide(const btConvexShape* shape0,const btTransform& wtrs0,
-					const btConvexShape* shape1,const btTransform& wtrs1,
-					btScalar	radialmargin,
-					btStackAlloc* stackAlloc,
-					sResults&	results);
-};
-
-#endif
Index: code/branches/physics/src/bullet/BulletCollision/NarrowPhaseCollision/btGjkEpa2.cpp
===================================================================
--- code/branches/physics/src/bullet/BulletCollision/NarrowPhaseCollision/btGjkEpa2.cpp	(revision 2192)
+++ code/branches/physics/src/bullet/BulletCollision/NarrowPhaseCollision/btGjkEpa2.cpp	(revision 2430)
@@ -38,5 +38,5 @@
 {
 
-// Config
+	// Config
 
 	/* GJK	*/ 
@@ -59,709 +59,709 @@
 
 
-// Shorthands
-typedef unsigned int	U;
-typedef unsigned char	U1;
-
-// MinkowskiDiff
-struct	MinkowskiDiff
+	// Shorthands
+	typedef unsigned int	U;
+	typedef unsigned char	U1;
+
+	// MinkowskiDiff
+	struct	MinkowskiDiff
 	{
-	const btConvexShape*	m_shapes[2];
-	btMatrix3x3				m_toshape1;
-	btTransform				m_toshape0;
-	btVector3				(btConvexShape::*Ls)(const btVector3&) const;
-	void					EnableMargin(bool enable)
-		{
-		if(enable)
-			Ls=&btConvexShape::localGetSupportVertexNonVirtual;
+		const btConvexShape*	m_shapes[2];
+		btMatrix3x3				m_toshape1;
+		btTransform				m_toshape0;
+		btVector3				(btConvexShape::*Ls)(const btVector3&) const;
+		void					EnableMargin(bool enable)
+		{
+			if(enable)
+				Ls=&btConvexShape::localGetSupportVertexNonVirtual;
 			else
-			Ls=&btConvexShape::localGetSupportVertexWithoutMarginNonVirtual;
+				Ls=&btConvexShape::localGetSupportVertexWithoutMarginNonVirtual;
 		}	
-	inline btVector3		Support0(const btVector3& d) const
-		{
-		return(((m_shapes[0])->*(Ls))(d));
+		inline btVector3		Support0(const btVector3& d) const
+		{
+			return(((m_shapes[0])->*(Ls))(d));
 		}
-	inline btVector3		Support1(const btVector3& d) const
-		{
-		return(m_toshape0*((m_shapes[1])->*(Ls))(m_toshape1*d));
+		inline btVector3		Support1(const btVector3& d) const
+		{
+			return(m_toshape0*((m_shapes[1])->*(Ls))(m_toshape1*d));
 		}
-	inline btVector3		Support(const btVector3& d) const
-		{
-		return(Support0(d)-Support1(-d));
+		inline btVector3		Support(const btVector3& d) const
+		{
+			return(Support0(d)-Support1(-d));
 		}
-	btVector3				Support(const btVector3& d,U index) const
-		{
-		if(index)
-			return(Support1(d));
+		btVector3				Support(const btVector3& d,U index) const
+		{
+			if(index)
+				return(Support1(d));
 			else
-			return(Support0(d));
+				return(Support0(d));
 		}
 	};
 
-typedef	MinkowskiDiff	tShape;
-
-
-// GJK
-struct	GJK
-{
-/* Types		*/ 
-struct	sSV
+	typedef	MinkowskiDiff	tShape;
+
+
+	// GJK
+	struct	GJK
 	{
-	btVector3	d,w;
-	};
-struct	sSimplex
-	{
-	sSV*		c[4];
-	btScalar	p[4];
-	U			rank;
-	};
-struct	eStatus	{ enum _ {
-	Valid,
-	Inside,
-	Failed		};};
-/* Fields		*/ 
-tShape			m_shape;
-btVector3		m_ray;
-btScalar		m_distance;
-sSimplex		m_simplices[2];
-sSV				m_store[4];
-sSV*			m_free[4];
-U				m_nfree;
-U				m_current;
-sSimplex*		m_simplex;
-eStatus::_		m_status;
-/* Methods		*/ 
-					GJK()
-	{
-	Initialize();
-	}
-void				Initialize()
-	{
-	m_ray		=	btVector3(0,0,0);
-	m_nfree		=	0;
-	m_status	=	eStatus::Failed;
-	m_current	=	0;
-	m_distance	=	0;
-	}
-eStatus::_			Evaluate(const tShape& shapearg,const btVector3& guess)
-	{
-	U			iterations=0;
-	btScalar	sqdist=0;
-	btScalar	alpha=0;
-	btVector3	lastw[4];
-	U			clastw=0;
-	/* Initialize solver		*/ 
-	m_free[0]			=	&m_store[0];
-	m_free[1]			=	&m_store[1];
-	m_free[2]			=	&m_store[2];
-	m_free[3]			=	&m_store[3];
-	m_nfree				=	4;
-	m_current			=	0;
-	m_status			=	eStatus::Valid;
-	m_shape				=	shapearg;
-	m_distance			=	0;
-	/* Initialize simplex		*/ 
-	m_simplices[0].rank	=	0;
-	m_ray				=	guess;
-	const btScalar	sqrl=	m_ray.length2();
-	appendvertice(m_simplices[0],sqrl>0?-m_ray:btVector3(1,0,0));
-	m_simplices[0].p[0]	=	1;
-	m_ray				=	m_simplices[0].c[0]->w;	
-	sqdist				=	sqrl;
-	lastw[0]			=
-	lastw[1]			=
-	lastw[2]			=
-	lastw[3]			=	m_ray;
-	/* Loop						*/ 
-	do	{
-		const U		next=1-m_current;
-		sSimplex&	cs=m_simplices[m_current];
-		sSimplex&	ns=m_simplices[next];
-		/* Check zero							*/ 
-		const btScalar	rl=m_ray.length();
-		if(rl<GJK_MIN_DISTANCE)
-			{/* Touching or inside				*/ 
-			m_status=eStatus::Inside;
-			break;
-			}
-		/* Append new vertice in -'v' direction	*/ 
-		appendvertice(cs,-m_ray);
-		const btVector3&	w=cs.c[cs.rank-1]->w;
-		bool				found=false;
-		for(U i=0;i<4;++i)
-			{
-			if((w-lastw[i]).length2()<GJK_DUPLICATED_EPS)
-				{ found=true;break; }
-			}
-		if(found)
-			{/* Return old simplex				*/ 
-			removevertice(m_simplices[m_current]);
-			break;
-			}
-			else
-			{/* Update lastw					*/ 
-			lastw[clastw=(clastw+1)&3]=w;
-			}
-		/* Check for termination				*/ 
-		const btScalar	omega=dot(m_ray,w)/rl;
-		alpha=btMax(omega,alpha);
-		if(((rl-alpha)-(GJK_ACCURARY*rl))<=0)
-			{/* Return old simplex				*/ 
-			removevertice(m_simplices[m_current]);
-			break;
-			}		
-		/* Reduce simplex						*/ 
-		btScalar	weights[4];
-		U			mask=0;
-		switch(cs.rank)
-			{
-			case	2:	sqdist=projectorigin(	cs.c[0]->w,
-												cs.c[1]->w,
-												weights,mask);break;
-			case	3:	sqdist=projectorigin(	cs.c[0]->w,
-												cs.c[1]->w,
-												cs.c[2]->w,
-												weights,mask);break;
-			case	4:	sqdist=projectorigin(	cs.c[0]->w,
-												cs.c[1]->w,
-												cs.c[2]->w,
-												cs.c[3]->w,
-												weights,mask);break;
-			}
-		if(sqdist>=0)
-			{/* Valid	*/ 
-			ns.rank		=	0;
-			m_ray		=	btVector3(0,0,0);
-			m_current	=	next;
-			for(U i=0,ni=cs.rank;i<ni;++i)
-				{
-				if(mask&(1<<i))
-					{
-					ns.c[ns.rank]		=	cs.c[i];
-					ns.p[ns.rank++]		=	weights[i];
-					m_ray				+=	cs.c[i]->w*weights[i];
+		/* Types		*/ 
+		struct	sSV
+		{
+			btVector3	d,w;
+		};
+		struct	sSimplex
+		{
+			sSV*		c[4];
+			btScalar	p[4];
+			U			rank;
+		};
+		struct	eStatus	{ enum _ {
+			Valid,
+			Inside,
+			Failed		};};
+			/* Fields		*/ 
+			tShape			m_shape;
+			btVector3		m_ray;
+			btScalar		m_distance;
+			sSimplex		m_simplices[2];
+			sSV				m_store[4];
+			sSV*			m_free[4];
+			U				m_nfree;
+			U				m_current;
+			sSimplex*		m_simplex;
+			eStatus::_		m_status;
+			/* Methods		*/ 
+			GJK()
+			{
+				Initialize();
+			}
+			void				Initialize()
+			{
+				m_ray		=	btVector3(0,0,0);
+				m_nfree		=	0;
+				m_status	=	eStatus::Failed;
+				m_current	=	0;
+				m_distance	=	0;
+			}
+			eStatus::_			Evaluate(const tShape& shapearg,const btVector3& guess)
+			{
+				U			iterations=0;
+				btScalar	sqdist=0;
+				btScalar	alpha=0;
+				btVector3	lastw[4];
+				U			clastw=0;
+				/* Initialize solver		*/ 
+				m_free[0]			=	&m_store[0];
+				m_free[1]			=	&m_store[1];
+				m_free[2]			=	&m_store[2];
+				m_free[3]			=	&m_store[3];
+				m_nfree				=	4;
+				m_current			=	0;
+				m_status			=	eStatus::Valid;
+				m_shape				=	shapearg;
+				m_distance			=	0;
+				/* Initialize simplex		*/ 
+				m_simplices[0].rank	=	0;
+				m_ray				=	guess;
+				const btScalar	sqrl=	m_ray.length2();
+				appendvertice(m_simplices[0],sqrl>0?-m_ray:btVector3(1,0,0));
+				m_simplices[0].p[0]	=	1;
+				m_ray				=	m_simplices[0].c[0]->w;	
+				sqdist				=	sqrl;
+				lastw[0]			=
+					lastw[1]			=
+					lastw[2]			=
+					lastw[3]			=	m_ray;
+				/* Loop						*/ 
+				do	{
+					const U		next=1-m_current;
+					sSimplex&	cs=m_simplices[m_current];
+					sSimplex&	ns=m_simplices[next];
+					/* Check zero							*/ 
+					const btScalar	rl=m_ray.length();
+					if(rl<GJK_MIN_DISTANCE)
+					{/* Touching or inside				*/ 
+						m_status=eStatus::Inside;
+						break;
+					}
+					/* Append new vertice in -'v' direction	*/ 
+					appendvertice(cs,-m_ray);
+					const btVector3&	w=cs.c[cs.rank-1]->w;
+					bool				found=false;
+					for(U i=0;i<4;++i)
+					{
+						if((w-lastw[i]).length2()<GJK_DUPLICATED_EPS)
+						{ found=true;break; }
+					}
+					if(found)
+					{/* Return old simplex				*/ 
+						removevertice(m_simplices[m_current]);
+						break;
 					}
 					else
-					{
-					m_free[m_nfree++]	=	cs.c[i];
-					}
-				}
-			if(mask==15) m_status=eStatus::Inside;
-			}
-			else
-			{/* Return old simplex				*/ 
-			removevertice(m_simplices[m_current]);
-			break;
-			}
-		m_status=((++iterations)<GJK_MAX_ITERATIONS)?m_status:eStatus::Failed;
-		} while(m_status==eStatus::Valid);
-	m_simplex=&m_simplices[m_current];
-	switch(m_status)
-		{
-		case	eStatus::Valid:		m_distance=m_ray.length();break;
-		case	eStatus::Inside:	m_distance=0;break;
-		}	
-	return(m_status);
-	}
-bool					EncloseOrigin()
-	{
-	switch(m_simplex->rank)
-		{
-		case	1:
-			{
-			for(U i=0;i<3;++i)
-				{
-				btVector3		axis=btVector3(0,0,0);
-				axis[i]=1;
-				appendvertice(*m_simplex, axis);
-				if(EncloseOrigin())	return(true);
-				removevertice(*m_simplex);
-				appendvertice(*m_simplex,-axis);
-				if(EncloseOrigin())	return(true);
-				removevertice(*m_simplex);
-				}
-			}
-		break;
-		case	2:
-			{
-			const btVector3	d=m_simplex->c[1]->w-m_simplex->c[0]->w;
-			for(U i=0;i<3;++i)
-				{
-				btVector3		axis=btVector3(0,0,0);
-				axis[i]=1;
-				const btVector3	p=cross(d,axis);
-				if(p.length2()>0)
-					{
-					appendvertice(*m_simplex, p);
-					if(EncloseOrigin())	return(true);
-					removevertice(*m_simplex);
-					appendvertice(*m_simplex,-p);
-					if(EncloseOrigin())	return(true);
-					removevertice(*m_simplex);
-					}
-				}
-			}
-		break;
-		case	3:
-			{
-			const btVector3	n=cross(m_simplex->c[1]->w-m_simplex->c[0]->w,
-									m_simplex->c[2]->w-m_simplex->c[0]->w);
-			if(n.length2()>0)
-				{
-				appendvertice(*m_simplex,n);
-				if(EncloseOrigin())	return(true);
-				removevertice(*m_simplex);
-				appendvertice(*m_simplex,-n);
-				if(EncloseOrigin())	return(true);
-				removevertice(*m_simplex);
-				}
-			}
-		break;
-		case	4:
-			{
-			if(btFabs(det(	m_simplex->c[0]->w-m_simplex->c[3]->w,
+					{/* Update lastw					*/ 
+						lastw[clastw=(clastw+1)&3]=w;
+					}
+					/* Check for termination				*/ 
+					const btScalar	omega=dot(m_ray,w)/rl;
+					alpha=btMax(omega,alpha);
+					if(((rl-alpha)-(GJK_ACCURARY*rl))<=0)
+					{/* Return old simplex				*/ 
+						removevertice(m_simplices[m_current]);
+						break;
+					}		
+					/* Reduce simplex						*/ 
+					btScalar	weights[4];
+					U			mask=0;
+					switch(cs.rank)
+					{
+					case	2:	sqdist=projectorigin(	cs.c[0]->w,
+									cs.c[1]->w,
+									weights,mask);break;
+					case	3:	sqdist=projectorigin(	cs.c[0]->w,
+									cs.c[1]->w,
+									cs.c[2]->w,
+									weights,mask);break;
+					case	4:	sqdist=projectorigin(	cs.c[0]->w,
+									cs.c[1]->w,
+									cs.c[2]->w,
+									cs.c[3]->w,
+									weights,mask);break;
+					}
+					if(sqdist>=0)
+					{/* Valid	*/ 
+						ns.rank		=	0;
+						m_ray		=	btVector3(0,0,0);
+						m_current	=	next;
+						for(U i=0,ni=cs.rank;i<ni;++i)
+						{
+							if(mask&(1<<i))
+							{
+								ns.c[ns.rank]		=	cs.c[i];
+								ns.p[ns.rank++]		=	weights[i];
+								m_ray				+=	cs.c[i]->w*weights[i];
+							}
+							else
+							{
+								m_free[m_nfree++]	=	cs.c[i];
+							}
+						}
+						if(mask==15) m_status=eStatus::Inside;
+					}
+					else
+					{/* Return old simplex				*/ 
+						removevertice(m_simplices[m_current]);
+						break;
+					}
+					m_status=((++iterations)<GJK_MAX_ITERATIONS)?m_status:eStatus::Failed;
+				} while(m_status==eStatus::Valid);
+				m_simplex=&m_simplices[m_current];
+				switch(m_status)
+				{
+				case	eStatus::Valid:		m_distance=m_ray.length();break;
+				case	eStatus::Inside:	m_distance=0;break;
+				}	
+				return(m_status);
+			}
+			bool					EncloseOrigin()
+			{
+				switch(m_simplex->rank)
+				{
+				case	1:
+					{
+						for(U i=0;i<3;++i)
+						{
+							btVector3		axis=btVector3(0,0,0);
+							axis[i]=1;
+							appendvertice(*m_simplex, axis);
+							if(EncloseOrigin())	return(true);
+							removevertice(*m_simplex);
+							appendvertice(*m_simplex,-axis);
+							if(EncloseOrigin())	return(true);
+							removevertice(*m_simplex);
+						}
+					}
+					break;
+				case	2:
+					{
+						const btVector3	d=m_simplex->c[1]->w-m_simplex->c[0]->w;
+						for(U i=0;i<3;++i)
+						{
+							btVector3		axis=btVector3(0,0,0);
+							axis[i]=1;
+							const btVector3	p=cross(d,axis);
+							if(p.length2()>0)
+							{
+								appendvertice(*m_simplex, p);
+								if(EncloseOrigin())	return(true);
+								removevertice(*m_simplex);
+								appendvertice(*m_simplex,-p);
+								if(EncloseOrigin())	return(true);
+								removevertice(*m_simplex);
+							}
+						}
+					}
+					break;
+				case	3:
+					{
+						const btVector3	n=cross(m_simplex->c[1]->w-m_simplex->c[0]->w,
+							m_simplex->c[2]->w-m_simplex->c[0]->w);
+						if(n.length2()>0)
+						{
+							appendvertice(*m_simplex,n);
+							if(EncloseOrigin())	return(true);
+							removevertice(*m_simplex);
+							appendvertice(*m_simplex,-n);
+							if(EncloseOrigin())	return(true);
+							removevertice(*m_simplex);
+						}
+					}
+					break;
+				case	4:
+					{
+						if(btFabs(det(	m_simplex->c[0]->w-m_simplex->c[3]->w,
 							m_simplex->c[1]->w-m_simplex->c[3]->w,
 							m_simplex->c[2]->w-m_simplex->c[3]->w))>0)
-				return(true);
-			}
-		break;
-		}
-	return(false);
-	}
-/* Internals	*/ 
-void				getsupport(const btVector3& d,sSV& sv) const
-	{
-	sv.d	=	d/d.length();
-	sv.w	=	m_shape.Support(sv.d);
-	}
-void				removevertice(sSimplex& simplex)
-	{
-	m_free[m_nfree++]=simplex.c[--simplex.rank];
-	}
-void				appendvertice(sSimplex& simplex,const btVector3& v)
-	{
-	simplex.p[simplex.rank]=0;
-	simplex.c[simplex.rank]=m_free[--m_nfree];
-	getsupport(v,*simplex.c[simplex.rank++]);
-	}
-static btScalar		det(const btVector3& a,const btVector3& b,const btVector3& c)
-	{
-	return(	a.y()*b.z()*c.x()+a.z()*b.x()*c.y()-
-			a.x()*b.z()*c.y()-a.y()*b.x()*c.z()+
-			a.x()*b.y()*c.z()-a.z()*b.y()*c.x());
-	}
-static btScalar		projectorigin(	const btVector3& a,
-									const btVector3& b,
-									btScalar* w,U& m)
-	{
-	const btVector3	d=b-a;
-	const btScalar	l=d.length2();
-	if(l>GJK_SIMPLEX2_EPS)
-		{
-		const btScalar	t(l>0?-dot(a,d)/l:0);
-		if(t>=1)		{ w[0]=0;w[1]=1;m=2;return(b.length2()); }
-		else if(t<=0)	{ w[0]=1;w[1]=0;m=1;return(a.length2()); }
-		else			{ w[0]=1-(w[1]=t);m=3;return((a+d*t).length2()); }
-		}
-	return(-1);
-	}
-static btScalar		projectorigin(	const btVector3& a,
-									const btVector3& b,
-									const btVector3& c,
-									btScalar* w,U& m)
-	{
-	static const U		imd3[]={1,2,0};
-	const btVector3*	vt[]={&a,&b,&c};
-	const btVector3		dl[]={a-b,b-c,c-a};
-	const btVector3		n=cross(dl[0],dl[1]);
-	const btScalar		l=n.length2();
-	if(l>GJK_SIMPLEX3_EPS)
-		{
-		btScalar	mindist=-1;
-		btScalar	subw[2];
-		U			subm;
-		for(U i=0;i<3;++i)
-			{
-			if(dot(*vt[i],cross(dl[i],n))>0)
-				{
-				const U			j=imd3[i];
-				const btScalar	subd(projectorigin(*vt[i],*vt[j],subw,subm));
-				if((mindist<0)||(subd<mindist))
-					{
-					mindist		=	subd;
-					m			=	static_cast<U>(((subm&1)?1<<i:0)+((subm&2)?1<<j:0));
-					w[i]		=	subw[0];
-					w[j]		=	subw[1];
-					w[imd3[j]]	=	0;				
-					}
+							return(true);
+					}
+					break;
 				}
-			}
-		if(mindist<0)
-			{
-			const btScalar	d=dot(a,n);	
-			const btScalar	s=btSqrt(l);
-			const btVector3	p=n*(d/l);
-			mindist	=	p.length2();
-			m		=	7;
-			w[0]	=	(cross(dl[1],b-p)).length()/s;
-			w[1]	=	(cross(dl[2],c-p)).length()/s;
-			w[2]	=	1-(w[0]+w[1]);
-			}
-		return(mindist);
-		}
-	return(-1);
-	}
-static btScalar		projectorigin(	const btVector3& a,
-									const btVector3& b,
-									const btVector3& c,
-									const btVector3& d,
-									btScalar* w,U& m)
-	{
-	static const U		imd3[]={1,2,0};
-	const btVector3*	vt[]={&a,&b,&c,&d};
-	const btVector3		dl[]={a-d,b-d,c-d};
-	const btScalar		vl=det(dl[0],dl[1],dl[2]);
-	const bool			ng=(vl*dot(a,cross(b-c,a-b)))<=0;
-	if(ng&&(btFabs(vl)>GJK_SIMPLEX4_EPS))
-		{
-		btScalar	mindist=-1;
-		btScalar	subw[3];
-		U			subm;
-		for(U i=0;i<3;++i)
-			{
-			const U			j=imd3[i];
-			const btScalar	s=vl*dot(d,cross(dl[i],dl[j]));
-			if(s>0)
-				{
-				const btScalar	subd=projectorigin(*vt[i],*vt[j],d,subw,subm);
-				if((mindist<0)||(subd<mindist))
-					{
-					mindist		=	subd;
-					m			=	static_cast<U>((subm&1?1<<i:0)+
+				return(false);
+			}
+			/* Internals	*/ 
+			void				getsupport(const btVector3& d,sSV& sv) const
+			{
+				sv.d	=	d/d.length();
+				sv.w	=	m_shape.Support(sv.d);
+			}
+			void				removevertice(sSimplex& simplex)
+			{
+				m_free[m_nfree++]=simplex.c[--simplex.rank];
+			}
+			void				appendvertice(sSimplex& simplex,const btVector3& v)
+			{
+				simplex.p[simplex.rank]=0;
+				simplex.c[simplex.rank]=m_free[--m_nfree];
+				getsupport(v,*simplex.c[simplex.rank++]);
+			}
+			static btScalar		det(const btVector3& a,const btVector3& b,const btVector3& c)
+			{
+				return(	a.y()*b.z()*c.x()+a.z()*b.x()*c.y()-
+					a.x()*b.z()*c.y()-a.y()*b.x()*c.z()+
+					a.x()*b.y()*c.z()-a.z()*b.y()*c.x());
+			}
+			static btScalar		projectorigin(	const btVector3& a,
+				const btVector3& b,
+				btScalar* w,U& m)
+			{
+				const btVector3	d=b-a;
+				const btScalar	l=d.length2();
+				if(l>GJK_SIMPLEX2_EPS)
+				{
+					const btScalar	t(l>0?-dot(a,d)/l:0);
+					if(t>=1)		{ w[0]=0;w[1]=1;m=2;return(b.length2()); }
+					else if(t<=0)	{ w[0]=1;w[1]=0;m=1;return(a.length2()); }
+					else			{ w[0]=1-(w[1]=t);m=3;return((a+d*t).length2()); }
+				}
+				return(-1);
+			}
+			static btScalar		projectorigin(	const btVector3& a,
+				const btVector3& b,
+				const btVector3& c,
+				btScalar* w,U& m)
+			{
+				static const U		imd3[]={1,2,0};
+				const btVector3*	vt[]={&a,&b,&c};
+				const btVector3		dl[]={a-b,b-c,c-a};
+				const btVector3		n=cross(dl[0],dl[1]);
+				const btScalar		l=n.length2();
+				if(l>GJK_SIMPLEX3_EPS)
+				{
+					btScalar	mindist=-1;
+					btScalar	subw[2];
+					U			subm;
+					for(U i=0;i<3;++i)
+					{
+						if(dot(*vt[i],cross(dl[i],n))>0)
+						{
+							const U			j=imd3[i];
+							const btScalar	subd(projectorigin(*vt[i],*vt[j],subw,subm));
+							if((mindist<0)||(subd<mindist))
+							{
+								mindist		=	subd;
+								m			=	static_cast<U>(((subm&1)?1<<i:0)+((subm&2)?1<<j:0));
+								w[i]		=	subw[0];
+								w[j]		=	subw[1];
+								w[imd3[j]]	=	0;				
+							}
+						}
+					}
+					if(mindist<0)
+					{
+						const btScalar	d=dot(a,n);	
+						const btScalar	s=btSqrt(l);
+						const btVector3	p=n*(d/l);
+						mindist	=	p.length2();
+						m		=	7;
+						w[0]	=	(cross(dl[1],b-p)).length()/s;
+						w[1]	=	(cross(dl[2],c-p)).length()/s;
+						w[2]	=	1-(w[0]+w[1]);
+					}
+					return(mindist);
+				}
+				return(-1);
+			}
+			static btScalar		projectorigin(	const btVector3& a,
+				const btVector3& b,
+				const btVector3& c,
+				const btVector3& d,
+				btScalar* w,U& m)
+			{
+				static const U		imd3[]={1,2,0};
+				const btVector3*	vt[]={&a,&b,&c,&d};
+				const btVector3		dl[]={a-d,b-d,c-d};
+				const btScalar		vl=det(dl[0],dl[1],dl[2]);
+				const bool			ng=(vl*dot(a,cross(b-c,a-b)))<=0;
+				if(ng&&(btFabs(vl)>GJK_SIMPLEX4_EPS))
+				{
+					btScalar	mindist=-1;
+					btScalar	subw[3];
+					U			subm;
+					for(U i=0;i<3;++i)
+					{
+						const U			j=imd3[i];
+						const btScalar	s=vl*dot(d,cross(dl[i],dl[j]));
+						if(s>0)
+						{
+							const btScalar	subd=projectorigin(*vt[i],*vt[j],d,subw,subm);
+							if((mindist<0)||(subd<mindist))
+							{
+								mindist		=	subd;
+								m			=	static_cast<U>((subm&1?1<<i:0)+
 									(subm&2?1<<j:0)+
 									(subm&4?8:0));
-					w[i]		=	subw[0];
-					w[j]		=	subw[1];
-					w[imd3[j]]	=	0;
-					w[3]		=	subw[2];
-					}
+								w[i]		=	subw[0];
+								w[j]		=	subw[1];
+								w[imd3[j]]	=	0;
+								w[3]		=	subw[2];
+							}
+						}
+					}
+					if(mindist<0)
+					{
+						mindist	=	0;
+						m		=	15;
+						w[0]	=	det(c,b,d)/vl;
+						w[1]	=	det(a,c,d)/vl;
+						w[2]	=	det(b,a,d)/vl;
+						w[3]	=	1-(w[0]+w[1]+w[2]);
+					}
+					return(mindist);
 				}
-			}
-		if(mindist<0)
-			{
-			mindist	=	0;
-			m		=	15;
-			w[0]	=	det(c,b,d)/vl;
-			w[1]	=	det(a,c,d)/vl;
-			w[2]	=	det(b,a,d)/vl;
-			w[3]	=	1-(w[0]+w[1]+w[2]);
-			}
-		return(mindist);
-		}
-	return(-1);
-	}
-};
-
-// EPA
-struct	EPA
-{
-/* Types		*/ 
-typedef	GJK::sSV	sSV;
-struct	sFace
+				return(-1);
+			}
+	};
+
+	// EPA
+	struct	EPA
 	{
-	btVector3	n;
-	btScalar	d;
-	btScalar	p;
-	sSV*		c[3];
-	sFace*		f[3];
-	sFace*		l[2];
-	U1			e[3];
-	U1			pass;
-	};
-struct	sList
-	{
-	sFace*		root;
-	U			count;
-				sList() : root(0),count(0)	{}
-	};
-struct	sHorizon
-	{
-	sFace*		cf;
-	sFace*		ff;
-	U			nf;
-				sHorizon() : cf(0),ff(0),nf(0)	{}
-	};
-struct	eStatus { enum _ {
-	Valid,
-	Touching,
-	Degenerated,
-	NonConvex,
-	InvalidHull,		
-	OutOfFaces,
-	OutOfVertices,
-	AccuraryReached,
-	FallBack,
-	Failed		};};
-/* Fields		*/ 
-eStatus::_		m_status;
-GJK::sSimplex	m_result;
-btVector3		m_normal;
-btScalar		m_depth;
-sSV				m_sv_store[EPA_MAX_VERTICES];
-sFace			m_fc_store[EPA_MAX_FACES];
-U				m_nextsv;
-sList			m_hull;
-sList			m_stock;
-/* Methods		*/ 
-					EPA()
-	{
-	Initialize();	
-	}
-
-
-					static inline void		bind(sFace* fa,U ea,sFace* fb,U eb)
-	{
-	fa->e[ea]=(U1)eb;fa->f[ea]=fb;
-	fb->e[eb]=(U1)ea;fb->f[eb]=fa;
-	}
-static inline void		append(sList& list,sFace* face)
-	{
-	face->l[0]	=	0;
-	face->l[1]	=	list.root;
-	if(list.root) list.root->l[0]=face;
-	list.root	=	face;
-	++list.count;
-	}
-static inline void		remove(sList& list,sFace* face)
-	{
-	if(face->l[1]) face->l[1]->l[0]=face->l[0];
-	if(face->l[0]) face->l[0]->l[1]=face->l[1];
-	if(face==list.root) list.root=face->l[1];
-	--list.count;
-	}
-
-
-void				Initialize()
-	{
-	m_status	=	eStatus::Failed;
-	m_normal	=	btVector3(0,0,0);
-	m_depth		=	0;
-	m_nextsv	=	0;
-	for(U i=0;i<EPA_MAX_FACES;++i)
-		{
-		append(m_stock,&m_fc_store[EPA_MAX_FACES-i-1]);
-		}
-	}
-eStatus::_			Evaluate(GJK& gjk,const btVector3& guess)
-	{
-	GJK::sSimplex&	simplex=*gjk.m_simplex;
-	if((simplex.rank>1)&&gjk.EncloseOrigin())
-		{
-
-		/* Clean up				*/ 
-		while(m_hull.root)
-			{
-			sFace*	f = m_hull.root;
-			remove(m_hull,f);
-			append(m_stock,f);
-			}
-		m_status	=	eStatus::Valid;
-		m_nextsv	=	0;
-		/* Orient simplex		*/ 
-		if(gjk.det(	simplex.c[0]->w-simplex.c[3]->w,
-					simplex.c[1]->w-simplex.c[3]->w,
-					simplex.c[2]->w-simplex.c[3]->w)<0)
-			{
-			btSwap(simplex.c[0],simplex.c[1]);
-			btSwap(simplex.p[0],simplex.p[1]);
-			}
-		/* Build initial hull	*/ 
-		sFace*	tetra[]={newface(simplex.c[0],simplex.c[1],simplex.c[2],true),
+		/* Types		*/ 
+		typedef	GJK::sSV	sSV;
+		struct	sFace
+		{
+			btVector3	n;
+			btScalar	d;
+			btScalar	p;
+			sSV*		c[3];
+			sFace*		f[3];
+			sFace*		l[2];
+			U1			e[3];
+			U1			pass;
+		};
+		struct	sList
+		{
+			sFace*		root;
+			U			count;
+			sList() : root(0),count(0)	{}
+		};
+		struct	sHorizon
+		{
+			sFace*		cf;
+			sFace*		ff;
+			U			nf;
+			sHorizon() : cf(0),ff(0),nf(0)	{}
+		};
+		struct	eStatus { enum _ {
+			Valid,
+			Touching,
+			Degenerated,
+			NonConvex,
+			InvalidHull,		
+			OutOfFaces,
+			OutOfVertices,
+			AccuraryReached,
+			FallBack,
+			Failed		};};
+			/* Fields		*/ 
+			eStatus::_		m_status;
+			GJK::sSimplex	m_result;
+			btVector3		m_normal;
+			btScalar		m_depth;
+			sSV				m_sv_store[EPA_MAX_VERTICES];
+			sFace			m_fc_store[EPA_MAX_FACES];
+			U				m_nextsv;
+			sList			m_hull;
+			sList			m_stock;
+			/* Methods		*/ 
+			EPA()
+			{
+				Initialize();	
+			}
+
+
+			static inline void		bind(sFace* fa,U ea,sFace* fb,U eb)
+			{
+				fa->e[ea]=(U1)eb;fa->f[ea]=fb;
+				fb->e[eb]=(U1)ea;fb->f[eb]=fa;
+			}
+			static inline void		append(sList& list,sFace* face)
+			{
+				face->l[0]	=	0;
+				face->l[1]	=	list.root;
+				if(list.root) list.root->l[0]=face;
+				list.root	=	face;
+				++list.count;
+			}
+			static inline void		remove(sList& list,sFace* face)
+			{
+				if(face->l[1]) face->l[1]->l[0]=face->l[0];
+				if(face->l[0]) face->l[0]->l[1]=face->l[1];
+				if(face==list.root) list.root=face->l[1];
+				--list.count;
+			}
+
+
+			void				Initialize()
+			{
+				m_status	=	eStatus::Failed;
+				m_normal	=	btVector3(0,0,0);
+				m_depth		=	0;
+				m_nextsv	=	0;
+				for(U i=0;i<EPA_MAX_FACES;++i)
+				{
+					append(m_stock,&m_fc_store[EPA_MAX_FACES-i-1]);
+				}
+			}
+			eStatus::_			Evaluate(GJK& gjk,const btVector3& guess)
+			{
+				GJK::sSimplex&	simplex=*gjk.m_simplex;
+				if((simplex.rank>1)&&gjk.EncloseOrigin())
+				{
+
+					/* Clean up				*/ 
+					while(m_hull.root)
+					{
+						sFace*	f = m_hull.root;
+						remove(m_hull,f);
+						append(m_stock,f);
+					}
+					m_status	=	eStatus::Valid;
+					m_nextsv	=	0;
+					/* Orient simplex		*/ 
+					if(gjk.det(	simplex.c[0]->w-simplex.c[3]->w,
+						simplex.c[1]->w-simplex.c[3]->w,
+						simplex.c[2]->w-simplex.c[3]->w)<0)
+					{
+						btSwap(simplex.c[0],simplex.c[1]);
+						btSwap(simplex.p[0],simplex.p[1]);
+					}
+					/* Build initial hull	*/ 
+					sFace*	tetra[]={newface(simplex.c[0],simplex.c[1],simplex.c[2],true),
 						newface(simplex.c[1],simplex.c[0],simplex.c[3],true),
 						newface(simplex.c[2],simplex.c[1],simplex.c[3],true),
 						newface(simplex.c[0],simplex.c[2],simplex.c[3],true)};
-		if(m_hull.count==4)
-			{
-			sFace*		best=findbest();
-			sFace		outer=*best;
-			U			pass=0;
-			U			iterations=0;
-			bind(tetra[0],0,tetra[1],0);
-			bind(tetra[0],1,tetra[2],0);
-			bind(tetra[0],2,tetra[3],0);
-			bind(tetra[1],1,tetra[3],2);
-			bind(tetra[1],2,tetra[2],1);
-			bind(tetra[2],2,tetra[3],1);
-			m_status=eStatus::Valid;
-			for(;iterations<EPA_MAX_ITERATIONS;++iterations)
-				{
-				if(m_nextsv<EPA_MAX_VERTICES)
-					{	
-					sHorizon		horizon;
-					sSV*			w=&m_sv_store[m_nextsv++];
-					bool			valid=true;					
-					best->pass	=	(U1)(++pass);
-					gjk.getsupport(best->n,*w);
-					const btScalar	wdist=dot(best->n,w->w)-best->d;
-					if(wdist>EPA_ACCURACY)
+					if(m_hull.count==4)
+					{
+						sFace*		best=findbest();
+						sFace		outer=*best;
+						U			pass=0;
+						U			iterations=0;
+						bind(tetra[0],0,tetra[1],0);
+						bind(tetra[0],1,tetra[2],0);
+						bind(tetra[0],2,tetra[3],0);
+						bind(tetra[1],1,tetra[3],2);
+						bind(tetra[1],2,tetra[2],1);
+						bind(tetra[2],2,tetra[3],1);
+						m_status=eStatus::Valid;
+						for(;iterations<EPA_MAX_ITERATIONS;++iterations)
 						{
-						for(U j=0;(j<3)&&valid;++j)
-							{
-							valid&=expand(	pass,w,
+							if(m_nextsv<EPA_MAX_VERTICES)
+							{	
+								sHorizon		horizon;
+								sSV*			w=&m_sv_store[m_nextsv++];
+								bool			valid=true;					
+								best->pass	=	(U1)(++pass);
+								gjk.getsupport(best->n,*w);
+								const btScalar	wdist=dot(best->n,w->w)-best->d;
+								if(wdist>EPA_ACCURACY)
+								{
+									for(U j=0;(j<3)&&valid;++j)
+									{
+										valid&=expand(	pass,w,
 											best->f[j],best->e[j],
 											horizon);
-							}
-						if(valid&&(horizon.nf>=3))
-							{
-							bind(horizon.cf,1,horizon.ff,2);
-							remove(m_hull,best);
-							append(m_stock,best);
-							best=findbest();
-							if(best->p>=outer.p) outer=*best;
-							} else { m_status=eStatus::InvalidHull;break; }
-						} else { m_status=eStatus::AccuraryReached;break; }
-					} else { m_status=eStatus::OutOfVertices;break; }
+									}
+									if(valid&&(horizon.nf>=3))
+									{
+										bind(horizon.cf,1,horizon.ff,2);
+										remove(m_hull,best);
+										append(m_stock,best);
+										best=findbest();
+										if(best->p>=outer.p) outer=*best;
+									} else { m_status=eStatus::InvalidHull;break; }
+								} else { m_status=eStatus::AccuraryReached;break; }
+							} else { m_status=eStatus::OutOfVertices;break; }
+						}
+						const btVector3	projection=outer.n*outer.d;
+						m_normal	=	outer.n;
+						m_depth		=	outer.d;
+						m_result.rank	=	3;
+						m_result.c[0]	=	outer.c[0];
+						m_result.c[1]	=	outer.c[1];
+						m_result.c[2]	=	outer.c[2];
+						m_result.p[0]	=	cross(	outer.c[1]->w-projection,
+							outer.c[2]->w-projection).length();
+						m_result.p[1]	=	cross(	outer.c[2]->w-projection,
+							outer.c[0]->w-projection).length();
+						m_result.p[2]	=	cross(	outer.c[0]->w-projection,
+							outer.c[1]->w-projection).length();
+						const btScalar	sum=m_result.p[0]+m_result.p[1]+m_result.p[2];
+						m_result.p[0]	/=	sum;
+						m_result.p[1]	/=	sum;
+						m_result.p[2]	/=	sum;
+						return(m_status);
+					}
 				}
-			const btVector3	projection=outer.n*outer.d;
-			m_normal	=	outer.n;
-			m_depth		=	outer.d;
-			m_result.rank	=	3;
-			m_result.c[0]	=	outer.c[0];
-			m_result.c[1]	=	outer.c[1];
-			m_result.c[2]	=	outer.c[2];
-			m_result.p[0]	=	cross(	outer.c[1]->w-projection,
-										outer.c[2]->w-projection).length();
-			m_result.p[1]	=	cross(	outer.c[2]->w-projection,
-										outer.c[0]->w-projection).length();
-			m_result.p[2]	=	cross(	outer.c[0]->w-projection,
-										outer.c[1]->w-projection).length();
-			const btScalar	sum=m_result.p[0]+m_result.p[1]+m_result.p[2];
-			m_result.p[0]	/=	sum;
-			m_result.p[1]	/=	sum;
-			m_result.p[2]	/=	sum;
-			return(m_status);
-			}
-		}
-	/* Fallback		*/ 
-	m_status	=	eStatus::FallBack;
-	m_normal	=	-guess;
-	const btScalar	nl=m_normal.length();
-	if(nl>0)
-		m_normal	=	m_normal/nl;
-		else
-		m_normal	=	btVector3(1,0,0);
-	m_depth	=	0;
-	m_result.rank=1;
-	m_result.c[0]=simplex.c[0];
-	m_result.p[0]=1;	
-	return(m_status);
+				/* Fallback		*/ 
+				m_status	=	eStatus::FallBack;
+				m_normal	=	-guess;
+				const btScalar	nl=m_normal.length();
+				if(nl>0)
+					m_normal	=	m_normal/nl;
+				else
+					m_normal	=	btVector3(1,0,0);
+				m_depth	=	0;
+				m_result.rank=1;
+				m_result.c[0]=simplex.c[0];
+				m_result.p[0]=1;	
+				return(m_status);
+			}
+			sFace*				newface(sSV* a,sSV* b,sSV* c,bool forced)
+			{
+				if(m_stock.root)
+				{
+					sFace*	face=m_stock.root;
+					remove(m_stock,face);
+					append(m_hull,face);
+					face->pass	=	0;
+					face->c[0]	=	a;
+					face->c[1]	=	b;
+					face->c[2]	=	c;
+					face->n		=	cross(b->w-a->w,c->w-a->w);
+					const btScalar	l=face->n.length();
+					const bool		v=l>EPA_ACCURACY;
+					face->p		=	btMin(btMin(
+						dot(a->w,cross(face->n,a->w-b->w)),
+						dot(b->w,cross(face->n,b->w-c->w))),
+						dot(c->w,cross(face->n,c->w-a->w)))	/
+						(v?l:1);
+					face->p		=	face->p>=-EPA_INSIDE_EPS?0:face->p;
+					if(v)
+					{
+						face->d		=	dot(a->w,face->n)/l;
+						face->n		/=	l;
+						if(forced||(face->d>=-EPA_PLANE_EPS))
+						{
+							return(face);
+						} else m_status=eStatus::NonConvex;
+					} else m_status=eStatus::Degenerated;
+					remove(m_hull,face);
+					append(m_stock,face);
+					return(0);
+				}
+				m_status=m_stock.root?eStatus::OutOfVertices:eStatus::OutOfFaces;
+				return(0);
+			}
+			sFace*				findbest()
+			{
+				sFace*		minf=m_hull.root;
+				btScalar	mind=minf->d*minf->d;
+				btScalar	maxp=minf->p;
+				for(sFace* f=minf->l[1];f;f=f->l[1])
+				{
+					const btScalar	sqd=f->d*f->d;
+					if((f->p>=maxp)&&(sqd<mind))
+					{
+						minf=f;
+						mind=sqd;
+						maxp=f->p;
+					}
+				}
+				return(minf);
+			}
+			bool				expand(U pass,sSV* w,sFace* f,U e,sHorizon& horizon)
+			{
+				static const U	i1m3[]={1,2,0};
+				static const U	i2m3[]={2,0,1};
+				if(f->pass!=pass)
+				{
+					const U	e1=i1m3[e];
+					if((dot(f->n,w->w)-f->d)<-EPA_PLANE_EPS)
+					{
+						sFace*	nf=newface(f->c[e1],f->c[e],w,false);
+						if(nf)
+						{
+							bind(nf,0,f,e);
+							if(horizon.cf) bind(horizon.cf,1,nf,2); else horizon.ff=nf;
+							horizon.cf=nf;
+							++horizon.nf;
+							return(true);
+						}
+					}
+					else
+					{
+						const U	e2=i2m3[e];
+						f->pass		=	(U1)pass;
+						if(	expand(pass,w,f->f[e1],f->e[e1],horizon)&&
+							expand(pass,w,f->f[e2],f->e[e2],horizon))
+						{
+							remove(m_hull,f);
+							append(m_stock,f);
+							return(true);
+						}
+					}
+				}
+				return(false);
+			}
+
+	};
+
+	//
+	static void	Initialize(	const btConvexShape* shape0,const btTransform& wtrs0,
+		const btConvexShape* shape1,const btTransform& wtrs1,
+		btGjkEpaSolver2::sResults& results,
+		tShape& shape,
+		bool withmargins)
+	{
+		/* Results		*/ 
+		results.witnesses[0]	=
+			results.witnesses[1]	=	btVector3(0,0,0);
+		results.status			=	btGjkEpaSolver2::sResults::Separated;
+		/* Shape		*/ 
+		shape.m_shapes[0]		=	shape0;
+		shape.m_shapes[1]		=	shape1;
+		shape.m_toshape1		=	wtrs1.getBasis().transposeTimes(wtrs0.getBasis());
+		shape.m_toshape0		=	wtrs0.inverseTimes(wtrs1);
+		shape.EnableMargin(withmargins);
 	}
-sFace*				newface(sSV* a,sSV* b,sSV* c,bool forced)
-	{
-	if(m_stock.root)
-		{
-		sFace*	face=m_stock.root;
-		remove(m_stock,face);
-		append(m_hull,face);
-		face->pass	=	0;
-		face->c[0]	=	a;
-		face->c[1]	=	b;
-		face->c[2]	=	c;
-		face->n		=	cross(b->w-a->w,c->w-a->w);
-		const btScalar	l=face->n.length();
-		const bool		v=l>EPA_ACCURACY;
-		face->p		=	btMin(btMin(
-							dot(a->w,cross(face->n,a->w-b->w)),
-							dot(b->w,cross(face->n,b->w-c->w))),
-							dot(c->w,cross(face->n,c->w-a->w)))	/
-							(v?l:1);
-		face->p		=	face->p>=-EPA_INSIDE_EPS?0:face->p;
-		if(v)
-			{
-			face->d		=	dot(a->w,face->n)/l;
-			face->n		/=	l;
-			if(forced||(face->d>=-EPA_PLANE_EPS))
-				{
-				return(face);
-				} else m_status=eStatus::NonConvex;
-			} else m_status=eStatus::Degenerated;
-		remove(m_hull,face);
-		append(m_stock,face);
-		return(0);
-		}
-	m_status=m_stock.root?eStatus::OutOfVertices:eStatus::OutOfFaces;
-	return(0);
-	}
-sFace*				findbest()
-	{
-	sFace*		minf=m_hull.root;
-	btScalar	mind=minf->d*minf->d;
-	btScalar	maxp=minf->p;
-	for(sFace* f=minf->l[1];f;f=f->l[1])
-		{
-		const btScalar	sqd=f->d*f->d;
-		if((f->p>=maxp)&&(sqd<mind))
-			{
-			minf=f;
-			mind=sqd;
-			maxp=f->p;
-			}
-		}
-	return(minf);
-	}
-bool				expand(U pass,sSV* w,sFace* f,U e,sHorizon& horizon)
-	{
-	static const U	i1m3[]={1,2,0};
-	static const U	i2m3[]={2,0,1};
-	if(f->pass!=pass)
-		{
-		const U	e1=i1m3[e];
-		if((dot(f->n,w->w)-f->d)<-EPA_PLANE_EPS)
-			{
-			sFace*	nf=newface(f->c[e1],f->c[e],w,false);
-			if(nf)
-				{
-				bind(nf,0,f,e);
-				if(horizon.cf) bind(horizon.cf,1,nf,2); else horizon.ff=nf;
-				horizon.cf=nf;
-				++horizon.nf;
-				return(true);
-				}
-			}
-			else
-			{
-			const U	e2=i2m3[e];
-			f->pass		=	(U1)pass;
-			if(	expand(pass,w,f->f[e1],f->e[e1],horizon)&&
-				expand(pass,w,f->f[e2],f->e[e2],horizon))
-				{
-				remove(m_hull,f);
-				append(m_stock,f);
-				return(true);
-				}
-			}
-		}
-	return(false);
-	}
-
-};
-
-//
-static void	Initialize(	const btConvexShape* shape0,const btTransform& wtrs0,
-						const btConvexShape* shape1,const btTransform& wtrs1,
-						btGjkEpaSolver2::sResults& results,
-						tShape& shape,
-						bool withmargins)
-{
-/* Results		*/ 
-results.witnesses[0]	=
-results.witnesses[1]	=	btVector3(0,0,0);
-results.status			=	btGjkEpaSolver2::sResults::Separated;
-/* Shape		*/ 
-shape.m_shapes[0]		=	shape0;
-shape.m_shapes[1]		=	shape1;
-shape.m_toshape1		=	wtrs1.getBasis().transposeTimes(wtrs0.getBasis());
-shape.m_toshape0		=	wtrs0.inverseTimes(wtrs1);
-shape.EnableMargin(withmargins);
-}
 
 }
@@ -776,42 +776,42 @@
 int			btGjkEpaSolver2::StackSizeRequirement()
 {
-return(sizeof(GJK)+sizeof(EPA));
+	return(sizeof(GJK)+sizeof(EPA));
 }
 
 //
 bool		btGjkEpaSolver2::Distance(	const btConvexShape*	shape0,
-										const btTransform&		wtrs0,
-										const btConvexShape*	shape1,
-										const btTransform&		wtrs1,
-										const btVector3&		guess,
-										sResults&				results)
+									  const btTransform&		wtrs0,
+									  const btConvexShape*	shape1,
+									  const btTransform&		wtrs1,
+									  const btVector3&		guess,
+									  sResults&				results)
 {
-tShape			shape;
-Initialize(shape0,wtrs0,shape1,wtrs1,results,shape,false);
-GJK				gjk;
-GJK::eStatus::_	gjk_status=gjk.Evaluate(shape,guess);
-if(gjk_status==GJK::eStatus::Valid)
+	tShape			shape;
+	Initialize(shape0,wtrs0,shape1,wtrs1,results,shape,false);
+	GJK				gjk;
+	GJK::eStatus::_	gjk_status=gjk.Evaluate(shape,guess);
+	if(gjk_status==GJK::eStatus::Valid)
 	{
-	btVector3	w0=btVector3(0,0,0);
-	btVector3	w1=btVector3(0,0,0);
-	for(U i=0;i<gjk.m_simplex->rank;++i)
-		{
-		const btScalar	p=gjk.m_simplex->p[i];
-		w0+=shape.Support( gjk.m_simplex->c[i]->d,0)*p;
-		w1+=shape.Support(-gjk.m_simplex->c[i]->d,1)*p;
+		btVector3	w0=btVector3(0,0,0);
+		btVector3	w1=btVector3(0,0,0);
+		for(U i=0;i<gjk.m_simplex->rank;++i)
+		{
+			const btScalar	p=gjk.m_simplex->p[i];
+			w0+=shape.Support( gjk.m_simplex->c[i]->d,0)*p;
+			w1+=shape.Support(-gjk.m_simplex->c[i]->d,1)*p;
 		}
-	results.witnesses[0]	=	wtrs0*w0;
-	results.witnesses[1]	=	wtrs0*w1;
-	results.normal			=	w0-w1;
-	results.distance		=	results.normal.length();
-	results.normal			/=	results.distance>GJK_MIN_DISTANCE?results.distance:1;
-	return(true);
+		results.witnesses[0]	=	wtrs0*w0;
+		results.witnesses[1]	=	wtrs0*w1;
+		results.normal			=	w0-w1;
+		results.distance		=	results.normal.length();
+		results.normal			/=	results.distance>GJK_MIN_DISTANCE?results.distance:1;
+		return(true);
 	}
 	else
 	{
-	results.status	=	gjk_status==GJK::eStatus::Inside?
-							sResults::Penetrating	:
-							sResults::GJK_Failed	;
-	return(false);
+		results.status	=	gjk_status==GJK::eStatus::Inside?
+			sResults::Penetrating	:
+		sResults::GJK_Failed	;
+		return(false);
 	}
 }
@@ -819,42 +819,42 @@
 //
 bool	btGjkEpaSolver2::Penetration(	const btConvexShape*	shape0,
-										const btTransform&		wtrs0,
-										const btConvexShape*	shape1,
-										const btTransform&		wtrs1,
-										const btVector3&		guess,
-										sResults&				results,
-										bool					usemargins)
+									 const btTransform&		wtrs0,
+									 const btConvexShape*	shape1,
+									 const btTransform&		wtrs1,
+									 const btVector3&		guess,
+									 sResults&				results,
+									 bool					usemargins)
 {
-tShape			shape;
-Initialize(shape0,wtrs0,shape1,wtrs1,results,shape,usemargins);
-GJK				gjk;	
-GJK::eStatus::_	gjk_status=gjk.Evaluate(shape,-guess);
-switch(gjk_status)
+	tShape			shape;
+	Initialize(shape0,wtrs0,shape1,wtrs1,results,shape,usemargins);
+	GJK				gjk;	
+	GJK::eStatus::_	gjk_status=gjk.Evaluate(shape,-guess);
+	switch(gjk_status)
 	{
 	case	GJK::eStatus::Inside:
 		{
-		EPA				epa;
-		EPA::eStatus::_	epa_status=epa.Evaluate(gjk,-guess);
-		if(epa_status!=EPA::eStatus::Failed)
-			{
-			btVector3	w0=btVector3(0,0,0);
-			for(U i=0;i<epa.m_result.rank;++i)
-				{
-				w0+=shape.Support(epa.m_result.c[i]->d,0)*epa.m_result.p[i];
+			EPA				epa;
+			EPA::eStatus::_	epa_status=epa.Evaluate(gjk,-guess);
+			if(epa_status!=EPA::eStatus::Failed)
+			{
+				btVector3	w0=btVector3(0,0,0);
+				for(U i=0;i<epa.m_result.rank;++i)
+				{
+					w0+=shape.Support(epa.m_result.c[i]->d,0)*epa.m_result.p[i];
 				}
-			results.status			=	sResults::Penetrating;
-			results.witnesses[0]	=	wtrs0*w0;
-			results.witnesses[1]	=	wtrs0*(w0-epa.m_normal*epa.m_depth);
-			results.normal			=	-epa.m_normal;
-			results.distance		=	-epa.m_depth;
-			return(true);
+				results.status			=	sResults::Penetrating;
+				results.witnesses[0]	=	wtrs0*w0;
+				results.witnesses[1]	=	wtrs0*(w0-epa.m_normal*epa.m_depth);
+				results.normal			=	-epa.m_normal;
+				results.distance		=	-epa.m_depth;
+				return(true);
 			} else results.status=sResults::EPA_Failed;
 		}
-	break;
+		break;
 	case	GJK::eStatus::Failed:
-	results.status=sResults::GJK_Failed;
-	break;
+		results.status=sResults::GJK_Failed;
+		break;
 	}
-return(false);
+	return(false);
 }
 
@@ -866,47 +866,47 @@
 											sResults& results)
 {
-tShape			shape;
-btSphereShape	shape1(margin);
-btTransform		wtrs1(btQuaternion(0,0,0,1),position);
-Initialize(shape0,wtrs0,&shape1,wtrs1,results,shape,false);
-GJK				gjk;	
-GJK::eStatus::_	gjk_status=gjk.Evaluate(shape,btVector3(1,1,1));
-if(gjk_status==GJK::eStatus::Valid)
+	tShape			shape;
+	btSphereShape	shape1(margin);
+	btTransform		wtrs1(btQuaternion(0,0,0,1),position);
+	Initialize(shape0,wtrs0,&shape1,wtrs1,results,shape,false);
+	GJK				gjk;	
+	GJK::eStatus::_	gjk_status=gjk.Evaluate(shape,btVector3(1,1,1));
+	if(gjk_status==GJK::eStatus::Valid)
 	{
-	btVector3	w0=btVector3(0,0,0);
-	btVector3	w1=btVector3(0,0,0);
-	for(U i=0;i<gjk.m_simplex->rank;++i)
-		{
-		const btScalar	p=gjk.m_simplex->p[i];
-		w0+=shape.Support( gjk.m_simplex->c[i]->d,0)*p;
-		w1+=shape.Support(-gjk.m_simplex->c[i]->d,1)*p;
+		btVector3	w0=btVector3(0,0,0);
+		btVector3	w1=btVector3(0,0,0);
+		for(U i=0;i<gjk.m_simplex->rank;++i)
+		{
+			const btScalar	p=gjk.m_simplex->p[i];
+			w0+=shape.Support( gjk.m_simplex->c[i]->d,0)*p;
+			w1+=shape.Support(-gjk.m_simplex->c[i]->d,1)*p;
 		}
-	results.witnesses[0]	=	wtrs0*w0;
-	results.witnesses[1]	=	wtrs0*w1;
-	const btVector3	delta=	results.witnesses[1]-
-							results.witnesses[0];
-	const btScalar	margin=	shape0->getMargin()+
-							shape1.getMargin();
-	const btScalar	length=	delta.length();	
-	results.normal			=	delta/length;
-	results.witnesses[0]	+=	results.normal*margin;
-	return(length-margin);
+		results.witnesses[0]	=	wtrs0*w0;
+		results.witnesses[1]	=	wtrs0*w1;
+		const btVector3	delta=	results.witnesses[1]-
+			results.witnesses[0];
+		const btScalar	margin=	shape0->getMarginNonVirtual()+
+			shape1.getMarginNonVirtual();
+		const btScalar	length=	delta.length();	
+		results.normal			=	delta/length;
+		results.witnesses[0]	+=	results.normal*margin;
+		return(length-margin);
 	}
 	else
 	{
-	if(gjk_status==GJK::eStatus::Inside)
-		{
-		if(Penetration(shape0,wtrs0,&shape1,wtrs1,gjk.m_ray,results))
-			{
-			const btVector3	delta=	results.witnesses[0]-
-									results.witnesses[1];
-			const btScalar	length=	delta.length();
-			if (length >= SIMD_EPSILON)
-				results.normal	=	delta/length;			
-			return(-length);
+		if(gjk_status==GJK::eStatus::Inside)
+		{
+			if(Penetration(shape0,wtrs0,&shape1,wtrs1,gjk.m_ray,results))
+			{
+				const btVector3	delta=	results.witnesses[0]-
+					results.witnesses[1];
+				const btScalar	length=	delta.length();
+				if (length >= SIMD_EPSILON)
+					results.normal	=	delta/length;			
+				return(-length);
 			}
 		}	
 	}
-return(SIMD_INFINITY);
+	return(SIMD_INFINITY);
 }
 
@@ -919,8 +919,8 @@
 										sResults&				results)
 {
-if(!Distance(shape0,wtrs0,shape1,wtrs1,guess,results))
-	return(Penetration(shape0,wtrs0,shape1,wtrs1,guess,results,false));
+	if(!Distance(shape0,wtrs0,shape1,wtrs1,guess,results))
+		return(Penetration(shape0,wtrs0,shape1,wtrs1,guess,results,false));
 	else
-	return(true);
+		return(true);
 }
 
Index: code/branches/physics/src/bullet/BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.cpp
===================================================================
--- code/branches/physics/src/bullet/BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.cpp	(revision 2192)
+++ code/branches/physics/src/bullet/BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.cpp	(revision 2430)
@@ -19,11 +19,4 @@
 #include "btGjkEpaPenetrationDepthSolver.h"
 
-#ifndef __SPU__
-//#define USE_ORIGINAL_GJK 1
-#endif
-
-#ifdef USE_ORIGINAL_GJK
-#include "BulletCollision/NarrowPhaseCollision/btGjkEpa.h"
-#endif
 
 #include "BulletCollision/NarrowPhaseCollision/btGjkEpa2.h"
@@ -32,5 +25,5 @@
 											  const btConvexShape* pConvexA, const btConvexShape* pConvexB,
 											  const btTransform& transformA, const btTransform& transformB,
-											  btVector3& v, btPoint3& wWitnessOnA, btPoint3& wWitnessOnB,
+											  btVector3& v, btVector3& wWitnessOnA, btVector3& wWitnessOnB,
 											  class btIDebugDraw* debugDraw, btStackAlloc* stackAlloc )
 {
@@ -42,11 +35,4 @@
 	const btScalar				radialmargin(btScalar(0.));
 	
-//#define USE_ORIGINAL_GJK 1
-#ifdef USE_ORIGINAL_GJK
-	btGjkEpaSolver::sResults	results;
-	if(btGjkEpaSolver::Collide(	pConvexA,transformA,
-								pConvexB,transformB,
-								radialmargin,stackAlloc,results))
-#else
 	btVector3	guessVector(transformA.getOrigin()-transformB.getOrigin());
 	btGjkEpaSolver2::sResults	results;
@@ -55,5 +41,4 @@
 								guessVector,results))
 	
-#endif
 		{
 	//	debugDraw->drawLine(results.witnesses[1],results.witnesses[1]+results.normal,btVector3(255,0,0));
Index: code/branches/physics/src/bullet/BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h
===================================================================
--- code/branches/physics/src/bullet/BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h	(revision 2192)
+++ code/branches/physics/src/bullet/BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h	(revision 2430)
@@ -29,5 +29,5 @@
 									  const btConvexShape* pConvexA, const btConvexShape* pConvexB,
 									  const btTransform& transformA, const btTransform& transformB,
-									  btVector3& v, btPoint3& wWitnessOnA, btPoint3& wWitnessOnB,
+									  btVector3& v, btVector3& wWitnessOnA, btVector3& wWitnessOnB,
 									  class btIDebugDraw* debugDraw,btStackAlloc* stackAlloc );
 
Index: code/branches/physics/src/bullet/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.cpp
===================================================================
--- code/branches/physics/src/bullet/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.cpp	(revision 2192)
+++ code/branches/physics/src/bullet/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.cpp	(revision 2430)
@@ -22,5 +22,5 @@
 
 #if defined(DEBUG) || defined (_DEBUG)
-#define TEST_NON_VIRTUAL 1
+//#define TEST_NON_VIRTUAL 1
 #include <stdio.h> //for debug printf
 #ifdef __SPU__
@@ -54,4 +54,6 @@
 void btGjkPairDetector::getClosestPoints(const ClosestPointInput& input,Result& output,class btIDebugDraw* debugDraw,bool swapResults)
 {
+	m_cachedSeparatingDistance = 0.f;
+
 	btScalar distance=btScalar(0.);
 	btVector3	normalInB(btScalar(0.),btScalar(0.),btScalar(0.));
@@ -63,15 +65,19 @@
 	localTransB.getOrigin() -= positionOffset;
 
-
+#ifdef __SPU__
 	btScalar marginA = m_minkowskiA->getMarginNonVirtual();
 	btScalar marginB = m_minkowskiB->getMarginNonVirtual();
-
+#else
+	btScalar marginA = m_minkowskiA->getMargin();
+	btScalar marginB = m_minkowskiB->getMargin();
 #ifdef TEST_NON_VIRTUAL
-	btScalar marginAv = m_minkowskiA->getMargin();
-	btScalar marginBv = m_minkowskiB->getMargin();
-
+	btScalar marginAv = m_minkowskiA->getMarginNonVirtual();
+	btScalar marginBv = m_minkowskiB->getMarginNonVirtual();
 	btAssert(marginA == marginAv);
 	btAssert(marginB == marginBv);
 #endif //TEST_NON_VIRTUAL
+#endif
+	
+
 
 	gNumGjkChecks++;
@@ -118,17 +124,20 @@
 			btVector3 seperatingAxisInB = m_cachedSeparatingAxis* input.m_transformB.getBasis();
 
+#ifdef __SPU__
+			btVector3 pInA = m_minkowskiA->localGetSupportVertexWithoutMarginNonVirtual(seperatingAxisInA);
+			btVector3 qInB = m_minkowskiB->localGetSupportVertexWithoutMarginNonVirtual(seperatingAxisInB);
+#else
+			btVector3 pInA = m_minkowskiA->localGetSupportingVertexWithoutMargin(seperatingAxisInA);
+			btVector3 qInB = m_minkowskiB->localGetSupportingVertexWithoutMargin(seperatingAxisInB);
 #ifdef TEST_NON_VIRTUAL
 			btVector3 pInAv = m_minkowskiA->localGetSupportingVertexWithoutMargin(seperatingAxisInA);
 			btVector3 qInBv = m_minkowskiB->localGetSupportingVertexWithoutMargin(seperatingAxisInB);
-#endif 
-			btVector3 pInA = m_minkowskiA->localGetSupportVertexWithoutMarginNonVirtual(seperatingAxisInA);
-			btVector3 qInB = m_minkowskiB->localGetSupportVertexWithoutMarginNonVirtual(seperatingAxisInB);
-#ifdef TEST_NON_VIRTUAL
 			btAssert((pInAv-pInA).length() < 0.0001);
 			btAssert((qInBv-qInB).length() < 0.0001);
 #endif //
-
-			btPoint3  pWorld = localTransA(pInA);	
-			btPoint3  qWorld = localTransB(qInB);
+#endif //__SPU__
+
+			btVector3  pWorld = localTransA(pInA);	
+			btVector3  qWorld = localTransB(qInB);
 
 #ifdef DEBUG_SPU_COLLISION_DETECTION
@@ -332,4 +341,7 @@
 		spu_printf("output 1\n");
 #endif
+		m_cachedSeparatingAxis = normalInB;
+		m_cachedSeparatingDistance = distance;
+
 		output.addContactPoint(
 			normalInB,
Index: code/branches/physics/src/bullet/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h
===================================================================
--- code/branches/physics/src/bullet/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h	(revision 2192)
+++ code/branches/physics/src/bullet/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h	(revision 2430)
@@ -21,5 +21,4 @@
 
 #include "btDiscreteCollisionDetectorInterface.h"
-#include "LinearMath/btPoint3.h"
 #include "BulletCollision/CollisionShapes/btCollisionMargin.h"
 
@@ -39,4 +38,5 @@
 	const btConvexShape* m_minkowskiB;
 	bool		m_ignoreMargin;
+	btScalar	m_cachedSeparatingDistance;
 	
 
@@ -69,4 +69,13 @@
 	}
 
+	const btVector3& getCachedSeparatingAxis() const
+	{
+		return m_cachedSeparatingAxis;
+	}
+	btScalar	getCachedSeparatingDistance() const
+	{
+		return m_cachedSeparatingDistance;
+	}
+
 	void	setPenetrationDepthSolver(btConvexPenetrationDepthSolver*	penetrationDepthSolver)
 	{
Index: code/branches/physics/src/bullet/BulletCollision/NarrowPhaseCollision/btManifoldPoint.h
===================================================================
--- code/branches/physics/src/bullet/BulletCollision/NarrowPhaseCollision/btManifoldPoint.h	(revision 2192)
+++ code/branches/physics/src/bullet/BulletCollision/NarrowPhaseCollision/btManifoldPoint.h	(revision 2430)
@@ -33,4 +33,6 @@
 				m_appliedImpulse(0.f),
 				m_lateralFrictionInitialized(false),
+				m_appliedImpulseLateral1(0.f),
+				m_appliedImpulseLateral2(0.f),
 				m_lifeTime(0)
 			{
Index: code/branches/physics/src/bullet/BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.cpp
===================================================================
--- code/branches/physics/src/bullet/BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.cpp	(revision 2192)
+++ code/branches/physics/src/bullet/BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.cpp	(revision 2430)
@@ -71,5 +71,5 @@
 												   const btConvexShape* convexA,const btConvexShape* convexB,
 												   const btTransform& transA,const btTransform& transB,
-												   btVector3& v, btPoint3& pa, btPoint3& pb,
+												   btVector3& v, btVector3& pa, btVector3& pb,
 												   class btIDebugDraw* debugDraw,btStackAlloc* stackAlloc
 												   )
Index: code/branches/physics/src/bullet/BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.h
===================================================================
--- code/branches/physics/src/bullet/BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.h	(revision 2192)
+++ code/branches/physics/src/bullet/BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.h	(revision 2430)
@@ -28,5 +28,5 @@
 	const btConvexShape* convexA,const btConvexShape* convexB,
 				const btTransform& transA,const btTransform& transB,
-			btVector3& v, btPoint3& pa, btPoint3& pb,
+			btVector3& v, btVector3& pa, btVector3& pb,
 			class btIDebugDraw* debugDraw,btStackAlloc* stackAlloc
 			);
Index: code/branches/physics/src/bullet/BulletCollision/NarrowPhaseCollision/btPersistentManifold.cpp
===================================================================
--- code/branches/physics/src/bullet/BulletCollision/NarrowPhaseCollision/btPersistentManifold.cpp	(revision 2192)
+++ code/branches/physics/src/bullet/BulletCollision/NarrowPhaseCollision/btPersistentManifold.cpp	(revision 2430)
@@ -17,5 +17,5 @@
 #include "btPersistentManifold.h"
 #include "LinearMath/btTransform.h"
-#include <assert.h>
+
 
 btScalar					gContactBreakingThreshold = btScalar(0.02);
@@ -67,5 +67,5 @@
 			}
 		}
-		assert(occurance<=0);
+		btAssert(occurance<=0);
 #endif //DEBUG_PERSISTENCY
 
@@ -165,5 +165,5 @@
 int btPersistentManifold::addManifoldPoint(const btManifoldPoint& newPoint)
 {
-	assert(validContactDistance(newPoint));
+	btAssert(validContactDistance(newPoint));
 
 	int insertIndex = getNumContacts();
@@ -191,5 +191,5 @@
 btScalar	btPersistentManifold::getContactBreakingThreshold() const
 {
-	return gContactBreakingThreshold;
+	return m_contactBreakingThreshold;
 }
 
Index: code/branches/physics/src/bullet/BulletCollision/NarrowPhaseCollision/btPersistentManifold.h
===================================================================
--- code/branches/physics/src/bullet/BulletCollision/NarrowPhaseCollision/btPersistentManifold.h	(revision 2192)
+++ code/branches/physics/src/bullet/BulletCollision/NarrowPhaseCollision/btPersistentManifold.h	(revision 2430)
@@ -25,5 +25,5 @@
 struct btCollisionResult;
 
-///contact breaking and merging threshold
+///maximum contact breaking and merging threshold
 extern btScalar gContactBreakingThreshold;
 
@@ -55,4 +55,6 @@
 	int	m_cachedPoints;
 
+	btScalar	m_contactBreakingThreshold;
+
 	
 	/// sort cached points so most isolated points come first
@@ -69,8 +71,9 @@
 	btPersistentManifold();
 
-	btPersistentManifold(void* body0,void* body1,int bla)
-		: m_body0(body0),m_body1(body1),m_cachedPoints(0)
+	btPersistentManifold(void* body0,void* body1,int , btScalar contactBreakingThreshold)
+		: m_body0(body0),m_body1(body1),m_cachedPoints(0),
+		m_contactBreakingThreshold(contactBreakingThreshold)
 	{
-		(void)bla;
+		
 	}
 
@@ -107,5 +110,5 @@
 	}
 
-	/// todo: get this margin from the current physics / collision environment
+	///@todo: get this margin from the current physics / collision environment
 	btScalar	getContactBreakingThreshold() const;
 	
Index: code/branches/physics/src/bullet/BulletCollision/NarrowPhaseCollision/btSimplexSolverInterface.h
===================================================================
--- code/branches/physics/src/bullet/BulletCollision/NarrowPhaseCollision/btSimplexSolverInterface.h	(revision 2192)
+++ code/branches/physics/src/bullet/BulletCollision/NarrowPhaseCollision/btSimplexSolverInterface.h	(revision 2430)
@@ -20,5 +20,4 @@
 
 #include "LinearMath/btVector3.h"
-#include "LinearMath/btPoint3.h"
 
 #define NO_VIRTUAL_INTERFACE 1
@@ -38,5 +37,5 @@
 	virtual void reset() = 0;
 
-	virtual void addVertex(const btVector3& w, const btPoint3& p, const btPoint3& q) = 0;
+	virtual void addVertex(const btVector3& w, const btVector3& p, const btVector3& q) = 0;
 	
 	virtual bool closest(btVector3& v) = 0;
@@ -46,5 +45,5 @@
 	virtual bool fullSimplex() const = 0;
 
-	virtual int getSimplex(btPoint3 *pBuf, btPoint3 *qBuf, btVector3 *yBuf) const = 0;
+	virtual int getSimplex(btVector3 *pBuf, btVector3 *qBuf, btVector3 *yBuf) const = 0;
 
 	virtual bool inSimplex(const btVector3& w) = 0;
@@ -54,5 +53,5 @@
 	virtual bool emptySimplex() const = 0;
 
-	virtual void compute_points(btPoint3& p1, btPoint3& p2) = 0;
+	virtual void compute_points(btVector3& p1, btVector3& p2) = 0;
 
 	virtual int numVertices() const =0;
Index: code/branches/physics/src/bullet/BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.cpp
===================================================================
--- code/branches/physics/src/bullet/BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.cpp	(revision 2192)
+++ code/branches/physics/src/bullet/BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.cpp	(revision 2430)
@@ -78,5 +78,5 @@
 
 	//add a vertex
-void btVoronoiSimplexSolver::addVertex(const btVector3& w, const btPoint3& p, const btPoint3& q)
+void btVoronoiSimplexSolver::addVertex(const btVector3& w, const btVector3& p, const btVector3& q)
 {
 	m_lastW = w;
@@ -268,5 +268,5 @@
 
 	//return the current simplex
-int btVoronoiSimplexSolver::getSimplex(btPoint3 *pBuf, btPoint3 *qBuf, btVector3 *yBuf) const
+int btVoronoiSimplexSolver::getSimplex(btVector3 *pBuf, btVector3 *qBuf, btVector3 *yBuf) const
 {
 	int i;
@@ -315,5 +315,5 @@
 }
 
-void btVoronoiSimplexSolver::compute_points(btPoint3& p1, btPoint3& p2) 
+void btVoronoiSimplexSolver::compute_points(btVector3& p1, btVector3& p2) 
 {
 	updateClosestVectorAndPoints();
@@ -326,5 +326,5 @@
 
 
-bool	btVoronoiSimplexSolver::closestPtPointTriangle(const btPoint3& p, const btPoint3& a, const btPoint3& b, const btPoint3& c,btSubSimplexClosestResult& result)
+bool	btVoronoiSimplexSolver::closestPtPointTriangle(const btVector3& p, const btVector3& a, const btVector3& b, const btVector3& c,btSubSimplexClosestResult& result)
 {
 	result.m_usedVertices.reset();
@@ -426,5 +426,5 @@
 
 /// Test if point p and d lie on opposite sides of plane through abc
-int btVoronoiSimplexSolver::pointOutsideOfPlane(const btPoint3& p, const btPoint3& a, const btPoint3& b, const btPoint3& c, const btPoint3& d)
+int btVoronoiSimplexSolver::pointOutsideOfPlane(const btVector3& p, const btVector3& a, const btVector3& b, const btVector3& c, const btVector3& d)
 {
 	btVector3 normal = (b-a).cross(c-a);
@@ -453,5 +453,5 @@
 
 
-bool	btVoronoiSimplexSolver::closestPtPointTetrahedron(const btPoint3& p, const btPoint3& a, const btPoint3& b, const btPoint3& c, const btPoint3& d, btSubSimplexClosestResult& finalResult)
+bool	btVoronoiSimplexSolver::closestPtPointTetrahedron(const btVector3& p, const btVector3& a, const btVector3& b, const btVector3& c, const btVector3& d, btSubSimplexClosestResult& finalResult)
 {
 	btSubSimplexClosestResult tempResult;
@@ -487,5 +487,5 @@
 	{
         closestPtPointTriangle(p, a, b, c,tempResult);
-		btPoint3 q = tempResult.m_closestPointOnSimplex;
+		btVector3 q = tempResult.m_closestPointOnSimplex;
 		
         btScalar sqDist = (q - p).dot( q - p);
@@ -514,5 +514,5 @@
 	{
         closestPtPointTriangle(p, a, c, d,tempResult);
-		btPoint3 q = tempResult.m_closestPointOnSimplex;
+		btVector3 q = tempResult.m_closestPointOnSimplex;
 		//convert result bitmask!
 
@@ -542,5 +542,5 @@
 	{
 		closestPtPointTriangle(p, a, d, b,tempResult);
-		btPoint3 q = tempResult.m_closestPointOnSimplex;
+		btVector3 q = tempResult.m_closestPointOnSimplex;
 		//convert result bitmask!
 
@@ -570,5 +570,5 @@
 	{
         closestPtPointTriangle(p, b, d, c,tempResult);
-		btPoint3 q = tempResult.m_closestPointOnSimplex;
+		btVector3 q = tempResult.m_closestPointOnSimplex;
 		//convert result bitmask!
         btScalar sqDist = (q - p).dot( q - p);
Index: code/branches/physics/src/bullet/BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h
===================================================================
--- code/branches/physics/src/bullet/BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h	(revision 2192)
+++ code/branches/physics/src/bullet/BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h	(revision 2430)
@@ -51,5 +51,5 @@
 struct	btSubSimplexClosestResult
 {
-	btPoint3	m_closestPointOnSimplex;
+	btVector3	m_closestPointOnSimplex;
 	//MASK for m_usedVertices
 	//stores the simplex vertex-usage, using the MASK, 
@@ -98,11 +98,11 @@
 
 	btVector3	m_simplexVectorW[VORONOI_SIMPLEX_MAX_VERTS];
-	btPoint3	m_simplexPointsP[VORONOI_SIMPLEX_MAX_VERTS];
-	btPoint3	m_simplexPointsQ[VORONOI_SIMPLEX_MAX_VERTS];
+	btVector3	m_simplexPointsP[VORONOI_SIMPLEX_MAX_VERTS];
+	btVector3	m_simplexPointsQ[VORONOI_SIMPLEX_MAX_VERTS];
 
 	
 
-	btPoint3	m_cachedP1;
-	btPoint3	m_cachedP2;
+	btVector3	m_cachedP1;
+	btVector3	m_cachedP2;
 	btVector3	m_cachedV;
 	btVector3	m_lastW;
@@ -117,7 +117,7 @@
 	bool	updateClosestVectorAndPoints();
 
-	bool	closestPtPointTetrahedron(const btPoint3& p, const btPoint3& a, const btPoint3& b, const btPoint3& c, const btPoint3& d, btSubSimplexClosestResult& finalResult);
-	int		pointOutsideOfPlane(const btPoint3& p, const btPoint3& a, const btPoint3& b, const btPoint3& c, const btPoint3& d);
-	bool	closestPtPointTriangle(const btPoint3& p, const btPoint3& a, const btPoint3& b, const btPoint3& c,btSubSimplexClosestResult& result);
+	bool	closestPtPointTetrahedron(const btVector3& p, const btVector3& a, const btVector3& b, const btVector3& c, const btVector3& d, btSubSimplexClosestResult& finalResult);
+	int		pointOutsideOfPlane(const btVector3& p, const btVector3& a, const btVector3& b, const btVector3& c, const btVector3& d);
+	bool	closestPtPointTriangle(const btVector3& p, const btVector3& a, const btVector3& b, const btVector3& c,btSubSimplexClosestResult& result);
 
 public:
@@ -125,5 +125,5 @@
 	 void reset();
 
-	 void addVertex(const btVector3& w, const btPoint3& p, const btPoint3& q);
+	 void addVertex(const btVector3& w, const btVector3& p, const btVector3& q);
 
 
@@ -137,5 +137,5 @@
 	 }
 
-	 int getSimplex(btPoint3 *pBuf, btPoint3 *qBuf, btVector3 *yBuf) const;
+	 int getSimplex(btVector3 *pBuf, btVector3 *qBuf, btVector3 *yBuf) const;
 
 	 bool inSimplex(const btVector3& w);
@@ -145,5 +145,5 @@
 	 bool emptySimplex() const ;
 
-	 void compute_points(btPoint3& p1, btPoint3& p2) ;
+	 void compute_points(btVector3& p1, btVector3& p2) ;
 
 	 int numVertices() const 
Index: code/branches/physics/src/bullet/BulletDynamics/CMakeLists.txt
===================================================================
--- code/branches/physics/src/bullet/BulletDynamics/CMakeLists.txt	(revision 2192)
+++ code/branches/physics/src/bullet/BulletDynamics/CMakeLists.txt	(revision 2430)
@@ -1,32 +1,20 @@
-ADD_LIBRARY(LibBulletDynamics
-
+SET(BulletDynamics_SRCS
 	ConstraintSolver/btContactConstraint.cpp
-	ConstraintSolver/btContactConstraint.h
 	ConstraintSolver/btConeTwistConstraint.cpp
-	ConstraintSolver/btConeTwistConstraint.h
 	ConstraintSolver/btGeneric6DofConstraint.cpp
-	ConstraintSolver/btGeneric6DofConstraint.h
 	ConstraintSolver/btHingeConstraint.cpp
-	ConstraintSolver/btHingeConstraint.h
 	ConstraintSolver/btPoint2PointConstraint.cpp
-	ConstraintSolver/btPoint2PointConstraint.h
 	ConstraintSolver/btSequentialImpulseConstraintSolver.cpp
-	ConstraintSolver/btSequentialImpulseConstraintSolver.h
 	ConstraintSolver/btSliderConstraint.cpp
-	ConstraintSolver/btSliderConstraint.h
 	ConstraintSolver/btSolve2LinearConstraint.cpp
-	ConstraintSolver/btSolve2LinearConstraint.h
 	ConstraintSolver/btTypedConstraint.cpp
-	ConstraintSolver/btTypedConstraint.h
 	Dynamics/Bullet-C-API.cpp
 	Dynamics/btDiscreteDynamicsWorld.cpp
-	Dynamics/btDiscreteDynamicsWorld.h
 	Dynamics/btSimpleDynamicsWorld.cpp
-	Dynamics/btSimpleDynamicsWorld.h
 	Dynamics/btRigidBody.cpp
-	Dynamics/btRigidBody.h
 	Vehicle/btRaycastVehicle.cpp
-	Vehicle/btRaycastVehicle.h
 	Vehicle/btWheelInfo.cpp
-	Vehicle/btWheelInfo.h
+	Character/btKinematicCharacterController.cpp
 )
+
+ADD_LIBRARY(BulletDynamics ${BulletDynamics_SRCS})
Index: code/branches/physics/src/bullet/BulletDynamics/Character/btCharacterControllerInterface.h
===================================================================
--- code/branches/physics/src/bullet/BulletDynamics/Character/btCharacterControllerInterface.h	(revision 2430)
+++ code/branches/physics/src/bullet/BulletDynamics/Character/btCharacterControllerInterface.h	(revision 2430)
@@ -0,0 +1,43 @@
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2008 Erwin Coumans  http://bulletphysics.com
+
+This software is provided 'as-is', without any express or implied warranty.
+In no event will the authors be held liable for any damages arising from the use of this software.
+Permission is granted to anyone to use this software for any purpose, 
+including commercial applications, and to alter it and redistribute it freely, 
+subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef CHARACTER_CONTROLLER_INTERFACE_H
+#define CHARACTER_CONTROLLER_INTERFACE_H
+
+#include "LinearMath/btVector3.h"
+
+class btCollisionShape;
+class btRigidBody;
+class btCollisionWorld;
+
+class btCharacterControllerInterface
+{
+public:
+	btCharacterControllerInterface () {};
+	virtual ~btCharacterControllerInterface () {};
+	
+	virtual void	setWalkDirection(const btVector3& walkDirection) = 0;
+	virtual void	reset () = 0;
+	virtual void	warp (const btVector3& origin) = 0;
+
+	virtual void	preStep ( btCollisionWorld* collisionWorld) = 0;
+	virtual void	playerStep (btCollisionWorld* collisionWorld, btScalar dt) = 0;
+	virtual bool	canJump () const = 0;
+	virtual void	jump () = 0;
+
+	virtual bool	onGround () const = 0;
+};
+
+#endif
Index: code/branches/physics/src/bullet/BulletDynamics/Character/btKinematicCharacterController.cpp
===================================================================
--- code/branches/physics/src/bullet/BulletDynamics/Character/btKinematicCharacterController.cpp	(revision 2430)
+++ code/branches/physics/src/bullet/BulletDynamics/Character/btKinematicCharacterController.cpp	(revision 2430)
@@ -0,0 +1,470 @@
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2008 Erwin Coumans  http://bulletphysics.com
+
+This software is provided 'as-is', without any express or implied warranty.
+In no event will the authors be held liable for any damages arising from the use of this software.
+Permission is granted to anyone to use this software for any purpose, 
+including commercial applications, and to alter it and redistribute it freely, 
+subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+*/
+
+#include "LinearMath/btIDebugDraw.h"
+#include "BulletCollision/CollisionDispatch/btGhostObject.h"
+#include "BulletCollision/CollisionShapes/btMultiSphereShape.h"
+#include "BulletCollision/BroadphaseCollision/btOverlappingPairCache.h"
+#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"
+#include "BulletCollision/CollisionDispatch/btCollisionWorld.h"
+#include "LinearMath/btDefaultMotionState.h"
+#include "btKinematicCharacterController.h"
+
+///@todo Interact with dynamic objects,
+///Ride kinematicly animated platforms properly
+///More realistic (or maybe just a config option) falling
+/// -> Should integrate falling velocity manually and use that in stepDown()
+///Support jumping
+///Support ducking
+class btKinematicClosestNotMeRayResultCallback : public btCollisionWorld::ClosestRayResultCallback
+{
+public:
+	btKinematicClosestNotMeRayResultCallback (btCollisionObject* me) : btCollisionWorld::ClosestRayResultCallback(btVector3(0.0, 0.0, 0.0), btVector3(0.0, 0.0, 0.0))
+	{
+		m_me = me;
+	}
+
+	virtual btScalar addSingleResult(btCollisionWorld::LocalRayResult& rayResult,bool normalInWorldSpace)
+	{
+		if (rayResult.m_collisionObject == m_me)
+			return 1.0;
+
+		return ClosestRayResultCallback::addSingleResult (rayResult, normalInWorldSpace);
+	}
+protected:
+	btCollisionObject* m_me;
+};
+
+class btKinematicClosestNotMeConvexResultCallback : public btCollisionWorld::ClosestConvexResultCallback
+{
+public:
+	btKinematicClosestNotMeConvexResultCallback (btCollisionObject* me) : btCollisionWorld::ClosestConvexResultCallback(btVector3(0.0, 0.0, 0.0), btVector3(0.0, 0.0, 0.0))
+	{
+		m_me = me;
+	}
+
+	virtual btScalar addSingleResult(btCollisionWorld::LocalConvexResult& convexResult,bool normalInWorldSpace)
+	{
+		if (convexResult.m_hitCollisionObject == m_me)
+			return 1.0;
+
+		return ClosestConvexResultCallback::addSingleResult (convexResult, normalInWorldSpace);
+	}
+protected:
+	btCollisionObject* m_me;
+};
+
+/*
+ * Returns the reflection direction of a ray going 'direction' hitting a surface with normal 'normal'
+ *
+ * from: http://www-cs-students.stanford.edu/~adityagp/final/node3.html
+ */
+btVector3 btKinematicCharacterController::computeReflectionDirection (const btVector3& direction, const btVector3& normal)
+{
+	return direction - (btScalar(2.0) * direction.dot(normal)) * normal;
+}
+
+/*
+ * Returns the portion of 'direction' that is parallel to 'normal'
+ */
+btVector3 btKinematicCharacterController::parallelComponent (const btVector3& direction, const btVector3& normal)
+{
+	btScalar magnitude = direction.dot(normal);
+	return normal * magnitude;
+}
+
+/*
+ * Returns the portion of 'direction' that is perpindicular to 'normal'
+ */
+btVector3 btKinematicCharacterController::perpindicularComponent (const btVector3& direction, const btVector3& normal)
+{
+	return direction - parallelComponent(direction, normal);
+}
+
+btKinematicCharacterController::btKinematicCharacterController (btPairCachingGhostObject* ghostObject,btConvexShape* convexShape,btScalar stepHeight)
+{
+	m_addedMargin = 0.02f;
+	m_walkDirection.setValue(0,0,0);
+	m_useGhostObjectSweepTest = true;
+	m_ghostObject = ghostObject;
+	m_stepHeight = stepHeight;
+	m_turnAngle = btScalar(0.0);
+	m_convexShape=convexShape;
+	
+}
+
+btKinematicCharacterController::~btKinematicCharacterController ()
+{
+}
+
+
+btPairCachingGhostObject* btKinematicCharacterController::getGhostObject()
+{
+	return m_ghostObject;
+}
+
+bool btKinematicCharacterController::recoverFromPenetration (btCollisionWorld* collisionWorld)
+{
+
+	bool penetration = false;
+
+	collisionWorld->getDispatcher()->dispatchAllCollisionPairs(m_ghostObject->getOverlappingPairCache(), collisionWorld->getDispatchInfo(), collisionWorld->getDispatcher());
+
+	m_currentPosition = m_ghostObject->getWorldTransform().getOrigin();
+	
+	btScalar maxPen = btScalar(0.0);
+	for (int i = 0; i < m_ghostObject->getOverlappingPairCache()->getNumOverlappingPairs(); i++)
+	{
+		m_manifoldArray.resize(0);
+
+		btBroadphasePair* collisionPair = &m_ghostObject->getOverlappingPairCache()->getOverlappingPairArray()[i];
+		
+		if (collisionPair->m_algorithm)
+			collisionPair->m_algorithm->getAllContactManifolds(m_manifoldArray);
+
+		
+		for (int j=0;j<m_manifoldArray.size();j++)
+		{
+			btPersistentManifold* manifold = m_manifoldArray[j];
+			btScalar directionSign = manifold->getBody0() == m_ghostObject ? btScalar(-1.0) : btScalar(1.0);
+			for (int p=0;p<manifold->getNumContacts();p++)
+			{
+				const btManifoldPoint&pt = manifold->getContactPoint(p);
+
+				if (pt.getDistance() < 0.0)
+				{
+					if (pt.getDistance() < maxPen)
+					{
+						maxPen = pt.getDistance();
+						m_touchingNormal = pt.m_normalWorldOnB * directionSign;//??
+
+					}
+					m_currentPosition += pt.m_normalWorldOnB * directionSign * pt.getDistance() * btScalar(0.2);
+					penetration = true;
+				} else {
+					//printf("touching %f\n", pt.getDistance());
+				}
+			}
+			
+			//manifold->clearManifold();
+		}
+	}
+	btTransform newTrans = m_ghostObject->getWorldTransform();
+	newTrans.setOrigin(m_currentPosition);
+	m_ghostObject->setWorldTransform(newTrans);
+//	printf("m_touchingNormal = %f,%f,%f\n",m_touchingNormal[0],m_touchingNormal[1],m_touchingNormal[2]);
+	return penetration;
+}
+
+void btKinematicCharacterController::stepUp ( btCollisionWorld* world)
+{
+	// phase 1: up
+	btTransform start, end;
+	m_targetPosition = m_currentPosition + btVector3 (btScalar(0.0), m_stepHeight, btScalar(0.0));
+
+	start.setIdentity ();
+	end.setIdentity ();
+
+	/* FIXME: Handle penetration properly */
+	start.setOrigin (m_currentPosition + btVector3(btScalar(0.0), btScalar(0.1), btScalar(0.0)));
+	end.setOrigin (m_targetPosition);
+
+	btKinematicClosestNotMeConvexResultCallback callback (m_ghostObject);
+	callback.m_collisionFilterGroup = getGhostObject()->getBroadphaseHandle()->m_collisionFilterGroup;
+	callback.m_collisionFilterMask = getGhostObject()->getBroadphaseHandle()->m_collisionFilterMask;
+	
+	if (m_useGhostObjectSweepTest)
+	{
+		m_ghostObject->convexSweepTest (m_convexShape, start, end, callback, world->getDispatchInfo().m_allowedCcdPenetration);
+	}
+	else
+	{
+		world->convexSweepTest (m_convexShape, start, end, callback);
+	}
+	
+	if (callback.hasHit())
+	{
+		// we moved up only a fraction of the step height
+		m_currentStepOffset = m_stepHeight * callback.m_closestHitFraction;
+		m_currentPosition.setInterpolate3 (m_currentPosition, m_targetPosition, callback.m_closestHitFraction);
+	} else {
+		m_currentStepOffset = m_stepHeight;
+		m_currentPosition = m_targetPosition;
+	}
+}
+
+void btKinematicCharacterController::updateTargetPositionBasedOnCollision (const btVector3& hitNormal, btScalar tangentMag, btScalar normalMag)
+{
+	btVector3 movementDirection = m_targetPosition - m_currentPosition;
+	btScalar movementLength = movementDirection.length();
+	if (movementLength>SIMD_EPSILON)
+	{
+		movementDirection.normalize();
+
+		btVector3 reflectDir = computeReflectionDirection (movementDirection, hitNormal);
+		reflectDir.normalize();
+
+		btVector3 parallelDir, perpindicularDir;
+
+		parallelDir = parallelComponent (reflectDir, hitNormal);
+		perpindicularDir = perpindicularComponent (reflectDir, hitNormal);
+
+		m_targetPosition = m_currentPosition;
+		if (0)//tangentMag != 0.0)
+		{
+			btVector3 parComponent = parallelDir * btScalar (tangentMag*movementLength);
+//			printf("parComponent=%f,%f,%f\n",parComponent[0],parComponent[1],parComponent[2]);
+			m_targetPosition +=  parComponent;
+		}
+
+		if (normalMag != 0.0)
+		{
+			btVector3 perpComponent = perpindicularDir * btScalar (normalMag*movementLength);
+//			printf("perpComponent=%f,%f,%f\n",perpComponent[0],perpComponent[1],perpComponent[2]);
+			m_targetPosition += perpComponent;
+		}
+	} else
+	{
+//		printf("movementLength don't normalize a zero vector\n");
+	}
+}
+
+void btKinematicCharacterController::stepForwardAndStrafe ( btCollisionWorld* collisionWorld, const btVector3& walkMove)
+{
+
+	btVector3 originalDir = walkMove.normalized();
+	if (walkMove.length() < SIMD_EPSILON)
+	{
+		originalDir.setValue(0.f,0.f,0.f);
+	}
+//	printf("originalDir=%f,%f,%f\n",originalDir[0],originalDir[1],originalDir[2]);
+	// phase 2: forward and strafe
+	btTransform start, end;
+	m_targetPosition = m_currentPosition + walkMove;
+	start.setIdentity ();
+	end.setIdentity ();
+	
+	btScalar fraction = 1.0;
+	btScalar distance2 = (m_currentPosition-m_targetPosition).length2();
+//	printf("distance2=%f\n",distance2);
+
+	if (m_touchingContact)
+	{
+		if (originalDir.dot(m_touchingNormal) > btScalar(0.0))
+			updateTargetPositionBasedOnCollision (m_touchingNormal);
+	}
+
+	int maxIter = 10;
+
+	while (fraction > btScalar(0.01) && maxIter-- > 0)
+	{
+		start.setOrigin (m_currentPosition);
+		end.setOrigin (m_targetPosition);
+
+		btKinematicClosestNotMeConvexResultCallback callback (m_ghostObject);
+		callback.m_collisionFilterGroup = getGhostObject()->getBroadphaseHandle()->m_collisionFilterGroup;
+		callback.m_collisionFilterMask = getGhostObject()->getBroadphaseHandle()->m_collisionFilterMask;
+
+
+		btScalar margin = m_convexShape->getMargin();
+		m_convexShape->setMargin(margin + m_addedMargin);
+
+
+		if (m_useGhostObjectSweepTest)
+		{
+			m_ghostObject->convexSweepTest (m_convexShape, start, end, callback, collisionWorld->getDispatchInfo().m_allowedCcdPenetration);
+		} else
+		{
+			collisionWorld->convexSweepTest (m_convexShape, start, end, callback, collisionWorld->getDispatchInfo().m_allowedCcdPenetration);
+		}
+		
+		m_convexShape->setMargin(margin);
+
+		
+		fraction -= callback.m_closestHitFraction;
+
+		if (callback.hasHit())
+		{	
+			// we moved only a fraction
+			btScalar hitDistance = (callback.m_hitPointWorld - m_currentPosition).length();
+			if (hitDistance<0.f)
+			{
+//				printf("neg dist?\n");
+			}
+
+			/* If the distance is farther than the collision margin, move */
+			if (hitDistance > m_addedMargin)
+			{
+//				printf("callback.m_closestHitFraction=%f\n",callback.m_closestHitFraction);
+				m_currentPosition.setInterpolate3 (m_currentPosition, m_targetPosition, callback.m_closestHitFraction);
+			}
+
+			updateTargetPositionBasedOnCollision (callback.m_hitNormalWorld);
+			btVector3 currentDir = m_targetPosition - m_currentPosition;
+			distance2 = currentDir.length2();
+			if (distance2 > SIMD_EPSILON)
+			{
+				currentDir.normalize();
+				/* See Quake2: "If velocity is against original velocity, stop ead to avoid tiny oscilations in sloping corners." */
+				if (currentDir.dot(originalDir) <= btScalar(0.0))
+				{
+					break;
+				}
+			} else
+			{
+//				printf("currentDir: don't normalize a zero vector\n");
+				break;
+			}
+		} else {
+			// we moved whole way
+			m_currentPosition = m_targetPosition;
+		}
+
+	//	if (callback.m_closestHitFraction == 0.f)
+	//		break;
+
+	}
+}
+
+void btKinematicCharacterController::stepDown ( btCollisionWorld* collisionWorld, btScalar dt)
+{
+	btTransform start, end;
+
+	// phase 3: down
+	btVector3 step_drop = btVector3(btScalar(0.0), m_currentStepOffset, btScalar(0.0));
+	btVector3 gravity_drop = btVector3(btScalar(0.0), m_stepHeight, btScalar(0.0));
+	m_targetPosition -= (step_drop + gravity_drop);
+
+	start.setIdentity ();
+	end.setIdentity ();
+
+	start.setOrigin (m_currentPosition);
+	end.setOrigin (m_targetPosition);
+
+	btKinematicClosestNotMeConvexResultCallback callback (m_ghostObject);
+	callback.m_collisionFilterGroup = getGhostObject()->getBroadphaseHandle()->m_collisionFilterGroup;
+	callback.m_collisionFilterMask = getGhostObject()->getBroadphaseHandle()->m_collisionFilterMask;
+	
+	if (m_useGhostObjectSweepTest)
+	{
+		m_ghostObject->convexSweepTest (m_convexShape, start, end, callback, collisionWorld->getDispatchInfo().m_allowedCcdPenetration);
+	} else
+	{
+		collisionWorld->convexSweepTest (m_convexShape, start, end, callback, collisionWorld->getDispatchInfo().m_allowedCcdPenetration);
+	}
+
+	if (callback.hasHit())
+	{
+		// we dropped a fraction of the height -> hit floor
+		m_currentPosition.setInterpolate3 (m_currentPosition, m_targetPosition, callback.m_closestHitFraction);
+	} else {
+		// we dropped the full height
+		
+		m_currentPosition = m_targetPosition;
+	}
+}
+
+void btKinematicCharacterController::reset ()
+{
+}
+
+void btKinematicCharacterController::warp (const btVector3& origin)
+{
+	btTransform xform;
+	xform.setIdentity();
+	xform.setOrigin (origin);
+	m_ghostObject->setWorldTransform (xform);
+}
+
+
+void btKinematicCharacterController::preStep ( btCollisionWorld* collisionWorld)
+{
+	
+	int numPenetrationLoops = 0;
+	m_touchingContact = false;
+	while (recoverFromPenetration (collisionWorld))
+	{
+		numPenetrationLoops++;
+		m_touchingContact = true;
+		if (numPenetrationLoops > 4)
+		{
+//			printf("character could not recover from penetration = %d\n", numPenetrationLoops);
+			break;
+		}
+	}
+
+	m_currentPosition = m_ghostObject->getWorldTransform().getOrigin();
+	m_targetPosition = m_currentPosition;
+//	printf("m_targetPosition=%f,%f,%f\n",m_targetPosition[0],m_targetPosition[1],m_targetPosition[2]);
+
+	
+}
+
+void btKinematicCharacterController::playerStep ( btCollisionWorld* collisionWorld, btScalar dt)
+{
+	btTransform xform;
+	xform = m_ghostObject->getWorldTransform ();
+
+//	printf("walkDirection(%f,%f,%f)\n",walkDirection[0],walkDirection[1],walkDirection[2]);
+//	printf("walkSpeed=%f\n",walkSpeed);
+
+	stepUp (collisionWorld);
+	stepForwardAndStrafe (collisionWorld, m_walkDirection);
+	stepDown (collisionWorld, dt);
+
+	xform.setOrigin (m_currentPosition);
+	m_ghostObject->setWorldTransform (xform);
+}
+
+void btKinematicCharacterController::setFallSpeed (btScalar fallSpeed)
+{
+	m_fallSpeed = fallSpeed;
+}
+
+void btKinematicCharacterController::setJumpSpeed (btScalar jumpSpeed)
+{
+	m_jumpSpeed = jumpSpeed;
+}
+
+void btKinematicCharacterController::setMaxJumpHeight (btScalar maxJumpHeight)
+{
+	m_maxJumpHeight = maxJumpHeight;
+}
+
+bool btKinematicCharacterController::canJump () const
+{
+	return onGround();
+}
+
+void btKinematicCharacterController::jump ()
+{
+	if (!canJump())
+		return;
+
+#if 0
+	currently no jumping.
+	btTransform xform;
+	m_rigidBody->getMotionState()->getWorldTransform (xform);
+	btVector3 up = xform.getBasis()[1];
+	up.normalize ();
+	btScalar magnitude = (btScalar(1.0)/m_rigidBody->getInvMass()) * btScalar(8.0);
+	m_rigidBody->applyCentralImpulse (up * magnitude);
+#endif
+}
+
+bool btKinematicCharacterController::onGround () const
+{
+	return true;
+}
Index: code/branches/physics/src/bullet/BulletDynamics/Character/btKinematicCharacterController.h
===================================================================
--- code/branches/physics/src/bullet/BulletDynamics/Character/btKinematicCharacterController.h	(revision 2430)
+++ code/branches/physics/src/bullet/BulletDynamics/Character/btKinematicCharacterController.h	(revision 2430)
@@ -0,0 +1,105 @@
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2008 Erwin Coumans  http://bulletphysics.com
+
+This software is provided 'as-is', without any express or implied warranty.
+In no event will the authors be held liable for any damages arising from the use of this software.
+Permission is granted to anyone to use this software for any purpose, 
+including commercial applications, and to alter it and redistribute it freely, 
+subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef KINEMATIC_CHARACTER_CONTROLLER_H
+#define KINEMATIC_CHARACTER_CONTROLLER_H
+
+#include "LinearMath/btVector3.h"
+
+#include "btCharacterControllerInterface.h"
+
+class btCollisionShape;
+class btRigidBody;
+class btCollisionWorld;
+class btCollisionDispatcher;
+class btPairCachingGhostObject;
+
+///btKinematicCharacterController is an object that supports a sliding motion in a world.
+///It uses a ghost object and convex sweep test to test for upcoming collisions. This is combined with discrete collision detection to recover from penetrations.
+///Interaction between btKinematicCharacterController and dynamic rigid bodies needs to be explicity implemented by the user.
+class btKinematicCharacterController : public btCharacterControllerInterface
+{
+protected:
+	btScalar m_halfHeight;
+	
+	btPairCachingGhostObject* m_ghostObject;
+	btConvexShape*	m_convexShape;//is also in m_ghostObject, but it needs to be convex, so we store it here to avoid upcast
+	
+	btScalar m_fallSpeed;
+	btScalar m_jumpSpeed;
+	btScalar m_maxJumpHeight;
+
+	btScalar m_turnAngle;
+	
+	btScalar m_stepHeight;
+
+	btScalar	m_addedMargin;//@todo: remove this and fix the code
+
+	///this is the desired walk direction, set by the user
+	btVector3	m_walkDirection;
+
+	//some internal variables
+	btVector3 m_currentPosition;
+	btScalar  m_currentStepOffset;
+	btVector3 m_targetPosition;
+
+	///keep track of the contact manifolds
+	btManifoldArray	m_manifoldArray;
+
+	bool m_touchingContact;
+	btVector3 m_touchingNormal;
+
+	bool	m_useGhostObjectSweepTest;
+	
+	btVector3 computeReflectionDirection (const btVector3& direction, const btVector3& normal);
+	btVector3 parallelComponent (const btVector3& direction, const btVector3& normal);
+	btVector3 perpindicularComponent (const btVector3& direction, const btVector3& normal);
+
+	bool recoverFromPenetration (btCollisionWorld* collisionWorld);
+	void stepUp (btCollisionWorld* collisionWorld);
+	void updateTargetPositionBasedOnCollision (const btVector3& hit_normal, btScalar tangentMag = btScalar(0.0), btScalar normalMag = btScalar(1.0));
+	void stepForwardAndStrafe (btCollisionWorld* collisionWorld, const btVector3& walkMove);
+	void stepDown (btCollisionWorld* collisionWorld, btScalar dt);
+public:
+	btKinematicCharacterController (btPairCachingGhostObject* ghostObject,btConvexShape* convexShape,btScalar stepHeight);
+	~btKinematicCharacterController ();
+	
+	virtual void	setWalkDirection(const btVector3& walkDirection)
+	{
+		m_walkDirection = walkDirection;
+	}
+
+	void reset ();
+	void warp (const btVector3& origin);
+
+	void preStep ( btCollisionWorld* collisionWorld);
+	void playerStep (btCollisionWorld* collisionWorld, btScalar dt);
+
+	void setFallSpeed (btScalar fallSpeed);
+	void setJumpSpeed (btScalar jumpSpeed);
+	void setMaxJumpHeight (btScalar maxJumpHeight);
+	bool canJump () const;
+	void jump ();
+
+	btPairCachingGhostObject* getGhostObject();
+	void	setUseGhostSweepTest(bool useGhostObjectSweepTest)
+	{
+		m_useGhostObjectSweepTest = useGhostObjectSweepTest;
+	}
+
+	bool onGround () const;
+};
+
+#endif // KINEMATIC_CHARACTER_CONTROLLER_H
Index: code/branches/physics/src/bullet/BulletDynamics/ConstraintSolver/btConeTwistConstraint.h
===================================================================
--- code/branches/physics/src/bullet/BulletDynamics/ConstraintSolver/btConeTwistConstraint.h	(revision 2192)
+++ code/branches/physics/src/bullet/BulletDynamics/ConstraintSolver/btConeTwistConstraint.h	(revision 2430)
@@ -21,5 +21,5 @@
 #define CONETWISTCONSTRAINT_H
 
-#include "../../LinearMath/btVector3.h"
+#include "LinearMath/btVector3.h"
 #include "btJacobianEntry.h"
 #include "btTypedConstraint.h"
Index: code/branches/physics/src/bullet/BulletDynamics/ConstraintSolver/btContactConstraint.cpp
===================================================================
--- code/branches/physics/src/bullet/BulletDynamics/ConstraintSolver/btContactConstraint.cpp	(revision 2192)
+++ code/branches/physics/src/bullet/BulletDynamics/ConstraintSolver/btContactConstraint.cpp	(revision 2430)
@@ -426,4 +426,4 @@
 
 	return btScalar(0.);
-};
-
+}
+
Index: code/branches/physics/src/bullet/BulletDynamics/ConstraintSolver/btContactConstraint.h
===================================================================
--- code/branches/physics/src/bullet/BulletDynamics/ConstraintSolver/btContactConstraint.h	(revision 2192)
+++ code/branches/physics/src/bullet/BulletDynamics/ConstraintSolver/btContactConstraint.h	(revision 2430)
@@ -17,5 +17,5 @@
 #define CONTACT_CONSTRAINT_H
 
-//todo: make into a proper class working with the iterative constraint solver
+///@todo: make into a proper class working with the iterative constraint solver
 
 class btRigidBody;
Index: code/branches/physics/src/bullet/BulletDynamics/ConstraintSolver/btContactSolverInfo.h
===================================================================
--- code/branches/physics/src/bullet/BulletDynamics/ConstraintSolver/btContactSolverInfo.h	(revision 2192)
+++ code/branches/physics/src/bullet/BulletDynamics/ConstraintSolver/btContactSolverInfo.h	(revision 2430)
@@ -22,5 +22,6 @@
 	SOLVER_FRICTION_SEPARATE = 2,
 	SOLVER_USE_WARMSTARTING = 4,
-	SOLVER_CACHE_FRIENDLY = 8
+	SOLVER_USE_FRICTION_WARMSTARTING = 8,
+	SOLVER_CACHE_FRIENDLY = 16
 };
 
@@ -45,4 +46,5 @@
 
 	int			m_solverMode;
+	int	m_restingContactRestitutionThreshold;
 
 
@@ -69,5 +71,6 @@
 		m_linearSlop = btScalar(0.0);
 		m_warmstartingFactor=btScalar(0.85);
-		m_solverMode = SOLVER_RANDMIZE_ORDER | SOLVER_CACHE_FRIENDLY | SOLVER_USE_WARMSTARTING;
+		m_solverMode = SOLVER_CACHE_FRIENDLY |  SOLVER_RANDMIZE_ORDER |  SOLVER_USE_WARMSTARTING;
+		m_restingContactRestitutionThreshold = 2;//resting contact lifetime threshold to disable restitution
 	}
 };
Index: code/branches/physics/src/bullet/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.cpp
===================================================================
--- code/branches/physics/src/bullet/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.cpp	(revision 2192)
+++ code/branches/physics/src/bullet/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.cpp	(revision 2430)
@@ -27,7 +27,4 @@
 
 
-static const btScalar kSign[] = { btScalar(1.0), btScalar(-1.0), btScalar(1.0) };
-static const int kAxisA[] = { 1, 0, 0 };
-static const int kAxisB[] = { 2, 2, 1 };
 #define GENERIC_D6_DISABLE_WARMSTARTING 1
 
@@ -157,5 +154,5 @@
     btScalar clippedMotorImpulse;
 
-    //todo: should clip against accumulated impulse
+    ///@todo: should clip against accumulated impulse
     if (unclippedMotorImpulse>0.0f)
     {
Index: code/branches/physics/src/bullet/BulletDynamics/ConstraintSolver/btHingeConstraint.cpp
===================================================================
--- code/branches/physics/src/bullet/BulletDynamics/ConstraintSolver/btHingeConstraint.cpp	(revision 2192)
+++ code/branches/physics/src/bullet/BulletDynamics/ConstraintSolver/btHingeConstraint.cpp	(revision 2430)
@@ -324,5 +324,4 @@
 					getRigidBodyB().computeAngularImpulseDenominator(normal);
 				// scale for mass and relaxation
-				//todo:  expose this 0.9 factor to developer
 				velrelOrthog *= (btScalar(1.)/denom) * m_relaxationFactor;
 			}
Index: code/branches/physics/src/bullet/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp
===================================================================
--- code/branches/physics/src/bullet/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp	(revision 2192)
+++ code/branches/physics/src/bullet/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp	(revision 2430)
@@ -438,5 +438,5 @@
 
 
-void	btSequentialImpulseConstraintSolver::addFrictionConstraint(const btVector3& normalAxis,int solverBodyIdA,int solverBodyIdB,int frictionIndex,btManifoldPoint& cp,const btVector3& rel_pos1,const btVector3& rel_pos2,btCollisionObject* colObj0,btCollisionObject* colObj1, btScalar relaxation)
+btSolverConstraint&	btSequentialImpulseConstraintSolver::addFrictionConstraint(const btVector3& normalAxis,int solverBodyIdA,int solverBodyIdB,int frictionIndex,btManifoldPoint& cp,const btVector3& rel_pos1,const btVector3& rel_pos2,btCollisionObject* colObj0,btCollisionObject* colObj1, btScalar relaxation)
 {
 
@@ -492,5 +492,5 @@
 	solverConstraint.m_jacDiagABInv = denom;
 
-
+	return solverConstraint;
 }
 
@@ -719,9 +719,17 @@
 
 							solverConstraint.m_friction = cp.m_combinedFriction;
-							solverConstraint.m_restitution =  restitutionCurve(rel_vel, cp.m_combinedRestitution);
-							if (solverConstraint.m_restitution <= btScalar(0.))
+
+							
+							if (cp.m_lifeTime>infoGlobal.m_restingContactRestitutionThreshold)
 							{
 								solverConstraint.m_restitution = 0.f;
-							};
+							} else
+							{
+								solverConstraint.m_restitution =  restitutionCurve(rel_vel, cp.m_combinedRestitution);
+								if (solverConstraint.m_restitution <= btScalar(0.))
+								{
+									solverConstraint.m_restitution = 0.f;
+								};
+							}
 
 							
@@ -761,49 +769,59 @@
 									cp.m_lateralFrictionDir1 /= btSqrt(lat_rel_vel);
 									addFrictionConstraint(cp.m_lateralFrictionDir1,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation);
-									cp.m_lateralFrictionDir2 = cp.m_lateralFrictionDir1.cross(cp.m_normalWorldOnB);
-									cp.m_lateralFrictionDir2.normalize();//??
-									addFrictionConstraint(cp.m_lateralFrictionDir2,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation);
+									if(infoGlobal.m_solverMode & SOLVER_USE_FRICTION_WARMSTARTING)
+									{
+										cp.m_lateralFrictionDir2 = cp.m_lateralFrictionDir1.cross(cp.m_normalWorldOnB);
+										cp.m_lateralFrictionDir2.normalize();//??
+										addFrictionConstraint(cp.m_lateralFrictionDir2,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation);
+										cp.m_lateralFrictionInitialized = true;
+									}
 								} else
 								{
 									//re-calculate friction direction every frame, todo: check if this is really needed
-									
 									btPlaneSpace1(cp.m_normalWorldOnB,cp.m_lateralFrictionDir1,cp.m_lateralFrictionDir2);
 									addFrictionConstraint(cp.m_lateralFrictionDir1,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation);
 									addFrictionConstraint(cp.m_lateralFrictionDir2,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation);
+									if (infoGlobal.m_solverMode & SOLVER_USE_FRICTION_WARMSTARTING)
+									{
+										cp.m_lateralFrictionInitialized = true;
+									}
 								}
-								cp.m_lateralFrictionInitialized = true;
 								
 							} else
 							{
 								addFrictionConstraint(cp.m_lateralFrictionDir1,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation);
-								addFrictionConstraint(cp.m_lateralFrictionDir2,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation);
+								if (infoGlobal.m_solverMode & SOLVER_USE_FRICTION_WARMSTARTING)
+									addFrictionConstraint(cp.m_lateralFrictionDir2,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation);
 							}
 
+							if (infoGlobal.m_solverMode & SOLVER_USE_FRICTION_WARMSTARTING)
 							{
-								btSolverConstraint& frictionConstraint1 = m_tmpSolverFrictionConstraintPool[solverConstraint.m_frictionIndex];
-								if (infoGlobal.m_solverMode & SOLVER_USE_WARMSTARTING)
 								{
-									frictionConstraint1.m_appliedImpulse = cp.m_appliedImpulseLateral1 * infoGlobal.m_warmstartingFactor;
-									if (rb0)
-										m_tmpSolverBodyPool[solverConstraint.m_solverBodyIdA].internalApplyImpulse(frictionConstraint1.m_contactNormal*rb0->getInvMass(),frictionConstraint1.m_angularComponentA,frictionConstraint1.m_appliedImpulse);
-									if (rb1)
-										m_tmpSolverBodyPool[solverConstraint.m_solverBodyIdB].internalApplyImpulse(frictionConstraint1.m_contactNormal*rb1->getInvMass(),frictionConstraint1.m_angularComponentB,-frictionConstraint1.m_appliedImpulse);
-								} else
+									btSolverConstraint& frictionConstraint1 = m_tmpSolverFrictionConstraintPool[solverConstraint.m_frictionIndex];
+									if (infoGlobal.m_solverMode & SOLVER_USE_WARMSTARTING)
+									{
+										frictionConstraint1.m_appliedImpulse = cp.m_appliedImpulseLateral1 * infoGlobal.m_warmstartingFactor;
+										if (rb0)
+											m_tmpSolverBodyPool[solverConstraint.m_solverBodyIdA].internalApplyImpulse(frictionConstraint1.m_contactNormal*rb0->getInvMass(),frictionConstraint1.m_angularComponentA,frictionConstraint1.m_appliedImpulse);
+										if (rb1)
+											m_tmpSolverBodyPool[solverConstraint.m_solverBodyIdB].internalApplyImpulse(frictionConstraint1.m_contactNormal*rb1->getInvMass(),frictionConstraint1.m_angularComponentB,-frictionConstraint1.m_appliedImpulse);
+									} else
+									{
+										frictionConstraint1.m_appliedImpulse = 0.f;
+									}
+								}
 								{
-									frictionConstraint1.m_appliedImpulse = 0.f;
-								}
-							}
-							{
-								btSolverConstraint& frictionConstraint2 = m_tmpSolverFrictionConstraintPool[solverConstraint.m_frictionIndex+1];
-								if (infoGlobal.m_solverMode & SOLVER_USE_WARMSTARTING)
-								{
-									frictionConstraint2.m_appliedImpulse = cp.m_appliedImpulseLateral2 * infoGlobal.m_warmstartingFactor;
-									if (rb0)
-										m_tmpSolverBodyPool[solverConstraint.m_solverBodyIdA].internalApplyImpulse(frictionConstraint2.m_contactNormal*rb0->getInvMass(),frictionConstraint2.m_angularComponentA,frictionConstraint2.m_appliedImpulse);
-									if (rb1)
-										m_tmpSolverBodyPool[solverConstraint.m_solverBodyIdB].internalApplyImpulse(frictionConstraint2.m_contactNormal*rb1->getInvMass(),frictionConstraint2.m_angularComponentB,-frictionConstraint2.m_appliedImpulse);
-								} else
-								{
-									frictionConstraint2.m_appliedImpulse = 0.f;
+									btSolverConstraint& frictionConstraint2 = m_tmpSolverFrictionConstraintPool[solverConstraint.m_frictionIndex+1];
+									if (infoGlobal.m_solverMode & SOLVER_USE_WARMSTARTING)
+									{
+										frictionConstraint2.m_appliedImpulse = cp.m_appliedImpulseLateral2 * infoGlobal.m_warmstartingFactor;
+										if (rb0)
+											m_tmpSolverBodyPool[solverConstraint.m_solverBodyIdA].internalApplyImpulse(frictionConstraint2.m_contactNormal*rb0->getInvMass(),frictionConstraint2.m_angularComponentA,frictionConstraint2.m_appliedImpulse);
+										if (rb1)
+											m_tmpSolverBodyPool[solverConstraint.m_solverBodyIdB].internalApplyImpulse(frictionConstraint2.m_contactNormal*rb1->getInvMass(),frictionConstraint2.m_angularComponentB,-frictionConstraint2.m_appliedImpulse);
+									} else
+									{
+										frictionConstraint2.m_appliedImpulse = 0.f;
+									}
 								}
 							}
@@ -833,5 +851,5 @@
 	int numFrictionPool = m_tmpSolverFrictionConstraintPool.size();
 
-	///todo: use stack allocator for such temporarily memory, same for solver bodies/constraints
+	///@todo: use stack allocator for such temporarily memory, same for solver bodies/constraints
 	m_orderTmpConstraintPool.resize(numConstraintPool);
 	m_orderFrictionConstraintPool.resize(numFrictionPool);
@@ -985,6 +1003,9 @@
 		btAssert(pt);
 		pt->m_appliedImpulse = solveManifold.m_appliedImpulse;
-		pt->m_appliedImpulseLateral1 = m_tmpSolverFrictionConstraintPool[solveManifold.m_frictionIndex].m_appliedImpulse;
-		pt->m_appliedImpulseLateral1 = m_tmpSolverFrictionConstraintPool[solveManifold.m_frictionIndex+1].m_appliedImpulse;
+		if (infoGlobal.m_solverMode & SOLVER_USE_FRICTION_WARMSTARTING)
+		{
+			pt->m_appliedImpulseLateral1 = m_tmpSolverFrictionConstraintPool[solveManifold.m_frictionIndex].m_appliedImpulse;
+			pt->m_appliedImpulseLateral2 = m_tmpSolverFrictionConstraintPool[solveManifold.m_frictionIndex+1].m_appliedImpulse;
+		}
 
 		//do a callback here?
@@ -1221,10 +1242,15 @@
 				cpd->m_penetration = cp.getDistance();///btScalar(info.m_numIterations);
 				cpd->m_friction = cp.m_combinedFriction;
-				cpd->m_restitution = restitutionCurve(rel_vel, combinedRestitution);
-				if (cpd->m_restitution <= btScalar(0.))
-				{
-					cpd->m_restitution = btScalar(0.0);
-
-				};
+				if (cp.m_lifeTime>info.m_restingContactRestitutionThreshold)
+				{
+					cpd->m_restitution = 0.f;
+				} else
+				{
+					cpd->m_restitution = restitutionCurve(rel_vel, combinedRestitution);
+					if (cpd->m_restitution <= btScalar(0.))
+					{
+						cpd->m_restitution = btScalar(0.0);
+					};
+				}
 				
 				//restitution and penetration work in same direction so
Index: code/branches/physics/src/bullet/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h
===================================================================
--- code/branches/physics/src/bullet/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h	(revision 2192)
+++ code/branches/physics/src/bullet/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h	(revision 2430)
@@ -24,8 +24,8 @@
 
 
-/// btSequentialImpulseConstraintSolver uses a Propagation Method and Sequentially applies impulses
-/// The approach is the 3D version of Erin Catto's GDC 2006 tutorial. See http://www.gphysics.com
-/// Although Sequential Impulse is more intuitive, it is mathematically equivalent to Projected Successive Overrelaxation (iterative LCP)
-/// Applies impulses for combined restitution and penetration recovery and to simulate friction
+///The btSequentialImpulseConstraintSolver uses a Propagation Method and Sequentially applies impulses
+///The approach is the 3D version of Erin Catto's GDC 2006 tutorial. See http://www.gphysics.com
+///Although Sequential Impulse is more intuitive, it is mathematically equivalent to Projected Successive Overrelaxation (iterative LCP)
+///Applies impulses for combined restitution and penetration recovery and to simulate friction
 class btSequentialImpulseConstraintSolver : public btConstraintSolver
 {
@@ -42,5 +42,5 @@
 	btScalar solveFriction(btRigidBody* body0,btRigidBody* body1, btManifoldPoint& cp, const btContactSolverInfo& info,int iter,btIDebugDraw* debugDrawer);
 	void  prepareConstraints(btPersistentManifold* manifoldPtr, const btContactSolverInfo& info,btIDebugDraw* debugDrawer);
-	void	addFrictionConstraint(const btVector3& normalAxis,int solverBodyIdA,int solverBodyIdB,int frictionIndex,btManifoldPoint& cp,const btVector3& rel_pos1,const btVector3& rel_pos2,btCollisionObject* colObj0,btCollisionObject* colObj1, btScalar relaxation);
+	btSolverConstraint&	addFrictionConstraint(const btVector3& normalAxis,int solverBodyIdA,int solverBodyIdB,int frictionIndex,btManifoldPoint& cp,const btVector3& rel_pos1,const btVector3& rel_pos2,btCollisionObject* colObj0,btCollisionObject* colObj1, btScalar relaxation);
 
 	ContactSolverFunc m_contactDispatch[MAX_CONTACT_SOLVER_TYPES][MAX_CONTACT_SOLVER_TYPES];
Index: code/branches/physics/src/bullet/BulletDynamics/ConstraintSolver/btSolverBody.h
===================================================================
--- code/branches/physics/src/bullet/BulletDynamics/ConstraintSolver/btSolverBody.h	(revision 2192)
+++ code/branches/physics/src/bullet/BulletDynamics/ConstraintSolver/btSolverBody.h	(revision 2430)
@@ -25,19 +25,21 @@
 
 
-///btSolverBody is an internal datastructure for the constraint solver. Only necessary data is packed to increase cache coherence/performance.
+///The btSolverBody is an internal datastructure for the constraint solver. Only necessary data is packed to increase cache coherence/performance.
 ATTRIBUTE_ALIGNED16 (struct)	btSolverBody
 {
 	BT_DECLARE_ALIGNED_ALLOCATOR();
 	
+	btMatrix3x3		m_worldInvInertiaTensor;
+
 	btVector3		m_angularVelocity;
+	btVector3		m_linearVelocity;
+	btVector3		m_centerOfMassPosition;
+	btVector3		m_pushVelocity;
+	btVector3		m_turnVelocity;
+
 	float			m_angularFactor;
 	float			m_invMass;
 	float			m_friction;
 	btRigidBody*	m_originalBody;
-	btVector3		m_linearVelocity;
-	btVector3		m_centerOfMassPosition;
-	
-	btVector3		m_pushVelocity;
-	btVector3		m_turnVelocity;
 	
 	
Index: code/branches/physics/src/bullet/BulletDynamics/Dynamics/Bullet-C-API.cpp
===================================================================
--- code/branches/physics/src/bullet/BulletDynamics/Dynamics/Bullet-C-API.cpp	(revision 2192)
+++ code/branches/physics/src/bullet/BulletDynamics/Dynamics/Bullet-C-API.cpp	(revision 2430)
@@ -39,5 +39,5 @@
 #include "BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h"
 #include "BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h"
-#include "BulletCollision/NarrowPhaseCollision/btGjkEpa.h"
+#include "BulletCollision/NarrowPhaseCollision/btGjkEpa2.h"
 #include "BulletCollision/CollisionShapes/btMinkowskiSumShape.h"
 #include "BulletCollision/NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h"
@@ -256,5 +256,5 @@
 	btAssert(colShape->getShapeType()==CONVEX_HULL_SHAPE_PROXYTYPE);
 	btConvexHullShape* convexHullShape = reinterpret_cast<btConvexHullShape*>( cshape);
-	convexHullShape->addPoint(btPoint3(x,y,z));
+	convexHullShape->addPoint(btVector3(x,y,z));
 
 }
Index: code/branches/physics/src/bullet/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp
===================================================================
--- code/branches/physics/src/bullet/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp	(revision 2192)
+++ code/branches/physics/src/bullet/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp	(revision 2430)
@@ -52,4 +52,7 @@
 #include "BulletDynamics/Vehicle/btVehicleRaycaster.h"
 #include "BulletDynamics/Vehicle/btWheelInfo.h"
+//character
+#include "BulletDynamics/Character/btCharacterControllerInterface.h"
+
 #include "LinearMath/btIDebugDraw.h"
 #include "LinearMath/btQuickprof.h"
@@ -126,4 +129,5 @@
 void	btDiscreteDynamicsWorld::debugDrawWorld()
 {
+	BT_PROFILE("debugDrawWorld");
 
 	if (getDebugDrawer() && getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_DrawContactPoints)
@@ -151,5 +155,4 @@
 		int i;
 
-		//todo: iterate over awake simulation islands!
 		for (  i=0;i<m_collisionObjects.size();i++)
 		{
@@ -180,5 +183,5 @@
 			if (m_debugDrawer && (m_debugDrawer->getDebugMode() & btIDebugDraw::DBG_DrawAabb))
 			{
-				btPoint3 minAabb,maxAabb;
+				btVector3 minAabb,maxAabb;
 				btVector3 colorvec(1,0,0);
 				colObj->getCollisionShape()->getAabb(colObj->getWorldTransform(), minAabb,maxAabb);
@@ -221,5 +224,5 @@
 void	btDiscreteDynamicsWorld::clearForces()
 {
-	//todo: iterate over awake simulation islands!
+	///@todo: iterate over awake simulation islands!
 	for ( int i=0;i<m_collisionObjects.size();i++)
 	{
@@ -237,5 +240,5 @@
 void	btDiscreteDynamicsWorld::applyGravity()
 {
-	//todo: iterate over awake simulation islands!
+	///@todo: iterate over awake simulation islands!
 	for ( int i=0;i<m_collisionObjects.size();i++)
 	{
@@ -251,7 +254,27 @@
 
 
+void	btDiscreteDynamicsWorld::synchronizeSingleMotionState(btRigidBody* body)
+{
+	btAssert(body);
+
+	if (body->getMotionState() && !body->isStaticOrKinematicObject())
+	{
+		//we need to call the update at least once, even for sleeping objects
+		//otherwise the 'graphics' transform never updates properly
+		///@todo: add 'dirty' flag
+		//if (body->getActivationState() != ISLAND_SLEEPING)
+		{
+			btTransform interpolatedTransform;
+			btTransformUtil::integrateTransform(body->getInterpolationWorldTransform(),
+				body->getInterpolationLinearVelocity(),body->getInterpolationAngularVelocity(),m_localTime*body->getHitFraction(),interpolatedTransform);
+			body->getMotionState()->setWorldTransform(interpolatedTransform);
+		}
+	}
+}
+
 
 void	btDiscreteDynamicsWorld::synchronizeMotionStates()
 {
+	BT_PROFILE("synchronizeMotionStates");
 	{
 		//todo: iterate over awake simulation islands!
@@ -261,17 +284,6 @@
 			
 			btRigidBody* body = btRigidBody::upcast(colObj);
-			if (body && body->getMotionState() && !body->isStaticOrKinematicObject())
-			{
-				//we need to call the update at least once, even for sleeping objects
-				//otherwise the 'graphics' transform never updates properly
-				//so todo: add 'dirty' flag
-				//if (body->getActivationState() != ISLAND_SLEEPING)
-				{
-					btTransform interpolatedTransform;
-					btTransformUtil::integrateTransform(body->getInterpolationWorldTransform(),
-						body->getInterpolationLinearVelocity(),body->getInterpolationAngularVelocity(),m_localTime*body->getHitFraction(),interpolatedTransform);
-					body->getMotionState()->setWorldTransform(interpolatedTransform);
-				}
-			}
+			if (body)
+				synchronizeSingleMotionState(body);
 		}
 	}
@@ -393,5 +405,6 @@
 	///update vehicle simulation
 	updateVehicles(timeStep);
-
+	
+	updateCharacters(timeStep);
 
 	updateActivationState( timeStep );
@@ -469,4 +482,18 @@
 }
 
+void	btDiscreteDynamicsWorld::updateCharacters(btScalar timeStep)
+{
+	BT_PROFILE("updateCharacters");
+	
+	for ( int i=0;i<m_characters.size();i++)
+	{
+		btCharacterControllerInterface* character = m_characters[i];
+		character->preStep (this);
+		character->playerStep (this,timeStep);
+	}
+}
+
+	
+	
 void	btDiscreteDynamicsWorld::updateActivationState(btScalar timeStep)
 {
@@ -532,4 +559,15 @@
 	m_vehicles.remove(vehicle);
 }
+
+void	btDiscreteDynamicsWorld::addCharacter(btCharacterControllerInterface* character)
+{
+	m_characters.push_back(character);
+}
+
+void	btDiscreteDynamicsWorld::removeCharacter(btCharacterControllerInterface* character)
+{
+	m_characters.remove(character);
+}
+
 
 SIMD_FORCE_INLINE	int	btGetConstraintIslandId(const btTypedConstraint* lhs)
@@ -665,5 +703,5 @@
 	
 	/// solve all the constraints for this island
-	m_islandManager->buildAndProcessIslands(getCollisionWorld()->getDispatcher(),getCollisionWorld()->getCollisionObjectArray(),&solverCallback);
+	m_islandManager->buildAndProcessIslands(getCollisionWorld()->getDispatcher(),getCollisionWorld(),&solverCallback);
 
 	m_constraintSolver->allSolved(solverInfo, m_debugDrawer, m_stackAlloc);
@@ -730,5 +768,9 @@
 	{
 		if (convexResult.m_hitCollisionObject == m_me)
-			return 1.0;
+			return 1.0f;
+
+		//ignore result if there is no contact response
+		if(!convexResult.m_hitCollisionObject->hasContactResponse())
+			return 1.0f;
 
 		btVector3 linVelA,linVelB;
@@ -751,5 +793,5 @@
 
 		///don't do CCD when the collision filters are not matching
-		if (!btCollisionWorld::ClosestConvexResultCallback::needsCollision(proxy0))
+		if (!ClosestConvexResultCallback::needsCollision(proxy0))
 			return false;
 
@@ -808,4 +850,8 @@
 						btConvexShape* convexShape = static_cast<btConvexShape*>(body->getCollisionShape());
 						btSphereShape tmpSphere(body->getCcdSweptSphereRadius());//btConvexShape* convexShape = static_cast<btConvexShape*>(body->getCollisionShape());
+
+						sweepResults.m_collisionFilterGroup = body->getBroadphaseProxy()->m_collisionFilterGroup;
+						sweepResults.m_collisionFilterMask  = body->getBroadphaseProxy()->m_collisionFilterMask;
+
 						convexSweepTest(&tmpSphere,body->getWorldTransform(),predictedTrans,sweepResults);
 						if (sweepResults.hasHit() && (sweepResults.m_closestHitFraction < 1.f))
@@ -827,4 +873,6 @@
 
 
+
+
 void	btDiscreteDynamicsWorld::predictUnconstraintMotion(btScalar timeStep)
 {
@@ -838,12 +886,10 @@
 			if (!body->isStaticOrKinematicObject())
 			{
-				if (body->isActive())
-				{
-					body->integrateVelocities( timeStep);
-					//damping
-					body->applyDamping(timeStep);
-
-					body->predictIntegratedTransform(timeStep,body->getInterpolationWorldTransform());
-				}
+				
+				body->integrateVelocities( timeStep);
+				//damping
+				body->applyDamping(timeStep);
+
+				body->predictIntegratedTransform(timeStep,body->getInterpolationWorldTransform());
 			}
 		}
@@ -1097,5 +1143,5 @@
 					btConcaveShape* concaveMesh = (btConcaveShape*) shape;
 					
-					//todo pass camera, for some culling
+					///@todo pass camera, for some culling? no -> we are not a graphics lib
 					btVector3 aabbMax(btScalar(1e30),btScalar(1e30),btScalar(1e30));
 					btVector3 aabbMin(btScalar(-1e30),btScalar(-1e30),btScalar(-1e30));
@@ -1126,5 +1172,5 @@
 					for (i=0;i<polyshape->getNumEdges();i++)
 					{
-						btPoint3 a,b;
+						btVector3 a,b;
 						polyshape->getEdge(i,a,b);
 						btVector3 wa = worldTransform * a;
Index: code/branches/physics/src/bullet/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h
===================================================================
--- code/branches/physics/src/bullet/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h	(revision 2192)
+++ code/branches/physics/src/bullet/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h	(revision 2430)
@@ -27,4 +27,5 @@
 
 class btRaycastVehicle;
+class btCharacterControllerInterface;
 class btIDebugDraw;
 #include "LinearMath/btAlignedObjectArray.h"
@@ -43,5 +44,4 @@
 	btAlignedObjectArray<btTypedConstraint*> m_constraints;
 
-
 	btVector3	m_gravity;
 
@@ -55,4 +55,7 @@
 	
 	btAlignedObjectArray<btRaycastVehicle*>	m_vehicles;
+	
+	btAlignedObjectArray<btCharacterControllerInterface*> m_characters;
+	
 
 	int	m_profileTimings;
@@ -62,7 +65,7 @@
 	virtual void	integrateTransforms(btScalar timeStep);
 		
-	void	calculateSimulationIslands();
+	virtual void	calculateSimulationIslands();
 
-	void	solveConstraints(btContactSolverInfo& solverInfo);
+	virtual void	solveConstraints(btContactSolverInfo& solverInfo);
 	
 	void	updateActivationState(btScalar timeStep);
@@ -70,13 +73,15 @@
 	void	updateVehicles(btScalar timeStep);
 
+	void	updateCharacters(btScalar timeStep);
+
 	void	startProfiling(btScalar timeStep);
 
 	virtual void	internalSingleStepSimulation( btScalar timeStep);
 
-	void	synchronizeMotionStates();
 
-	void	saveKinematicState(btScalar timeStep);
+	virtual void	saveKinematicState(btScalar timeStep);
 
 	void	debugDrawSphere(btScalar radius, const btTransform& transform, const btVector3& color);
+
 
 public:
@@ -92,11 +97,21 @@
 
 
-	void	addConstraint(btTypedConstraint* constraint, bool disableCollisionsBetweenLinkedBodies=false);
+	virtual void	synchronizeMotionStates();
 
-	void	removeConstraint(btTypedConstraint* constraint);
+	///this can be useful to synchronize a single rigid body -> graphics object
+	void	synchronizeSingleMotionState(btRigidBody* body);
 
-	void	addVehicle(btRaycastVehicle* vehicle);
+	virtual void	addConstraint(btTypedConstraint* constraint, bool disableCollisionsBetweenLinkedBodies=false);
 
-	void	removeVehicle(btRaycastVehicle* vehicle);
+	virtual void	removeConstraint(btTypedConstraint* constraint);
+
+	virtual void	addVehicle(btRaycastVehicle* vehicle);
+
+	virtual void	removeVehicle(btRaycastVehicle* vehicle);
+	
+	virtual void	addCharacter(btCharacterControllerInterface* character);
+
+	virtual void	removeCharacter(btCharacterControllerInterface* character);
+		
 
 	btSimulationIslandManager*	getSimulationIslandManager()
@@ -114,5 +129,4 @@
 		return this;
 	}
-
 
 	virtual void	setGravity(const btVector3& gravity);
@@ -153,4 +167,5 @@
 	virtual void	setNumTasks(int numTasks)
 	{
+        (void) numTasks;
 	}
 
Index: code/branches/physics/src/bullet/BulletDynamics/Dynamics/btDynamicsWorld.h
===================================================================
--- code/branches/physics/src/bullet/BulletDynamics/Dynamics/btDynamicsWorld.h	(revision 2192)
+++ code/branches/physics/src/bullet/BulletDynamics/Dynamics/btDynamicsWorld.h	(revision 2430)
@@ -24,4 +24,5 @@
 class btConstraintSolver;
 class btDynamicsWorld;
+class btCharacterControllerInterface;
 
 /// Type for the callback for each tick
@@ -76,8 +77,15 @@
 		virtual void	removeVehicle(btRaycastVehicle* vehicle) {(void)vehicle;}
 
+		virtual void	addCharacter(btCharacterControllerInterface* character) {(void)character;}
+
+		virtual void	removeCharacter(btCharacterControllerInterface* character) {(void)character;}
+
+
 		//once a rigidbody is added to the dynamics world, it will get this gravity assigned
 		//existing rigidbodies in the world get gravity assigned too, during this method
 		virtual void	setGravity(const btVector3& gravity) = 0;
 		virtual btVector3 getGravity () const = 0;
+
+		virtual void	synchronizeMotionStates() = 0;
 
 		virtual void	addRigidBody(btRigidBody* body) = 0;
Index: code/branches/physics/src/bullet/BulletDynamics/Dynamics/btRigidBody.h
===================================================================
--- code/branches/physics/src/bullet/BulletDynamics/Dynamics/btRigidBody.h	(revision 2192)
+++ code/branches/physics/src/bullet/BulletDynamics/Dynamics/btRigidBody.h	(revision 2430)
@@ -18,5 +18,4 @@
 
 #include "LinearMath/btAlignedObjectArray.h"
-#include "LinearMath/btPoint3.h"
 #include "LinearMath/btTransform.h"
 #include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
@@ -32,5 +31,5 @@
 
 
-///btRigidBody is the main class for rigid body objects. It is derived from btCollisionObject, so it keeps a pointer to a btCollisionShape.
+///The btRigidBody is the main class for rigid body objects. It is derived from btCollisionObject, so it keeps a pointer to a btCollisionShape.
 ///It is recommended for performance and memory use to share btCollisionShape objects whenever possible.
 ///There are 3 types of rigid bodies: 
@@ -76,5 +75,5 @@
 
 
-	///btRigidBodyConstructionInfo provides information to create a rigid body. Setting mass to zero creates a fixed (non-dynamic) rigid body.
+	///The btRigidBodyConstructionInfo structure provides information to create a rigid body. Setting mass to zero creates a fixed (non-dynamic) rigid body.
 	///For dynamic objects, you can use the collision shape to approximate the local inertia tensor, otherwise use the zero vector (default argument)
 	///You can use the motion state to synchronize the world transform between physics and graphics objects. 
@@ -304,5 +303,5 @@
 	void updateInertiaTensor();    
 	
-	const btPoint3&     getCenterOfMassPosition() const { 
+	const btVector3&     getCenterOfMassPosition() const { 
 		return m_worldTransform.getOrigin(); 
 	}
@@ -322,13 +321,10 @@
 	inline void setLinearVelocity(const btVector3& lin_vel)
 	{ 
-		assert (m_collisionFlags != btCollisionObject::CF_STATIC_OBJECT);
 		m_linearVelocity = lin_vel; 
 	}
 
-	inline void setAngularVelocity(const btVector3& ang_vel) { 
-		assert (m_collisionFlags != btCollisionObject::CF_STATIC_OBJECT);
-		{
-			m_angularVelocity = ang_vel; 
-		}
+	inline void setAngularVelocity(const btVector3& ang_vel) 
+	{ 
+		m_angularVelocity = ang_vel; 
 	}
 
@@ -354,5 +350,5 @@
 
 	
-	SIMD_FORCE_INLINE btScalar computeImpulseDenominator(const btPoint3& pos, const btVector3& normal) const
+	SIMD_FORCE_INLINE btScalar computeImpulseDenominator(const btVector3& pos, const btVector3& normal) const
 	{
 		btVector3 r0 = pos - getCenterOfMassPosition();
Index: code/branches/physics/src/bullet/BulletDynamics/Dynamics/btSimpleDynamicsWorld.cpp
===================================================================
--- code/branches/physics/src/bullet/BulletDynamics/Dynamics/btSimpleDynamicsWorld.cpp	(revision 2192)
+++ code/branches/physics/src/bullet/BulletDynamics/Dynamics/btSimpleDynamicsWorld.cpp	(revision 2430)
@@ -98,5 +98,5 @@
 void	btSimpleDynamicsWorld::clearForces()
 {
-	//todo: iterate over awake simulation islands!
+	///@todo: iterate over awake simulation islands!
 	for ( int i=0;i<m_collisionObjects.size();i++)
 	{
@@ -157,5 +157,5 @@
 			if (body->isActive() && (!body->isStaticObject()))
 			{
-				btPoint3 minAabb,maxAabb;
+				btVector3 minAabb,maxAabb;
 				colObj->getCollisionShape()->getAabb(colObj->getWorldTransform(), minAabb,maxAabb);
 				btBroadphaseInterface* bp = getBroadphase();
@@ -211,5 +211,5 @@
 void	btSimpleDynamicsWorld::synchronizeMotionStates()
 {
-	//todo: iterate over awake simulation islands!
+	///@todo: iterate over awake simulation islands!
 	for ( int i=0;i<m_collisionObjects.size();i++)
 	{
Index: code/branches/physics/src/bullet/BulletDynamics/Dynamics/btSimpleDynamicsWorld.h
===================================================================
--- code/branches/physics/src/bullet/BulletDynamics/Dynamics/btSimpleDynamicsWorld.h	(revision 2192)
+++ code/branches/physics/src/bullet/BulletDynamics/Dynamics/btSimpleDynamicsWorld.h	(revision 2430)
@@ -23,5 +23,5 @@
 class btConstraintSolver;
 
-///btSimpleDynamicsWorld serves as unit-test and to verify more complicated and optimized dynamics worlds.
+///The btSimpleDynamicsWorld serves as unit-test and to verify more complicated and optimized dynamics worlds.
 ///Please use btDiscreteDynamicsWorld instead (or btContinuousDynamicsWorld once it is finished).
 class btSimpleDynamicsWorld : public btDynamicsWorld
@@ -61,5 +61,5 @@
 	virtual void	updateAabbs();
 
-	void	synchronizeMotionStates();
+	virtual void	synchronizeMotionStates();
 
 	virtual void	setConstraintSolver(btConstraintSolver* solver);
Index: code/branches/physics/src/bullet/BulletDynamics/Vehicle/btRaycastVehicle.cpp
===================================================================
--- code/branches/physics/src/bullet/BulletDynamics/Vehicle/btRaycastVehicle.cpp	(revision 2192)
+++ code/branches/physics/src/bullet/BulletDynamics/Vehicle/btRaycastVehicle.cpp	(revision 2430)
@@ -189,5 +189,5 @@
 		wheel.m_raycastInfo.m_isInContact = true;
 		
-		wheel.m_raycastInfo.m_groundObject = &s_fixedObject;//todo for driving on dynamic/movable objects!;
+		wheel.m_raycastInfo.m_groundObject = &s_fixedObject;///@todo for driving on dynamic/movable objects!;
 		//wheel.m_raycastInfo.m_groundObject = object;
 
@@ -692,5 +692,5 @@
 					btVector3 sideImp = m_axle[wheel] * m_sideImpulse[wheel];
 
-					rel_pos[2] *= wheelInfo.m_rollInfluence;
+					rel_pos[m_indexForwardAxis] *= wheelInfo.m_rollInfluence;
 					m_chassisBody->applyImpulse(sideImp,rel_pos);
 
Index: code/branches/physics/src/bullet/CMakeLists.txt
===================================================================
--- code/branches/physics/src/bullet/CMakeLists.txt	(revision 2192)
+++ code/branches/physics/src/bullet/CMakeLists.txt	(revision 2430)
@@ -1,3 +1,2 @@
-ADD_SUBDIRECTORY(BulletSoftBody)
 ADD_SUBDIRECTORY(BulletCollision)
 ADD_SUBDIRECTORY(BulletDynamics)
Index: code/branches/physics/src/bullet/ChangeLog
===================================================================
--- code/branches/physics/src/bullet/ChangeLog	(revision 2192)
+++ code/branches/physics/src/bullet/ChangeLog	(revision 2430)
@@ -4,4 +4,46 @@
 Todo: update changelog from April - July 2008
 See http://code.google.com/p/bullet/source/list for more complete log in Subversion
+
+2008 November 12
+	- Add compound shape export to BulletColladaConverter
+	Thanks to JamesH for the report: http://www.bulletphysics.com/Bullet/phpBB3/viewtopic.php?f=12&t=2840
+	- Fix compiler build for Visual Studio 6
+	Thanks to JoF for the report: http://www.bulletphysics.com/Bullet/phpBB3/viewtopic.php?f=9&t=2841
+
+2008 November 11
+	- Add CProfileManager::dumpAll() to dump performance statistics to console using printf.
+	- Add support for interaction between btSoftBody and btCollisionObject/btGhostObject
+
+2008 November 8
+	- Fix PosixThreadSupport
+	- Add improved btHeightfieldTerrainShape support and new Demos/TerrainDemo
+	Thanks to tomva, http://code.google.com/p/bullet/issues/detail?id=63&can=1
+	- Moved kinematic character controller from Demos/CharacterDemo into src/BulletDynamics/Character/btKinematicCharacterController.cpp
+
+2008 November 6
+	- reduced default memory pool allocation from 40Mb to 3Mb. This should be more suitable for all platforms, including iPhone
+	- improved CUDA broadphase
+	- IBM Cell SDK 3.x support, fix ibmsdk Makefiles
+	- improved CMake support with 'install' and 'framework option
+	
+2008 November 4
+	- add btAxisSweep::resetPool to avoid non-determinism due to shuffled linked list
+	Thanks to Ole for the contribution, 
+
+2008 October 30
+	- disabled btTriangleMesh duplicate search by default, it is extremely slow
+	- added Extras/IFF binary chunk serialization library as preparation for in-game native platform serialization (planned COLLADA DOM -> IFF converter)
+
+2008 October 20
+	- added SCE Physics Effects box-box collision detection for SPU/BulletMultiThreaded version
+	See Bullet/src/BulletMultiThreaded/SpuNarrowPhaseCollisionTask/boxBoxDistance.cpp
+	Thanks to Sony Computer Entertainment Japan, SCEI for the contribution
+
+2008 October 17
+	- Added btGhostObject support, this helps character controller, explosions, triggers and other local spatial queries
+
+2008 October 10
+	- Moved aabb to btBroadphaseProxy, improves rayTest dramatically. Further raytest improvements using the broadphase acceleration structures are planned
+	- Moved BulletMultiThreaded from Extras to /src/BulletMultiThreaded for better integration
 
 
Index: code/branches/physics/src/bullet/LinearMath/CMakeLists.txt
===================================================================
--- code/branches/physics/src/bullet/LinearMath/CMakeLists.txt	(revision 2192)
+++ code/branches/physics/src/bullet/LinearMath/CMakeLists.txt	(revision 2430)
@@ -1,27 +1,4 @@
-ADD_LIBRARY(LibLinearMath
-		btAlignedObjectArray.h
-		btList.h
-		btPoolAllocator.h
-		btRandom.h
-		btVector3.h
-		btDefaultMotionState.h
-		btMatrix3x3.h
-		btQuadWord.h
-		btHashMap.h
-		btScalar.h
-		btAabbUtil2.h
-		btConvexHull.h
+SET(LinearMath_SRCS
 		btConvexHull.cpp
-		btMinMax.h
-		btQuaternion.h
-		btStackAlloc.h
-		btGeometryUtil.h
-		btMotionState.h
-		btTransform.h
-		btAlignedAllocator.h
-		btIDebugDraw.h
-		btPoint3.h
-		btQuickprof.h
-		btTransformUtil.h
 		btQuickprof.cpp
 		btGeometryUtil.cpp
@@ -29,2 +6,3 @@
 )
 
+ADD_LIBRARY(LinearMath ${LinearMath_SRCS})
Index: code/branches/physics/src/bullet/LinearMath/btAabbUtil2.h
===================================================================
--- code/branches/physics/src/bullet/LinearMath/btAabbUtil2.h	(revision 2192)
+++ code/branches/physics/src/bullet/LinearMath/btAabbUtil2.h	(revision 2430)
@@ -22,4 +22,6 @@
 #include "btMinMax.h"
 
+
+
 SIMD_FORCE_INLINE void AabbExpand (btVector3& aabbMin,
 								   btVector3& aabbMax,
@@ -31,4 +33,15 @@
 }
 
+/// conservative test for overlap between two aabbs
+SIMD_FORCE_INLINE bool TestPointAgainstAabb2(const btVector3 &aabbMin1, const btVector3 &aabbMax1,
+								const btVector3 &point)
+{
+	bool overlap = true;
+	overlap = (aabbMin1.getX() > point.getX() || aabbMax1.getX() < point.getX()) ? false : overlap;
+	overlap = (aabbMin1.getZ() > point.getZ() || aabbMax1.getZ() < point.getZ()) ? false : overlap;
+	overlap = (aabbMin1.getY() > point.getY() || aabbMax1.getY() < point.getY()) ? false : overlap;
+	return overlap;
+}
+
 
 /// conservative test for overlap between two aabbs
@@ -37,7 +50,7 @@
 {
 	bool overlap = true;
-	overlap = (aabbMin1[0] > aabbMax2[0] || aabbMax1[0] < aabbMin2[0]) ? false : overlap;
-	overlap = (aabbMin1[2] > aabbMax2[2] || aabbMax1[2] < aabbMin2[2]) ? false : overlap;
-	overlap = (aabbMin1[1] > aabbMax2[1] || aabbMax1[1] < aabbMin2[1]) ? false : overlap;
+	overlap = (aabbMin1.getX() > aabbMax2.getX() || aabbMax1.getX() < aabbMin2.getX()) ? false : overlap;
+	overlap = (aabbMin1.getZ() > aabbMax2.getZ() || aabbMax1.getZ() < aabbMin2.getZ()) ? false : overlap;
+	overlap = (aabbMin1.getY() > aabbMax2.getY() || aabbMax1.getY() < aabbMin2.getY()) ? false : overlap;
 	return overlap;
 }
@@ -72,4 +85,5 @@
 		   (p.getZ() >  halfExtent.getZ() ? 0x20 : 0x0);
 }
+
 
 
@@ -83,8 +97,8 @@
 {
 	btScalar tmax, tymin, tymax, tzmin, tzmax;
-	tmin = (bounds[raySign[0]][0] - rayFrom[0]) * rayInvDirection[0];
-	tmax = (bounds[1-raySign[0]][0] - rayFrom[0]) * rayInvDirection[0];
-	tymin = (bounds[raySign[1]][1] - rayFrom[1]) * rayInvDirection[1];
-	tymax = (bounds[1-raySign[1]][1] - rayFrom[1]) * rayInvDirection[1];
+	tmin = (bounds[raySign[0]].getX() - rayFrom.getX()) * rayInvDirection.getX();
+	tmax = (bounds[1-raySign[0]].getX() - rayFrom.getX()) * rayInvDirection.getX();
+	tymin = (bounds[raySign[1]].getY() - rayFrom.getY()) * rayInvDirection.getY();
+	tymax = (bounds[1-raySign[1]].getY() - rayFrom.getY()) * rayInvDirection.getY();
 
 	if ( (tmin > tymax) || (tymin > tmax) )
@@ -97,6 +111,6 @@
 		tmax = tymax;
 
-	tzmin = (bounds[raySign[2]][2] - rayFrom[2]) * rayInvDirection[2];
-	tzmax = (bounds[1-raySign[2]][2] - rayFrom[2]) * rayInvDirection[2];
+	tzmin = (bounds[raySign[2]].getZ() - rayFrom.getZ()) * rayInvDirection.getZ();
+	tzmax = (bounds[1-raySign[2]].getZ() - rayFrom.getZ()) * rayInvDirection.getZ();
 
 	if ( (tmin > tzmax) || (tzmin > tmax) )
@@ -197,4 +211,24 @@
 }
 
+#define USE_BANCHLESS 1
+#ifdef USE_BANCHLESS
+	//This block replaces the block below and uses no branches, and replaces the 8 bit return with a 32 bit return for improved performance (~3x on XBox 360)
+	SIMD_FORCE_INLINE unsigned testQuantizedAabbAgainstQuantizedAabb(const unsigned short int* aabbMin1,const unsigned short int* aabbMax1,const unsigned short int* aabbMin2,const unsigned short int* aabbMax2)
+	{		
+		return static_cast<unsigned int>(btSelect((unsigned)((aabbMin1[0] <= aabbMax2[0]) & (aabbMax1[0] >= aabbMin2[0])
+			& (aabbMin1[2] <= aabbMax2[2]) & (aabbMax1[2] >= aabbMin2[2])
+			& (aabbMin1[1] <= aabbMax2[1]) & (aabbMax1[1] >= aabbMin2[1])),
+			1, 0));
+	}
+#else
+	SIMD_FORCE_INLINE bool testQuantizedAabbAgainstQuantizedAabb(const unsigned short int* aabbMin1,const unsigned short int* aabbMax1,const unsigned short int* aabbMin2,const unsigned short int* aabbMax2)
+	{
+		bool overlap = true;
+		overlap = (aabbMin1[0] > aabbMax2[0] || aabbMax1[0] < aabbMin2[0]) ? false : overlap;
+		overlap = (aabbMin1[2] > aabbMax2[2] || aabbMax1[2] < aabbMin2[2]) ? false : overlap;
+		overlap = (aabbMin1[1] > aabbMax2[1] || aabbMax1[1] < aabbMin2[1]) ? false : overlap;
+		return overlap;
+	}
+#endif //USE_BANCHLESS
 
 #endif
Index: code/branches/physics/src/bullet/LinearMath/btConvexHull.cpp
===================================================================
--- code/branches/physics/src/bullet/LinearMath/btConvexHull.cpp	(revision 2192)
+++ code/branches/physics/src/bullet/LinearMath/btConvexHull.cpp	(revision 2430)
@@ -343,9 +343,9 @@
 }
 
-class Tri;
-
-
-
-class Tri : public int3
+class btHullTriangle;
+
+
+
+class btHullTriangle : public int3
 {
 public:
@@ -354,10 +354,10 @@
 	int vmax;
 	btScalar rise;
-	Tri(int a,int b,int c):int3(a,b,c),n(-1,-1,-1)
+	btHullTriangle(int a,int b,int c):int3(a,b,c),n(-1,-1,-1)
 	{
 		vmax=-1;
 		rise = btScalar(0.0);
 	}
-	~Tri()
+	~btHullTriangle()
 	{
 	}
@@ -366,5 +366,5 @@
 
 
-int &Tri::neib(int a,int b)
+int &btHullTriangle::neib(int a,int b)
 {
 	static int er=-1;
@@ -380,5 +380,5 @@
 	return er;
 }
-void HullLibrary::b2bfix(Tri* s,Tri*t)
+void HullLibrary::b2bfix(btHullTriangle* s,btHullTriangle*t)
 {
 	int i;
@@ -396,5 +396,5 @@
 }
 
-void HullLibrary::removeb2b(Tri* s,Tri*t)
+void HullLibrary::removeb2b(btHullTriangle* s,btHullTriangle*t)
 {
 	b2bfix(s,t);
@@ -404,5 +404,5 @@
 }
 
-void HullLibrary::checkit(Tri *t)
+void HullLibrary::checkit(btHullTriangle *t)
 {
 	(void)t;
@@ -428,8 +428,8 @@
 }
 
-Tri*	HullLibrary::allocateTriangle(int a,int b,int c)
-{
-	void* mem = btAlignedAlloc(sizeof(Tri),16);
-	Tri* tr = new (mem)Tri(a,b,c);
+btHullTriangle*	HullLibrary::allocateTriangle(int a,int b,int c)
+{
+	void* mem = btAlignedAlloc(sizeof(btHullTriangle),16);
+	btHullTriangle* tr = new (mem)btHullTriangle(a,b,c);
 	tr->id = m_tris.size();
 	m_tris.push_back(tr);
@@ -438,24 +438,24 @@
 }
 
-void	HullLibrary::deAllocateTriangle(Tri* tri)
+void	HullLibrary::deAllocateTriangle(btHullTriangle* tri)
 {
 	btAssert(m_tris[tri->id]==tri);
 	m_tris[tri->id]=NULL;
-	tri->~Tri();
+	tri->~btHullTriangle();
 	btAlignedFree(tri);
 }
 
 
-void HullLibrary::extrude(Tri *t0,int v)
+void HullLibrary::extrude(btHullTriangle *t0,int v)
 {
 	int3 t= *t0;
 	int n = m_tris.size();
-	Tri* ta = allocateTriangle(v,t[1],t[2]);
+	btHullTriangle* ta = allocateTriangle(v,t[1],t[2]);
 	ta->n = int3(t0->n[0],n+1,n+2);
 	m_tris[t0->n[0]]->neib(t[1],t[2]) = n+0;
-	Tri* tb = allocateTriangle(v,t[2],t[0]);
+	btHullTriangle* tb = allocateTriangle(v,t[2],t[0]);
 	tb->n = int3(t0->n[1],n+2,n+0);
 	m_tris[t0->n[1]]->neib(t[2],t[0]) = n+1;
-	Tri* tc = allocateTriangle(v,t[0],t[1]);
+	btHullTriangle* tc = allocateTriangle(v,t[0],t[1]);
 	tc->n = int3(t0->n[2],n+0,n+1);
 	m_tris[t0->n[2]]->neib(t[0],t[1]) = n+2;
@@ -470,8 +470,8 @@
 }
 
-Tri* HullLibrary::extrudable(btScalar epsilon)
+btHullTriangle* HullLibrary::extrudable(btScalar epsilon)
 {
 	int i;
-	Tri *t=NULL;
+	btHullTriangle *t=NULL;
 	for(i=0;i<m_tris.size();i++)
 	{
@@ -551,8 +551,8 @@
 
 	btVector3 center = (verts[p[0]]+verts[p[1]]+verts[p[2]]+verts[p[3]]) / btScalar(4.0);  // a valid interior point
-	Tri *t0 = allocateTriangle(p[2],p[3],p[1]); t0->n=int3(2,3,1);
-	Tri *t1 = allocateTriangle(p[3],p[2],p[0]); t1->n=int3(3,2,0);
-	Tri *t2 = allocateTriangle(p[0],p[1],p[3]); t2->n=int3(0,1,3);
-	Tri *t3 = allocateTriangle(p[1],p[0],p[2]); t3->n=int3(1,0,2);
+	btHullTriangle *t0 = allocateTriangle(p[2],p[3],p[1]); t0->n=int3(2,3,1);
+	btHullTriangle *t1 = allocateTriangle(p[3],p[2],p[0]); t1->n=int3(3,2,0);
+	btHullTriangle *t2 = allocateTriangle(p[0],p[1],p[3]); t2->n=int3(0,1,3);
+	btHullTriangle *t3 = allocateTriangle(p[1],p[0],p[2]); t3->n=int3(1,0,2);
 	isextreme[p[0]]=isextreme[p[1]]=isextreme[p[2]]=isextreme[p[3]]=1;
 	checkit(t0);checkit(t1);checkit(t2);checkit(t3);
@@ -560,5 +560,5 @@
 	for(j=0;j<m_tris.size();j++)
 	{
-		Tri *t=m_tris[j];
+		btHullTriangle *t=m_tris[j];
 		btAssert(t);
 		btAssert(t->vmax<0);
@@ -567,5 +567,5 @@
 		t->rise = dot(n,verts[t->vmax]-verts[(*t)[0]]);
 	}
-	Tri *te;
+	btHullTriangle *te;
 	vlimit-=4;
 	while(vlimit >0 && ((te=extrudable(epsilon)) != 0))
@@ -595,5 +595,5 @@
 			if(above(verts,nt,center,btScalar(0.01)*epsilon)  || cross(verts[nt[1]]-verts[nt[0]],verts[nt[2]]-verts[nt[1]]).length()< epsilon*epsilon*btScalar(0.1) )
 			{
-				Tri *nb = m_tris[m_tris[j]->n[0]];
+				btHullTriangle *nb = m_tris[m_tris[j]->n[0]];
 				btAssert(nb);btAssert(!hasvert(*nb,v));btAssert(nb->id<j);
 				extrude(nb,v);
@@ -604,5 +604,5 @@
 		while(j--)
 		{
-			Tri *t=m_tris[j];
+			btHullTriangle *t=m_tris[j];
 			if(!t) continue;
 			if(t->vmax>=0) break;
Index: code/branches/physics/src/bullet/LinearMath/btConvexHull.h
===================================================================
--- code/branches/physics/src/bullet/LinearMath/btConvexHull.h	(revision 2192)
+++ code/branches/physics/src/bullet/LinearMath/btConvexHull.h	(revision 2430)
@@ -138,11 +138,7 @@
 	ConvexH()
 	{
-		int i;
-		i=0;
 	}
 	~ConvexH()
 	{
-		int i;
-		i=0;
 	}
 	btAlignedObjectArray<btVector3> vertices;
@@ -189,5 +185,5 @@
 {
 
-	btAlignedObjectArray<class Tri*> m_tris;
+	btAlignedObjectArray<class btHullTriangle*> m_tris;
 
 public:
@@ -204,13 +200,13 @@
 	bool ComputeHull(unsigned int vcount,const btVector3 *vertices,PHullResult &result,unsigned int vlimit);
 
-	class Tri*	allocateTriangle(int a,int b,int c);
-	void	deAllocateTriangle(Tri*);
-	void b2bfix(Tri* s,Tri*t);
-
-	void removeb2b(Tri* s,Tri*t);
-
-	void checkit(Tri *t);
-
-	Tri* extrudable(btScalar epsilon);
+	class btHullTriangle*	allocateTriangle(int a,int b,int c);
+	void	deAllocateTriangle(btHullTriangle*);
+	void b2bfix(btHullTriangle* s,btHullTriangle*t);
+
+	void removeb2b(btHullTriangle* s,btHullTriangle*t);
+
+	void checkit(btHullTriangle *t);
+
+	btHullTriangle* extrudable(btScalar epsilon);
 
 	int calchull(btVector3 *verts,int verts_count, TUIntArray& tris_out, int &tris_count,int vlimit);
@@ -222,5 +218,5 @@
 	class ConvexH* ConvexHCrop(ConvexH& convex,const btPlane& slice);
 
-	void extrude(class Tri* t0,int v);
+	void extrude(class btHullTriangle* t0,int v);
 
 	ConvexH* test_cube();
Index: code/branches/physics/src/bullet/LinearMath/btMatrix3x3.h
===================================================================
--- code/branches/physics/src/bullet/LinearMath/btMatrix3x3.h	(revision 2192)
+++ code/branches/physics/src/bullet/LinearMath/btMatrix3x3.h	(revision 2430)
@@ -24,12 +24,14 @@
 
 
-///The btMatrix3x3 class implements a 3x3 rotation matrix, to perform linear algebra in combination with btQuaternion, btTransform and btVector3.
-///Make sure to only include a pure orthogonal matrix without scaling.
+/**@brief The btMatrix3x3 class implements a 3x3 rotation matrix, to perform linear algebra in combination with btQuaternion, btTransform and btVector3.
+ * Make sure to only include a pure orthogonal matrix without scaling. */
 class btMatrix3x3 {
 	public:
+  /** @brief No initializaion constructor */
 		btMatrix3x3 () {}
 		
 //		explicit btMatrix3x3(const btScalar *m) { setFromOpenGLSubMatrix(m); }
 		
+  /**@brief Constructor from Quaternion */
 		explicit btMatrix3x3(const btQuaternion& q) { setRotation(q); }
 		/*
@@ -40,4 +42,5 @@
 		}
 		*/
+  /** @brief Constructor with row major formatting */
 		btMatrix3x3(const btScalar& xx, const btScalar& xy, const btScalar& xz,
 				  const btScalar& yx, const btScalar& yy, const btScalar& yz,
@@ -48,5 +51,5 @@
 					 zx, zy, zz);
 		}
-		
+  /** @brief Copy constructor */
 		SIMD_FORCE_INLINE btMatrix3x3 (const btMatrix3x3& other)
 		{
@@ -55,5 +58,5 @@
 			m_el[2] = other.m_el[2];
 		}
-
+  /** @brief Assignment Operator */
 		SIMD_FORCE_INLINE btMatrix3x3& operator=(const btMatrix3x3& other)
 		{
@@ -64,4 +67,6 @@
 		}
 
+  /** @brief Get a column of the matrix as a vector 
+   *  @param i Column number 0 indexed */
 		SIMD_FORCE_INLINE btVector3 getColumn(int i) const
 		{
@@ -70,11 +75,14 @@
 		
 
-
+  /** @brief Get a row of the matrix as a vector 
+   *  @param i Row number 0 indexed */
 		SIMD_FORCE_INLINE const btVector3& getRow(int i) const
 		{
+			btFullAssert(0 <= i && i < 3);
 			return m_el[i];
 		}
 
-
+  /** @brief Get a mutable reference to a row of the matrix as a vector 
+   *  @param i Row number 0 indexed */
 		SIMD_FORCE_INLINE btVector3&  operator[](int i)
 		{ 
@@ -83,4 +91,6 @@
 		}
 		
+  /** @brief Get a const reference to a row of the matrix as a vector 
+   *  @param i Row number 0 indexed */
 		SIMD_FORCE_INLINE const btVector3& operator[](int i) const
 		{
@@ -89,7 +99,11 @@
 		}
 		
+  /** @brief Multiply by the target matrix on the right
+   *  @param m Rotation matrix to be applied 
+   * Equivilant to this = this * m */
 		btMatrix3x3& operator*=(const btMatrix3x3& m); 
 		
-	
+  /** @brief Set from a carray of btScalars 
+   *  @param m A pointer to the beginning of an array of 9 btScalars */
 	void setFromOpenGLSubMatrix(const btScalar *m)
 		{
@@ -99,5 +113,14 @@
 
 		}
-
+  /** @brief Set the values of the matrix explicitly (row major)
+   *  @param xx Top left
+   *  @param xy Top Middle
+   *  @param xz Top Right
+   *  @param yx Middle Left
+   *  @param yy Middle Middle
+   *  @param yz Middle Right
+   *  @param zx Bottom Left
+   *  @param zy Bottom Middle
+   *  @param zz Bottom Right*/
 		void setValue(const btScalar& xx, const btScalar& xy, const btScalar& xz, 
 					  const btScalar& yx, const btScalar& yy, const btScalar& yz, 
@@ -108,5 +131,7 @@
 			m_el[2].setValue(zx,zy,zz);
 		}
-  
+
+  /** @brief Set the matrix from a quaternion
+   *  @param q The Quaternion to match */  
 		void setRotation(const btQuaternion& q) 
 		{
@@ -124,33 +149,25 @@
 		
 
-
+  /** @brief Set the matrix from euler angles using YPR around YXZ respectively
+   *  @param yaw Yaw about Y axis
+   *  @param pitch Pitch about X axis
+   *  @param roll Roll about Z axis 
+   */
 		void setEulerYPR(const btScalar& yaw, const btScalar& pitch, const btScalar& roll) 
 		{
-
-			btScalar cy(btCos(yaw)); 
-			btScalar  sy(btSin(yaw)); 
-			btScalar  cp(btCos(pitch)); 
-			btScalar  sp(btSin(pitch)); 
-			btScalar  cr(btCos(roll));
-			btScalar  sr(btSin(roll));
-			btScalar  cc = cy * cr; 
-			btScalar  cs = cy * sr; 
-			btScalar  sc = sy * cr; 
-			btScalar  ss = sy * sr;
-			setValue(cc - sp * ss, -cs - sp * sc, -sy * cp,
-                     cp * sr,       cp * cr,      -sp,
-					 sc + sp * cs, -ss + sp * cc,  cy * cp);
-		
-		}
-
-	/**
-	 * setEulerZYX
-	 * @param euler a const reference to a btVector3 of euler angles
+			setEulerZYX(roll, pitch, yaw);
+		}
+
+	/** @brief Set the matrix from euler angles YPR around ZYX axes
+	 * @param eulerX Roll about X axis
+         * @param eulerY Pitch around Y axis
+         * @param eulerZ Yaw aboud Z axis
+         * 
 	 * These angles are used to produce a rotation matrix. The euler
 	 * angles are applied in ZYX order. I.e a vector is first rotated 
 	 * about X then Y and then Z
 	 **/
-	
-	void setEulerZYX(btScalar eulerX,btScalar eulerY,btScalar eulerZ) {
+	void setEulerZYX(btScalar eulerX,btScalar eulerY,btScalar eulerZ) { 
+  ///@todo proposed to reverse this since it's labeled zyx but takes arguments xyz and it will match all other parts of the code
 		btScalar ci ( btCos(eulerX)); 
 		btScalar cj ( btCos(eulerY)); 
@@ -169,4 +186,5 @@
 	}
 
+  /**@brief Set the matrix to the identity */
 		void setIdentity()
 		{ 
@@ -175,5 +193,6 @@
 					 btScalar(0.0), btScalar(0.0), btScalar(1.0)); 
 		}
-    
+  /**@brief Fill the values of the matrix into a 9 element array 
+   * @param m The array to be filled */
 		void getOpenGLSubMatrix(btScalar *m) const 
 		{
@@ -192,4 +211,6 @@
 		}
 
+  /**@brief Get the matrix represented as a quaternion 
+   * @param q The quaternion which will be set */
 		void getRotation(btQuaternion& q) const
 		{
@@ -225,33 +246,100 @@
 			q.setValue(temp[0],temp[1],temp[2],temp[3]);
 		}
-	
-		void getEuler(btScalar& yaw, btScalar& pitch, btScalar& roll) const
+
+  /**@brief Get the matrix represented as euler angles around YXZ, roundtrip with setEulerYPR
+   * @param yaw Yaw around Y axis
+   * @param pitch Pitch around X axis
+   * @param roll around Z axis */	
+		void getEulerYPR(btScalar& yaw, btScalar& pitch, btScalar& roll) const
 		{
 			
-			if (btScalar(m_el[1].z()) < btScalar(1))
-			{
-				if (btScalar(m_el[1].z()) > -btScalar(1))
-				{
-					yaw = btScalar(btAtan2(m_el[1].x(), m_el[0].x()));
-					pitch = btScalar(btAsin(-m_el[1].y()));
-					roll = btScalar(btAtan2(m_el[2].y(), m_el[2].z()));
-				}
-				else 
-				{
-					yaw = btScalar(-btAtan2(-m_el[0].y(), m_el[0].z()));
-					pitch = SIMD_HALF_PI;
-					roll = btScalar(0.0);
-				}
-			}
-			else
-			{
-				yaw = btScalar(btAtan2(-m_el[0].y(), m_el[0].z()));
-				pitch = -SIMD_HALF_PI;
-				roll = btScalar(0.0);
-			}
-		}
-		
-
-	
+			// first use the normal calculus
+			yaw = btScalar(btAtan2(m_el[1].x(), m_el[0].x()));
+			pitch = btScalar(btAsin(-m_el[2].x()));
+			roll = btScalar(btAtan2(m_el[2].y(), m_el[2].z()));
+
+			// on pitch = +/-HalfPI
+			if (btFabs(pitch)==SIMD_HALF_PI)
+			{
+				if (yaw>0)
+					yaw-=SIMD_PI;
+				else
+					yaw+=SIMD_PI;
+
+				if (roll>0)
+					roll-=SIMD_PI;
+				else
+					roll+=SIMD_PI;
+			}
+		};
+
+
+  /**@brief Get the matrix represented as euler angles around ZYX
+   * @param yaw Yaw around X axis
+   * @param pitch Pitch around Y axis
+   * @param roll around X axis 
+   * @param solution_number Which solution of two possible solutions ( 1 or 2) are possible values*/	
+  void getEulerZYX(btScalar& yaw, btScalar& pitch, btScalar& roll, unsigned int solution_number = 1) const
+  {
+    struct Euler{btScalar yaw, pitch, roll;};
+    Euler euler_out;
+    Euler euler_out2; //second solution
+    //get the pointer to the raw data
+    
+    // Check that pitch is not at a singularity
+    if (btFabs(m_el[2].x()) >= 1)
+    {
+      euler_out.yaw = 0;
+      euler_out2.yaw = 0;
+	
+      // From difference of angles formula
+      btScalar delta = btAtan2(m_el[0].x(),m_el[0].z());
+      if (m_el[2].x() > 0)  //gimbal locked up
+      {
+        euler_out.pitch = SIMD_PI / btScalar(2.0);
+        euler_out2.pitch = SIMD_PI / btScalar(2.0);
+        euler_out.roll = euler_out.pitch + delta;
+        euler_out2.roll = euler_out.pitch + delta;
+      }
+      else // gimbal locked down
+      {
+        euler_out.pitch = -SIMD_PI / btScalar(2.0);
+        euler_out2.pitch = -SIMD_PI / btScalar(2.0);
+        euler_out.roll = -euler_out.pitch + delta;
+        euler_out2.roll = -euler_out.pitch + delta;
+      }
+    }
+    else
+    {
+      euler_out.pitch = - btAsin(m_el[2].x());
+      euler_out2.pitch = SIMD_PI - euler_out.pitch;
+	
+      euler_out.roll = btAtan2(m_el[2].y()/btCos(euler_out.pitch), 
+			       m_el[2].z()/btCos(euler_out.pitch));
+      euler_out2.roll = btAtan2(m_el[2].y()/btCos(euler_out2.pitch), 
+				m_el[2].z()/btCos(euler_out2.pitch));
+	
+      euler_out.yaw = btAtan2(m_el[1].x()/btCos(euler_out.pitch), 
+			      m_el[0].x()/btCos(euler_out.pitch));
+      euler_out2.yaw = btAtan2(m_el[1].x()/btCos(euler_out2.pitch), 
+                               m_el[0].x()/btCos(euler_out2.pitch));
+    }
+    
+    if (solution_number == 1)
+    { 
+		yaw = euler_out.yaw; 
+		pitch = euler_out.pitch;
+		roll = euler_out.roll;
+    }
+    else
+    { 
+		yaw = euler_out2.yaw; 
+		pitch = euler_out2.pitch;
+		roll = euler_out2.roll;
+    }
+  }
+
+  /**@brief Create a scaled copy of the matrix 
+   * @param s Scaling vector The elements of the vector will scale each column */
 		
 		btMatrix3x3 scaled(const btVector3& s) const
@@ -262,8 +350,13 @@
 		}
 
+  /**@brief Return the determinant of the matrix */
 		btScalar            determinant() const;
+  /**@brief Return the adjoint of the matrix */
 		btMatrix3x3 adjoint() const;
+  /**@brief Return the matrix with all values non negative */
 		btMatrix3x3 absolute() const;
+  /**@brief Return the transpose of the matrix */
 		btMatrix3x3 transpose() const;
+  /**@brief Return the inverse of the matrix */
 		btMatrix3x3 inverse() const; 
 		
@@ -285,10 +378,13 @@
 		
 
-		///diagonalizes this matrix by the Jacobi method. rot stores the rotation
-		///from the coordinate system in which the matrix is diagonal to the original
-		///coordinate system, i.e., old_this = rot * new_this * rot^T. The iteration
-		///stops when all off-diagonal elements are less than the threshold multiplied
-		///by the sum of the absolute values of the diagonal, or when maxSteps have
-		///been executed. Note that this matrix is assumed to be symmetric.
+  /**@brief diagonalizes this matrix by the Jacobi method.
+   * @param rot stores the rotation from the coordinate system in which the matrix is diagonal to the original
+   * coordinate system, i.e., old_this = rot * new_this * rot^T. 
+   * @param threshold See iteration
+   * @param iteration The iteration stops when all off-diagonal elements are less than the threshold multiplied 
+   * by the sum of the absolute values of the diagonal, or when maxSteps have been executed. 
+   * 
+   * Note that this matrix is assumed to be symmetric. 
+   */
 		void diagonalize(btMatrix3x3& rot, btScalar threshold, int maxSteps)
 		{
@@ -372,9 +468,16 @@
 		
 	protected:
+  /**@brief Calculate the matrix cofactor 
+   * @param r1 The first row to use for calculating the cofactor
+   * @param c1 The first column to use for calculating the cofactor
+   * @param r1 The second row to use for calculating the cofactor
+   * @param c1 The second column to use for calculating the cofactor
+   * See http://en.wikipedia.org/wiki/Cofactor_(linear_algebra) for more details
+   */
 		btScalar cofac(int r1, int c1, int r2, int c2) const 
 		{
 			return m_el[r1][c1] * m_el[r2][c2] - m_el[r1][c2] * m_el[r2][c1];
 		}
-
+  ///Data storage for the matrix, each vector is a row of the matrix
 		btVector3 m_el[3];
 	};
@@ -495,4 +598,6 @@
 */
 
+/**@brief Equality operator between two matrices
+ * It will test all elements are equal.  */
 SIMD_FORCE_INLINE bool operator==(const btMatrix3x3& m1, const btMatrix3x3& m2)
 {
Index: code/branches/physics/src/bullet/LinearMath/btPoint3.h
===================================================================
--- code/branches/physics/src/bullet/LinearMath/btPoint3.h	(revision 2192)
+++ 	(revision )
@@ -1,24 +1,0 @@
-/*
-Copyright (c) 2003-2006 Gino van den Bergen / Erwin Coumans  http://continuousphysics.com/Bullet/
-
-This software is provided 'as-is', without any express or implied warranty.
-In no event will the authors be held liable for any damages arising from the use of this software.
-Permission is granted to anyone to use this software for any purpose, 
-including commercial applications, and to alter it and redistribute it freely, 
-subject to the following restrictions:
-
-1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
-2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
-3. This notice may not be removed or altered from any source distribution.
-*/
-
-
-
-#ifndef btPoint3_H
-#define btPoint3_H
-
-#include "btVector3.h"
-
-typedef btVector3 btPoint3;
-
-#endif
Index: code/branches/physics/src/bullet/LinearMath/btQuadWord.h
===================================================================
--- code/branches/physics/src/bullet/LinearMath/btQuadWord.h	(revision 2192)
+++ code/branches/physics/src/bullet/LinearMath/btQuadWord.h	(revision 2430)
@@ -19,119 +19,165 @@
 #include "btScalar.h"
 #include "btMinMax.h"
-#include <math.h>
 
 
+#if defined (__CELLOS_LV2) && defined (__SPU__)
+#include <altivec.h>
+#endif
 
-///The btQuadWordStorage class is base class for btVector3 and btQuaternion. 
-///Some issues under PS3 Linux with IBM 2.1 SDK, gcc compiler prevent from using aligned quadword. todo: look into this
-///ATTRIBUTE_ALIGNED16(class) btQuadWordStorage
+/**@brief The btQuadWordStorage class is base class for btVector3 and btQuaternion. 
+ * Some issues under PS3 Linux with IBM 2.1 SDK, gcc compiler prevent from using aligned quadword.
+ */
+#ifndef USE_LIBSPE2
+ATTRIBUTE_ALIGNED16(class) btQuadWordStorage
+#else
 class btQuadWordStorage
+#endif
 {
 protected:
 
-	btScalar	m_x;
-	btScalar	m_y;
-	btScalar	m_z;
-	btScalar	m_unusedW;
-
+#if defined (__SPU__) && defined (__CELLOS_LV2__)
+	union {
+		vec_float4 mVec128;
+		btScalar	m_floats[4];
+	};
 public:
+	vec_float4	get128() const
+	{
+		return mVec128;
+	}
+#else //__CELLOS_LV2__ __SPU__
+	btScalar	m_floats[4];
+#endif //__CELLOS_LV2__ __SPU__
 
 };
 
-
-///btQuadWord is base-class for vectors, points
+/** @brief The btQuadWord is base-class for vectors, points */
 class	btQuadWord : public btQuadWordStorage
 {
 	public:
-	
-//		SIMD_FORCE_INLINE btScalar&       operator[](int i)       { return (&m_x)[i];	}      
-//		SIMD_FORCE_INLINE const btScalar& operator[](int i) const { return (&m_x)[i]; }
+  
 
-		SIMD_FORCE_INLINE const btScalar& getX() const { return m_x; }
+  /**@brief Return the x value */
+		SIMD_FORCE_INLINE const btScalar& getX() const { return m_floats[0]; }
+  /**@brief Return the y value */
+		SIMD_FORCE_INLINE const btScalar& getY() const { return m_floats[1]; }
+  /**@brief Return the z value */
+		SIMD_FORCE_INLINE const btScalar& getZ() const { return m_floats[2]; }
+  /**@brief Set the x value */
+		SIMD_FORCE_INLINE void	setX(btScalar x) { m_floats[0] = x;};
+  /**@brief Set the y value */
+		SIMD_FORCE_INLINE void	setY(btScalar y) { m_floats[1] = y;};
+  /**@brief Set the z value */
+		SIMD_FORCE_INLINE void	setZ(btScalar z) { m_floats[2] = z;};
+  /**@brief Set the w value */
+		SIMD_FORCE_INLINE void	setW(btScalar w) { m_floats[3] = w;};
+  /**@brief Return the x value */
+		SIMD_FORCE_INLINE const btScalar& x() const { return m_floats[0]; }
+  /**@brief Return the y value */
+		SIMD_FORCE_INLINE const btScalar& y() const { return m_floats[1]; }
+  /**@brief Return the z value */
+		SIMD_FORCE_INLINE const btScalar& z() const { return m_floats[2]; }
+  /**@brief Return the w value */
+		SIMD_FORCE_INLINE const btScalar& w() const { return m_floats[3]; }
 
-		SIMD_FORCE_INLINE const btScalar& getY() const { return m_y; }
+	//SIMD_FORCE_INLINE btScalar&       operator[](int i)       { return (&m_floats[0])[i];	}      
+	//SIMD_FORCE_INLINE const btScalar& operator[](int i) const { return (&m_floats[0])[i]; }
+	///operator btScalar*() replaces operator[], using implicit conversion. We added operator != and operator == to avoid pointer comparisons.
+	SIMD_FORCE_INLINE	operator       btScalar *()       { return &m_floats[0]; }
+	SIMD_FORCE_INLINE	operator const btScalar *() const { return &m_floats[0]; }
 
-		SIMD_FORCE_INLINE const btScalar& getZ() const { return m_z; }
+	SIMD_FORCE_INLINE	bool	operator==(const btQuadWord& other) const
+	{
+		return ((m_floats[3]==other.m_floats[3]) && (m_floats[2]==other.m_floats[2]) && (m_floats[1]==other.m_floats[1]) && (m_floats[0]==other.m_floats[0]));
+	}
 
-		SIMD_FORCE_INLINE void	setX(btScalar x) { m_x = x;};
+	SIMD_FORCE_INLINE	bool	operator!=(const btQuadWord& other) const
+	{
+		return !(*this == other);
+	}
 
-		SIMD_FORCE_INLINE void	setY(btScalar y) { m_y = y;};
-
-		SIMD_FORCE_INLINE void	setZ(btScalar z) { m_z = z;};
-
-		SIMD_FORCE_INLINE void	setW(btScalar w) { m_unusedW = w;};
-
-		SIMD_FORCE_INLINE const btScalar& x() const { return m_x; }
-
-		SIMD_FORCE_INLINE const btScalar& y() const { return m_y; }
-
-		SIMD_FORCE_INLINE const btScalar& z() const { return m_z; }
-
-		SIMD_FORCE_INLINE const btScalar& w() const { return m_unusedW; }
-
-
-		SIMD_FORCE_INLINE	operator       btScalar *()       { return &m_x; }
-		SIMD_FORCE_INLINE	operator const btScalar *() const { return &m_x; }
-
-
-
+  /**@brief Set x,y,z and zero w 
+   * @param x Value of x
+   * @param y Value of y
+   * @param z Value of z
+   */
 		SIMD_FORCE_INLINE void 	setValue(const btScalar& x, const btScalar& y, const btScalar& z)
 		{
-			m_x=x;
-			m_y=y;
-			m_z=z;
-			m_unusedW = 0.f;
+			m_floats[0]=x;
+			m_floats[1]=y;
+			m_floats[2]=z;
+			m_floats[3] = 0.f;
 		}
 
 /*		void getValue(btScalar *m) const 
 		{
-			m[0] = m_x;
-			m[1] = m_y;
-			m[2] = m_z;
+			m[0] = m_floats[0];
+			m[1] = m_floats[1];
+			m[2] = m_floats[2];
 		}
 */
+/**@brief Set the values 
+   * @param x Value of x
+   * @param y Value of y
+   * @param z Value of z
+   * @param w Value of w
+   */
 		SIMD_FORCE_INLINE void	setValue(const btScalar& x, const btScalar& y, const btScalar& z,const btScalar& w)
 		{
-			m_x=x;
-			m_y=y;
-			m_z=z;
-			m_unusedW=w;
+			m_floats[0]=x;
+			m_floats[1]=y;
+			m_floats[2]=z;
+			m_floats[3]=w;
 		}
-
+  /**@brief No initialization constructor */
 		SIMD_FORCE_INLINE btQuadWord()
-		//	:m_x(btScalar(0.)),m_y(btScalar(0.)),m_z(btScalar(0.)),m_unusedW(btScalar(0.))
+		//	:m_floats[0](btScalar(0.)),m_floats[1](btScalar(0.)),m_floats[2](btScalar(0.)),m_floats[3](btScalar(0.))
 		{
 		}
-
+  /**@brief Copy constructor */
 		SIMD_FORCE_INLINE btQuadWord(const btQuadWordStorage& q)
 		{
 			*((btQuadWordStorage*)this) = q;
 		}
-
+  /**@brief Three argument constructor (zeros w)
+   * @param x Value of x
+   * @param y Value of y
+   * @param z Value of z
+   */
 		SIMD_FORCE_INLINE btQuadWord(const btScalar& x, const btScalar& y, const btScalar& z)		
 		{
-			m_x = x, m_y = y, m_z = z, m_unusedW = 0.0f;
+			m_floats[0] = x, m_floats[1] = y, m_floats[2] = z, m_floats[3] = 0.0f;
 		}
 
+/**@brief Initializing constructor
+   * @param x Value of x
+   * @param y Value of y
+   * @param z Value of z
+   * @param w Value of w
+   */
 		SIMD_FORCE_INLINE btQuadWord(const btScalar& x, const btScalar& y, const btScalar& z,const btScalar& w) 
 		{
-			m_x = x, m_y = y, m_z = z, m_unusedW = w;
+			m_floats[0] = x, m_floats[1] = y, m_floats[2] = z, m_floats[3] = w;
 		}
 
-
+  /**@brief Set each element to the max of the current values and the values of another btQuadWord
+   * @param other The other btQuadWord to compare with 
+   */
 		SIMD_FORCE_INLINE void	setMax(const btQuadWord& other)
 		{
-			btSetMax(m_x, other.m_x);
-			btSetMax(m_y, other.m_y);
-			btSetMax(m_z, other.m_z);
-			btSetMax(m_unusedW, other.m_unusedW);
+			btSetMax(m_floats[0], other.m_floats[0]);
+			btSetMax(m_floats[1], other.m_floats[1]);
+			btSetMax(m_floats[2], other.m_floats[2]);
+			btSetMax(m_floats[3], other.m_floats[3]);
 		}
-
+  /**@brief Set each element to the min of the current values and the values of another btQuadWord
+   * @param other The other btQuadWord to compare with 
+   */
 		SIMD_FORCE_INLINE void	setMin(const btQuadWord& other)
 		{
-			btSetMin(m_x, other.m_x);
-			btSetMin(m_y, other.m_y);
-			btSetMin(m_z, other.m_z);
-			btSetMin(m_unusedW, other.m_unusedW);
+			btSetMin(m_floats[0], other.m_floats[0]);
+			btSetMin(m_floats[1], other.m_floats[1]);
+			btSetMin(m_floats[2], other.m_floats[2]);
+			btSetMin(m_floats[3], other.m_floats[3]);
 		}
 
Index: code/branches/physics/src/bullet/LinearMath/btQuaternion.h
===================================================================
--- code/branches/physics/src/bullet/LinearMath/btQuaternion.h	(revision 2192)
+++ code/branches/physics/src/bullet/LinearMath/btQuaternion.h	(revision 2430)
@@ -18,28 +18,41 @@
 #define SIMD__QUATERNION_H_
 
+
 #include "btVector3.h"
 
-///The btQuaternion implements quaternion to perform linear algebra rotations in combination with btMatrix3x3, btVector3 and btTransform.
+/**@brief The btQuaternion implements quaternion to perform linear algebra rotations in combination with btMatrix3x3, btVector3 and btTransform. */
 class btQuaternion : public btQuadWord {
 public:
+  /**@brief No initialization constructor */
 	btQuaternion() {}
 
 	//		template <typename btScalar>
 	//		explicit Quaternion(const btScalar *v) : Tuple4<btScalar>(v) {}
-
+  /**@brief Constructor from scalars */
 	btQuaternion(const btScalar& x, const btScalar& y, const btScalar& z, const btScalar& w) 
 		: btQuadWord(x, y, z, w) 
 	{}
-
+  /**@brief Axis angle Constructor
+   * @param axis The axis which the rotation is around
+   * @param angle The magnitude of the rotation around the angle (Radians) */
 	btQuaternion(const btVector3& axis, const btScalar& angle) 
 	{ 
 		setRotation(axis, angle); 
 	}
-
+  /**@brief Constructor from Euler angles
+   * @param yaw Angle around Y unless BT_EULER_DEFAULT_ZYX defined then Z
+   * @param pitch Angle around X unless BT_EULER_DEFAULT_ZYX defined then Y
+   * @param roll Angle around Z unless BT_EULER_DEFAULT_ZYX defined then X */
 	btQuaternion(const btScalar& yaw, const btScalar& pitch, const btScalar& roll)
 	{ 
+#ifndef BT_EULER_DEFAULT_ZYX
 		setEuler(yaw, pitch, roll); 
-	}
-
+#else
+		setEulerZYX(yaw, pitch, roll); 
+#endif 
+	}
+  /**@brief Set the rotation using axis angle notation 
+   * @param axis The axis around which to rotate
+   * @param angle The magnitude of the rotation in Radians */
 	void setRotation(const btVector3& axis, const btScalar& angle)
 	{
@@ -50,5 +63,8 @@
 			btCos(angle * btScalar(0.5)));
 	}
-
+  /**@brief Set the quaternion using Euler angles
+   * @param yaw Angle around Y
+   * @param pitch Angle around X
+   * @param roll Angle around Z */
 	void setEuler(const btScalar& yaw, const btScalar& pitch, const btScalar& roll)
 	{
@@ -67,38 +83,67 @@
 			cosRoll * cosPitch * cosYaw + sinRoll * sinPitch * sinYaw);
 	}
-
-	btQuaternion& operator+=(const btQuaternion& q)
-	{
-		m_x += q.x(); m_y += q.y(); m_z += q.z(); m_unusedW += q.m_unusedW;
+  /**@brief Set the quaternion using euler angles 
+   * @param yaw Angle around Z
+   * @param pitch Angle around Y
+   * @param roll Angle around X */
+	void setEulerZYX(const btScalar& yaw, const btScalar& pitch, const btScalar& roll)
+	{
+		btScalar halfYaw = btScalar(yaw) * btScalar(0.5);  
+		btScalar halfPitch = btScalar(pitch) * btScalar(0.5);  
+		btScalar halfRoll = btScalar(roll) * btScalar(0.5);  
+		btScalar cosYaw = btCos(halfYaw);
+		btScalar sinYaw = btSin(halfYaw);
+		btScalar cosPitch = btCos(halfPitch);
+		btScalar sinPitch = btSin(halfPitch);
+		btScalar cosRoll = btCos(halfRoll);
+		btScalar sinRoll = btSin(halfRoll);
+		setValue(sinRoll * cosPitch * cosYaw - cosRoll * sinPitch * sinYaw, //x
+                         cosRoll * sinPitch * cosYaw + sinRoll * cosPitch * sinYaw, //y
+                         cosRoll * cosPitch * sinYaw - sinRoll * sinPitch * cosYaw, //z
+                         cosRoll * cosPitch * cosYaw + sinRoll * sinPitch * sinYaw); //formerly yzx
+	}
+  /**@brief Add two quaternions
+   * @param q The quaternion to add to this one */
+	SIMD_FORCE_INLINE	btQuaternion& operator+=(const btQuaternion& q)
+	{
+		m_floats[0] += q.x(); m_floats[1] += q.y(); m_floats[2] += q.z(); m_floats[3] += q.m_floats[3];
 		return *this;
 	}
 
+  /**@brief Subtract out a quaternion
+   * @param q The quaternion to subtract from this one */
 	btQuaternion& operator-=(const btQuaternion& q) 
 	{
-		m_x -= q.x(); m_y -= q.y(); m_z -= q.z(); m_unusedW -= q.m_unusedW;
+		m_floats[0] -= q.x(); m_floats[1] -= q.y(); m_floats[2] -= q.z(); m_floats[3] -= q.m_floats[3];
 		return *this;
 	}
 
+  /**@brief Scale this quaternion
+   * @param s The scalar to scale by */
 	btQuaternion& operator*=(const btScalar& s)
 	{
-		m_x *= s; m_y *= s; m_z *= s; m_unusedW *= s;
+		m_floats[0] *= s; m_floats[1] *= s; m_floats[2] *= s; m_floats[3] *= s;
 		return *this;
 	}
 
-
+  /**@brief Multiply this quaternion by q on the right
+   * @param q The other quaternion 
+   * Equivilant to this = this * q */
 	btQuaternion& operator*=(const btQuaternion& q)
 	{
-		setValue(m_unusedW * q.x() + m_x * q.m_unusedW + m_y * q.z() - m_z * q.y(),
-			m_unusedW * q.y() + m_y * q.m_unusedW + m_z * q.x() - m_x * q.z(),
-			m_unusedW * q.z() + m_z * q.m_unusedW + m_x * q.y() - m_y * q.x(),
-			m_unusedW * q.m_unusedW - m_x * q.x() - m_y * q.y() - m_z * q.z());
+		setValue(m_floats[3] * q.x() + m_floats[0] * q.m_floats[3] + m_floats[1] * q.z() - m_floats[2] * q.y(),
+			m_floats[3] * q.y() + m_floats[1] * q.m_floats[3] + m_floats[2] * q.x() - m_floats[0] * q.z(),
+			m_floats[3] * q.z() + m_floats[2] * q.m_floats[3] + m_floats[0] * q.y() - m_floats[1] * q.x(),
+			m_floats[3] * q.m_floats[3] - m_floats[0] * q.x() - m_floats[1] * q.y() - m_floats[2] * q.z());
 		return *this;
 	}
-
+  /**@brief Return the dot product between this quaternion and another
+   * @param q The other quaternion */
 	btScalar dot(const btQuaternion& q) const
 	{
-		return m_x * q.x() + m_y * q.y() + m_z * q.z() + m_unusedW * q.m_unusedW;
-	}
-
+		return m_floats[0] * q.x() + m_floats[1] * q.y() + m_floats[2] * q.z() + m_floats[3] * q.m_floats[3];
+	}
+
+  /**@brief Return the length squared of the quaternion */
 	btScalar length2() const
 	{
@@ -106,4 +151,5 @@
 	}
 
+  /**@brief Return the length of the quaternion */
 	btScalar length() const
 	{
@@ -111,4 +157,6 @@
 	}
 
+  /**@brief Normalize the quaternion 
+   * Such that x^2 + y^2 + z^2 +w^2 = 1 */
 	btQuaternion& normalize() 
 	{
@@ -116,12 +164,15 @@
 	}
 
+  /**@brief Return a scaled version of this quaternion
+   * @param s The scale factor */
 	SIMD_FORCE_INLINE btQuaternion
 	operator*(const btScalar& s) const
 	{
-		return btQuaternion(x() * s, y() * s, z() * s, m_unusedW * s);
-	}
-
-
-
+		return btQuaternion(x() * s, y() * s, z() * s, m_floats[3] * s);
+	}
+
+
+  /**@brief Return an inversely scaled versionof this quaternion
+   * @param s The inverse scale factor */
 	btQuaternion operator/(const btScalar& s) const
 	{
@@ -130,5 +181,6 @@
 	}
 
-
+  /**@brief Inversely scale this quaternion
+   * @param s The scale factor */
 	btQuaternion& operator/=(const btScalar& s) 
 	{
@@ -137,10 +189,11 @@
 	}
 
-
+  /**@brief Return a normalized version of this quaternion */
 	btQuaternion normalized() const 
 	{
 		return *this / length();
 	} 
-
+  /**@brief Return the angle between this quaternion and the other 
+   * @param q The other quaternion */
 	btScalar angle(const btQuaternion& q) const 
 	{
@@ -149,38 +202,44 @@
 		return btAcos(dot(q) / s);
 	}
-
+  /**@brief Return the angle of rotation represented by this quaternion */
 	btScalar getAngle() const 
 	{
-		btScalar s = btScalar(2.) * btAcos(m_unusedW);
+		btScalar s = btScalar(2.) * btAcos(m_floats[3]);
 		return s;
 	}
 
 
-
+  /**@brief Return the inverse of this quaternion */
 	btQuaternion inverse() const
 	{
-		return btQuaternion(-m_x, -m_y, -m_z, m_unusedW);
-	}
-
+		return btQuaternion(-m_floats[0], -m_floats[1], -m_floats[2], m_floats[3]);
+	}
+
+  /**@brief Return the sum of this quaternion and the other 
+   * @param q2 The other quaternion */
 	SIMD_FORCE_INLINE btQuaternion
 	operator+(const btQuaternion& q2) const
 	{
 		const btQuaternion& q1 = *this;
-		return btQuaternion(q1.x() + q2.x(), q1.y() + q2.y(), q1.z() + q2.z(), q1.m_unusedW + q2.m_unusedW);
-	}
-
+		return btQuaternion(q1.x() + q2.x(), q1.y() + q2.y(), q1.z() + q2.z(), q1.m_floats[3] + q2.m_floats[3]);
+	}
+
+  /**@brief Return the difference between this quaternion and the other 
+   * @param q2 The other quaternion */
 	SIMD_FORCE_INLINE btQuaternion
 	operator-(const btQuaternion& q2) const
 	{
 		const btQuaternion& q1 = *this;
-		return btQuaternion(q1.x() - q2.x(), q1.y() - q2.y(), q1.z() - q2.z(), q1.m_unusedW - q2.m_unusedW);
-	}
-
+		return btQuaternion(q1.x() - q2.x(), q1.y() - q2.y(), q1.z() - q2.z(), q1.m_floats[3] - q2.m_floats[3]);
+	}
+
+  /**@brief Return the negative of this quaternion 
+   * This simply negates each element */
 	SIMD_FORCE_INLINE btQuaternion operator-() const
 	{
 		const btQuaternion& q2 = *this;
-		return btQuaternion( - q2.x(), - q2.y(),  - q2.z(),  - q2.m_unusedW);
-	}
-
+		return btQuaternion( - q2.x(), - q2.y(),  - q2.z(),  - q2.m_floats[3]);
+	}
+  /**@todo document this and it's use */
 	SIMD_FORCE_INLINE btQuaternion farthest( const btQuaternion& qd) const 
 	{
@@ -193,4 +252,8 @@
 	}
 
+  /**@brief Return the quaternion which is the result of Spherical Linear Interpolation between this and the other quaternion
+   * @param q The other quaternion to interpolate with 
+   * @param t The ratio between this and q to interpolate.  If t = 0 the result is this, if t=1 the result is q.
+   * Slerp interpolates assuming constant velocity.  */
 	btQuaternion slerp(const btQuaternion& q, const btScalar& t) const
 	{
@@ -201,8 +264,8 @@
 			btScalar s0 = btSin((btScalar(1.0) - t) * theta);
 			btScalar s1 = btSin(t * theta);   
-			return btQuaternion((m_x * s0 + q.x() * s1) * d,
-				(m_y * s0 + q.y() * s1) * d,
-				(m_z * s0 + q.z() * s1) * d,
-				(m_unusedW * s0 + q.m_unusedW * s1) * d);
+			return btQuaternion((m_floats[0] * s0 + q.x() * s1) * d,
+				(m_floats[1] * s0 + q.y() * s1) * d,
+				(m_floats[2] * s0 + q.z() * s1) * d,
+				(m_floats[3] * s0 + q.m_floats[3] * s1) * d);
 		}
 		else
@@ -212,5 +275,5 @@
 	}
 
-	SIMD_FORCE_INLINE const btScalar& getW() const { return m_unusedW; }
+	SIMD_FORCE_INLINE const btScalar& getW() const { return m_floats[3]; }
 
 	
@@ -218,5 +281,5 @@
 
 
-
+/**@brief Return the negative of a quaternion */
 SIMD_FORCE_INLINE btQuaternion
 operator-(const btQuaternion& q)
@@ -227,5 +290,5 @@
 
 
-
+/**@brief Return the product of two quaternions */
 SIMD_FORCE_INLINE btQuaternion
 operator*(const btQuaternion& q1, const btQuaternion& q2) {
@@ -254,4 +317,5 @@
 }
 
+/**@brief Calculate the dot product between two quaternions */
 SIMD_FORCE_INLINE btScalar 
 dot(const btQuaternion& q1, const btQuaternion& q2) 
@@ -261,4 +325,5 @@
 
 
+/**@brief Return the length of a quaternion */
 SIMD_FORCE_INLINE btScalar
 length(const btQuaternion& q) 
@@ -267,4 +332,5 @@
 }
 
+/**@brief Return the angle between two quaternions*/
 SIMD_FORCE_INLINE btScalar
 angle(const btQuaternion& q1, const btQuaternion& q2) 
@@ -273,5 +339,5 @@
 }
 
-
+/**@brief Return the inverse of a quaternion*/
 SIMD_FORCE_INLINE btQuaternion
 inverse(const btQuaternion& q) 
@@ -280,4 +346,9 @@
 }
 
+/**@brief Return the result of spherical linear interpolation betwen two quaternions 
+ * @param q1 The first quaternion
+ * @param q2 The second quaternion 
+ * @param t The ration between q1 and q2.  t = 0 return q1, t=1 returns q2 
+ * Slerp assumes constant velocity between positions. */
 SIMD_FORCE_INLINE btQuaternion
 slerp(const btQuaternion& q1, const btQuaternion& q2, const btScalar& t) 
Index: code/branches/physics/src/bullet/LinearMath/btQuickprof.cpp
===================================================================
--- code/branches/physics/src/bullet/LinearMath/btQuickprof.cpp	(revision 2192)
+++ code/branches/physics/src/bullet/LinearMath/btQuickprof.cpp	(revision 2430)
@@ -111,5 +111,5 @@
 	TotalCalls = 0;
 	TotalTime = 0.0f;
-	gProfileClock.reset();
+	
 
 	if ( Child ) {
@@ -252,4 +252,5 @@
 void	CProfileManager::Reset( void )
 { 
+	gProfileClock.reset();
 	Root.Reset();
     Root.Call();
@@ -279,4 +280,67 @@
 }
 
+#include <stdio.h>
+
+void	CProfileManager::dumpRecursive(CProfileIterator* profileIterator, int spacing)
+{
+	profileIterator->First();
+	if (profileIterator->Is_Done())
+		return;
+
+	float accumulated_time=0,parent_time = profileIterator->Is_Root() ? CProfileManager::Get_Time_Since_Reset() : profileIterator->Get_Current_Parent_Total_Time();
+	int i;
+	int frames_since_reset = CProfileManager::Get_Frame_Count_Since_Reset();
+	for (i=0;i<spacing;i++)	printf(".");
+	printf("----------------------------------\n");
+	for (i=0;i<spacing;i++)	printf(".");
+	printf("Profiling: %s (total running time: %.3f ms) ---\n",	profileIterator->Get_Current_Parent_Name(), parent_time );
+	float totalTime = 0.f;
+
+	
+	int numChildren = 0;
+	
+	for (i = 0; !profileIterator->Is_Done(); i++,profileIterator->Next())
+	{
+		numChildren++;
+		float current_total_time = profileIterator->Get_Current_Total_Time();
+		accumulated_time += current_total_time;
+		float fraction = parent_time > SIMD_EPSILON ? (current_total_time / parent_time) * 100 : 0.f;
+		{
+			int i;	for (i=0;i<spacing;i++)	printf(".");
+		}
+		printf("%d -- %s (%.2f %%) :: %.3f ms / frame (%d calls)\n",i, profileIterator->Get_Current_Name(), fraction,(current_total_time / (double)frames_since_reset),profileIterator->Get_Current_Total_Calls());
+		totalTime += current_total_time;
+		//recurse into children
+	}
+
+	if (parent_time < accumulated_time)
+	{
+		printf("what's wrong\n");
+	}
+	for (i=0;i<spacing;i++)	printf(".");
+	printf("%s (%.3f %%) :: %.3f ms\n", "Unaccounted:",parent_time > SIMD_EPSILON ? ((parent_time - accumulated_time) / parent_time) * 100 : 0.f, parent_time - accumulated_time);
+	
+	for (i=0;i<numChildren;i++)
+	{
+		profileIterator->Enter_Child(i);
+		dumpRecursive(profileIterator,spacing+3);
+		profileIterator->Enter_Parent();
+	}
+}
+
+
+
+void	CProfileManager::dumpAll()
+{
+	CProfileIterator* profileIterator = 0;
+	profileIterator = CProfileManager::Get_Iterator();
+
+	dumpRecursive(profileIterator,0);
+
+	CProfileManager::Release_Iterator(profileIterator);
+}
+
+
+
 #endif //USE_BT_CLOCK
 
Index: code/branches/physics/src/bullet/LinearMath/btQuickprof.h
===================================================================
--- code/branches/physics/src/bullet/LinearMath/btQuickprof.h	(revision 2192)
+++ code/branches/physics/src/bullet/LinearMath/btQuickprof.h	(revision 2430)
@@ -11,12 +11,18 @@
 // Ogre (www.ogre3d.org).
 
+
+
 #ifndef QUICK_PROF_H
 #define QUICK_PROF_H
+
+//To disable built-in profiling, please comment out next line
+//#define BT_NO_PROFILE 1
+#ifndef BT_NO_PROFILE
 
 #include "btScalar.h"
 #include "LinearMath/btAlignedAllocator.h"
 #include <new>
-//To disable built-in profiling, please comment out next line
-//#define BT_NO_PROFILE 1
+
+
 
 
@@ -322,4 +328,8 @@
 	static	void						Release_Iterator( CProfileIterator * iterator ) { delete ( iterator); }
 
+	static void	dumpRecursive(CProfileIterator* profileIterator, int spacing);
+
+	static void	dumpAll();
+
 private:
 	static	CProfileNode			Root;
@@ -345,10 +355,12 @@
 };
 
-#if !defined(BT_NO_PROFILE)
+
 #define	BT_PROFILE( name )			CProfileSample __profile( name )
-#else
+
+#else
+
 #define	BT_PROFILE( name )
-#endif
-
+
+#endif //#ifndef BT_NO_PROFILE
 
 
Index: code/branches/physics/src/bullet/LinearMath/btScalar.h
===================================================================
--- code/branches/physics/src/bullet/LinearMath/btScalar.h	(revision 2192)
+++ code/branches/physics/src/bullet/LinearMath/btScalar.h	(revision 2430)
@@ -19,4 +19,5 @@
 
 #include <math.h>
+
 #include <stdlib.h>//size_t for MSVC 6.0
 
@@ -25,5 +26,5 @@
 #include <float.h>
 
-#define BT_BULLET_VERSION 272
+#define BT_BULLET_VERSION 273
 
 inline int	btGetVersion()
@@ -66,5 +67,5 @@
 
 		#include <assert.h>
-#if defined(DEBUG) || defined (_DEBUG)
+#ifdef BT_DEBUG
 		#define btAssert assert
 #else
@@ -86,5 +87,9 @@
 		#include <assert.h>
 		#endif
+#ifdef BT_DEBUG
 		#define btAssert assert
+#else
+		#define btAssert(x)
+#endif
 		//btFullAssert is optional, slows down a lot
 		#define btFullAssert(x)
@@ -103,5 +108,9 @@
 		#include <assert.h>
 		#endif
+#ifdef BT_DEBUG
 		#define btAssert assert
+#else
+		#define btAssert(x)
+#endif
 		//btFullAssert is optional, slows down a lot
 		#define btFullAssert(x)
Index: code/branches/physics/src/bullet/LinearMath/btStackAlloc.h
===================================================================
--- code/branches/physics/src/bullet/LinearMath/btStackAlloc.h	(revision 2192)
+++ code/branches/physics/src/bullet/LinearMath/btStackAlloc.h	(revision 2430)
@@ -24,4 +24,5 @@
 #include "btAlignedAllocator.h"
 
+///The btBlock class is an internal structure for the btStackAlloc memory allocator.
 struct btBlock
 {
Index: code/branches/physics/src/bullet/LinearMath/btTransform.h
===================================================================
--- code/branches/physics/src/bullet/LinearMath/btTransform.h	(revision 2192)
+++ code/branches/physics/src/bullet/LinearMath/btTransform.h	(revision 2430)
@@ -22,6 +22,6 @@
 
 
-///The btTransform class supports rigid transforms with only translation and rotation and no scaling/shear.
-///It can be used in combination with btVector3, btQuaternion and btMatrix3x3 linear algebra classes.
+/**@brief The btTransform class supports rigid transforms with only translation and rotation and no scaling/shear.
+ *It can be used in combination with btVector3, btQuaternion and btMatrix3x3 linear algebra classes. */
 class btTransform {
 	
@@ -29,7 +29,9 @@
 public:
 	
-	
+  /**@brief No initialization constructor */
 	btTransform() {}
-
+  /**@brief Constructor from btQuaternion (optional btVector3 )
+   * @param q Rotation from quaternion 
+   * @param c Translation from Vector (default 0,0,0) */
 	explicit SIMD_FORCE_INLINE btTransform(const btQuaternion& q, 
 		const btVector3& c = btVector3(btScalar(0), btScalar(0), btScalar(0))) 
@@ -38,4 +40,7 @@
 	{}
 
+  /**@brief Constructor from btMatrix3x3 (optional btVector3)
+   * @param b Rotation from Matrix 
+   * @param c Translation from Vector default (0,0,0)*/
 	explicit SIMD_FORCE_INLINE btTransform(const btMatrix3x3& b, 
 		const btVector3& c = btVector3(btScalar(0), btScalar(0), btScalar(0)))
@@ -43,5 +48,5 @@
 		m_origin(c)
 	{}
-
+  /**@brief Copy constructor */
 	SIMD_FORCE_INLINE btTransform (const btTransform& other)
 		: m_basis(other.m_basis),
@@ -49,5 +54,5 @@
 	{
 	}
-
+  /**@brief Assignment Operator */
 	SIMD_FORCE_INLINE btTransform& operator=(const btTransform& other)
 	{
@@ -58,4 +63,8 @@
 
 
+  /**@brief Set the current transform as the value of the product of two transforms
+   * @param t1 Transform 1
+   * @param t2 Transform 2
+   * This = Transform1 * Transform2 */
 		SIMD_FORCE_INLINE void mult(const btTransform& t1, const btTransform& t2) {
 			m_basis = t1.m_basis * t2.m_basis;
@@ -70,5 +79,5 @@
 		*/
 
-
+/**@brief Return the transform of the vector */
 	SIMD_FORCE_INLINE btVector3 operator()(const btVector3& x) const
 	{
@@ -78,4 +87,5 @@
 	}
 
+  /**@brief Return the transform of the vector */
 	SIMD_FORCE_INLINE btVector3 operator*(const btVector3& x) const
 	{
@@ -83,10 +93,21 @@
 	}
 
+  /**@brief Return the transform of the btQuaternion */
+	SIMD_FORCE_INLINE btQuaternion operator*(const btQuaternion& q) const
+	{
+		return getRotation() * q;
+	}
+
+  /**@brief Return the basis matrix for the rotation */
 	SIMD_FORCE_INLINE btMatrix3x3&       getBasis()          { return m_basis; }
+  /**@brief Return the basis matrix for the rotation */
 	SIMD_FORCE_INLINE const btMatrix3x3& getBasis()    const { return m_basis; }
 
+  /**@brief Return the origin vector translation */
 	SIMD_FORCE_INLINE btVector3&         getOrigin()         { return m_origin; }
+  /**@brief Return the origin vector translation */
 	SIMD_FORCE_INLINE const btVector3&   getOrigin()   const { return m_origin; }
 
+  /**@brief Return a quaternion representing the rotation */
 	btQuaternion getRotation() const { 
 		btQuaternion q;
@@ -96,4 +117,6 @@
 	
 	
+  /**@brief Set from an array 
+   * @param m A pointer to a 15 element array (12 rotation(row major padded on the right by 1), and 3 translation */
 	void setFromOpenGLMatrix(const btScalar *m)
 	{
@@ -102,4 +125,6 @@
 	}
 
+  /**@brief Fill an array representation
+   * @param m A pointer to a 15 element array (12 rotation(row major padded on the right by 1), and 3 translation */
 	void getOpenGLMatrix(btScalar *m) const 
 	{
@@ -111,4 +136,6 @@
 	}
 
+  /**@brief Set the translational element
+   * @param origin The vector to set the translation to */
 	SIMD_FORCE_INLINE void setOrigin(const btVector3& origin) 
 	{ 
@@ -119,5 +146,5 @@
 
 
-
+  /**@brief Set the rotational element by btMatrix3x3 */
 	SIMD_FORCE_INLINE void setBasis(const btMatrix3x3& basis)
 	{ 
@@ -125,4 +152,5 @@
 	}
 
+  /**@brief Set the rotational element by btQuaternion */
 	SIMD_FORCE_INLINE void setRotation(const btQuaternion& q)
 	{
@@ -131,5 +159,5 @@
 
 
-
+  /**@brief Set this transformation to the identity */
 	void setIdentity()
 	{
@@ -138,5 +166,6 @@
 	}
 
-	
+  /**@brief Multiply this Transform by another(this = this * another) 
+   * @param t The other transform */
 	btTransform& operator*=(const btTransform& t) 
 	{
@@ -146,4 +175,5 @@
 	}
 
+  /**@brief Return the inverse of this transform */
 	btTransform inverse() const
 	{ 
@@ -152,8 +182,13 @@
 	}
 
+  /**@brief Return the inverse of this transform times the other transform
+   * @param t The other transform 
+   * return this.inverse() * the other */
 	btTransform inverseTimes(const btTransform& t) const;  
 
+  /**@brief Return the product of this transform and the other */
 	btTransform operator*(const btTransform& t) const;
 
+  /**@brief Return an identity transform */
 	static btTransform	getIdentity()
 	{
@@ -164,6 +199,7 @@
 	
 private:
-
+  ///Storage for the rotation
 	btMatrix3x3 m_basis;
+  ///Storage for the translation
 	btVector3   m_origin;
 };
@@ -192,4 +228,5 @@
 }
 
+/**@brief Test if two transforms have all elements equal */
 SIMD_FORCE_INLINE bool operator==(const btTransform& t1, const btTransform& t2)
 {
Index: code/branches/physics/src/bullet/LinearMath/btTransformUtil.h
===================================================================
--- code/branches/physics/src/bullet/LinearMath/btTransformUtil.h	(revision 2192)
+++ code/branches/physics/src/bullet/LinearMath/btTransformUtil.h	(revision 2430)
@@ -101,4 +101,36 @@
 	}
 
+	static void	calculateVelocityQuaternion(const btVector3& pos0,const btVector3& pos1,const btQuaternion& orn0,const btQuaternion& orn1,btScalar timeStep,btVector3& linVel,btVector3& angVel)
+	{
+		linVel = (pos1 - pos0) / timeStep;
+		btVector3 axis;
+		btScalar  angle;
+		if (orn0 != orn1)
+		{
+			calculateDiffAxisAngleQuaternion(orn0,orn1,axis,angle);
+			angVel = axis * angle / timeStep;
+		} else
+		{
+			angVel.setValue(0,0,0);
+		}
+	}
+
+	static void calculateDiffAxisAngleQuaternion(const btQuaternion& orn0,const btQuaternion& orn1a,btVector3& axis,btScalar& angle)
+	{
+		btQuaternion orn1 = orn0.farthest(orn1a);
+		btQuaternion dorn = orn1 * orn0.inverse();
+		///floating point inaccuracy can lead to w component > 1..., which breaks 
+		dorn.normalize();
+		angle = dorn.getAngle();
+		axis = btVector3(dorn.x(),dorn.y(),dorn.z());
+		axis[3] = btScalar(0.);
+		//check for axis length
+		btScalar len = axis.length2();
+		if (len < SIMD_EPSILON*SIMD_EPSILON)
+			axis = btVector3(btScalar(1.),btScalar(0.),btScalar(0.));
+		else
+			axis /= btSqrt(len);
+	}
+
 	static void	calculateVelocity(const btTransform& transform0,const btTransform& transform1,btScalar timeStep,btVector3& linVel,btVector3& angVel)
 	{
@@ -112,18 +144,9 @@
 	static void calculateDiffAxisAngle(const btTransform& transform0,const btTransform& transform1,btVector3& axis,btScalar& angle)
 	{
-	
-	#ifdef USE_QUATERNION_DIFF
-		btQuaternion orn0 = transform0.getRotation();
-		btQuaternion orn1a = transform1.getRotation();
-		btQuaternion orn1 = orn0.farthest(orn1a);
-		btQuaternion dorn = orn1 * orn0.inverse();
-#else
 		btMatrix3x3 dmat = transform1.getBasis() * transform0.getBasis().inverse();
 		btQuaternion dorn;
 		dmat.getRotation(dorn);
-#endif//USE_QUATERNION_DIFF
-	
+
 		///floating point inaccuracy can lead to w component > 1..., which breaks 
-
 		dorn.normalize();
 		
@@ -141,4 +164,84 @@
 };
 
+
+///The btConvexSeparatingDistanceUtil can help speed up convex collision detection 
+///by conservatively updating a cached separating distance/vector instead of re-calculating the closest distance
+class	btConvexSeparatingDistanceUtil
+{
+	btQuaternion	m_ornA;
+	btQuaternion	m_ornB;
+	btVector3	m_posA;
+	btVector3	m_posB;
+	
+	btVector3	m_separatingNormal;
+
+	btScalar	m_boundingRadiusA;
+	btScalar	m_boundingRadiusB;
+	btScalar	m_separatingDistance;
+
+public:
+
+	btConvexSeparatingDistanceUtil(btScalar	boundingRadiusA,btScalar	boundingRadiusB)
+		:m_boundingRadiusA(boundingRadiusA),
+		m_boundingRadiusB(boundingRadiusB),
+		m_separatingDistance(0.f)
+	{
+	}
+
+	btScalar	getConservativeSeparatingDistance()
+	{
+		return m_separatingDistance;
+	}
+
+	void	updateSeparatingDistance(const btTransform& transA,const btTransform& transB)
+	{
+		const btVector3& toPosA = transA.getOrigin();
+		const btVector3& toPosB = transB.getOrigin();
+		btQuaternion toOrnA = transA.getRotation();
+		btQuaternion toOrnB = transB.getRotation();
+
+		if (m_separatingDistance>0.f)
+		{
+			
+
+			btVector3 linVelA,angVelA,linVelB,angVelB;
+			btTransformUtil::calculateVelocityQuaternion(m_posA,toPosA,m_ornA,toOrnA,btScalar(1.),linVelA,angVelA);
+			btTransformUtil::calculateVelocityQuaternion(m_posB,toPosB,m_ornB,toOrnB,btScalar(1.),linVelB,angVelB);
+			btScalar maxAngularProjectedVelocity = angVelA.length() * m_boundingRadiusA + angVelB.length() * m_boundingRadiusB;
+			btVector3 relLinVel = (linVelB-linVelA);
+			btScalar relLinVelocLength = (linVelB-linVelA).dot(m_separatingNormal);
+			if (relLinVelocLength<0.f)
+			{
+				relLinVelocLength = 0.f;
+			}
+	
+			btScalar	projectedMotion = maxAngularProjectedVelocity +relLinVelocLength;
+			m_separatingDistance -= projectedMotion;
+		}
+	
+		m_posA = toPosA;
+		m_posB = toPosB;
+		m_ornA = toOrnA;
+		m_ornB = toOrnB;
+	}
+
+	void	initSeparatingDistance(const btVector3& separatingVector,btScalar separatingDistance,const btTransform& transA,const btTransform& transB)
+	{
+		m_separatingNormal = separatingVector;
+		m_separatingDistance = separatingDistance;
+		
+		const btVector3& toPosA = transA.getOrigin();
+		const btVector3& toPosB = transB.getOrigin();
+		btQuaternion toOrnA = transA.getRotation();
+		btQuaternion toOrnB = transB.getRotation();
+		m_posA = toPosA;
+		m_posB = toPosB;
+		m_ornA = toOrnA;
+		m_ornB = toOrnB;
+	}
+
+};
+
+
 #endif //SIMD_TRANSFORM_UTIL_H
 
Index: code/branches/physics/src/bullet/LinearMath/btVector3.h
===================================================================
--- code/branches/physics/src/bullet/LinearMath/btVector3.h	(revision 2192)
+++ code/branches/physics/src/bullet/LinearMath/btVector3.h	(revision 2430)
@@ -20,12 +20,16 @@
 #include "btQuadWord.h"
 
-///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
+/**@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
+ */
 class	btVector3 : public btQuadWord {
 
 public:
+  /**@brief No initialization constructor */
 	SIMD_FORCE_INLINE btVector3() {}
 
+  /**@brief Constructor from btQuadWordStorage (btVector3 inherits from this so is also valid)
+   * Note: Vector3 derives from btQuadWordStorage*/
 	SIMD_FORCE_INLINE btVector3(const btQuadWordStorage& q) 
 		: btQuadWord(q)
@@ -33,5 +37,9 @@
 	}
 	
-
+  /**@brief Constructor from scalars 
+   * @param x X value
+   * @param y Y value 
+   * @param z Z value 
+   */
 	SIMD_FORCE_INLINE btVector3(const btScalar& x, const btScalar& y, const btScalar& z) 
 		:btQuadWord(x,y,z,btScalar(0.))
@@ -45,26 +53,31 @@
 
 	
-
+/**@brief Add a vector to this one 
+ * @param The vector to add to this one */
 	SIMD_FORCE_INLINE btVector3& operator+=(const btVector3& v)
 	{
 
-		m_x += v.x(); m_y += v.y(); m_z += v.z();
+		m_floats[0] += v.x(); m_floats[1] += v.y(); m_floats[2] += v.z();
 		return *this;
 	}
 
 
-
+  /**@brief Subtract a vector from this one
+   * @param The vector to subtract */
 	SIMD_FORCE_INLINE btVector3& operator-=(const btVector3& v) 
 	{
-		m_x -= v.x(); m_y -= v.y(); m_z -= v.z();
+		m_floats[0] -= v.x(); m_floats[1] -= v.y(); m_floats[2] -= v.z();
 		return *this;
 	}
-
+  /**@brief Scale the vector
+   * @param s Scale factor */
 	SIMD_FORCE_INLINE btVector3& operator*=(const btScalar& s)
 	{
-		m_x *= s; m_y *= s; m_z *= s;
+		m_floats[0] *= s; m_floats[1] *= s; m_floats[2] *= s;
 		return *this;
 	}
 
+  /**@brief Inversely scale the vector 
+   * @param s Scale factor to divide by */
 	SIMD_FORCE_INLINE btVector3& operator/=(const btScalar& s) 
 	{
@@ -73,9 +86,12 @@
 	}
 
+  /**@brief Return the dot product
+   * @param v The other vector in the dot product */
 	SIMD_FORCE_INLINE btScalar dot(const btVector3& v) const
 	{
-		return m_x * v.x() + m_y * v.y() + m_z * v.z();
-	}
-
+		return m_floats[0] * v.x() + m_floats[1] * v.y() + m_floats[2] * v.z();
+	}
+
+  /**@brief Return the length of the vector squared */
 	SIMD_FORCE_INLINE btScalar length2() const
 	{
@@ -83,4 +99,5 @@
 	}
 
+  /**@brief Return the length of the vector */
 	SIMD_FORCE_INLINE btScalar length() const
 	{
@@ -88,8 +105,14 @@
 	}
 
+  /**@brief Return the distance squared between the ends of this and another vector
+   * This is symantically treating the vector like a point */
 	SIMD_FORCE_INLINE btScalar distance2(const btVector3& v) const;
 
+  /**@brief Return the distance between the ends of this and another vector
+   * This is symantically treating the vector like a point */
 	SIMD_FORCE_INLINE btScalar distance(const btVector3& v) const;
 
+  /**@brief Normalize this vector 
+   * x^2 + y^2 + z^2 = 1 */
 	SIMD_FORCE_INLINE btVector3& normalize() 
 	{
@@ -97,8 +120,14 @@
 	}
 
+  /**@brief Return a normalized version of this vector */
 	SIMD_FORCE_INLINE btVector3 normalized() const;
 
+  /**@brief Rotate 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 );
 
+  /**@brief Return the angle between this and another vector
+   * @param v The other vector */
 	SIMD_FORCE_INLINE btScalar angle(const btVector3& v) const 
 	{
@@ -107,36 +136,41 @@
 		return btAcos(dot(v) / s);
 	}
-
+  /**@brief Return a vector will the absolute values of each element */
 	SIMD_FORCE_INLINE btVector3 absolute() const 
 	{
 		return btVector3(
-			btFabs(m_x), 
-			btFabs(m_y), 
-			btFabs(m_z));
-	}
-
+			btFabs(m_floats[0]), 
+			btFabs(m_floats[1]), 
+			btFabs(m_floats[2]));
+	}
+  /**@brief Return the cross product between this and another vector 
+   * @param v The other vector */
 	SIMD_FORCE_INLINE btVector3 cross(const btVector3& v) const
 	{
 		return btVector3(
-			m_y * v.z() - m_z * v.y(),
-			m_z * v.x() - m_x * v.z(),
-			m_x * v.y() - m_y * v.x());
+			m_floats[1] * v.z() - m_floats[2] * v.y(),
+			m_floats[2] * v.x() - m_floats[0] * v.z(),
+			m_floats[0] * v.y() - m_floats[1] * v.x());
 	}
 
 	SIMD_FORCE_INLINE btScalar triple(const btVector3& v1, const btVector3& v2) const
 	{
-		return m_x * (v1.y() * v2.z() - v1.z() * v2.y()) + 
-			m_y * (v1.z() * v2.x() - v1.x() * v2.z()) + 
-			m_z * (v1.x() * v2.y() - v1.y() * v2.x());
-	}
-
+		return m_floats[0] * (v1.y() * v2.z() - v1.z() * v2.y()) + 
+			m_floats[1] * (v1.z() * v2.x() - v1.x() * v2.z()) + 
+			m_floats[2] * (v1.x() * v2.y() - v1.y() * v2.x());
+	}
+
+  /**@brief Return the axis with the smallest value 
+   * Note return values are 0,1,2 for x, y, or z */
 	SIMD_FORCE_INLINE int minAxis() const
 	{
-		return m_x < m_y ? (m_x < m_z ? 0 : 2) : (m_y < m_z ? 1 : 2);
-	}
-
+		return m_floats[0] < m_floats[1] ? (m_floats[0] < m_floats[2] ? 0 : 2) : (m_floats[1] < m_floats[2] ? 1 : 2);
+	}
+
+  /**@brief Return the axis with the largest value 
+   * Note return values are 0,1,2 for x, y, or z */
 	SIMD_FORCE_INLINE int maxAxis() const 
 	{
-		return m_x < m_y ? (m_y < m_z ? 2 : 1) : (m_x < m_z ? 2 : 0);
+		return m_floats[0] < m_floats[1] ? (m_floats[1] < m_floats[2] ? 2 : 1) : (m_floats[0] < m_floats[2] ? 2 : 0);
 	}
 
@@ -154,22 +188,26 @@
 	{
 		btScalar s = btScalar(1.0) - rt;
-		m_x = s * v0.x() + rt * v1.x();
-		m_y = s * v0.y() + rt * v1.y();
-		m_z = s * v0.z() + rt * v1.z();
+		m_floats[0] = s * v0.x() + rt * v1.x();
+		m_floats[1] = s * v0.y() + rt * v1.y();
+		m_floats[2] = s * v0.z() + rt * v1.z();
 		//don't do the unused w component
 		//		m_co[3] = s * v0[3] + rt * v1[3];
 	}
 
+  /**@brief Return the linear interpolation between this and another vector 
+   * @param v The other vector 
+   * @param t The ration of this to v (t = 0 => return this, t=1 => return other) */
 	SIMD_FORCE_INLINE btVector3 lerp(const btVector3& v, const btScalar& t) const 
 	{
-		return btVector3(m_x + (v.x() - m_x) * t,
-			m_y + (v.y() - m_y) * t,
-			m_z + (v.z() - m_z) * t);
-	}
-
-
+		return btVector3(m_floats[0] + (v.x() - m_floats[0]) * t,
+			m_floats[1] + (v.y() - m_floats[1]) * t,
+			m_floats[2] + (v.z() - m_floats[2]) * t);
+	}
+
+  /**@brief Elementwise multiply this vector by the other 
+   * @param v The other vector */
 	SIMD_FORCE_INLINE btVector3& operator*=(const btVector3& v)
 	{
-		m_x *= v.x(); m_y *= v.y(); m_z *= v.z();
+		m_floats[0] *= v.x(); m_floats[1] *= v.y(); m_floats[2] *= v.z();
 		return *this;
 	}
@@ -179,4 +217,5 @@
 };
 
+/**@brief Return the sum of two vectors (Point symantics)*/
 SIMD_FORCE_INLINE btVector3 
 operator+(const btVector3& v1, const btVector3& v2) 
@@ -185,4 +224,5 @@
 }
 
+/**@brief Return the elementwise product of two vectors */
 SIMD_FORCE_INLINE btVector3 
 operator*(const btVector3& v1, const btVector3& v2) 
@@ -191,4 +231,5 @@
 }
 
+/**@brief Return the difference between two vectors */
 SIMD_FORCE_INLINE btVector3 
 operator-(const btVector3& v1, const btVector3& v2)
@@ -196,5 +237,5 @@
 	return btVector3(v1.x() - v2.x(), v1.y() - v2.y(), v1.z() - v2.z());
 }
-
+/**@brief Return the negative of the vector */
 SIMD_FORCE_INLINE btVector3 
 operator-(const btVector3& v)
@@ -203,4 +244,5 @@
 }
 
+/**@brief Return the vector scaled by s */
 SIMD_FORCE_INLINE btVector3 
 operator*(const btVector3& v, const btScalar& s)
@@ -209,4 +251,5 @@
 }
 
+/**@brief Return the vector scaled by s */
 SIMD_FORCE_INLINE btVector3 
 operator*(const btScalar& s, const btVector3& v)
@@ -215,4 +258,5 @@
 }
 
+/**@brief Return the vector inversely scaled by s */
 SIMD_FORCE_INLINE btVector3
 operator/(const btVector3& v, const btScalar& s)
@@ -222,4 +266,5 @@
 }
 
+/**@brief Return the vector inversely scaled by s */
 SIMD_FORCE_INLINE btVector3
 operator/(const btVector3& v1, const btVector3& v2)
@@ -228,4 +273,5 @@
 }
 
+/**@brief Return the dot product between two vectors */
 SIMD_FORCE_INLINE btScalar 
 dot(const btVector3& v1, const btVector3& v2) 
@@ -235,5 +281,5 @@
 
 
-
+/**@brief Return the distance squared between two vectors */
 SIMD_FORCE_INLINE btScalar
 distance2(const btVector3& v1, const btVector3& v2) 
@@ -243,4 +289,5 @@
 
 
+/**@brief Return the distance between two vectors */
 SIMD_FORCE_INLINE btScalar
 distance(const btVector3& v1, const btVector3& v2) 
@@ -249,4 +296,5 @@
 }
 
+/**@brief Return the angle between two vectors */
 SIMD_FORCE_INLINE btScalar
 angle(const btVector3& v1, const btVector3& v2) 
@@ -255,4 +303,5 @@
 }
 
+/**@brief Return the cross product of two vectors */
 SIMD_FORCE_INLINE btVector3 
 cross(const btVector3& v1, const btVector3& v2) 
@@ -267,4 +316,8 @@
 }
 
+/**@brief Return the linear interpolation between two vectors
+ * @param v1 One vector 
+ * @param v2 The other vector 
+ * @param t The ration of this to v (t = 0 => return v1, t=1 => return v2) */
 SIMD_FORCE_INLINE btVector3 
 lerp(const btVector3& v1, const btVector3& v2, const btScalar& t)
@@ -273,5 +326,5 @@
 }
 
-
+/**@brief Test if each element of the vector is equivalent */
 SIMD_FORCE_INLINE bool operator==(const btVector3& p1, const btVector3& p2) 
 {
@@ -317,5 +370,5 @@
 		: btVector3(x,y,z)
 	{
-		m_unusedW = w;
+		m_floats[3] = w;
 	}
 
@@ -324,13 +377,13 @@
 	{
 		return btVector4(
-			btFabs(m_x), 
-			btFabs(m_y), 
-			btFabs(m_z),
-			btFabs(m_unusedW));
-	}
-
-
-
-	btScalar	getW() const { return m_unusedW;}
+			btFabs(m_floats[0]), 
+			btFabs(m_floats[1]), 
+			btFabs(m_floats[2]),
+			btFabs(m_floats[3]));
+	}
+
+
+
+	btScalar	getW() const { return m_floats[3];}
 
 
@@ -339,23 +392,23 @@
 		int maxIndex = -1;
 		btScalar maxVal = btScalar(-1e30);
-		if (m_x > maxVal)
+		if (m_floats[0] > maxVal)
 		{
 			maxIndex = 0;
-			maxVal = m_x;
-		}
-		if (m_y > maxVal)
+			maxVal = m_floats[0];
+		}
+		if (m_floats[1] > maxVal)
 		{
 			maxIndex = 1;
-			maxVal = m_y;
-		}
-		if (m_z > maxVal)
+			maxVal = m_floats[1];
+		}
+		if (m_floats[2] > maxVal)
 		{
 			maxIndex = 2;
-			maxVal = m_z;
-		}
-		if (m_unusedW > maxVal)
+			maxVal = m_floats[2];
+		}
+		if (m_floats[3] > maxVal)
 		{
 			maxIndex = 3;
-			maxVal = m_unusedW;
+			maxVal = m_floats[3];
 		}
 		
@@ -372,23 +425,23 @@
 		int minIndex = -1;
 		btScalar minVal = btScalar(1e30);
-		if (m_x < minVal)
+		if (m_floats[0] < minVal)
 		{
 			minIndex = 0;
-			minVal = m_x;
-		}
-		if (m_y < minVal)
+			minVal = m_floats[0];
+		}
+		if (m_floats[1] < minVal)
 		{
 			minIndex = 1;
-			minVal = m_y;
-		}
-		if (m_z < minVal)
+			minVal = m_floats[1];
+		}
+		if (m_floats[2] < minVal)
 		{
 			minIndex = 2;
-			minVal = m_z;
-		}
-		if (m_unusedW < minVal)
+			minVal = m_floats[2];
+		}
+		if (m_floats[3] < minVal)
 		{
 			minIndex = 3;
-			minVal = m_unusedW;
+			minVal = m_floats[3];
 		}
 		
Index: code/branches/physics/src/bullet/VERSION
===================================================================
--- code/branches/physics/src/bullet/VERSION	(revision 2192)
+++ code/branches/physics/src/bullet/VERSION	(revision 2430)
@@ -1,2 +1,1 @@
-Bullet Collision Detection and Physics Library version 2.72
-http://bullet.googlecode.com
+2.73
