Box2D and the animated physics

This post is to give my solution to a problem I had during the development of my personal 2D game engine. The engine uses Box2D as a physics system that allow us in a very easy way to create bodies and update them without knowing only basic physics. The problem I faced was how to implement a system that allows to have a different physic body at every frame without the system becoming crazy.

The way I used to modify the body at every frame is to “create” and “destroy” the fixtures for every frame. The quotation marks are there because there is no memory allocation for every change, we will avoid it preloading the fixture definition of all the fixtures that we are going to activate and deactivate.

The functions Box2D functions we are going to use are the next ones:

/// 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.
b2Fixture* CreateFixture(const b2FixtureDef* def);

/// 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.
void DestroyFixture(b2Fixture* fixture);

So lets say we have a class that stores the fixtures for the different frames of an animation. The only thing we need is an array or vector that stores the fixture definitions and another array or vector that stores the fixtures created by the body. To create the fixtures we need also the body that is going to hold them and also we have to know if the fixtures are currently active or not, so we need something like this defined in the header:

b2Body* m_pBodyContainer;
b2Fixture* m_pFixtureArray[ME_FIXTURE_CONT_SIZE];
b2FixtureDef m_pFixtureDefinitionArray[ME_FIXTURE_CONT_SIZE];
int m_iNumOfFixtures;
bool m_bActive;

So, once m_pFixtureDefinitionArray is filled we can start “creating” and “destroying” the fixtures.

To create the fixtures we are going to call CreateFixture and store the fixture pointer at m_pFixtureArray:

void MEPhysicsFixtureContainer::Activate(void)
{
	if(m_bActive==false) {
		for(int i=0; i<m_iNumOfFixtures; ++i) {
			m_pFixtureArray[i]=m_pBodyContainer->CreateFixture(&m_pFixtureDefinitionArray[i]);
		}
		m_bActive=true;
	}
}

To destroy them we will use the function DestroyFixture and use the stored b2Fixture pointers as input parameter:

void MEPhysicsFixtureContainer::Deactivate(void)
{
	if(m_bActive==true) {
		for(int i=0; i<m_iNumOfFixtures; ++i) {
			m_pBodyContainer->DestroyFixture(m_pFixtureArray[i]);
		}
		m_bActive=false;
	}
}

Of course if we can avoid change the fixtures every frame we should avoid it, but this is a good way to change them with the preloaded definitions.

Feel free to use this code without any restriction and share this page if you think this may be useful for other developers.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.