| 
							- /*
 - * Copyright (c) 2006-2007 Erin Catto http://www.box2d.org
 - *
 - * This software is provided 'as-is', without any express or implied
 - * warranty.  In no event will the authors be held liable for any damages
 - * arising from the use of this software.
 - * Permission is granted to anyone to use this software for any purpose,
 - * including commercial applications, and to alter it and redistribute it
 - * freely, subject to the following restrictions:
 - * 1. The origin of this software must not be misrepresented; you must not
 - * claim that you wrote the original software. If you use this software
 - * in a product, an acknowledgment in the product documentation would be
 - * appreciated but is not required.
 - * 2. Altered source versions must be plainly marked as such, and must not be
 - * misrepresented as being the original software.
 - * 3. This notice may not be removed or altered from any source distribution.
 - */
 - 
 - #include "b2Body.h"
 - #include "b2Fixture.h"
 - #include "b2World.h"
 - #include "Contacts/b2Contact.h"
 - #include "Joints/b2Joint.h"
 - 
 - b2Body::b2Body(const b2BodyDef* bd, b2World* world)
 - {
 - 	b2Assert(bd->position.IsValid());
 - 	b2Assert(bd->linearVelocity.IsValid());
 - 	b2Assert(b2IsValid(bd->angle));
 - 	b2Assert(b2IsValid(bd->angularVelocity));
 - 	b2Assert(b2IsValid(bd->angularDamping) && bd->angularDamping >= 0.0f);
 - 	b2Assert(b2IsValid(bd->linearDamping) && bd->linearDamping >= 0.0f);
 - 
 - 	m_flags = 0;
 - 
 - 	if (bd->bullet)
 - 	{
 - 		m_flags |= e_bulletFlag;
 - 	}
 - 	if (bd->fixedRotation)
 - 	{
 - 		m_flags |= e_fixedRotationFlag;
 - 	}
 - 	if (bd->allowSleep)
 - 	{
 - 		m_flags |= e_autoSleepFlag;
 - 	}
 - 	if (bd->awake)
 - 	{
 - 		m_flags |= e_awakeFlag;
 - 	}
 - 	if (bd->active)
 - 	{
 - 		m_flags |= e_activeFlag;
 - 	}
 - 
 - 	m_world = world;
 - 
 - 	m_xf.p = bd->position;
 - 	m_xf.q.Set(bd->angle);
 - 
 - 	m_sweep.localCenter.SetZero();
 - 	m_sweep.c0 = m_xf.p;
 - 	m_sweep.c = m_xf.p;
 - 	m_sweep.a0 = bd->angle;
 - 	m_sweep.a = bd->angle;
 - 	m_sweep.alpha0 = 0.0f;
 - 
 - 	m_jointList = NULL;
 - 	m_contactList = NULL;
 - 	m_prev = NULL;
 - 	m_next = NULL;
 - 
 - 	m_linearVelocity = bd->linearVelocity;
 - 	m_angularVelocity = bd->angularVelocity;
 - 
 - 	m_linearDamping = bd->linearDamping;
 - 	m_angularDamping = bd->angularDamping;
 - 	m_gravityScale = bd->gravityScale;
 - 
 - 	m_force.SetZero();
 - 	m_torque = 0.0f;
 - 
 - 	m_sleepTime = 0.0f;
 - 
 - 	m_type = bd->type;
 - 
 - 	if (m_type == b2_dynamicBody)
 - 	{
 - 		m_mass = 1.0f;
 - 		m_invMass = 1.0f;
 - 	}
 - 	else
 - 	{
 - 		m_mass = 0.0f;
 - 		m_invMass = 0.0f;
 - 	}
 - 
 - 	m_I = 0.0f;
 - 	m_invI = 0.0f;
 - 
 - 	m_userData = bd->userData;
 - 
 - 	m_fixtureList = NULL;
 - 	m_fixtureCount = 0;
 - }
 - 
 - b2Body::~b2Body()
 - {
 - 	// shapes and joints are destroyed in b2World::Destroy
 - }
 - 
 - void b2Body::SetType(b2BodyType type)
 - {
 - 	b2Assert(m_world->IsLocked() == false);
 - 	if (m_world->IsLocked() == true)
 - 	{
 - 		return;
 - 	}
 - 
 - 	if (m_type == type)
 - 	{
 - 		return;
 - 	}
 - 
 - 	m_type = type;
 - 
 - 	ResetMassData();
 - 
 - 	if (m_type == b2_staticBody)
 - 	{
 - 		m_linearVelocity.SetZero();
 - 		m_angularVelocity = 0.0f;
 - 		m_sweep.a0 = m_sweep.a;
 - 		m_sweep.c0 = m_sweep.c;
 - 		SynchronizeFixtures();
 - 	}
 - 
 - 	SetAwake(true);
 - 
 - 	m_force.SetZero();
 - 	m_torque = 0.0f;
 - 
 - 	// Since the body type changed, we need to flag contacts for filtering.
 - 	for (b2Fixture* f = m_fixtureList; f; f = f->m_next)
 - 	{
 - 		f->Refilter();
 - 	}
 - }
 - 
 - b2Fixture* b2Body::CreateFixture(const b2FixtureDef* def)
 - {
 - 	b2Assert(m_world->IsLocked() == false);
 - 	if (m_world->IsLocked() == true)
 - 	{
 - 		return NULL;
 - 	}
 - 
 - 	b2BlockAllocator* allocator = &m_world->m_blockAllocator;
 - 
 - 	void* memory = allocator->Allocate(sizeof(b2Fixture));
 - 	b2Fixture* fixture = new (memory) b2Fixture;
 - 	fixture->Create(allocator, this, def);
 - 
 - 	if (m_flags & e_activeFlag)
 - 	{
 - 		b2BroadPhase* broadPhase = &m_world->m_contactManager.m_broadPhase;
 - 		fixture->CreateProxies(broadPhase, m_xf);
 - 	}
 - 
 - 	fixture->m_next = m_fixtureList;
 - 	m_fixtureList = fixture;
 - 	++m_fixtureCount;
 - 
 - 	fixture->m_body = this;
 - 
 - 	// Adjust mass properties if needed.
 - 	if (fixture->m_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.
 - 	m_world->m_flags |= b2World::e_newFixture;
 - 
 - 	return fixture;
 - }
 - 
 - b2Fixture* b2Body::CreateFixture(const b2Shape* shape, float32 density)
 - {
 - 	b2FixtureDef def;
 - 	def.shape = shape;
 - 	def.density = density;
 - 
 - 	return CreateFixture(&def);
 - }
 - 
 - 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);
 -     juce::ignoreUnused (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);
 - 		}
 - 	}
 - 
 - 	b2BlockAllocator* allocator = &m_world->m_blockAllocator;
 - 
 - 	if (m_flags & e_activeFlag)
 - 	{
 - 		b2BroadPhase* broadPhase = &m_world->m_contactManager.m_broadPhase;
 - 		fixture->DestroyProxies(broadPhase);
 - 	}
 - 
 - 	fixture->Destroy(allocator);
 - 	fixture->m_body = NULL;
 - 	fixture->m_next = NULL;
 - 	fixture->~b2Fixture();
 - 	allocator->Free(fixture, sizeof(b2Fixture));
 - 
 - 	--m_fixtureCount;
 - 
 - 	// Reset the mass data.
 - 	ResetMassData();
 - }
 - 
 - void b2Body::ResetMassData()
 - {
 - 	// Compute mass data from shapes. Each shape has its own density.
 - 	m_mass = 0.0f;
 - 	m_invMass = 0.0f;
 - 	m_I = 0.0f;
 - 	m_invI = 0.0f;
 - 	m_sweep.localCenter.SetZero();
 - 
 - 	// Static and kinematic bodies have zero mass.
 - 	if (m_type == b2_staticBody || m_type == b2_kinematicBody)
 - 	{
 - 		m_sweep.c0 = m_xf.p;
 - 		m_sweep.c = m_xf.p;
 - 		m_sweep.a0 = m_sweep.a;
 - 		return;
 - 	}
 - 
 - 	b2Assert(m_type == b2_dynamicBody);
 - 
 - 	// Accumulate mass over all fixtures.
 - 	b2Vec2 localCenter = b2Vec2_zero;
 - 	for (b2Fixture* f = m_fixtureList; f; f = f->m_next)
 - 	{
 - 		if (f->m_density == 0.0f)
 - 		{
 - 			continue;
 - 		}
 - 
 - 		b2MassData massData;
 - 		f->GetMassData(&massData);
 - 		m_mass += massData.mass;
 - 		localCenter += massData.mass * massData.center;
 - 		m_I += massData.I;
 - 	}
 - 
 - 	// Compute center of mass.
 - 	if (m_mass > 0.0f)
 - 	{
 - 		m_invMass = 1.0f / m_mass;
 - 		localCenter *= m_invMass;
 - 	}
 - 	else
 - 	{
 - 		// Force all dynamic bodies to have a positive mass.
 - 		m_mass = 1.0f;
 - 		m_invMass = 1.0f;
 - 	}
 - 
 - 	if (m_I > 0.0f && (m_flags & e_fixedRotationFlag) == 0)
 - 	{
 - 		// Center the inertia about the center of mass.
 - 		m_I -= m_mass * b2Dot(localCenter, localCenter);
 - 		b2Assert(m_I > 0.0f);
 - 		m_invI = 1.0f / m_I;
 - 
 - 	}
 - 	else
 - 	{
 - 		m_I = 0.0f;
 - 		m_invI = 0.0f;
 - 	}
 - 
 - 	// Move center of mass.
 - 	b2Vec2 oldCenter = m_sweep.c;
 - 	m_sweep.localCenter = localCenter;
 - 	m_sweep.c0 = m_sweep.c = b2Mul(m_xf, m_sweep.localCenter);
 - 
 - 	// Update center of mass velocity.
 - 	m_linearVelocity += b2Cross(m_angularVelocity, m_sweep.c - oldCenter);
 - }
 - 
 - void b2Body::SetMassData(const b2MassData* massData)
 - {
 - 	b2Assert(m_world->IsLocked() == false);
 - 	if (m_world->IsLocked() == true)
 - 	{
 - 		return;
 - 	}
 - 
 - 	if (m_type != b2_dynamicBody)
 - 	{
 - 		return;
 - 	}
 - 
 - 	m_invMass = 0.0f;
 - 	m_I = 0.0f;
 - 	m_invI = 0.0f;
 - 
 - 	m_mass = massData->mass;
 - 	if (m_mass <= 0.0f)
 - 	{
 - 		m_mass = 1.0f;
 - 	}
 - 
 - 	m_invMass = 1.0f / m_mass;
 - 
 - 	if (massData->I > 0.0f && (m_flags & b2Body::e_fixedRotationFlag) == 0)
 - 	{
 - 		m_I = massData->I - m_mass * b2Dot(massData->center, massData->center);
 - 		b2Assert(m_I > 0.0f);
 - 		m_invI = 1.0f / m_I;
 - 	}
 - 
 - 	// Move center of mass.
 - 	b2Vec2 oldCenter = m_sweep.c;
 - 	m_sweep.localCenter =  massData->center;
 - 	m_sweep.c0 = m_sweep.c = b2Mul(m_xf, m_sweep.localCenter);
 - 
 - 	// Update center of mass velocity.
 - 	m_linearVelocity += b2Cross(m_angularVelocity, m_sweep.c - oldCenter);
 - }
 - 
 - bool b2Body::ShouldCollide(const b2Body* other) const
 - {
 - 	// At least one body should be dynamic.
 - 	if (m_type != b2_dynamicBody && other->m_type != b2_dynamicBody)
 - 	{
 - 		return false;
 - 	}
 - 
 - 	// Does a joint prevent collision?
 - 	for (b2JointEdge* jn = m_jointList; jn; jn = jn->next)
 - 	{
 - 		if (jn->other == other)
 - 		{
 - 			if (jn->joint->m_collideConnected == false)
 - 			{
 - 				return false;
 - 			}
 - 		}
 - 	}
 - 
 - 	return true;
 - }
 - 
 - void b2Body::SetTransform(const b2Vec2& position, float32 angle)
 - {
 - 	b2Assert(m_world->IsLocked() == false);
 - 	if (m_world->IsLocked() == true)
 - 	{
 - 		return;
 - 	}
 - 
 - 	m_xf.q.Set(angle);
 - 	m_xf.p = position;
 - 
 - 	m_sweep.c = b2Mul(m_xf, m_sweep.localCenter);
 - 	m_sweep.a = angle;
 - 
 - 	m_sweep.c0 = m_sweep.c;
 - 	m_sweep.a0 = angle;
 - 
 - 	b2BroadPhase* broadPhase = &m_world->m_contactManager.m_broadPhase;
 - 	for (b2Fixture* f = m_fixtureList; f; f = f->m_next)
 - 	{
 - 		f->Synchronize(broadPhase, m_xf, m_xf);
 - 	}
 - 
 - 	m_world->m_contactManager.FindNewContacts();
 - }
 - 
 - void b2Body::SynchronizeFixtures()
 - {
 - 	b2Transform xf1;
 - 	xf1.q.Set(m_sweep.a0);
 - 	xf1.p = m_sweep.c0 - b2Mul(xf1.q, m_sweep.localCenter);
 - 
 - 	b2BroadPhase* broadPhase = &m_world->m_contactManager.m_broadPhase;
 - 	for (b2Fixture* f = m_fixtureList; f; f = f->m_next)
 - 	{
 - 		f->Synchronize(broadPhase, xf1, m_xf);
 - 	}
 - }
 - 
 - void b2Body::SetActive(bool flag)
 - {
 - 	b2Assert(m_world->IsLocked() == false);
 - 
 - 	if (flag == IsActive())
 - 	{
 - 		return;
 - 	}
 - 
 - 	if (flag)
 - 	{
 - 		m_flags |= e_activeFlag;
 - 
 - 		// Create all proxies.
 - 		b2BroadPhase* broadPhase = &m_world->m_contactManager.m_broadPhase;
 - 		for (b2Fixture* f = m_fixtureList; f; f = f->m_next)
 - 		{
 - 			f->CreateProxies(broadPhase, m_xf);
 - 		}
 - 
 - 		// Contacts are created the next time step.
 - 	}
 - 	else
 - 	{
 - 		m_flags &= ~e_activeFlag;
 - 
 - 		// Destroy all proxies.
 - 		b2BroadPhase* broadPhase = &m_world->m_contactManager.m_broadPhase;
 - 		for (b2Fixture* f = m_fixtureList; f; f = f->m_next)
 - 		{
 - 			f->DestroyProxies(broadPhase);
 - 		}
 - 
 - 		// Destroy the attached contacts.
 - 		b2ContactEdge* ce = m_contactList;
 - 		while (ce)
 - 		{
 - 			b2ContactEdge* ce0 = ce;
 - 			ce = ce->next;
 - 			m_world->m_contactManager.Destroy(ce0->contact);
 - 		}
 - 		m_contactList = NULL;
 - 	}
 - }
 - 
 - void b2Body::Dump()
 - {
 - 	int32 bodyIndex = m_islandIndex;
 - 
 - 	b2Log("{\n");
 - 	b2Log("  b2BodyDef bd;\n");
 - 	b2Log("  bd.type = b2BodyType(%d);\n", m_type);
 - 	b2Log("  bd.position.Set(%.15lef, %.15lef);\n", m_xf.p.x, m_xf.p.y);
 - 	b2Log("  bd.angle = %.15lef;\n", m_sweep.a);
 - 	b2Log("  bd.linearVelocity.Set(%.15lef, %.15lef);\n", m_linearVelocity.x, m_linearVelocity.y);
 - 	b2Log("  bd.angularVelocity = %.15lef;\n", m_angularVelocity);
 - 	b2Log("  bd.linearDamping = %.15lef;\n", m_linearDamping);
 - 	b2Log("  bd.angularDamping = %.15lef;\n", m_angularDamping);
 - 	b2Log("  bd.allowSleep = bool(%d);\n", m_flags & e_autoSleepFlag);
 - 	b2Log("  bd.awake = bool(%d);\n", m_flags & e_awakeFlag);
 - 	b2Log("  bd.fixedRotation = bool(%d);\n", m_flags & e_fixedRotationFlag);
 - 	b2Log("  bd.bullet = bool(%d);\n", m_flags & e_bulletFlag);
 - 	b2Log("  bd.active = bool(%d);\n", m_flags & e_activeFlag);
 - 	b2Log("  bd.gravityScale = %.15lef;\n", m_gravityScale);
 - 	b2Log("  bodies[%d] = m_world->CreateBody(&bd);\n", m_islandIndex);
 - 	b2Log("\n");
 - 	for (b2Fixture* f = m_fixtureList; f; f = f->m_next)
 - 	{
 - 		b2Log("  {\n");
 - 		f->Dump(bodyIndex);
 - 		b2Log("  }\n");
 - 	}
 - 	b2Log("}\n");
 - }
 
 
  |