#include #include #include #include "Foliage.h" //-------------------------------------------------------------------------------------------------------------------------------- // Void constructor // Parameters --> None //-------------------------------------------------------------------------------------------------------------------------------- Foliage::Foliage(int leavessubmeshID, const Geometry::SubMesh *leavesSubMesh, const Geometry::TreeSimplificationSequence * simpSeq/*, Geometry::CREATEVERTEXDATAFUNC vdfun*/): Acth(NULL), //create_vertex_data_func(vdfun==NULL?Geometry::DefaultVertexDataCreator:vdfun), //create_index_data_func(idfun==NULL?Geometry::DefaultIndexDataCreator:idfun), /*vertexdata(NULL),*/ Leaves(NULL), MinDet(NULL) { begin = final = -1; // indexdata=NULL; // ReadVertices(leavesSubMesh); int countv= int(leavesSubMesh->mVertexBuffer->mVertexCount); Leaves = new RuntimeLeaf[countv*2]; TotalVerts = countv; ReadLeafs(leavesSubMesh); if (!ReadSimpSeq(simpSeq)) exit(1); FillRoot(); // CalculateTexCoordsAndNorms(); // indexdata->SetNumValidIndices(0); int h=0; Acth = new ActiveLeafNode[leafCount*8]; for (h=0; h < leafCount; h++) { Acth[h].index = h; if ( h != 0) { Acth[h].prev = (h-1); Acth[h-1].next = h; } } begin = 0; final = leafCount-1; active_leaf_count = leafCount; leavesSubMeshID=leavessubmeshID; } //-------------------------------------------------------------------------------------------------------------------------------- // Destructor. We must deallocate the memory allocated for pointers to vertices and edges //-------------------------------------------------------------------------------------------------------------------------------- Foliage::~Foliage (void) { // if (vertexdata) delete vertexdata; // if (indexdata) delete indexdata; delete[] Leaves; delete MinDet; delete Acth; } /****************************************** CRITERIO **************************************************/ //--------------------------------------------------------------------------------------------------------- // es activo? //--------------------------------------------------------------------------------------------------------- bool Foliage::IsActive (int num) const { return ( (Acth[num].prev != -1) || (Acth[num].next != -1)); } void Foliage::CalculateLOD(int nleaves) { if ((nleaves <= leafCount) && (nleaves > minLeaves)) { if ( nleaves < active_leaf_count) { RCecol (active_leaf_count - nleaves); } else { RCsplit (nleaves-active_leaf_count); } active_leaf_count = nleaves; } } void Foliage::RCecol ( int num) { int j, h; j = num; h = final+1; while ((h<=leafTotal) && (j>0)) { while (( begin == Leaves[h].childLeft) || ( begin == Leaves[h].childRight)) begin = Acth[begin].next; while (( final == Leaves[h].childLeft) || ( final == Leaves[h].childRight)) final = Acth[final].prev; if (Acth[Leaves[h].childLeft].next != -1) Acth[Acth[Leaves[h].childLeft].next].prev = Acth[Leaves[h].childLeft].prev; if (Acth[Leaves[h].childLeft].prev != -1) Acth[Acth[Leaves[h].childLeft].prev].next = Acth[Leaves[h].childLeft].next; if (Acth[Leaves[h].childRight].next != -1) Acth[Acth[Leaves[h].childRight].next].prev = Acth[Leaves[h].childRight].prev; if (Acth[Leaves[h].childRight].prev != -1) Acth[Acth[Leaves[h].childRight].prev].next = Acth[Leaves[h].childRight].next; // desconecto a los hijos Acth[Leaves[h].childLeft].prev = -1; Acth[Leaves[h].childLeft].next = -1; Acth[Leaves[h].childRight].prev = -1; Acth[Leaves[h].childRight].next = -1; //añado al final Acth[h].prev = final; Acth[h].next = -1; Acth[final].next = h; final = h; // decremento el contador de colapsos j--; //incremento el posible siguiente colapso h++; } } int Foliage::PrevActive(int h) { int i; if (begin > h) i = -1; else { i = h--; while (IsActive(i) == false) i--; } return (i); } int Foliage::NextActive(int h) { int i; i = h++; while ((IsActive(i) == false) || (i> leafTotal)) i++; if (i > leafTotal) i=-1; return (i); } void Foliage::RCsplit ( int num) { int j, h, ant, post; j = num; h = final; while (h>leafCount && j>0) { ///////////// insertar a los hijos en orden segun su indice //hijo izquierdo ant = PrevActive(Leaves[h].childLeft); post = NextActive(Leaves[h].childLeft); Acth[Leaves[h].childLeft].next = post; Acth[Leaves[h].childLeft].prev = ant; if (ant != -1) Acth[ant].next = Leaves[h].childLeft; else begin = Leaves[h].childLeft; if (post != -1) Acth[post].prev = Leaves[h].childLeft; //hijo derecho ant = PrevActive(Leaves[h].childRight); post = NextActive(Leaves[h].childRight); Acth[Leaves[h].childRight].next = post; Acth[Leaves[h].childRight].prev = ant; if (ant != -1) Acth[ant].next = Leaves[h].childRight; else begin = Leaves[h].childRight; if (post != -1) Acth[post].prev = Leaves[h].childRight; // despues de insertar los hijos miro a ver cual spliteare el siguiente final = Acth[h].prev; //y desconecto al padre if ( Acth[h].prev != -1) Acth[Acth[h].prev].next = Acth[h].next; //if ( Acth[h].next != -1) // Acth[Acth[h].next].prev = Acth[h].prev; Acth[h].prev = -1; Acth[h].next = -1; // decremento el contador de colapsos j--; //incremento el posible siguiente colapso h--; } } /* void Foliage::ReadVertices(const Geometry::SubMesh *submesh) { int countv= int(submesh->mVertexBuffer->mVertexCount); vertexdata = create_vertex_data_func(2*countv); Leaves = new Leaf[countv*2]; //indexdata = create_index_data_func(countv*2*3); // 3 indices x 2 triangulos x hoja vertexdata->Begin(); for (int i=0; iSetVertexCoord( i, submesh->mVertexBuffer->mPosition[i].x, submesh->mVertexBuffer->mPosition[i].y, submesh->mVertexBuffer->mPosition[i].z ); } vertexdata->End(); TotalVerts = countv; } void Foliage::GetNormalH (Leaf &aleaf) { float onex, oney, onez; float twox, twoy, twoz; float threex, threey, threez; vertexdata->GetVertexCoord(aleaf.vertsLeaf[0],onex,oney,onez); vertexdata->GetVertexCoord(aleaf.vertsLeaf[1],twox,twoy,twoz); vertexdata->GetVertexCoord(aleaf.vertsLeaf[2],threex,threey,threez); float v1[3]={twox-onex,twoy-oney,twoz-onez}; float v2[3]={threex-onex,threey-oney,threez-onez}; Normalize(v1,v1); Normalize(v2,v2); // aleaf.Normal[0] = (twoz-onez)*(threey-oney) - (twoy-oney)*(threez-onez); // aleaf.Normal[1] = (twox-onex)*(threez-onez) - (threex-onex)*(twoz-onez); // aleaf.Normal[2] = (threex-onex)*(twoy-oney) - (twox-onex)*(threey-oney); CrossProduct(v1,v2,aleaf.normal); } void Foliage::CrossProduct(const float *v1, const float *v2, float *res) { res[0] = v1[1]*v2[2] - v1[2]*v2[1]; res[1] = v1[2]*v2[0] - v1[0]*v2[2]; res[2] = v1[0]*v2[1] - v1[1]*v2[0]; } void Foliage::Normalize(const float *v, float *res) { float module=sqrtf(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]); res[0]=v[0]/module; res[1]=v[1]/module; res[2]=v[2]/module; } */ void Foliage::ReadLeafs(const Geometry::SubMesh *submesh) { int numtris = int(submesh->mIndexCount / 3); leafCount = numtris / 2; for (int h=0; hmIndex[h*6+0]; Leaves[h].vertsLeaf[1] = submesh->mIndex[h*6+1]; Leaves[h].vertsLeaf[2] = submesh->mIndex[h*6+2]; Leaves[h].vertsLeaf[3] = submesh->mIndex[h*6+5]; // Leaves[h].visible = 0; // GetNormalH ( Leaves[h]); } } /// returns the number of total leafs bool Foliage::ReadSimpSeq(const Geometry::TreeSimplificationSequence * simpSeq) { int tn, tv1,tv2, e=0; tn = leafCount; for (std::vector::const_iterator it = simpSeq->mSteps.begin(); it != simpSeq->mSteps.end(); it++) { Leaves[tn].vertsLeaf[0] = it->mNewQuad[0]; Leaves[tn].vertsLeaf[1] = it->mNewQuad[1]; Leaves[tn].vertsLeaf[2] = it->mNewQuad[2]; Leaves[tn].vertsLeaf[3] = it->mNewQuad[3]; // Leaves[tn].visible = 0; // GetNormalH (Leaves[tn]); tv1 = it->mV0/2; tv2 = it->mT0/2; Leaves[tn].childLeft= tv1; Leaves[tn].childRight= tv2; Leaves[tv1].parent = tn; Leaves[tv2].parent = tn; tn++; } /* FILE* fp_simpli; char linea[256]; int v0, v1, v2, v3, tn, tv1,tv2, e=0; if ((fp_simpli = fopen (simpSeqFile, "r")) == NULL) { printf ("No he podido abrir el fichero %s\n", simpSeqFile); return false; } else { tn = leafCount; while (fgets (linea, 255, fp_simpli) != NULL) { if (linea[0]<'0' || linea[0]>'9') continue; long int triviej00=-1, triviej01=-1; long int triviej10=-1, triviej11=-1; sscanf(linea, "%lu %lu %lu %lu & %lu %lu %lu %lu", &triviej00,&triviej01,&triviej10,&triviej11, &v0,&v1,&v2,&v3); Leaves[tn].vertsLeaf[0] = v0; Leaves[tn].vertsLeaf[1] = v1; Leaves[tn].vertsLeaf[2] = v2; Leaves[tn].vertsLeaf[3] = v3; Leaves[tn].visible = 0; GetNormalH (Leaves[tn]); tv1 = triviej00/2; tv2 = triviej10/2; Leaves[tn].childLeft= tv1; Leaves[tn].childRight= tv2; Leaves[tv1].parent = tn; Leaves[tv2].parent = tn; tn++; } } fclose(fp_simpli);*/ leafTotal=tn; return true; } void Foliage::FillRoot(void) { int i,j, k, t, cont; bool esta, fin; i=0; k=-1; cont =-1; MinDet = new ActiveLeafNode[leafCount*2]; while (i-1) j=Leaves[j].parent; Leaves[i].root = j; // para la estructura MinDet if ( k == -1){ k++; MinDet[k].index = j; cont =k; } else { t = 0; esta = false; fin = false; while (( fin == false) && (esta == false)) { if ( MinDet[t].index == j) esta = true; else t++; if (MinDet[t].index == -1) fin = true; } if ( esta == false) { cont++; MinDet[cont].index = j; } } i++; } minLeaves = cont; } /*void Foliage::CalculateTexCoordsAndNorms(void) { vertexdata->Begin(); for (int i=0; iSetVertexNormal(Leaves[i].vertsLeaf[0], lanormal[0], lanormal[1], lanormal[2]); vertexdata->SetVertexTexCoord(Leaves[i].vertsLeaf[0], 0.0f, 1.0f); vertexdata->SetVertexNormal(Leaves[i].vertsLeaf[1], lanormal[0], lanormal[1], lanormal[2]); vertexdata->SetVertexTexCoord(Leaves[i].vertsLeaf[1], 0.0f, 0.0f); vertexdata->SetVertexNormal(Leaves[i].vertsLeaf[2], lanormal[0], lanormal[1], lanormal[2]); vertexdata->SetVertexTexCoord(Leaves[i].vertsLeaf[2], 1.0f, 1.0f); vertexdata->SetVertexNormal(Leaves[i].vertsLeaf[3], lanormal[0], lanormal[1], lanormal[2]); vertexdata->SetVertexTexCoord(Leaves[i].vertsLeaf[3], 1.0f, 0.0f); } vertexdata->End(); } */ Foliage::Foliage(const Foliage *ar) { leafCount = ar->leafCount; MinDet = new ActiveLeafNode[leafCount*2]; // for (unsigned int i=0; iMinDet[i]; memcpy(MinDet,ar->MinDet,sizeof(ActiveLeafNode)*leafCount*2); leafTotal=ar->leafTotal; minLeaves=ar->minLeaves; TotalVerts=ar->TotalVerts; /* create_vertex_data_func=ar->create_vertex_data_func; // create_index_data_func=ar->create_index_data_func; vertexdata=create_vertex_data_func(ar->vertexdata->GetNumVertices()); vertexdata->Begin(); for (unsigned int i=0; iGetNumVertices(); i++) { float va,vb,vc; ar->vertexdata->GetVertexCoord(i,va,vb,vc); vertexdata->SetVertexCoord(i,va,vb,vc); ar->vertexdata->GetVertexNormal(i,va,vb,vc); vertexdata->SetVertexNormal(i,va,vb,vc); } vertexdata->End();*/ /* indexdata=create_index_data_func(ar->indexdata->GetNumMaxIndices()); indexdata->Begin(ar->leavesSubMeshID,indexdata->GetNumMaxIndices()); for (unsigned int i=0; iGetNumMaxIndices(); i++) indexdata->SetIndex(i,ar->indexdata->GetIndex(i)); indexdata->End();*/ Leaves=new RuntimeLeaf[TotalVerts]; // for (unsigned int i=0; iGetNumVertices(); i++) // Leaves[i]=ar->Leaves[i]; memcpy(Leaves,ar->Leaves,sizeof(Leaf)*TotalVerts); // esto no sé si devería haber akí // indexdata->SetNumValidIndices(0); int h=0; Acth = new ActiveLeafNode[leafCount*8]; for ( h=0; h < leafCount; h++) { Acth[h].index = h; if ( h != 0) { Acth[h].prev = (h-1); Acth[h-1].next = h; } } begin = 0; final = leafCount-1; active_leaf_count = leafCount; }