/** @private */ virtual public void Reset(b2Fixture fixtureA = null, b2Fixture fixtureB = null) { m_flags = e_enabledFlag; if (fixtureA == null || fixtureB == null) { m_fixtureA = null; m_fixtureB = null; return; } if (fixtureA.IsSensor() || fixtureB.IsSensor()) { m_flags |= e_sensorFlag; } b2Body bodyA = fixtureA.GetBody(); b2Body bodyB = fixtureB.GetBody(); if (bodyA.GetType() != b2Body.b2_dynamicBody || bodyA.IsBullet() || bodyB.GetType() != b2Body.b2_dynamicBody || bodyB.IsBullet()) { m_flags |= e_continuousFlag; } m_fixtureA = fixtureA; m_fixtureB = fixtureB; m_manifold.m_pointCount = 0; m_prev = null; m_next = null; m_nodeA.contact = null; m_nodeA.prev = null; m_nodeA.next = null; m_nodeA.other = null; m_nodeB.contact = null; m_nodeB.prev = null; m_nodeB.next = null; m_nodeB.other = null; }
internal static void Destroy(ref b2Contact contact) { Debug.Assert(s_initialized == true); b2Fixture fixtureA = contact.m_fixtureA; b2Fixture fixtureB = contact.m_fixtureB; if (contact.m_manifold.pointCount > 0 && fixtureA.IsSensor() == false && fixtureB.IsSensor() == false) { fixtureA.GetBody().SetAwake(true); fixtureB.GetBody().SetAwake(true); } b2Shape.Type typeA = fixtureA.GetType(); b2Shape.Type typeB = fixtureB.GetType(); Debug.Assert(0 <= ((int)typeA) && typeB < b2Shape.Type.e_typeCount); Debug.Assert(0 <= ((int)typeA) && typeB < b2Shape.Type.e_typeCount); b2ContactDestroyFcn destroyFcn = s_registers[(int)typeA, (int)typeB].destroyFcn; destroyFcn(ref contact); }
// Broad-phase callback. public void AddPair(object proxyUserDataA, object proxyUserDataB) { b2FixtureProxy proxyA = (b2FixtureProxy)proxyUserDataA; b2FixtureProxy proxyB = (b2FixtureProxy)proxyUserDataB; b2Fixture fixtureA = proxyA.fixture; b2Fixture fixtureB = proxyB.fixture; int indexA = proxyA.childIndex; int indexB = proxyB.childIndex; b2Body bodyA = fixtureA.GetBody(); b2Body bodyB = fixtureB.GetBody(); // 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? b2ContactEdge edge = bodyB.GetContactList(); while (edge != null) { if (edge.other == bodyA) { b2Fixture fA = edge.contact.GetFixtureA(); b2Fixture fB = edge.contact.GetFixtureB(); int iA = edge.contact.GetChildIndexA(); int iB = edge.contact.GetChildIndexB(); 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 user filtering. if (m_contactFilter != null && m_contactFilter.ShouldCollide(fixtureA, fixtureB) == false) { return; } // Call the factory. b2Contact c = b2Contact.Create(fixtureA, indexA, fixtureB, indexB); if (c == null) { return; } // Contact creation may swap fixtures. fixtureA = c.GetFixtureA(); fixtureB = c.GetFixtureB(); indexA = c.GetChildIndexA(); indexB = c.GetChildIndexB(); bodyA = fixtureA.GetBody(); bodyB = fixtureB.GetBody(); // Insert into the world. c.m_prev = null; c.m_next = m_contactList; if (m_contactList != null) { m_contactList.m_prev = c; } m_contactList = c; // Connect to island graph. // Connect to body A c.m_nodeA.contact = c; c.m_nodeA.other = bodyB; c.m_nodeA.prev = null; c.m_nodeA.next = bodyA.m_contactList; if (bodyA.m_contactList != null) { bodyA.m_contactList.prev = c.m_nodeA; } bodyA.m_contactList = c.m_nodeA; // Connect to body B c.m_nodeB.contact = c; c.m_nodeB.other = bodyA; c.m_nodeB.prev = null; c.m_nodeB.next = bodyB.m_contactList; if (bodyB.m_contactList != null) { bodyB.m_contactList.prev = c.m_nodeB; } bodyB.m_contactList = c.m_nodeB; // Wake up the bodies if (fixtureA.IsSensor() == false && fixtureB.IsSensor() == false) { bodyA.SetAwake(true); bodyB.SetAwake(true); } ++m_contactCount; }