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 <dalvifahim@gmail.com>
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 <dalvifahim@gmail.com>
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 <dalvifahim@gmail.com>
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.
This commit is contained in:
Fahim Imaduddin Dalvi 2022-01-04 18:10:03 +03:00
parent d4b02d58d6
commit c4c5829d37
2 changed files with 22 additions and 4 deletions

View File

@ -541,7 +541,7 @@ void VertexNormalGenerator::populateCenter(osgTerrain::Layer* elevationLayer, os
_masterLocator->convertLocalToModel(osg::Vec3d(ndc.x(), ndc.y(), -1000), origin); _masterLocator->convertLocalToModel(osg::Vec3d(ndc.x(), ndc.y(), -1000), origin);
_masterLocator->convertLocalToModel(ndc, model); _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())); 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)) { 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 // Check against constraints to stop lights on roads
const osg::Vec3 vp = v_x * pointInTriangle.x() + v_y * pointInTriangle.y() + v_0; 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; continue;
handler->placeObject(vp, up, n); handler->placeObject(vp, up, n);
@ -2364,7 +2370,7 @@ void VPBTechnique::removeElevationConstraint(osg::ref_ptr<osg::Node> constraint)
// Check a given vertex against any elevation constraints E.g. to ensure the terrain mesh doesn't // 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 // 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. // 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<std::mutex> lock(VPBTechnique::_elevationConstraintMutex); // Lock the _elevationConstraintGroup for this scope const std::lock_guard<std::mutex> lock(VPBTechnique::_elevationConstraintMutex); // Lock the _elevationConstraintGroup for this scope
osg::ref_ptr<osgUtil::LineSegmentIntersector> intersector; osg::ref_ptr<osgUtil::LineSegmentIntersector> 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<std::mutex> lock(VPBTechnique::_elevationConstraintMutex); // Lock the _elevationConstraintGroup for this scope
osg::ref_ptr<osgUtil::LineSegmentIntersector> 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 // Add an osg object representing a contraint on the terrain mesh. The generated
// terrain mesh will not include any random objects intersecting with the // terrain mesh will not include any random objects intersecting with the
// constraint model. // constraint model.

View File

@ -96,7 +96,8 @@ class VPBTechnique : public TerrainTechnique
// As airports are generated in a separate loading thread, these are static. // As airports are generated in a separate loading thread, these are static.
static void addElevationConstraint(osg::ref_ptr<osg::Node> constraint); static void addElevationConstraint(osg::ref_ptr<osg::Node> constraint);
static void removeElevationConstraint(osg::ref_ptr<osg::Node> constraint); static void removeElevationConstraint(osg::ref_ptr<osg::Node> 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(); static void clearConstraints();