# Bodies are colliding but refusing to rotate in Box2D

I'm running box2d in C++ and hooking it up to C# via p/invoke. All physics stuff occurs in C++.

My problem is that bodes know when they are colliding and do so with great precision. However if I have two boxes which are 10x10 units, one located at the origin and is static while another is set 30 units in the sky 4 units across and is dynamic, when the dynamic box falls and hits the static one it stops falling but doesn't turn and slide off the edge.

Here's a screenshot of what I mean:

The box on top is as far to the left as it possibly can be, any further left and it will fall past the box on the bottom. There is barely a pixel overlap that's keeping the top box there. As you can see it's not rotating to fall off.

This also happens (again only the lowest most box is static, the rest fell down a distance to get there),

Any ideas what I'm doing wrong?

My code for creating boxes is as such:

extern "C"
int CreateBox(b2Vec2 dim, b2Vec2 pos, bool dynamic, int worldid)
{
dim.x /= 100.0f;
dim.y /= 100.0f;
pos.x /= 100.0f;
pos.y /= 100.0f;

World &g = GetWorld(worldid);
b2BodyDef bodef;

bodef.type = b2_staticBody;
if(dynamic)
{
bodef.type = b2_dynamicBody;
}
bodef.position = pos;
bodef.angle = 0;
b2Body* pBody = g.m_pWorld->CreateBody(&bodef);

b2PolygonShape groundBox;
b2Vec2 center = b2Vec2(-dim.x / 2.0f, -dim.y / 2.0f);
groundBox.SetAsBox(dim.x / 2.0f, dim.y / 2.0f, center, 0);
for(int i = 0; i < b2_maxPolygonVertices; i++)
{
b2Vec2 vert = groundBox.m_vertices[i];
vert.x += dim.x / 2.0f;
vert.y += dim.y / 2.0f;
groundBox.m_vertices[i] = vert;
}

b2FixtureDef fixtureDef;
fixtureDef.shape = &groundBox;
pBody->CreateFixture(&fixtureDef);
//fixtureDef.density = 10;

pBody->SetUserData((void*)++g.m_actorid);

g.m_bodies.push_back(pBody);

if(dynamic)
{
//   pBody->SetAngularVelocity(0.5f);
}

return g.m_actorid;
}


and I create the boxes in C# like so:

m_worldid = CreateWorld(ToB2(new Vector2(0, -1.8f)));

m_boxID1 = CreateBox(ToB2(new Vector2(50, 50)), ToB2(new Vector2(-51,300)), true, m_worldid); m_boxID2 = CreateBox(ToB2(new Vector2(50, 50)), ToB2(new Vector2(0,0)), false, m_worldid);

Using the box ids I grab positions and rotations from the C++ code (and the get functions take into account that I've /= 100 the dimensions), it all works fine on that front, code here for those interested:

extern "C"
ActorTransform BodyTransform(int bodyid, int worldid)
{
World &g = GetWorld(worldid);

for(int i = 0; i < g.m_bodies.size(); i++)
{
if( (int)g.m_bodies[i]->GetUserData() == bodyid)
{
ActorTransform c;
c.Position = g.m_bodies[i]->GetPosition();
c.Rotation = g.m_bodies[i]->GetAngle();
c.Position *= 100.0f;

return c;
}
}
}


Another interesting thing to note is if I set an angular velocity on the box it actually is physically represented on screen and it can cause the box to fall off, setting rotatens on bodes also seems to work.

Actually continuing on from setting angular velocities. I found that if I set an angular velocity just once the velocity doesn't go away, even after it lands on the static box it continues to rotate as if it were a motor or something. I'm guessing this has something to do with my core problem since bodies aren't meant to maintain an angular velocity that was set on them just once..

so any ideas?

• You say you have some static bodies, but CreateBox doesn't seem to ever create them - is this really the code you're using? – user744 Aug 14 '11 at 11:36
• oooh, is there a difference between kinematic bodies and static bodies (I use b2_kinematic out of a sense of familiarity), I just changed b2_kinematic to b2_static to clarify that point – meds Aug 14 '11 at 11:39
• There is a difference between them but it's not that relevant; I just wanted to make sure you were showing us the code you were actually using, because there is a fixedRotation flag on bodies, and you might have been setting that in the real code but not the question code. – user744 Aug 14 '11 at 14:58
• ah no, didn't even know about the fixedRotation flag, thanks for letting me know! haha – meds Aug 14 '11 at 16:09

Ok fixed it thanks to someone from the box2d forums correct an obvious mistake.

Change this:

pBody->CreateFixture(&fixtureDef);
//fixtureDef.density = 10;


into this:

fixtureDef.density = 10;
pBody->CreateFixture(&fixtureDef);


Done.