root/OpenSceneGraph/trunk/examples/osganalysis/osganalysis.cpp @ 12035

Revision 12035, 25.1 kB (checked in by robert, 4 years ago)

Added --speed option and output of buffer object and texture object pool stats at the end of the animation path.

Line 
1/* OpenSceneGraph example, osgterrain.
2*
3*  Permission is hereby granted, free of charge, to any person obtaining a copy
4*  of this software and associated documentation files (the "Software"), to deal
5*  in the Software without restriction, including without limitation the rights
6*  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7*  copies of the Software, and to permit persons to whom the Software is
8*  furnished to do so, subject to the following conditions:
9*
10*  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
11*  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
12*  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
13*  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
14*  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
15*  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
16*  THE SOFTWARE.
17*/
18
19
20#include <osgViewer/Viewer>
21#include <osgViewer/ViewerEventHandlers>
22
23#include <osgDB/ReadFile>
24#include <osgDB/WriteFile>
25#include <osgDB/FileNameUtils>
26
27#include <osgGA/TrackballManipulator>
28#include <osgGA/StateSetManipulator>
29#include <osgGA/TrackballManipulator>
30#include <osgGA/FlightManipulator>
31#include <osgGA/DriveManipulator>
32#include <osgGA/KeySwitchMatrixManipulator>
33#include <osgGA/AnimationPathManipulator>
34#include <osgGA/TerrainManipulator>
35
36#include <osgUtil/IncrementalCompileOperation>
37#include <osgUtil/Simplifier>
38#include <osgUtil/MeshOptimizers>
39
40class StripStateVisitor : public osg::NodeVisitor
41{
42public:
43    StripStateVisitor(bool useStateSets, bool useDisplayLists, bool useVBO):
44        osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN),
45        _useStateSets(useStateSets),
46        _useDisplayLists(useDisplayLists),
47        _useVBO(useVBO) {}
48
49    bool _useStateSets;
50    bool _useDisplayLists;
51    bool _useVBO;
52
53    void apply(osg::Node& node)
54    {
55        if (!_useStateSets && node.getStateSet()) node.setStateSet(0);
56        traverse(node);
57    }
58
59    void apply(osg::Geode& node)
60    {
61        if (!_useStateSets && node.getStateSet()) node.setStateSet(0);
62        for(unsigned int i = 0; i<node.getNumDrawables(); ++i)
63        {
64            process(*node.getDrawable(i));
65        }
66
67        traverse(node);
68    }
69
70    void process(osg::Drawable& drawable)
71    {
72        if (!_useStateSets && drawable.getStateSet())
73        {
74            drawable.setStateSet(0);
75        }
76
77        drawable.setUseDisplayList(_useDisplayLists);
78        drawable.setUseVertexBufferObjects(_useVBO);
79    }
80};
81
82class SwapArrayVisitor : public osg::ArrayVisitor
83{
84public:
85    SwapArrayVisitor(osg::Array* array):
86        _array(array) {}
87
88    template <class ARRAY>
89    void apply_imp(ARRAY& array)
90    {
91        if (array.getType()!=_array->getType())
92        {
93            OSG_NOTICE<<"Arrays incompatible"<<std::endl;
94            return;
95        }
96        OSG_NOTICE<<"Swapping Array"<<std::endl;
97        array.swap(*static_cast<ARRAY*>(_array));
98    }
99
100    virtual void apply(osg::ByteArray& ba) { apply_imp(ba); }
101    virtual void apply(osg::ShortArray& ba) { apply_imp(ba); }
102    virtual void apply(osg::IntArray& ba) { apply_imp(ba); }
103    virtual void apply(osg::UByteArray& ba) { apply_imp(ba); }
104    virtual void apply(osg::UShortArray& ba) { apply_imp(ba); }
105    virtual void apply(osg::UIntArray& ba) { apply_imp(ba); }
106    virtual void apply(osg::Vec4ubArray& ba) { apply_imp(ba); }
107    virtual void apply(osg::FloatArray& ba) { apply_imp(ba); }
108    virtual void apply(osg::Vec2Array& ba) { apply_imp(ba); }
109    virtual void apply(osg::Vec3Array& ba) { apply_imp(ba); }
110    virtual void apply(osg::Vec4Array& ba) { apply_imp(ba); }
111
112    osg::Array* _array;
113};
114
115class MemoryVisitor : public osg::NodeVisitor
116{
117public:
118     MemoryVisitor():
119         osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN) {}
120
121
122    void reset()
123    {
124         _nodes.clear();
125         _geometryMap.clear();
126         _arrayMap.clear();
127         _primitiveSetMap.clear();
128    }
129
130    void apply(osg::Node& node)
131    {
132        _nodes.insert(&node);
133        traverse(node);
134    }
135
136    void apply(osg::Geode& geode)
137    {
138        _nodes.insert(&geode);
139        for(unsigned int i=0; i<geode.getNumDrawables(); ++i)
140        {
141            apply(&geode, geode.getDrawable(i));
142        }
143    }
144
145    void apply(osg::Geode* geode, osg::Drawable* drawable)
146    {
147        if (!drawable) return;
148
149        osg::Geometry* geometry = drawable->asGeometry();
150        if (geometry)
151        {
152            _geometryMap[geometry].insert(geode);
153
154            apply(geometry, geometry->getVertexArray());
155            apply(geometry, geometry->getNormalArray());
156            apply(geometry, geometry->getColorArray());
157            apply(geometry, geometry->getSecondaryColorArray());
158            apply(geometry, geometry->getFogCoordArray());
159
160            for(unsigned int i=0; i<geometry->getNumTexCoordArrays(); ++i)
161            {
162                apply(geometry, geometry->getTexCoordArray(i));
163            }
164            for(unsigned int i=0; i<geometry->getNumVertexAttribArrays(); ++i)
165            {
166                apply(geometry, geometry->getVertexAttribArray(i));
167            }
168
169            for(unsigned int i=0; i<geometry->getNumPrimitiveSets(); ++i)
170            {
171                apply(geometry, geometry->getPrimitiveSet(i));
172            }
173        }
174    }
175
176    void apply(osg::Geometry* geometry, osg::Array* array)
177    {
178        if (!array) return;
179        _arrayMap[array].insert(geometry);
180    }
181
182    void apply(osg::Geometry* geometry, osg::PrimitiveSet* primitiveSet)
183    {
184        if (!primitiveSet) return;
185        _primitiveSetMap[primitiveSet].insert(geometry);
186    }
187
188    void report(std::ostream& out)
189    {
190        out<<"Nodes "<<_nodes.size()<<std::endl;
191        out<<"Geometries "<<_geometryMap.size()<<std::endl;
192        out<<"Arrays "<<_arrayMap.size()<<std::endl;
193        out<<"PrimitiveSets "<<_primitiveSetMap.size()<<std::endl;
194    }
195
196    void reallocate()
197    {
198        OSG_NOTICE<<"Reallocating Arrays"<<std::endl;
199
200        typedef std::vector< osg::ref_ptr<osg::Array> > ArrayVector;
201        typedef std::vector< osg::ref_ptr<osg::Geometry> > GeometryVector;
202        ArrayVector newArrays;
203        GeometryVector newGeometries;
204        for(GeometryMap::iterator itr = _geometryMap.begin();
205            itr != _geometryMap.end();
206            ++itr)
207        {
208            osg::Geometry* geometry = itr->first;
209            bool useVBO = geometry->getUseVertexBufferObjects();
210            osg::Geometry* newGeometry = osg::clone(geometry, osg::CopyOp(osg::CopyOp::DEEP_COPY_ALL));
211            newGeometry->setUseVertexBufferObjects(false);
212            newGeometry->setUseVertexBufferObjects(useVBO);
213            newGeometries.push_back(newGeometry);
214        }
215
216        GeometryVector::iterator geom_itr = newGeometries.begin();
217        for(GeometryMap::iterator itr = _geometryMap.begin();
218            itr != _geometryMap.end();
219            ++itr, ++geom_itr)
220        {
221            osg::Geometry* geometry = itr->first;
222            Geodes& geodes = itr->second;
223            for(Geodes::iterator gitr = geodes.begin();
224                gitr != geodes.end();
225                ++gitr)
226            {
227                osg::Geode* geode = const_cast<osg::Geode*>(*gitr);
228                geode->replaceDrawable(geometry, geom_itr->get());
229            }
230        }
231    }
232
233    typedef std::vector< osg::ref_ptr<osg::Geometry> > GeometryVector;
234    typedef std::pair<osg::Array*, osg::Array*> ArrayPair;
235    typedef std::vector< ArrayPair > ArrayVector;
236    typedef std::pair<osg::PrimitiveSet*, osg::PrimitiveSet*> PrimitiveSetPair;
237    typedef std::vector< PrimitiveSetPair > PrimitiveSetVector;
238
239    osg::Array* cloneArray(ArrayVector& arrayVector, osg::Array* array)
240    {
241        if (!array) return 0;
242        osg::Array* newArray = static_cast<osg::Array*>(array->cloneType());
243        arrayVector.push_back(ArrayPair(array,newArray));
244        return newArray;
245    }
246
247    osg::PrimitiveSet* clonePrimitiveSet(PrimitiveSetVector& psVector, osg::PrimitiveSet* ps)
248    {
249        if (!ps) return 0;
250        osg::PrimitiveSet* newPS = static_cast<osg::PrimitiveSet*>(ps->cloneType());
251        psVector.push_back(PrimitiveSetPair(ps,newPS));
252        return newPS;
253    }
254
255    void reallocate2()
256    {
257        OSG_NOTICE<<"Reallocating Arrays"<<std::endl;
258
259        ArrayVector arrayVector;
260        PrimitiveSetVector primitiveSetVector;
261        GeometryVector newGeometries;
262
263        for(GeometryMap::iterator itr = _geometryMap.begin();
264            itr != _geometryMap.end();
265            ++itr)
266        {
267            osg::Geometry* geometry = itr->first;
268            osg::ref_ptr<osg::Geometry> newGeometry = osg::clone(geometry, osg::CopyOp::SHALLOW_COPY);
269            newGeometries.push_back(newGeometry.get());
270
271            newGeometry->setVertexArray(cloneArray(arrayVector, geometry->getVertexArray()));
272            newGeometry->setNormalArray(cloneArray(arrayVector, geometry->getNormalArray()));
273            newGeometry->setColorArray(cloneArray(arrayVector, geometry->getColorArray()));
274            newGeometry->setSecondaryColorArray(cloneArray(arrayVector, geometry->getSecondaryColorArray()));
275            newGeometry->setFogCoordArray(cloneArray(arrayVector, geometry->getFogCoordArray()));
276            for(unsigned int i=0; i<geometry->getNumTexCoordArrays(); ++i)
277            {
278                newGeometry->setTexCoordArray(i, cloneArray(arrayVector, geometry->getTexCoordArray(i)));
279            }
280            for(unsigned int i=0; i<geometry->getNumVertexAttribArrays(); ++i)
281            {
282                newGeometry->setVertexAttribArray(i, cloneArray(arrayVector, geometry->getVertexAttribArray(i)));
283            }
284
285            for(unsigned int i=0; i<geometry->getNumPrimitiveSets(); ++i)
286            {
287                newGeometry->setPrimitiveSet(i,clonePrimitiveSet(primitiveSetVector, geometry->getPrimitiveSet(i)));
288            }
289        }
290
291        GeometryVector::iterator geom_itr = newGeometries.begin();
292        for(GeometryMap::iterator itr = _geometryMap.begin();
293            itr != _geometryMap.end();
294            ++itr, ++geom_itr)
295        {
296            osg::Geometry* geometry = itr->first;
297            Geodes& geodes = itr->second;
298            for(Geodes::iterator gitr = geodes.begin();
299                gitr != geodes.end();
300                ++gitr)
301            {
302                osg::Geode* geode = const_cast<osg::Geode*>(*gitr);
303                geode->replaceDrawable(geometry, geom_itr->get());
304            }
305        }
306    }
307
308protected:
309
310     typedef std::set<osg::Node*>  Nodes;
311     typedef std::set<osg::Geode*>  Geodes;
312     typedef std::set<osg::Geometry*>  Geometries;
313     typedef std::map<osg::Geometry*, Geodes> GeometryMap;
314     typedef std::map<osg::Array*, Geometries> ArrayMap;
315     typedef std::map<osg::PrimitiveSet*, Geometries> PrimitiveSetMap;
316
317     Nodes              _nodes;
318     GeometryMap        _geometryMap;
319     ArrayMap           _arrayMap;
320     PrimitiveSetMap    _primitiveSetMap;
321};
322
323class SceneGraphProcessor : public osg::Referenced
324{
325public:
326    SceneGraphProcessor()
327    {
328        _init();
329    }
330
331    SceneGraphProcessor(osg::ArgumentParser& arguments)
332    {
333        _init();
334
335        while (arguments.read("--vbo")) { modifyDrawableSettings = true; useVBO = true;  }
336        while (arguments.read("--dl")) { modifyDrawableSettings = true; useDisplayLists = true;  }
337
338        while (arguments.read("-s", simplificatioRatio)) {}
339        while (arguments.read("--tristripper")) { useTriStripVisitor=true; }
340        while (arguments.read("--no-tristripper")) { useTriStripVisitor=false; }
341        while (arguments.read("--smoother")) {  useSmoothingVisitor=true; }
342        while (arguments.read("--no-smoother")) {  useSmoothingVisitor=false; }
343
344        while (arguments.read("--remove-duplicate-vertices") || arguments.read("--rdv")) removeDuplicateVertices = true;
345        while (arguments.read("--optimize-vertex-cache") || arguments.read("--ovc")) optimizeVertexCache = true;
346        while (arguments.read("--optimize-vertex-order") || arguments.read("--ovo")) optimizeVertexOrder = true;
347
348        while (arguments.read("--build-mipmaps")) { modifyTextureSettings = true; buildImageMipmaps = true; }
349        while (arguments.read("--compress")) { modifyTextureSettings = true; compressImages = true; }
350        while (arguments.read("--disable-mipmaps")) { modifyTextureSettings = true; disableMipmaps = true; }
351
352        while (arguments.read("--reallocate") || arguments.read("--ra") ) { reallocateMemory = true; }
353
354
355        OSG_NOTICE<<"simplificatioRatio="<<simplificatioRatio<<std::endl;
356    }
357
358    virtual osg::Node* process(osg::Node* node)
359    {
360        if (!node)
361        {
362            OSG_NOTICE<<"SceneGraphProcessor::process(Node*) : error cannot process NULL Node."<<std::endl;
363            return 0;
364        }
365
366        OSG_NOTICE<<"SceneGraphProcessor::process("<<node<<") : "<<node->getName()<<std::endl;
367
368        if (simplificatioRatio < 1.0)
369        {
370            OSG_NOTICE<<"Running simplifier with simplification ratio="<<simplificatioRatio<<std::endl;
371            float maxError = 4.0f;
372            osgUtil::Simplifier simplifier(simplificatioRatio, maxError);
373            simplifier.setDoTriStrip(useTriStripVisitor);
374            simplifier.setSmoothing(useSmoothingVisitor);
375            node->accept(simplifier);
376        }
377
378        if (removeDuplicateVertices)
379        {
380            OSG_NOTICE<<"Running osgUtil::IndexMeshVisitor"<<std::endl;
381            osgUtil::IndexMeshVisitor imv;
382            node->accept(imv);
383            imv.makeMesh();
384        }
385
386        if (optimizeVertexCache)
387        {
388            OSG_NOTICE<<"Running osgUtil::VertexCacheVisitor"<<std::endl;
389            osgUtil::VertexCacheVisitor vcv;
390            node->accept(vcv);
391            vcv.optimizeVertices();
392        }
393
394        if (optimizeVertexOrder)
395        {
396            OSG_NOTICE<<"Running osgUtil::VertexAccessOrderVisitor"<<std::endl;
397            osgUtil::VertexAccessOrderVisitor vaov;
398            node->accept(vaov);
399            vaov.optimizeOrder();
400        }
401
402        if (modifyDrawableSettings || modifyTextureSettings)
403        {
404            OSG_NOTICE<<"Running StripStateVisitor"<<std::endl;
405            StripStateVisitor ssv(true, useDisplayLists, useVBO);
406            node->accept(ssv);
407        }
408
409        MemoryVisitor mv;
410        node->accept(mv);
411        mv.report(osg::notify(osg::NOTICE));
412
413        if (reallocateMemory)
414        {
415            OSG_NOTICE<<"Running Reallocation of scene graph memory"<<std::endl;
416            mv.reallocate();
417        }
418
419        mv.reset();
420        node->accept(mv);
421        mv.report(osg::notify(osg::NOTICE));
422
423        return node;
424    }
425
426protected:
427
428    void _init()
429    {
430        modifyDrawableSettings = false;
431        useVBO = false;
432        useDisplayLists = false;
433
434        simplificatioRatio = 1.0;
435        useTriStripVisitor = false;
436        useSmoothingVisitor = false;
437
438        removeDuplicateVertices = false;
439        optimizeVertexCache = false;
440        optimizeVertexOrder = false;
441
442        reallocateMemory = false;
443       
444        modifyTextureSettings = false;
445        buildImageMipmaps = false;
446        compressImages = false;
447        disableMipmaps = false;
448    }
449
450    bool modifyDrawableSettings;
451    bool useVBO;
452    bool useDisplayLists;
453
454    float simplificatioRatio;
455    bool useTriStripVisitor;
456    bool useSmoothingVisitor;
457
458    bool removeDuplicateVertices;
459    bool optimizeVertexCache;
460    bool optimizeVertexOrder;
461
462    bool reallocateMemory;
463   
464    bool modifyTextureSettings;
465    bool buildImageMipmaps;
466    bool compressImages;
467    bool disableMipmaps;
468
469};
470//
471class DatabasePagingOperation : public osg::Operation, public osgUtil::IncrementalCompileOperation::CompileCompletedCallback
472{
473public:
474
475    DatabasePagingOperation(const std::string& filename,
476                            const std::string& outputFilename,
477                             SceneGraphProcessor* sceneGraphProcessor,
478                             osgUtil::IncrementalCompileOperation* ico):
479        Operation("DatabasePaging Operation", false),
480        _filename(filename),
481        _outputFilename(outputFilename),
482        _modelReadyToMerge(false),
483        _sceneGraphProcessor(sceneGraphProcessor),
484        _incrementalCompileOperation(ico)
485        {
486        }
487
488    virtual void operator () (osg::Object* object)
489    {
490        osg::notify(osg::NOTICE)<<"LoadAndCompileOperation "<<_filename<<std::endl;
491
492        _modelReadyToMerge = false;
493        _loadedModel = osgDB::readNodeFile(_filename);
494
495        if (_loadedModel.valid())
496        {
497            if (_sceneGraphProcessor.valid())
498            {
499                _loadedModel = _sceneGraphProcessor->process(_loadedModel.get());
500            }
501        }
502
503        if (_loadedModel.valid())
504        {
505            if (!_outputFilename.empty())
506            {
507                OSG_NOTICE<<"Writing out file "<<_outputFilename<<std::endl;
508               
509                osgDB::writeNodeFile(*_loadedModel, _outputFilename);
510            }
511
512            if (_incrementalCompileOperation.valid())
513            {
514                osg::ref_ptr<osgUtil::IncrementalCompileOperation::CompileSet> compileSet =
515                    new osgUtil::IncrementalCompileOperation::CompileSet(_loadedModel.get());
516
517                compileSet->_compileCompletedCallback = this;
518
519                _incrementalCompileOperation->add(compileSet.get());
520            }
521            else
522            {
523                _modelReadyToMerge = true;
524            }
525        }
526
527        osg::notify(osg::NOTICE)<<"done LoadAndCompileOperation "<<_filename<<std::endl;
528    }
529
530    virtual bool compileCompleted(osgUtil::IncrementalCompileOperation::CompileSet* compileSet)
531    {
532        OSG_NOTICE<<"compileCompleted"<<std::endl;
533        _modelReadyToMerge = true;
534        return true;
535    }
536
537    std::string                                         _filename;
538    std::string                                         _outputFilename;
539    osg::ref_ptr<osg::Node>                             _loadedModel;
540    bool                                                _modelReadyToMerge;
541    osg::ref_ptr<SceneGraphProcessor>                   _sceneGraphProcessor;
542    osg::ref_ptr<osgUtil::IncrementalCompileOperation>  _incrementalCompileOperation;
543};
544
545class TexturePoolHandler : public osgGA::GUIEventHandler
546{
547public:
548    virtual bool handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& aa)
549    {
550        if (ea.getEventType() == osgGA::GUIEventAdapter::KEYUP)
551        {
552            if (ea.getKey()=='r')
553            {
554                osg::Texture::getTextureObjectManager(0)->reportStats(osg::notify(osg::NOTICE));
555                osg::GLBufferObjectManager::getGLBufferObjectManager(0)->reportStats(osg::notify(osg::NOTICE));
556            }
557        }
558        return false;
559    }
560};
561
562struct ReportStatsAnimationCompletedCallback : public osgGA::AnimationPathManipulator::AnimationCompletedCallback
563{
564    virtual void completed(const osgGA::AnimationPathManipulator*)
565    {
566        OSG_NOTICE<<"Animation completed"<<std::endl;
567        osg::Texture::getTextureObjectManager(0)->reportStats(osg::notify(osg::NOTICE));
568        osg::GLBufferObjectManager::getGLBufferObjectManager(0)->reportStats(osg::notify(osg::NOTICE));
569    }
570};
571
572int main(int argc, char** argv)
573{
574    osg::ArgumentParser arguments(&argc, argv);
575
576    // construct the viewer.
577    osgViewer::Viewer viewer(arguments);
578
579    // set up camera manipulators
580    {
581        osg::ref_ptr<osgGA::KeySwitchMatrixManipulator> keyswitchManipulator = new osgGA::KeySwitchMatrixManipulator;
582
583        keyswitchManipulator->addMatrixManipulator( '1', "Trackball", new osgGA::TrackballManipulator() );
584        keyswitchManipulator->addMatrixManipulator( '2', "Flight", new osgGA::FlightManipulator() );
585        keyswitchManipulator->addMatrixManipulator( '3', "Drive", new osgGA::DriveManipulator() );
586        keyswitchManipulator->addMatrixManipulator( '4', "Terrain", new osgGA::TerrainManipulator() );
587
588        char keyForAnimationPath = '8';
589        double animationSpeed = 1.0;
590        while(arguments.read("--speed",animationSpeed) ) {}
591
592        std::string pathfile;
593        while (arguments.read("-p",pathfile))
594        {
595            osgGA::AnimationPathManipulator* apm = new osgGA::AnimationPathManipulator(pathfile);
596            if (apm || !apm->valid())
597            {
598                apm->setTimeScale(animationSpeed);
599                apm->setAnimationCompletedCallback(new ReportStatsAnimationCompletedCallback());
600               
601                unsigned int num = keyswitchManipulator->getNumMatrixManipulators();
602                keyswitchManipulator->addMatrixManipulator( keyForAnimationPath, "Path", apm );
603                keyswitchManipulator->selectMatrixManipulator(num);
604                ++keyForAnimationPath;
605            }
606        }
607
608        viewer.setCameraManipulator( keyswitchManipulator.get() );
609    }
610
611    // set up event handlers
612    {
613        viewer.addEventHandler( new osgViewer::StatsHandler());
614        viewer.addEventHandler( new osgViewer::WindowSizeHandler() );
615        viewer.addEventHandler( new osgGA::StateSetManipulator(viewer.getCamera()->getOrCreateStateSet()) );
616        viewer.addEventHandler( new TexturePoolHandler() );
617    }
618
619    /////////////////////////////////////////////////////////////////////////////////
620    //
621    // IncrementalCompileOperation settings
622    //
623    osg::ref_ptr<osgUtil::IncrementalCompileOperation> incrementalCompile = new osgUtil::IncrementalCompileOperation;
624    viewer.setIncrementalCompileOperation(incrementalCompile.get());
625
626    if (arguments.read("--force") || arguments.read("-f"))
627    {
628        incrementalCompile->assignForceTextureDownloadGeometry();
629    }
630
631    if (arguments.read("-a"))
632    {
633        incrementalCompile->setMinimumTimeAvailableForGLCompileAndDeletePerFrame(1);
634        incrementalCompile->setConservativeTimeRatio(1);
635        incrementalCompile->setMaximumNumOfObjectsToCompilePerFrame(100);
636    }
637    else if (arguments.read("-c"))
638    {
639        incrementalCompile->setMinimumTimeAvailableForGLCompileAndDeletePerFrame(0.0001);
640        incrementalCompile->setConservativeTimeRatio(0.01);
641        incrementalCompile->setMaximumNumOfObjectsToCompilePerFrame(1);
642    }
643
644    /////////////////////////////////////////////////////////////////////////////////
645    //
646    // SceneGraph processing setup
647    //
648    osg::ref_ptr<SceneGraphProcessor> sceneGraphProcessor = new SceneGraphProcessor(arguments);
649
650    /////////////////////////////////////////////////////////////////////////////////
651    //
652    // Database settings
653    //
654    double timeBetweenMerges = 2.0;
655    while(arguments.read("--interval",timeBetweenMerges)) {}
656
657    std::string outputPostfix;
658    while (arguments.read("-o",outputPostfix)) { OSG_NOTICE<<"Set ouputPostfix to "<<outputPostfix<<std::endl; }
659
660
661    typedef std::vector< std::string > FileNames;
662    FileNames fileNames;
663    for(int pos=1;pos<arguments.argc();++pos)
664    {
665        if (!arguments.isOption(pos))
666        {
667            fileNames.push_back(arguments[pos]);
668        }
669    }
670
671    if (fileNames.empty())
672    {
673        OSG_NOTICE<<"No files loaded, please specify files on commandline."<<std::endl;
674        return 1;
675    }
676
677    // load the models using a paging thread and use the incremental compile operation to
678    // manage the compilation of GL objects without breaking frame.
679
680    unsigned int modelIndex = 0;
681
682    osg::ref_ptr<osg::OperationThread> databasePagingThread;
683    osg::ref_ptr<DatabasePagingOperation> databasePagingOperation;
684
685    databasePagingThread = new osg::OperationThread;
686    databasePagingThread->startThread();
687
688    std::string filename = fileNames[modelIndex++];
689    std::string outputFilename = outputPostfix.empty() ? std::string() : osgDB::getStrippedName(filename)+outputPostfix;
690
691    databasePagingOperation = new DatabasePagingOperation(
692        filename,
693        outputFilename,
694        sceneGraphProcessor.get(),
695        incrementalCompile.get());
696
697    databasePagingThread->add(databasePagingOperation.get());
698
699    osg::ref_ptr<osg::Group> group = new osg::Group;
700    viewer.setSceneData(group.get());
701
702    viewer.realize();
703
704    double timeOfLastMerge = viewer.getFrameStamp()->getReferenceTime();
705
706    while(!viewer.done())
707    {
708        viewer.frame();
709
710        double currentTime = viewer.getFrameStamp()->getReferenceTime();
711
712        if (!databasePagingOperation &&
713            modelIndex<fileNames.size() &&
714            (currentTime-timeOfLastMerge)>timeBetweenMerges)
715        {
716            std::string filename = fileNames[modelIndex++];
717            std::string outputFilename = outputPostfix.empty() ? std::string() : osgDB::getStrippedName(filename)+outputPostfix;
718
719            databasePagingOperation = new DatabasePagingOperation(
720                filename,
721                outputFilename,
722                sceneGraphProcessor.get(),
723                incrementalCompile.get());
724
725            databasePagingThread->add(databasePagingOperation.get());
726        }
727
728        if (databasePagingOperation.get() && databasePagingOperation->_modelReadyToMerge)
729        {
730            timeOfLastMerge = currentTime;
731
732            group->removeChildren(0,group->getNumChildren());
733
734            group->addChild(databasePagingOperation->_loadedModel.get());
735
736            viewer.home();
737
738            // we no longer need the paging operation as it's done it's job.
739            databasePagingOperation = 0;
740
741            viewer.home();
742        }
743    }
744
745    return 0;
746}
Note: See TracBrowser for help on using the browser.