抖动不稳定的JBox2D机身

时间:2014-01-26 18:10:43

标签: java box2d simulation java-2d jbox2d

编辑2: http://youtu.be/KiCzUZ69gpA - 正如您在此视频中看到的那样,当我为每个身体渲染一些文字时,摇动效果放大。观察当每个物体在其附近渲染一些文本时,地面体(蓝色)如何猛烈摇晃,以及当文本渲染被注释掉时它是如何形成的。这必须连接!

编辑:我对原始问题做了两个重要的补充:我添加了渲染功能,相机(翻译)方法我认为错误实际上存在,而不是在JBox2D中。

我正在尝试模拟和渲染许多与RevoluteJoint s连接的随机体(2-20)。一个主体可以连接到多个其他主体,并且没有单独的结构,即所有主体都是相互连接的。

然而,在观看实时渲染时,它非常不稳定且不稳定。我的意思是,身体的位置(或者角度)似乎随机波动,没有明显的原因,使模拟看起来不稳定。

这是我正在观察的视频:

http://youtu.be/xql-ypso1ZU

注意中间正方形和旋转矩形。中间的正方形在看似随机的间隔内来回移动其位置,旋转的矩形非常紧张(看看它正在旋转的点)。

这会产生什么影响?它是(J)Box2D的一个已知问题,还是我的渲染系统的一个问题?我认为我在某种程度上错误配置了物理引擎,但渲染系统中的一些浮点数学也可能是罪魁祸首

以下是我创建身体和关节的方法:

private Body setPart(Part part) {
    // body definition
    BodyDef bd = new BodyDef();
    bd.position.set(0f, -10f);
    bd.angle = 0f;
    bd.type = BodyType.DYNAMIC;

    // define shape of the body.
    PolygonShape Shape = new PolygonShape();
    Shape.setAsBox(part.width / 2, part.height / 2);

    // define fixture of the body.
    FixtureDef fd = new FixtureDef();
    Filter filter = new Filter();
    filter.groupIndex = -1;
    fd.filter = filter;
    fd.shape = Shape;
    fd.density = 0.5f;
    fd.friction = 0.3f;
    fd.restitution = 0.5f;

    // create the body and add fixture to it
    Body body = world.createBody(bd);
    body.createFixture(fd);
    body.setUserData(new PartUserData());

    return body;
}

private void setJoint(PartJoint partJoint) {
    Body bodyOne = partToBody.get(partJoint.partOne);
    Body bodyTwo = partToBody.get(partJoint.partTwo);

    RevoluteJointDef jointDef = new RevoluteJointDef();
    jointDef.bodyA = bodyOne;
    jointDef.bodyB = bodyTwo;

    jointDef.localAnchorA = partJoint.partOne
            .getAnchor(partJoint.percentOne);
    jointDef.localAnchorB = partJoint.partTwo
            .getAnchor(partJoint.percentTwo);

    // rotation
    jointDef.lowerAngle = GeomUtil.circle(partJoint.rotateFrom);
    jointDef.upperAngle = GeomUtil.circle(partJoint.rotateTo);
    jointDef.enableLimit = true;
    jointDef.maxMotorTorque = 10.0f; // TODO limit maximum torque
    jointDef.motorSpeed = GeomUtil.circle(partJoint.angularVelocity);
    jointDef.enableMotor = true;

    world.createJoint(jointDef);
}

时间步长为0.01f

以下是我绘制身体的方法:

private void drawBody(Body body) {
    // setup the transforms
    Vector position = camera.translate(body.getPosition());
    currentGraphics.translate(position.x, position.y);
    currentGraphics.rotate(body.getAngle());

    // do the actual rendering
    for (Fixture fixture = body.getFixtureList(); fixture != null; fixture = fixture
            .getNext()) {
        PolygonShape shape = (PolygonShape) fixture.getShape();

        if (body.getUserData() instanceof PartUserData) {
            fillShape(shape, partFillColor);
            currentGraphics.setStroke(partOutlineStroke);
            outlineShape(shape, partOutlineColor);
        } else {
            fillShape(shape, groundFillColor);
            outlineShape(shape, groundOutlineColor);
        }
    }

    // clean up
    currentGraphics.rotate(-body.getAngle());
    currentGraphics.translate(-position.x, -position.y);
    currentGraphics.setColor(defaultColor);
    currentGraphics.setStroke(defaultStroke);
}

我认为问题可能就是我处理所有身体的渲染方式。

这是每个机构的算法: 1.将Graphics2D对象转换为其位置 2.按body.getAngle()旋转 3.渲染身体 4.向后旋转图形 5.翻译图形

在所有这些转变中,有可能出现问题吗?

当我删除对相机方法的调用时,效果似乎已减少。这些是相关的相机方法:

public Vector translate(Vec2 worldPosition) {
    Vector point = new Vector();

    point.x = (int) (worldPosition.x * pixelsPerMeter) - position.x;
    point.y = (int) (worldPosition.y * pixelsPerMeter) - position.y;

    point.x = (int) (point.x * zoom);
    point.y = (int) (point.y * zoom);

    point.x += renderer.getWidth() / 2;
    point.y += renderer.getHeight() / 2;

    return point;
}

public Vector translateRelative(Vec2 worldPosition) {
    Vector point = new Vector();

    point.x = (int) (worldPosition.x * pixelsPerMeter);
    point.y = (int) (worldPosition.y * pixelsPerMeter);

    point.x = (int) (point.x * zoom);
    point.y = (int) (point.y * zoom);

    return point;
}

但是它们中的哪一部分会引起问题?

2 个答案:

答案 0 :(得分:0)

tl;博士:我找到了一个解决方案,但还没有发现确切的问题。很确定这是我的翻译方法。

似乎我已经确定了问题的范围和解决方案,但我仍然不确定究竟是什么导致了这种行为。

在我在问题中发布的那些翻译公式中,所有JBox2D向量都乘以称为pixelsPerMeter的标度。当我将此比例设置为较低值时,会发生抖动效果(同样重要的是要注意还有另一个因素,称为zoom,对于较低的pixelsPerMeter通常更大。< / p>

所以,可能是当乘以相对较低的pixelsPerMeter时,我必须乘以更高的zoom因子,因为我在两者中都转换为int s步骤,浮点数学中可能存在一些错误。请参阅我在问题中发布的翻译方法。

以下是一段视频演示:(待上传)

请注意,当我将pixelsPerMeter设置为250时,抖动似乎已经消失,而当我将其设置为25时,它非常明显。

答案 1 :(得分:0)

您的解决方案是正确的。您不应该使用Box2D物理引擎的像素单位:)

http://box2d.org/2011/12/pixels/

https://code.google.com/p/box2d/wiki/FAQ#How_do_I_convert_pixels_to_meters