Index: code/trunk/src/external/bullet/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp
===================================================================
--- code/trunk/src/external/bullet/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp	(revision 8351)
+++ code/trunk/src/external/bullet/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp	(revision 8393)
@@ -36,4 +36,6 @@
 #include "BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.h"
 #include "BulletDynamics/ConstraintSolver/btSliderConstraint.h"
+#include "BulletDynamics/ConstraintSolver/btContactConstraint.h"
+
 
 #include "LinearMath/btIDebugDraw.h"
@@ -46,4 +48,11 @@
 
 #include "LinearMath/btSerializer.h"
+
+#if 0
+btAlignedObjectArray<btVector3> debugContacts;
+btAlignedObjectArray<btVector3> debugNormals;
+int startHit=2;
+int firstHit=startHit;
+#endif
 
 
@@ -315,6 +324,11 @@
 	dispatchInfo.m_debugDraw = getDebugDrawer();
 
+
 	///perform collision detection
 	performDiscreteCollisionDetection();
+
+	if (getDispatchInfo().m_useContinuous)
+		addSpeculativeContacts(timeStep);
+
 
 	calculateSimulationIslands();
@@ -746,9 +760,10 @@
 class btClosestNotMeConvexResultCallback : public btCollisionWorld::ClosestConvexResultCallback
 {
+public:
+
 	btCollisionObject* m_me;
 	btScalar m_allowedPenetration;
 	btOverlappingPairCache* m_pairCache;
 	btDispatcher* m_dispatcher;
-
 
 public:
@@ -798,4 +813,5 @@
 		if (m_dispatcher->needsResponse(m_me,otherObj))
 		{
+#if 0
 			///don't do CCD when there are already contact points (touching contact/penetration)
 			btAlignedObjectArray<btPersistentManifold*> manifoldArray;
@@ -815,6 +831,9 @@
 				}
 			}
-		}
-		return true;
+#endif
+			return true;
+		}
+
+		return false;
 	}
 
@@ -825,5 +844,4 @@
 int gNumClampedCcdMotions=0;
 
-//#include "stdio.h"
 void	btDiscreteDynamicsWorld::integrateTransforms(btScalar timeStep)
 {
@@ -837,4 +855,107 @@
 		if (body->isActive() && (!body->isStaticOrKinematicObject()))
 		{
+
+			body->predictIntegratedTransform(timeStep, predictedTrans);
+			
+			btScalar squareMotion = (predictedTrans.getOrigin()-body->getWorldTransform().getOrigin()).length2();
+
+			
+
+			if (getDispatchInfo().m_useContinuous && body->getCcdSquareMotionThreshold() && body->getCcdSquareMotionThreshold() < squareMotion)
+			{
+				BT_PROFILE("CCD motion clamping");
+				if (body->getCollisionShape()->isConvex())
+				{
+					gNumClampedCcdMotions++;
+#ifdef USE_STATIC_ONLY
+					class StaticOnlyCallback : public btClosestNotMeConvexResultCallback
+					{
+					public:
+
+						StaticOnlyCallback (btCollisionObject* me,const btVector3& fromA,const btVector3& toA,btOverlappingPairCache* pairCache,btDispatcher* dispatcher) : 
+						  btClosestNotMeConvexResultCallback(me,fromA,toA,pairCache,dispatcher)
+						{
+						}
+
+					  	virtual bool needsCollision(btBroadphaseProxy* proxy0) const
+						{
+							btCollisionObject* otherObj = (btCollisionObject*) proxy0->m_clientObject;
+							if (!otherObj->isStaticOrKinematicObject())
+								return false;
+							return btClosestNotMeConvexResultCallback::needsCollision(proxy0);
+						}
+					};
+
+					StaticOnlyCallback sweepResults(body,body->getWorldTransform().getOrigin(),predictedTrans.getOrigin(),getBroadphase()->getOverlappingPairCache(),getDispatcher());
+#else
+					btClosestNotMeConvexResultCallback sweepResults(body,body->getWorldTransform().getOrigin(),predictedTrans.getOrigin(),getBroadphase()->getOverlappingPairCache(),getDispatcher());
+#endif
+					//btConvexShape* convexShape = static_cast<btConvexShape*>(body->getCollisionShape());
+					btSphereShape tmpSphere(body->getCcdSweptSphereRadius());//btConvexShape* convexShape = static_cast<btConvexShape*>(body->getCollisionShape());
+					sweepResults.m_allowedPenetration=getDispatchInfo().m_allowedCcdPenetration;
+
+					sweepResults.m_collisionFilterGroup = body->getBroadphaseProxy()->m_collisionFilterGroup;
+					sweepResults.m_collisionFilterMask  = body->getBroadphaseProxy()->m_collisionFilterMask;
+					btTransform modifiedPredictedTrans = predictedTrans;
+					modifiedPredictedTrans.setBasis(body->getWorldTransform().getBasis());
+
+					convexSweepTest(&tmpSphere,body->getWorldTransform(),modifiedPredictedTrans,sweepResults);
+					if (sweepResults.hasHit() && (sweepResults.m_closestHitFraction < 1.f))
+					{
+						
+						//printf("clamped integration to hit fraction = %f\n",fraction);
+						body->setHitFraction(sweepResults.m_closestHitFraction);
+						body->predictIntegratedTransform(timeStep*body->getHitFraction(), predictedTrans);
+						body->setHitFraction(0.f);
+						body->proceedToTransform( predictedTrans);
+
+#if 0
+						btVector3 linVel = body->getLinearVelocity();
+
+						btScalar maxSpeed = body->getCcdMotionThreshold()/getSolverInfo().m_timeStep;
+						btScalar maxSpeedSqr = maxSpeed*maxSpeed;
+						if (linVel.length2()>maxSpeedSqr)
+						{
+							linVel.normalize();
+							linVel*= maxSpeed;
+							body->setLinearVelocity(linVel);
+							btScalar ms2 = body->getLinearVelocity().length2();
+							body->predictIntegratedTransform(timeStep, predictedTrans);
+
+							btScalar sm2 = (predictedTrans.getOrigin()-body->getWorldTransform().getOrigin()).length2();
+							btScalar smt = body->getCcdSquareMotionThreshold();
+							printf("sm2=%f\n",sm2);
+						}
+#else
+						//response  between two dynamic objects without friction, assuming 0 penetration depth
+						btScalar appliedImpulse = 0.f;
+						btScalar depth = 0.f;
+						appliedImpulse = resolveSingleCollision(body,sweepResults.m_hitCollisionObject,sweepResults.m_hitPointWorld,sweepResults.m_hitNormalWorld,getSolverInfo(), depth);
+						
+
+#endif
+
+        				continue;
+					}
+				}
+			}
+			
+
+			body->proceedToTransform( predictedTrans);
+		}
+	}
+}
+
+void	btDiscreteDynamicsWorld::addSpeculativeContacts(btScalar timeStep)
+{
+	BT_PROFILE("addSpeculativeContacts");
+	btTransform predictedTrans;
+	for ( int i=0;i<m_nonStaticRigidBodies.size();i++)
+	{
+		btRigidBody* body = m_nonStaticRigidBodies[i];
+		body->setHitFraction(1.f);
+
+		if (body->isActive() && (!body->isStaticOrKinematicObject()))
+		{
 			body->predictIntegratedTransform(timeStep, predictedTrans);
 			btScalar squareMotion = (predictedTrans.getOrigin()-body->getWorldTransform().getOrigin()).length2();
@@ -842,5 +963,5 @@
 			if (body->getCcdSquareMotionThreshold() && body->getCcdSquareMotionThreshold() < squareMotion)
 			{
-				BT_PROFILE("CCD motion clamping");
+				BT_PROFILE("search speculative contacts");
 				if (body->getCollisionShape()->isConvex())
 				{
@@ -853,17 +974,82 @@
 					sweepResults.m_collisionFilterGroup = body->getBroadphaseProxy()->m_collisionFilterGroup;
 					sweepResults.m_collisionFilterMask  = body->getBroadphaseProxy()->m_collisionFilterMask;
-
-					convexSweepTest(&tmpSphere,body->getWorldTransform(),predictedTrans,sweepResults);
+					btTransform modifiedPredictedTrans;
+					modifiedPredictedTrans = predictedTrans;
+					modifiedPredictedTrans.setBasis(body->getWorldTransform().getBasis());
+
+					convexSweepTest(&tmpSphere,body->getWorldTransform(),modifiedPredictedTrans,sweepResults);
 					if (sweepResults.hasHit() && (sweepResults.m_closestHitFraction < 1.f))
 					{
-						body->setHitFraction(sweepResults.m_closestHitFraction);
-						body->predictIntegratedTransform(timeStep*body->getHitFraction(), predictedTrans);
-						body->setHitFraction(0.f);
-//							printf("clamped integration to hit fraction = %f\n",fraction);
+						btBroadphaseProxy* proxy0 = body->getBroadphaseHandle();
+						btBroadphaseProxy* proxy1 = sweepResults.m_hitCollisionObject->getBroadphaseHandle();
+						btBroadphasePair* pair = sweepResults.m_pairCache->findPair(proxy0,proxy1);
+						if (pair)
+						{
+							if (pair->m_algorithm)
+							{
+								btManifoldArray contacts;
+								pair->m_algorithm->getAllContactManifolds(contacts);
+								if (contacts.size())
+								{
+									btManifoldResult result(body,sweepResults.m_hitCollisionObject);
+									result.setPersistentManifold(contacts[0]);
+
+									btVector3 vec = (modifiedPredictedTrans.getOrigin()-body->getWorldTransform().getOrigin());
+									vec*=sweepResults.m_closestHitFraction;
+									
+									btScalar lenSqr = vec.length2();
+									btScalar depth = 0.f;
+									btVector3 pointWorld = sweepResults.m_hitPointWorld;
+									if (lenSqr>SIMD_EPSILON)
+									{
+										depth = btSqrt(lenSqr);
+										pointWorld -= vec;
+										vec /= depth;
+									}
+
+									if (contacts[0]->getBody0()==body)
+									{
+										result.addContactPoint(sweepResults.m_hitNormalWorld,pointWorld,depth);
+#if 0
+										debugContacts.push_back(sweepResults.m_hitPointWorld);//sweepResults.m_hitPointWorld);
+										debugNormals.push_back(sweepResults.m_hitNormalWorld);
+#endif
+									} else
+									{
+										//swapped
+										result.addContactPoint(-sweepResults.m_hitNormalWorld,pointWorld,depth);
+										//sweepResults.m_hitPointWorld,depth);
+										
+#if 0
+										if (1)//firstHit==1)
+										{
+											firstHit=0;
+											debugNormals.push_back(sweepResults.m_hitNormalWorld);
+											debugContacts.push_back(pointWorld);//sweepResults.m_hitPointWorld);
+											debugNormals.push_back(sweepResults.m_hitNormalWorld);
+											debugContacts.push_back(sweepResults.m_hitPointWorld);
+										}
+										firstHit--;
+#endif
+									}
+								}
+
+							} else
+							{
+								//no algorithm, use dispatcher to create one
+
+							}
+
+
+						} else
+						{
+							//add an overlapping pair
+							//printf("pair missing\n");
+
+						}
 					}
 				}
 			}
 			
-			body->proceedToTransform( predictedTrans);
 		}
 	}
@@ -1010,4 +1196,5 @@
 			}
 			break;
+		case D6_SPRING_CONSTRAINT_TYPE:
 		case D6_CONSTRAINT_TYPE:
 			{
Index: code/trunk/src/external/bullet/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h
===================================================================
--- code/trunk/src/external/bullet/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h	(revision 8351)
+++ code/trunk/src/external/bullet/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h	(revision 8393)
@@ -63,4 +63,6 @@
 	virtual void	integrateTransforms(btScalar timeStep);
 		
+	virtual void	addSpeculativeContacts(btScalar timeStep);
+
 	virtual void	calculateSimulationIslands();
 
Index: code/trunk/src/external/bullet/BulletDynamics/Dynamics/btDynamicsWorld.h
===================================================================
--- code/trunk/src/external/bullet/BulletDynamics/Dynamics/btDynamicsWorld.h	(revision 8351)
+++ code/trunk/src/external/bullet/BulletDynamics/Dynamics/btDynamicsWorld.h	(revision 8393)
@@ -33,5 +33,6 @@
 	BT_SIMPLE_DYNAMICS_WORLD=1,
 	BT_DISCRETE_DYNAMICS_WORLD=2,
-	BT_CONTINUOUS_DYNAMICS_WORLD=3
+	BT_CONTINUOUS_DYNAMICS_WORLD=3,
+	BT_SOFT_RIGID_DYNAMICS_WORLD=4
 };
 
@@ -86,4 +87,6 @@
 
 		virtual void	addRigidBody(btRigidBody* body) = 0;
+
+		virtual void	addRigidBody(btRigidBody* body, short group, short mask) = 0;
 
 		virtual void	removeRigidBody(btRigidBody* body) = 0;
Index: code/trunk/src/external/bullet/BulletDynamics/Dynamics/btRigidBody.cpp
===================================================================
--- code/trunk/src/external/bullet/BulletDynamics/Dynamics/btRigidBody.cpp	(revision 8351)
+++ code/trunk/src/external/bullet/BulletDynamics/Dynamics/btRigidBody.cpp	(revision 8393)
@@ -52,6 +52,6 @@
 	m_totalForce.setValue(btScalar(0.0), btScalar(0.0), btScalar(0.0));
 	m_totalTorque.setValue(btScalar(0.0), btScalar(0.0), btScalar(0.0)),
-	m_linearDamping = btScalar(0.);
-	m_angularDamping = btScalar(0.5);
+    setDamping(constructionInfo.m_linearDamping, constructionInfo.m_angularDamping);
+
 	m_linearSleepingThreshold = constructionInfo.m_linearSleepingThreshold;
 	m_angularSleepingThreshold = constructionInfo.m_angularSleepingThreshold;
@@ -85,5 +85,4 @@
 	
 	setMassProps(constructionInfo.m_mass, constructionInfo.m_localInertia);
-    setDamping(constructionInfo.m_linearDamping, constructionInfo.m_angularDamping);
 	updateInertiaTensor();
 
Index: code/trunk/src/external/bullet/BulletDynamics/Dynamics/btRigidBody.h
===================================================================
--- code/trunk/src/external/bullet/BulletDynamics/Dynamics/btRigidBody.h	(revision 8351)
+++ code/trunk/src/external/bullet/BulletDynamics/Dynamics/btRigidBody.h	(revision 8393)
@@ -14,6 +14,6 @@
 */
 
-#ifndef RIGIDBODY_H
-#define RIGIDBODY_H
+#ifndef BT_RIGIDBODY_H
+#define BT_RIGIDBODY_H
 
 #include "LinearMath/btAlignedObjectArray.h"
@@ -90,5 +90,5 @@
 	
 	int				m_debugBodyId;
-
+	
 
 protected:
@@ -271,10 +271,10 @@
 	}
 
-	const btVector3& getTotalForce()
+	const btVector3& getTotalForce() const
 	{
 		return m_totalForce;
 	};
 
-	const btVector3& getTotalTorque()
+	const btVector3& getTotalTorque() const
 	{
 		return m_totalTorque;
@@ -505,5 +505,5 @@
 	}
 
-	int getNumConstraintRefs()
+	int getNumConstraintRefs() const
 	{
 		return m_constraintRefs.size();
@@ -618,4 +618,5 @@
 
 	void	internalWritebackVelocity(btScalar timeStep);
+
 	
 
@@ -687,4 +688,4 @@
 
 
-#endif
-
+#endif //BT_RIGIDBODY_H
+
Index: code/trunk/src/external/bullet/BulletDynamics/Dynamics/btSimpleDynamicsWorld.cpp
===================================================================
--- code/trunk/src/external/bullet/BulletDynamics/Dynamics/btSimpleDynamicsWorld.cpp	(revision 8351)
+++ code/trunk/src/external/bullet/BulletDynamics/Dynamics/btSimpleDynamicsWorld.cpp	(revision 8393)
@@ -79,5 +79,5 @@
 		infoGlobal.m_timeStep = timeStep;
 		m_constraintSolver->prepareSolve(0,numManifolds);
-		m_constraintSolver->solveGroup(0,0,manifoldPtr, numManifolds,0,0,infoGlobal,m_debugDrawer, m_stackAlloc,m_dispatcher1);
+		m_constraintSolver->solveGroup(&getCollisionObjectArray()[0],getNumCollisionObjects(),manifoldPtr, numManifolds,0,0,infoGlobal,m_debugDrawer, m_stackAlloc,m_dispatcher1);
 		m_constraintSolver->allSolved(infoGlobal,m_debugDrawer, m_stackAlloc);
 	}
@@ -155,4 +155,31 @@
 	}
 }
+
+void	btSimpleDynamicsWorld::addRigidBody(btRigidBody* body, short group, short mask)
+{
+	body->setGravity(m_gravity);
+
+	if (body->getCollisionShape())
+	{
+		addCollisionObject(body,group,mask);
+	}
+}
+
+
+void	btSimpleDynamicsWorld::debugDrawWorld()
+{
+
+}
+				
+void	btSimpleDynamicsWorld::addAction(btActionInterface* action)
+{
+
+}
+
+void	btSimpleDynamicsWorld::removeAction(btActionInterface* action)
+{
+
+}
+
 
 void	btSimpleDynamicsWorld::updateAabbs()
Index: code/trunk/src/external/bullet/BulletDynamics/Dynamics/btSimpleDynamicsWorld.h
===================================================================
--- code/trunk/src/external/bullet/BulletDynamics/Dynamics/btSimpleDynamicsWorld.h	(revision 8351)
+++ code/trunk/src/external/bullet/BulletDynamics/Dynamics/btSimpleDynamicsWorld.h	(revision 8393)
@@ -57,5 +57,13 @@
 	virtual void	addRigidBody(btRigidBody* body);
 
+	virtual void	addRigidBody(btRigidBody* body, short group, short mask);
+
 	virtual void	removeRigidBody(btRigidBody* body);
+
+	virtual void	debugDrawWorld();
+				
+	virtual void	addAction(btActionInterface* action);
+
+	virtual void	removeAction(btActionInterface* action);
 
 	///removeCollisionObject will first check if it is a rigid body, if so call removeRigidBody otherwise call btCollisionWorld::removeCollisionObject
