Box2D Diferença entre WorldCenter e posição

9

Portanto, esse problema está ocorrendo há alguns dias. Primeiro, qual é a diferença entre digamos Body.getWorldCenter () e Body.getPosition (). Ouvi dizer que o WorldCenter pode ter a ver com o centro de gravidade ou algo assim.

Segundo, quando eu crio um corpo Box2D para um sprite, o corpo está sempre no canto inferior esquerdo. Verifico imprimindo um retângulo de 1 pixel ao redor da box.getWorldCenter (). Pelo que entendi, o Corpo deve estar no centro do Sprite e sua caixa delimitadora deve envolver o Sprite, correto?

Aqui está uma imagem do que quero dizer (o Sprite é vermelho, azul do corpo):

insira a descrição da imagem aqui

Aqui está um código:

Criador do corpo:

    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;
}

Fazendo o 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 );
}
Trabalhador autonomo
fonte

Respostas:

10

Primeiro, qual é a diferença entre digamos Body.getWorldCenter () e Body.getPosition ().

Body.getWorldCenter()é o centro de gravidade. Body.getPosition()é o centro da AABB. Para uma caixa ou círculo simples, eles serão os mesmos; no entanto, se seu corpo estiver desequilibrado (por exemplo, equipamentos múltiplos / com densidades diferentes), eles serão diferentes. Tente também definir sua origem antes do local.

assim

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

ao invés de

mSprite.setPosition( pX, pY );
mSprite.setOrigin( mSprite.getWidth()/2, mSprite.getHeight()/2);
ClassicThunder
fonte
11
Portanto, é melhor definir a origem do que fazer isso no loop de renderização: mSprite.setPosition (mBody.getPosition (). X * C.P2M - mSprite.getWidth () / 2, mBody.getPosition (). Y * ...) ?
Free Lancer
Além disso, isso é realmente estranho, mas parece que em velocidades realmente altas a Textura parece estar à frente das caixas delimitadoras Sprite e Body.
Free Lancer
11
@FreeLancer Eu estava pensando a mesma pergunta exata sobre se seria melhor definir a origem ou compensar o desenho.
Amplify91
11
Não importa se você mesmo compensou o desenho ou se o Box2D o compensou usando o valor de origem. Os mesmos cálculos acontecem em algum lugar. É mais fácil raciocinar em seu próprio código, pois a posição é o centro de algo :).
Roy T.
Ok, então tentei definir a origem primeiro, como você disse, mas depois de alterar o método draw () do carro para: mSprite.setPosition (mBody.getPosition (). X * C.P2M, mB ...) Voltou ao mesmo problema
Free Lancer