How to use Box2D allocator?

513 views Asked by At

There are two questions here. First if I need to create b2BlockAllocator before Clone and then delete(where?) after clone? Xcode profiling instrument doesn't show C++ leaks...

b2FixtureDef fixd = fix->fixture;
const b2Shape *shape = fixd.shape;
if(shape->GetType()== b2Shape::e_polygon && flip)
{
    b2PolygonShape* ps = (b2PolygonShape*)shape->Clone(new b2BlockAllocator());
    for(int i=0;i<ps->m_vertexCount;i++)
    {
        ps->m_vertices[i].x *= -1;
        ps->m_vertices[i].y *= -1;
    }

    ps->Set(&ps->m_vertices[0], ps->m_vertexCount);
    body->CreateFixture(ps, 1.0f);
...

In this code I take cached shape object, clone it, modify vertices, set to calculate normals and assigning it object to body. Question - is this legal?

Update:

-(void) addFixturesToBody:(b2Body*)body forShapeName:(NSString*)shapeName flip:(BOOL)flip
{
    BodyDef *so = [shapeObjects_ objectForKey:shapeName];
    assert(so);

    FixtureDef *fix = so->fixtures;
    while(fix)
    {
        b2FixtureDef fixd = fix->fixture;
        const b2Shape *shape = fixd.shape;
        if(shape->GetType()== b2Shape::e_polygon && flip)
        {
            b2BlockAllocator allocator;
            b2PolygonShape* ps = (b2PolygonShape*)shape->Clone(&allocator);
            for(int i=0;i<ps->m_vertexCount;i++)
            {
                ps->m_vertices[i].x *= -1;
                ps->m_vertices[i].y *= -1;
            }

            ps->Set(&ps->m_vertices[0], ps->m_vertexCount);
            body->CreateFixture(ps, 1.0f);
        }
        else
        {
            NSLog(@"noflip...%@", shapeName);
            body->CreateFixture(&fix->fixture);
        }
        fix = fix->next;
    }
}
2

There are 2 answers

0
Bill Kotsias On BEST ANSWER

I reply 4 years late while trying to find a similar answer. It seems few people have gone the extra mile with Box2D.

So, you are definitely leaking since new b2BlockAllocator doesn't get deleted anywhere, neither by you nor by the Clone function.

Just create a local b2BlockAllocator so that it will be destroyed when out-of-scope. And that's it.

    b2BlockAllocator cloneHelper;
    b2PolygonShape* ps = (b2PolygonShape*)shape->Clone(&cloneHelper);
0
Louis Langholtz On

I wouldn't use the Box2D allocator because I wouldn't be using the b2Shape::Clone method. Not directly. Instead, I'd do the following:

  1. copy the vertices of the polygon shape to a local array,
  2. modify those copies,
  3. instantiate a b2PolygonShape,
  4. invoke Set on the newly instantiated b2PolygonShape to assign it my modified vertices,
  5. create a new fixture using my assigned b2PolygonShape on the original body by calling the body's b2Body::CreateFixture method, and
  6. call the body's b2Body::DestroyFixture method to get rid of the original fixture.

The b2BlockAllocator class can be instantiated and used to dynamically allocate memory that in turn can be used within the lifetime of the b2BlockAllocator instance, but that'd be more overhead than necessary for what you're trying to do.