4
\$\begingroup\$

I have a rectangle in my player class with the following properties

b2BodyDef player;
player.type = b2_dynamicBody;
player.position.Set(x + width, 10.17f - (y + height));

m_PhysicsBody = level->GetPhysicsWorld().CreateBody(&player);

b2PolygonShape shape;
shape.SetAsBox(width, height);

b2FixtureDef fixture;
fixture.shape = &shape;
fixture.density = 1.0f;
fixture.friction = 1.0f;

m_PhysicsFixture = m_PhysicsBody->CreateFixture(&fixture);
m_PhysicsFixture->SetUserData(this);

and another rectangle in my level class with the following properties

b2BodyDef ground;

ground.position.Set(x + width, 10.17 - (y + height));

b2PolygonShape groundBox;
groundBox.SetAsBox(width, height);

b2Body* m_Body = m_PhysicsWorld.CreateBody(&ground);

b2FixtureDef fixture;
fixture.shape = &groundBox;

fixture.friction = 1.0f;

m_PhysicsFixture = m_Body->CreateFixture(&fixture);

m_PhysicsFixture->GetShape()->ComputeAABB(&aabb, m_Body->GetTransform(), 0);

The problem is that unless the player object is a perfect square (the width and the height are exactly the same) it won't sit exactly on top of the ground object I created in the level class. It intersects it a little bit before coming to a rest. I've attached a picture so you guys can see.enter image description here

The way that I render the shapes is as follows

b2AABB aabb;
m_PhysicsFixture->GetShape()->ComputeAABB(&aabb, m_PhysicsBody->GetTransform(), 0);

DrawRectangle(aabb.lowerBound.x * 100.0f, (m_Window.GetHeight() - (aabb.lowerBound.y * 100.0f)), (aabb.upperBound.x - aabb.lowerBound.x) * 100.0f, (aabb.upperBound.y - aabb.lowerBound.y) * 100.0f);

I multiply the values by 100.0f to make it bigger, and y is the height of the window minus y. This is because I'm using SDL, which sets the upper-left corner as the 0,0 origin. So all the way at the very top, y = 0, and all the way at the bottom, y = the window height.

\$\endgroup\$
1
\$\begingroup\$

Box2D objects sitting on top of each other in a non-zero gravity situation will have some overlap, at least overlap within their shapes' "skins" (their outer shapes). That's normal and intentional.

The skins are buffer zones of a sort that serve to eliminate jitter; to help get the system to a steady state. In Box2D, the skin's size is determined by the value of the b2Shape::m_radius member variable.

Usually overlap is not visible though. It can become visible if:

  1. Your view is more zoomed in than is typical (like if the scales aren't in the recommended ranges) and you are viewing the outer shapes or viewing their AABBs.
  2. The density/mass of the upper object's fixture(s) is significantly higher than that of the lower body's.
  3. There are a bunch of bodies stacked on top of one another.
  4. The simulation isn't using enough position iterations.
  5. The simulation is failing to match up with the impulses of previous contact IDs which can sometimes happen in more dynamic simulations where contacts persist a while like in the Tumbler Testbed test.

Changing the position iteration count can effect how much overlap there will be each world step. Typically I'd expect increasing the position iterations to resolve excess overlap quicker. This should reduce overlap for situations 2, 3, or 4. Changing the fixture densities so they're closer to each other may also help. Changing the scale(s) may help with situation 1. Situation 5 doesn't seem related to what you've described but it requires changing Box2D's source code to deal with.

You can observe overlap in the native Box2D Testbed with like the Sphere Stack test if you zoom in enough on the lowest two circles.

Hope this helps!

\$\endgroup\$
  • \$\begingroup\$ Your first situation might apply. I edited the post to show how I render the boxes. I am rendering their AABBS. I also multiply the values by 100.0f to make them bigger. But I still don't understand exactly what I'm doing wrong and why I don't have this problem when the shape is a perfect square. \$\endgroup\$ – Sean Carey Nov 12 '17 at 20:51
  • \$\begingroup\$ Box2D AABB's are displaced and extended from the coordinates of all the points of the given convex shape they're for. So their actual boundaries are not the minimal container it seems you're thinking of them as. Anyway, is your Y changing between creating the player and ground or are you creating them within each other? \$\endgroup\$ – Louis Langholtz Nov 12 '17 at 21:35
  • \$\begingroup\$ I ask about their y positions on creation because that might explain the difference you're seeing between a rectangle and square. \$\endgroup\$ – Louis Langholtz Nov 12 '17 at 21:37
  • \$\begingroup\$ The player and the ground each have their own Y. They're different classes and they don't extend each other or share any values. \$\endgroup\$ – Sean Carey Nov 12 '17 at 21:58
  • \$\begingroup\$ @CareyOn Thanks... that helps to know. What are the player and ground y and height values then when they are created? \$\endgroup\$ – Louis Langholtz Nov 12 '17 at 22:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.