// For teleporting a body without considering new contacts immediately. public void SetTransformIgnoreContacts(Vector2 position, float angle) { Debug.Assert(_world.IsLocked == false); if (_world.IsLocked == true) { return; } _xf.R.Set(angle); _xf.Position = position; _sweep.c0 = _sweep.c = MathUtils.Multiply(ref _xf, _sweep.localCenter); _sweep.a0 = _sweep.a = angle; BroadPhase broadPhase = _world._contactManager._broadPhase; for (Fixture f = _fixtureList; f != null; f = f._next) { f.Synchronize(broadPhase, ref _xf, ref _xf); } }
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); } }
/// Creates a fixture and attach it to this body. Use this function if you need /// to set some fixture parameters, like friction. Otherwise you can create the /// fixture directly from a shape. /// If the density is non-zero, this function automatically updates the mass of the body. /// Contacts are not created until the next time step. /// @param def the fixture definition. /// @warning This function is locked during callbacks. public Fixture CreateFixture(FixtureDef def) { Debug.Assert(_world.IsLocked == false); if (_world.IsLocked == true) { return(null); } Fixture fixture = new Fixture(); fixture.Create(this, def); if ((_flags & BodyFlags.Active) == BodyFlags.Active) { BroadPhase broadPhase = _world._contactManager._broadPhase; fixture.CreateProxies(broadPhase, ref _xf); } fixture._next = _fixtureList; _fixtureList = fixture; ++_fixtureCount; fixture._body = this; // Adjust mass properties if needed. if (fixture._density > 0.0f) { ResetMassData(); } // Let the world know we have a new fixture. This will cause new contacts // to be created at the beginning of the next time step. _world._flags |= WorldFlags.NewFixture; return(fixture); }
/// Destroy a fixture. This removes the fixture from the broad-phase and /// destroys all contacts associated with this fixture. This will /// automatically adjust the mass of the body if the body is dynamic and the /// fixture has positive density. /// All fixtures attached to a body are implicitly destroyed when the body is destroyed. /// @param fixture the fixture to be removed. /// @warning This function is locked during callbacks. public void DestroyFixture(Fixture fixture) { Debug.Assert(_world.IsLocked == false); if (_world.IsLocked == true) { return; } Debug.Assert(fixture._body == this); // Remove the fixture from this body's singly linked list. Debug.Assert(_fixtureCount > 0); Fixture node = _fixtureList; bool found = false; while (node != null) { if (node == fixture) { _fixtureList = fixture._next; found = true; break; } node = node._next; } // You tried to remove a shape that is not attached to this body. Debug.Assert(found); // Destroy any contacts associated with the fixture. ContactEdge edge = _contactList; while (edge != null) { Contact c = edge.Contact; edge = edge.Next; Fixture fixtureA = c.GetFixtureA(); Fixture fixtureB = c.GetFixtureB(); if (fixture == fixtureA || fixture == fixtureB) { // This destroys the contact and removes it from // this body's contact list. _world._contactManager.Destroy(c); } } if ((_flags & BodyFlags.Active) == BodyFlags.Active) { Debug.Assert(fixture._proxyId != BroadPhase.NullProxy); BroadPhase broadPhase = _world._contactManager._broadPhase; fixture.DestroyProxies(broadPhase); } fixture.Destroy(); fixture._body = null; fixture._next = null; --_fixtureCount; ResetMassData(); }
/// 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()) { AABB aabb; bp.GetFatAABB(f._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); } } }