Map optimization

Hello,



I'm trying to create a map constituted of nxn (n= 32, 64 or 128) blocks (1x2x1, each block constituted of 6 quads). At the beginning in my map, all the blocks are just stuck to each other, so i set the cullstate of each block such that only the top quad of each block is displayed. By just doing it like this, i'm at 7 fps when i move the camera to the top of the map (for displaying 32x32 = 1024 quads), would anyone have any idea of how to improve this (I already started to use sharedmesh but still …) ? quadtree ? mesh locking ? change the cullstate ?



Thanks,

Adrien



import com.jme.app.SimpleGame;
import com.jme.system.DisplaySystem;
import com.jme.bounding.BoundingBox;
import com.jme.scene.shape.Box;
import com.jme.scene.shape.Quad;
import com.jme.math.FastMath;
import com.jme.math.Matrix3f;

public class MyMap extends SimpleGame{
   
   public static void main(String[] args){
      
   MyMap app = new MyMap();
   app.setDialogBehaviour(SimpleGame.ALWAYS_SHOW_PROPS_DIALOG);
   app.start();
}

   
   protected void update(){
      
   }
   
   
protected void simpleInitGame(){
      
      int lambda = 20;
      int n = 32;
      //left = (-1,0,0) right = (1,0,0) front = (0,0,-1) back = (0,0,1) (front, right, back and left in this order)
      
      
      
      int[][] mapPicture = new int[n][n];
      
      
      Quad myTop =  new Quad("basic top",1*lambda, 1*lambda);
      
      myTop.setLocalRotation(new Matrix3f(1.0f,0f,0f,0f,0f,-1.0f,0f,1.0f,0f));
      myTop.setLocalTranslation(new Vector3f(0,2*lambda,0));

      
      Quad myLeft = new Quad("dirt left",1*lambda,4*lambda);
      
      myLeft.setLocalRotation(new Matrix3f(0,0,1.0f,0,1.0f,0,-1.0f,0,0));
      myLeft.setLocalTranslation(new Vector3f(-0.5f*lambda,0,0));
      
      
      Quad myRight = new Quad("dirt right",1*lambda,4*lambda);
      myRight.setLocalRotation(new Matrix3f(0,0,-1.0f,0,1.0f,0,1.0f,0,0));
      myRight.setLocalTranslation(new Vector3f(0.5f*lambda,0,0));
      
      
      Quad myFront = new Quad("dirt front",1*lambda,4*lambda);
      myFront.setLocalTranslation(new Vector3f(0,0,-0.5f*lambda));
      
      
      Quad myBack = new Quad("dirt back",1*lambda,4*lambda);
      myBack.setLocalRotation(new Matrix3f(-1.0f,0,0,0,1.0f,0,0,0,-1.0f));
      myBack.setLocalTranslation(new Vector3f(0,0,0.5f*lambda));
      
      
      Quad myFloor = new Quad("dirt floor",1*lambda,1*lambda);
      myFloor.setLocalRotation(new Matrix3f(1.0f,0f,0f,0f,0f,-1.0f,0f,1.0f,0f));
      
      CullState cs = display.getRenderer().createCullState();
      cs.setCullMode(CullState.CS_FRONT);
      
      rootNode.setRenderState(cs);
      
      // map initiation
        for (int i = 0; i<n;i++){
           for (int j=0;j<n;j++){
              mapPicture[i][j] = 1;
           }
        }
       
        for (int i = 1;i<n-1;i++){
           mapPicture[i][(int)(n/2)] = 2;
           mapPicture[(int)(n/2)][i] = 3;
        }
       
           int testVariable;
           
         SharedMesh[][] myTops = new SharedMesh[n][n];
         SharedMesh[][][] mySides = new SharedMesh[n][n][4];
         SharedMesh[][] myBottoms = new SharedMesh[n][n];
         
         Node[][] mapNodes = new Node[n][n];
         Node myDungeon = new Node("my dungeon map node");
         
         for (int i=0;i<n;i++){
            for (int j=0;j<n;j++){
               myTops[i][j] = new SharedMesh("top i:" + i +" , j:" +j,myTop);
               myTops[i][j].setLocalTranslation(new Vector3f(i*lambda,0,j*lambda));
               myTops[i][j].setCullMode(SceneElement.CULL_DYNAMIC);
               
               myBottoms[i][j] = new SharedMesh("floor i:" + i +" , j:" +j,myFloor);
               myBottoms[i][j].setLocalTranslation(new Vector3f(i*lambda,0,j*lambda));
               myBottoms[i][j].setCullMode(SceneElement.CULL_ALWAYS);
               
               mySides[i][j][0] = new SharedMesh("front i:" + i +" , j:" +j,myFront);
               mySides[i][j][0].setLocalTranslation(new Vector3f(i*lambda,0,j*lambda));
               mySides[i][j][0].setCullMode(SceneElement.CULL_ALWAYS);
               
               mySides[i][j][1] = new SharedMesh("right i:" + i +" , j:" +j,myRight);
               mySides[i][j][1].setLocalTranslation(new Vector3f(i*lambda,0,j*lambda));
               mySides[i][j][1].setCullMode(SceneElement.CULL_ALWAYS);
               
               mySides[i][j][2] = new SharedMesh("back i:" + i +" , j:" +j,myBack);
               mySides[i][j][2].setLocalTranslation(new Vector3f(i*lambda,0,j*lambda));
               mySides[i][j][2].setCullMode(SceneElement.CULL_ALWAYS);
               
               mySides[i][j][3] = new SharedMesh("left i:" + i +" , j:" +j,myLeft);
               mySides[i][j][3].setLocalTranslation(new Vector3f(i*lambda,0,j*lambda));
               mySides[i][j][3].setCullMode(SceneElement.CULL_ALWAYS);
               
               mapNodes[i][j] = new Node("block i:" +i + " ,j: "+j);
               mapNodes[i][j].attachChild(myTops[i][j]);
               mapNodes[i][j].attachChild(myBottoms[i][j]);
               mapNodes[i][j].attachChild(mySides[i][j][0]);
               mapNodes[i][j].attachChild(mySides[i][j][1]);
               mapNodes[i][j].attachChild(mySides[i][j][2]);
               mapNodes[i][j].attachChild(mySides[i][j][3]);
               
               myDungeon.attachChild(mapNodes[i][j]);
            }
         }
      
         rootNode.attachChild(myDungeon);
         }
}


a) don't use quads. use a few triangle batches.

a2) try to use triangle strips

b) use diaplay lists (lock() your root node) or vbos



b) is really easy and should give a big speed boost. my prototype dungeon was made of quads like your map, and it was a huge difference when i locked it.