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

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