/** * Creates a fixture and attach it to this body. Use this function if you need to set some fixture * parameters, like friction. Otherwise you can create the fixture directly from a shape. If the * density is non-zero, this function automatically updates the mass of the body. Contacts are not * created until the next time step. * * @param def the fixture definition. * @warning This function is locked during callbacks. */ public final Fixture createFixture(FixtureDef def) { assert (m_world.isLocked() == false); if (m_world.isLocked() == true) { return null; } // djm TODO from pool? Fixture fixture = new Fixture(); fixture.create(this, def); if ((m_flags & e_activeFlag) == e_activeFlag) { BroadPhase broadPhase = m_world.m_contactManager.m_broadPhase; fixture.createProxy(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 |= World.NEW_FIXTURE; return fixture; }
/** * Set the mass properties to override the mass properties of the fixtures. Note that this changes * the center of mass position. Note that creating or destroying fixtures can also alter the mass. * This function has no effect if the body isn't dynamic. * * @param massData the mass properties. */ public final void setMassData(MassData massData) { // TODO_ERIN adjust linear velocity and torque to account for movement of center. assert (m_world.isLocked() == false); if (m_world.isLocked() == true) { return; } if (m_type != BodyType.DYNAMIC) { return; } m_invMass = 0.0f; m_I = 0.0f; m_invI = 0.0f; m_mass = massData.mass; if (m_mass <= 0.0f) { m_mass = 1f; } m_invMass = 1.0f / m_mass; if (massData.I > 0.0f && (m_flags & e_fixedRotationFlag) == 0) { m_I = massData.I - m_mass * Vec2.dot(massData.center, massData.center); assert (m_I > 0.0f); m_invI = 1.0f / m_I; } final Vec2 oldCenter = m_world.getPool().popVec2(); // Move center of mass. oldCenter.set(m_sweep.c); m_sweep.localCenter.set(massData.center); // m_sweep.c0 = m_sweep.c = Mul(m_xf, m_sweep.localCenter); Transform.mulToOut(m_xf, m_sweep.localCenter, m_sweep.c0); m_sweep.c.set(m_sweep.c0); // Update center of mass velocity. // m_linearVelocity += Cross(m_angularVelocity, m_sweep.c - oldCenter); final Vec2 temp = m_world.getPool().popVec2(); temp.set(m_sweep.c).subLocal(oldCenter); Vec2.crossToOut(m_angularVelocity, temp, temp); m_linearVelocity.addLocal(temp); m_world.getPool().pushVec2(2); }
/** * Set the position of the body's origin and rotation. This breaks any contacts and wakes the * other bodies. Manipulating a body's transform may cause non-physical behavior. * * @param position the world position of the body's local origin. * @param angle the world rotation in radians. */ public final void setTransform(Vec2 position, float angle) { assert (m_world.isLocked() == false); if (m_world.isLocked() == true) { return; } m_xf.R.set(angle); m_xf.position.set(position); // m_sweep.c0 = m_sweep.c = Mul(m_xf, m_sweep.localCenter); Transform.mulToOut(m_xf, m_sweep.localCenter, m_sweep.c0); m_sweep.c.set(m_sweep.c0); m_sweep.a0 = m_sweep.a = angle; BroadPhase broadPhase = m_world.m_contactManager.m_broadPhase; for (Fixture f = m_fixtureList; f != null; f = f.m_next) { f.synchronize(broadPhase, m_xf, m_xf); } m_world.m_contactManager.findNewContacts(); }
/** * Destroy a fixture. This removes the fixture from the broad-phase and destroys all contacts * associated with this fixture. This will automatically adjust the mass of the body if the body * is dynamic and the fixture has positive density. All fixtures attached to a body are implicitly * destroyed when the body is destroyed. * * @param fixture the fixture to be removed. * @warning This function is locked during callbacks. */ public final void destroyFixture(Fixture fixture) { assert (m_world.isLocked() == false); if (m_world.isLocked() == true) { return; } assert (fixture.m_body == this); // Remove the fixture from this body's singly linked list. assert (m_fixtureCount > 0); Fixture node = m_fixtureList; Fixture last = null; // java change boolean found = false; while (node != null) { if (node == fixture) { node = fixture.m_next; found = true; break; } last = node; node = node.m_next; } // You tried to remove a shape that is not attached to this body. assert (found); // java change, remove it from the list if (last == null) { m_fixtureList = fixture.m_next; } else { last.m_next = fixture.m_next; } // Destroy any contacts associated with the fixture. ContactEdge edge = m_contactList; while (edge != null) { Contact c = edge.contact; edge = edge.next; Fixture fixtureA = c.getFixtureA(); Fixture 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); } } if ((m_flags & e_activeFlag) == e_activeFlag) { assert (fixture.m_proxy != null); BroadPhase broadPhase = m_world.m_contactManager.m_broadPhase; fixture.destroyProxy(broadPhase); } else { assert (fixture.m_proxy == null); } fixture.destroy(); fixture.m_body = null; fixture.m_next = null; fixture = null; --m_fixtureCount; // Reset the mass data. resetMassData(); }