source: GTP/trunk/Lib/Geom/shared/GeoTool/src/GeoMeshLoader.cpp @ 980

Revision 980, 26.6 KB checked in by gumbau, 18 years ago (diff)
Line 
1/*==========================================================================
2 *      (C) 2005 Universitat Jaume I
3 *==========================================================================
4 *      PROYECT:        GAME TOOLS
5 *==========================================================================*/
6/*      CONTENT:       
7 *
8 *
9 *      @file   GeoMeshLoader.cpp
10 *==========================================================================*/
11
12#include        "GeoMeshLoader.h"
13
14using namespace Geometry;
15using   namespace       std;
16
17//      Jump a chunk.
18void GeoMeshLoader::jumpChunk(FILE      *f)
19{
20        fseek(f,-(long)CHUNK_OVERHEAD_SIZE,1);
21
22        //      Return to the begin of the chunk.
23        fseek(f,long_actual,SEEK_CUR);
24}
25
26//      Read a chunk.
27unsigned short GeoMeshLoader::readChunk(FILE    *f)
28{
29        unsigned        short   id;
30
31        fread(&id,sizeof(unsigned short),1,f);
32        fread(&long_actual,sizeof(unsigned long),1,f);
33                                                                       
34        return id;
35}
36
37//      Read geometry vertex element.
38void GeoMeshLoader::readGeometryVertexElement(FILE      *f, Mesh        *geoMesh)
39{
40        unsigned        short           source;
41        GeometryElement         aux;
42        int                                                             i;
43        bool                                                    encontrado;
44        VertexElementType       vType;
45
46        i                                               =       0;
47        encontrado      =       false;
48
49        //              VertexElementSemantic vSemantic;
50        // unsigned short source;       // buffer bind source
51        fread(&source,sizeof(unsigned short),1,f);
52
53        // unsigned short type;         // VertexElementType
54        fread(&aux.type,sizeof(unsigned short),1,f);
55
56        vType   =       static_cast<VertexElementType>(aux.type);
57
58        /*
59        if (vType == VET_FLOAT3)
60        {
61                printf("%u es float3 ",aux.type);
62        }
63
64        if (vType == VET_FLOAT4)
65        {
66                printf("%u es float4 ",aux.type);
67        }
68
69        if (vType == VET_FLOAT2)
70        {
71                printf("%u es float2 ",aux.type);
72        }
73        */
74
75        // unsigned short semantic; // VertexElementSemantic
76        fread(&aux.semantic,sizeof(unsigned short),1,f);
77
78        //      vSemantic = static_cast<VertexElementSemantic>(tmp);
79        //      unsigned short offset;  // start offset in buffer in bytes
80        fread(&aux.offset,sizeof(unsigned short),1,f);
81
82        // unsigned short index;        // index of the semantic
83        /*
84        VES_POSITION  Position, 3 reals per vertex. 
85        VES_BLEND_WEIGHTS  Blending weights. 
86        VES_BLEND_INDICES  Blending indices. 
87        VES_NORMAL  Normal, 3 reals per vertex. 
88        VES_DIFFUSE  Diffuse colours. 
89        VES_SPECULAR  Specular colours. 
90        VES_TEXTURE_COORDINATES  Texture coordinates. 
91        VES_BINORMAL  Binormal (Y axis if normal is Z). 
92        VES_TANGENT  Tangent (X axis if normal is Z). 
93        */
94        fread(&aux.index,sizeof(unsigned short),1,f);
95
96        while ((i < list.size()) && (!encontrado))
97        {
98                if (list[i].source==source)
99                {
100                        encontrado      =       true;
101                }
102                else
103                {
104                        i++;
105                }
106        }
107
108        if (encontrado)
109        {
110                list[i].list.push_back(aux);
111        }
112        else
113        {
114                GT      aux2;
115               
116                aux2.source     =       source;
117                aux2.list.push_back(aux);
118                list.push_back(aux2);
119        }
120}
121
122//      Read geometry vertex declaration.
123void GeoMeshLoader::readGeometryVertexDeclaration(FILE  *f, Mesh        *geoMesh)
124{
125        unsigned short chunkID;
126  // Find optional geometry chunks
127  if (!feof(f))
128  {
129    chunkID     =       readChunk(f);
130
131    while(!feof(f) && (chunkID == M_GEOMETRY_VERTEX_ELEMENT ))
132    {
133      switch (chunkID)
134      {
135                                case M_GEOMETRY_VERTEX_ELEMENT:
136
137                                        //      Debug.
138                                        cout    <<      "               M_GEOMETRY_VERTEX_ELEMENT"
139                                                                <<      endl;
140                                       
141          readGeometryVertexElement(f, geoMesh);
142
143          break;
144      }
145
146      // Get next chunk
147      if (!feof(f))
148      {
149                                chunkID = readChunk(f);
150      }
151    }// End while.
152
153    if (!feof(f))
154    {
155                        // Backpedal back to start of non-submesh chunk
156                        fseek(f,-(long)CHUNK_OVERHEAD_SIZE,1);
157    }
158
159  }//   End if (!feof(f))
160}//     End readGeometryVertexDeclaration.
161
162//      Read geometry vertex buffer.
163void GeoMeshLoader::readGeometryVertexBuffer(FILE       *f, Mesh        *geoMesh, int option)
164{
165        unsigned        short   bindIndex;
166        unsigned        short   vertexSize;
167        unsigned        short   headerID;
168        int                                                     i;
169        float                                           aux;
170        int                                                     k;
171        bool                                            encontrado;
172        float                                           x,y,z;
173        SubMesh                                 *geoSubMesh;
174        VertexBuffer            *vertex_buffer;
175
176        i                                               =       0;
177        k                                               =       0;
178        encontrado      =       false;
179       
180        if (option == GEOMESH_BUILD)
181        {
182                //      If is the main mesh.
183                if (currentSubMesh == -1)
184                {
185                        vertex_buffer   =       geoMesh->mVertexBuffer;
186                }
187                //      If is a submesh.
188                else
189                {
190                        //      Gets the current submesh
191                        geoSubMesh              =       &geoMesh->mSubMesh[currentSubMesh];
192                        vertex_buffer   =       geoSubMesh->mVertexBuffer;
193                }
194        }
195       
196        // Index to bind this buffer to
197        fread(&bindIndex,sizeof(unsigned short),1,f);
198
199        // Per-vertex size, must agree with declaration at this index
200        fread(&vertexSize,sizeof(unsigned short),1,f);
201
202        // Check for vertex data header
203        headerID        =       readChunk(f);
204
205        if (headerID != M_GEOMETRY_VERTEX_BUFFER_DATA)
206        {
207                cout    <<      "Can't find vertex buffer data area"
208                                        <<      endl;
209        }
210        else
211        {
212                //      Debug.
213                cout    <<      "               M_GEOMETRY_VERTEX_BUFFER_DATA"
214                                        <<      endl;
215        }
216
217        while ((i<list.size())&&(!encontrado))
218        {
219                if (list[i].source      ==      bindIndex)
220                {
221                        encontrado      =       true;
222                }
223                else
224                {
225                        i++;
226                }
227        }
228
229        if (encontrado)
230        {
231                for (k  =       0;      k < numVertices;        k++)
232                {
233                        //      For each element in this source.
234                        for(int j       =       0;      j < list[i].list.size();        j++)
235                        {
236                                //      Positions.
237                                if (list[i].list[j].semantic == 1)
238                                {
239                                        fread(&x,sizeof(float),1,f);
240                                        fread(&y,sizeof(float),1,f);
241                                        fread(&z,sizeof(float),1,f);
242
243                                        if (option == GEOMESH_BUILD)
244                                        {
245                                                vertex_buffer->mVertexInfo              |=      VERTEX_POSITION;
246                                                vertex_buffer->mPosition[k].x   =               x;
247                                                vertex_buffer->mPosition[k].y   =               y;
248                                                vertex_buffer->mPosition[k].z   =               z;
249                                        }
250                                }
251                                //      If are not vertices.
252                                else
253                                {
254                                        if (list[i].list[j].type == 2)
255                                        {
256                                                fread(&x,sizeof(float),1,f);
257                                                fread(&y,sizeof(float),1,f);
258                                                fread(&z,sizeof(float),1,f);
259
260                                                if (option == GEOMESH_BUILD)
261                                                {
262                                                        vertex_buffer->mVertexInfo      |=      VERTEX_NORMAL;
263                                                        vertex_buffer->mNormal[k].x     =               x;
264                                                        vertex_buffer->mNormal[k].y     =               y;
265                                                        vertex_buffer->mNormal[k].z     =               z;
266                                                }
267                                        }
268                                        if (list[i].list[j].type == 1)
269                                        {
270                                                fread(&x,sizeof(float),1,f);
271                                                fread(&y,sizeof(float),1,f);
272                                               
273                                                if (option == GEOMESH_BUILD)
274                                                {
275                                                        vertex_buffer->mVertexInfo                      |=      VERTEX_TEXCOORDS;
276                                                        vertex_buffer->mTexCoords[k].x  =               x;
277                                                        vertex_buffer->mTexCoords[k].y  =               y;
278                                                }
279                                        }
280                                }
281                        }
282                }
283        }
284        else
285        {
286                //      Debug.
287                cout    <<      "Error: Source not found."
288                                        <<      endl;
289        }
290
291}
292
293//      Read Geometry.
294void GeoMeshLoader::readGeometry(FILE   *f, Mesh        *geoMesh, int option)
295{
296        SubMesh                         *geoSubMesh;
297        VertexBuffer    *vertex_buffer;
298       
299        fread(&numVertices,sizeof(unsigned int),1,f);
300
301        if (option == GEOMESH_BUILD)
302        {
303                if (currentSubMesh == -1)
304                {
305                        //      Get the current vertex buffer.
306                        vertex_buffer   =       geoMesh->mVertexBuffer;
307                }
308                else
309                {
310                        //      Get the current submesh.
311                        geoSubMesh              =       &geoMesh->mSubMesh[currentSubMesh];
312
313                        //      Create the VertexBuffer of the submesh.
314                        geoSubMesh->mVertexBuffer       =       new VertexBuffer();
315
316                        //      Get the current vertex buffer.
317                        vertex_buffer   =       geoSubMesh->mVertexBuffer;
318                }
319
320                //      Initialize the VertexBuffer of the current submesh.
321                vertex_buffer->mVertexCount     =       numVertices;
322
323                //      Initialize the position array.
324                vertex_buffer->mPosition        =       new Vector3[numVertices];
325
326                //      Initialize the normal array.
327                vertex_buffer->mNormal          =       new Vector3[numVertices];
328
329                //      Initialize the texture coords array.
330                vertex_buffer->mTexCoords       =       new Vector2[numVertices];
331        }
332
333        // Find optional geometry chunks
334        if (!feof(f))
335        {
336                unsigned short chunkID = readChunk(f);
337       
338                while(!feof(f) &&
339                                        (chunkID == M_GEOMETRY_VERTEX_DECLARATION ||
340                                        chunkID == M_GEOMETRY_VERTEX_BUFFER ))
341                {
342                        switch (chunkID)
343                        {
344                                case M_GEOMETRY_VERTEX_DECLARATION:
345
346                                        //      Debug.
347                                        cout    <<      "               M_GEOMETRY_VERTEX_DECLARATION"
348                                                                <<      endl;
349                                       
350                                        readGeometryVertexDeclaration(f, geoMesh);
351                                       
352                                        break;
353                                       
354                                case M_GEOMETRY_VERTEX_BUFFER:
355                                       
356                                        //      Debug.
357                                        cout    <<      "               M_GEOMETRY_VERTEX_BUFFER"
358                                                                <<      endl;
359                                       
360                                        readGeometryVertexBuffer(f, geoMesh,option);
361                                       
362                                        break;
363                        }
364               
365                        // Get next chunk.
366                        if (!feof(f))
367                        {
368                                chunkID = readChunk(f);
369                        }
370                }
371
372                if (!feof(f))
373                {
374                        // Backpedal back to start of non-submesh chunk.
375                        fseek(f,-(long)CHUNK_OVERHEAD_SIZE,1);
376                }
377        }
378}
379
380//      Read a submesh operation.
381void GeoMeshLoader::readSubMeshOperation(       FILE    *f,
382                                                                                                                                                                        Mesh    *geoMesh,
383                                                                                                                                                                        int     option)
384{
385        unsigned        short   opType;
386       
387        fread(&opType,sizeof(unsigned short),1,f);
388
389        if (option == GEOMESH_BUILD)
390        {
391                if (opType == 5)
392                {
393                        geoMesh->mSubMesh[currentSubMesh].mType =       GEO_TRIANGLE_STRIPS;
394                }
395                else
396                {
397                        geoMesh->mSubMesh[currentSubMesh].mType =       GEO_TRIANGLE_LIST;
398                }
399        }
400}
401
402//      Read a submesh.
403void GeoMeshLoader::readSubMesh(FILE    *f, Mesh        *geoMesh, int option)
404{
405        SubMesh                                 *geoSubMesh;
406        unsigned        short   chunkID;
407        char                                            materialName[255];
408        bool                                            useSharedVertices;
409        unsigned        int             numIndices;
410        bool                                            idx32bit;
411
412        switch  (option)
413        {
414                case    SUBMESH_COUNT:
415                        geoMesh->mSubMeshCount++;
416                        break;
417                case    GEOMESH_BUILD:
418
419                        //      Initialize the new subMesh.
420                        geoSubMesh      =       &geoMesh->mSubMesh[currentSubMesh];
421        }
422       
423        list.clear();
424
425        //      Gets material name.
426        fgets(materialName,255,f);
427
428        fread(&useSharedVertices,sizeof(bool),1,f);
429       
430        if (option      ==      GEOMESH_BUILD)
431        {
432                //      Obtain the material name.
433                strcpy(geoSubMesh->mMaterialName,materialName);
434               
435                //      Obtain the flag of vertex shared.
436                geoSubMesh->mSharedVertexBuffer =       useSharedVertices;
437               
438                if (useSharedVertices)
439                {
440                        //      The VB of the submesh points to the VB of the mesh.
441                        geoSubMesh->mVertexBuffer       =       geoMesh->mVertexBuffer;
442                }
443        }
444
445        fread(&numIndices,sizeof(unsigned int),1,f);
446        fread(&idx32bit,sizeof(bool),1,f);
447       
448        if (option == GEOMESH_BUILD)
449        {
450                        //      Sets the index count of the submesh.
451                        geoSubMesh->mIndexCount =       numIndices;
452       
453                        //      Create the index arrar for this submesh.
454                        geoSubMesh->mIndex      =       new Index[numIndices];
455        }
456       
457        /*
458        if (idx32bit)
459        {
460                printf("\tSon 32 bits por indice\n");
461        }
462        else
463        {
464                printf("\tSon 16 bits por indice\n");
465        }
466        */
467
468        //Sumo uno a los vertices porque en el obj no puede hacer un vertice 0
469        if (idx32bit)
470        {
471                unsigned int aux;
472
473                for (int i = 0; i < numIndices; i++)
474                {
475                        fread(&aux,sizeof(unsigned int),1,f);
476
477                        if (option == GEOMESH_BUILD)
478                        {
479                                        geoSubMesh->mIndex[i]   =       aux;
480                        }
481                }
482        }
483        else
484        {
485                unsigned short aux;
486
487                for (int i = 0; i < numIndices; i++)
488                {
489                        fread(&aux,sizeof(unsigned short),1,f);
490                       
491                        if (option == GEOMESH_BUILD)
492                        {
493                                geoSubMesh->mIndex[i]   =       aux;
494                        }
495                }
496        }
497
498  // M_GEOMETRY chunk
499        // (Optional: present only if useSharedVertices = false)
500  if (!useSharedVertices)
501        {
502                chunkID = readChunk(f);
503               
504                if (chunkID != M_GEOMETRY)
505                {
506                        //      Debug.
507                        cout    <<      "Error: Missing mesh geometry."
508                                                <<      endl;
509                }
510               
511                readGeometry(f, geoMesh, option);
512        }
513
514        // Find all bone assignments (if present)
515        if (!feof(f))
516        {
517                chunkID = readChunk(f);
518                while(!feof(f) &&
519                                        (chunkID == M_SUBMESH_BONE_ASSIGNMENT ||
520                                        chunkID == M_SUBMESH_OPERATION))
521                {
522                        switch(chunkID)
523                        {
524                                case M_SUBMESH_OPERATION:
525                                                               
526                                        //      Debug.
527                                        cout    <<      "               M_SUBMESH_OPERATION"
528                                                                <<      endl;
529
530                                        readSubMeshOperation(f, geoMesh, option);
531                                       
532                                        break;
533                                       
534                                case M_SUBMESH_BONE_ASSIGNMENT:
535                                       
536                                        //      Debug.
537                                        //cout  <<      "               M_SUBMESH_BONE_ASSIGNMENT"
538                                        //                      <<      endl;
539                                       
540                                        if (option      ==      GEOMESH_BUILD)
541                                        {
542                                                readSubMeshBoneAssignment(f, geoSubMesh, option);
543                                        }
544                                        else
545                                        {
546                                                jumpChunk(f);
547                                        }
548                                       
549                                        break;
550                        }
551
552                        if (!feof(f))
553                        {
554                                chunkID =       readChunk(f);
555                        }
556
557                }
558                if (!feof(f))
559                {
560                        // Backpedal back to start of chunk.
561                        fseek(f,-(long)CHUNK_OVERHEAD_SIZE,1);
562                }
563        }
564
565}
566
567//      Read a mesh lod information.
568void GeoMeshLoader::readMeshLodInfo(FILE        *f, Mesh        *geoMesh)
569{
570        unsigned        short   chunkID;
571        unsigned        short   i;
572        unsigned        short   aux;
573        bool                                            aux2;
574
575  // unsigned short numLevels;
576        fread(&aux,sizeof(unsigned short),1,f);
577        // bool manual;
578        // (true for manual alternate meshes, false for generated)
579        fread(&aux2,sizeof(bool),1,f);
580
581        // Loop from 1 rather than 0 (full detail index is not in file)
582        for (i = 1; i < aux; ++i)
583        {
584                chunkID = readChunk(f);
585                if (chunkID != M_MESH_LOD_USAGE)
586                {
587                        //      Debug.
588                        cout    <<      "Error: Missing M_MESH_LOD_USAGE chunk"
589                                                <<      endl;
590                }
591                else
592                {
593                        cout    <<      "               M_MESH_LOD_USAGE"
594                                                <<      endl;
595                }
596               
597                jumpChunk(f);
598
599        }
600}
601
602//      Read a submesh name table.
603void GeoMeshLoader::readSubMeshNameTable(FILE   *f, Mesh        *geoMesh)
604{
605                unsigned        short   chunkID;
606                unsigned        short   subMeshIndex;
607                char                                            string[255];
608
609                if (!feof(f))
610                {
611                        chunkID =       readChunk(f);
612                       
613                        while   (!feof(f) && (chunkID == M_SUBMESH_NAME_TABLE_ELEMENT ))
614                        {
615                                //      Debug.
616                                cout    <<      "               M_SUBMESH_NAME_TABLE_ELEMENT"
617                                                        <<      endl;
618                               
619                                // Read in the index of the submesh.
620                                fread(&subMeshIndex,sizeof(unsigned short),1,f);
621                               
622                                // Read in the String and map it to its index.
623                                fgets(string,255,f);
624
625                                // If we're not end of file get the next chunk ID.
626                                if (!feof(f))
627                                {
628                                        chunkID = readChunk(f);
629                                }
630                        }
631                        if (!feof(f))
632                        {
633                                // Backpedal back to start of chunk.
634                                fseek(f,-(long)CHUNK_OVERHEAD_SIZE,1);
635                        }
636                }
637}
638
639//      Read a mesh file.
640void GeoMeshLoader::readMesh(FILE       *f, Mesh        *geoMesh, int option)
641{
642        unsigned        short   chunkID;
643        bool                                            nada;
644
645        //      Create the VertexBuffer of the mesh.
646        geoMesh->mVertexBuffer  =       new     VertexBuffer();
647        geoMesh->mVertexBuffer->mVertexCount    =       0;
648
649        //La vacio antes de leer el mesh
650        list.clear();
651
652        // bool skeletallyAnimated
653        fread(&nada,sizeof(bool),1,f);
654
655  // Find all subchunks
656        if (!feof(f))
657        {
658                chunkID =       readChunk(f);
659
660                while(!feof(f) &&
661                                (chunkID == M_GEOMETRY ||
662                                 chunkID == M_SUBMESH ||
663                                 chunkID == M_MESH_SKELETON_LINK ||
664                                 chunkID == M_MESH_BONE_ASSIGNMENT ||
665                                 chunkID == M_MESH_LOD ||
666                                 chunkID == M_MESH_BOUNDS ||
667                                 chunkID == M_SUBMESH_NAME_TABLE ||
668                                 chunkID == M_EDGE_LISTS))
669                {
670                        switch(chunkID)
671                        {
672                                case M_GEOMETRY:
673
674                                        //      Debug.
675                                        cout    <<      "               M_GEOMETRY"
676                                                                <<      endl;
677
678                                        readGeometry(f, geoMesh, option);
679                                        break;
680
681                                case M_SUBMESH:
682
683                                        //      Debug.
684                                        cout    <<      "               M_SUBMESH"
685                                                                <<      endl;
686
687                                        if (option == GEOMESH_BUILD)
688                                        {
689                                                //      Increments the current submesh.
690                                                currentSubMesh++;
691                                        }
692
693                                        readSubMesh(f, geoMesh, option);
694
695                                        break;
696
697                                case M_MESH_SKELETON_LINK:
698
699                                        //      Debug.
700                                        cout    <<      "               M_MESH_SKELETON_LINK  "
701                                                                <<      endl;
702                                                               
703
704                                        readSkeletonLink(f, geoMesh, option);
705
706                                        break;
707
708                                case M_MESH_BONE_ASSIGNMENT:
709
710                                        //      Debug.
711                                        //cout  <<      "               M_MESH_BONE_ASSIGNMENT  "
712                                        //                      <<      endl;
713
714                                        //OSCAR
715                                        readMeshBoneAssignment(f, geoMesh, option);
716
717                                        break;
718
719                                case M_MESH_LOD:
720
721                                        //      Debug.
722                                        cout    <<      "               M_MESH_LOD"
723                                                                <<      endl;
724                                       
725                                        readMeshLodInfo(f, geoMesh);
726                                        break;
727
728                                case M_MESH_BOUNDS:
729
730                                        //      Debug.
731                                        cout    <<      "               M_MESH_BOUNDS "
732                                                                <<      endl;
733
734                                        //jumpChunk(f);
735                                        readMeshBounds(f, geoMesh, option);
736                                        break;
737
738                                case M_SUBMESH_NAME_TABLE:
739
740                                        //      Debug.
741                                        cout    <<      "               M_SUBMESH_NAME_TABLE "
742                                                                <<      endl;
743
744                                        readSubMeshNameTable(f, geoMesh);
745                                        break;
746
747                                case M_EDGE_LISTS:
748
749                                        //      Debug.
750                                        cout    <<      "               M_EDGE_LISTS "
751                                                                <<      endl;
752
753                                        jumpChunk(f);
754                                        break;
755                        }
756
757                        if (!feof(f))
758                        {
759                                chunkID =       readChunk(f);
760                        }
761
762                }
763
764                if (!feof(f))
765                {
766                        // Backpedal back to start of chunk
767                        fseek(f,-(long)CHUNK_OVERHEAD_SIZE,1);
768
769                        //      Debug.
770                        cout    <<      "Error: Reading failure."
771                                                <<      endl;
772                }
773        }
774
775}
776
777/*
778                Allocate memory to the array of strips
779*/
780SubMesh* GeoMeshLoader::BuildStripsGeoSubMesh(SubMesh* geoSubMesh)
781{
782        bool            head_found;
783        bool            tail_found;
784        int                     strip_count;
785        int                     tailIndex;
786        size_t  tail;
787
788
789        head_found                                                      =       false;
790        tail_found                                                      =       false;
791        geoSubMesh->mStripCount =       1;
792
793        //      Foreachone of the indices.
794        //      Obtains the number of triangle strips.
795        for (int i = 0; i < (geoSubMesh->mIndexCount - 1); i++)
796        {
797                if (geoSubMesh->mIndex[i] == geoSubMesh->mIndex[i+1])
798                {
799                        if (head_found)
800                        {
801                                tail_found      =       true;
802                        }
803                        else
804                        {
805                                head_found      =       true;
806                        }
807
808                        //      Jump one index.
809                        i++;
810                }
811                else
812                {
813                        //      Increments the number of triangle strips.
814                        if (tail_found)
815                        {
816                                geoSubMesh->mStripCount++;
817                        }
818
819                        head_found      =       false;
820                        tail_found      =       false;
821                }
822        }
823
824        geoSubMesh->mStrip              =       (Index**) malloc(       sizeof(Index*)
825                        *
826                        geoSubMesh->mStripCount);
827
828        //      Number of strips. Initially there is one triangle strip.
829        strip_count     =       1;
830
831        head_found                                              =       false;
832        tail_found                                              =       false;
833
834        //      Initialize the fist triangle strip.
835        geoSubMesh->mStrip[0]   =       &geoSubMesh->mIndex[0];
836
837        //      Foreachone of the indices.
838        //      Assigns the beginning of the triangle strips.
839        for(int i = 0;i < (geoSubMesh->mIndexCount - 1); i++)
840        {
841                if(geoSubMesh->mIndex[i] == geoSubMesh->mIndex[i+1])
842                {
843                        if(head_found)
844                        {
845                                if (!tail_found)
846                                {
847                                        tailIndex               =       i;
848                                }
849
850                                tail_found      =       true;
851                        }
852                        else
853                        {
854                                head_found      =       true;
855                        }
856
857                        //      Jump one index.
858                        i++;
859                }
860                else
861                {
862                        //      Increments the number of triangle strips.
863                        if(tail_found)
864                        {
865                                geoSubMesh->mStrip[strip_count++]       =       &geoSubMesh->mIndex[tailIndex];
866                        }
867
868                        head_found      =       false;
869                        tail_found      =       false;
870                }
871        }
872
873        //      Remove degenerate triangles of a submesh given.
874        geoSubMesh      =       removeDegenerateTriangles(geoSubMesh);
875
876        return  geoSubMesh;
877}
878
879//      Remove degenerate triangles of a submesh given.
880SubMesh *       GeoMeshLoader::removeDegenerateTriangles(SubMesh        *geoSubMesh)
881{
882        Index           *indices;
883        Index           *index;
884        Index           *indexBegin;
885        Index           *indexEnd;
886        Index           *new_strip_starts;
887        size_t  new_index_count;
888        size_t  current_index;
889
890        //      Stores the new starts of strips.
891        new_strip_starts        =       new     Index[geoSubMesh->mStripCount];
892       
893        //      Calculate the new index count.
894        new_index_count =       geoSubMesh->mIndexCount
895                -
896                (2 * geoSubMesh->mStripCount)
897                +
898                2;
899
900        //      Auxiliar index array.
901        indices =       new     Index[new_index_count];
902
903        //      Initialize the current index;
904        current_index   =       0;
905       
906        //      For each one of the strips.
907        for (int strip = 0; strip < geoSubMesh->mStripCount; strip++)
908        {
909                //      Stars of strip without degenerate triangles.
910                new_strip_starts[strip] =       current_index;
911               
912                //      First index of the strip.
913                indexBegin      =       geoSubMesh->mStrip[strip];
914
915                //      If is the final strip
916                if (strip       == (geoSubMesh->mStripCount - 1))
917                {
918                        //      The end of the index array.
919                        indexEnd        = &geoSubMesh->mIndex[geoSubMesh->mIndexCount];
920                }
921                else
922                {
923                        //      The beginning of the next strip.
924                        indexEnd        = geoSubMesh->mStrip[strip + 1];
925                }
926
927                int i;
928                i       = 0;
929
930                //      If is not the first strip.
931                if (strip != 0)
932                {
933                        indexBegin++;
934                }
935
936                //      If is not the last strip.
937                if (strip       != (geoSubMesh->mStripCount - 1))
938                {
939                        indexEnd--;
940                }
941
942                //      For each index of the strip.
943                for (index = indexBegin; index < indexEnd; index++)
944                {
945                        indices[current_index++]        =       indexBegin[i];
946
947                        //      Increments i.
948                        i++;
949                }
950
951        }
952
953        //      Free Index memory.
954        delete  []geoSubMesh->mIndex;
955
956        //      Update index count.
957        geoSubMesh->mIndexCount =       new_index_count;
958
959        geoSubMesh->mIndex      =       new     Index[new_index_count];
960
961        //      Store new index array without degenerate triangles.
962        for (size_t     i       =       0;      i       <       geoSubMesh->mIndexCount; i++)
963        {
964                geoSubMesh->mIndex[i]   =       indices[i];
965        }
966
967        //      Free auxiliar index array;
968        delete  []indices;
969
970        //      Update start of the strip.
971        for (int        strip   =       0; strip < geoSubMesh->mStripCount; strip++)
972        {
973                geoSubMesh->mStrip[strip]       =       &geoSubMesh->mIndex[new_strip_starts[strip]];
974        }
975
976        //      Free auxiliar strip starts.
977        delete  []new_strip_starts;
978       
979        return  geoSubMesh;
980}
981
982//      Loads a mesh.
983Mesh* GeoMeshLoader::load(char  *nameFileMesh)
984{
985        unsigned        short   uno;
986  unsigned      short   chunkID;
987        char                                            version[255];
988        char                                            kk;
989        FILE                                            *pFile;
990        SubMesh                                 *geosubmesh;
991
992        //      Initialize the current submesh;
993        currentSubMesh  =       -1;
994       
995        //      Debug.
996        cout    <<      "---------------------------------"
997                                <<      endl
998                                <<      "\t LOAD MESH"
999                                <<      endl
1000                                <<      "---------------------------------"
1001                                <<      endl;
1002
1003        //      Initialize the return value.
1004        geoMesh =       new     Mesh();
1005
1006        //      Open the mesh file.
1007        pFile   =       fopen( nameFileMesh, "rb" );
1008
1009  if (!pFile)
1010  {
1011                //      Debug.
1012                cout    <<      "Error: File "
1013                                        <<      nameFileMesh
1014                                        <<      " not found."
1015                                        <<      endl;
1016               
1017                exit(0);
1018  }
1019
1020        //      Count the submeshes
1021        //      and next build the geomesh.
1022        for (int option = 0; option < 2;option++)
1023        {
1024                fread(&uno,sizeof(unsigned short),1,pFile);
1025
1026                if (uno != M_HEADER)
1027                {
1028                        //      Debug.
1029                        cout    <<      "Error: Header not found."
1030                                                <<      endl;
1031                }
1032
1033                // Read version.
1034                fgets(version,255,pFile);
1035
1036                cout    <<      version <<      endl;
1037
1038                if (strcmp(version,"[MeshSerializer_v1.30]\n"))
1039                {
1040                        //      Debug.
1041                        cout    <<      "Error: Wrong mesh version."
1042                                                <<      endl
1043                                                <<      "Only version 1.3 or older allowed."
1044                                                <<      endl;
1045                }
1046
1047                while(!feof(pFile))
1048                {
1049                        chunkID = readChunk(pFile);
1050
1051                        switch (chunkID)
1052                        {
1053                                case M_MESH:
1054                                        readMesh(pFile, geoMesh, option);
1055                                        break;
1056                        }
1057                }
1058
1059                //      Create the submesh array
1060                if (option == SUBMESH_COUNT)
1061                {               
1062                        geoMesh->mSubMesh       = new SubMesh[geoMesh->mSubMeshCount];
1063                }
1064                                                       
1065                //      Move the curso to the begining of the file.
1066                fseek(pFile,0,SEEK_SET);
1067        }
1068
1069        //      Goes to the end of the file.
1070        fseek(pFile,0,SEEK_END);
1071
1072        //      Gets the size of the file.
1073        mFileSize       =       ftell(pFile);
1074       
1075        // Close the mesh file.
1076        fclose(pFile);
1077       
1078        for (int submesh = 0;   submesh < geoMesh->mSubMeshCount; submesh++)
1079        {
1080                //      Gets the actual submesh.
1081                geosubmesh      =       &geoMesh->mSubMesh[submesh];
1082               
1083                if (geosubmesh->mType == Geometry::GEO_TRIANGLE_STRIPS)
1084                {
1085                        //      Fill the strips list.
1086                        geosubmesh      =       BuildStripsGeoSubMesh(geosubmesh);
1087                }
1088        }
1089       
1090        //      Sets coods between -1 and 1.
1091        normalizeModel(geoMesh);
1092
1093        return  geoMesh;
1094}
1095
1096//      Sets coords between -1 and 1.
1097void    GeoMeshLoader::normalizeModel(Mesh      *geoMesh)
1098{
1099        unsigned        int     i;
1100        float                                   maxx, minx, maxy, miny, maxz, minz;
1101        float                                   cx, cy, cz, w, h, d, max;
1102        float                                   scale;
1103        VertexBuffer    *vertex_buffer;
1104
1105        //      Gets vertex buffer.
1106        vertex_buffer   =       geoMesh->mSubMesh[0].mVertexBuffer;
1107       
1108        //      Get the max/mins.
1109        maxx = minx = vertex_buffer->mPosition[0].x;
1110        maxy = miny = vertex_buffer->mPosition[0].y;
1111        maxz = minz = vertex_buffer->mPosition[0].z;
1112       
1113        //      For each submesh.
1114        for (int submesh = 0; submesh < geoMesh->mSubMeshCount; submesh++)
1115        {
1116                //      Gets the actual submesh.
1117                vertex_buffer   =       geoMesh->mSubMesh[submesh].mVertexBuffer;
1118
1119                //      For each index of the strip.
1120                for (int i = 0; i < vertex_buffer->mVertexCount; i++)
1121                {
1122                        if (maxx < vertex_buffer->mPosition[i].x)
1123                        {
1124                                maxx = vertex_buffer->mPosition[i].x;
1125                        }
1126
1127                        if (minx > vertex_buffer->mPosition[i].x)
1128                        {
1129                                minx = vertex_buffer->mPosition[i].x;
1130                        }
1131
1132                        if (maxy < vertex_buffer->mPosition[i].y)
1133                        {
1134                                maxy = vertex_buffer->mPosition[i].y;
1135                        }
1136
1137                        if (miny > vertex_buffer->mPosition[i].y)
1138                        {
1139                                miny = vertex_buffer->mPosition[i].y;
1140                        }
1141
1142                        if (maxz < vertex_buffer->mPosition[i].z)
1143                        {
1144                                maxz = vertex_buffer->mPosition[i].z;
1145                        }
1146
1147                        if (minz > vertex_buffer->mPosition[i].z)
1148                        {
1149                                minz = vertex_buffer->mPosition[i].z;
1150                        }
1151                }
1152
1153                //      If is a shared vertex Buffer.
1154                if (geoMesh->mSubMesh[submesh].mSharedVertexBuffer)
1155                {
1156                        break;
1157                }
1158        }
1159       
1160        //      Calculate model width, height, and depth.
1161        w = fabs(maxx) + fabs(minx);
1162        h = fabs(maxy) + fabs(miny);
1163        d = fabs(maxz) + fabs(minz);
1164
1165        //      Calculate center of the model.
1166        cx = (maxx + minx) / 2.0;
1167        cy = (maxy + miny) / 2.0;
1168        cz = (maxz + minz) / 2.0;
1169
1170
1171        //      Calculate max dimension.
1172        if (w > h)
1173        {
1174                max     =       w;
1175        }
1176        else
1177        {
1178                max     =       h;
1179        }
1180
1181        if (d > max)
1182        {
1183                max     =       d;
1184        }
1185       
1186        //      Calculate unitizing scale factor.
1187        scale = 1.0 / max;
1188
1189        geoMesh->mMeshBounds.scaleFactor                =       scale;
1190
1191        //      Translate around center then scale.
1192        //      For each submesh.
1193        for (int submesh = 0; submesh < geoMesh->mSubMeshCount; submesh++)
1194        {
1195                //      Gets the actual submesh.
1196                vertex_buffer   =       geoMesh->mSubMesh[submesh].mVertexBuffer;
1197
1198                //      For each index of the strip.
1199                for (int i = 0; i < vertex_buffer->mVertexCount; i++)
1200                {
1201                        vertex_buffer->mPosition[i].x -= cx;
1202                        vertex_buffer->mPosition[i].y -= cy;
1203                        vertex_buffer->mPosition[i].z -= cz;
1204                        vertex_buffer->mPosition[i].x *= scale;
1205                        vertex_buffer->mPosition[i].y *= scale;
1206                        vertex_buffer->mPosition[i].z *= scale;
1207                }
1208
1209                //      If is a shared vertex Buffer.
1210                if (geoMesh->mSubMesh[submesh].mSharedVertexBuffer)
1211                {
1212                        break;
1213                }
1214        }
1215
1216}
1217
1218//      Get the size in bytes of the file.
1219size_t  GeoMeshLoader::getFileSize()
1220{
1221        return  mFileSize;
1222}
1223
1224//      Constructor
1225GeoMeshLoader::GeoMeshLoader()
1226{
1227        geoMesh                 =       NULL;
1228        mFileSize               =       0;
1229}
1230
1231//      Destroyer.
1232GeoMeshLoader::~GeoMeshLoader()
1233{
1234        delete  geoMesh;
1235}
1236
1237//OSCAR
1238void GeoMeshLoader::readSubMeshBoneAssignment(FILE* f, SubMesh* geoSubMesh,int option)
1239{
1240        if (option == GEOMESH_BUILD)
1241        {
1242                VertexBoneAssignment assign;
1243
1244                // unsigned int vertexIndex;
1245                fread(&(assign.vertexIndex),sizeof(unsigned int),1,f);
1246                // unsigned short boneIndex;
1247                fread(&(assign.boneIndex),sizeof(unsigned short),1,f);
1248                // float weight
1249                fread(&(assign.weight),sizeof(float),1,f);
1250
1251                geoSubMesh->mBones.push_back(assign);
1252        }
1253}
1254
1255//OSCAR
1256void GeoMeshLoader::readMeshBoneAssignment(FILE* f, Mesh* geoMesh,int option)
1257{
1258        if (option == GEOMESH_BUILD)
1259        {
1260                VertexBoneAssignment assign;
1261
1262                // unsigned int vertexIndex;
1263                fread(&(assign.vertexIndex),sizeof(unsigned int),1,f);
1264                // unsigned short boneIndex;
1265                fread(&(assign.boneIndex),sizeof(unsigned short),1,f);
1266                // float weight
1267                fread(&(assign.weight),sizeof(float),1,f);
1268
1269
1270                geoMesh->mBones.push_back(assign);
1271        }
1272}
1273
1274//OSCAR
1275void GeoMeshLoader::readSkeletonLink(FILE* f, Mesh* geoMesh,int option)
1276{
1277        if (option == GEOMESH_BUILD)
1278        {
1279                fgets(geoMesh->mSkeletonName,255,f);
1280               
1281                geoMesh->hasSkeleton    =       true;
1282
1283                //      Debug.
1284                cout    <<      "Skeleton Name: "
1285                                        <<      geoMesh->mSkeletonName
1286                                        <<      endl;
1287        }
1288}
1289
1290//      Read bounding box settings.
1291void    GeoMeshLoader::readMeshBounds(FILE      *f, Mesh        *geoMesh,       int     option)
1292{
1293        if (option == GEOMESH_BUILD)
1294        {
1295                fread(&(geoMesh->mMeshBounds.minX),sizeof(float),1,f);
1296                fread(&(geoMesh->mMeshBounds.minY),sizeof(float),1,f);
1297                fread(&(geoMesh->mMeshBounds.minZ),sizeof(float),1,f);
1298                fread(&(geoMesh->mMeshBounds.maxX),sizeof(float),1,f);
1299                fread(&(geoMesh->mMeshBounds.maxY),sizeof(float),1,f);
1300                fread(&(geoMesh->mMeshBounds.maxZ),sizeof(float),1,f);
1301                fread(&(geoMesh->mMeshBounds.radius),sizeof(float),1,f);
1302        }
1303}
1304
Note: See TracBrowser for help on using the repository browser.