Фильтрация контактов Box2d

я использую box2d в iOS и библиотеку cocos2d. В настоящее время я пытаюсь использовать фильтрацию контактов, но обнаружил, что метод битовой маскировки категории просто не работает для меня. Я понял метод, но по какой-то странной причине он не работает.

Я инициализирую данные фильтра своих объектов после создания объекта, потому что я использую внешнюю библиотеку и не имею прямого доступа к приспособлению при создании. (Он находится в файле .plist).

 bodydef.type = b2_dynamicBody;
 bodydef.position.Set(location.x/PTM_RATIO, location.y/PTM_RATIO);
 bodydef.userData = self;
 bodydef.fixedRotation = true;
 //bodydef.angularDamping = 2.0f;
 body = world->CreateBody(&bodydef);

 // add the fixture definitions to the body
 [[GB2ShapeCache sharedShapeCache] addShapesWithFile:@"bubblephysics.plist"];
 [[GB2ShapeCache sharedShapeCache] addFixturesToBody:body forShapeName:filename];
 [sprite setAnchorPoint:[[GB2ShapeCache sharedShapeCache] anchorPointForShape:filename]];

 //Apply a new filter on the initialized body
 b2Fixture *tempFixture = self.body->GetFixtureList();
 b2Filter temp = tempFixture->GetFilterData();

 if ([self isMemberOfClass:[Boopop class]]){    
     temp.categoryBits = 0x0004;
     temp.maskBits = 0x0000;
     temp.groupIndex = 0;
     tempFixture->SetFilterData(temp);
 }
 if ([self isMemberOfClass:[BubbleNode class]]){
     temp.categoryBits = 0x0004;
     temp.maskBits = 0x0000;
     temp.groupIndex = 0;
     tempFixture->SetFilterData(temp);
 }

В основном я обновляю свои контактные фильтры на лету двумя способами:

-(void)freezeBubble{
    self.isFrozen = NO; //Stops Iteration of the b2Body and CCSprite;
    b2Fixture *tempFixture = self.body->GetFixtureList();
    b2Filter temp = tempFixture->GetFilterData();
    temp.groupIndex = 0;
    temp.categoryBits = 0x0004;
    temp.maskBits = 0x0000;
    tempFixture->SetFilterData(temp);
}
-(void)unfreezeBubble{
    self.isFrozen = NO;
    b2Fixture *tempFixture = self.body->GetFixtureList();
    b2Filter temp = tempFixture->GetFilterData();
    NSLog(@"Previous Bits: cat = %d, mask = %d",temp.categoryBits,temp.maskBits);
    temp.groupIndex = 0;
    temp.categoryBits = 0x0004;
    temp.maskBits = 0x0000;
    tempFixture->SetFilterData(temp);
}

Я пробовал оба метода, groupIndex и categoryBits, оба не работают. Установка для всех групповых индексов значения -1 не приводит к тому, что все мои объекты BubbleNode и Boopop фильтруют коллизии. Точно так же установка их maskBits в 0x0000 также не приводит к фильтрации их коллизий.

Я довольно озадачен, я думал, что, возможно, это как-то связано с моим методом, но установка всех значений groupIndex в -1 должна привести к тому, что все они будут фильтровать друг друга.
Итак, теперь я подвергаю сомнению свой код больше, чем биты.

Помогите всем!
Спасибо!


person Ospho    schedule 16.08.2011    source источник


Ответы (1)


Я читал ваш вопрос несколько раз, но до сих пор не совсем понимаю, хотите ли вы, чтобы они столкнулись или нет. Итак, здесь я просто опубликую способ установки categoryBits и maskBits в зависимости от того, хотите ли вы, чтобы они сталкивались или нет:

uint16 boopopCategoryBits = 1 << 0;
uint16 bubbleCategoryBits = 1 << 1;

uint16 boopopMaskBits = 0;
uint16 bubbleMaskBits = 0;

bool boobop_n_boobop_should_collide = true;
bool bubble_n_bubble_should_collide = true;
bool boobop_n_bubble_should_collide = true;

if (boobop_n_boobop_should_collide) {
    boopopMaskBits = boopopMaskBits | boopopCategoryBits;
}

if (bubble_n_bubble_should_collide) {
    bubbleMaskBits = bubbleMaskBits | bubbleCategoryBits;
}

if (boobop_n_bubble_should_collide) {
    bubbleMaskBits = bubbleMaskBits | boopopCategoryBits;
    boopopMaskBits = boopopMaskBits | bubbleCategoryBits;
}

Результаты

(boobop_n_boopop : bubble_n_bubble : boobop_n_bubble = boopopMaskBits : bubbleMaskBits)

true  : true  : true  = 3 : 3

true  : true  : false = 1 : 2

true  : false : false = 1 : 0

false : false : false = 0 : 0

false : true  : false = 0 : 2

false : true  : true  = 2 : 3

false : false : true  = 2 : 1

true  : false : true  = 3 : 1

Надеюсь это поможет.

person Lukman    schedule 16.08.2011
comment
Привет, да, я понимаю битовую маскировку, но что-то не работает в моем коде. Я посмотрел на ваш другой пост о нескольких приспособлениях на 1 теле, которые заставят их слипаться, если они появятся. Я исправил это и удалил инициализацию из файла plist, и теперь маскирование работает. Спасибо! - person Ospho; 17.08.2011