void Body::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 = glm::vec2(0.0f,0.0f); // Static and kinematic bodies have zero mass. if (m_type == staticBody || m_type == kinematicBody) { m_sweep.c0 = m_xf.p; m_sweep.c = m_xf.p; m_sweep.a0 = m_sweep.a; return; } assert(m_type == dynamicBody); // Accumulate mass over all fixtures. glm::vec2 localCenter = glm::vec2(0.0f,0.0f); for (Fixture* f = m_fixtureList; f; f = f->m_next) { if (f->m_density == 0.0f) { continue; } MassData 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 & fixedRotationFlag) == 0) { // Center the inertia about the center of mass. m_I -= m_mass * glm::dot(localCenter, localCenter); assert(m_I > 0.0f); m_invI = 1.0f / m_I; } else { m_I = 0.0f; m_invI = 0.0f; } // Move center of mass. glm::vec2 oldCenter = m_sweep.c; m_sweep.localCenter = localCenter; m_sweep.c0 = m_sweep.c = Physics::Transform2D::Mul(m_xf, m_sweep.localCenter); // Update center of mass velocity. m_linearVelocity += MathUtils::Cross2(m_angularVelocity, m_sweep.c - oldCenter); }