Mathias FROEHLICH:
remove a hack and do it properly: if the requested elevation is for some reason below the surface and the intersection test fails (as it appears to be the case in EGLL), try again from 10000m ASL mf: typos
This commit is contained in:
parent
72f46a4a6f
commit
435d874e35
2 changed files with 46 additions and 18 deletions
|
@ -196,6 +196,10 @@ FGInterface::common_init ()
|
|||
double alt_m = alt_ft * SG_FEET_TO_METER;
|
||||
set_Longitude( lon );
|
||||
set_Latitude( lat );
|
||||
SG_LOG( SG_FLIGHT, SG_INFO, "Checking for lon = "
|
||||
<< lon*SGD_RADIANS_TO_DEGREES << "deg, lat = "
|
||||
<< lat*SGD_RADIANS_TO_DEGREES << "deg, alt = "
|
||||
<< alt_ft << "ft");
|
||||
|
||||
double ground_elev_m = get_groundlevel_m(lat, lon, alt_m);
|
||||
double ground_elev_ft = ground_elev_m * SG_METER_TO_FEET;
|
||||
|
@ -894,26 +898,50 @@ FGInterface::get_agl_ft(double t, const double pt[3], double max_altoff,
|
|||
double
|
||||
FGInterface::get_groundlevel_m(double lat, double lon, double alt)
|
||||
{
|
||||
// First compute the sea level radius,
|
||||
sgdVec3 pos, cpos;
|
||||
sgGeodToCart(lat, lon, 0, pos);
|
||||
double slr = sgdLengthVec3(pos);
|
||||
// .. then the cartesian position of the given lat/lon/alt.
|
||||
// Compute the cartesian position of the given lat/lon/alt.
|
||||
sgGeodToCart(lat, lon, alt, pos);
|
||||
|
||||
// FIXME: how to handle t - ref_time differences ???
|
||||
double ref_time, radius;
|
||||
// Prepare the ground cache for that position.
|
||||
if (!is_valid_m(&ref_time, cpos, &radius))
|
||||
prepare_ground_cache_m(ref_time, pos, 10);
|
||||
else if (radius*radius <= sgdDistanceSquaredVec3(pos, cpos))
|
||||
prepare_ground_cache_m(ref_time, pos, radius);
|
||||
if (!is_valid_m(&ref_time, cpos, &radius)) {
|
||||
bool ok = prepare_ground_cache_m(ref_time, pos, 10);
|
||||
/// This is most likely the case when the given altitude is
|
||||
/// too low, try with a new altitude of 10000m, that should be
|
||||
/// sufficient to find a ground level below everywhere on our planet
|
||||
if (!ok) {
|
||||
sgGeodToCart(lat, lon, 10000, pos);
|
||||
/// If there is still no ground, return sea level radius
|
||||
if (!prepare_ground_cache_m(ref_time, pos, 10))
|
||||
return 0;
|
||||
}
|
||||
} else if (radius*radius <= sgdDistanceSquaredVec3(pos, cpos)) {
|
||||
/// We reuse the old radius value, but only if it is at least 10 Meters ..
|
||||
if (!(10 < radius)) // Well this strange compare is nan safe
|
||||
radius = 10;
|
||||
|
||||
bool ok = prepare_ground_cache_m(ref_time, pos, radius);
|
||||
/// This is most likely the case when the given altitude is
|
||||
/// too low, try with a new altitude of 10000m, that should be
|
||||
/// sufficient to find a ground level below everywhere on our planet
|
||||
if (!ok) {
|
||||
sgGeodToCart(lat, lon, 10000, pos);
|
||||
/// If there is still no ground, return sea level radius
|
||||
if (!prepare_ground_cache_m(ref_time, pos, radius))
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
double contact[3], normal[3], vel[3], lc, ff, agl;
|
||||
int type;
|
||||
// Ignore the return value here, since it just tells us if
|
||||
// the returns stem from the groundcache or from the coarse
|
||||
// computations below the groundcache. The contact point is still something
|
||||
// valid, the normals and the other returns just contain some defaults.
|
||||
get_agl_m(ref_time, pos, 2.0, contact, normal, vel, &type, &lc, &ff, &agl);
|
||||
|
||||
return sgdLengthVec3(contact) - slr;
|
||||
Point3D geodPos = sgCartToGeod(Point3D(contact[0], contact[1], contact[2]));
|
||||
return geodPos.elev();
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
@ -202,7 +202,7 @@ FGGroundCache::extractGroundProperty( ssgLeaf* l )
|
|||
{
|
||||
// FIXME: Do more ...
|
||||
// Idea: have a get_globals() function which knows about that stuff.
|
||||
// Or most propably read that from a configuration file,
|
||||
// Or most probably read that from a configuration file,
|
||||
// from property tree or whatever ...
|
||||
|
||||
// Get ground dependent data.
|
||||
|
@ -361,7 +361,7 @@ FGGroundCache::putSurfaceLeafIntoCache(const sgdSphere *sp,
|
|||
sgdSubVec3(off, isectpoint, tmp);
|
||||
// Only accept the altitude if the intersection point is below the
|
||||
// ground cache midpoint
|
||||
if (0 < sgdScalarProductVec3( off, down ) || !found_ground) {
|
||||
if (0 < sgdScalarProductVec3( off, down )) {
|
||||
found_ground = true;
|
||||
sgdAddVec3(isectpoint, cache_center);
|
||||
double this_radius = sgdLengthVec3(isectpoint);
|
||||
|
@ -441,7 +441,7 @@ FGGroundCache::cache_fill(ssgBranch *branch, sgdMat4 xform,
|
|||
if ( e->isAKindOf( ssgTypeBranch() ) ) {
|
||||
ssgBranch *b = (ssgBranch *)e;
|
||||
if ( b->isAKindOf( ssgTypeTransform() ) ) {
|
||||
// Collect up the transfors required to reach that part of
|
||||
// Collect up the transforms required to reach that part of
|
||||
// the branch.
|
||||
sgMat4 xform2;
|
||||
sgMakeIdentMat4( xform2 );
|
||||
|
@ -458,9 +458,9 @@ FGGroundCache::cache_fill(ssgBranch *branch, sgdMat4 xform,
|
|||
// This will minimize the number of vertices/triangles in the cache.
|
||||
else if (e->isAKindOf(ssgTypeLeaf())) {
|
||||
// Since we reach that leaf if we have an intersection with the
|
||||
// most propably bigger wire/catapult cache sphere, we need to check
|
||||
// most probably bigger wire/catapult cache sphere, we need to check
|
||||
// that here, if the smaller cache for the surface has a chance for hits.
|
||||
// Also, if the spheres do not intersect compute a croase agl value
|
||||
// Also, if the spheres do not intersect compute a coarse agl value
|
||||
// by following the line downwards originating at the aircraft.
|
||||
bool spIsec = sp->intersects(&esphere);
|
||||
putSurfaceLeafIntoCache(sp, xform, spIsec, down, (ssgLeaf *)e);
|
||||
|
@ -493,7 +493,7 @@ FGGroundCache::prepare_ground_cache(double ref_time, const double pt[3],
|
|||
// Decide where we put the scenery center.
|
||||
Point3D old_cntr = globals->get_scenery()->get_center();
|
||||
Point3D cntr(pt[0], pt[1], pt[2]);
|
||||
// Only move the cache center if it is unaccaptable far away.
|
||||
// Only move the cache center if it is unacceptable far away.
|
||||
if (40*40 < old_cntr.distance3Dsquared(cntr))
|
||||
globals->get_scenery()->set_center(cntr);
|
||||
else
|
||||
|
@ -523,7 +523,7 @@ FGGroundCache::prepare_ground_cache(double ref_time, const double pt[3],
|
|||
sgdSetVec3(down, -pt[0], -pt[1], -pt[2]);
|
||||
sgdNormalizeVec3(down);
|
||||
|
||||
// We collaps all transforms we need to reach a particular leaf.
|
||||
// We collapse all transforms we need to reach a particular leaf.
|
||||
// The leafs itself will be then transformed later.
|
||||
// So our cache is just flat.
|
||||
// For leafs which are moving (carriers surface, etc ...)
|
||||
|
@ -736,7 +736,7 @@ bool FGGroundCache::caught_wire(double t, const double pt[4][3])
|
|||
sgdCopyVec3( tri[1][2], pt[3] );
|
||||
|
||||
// Intersect the wire lines with each of these triangles.
|
||||
// You have cautght a wire if they intersect.
|
||||
// You have caught a wire if they intersect.
|
||||
for (size_t i = 0; i < sz; ++i) {
|
||||
sgdVec3 le[2];
|
||||
for (int k = 0; k < 2; ++k) {
|
||||
|
|
Loading…
Add table
Reference in a new issue