box2d collision groups

被刻印的时光 ゝ 提交于 2019-12-18 20:04:14

问题


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) ?


回答1:


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/




回答2:


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:


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




回答4:


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)




回答5:


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));


来源:https://stackoverflow.com/questions/936935/box2d-collision-groups

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!