public int AddProxy(ref FixtureProxy proxy) { int proxyID = _currID++; proxy.ProxyId = proxyID; AABB aabb = Fatten(ref proxy.AABB); Element<FixtureProxy> qtnode = new Element<FixtureProxy>(proxy, aabb); _idRegister.Add(proxyID, qtnode); _quadTree.AddNode(qtnode); return proxyID; }
// These support body activation/deactivation. internal void CreateProxies(IBroadPhase broadPhase, ref Transform xf) { Debug.Assert(ProxyCount == 0); // Create proxies in the broad-phase. ProxyCount = Shape.ChildCount; for (int i = 0; i < ProxyCount; ++i) { FixtureProxy proxy = new FixtureProxy(); Shape.ComputeAABB(out proxy.AABB, ref xf, i); proxy.Fixture = this; proxy.ChildIndex = i; proxy.ProxyId = broadPhase.AddProxy(ref proxy); Proxies[i] = proxy; } }
// 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; PhysicsBody bodyA = fixtureA.Body; PhysicsBody 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; bodyA = fixtureA.Body; bodyB = fixtureB.Body; // Insert into the world. ContactList.Add(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; }