Example #1
0
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;
}
Example #2
0
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);
	}
}
Example #3
0
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;
}
Example #4
0
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();
}
Example #5
0
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();
	}
}