简体   繁体   English

Farseer Physics对象不太接触

[英]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. 我刚刚让Farseer Physics工作,我创建了一个快速/粗略的基础对象,我可以用来轻松创建对象。

So I've set up a quick simulation and it looks like this: 所以我设置了一个快速模拟,它看起来像这样: 盒子没有碰撞的更精简的例子

in DebugView, it looks like this: 在DebugView中,它看起来像这样: 调试模式下框的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. 它并没有在所有的Farseer演示中都这样做。 I've checked the texture and it has no invisible pixels , orange pixels fill the entire file. 我检查了纹理,它没有不可见的pixels ,橙色pixels填满整个文件。

Polygons in Farseer have a thin "skin" around them. Farseer中的多边形周围有一层薄薄的“皮肤”。 They will not contact each other exactly - but be offset by this skin. 它们不会完全相互接触 - 但会被这个皮肤抵消。 This is by design. 这是设计的。

For more details, see Settings.PolygonRadius . 有关更多详细信息,请参阅Settings.PolygonRadius It's basically there to help improve collision detection. 它基本上可以帮助改善碰撞检测。

By default the polygon radius is 0.01 physics units. 默认情况下,多边形半径为0.01物理单位。 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. 你会注意到,在1 unit = 100 pixels比例下,多边形半径恰好等于一个像素 - 因此你的对象之间有一个像素间隙。

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. 不要忘记,Farseer可以处理尺寸和重量从0.1到10个单位的物体。 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. 对于实质性的东西,我建议在物理空间中编码所有内容,然后使用相机矩阵(可以传递给SpriteBatch.Begin )在渲染时缩放所有内容。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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