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

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