Index: code/trunk/src/external/bullet/BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.cpp
===================================================================
--- code/trunk/src/external/bullet/BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.cpp	(revision 8351)
+++ code/trunk/src/external/bullet/BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.cpp	(revision 8393)
@@ -23,4 +23,5 @@
 #include "btGjkPairDetector.h"
 #include "btPointCollector.h"
+#include "BulletCollision/CollisionShapes/btStaticPlaneShape.h"
 
 
@@ -29,11 +30,62 @@
 :m_simplexSolver(simplexSolver),
 m_penetrationDepthSolver(penetrationDepthSolver),
-m_convexA(convexA),m_convexB(convexB)
-{
-}
+m_convexA(convexA),m_convexB1(convexB),m_planeShape(0)
+{
+}
+
+
+btContinuousConvexCollision::btContinuousConvexCollision( const btConvexShape*	convexA,const btStaticPlaneShape*	plane)
+:m_simplexSolver(0),
+m_penetrationDepthSolver(0),
+m_convexA(convexA),m_convexB1(0),m_planeShape(plane)
+{
+}
+
 
 /// This maximum should not be necessary. It allows for untested/degenerate cases in production code.
 /// You don't want your game ever to lock-up.
 #define MAX_ITERATIONS 64
+
+void btContinuousConvexCollision::computeClosestPoints( const btTransform& transA, const btTransform& transB,btPointCollector& pointCollector)
+{
+	if (m_convexB1)
+	{
+		m_simplexSolver->reset();
+		btGjkPairDetector gjk(m_convexA,m_convexB1,m_convexA->getShapeType(),m_convexB1->getShapeType(),m_convexA->getMargin(),m_convexB1->getMargin(),m_simplexSolver,m_penetrationDepthSolver);		
+		btGjkPairDetector::ClosestPointInput input;
+		input.m_transformA = transA;
+		input.m_transformB = transB;
+		gjk.getClosestPoints(input,pointCollector,0);
+	} else
+	{
+		//convex versus plane
+		const btConvexShape* convexShape = m_convexA;
+		const btStaticPlaneShape* planeShape = m_planeShape;
+		
+		bool hasCollision = false;
+		const btVector3& planeNormal = planeShape->getPlaneNormal();
+		const btScalar& planeConstant = planeShape->getPlaneConstant();
+		
+		btTransform convexWorldTransform = transA;
+		btTransform convexInPlaneTrans;
+		convexInPlaneTrans= transB.inverse() * convexWorldTransform;
+		btTransform planeInConvex;
+		planeInConvex= convexWorldTransform.inverse() * transB;
+		
+		btVector3 vtx = convexShape->localGetSupportingVertex(planeInConvex.getBasis()*-planeNormal);
+
+		btVector3 vtxInPlane = convexInPlaneTrans(vtx);
+		btScalar distance = (planeNormal.dot(vtxInPlane) - planeConstant);
+
+		btVector3 vtxInPlaneProjected = vtxInPlane - distance*planeNormal;
+		btVector3 vtxInPlaneWorld = transB * vtxInPlaneProjected;
+		btVector3 normalOnSurfaceB = transB.getBasis() * planeNormal;
+
+		pointCollector.addContactPoint(
+			normalOnSurfaceB,
+			vtxInPlaneWorld,
+			distance);
+	}
+}
 
 bool	btContinuousConvexCollision::calcTimeOfImpact(
@@ -45,5 +97,4 @@
 {
 
-	m_simplexSolver->reset();
 
 	/// compute linear and angular velocity for this interval, to interpolate
@@ -54,5 +105,5 @@
 
 	btScalar boundingRadiusA = m_convexA->getAngularMotionDisc();
-	btScalar boundingRadiusB = m_convexB->getAngularMotionDisc();
+	btScalar boundingRadiusB = m_convexB1?m_convexB1->getAngularMotionDisc():0.f;
 
 	btScalar maxAngularProjectedVelocity = angVelA.length() * boundingRadiusA + angVelB.length() * boundingRadiusB;
@@ -65,5 +116,4 @@
 
 
-	btScalar radius = btScalar(0.001);
 
 	btScalar lambda = btScalar(0.);
@@ -84,11 +134,5 @@
 
 
-	btTransform identityTrans;
-	identityTrans.setIdentity();
-
-	btSphereShape	raySphere(btScalar(0.0));
-	raySphere.setMargin(btScalar(0.));
-
-
+	btScalar radius = 0.001f;
 //	result.drawCoordSystem(sphereTr);
 
@@ -96,14 +140,6 @@
 
 	{
-		
-		btGjkPairDetector gjk(m_convexA,m_convexB,m_convexA->getShapeType(),m_convexB->getShapeType(),m_convexA->getMargin(),m_convexB->getMargin(),m_simplexSolver,m_penetrationDepthSolver);		
-		btGjkPairDetector::ClosestPointInput input;
 	
-		//we don't use margins during CCD
-	//	gjk.setIgnoreMargin(true);
-
-		input.m_transformA = fromA;
-		input.m_transformB = fromB;
-		gjk.getClosestPoints(input,pointCollector1,0);
+		computeClosestPoints(fromA,fromB,pointCollector1);
 
 		hasResult = pointCollector1.m_hasResult;
@@ -114,9 +150,10 @@
 	{
 		btScalar dist;
-		dist = pointCollector1.m_distance;
+		dist = pointCollector1.m_distance + result.m_allowedPenetration;
 		n = pointCollector1.m_normalOnBInWorld;
-
 		btScalar projectedLinearVelocity = relLinVel.dot(n);
-		
+		if ((projectedLinearVelocity+ maxAngularProjectedVelocity)<=SIMD_EPSILON)
+			return false;
+
 		//not close enough
 		while (dist > radius)
@@ -126,17 +163,8 @@
 				result.m_debugDrawer->drawSphere(c,0.2f,btVector3(1,1,1));
 			}
-			numIter++;
-			if (numIter > maxIter)
-			{
-				return false; //todo: report a failure
-			}
 			btScalar dLambda = btScalar(0.);
 
 			projectedLinearVelocity = relLinVel.dot(n);
 
-			//calculate safe moving fraction from distance / (linear+rotational velocity)
-			
-			//btScalar clippedDist  = GEN_min(angularConservativeRadius,dist);
-			//btScalar clippedDist  = dist;
 			
 			//don't report time of impact for motion away from the contact normal (or causes minor penetration)
@@ -183,35 +211,25 @@
 
 			btPointCollector	pointCollector;
-			btGjkPairDetector gjk(m_convexA,m_convexB,m_simplexSolver,m_penetrationDepthSolver);
-			btGjkPairDetector::ClosestPointInput input;
-			input.m_transformA = interpolatedTransA;
-			input.m_transformB = interpolatedTransB;
-			gjk.getClosestPoints(input,pointCollector,0);
+			computeClosestPoints(interpolatedTransA,interpolatedTransB,pointCollector);
+
 			if (pointCollector.m_hasResult)
 			{
-				if (pointCollector.m_distance < btScalar(0.))
-				{
-					//degenerate ?!
-					result.m_fraction = lastLambda;
-					n = pointCollector.m_normalOnBInWorld;
-					result.m_normal=n;//.setValue(1,1,1);// = n;
-					result.m_hitPoint = pointCollector.m_pointInWorld;
-					return true;
-				}
+				dist = pointCollector.m_distance+result.m_allowedPenetration;
 				c = pointCollector.m_pointInWorld;		
 				n = pointCollector.m_normalOnBInWorld;
-				dist = pointCollector.m_distance;
 			} else
 			{
-				//??
-				return false;
-			}
-			
-
+				result.reportFailure(-1, numIter);
+				return false;
+			}
+
+			numIter++;
+			if (numIter > maxIter)
+			{
+				result.reportFailure(-2, numIter);
+				return false;
+			}
 		}
 	
-		if ((projectedLinearVelocity+ maxAngularProjectedVelocity)<=result.m_allowedPenetration)//SIMD_EPSILON)
-			return false;
-			
 		result.m_fraction = lambda;
 		result.m_normal = n;
@@ -222,15 +240,4 @@
 	return false;
 
-/*
-//todo:
-	//if movement away from normal, discard result
-	btVector3 move = transBLocalTo.getOrigin() - transBLocalFrom.getOrigin();
-	if (result.m_fraction < btScalar(1.))
-	{
-		if (move.dot(result.m_normal) <= btScalar(0.))
-		{
-		}
-	}
-*/
-
-}
+}
+
