The class manages contact between two shapes. A contact exists for each overlapping AABB in the broad-phase (except if filtered). Therefore a contact object may exist that has no contact points.
 public static bool OnMeleeHit(Fixture a, Fixture b, Contact c)
 {
     if (b.Body.IsBullet)
         return true;
     Projectile p = (Projectile)a.UserData;
     // If we hit a weapon.
     if (b.UserData is Weapon)
     {
         Weapon w = (Weapon)b.UserData;
         w.TakeDamage(p.GetPower());
     }
     // If we hit a bot
     if (b.UserData is Bot)
     {
         Bot bot = (Bot)b.UserData;
         bot.TakeDamage(p.GetPower());
     }
     // If we hit a projectile (e.g. an axe)
     if (b.UserData is Projectile)
     {
         Projectile o = (Projectile)b.UserData;
         o.TakeDamage(p.GetPower());
     }
     return true;
 }
        public static bool OnBulletHit(Fixture a, Fixture b, Contact c)
        {
            // Fixture a is always the bullet, and Fixture b is what it hit.

            if (b.UserData is String && ((string)(b.UserData.ToString())).Equals("Wall"))
            {
                if (!m_toRemove.Contains(a.Body))
                    m_toRemove.Add(a.Body);
                return true;
            }
            if (b.Body.IsBullet)
                return true;
            // If we've gotten this far, b.UserData is an Object
            Projectile p = (Projectile)a.UserData;

            // If we hit a weapon.
            if (b.UserData is Weapon)
            {
                Weapon w = (Weapon)b.UserData;
                w.TakeDamage(p.GetPower());
            }
            // If we hit a bot
            if (b.UserData is Bot)
            {
                Bot bot = (Bot)b.UserData;
                bot.TakeDamage(p.GetPower());
            }
            // If we hit a projectile (e.g. an axe)
            if (b.UserData is Projectile)
            {
                Projectile o = (Projectile)b.UserData;
                o.TakeDamage(p.GetPower());
            }
            if (!m_toRemove.Contains(a.Body))
                m_toRemove.Add(a.Body);
            return true;
        }
Exemple #3
0
 public bool OnCollision(Fixture f1, Fixture f2, Contact c)
 {
     return true;
 }
 public void Add(Contact contact)
 {
     Debug.Assert(ContactCount < _contactCapacity);
     _contacts[ContactCount++] = contact;
 }
 public bool MyOnCollision(Fixture f1, Fixture f2, Contact c)
 {
     //f2.Body.Dispose();
     return true;
 }
Exemple #6
0
        private void Reset(Fixture fA, int indexA, Fixture fB, int indexB)
        {
            Flags = ContactFlags.Enabled;

            FixtureA = fA;
            FixtureB = fB;

            ChildIndexA = indexA;
            ChildIndexB = indexB;

            Manifold.PointCount = 0;

            Prev = null;
            Next = null;

            NodeA.Contact = null;
            NodeA.Prev = null;
            NodeA.Next = null;
            NodeA.Other = null;

            NodeB.Contact = null;
            NodeB.Prev = null;
            NodeB.Next = null;
            NodeB.Other = null;

            TOICount = 0;
        }
Exemple #7
0
        internal static Contact Create(Fixture fixtureA, int indexA, Fixture fixtureB, int indexB)
        {
            ShapeType type1 = fixtureA.ShapeType;
            ShapeType type2 = fixtureB.ShapeType;

            Debug.Assert(ShapeType.Unknown < type1 && type1 < ShapeType.TypeCount);
            Debug.Assert(ShapeType.Unknown < type2 && type2 < ShapeType.TypeCount);

            Contact c;
            Queue<Contact> pool = fixtureA.Body.World.ContactPool;
            if (pool.Count > 0)
            {
                c = pool.Dequeue();
                if ((type1 >= type2 || (type1 == ShapeType.Edge && type2 == ShapeType.Polygon))
                    &&
                    !(type2 == ShapeType.Edge && type1 == ShapeType.Polygon))
                {
                    c.Reset(fixtureA, indexA, fixtureB, indexB);
                }
                else
                {
                    c.Reset(fixtureB, indexB, fixtureA, indexA);
                }
            }
            else
            {
                // Edge+Polygon is non-symetrical due to the way Erin handles collision type registration.
                if ((type1 >= type2 || (type1 == ShapeType.Edge && type2 == ShapeType.Polygon))
                    &&
                    !(type2 == ShapeType.Edge && type1 == ShapeType.Polygon))
                {
                    c = new Contact(fixtureA, indexA, fixtureB, indexB);
                }
                else
                {
                    c = new Contact(fixtureB, indexB, fixtureA, indexA);
                }
            }

            c._type = _registers[(int) type1, (int) type2];

            return c;
        }
        private void PostSolve(Contact contact, ContactConstraint impulse)
        {
            if (!Broken)
            {
                if (Parts.Contains(contact.FixtureA) || Parts.Contains(contact.FixtureB))
                {
                    float maxImpulse = 0.0f;
                    int count = contact.Manifold.PointCount;

                    for (int i = 0; i < count; ++i)
                    {
                        maxImpulse = Math.Max(maxImpulse, impulse.Points[i].NormalImpulse);
                    }

                    if (maxImpulse > Strength)
                    {
                        // Flag the body for breaking.
                        _break = true;
                    }
                }
            }
        }
Exemple #9
0
        internal ContactManager()
        {
            ContactList = null;
            ContactCount = 0;

            OnBroadphaseCollision = AddPair;
        }
Exemple #10
0
        // Broad-phase callback.
        private void AddPair(ref FixtureProxy proxyA, ref FixtureProxy proxyB)
        {
            Fixture fixtureA = proxyA.Fixture;
            Fixture fixtureB = proxyB.Fixture;

            int indexA = proxyA.ChildIndex;
            int indexB = proxyB.ChildIndex;

            Body bodyA = fixtureA.Body;
            Body bodyB = fixtureB.Body;

            // Are the fixtures on the same body?
            if (bodyA == bodyB)
            {
                return;
            }

            // Does a contact already exist?
            ContactEdge edge = bodyB.ContactList;
            while (edge != null)
            {
                if (edge.Other == bodyA)
                {
                    Fixture fA = edge.Contact.FixtureA;
                    Fixture fB = edge.Contact.FixtureB;
                    int iA = edge.Contact.ChildIndexA;
                    int iB = edge.Contact.ChildIndexB;

                    if (fA == fixtureA && fB == fixtureB && iA == indexA && iB == indexB)
                    {
                        // A contact already exists.
                        return;
                    }

                    if (fA == fixtureB && fB == fixtureA && iA == indexB && iB == indexA)
                    {
                        // A contact already exists.
                        return;
                    }
                }

                edge = edge.Next;
            }

            // Does a joint override collision? Is at least one body dynamic?
            if (bodyB.ShouldCollide(bodyA) == false)
                return;

            //Check default filter
            if (ShouldCollide(fixtureA, fixtureB) == false)
                return;

            // Check user filtering.
            if (ContactFilter != null && ContactFilter(fixtureA, fixtureB) == false)
                return;

            if (fixtureA.BeforeCollision != null && fixtureA.BeforeCollision(fixtureA, fixtureB) == false)
                return;

            if (fixtureB.BeforeCollision != null && fixtureB.BeforeCollision(fixtureB, fixtureA) == false)
                return;

            // Call the factory.
            Contact c = Contact.Create(fixtureA, indexA, fixtureB, indexB);

            // Contact creation may swap fixtures.
            fixtureA = c.FixtureA;
            fixtureB = c.FixtureB;
            indexA = c.ChildIndexA;
            indexB = c.ChildIndexB;
            bodyA = fixtureA.Body;
            bodyB = fixtureB.Body;

            // Insert into the world.
            c.Prev = null;
            c.Next = ContactList;
            if (ContactList != null)
            {
                ContactList.Prev = c;
            }
            ContactList = c;

            // Connect to island graph.

            // Connect to body A
            c.NodeA.Contact = c;
            c.NodeA.Other = bodyB;

            c.NodeA.Prev = null;
            c.NodeA.Next = bodyA.ContactList;
            if (bodyA.ContactList != null)
            {
                bodyA.ContactList.Prev = c.NodeA;
            }
            bodyA.ContactList = c.NodeA;

            // Connect to body B
            c.NodeB.Contact = c;
            c.NodeB.Other = bodyA;

            c.NodeB.Prev = null;
            c.NodeB.Next = bodyB.ContactList;
            if (bodyB.ContactList != null)
            {
                bodyB.ContactList.Prev = c.NodeB;
            }
            bodyB.ContactList = c.NodeB;

            ++ContactCount;
        }
Exemple #11
0
        internal void Destroy(Contact contact)
        {
            Fixture fixtureA = contact.FixtureA;
            Fixture fixtureB = contact.FixtureB;
            Body bodyA = fixtureA.Body;
            Body bodyB = fixtureB.Body;

            if (EndContact != null && contact.IsTouching())
            {
                EndContact(contact);
            }

            // Remove from the world.
            if (contact.Prev != null)
            {
                contact.Prev.Next = contact.Next;
            }

            if (contact.Next != null)
            {
                contact.Next.Prev = contact.Prev;
            }

            if (contact == ContactList)
            {
                ContactList = contact.Next;
            }

            // Remove from body 1
            if (contact.NodeA.Prev != null)
            {
                contact.NodeA.Prev.Next = contact.NodeA.Next;
            }

            if (contact.NodeA.Next != null)
            {
                contact.NodeA.Next.Prev = contact.NodeA.Prev;
            }

            if (contact.NodeA == bodyA.ContactList)
            {
                bodyA.ContactList = contact.NodeA.Next;
            }

            // Remove from body 2
            if (contact.NodeB.Prev != null)
            {
                contact.NodeB.Prev.Next = contact.NodeB.Next;
            }

            if (contact.NodeB.Next != null)
            {
                contact.NodeB.Next.Prev = contact.NodeB.Prev;
            }

            if (contact.NodeB == bodyB.ContactList)
            {
                bodyB.ContactList = contact.NodeB.Next;
            }

            contact.Destroy();

            --ContactCount;
        }
        public void Reset(Contact[] contacts, int contactCount, float impulseRatio, bool warmstarting)
        {
            _contacts = contacts;

            _constraintCount = contactCount;

            // grow the array
            if (Constraints == null || Constraints.Length < _constraintCount)
            {
                Constraints = new ContactConstraint[_constraintCount*2];

                for (int i = 0; i < Constraints.Length; i++)
                {
                    Constraints[i] = new ContactConstraint();
                }
            }

            // Initialize position independent portions of the constraints.
            for (int i = 0; i < _constraintCount; ++i)
            {
                Contact contact = contacts[i];

                Fixture fixtureA = contact.FixtureA;
                Fixture fixtureB = contact.FixtureB;
                Shape shapeA = fixtureA.Shape;
                Shape shapeB = fixtureB.Shape;
                float radiusA = shapeA.Radius;
                float radiusB = shapeB.Radius;
                Body bodyA = fixtureA.Body;
                Body bodyB = fixtureB.Body;
                Manifold manifold = contact.Manifold;

                Debug.Assert(manifold.PointCount > 0);

                ContactConstraint cc = Constraints[i];
                cc.Friction = Settings.MixFriction(fixtureA.Friction, fixtureB.Friction);
                cc.Restitution = Settings.MixRestitution(fixtureA.Restitution, fixtureB.Restitution);
                cc.BodyA = bodyA;
                cc.BodyB = bodyB;
                cc.Manifold = manifold;
                cc.Normal = Vector2.Zero;
                cc.PointCount = manifold.PointCount;

                cc.LocalNormal = manifold.LocalNormal;
                cc.LocalPoint = manifold.LocalPoint;
                cc.RadiusA = radiusA;
                cc.RadiusB = radiusB;
                cc.Type = manifold.Type;

                for (int j = 0; j < cc.PointCount; ++j)
                {
                    ManifoldPoint cp = manifold.Points[j];
                    ContactConstraintPoint ccp = cc.Points[j];

                    if (warmstarting)
                    {
                        ccp.NormalImpulse = impulseRatio*cp.NormalImpulse;
                        ccp.TangentImpulse = impulseRatio*cp.TangentImpulse;
                    }
                    else
                    {
                        ccp.NormalImpulse = 0.0f;
                        ccp.TangentImpulse = 0.0f;
                    }

                    ccp.LocalPoint = cp.LocalPoint;
                    ccp.rA = Vector2.Zero;
                    ccp.rB = Vector2.Zero;
                    ccp.NormalMass = 0.0f;
                    ccp.TangentMass = 0.0f;
                    ccp.VelocityBias = 0.0f;
                }

                cc.K.SetZero();
                cc.NormalMass.SetZero();
            }
        }