Further work on bug 905.
Tolerate Octree leaf children which have been moved outside their leaf's BBox. This is necessary since lazy-loading of ILS and threshold files can cause re-locations even during child traversal, where updating the hierarchy is very complex. Instead, simply tolerate this case, and rely on the real position data (which is correct).
This commit is contained in:
parent
48c1b51875
commit
91c6e3433d
3 changed files with 8 additions and 18 deletions
|
@ -1350,6 +1350,14 @@ void NavDataCache::updatePosition(PositionedID item, const SGGeod &pos)
|
||||||
sqlite3_bind_double(d->setAirportPos, 3, pos.getLatitudeDeg());
|
sqlite3_bind_double(d->setAirportPos, 3, pos.getLatitudeDeg());
|
||||||
sqlite3_bind_double(d->setAirportPos, 4, pos.getElevationM());
|
sqlite3_bind_double(d->setAirportPos, 4, pos.getElevationM());
|
||||||
|
|
||||||
|
// bug 905; the octree leaf may change here, but the leaf may already be
|
||||||
|
// loaded, and caching its children. (Either the old or new leaf!). Worse,
|
||||||
|
// we may be called here as a result of loading one of those leaf's children.
|
||||||
|
// instead of dealing with all those possibilites, such as modifying
|
||||||
|
// the in-memory leaf's STL child container, we simply leave the runtime
|
||||||
|
// structures alone. This is fine providing items do no move very far, since
|
||||||
|
// all the spatial searches ultimately use the items' real cartesian position,
|
||||||
|
// which was updated above.
|
||||||
Octree::Leaf* octreeLeaf = Octree::global_spatialOctree->findLeafForPos(cartPos);
|
Octree::Leaf* octreeLeaf = Octree::global_spatialOctree->findLeafForPos(cartPos);
|
||||||
sqlite3_bind_int64(d->setAirportPos, 5, octreeLeaf->guid());
|
sqlite3_bind_int64(d->setAirportPos, 5, octreeLeaf->guid());
|
||||||
|
|
||||||
|
|
|
@ -139,8 +139,6 @@ public:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Modify the position of an existing item.
|
* Modify the position of an existing item.
|
||||||
* Use with care, since loaded instances will not be updated (at present -
|
|
||||||
* this behaviour could in theorey be improved)
|
|
||||||
*/
|
*/
|
||||||
void updatePosition(PositionedID item, const SGGeod &pos);
|
void updatePosition(PositionedID item, const SGGeod &pos);
|
||||||
|
|
||||||
|
|
|
@ -67,22 +67,6 @@ void Leaf::visit(const SGVec3d& aPos, double aCutoff,
|
||||||
|
|
||||||
for (; it != end; ++it) {
|
for (; it != end; ++it) {
|
||||||
FGPositioned* p = cache->loadById(it->second);
|
FGPositioned* p = cache->loadById(it->second);
|
||||||
if (!intersects(_box, p->cart())) {
|
|
||||||
// see http://code.google.com/p/flightgear-bugs/issues/detail?id=905
|
|
||||||
|
|
||||||
SG_LOG(SG_GENERAL, SG_WARN, "XXXXXXXXX bad spatial index for " << it->second
|
|
||||||
<< "; " << p->ident() << " of type " <<
|
|
||||||
FGPositioned::nameForType(p->type()));
|
|
||||||
SG_LOG(SG_GENERAL, SG_WARN, "\tgeodetic location:" << p->geod());
|
|
||||||
SG_LOG(SG_GENERAL, SG_WARN, "\tcartesian location:" << p->cart());
|
|
||||||
|
|
||||||
SG_LOG(SG_GENERAL, SG_WARN, "leaf box:" <<
|
|
||||||
_box.getMin() << " x " << _box.getMax());
|
|
||||||
|
|
||||||
throw sg_exception("Bad spatial index data");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
double d = dist(aPos, p->cart());
|
double d = dist(aPos, p->cart());
|
||||||
if (d > aCutoff) {
|
if (d > aCutoff) {
|
||||||
continue;
|
continue;
|
||||||
|
|
Loading…
Reference in a new issue