void CitySceneGenerator::generate(Scene* scene) { auto renderer = scene->renderer(); auto material = std::make_shared<PhongMaterial>(renderer); material->setShader(renderer->shaderManager()->getGlslProgram("phong")); PhongMaterialData materialData = { glm::vec4(0.0f, 0.1f, 0.0f, 1.0f), glm::vec4(0.8f, 0.3f, 0.1f, 1.0f), glm::vec4(0.3f, 0.3f, 0.3f, 1.0f), 5.0f }; material->properties()->setData(materialData); material->properties()->flushData(); auto mesh = std::make_shared<Mesh>(); mesh->setPrimitiveType(PrimitiveType::TriangleList); size_t buildingVerticesCount = sizeof(buildingVertices) / sizeof(*buildingVertices); std::vector<char> vertices(reinterpret_cast<const char*>(buildingVertices), reinterpret_cast<const char*>(buildingVertices) + sizeof(buildingVertices)); std::vector<VertexElement> layout = { VertexElement(3, VertexElementType::Float), VertexElement(3, VertexElementType::Float) }; mesh->loadVertices(vertices, buildingVerticesCount, layout); size_t buildingIndicesCount = sizeof(buildingIndices) / sizeof(*buildingIndices); std::vector<uint32_t> indices(reinterpret_cast<const unsigned*>(buildingIndices), reinterpret_cast<const unsigned*>(buildingIndices) + buildingIndicesCount); mesh->loadIndices(indices); size_t numBuildings = 1000; float citySize = 500.0f; float minBuildingSize = 10.0f; float maxBuildingSize = 60.0f; float minHeightToWidthRatio = 8.0f; float maxHeightToWidthRatio = 16.0f; std::uniform_real_distribution<float> angleDist(0.0f, 360.0f); std::uniform_real_distribution<float> positionDist(-citySize, citySize); std::uniform_real_distribution<float> canonicalDist; std::vector<std::shared_ptr<BaseSceneObject>> buildings; for (size_t i = 0; i < numBuildings; i++) { auto building = std::make_shared<Building>(mesh, material); // set random position glm::mat4 model = glm::translate(glm::mat4(1.0f), glm::vec3(positionDist(m_rng), positionDist(m_rng), 0.0f) ); // rotate around z with random angle model = glm::rotate(model, angleDist(m_rng), glm::vec3(0.0f, 0.0f, 1.0f)); glm::vec3 scale; // multiplying uniform distribution will generate beta distribution scale.x = canonicalDist(m_rng) * canonicalDist(m_rng) * canonicalDist(m_rng) * canonicalDist(m_rng) * (maxBuildingSize - minBuildingSize) + minBuildingSize; scale.y = scale.x; scale.z = canonicalDist(m_rng) * canonicalDist(m_rng) * canonicalDist(m_rng) * scale.x * (maxHeightToWidthRatio - minHeightToWidthRatio) + minHeightToWidthRatio; model = glm::scale(model, scale); building->setModelMatrix(model); building->calculateBBox(); buildings.push_back(building); } scene->setStaticGeometry(std::move(buildings)); }
int main(int argc,char *argv[]) { ////////////////////////////////////////////////////////////// //PROGRAM VARIBALES ////////////////////////////////////////////////////////////// char mapfile[FSIZE]="",distfile[FSIZE]="",type[2]=""; char ctype,coper='s'; int cx=0,cy=1; ////////////////////////////////////////////////////////////// //INITIALIZE ////////////////////////////////////////////////////////////// TITLE(stdout,'*',"COMPUTE A SCALAR MAP"); ////////////////////////////////////////////////////////////// //SET OPTIONS AND USAGE ////////////////////////////////////////////////////////////// SET_OPTIONS(":hvVm:d:t:o:x:y:"); SET_USAGE( "============================================================================\n" "Usage:\n" "\n" "\t./program -m <mapfile> [-d <distfile>] -t <type_dist> [-o <type_oper>]\n" "\t -x <direction_x> [-y <direction_y>]\n" /* Collapse the information in the <mapfile>. Collapsing a map means to produce a 2-D or a 1-D (<type_dist>: 1D or 2D) from a full 3-D map. What collapse do is to take a given direction in the grid and apply over all the cells in that direction an operation (<type_oper>: sum, average). You can indicate the directions that should be preserved (<direction_x> and/or <direction_y>). */ "\n" "=========================================================================\n" ); ////////////////////////////////////////////////////////////// //READ OPTIONS ////////////////////////////////////////////////////////////// while(ITEROPTIONS){ switch(OPTION){ case 'm': strcpy(mapfile,optarg); break; case 'd': strcpy(distfile,optarg); break; case 't': strcpy(type,optarg); break; case 'o': coper=optarg[0]; break; case 'x': cx=atoi(optarg); break; case 'y': cy=atoi(optarg); break; //======================================== //COMMON //======================================== case 'v': VERBOSITY=1; break; case 'V': VERBOSITY=2; break; //DETECT ERRORS OPTION_ERRORS; } } ////////////////////////////////////////////////////////////// //VALIDATE OPTIONS ////////////////////////////////////////////////////////////// if(isBlank(mapfile)){ fprintf(stderr,"Error: No mapfile was provided\n"); PRINT_USAGE; EXIT; } if(!fileExists(mapfile)){ fprintf(stderr,"Error: Mapfile '%s' does not exist\n",mapfile); PRINT_USAGE; EXIT; } if(isBlank(distfile)){ sprintf(distfile,"%s.dst",mapfile); } if(isBlank(type)){ strcpy(type,"1D"); } ctype=type[0]; if(ctype=='2'){ if(cx==cy){ fprintf(stderr,"Error: x(%d) and y(%d) cannot be equal\n",cx,cy,mapfile); PRINT_USAGE; EXIT; } }else{ cy=(cx+1)%3; } ////////////////////////////////////////////////////////////// //REPORT INPUT INFORMATION ////////////////////////////////////////////////////////////// if(VERBOSE(1)){ BAR(stdout,'O'); fprintf(stdout,"Map file: %s\n",mapfile); fprintf(stdout,"Distributuion file: %s\n",distfile); fprintf(stdout,"Type of distribution: %s\n",type); fprintf(stdout,"Type of operation: %c\n",coper); fprintf(stdout,"X column: %d\n",cx); if(ctype!='2') fprintf(stdout,"Y column: %d\n",cy); BAR(stdout,'O'); } ////////////////////////////////////////////////////////////// //PROGRAM ////////////////////////////////////////////////////////////// int i,j,k,n,p; char linea[LSIZE],ctmp[LSIZE]; int nx,ny,nz; real *fieldmap; real x,y,z; real C[3][MAXGRID]; int ix,iy,iz; int ndx,ndy,ndz; //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //READ MAP FILE //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% STPRINTF("Getting data from mapfile '%s'...\n",mapfile); file fm=fopen(mapfile,"r"); //Read header for(i=1;i<=6;i++) fgets(linea,sizeof linea,fm); //Get number of data points in the grid fgets(linea,sizeof linea,fm); sscanf(linea,"%s %d %d %d",ctmp,&nx,&ny,&nz); fieldmap=(real*)calloc(nx*ny*nz,sizeof(real)); //Read data points fgets(linea,sizeof linea,fm); n=0; for(k=0;k<nz;k++){ for(i=0;i<nx;i++){ for(j=0;j<ny;j++){ p=i+j*nx+k*nx*ny; fgets(linea,sizeof linea,fm);n++; //fprintf(stdout,"DATA LINEA %d: %s",n,linea); sscanf(linea,"%f %f %f %f", &x,&y,&z,&fieldmap[p]); //fprintf(stdout,"%d %d %d : %d = %g\n",i,j,k,p,fieldmap[p]); C[1][j]=y; } C[0][i]=x; //Blank line fgets(linea,sizeof linea,fm);n++; //fprintf(stdout,"LINEA %d: %s",n,linea); } C[2][k]=z; //Blank line fgets(linea,sizeof linea,fm);n++; //fprintf(stdout,"LINEA %d: %s",n,linea); } fclose(fm); /* fprintf(stdout,"X:"); arrayPrintf(stdout,"%.2e ",C[0],nx); fprintf(stdout,"\n"); fprintf(stdout,"Y:"); arrayPrintf(stdout,"%.2e ",C[1],ny); fprintf(stdout,"\n"); fprintf(stdout,"Z:"); arrayPrintf(stdout,"%.2e ",C[2],nz); fprintf(stdout,"\n"); */ //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //COLLAPSE DATA //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% STPRINTF("Collapsing data...\n"); real XDIST[MAXGRID],YDIST[MAXGRID]; real distmap[MAXGRID][MAXGRID]; switch(cx){ case 0: ndx=nx;ix=0; switch(cy){ case 1: ndy=ny;iy=1; ndz=nz;iz=2; break; case 2: ndy=nz;iy=2; ndz=ny;iz=1; break; } break; case 1: ndx=ny;ix=1; switch(cy){ case 0: ndy=nx;iy=0; ndz=nz;iz=2; break; case 2: ndy=nz;iy=2; ndz=nx;iz=0; break; } break; case 2: ndx=nz;ix=2; switch(cy){ case 0: ndy=nx;iy=0; ndz=ny;iz=1; break; case 1: ndy=ny;iy=1; ndz=nx;iz=0; break; } break; } /* fprintf(stdout,"ix,iy,iz: %d,%d,%d\n",ix,iy,iz); fprintf(stdout,"nx,ny,nz: %d,%d,%d\n",ndx,ndy,ndz); */ /* i=1;j=3;k=2; p=positionDist(ix,iy,iz,i,j,k,nx,ny,nz); fprintf(stdout,"ENTRY (%d,%d,%d:%d): %e\n",i,j,k,p,fieldmap[p]); exit(0); //*/ switch(ctype){ case '1': for(i=0;i<ndx;i++){ XDIST[i]=C[ix][i]; //fprintf(stdout,"CONST %d: %g\n",i,XDIST[i]); distmap[i][0]=0; for(j=0;j<ndy;j++){ for(k=0;k<ndz;k++){ p=positionDist(ix,iy,iz,i,j,k,nx,ny,nz); /* fprintf(stdout,"\tSumming up %d:%d,%d:%d,%d:%d = %d: %g\n", ix,i,iy,j,iz,k,p,fieldmap[p]); */ distmap[i][0]+=fieldmap[p]; } } if(coper=='a') distmap[i][0]/=(ndy*ndz); } break; case '2': for(i=0;i<ndx;i++){ XDIST[i]=C[ix][i]; for(j=0;j<ndy;j++){ YDIST[j]=C[iy][j]; distmap[i][j]=0; for(k=0;k<ndz;k++){ p=positionDist(ix,iy,iz,i,j,k,nx,ny,nz); distmap[i][j]+=fieldmap[p]; } if(coper=='a') distmap[i][j]/=ndz; } } break; } //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //STORE DISTRIBUTION //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% STPRINTF("Storing distribution in file '%s'...\n",distfile); file fd=fileOpen(distfile,"w"); fprintf(fd,"#MapFile: %s\n",mapfile); fprintf(fd,"#TypeDist: %s\n",type); switch(ctype){ case '1': fprintf(fd,"#ColapseDirections: %d\n",cx); fprintf(fd,"%-14s %-14s\n","#1:X","2:DIST"); for(i=0;i<ndx;i++){ //fprintf(fd,"%+14.7e %+14.7e\n",XDIST[i],distmap[i][0]); fprintf(fd,"%+14.7e %g\n",XDIST[i],distmap[i][0]); } break; case '2': fprintf(fd,"#ColapseDirections: %d %d\n",cx,cy); fprintf(fd,"%-14s %-14s\t%-14s\n","#1:X","2:Y","3:DIST"); for(i=0;i<ndx;i++){ for(j=0;j<ndy;j++){ //fprintf(fd,"%+14.7e %+14.7e\t%+14.7e\n",XDIST[i],YDIST[j],distmap[i][j]); fprintf(fd,"%+14.7e %+14.7e\t%g\n",XDIST[i],YDIST[j],distmap[i][j]); } fprintf(fd,"\n"); } break; } return 0; }