public static int ClipSegmentToLine(ClipVertex[] vOut, ClipVertex[] vIn,
							  Vector3 normal, float offset)
		{
			// Start with no output points
			int numOut = 0;

			// Calculate the distance of end points to the line
			float distance0 = Vector3.Dot(normal, vIn[0].v) - offset;
			float distance1 = Vector3.Dot(normal, vIn[1].v) - offset;

			// If the points are behind the plane
			if (distance0 <= 0.0f) vOut[numOut++] = vIn[0];
			if (distance1 <= 0.0f) vOut[numOut++] = vIn[1];

			// If the points are on different sides of the plane
			if (distance0 * distance1 < 0.0f)
			{
				// Find intersection point of edge and plane
				float interp = distance0 / (distance0 - distance1);
				vOut[numOut].v = vIn[0].v + interp * (vIn[1].v - vIn[0].v);
				if (distance0 > 0.0f)
				{
					vOut[numOut].id = vIn[0].id;
				}
				else
				{
					vOut[numOut].id = vIn[1].id;
				}
				++numOut;
			}

			return numOut;
		}
		static void FindIncidentEdge(ClipVertex[] c,
									 Box2dShape poly1, ref Matrix xf1, int edge1,
									 Box2dShape poly2, ref Matrix xf2)
		{
			Vector3[] normals1 = poly1.GetNormals();

			int count2 = poly2.GetVertexCount();
			Vector3[] vertices2 = poly2.GetVertices();
			Vector3[] normals2 = poly2.GetNormals();

			Debug.Assert(0 <= edge1 && edge1 < poly1.GetVertexCount());

			// Get the normal of the reference edge in poly2's frame.
			Vector3 normal1 = Vector3.TransformNormal(Vector3.TransformNormal(normals1[edge1],xf1),MathUtil.TransposeBasis(xf2));
			
			// Find the incident edge on poly2.
			int index = 0;
			float minDot = MathUtil.BT_LARGE_FLOAT;
			for (int i = 0; i < count2; ++i)
			{
				float dot = Vector3.Dot(normal1, normals2[i]);
				if (dot < minDot)
				{
					minDot = dot;
					index = i;
				}
			}

			// Build the clip vertices for the incident edge.
			int i1 = index;
			int i2 = i1 + 1 < count2 ? i1 + 1 : 0;

			c[0].v = Vector3.Transform(vertices2[i1],xf2);
		//	c[0].id.features.referenceEdge = (unsigned char)edge1;
		//	c[0].id.features.incidentEdge = (unsigned char)i1;
		//	c[0].id.features.incidentVertex = 0;

			c[1].v = Vector3.Transform(vertices2[i2],xf2);
		//	c[1].id.features.referenceEdge = (unsigned char)edge1;
		//	c[1].id.features.incidentEdge = (unsigned char)i2;
		//	c[1].id.features.incidentVertex = 1;
		}
		void B2CollidePolygons(ref ManifoldResult manifold,
							  Box2dShape polyA, ref Matrix xfA,
							  Box2dShape polyB, ref Matrix xfB)
		{

			int edgeA = 0;
			float separationA = FindMaxSeparation(ref edgeA, polyA, ref xfA, polyB, ref xfB);
			if (separationA > 0.0f)
			{
				return;
			}

			int edgeB = 0;
			float separationB = FindMaxSeparation(ref edgeB, polyB, ref xfB, polyA, ref xfA);
			if (separationB > 0.0f)
			{
				return;
			}

			Box2dShape poly1;	// reference poly
			Box2dShape poly2;	// incident poly
			Matrix xf1, xf2;
			int edge1;		// reference edge
			bool flip;
			const float k_relativeTol = 0.98f;
			const float k_absoluteTol = 0.001f;

			// TODO_ERIN use "radius" of poly for absolute tolerance.
			if (separationB > k_relativeTol * separationA + k_absoluteTol)
			{
				poly1 = polyB;
				poly2 = polyA;
				xf1 = xfB;
				xf2 = xfA;
				edge1 = edgeB;
				flip = true;
			}
			else
			{
				poly1 = polyA;
				poly2 = polyB;
				xf1 = xfA;
				xf2 = xfB;
				edge1 = edgeA;
				flip = false;
			}

			ClipVertex[] incidentEdge = new ClipVertex[2];
			FindIncidentEdge(incidentEdge, poly1, ref xf1, edge1, poly2, ref xf2);

			int count1 = poly1.GetVertexCount();
			Vector3[] vertices1 = poly1.GetVertices();

			Vector3 v11 = vertices1[edge1];
			Vector3 v12 = edge1 + 1 < count1 ? vertices1[edge1+1] : vertices1[0];

			Vector3 dv = v12 - v11;
			Vector3 sideNormal = Vector3.TransformNormal( v12 - v11,xf1);
			sideNormal.Normalize();
			Vector3 frontNormal = CrossS(ref sideNormal, 1.0f);
			
			v11 = Vector3.Transform(v11,xf1);
			v12 = Vector3.Transform(v12,xf1);

			float frontOffset = Vector3.Dot(frontNormal, v11);
			float sideOffset1 = -Vector3.Dot(sideNormal, v11);
			float sideOffset2 = Vector3.Dot(sideNormal, v12);

			// Clip incident edge against extruded edge1 side edges.
			ClipVertex[] clipPoints1 = new ClipVertex[2];
			clipPoints1[0].v = Vector3.Zero;
			clipPoints1[1].v = Vector3.Zero;

			ClipVertex[] clipPoints2 = new ClipVertex[2];
			clipPoints2[0].v = Vector3.Zero;
			clipPoints2[1].v = Vector3.Zero;


			int np;

			// Clip to box side 1
			np = ClipSegmentToLine(clipPoints1, incidentEdge, -sideNormal, sideOffset1);

			if (np < 2)
			{
				return;
			}

			// Clip to negative box side 1
			np = ClipSegmentToLine(clipPoints2, clipPoints1,  sideNormal, sideOffset2);

			if (np < 2)
			{
				return;
			}

			// Now clipPoints2 contains the clipped points.
			Vector3 manifoldNormal = flip ? -frontNormal : frontNormal;

			int pointCount = 0;
			for (int i = 0; i < b2_maxManifoldPoints; ++i)
			{
				float separation = Vector3.Dot(frontNormal, clipPoints2[i].v) - frontOffset;

				if (separation <= 0.0f)
				{
					
					//b2ManifoldPoint* cp = manifold.points + pointCount;
					//float separation = separation;
					//cp.localPoint1 = b2MulT(xfA, clipPoints2[i].v);
					//cp.localPoint2 = b2MulT(xfB, clipPoints2[i].v);

					manifold.AddContactPoint(-manifoldNormal,clipPoints2[i].v,separation);

		//			cp.id = clipPoints2[i].id;
		//			cp.id.features.flip = flip;
					++pointCount;
				}
			}

		//	manifold.pointCount = pointCount;}
		}