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

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