public void CollidePolygonAndCircle(Manifold manifold, PolygonShape polygon, Transform xfA, CircleShape circle, Transform xfB)
{
manifold.PointCount = 0;
//Vec2 v = circle.m_p;
// Compute circle position in the frame of the polygon.
// before inline:
Transform.MulToOut(xfB, circle.P, C);
Transform.MulTransToOut(xfA, C, C_LOCAL);
float cLocalx = C_LOCAL.X;
float cLocaly = C_LOCAL.Y;
// after inline:
// final float cy = xfB.p.y + xfB.q.ex.y * v.x + xfB.q.ey.y * v.y;
// final float cx = xfB.p.x + xfB.q.ex.x * v.x + xfB.q.ey.x * v.y;
// final float v1x = cx - xfA.p.x;
// final float v1y = cy - xfA.p.y;
// final Vec2 b = xfA.q.ex;
// final Vec2 b1 = xfA.q.ey;
// final float cLocaly = v1x * b1.x + v1y * b1.y;
// final float cLocalx = v1x * b.x + v1y * b.y;
// end inline
// Find the min separating edge.
int normalIndex = 0;
//UPGRADE_TODO: The equivalent in .NET for field 'java.lang.Float.MIN_VALUE' may return a different value. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1043'"
float separation = Single.Epsilon;
float radius = polygon.Radius + circle.Radius;
int vertexCount = polygon.VertexCount;
Vec2[] vertices = polygon.Vertices;
Vec2[] normals = polygon.Normals;
for (int i = 0; i < vertexCount; i++)
{
// before inline
// temp.set(cLocal).subLocal(vertices[i]);
// float s = Vec2.dot(normals[i], temp);
// after inline
Vec2 vertex = vertices[i];
float tempx = cLocalx - vertex.X;
float tempy = cLocaly - vertex.Y;
Vec2 normal = normals[i];
float s = normal.X * tempx + normal.Y * tempy;
if (s > radius)
{
// early out
return;
}
if (s > separation)
{
separation = s;
normalIndex = i;
}
}
// Vertices that subtend the incident face.
int vertIndex1 = normalIndex;
int vertIndex2 = vertIndex1 + 1 < vertexCount ? vertIndex1 + 1 : 0;
Vec2 v1 = vertices[vertIndex1];
Vec2 v2 = vertices[vertIndex2];
// If the center is inside the polygon ...
if (separation < Settings.EPSILON)
{
manifold.PointCount = 1;
manifold.Type = Manifold.ManifoldType.FaceA;
// before inline:
// manifold.localNormal.set(normals[normalIndex]);
// manifold.localPoint.set(v1).addLocal(v2).mulLocal(.5f);
// manifold.points[0].localPoint.set(circle.m_p);
// after inline:
Vec2 normal = normals[normalIndex];
manifold.LocalNormal.X = normal.X;
manifold.LocalNormal.Y = normal.Y;
manifold.LocalPoint.X = (v1.X + v2.X) * .5f;
manifold.LocalPoint.Y = (v1.Y + v2.Y) * .5f;
ManifoldPoint mpoint = manifold.Points[0];
mpoint.LocalPoint.X = circle.P.X;
mpoint.LocalPoint.Y = circle.P.Y;
mpoint.Id.Zero();
// end inline
return;
}
// Compute barycentric coordinates
// before inline:
// temp.set(cLocal).subLocal(v1);
// temp2.set(v2).subLocal(v1);
// float u1 = Vec2.dot(temp, temp2);
// temp.set(cLocal).subLocal(v2);
// temp2.set(v1).subLocal(v2);
// float u2 = Vec2.dot(temp, temp2);
// after inline:
float tempX = cLocalx - v1.X;
float tempY = cLocaly - v1.Y;
float temp2X = v2.X - v1.X;
float temp2Y = v2.Y - v1.Y;
float u1 = tempX * temp2X + tempY * temp2Y;
float temp3X = cLocalx - v2.X;
float temp3Y = cLocaly - v2.Y;
float temp4X = v1.X - v2.X;
float temp4Y = v1.Y - v2.Y;
float u2 = temp3X * temp4X + temp3Y * temp4Y;
// end inline
if (u1 <= 0f)
{
// inlined
float dx = cLocalx - v1.X;
float dy = cLocaly - v1.Y;
if (dx * dx + dy * dy > radius * radius)
{
return;
}
manifold.PointCount = 1;
manifold.Type = Manifold.ManifoldType.FaceA;
// before inline:
// manifold.localNormal.set(cLocal).subLocal(v1);
// after inline:
manifold.LocalNormal.X = cLocalx - v1.X;
manifold.LocalNormal.Y = cLocaly - v1.Y;
// end inline
manifold.LocalNormal.Normalize();
manifold.LocalPoint.Set(v1);
manifold.Points[0].LocalPoint.Set(circle.P);
manifold.Points[0].Id.Zero();
}
else if (u2 <= 0.0f)
{
// inlined
float dx = cLocalx - v2.X;
float dy = cLocaly - v2.Y;
if (dx * dx + dy * dy > radius * radius)
{
return;
}
manifold.PointCount = 1;
manifold.Type = Manifold.ManifoldType.FaceA;
// before inline:
// manifold.localNormal.set(cLocal).subLocal(v2);
// after inline:
manifold.LocalNormal.X = cLocalx - v2.X;
manifold.LocalNormal.Y = cLocaly - v2.Y;
// end inline
manifold.LocalNormal.Normalize();
manifold.LocalPoint.Set(v2);
manifold.Points[0].LocalPoint.Set(circle.P);
manifold.Points[0].Id.Zero();
}
else
{
// Vec2 faceCenter = 0.5f * (v1 + v2);
// (temp is faceCenter)
// before inline:
// temp.set(v1).addLocal(v2).mulLocal(.5f);
//
// temp2.set(cLocal).subLocal(temp);
// separation = Vec2.dot(temp2, normals[vertIndex1]);
// if (separation > radius) {
// return;
// }
// after inline:
float fcx = (v1.X + v2.X) * .5f;
float fcy = (v1.Y + v2.Y) * .5f;
float tx = cLocalx - fcx;
float ty = cLocaly - fcy;
Vec2 normal = normals[vertIndex1];
separation = tx * normal.X + ty * normal.Y;
if (separation > radius)
{
return;
}
// end inline
manifold.PointCount = 1;
manifold.Type = Manifold.ManifoldType.FaceA;
manifold.LocalNormal.Set(normals[vertIndex1]);
manifold.LocalPoint.X = fcx; // (faceCenter)
manifold.LocalPoint.Y = fcy;
manifold.Points[0].LocalPoint.Set(circle.P);
manifold.Points[0].Id.Zero();
}
}