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

Revision 11848, 12.0 kB (checked in by robert, 4 years ago)

Cleaned up main loop, so it's more readable, seperating out the paging and non paging implementations

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