public virtual void ProcessTriangle(ObjectArray<Vector3> triangle, int partId, int triangleIndex)
		{
			TriangleShape triangleShape = new TriangleShape(triangle[0], triangle[1], triangle[2]);
			triangleShape.Margin = m_triangleCollisionMargin;

			VoronoiSimplexSolver simplexSolver = new VoronoiSimplexSolver();
			GjkEpaPenetrationDepthSolver gjkEpaPenetrationSolver = new GjkEpaPenetrationDepthSolver();

			//#define  USE_SUBSIMPLEX_CONVEX_CAST 1
			//if you reenable USE_SUBSIMPLEX_CONVEX_CAST see commented ref code below
#if USE_SUBSIMPLEX_CONVEX_CAST
	        SubsimplexConvexCast convexCaster = new SubsimplexConvexCast(m_convexShape, triangleShape, simplexSolver);
#else
			//btGjkConvexCast	convexCaster(m_convexShape,&triangleShape,&simplexSolver);
			ContinuousConvexCollision convexCaster = new ContinuousConvexCollision(m_convexShape,triangleShape,simplexSolver,gjkEpaPenetrationSolver);
#endif //#USE_SUBSIMPLEX_CONVEX_CAST
	
			CastResult castResult = new CastResult();
			castResult.m_fraction = 1f;
			if (convexCaster.CalcTimeOfImpact(ref m_convexShapeFrom,ref m_convexShapeTo,ref m_triangleToWorld, ref m_triangleToWorld, castResult))
			{
				//add hit
				if (castResult.m_normal.LengthSquared() > 0.0001f)
				{					
					if (castResult.m_fraction < m_hitFraction)
					{
						/* btContinuousConvexCast's normal is already in world space */
						/*
                        #ifdef USE_SUBSIMPLEX_CONVEX_CAST
				                        //rotate normal into worldspace
				                        castResult.m_normal = m_convexShapeFrom.getBasis() * castResult.m_normal;
                        #endif //USE_SUBSIMPLEX_CONVEX_CAST
                        */
						castResult.m_normal.Normalize();

						ReportHit (ref castResult.m_normal,ref castResult.m_hitPoint,castResult.m_fraction,partId,triangleIndex);
					}
				}
			}
		}
		public void ProcessTriangle(ObjectArray<Vector3> triangle, int partId, int triangleIndex)
		{
			//do a swept sphere for now
			Matrix ident = Matrix.Identity;
			CastResult castResult = new CastResult();
			castResult.m_fraction = m_hitFraction;
			SphereShape	pointShape = new SphereShape(m_ccdSphereRadius);
			TriangleShape triShape = new TriangleShape(triangle[0],triangle[1],triangle[2]);
			VoronoiSimplexSolver	simplexSolver = new VoronoiSimplexSolver();
			SubSimplexConvexCast convexCaster = new SubSimplexConvexCast(pointShape,triShape,simplexSolver);
			//GjkConvexCast	convexCaster(&pointShape,convexShape,&simplexSolver);
			//ContinuousConvexCollision convexCaster(&pointShape,convexShape,&simplexSolver,0);
			//local space?

			if (convexCaster.CalcTimeOfImpact(ref m_ccdSphereFromTrans,ref m_ccdSphereToTrans,
			                                  ref ident,ref ident,castResult))
			{
				if (m_hitFraction > castResult.m_fraction)
				{
					m_hitFraction = castResult.m_fraction;
				}
			}

		}
 public SphereTriangleDetector(SphereShape sphere,TriangleShape triangle, float contactBreakingThreshold)
 {
     m_sphere = sphere;
     m_triangle = triangle;
     m_contactBreakingThreshold = contactBreakingThreshold;
 }
		public virtual void ProcessTriangle(ObjectArray<Vector3> triangle, int partId, int triangleIndex)
		{
			//aabb filter is already applied!	
			CollisionAlgorithmConstructionInfo ci = new CollisionAlgorithmConstructionInfo();
			ci.SetDispatcher(m_dispatcher);

			CollisionObject ob = (CollisionObject)m_triBody;
        	
			///debug drawing of the overlapping triangles
			///

			if (m_dispatchInfoPtr != null && m_dispatchInfoPtr.getDebugDraw() != null&& ((m_dispatchInfoPtr.getDebugDraw().GetDebugMode() & DebugDrawModes.DBG_DrawWireframe) > 0))
			{
				Vector3 color = new Vector3(1,1,0);
				Matrix tr = ob.GetWorldTransform();
				Vector3[] transformedTriangles = new Vector3[3];
				for(int i=0;i<transformedTriangles.Length;++i)
				{
					transformedTriangles[i] = Vector3.Transform(triangle[i],tr);
				}
				m_dispatchInfoPtr.getDebugDraw().DrawLine(ref transformedTriangles[0], ref transformedTriangles[1], ref color);
				m_dispatchInfoPtr.getDebugDraw().DrawLine(ref transformedTriangles[1], ref transformedTriangles[2], ref color);
				m_dispatchInfoPtr.getDebugDraw().DrawLine(ref transformedTriangles[2], ref transformedTriangles[0], ref color);

			}

			if (m_convexBody.GetCollisionShape().IsConvex())
			{
				TriangleShape tm = new TriangleShape(triangle[0],triangle[1],triangle[2]);	
				tm.Margin = m_collisionMarginTriangle;
        		
				CollisionShape tmpShape = ob.GetCollisionShape();
				ob.InternalSetTemporaryCollisionShape(tm);
        		
				CollisionAlgorithm colAlgo = ci.GetDispatcher().FindAlgorithm(m_convexBody,m_triBody,m_manifoldPtr);
				///this should use the btDispatcher, so the actual registered algorithm is used
				//		btConvexConvexAlgorithm cvxcvxalgo(m_manifoldPtr,ci,m_convexBody,m_triBody);

				if (m_resultOut.GetBody0Internal() == m_triBody)
				{
					m_resultOut.SetShapeIdentifiersA(partId, triangleIndex);
				}
				else
				{
					m_resultOut.SetShapeIdentifiersB(partId, triangleIndex);
				}

				colAlgo.ProcessCollision(m_convexBody,m_triBody,m_dispatchInfoPtr, m_resultOut);
				colAlgo.Cleanup();
				ci.GetDispatcher().FreeCollisionAlgorithm(colAlgo);
				colAlgo = null;

				ob.InternalSetTemporaryCollisionShape( tmpShape);
			}
		}