Search code examples
libgdxbox2d

Box2d/LibGDX: Rotate fixture along sprite's origin. See illustration


If I applyAngularImpulse to this circle sprite's body, it rotates along its center which is what I want to happen. But its collision mask fixture (in green) spins along its own center instead of the center of the sprite. How can I get it to rotate along the sprite's center too, so that the collision mask and sprite stay synced?

For example, in the image below, as the circle spins around and the red part makes its way to the top left, I want the green collision mask to be in position #3. But #2 occurs. I know why this is happening, but how can I achieve what I'm trying to accomplish here?

enter image description here


Solution

  • You need to create two fixtures - one of size of sprite (and the sprite should be centered with this fixture) and the second moved to the edge of circle (your current collision fixture)

    BodyDef bodyDef;
    
    ...
    
    Body body = world.createBody(bodyDef);
    
    FixtureDef circleFixture = new FixtureDef();
    FixtureDef collisionFixture = new FixtureDef();
    
    CircleShape circle = new CircleShape();
    circle.setRadius(spriteRadius);
    circleFixture.shape = circle;
    
    //same for collision fixture with proper shape - (0,0) i a center of circle
    float[] vertices = new float[]{x1, y1, x2, y2...};
    
    ChainShape chain = new ChainShape();
    chain.createLoop(vertices);
    fixtureDefs.peek().shape = chain;
    

    Now if you need to keep collision fixture on the edge of circle just define points that will place it there - for example for circle with radius of 2 vertices

    {5, -1, 6, 0, 5, 1, 4, 0}
    

    would give something like

    enter image description here

    and after rotation it should behave like

    enter image description here

    of course you need to render your sprite at the center of circle fixture