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

Revision 774, 13.8 KB checked in by gumbau, 18 years ago (diff)

GTGeometry and GeoTool? initial imports

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()
409{
410        return  (uint32)        mTotalStrips;
411}
412
413//-----------------------------------------------------------------------------
414//      Private.
415//-----------------------------------------------------------------------------
416
417/*
418        Copy a STL vector to a C array.
419*/
420void LodStripsLibrary::CopyVectors2Arrays()
421{
422        int                                                             i;
423        int                                                             j;
424        int                                                             *vertex;
425        int                                                             t_actual;
426        SmallInt                                        max;
427        SmallInt                                        t;
428        SmallInt                                        strip;
429        SmallInt                                        *data_array;
430        SmallIntVector          tira;
431        LODRegisterType         lod_register;
432        LODRegisterType         *changes_array;
433        LODRegisterVector       list_changes;
434
435        mTotalStrips            =       mFileStrips.size();
436        mVertex                                 =       new SmallInt[mTotalVertices];
437        mStripsChanges  =       new SmallInt[mTotalChanges];
438        mStrips                                 =       new SmallIntVector[mTotalStrips];
439        data_array                      =       new SmallInt[mData.size()];
440       
441        //Calcular el tamaño maximo de tira y el numero de caras total
442        max                                     =       0;
443        mTotalFaces     =       0;
444       
445        for (i = 0; i < mFileStrips.size(); i++)
446        {
447                t       =       mFileStrips[i].size();
448               
449                if (t>max)
450                {
451                        max     =       t;
452                }
453
454                mTotalFaces     +=      t - 2;
455        }
456
457        //Nueva version de ALLOCATE.
458        changes_array   =       new LODRegisterType[mFileChangesLOD.size()];
459       
460        //Rellenar vChanges
461        for (i = 0; i < mFileChangesLOD.size(); ++i)
462        {
463                changes_array[i]        =       mFileChangesLOD[i];
464        }
465
466        mCurrentRegLOD  =       changes_array;
467       
468        //COPY----------------------------------
469        //Copiar las tiras
470        for (i = 0; i < mFileStrips.size(); i++)
471        {
472                for (j = 0; j < mFileStrips[i].size(); j++)
473                {
474                        //Rellenar el vVector
475                        mStrips[i].push_back(mFileStrips[i][j]);
476                }
477               
478                //Poner a 0 los flags de modificados.
479                mStripsChanges[i]       =       0;
480        }
481
482        for (i = 0; i < mData.size(); i++)
483        {
484                data_array[i]   =       mData[i];
485        }
486       
487        mCurrentData    =       data_array;
488
489        //Meter los vertices en mVertex
490        for(i = 0; i < mFileVertices.size(); i++)
491        {
492                mVertex[i]      =       mFileVertices[i];
493        }
494}
495
496//-----------------------------------------------------------------------------
497// LoadStripMesh
498//-----------------------------------------------------------------------------
499void LodStripsLibrary::LoadStripMesh(char *name, Mesh *geomesh)
500{
501        FILE                                                                                                                    *fp;
502        VertexType                                                                                              vertex_aux;
503        SmallIntVector                                                                          strip_aux;
504        LODRegisterType                                                                         lod_register;
505        std::vector                     <LODRegisterType>       list_pos;
506        std::vector                     <unsigned int>          p_changes;
507        int                                                                                                                             value;
508        int                                                                                                                             v               =       0;
509        int                                                                                                                             t               =       -1;
510        int                                                                                                                             s               =       0;
511        int                                                                                                                             sig     =       0;
512        int                                                                                                                             c               =       -1;
513        char                                                                                                                    buff[80];
514        char                                                                                                                    *ptr;
515        Index                                                                                                                   *index;
516        Index                                                                                                                   *indexBegin;
517        Index                                                                                                                   *indexEnd;
518        SubMesh                                                                                                         *geoSubMesh;
519
520        //      For each one of the submeshes.
521        for (int submesh        =       0; submesh < geomesh->mSubMeshCount; submesh++)
522        {
523                geoSubMesh      =       &geomesh->mSubMesh[submesh];
524
525                //      For each one of the strips.
526                for (int strip = 0; strip < geoSubMesh->mStripCount; strip++)
527                {
528                        // Insert an empty strip.
529                        t++;
530                        strip_aux.clear();
531                        mFileStrips.push_back(strip_aux);
532
533                        //      First index of the strip.
534                        indexBegin      =       geoSubMesh->mStrip[strip];
535
536                        //      If the strips is not the first.
537                        if (strip != 0)
538                        {
539                                indexBegin++;
540                        }
541
542                        //      If is the final strip
543                        if (strip       == (geoSubMesh->mStripCount - 1))
544                        {
545                                //      The end of the index array.
546                                indexEnd        = &geoSubMesh->mIndex[geoSubMesh->mIndexCount];
547                        }
548                        else
549                        {
550                                //      The beginning of the next strip.
551                                indexEnd        = geoSubMesh->mStrip[strip + 1];
552
553                                //      Remove degenerated
554                                indexEnd--;
555                        }
556                       
557                        int i;
558                        i       = 0;
559                        //      For each index of the strip.
560                        for (index = indexBegin; index < indexEnd; index++)
561                        {
562                                mFileStrips[t].push_back(indexBegin[i]);
563                                i++;
564                        }
565                }
566        }
567
568        //      Open the LOD file.
569        if ((fp = fopen (name, "r")) == NULL)
570        {
571                //      Error in open.
572        }
573        else
574        {
575                mTotalChanges   =       0;
576               
577
578                while (!feof (fp))
579                {
580                        fgets (buff, 80, fp);
581                       
582                        if (*buff == 'v')
583                        {
584                                //VERTICES
585                                sscanf (buff+2,"%d",&value);
586                               
587                                mFileVertices.push_back(value);
588                                v++;
589                        }
590                        else if ( (*buff == 'c') || (*buff == 'd'))
591                        {
592                                if (*buff == 'c')
593                                {
594                                        // c indica que empieza un nuevo cambio
595                                        c++;
596                                }
597                                else
598                                {
599                                        unsigned        int     a;
600                                        unsigned        int     b;
601                                        unsigned        int     c;
602                                        unsigned        int     d;
603                                       
604                                        sscanf (buff+2,"%u %u %u %u\n",&a,&b,&c,&d);
605                                        lod_register.strip                                              =       a;
606                                        lod_register.position                                   =       b;
607                                        lod_register.vertexRepetition   =       c;
608                                        lod_register.edgeRepetition             =       d;
609                                       
610                                        mFileChangesLOD.push_back(lod_register);
611                                }
612                        }
613                        else if (*buff=='b')
614                        {
615                                sscanf(buff+2,"%u",&value);
616                                mData.push_back(value);
617                        }
618                        else if (*buff=='p')
619                        {
620                                sscanf (buff+2,"%u",&value);
621                                p_changes.push_back(value);
622                        }//Fin ElseIf
623
624                } // End WhileEOF
625               
626                fclose(fp);
627               
628                //      Max / Min values for LOD.
629                mLods                                                                                   =       p_changes.size();
630                mMinLod                                                                         =       0;
631                mMaxLod                                                                         =       mLods;
632
633                //// CHAPUZA PROVISIONAL: EL ULTIMO ELEMENTO SE REPITE 2 VECES V.v
634                mPChanges                       =       new SmallInt[mLods];
635               
636                for (unsigned int i = 0; i < mLods; i++)
637                {
638                        mPChanges[i] = p_changes[i];
639                }
640
641                mTotalVertices                  =       mFileVertices.size();
642                mTotalStrips                            =       mFileStrips.size();
643                mTotalChanges                           =       mFileChangesLOD.size();
644
645                //Copy the data to the structure we will use
646                CopyVectors2Arrays();
647        }
648}
649
Note: See TracBrowser for help on using the repository browser.