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

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