From c4c5829d37389477bd83e13c79f58a77e249fe5a Mon Sep 17 00:00:00 2001 From: Fahim Imaduddin Dalvi Date: Tue, 4 Jan 2022 18:10:03 +0300 Subject: [PATCH] Added airport terrain check for random objects Random objects like lights and trees are not placed on airport terrain anymore. This commit also refactors some of the existing code for clarity. Discussion can be found here [1] and detailed history here [2]. [1] https://sourceforge.net/p/flightgear/simgear/merge-requests/102/ [2] https://sourceforge.net/u/fahimdalvi/simgear/ci/bugfix/ws30_random_objects_avoid_airports/~/tree/ Squashed commit of the following: commit 643198f8d52da8d65a674b052c508f03d7f83ac0 Author: Fahim Imaduddin Dalvi Date: Tue Jan 4 09:57:34 2022 +0300 Implemented corrected airport intersection logic We now convert the point into the correct coordinate system before checking for intersections with the airport geometry. commit 7e0819e4f88992658301a2c15d890fc489cfe3b6 Author: Fahim Imaduddin Dalvi Date: Wed Nov 10 19:59:04 2021 +0300 Added airport terrain check code for random objects This commit does not work as expected. The light-coverage check is disabled to amplify the bug. commit eb21e8fd256dcf124857ac51afc0d7c3c90ae1c6 Author: Fahim Imaduddin Dalvi Date: Wed Nov 10 19:53:44 2021 +0300 Refactored elevation constraint checking code This commit provides a separate elevation constraint function that does not displace the given point. The current function has been renamed to indicate the displacement side effect. --- simgear/scene/tgdb/VPBTechnique.cxx | 23 ++++++++++++++++++++--- simgear/scene/tgdb/VPBTechnique.hxx | 3 ++- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/simgear/scene/tgdb/VPBTechnique.cxx b/simgear/scene/tgdb/VPBTechnique.cxx index 53c78c89..e9835bdf 100644 --- a/simgear/scene/tgdb/VPBTechnique.cxx +++ b/simgear/scene/tgdb/VPBTechnique.cxx @@ -541,7 +541,7 @@ void VertexNormalGenerator::populateCenter(osgTerrain::Layer* elevationLayer, os _masterLocator->convertLocalToModel(osg::Vec3d(ndc.x(), ndc.y(), -1000), origin); _masterLocator->convertLocalToModel(ndc, model); - model = VPBTechnique::checkAgainstElevationConstraints(origin, model, _constraint_vtx_gap); + model = VPBTechnique::checkAndDisplaceAgainstElevationConstraints(origin, model, _constraint_vtx_gap); texcoords->push_back(osg::Vec2(ndc.x(), ndc.y())); @@ -1641,7 +1641,13 @@ void VPBTechnique::applyMaterials(BufferData& buffer, Locator* masterLocator) D, ll_O, ll_x, ll_y, t_0, t_x, t_y, x_scale, y_scale, pointInTriangle)) { // Check against constraints to stop lights on roads const osg::Vec3 vp = v_x * pointInTriangle.x() + v_y * pointInTriangle.y() + v_0; - if (checkAgainstRandomObjectsConstraints(_randomObjectsConstraintGroup, vp - up * 100, vp + up * 100)) + const osg::Vec3 upperPoint = vp + up * 100; + const osg::Vec3 lowerPoint = vp - up * 100; + if (checkAgainstRandomObjectsConstraints(_randomObjectsConstraintGroup, lowerPoint, upperPoint)) + continue; + + const osg::Matrixd localToGeocentricTransform = buffer._transform->getMatrix(); + if (checkAgainstElevationConstraints(lowerPoint * localToGeocentricTransform, upperPoint * localToGeocentricTransform)) continue; handler->placeObject(vp, up, n); @@ -2364,7 +2370,7 @@ void VPBTechnique::removeElevationConstraint(osg::ref_ptr constraint) // Check a given vertex against any elevation constraints E.g. to ensure the terrain mesh doesn't // poke through any airport meshes. If such a constraint exists, the function will return a replacement // vertex displaces such that it lies 1m below the contraint relative to the passed in origin. -osg::Vec3d VPBTechnique::checkAgainstElevationConstraints(osg::Vec3d origin, osg::Vec3d vertex, float vtx_gap) +osg::Vec3d VPBTechnique::checkAndDisplaceAgainstElevationConstraints(osg::Vec3d origin, osg::Vec3d vertex, float vtx_gap) { const std::lock_guard lock(VPBTechnique::_elevationConstraintMutex); // Lock the _elevationConstraintGroup for this scope osg::ref_ptr intersector; @@ -2382,6 +2388,17 @@ osg::Vec3d VPBTechnique::checkAgainstElevationConstraints(osg::Vec3d origin, osg } } +bool VPBTechnique::checkAgainstElevationConstraints(osg::Vec3d origin, osg::Vec3d vertex) +{ + const std::lock_guard lock(VPBTechnique::_elevationConstraintMutex); // Lock the _elevationConstraintGroup for this scope + osg::ref_ptr intersector; + intersector = new osgUtil::LineSegmentIntersector(origin, vertex); + osgUtil::IntersectionVisitor visitor(intersector.get()); + _elevationConstraintGroup->accept(visitor); + return intersector->containsIntersections(); +} + + // Add an osg object representing a contraint on the terrain mesh. The generated // terrain mesh will not include any random objects intersecting with the // constraint model. diff --git a/simgear/scene/tgdb/VPBTechnique.hxx b/simgear/scene/tgdb/VPBTechnique.hxx index 1436c0b5..02f78201 100644 --- a/simgear/scene/tgdb/VPBTechnique.hxx +++ b/simgear/scene/tgdb/VPBTechnique.hxx @@ -96,7 +96,8 @@ class VPBTechnique : public TerrainTechnique // As airports are generated in a separate loading thread, these are static. static void addElevationConstraint(osg::ref_ptr constraint); static void removeElevationConstraint(osg::ref_ptr constraint); - static osg::Vec3d checkAgainstElevationConstraints(osg::Vec3d origin, osg::Vec3d vertex, float vertex_gap); + static osg::Vec3d checkAndDisplaceAgainstElevationConstraints(osg::Vec3d origin, osg::Vec3d vertex, float vertex_gap); + static bool checkAgainstElevationConstraints(osg::Vec3d origin, osg::Vec3d vertex); static void clearConstraints();