// We need separation create/destroy functions from the constructor/destructor because // the destructor cannot access the allocator (no destructor arguments allowed by C++). internal void Create(b2Body body, b2FixtureDef def) { m_userData = def.userData; m_friction = def.friction; m_restitution = def.restitution; m_body = body; m_next = null; m_filter = def.filter; m_isSensor = def.isSensor; m_shape = def.shape.Clone(); // Reserve proxy space int childCount = m_shape.GetChildCount(); m_proxies = Arrays.InitializeWithDefaultInstances <b2FixtureProxy>(childCount); for (int i = 0; i < childCount; ++i) { m_proxies[i] = new b2FixtureProxy(); m_proxies[i].fixture = null; m_proxies[i].proxyId = (int)b2BroadPhase.AnonymousEnum.e_nullProxy; } m_proxyCount = 0; m_density = def.density; }
public int CreateProxy(ref b2AABB aabb, ref b2FixtureProxy userData) { int proxyId = m_tree.CreateProxy(ref aabb, ref userData); ++m_proxyCount; BufferMove(proxyId); return(proxyId); }
internal void DestroyProxies(b2BroadPhase broadPhase) { // Destroy proxies in the broad-phase. for (int i = 0; i < m_proxyCount; ++i) { b2FixtureProxy proxy = m_proxies[i]; broadPhase.DestroyProxy(proxy.proxyId); proxy.proxyId = (int)b2BroadPhase.AnonymousEnum.e_nullProxy; } m_proxyCount = 0; }
// These support body activation/deactivation. internal void CreateProxies(b2BroadPhase broadPhase, b2Transform xf) { Debug.Assert(m_proxyCount == 0); // Create proxies in the broad-phase. m_proxyCount = m_shape.GetChildCount(); for (int i = 0; i < m_proxyCount; ++i) { b2FixtureProxy proxy = m_proxies[i]; m_shape.ComputeAABB(ref proxy.aabb, xf, i); proxy.proxyId = broadPhase.CreateProxy(ref proxy.aabb, proxy); proxy.fixture = this; proxy.childIndex = i; } }
internal void Synchronize(b2BroadPhase broadPhase, b2Transform transform1, b2Transform transform2) { if (m_proxyCount == 0) { return; } for (int i = 0; i < m_proxyCount; ++i) { b2FixtureProxy proxy = m_proxies[i]; // Compute an AABB that covers the swept shape (may miss some rotation effect). b2AABB aabb1 = new b2AABB(); b2AABB aabb2 = new b2AABB(); m_shape.ComputeAABB(ref aabb1, transform1, proxy.childIndex); m_shape.ComputeAABB(ref aabb2, transform2, proxy.childIndex); proxy.aabb.Combine(ref aabb1, ref aabb2); b2Vec2 displacement = transform2.p - transform1.p; broadPhase.MoveProxy(proxy.proxyId, ref proxy.aabb, displacement); } }
internal static global::System.Runtime.InteropServices.HandleRef getCPtr(b2FixtureProxy obj) { return((obj == null) ? new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero) : obj.swigCPtr); }
// 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; }