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() );
- 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;
-}
-
-//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() );
+ // 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 );
+ }
-//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 alt;
+ if (globals->get_scenery()->get_elevation_m(pos.lat(), pos.lon(),
+ 20000.0, alt))
+ tgt_altitude = alt;
+}
_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);
}
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;
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 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" );
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" );
// 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;
}
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
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");
&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.
// 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
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
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,
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()) {
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 {
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,
// 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();
}
globals->set_warp( net->warp );
- globals->get_scenery()->set_cur_elev( net->ground_elev );
// Approach
fgSetDouble( "/instrumentation/nav[0]/frequencies/selected-mhz",
#include <simgear/debug/logstream.hxx>
#include <simgear/scene/tgdb/userdata.hxx>
+#include <simgear/math/sg_geodesy.hxx>
#include <simgear/scene/model/placementtrans.hxx>
#include <Main/fg_props.hxx>
+#include "hitlist.hxx"
#include "scenery.hxx"
SG_LOG( SG_TERRAIN, SG_INFO, "Initializing scenery subsystem" );
center = Point3D(0.0);
- cur_elev = -9999;
}
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 ) {
++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;
+}
// 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;
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 );
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; }
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);
// 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;
}
// 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;
}
// 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;
}
}
}
- // cout << "current elevation (ssg) == " << scenery.get_cur_elev() << endl;
-
// Notify the tile loader that it can load another tile
loader.update();
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()" );
// save bucket...
previous_bucket = current_bucket;
- updateCurrentElevAtPos( abs_pos_vector, altitude_m,
- location->get_tile_center() );
-
return 1;
}
}
}
-
-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
{
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;
+}
// 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
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);
};