2
votes

I am creating a box2d body for my iOS game, that is built from 4 shapes that are convex. The problem is that it fails when calling the init method. Here's my code:

@implementation Banan
-(void)createBodyAtLocation:(CGPoint)location
{
    int num;
    float density = 1.0f;

    b2BodyDef bodyDef;
    bodyDef.type = b2_dynamicBody;
    bodyDef.position = b2Vec2(location.x/PTM_RATIO/RETSIZE, location.y/PTM_RATIO/RETSIZE);
    body = world->CreateBody(&bodyDef);
    body -> SetUserData(self);

    //first shape
    b2FixtureDef fixtureDef1;
    b2PolygonShape shape1;
    num = 4;
    b2Vec2 verts1[4];
        verts1[0].Set(58.9f / PTM_RATIO, 46.3f / PTM_RATIO);
         verts1[1].Set(63.3f / PTM_RATIO, 41.5f / PTM_RATIO);
        verts1[2].Set(47.4f / PTM_RATIO, 15.6f / PTM_RATIO);
         verts1[3].Set(43.6f / PTM_RATIO, 24.3f / PTM_RATIO);
    shape1.Set(verts1, num);
    fixtureDef1.shape = &shape1;
    fixtureDef1.density = density;


    //second
    b2FixtureDef fixtureDef2;
    b2PolygonShape shape2;
    num = 5;
    b2Vec2 verts2[5];
    verts2[0].Set(42.1f / PTM_RATIO, 21.7f / PTM_RATIO);
    verts2[1].Set(46.6f / PTM_RATIO, -0.1f / PTM_RATIO);
    verts2[2].Set(29.1f / PTM_RATIO, -32.2f / PTM_RATIO);
    verts2[3].Set(2.5f / PTM_RATIO, -45.2f / PTM_RATIO);
    verts2[4].Set(6.8f / PTM_RATIO, -10.4f / PTM_RATIO);
    shape2.Set(verts2, num);
    fixtureDef2.shape = &shape2;
    fixtureDef2.density = density;

    //third
    b2FixtureDef fixtureDef3;
    b2PolygonShape shape3;
    num = 4;
    b2Vec2 verts3[4];
    verts3[0].Set(5.6f / PTM_RATIO, -9.7f / PTM_RATIO);
    verts3[1].Set(-0.3f / PTM_RATIO, -45.7f / PTM_RATIO);
    verts3[2].Set(-32.7f / PTM_RATIO, -41.2f / PTM_RATIO);
    verts3[3].Set(-28.2f / PTM_RATIO, -15.7f / PTM_RATIO);
    shape3.Set(verts3, num);
    fixtureDef3.shape = &shape3;
    fixtureDef3.density = density;

    //fourth
    b2FixtureDef fixtureDef4;
    b2PolygonShape shape4;
    num = 4;
    b2Vec2 verts4[4];
    verts4[0].Set(-28.7f / PTM_RATIO, -14.8f / PTM_RATIO);
    verts4[1].Set(-40.8f / PTM_RATIO, -36.0f / PTM_RATIO);
    verts4[2].Set(-60.5f / PTM_RATIO, -2.4f / PTM_RATIO);
    verts4[3].Set(-58.0f / PTM_RATIO, 2.9f / PTM_RATIO);
    shape4.Set(verts3, num);
    fixtureDef4.shape = &shape4;
    fixtureDef4.density = density;

    //attach to shape
    body->CreateFixture(&fixtureDef1);
    body->CreateFixture(&fixtureDef2);
    body->CreateFixture(&fixtureDef3);
    body->CreateFixture(&fixtureDef4);
}
- (id)initWithWorld:(b2World *)tworld atLocation:(CGPoint)location {
    if ((self = [super init])) {
        world = tworld;
        [self initWithFile:@"Banana.png"];
        [self createBodyAtLocation:location];
    }
    return self;
}


-(void)dealloc
{
    [super dealloc];
}
@end

The '-initWithWorld: atLocation:' method is invoked by ccTouchBegan method and then kills my app. The errors are the following:

Assertion failed: (area > 1.19209290e-7F), function ComputeCentroid, ...

-(void)createBananaAtLocation:(CGPoint)location
{
    Banan *ban = [[[Banan alloc] initWithWorld:world atLocation:location] autorelease];//fails at this line when is invoked
    [self addChild:ban];

}
-(BOOL)ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event
{
    CGPoint touchLocation = [touch locationInView:[touch view]];
    touchLocation = [[CCDirector sharedDirector]
                     convertToGL:touchLocation];
    touchLocation = [self convertToNodeSpace:touchLocation];
    b2Vec2 locationWorld =
    b2Vec2(touchLocation.x/PTM_RATIO, touchLocation.y/PTM_RATIO);

    [self createBananaAtLocation:touchLocation]; //error at this line
    return YES;
}
1

1 Answers

4
votes

In your case vertices are oriented clockwise, while b2Polygon requirement is counterclockwise. It leads to calculation of negative area of the polygon. You have to change order of your vertices.