source: GTP/trunk/Lib/Geom/shared/GTGeometry/src/GeoMeshSaver.cpp @ 2127

Revision 2127, 23.9 KB checked in by gumbau, 17 years ago (diff)
Line 
1/*========================================================================
2 *      (C) 2005 Universitat Jaume I
3 *========================================================================
4 *      PROYECT:        GAME TOOLS
5 *=======================================================================*/
6/*      CONTENT:       
7 *
8 *
9 *      @file   GeoMeshSaver.cpp
10 *=======================================================================*/
11#include        <GeoMeshSaver.h>
12
13using   namespace       Geometry;
14using   namespace       std;
15
16//-------------------------------------------------------------------------
17//              Public:
18//-------------------------------------------------------------------------
19
20//-------------------------------------------------------------------------
21//      Constructors.
22//-------------------------------------------------------------------------
23GeoMeshSaver::GeoMeshSaver()
24{
25        leavesSubMesh   =       -1;
26        leavesVB                        =       NULL;
27        numindices              =       0;
28        indices                         =       NULL;
29}
30
31//-------------------------------------------------------------------------
32//      Destructor.
33//-------------------------------------------------------------------------
34GeoMeshSaver::~GeoMeshSaver()
35{
36        delete  mGeoMesh;
37}
38
39//-------------------------------------------------------------------------
40//      Saves a Mesh into a file.
41//-------------------------------------------------------------------------
42size_t  GeoMeshSaver::save(Mesh *geoMesh,       const   char    *fileNameMesh)
43{
44        size_t  size;
45        String  name(fileNameMesh);
46        SubMesh *geosubmesh;
47
48        mGeoMesh        =       new Mesh();
49
50        //      Set the mesh.
51        *mGeoMesh       =       *geoMesh;
52
53        //      Debug.
54        cout    <<      endl
55                                <<      endl
56                                <<      "-----------------------------------"
57                                <<      endl
58                                <<      "\t SAVE MESH"
59                                <<      endl
60                                <<      "-----------------------------------"
61                                <<      endl
62                                <<      endl;
63
64        //      Unnormalize geometry model.
65        unnormalizeModel(mGeoMesh);
66
67        if ((leavesSubMesh > -1) && leavesVB)
68        {
69                //      Gets the leaves submesh.
70                geosubmesh      =       &mGeoMesh->mSubMesh[leavesSubMesh];
71               
72                Vector3 bmax(   geoMesh->mMeshBounds.maxX,
73                                                                        geoMesh->mMeshBounds.maxY,
74                                                                        geoMesh->mMeshBounds.maxZ);
75               
76                Vector3 bmin(   geoMesh->mMeshBounds.minX,
77                                                                        geoMesh->mMeshBounds.minY,
78                                                                        geoMesh->mMeshBounds.minZ);
79               
80                Vector3 center = (bmax + bmin) * 0.5f;
81               
82                float   scale   =       geoMesh->mMeshBounds.scaleFactor;
83               
84                geosubmesh->mSharedVertexBuffer =       false;
85                geosubmesh->mStripCount                                 =       0;
86                geosubmesh->mIndexCount                                 =       numindices;
87               
88                size_t  icount  =       geosubmesh->mIndexCount;
89               
90                geosubmesh->mIndex      =       new Index[icount];
91               
92                for (size_t     i       =       0;      i < icount;     i++)
93                {
94                        geosubmesh->mIndex[i]   =       indices[i];
95                }
96
97                geosubmesh->mType                                       =       GEO_TRIANGLE_LIST;
98                geosubmesh->mVertexBuffer       =       new VertexBuffer();
99                geosubmesh->mVertexBuffer->mVertexInfo
100                                                                                                                                                                                                                =       VERTEX_POSITION;
101               
102                geosubmesh->mVertexBuffer->mVertexCount
103                                                                                                                                                                                                                =       leavesVB->mVertexCount;
104               
105                size_t  vcount;
106                       
107                vcount = geosubmesh->mVertexBuffer->mVertexCount;
108               
109                geosubmesh->mVertexBuffer->mPosition
110                                                                                                                                                                                                                =       new Vector3[vcount];
111               
112                geosubmesh->mVertexBuffer->mNormal
113                                                                                                                                                                                                                =       new Vector3[vcount];
114               
115                geosubmesh->mVertexBuffer->mTexCoords
116                                                                                                                                                                                                                =       new Vector2[vcount];
117               
118                for (size_t     i       =       0;      i < vcount;     i++)
119                {
120                        geosubmesh->mVertexBuffer->mPosition[i].x = leavesVB->mPosition[i].x / scale + center.x;
121                        geosubmesh->mVertexBuffer->mPosition[i].y = leavesVB->mPosition[i].y / scale + center.y;
122                        geosubmesh->mVertexBuffer->mPosition[i].z = leavesVB->mPosition[i].z / scale + center.z;
123                        geosubmesh->mVertexBuffer->mNormal[i].x = leavesVB->mNormal[i].x;
124                        geosubmesh->mVertexBuffer->mNormal[i].y = leavesVB->mNormal[i].y;
125                        geosubmesh->mVertexBuffer->mNormal[i].z = leavesVB->mNormal[i].z;
126                        geosubmesh->mVertexBuffer->mTexCoords[i].x = leavesVB->mTexCoords[i].x;
127                        geosubmesh->mVertexBuffer->mTexCoords[i].y = leavesVB->mTexCoords[i].y;
128                }
129        }
130
131        //      Open the file.
132        mSerializer     =       new     Serializer(name,Serializer::WRITE);
133
134        //      Write the file header.
135        writeFileHeader();
136
137        //      Write the mesh data.
138        writeMesh(mGeoMesh);
139
140        size    =       mSerializer->GetSize();
141       
142        //      Close the file.
143        delete  mSerializer;
144       
145        //      Return the number of bytes written.
146        return  size;
147}
148
149//-------------------------------------------------------------------------
150//              Private:
151//-------------------------------------------------------------------------
152
153//-------------------------------------------------------------------------
154//      Write the main mesh.
155//-------------------------------------------------------------------------
156void    GeoMeshSaver::writeMesh(Mesh    *geoMesh)
157{
158        // Header
159        writeChunkHeader(M_MESH, (unsigned long)calcMeshSize(geoMesh));
160
161        //      Debug.
162        cout    <<      "               M_MESH"
163                                <<      endl;
164
165        //      Write the skeletally animated flag.
166        writeBools(geoMesh->hasSkeleton,1);
167       
168        //      Write shared geometry.
169        if (geoMesh->mVertexBuffer->mVertexCount > 0)
170        {
171                writeGeometry(geoMesh->mVertexBuffer);
172        }
173
174        //      Write submeshes.
175        for (size_t i = 0;      i < geoMesh->mSubMeshCount;     i++)
176        {
177                writeSubMesh(&geoMesh->mSubMesh[i]);
178        }
179
180        // Write skeleton info if required
181        if (geoMesh->hasSkeleton)
182        {
183                // Write skeleton link
184                writeSkeletonLink(geoMesh->mSkeletonName);
185
186                // Write bone assignments
187                if (!geoMesh->mBones.empty())
188                {
189
190                        for (size_t i = 0; i< geoMesh->mBones.size(); i++)
191                        {
192                                writeMeshBoneAssignment(geoMesh->mBones[i]);
193                        }
194
195                }
196        }
197
198        //      Write the mesh bounds.
199        writeMeshBounds(geoMesh);
200
201        /*
202        // Write LOD data if any
203        if (pMesh->getNumLodLevels() > 1)
204        {
205        LogManager::getSingleton().logMessage("Exporting LOD information....");
206        writeLodInfo(pMesh);
207        LogManager::getSingleton().logMessage("LOD information exported.");
208
209        }
210        // Write bounds information
211        LogManager::getSingleton().logMessage("Exporting bounds information....");
212        writeBoundsInfo(pMesh);
213        LogManager::getSingleton().logMessage("Bounds information exported.");
214
215        // Write submesh name table
216        LogManager::getSingleton().logMessage("Exporting submesh name table...");
217        writeSubMeshNameTable(pMesh);
218        LogManager::getSingleton().logMessage("Submesh name table exported.");
219
220        // Write edge lists
221        if (pMesh->isEdgeListBuilt())
222        {
223        LogManager::getSingleton().logMessage("Exporting edge lists...");
224        writeEdgeList(pMesh);
225        LogManager::getSingleton().logMessage("Edge lists exported");
226        }
227        */
228}//     End write mesh.
229
230//-------------------------------------------------------------------------
231//      Write a submesh.
232//-------------------------------------------------------------------------
233void    GeoMeshSaver::writeSubMesh(SubMesh      *geoSubMesh)
234{
235        bool                                            idx32bit;
236        size_t                                  indexCount;
237        //Index                                         *index;
238        //Index                                         *indexBegin;
239        //Index                                         *indexEnd;
240
241        // Header.
242        writeChunkHeader(M_SUBMESH, (unsigned long)calcSubMeshSize(geoSubMesh));
243
244        //      Debug.
245        cout    <<      "               M_SUBMESH"
246                                <<      endl;
247
248        // Material Name.
249        strcat(geoSubMesh->mMaterialName,"\n");
250        mSerializer->WriteData(geoSubMesh->mMaterialName);
251
252        // bool useSharedVertices
253        writeBools(geoSubMesh->mSharedVertexBuffer, 1);
254
255        indexCount      =       geoSubMesh->mIndexCount;
256       
257        /*
258        //      If the submesh is in triangle strips.
259        if (geoSubMesh->mType == GEO_TRIANGLE_STRIPS)
260        {
261                indexCount      +=      (2 * geoSubMesh->mStripCount)
262                                                                                -
263                                                                                2;
264        }
265        */
266       
267        //      Write index count.
268        writeInts((unsigned long)indexCount, 1);
269
270        // bool indexes32Bit
271        idx32bit        =       true;
272        writeBools(idx32bit, 1);
273
274        /*
275        //      If the submesh is in triangle strips.
276        if (geoSubMesh->mType == GEO_TRIANGLE_STRIPS)
277        {
278                //      For each one of the strips.
279                for (int strip = 0; strip < geoSubMesh->mStripCount; strip++)
280                {
281                        //      First index of the strip.
282                        indexBegin      =       geoSubMesh->mStrip[strip];
283
284                        //      If is the final strip
285                        if (strip       == (geoSubMesh->mStripCount - 1))
286                        {
287                                //      The end of the index array.
288                                indexEnd        = &geoSubMesh->mIndex[geoSubMesh->mIndexCount];
289                        }
290                        else
291                        {
292                                //      The beginning of the next strip.
293                                indexEnd        = geoSubMesh->mStrip[strip + 1];
294                        }
295
296                        int i;
297                        i       = 0;
298
299                        //      Degenerate.
300                        if (strip != 0)
301                        {
302                                writeInts(indexBegin[i], 1);
303                        }
304                       
305                        //      For each index of the strip.
306                        for (index = indexBegin; index < indexEnd; index++)
307                        {
308                                writeInts(indexBegin[i], 1);
309                               
310                                //      Increments i.
311                                i++;
312                        }
313
314                        //      Degenerate.
315                        if (strip       != (geoSubMesh->mStripCount - 1))
316                        {
317                                writeInts(indexBegin[i - 1], 1);
318                        }
319                }
320        }
321        //      If the submesh is in triangle list.
322        else
323        {
324        */
325                //      Write the index array.
326                for (size_t i = 0; i < geoSubMesh->mIndexCount; i++)
327                {
328                        writeInts(geoSubMesh->mIndex[i], 1);
329                }
330        //}
331
332        // M_GEOMETRY stream (Optional: present only if useSharedVertices = false)
333        if (!geoSubMesh->mSharedVertexBuffer)
334        {
335                writeGeometry(geoSubMesh->mVertexBuffer);
336        }
337
338        // Operation type
339        writeSubMeshOperation(geoSubMesh);
340
341        // Bone assignments.
342        if (!geoSubMesh->mBones.empty())
343        {
344                for (size_t i = 0; i < geoSubMesh->mBones.size(); i++)
345                {
346                        writeSubMeshBoneAssignment(geoSubMesh->mBones[i]);
347                }
348        }
349}
350
351//-------------------------------------------------------------------------
352//      Write the submesh operation chunk and data.
353//-------------------------------------------------------------------------
354void GeoMeshSaver::writeSubMeshOperation(const  SubMesh *geoSubMesh)
355{
356        unsigned        short opType;
357        unsigned        long    size;
358
359        size    =       CHUNK_OVERHEAD_SIZE     +       sizeof(unsigned short);
360       
361        // Header
362        writeChunkHeader(M_SUBMESH_OPERATION, size);
363
364        //      Debug.
365        cout    <<      "               M_SUBMESH_OPERATION"
366                                <<      endl;
367
368        //      If the mesh is in triangle strips.
369        if (geoSubMesh->mType   ==      GEO_TRIANGLE_STRIPS)
370        {
371                opType  =       5;
372        }
373        //      If the mesh is in triangle list.
374        else
375        {
376                opType  =       4;
377        }
378       
379        writeShorts(opType, 1);
380}
381
382//-------------------------------------------------------------------------
383//      Write geometry.
384//-------------------------------------------------------------------------
385void    GeoMeshSaver::writeGeometry(VertexBuffer        *vertexBuffer)
386{
387        unsigned        short   element;
388        unsigned        long    size;
389        unsigned        short   buffer_count;
390
391        buffer_count    =       3;
392       
393        //      Calculate the size in bytes of the geometry chunk.
394        size    =       (unsigned long)calcGeometrySize(vertexBuffer);
395               
396        //      Header.
397        //
398        //      Write the M_GEOMETRY header.
399        writeChunkHeader(M_GEOMETRY, size);
400
401        //      Debug.
402        cout    <<      "               M_GEOMETRY"
403                                <<      endl;
404
405        writeInts((unsigned long)vertexBuffer->mVertexCount,1);
406
407        //      Vertex declaration.
408        //      Calculate the size of vertex declaration.
409        size    =       CHUNK_OVERHEAD_SIZE
410                                        +
411                                        buffer_count
412                                        *
413                                        (CHUNK_OVERHEAD_SIZE    +       (sizeof(unsigned short) *       5));
414
415        //      Write the vertex declaration header.
416        writeChunkHeader(       M_GEOMETRY_VERTEX_DECLARATION,size);
417
418        //      Debug.
419        cout    <<      "               M_GEOMETRY_VERTEX_DECLARATION"
420                                <<      endl;
421
422        //      Obtain the size of the vertex element chunk.
423        size    =       CHUNK_OVERHEAD_SIZE     +       (sizeof(unsigned short) *       5);
424
425        //      Positions.
426        //      Write the vertex element header for position.
427        writeChunkHeader(       M_GEOMETRY_VERTEX_ELEMENT,size);
428
429        //      Debug.
430        cout    <<      "               M_GEOMETRY_VERTEX_ELEMENT"
431                                <<      endl;
432
433        element =       0;
434        writeShorts(element,1);
435
436        element =       VET_FLOAT3;
437        writeShorts(element,1);
438       
439        element =       VES_POSITION;
440        writeShorts(element,1);
441       
442        element =       0;
443        writeShorts(element,1);
444       
445        element =       0;
446        writeShorts(element,1);
447
448        //      Normals.
449        //      Write the vertex element header for position.
450        writeChunkHeader(       M_GEOMETRY_VERTEX_ELEMENT,size);
451       
452        //      Debug.
453        cout    <<      "               M_GEOMETRY_VERTEX_ELEMENT"
454                                <<      endl;
455
456        element =       1;
457        writeShorts(element,1);
458       
459        element =       VET_FLOAT3;
460        writeShorts(element,1);
461       
462        element =       VES_NORMAL;
463        writeShorts(element,1);
464       
465        element =       0;
466        writeShorts(element,1);
467       
468        element =       0;
469        writeShorts(element,1);
470
471        //      Textures.
472        //      Write the vertex element header for position.
473        writeChunkHeader(M_GEOMETRY_VERTEX_ELEMENT,size);
474       
475        //      Debug.
476        cout    <<      "               M_GEOMETRY_VERTEX_ELEMENT"
477                                <<      endl;
478
479        element =       2;
480        writeShorts(element,1);
481       
482        element =       VET_FLOAT2;
483        writeShorts(element,1);
484       
485        element =       VES_TEXTURE_COORDINATES;
486        writeShorts(element,1);
487       
488        element =       0;
489        writeShorts(element,1);
490       
491        element =       0;
492        writeShorts(element,1);
493
494        //      Obtain the size for vertex buffer header for positons.
495        size    =       (2      *       CHUNK_OVERHEAD_SIZE)    +       (2      *       sizeof(unsigned short));
496
497        //      Write the vertex buffer header for positions.
498        writeChunkHeader(M_GEOMETRY_VERTEX_BUFFER,      size);
499
500        //      Debug.
501        cout    <<      "               M_GEOMETRY_VERTEX_BUFFER"
502                                <<      endl;
503
504        element =       0;
505        writeShorts(element,1);
506       
507        element =       12;
508        writeShorts(element,1);
509
510        //      Obtain the size for the vertex buffer data header for positions.
511        size    =       CHUNK_OVERHEAD_SIZE
512                                        +
513                                        ((sizeof(float) *       3)      *       vertexBuffer->mVertexCount);
514
515        //      Write the vertex buffer data header for positions.
516        writeChunkHeader(M_GEOMETRY_VERTEX_BUFFER_DATA, size);
517
518        //      Debug.
519        cout    <<      "               M_GEOMETRY_VERTEX_BUFFER_DATA"
520                                <<      endl;
521
522        //      Write all the positions coords.
523        mSerializer->WriteArray(vertexBuffer->mPosition,
524                                                                                                        vertexBuffer->mVertexCount);
525
526        //      Obtain the size for vertex buffer header for normals.
527        size    =       (2      *       CHUNK_OVERHEAD_SIZE)    +       (2      *       sizeof(unsigned short));
528
529        //      Write the vertex buffer header.
530        writeChunkHeader(       M_GEOMETRY_VERTEX_BUFFER,       size);
531
532        //      Debug.
533        cout    <<      "               M_GEOMETRY_VERTEX_BUFFER"
534                                <<      endl;
535
536        element =       1;
537        writeShorts(element,1);
538       
539        element =       12;
540        writeShorts(element,1);
541
542        //      Obtain the size for the vertex buffer data header for normals.
543        size    =       CHUNK_OVERHEAD_SIZE
544                                        +
545                                        ((sizeof(float) *       3)      *       vertexBuffer->mVertexCount);
546
547        //      Write the vertex buffer data header for normals.
548        writeChunkHeader(M_GEOMETRY_VERTEX_BUFFER_DATA, size);
549
550        //      Debug.
551        cout    <<      "               M_GEOMETRY_VERTEX_BUFFER_DATA"
552                                <<      endl;
553
554        //      Write all the normals coords.
555        mSerializer->WriteArray(vertexBuffer->mNormal,
556                                                                                                        vertexBuffer->mVertexCount);
557
558        //      Obtain the size for vertex buffer header for textures.
559        size    =       (2      *       CHUNK_OVERHEAD_SIZE)    +       (2      *       sizeof(unsigned short));
560
561        //      Write the vertex buffer header for textures.
562        writeChunkHeader(M_GEOMETRY_VERTEX_BUFFER,      size);
563
564        //      Debug.
565        cout    <<      "               M_GEOMETRY_VERTEX_BUFFER"
566                                <<      endl;
567
568        element =       2;
569        writeShorts(element,1);
570       
571        element =       8;
572        writeShorts(element,1);
573
574        //      Obtain the size for the vertex buffer data header for textures.
575        size    =       CHUNK_OVERHEAD_SIZE
576                                        +
577                                        ((sizeof(float) *       2)      *       vertexBuffer->mVertexCount);
578
579        //      Write the vertex buffer data header for textures.
580        writeChunkHeader(M_GEOMETRY_VERTEX_BUFFER_DATA, size);
581
582        //      Debug.
583        cout    <<      "               M_GEOMETRY_VERTEX_BUFFER_DATA"
584                                <<      endl;
585
586        //      Write all the texture coords.
587        mSerializer->WriteArray(vertexBuffer->mTexCoords,
588                                                                                                        vertexBuffer->mVertexCount);
589}
590
591//-------------------------------------------------------------------------
592//      Write Mesh Bounds.
593//-------------------------------------------------------------------------
594void    GeoMeshSaver::writeMeshBounds(Mesh      *geoMesh)
595{
596        size_t  size;
597
598        size    =       CHUNK_OVERHEAD_SIZE
599                                        +
600                                        (sizeof(float)  *       7);
601
602        writeChunkHeader(M_MESH_BOUNDS, (unsigned long)size);
603
604        //      Debug.
605        cout    <<      "               M_MESH_BOUNDS"
606                                <<      endl;
607
608        writeFloats(geoMesh->mMeshBounds.minX,1);
609        writeFloats(geoMesh->mMeshBounds.minY,1);
610        writeFloats(geoMesh->mMeshBounds.minZ,1);
611        writeFloats(geoMesh->mMeshBounds.maxX,1);
612        writeFloats(geoMesh->mMeshBounds.maxY,1);
613        writeFloats(geoMesh->mMeshBounds.maxZ,1);
614        writeFloats(geoMesh->mMeshBounds.radius,1);
615}
616
617//-------------------------------------------------------------------------
618//      Calculate the mesh size in bytes.
619//-------------------------------------------------------------------------
620size_t GeoMeshSaver::calcMeshSize(const Mesh    *geoMesh)
621{
622        size_t size = CHUNK_OVERHEAD_SIZE;
623
624        // Number of shared vertices
625        size += sizeof(uint32);
626
627        // Geometry
628        if (geoMesh->mVertexBuffer->mVertexCount > 0)
629        {
630                size += calcGeometrySize(geoMesh->mVertexBuffer);
631        }
632
633        // Submeshes
634        for (unsigned short i = 0; i < geoMesh->mSubMeshCount; ++i)
635        {
636                size += calcSubMeshSize(&geoMesh->mSubMesh[i]);
637        }
638
639        //      Mesh Bounds size added.
640        size    +=      CHUNK_OVERHEAD_SIZE
641                                                +
642                                                (sizeof(float)  *       7);
643
644        // Skeleton link
645        if (geoMesh->hasSkeleton)
646        {
647                size += calcSkeletonLinkSize(geoMesh);
648        }
649
650        /*
651        // Submesh name table
652        size += calcSubMeshNameTableSize(geoMesh);
653
654        // Edge list
655        if (geoMesh->isEdgeListBuilt())
656        {
657                size += calcEdgeListSize(geoMesh);
658        }
659        */
660       
661        return size;
662}
663
664//-------------------------------------------------------------------------
665//      Calc the size in bytes for the submesh.
666//-------------------------------------------------------------------------
667size_t GeoMeshSaver::calcSubMeshSize(const SubMesh      *geoSubMesh)
668{
669        size_t size = CHUNK_OVERHEAD_SIZE;
670
671        // Material name
672        size += strlen(geoSubMesh->mMaterialName);
673
674        // bool useSharedVertices
675        size += sizeof(bool);
676        // unsigned int indexCount
677        size += sizeof(unsigned int);
678        // bool indexes32bit
679        size += sizeof(bool);
680
681        // unsigned int* faceVertexIndices
682        size += sizeof(unsigned int) * geoSubMesh->mIndexCount;
683
684        // Geometry
685        if (!geoSubMesh->mSharedVertexBuffer)
686        {
687                size += calcGeometrySize(geoSubMesh->mVertexBuffer);
688        }
689
690        return size;
691}
692
693//-------------------------------------------------------------------------
694//      Calculate the geometry size in bytes.
695//-------------------------------------------------------------------------
696size_t GeoMeshSaver::calcGeometrySize(const VertexBuffer* vertexBuffer)
697{
698        unsigned        long            size;
699        unsigned        long            buffer_count;
700
701        //      and another for normals.
702        buffer_count    =       3;
703
704        //      Calculate the size of the Geometry chunk.
705        size    =       CHUNK_OVERHEAD_SIZE     +       sizeof(unsigned int);
706        size    =       size
707                                        +
708                                        CHUNK_OVERHEAD_SIZE
709                                        +
710                                        buffer_count
711                                        *
712                                        (CHUNK_OVERHEAD_SIZE    +       (sizeof(unsigned short) *       5));
713        size    =       size
714                                        +
715                                        buffer_count
716                                        *
717                                        (       (CHUNK_OVERHEAD_SIZE            *       2)
718                                                +
719                                                (sizeof(unsigned short) *       2)
720                                                +
721                                                vertexBuffer->mVertexCount
722                                        );
723
724        return size;
725}
726
727//-------------------------------------------------------------------------
728//      Calculate the skeleton link size in bytes.
729//-------------------------------------------------------------------------
730size_t  GeoMeshSaver::calcSkeletonLinkSize(const Mesh   *geoMesh)
731{
732        size_t  size    =               CHUNK_OVERHEAD_SIZE;
733        size                                    +=      strlen(geoMesh->mSkeletonName);
734
735        //      Debug.
736        //cout  <<      "Length Skeleton Link: "
737        //                      <<      strlen(geoMesh->mSkeletonName)
738        //                      <<      endl;
739
740        return  size;
741}
742
743//-------------------------------------------------------------------------
744//      Write the file header.
745//-------------------------------------------------------------------------
746void GeoMeshSaver::writeFileHeader(void)
747{
748        String  mesh_version("[MeshSerializer_v1.30]\n");
749       
750        writeShorts(M_HEADER, 1);
751
752        writeString(mesh_version);
753
754}
755
756//-------------------------------------------------------------------------
757//      Write a header chunk given.
758//-------------------------------------------------------------------------
759void GeoMeshSaver::writeChunkHeader(unsigned short      id,
760                                                                                                                                                unsigned long           size)
761{
762        mSerializer->WriteData(&id,sizeof(unsigned short),1);
763        mSerializer->WriteData(&size,sizeof(unsigned long),1);
764}
765
766//-------------------------------------------------------------------------
767//      Write integers into the file.
768//-------------------------------------------------------------------------
769void    GeoMeshSaver::writeInts(unsigned long   id,
770                                                                                                                        unsigned long   count)
771{
772        mSerializer->WriteData(&id,sizeof(id),count);
773}
774
775//-------------------------------------------------------------------------
776//      Write shorts into the file
777//-------------------------------------------------------------------------
778void    GeoMeshSaver::writeShorts(unsigned short        id,
779                                                                                                                                unsigned long           count)
780{
781        mSerializer->WriteData(&id,sizeof(id),count);
782}
783
784//-------------------------------------------------------------------------
785//      Write float into the file.
786//-------------------------------------------------------------------------
787void    GeoMeshSaver::writeFloats(float                                         id,
788                                                                                                                                unsigned long           count)
789{
790        mSerializer->WriteData(&id,sizeof(id),count);
791}
792
793//-------------------------------------------------------------------------
794//      Write a string into the file.
795//-------------------------------------------------------------------------
796void GeoMeshSaver::writeString(const    String  &string)
797{
798        mSerializer->WriteData(string);
799}
800
801//-------------------------------------------------------------------------
802//      Write booleans into the file.
803//-------------------------------------------------------------------------
804void    GeoMeshSaver::writeBools(       const bool id,
805                                                                                                                                unsigned        long            count)
806{
807        mSerializer->WriteData(&id,sizeof(bool),count);
808}
809
810//-------------------------------------------------------------------------
811//      Write skeleton filename.
812//-------------------------------------------------------------------------
813void GeoMeshSaver::writeSkeletonLink(const String& skelName)
814{       
815        writeChunkHeader(       M_MESH_SKELETON_LINK,
816                                                                                (unsigned long)calcSkeletonLinkSize(mGeoMesh));
817
818        //      Debug.
819        cout    <<      "               M_MESH_SKELETON_LINK"
820                                <<      endl;
821
822        writeString(skelName);
823}
824
825//-------------------------------------------------------------------------
826//      Write bones assignmets.
827//-------------------------------------------------------------------------
828void GeoMeshSaver::writeMeshBoneAssignment(const VertexBoneAssignment& assign)
829{
830        size_t size = CHUNK_OVERHEAD_SIZE + sizeof(unsigned int) + sizeof(unsigned short)+ sizeof(float);
831
832        writeChunkHeader(M_MESH_BONE_ASSIGNMENT, (unsigned long)size);
833
834        // unsigned int vertexIndex;
835        writeInts(assign.vertexIndex, 1);
836        // unsigned short boneIndex;
837        writeShorts(assign.boneIndex, 1);
838        // float weight;
839        writeFloats(assign.weight, 1);
840}
841
842//-------------------------------------------------------------------------
843//      Write bones assignmets.
844//-------------------------------------------------------------------------
845void GeoMeshSaver::writeSubMeshBoneAssignment(const VertexBoneAssignment& assign)
846{
847        size_t size = CHUNK_OVERHEAD_SIZE + sizeof(unsigned int) + sizeof(unsigned short)+ sizeof(float);
848
849        writeChunkHeader(M_SUBMESH_BONE_ASSIGNMENT, (unsigned long)size);
850
851        // unsigned int vertexIndex;
852        writeInts(assign.vertexIndex, 1);
853        // unsigned short boneIndex;
854        writeShorts(assign.boneIndex, 1);
855        // float weight;
856        writeFloats(assign.weight, 1);
857}
858
859//-------------------------------------------------------------------------
860//      unnormalize geometry model.
861//-------------------------------------------------------------------------
862void    GeoMeshSaver::unnormalizeModel(Mesh     *geoMesh)
863{
864        float   maxx;
865        float   maxy;
866        float   maxz;
867        float   minx;
868        float   miny;
869        float   minz;
870        float   cx;
871        float   cy;
872        float   cz;
873        float   scale;
874       
875        VertexBuffer    *vertex_buffer;
876
877        maxx    =       geoMesh->mMeshBounds.maxX;
878        maxy    =       geoMesh->mMeshBounds.maxY;
879        maxz    =       geoMesh->mMeshBounds.maxZ;
880        minx    =       geoMesh->mMeshBounds.minX;
881        miny    =       geoMesh->mMeshBounds.minY;
882        minz    =       geoMesh->mMeshBounds.minZ;
883        scale   =       geoMesh->mMeshBounds.scaleFactor;
884       
885        //      Calculate center of the model.
886        cx = (maxx + minx) / 2.0f;
887        cy = (maxy + miny) / 2.0f;
888        cz = (maxz + minz) / 2.0f;
889
890        //      Translate around center then scale.
891        //      For each submesh.
892
893        bool sharedScaled       =       false;
894
895        for (size_t submesh = 0; submesh < geoMesh->mSubMeshCount; submesh++)
896        {
897                //      Gets the actual submesh.
898                vertex_buffer   =       geoMesh->mSubMesh[submesh].mVertexBuffer;
899
900                if (geoMesh->mSubMesh[submesh].mSharedVertexBuffer && sharedScaled)
901                {
902                        continue;
903                }
904
905                //      For each index of the strip.
906                for (size_t i = 0; i < vertex_buffer->mVertexCount; i++)
907                {
908                        vertex_buffer->mPosition[i].x /= scale;
909                        vertex_buffer->mPosition[i].y /= scale;
910                        vertex_buffer->mPosition[i].z /= scale;
911                        vertex_buffer->mPosition[i].x += cx;
912                        vertex_buffer->mPosition[i].y += cy;
913                        vertex_buffer->mPosition[i].z += cz;
914                }
915
916                //      If is a shared vertex Buffer.
917                if (geoMesh->mSubMesh[submesh].mSharedVertexBuffer)
918                {
919                        sharedScaled    =       true;
920                }
921        }
922}
923
Note: See TracBrowser for help on using the repository browser.