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

Revision 1058, 14.9 KB checked in by gumbau, 18 years ago (diff)

LODs parameters changed to the range 1-0 (max-min)

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, CREATEMULTIINDEXDATAFUNC midfun)
20:create_multi_index_data_func(midfun?midfun:DefaultMultiIndexDataCreator)
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//      Gets the maximum level of detail.
244//-----------------------------------------------------------------------------
245uint32 LodStripsLibrary::MaxLod()
246{
247        return  mMaxLod;
248}
249
250//-----------------------------------------------------------------------------
251//      Gets the minimum level of detail.
252//-----------------------------------------------------------------------------
253uint32 LodStripsLibrary::MinLod()
254{
255        return  mMinLod;
256}
257
258//-----------------------------------------------------------------------------
259//      Returns the number of vertices of the highest LOD.
260//-----------------------------------------------------------------------------
261uint32  LodStripsLibrary::MaxVertices()
262{
263        return  mMaxVerticesLOD;
264}
265
266//-----------------------------------------------------------------------------
267//      Returns the number of vertices of the lowest LOD.
268//-----------------------------------------------------------------------------
269uint32  LodStripsLibrary::MinVertices()
270{
271        uint32  number_of_vertices;
272
273        //      Total vertices of minimum lod.
274        number_of_vertices      =       mMaxVerticesLOD - (mMinLod + 1);
275
276        return  number_of_vertices;
277}
278
279//-----------------------------------------------------------------------------
280//      Returns the number of triangles of the highest LOD.
281//-----------------------------------------------------------------------------
282uint32  LodStripsLibrary::MaxFaces()
283{
284/*      uint32  number_of_faces;
285
286        uint32  current_lod;
287
288        current_lod     =       GoToLod(MaxLod());
289
290        //      Initialize number of faces count.
291        number_of_faces =       0;
292
293        //      For each strip.
294        for (unsigned int strip =       0; strip < mTotalStrips; strip++)
295        {
296                number_of_faces +=      int(mStrips[strip].size() - 2);
297        }
298
299        GoToLod(current_lod);
300
301        return  number_of_faces;*/
302
303        return maxFaces;
304}
305
306//-----------------------------------------------------------------------------
307//      Returns the number of triangles of the lowest LOD.
308//-----------------------------------------------------------------------------
309uint32  LodStripsLibrary::MinFaces()
310{
311/*      uint32  current_lod;
312        uint32  number_of_faces;
313
314        current_lod     =       GoToLod(MinLod());
315
316        //      Initialize number of faces count.
317        number_of_faces =       0;
318
319        //      For each strip.
320        for (unsigned int strip =       0; strip < mTotalStrips; strip++)
321        {
322                number_of_faces +=      int(mStrips[strip].size() - 2);
323        }
324
325        GoToLod(current_lod);
326
327        return  number_of_faces;*/
328
329        return minFaces;
330}
331
332//-----------------------------------------------------------------------------
333//      Establishes the new LOD range.
334//      Only the LODs in that range are stored and used.
335//-----------------------------------------------------------------------------
336void            LodStripsLibrary::TrimByLod(uint32 minLod, uint32 maxLod)
337{
338        //      Refresh number of vercies of the max lod.
339        mMaxVerticesLOD +=      mMaxLod - maxLod;
340       
341        mMinLod =       minLod;
342        mMaxLod =       maxLod;
343}
344/*
345//-----------------------------------------------------------------------------
346//      Get strip count.
347//-----------------------------------------------------------------------------
348uint32  LodStripsLibrary::GetStripCount() const
349{
350        return  (uint32)        mTotalStrips;
351}
352
353//-----------------------------------------------------------------------------
354//      Get Index by strip.
355//-----------------------------------------------------------------------------
356uint32  LodStripsLibrary::GetIndexCountByStrip(uint32 istrip) const
357{
358        return (uint32) mStrips[istrip].size();
359}
360*/
361//-----------------------------------------------------------------------------
362//      Private.
363//-----------------------------------------------------------------------------
364
365//-----------------------------------------------------------------------------
366//      Copy a STL vector to a C array.
367//-----------------------------------------------------------------------------
368void LodStripsLibrary::CopyVectors2Arrays()
369{
370        unsigned int                    i;
371        unsigned int                    j;
372        SmallInt                                        max;
373        SmallInt                                        t;
374        SmallInt                                        *data_array;
375        SmallIntVector          tira;
376        LODRegisterType         *changes_array;
377        LODRegisterVector       list_changes;
378
379        mTotalStrips            =       int(mFileStrips.size());
380        mVertex                                 =       new SmallInt[mTotalVertices];
381        mStripsChanges  =       new SmallInt[mTotalChanges];
382        mStrips                                 =       new SmallIntVector[mTotalStrips];
383        data_array                      =       new SmallInt[mData.size()];
384       
385        max                                     =       0;
386        mTotalFaces     =       0;
387
388        unsigned int * strip_sizes = new unsigned int[mFileStrips.size()];
389        for (i = 0; i < mFileStrips.size(); i++)
390        {
391                strip_sizes[i] = t = int(mFileStrips[i].size());
392                if (t>max)
393                        max     =       t;
394                mTotalFaces     +=      t - 2;
395        }
396
397        changes_array   =       new LODRegisterType[mFileChangesLOD.size()];
398       
399        //      Fill up changes array.
400        for (i = 0; i < mFileChangesLOD.size(); ++i)
401        {
402                changes_array[i]        =       mFileChangesLOD[i];
403        }
404
405        mCurrentRegLOD  =       changes_array;
406       
407        //      Copy strips.
408        dataRetrievalInterface=create_multi_index_data_func(mFileStrips.size(),strip_sizes);
409        dataRetrievalInterface->Begin();
410        for (i = 0; i < mFileStrips.size(); i++)
411        {
412                for (j = 0; j < mFileStrips[i].size(); j++)
413                {
414                        mStrips[i].push_back(mFileStrips[i][j]);
415                        dataRetrievalInterface->SetIndex(i,j,mFileStrips[i][j]);
416                }
417               
418                //      Reset flags of strips changed.
419                mStripsChanges[i]       =       0;
420        }
421        dataRetrievalInterface->End();
422
423        for (i = 0; i < mData.size(); i++)
424        {
425                data_array[i]   =       mData[i];
426        }
427       
428        mCurrentData    =       data_array;
429
430        //      Fill up mVertex.
431        for(i = 0; i < mFileVertices.size(); i++)
432        {
433                mVertex[i]      =       mFileVertices[i];
434        }
435
436        delete[] strip_sizes;
437}
438
439//-----------------------------------------------------------------------------
440//      LoadStripMesh
441//-----------------------------------------------------------------------------
442void LodStripsLibrary::LoadStripMesh(char *name, Mesh *geomesh)
443{
444        FILE                                                                                                                    *fp;
445        SmallIntVector                                                                          strip_aux;
446        LODRegisterType                                                                         lod_register;
447        std::vector                     <LODRegisterType>       list_pos;
448        std::vector                     <unsigned int>          p_changes;
449        int                                                                                                                             value;
450        int                                                                                                                             v                       =       0;
451        int                                                                                                                             t                       =       -1;
452        int                                                                                                                             s                       =       0;
453        int                                                                                                                             next    =       0;
454        int                                                                                                                             c                       =       -1;
455        char                                                                                                                    buff[80];
456        Index                                                                                                                   *index;
457        Index                                                                                                                   *indexBegin;
458        Index                                                                                                                   *indexEnd;
459        SubMesh                                                                                                         *geoSubMesh;
460
461
462
463        //      For each one of the submeshes.
464        for (unsigned int submesh       =       0; submesh < geomesh->mSubMeshCount; submesh++)
465        {
466                geoSubMesh      =       &geomesh->mSubMesh[submesh];
467
468                //      For each one of the strips.
469                for (unsigned int strip = 0; strip < geoSubMesh->mStripCount; strip++)
470                {
471                        // Insert an empty strip.
472                        t++;
473                        strip_aux.clear();
474                        mFileStrips.push_back(strip_aux);
475
476                        //      First index of the strip.
477                        indexBegin      =       geoSubMesh->mStrip[strip];
478
479                        //      If the strips is not the first.
480                        /*
481                        if (strip != 0)
482                        {
483                                indexBegin++;
484                        }
485                        */
486
487                        //      If is the final strip
488                        if (strip       == (geoSubMesh->mStripCount - 1))
489                        {
490                                //      The end of the index array.
491                                indexEnd        = &geoSubMesh->mIndex[geoSubMesh->mIndexCount];
492                        }
493                        else
494                        {
495                                //      The beginning of the next strip.
496                                indexEnd        = geoSubMesh->mStrip[strip + 1];
497
498                                //      Remove degenerated
499                                //indexEnd--;
500                        }
501                       
502                        int i;
503                        i       = 0;
504                        //      For each index of the strip.
505                        for (index = indexBegin; index < indexEnd; index++)
506                        {
507                                mFileStrips[t].push_back(indexBegin[i]);
508                                i++;
509                        }
510                }
511        }
512
513        //      Open the LOD file.
514        if ((fp = fopen (name, "r")) == NULL)
515        {
516                //      Error in open.
517        }
518        else
519        {
520                mTotalChanges   =       0;
521               
522                while (!feof (fp))
523                {
524                        fgets (buff, 80, fp);
525                       
526                        if (*buff == 'v')
527                        {
528                                sscanf (buff+2,"%d",&value);
529                               
530                                mFileVertices.push_back(value);
531                                v++;
532                        }
533                        else if ( (*buff == 'c') || (*buff == 'd'))
534                        {
535                                if (*buff == 'c')
536                                {
537                                        c++;
538                                }
539                                else
540                                {
541                                        unsigned        int     a;
542                                        unsigned        int     b;
543                                        unsigned        int     c;
544                                        unsigned        int     d;
545                                       
546                                        sscanf (buff+2,"%u %u %u %u\n",&a,&b,&c,&d);
547                                        lod_register.strip                                              =       a;
548                                        lod_register.position                                   =       b;
549                                        lod_register.vertexRepetition   =       c;
550                                        lod_register.edgeRepetition             =       d;
551                                       
552                                        mFileChangesLOD.push_back(lod_register);
553                                }
554                        }
555                        else if (*buff=='b')
556                        {
557                                sscanf(buff+2,"%u",&value);
558                                mData.push_back(value);
559                        }
560                        else if (*buff=='p')
561                        {
562                                sscanf (buff+2,"%u",&value);
563                                p_changes.push_back(value);
564                        }
565                }
566               
567                fclose(fp);
568               
569                //      Max / Min values for LOD.
570                mLods                                                                                   =       int(p_changes.size());
571                mMaxLod                                                                         =       0;
572                mMinLod                                                                         =       mLods;
573
574                mPChanges                       =       new SmallInt[mLods];
575               
576                for (unsigned int i = 0; i < mLods; i++)
577                {
578                        mPChanges[i] = p_changes[i];
579                }
580
581                mTotalVertices          =       int(mFileVertices.size());
582                mMaxVerticesLOD         =       mTotalVertices;
583                mTotalStrips                    =       int(mFileStrips.size());
584                mTotalChanges                   =       int(mFileChangesLOD.size());
585
586                //Copy the data to the structure we will use
587                CopyVectors2Arrays();
588        }
589}
590
591
592void LodStripsLibrary::UpdateDataRetrievalInterface(void)
593{
594        dataRetrievalInterface->Begin();
595        for (int i=0; i<mTotalStrips; i++)
596        {
597                unsigned int j=0;
598                for (SmallIntVector::iterator it=mStrips[i].begin(); it!=mStrips[i].end(); it++, j++)
599                        dataRetrievalInterface->SetIndex(i,j,*it);
600                dataRetrievalInterface->SetNumValidIndices(i,j);
601        }
602        dataRetrievalInterface->End();
603}
Note: See TracBrowser for help on using the repository browser.