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

Revision 1599, 37.3 KB checked in by gumbau, 18 years ago (diff)

Fixed bug in new vertices added during the simplification process.

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