2

我正在使用 Libgdx 的 box2d 端口。我正在创建一个边缘形状,但它不会在与其他多边形碰撞时旋转。为什么是这样?

这是我设置边缘形状的代码。

float x = 3;
float y = 10;
BodyDef bodyDef = new BodyDef();
bodyDef.type = BodyType.DynamicBody;
bodyDef.position.set(x, y);

Body body = this.world.createBody(bodyDef);
MassData massdata = new MassData();
massdata.center.set(1,1);
massdata.mass = 10;
body.setMassData(massdata);

FixtureDef fixtureDef = new FixtureDef();
EdgeShape shape = new EdgeShape();
shape.set(0, 0, 2, 2);
fixtureDef.shape= shape;
fixtureDef.friction = 1;
fixtureDef.restitution = .5f;
fixtureDef.density = 10;
body.createFixture(fixtureDef);
4

3 回答 3

3

这是因为 Box2D 中的边缘形状旨在创建静态风景。由于动力学,它根本无法移动。我猜运动学会起作用。这是合乎逻辑的,因为 EdgeShape 没有质量,因为它没有表面(或体积,如果您将 2D 世界视为具有固定深度的 3D)。

这是手册的摘录,它证实了我最初的想法:

边缘形状是线段。提供这些是为了帮助为您的游戏制作一个自由形式的静态环境。边缘形状的一个主要限制是它们可以与圆形和多边形碰撞,但不能与自身碰撞。Box2D 使用的碰撞算法要求两个碰撞形状中的至少一个具有体积。边缘形状没有体积,因此边缘边缘碰撞是不可能的。

于 2013-07-10T00:27:33.510 回答
2

正如Martijn所说,我计算并设置了身体的质量数据。为此,我在假设密度均匀的情况下计算质心。我正在使用 LIBGDX,所以我需要一种在 java 中执行此操作的方法。我使用 Box2D 的源代码编写了例程。随意使用它来做任何你喜欢的事情。

EdgeShapes 没有质量,因此没有物理行为。要引起这种行为,需要手动计算。

public static MassData calculateMassData(List<Vector2> vertices,
        float density) {
    float k_inv3 = 1.0f / 3.0f;
    float area = 0.0f;
    float I = 0.0f;
    Vector2 center = new Vector2();

    Vector2 s = new Vector2();
    for (int i = 0, size = vertices.size(); i < size; i++) {
        s.add(vertices.get(i));
    }
    s.div(vertices.size());

    for (int i = 0, size = vertices.size(); i < size; ++i) {
        // Triangle vertices.
        Vector2 e1 = new Vector2(vertices.get(i));
        e1.sub(s);
        Vector2 e2 = new Vector2(i + 1 < size ? vertices.get(i + 1)
                : vertices.get(0));
        e2.sub(s);

        float D = e1.crs(e2);

        float triangleArea = 0.5f * D;
        area += triangleArea;

        // Area weighted centroid
        center.add(e1.cpy().add(e2).mul(k_inv3).mul(triangleArea));

        float ex1 = e1.x, ey1 = e1.y;
        float ex2 = e2.x, ey2 = e2.y;

        float intx2 = ex1 * ex1 + ex2 * ex1 + ex2 * ex2;
        float inty2 = ey1 * ey1 + ey2 * ey1 + ey2 * ey2;

        I += (0.25f * k_inv3 * D) * (intx2 + inty2);
    }

    MassData data = new MassData();
    // Total mass
    data.mass = density * area;

    center.mul(1.0f / area);
    data.center.set(center.cpy().add(s));
    // Inertia tensor relative to the local origin (point s).
    data.I = density * I;

    // Shift to center of mass then to original body origin.
    data.I += data.mass
            * (data.center.dot(data.center) - center.dot(center));
    data.I = (data.I);
    return data;
} 

边缘形状的2个限制:

  1. 边缘形状不会与其他边缘形状发生冲突
  2. 边缘形状不是正常的多边形。对于仅使用边缘形状构建的任何多边形,都没有真正的外部/内部定义。

由于#2,其他物体可以在使用边缘形状构建的多边形内结束。

由于#1,我采用了不同的方法并使用一系列窄矩形构建了我的多边形。这运作良好,但不幸的是不能解决#2。

我不想将 PolygonShape 用于固定装置,因为我尝试建模的多边形很复杂。它可以有数百个顶点。

我尝试过对我的多边形进行三角剖分并从每个三角形中创建固定装置。不幸的是,生成的三角形面积对于 Box2D 来说通常太小,并且会导致 box2d 出现异常。

我对这里的其他解决方案持开放态度。

于 2013-07-10T00:54:58.070 回答
1

试试: http: //libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/physics/box2d/Body.html#setFixedRotation%28boolean%29

body.setFixedRotation(false)

你的摩擦也太高了。试试 0.6f

于 2013-07-04T00:44:38.377 回答