How to properly add texture to multi-fixture/shape b2Body
- by Blazej Wdowikowski
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?