10
\$\begingroup\$

So this problem has been brothering for a couple of days now. First off, what is the difference between say Body.getWorldCenter() and Body.getPosition(). I heard that WorldCenter might have to do with the center of gravity or something.

Second, When I create a Box2D Body for a sprite the Body is always at the lower left corner. I check it by printing a Rectangle of 1 pixel around the box.getWorldCenter(). From what I understand the Body should be in the center of the Sprite and its bounding box should wrap around the Sprite, correct?

Here's an image of what I mean (The Sprite is Red, Body Blue):

enter image description here

Here's some code:

Body Creator:

    public static Body createBoxBody( final World pPhysicsWorld, final BodyType pBodyType, 
            final FixtureDef pFixtureDef, Sprite pSprite ) {

        float pRotation = 0;
        float pCenterX = pSprite.getX() + pSprite.getWidth() / 2;
        float pCenterY = pSprite.getY() + pSprite.getHeight() / 2;
        float pWidth = pSprite.getWidth();
        float pHeight = pSprite.getHeight();

        final BodyDef boxBodyDef = new BodyDef();
        boxBodyDef.type = pBodyType;

        //boxBodyDef.position.x = pCenterX / Constants.PIXEL_METER_RATIO;
        //boxBodyDef.position.y = pCenterY / Constants.PIXEL_METER_RATIO;

        boxBodyDef.position.x = pSprite.getX() / Constants.PIXEL_METER_RATIO;
        boxBodyDef.position.y = pSprite.getY() / Constants.PIXEL_METER_RATIO;

        Vector2 v = new Vector2( boxBodyDef.position.x * Constants.PIXEL_METER_RATIO, boxBodyDef.position.y * Constants.PIXEL_METER_RATIO );
        Gdx.app.log("@Physics", "createBoxBody():: Box Position: " + v);

        // Temporary Box shape of the Body
        final PolygonShape boxPoly = new PolygonShape();
        final float halfWidth = pWidth * 0.5f / Constants.PIXEL_METER_RATIO;
        final float halfHeight = pHeight * 0.5f / Constants.PIXEL_METER_RATIO;
        boxPoly.setAsBox( halfWidth, halfHeight );  // set the anchor point to be the center of the sprite

        pFixtureDef.shape = boxPoly;


        final Body boxBody = pPhysicsWorld.createBody(boxBodyDef);
        Gdx.app.log("@Physics", "createBoxBody():: Box Center: " + boxBody.getPosition().mul(Constants.PIXEL_METER_RATIO));
        boxBody.createFixture(pFixtureDef);

        boxBody.setTransform( boxBody.getWorldCenter(), MathUtils.degreesToRadians * pRotation );


        boxPoly.dispose();

        return boxBody;
}

Making the Sprite:

    public Car( Texture texture, float pX, float pY, World world ) {

        super( "Car" ); 

        mSprite = new Sprite( texture );
        mSprite.setSize( mSprite.getWidth() / 6, mSprite.getHeight() / 6 );
        mSprite.setPosition( pX, pY );
        mSprite.setOrigin( mSprite.getWidth()/2, mSprite.getHeight()/2);

        FixtureDef carFixtureDef = new FixtureDef();

        // Set the Fixture's properties, like friction, using the car's shape
        carFixtureDef.restitution = 1f;
        carFixtureDef.friction = 1f;
        carFixtureDef.density = 1f; // needed to rotate body using applyTorque      

        mBody = Physics.createBoxBody( world, BodyDef.BodyType.DynamicBody, carFixtureDef, mSprite );
}
\$\endgroup\$

1 Answer 1

10
\$\begingroup\$

First off, what is the difference between say Body.getWorldCenter() and Body.getPosition().

Body.getWorldCenter() is the center of gravity. Body.getPosition() is the center of the AABB. For a simple box or circle they will be the same however if your body is unbalanced (ex. multiple fixtures /w different densities) they will differ. Also try setting your origin before the location.

So

mSprite.setOrigin( mSprite.getWidth()/2, mSprite.getHeight()/2);
mSprite.setPosition( pX, pY );

instead of

mSprite.setPosition( pX, pY );
mSprite.setOrigin( mSprite.getWidth()/2, mSprite.getHeight()/2);
\$\endgroup\$
6
  • 1
    \$\begingroup\$ So is setting the origin better than doing this in the render loop: mSprite.setPosition( mBody.getPosition().x * C.P2M - mSprite.getWidth()/2, mBody.getPosition().y * ...) ? \$\endgroup\$ Mar 26, 2012 at 5:15
  • \$\begingroup\$ Also, this is really weird, but it seems that at really high speeds the Texture seems to be ahead of both the Sprite and Body bounding boxes. \$\endgroup\$ Mar 26, 2012 at 5:17
  • 1
    \$\begingroup\$ @FreeLancer I was thinking the same exact question about whether it would be better to set the origin or offset the drawing. \$\endgroup\$
    – Amplify91
    Mar 26, 2012 at 5:26
  • 1
    \$\begingroup\$ It doesn't matter if you offset the drawing yourself or if you let Box2D offset it by using the origin value. The same calculations happen somewhere. It's just easier to reason in your own code as the position being the center of something :). \$\endgroup\$
    – Roy T.
    Mar 26, 2012 at 6:23
  • \$\begingroup\$ Ok, so I tried setting the origin first like you said but after changing the Car's draw() method to: mSprite.setPosition( mBody.getPosition().x * C.P2M, mB...) It went back to the same problem \$\endgroup\$ Mar 26, 2012 at 6:39

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .