in Box2D/Dynamics/b2Body.cpp [281:351]
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);
}