source: OGRE/trunk/ogrenew/Tools/MeshUpgrader/src/main.cpp @ 692

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

adding ogre 1.2 and dependencies

Line 
1/*
2-----------------------------------------------------------------------------
3This source file is part of OGRE
4    (Object-oriented Graphics Rendering Engine)
5For the latest info, see http://www.ogre3d.org/
6
7Copyright (c) 2000-2005 The OGRE Team
8Also see acknowledgements in Readme.html
9
10This program is free software; you can redistribute it and/or modify it under
11the terms of the GNU Lesser General Public License as published by the Free Software
12Foundation; either version 2 of the License, or (at your option) any later
13version.
14
15This program is distributed in the hope that it will be useful, but WITHOUT
16ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
18
19You should have received a copy of the GNU Lesser General Public License along with
20this program; if not, write to the Free Software Foundation, Inc., 59 Temple
21Place - Suite 330, Boston, MA 02111-1307, USA, or go to
22http://www.gnu.org/copyleft/lesser.txt.
23-----------------------------------------------------------------------------
24*/
25
26
27#include "Ogre.h"
28#include "OgreMeshSerializer.h"
29#include "OgreSkeletonSerializer.h"
30#include "OgreDefaultHardwareBufferManager.h"
31#include "OgreHardwareVertexBuffer.h"
32
33#include <iostream>
34#include <sys/stat.h>
35
36using namespace std;
37using namespace Ogre;
38
39void help(void)
40{
41    // Print help message
42    cout << endl << "OgreMeshUpgrader: Upgrades .mesh files to the latest version." << endl;
43    cout << "Provided for OGRE by Steve Streeting 2004" << endl << endl;
44    cout << "Usage: OgreMeshUpgrader [-e] sourcefile [destfile] " << endl;
45        cout << "-i             = Interactive mode, prompt for options" << endl;
46        cout << "-l lodlevels   = number of LOD levels" << endl;
47        cout << "-d loddist     = distance increment to reduce LOD" << endl;
48        cout << "-p lodpercent  = Percentage triangle reduction amount per LOD" << endl;
49        cout << "-f lodnumtris  = Fixed vertex reduction per LOD" << endl;
50    cout << "-e         = DON'T generate edge lists (for stencil shadows)" << endl;
51    cout << "-t         = Generate tangents (for normal mapping)" << endl;
52        cout << "-r         = DON'T reorganise buffers to recommended format" << endl;
53        cout << "-d3d       = Convert to D3D colour formats" << endl;
54        cout << "-gl        = Convert to GL colour formats" << endl;
55        cout << "-srcd3d    = Interpret ambiguous colours as D3D style" << endl;
56        cout << "-srcgl     = Interpret ambiguous colours as GL style" << endl;
57        cout << "-E endian  = Set endian mode 'big' 'little' or 'native' (default)" << endl;
58    cout << "sourcefile = name of file to convert" << endl;
59    cout << "destfile   = optional name of file to write to. If you don't" << endl;
60    cout << "             specify this OGRE overwrites the existing file." << endl;
61
62    cout << endl;
63}
64
65struct UpgradeOptions
66{
67        bool interactive;
68        bool suppressEdgeLists;
69        bool generateTangents;
70        bool dontReorganise;
71        bool destColourFormatSet;
72        VertexElementType destColourFormat;
73        bool srcColourFormatSet;
74        VertexElementType srcColourFormat;
75        unsigned short numLods;
76        Real lodDist;
77        Real lodPercent;
78        size_t lodFixed;
79        bool usePercent;
80        Serializer::Endian endian;
81
82};
83
84
85// Crappy globals
86// NB some of these are not directly used, but are required to
87//   instantiate the singletons used in the dlls
88LogManager* logMgr;
89Math* mth;
90MaterialManager* matMgr;
91SkeletonManager* skelMgr;
92MeshSerializer* meshSerializer;
93SkeletonSerializer* skeletonSerializer;
94DefaultHardwareBufferManager *bufferManager;
95ResourceGroupManager* rgm;
96MeshManager* meshMgr;
97UpgradeOptions opts;
98
99void parseOpts(UnaryOptionList& unOpts, BinaryOptionList& binOpts)
100{
101        opts.interactive = false;
102        opts.suppressEdgeLists = false;
103        opts.generateTangents = false;
104        opts.dontReorganise = false;
105        opts.endian = Serializer::ENDIAN_NATIVE;
106        opts.destColourFormatSet = false;
107        opts.srcColourFormatSet = false;
108
109        opts.lodDist = 500;
110        opts.lodFixed = 0;
111        opts.lodPercent = 20;
112        opts.numLods = 0;
113        opts.usePercent = true;
114
115
116        UnaryOptionList::iterator ui = unOpts.find("-e");
117        opts.suppressEdgeLists = ui->second;
118        ui = unOpts.find("-t");
119        opts.generateTangents = ui->second;
120        ui = unOpts.find("-i");
121        opts.interactive = ui->second;
122        ui = unOpts.find("-r");
123        opts.dontReorganise = ui->second;
124        ui = unOpts.find("-d3d");
125        if (ui->second)
126        {
127                opts.destColourFormatSet = true;
128                opts.destColourFormat = VET_COLOUR_ARGB;
129        }
130        ui = unOpts.find("-gl");
131        if (ui->second)
132        {
133                opts.destColourFormatSet = true;
134                opts.destColourFormat = VET_COLOUR_ABGR;
135        }
136        ui = unOpts.find("-srcd3d");
137        if (ui->second)
138        {
139                opts.srcColourFormatSet = true;
140                opts.srcColourFormat = VET_COLOUR_ARGB;
141        }
142        ui = unOpts.find("-srcgl");
143        if (ui->second)
144        {
145                opts.srcColourFormatSet = true;
146                opts.srcColourFormat = VET_COLOUR_ABGR;
147        }
148
149
150        BinaryOptionList::iterator bi = binOpts.find("-l");
151        if (!bi->second.empty())
152        {
153                opts.numLods = StringConverter::parseInt(bi->second);
154        }
155
156        bi = binOpts.find("-d");
157        if (!bi->second.empty())
158        {
159                opts.lodDist = StringConverter::parseReal(bi->second);
160        }
161
162        bi = binOpts.find("-p");
163        if (!bi->second.empty())
164        {
165                opts.lodPercent = StringConverter::parseReal(bi->second);
166                opts.usePercent = true;
167        }
168
169
170        bi = binOpts.find("-f");
171        if (!bi->second.empty())
172        {
173                opts.lodFixed = StringConverter::parseInt(bi->second);
174                opts.usePercent = false;
175        }
176
177        bi = binOpts.find("-E");
178        if (!bi->second.empty())
179        {
180            if (bi->second == "big")
181            opts.endian = Serializer::ENDIAN_BIG;
182            else if (bi->second == "little")
183            opts.endian = Serializer::ENDIAN_LITTLE;
184            else
185            opts.endian = Serializer::ENDIAN_NATIVE;
186    }
187
188}
189
190String describeSemantic(VertexElementSemantic sem)
191{
192        switch (sem)
193        {
194        case VES_POSITION:
195                return "Positions";
196        case VES_NORMAL:
197                return "Normals";
198        case VES_BLEND_WEIGHTS:
199                return "Blend Weights";
200        case VES_BLEND_INDICES:
201                return "Blend Indices";
202        case VES_DIFFUSE:
203                return "Diffuse";
204        case VES_SPECULAR:
205                return "Specular";
206        case VES_TEXTURE_COORDINATES:
207                return "Texture coordinates";
208        case VES_BINORMAL:
209                return "Binormals";
210        case VES_TANGENT:
211                return "Tangents";
212        };
213    return "";
214}
215void displayVertexBuffers(VertexDeclaration::VertexElementList& elemList)
216{
217        // Iterate per buffer
218        unsigned short currentBuffer = 999;
219        unsigned short elemNum = 0;
220        VertexDeclaration::VertexElementList::iterator i, iend;
221        iend = elemList.end();
222        for (i = elemList.begin(); i != iend; ++i)
223        {
224                if (i->getSource() != currentBuffer)
225                {
226                        currentBuffer = i->getSource();
227                        cout << "> Buffer " << currentBuffer << ":" << endl;
228                }
229                cout << "   - Element " << elemNum++ << ": " << describeSemantic(i->getSemantic());
230                if (i->getSemantic() == VES_TEXTURE_COORDINATES)
231                {
232                        cout << " (index " << i->getIndex() << ")";
233                }
234                cout << endl;
235
236        }
237}
238// Sort routine for VertexElement
239bool vertexElementLess(const VertexElement& e1, const VertexElement& e2)
240{
241        // Sort by source first
242        if (e1.getSource() < e2.getSource())
243        {
244                return true;
245        }
246        else if (e1.getSource() == e2.getSource())
247        {
248                // Use ordering of semantics to sort
249                if (e1.getSemantic() < e2.getSemantic())
250                {
251                        return true;
252                }
253                else if (e1.getSemantic() == e2.getSemantic())
254                {
255                        // Use index to sort
256                        if (e1.getIndex() < e2.getIndex())
257                        {
258                                return true;
259                        }
260                }
261        }
262        return false;
263}
264void copyElems(VertexDeclaration* decl, VertexDeclaration::VertexElementList* elemList)
265{
266       
267        elemList->clear();
268        const VertexDeclaration::VertexElementList& origElems = decl->getElements();
269    VertexDeclaration::VertexElementList::const_iterator i, iend;
270        iend = origElems.end();
271        for (i = origElems.begin(); i != iend; ++i)
272        {
273                elemList->push_back(*i);
274        }
275        elemList->sort(VertexDeclaration::vertexElementLess);
276}
277// Utility function to allow the user to modify the layout of vertex buffers.
278void reorganiseVertexBuffers(const String& desc, Mesh& mesh, VertexData* vertexData)
279{
280        cout << endl << desc << ":- " << endl;
281        // Copy elements into a list
282        VertexDeclaration::VertexElementList elemList;
283        copyElems(vertexData->vertexDeclaration, &elemList);
284
285        bool finish = false;
286        bool anyChanges = false;
287        while (!finish)
288        {
289                displayVertexBuffers(elemList);
290                cout << endl;
291
292                cout << "Options: (a)utomatic" << endl;
293        cout << "         (m)ove element" << endl;
294                cout << "         (d)elete element" << endl;
295                cout << "         (r)eset" << endl;
296                cout << "         (f)inish" << endl;
297                String response = "";
298                while (response.empty())
299                {
300                        cin >> response;
301                        StringUtil::toLowerCase(response);
302
303                        if (response == "m")
304                        {
305                                String moveResp;
306                                cout << "Which element do you want to move (type number): ";
307                                cin >> moveResp;
308                                if (!moveResp.empty())
309                                {
310                                        int eindex = StringConverter::parseInt(moveResp);
311                                        VertexDeclaration::VertexElementList::iterator movei = elemList.begin();
312                                        std::advance(movei, eindex);
313                                        cout << endl << "Move element " << eindex << "(" + describeSemantic(movei->getSemantic()) << ") to which buffer: ";
314                                        cin >> moveResp;
315                                        if (!moveResp.empty())
316                                        {
317                                                int bindex = StringConverter::parseInt(moveResp);
318                                                // Move (note offset will be wrong)
319                                                *movei = VertexElement(bindex, 0, movei->getType(),
320                                                        movei->getSemantic(), movei->getIndex());
321                                                elemList.sort(vertexElementLess);
322                        anyChanges = true;
323                                                               
324                                        }
325                                }
326                        }
327            else if (response == "a")
328            {
329                // Automatic
330                VertexDeclaration* newDcl =
331                    vertexData->vertexDeclaration->getAutoOrganisedDeclaration(
332                        mesh.hasSkeleton(), mesh.hasVertexAnimation());
333                copyElems(newDcl, &elemList);
334                HardwareBufferManager::getSingleton().destroyVertexDeclaration(newDcl);
335                anyChanges = true;
336
337            }
338                        else if (response == "d")
339                        {
340                                String moveResp;
341                                cout << "Which element do you want to delete (type number): ";
342                                cin >> moveResp;
343                                if (!moveResp.empty())
344                                {
345                                        int eindex = StringConverter::parseInt(moveResp);
346                                        VertexDeclaration::VertexElementList::iterator movei = elemList.begin();
347                                        std::advance(movei, eindex);
348                    cout << std::endl << "Delete element " << eindex << "(" + describeSemantic(movei->getSemantic()) << ")?: ";
349                                        cin >> moveResp;
350                                        StringUtil::toLowerCase(moveResp);
351                                        if (moveResp == "y")
352                                        {
353                                                elemList.erase(movei);
354                        anyChanges = true;
355                                        }
356                                }
357                        }
358                        else if (response == "r")
359                        {
360                                // reset
361                                copyElems(vertexData->vertexDeclaration, &elemList);
362                                anyChanges = false;
363                        }
364                        else if (response == "f")
365                        {
366                                // finish
367                                finish = true;
368                        }
369                        else
370                        {
371                                response == "";
372                        }
373                       
374                }
375        }
376
377        if (anyChanges)
378        {
379                String response;
380                while (response.empty())
381                {
382                        displayVertexBuffers(elemList);
383                        cout << "Really reorganise the vertex buffers this way?";
384                        cin >> response;
385                        StringUtil::toLowerCase(response);
386                        if (response == "y")
387                        {
388                                VertexDeclaration* newDecl = HardwareBufferManager::getSingleton().createVertexDeclaration();
389                                VertexDeclaration::VertexElementList::iterator i, iend;
390                                iend = elemList.end();
391                                unsigned short currentBuffer = 999;
392                                size_t offset;
393                                for (i = elemList.begin(); i != iend; ++i)
394                                {
395                                        // Calc offsets since reorg changes them
396                                        if (i->getSource() != currentBuffer)
397                                        {
398                                                offset = 0;
399                                                currentBuffer = i->getSource();
400                                        }
401                                        newDecl->addElement(
402                                                currentBuffer,
403                                                offset,
404                                                i->getType(),
405                                                i->getSemantic(),
406                                                i->getIndex());
407
408                                        offset += VertexElement::getTypeSize(i->getType());
409                                       
410                                }
411                // Usages don't matter here since we're onlly exporting
412                BufferUsageList bufferUsages;
413                for (size_t u = 0; u <= newDecl->getMaxSource(); ++u)
414                    bufferUsages.push_back(HardwareBuffer::HBU_STATIC_WRITE_ONLY);
415                                vertexData->reorganiseBuffers(newDecl, bufferUsages);
416                        }
417                        else if (response == "n")
418                        {
419                                // do nothing
420                        }
421                        else
422                        {
423                                response = "";
424                        }
425        }
426               
427        }
428               
429
430       
431}
432// Utility function to allow the user to modify the layout of vertex buffers.
433void reorganiseVertexBuffers(Mesh& mesh)
434{
435        if (mesh.sharedVertexData)
436        {
437                if (opts.interactive)
438                        reorganiseVertexBuffers("Shared Geometry", mesh, mesh.sharedVertexData);
439                else
440                {
441                        // Automatic
442                        VertexDeclaration* newDcl =
443                                mesh.sharedVertexData->vertexDeclaration->getAutoOrganisedDeclaration(
444                                mesh.hasSkeleton(), mesh.hasVertexAnimation());
445                        if (*newDcl != *(mesh.sharedVertexData->vertexDeclaration))
446                        {
447                                // Usages don't matter here since we're onlly exporting
448                                BufferUsageList bufferUsages;
449                                for (size_t u = 0; u <= newDcl->getMaxSource(); ++u)
450                                        bufferUsages.push_back(HardwareBuffer::HBU_STATIC_WRITE_ONLY);
451                                mesh.sharedVertexData->reorganiseBuffers(newDcl, bufferUsages);
452                        }
453
454                }
455        }
456
457    Mesh::SubMeshIterator smIt = mesh.getSubMeshIterator();
458        unsigned short idx = 0;
459        while (smIt.hasMoreElements())
460        {
461                SubMesh* sm = smIt.getNext();
462                if (!sm->useSharedVertices)
463                {
464                        if (opts.interactive)
465                        {
466                                StringUtil::StrStreamType str;
467                                str << "SubMesh " << idx++;
468                                reorganiseVertexBuffers(str.str(), mesh, sm->vertexData);
469                        }
470                        else
471                        {
472                                // Automatic
473                                VertexDeclaration* newDcl =
474                                        sm->vertexData->vertexDeclaration->getAutoOrganisedDeclaration(
475                                        mesh.hasSkeleton(), mesh.hasVertexAnimation());
476                                if (*newDcl != *(sm->vertexData->vertexDeclaration))
477                                {
478                                        // Usages don't matter here since we're onlly exporting
479                                        BufferUsageList bufferUsages;
480                                        for (size_t u = 0; u <= newDcl->getMaxSource(); ++u)
481                                                bufferUsages.push_back(HardwareBuffer::HBU_STATIC_WRITE_ONLY);
482                                        sm->vertexData->reorganiseBuffers(newDcl, bufferUsages);
483                                }
484                               
485                        }
486                }
487        }
488}
489
490
491void vertexBufferReorg(Mesh& mesh)
492{
493        String response;
494
495        if (opts.interactive)
496        {
497
498                // Check to see whether we would like to reorganise vertex buffers
499                std::cout << "\nWould you like to reorganise the vertex buffers for this mesh?";
500                while (response.empty())
501                {
502                        cin >> response;
503                        StringUtil::toLowerCase(response);
504                        if (response == "y")
505                        {
506                                reorganiseVertexBuffers(mesh);
507                        }
508                        else if (response == "n")
509                        {
510                                // Do nothing
511                        }
512                        else
513                        {
514                                response = "";
515                        }
516                }
517        }
518        else if (!opts.dontReorganise)
519        {
520                reorganiseVertexBuffers(mesh);
521        }
522
523}
524
525void buildLod(Mesh* mesh)
526{       
527        String response;
528
529        // Prompt for LOD generation?
530        bool genLod = false;
531        bool askLodDtls = false;
532        if (!opts.interactive) // derive from params if in batch mode
533        {
534                askLodDtls = false;
535                if (opts.numLods == 0)
536                {
537                        genLod = false;
538                }
539                else
540                {
541                        genLod = true;
542                }
543        }
544        else if(opts.numLods == 0) // otherwise only ask if not specified on command line
545        {
546                if (mesh->getNumLodLevels() > 1)
547                {
548                        std::cout << "\nXML already contains level-of detail information.\n"
549                                "Do you want to: (u)se it, (r)eplace it, or (d)rop it?";
550                        while (response == "")
551                        {
552                                cin >> response;
553                                StringUtil::toLowerCase(response);
554                                if (response == "u")
555                                {
556                                        // Do nothing
557                                }
558                                else if (response == "d")
559                                {
560                                        mesh->removeLodLevels();
561                                }
562                                else if (response == "r")
563                                {
564                                        genLod = true;
565                                        askLodDtls = true;
566
567                                }
568                                else
569                                {
570                                        response = "";
571                                }
572                        }// while response == ""
573                }
574                else // no existing LOD
575                {
576                        std::cout << "\nWould you like to generate LOD information? (y/n)";
577                        while (response == "")
578                        {
579                                cin >> response;
580                                StringUtil::toLowerCase(response);
581                                if (response == "n")
582                                {
583                                        // Do nothing
584                                }
585                                else if (response == "y")
586                                {
587                                        genLod = true;
588                                        askLodDtls = true;
589                                }
590                        }
591                }
592        }
593
594        if (genLod)
595        {
596                unsigned short numLod;
597                ProgressiveMesh::VertexReductionQuota quota;
598                Real reduction;
599                Mesh::LodDistanceList distanceList;
600
601                if (askLodDtls)
602                {
603                        cout << "\nHow many extra LOD levels would you like to generate?";
604                        cin >> numLod;
605
606                        cout << "\nWhat unit of reduction would you like to use:" <<
607                                "\n(f)ixed or (p)roportional?";
608                        cin >> response;
609                        StringUtil::toLowerCase(response);
610                        if (response == "f")
611                        {
612                                quota = ProgressiveMesh::VRQ_CONSTANT;
613                                cout << "\nHow many vertices should be removed at each LOD?";
614                        }
615                        else
616                        {
617                                quota = ProgressiveMesh::VRQ_PROPORTIONAL;
618                                cout << "\nWhat percentage of remaining vertices should be removed "
619                                        "\at each LOD (e.g. 50)?";
620                        }
621                        cin >> reduction;
622                        if (quota == ProgressiveMesh::VRQ_PROPORTIONAL)
623                        {
624                                // Percentage -> parametric
625                                reduction = reduction * 0.01f;
626                        }
627
628                        cout << "\nEnter the distance for each LOD to come into effect.";
629
630                        Real distance;
631                        for (unsigned short iLod = 0; iLod < numLod; ++iLod)
632                        {
633                                cout << "\nLOD Level " << (iLod+1) << ":";
634                                cin >> distance;
635                                distanceList.push_back(distance);
636                        }
637                }
638                else
639                {
640                        numLod = opts.numLods;
641                        quota = opts.usePercent?
642                                ProgressiveMesh::VRQ_PROPORTIONAL : ProgressiveMesh::VRQ_CONSTANT;
643                        if (opts.usePercent)
644                        {
645                                reduction = opts.lodPercent * 0.01f;
646                        }
647                        else
648                        {
649                                reduction = opts.lodFixed;
650                        }
651                        Real currDist = 0;
652                        for (unsigned short iLod = 0; iLod < numLod; ++iLod)
653                        {
654                                currDist += opts.lodDist;
655                                distanceList.push_back(currDist);
656                        }
657
658                }
659
660                mesh->generateLodLevels(distanceList, quota, reduction);
661        }
662
663}
664
665void checkColour(VertexData* vdata, bool &hasColour, bool &hasAmbiguousColour,
666        VertexElementType& originalType)
667{
668        const VertexDeclaration::VertexElementList& elemList = vdata->vertexDeclaration->getElements();
669        for (VertexDeclaration::VertexElementList::const_iterator i = elemList.begin();
670                i != elemList.end(); ++i)
671        {
672                const VertexElement& elem = *i;
673                switch (elem.getType())
674                {
675                case VET_COLOUR:
676                        hasAmbiguousColour = true;
677                case VET_COLOUR_ABGR:
678                case VET_COLOUR_ARGB:
679                        hasColour = true;
680                        originalType = elem.getType();
681                default:
682                        // do nothing
683                        ;
684                };
685        }
686
687}
688
689void resolveColourAmbiguities(Mesh* mesh)
690{
691        // Check what we're dealing with
692        bool hasColour = false;
693        bool hasAmbiguousColour = false;
694        VertexElementType originalType;
695        if (mesh->sharedVertexData)
696        {
697                checkColour(mesh->sharedVertexData, hasColour, hasAmbiguousColour, originalType);
698        }
699        for (unsigned short i = 0; i < mesh->getNumSubMeshes(); ++i)
700        {
701                SubMesh* sm = mesh->getSubMesh(i);
702                if (sm->useSharedVertices == false)
703                {
704                        checkColour(sm->vertexData, hasColour, hasAmbiguousColour, originalType);
705                }
706        }
707
708        String response;
709        if (hasAmbiguousColour)
710        {
711                if (opts.srcColourFormatSet)
712                {
713                        originalType = opts.srcColourFormat;
714                }
715                else
716                {
717                        // unknown input colour, have to ask
718                        std::cout << "\nYour mesh has vertex colours but I don't know whether they were generated\n"
719                                << "using GL or D3D ordering. Please indicate which was used when the mesh was\n"
720                                << "created (type 'gl' or 'd3d').\n";
721                        while (response.empty())
722                        {
723                                cin >> response;
724                                StringUtil::toLowerCase(response);
725                                if (response == "d3d")
726                                {
727                                        originalType = VET_COLOUR_ARGB;
728                                }
729                                else if (response == "gl")
730                                {
731                                        originalType = VET_COLOUR_ABGR;
732                                }
733                                else
734                                {
735                                        response = "";
736                                }
737                        }
738                }
739        }
740
741        // Ask what format we want to save in
742        VertexElementType desiredType;
743        if (hasColour)
744        {
745                if (opts.destColourFormatSet)
746                {
747                        desiredType = opts.destColourFormat;
748                }
749                else
750                {
751                        if (opts.interactive)
752                        {
753
754                                response = "";
755                                std::cout << "\nYour mesh has vertex colours, which can be stored in one of two layouts,\n"
756                                        << "each of which will be slightly faster to load in a different render system.\n"
757                                        << "Do you want to prefer Direct3D (d3d) or OpenGL (gl)?\n";
758                                while (response.empty())
759                                {
760                                        cin >> response;
761                                        StringUtil::toLowerCase(response);
762                                        if (response == "d3d")
763                                        {
764                                                desiredType = VET_COLOUR_ARGB;
765                                        }
766                                        else if (response == "gl")
767                                        {
768                                                desiredType = VET_COLOUR_ABGR;
769                                        }
770                                        else
771                                        {
772                                                response = "";
773                                        }
774                                }
775                        }
776                        else
777                        {
778                                // 'do no harm'
779                                return;
780                        }
781                }
782
783        }
784
785        if (mesh->sharedVertexData)
786        {
787                mesh->sharedVertexData->convertPackedColour(originalType, desiredType);
788        }
789        for (unsigned short i = 0; i < mesh->getNumSubMeshes(); ++i)
790        {
791                SubMesh* sm = mesh->getSubMesh(i);
792                if (sm->useSharedVertices == false)
793                {
794                        sm->vertexData->convertPackedColour(originalType, desiredType);
795                }
796        }
797
798
799}
800
801int main(int numargs, char** args)
802{
803    if (numargs < 2)
804    {
805        help();
806        return -1;
807    }
808
809    logMgr = new LogManager();
810        logMgr->createLog("OgreMeshUpgrade.log", true);
811    rgm = new ResourceGroupManager();
812    mth = new Math();
813    matMgr = new MaterialManager();
814    matMgr->initialise();
815    skelMgr = new SkeletonManager();
816    meshSerializer = new MeshSerializer();
817    skeletonSerializer = new SkeletonSerializer();
818    bufferManager = new DefaultHardwareBufferManager(); // needed because we don't have a rendersystem
819    meshMgr = new MeshManager();
820        // don't pad during upgrade
821        meshMgr->setBoundsPaddingFactor(0.0f);
822
823   
824    UnaryOptionList unOptList;
825    BinaryOptionList binOptList;
826
827        unOptList["-i"] = false;
828    unOptList["-e"] = false;
829    unOptList["-t"] = false;
830        unOptList["-r"] = false;
831        unOptList["-gl"] = false;
832        unOptList["-d3d"] = false;
833        unOptList["-srcgl"] = false;
834        unOptList["-srcd3d"] = false;
835        binOptList["-l"] = "";
836        binOptList["-d"] = "";
837        binOptList["-p"] = "";
838        binOptList["-f"] = "";
839        binOptList["-E"] = "";
840
841    int startIdx = findCommandLineOpts(numargs, args, unOptList, binOptList);
842        parseOpts(unOptList, binOptList);
843
844    String source(args[startIdx]);
845
846    logMgr->createLog("OgreMeshUpgrader.log");
847
848
849    // Load the mesh
850    struct stat tagStat;
851
852    FILE* pFile = fopen( source.c_str(), "rb" );
853    if (!pFile)
854    {
855        OGRE_EXCEPT(Exception::ERR_FILE_NOT_FOUND,
856            "File " + source + " not found.", "OgreMeshUpgrade");
857    }
858    stat( source.c_str(), &tagStat );
859    MemoryDataStream* memstream = new MemoryDataStream(source, tagStat.st_size, true);
860    fread( (void*)memstream->getPtr(), tagStat.st_size, 1, pFile );
861    fclose( pFile );
862
863        Mesh mesh(meshMgr, "conversion", 0, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
864
865    DataStreamPtr stream(memstream);
866    meshSerializer->importMesh(stream, &mesh);
867
868    // Write out the converted mesh
869    String dest;
870    if (numargs == startIdx + 2)
871    {
872        dest = args[startIdx + 1];
873    }
874    else
875    {
876        dest = source;
877    }
878
879        String response;
880
881        vertexBufferReorg(mesh);
882
883        // Deal with VET_COLOUR ambiguities
884        resolveColourAmbiguities(&mesh);
885       
886        buildLod(&mesh);
887
888    // Make sure we generate edge lists, provided they are not deliberately disabled
889    if (!opts.suppressEdgeLists)
890    {
891        cout << "\nGenerating edge lists.." << std::endl;
892        mesh.buildEdgeList();
893    }
894        else
895        {
896                mesh.freeEdgeList();
897        }
898
899    // Generate tangents?
900    if (opts.generateTangents)
901    {
902        unsigned short srcTex, destTex;
903        bool existing = mesh.suggestTangentVectorBuildParams(srcTex, destTex);
904        if (existing)
905        {
906                        if (opts.interactive)
907                        {
908                                std::cout << "\nThis mesh appears to already have a set of 3D texture coordinates, " <<
909                                        "which would suggest tangent vectors have already been calculated. Do you really " <<
910                                        "want to generate new tangent vectors (may duplicate)? (y/n)";
911                                while (response == "")
912                                {
913                                        cin >> response;
914                                        StringUtil::toLowerCase(response);
915                                        if (response == "y")
916                                        {
917                                                // Do nothing
918                                        }
919                                        else if (response == "n")
920                                        {
921                                                opts.generateTangents = false;
922                                        }
923                                        else
924                                        {
925                                                response = "";
926                                        }
927                                }
928                        }
929                        else
930                        {
931                                // safe
932                                opts.generateTangents = false;
933                        }
934
935        }
936        if (opts.generateTangents)
937        {
938            cout << "Generating tangent vectors...." << std::endl;
939            mesh.buildTangentVectors(srcTex, destTex);
940        }
941    }
942
943
944
945    meshSerializer->exportMesh(&mesh, dest, opts.endian);
946   
947
948
949
950    delete meshMgr;
951    delete skeletonSerializer;
952    delete meshSerializer;
953    delete skelMgr;
954    delete matMgr;
955    delete mth;
956    delete rgm;
957    delete logMgr;
958
959    return 0;
960
961}
962
Note: See TracBrowser for help on using the repository browser.