简体   繁体   中英

Farseer Physics objects don't quite touch

I've just got Farseer Physics working and I've created a quick/crude base object I can use to create objects easily.

So I've set up a quick simulation and it looks like this: 盒子没有碰撞的更精简的例子

in DebugView, it looks like this: 调试模式下框的Farseer示例

Upon closer inspection, with both modes enabled, I can see that the Orange boxes have one row and column of pixels missing: 缺少纹理上的像素

Anyone know why that might be?

class BasePhys
{
    public float unitToPixel;
    public float pixelToUnit;
    public Vector2 size;
    public Body body;
    public Texture2D texture;

    public BasePhys(World world, int x, int y)
    {
        this.unitToPixel = 100.0f;
        this.pixelToUnit = 1 / unitToPixel;
        TextureManager.GetTextureByName("base", ref this.texture);
        this.size = new Vector2(this.texture.Width, this.texture.Height);
        this.body = BodyFactory.CreateRectangle(world, this.size.X * this.pixelToUnit, this.size.Y * this.pixelToUnit, 1);
        this.body.BodyType = BodyType.Dynamic;
        this.body.Position = new Vector2(x * this.pixelToUnit, y * this.pixelToUnit);
    }
    public void Draw(SpriteBatch spriteBatch)
    {
        Vector2 scale = new Vector2(this.size.X / (float)this.texture.Width, this.size.Y / (float)this.texture.Height);
        Vector2 position = this.body.Position * unitToPixel;
        spriteBatch.Draw(this.texture, position, null, Color.White, this.body.Rotation, new Vector2(this.texture.Width / 2.0f, this.texture.Height / 2.0f), scale, SpriteEffects.None, 0);
    }
}

Does anyone know why this may be? It doesn't do it in all the Farseer demos. I've checked the texture and it has no invisible pixels , orange pixels fill the entire file.

Polygons in Farseer have a thin "skin" around them. They will not contact each other exactly - but be offset by this skin. This is by design.

For more details, see Settings.PolygonRadius . It's basically there to help improve collision detection.

By default the polygon radius is 0.01 physics units. You'll notice that, at your scale of 1 unit = 100 pixels , the polygon radius is equal to exactly one pixel - hence the one pixel gap between your objects.

Probably the easiest fix for this would be to make your rectangle sizes smaller by twice the polygon radius in each direction. Alternately you could scale the texture slightly larger to account for the radius.

(Don't turn off the radius itself - you'll get physics glitches.)


Don't forget that Farseer is tuned to handle objects of sizes and weights ranging from 0.1 to 10 units. Traditionally you would use meters and kilograms for these scales (although you don't have to).

Personally I find the pixel-to-unit conversion a bit ugly, because you end up with error-prone scaling code scattered throughout your project. For something substantial I'd recommend coding everything in physics-space, and then using a camera matrix (which you could pass to SpriteBatch.Begin ) to scale everything at render time.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM