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

Revision 1322, 17.0 KB checked in by gumbau, 18 years ago (diff)

Removed online degenerated vertices

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