diff --git a/src/Main/fg_init.cxx b/src/Main/fg_init.cxx index 86fa6f097..96e138092 100644 --- a/src/Main/fg_init.cxx +++ b/src/Main/fg_init.cxx @@ -798,6 +798,8 @@ void fgReInitSubsystems() globals->restoreInitialState(); // update our position based on current presets + // this will mark position as needed finalized which we'll do in the + // main-loop flightgear::initPosition(); // Force reupdating the positions of the ai 3d models. They are used for diff --git a/src/Main/main.cxx b/src/Main/main.cxx index 2073b9e15..abb786253 100644 --- a/src/Main/main.cxx +++ b/src/Main/main.cxx @@ -217,15 +217,9 @@ static void fgIdleFunction ( void ) { } } else if ( idle_state == 10 ) { - idle_state = 800; + idle_state = 900; fgPostInitSubsystems(); - } else if ( idle_state == 800 ) { - if (flightgear::finalizePosition()) { - idle_state = 900; - fgSplashProgress("init-graphics"); - } else { - fgSplashProgress("finalize-position"); - } + fgSplashProgress("finalize-position"); } else if ( idle_state == 900 ) { idle_state = 1000; diff --git a/src/Main/positioninit.cxx b/src/Main/positioninit.cxx index c904a48fa..c7c63b533 100644 --- a/src/Main/positioninit.cxx +++ b/src/Main/positioninit.cxx @@ -25,6 +25,7 @@ // simgear #include #include +#include #include "globals.hxx" #include "fg_props.hxx" @@ -44,6 +45,9 @@ namespace flightgear /// unresponsive, we need a timeout value. This value is reset on initPosition, /// and tracked through each call to finalizePosition. static SGTimeStamp global_finalizeTime; +static bool global_callbackRegistered = false; + +static void finalizePosition(); // Set current tower position lon/lat given an airport id static bool fgSetTowerPosFromAirportID( const string& id) { @@ -401,7 +405,11 @@ static bool fgSetPosFromFix( const string& id ) bool initPosition() { global_finalizeTime = SGTimeStamp(); // reset to invalid - + if (!global_callbackRegistered) { + globals->get_event_mgr()->addTask("finalizePosition", &finalizePosition, 0.1); + global_callbackRegistered = true; + } + double gs = fgGetDouble("/sim/presets/glideslope-deg") * SG_DEGREES_TO_RADIANS ; double od = fgGetDouble("/sim/presets/offset-distance-nm"); @@ -544,16 +552,57 @@ bool initPosition() fgSetBool("/sim/presets/onground", true); } + fgSetBool("/sim/position-finalized", false); + return true; } -bool finalizePosition() +bool finalizeMetar() +{ + double hdg = fgGetDouble( "/environment/metar/base-wind-dir-deg", 9999.0 ); + string apt = fgGetString( "/sim/startup/options/airport" ); + string rwy = fgGetString( "/sim/startup/options/runway" ); + double strthdg = fgGetDouble( "/sim/startup/options/heading-deg", 9999.0 ); + string parkpos = fgGetString( "/sim/presets/parkpos" ); + bool onground = fgGetBool( "/sim/presets/onground", false ); + // this logic is taken from former startup.nas + bool needMetar = (hdg < 360.0) && !apt.empty() && (strthdg > 360.0) && + rwy.empty() && onground && parkpos.empty(); + + if (needMetar) { + // timeout so we don't spin forever if the network is down + if (global_finalizeTime.elapsedMSec() > fgGetInt("/sim/startup/metar-fetch-timeout-msec", 10000)) { + SG_LOG(SG_GENERAL, SG_WARN, "finalizePosition: timed out waiting for METAR fetch"); + return true; + } + + if (!fgGetBool( "/environment/metar/valid" )) { + // bit hacky - run these two subsystems. We can't run the whole + // lot since some view things aren't initialised and hence FGLight + // crashes. + globals->get_subsystem("http")->update(0.0); + globals->get_subsystem("environment")->update(0.0); + return false; + } + + SG_LOG(SG_ENVIRONMENT, SG_INFO, + "Using METAR for runway selection: '" << fgGetString("/environment/metar/data") << "'" ); + setPosFromAirportIDandHdg( apt, hdg ); + // fall through to return true + } // of need-metar case + + return true; +} + +void finalizePosition() { // first call to finalize after an initPosition call if (global_finalizeTime.get_usec() == 0) { global_finalizeTime = SGTimeStamp::now(); } + bool done = true; + /* Scenarios require Nasal, so FGAIManager loads the scenarios, * including its models such as a/c carriers, in its 'postinit', * which is the very last thing we do. @@ -569,42 +618,16 @@ bool finalizePosition() // clear preset location and re-trigger position setup fgSetDouble("/sim/presets/longitude-deg", 9999); fgSetDouble("/sim/presets/latitude-deg", 9999); - return initPosition(); + initPosition(); + } else { + done = finalizeMetar(); + } + + fgSetBool("/sim/position-finalized", done); + if (done) { + globals->get_event_mgr()->removeTask("finalizePosition"); + global_callbackRegistered = false; } - - double hdg = fgGetDouble( "/environment/metar/base-wind-dir-deg", 9999.0 ); - string apt = fgGetString( "/sim/startup/options/airport" ); - string rwy = fgGetString( "/sim/startup/options/runway" ); - double strthdg = fgGetDouble( "/sim/startup/options/heading-deg", 9999.0 ); - string parkpos = fgGetString( "/sim/presets/parkpos" ); - bool onground = fgGetBool( "/sim/presets/onground", false ); -// this logic is taken from former startup.nas - bool needMetar = (hdg < 360.0) && !apt.empty() && (strthdg > 360.0) && - rwy.empty() && onground && parkpos.empty(); - - if (needMetar) { - // timeout so we don't spin forever if the network is down - if (global_finalizeTime.elapsedMSec() > fgGetInt("/sim/startup/metar-fetch-timeout-msec", 5000)) { - SG_LOG(SG_GENERAL, SG_WARN, "finalizePosition: timed out waiting for METAR fetch"); - return true; - } - - if (!fgGetBool( "/environment/metar/valid" )) { - // bit hacky - run these two subsystems. We can't run the whole - // lot since some view things aren't initialised and hence FGLight - // crashes. - globals->get_subsystem("http")->update(0.0); - globals->get_subsystem("environment")->update(0.0); - return false; - } - - SG_LOG(SG_ENVIRONMENT, SG_INFO, - "Using METAR for runway selection: '" << fgGetString("/environment/metar/data") << "'" ); - setPosFromAirportIDandHdg( apt, hdg ); - // fall through to return true - } // of need-metar case - - return true; } } // of namespace flightgear diff --git a/src/Main/positioninit.hxx b/src/Main/positioninit.hxx index 69a7e6809..ac12adecd 100644 --- a/src/Main/positioninit.hxx +++ b/src/Main/positioninit.hxx @@ -27,15 +27,6 @@ namespace flightgear // Set the initial position based on presets (or defaults) bool initPosition(); - -/** - * finalize the position once subsystems, Nasal and scenarios are loaded; - * all of which can potentially affect the position. - * returns true if the position is finally set, or false if more time - * is required to finalize the position (eg, awaiting METAR to set the - * active runway) - */ -bool finalizePosition(); // Listen to /sim/tower/airport-id and set tower view position accordingly void initTowerLocationListener(); diff --git a/src/Scenery/tilemgr.cxx b/src/Scenery/tilemgr.cxx index 7dfeddf92..22efc3da3 100644 --- a/src/Scenery/tilemgr.cxx +++ b/src/Scenery/tilemgr.cxx @@ -322,14 +322,19 @@ void FGTileMgr::update(double) if (!_scenery_loaded->getBoolValue()) { bool fdmInited = fgGetBool("sim/fdm-initialized"); - if (_scenery_override->getBoolValue() || (isSceneryLoaded() && fdmInited)) + 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))) { _scenery_loaded->setBoolValue(true); fgSplashProgress(""); } else { - fgSplashProgress("loading-scenery"); + fgSplashProgress(positionFinalized ? "loading-scenery" : "finalize-position"); // be nice to loader threads while waiting for initial scenery, reduce to 20fps SGTimeStamp::sleepForMSec(50); } diff --git a/src/Viewer/renderer.cxx b/src/Viewer/renderer.cxx index 3f82a2052..2e8d8fe87 100644 --- a/src/Viewer/renderer.cxx +++ b/src/Viewer/renderer.cxx @@ -517,6 +517,8 @@ FGRenderer::init( void ) if (!_classicalRenderer) _pipeline = makeRenderingPipeline(_renderer, 0); _scenery_loaded = fgGetNode("/sim/sceneryloaded", true); + _position_finalized = fgGetNode("/sim/position-finalized", true); + _panel_hotspots = fgGetNode("/sim/panel-hotspots", true); _virtual_cockpit = fgGetNode("/sim/virtual-cockpit", true); @@ -1543,7 +1545,7 @@ FGRenderer::setupView( void ) // Update all Visuals (redraws anything graphics related) void FGRenderer::update( ) { - if (!_scenery_loaded->getBoolValue()) + if (!_position_finalized || !_scenery_loaded->getBoolValue()) { _splash_alpha->setDoubleValue(1.0); return; diff --git a/src/Viewer/renderer.hxx b/src/Viewer/renderer.hxx index a98a4b62f..a064dcd30 100644 --- a/src/Viewer/renderer.hxx +++ b/src/Viewer/renderer.hxx @@ -121,7 +121,8 @@ public: protected: osg::ref_ptr viewer; osg::ref_ptr eventHandler; - SGPropertyNode_ptr _scenery_loaded; + SGPropertyNode_ptr _scenery_loaded, _position_finalized; + SGPropertyNode_ptr _skyblend, _splash_alpha; SGPropertyNode_ptr _point_sprites, _enhanced_lighting, _distance_attenuation; SGPropertyNode_ptr _textures;