diff --git a/examples/osganalysis/osganalysis.cpp b/examples/osganalysis/osganalysis.cpp index 785e590b7..031e8ce7d 100644 --- a/examples/osganalysis/osganalysis.cpp +++ b/examples/osganalysis/osganalysis.cpp @@ -23,9 +23,71 @@ #include #include - -struct CustomCompileCompletedCallback : public osgUtil::IncrementalCompileOperation::CompileCompletedCallback +class SceneGraphProcessor : public osg::Referenced { +public: + SceneGraphProcessor() + { + _init(); + } + + SceneGraphProcessor(osg::ArgumentParser& arguments) + { + _init(); + + while (arguments.read("--vbo")) { modifyDrawableSettings = true; useVBO = true; } + while (arguments.read("--dl")) { modifyDrawableSettings = true; useDisplayLists = true; } + while (arguments.read("--simplify", simplificatioRatio)) {} + + while (arguments.read("--build-mipmaps")) { modifyTextureSettings = true; buildImageMipmaps = true; } + while (arguments.read("--compress")) { modifyTextureSettings = true; compressImages = true; } + while (arguments.read("--disable-mipmaps")) { modifyTextureSettings = true; disableMipmaps = true; } + } + + virtual osg::Node* process(osg::Node* node) + { + if (!node) + { + OSG_NOTICE<<"SceneGraphProcessor::process(Node*) : error cannot process NULL Node."<getName()<process(_loadedModel.get()); + } + } + + if (_loadedModel.valid()) + { + if (_incrementalCompileOperation.valid()) + { + osg::ref_ptr compileSet = + new osgUtil::IncrementalCompileOperation::CompileSet(_loadedModel.get()); + + compileSet->_compileCompletedCallback = this; + + _incrementalCompileOperation->add(compileSet.get()); + } + else + { + _modelReadyToMerge = true; + } + } + + osg::notify(osg::NOTICE)<<"done LoadAndCompileOperation "<<_filename< _loadedModel; + bool _modelReadyToMerge; + osg::ref_ptr _sceneGraphProcessor; + osg::ref_ptr _incrementalCompileOperation; +}; + + int main(int argc, char** argv) { osg::ArgumentParser arguments(&argc, argv); @@ -50,39 +175,107 @@ int main(int argc, char** argv) viewer.addEventHandler(new osgViewer::StatsHandler()); viewer.addEventHandler(new osgViewer::WindowSizeHandler); + ///////////////////////////////////////////////////////////////////////////////// + // + // IncrementalCompileOperation settings + // osg::ref_ptr incrementalCompile = new osgUtil::IncrementalCompileOperation; viewer.setIncrementalCompileOperation(incrementalCompile.get()); + if (arguments.read("--force") || arguments.read("-f")) + { + incrementalCompile->assignForceTextureDownloadGeometry(); + } + + if (arguments.read("-a")) + { + incrementalCompile->setMinimumTimeAvailableForGLCompileAndDeletePerFrame(1); + incrementalCompile->setConservativeTimeRatio(1); + incrementalCompile->setMaximumNumOfObjectsToCompilePerFrame(100); + } + else if (arguments.read("-c")) + { + incrementalCompile->setMinimumTimeAvailableForGLCompileAndDeletePerFrame(0.0001); + incrementalCompile->setConservativeTimeRatio(0.01); + incrementalCompile->setMaximumNumOfObjectsToCompilePerFrame(1); + } + + ///////////////////////////////////////////////////////////////////////////////// + // + // SceneGraph processing setup + // + osg::ref_ptr sceneGraphProcessor = new SceneGraphProcessor(arguments); + + ///////////////////////////////////////////////////////////////////////////////// + // + // Database settings + // double timeBetweenMerges = 2.0; while(arguments.read("--interval",timeBetweenMerges)) {} - typedef std::vector< osg::ref_ptr > Models; - Models models; + bool readDatabasesInPagingThread = false; + while(arguments.read("--paging")) { readDatabasesInPagingThread = true; } + typedef std::vector< std::string > FileNames; + FileNames fileNames; for(int pos=1;posgetName().empty()) node->setName( arguments[pos] ); - models.push_back(node); - } + fileNames.push_back(arguments[pos]); } } - OSG_NOTICE<<"models.size()="< > Models; + unsigned int modelIndex = 0; + Models models; osg::ref_ptr group = new osg::Group; - - unsigned int modelIndex = 0; - - group->addChild(models[modelIndex++].get()); - viewer.setSceneData(group); + osg::ref_ptr databasePagingThread; + osg::ref_ptr databasePagingOperation; + if (readDatabasesInPagingThread) + { + databasePagingThread = new osg::OperationThread; + databasePagingThread->startThread(); + + databasePagingOperation = new DatabasePagingOperation( + fileNames[modelIndex++], + sceneGraphProcessor.get(), + incrementalCompile.get()); + + databasePagingThread->add(databasePagingOperation.get()); + + } + else + { + for(FileNames::iterator itr = fileNames.begin(); + itr != fileNames.end(); + ++itr) + { + // not an option so assume string is a filename. + osg::ref_ptr node = osgDB::readNodeFile( *itr ); + if(node.valid()) + { + if (node->getName().empty()) node->setName( *itr ); + + node = sceneGraphProcessor->process(node.get()); + + models.push_back(node.get()); + } + } + + group->addChild(models[modelIndex++].get()); + + } + viewer.realize(); double timeOfLastMerge = viewer.getFrameStamp()->getReferenceTime(); @@ -95,37 +288,69 @@ int main(int argc, char** argv) double currentTime = viewer.getFrameStamp()->getReferenceTime(); - if (!compileCompletedCallback && - modelIndextimeBetweenMerges) + if (readDatabasesInPagingThread) { - OSG_NOTICE<<"Compiling model "<timeBetweenMerges) + { + databasePagingOperation = new DatabasePagingOperation( + fileNames[modelIndex++], + sceneGraphProcessor.get(), + incrementalCompile.get()); - osg::ref_ptr compileSet = - new osgUtil::IncrementalCompileOperation::CompileSet(models[modelIndex].get()); + databasePagingThread->add(databasePagingOperation.get()); + } - compileCompletedCallback = new CustomCompileCompletedCallback; + if (databasePagingOperation.get() && databasePagingOperation->_modelReadyToMerge) + { + timeOfLastMerge = currentTime; - compileSet->_compileCompletedCallback = compileCompletedCallback; + group->removeChildren(0,group->getNumChildren()); - incrementalCompile->add(compileSet.get()); + group->addChild(databasePagingOperation->_loadedModel.get()); + + viewer.home(); + + // we no longer need the paging operation as it's done it's job. + databasePagingOperation = 0; + + viewer.home(); + } } - - if (compileCompletedCallback.valid() && compileCompletedCallback->completed) + else { - OSG_NOTICE<<"Merging model "<timeBetweenMerges) + { + OSG_NOTICE<<"Compiling model "< compileSet = + new osgUtil::IncrementalCompileOperation::CompileSet(models[modelIndex].get()); - compileCompletedCallback = 0; + compileCompletedCallback = new CustomCompileCompletedCallback; - group->removeChildren(0,group->getNumChildren()); + compileSet->_compileCompletedCallback = compileCompletedCallback; - group->addChild(models[modelIndex++].get()); + incrementalCompile->add(compileSet.get()); + } - viewer.home(); + if (compileCompletedCallback.valid() && compileCompletedCallback->completed) + { + OSG_NOTICE<<"Merging model "<removeChildren(0,group->getNumChildren()); + + group->addChild(models[modelIndex++].get()); + + compileCompletedCallback = 0; + + viewer.home(); + } } - } return 0; diff --git a/include/osgUtil/IncrementalCompileOperation b/include/osgUtil/IncrementalCompileOperation index 13333169a..2a459b740 100644 --- a/include/osgUtil/IncrementalCompileOperation +++ b/include/osgUtil/IncrementalCompileOperation @@ -232,7 +232,7 @@ class OSGUTIL_EXPORT IncrementalCompileOperation : public osg::GraphicsOperation typedef std::set ContextSet; typedef std::map CompileMap; - struct CompileCompletedCallback : public osg::Referenced + struct CompileCompletedCallback : public virtual osg::Referenced { /// return true if the callback assumes responsibility for merging any associated subgraphs with the main scene graph /// return false if callback doesn't handle the merge, and instead requires the IncrementalCompileOperation to handle this for us diff --git a/src/osgUtil/IncrementalCompileOperation.cpp b/src/osgUtil/IncrementalCompileOperation.cpp index edd95d199..d70f991f2 100644 --- a/src/osgUtil/IncrementalCompileOperation.cpp +++ b/src/osgUtil/IncrementalCompileOperation.cpp @@ -220,7 +220,7 @@ void CompileOperator::runTimingTests(osg::RenderInfo& renderInfo) bool useVBO = false; for(unsigned int i=0; i geometry = createTestGeometry(numVertices, useVBO); double size = geometry->getGLObjectSizeHint(); double time = timeCompile(renderInfo, geometry); @@ -233,7 +233,7 @@ void CompileOperator::runTimingTests(osg::RenderInfo& renderInfo) bool useVBO = true; for(unsigned int i=0; i geometry = createTestGeometry(numVertices, useVBO); double size = geometry->getGLObjectSizeHint(); double time = timeCompile(renderInfo, geometry);