source: GTP/trunk/Lib/Geom/shared/GTGeometry/src/GeoMeshSimplifier.cpp @ 2323

Revision 2323, 29.6 KB checked in by gumbau, 18 years ago (diff)
Line 
1#include "GeoMeshSimplifier.h"
2#include "GeoMeshSimpSequence.h"
3#include "SimplificationMethod.h"
4#include <iostream>
5#include <fstream>
6
7using namespace Geometry;
8using namespace std;
9
10//////////////////////////////////////////////////////////////////////////
11//                                                                                                                                                                                                                                                                                      //
12//                                                                                      MeshSimplifier class                                                                                                            //
13//                                                                                                                                                                                                                                                                                      //
14//////////////////////////////////////////////////////////////////////////
15
16//-------------------------------------------------------------------------
17//      MeshSimplifier constructor.
18//-------------------------------------------------------------------------
19MeshSimplifier::MeshSimplifier( const Mesh      *m,
20                                                                                                                                TIPOFUNC                upb)
21{
22        //      Saves initial state of mesh.
23        mInitialMesh    =       new Mesh();
24        *mInitialMesh   =       *m;
25       
26        mGeoMesh                                =       NULL;
27        msimpsequence           =       NULL;
28        indexMeshLeaves =       -1;
29
30        //      Sets the actual progress bar function.
31        mUPB    =       upb;
32}
33
34//-------------------------------------------------------------------------
35//      MeshSimplifier destroyer.
36//-------------------------------------------------------------------------
37MeshSimplifier::~MeshSimplifier()
38{
39        delete  mInitialMesh;
40        delete  msimpsequence;
41}
42
43//-------------------------------------------------------------------------
44//      Erase submeshes that have not indices.
45//-------------------------------------------------------------------------
46void    MeshSimplifier::eraseVoidSubMeshes(Mesh *geoMesh)
47{
48        SubMesh *geosubmesh;
49        size_t  valid_submesh_count;
50        size_t  submesh;
51
52        valid_submesh_count     =       0;
53
54        //      For each submesh.
55        for     (size_t i       =       0; i < geoMesh->mSubMeshCount;  i++)
56        {
57                if ((geoMesh->mSubMesh[i].mIndexCount > 0)
58                                ||
59                                (indexMeshLeaves == i))
60                {
61                        valid_submesh_count++;
62                }
63        }
64
65        //      Reserve memory for valid submeshes.
66        geosubmesh      =       new     SubMesh[valid_submesh_count];
67
68        submesh =       0;
69       
70        //      For each submesh.
71        for (size_t i = 0; i < geoMesh->mSubMeshCount; i++)
72        {
73                //      If leaves submesh is found.
74                if (indexMeshLeaves == i)
75                {
76                        geosubmesh[i].mStripCount       =       0;
77                        geosubmesh[i].mStrip                    =       NULL;
78
79                        geosubmesh[i].mSharedVertexBuffer       =       false;
80
81                        strcpy( geosubmesh[i].mMaterialName,
82                                        mInitialMesh->mSubMesh[i].mMaterialName);
83
84                        //      Copy submesh bones.
85                        if (!mInitialMesh->mSubMesh[i].mBones.empty())
86                        {
87                                for (   size_t j = 0;
88                                                j < mInitialMesh->mSubMesh[i].mBones.size();
89                                                j++)
90                                {
91                                        geosubmesh[i].mBones.push_back(mInitialMesh->
92                                                        mSubMesh[i].mBones[j]);
93                                }
94                        }
95
96                        //      Leaves mesh.
97                        geosubmesh[i].mIndexCount       =       
98                                mInitialMesh->mSubMesh[i].mIndexCount;
99
100                        geosubmesh[i].mIndex    =
101                                new Geometry::Index[geosubmesh[i].mIndexCount];
102
103                        memcpy( geosubmesh[i].mIndex,
104                                        mInitialMesh->mSubMesh[i].mIndex,
105                                        mInitialMesh->mSubMesh[i].mIndexCount * sizeof(Index));
106
107                        //      Copy the leaves submesh vertices.
108                        geosubmesh[i].mVertexBuffer     =
109                                mInitialMesh->mSubMesh[i].mVertexBuffer->Clone();
110
111                        //      Next valid submesh.
112                        submesh++;
113                }
114                else if (geoMesh->mSubMesh[i].mIndexCount > 0)
115                {
116                        geosubmesh[submesh].mSharedVertexBuffer =
117                                                                        geoMesh->mSubMesh[i].mSharedVertexBuffer;
118
119                        geosubmesh[submesh].mVertexBuffer       =       geoMesh->mVertexBuffer;
120
121                        geosubmesh[submesh].mType                               =       geoMesh->mSubMesh[i].mType;
122
123                        geosubmesh[submesh].mStripCount =       geoMesh->mSubMesh[i].mStripCount;
124
125                        geosubmesh[submesh].mIndexCount =       geoMesh->mSubMesh[i].mIndexCount;
126
127                        //      Reserve memory for indices.
128                        geosubmesh[submesh].mIndex      =
129                                                                                                        new Index[geosubmesh[submesh].mIndexCount];
130
131                        //      Copy indices.
132                        memcpy( geosubmesh[submesh].mIndex,
133                                        geoMesh->mSubMesh[i].mIndex,
134                                        geoMesh->mSubMesh[i].mIndexCount * sizeof(Index));
135
136                        //      Reserve memory for array of strips.
137                        geosubmesh[submesh].mStrip      =
138                                new Index*[geoMesh->mSubMesh[submesh].mStripCount];
139
140                        //      Copy strip list of the submesh.
141                        for (size_t j = 0; j < geoMesh->mSubMesh[i].mStripCount; j++)
142                        {
143                                geosubmesh[submesh].mStrip[j]   =       geoMesh->mSubMesh[i].mStrip[j];
144                        }
145
146                        strcpy( geosubmesh[submesh].mMaterialName,
147                                        geoMesh->mSubMesh[i].mMaterialName);
148
149                        for (size_t     j       =       0;      j < geoMesh->mSubMesh[i].mBones.size(); j++)
150                        {
151                                geosubmesh[submesh].mBones
152                                        .push_back(geoMesh->mSubMesh[i].mBones[j]);
153                        }
154
155                        //      Next valid submesh.
156                        submesh++;
157                }
158        }
159
160        //      Delete submeshes.
161        delete  []geoMesh->mSubMesh;
162
163        geoMesh->mSubMeshCount  =       valid_submesh_count;
164        geoMesh->mSubMesh                               =       geosubmesh;
165}
166
167//-------------------------------------------------------------------------
168// Returns the simplified mesh.
169//-------------------------------------------------------------------------
170Mesh *  MeshSimplifier::GetMesh()
171{
172        //      Delete void submeshes.
173        eraseVoidSubMeshes(mGeoMesh);
174
175        return mGeoMesh;
176}
177
178//-------------------------------------------------------------------------
179//      Set submesh leaves
180//-------------------------------------------------------------------------
181void MeshSimplifier::setMeshLeaves(Geometry::Index index)
182{
183        indexMeshLeaves =       index;
184}
185
186//-------------------------------------------------------------------------
187// Returns the simplification sequence for general meshes.
188//-------------------------------------------------------------------------
189MeshSimplificationSequence *MeshSimplifier::GetSimplificationSequence()
190{
191        return msimpsequence;
192}
193
194//-------------------------------------------------------------------------
195//    Sort mesh bones.
196//-------------------------------------------------------------------------
197void MeshSimplifier::sortBones()
198{
199        VertexBuffer    *simplified_vb;
200        VertexBuffer    *initial_vb;
201
202        std::vector<VertexBoneAssignment>       *simplified_bones;
203        std::vector<VertexBoneAssignment>       *initial_bones;
204
205        // After simplifying, the object always is shared vertex
206        // so, the bones must be placed in the GeoMesh
207        simplified_bones        =       &mGeoMesh->mBones;
208        simplified_vb                   =       mGeoMesh->mVertexBuffer;
209
210        // we assume the original mesh is shared vertex
211        // because before the simplification process
212        // the mesh becomes converted to shared vertex
213        // so, the original bones must be searched in the
214        // Mesh, not in every submesh
215
216        simplified_bones->clear();
217
218        //    Vertex buffers.
219        initial_vb      =       mInitialMesh->mVertexBuffer;
220
221        //    Bones.
222        initial_bones   =       &mInitialMesh->mBones;
223
224        //  For each bone assignment.
225        for (int b = 0; b < initial_bones->size(); b++)
226        {
227                VertexBoneAssignment    assign;
228
229                int n   =       (*initial_bones)[b].vertexIndex;
230
231                //      For each vertex.
232                for (int i      =       0;      i < simplified_vb->mVertexCount;        i++)
233                {
234                        if (simplified_vb->mPosition[i].x == initial_vb->mPosition[n].x &&
235                                        simplified_vb->mPosition[i].y == initial_vb->mPosition[n].y &&
236                                        simplified_vb->mPosition[i].z == initial_vb->mPosition[n].z)
237                        {
238                                assign.vertexIndex      =       i;
239                                assign.boneIndex                =       (*initial_bones)[b].boneIndex;
240                                assign.weight                           =       (*initial_bones)[b].weight;
241
242                                simplified_bones->push_back(assign);
243                        }
244                }
245        }
246}
247
248//////////////////////////////////////////////////////////////////////////
249//                                                                                                                                                                                                                                                                                      //
250//                                                                      GeometryBasedSimplifier class                                                                                           //
251//                                                                                                                                                                                                                                                                                      //
252//////////////////////////////////////////////////////////////////////////
253
254//-------------------------------------------------------------------------
255//      Constructor.
256//-------------------------------------------------------------------------
257GeometryBasedSimplifier::GeometryBasedSimplifier(       const Mesh      *m,
258                                                                                                                                                                                                        TIPOFUNC                upb)
259                                                                                                                                                                                                :MeshSimplifier(m,upb)
260{
261}
262
263//-------------------------------------------------------------------------
264//      Destructor.
265//-------------------------------------------------------------------------
266GeometryBasedSimplifier::~GeometryBasedSimplifier()
267{
268}
269
270//-------------------------------------------------------------------------
271// Starts the simplification process. Receives as a parameter
272// the LOD factor in a range of [0,1]. Implements the Simplifier::Simplify
273// method to perform an image based simplification.
274//-------------------------------------------------------------------------
275int     GeometryBasedSimplifier::Simplify(Real paramlod)
276{
277        SimplificationMethod *m_qslim   =       new SimplificationMethod(mInitialMesh);
278
279        m_qslim->setMeshLeaves(indexMeshLeaves);
280
281        msimpsequence   =       m_qslim->Decimate(paramlod,0,mUPB);
282
283        mGeoMesh        =       m_qslim->GetMesh();
284
285        delete  m_qslim;
286
287        return  NO_GL_ERROR;
288}
289
290//-------------------------------------------------------------------------
291// Starts the simplification process. Receives as a parameter the
292// number of vertices of the resulting mesh.
293// Implements the Simplifier::Simplify method to
294// perform an image based simplification.
295//-------------------------------------------------------------------------
296int     GeometryBasedSimplifier::Simplify(uint32 numvertices)
297{
298        SimplificationMethod *m_qslim   =       new SimplificationMethod(mInitialMesh);
299       
300        m_qslim->setMeshLeaves(indexMeshLeaves);
301       
302        msimpsequence   =       m_qslim->Decimate((float)numvertices,1,mUPB);
303
304        mGeoMesh        =       m_qslim->GetMesh();
305
306        delete m_qslim;
307
308        return  NO_GL_ERROR;
309}
310
311//////////////////////////////////////////////////////////////////////////
312//                                                                                                                                                                                                                                                                                      //
313//                                                              ViewPointDrivenSimplifier class                                                                                         //
314//                                                                                                                                                                                                                                                                                      //
315//////////////////////////////////////////////////////////////////////////
316
317//------------------------------------------------------------------------
318// Class constructor. Will call Simplifier class constructor.
319//------------------------------------------------------------------------
320ViewPointDrivenSimplifier::ViewPointDrivenSimplifier(   const Mesh      *m,
321                                                                                                                                                                                                                        TIPOFUNC                upb)
322                                                                                                                                                                                                                :MeshSimplifier(m,upb)
323{
324        //      Set progress update function
325        VMI::mUPB       =       upb;
326
327        VMI::width  = 256;
328        VMI::height = 256;
329
330        VMI::bEnableOffScreen                   = GL_TRUE;
331        VMI::bBeQuiet                           = GL_FALSE;
332        VMI::bSaveLog                           = GL_FALSE;
333        VMI::bLoadCamerasFromFile               = GL_FALSE;
334        VMI::bRemoveRedundantVertices = GL_TRUE;
335
336        VMI::cameraType = 3; // 20 viewpoints
337        VMI::radius = 1.3;
338        VMI::fov = 60.0;
339
340        printf("w: %d h: %d\n", VMI::width, VMI::height);
341
342        printf( "t: %d c: %d o: %d r: %f\n",
343                        VMI::numDemandedTriangles,
344                        VMI::cameraType,
345                        VMI::bEnableOffScreen,
346                        VMI::radius);
347
348        //      Fill up attributes.
349        fillUpPosNorTC(mInitialMesh);
350
351        VMI::vPositions =       vPositions;
352        VMI::vNormals           =       vNormals;
353        VMI::vTexCoords =       vTexCoords;
354
355        mGeoMesh        =       new Mesh();
356
357        *mGeoMesh       =       *m;
358
359        //      Transform NoSV Mesh to a SV Mesh.
360        //mGeoMesh      =       mGeoMesh->toSharedVertex();
361       
362        //      Join Vertices.
363        mTexConserver   =        new    TextureConserver();
364        mTexConserver->JoinVertices(mGeoMesh);
365
366        //      Loads the vmi mesh structure for a geometry mesh given.
367        VMI::mesh = initMeshStructure(mGeoMesh);
368}
369
370//------------------------------------------------------------------------
371//      Init VMI options.
372//------------------------------------------------------------------------
373int     ViewPointDrivenSimplifier::init(void)
374{
375        int     error;
376
377        // RGB and Alpha.
378        glutInitDisplayMode(GLUT_DEPTH | GLUT_RGBA | GLUT_DOUBLE | GLUT_ALPHA);
379        glutInitWindowSize(VMI::width, VMI::height);
380        glutInitWindowPosition(100, 100);
381
382        VMI::vmiWin     =       glutCreateWindow("VMI");
383
384        glewInit();
385
386        error   =       VMI::init();
387
388        if (VMI::bLoadCamerasFromFile == GL_FALSE)
389                VMI::cameras = VMI::setCameras( VMI::radius,
390                                                                                                                                                VMI::cameraType,
391                                                                                                                                                &VMI::numCameras);
392
393        VMI::histogram  =       VMI::initHistogram(     VMI::mesh->currentNumTriangles,
394                                                                                                                                                                VMI::numCameras);
395
396        VMI::initialIs  =       VMI::initIs(VMI::numCameras);
397
398        return  error;
399}
400
401//-------------------------------------------------------------------------
402/// Class destructor.
403//-------------------------------------------------------------------------
404ViewPointDrivenSimplifier::~ViewPointDrivenSimplifier(void)
405{
406        // Free memory
407        VMI::freeMemory();
408
409        delete  VMI::mSequence;
410        VMI::mSequence  =       NULL;
411}
412
413/// Starts the simplification process. Receives as a parameter the
414///     LOD factor in a range of [0,1]. Implements the
415///     Simplifier::Simplify method to perform an image based simplification.
416int ViewPointDrivenSimplifier::Simplify(Real percent)
417{
418        int error;
419
420        error   =        init();
421
422        VMI::numDemandedTriangles = (int)(VMI::mesh->numTriangles * percent);
423
424        if ((VMI::numDemandedTriangles == 0)
425                        ||
426                        (VMI::numDemandedTriangles >= VMI::mesh->currentNumTriangles))
427        {
428                printf("Illegal number of triangles.\n");
429        }
430
431        if (error == NO_GL_ERROR)
432        {
433                VMI::display();
434
435                //      Cleans firts simplification.
436                VMI::freeMemory();
437
438                VMI::mesh =     initMeshStructure(mInitialMesh);
439
440                VMI::contractInitialMesh(VMI::mesh);
441
442                //      Load a geometry mesh for vmi mesh.
443                loadMesh();
444
445                GetMeshSimpSequence();
446
447                //      Sort bones.
448                bonesReassignament();
449        }
450
451        return  error;
452}
453
454//-------------------------------------------------------------------------
455/// Starts the simplification process. Receives as a parameter
456///     the number of vertices of the resulting mesh.
457/// Implements the Simplifier::Simplify method to perform
458///     an image based simplification.
459//-------------------------------------------------------------------------
460int ViewPointDrivenSimplifier::Simplify(uint32 numVertices)
461{
462        float   percent;
463        int     error;
464
465        error   =        init();
466
467        percent =       (numVertices    *       100.0) / VMI::mesh->numVertices;
468
469        VMI::numDemandedTriangles = (int)(VMI::mesh->numTriangles
470                                                                                                                                                *
471                                                                                                                                                (percent / 100));
472
473        if ((VMI::numDemandedTriangles == 0)
474                        ||
475                        (VMI::numDemandedTriangles >= VMI::mesh->currentNumTriangles))
476        {
477                printf("Illegal number of triangles.\n");
478        }
479
480        if (error == NO_GL_ERROR)
481        {
482                VMI::display();
483
484                //      Cleans firts simplification.
485                VMI::freeMemory();
486
487                VMI::mesh =     initMeshStructure(mInitialMesh);
488
489                VMI::contractInitialMesh(VMI::mesh);
490
491                //      Load a geometry mesh for vmi mesh.
492                loadMesh();
493
494                GetMeshSimpSequence();
495
496                //      Sort bones.
497                bonesReassignament();
498        }
499
500        return  error;
501}
502
503//-------------------------------------------------------------------------
504//      Gets the VMI mesh simplification sequence.
505//-------------------------------------------------------------------------
506void    ViewPointDrivenSimplifier::GetMeshSimpSequence()
507{
508        size_t  j = 0;
509       
510        MeshSimplificationSequence::Step        current_step;
511       
512        msimpsequence   =       new MeshSimplificationSequence();
513
514        //      Copy the mesh simplification sequence.
515        msimpsequence->mSteps                           =       VMI::mSequence->mSteps;
516        msimpsequence->mNewVertices     =       VMI::mSequence->mNewVertices;
517
518        cout    <<      "Steps of simplification: "
519                                <<      msimpsequence->mSteps.size()
520                                <<      " Number of new vertices: "
521                                <<      msimpsequence->mNewVertices.size()
522                                <<      endl;
523}
524
525//-------------------------------------------------------------------------
526//      Initialize the mesh of VMI module.
527//-------------------------------------------------------------------------
528VMI::Mesh *     ViewPointDrivenSimplifier::initMeshStructure(Mesh       *geoMesh)
529{
530        GLuint                          i, j, v1, v2, v3, e;
531        float x, y, z;
532        VMI::Mesh               *vmi_mesh;
533        SubMesh                         *geosubmesh;
534        VertexBuffer    *vertex_buffer;
535        int                                             mesh_index_count;
536
537        //      Reallocate memory for vmi mesh object.
538        vmi_mesh = (VMI::Mesh *)malloc(sizeof(VMI::Mesh));
539
540        if (vmi_mesh == NULL)
541        {
542                fprintf(stderr, "Error allocating memory\n");
543                exit(1);
544        }
545
546        //      Shared vertex buffer.
547        vertex_buffer   =       geoMesh->mVertexBuffer;
548       
549        //      Reallocate memory for vertices of mesh.
550        vmi_mesh->vertices = (VMI::Vertex *)malloc(sizeof(VMI::Vertex)
551                                                                                                                                                                *
552                                                                                                                                                                vertex_buffer->mVertexCount);
553        vmi_mesh->numVertices = 0;
554
555        if (vmi_mesh->vertices == NULL)
556        {
557                fprintf(stderr, "Error allocating memory\n");
558                exit(1);
559        }
560
561        //      Initialize mesh index count.
562        mesh_index_count        =       0;
563       
564        for (   unsigned int submesh    =       0;
565                                submesh < geoMesh->mSubMeshCount;
566                                submesh++)
567        {
568                mesh_index_count        +=      int(geoMesh->mSubMesh[submesh].mIndexCount);
569        }
570       
571        //      Reallocate memory for indices.
572        vmi_mesh->triangles = (VMI::Triangle *)malloc(sizeof(VMI::Triangle)
573                                                                                                                                                                                *
574                                                                                                                                                                                (mesh_index_count / 3));
575        vmi_mesh->numTriangles = 0;
576
577        if (vmi_mesh->triangles == NULL)
578        {
579                fprintf(stderr, "Error allocating memory\n");
580                exit(1);
581        }
582
583        printf("Adding vertices...");
584
585        //      Fill up vertices.
586        for (i = 0; i < vertex_buffer->mVertexCount; i++)
587        {
588                // Vertices start at 0.
589                x = vertex_buffer->mPosition[i].x;
590                y = vertex_buffer->mPosition[i].y;
591                z = vertex_buffer->mPosition[i].z;
592
593                addVertex(vmi_mesh, x, y, z);
594        }
595       
596        printf("Ok\n");
597        vmi_mesh->currentNumVertices = vmi_mesh->numVertices;
598
599        printf("Vertices: %d\n",vmi_mesh->numVertices);
600
601        //      Fill up triangles.
602        printf("Adding triangles...");
603       
604        //      For each submesh.
605        for (   unsigned int submesh    =       0;
606                                submesh <       geoMesh->mSubMeshCount;
607                                submesh++)
608        {
609                //      Gets actual submesh.
610                geosubmesh      =       &geoMesh->mSubMesh[submesh];
611               
612                //      For each three vertices.
613                for (i = 0; i < (geosubmesh->mIndexCount / 3); i++)
614                {
615                        v1 = geosubmesh->mIndex[(3 * i)];
616                        v2 = geosubmesh->mIndex[(3 * i) + 1];
617                        v3 = geosubmesh->mIndex[(3 * i) + 2];
618
619                        // not a degenerated triangle
620                        //if ((v1 != v2) && (v2 != v3) && (v1 != v3)) {
621
622                                addTriangle(vmi_mesh, submesh, v1, v2, v3);
623                        //}
624                }
625        }
626       
627        printf("Ok\n");
628
629        vmi_mesh->currentNumTriangles = vmi_mesh->numTriangles;
630        printf("Number of triangles: %d\n", vmi_mesh->numTriangles);
631        //printf("Number of degenerated triangles: %d\n", pmodel->numtriangles - vmi_mesh->numTriangles);
632       
633        // E = 3 T / 2
634        vmi_mesh->edges = (VMI::Edge *)malloc(sizeof(VMI::Edge)
635                                                                                *
636                                                                                vmi_mesh->numTriangles * 3);
637        vmi_mesh->numEdges = 0;
638
639        if (vmi_mesh->edges == NULL)
640        {
641                fprintf(stderr, "Error allocating memory\n");
642                exit(1);
643        }
644
645        printf("Adding edges...");
646
647        //      For each triangle adds three edges.
648        for (i  =       0; i < vmi_mesh->numTriangles; i++)
649        {
650                v1      =       vmi_mesh->triangles[i].indices[0];
651                v2      =       vmi_mesh->triangles[i].indices[1];
652                v3      =       vmi_mesh->triangles[i].indices[2];
653
654                if ((e = findEdge(vmi_mesh->edges, vmi_mesh->numEdges, v1, v2)) == -1)
655                {
656                        addEdge(vmi_mesh, v1, v2);
657                }
658
659                if ((e = findEdge(vmi_mesh->edges, vmi_mesh->numEdges, v2, v3)) == -1)
660                {
661                        addEdge(vmi_mesh, v2, v3);
662                }
663               
664                if ((e = findEdge(vmi_mesh->edges, vmi_mesh->numEdges, v3, v1)) == -1)
665                {
666                        addEdge(vmi_mesh, v3, v1);
667                }
668        }
669       
670        printf("Ok\n");
671
672        //      Creates vertex multimap.
673        initVertexMultimap(vmi_mesh,mTexConserver->mVertices);
674
675        return vmi_mesh;
676}
677
678//-------------------------------------------------------------------------
679//      Gets the geometry mesh of a  the vmi mesh given.
680//-------------------------------------------------------------------------
681void    ViewPointDrivenSimplifier::loadMesh()
682{
683        int                                             num_indices;
684        SubMesh                         *geosubmesh;
685        VertexBuffer    *vertex_buffer;
686       
687        //      Gets old vertex buffer.
688        vertex_buffer   =       mGeoMesh->mVertexBuffer;
689       
690        //      Initialize auxiliar vertex buffer.
691        mVB     =       new     VertexBuffer();
692       
693        mVB->mPosition          =       new     Vector3[VMI::mesh->currentNumVertices];
694        mVB->mNormal                    =       new     Vector3[VMI::mesh->currentNumVertices];
695        mVB->mTexCoords         =       new     Vector2[VMI::mesh->currentNumVertices];
696
697        mVB->mVertexInfo        =       vertex_buffer->mVertexInfo;
698
699        //      For each submesh.
700        for (size_t     submesh =       0; submesh < mGeoMesh->mSubMeshCount; submesh++)
701        {
702                geosubmesh      =       &mGeoMesh->mSubMesh[submesh];
703
704                delete  []geosubmesh->mIndex;
705
706                //      Initialize submesh index count;
707                num_indices     =       0;
708
709                //      For each triangle.
710                for (size_t     i = 0; i < VMI::mesh->numTriangles; i++)
711                {
712                        //      If is enable and of the current submesh.
713                        if ((VMI::mesh->triangles[i].enable)
714                                        &&
715                                        (VMI::mesh->triangles[i].submesh == submesh))
716                        {
717                                //      Increments submesh index count.
718                                num_indices     +=      3;
719                        }
720                }
721
722                geosubmesh->mIndexCount =       num_indices;
723
724                geosubmesh->mIndex      =       new Geometry::Index[geosubmesh->mIndexCount];
725
726                //      Initialize number of indices.
727                num_indices     =       0;
728
729                //      Fill up indices.
730                for (size_t     i = 0; i < VMI::mesh->numTriangles; i++)
731                {
732                        if ((VMI::mesh->triangles[i].enable)
733                                        &&
734                                        (VMI::mesh->triangles[i].submesh == submesh))
735                        {
736                                geosubmesh->mIndex[num_indices++]       =
737                                                                                                                                        VMI::mesh->triangles[i].indices[0];
738
739                                geosubmesh->mIndex[num_indices++]       =
740                                                                                                                                        VMI::mesh->triangles[i].indices[1];
741
742                                geosubmesh->mIndex[num_indices++]       =
743                                                                                                                                        VMI::mesh->triangles[i].indices[2];
744                        }
745                }
746       
747                //      For each index.
748                for (size_t     i = 0; i < geosubmesh->mIndexCount; i++)
749                {
750                        findVertex(submesh,i);
751                }
752
753                geosubmesh->mVertexBuffer       =       mVB;
754        }
755
756        delete  vertex_buffer;
757       
758        mGeoMesh->mVertexBuffer =       mVB;
759}
760
761//-------------------------------------------------------------------------
762//      Find vertex in auxiliar vertex buffer.
763//-------------------------------------------------------------------------
764void    ViewPointDrivenSimplifier::findVertex(size_t    submesh, size_t elem)
765{
766        bool                                                                            found;
767        int                                                                                     index;
768        unsigned int                                            i;
769        int                                                                                     new_elem;
770        VertexBuffer                                            *vertex_buffer;
771        map<int,int>::iterator  it;
772
773        found   =       false;
774
775        //      Shared vertex buffer.
776        vertex_buffer   =       mInitialMesh->mVertexBuffer;
777
778        index   =       mGeoMesh->mSubMesh[submesh].mIndex[elem];
779
780        i       =       0;
781
782        if ((it =       mIndexMap.find(index)) != mIndexMap.end())
783        {
784                mGeoMesh->mSubMesh[submesh].mIndex[elem]        =       (*it).second;
785        }
786        else
787        {
788                mIndexMap[index]        =       int(mVB->mVertexCount);
789
790                //      Last element.
791                new_elem        =       int(mVB->mVertexCount);
792
793                mVB->mPosition[new_elem]        =       VMI::vPositions[index];
794                mVB->mNormal[new_elem]          =       VMI::vNormals[index];
795                mVB->mTexCoords[new_elem]       =       VMI::vTexCoords[index];
796
797                //      Update index.
798                mGeoMesh->mSubMesh[submesh].mIndex[elem]        =        new_elem;
799
800                //      Increments vertex count.
801                mVB->mVertexCount++;
802        }
803}
804
805//-------------------------------------------------------------------------
806//      Reassigns bones.
807//-------------------------------------------------------------------------
808void ViewPointDrivenSimplifier::bonesReassignament()
809{
810        size_t                                                                  vertex_id;
811        size_t                                                                  bones_count;
812        bool                                                                            vertex_found;
813        map<int,int>::iterator  im;
814        VertexBoneAssignment            bone;
815
816        vector<VertexBoneAssignment>::iterator  ib;
817
818        //      Copy new vertices.
819        for (unsigned   int     i       =       0;      i < msimpsequence->mNewVertices.size(); i++)
820        {
821                vertex_id       =       msimpsequence->mNewVertices[i].id;
822
823                //      Initialize number of bones.
824                bones_count     =       mInitialMesh->mBones.size();
825
826                // check if my twin-vertex-bone has a bone assignment
827                // we check only the GeoMesh bones because the lodstrips
828                // only works for sharedvertex bones.
829                for (int  j = 0; j < bones_count; j++)
830                {
831                        ib      =       mInitialMesh->mBones.begin() + j;
832
833                        if (ib->vertexIndex == msimpsequence->mNewVertices[i].bonefrom)
834                        {
835                                bone.vertexIndex        = vertex_id;
836                                bone.boneIndex          = ib->boneIndex;
837                                bone.weight                             = ib->weight;
838
839                                mInitialMesh->mBones.push_back(bone);
840                                bones_count++;
841                        }
842                }
843        }
844
845        //      Clears bones.
846        mGeoMesh->mBones.clear();
847
848        //      For each bone assignment.
849        for (unsigned int i = 0; i < mInitialMesh->mBones.size(); i++)
850        {
851                bone.vertexIndex        =       mInitialMesh->mBones[i].vertexIndex;
852                bone.boneIndex          =       mInitialMesh->mBones[i].boneIndex;
853                bone.weight                             =       mInitialMesh->mBones[i].weight;
854
855                vertex_found    =       false;
856
857                //      If the vertex is found in the simplification model.
858                if ((im = mIndexMap.find(bone.vertexIndex))
859                                !=
860                                mIndexMap.end())
861                {
862                        bone.vertexIndex        =       (*im).second;
863
864                        mGeoMesh->mBones.push_back(bone);
865
866                        vertex_found    =       true;
867                }
868        }
869}
870
871//-------------------------------------------------------------------------
872//      Fill up position, normal and texture coordinates.
873//-------------------------------------------------------------------------
874void    ViewPointDrivenSimplifier::fillUpPosNorTC(Mesh  *geoMesh)
875{
876        VertexBuffer    *vertex_buffer;
877        Vector3                         v3;
878        Vector2                         v2;
879
880        vertex_buffer   =       geoMesh->mVertexBuffer;
881
882        for (size_t     i = 0; i < vertex_buffer->mVertexCount; i++)
883        {
884                v3      =       vertex_buffer->mPosition[i];
885
886                vPositions.push_back(v3);
887
888                v3      =       vertex_buffer->mNormal[i];
889
890                vNormals.push_back(v3);
891
892                v2      =       vertex_buffer->mTexCoords[i];
893
894                vTexCoords.push_back(v2);
895        }
896}
897
898//-------------------------------------------------------------------------
899//      EdgesMultimap class
900//-------------------------------------------------------------------------
901
902//-------------------------------------------------------------------------
903//      Constructor.
904//-------------------------------------------------------------------------
905EdgesMultimap::EdgesMultimap()
906{
907}
908
909//-------------------------------------------------------------------------
910//      Destructor.
911//-------------------------------------------------------------------------
912EdgesMultimap::~EdgesMultimap()
913{
914        edges.clear();
915}
916
917//-------------------------------------------------------------------------
918//      Insert and edge.
919//-------------------------------------------------------------------------
920void    EdgesMultimap::insert(int v1,int v2)
921{
922        edges.insert(pair<int,int>(v1,v2));
923        edges.insert(pair<int,int>(v2,v1));
924}
925
926//-------------------------------------------------------------------------
927//      Remove edges with v1 and v2.
928//-------------------------------------------------------------------------
929void    EdgesMultimap::remove(int v1,int v2)
930{
931        multimap<int,int>::iterator     lb;
932        multimap<int,int>::iterator     ub;
933
934        if (edges.find(v1) != edges.end())
935        {
936                lb      =       edges.lower_bound(v1);
937                ub      =       edges.upper_bound(v1);
938
939                while (lb != ub)
940                {
941                        if ((*lb).second == v2)
942                        {
943                                //      Remove edge.
944                                edges.erase(lb);
945
946                                lb      =       ub;
947                        }
948                        else
949                        {
950                                lb++;
951                        }
952                }
953        }
954
955        if (edges.find(v2) != edges.end())
956        {
957                lb      =       edges.lower_bound(v2);
958                ub      =       edges.upper_bound(v2);
959
960                while (lb != ub)
961                {
962                        if ((*lb).second == v1)
963                        {
964                                //      Remove edge.
965                                edges.erase(lb);
966
967                                lb      =       ub;
968                        }
969                        else
970                        {
971                                lb++;
972                        }
973                }
974        }
975
976}
977
978//-------------------------------------------------------------------------
979//      Checks if the edge (v1,v2) exists.
980//-------------------------------------------------------------------------
981bool    EdgesMultimap::exists(int v1,int v2)
982{
983        bool                                                                                            found;
984        multimap<int,int>::iterator     lb;
985        multimap<int,int>::iterator     ub;
986
987        found   =       false;
988
989        //      Find range.
990        lb      =       edges.lower_bound(v1);
991        ub      =       edges.upper_bound(v1);
992
993        //      Search for all v1 edges.
994        while (lb != ub)
995        {
996                //      If edge is found.
997                if ((*lb).second = v2)
998                {
999                        found   =       true;
1000                        lb              =       ub;
1001                }
1002                else
1003                {
1004                        //      Next iteration.
1005                        lb++;
1006                }
1007        }
1008
1009        return  found;
1010}
1011
1012//-------------------------------------------------------------------------
1013//      Change vertex v1 to v2 in the map.
1014//-------------------------------------------------------------------------
1015void    EdgesMultimap::contract(int v1,int v2)
1016{
1017        multimap<int,int>::iterator     it;
1018        int     v_aux;
1019
1020        //      Remove contracted edge.
1021        remove(v1,v2);
1022
1023        //      Modify all edges where appears v1 to v2.
1024        while ((it =    edges.find(v1)) != edges.end())
1025        {
1026                v_aux   =       (*it).second;
1027
1028                //      Remove current edge.
1029                remove(v1,v_aux);
1030
1031                //      Modify edge.
1032                insert(v2,v_aux);
1033        }
1034}
1035
1036//-------------------------------------------------------------------------
1037//      TextureConserver class
1038//-------------------------------------------------------------------------
1039TextureConserver::TextureConserver()
1040{
1041        mEdges          =       new     EdgesMultimap();
1042        mGeoMesh        =       new Mesh();
1043}
1044
1045TextureConserver::~TextureConserver()
1046{
1047        delete  mGeoMesh;
1048        delete  mEdges;
1049}
1050
1051//-------------------------------------------------------------------------
1052//      Join twin vertices into a unique vertex.
1053//-------------------------------------------------------------------------
1054void    TextureConserver::JoinVertices(Mesh *mesh)
1055{
1056        map<_coord_, int>                                                       uniquevertices;
1057        map<int, int>                                                                   newindices;
1058        multimap<int, int>::iterator    it;
1059        map<int, int>::iterator                         it_map;
1060        VertexBuffer                                                                    *vertex_buffer;
1061        VertexBuffer                                                                    *mGMVB;
1062        unsigned        int                                                                     vertex_count;
1063        unsigned        int                                                                     i;
1064        unsigned        int                                                                     aux_i;
1065        unsigned        int                                                                     submesh;
1066        SubMesh                                                                                         *geosubmesh;
1067        _coord_                                                                                         vertex_aux;
1068
1069        //      Copy actual mesh.
1070        *mGeoMesh               =       *mesh;
1071
1072        //      Gets the shared vertex buffer.
1073        vertex_buffer   =       mGeoMesh->mVertexBuffer;
1074
1075        //      Initialize unique vertices count.
1076        vertex_count    =       0;
1077
1078        //      Fill up vertices.
1079        for (i  =       0; i < vertex_buffer->mVertexCount; i++)
1080        {
1081                vertex_aux.x    = vertex_buffer->mPosition[i].x;
1082                vertex_aux.y    = vertex_buffer->mPosition[i].y;
1083                vertex_aux.z    = vertex_buffer->mPosition[i].z;
1084
1085                //      New index.
1086                if (uniquevertices.find(vertex_aux) == uniquevertices.end())
1087                {
1088                        uniquevertices[vertex_aux]      = vertex_count;
1089                        newindices[i]                                                           = vertex_count;
1090
1091                        mVertices.insert(pair<int,int>(vertex_count,i));
1092                       
1093                        //      Increments unique vertices count.
1094                        vertex_count++;
1095                }
1096                //      The map of unique vertices already contains this vertex.
1097                else
1098                {
1099                        int newindex    =       uniquevertices[vertex_aux];
1100                        newindices[i]   =       newindex;
1101
1102                        mVertices.insert(pair<int,int>(newindex,i));
1103                }
1104        }
1105
1106        //      Delete vertices.
1107        delete  mesh->mVertexBuffer;
1108
1109        mesh->mVertexBuffer     =       new VertexBuffer();
1110
1111        mesh->mVertexBuffer->mPosition          = new Vector3[vertex_count];
1112        mesh->mVertexBuffer->mNormal                    = new Vector3[vertex_count];
1113        mesh->mVertexBuffer->mTexCoords         = new Vector2[vertex_count];
1114
1115        mesh->mVertexBuffer->mVertexInfo        = vertex_buffer->mVertexInfo;
1116        mesh->mVertexBuffer->mVertexCount       = vertex_count;
1117
1118        mGMVB   =       mesh->mVertexBuffer;
1119
1120        //      Fill up unique vertices.
1121        for (i  =        0; i < vertex_count; i++)
1122        {
1123                //      Find first ocurrence of unique vertex.
1124                it      =       mVertices.find(i);
1125
1126                aux_i   =       (*it).second;
1127
1128                mGMVB->mPosition[i].x   =       vertex_buffer->mPosition[aux_i].x;
1129                mGMVB->mPosition[i].y   =       vertex_buffer->mPosition[aux_i].y;
1130                mGMVB->mPosition[i].z   =       vertex_buffer->mPosition[aux_i].z;
1131
1132                mGMVB->mNormal[i].x     =       vertex_buffer->mNormal[aux_i].x;
1133                mGMVB->mNormal[i].y     =       vertex_buffer->mNormal[aux_i].y;
1134                mGMVB->mNormal[i].z     =       vertex_buffer->mNormal[aux_i].z;
1135
1136                mGMVB->mTexCoords[i].x  =       vertex_buffer->mTexCoords[aux_i].x;
1137                mGMVB->mTexCoords[i].y  =       vertex_buffer->mTexCoords[aux_i].y;
1138        }
1139
1140        //      Fill up indices to unique vertices.
1141        //      For each submesh.
1142        for (submesh    =       0; submesh < mesh->mSubMeshCount; submesh++)
1143        {
1144                geosubmesh      =       &mesh->mSubMesh[submesh];
1145
1146                //      Change indices.
1147                for (i  =       0; i < geosubmesh->mIndexCount; i++)
1148                {
1149                        //      Unique index asociated to the given one.
1150                        it_map  =       newindices.find(geosubmesh->mIndex[i]);
1151
1152                        geosubmesh->mIndex[i]   =       (*it_map).second;
1153                }
1154        }
1155}
1156
1157//-------------------------------------------------------------------------
1158//      Return  mesh that may have repeated vertices for texture aparence.
1159//-------------------------------------------------------------------------
1160Mesh    *TextureConserver::GetMesh()
1161{
1162        return  mGeoMesh;
1163}
1164
Note: See TracBrowser for help on using the repository browser.