public void HandleCollision(Manifold m, TFRigidbody a, TFRigidbody b) { TFCircleCollider A = (TFCircleCollider)a.coll; TFCircleCollider B = (TFCircleCollider)b.coll; //Calculate translational vector, which is normal FixVec2 normal = ((FixVec2)b.Position) - ((FixVec2)a.Position); Fix distSpr = normal.GetMagnitudeSquared(); Fix radius = A.radius + B.radius; //Not in contact if (distSpr >= radius * radius) { m.contactCount = 0; return; } Fix distance = FixMath.Sqrt(distSpr); m.contactCount = 1; if (distance == Fix.zero) { m.penetration = A.radius; m.normal = new FixVec2(1, 0); m.contacts[0] = (FixVec2)a.Position; } else { m.penetration = radius - distance; m.normal = normal / distance; m.contacts[0] = m.normal * A.radius + ((FixVec2)a.Position); } }
void CreateCircle() { GameObject go = new GameObject("Circle"); TFTransform fp = go.AddComponent <TFTransform>(); TFCircleCollider cc = go.AddComponent <TFCircleCollider>(); TFRigidbody rb = go.AddComponent <TFRigidbody>(); var v3 = Input.mousePosition; v3.z = 0; v3 = Camera.main.ScreenToWorldPoint(v3); fp.Position = new FixVec3((Fix)v3.x, (Fix)v3.y, 0); cc.radius = (Fix)Random.Range(0.05f, 1.2f); rb.bodyType = TFBodyType.Dynamic; rb.inertia = (Fix)Random.Range(0.0f, 1.0f); rb.Position = (FixVec2)fp.Position; rb.material = TFPhysics.instance.settings.defaultMaterial; fp.LocalScale = new FixVec3(cc.radius * ((Fix)1.45f), cc.radius * ((Fix)1.45f), 1); //Sprite GameObject cSprite = GameObject.Instantiate(circleSprite); cSprite.transform.SetParent(go.transform, false); }
public void HandleCollision(Manifold m, TFRigidbody a, TFRigidbody b) { TFEdgeCollider A = (TFEdgeCollider)a.coll; TFCircleCollider B = (TFCircleCollider)b.coll; // No line segments, return out. if (A.vertices.Count < 2) { return; } // Transform circle center to Edge model space FixVec2 circleCenter = A.u.Transposed() * (b.Position - a.Position); // Iterate through all the line segments to find contact point. for (int i = 0; i < A.vertices.Count - 1; i++) { FixVec2 rayDir = (A.vertices[i + 1] - A.vertices[i]); FixVec2 centerRay = (A.vertices[i] - circleCenter); Fix k = rayDir.Dot(rayDir); Fix l = 2 * centerRay.Dot(rayDir); Fix n = centerRay.Dot(centerRay) - (B.radius * B.radius); Fix discriminant = l * l - 4 * k * n; // No intersection. if (discriminant <= Fix.zero) { continue; } discriminant = FixMath.Sqrt(discriminant); Fix t1 = (-l - discriminant) / (2 * k); Fix t2 = (-l + discriminant) / (2 * k); Fix s = FixVec2.Dot(A.normals[i], circleCenter - A.vertices[i]); if (t1 >= Fix.zero && t1 <= Fix.one) { //t1 is the intersection, and it's closer than t2. m.contactCount = 1; m.contacts[0] = (A.u * A.vertices[i] + a.Position) + (t1 * rayDir); m.normal = A.normals[i]; m.penetration = B.radius - s; return; } if (t2 >= Fix.zero && t2 <= Fix.one) { // t1 didn't insection, so we either started inside the circle // or completely past it. m.contactCount = 1; m.contacts[0] = (A.u * A.vertices[i] + a.Position) + (t2 * rayDir); m.normal = A.normals[i]; m.penetration = B.radius - s; return; } } }
public void HandleCollision(Manifold m, TFRigidbody a, TFRigidbody b) { TFCircleCollider A = (TFCircleCollider)a.coll; TFPolygonCollider B = (TFPolygonCollider)b.coll; m.contactCount = 0; // Transform circle center to Polygon model space FixVec2 center = B.u.Transposed() * (a.Position - b.Position); // Find edge with minimum penetration // Exact concept as using support points in Polygon vs Polygon Fix separation = -Fix.MaxValue; int faceNormal = 0; for (int i = 0; i < B.VertexCount; ++i) { Fix s = FixVec2.Dot(B.normals[i], center - B.GetVertex(i)); if (s > A.radius) { return; } if (s > separation) { separation = s; faceNormal = i; } } // Grab face's vertices FixVec2 v1 = B.GetVertex(faceNormal); int i2 = (faceNormal + 1) < B.VertexCount ? faceNormal + 1 : 0; FixVec2 v2 = B.GetVertex(i2); // Check to see if center is within polygon if (separation < Fix.Epsilon) { m.contactCount = 1; m.normal = -(B.u * B.normals[faceNormal]); m.contacts[0] = m.normal * A.radius + a.Position; m.penetration = A.radius; return; } // Determine which voronoi region of the edge center of circle lies within Fix dot1 = FixVec2.Dot(center - v1, v2 - v1); Fix dot2 = FixVec2.Dot(center - v2, v1 - v2); m.penetration = A.radius - separation; //Closest to v1 if (dot1 <= Fix.zero) { if ((center - v1).GetMagnitudeSquared() > A.radius * A.radius) { return; } m.contactCount = 1; FixVec2 n = v1 - center; n = B.u * n; n = n.Normalized(); m.normal = n; v1 = B.u * v1 + b.Position; m.contacts[0] = v1; } else if (dot2 <= Fix.zero) { //Closest to v2 if ((center - v2).GetMagnitudeSquared() > A.radius * A.radius) { return; } m.contactCount = 1; FixVec2 n = v2 - center; v2 = B.u * v2 + b.Position; m.contacts[0] = v2; n = B.u * n; n = n.Normalized(); m.normal = n; } else { //Closest to face FixVec2 n = B.normals[faceNormal]; if (FixVec2.Dot(center - v1, n) > A.radius) { return; } n = B.u * n; m.normal = -n; m.contacts[0] = m.normal * A.radius + a.Position; m.contactCount = 1; } }