source: GTP/trunk/Lib/Geom/shared/GeoTool/src/GeoMeshSaver.cpp @ 1070

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