/* This function does the quicksort Arguments : array - the array to be sorted startIndex - index of the first element of the section endIndex - index of the last element of the section */ void QuickSort(int* array, int startIndex, int endIndex) { int pivot = array[startIndex]; //pivot element is the leftmost element int splitPoint; if(endIndex > startIndex) //if they are equal, it means there is //only one element and quicksort's job //here is finished { splitPoint = SplitArray(array, pivot, startIndex, endIndex); //SplitArray() returns the position where //pivot belongs to array[splitPoint] = pivot; QuickSort(array, startIndex, splitPoint-1); //Quick sort first half QuickSort(array, splitPoint+1, endIndex); //Quick sort second half } }
void CUnit3DLoader::CreateArrays(UnitModel& model) { UnitModelGeometry& geometry=*model.geometry; vector<ArrayVertex>& va=geometry.vertexSplitting; bool newSplit=false; if(va.empty()){ newSplit=true; va.resize(geometry.vertex.size()); for(int a=0;a<geometry.vertex.size();++a){ ArrayVertex& v=va[a]; ArrayVertexSub vs; vs.num=a; vs.texCoord[0]=-1; v.sub.push_back(vs); } } else { for(vector<ArrayVertex>::iterator vi=va.begin();vi!=va.end();++vi){ for(vector<ArrayVertexSub>::iterator vsi=vi->sub.begin();vsi!=vi->sub.end();++vsi){ vsi->texCoord[0]=-1; } } } vector<Tri>::iterator ti; vector<TriTex>::iterator tti; int newNum=geometry.vertex.size(); for(ti=geometry.tri.begin(),tti=model.triTex.begin();ti!=geometry.tri.end();++ti,++tti){ //split on texcoord for(int b=0;b<3;++b){ ArrayVertex& v=va[ti->verteces[b]]; vector<ArrayVertexSub>::iterator vi; bool createNew=true; for(vi=v.sub.begin();vi!=v.sub.end();++vi){ if(vi->texCoord[0]==-1){ vi->texCoord[0]=tti->texPos[b][0]; vi->texCoord[1]=tti->texPos[b][1]; } if(vi->texCoord[0]==tti->texPos[b][0] && vi->texCoord[0]==tti->texPos[b][0]){ createNew=false; break; } } if(createNew){ if(!newSplit){ handleerror(0,"Impossible split","error in unit3dloader",0); } ArrayVertexSub vs; vs.num=newNum++; vs.texCoord[0]=tti->texPos[b][0]; vs.texCoord[1]=tti->texPos[b][1]; v.sub.push_back(vs); } } } if(newSplit){ SplitArray(geometry.vertex,geometry.vertexSplitting);//split the main frame; for(map<string,Animation*>::iterator ai=geometry.animations.begin();ai!=geometry.animations.end();++ai){//split the animation frames for(vector<AnimFrame>::iterator fi=ai->second->frames.begin();fi!=ai->second->frames.end();++fi){ SplitArray(fi->vertex,geometry.vertexSplitting); } } } if(!model.texCoordBuffer){ glGenBuffersARB( 1, &model.texCoordBuffer ); glBindBufferARB( GL_ARRAY_BUFFER_ARB, model.texCoordBuffer ); glBufferDataARB( GL_ARRAY_BUFFER_ARB, geometry.vertex.size()*2*sizeof(float), 0, GL_STATIC_DRAW_ARB ); float* texCoordBuf=(float*)glMapBufferARB(GL_ARRAY_BUFFER_ARB,GL_WRITE_ONLY_ARB); if(!texCoordBuf){ handleerror(0,"glMapBuffer failed","Exiting",0); exit(0); } for(vector<ArrayVertex>::iterator vi=va.begin();vi!=va.end();++vi){ for(vector<ArrayVertexSub>::iterator vsi=vi->sub.begin();vsi!=vi->sub.end();++vsi){ texCoordBuf[vsi->num*2]=vsi->texCoord[0]; texCoordBuf[vsi->num*2+1]=vsi->texCoord[1]; } } if(!glUnmapBufferARB(GL_ARRAY_BUFFER_ARB)){ handleerror(0,"glUnmapBuffer failed","Exiting",0); exit(0); } } if(!geometry.indexBuffer){ glGenBuffersARB( 1, &geometry.indexBuffer ); glBindBufferARB( GL_ELEMENT_ARRAY_BUFFER_ARB, geometry.indexBuffer ); glBufferDataARB( GL_ELEMENT_ARRAY_BUFFER_ARB, geometry.tri.size()*3*sizeof(unsigned short), 0, GL_STATIC_DRAW_ARB ); unsigned short* indexBuf=(unsigned short*)glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB,GL_WRITE_ONLY_ARB); if(!indexBuf){ handleerror(0,"glMapBuffer failed","Exiting",0); exit(0); } int ip=0; vector<Tri>::iterator ti; vector<TriTex>::iterator tti; for(ti=geometry.tri.begin(),tti=model.triTex.begin();ti!=geometry.tri.end();++ti,++tti){ for(int a=0;a<3;++a){ int vert=ti->verteces[a]; vector<ArrayVertexSub>& avs=va[vert].sub; for(vector<ArrayVertexSub>::iterator vsi=avs.begin();vsi!=avs.end();++vsi){ if(vsi->texCoord[0]==tti->texPos[a][0] && vsi->texCoord[1]==tti->texPos[a][1]){ vert=vsi->num; break; } } indexBuf[ip++]=vert; } } if(!glUnmapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB)){ handleerror(0,"glUnmapBuffer failed","Exiting",0); exit(0); } glBindBufferARB( GL_ELEMENT_ARRAY_BUFFER_ARB, 0); } if(!geometry.normalBuffer){ glGenBuffersARB( 1, &geometry.normalBuffer ); glBindBufferARB( GL_ARRAY_BUFFER_ARB, geometry.normalBuffer ); glBufferDataARB( GL_ARRAY_BUFFER_ARB, geometry.vertex.size()*3*sizeof(float), 0, GL_STATIC_DRAW_ARB ); float* normalBuf=(float*)glMapBufferARB(GL_ARRAY_BUFFER_ARB,GL_WRITE_ONLY_ARB); if(!normalBuf){ handleerror(0,"glMapBuffer failed","Exiting",0); exit(0); } for(vector<ArrayVertex>::iterator vi=va.begin();vi!=va.end();++vi){ int oldNum=vi->sub.begin()->num; for(vector<ArrayVertexSub>::iterator vsi=vi->sub.begin();vsi!=vi->sub.end();++vsi){ normalBuf[vsi->num*3+0]=geometry.vertexNormal[oldNum].x; normalBuf[vsi->num*3+1]=geometry.vertexNormal[oldNum].y; normalBuf[vsi->num*3+2]=geometry.vertexNormal[oldNum].z; } } if(!glUnmapBufferARB(GL_ARRAY_BUFFER_ARB)){ handleerror(0,"glUnmapBuffer failed","Exiting",0); exit(0); } } geometry.numVerteces=geometry.vertex.size(); geometry.numIndeces=geometry.tri.size()*3; glBindBufferARB( GL_ARRAY_BUFFER_ARB, 0); }