I am writing custom voxel engine in Java with JME3, but it is very slow, for simplicity I am rendering cubes instead of faces, also border detection messes up output mesh (doesn't draw cubes on chunk edges).I would be very thankful if someone with more skill looked into it.I have included all the code so you won't miss anything.You could have a look at CubicalMeshificator and improve on it, lets say by making only necessary faces not whole cubes.You can find rest of the code here:http://pastebin.com/7S90L1BdCubicalMeshificator (extracts mesh from voxel data)public class CubicalMeshificator {    private static LinkedList<Vector3f> verticesPosition = new LinkedList<Vector3f>();    private static LinkedList<Vector3f> verticesNormal = new LinkedList<Vector3f>();    private static LinkedList<Vector2f> verticesUV = new LinkedList<Vector2f>();    private static LinkedList<Integer> indices = new LinkedList<Integer>();    public static Mesh createMesh(Voxel [][][] voxels, Vector3f size, float voxelSize) {        for(int x = 0; x < size.x; x++) {            for(int y = 0; y < size.y; y++) {                for(int z = 0; z < size.z; z++) {                    if(x-1 >= 0 && x+1 < size.x &&                       y-1 >= 0 && y+1 < size.y &&                       z-1 >= 0 && z+1 < size.z)                    if(voxels[x][y][z].getId() != EVoxel.Air &&                        (voxels[x+1][y][z].getId() == EVoxel.Air ||                        voxels[x-1][y][z].getId() == EVoxel.Air ||                        voxels[x][y][z+1].getId() == EVoxel.Air ||                        voxels[x][y][z-1].getId() == EVoxel.Air ||                        voxels[x][y+1][z].getId() == EVoxel.Air ||                        voxels[x][y-1][z].getId() == EVoxel.Air) ) {                        verticesPosition.add(new Vector3f(x*voxelSize, y*voxelSize, z*voxelSize));                        verticesPosition.add(new Vector3f(x*voxelSize+voxelSize, y*voxelSize, z*voxelSize));                        verticesPosition.add(new Vector3f(x*voxelSize, y*voxelSize+voxelSize, z*voxelSize));                        verticesPosition.add(new Vector3f(x*voxelSize+voxelSize, y*voxelSize+voxelSize, z*voxelSize));                        verticesPosition.add(new Vector3f(x*voxelSize, y*voxelSize, z*voxelSize+voxelSize));                        verticesPosition.add(new Vector3f(x*voxelSize+voxelSize, y*voxelSize, z*voxelSize+voxelSize));                        verticesPosition.add(new Vector3f(x*voxelSize, y*voxelSize+voxelSize, z*voxelSize+voxelSize));                        verticesPosition.add(new Vector3f(x*voxelSize+voxelSize, y*voxelSize+voxelSize, z*voxelSize+voxelSize));                       indices.add(verticesPosition.size() + 3);                       indices.add(verticesPosition.size() + 1);                       indices.add(verticesPosition.size() + 0);                       indices.add(verticesPosition.size() + 0);                       indices.add(verticesPosition.size() + 2);                       indices.add(verticesPosition.size() + 3);                       indices.add(verticesPosition.size() + 7);                       indices.add(verticesPosition.size() + 5);                       indices.add(verticesPosition.size() + 1);                       indices.add(verticesPosition.size() + 1);                       indices.add(verticesPosition.size() + 3);                       indices.add(verticesPosition.size() + 7);                       indices.add(verticesPosition.size() + 6);                       indices.add(verticesPosition.size() + 4);                       indices.add(verticesPosition.size() + 5);                       indices.add(verticesPosition.size() + 5);                       indices.add(verticesPosition.size() + 7);                       indices.add(verticesPosition.size() + 6);                       indices.add(verticesPosition.size() + 2);                       indices.add(verticesPosition.size() + 0);                       indices.add(verticesPosition.size() + 4);                       indices.add(verticesPosition.size() + 4);                       indices.add(verticesPosition.size() + 6);                       indices.add(verticesPosition.size() + 2);                       indices.add(verticesPosition.size() + 7);                       indices.add(verticesPosition.size() + 3);                       indices.add(verticesPosition.size() + 2);                       indices.add(verticesPosition.size() + 2);                       indices.add(verticesPosition.size() + 6);                       indices.add(verticesPosition.size() + 7);                       indices.add(verticesPosition.size() + 1);                       indices.add(verticesPosition.size() + 5);                       indices.add(verticesPosition.size() + 4);                       indices.add(verticesPosition.size() + 4);                       indices.add(verticesPosition.size() + 0);                       indices.add(verticesPosition.size() + 1);                    }                }            }        }        Mesh mesh = new Mesh();        mesh.setBuffer(VertexBuffer.Type.Position, 3, BufferUtils.createFloatBuffer(verticesPosition.toArray(new Vector3f[0])));        mesh.setBuffer(VertexBuffer.Type.Normal, 3, BufferUtils.createFloatBuffer(verticesNormal.toArray(new Vector3f[0])));        mesh.setBuffer(VertexBuffer.Type.TexCoord, 2, BufferUtils.createFloatBuffer(verticesUV.toArray(new Vector2f[0])));        mesh.setBuffer(VertexBuffer.Type.Index, 3, listToBuffer(indices));        mesh.scaleTextureCoordinates(new Vector2f(5, 5));        mesh.updateBound();        return mesh;    }    public static IntBuffer listToBuffer(List<Integer> list)    {        IntBuffer buff = BufferUtils.createIntBuffer(list.size());        buff.clear();        for (Integer e : list) {            buff.put(e.intValue());        }        buff.flip();        return buff;    }}
Voxel Engine optimization
java;graphics