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

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