diff --git a/aclocal.m4 b/aclocal.m4 index 78a4037e5..7d5836b91 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -1,4 +1,4 @@ -dnl aclocal.m4 generated automatically by aclocal 1.4 +dnl aclocal.m4 generated automatically by aclocal 1.4-p4 dnl Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation diff --git a/src/Autopilot/newauto.cxx b/src/Autopilot/newauto.cxx index ff6584175..845e3be4f 100644 --- a/src/Autopilot/newauto.cxx +++ b/src/Autopilot/newauto.cxx @@ -913,7 +913,7 @@ static inline double fgAPget_agl( void ) { double agl; agl = cur_fdm_state->get_Altitude() * SG_FEET_TO_METER - - scenery.cur_elev; + - scenery.get_cur_elev(); return( agl ); } @@ -929,8 +929,8 @@ void FGAutopilot::AltitudeSet( double new_altitude ) { target_alt = new_altitude * SG_FEET_TO_METER; } - if( target_alt < scenery.cur_elev ) { - target_alt = scenery.cur_elev; + if( target_alt < scenery.get_cur_elev() ) { + target_alt = scenery.get_cur_elev(); } TargetAltitude = target_alt; diff --git a/src/Cockpit/cockpit.cxx b/src/Cockpit/cockpit.cxx index 2c84e573d..6feb75bb3 100644 --- a/src/Cockpit/cockpit.cxx +++ b/src/Cockpit/cockpit.cxx @@ -198,10 +198,10 @@ float get_agl( void ) if ( fgGetString("/sim/startup/units") == "feet" ) { agl = (current_aircraft.fdm_state->get_Altitude() - - scenery.cur_elev * SG_METER_TO_FEET); + - scenery.get_cur_elev() * SG_METER_TO_FEET); } else { agl = (current_aircraft.fdm_state->get_Altitude() * SG_FEET_TO_METER - - scenery.cur_elev); + - scenery.get_cur_elev()); } return agl; diff --git a/src/FDM/ADA.cxx b/src/FDM/ADA.cxx index 44fb78fe9..ae8e33ed3 100644 --- a/src/FDM/ADA.cxx +++ b/src/FDM/ADA.cxx @@ -228,8 +228,7 @@ bool FGADA::update( int multiloop ) { // Convert from the FGInterface struct to the FGADA struct (output) bool FGADA::copy_to_FGADA () { - - ground_elevation = scenery.cur_elev; + ground_elevation = scenery.get_cur_elev(); return true; } diff --git a/src/FDM/JSBSim.cxx b/src/FDM/JSBSim.cxx index 4ec1faf70..183e8dac3 100644 --- a/src/FDM/JSBSim.cxx +++ b/src/FDM/JSBSim.cxx @@ -294,7 +294,7 @@ bool FGJSBsim::copy_to_JSBsim() { } Position->SetSeaLevelRadius( get_Sea_level_radius() ); - Position->SetRunwayRadius( scenery.cur_elev*SG_METER_TO_FEET + Position->SetRunwayRadius( scenery.get_cur_elev()*SG_METER_TO_FEET + get_Sea_level_radius() ); Atmosphere->SetExTemperature(get_Static_temperature()); diff --git a/src/FDM/LaRCsim.cxx b/src/FDM/LaRCsim.cxx index f7a769b52..f6343d676 100644 --- a/src/FDM/LaRCsim.cxx +++ b/src/FDM/LaRCsim.cxx @@ -185,7 +185,7 @@ bool FGLaRCsim::update( int multiloop ) { // Inform LaRCsim of the local terrain altitude // Runway_altitude = get_Runway_altitude(); - Runway_altitude = scenery.cur_elev * SG_METER_TO_FEET; + Runway_altitude = scenery.get_cur_elev() * SG_METER_TO_FEET; // Weather /* V_north_airmass = get_V_north_airmass(); diff --git a/src/FDM/flight.cxx b/src/FDM/flight.cxx index 1c16f7c4f..29c62d05a 100644 --- a/src/FDM/flight.cxx +++ b/src/FDM/flight.cxx @@ -78,7 +78,6 @@ FGInterface::FGInterface() { } FGInterface::FGInterface( double dt ) { - _setup(); delta_t = dt; remainder = elapsed = multi_loop = 0; @@ -98,6 +97,9 @@ FGInterface::~FGInterface() { void FGInterface::_setup () { + inited = false; + bound = false; + init_vec( d_pilot_rp_body_v ); init_vec( d_cg_rp_body_v ); init_vec( f_body_total_v ); @@ -179,6 +181,8 @@ FGInterface::init () { SG_LOG(SG_FLIGHT, SG_INFO, "Start initializing FGInterface"); + inited = true; + stamp(); set_remainder(0); @@ -186,7 +190,7 @@ FGInterface::init () SG_LOG(SG_FLIGHT, SG_INFO, "...initializing position..."); set_Longitude(fgGetDouble("/position/longitude-deg") * SGD_DEGREES_TO_RADIANS); set_Latitude(fgGetDouble("/position/latitude-deg") * SGD_DEGREES_TO_RADIANS); - double ground_elev_m = scenery.cur_elev + 1; + double ground_elev_m = scenery.get_cur_elev() + 1; double ground_elev_ft = ground_elev_m * METERS_TO_FEET; if (fgGetBool("/sim/startup/onground") || fgGetDouble("/position/altitude-ft") < ground_elev_ft) @@ -201,6 +205,8 @@ FGInterface::init () // Set sea-level radius SG_LOG(SG_FLIGHT, SG_INFO, "...initializing sea-level radius..."); + SG_LOG(SG_FLIGHT, SG_INFO, " lat = " << get_Latitude() << " alt = " + << get_Altitude() ); double sea_level_radius_meters; double lat_geoc; sgGeodToGeoc(get_Latitude(), get_Altitude(), @@ -255,6 +261,8 @@ FGInterface::init () void FGInterface::bind () { + bound = true; + // Time management (read-only) fgTie("/fdm/time/delta_t", this, &FGInterface::get_delta_t); // read-only @@ -364,6 +372,8 @@ FGInterface::bind () void FGInterface::unbind () { + bound = false; + fgUntie("/fdm/time/delta_t"); fgUntie("/fdm/time/elapsed"); fgUntie("/fdm/time/remainder"); @@ -371,9 +381,10 @@ FGInterface::unbind () fgUntie("/position/latitude-deg"); fgUntie("/position/longitude-deg"); fgUntie("/position/altitude-ft"); - fgUntie("/position/heading"); - fgUntie("/position/pitch"); - fgUntie("/position/roll"); + fgUntie("/position/altitude-agl-ft"); + fgUntie("/orientation/heading-deg"); + fgUntie("/orientation/pitch-deg"); + fgUntie("/orientation/roll-deg"); fgUntie("/velocities/airspeed-kt"); fgUntie("/velocities/speed-north-fps"); fgUntie("/velocities/speed-east-fps"); @@ -426,7 +437,7 @@ void FGInterface::_updatePosition( double lat_geoc, double lon, double alt ) { _set_Geodetic_Position( lat_geod, lon, alt ); _set_Sea_level_radius( sl_radius2 * SG_METER_TO_FEET ); - _set_Runway_altitude( scenery.cur_elev*METERS_TO_FEET ); + _set_Runway_altitude( scenery.get_cur_elev()*METERS_TO_FEET ); _set_sin_lat_geocentric( lat_geoc ); _set_cos_lat_geocentric( lat_geoc ); diff --git a/src/FDM/flight.hxx b/src/FDM/flight.hxx index 68fda53ea..e01fc43cf 100644 --- a/src/FDM/flight.hxx +++ b/src/FDM/flight.hxx @@ -183,6 +183,14 @@ class FGInterface : public FGSubsystem { private: + // Has the init() method been called. This is used to delay + // initialization until scenery can be loaded and we know the true + // ground elevation. + bool inited; + + // Have we bound to the property system + bool bound; + // periodic update management variable. This is a scheme to run // the fdm with a fixed delta-t. We control how many iteration of // the fdm to run with the fixed dt based on the elapsed time from @@ -507,6 +515,12 @@ public: FG_EXTERNAL = 10 }; + // initialization + inline bool get_inited() const { return inited; } + inline void set_inited( bool value ) { inited = value; } + + inline bool get_bound() const { return bound; } + // time and update management values inline double get_delta_t() const { return delta_t; } inline void set_delta_t( double dt ) { delta_t = dt; } diff --git a/src/GUI/apt_dlg.cxx b/src/GUI/apt_dlg.cxx index e064e390a..970d40dea 100644 --- a/src/GUI/apt_dlg.cxx +++ b/src/GUI/apt_dlg.cxx @@ -51,6 +51,11 @@ void AptDialog_Cancel(puObject *) void AptDialog_OK (puObject *) { + static const SGPropertyNode *longitude + = fgGetNode("/position/longitude-deg"); + static const SGPropertyNode *latitude + = fgGetNode("/position/latitude-deg"); + SGPath path( globals->get_fg_root() ); path.append( "Airports" ); path.append( "simple.mk4" ); @@ -78,6 +83,11 @@ void AptDialog_OK (puObject *) if ( airports.search( AptId, &a ) ) { + // unbind the current fdm state so property changes + // don't get lost when we subsequently delete this fdm + // and create a new one. + cur_fdm_state->unbind(); + AptId = a.id.c_str(); /// NHV fix wrong case crash fgSetString("/sim/startup/airport-id", AptId.c_str() ); // fgSetDouble("/position/altitude-ft", -9999.0 ); @@ -87,26 +97,24 @@ void AptDialog_OK (puObject *) SGD_RADIANS_TO_DEGREES); BusyCursor(0); fgReInitSubsystems(); - if ( global_tile_mgr.init() ) { + // if ( global_tile_mgr.init() ) { // Load the local scenery data - global_tile_mgr.update( - cur_fdm_state->get_Longitude() - * SGD_RADIANS_TO_DEGREES, - cur_fdm_state->get_Latitude() - * SGD_RADIANS_TO_DEGREES ); - } else { - SG_LOG( SG_GENERAL, SG_ALERT, - "Error in Tile Manager initialization!" ); - exit(-1); - } + global_tile_mgr.update( longitude->getDoubleValue(), + longitude->getDoubleValue() ); + // } else { + // SG_LOG( SG_GENERAL, SG_ALERT, + // "Error in Tile Manager initialization!" ); + // exit(-1); + // } BusyCursor(1); } else { AptId += " not in database."; mkDialog(AptId.c_str()); } } - if(!freeze) + if ( !freeze ) { globals->set_freeze( false ); + } } diff --git a/src/Main/fg_init.cxx b/src/Main/fg_init.cxx index 17c2600b9..1be234127 100644 --- a/src/Main/fg_init.cxx +++ b/src/Main/fg_init.cxx @@ -455,7 +455,7 @@ bool fgInitGeneral( void ) { if ( ! root.length() ) { // No root path set? Then bail ... SG_LOG( SG_GENERAL, SG_ALERT, - "Cannot continue without environment variable FG_ROOT" + "Cannot continue without a path to the base package " << "being defined." ); exit(-1); } @@ -508,12 +508,8 @@ bool fgInitSubsystems( void ) { // Initialize the scenery management subsystem. //////////////////////////////////////////////////////////////////// - if ( fgSceneryInit() ) { - // Material lib initialized ok. - } else { - SG_LOG( SG_GENERAL, SG_ALERT, "Error in Scenery initialization!" ); - exit(-1); - } + scenery.init(); + scenery.bind(); if ( global_tile_mgr.init() ) { // Load the local scenery data @@ -526,7 +522,7 @@ bool fgInitSubsystems( void ) { SG_LOG( SG_GENERAL, SG_DEBUG, "Current terrain elevation after tile mgr init " << - scenery.cur_elev ); + scenery.get_cur_elev() ); //////////////////////////////////////////////////////////////////// @@ -562,8 +558,10 @@ bool fgInitSubsystems( void ) { exit(-1); } - cur_fdm_state->init(); - cur_fdm_state->bind(); + // Actual fdm initialization is delayed until we get a proper + // scenery elevation hit. This is checked for in main.cxx + // cur_fdm_state->init(); + // cur_fdm_state->bind(); // allocates structures so must happen before any of the flight // model or control parameters are set @@ -839,26 +837,61 @@ bool fgInitSubsystems( void ) { void fgReInitSubsystems( void ) { + static const SGPropertyNode *longitude + = fgGetNode("/position/longitude-deg"); + static const SGPropertyNode *latitude + = fgGetNode("/position/latitude-deg"); + static const SGPropertyNode *altitude + = fgGetNode("/position/altitude-ft"); + SG_LOG( SG_GENERAL, SG_INFO, - "/position/altitude = " << fgGetDouble("/position/altitude-ft") ); + "/position/altitude = " << altitude->getDoubleValue() ); bool freeze = globals->get_freeze(); - if( !freeze ) + if( !freeze ) { globals->set_freeze( true ); + } // Initialize the Scenery Management subsystem - if ( ! fgSceneryInit() ) { - SG_LOG( SG_GENERAL, SG_ALERT, "Error in Scenery initialization!" ); - exit(-1); - } + scenery.init(); - if( global_tile_mgr.init() ) { + // if( global_tile_mgr.init() ) { // Load the local scenery data - global_tile_mgr.update( fgGetDouble("/position/longitude-deg"), - fgGetDouble("/position/latitude-deg") ); - } else { - SG_LOG( SG_GENERAL, SG_ALERT, "Error in Tile Manager initialization!" ); - exit(-1); + global_tile_mgr.update( longitude->getDoubleValue(), + latitude->getDoubleValue() ); + // } else { + // SG_LOG( SG_GENERAL, SG_ALERT, "Error in Tile Manager initialization!" ); + // exit(-1); + // } + + // Delete then Initialize the flight model subsystem. + delete cur_fdm_state; + + double dt = 1.0 / fgGetInt("/sim/model-hz"); + aircraft_dir = fgGetString("/sim/aircraft-dir"); + const string &model = fgGetString("/sim/flight-model"); + try { + if (model == "larcsim") { + cur_fdm_state = new FGLaRCsim( dt ); + } else if (model == "jsb") { + cur_fdm_state = new FGJSBsim( dt ); + } else if (model == "ada") { + cur_fdm_state = new FGADA( dt ); + } else if (model == "balloon") { + cur_fdm_state = new FGBalloonSim( dt ); + } else if (model == "magic") { + cur_fdm_state = new FGMagicCarpet( dt ); + } else if (model == "external") { + cur_fdm_state = new FGExternal( dt ); + } else { + SG_LOG(SG_GENERAL, SG_ALERT, + "Unrecognized flight model '" << model + << ", can't init aircraft"); + exit(-1); + } + } catch ( ... ) { + SG_LOG(SG_GENERAL, SG_ALERT, "FlightGear aborting\n\n"); + exit(-1); } // Initialize view parameters @@ -868,12 +901,12 @@ void fgReInitSubsystems( void ) pilot_view->set_view_offset( 0.0 ); pilot_view->set_goal_view_offset( 0.0 ); - pilot_view->set_geod_view_pos( cur_fdm_state->get_Longitude(), - cur_fdm_state->get_Lat_geocentric(), - cur_fdm_state->get_Altitude() * - SG_FEET_TO_METER ); - pilot_view->set_sea_level_radius( cur_fdm_state->get_Sea_level_radius() * - SG_FEET_TO_METER ); + pilot_view->set_geod_view_pos( longitude->getDoubleValue() + * SGD_DEGREES_TO_RADIANS, + latitude->getDoubleValue() + * SGD_DEGREES_TO_RADIANS, + cur_fdm_state->get_Altitude() + * SG_FEET_TO_METER ); pilot_view->set_rph( cur_fdm_state->get_Phi(), cur_fdm_state->get_Theta(), cur_fdm_state->get_Psi() ); @@ -884,8 +917,6 @@ void fgReInitSubsystems( void ) SG_LOG( SG_GENERAL, SG_DEBUG, " abs_view_pos = " << globals->get_current_view()->get_abs_view_pos()); - cur_fdm_state->init(); - globals->get_controls()->reset_all(); current_autopilot->reset(); diff --git a/src/Main/fg_props.cxx b/src/Main/fg_props.cxx index 9dca63c5c..114167ae4 100644 --- a/src/Main/fg_props.cxx +++ b/src/Main/fg_props.cxx @@ -394,7 +394,7 @@ getHeadingMag () static double getRPM () { - if ( current_aircraft.fdm_state->get_engine(0) != NULL ) { + if ( current_aircraft.fdm_state->get_num_engines() > 0 ) { return current_aircraft.fdm_state->get_engine(0)->get_RPM(); } else { return 0.0; @@ -408,7 +408,7 @@ getRPM () static double getEGT () { - if ( current_aircraft.fdm_state->get_engine(0) != NULL ) { + if ( current_aircraft.fdm_state->get_num_engines() > 0 ) { return current_aircraft.fdm_state->get_engine(0)->get_EGT(); } else { return 0.0; @@ -421,7 +421,7 @@ getEGT () static double getCHT () { - if ( current_aircraft.fdm_state->get_engine(0) != NULL ) { + if ( current_aircraft.fdm_state->get_num_engines() > 0 ) { return current_aircraft.fdm_state->get_engine(0)->get_CHT(); } else { return 0.0; @@ -434,7 +434,7 @@ getCHT () static double getOilTemp () { - if ( current_aircraft.fdm_state->get_engine(0) != NULL ) { + if ( current_aircraft.fdm_state->get_num_engines() > 0 ) { return current_aircraft.fdm_state->get_engine(0)->get_Oil_Temp(); } else { return 0.0; @@ -447,7 +447,7 @@ getOilTemp () static double getMP () { - if ( current_aircraft.fdm_state->get_engine(0) != NULL ) { + if ( current_aircraft.fdm_state->get_num_engines() > 0 ) { return current_aircraft.fdm_state->get_engine(0)->get_Manifold_Pressure(); } else { return 0.0; @@ -461,7 +461,7 @@ getMP () static double getFuelFlow () { - if ( current_aircraft.fdm_state->get_engine(0) != NULL ) { + if ( current_aircraft.fdm_state->get_num_engines() > 0 ) { return current_aircraft.fdm_state->get_engine(0)->get_Fuel_Flow(); } else { return 0.0; @@ -474,7 +474,7 @@ getFuelFlow () static bool getRunningFlag () { - if ( current_aircraft.fdm_state->get_engine(0) != NULL ) { + if ( current_aircraft.fdm_state->get_num_engines() > 0 ) { return current_aircraft.fdm_state->get_engine(0)->get_Running_Flag(); } else { return false; @@ -487,7 +487,7 @@ getRunningFlag () static bool getCrankingFlag () { - if ( current_aircraft.fdm_state->get_engine(0) != NULL ) { + if ( current_aircraft.fdm_state->get_num_engines() > 0 ) { return current_aircraft.fdm_state->get_engine(0)->get_Cranking_Flag(); } else { return false; @@ -924,7 +924,7 @@ setWindDown (double speed) static void setRunningFlag (bool flag) { - if(current_aircraft.fdm_state->get_engine(0) != NULL) { + if ( current_aircraft.fdm_state->get_num_engines() > 0 ) { current_aircraft.fdm_state->get_engine(0)->set_Running_Flag( flag ); } } @@ -938,7 +938,7 @@ setRunningFlag (bool flag) static void setCrankingFlag (bool flag) { - if(current_aircraft.fdm_state->get_engine(0) != NULL) { + if ( current_aircraft.fdm_state->get_num_engines() > 0 ) { current_aircraft.fdm_state->get_engine(0)->set_Cranking_Flag( flag ); } } diff --git a/src/Main/main.cxx b/src/Main/main.cxx index 8395f0320..845b1ad6e 100644 --- a/src/Main/main.cxx +++ b/src/Main/main.cxx @@ -56,10 +56,6 @@ # include // for stat() #endif -// #ifdef HAVE_LIBX11 -// # include -// #endif - #include #include #include @@ -161,9 +157,6 @@ FGGeneral general; static int idle_state = 0; static long global_multi_loop; -// attempt to avoid a large bounce at startup -static bool initial_freeze = true; - // forward declaration void fgReshape( int width, int height ); @@ -404,6 +397,13 @@ void trRenderFrame( void ) { // Update all Visuals (redraws anything graphics related) void fgRenderFrame( void ) { + static const SGPropertyNode *longitude + = fgGetNode("/position/longitude-deg"); + static const SGPropertyNode *latitude + = fgGetNode("/position/latitude-deg"); + static const SGPropertyNode *altitude + = fgGetNode("/position/altitude-ft"); + // Update the default (kludged) properties. fgUpdateProps(); @@ -431,7 +431,7 @@ void fgRenderFrame( void ) { // initializations and are running the main loop, so this will // now work without seg faulting the system. - // printf("Ground = %.2f Altitude = %.2f\n", scenery.cur_elev, + // printf("Ground = %.2f Altitude = %.2f\n", scenery.get_cur_elev(), // FG_Altitude * SG_FEET_TO_METER); // this is just a temporary hack, to make me understand Pui @@ -439,20 +439,19 @@ void fgRenderFrame( void ) { // end of hack // calculate our current position in cartesian space - scenery.center = scenery.next_center; + scenery.set_center( scenery.get_next_center() ); // printf("scenery center = %.2f %.2f %.2f\n", scenery.center.x(), // scenery.center.y(), scenery.center.z()); FGViewerRPH *pilot_view = (FGViewerRPH *)globals->get_viewmgr()->get_view( 0 ); - pilot_view->set_geod_view_pos( cur_fdm_state->get_Longitude(), - cur_fdm_state->get_Lat_geocentric(), - cur_fdm_state->get_Altitude() * - SG_FEET_TO_METER ); - pilot_view->set_sea_level_radius( cur_fdm_state-> - get_Sea_level_radius() * - SG_FEET_TO_METER ); + pilot_view->set_geod_view_pos( longitude->getDoubleValue() + * SGD_DEGREES_TO_RADIANS, + latitude->getDoubleValue() + * SGD_DEGREES_TO_RADIANS, + altitude->getDoubleValue() + * SG_FEET_TO_METER ); pilot_view->set_rph( cur_fdm_state->get_Phi(), cur_fdm_state->get_Theta(), cur_fdm_state->get_Psi() ); @@ -479,13 +478,12 @@ void fgRenderFrame( void ) { sgXformVec3( po, *pPO, pilot_view->get_UP() ); sgXformVec3( npo, po, CXFM ); - chase_view->set_geod_view_pos( cur_fdm_state->get_Longitude(), - cur_fdm_state->get_Lat_geocentric(), - cur_fdm_state->get_Altitude() * - SG_FEET_TO_METER ); - chase_view->set_sea_level_radius( cur_fdm_state-> - get_Sea_level_radius() * - SG_FEET_TO_METER ); + chase_view->set_geod_view_pos( longitude->getDoubleValue() + * SGD_DEGREES_TO_RADIANS, + latitude->getDoubleValue() + * SGD_DEGREES_TO_RADIANS, + altitude->getDoubleValue() + * SG_FEET_TO_METER ); chase_view->set_pilot_offset( npo[0], npo[1], npo[2] ); chase_view->set_view_forward( pilot_view->get_view_pos() ); chase_view->set_view_up( wup ); @@ -643,9 +641,11 @@ void fgRenderFrame( void ) { thesky->reposition( globals->get_current_view()->get_view_pos(), globals->get_current_view()->get_zero_elev(), globals->get_current_view()->get_world_up(), - cur_fdm_state->get_Longitude(), - cur_fdm_state->get_Latitude(), - cur_fdm_state->get_Altitude() * SG_FEET_TO_METER, + longitude->getDoubleValue() + * SGD_DEGREES_TO_RADIANS, + latitude->getDoubleValue() + * SGD_DEGREES_TO_RADIANS, + altitude->getDoubleValue() * SG_FEET_TO_METER, cur_light_params.sun_rotation, globals->get_time_params()->getGst(), globals->get_ephem()->getSunRightAscension(), @@ -689,7 +689,7 @@ void fgRenderFrame( void ) { ssgSetFOV(fov, fov * globals->get_current_view()->get_fov_ratio()); double agl = current_aircraft.fdm_state->get_Altitude() * SG_FEET_TO_METER - - scenery.cur_elev; + - scenery.get_cur_elev(); // SG_LOG( SG_ALL, SG_INFO, "visibility is " // << current_weather.get_visibility() ); @@ -874,8 +874,9 @@ void fgRenderFrame( void ) { fgCockpitUpdate(); // update the panel subsystem - if (current_panel != 0) - current_panel->update(); + if ( current_panel != NULL ) { + current_panel->update(); + } // We can do translucent menus, so why not. :-) menus->apply(); @@ -894,13 +895,40 @@ void fgRenderFrame( void ) { void fgUpdateTimeDepCalcs() { static bool inited = false; + // cout << "Updating time dep calcs()" << endl; + fgLIGHT *l = &cur_light_params; int i; long multi_loop = 1; - if ( !globals->get_freeze() && !initial_freeze ) { - // conceptually, this could be done for each fdm instance ... + // Initialize the FDM here if it hasn't been and if we have a + // scenery elevation hit. + + // cout << "cur_fdm_state->get_inited() = " << cur_fdm_state->get_inited() + // << " cur_elev = " << scenery.get_cur_elev() << endl; + + if ( !cur_fdm_state->get_inited() && scenery.get_cur_elev() > -9990 ) { + cout << "Finally initializing fdm" << endl; + cur_fdm_state->init(); + if ( cur_fdm_state->get_bound() ) { + cur_fdm_state->unbind(); + } + cur_fdm_state->bind(); + } + + // conceptually, the following block could be done for each fdm + // instance ... + if ( !cur_fdm_state->get_inited() ) { + // do nothing, fdm isn't inited yet + } else if ( globals->get_freeze() ) { + // we are frozen, run the fdm's with 0 time slices in case + // they want to do something with that. + + cur_fdm_state->update( 0 ); + FGSteam::update( 0 ); + } else { + // we have been inited, and we are not frozen, we are good to go ... if ( !inited ) { cur_fdm_state->stamp(); @@ -938,13 +966,6 @@ void fgUpdateTimeDepCalcs() { cur_fdm_state->update( 1 ); } FGSteam::update( multi_loop * fgGetInt("/sim/speed-up") ); - } else { - cur_fdm_state->update( 0 ); - FGSteam::update( 0 ); - - //if ( global_tile_mgr.queue_size() == 0 ) { - initial_freeze = false; - //} } if ( fgGetString("/sim/view-mode") == "pilot" ) { @@ -1024,6 +1045,13 @@ static const double alt_adjust_m = alt_adjust_ft * SG_FEET_TO_METER; // What should we do when we have nothing else to do? Let's get ready // for the next move and update the display? static void fgMainLoop( void ) { + static const SGPropertyNode *longitude + = fgGetNode("/position/longitude-deg"); + static const SGPropertyNode *latitude + = fgGetNode("/position/latitude-deg"); + static const SGPropertyNode *altitude + = fgGetNode("/position/altitude-ft"); + static long remainder = 0; long elapsed; #ifdef FANCY_FRAME_COUNTER @@ -1069,20 +1097,20 @@ static void fgMainLoop( void ) { // probably move eventually /* printf("Before - ground = %.2f runway = %.2f alt = %.2f\n", - scenery.cur_elev, + scenery.get_cur_elev(), cur_fdm_state->get_Runway_altitude() * SG_FEET_TO_METER, cur_fdm_state->get_Altitude() * SG_FEET_TO_METER); */ - if ( scenery.cur_elev > -9990 ) { + if ( scenery.get_cur_elev() > -9990 ) { if ( cur_fdm_state->get_Altitude() * SG_FEET_TO_METER < - (scenery.cur_elev + alt_adjust_m - 3.0) ) { + (scenery.get_cur_elev() + alt_adjust_m - 3.0) ) { // now set aircraft altitude above ground printf("(*) Current Altitude = %.2f < %.2f forcing to %.2f\n", cur_fdm_state->get_Altitude() * SG_FEET_TO_METER, - scenery.cur_elev + alt_adjust_m - 3.0, - scenery.cur_elev + alt_adjust_m ); + scenery.get_cur_elev() + alt_adjust_m - 3.0, + scenery.get_cur_elev() + alt_adjust_m ); fgFDMForceAltitude( fgGetString("/sim/flight-model"), - scenery.cur_elev + alt_adjust_m ); + scenery.get_cur_elev() + alt_adjust_m ); SG_LOG( SG_ALL, SG_DEBUG, "<*> resetting altitude to " @@ -1092,7 +1120,7 @@ static void fgMainLoop( void ) { } /* printf("Adjustment - ground = %.2f runway = %.2f alt = %.2f\n", - scenery.cur_elev, + scenery.get_cur_elev(), cur_fdm_state->get_Runway_altitude() * SG_FEET_TO_METER, cur_fdm_state->get_Altitude() * SG_FEET_TO_METER); */ @@ -1103,8 +1131,8 @@ static void fgMainLoop( void ) { globals->inc_warp( globals->get_warp_delta() ); } - t->update( cur_fdm_state->get_Longitude(), - cur_fdm_state->get_Latitude(), + t->update( longitude->getDoubleValue() * SGD_DEGREES_TO_RADIANS, + latitude->getDoubleValue() * SGD_DEGREES_TO_RADIANS, globals->get_warp() ); if ( globals->get_warp_delta() != 0 ) { @@ -1112,9 +1140,11 @@ static void fgMainLoop( void ) { } // update magvar model - globals->get_mag()->update( cur_fdm_state->get_Longitude(), - cur_fdm_state->get_Latitude(), - cur_fdm_state->get_Altitude()* SG_FEET_TO_METER, + globals->get_mag()->update( longitude->getDoubleValue() + * SGD_DEGREES_TO_RADIANS, + latitude->getDoubleValue() + * SGD_DEGREES_TO_RADIANS, + altitude->getDoubleValue() * SG_FEET_TO_METER, globals->get_time_params()->getJD() ); // Get elapsed time (in usec) for this past frame @@ -1177,7 +1207,7 @@ static void fgMainLoop( void ) { if ( global_multi_loop > 0 ) { fgUpdateTimeDepCalcs(); } else { - SG_LOG( SG_ALL, SG_DEBUG, + SG_LOG( SG_ALL, SG_INFO, "Elapsed time is zero ... we're zinging" ); } @@ -1187,10 +1217,8 @@ static void fgMainLoop( void ) { #endif // see if we need to load any new scenery tiles - global_tile_mgr.update( cur_fdm_state->get_Longitude() - * SGD_RADIANS_TO_DEGREES, - cur_fdm_state->get_Latitude() - * SGD_RADIANS_TO_DEGREES ); + global_tile_mgr.update( longitude->getDoubleValue(), + latitude->getDoubleValue() ); // see if we need to load any deferred-load textures material_lib.load_next_deferred(); @@ -1512,7 +1540,6 @@ int fgGlutInitEvents( void ) { // Main loop int mainLoop( int argc, char **argv ) { - #if defined( macintosh ) freopen ("stdout.txt", "w", stdout ); freopen ("stderr.txt", "w", stderr ); @@ -1629,11 +1656,21 @@ int mainLoop( int argc, char **argv ) { fgGetDouble("/orientation/heading-deg") ); } + // Any time after globals is created we are ready to use the + // property system + static const SGPropertyNode *longitude + = fgGetNode("/position/longitude-deg", true); + static const SGPropertyNode *latitude + = fgGetNode("/position/latitude-deg", true); + + // Initialize time SGPath zone( globals->get_fg_root() ); zone.append( "Timezone" ); - SGTime *t = new SGTime( fgGetDouble("/position/longitude-deg") * SGD_DEGREES_TO_RADIANS, - fgGetDouble("/position/latitude-deg") * SGD_DEGREES_TO_RADIANS, + SGTime *t = new SGTime( longitude->getDoubleValue() + * SGD_DEGREES_TO_RADIANS, + latitude->getDoubleValue() + * SGD_DEGREES_TO_RADIANS, zone.str() ); // Handle potential user specified time offsets @@ -2099,7 +2136,7 @@ void fgUpdateDCS (void) { Point3D obj_pos = sgGeodToCart( obj_posn ); // Translate moving object w.r.t eye - Point3D Objtrans = obj_pos-scenery.center; + Point3D Objtrans = obj_pos-scenery.get_center(); bz[0]=Objtrans.x(); bz[1]=Objtrans.y(); bz[2]=Objtrans.z(); diff --git a/src/Main/viewer_lookat.cxx b/src/Main/viewer_lookat.cxx index f39c08bf1..3b4fb808b 100644 --- a/src/Main/viewer_lookat.cxx +++ b/src/Main/viewer_lookat.cxx @@ -34,6 +34,7 @@ #include #include #include +#include #include #include @@ -107,21 +108,24 @@ void FGViewerLookAt::update() { Point3D tmp; sgVec3 minus_z; - // calculate the cartesion coords of the current lat/lon/0 elev - Point3D p = Point3D( geod_view_pos[0], - geod_view_pos[1], - sea_level_radius ); + // convert to geocentric coordinates + double geoc_lat; + sgGeodToGeoc( geod_view_pos[1], geod_view_pos[2], + &sea_level_radius, &geoc_lat ); - tmp = sgPolarToCart3d(p) - scenery.center; + // calculate the cartesion coords of the current lat/lon/0 elev + Point3D p = Point3D( geod_view_pos[0], geoc_lat, sea_level_radius ); + + tmp = sgPolarToCart3d(p) - scenery.get_center(); sgSetVec3( zero_elev, tmp[0], tmp[1], tmp[2] ); // calculate view position in current FG view coordinate system // p.lon & p.lat are already defined earlier, p.radius was set to // the sea level radius, so now we add in our altitude. - if ( geod_view_pos[2] > (scenery.cur_elev + 0.5 * SG_METER_TO_FEET) ) { + if ( geod_view_pos[2] > (scenery.get_cur_elev() + 0.5 * SG_METER_TO_FEET) ) { p.setz( p.radius() + geod_view_pos[2] ); } else { - p.setz( p.radius() + scenery.cur_elev + 0.5 * SG_METER_TO_FEET ); + p.setz( p.radius() + scenery.get_cur_elev() + 0.5 * SG_METER_TO_FEET ); } tmp = sgPolarToCart3d(p); @@ -129,7 +133,10 @@ void FGViewerLookAt::update() { // view_pos = abs_view_pos - scenery.center; sgdVec3 sc; - sgdSetVec3( sc, scenery.center.x(), scenery.center.y(), scenery.center.z()); + sgdSetVec3( sc, + scenery.get_center().x(), + scenery.get_center().y(), + scenery.get_center().z() ); sgdVec3 vp; sgdSubVec3( vp, abs_view_pos, sc ); sgSetVec3( view_pos, vp ); diff --git a/src/Main/viewer_rph.cxx b/src/Main/viewer_rph.cxx index 7b6aa6ac2..e8ab87b62 100644 --- a/src/Main/viewer_rph.cxx +++ b/src/Main/viewer_rph.cxx @@ -35,6 +35,7 @@ #include #include #include +#include #include #include @@ -159,21 +160,24 @@ void FGViewerRPH::update() { sgVec3 minus_z, forward; sgMat4 VIEWo; - // calculate the cartesion coords of the current lat/lon/0 elev - Point3D p = Point3D( geod_view_pos[0], - geod_view_pos[1], - sea_level_radius ); + // convert to geocentric coordinates + double geoc_lat; + sgGeodToGeoc( geod_view_pos[1], geod_view_pos[2], + &sea_level_radius, &geoc_lat ); - tmp = sgPolarToCart3d(p) - scenery.center; + // calculate the cartesion coords of the current lat/lon/0 elev + Point3D p = Point3D( geod_view_pos[0], geoc_lat, sea_level_radius ); + + tmp = sgPolarToCart3d(p) - scenery.get_center(); sgSetVec3( zero_elev, tmp[0], tmp[1], tmp[2] ); // calculate view position in current FG view coordinate system // p.lon & p.lat are already defined earlier, p.radius was set to // the sea level radius, so now we add in our altitude. - if ( geod_view_pos[2] > (scenery.cur_elev + 0.5 * SG_METER_TO_FEET) ) { + if ( geod_view_pos[2] > (scenery.get_cur_elev() + 0.5 * SG_METER_TO_FEET) ) { p.setz( p.radius() + geod_view_pos[2] ); } else { - p.setz( p.radius() + scenery.cur_elev + 0.5 * SG_METER_TO_FEET ); + p.setz( p.radius() + scenery.get_cur_elev() + 0.5 * SG_METER_TO_FEET ); } tmp = sgPolarToCart3d(p); @@ -181,7 +185,10 @@ void FGViewerRPH::update() { // view_pos = abs_view_pos - scenery.center; sgdVec3 sc; - sgdSetVec3( sc, scenery.center.x(), scenery.center.y(), scenery.center.z()); + sgdSetVec3( sc, + scenery.get_center().x(), + scenery.get_center().y(), + scenery.get_center().z() ); sgdVec3 vp; sgdSubVec3( vp, abs_view_pos, sc ); sgSetVec3( view_pos, vp ); diff --git a/src/Network/native_ctrls.cxx b/src/Network/native_ctrls.cxx index f34367dbc..646a1d160 100644 --- a/src/Network/native_ctrls.cxx +++ b/src/Network/native_ctrls.cxx @@ -75,7 +75,7 @@ static void global2raw( const FGControls *global, FGRawCtrls *raw ) { raw->brake[i] = globals->get_controls()->get_brake(i); } - raw->hground = scenery.cur_elev; + raw->hground = scenery.get_cur_elev(); } @@ -96,7 +96,7 @@ static void raw2global( const FGRawCtrls *raw, FGControls *global ) { for ( i = 0; i < FG_MAX_WHEELS; ++i ) { globals->get_controls()->set_brake( i, raw->brake[i] ); } - scenery.cur_elev = raw->hground; + scenery.set_cur_elev( raw->hground ); } else { SG_LOG( SG_IO, SG_ALERT, "Error: version mismatch in raw2global()" ); SG_LOG( SG_IO, SG_ALERT, diff --git a/src/Scenery/scenery.cxx b/src/Scenery/scenery.cxx index b5a4406f0..1341d21d4 100644 --- a/src/Scenery/scenery.cxx +++ b/src/Scenery/scenery.cxx @@ -37,19 +37,38 @@ #include +#include
+ #include "scenery.hxx" // Shared structure to hold current scenery parameters -struct fgSCENERY scenery; +FGScenery scenery; -// Initialize the Scenery Management system -int fgSceneryInit( void ) { +// Scenery Management system +FGScenery::FGScenery() { SG_LOG( SG_TERRAIN, SG_INFO, "Initializing scenery subsystem" ); - scenery.center = Point3D(0.0); - scenery.cur_elev = -9999; - - return 1; + center = Point3D(0.0); + cur_elev = -9999; +} + +// Initialize the Scenery Management system +FGScenery::~FGScenery() { +} + +void FGScenery::init() { +} + +void FGScenery::update() { +} + +void FGScenery::bind() { + fgTie("/environment/ground-elevation-m", this, + &FGScenery::get_cur_elev, &FGScenery::set_cur_elev); +} + +void FGScenery::unbind() { + fgUntie("/environment/ground-elevation-m"); } diff --git a/src/Scenery/scenery.hxx b/src/Scenery/scenery.hxx index a0fc95e8a..f67883756 100644 --- a/src/Scenery/scenery.hxx +++ b/src/Scenery/scenery.hxx @@ -33,9 +33,11 @@ #include #include +#include
+ // Define a structure containing global scenery parameters -struct fgSCENERY { +class FGScenery : public FGSubsystem { // center of current scenery chunk Point3D center; @@ -55,9 +57,33 @@ struct fgSCENERY { // unit normal at point used to determine current elevation sgdVec3 cur_normal; + +public: + + FGScenery(); + ~FGScenery(); + + // Implementation of FGSubsystem. + void init (); + void bind (); + void unbind (); + void update (); + + inline double get_cur_elev() const { return cur_elev; } + inline void set_cur_elev( double e ) { cur_elev = e; } + + inline Point3D get_center() const { return center; } + inline void set_center( Point3D p ) { center = p; } + + inline Point3D get_next_center() const { return next_center; } + inline void set_next_center( Point3D p ) { next_center = p; } + + inline void set_cur_radius( double r ) { cur_radius = r; } + inline void set_cur_normal( sgdVec3 n ) { sgdCopyVec3( cur_normal, n ); } }; -extern struct fgSCENERY scenery; + +extern FGScenery scenery; // Initialize the Scenery Management system diff --git a/src/Scenery/tileentry.cxx b/src/Scenery/tileentry.cxx index b55cf8dec..c1e4bc3c7 100644 --- a/src/Scenery/tileentry.cxx +++ b/src/Scenery/tileentry.cxx @@ -778,7 +778,7 @@ void FGTileEntry::prep_ssg_node( const Point3D& p, float vis) { double agl; if ( current_aircraft.fdm_state ) { agl = current_aircraft.fdm_state->get_Altitude() * SG_FEET_TO_METER - - scenery.cur_elev; + - scenery.get_cur_elev(); } else { agl = 0.0; } @@ -829,7 +829,7 @@ void FGTileEntry::prep_ssg_node( const Point3D& p, float vis) { double agl1; if ( current_aircraft.fdm_state ) { agl1 = current_aircraft.fdm_state->get_Altitude() * SG_FEET_TO_METER - - scenery.cur_elev; + - scenery.get_cur_elev(); } else { agl1 = 0.0; } @@ -1261,7 +1261,7 @@ FGTileEntry::load( const SGPath& base, bool is_base ) terra_transform->addKid( terra_range ); // calculate initial tile offset - SetOffset( scenery.center ); + SetOffset( scenery.get_center() ); sgCoord sgcoord; sgSetCoord( &sgcoord, offset.x(), offset.y(), offset.z(), diff --git a/src/Scenery/tilemgr.cxx b/src/Scenery/tilemgr.cxx index 912aa2994..eb2dbf591 100644 --- a/src/Scenery/tilemgr.cxx +++ b/src/Scenery/tilemgr.cxx @@ -154,6 +154,7 @@ void FGTileMgr::sched_tile( const SGBucket& b ) { // schedule a needed buckets for loading void FGTileMgr::schedule_needed() { + cout << "scheduling needed tiles for " << longitude << " " << latitude << endl; #ifndef FG_OLD_WEATHER if ( WeatherDatabase != NULL ) { vis = WeatherDatabase->getWeatherVisibility(); @@ -250,13 +251,8 @@ void FGTileMgr::initialize_queue() // chunks. If the chunk isn't already in the cache, then read it from // disk. int FGTileMgr::update( double lon, double lat ) { - SG_LOG( SG_TERRAIN, SG_DEBUG, "FGTileMgr::update()" ); + SG_LOG( SG_TERRAIN, SG_DEBUG, "FGTileMgr::update() for" << lon << " " << lat ); - // FGInterface *f = current_aircraft.fdm_state; - - // lonlat for this update - // longitude = f->get_Longitude() * SGD_RADIANS_TO_DEGREES; - // latitude = f->get_Latitude() * SGD_RADIANS_TO_DEGREES; longitude = lon; latitude = lat; // SG_LOG( SG_TERRAIN, SG_DEBUG, "lon "<< lonlat[LON] << @@ -267,25 +263,27 @@ int FGTileMgr::update( double lon, double lat ) { if ( tile_cache.exists( current_bucket ) ) { current_tile = tile_cache.get_tile( current_bucket ); - scenery.next_center = current_tile->center; + scenery.set_next_center( current_tile->center ); } else { SG_LOG( SG_TERRAIN, SG_WARN, "Tile not found (Ok if initializing)" ); } if ( state == Running ) { + SG_LOG( SG_TERRAIN, SG_DEBUG, "State == Running" ); if ( !(current_bucket == previous_bucket) ) { // We've moved to a new bucket, we need to schedule any // needed tiles for loading. schedule_needed(); } } else if ( state == Start || state == Inited ) { + SG_LOG( SG_TERRAIN, SG_INFO, "State == Start || Inited" ); initialize_queue(); state = Running; - } - // load the next tile in the load queue (or authorize the next - // load in the case of the threaded tile pager) - loader.update(); + // load the next tile in the load queue (or authorize the next + // load in the case of the threaded tile pager) + loader.update(); + } // load the next model in the load queue. Currently this must // happen in the render thread because model loading can trigger @@ -311,7 +309,7 @@ int FGTileMgr::update( double lon, double lat ) { delete dm; } - // cout << "current elevation (ssg) == " << scenery.cur_elev << endl; + // cout << "current elevation (ssg) == " << scenery.get_cur_elev() << endl; previous_bucket = current_bucket; last_longitude = longitude; @@ -320,23 +318,29 @@ int FGTileMgr::update( double lon, double lat ) { // activate loader thread one out of every 5 frames if ( counter_hack == 0 ) { // Notify the tile loader that it can load another tile - // loader.update(); + loader.update(); - if ( !attach_queue.empty() ) { -#ifdef ENABLE_THREADS - FGTileEntry* e = attach_queue.pop(); -#else - FGTileEntry* e = attach_queue.front(); - attach_queue.pop(); -#endif - e->add_ssg_nodes( terrain, ground ); - // cout << "Adding ssg nodes for " - } } counter_hack = (counter_hack + 1) % 5; - sgdVec3 sc; - sgdSetVec3( sc, scenery.center[0], scenery.center[1], scenery.center[2] ); + if ( !attach_queue.empty() ) { +#ifdef ENABLE_THREADS + FGTileEntry* e = attach_queue.pop(); +#else + FGTileEntry* e = attach_queue.front(); + attach_queue.pop(); +#endif + e->add_ssg_nodes( terrain, ground ); + // cout << "Adding ssg nodes for " + } + + sgdVec3 sc; + sgdSetVec3( sc, + scenery.get_center()[0], + scenery.get_center()[1], + scenery.get_center()[2] ); + +#if 0 if ( scenery.center == Point3D(0.0) ) { // initializing cout << "initializing scenery current elevation ... " << endl; @@ -356,24 +360,31 @@ int FGTileMgr::update( double lon, double lat ) { if ( fgCurrentElev(tmp_abs_view_pos, sc, &hit_list, &tmp_elev, &scenery.cur_radius, scenery.cur_normal) ) { - scenery.cur_elev = tmp_elev; + scenery.set_cur_elev( tmp_elev ); } else { - scenery.cur_elev = 0.0; + scenery.set_cur_elev( 0.0 ); } - cout << "result = " << scenery.cur_elev << endl; + cout << "result = " << scenery.get_cur_elev() << endl; } else { +#endif // cout << "abs view pos = " << current_view.abs_view_pos // << " view pos = " << current_view.view_pos << endl; double tmp_elev; + double tmp_radius; + sgdVec3 tmp_normal; if ( fgCurrentElev(globals->get_current_view()->get_abs_view_pos(), sc, &hit_list, - &tmp_elev, &scenery.cur_radius, scenery.cur_normal) ) + &tmp_elev, &tmp_radius, tmp_normal) ) { - scenery.cur_elev = tmp_elev; + scenery.set_cur_elev( tmp_elev ); + scenery.set_cur_radius( tmp_radius ); + scenery.set_cur_normal( tmp_normal ); } else { - scenery.cur_elev = 0.0; + scenery.set_cur_elev( -9999.0 ); } +#if 0 } +#endif return 1; } @@ -402,7 +413,7 @@ void FGTileMgr::prep_ssg_nodes() { while ( ! tile_cache.at_end() ) { // cout << "processing a tile" << endl; if ( (e = tile_cache.get_current()) ) { - e->prep_ssg_node( scenery.center, vis); + e->prep_ssg_node( scenery.get_center(), vis); } else { cout << "warning ... empty tile in cache" << endl; } diff --git a/src/Time/moonpos.cxx b/src/Time/moonpos.cxx index 9507f1a9f..1818cdd53 100644 --- a/src/Time/moonpos.cxx +++ b/src/Time/moonpos.cxx @@ -399,7 +399,7 @@ void fgUpdateMoonPos( void ) { Point3D vp( v->get_view_pos()[0], v->get_view_pos()[1], v->get_view_pos()[2] ); - rel_moonpos = l->fg_moonpos - ( vp + scenery.center ); + rel_moonpos = l->fg_moonpos - ( vp + scenery.get_center() ); sgSetVec3( to_moon, rel_moonpos.x(), rel_moonpos.y(), rel_moonpos.z() ); // printf( "Vector to moon = %.2f %.2f %.2f\n", // to_moon[0], to_moon[1], to_moon[2]); diff --git a/src/Time/sunpos.cxx b/src/Time/sunpos.cxx index 961e03706..c436b1b7d 100644 --- a/src/Time/sunpos.cxx +++ b/src/Time/sunpos.cxx @@ -306,7 +306,7 @@ void fgUpdateSunPos( void ) { Point3D vp( v->get_view_pos()[0], v->get_view_pos()[1], v->get_view_pos()[2] ); - rel_sunpos = l->fg_sunpos - ( vp + scenery.center ); + rel_sunpos = l->fg_sunpos - ( vp + scenery.get_center() ); sgSetVec3( to_sun, rel_sunpos.x(), rel_sunpos.y(), rel_sunpos.z() ); // printf( "Vector to sun = %.2f %.2f %.2f\n", // v->to_sun[0], v->to_sun[1], v->to_sun[2]);