source: GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/leaves/foliage.cpp @ 1526

Revision 1526, 12.6 KB checked in by gumbau, 18 years ago (diff)

Updated modules to the new interface and the new simplification algorithm improvements.

RevLine 
[830]1#include <stdio.h>
2#include <string.h>
3#include <math.h>
4
5#include "Foliage.h"
6
7
8//--------------------------------------------------------------------------------------------------------------------------------
9// Void constructor
10// Parameters --> None
11//--------------------------------------------------------------------------------------------------------------------------------
[1526]12Foliage::Foliage(int leavessubmeshID,
13                                 const Geometry::SubMesh *leavesSubMesh,
14                                 const Geometry::TreeSimplificationSequence * simpSeq/*,
15                                 Geometry::CREATEVERTEXDATAFUNC vdfun*/):
[1019]16Acth(NULL),
[1526]17//create_vertex_data_func(vdfun==NULL?Geometry::DefaultVertexDataCreator:vdfun),
18//create_index_data_func(idfun==NULL?Geometry::DefaultIndexDataCreator:idfun),
19/*vertexdata(NULL),*/ Leaves(NULL), MinDet(NULL)
[830]20{
[1058]21        begin = final = -1;
[1526]22//      indexdata=NULL;
[1019]23
[1526]24//      ReadVertices(leavesSubMesh);
25        int countv= int(leavesSubMesh->mVertexBuffer->mVertexCount);
26        Leaves = new RuntimeLeaf[countv*2];
27        TotalVerts = countv;
28
[1019]29        ReadLeafs(leavesSubMesh);
30        if (!ReadSimpSeq(simpSeq)) exit(1);
[1058]31        FillRoot();
[1526]32//      CalculateTexCoordsAndNorms();
[1019]33
[1526]34//      indexdata->SetNumValidIndices(0);
[1019]35
36        int h=0;
37
[1058]38        Acth  = new ActiveLeafNode[leafCount*8];
[1019]39
[1058]40        for (h=0; h < leafCount; h++) {
[1019]41
[1057]42                Acth[h].index = h;
[1019]43                if ( h != 0)
44                {
45                        Acth[h].prev = (h-1);
46                        Acth[h-1].next = h;
47                }
48
49        }
50                               
[1058]51        begin = 0;
52        final = leafCount-1;
53        active_leaf_count = leafCount;
[1526]54        leavesSubMeshID=leavessubmeshID;
[830]55}
56
57//--------------------------------------------------------------------------------------------------------------------------------
58// Destructor. We must deallocate the memory allocated for pointers to vertices and edges
59//--------------------------------------------------------------------------------------------------------------------------------
60Foliage::~Foliage (void)
61{
[1526]62//      if (vertexdata) delete vertexdata;
63//      if (indexdata) delete indexdata;
[1019]64        delete[] Leaves;
65        delete MinDet;
[830]66        delete Acth;
67}
68
69/******************************************   CRITERIO **************************************************/
70
71
72
73//---------------------------------------------------------------------------------------------------------
74// es activo?
75//---------------------------------------------------------------------------------------------------------
76
[1057]77bool Foliage::IsActive (int num) const
[830]78{
79        return ( (Acth[num].prev != -1) || (Acth[num].next != -1));
80}
81
82
83
[1058]84void Foliage::CalculateLOD(int nleaves)
[830]85{
[1058]86        if ((nleaves <= leafCount) && (nleaves > minLeaves))
[830]87        {
[1058]88                if ( nleaves < active_leaf_count) {
89                        RCecol (active_leaf_count - nleaves);
[830]90                }
91                else  {
[1058]92                         RCsplit (nleaves-active_leaf_count);
[830]93                }
94
[1058]95                active_leaf_count = nleaves;
[830]96        }
97
98}
99
100
101void Foliage::RCecol ( int num)
102{
103
104        int  j, h;
105
106        j = num;
107        h = final+1;
[1058]108                while ((h<=leafTotal) && (j>0))
[830]109                {
[1058]110                        while (( begin == Leaves[h].childLeft) || ( begin == Leaves[h].childRight))
111                                begin = Acth[begin].next;
[830]112
[1019]113                        while (( final == Leaves[h].childLeft) || ( final == Leaves[h].childRight))
[830]114                                final = Acth[final].prev;
115
[1019]116                        if (Acth[Leaves[h].childLeft].next != -1)
117                                Acth[Acth[Leaves[h].childLeft].next].prev = Acth[Leaves[h].childLeft].prev;
118                        if (Acth[Leaves[h].childLeft].prev != -1)
119                                Acth[Acth[Leaves[h].childLeft].prev].next = Acth[Leaves[h].childLeft].next;
[830]120
[1019]121                        if (Acth[Leaves[h].childRight].next != -1)
122                                Acth[Acth[Leaves[h].childRight].next].prev = Acth[Leaves[h].childRight].prev;
123                        if (Acth[Leaves[h].childRight].prev != -1)
124                                Acth[Acth[Leaves[h].childRight].prev].next = Acth[Leaves[h].childRight].next;
[830]125
126       
127                        //  desconecto a los hijos
[1019]128                        Acth[Leaves[h].childLeft].prev = -1;
129                        Acth[Leaves[h].childLeft].next = -1;
130                        Acth[Leaves[h].childRight].prev = -1;
131                        Acth[Leaves[h].childRight].next = -1;
[830]132
133                        //añado al final
134                        Acth[h].prev = final;
135                        Acth[h].next = -1;
136                        Acth[final].next = h;
137                        final = h;
138
139
140                        // decremento el contador de colapsos
141                        j--;
142                        //incremento el posible siguiente colapso
143                        h++;
144                }
145}
146
[1058]147int Foliage::PrevActive(int h)
[830]148{
149        int i;
150
151       
[1058]152        if (begin > h)  i = -1;
[830]153        else
154        {
155                i = h--;
156       
[1057]157                while (IsActive(i) == false)   
[830]158                        i--;
159        }
160
161        return (i);
162}
163
[1058]164int Foliage::NextActive(int h)
[830]165{       int i;
166
167        i = h++;
168       
[1058]169        while ((IsActive(i) == false) || (i> leafTotal))
[830]170                i++;
171
[1058]172        if (i > leafTotal) i=-1;
[830]173
174
175        return (i);
176}
177
178void Foliage::RCsplit ( int num)
179{
180
181        int  j, h, ant, post;
182
183        j = num;
184        h = final;
[1058]185        while (h>leafCount &&  j>0)
[830]186        {
187                ///////////// insertar a los hijos en orden segun su indice
188                //hijo izquierdo
[1058]189                ant = PrevActive(Leaves[h].childLeft);
190                post = NextActive(Leaves[h].childLeft);
[830]191
192
[1019]193                Acth[Leaves[h].childLeft].next = post;
194                Acth[Leaves[h].childLeft].prev = ant;
195                if (ant != -1) Acth[ant].next = Leaves[h].childLeft;
[1058]196                        else begin = Leaves[h].childLeft;
[1019]197                if (post != -1) Acth[post].prev = Leaves[h].childLeft;
[830]198
199               
200                //hijo derecho
[1058]201                ant = PrevActive(Leaves[h].childRight);
202                post = NextActive(Leaves[h].childRight);
[830]203
204
[1019]205                Acth[Leaves[h].childRight].next = post;
206                Acth[Leaves[h].childRight].prev = ant;
207                if (ant != -1)  Acth[ant].next = Leaves[h].childRight;
[1058]208                                else begin = Leaves[h].childRight;
[1019]209                if (post != -1) Acth[post].prev = Leaves[h].childRight;
[830]210
211
212                // despues de insertar los hijos miro a ver cual spliteare el siguiente
213                final = Acth[h].prev;
214               
215                //y desconecto al padre
216                if ( Acth[h].prev != -1)
217                        Acth[Acth[h].prev].next = Acth[h].next;
218                //if ( Acth[h].next != -1)
219                //      Acth[Acth[h].next].prev = Acth[h].prev;
220                Acth[h].prev = -1;
221                Acth[h].next = -1;
222       
223                // decremento el contador de colapsos
224                j--;
225                //incremento el posible siguiente colapso
226                h--;
227
228
229        }
230
231
232 }
[1526]233/*
[1019]234void Foliage::ReadVertices(const Geometry::SubMesh *submesh)
235{
236        int countv= int(submesh->mVertexBuffer->mVertexCount);
237        vertexdata = create_vertex_data_func(2*countv);
238        Leaves = new Leaf[countv*2];
[1526]239        //indexdata = create_index_data_func(countv*2*3); // 3 indices x 2 triangulos x hoja
[1019]240       
241        vertexdata->Begin();
242        for (int i=0; i<countv; i++)
243        {
244                vertexdata->SetVertexCoord( i,  submesh->mVertexBuffer->mPosition[i].x,
245                                                                                submesh->mVertexBuffer->mPosition[i].y,
246                                                                                submesh->mVertexBuffer->mPosition[i].z );
247        }
248        vertexdata->End();
249
[1058]250        TotalVerts = countv;
[1019]251}
252
253
254void Foliage::GetNormalH (Leaf &aleaf)
255{
256
257        float onex, oney, onez;
258        float twox, twoy, twoz;
259        float threex, threey, threez;
260
261        vertexdata->GetVertexCoord(aleaf.vertsLeaf[0],onex,oney,onez);
262        vertexdata->GetVertexCoord(aleaf.vertsLeaf[1],twox,twoy,twoz);
263        vertexdata->GetVertexCoord(aleaf.vertsLeaf[2],threex,threey,threez);
264
265        float v1[3]={twox-onex,twoy-oney,twoz-onez};
266        float v2[3]={threex-onex,threey-oney,threez-onez};
267
268        Normalize(v1,v1);
269        Normalize(v2,v2);
270       
271//      aleaf.Normal[0] = (twoz-onez)*(threey-oney) - (twoy-oney)*(threez-onez);
272//      aleaf.Normal[1] = (twox-onex)*(threez-onez) - (threex-onex)*(twoz-onez);
273//      aleaf.Normal[2] = (threex-onex)*(twoy-oney) - (twox-onex)*(threey-oney);
274
275        CrossProduct(v1,v2,aleaf.normal);
276       
277}
278
279void Foliage::CrossProduct(const float *v1, const float *v2, float *res)
280{
281        res[0] = v1[1]*v2[2] - v1[2]*v2[1];
282        res[1] = v1[2]*v2[0] - v1[0]*v2[2];
283        res[2] = v1[0]*v2[1] - v1[1]*v2[0];
284}
285
286void Foliage::Normalize(const float *v, float *res)
287{
288        float module=sqrtf(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
289        res[0]=v[0]/module;
290        res[1]=v[1]/module;
291        res[2]=v[2]/module;
292}
[1526]293*/
[1019]294void Foliage::ReadLeafs(const Geometry::SubMesh *submesh)
295{
296        int numtris = int(submesh->mIndexCount / 3);
[1058]297        leafCount =  numtris / 2;
298        for (int h=0; h<leafCount; h++)
[1019]299        {
300                Leaves[h].vertsLeaf[0] = submesh->mIndex[h*6+0];
301                Leaves[h].vertsLeaf[1] = submesh->mIndex[h*6+1];
302                Leaves[h].vertsLeaf[2] = submesh->mIndex[h*6+2];
303                Leaves[h].vertsLeaf[3] = submesh->mIndex[h*6+5];
[1526]304//              Leaves[h].visible = 0;
[1019]305
[1526]306//              GetNormalH ( Leaves[h]);
[1019]307        }
308}
309
310/// returns the number of total leafs
[1083]311bool Foliage::ReadSimpSeq(const Geometry::TreeSimplificationSequence * simpSeq)
[1019]312{
[1078]313        int tn, tv1,tv2, e=0;
314
315        tn = leafCount;
[1083]316        for (std::vector<Geometry::TreeSimplificationSequence::Step>::const_iterator it = simpSeq->mSteps.begin(); it != simpSeq->mSteps.end(); it++)
[1078]317        {
318                Leaves[tn].vertsLeaf[0] = it->mNewQuad[0];
319                Leaves[tn].vertsLeaf[1] = it->mNewQuad[1];
320                Leaves[tn].vertsLeaf[2] = it->mNewQuad[2];
321                Leaves[tn].vertsLeaf[3] = it->mNewQuad[3];
322
[1526]323//              Leaves[tn].visible = 0;
[1078]324
[1526]325//              GetNormalH  (Leaves[tn]);
[1078]326
327                tv1 = it->mV0/2;
328                tv2 = it->mT0/2;
329
330                Leaves[tn].childLeft= tv1;
331                Leaves[tn].childRight= tv2;
332
333                Leaves[tv1].parent = tn;
334                Leaves[tv2].parent = tn;               
335
336                tn++;
337        }
338
339/*      FILE* fp_simpli;
[1019]340        char linea[256];
341        int v0, v1, v2, v3, tn, tv1,tv2, e=0;
342
343        if ((fp_simpli = fopen (simpSeqFile, "r")) == NULL)
344        {
345                printf ("No he podido abrir el fichero %s\n", simpSeqFile);
346                return false;
347        }
348        else
349        {
[1058]350                tn = leafCount;
[1019]351                while (fgets (linea, 255, fp_simpli) != NULL)
352                {
353                        if (linea[0]<'0' || linea[0]>'9')
354                                continue;
355               
356                        long int triviej00=-1, triviej01=-1;
357                        long int triviej10=-1, triviej11=-1;
358                        sscanf(linea, "%lu %lu %lu %lu & %lu %lu %lu %lu", &triviej00,&triviej01,&triviej10,&triviej11, &v0,&v1,&v2,&v3);
359
360                        Leaves[tn].vertsLeaf[0] = v0;
361                        Leaves[tn].vertsLeaf[1] = v1;
362                        Leaves[tn].vertsLeaf[2] = v2;
363                        Leaves[tn].vertsLeaf[3] = v3;
364
365                        Leaves[tn].visible = 0;
366
367                        GetNormalH  (Leaves[tn]);
368
369                        tv1 = triviej00/2;
370                        tv2 = triviej10/2;
371
372                        Leaves[tn].childLeft= tv1;
373                        Leaves[tn].childRight= tv2;
374
375                        Leaves[tv1].parent = tn;
376                        Leaves[tv2].parent = tn;               
377
378                        tn++;
379                }
380
381        }
382
[1078]383        fclose(fp_simpli);*/
[1019]384
[1058]385        leafTotal=tn;
[1019]386               
387        return true;
388}
389
[1058]390void Foliage::FillRoot(void)
[1019]391{
392        int i,j, k, t, cont;
393        bool esta, fin;
394
395        i=0;
396        k=-1;
397        cont =-1;
398
[1058]399        MinDet  = new ActiveLeafNode[leafCount*2];
[1019]400       
[1058]401        while (i<leafTotal)
[1019]402        {
403                j=i;
[1058]404                while (Leaves[j].parent>-1) j=Leaves[j].parent;
[1019]405                Leaves[i].root = j;
406
407
408                // para la estructura MinDet
409                if ( k == -1){
410                        k++;
[1057]411                        MinDet[k].index = j;
[1019]412                        cont =k;
413                }
414                else
415                {
416                        t = 0;
417                        esta = false;
418                        fin = false;
419
420                        while (( fin == false) && (esta == false))
[1057]421                        {       if ( MinDet[t].index == j) esta = true;
[1019]422                                        else t++;
[1057]423                                if (MinDet[t].index == -1) fin = true;
[1019]424                        }
425
[1058]426                        if ( esta == false)
[1019]427                        {
428                                cont++;
[1057]429                                MinDet[cont].index = j;
[1019]430                        }
431                }
432
[1058]433                i++;
[1019]434        }       
435
[1058]436        minLeaves = cont;
[1019]437
438}
439
[1526]440/*void Foliage::CalculateTexCoordsAndNorms(void)
[1019]441{       
442        vertexdata->Begin();
[1058]443        for (int i=0; i<leafCount; i++)
[1019]444        {       
445                const float* lanormal = Leaves[i].normal;
446                vertexdata->SetVertexNormal(Leaves[i].vertsLeaf[0], lanormal[0], lanormal[1], lanormal[2]);
447                vertexdata->SetVertexTexCoord(Leaves[i].vertsLeaf[0], 0.0f, 1.0f);
448
449                vertexdata->SetVertexNormal(Leaves[i].vertsLeaf[1], lanormal[0], lanormal[1], lanormal[2]);
450                vertexdata->SetVertexTexCoord(Leaves[i].vertsLeaf[1], 0.0f, 0.0f);
451
452                vertexdata->SetVertexNormal(Leaves[i].vertsLeaf[2], lanormal[0], lanormal[1], lanormal[2]);
453                vertexdata->SetVertexTexCoord(Leaves[i].vertsLeaf[2], 1.0f, 1.0f);
454
455                vertexdata->SetVertexNormal(Leaves[i].vertsLeaf[3], lanormal[0], lanormal[1], lanormal[2]);
456                vertexdata->SetVertexTexCoord(Leaves[i].vertsLeaf[3], 1.0f, 0.0f);
457        }
458        vertexdata->End();
459}
[1526]460*/
[1019]461Foliage::Foliage(const Foliage *ar)
462{
[1058]463        leafCount = ar->leafCount;
464        MinDet = new ActiveLeafNode[leafCount*2];
[1019]465//      for (unsigned int i=0; i<nHojas*2; i++)
466//              MinDet[i]=ar->MinDet[i];
[1058]467        memcpy(MinDet,ar->MinDet,sizeof(ActiveLeafNode)*leafCount*2);
468        leafTotal=ar->leafTotal;
469        minLeaves=ar->minLeaves;
470        TotalVerts=ar->TotalVerts;
[1019]471
[1526]472/*      create_vertex_data_func=ar->create_vertex_data_func;
473//      create_index_data_func=ar->create_index_data_func;
[1019]474        vertexdata=create_vertex_data_func(ar->vertexdata->GetNumVertices());
475        vertexdata->Begin();
476        for (unsigned int i=0; i<vertexdata->GetNumVertices(); i++)
477        {
478                float va,vb,vc;
479                ar->vertexdata->GetVertexCoord(i,va,vb,vc);
480                vertexdata->SetVertexCoord(i,va,vb,vc);
481                ar->vertexdata->GetVertexNormal(i,va,vb,vc);
482                vertexdata->SetVertexNormal(i,va,vb,vc);
483        }
[1526]484        vertexdata->End();*/
485/*      indexdata=create_index_data_func(ar->indexdata->GetNumMaxIndices());
486        indexdata->Begin(ar->leavesSubMeshID,indexdata->GetNumMaxIndices());
[1019]487        for (unsigned int i=0; i<indexdata->GetNumMaxIndices(); i++)
488                indexdata->SetIndex(i,ar->indexdata->GetIndex(i));
[1526]489        indexdata->End();*/
[1019]490
[1526]491        Leaves=new RuntimeLeaf[TotalVerts];
[1019]492//      for (unsigned int i=0; i<vertexdata->GetNumVertices(); i++)
493//              Leaves[i]=ar->Leaves[i];
[1526]494        memcpy(Leaves,ar->Leaves,sizeof(Leaf)*TotalVerts);
[1019]495
496        // esto no sé si devería haber akí
[1526]497//      indexdata->SetNumValidIndices(0);
[1019]498
499        int h=0;
500
[1058]501        Acth  = new ActiveLeafNode[leafCount*8];
[1019]502
[1058]503        for ( h=0; h < leafCount; h++) {
[1019]504
[1057]505                Acth[h].index = h;
[1019]506                if ( h != 0)
507                {
508                        Acth[h].prev = (h-1);
509                        Acth[h-1].next = h;
510                }
511
512        }
513                               
[1058]514        begin = 0;
515        final = leafCount-1;
516        active_leaf_count = leafCount;
[1019]517
518}
Note: See TracBrowser for help on using the repository browser.