public void Create(b2Body body, b2FixtureDef def) { m_userData = def.userData; m_friction = def.friction; m_restitution = def.restitution; m_body = body; Next = null; m_filter = def.filter; m_isSensor = def.isSensor; m_shape = def.shape.Clone(); // Reserve proxy space int childCount = m_shape.GetChildCount(); for (int i = 0; i < childCount; ++i) { b2FixtureProxy proxy = new b2FixtureProxy(); proxy.fixture = null; proxy.proxyId = b2BroadPhase.e_nullProxy; m_proxies.Add(proxy); } m_proxyCount = 0; m_density = def.density; }
public virtual void Synchronize(b2BroadPhase broadPhase, ref b2Transform transform1, ref b2Transform transform2) { if (m_proxyCount == 0) { return; } for (int i = 0, count = m_proxyCount; i < count; ++i) { b2FixtureProxy proxy = m_proxies[i]; // Compute an AABB that covers the swept shape (may miss some rotation effect). b2AABB aabb1, aabb2; Shape.ComputeAABB(out aabb1, ref transform1, proxy.childIndex); Shape.ComputeAABB(out aabb2, ref transform2, proxy.childIndex); proxy.aabb.Combine(ref aabb1, ref aabb2); b2Vec2 displacement; displacement.x = transform2.p.x - transform1.p.x; displacement.y = transform2.p.y - transform1.p.y; broadPhase.MoveProxy(proxy.proxyId, ref proxy.aabb, ref displacement); } }
public virtual 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 = b2BroadPhase.e_nullProxy; } m_proxies.Clear(); m_proxyCount = 0; }
public virtual void CreateProxies(b2BroadPhase broadPhase, b2Transform xf) { // Create proxies in the broad-phase. m_proxyCount = m_shape.GetChildCount(); for (int i = 0; i < m_proxyCount; ++i) { b2FixtureProxy proxy = m_proxies[i]; proxy.aabb = m_shape.ComputeAABB(xf, i); proxy.proxyId = broadPhase.CreateProxy(proxy.aabb, proxy); proxy.fixture = this; proxy.childIndex = i; } }
public float RayCastCallback(ref b2RayCastInput input, int proxyId) { b2FixtureProxy proxy = broadPhase.GetUserData(proxyId); b2Fixture fixture = proxy.fixture; int index = proxy.childIndex; b2RayCastOutput output; bool hit = fixture.RayCast(out output, input, index); if (hit) { float fraction = output.fraction; b2Vec2 point = (1.0f - fraction) * input.p1 + fraction * input.p2; return(callback.ReportFixture(fixture, point, output.normal, fraction)); } return(input.maxFraction); }
public virtual 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, aabb2; aabb1 = m_shape.ComputeAABB(transform1, proxy.childIndex); aabb2 = m_shape.ComputeAABB(transform2, proxy.childIndex); proxy.aabb.Combine(aabb1, aabb2); b2Vec2 displacement = transform2.p - transform1.p; broadPhase.MoveProxy(proxy.proxyId, proxy.aabb, displacement); } }
public void DrawDebugData() { if (m_debugDraw == null) { return; } b2DrawFlags flags = m_debugDraw.GetFlags(); if (flags & b2DrawFlags.e_shapeBit) { for (b2Body b = m_bodyList; b; b = b.Next) { b2Transform xf = b.Transform; for (b2Fixture f = b.FixtureList; f != null; f = f.Next) { if (b.IsActive() == false) { DrawShape(f, xf, new b2Color(0.5f, 0.5f, 0.3f)); } else if (b.GetType() == b2BodyType.b2_staticBody) { DrawShape(f, xf, new b2Color(0.5f, 0.9f, 0.5f)); } else if (b.GetType() == b2BodyType.b2_kinematicBody) { DrawShape(f, xf, new b2Color(0.5f, 0.5f, 0.9f)); } else if (b.IsAwake() == false) { DrawShape(f, xf, new b2Color(0.6f, 0.6f, 0.6f)); } else { DrawShape(f, xf, new b2Color(0.9f, 0.7f, 0.7f)); } } } } if (flags.HasFlag(b2DrawFlags.e_jointBit)) { for (b2Joint j = m_jointList; j != null; j = j.GetNext()) { DrawJoint(j); } } if (flags.HasFlag(b2DrawFlags.e_pairBit)) { b2Color color = new b2Color(0.3f, 0.9f, 0.9f); for (b2Contact c = m_contactManager.ContactList; c != null; c = c.Next) { //b2Fixture fixtureA = c.GetFixtureA(); //b2Fixture fixtureB = c.GetFixtureB(); //b2Vec2 cA = fixtureA.GetAABB().GetCenter(); //b2Vec2 cB = fixtureB.GetAABB().GetCenter(); //m_debugDraw.DrawSegment(cA, cB, color); } } if (flags.HasFlag(b2DrawFlags.e_aabbBit)) { b2Color color(0.9f, 0.3f, 0.9f); b2BroadPhase bp = m_contactManager.BroadPhase; for (b2Body b = m_bodyList; b != null; b = b.Next) { if (b.IsActive() == false) { continue; } for (b2Fixture f = b.FixtureList; f != null; f = f.Next) { for (int i = 0; i < f.ProxyCount; ++i) { b2FixtureProxy proxy = f.Proxies[i]; b2AABB aabb = bp.GetFatAABB(proxy.proxyId); b2Vec2[] vs = new b2Vec2[4]; vs[0].Set(aabb.lowerBound.x, aabb.lowerBound.y); vs[1].Set(aabb.upperBound.x, aabb.lowerBound.y); vs[2].Set(aabb.upperBound.x, aabb.upperBound.y); vs[3].Set(aabb.lowerBound.x, aabb.upperBound.y); m_debugDraw.DrawPolygon(vs, 4, color); } } } } if (flags.HasFlag(b2DrawFlags.e_centerOfMassBit)) { for (b2Body b = m_bodyList; b != null; b = b.Next) { b2Transform xf = b.Transform; xf.p = b.WorldCenter; m_debugDraw.DrawTransform(xf); } } }
public bool QueryCallback(int proxyId) { b2FixtureProxy proxy = (b2FixtureProxy)broadPhase.GetUserData(proxyId); return(callback.ReportFixture(proxy.fixture)); }
public void AddPair(ref b2FixtureProxy proxyA, ref b2FixtureProxy proxyB) { b2Fixture fixtureA = proxyA.fixture; b2Fixture fixtureB = proxyB.fixture; int indexA = proxyA.childIndex; int indexB = proxyB.childIndex; b2Body bodyA = fixtureA.Body; b2Body 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? b2ContactEdge edge = bodyB.ContactList; while (edge != null) { if (edge.Other == bodyA) { b2Fixture fA = edge.Contact.FixtureA; b2Fixture fB = edge.Contact.FixtureB; int iA = edge.Contact.m_indexA; int iB = edge.Contact.m_indexB; 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)) { return; } // Check user filtering. if (m_contactFilter != null && !m_contactFilter.ShouldCollide(fixtureA, fixtureB)) { return; } // Call the factory. b2Contact c = b2Contact.Create(fixtureA, indexA, fixtureB, indexB); if (c == null) { return; } // Contact creation may swap fixtures. //fixtureA = c.FixtureA; //fixtureB = c.FixtureB; //indexA = c.m_indexA; //indexB = c.m_indexB; bodyA = c.FixtureA.Body; bodyB = c.FixtureB.Body; // Insert into the world. c.Prev = null; c.Next = m_contactList; if (m_contactList != null) { m_contactList.Prev = c; } m_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.SetAwake(true); bodyB.SetAwake(true); ++m_contactCount; }
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) { 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 && m_contactFilter.ShouldCollide(fixtureA, fixtureB) == false) { return; } // Call the factory. b2Contact c = b2Contact.Create(fixtureA, indexA, fixtureB, indexB, m_allocator); 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 bodyA.SetAwake(true); bodyB.SetAwake(true); ++m_contactCount; }