source: GTP/trunk/Lib/Geom/shared/GTGeometry/src/GeoLodStripsLibrary.cpp @ 1088

Revision 1088, 16.6 KB checked in by gumbau, 18 years ago (diff)

Fixed memory consumption issue

Line 
1/*==========================================================================
2 *      (C) 2005 Universitat Jaume I
3 *==========================================================================
4 *      PROYECT:        GAME TOOLS
5 *==========================================================================
6 *      CONTENT:
7 *
8 *
9 *      @file   GeoLodStripsLibrary.cpp
10 *===========================================================================*/
11
12#include "GeoLodStripsLibrary.h"
13
14using namespace Geometry;
15
16//-----------------------------------------------------------------------------
17//      Constructors.
18//-----------------------------------------------------------------------------
19LodStripsLibrary::LodStripsLibrary(const LodStripsLibraryData *lodstripsdata, Mesh *geomesh, CREATEINDEXDATAFUNC idfun)
20:create_index_data_func(idfun?idfun:DefaultIndexDataCreator)
21{
22//      const   char    *name_of_file;
23
24        //      Sets the current lod.
25        mCurrentLod     =       0;
26
27        //      Converts a String to const char *.
28//      name_of_file    =       name.data();
29
30        //      Sets the global mesh.
31        mGeoMesh = geomesh;
32
33        dataRetrievalInterface=NULL;
34        indices_x_submesh = NULL;
35        offsets_x_submesh = NULL;
36       
37        //      Loads the Level Of Detail file.
38        LodStripsLibrary::LoadStripMesh(lodstripsdata,mGeoMesh);
39
40        GoToLod(0.0f); 
41        minFaces = 0;
42        for (unsigned int strip = 0; strip < mTotalStrips; strip++)
43                minFaces += int(mStrips[strip].size() - 2);
44
45        GoToLod(1.0f);
46        maxFaces = 0;
47        for (unsigned int strip = 0; strip < mTotalStrips; strip++)
48                maxFaces += int(mStrips[strip].size() - 2);
49}
50
51//-----------------------------------------------------------------------------
52//      Destroyer.
53//-----------------------------------------------------------------------------
54LodStripsLibrary::~LodStripsLibrary()
55{
56        delete  [] mStrips;
57        if (dataRetrievalInterface)
58                delete dataRetrievalInterface;
59        if (indices_x_submesh)
60                delete[] indices_x_submesh;
61        if (offsets_x_submesh)
62                delete[] offsets_x_submesh;
63}
64
65//-----------------------------------------------------------------------------
66//      Public.
67//-----------------------------------------------------------------------------
68
69//-----------------------------------------------------------------------------
70//      Go to the level of detail.
71//-----------------------------------------------------------------------------
72void LodStripsLibrary::GoToLod(float lodfactor)
73{
74        register        int                                                     j;
75        register        int                                                     offset;
76        long                    int                                                     i;
77        long                    int                                                     k;
78        long                    int                                                     b_change_ok     =       1;
79        unsigned long   int                                     lod;
80        long                    int                                                     t;
81        long                    int                                                     r;
82        long                    int                                                     next;
83        long                    int                                                     el1;
84        long                    int                                                     el2;
85        long                    int                                                     total_changes;
86        long                    int                                                     totalR;
87        SmallIntVector                                          *strip;
88        SmallIntVector::iterator        start;
89        uint32                                                                          return_value;
90
91        uint32 newLOD = (uint32)((1.0f - lodfactor) * mLods);
92   
93        //      Initialize the return value to the current LOD.
94        return_value    =       mCurrentLod;
95
96        if (newLOD != mCurrentLod)
97        {
98                if (newLOD > mCurrentLod)
99                {
100                        //      Forwards.
101                        //      Increments LOD.
102                        for (lod = mCurrentLod; lod < newLOD; lod++)
103                        {
104                                next                                            =       mVertex[lod];
105                                total_changes   =       mPChanges[lod];
106
107                                for (i = 0; i < total_changes; i++)
108                                {
109                                        //      Strip change.
110                                        t                       =       mCurrentRegLOD->strip;
111                                        strip   =       &(mStrips[t]);
112                                        start   =       strip->begin();                         
113                               
114                                        //      Position.
115                                        totalR  =       mCurrentRegLOD->position;
116
117                                        for (j = totalR - 1; j >= 0; j--)
118                                        {
119                                                start[*mCurrentData]    =       next;
120                                               
121                                                ++mCurrentData;
122                                        }
123                                       
124                                        //      L1.
125                                        totalR  =       mCurrentRegLOD->vertexRepetition;
126                                       
127                                        for (j = totalR - 1; j >= 0; j--)
128                                        {
129                                                offset  =       *mCurrentData + 1;
130
131                                                strip->erase(   start + offset,
132                                                                                                        start
133                                                                                                        +
134                                                                                                        offset
135                                                                                                        +
136                                                                                                        (*(mCurrentData + 1)));
137
138                                                ++mCurrentData;
139                                                ++mCurrentData;
140                                        }
141                                       
142                                        //      L2
143                                        totalR  =       mCurrentRegLOD->edgeRepetition;
144                                       
145                                        for (j = totalR - 1; j >= 0; j--)
146                                        {
147                                                offset  =       *mCurrentData + 2;
148                                                strip->erase(   start   +       offset,
149                                                                                                        start
150                                                                                                        +
151                                                                                                        offset
152                                                                                                        +
153                                                                                                        2*(*(mCurrentData + 1)));
154
155                                                mCurrentData++;
156                                                mCurrentData++;
157                                        }
158
159                                        mCurrentRegLOD++;
160                                       
161                                        mStripsChanges[t]       =       1;
162                               
163                                }
164                               
165                                mCurrentLod     =       lod + 1;
166                        }
167
168                }
169                //      If LOD is less than actual.
170                else
171                {
172                        mCurrentRegLOD--;
173                        mCurrentData--;
174                       
175                        //      Decrements LOD.
176                        for (lod = mCurrentLod; lod > newLOD; lod--)
177                        {
178                                total_changes   =       mPChanges[lod - 1];
179                               
180                                for (i = 0; i < total_changes; i++)
181                                {
182                                        t                       =       mCurrentRegLOD->strip;
183                                        strip   =       &(mStrips[t]);
184                                        start   =       mStrips[t].begin();
185
186                                        //      L2.
187                                        totalR  =       mCurrentRegLOD->edgeRepetition;
188                                       
189                                        for (j = 0; j < totalR; j++)
190                                        {
191                                                el1     =       (*strip)[*(mCurrentData - 1)];
192                                                el2     =       (*strip)[*(mCurrentData - 1) + 1];
193                                                r               =       *(mCurrentData);
194                                               
195                                                for (k = 0; k < r; k++)
196                                                {
197                                                        (*strip).insert(start+*(mCurrentData - 1),el2);
198                                                        (*strip).insert(start+*(mCurrentData - 1),el1);
199                                                }
200                                               
201                                                mCurrentData--;
202                                                mCurrentData--;
203                                        }
204
205                                        //      Vertex Repetition.
206                                        totalR  =       mCurrentRegLOD->vertexRepetition;
207                                       
208                                        for (j = 0; j < totalR; j++)
209                                        {
210                                                el1     =       (*strip)[*(mCurrentData-1)];
211                                                r               =       *(mCurrentData);
212                                               
213                                                for (k = 0; k < r; k++)
214                                                {
215                                                        (*strip).insert(start+*(mCurrentData-1),el1);
216                                                }
217
218                                                mCurrentData--;
219                                                mCurrentData--;
220                                        }
221                                       
222                                        //      POS.
223                                        totalR  =       mCurrentRegLOD->position;
224                                       
225                                        for (j = 0; j < totalR; j++)
226                                        {
227                                                (*strip)[*mCurrentData] =       lod - 1;
228                                                mCurrentData--;
229                                        }
230                                       
231                                        mCurrentRegLOD--;
232                                        mStripsChanges[t]       =       1;
233                                }                       
234                               
235                                //      Update LOD.
236                                mCurrentLod     =       lod - 1;
237                        }
238                       
239                        mCurrentData++;
240                        mCurrentRegLOD++;
241                }
242        }
243
244        UpdateDataRetrievalInterface();
245//      return  return_value;
246}
247
248//-----------------------------------------------------------------------------
249//      Returns the number of vertices of the highest LOD.
250//-----------------------------------------------------------------------------
251uint32  LodStripsLibrary::MaxVertices()
252{
253        return  mMaxVerticesLOD;
254}
255
256//-----------------------------------------------------------------------------
257//      Returns the number of vertices of the lowest LOD.
258//-----------------------------------------------------------------------------
259uint32  LodStripsLibrary::MinVertices()
260{
261        uint32  number_of_vertices;
262
263        //      Total vertices of minimum lod.
264        number_of_vertices      =       mMaxVerticesLOD - (mMinLod + 1);
265
266        return  number_of_vertices;
267}
268
269//-----------------------------------------------------------------------------
270//      Returns the number of triangles of the highest LOD.
271//-----------------------------------------------------------------------------
272uint32  LodStripsLibrary::MaxFaces()
273{
274/*      uint32  number_of_faces;
275
276        uint32  current_lod;
277
278        current_lod     =       GoToLod(MaxLod());
279
280        //      Initialize number of faces count.
281        number_of_faces =       0;
282
283        //      For each strip.
284        for (unsigned int strip =       0; strip < mTotalStrips; strip++)
285        {
286                number_of_faces +=      int(mStrips[strip].size() - 2);
287        }
288
289        GoToLod(current_lod);
290
291        return  number_of_faces;*/
292
293        return maxFaces;
294}
295
296//-----------------------------------------------------------------------------
297//      Returns the number of triangles of the lowest LOD.
298//-----------------------------------------------------------------------------
299uint32  LodStripsLibrary::MinFaces()
300{
301/*      uint32  current_lod;
302        uint32  number_of_faces;
303
304        current_lod     =       GoToLod(MinLod());
305
306        //      Initialize number of faces count.
307        number_of_faces =       0;
308
309        //      For each strip.
310        for (unsigned int strip =       0; strip < mTotalStrips; strip++)
311        {
312                number_of_faces +=      int(mStrips[strip].size() - 2);
313        }
314
315        GoToLod(current_lod);
316
317        return  number_of_faces;*/
318
319        return minFaces;
320}
321
322//-----------------------------------------------------------------------------
323//      Establishes the new LOD range.
324//      Only the LODs in that range are stored and used.
325//-----------------------------------------------------------------------------
326void            LodStripsLibrary::TrimByLod(uint32 minLod, uint32 maxLod)
327{
328        //      Refresh number of vercies of the max lod.
329        mMaxVerticesLOD +=      mMaxLod - maxLod;
330       
331        mMinLod =       minLod;
332        mMaxLod =       maxLod;
333}
334/*
335//-----------------------------------------------------------------------------
336//      Get strip count.
337//-----------------------------------------------------------------------------
338uint32  LodStripsLibrary::GetStripCount() const
339{
340        return  (uint32)        mTotalStrips;
341}
342
343//-----------------------------------------------------------------------------
344//      Get Index by strip.
345//-----------------------------------------------------------------------------
346uint32  LodStripsLibrary::GetIndexCountByStrip(uint32 istrip) const
347{
348        return (uint32) mStrips[istrip].size();
349}
350*/
351//-----------------------------------------------------------------------------
352//      Private.
353//-----------------------------------------------------------------------------
354
355//-----------------------------------------------------------------------------
356//      Copy a STL vector to a C array.
357//-----------------------------------------------------------------------------
358void LodStripsLibrary::CopyVectors2Arrays()
359{
360        SmallInt                                        max;
361        SmallInt                                        t;
362        SmallInt                                        *data_array;
363        SmallIntVector          tira;
364        LODRegisterType         *changes_array;
365        LODRegisterVector       list_changes;
366
367        mTotalStrips            =       int(mFileStrips.size());
368        mVertex                                 =       new SmallInt[mTotalVertices];
369        mStripsChanges  =       new SmallInt[mTotalChanges];
370        mStrips                                 =       new SmallIntVector[mTotalStrips];
371        data_array                      =       new SmallInt[mData.size()];
372       
373        max                                     =       0;
374        mTotalFaces     =       0;
375
376//      unsigned int * strip_sizes = new unsigned int[mFileStrips.size()];
377        unsigned int total_strip_size = 0;
378       
379        for (unsigned   int     i = 0; i < mFileStrips.size(); i++)
380        {
381                total_strip_size += t = int(mFileStrips[i].size());
382                if (t>max)
383                        max     =       t;
384                mTotalFaces     +=      t - 2;
385        }
386
387        changes_array   =       new LODRegisterType[mFileChangesLOD.size()];
388       
389        //      Fill up changes array.
390        for (unsigned   int     i = 0; i < mFileChangesLOD.size(); ++i)
391        {
392                changes_array[i]        =       mFileChangesLOD[i];
393        }
394
395        mCurrentRegLOD  =       changes_array;
396       
397        //      Copy strips.
398        unsigned int numDegenerated = 2*mTotalStrips - 2;
399        dataRetrievalInterface=create_index_data_func(total_strip_size+numDegenerated); // temporal!
400        dataRetrievalInterface->Begin();
401
402        unsigned        int     ii = 0;
403
404        for (unsigned   int     i = 0; i < mFileStrips.size(); i++)
405        {
406                for (unsigned   int     j = 0; j < mFileStrips[i].size(); j++,ii++)
407                {
408                        mStrips[i].push_back(mFileStrips[i][j]);
409                        dataRetrievalInterface->SetIndex(ii,mFileStrips[i][j]);
410                }
411               
412                //      Reset flags of strips changed.
413                mStripsChanges[i]       =       0;
414        }
415        dataRetrievalInterface->End();
416
417        for (unsigned   int     i = 0; i < mData.size(); i++)
418        {
419                data_array[i]   =       mData[i];
420        }
421       
422        mCurrentData    =       data_array;
423
424        //      Fill up mVertex.
425        for(unsigned    int     i = 0; i < mFileVertices.size(); i++)
426        {
427                mVertex[i]      =       mFileVertices[i];
428        }
429
430//      delete[] strip_sizes;
431}
432
433//-----------------------------------------------------------------------------
434//      LoadStripMesh
435//-----------------------------------------------------------------------------
436void LodStripsLibrary::LoadStripMesh(const LodStripsLibraryData *lodstripsdata, Mesh *geomesh)
437{
438        FILE                                                                                                                    *fp;
439        SmallIntVector                                                                          strip_aux;
440        LODRegisterType                                                                         lod_register;
441        std::vector                     <LODRegisterType>       list_pos;
442        std::vector                     <unsigned int>          p_changes;
443        int                                                                                                                             value;
444        int                                                                                                                             v                       =       0;
445        int                                                                                                                             t                       =       -1;
446        int                                                                                                                             s                       =       0;
447        int                                                                                                                             next    =       0;
448        int                                                                                                                             c                       =       -1;
449        char                                                                                                                    buff[80];
450        Index                                                                                                                   *index;
451        Index                                                                                                                   *indexBegin;
452        Index                                                                                                                   *indexEnd;
453        SubMesh                                                                                                         *geoSubMesh;
454
455        //      For each one of the submeshes.
456        indices_x_submesh = new int[geomesh->mSubMeshCount];
457        offsets_x_submesh = new int[geomesh->mSubMeshCount];
458        for (unsigned int submesh       =       0; submesh < geomesh->mSubMeshCount; submesh++)
459        {
460                geoSubMesh      =       &geomesh->mSubMesh[submesh];
461
462                //      For each one of the strips.
463                for (unsigned int strip = 0; strip < geoSubMesh->mStripCount; strip++)
464                {
465                        // Insert an empty strip.
466                        t++;
467                        strip_aux.clear();
468                        mFileStrips.push_back(strip_aux);
469
470                        //      First index of the strip.
471                        indexBegin      =       geoSubMesh->mStrip[strip];
472
473                        //      If the strips is not the first.
474                        /*
475                        if (strip != 0)
476                        {
477                                indexBegin++;
478                        }
479                        */
480
481                        //      If is the final strip
482                        if (strip       == (geoSubMesh->mStripCount - 1))
483                        {
484                                //      The end of the index array.
485                                indexEnd        = &geoSubMesh->mIndex[geoSubMesh->mIndexCount];
486                        }
487                        else
488                        {
489                                //      The beginning of the next strip.
490                                indexEnd        = geoSubMesh->mStrip[strip + 1];
491
492                                //      Remove degenerated
493                                //indexEnd--;
494                        }
495                       
496                        int i;
497                        i       = 0;
498                        indices_x_submesh[submesh] = 0;
499                        if (submesh==0)
500                                offsets_x_submesh[submesh] = 0;
501                        else
502                                offsets_x_submesh[submesh] = indices_x_submesh[submesh-1];
503
504                        //      For each index of the strip.
505                        for (index = indexBegin; index < indexEnd; index++)
506                        {
507                                mFileStrips[t].push_back(indexBegin[i]);
508                                indices_x_submesh[submesh]++;
509                                i++;
510                        }                       
511                }
512        }
513
514        //      TODO:   LOD file loaded in load file mesh process.
515        //      Open the LOD file.
516/*      if ((fp = fopen (name, "r")) == NULL)
517        {
518                //      Error in open.
519        }
520        else
521        {
522                mTotalChanges   =       0;
523               
524                while (!feof (fp))
525                {
526                        fgets (buff, 80, fp);
527                       
528                        if (*buff == 'v')
529                        {
530                                sscanf (buff+2,"%d",&value);
531                               
532                                mFileVertices.push_back(value);
533                                v++;
534                        }
535                        else if ( (*buff == 'c') || (*buff == 'd'))
536                        {
537                                if (*buff == 'c')
538                                {
539                                        c++;
540                                }
541                                else
542                                {
543                                        unsigned        int     a;
544                                        unsigned        int     b;
545                                        unsigned        int     c;
546                                        unsigned        int     d;
547                                       
548                                        sscanf (buff+2,"%u %u %u %u\n",&a,&b,&c,&d);
549                                        lod_register.strip                                              =       a;
550                                        lod_register.position                                   =       b;
551                                        lod_register.vertexRepetition   =       c;
552                                        lod_register.edgeRepetition             =       d;
553                                       
554                                        mFileChangesLOD.push_back(lod_register);
555                                }
556                        }
557                        else if (*buff=='b')
558                        {
559                                sscanf(buff+2,"%u",&value);
560                                mData.push_back(value);
561                        }
562                        else if (*buff=='p')
563                        {
564                                sscanf (buff+2,"%u",&value);
565                                p_changes.push_back(value);
566                        }
567                }
568               
569                fclose(fp);*/
570
571        mFileVertices = lodstripsdata->mFileVertices;
572        mFileChangesLOD = lodstripsdata->mFileChangesLOD;
573        mData = lodstripsdata->mData;
574        p_changes = lodstripsdata->p_changes;
575               
576               
577                //      Max / Min values for LOD.
578                mLods                                                                                   =       int(p_changes.size());
579                mMaxLod                                                                         =       0;
580                mMinLod                                                                         =       mLods;
581
582                mPChanges                       =       new SmallInt[mLods];
583               
584                for (unsigned int i = 0; i < mLods; i++)
585                {
586                        mPChanges[i] = p_changes[i];
587                }
588
589                mTotalVertices          =       int(mFileVertices.size());
590                mMaxVerticesLOD         =       mTotalVertices;
591                mTotalStrips                    =       int(mFileStrips.size());
592                mTotalChanges                   =       int(mFileChangesLOD.size());
593
594                //Copy the data to the structure we will use
595                CopyVectors2Arrays();
596//      }
597}
598
599void LodStripsLibrary::UpdateDataRetrievalInterface(void)
600{
601        unsigned        int     ii      =       0;
602       
603        dataRetrievalInterface->Begin();
604
605        int counter = 0;
606        int target_submesh = 0;
607        int strip_count = 0;
608
609        for (unsigned   int i=0; i<mTotalStrips; i++, strip_count++)
610        {
611                if (strip_count >= mGeoMesh->mSubMesh[target_submesh].mStripCount)
612                {
613                        indices_x_submesh[target_submesh] = counter;
614                        if (target_submesh==0)
615                                offsets_x_submesh[target_submesh] = 0;
616                        else
617                                offsets_x_submesh[target_submesh] = indices_x_submesh[target_submesh-1] + offsets_x_submesh[target_submesh-1];
618
619                        counter = 0;
620                        strip_count = 0;
621                        target_submesh++;
622                }
623               
624                int lastindex = -1;
625                for (SmallIntVector::iterator it=mStrips[i].begin(); it!=mStrips[i].end(); it++, ii++)
626                {
627                        // repeat the first index of the strip: degenerate
628                        if (lastindex==-1)
629                        {
630                                lastindex=*it;
631                                dataRetrievalInterface->SetIndex(ii,*it);                               
632                                counter++;
633                                ii++;
634                        }
635                        lastindex=*it;
636                        dataRetrievalInterface->SetIndex(ii,*it);
637                        counter++;
638                }
639
640                // last repeat last vertex of the strip: degenerate
641                dataRetrievalInterface->SetIndex(ii,lastindex);
642                counter++;
643                ii++;
644
645                dataRetrievalInterface->SetNumValidIndices(ii);
646        }
647
648        if (strip_count >= mGeoMesh->mSubMesh[target_submesh].mStripCount)
649        {
650                indices_x_submesh[target_submesh] = counter;
651                if (target_submesh==0)
652                        offsets_x_submesh[target_submesh] = 0;
653                else
654                        offsets_x_submesh[target_submesh] = indices_x_submesh[target_submesh-1] + offsets_x_submesh[target_submesh-1];
655
656                counter = 0;
657                strip_count = 0;
658                target_submesh++;
659        }
660
661        dataRetrievalInterface->End();
662}
Note: See TracBrowser for help on using the repository browser.