Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
127 views
in Technique[技术] by (71.8m points)

java - Rendering Complex Bodies in Libgdx

I am trying to render the bodies that I made in the open-source tool using ShapeRenderer. It seems to work for simple shapes like a square by simply retrieving the vertices and giving them back to the ShapeRenderer. However, when it comes to complex Bodies with about 9 polygons (the one I'm trying to render) I've tried rendering the polygons one by one, but it looks like it's giving me the same polygon over and over again, no matter how I initialize or go through my list of Vector2[]. I've been stuck on this for a while now, and any insight would help. (I'm using the BodyEditorLoader class to get the vertices)

BodyEditorLoader Class where I get my vertices from. (Gotten from open source library)

public class BodyEditorLoader {

    // Model
    private final Model model;

    // Reusable stuff
    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();
    //My stuff
    public Vector2[] shapeVertices;
    public ArrayList<Vector2[]> polygonModelList = new ArrayList<>();
    public List<PolygonModel> polygonModels = new ArrayList<>();

    // -------------------------------------------------------------------------
    // Ctors
    // -------------------------------------------------------------------------

    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 void attachFixture(Body body, String name, FixtureDef fd, float 
    scale,Object data) {
        RigidBodyModel rbModel = model.rigidBodies.get(name);
        polygonModels = rbModel.polygons;
        if (rbModel == null) throw new RuntimeException("Name '" + name + "' was not found.");

        Vector2 origin = vec.set(rbModel.origin).scl(scale);

        for (int i=0, n=rbModel.polygons.size(); i<n; i++) {
            PolygonModel polygon = rbModel.polygons.get(i);
            Vector2[] vertices = polygon.buffer;
            //Here is were i'm putting the new vertices into an array
            polygonModelList.add(vertices);
            for (int ii=0, nn=vertices.length; ii<nn; ii++) {
                vertices[ii] = newVec().set(polygon.vertices.get(ii)).scl(scale);
                vertices[ii].sub(origin);
            }

            polygonShape.set(vertices);

            shapeVertices = vertices;
            fd.shape = polygonShape;
            Fixture fixture =body.createFixture(fd);
            fixture.setUserData(data);
            fixture.getBody();
            for (int ii=0, nn=vertices.length; ii<nn; ii++) {
                free(vertices[ii]);
            }
        }
        System.out.println(rbModel.polygons.size());

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

            circleShape.setPosition(center);
            circleShape.setRadius(radius);
            fd.shape = circleShape;
            Fixture fixture = body.createFixture(fd);
            fixture.setUserData(data);

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

The code above is not the full class(just because i thought it had a lot of lines) if you'd like to check it out its here: https://github.com/MovingBlocks/box2d-editor/tree/develop/loader-libgdx/src/aurelienribon/bodyeditor

My Structure class

public class Structure {
    BodyDef bd;
    Body body;
    FixtureDef fd;
    float x;
    float y;
    Vector2[] originalShapeVertices;
    Vector2[] scaledShapeVertices;
    ArrayList<Vector2[]> polygonList = new ArrayList<>();
    List<BodyEditorLoader.PolygonModel> polygonModels = new ArrayList<>();
    
    public Structure(float x, float y,World world, BodyEditorLoader bodyEditorLoader)
    {
        this.x = x;
        this.y = y;

        bd = new BodyDef();
        bd.type = BodyDef.BodyType.StaticBody;
        bd.position.set(x,y);
        body = world.createBody(bd);
        body.setUserData(this);

        fd = new FixtureDef();
        fd.density = 1;
        fd.friction = 1;
        fd.restitution = 1;

        bodyEditorLoader.attachFixture(body,"Structure",fd,500f,this);

        //System.out.println(Arrays.toString(bodyEditorLoader.shapeVertices));

        polygonModels = bodyEditorLoader.polygonModels;
        initVerticesFromModel();

    }

    public void initVerticesFromModel()
    {
        for (BodyEditorLoader.PolygonModel model : polygonModels) {
            polygonList.add(model.buffer);
        }
    }

    public float[] getPolygonVectors(Vector2 [] vertices)
    {
        float[] copiedVertices = new float[vertices.length * 2];

        for (int i=0, j=0; i<copiedVertices.length; i+=2,j++)
        {
            copiedVertices[i] = vertices[j].x;
            copiedVertices[i+1] = vertices[j].y;

        }

        return copiedVertices;

    }



    public Vector2[] getScaledShapeVertices(Vector2[] originalShapeVertices)
    {
        Vector2[] scaledShapeVertices = new Vector2[originalShapeVertices.length];
        for (int i=0; i<scaledShapeVertices.length; i++)
        {
            Vector2 newVertex = new Vector2(originalShapeVertices[i].x+body.getPosition().x,originalShapeVertices[i].y+body.getPosition().y);
            scaledShapeVertices[i] = newVertex;

        }

        return scaledShapeVertices;

    }

    public Line2D.Float[] getBodySegments()
    {
        Vector2[] vertices = scaledShapeVertices;
        Line2D.Float[] segments = new Line2D.Float[vertices.length];

        for (int i =0; i<segments.length; i++)
        {
            int nextPoint = i+1;
            if (nextPoint >= segments.length)
            {
                nextPoint = segments.length-1;
                segments[i] = new Line2D.Float(vertices[nextPoint].x,vertices[nextPoint].y,vertices[0].x,vertices[0].y);
            }
            else {
                segments[i] = new Line2D.Float(vertices[i].x, vertices[i].y, vertices[nextPoint].x, vertices[nextPoint].y);
            }
        }

        return segments;

    }
}

Finally How I render it using ShapeRenderer

Structure demo = new Structure(200,100,world,structureLoader);
@public void render()
{
     shapeRenderer.setProjectionMatrix(camera.combined);
     shapeRenderer.begin(ShapeRenderer.ShapeType.Line);

     for(int i =0; i<9; i++) {
     float[]polygon = 
    demo.getPolygonVectors(demo.getScaledShapeVertices(demo.polygonList.get(i)));
     shapeRenderer.polygon(polygon);
     }

     shapeRenderer.end();
}
question from:https://stackoverflow.com/questions/65946881/rendering-complex-bodies-in-libgdx

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

For anyone wanting to do attempt the same, the error comes from me copying the wrong list of vectors. Instead of copying:

polygon.buffer

You have to copy the

List<Vector2> vertices

located in the PolygonModel. In the end, creating a list of lists of sorts, by adding each list to it.

List<List<Vector2>> copiedPolygons = new ArrayList<>();
for(PolygonModel polygon : rbModel.polygons)
  {
    copiedPolygons.add(polygon.vertices);
  }

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...