b2Fixture* b2Body::CreateFixture(const b2FixtureDef* def) { b2Assert(m_world->IsLocked() == false); if (m_world->IsLocked() == true) { return NULL; } b2BlockAllocator* allocator = &m_world->m_blockAllocator; b2BroadPhase* broadPhase = &m_world->m_contactManager.m_broadPhase; void* mem = allocator->Allocate(sizeof(b2Fixture)); b2Fixture* fixture = new (mem) b2Fixture; fixture->Create(allocator, broadPhase, this, m_xf, def); fixture->m_next = m_fixtureList; m_fixtureList = fixture; ++m_fixtureCount; fixture->m_body = this; bool needMassUpdate = fixture->m_massData.mass > 0.0f || fixture->m_massData.I > 0.0f; // Adjust mass properties if needed. if (needMassUpdate) { ResetMass(); } // 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. m_world->m_flags |= b2World::e_newFixture; return fixture; }
void b3Body::SetType(b3BodyType type) { if (m_type == type) { return; } m_type = type; ResetMass(); m_force.SetZero(); m_torque.SetZero(); if (m_type == e_staticBody) { m_linearVelocity.SetZero(); m_angularVelocity.SetZero(); m_sweep.worldCenter0 = m_sweep.worldCenter; m_sweep.orientation0 = m_sweep.orientation; SynchronizeShapes(); } SetAwake(true); DestroyContacts(); // Move the shape proxies so new contacts can be created. b3BroadPhase* phase = &m_world->m_contactMan.m_broadPhase; for (b3Shape* s = m_shapeList.m_head; s; s = s->m_next) { phase->BufferMove(s->m_broadPhaseID); } }
b3Shape* b3Body::CreateShape(const b3ShapeDef& def) { // Create the shape with the definition. b3Shape* shape = b3Shape::Create(def); shape->m_body = this; shape->m_isSensor = def.isSensor; shape->m_userData = def.userData; shape->m_density = def.density; shape->m_friction = def.friction; shape->m_restitution = def.restitution; // Add the shape to this body shape list. m_shapeList.PushFront(shape); // Since a new shape was added the new mass properties of // this body need to be recomputed. if (shape->m_density > 0.0f) { ResetMass(); } // Compute the world AABB of the new shape and assign a broad-phase proxy to it. b3Transform xf = m_xf; b3AABB3 aabb; shape->ComputeAABB(&aabb, xf); shape->m_broadPhaseID = m_world->m_contactMan.m_broadPhase.CreateProxy(aabb, shape); // Tell the world that a new shape was added so new contacts can be created. m_world->m_flags |= b3World::e_shapeAddedFlag; return shape; }
void b3Body::DestroyShape(b3Shape* shape) { // Remove the shape from this body shape list. B3_ASSERT(shape->m_body == this); m_shapeList.Remove(shape); // Destroy any contacts associated with the shape. shape->DestroyContacts(); // Destroy the broad-phase proxy associated with the shape. m_world->m_contactMan.m_broadPhase.DestroyProxy(shape->m_broadPhaseID); // Destroy the shape. b3Shape::Destroy(shape); // Recalculate the new inertial properties of this body. ResetMass(); }
void b2Body::DestroyFixture(b2Fixture* fixture) { b2Assert(m_world->IsLocked() == false); if (m_world->IsLocked() == true) { return; } b2Assert(fixture->m_body == this); // Remove the fixture from this body's singly linked list. b2Assert(m_fixtureCount > 0); b2Fixture** node = &m_fixtureList; bool found = false; while (*node != NULL) { if (*node == fixture) { *node = fixture->m_next; found = true; break; } node = &(*node)->m_next; } // You tried to remove a shape that is not attached to this body. b2Assert(found); // Destroy any contacts associated with the fixture. b2ContactEdge* edge = m_contactList; while (edge) { b2Contact* c = edge->contact; edge = edge->next; b2Fixture* fixtureA = c->GetFixtureA(); b2Fixture* fixtureB = c->GetFixtureB(); if (fixture == fixtureA || fixture == fixtureB) { // This destroys the contact and removes it from // this body's contact list. m_world->m_contactManager.Destroy(c); } } bool needMassUpdate = fixture->m_massData.mass > 0.0f || fixture->m_massData.I > 0.0f; b2BlockAllocator* allocator = &m_world->m_blockAllocator; b2BroadPhase* broadPhase = &m_world->m_contactManager.m_broadPhase; fixture->Destroy(allocator, broadPhase); fixture->m_body = NULL; fixture->m_next = NULL; fixture->~b2Fixture(); allocator->Free(fixture, sizeof(b2Fixture)); --m_fixtureCount; // Adjust mass properties if needed. if (needMassUpdate) { ResetMass(); } }