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

Revision 11850, 13.8 kB (checked in by robert, 4 years ago)

Added StateSetManipulator? usage

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
25#include <osgGA/TrackballManipulator>
26#include <osgGA/StateSetManipulator>
27
28#include <osgUtil/IncrementalCompileOperation>
29#include <osgUtil/Simplifier>
30
31class StripStateVisitor : public osg::NodeVisitor
32{
33public:
34    StripStateVisitor(bool useStateSets, bool useDisplayLists, bool useVBO):
35        osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN),
36        _useStateSets(useStateSets),
37        _useDisplayLists(useDisplayLists),
38        _useVBO(useVBO) {}
39
40    bool _useStateSets;
41    bool _useDisplayLists;
42    bool _useVBO;
43
44    void apply(osg::Node& node)
45    {
46        if (!_useStateSets && node.getStateSet()) node.setStateSet(0);
47        traverse(node);
48    }
49
50    void apply(osg::Geode& node)
51    {
52        if (!_useStateSets && node.getStateSet()) node.setStateSet(0);
53        for(unsigned int i = 0; i<node.getNumDrawables(); ++i)
54        {
55            process(*node.getDrawable(i));
56        }
57
58        traverse(node);
59    }
60
61    void process(osg::Drawable& drawable)
62    {
63        if (!_useStateSets && drawable.getStateSet())
64        {
65            drawable.setStateSet(0);
66        }
67
68        drawable.setUseDisplayList(_useDisplayLists);
69        drawable.setUseVertexBufferObjects(_useVBO);
70    }
71};
72
73class SceneGraphProcessor : public osg::Referenced
74{
75public:
76    SceneGraphProcessor()
77    {
78        _init();
79    }
80
81    SceneGraphProcessor(osg::ArgumentParser& arguments)
82    {
83        _init();
84
85        while (arguments.read("--vbo")) { modifyDrawableSettings = true; useVBO = true;  }
86        while (arguments.read("--dl")) { modifyDrawableSettings = true; useDisplayLists = true;  }
87
88        while (arguments.read("-s", simplificatioRatio)) {}
89
90        while (arguments.read("--build-mipmaps")) { modifyTextureSettings = true; buildImageMipmaps = true; }
91        while (arguments.read("--compress")) { modifyTextureSettings = true; compressImages = true; }
92        while (arguments.read("--disable-mipmaps")) { modifyTextureSettings = true; disableMipmaps = true; }
93
94        OSG_NOTICE<<"simplificatioRatio="<<simplificatioRatio<<std::endl;
95    }
96
97    virtual osg::Node* process(osg::Node* node)
98    {
99        if (!node)
100        {
101            OSG_NOTICE<<"SceneGraphProcessor::process(Node*) : error cannot process NULL Node."<<std::endl;
102            return 0;
103        }
104
105        OSG_NOTICE<<"SceneGraphProcessor::process("<<node<<") : "<<node->getName()<<std::endl;
106
107        if (simplificatioRatio < 1.0)
108        {
109            OSG_NOTICE<<"Running simplifier with simplification ratio="<<simplificatioRatio<<std::endl;
110            float maxError = 4.0f;
111            osgUtil::Simplifier simplifier(simplificatioRatio, maxError);
112            node->accept(simplifier);
113        }
114
115        if (modifyDrawableSettings || modifyTextureSettings)
116        {
117            OSG_NOTICE<<"Running StripStateVisitor"<<std::endl;
118            StripStateVisitor ssv(true, useDisplayLists, useVBO);
119            node->accept(ssv);
120        }
121
122
123        return node;
124    }
125
126protected:
127
128    void _init()
129    {
130        modifyDrawableSettings = false;
131        useVBO = false;
132        useDisplayLists = false;
133        simplificatioRatio = 1.0;
134
135        modifyTextureSettings = false;
136        buildImageMipmaps = false;
137        compressImages = false;
138        disableMipmaps = false;
139    }
140
141    bool modifyDrawableSettings;
142    bool useVBO;
143    bool useDisplayLists;
144    float simplificatioRatio;
145
146    bool modifyTextureSettings;
147    bool buildImageMipmaps;
148    bool compressImages;
149    bool disableMipmaps;
150
151};
152
153
154class CustomCompileCompletedCallback : public osgUtil::IncrementalCompileOperation::CompileCompletedCallback
155{
156public:
157    CustomCompileCompletedCallback():
158        completed(false) {}
159
160    virtual bool compileCompleted(osgUtil::IncrementalCompileOperation::CompileSet* compileSet)
161    {
162        OSG_NOTICE<<"compileCompleted"<<std::endl;
163        completed = true;
164        return true;
165    }
166
167    bool completed;
168};
169
170class DatabasePagingOperation : public osg::Operation, public osgUtil::IncrementalCompileOperation::CompileCompletedCallback
171{
172public:
173
174    DatabasePagingOperation(const std::string& filename,
175                             SceneGraphProcessor* sceneGraphProcessor,
176                             osgUtil::IncrementalCompileOperation* ico):
177        Operation("DatabasePaging Operation", false),
178        _filename(filename),
179        _modelReadyToMerge(false),
180        _sceneGraphProcessor(sceneGraphProcessor),
181        _incrementalCompileOperation(ico) {}
182
183    virtual void operator () (osg::Object* object)
184    {
185        osg::notify(osg::NOTICE)<<"LoadAndCompileOperation "<<_filename<<std::endl;
186
187        _modelReadyToMerge = false;
188        _loadedModel = osgDB::readNodeFile(_filename);
189
190        if (_loadedModel.valid())
191        {
192            if (_sceneGraphProcessor.valid())
193            {
194                _loadedModel = _sceneGraphProcessor->process(_loadedModel.get());
195            }
196        }
197
198        if (_loadedModel.valid())
199        {
200            if (_incrementalCompileOperation.valid())
201            {
202                osg::ref_ptr<osgUtil::IncrementalCompileOperation::CompileSet> compileSet =
203                    new osgUtil::IncrementalCompileOperation::CompileSet(_loadedModel.get());
204
205                compileSet->_compileCompletedCallback = this;
206
207                _incrementalCompileOperation->add(compileSet.get());
208            }
209            else
210            {
211                _modelReadyToMerge = true;
212            }
213        }
214
215        osg::notify(osg::NOTICE)<<"done LoadAndCompileOperation "<<_filename<<std::endl;
216    }
217
218    virtual bool compileCompleted(osgUtil::IncrementalCompileOperation::CompileSet* compileSet)
219    {
220        OSG_NOTICE<<"compileCompleted"<<std::endl;
221        _modelReadyToMerge = true;
222        return true;
223    }
224
225    std::string                                         _filename;
226    osg::ref_ptr<osg::Node>                             _loadedModel;
227    bool                                                _modelReadyToMerge;
228    osg::ref_ptr<SceneGraphProcessor>                   _sceneGraphProcessor;
229    osg::ref_ptr<osgUtil::IncrementalCompileOperation>  _incrementalCompileOperation;
230};
231
232
233int main(int argc, char** argv)
234{
235    osg::ArgumentParser arguments(&argc, argv);
236
237    // construct the viewer.
238    osgViewer::Viewer viewer(arguments);
239
240    viewer.setCameraManipulator( new osgGA::TrackballManipulator() );
241    viewer.addEventHandler( new osgViewer::StatsHandler());
242    viewer.addEventHandler( new osgViewer::WindowSizeHandler() );
243    viewer.addEventHandler( new osgGA::StateSetManipulator(viewer.getCamera()->getOrCreateStateSet()) );
244
245    /////////////////////////////////////////////////////////////////////////////////
246    //
247    // IncrementalCompileOperation settings
248    //
249    osg::ref_ptr<osgUtil::IncrementalCompileOperation> incrementalCompile = new osgUtil::IncrementalCompileOperation;
250    viewer.setIncrementalCompileOperation(incrementalCompile.get());
251
252    if (arguments.read("--force") || arguments.read("-f"))
253    {
254        incrementalCompile->assignForceTextureDownloadGeometry();
255    }
256
257    if (arguments.read("-a"))
258    {
259        incrementalCompile->setMinimumTimeAvailableForGLCompileAndDeletePerFrame(1);
260        incrementalCompile->setConservativeTimeRatio(1);
261        incrementalCompile->setMaximumNumOfObjectsToCompilePerFrame(100);
262    }
263    else if (arguments.read("-c"))
264    {
265        incrementalCompile->setMinimumTimeAvailableForGLCompileAndDeletePerFrame(0.0001);
266        incrementalCompile->setConservativeTimeRatio(0.01);
267        incrementalCompile->setMaximumNumOfObjectsToCompilePerFrame(1);
268    }
269
270    /////////////////////////////////////////////////////////////////////////////////
271    //
272    // SceneGraph processing setup
273    //
274    osg::ref_ptr<SceneGraphProcessor> sceneGraphProcessor = new SceneGraphProcessor(arguments);
275
276    /////////////////////////////////////////////////////////////////////////////////
277    //
278    // Database settings
279    //
280    double timeBetweenMerges = 2.0;
281    while(arguments.read("--interval",timeBetweenMerges)) {}
282
283    bool readDatabasesInPagingThread = false;
284    while(arguments.read("--paging")) { readDatabasesInPagingThread = true; }
285
286    typedef std::vector< std::string > FileNames;
287    FileNames fileNames;
288    for(int pos=1;pos<arguments.argc();++pos)
289    {
290        if (!arguments.isOption(pos))
291        {
292            fileNames.push_back(arguments[pos]);
293        }
294    }
295
296    if (fileNames.empty())
297    {
298        OSG_NOTICE<<"No files loaded, please specifies files on commandline."<<std::endl;
299        return 1;
300    }
301
302
303    if (readDatabasesInPagingThread)
304    {
305        // load the models using a paging thread and use the incremental compile operation to
306        // manage the compilation of GL objects without breaking frame.
307
308        unsigned int modelIndex = 0;
309
310        osg::ref_ptr<osg::OperationThread> databasePagingThread;
311        osg::ref_ptr<DatabasePagingOperation> databasePagingOperation;
312
313        databasePagingThread = new osg::OperationThread;
314        databasePagingThread->startThread();
315
316        databasePagingOperation = new DatabasePagingOperation(
317            fileNames[modelIndex++],
318            sceneGraphProcessor.get(),
319            incrementalCompile.get());
320
321        databasePagingThread->add(databasePagingOperation.get());
322
323        osg::ref_ptr<osg::Group> group = new osg::Group;
324        viewer.setSceneData(group);
325
326        viewer.realize();
327
328        double timeOfLastMerge = viewer.getFrameStamp()->getReferenceTime();
329
330        while(!viewer.done())
331        {
332            viewer.frame();
333
334            double currentTime = viewer.getFrameStamp()->getReferenceTime();
335
336            if (!databasePagingOperation &&
337                modelIndex<fileNames.size() &&
338                (currentTime-timeOfLastMerge)>timeBetweenMerges)
339            {
340                databasePagingOperation = new DatabasePagingOperation(
341                    fileNames[modelIndex++],
342                    sceneGraphProcessor.get(),
343                    incrementalCompile.get());
344
345                databasePagingThread->add(databasePagingOperation.get());
346            }
347
348            if (databasePagingOperation.get() && databasePagingOperation->_modelReadyToMerge)
349            {
350                timeOfLastMerge = currentTime;
351
352                group->removeChildren(0,group->getNumChildren());
353
354                group->addChild(databasePagingOperation->_loadedModel.get());
355
356                viewer.home();
357
358                // we no longer need the paging operation as it's done it's job.
359                databasePagingOperation = 0;
360
361                viewer.home();
362            }
363        }
364
365    }
366    else
367    {
368        // load the models directly and then just use the IncrementalCompileOperation to
369        // compile the GL objects for us.
370        typedef std::vector< osg::ref_ptr<osg::Node> > Models;
371        Models models;
372        unsigned int modelIndex = 0;
373
374        for(FileNames::iterator itr = fileNames.begin();
375            itr != fileNames.end();
376            ++itr)
377        {
378            // not an option so assume string is a filename.
379            osg::ref_ptr<osg::Node> node = osgDB::readNodeFile( *itr );
380            if(node.valid())
381            {
382                if (node->getName().empty()) node->setName( *itr );
383
384                node = sceneGraphProcessor->process(node.get());
385
386                models.push_back(node.get());
387            }
388        }
389
390        osg::ref_ptr<osg::Group> group = new osg::Group;
391        group->addChild(models[modelIndex++].get());
392
393        viewer.setSceneData(group);
394
395        viewer.realize();
396
397        double timeOfLastMerge = viewer.getFrameStamp()->getReferenceTime();
398
399        osg::ref_ptr<CustomCompileCompletedCallback> compileCompletedCallback;
400
401        while(!viewer.done())
402        {
403            viewer.frame();
404
405            double currentTime = viewer.getFrameStamp()->getReferenceTime();
406
407            if (!compileCompletedCallback &&
408                modelIndex<fileNames.size() &&
409                (currentTime-timeOfLastMerge)>timeBetweenMerges)
410            {
411                OSG_NOTICE<<"Compiling model "<<modelIndex<<" at "<<currentTime<<std::endl;
412
413                osg::ref_ptr<osgUtil::IncrementalCompileOperation::CompileSet> compileSet =
414                    new osgUtil::IncrementalCompileOperation::CompileSet(models[modelIndex].get());
415
416                compileCompletedCallback = new CustomCompileCompletedCallback;
417
418                compileSet->_compileCompletedCallback = compileCompletedCallback;
419
420                incrementalCompile->add(compileSet.get());
421            }
422
423            if (compileCompletedCallback.valid() && compileCompletedCallback->completed)
424            {
425                OSG_NOTICE<<"Merging model "<<modelIndex<<" at "<<currentTime<<std::endl;
426
427                timeOfLastMerge = currentTime;
428
429                group->removeChildren(0,group->getNumChildren());
430
431                group->addChild(models[modelIndex++].get());
432
433                compileCompletedCallback = 0;
434
435                viewer.home();
436            }
437        }
438    }
439
440    return 0;
441}
Note: See TracBrowser for help on using the browser.