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

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