From 39cedd1256a6d09fc684efff5658daf4c7985f87 Mon Sep 17 00:00:00 2001 From: Stuart Buchanan Date: Wed, 1 Jul 2020 21:02:16 +0100 Subject: [PATCH] Fix fgviewer for Compositor --- src/Scenery/tilemgr.cxx | 74 +++++++++++++++++++++-------------------- src/Viewer/fgviewer.cxx | 66 ++++++++++++++++++++++++++---------- 2 files changed, 86 insertions(+), 54 deletions(-) diff --git a/src/Scenery/tilemgr.cxx b/src/Scenery/tilemgr.cxx index b42ddf4c3..f08d97c88 100644 --- a/src/Scenery/tilemgr.cxx +++ b/src/Scenery/tilemgr.cxx @@ -68,12 +68,12 @@ public: _lodBare(fgGetNode("/sim/rendering/static-lod/bare", true)) { _useVBOsProp->addChangeListener(this, true); - + _enableCacheProp->addChangeListener(this, true); if (_enableCacheProp->getType() == simgear::props::NONE) { _enableCacheProp->setBoolValue(true); } - + if (_pagedLODMaximumProp->getType() == simgear::props::NONE) { // not set, use OSG default / environment value variable osg::ref_ptr viewer(globals->get_renderer()->getViewer()); @@ -85,7 +85,7 @@ public: _lodBareDelta->addChangeListener(this, true); _lodRoughDelta->addChangeListener(this, true); } - + ~TileManagerListener() { _useVBOsProp->removeChangeListener(this); @@ -95,7 +95,7 @@ public: _lodBareDelta->removeChangeListener(this); _lodRoughDelta->removeChangeListener(this); } - + virtual void valueChanged(SGPropertyNode* prop) { if (prop == _useVBOsProp) { @@ -107,7 +107,10 @@ public: } else if (prop == _pagedLODMaximumProp) { int v = prop->getIntValue(); osg::ref_ptr viewer(globals->get_renderer()->getViewer()); - viewer->getDatabasePager()->setTargetMaximumNumberOfPageLOD(v); + if (viewer) { + osgDB::DatabasePager* pager = viewer->getDatabasePager(); + if (pager) pager->setTargetMaximumNumberOfPageLOD(v); + } } else if (prop == _lodDetailed || prop == _lodBareDelta || prop == _lodRoughDelta) { // compatibility with earlier versions; set the static lod ranges appropriately as otherwise (bad) self managed // LOD on scenery with range animations doesn't work. @@ -117,7 +120,7 @@ public: _lodBare->setDoubleValue(_lodRough->getDoubleValue() + _lodBareDelta->getDoubleValue()); } } - + private: FGTileMgr* _manager; SGPropertyNode_ptr _useVBOsProp, @@ -183,10 +186,10 @@ void FGTileMgr::reinit() // drops the previous options reference _options = new simgear::SGReaderWriterOptions; _listener = new TileManagerListener(this); - + materialLibChanged(); _options->setPropertyNode(globals->get_props()); - + osgDB::FilePathList &fp = _options->getDatabasePathList(); const PathList &sc = globals->get_fg_scenery(); fp.clear(); @@ -194,18 +197,18 @@ void FGTileMgr::reinit() fp.push_back(it->utf8Str()); } _options->setPluginStringData("SimGear::FG_ROOT", globals->get_fg_root().utf8Str()); - + if (_terra_sync) { _options->setPluginStringData("SimGear::TERRASYNC_ROOT", globals->get_terrasync_dir().utf8Str()); } - + if (!_disableNasalHooks->getBoolValue()) _options->setModelData(new FGNasalModelDataProxy); double detailed = fgGetDouble("/sim/rendering/static-lod/detailed", SG_OBJECT_RANGE_DETAILED); double rough = fgGetDouble("/sim/rendering/static-lod/rough-delta", SG_OBJECT_RANGE_ROUGH) + detailed; double bare = fgGetDouble("/sim/rendering/static-lod/bare", SG_OBJECT_RANGE_BARE) + rough; - + _options->setPluginStringData("SimGear::LOD_RANGE_BARE", std::to_string(bare)); _options->setPluginStringData("SimGear::LOD_RANGE_ROUGH", std::to_string(rough)); _options->setPluginStringData("SimGear::LOD_RANGE_DETAILED", std::to_string(detailed)); @@ -223,7 +226,7 @@ void FGTileMgr::reinit() } _options->setSceneryPathSuffixes(scenerySuffixes); - + if (state != Start) { // protect against multiple scenery reloads and properly reset flags, @@ -233,25 +236,25 @@ void FGTileMgr::reinit() return; } } - + _scenery_loaded->setBoolValue(false); fgSetDouble("/sim/startup/splash-alpha", 1.0); - + materialLibChanged(); // remove all old scenery nodes from scenegraph and clear cache osg::Group* group = globals->get_scenery()->get_terrain_branch(); group->removeChildren(0, group->getNumChildren()); tile_cache.init(); - + // clear OSG cache, except on initial start-up if (state != Start) { osgDB::Registry::instance()->clearObjectCache(); } - + state = Inited; - + previous_bucket.make_bad(); current_bucket.make_bad(); scheduled_visibility = 100.0; @@ -319,7 +322,7 @@ void FGTileMgr::schedule_needed(const SGBucket& curr_bucket, double vis) "scheduling needed tiles for " << curr_bucket << ", tile-width-m:" << tile_width << ", tile-height-m:" << tile_height); - + // cout << "tile width = " << tile_width << " tile_height = " // << tile_height << endl; // starting with 2018.3 we will use deltas rather than absolutes as it is more intuitive for the user @@ -339,7 +342,7 @@ void FGTileMgr::schedule_needed(const SGBucket& curr_bucket, double vis) // cout << "max cache size = " << tile_cache.get_max_cache_size() // << " current cache size = " << tile_cache.get_size() << endl; - // clear flags of all tiles belonging to the previous view set + // clear flags of all tiles belonging to the previous view set tile_cache.clear_current_view(); // update timestamps, so all tiles scheduled now are *newer* than any tile previously loaded @@ -361,10 +364,10 @@ void FGTileMgr::schedule_needed(const SGBucket& curr_bucket, double vis) if (!b.isValid()) { continue; } - + float priority = (-1.0) * (x*x+y*y); sched_tile( b, priority, true, 0.0 ); - + if (_terra_sync) { _terra_sync->scheduleTile(b); } @@ -385,7 +388,7 @@ void FGTileMgr::update_queues(bool& isDownloadingScenery) TileEntry *e; int loading=0; int sz=0; - + tile_cache.set_current_time( current_time ); tile_cache.reset_traversal(); @@ -398,7 +401,7 @@ void FGTileMgr::update_queues(bool& isDownloadingScenery) // Set the ssg transform and update it's range selector // based on current visibilty e->prep_ssg_node(vis); - + if (!e->is_loaded()) { bool nonExpiredOrCurrent = !e->is_expired(current_time) || e->is_current_view(); bool downloading = isTileDirSyncing(e->tileFileName); @@ -429,7 +432,7 @@ void FGTileMgr::update_queues(bool& isDownloadingScenery) dropTiles = true; drop_count = sz; // no limit on tiles to drop } - + if (dropTiles) { long drop_index = _enableCache ? tile_cache.get_drop_tile() : @@ -441,14 +444,14 @@ void FGTileMgr::update_queues(bool& isDownloadingScenery) SG_LOG(SG_TERRAIN, SG_DEBUG, "Dropping:" << old->get_tile_bucket()); tile_cache.clear_entry(drop_index); - + osg::ref_ptr subgraph = old->getNode(); old->removeFromSceneGraph(); delete old; // zeros out subgraph ref_ptr, so subgraph is owned by // the pager and will be deleted in the pager thread. _pager->queueDeleteRequest(subgraph); - + if (!_enableCache) drop_index = tile_cache.get_first_expired_tile(); // limit tiles dropped to drop_count @@ -477,8 +480,8 @@ void FGTileMgr::update(double) bool fdmInited = fgGetBool("sim/fdm-initialized"); bool positionFinalized = fgGetBool("sim/position-finalized"); bool sceneryOverride = _scenery_override->getBoolValue(); - - + + // we are done if final position is set and the scenery & FDM are done. // scenery-override can ignore the last two, but not position finalization. if (positionFinalized && (sceneryOverride || (isSceneryLoaded() && fdmInited))) @@ -495,7 +498,7 @@ void FGTileMgr::update(double) } else { fgSplashProgress("loading-scenery"); } - + // be nice to loader threads while waiting for initial scenery, reduce to 20fps SGTimeStamp::sleepForMSec(50); } @@ -535,7 +538,7 @@ void FGTileMgr::schedule_tiles_at(const SGGeod& location, double range_m) scheduled_visibility = range_m; schedule_needed(current_bucket, range_m); } - + // save bucket previous_bucket = current_bucket; } else if ( state == Start || state == Inited ) { @@ -562,7 +565,7 @@ bool FGTileMgr::schedule_scenery(const SGGeod& position, double range_m, double SGBucket bucket(position); available = sched_tile( bucket, priority, false, duration ); - + if ((!available)&&(duration==0.0)) { SG_LOG( SG_TERRAIN, SG_DEBUG, "schedule_scenery: Scheduling tile at bucket:" << bucket << " return false" ); return false; @@ -576,7 +579,7 @@ bool FGTileMgr::schedule_scenery(const SGGeod& position, double range_m, double double tile_r = 0.5*sqrt(tile_width*tile_width + tile_height*tile_height); double max_dist = tile_r + range_m; double max_dist2 = max_dist*max_dist; - + int xrange = (int)fabs(range_m / tile_width) + 1; int yrange = (int)fabs(range_m / tile_height) + 1; @@ -591,7 +594,7 @@ bool FGTileMgr::schedule_scenery(const SGGeod& position, double range_m, double if (!b.isValid()) { continue; } - + double distance2 = distSqr(cartPos, SGVec3d::fromGeod(b.get_center())); // Do not ask if it is just the next tile but way out of range. if (distance2 <= max_dist2) @@ -622,11 +625,10 @@ bool FGTileMgr::isTileDirSyncing(const std::string& tileFileName) const if (!_terra_sync) { return false; } - + std::string nameWithoutExtension = tileFileName.substr(0, tileFileName.size() - 4); long int bucketIndex = simgear::strutils::to_int(nameWithoutExtension); SGBucket bucket(bucketIndex); - + return _terra_sync->isTileDirPending(bucket.gen_base_path()); } - diff --git a/src/Viewer/fgviewer.cxx b/src/Viewer/fgviewer.cxx index 48fab6e67..7fd5a82f5 100644 --- a/src/Viewer/fgviewer.cxx +++ b/src/Viewer/fgviewer.cxx @@ -33,6 +33,9 @@ #include +#include +#include + #include
#include
#include
@@ -110,8 +113,10 @@ fgviewerMain(int argc, char** argv) osg::ArgumentParser arguments(&argc, argv); // construct the viewer. - osgViewer::Viewer viewer(arguments); - osg::Camera* camera = viewer.getCamera(); + FGRenderer* fgrenderer = new FGRenderer(); + osgViewer::Viewer* viewer = new osgViewer::Viewer(arguments); + fgrenderer->setViewer(viewer); + osg::Camera* camera = viewer->getCamera(); osgViewer::Renderer* renderer = static_cast(camera->getRenderer()); for (int i = 0; i < 2; ++i) { @@ -126,7 +131,7 @@ fgviewerMain(int argc, char** argv) fog->setDensity(.0000001); cameraSS->setAttributeAndModes(fog); // ... for some reason, get rid of that FIXME! - viewer.setThreadingModel(osgViewer::Viewer::SingleThreaded); + viewer->setThreadingModel(osgViewer::Viewer::SingleThreaded); // set up the camera manipulators. osgGA::KeySwitchMatrixManipulator* keyswitchManipulator; @@ -140,18 +145,18 @@ fgviewerMain(int argc, char** argv) new osgGA::DriveManipulator); keyswitchManipulator->addMatrixManipulator('4', "Terrain", new osgGA::TerrainManipulator); - viewer.setCameraManipulator(keyswitchManipulator); + viewer->setCameraManipulator(keyswitchManipulator); // Usefull stats - viewer.addEventHandler(new osgViewer::HelpHandler); - viewer.addEventHandler(new osgViewer::StatsHandler); - viewer.addEventHandler( new osgGA::StateSetManipulator(viewer.getCamera()->getOrCreateStateSet()) ); + viewer->addEventHandler(new osgViewer::HelpHandler); + viewer->addEventHandler(new osgViewer::StatsHandler); + viewer->addEventHandler( new osgGA::StateSetManipulator(viewer->getCamera()->getOrCreateStateSet()) ); // Same FIXME ... - // viewer.addEventHandler(new osgViewer::ThreadingHandler); - viewer.addEventHandler(new osgViewer::LODScaleHandler); - viewer.addEventHandler(new osgViewer::ScreenCaptureHandler); + // viewer->addEventHandler(new osgViewer::ThreadingHandler); + viewer->addEventHandler(new osgViewer::LODScaleHandler); + viewer->addEventHandler(new osgViewer::ScreenCaptureHandler); - viewer.addEventHandler(new GraphDumpHandler); + viewer->addEventHandler(new GraphDumpHandler); // Extract files to load from arguments now; this way fgInitConfig // won't choke on them. @@ -168,8 +173,19 @@ fgviewerMain(int argc, char** argv) // A subset of full flightgear initialization. // Allocate global data structures. This needs to happen before // we parse command line options - globals = new FGGlobals; + globals->set_renderer(fgrenderer); + + SGPath dataPath = fgHomePath(); + globals->set_fg_home(dataPath); + + std::string s; + if (arguments.read("--fg-scenery", s)) { + globals->append_fg_scenery(SGPath::fromLocal8Bit(s.c_str())); + } + if (std::getenv("FG_SCENERY")) { + globals->append_fg_scenery(SGPath::fromEnv("FG_SCENERY")); + } int configResult = fgInitConfig(arguments.argc(), arguments.argv(), false); if (configResult == flightgear::FG_OPTIONS_ERROR) { @@ -209,10 +225,24 @@ fgviewerMain(int argc, char** argv) options->setPropertyNode(globals->get_props()); options->setPluginStringData("SimGear::PREVIEW", "ON"); - FGScenery* scenery = globals->add_new_subsystem(); + // Now init the renderer, as we've got all the options, globals etc. + fgrenderer->init(); + + FGScenery* scenery = globals->add_new_subsystem(SGSubsystemMgr::DISPLAY); scenery->init(); scenery->bind(); + if (! flightgear::NavDataCache::instance()) { + flightgear::NavDataCache* cache = flightgear::NavDataCache::createInstance(); + cache->updateListsOfDatFiles(); + if (cache->isRebuildRequired()) { + while (cache->rebuild() != flightgear::NavDataCache::REBUILD_DONE) { + SGTimeStamp::sleepForMSec(1000); + std::cerr << "." << std::flush; + } + } + } + // read the scene from the list of file specified command line args. osg::ref_ptr loadedModel; loadedModel = osgDB::readNodeFiles(dataFiles, options); @@ -224,14 +254,14 @@ fgviewerMain(int argc, char** argv) return EXIT_FAILURE; } - // pass the loaded scene graph to the viewer. - viewer.setSceneData(loadedModel.get()); + // pass the loaded scene graph to the viewer-> + viewer->setSceneData(loadedModel.get()); + + int result = viewer->run(); - int result = viewer.run(); - // clear cache now, since it contains SimGear objects. Otherwise SG_LOG // calls during shutdown will cause crashes. osgDB::Registry::instance()->clearObjectCache(); - + return result; }