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

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