Điều gì khiến các khớp xoay của Box2D tách ra?


7

Tôi đã tạo ra một con búp bê giẻ rách bằng cách sử dụng các cơ thể động (hình chữ nhật) và các khớp xoay tròn đơn giản (với các góc dưới và trên). Khi con búp bê giẻ rách của tôi chạm đất (là một cơ thể tĩnh), các cơ thể dường như bồn chồn và các khớp xương tách ra.

Có vẻ như các cơ thể đang dính vào mặt đất, và động lực của con búp bê giẻ rách kéo khớp ra (xem ảnh chụp màn hình bên dưới).

văn bản thay thế

Tôi không chắc nó có liên quan hay không, nhưng tôi đang sử dụng trình bao bọc Java Badlogic GDX cho Box2D. Đây là một số đoạn của những gì tôi nghĩ là mã có liên quan nhất:

private RevoluteJoint joinBodyParts(
    Body a, Body b, Vector2 anchor, 
    float lowerAngle, float upperAngle) {

    RevoluteJointDef jointDef = new RevoluteJointDef();

    jointDef.initialize(a, b, a.getWorldPoint(anchor));

    jointDef.enableLimit = true;
    jointDef.lowerAngle = lowerAngle;
    jointDef.upperAngle = upperAngle;

    return (RevoluteJoint)world.createJoint(jointDef);
}

private Body createRectangleBodyPart(
    float x, float y, float width, float height) {

    PolygonShape shape = new PolygonShape();
    shape.setAsBox(width, height);

    BodyDef bodyDef = new BodyDef();
    bodyDef.type = BodyType.DynamicBody;
    bodyDef.position.y = y;
    bodyDef.position.x = x;

    Body body = world.createBody(bodyDef);

    FixtureDef fixtureDef = new FixtureDef();
    fixtureDef.shape = shape;
    fixtureDef.density = 10;

    fixtureDef.filter.groupIndex = -1;
    fixtureDef.filter.categoryBits = FILTER_BOY;
    fixtureDef.filter.maskBits = FILTER_STUFF | FILTER_WALL;

    body.createFixture(fixtureDef);
    shape.dispose();

    return body;
}

Tôi đã bỏ qua phương pháp tạo đầu, vì nó khá giống với phương pháp hình chữ nhật (chỉ sử dụng hình dạng cricle).

Những phương thức này được sử dụng như vậy:

    torso = createRectangleBodyPart(x, y + 5, 0.25f, 1.5f);
    Body head = createRoundBodyPart(x, y + 7.4f, 1);

    Body leftLegTop = createRectangleBodyPart(x, y + 2.7f, 0.25f, 1);
    Body rightLegTop = createRectangleBodyPart(x, y + 2.7f, 0.25f, 1);
    Body leftLegBottom = createRectangleBodyPart(x, y + 1, 0.25f, 1);
    Body rightLegBottom = createRectangleBodyPart(x, y + 1, 0.25f, 1);

    Body leftArm = createRectangleBodyPart(x, y + 5, 0.25f, 1.2f);
    Body rightArm = createRectangleBodyPart(x, y + 5, 0.25f, 1.2f);

    joinBodyParts(torso, head, new Vector2(0, 1.6f), headAngle);

    leftLegTopJoint = joinBodyParts(torso, leftLegTop, new Vector2(0, -1.2f), 0.1f, legAngle);
    rightLegTopJoint = joinBodyParts(torso, rightLegTop, new Vector2(0, -1.2f), 0.1f, legAngle);
    leftLegBottomJoint = joinBodyParts(leftLegTop, leftLegBottom, new Vector2(0, -1), -legAngle * 1.5f, 0);
    rightLegBottomJoint = joinBodyParts(rightLegTop, rightLegBottom, new Vector2(0, -1), -legAngle * 1.5f, 0);

    leftArmJoint = joinBodyParts(torso, leftArm, new Vector2(0, 1), -armAngle * 0.7f, armAngle);
    rightArmJoint = joinBodyParts(torso, rightArm, new Vector2(0, 1), -armAngle * 0.7f, armAngle);

Bạn có chạy mô phỏng vật lý của bạn với một dấu thời gian cố định? Nếu không, bạn chắc chắn nên làm điều đó đầu tiên.
bummzack

Câu trả lời:


5

Box2D sử dụng một bộ giải dạng lặp chứ không phải dạng đóng . Điều này có nghĩa là tất cả các ràng buộc là hơi mềm. Box2D sẽ rất cố gắng để làm những gì bạn nói, nhưng sự thiếu chính xác xảy ra.

Để giảm thiểu điều này, có một số điều bạn có thể làm, theo thứ tự quan trọng:

  • Sử dụng dấu thời gian có kích thước cố định (đối số đầu tiên Step). Điều này làm cho người giải quyết ổn định hơn - sự thiếu chính xác của bạn có nhiều khả năng triệt tiêu lẫn nhau hoặc ít nhất là hành xử giống nhau mỗi lần.
  • Sử dụng dấu thời gian nhỏ hơn (1/60 hoặc 1/120 thay vì 1/30). Dấu thời gian nhỏ hơn có nghĩa là không chính xác nhỏ hơn.
  • Sử dụng nhiều lần lặp bộ giải hơn (đối số thứ 2/3 đến Step). Bạn nên cố gắng để có được ít nhất 10 mỗi. Lặp lại nhiều bộ giải hơn có nghĩa là nhiều cơ hội hơn mỗi dấu thời gian để tìm sự ổn định và thỏa mãn chính xác các ràng buộc - đại khái, ít cơ hội không chính xác. Tuy nhiên, dấu thời gian nhỏ hơn, stabler tốt hơn nhiều lần lặp. Với các ràng buộc đủ phức tạp, bạn có thể không bao giờ giải quyết chúng chính xác 100%, vì vậy hãy thử giảm dấu thời gian trước khi tăng số lần lặp.
  • Sử dụng hình dạng ít dày đặc hơn. Mật độ 10 khá nặng. Hãy thử tiêu chuẩn hóa một cái gì đó nhỏ hơn - như 1 - làm mật độ mặc định của bạn.

Xin chào Joe, cảm ơn vì lời khuyên. Tôi đã thử tất cả các đề xuất của bạn nhưng tiếc là điều này dường như không tạo ra sự khác biệt. Đây là mã nguồn đầy đủ (hiện tại nó chỉ là một nguyên mẫu hacky) - pastebin.com/F6YX3AyV
Nick Bolton
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.