0

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

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

我正在尝试模拟和渲染许多与RevoluteJoints 连接的随机体(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;
}

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

4

2 回答 2

0

tl; dr:我找到了解决方案,但尚未确定确切的问题。可以肯定的是我的翻译方法。

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

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

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

这是一个演示这一点的视频:(待上传)

请注意,当我将 设置为pixelsPerMeter250,晃动似乎消失了,而当我将其设置为 时25,它非常明显。

于 2014-01-28T21:42:31.673 回答
0

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

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

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

于 2014-01-28T23:09:14.477 回答