Let me first say that Box2D is great. Thanks very much to all the contributors.
In my game the player controls a ball that can grow and shrink. I implemented this scaling by repeatedly deleting and recreating the b2Body every frame at the new size. So, over the course of say 30 frames, the ball will appear to scale up. But from Box2D's perspective it is actually being deleted and recreated. In order to keep the ball moving and rotating while it is being scaled, I store the old angle, position, and velocity, before deleting the b2Body and then set the new b2Body to those values.
This generally works very well, and it used to work perfectly (when I was using r32). However, I'm having a bit of a problem now (latest revision). If the ball is touching another body while scaling, its position and rotation freeze. The AngularVelocity and LinearVelocity have a value you in them, but the body behaves as if they are 0. I don't know enough about Box2D to speculate as to what the problem might be.
I created a Test (see below) that shows my problem in action. It creates a circle and sends it off moving to the right. Then, every frame, it deletes and creates a new circle, growing it a little bit at a time. The circle should move quickly off to the right, but instead it just sits there. Set a breakpoint in the Step and you'll see that LinearVelocity stays large. Notably, if I create a box instead of a circle the problem doesn't occur.
Any ideas?
Cheers,
James
Code:
#ifndef SCALE_SLIDE_H
#define SCALE_SLIDE_H
class ScaleSlide : public Test
{
public:
b2Body* tempBody ;
float scalingRadius ;
virtual void Step(Settings* settings)
{
Test::Step( settings ) ;
float32 oldAngle = tempBody->GetAngle( ) ;
float32 oldAngularVelocity = tempBody->GetAngularVelocity( ) ;
b2Vec2 oldPos = tempBody->GetPosition( ) ;
b2Vec2 oldVelocity = tempBody->GetLinearVelocity( ) ;
m_world->DestroyBody( tempBody ) ;
scalingRadius += 0.01f ;
b2CircleShape shape ;
shape.m_radius = scalingRadius ;
//b2PolygonShape shape;
//shape.SetAsBox(scalingRadius, scalingRadius);
b2BodyDef bd;
bd.type = b2_dynamicBody;
tempBody = m_world->CreateBody(&bd);
tempBody->CreateFixture(&shape, 5.0f);
tempBody->SetLinearVelocity( oldVelocity ) ;
tempBody->SetAngularVelocity( oldAngularVelocity ) ;
tempBody->SetTransform( oldPos, oldAngle ) ;
}
ScaleSlide()
{
{
b2BodyDef bd;
b2Body* ground = m_world->CreateBody(&bd);
b2PolygonShape shape;
shape.SetAsEdge(b2Vec2(-40.0f, 0.0f), b2Vec2(40.0f, 0.0f));
ground->CreateFixture(&shape, 0.0f);
}
scalingRadius = 1.0f ;
b2CircleShape shape ;
shape.m_radius = scalingRadius ;
//b2PolygonShape shape;
//shape.SetAsBox(scalingRadius, scalingRadius);
b2Vec2 pos(-7.0f, 0.75f);
b2BodyDef bd;
bd.type = b2_dynamicBody;
bd.position = pos;
tempBody = m_world->CreateBody(&bd);
tempBody->CreateFixture(&shape, 5.0f);
tempBody->SetLinearVelocity( b2Vec2( 100.0, 0.0 ) ) ;
}
static Test* Create()
{
return new ScaleSlide;
}
};
#endif