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?
CreateBox
doesn't seem to ever create them - is this really the code you're using? \$\endgroup\$fixedRotation
flag on bodies, and you might have been setting that in the real code but not the question code. \$\endgroup\$