source: GTP/trunk/Lib/Geom/shared/GTGeometry/src/GeoLodStripsConstructor.cpp @ 1600

Revision 1600, 32.7 KB checked in by gumbau, 18 years ago (diff)

Fixed simplification bug when simplifying to extremely a low factor

Line 
1#include <iostream>
2#include <fstream>
3#include <time.h>
4#include "GeoLodStripsConstructor.h"
5#include "GeoMeshLoader.h"
6
7using namespace Geometry;
8
9//---------------------------------------------------------------------------
10//      Call GenerarModeloV and CopiarVectorsArraysNUEVAED to make changes.
11//---------------------------------------------------------------------------
12void LodStripsConstructor::GenerarModeloCompleto(TIPOFUNC       upb)
13{       
14        float   percent;
15
16        this->GenerarModeloV(upb);
17        this->CopiarVectors2ArraysNUEVAED();
18
19        //      Last updtate of the progress bar.
20        percent =       100.0;
21        upb(percent);
22}
23
24//---------------------------------------------------------------------------
25//      It makes Lods changes and count them.
26//---------------------------------------------------------------------------
27void LodStripsConstructor::CalcularCambiosLODsVNuevaED(TIPOFUNC upb)
28{
29        long            int                                     k;
30        long            int                                     i;
31        unsigned long           int                     t;
32        long            int                                     r;
33        unsigned long           int                     v;
34        long            int                                     p0;
35        long            int                                     lod     =       0;
36        long            int                                     sigue;
37        long            int                                     ac[3]   =       {0,0,0};
38        long            int                                     totalRegs       =       0;
39        long            int                                     RegsCambios;
40        std::vector<std::vector<int> >  TiraOriginal;
41        LODData                                                 regLOD;
42        std::vector<LODData>                    listaCambios;
43        float                                                   percent;
44        float                                                   increment;
45        long            int                                     update;
46
47        //      Saves original copy.
48        TiraOriginal                    =       this->cStrips;
49
50        this->MARCAVACIO        =       int(10 * this->cVerts.size());
51       
52        listaCambios.clear();
53
54        //      Initialize increment.
55        increment       =       0.0;
56       
57        for     (lod = 0; ((this->cVerts[lod].Next) != -1); lod++)
58        {
59                increment       +=      1.0;
60        }
61
62
63        update          =       -1;
64        increment       =       (float)30.0     /       increment;
65        percent         =       1.0;
66       
67        this->LodsDisp  =       this->TOTALCAMBIOS      =       lod;
68        pCambios                =       new uint32[this->TOTALCAMBIOS];
69        pCambios[0]             =       0;
70       
71        for     (lod = 0; ((this->cVerts[lod].Next) != -1); lod++)
72        {
73                tipoVertice & cVertsLOD = this->cVerts[lod];
74               
75                RegsCambios                             =       0;
76                regLOD.obligatory       =       this->Ordenacion[lod].obligatory;
77               
78                for(t = 0; t < this->cStrips.size(); t++)
79                {
80                        std::vector<int> & cStripsT = this->cStrips[t];
81
82                        //      Initialize.
83                        regLOD.strip    =       this->MARCAVACIO;
84
85                        //      Change vertices.
86                        totalRegs               =       0;
87                       
88                        for (v = 0; v < cStripsT.size(); v++)
89                        {
90                                if (cStripsT[v] == lod)
91                                {
92                                        //      Strips.
93                                        if (regLOD.strip == this->MARCAVACIO)
94                                                regLOD.strip = t;
95                                       
96                                        ++totalRegs;
97
98                                        cDatos.push_back(v);
99
100                                        cStripsT[v]     =       cVertsLOD.Next;
101                                }
102                        }
103                       
104                        regLOD.nP       =       char(totalRegs);
105
106                        //      Simplifications length 1.
107                        //      Changes for simplification of level 1 to greater than 2.
108                        totalRegs       =       0;
109                        i                       =       0;
110                        r                       =       0;
111                        sigue           =       0;
112                        k                       =       long(cStripsT.size()-3);
113                       
114                        while (i < k)
115                        {
116                                if (    (cStripsT[i] == cStripsT[i+1])
117                                                        &&
118                                                        (cStripsT[i+1] == cStripsT[i+2])
119                                                )
120                                {
121                                        //      Saves beginning of repetition.
122                                        if (!r)
123                                        {
124                                                p0      =       i;
125                                        }
126                                       
127                                        //cStripsT.eraseAtPos(i);
128                                        cStripsT.erase(cStripsT.begin()+i);
129                                        i--;
130                                        r++;
131                                       
132                                        if ((i+1) != cStripsT.size()-1)
133                                        {
134                                                sigue   =       1;
135                                        }
136                                        else
137                                        {
138                                                sigue   =       0;
139                                        }
140                                       
141                                }
142                                else
143                                {
144                                        sigue   =       0;
145                                }
146
147                                if (!sigue && r)
148                                {
149                                       
150
151                                       
152                                        //cDatos.push_back(p0);
153                                        //cDatos.push_back(r);
154
155                                        //r     =       0;
156                                        //k     =       long(cStripsT.size()-r-3);
157                                       
158                                        long auxp0, auxr;
159                                        //regLOD.strip= t;
160                                        auxp0= p0;
161                                        auxr= r;
162                                               
163                                        if (r==1)
164                                        {
165                                                while(r>0)
166                                                {
167                                                        cStripsT.insert(cStripsT.begin()+p0,cStripsT[p0]);
168                                                        r--;
169                                                }
170                                                i=p0;
171                                        }                                       
172                                        else
173                                        {
174                                                if (r%2) //If r is odd the changes are undone
175                                                {
176                                                        cStripsT.insert(cStripsT.begin()+p0,cStripsT[p0]);
177                                                        r--;
178                                                        auxr=r;
179                                                }
180                                                //listaPos.push_back(pos);
181                                                cDatos.push_back(auxp0);
182                                                cDatos.push_back(auxr);
183                                        if (regLOD.strip == this->MARCAVACIO)
184                                        {
185                                                regLOD.strip    =       t;
186                                        }
187
188                                        ++totalRegs;
189                                        }
190
191
192                                        r       =       0;
193
194                                        k       =       (long)(cStripsT.size() - 3);
195
196                                }
197
198                                i++;
199                        }
200                       
201                        regLOD.nL1      =       char(totalRegs);
202
203                        //TERCERO: Simplificaciones de Longitud 2 tipo V1 V2 V1 V2 -> V1 V2
204                        totalRegs       =       0;
205                        i                                       =       0;
206                        r                                       =       0;
207                        sigue                   =       0;
208                        k                                       =       long(cStripsT.size() - 4);
209                       
210                        while   (i < k)
211                        {
212                                if (    (cStripsT[i] == cStripsT[i+2])
213                                                        &&
214                                                        (cStripsT[i+1] == cStripsT[i+3])
215                                                )
216                                {
217                                        if (!r)
218                                        {
219                                                p0      =       i;
220                                        }
221                                       
222                                        //cStripsT.eraseAtPos(i);
223                                        cStripsT.erase(this->cStrips[t].begin()+i);
224                                        //cStripsT.eraseAtPos(i);
225                                        cStripsT.erase(this->cStrips[t].begin()+i);
226                                        r++;
227                                       
228                                        i       -=      2;
229                                       
230                                        if ((i+1) != cStripsT.size()-3)
231                                        {
232                                                sigue   =       1;
233                                        }
234                                        else
235                                        {
236                                                sigue   =       0;
237                                        }
238                                       
239                                }
240                                else
241                                {
242                                        sigue   =       0;
243                                }
244
245                                if (!sigue && r)
246                                {
247                                        if (regLOD.strip == this->MARCAVACIO)
248                                        {
249                                                regLOD.strip    =       t;
250                                        }
251                                       
252                                        ++totalRegs;
253
254                                        cDatos.push_back(p0);
255                                        cDatos.push_back(r);
256                                       
257                                        r       =       0;
258                                        k       =       long((cStripsT.size()-4-2*r));
259                                }
260
261                                i++;
262                        }
263                       
264                        regLOD.nL2      =       char(totalRegs);
265                       
266                        if (regLOD.strip != this->MARCAVACIO)
267                        {
268                                RegsCambios++;
269                                listaCambios.push_back(regLOD);
270                        }
271                }//     End for t.
272               
273                pCambios[lod]   =       RegsCambios;
274        }//     End for lod.
275
276        this->cCambios  =       listaCambios;
277
278        //      Guardar el numero de LODS disponibles.
279        this->TOTALCAMBIOS      =       this->LodsDisp=lod;
280
281        //Retornar a la lista original
282        this->cStrips   =       TiraOriginal;
283}
284
285//---------------------------------------------------------------------------
286//Put in order vertex of Mesh from simplification sequence
287//---------------------------------------------------------------------------
288void LodStripsConstructor::OrdenarModeloVQSLIM(TIPOFUNC upb)
289{
290        unsigned long int i;
291        unsigned long int j;
292        unsigned long int t;
293        unsigned long int v;
294        long int vSig;
295        long int k;
296        VECTORVERTEX                    Vertices;
297        std::vector<tipoVertice>                NuevosVerts;
298        std::vector<std::vector<int> >  NuevasTiras;
299        std::vector<int>                tira;
300        tipoOrden                               Orden;
301        tipoOrden                               *Ord;
302        bool                                    bEncontrado;
303
304
305        //      Progress bar
306        float                   percent;
307        float                   increment;
308        long    int     update;
309
310        bEncontrado = false;
311
312        size_t  mStepsSize = mGeoMeshSQ->mSteps.size();
313
314        update                  =       -1;
315        percent                 =       1.0;
316        increment               =       (float)(10.0) / (float)mStepsSize;
317       
318        for     (i = 0; i < mStepsSize; i++)
319        {
320                if (update      != (int)(i * increment))
321                {
322                        update  =       (int)(i * increment);
323                        upb(percent);
324                }
325               
326                const MeshSimplificationSequence::Step & theStep = this->mGeoMeshSQ->mSteps[i];
327
328                Orden.vQslimNext        =       theStep.mV0;
329                Orden.vQslim                    =       theStep.mV1;
330                Orden.obligatory        =       theStep.obligatory;
331                Orden.vLS                                       =       i;
332
333                Orden.x                                 =       theStep.x;
334                Orden.vLSNext           =       -1;
335                Orden.cambio            =       "n";
336
337                Ordenacion.push_back(Orden);
338        }
339       
340        update          =       -1;
341        increment       =       (float)(10.0) / (float)(Ordenacion.size());
342        percent         =       1.0;
343
344        update          =       -1;
345        increment       =       (float)(10.0) / (float)(Ordenacion.size());
346        percent         =       1.0;
347
348        //      3 seg.
349        //Ordenacion de los vertices
350        for(i = 0; i < Ordenacion.size(); i++)
351        {
352                if (update      !=      (int)(i * increment))
353                {
354                        update  =       (int)(i * increment);
355                        upb(percent);
356                }
357
358                int OrdvQslim = Ordenacion[i].vQslim;
359                int OrdvQslimNext = Ordenacion[i].vQslimNext;
360
361                NuevosVerts.push_back(this->cVerts[OrdvQslim]);
362
363                cVerts[OrdvQslim].Next  =       -1;
364        }
365
366        //      Añadir aquellos vertices que no estaban en NuevosVerts
367        //      y no se simplificaban.
368        int cont                =       0;
369        int contestaban =       0;
370
371        size_t  cVertsSize = this->cVerts.size();
372        for(i = 0; i < cVertsSize; i++)
373        {
374                if (this->cVerts[i].Next != -1)
375                {
376                        cont++;
377                        NuevosVerts.push_back(this->cVerts[i]);
378                        Orden.vLS                       =       int(Ordenacion.size());
379                        Orden.obligatory        = 0;
380                        Orden.vLSNext           =       -1;
381                        Orden.vQslim            =       i;
382                        Orden.vQslimNext        =       -1;
383
384                        Ordenacion.push_back(Orden);
385                }
386                else
387                {
388                        contestaban++;
389                }
390        }
391
392        update          =       -1;
393        increment       =       (float)(10.0)   /       (float)(Ordenacion.size());
394        percent         =       1.0;
395       
396        //      2 min.
397        //      Calcular los siguiente teniendo en cuenta el simplif.
398        for (i = 0; i < Ordenacion.size(); i++)
399        {
400                if (update      !=      (int)(i * increment))
401                {
402                        update  =       (int)(i * increment);
403                        upb(percent);
404                }
405               
406                v       =       Ordenacion[i].vQslimNext;
407
408                //Buscar ese vertice v cual es ahora
409                vSig    =       0;
410
411                for (t = 0; t < Ordenacion.size() && !vSig;t++)
412                {
413                        if (Ordenacion[t].vQslim == v)
414                        {
415                                vSig    =       Ordenacion[t].vLS;
416                        }
417                }
418
419                if (vSig != 0)
420                {
421                        Ordenacion[i].vLSNext   =       vSig;
422                }
423        }
424
425        //Creacion de nuevas tiras con las mismas dimensiones
426        size_t  cStripsSize = this->cStrips.size();
427        for(t = 0; t < cStripsSize; t++)
428        {
429                tira.clear();
430
431                size_t  cStripsSizeT = this->cStrips[t].size();
432
433                for(i = 0; i < cStripsSizeT; i++)
434                {
435                        tira.push_back(0);
436                }
437
438                NuevasTiras.push_back(tira);
439        }
440
441        update          =       -1;
442        increment       =       (float)(20.0) / (float)(NuevosVerts.size());
443        percent         =       1.0;
444
445        k       =       0;
446
447        //      2 min.
448        //Cambiar los vertices de las tiras
449        size_t  NuevosVertsSize = NuevosVerts.size();
450
451        for(v = 0; v < NuevosVertsSize; v++)
452        {
453                if (update != (int)(v * increment))
454                {
455                        update  =       (int)(v * increment);
456                        upb(percent);
457                }               
458
459                const tipoOrden & OrdenacionV = Ordenacion[v];
460
461                for(t = 0; t < cStrips.size(); t++)
462                {
463                        std::vector<int> & thisStrip = cStrips[t];                     
464                        std::vector<int> & NuevasTirasT = NuevasTiras[t];
465                        size_t  cStripsSizeT = thisStrip.size();
466
467                        for(i = 0; i < cStripsSizeT; i++)
468                        {
469                                if (thisStrip[i] == OrdenacionV.vQslim)
470                                {
471                                        k++;
472                                        NuevasTirasT[i] =       v;
473                                }
474                        }
475                }
476        }
477
478        //Cambiar a Tiras Nuevas
479        this->cStrips   =       NuevasTiras;
480
481        //NuevosVerts y Ordenacion = tamaño.
482        NuevosVertsSize = NuevosVerts.size();
483
484        for(i = 0; i < NuevosVertsSize; i++)
485        {
486                NuevosVerts[i].Next     =       Ordenacion[i].vLSNext;
487        }
488
489        //Cambiar cVerts por nuevosVerts.
490        this->cVerts    =       NuevosVerts;
491
492        //percent       =       100.0;
493        //upb(percent);
494}
495
496//---------------------------------------------------------------------------
497//      Constructor of LodStripsConstructor object from
498//      a Mesh and MeshSimplificationSequence.
499//---------------------------------------------------------------------------
500LodStripsConstructor::LodStripsConstructor(const Mesh                                           *m,
501                                                                                                                const MeshSimplificationSequence        *ms,
502                                                                                                                        size_t                                                                                                          submesh,
503                                                                                                                        TIPOFUNC                                                                                                        upb)
504{
505        MARCA   =       TOTALTIRAS      =       TOTALVERTS      =       TOTALCAMBIOS    =       0;
506       
507        meshoriginal    =       m;
508       
509        mGeoMesh                        =       new Mesh();
510        *mGeoMesh                       =       *m;
511       
512        mInitialMesh    =       new Mesh();
513        *mInitialMesh   =       *m;
514       
515        this->mGeoMeshSQ        =       const_cast<MeshSimplificationSequence*>(ms);
516
517        //      Add new vertices to mesh.
518        AddNewVertices();
519
520        //      Set the leaves submesh.
521        mSubMeshLeaves  =       submesh;
522       
523        this->GenerarModeloCompleto(upb);
524}
525
526//---------------------------------------------------------------------------
527//      Destructor LodStripsConstructor object
528//---------------------------------------------------------------------------
529LodStripsConstructor::~LodStripsConstructor()
530{
531        delete [] vDatos;
532        delete [] vCambios;
533/*      vector <LODData> cCambiosTemp;
534        cCambios.swap(cCambiosTemp);*/
535        cCambios.clear();
536
537/*      VECTORUNINT cDatosTemp;
538        cDatos.swap(cDatosTemp);*/
539        cDatos.clear();
540
541        delete [] vStrips;
542
543        delete [] vVerts;
544
545//      vector <VECTORINT> cStripsTemp;
546//      cStrips.swap(cStripsTemp);;
547        cStrips.clear();
548
549//      VECTORVERTEX cVertsTemp;
550//      cVerts.swap(cVertsTemp);
551        cVerts.clear();
552
553        delete [] pCambios;
554
555        delete  mInitialMesh;
556        delete  mGeoMesh;
557}
558
559//---------------------------------------------------------------------------
560//      Build lod file with necessary information and save all changes at
561//      lodStripConstructor object.
562//---------------------------------------------------------------------------
563void LodStripsConstructor::Save(std::string filename)
564{
565        int vertexCount         =       (int)this->cVerts.size();
566        int changesCount        =       (int)this->cCambios.size();
567        int dataCount                   =       (int)this->cDatos.size();
568        int cambiosCount        =       this->TOTALCAMBIOS;
569        int size                                        =       changesCount*sizeof(LODData)
570                                                                                        +
571                                                                                        (vertexCount + dataCount + cambiosCount + 4)
572                                                                                        *
573                                                                                        sizeof(int)
574                                                                                        +
575                                                                                        CHUNK_OVERHEAD_SIZE;
576
577        FILE *f =       fopen(filename.c_str(),"ab");
578
579        unsigned short chunkid  =       0xabcd;
580
581        fwrite(&chunkid,sizeof(unsigned short),1,f);
582        fwrite(&size,sizeof(unsigned long),1,f);
583
584        // VERTICES.
585        fwrite(&vertexCount, sizeof(int), 1, f);
586
587        for (size_t     i = 0; i < this->cVerts.size(); i++)
588        {
589                int auxv        =       cVerts[i].Next;
590                fwrite(&auxv, sizeof(int), 1, f);
591        }
592
593        //      CSTRIPS.
594        this->TOTALINDICES      =       0;
595       
596        for(size_t      i = 0; i < this->cStrips.size(); i++)
597        {
598                this->TOTALINDICES += int(this->cStrips[i].size());
599        }
600
601        //      lines starting with a d.
602        //      Changes
603        fwrite(&changesCount, sizeof(int), 1, f);
604        for(size_t      i = 0; i < this->cCambios.size(); i++)
605        {
606                LODData change= cCambios[i];
607                fwrite(&change, sizeof(LODData), 1, f);
608        }
609
610        //      Data.
611        fwrite(&dataCount, sizeof(int), 1, f);
612        for(size_t      i = 0; i < this->cDatos.size(); i++)
613        {
614                int data= cDatos[i];
615                fwrite(&data, sizeof(int), 1, f);
616        }
617
618        //      lines starting with a p.
619        //      Chages made in a LOD.
620        fwrite(&cambiosCount, sizeof(int), 1, f);
621
622        for(size_t      i = 0; i < this->TOTALCAMBIOS; i++)
623        {
624                int cambio= pCambios[i];
625                fwrite(&cambio, sizeof(int), 1, f);
626        }
627
628        fclose(f);
629}
630
631int LodStripsConstructor::igual(Geometry::Vector3 vo,Geometry::Vector3 vc)
632{
633        if (vo.x==vc.x && vo.y==vc.y && vo.z==vc.z)
634                return 1;
635        else
636                return 0;
637}
638
639int LodStripsConstructor::igual(Geometry::Vector2 vo,Geometry::Vector2 vc)
640{
641        if (vo.x==vc.x && vo.y==vc.y)
642                return 1;
643        else
644                return 0;
645}
646
647/*void LodStripsConstructor::Load(Serializer &oSerializer)
648{
649}*/
650
651//---------------------------------------------------------------------------
652//      Call leeVerticesyTirasDeMesh, OrdenarModeloVQSLIM
653//      and CalcularCambiosLODsVNuevaED to make changes at vertex
654//      and index strutures.
655//---------------------------------------------------------------------------
656void LodStripsConstructor::GenerarModeloV(TIPOFUNC      upb)
657{
658        long int        max;
659        long int        t;
660        unsigned long int       i;
661        float                   percent;
662
663        percent =       10;
664
665        this->leeVerticesyTirasDeMesh();
666
667        upb(percent);
668
669        this->OrdenarModeloVQSLIM(upb);
670
671        //Calcular el tamaño maximo de tira
672        max     =       0;
673
674        for(i = 0; i < this->TOTALTIRAS; i++)
675        {
676                t = long(this->cStrips[i].size());             
677                if (t > max)
678                        max     = t;
679        }
680
681        this->MARCA     =       max + 1;
682        this->CalcularCambiosLODsVNuevaED(upb);
683}
684
685//---------------------------------------------------------------------------
686//      It fills structs with vertex and index information.
687//---------------------------------------------------------------------------
688void LodStripsConstructor::CopiarVectors2ArraysNUEVAED()
689{
690        unsigned int            i;
691        unsigned int            j;
692        uint32                  max;
693        uint32                  t;
694        VECTORINT               tira;
695        LODChanges      listaCambios;
696
697        //      ALLOCATE----------------
698        this->TOTALVERTS        =       int(this->cVerts.size());
699        this->TOTALTIRAS        =       int(this->cStrips.size());
700        this->vVerts                    =       new tipoVertice[this->TOTALVERTS];
701        this->lStripsV          =       new VECTORINT[this->TOTALTIRAS];
702        this->vDatos                    =       new uint32[cDatos.size()];
703       
704        //      Calcular el tamaño maximo de tira y el numero de caras total.
705        max                                                             =       0;
706        this->TOTALCARAS        =       0;
707
708        for     (i = 0; i < this->cStrips.size(); i++)
709        {
710                t       =       int(this->cStrips[i].size());
711               
712                if (t > max)
713                {
714                        max     =       t;
715                }
716
717                this->TOTALCARAS        +=      (t-2);
718        }
719       
720        this->vStrips   =       Allocate2DArrayINT(this->TOTALTIRAS,max+1);
721        this->MARCA             =       int(this->cVerts.size());
722        vCambios                        =       new LODData[this->cCambios.size()];
723       
724        //      Rellenar vChanges.
725        for     (i = 0; i < this->cCambios.size();++i)
726        {
727                vCambios[i]     =       cCambios[i];
728        }
729       
730        for (i = 0; i < this->cStrips.size(); i++)
731        {
732                for (j = 0; j < this->cStrips[i].size(); j++)
733                {
734                        //      Rellenar el array vStrips.
735                        this->vStrips[i][j]     = this->cStrips[i][j];
736                       
737                        //      Rellenar el vVector.
738                        this->lStripsV[i].push_back(this->cStrips[i][j]);
739                }
740               
741                this->vStrips[i][j]     =       this->MARCA;
742        }
743
744        for (i = 0; i < cDatos.size(); i++)
745        {
746                vDatos[i]       =       cDatos[i];
747        }
748       
749        pCurrentData    =       vDatos;
750
751        //      Meter los vertices en vVerts.
752        for     (i = 0; i < this->cVerts.size(); i++)
753        {
754                this->vVerts[i] =       this->cVerts[i];
755        }
756
757}
758
759//---------------------------------------------------------------------------
760//      It fills cVerts and cStrips with original Mesh vertex and strips
761//      information.
762//---------------------------------------------------------------------------
763void LodStripsConstructor::leeVerticesyTirasDeMesh()
764{
765        tipoVertice     vAux;
766        std::vector<int>                tira;
767        size_t                  i;
768        size_t                  j;
769        bool                            error;
770
771        error   =       false;
772       
773        if(this->mGeoMesh->mSubMeshCount == 1)
774        {
775                error   =       false;
776        }
777        else
778        {
779                for     (i = 0; i < this->mGeoMesh->mSubMeshCount;i++)
780                {
781                        if      (this->mGeoMesh->mSubMesh[i].mSharedVertexBuffer == true)
782                        {
783                                error   =       false;
784                        }
785                        else
786                        {
787                                error   =       true;
788                                break;
789                        }
790                }
791        }
792       
793        if(!error)
794        {
795                if      (       (this->mGeoMesh->mSubMesh[0].mSharedVertexBuffer == true)
796                                        &&
797                                        (this->mGeoMesh->mSubMeshCount > 1)
798                                )
799                {
800                        for     (j = 0; j < this->mGeoMesh->mVertexBuffer->mVertexCount; j++)
801                        {
802                                //      Si hay mas de un submesh ListaIndices no se rellena correctamente
803                                vAux.Vertex[0] = this->mGeoMesh->mVertexBuffer->mPosition[j].x;
804                                vAux.Vertex[1] = this->mGeoMesh->mVertexBuffer->mPosition[j].y;
805                                vAux.Vertex[2] = this->mGeoMesh->mVertexBuffer->mPosition[j].z;
806
807                                //      Añadimos las normales en cVerts.
808                                if      (       this->mGeoMesh->mVertexBuffer->mVertexInfo
809                                                        &
810                                                        Geometry::VERTEX_NORMAL
811                                                )
812                                {
813                                        vAux.Normal[0] = this->mGeoMesh->mVertexBuffer->mNormal[j].x;
814                                        vAux.Normal[1] = this->mGeoMesh->mVertexBuffer->mNormal[j].y;
815                                        vAux.Normal[2] = this->mGeoMesh->mVertexBuffer->mNormal[j].z;
816                                }
817
818                                //      Añadimos las coordenadas de textura a cVerts.
819                                if      (       this->mGeoMesh->mVertexBuffer->mVertexInfo
820                                                        &
821                                                        Geometry::VERTEX_TEXCOORDS
822                                                )
823                                {
824                                        vAux.TexCoords[0] = this->mGeoMesh->mVertexBuffer->mTexCoords[j].x;
825                                        vAux.TexCoords[1] = this->mGeoMesh->mVertexBuffer->mTexCoords[j].y;
826                                }
827
828                                vAux.Next               =       -10;
829                                vAux.numMesh    =       0;                     
830                                vAux.obligatory =       0;
831                               
832                                this->cVerts.push_back(vAux);
833                        }
834                }
835                else
836                {
837                        for     (i = 0; i < this->mGeoMesh->mSubMeshCount; i++)
838                        {
839                                for     (       j = 0;
840                                                j < this->mGeoMesh->mSubMesh[i].mVertexBuffer->mVertexCount;
841                                                j++)
842                                {
843                                        //      Si hay mas de un submesh ListaIndices
844                                        //      no se rellena correctamente.
845                                        vAux.Vertex[0] = this->mGeoMesh->mSubMesh[i].
846                                                mVertexBuffer->mPosition[j].x;
847                                        vAux.Vertex[1] = this->mGeoMesh->mSubMesh[i].
848                                                mVertexBuffer->mPosition[j].y;
849                                        vAux.Vertex[2] = this->mGeoMesh->mSubMesh[i].
850                                                mVertexBuffer->mPosition[j].z;
851                                        //      Añadimos las normales en cVerts.
852                                        vAux.Normal[0] = this->mGeoMesh->mSubMesh[i].
853                                                mVertexBuffer->mNormal[j].x;
854                                        vAux.Normal[1] = this->mGeoMesh->mSubMesh[i].
855                                                mVertexBuffer->mNormal[j].y;
856                                        vAux.Normal[2] = this->mGeoMesh->mSubMesh[i].
857                                                mVertexBuffer->mNormal[j].z;
858
859                                        //      Añadimos las coordenadas de textura a cVerts.
860                                        vAux.TexCoords[0]       =       this->mGeoMesh->mSubMesh[i].
861                                                mVertexBuffer->mTexCoords[j].x;
862                                        vAux.TexCoords[1] = this->mGeoMesh->mSubMesh[i].
863                                                mVertexBuffer->mTexCoords[j].y;
864
865                                        vAux.Next                       =       -10;
866                                        vAux.numMesh    =       int(i);
867
868                                        this->cVerts.push_back(vAux);
869                                }
870                        }
871                }       
872
873                Index   indice_acum;
874                Index   num_vert;
875
876                num_vert        =       0;
877
878                // load the strips list         
879                for     (i = 0; i < this->mGeoMesh->mSubMeshCount; i++)
880                {
881                        //      If is not the leaves submesh.
882                        if (mSubMeshLeaves != i)
883                        {
884                                indice_acum     =       0;
885
886                                for     (j = 0; j < this->mGeoMesh->mSubMesh[i].mStripCount; j++)
887                                {
888                                        Index   *aux    =       this->mGeoMesh->mSubMesh[i].mStrip[j];
889
890                                        // remove strip degenerates (first indices) except for the first (DEG!)
891                                        if (j != 0)
892                                        {
893                                                // La primera tira no empieza por índices repetidos.
894                                                aux     = aux+1;
895                                                indice_acum++;
896                                        }
897                                       
898                                        if (j+1 < this->mGeoMesh->mSubMesh[i].mStripCount)
899                                        {
900                                                Index   *siguiente      =       this->mGeoMesh->mSubMesh[i].mStrip[j+1];
901
902                                                tira.clear();
903
904                                                while (aux != siguiente)
905                                                {
906                                                        tira.push_back(*aux);
907                                                        indice_acum++;
908
909                                                        aux     =       aux + 1;
910                                                }
911
912                                                // DEG!: remove strip degenerates (last indices) except for the last strip
913                                                tira.pop_back();
914
915                                                this->cStrips.push_back(tira);
916                                        }
917                                        else
918                                        {
919                                                // Insertar los indices de la última tira en el cStrips
920                                                tira.clear();
921
922                                                for     (       unsigned int k = indice_acum;
923                                                                k < this->mGeoMesh->mSubMesh[i].mIndexCount;
924                                                                k++)
925                                                {
926                                                        tira.push_back(this->mGeoMesh->mSubMesh[i].mIndex[k]);
927                                                }
928
929                                                this->cStrips.push_back(tira);
930                                        }
931                                }
932
933                                num_vert        +=      int(this->mGeoMesh->mSubMesh[i].
934                                        mVertexBuffer->mVertexCount);
935                        }
936                }
937
938                this->TOTALVERTS        =       int(cVerts.size());
939                this->TOTALTIRAS        =       int(cStrips.size());
940        }
941        else
942        {
943                //      Error.
944        }
945}
946
947//---------------------------------------------------------------------------
948//      GetMesh: Return de current Mesh.
949//---------------------------------------------------------------------------
950Mesh    *       LodStripsConstructor::GetMesh()
951{
952        Mesh            *mesh_built;
953
954        mesh_built              =       new Mesh();
955        *mesh_built             =       *mGeoMesh;
956
957        return  mesh_built;
958}
959
960//---------------------------------------------------------------------------
961// Sets what is the submesh that stores the leaves.
962//---------------------------------------------------------------------------
963void LodStripsConstructor::SetSubMeshLeaves(size_t      submesh)
964{
965        mSubMeshLeaves  =       submesh;
966}
967
968//---------------------------------------------------------------------------
969//      Sort submesh bones.
970//---------------------------------------------------------------------------
971void LodStripsConstructor::sortBones()
972{
973        VertexBuffer                                    *mesh_vb;
974        VertexBuffer                                    *copy_vb;
975
976        std::vector<VertexBoneAssignment>       *mesh_bones;
977        std::vector<VertexBoneAssignment>       *copy_bones;
978
979        // After simplifying, the object always is shared vertex
980        // so, the bones must be placed in the GeoMesh
981        mesh_bones      =       &mGeoMesh->mBones;
982        mesh_vb =       mGeoMesh->mVertexBuffer;
983
984        // we assume the original mesh is shared vertex
985        // because before the simplification process
986        // the mesh becomes converted to shared vertex
987        // so, the original bones must be searched in the
988        // Mesh, not in every submesh
989
990        mesh_bones->clear();
991
992        //      Vertex buffers.
993        copy_vb =       mInitialMesh->mVertexBuffer;
994
995        //      Bones.
996        copy_bones = &mInitialMesh->mBones;
997       
998        //      If there are submesh bones.
999        for (int b = 0; b < copy_bones->size(); b++)
1000        {
1001                VertexBoneAssignment    assign;
1002
1003                int n   =       (*copy_bones)[b].vertexIndex;
1004
1005                //      Initialize o.
1006               
1007                int o=0;
1008                for (o=0; o<mesh_vb->mVertexCount; o++)
1009                {
1010                        if (mesh_vb->mPosition[o].x == copy_vb->mPosition[n].x &&
1011                                mesh_vb->mPosition[o].y == copy_vb->mPosition[n].y &&
1012                                mesh_vb->mPosition[o].z == copy_vb->mPosition[n].z)
1013                        {
1014                                assign.vertexIndex = o;
1015                                assign.boneIndex   = (*copy_bones)[b].boneIndex;
1016                                assign.weight      = 1.0f;
1017                                mesh_bones->push_back(assign);
1018                        }                       
1019                }
1020        }
1021}
1022
1023void LodStripsConstructor::UpdateMesh(void)
1024{
1025        int num_no      =       0;
1026        //int i=0,j=0;
1027
1028        if(this->mGeoMesh->mSubMesh[0].mSharedVertexBuffer == true)
1029        {
1030                //mPosition
1031                delete[] this->mGeoMesh->mVertexBuffer->mPosition;
1032                this->mGeoMesh->mVertexBuffer->mPosition = new Vector3[this->cVerts.size()];
1033
1034                //mNormal
1035                if (meshoriginal->mSubMesh[0].mVertexBuffer->mVertexInfo & Geometry::VERTEX_NORMAL)
1036                {
1037                        delete[] this->mGeoMesh->mVertexBuffer->mNormal;
1038                        this->mGeoMesh->mVertexBuffer->mNormal = new Vector3[this->cVerts.size()];
1039                }
1040
1041                //mTexCoords
1042                if (meshoriginal->mSubMesh[0].mVertexBuffer->mVertexInfo & Geometry::VERTEX_TEXCOORDS)
1043                {
1044                        delete[] this->mGeoMesh->mVertexBuffer->mTexCoords;
1045                        this->mGeoMesh->mVertexBuffer->mTexCoords = new Vector2[this->cVerts.size()];
1046                }
1047
1048                this->mGeoMesh->mVertexBuffer->mVertexCount     =       this->cVerts.size();
1049                this->mGeoMesh->mVertexBuffer->mVertexInfo              =       this->meshoriginal->mSubMesh[0].mVertexBuffer->mVertexInfo;
1050
1051                for(size_t      i = 0; i < this->mGeoMesh->mSubMeshCount; i++)
1052                {
1053                        this->mGeoMesh->mSubMesh[i].mVertexBuffer       =       this->mGeoMesh->mVertexBuffer;
1054                        this->mGeoMesh->mSubMesh[i].mSharedVertexBuffer =       true;
1055                }
1056
1057                int     indice  =       0;
1058
1059                for (size_t     j       =       0;      j < this->cVerts.size();        j++)
1060                {
1061                        //Copiamos las coordeandas de posicion
1062                        this->mGeoMesh->mVertexBuffer->mPosition[indice].x      =       this->cVerts[j].Vertex[0];
1063                        this->mGeoMesh->mVertexBuffer->mPosition[indice].y      =       this->cVerts[j].Vertex[1];
1064                        this->mGeoMesh->mVertexBuffer->mPosition[indice].z      =       this->cVerts[j].Vertex[2];
1065
1066                        //Copiamos las normales
1067                        if (meshoriginal->mVertexBuffer->mVertexInfo & Geometry::VERTEX_NORMAL)
1068                        {
1069                                this->mGeoMesh->mVertexBuffer->mNormal[indice].x        =       this->cVerts[j].Normal[0];
1070                                this->mGeoMesh->mVertexBuffer->mNormal[indice].y        =       this->cVerts[j].Normal[1];
1071                                this->mGeoMesh->mVertexBuffer->mNormal[indice].z        =       this->cVerts[j].Normal[2];
1072                        }
1073
1074                        //Copiamos las coordenadas de textura
1075                        if (meshoriginal->mVertexBuffer->mVertexInfo & Geometry::VERTEX_TEXCOORDS)
1076                        {
1077                                this->mGeoMesh->mVertexBuffer->mTexCoords[indice].x     =       this->cVerts[j].TexCoords[0];
1078                                this->mGeoMesh->mVertexBuffer->mTexCoords[indice].y     =       this->cVerts[j].TexCoords[1];
1079                        }
1080
1081                        indice++;
1082                }
1083
1084                this->mGeoMesh->mVertexBuffer->mVertexCount     =       indice;
1085        }
1086        else    //OSCAR
1087        {
1088                //Supondre que solo tengo un submesh con vertices no compartidos
1089                //mPosition
1090                delete[]        this->mGeoMesh->mSubMesh[0].mVertexBuffer->mPosition;
1091               
1092                this->mGeoMesh->mSubMesh[0].mVertexBuffer->mPosition    =       new Vector3[this->cVerts.size()];
1093
1094                //mNormal
1095                if (meshoriginal->mSubMesh[0].mVertexBuffer->mVertexInfo & Geometry::VERTEX_NORMAL)
1096                {
1097                        delete[] this->mGeoMesh->mSubMesh[0].mVertexBuffer->mNormal;
1098                        this->mGeoMesh->mSubMesh[0].mVertexBuffer->mNormal = new Vector3[this->cVerts.size()];
1099                }
1100
1101                //mTexCoords
1102                if (meshoriginal->mSubMesh[0].mVertexBuffer->mVertexInfo & Geometry::VERTEX_TEXCOORDS)
1103                {
1104                        delete[] this->mGeoMesh->mSubMesh[0].mVertexBuffer->mTexCoords;
1105                        this->mGeoMesh->mSubMesh[0].mVertexBuffer->mTexCoords = new Vector2[this->cVerts.size()];
1106                }
1107
1108                this->mGeoMesh->mSubMesh[0].mVertexBuffer->mVertexCount =this->cVerts.size();
1109                this->mGeoMesh->mSubMesh[0].mVertexBuffer->mVertexInfo = this->meshoriginal->mSubMesh[0].mVertexBuffer->mVertexInfo;
1110
1111                this->mGeoMesh->mSubMesh[0].mSharedVertexBuffer=false;
1112
1113                int     indice  =       0;
1114
1115                for (size_t     j       =       0;      j < this->cVerts.size();        j++)
1116                {
1117                        //Copiamos las coordeandas de posicion
1118                        this->mGeoMesh->mSubMesh[0].mVertexBuffer->mPosition[indice].x=this->cVerts[j].Vertex[0];
1119                        this->mGeoMesh->mSubMesh[0].mVertexBuffer->mPosition[indice].y=this->cVerts[j].Vertex[1];
1120                        this->mGeoMesh->mSubMesh[0].mVertexBuffer->mPosition[indice].z=this->cVerts[j].Vertex[2];
1121
1122                        //Copiamos las normales
1123                        if (meshoriginal->mSubMesh[0].mVertexBuffer->mVertexInfo & Geometry::VERTEX_NORMAL)
1124                        {
1125                                this->mGeoMesh->mSubMesh[0].mVertexBuffer->mNormal[indice].x=this->cVerts[j].Normal[0];
1126                                this->mGeoMesh->mSubMesh[0].mVertexBuffer->mNormal[indice].y=this->cVerts[j].Normal[1];
1127                                this->mGeoMesh->mSubMesh[0].mVertexBuffer->mNormal[indice].z=this->cVerts[j].Normal[2];
1128                        }
1129
1130                        //Copiamos las coordenadas de textura
1131                        if (meshoriginal->mSubMesh[0].mVertexBuffer->mVertexInfo & Geometry::VERTEX_TEXCOORDS)
1132                        {
1133                                this->mGeoMesh->mSubMesh[0].mVertexBuffer->mTexCoords[indice].x=this->cVerts[j].TexCoords[0];
1134                                this->mGeoMesh->mSubMesh[0].mVertexBuffer->mTexCoords[indice].y=this->cVerts[j].TexCoords[1];
1135                        }
1136                        indice++;
1137                }
1138                this->mGeoMesh->mSubMesh[0].mVertexBuffer->mVertexCount =indice;
1139        }
1140       
1141        int indice_acum = 0;
1142
1143        for(size_t      i = 0;  i < this->mGeoMesh->mSubMeshCount;      i++)
1144        {
1145                Geometry::SubMesh & subMesh = meshoriginal->mSubMesh[i];
1146                Geometry::SubMesh & mGeoMeshSubMesh = this->mGeoMesh->mSubMesh[i];
1147
1148                for (size_t ind=0; ind < subMesh.mIndexCount; ind++)
1149                {
1150                        Index indIndex = subMesh.mIndex[ind];
1151                        if (subMesh.mVertexBuffer->mVertexInfo & Geometry::VERTEX_TEXCOORDS)
1152                        {
1153                                //Hay coordenadas de textura y normales
1154                                if(subMesh.mVertexBuffer->mVertexInfo & Geometry::VERTEX_NORMAL)
1155                                {
1156                                        for (size_t indvo=0; indvo<mGeoMeshSubMesh.mVertexBuffer->mVertexCount; indvo++)
1157                                        {
1158                                                if (igual(subMesh.mVertexBuffer->mPosition[indIndex],mGeoMeshSubMesh.mVertexBuffer->mPosition[indvo]))
1159                                                {
1160                                                        if (igual(subMesh.mVertexBuffer->mNormal[indIndex],mGeoMeshSubMesh.mVertexBuffer->mNormal[indvo]))
1161                                                        {
1162                                                                if (igual(subMesh.mVertexBuffer->mTexCoords[indIndex],mGeoMeshSubMesh.mVertexBuffer->mTexCoords[indvo]))
1163                                                                {
1164                                                                        mGeoMeshSubMesh.mIndex[ind]= int(indvo);//+indice_acum;
1165                                                                }
1166                                                        }
1167                                                }
1168                                        }
1169                                }
1170                                else            //Hay coordenadas de textura pero no hay normales
1171                                {
1172                                        for (size_t indvo=0; indvo<mGeoMeshSubMesh.mVertexBuffer->mVertexCount; indvo++)
1173                                        {
1174                                                if (igual(subMesh.mVertexBuffer->mPosition[indIndex],mGeoMeshSubMesh.mVertexBuffer->mPosition[indvo]))
1175                                                {
1176                                                        if (igual(subMesh.mVertexBuffer->mTexCoords[indIndex],mGeoMeshSubMesh.mVertexBuffer->mTexCoords[indvo]))
1177                                                        {
1178                                                                mGeoMeshSubMesh.mIndex[ind]=int(indvo);//+indice_acum;
1179                                                        }
1180                                                }
1181                                        }
1182                                }
1183                        }
1184                        else
1185                        {
1186                                // No hay coordenadas de textura pero si normales
1187                                if(subMesh.mVertexBuffer->mVertexInfo & Geometry::VERTEX_NORMAL)
1188                                {
1189                                        for (size_t indvo=0; indvo<mGeoMeshSubMesh.mVertexBuffer->mVertexCount; indvo++)
1190                                        {
1191                                                if (igual(subMesh.mVertexBuffer->mPosition[indIndex],mGeoMeshSubMesh.mVertexBuffer->mPosition[indvo]))
1192                                                {
1193                                                        if (igual(subMesh.mVertexBuffer->mNormal[indIndex],mGeoMeshSubMesh.mVertexBuffer->mNormal[indvo]))
1194                                                        {
1195                                                                mGeoMeshSubMesh.mIndex[ind]=int(indvo);//+indice_acum;
1196                                                        }
1197                                                }
1198                                        }
1199                                }
1200                                else            //No hay coordenadas de texturas ni normales
1201                                {
1202                                        for (size_t indvo=0; indvo<mGeoMeshSubMesh.mVertexBuffer->mVertexCount; indvo++)
1203                                        {
1204                                                if (igual(subMesh.mVertexBuffer->mPosition[indIndex],mGeoMeshSubMesh.mVertexBuffer->mPosition[indvo]))
1205                                                {
1206                                                        mGeoMeshSubMesh.mIndex[ind]=int(indvo);//+indice_acum;
1207                                                }
1208                                        }
1209                                }
1210                        }
1211                }
1212        }
1213
1214        //      Sort submesh bones.
1215        this->sortBones();
1216}
1217
1218//---------------------------------------------------------------------------
1219//      Add new vertices to mesh.
1220//---------------------------------------------------------------------------
1221void LodStripsConstructor::AddNewVertices()
1222{
1223        int                             num_vertices;
1224        SubMesh                 *geosubmesh;
1225        VertexBuffer    *vertex_buffer;
1226        VertexBuffer    *new_vertex_buffer;
1227
1228        //      Gets old vertex buffer.
1229        vertex_buffer   =       mGeoMesh->mVertexBuffer;
1230       
1231        num_vertices    =       vertex_buffer->mVertexCount
1232                                                                        +
1233                                                mGeoMeshSQ->mNewVertices.size();
1234
1235        //      Initialize auxiliar vertex buffer.
1236        new_vertex_buffer       =       new     VertexBuffer();
1237
1238        new_vertex_buffer->mVertexCount =       num_vertices;
1239       
1240        new_vertex_buffer->mPosition            =       new     Vector3[num_vertices];
1241        new_vertex_buffer->mNormal                      =       new     Vector3[num_vertices];
1242        new_vertex_buffer->mTexCoords           =       new     Vector2[num_vertices];
1243
1244        new_vertex_buffer->mVertexInfo  =       vertex_buffer->mVertexInfo;
1245
1246        //      Num old vertices.
1247        num_vertices    =       vertex_buffer->mVertexCount;
1248
1249        //      Copy the old vertex buffer.
1250        for     (unsigned       int     i       =       0;      i < num_vertices;       i++)
1251        {
1252                new_vertex_buffer->mPosition[i] =       vertex_buffer->mPosition[i];
1253                new_vertex_buffer->mNormal[i]   =       vertex_buffer->mNormal[i];
1254                new_vertex_buffer->mTexCoords[i]=       vertex_buffer->mTexCoords[i];
1255        }
1256
1257
1258        //      Copy new vertices.
1259        std::vector<VertexBoneAssignment> newbones;
1260        for (unsigned   int     i       =       0;      i < mGeoMeshSQ->mNewVertices.size();    i++)
1261        {
1262                new_vertex_buffer->mPosition[num_vertices + i] = mGeoMeshSQ->mNewVertices[i].position;
1263                new_vertex_buffer->mTexCoords[num_vertices + i] = mGeoMeshSQ->mNewVertices[i].texcoord;
1264                new_vertex_buffer->mNormal[num_vertices + i] = mGeoMeshSQ->mNewVertices[i].normal;
1265
1266                // check if my twin-vertex-bone has a bone assignment
1267                // we check only the GeoMesh bones because the lodstrips only works for sharedvertex bones
1268                for (std::vector<VertexBoneAssignment>::iterator it = mGeoMesh->mBones.begin(); it != mGeoMesh->mBones.end(); it ++)
1269                {
1270                        if (it->vertexIndex == mGeoMeshSQ->mNewVertices[i].bonefrom)
1271                        {
1272                                VertexBoneAssignment vba;
1273                                vba.boneIndex = it->boneIndex;
1274                                vba.vertexIndex = mGeoMeshSQ->mNewVertices[i].id;
1275                                vba.weight = it->weight;
1276                                newbones.push_back(vba);
1277                        }
1278                }
1279        }
1280
1281        for (std::vector<VertexBoneAssignment>::iterator it = newbones.begin(); it != newbones.end(); it++)
1282                mGeoMesh->mBones.push_back(*it);
1283
1284
1285        //      For each submesh.
1286        for (unsigned int submesh       =       0; submesh < mGeoMesh->mSubMeshCount; submesh++)
1287        {
1288                geosubmesh      =       &mGeoMesh->mSubMesh[submesh];
1289
1290                geosubmesh->mVertexBuffer       =       new_vertex_buffer;
1291        }
1292
1293        delete  vertex_buffer;
1294       
1295        mGeoMesh->mVertexBuffer =       new_vertex_buffer;
1296}
1297
Note: See TracBrowser for help on using the repository browser.