Search code examples
objective-ccocos2d-iphonebox2dobjective-c++

Box2d Contact Filtering


im using box2d in iOS and the cocos2d-library. I'm currently attempting to use contact filtering, but found that the category bit masking method simply isnt working for me. I've understood the method, but for some strange reason its not working.

Im initialising my objects filter data after I create the object, this is because I'm using an external library and dont have direct access to the fixture on creation. (It resides in a .plist file).

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

Basically im updating my contact filters on the fly, with two methods:

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

I've tried both techniques, the groupIndex and categoryBits, both dont work. Setting all group indicies to -1 doesnt cause all my BubbleNode and Boopop objects to filter the collision. Likewise, setting their maskBits to 0x0000 doesnt cause it to filter their collisions either.

Im pretty stumped, I thought perhaps it was something to do with my method, but setting all the groupIndex values to -1 should cause them all to filter eachother.
So now, im questioning my code more than the bits.

Help anyone!
Thanks!


Solution

  • I read your question multiple times, but I still don't quite get it whether you want them to collide or not. So here I'll just post the way to set the categoryBits and maskBits based on whether you want them to collide or not:

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

    Results

    (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
    

    Hope this helps.