Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/Tools/LightwaveConverter/src/main.cpp @ 7

Last change on this file since 7 was 6, checked in by anonymous, 17 years ago

=…

File size: 17.9 KB
Line 
1#include "lwo.h"
2#include "lwReader.h"
3#include "lwo2mesh.h"
4
5#include "Ogre.h"
6#include "OgreMeshSerializer.h"
7#include "OgreSkeletonSerializer.h"
8#include "OgreDefaultHardwareBufferManager.h"
9
10#if OGRE_PLATFORM == OGRE_PLATFORM_LINUX
11#include "asm/io.h"
12#else
13#include "io.h"
14#endif
15#include "time.h"
16
17LogManager* logMgr;
18ResourceGroupManager* resourceGroupMgr;
19Math* mth;
20MaterialManager* matMgr;
21SkeletonManager* skelMgr;
22MeshManager* meshMgr;
23MeshSerializer* meshSerializer;
24MaterialSerializer* materialSerializer;
25SkeletonSerializer* skeletonSerializer;
26DefaultHardwareBufferManager* bufferMgr;
27
28bool flags[NUMFLAGS] =
29{
30        false, // lightwave info
31        false, // dump vmaps
32        true,  // shared geometry
33        false, // layers
34        false, // generate LOD
35        true,  // generate edge lists
36        true,  // generate tangents
37        true,  // use fixed method
38        true,  // materials
39        false, // RenameMaterials
40        false, // UseInteractiveMethod
41        true,  // UseObjectMethod, default
42        false, // UsePrefixMethod
43        true,  // skeleton
44        true,  // has normals
45        true,  // new submesh
46        true   // linear copy
47};
48
49Mesh::LodDistanceList distanceList;
50Real reduction = 0.0f;
51char *matPrefix = 0;
52
53ostream& nl(ostream& os)
54{
55        return os << '\n';
56}
57
58int nobjects = 0, nlayers = 0, nsurfs = 0, nenvs = 0, nclips = 0, npoints = 0, npolygons = 0;
59
60/*
61======================================================================
62print_vmaps1()
63
64  Print vmap values for a layer, looping through the vmaps.
65 
66        for each vmap
67        print vmap statistics
68        for each mapped point
69        print point index and position
70        if vmad, print polygon index and vertex number
71        print vmap values
72====================================================================== */
73
74static void print_vmaps1( FILE *fp, lwLayer *layer )
75{
76        lwPoint *pt;
77        lwVMap *vmap;
78        char *tag;
79        unsigned int i, j, k, n;
80       
81        fprintf( fp, "\n\nVertex Maps (%d)\n\n", layer->vmaps.size() );
82       
83        for ( i = 0; i < layer->vmaps.size(); i++ )
84        {
85                vmap = layer->vmaps[i];
86
87                tag = ( char * ) &vmap->type;
88               
89                fprintf( fp, "%c%c%c%c \"%s\"  dim %d  nverts %d  vmad (%s)\n",
90                        tag[ 3 ], tag[ 2 ], tag[ 1 ], tag[ 0 ],
91                        vmap->name,
92                        vmap->dim,
93                        vmap->nverts,
94                        vmap->perpoly ? "yes" : "no" );
95               
96                printf( "%c%c%c%c \"%s\"  dim %d  nverts %d  vmad (%s)\n",
97                        tag[ 3 ], tag[ 2 ], tag[ 1 ], tag[ 0 ],
98                        vmap->name,
99                        vmap->dim,
100                        vmap->nverts,
101                        vmap->perpoly ? "yes" : "no" );
102               
103                for ( j = 0; j < vmap->nverts; j++ ) {
104                        /* point index */
105                        fprintf( fp, "  point %d ", vmap->vindex[ j ] );
106                       
107                        /* if vmad */
108                        if ( vmap->perpoly ) {
109                                lwPolygon *pol;
110                               
111                                /* polygon index */
112                                k = vmap->pindex[ j ];
113                                fprintf( fp, " poly %d ", k );
114                               
115                                /* vertex index */
116                                pol = layer->polygons[ k ];
117                                for ( n = 0; n < pol->vertices.size(); n++ )
118                                        if ( pol->vertices[ n ]->index == vmap->vindex[ j ] ) break;
119                                        fprintf( fp, " vert %d ", n );
120                        }
121                       
122                        /* point coords */
123                        pt = layer->points[ vmap->vindex[ j ]];
124                        fprintf( fp, " (%g, %g, %g) ", pt->x, pt->y, pt->z );
125                       
126                        /* vmap values */
127                        for ( k = 0; k < vmap->dim; k++ )
128                                fprintf( fp, " %g", vmap->val[ j ][ k ] );
129                       
130                        /* done with this point */
131                        fprintf( fp, "\n" );
132                }
133                /* done with this vmap */
134                fprintf( fp, "\n" );
135        }
136        /* done with this layer */
137        fprintf( fp, "\n\n" );
138}
139
140
141/*
142======================================================================
143print_vmaps2()
144
145  Print vmap values for a layer, looping through the points.
146 
147        for each point
148        print point index, position, number of vmaps, polygon indexes
149        for each vmap on the point
150        print vmap name, type and values
151====================================================================== */
152
153static void print_vmaps2( FILE *fp, lwLayer *layer )
154{
155        lwPoint *pt;
156        lwVMap *vmap;
157        char *tag;
158        unsigned int i, j, k, n;
159       
160        fprintf( fp, "\n\nPoints (%d)\n\n", layer->points.size() );
161       
162        for ( i = 0; i < layer->points.size(); i++ ) {
163                pt = layer->points[ i ];
164               
165                /* point index and position */
166                fprintf( fp, "%d (%g, %g, %g)", i, pt->x, pt->y, pt->z );
167               
168                /* number of vmaps and polygons */
169                fprintf( fp, "  nvmaps %d  npolygons %d", pt->vmaps.size(), pt->polygons.size() );
170               
171                /* polygon indexes */
172                fprintf( fp, " [" );
173                for ( j = 0; j < pt->polygons.size(); j++ )
174                        fprintf( fp, " %d", pt->polygons[ j ] );
175                fprintf( fp, "]\n" );
176               
177                /* vmaps for this point */
178                for ( j = 0; j < pt->vmaps.size(); j++ ) {
179                        vmap = pt->vmaps[ j ].vmap;
180                        n = pt->vmaps[ j ].index;
181                       
182                        tag = ( char * ) &vmap->type;
183                       
184                        fprintf( fp, "  %c%c%c%c \"%s\" vmad (%s)",
185                                tag[ 3 ], tag[ 2 ], tag[ 1 ], tag[ 0 ], vmap->name,
186                                vmap->perpoly ? "yes" : "no" );
187                       
188                        /* vmap values */
189                        for ( k = 0; k < vmap->dim; k++ )
190                                fprintf( fp, " %g", vmap->val[ n ][ k ] );
191                       
192                        /* done with this vmap */
193                        fprintf( fp, "\n" );
194                }
195                /* done with this point */
196                fprintf( fp, "\n" );
197        }
198        /* done with this layer */
199        fprintf( fp, "\n\n" );
200}
201
202
203/*
204======================================================================
205print_vmaps3()
206
207  Print vmap values for a layer, looping through the polygons.
208 
209        for each polygon
210        print polygon index, number of points
211        for each vertex
212        print point index, position, number of vmaps
213        for each vmap on the point
214        print vmap name, type and values
215====================================================================== */
216
217static void print_vmaps3( FILE *fp, lwLayer *layer )
218{
219        lwPoint *pt;
220        lwPolygon *pol;
221        lwVMap *vmap;
222        char *tag;
223        unsigned int i, j, k, m, n;
224       
225        fprintf( fp, "\n\nPolygons (%d)\n\n", layer->polygons.size() );
226       
227        for ( i = 0; i < layer->polygons.size(); i++ ) {
228                pol = layer->polygons[ i ];
229               
230                /* polygon index, type, number of vertices */
231                tag = ( char * ) &pol->type;
232                fprintf( fp, "%d %c%c%c%c  nverts %d\n", i,
233                        tag[ 3 ], tag[ 2 ], tag[ 1 ], tag[ 0 ], pol->vertices.size() );
234               
235                for ( k = 0; k < pol->vertices.size(); k++ ) {
236                        /* point index, position, number of vmads and vmaps */
237                        n = pol->vertices[ k ]->index;
238                        pt = layer->points[ n ];
239                        fprintf( fp, "%d (%g, %g, %g)  nvmads %d  nvmaps %d\n", n,
240                                pt->x, pt->y, pt->z,
241                                pol->vertices[ k ]->vmaps.size(), pt->vmaps.size() - pol->vertices[ k ]->vmaps.size() );
242                       
243                        /* vmads for this vertex */
244                        for ( j = 0; j < pol->vertices[ k ]->vmaps.size(); j++ ) {
245                                vmap = pol->vertices[ k ]->vmaps[ j ].vmap;
246                                n = pol->vertices[ k ]->vmaps[ j ].index;
247                               
248                                tag = ( char * ) &vmap->type;
249                                fprintf( fp, "  %c%c%c%c vmad \"%s\"",
250                                        tag[ 3 ], tag[ 2 ], tag[ 1 ], tag[ 0 ], vmap->name );
251                               
252                                /* vmap values */
253                                for ( m = 0; m < vmap->dim; m++ )
254                                        fprintf( fp, " %g", vmap->val[ m ][ n ] );
255                               
256                                /* done with this vmad */
257                                fprintf( fp, "\n" );
258                        }
259                       
260                        /* vmaps for this vertex */
261                        for ( j = 0; j < pt->vmaps.size(); j++ ) {
262                                vmap = pt->vmaps[ j ].vmap;
263                                if ( vmap->perpoly ) continue;
264                                n = pt->vmaps[ j ].index;
265                               
266                                tag = ( char * ) &vmap->type;
267                                fprintf( fp, "  %c%c%c%c vmap \"%s\"",
268                                        tag[ 3 ], tag[ 2 ], tag[ 1 ], tag[ 0 ], vmap->name );
269                               
270                                /* vmap values */
271                                for ( m = 0; m < vmap->dim; m++ )
272                                        fprintf( fp, " %g", vmap->val[ m ][ n ] );
273                               
274                                /* done with this vmap */
275                                fprintf( fp, "\n" );
276                        }
277                       
278                        /* done with this vertex */
279                        if ( pt->vmaps.size() )
280                                fprintf( fp, "\n" );
281                }
282                /* done with this polygon */
283                fprintf( fp, "\n" );
284        }
285        /* done with this layer */
286        fprintf( fp, "\n\n" );
287}
288
289
290/*
291======================================================================
292print_vmaps()
293
294  Print vmap values for a layer.
295 
296        Calls print_vmaps1(), print_vmaps2() and print_vmaps3().
297====================================================================== */
298
299void print_vmaps( lwObject *obj )
300{
301        FILE *fp[ 3 ];
302        char buf[ 64 ];
303        lwLayer *layer;
304        unsigned int i, j;
305       
306        for ( i = 0; i < 3; i++ ) {
307                sprintf( buf, "vmapout%d.txt", i + 1 );
308                fp[ i ] = fopen( buf, "w" );
309                if ( !fp[ i ] ) {
310                        for ( j = i - 1; j >= 0; j-- )
311                                fclose( fp[ j ] );
312                        return;
313                }
314        }
315       
316        for ( i = 0; i < obj->layers.size(); i++ )
317        {
318                layer = obj->layers[i];
319
320                fprintf( fp[ 0 ], "------------------------\nLayer %d\n", i );
321                print_vmaps1( fp[ 0 ], layer );
322               
323                fprintf( fp[ 1 ], "------------------------\nLayer %d\n", i );
324                print_vmaps2( fp[ 1 ], layer );
325               
326                fprintf( fp[ 2 ], "------------------------\nLayer %d\n", i );
327                print_vmaps3( fp[ 2 ], layer );
328        }
329       
330        for ( i = 0; i < 3; i++ )
331                fclose( fp[ i ] );
332}
333
334int make_filename( char *spec, char *name, char *fullname )
335{
336        char
337                drive[ _MAX_DRIVE ],
338                dir[ _MAX_DIR ],
339                node[ _MAX_FNAME ],
340                ext[ _MAX_EXT ];
341       
342        _splitpath( spec, drive, dir, node, ext );
343        _makepath( fullname, drive, dir, name, NULL );
344        return 1;
345}
346
347int make_destname( char *spec, char *name, char *fullname )
348{
349        char
350                drive[ _MAX_DRIVE ],
351                dir[ _MAX_DIR ],
352                node[ _MAX_FNAME ],
353                ext[ _MAX_EXT ],
354                dnode[ _MAX_FNAME ];
355       
356        _splitpath( name, drive, dir, dnode, ext );
357        _splitpath( spec, drive, dir, node, ext );
358        _makepath( fullname, drive, dir, dnode, ".mesh" );
359        return 1;
360}
361
362int make_filespec( char *spec, char *subdir, char *fullname )
363{
364        char
365                name[ _MAX_FNAME ],
366                drive[ _MAX_DRIVE ],
367                dir[ _MAX_DIR ],
368                node[ _MAX_FNAME ],
369                ext[ _MAX_EXT ];
370       
371        _splitpath( spec, drive, dir, node, ext );
372        _makepath( name, drive, dir, subdir, NULL );
373        _makepath( fullname, NULL, name, node, ext );
374        return 1;
375}
376
377void help( char *filename )
378{
379        cout << "lwo2mesh v0.89b (2005.02.09) by Dennis Verbeek." << nl
380                << "Converts a Lightwave object to an Ogre mesh." << nl
381                << "Please send any feedback to: dennis.verbeek@chello.nl" << nl << nl
382#if OGRE_PLATFORM == OGRE_PLATFORM_LINUX
383                << "Linux Port (2004.10.16) by Magnus Møller Petersen." << nl
384                << "Please send feedback concerning Linux to: magnus@moaner.dk" << nl << nl
385#endif
386                << "Usage: " << filename << " [options] source [dest]" << nl
387                << "options:" << nl
388                << "-g do not use shared geometry" << nl
389                << "-d generate level of detail information" << nl
390                << "   method (f)ixed or (p)roportional" << nl
391                << "   reduction (fixed) or reductionfactor (proportional)" << nl
392                << "   number of LOD levels" << nl
393                << "   distances" << nl
394                << "   example: -dp 0.5 4 1000.0 2000.0 4000.0 8000.0" << nl
395                << "-l save layers separately" << nl
396                << "-m do not export materials" << nl
397                << "-r rename materials" << nl
398                << "   method (i)nteractive, (o)bjectname or (p)refix" << nl
399                << "   example: -rp prefix_" << nl
400                << "-s do not export skeleton" << nl
401                << "-i info on .lwo only, no conversion to mesh" << nl
402                << "   -v dump vertex maps" << endl;
403        exit(0);
404}
405
406void info(lwObject *object, char *filename)
407{
408        unsigned int points = 0;
409        unsigned int polygons = 0;
410
411        nlayers += object->layers.size();
412        nsurfs += object->surfaces.size();
413        nclips += object->clips.size();
414        nenvs += object->envelopes.size();
415
416        cout << "File: " << filename << nl
417                << setw(8) << object->layers.size() << " layers" << nl
418                << setw(8) << object->surfaces.size() << " surfaces" << nl
419                << setw(8) << object->clips.size() << " clips" << nl
420                << setw(8) << object->envelopes.size() << " envelopes" << endl;
421       
422        if (object->layers.size() > 1)
423        {
424                for( unsigned int i = 0; i < object->layers.size(); i++ )
425                {
426                        points += object->layers[i]->points.size();
427                        cout << setw(8) << object->layers[i]->points.size() << " points (layer " << i;
428                       
429                        if (object->layers[i]->name)
430                                cout << ", " << object->layers[i]->name << ")" << endl;
431                        else
432                                cout << ")" << endl;
433                       
434                        polygons += object->layers[i]->polygons.size();
435                        cout << setw(8) << object->layers[i]->polygons.size() << " polygons (layer " << i;
436                       
437                        if (object->layers[i]->name)                           
438                                cout << ", " << object->layers[i]->name << ")" << endl;
439                        else
440                                cout << ")" << endl;
441                }
442        }
443        else
444        {
445                points += object->layers[0]->points.size();
446                polygons += object->layers[0]->polygons.size();
447        }
448       
449        cout << setw(8) << points << " points (total)" << nl
450                << setw(8) << polygons << " polygons (total)" << nl << endl;
451       
452        nobjects++;
453        npoints += points;
454        npolygons += polygons;
455       
456        if (flags[PrintVMaps])
457                print_vmaps( object );
458}
459
460#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
461int readFiles( char *source, char *dest)
462{
463        long h, err;
464        struct _finddata_t data;
465        char *filename, *prevname, *destname;
466        unsigned int failID;
467        int failpos;
468        lwReader reader;
469        Lwo2MeshWriter lwo2mesh;
470       
471        filename = (char *)malloc(3 * 512);
472        if ( !filename ) return 0;
473        prevname = filename + 512;
474        destname = filename + 1024;
475       
476        err = h = _findfirst( source, &data );
477        if ( err == -1 )
478        {
479                printf( "No files found: '%s'\n", source );
480                return 0;
481        }
482       
483        while ( err != -1 )
484        {
485                if (( data.attrib & _A_SUBDIR ) && data.name[ 0 ] != '.' )
486                {
487                        make_filespec( source, data.name, filename );
488                        readFiles( filename, dest );
489                }
490                if ( !( data.attrib & _A_SUBDIR ))
491                {
492                        make_filename( source, data.name, filename );
493
494                        if ( !strcmp( filename, prevname )) break;
495                        strcpy( prevname, filename );
496                        failID = failpos = 0;
497
498                        lwObject *object = reader.readObjectFromFile( filename );
499                        if ( object )
500                        {
501                                if (flags[InfoOnly])
502                                        info(object, filename);
503                                else
504                                {
505                                        make_destname( dest, data.name, destname );
506                                        lwo2mesh.writeLwo2Mesh(object, destname);
507                                }
508                                delete object;
509                        }
510                }
511                err = _findnext( h, &data );
512        }
513       
514        _findclose( h );
515        free (filename);
516        return 1;
517}
518#elif OGRE_PLATFORM == OGRE_PLATFORM_LINUX
519int readFiles( char *source, char *dest ) {
520        return 1;
521}
522#else
523#define readFiles( a, b )
524#endif
525
526int main( int argc, char *argv[] )
527{
528        int i = 1;
529        unsigned int ndistances = 0;
530        Real distance = 0;
531        char *source = 0;
532        char *dest = 0;
533
534        if ( argc < 2 ) help(argv[0]);
535
536        while (i < argc)
537        {
538                if (argv[i][0] == '-' || argv[i][0] == '/')
539                {
540                        switch (argv[i++][1])
541                        {
542                        case 'd':
543                        case 'D':
544                                i--;
545                                flags[GenerateLOD] = true;
546                                switch (argv[i++][2])
547                                {
548                                case 'f':
549                                case 'F':
550                                        flags[UseFixedMethod] = true;
551                                        break;
552                                case 'p':
553                                case 'P':
554                                        flags[UseFixedMethod] = false;
555                                        break;
556                                default:
557                                        help(argv[0]);
558                                }
559                                try
560                                {
561                                        reduction = atof(argv[i++]);
562                                        ndistances = atoi(argv[i++]);
563                                        while (ndistances > 0)
564                                        {
565                                                if (i < argc && argv[i][0] != '-' && argv[i][0] != '/')
566                                                        distanceList.push_back(atof(argv[i++]));                                                                       
567                                                else
568                                                        ndistances = 0;
569                                                ndistances--;
570                                        }
571                                }
572                                catch (Exception *e)
573                                {
574                                        ndistances = 0;
575                                        distanceList.clear();
576                                        flags[GenerateLOD] = false;
577                                }
578                                break;
579                        case 'g':
580                        case 'G':
581                                flags[UseSharedVertexData] = false;
582                                break;
583                        case 'i':
584                        case 'I':
585                                flags[InfoOnly] = true;
586                                break;
587                        case 'l':
588                        case 'L':
589                                flags[UseSeparateLayers] = true;
590                                break;
591                        case 'm':
592                        case 'M':
593                                flags[ExportMaterials] = false;
594                                break;
595                        case 'r':
596                        case 'R':
597                                flags[RenameMaterials] = true;
598                                if (strlen(argv[i-1]) > 2) {
599                                        i--;
600                                        switch (argv[i++][2])
601                                        {
602                                        case 'i':
603                                        case 'I':
604                                                flags[UseInteractiveMethod] = true;
605                                                break;
606                                        case 'o':
607                                        case 'O':
608                                                flags[UseObjectMethod] = true; // default
609                                                break;
610                                        case 'p':
611                                        case 'P':
612                                                flags[UsePrefixMethod] = true;
613                                                if (argv[i][0] != '-' && argv[i][0] != '/')
614                                                        matPrefix = argv[i++];
615                                                else
616                                                        help(argv[0]);
617                                                break;
618                                        default:
619                                                help(argv[0]);
620                                        }
621                                }
622                                break;
623                        case 's':
624                        case 'S':
625                                flags[ExportSkeleton] = false;
626                                break;
627                        case 'v':
628                        case 'V':
629                                flags[PrintVMaps] = true;
630                                break;
631                        default:
632                                help(argv[0]);
633                        }
634                }
635                else
636                {
637                        if (!source) source = argv[i];
638                        else
639                                if (!dest) dest = argv[i];
640                        i++;
641                }
642        }
643
644        if ( !source ) help(argv[0]);
645
646        if (!dest) dest = "\0";
647
648        float t1, t2;
649       
650        t1 = ( float ) clock() / CLOCKS_PER_SEC;
651
652        if (!flags[InfoOnly])
653        {
654                logMgr = new LogManager();
655                logMgr->createLog("lwo2mesh.log", true);
656                resourceGroupMgr = new ResourceGroupManager();
657                mth = new Math();
658                matMgr = new MaterialManager();
659                matMgr->initialise();
660                meshMgr  = new MeshManager();
661                skelMgr = new SkeletonManager();
662                meshSerializer = new MeshSerializer();
663                materialSerializer = new MaterialSerializer();
664                skeletonSerializer = new SkeletonSerializer();
665                bufferMgr = new DefaultHardwareBufferManager(); // needed because we don't have a rendersystem
666        }
667
668        if ( strchr(source, '*') ) 
669                // On Linux this will only be called if you pass the source argument in
670                // quotation marks (e.g. as LightwaveConverter "abc..*" ). Otherwise the
671                // shell will expand the arguments. At least, this is how it works with
672                // bash.
673                readFiles( source, dest );
674        else
675        {
676                lwReader reader;
677                lwObject *object = reader.readObjectFromFile(source);
678                if ( object )
679                {
680                        if (flags[InfoOnly])
681                                info(object, source);
682                        else
683                        {
684                                char *destname = (char *)malloc(512);
685                                if ( !destname ) return 1;
686
687                                if (strlen(dest))
688                                        make_destname(dest, dest, destname);
689                                else
690                                        make_destname(dest, source, destname);
691
692                                Lwo2MeshWriter lwo2mesh;
693                                lwo2mesh.writeLwo2Mesh(object, destname);
694                                free(destname);
695                        }
696                        delete object;
697                }
698        }
699
700        t2 = ( float ) clock() / CLOCKS_PER_SEC - t1;
701       
702        if (flags[InfoOnly])
703        {
704                cout << "Total:" << nl
705                        << setw(8) << nobjects << " objects" << nl
706                        << setw(8) << nlayers << " layers" << nl
707                        << setw(8) << nsurfs << " surfaces" << nl
708                        << setw(8) << nclips << " clips" << nl
709                        << setw(8) << nenvs << " envelopes" << nl
710                        << setw(8) << npoints << " points" << nl
711                        << setw(8) << npolygons << " polygons" << nl
712                        << setw(8) << t2 << " seconds processing time." << endl;
713        }
714        else
715        {
716                delete bufferMgr;
717                delete skeletonSerializer;
718                delete materialSerializer;
719                delete meshSerializer;
720                delete meshMgr;
721                delete skelMgr;
722                delete matMgr;
723                delete mth;
724                delete resourceGroupMgr;
725                delete logMgr;
726        }
727
728        return 0;
729       
730}
Note: See TracBrowser for help on using the repository browser.