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

Revision 692, 21.5 KB checked in by mattausch, 18 years ago (diff)

adding ogre 1.2 and dependencies

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.isNull())
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                        unsigned int j;
180                        lwTexture *tex;
181                        int cindex;
182                        lwClip *clip;
183                       
184                        for (j = 0; j < surface->color.textures.size(); j++)
185                        {
186                                tex = surface->color.textures[j];
187                                cindex = tex->param.imap->cindex;
188                                clip = object->lwFindClip(cindex);
189                               
190                                if (clip)
191                                {
192                                        _splitpath( clip->source.still->name, drive, dir, node, ext );
193                                        _makepath( texname, 0, 0, node, ext );                                 
194                                        ogreMat->getTechnique(0)->getPass(0)->createTextureUnitState(texname);
195                                }
196                        }
197
198                        for (j = 0; j < surface->transparency.val.textures.size(); j++)
199                        {
200                                tex = surface->transparency.val.textures[j];
201                                cindex = tex->param.imap->cindex;
202                                clip = object->lwFindClip(cindex);
203                               
204                                if (clip)
205                                {
206                                        _splitpath( clip->source.still->name, drive, dir, node, ext );
207                                        _makepath( texname, 0, 0, node, ext );                                 
208                                        ogreMat->getTechnique(0)->getPass(0)->createTextureUnitState(texname);
209                                }
210                        }
211                        materialSerializer->queueForExport(ogreMat);
212                }
213        }
214}
215
216Skeleton *Lwo2MeshWriter::doExportSkeleton(const String &skelName, int l)
217{
218        vpolygons bones;
219        bones.clear();
220        bones.reserve(256);
221
222        vpoints bonepoints;
223        bonepoints.clear();
224        bonepoints.reserve(512);
225
226        if (l == -1)
227        {
228                for (l = 0; l < object->layers.size(); ++l)
229                {
230                        copyPoints(-1, ID_BONE, object->layers[l]->points, bonepoints);
231                        copyPolygons(-1, ID_BONE, object->layers[l]->polygons, bones);
232                }
233        }
234        else
235        {
236                copyPoints(-1, ID_BONE, object->layers[l]->points, bonepoints);
237                copyPolygons(-1, ID_BONE, object->layers[l]->polygons, bones);
238        }
239
240        if (!bones.size()) return NULL; // no bones means no skeleton
241
242        SkeletonPtr ogreskel = Ogre::SkeletonManager::getSingleton().create(skelName, Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
243
244        unsigned int i;
245        // Create all the bones in turn
246        for (i = 0; i < bones.size(); ++i)
247        {
248                lwPolygon* bone = bones[i];
249                if (bone->vertices.size() != 2) continue; // a bone has only 2 sides
250
251                Bone* ogreBone = ogreskel->createBone("Bone");
252
253                Ogre::Vector3 bonePos(bone->vertices[0]->point->x, bone->vertices[0]->point->y, bone->vertices[0]->point->z);
254
255                ogreBone->setPosition(bonePos);
256                // Hmm, Milkshape has chosen a Euler angle representation of orientation which is not smart
257                // Rotation Matrix or Quaternion would have been the smarter choice
258                // Might we have Gimbal lock here? What order are these 3 angles supposed to be applied?
259                // Grr, we'll try our best anyway...
260                Quaternion qx, qy, qz, qfinal;
261/*
262                qx.FromAngleAxis(msBoneRot[0], Vector3::UNIT_X);
263                qy.FromAngleAxis(msBoneRot[1], Vector3::UNIT_Y);
264                qz.FromAngleAxis(msBoneRot[2], Vector3::UNIT_Z);
265*/
266                // Assume rotate by x then y then z
267                qfinal = qz * qy * qx;
268                ogreBone->setOrientation(qfinal);
269        }
270/*
271        for (i = 0; i < numBones; ++i)
272        {
273                msBone* bone = msModel_GetBoneAt(pModel, i);
274
275                if (strlen(bone->szParentName) == 0)
276                {
277                }
278                else
279                {
280                        Bone* ogrechild = ogreskel->getBone(bone->szName);
281                        Bone* ogreparent = ogreskel->getBone(bone->szParentName);
282
283                        if (ogrechild == 0)
284                        {
285                                continue;
286                        }
287                        if (ogreparent == 0)
288                        {
289                                continue;
290                        }
291                        // Make child
292                        ogreparent->addChild(ogrechild);
293                }
294
295
296        }
297
298        // Create the Animation(s)
299        doExportAnimations(pModel, ogreskel);
300
301        // Create skeleton serializer & export
302        SkeletonSerializer serializer;
303        serializer.exportSkeleton(ogreskel, szFile);
304
305        ogreMesh->_notifySkeleton(ogreskel);
306
307        return ogreskel;
308*/
309    if (!ogreskel.isNull())
310        Ogre::SkeletonManager::getSingleton().remove(ogreskel->getHandle());
311
312        return NULL;
313}
314
315#define POSITION_BINDING 0
316#define NORMAL_BINDING 1
317#define TEXCOORD_BINDING 2
318
319VertexData *Lwo2MeshWriter::setupVertexData(unsigned short vertexCount, VertexData *oldVertexData, bool deleteOldVertexData)
320{
321        VertexData *vertexData = new VertexData();
322
323        if (oldVertexData)
324        {
325        // Basic vertex info
326        vertexData->vertexStart = oldVertexData->vertexStart;
327                vertexData->vertexCount = oldVertexData->vertexCount + vertexCount;
328
329                const VertexBufferBinding::VertexBufferBindingMap bindings = oldVertexData->vertexBufferBinding->getBindings();
330                VertexBufferBinding::VertexBufferBindingMap::const_iterator vbi, vbend;
331                vbend = bindings.end();
332
333                for (vbi = bindings.begin(); vbi != vbend; ++vbi)
334                {
335                        HardwareVertexBufferSharedPtr srcbuf = vbi->second;
336                        // create new buffer with the same settings
337                        HardwareVertexBufferSharedPtr dstBuf =
338                                HardwareBufferManager::getSingleton().createVertexBuffer(
339                                        srcbuf->getVertexSize(), srcbuf->getNumVertices() + vertexCount, srcbuf->getUsage(), srcbuf->isSystemMemory());
340
341                        // copy data
342                        dstBuf->copyData(*srcbuf, 0, 0, srcbuf->getSizeInBytes(), true);
343
344                        // Copy binding
345                        vertexData->vertexBufferBinding->setBinding(vbi->first, dstBuf);
346                }
347
348        // Copy elements
349        const VertexDeclaration::VertexElementList elems = oldVertexData->vertexDeclaration->getElements();
350        VertexDeclaration::VertexElementList::const_iterator ei, eiend;
351        eiend = elems.end();
352        for (ei = elems.begin(); ei != eiend; ++ei)
353        {
354            vertexData->vertexDeclaration->addElement(
355                ei->getSource(),
356                ei->getOffset(),
357                ei->getType(),
358                ei->getSemantic(),
359                ei->getIndex() );
360        }
361                if (deleteOldVertexData) delete oldVertexData;
362        }
363        else
364        {
365                vertexData->vertexCount = vertexCount;
366               
367                VertexBufferBinding* bind = vertexData->vertexBufferBinding;
368                VertexDeclaration* decl = vertexData->vertexDeclaration;
369               
370                decl->addElement(POSITION_BINDING, 0, VET_FLOAT3, VES_POSITION);
371                HardwareVertexBufferSharedPtr pbuf = HardwareBufferManager::getSingleton().createVertexBuffer(decl->getVertexSize(POSITION_BINDING), vertexData->vertexCount, HardwareBuffer::HBU_DYNAMIC, false);
372                bind->setBinding(POSITION_BINDING, pbuf);
373               
374                decl->addElement(NORMAL_BINDING, 0, VET_FLOAT3, VES_NORMAL);
375                HardwareVertexBufferSharedPtr nbuf = HardwareBufferManager::getSingleton().createVertexBuffer(decl->getVertexSize(NORMAL_BINDING), vertexData->vertexCount, HardwareBuffer::HBU_DYNAMIC, false);
376                bind->setBinding(NORMAL_BINDING, nbuf);
377               
378                decl->addElement(TEXCOORD_BINDING, 0, VET_FLOAT2, VES_TEXTURE_COORDINATES);
379                HardwareVertexBufferSharedPtr tbuf = HardwareBufferManager::getSingleton().createVertexBuffer(decl->getVertexSize(TEXCOORD_BINDING), vertexData->vertexCount, HardwareBuffer::HBU_DYNAMIC, false);
380                bind->setBinding(TEXCOORD_BINDING, tbuf);
381        }       
382        return vertexData;
383}
384
385void Lwo2MeshWriter::copyPoints(int surfaceIndex, unsigned long polygontype, vpoints &sourcepoints, vpoints &destpoints)
386{
387        for (unsigned int i = 0; i < sourcepoints.size(); i++)
388        {
389                lwPoint *point = sourcepoints[i];
390               
391                for (unsigned int j = 0; j < point->polygons.size(); j++)
392                {
393                        lwPolygon *polygon = point->polygons[j];
394                        if (polygon->type == polygontype)
395                                if (surfaceIndex == -1 || surfaceIndex == polygon->surfidx)
396                                {
397                                        destpoints.push_back(point);
398                                        break;
399                                }
400                }
401        }
402}
403
404void Lwo2MeshWriter::copyPolygons(int surfaceIndex, unsigned long polygontype, vpolygons &sourcepolygons, vpolygons &destpolygons)
405{
406        for (unsigned int i = 0; i < sourcepolygons.size(); i++)
407        {
408                lwPolygon *polygon = sourcepolygons[i];
409                if (polygon->type == polygontype)
410                        if (surfaceIndex == -1 || surfaceIndex == polygon->surfidx)
411                                destpolygons.push_back(polygon);
412        }
413}
414
415void Lwo2MeshWriter::copyDataToVertexData(vpoints &points,
416                                                                                vpolygons &polygons,
417                                                                                vvmaps &vmaps,
418                                                                                IndexData *indexData,
419                                                                                VertexData *vertexData,
420                                                                                unsigned short vertexDataOffset)
421{
422        lwVMap *vmap = 0;
423        unsigned int ni;
424       
425        HardwareVertexBufferSharedPtr pbuf = vertexData->vertexBufferBinding->getBuffer(POSITION_BINDING);
426        HardwareVertexBufferSharedPtr nbuf = vertexData->vertexBufferBinding->getBuffer(NORMAL_BINDING);
427        HardwareVertexBufferSharedPtr tbuf = vertexData->vertexBufferBinding->getBuffer(TEXCOORD_BINDING);
428        HardwareIndexBufferSharedPtr ibuf = indexData->indexBuffer;
429
430        float* pPos = static_cast<float*>(pbuf->lock(HardwareBuffer::HBL_DISCARD));
431        float* pNor = static_cast<float*>(nbuf->lock(HardwareBuffer::HBL_DISCARD));
432        float* pTex = static_cast<float*>(tbuf->lock(HardwareBuffer::HBL_DISCARD));
433        unsigned short *pIdx = static_cast<unsigned short*>(ibuf->lock(HardwareBuffer::HBL_DISCARD));
434
435        for (unsigned int p = 0; p < polygons.size(); p++)
436        {
437                lwPolygon *polygon = polygons[p];
438               
439                if (polygon->vertices.size() != 3) continue; // only copy triangles;
440
441                for (unsigned int v = 0; v < polygon->vertices.size(); v++)
442                {
443                        lwVertex *vertex = polygon->vertices[v];
444                        lwPoint *point = vertex->point;
445                        unsigned short i = getPointIndex(point, points);
446
447                        pIdx[p*3 + v] = vertexDataOffset + i;
448                       
449                        ni = (vertexDataOffset + i) * 3;
450                       
451                        pPos[ni] = vertex->point->x;
452                        pPos[ni + 1] = vertex->point->y;
453                        pPos[ni + 2] = vertex->point->z;
454                       
455                        pNor[ni] = vertex->normal.x;
456                        pNor[ni + 1] = vertex->normal.y;
457                        pNor[ni + 2] = vertex->normal.z;
458                       
459                        bool found = false;
460                       
461                        ni = (vertexDataOffset + i) * 2;
462                       
463                        for (unsigned int v = 0; v < point->vmaps.size(); v++)
464                        {
465                                for (unsigned int vr = 0; vr < vmaps.size(); vr++)
466                                {
467                                        vmap = vmaps[vr];
468                                        if (point->vmaps[v].vmap == vmap)
469                                        {
470                                                int n = point->vmaps[v].index;
471                                               
472                                                pTex[ni] = vmap->val[n][0];
473                                                pTex[ni + 1] = 1.0f - vmap->val[n][1];
474                                                found = true;
475                                                break;
476                                        }
477                                }
478                                if (found) break;
479                        }
480                }
481        }
482    pbuf->unlock();
483    nbuf->unlock();
484    tbuf->unlock();
485        ibuf->unlock();
486}
487
488void Lwo2MeshWriter::prepLwObject(void)
489{
490        unsigned int l, p;
491       
492        for (l = 0; l < object->layers.size(); l++)
493        {
494                lwLayer *layer = object->layers[l];
495               
496#ifdef _DEBUG
497                cout << "Triangulating layer " << l << ", Polygons before: " << layer->polygons.size();
498#endif
499                layer->triangulatePolygons();
500#ifdef _DEBUG
501                cout << ", Polygons after: " << layer->polygons.size() << endl;
502#endif
503               
504                // Mirror x-coord for Ogre;
505                for (p = 0; p < layer->points.size(); p++)
506                {
507                        layer->points[p]->x *= -1.0f;
508                        layer->points[p]->polygons.clear();
509                }
510                // Unscrew the bounding box
511                float x = layer->bboxmin.x * -1.0f;
512                layer->bboxmin.x = layer->bboxmax.x * -1.0f;
513                layer->bboxmax.x = x;
514               
515                for ( p = 0; p < layer->polygons.size(); p++ )
516                {
517                        lwPolygon *polygon = layer->polygons[ p ];
518                        for (unsigned int j = 0; j < polygon->vertices.size(); j++ )
519                                polygon->vertices[ j ]->point->polygons.push_back(polygon);
520                }       
521               
522                for (p = 0; p < layer->polygons.size(); p++)
523                        layer->polygons[p]->flip();
524               
525                layer->calculatePolygonNormals();
526                layer->calculateVertexNormals();
527        }
528}
529
530inline int Lwo2MeshWriter::getPointIndex(lwPoint *point, vpoints &points)
531{
532        for (unsigned int i = 0; i < points.size(); ++i)
533                if (points[i] == point) return i;
534               
535        return -1;
536}
537
538inline String Lwo2MeshWriter::makeLayerFileName(char* dest, unsigned int l, char *layername)
539{
540        char
541                drive[ _MAX_DRIVE ],
542                dir[ _MAX_DIR ],
543                node[ _MAX_FNAME ],
544                ext[ _MAX_EXT ],
545                buf[ _MAX_DRIVE + _MAX_DIR + _MAX_FNAME + _MAX_EXT + 5 ];
546
547        String LayerFileName;
548        String TempName;
549
550        _splitpath( dest, drive, dir, node, ext );
551
552        TempName = String( node );
553   
554        if (layername) {
555                TempName += ".";
556                TempName += layername;
557        } else {
558                TempName += ".layer" + StringConverter::toString(l);
559        }
560
561        _makepath( buf, drive, dir, TempName.c_str(), ext );
562        LayerFileName = String( buf );
563
564        return LayerFileName;
565}
566
567inline String Lwo2MeshWriter::makeMaterialFileName(char* dest)
568{
569        char
570                drive[ _MAX_DRIVE ],
571                dir[ _MAX_DIR ],
572                node[ _MAX_FNAME ],
573                ext[ _MAX_EXT ],
574                buf[ _MAX_DRIVE + _MAX_DIR + _MAX_FNAME + _MAX_EXT + 5 ];
575
576        String MaterialFileName;
577
578        _splitpath( dest, drive, dir, node, ext );
579        _makepath( buf, drive, dir, node, ".material" );
580 
581        const char *test = MaterialFileName.c_str();
582        MaterialFileName = String( buf );
583
584        return MaterialFileName;
585}
586
587inline void Lwo2MeshWriter::getTextureVMaps(vtextures &textures, vvmaps &svmaps, vvmaps &dvmaps)
588{
589        for (unsigned int i = 0; i < textures.size(); i++)
590        {
591                lwTexture *texture = textures[i];
592               
593                if (texture->type == ID_IMAP && texture->param.imap)
594                {
595                        char *mapname = texture->param.imap->vmap_name;
596                        if (mapname)
597                                for (unsigned int v = 0; v < svmaps.size(); v++)
598                                {
599                                        lwVMap *vmap = svmaps[v];
600                                        if (strcmp(mapname, vmap->name) == 0) dvmaps.push_back(vmap);
601                                }
602                }
603        }
604        return;
605}
606
607bool Lwo2MeshWriter::writeLwo2Mesh(lwObject *nobject, char *ndest)
608{
609        object = nobject;
610        dest = ndest;
611       
612        if (!object) return false;
613        if (!object->layers.size()) return false;
614       
615        prepLwObject();
616       
617        vpoints points;
618        vpolygons polygons;
619        vvmaps vmaps;
620       
621        MeshSerializer meshserializer;
622
623        if (flags[ExportMaterials])
624        {
625                doExportMaterials();
626                materialSerializer->exportQueued(makeMaterialFileName(dest));
627        }
628
629        unsigned int ml = object->layers.size();
630
631        bool SeparateLayers = flags[UseSeparateLayers] && ml > 1;
632
633    if (!SeparateLayers) ogreMesh = Ogre::MeshManager::getSingleton().create(ndest, Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
634
635        Ogre::Vector3 boundingBoxMin(FLT_MAX, FLT_MAX, FLT_MAX);
636        Ogre::Vector3 boundingBoxMax(FLT_MIN, FLT_MIN, FLT_MIN);
637
638
639        for( unsigned int ol = 0; ol < ml; ++ol )
640        {
641                if (!object->layers[ol]->polygons.size())
642                        continue;
643
644                Ogre::Vector3 currentMin(object->layers[ol]->bboxmin.x,
645                                                                 object->layers[ol]->bboxmin.y,
646                                                                 object->layers[ol]->bboxmin.z);
647                Ogre::Vector3 currentMax(object->layers[ol]->bboxmax.x,
648                                                                 object->layers[ol]->bboxmax.y,
649                                                                 object->layers[ol]->bboxmax.z);
650
651                if (SeparateLayers)
652                {       
653                        ogreMesh = Ogre::MeshManager::getSingleton().create(ndest, Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
654                        ogreMesh->_setBounds(Ogre::AxisAlignedBox(currentMin, currentMax));
655                        ogreMesh->_setBoundingSphereRadius(Ogre::Math::Sqrt(std::max(currentMin.squaredLength(), currentMax.squaredLength())));
656                }
657                else
658                {
659                        boundingBoxMin.makeFloor(currentMin);
660                        boundingBoxMax.makeCeil(currentMax);
661                }
662               
663                for (unsigned int s = 0; s < object->surfaces.size(); s++)
664                {
665                        lwSurface *surface = object->surfaces[s];
666                       
667                        points.clear();
668                        polygons.clear();
669                        vmaps.clear();
670                       
671                        unsigned int l = ol;
672
673                        for( unsigned int il = 0; il < ml; ++il )
674                        {
675                                if (!SeparateLayers) l = il;
676
677                                copyPoints(s, ID_FACE, object->layers[l]->points, points);
678                                copyPolygons(s, ID_FACE, object->layers[l]->polygons, polygons);
679                                getTextureVMaps(surface->color.textures, object->layers[l]->vmaps, vmaps);
680
681                                if (SeparateLayers) break;
682                        }
683
684                        if (!polygons.size()) continue;                         
685                       
686                        SubMesh *ogreSubMesh = ogreMesh->createSubMesh();
687                        ogreSubMesh->useSharedVertices = flags[UseSharedVertexData] && points.size() < POINTLIMIT;
688
689                        ogreSubMesh->indexData->indexCount = polygons.size() * 3;
690                        ogreSubMesh->indexData->indexBuffer = HardwareBufferManager::getSingleton().createIndexBuffer(HardwareIndexBuffer::IT_16BIT, ogreSubMesh->indexData->indexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY);
691                        ogreSubMesh->setMaterialName(surface->name);
692                       
693
694                        if (ogreSubMesh->useSharedVertices)
695                        {
696                                unsigned short vertexDataOffset = 0;
697                                if (ogreMesh->sharedVertexData) vertexDataOffset = ogreMesh->sharedVertexData->vertexCount;
698                                ogreMesh->sharedVertexData = setupVertexData(points.size(), ogreMesh->sharedVertexData);
699                                copyDataToVertexData(points, polygons, vmaps, ogreSubMesh->indexData, ogreMesh->sharedVertexData, vertexDataOffset);
700                        }
701                        else
702                        {
703                                ogreSubMesh->vertexData = setupVertexData(points.size());
704                                copyDataToVertexData(points, polygons, vmaps, ogreSubMesh->indexData, ogreSubMesh->vertexData);
705                        }
706                }
707
708                if (!SeparateLayers)
709                {       
710                        ogreMesh->_setBounds(Ogre::AxisAlignedBox(boundingBoxMin, boundingBoxMax));
711                        ogreMesh->_setBoundingSphereRadius(Ogre::Math::Sqrt(std::max(boundingBoxMin.squaredLength(), boundingBoxMax.squaredLength())));
712                }
713               
714                String fname = SeparateLayers ? makeLayerFileName(dest, ol, object->layers[ol]->name) : dest;
715
716                Skeleton *skeleton = 0;
717
718                if (flags[ExportSkeleton])
719                        if (SeparateLayers)
720                                skeleton = doExportSkeleton(fname, ol);
721                        else
722                                if (!ol) skeleton = doExportSkeleton(fname, -1);
723
724                if (flags[GenerateLOD])
725                {
726                        ProgressiveMesh::VertexReductionQuota quota;
727
728                        if (flags[UseFixedMethod])
729                                quota = ProgressiveMesh::VRQ_CONSTANT;
730                        else
731                                quota = ProgressiveMesh::VRQ_PROPORTIONAL;
732                                       
733                        ogreMesh->generateLodLevels(distanceList, quota, reduction);
734                }
735
736                if (flags[GenerateEdgeLists])
737                {
738                        ogreMesh->buildEdgeList();
739                }
740
741                if (flags[GenerateTangents])
742                {
743                        ogreMesh->buildTangentVectors();
744                }
745               
746                try
747                {
748                        meshserializer.exportMesh(ogreMesh.getPointer(), fname);
749                }
750                catch (...)
751                {
752                        cout << "Could not export to file: " << fname << endl;
753                }
754
755                ogreMesh->unload();
756
757                Ogre::MeshManager::getSingleton().remove(ogreMesh->getHandle());
758                if (flags[ExportSkeleton] && skeleton) delete skeleton;
759
760                if (!SeparateLayers) break;
761        }
762
763        return true;
764}
Note: See TracBrowser for help on using the repository browser.