Hello,
A while ago I threw together a LOD system based on quads being loaded in and out depending on the distance from them and the camera. The quads are created as needed rather than at start up. Recently as I have been using it more I have noticed it becomes very slow at times. I was wondering if I am doing something entirely wrong or if there was anything I can do to improve on it.
Here is the code that examines the list of quads and makes more if needed:
for(int i = 0; i<Quad.list.size(); i++){
Quad q = Quad.list.get(i);
Vector3f center = Quad.getCenter(q);
float width = q.width;
float distance = center.distance(cam.getLocation());
float view = (float) (2 * width);
// if children = true the quad has children being displayed on screen
//q.childs is the arraylist holding the quad's children
if(view >= distance && !q.children && q.width >= (max_size)){
if(q.childs != null){
if(q.parent != null && q.parent.childs.get(0).receiving){
Quad.list.remove(q.parent);
}
int size = verts.length;
q.children = true;
q.receiving = false;
q.childs.get(0).receiving = true;
q.childs.get(1).receiving = true;
q.childs.get(2).receiving = true;
q.childs.get(3).receiving = true;
Quad.list.addAll(q.childs);
int length = indices.length;
int[] indices2 = new int[length+4608];
System.arraycopy(indices, 0, indices2,0,length);
indices = null;
verts = null;
verts = (Quad.getVertices());
VertexBuffer vb = mesh.getBuffer(Type.Position);
vb.updateData(BufferUtils.createFloatBuffer(verts));
int n = length;
for(int u = size; u<verts.length; u+=4){
indices2[n++] = u;
indices2[n++] = u+1;
indices2[n++] = u+2;
indices2[n++] = u+2;
indices2[n++] = u+3;
indices2[n++] = u;
}
indices = indices2;
indices2 = null;
VertexBuffer ib = mesh.getBuffer(Type.Index);
ib.updateData(BufferUtils.createIntBuffer(indices));
}else{
if(q.parent != null && q.parent.childs.get(0).receiving){
Quad.list.remove(q.parent);
}
int size = verts.length;
Quad.split(q,q.index1,q.index2);
verts = (Quad.getVertices());
int length = indices.length;
int[] indices2 = new int[(verts.length/4)*6];
System.arraycopy(indices, 0, indices2,0,length);
indices = null;
VertexBuffer vb = mesh.getBuffer(Type.Position);
vb.updateData(BufferUtils.createFloatBuffer(verts));
int n = length;
for(int u = size; u<verts.length; u+=4){
indices2[n++] = u;
indices2[n++] = u+1;
indices2[n++] = u+2;
indices2[n++] = u+2;
indices2[n++] = u+3;
indices2[n++] = u;
}
indices = indices2;
indices2 = null;
VertexBuffer ib = mesh.getBuffer(Type.Index);
ib.updateData(BufferUtils.createIntBuffer(indices));
}
}
else if(view < distance && q.children){
q.childs.get(0).receiving = false;
q.childs.get(1).receiving = false;
q.childs.get(2).receiving = false;
q.childs.get(3).receiving = false;
Quad.list.removeAll(q.childs);
q.receiving = true;
q.children = false;
if(q.parent != null && q.parent.childs.get(0).receiving && q.parent.childs.get(1).receiving && q.parent.childs.get(2).receiving && q.parent.childs.get(3).receiving){
Quad.list.add(q.parent);
}
VertexBuffer vb = mesh.getBuffer(Type.Position);
verts = (Quad.getVertices());
vb.updateData(BufferUtils.createFloatBuffer(verts));
int newSize = (verts.length/4)*6;
int[] indices2 = new int[newSize];
System.arraycopy(indices, 0, indices2, 0, newSize);
indices = null;
indices = indices2;
VertexBuffer vi =(mesh.getBuffer(Type.Index));
vi.updateData(BufferUtils.createIntBuffer(indices));
}
}
The way in which I gather the vertices from the quads is shown as follows:
public static Vector3f[] getVertices(){
ArrayList<Vector3f> returning = new ArrayList<Vector3f>();
for(int i = 0; i<list.size(); i++){
Quad q = list.get(i);
if(q.receiving){
returning.addAll(q.leaves);
}
}
Vector3f[] r = new Vector3f[returning.size()];
returning.toArray(r);
returning.clear();
returning = null;
return r;
}
If a quad is "reveiving" then it's vertices are being drawn on screen. I think if any problems exist then this is the block of code in which they do.
Any help is appreciated, thanks.