// We need separation create/destroy functions from the constructor/destructor because // the destructor cannot access the allocator (no destructor arguments allowed by C++). public void Create(Body body, FixtureDef def) { UserData = def.UserData; Friction = def.Friction; Restitution = def.Restitution; Body = body; Next = null; Filter.Set(def.Filter); IsSensor = def.IsSensor; Shape = def.Shape.Clone(); // Reserve proxy space int childCount = Shape.ChildCount; if (Proxies == null) { Proxies = new FixtureProxy[childCount]; for (int i = 0; i < childCount; i++) { Proxies[i] = new FixtureProxy {Fixture = null, ProxyId = BroadPhase.NULL_PROXY}; } } if (Proxies.Length < childCount) { FixtureProxy[] old = Proxies; int newLen = MathUtils.Max(old.Length * 2, childCount); Proxies = new FixtureProxy[newLen]; Array.Copy(old, 0, Proxies, 0, old.Length); for (int i = 0; i < newLen; i++) { if (i >= old.Length) { Proxies[i] = new FixtureProxy(); } Proxies[i].Fixture = null; Proxies[i].ProxyId = BroadPhase.NULL_PROXY; } } ProxyCount = 0; m_density = def.Density; }
/// <summary> /// Broad-phase callback. /// </summary> /// <param name="proxyUserDataA"></param> /// <param name="proxyUserDataB"></param> public void AddPair(object proxyUserDataA, object proxyUserDataB) { FixtureProxy proxyA = (FixtureProxy)proxyUserDataA; FixtureProxy proxyB = (FixtureProxy)proxyUserDataB; 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; } // TODO_ERIN use a hash table to remove a potential bottleneck when both // bodies have a lot of contacts. // 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 && iA == indexA && fB == fixtureB && iB == indexB) { // A contact already exists. return; } if (fA == fixtureB && iA == indexB && fB == fixtureA && 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 user filtering. if (ContactFilter != null && ContactFilter.ShouldCollide(fixtureA, fixtureB) == false) { return; } // Call the factory. Contact c = pool.PopContact(fixtureA, indexA, fixtureB, indexB); if (c == null) { return; } // Contact creation may swap fixtures. fixtureA = c.FixtureA; fixtureB = c.FixtureB; 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; // wake up the bodies bodyA.Awake = true; bodyB.Awake = true; ++ContactCount; }
// We need separation create/destroy functions from the constructor/destructor because // the destructor cannot access the allocator (no destructor arguments allowed by C++). public virtual void create(Body body, FixtureDef def) { m_userData = def.userData; m_friction = def.friction; m_restitution = def.restitution; m_body = body; m_next = null; m_filter.set_Renamed(def.filter); m_isSensor = def.isSensor; m_shape = def.shape.Clone(); // Reserve proxy space int childCount = m_shape.ChildCount; if (m_proxies == null) { m_proxies = new FixtureProxy[childCount]; for (int i = 0; i < childCount; i++) { m_proxies[i] = new FixtureProxy(); m_proxies[i].fixture = null; m_proxies[i].proxyId = BroadPhase.NULL_PROXY; } } if (m_proxies.Length < childCount) { FixtureProxy[] old = m_proxies; int newLen = MathUtils.max(old.Length * 2, childCount); m_proxies = new FixtureProxy[newLen]; Array.Copy(old, 0, m_proxies, 0, old.Length); for (int i = 0; i < newLen; i++) { if (i >= old.Length) { m_proxies[i] = new FixtureProxy(); } m_proxies[i].fixture = null; m_proxies[i].proxyId = BroadPhase.NULL_PROXY; } } m_proxyCount = 0; m_density = def.density; }