Body rotating from top left but not from center

Discuss issues specific the Java port of Box2D
Liwaa
Posts: 1
Joined: Wed Oct 11, 2017 1:40 pm

Body rotating from top left but not from center

Postby Liwaa » Wed Oct 11, 2017 1:45 pm

So im using LibGDX with box2D, and problems I'm facing is the body rotating from the top left, while i want it to rotate from the center.
Im using an application called physics body editor to set the fixtures for bodies, and heres how everything is loaded:
Code for attaching fixtures using physics body editor:

Code: Select all

 
public class BodyRectangle extends Rectangle{

public Body body;
    public BodyRectangle(float x, float y, float width, float height) {
        super(x, y, width, height);

    }


    // give fixtures to the body using the physics bodyEditorLoader code
   // i believe fixes should be done here
    protected BodyRectangle setWithBody(boolean value, BodyDef.BodyType type, String name, FileHandle file, Object userData){
        BodyDef def = new BodyDef();
        def.position.set(x,y);
        def.type =type;

        Body body = world.createBody(def);
        FixtureDef fdef = new FixtureDef();

       // PolygonShape shape = new PolygonShape();
        //shape.setAsBox(width/2, height/2, new Vector2(width/2,height/2),0);
        BodyEditorLoader loader = new BodyEditorLoader(file);
        loader.attachFixture(body, name,fdef,width,height, userData);
        MassData data = body.getMassData();
        data.center.set(width/2, height/2);

        body.setMassData(data);

        this.body = body;

        return this;

    }
}


// physics body editor loader code:
public class BodyEditorLoader {

   /**
    * Internet library
    */

   private final Model model;
   private final List<Vector2> vectorPool = new ArrayList<Vector2>();
   private final PolygonShape polygonShape = new PolygonShape();
   private final CircleShape circleShape = new CircleShape();
   private final Vector2 vec = new Vector2();



   public BodyEditorLoader(FileHandle file) {
      if (file == null) throw new NullPointerException("file is null");
      model = readJson(file.readString());
   }

   public BodyEditorLoader(String str) {
      if (str == null) throw new NullPointerException("str is null");
      model = readJson(str);
   }

   // -------------------------------------------------------------------------
   // Public API
   // -------------------------------------------------------------------------

   /**
    * Creates and applies the fixtures defined in the editor. The name
    * parameter is used to retrieve the right fixture from the loaded file.
    * <br/><br/>
    *
    * The body reference point (the red cross in the tool) is by default
    * located at the bottom left corner of the image. This reference point
    * will be put right over the BodyDef position point. Therefore, you should
    * place this reference point carefully to let you place your body in your
    * world easily with its BodyDef.position point. Note that to draw an image
    * at the position of your body, you will need to know this reference point
    * (see {@link #getOrigin(String, float)}.
    * <br/><br/>
    *
    * Also, saved shapes are normalized. As shown in the tool, the width of
    * the image is considered to be always 1 meter. Thus, you need to provide
    * a scale factor so the polygons get resized according to your needs (not
    * every body is 1 meter large in your game, I guess).
    *
    * @param body The Box2d body you want to attach the fixture to.
    * @param name The name of the fixture you want to load.
    * @param fd The fixture parameters to apply to the created body fixture.
    * @param scaleX The desired scale of the body. The default width is 1.
    *  @param scaleY The desired scale of the body. The default width is 1.
    */
   public void attachFixture(Body body, String name, FixtureDef fd, float scaleX, float scaleY, Object userData) {
      RigidBodyModel rbModel = model.rigidBodies.get(name);
      if (rbModel == null) throw new RuntimeException("Name '" + name + "' was not found.");

      Vector2 origin = vec.set(rbModel.origin).scl(scaleX,scaleY);

      for (int i=0, n=rbModel.polygons.size(); i<n; i++) {
         PolygonModel polygon = rbModel.polygons.get(i);

         Vector2[] vertices = polygon.buffer;

         for (int ii=0, nn=vertices.length; ii<nn; ii++) {
            vertices[ii] = newVec().set(polygon.vertices.get(ii)).scl(scaleX,scaleY);
            vertices[ii].sub(origin);
         }

         polygonShape.set(vertices);

         fd.shape = polygonShape;
         body.createFixture(fd).setUserData(userData);

         for (int ii=0, nn=vertices.length; ii<nn; ii++) {
            free(vertices[ii]);
         }
      }

      for (int i=0, n=rbModel.circles.size(); i<n; i++) {
         CircleModel circle = rbModel.circles.get(i);
         Vector2 center = newVec().set(circle.center).scl(scaleX,scaleY);
         float radius = circle.radius * scaleX;

         circleShape.setPosition(center);
         circleShape.setRadius(radius);
         fd.shape = circleShape;
         body.createFixture(fd).setUserData(userData);

         free(center);
      }
   }

   /**
    * Gets the image path attached to the given name.
    */
   public String getImagePath(String name) {
      RigidBodyModel rbModel = model.rigidBodies.get(name);
      if (rbModel == null) throw new RuntimeException("Name '" + name + "' was not found.");

      return rbModel.imagePath;
   }

   /**
    * Gets the origin point attached to the given name. Since the point is
    * normalized in [0,1] coordinates, it needs to be scaled to your body
    * size. Warning: this method returns the same Vector2 object each time, so
    * copy it if you need it for later use.
    */
   public Vector2 getOrigin(String name, float scale) {
      RigidBodyModel rbModel = model.rigidBodies.get(name);
      if (rbModel == null) throw new RuntimeException("Name '" + name + "' was not found.");

      return vec.set(rbModel.origin).scl(scale);
   }

   /**
    * <b>For advanced users only.</b> Lets you access the internal model of
    * this loader and modify it. Be aware that any modification is permanent
    * and that you should really know what you are doing.
    */
   public Model getInternalModel() {
      return model;
   }

   // -------------------------------------------------------------------------
   // Json Models
   // -------------------------------------------------------------------------

   public static class Model {
      public final Map<String, RigidBodyModel> rigidBodies = new HashMap<String, RigidBodyModel>();
   }

   public static class RigidBodyModel {
      public String name;
      public String imagePath;
      public final Vector2 origin = new Vector2();
      public final List<PolygonModel> polygons = new ArrayList<PolygonModel>();
      public final List<CircleModel> circles = new ArrayList<CircleModel>();
   }

   public static class PolygonModel {
      public final List<Vector2> vertices = new ArrayList<Vector2>();
      private Vector2[] buffer; // used to avoid allocation in attachFixture()
   }

   public static class CircleModel {
      public final Vector2 center = new Vector2();
      public float radius;
   }

   // -------------------------------------------------------------------------
   // Json reading process
   // -------------------------------------------------------------------------

   private Model readJson(String str) {
      Model m = new Model();

      JsonValue map = new JsonReader().parse(str);

      JsonValue bodyElem = map.getChild("rigidBodies");
      for (; bodyElem != null; bodyElem = bodyElem.next()) {
         RigidBodyModel rbModel = readRigidBody(bodyElem);
         m.rigidBodies.put(rbModel.name, rbModel);
      }

      return m;
   }

   private RigidBodyModel readRigidBody(JsonValue bodyElem) {
      RigidBodyModel rbModel = new RigidBodyModel();
      rbModel.name = bodyElem.getString("name");
      rbModel.imagePath = bodyElem.getString("imagePath");

      JsonValue originElem = bodyElem.get("origin");
      rbModel.origin.x = originElem.getFloat("x");
      rbModel.origin.y = originElem.getFloat("y");

      // polygons
      JsonValue polygonsElem = bodyElem.getChild("polygons");   
      for (; polygonsElem != null ;polygonsElem = polygonsElem.next()){

         PolygonModel polygon = new PolygonModel();
         rbModel.polygons.add(polygon);

         JsonValue vertexElem = polygonsElem.child();
         for (; vertexElem != null; vertexElem = vertexElem.next()) {
            float x = vertexElem.getFloat("x");
            float y = vertexElem.getFloat("y");
            polygon.vertices.add(new Vector2(x, y));
         }

         polygon.buffer = new Vector2[polygon.vertices.size()];

      }

      // circles
      JsonValue circleElem = bodyElem.getChild("circles");

      for (; circleElem != null; circleElem = circleElem.next()) {
         CircleModel circle = new CircleModel();
         rbModel.circles.add(circle);

         circle.center.x = circleElem.getFloat("cx");
         circle.center.y = circleElem.getFloat("cy");
         circle.radius = circleElem.getFloat("r");
      }

      return rbModel;
   }

   // -------------------------------------------------------------------------
   // Helpers
   // -------------------------------------------------------------------------

   private Vector2 newVec() {
      return vectorPool.isEmpty() ? new Vector2() : vectorPool.remove(0);
   }

   private void free(Vector2 v) {
      vectorPool.add(v);
   }

Code for drawing rotated Sprite:

Code: Select all

    public void drawBitMap(Bitmap bit, float x, float y, float width, float height, float rotation){
    Sprite sprt = null;
    if (!sprts.containsKey(bit)) {
         sprt = new Sprite(bit.texture);
        sprts.put(bit, sprt);
    }else{
        sprt = sprts.get(bit);
    }
    sprt.setOrigin(width/2,height/2);
    sprt.setRotation(rotation);
    sprt.setPosition(x,y);

    sprt.setSize(width,height);
    sprt.draw(this);
}


code for rotating body:

Code: Select all

body.setTransform(x, y, rotation * MathUtils.degreesToRadians);


Images of what is happening:
Gb7As.png
Gb7As.png (17.71 KiB) Viewed 13 times

Return to “Java”



Who is online

Users browsing this forum: No registered users and 2 guests