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

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