在 Libgdx 中渲染复杂的物体

Rendering Complex Bodies in Libgdx

我正在尝试使用 ShapeRenderer 渲染我在开源工具中制作的物体。 通过简单地检索顶点并将它们返回给 ShapeRenderer,它似乎适用于像正方形这样的简单形状。然而,当涉及到具有大约 9 个多边形(我正在尝试渲染的那个)的复杂物体时,我已经尝试一个一个地渲染多边形,但看起来它一遍又一遍地给我相同的多边形,无论我如何初始化或遍历我的 Vector2[] 列表。我已经坚持了一段时间,任何见解都会有所帮助。 (我正在使用 BodyEditorLoader class 来获取顶点)

BodyEditorLoader Class 我从中获取顶点。 (来自开源库)

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()
    }

上面的代码不是完整的class(只是因为我认为它有很多行)如果你想在这里查看它:https://github.com/MovingBlocks/box2d-editor/tree/develop/loader-libgdx/src/aurelienribon/bodyeditor

我的结构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;

    }
}

最后我如何使用 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();
}

对于任何想做同样尝试的人,错误来自于我复制了错误的向量列表。而不是复制:

polygon.buffer

您必须复制

List<Vector2> vertices

位于多边形模型中。最后,通过向其中添加每个列表来创建各种列表的列表。

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