コード例 #1
0
        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);
            }
        }
コード例 #2
0
ファイル: CreateBodies.cs プロジェクト: weihua44/2DFPhysics
    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);
    }
コード例 #3
0
        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;
                }
            }
        }
コード例 #4
0
        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;
            }
        }