示例#1
0
void generateMesh(int width, int length, int height, vector <vector <vector<Chamber> > > cells) { //note that this is lwh of actual cells (including walls)
  Mesh maze;
  srand(time(NULL));
  maze.request_face_normals();
  maze.request_vertex_normals();
  maze.request_vertex_texcoords2D();
  //maze.add_property(v_index);
  //GENERATE MAIN VERTICES THAT WILL ANCHOR THE WALLS
  Mesh::VertexHandle mainVert[length+1][height+1][width+1];
  for (int i = 0; i <= height; i++){
    for (int j = 0; j <= width; j++){
      for (int k = 0; k <= length; k++){
        double distortx = (double)(rand() % maxDistort)/(1.5*maxDistort/tileSize);
        double distorty = (double)(rand() % maxDistort)/(1.5*maxDistort/tileSize);
        double distortz = (double)(rand() % maxDistort)/(1.5*maxDistort/tileSize);
        if (k != length-1 && (k%2==1 || k == 0)) distortx = -distortx;
        if (j != width-1 && (j%2==1 || j == 0)) distortz = -distortz;
        if (i != height-1 && (i%2==1 || i == 0)) distorty = -distorty;
        Vec3f point(k * tileSize + distortx, i * tileSize + distorty, j * tileSize + distortz);
        mainVert[k][i][j] = maze.add_vertex(point);
        //maze.property(v_index, mainVert[k][i][j]) = i*height + j*width + k;
        //maze.set_texcoord2D(mainVert[k][i][j], Vec2f(0,0));
      }
    }
  }
  //LINK UP MESH
  vector<Mesh::VertexHandle> face_vhandles;
  for (int i = 0; i < height; i++){
    for (int j = 0; j < width; j++){
      for (int k = 0; k < length; k++){
        if (cells[k][i][j].isWall()){ //if it is a wall
          int type = cells[k][i][j].type();
          if (type == FC || type == YWALL){
            //bottom
            if (i == 0 || !cells[k][i-1][j].isWall() ){
              face_vhandles.clear();
              face_vhandles.push_back(mainVert[k][i][j]);
              face_vhandles.push_back(mainVert[k][i][j+1]);
              face_vhandles.push_back(mainVert[k+1][i][j+1]);
              maze.add_face(face_vhandles);
              face_vhandles.clear();
              face_vhandles.push_back(mainVert[k+1][i][j]);
              face_vhandles.push_back(mainVert[k][i][j]);
              face_vhandles.push_back(mainVert[k+1][i][j+1]);
              maze.add_face(face_vhandles);
              n_faces += 2;
            }
            //top
            if (i == height-1 || !cells[k][i+1][j].isWall()){
              face_vhandles.clear();
              face_vhandles.push_back(mainVert[k][i+1][j]);
              face_vhandles.push_back(mainVert[k+1][i+1][j+1]);
              face_vhandles.push_back(mainVert[k][i+1][j+1]);
              maze.add_face(face_vhandles);
              face_vhandles.clear();
              face_vhandles.push_back(mainVert[k][i+1][j]);
              face_vhandles.push_back(mainVert[k+1][i+1][j]);
              face_vhandles.push_back(mainVert[k+1][i+1][j+1]);
              maze.add_face(face_vhandles);
              n_faces += 2;
            }
          }
          if(type == FC || type == CORE || type == XWALL){
            //left
            if (k == 0 || !cells[k-1][i][j].isWall()){
              face_vhandles.clear();
              face_vhandles.push_back(mainVert[k][i][j]);
              face_vhandles.push_back(mainVert[k][i+1][j]);
              face_vhandles.push_back(mainVert[k][i+1][j+1]);
              maze.add_face(face_vhandles);
              face_vhandles.clear();
              face_vhandles.push_back(mainVert[k][i][j]);
              face_vhandles.push_back(mainVert[k][i+1][j+1]);
              face_vhandles.push_back(mainVert[k][i][j+1]);
              maze.add_face(face_vhandles);
              n_faces += 2;
            }
            //right
            if (k == length-1 || !cells[k+1][i][j].isWall()){
              face_vhandles.clear();
              face_vhandles.push_back(mainVert[k+1][i][j]);
              face_vhandles.push_back(mainVert[k+1][i+1][j+1]);
              face_vhandles.push_back(mainVert[k+1][i+1][j]);
              maze.add_face(face_vhandles);
              face_vhandles.clear();
              face_vhandles.push_back(mainVert[k+1][i][j]);
              face_vhandles.push_back(mainVert[k+1][i][j+1]);
              face_vhandles.push_back(mainVert[k+1][i+1][j+1]);
              maze.add_face(face_vhandles);
              n_faces += 2;
            }
          }
          if(type == FC || type == CORE || type == ZWALL){
            //close
            if (j == 0 || !cells[k][i][j-1].isWall()){
              face_vhandles.clear();
              face_vhandles.push_back(mainVert[k][i][j]);
              face_vhandles.push_back(mainVert[k+1][i+1][j]);
              face_vhandles.push_back(mainVert[k][i+1][j]);
              maze.add_face(face_vhandles);
              face_vhandles.clear();
              face_vhandles.push_back(mainVert[k][i][j]);
              face_vhandles.push_back(mainVert[k+1][i][j]);
              face_vhandles.push_back(mainVert[k+1][i+1][j]);
              maze.add_face(face_vhandles);
              n_faces += 2;
            }
            //far
            if (j == width-1 || !cells[k][i][j+1].isWall()){
              face_vhandles.clear();
              face_vhandles.push_back(mainVert[k][i][j+1]);
              face_vhandles.push_back(mainVert[k][i+1][j+1]);
              face_vhandles.push_back(mainVert[k+1][i+1][j+1]);
              maze.add_face(face_vhandles);
              face_vhandles.clear();
              face_vhandles.push_back(mainVert[k][i][j+1]);
              face_vhandles.push_back(mainVert[k+1][i+1][j+1]);
              face_vhandles.push_back(mainVert[k+1][i][j+1]);
              maze.add_face(face_vhandles);
              n_faces += 2;
            }
          }

        }
      }
    }
  }
  
  // subdivide
  Loop sDivide;
  sDivide.attach(maze);
  bool success = sDivide(3);
  sDivide.detach();
  maze.update_normals();

  double scale = max(max(length, width), height)*tileSize;
  for (Mesh::ConstVertexIter vIt = maze.vertices_begin(); vIt != maze.vertices_end(); ++vIt){
    Vec3f vert = maze.point(vIt);
    double effect = 0.5 * octave_noise_3d(6.0, .75, 2, vert[0]/scale, vert[1]/scale, vert[2]/scale);
    Vec3f shift(effect*maze.normal(vIt)[0], effect*maze.normal(vIt)[1], effect*maze.normal(vIt)[2]);
    maze.set_point(vIt, vert - shift);
    maze.set_texcoord2D(vIt, Vec2f(0,0));
  }
  maze.update_normals();

  //WRITE OBJ FILE
  IO::Options wopt;
  wopt += IO::Options::VertexNormal;
  wopt += IO::Options::VertexTexCoord;
  if (!OpenMesh::IO::write_mesh(maze, "maze.obj", wopt)) 
  {
    std::cerr << "write error\n";
    exit(1);
  }

}