How to properly add texture to multi-fixture/shape b2Body

Posted by Blazej Wdowikowski on Game Development See other posts from Game Development or by Blazej Wdowikowski
Published on 2012-08-30T20:36:19Z Indexed on 2012/08/30 21:51 UTC
Read the original article Hit count: 311

Filed under:
|
|
|

Hello to everyone this is my first poste here I hope that will be not fail start.

At start I must say I make part 1 in Ray's Tutorial "How To Make A Game Like Fruit Ninja With Box2D and Cocos2D". But I wonder what when I want make more complex body with texture? Simple just add n b2FixtureDef to the same body.

OK but what about texture? If I will take code from that tutorial it only fill last fixture. Probably it does not takes every b2Vec2 point. I was right, it did not. So quick refactor and from that

-(id)initWithTexture:(CCTexture2D*)texture body:(b2Body*)body original:(BOOL)original
{
    // gather all the vertices from our Box2D shape
    b2Fixture *originalFixture = body->GetFixtureList();
    b2PolygonShape *shape = (b2PolygonShape*)originalFixture->GetShape();
    int vertexCount = shape->GetVertexCount();
    NSMutableArray *points = [NSMutableArray arrayWithCapacity:vertexCount];
    for(int i = 0; i < vertexCount; i++) {
        CGPoint p = ccp(shape->GetVertex(i).x * PTM_RATIO, shape->GetVertex(i).y * PTM_RATIO);
        [points addObject:[NSValue valueWithCGPoint:p]];
    }

    if ((self = [super initWithPoints:points andTexture:texture]))
    {
        _body = body;
        _body->SetUserData(self);
        _original = original;
        // gets the center of the polygon
        _centroid = self.body->GetLocalCenter();
        // assign an anchor point based on the center
        self.anchorPoint = ccp(_centroid.x * PTM_RATIO / texture.contentSize.width, 
                               _centroid.y * PTM_RATIO / texture.contentSize.height);
    }
    return self;
}

I came up with that

-(id)initWithTexture:(CCTexture2D*)texture body:(b2Body*)body original:(BOOL)original
{
    int vertexCount = 0;
    //gather total number of b2Vect2 points
    b2Fixture *currentFixture = body->GetFixtureList();
    while (currentFixture) { //new
        b2PolygonShape *shape = (b2PolygonShape*)currentFixture->GetShape();
        vertexCount += shape->GetVertexCount();
        currentFixture = currentFixture->GetNext();
    }


    NSMutableArray *points = [NSMutableArray arrayWithCapacity:vertexCount];
    // gather all the vertices from our Box2D shape
    b2Fixture *originalFixture = body->GetFixtureList();
    while (originalFixture) { //new
        NSLog((NSString*)@"-");
        b2PolygonShape *shape = (b2PolygonShape*)originalFixture->GetShape();
        int currentVertexCount = shape->GetVertexCount();

        for(int i = 0; i < currentVertexCount; i++) {
            CGPoint p = ccp(shape->GetVertex(i).x * PTM_RATIO, shape->GetVertex(i).y * PTM_RATIO);
            [points addObject:[NSValue valueWithCGPoint:p]];
        }
        originalFixture = originalFixture->GetNext();
    }

    if ((self = [super initWithPoints:points andTexture:texture]))
    {
        _body = body;
        _body->SetUserData(self);
        _original = original;
        // gets the center of the polygon
        _centroid = self.body->GetLocalCenter();
        // assign an anchor point based on the center
        self.anchorPoint = ccp(_centroid.x * PTM_RATIO / texture.contentSize.width,_centroid.y * PTM_RATIO / texture.contentSize.height);
    }
    return self;
}

I was working for simple two fixtures body like

b2BodyDef bodyDef;
bodyDef.type = b2_dynamicBody;
bodyDef.position = position;
bodyDef.angle = rotation;
b2Body *body = world->CreateBody(&bodyDef);

b2FixtureDef fixtureDef;
fixtureDef.density = 1.0;
fixtureDef.friction = 0.5;
fixtureDef.restitution = 0.2;
fixtureDef.filter.categoryBits = 0x0001;
fixtureDef.filter.maskBits = 0x0001;

b2Vec2 vertices[] = {
    b2Vec2(0.0/PTM_RATIO,50.0/PTM_RATIO),
    b2Vec2(0.0/PTM_RATIO,0.0/PTM_RATIO),
    b2Vec2(50.0/PTM_RATIO,30.1/PTM_RATIO),
    b2Vec2(60.0/PTM_RATIO,60.0/PTM_RATIO)
};

b2PolygonShape shape;
shape.Set(vertices, 4);
fixtureDef.shape = &shape;
body->CreateFixture(&fixtureDef);

b2Vec2 vertices2[] = {
    b2Vec2(20.0/PTM_RATIO,50.0/PTM_RATIO),
    b2Vec2(20.0/PTM_RATIO,0.0/PTM_RATIO),
    b2Vec2(70.0/PTM_RATIO,30.1/PTM_RATIO),
    b2Vec2(80.0/PTM_RATIO,60.0/PTM_RATIO)
};

shape.Set(vertices2, 4);
fixtureDef.shape = &shape;
body->CreateFixture(&fixtureDef);

But if I try put secondary shape upper than first it starting wierd, texture goes crazy. For example not mention about more complex shapes. What's more if shapes have one common point texture will not render for them at all [For that I use Physics Edytor like in tutorial part1]

BTW. I use PolygonSprite and in method createWithWorld... another shapes.

Uff.. Question

So my question is, why texture coords are in such a mess up? It's my modify method or just wrong approach? Maybe I should remove duplicated from points array?

© Game Development or respective owner

Related posts about textures

Related posts about cocos2d-iphone