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

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