#include #include #include #include "GeoLodStripsConstructor.h" #include "GeoMeshLoader.h" using namespace Geometry; //--------------------------------------------------------------------------- // Call GenerarModeloV and CopiarVectorsArraysNUEVAED to make changes. //--------------------------------------------------------------------------- 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) { 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; 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++) { tipoVertice & cVertsLOD = this->cVerts[lod]; RegsCambios = 0; regLOD.obligatory = this->Ordenacion[lod].obligatory; 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 = (long)(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 //--------------------------------------------------------------------------- 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; std::vector > NuevasTiras; std::vector tira; tipoOrden Orden; tipoOrden *Ord; bool bEncontrado; // Progress bar float percent; float increment; long int update; bEncontrado = false; size_t mStepsSize = mGeoMeshSQ->mSteps.size(); 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 MeshSimplificationSequence::Step & theStep = this->mGeoMeshSQ->mSteps[i]; Orden.vQslimNext = theStep.mV0; Orden.vQslim = theStep.mV1; Orden.obligatory = theStep.obligatory; Orden.vLS = i; Orden.x = theStep.x; Orden.vLSNext = -1; Orden.cambio = "n"; Ordenacion.push_back(Orden); } update = -1; increment = (float)(10.0) / (float)(Ordenacion.size()); percent = 1.0; 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); } int OrdvQslim = Ordenacion[i].vQslim; int OrdvQslimNext = Ordenacion[i].vQslimNext; NuevosVerts.push_back(this->cVerts[OrdvQslim]); cVerts[OrdvQslim].Next = -1; } // Añadir aquellos vertices que no estaban en NuevosVerts // y no se simplificaban. int cont = 0; int contestaban = 0; size_t 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.obligatory = 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 size_t cStripsSize = this->cStrips.size(); for(t = 0; t < cStripsSize; t++) { tira.clear(); size_t 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 size_t 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]; size_t 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. //--------------------------------------------------------------------------- LodStripsConstructor::LodStripsConstructor(const Mesh *m, const MeshSimplificationSequence *ms, size_t submesh, TIPOFUNC upb) { MARCA = TOTALTIRAS = TOTALVERTS = TOTALCAMBIOS = 0; meshoriginal = m; mGeoMesh = new Mesh(); *mGeoMesh = *m; mInitialMesh = new Mesh(); *mInitialMesh = *m; this->mGeoMeshSQ = const_cast(ms); // Add new vertices to mesh. AddNewVertices(); // Set the leaves submesh. mSubMeshLeaves = submesh; this->GenerarModeloCompleto(upb); } //--------------------------------------------------------------------------- // Destructor LodStripsConstructor object //--------------------------------------------------------------------------- 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 mInitialMesh; delete mGeoMesh; } //--------------------------------------------------------------------------- // Build lod file with necessary information and save all changes at // lodStripConstructor object. //--------------------------------------------------------------------------- void LodStripsConstructor::Save(std::string filename) { int vertexCount = (int)this->cVerts.size(); int changesCount = (int)this->cCambios.size(); int dataCount = (int)this->cDatos.size(); int cambiosCount = this->TOTALCAMBIOS; int size = changesCount*sizeof(LODData) + (vertexCount + dataCount + cambiosCount + 4) * sizeof(int) + CHUNK_OVERHEAD_SIZE; FILE *f = fopen(filename.c_str(),"ab"); unsigned short chunkid = 0xabcd; fwrite(&chunkid,sizeof(unsigned short),1,f); fwrite(&size,sizeof(unsigned long),1,f); // VERTICES. fwrite(&vertexCount, sizeof(int), 1, f); for (size_t i = 0; i < this->cVerts.size(); i++) { int auxv = cVerts[i].Next; fwrite(&auxv, sizeof(int), 1, f); } // CSTRIPS. this->TOTALINDICES = 0; for(size_t i = 0; i < this->cStrips.size(); i++) { this->TOTALINDICES += int(this->cStrips[i].size()); } // lines starting with a d. // Changes fwrite(&changesCount, sizeof(int), 1, f); for(size_t i = 0; i < this->cCambios.size(); i++) { LODData change= cCambios[i]; fwrite(&change, sizeof(LODData), 1, f); } // Data. fwrite(&dataCount, sizeof(int), 1, f); for(size_t i = 0; i < this->cDatos.size(); i++) { int data= cDatos[i]; fwrite(&data, sizeof(int), 1, f); } // lines starting with a p. // Chages made in a LOD. fwrite(&cambiosCount, sizeof(int), 1, f); for(size_t i = 0; i < this->TOTALCAMBIOS; i++) { int cambio= pCambios[i]; fwrite(&cambio, sizeof(int), 1, f); } fclose(f); } 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. //--------------------------------------------------------------------------- void LodStripsConstructor::GenerarModeloV(TIPOFUNC upb) { long int max; long int t; unsigned long int i; float percent; percent = 10; this->leeVerticesyTirasDeMesh(); upb(percent); 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. //--------------------------------------------------------------------------- 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. //--------------------------------------------------------------------------- void LodStripsConstructor::leeVerticesyTirasDeMesh() { tipoVertice vAux; std::vector tira; size_t i; size_t j; bool error; error = false; if(this->mGeoMesh->mSubMeshCount == 1) { error = false; } else { for (i = 0; i < this->mGeoMesh->mSubMeshCount;i++) { if (this->mGeoMesh->mSubMesh[i].mSharedVertexBuffer == true) { error = false; } else { error = true; break; } } } if(!error) { if ( (this->mGeoMesh->mSubMesh[0].mSharedVertexBuffer == true) && (this->mGeoMesh->mSubMeshCount > 1) ) { for (j = 0; j < this->mGeoMesh->mVertexBuffer->mVertexCount; j++) { // Si hay mas de un submesh ListaIndices no se rellena correctamente vAux.Vertex[0] = this->mGeoMesh->mVertexBuffer->mPosition[j].x; vAux.Vertex[1] = this->mGeoMesh->mVertexBuffer->mPosition[j].y; vAux.Vertex[2] = this->mGeoMesh->mVertexBuffer->mPosition[j].z; // Añadimos las normales en cVerts. if ( this->mGeoMesh->mVertexBuffer->mVertexInfo & Geometry::VERTEX_NORMAL ) { vAux.Normal[0] = this->mGeoMesh->mVertexBuffer->mNormal[j].x; vAux.Normal[1] = this->mGeoMesh->mVertexBuffer->mNormal[j].y; vAux.Normal[2] = this->mGeoMesh->mVertexBuffer->mNormal[j].z; } // Añadimos las coordenadas de textura a cVerts. if ( this->mGeoMesh->mVertexBuffer->mVertexInfo & Geometry::VERTEX_TEXCOORDS ) { vAux.TexCoords[0] = this->mGeoMesh->mVertexBuffer->mTexCoords[j].x; vAux.TexCoords[1] = this->mGeoMesh->mVertexBuffer->mTexCoords[j].y; } vAux.Next = -10; vAux.numMesh = 0; vAux.obligatory = 0; this->cVerts.push_back(vAux); } } else { for (i = 0; i < this->mGeoMesh->mSubMeshCount; i++) { for ( j = 0; j < this->mGeoMesh->mSubMesh[i].mVertexBuffer->mVertexCount; j++) { // Si hay mas de un submesh ListaIndices // no se rellena correctamente. vAux.Vertex[0] = this->mGeoMesh->mSubMesh[i]. mVertexBuffer->mPosition[j].x; vAux.Vertex[1] = this->mGeoMesh->mSubMesh[i]. mVertexBuffer->mPosition[j].y; vAux.Vertex[2] = this->mGeoMesh->mSubMesh[i]. mVertexBuffer->mPosition[j].z; // Añadimos las normales en cVerts. vAux.Normal[0] = this->mGeoMesh->mSubMesh[i]. mVertexBuffer->mNormal[j].x; vAux.Normal[1] = this->mGeoMesh->mSubMesh[i]. mVertexBuffer->mNormal[j].y; vAux.Normal[2] = this->mGeoMesh->mSubMesh[i]. mVertexBuffer->mNormal[j].z; // Añadimos las coordenadas de textura a cVerts. vAux.TexCoords[0] = this->mGeoMesh->mSubMesh[i]. mVertexBuffer->mTexCoords[j].x; vAux.TexCoords[1] = this->mGeoMesh->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; // load the strips list for (i = 0; i < this->mGeoMesh->mSubMeshCount; i++) { // If is not the leaves submesh. if (mSubMeshLeaves != i) { indice_acum = 0; for (j = 0; j < this->mGeoMesh->mSubMesh[i].mStripCount; j++) { Index *aux = this->mGeoMesh->mSubMesh[i].mStrip[j]; // remove strip degenerates (first indices) except for the first (DEG!) if (j != 0) { // La primera tira no empieza por índices repetidos. aux = aux+1; indice_acum++; } if (j+1 < this->mGeoMesh->mSubMesh[i].mStripCount) { Index *siguiente = this->mGeoMesh->mSubMesh[i].mStrip[j+1]; tira.clear(); while (aux != siguiente) { tira.push_back(*aux); indice_acum++; aux = aux + 1; } // DEG!: remove strip degenerates (last indices) except for the last strip 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->mGeoMesh->mSubMesh[i].mIndexCount; k++) { tira.push_back(this->mGeoMesh->mSubMesh[i].mIndex[k]); } this->cStrips.push_back(tira); } } num_vert += int(this->mGeoMesh->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 = *mGeoMesh; return mesh_built; } //--------------------------------------------------------------------------- // Sets what is the submesh that stores the leaves. //--------------------------------------------------------------------------- void LodStripsConstructor::SetSubMeshLeaves(size_t submesh) { mSubMeshLeaves = submesh; } //--------------------------------------------------------------------------- // Sort submesh bones. //--------------------------------------------------------------------------- void LodStripsConstructor::sortBones() { VertexBuffer *mesh_vb; VertexBuffer *copy_vb; std::vector *mesh_bones; std::vector *copy_bones; // After simplifying, the object always is shared vertex // so, the bones must be placed in the GeoMesh mesh_bones = &mGeoMesh->mBones; mesh_vb = mGeoMesh->mVertexBuffer; // we assume the original mesh is shared vertex // because before the simplification process // the mesh becomes converted to shared vertex // so, the original bones must be searched in the // Mesh, not in every submesh mesh_bones->clear(); // Vertex buffers. copy_vb = mInitialMesh->mVertexBuffer; // Bones. copy_bones = &mInitialMesh->mBones; // If there are submesh bones. for (int b = 0; b < copy_bones->size(); b++) { VertexBoneAssignment assign; int n = (*copy_bones)[b].vertexIndex; // Initialize o. int o=0; for (o=0; omVertexCount; o++) { if (mesh_vb->mPosition[o].x == copy_vb->mPosition[n].x && mesh_vb->mPosition[o].y == copy_vb->mPosition[n].y && mesh_vb->mPosition[o].z == copy_vb->mPosition[n].z) { assign.vertexIndex = o; assign.boneIndex = (*copy_bones)[b].boneIndex; assign.weight = 1.0f; mesh_bones->push_back(assign); } } } } void LodStripsConstructor::UpdateMesh(void) { int num_no = 0; //int i=0,j=0; if(this->mGeoMesh->mSubMesh[0].mSharedVertexBuffer == true) { //mPosition delete[] this->mGeoMesh->mVertexBuffer->mPosition; this->mGeoMesh->mVertexBuffer->mPosition = new Vector3[this->cVerts.size()]; //mNormal if (meshoriginal->mSubMesh[0].mVertexBuffer->mVertexInfo & Geometry::VERTEX_NORMAL) { delete[] this->mGeoMesh->mVertexBuffer->mNormal; this->mGeoMesh->mVertexBuffer->mNormal = new Vector3[this->cVerts.size()]; } //mTexCoords if (meshoriginal->mSubMesh[0].mVertexBuffer->mVertexInfo & Geometry::VERTEX_TEXCOORDS) { delete[] this->mGeoMesh->mVertexBuffer->mTexCoords; this->mGeoMesh->mVertexBuffer->mTexCoords = new Vector2[this->cVerts.size()]; } this->mGeoMesh->mVertexBuffer->mVertexCount = this->cVerts.size(); this->mGeoMesh->mVertexBuffer->mVertexInfo = this->meshoriginal->mSubMesh[0].mVertexBuffer->mVertexInfo; for(size_t i = 0; i < this->mGeoMesh->mSubMeshCount; i++) { this->mGeoMesh->mSubMesh[i].mVertexBuffer = this->mGeoMesh->mVertexBuffer; this->mGeoMesh->mSubMesh[i].mSharedVertexBuffer = true; } int indice = 0; for (size_t j = 0; j < this->cVerts.size(); j++) { //Copiamos las coordeandas de posicion this->mGeoMesh->mVertexBuffer->mPosition[indice].x = this->cVerts[j].Vertex[0]; this->mGeoMesh->mVertexBuffer->mPosition[indice].y = this->cVerts[j].Vertex[1]; this->mGeoMesh->mVertexBuffer->mPosition[indice].z = this->cVerts[j].Vertex[2]; //Copiamos las normales if (meshoriginal->mVertexBuffer->mVertexInfo & Geometry::VERTEX_NORMAL) { this->mGeoMesh->mVertexBuffer->mNormal[indice].x = this->cVerts[j].Normal[0]; this->mGeoMesh->mVertexBuffer->mNormal[indice].y = this->cVerts[j].Normal[1]; this->mGeoMesh->mVertexBuffer->mNormal[indice].z = this->cVerts[j].Normal[2]; } //Copiamos las coordenadas de textura if (meshoriginal->mVertexBuffer->mVertexInfo & Geometry::VERTEX_TEXCOORDS) { this->mGeoMesh->mVertexBuffer->mTexCoords[indice].x = this->cVerts[j].TexCoords[0]; this->mGeoMesh->mVertexBuffer->mTexCoords[indice].y = this->cVerts[j].TexCoords[1]; } indice++; } this->mGeoMesh->mVertexBuffer->mVertexCount = indice; } else //OSCAR { //Supondre que solo tengo un submesh con vertices no compartidos //mPosition delete[] this->mGeoMesh->mSubMesh[0].mVertexBuffer->mPosition; this->mGeoMesh->mSubMesh[0].mVertexBuffer->mPosition = new Vector3[this->cVerts.size()]; //mNormal if (meshoriginal->mSubMesh[0].mVertexBuffer->mVertexInfo & Geometry::VERTEX_NORMAL) { delete[] this->mGeoMesh->mSubMesh[0].mVertexBuffer->mNormal; this->mGeoMesh->mSubMesh[0].mVertexBuffer->mNormal = new Vector3[this->cVerts.size()]; } //mTexCoords if (meshoriginal->mSubMesh[0].mVertexBuffer->mVertexInfo & Geometry::VERTEX_TEXCOORDS) { delete[] this->mGeoMesh->mSubMesh[0].mVertexBuffer->mTexCoords; this->mGeoMesh->mSubMesh[0].mVertexBuffer->mTexCoords = new Vector2[this->cVerts.size()]; } this->mGeoMesh->mSubMesh[0].mVertexBuffer->mVertexCount =this->cVerts.size(); this->mGeoMesh->mSubMesh[0].mVertexBuffer->mVertexInfo = this->meshoriginal->mSubMesh[0].mVertexBuffer->mVertexInfo; this->mGeoMesh->mSubMesh[0].mSharedVertexBuffer=false; int indice = 0; for (size_t j = 0; j < this->cVerts.size(); j++) { //Copiamos las coordeandas de posicion this->mGeoMesh->mSubMesh[0].mVertexBuffer->mPosition[indice].x=this->cVerts[j].Vertex[0]; this->mGeoMesh->mSubMesh[0].mVertexBuffer->mPosition[indice].y=this->cVerts[j].Vertex[1]; this->mGeoMesh->mSubMesh[0].mVertexBuffer->mPosition[indice].z=this->cVerts[j].Vertex[2]; //Copiamos las normales if (meshoriginal->mSubMesh[0].mVertexBuffer->mVertexInfo & Geometry::VERTEX_NORMAL) { this->mGeoMesh->mSubMesh[0].mVertexBuffer->mNormal[indice].x=this->cVerts[j].Normal[0]; this->mGeoMesh->mSubMesh[0].mVertexBuffer->mNormal[indice].y=this->cVerts[j].Normal[1]; this->mGeoMesh->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->mGeoMesh->mSubMesh[0].mVertexBuffer->mTexCoords[indice].x=this->cVerts[j].TexCoords[0]; this->mGeoMesh->mSubMesh[0].mVertexBuffer->mTexCoords[indice].y=this->cVerts[j].TexCoords[1]; } indice++; } this->mGeoMesh->mSubMesh[0].mVertexBuffer->mVertexCount =indice; } int indice_acum = 0; for(size_t i = 0; i < this->mGeoMesh->mSubMeshCount; i++) { Geometry::SubMesh & subMesh = meshoriginal->mSubMesh[i]; Geometry::SubMesh & mGeoMeshSubMesh = this->mGeoMesh->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],mGeoMeshSubMesh.mVertexBuffer->mPosition[indvo])) { if (igual(subMesh.mVertexBuffer->mNormal[indIndex],mGeoMeshSubMesh.mVertexBuffer->mNormal[indvo])) { if (igual(subMesh.mVertexBuffer->mTexCoords[indIndex],mGeoMeshSubMesh.mVertexBuffer->mTexCoords[indvo])) { mGeoMeshSubMesh.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],mGeoMeshSubMesh.mVertexBuffer->mPosition[indvo])) { if (igual(subMesh.mVertexBuffer->mTexCoords[indIndex],mGeoMeshSubMesh.mVertexBuffer->mTexCoords[indvo])) { mGeoMeshSubMesh.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],mGeoMeshSubMesh.mVertexBuffer->mPosition[indvo])) { if (igual(subMesh.mVertexBuffer->mNormal[indIndex],mGeoMeshSubMesh.mVertexBuffer->mNormal[indvo])) { mGeoMeshSubMesh.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],mGeoMeshSubMesh.mVertexBuffer->mPosition[indvo])) { mGeoMeshSubMesh.mIndex[ind]=int(indvo);//+indice_acum; } } } } } } // Sort submesh bones. this->sortBones(); } //--------------------------------------------------------------------------- // Add new vertices to mesh. //--------------------------------------------------------------------------- void LodStripsConstructor::AddNewVertices() { int num_vertices; SubMesh *geosubmesh; VertexBuffer *vertex_buffer; VertexBuffer *new_vertex_buffer; // Gets old vertex buffer. vertex_buffer = mGeoMesh->mVertexBuffer; num_vertices = vertex_buffer->mVertexCount + mGeoMeshSQ->mNewVertices.size(); // Initialize auxiliar vertex buffer. new_vertex_buffer = new VertexBuffer(); new_vertex_buffer->mVertexCount = num_vertices; new_vertex_buffer->mPosition = new Vector3[num_vertices]; new_vertex_buffer->mNormal = new Vector3[num_vertices]; new_vertex_buffer->mTexCoords = new Vector2[num_vertices]; new_vertex_buffer->mVertexInfo = vertex_buffer->mVertexInfo; // Num old vertices. num_vertices = vertex_buffer->mVertexCount; // Copy the old vertex buffer. for (unsigned int i = 0; i < num_vertices; i++) { new_vertex_buffer->mPosition[i] = vertex_buffer->mPosition[i]; new_vertex_buffer->mNormal[i] = vertex_buffer->mNormal[i]; new_vertex_buffer->mTexCoords[i]= vertex_buffer->mTexCoords[i]; } // Copy new vertices. for (unsigned int i = 0; i < mGeoMeshSQ->mNewVertices.size(); i++) { new_vertex_buffer->mPosition[num_vertices + i] = mGeoMeshSQ->mNewVertices[i].position; new_vertex_buffer->mTexCoords[num_vertices + i] = mGeoMeshSQ->mNewVertices[i].texcoord; new_vertex_buffer->mNormal[num_vertices + i] = mGeoMeshSQ->mNewVertices[i].normal; // check if my twin-vertex-bone has a bone assignment // we check only the GeoMesh bones because the lodstrips only works for sharedvertex bones for (std::vector::iterator it = mGeoMesh->mBones.begin(); it != mGeoMesh->mBones.end(); it ++) { if (it->vertexIndex == mGeoMeshSQ->mNewVertices[i].bonefrom) { VertexBoneAssignment vba; vba.boneIndex = it->boneIndex; vba.vertexIndex = mGeoMeshSQ->mNewVertices[i].id; vba.weight = it->weight; mGeoMesh->mBones.push_back(vba); } } } // For each submesh. for (unsigned int submesh = 0; submesh < mGeoMesh->mSubMeshCount; submesh++) { geosubmesh = &mGeoMesh->mSubMesh[submesh]; geosubmesh->mVertexBuffer = new_vertex_buffer; } delete vertex_buffer; mGeoMesh->mVertexBuffer = new_vertex_buffer; }