Example #1
0
    public void StartImpulseObject()
    {
        if (started)
        {
            return;
        }
        verts = Vec2.ArrayOf(activePoints.Length);
        for (int v = 0; v < activePoints.Length; v++)
        {
            verts[v].x = activePoints[v].x;
            verts[v].y = activePoints[v].y;
        }

        body = impulse.Add(new Polygon(verts), transform.position.x, transform.position.y);
        body.SetOrient(0);
        body.restitution     = 0.2f;
        body.dynamicFriction = 0.2f;
        body.staticFriction  = 0.4f;
        shape   = ((Polygon)body.shape);
        started = true;
    }
Example #2
0
        public override void HandleCollision(Manifold m, Body a, Body b)
        {
            Polygon A = (Polygon)a.shape;
            Polygon B = (Polygon)b.shape;

            m.contactCount = 0;

            // Check for a separating axis with A's face planes
            int[] faceA        = { 0 };
            float penetrationA = FindAxisLeastPenetration(faceA, A, B);

            if (penetrationA >= 0.0f)
            {
                return;
            }

            // Check for a separating axis with B's face planes
            int[] faceB        = { 0 };
            float penetrationB = FindAxisLeastPenetration(faceB, B, A);

            if (penetrationB >= 0.0f)
            {
                return;
            }

            int  referenceIndex;
            bool flip;       // Always point from a to b

            Polygon RefPoly; // Reference
            Polygon IncPoly; // Incident

            // Determine which shape contains reference face
            if (ImpulseMath.Gt(penetrationA, penetrationB))
            {
                RefPoly        = A;
                IncPoly        = B;
                referenceIndex = faceA[0];
                flip           = false;
            }
            else
            {
                RefPoly        = B;
                IncPoly        = A;
                referenceIndex = faceB[0];
                flip           = true;
            }

            // World space incident face
            Vec2[] incidentFace = Vec2.ArrayOf(2);

            FindIncidentFace(incidentFace, RefPoly, IncPoly, referenceIndex);

            // y
            // ^ .n ^
            // +---c ------posPlane--
            // x < | i |\
            // +---+ c-----negPlane--
            // \ v
            // r
            //
            // r : reference face
            // i : incident poly
            // c : clipped point
            // n : incident normal

            // Setup reference face vertices
            Vec2 v1 = RefPoly.vertices[referenceIndex];

            referenceIndex = referenceIndex + 1 == RefPoly.vertexCount ? 0 : referenceIndex + 1;
            Vec2 v2 = RefPoly.vertices[referenceIndex];

            // Transform vertices to world space
            // v1 = RefPoly->u * v1 + RefPoly->body->position;
            // v2 = RefPoly->u * v2 + RefPoly->body->position;
            v1 = RefPoly.u.Mul(v1).Addi(RefPoly.body.position);
            v2 = RefPoly.u.Mul(v2).Addi(RefPoly.body.position);

            // Calculate reference face side normal in world space
            // Vec2 sidePlaneNormal = (v2 - v1);
            // sidePlaneNormal.Normalize( );
            Vec2 sidePlaneNormal = v2.Sub(v1);

            sidePlaneNormal.Normalize();

            // Orthogonalize
            // Vec2 refFaceNormal( sidePlaneNormal.y, -sidePlaneNormal.x );
            Vec2 refFaceNormal = new Vec2(sidePlaneNormal.y, -sidePlaneNormal.x);

            // ax + by = c
            // c is distance from origin
            // real refC = Dot( refFaceNormal, v1 );
            // real negSide = -Dot( sidePlaneNormal, v1 );
            // real posSide = Dot( sidePlaneNormal, v2 );
            float refC    = Vec2.Dot(refFaceNormal, v1);
            float negSide = -Vec2.Dot(sidePlaneNormal, v1);
            float posSide = Vec2.Dot(sidePlaneNormal, v2);

            // Clip incident face to reference face side planes
            // if(Clip( -sidePlaneNormal, negSide, incidentFace ) < 2)
            if (Clip(sidePlaneNormal.Neg(), negSide, incidentFace) < 2)
            {
                return; // Due to floating point error, possible to not have required
                        // points
            }

            // if(Clip( sidePlaneNormal, posSide, incidentFace ) < 2)
            if (Clip(sidePlaneNormal, posSide, incidentFace) < 2)
            {
                return; // Due to floating point error, possible to not have required
                        // points
            }

            // Flip
            m.normal.Set(refFaceNormal);
            if (flip)
            {
                m.normal.Negi();
            }

            // Keep points behind reference face
            int   cp         = 0; // clipped points behind reference face
            float separation = Vec2.Dot(refFaceNormal, incidentFace[0]) - refC;

            if (separation <= 0.0f)
            {
                m.contacts[cp].Set(incidentFace[0]);
                m.penetration = -separation;
                ++cp;
            }
            else
            {
                m.penetration = 0;
            }

            separation = Vec2.Dot(refFaceNormal, incidentFace[1]) - refC;

            if (separation <= 0.0f)
            {
                m.contacts[cp].Set(incidentFace[1]);

                m.penetration += -separation;
                ++cp;

                // Average penetration
                m.penetration /= cp;
            }

            m.contactCount = cp;
        }
    void InputImpulseEngine(CommonMonoBehaviour.GameInput input)
    {
        if (!playing)
        {
            return;
        }
        if (input.keyDown[0])
        {
            playing = false;
        }

        if (input.keyDown[1])
        {
            if (input.mouseUp[0] || input.mouseDown[0])
            {
                float hw = ImpulseMath.Random(1.0f, 3.0f);
                float hh = ImpulseMath.Random(1.0f, 3.0f);

                Body b = impulse.Add(new Polygon(hw, hh), input.rayPosition.x, input.rayPosition.y);
                b.SetOrient(0.0f);
            }
            if (input.mouseUp[1] || input.mouseDown[1])
            {
                float r         = ImpulseMath.Random(1.0f, 5.0f);
                int   vertCount = 3;

                Vec2[] verts = Vec2.ArrayOf(vertCount);
                for (int i = 0; i < vertCount; i++)
                {
                    verts[i].Set(ImpulseMath.Random(-r, r), ImpulseMath.Random(-r, r));
                }

                Body b = impulse.Add(new Polygon(verts), input.rayPosition.x, input.rayPosition.y);
                b.SetOrient(ImpulseMath.Random(-ImpulseMath.PI, ImpulseMath.PI));
                b.restitution     = 0.2f;
                b.dynamicFriction = 0.2f;
                b.staticFriction  = 0.4f;
            }
        }
        else
        {
            if (input.mouseUp[0] || input.mouseDown[0])
            {
                float r         = ImpulseMath.Random(1.0f, 5.0f);
                int   vertCount = ImpulseMath.Random(3, Polygon.MAX_POLY_VERTEX_COUNT);

                Vec2[] verts = Vec2.ArrayOf(vertCount);
                for (int i = 0; i < vertCount; i++)
                {
                    verts[i].Set(ImpulseMath.Random(-r, r), ImpulseMath.Random(-r, r));
                }

                Body b = impulse.Add(new Polygon(verts), input.rayPosition.x, input.rayPosition.y);
                b.SetOrient(ImpulseMath.Random(-ImpulseMath.PI, ImpulseMath.PI));
                b.restitution     = 0.2f;
                b.dynamicFriction = 0.2f;
                b.staticFriction  = 0.4f;
            }
            if (input.mouseUp[1] || input.mouseDown[1])
            {
                float r = ImpulseMath.Random(1.0f, 3.0f);

                impulse.Add(new Circle(r), input.rayPosition.x, input.rayPosition.y);
            }
            //Move your cube GameObject to the point where you clicked
            if (PointerTransform)
            {
                PointerTransform.position = input.rayPosition;
            }
        }
    }