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

Revision 1017, 20.5 KB checked in by gumbau, 18 years ago (diff)

LodStripsConstructor? optimized and fixed bug building a lodtree

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