source: GTP/trunk/Lib/Geom/shared/GTGeometry/src/libs/SimplificationMethod.cpp @ 2089

Revision 2089, 44.5 KB checked in by gumbau, 17 years ago (diff)
Line 
1#include <stdlib.h>
2#include "SimplificationMethod.h"
3#include <iostream>
4#include <fstream>
5#include <gfx/geom/ProxGrid.h>
6#include "quadrics.h"
7
8using namespace std;
9using namespace Geometry;
10using   namespace       simplif;
11
12//-------------------------------------------------------------------------
13//      Constructor
14//-------------------------------------------------------------------------
15SimplificationMethod::SimplificationMethod(const Mesh *m)
16{
17        mInitialMesh                            =       new Mesh();
18        *mInitialMesh                           =       *m;
19        mGeoMesh                                                =       NULL;
20        first_index_submesh     =       new unsigned int[mInitialMesh->mSubMeshCount];
21        indexMeshLeaves                 =       -1;
22
23        //      Create simplification sequence.
24        msimpseq        =       new MeshSimplificationSequence();
25}
26
27//-------------------------------------------------------------------------
28//      Destructor
29//-------------------------------------------------------------------------
30SimplificationMethod::~SimplificationMethod()
31{
32        delete  heap;
33        delete  [] first_index_submesh;
34
35        delete  mInitialMesh;
36}
37
38//-------------------------------------------------------------------------
39//      Recalculate the cost of the vertices of an edge
40//-------------------------------------------------------------------------
41void SimplificationMethod::compute_pair_info(simplif::pair_info *auxpair)
42{
43        simplif::Vertex *v0 = auxpair->v0;
44        simplif::Vertex *v1 = auxpair->v1;
45
46        simplif::vert_info& v0_info = vertex_info(v0);
47        simplif::vert_info& v1_info = vertex_info(v1);
48
49        simplif::Mat4 Q                 =       v0_info.Q + v1_info.Q;
50        simplif::real norm      =       v0_info.norm + v1_info.norm;
51
52        auxpair->cost = simplif::quadrix_pair_target(   Q,
53                                                                                                                                                                                                v0,
54                                                                                                                                                                                                v1,
55                                                                                                                                                                                                auxpair->candidate);
56
57        if ( simplif::will_weight_by_area )
58        {
59                auxpair->cost /= norm;
60        }
61
62        if ( simplif::will_preserve_mesh_quality )
63        {
64                auxpair->cost += pair_mesh_penalty(M0, v0, v1, auxpair->candidate);
65        }
66
67        //
68        // NOTICE:  In the heap we use the negative cost.  That's because
69        //          the heap is implemented as a MAX heap.
70        //
71        if ( auxpair->isInHeap() )
72        {
73                heap->update(auxpair, (float)-auxpair->cost);
74        }
75        else
76        {
77                heap->insert(auxpair, (float)-auxpair->cost);
78        }
79}
80
81//-------------------------------------------------------------------------
82//      Reasign the new vertex to the adequate face
83//-------------------------------------------------------------------------
84int SimplificationMethod::predict_face( simplif::Face& F,
85                                                                                                                                                                simplif::Vertex *v1,
86                                                                                                                                                                simplif::Vertex *v2,
87                                                                                                                                                                simplif::Vec3& vnew,
88                                                                                                                                                                simplif::Vec3& f1,
89                                                                                                                                                                simplif::Vec3& f2,
90                                                                                                                                                                simplif::Vec3& f3)
91{
92        int nmapped = 0;
93
94        if ( F.vertex(0) == v1 || F.vertex(0) == v2 )
95        {
96                f1 = vnew;  nmapped++;
97        }
98        else
99        {
100                f1 = *F.vertex(0);
101        }
102
103        if ( F.vertex(1) == v1 || F.vertex(1) == v2 )
104        {
105                f2 = vnew;  nmapped++;
106        }
107        else
108        {
109                f2 = *F.vertex(1);
110        }
111
112        if ( F.vertex(2) == v1 || F.vertex(2) == v2 )
113        {
114                f3 = vnew;  nmapped++;
115        }
116        else
117        {
118                f3 = *F.vertex(2);
119        }
120
121        return nmapped;
122}
123
124#define MESH_INVERSION_PENALTY 1e9
125
126//-------------------------------------------------------------------------
127//-------------------------------------------------------------------------
128simplif::real SimplificationMethod::pair_mesh_penalty(simplif::Model& M,
129                                                                                                                                                                                                                        simplif::Vertex *v1,
130                                                                                                                                                                                                                        simplif::Vertex *v2,
131                                                                                                                                                                                                                        simplif::Vec3& vnew)
132{
133        static simplif::face_buffer changed;
134
135        changed.reset();
136
137        M.contractionRegion(v1, v2, changed);
138
139        // real Nsum = 0;
140        simplif::real Nmin = 0;
141
142        for (int i      =       0; i < changed.length(); i++)
143        {
144                simplif::Face& F = *changed(i);
145                simplif::Vec3 f1, f2, f3;
146
147                int nmapped = predict_face(F, v1, v2, vnew, f1, f2, f3);
148
149                // Only consider non-degenerate faces
150                if( nmapped < 2 )
151                {
152                        simplif::Plane Pnew(f1, f2, f3);
153
154                        simplif::real delta =  Pnew.normal() * F.plane().normal();
155
156                        if( Nmin > delta )
157                        {
158                                Nmin = delta;
159                        }
160                }
161        }
162
163        //return (-Nmin) * MESH_INVERSION_PENALTY;
164        if( Nmin < 0.0 )
165        {
166                return MESH_INVERSION_PENALTY;
167        }
168        else
169        {
170                return 0.0;
171        }
172}
173
174//-------------------------------------------------------------------------
175//      Returns true if the givens vertices are a valid pair
176//-------------------------------------------------------------------------
177bool SimplificationMethod::check_for_pair(simplif::Vertex *v0,
178                                                                                                                                                                        simplif::Vertex *v1)
179{
180        const simplif::pair_buffer& pairs = vertex_info(v0).pairs;
181
182        for(int i=0; i<pairs.length(); i++)
183        {
184                if( pairs(i)->v0==v1 || pairs(i)->v1==v1 )
185                {
186                        return true;
187                }
188        }
189
190        return false;
191}
192
193//-------------------------------------------------------------------------
194//      Create a new pair with two given vertices
195//-------------------------------------------------------------------------
196simplif::pair_info *SimplificationMethod::new_pair(     simplif::Vertex *v0,
197                                                                                                                                                                                                                simplif::Vertex *v1)
198{
199        simplif::vert_info& v0_info = vertex_info(v0);
200        simplif::vert_info& v1_info = vertex_info(v1);
201
202        simplif::pair_info *pair = new simplif::pair_info(v0,v1);
203
204        v0_info.pairs.add(pair);
205        v1_info.pairs.add(pair);
206
207        return pair;
208}
209
210//-------------------------------------------------------------------------
211//      Remove a given pair
212//-------------------------------------------------------------------------
213void SimplificationMethod::delete_pair(simplif::pair_info *auxpair)
214{
215        simplif::vert_info& v0_info = vertex_info(auxpair->v0);
216        simplif::vert_info& v1_info = vertex_info(auxpair->v1);
217
218        v0_info.pairs.remove(v0_info.pairs.find(auxpair));
219        v1_info.pairs.remove(v1_info.pairs.find(auxpair));
220
221        if ( auxpair->isInHeap() )
222        {
223                heap->kill(auxpair->getHeapPos());
224        }
225
226        delete auxpair;
227}
228
229//-------------------------------------------------------------------------
230//      Contract a given pair
231//-------------------------------------------------------------------------
232void SimplificationMethod::do_contract( simplif::Model& m,
233                                                                                                                                                                simplif::pair_info *auxpair)
234{
235        simplif::Vertex                 *v0                     = auxpair->v0;
236        simplif::Vertex                 *v1                     = auxpair->v1;
237        simplif::Vec3                   vnew            = auxpair->candidate;
238        float                                                           x,y,z;
239        simplif::Vertex                 *aux_vert;
240
241        _float3_                                                removed_vert;
242        int                                                                     i;
243        vertex_map_str                  lb;
244        vertex_map_str                  ub;
245       
246        // V0 must be always the alive vertex
247        // V1 must be always the removed vertex
248        if (vnew == (*v0))
249        {
250                //      Coords of the removed vertex.
251                x       =       (*v1)[X];
252                y       =       (*v1)[Y];
253                z       =       (*v1)[Z];
254
255                aux_vert        =       v1;
256        }
257        else
258        {
259                //      Coords of the removed vertex.
260                x       =       (*v0)[X];
261                y       =       (*v0)[Y];
262                z       =       (*v0)[Z];
263
264                //      Simplification step.
265                aux_vert        =       v0;
266                v0      =       v1;
267                v1      =       aux_vert;
268        }
269
270        simplif::vert_info&     v0_info = vertex_info(v0);
271        simplif::vert_info&     v1_info = vertex_info(v1);
272
273        //      Simplification step.
274        simplifstep.mV0 = v0->vID;
275        simplifstep.mV1 = v1->vID;
276
277        //      Position of the vertex removed.
278        removed_vert    =       _float3_(x,y,z);
279
280        //      If position of the removed vertex is found.
281        if (vertexMultimap.end() != vertexMultimap.find(removed_vert))
282        {
283                lb      =       vertexMultimap.lower_bound(removed_vert);
284                ub      =       vertexMultimap.upper_bound(removed_vert);
285
286                //      For each vertex.
287                while   (lb != ub)
288                {
289                        //      If removed vertex is found.
290                        if ((*lb).second == aux_vert->vID)
291                        {
292                                //      Debug.
293                                cout    <<      "to remove: "
294                                                        <<      (*lb).second
295                                                        <<      endl;
296
297                                //      Delete vertex that disappears.
298                                vertexMultimap.erase(lb);
299                               
300                                //      Break while.
301                                lb      =       ub;
302                        }
303                        else
304                        {
305                                //      Next iteration.
306                                lb++;
307                        }
308                }
309        }
310
311        //      Make v0 be the new vertex
312        v0_info.Q                       += v1_info.Q;
313        v0_info.norm    += v1_info.norm;
314
315        simplif::Vec3 p(vnew);
316
317        //      Perform the actual contraction.
318        static simplif::face_buffer changed;
319
320        changed.reset();
321        m.contract(v0, v1, vnew, changed);
322
323        //      Stores the displacement in the simplification step.
324        simplifstep.x = (float)0.0f;
325        simplifstep.y = (float)0.0f;
326        simplifstep.z = (float)0.0f;
327
328        //      Number of triangles that are removed in this simplification step.
329        int _numDelTris = 0; // 1 or 2 triangles can be removed.
330
331        for (i = 0;     i < changed.length();   i++)
332        {
333                if (!changed(i)->isValid())
334                {
335                        _numDelTris++;
336                }
337        }
338
339        int del_index   =       0;
340
341        //      Clears faces list.
342        simplifstep.mModfaces.clear();
343
344        //      mModfaces y mT0, mT1 of simplifstep stores
345        //      the triangles id's -> geomesh has not triangles id's.
346        for (i  =       0;      i < changed.length();   i++)
347        {
348                simplif::Face *auxface  =       changed(i);
349
350                if (auxface->isValid())
351                {
352                        //      Modified triangles.
353                        simplifstep.mModfaces.push_back(auxface->validID());
354                }
355                else
356                {
357                        //      Removed triangles.
358                        if (_numDelTris == 1)
359                        {
360                                simplifstep.mT0 =       auxface->validID();
361                                simplifstep.mT1 =       auxface->validID();
362                        }
363                        else
364                        {
365                                if(del_index == 0)
366                                {
367                                        simplifstep.mT0 =       auxface->validID();
368                                        del_index++;
369                                }
370                                else
371                                {
372                                        simplifstep.mT1 =       auxface->validID();
373                                }
374                        }
375                }
376        }
377
378        //      Simplification sequence that make reference to the
379        //      simplification method sequence.
380        //decim_data.push_back(simplifstep);
381
382        //      Adds new simplification step.
383        msimpseq->mSteps.push_back(simplifstep);
384
385#ifdef SUPPORT_VCOLOR
386        //      If the vertices are colored, color the new vertex
387        //      using the average of the old colors.
388        v0->props->color += v1->props->color;
389        v0->props->color /= 2;
390#endif
391
392        //      Remove the pair that we just contracted.
393        delete_pair(auxpair);
394
395        //      Recalculate pairs associated with v0.
396        for (i  =       0;      i < v0_info.pairs.length();     i++)
397        {
398                simplif::pair_info *p = v0_info.pairs(i);
399                compute_pair_info(p);
400        }
401
402        //      Process pairs associated with now dead vertex.
403        //      Collect condemned pairs for execution.
404        static simplif::pair_buffer condemned(6);
405
406        condemned.reset();
407
408        //      Recalculate pairs associated with v1.
409        for (i  =       0;      i < v1_info.pairs.length(); i++)
410        {
411                simplif::pair_info *p = v1_info.pairs(i);
412
413                simplif::Vertex *u;
414
415                if ( p->v0 == v1 )
416                {
417                        u = p->v1;
418                }
419                else
420                {
421                        if ( p->v1 == v1)
422                        {
423                                u = p->v0;
424                        }
425                        else
426                        {
427                                std::cerr << "YOW!  This is a bogus pair." << endl;
428                        }
429                }
430
431                if ( !check_for_pair(u, v0) )
432                {
433                        p->v0   =       v0;
434                        p->v1   =       u;
435
436                        v0_info.pairs.add(p);
437                        compute_pair_info(p);
438                }
439                else
440                {
441                        condemned.add(p);
442                }
443        }
444
445        for (i  =       0;      i < condemned.length(); i++)
446        {
447                // Do you have any last requests?
448                delete_pair(condemned(i));
449        }
450
451        //      Safety precaution.
452        v1_info.pairs.reset();
453}
454
455//-------------------------------------------------------------------------
456//-------------------------------------------------------------------------
457bool SimplificationMethod::decimate_quadric(simplif::Vertex *v,
458                                                                                                                                                                                simplif::Mat4& Q)
459{
460        if( vinfo.length() > 0 )
461        {
462                Q = vinfo(v->uniqID).Q;
463                return true;
464        }
465        else
466        {
467                return false;
468        }
469}
470
471//-------------------------------------------------------------------------
472//      Extract a pair from the heap, concract it and remove it from the heap.
473//-------------------------------------------------------------------------
474void SimplificationMethod::decimate_contract(simplif::Model& m)
475{
476        simplif::heap_node      *top;
477        simplif::pair_info      *pair;
478        simplif::Vertex                 *v0;
479        simplif::Vertex                 *v1;
480        simplif::Vec3                           candidate;
481        _float3_                                                f0;
482        _float3_                                                f1;
483
484        for (;;)
485        {
486                top     =       heap->extract();
487               
488                if (!top)
489                {
490                        return;
491                }
492               
493                pair    =       (simplif::pair_info *)top->obj;
494
495                //      Remove all the vertices of the removed edges.
496                bool    sharededge      =       false;
497               
498                for (int        i       =       0;      i < pair->v0->edgeUses().length();      i++)
499                {
500                        simplif::Edge   *econ   =       pair->v0->edgeUses()(i);
501                       
502                        if (pair->v1->vID == econ->org()->vID
503                                        ||
504                                        pair->v1->vID == econ->dest()->vID)
505                        {
506                                sharededge      =       true;
507                                break;
508                        }
509                }
510
511                //      Coordinates of the pair.
512                f0      =       _float3_((*pair->v0)[X],(*pair->v0)[Y],(*pair->v0)[Z]);
513                f1      =       _float3_((*pair->v1)[X],(*pair->v1)[Y],(*pair->v1)[Z]);
514
515                if (pair->isValid()
516                                &&
517                                sharededge
518                                &&
519                                (vertexMultimap.find(f0) != vertexMultimap.end())
520                                &&
521                                (vertexMultimap.find(f1) != vertexMultimap.end()))
522                {
523                        break;
524                }
525
526                //      Debug.
527                cout    <<      "Deleting pair ("
528                                        <<      pair->v0->vID
529                                        <<      "--"
530                                        <<      pair->v1->vID
531                                        <<      ")"
532                                        <<      endl;
533
534                //      Deletes repetitions of pair in heap.
535                delete_pair(pair);
536        }
537
538        //      Copy pair.
539        v0      =       new Vertex(     (*pair->v0)[X],
540                                                                                (*pair->v0)[Y],
541                                                                                (*pair->v0)[Z]);
542
543        v0->vID = pair->v0->vID;
544       
545        v1      =       new Vertex(     (*pair->v1)[X],
546                                                                                (*pair->v1)[Y],
547                                                                                (*pair->v1)[Z]);
548
549        v1->vID = pair->v1->vID;
550
551        candidate       =       pair->candidate;
552
553        //      First contract.
554        simplifstep.obligatory  =       0;
555
556        //      Debug.
557        cout    <<      "Contracting... "
558                                <<      endl;
559
560        //      Contract main pair.
561        do_contract(m, pair);
562
563        //      Twin contract and lonely vertex contract.
564        simplifstep.obligatory  =       1;
565
566        //      Attempt to maintain valid vertex information.
567        M0.validVertCount--;
568
569        //      Find twin vertices to the contracted one and contract them.
570        removeTwinVertices(m,v0,v1,candidate);
571
572        //      Free Memory.
573        delete  v0;
574        delete  v1;
575}
576
577//-------------------------------------------------------------------------
578//      Find twin vertices to the contracted one and contract them.
579//-------------------------------------------------------------------------
580void SimplificationMethod::removeTwinVertices(simplif::Model    &m,
581                                                                                                                                                                                        simplif::Vertex *v0,
582                                                                                                                                                                                        simplif::Vertex *v1,
583                                                                                                                                                                                        simplif::Vec3           candidate)
584{
585        bool                                                            twin_found;
586        simplif::Edge                           *edge;
587        simplif::pair_info      *pair;
588        simplif::Vertex                 *vert;
589        simplif::Vertex                 *lonely_vert;
590        simplif::Vertex                 *new_vert;
591        vertex_map_str                  lb;
592        vertex_map_str                  ub;
593        vertex_map_str                  it;
594        _float3_                                                f0;
595        _float3_                                                f1;
596        simplif::Edge                           *econ;
597        simplif::vert_info      new_vert_info;
598        Geometry::GeoVertex     vertex_added;
599        simplif::Vertex                 *take_bone_from_vert;
600        float                                                           x,y,z;
601
602        if ((*v0) != (*v1))
603        {
604                //      Gets the vertex that is not the candidate.
605                if ((*v1) == candidate)
606                {
607                        vert                                                            = v0;
608                        v0                                                                      =       v1;
609                        v1                                                                      =       vert;
610                }
611
612                take_bone_from_vert = v0;
613
614                f0      =       _float3_((*v0)[X],(*v0)[Y],(*v0)[Z]);
615                f1      =       _float3_((*v1)[X],(*v1)[Y],(*v1)[Z]);
616
617                while ((it = vertexMultimap.find(f1)) != vertexMultimap.end())
618                {
619                        twin_found      =       false;
620
621                        lonely_vert     =       m.vertex((*it).second);
622
623                        for (int        i       =       0;      i < lonely_vert->edgeUses().length();   i++)
624                        {
625                                econ    =       lonely_vert->edgeUses()(i);
626
627                                if (((*econ->org()) == (*v0))
628                                                ||
629                                                ((*econ->dest()) == (*v0)))
630                                {
631                                        lb      =       vertexMultimap.lower_bound(f0);
632                                        ub      =       vertexMultimap.upper_bound(f0);
633
634                                        //      For each vertex.
635                                        while   (lb != ub)
636                                        {
637                                                //      If removed vertex is found.
638                                                if (((*lb).second == econ->org()->vID)
639                                                                ||
640                                                                ((*lb).second == econ->dest()->vID))
641                                                {
642                                                        twin_found      =       true;
643
644                                                        //      Break while.
645                                                        lb      =       ub;
646                                                }
647                                                else
648                                                {
649                                                        //      Next iteration.
650                                                        lb++;
651                                                }
652                                        }
653
654                                        break;
655                                }
656                        }
657
658                        //      If a twin edge has been found.
659                        if (twin_found)
660                        {
661                                //      Debug.
662                                cout    <<      "Twin Contracted..."    <<      endl;
663
664                                //      Extract twin edge from heap.
665                                pair    =       new_pair(econ->org(),econ->dest());
666
667                                //      Copy candidate.
668                                pair->candidate =       candidate;
669
670                                pair->notInHeap();
671
672                                //      Contract twin pair.
673                                do_contract(m, pair);
674                                M0.validVertCount--;
675                        }
676                        else
677                        {
678                                //      Debug.
679                                cout    <<      "Contracting new pair..."       <<      endl;
680
681                                new_vert        =       m.newVertex(candidate[X],candidate[Y],candidate[Z]);
682
683                                //      Add new vert to multimap.
684                                x       =       (*new_vert)[X];
685                                y       =       (*new_vert)[Y];
686                                z       =       (*new_vert)[Z];
687
688                                //      Adds new vertex to multimap.
689                                vertexMultimap.insert(vertex_pair(_float3_(x,y,z),new_vert->vID));
690
691                                //      Creates new edge.
692                                edge    =       m.newEdge(new_vert,lonely_vert);
693
694                                //      We assume here there are the same number of vertices
695                                //      and texture coordinates and normals.
696
697                                // Assign a texture coordinate for the vertex.
698                                simplif::Vec2 newtexcoord = m.texcoord(lonely_vert->vID);
699                                m.in_TexCoord(newtexcoord);
700
701                                //      Assign a normal coordinate for the vbertex.
702                                simplif::Vec3 newnormal = m.normal(lonely_vert->vID);
703                                m.in_Normal(newnormal);
704
705                                //      Adds new vertex information to simplification sequence.
706                                vertex_added.id                         =       new_vert->vID;
707
708                                vertex_added.bonefrom   =       take_bone_from_vert->vID;
709
710                                vertex_added.position   =       Vector3(candidate[X],
711                                                                                                                                                                candidate[Y],
712                                                                                                                                                                candidate[Z]);
713
714                                simplif::Vec2 tc                        = m.texcoord(new_vert->vID);
715                                vertex_added.texcoord   =       Vector2(tc[X],tc[Y]);
716
717                                simplif::Vec3 vn                = m.normal(new_vert->vID);
718                                vertex_added.normal     =       Vector3(vn[X],vn[Y],vn[Z]);
719
720                                msimpseq->mNewVertices.push_back(vertex_added);
721
722                                pair                                            =       new_pair(new_vert,lonely_vert);
723                                pair->candidate =       candidate;
724                                pair->notInHeap();
725
726                                //      Contract new pair.
727                                do_contract(m, pair);
728                                M0.validVertCount--;
729                        }
730                }
731        }
732}
733
734//-------------------------------------------------------------------------
735//-------------------------------------------------------------------------
736simplif::real SimplificationMethod::decimate_error(simplif::Vertex *v)
737{
738        simplif::vert_info& info = vertex_info(v);
739
740        simplif::real err = simplif::quadrix_evaluate_vertex(*v, info.Q);
741
742    if ( simplif::will_weight_by_area )
743                {
744                        err /= info.norm;
745                }
746
747    return err;
748}
749
750//-------------------------------------------------------------------------
751//      Extract the minimum cost of the the valid nodes (not simplified)
752//-------------------------------------------------------------------------
753simplif::real SimplificationMethod::decimate_min_error()
754{
755        simplif::heap_node *top;
756        simplif::pair_info *pair;
757
758        for(;;)
759        {
760                top = heap->top();
761               
762                if( !top )
763                {
764                        return -1.0;
765                }
766
767                pair = (simplif::pair_info *)top->obj;
768
769                if( pair->isValid() )
770                {
771                        break;
772                }
773
774                top = heap->extract();
775                delete_pair(pair);
776        }
777
778        return pair->cost;
779}
780
781//-------------------------------------------------------------------------
782//      Returns the maximum error by vertex
783//-------------------------------------------------------------------------
784simplif::real SimplificationMethod::decimate_max_error(simplif::Model& m)
785{
786        simplif::real max_err = 0;
787
788        for(int i=0; i<m.vertCount(); i++)
789                if( m.vertex(i)->isValid() )
790                {
791                        max_err = MAX(max_err, decimate_error(m.vertex(i)));
792                }
793
794        return max_err;
795}
796
797//-------------------------------------------------------------------------
798//      Initializations
799//-------------------------------------------------------------------------
800void SimplificationMethod::decimate_init(       simplif::Model  &m,
801                                                                                                                                                                        simplif::real   limit)
802{
803        int i,j;
804
805        //      Reserve memory for vert_info array.
806        vinfo.init(m.vertCount()*2);
807
808        if (simplif::will_use_vertex_constraint)
809        {
810                //      For each vertex, calculate contraints.
811                for     (i      =       0;      i < m.vertCount();      i++)
812                {
813                        simplif::Vertex *v      =       m.vertex(i);
814                       
815                        if (v->isValid())
816                        {
817                                vertex_info(v).Q = simplif::quadrix_vertex_constraint(*v);
818                        }
819                }
820        }
821
822        //      For each face, recalculate constraints.
823        for (i  =       0;      i < m.faceCount();      i++)
824        {
825                if (m.face(i)->isValid())
826                {
827                        if (simplif::will_use_plane_constraint)
828                        {
829                                simplif::Mat4 Q = simplif::quadrix_plane_constraint(*m.face(i));
830                                simplif::real norm = 0.0;
831
832                                if (simplif::will_weight_by_area)
833                                {
834                                        norm    =               m.face(i)->area();
835                                        Q                       *=      norm;
836                                }
837
838                                for (j  =       0;      j < 3;  j++)
839                                {
840                                        vertex_info(m.face(i)->vertex(j)).Q                     +=      Q;
841                                        vertex_info(m.face(i)->vertex(j)).norm  +=      norm;
842                                }
843                        }
844                }
845        }
846
847        if (simplif::will_constrain_boundaries)
848        {
849                //      For each edge, recalculate constraints.
850                for (i  =       0;      i < m.edgeCount();      i++)
851                {
852                        if (m.edge(i)->isValid() && simplif::check_for_discontinuity(m.edge(i)))
853                        {
854                                simplif::Mat4 B = simplif::quadrix_discontinuity_constraint(m.edge(i));
855                                simplif::real norm = 0.0;
856
857                                if (simplif::will_weight_by_area)
858                                {
859                                        norm    =               simplif::norm2(*m.edge(i)->org() - *m.edge(i)->dest());
860                                        B                       *=      norm;
861                                }
862
863                                B *= simplif::boundary_constraint_weight;
864                                vertex_info(m.edge(i)->org()).Q += B;
865                                vertex_info(m.edge(i)->org()).norm += norm;
866                                vertex_info(m.edge(i)->dest()).Q += B;
867                                vertex_info(m.edge(i)->dest()).norm += norm;
868                        }
869                }
870        }
871
872        //      Create heap.
873        heap = new simplif::Heap(m.validEdgeCount);
874
875        int pair_count = 0;
876
877        //      For each edge, add pairs to heap.
878        for (i  =       0;      i < m.edgeCount();      i++)
879        {
880                if (m.edge(i)->isValid())
881                {
882                        simplif::pair_info *pair = new_pair(m.edge(i)->org(), m.edge(i)->dest());
883                        //pointers_to_remove.push_back(pair);
884
885                        compute_pair_info(pair);
886                        pair_count++;
887                }
888        }
889
890        if (limit < 0)
891        {
892                limit   =       m.bounds.radius * 0.05;
893        }
894       
895        proximity_limit =       limit * limit;
896       
897        if (proximity_limit > 0)
898        {
899                simplif::ProxGrid grid(m.bounds.min, m.bounds.max, limit);
900               
901                //      Add points to grid.
902                for (i  =       0;      i < m.vertCount();      i++)
903                {
904                        grid.addPoint(m.vertex(i));
905                }
906
907                simplif::buffer<simplif::Vec3 *> nearby(32);
908               
909                //      For each vertex.
910                for (i  =       0;      i < m.vertCount();      i++)
911                {
912                        nearby.reset();
913                        grid.proximalPoints(m.vertex(i), nearby);
914
915                        for (j  =       0;      j < nearby.length();    j++)
916                        {
917                                simplif::Vertex *v1 = m.vertex(i);
918                                simplif::Vertex *v2 = (simplif::Vertex *)nearby(j);
919
920                                if (v1->isValid() && v2->isValid())
921                                {
922#ifdef SAFETY
923                                        assert(pair_is_valid(v1,v2));
924#endif
925                                        if (!check_for_pair(v1,v2))
926                                        {
927                                                simplif::pair_info *pair = new_pair(v1,v2);
928                                                compute_pair_info(pair);
929                                                pair_count++;
930                                        }
931                                }
932                        }
933                }
934        }
935}
936
937//-------------------------------------------------------------------------
938//      Initilizations
939//-------------------------------------------------------------------------
940void SimplificationMethod::simplifmethod_init(void)
941{
942        // Change mesh structure.
943        generateSimplifModel();
944               
945        M0.bounds.complete();
946
947        initialVertCount = M0.vertCount();
948        initialEdgeCount = M0.edgeCount();
949        initialFaceCount = M0.faceCount();
950
951        // Get rid of degenerate faces.
952        for (int        i       =       0;      i < M0.faceCount();     i++)
953        {
954                if (!M0.face(i)->plane().isValid())
955                {
956                        M0.killFace(M0.face(i));
957                }
958        }
959
960        M0.removeDegeneracy(M0.allFaces());
961
962        // Get rid of unused vertices.
963        for (int        i       =       0;      i < M0.vertCount();     i++)
964        {
965                if (M0.vertex(i)->edgeUses().length() == 0)
966                {
967                        M0.vertex(i)->kill();
968                }
969        }
970}
971
972//-------------------------------------------------------------------------
973//      Do the contractions till the required LOD (percentage option)
974//-------------------------------------------------------------------------
975void SimplificationMethod::simplifmethod_run(int finalfaces,TIPOFUNC upb)
976{
977        decimate_init(M0, simplif::pair_selection_tolerance);
978        unsigned        int     contador        =       0;
979        float                                   percent; // simplification percentage.
980
981        percent =       (float)(2.0 * 100.0) / (M0.validFaceCount - finalfaces);
982
983        //      Update progress bar.
984        if (upb)
985        {
986                upb(0.0);
987        }
988
989        /*
990        for (   std::vector<MeshSimplificationSequence::Step>::iterator
991                                it      =       decim_data.begin();
992                                it != decim_data.end();
993                                it++)
994        {
995                it->mModfaces.clear();
996        }
997       
998        decim_data.clear();
999        */
1000
1001        //      Debug.
1002        cout    <<      "M0.validFaceCount: "   <<      M0.validFaceCount       <<      endl;
1003        cout    <<      "finalfaces: "                          <<      finalfaces                              <<      endl;
1004       
1005        while ( M0.validFaceCount > finalfaces/*simplif::face_target*/
1006                                        && M0.validFaceCount > 1
1007                                        && decimate_min_error() < simplif::error_tolerance )
1008        {
1009                decimate_contract(M0);
1010
1011                //      Update progress bar.
1012                if (upb)
1013                {
1014                        upb(percent);
1015                }
1016        }
1017
1018        //      Update progress bar.
1019        if (upb)
1020        {
1021                upb(100.0);
1022        }
1023}
1024
1025//-------------------------------------------------------------------------
1026//      Do the contractions till the required LOD (number of vertices option)
1027//-------------------------------------------------------------------------
1028void SimplificationMethod::simplifmethod_runv(int numvertices,TIPOFUNC upb)
1029{
1030        decimate_init(M0, simplif::pair_selection_tolerance);
1031        unsigned        int     contador        =       0;
1032        int                                             previousValidVertCount;
1033        float                                   percent; // Simplification percentage.
1034
1035        previousValidVertCount  =       0;
1036
1037        percent =       (float)(2.0 * 100.0)
1038                                                /
1039                                                (float)((M0.validFaceCount - numvertices / 3.0));
1040
1041        //      Update progress bar.
1042        if (upb)
1043        {
1044                upb(0.0);
1045        }
1046
1047        /*
1048        for (   std::vector<MeshSimplificationSequence::Step>::iterator
1049                                it      =       decim_data.begin();
1050                                it != decim_data.end();
1051                                it++)
1052        {
1053                it->mModfaces.clear();
1054        }
1055       
1056        decim_data.clear();
1057        */
1058
1059        //      Debug.
1060        cout    <<      "M0.validVertCount:     "       <<      M0.validVertCount       <<      endl;
1061        cout    <<      "numvertices:   "       <<      numvertices     <<      endl;
1062
1063        while(  M0.validVertCount > numvertices /*simplif::face_target*/
1064                        &&
1065                        decimate_min_error() < simplif::error_tolerance
1066                        &&
1067                        previousValidVertCount  !=      M0.validVertCount)
1068        {
1069                previousValidVertCount  =       M0.validVertCount;
1070
1071                decimate_contract(M0);
1072
1073                //      Update progress bar.
1074                if (upb)
1075                {
1076                        upb(percent);
1077                }
1078        }
1079
1080        //      Update progress bar.
1081        if (upb)
1082        {
1083                upb(100.0);
1084        }
1085}
1086
1087//-------------------------------------------------------------------------
1088//      Generate simplification model.
1089//-------------------------------------------------------------------------
1090void    SimplificationMethod::generateSimplifModel(void)
1091{
1092        int             face_index      =       0;
1093        int             vertID;
1094        float   x,y,z;
1095
1096        //      For each submesh.
1097        bool added_vertices = false;
1098        for (size_t     i =     0;      i       <       mInitialMesh->mSubMeshCount;    i++)
1099        {
1100                //      If is not a tree leaves submesh.
1101                if (i != indexMeshLeaves)
1102                {
1103                        //      For all the vertices of each submesh.
1104                        for (   size_t  j       =       0;
1105                                        j < mInitialMesh->mSubMesh[i].mVertexBuffer->mVertexCount;
1106                                        j++)
1107                        {
1108                                x       =       mInitialMesh->mSubMesh[i].mVertexBuffer->mPosition[j].x;
1109                                y       =       mInitialMesh->mSubMesh[i].mVertexBuffer->mPosition[j].y;
1110                                z       =       mInitialMesh->mSubMesh[i].mVertexBuffer->mPosition[j].z;
1111
1112                                //      If the vertex is not in vertices_map, then is added.
1113                                vertID  =       M0.in_Vertex(simplif::Vec3(
1114                                                        mInitialMesh->mSubMesh[i].mVertexBuffer->mPosition[j].x,
1115                                                        mInitialMesh->mSubMesh[i].mVertexBuffer->mPosition[j].y,
1116                                                        mInitialMesh->mSubMesh[i].mVertexBuffer->mPosition[j].z));
1117
1118                                M0.in_Normal(simplif::Vec3(
1119                                                        mInitialMesh->mSubMesh[i].mVertexBuffer->mNormal[j].x,
1120                                                        mInitialMesh->mSubMesh[i].mVertexBuffer->mNormal[j].y,
1121                                                        mInitialMesh->mSubMesh[i].mVertexBuffer->mNormal[j].z));
1122
1123                                M0.in_TexCoord(simplif::Vec2(
1124                                                        mInitialMesh->mSubMesh[i].mVertexBuffer->mTexCoords[j].x,
1125                                                        mInitialMesh->mSubMesh[i].mVertexBuffer->mTexCoords[j].y));
1126
1127                                added_vertices = true;
1128
1129                                //      Add vertex to multimap.
1130                                vertexMultimap.insert(vertex_pair(_float3_(x,y,z),vertID));
1131                        }
1132                }
1133
1134                //      If is shared vertex buffer object.
1135                if (mInitialMesh->mSubMesh[i].mSharedVertexBuffer && added_vertices)
1136                {
1137                        printf("Shared break");
1138                        break;
1139                }
1140        }
1141
1142        //      For each submesh.
1143        for (size_t     i = 0;  i < mInitialMesh->mSubMeshCount;        i++)
1144        {
1145                if (i != indexMeshLeaves)
1146                {
1147                        for (   Geometry::Index j       =       0;
1148                                                j < mInitialMesh->mSubMesh[i].mIndexCount;
1149                                                j       +=      3)
1150                        {
1151                                //      +1 is required because the first index in the
1152                                //      simplification method is 1
1153                                //      Index of the vertex in vertices_map.
1154                                Geometry::Index index0  =               mInitialMesh->mSubMesh[i].mIndex[j];
1155                               
1156                                Geometry::Index index1  =               mInitialMesh->mSubMesh[i].mIndex[j + 1];
1157                               
1158                                Geometry::Index index2  =               mInitialMesh->mSubMesh[i].mIndex[j + 2];
1159                               
1160                                //      Create a triangle with its indices in vertices_map.
1161                                face_index      =       M0.miin_Face(
1162                                                index0,
1163                                                index1,
1164                                                index2);
1165
1166                                //      igeo allows to identify the submesh that contains the triangle.
1167                                M0.face(face_index)->igeo       =       (int)i;
1168                        }
1169                }
1170        }
1171        number_of_triangles     =       face_index;
1172}
1173
1174//-------------------------------------------------------------------------
1175//      simplifmethod_init is executed to do some initalizations
1176//      simplifmethod_run is executed to do the decimation
1177//      Then, the simpified model is created and the decimation
1178//      information is returned.
1179//-------------------------------------------------------------------------
1180MeshSimplificationSequence *SimplificationMethod::Decimate(     float lod,
1181                                                                                                                                                                                                                                                int simpliftype,
1182                                                                                                                                                                                                                                                TIPOFUNC upb)
1183{
1184        bool                                                                                            shared_vertex;
1185        unsigned        int                                                             vertex_count;
1186        std::map<int,int>::iterator     findit;
1187        //      Initialize      vertex count.
1188        vertex_count    =       0;
1189
1190        //      Initialize shared vertex buffer flag.
1191        shared_vertex   =       false;
1192
1193        //      Determines if the mesh have shared vertex buffer.
1194        for (int i = 0; i < mInitialMesh->mSubMeshCount;        i++)
1195        {
1196                if (mInitialMesh->mSubMesh[i].mSharedVertexBuffer)
1197                {
1198                        shared_vertex   =       true;
1199                        break;
1200                }
1201        }
1202
1203        simplifmethod_init();
1204
1205        if (simpliftype == 0)
1206        {
1207                //      Percentage option.
1208                simplifmethod_run((int)(number_of_triangles*lod),upb);
1209        }
1210        else
1211        {
1212                //      Number of vertices option.
1213                simplifmethod_runv((int)lod,upb);
1214        }
1215
1216        MAPAINDIND *unique_verts_inds_by_geo =
1217                new MAPAINDIND[mInitialMesh->mSubMeshCount];
1218
1219        MAPAINDIND      shared_vertex_map;
1220
1221        REPINDLIST *ver_inds_rep_by_geo = new REPINDLIST[mInitialMesh->mSubMeshCount];
1222
1223        //      Index counter by submesh.
1224        int *inextvert = new int[mInitialMesh->mSubMeshCount];
1225
1226        for (unsigned int       i = 0;  i < mInitialMesh->mSubMeshCount;        i++)
1227        {
1228                inextvert[i] = 0;
1229        }
1230
1231        //      Construct the model.
1232        std::cout << "M0.faceCount(): " << M0.faceCount() << std::endl;
1233
1234        //      For each face.
1235        for (int        i = 0;  i < M0.faceCount();     i++)
1236        {
1237                if (M0.face(i)->isValid())
1238                {
1239                        simplif::Face *auxface  =       M0.face(i);
1240
1241                        //      Determine to which submesh pertains the triangle.
1242                        int igeo = auxface->igeo;
1243
1244                        //      For each index of the face.
1245                        for (size_t     j = 0; j < 3; j++)
1246                        {
1247                                if (shared_vertex)
1248                                {
1249                                        //      Insert to each submesh its triangles.
1250                                        findit =        shared_vertex_map.find(auxface->vertex(j)->vID);
1251
1252                                        if (findit == shared_vertex_map.end())
1253                                        {
1254                                                //      If it is not added... add and map it.
1255                                                shared_vertex_map[auxface->vertex(j)->vID] =    vertex_count;
1256
1257                                                vertex_count++;
1258                                        }
1259                                }
1260                                else
1261                                {
1262                                        //      Insert to each submesh its triangles.
1263                                        findit =        unique_verts_inds_by_geo[igeo].
1264                                                find(auxface->vertex(j)->vID);
1265
1266                                        if (findit == unique_verts_inds_by_geo[igeo].end())
1267                                        {
1268                                                //      If it is not added... add and map it.
1269                                                unique_verts_inds_by_geo[igeo][auxface->vertex(j)->vID] =
1270                                                        inextvert[igeo];
1271
1272                                                inextvert[igeo]++;
1273                                        }
1274                                }
1275
1276                                //      Total number of indices by submesh.
1277                                ver_inds_rep_by_geo[igeo].push_back(auxface->vertex(j)->vID);
1278                        }
1279                }
1280        }
1281
1282        //      Output simplified mesh.
1283        mGeoMesh                                                                =       new Mesh();
1284        mGeoMesh->mVertexBuffer =       new     VertexBuffer();
1285
1286        mGeoMesh->mSubMeshCount = mInitialMesh->mSubMeshCount;
1287
1288        //      Memory allocation for the submeshes.
1289        mGeoMesh->mSubMesh = new SubMesh[mInitialMesh->mSubMeshCount];
1290
1291        //      Fill up bounding box settings.
1292        mGeoMesh->mMeshBounds.maxX                                      =       mInitialMesh->mMeshBounds.maxX;
1293        mGeoMesh->mMeshBounds.maxY                                      =       mInitialMesh->mMeshBounds.maxY;
1294        mGeoMesh->mMeshBounds.maxZ                                      =       mInitialMesh->mMeshBounds.maxZ;
1295        mGeoMesh->mMeshBounds.minX                                      =       mInitialMesh->mMeshBounds.minX;
1296        mGeoMesh->mMeshBounds.minY                                      =       mInitialMesh->mMeshBounds.minY;
1297        mGeoMesh->mMeshBounds.minZ                                      =       mInitialMesh->mMeshBounds.minZ;
1298        mGeoMesh->mMeshBounds.radius                            =       mInitialMesh->mMeshBounds.radius;
1299        mGeoMesh->mMeshBounds.scaleFactor               =       mInitialMesh->mMeshBounds.scaleFactor;
1300
1301        //      Copy skeleton name.
1302        if (mInitialMesh->hasSkeleton)
1303        {
1304                mGeoMesh->hasSkeleton   =       true;
1305
1306                strcpy(mGeoMesh->mSkeletonName,mInitialMesh->mSkeletonName);
1307        }
1308
1309        //      If the mesh has shared vertex.
1310        if (shared_vertex)
1311        {
1312                fillUpSharedVertices(shared_vertex_map,ver_inds_rep_by_geo);
1313        }
1314        else
1315        {
1316                fillUpVertices(unique_verts_inds_by_geo,ver_inds_rep_by_geo);
1317        }
1318
1319        //------------------------//
1320        //      Bones reassignment.             //
1321        //------------------------//
1322        VertexBoneAssignment    bone;
1323        bool                                                                    vertex_found;
1324        MAPAINDIND::iterator    it;
1325
1326        addNewBoneAssignments();
1327
1328        //      For each bone assignment.
1329        for (unsigned int i = 0; i < mInitialMesh->mBones.size(); i++)
1330        {
1331                bone.vertexIndex        =       mInitialMesh->mBones[i].vertexIndex;
1332                bone.boneIndex          =       mInitialMesh->mBones[i].boneIndex;
1333                bone.weight                             =       mInitialMesh->mBones[i].weight;
1334
1335                vertex_found    =       false;
1336
1337                //      If the vertex is found in the simplification model.
1338                if ((it = shared_vertex_map.find(bone.vertexIndex))
1339                                !=
1340                                shared_vertex_map.end())
1341                {
1342                        bone.vertexIndex        =       (*it).second;
1343
1344                        mGeoMesh->mBones.push_back(bone);
1345                        vertex_found    =       true;
1346                }
1347        }
1348        //------------------------------------------------------------//
1349
1350        delete[] unique_verts_inds_by_geo;
1351        delete[] ver_inds_rep_by_geo;
1352        delete[] inextvert;
1353
1354        //      Store the simplification steps in MeshSimplificationSequence.
1355        int     acum    =       0;
1356
1357        for (size_t i   =       0; i < mInitialMesh->mSubMeshCount; i++)
1358        {
1359                if (mInitialMesh->mSubMesh[i].mSharedVertexBuffer)
1360                {
1361                        first_index_submesh[i]  =       0;
1362                }
1363                else
1364                {
1365                        first_index_submesh[i]  =       acum;
1366                }
1367
1368                acum    +=      (int)mInitialMesh->mSubMesh[i].mVertexBuffer->mVertexCount;
1369        }
1370
1371        vector<int>     v0;
1372        vector<int>     v1;
1373        vector<int>     submesh0;
1374        vector<int>     submesh1;
1375
1376        return msimpseq;
1377}
1378
1379//-------------------------------------------------------------------------
1380//      Add bone assignments for new bones.
1381//-------------------------------------------------------------------------
1382void    SimplificationMethod::addNewBoneAssignments()
1383{
1384        size_t  vertex_id;
1385        size_t  bones_count;
1386        VertexBoneAssignment bone;
1387        vector<VertexBoneAssignment>::iterator  it;
1388
1389        //      Copy new vertices.
1390        for (unsigned   int     i       =       0;      i < msimpseq->mNewVertices.size();      i++)
1391        {
1392                vertex_id       =       msimpseq->mNewVertices[i].id;
1393
1394                //      Initialize number of bones.
1395                bones_count     =       mInitialMesh->mBones.size();
1396
1397                // check if my twin-vertex-bone has a bone assignment
1398                // we check only the GeoMesh bones because the lodstrips
1399                // only works for sharedvertex bones.
1400                for (int  j = 0; j < bones_count; j++)
1401                {
1402                        it      =       mInitialMesh->mBones.begin() + j;
1403
1404                        if (it->vertexIndex == msimpseq->mNewVertices[i].bonefrom)
1405                        {
1406                                bone.vertexIndex        = vertex_id;
1407                                bone.boneIndex          = it->boneIndex;
1408                                bone.weight                             = it->weight;
1409
1410                                mInitialMesh->mBones.push_back(bone);
1411                                bones_count++;
1412                        }
1413                }
1414        }
1415}
1416
1417//-------------------------------------------------------------------------
1418//      Erase submeshes that have not indices.
1419//-------------------------------------------------------------------------
1420void    SimplificationMethod::eraseVoidSubMeshes(Mesh   *geoMesh)
1421{
1422        SubMesh *geosubmesh;
1423        size_t  valid_submesh_count;
1424        size_t  submesh;
1425
1426        valid_submesh_count     =       0;
1427
1428        //      For each submesh.
1429        for     (size_t i       =       0; i < geoMesh->mSubMeshCount;  i++)
1430        {
1431                //      Debug.
1432                cout    <<      "Indices of submesh "
1433                                        <<      i
1434                                        <<      ": "
1435                                        <<      geoMesh->mSubMesh[i].mIndexCount
1436                                        <<      endl;
1437
1438                if ((geoMesh->mSubMesh[i].mIndexCount > 0)
1439                                ||
1440                                (indexMeshLeaves == i))
1441                {
1442                        valid_submesh_count++;
1443                }
1444        }
1445
1446        //      Reassign submesh count.
1447        geoMesh->mSubMeshCount  =       valid_submesh_count;
1448
1449        //      Reserve memory for valid submeshes.
1450        geosubmesh      =       new     SubMesh[valid_submesh_count];
1451
1452        submesh =       0;
1453       
1454        //      For each submesh.
1455        for (size_t i = 0; i < geoMesh->mSubMeshCount; i++)
1456        {
1457                //      If leaves submesh is found.
1458                if (indexMeshLeaves == i)
1459                {
1460                        geosubmesh[i].mStripCount       =       0;
1461                        geosubmesh[i].mStrip                    =       NULL;
1462
1463                        geosubmesh[i].mSharedVertexBuffer       =       false;
1464
1465                        strcpy( geosubmesh[i].mMaterialName,
1466                                        mInitialMesh->mSubMesh[i].mMaterialName);
1467
1468                        //      Copy submesh bones.
1469                        if (!mInitialMesh->mSubMesh[i].mBones.empty())
1470                        {
1471                                for (   size_t j = 0;
1472                                                j < mInitialMesh->mSubMesh[i].mBones.size();
1473                                                j++)
1474                                {
1475                                        geosubmesh[i].mBones.push_back(mInitialMesh->
1476                                                        mSubMesh[i].mBones[j]);
1477                                }
1478                        }
1479
1480                        //      Leaves mesh.
1481                        geosubmesh[i].mIndexCount       =       
1482                                mInitialMesh->mSubMesh[i].mIndexCount;
1483
1484                        geosubmesh[i].mIndex    =
1485                                new Geometry::Index[geosubmesh[i].mIndexCount];
1486
1487                        memcpy( geosubmesh[i].mIndex,
1488                                        mInitialMesh->mSubMesh[i].mIndex,
1489                                        mInitialMesh->mSubMesh[i].mIndexCount * sizeof(Index));
1490
1491                        //      Copy the leaves submesh vertices.
1492                        geosubmesh[i].mVertexBuffer     =
1493                                mInitialMesh->mSubMesh[i].mVertexBuffer->Clone();
1494
1495                        //      Next valid submesh.
1496                        submesh++;
1497                }
1498                else if (geoMesh->mSubMesh[i].mIndexCount > 0)
1499                {
1500                        geosubmesh[submesh].mSharedVertexBuffer =
1501                                                                        geoMesh->mSubMesh[i].mSharedVertexBuffer;
1502
1503                        geosubmesh[submesh].mVertexBuffer       =       geoMesh->mVertexBuffer;
1504
1505                        geosubmesh[submesh].mType                               =       geoMesh->mSubMesh[i].mType;
1506
1507                        geosubmesh[submesh].mStripCount =       geoMesh->mSubMesh[i].mStripCount;
1508
1509                        geosubmesh[submesh].mIndexCount =       geoMesh->mSubMesh[i].mIndexCount;
1510
1511                        //      Reserve memory for indices.
1512                        geosubmesh[submesh].mIndex      =
1513                                                                                                        new Index[geosubmesh[submesh].mIndexCount];
1514
1515                        //      Copy indices.
1516                        memcpy( geosubmesh[submesh].mIndex,
1517                                        geoMesh->mSubMesh[i].mIndex,
1518                                        geoMesh->mSubMesh[i].mIndexCount * sizeof(Index));
1519
1520                        //      Reserve memory for array of strips.
1521                        geosubmesh[submesh].mStrip      =
1522                                new Index*[geoMesh->mSubMesh[submesh].mStripCount];
1523
1524                        //      Copy strip list of the submesh.
1525                        for (size_t j = 0; j < geoMesh->mSubMesh[i].mStripCount; j++)
1526                        {
1527                                geosubmesh[submesh].mStrip[j]   =       geoMesh->mSubMesh[i].mStrip[j];
1528                        }
1529
1530                        strcpy( geosubmesh[submesh].mMaterialName,
1531                                        geoMesh->mSubMesh[i].mMaterialName);
1532
1533                        for (size_t     j       =       0;      j < geoMesh->mSubMesh[i].mBones.size(); j++)
1534                        {
1535                                geosubmesh[submesh].mBones
1536                                        .push_back(geoMesh->mSubMesh[i].mBones[j]);
1537                        }
1538
1539                        //      Next valid submesh.
1540                        submesh++;
1541                }
1542        }
1543
1544        //      Delete submeshes.
1545        delete  []geoMesh->mSubMesh;
1546
1547        geoMesh->mSubMesh       =       geosubmesh;
1548}
1549
1550//-------------------------------------------------------------------------
1551//      Fill up vertices.
1552//-------------------------------------------------------------------------
1553void    SimplificationMethod::fillUpVertices(
1554                                                                                                                        MAPAINDIND      *unique_verts_inds_by_geo,
1555                                                                                                                        REPINDLIST      *ver_inds_rep_by_geo)
1556{
1557        bool copiedShared = false;
1558
1559        //      For each submesh.
1560        for (size_t     i = 0;  i < mInitialMesh->mSubMeshCount;        i++)
1561        {
1562                mGeoMesh->mSubMesh[i].mStripCount       =       0;
1563                mGeoMesh->mSubMesh[i].mStrip                    =       NULL;
1564
1565                mGeoMesh->
1566                        mSubMesh[i].mSharedVertexBuffer =       false;
1567
1568                strcpy( mGeoMesh->mSubMesh[i].mMaterialName,
1569                                mInitialMesh->mSubMesh[i].mMaterialName);
1570
1571                //      Copy submesh bones.
1572                if (!mInitialMesh->mSubMesh[i].mBones.empty())
1573                {
1574                        for (   unsigned int j = 0;
1575                                                j < mInitialMesh->mSubMesh[i].mBones.size();
1576                                                j++)
1577                        {
1578                                mGeoMesh->mSubMesh[i].mBones.push_back(mInitialMesh->
1579                                                mSubMesh[i].mBones[j]);
1580                        }
1581                }
1582
1583                if (i != indexMeshLeaves)
1584                {
1585                        //      Indices vectors.
1586                        mGeoMesh->mSubMesh[i].mIndexCount       =       ver_inds_rep_by_geo[i].size();
1587
1588                        mGeoMesh->mSubMesh[i].mIndex                    =       new Geometry::Index[mGeoMesh->
1589                                mSubMesh[i].mIndexCount];
1590
1591                        //      Store the indices.
1592                        for (unsigned int       j = 0;  j < mGeoMesh->mSubMesh[i].mIndexCount;  j++)
1593                        {
1594                                //      Obtain the indices that point at VertexBuffer.
1595                                mGeoMesh->mSubMesh[i].mIndex[j] =
1596                                        unique_verts_inds_by_geo[i][ver_inds_rep_by_geo[i][j]];
1597                        }
1598
1599                        //      Copy the vertices.
1600                        if (mGeoMesh->mSubMesh[i].mSharedVertexBuffer)
1601                        {
1602                                //      Shared vertices.
1603                                if (!copiedShared)
1604                                {
1605                                        mGeoMesh->mVertexBuffer = new VertexBuffer();
1606                                        copiedShared                                            = true;
1607                                }
1608
1609                                mGeoMesh->mSubMesh[i].mVertexBuffer = mGeoMesh->mVertexBuffer;
1610                        }
1611                        else
1612                        {
1613                                //      There's no shared vertices.
1614                                mGeoMesh->mSubMesh[i].mVertexBuffer     =       new VertexBuffer();
1615                        }
1616
1617                        mGeoMesh->mSubMesh[i].mVertexBuffer->mVertexCount       =
1618                                unique_verts_inds_by_geo[i].size();
1619
1620                        mGeoMesh->mSubMesh[i].mVertexBuffer->mVertexInfo        =
1621                                mInitialMesh->mSubMesh[i].mVertexBuffer->mVertexInfo;
1622
1623                        //      Allocate memory for position, normal and texutre coordinates.
1624                        mGeoMesh->mSubMesh[i].mVertexBuffer->mPosition  =
1625                                new Vector3[mGeoMesh->mSubMesh[i].mVertexBuffer->mVertexCount];
1626
1627                        mGeoMesh->mSubMesh[i].mVertexBuffer->mNormal            =
1628                                new Vector3[mGeoMesh->mSubMesh[i].mVertexBuffer->mVertexCount];
1629
1630                        mGeoMesh->mSubMesh[i].mVertexBuffer->mTexCoords =
1631                                new Vector2[mGeoMesh->mSubMesh[i].mVertexBuffer->mVertexCount];
1632
1633                        for (MAPAINDIND::iterator mapit = unique_verts_inds_by_geo[i].begin();
1634                                                mapit != unique_verts_inds_by_geo[i].end();
1635                                                mapit++)
1636                        {
1637                                //      Key and value.
1638                                int isrc = mapit->first;
1639                                int idst = mapit->second;
1640
1641                                //      Vertex coordinate.
1642                                //      Construction of the submeshes.
1643                                Vector3 v3(     (Real)M0.vertex(isrc)->operator [](0),
1644                                                (Real)M0.vertex(isrc)->operator [](1),
1645                                                (Real)M0.vertex(isrc)->operator [](2));
1646
1647                                mGeoMesh->mSubMesh[i].mVertexBuffer->mPosition[idst]    =       v3;
1648
1649                                //      Normal coordinates.
1650                                Vector3 v3n(    (Real)M0.normal(isrc)(0),
1651                                                (Real)M0.normal(isrc)(1),
1652                                                (Real)M0.normal(isrc)(2));
1653
1654                                mGeoMesh->mSubMesh[i].mVertexBuffer->mNormal[idst]      =       v3n;
1655
1656                                //      Texture coordinates.
1657                                Vector2 v2(     (Real)M0.texcoord(isrc)(0),
1658                                                (Real)M0.texcoord(isrc)(1));
1659
1660                                mGeoMesh->mSubMesh[i].mVertexBuffer->mTexCoords[idst]   =       v2;
1661                        }
1662                }
1663                //      Leaves mesh.
1664                else
1665                {
1666                        mGeoMesh->mSubMesh[i].mIndexCount       =       
1667                                                                                                                mInitialMesh->mSubMesh[i].mIndexCount;
1668
1669                        mGeoMesh->mSubMesh[i].mIndex    =               
1670                                                new Geometry::Index[mGeoMesh->mSubMesh[i].mIndexCount];
1671
1672                        //      Copy the leaves submesh indexes.
1673                        for (   unsigned int    j       =       0;
1674                                                j < mGeoMesh->mSubMesh[i].mIndexCount;
1675                                                j++)
1676                        {
1677                                mGeoMesh->mSubMesh[i].mIndex[j] =       mInitialMesh->mSubMesh[i].mIndex[j];
1678                        }
1679
1680                        //      Copy the leaves submesh vertices.
1681                        mGeoMesh->mSubMesh[i].mVertexBuffer     =       new VertexBuffer();
1682
1683                        mGeoMesh->mSubMesh[i].mVertexBuffer->mVertexCount       =
1684                                mInitialMesh->mSubMesh[i].mVertexBuffer->mVertexCount;
1685
1686                        mGeoMesh->mSubMesh[i].mVertexBuffer->mVertexInfo        =
1687                                mInitialMesh->mSubMesh[i].mVertexBuffer->mVertexInfo;
1688
1689                        //      Allocate memory for position, normal and texture coordinates.
1690                        mGeoMesh->mSubMesh[i].mVertexBuffer->mPosition  =
1691                                new Vector3[mGeoMesh->mSubMesh[i].mVertexBuffer->mVertexCount];
1692
1693                        mGeoMesh->mSubMesh[i].mVertexBuffer->mNormal    =
1694                                new Vector3[mGeoMesh->mSubMesh[i].mVertexBuffer->mVertexCount];
1695
1696                        mGeoMesh->mSubMesh[i].mVertexBuffer->mTexCoords =
1697                                new Vector2[mGeoMesh->mSubMesh[i].mVertexBuffer->mVertexCount];
1698
1699                        for (   unsigned int j = 0;
1700                                        j < mGeoMesh->mSubMesh[i].mVertexBuffer->mVertexCount;
1701                                        j++)
1702                        {
1703                                //      Position.
1704                                mGeoMesh->mSubMesh[i].mVertexBuffer->mPosition[j].x     =
1705                                        mInitialMesh->mSubMesh[i].mVertexBuffer->mPosition[j].x;
1706
1707                                mGeoMesh->mSubMesh[i].mVertexBuffer->mPosition[j].y     =
1708                                        mInitialMesh->mSubMesh[i].mVertexBuffer->mPosition[j].y;
1709
1710                                mGeoMesh->mSubMesh[i].mVertexBuffer->mPosition[j].z     =
1711                                        mInitialMesh->mSubMesh[i].mVertexBuffer->mPosition[j].z;
1712
1713                                //      Normals.
1714                                mGeoMesh->mSubMesh[i].mVertexBuffer->mNormal[j].x       =
1715                                        mInitialMesh->mSubMesh[i].mVertexBuffer->mNormal[j].x;
1716
1717                                mGeoMesh->mSubMesh[i].mVertexBuffer->mNormal[j].y       =
1718                                        mInitialMesh->mSubMesh[i].mVertexBuffer->mNormal[j].y;
1719
1720                                mGeoMesh->mSubMesh[i].mVertexBuffer->mNormal[j].z       =
1721                                        mInitialMesh->mSubMesh[i].mVertexBuffer->mNormal[j].z;
1722
1723                                //      Textures.
1724                                mGeoMesh->mSubMesh[i].mVertexBuffer->mTexCoords[j].x    =
1725                                        mInitialMesh->mSubMesh[i].mVertexBuffer->mTexCoords[j].x;
1726
1727                                mGeoMesh->mSubMesh[i].mVertexBuffer->mTexCoords[j].y    =
1728                                        mInitialMesh->mSubMesh[i].mVertexBuffer->mTexCoords[j].y;
1729                        }
1730                }
1731        }
1732}
1733
1734//-------------------------------------------------------------------------
1735//      Fill up shared vertices.
1736//-------------------------------------------------------------------------
1737void    SimplificationMethod::fillUpSharedVertices(
1738                                                                                                                MAPAINDIND      &shared_vertex_map,
1739                                                                                                                REPINDLIST      *ver_inds_rep_by_geo)
1740{
1741        mGeoMesh->mVertexBuffer = new VertexBuffer();
1742
1743        //      For each submesh.
1744        for (size_t     i = 0;  i < mInitialMesh->mSubMeshCount;        i++)
1745        {
1746                mGeoMesh->
1747                        mSubMesh[i].mSharedVertexBuffer =       mInitialMesh->
1748                                                                                                                                                                        mSubMesh[i].mSharedVertexBuffer;
1749
1750                //      Reassign submesh vertex buffers.
1751                mGeoMesh->mSubMesh[i].mVertexBuffer = mGeoMesh->mVertexBuffer;
1752
1753                mGeoMesh->mSubMesh[i].mStripCount       =       0;
1754                mGeoMesh->mSubMesh[i].mStrip                    =       NULL;
1755
1756                strcpy( mGeoMesh->mSubMesh[i].mMaterialName,
1757                                mInitialMesh->mSubMesh[i].mMaterialName);
1758
1759                //      Indices vectors.
1760                mGeoMesh->mSubMesh[i].mIndexCount       =       ver_inds_rep_by_geo[i].size();
1761
1762                mGeoMesh->mSubMesh[i].mIndex                    =       new Geometry::Index[mGeoMesh->
1763                                                                                                                                                                                                mSubMesh[i].mIndexCount];
1764
1765                //      Store the indices.
1766                for (unsigned int       j = 0;  j < mGeoMesh->mSubMesh[i].mIndexCount;  j++)
1767                {
1768                        //      Obtain the indices that point at VertexBuffer.
1769                        mGeoMesh->mSubMesh[i].mIndex[j] =
1770                                shared_vertex_map[ver_inds_rep_by_geo[i][j]];
1771                }
1772        }
1773
1774        mGeoMesh->mVertexBuffer->mVertexCount   =       shared_vertex_map.size();
1775
1776        mGeoMesh->mVertexBuffer->mVertexInfo    =       
1777                                                                                                                        mInitialMesh->mVertexBuffer->mVertexInfo;
1778
1779        //      Allocate memory for position, normal and texutre coordinates.
1780        mGeoMesh->mVertexBuffer->mPosition      =
1781                new Vector3[mGeoMesh->mVertexBuffer->mVertexCount];
1782
1783        mGeoMesh->mVertexBuffer->mNormal                =
1784                new Vector3[mGeoMesh->mVertexBuffer->mVertexCount];
1785
1786        mGeoMesh->mVertexBuffer->mTexCoords     =
1787                new Vector2[mGeoMesh->mVertexBuffer->mVertexCount];
1788
1789        for (MAPAINDIND::iterator mapit = shared_vertex_map.begin();
1790                        mapit != shared_vertex_map.end();
1791                        mapit++)
1792        {
1793                //      Key and value.
1794                int isrc = mapit->first;
1795                int idst = mapit->second;
1796
1797                //      Vertex coordinate.
1798                //      Construction of the submeshes.
1799                Vector3 v3(     (Real)M0.vertex(isrc)->operator [](0),
1800                                                                (Real)M0.vertex(isrc)->operator [](1),
1801                                                                (Real)M0.vertex(isrc)->operator [](2));
1802
1803                mGeoMesh->mVertexBuffer->mPosition[idst]        =       v3;
1804
1805                //      Normal coordinates.
1806                Vector3 v3n((Real)M0.normal(isrc)(0),
1807                                                                (Real)M0.normal(isrc)(1),
1808                                                                (Real)M0.normal(isrc)(2));
1809
1810                mGeoMesh->mVertexBuffer->mNormal[idst]  =       v3n;
1811
1812                //      Texture coordinates.
1813                Vector2 v2(     (Real)M0.texcoord(isrc)(0),
1814                                                                (Real)M0.texcoord(isrc)(1));
1815
1816                mGeoMesh->mVertexBuffer->mTexCoords[idst]       =       v2;
1817        }
1818}
1819
1820//-------------------------------------------------------------------------
1821//      Set submesh leaves.
1822//-------------------------------------------------------------------------
1823void SimplificationMethod::setMeshLeaves(int meshLeaves)
1824{
1825        indexMeshLeaves =       meshLeaves;
1826}
1827
1828//      Gets mesh simplified.
1829Mesh    *       SimplificationMethod::GetMesh()
1830{
1831        //      Delete void submeshes.
1832        eraseVoidSubMeshes(mGeoMesh);
1833
1834        return  mGeoMesh;
1835}
1836
Note: See TracBrowser for help on using the repository browser.