(61d00a474) v0.9.7.1
This commit is contained in:
@@ -1,4 +1,11 @@
|
||||
/*
|
||||
// Copyright (c) 2017 Kastellanos Nikolaos
|
||||
|
||||
/* Original source Farseer Physics Engine:
|
||||
* Copyright (c) 2014 Ian Qvist, http://farseerphysics.codeplex.com
|
||||
* Microsoft Permissive License (Ms-PL) v1.1
|
||||
*/
|
||||
|
||||
/*
|
||||
* Farseer Physics Engine:
|
||||
* Copyright (c) 2012 Ian Qvist
|
||||
*
|
||||
@@ -26,6 +33,7 @@ using System.Diagnostics;
|
||||
using System.Runtime.InteropServices;
|
||||
using FarseerPhysics.Collision.Shapes;
|
||||
using FarseerPhysics.Common;
|
||||
using FarseerPhysics.Common.Maths;
|
||||
using Microsoft.Xna.Framework;
|
||||
|
||||
namespace FarseerPhysics.Collision
|
||||
@@ -382,8 +390,8 @@ namespace FarseerPhysics.Collision
|
||||
/// <param name="aabb">The aabb.</param>
|
||||
public void Combine(ref AABB aabb)
|
||||
{
|
||||
LowerBound = Vector2.Min(LowerBound, aabb.LowerBound);
|
||||
UpperBound = Vector2.Max(UpperBound, aabb.UpperBound);
|
||||
Vector2.Min(ref LowerBound, ref aabb.LowerBound, out LowerBound);
|
||||
Vector2.Max(ref UpperBound, ref aabb.UpperBound, out UpperBound);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -393,8 +401,8 @@ namespace FarseerPhysics.Collision
|
||||
/// <param name="aabb2">The aabb2.</param>
|
||||
public void Combine(ref AABB aabb1, ref AABB aabb2)
|
||||
{
|
||||
LowerBound = Vector2.Min(aabb1.LowerBound, aabb2.LowerBound);
|
||||
UpperBound = Vector2.Max(aabb1.UpperBound, aabb2.UpperBound);
|
||||
Vector2.Min(ref aabb1.LowerBound, ref aabb2.LowerBound, out LowerBound);
|
||||
Vector2.Max(ref aabb1.UpperBound, ref aabb2.UpperBound, out UpperBound);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -434,15 +442,13 @@ namespace FarseerPhysics.Collision
|
||||
/// <param name="a">The first AABB.</param>
|
||||
/// <param name="b">The second AABB.</param>
|
||||
/// <returns>True if they are overlapping.</returns>
|
||||
|
||||
public static bool TestOverlap(ref AABB a, ref AABB b)
|
||||
{
|
||||
if (b.LowerBound.X - a.UpperBound.X > 0.0f ||
|
||||
b.LowerBound.Y - a.UpperBound.Y > 0.0f ||
|
||||
a.LowerBound.X - b.UpperBound.X > 0.0f ||
|
||||
a.LowerBound.Y - b.UpperBound.Y > 0.0f) return false;
|
||||
|
||||
return true;
|
||||
return
|
||||
b.LowerBound.X - a.UpperBound.X <= 0.0f &&
|
||||
b.LowerBound.Y - a.UpperBound.Y <= 0.0f &&
|
||||
a.LowerBound.X - b.UpperBound.X <= 0.0f &&
|
||||
a.LowerBound.Y - b.UpperBound.Y <= 0.0f;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -537,16 +543,6 @@ namespace FarseerPhysics.Collision
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This holds polygon B expressed in frame A.
|
||||
/// </summary>
|
||||
public class TempPolygon
|
||||
{
|
||||
public Vector2[] Vertices = new Vector2[Settings.MaxPolygonVertices];
|
||||
public Vector2[] Normals = new Vector2[Settings.MaxPolygonVertices];
|
||||
public int Count;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This structure is used to keep track of the best separating axis.
|
||||
/// </summary>
|
||||
@@ -587,9 +583,6 @@ namespace FarseerPhysics.Collision
|
||||
/// </summary>
|
||||
public static class Collision
|
||||
{
|
||||
[ThreadStatic]
|
||||
private static DistanceInput _input;
|
||||
|
||||
/// <summary>
|
||||
/// Test overlap between the two shapes.
|
||||
/// </summary>
|
||||
@@ -602,9 +595,9 @@ namespace FarseerPhysics.Collision
|
||||
/// <returns></returns>
|
||||
public static bool TestOverlap(Shape shapeA, int indexA, Shape shapeB, int indexB, ref Transform xfA, ref Transform xfB)
|
||||
{
|
||||
_input = _input ?? new DistanceInput();
|
||||
_input.ProxyA.Set(shapeA, indexA);
|
||||
_input.ProxyB.Set(shapeB, indexB);
|
||||
DistanceInput _input = new DistanceInput();
|
||||
_input.ProxyA = new DistanceProxy(shapeA, indexA);
|
||||
_input.ProxyB = new DistanceProxy(shapeB, indexB);
|
||||
_input.TransformA = xfA;
|
||||
_input.TransformB = xfB;
|
||||
_input.UseRadii = true;
|
||||
@@ -663,8 +656,8 @@ namespace FarseerPhysics.Collision
|
||||
{
|
||||
manifold.PointCount = 0;
|
||||
|
||||
Vector2 pA = MathUtils.Mul(ref xfA, circleA.Position);
|
||||
Vector2 pB = MathUtils.Mul(ref xfB, circleB.Position);
|
||||
Vector2 pA = Transform.Multiply(ref circleA._position, ref xfA);
|
||||
Vector2 pB = Transform.Multiply(ref circleB._position, ref xfB);
|
||||
|
||||
Vector2 d = pB - pA;
|
||||
float distSqr = Vector2.Dot(d, d);
|
||||
@@ -700,8 +693,8 @@ namespace FarseerPhysics.Collision
|
||||
manifold.PointCount = 0;
|
||||
|
||||
// Compute circle position in the frame of the polygon.
|
||||
Vector2 c = MathUtils.Mul(ref xfB, circleB.Position);
|
||||
Vector2 cLocal = MathUtils.MulT(ref xfA, c);
|
||||
Vector2 c = Transform.Multiply(ref circleB._position, ref xfB);
|
||||
Vector2 cLocal = Transform.Divide(ref c, ref xfA);
|
||||
|
||||
// Find the min separating edge.
|
||||
int normalIndex = 0;
|
||||
@@ -902,13 +895,13 @@ namespace FarseerPhysics.Collision
|
||||
Vector2 localNormal = new Vector2(localTangent.Y, -localTangent.X);
|
||||
Vector2 planePoint = 0.5f * (v11 + v12);
|
||||
|
||||
Vector2 tangent = MathUtils.Mul(xf1.q, localTangent);
|
||||
Vector2 tangent = Complex.Multiply(ref localTangent, ref xf1.q);
|
||||
|
||||
float normalx = tangent.Y;
|
||||
float normaly = -tangent.X;
|
||||
|
||||
v11 = MathUtils.Mul(ref xf1, v11);
|
||||
v12 = MathUtils.Mul(ref xf1, v12);
|
||||
v11 = Transform.Multiply(ref v11, ref xf1);
|
||||
v12 = Transform.Multiply(ref v12, ref xf1);
|
||||
|
||||
// Face offset.
|
||||
float frontOffset = normalx * v11.X + normaly * v11.Y;
|
||||
@@ -948,7 +941,7 @@ namespace FarseerPhysics.Collision
|
||||
if (separation <= totalRadius)
|
||||
{
|
||||
ManifoldPoint cp = manifold.Points[pointCount];
|
||||
cp.LocalPoint = MathUtils.MulT(ref xf2, clipPoints2[i].V);
|
||||
Transform.Divide(clipPoints2[i].V, ref xf2, out cp.LocalPoint);
|
||||
cp.Id = clipPoints2[i].ID;
|
||||
|
||||
if (flip)
|
||||
@@ -984,7 +977,7 @@ namespace FarseerPhysics.Collision
|
||||
manifold.PointCount = 0;
|
||||
|
||||
// Compute circle in frame of edge
|
||||
Vector2 Q = MathUtils.MulT(ref transformA, MathUtils.Mul(ref transformB, ref circleB._position));
|
||||
Vector2 Q = Transform.Divide(Transform.Multiply(ref circleB._position, ref transformB), ref transformA);
|
||||
|
||||
Vector2 A = edgeA.Vertex1, B = edgeA.Vertex2;
|
||||
Vector2 e = B - A;
|
||||
@@ -1126,24 +1119,29 @@ namespace FarseerPhysics.Collision
|
||||
/// <param name="xfB">The xf B.</param>
|
||||
public static void CollideEdgeAndPolygon(ref Manifold manifold, EdgeShape edgeA, ref Transform xfA, PolygonShape polygonB, ref Transform xfB)
|
||||
{
|
||||
EPCollider collider = new EPCollider();
|
||||
collider.Collide(ref manifold, edgeA, ref xfA, polygonB, ref xfB);
|
||||
EPCollider.Collide(ref manifold, edgeA, ref xfA, polygonB, ref xfB);
|
||||
}
|
||||
|
||||
private class EPCollider
|
||||
private static class EPCollider
|
||||
{
|
||||
private TempPolygon _polygonB = new TempPolygon();
|
||||
/// <summary>
|
||||
/// This holds polygon B expressed in frame A.
|
||||
/// </summary>
|
||||
internal struct TempPolygon
|
||||
{
|
||||
public Vector2[] Vertices;
|
||||
public Vector2[] Normals;
|
||||
public int Count;
|
||||
|
||||
Transform _xf;
|
||||
Vector2 _centroidB;
|
||||
Vector2 _v0, _v1, _v2, _v3;
|
||||
Vector2 _normal0, _normal1, _normal2;
|
||||
Vector2 _normal;
|
||||
Vector2 _lowerLimit, _upperLimit;
|
||||
float _radius;
|
||||
bool _front;
|
||||
internal TempPolygon(int maxPolygonVertices)
|
||||
{
|
||||
Vertices = new Vector2[maxPolygonVertices];
|
||||
Normals = new Vector2[maxPolygonVertices];
|
||||
Count = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public void Collide(ref Manifold manifold, EdgeShape edgeA, ref Transform xfA, PolygonShape polygonB, ref Transform xfB)
|
||||
public static void Collide(ref Manifold manifold, EdgeShape edgeA, ref Transform xfA, PolygonShape polygonB, ref Transform xfB)
|
||||
{
|
||||
// Algorithm:
|
||||
// 1. Classify v1 and v2
|
||||
@@ -1155,43 +1153,54 @@ namespace FarseerPhysics.Collision
|
||||
// 7. Return if _any_ axis indicates separation
|
||||
// 8. Clip
|
||||
|
||||
_xf = MathUtils.MulT(xfA, xfB);
|
||||
TempPolygon tempPolygonB = new TempPolygon(Settings.MaxPolygonVertices);
|
||||
Transform xf;
|
||||
Vector2 centroidB;
|
||||
Vector2 normal0 = new Vector2();
|
||||
Vector2 normal1;
|
||||
Vector2 normal2 = new Vector2();
|
||||
Vector2 normal;
|
||||
Vector2 lowerLimit, upperLimit;
|
||||
float radius;
|
||||
bool front;
|
||||
|
||||
_centroidB = MathUtils.Mul(ref _xf, polygonB.MassData.Centroid);
|
||||
Transform.Divide(ref xfB, ref xfA, out xf);
|
||||
|
||||
_v0 = edgeA.Vertex0;
|
||||
_v1 = edgeA._vertex1;
|
||||
_v2 = edgeA._vertex2;
|
||||
_v3 = edgeA.Vertex3;
|
||||
centroidB = Transform.Multiply(polygonB.MassData.Centroid, ref xf);
|
||||
|
||||
Vector2 v0 = edgeA.Vertex0;
|
||||
Vector2 v1 = edgeA._vertex1;
|
||||
Vector2 v2 = edgeA._vertex2;
|
||||
Vector2 v3 = edgeA.Vertex3;
|
||||
|
||||
bool hasVertex0 = edgeA.HasVertex0;
|
||||
bool hasVertex3 = edgeA.HasVertex3;
|
||||
|
||||
Vector2 edge1 = _v2 - _v1;
|
||||
Vector2 edge1 = v2 - v1;
|
||||
edge1.Normalize();
|
||||
_normal1 = new Vector2(edge1.Y, -edge1.X);
|
||||
float offset1 = Vector2.Dot(_normal1, _centroidB - _v1);
|
||||
normal1 = new Vector2(edge1.Y, -edge1.X);
|
||||
float offset1 = Vector2.Dot(normal1, centroidB - v1);
|
||||
float offset0 = 0.0f, offset2 = 0.0f;
|
||||
bool convex1 = false, convex2 = false;
|
||||
|
||||
// Is there a preceding edge?
|
||||
if (hasVertex0)
|
||||
{
|
||||
Vector2 edge0 = _v1 - _v0;
|
||||
Vector2 edge0 = v1 - v0;
|
||||
edge0.Normalize();
|
||||
_normal0 = new Vector2(edge0.Y, -edge0.X);
|
||||
convex1 = MathUtils.Cross(edge0, edge1) >= 0.0f;
|
||||
offset0 = Vector2.Dot(_normal0, _centroidB - _v0);
|
||||
normal0 = new Vector2(edge0.Y, -edge0.X);
|
||||
convex1 = MathUtils.Cross(ref edge0, ref edge1) >= 0.0f;
|
||||
offset0 = Vector2.Dot(normal0, centroidB - v0);
|
||||
}
|
||||
|
||||
// Is there a following edge?
|
||||
if (hasVertex3)
|
||||
{
|
||||
Vector2 edge2 = _v3 - _v2;
|
||||
Vector2 edge2 = v3 - v2;
|
||||
edge2.Normalize();
|
||||
_normal2 = new Vector2(edge2.Y, -edge2.X);
|
||||
convex2 = MathUtils.Cross(edge1, edge2) > 0.0f;
|
||||
offset2 = Vector2.Dot(_normal2, _centroidB - _v2);
|
||||
normal2 = new Vector2(edge2.Y, -edge2.X);
|
||||
convex2 = MathUtils.Cross(ref edge1, ref edge2) > 0.0f;
|
||||
offset2 = Vector2.Dot(normal2, centroidB - v2);
|
||||
}
|
||||
|
||||
// Determine front or back collision. Determine collision normal limits.
|
||||
@@ -1199,66 +1208,66 @@ namespace FarseerPhysics.Collision
|
||||
{
|
||||
if (convex1 && convex2)
|
||||
{
|
||||
_front = offset0 >= 0.0f || offset1 >= 0.0f || offset2 >= 0.0f;
|
||||
if (_front)
|
||||
front = offset0 >= 0.0f || offset1 >= 0.0f || offset2 >= 0.0f;
|
||||
if (front)
|
||||
{
|
||||
_normal = _normal1;
|
||||
_lowerLimit = _normal0;
|
||||
_upperLimit = _normal2;
|
||||
normal = normal1;
|
||||
lowerLimit = normal0;
|
||||
upperLimit = normal2;
|
||||
}
|
||||
else
|
||||
{
|
||||
_normal = -_normal1;
|
||||
_lowerLimit = -_normal1;
|
||||
_upperLimit = -_normal1;
|
||||
normal = -normal1;
|
||||
lowerLimit = -normal1;
|
||||
upperLimit = -normal1;
|
||||
}
|
||||
}
|
||||
else if (convex1)
|
||||
{
|
||||
_front = offset0 >= 0.0f || (offset1 >= 0.0f && offset2 >= 0.0f);
|
||||
if (_front)
|
||||
front = offset0 >= 0.0f || (offset1 >= 0.0f && offset2 >= 0.0f);
|
||||
if (front)
|
||||
{
|
||||
_normal = _normal1;
|
||||
_lowerLimit = _normal0;
|
||||
_upperLimit = _normal1;
|
||||
normal = normal1;
|
||||
lowerLimit = normal0;
|
||||
upperLimit = normal1;
|
||||
}
|
||||
else
|
||||
{
|
||||
_normal = -_normal1;
|
||||
_lowerLimit = -_normal2;
|
||||
_upperLimit = -_normal1;
|
||||
normal = -normal1;
|
||||
lowerLimit = -normal2;
|
||||
upperLimit = -normal1;
|
||||
}
|
||||
}
|
||||
else if (convex2)
|
||||
{
|
||||
_front = offset2 >= 0.0f || (offset0 >= 0.0f && offset1 >= 0.0f);
|
||||
if (_front)
|
||||
front = offset2 >= 0.0f || (offset0 >= 0.0f && offset1 >= 0.0f);
|
||||
if (front)
|
||||
{
|
||||
_normal = _normal1;
|
||||
_lowerLimit = _normal1;
|
||||
_upperLimit = _normal2;
|
||||
normal = normal1;
|
||||
lowerLimit = normal1;
|
||||
upperLimit = normal2;
|
||||
}
|
||||
else
|
||||
{
|
||||
_normal = -_normal1;
|
||||
_lowerLimit = -_normal1;
|
||||
_upperLimit = -_normal0;
|
||||
normal = -normal1;
|
||||
lowerLimit = -normal1;
|
||||
upperLimit = -normal0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_front = offset0 >= 0.0f && offset1 >= 0.0f && offset2 >= 0.0f;
|
||||
if (_front)
|
||||
front = offset0 >= 0.0f && offset1 >= 0.0f && offset2 >= 0.0f;
|
||||
if (front)
|
||||
{
|
||||
_normal = _normal1;
|
||||
_lowerLimit = _normal1;
|
||||
_upperLimit = _normal1;
|
||||
normal = normal1;
|
||||
lowerLimit = normal1;
|
||||
upperLimit = normal1;
|
||||
}
|
||||
else
|
||||
{
|
||||
_normal = -_normal1;
|
||||
_lowerLimit = -_normal2;
|
||||
_upperLimit = -_normal0;
|
||||
normal = -normal1;
|
||||
lowerLimit = -normal2;
|
||||
upperLimit = -normal0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1266,34 +1275,34 @@ namespace FarseerPhysics.Collision
|
||||
{
|
||||
if (convex1)
|
||||
{
|
||||
_front = offset0 >= 0.0f || offset1 >= 0.0f;
|
||||
if (_front)
|
||||
front = offset0 >= 0.0f || offset1 >= 0.0f;
|
||||
if (front)
|
||||
{
|
||||
_normal = _normal1;
|
||||
_lowerLimit = _normal0;
|
||||
_upperLimit = -_normal1;
|
||||
normal = normal1;
|
||||
lowerLimit = normal0;
|
||||
upperLimit = -normal1;
|
||||
}
|
||||
else
|
||||
{
|
||||
_normal = -_normal1;
|
||||
_lowerLimit = _normal1;
|
||||
_upperLimit = -_normal1;
|
||||
normal = -normal1;
|
||||
lowerLimit = normal1;
|
||||
upperLimit = -normal1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_front = offset0 >= 0.0f && offset1 >= 0.0f;
|
||||
if (_front)
|
||||
front = offset0 >= 0.0f && offset1 >= 0.0f;
|
||||
if (front)
|
||||
{
|
||||
_normal = _normal1;
|
||||
_lowerLimit = _normal1;
|
||||
_upperLimit = -_normal1;
|
||||
normal = normal1;
|
||||
lowerLimit = normal1;
|
||||
upperLimit = -normal1;
|
||||
}
|
||||
else
|
||||
{
|
||||
_normal = -_normal1;
|
||||
_lowerLimit = _normal1;
|
||||
_upperLimit = -_normal0;
|
||||
normal = -normal1;
|
||||
lowerLimit = normal1;
|
||||
upperLimit = -normal0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1301,67 +1310,67 @@ namespace FarseerPhysics.Collision
|
||||
{
|
||||
if (convex2)
|
||||
{
|
||||
_front = offset1 >= 0.0f || offset2 >= 0.0f;
|
||||
if (_front)
|
||||
front = offset1 >= 0.0f || offset2 >= 0.0f;
|
||||
if (front)
|
||||
{
|
||||
_normal = _normal1;
|
||||
_lowerLimit = -_normal1;
|
||||
_upperLimit = _normal2;
|
||||
normal = normal1;
|
||||
lowerLimit = -normal1;
|
||||
upperLimit = normal2;
|
||||
}
|
||||
else
|
||||
{
|
||||
_normal = -_normal1;
|
||||
_lowerLimit = -_normal1;
|
||||
_upperLimit = _normal1;
|
||||
normal = -normal1;
|
||||
lowerLimit = -normal1;
|
||||
upperLimit = normal1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_front = offset1 >= 0.0f && offset2 >= 0.0f;
|
||||
if (_front)
|
||||
front = offset1 >= 0.0f && offset2 >= 0.0f;
|
||||
if (front)
|
||||
{
|
||||
_normal = _normal1;
|
||||
_lowerLimit = -_normal1;
|
||||
_upperLimit = _normal1;
|
||||
normal = normal1;
|
||||
lowerLimit = -normal1;
|
||||
upperLimit = normal1;
|
||||
}
|
||||
else
|
||||
{
|
||||
_normal = -_normal1;
|
||||
_lowerLimit = -_normal2;
|
||||
_upperLimit = _normal1;
|
||||
normal = -normal1;
|
||||
lowerLimit = -normal2;
|
||||
upperLimit = normal1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_front = offset1 >= 0.0f;
|
||||
if (_front)
|
||||
front = offset1 >= 0.0f;
|
||||
if (front)
|
||||
{
|
||||
_normal = _normal1;
|
||||
_lowerLimit = -_normal1;
|
||||
_upperLimit = -_normal1;
|
||||
normal = normal1;
|
||||
lowerLimit = -normal1;
|
||||
upperLimit = -normal1;
|
||||
}
|
||||
else
|
||||
{
|
||||
_normal = -_normal1;
|
||||
_lowerLimit = _normal1;
|
||||
_upperLimit = _normal1;
|
||||
normal = -normal1;
|
||||
lowerLimit = normal1;
|
||||
upperLimit = normal1;
|
||||
}
|
||||
}
|
||||
|
||||
// Get polygonB in frameA
|
||||
_polygonB.Count = polygonB.Vertices.Count;
|
||||
tempPolygonB.Count = polygonB.Vertices.Count;
|
||||
for (int i = 0; i < polygonB.Vertices.Count; ++i)
|
||||
{
|
||||
_polygonB.Vertices[i] = MathUtils.Mul(ref _xf, polygonB.Vertices[i]);
|
||||
_polygonB.Normals[i] = MathUtils.Mul(_xf.q, polygonB.Normals[i]);
|
||||
tempPolygonB.Vertices[i] = Transform.Multiply(polygonB.Vertices[i], ref xf);
|
||||
tempPolygonB.Normals[i] = Complex.Multiply(polygonB.Normals[i], ref xf.q);
|
||||
}
|
||||
|
||||
_radius = 2.0f * Settings.PolygonRadius;
|
||||
radius = 2.0f * Settings.PolygonRadius;
|
||||
|
||||
manifold.PointCount = 0;
|
||||
|
||||
EPAxis edgeAxis = ComputeEdgeSeparation();
|
||||
EPAxis edgeAxis = ComputeEdgeSeparation(ref tempPolygonB, ref normal, ref v1, front);
|
||||
|
||||
// If no valid normal can be found than this edge should not collide.
|
||||
if (edgeAxis.Type == EPAxisType.Unknown)
|
||||
@@ -1369,13 +1378,13 @@ namespace FarseerPhysics.Collision
|
||||
return;
|
||||
}
|
||||
|
||||
if (edgeAxis.Separation > _radius)
|
||||
if (edgeAxis.Separation > radius)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
EPAxis polygonAxis = ComputePolygonSeparation();
|
||||
if (polygonAxis.Type != EPAxisType.Unknown && polygonAxis.Separation > _radius)
|
||||
EPAxis polygonAxis = ComputePolygonSeparation(ref tempPolygonB, ref normal, ref v1, ref v2, ref lowerLimit, ref upperLimit, radius);
|
||||
if (polygonAxis.Type != EPAxisType.Unknown && polygonAxis.Separation > radius)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -1406,10 +1415,10 @@ namespace FarseerPhysics.Collision
|
||||
|
||||
// Search for the polygon normal that is most anti-parallel to the edge normal.
|
||||
int bestIndex = 0;
|
||||
float bestValue = Vector2.Dot(_normal, _polygonB.Normals[0]);
|
||||
for (int i = 1; i < _polygonB.Count; ++i)
|
||||
float bestValue = Vector2.Dot(normal, tempPolygonB.Normals[0]);
|
||||
for (int i = 1; i < tempPolygonB.Count; ++i)
|
||||
{
|
||||
float value = Vector2.Dot(_normal, _polygonB.Normals[i]);
|
||||
float value = Vector2.Dot(normal, tempPolygonB.Normals[i]);
|
||||
if (value < bestValue)
|
||||
{
|
||||
bestValue = value;
|
||||
@@ -1418,10 +1427,10 @@ namespace FarseerPhysics.Collision
|
||||
}
|
||||
|
||||
int i1 = bestIndex;
|
||||
int i2 = i1 + 1 < _polygonB.Count ? i1 + 1 : 0;
|
||||
int i2 = i1 + 1 < tempPolygonB.Count ? i1 + 1 : 0;
|
||||
|
||||
ClipVertex c0 = ie[0];
|
||||
c0.V = _polygonB.Vertices[i1];
|
||||
c0.V = tempPolygonB.Vertices[i1];
|
||||
c0.ID.Features.IndexA = 0;
|
||||
c0.ID.Features.IndexB = (byte)i1;
|
||||
c0.ID.Features.TypeA = (byte)ContactFeatureType.Face;
|
||||
@@ -1429,35 +1438,35 @@ namespace FarseerPhysics.Collision
|
||||
ie[0] = c0;
|
||||
|
||||
ClipVertex c1 = ie[1];
|
||||
c1.V = _polygonB.Vertices[i2];
|
||||
c1.V = tempPolygonB.Vertices[i2];
|
||||
c1.ID.Features.IndexA = 0;
|
||||
c1.ID.Features.IndexB = (byte)i2;
|
||||
c1.ID.Features.TypeA = (byte)ContactFeatureType.Face;
|
||||
c1.ID.Features.TypeB = (byte)ContactFeatureType.Vertex;
|
||||
ie[1] = c1;
|
||||
|
||||
if (_front)
|
||||
if (front)
|
||||
{
|
||||
rf.i1 = 0;
|
||||
rf.i2 = 1;
|
||||
rf.v1 = _v1;
|
||||
rf.v2 = _v2;
|
||||
rf.normal = _normal1;
|
||||
rf.v1 = v1;
|
||||
rf.v2 = v2;
|
||||
rf.normal = normal1;
|
||||
}
|
||||
else
|
||||
{
|
||||
rf.i1 = 1;
|
||||
rf.i2 = 0;
|
||||
rf.v1 = _v2;
|
||||
rf.v2 = _v1;
|
||||
rf.normal = -_normal1;
|
||||
rf.v1 = v2;
|
||||
rf.v2 = v1;
|
||||
rf.normal = -normal1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
manifold.Type = ManifoldType.FaceB;
|
||||
ClipVertex c0 = ie[0];
|
||||
c0.V = _v1;
|
||||
c0.V = v1;
|
||||
c0.ID.Features.IndexA = 0;
|
||||
c0.ID.Features.IndexB = (byte)primaryAxis.Index;
|
||||
c0.ID.Features.TypeA = (byte)ContactFeatureType.Vertex;
|
||||
@@ -1465,7 +1474,7 @@ namespace FarseerPhysics.Collision
|
||||
ie[0] = c0;
|
||||
|
||||
ClipVertex c1 = ie[1];
|
||||
c1.V = _v2;
|
||||
c1.V = v2;
|
||||
c1.ID.Features.IndexA = 0;
|
||||
c1.ID.Features.IndexB = (byte)primaryAxis.Index;
|
||||
c1.ID.Features.TypeA = (byte)ContactFeatureType.Vertex;
|
||||
@@ -1473,10 +1482,10 @@ namespace FarseerPhysics.Collision
|
||||
ie[1] = c1;
|
||||
|
||||
rf.i1 = primaryAxis.Index;
|
||||
rf.i2 = rf.i1 + 1 < _polygonB.Count ? rf.i1 + 1 : 0;
|
||||
rf.v1 = _polygonB.Vertices[rf.i1];
|
||||
rf.v2 = _polygonB.Vertices[rf.i2];
|
||||
rf.normal = _polygonB.Normals[rf.i1];
|
||||
rf.i2 = rf.i1 + 1 < tempPolygonB.Count ? rf.i1 + 1 : 0;
|
||||
rf.v1 = tempPolygonB.Vertices[rf.i1];
|
||||
rf.v2 = tempPolygonB.Vertices[rf.i2];
|
||||
rf.normal = tempPolygonB.Normals[rf.i1];
|
||||
}
|
||||
|
||||
rf.sideNormal1 = new Vector2(rf.normal.Y, -rf.normal.X);
|
||||
@@ -1522,13 +1531,13 @@ namespace FarseerPhysics.Collision
|
||||
{
|
||||
float separation = Vector2.Dot(rf.normal, clipPoints2[i].V - rf.v1);
|
||||
|
||||
if (separation <= _radius)
|
||||
if (separation <= radius)
|
||||
{
|
||||
ManifoldPoint cp = manifold.Points[pointCount];
|
||||
|
||||
if (primaryAxis.Type == EPAxisType.EdgeA)
|
||||
{
|
||||
cp.LocalPoint = MathUtils.MulT(ref _xf, clipPoints2[i].V);
|
||||
Transform.Divide(clipPoints2[i].V, ref xf, out cp.LocalPoint);
|
||||
cp.Id = clipPoints2[i].ID;
|
||||
}
|
||||
else
|
||||
@@ -1548,16 +1557,16 @@ namespace FarseerPhysics.Collision
|
||||
manifold.PointCount = pointCount;
|
||||
}
|
||||
|
||||
private EPAxis ComputeEdgeSeparation()
|
||||
private static EPAxis ComputeEdgeSeparation(ref TempPolygon polygonB, ref Vector2 normal, ref Vector2 v1, bool front)
|
||||
{
|
||||
EPAxis axis;
|
||||
axis.Type = EPAxisType.EdgeA;
|
||||
axis.Index = _front ? 0 : 1;
|
||||
axis.Index = front ? 0 : 1;
|
||||
axis.Separation = Settings.MaxFloat;
|
||||
|
||||
for (int i = 0; i < _polygonB.Count; ++i)
|
||||
for (int i = 0; i < polygonB.Count; ++i)
|
||||
{
|
||||
float s = Vector2.Dot(_normal, _polygonB.Vertices[i] - _v1);
|
||||
float s = Vector2.Dot(normal, polygonB.Vertices[i] - v1);
|
||||
if (s < axis.Separation)
|
||||
{
|
||||
axis.Separation = s;
|
||||
@@ -1567,24 +1576,24 @@ namespace FarseerPhysics.Collision
|
||||
return axis;
|
||||
}
|
||||
|
||||
private EPAxis ComputePolygonSeparation()
|
||||
private static EPAxis ComputePolygonSeparation(ref TempPolygon polygonB, ref Vector2 normal, ref Vector2 v1, ref Vector2 v2, ref Vector2 lowerLimit, ref Vector2 upperLimit, float radius)
|
||||
{
|
||||
EPAxis axis;
|
||||
axis.Type = EPAxisType.Unknown;
|
||||
axis.Index = -1;
|
||||
axis.Separation = -Settings.MaxFloat;
|
||||
|
||||
Vector2 perp = new Vector2(-_normal.Y, _normal.X);
|
||||
Vector2 perp = new Vector2(-normal.Y, normal.X);
|
||||
|
||||
for (int i = 0; i < _polygonB.Count; ++i)
|
||||
for (int i = 0; i < polygonB.Count; ++i)
|
||||
{
|
||||
Vector2 n = -_polygonB.Normals[i];
|
||||
Vector2 n = -polygonB.Normals[i];
|
||||
|
||||
float s1 = Vector2.Dot(n, _polygonB.Vertices[i] - _v1);
|
||||
float s2 = Vector2.Dot(n, _polygonB.Vertices[i] - _v2);
|
||||
float s1 = Vector2.Dot(n, polygonB.Vertices[i] - v1);
|
||||
float s2 = Vector2.Dot(n, polygonB.Vertices[i] - v2);
|
||||
float s = Math.Min(s1, s2);
|
||||
|
||||
if (s > _radius)
|
||||
if (s > radius)
|
||||
{
|
||||
// No collision
|
||||
axis.Type = EPAxisType.EdgeB;
|
||||
@@ -1596,14 +1605,14 @@ namespace FarseerPhysics.Collision
|
||||
// Adjacency
|
||||
if (Vector2.Dot(n, perp) >= 0.0f)
|
||||
{
|
||||
if (Vector2.Dot(n - _upperLimit, _normal) < -Settings.AngularSlop)
|
||||
if (Vector2.Dot(n - upperLimit, normal) < -Settings.AngularSlop)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Vector2.Dot(n - _lowerLimit, _normal) < -Settings.AngularSlop)
|
||||
if (Vector2.Dot(n - lowerLimit, normal) < -Settings.AngularSlop)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -1682,7 +1691,7 @@ namespace FarseerPhysics.Collision
|
||||
/// <param name="poly2">The poly2.</param>
|
||||
/// <param name="xf2">The XF2.</param>
|
||||
/// <returns></returns>
|
||||
private static float EdgeSeparation(PolygonShape poly1, ref Transform xf1, int edge1, PolygonShape poly2, ref Transform xf2)
|
||||
private static float EdgeSeparation(PolygonShape poly1, ref Transform xf1To2, int edge1, PolygonShape poly2)
|
||||
{
|
||||
List<Vector2> vertices1 = poly1.Vertices;
|
||||
List<Vector2> normals1 = poly1.Normals;
|
||||
@@ -1693,8 +1702,7 @@ namespace FarseerPhysics.Collision
|
||||
Debug.Assert(0 <= edge1 && edge1 < poly1.Vertices.Count);
|
||||
|
||||
// Convert normal from poly1's frame into poly2's frame.
|
||||
Vector2 normal1World = MathUtils.Mul(xf1.q, normals1[edge1]);
|
||||
Vector2 normal1 = MathUtils.MulT(xf2.q, normal1World);
|
||||
Vector2 normal1 = Complex.Multiply(normals1[edge1], ref xf1To2.q);
|
||||
|
||||
// Find support vertex on poly2 for -normal.
|
||||
int index = 0;
|
||||
@@ -1702,7 +1710,7 @@ namespace FarseerPhysics.Collision
|
||||
|
||||
for (int i = 0; i < count2; ++i)
|
||||
{
|
||||
float dot = Vector2.Dot(vertices2[i], normal1);
|
||||
float dot = MathUtils.Dot(vertices2[i], ref normal1);
|
||||
if (dot < minDot)
|
||||
{
|
||||
minDot = dot;
|
||||
@@ -1710,9 +1718,10 @@ namespace FarseerPhysics.Collision
|
||||
}
|
||||
}
|
||||
|
||||
Vector2 v1 = MathUtils.Mul(ref xf1, vertices1[edge1]);
|
||||
Vector2 v2 = MathUtils.Mul(ref xf2, vertices2[index]);
|
||||
float separation = Vector2.Dot(v2 - v1, normal1World);
|
||||
Vector2 v1 = Transform.Multiply(vertices1[edge1], ref xf1To2);
|
||||
Vector2 v2 = vertices2[index];
|
||||
float separation = MathUtils.Dot(v2 - v1, ref normal1);
|
||||
|
||||
return separation;
|
||||
}
|
||||
|
||||
@@ -1730,16 +1739,18 @@ namespace FarseerPhysics.Collision
|
||||
int count1 = poly1.Vertices.Count;
|
||||
List<Vector2> normals1 = poly1.Normals;
|
||||
|
||||
var xf1To2 = Transform.Divide(ref xf1, ref xf2);
|
||||
|
||||
// Vector pointing from the centroid of poly1 to the centroid of poly2.
|
||||
Vector2 d = MathUtils.Mul(ref xf2, poly2.MassData.Centroid) - MathUtils.Mul(ref xf1, poly1.MassData.Centroid);
|
||||
Vector2 dLocal1 = MathUtils.MulT(xf1.q, d);
|
||||
Vector2 c2local = Transform.Divide(poly2.MassData.Centroid, ref xf1To2);
|
||||
Vector2 dLocal1 = c2local - poly1.MassData.Centroid;
|
||||
|
||||
// Find edge normal on poly1 that has the largest projection onto d.
|
||||
int edge = 0;
|
||||
float maxDot = -Settings.MaxFloat;
|
||||
for (int i = 0; i < count1; ++i)
|
||||
{
|
||||
float dot = Vector2.Dot(normals1[i], dLocal1);
|
||||
float dot = MathUtils.Dot(normals1[i], ref dLocal1);
|
||||
if (dot > maxDot)
|
||||
{
|
||||
maxDot = dot;
|
||||
@@ -1748,15 +1759,15 @@ namespace FarseerPhysics.Collision
|
||||
}
|
||||
|
||||
// Get the separation for the edge normal.
|
||||
float s = EdgeSeparation(poly1, ref xf1, edge, poly2, ref xf2);
|
||||
float s = EdgeSeparation(poly1, ref xf1To2, edge, poly2);
|
||||
|
||||
// Check the separation for the previous edge normal.
|
||||
int prevEdge = edge - 1 >= 0 ? edge - 1 : count1 - 1;
|
||||
float sPrev = EdgeSeparation(poly1, ref xf1, prevEdge, poly2, ref xf2);
|
||||
float sPrev = EdgeSeparation(poly1, ref xf1To2, prevEdge, poly2);
|
||||
|
||||
// Check the separation for the next edge normal.
|
||||
int nextEdge = edge + 1 < count1 ? edge + 1 : 0;
|
||||
float sNext = EdgeSeparation(poly1, ref xf1, nextEdge, poly2, ref xf2);
|
||||
float sNext = EdgeSeparation(poly1, ref xf1To2, nextEdge, poly2);
|
||||
|
||||
// Find the best edge and the search direction.
|
||||
int bestEdge;
|
||||
@@ -1788,7 +1799,7 @@ namespace FarseerPhysics.Collision
|
||||
else
|
||||
edge = bestEdge + 1 < count1 ? bestEdge + 1 : 0;
|
||||
|
||||
s = EdgeSeparation(poly1, ref xf1, edge, poly2, ref xf2);
|
||||
s = EdgeSeparation(poly1, ref xf1To2, edge, poly2);
|
||||
|
||||
if (s > bestSeparation)
|
||||
{
|
||||
@@ -1817,7 +1828,7 @@ namespace FarseerPhysics.Collision
|
||||
Debug.Assert(0 <= edge1 && edge1 < poly1.Vertices.Count);
|
||||
|
||||
// Get the normal of the reference edge in poly2's frame.
|
||||
Vector2 normal1 = MathUtils.MulT(xf2.q, MathUtils.Mul(xf1.q, normals1[edge1]));
|
||||
Vector2 normal1 = Complex.Divide(Complex.Multiply(normals1[edge1], ref xf1.q), ref xf2.q);
|
||||
|
||||
|
||||
// Find the incident edge on poly2.
|
||||
@@ -1839,7 +1850,7 @@ namespace FarseerPhysics.Collision
|
||||
|
||||
ClipVertex cv0 = c[0];
|
||||
|
||||
cv0.V = MathUtils.Mul(ref xf2, vertices2[i1]);
|
||||
cv0.V = Transform.Multiply(vertices2[i1], ref xf2);
|
||||
cv0.ID.Features.IndexA = (byte)edge1;
|
||||
cv0.ID.Features.IndexB = (byte)i1;
|
||||
cv0.ID.Features.TypeA = (byte)ContactFeatureType.Face;
|
||||
@@ -1848,7 +1859,7 @@ namespace FarseerPhysics.Collision
|
||||
c[0] = cv0;
|
||||
|
||||
ClipVertex cv1 = c[1];
|
||||
cv1.V = MathUtils.Mul(ref xf2, vertices2[i2]);
|
||||
cv1.V = Transform.Multiply(vertices2[i2], ref xf2);
|
||||
cv1.ID.Features.IndexA = (byte)edge1;
|
||||
cv1.ID.Features.IndexB = (byte)i2;
|
||||
cv1.ID.Features.TypeA = (byte)ContactFeatureType.Face;
|
||||
|
||||
Reference in New Issue
Block a user