0
votes

When I create a joint between two bodies, their position changes. I don't create any forces.

Code:

#include <iostream>
#include <Box2D/Box2D.h>

int main() {
    // WORLD
    b2World world(b2Vec2(0, 0));

    // BODY DEF
    b2BodyDef bodyDef;
    bodyDef.type = b2_dynamicBody;

    // SHAPES
    b2PolygonShape polygonShape;
    polygonShape.SetAsBox(1, 1);

    b2PolygonShape polygonShape2;
    polygonShape2.SetAsBox(0.5, 0.5);

    // BODY 1
    b2Body* body = world.CreateBody(&bodyDef);
    b2Fixture* fixture = body->CreateFixture(&polygonShape, 1);

    // BODY 2
    b2Body* body2 = world.CreateBody(&bodyDef);
    b2Fixture* fixture2 = body2->CreateFixture(&polygonShape2, 1);

    // JOINT
    b2RevoluteJointDef jointDef;
    jointDef.bodyA = body;
    jointDef.localAnchorB.SetZero();

    jointDef.bodyB = body2;
    jointDef.localAnchorA.Set(1, 1);
    b2Joint* joint = world.CreateJoint(&jointDef);

    // LOGS (X POSITION)
    std::cout << "[ body 1 ] " << body->GetPosition().x << std::endl;
    std::cout << "[ body 2 ] " << body2->GetPosition().x << std::endl;

    world.Step(1 / 50.0f, 8, 3);

    std::cout << "[ body 1 ] " << body->GetPosition().x << std::endl;
    std::cout << "[ body 2 ] " << body2->GetPosition().x << std::endl;
    return 0;
}

Output (x position):

[ body 1 ] 0                                (before step)
[ body 2 ] 0
[ body 1 ] -0.2                             (after step)
[ body 2 ] 0.8

I think it should return

[ body 1 ] 0                                (before step)
[ body 2 ] 0
[ body 1 ] 0                                (after step)
[ body 2 ] 1

Maybe something's wrong in my code? I'm new in Box2D. What I should do to get the expected result?

Before the step the position of body 1 and body 2 is (0, 0). I think it should place body 2 to (1, 1) automatically after the step, it shouldn't move both bodies.

1
At > 100 rep, you should know that you're supposed to post code, not links to code. - molbdnilo
@molbdnilo I'll try to decrease the lines of code and post it here, but I don't know stackoverflow will accept it. - Szymon Marczak
@molbdnilo Thanks. - Szymon Marczak
Added body2->SetTransform(body->GetPosition() + joint->GetAnchorA(), body2->GetAngle()); before calling world.Step. It places the second body on its correct position. If it isn't correct, 'invicible' force moves it to its correct position. - Szymon Marczak

1 Answers

1
votes

Your code is not setting the b2BodyDef position field, so both bodies are getting created with their centers at the default location of Vec2(0, 0) (per the b2BodyDef structure definition in the b2Body.h file). Based on the positions that your code sets localAnchorA and localAnchorB to, I suspect your code for creating the bodies needs to be more like:

b2BodyDef bodyDef1;
bodyDef1.type = b2_dynamicBody;
bodyDef1.position.Set(0.0f, 0.0f);

b2BodyDef bodyDef2;
bodyDef2.type = b2_dynamicBody;
bodyDef2.position.Set(1.0f, 1.0f);
...
b2Body* body = world.CreateBody(&bodyDef1);
...
b2Body* body2 = world.CreateBody(&bodyDef2);

This way your body polygonShape is centered at Vec2(0.0f, 0.0f), your body2 polygonShape2 is centered at the former shape's top right corner, and the anchor point that joins both bodies is right there at that same corner (the world position of Vec2(1.0f, 1.0f)).