internal void Synchronize(BroadPhase broadPhase, Transform transform1, Transform transform2) //broadphase was pointer { if (m_proxies.Count() == 0) { return; } for (int i = 0; i < m_proxies.Count(); ++i) { FixtureProxy proxy = m_proxies[i]; // Compute an AABB that covers the swept shape (may miss some rotation effect). AABB aabb1, aab; m_shape.ComputeAABB(out aabb1, transform1, proxy.childIndex); m_shape.ComputeAABB(out aab, transform2, proxy.childIndex); proxy.aabb.Combine(aabb1, aab); Vec2 displacement = transform2.p - transform1.p; broadPhase.MoveProxy(proxy.proxyId, proxy.aabb, displacement); } }
internal void Synchronize(BroadPhase broadPhase, ref Transform transform1, ref Transform transform2) { if (_proxyCount == 0) { return; } for (int i = 0; i < _proxyCount; ++i) { FixtureProxy proxy = _proxies[i]; // Compute an AABB that covers the swept Shape (may miss some rotation effect). AABB 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); Vector2 displacement = transform2.Position - transform1.Position; broadPhase.MoveProxy(proxy.proxyId, ref proxy.aabb, displacement); } }
bool QueryCallback(int proxyId) { FixtureProxy proxy = (FixtureProxy)broadPhase.GetUserData(proxyId); return(callback.ReportFixture(proxy.fixture)); }
// Broad-phase callback. internal void AddPair(FixtureProxy proxyA, FixtureProxy proxyB) { Fixture fixtureA = proxyA.fixture; Fixture fixtureB = proxyB.fixture; int indexA = proxyA.childIndex; int indexB = proxyB.childIndex; Body bodyA = fixtureA.GetBody(); Body bodyB = fixtureB.GetBody(); // Are the fixtures on the same body? if (bodyA == bodyB) { return; } // Does a contact already exist? ContactEdge edge = bodyB.GetContactList(); while (edge != null) { if (edge.Other == bodyA) { Fixture fA = edge.Contact.GetFixtureA(); Fixture 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 (ContactFilter != null && ContactFilter.ShouldCollide(fixtureA, fixtureB) == false) { return; } // Call the factory. Contact c = Contact.Create(fixtureA, indexA, fixtureB, indexB); // 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._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; ++_contactCount; }
// Broad-phase callback. 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.GetBody(); Body 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? List <ContactEdge> edges = bodyB.GetContactList(); foreach (ContactEdge edge in edges) { if (edge.other == bodyA) { Fixture fA = edge.contact.FixtureA; Fixture fB = edge.contact.FixtureB; 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; } } } // 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. Contact c = Contact.Create(fixtureA, indexA, fixtureB, indexB); if (c == null) { return; } // Contact creation may swap fixtures. fixtureA = c.FixtureA; fixtureB = c.FixtureB; indexA = c.GetChildIndexA(); indexB = c.GetChildIndexB(); bodyA = fixtureA.GetBody(); bodyB = fixtureB.GetBody(); // Insert into the world. m_contactList.Add(c); // Connect to island graph. // Connect to body A c.m_nodeA.contact = c; c.m_nodeA.other = bodyB; bodyA.m_contactList.Add(c.m_nodeA); // Connect to body B c.m_nodeB.contact = c; c.m_nodeB.other = bodyA; bodyB.m_contactList.Add(c.m_nodeB); // Wake up the bodies if (fixtureA.IsSensor == false && fixtureB.IsSensor == false) { bodyA.SetAwake(true); bodyB.SetAwake(true); } }
// These support body activation/deactivation. internal void CreateProxies(BroadPhase broadPhase, Transform xf){ //broadPhase was pointer Utilities.Assert(m_proxies.Count() == 0); // Create proxies in the broad-phase. int m_proxyCount = m_shape.GetChildCount(); for (int i = 0; i < m_proxyCount; ++i) { FixtureProxy proxy = new FixtureProxy(); m_shape.ComputeAABB(out proxy.aabb, xf, i); proxy.proxyId = broadPhase.CreateProxy(proxy.aabb, proxy); proxy.fixture = this; proxy.childIndex = i; m_proxies.Add(proxy); } }
bool QueryAABBCallbackWrapper(int proxyId) { FixtureProxy proxy = (FixtureProxy)_contactManager._broadPhase.GetUserData(proxyId); return(_queryAABBCallback(proxy)); }
/// Call this to draw shapes and other debug draw data. public void DrawDebugData() { if (DebugDraw == null) { return; } DebugDrawFlags flags = DebugDraw.Flags; if ((flags & DebugDrawFlags.Shape) == DebugDrawFlags.Shape) { for (Body b = _bodyList; b != null; b = b.GetNext()) { Transform xf; b.GetTransform(out xf); for (Fixture f = b.GetFixtureList(); f != null; f = f.GetNext()) { if (b.IsActive() == false) { DrawShape(f, xf, new Color(0.5f, 0.5f, 0.3f)); } else if (b.GetType() == BodyType.Static) { DrawShape(f, xf, new Color(0.5f, 0.9f, 0.5f)); } else if (b.GetType() == BodyType.Kinematic) { DrawShape(f, xf, new Color(0.5f, 0.5f, 0.9f)); } else if (b.IsAwake() == false) { DrawShape(f, xf, new Color(0.6f, 0.6f, 0.6f)); } else { DrawShape(f, xf, new Color(0.9f, 0.7f, 0.7f)); } } } } if ((flags & DebugDrawFlags.Joint) == DebugDrawFlags.Joint) { for (Joint j = _jointList; j != null; j = j.GetNext()) { DrawJoint(j); } } if ((flags & DebugDrawFlags.Pair) == DebugDrawFlags.Pair) { Color color = new Color(0.3f, 0.9f, 0.9f); for (Contact c = _contactManager._contactList; c != null; c = c.GetNext()) { /* * Fixture fixtureA = c.GetFixtureA(); * Fixture fixtureB = c.GetFixtureB(); * * AABB aabbA; * AABB aabbB; * fixtureA.GetAABB(out aabbA); * fixtureB.GetAABB(out aabbB); * * Vector2 cA = aabbA.GetCenter(); * Vector2 cB = aabbB.GetCenter(); * * DebugDraw.DrawSegment(cA, cB, color); */ } } if ((flags & DebugDrawFlags.AABB) == DebugDrawFlags.AABB) { Color color = new Color(0.9f, 0.3f, 0.9f); BroadPhase bp = _contactManager._broadPhase; for (Body b = _bodyList; b != null; b = b.GetNext()) { if (b.IsActive() == false) { continue; } for (Fixture f = b.GetFixtureList(); f != null; f = f.GetNext()) { for (int i = 0; i < f._proxyCount; ++i) { FixtureProxy proxy = f._proxies[i]; AABB aabb; bp.GetFatAABB(proxy.proxyId, out aabb); FixedArray8 <Vector2> vs = new FixedArray8 <Vector2>(); vs[0] = new Vector2(aabb.lowerBound.x, aabb.lowerBound.y); vs[1] = new Vector2(aabb.upperBound.x, aabb.lowerBound.y); vs[2] = new Vector2(aabb.upperBound.x, aabb.upperBound.y); vs[3] = new Vector2(aabb.lowerBound.x, aabb.upperBound.y); DebugDraw.DrawPolygon(ref vs, 4, color); } } } } if ((flags & DebugDrawFlags.CenterOfMass) == DebugDrawFlags.CenterOfMass) { for (Body b = _bodyList; b != null; b = b.GetNext()) { Transform xf; b.GetTransform(out xf); xf.Position = b.GetWorldCenter(); DebugDraw.DrawTransform(ref xf); } } }
/// Call this to draw shapes and other debug draw data. public void DrawDebugData() { if (m_debugDraw == null) { return; } Draw.DrawFlags flags = m_debugDraw.GetFlags(); if (flags.HasFlag(Draw.DrawFlags.e_shapeBit)) { foreach (Body b in m_bodyList) { Transform xf = b.GetTransform(); foreach (Fixture f in b.GetFixtureList()) { if (b.IsActive() == false) { DrawShape(f, xf, Color.FromArgb(128, 128, 75)); } else if (b.GetBodyType() == BodyType._staticBody) { DrawShape(f, xf, Color.FromArgb(128, 225, 128)); } else if (b.GetBodyType() == BodyType._kinematicBody) { DrawShape(f, xf, Color.FromArgb(128, 128, 225)); } else if (b.IsAwake() == false) { DrawShape(f, xf, Color.FromArgb(150, 150, 150)); } else { DrawShape(f, xf, Color.FromArgb(225, 175, 175)); } } } } if (flags.HasFlag(Draw.DrawFlags.e_jointBit)) { foreach (Joint j in m_jointList) { DrawJoint(j); } } if (flags.HasFlag(Draw.DrawFlags.e_pairBit)) { Color color = Color.FromArgb(75, 225, 225); foreach (Contact c in m_contactManager.m_contactList) { //Fixture fixtureA = c.FixtureA; //Fixture fixtureB = c.FixtureB; //Vec2 cA = fixtureA.GetAABB().GetCenter(); //Vec2 cB = fixtureB.GetAABB().GetCenter(); //m_debugDraw.DrawSegment(cA, cB, color); } } if (flags.HasFlag(Draw.DrawFlags.e_aabbBit)) { Color color = Color.FromArgb(225, 75, 225); BroadPhase bp = m_contactManager.m_broadPhase; foreach (Body b in m_bodyList) { if (b.IsActive() == false) { continue; } foreach (Fixture f in b.GetFixtureList()) { for (int i = 0; i < f.m_proxies.Count(); ++i) { FixtureProxy proxy = f.m_proxies[i]; AABB aabb = bp.GetFatAABB(proxy.proxyId); Vec2[] vs = new Vec2[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(Draw.DrawFlags.e_centerOfMassBit)) { foreach (Body b in m_bodyList) { Transform xf = b.GetTransform(); xf.p = b.GetWorldCenter(); m_debugDraw.DrawTransform(xf); } } }