/// Set the active state of the body. An inactive body is not /// simulated and cannot be collided with or woken up. /// If you pass a flag of true, all fixtures will be added to the /// broad-phase. /// If you pass a flag of false, all fixtures will be removed from /// the broad-phase and all contacts will be destroyed. /// Fixtures and joints are otherwise unaffected. you may continue /// to create/destroy fixtures and joints on inactive bodies. /// Fixtures on an inactive body are implicitly inactive and will /// not participate in collisions, ray-casts, or queries. /// Joints connected to an inactive body are implicitly inactive. /// An inactive body is still owned by a b2World object and remains /// in the body list. public void SetActive(bool flag) { if (flag == IsActive()) { return; } if (flag) { _flags |= BodyFlags.Active; // Create all proxies. BroadPhase broadPhase = _world._contactManager._broadPhase; for (Fixture f = _fixtureList; f != null; f = f._next) { f.CreateProxies(broadPhase, ref _xf); } // Contacts are created the next time step. } else { _flags &= ~BodyFlags.Active; // Destroy all proxies. BroadPhase broadPhase = _world._contactManager._broadPhase; for (Fixture f = _fixtureList; f != null; f = f._next) { f.DestroyProxies(broadPhase); } // Destroy the attached contacts. ContactEdge ce = _contactList; while (ce != null) { ContactEdge ce0 = ce; ce = ce.Next; _world._contactManager.Destroy(ce0.Contact); } _contactList = null; } }
/// 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(); }
/// Destroy a rigid body given a definition. No reference to the definition /// is retained. This function is locked during callbacks. /// @warning This automatically deletes all associated shapes and joints. /// @warning This function is locked during callbacks. public void DestroyBody(Body b) { //Debug.Assert(_bodyCount > 0); //Debug.Assert(!IsLocked); if (IsLocked) { return; } // Delete the attached joints. JointEdge je = b._jointList; while (je != null) { JointEdge je0 = je; je = je.Next; if (DestructionListener != null) { DestructionListener.SayGoodbye(je0.Joint); } DestroyJoint(je0.Joint); } b._jointList = null; // Delete the attached contacts. ContactEdge ce = b._contactList; while (ce != null) { ContactEdge ce0 = ce; ce = ce.Next; _contactManager.Destroy(ce0.Contact); } b._contactList = null; // Delete the attached fixtures. This destroys broad-phase proxies. Fixture f = b._fixtureList; while (f != null) { Fixture f0 = f; f = f._next; if (DestructionListener != null) { DestructionListener.SayGoodbye(f0); } f0.DestroyProxies(_contactManager._broadPhase); f0.Destroy(); } b._fixtureList = null; b._fixtureCount = 0; // Remove world body list. if (b._prev != null) { b._prev._next = b._next; } if (b._next != null) { b._next._prev = b._prev; } if (b == _bodyList) { _bodyList = b._next; } --_bodyCount; }