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

Revision 2341, 24.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                strcat(geoMesh->mSkeletonName,"\n");
184
185                // Write skeleton link
186                writeSkeletonLink(geoMesh->mSkeletonName);
187
188                // Write bone assignments
189                if (!geoMesh->mBones.empty())
190                {
191
192                        for (size_t i = 0; i< geoMesh->mBones.size(); i++)
193                        {
194                                writeMeshBoneAssignment(geoMesh->mBones[i]);
195                        }
196
197                }
198        }
199
200        //      Write the mesh bounds.
201        writeMeshBounds(geoMesh);
202
203        // Write submesh name table.
204        writeSubMeshNameTable(geoMesh);
205
206        /*
207        // Write LOD data if any
208        if (pMesh->getNumLodLevels() > 1)
209        {
210        LogManager::getSingleton().logMessage("Exporting LOD information....");
211        writeLodInfo(pMesh);
212        LogManager::getSingleton().logMessage("LOD information exported.");
213
214        }
215        // Write bounds information
216        LogManager::getSingleton().logMessage("Exporting bounds information....");
217        writeBoundsInfo(pMesh);
218        LogManager::getSingleton().logMessage("Bounds information 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// Write submesh name table.
619//-------------------------------------------------------------------------
620void    GeoMeshSaver::writeSubMeshNameTable(Mesh        *geoMesh)
621{
622        size_t  size;
623        size_t  names_size;
624
625        //      Size of the names of the submeshes.
626        names_size      =       0;
627
628        //      For each submesh.
629        for (size_t     i = 0; i < geoMesh->mSubMeshCount;      i++)
630        {
631                names_size      =       strlen(geoMesh->mSubMesh[i].mName);
632        }
633
634        size    =       CHUNK_OVERHEAD_SIZE
635                                        +
636                                        names_size
637                                        +
638                                        (CHUNK_OVERHEAD_SIZE + sizeof(short)) * geoMesh->mSubMeshCount;
639
640        writeChunkHeader(M_SUBMESH_NAME_TABLE, (unsigned long)size);
641
642        //      For each submesh.
643        for (size_t     i = 0;  i < geoMesh->mSubMeshCount;     i++)
644        {
645                size    =       CHUNK_OVERHEAD_SIZE
646                                                +
647                                                sizeof(short)
648                                                +
649                                                strlen(geoMesh->mSubMesh[i].mName);
650
651                writeChunkHeader(M_SUBMESH_NAME_TABLE_ELEMENT, (unsigned long)size);
652
653                writeShorts(i, 1);
654
655                strcat(geoMesh->mSubMesh[i].mName,"\n");
656                mSerializer->WriteData(geoMesh->mSubMesh[i].mName);
657        }
658}
659
660//-------------------------------------------------------------------------
661//      Calculate the mesh size in bytes.
662//-------------------------------------------------------------------------
663size_t GeoMeshSaver::calcMeshSize(const Mesh    *geoMesh)
664{
665        size_t size = CHUNK_OVERHEAD_SIZE;
666
667        // Number of shared vertices
668        size += sizeof(uint32);
669
670        // Geometry
671        if (geoMesh->mVertexBuffer->mVertexCount > 0)
672        {
673                size += calcGeometrySize(geoMesh->mVertexBuffer);
674        }
675
676        // Submeshes
677        for (unsigned short i = 0; i < geoMesh->mSubMeshCount; ++i)
678        {
679                size += calcSubMeshSize(&geoMesh->mSubMesh[i]);
680        }
681
682        //      Mesh Bounds size added.
683        size    +=      CHUNK_OVERHEAD_SIZE
684                                                +
685                                                (sizeof(float)  *       7);
686
687        // Skeleton link
688        if (geoMesh->hasSkeleton)
689        {
690                size += calcSkeletonLinkSize(geoMesh);
691        }
692
693        /*
694        // Submesh name table
695        size += calcSubMeshNameTableSize(geoMesh);
696
697        // Edge list
698        if (geoMesh->isEdgeListBuilt())
699        {
700                size += calcEdgeListSize(geoMesh);
701        }
702        */
703       
704        return size;
705}
706
707//-------------------------------------------------------------------------
708//      Calc the size in bytes for the submesh.
709//-------------------------------------------------------------------------
710size_t GeoMeshSaver::calcSubMeshSize(const SubMesh      *geoSubMesh)
711{
712        size_t size = CHUNK_OVERHEAD_SIZE;
713
714        // Material name
715        size += strlen(geoSubMesh->mMaterialName);
716
717        // bool useSharedVertices
718        size += sizeof(bool);
719        // unsigned int indexCount
720        size += sizeof(unsigned int);
721        // bool indexes32bit
722        size += sizeof(bool);
723
724        // unsigned int* faceVertexIndices
725        size += sizeof(unsigned int) * geoSubMesh->mIndexCount;
726
727        // Geometry
728        if (!geoSubMesh->mSharedVertexBuffer)
729        {
730                size += calcGeometrySize(geoSubMesh->mVertexBuffer);
731        }
732
733        return size;
734}
735
736//-------------------------------------------------------------------------
737//      Calculate the geometry size in bytes.
738//-------------------------------------------------------------------------
739size_t GeoMeshSaver::calcGeometrySize(const VertexBuffer* vertexBuffer)
740{
741        unsigned        long            size;
742        unsigned        long            buffer_count;
743
744        //      and another for normals.
745        buffer_count    =       3;
746
747        //      Calculate the size of the Geometry chunk.
748        size    =       CHUNK_OVERHEAD_SIZE     +       sizeof(unsigned int);
749        size    =       size
750                                        +
751                                        CHUNK_OVERHEAD_SIZE
752                                        +
753                                        buffer_count
754                                        *
755                                        (CHUNK_OVERHEAD_SIZE    +       (sizeof(unsigned short) *       5));
756        size    =       size
757                                        +
758                                        buffer_count
759                                        *
760                                        (       (CHUNK_OVERHEAD_SIZE            *       2)
761                                                +
762                                                (sizeof(unsigned short) *       2)
763                                                +
764                                                vertexBuffer->mVertexCount
765                                        );
766
767        return size;
768}
769
770//-------------------------------------------------------------------------
771//      Calculate the skeleton link size in bytes.
772//-------------------------------------------------------------------------
773size_t  GeoMeshSaver::calcSkeletonLinkSize(const Mesh   *geoMesh)
774{
775        size_t  size    =               CHUNK_OVERHEAD_SIZE;
776        size                                    +=      strlen(geoMesh->mSkeletonName);
777
778        //      Debug.
779        //cout  <<      "Length Skeleton Link: "
780        //                      <<      strlen(geoMesh->mSkeletonName)
781        //                      <<      endl;
782
783        return  size;
784}
785
786//-------------------------------------------------------------------------
787//      Write the file header.
788//-------------------------------------------------------------------------
789void GeoMeshSaver::writeFileHeader(void)
790{
791        String  mesh_version("[MeshSerializer_v1.30]\n");
792       
793        writeShorts(M_HEADER, 1);
794
795        writeString(mesh_version);
796}
797
798//-------------------------------------------------------------------------
799//      Write a header chunk given.
800//-------------------------------------------------------------------------
801void GeoMeshSaver::writeChunkHeader(unsigned short      id,
802                                                                                                                                                unsigned long           size)
803{
804        mSerializer->WriteData(&id,sizeof(unsigned short),1);
805        mSerializer->WriteData(&size,sizeof(unsigned long),1);
806}
807
808//-------------------------------------------------------------------------
809//      Write integers into the file.
810//-------------------------------------------------------------------------
811void    GeoMeshSaver::writeInts(unsigned long   id,
812                                                                                                                        unsigned long   count)
813{
814        mSerializer->WriteData(&id,sizeof(id),count);
815}
816
817//-------------------------------------------------------------------------
818//      Write shorts into the file
819//-------------------------------------------------------------------------
820void    GeoMeshSaver::writeShorts(unsigned short        id,
821                                                                                                                                unsigned long           count)
822{
823        mSerializer->WriteData(&id,sizeof(id),count);
824}
825
826//-------------------------------------------------------------------------
827//      Write float into the file.
828//-------------------------------------------------------------------------
829void    GeoMeshSaver::writeFloats(float                                         id,
830                                                                                                                                unsigned long           count)
831{
832        mSerializer->WriteData(&id,sizeof(id),count);
833}
834
835//-------------------------------------------------------------------------
836//      Write a string into the file.
837//-------------------------------------------------------------------------
838void GeoMeshSaver::writeString(const    String  &string)
839{
840        mSerializer->WriteData(string);
841}
842
843//-------------------------------------------------------------------------
844//      Write booleans into the file.
845//-------------------------------------------------------------------------
846void    GeoMeshSaver::writeBools(       const bool id,
847                                                                                                                                unsigned        long            count)
848{
849        mSerializer->WriteData(&id,sizeof(bool),count);
850}
851
852//-------------------------------------------------------------------------
853//      Write skeleton filename.
854//-------------------------------------------------------------------------
855void GeoMeshSaver::writeSkeletonLink(const String& skelName)
856{       
857        writeChunkHeader(       M_MESH_SKELETON_LINK,
858                                                                                (unsigned long)calcSkeletonLinkSize(mGeoMesh));
859
860        //      Debug.
861        cout    <<      "               M_MESH_SKELETON_LINK"
862                                <<      endl;
863
864        writeString(skelName);
865}
866
867//-------------------------------------------------------------------------
868//      Write bones assignmets.
869//-------------------------------------------------------------------------
870void GeoMeshSaver::writeMeshBoneAssignment(const VertexBoneAssignment& assign)
871{
872        size_t size = CHUNK_OVERHEAD_SIZE + sizeof(unsigned int) + sizeof(unsigned short)+ sizeof(float);
873
874        writeChunkHeader(M_MESH_BONE_ASSIGNMENT, (unsigned long)size);
875
876        // unsigned int vertexIndex;
877        writeInts(assign.vertexIndex, 1);
878        // unsigned short boneIndex;
879        writeShorts(assign.boneIndex, 1);
880        // float weight;
881        writeFloats(assign.weight, 1);
882}
883
884//-------------------------------------------------------------------------
885//      Write bones assignmets.
886//-------------------------------------------------------------------------
887void GeoMeshSaver::writeSubMeshBoneAssignment(const VertexBoneAssignment& assign)
888{
889        size_t size = CHUNK_OVERHEAD_SIZE + sizeof(unsigned int) + sizeof(unsigned short)+ sizeof(float);
890
891        writeChunkHeader(M_SUBMESH_BONE_ASSIGNMENT, (unsigned long)size);
892
893        // unsigned int vertexIndex;
894        writeInts(assign.vertexIndex, 1);
895        // unsigned short boneIndex;
896        writeShorts(assign.boneIndex, 1);
897        // float weight;
898        writeFloats(assign.weight, 1);
899}
900
901//-------------------------------------------------------------------------
902//      unnormalize geometry model.
903//-------------------------------------------------------------------------
904void    GeoMeshSaver::unnormalizeModel(Mesh     *geoMesh)
905{
906        float   maxx;
907        float   maxy;
908        float   maxz;
909        float   minx;
910        float   miny;
911        float   minz;
912        float   cx;
913        float   cy;
914        float   cz;
915        float   scale;
916       
917        VertexBuffer    *vertex_buffer;
918
919        maxx    =       geoMesh->mMeshBounds.maxX;
920        maxy    =       geoMesh->mMeshBounds.maxY;
921        maxz    =       geoMesh->mMeshBounds.maxZ;
922        minx    =       geoMesh->mMeshBounds.minX;
923        miny    =       geoMesh->mMeshBounds.minY;
924        minz    =       geoMesh->mMeshBounds.minZ;
925        scale   =       geoMesh->mMeshBounds.scaleFactor;
926       
927        //      Calculate center of the model.
928        cx = (maxx + minx) / 2.0f;
929        cy = (maxy + miny) / 2.0f;
930        cz = (maxz + minz) / 2.0f;
931
932        //      Translate around center then scale.
933        //      For each submesh.
934
935        bool sharedScaled       =       false;
936
937        for (size_t submesh = 0; submesh < geoMesh->mSubMeshCount; submesh++)
938        {
939                //      Gets the actual submesh.
940                vertex_buffer   =       geoMesh->mSubMesh[submesh].mVertexBuffer;
941
942                if (geoMesh->mSubMesh[submesh].mSharedVertexBuffer && sharedScaled)
943                {
944                        continue;
945                }
946
947                //      For each index of the strip.
948                for (size_t i = 0; i < vertex_buffer->mVertexCount; i++)
949                {
950                        vertex_buffer->mPosition[i].x /= scale;
951                        vertex_buffer->mPosition[i].y /= scale;
952                        vertex_buffer->mPosition[i].z /= scale;
953                        vertex_buffer->mPosition[i].x += cx;
954                        vertex_buffer->mPosition[i].y += cy;
955                        vertex_buffer->mPosition[i].z += cz;
956                }
957
958                //      If is a shared vertex Buffer.
959                if (geoMesh->mSubMesh[submesh].mSharedVertexBuffer)
960                {
961                        sharedScaled    =       true;
962                }
963        }
964}
965
Note: See TracBrowser for help on using the repository browser.