Monday, February 8, 2010

Transitioning to Box2D 2.1: b2Fixtures

My game development team got a bit of a shot a few weeks ago when found that our ActionScript 3.0 physics engine, Box2D had released the Alpha version for their 2.1 update called 2.1a. Strangely, the C++ version of Box2D has yet to release this update.

I actually stumbled into downloading the new version while looking for a way to create multi-shape bodies. I figured the examples that come with the Box2D source would show me how. Boy was I in for a surprise: what were all these b2Fixtures doing in the code?


One of the many changes in Box2D 2.1a are the new b2Fixtures. Fixtures replace b2ShapDef's from 2.0.

The b2Fixtures must be used to associate b2Shape's with b2Body's. In addition they now hold values such as friction, restitution, density, isSensor, etc.


var bodyDef:b2BodyDef = new b2BodyDef();
bodyDef.type = b2Body.b2_dynamicBody;
bodyDef.position.Set(10 / m_physScale, 10 / m_physScale);

var shapeDef:b2PolygonShape = new b2PolygonShape();
shapeDef.SetAsBox(20 / m_physScale, 20 / m_physScale);

var fixtureDef:b2FixtureDef = new b2FixtureDef();
fixtureDef.shape = shapeDef;
body = m_world.CreateBody(bodyDef);
body.CreateFixture(fixtureDef);


Note that all the size and position variables are divided by m_physScale. This scales everything down by 30. We found out the hard way that Box2D works on very small scales. If your physical bodies are too big, then the forces needed to affect them will be ridiculously large.

In this code, b2BodyDef is used to set the Body's position in the world, and define that it is a dynamic body. Notice that b2Body enumerates the Body types. b2PolygonShape defines the square polygon for this Fixture. b2Fixture then takes the Shape. The world creates the Body and then the Body creates the Fixture.

In order to create compound Bodies with multiple shapes, we need to use b2PolygonShape.SetAsOrientedBox().

For b2CircleShape's we have to use b2CircleShape.SetLocalPosition().

Here's some code for creating a Body with both a square and a circle.


var bodyDef:b2BodyDef = new b2BodyDef();
bodyDef.type = b2Body.b2_dynamicBody;
bodyDef.position.Set(10 / m_physScale, 10 / m_physScale);

var shapeDef:b2PolygonShape = new b2PolygonShape();
shapeDef.SetAsOrientedBox(20/m_physScale, 20/m_physScale, new b2Vec2(0.0, -15.0/m_physScale), 0.5 * Math.PI);

var circleDef:b2CircleShape = new b2CircleShape();
circleDef.SetRadius(10/m_physScale);
circleDef.SetLocalPosition(new b2Vec2(20 / m_physScale, 20 / m_physScale));

var fixtureDef:b2FixtureDef = new b2FixtureDef();
fixtureDef.shape = shapeDef;
var fixtureDef2:b2FixtureDef = new b2FixtureDef();
fixtureDef2.shape = circleDef;
body = m_world.CreateBody(bodyDef);
body.CreateFixture(fixtureDef);
body.CreateFixture(fixtureDef2);


Stay tuned for other changes that 2.1a has introduced.

2 comments:

JiMKE said...

Thanx a lot!
It was so helpful for me!

Sean said...

Hey man, nice post.

Out of curiosity, you wouldn't happen to know how you can create a custom polygon shape (i.e. not a rect or circle) to apply to the fixture, do you?

I'm new to box2d, but the 2.0 seemed to make more sense in this regard, since you could set the number and placement of vertices. Can you still do that in 2.1?