1
0
Fork 0

Mathias Frhlich:

I have prepared a patch that:
- Introduces a FGTileMgr::scenery_available method which asks the tilemanager
  if scenery for a given range around a lat/lon pair is already loaded and make
  use of that method at some -9999 meter checks.
- Introduces a FGScenery::get_elevation_m method which queries the altitude at
  a given position. In constrast to the groundcache functions this is the best
  choice if you ask for one *single* altitude value. Make use of that thing in
  AI/ATC classes and for the current views ground level. At the current views
  part the groundcache is reused if possible.
- The computation of the 'current groundlevel' is no longer done on the
  tilemanagers update since the required functions are now better seperated.

Alltogether it eliminates somehow redundant terrain level computations which
are now superseeded by that more finegrained functions and the existence of
the groundcache. Additionally it introduces an api to commonly required
functions which was very complex to do prevously.
This commit is contained in:
ehofman 2005-08-14 12:57:12 +00:00
parent 397a15c829
commit 7b824755ee
17 changed files with 223 additions and 254 deletions

View file

@ -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());
//}

View file

@ -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);
}

View file

@ -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;

View file

@ -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" );

View file

@ -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" );

View file

@ -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;
}

View file

@ -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");

View file

@ -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.

View file

@ -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()) {

View file

@ -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 {

View file

@ -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,

View file

@ -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",

View file

@ -30,10 +30,12 @@
#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"
@ -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;
}

View file

@ -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; }

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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);
};