source: OGRE/trunk/ogrenew/Tools/LightwaveConverter/src/lwo2mesh.cpp @ 657

Revision 657, 20.5 KB checked in by mattausch, 19 years ago (diff)

added ogre dependencies and patched ogre sources

Line 
1#include "Vector3.h"
2#include "lwo2mesh.h"
3#include "Ogre.h"
4#include "OgreMesh.h"
5#include "OgreStringConverter.h"
6#include "OgreDefaultHardwareBufferManager.h"
7
8#if OGRE_PLATFORM == OGRE_PLATFORM_LINUX
9#include <math.h>
10#include <float.h>  // FLT_MIN, FLT_MAX
11#include <libgen.h> // dirname(), basename().
12#include <string.h> // strtok();
13#include <string>   // string class
14#endif
15
16#define POLYLIMIT 0x5555
17#define POINTLIMIT 0x5555
18
19extern Mesh::LodDistanceList distanceList;
20extern Real reduction;
21extern bool flags[NUMFLAGS];
22extern MaterialSerializer* materialSerializer;
23extern char *matPrefix;
24
25extern ostream& nl(ostream& os);
26
27#if OGRE_PLATFORM == OGRE_PLATFORM_LINUX
28
29/* We expect the caller to provide an arrays of chars for the output. */
30void _splitpath( const char *_fn, char *_drive, char *_dir, char *_node, char *_ext ) {
31       
32   /* A crazy mix of both c and c++.. */
33       
34   const char *delimiters = ".";
35   char buf[ _MAX_DRIVE+_MAX_DIR+_MAX_FNAME+_MAX_EXT + 5 ];
36   char *exte, *ddir, *fnam, *_ext_tmp;
37
38   strcpy( buf, _fn );
39   strcpy( _drive, "" ); // _drive is always empth on linux.
40
41   if ( String( buf ).empty() ) {
42       strcpy( _node, "" );
43       strcpy( _dir, "" );
44       strcpy( _ext, "" );
45       return;
46   }
47   
48   fnam = basename( buf );
49   strcpy( _node, fnam );
50   ddir = dirname( buf );
51   strcpy( _dir, ddir );
52   
53   _ext_tmp = strtok( fnam, delimiters );
54   while ( ( _ext_tmp = strtok( NULL, delimiters ) ) != NULL ) exte = _ext_tmp;
55   strcpy( _ext, exte );
56
57   _node[ strlen(_node) - strlen(_ext) - 1 ] = '\0';
58
59}
60
61/* We expect the caller to provide an array of chars for the output. */
62void _makepath( char *_fn, const char *_drive, const char *_dir,
63       const char *_node, const char *_ext ) {
64   
65   /* A crazy mix of both c and c++.. */
66
67   std::string buf("");
68
69   if ( _drive != NULL ) // On Linux, this is usually empty.
70       buf += _drive;
71       
72   if ( _dir != NULL ) { // The directory part.
73       if ( std::string(_dir).empty() )
74           buf += ".";
75       buf += _dir;
76       buf += "/";
77   }
78   
79   if ( _node != NULL ) // The filename without the extension.
80       buf += _node;
81   
82   if ( _ext != NULL ) { // The extension.
83       if ( std::string( _ext ).compare( 0, 1, "." ) != 0 )
84           buf += ".";
85       buf += _ext;
86   }
87
88   strcpy( _fn, buf.c_str() );
89}
90
91#endif
92
93void Lwo2MeshWriter::doExportMaterials()
94{
95        char
96                drive[ _MAX_DRIVE ],
97                dir[ _MAX_DIR ],
98                node[ _MAX_FNAME ],
99                ext[ _MAX_EXT ],
100                texname [128];
101
102        unsigned int slength = 0;
103
104        if (flags[RenameMaterials])
105        {
106                if (flags[UseInteractiveMethod])
107                {
108                        for (unsigned int i = 0; i < object->surfaces.size(); ++i)
109                        {               
110                                lwSurface *surface = object->surfaces[i];
111                                cout << "Rename surface " << surface->name << " to: ";
112                                cin >> texname;
113                                surface->setname(texname);
114                        }
115                } else {
116                        _splitpath( dest, drive, dir, node, ext );
117
118                        for (unsigned int i = 0; i < object->surfaces.size(); ++i)
119                        {
120                                lwSurface *surface = object->surfaces[i];
121                                if (flags[UsePrefixMethod])
122                                        strcpy(texname,matPrefix);
123                                else
124                                {
125                                        strcpy(texname,node);
126                                        strcat(texname,"_");
127                                }
128
129                                strcat(texname, surface->name);
130                                surface->setname(texname);
131                        }
132                }
133        }
134
135        for (unsigned int i = 0; i < object->surfaces.size(); ++i)
136        {               
137                lwSurface *surface = object->surfaces[i];
138
139                // Create deferred material so no load
140                MaterialPtr ogreMat = MaterialManager::getSingleton().getByName(surface->name);
141               
142                if (!ogreMat)
143                {
144                        ogreMat = MaterialManager::getSingleton().create(surface->name,
145                ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
146                       
147                        ogreMat->setAmbient
148                        (
149                                surface->color.rgb[0],
150                                surface->color.rgb[1],
151                                surface->color.rgb[2]
152                        );
153                       
154                        ogreMat->setDiffuse
155                        (
156                                surface->diffuse.val * surface->color.rgb[0],
157                                surface->diffuse.val * surface->color.rgb[1],
158                                surface->diffuse.val * surface->color.rgb[2],
159                                1.0f
160                        );
161                       
162                        ogreMat->setSpecular
163                        (
164                                surface->specularity.val * surface->color.rgb[0],
165                                surface->specularity.val * surface->color.rgb[1],
166                                surface->specularity.val * surface->color.rgb[2],
167                                1.0f
168                        );
169                       
170                        ogreMat->setShininess(surface->glossiness.val);
171                       
172                        ogreMat->setSelfIllumination
173                        (
174                                surface->luminosity.val * surface->color.rgb[0],
175                                surface->luminosity.val * surface->color.rgb[1],
176                                surface->luminosity.val * surface->color.rgb[2]
177                        );
178                       
179                        for (unsigned int j = 0; j < surface->color.textures.size(); j++)
180                        {
181                                lwTexture *tex = surface->color.textures[j];
182                                int cindex = tex->param.imap->cindex;
183                                lwClip *clip = object->lwFindClip(cindex);
184                               
185                                if (clip)
186                                {
187                                        _splitpath( clip->source.still->name, drive, dir, node, ext );
188                                        _makepath( texname, 0, 0, node, ext );                                 
189                                        ogreMat->getTechnique(0)->getPass(0)->createTextureUnitState(texname);
190                                }
191                        }                       
192                        materialSerializer->queueForExport(ogreMat);
193                }
194        }
195}
196
197Skeleton *Lwo2MeshWriter::doExportSkeleton(const String &skelName, int l)
198{
199        vpolygons bones;
200        bones.clear();
201        bones.reserve(256);
202
203        vpoints bonepoints;
204        bonepoints.clear();
205        bonepoints.reserve(512);
206
207        if (l == -1)
208        {
209                for (l = 0; l < object->layers.size(); ++l)
210                {
211                        copyPoints(-1, ID_BONE, object->layers[l]->points, bonepoints);
212                        copyPolygons(-1, ID_BONE, object->layers[l]->polygons, bones);
213                }
214        }
215        else
216        {
217                copyPoints(-1, ID_BONE, object->layers[l]->points, bonepoints);
218                copyPolygons(-1, ID_BONE, object->layers[l]->polygons, bones);
219        }
220
221        if (!bones.size()) return NULL; // no bones means no skeleton
222
223        Skeleton *ogreskel = new Skeleton(skelName);
224
225        unsigned int i;
226        // Create all the bones in turn
227        for (i = 0; i < bones.size(); ++i)
228        {
229                lwPolygon* bone = bones[i];
230                if (bone->vertices.size() != 2) continue; // a bone has only 2 sides
231
232                Bone* ogreBone = ogreskel->createBone("Bone");
233
234                Ogre::Vector3 bonePos(bone->vertices[0]->point->x, bone->vertices[0]->point->y, bone->vertices[0]->point->z);
235
236                ogreBone->setPosition(bonePos);
237                // Hmm, Milkshape has chosen a Euler angle representation of orientation which is not smart
238                // Rotation Matrix or Quaternion would have been the smarter choice
239                // Might we have Gimbal lock here? What order are these 3 angles supposed to be applied?
240                // Grr, we'll try our best anyway...
241                Quaternion qx, qy, qz, qfinal;
242/*
243                qx.FromAngleAxis(msBoneRot[0], Vector3::UNIT_X);
244                qy.FromAngleAxis(msBoneRot[1], Vector3::UNIT_Y);
245                qz.FromAngleAxis(msBoneRot[2], Vector3::UNIT_Z);
246*/
247                // Assume rotate by x then y then z
248                qfinal = qz * qy * qx;
249                ogreBone->setOrientation(qfinal);
250        }
251/*
252        for (i = 0; i < numBones; ++i)
253        {
254                msBone* bone = msModel_GetBoneAt(pModel, i);
255
256                if (strlen(bone->szParentName) == 0)
257                {
258                }
259                else
260                {
261                        Bone* ogrechild = ogreskel->getBone(bone->szName);
262                        Bone* ogreparent = ogreskel->getBone(bone->szParentName);
263
264                        if (ogrechild == 0)
265                        {
266                                continue;
267                        }
268                        if (ogreparent == 0)
269                        {
270                                continue;
271                        }
272                        // Make child
273                        ogreparent->addChild(ogrechild);
274                }
275
276
277        }
278
279        // Create the Animation(s)
280        doExportAnimations(pModel, ogreskel);
281
282        // Create skeleton serializer & export
283        SkeletonSerializer serializer;
284        serializer.exportSkeleton(ogreskel, szFile);
285
286        ogreMesh->_notifySkeleton(ogreskel);
287
288        return ogreskel;
289*/
290        delete ogreskel;
291        return NULL;
292}
293
294#define POSITION_BINDING 0
295#define NORMAL_BINDING 1
296#define TEXCOORD_BINDING 2
297
298VertexData *Lwo2MeshWriter::setupVertexData(unsigned short vertexCount, VertexData *oldVertexData, bool deleteOldVertexData)
299{
300        VertexData *vertexData = new VertexData();
301
302        if (oldVertexData)
303        {
304        // Basic vertex info
305        vertexData->vertexStart = oldVertexData->vertexStart;
306                vertexData->vertexCount = oldVertexData->vertexCount + vertexCount;
307
308                const VertexBufferBinding::VertexBufferBindingMap bindings = oldVertexData->vertexBufferBinding->getBindings();
309                VertexBufferBinding::VertexBufferBindingMap::const_iterator vbi, vbend;
310                vbend = bindings.end();
311
312                for (vbi = bindings.begin(); vbi != vbend; ++vbi)
313                {
314                        HardwareVertexBufferSharedPtr srcbuf = vbi->second;
315                        // create new buffer with the same settings
316                        HardwareVertexBufferSharedPtr dstBuf =
317                                HardwareBufferManager::getSingleton().createVertexBuffer(
318                                        srcbuf->getVertexSize(), srcbuf->getNumVertices() + vertexCount, srcbuf->getUsage(), srcbuf->isSystemMemory());
319
320                        // copy data
321                        dstBuf->copyData(*srcbuf, 0, 0, srcbuf->getSizeInBytes(), true);
322
323                        // Copy binding
324                        vertexData->vertexBufferBinding->setBinding(vbi->first, dstBuf);
325                }
326
327        // Copy elements
328        const VertexDeclaration::VertexElementList elems = oldVertexData->vertexDeclaration->getElements();
329        VertexDeclaration::VertexElementList::const_iterator ei, eiend;
330        eiend = elems.end();
331        for (ei = elems.begin(); ei != eiend; ++ei)
332        {
333            vertexData->vertexDeclaration->addElement(
334                ei->getSource(),
335                ei->getOffset(),
336                ei->getType(),
337                ei->getSemantic(),
338                ei->getIndex() );
339        }
340                if (deleteOldVertexData) delete oldVertexData;
341        }
342        else
343        {
344                vertexData->vertexCount = vertexCount;
345               
346                VertexBufferBinding* bind = vertexData->vertexBufferBinding;
347                VertexDeclaration* decl = vertexData->vertexDeclaration;
348               
349                decl->addElement(POSITION_BINDING, 0, VET_FLOAT3, VES_POSITION);
350                HardwareVertexBufferSharedPtr pbuf = HardwareBufferManager::getSingleton().createVertexBuffer(decl->getVertexSize(POSITION_BINDING), vertexData->vertexCount, HardwareBuffer::HBU_DYNAMIC, false);
351                bind->setBinding(POSITION_BINDING, pbuf);
352               
353                decl->addElement(NORMAL_BINDING, 0, VET_FLOAT3, VES_NORMAL);
354                HardwareVertexBufferSharedPtr nbuf = HardwareBufferManager::getSingleton().createVertexBuffer(decl->getVertexSize(NORMAL_BINDING), vertexData->vertexCount, HardwareBuffer::HBU_DYNAMIC, false);
355                bind->setBinding(NORMAL_BINDING, nbuf);
356               
357                decl->addElement(TEXCOORD_BINDING, 0, VET_FLOAT2, VES_TEXTURE_COORDINATES);
358                HardwareVertexBufferSharedPtr tbuf = HardwareBufferManager::getSingleton().createVertexBuffer(decl->getVertexSize(TEXCOORD_BINDING), vertexData->vertexCount, HardwareBuffer::HBU_DYNAMIC, false);
359                bind->setBinding(TEXCOORD_BINDING, tbuf);
360        }       
361        return vertexData;
362}
363
364void Lwo2MeshWriter::copyPoints(int surfaceIndex, unsigned long polygontype, vpoints &sourcepoints, vpoints &destpoints)
365{
366        for (unsigned int i = 0; i < sourcepoints.size(); i++)
367        {
368                lwPoint *point = sourcepoints[i];
369               
370                for (unsigned int j = 0; j < point->polygons.size(); j++)
371                {
372                        lwPolygon *polygon = point->polygons[j];
373                        if (polygon->type == polygontype)
374                                if (surfaceIndex == -1 || surfaceIndex == polygon->surfidx)
375                                {
376                                        destpoints.push_back(point);
377                                        break;
378                                }
379                }
380        }
381}
382
383void Lwo2MeshWriter::copyPolygons(int surfaceIndex, unsigned long polygontype, vpolygons &sourcepolygons, vpolygons &destpolygons)
384{
385        for (unsigned int i = 0; i < sourcepolygons.size(); i++)
386        {
387                lwPolygon *polygon = sourcepolygons[i];
388                if (polygon->type == polygontype)
389                        if (surfaceIndex == -1 || surfaceIndex == polygon->surfidx)
390                                destpolygons.push_back(polygon);
391        }
392}
393
394void Lwo2MeshWriter::copyDataToVertexData(vpoints &points,
395                                                                                vpolygons &polygons,
396                                                                                vvmaps &vmaps,
397                                                                                IndexData *indexData,
398                                                                                VertexData *vertexData,
399                                                                                unsigned short vertexDataOffset)
400{
401        lwVMap *vmap = 0;
402        unsigned int ni;
403       
404        HardwareVertexBufferSharedPtr pbuf = vertexData->vertexBufferBinding->getBuffer(POSITION_BINDING);
405        HardwareVertexBufferSharedPtr nbuf = vertexData->vertexBufferBinding->getBuffer(NORMAL_BINDING);
406        HardwareVertexBufferSharedPtr tbuf = vertexData->vertexBufferBinding->getBuffer(TEXCOORD_BINDING);
407        HardwareIndexBufferSharedPtr ibuf = indexData->indexBuffer;
408
409        float* pPos = static_cast<float*>(pbuf->lock(HardwareBuffer::HBL_DISCARD));
410        float* pNor = static_cast<float*>(nbuf->lock(HardwareBuffer::HBL_DISCARD));
411        float* pTex = static_cast<float*>(tbuf->lock(HardwareBuffer::HBL_DISCARD));
412        unsigned short *pIdx = static_cast<unsigned short*>(ibuf->lock(HardwareBuffer::HBL_DISCARD));
413
414        for (unsigned int p = 0; p < polygons.size(); p++)
415        {
416                lwPolygon *polygon = polygons[p];
417               
418                if (polygon->vertices.size() != 3) continue; // only copy triangles;
419
420                for (unsigned int v = 0; v < polygon->vertices.size(); v++)
421                {
422                        lwVertex *vertex = polygon->vertices[v];
423                        lwPoint *point = vertex->point;
424                        unsigned short i = getPointIndex(point, points);
425
426                        pIdx[p*3 + v] = vertexDataOffset + i;
427                       
428                        ni = (vertexDataOffset + i) * 3;
429                       
430                        pPos[ni] = vertex->point->x;
431                        pPos[ni + 1] = vertex->point->y;
432                        pPos[ni + 2] = vertex->point->z;
433                       
434                        pNor[ni] = vertex->normal.x;
435                        pNor[ni + 1] = vertex->normal.y;
436                        pNor[ni + 2] = vertex->normal.z;
437                       
438                        bool found = false;
439                       
440                        ni = (vertexDataOffset + i) * 2;
441                       
442                        for (unsigned int v = 0; v < point->vmaps.size(); v++)
443                        {
444                                for (unsigned int vr = 0; vr < vmaps.size(); vr++)
445                                {
446                                        vmap = vmaps[vr];
447                                        if (point->vmaps[v].vmap == vmap)
448                                        {
449                                                int n = point->vmaps[v].index;
450                                               
451                                                pTex[ni] = vmap->val[n][0];
452                                                pTex[ni + 1] = 1.0f - vmap->val[n][1];
453                                                found = true;
454                                                break;
455                                        }
456                                }
457                                if (found) break;
458                        }
459                }
460        }
461    pbuf->unlock();
462    nbuf->unlock();
463    tbuf->unlock();
464        ibuf->unlock();
465}
466
467void Lwo2MeshWriter::prepLwObject(void)
468{
469        unsigned int l, p;
470       
471        for (l = 0; l < object->layers.size(); l++)
472        {
473                lwLayer *layer = object->layers[l];
474               
475#ifdef _DEBUG
476                cout << "Triangulating layer " << l << ", Polygons before: " << layer->polygons.size();
477#endif
478                layer->triangulatePolygons();
479#ifdef _DEBUG
480                cout << ", Polygons after: " << layer->polygons.size() << endl;
481#endif
482               
483                // Mirror x-coord for Ogre;
484                for (p = 0; p < layer->points.size(); p++)
485                {
486                        layer->points[p]->x *= -1.0f;
487                        layer->points[p]->polygons.clear();
488                }
489                // Unscrew the bounding box
490                float x = layer->bboxmin.x * -1.0f;
491                layer->bboxmin.x = layer->bboxmax.x * -1.0f;
492                layer->bboxmax.x = x;
493               
494                for ( p = 0; p < layer->polygons.size(); p++ )
495                {
496                        lwPolygon *polygon = layer->polygons[ p ];
497                        for (unsigned int j = 0; j < polygon->vertices.size(); j++ )
498                                polygon->vertices[ j ]->point->polygons.push_back(polygon);
499                }       
500               
501                for (p = 0; p < layer->polygons.size(); p++)
502                        layer->polygons[p]->flip();
503               
504                layer->calculatePolygonNormals();
505                layer->calculateVertexNormals();
506        }
507}
508
509inline int Lwo2MeshWriter::getPointIndex(lwPoint *point, vpoints &points)
510{
511        for (unsigned int i = 0; i < points.size(); ++i)
512                if (points[i] == point) return i;
513               
514        return -1;
515}
516
517inline String Lwo2MeshWriter::makeLayerFileName(char* dest, unsigned int l, char *layername)
518{
519        char
520                drive[ _MAX_DRIVE ],
521                dir[ _MAX_DIR ],
522                node[ _MAX_FNAME ],
523                ext[ _MAX_EXT ],
524                buf[ _MAX_DRIVE + _MAX_DIR + _MAX_FNAME + _MAX_EXT + 5 ];
525
526        String LayerFileName;
527        String TempName;
528
529        _splitpath( dest, drive, dir, node, ext );
530
531        TempName = String( node );
532   
533        if (layername) {
534                TempName += ".";
535                TempName += layername;
536        } else {
537                TempName += ".layer" + StringConverter::toString(l);
538        }
539
540        _makepath( buf, drive, dir, TempName.c_str(), ext );
541        LayerFileName = String( buf );
542
543        return LayerFileName;
544}
545
546inline String Lwo2MeshWriter::makeMaterialFileName(char* dest)
547{
548        char
549                drive[ _MAX_DRIVE ],
550                dir[ _MAX_DIR ],
551                node[ _MAX_FNAME ],
552                ext[ _MAX_EXT ],
553                buf[ _MAX_DRIVE + _MAX_DIR + _MAX_FNAME + _MAX_EXT + 5 ];
554
555        String MaterialFileName;
556
557        _splitpath( dest, drive, dir, node, ext );
558        _makepath( buf, drive, dir, node, ".material" );
559 
560        const char *test = MaterialFileName.c_str();
561        MaterialFileName = String( buf );
562
563        return MaterialFileName;
564}
565
566inline void Lwo2MeshWriter::getTextureVMaps(vtextures &textures, vvmaps &svmaps, vvmaps &dvmaps)
567{
568        for (unsigned int i = 0; i < textures.size(); i++)
569        {
570                lwTexture *texture = textures[i];
571               
572                if (texture->type == ID_IMAP && texture->param.imap)
573                {
574                        char *mapname = texture->param.imap->vmap_name;
575                        if (mapname)
576                                for (unsigned int v = 0; v < svmaps.size(); v++)
577                                {
578                                        lwVMap *vmap = svmaps[v];
579                                        if (strcmp(mapname, vmap->name) == 0) dvmaps.push_back(vmap);
580                                }
581                }
582        }
583        return;
584}
585
586bool Lwo2MeshWriter::writeLwo2Mesh(lwObject *nobject, char *ndest)
587{
588        object = nobject;
589        dest = ndest;
590       
591        if (!object) return false;
592        if (!object->layers.size()) return false;
593       
594        LogManager::getSingleton().createLog("Lwo2MeshWriter.log");
595       
596        prepLwObject();
597       
598        vpoints points;
599        vpolygons polygons;
600        vvmaps vmaps;
601       
602        MeshSerializer meshserializer;
603
604        if (flags[ExportMaterials])
605        {
606                doExportMaterials();
607                materialSerializer->exportQueued(makeMaterialFileName(dest));
608        }
609
610        unsigned int ml = object->layers.size();
611
612        bool SeparateLayers = flags[UseSeparateLayers] && ml > 1;
613
614        if (!SeparateLayers) ogreMesh = new Mesh(ndest);
615
616        Ogre::Vector3 boundingBoxMin(FLT_MAX, FLT_MAX, FLT_MAX);
617        Ogre::Vector3 boundingBoxMax(FLT_MIN, FLT_MIN, FLT_MIN);
618
619
620        for( unsigned int ol = 0; ol < ml; ++ol )
621        {
622                if (!object->layers[ol]->polygons.size())
623                        continue;
624
625                Ogre::Vector3 currentMin(object->layers[ol]->bboxmin.x,
626                                                                 object->layers[ol]->bboxmin.y,
627                                                                 object->layers[ol]->bboxmin.z);
628                Ogre::Vector3 currentMax(object->layers[ol]->bboxmax.x,
629                                                                 object->layers[ol]->bboxmax.y,
630                                                                 object->layers[ol]->bboxmax.z);
631
632                if (SeparateLayers)
633                {       
634                        ogreMesh = new Mesh(ndest);
635                        ogreMesh->_setBounds(Ogre::AxisAlignedBox(currentMin, currentMax));
636                        ogreMesh->_setBoundingSphereRadius(Ogre::Math::Sqrt(std::max(currentMin.squaredLength(), currentMax.squaredLength())));
637                }
638                else
639                {
640                        boundingBoxMin.makeFloor(currentMin);
641                        boundingBoxMax.makeCeil(currentMax);
642                }
643               
644                for (unsigned int s = 0; s < object->surfaces.size(); s++)
645                {
646                        lwSurface *surface = object->surfaces[s];
647                       
648                        points.clear();
649                        polygons.clear();
650                        vmaps.clear();
651                       
652                        unsigned int l = ol;
653
654                        for( unsigned int il = 0; il < ml; ++il )
655                        {
656                                if (!SeparateLayers) l = il;
657
658                                copyPoints(s, ID_FACE, object->layers[l]->points, points);
659                                copyPolygons(s, ID_FACE, object->layers[l]->polygons, polygons);
660                                getTextureVMaps(surface->color.textures, object->layers[l]->vmaps, vmaps);
661
662                                if (SeparateLayers) break;
663                        }
664
665                        if (!polygons.size()) continue;                         
666                       
667                        SubMesh *ogreSubMesh = ogreMesh->createSubMesh();
668                        ogreSubMesh->useSharedVertices = flags[UseSharedVertexData] && points.size() < POINTLIMIT;
669
670                        ogreSubMesh->indexData->indexCount = polygons.size() * 3;
671                        ogreSubMesh->indexData->indexBuffer = HardwareBufferManager::getSingleton().createIndexBuffer(HardwareIndexBuffer::IT_16BIT, ogreSubMesh->indexData->indexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY);
672                        ogreSubMesh->setMaterialName(surface->name);
673                       
674
675                        if (ogreSubMesh->useSharedVertices)
676                        {
677                                unsigned short vertexDataOffset = 0;
678                                if (ogreMesh->sharedVertexData) vertexDataOffset = ogreMesh->sharedVertexData->vertexCount;
679                                ogreMesh->sharedVertexData = setupVertexData(points.size(), ogreMesh->sharedVertexData);
680                                copyDataToVertexData(points, polygons, vmaps, ogreSubMesh->indexData, ogreMesh->sharedVertexData, vertexDataOffset);
681                        }
682                        else
683                        {
684                                ogreSubMesh->vertexData = setupVertexData(points.size());
685                                copyDataToVertexData(points, polygons, vmaps, ogreSubMesh->indexData, ogreSubMesh->vertexData);
686                        }
687                }
688
689                if (!SeparateLayers)
690                {       
691                        ogreMesh->_setBounds(Ogre::AxisAlignedBox(boundingBoxMin, boundingBoxMax));
692                        ogreMesh->_setBoundingSphereRadius(Ogre::Math::Sqrt(std::max(boundingBoxMin.squaredLength(), boundingBoxMax.squaredLength())));
693                }
694               
695                String fname = SeparateLayers ? makeLayerFileName(dest, ol, object->layers[ol]->name) : dest;
696
697                Skeleton *skeleton = 0;
698
699                if (flags[ExportSkeleton])
700                        if (SeparateLayers)
701                                skeleton = doExportSkeleton(fname, ol);
702                        else
703                                if (!ol) skeleton = doExportSkeleton(fname, -1);
704
705                if (flags[GenerateLOD])
706                {
707                        ProgressiveMesh::VertexReductionQuota quota;
708
709                        if (flags[UseFixedMethod])
710                                quota = ProgressiveMesh::VRQ_CONSTANT;
711                        else
712                                quota = ProgressiveMesh::VRQ_PROPORTIONAL;
713                                       
714                        ogreMesh->generateLodLevels(distanceList, quota, reduction);
715                }
716               
717                try
718                {
719                        meshserializer.exportMesh(ogreMesh, fname);
720                }
721                catch (...)
722                {
723                        cout << "Could not export to file: " << fname << endl;
724                }
725
726                ogreMesh->unload();
727
728                delete ogreMesh;
729                if (flags[ExportSkeleton] && skeleton) delete skeleton;
730
731                if (!SeparateLayers) break;
732        }
733
734        return true;
735}
Note: See TracBrowser for help on using the repository browser.