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