#ifndef __PLANET_H__ #define __PLANET_H__ #include #include #include #include #include #include #include #include #include #define CHUNK_SIZE 16 glm::vec3 posMasks[18]={ glm::vec3(1.0,0.0,0.0), glm::vec3(0.0,-1.0,0.0), glm::vec3(0.0,0.0,-1.0), glm::vec3(0.0,1.0,0.0), glm::vec3(1.0,0.0,0.0), glm::vec3(0.0,0.0,-1.0), glm::vec3(0.0,0.0,1.0), glm::vec3(-1.0,0.0,0.0), glm::vec3(0.0,-1.0,0.0), glm::vec3(-1.0,0.0,0.0), glm::vec3(0.0,-1.0,0.0), glm::vec3(0.0,0.0,-1.0), glm::vec3(0.0,-1.0,0.0), glm::vec3(1.0,0.0,0.0), glm::vec3(0.0,0.0,-1.0), glm::vec3(0.0,0.0,-1.0), glm::vec3(-1.0,0.0,0.0), glm::vec3(0.0,-1.0,0.0), }; //TODO: generate the Heightmap on the GPU via compute shaders float *generateHeightmap(glm::vec3 start, glm::vec3 end){ float *ret = (float*)malloc(CHUNK_SIZE*CHUNK_SIZE*sizeof(float)); for (int i=0; igetSizeVtx(); } return res; } if(!vtx) return 0; return sizeof(vtx->vertices)/sizeof(vtx->vertices[0]); } unsigned int getSizeInd(){ if(children[0]!=NULL&&children[1]!=NULL&&children[2]!=NULL&&children[3]!=NULL){ unsigned int res=0; for (int i=0; i<4; i++) { res+=children[i]->getSizeInd(); } return res; } if(!vtx) return 0; return sizeof(vtx->indices)/sizeof(vtx->indices[0]); } void putVtxInList(glm::vec3 *list, unsigned int *current){ if(children[0]&&children[1]&&children[2]&&children[3]){ for (int i=0; i<4; i++) { children[i]->putVtxInList(list,current); } return; } if(vtx){ memcpy(&list[*current], &vtx->vertices, sizeof(vtx->vertices)); *current+=sizeof(vtx->vertices)/sizeof(vtx->vertices[0]); } } void putIndInList(unsigned int *list, unsigned int *icurrent, unsigned int *vcurrent){ if(children[0]!=NULL&&children[1]!=NULL&&children[2]!=NULL&&children[3]!=NULL){ for (int i=0; i<4; i++) { children[i]->putIndInList(list,icurrent,vcurrent); } return; } if(vtx){ for(int i=0; iindices)/sizeof(vtx->indices[0]);i++){ list[*icurrent+i]=vtx->indices[i]+*vcurrent; } *icurrent+=sizeof(vtx->indices)/sizeof(vtx->indices[0]); *vcurrent+=sizeof(vtx->vertices)/sizeof(vtx->vertices[0]); } } void generatePlane(){ terraPlaneVtx *tpvtx = (terraPlaneVtx*)malloc(sizeof(terraPlaneVtx)); vtx=tpvtx; //use alternative axis when y is not available to measure the size of the square (bzw. chunk) float scaler=(orientation==1||orientation==4)?std::abs(endPos.x-startPos.x):std::abs(endPos.y-startPos.y); float divider=(float)CHUNK_SIZE-1.0; glm::vec3 midpoint=(startPos+endPos) /2.f; for (unsigned int j=0; jvertices[j]=cv; } unsigned int s=0; for (unsigned int j=0; j<(CHUNK_SIZE-1)*(CHUNK_SIZE-1)*2*3+s; j+=6) { if((j/6+1)%CHUNK_SIZE==0&&j!=0){ s+=6; continue; } unsigned int jdiv=j/6; vtx->indices[j -s]=jdiv; vtx->indices[j+1-s]=jdiv+1; vtx->indices[j+2-s]=jdiv+CHUNK_SIZE; vtx->indices[j+3-s]=jdiv+1; vtx->indices[j+4-s]=jdiv+CHUNK_SIZE+1; vtx->indices[j+5-s]=jdiv+CHUNK_SIZE; } } // !WIP! void subdivide(){ if(vtx){ free(vtx); } chunk *chunks = (chunk*)malloc(sizeof(chunk)*4); glm::vec3 midpoint=(startPos+endPos)/2.f; glm::vec3 midAdd=endPos-startPos; glm::vec3 selX=glm::normalize(posMasks[orientation*3+1]); glm::vec3 selY=glm::normalize(posMasks[orientation*3+2]); chunks[0].startPos=startPos; chunks[0].endPos=midpoint; chunks[1].startPos=startPos - midAdd * selX /2.f; chunks[1].endPos=midpoint - midAdd * selX /2.f; chunks[2].startPos=startPos - midAdd * selY / 2.f; chunks[2].endPos=midpoint - midAdd * selY / 2.f; chunks[3].startPos=midpoint; chunks[3].endPos=endPos; for (int i=0; i<4; i++) { chunks[i].orientation=orientation; chunks[i].generatePlane(); chunks[i].children[0]=nullptr; chunks[i].children[1]=nullptr; chunks[i].children[2]=nullptr; chunks[i].children[3]=nullptr; children[i]=&chunks[i]; //std::cout<<"children[i]->getSizeInd() = " << children[i]->getSizeInd() << " i = " << i << "\n"; } } }; class planet{ public: chunk chunks[6]; void generateSphere(){ for (int i=0; i<6; i++) { chunks[i].orientation=i; chunks[i].startPos= 0.5f*(posMasks[i*3]+ (posMasks[i*3+1] + posMasks[i*3+2])); chunks[i].endPos= 0.5f*(posMasks[i*3]- (posMasks[i*3+1] + posMasks[i*3+2])); chunks[i].generatePlane(); } //chunks[0].subdivide(); //chunks[0].children[0]->subdivide(); } planetMesh toPlanetMesh(){ unsigned int ind=0; unsigned int vert=0; for (unsigned int i=0; i<6; i++) { ind+=chunks[i].getSizeInd(); vert+=chunks[i].getSizeVtx(); } //std::cout<<"ind "<