diff --git a/simgear/scene/tgdb/ReaderWriterSTG.cxx b/simgear/scene/tgdb/ReaderWriterSTG.cxx index f8162595..a43832e2 100644 --- a/simgear/scene/tgdb/ReaderWriterSTG.cxx +++ b/simgear/scene/tgdb/ReaderWriterSTG.cxx @@ -334,46 +334,6 @@ struct ReaderWriterSTG::_ModelBin { } } - if (!_lineFeatureList.empty()) { - - LineFeatureBinList lineFeatures; - - for (const auto& b : _lineFeatureList) { - // add the lineFeatures to the list - const auto path = SGPath(b._filename); - lineFeatures.push_back(LineFeatureBin(path, b._material)); - } - - VPBTechnique::addLineFeatureList(_bucket, lineFeatures, _terrainNode); - } - - if (!_areaFeatureList.empty()) { - - AreaFeatureBinList areaFeatures; - - for (const auto& b : _areaFeatureList) { - // add the lineFeatures to the list - const auto path = SGPath(b._filename); - areaFeatures.push_back(AreaFeatureBin(path, b._material)); - } - - VPBTechnique::addAreaFeatureList(_bucket, areaFeatures, _terrainNode); - } - - if (!_coastFeatureList.empty()) { - - CoastlineBinList coastFeatures; - - for (const auto& b : _coastFeatureList) { - // add the lineFeatures to the list - const auto path = SGPath(b._filename); - coastFeatures.push_back(CoastlineBin(path)); - } - - VPBTechnique::addCoastlineList(_bucket, coastFeatures, _terrainNode); - } - - return group.release(); } @@ -382,10 +342,6 @@ struct ReaderWriterSTG::_ModelBin { std::list<_Sign> _signList; std::list<_BuildingList> _buildingList; std::list<_TreeList> _treeList; - std::list<_LineFeatureList> _lineFeatureList; - std::list<_AreaFeatureList> _areaFeatureList; - std::list<_CoastlineList> _coastFeatureList; - osg::ref_ptr _terrainNode; /// The original options to use for this bunch of models osg::ref_ptr _options; @@ -745,6 +701,47 @@ struct ReaderWriterSTG::_ModelBin { bool vpb_active = SGSceneFeatures::instance()->getVPBActive(); if (vpb_active) { + + // Load any line area or coastline features, which we will need before we generate the tile. + if (!_lineFeatureListList.empty()) { + + LineFeatureBinList lineFeatures; + + for (const auto& b : _lineFeatureListList) { + // add the lineFeatures to the list + const auto path = SGPath(b._filename); + lineFeatures.push_back(LineFeatureBin(path, b._material)); + } + + VPBTechnique::addLineFeatureList(bucket, lineFeatures); + } + + if (!_areaFeatureListList.empty()) { + + AreaFeatureBinList areaFeatures; + + for (const auto& b : _areaFeatureListList) { + // add the lineFeatures to the list + const auto path = SGPath(b._filename); + areaFeatures.push_back(AreaFeatureBin(path, b._material)); + } + + VPBTechnique::addAreaFeatureList(bucket, areaFeatures); + } + + if (!_coastFeatureListList.empty()) { + + CoastlineBinList coastFeatures; + + for (const auto& b : _coastFeatureListList) { + // add the lineFeatures to the list + const auto path = SGPath(b._filename); + coastFeatures.push_back(CoastlineBin(path)); + } + + VPBTechnique::addCoastlineList(bucket, coastFeatures); + } + std::string filename = "vpb/" + bucket.gen_vpb_base() + ".osgb"; if (tile_map.count(filename) == 0) { vpb_node = osgDB::readRefNodeFile(filename, options); @@ -846,13 +843,6 @@ struct ReaderWriterSTG::_ModelBin { readFileCallback->_options = options; readFileCallback->_bucket = bucket; - if (vpb_active && vpb_node) { - readFileCallback->_lineFeatureList = _lineFeatureListList; - readFileCallback->_areaFeatureList = _areaFeatureListList; - readFileCallback->_coastFeatureList = _coastFeatureListList; - readFileCallback->_terrainNode = vpb_node; - } - osg::ref_ptr callbackOptions = new osgDB::Options; callbackOptions->setReadFileCallback(readFileCallback.get()); pagedLOD->setDatabaseOptions(callbackOptions.get()); diff --git a/simgear/scene/tgdb/VPBTechnique.cxx b/simgear/scene/tgdb/VPBTechnique.cxx index a8704a39..94891994 100644 --- a/simgear/scene/tgdb/VPBTechnique.cxx +++ b/simgear/scene/tgdb/VPBTechnique.cxx @@ -137,13 +137,12 @@ void VPBTechnique::setFilterMatrixAs(FilterType filterType) void VPBTechnique::init(int dirtyMask, bool assumeMultiThreaded) { if (!_terrainTile) return; + if (dirtyMask==0) return; OpenThreads::ScopedLock lock(_writeBufferMutex); osg::ref_ptr tile = _terrainTile; - if (dirtyMask==0) return; - osgTerrain::TileID tileID = tile->getTileID(); SG_LOG(SG_TERRAIN, SG_DEBUG, "Init of tile " << tileID.x << "," << tileID.y << " level " << tileID.level << " " << dirtyMask); @@ -2233,43 +2232,6 @@ void VPBTechnique::releaseGLObjects(osg::State* state) const if (_newBufferData.valid() && _newBufferData->_transform.valid()) _newBufferData->_transform->releaseGLObjects(state); } -// Simple vistor to check for any underlying terrain meshes that intersect with a given constraint therefore may need to be modified -// (e.g elevation lowered to ensure the terrain doesn't poke through an airport mesh, or line features generated) -class TerrainVisitor : public osg::NodeVisitor { - public: - osg::ref_ptr _constraint; // Object describing the volume to be modified. - int _dirtyMask; // Dirty mask to apply. - int _minLevel; // Minimum LoD level to modify. - TerrainVisitor( osg::ref_ptr node, int mask, int minLevel) : - osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN), - _constraint(node), - _dirtyMask(mask), - _minLevel(minLevel) - { } - virtual ~TerrainVisitor() - { } - - void apply(osg::Node& node) - { - osgTerrain::TerrainTile* tile = dynamic_cast(&node); - if (tile) { - // Determine if the constraint should affect this tile. - const int level = tile->getTileID().level; - const osg::BoundingSphere tileBB = tile->getBound(); - if ((level >= _minLevel) && tileBB.intersects(_constraint->getBound())) { - // Dirty any existing terrain tiles containing this constraint, which will force regeneration - osgTerrain::TileID tileID = tile->getTileID(); - SG_LOG(SG_TERRAIN, SG_DEBUG, "Setting dirty mask for tile " << tileID.x << "," << tileID.y << " level " << tileID.level << " " << _dirtyMask); - tile->setDirtyMask(_dirtyMask); - } else if (tileBB.intersects(_constraint->getBound())) { - traverse(node); - } - } else { - traverse(node); - } - } -}; - // Add an osg object representing a contraint on the terrain mesh. The generated terrain mesh will not include any vertices that // lie above the constraint model. (Note that geometry may result in edges intersecting the constraint model in cases where there // are significantly higher vertices that lie just outside the constraint model. @@ -2277,9 +2239,6 @@ void VPBTechnique::addElevationConstraint(osg::ref_ptr constraint, os { const std::lock_guard lock(VPBTechnique::_constraint_mutex); // Lock the _constraintGroup for this scope _constraintGroup->addChild(constraint.get()); - - TerrainVisitor ftv(constraint, TerrainTile::ALL_DIRTY, 0); - terrain->accept(ftv); } // Remove a previously added constraint. E.g on model unload. @@ -2310,7 +2269,7 @@ osg::Vec3d VPBTechnique::checkAgainstElevationConstraints(osg::Vec3d origin, osg } } -void VPBTechnique::addLineFeatureList(SGBucket bucket, LineFeatureBinList roadList, osg::ref_ptr terrainNode) +void VPBTechnique::addLineFeatureList(SGBucket bucket, LineFeatureBinList roadList) { if (roadList.empty()) return; @@ -2320,26 +2279,9 @@ void VPBTechnique::addLineFeatureList(SGBucket bucket, LineFeatureBinList roadLi _lineFeatureLists.push_back(std::pair(bucket, roadList)); } - // We need to trigger a re-build of the appropriate Terrain tile, so create a pretend node and run the TerrainVisitor to - // "dirty" the TerrainTile that it intersects with. - osg::ref_ptr n = new osg::Node(); - - //SGVec3d coord1, coord2; - //SGGeodesy::SGGeodToCart(SGGeod::fromDegM(bucket.get_center_lon() -0.5*bucket.get_width(), bucket.get_center_lat() -0.5*bucket.get_height(), 0.0), coord1); - //SGGeodesy::SGGeodToCart(SGGeod::fromDegM(bucket.get_center_lon() +0.5*bucket.get_width(), bucket.get_center_lat() +0.5*bucket.get_height(), 0.0), coord2); - //osg::BoundingBox bbox = osg::BoundingBox(toOsg(coord1), toOsg(coord2)); - //n->setInitialBound(bbox); - - SGVec3d coord; - SGGeodesy::SGGeodToCart(SGGeod::fromDegM(bucket.get_center_lon(), bucket.get_center_lat(), 0.0), coord); - n->setInitialBound(osg::BoundingSphere(toOsg(coord), max(bucket.get_width_m(), bucket.get_height_m()))); - - SG_LOG(SG_TERRAIN, SG_DEBUG, "Adding line features to " << bucket.gen_index_str()); - TerrainVisitor ftv(n, TerrainTile::ALL_DIRTY, 0); - terrainNode->accept(ftv); } -void VPBTechnique::addAreaFeatureList(SGBucket bucket, AreaFeatureBinList areaList, osg::ref_ptr terrainNode) +void VPBTechnique::addAreaFeatureList(SGBucket bucket, AreaFeatureBinList areaList) { if (areaList.empty()) return; @@ -2348,27 +2290,9 @@ void VPBTechnique::addAreaFeatureList(SGBucket bucket, AreaFeatureBinList areaLi const std::lock_guard lock(VPBTechnique::_areaFeatureLists_mutex); // Lock the _lineFeatureLists for this scope _areaFeatureLists.push_back(std::pair(bucket, areaList)); } - - // We need to trigger a re-build of the appropriate Terrain tile, so create a pretend node and run the TerrainVisitor to - // "dirty" the TerrainTile that it intersects with. - osg::ref_ptr n = new osg::Node(); - - //SGVec3d coord1, coord2; - //SGGeodesy::SGGeodToCart(SGGeod::fromDegM(bucket.get_center_lon() -0.5*bucket.get_width(), bucket.get_center_lat() -0.5*bucket.get_height(), 0.0), coord1); - //SGGeodesy::SGGeodToCart(SGGeod::fromDegM(bucket.get_center_lon() +0.5*bucket.get_width(), bucket.get_center_lat() +0.5*bucket.get_height(), 0.0), coord2); - //osg::BoundingBox bbox = osg::BoundingBox(toOsg(coord1), toOsg(coord2)); - //n->setInitialBound(bbox); - - SGVec3d coord; - SGGeodesy::SGGeodToCart(SGGeod::fromDegM(bucket.get_center_lon(), bucket.get_center_lat(), 0.0), coord); - n->setInitialBound(osg::BoundingSphere(toOsg(coord), max(bucket.get_width_m(), bucket.get_height_m()))); - - SG_LOG(SG_TERRAIN, SG_DEBUG, "Adding line features to " << bucket.gen_index_str()); - TerrainVisitor ftv(n, TerrainTile::ALL_DIRTY, 0); - terrainNode->accept(ftv); } -void VPBTechnique::addCoastlineList(SGBucket bucket, CoastlineBinList coastline, osg::ref_ptr terrainNode) +void VPBTechnique::addCoastlineList(SGBucket bucket, CoastlineBinList coastline) { if (coastline.empty()) return; @@ -2378,28 +2302,11 @@ void VPBTechnique::addCoastlineList(SGBucket bucket, CoastlineBinList coastline, _coastFeatureLists.push_back(std::pair(bucket, coastline)); } - // We need to trigger a re-build of the appropriate Terrain tile, so create a pretend node and run the TerrainVisitor to - // "dirty" the TerrainTile that it intersects with. - osg::ref_ptr n = new osg::Node(); - - //SGVec3d coord1, coord2; - //SGGeodesy::SGGeodToCart(SGGeod::fromDegM(bucket.get_center_lon() -0.5*bucket.get_width(), bucket.get_center_lat() -0.5*bucket.get_height(), 0.0), coord1); - //SGGeodesy::SGGeodToCart(SGGeod::fromDegM(bucket.get_center_lon() +0.5*bucket.get_width(), bucket.get_center_lat() +0.5*bucket.get_height(), 0.0), coord2); - //osg::BoundingBox bbox = osg::BoundingBox(toOsg(coord1), toOsg(coord2)); - //n->setInitialBound(bbox); - - SGVec3d coord; - SGGeodesy::SGGeodToCart(SGGeod::fromDegM(bucket.get_center_lon(), bucket.get_center_lat(), 0.0), coord); - n->setInitialBound(osg::BoundingSphere(toOsg(coord), max(bucket.get_width_m(), bucket.get_height_m()))); - - SG_LOG(SG_TERRAIN, SG_DEBUG, "Adding line features to " << bucket.gen_index_str()); - TerrainVisitor ftv(n, TerrainTile::ALL_DIRTY, 0); - terrainNode->accept(ftv); } void VPBTechnique::unloadFeatures(SGBucket bucket) { - SG_LOG(SG_TERRAIN, SG_DEBUG, "Erasing all roads with entry " << bucket); + SG_LOG(SG_TERRAIN, SG_DEBUG, "Erasing all features with entry " << bucket); const std::lock_guard lock(VPBTechnique::_lineFeatureLists_mutex); // Lock the _lineFeatureLists for this scope // C++ 20... //std::erase_if(_lineFeatureLists, [bucket](BucketLineFeatureBinList p) { return p.first == bucket; } ); diff --git a/simgear/scene/tgdb/VPBTechnique.hxx b/simgear/scene/tgdb/VPBTechnique.hxx index 2f4f30c4..0e24cc26 100644 --- a/simgear/scene/tgdb/VPBTechnique.hxx +++ b/simgear/scene/tgdb/VPBTechnique.hxx @@ -97,9 +97,9 @@ class VPBTechnique : public TerrainTechnique static osg::Vec3d checkAgainstElevationConstraints(osg::Vec3d origin, osg::Vec3d vertex, float vertex_gap); // LineFeatures and AreaFeatures are draped over the underlying mesh. - static void addLineFeatureList(SGBucket bucket, LineFeatureBinList roadList, osg::ref_ptr terrainNode); - static void addAreaFeatureList(SGBucket bucket, AreaFeatureBinList areaList, osg::ref_ptr terrainNode); - static void addCoastlineList(SGBucket bucket, CoastlineBinList areaList, osg::ref_ptr terrainNode); + static void addLineFeatureList(SGBucket bucket, LineFeatureBinList roadList); + static void addAreaFeatureList(SGBucket bucket, AreaFeatureBinList areaList); + static void addCoastlineList(SGBucket bucket, CoastlineBinList areaList); static void unloadFeatures(SGBucket bucket); protected: