box2d collision groups

2019-02-12 12:51发布

does anyone know whether bodies only collide when (body1.categoryBits & body2.maskBits) && (body1.maskBits & body2.categoryBits) ? or do they already collide when (body1.categoryBits & body2.maskBits) || (body1.maskBits & body2.categoryBits) ?

5条回答
贪生不怕死
2楼-- · 2019-02-12 13:39

From the Box2D manual:

6.2.3. Filtering

Collision filtering is a system for preventing collision between shapes. For example, say you make a character that rides a bicycle. You want the bicycle to collide with the terrain and the character to collide with the terrain, but you don't want the character to collide with the bicycle (because they must overlap). Box2D supports such collision filtering using categories and groups.

Box2D supports 16 collision categories. For each shape you can specify which category it belongs to. You also specify what other categories this shape can collide with. For example, you could specify in a multiplayer game that all players don't collide with each other and monsters don't collide with each other, but players and monsters should collide. This is done with masking bits. For example:

playerShapeDef.filter.categoryBits = 0x0002;
monsterShapeDef.filter.categoryBits = 0x0004;
playerShape.filter.maskBits = 0x0004;
monsterShapeDef.filter.maskBits = 0x0002;

Collision groups let you specify an integral group index. You can have all shapes with the same group index always collide (positive index) or never collide (negative index). Group indices are usually used for things that are somehow related, like the parts of a bicycle. In the following example, shape1 and shape2 always collide, but shape3 and shape4 never collide.

shape1Def.filter.groupIndex = 2;
shape2Def.filter.groupIndex = 2;
shape3Def.filter.groupIndex = -8;
shape4Def.filter.groupIndex = -8;

Collisions between shapes of different group indices are filtered according the category and mask bits. In other words, group filtering has higher precendence than category filtering.

查看更多
再贱就再见
3楼-- · 2019-02-12 13:40

I have used walls and many players (our Player and enemies). My player and enemies collides with walls but don't collide with each other. I have done like this and it worked. You have to set the groupIndex to negative value for the objects not to collide with each other. Define the fixtures like this.

    /* The categories. */
public static final short CATEGORYBIT_WALL = 1;
public static final short CATEGORYBIT_PLAYERS = 2;

/* And what should collide with what. */
public static final short MASKBITS_WALL = CATEGORYBIT_WALL + CATEGORYBIT_PLAYERS;

public static final FixtureDef WALL_FIXTURE_DEF = PhysicsFactory.createFixtureDef(0, 0.5f, 0.5f, false, CATEGORYBIT_WALL, MASKBITS_WALL, (short)0);
public static final FixtureDef PLAYERS_FIXTURE_DEF = PhysicsFactory.createFixtureDef(1, 0.5f, 0.5f, false, CATEGORYBIT_PLAYERS, MASKBITS_WALL, (short)-1);

and apply to your bodies.

AnimatedSprite player, enemy;
Body playerBody, enemyBody;

player= new AnimatedSprite(CAMERA_WIDTH/2, CAMERA_HEIGHT/2,     this.playerRegion, this.getVertexBufferObjectManager());
playerBody = PhysicsFactory.createBoxBody(this.mPhysicsWorld, player,     BodyType.DynamicBody, PLAYERS_FIXTURE_DEF);   
this.mPhysicsWorld.registerPhysicsConnector(new PhysicsConnector(player, playerBody, true, false));

enemy= new AnimatedSprite(CAMERA_WIDTH/4, CAMERA_HEIGHT/2, this.enemyRegion, this.getVertexBufferObjectManager());

enemyBody= PhysicsFactory.createCircleBody(this.mPhysicsWorld, enemy, BodyType.DynamicBody, PLAYERS_FIXTURE_DEF);
this.mPhysicsWorld.registerPhysicsConnector(new PhysicsConnector(enemy, enemyBody, true, false));
查看更多
老娘就宠你
4楼-- · 2019-02-12 13:44

Looking at the source of Box2d, it shows that if the fixtures belong to different groups (or the groups are 0) then the catgory and masks are compared as follows:

    bool collide = (filterA.maskBits & filterB.categoryBits) != 0 && 
                   (filterA.categoryBits & filterB.maskBits) != 0;

So it looks like fixture only collide if the collision is allowed by both fixtures' masks. (IE: AND logic)

查看更多
Deceive 欺骗
5楼-- · 2019-02-12 13:46

If anyone is still looking for more explanations, I made a detailed tutorial here :
http://aurelienribon.wordpress.com/2011/07/01/box2d-tutorial-collision-filtering/

查看更多
够拽才男人
6楼-- · 2019-02-12 13:56

This is the way I've understood how maskBits and categoryBits work. Let's say you have 3 objects : objectA, objectB and objectC.

Define for each object a category :

objectA.categoryBits = 0x0002;
objectB.categoryBits = 0x0004;
objectC.categoryBits = 0x0008;

Then, set the maskBits, which define the collisions rules for each categoryBits :

-> objectA collide with everyone (0xFFFF) and (&) not(~) objectB (0x0004)
objectA.maskBits = 0xFFFF & ~0x0004;

-> objectB collide with objectA (0x0002) or (|) objectC (0x0008) but no one else
objectB.maskBits = 0x0002 | 0x0008;

-> objectC collide with objectA (0x0002) but no one else
objectC.maskBits = 0x0002;

I don't know if this is correct, but it worked for me.

HTH

查看更多
登录 后发表回答