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

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