We are about to switch to a new forum software. Until then we have removed the registration on this forum.
Hi there,
i'm currently working with Box2D. Ther purpose is, to load an SVG file and make Box2D Elements out of the single Shapes. Everything works just fine...except one bug that drives me totaly nuts. ;(
When i just display the verticies...everything is fine.
But if i try to translate the shape it makes a big jump an is totaly out of it's position. (in thise case only the leafs are active)
If i put out the if(isActive) evereything is missplaced from the start.
Et the code:
public class Shape{
private Body body;
public ShapeColor sColor;
public boolean isActive;
public String layer;
private Mover mover;
private Vec2 bodyCenter = new Vec2(0,0);
//Vec2 pos ;
private final short CATEGORY_LEAF = 0x0001; // 0000000000000001 in binary
private final short CATEGORY_TRUNK = 0x0002; // 0000000000000010 in binary
private final short MASK_TRUNK = CATEGORY_LEAF;
private final short MASK_LEAF = CATEGORY_TRUNK | CATEGORY_LEAF ;
private final short MASK_ALL = ~CATEGORY_TRUNK;
private final short MASK_NONE = -1;
private final short MASK_O = 0;
private Box2DProcessing box2d;
private float offset;
public Shape(Box2DProcessing box2d, String layer, Vec2[] shapeVerticies, ShapeColor sColor, float offset){
this.box2d = box2d;
this.layer = layer;
this.sColor = sColor;
this.offset = offset;
isActive = false;
makeBody( shapeVerticies);
makeMover();
}
public void display(){
Fixture f = body.getFixtureList();
PolygonShape ps = (PolygonShape) f.getShape();
float a = body.getAngle();
Vec2 pos = box2d.getBodyPixelCoord(body);
pushMatrix();
if(isActive){
translate(pos.x, pos.y);
rotate(-a);
}
noStroke();
beginShape();
// For every vertex, convert to pixel vector
for (int i = 0; i < ps.getVertexCount(); i++) {
Vec2 v = box2d.vectorWorldToPixels(ps.getVertex(i));
fill(sColor.getColor(v.x,v.y));
vertex(v.x, v.y);
}
endShape(CLOSE);
popMatrix();
}
private void killBody() {
box2d.destroyBody(body);
}
private void makeMover(){
if (layer.equals("trunk")) {
this.mover = new Mover(this);
}
if (layer.equals("leafs")) {
//this.mover = new RandomMover(this);
this.mover = new Mover(this);
}
}
private void makeBody( Vec2[] shapes) {
// Define a polygon (this is what we use for a rectangle)
PolygonShape ps = new PolygonShape();
Vec2[] vertices = new Vec2[shapes.length];
for(int i = 0; i<shapes.length;i++){
vertices[i] = box2d.vectorPixelsToWorld(shapes[i]);
}
Vec2 center = getCenter(vertices);
ps.set(vertices, vertices.length);
// Define the body
BodyDef bd = new BodyDef();
bd.type = BodyType.DYNAMIC;
//bd.type = BodyType.KINEMATIC;
bd.position.set(box2d.coordPixelsToWorld(center));
bd.linearDamping = 0.8;
// bd.angularDamping = 3.9;
body = box2d.createBody(bd);
// Define the Ficture
FixtureDef fd = new FixtureDef();
fd.shape = ps;
fd.density = 1;
fd.friction = 0.0;//random(0.7, 0.9);
fd.restitution = 0.2;
if (layer.equals("leafs")) {
fd.filter.categoryBits = CATEGORY_LEAF;
//fd.filter.maskBits = MASK_TRUNK;
fd.filter.maskBits = MASK_O;
}
if (layer.equals("trunk")) {
fd.filter.categoryBits = CATEGORY_TRUNK;
//fd.filter.maskBits = MASK_ALL;
fd.filter.maskBits = MASK_O;
//fd.filter.maskBits = MASK_TRUNK;
}
body.createFixture(fd);
body.setUserData(this);
}
private Vec2 getCenter(Vec2[] v){
float x=0f;
float y=0f;
float vCount = v.length;
for(int i=0;i<vCount;i++){
x = x + v[i].x;
y = y + v[i].y;
}
Vec2 center = new Vec2((float)x/vCount,(float)y/vCount);
return center;
}
public void move(boolean status){
if(status==true){
isActive=true;
mover.move();
}else{
isActive=false;
mover.stopMovement();
}
}
}
I have no idea what the problem is. Conversion Problem from box2d to realWorldCoords? Floating point problems? Me being an idiot? :D
Working on this for about...ehhh 12 hours or so. Hope i was still able to explain everythin in an understandable way :) I'm so thankful for your help! :)
Answers
Could it be that there is something wrong with the way i calculate the center of the triangles?
Update: Yes it has something to do whith the positioning. If i change
bd.position.set(box2d.coordPixelsToWorld(center));
to
bd.position.set(box2d.coordPixelsToWorld(width,height));
everything is shown proberly. But this seems to me like a shity workaround and i'm still confused. @-)
:D