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

Revision 2194, 28.0 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        mGeoMesh        =       new Mesh();
227
228        *mGeoMesh       =       *m;
229
230        //      Transform NoSV Mesh to a SV Mesh.
231        //mGeoMesh      =       mGeoMesh->toSharedVertex();
232       
233        //      Join Vertices.
234        mTexConserver   =        new    TextureConserver();
235        mTexConserver->JoinVertices(mGeoMesh);
236
237        //      Loads the vmi mesh structure for a geometry mesh given.
238        VMI::mesh = initMeshStructure(mGeoMesh);
239
240        // RGB and Alpha.
241        glutInitDisplayMode(GLUT_DEPTH | GLUT_RGBA | GLUT_DOUBLE | GLUT_ALPHA);
242        glutInitWindowSize(VMI::width, VMI::height);
243        glutInitWindowPosition(100, 100);
244
245        VMI::vmiWin     =       glutCreateWindow("VMI");
246
247        glewInit();
248
249        VMI::init();
250
251        if (VMI::bLoadCamerasFromFile == GL_FALSE)
252                VMI::cameras = VMI::setCameras( VMI::radius,
253                                                                                                                                                VMI::cameraType,
254                                                                                                                                                &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        }
439       
440        printf("Ok\n");
441        vmi_mesh->numVertices = int(vertex_buffer->mVertexCount);
442        vmi_mesh->currentNumVertices = int(vertex_buffer->mVertexCount);
443
444        printf("Vertices: %d\n",vmi_mesh->numVertices);
445
446        //      Fill up triangles.
447        printf("Adding triangles...");
448       
449        //      Initialize index of triangle.
450        index   =       0;
451       
452        //      For each submesh.
453        for (   unsigned int submesh    =       0;
454                                submesh <       geoMesh->mSubMeshCount;
455                                submesh++)
456        {
457                //      Gets actual submesh.
458                geosubmesh      =       &geoMesh->mSubMesh[submesh];
459               
460                //      For each three vertices.
461                for (i = 0; i < (geosubmesh->mIndexCount / 3); i++)
462                {
463                        vmi_mesh->triangles[index].id                           = index;
464                        vmi_mesh->triangles[index].submesh              = submesh;
465                        vmi_mesh->triangles[index].indices[0] = geosubmesh->mIndex[(3 * i)];
466                        vmi_mesh->triangles[index].indices[1] = geosubmesh->mIndex[(3 * i) + 1];
467                        vmi_mesh->triangles[index].indices[2] = geosubmesh->mIndex[(3 * i) + 2];
468
469                        vmi_mesh->triangles[index].area = computeTriangleArea(
470                                                                                                                                                                                vmi_mesh->vertices,
471                                                                                                                                                                                &vmi_mesh->triangles[index]);
472
473                        computeTriangleNormal(vmi_mesh->vertices,
474                                                                                                                &vmi_mesh->triangles[index]);
475
476                        vmi_mesh->triangles[index].saliency = 0.0;
477
478                        vmi_mesh->triangles[index].enable = GL_TRUE;
479
480                        for (j = 0; j < 3; j++)
481                        {
482                                // Adding triangle index adjacent to 3 vertices.
483                                v1 = vmi_mesh->triangles[index].indices[j];
484
485                                // Reallocate memory for the new adjacent triangle.
486                                vmi_mesh->vertices[v1].triangles =
487                                                                                        (int *)realloc(vmi_mesh->vertices[v1].triangles,
488                                                                                        (vmi_mesh->vertices[v1].numTriangles + 1)
489                                                                                        *
490                                                                                        sizeof(int));
491
492                                VMI::addItem(   (int *)vmi_mesh->vertices[v1].triangles,
493                                                                                        (int *)&vmi_mesh->vertices[v1].numTriangles,
494                                                                                        index);
495                        }
496
497                        //      Increments triangle count.
498                        index++;
499                }
500        }
501       
502        printf("Ok\n");
503
504        vmi_mesh->numTriangles                          = mesh_index_count / 3;
505        vmi_mesh->currentNumTriangles = mesh_index_count / 3;
506
507        printf("Num Triangles: %d\n",vmi_mesh->numTriangles);
508       
509        // E = 3 T / 2
510        vmi_mesh->edges = (VMI::Edge *)malloc(sizeof(VMI::Edge)
511                                                                                *
512                                                                                vmi_mesh->numTriangles * 3);
513
514        if (vmi_mesh->edges == NULL)
515        {
516                fprintf(stderr, "Error allocating memory\n");
517                exit(1);
518        }
519
520        printf("Adding edges...");
521        n = 0;
522
523        //      For each triangle adds three edges.
524        for (i  =       0; i < vmi_mesh->numTriangles; i++)
525        {
526                t               =       0;
527                v1      =       vmi_mesh->triangles[i].indices[0];
528                v2      =       vmi_mesh->triangles[i].indices[1];
529                v3      =       vmi_mesh->triangles[i].indices[2];
530
531                if ((e = findEdge(vmi_mesh->edges, n, v1, v2)) == -1)
532                {
533                        vmi_mesh->edges[n].u                                            =       v1;
534                        vmi_mesh->edges[n].v                                            =       v2;
535                        vmi_mesh->edges[n].enable                       =       GL_TRUE;
536
537                        n++;
538                }
539
540                if ((e = findEdge(vmi_mesh->edges, n, v2, v3)) == -1)
541                {
542                        vmi_mesh->edges[n].u                                            = v2;
543                        vmi_mesh->edges[n].v                                            = v3;
544                        vmi_mesh->edges[n].enable                       = GL_TRUE;
545
546                        n++;
547                }
548               
549                if ((e = findEdge(vmi_mesh->edges, n, v3, v1)) == -1)
550                {
551                        vmi_mesh->edges[n].u                                            = v3;
552                        vmi_mesh->edges[n].v                                            = v1;
553                        vmi_mesh->edges[n].enable                       = GL_TRUE;
554
555                        n++;
556                }
557        }
558       
559        printf("Ok\n");
560        vmi_mesh->numEdges = n;
561
562        for (i  =       0; i < vmi_mesh->numEdges; i++)
563        {
564                v1 = vmi_mesh->edges[i].u;
565                v2 = vmi_mesh->edges[i].v;
566
567                vmi_mesh->vertices[v1].edges    =
568                                                        (int *)realloc(vmi_mesh->vertices[v1].edges,
569                                                        (vmi_mesh->vertices[v1].numEdges + 1) * sizeof(int));
570
571                // Adding edge i adjacent to vertex v1
572                VMI::addItem(   vmi_mesh->vertices[v1].edges,
573                                                                        &vmi_mesh->vertices[v1].numEdges,
574                                                                        i);
575
576                vmi_mesh->vertices[v2].edges =
577                                                                (int *)realloc(vmi_mesh->vertices[v2].edges,
578                                                                (vmi_mesh->vertices[v2].numEdges + 1) * sizeof(int));
579
580                // Adding edge i adjacent to vertex v2
581                VMI::addItem(   vmi_mesh->vertices[v2].edges,
582                                                                        &vmi_mesh->vertices[v2].numEdges,
583                                                                        i);
584        }
585
586        //      Creates vertex multimap.
587        initVertexMultimap(vmi_mesh,mTexConserver->mVertices);
588
589        return vmi_mesh;
590}
591
592//-------------------------------------------------------------------------
593//      Gets the geometry mesh of a  the vmi mesh given.
594//-------------------------------------------------------------------------
595void    ViewPointDrivenSimplifier::loadMesh()
596{
597        int                                             num_indices;
598        SubMesh                         *geosubmesh;
599        VertexBuffer    *vertex_buffer;
600       
601        //      Gets old vertex buffer.
602        vertex_buffer   =       mGeoMesh->mVertexBuffer;
603       
604        //      Initialize auxiliar vertex buffer.
605        mVB     =       new     VertexBuffer();
606       
607        mVB->mPosition          =       new     Vector3[VMI::mesh->currentNumVertices];
608        mVB->mNormal                    =       new     Vector3[VMI::mesh->currentNumVertices];
609        mVB->mTexCoords         =       new     Vector2[VMI::mesh->currentNumVertices];
610
611        mVB->mVertexInfo        =       vertex_buffer->mVertexInfo;
612
613        //      For each submesh.
614        for (size_t     submesh =       0; submesh < mGeoMesh->mSubMeshCount; submesh++)
615        {
616                geosubmesh      =       &mGeoMesh->mSubMesh[submesh];
617
618                delete  []geosubmesh->mIndex;
619
620                //      Initialize submesh index count;
621                num_indices     =       0;
622
623                //      For each triangle.
624                for (size_t     i = 0; i < VMI::mesh->numTriangles; i++)
625                {
626                        //      If is enable and of the current submesh.
627                        if ((VMI::mesh->triangles[i].enable)
628                                        &&
629                                        (VMI::mesh->triangles[i].submesh == submesh))
630                        {
631                                //      Increments submesh index count.
632                                num_indices     +=      3;
633                        }
634                }
635
636                geosubmesh->mIndexCount =       num_indices;
637
638                geosubmesh->mIndex      =       new Geometry::Index[geosubmesh->mIndexCount];
639
640                //      Initialize number of indices.
641                num_indices     =       0;
642
643                //      Fill up indices.
644                for (size_t     i = 0; i < VMI::mesh->numTriangles; i++)
645                {
646                        if ((VMI::mesh->triangles[i].enable)
647                                        &&
648                                        (VMI::mesh->triangles[i].submesh == submesh))
649                        {
650                                geosubmesh->mIndex[num_indices++]       =
651                                                                                                                                        VMI::mesh->triangles[i].indices[0];
652
653                                geosubmesh->mIndex[num_indices++]       =
654                                                                                                                                        VMI::mesh->triangles[i].indices[1];
655
656                                geosubmesh->mIndex[num_indices++]       =
657                                                                                                                                        VMI::mesh->triangles[i].indices[2];
658                        }
659                }
660       
661                //      For each index.
662                for (size_t     i = 0; i < geosubmesh->mIndexCount; i++)
663                {
664                        findVertex(submesh,i);
665                }
666
667                geosubmesh->mVertexBuffer       =       mVB;
668        }
669
670        delete  vertex_buffer;
671       
672        mGeoMesh->mVertexBuffer =       mVB;
673}
674
675//-------------------------------------------------------------------------
676//      Find vertex in auxiliar vertex buffer.
677//-------------------------------------------------------------------------
678void    ViewPointDrivenSimplifier::findVertex(size_t    submesh, size_t elem)
679{
680        bool                                                                            found;
681        int                                                                                     index;
682        unsigned int                                            i;
683        int                                                                                     new_elem;
684        VertexBuffer                                            *vertex_buffer;
685        map<int,int>::iterator  it;
686
687        found   =       false;
688
689        //      Shared vertex buffer.
690        vertex_buffer   =       mInitialMesh->mVertexBuffer;
691
692        index   =       mGeoMesh->mSubMesh[submesh].mIndex[elem];
693
694        i       =       0;
695
696        if ((it =       mIndexMap.find(index)) != mIndexMap.end())
697        {
698                mGeoMesh->mSubMesh[submesh].mIndex[elem]        =       (*it).second;
699        }
700        else
701        {
702                mIndexMap[index]        =       int(mVB->mVertexCount);
703
704                //      Last element.
705                new_elem        =       int(mVB->mVertexCount);
706
707                mVB->mPosition[new_elem]        =       VMI::vPositions[index];
708                mVB->mNormal[new_elem]          =       VMI::vNormals[index];
709                mVB->mTexCoords[new_elem]       =       VMI::vTexCoords[index];
710
711                //      Update index.
712                mGeoMesh->mSubMesh[submesh].mIndex[elem]        =        new_elem;
713
714                //      Increments vertex count.
715                mVB->mVertexCount++;
716        }
717}
718
719//-------------------------------------------------------------------------
720//      Reassigns bones.
721//-------------------------------------------------------------------------
722void ViewPointDrivenSimplifier::bonesReassignament()
723{
724        size_t                                                                  vertex_id;
725        size_t                                                                  bones_count;
726        bool                                                                            vertex_found;
727        map<int,int>::iterator  im;
728        VertexBoneAssignment            bone;
729
730        vector<VertexBoneAssignment>::iterator  ib;
731
732        //      Copy new vertices.
733        for (unsigned   int     i       =       0;      i < msimpsequence->mNewVertices.size(); i++)
734        {
735                vertex_id       =       msimpsequence->mNewVertices[i].id;
736
737                //      Initialize number of bones.
738                bones_count     =       mInitialMesh->mBones.size();
739
740                // check if my twin-vertex-bone has a bone assignment
741                // we check only the GeoMesh bones because the lodstrips
742                // only works for sharedvertex bones.
743                for (int  j = 0; j < bones_count; j++)
744                {
745                        ib      =       mInitialMesh->mBones.begin() + j;
746
747                        if (ib->vertexIndex == msimpsequence->mNewVertices[i].bonefrom)
748                        {
749                                bone.vertexIndex        = vertex_id;
750                                bone.boneIndex          = ib->boneIndex;
751                                bone.weight                             = ib->weight;
752
753                                mInitialMesh->mBones.push_back(bone);
754                                bones_count++;
755                        }
756                }
757        }
758
759        //      Clears bones.
760        mGeoMesh->mBones.clear();
761
762        //      For each bone assignment.
763        for (unsigned int i = 0; i < mInitialMesh->mBones.size(); i++)
764        {
765                bone.vertexIndex        =       mInitialMesh->mBones[i].vertexIndex;
766                bone.boneIndex          =       mInitialMesh->mBones[i].boneIndex;
767                bone.weight                             =       mInitialMesh->mBones[i].weight;
768
769                vertex_found    =       false;
770
771                //      If the vertex is found in the simplification model.
772                if ((im = mIndexMap.find(bone.vertexIndex))
773                                !=
774                                mIndexMap.end())
775                {
776                        bone.vertexIndex        =       (*im).second;
777
778                        mGeoMesh->mBones.push_back(bone);
779                        vertex_found    =       true;
780                }
781        }
782}
783
784//-------------------------------------------------------------------------
785//      Fill up position, normal and texture coordinates.
786//-------------------------------------------------------------------------
787void    ViewPointDrivenSimplifier::fillUpPosNorTC(Mesh  *geoMesh)
788{
789        VertexBuffer    *vertex_buffer;
790        Vector3                         v3;
791        Vector2                         v2;
792
793        vertex_buffer   =       geoMesh->mVertexBuffer;
794
795        for (size_t     i = 0; i < vertex_buffer->mVertexCount; i++)
796        {
797                v3      =       vertex_buffer->mPosition[i];
798
799                vPositions.push_back(v3);
800
801                v3      =       vertex_buffer->mNormal[i];
802
803                vNormals.push_back(v3);
804
805                v2      =       vertex_buffer->mTexCoords[i];
806
807                vTexCoords.push_back(v2);
808        }
809}
810
811//-------------------------------------------------------------------------
812//      EdgesMultimap class
813//-------------------------------------------------------------------------
814
815//-------------------------------------------------------------------------
816//      Constructor.
817//-------------------------------------------------------------------------
818EdgesMultimap::EdgesMultimap()
819{
820}
821
822//-------------------------------------------------------------------------
823//      Destructor.
824//-------------------------------------------------------------------------
825EdgesMultimap::~EdgesMultimap()
826{
827        edges.clear();
828}
829
830//-------------------------------------------------------------------------
831//      Insert and edge.
832//-------------------------------------------------------------------------
833void    EdgesMultimap::insert(int v1,int v2)
834{
835        edges.insert(pair<int,int>(v1,v2));
836        edges.insert(pair<int,int>(v2,v1));
837}
838
839//-------------------------------------------------------------------------
840//      Remove edges with v1 and v2.
841//-------------------------------------------------------------------------
842void    EdgesMultimap::remove(int v1,int v2)
843{
844        multimap<int,int>::iterator     lb;
845        multimap<int,int>::iterator     ub;
846
847        if (edges.find(v1) != edges.end())
848        {
849                lb      =       edges.lower_bound(v1);
850                ub      =       edges.upper_bound(v1);
851
852                while (lb != ub)
853                {
854                        if ((*lb).second == v2)
855                        {
856                                //      Remove edge.
857                                edges.erase(lb);
858
859                                lb      =       ub;
860                        }
861                        else
862                        {
863                                lb++;
864                        }
865                }
866        }
867
868        if (edges.find(v2) != edges.end())
869        {
870                lb      =       edges.lower_bound(v2);
871                ub      =       edges.upper_bound(v2);
872
873                while (lb != ub)
874                {
875                        if ((*lb).second == v1)
876                        {
877                                //      Remove edge.
878                                edges.erase(lb);
879
880                                lb      =       ub;
881                        }
882                        else
883                        {
884                                lb++;
885                        }
886                }
887        }
888
889}
890
891//-------------------------------------------------------------------------
892//      Checks if the edge (v1,v2) exists.
893//-------------------------------------------------------------------------
894bool    EdgesMultimap::exists(int v1,int v2)
895{
896        bool                                                                                            found;
897        multimap<int,int>::iterator     lb;
898        multimap<int,int>::iterator     ub;
899
900        found   =       false;
901
902        //      Find range.
903        lb      =       edges.lower_bound(v1);
904        ub      =       edges.upper_bound(v1);
905
906        //      Search for all v1 edges.
907        while (lb != ub)
908        {
909                //      If edge is found.
910                if ((*lb).second = v2)
911                {
912                        found   =       true;
913                        lb              =       ub;
914                }
915                else
916                {
917                        //      Next iteration.
918                        lb++;
919                }
920        }
921
922        return  found;
923}
924
925//-------------------------------------------------------------------------
926//      Change vertex v1 to v2 in the map.
927//-------------------------------------------------------------------------
928void    EdgesMultimap::contract(int v1,int v2)
929{
930        multimap<int,int>::iterator     it;
931        int     v_aux;
932
933        //      Remove contracted edge.
934        remove(v1,v2);
935
936        //      Modify all edges where appears v1 to v2.
937        while ((it =    edges.find(v1)) != edges.end())
938        {
939                v_aux   =       (*it).second;
940
941                //      Remove current edge.
942                remove(v1,v_aux);
943
944                //      Modify edge.
945                insert(v2,v_aux);
946        }
947}
948
949//-------------------------------------------------------------------------
950//      TextureConserver class
951//-------------------------------------------------------------------------
952TextureConserver::TextureConserver()
953{
954        mEdges          =       new     EdgesMultimap();
955        mGeoMesh        =       new Mesh();
956}
957
958TextureConserver::~TextureConserver()
959{
960        delete  mGeoMesh;
961        delete  mEdges;
962}
963
964//-------------------------------------------------------------------------
965//      Join twin vertices into a unique vertex.
966//-------------------------------------------------------------------------
967void    TextureConserver::JoinVertices(Mesh *mesh)
968{
969        map<_coord_, int>                                                       uniquevertices;
970        map<int, int>                                                                   newindices;
971        multimap<int, int>::iterator    it;
972        map<int, int>::iterator                         it_map;
973        VertexBuffer                                                                    *vertex_buffer;
974        VertexBuffer                                                                    *mGMVB;
975        unsigned        int                                                                     vertex_count;
976        unsigned        int                                                                     i;
977        unsigned        int                                                                     aux_i;
978        unsigned        int                                                                     submesh;
979        SubMesh                                                                                         *geosubmesh;
980        _coord_                                                                                         vertex_aux;
981
982        //      Copy actual mesh.
983        *mGeoMesh               =       *mesh;
984
985        //      Gets the shared vertex buffer.
986        vertex_buffer   =       mGeoMesh->mVertexBuffer;
987
988        //      Initialize unique vertices count.
989        vertex_count    =       0;
990
991        //      Fill up vertices.
992        for (i  =       0; i < vertex_buffer->mVertexCount; i++)
993        {
994                vertex_aux.x    = vertex_buffer->mPosition[i].x;
995                vertex_aux.y    = vertex_buffer->mPosition[i].y;
996                vertex_aux.z    = vertex_buffer->mPosition[i].z;
997
998                //      New index.
999                if (uniquevertices.find(vertex_aux) == uniquevertices.end())
1000                {
1001                        uniquevertices[vertex_aux]      = vertex_count;
1002                        newindices[i]                                                           = vertex_count;
1003
1004                        mVertices.insert(pair<int,int>(vertex_count,i));
1005                       
1006                        //      Increments unique vertices count.
1007                        vertex_count++;
1008                }
1009                //      The map of unique vertices already contains this vertex.
1010                else
1011                {
1012                        int newindex    =       uniquevertices[vertex_aux];
1013                        newindices[i]   =       newindex;
1014
1015                        mVertices.insert(pair<int,int>(newindex,i));
1016                }
1017        }
1018
1019        //      Delete vertices.
1020        delete  mesh->mVertexBuffer;
1021
1022        mesh->mVertexBuffer     =       new VertexBuffer();
1023
1024        mesh->mVertexBuffer->mPosition          = new Vector3[vertex_count];
1025        mesh->mVertexBuffer->mNormal                    = new Vector3[vertex_count];
1026        mesh->mVertexBuffer->mTexCoords         = new Vector2[vertex_count];
1027
1028        mesh->mVertexBuffer->mVertexInfo        = vertex_buffer->mVertexInfo;
1029        mesh->mVertexBuffer->mVertexCount       = vertex_count;
1030
1031        mGMVB   =       mesh->mVertexBuffer;
1032
1033        //      Fill up unique vertices.
1034        for (i  =        0; i < vertex_count; i++)
1035        {
1036                //      Find first ocurrence of unique vertex.
1037                it      =       mVertices.find(i);
1038
1039                aux_i   =       (*it).second;
1040
1041                mGMVB->mPosition[i].x   =       vertex_buffer->mPosition[aux_i].x;
1042                mGMVB->mPosition[i].y   =       vertex_buffer->mPosition[aux_i].y;
1043                mGMVB->mPosition[i].z   =       vertex_buffer->mPosition[aux_i].z;
1044
1045                mGMVB->mNormal[i].x     =       vertex_buffer->mNormal[aux_i].x;
1046                mGMVB->mNormal[i].y     =       vertex_buffer->mNormal[aux_i].y;
1047                mGMVB->mNormal[i].z     =       vertex_buffer->mNormal[aux_i].z;
1048
1049                mGMVB->mTexCoords[i].x  =       vertex_buffer->mTexCoords[aux_i].x;
1050                mGMVB->mTexCoords[i].y  =       vertex_buffer->mTexCoords[aux_i].y;
1051        }
1052
1053        //      Fill up indices to unique vertices.
1054        //      For each submesh.
1055        for (submesh    =       0; submesh < mesh->mSubMeshCount; submesh++)
1056        {
1057                geosubmesh      =       &mesh->mSubMesh[submesh];
1058
1059                //      Change indices.
1060                for (i  =       0; i < geosubmesh->mIndexCount; i++)
1061                {
1062                        //      Unique index asociated to the given one.
1063                        it_map  =       newindices.find(geosubmesh->mIndex[i]);
1064
1065                        geosubmesh->mIndex[i]   =       (*it_map).second;
1066                }
1067        }
1068}
1069
1070//-------------------------------------------------------------------------
1071//      Return  mesh that may have repeated vertices for texture aparence.
1072//-------------------------------------------------------------------------
1073Mesh    *TextureConserver::GetMesh()
1074{
1075        return  mGeoMesh;
1076}
1077
Note: See TracBrowser for help on using the repository browser.