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

Revision 11918, 24.1 kB (checked in by robert, 4 years ago)

Added texture pool handler to print out results from texture pool

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