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

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

Fixed simplification bug when simplifying to extremely a low factor

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                        heap->kill(i);
687
688                        //      Copy candidate.
689                        pair->candidate =       candidate;
690
691                        //      Contract twin pair.
692                        do_contract(m, pair);
693                        i--;
694                        M0.validVertCount--;
695                }
696        }
697}
698
699//---------------------------------------------------------------------------
700//---------------------------------------------------------------------------
701simplif::real SimplificationMethod::decimate_error(simplif::Vertex *v)
702{
703        simplif::vert_info& info = vertex_info(v);
704
705        simplif::real err = simplif::quadrix_evaluate_vertex(*v, info.Q);
706
707    if( simplif::will_weight_by_area )
708                {
709                        err /= info.norm;
710                }
711
712    return err;
713}
714
715//---------------------------------------------------------------------------
716//      Extract the minimum cost of the the valid nodes (not simplified)
717//---------------------------------------------------------------------------
718simplif::real SimplificationMethod::decimate_min_error()
719{
720        simplif::heap_node *top;
721        simplif::pair_info *pair;
722
723        for(;;)
724        {
725                top = heap->top();
726               
727                if( !top )
728                {
729                        return -1.0;
730                }
731
732                pair = (simplif::pair_info *)top->obj;
733
734                if( pair->isValid() )
735                {
736                        break;
737                }
738
739                top = heap->extract();
740                delete_pair(pair);
741        }
742
743        return pair->cost;
744}
745
746//---------------------------------------------------------------------------
747//      Returns the maximum error by vertex
748//---------------------------------------------------------------------------
749simplif::real SimplificationMethod::decimate_max_error(simplif::Model& m)
750{
751        simplif::real max_err = 0;
752
753        for(int i=0; i<m.vertCount(); i++)
754                if( m.vertex(i)->isValid() )
755                {
756                        max_err = MAX(max_err, decimate_error(m.vertex(i)));
757                }
758
759        return max_err;
760}
761
762//---------------------------------------------------------------------------
763//      Initializations
764//---------------------------------------------------------------------------
765void SimplificationMethod::decimate_init(simplif::Model& m, simplif::real limit)
766{
767        int i,j;
768
769        //      Reserve memory for vert_info array.
770        vinfo.init(m.vertCount()*2);
771
772        if (simplif::will_use_vertex_constraint)
773        {
774                //      For each vertex, calculate contraints.
775                for     (i      =       0;      i < m.vertCount();      i++)
776                {
777                        simplif::Vertex *v      =       m.vertex(i);
778                       
779                        if (v->isValid())
780                        {
781                                vertex_info(v).Q = simplif::quadrix_vertex_constraint(*v);
782                        }
783                }
784        }
785
786        //      Sets the fill value of the vinfo buffer.
787        //vinfo.setFill(m.vertCount());
788
789        //      For each face, recalculate constraints.
790        for (i  =       0;      i < m.faceCount();      i++)
791        {
792                if (m.face(i)->isValid())
793                {
794                        if (simplif::will_use_plane_constraint)
795                        {
796                                simplif::Mat4 Q = simplif::quadrix_plane_constraint(*m.face(i));
797                                simplif::real norm = 0.0;
798
799                                if (simplif::will_weight_by_area)
800                                {
801                                        norm    =               m.face(i)->area();
802                                        Q                       *=      norm;
803                                }
804
805                                for (j  =       0;      j < 3;  j++)
806                                {
807                                        vertex_info(m.face(i)->vertex(j)).Q                     +=      Q;
808                                        vertex_info(m.face(i)->vertex(j)).norm  +=      norm;
809                                }
810                        }
811                }
812        }
813
814        if (simplif::will_constrain_boundaries)
815        {
816                //      For each edge, recalculate constraints.
817                for (i  =       0;      i < m.edgeCount();      i++)
818                {
819                        if (m.edge(i)->isValid() && simplif::check_for_discontinuity(m.edge(i)))
820                        {
821                                simplif::Mat4 B = simplif::quadrix_discontinuity_constraint(m.edge(i));
822                                simplif::real norm = 0.0;
823
824                                if (simplif::will_weight_by_area)
825                                {
826                                        norm    =               simplif::norm2(*m.edge(i)->org() - *m.edge(i)->dest());
827                                        B                       *=      norm;
828                                }
829
830                                B *= simplif::boundary_constraint_weight;
831                                vertex_info(m.edge(i)->org()).Q += B;
832                                vertex_info(m.edge(i)->org()).norm += norm;
833                                vertex_info(m.edge(i)->dest()).Q += B;
834                                vertex_info(m.edge(i)->dest()).norm += norm;
835                        }
836                }
837        }
838
839        //      Create heap.
840        heap = new simplif::Heap(m.validEdgeCount);
841
842        int pair_count = 0;
843
844        //      For each edge, add pairs to heap.
845        for (i  =       0;      i < m.edgeCount();      i++)
846        {
847                if (m.edge(i)->isValid())
848                {
849                        simplif::pair_info *pair = new_pair(m.edge(i)->org(), m.edge(i)->dest());
850                        //pointers_to_remove.push_back(pair);
851                        compute_pair_info(pair);
852                        pair_count++;
853                }
854        }
855
856        if (limit < 0)
857        {
858                limit   =       m.bounds.radius * 0.05;
859        }
860       
861        proximity_limit =       limit * limit;
862       
863        if (proximity_limit > 0)
864        {
865                simplif::ProxGrid grid(m.bounds.min, m.bounds.max, limit);
866               
867                //      Add points to grid.
868                for (i  =       0;      i < m.vertCount();      i++)
869                {
870                        grid.addPoint(m.vertex(i));
871                }
872
873                simplif::buffer<simplif::Vec3 *> nearby(32);
874               
875                //      For each vertex.
876                for (i  =       0;      i < m.vertCount();      i++)
877                {
878                        nearby.reset();
879                        grid.proximalPoints(m.vertex(i), nearby);
880
881                        for (j  =       0;      j < nearby.length();    j++)
882                        {
883                                simplif::Vertex *v1 = m.vertex(i);
884                                simplif::Vertex *v2 = (simplif::Vertex *)nearby(j);
885
886                                if (v1->isValid() && v2->isValid())
887                                {
888#ifdef SAFETY
889                                        assert(pair_is_valid(v1,v2));
890#endif
891                                        if (!check_for_pair(v1,v2))
892                                        {
893                                                simplif::pair_info *pair = new_pair(v1,v2);
894                                                compute_pair_info(pair);
895                                                pair_count++;
896                                        }
897                                }
898                        }
899                }
900        }
901}
902
903//---------------------------------------------------------------------------
904//      Initilizations
905//---------------------------------------------------------------------------
906void SimplificationMethod::simplifmethod_init(void)
907{
908        // Change mesh structure.
909        generateSimplifModel();
910               
911        M0.bounds.complete();
912
913        initialVertCount = M0.vertCount();
914        initialEdgeCount = M0.edgeCount();
915        initialFaceCount = M0.faceCount();
916
917        // Get rid of degenerate faces.
918        for (int        i       =       0;      i < M0.faceCount();     i++)
919        {
920                if (!M0.face(i)->plane().isValid())
921                {
922                        M0.killFace(M0.face(i));
923                }
924        }
925
926        M0.removeDegeneracy(M0.allFaces());
927
928        // Get rid of unused vertices.
929        for (int        i       =       0;      i < M0.vertCount();     i++)
930        {
931                if (M0.vertex(i)->edgeUses().length() == 0)
932                {
933                        M0.vertex(i)->kill();
934                }
935        }
936}
937
938//---------------------------------------------------------------------------
939//      Do the contractions till the required LOD (percentage option)
940//---------------------------------------------------------------------------
941void SimplificationMethod::simplifmethod_run(int finalfaces,TIPOFUNC upb)
942{
943        decimate_init(M0, simplif::pair_selection_tolerance);
944        unsigned        int     contador        =       0;
945        float                                   percent; // simplification percentage.
946
947        percent =       (float)(2.0 * 100.0) / (M0.validFaceCount - finalfaces);
948
949        //      Update progress bar.
950        if (upb)
951        {
952                upb(0.0);
953        }
954
955        /*
956        for (   std::vector<MeshSimplificationSequence::Step>::iterator
957                                it      =       decim_data.begin();
958                                it != decim_data.end();
959                                it++)
960        {
961                it->mModfaces.clear();
962        }
963       
964        decim_data.clear();
965        */
966
967        //      Debug.
968        cout    <<      "M0.validFaceCount: "   <<      M0.validFaceCount       <<      endl;
969        cout    <<      "finalfaces: "                          <<      finalfaces                              <<      endl;
970       
971        while ( M0.validFaceCount > finalfaces/*simplif::face_target*/
972                                        && M0.validFaceCount > 1
973                                        && decimate_min_error() < simplif::error_tolerance )
974        {
975                decimate_contract(M0);
976
977                //      Update progress bar.
978                if (upb)
979                {
980                        upb(percent);
981                }
982        }
983
984        //      Update progress bar.
985        if (upb)
986        {
987                upb(100.0);
988        }
989}
990
991//---------------------------------------------------------------------------
992//      Do the contractions till the required LOD (number of vertices option)
993//---------------------------------------------------------------------------
994void SimplificationMethod::simplifmethod_runv(int numvertices,TIPOFUNC upb)
995{
996        decimate_init(M0, simplif::pair_selection_tolerance);
997        unsigned        int     contador        =       0;
998        int                                             previousValidVertCount;
999        float                                   percent; // Simplification percentage.
1000
1001        previousValidVertCount  =       0;
1002
1003        percent =       (float)(2.0 * 100.0)
1004                                                /
1005                                                (float)((M0.validFaceCount - numvertices / 3.0));
1006
1007        //      Update progress bar.
1008        if (upb)
1009        {
1010                upb(0.0);
1011        }
1012
1013        /*
1014        for (   std::vector<MeshSimplificationSequence::Step>::iterator
1015                                it      =       decim_data.begin();
1016                                it != decim_data.end();
1017                                it++)
1018        {
1019                it->mModfaces.clear();
1020        }
1021       
1022        decim_data.clear();
1023        */
1024
1025        //      Debug.
1026        cout    <<      "M0.validVertCount:     "       <<      M0.validVertCount       <<      endl;
1027        cout    <<      "numvertices:   "       <<      numvertices     <<      endl;
1028
1029        while(  M0.validVertCount > numvertices /*simplif::face_target*/
1030                        &&
1031                        decimate_min_error() < simplif::error_tolerance
1032                        &&
1033                        previousValidVertCount  !=      M0.validVertCount)
1034        {
1035                previousValidVertCount  =       M0.validVertCount;
1036
1037                decimate_contract(M0);
1038
1039                //      Update progress bar.
1040                if (upb)
1041                {
1042                        upb(percent);
1043                }
1044        }
1045
1046        //      Update progress bar.
1047        if (upb)
1048        {
1049                upb(100.0);
1050        }
1051}
1052
1053//---------------------------------------------------------------------------
1054// Class to create a map without repeated vertices
1055//---------------------------------------------------------------------------
1056class _float3_
1057{
1058        public:
1059
1060                float x,y,z;
1061
1062                _float3_(float x=0.0f, float y=0.0f, float z=0.0f)
1063                {
1064                        this->x = x; this->y = y; this->z = z;
1065                }
1066
1067                _float3_(const _float3_ &f)
1068                {
1069                        x=f.x; y=f.y; z=f.z;
1070                }
1071
1072                _float3_ & operator=(const _float3_ &f)
1073                {
1074                        x=f.x; y=f.y; z=f.z; return *this;
1075                }
1076
1077                bool operator<(const _float3_ &f) const
1078                {
1079                        if (x<f.x) return true;
1080                        if (x>f.x) return false;
1081                        if (y<f.y) return true;
1082                        if (y>f.y) return false;
1083                        if (z<f.z) return true;
1084                        if (z>f.z) return false;
1085                        return false;
1086                }
1087};
1088
1089//---------------------------------------------------------------------------
1090//      Generate simplification model.
1091//---------------------------------------------------------------------------
1092void    SimplificationMethod::generateSimplifModel(void)
1093{
1094        int     face_index      =       0;
1095
1096        //      For each submesh.
1097        bool added_vertices = false;
1098        for (size_t     i =     0;      i       <       objmesh->mSubMeshCount; i++)
1099        {
1100                //      If is not a tree leaves submesh.
1101                if (i != indexMeshLeaves)
1102                {
1103                        //      For all the vertices of each submesh.
1104                        for (   size_t  j       =       0;
1105                                        j < objmesh->mSubMesh[i].mVertexBuffer->mVertexCount;
1106                                        j++)
1107                        {
1108                                //      If the vertex is not in vertices_map, then is added.
1109                                M0.in_Vertex(simplif::Vec3(
1110                                                        objmesh->mSubMesh[i].mVertexBuffer->mPosition[j].x,
1111                                                        objmesh->mSubMesh[i].mVertexBuffer->mPosition[j].y,
1112                                                        objmesh->mSubMesh[i].mVertexBuffer->mPosition[j].z));
1113
1114                                M0.in_Normal(simplif::Vec3(
1115                                                        objmesh->mSubMesh[i].mVertexBuffer->mNormal[j].x,
1116                                                        objmesh->mSubMesh[i].mVertexBuffer->mNormal[j].y,
1117                                                        objmesh->mSubMesh[i].mVertexBuffer->mNormal[j].z));
1118
1119                                M0.in_TexCoord(simplif::Vec2(
1120                                                        objmesh->mSubMesh[i].mVertexBuffer->mTexCoords[j].x,
1121                                                        objmesh->mSubMesh[i].mVertexBuffer->mTexCoords[j].y));
1122
1123                                added_vertices = true;
1124                        }
1125                }       
1126               
1127                //      If is shared vertex buffer object.
1128                if (objmesh->mSubMesh[i].mSharedVertexBuffer && added_vertices)
1129                {
1130                        printf("Shared break");
1131                        break;
1132                }
1133        }
1134
1135        //      For each submesh.
1136        for (size_t     i = 0;  i < objmesh->mSubMeshCount;     i++)
1137        {
1138                if (i != indexMeshLeaves)
1139                {
1140                        for (Index      j       =       0;      j < objmesh->mSubMesh[i].mIndexCount;   j       +=      3)
1141                        {
1142                                //      +1 is required because the first index in the
1143                                //      simplification method is 1
1144                                //      Index of the vertex in vertices_map.
1145                                Index index0    =               objmesh->mSubMesh[i].mIndex[j];
1146                               
1147                                Index index1    =               objmesh->mSubMesh[i].mIndex[j + 1];
1148                               
1149                                Index index2    =               objmesh->mSubMesh[i].mIndex[j + 2];
1150                               
1151                                //      Create a triangle with its indices in vertices_map.
1152                                face_index      =       M0.miin_Face(
1153                                                index0,
1154                                                index1,
1155                                                index2);
1156
1157                                //      igeo allows to identify the submesh that contains the triangle.
1158                                M0.face(face_index)->igeo       =       (int)i;
1159                        }
1160                }
1161        }
1162        number_of_triangles     =       face_index;
1163}
1164
1165//---------------------------------------------------------------------------
1166//      simplifmethod_init is executed to do some initalizations
1167//      simplifmethod_run is executed to do the decimation
1168//      Then, the simpified model is created and the decimation
1169//      information is returned.
1170//---------------------------------------------------------------------------
1171MeshSimplificationSequence *SimplificationMethod::Decimate(     float lod,
1172                                                                                                                                                                                                                                                int simpliftype,
1173                                                                                                                                                                                                                                                TIPOFUNC upb)
1174{
1175        simplifmethod_init();
1176
1177        if (simpliftype == 0)
1178        {
1179                //      Percentage option.
1180                simplifmethod_run((int)(number_of_triangles*lod),upb);
1181        }
1182        else
1183        {
1184                //      Number of vertices option.
1185                simplifmethod_runv((int)lod,upb);
1186        }
1187
1188        //      Store unique vertices by submesh (without repetitions).
1189        typedef std::map<int,int> MAPAINDIND;
1190
1191        //      Store all the indices by submesh (with repetitions).
1192        typedef std::vector<int> REPINDLIST;
1193
1194        MAPAINDIND *unique_verts_inds_by_geo =
1195                                                                                                                new MAPAINDIND[objmesh->mSubMeshCount];
1196
1197        REPINDLIST *ver_inds_rep_by_geo = new REPINDLIST[objmesh->mSubMeshCount];
1198
1199        //      Index counter by submesh.
1200        int *inextvert = new int[objmesh->mSubMeshCount];
1201
1202        for (unsigned int       i = 0;  i < objmesh->mSubMeshCount;     i++)
1203        {
1204                inextvert[i] = 0;
1205        }
1206
1207        //      Construct the model.
1208        std::cout << "M0.faceCount(): " << M0.faceCount() << std::endl;
1209        for (int        i = 0;  i < M0.faceCount();     i++)
1210        {
1211                if (M0.face(i)->isValid())
1212                {
1213                        simplif::Face *auxface  =       M0.face(i);
1214
1215                        //      Determine to which submesh pertains the triangle.
1216                        int igeo = auxface->igeo;
1217
1218                        //      Insert to each submesh its triangles.
1219                        std::map<int,int>::iterator findit =
1220                                unique_verts_inds_by_geo[igeo].find(auxface->vertex(0)->validID());
1221                       
1222                        if (findit == unique_verts_inds_by_geo[igeo].end())
1223                        {
1224                                //      If it is not added... add and map it.
1225                                unique_verts_inds_by_geo[igeo][auxface->vertex(0)->validID()] =
1226                                                                                                                                                                                                                                                inextvert[igeo];
1227                               
1228                                inextvert[igeo]++;
1229                        }
1230
1231                        findit =
1232                                unique_verts_inds_by_geo[igeo].find(auxface->vertex(1)->validID());
1233                       
1234                        if (findit == unique_verts_inds_by_geo[igeo].end())
1235                        {
1236                                //      If it is not added... add and map it.
1237                                unique_verts_inds_by_geo[igeo][auxface->vertex(1)->validID()] =
1238                                                                                                                                                                                                                                                inextvert[igeo];
1239                                inextvert[igeo]++;
1240                        }
1241                       
1242                        findit =
1243                                unique_verts_inds_by_geo[igeo].find(auxface->vertex(2)->validID());
1244                       
1245                        if (findit == unique_verts_inds_by_geo[igeo].end())
1246                        {
1247                                //      If it is not added... add and map it.
1248                                unique_verts_inds_by_geo[igeo][auxface->vertex(2)->validID()] =
1249                                                                                                                                                                                                                                                inextvert[igeo];
1250                                inextvert[igeo]++;
1251                        }
1252
1253                        //      Total number of indices by submesh.
1254                        ver_inds_rep_by_geo[igeo].push_back(auxface->vertex(0)->validID());
1255                        ver_inds_rep_by_geo[igeo].push_back(auxface->vertex(1)->validID());
1256                        ver_inds_rep_by_geo[igeo].push_back(auxface->vertex(2)->validID());
1257                }
1258        }
1259
1260        //      Output simplified mesh.
1261        mGeoMesh                                                                =       new Mesh();
1262        mGeoMesh->mVertexBuffer =       new     VertexBuffer();
1263
1264        mGeoMesh->mSubMeshCount = objmesh->mSubMeshCount;
1265
1266        //      Memory allocation for the submeshes.
1267        mGeoMesh->mSubMesh = new SubMesh[objmesh->mSubMeshCount];
1268
1269        //      Fill up bounding box settings.
1270        mGeoMesh->mMeshBounds.maxX                                      =       objmesh->mMeshBounds.maxX;
1271        mGeoMesh->mMeshBounds.maxY                                      =       objmesh->mMeshBounds.maxY;
1272        mGeoMesh->mMeshBounds.maxZ                                      =       objmesh->mMeshBounds.maxZ;
1273        mGeoMesh->mMeshBounds.minX                                      =       objmesh->mMeshBounds.minX;
1274        mGeoMesh->mMeshBounds.minY                                      =       objmesh->mMeshBounds.minY;
1275        mGeoMesh->mMeshBounds.minZ                                      =       objmesh->mMeshBounds.minZ;
1276        mGeoMesh->mMeshBounds.radius                            =       objmesh->mMeshBounds.radius;
1277        mGeoMesh->mMeshBounds.scaleFactor               =       objmesh->mMeshBounds.scaleFactor;
1278
1279        //      Copy skeleton name.
1280        if (objmesh->hasSkeleton)
1281        {
1282                mGeoMesh->hasSkeleton   =       true;
1283
1284                strcpy(mGeoMesh->mSkeletonName,objmesh->mSkeletonName);
1285        }
1286
1287        //      Copy mesh bones.
1288        if (!objmesh->mBones.empty())
1289        {
1290                for (unsigned int j = 0; j < objmesh->mBones.size(); j++)
1291                {
1292                        mGeoMesh->mBones.push_back(objmesh->mBones[j]);
1293                }
1294        }
1295
1296        bool copiedShared = false;
1297
1298        //      For each submesh.
1299        for (size_t     i = 0;  i < objmesh->mSubMeshCount;     i++)
1300        {
1301                mGeoMesh->mSubMesh[i].mStripCount       =       0;
1302                mGeoMesh->mSubMesh[i].mStrip                    =       NULL;
1303
1304                mGeoMesh->
1305                        mSubMesh[i].mSharedVertexBuffer =       false;
1306
1307                strcpy( mGeoMesh->mSubMesh[i].mMaterialName,
1308                                objmesh->mSubMesh[i].mMaterialName);
1309
1310                //      Copy submesh bones.
1311                if (!objmesh->mSubMesh[i].mBones.empty())
1312                {
1313                        for (unsigned int j = 0; j < objmesh->mSubMesh[i].mBones.size(); j++)
1314                        {
1315                                mGeoMesh->mSubMesh[i].mBones.push_back(objmesh->
1316                                                                                                                                                                mSubMesh[i].mBones[j]);
1317                        }
1318                }
1319
1320                if (i != indexMeshLeaves)
1321                {
1322                        //      Indices vectors.
1323                        mGeoMesh->mSubMesh[i].mIndexCount       =       ver_inds_rep_by_geo[i].size();
1324                       
1325                        mGeoMesh->mSubMesh[i].mIndex                    =       new Index[mGeoMesh->
1326                                                                                                                                                                                mSubMesh[i].mIndexCount];
1327
1328                        //      Store the indices.
1329                        for (unsigned int       j = 0;  j < mGeoMesh->mSubMesh[i].mIndexCount;  j++)
1330                        {
1331                                //      Obtain the indices that point at VertexBuffer.
1332                                mGeoMesh->mSubMesh[i].mIndex[j] =
1333                                        unique_verts_inds_by_geo[i].
1334                                                                operator [](ver_inds_rep_by_geo[i].
1335                                                                operator [](j));
1336                        }
1337
1338                        //      Copy the vertices.
1339                        if (mGeoMesh->mSubMesh[i].mSharedVertexBuffer)
1340                        {
1341                                //      Shared vertices.
1342                                if (!copiedShared)
1343                                {
1344                                        mGeoMesh->mVertexBuffer = new VertexBuffer();
1345                                        copiedShared                                            = true;
1346                                }
1347
1348                                mGeoMesh->mSubMesh[i].mVertexBuffer = mGeoMesh->mVertexBuffer;
1349                        }
1350                        else
1351                        {
1352                                //      There's no shared vertices.
1353                                mGeoMesh->mSubMesh[i].mVertexBuffer     =       new VertexBuffer();
1354                        }
1355
1356                        mGeoMesh->mSubMesh[i].mVertexBuffer->mVertexCount       =
1357                                                                                                                                        unique_verts_inds_by_geo[i].size();
1358                       
1359                        mGeoMesh->mSubMesh[i].mVertexBuffer->mVertexInfo        =
1360                                                                                        objmesh->mSubMesh[i].mVertexBuffer->mVertexInfo;
1361
1362                        //      Allocate memory for position, normal and texutre coordinates.
1363                        mGeoMesh->mSubMesh[i].mVertexBuffer->mPosition  =
1364                                                new Vector3[mGeoMesh->mSubMesh[i].mVertexBuffer->mVertexCount];
1365                       
1366                        mGeoMesh->mSubMesh[i].mVertexBuffer->mNormal            =
1367                                                new Vector3[mGeoMesh->mSubMesh[i].mVertexBuffer->mVertexCount];
1368                       
1369                        mGeoMesh->mSubMesh[i].mVertexBuffer->mTexCoords =
1370                                                new Vector2[mGeoMesh->mSubMesh[i].mVertexBuffer->mVertexCount];
1371
1372                        for (   MAPAINDIND::iterator mapit = unique_verts_inds_by_geo[i].begin();
1373                                                mapit != unique_verts_inds_by_geo[i].end();
1374                                                mapit++)
1375                        {
1376                                //      Key and value.
1377                                int isrc = mapit->first;
1378                                int idst = mapit->second;
1379
1380                                //      Vertex coordinate.
1381                                //      Construction of the submeshes.
1382                                Vector3 v3(     (Real)M0.vertex(isrc)->operator [](0),
1383                                                                                (Real)M0.vertex(isrc)->operator [](1),
1384                                                                                (Real)M0.vertex(isrc)->operator [](2));
1385                               
1386                                mGeoMesh->mSubMesh[i].mVertexBuffer->mPosition[idst]    =       v3;
1387
1388                                //      Normal coordinates.
1389                                Vector3 v3n(    (Real)M0.normal(isrc)(0),
1390                                                                                        (Real)M0.normal(isrc)(1),
1391                                                                                        (Real)M0.normal(isrc)(2));
1392                               
1393                                mGeoMesh->mSubMesh[i].mVertexBuffer->mNormal[idst]      =       v3n;
1394
1395                                //      Texture coordinates.
1396                                Vector2 v2(     (Real)M0.texcoord(isrc)(0),
1397                                                                                (Real)M0.texcoord(isrc)(1));
1398                               
1399                                mGeoMesh->mSubMesh[i].mVertexBuffer->mTexCoords[idst]   =       v2;
1400                        }
1401                }
1402                else
1403                {
1404                        //      Leaves mesh.
1405                        mGeoMesh->mSubMesh[i].mIndexCount       =       objmesh->mSubMesh[i].mIndexCount;
1406                       
1407                        mGeoMesh->mSubMesh[i].mIndex    =               new Index[mGeoMesh->mSubMesh[i].mIndexCount];
1408
1409                        //      Copy the leaves submesh indexes.
1410                        for (unsigned int       j       =       0;      j < mGeoMesh->mSubMesh[i].mIndexCount;  j++)
1411                        {       
1412                                mGeoMesh->mSubMesh[i].mIndex[j] =       objmesh->mSubMesh[i].mIndex[j];
1413                        }
1414
1415                        //      Copy the leaves submesh vertices.
1416                        mGeoMesh->mSubMesh[i].mVertexBuffer     =       new VertexBuffer();
1417                       
1418                        mGeoMesh->mSubMesh[i].mVertexBuffer->mVertexCount       =
1419                                                                                                                objmesh->mSubMesh[i].mVertexBuffer->mVertexCount;
1420                       
1421                        mGeoMesh->mSubMesh[i].mVertexBuffer->mVertexInfo        =
1422                                                                                                                objmesh->mSubMesh[i].mVertexBuffer->mVertexInfo;
1423
1424                        //      Allocate memory for position, normal and texture coordinates.
1425                        mGeoMesh->mSubMesh[i].mVertexBuffer->mPosition  =
1426                                                        new Vector3[mGeoMesh->mSubMesh[i].mVertexBuffer->mVertexCount];
1427                       
1428                        mGeoMesh->mSubMesh[i].mVertexBuffer->mNormal    =
1429                                                        new Vector3[mGeoMesh->mSubMesh[i].mVertexBuffer->mVertexCount];
1430                       
1431                        mGeoMesh->mSubMesh[i].mVertexBuffer->mTexCoords =
1432                                                        new Vector2[mGeoMesh->mSubMesh[i].mVertexBuffer->mVertexCount];
1433
1434                        for (   unsigned int j = 0;
1435                                        j < mGeoMesh->mSubMesh[i].mVertexBuffer->mVertexCount;
1436                                        j++)
1437                        {
1438                                //      Position.
1439                                mGeoMesh->mSubMesh[i].mVertexBuffer->mPosition[j].x     =
1440                                                                        objmesh->mSubMesh[i].mVertexBuffer->mPosition[j].x;
1441                               
1442                                mGeoMesh->mSubMesh[i].mVertexBuffer->mPosition[j].y     =
1443                                                                        objmesh->mSubMesh[i].mVertexBuffer->mPosition[j].y;
1444                               
1445                                mGeoMesh->mSubMesh[i].mVertexBuffer->mPosition[j].z     =
1446                                                                        objmesh->mSubMesh[i].mVertexBuffer->mPosition[j].z;
1447
1448                                //      Normals.
1449                                mGeoMesh->mSubMesh[i].mVertexBuffer->mNormal[j].x       =
1450                                                                        objmesh->mSubMesh[i].mVertexBuffer->mNormal[j].x;
1451                               
1452                                mGeoMesh->mSubMesh[i].mVertexBuffer->mNormal[j].y       =
1453                                                                        objmesh->mSubMesh[i].mVertexBuffer->mNormal[j].y;
1454                               
1455                                mGeoMesh->mSubMesh[i].mVertexBuffer->mNormal[j].z       =
1456                                                                        objmesh->mSubMesh[i].mVertexBuffer->mNormal[j].z;
1457
1458                                //      Textures.
1459                                mGeoMesh->mSubMesh[i].mVertexBuffer->mTexCoords[j].x    =
1460                                                                        objmesh->mSubMesh[i].mVertexBuffer->mTexCoords[j].x;
1461                               
1462                                mGeoMesh->mSubMesh[i].mVertexBuffer->mTexCoords[j].y    =
1463                                                                        objmesh->mSubMesh[i].mVertexBuffer->mTexCoords[j].y;
1464                        }
1465                }
1466        }
1467
1468        delete[] unique_verts_inds_by_geo;
1469        delete[] ver_inds_rep_by_geo;
1470        delete[] inextvert;
1471
1472        //      Store the simplification steps in MeshSimplificationSequence.
1473        int     acum    =       0;
1474
1475        for (size_t i   =       0; i < objmesh->mSubMeshCount; i++)
1476        {
1477                if (objmesh->mSubMesh[i].mSharedVertexBuffer)
1478                {
1479                        first_index_submesh[i]  =       0;
1480                }
1481                else
1482                {
1483                        first_index_submesh[i]  =       acum;
1484                }
1485
1486                acum    +=      (int)objmesh->mSubMesh[i].mVertexBuffer->mVertexCount;
1487        }
1488
1489        vector<int>     v0;
1490        vector<int>     v1;
1491        vector<int>     submesh0;
1492        vector<int>     submesh1;
1493
1494        return msimpseq;
1495}
1496
1497//---------------------------------------------------------------------------
1498//      Set submesh leaves.
1499//---------------------------------------------------------------------------
1500void SimplificationMethod::setMeshLeaves(int meshLeaves)
1501{
1502        indexMeshLeaves =       meshLeaves;
1503}
1504
1505//      Gets mesh simplified.
1506Mesh    *       SimplificationMethod::GetMesh()
1507{
1508        return  mGeoMesh;
1509}
1510
Note: See TracBrowser for help on using the repository browser.