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; }
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; }
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; }
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; } } } }
internal ContactManager() { ContactList = null; ContactCount = 0; OnBroadphaseCollision = AddPair; }
// 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; }
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(); } }