3
\$\begingroup\$

I've just written two new headers: one that integrates Box2D and SFML by a class called BodyRep which creates/ is a graphic representation of any body, and one that produces huge amounts of uniform shapes, as to reduce copy/pasting.

Things I'm worried about:

  • Performance: very important here considering this is based on a physics engine.
  • Memory-management: using the least amount of memory possible.
    • More specifically, the ShapeFactory constructor, as I think I might be creating another body rep object by accident (the extra body parameter, which needs to be added, makes things a bit more tricky).

SFboxML.h

#ifndef SFboxML_H
#define SFboxML_H

#include <Box2D.h>
#include <SFML\Graphics.hpp>
#include <SFML\System.hpp>
#include <vector>

#    define M_PI 3.14159265358979323846 

float ConvToRad(float Angle){return (Angle* M_PI)/ 180;}; 
float ConvToDeg(float Radian){return (Radian*180)/M_PI;};

float32 ConvToB2(float Angle){return -ConvToRad(Angle);};
float ConvToSFML(float Radian){return -ConvToDeg(Radian);};

namespace sb{

class BodyRep : public sf::Body
{
private:
    b2Body* m_b2Body;

public:

    BodyRep(b2Body* Body, sf::Color Color = sf::Color(255,255,255,255)): m_b2Body(Body){ //TODO: add other params like color
        //Iterate through all the fixtures
        for (b2Fixture* fixture = Body->GetFixtureList(); fixture; fixture = fixture->GetNext()){   

            signed short shapeType = fixture->GetType(); 
            sf::Shape TempShape;

            // Circle shape
             if(shapeType == b2Shape::e_circle){ 
                 b2CircleShape* circleShape = (b2CircleShape*)fixture->GetShape();
                 TempShape = sf::Shape::Circle(sf::Vector2f(0,0), circleShape->m_radius*30, Color); 
             }

            // Polygon Shape        
             else if(shapeType == b2Shape::e_polygon){  
                b2PolygonShape* polygonShape = (b2PolygonShape*)fixture->GetShape();
                for(unsigned short I=0; I<polygonShape->GetVertexCount(); I++){
                    TempShape.AddPoint(
                        polygonShape->GetVertex(I).x*30,
                        polygonShape->GetVertex(I).y*30);
                }
             }
        //Defaults
        TempShape.EnableFill(true);
        TempShape.SetColor(Color);
        AddShape(TempShape);
        }
    };

    void Draw(sf::RenderWindow& target){
        SetPosition(m_b2Body->GetPosition().x*30, m_b2Body->GetPosition().y*30);
        SetRotation(ConvToSFML(m_b2Body->GetAngle()));
        sf::Body::Draw(target);
    };

        //TODO: make other functions and redo everything once 
        //      i've made the SFML body class
};

}// namespace sb


// TODO: sync the sfml shape and box2d polygon's centers.e

#endif

ShapeFactory.h

#ifndef SHAPE_FACTORY_H
#define SHAPE_FACTORY_H

#include <Box2D.h>
#include <SFML\Graphics.hpp>
#include <SFML\System.hpp>
#include <vector>
#include <My\SFboxML.h>

namespace my{

class ShapeFactory 
{
protected:
    std::vector<b2Body*> Bodies;
    std::vector<sb::BodyRep*> GraphicReps;
    std::vector<b2FixtureDef> FixDefs;
    b2BodyDef BodyDef;
    b2World* World;
    unsigned int numb_bodies;

public:
    void Draw(sf::RenderWindow& target){
        for(unsigned int I=0; I< numb_bodies; I++)
            GraphicReps[I]->Draw(target);
    };

    void Create(unsigned int numbBods){
        for(unsigned int I=0; I< numbBods; I++){
            // Make another body in World.
            Bodies.push_back(World->CreateBody(&BodyDef));
            // Add the fixtures to the body.
            for(unsigned short i=0; i<FixDefs.size(); i++)
                Bodies[I]->CreateFixture(&FixDefs[i]);
            //Create Graphical rep.           TODO: add coloring/ other visual options
            GraphicReps.push_back(new sb::BodyRep(Bodies[I]));
            numb_bodies++;}
    };

//////////////////////////  Constructors    /////////////////////////////////////////////////////////////////////////////
    ShapeFactory(b2World& world, b2BodyDef& bodyDef, b2FixtureDef& fixtureDef, unsigned int numb){
        World= &world;
        BodyDef=bodyDef;
        FixDefs.push_back(fixtureDef); //TODO: make more than 1 fix possible
        numb_bodies=0;
        Create(numb);
    };

    ShapeFactory(b2Body* Body, unsigned int numb){
        // Set the world
        World= Body->GetWorld();
        // Make the body def
        BodyDef.active=             Body->IsActive();
        BodyDef.angle=              Body->GetAngle();
        BodyDef.angularDamping=     Body->GetAngularDamping();
        BodyDef.angularVelocity=    Body->GetAngularVelocity();
        BodyDef.awake=              Body->IsAwake();
        BodyDef.bullet=             Body->IsBullet();
        BodyDef.fixedRotation=      Body->IsFixedRotation();
        BodyDef.inertiaScale=       Body->GetInertia();
        BodyDef.linearDamping=      Body->GetLinearDamping();
        BodyDef.linearVelocity=     Body->GetLinearVelocity();
        BodyDef.position=           Body->GetPosition();
        BodyDef.type=               Body->GetType();
        BodyDef.userData=           Body->GetUserData();

        // Make the fixture defs
        b2FixtureDef FixtureDef;
        for (b2Fixture* fixture = Body->GetFixtureList(); fixture; fixture = fixture->GetNext()){
            FixtureDef.density =    fixture->GetDensity();
            FixtureDef.filter=      fixture->GetFilterData();
            FixtureDef.friction=    fixture->GetFriction();
            FixtureDef.isSensor=    fixture->IsSensor();
            FixtureDef.restitution= fixture->GetRestitution();
            FixtureDef.shape=       fixture->GetShape(); //TODO: make sure the specific shape vertexes pass in too
            FixtureDef.userData=    fixture->GetUserData();
            FixDefs.push_back(FixtureDef);}

        // Deal with the used Body 
        Bodies.push_back(Body);          
        GraphicReps.push_back(new sb::BodyRep(Bodies[0]));
        numb_bodies++;

        // Generate the Body in the world, add fixtures, make a graphical rep.
        numb_bodies=1;
        Create(numb);

        };
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

}; // ShapeFactory

}// namespace my

#endif
\$\endgroup\$
  • 1
    \$\begingroup\$ Can you please provide code that would use these headers as an example, or provide test cases for it. \$\endgroup\$ – pacmaninbw Oct 19 at 17:52