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

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