#include #include #include "GeoLodStripsConstructor.h" using namespace Geometry; //-------------------------------------------------------------------------- //Call GenerarModeloV and CopiarVectorsArraysNUEVAED to make changes //--------------------------------------------------------------------------- // Se utiliza en el constructor sobrecargado. void LodStripsConstructor::GenerarModeloCompleto(TIPOFUNC upb) { float percent; this->GenerarModeloV(upb); this->CopiarVectors2ArraysNUEVAED(); // Last updtate of the progress bar. percent = 100.0; upb(percent); } //----------------------------------------------------------------------------------- //It makes Lods changes and count them //----------------------------------------------------------------------------------- void LodStripsConstructor::CalcularCambiosLODsVNuevaED(TIPOFUNC upb) { // LODPosition pos; // vector listaPos; long int k; long int i; unsigned long int t; long int r; unsigned long int v; long int p0; long int lod = 0; long int sigue; long int ac[3] = {0,0,0}; long int totalRegs = 0; long int RegsCambios; std::vector > TiraOriginal; LODData regLOD; //LODChanges listaCambios; std::vector listaCambios; float percent; float increment; long int update; // Saves original copy. TiraOriginal = this->cStrips; this->MARCAVACIO = int(10 * this->cVerts.size()); listaCambios.clear(); // Initialize increment. increment = 0.0; for (lod = 0; ((this->cVerts[lod].Next) != -1); lod++) { increment += 1.0; } update = -1; increment = (float)30.0 / increment; percent = 1.0; this->LodsDisp = this->TOTALCAMBIOS = lod; pCambios = new uint32[this->TOTALCAMBIOS]; pCambios[0] = 0; for (lod = 0; ((this->cVerts[lod].Next) != -1); lod++) { /* if (update != (int)(increment * lod)) { update = (int)(increment * lod); upb(percent); }*/ tipoVertice & cVertsLOD = this->cVerts[lod]; RegsCambios = 0; regLOD.obligatory = this->Ordenacion[lod].obligatorio; for(t = 0; t < this->cStrips.size(); t++) { std::vector & cStripsT = this->cStrips[t]; // Initialize. regLOD.strip = this->MARCAVACIO; // Change vertices. totalRegs = 0; for (v = 0; v < cStripsT.size(); v++) { if (cStripsT[v] == lod) { // Strips. if (regLOD.strip == this->MARCAVACIO) { regLOD.strip = t; } ++totalRegs; cDatos.push_back(v); cStripsT[v] = cVertsLOD.Next; } } regLOD.nP = char(totalRegs); // Simplifications length 1. // Changes for simplification of level 1 to greater than 2. totalRegs = 0; i = 0; r = 0; sigue = 0; k = long(cStripsT.size()-3); while (i < k) { if ( (cStripsT[i] == cStripsT[i+1]) && (cStripsT[i+1] == cStripsT[i+2]) ) { // Saves beginning of repetition. if (!r) { p0 = i; } //cStripsT.eraseAtPos(i); cStripsT.erase(cStripsT.begin()+i); i--; r++; if ((i+1) != cStripsT.size()-1) { sigue = 1; } else { sigue = 0; } } else { sigue = 0; } if (!sigue && r) { /* cDatos.push_back(p0); cDatos.push_back(r); r = 0; k = long(cStripsT.size()-r-3); */ long auxp0, auxr; //regLOD.strip= t; auxp0= p0; auxr= r; if (r==1) { while(r>0) { cStripsT.insert(cStripsT.begin()+p0,cStripsT[p0]); r--; } i=p0; } else { if (r%2) //If r is odd the changes are undone { cStripsT.insert(cStripsT.begin()+p0,cStripsT[p0]); r--; auxr=r; } //listaPos.push_back(pos); cDatos.push_back(auxp0); cDatos.push_back(auxr); if (regLOD.strip == this->MARCAVACIO) { regLOD.strip = t; } ++totalRegs; } r= 0; k=cStripsT.size()-3; } i++; } regLOD.nL1 = char(totalRegs); //TERCERO: Simplificaciones de Longitud 2 tipo V1 V2 V1 V2 -> V1 V2 totalRegs = 0; i = 0; r = 0; sigue = 0; k = long(cStripsT.size() - 4); while (i < k) { if ( (cStripsT[i] == cStripsT[i+2]) && (cStripsT[i+1] == cStripsT[i+3]) ) { if (!r) { p0 = i; } //cStripsT.eraseAtPos(i); cStripsT.erase(this->cStrips[t].begin()+i); //cStripsT.eraseAtPos(i); cStripsT.erase(this->cStrips[t].begin()+i); r++; i -= 2; if ((i+1) != cStripsT.size()-3) { sigue = 1; } else { sigue = 0; } } else { sigue = 0; } if (!sigue && r) { if (regLOD.strip == this->MARCAVACIO) { regLOD.strip = t; } ++totalRegs; cDatos.push_back(p0); cDatos.push_back(r); r = 0; k = long((cStripsT.size()-4-2*r)); } i++; } regLOD.nL2 = char(totalRegs); if (regLOD.strip != this->MARCAVACIO) { RegsCambios++; listaCambios.push_back(regLOD); } }// End for t. pCambios[lod] = RegsCambios; }// End for lod. this->cCambios = listaCambios; // Guardar el numero de LODS disponibles. this->TOTALCAMBIOS = this->LodsDisp=lod; //Retornar a la lista original this->cStrips = TiraOriginal; } //----------------------------------------------------------------------- //Put in order vertex of Mesh from simplification sequence //----------------------------------------------------------------------- #include void LodStripsConstructor::OrdenarModeloVQSLIM(TIPOFUNC upb) { unsigned long int i; unsigned long int j; unsigned long int t; unsigned long int v; long int vSig; long int k; VECTORVERTEX Vertices; std::vector NuevosVerts; //vector NuevasTiras; std::vector > NuevasTiras; // VECTORINT tira; std::vector tira; vector mV1Aux; tipoOrden Orden; tipoOrden *Ord; bool bEncontrado; long int c1; long int c2; // Progress bar float percent; float increment; long int update; bEncontrado = false; int mStepsSize = geoMeshSQ->mSteps.size(); c1 = 0; c2 = 0; update = -1; percent = 1.0; increment = (float)(10.0) / (float)mStepsSize; for (i = 0; i < mStepsSize; i++) { if (update != (int)(i * increment)) { update = (int)(i * increment); upb(percent); } const Geometry::MeshSimplificationSequence::Step & theStep = this->geoMeshSQ->mSteps[i]; mV1Aux.push_back(theStep.mV1); Orden.vQslimNext = theStep.mV0; Orden.vQslim = theStep.mV1; Orden.obligatorio = theStep.obligatorio; Orden.vLS = i; Orden.x = theStep.x; Orden.vLSNext = -1; Orden.cambio = "n"; Ordenacion.push_back(Orden); } this->NumVertsRepetidos = c2; update = -1; increment = (float)(10.0) / (float)(Ordenacion.size()); percent = 1.0; // Change all vertices that have x != 0. for(i = 0; i < Ordenacion.size(); i++) { if (update != (int)(i * increment)) { update = (int)(i * increment); upb(percent); } Ord = &(Ordenacion[i]); if (Ord->x!=0) { // Change the simplification order. v = Ord->vQslim; Ord->vQslim = Ord->vQslimNext; Ord->vQslimNext = v; for (j = i+1; j < Ordenacion.size(); j++) { tipoOrden & ordJ = Ordenacion[j]; if (ordJ.vQslim == Ord->vQslim) { ordJ.vQslim = Ord->vQslimNext; ordJ.cambio = "y"; } else if (ordJ.vQslimNext == Ord->vQslim) { ordJ.vQslimNext = Ord->vQslimNext; ordJ.cambio = "y"; } } } } update = -1; increment = (float)(10.0) / (float)(Ordenacion.size()); percent = 1.0; // 3 seg. //Ordenacion de los vertices for(i = 0; i < Ordenacion.size(); i++) { if (update != (int)(i * increment)) { update = (int)(i * increment); upb(percent); } c1++; NuevosVerts.push_back(this->cVerts[Ordenacion[i].vQslim]); cVerts[Ordenacion[i].vQslim].Next = -1; } // Añadir aquellos vertices que no estaban en NuevosVerts // y no se simplificaban. int cont = 0; int contestaban = 0; int cVertsSize = this->cVerts.size(); for(i = 0; i < cVertsSize; i++) { if (this->cVerts[i].Next != -1) { cont++; NuevosVerts.push_back(this->cVerts[i]); Orden.vLS = int(Ordenacion.size()); Orden.obligatorio = 0; Orden.vLSNext = -1; Orden.vQslim = i; Orden.vQslimNext = -1; Ordenacion.push_back(Orden); } else { contestaban++; } } update = -1; increment = (float)(10.0) / (float)(Ordenacion.size()); percent = 1.0; // 2 min. // Calcular los siguiente teniendo en cuenta el simplif. for (i = 0; i < Ordenacion.size(); i++) { if (update != (int)(i * increment)) { update = (int)(i * increment); upb(percent); } v = Ordenacion[i].vQslimNext; //Buscar ese vertice v cual es ahora vSig = 0; for (t = 0; t < Ordenacion.size() && !vSig;t++) { if (Ordenacion[t].vQslim==v) { vSig=Ordenacion[t].vLS; } } if (vSig!=0) { Ordenacion[i].vLSNext = vSig; } } //Creacion de nuevas tiras con las mismas dimensiones int cStripsSize = this->cStrips.size(); for(t = 0; t < cStripsSize; t++) { tira.clear(); int cStripsSizeT = this->cStrips[t].size(); for(i = 0; i < cStripsSizeT; i++) tira.push_back(0); NuevasTiras.push_back(tira); } update = -1; increment = (float)(20.0) / (float)(NuevosVerts.size()); percent = 1.0; k = 0; // 2 min. //Cambiar los vertices de las tiras int NuevosVertsSize = NuevosVerts.size(); for(v = 0; v < NuevosVertsSize; v++) { if (update != (int)(v * increment)) { update = (int)(v * increment); upb(percent); } const tipoOrden & OrdenacionV = Ordenacion[v]; for(t = 0; t < cStrips.size(); t++) { std::vector & thisStrip = cStrips[t]; std::vector & NuevasTirasT = NuevasTiras[t]; int cStripsSizeT = thisStrip.size(); for(i = 0; i < cStripsSizeT; i++) { if (thisStrip[i] == OrdenacionV.vQslim) { k++; NuevasTirasT[i] = v; } } } } //Cambiar a Tiras Nuevas this->cStrips = NuevasTiras; //NuevosVerts y Ordenacion = tamaño. NuevosVertsSize = NuevosVerts.size(); for(i = 0; i < NuevosVertsSize; i++) { NuevosVerts[i].Next = Ordenacion[i].vLSNext; } //Cambiar cVerts por nuevosVerts. this->cVerts = NuevosVerts; //percent = 100.0; //upb(percent); } //----------------------------------------------------------------------------- // Constructor of LodStripsConstructor object from // a Mesh and MeshSimplificationSequence // Constructor del objeto LodStripsConstructor. // Tomamos el Mesh y la secuencia de simplificacion que se pasan // como parametros y llamamos a la funcion GenerarModeloCompleto para // que se realicen las modificaciones a efectuar //----------------------------------------------------------------------------- LodStripsConstructor::LodStripsConstructor(const Mesh *m, const MeshSimplificationSequence *ms, size_t submesh, TIPOFUNC upb) { MARCA = TOTALTIRAS = TOTALVERTS = TOTALCAMBIOS = 0; meshoriginal = m; this->geoMesh = new Geometry::Mesh(); *this->geoMesh = *m; this->geoMeshSQ = const_cast(ms); // Set the leaves submesh. mSubMeshLeaves = submesh; this->GenerarModeloCompleto(upb); } //--------------------------------------------- // Destructor LodStripsConstructor object // Destructor de la clase LodStripsConstructor //--------------------------------------------- LodStripsConstructor::~LodStripsConstructor() { delete [] vDatos; delete [] vCambios; /* vector cCambiosTemp; cCambios.swap(cCambiosTemp);*/ cCambios.clear(); /* VECTORUNINT cDatosTemp; cDatos.swap(cDatosTemp);*/ cDatos.clear(); delete [] vStrips; delete [] vVerts; // vector cStripsTemp; // cStrips.swap(cStripsTemp);; cStrips.clear(); // VECTORVERTEX cVertsTemp; // cVerts.swap(cVertsTemp); cVerts.clear(); delete [] pCambios; delete this->geoMesh; } //------------------------------------------------------------------------------ // build lod file with necessary information and save all changes at // lodStripConstructor object // Construimos el archivo Lod donde se guarda la informacion sobre los // cambios realizados en el mesh // y copiamos todos los cambios realizados sobre las estructuras que // contienen los vertices y los indices // modificados sobre el objeto Mesh de la clase //------------------------------------------------------------------------------ void LodStripsConstructor::Save(Serializer &oSerializer) { unsigned int i, j; int k = 0; char simp[256]; //****************** 1º CONSTRUCCION DEL FICHERO.LOD ********************* // VERTICES. for(i = 0; i < this->cVerts.size(); i++) { sprintf(simp,"v %d\n",cVerts[i].Next); oSerializer.WriteData(simp,sizeof(char),strlen(simp)); } // CSTRIPS. this->TOTALINDICES = 0; for(i = 0; i < this->cStrips.size(); i++) { this->TOTALINDICES += int(this->cStrips[i].size()); } // lines starting with a d. // Changes for(i = 0; i < this->cCambios.size(); i++) { sprintf(simp,"c\n"); oSerializer.WriteData(simp,sizeof(char),strlen(simp)); sprintf(simp, "d %u %u %u %u %u\n", cCambios[i].strip, cCambios[i].nP, cCambios[i].nL1, cCambios[i].nL2, cCambios[i].obligatory); oSerializer.WriteData(simp,sizeof(char),strlen(simp)); } // Lines starting with a b. // Data. sprintf(simp,"a\n"); oSerializer.WriteData(simp,sizeof(char),strlen(simp)); for(i = 0; i < this->cDatos.size(); i++) { sprintf(simp,"b %d\n",cDatos[i]); oSerializer.WriteData(simp,sizeof(char),strlen(simp)); } // lines starting with a p. // Chages made in a LOD. for(i = 0; i < this->TOTALCAMBIOS; i++) { sprintf(simp,"p %d\n",this->pCambios[i]); oSerializer.WriteData(simp,sizeof(char),strlen(simp)); } oSerializer.WriteData("\n",sizeof(char),1); //******************* 2º DEVOLVER EL MESH CON LAS MODIFICACIONES EFECTUADAS ********************* int num_no = 0; if(this->geoMesh->mSubMesh[0].mSharedVertexBuffer == true) { //mPosition delete[] this->geoMesh->mVertexBuffer->mPosition; this->geoMesh->mVertexBuffer->mPosition = new Vector3[this->cVerts.size()]; //mNormal if (meshoriginal->mSubMesh[0].mVertexBuffer->mVertexInfo & Geometry::VERTEX_NORMAL) { delete[] this->geoMesh->mVertexBuffer->mNormal; this->geoMesh->mVertexBuffer->mNormal = new Vector3[this->cVerts.size()]; } //mTexCoords if (meshoriginal->mSubMesh[0].mVertexBuffer->mVertexInfo & Geometry::VERTEX_TEXCOORDS) { delete[] this->geoMesh->mVertexBuffer->mTexCoords; this->geoMesh->mVertexBuffer->mTexCoords = new Vector2[this->cVerts.size()]; } this->geoMesh->mVertexBuffer->mVertexCount = this->cVerts.size(); this->geoMesh->mVertexBuffer->mVertexInfo = this->meshoriginal->mSubMesh[0].mVertexBuffer->mVertexInfo; for(i = 0; i < this->geoMesh->mSubMeshCount; i++) { this->geoMesh->mSubMesh[i].mVertexBuffer = this->geoMesh->mVertexBuffer; this->geoMesh->mSubMesh[i].mSharedVertexBuffer = true; } int indice = 0; for (j = 0; j < this->cVerts.size(); j++) { //Copiamos las coordeandas de posicion this->geoMesh->mVertexBuffer->mPosition[indice].x = this->cVerts[j].Vertex[0]; this->geoMesh->mVertexBuffer->mPosition[indice].y = this->cVerts[j].Vertex[1]; this->geoMesh->mVertexBuffer->mPosition[indice].z = this->cVerts[j].Vertex[2]; //Copiamos las normales if (meshoriginal->mVertexBuffer->mVertexInfo & Geometry::VERTEX_NORMAL) { this->geoMesh->mVertexBuffer->mNormal[indice].x = this->cVerts[j].Normal[0]; this->geoMesh->mVertexBuffer->mNormal[indice].y = this->cVerts[j].Normal[1]; this->geoMesh->mVertexBuffer->mNormal[indice].z = this->cVerts[j].Normal[2]; } //Copiamos las coordenadas de textura if (meshoriginal->mVertexBuffer->mVertexInfo & Geometry::VERTEX_TEXCOORDS) { this->geoMesh->mVertexBuffer->mTexCoords[indice].x = this->cVerts[j].TexCoords[0]; this->geoMesh->mVertexBuffer->mTexCoords[indice].y = this->cVerts[j].TexCoords[1]; } indice++; } this->geoMesh->mVertexBuffer->mVertexCount = indice; } else //OSCAR { //Supondre que solo tengo un submesh con vertices no compartidos //mPosition delete[] this->geoMesh->mSubMesh[0].mVertexBuffer->mPosition; this->geoMesh->mSubMesh[0].mVertexBuffer->mPosition = new Vector3[this->cVerts.size()]; //mNormal if (meshoriginal->mSubMesh[0].mVertexBuffer->mVertexInfo & Geometry::VERTEX_NORMAL) { delete[] this->geoMesh->mSubMesh[0].mVertexBuffer->mNormal; this->geoMesh->mSubMesh[0].mVertexBuffer->mNormal = new Vector3[this->cVerts.size()]; } //mTexCoords if (meshoriginal->mSubMesh[0].mVertexBuffer->mVertexInfo & Geometry::VERTEX_TEXCOORDS) { delete[] this->geoMesh->mSubMesh[0].mVertexBuffer->mTexCoords; this->geoMesh->mSubMesh[0].mVertexBuffer->mTexCoords = new Vector2[this->cVerts.size()]; } this->geoMesh->mSubMesh[0].mVertexBuffer->mVertexCount =this->cVerts.size(); this->geoMesh->mSubMesh[0].mVertexBuffer->mVertexInfo = this->meshoriginal->mSubMesh[0].mVertexBuffer->mVertexInfo; this->geoMesh->mSubMesh[0].mSharedVertexBuffer=false; int indice=0; for (j=0; jcVerts.size(); j++) { //Copiamos las coordeandas de posicion this->geoMesh->mSubMesh[0].mVertexBuffer->mPosition[indice].x=this->cVerts[j].Vertex[0]; this->geoMesh->mSubMesh[0].mVertexBuffer->mPosition[indice].y=this->cVerts[j].Vertex[1]; this->geoMesh->mSubMesh[0].mVertexBuffer->mPosition[indice].z=this->cVerts[j].Vertex[2]; //Copiamos las normales if (meshoriginal->mSubMesh[0].mVertexBuffer->mVertexInfo & Geometry::VERTEX_NORMAL) { this->geoMesh->mSubMesh[0].mVertexBuffer->mNormal[indice].x=this->cVerts[j].Normal[0]; this->geoMesh->mSubMesh[0].mVertexBuffer->mNormal[indice].y=this->cVerts[j].Normal[1]; this->geoMesh->mSubMesh[0].mVertexBuffer->mNormal[indice].z=this->cVerts[j].Normal[2]; } //Copiamos las coordenadas de textura if (meshoriginal->mSubMesh[0].mVertexBuffer->mVertexInfo & Geometry::VERTEX_TEXCOORDS) { this->geoMesh->mSubMesh[0].mVertexBuffer->mTexCoords[indice].x=this->cVerts[j].TexCoords[0]; this->geoMesh->mSubMesh[0].mVertexBuffer->mTexCoords[indice].y=this->cVerts[j].TexCoords[1]; } indice++; } this->geoMesh->mSubMesh[0].mVertexBuffer->mVertexCount =indice; } int indice_acum = 0; for(i=0;igeoMesh->mSubMeshCount;i++) { Geometry::SubMesh & subMesh = meshoriginal->mSubMesh[i]; Geometry::SubMesh & geoMeshSubMesh = this->geoMesh->mSubMesh[i]; for (size_t ind=0; ind < subMesh.mIndexCount; ind++) { Index indIndex = subMesh.mIndex[ind]; if (subMesh.mVertexBuffer->mVertexInfo & Geometry::VERTEX_TEXCOORDS) { //Hay coordenadas de textura y normales if(subMesh.mVertexBuffer->mVertexInfo & Geometry::VERTEX_NORMAL) { for (size_t indvo=0; indvomVertexCount; indvo++) { if (igual(subMesh.mVertexBuffer->mPosition[indIndex],geoMeshSubMesh.mVertexBuffer->mPosition[indvo])) { if (igual(subMesh.mVertexBuffer->mNormal[indIndex],geoMeshSubMesh.mVertexBuffer->mNormal[indvo])) { if (igual(subMesh.mVertexBuffer->mTexCoords[indIndex],geoMeshSubMesh.mVertexBuffer->mTexCoords[indvo])) { geoMeshSubMesh.mIndex[ind]= int(indvo);//+indice_acum; } } } } } else //Hay coordenadas de textura pero no hay normales { for (size_t indvo=0; indvomVertexCount; indvo++) { if (igual(subMesh.mVertexBuffer->mPosition[indIndex],geoMeshSubMesh.mVertexBuffer->mPosition[indvo])) { if (igual(subMesh.mVertexBuffer->mTexCoords[indIndex],geoMeshSubMesh.mVertexBuffer->mTexCoords[indvo])) { geoMeshSubMesh.mIndex[ind]=int(indvo);//+indice_acum; } } } } } else { // No hay coordenadas de textura pero si normales if(subMesh.mVertexBuffer->mVertexInfo & Geometry::VERTEX_NORMAL) { for (size_t indvo=0; indvomVertexCount; indvo++) { if (igual(subMesh.mVertexBuffer->mPosition[indIndex],geoMeshSubMesh.mVertexBuffer->mPosition[indvo])) { if (igual(subMesh.mVertexBuffer->mNormal[indIndex],geoMeshSubMesh.mVertexBuffer->mNormal[indvo])) { geoMeshSubMesh.mIndex[ind]=int(indvo);//+indice_acum; } } } } else //No hay coordenadas de texturas ni normales { for (size_t indvo=0; indvomVertexCount; indvo++) { if (igual(subMesh.mVertexBuffer->mPosition[indIndex],geoMeshSubMesh.mVertexBuffer->mPosition[indvo])) { geoMeshSubMesh.mIndex[ind]=int(indvo);//+indice_acum; } } } } } } } int LodStripsConstructor::igual(Geometry::Vector3 vo,Geometry::Vector3 vc) { if (vo.x==vc.x && vo.y==vc.y && vo.z==vc.z) return 1; else return 0; } int LodStripsConstructor::igual(Geometry::Vector2 vo,Geometry::Vector2 vc) { if (vo.x==vc.x && vo.y==vc.y) return 1; else return 0; } void LodStripsConstructor::Load(Serializer &oSerializer) { } //----------------------------------------------------------------------------------------------- //Call leeVerticesyTirasDeMesh, OrdenarModeloVQSLIM and CalcularCambiosLODsVNuevaED to make changes //at vertex and index strutures //Llama a los metodos que realizan los cambios sobre las estructuras que contienen la informacion //de los vertices y los indices //----------------------------------------------------------------------------------------------- void LodStripsConstructor::GenerarModeloV(TIPOFUNC upb) { long int max; long int t; unsigned long int i; float percent; percent = 10; this->leeVerticesyTirasDeMesh(); upb(percent); // 6 min. this->OrdenarModeloVQSLIM(upb); //Calcular el tamaño maximo de tira max = 0; for(i = 0; i < this->TOTALTIRAS; i++) { t = long(this->cStrips[i].size()); if (t > max) { max = t; } } this->MARCA = max + 1; this->CalcularCambiosLODsVNuevaED(upb); } //----------------------------------------------------------------------------------------- //It fills structs with vertex and index information //Rellena estructuras de datos que contienen la informacion de vertices y tiras modificadas //----------------------------------------------------------------------------------------- void LodStripsConstructor::CopiarVectors2ArraysNUEVAED() { unsigned int i; unsigned int j; uint32 max; uint32 t; VECTORINT tira; LODChanges listaCambios; // ALLOCATE---------------- this->TOTALVERTS = int(this->cVerts.size()); this->TOTALTIRAS = int(this->cStrips.size()); this->vVerts = new tipoVertice[this->TOTALVERTS]; this->lStripsV = new VECTORINT[this->TOTALTIRAS]; this->vDatos = new uint32[cDatos.size()]; // Calcular el tamaño maximo de tira y el numero de caras total. max = 0; this->TOTALCARAS = 0; for (i = 0; i < this->cStrips.size(); i++) { t = int(this->cStrips[i].size()); if (t > max) { max = t; } this->TOTALCARAS += (t-2); } this->vStrips = Allocate2DArrayINT(this->TOTALTIRAS,max+1); this->MARCA = int(this->cVerts.size()); vCambios = new LODData[this->cCambios.size()]; // Rellenar vChanges. for (i = 0; i < this->cCambios.size();++i) { vCambios[i] = cCambios[i]; } for (i = 0; i < this->cStrips.size(); i++) { for (j = 0; j < this->cStrips[i].size(); j++) { // Rellenar el array vStrips. this->vStrips[i][j] = this->cStrips[i][j]; // Rellenar el vVector. this->lStripsV[i].push_back(this->cStrips[i][j]); } this->vStrips[i][j] = this->MARCA; } for (i = 0; i < cDatos.size(); i++) { vDatos[i] = cDatos[i]; } pCurrentData = vDatos; // Meter los vertices en vVerts. for (i = 0; i < this->cVerts.size(); i++) { this->vVerts[i] = this->cVerts[i]; } } //--------------------------------------------------------------------------------------------------- //It fills cVerts and cStrips with original Mesh vertex and strips information //Rellena las estructuras cVerts Y cStrips a partir de de los vertices y las tiras del mesh original //--------------------------------------------------------------------------------------------------- void LodStripsConstructor::leeVerticesyTirasDeMesh() { tipoVertice vAux; std::vector tira; size_t i; size_t j; bool error; error = false; if(this->geoMesh->mSubMeshCount == 1) { error = false; } else { for (i = 0; i < this->geoMesh->mSubMeshCount;i++) { if (this->geoMesh->mSubMesh[i].mSharedVertexBuffer == true) { error = false; } else { error = true; break; } } } if(!error) { if ( (this->geoMesh->mSubMesh[0].mSharedVertexBuffer == true) && (this->geoMesh->mSubMeshCount > 1) ) { for (j = 0; j < this->geoMesh->mVertexBuffer->mVertexCount; j++) { // Si hay mas de un submesh ListaIndices no se rellena correctamente vAux.Vertex[0] = this->geoMesh->mVertexBuffer->mPosition[j].x; vAux.Vertex[1] = this->geoMesh->mVertexBuffer->mPosition[j].y; vAux.Vertex[2] = this->geoMesh->mVertexBuffer->mPosition[j].z; // Añadimos las normales en cVerts. if ( this->geoMesh->mVertexBuffer->mVertexInfo & Geometry::VERTEX_NORMAL ) { vAux.Normal[0] = this->geoMesh->mVertexBuffer->mNormal[j].x; vAux.Normal[1] = this->geoMesh->mVertexBuffer->mNormal[j].y; vAux.Normal[2] = this->geoMesh->mVertexBuffer->mNormal[j].z; } // Añadimos las coordenadas de textura a cVerts. if ( this->geoMesh->mVertexBuffer->mVertexInfo & Geometry::VERTEX_TEXCOORDS ) { vAux.TexCoords[0] = this->geoMesh->mVertexBuffer->mTexCoords[j].x; vAux.TexCoords[1] = this->geoMesh->mVertexBuffer->mTexCoords[j].y; } vAux.Next = -10; vAux.numMesh = 0; vAux.obligatorio = 0; this->cVerts.push_back(vAux); } } else { for (i = 0; i < this->geoMesh->mSubMeshCount; i++) { for ( j = 0; j < this->geoMesh->mSubMesh[i].mVertexBuffer->mVertexCount; j++) { // Si hay mas de un submesh ListaIndices // no se rellena correctamente. vAux.Vertex[0] = this->geoMesh->mSubMesh[i]. mVertexBuffer->mPosition[j].x; vAux.Vertex[1] = this->geoMesh->mSubMesh[i]. mVertexBuffer->mPosition[j].y; vAux.Vertex[2] = this->geoMesh->mSubMesh[i]. mVertexBuffer->mPosition[j].z; // Añadimos las normales en cVerts. vAux.Normal[0] = this->geoMesh->mSubMesh[i]. mVertexBuffer->mNormal[j].x; vAux.Normal[1] = this->geoMesh->mSubMesh[i]. mVertexBuffer->mNormal[j].y; vAux.Normal[2] = this->geoMesh->mSubMesh[i]. mVertexBuffer->mNormal[j].z; // Añadimos las coordenadas de textura a cVerts. vAux.TexCoords[0] = this->geoMesh->mSubMesh[i]. mVertexBuffer->mTexCoords[j].x; vAux.TexCoords[1] = this->geoMesh->mSubMesh[i]. mVertexBuffer->mTexCoords[j].y; vAux.Next = -10; vAux.numMesh = int(i); this->cVerts.push_back(vAux); } } } Index indice_acum; Index num_vert; num_vert = 0; for (i = 0; i < this->geoMesh->mSubMeshCount; i++) { // If is not the leaves submesh. if (mSubMeshLeaves != i) { indice_acum = 0; for (j = 0; j < this->geoMesh->mSubMesh[i].mStripCount; j++) { Index *aux = this->geoMesh->mSubMesh[i].mStrip[j]; /* if (j != 0) { // La primera tira no empieza por índices repetidos. aux = aux+1; indice_acum++; } */ if (j+1 < this->geoMesh->mSubMesh[i].mStripCount) { Index *siguiente = this->geoMesh->mSubMesh[i].mStrip[j+1]; tira.clear(); while (aux != siguiente) { tira.push_back(*aux); indice_acum++; aux = aux + 1; } //tira.pop_back(); this->cStrips.push_back(tira); } else { // Insertar los indices de la última tira en el cStrips tira.clear(); for ( unsigned int k = indice_acum; k < this->geoMesh->mSubMesh[i].mIndexCount; k++) { tira.push_back(this->geoMesh->mSubMesh[i].mIndex[k]); } this->cStrips.push_back(tira); } } num_vert += int(this->geoMesh->mSubMesh[i]. mVertexBuffer->mVertexCount); } } this->TOTALVERTS = int(cVerts.size()); this->TOTALTIRAS = int(cStrips.size()); } else { // Error. } } // GetMesh: Return de current Mesh. Mesh * LodStripsConstructor::GetMesh() { Mesh *mesh_built; mesh_built = new Mesh(); *mesh_built = *geoMesh; return mesh_built; } // Sets what is the submesh that stores the leaves. void LodStripsConstructor::SetSubMeshLeaves(size_t submesh) { mSubMeshLeaves = submesh; }