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

Revision 2079, 31.9 KB checked in by gumbau, 17 years ago (diff)
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       
298        std::vector<tipoVertice>                                NuevosVerts;
299        std::vector<std::vector<int> >  NuevasTiras;
300        std::vector<int>                                                                tira;
301
302        tipoOrden                       Orden;
303        tipoOrden                       *Ord;
304        bool                                    bEncontrado;
305
306        //      Progress bar
307        float                   percent;
308        float                   increment;
309        long    int     update;
310
311        VertexBoneAssignment    bone;
312
313        bEncontrado = false;
314
315        size_t  mStepsSize = mGeoMeshSQ->mSteps.size();
316
317        update                  =       -1;
318        percent                 =       1.0;
319        increment               =       (float)(10.0) / (float)mStepsSize;
320       
321        for     (i = 0; i < mStepsSize; i++)
322        {
323                if (update      != (int)(i * increment))
324                {
325                        update  =       (int)(i * increment);
326                        upb(percent);
327                }
328               
329                const MeshSimplificationSequence::Step & theStep = this->mGeoMeshSQ->mSteps[i];
330
331                Orden.vQslimNext        =       theStep.mV0;
332                Orden.vQslim                    =       theStep.mV1;
333                Orden.obligatory        =       theStep.obligatory;
334                Orden.vLS                                       =       i;
335
336                Orden.x                                 =       theStep.x;
337                Orden.vLSNext           =       -1;
338                Orden.cambio            =       "n";
339
340                Ordenacion.push_back(Orden);
341        }
342       
343        update          =       -1;
344        increment       =       (float)(10.0) / (float)(Ordenacion.size());
345        percent         =       1.0;
346
347        update          =       -1;
348        increment       =       (float)(10.0) / (float)(Ordenacion.size());
349        percent         =       1.0;
350
351        //      3 seg.
352        //Ordenacion de los vertices
353        for (i = 0; i < Ordenacion.size(); i++)
354        {
355                if (update      !=      (int)(i * increment))
356                {
357                        update  =       (int)(i * increment);
358                        upb(percent);
359                }
360
361                int OrdvQslim = Ordenacion[i].vQslim;
362                //int OrdvQslimNext = Ordenacion[i].vQslimNext;
363
364                NuevosVerts.push_back(this->cVerts[OrdvQslim]);
365
366                cVerts[OrdvQslim].Next  =       -1;
367        }
368
369        //      Añadir aquellos vertices que no estaban en NuevosVerts
370        //      y no se simplificaban.
371        int cont                =       0;
372        int contestaban =       0;
373
374        size_t  cVertsSize = this->cVerts.size();
375        for(i = 0; i < cVertsSize; i++)
376        {
377                if (this->cVerts[i].Next != -1)
378                {
379                        cont++;
380                        NuevosVerts.push_back(this->cVerts[i]);
381                        Orden.vLS                       =       int(Ordenacion.size());
382                        Orden.obligatory        = 0;
383                        Orden.vLSNext           =       -1;
384                        Orden.vQslim            =       i;
385                        Orden.vQslimNext        =       -1;
386
387                        Ordenacion.push_back(Orden);
388                }
389                else
390                {
391                        contestaban++;
392                }
393        }
394
395        update          =       -1;
396        increment       =       (float)(10.0)   /       (float)(Ordenacion.size());
397        percent         =       1.0;
398       
399        //      2 min.
400        //      Calcular los siguiente teniendo en cuenta el simplif.
401        for (i = 0; i < Ordenacion.size(); i++)
402        {
403                if (update      !=      (int)(i * increment))
404                {
405                        update  =       (int)(i * increment);
406                        upb(percent);
407                }
408               
409                v       =       Ordenacion[i].vQslimNext;
410
411                //Buscar ese vertice v cual es ahora
412                vSig    =       0;
413
414                for (t = 0; t < Ordenacion.size() && !vSig;t++)
415                {
416                        if (Ordenacion[t].vQslim == v)
417                        {
418                                vSig    =       Ordenacion[t].vLS;
419                        }
420                }
421
422                if (vSig != 0)
423                {
424                        Ordenacion[i].vLSNext   =       vSig;
425                }
426       
427                //      Bone reassignment.
428                for (size_t assig = 0; assig < mInitialMesh->mBones.size(); assig++)
429                {
430                        if (mInitialMesh->mBones[assig].vertexIndex == Ordenacion[i].vQslim)
431                        {
432                                bone.vertexIndex        =       i;
433                                bone.boneIndex          =       mInitialMesh->mBones[assig].boneIndex;
434                                bone.weight                             =       mInitialMesh->mBones[assig].weight;
435
436                                mGeoMesh->mBones.push_back(bone);
437                        }
438                }
439        }
440
441        //Creacion de nuevas tiras con las mismas dimensiones
442        size_t  cStripsSize = this->cStrips.size();
443        for(t = 0; t < cStripsSize; t++)
444        {
445                tira.clear();
446
447                size_t  cStripsSizeT = this->cStrips[t].size();
448
449                for(i = 0; i < cStripsSizeT; i++)
450                {
451                        tira.push_back(0);
452                }
453
454                NuevasTiras.push_back(tira);
455        }
456
457        update          =       -1;
458        increment       =       (float)(20.0) / (float)(NuevosVerts.size());
459        percent         =       1.0;
460
461        k       =       0;
462
463        //      2 min.
464        //Cambiar los vertices de las tiras
465        size_t  NuevosVertsSize = NuevosVerts.size();
466
467        for(v = 0; v < NuevosVertsSize; v++)
468        {
469                if (update != (int)(v * increment))
470                {
471                        update  =       (int)(v * increment);
472                        upb(percent);
473                }               
474
475                const tipoOrden & OrdenacionV = Ordenacion[v];
476
477                for(t = 0; t < cStrips.size(); t++)
478                {
479                        std::vector<int> & thisStrip = cStrips[t];                     
480                        std::vector<int> & NuevasTirasT = NuevasTiras[t];
481                        size_t  cStripsSizeT = thisStrip.size();
482
483                        for(i = 0; i < cStripsSizeT; i++)
484                        {
485                                if (thisStrip[i] == OrdenacionV.vQslim)
486                                {
487                                        k++;
488                                        NuevasTirasT[i] =       v;
489                                }
490                        }
491                }
492        }
493
494        //Cambiar a Tiras Nuevas
495        this->cStrips   =       NuevasTiras;
496
497        //NuevosVerts y Ordenacion = tamaño.
498        NuevosVertsSize = NuevosVerts.size();
499
500        for(i = 0; i < NuevosVertsSize; i++)
501        {
502                NuevosVerts[i].Next     =       Ordenacion[i].vLSNext;
503        }
504
505        //Cambiar cVerts por nuevosVerts.
506        this->cVerts    =       NuevosVerts;
507
508        //percent       =       100.0;
509        //upb(percent);
510}
511
512//-------------------------------------------------------------------------
513//      Constructor of LodStripsConstructor object from
514//      a Mesh and MeshSimplificationSequence.
515//-------------------------------------------------------------------------
516LodStripsConstructor::LodStripsConstructor(const Mesh                                           *m,
517                                                                                                                const MeshSimplificationSequence        *ms,
518                                                                                                                        size_t                                                                                                          submesh,
519                                                                                                                        TIPOFUNC                                                                                                        upb)
520{
521        MARCA   =       TOTALTIRAS      =       TOTALVERTS      =       TOTALCAMBIOS    =       0;
522       
523        meshoriginal    =       m;
524       
525        mGeoMesh                        =       new Mesh();
526        *mGeoMesh                       =       *m;
527
528        //      Initialize bones assignments.
529        mGeoMesh->mBones.clear();
530
531        mInitialMesh    =       new Mesh();
532        *mInitialMesh   =       *m;
533       
534        this->mGeoMeshSQ        =       const_cast<MeshSimplificationSequence*>(ms);
535
536        //      Add new vertices to mesh.
537        AddNewVertices();
538
539        //      Set the leaves submesh.
540        mSubMeshLeaves  =       submesh;
541       
542        this->GenerarModeloCompleto(upb);
543}
544
545//-------------------------------------------------------------------------
546//      Destructor LodStripsConstructor object
547//-------------------------------------------------------------------------
548LodStripsConstructor::~LodStripsConstructor()
549{
550        delete [] vDatos;
551        delete [] vCambios;
552/*      vector <LODData> cCambiosTemp;
553        cCambios.swap(cCambiosTemp);*/
554        cCambios.clear();
555
556/*      VECTORUNINT cDatosTemp;
557        cDatos.swap(cDatosTemp);*/
558        cDatos.clear();
559
560        delete [] vStrips;
561        delete [] vVerts;
562
563//      vector <VECTORINT> cStripsTemp;
564//      cStrips.swap(cStripsTemp);;
565        cStrips.clear();
566
567//      VECTORVERTEX cVertsTemp;
568//      cVerts.swap(cVertsTemp);
569        cVerts.clear();
570
571        delete [] pCambios;
572        delete  mInitialMesh;
573        delete  mGeoMesh;
574}
575
576//-------------------------------------------------------------------------
577//      Build lod file with necessary information and save all changes at
578//      lodStripConstructor object.
579//-------------------------------------------------------------------------
580void LodStripsConstructor::Save(std::string filename)
581{
582        int vertexCount         =       (int)this->cVerts.size();
583        int changesCount        =       (int)this->cCambios.size();
584        int dataCount                   =       (int)this->cDatos.size();
585        int cambiosCount        =       this->TOTALCAMBIOS;
586        int size                                        =       changesCount*sizeof(LODData)
587                                                                                        +
588                                                                                        (vertexCount + dataCount + cambiosCount + 4)
589                                                                                        *
590                                                                                        sizeof(int)
591                                                                                        +
592                                                                                        CHUNK_OVERHEAD_SIZE;
593
594        FILE *f =       fopen(filename.c_str(),"ab");
595
596        unsigned short chunkid  =       0xabcd;
597
598        fwrite(&chunkid,sizeof(unsigned short),1,f);
599        fwrite(&size,sizeof(unsigned long),1,f);
600
601        // VERTICES.
602        fwrite(&vertexCount, sizeof(int), 1, f);
603
604        for (size_t     i = 0; i < this->cVerts.size(); i++)
605        {
606                int auxv        =       cVerts[i].Next;
607                fwrite(&auxv, sizeof(int), 1, f);
608        }
609
610        //      CSTRIPS.
611        this->TOTALINDICES      =       0;
612       
613        for (size_t     i = 0; i < this->cStrips.size(); i++)
614        {
615                this->TOTALINDICES += int(this->cStrips[i].size());
616        }
617
618        //      lines starting with a d.
619        //      Changes
620        fwrite(&changesCount, sizeof(int), 1, f);
621
622        for(size_t      i = 0; i < this->cCambios.size(); i++)
623        {
624                LODData change= cCambios[i];
625                fwrite(&change, sizeof(LODData), 1, f);
626        }
627
628        //      Data.
629        fwrite(&dataCount, sizeof(int), 1, f);
630
631        for(size_t      i = 0; i < this->cDatos.size(); i++)
632        {
633                int data= cDatos[i];
634                fwrite(&data, sizeof(int), 1, f);
635        }
636
637        //      lines starting with a p.
638        //      Chages made in a LOD.
639        fwrite(&cambiosCount, sizeof(int), 1, f);
640
641        for(size_t      i = 0; i < this->TOTALCAMBIOS; i++)
642        {
643                int cambio= pCambios[i];
644                fwrite(&cambio, sizeof(int), 1, f);
645        }
646
647        fclose(f);
648}
649
650int LodStripsConstructor::igual(Geometry::Vector3 vo,Geometry::Vector3 vc)
651{
652        if (vo.x==vc.x && vo.y==vc.y && vo.z==vc.z)
653                return 1;
654        else
655                return 0;
656}
657
658int LodStripsConstructor::igual(Geometry::Vector2 vo,Geometry::Vector2 vc)
659{
660        if (vo.x==vc.x && vo.y==vc.y)
661                return 1;
662        else
663                return 0;
664}
665
666/*void LodStripsConstructor::Load(Serializer &oSerializer)
667{
668}*/
669
670//---------------------------------------------------------------------------
671//      Call leeVerticesyTirasDeMesh, OrdenarModeloVQSLIM
672//      and CalcularCambiosLODsVNuevaED to make changes at vertex
673//      and index strutures.
674//---------------------------------------------------------------------------
675void LodStripsConstructor::GenerarModeloV(TIPOFUNC      upb)
676{
677        long int        max;
678        long int        t;
679        unsigned long int       i;
680        float                   percent;
681
682        percent =       10;
683
684        this->leeVerticesyTirasDeMesh();
685
686        upb(percent);
687
688        this->OrdenarModeloVQSLIM(upb);
689
690        //Calcular el tamaño maximo de tira
691        max     =       0;
692
693        for(i = 0; i < this->TOTALTIRAS; i++)
694        {
695                t = long(this->cStrips[i].size());             
696                if (t > max)
697                        max     = t;
698        }
699
700        this->MARCA     =       max + 1;
701        this->CalcularCambiosLODsVNuevaED(upb);
702}
703
704//---------------------------------------------------------------------------
705//      It fills structs with vertex and index information.
706//---------------------------------------------------------------------------
707void LodStripsConstructor::CopiarVectors2ArraysNUEVAED()
708{
709        unsigned int            i;
710        unsigned int            j;
711        uint32                  max;
712        uint32                  t;
713        VECTORINT               tira;
714        LODChanges      listaCambios;
715
716        //      ALLOCATE----------------
717        this->TOTALVERTS        =       int(this->cVerts.size());
718        this->TOTALTIRAS        =       int(this->cStrips.size());
719        this->vVerts                    =       new tipoVertice[this->TOTALVERTS];
720        this->lStripsV          =       new VECTORINT[this->TOTALTIRAS];
721        this->vDatos                    =       new uint32[cDatos.size()];
722       
723        //      Calcular el tamaño maximo de tira y el numero de caras total.
724        max                                                             =       0;
725        this->TOTALCARAS        =       0;
726
727        for     (i = 0; i < this->cStrips.size(); i++)
728        {
729                t       =       int(this->cStrips[i].size());
730               
731                if (t > max)
732                {
733                        max     =       t;
734                }
735
736                this->TOTALCARAS        +=      (t-2);
737        }
738       
739        this->vStrips   =       Allocate2DArrayINT(this->TOTALTIRAS,max+1);
740        this->MARCA             =       int(this->cVerts.size());
741        vCambios                        =       new LODData[this->cCambios.size()];
742       
743        //      Rellenar vChanges.
744        for     (i = 0; i < this->cCambios.size();++i)
745        {
746                vCambios[i]     =       cCambios[i];
747        }
748       
749        for (i = 0; i < this->cStrips.size(); i++)
750        {
751                for (j = 0; j < this->cStrips[i].size(); j++)
752                {
753                        //      Rellenar el array vStrips.
754                        this->vStrips[i][j]     = this->cStrips[i][j];
755                       
756                        //      Rellenar el vVector.
757                        this->lStripsV[i].push_back(this->cStrips[i][j]);
758                }
759               
760                this->vStrips[i][j]     =       this->MARCA;
761        }
762
763        for (i = 0; i < cDatos.size(); i++)
764        {
765                vDatos[i]       =       cDatos[i];
766        }
767       
768        pCurrentData    =       vDatos;
769
770        //      Meter los vertices en vVerts.
771        for     (i = 0; i < this->cVerts.size(); i++)
772        {
773                this->vVerts[i] =       this->cVerts[i];
774        }
775
776}
777
778//---------------------------------------------------------------------------
779//      It fills cVerts and cStrips with original Mesh vertex and strips
780//      information.
781//---------------------------------------------------------------------------
782void LodStripsConstructor::leeVerticesyTirasDeMesh()
783{
784        tipoVertice     vAux;
785        std::vector<int>                tira;
786        size_t                  i;
787        size_t                  j;
788        bool                            error;
789
790        error   =       false;
791       
792        if(this->mGeoMesh->mSubMeshCount == 1)
793        {
794                error   =       false;
795        }
796        else
797        {
798                for     (i = 0; i < this->mGeoMesh->mSubMeshCount;i++)
799                {
800                        if      (this->mGeoMesh->mSubMesh[i].mSharedVertexBuffer == true)
801                        {
802                                error   =       false;
803                        }
804                        else
805                        {
806                                error   =       true;
807                                break;
808                        }
809                }
810        }
811       
812        if(!error)
813        {
814                if      (       (this->mGeoMesh->mSubMesh[0].mSharedVertexBuffer == true)
815                                        &&
816                                        (this->mGeoMesh->mSubMeshCount > 1)
817                                )
818                {
819                        for     (j = 0; j < this->mGeoMesh->mVertexBuffer->mVertexCount; j++)
820                        {
821                                //      Si hay mas de un submesh ListaIndices no se rellena correctamente
822                                vAux.Vertex[0] = this->mGeoMesh->mVertexBuffer->mPosition[j].x;
823                                vAux.Vertex[1] = this->mGeoMesh->mVertexBuffer->mPosition[j].y;
824                                vAux.Vertex[2] = this->mGeoMesh->mVertexBuffer->mPosition[j].z;
825
826                                //      Añadimos las normales en cVerts.
827                                if      (       this->mGeoMesh->mVertexBuffer->mVertexInfo
828                                                        &
829                                                        Geometry::VERTEX_NORMAL
830                                                )
831                                {
832                                        vAux.Normal[0] = this->mGeoMesh->mVertexBuffer->mNormal[j].x;
833                                        vAux.Normal[1] = this->mGeoMesh->mVertexBuffer->mNormal[j].y;
834                                        vAux.Normal[2] = this->mGeoMesh->mVertexBuffer->mNormal[j].z;
835                                }
836
837                                //      Añadimos las coordenadas de textura a cVerts.
838                                if      (       this->mGeoMesh->mVertexBuffer->mVertexInfo
839                                                        &
840                                                        Geometry::VERTEX_TEXCOORDS
841                                                )
842                                {
843                                        vAux.TexCoords[0] = this->mGeoMesh->mVertexBuffer->mTexCoords[j].x;
844                                        vAux.TexCoords[1] = this->mGeoMesh->mVertexBuffer->mTexCoords[j].y;
845                                }
846
847                                vAux.Next               =       -10;
848                                vAux.numMesh    =       0;                     
849                                vAux.obligatory =       0;
850                               
851                                this->cVerts.push_back(vAux);
852                        }
853                }
854                else
855                {
856                        for     (i = 0; i < this->mGeoMesh->mSubMeshCount; i++)
857                        {
858                                for     (       j = 0;
859                                                j < this->mGeoMesh->mSubMesh[i].mVertexBuffer->mVertexCount;
860                                                j++)
861                                {
862                                        //      Si hay mas de un submesh ListaIndices
863                                        //      no se rellena correctamente.
864                                        vAux.Vertex[0] = this->mGeoMesh->mSubMesh[i].
865                                                mVertexBuffer->mPosition[j].x;
866                                        vAux.Vertex[1] = this->mGeoMesh->mSubMesh[i].
867                                                mVertexBuffer->mPosition[j].y;
868                                        vAux.Vertex[2] = this->mGeoMesh->mSubMesh[i].
869                                                mVertexBuffer->mPosition[j].z;
870                                        //      Añadimos las normales en cVerts.
871                                        vAux.Normal[0] = this->mGeoMesh->mSubMesh[i].
872                                                mVertexBuffer->mNormal[j].x;
873                                        vAux.Normal[1] = this->mGeoMesh->mSubMesh[i].
874                                                mVertexBuffer->mNormal[j].y;
875                                        vAux.Normal[2] = this->mGeoMesh->mSubMesh[i].
876                                                mVertexBuffer->mNormal[j].z;
877
878                                        //      Añadimos las coordenadas de textura a cVerts.
879                                        vAux.TexCoords[0]       =       this->mGeoMesh->mSubMesh[i].
880                                                mVertexBuffer->mTexCoords[j].x;
881                                        vAux.TexCoords[1] = this->mGeoMesh->mSubMesh[i].
882                                                mVertexBuffer->mTexCoords[j].y;
883
884                                        vAux.Next                       =       -10;
885                                        vAux.numMesh    =       int(i);
886
887                                        this->cVerts.push_back(vAux);
888                                }
889                        }
890                }       
891
892                Index   indice_acum;
893                Index   num_vert;
894
895                num_vert        =       0;
896
897                // load the strips list         
898                for     (i = 0; i < this->mGeoMesh->mSubMeshCount; i++)
899                {
900                        //      If is not the leaves submesh.
901                        if (mSubMeshLeaves != i)
902                        {
903                                indice_acum     =       0;
904
905                                for     (j = 0; j < this->mGeoMesh->mSubMesh[i].mStripCount; j++)
906                                {
907                                        Index   *aux    =       this->mGeoMesh->mSubMesh[i].mStrip[j];
908
909                                        // remove strip degenerates (first indices) except for the first (DEG!)
910                                        if (j != 0)
911                                        {
912                                                // La primera tira no empieza por índices repetidos.
913                                                aux     = aux+1;
914                                                indice_acum++;
915                                        }
916                                       
917                                        if (j+1 < this->mGeoMesh->mSubMesh[i].mStripCount)
918                                        {
919                                                Index   *siguiente      =       this->mGeoMesh->mSubMesh[i].mStrip[j+1];
920
921                                                tira.clear();
922
923                                                while (aux != siguiente)
924                                                {
925                                                        tira.push_back(*aux);
926                                                        indice_acum++;
927
928                                                        aux     =       aux + 1;
929                                                }
930
931                                                // DEG!: remove strip degenerates (last indices) except for the last strip
932                                                tira.pop_back();
933
934                                                this->cStrips.push_back(tira);
935                                        }
936                                        else
937                                        {
938                                                // Insertar los indices de la última tira en el cStrips
939                                                tira.clear();
940
941                                                for     (       unsigned int k = indice_acum;
942                                                                k < this->mGeoMesh->mSubMesh[i].mIndexCount;
943                                                                k++)
944                                                {
945                                                        tira.push_back(this->mGeoMesh->mSubMesh[i].mIndex[k]);
946                                                }
947
948                                                this->cStrips.push_back(tira);
949                                        }
950                                }
951
952                                num_vert        +=      int(this->mGeoMesh->mSubMesh[i].
953                                        mVertexBuffer->mVertexCount);
954                        }
955                }
956
957                this->TOTALVERTS        =       int(cVerts.size());
958                this->TOTALTIRAS        =       int(cStrips.size());
959        }
960        else
961        {
962                //      Error.
963        }
964}
965
966//---------------------------------------------------------------------------
967//      GetMesh: Return de current Mesh.
968//---------------------------------------------------------------------------
969Mesh    *       LodStripsConstructor::GetMesh()
970{
971        Mesh            *mesh_built;
972
973        mesh_built              =       new Mesh();
974        *mesh_built             =       *mGeoMesh;
975
976        return  mesh_built;
977}
978
979//---------------------------------------------------------------------------
980// Sets what is the submesh that stores the leaves.
981//---------------------------------------------------------------------------
982void LodStripsConstructor::SetSubMeshLeaves(size_t      submesh)
983{
984        mSubMeshLeaves  =       submesh;
985}
986
987//---------------------------------------------------------------------------
988//      Update mesh.
989//---------------------------------------------------------------------------
990void LodStripsConstructor::UpdateMesh(void)
991{
992        int num_no      =       0;
993        //int i=0,j=0;
994
995        if(this->mGeoMesh->mSubMesh[0].mSharedVertexBuffer == true)
996        {
997                //mPosition
998                delete[] this->mGeoMesh->mVertexBuffer->mPosition;
999                this->mGeoMesh->mVertexBuffer->mPosition = new Vector3[this->cVerts.size()];
1000
1001                //mNormal
1002                if (meshoriginal->mSubMesh[0].mVertexBuffer->mVertexInfo & Geometry::VERTEX_NORMAL)
1003                {
1004                        delete[] this->mGeoMesh->mVertexBuffer->mNormal;
1005                        this->mGeoMesh->mVertexBuffer->mNormal = new Vector3[this->cVerts.size()];
1006                }
1007
1008                //mTexCoords
1009                if (meshoriginal->mSubMesh[0].mVertexBuffer->mVertexInfo & Geometry::VERTEX_TEXCOORDS)
1010                {
1011                        delete[] this->mGeoMesh->mVertexBuffer->mTexCoords;
1012                        this->mGeoMesh->mVertexBuffer->mTexCoords = new Vector2[this->cVerts.size()];
1013                }
1014
1015                this->mGeoMesh->mVertexBuffer->mVertexCount     =       this->cVerts.size();
1016                this->mGeoMesh->mVertexBuffer->mVertexInfo              =       this->meshoriginal->mSubMesh[0].mVertexBuffer->mVertexInfo;
1017
1018                for(size_t      i = 0; i < this->mGeoMesh->mSubMeshCount; i++)
1019                {
1020                        this->mGeoMesh->mSubMesh[i].mVertexBuffer       =       this->mGeoMesh->mVertexBuffer;
1021                        this->mGeoMesh->mSubMesh[i].mSharedVertexBuffer =       true;
1022                }
1023
1024                int     indice  =       0;
1025
1026                for (size_t     j       =       0;      j < this->cVerts.size();        j++)
1027                {
1028                        //Copiamos las coordeandas de posicion
1029                        this->mGeoMesh->mVertexBuffer->mPosition[indice].x      =       this->cVerts[j].Vertex[0];
1030                        this->mGeoMesh->mVertexBuffer->mPosition[indice].y      =       this->cVerts[j].Vertex[1];
1031                        this->mGeoMesh->mVertexBuffer->mPosition[indice].z      =       this->cVerts[j].Vertex[2];
1032
1033                        //Copiamos las normales
1034                        if (meshoriginal->mVertexBuffer->mVertexInfo & Geometry::VERTEX_NORMAL)
1035                        {
1036                                this->mGeoMesh->mVertexBuffer->mNormal[indice].x        =       this->cVerts[j].Normal[0];
1037                                this->mGeoMesh->mVertexBuffer->mNormal[indice].y        =       this->cVerts[j].Normal[1];
1038                                this->mGeoMesh->mVertexBuffer->mNormal[indice].z        =       this->cVerts[j].Normal[2];
1039                        }
1040
1041                        //Copiamos las coordenadas de textura
1042                        if (meshoriginal->mVertexBuffer->mVertexInfo & Geometry::VERTEX_TEXCOORDS)
1043                        {
1044                                this->mGeoMesh->mVertexBuffer->mTexCoords[indice].x     =       this->cVerts[j].TexCoords[0];
1045                                this->mGeoMesh->mVertexBuffer->mTexCoords[indice].y     =       this->cVerts[j].TexCoords[1];
1046                        }
1047
1048                        indice++;
1049                }
1050
1051                this->mGeoMesh->mVertexBuffer->mVertexCount     =       indice;
1052        }
1053        else    //OSCAR
1054        {
1055                //Supondre que solo tengo un submesh con vertices no compartidos
1056                //mPosition
1057                delete[]        this->mGeoMesh->mSubMesh[0].mVertexBuffer->mPosition;
1058               
1059                this->mGeoMesh->mSubMesh[0].mVertexBuffer->mPosition    =       new Vector3[this->cVerts.size()];
1060
1061                //mNormal
1062                if (meshoriginal->mSubMesh[0].mVertexBuffer->mVertexInfo & Geometry::VERTEX_NORMAL)
1063                {
1064                        delete[] this->mGeoMesh->mSubMesh[0].mVertexBuffer->mNormal;
1065                        this->mGeoMesh->mSubMesh[0].mVertexBuffer->mNormal = new Vector3[this->cVerts.size()];
1066                }
1067
1068                //mTexCoords
1069                if (meshoriginal->mSubMesh[0].mVertexBuffer->mVertexInfo & Geometry::VERTEX_TEXCOORDS)
1070                {
1071                        delete[] this->mGeoMesh->mSubMesh[0].mVertexBuffer->mTexCoords;
1072                        this->mGeoMesh->mSubMesh[0].mVertexBuffer->mTexCoords = new Vector2[this->cVerts.size()];
1073                }
1074
1075                this->mGeoMesh->mSubMesh[0].mVertexBuffer->mVertexCount =this->cVerts.size();
1076                this->mGeoMesh->mSubMesh[0].mVertexBuffer->mVertexInfo = this->meshoriginal->mSubMesh[0].mVertexBuffer->mVertexInfo;
1077
1078                this->mGeoMesh->mSubMesh[0].mSharedVertexBuffer=false;
1079
1080                int     indice  =       0;
1081
1082                for (size_t     j       =       0;      j < this->cVerts.size();        j++)
1083                {
1084                        //Copiamos las coordeandas de posicion
1085                        this->mGeoMesh->mSubMesh[0].mVertexBuffer->mPosition[indice].x=this->cVerts[j].Vertex[0];
1086                        this->mGeoMesh->mSubMesh[0].mVertexBuffer->mPosition[indice].y=this->cVerts[j].Vertex[1];
1087                        this->mGeoMesh->mSubMesh[0].mVertexBuffer->mPosition[indice].z=this->cVerts[j].Vertex[2];
1088
1089                        //Copiamos las normales
1090                        if (meshoriginal->mSubMesh[0].mVertexBuffer->mVertexInfo & Geometry::VERTEX_NORMAL)
1091                        {
1092                                this->mGeoMesh->mSubMesh[0].mVertexBuffer->mNormal[indice].x=this->cVerts[j].Normal[0];
1093                                this->mGeoMesh->mSubMesh[0].mVertexBuffer->mNormal[indice].y=this->cVerts[j].Normal[1];
1094                                this->mGeoMesh->mSubMesh[0].mVertexBuffer->mNormal[indice].z=this->cVerts[j].Normal[2];
1095                        }
1096
1097                        //Copiamos las coordenadas de textura
1098                        if (meshoriginal->mSubMesh[0].mVertexBuffer->mVertexInfo & Geometry::VERTEX_TEXCOORDS)
1099                        {
1100                                this->mGeoMesh->mSubMesh[0].mVertexBuffer->mTexCoords[indice].x=this->cVerts[j].TexCoords[0];
1101                                this->mGeoMesh->mSubMesh[0].mVertexBuffer->mTexCoords[indice].y=this->cVerts[j].TexCoords[1];
1102                        }
1103                        indice++;
1104                }
1105                this->mGeoMesh->mSubMesh[0].mVertexBuffer->mVertexCount =indice;
1106        }
1107       
1108        int indice_acum = 0;
1109
1110        for(size_t      i = 0;  i < this->mGeoMesh->mSubMeshCount;      i++)
1111        {
1112                Geometry::SubMesh & subMesh = meshoriginal->mSubMesh[i];
1113                Geometry::SubMesh & mGeoMeshSubMesh = this->mGeoMesh->mSubMesh[i];
1114
1115                for (size_t ind=0; ind < subMesh.mIndexCount; ind++)
1116                {
1117                        Index indIndex = subMesh.mIndex[ind];
1118                        if (subMesh.mVertexBuffer->mVertexInfo & Geometry::VERTEX_TEXCOORDS)
1119                        {
1120                                //Hay coordenadas de textura y normales
1121                                if(subMesh.mVertexBuffer->mVertexInfo & Geometry::VERTEX_NORMAL)
1122                                {
1123                                        for (size_t indvo=0; indvo<mGeoMeshSubMesh.mVertexBuffer->mVertexCount; indvo++)
1124                                        {
1125                                                if (igual(subMesh.mVertexBuffer->mPosition[indIndex],mGeoMeshSubMesh.mVertexBuffer->mPosition[indvo]))
1126                                                {
1127                                                        if (igual(subMesh.mVertexBuffer->mNormal[indIndex],mGeoMeshSubMesh.mVertexBuffer->mNormal[indvo]))
1128                                                        {
1129                                                                if (igual(subMesh.mVertexBuffer->mTexCoords[indIndex],mGeoMeshSubMesh.mVertexBuffer->mTexCoords[indvo]))
1130                                                                {
1131                                                                        mGeoMeshSubMesh.mIndex[ind]= int(indvo);//+indice_acum;
1132                                                                }
1133                                                        }
1134                                                }
1135                                        }
1136                                }
1137                                else            //Hay coordenadas de textura pero no hay normales
1138                                {
1139                                        for (size_t indvo=0; indvo<mGeoMeshSubMesh.mVertexBuffer->mVertexCount; indvo++)
1140                                        {
1141                                                if (igual(subMesh.mVertexBuffer->mPosition[indIndex],mGeoMeshSubMesh.mVertexBuffer->mPosition[indvo]))
1142                                                {
1143                                                        if (igual(subMesh.mVertexBuffer->mTexCoords[indIndex],mGeoMeshSubMesh.mVertexBuffer->mTexCoords[indvo]))
1144                                                        {
1145                                                                mGeoMeshSubMesh.mIndex[ind]=int(indvo);//+indice_acum;
1146                                                        }
1147                                                }
1148                                        }
1149                                }
1150                        }
1151                        else
1152                        {
1153                                // No hay coordenadas de textura pero si 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                                                                mGeoMeshSubMesh.mIndex[ind]=int(indvo);//+indice_acum;
1163                                                        }
1164                                                }
1165                                        }
1166                                }
1167                                else            //No hay coordenadas de texturas ni normales
1168                                {
1169                                        for (size_t indvo=0; indvo<mGeoMeshSubMesh.mVertexBuffer->mVertexCount; indvo++)
1170                                        {
1171                                                if (igual(subMesh.mVertexBuffer->mPosition[indIndex],mGeoMeshSubMesh.mVertexBuffer->mPosition[indvo]))
1172                                                {
1173                                                        mGeoMeshSubMesh.mIndex[ind]=int(indvo);//+indice_acum;
1174                                                }
1175                                        }
1176                                }
1177                        }
1178                }
1179        }
1180}
1181
1182//-------------------------------------------------------------------------
1183//      Add new vertices to mesh.
1184//-------------------------------------------------------------------------
1185void LodStripsConstructor::AddNewVertices()
1186{
1187        size_t                          num_vertices;
1188        size_t                          bones_count;
1189        SubMesh                         *geosubmesh;
1190        VertexBuffer    *vertex_buffer;
1191        VertexBuffer    *new_vertex_buffer;
1192
1193        vector<VertexBoneAssignment>::iterator  it;
1194
1195        //      Gets old vertex buffer.
1196        vertex_buffer   =       mGeoMesh->mVertexBuffer;
1197       
1198        num_vertices    =       vertex_buffer->mVertexCount
1199                                                                        +
1200                                                mGeoMeshSQ->mNewVertices.size();
1201
1202        //      Initialize auxiliar vertex buffer.
1203        new_vertex_buffer       =       new     VertexBuffer();
1204
1205        new_vertex_buffer->mVertexCount =       num_vertices;
1206       
1207        new_vertex_buffer->mPosition            =       new     Vector3[num_vertices];
1208        new_vertex_buffer->mNormal                      =       new     Vector3[num_vertices];
1209        new_vertex_buffer->mTexCoords           =       new     Vector2[num_vertices];
1210
1211        new_vertex_buffer->mVertexInfo  =       vertex_buffer->mVertexInfo;
1212
1213        //      Num old vertices.
1214        num_vertices    =       vertex_buffer->mVertexCount;
1215
1216        //      Copy the old vertex buffer.
1217        for     (unsigned       int     i       =       0;      i < num_vertices;       i++)
1218        {
1219                new_vertex_buffer->mPosition[i] =       vertex_buffer->mPosition[i];
1220                new_vertex_buffer->mNormal[i]   =       vertex_buffer->mNormal[i];
1221                new_vertex_buffer->mTexCoords[i]=       vertex_buffer->mTexCoords[i];
1222        }
1223
1224        //      Copy new vertices.
1225        for (unsigned   int     i       =       0;      i < mGeoMeshSQ->mNewVertices.size();    i++)
1226        {
1227                new_vertex_buffer->mPosition[num_vertices + i] =
1228                                                                                                                                                mGeoMeshSQ->mNewVertices[i].position;
1229
1230                new_vertex_buffer->mTexCoords[num_vertices + i] =
1231                                                                                                                                                mGeoMeshSQ->mNewVertices[i].texcoord;
1232
1233                new_vertex_buffer->mNormal[num_vertices + i] =
1234                                                                                                                                                mGeoMeshSQ->mNewVertices[i].normal;
1235
1236                //      Initialize number of bones.
1237                bones_count     =       mInitialMesh->mBones.size();
1238
1239                // Check if my twin-vertex-bone has a bone assignment
1240                // we check only the GeoMesh bones because the lodstrips
1241                // only works for sharedvertex bones
1242                for (int bone = 0; bone < bones_count; bone++)
1243                {
1244                        it      =       mInitialMesh->mBones.begin() + bone;
1245
1246                        if (it->vertexIndex == mGeoMeshSQ->mNewVertices[i].bonefrom)
1247                        {
1248                                VertexBoneAssignment vba;
1249
1250                                vba.boneIndex           =       it->boneIndex;
1251                                vba.vertexIndex =       mGeoMeshSQ->mNewVertices[i].id;
1252                                vba.weight                      =       it->weight;
1253
1254                                mInitialMesh->mBones.push_back(vba);
1255                                bones_count++;
1256                        }
1257                }
1258        }
1259
1260        //      For each submesh.
1261        for (unsigned int submesh       =       0; submesh < mGeoMesh->mSubMeshCount; submesh++)
1262        {
1263                geosubmesh      =       &mGeoMesh->mSubMesh[submesh];
1264
1265                geosubmesh->mVertexBuffer       =       new_vertex_buffer;
1266        }
1267
1268        delete  vertex_buffer;
1269       
1270        mGeoMesh->mVertexBuffer =       new_vertex_buffer;
1271}
1272
Note: See TracBrowser for help on using the repository browser.