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

Revision 1526, 37.2 KB checked in by gumbau, 18 years ago (diff)

Updated modules to the new interface and the new simplification algorithm improvements.

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