From: frohlich Date: Thu, 12 Mar 2009 06:21:35 +0000 (+0000) Subject: Improove FGTileMgr::scenery_available for small ranges. X-Git-Url: https://git.mxchange.org/?a=commitdiff_plain;h=7e73a8788223c9c2af3c26435162e0667b412279;p=flightgear.git Improove FGTileMgr::scenery_available for small ranges. Use SGGeod in FGTileMgr, FGScenery apis. Modified Files: src/AIModel/AIBallistic.cxx src/Main/main.cxx src/Scenery/scenery.cxx src/Scenery/scenery.hxx src/Scenery/tilemgr.cxx src/Scenery/tilemgr.hxx src/Scripting/NasalSys.cxx --- diff --git a/src/AIModel/AIBallistic.cxx b/src/AIModel/AIBallistic.cxx index 8ad900bdb..5b9a6f5da 100644 --- a/src/AIModel/AIBallistic.cxx +++ b/src/AIModel/AIBallistic.cxx @@ -433,8 +433,8 @@ void FGAIBallistic::setForcePath(const string& p) { bool FGAIBallistic::getHtAGL(){ - if (globals->get_scenery()->get_elevation_m(pos.getLatitudeDeg(), pos.getLongitudeDeg(), - 10000.0, _elevation_m, &_material)){ + if (globals->get_scenery()->get_elevation_m(SGGeod::fromGeodM(pos, 10000), + _elevation_m, &_material)){ _ht_agl_ft = pos.getElevationFt() - _elevation_m * SG_METER_TO_FEET; if (_material) { const vector& names = _material->get_names(); diff --git a/src/Main/main.cxx b/src/Main/main.cxx index c0251b13f..634bda309 100644 --- a/src/Main/main.cxx +++ b/src/Main/main.cxx @@ -137,7 +137,8 @@ void fgUpdateTimeDepCalcs() { // We require just to have 50 meter scenery availabe around // the aircraft. double range = 1000.0; - if (globals->get_scenery()->scenery_available(lat, lon, range)) { + SGGeod geod = SGGeod::fromDeg(lon, lat); + if (globals->get_scenery()->scenery_available(geod, range)) { //SG_LOG(SG_FLIGHT, SG_INFO, "Finally initializing fdm"); cur_fdm_state->init(); if ( cur_fdm_state->get_bound() ) { diff --git a/src/Scenery/scenery.cxx b/src/Scenery/scenery.cxx index 13cc67ffc..b9b77ca25 100644 --- a/src/Scenery/scenery.cxx +++ b/src/Scenery/scenery.cxx @@ -117,13 +117,6 @@ void FGScenery::bind() { void FGScenery::unbind() { } -bool -FGScenery::get_elevation_m(double lat, double lon, double max_alt, - double& alt, const SGMaterial** material) -{ - return get_elevation_m(SGGeod::fromDegM(lon, lat, max_alt), alt, material); -} - bool FGScenery::get_cart_elevation_m(const SGVec3d& pos, double max_altoff, double& alt, const SGMaterial** material) @@ -212,13 +205,13 @@ FGScenery::get_cart_ground_intersection(const SGVec3d& pos, const SGVec3d& dir, return hits; } -bool FGScenery::scenery_available(double lat, double lon, double range_m) +bool FGScenery::scenery_available(const SGGeod& position, double range_m) { - if(globals->get_tile_mgr()->scenery_available(lat, lon, range_m)) + if(globals->get_tile_mgr()->scenery_available(position, range_m)) { double elev; - get_elevation_m(lat, lon, SG_MAX_ELEVATION_M, elev, 0); - SGVec3f p = SGVec3f::fromGeod(SGGeod::fromDegM(lon,lat,elev)); + get_elevation_m(SGGeod::fromGeodM(position, SG_MAX_ELEVATION_M), elev, 0); + SGVec3f p = SGVec3f::fromGeod(SGGeod::fromGeodM(position, elev)); simgear::CheckSceneryVisitor csnv(getPagerSingleton(), p.osg(), range_m); // currently the PagedLODs will not be loaded by the DatabasePager // while the splashscreen is there, so CheckSceneryVisitor force-loads diff --git a/src/Scenery/scenery.hxx b/src/Scenery/scenery.hxx index 0fdd9cd89..bc8b4f710 100644 --- a/src/Scenery/scenery.hxx +++ b/src/Scenery/scenery.hxx @@ -70,8 +70,6 @@ public: /// 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, const SGMaterial** material); bool get_elevation_m(const SGGeod& geod, double& alt, const SGMaterial** material); @@ -87,7 +85,7 @@ public: /// value is undefined. /// All values are meant to be in meters. bool get_cart_elevation_m(const SGVec3d& pos, double max_altoff, - double& radius, const SGMaterial** material); + double& elevation, const SGMaterial** material); /// Compute the nearest intersection point of the line starting from /// start going in direction dir with the terrain. @@ -105,7 +103,7 @@ public: /// 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); + bool scenery_available(const SGGeod& position, double range_m); // Static because access to the pager is needed before the rest of // the scenery is initialized. diff --git a/src/Scenery/tilemgr.cxx b/src/Scenery/tilemgr.cxx index 6066ebd0a..26c92bb89 100644 --- a/src/Scenery/tilemgr.cxx +++ b/src/Scenery/tilemgr.cxx @@ -383,26 +383,26 @@ void FGTileMgr::prep_ssg_nodes(float vis) { } bool FGTileMgr::scenery_available(const SGGeod& position, double range_m) -{ - return scenery_available(position.getLatitudeDeg(), - position.getLongitudeDeg(), range_m); -} - -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 ) + if (position.getLongitudeDeg() < -180 || position.getLongitudeDeg() > 180 || + position.getLatitudeDeg() < -90 || position.getLatitudeDeg() > 90) return false; - SGBucket bucket(lon, lat); + SGBucket bucket(position); TileEntry *te = tile_cache.get_tile(bucket); if (!te || !te->is_loaded()) return false; + SGVec3d cartPos = SGVec3d::fromGeod(position); + // 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(); + double tile_r = 0.5*sqrt(tile_width*tile_width + tile_height*tile_height); + double max_dist = tile_r + range_m; + double max_dist2 = max_dist*max_dist; int xrange = (int)fabs(range_m / tile_width) + 1; int yrange = (int)fabs(range_m / tile_height) + 1; @@ -411,7 +411,11 @@ bool FGTileMgr::scenery_available(double lat, double lon, double range_m) 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 ); + SGBucket b = sgBucketOffset( position.getLongitudeDeg(), + position.getLatitudeDeg(), x, y ); + // Do not ask if it is just the next tile but way out of range. + if (max_dist2 < distSqr(cartPos, SGVec3d::fromGeod(b.get_center()))) + continue; TileEntry *te = tile_cache.get_tile(b); if (!te || !te->is_loaded()) return false; diff --git a/src/Scenery/tilemgr.hxx b/src/Scenery/tilemgr.hxx index e7ee84944..6b415e53b 100644 --- a/src/Scenery/tilemgr.hxx +++ b/src/Scenery/tilemgr.hxx @@ -106,7 +106,6 @@ public: /// 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); bool scenery_available(const SGGeod& position, double range_m); // Load a model for a tile diff --git a/src/Scripting/NasalSys.cxx b/src/Scripting/NasalSys.cxx index 528d07bd0..1085cc270 100644 --- a/src/Scripting/NasalSys.cxx +++ b/src/Scripting/NasalSys.cxx @@ -471,7 +471,8 @@ static naRef f_geodinfo(naContext c, naRef me, int argc, naRef* args) double lon = naNumValue(args[1]).num; double elev; const SGMaterial *mat; - if(!globals->get_scenery()->get_elevation_m(lat, lon, 10000.0, elev, &mat)) + SGGeod geod = SGGeod::fromDegM(lon, lat, 10000); + if(!globals->get_scenery()->get_elevation_m(geod, elev, &mat)) return naNil(); naRef vec = naNewVector(c); naVec_append(vec, naNum(elev));