Box2d - Changing contact filter on the fly
Im using cocos2d (iOS) and box2d to create a game.
I have come to the point where I need to change the contact filter mid simulation and wondering how to go about this. I need to use maskbits and categorybits, which is fine, im just unsure how to apply them to a b2body mid game.I'm thinking I may need to retrieve the original b2fixture or b2fixturedef of the b2body on initialization, alter the values accordingly then call a method to re开发者_StackOverflow社区fresh - world.Refilter()?
Does this sound somewhat accurate?
Any advice is surely appreciated
Oliver.b2Filter filter;
for ( b2Fixture* f = body->GetFixtureList(); f; f = f->GetNext() ) {
f->GetFilterData( &filter );
filter.categoryBits = ...;
filter.maskBits = ...;
filter.groupIndex = ...;
f->SetFilterData( &filter );
}
Obviously this would change the filter settings for all fixtures on a body - if you want to be more selective you will have to be able to tell which fixture is which somehow. Eg. if you know it's the only circle fixture you could just look at the type of the fixture to decide, otherwise you would have to make use of the fixture's user data I guess.
You can iterate over all bodies in the b2World. On each body you can iterate over it's fixture and change it's filter. To identify your bodies you can use userData.
The answer from iforce2d might be obsolete. I got the following code working properly with box2d v2.2.1, cocos2D v2.0.0 using Xcode v4.5.2 (here I assume I have a pointer to a b2Body named 'body' with only one fixture, i.e., I don't iterate over all fixtures on the body):
b2Fixture *fix = body->GetFixtureList();
b2Filter filter = fix->GetFilterData();
filter.groupIndex = -1*kPlayerGroupIndex;
fix->SetFilterData(filter);
In the above code I prevent 'body' from colliding with my player body which also has the same groupIndex value, i.e., -1*kPlayerGroupIndex, where kPlayerGroupIndex is a positive integer constant. Any bodies with this negative groupIndex never collide with one another. You could also update the categoryBits or maskBits accordingly to prevent collisions.
GetFilterData(&filter) and SetFilterData(&filter) returned errors for me given the version numbers I quoted above.
精彩评论