diff --git a/src/AIModel/AIAircraft.cxx b/src/AIModel/AIAircraft.cxx index efe563057..08623551b 100644 --- a/src/AIModel/AIAircraft.cxx +++ b/src/AIModel/AIAircraft.cxx @@ -907,56 +907,17 @@ void FGAIAircraft::getGroundElev(double dt) { return; } - - //globals->get_tile_mgr()->prep_ssg_nodes( acmodel_location, - globals->get_tile_mgr()->prep_ssg_nodes( aip.getSGLocation(), visibility_meters ); - Point3D scenery_center = globals->get_scenery()->get_center(); + // FIXME: make shure the pos.lat/pos.lon values are in degrees ... + double range = 500.0; + if (!globals->get_tile_mgr()->scenery_available(pos.lat(), pos.lon(), range)) + { + // Try to shedule tiles for that position. + globals->get_tile_mgr()->update( aip.getSGLocation(), range ); + } - globals->get_tile_mgr()->update( aip.getSGLocation(), - visibility_meters, - (aip.getSGLocation())->get_absolute_view_pos( scenery_center ) ); - // save results of update in SGLocation for fdm... - - //if ( globals->get_scenery()->get_cur_elev() > -9990 ) { - // acmodel_location-> - // set_cur_elev_m( globals->get_scenery()->get_cur_elev() ); - //} - - // The need for this here means that at least 2 consecutive passes are needed :-( - aip.getSGLocation()->set_tile_center( globals->get_scenery()->get_next_center() ); - globals->get_tile_mgr()->prep_ssg_nodes( aip.getSGLocation(), visibility_meters ); - //Point3D scenery_center = globals->get_scenery()->get_center(); - - globals->get_tile_mgr()->update( aip.getSGLocation(), - visibility_meters, - (aip.getSGLocation())->get_absolute_view_pos( scenery_center ) ); - // save results of update in SGLocation for fdm... - - //if ( globals->get_scenery()->get_cur_elev() > -9990 ) { - // acmodel_location-> - // set_cur_elev_m( globals->get_scenery()->get_cur_elev() ); - //} - - // The need for this here means that at least 2 consecutive passes are needed :-( - aip.getSGLocation()->set_tile_center( globals->get_scenery()->get_next_center() ); - //cerr << "Transform Elev is " << globals->get_scenery()->get_cur_elev() << '\n'; - tgt_altitude = (globals->get_scenery()->get_cur_elev() * SG_METER_TO_FEET) + groundOffset; + // FIXME: make shure the pos.lat/pos.lon values are in degrees ... + double alt; + if (globals->get_scenery()->get_elevation_m(pos.lat(), pos.lon(), + 20000.0, alt)) + tgt_altitude = alt; } - -//globals->get_tile_mgr()->prep_ssg_nodes( _aip.getSGLocation(), visibility_meters ); -//Point3D scenery_center = globals->get_scenery()->get_center(); -//globals->get_tile_mgr()->update(_aip.getSGLocation(), visibility_meters, (_aip.getSGLocation())->get_absolute_view_pos( scenery_center ) ); -// save results of update in SGLocation for fdm... - -//if ( globals->get_scenery()->get_cur_elev() > -9990 ) { -// acmodel_location-> -// set_cur_elev_m( globals->get_scenery()->get_cur_elev() ); -//} - -// The need for this here means that at least 2 consecutive passes are needed :-( -//_aip.getSGLocation()->set_tile_center( globals->get_scenery()->get_next_center() ); - -//cout << "Transform Elev is " << globals->get_scenery()->get_cur_elev() << '\n'; -//_aip.getSGLocation()->set_cur_elev_m(globals->get_scenery()->get_cur_elev()); -//return(globals->get_scenery()->get_cur_elev()); -//} diff --git a/src/ATC/AILocalTraffic.cxx b/src/ATC/AILocalTraffic.cxx index c96a4661f..fe716d904 100644 --- a/src/ATC/AILocalTraffic.cxx +++ b/src/ATC/AILocalTraffic.cxx @@ -1580,24 +1580,19 @@ void FGAILocalTraffic::DoGroundElev() { _aip.getSGLocation()->set_cur_elev_m(aptElev); return; } - - - //globals->get_tile_mgr()->prep_ssg_nodes( acmodel_location, - globals->get_tile_mgr()->prep_ssg_nodes( _aip.getSGLocation(), visibility_meters ); - Point3D scenery_center = globals->get_scenery()->get_center(); - globals->get_tile_mgr()->update( _aip.getSGLocation(), visibility_meters, (_aip.getSGLocation())->get_absolute_view_pos( scenery_center ) ); - // save results of update in SGLocation for fdm... - - //if ( globals->get_scenery()->get_cur_elev() > -9990 ) { - // acmodel_location-> - // set_cur_elev_m( globals->get_scenery()->get_cur_elev() ); - //} - - // The need for this here means that at least 2 consecutive passes are needed :-( - _aip.getSGLocation()->set_tile_center( globals->get_scenery()->get_next_center() ); - - //cout << "Transform Elev is " << globals->get_scenery()->get_cur_elev() << '\n'; - _aip.getSGLocation()->set_cur_elev_m(globals->get_scenery()->get_cur_elev()); - //return(globals->get_scenery()->get_cur_elev()); + + // FIXME: make shure the pos.lat/pos.lon values are in degrees ... + double range = 500.0; + double lat = _aip.getSGLocation()->getLatitude_deg(); + double lon = _aip.getSGLocation()->getLongitude_deg(); + if (!globals->get_tile_mgr()->scenery_available(lat, lon, range)) { + // Try to shedule tiles for that position. + globals->get_tile_mgr()->update( _aip.getSGLocation(), range ); + } + + // FIXME: make shure the pos.lat/pos.lon values are in degrees ... + double alt; + if (globals->get_scenery()->get_elevation_m(lat, lon, 20000.0, alt)) + _aip.getSGLocation()->set_cur_elev_m(alt); } diff --git a/src/Cockpit/cockpit.cxx b/src/Cockpit/cockpit.cxx index 8b49ca916..ce8d5d897 100644 --- a/src/Cockpit/cockpit.cxx +++ b/src/Cockpit/cockpit.cxx @@ -207,10 +207,10 @@ float get_agl( void ) if ( !strcmp(startup_units_node->getStringValue(), "feet") ) { agl = (current_aircraft.fdm_state->get_Altitude() - - globals->get_scenery()->get_cur_elev() * SG_METER_TO_FEET); + - current_aircraft.fdm_state->get_Runway_altitude()); } else { - agl = (current_aircraft.fdm_state->get_Altitude() * SG_FEET_TO_METER - - globals->get_scenery()->get_cur_elev()); + agl = (current_aircraft.fdm_state->get_Altitude() + - current_aircraft.fdm_state->get_Runway_altitude()) * SG_FEET_TO_METER; } return agl; diff --git a/src/FDM/ExternalNet/ExternalNet.cxx b/src/FDM/ExternalNet/ExternalNet.cxx index 72578bd79..c00ce9d40 100644 --- a/src/FDM/ExternalNet/ExternalNet.cxx +++ b/src/FDM/ExternalNet/ExternalNet.cxx @@ -102,7 +102,7 @@ void FGExternalNet::init() { double lon = fgGetDouble( "/sim/presets/longitude-deg" ); double lat = fgGetDouble( "/sim/presets/latitude-deg" ); double alt = fgGetDouble( "/sim/presets/altitude-ft" ); - double ground = fgGetDouble( "/environment/ground-elevation-m" ); + double ground = get_Runway_altitude_m(); double heading = fgGetDouble("/sim/presets/heading-deg"); double speed = fgGetDouble( "/sim/presets/airspeed-kt" ); diff --git a/src/FDM/ExternalPipe/ExternalPipe.cxx b/src/FDM/ExternalPipe/ExternalPipe.cxx index 4cd13bc81..ddb044046 100644 --- a/src/FDM/ExternalPipe/ExternalPipe.cxx +++ b/src/FDM/ExternalPipe/ExternalPipe.cxx @@ -230,7 +230,7 @@ void FGExternalPipe::init_binary() { double lon = fgGetDouble( "/sim/presets/longitude-deg" ); double lat = fgGetDouble( "/sim/presets/latitude-deg" ); double alt = fgGetDouble( "/sim/presets/altitude-ft" ); - double ground = fgGetDouble( "/environment/ground-elevation-m" ); + double ground = get_Runway_altitude_m(); double heading = fgGetDouble("/sim/presets/heading-deg"); double speed = fgGetDouble( "/sim/presets/airspeed-kt" ); double weight = fgGetDouble( "/sim/aircraft-weight-lbs" ); @@ -293,7 +293,7 @@ void FGExternalPipe::init_property() { double lon = fgGetDouble( "/sim/presets/longitude-deg" ); double lat = fgGetDouble( "/sim/presets/latitude-deg" ); double alt = fgGetDouble( "/sim/presets/altitude-ft" ); - double ground = fgGetDouble( "/environment/ground-elevation-m" ); + double ground = get_Runway_altitude_m(); double heading = fgGetDouble("/sim/presets/heading-deg"); double speed = fgGetDouble( "/sim/presets/airspeed-kt" ); double weight = fgGetDouble( "/sim/aircraft-weight-lbs" ); diff --git a/src/FDM/SP/ADA.cxx b/src/FDM/SP/ADA.cxx index 11728b7bf..4ef0ea608 100644 --- a/src/FDM/SP/ADA.cxx +++ b/src/FDM/SP/ADA.cxx @@ -235,7 +235,7 @@ void FGADA::update( double dt ) { // Convert from the FGInterface struct to the FGADA struct (output) bool FGADA::copy_to_FGADA () { - ground_elevation = globals->get_scenery()->get_cur_elev(); + ground_elevation = get_Runway_altitude_m(); return true; } diff --git a/src/FDM/flight.cxx b/src/FDM/flight.cxx index cedeb29a7..9bda7929a 100644 --- a/src/FDM/flight.cxx +++ b/src/FDM/flight.cxx @@ -314,6 +314,8 @@ FGInterface::bind () fgSetArchivable("/position/ground-elev-m"); fgTie("/position/ground-elev-m", this, &FGInterface::get_Runway_altitude_m); // read-only + fgTie("/environment/ground-elevation-m", this, + &FGInterface::get_Runway_altitude_m); // read-only fgSetArchivable("/position/sea-level-radius-ft"); fgTie("/position/sea-level-radius-ft", this, &FGInterface::get_Sea_level_radius); // read-only @@ -452,6 +454,7 @@ FGInterface::unbind () fgUntie("/position/altitude-agl-ft"); fgUntie("/position/ground-elev-ft"); fgUntie("/position/ground-elev-m"); + fgUntie("/environment/ground-elevation-m"); fgUntie("/position/sea-level-radius-ft"); fgUntie("/orientation/roll-deg"); fgUntie("/orientation/pitch-deg"); diff --git a/src/Main/fg_init.cxx b/src/Main/fg_init.cxx index 2e2f653ac..66a0f327b 100644 --- a/src/Main/fg_init.cxx +++ b/src/Main/fg_init.cxx @@ -1607,10 +1607,6 @@ bool fgInitSubsystems() { &FGTileMgr::refresh_view_timestamps, 15 ); - SG_LOG( SG_GENERAL, SG_DEBUG, - "Current terrain elevation after tile mgr init " << - globals->get_scenery()->get_cur_elev() ); - //////////////////////////////////////////////////////////////////// // Initialize the flight model subsystem. diff --git a/src/Main/main.cxx b/src/Main/main.cxx index 7188ffa37..e3b2f22f9 100644 --- a/src/Main/main.cxx +++ b/src/Main/main.cxx @@ -139,15 +139,21 @@ void fgUpdateTimeDepCalcs() { // cout << "cur_fdm_state->get_inited() = " << cur_fdm_state->get_inited() // << " cur_elev = " << scenery.get_cur_elev() << endl; - if ( !cur_fdm_state->get_inited() && - globals->get_scenery()->get_cur_elev() > -9990 ) - { - SG_LOG(SG_FLIGHT,SG_INFO, "Finally initializing fdm"); + if (!cur_fdm_state->get_inited()) { + // Check for scenery around the aircraft. + double lon = fgGetDouble("/sim/presets/longitude-deg"); + double lat = fgGetDouble("/sim/presets/latitude-deg"); + // We require just to have 50 meter scenery availabe around + // the aircraft. + double range = 50.0; + if (globals->get_tile_mgr()->scenery_available(lat, lon, range)) { + SG_LOG(SG_FLIGHT,SG_INFO, "Finally initializing fdm"); 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 @@ -520,55 +526,39 @@ static void fgMainLoop( void ) { globals->get_scenery()->set_next_center( cntr ); } - // get the location data for the primary FDM (now hardcoded to ac model)... - SGLocation *acmodel_loc = NULL; - acmodel_loc = (SGLocation *)globals-> - get_aircraft_model()->get3DModel()->getSGLocation(); - - // update tile manager for FDM... - // ...only if location is different than the current-view location - // (to avoid duplicating effort) - if( !fgGetBool("/sim/current-view/config/from-model") ) { - if( acmodel_loc != NULL ) { - globals->get_tile_mgr()->prep_ssg_nodes( acmodel_loc, - visibility_meters ); - globals->get_tile_mgr()-> - update( acmodel_loc, visibility_meters, - acmodel_loc-> - get_absolute_view_pos(globals-> - get_scenery()->get_center()) ); - globals->get_scenery()->set_center( cntr ); - - // save results of update in SGLocation for fdm... - if ( globals->get_scenery()->get_cur_elev() > -9990 ) { - acmodel_loc-> - set_cur_elev_m( globals->get_scenery()->get_cur_elev() ); - fgSetDouble("/position/ground-elev-m", - globals->get_scenery()->get_cur_elev()); - } - acmodel_loc-> - set_tile_center( globals->get_scenery()->get_next_center() ); - } - } - globals->get_tile_mgr()->prep_ssg_nodes( current_view->getSGLocation(), visibility_meters ); // update tile manager for view... - // IMPORTANT!!! the tilemgr update for view location _must_ be - // done last after the FDM's until all of Flight Gear code - // references the viewer's location for elevation instead of the - // "scenery's" current elevation. SGLocation *view_location = globals->get_current_view()->getSGLocation(); - globals->get_tile_mgr()->update( view_location, visibility_meters, - current_view->get_absolute_view_pos() ); + globals->get_tile_mgr()->update( view_location, visibility_meters ); globals->get_scenery()->set_center( cntr ); - // save results of update in SGLocation for fdm... - if ( globals->get_scenery()->get_cur_elev() > -9990 ) { - current_view->getSGLocation()-> - set_cur_elev_m( globals->get_scenery()->get_cur_elev() ); + { + double lon = view_location->getLongitude_deg(); + double lat = view_location->getLatitude_deg(); + double alt = view_location->getAltitudeASL_ft() * SG_FEET_TO_METER; + + // check if we can reuse the groundcache for that purpose. + double ref_time, pt[3], r; + bool valid = cur_fdm_state->is_valid_m(&ref_time, pt, &r); + if (valid && + cntr.distance3Dsquared(Point3D(pt[0], pt[1], pt[2])) < r*r) { + // Reuse the cache ... + double lev + = cur_fdm_state->get_groundlevel_m(lat*SGD_DEGREES_TO_RADIANS, + lon*SGD_DEGREES_TO_RADIANS, + alt + 2.0); + view_location->set_cur_elev_m( lev ); + } else { + // Do full intersection test. + double lev; + if (globals->get_scenery()->get_elevation_m(lat, lon, alt+2, lev)) + view_location->set_cur_elev_m( lev ); + else + view_location->set_cur_elev_m( -9999.0 ); + } } - current_view->getSGLocation()-> - set_tile_center( globals->get_scenery()->get_next_center() ); + + view_location->set_tile_center( globals->get_scenery()->get_next_center() ); #ifdef ENABLE_AUDIO_SUPPORT // Right now we make a simplifying assumption that the primary @@ -577,6 +567,11 @@ static void fgMainLoop( void ) { static sgVec3 last_pos_offset; + // get the location data for the primary FDM (now hardcoded to ac model)... + SGLocation *acmodel_loc = NULL; + acmodel_loc = (SGLocation *)globals-> + get_aircraft_model()->get3DModel()->getSGLocation(); + // set positional offset for sources sgVec3 source_pos_offset; sgSubVec3( source_pos_offset, @@ -600,22 +595,6 @@ static void fgMainLoop( void ) { globals->get_soundmgr()->set_listener_pos( listener_pos ); #endif - // If fdm location is same as viewer's then we didn't do the - // update for fdm location above so we need to save the viewer - // results in the fdm SGLocation as well... - if( fgGetBool("/sim/current-view/config/from-model") ) { - if( acmodel_loc != 0 ) { - if ( globals->get_scenery()->get_cur_elev() > -9990 ) { - acmodel_loc->set_cur_elev_m( globals->get_scenery()-> - get_cur_elev() ); - fgSetDouble("/position/ground-elev-m", - globals->get_scenery()->get_cur_elev()); - } - acmodel_loc->set_tile_center( globals->get_scenery()-> - get_next_center() ); - } - } - // END Tile Manager udpates if (!scenery_loaded && globals->get_tile_mgr()->all_queues_empty() && cur_fdm_state->get_inited()) { diff --git a/src/Main/renderer.cxx b/src/Main/renderer.cxx index 05b85037b..cfa716fb4 100644 --- a/src/Main/renderer.cxx +++ b/src/Main/renderer.cxx @@ -489,9 +489,9 @@ FGRenderer::update( bool refresh_camera_settings ) { double agl = current_aircraft.fdm_state->get_Altitude() * SG_FEET_TO_METER - - globals->get_scenery()->get_cur_elev(); + - cur_fdm_state->get_Runway_altitude_m(); - if ( agl > 50.0 ) { + if ( agl > 10.0 ) { scene_nearplane = 10.0f; scene_farplane = 120000.0f; } else { diff --git a/src/Network/native_fdm.cxx b/src/Network/native_fdm.cxx index e2b6a69ae..88ac0ffa9 100644 --- a/src/Network/native_fdm.cxx +++ b/src/Network/native_fdm.cxx @@ -383,8 +383,8 @@ void FGNetFDM2Props( FGNetFDM *net, bool net_byte_order ) { if ( net->agl > -9000 ) { cur_fdm_state->_set_Altitude_AGL( net->agl * SG_METER_TO_FEET ); } else { - double agl_m - = net->altitude - globals->get_scenery()->get_cur_elev(); + double agl_m = net->altitude + - cur_fdm_state->get_Runway_altitude_m(); cur_fdm_state->_set_Altitude_AGL( agl_m * SG_METER_TO_FEET ); } cur_fdm_state->_set_Euler_Angles( net->phi, diff --git a/src/Network/native_gui.cxx b/src/Network/native_gui.cxx index b9d3ce489..2047a0aef 100644 --- a/src/Network/native_gui.cxx +++ b/src/Network/native_gui.cxx @@ -163,7 +163,7 @@ void FGProps2NetGUI( FGNetGUI *net ) { // Environment net->cur_time = globals->get_time_params()->get_cur_time(); net->warp = globals->get_warp(); - net->ground_elev = globals->get_scenery()->get_cur_elev(); + net->ground_elev = cur_fdm_state->get_Runway_altitude_m(); // Approach net->tuned_freq = nav_freq->getDoubleValue(); @@ -304,7 +304,6 @@ void FGNetGUI2Props( FGNetGUI *net ) { } globals->set_warp( net->warp ); - globals->get_scenery()->set_cur_elev( net->ground_elev ); // Approach fgSetDouble( "/instrumentation/nav[0]/frequencies/selected-mhz", diff --git a/src/Scenery/scenery.cxx b/src/Scenery/scenery.cxx index 8e0f361c1..88badf93e 100644 --- a/src/Scenery/scenery.cxx +++ b/src/Scenery/scenery.cxx @@ -30,10 +30,12 @@ #include #include +#include #include #include
+#include "hitlist.hxx" #include "scenery.hxx" @@ -42,7 +44,6 @@ FGScenery::FGScenery() { SG_LOG( SG_TERRAIN, SG_INFO, "Initializing scenery subsystem" ); center = Point3D(0.0); - cur_elev = -9999; } @@ -93,13 +94,10 @@ void FGScenery::update(double dt) { 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"); } void FGScenery::set_center( Point3D p ) { @@ -131,3 +129,60 @@ void FGScenery::unregister_placement_transform(ssgPlacementTransform *trans) { ++it; } } + +bool +FGScenery::get_elevation_m(double lat, double lon, double max_alt, + double& alt, bool exact) +{ +// std::cout << __PRETTY_FUNCTION__ << " " +// << lat << " " +// << lon << " " +// << max_alt +// << std::endl; + sgdVec3 pos; + sgGeodToCart(lat*SG_DEGREES_TO_RADIANS, lon*SG_DEGREES_TO_RADIANS, + max_alt, pos); + return get_cart_elevation_m(pos, 0, alt, exact); +} + +bool +FGScenery::get_cart_elevation_m(const sgdVec3 pos, double max_altoff, + double& alt, bool exact) +{ + Point3D saved_center = center; + bool replaced_center = false; + if (exact) { + Point3D ppos(pos[0], pos[1], pos[2]); + if (30.0*30.0 < ppos.distance3Dsquared(center)) { + set_center( ppos ); + replaced_center = false; + } + } + + // overridden with actual values if a terrain intersection is + // found + double hit_radius = 0.0; + sgdVec3 hit_normal = { 0.0, 0.0, 0.0 }; + + bool hit = false; + if ( fabs(pos[0]) > 1.0 || fabs(pos[1]) > 1.0 || fabs(pos[2]) > 1.0 ) { + sgdVec3 sc; + sgdSetVec3(sc, center[0], center[1], center[2]); + + sgdVec3 ncpos; + sgdCopyVec3(ncpos, pos); + + FGHitList hit_list; + + // scenery center has been properly defined so any hit should + // be valid (and not just luck) + hit = fgCurrentElev(ncpos, max_altoff+sgdLengthVec3(pos), + sc, (ssgTransform*)get_scene_graph(), + &hit_list, &alt, &hit_radius, hit_normal); + } + + if (replaced_center) + set_center( saved_center ); + + return hit; +} diff --git a/src/Scenery/scenery.hxx b/src/Scenery/scenery.hxx index d96660cee..847f2e3a4 100644 --- a/src/Scenery/scenery.hxx +++ b/src/Scenery/scenery.hxx @@ -52,20 +52,10 @@ class FGScenery : public SGSubsystem { // next center of current scenery chunk Point3D next_center; + // FIXME this should be a views property // angle of sun relative to current local horizontal double sun_angle; - // elevation of terrain at our current lat/lon (based on the - // actual drawn polygons) - double cur_elev; - - // the distance (radius) from the center of the earth to the - // current scenery elevation point - double cur_radius; - - // unit normal at point used to determine current elevation - sgdVec3 cur_normal; - // SSG scene graph ssgRoot *scene_graph; ssgBranch *terrain_branch; @@ -91,8 +81,32 @@ public: void unbind (); void update (double dt); - inline double get_cur_elev() const { return cur_elev; } - inline void set_cur_elev( double e ) { cur_elev = e; } + /// Compute the elevation of the scenery at geodetic latitude lat, + /// geodetic longitude lon and not higher than max_alt. + /// If the exact flag is set to true, the scenery center is moved to + /// gain a higher accuracy of that query. The center is restored past + /// that to the original value. + /// The altitude hit is returned in the alt argument. + /// The method returns true if the scenery is available for the given + /// lat/lon pair. If there is no scenery for that point, the altitude + /// value is undefined. + /// All values are meant to be in meters or degrees. + bool get_elevation_m(double lat, double lon, double max_alt, + double& alt, bool exact = false); + + /// Compute the elevation of the scenery beow the cartesian point pos. + /// you the returned scenery altitude is not higher than the position + /// pos plus an ofset given with max_altoff. + /// If the exact flag is set to true, the scenery center is moved to + /// gain a higher accuracy of that query. The center is restored past + /// that to the original value. + /// The altitude hit is returned in the alt argument. + /// The method returns true if the scenery is available for the given + /// lat/lon pair. If there is no scenery for that point, the altitude + /// value is undefined. + /// All values are meant to be in meters. + bool get_cart_elevation_m(const sgdVec3 pos, double max_altoff, + double& radius, bool exact = false); inline Point3D get_center() const { return center; } void set_center( Point3D p ); @@ -100,9 +114,6 @@ public: 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 ); } - inline ssgRoot *get_scene_graph () const { return scene_graph; } inline void set_scene_graph (ssgRoot * s) { scene_graph = s; } diff --git a/src/Scenery/tileentry.cxx b/src/Scenery/tileentry.cxx index d3b900071..b0639d588 100644 --- a/src/Scenery/tileentry.cxx +++ b/src/Scenery/tileentry.cxx @@ -343,8 +343,8 @@ void FGTileEntry::prep_ssg_node( const Point3D& p, sgVec3 up, float vis) { sgCopyVec3( lift_vec, up ); double agl; - agl = globals->get_current_view()->getAltitudeASL_ft() - * SG_FEET_TO_METER - globals->get_scenery()->get_cur_elev(); + agl = globals->get_current_view()->getAltitudeASL_ft()*SG_FEET_TO_METER + - globals->get_current_view()->getSGLocation()->get_cur_elev_m(); // Compute the distance of the scenery center from the view position. double dist = center.distance3D(p); @@ -386,9 +386,9 @@ void FGTileEntry::prep_ssg_node( const Point3D& p, sgVec3 up, float vis) { // we fudge agl by 30 meters so that the lifting function // doesn't phase in until we are > 30m agl. double agl; - agl = globals->get_current_view()->getAltitudeASL_ft() - * SG_FEET_TO_METER - globals->get_scenery()->get_cur_elev() - - 30.0; + agl = globals->get_current_view()->getAltitudeASL_ft()*SG_FEET_TO_METER + - globals->get_current_view()->getSGLocation()->get_cur_elev_m() + - 30.0; if ( agl < 0.0 ) { agl = 0.0; } @@ -421,9 +421,9 @@ void FGTileEntry::prep_ssg_node( const Point3D& p, sgVec3 up, float vis) { // we fudge agl by 30 meters so that the lifting function // doesn't phase in until we are > 30m agl. double agl; - agl = globals->get_current_view()->getAltitudeASL_ft() - * SG_FEET_TO_METER - globals->get_scenery()->get_cur_elev() - - 30.0; + agl = globals->get_current_view()->getAltitudeASL_ft()*SG_FEET_TO_METER + - globals->get_current_view()->getSGLocation()->get_cur_elev_m() + - 30.0; if ( agl < 0.0 ) { agl = 0.0; } @@ -462,9 +462,9 @@ void FGTileEntry::prep_ssg_node( const Point3D& p, sgVec3 up, float vis) { // we fudge agl by 30 meters so that the lifting function // doesn't phase in until we are > 30m agl. double agl; - agl = globals->get_current_view()->getAltitudeASL_ft() - * SG_FEET_TO_METER - globals->get_scenery()->get_cur_elev() - - 30.0; + agl = globals->get_current_view()->getAltitudeASL_ft()*SG_FEET_TO_METER + - globals->get_current_view()->getSGLocation()->get_cur_elev_m() + - 30.0; if ( agl < 0.0 ) { agl = 0.0; } diff --git a/src/Scenery/tilemgr.cxx b/src/Scenery/tilemgr.cxx index 1cd496edd..9b28c8894 100644 --- a/src/Scenery/tilemgr.cxx +++ b/src/Scenery/tilemgr.cxx @@ -333,8 +333,6 @@ void FGTileMgr::update_queues() } } - // cout << "current elevation (ssg) == " << scenery.get_cur_elev() << endl; - // Notify the tile loader that it can load another tile loader.update(); @@ -386,15 +384,11 @@ void FGTileMgr::update_queues() int FGTileMgr::update( double visibility_meters ) { SGLocation *location = globals->get_current_view()->getSGLocation(); - sgdVec3 abs_pos_vector; - sgdCopyVec3( abs_pos_vector, - globals->get_current_view()->get_absolute_view_pos() ); - return update( location, visibility_meters, abs_pos_vector ); + return update( location, visibility_meters ); } -int FGTileMgr::update( SGLocation *location, double visibility_meters, - sgdVec3 abs_pos_vector ) +int FGTileMgr::update( SGLocation *location, double visibility_meters ) { SG_LOG( SG_TERRAIN, SG_DEBUG, "FGTileMgr::update()" ); @@ -442,9 +436,6 @@ int FGTileMgr::update( SGLocation *location, double visibility_meters, // save bucket... previous_bucket = current_bucket; - updateCurrentElevAtPos( abs_pos_vector, altitude_m, - location->get_tile_center() ); - return 1; } @@ -461,52 +452,6 @@ void FGTileMgr::refresh_view_timestamps() { } } - -int FGTileMgr::updateCurrentElevAtPos( sgdVec3 abs_pos_vector, - double max_alt_m, - Point3D center) -{ - sgdVec3 sc; - - sgdSetVec3( sc, center[0], center[1], center[2]); - - // overridden with actual values if a terrain intersection is - // found - double hit_elev = -9999.0; - double hit_radius = 0.0; - sgdVec3 hit_normal = { 0.0, 0.0, 0.0 }; - - bool hit = false; - if ( fabs(sc[0]) > 1.0 || fabs(sc[1]) > 1.0 || fabs(sc[2]) > 1.0 ) { - // scenery center has been properly defined so any hit should - // be valid (and not just luck) - hit = fgCurrentElev(abs_pos_vector, - max_alt_m, - sc, - // uncomment next paramater to fly under - // bridges and a slightly faster algorithm - // but you won't be able to land on aircraft carriers - // current_tile->get_terra_transform(), - &hit_list, - &hit_elev, - &hit_radius, - hit_normal); - } - - if ( hit ) { - // cout << "elev = " << hit_elev << " " << hit_radius << endl; - globals->get_scenery()->set_cur_elev( hit_elev ); - globals->get_scenery()->set_cur_radius( hit_radius ); - globals->get_scenery()->set_cur_normal( hit_normal ); - } else { - globals->get_scenery()->set_cur_elev( -9999.0 ); - globals->get_scenery()->set_cur_radius( 0.0 ); - globals->get_scenery()->set_cur_normal( hit_normal ); - } - return hit; -} - - void FGTileMgr::prep_ssg_nodes( SGLocation *location, float vis ) { // traverse the potentially viewable tile list and update range @@ -541,3 +486,38 @@ int FGTileMgr::tile_filter_cb( ssgEntity *, int ) { return tile_filter ? 1 : 0; } + +bool FGTileMgr::scenery_available(double lat, double lon, double range_m) +{ + // sanity check (unfortunately needed!) + if ( lon < -180.0 || lon > 180.0 || lat < -90.0 || lat > 90.0 ) + return false; + + SGBucket bucket(lon, lat); + FGTileEntry *te = tile_cache.get_tile(bucket); + if (!te || !te->is_loaded()) + return false; + + // Traverse all tiles required to be there for the given visibility. + // This uses exactly the same algorithm like the tile scheduler. + double tile_width = bucket.get_width_m(); + double tile_height = bucket.get_height_m(); + + int xrange = (int)fabs(range_m / tile_width) + 1; + int yrange = (int)fabs(range_m / tile_height) + 1; + + for ( int x = -xrange; x <= xrange; ++x ) { + for ( int y = -yrange; y <= yrange; ++y ) { + // We have already checked for the center tile. + if ( x != 0 || y != 0 ) { + SGBucket b = sgBucketOffset( lon, lat, x, y ); + FGTileEntry *te = tile_cache.get_tile(b); + if (!te || !te->is_loaded()) + return false; + } + } + } + + // Survived all tests. + return true; +} diff --git a/src/Scenery/tilemgr.hxx b/src/Scenery/tilemgr.hxx index 6e4b30f34..a487264da 100644 --- a/src/Scenery/tilemgr.hxx +++ b/src/Scenery/tilemgr.hxx @@ -166,22 +166,7 @@ public: // local chunks. If the chunk isn't already in the cache, then // read it from disk. int update( double visibility_meters ); - int update( SGLocation *location, double visibility_meters, - sgdVec3 abs_pos_vector ); - - int updateCurrentElevAtPos( sgdVec3 abs_pos_vector, double altitude_m, - Point3D center ); - - // Determine scenery altitude. Normally this just happens when we - // render the scene, but we'd also like to be able to do this - // explicitely. lat & lon are in radians. abs_view_pos in - // meters. Returns result in meters. - void my_ssg_los( string s, ssgBranch *branch, sgdMat4 m, - const sgdVec3 p, const sgdVec3 dir, sgdVec3 normal ); - - void my_ssg_los( ssgBranch *branch, sgdMat4 m, - const sgdVec3 p, const sgdVec3 dir, - FGHitList *list ); + int update( SGLocation *location, double visibility_meters); // Prepare the ssg nodes corresponding to each tile. For each // tile, set the ssg transform and update it's range selector @@ -198,6 +183,11 @@ public: static bool set_tile_filter( bool f ); static int tile_filter_cb( ssgEntity *, int ); + + /// Returns true if scenery is avaliable for the given lat, lon position + /// within a range of range_m. + /// lat and lon are expected to be in degrees. + bool scenery_available(double lat, double lon, double range_m); };