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

Revision 11853, 11.6 kB (checked in by robert, 3 years ago)

Added number of primitive sets to on screen stats

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
29#include <osgUtil/IncrementalCompileOperation>
30#include <osgUtil/Simplifier>
31
32class StripStateVisitor : public osg::NodeVisitor
33{
34public:
35    StripStateVisitor(bool useStateSets, bool useDisplayLists, bool useVBO):
36        osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN),
37        _useStateSets(useStateSets),
38        _useDisplayLists(useDisplayLists),
39        _useVBO(useVBO) {}
40
41    bool _useStateSets;
42    bool _useDisplayLists;
43    bool _useVBO;
44
45    void apply(osg::Node& node)
46    {
47        if (!_useStateSets && node.getStateSet()) node.setStateSet(0);
48        traverse(node);
49    }
50
51    void apply(osg::Geode& node)
52    {
53        if (!_useStateSets && node.getStateSet()) node.setStateSet(0);
54        for(unsigned int i = 0; i<node.getNumDrawables(); ++i)
55        {
56            process(*node.getDrawable(i));
57        }
58
59        traverse(node);
60    }
61
62    void process(osg::Drawable& drawable)
63    {
64        if (!_useStateSets && drawable.getStateSet())
65        {
66            drawable.setStateSet(0);
67        }
68
69        drawable.setUseDisplayList(_useDisplayLists);
70        drawable.setUseVertexBufferObjects(_useVBO);
71    }
72};
73
74class SceneGraphProcessor : public osg::Referenced
75{
76public:
77    SceneGraphProcessor()
78    {
79        _init();
80    }
81
82    SceneGraphProcessor(osg::ArgumentParser& arguments)
83    {
84        _init();
85
86        while (arguments.read("--vbo")) { modifyDrawableSettings = true; useVBO = true;  }
87        while (arguments.read("--dl")) { modifyDrawableSettings = true; useDisplayLists = true;  }
88
89        while (arguments.read("-s", simplificatioRatio)) {}
90
91        while (arguments.read("--build-mipmaps")) { modifyTextureSettings = true; buildImageMipmaps = true; }
92        while (arguments.read("--compress")) { modifyTextureSettings = true; compressImages = true; }
93        while (arguments.read("--disable-mipmaps")) { modifyTextureSettings = true; disableMipmaps = true; }
94
95        OSG_NOTICE<<"simplificatioRatio="<<simplificatioRatio<<std::endl;
96    }
97
98    virtual osg::Node* process(osg::Node* node)
99    {
100        if (!node)
101        {
102            OSG_NOTICE<<"SceneGraphProcessor::process(Node*) : error cannot process NULL Node."<<std::endl;
103            return 0;
104        }
105
106        OSG_NOTICE<<"SceneGraphProcessor::process("<<node<<") : "<<node->getName()<<std::endl;
107
108        if (simplificatioRatio < 1.0)
109        {
110            OSG_NOTICE<<"Running simplifier with simplification ratio="<<simplificatioRatio<<std::endl;
111            float maxError = 4.0f;
112            osgUtil::Simplifier simplifier(simplificatioRatio, maxError);
113            //simplifier.setDoTriStrip(false);
114            //simplifier.setSmoothing(false);
115            node->accept(simplifier);
116        }
117
118        if (modifyDrawableSettings || modifyTextureSettings)
119        {
120            OSG_NOTICE<<"Running StripStateVisitor"<<std::endl;
121            StripStateVisitor ssv(true, useDisplayLists, useVBO);
122            node->accept(ssv);
123        }
124
125
126        return node;
127    }
128
129protected:
130
131    void _init()
132    {
133        modifyDrawableSettings = false;
134        useVBO = false;
135        useDisplayLists = false;
136        simplificatioRatio = 1.0;
137
138        modifyTextureSettings = false;
139        buildImageMipmaps = false;
140        compressImages = false;
141        disableMipmaps = false;
142    }
143
144    bool modifyDrawableSettings;
145    bool useVBO;
146    bool useDisplayLists;
147    float simplificatioRatio;
148
149    bool modifyTextureSettings;
150    bool buildImageMipmaps;
151    bool compressImages;
152    bool disableMipmaps;
153
154};
155
156class DatabasePagingOperation : public osg::Operation, public osgUtil::IncrementalCompileOperation::CompileCompletedCallback
157{
158public:
159
160    DatabasePagingOperation(const std::string& filename,
161                            const std::string& outputFilename,
162                             SceneGraphProcessor* sceneGraphProcessor,
163                             osgUtil::IncrementalCompileOperation* ico):
164        Operation("DatabasePaging Operation", false),
165        _filename(filename),
166        _outputFilename(outputFilename),
167        _modelReadyToMerge(false),
168        _sceneGraphProcessor(sceneGraphProcessor),
169        _incrementalCompileOperation(ico) {}
170
171    virtual void operator () (osg::Object* object)
172    {
173        osg::notify(osg::NOTICE)<<"LoadAndCompileOperation "<<_filename<<std::endl;
174
175        _modelReadyToMerge = false;
176        _loadedModel = osgDB::readNodeFile(_filename);
177
178        if (_loadedModel.valid())
179        {
180            if (_sceneGraphProcessor.valid())
181            {
182                _loadedModel = _sceneGraphProcessor->process(_loadedModel.get());
183            }
184        }
185
186        if (_loadedModel.valid())
187        {
188            if (!_outputFilename.empty())
189            {
190                osgDB::writeNodeFile(*_loadedModel, _outputFilename);
191            }
192
193            if (_incrementalCompileOperation.valid())
194            {
195                osg::ref_ptr<osgUtil::IncrementalCompileOperation::CompileSet> compileSet =
196                    new osgUtil::IncrementalCompileOperation::CompileSet(_loadedModel.get());
197
198                compileSet->_compileCompletedCallback = this;
199
200                _incrementalCompileOperation->add(compileSet.get());
201            }
202            else
203            {
204                _modelReadyToMerge = true;
205            }
206        }
207
208        osg::notify(osg::NOTICE)<<"done LoadAndCompileOperation "<<_filename<<std::endl;
209    }
210
211    virtual bool compileCompleted(osgUtil::IncrementalCompileOperation::CompileSet* compileSet)
212    {
213        OSG_NOTICE<<"compileCompleted"<<std::endl;
214        _modelReadyToMerge = true;
215        return true;
216    }
217
218    std::string                                         _filename;
219    std::string                                         _outputFilename;
220    osg::ref_ptr<osg::Node>                             _loadedModel;
221    bool                                                _modelReadyToMerge;
222    osg::ref_ptr<SceneGraphProcessor>                   _sceneGraphProcessor;
223    osg::ref_ptr<osgUtil::IncrementalCompileOperation>  _incrementalCompileOperation;
224};
225
226
227int main(int argc, char** argv)
228{
229    osg::ArgumentParser arguments(&argc, argv);
230
231    // construct the viewer.
232    osgViewer::Viewer viewer(arguments);
233
234    viewer.setCameraManipulator( new osgGA::TrackballManipulator() );
235    viewer.addEventHandler( new osgViewer::StatsHandler());
236    viewer.addEventHandler( new osgViewer::WindowSizeHandler() );
237    viewer.addEventHandler( new osgGA::StateSetManipulator(viewer.getCamera()->getOrCreateStateSet()) );
238
239    /////////////////////////////////////////////////////////////////////////////////
240    //
241    // IncrementalCompileOperation settings
242    //
243    osg::ref_ptr<osgUtil::IncrementalCompileOperation> incrementalCompile = new osgUtil::IncrementalCompileOperation;
244    viewer.setIncrementalCompileOperation(incrementalCompile.get());
245
246    if (arguments.read("--force") || arguments.read("-f"))
247    {
248        incrementalCompile->assignForceTextureDownloadGeometry();
249    }
250
251    if (arguments.read("-a"))
252    {
253        incrementalCompile->setMinimumTimeAvailableForGLCompileAndDeletePerFrame(1);
254        incrementalCompile->setConservativeTimeRatio(1);
255        incrementalCompile->setMaximumNumOfObjectsToCompilePerFrame(100);
256    }
257    else if (arguments.read("-c"))
258    {
259        incrementalCompile->setMinimumTimeAvailableForGLCompileAndDeletePerFrame(0.0001);
260        incrementalCompile->setConservativeTimeRatio(0.01);
261        incrementalCompile->setMaximumNumOfObjectsToCompilePerFrame(1);
262    }
263
264    /////////////////////////////////////////////////////////////////////////////////
265    //
266    // SceneGraph processing setup
267    //
268    osg::ref_ptr<SceneGraphProcessor> sceneGraphProcessor = new SceneGraphProcessor(arguments);
269
270    /////////////////////////////////////////////////////////////////////////////////
271    //
272    // Database settings
273    //
274    double timeBetweenMerges = 2.0;
275    while(arguments.read("--interval",timeBetweenMerges)) {}
276
277    std::string outputPostfix;
278    while (arguments.read("-o",outputPostfix)) {}
279
280
281    typedef std::vector< std::string > FileNames;
282    FileNames fileNames;
283    for(int pos=1;pos<arguments.argc();++pos)
284    {
285        if (!arguments.isOption(pos))
286        {
287            fileNames.push_back(arguments[pos]);
288        }
289    }
290
291    if (fileNames.empty())
292    {
293        OSG_NOTICE<<"No files loaded, please specifies files on commandline."<<std::endl;
294        return 1;
295    }
296
297    // load the models using a paging thread and use the incremental compile operation to
298    // manage the compilation of GL objects without breaking frame.
299
300    unsigned int modelIndex = 0;
301
302    osg::ref_ptr<osg::OperationThread> databasePagingThread;
303    osg::ref_ptr<DatabasePagingOperation> databasePagingOperation;
304
305    databasePagingThread = new osg::OperationThread;
306    databasePagingThread->startThread();
307
308    std::string filename = fileNames[modelIndex++];
309    std::string outputFilename = outputPostfix.empty() ? std::string() : filename+outputPostfix;
310
311    databasePagingOperation = new DatabasePagingOperation(
312        filename,
313        outputFilename,
314        sceneGraphProcessor.get(),
315        incrementalCompile.get());
316
317    databasePagingThread->add(databasePagingOperation.get());
318
319    osg::ref_ptr<osg::Group> group = new osg::Group;
320    viewer.setSceneData(group);
321
322    viewer.realize();
323
324    double timeOfLastMerge = viewer.getFrameStamp()->getReferenceTime();
325
326    while(!viewer.done())
327    {
328        viewer.frame();
329
330        double currentTime = viewer.getFrameStamp()->getReferenceTime();
331
332        if (!databasePagingOperation &&
333            modelIndex<fileNames.size() &&
334            (currentTime-timeOfLastMerge)>timeBetweenMerges)
335        {
336            std::string filename = fileNames[modelIndex++];
337            std::string outputFilename = outputPostfix.empty() ? std::string() : filename+outputPostfix;
338
339            databasePagingOperation = new DatabasePagingOperation(
340                filename,
341                outputFilename,
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    return 0;
366}
Note: See TracBrowser for help on using the browser.