// This is a callback from the broadphase when two AABB proxies begin // to overlap. We create a Contact to manage the narrow phase. public override object PairAdded(object proxyUserData1, object proxyUserData2) { Shape shape1 = proxyUserData1 as Shape; Shape shape2 = proxyUserData2 as Shape; Body body1 = shape1.GetBody(); Body body2 = shape2.GetBody(); if (body1.IsStatic() && body2.IsStatic()) { return(_nullContact); } if (shape1.GetBody() == shape2.GetBody()) { return(_nullContact); } if (body2.IsConnected(body1)) { return(_nullContact); } if (_world._contactFilter != null && _world._contactFilter.ShouldCollide(shape1, shape2) == false) { return(_nullContact); } // Call the factory. Contact c = Contact.Create(shape1, shape2); if (c == null) { return(_nullContact); } // Contact creation may swap shapes. shape1 = c.GetShape1(); shape2 = c.GetShape2(); body1 = shape1.GetBody(); body2 = shape2.GetBody(); // Insert into the world. c._prev = null; c._next = _world._contactList; if (_world._contactList != null) { _world._contactList._prev = c; } _world._contactList = c; // Connect to island graph. // Connect to body 1 c._node1.Contact = c; c._node1.Other = body2; c._node1.Prev = null; c._node1.Next = body1._contactList; if (body1._contactList != null) { body1._contactList.Prev = c._node1; } body1._contactList = c._node1; // Connect to body 2 c._node2.Contact = c; c._node2.Other = body1; c._node2.Prev = null; c._node2.Next = body2._contactList; if (body2._contactList != null) { body2._contactList.Prev = c._node2; } body2._contactList = c._node2; ++_world._contactCount; return(c); }
public void AddPair(object proxyUserDataA, object proxyUserDataB) { Fixture fixtureA = (Fixture)proxyUserDataA; Fixture fixtureB = (Fixture)proxyUserDataB; Body bodyA = fixtureA.GetBody(); Body bodyB = fixtureB.GetBody(); // Are the fixtures on the same body? if (bodyA == bodyB) { return; } // Are both bodies static? if (bodyA.IsStatic() && bodyB.IsStatic()) { return; } // Does a contact already exist? ContactEdge edge = bodyB.GetContactList(); while (edge != null) { if (edge.Other == bodyA) { Fixture fA = edge.Contact.GetFixtureA(); Fixture fB = edge.Contact.GetFixtureB(); if (fA == fixtureA && fB == fixtureB) { // A contact already exists. return; } if (fA == fixtureB && fB == fixtureA) { // A contact already exists. return; } } edge = edge.Next; } // Does a joint override collision? if (bodyB.IsConnected(bodyA)) { return; } // Check user filtering. if (_contactFilter.ShouldCollide(fixtureA, fixtureB) == false) { return; } // Call the factory. Contact c = Contact.Create(fixtureA, fixtureB); // Contact creation may swap fixtures. fixtureA = c.GetFixtureA(); fixtureB = c.GetFixtureB(); bodyA = fixtureA.GetBody(); bodyB = fixtureB.GetBody(); // 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; }
public override object PairAdded(object proxyUserData1, object proxyUserData2) { Shape shape = proxyUserData1 as Shape; Shape shape2 = proxyUserData2 as Shape; Body body = shape.GetBody(); Body body2 = shape2.GetBody(); object result; if (body.IsStatic() && body2.IsStatic()) { result = this._nullContact; } else { if (shape.GetBody() == shape2.GetBody()) { result = this._nullContact; } else { if (body2.IsConnected(body)) { result = this._nullContact; } else { if (this._world._contactFilter != null && !this._world._contactFilter.ShouldCollide(shape, shape2)) { result = this._nullContact; } else { Contact contact = Contact.Create(shape, shape2); if (contact == null) { result = this._nullContact; } else { shape = contact.GetShape1(); shape2 = contact.GetShape2(); body = shape.GetBody(); body2 = shape2.GetBody(); contact._prev = null; contact._next = this._world._contactList; if (this._world._contactList != null) { this._world._contactList._prev = contact; } this._world._contactList = contact; contact._node1.Contact = contact; contact._node1.Other = body2; contact._node1.Prev = null; contact._node1.Next = body._contactList; if (body._contactList != null) { body._contactList.Prev = contact._node1; } body._contactList = contact._node1; contact._node2.Contact = contact; contact._node2.Other = body; contact._node2.Prev = null; contact._node2.Next = body2._contactList; if (body2._contactList != null) { body2._contactList.Prev = contact._node2; } body2._contactList = contact._node2; this._world._contactCount++; result = contact; } } } } } return(result); }
// This is the top level collision call for the time step. Here // all the narrow phase collision is processed for the world // contact list. public void Collide() { // Update awake contacts. Contact c = _contactList; while (c != null) { Fixture fixtureA = c.GetFixtureA(); Fixture fixtureB = c.GetFixtureB(); Body bodyA = fixtureA.GetBody(); Body bodyB = fixtureB.GetBody(); if (bodyA.IsSleeping() && bodyB.IsSleeping()) { c = c.GetNext(); continue; } // Is this contact flagged for filtering? if ((c.Flags & ContactFlag.FilterFlag) == ContactFlag.FilterFlag) { //TODO: The following code (next 4 if blocks) use a class and thus copy by ref. It might expect to copy by value // Are both bodies static? if (bodyA.IsStatic() && bodyB.IsStatic()) { Contact cNuke = c; c = cNuke.GetNext(); Destroy(cNuke); continue; } // Does a joint override collision? if (bodyB.IsConnected(bodyA)) { Contact cNuke = c; c = cNuke.GetNext(); Destroy(cNuke); continue; } // Check user filtering. if (_contactFilter.ShouldCollide(fixtureA, fixtureB) == false) { Contact cNuke = c; c = cNuke.GetNext(); Destroy(cNuke); continue; } // Clear the filtering flag. c.Flags &= ~ContactFlag.FilterFlag; } int proxyIdA = fixtureA.ProxyId; int proxyIdB = fixtureB.ProxyId; bool overlap = _broadPhase.TestOverlap(proxyIdA, proxyIdB); // Here we destroy contacts that cease to overlap in the broad-phase. if (overlap == false) { Contact cNuke = c; c = cNuke.GetNext(); Destroy(cNuke); continue; } // The contact persists. c.Update(_contactListener); c = c.GetNext(); } }
// This is a callback from the broadphase when two AABB proxies begin // to overlap. We create a Contact to manage the narrow phase. public override object PairAdded(object proxyUserDataA, object proxyUserDataB) { Fixture fixtureA = proxyUserDataA as Fixture; Fixture fixtureB = proxyUserDataB as Fixture; Body bodyA = fixtureA.Body; Body bodyB = fixtureB.Body; if (bodyA.IsStatic() && bodyB.IsStatic()) { return(_nullContact); } if (fixtureA.Body == fixtureB.Body) { return(_nullContact); } if (bodyB.IsConnected(bodyA)) { return(_nullContact); } if (_world._contactFilter != null && _world._contactFilter.ShouldCollide(fixtureA, fixtureB) == false) { return(_nullContact); } // Call the factory. Contact c = Contact.Create(fixtureA, fixtureB); if (c == null) { return(_nullContact); } // Contact creation may swap shapes. fixtureA = c.FixtureA; fixtureB = c.FixtureB; bodyA = fixtureA.Body; bodyB = fixtureB.Body; // Insert into the world. c._prev = null; c._next = _world._contactList; if (_world._contactList != null) { _world._contactList._prev = c; } _world._contactList = c; // Connect to island graph. // Connect to body 1 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 2 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; ++_world._contactCount; return(c); }