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.

Line 
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//--------------------------------------------------------------------------------------------------------------------------------
12Foliage::Foliage(int leavessubmeshID,
13                                 const Geometry::SubMesh *leavesSubMesh,
14                                 const Geometry::TreeSimplificationSequence * simpSeq/*,
15                                 Geometry::CREATEVERTEXDATAFUNC vdfun*/):
16Acth(NULL),
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)
20{
21        begin = final = -1;
22//      indexdata=NULL;
23
24//      ReadVertices(leavesSubMesh);
25        int countv= int(leavesSubMesh->mVertexBuffer->mVertexCount);
26        Leaves = new RuntimeLeaf[countv*2];
27        TotalVerts = countv;
28
29        ReadLeafs(leavesSubMesh);
30        if (!ReadSimpSeq(simpSeq)) exit(1);
31        FillRoot();
32//      CalculateTexCoordsAndNorms();
33
34//      indexdata->SetNumValidIndices(0);
35
36        int h=0;
37
38        Acth  = new ActiveLeafNode[leafCount*8];
39
40        for (h=0; h < leafCount; h++) {
41
42                Acth[h].index = h;
43                if ( h != 0)
44                {
45                        Acth[h].prev = (h-1);
46                        Acth[h-1].next = h;
47                }
48
49        }
50                               
51        begin = 0;
52        final = leafCount-1;
53        active_leaf_count = leafCount;
54        leavesSubMeshID=leavessubmeshID;
55}
56
57//--------------------------------------------------------------------------------------------------------------------------------
58// Destructor. We must deallocate the memory allocated for pointers to vertices and edges
59//--------------------------------------------------------------------------------------------------------------------------------
60Foliage::~Foliage (void)
61{
62//      if (vertexdata) delete vertexdata;
63//      if (indexdata) delete indexdata;
64        delete[] Leaves;
65        delete MinDet;
66        delete Acth;
67}
68
69/******************************************   CRITERIO **************************************************/
70
71
72
73//---------------------------------------------------------------------------------------------------------
74// es activo?
75//---------------------------------------------------------------------------------------------------------
76
77bool Foliage::IsActive (int num) const
78{
79        return ( (Acth[num].prev != -1) || (Acth[num].next != -1));
80}
81
82
83
84void Foliage::CalculateLOD(int nleaves)
85{
86        if ((nleaves <= leafCount) && (nleaves > minLeaves))
87        {
88                if ( nleaves < active_leaf_count) {
89                        RCecol (active_leaf_count - nleaves);
90                }
91                else  {
92                         RCsplit (nleaves-active_leaf_count);
93                }
94
95                active_leaf_count = nleaves;
96        }
97
98}
99
100
101void Foliage::RCecol ( int num)
102{
103
104        int  j, h;
105
106        j = num;
107        h = final+1;
108                while ((h<=leafTotal) && (j>0))
109                {
110                        while (( begin == Leaves[h].childLeft) || ( begin == Leaves[h].childRight))
111                                begin = Acth[begin].next;
112
113                        while (( final == Leaves[h].childLeft) || ( final == Leaves[h].childRight))
114                                final = Acth[final].prev;
115
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;
120
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;
125
126       
127                        //  desconecto a los hijos
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;
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
147int Foliage::PrevActive(int h)
148{
149        int i;
150
151       
152        if (begin > h)  i = -1;
153        else
154        {
155                i = h--;
156       
157                while (IsActive(i) == false)   
158                        i--;
159        }
160
161        return (i);
162}
163
164int Foliage::NextActive(int h)
165{       int i;
166
167        i = h++;
168       
169        while ((IsActive(i) == false) || (i> leafTotal))
170                i++;
171
172        if (i > leafTotal) i=-1;
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;
185        while (h>leafCount &&  j>0)
186        {
187                ///////////// insertar a los hijos en orden segun su indice
188                //hijo izquierdo
189                ant = PrevActive(Leaves[h].childLeft);
190                post = NextActive(Leaves[h].childLeft);
191
192
193                Acth[Leaves[h].childLeft].next = post;
194                Acth[Leaves[h].childLeft].prev = ant;
195                if (ant != -1) Acth[ant].next = Leaves[h].childLeft;
196                        else begin = Leaves[h].childLeft;
197                if (post != -1) Acth[post].prev = Leaves[h].childLeft;
198
199               
200                //hijo derecho
201                ant = PrevActive(Leaves[h].childRight);
202                post = NextActive(Leaves[h].childRight);
203
204
205                Acth[Leaves[h].childRight].next = post;
206                Acth[Leaves[h].childRight].prev = ant;
207                if (ant != -1)  Acth[ant].next = Leaves[h].childRight;
208                                else begin = Leaves[h].childRight;
209                if (post != -1) Acth[post].prev = Leaves[h].childRight;
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 }
233/*
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];
239        //indexdata = create_index_data_func(countv*2*3); // 3 indices x 2 triangulos x hoja
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
250        TotalVerts = countv;
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}
293*/
294void Foliage::ReadLeafs(const Geometry::SubMesh *submesh)
295{
296        int numtris = int(submesh->mIndexCount / 3);
297        leafCount =  numtris / 2;
298        for (int h=0; h<leafCount; h++)
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];
304//              Leaves[h].visible = 0;
305
306//              GetNormalH ( Leaves[h]);
307        }
308}
309
310/// returns the number of total leafs
311bool Foliage::ReadSimpSeq(const Geometry::TreeSimplificationSequence * simpSeq)
312{
313        int tn, tv1,tv2, e=0;
314
315        tn = leafCount;
316        for (std::vector<Geometry::TreeSimplificationSequence::Step>::const_iterator it = simpSeq->mSteps.begin(); it != simpSeq->mSteps.end(); it++)
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
323//              Leaves[tn].visible = 0;
324
325//              GetNormalH  (Leaves[tn]);
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;
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        {
350                tn = leafCount;
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
383        fclose(fp_simpli);*/
384
385        leafTotal=tn;
386               
387        return true;
388}
389
390void Foliage::FillRoot(void)
391{
392        int i,j, k, t, cont;
393        bool esta, fin;
394
395        i=0;
396        k=-1;
397        cont =-1;
398
399        MinDet  = new ActiveLeafNode[leafCount*2];
400       
401        while (i<leafTotal)
402        {
403                j=i;
404                while (Leaves[j].parent>-1) j=Leaves[j].parent;
405                Leaves[i].root = j;
406
407
408                // para la estructura MinDet
409                if ( k == -1){
410                        k++;
411                        MinDet[k].index = j;
412                        cont =k;
413                }
414                else
415                {
416                        t = 0;
417                        esta = false;
418                        fin = false;
419
420                        while (( fin == false) && (esta == false))
421                        {       if ( MinDet[t].index == j) esta = true;
422                                        else t++;
423                                if (MinDet[t].index == -1) fin = true;
424                        }
425
426                        if ( esta == false)
427                        {
428                                cont++;
429                                MinDet[cont].index = j;
430                        }
431                }
432
433                i++;
434        }       
435
436        minLeaves = cont;
437
438}
439
440/*void Foliage::CalculateTexCoordsAndNorms(void)
441{       
442        vertexdata->Begin();
443        for (int i=0; i<leafCount; i++)
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}
460*/
461Foliage::Foliage(const Foliage *ar)
462{
463        leafCount = ar->leafCount;
464        MinDet = new ActiveLeafNode[leafCount*2];
465//      for (unsigned int i=0; i<nHojas*2; i++)
466//              MinDet[i]=ar->MinDet[i];
467        memcpy(MinDet,ar->MinDet,sizeof(ActiveLeafNode)*leafCount*2);
468        leafTotal=ar->leafTotal;
469        minLeaves=ar->minLeaves;
470        TotalVerts=ar->TotalVerts;
471
472/*      create_vertex_data_func=ar->create_vertex_data_func;
473//      create_index_data_func=ar->create_index_data_func;
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        }
484        vertexdata->End();*/
485/*      indexdata=create_index_data_func(ar->indexdata->GetNumMaxIndices());
486        indexdata->Begin(ar->leavesSubMeshID,indexdata->GetNumMaxIndices());
487        for (unsigned int i=0; i<indexdata->GetNumMaxIndices(); i++)
488                indexdata->SetIndex(i,ar->indexdata->GetIndex(i));
489        indexdata->End();*/
490
491        Leaves=new RuntimeLeaf[TotalVerts];
492//      for (unsigned int i=0; i<vertexdata->GetNumVertices(); i++)
493//              Leaves[i]=ar->Leaves[i];
494        memcpy(Leaves,ar->Leaves,sizeof(Leaf)*TotalVerts);
495
496        // esto no sé si devería haber akí
497//      indexdata->SetNumValidIndices(0);
498
499        int h=0;
500
501        Acth  = new ActiveLeafNode[leafCount*8];
502
503        for ( h=0; h < leafCount; h++) {
504
505                Acth[h].index = h;
506                if ( h != 0)
507                {
508                        Acth[h].prev = (h-1);
509                        Acth[h-1].next = h;
510                }
511
512        }
513                               
514        begin = 0;
515        final = leafCount-1;
516        active_leaf_count = leafCount;
517
518}
Note: See TracBrowser for help on using the repository browser.