группы столкновений box2d - PullRequest
10 голосов
/ 02 июня 2009

Кто-нибудь знает, сталкиваются ли тела только когда (body1.categoryBits & body2.maskBits) && (body1.maskBits & body2.categoryBits)? или они уже сталкиваются, когда (body1.categoryBits & body2.maskBits) || (body1.maskBits & body2.categoryBits)?

Ответы [ 5 ]

29 голосов
/ 05 июля 2011

Если кто-то все еще ищет больше объяснений, я сделал подробное руководство здесь:
http://aurelienribon.wordpress.com/2011/07/01/box2d-tutorial-collision-filtering/

15 голосов
/ 02 июня 2009

Из Box2D руководство :

6.2.3. Фильтрация

Фильтрация столкновений - это система для предотвращение столкновения между фигурами. Например, скажем, вы делаете персонаж который ездит на велосипеде. Вы хотите велосипед, чтобы столкнуться с местностью и персонаж сталкиваться с местность, но вы не хотите персонаж, чтобы столкнуться с велосипедом (потому что они должны перекрываться). Box2D поддерживает такую ​​фильтрацию столкновений используя категории и группы.

Box2D поддерживает 16 столкновений категории. Для каждой фигуры вы можете указать, к какой категории он относится. Вы также указываете, какие другие категории эта форма может столкнуться с. За Например, вы можете указать в многопользовательская игра, которая всех игроков не сталкиваются друг с другом и монстры не сталкиваются с каждым другие, но игроки и монстры должны сталкиваются. Это сделано с маскировкой биты. Например:

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

Группы столкновений позволяют указать интегральный групповой индекс. Вы можете иметь все фигуры с одинаковым групповым индексом всегда сталкиваться (положительный индекс) или никогда не сталкиваться (отрицательный индекс). группа индексы обычно используются для вещей которые как-то связаны, как части велосипеда. В следующих Например, shape1 и shape2 всегда сталкиваются, но shape3 и shape4 никогда сталкиваются.

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

Столкновения между формами разных групповые индексы фильтруются в соответствии биты категории и маски. В других слова, групповая фильтрация выше приоритет перед фильтрацией по категориям.

11 голосов
/ 03 февраля 2011

Вот так я понял, как работают maskBits и categoryBits. Допустим, у вас есть 3 объекта: objectA, objectB и objectC.

Определите для каждого объекта категорию:

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

Затем установите maskBits, который определяет правила коллизий для каждой категорииBits:

-> objectA сталкивается со всеми (0xFFFF) и (&) not (~) objectB (0x0004)
objectA.maskBits = 0xFFFF & ~ 0x0004;

-> objectB сталкивается с objectA (0x0002) или (|) objectC (0x0008), но больше никто не
objectB.maskBits = 0x0002 | 0x0008;

-> objectC сталкивается с objectA (0x0002), но больше ни с кем
objectC.maskBits = 0x0002;

Я не знаю, правильно ли это, но у меня это сработало.

НТН

3 голосов
/ 18 января 2011

Глядя на источник Box2d, он показывает, что, если приборы принадлежат разным группам (или группам 0), тогда категория и маски сравниваются следующим образом:

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

Таким образом, похоже, что прибор только сталкивается, если столкновение разрешено масками обоих приборов. (IE: И логика)

0 голосов
/ 23 сентября 2015

Я использовал стены и много игроков (наш игрок и враги). Мой игрок и враги сталкиваются со стенами, но не сталкиваются друг с другом. Я сделал так, и это сработало. Вы должны установить для groupIndex отрицательное значение, чтобы объекты не сталкивались друг с другом. Определите приборы так:

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

и примените к своим телам.

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