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

Revision 1069, 14.4 KB checked in by gumbau, 18 years ago (diff)

MultiIndexData? replaced by IndexData?

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