From d4b02d58d67b8d82ba53a2c9b76633b48ba2e726 Mon Sep 17 00:00:00 2001 From: Fahim Imaduddin Dalvi Date: Tue, 4 Jan 2022 17:56:41 +0300 Subject: [PATCH] Refactored constraint checking for random objects The Random objects check now happens in the scanline read in VPBTechnique, rather in the VBPMaterialHandler objects. These checks are not specific to any handler, and are thus better suited to be outside of specific material handling logic. --- simgear/scene/tgdb/VPBMaterialHandler.cxx | 64 ++++++++++------------- simgear/scene/tgdb/VPBMaterialHandler.hxx | 35 ++++++------- simgear/scene/tgdb/VPBTechnique.cxx | 27 ++++++++-- simgear/scene/tgdb/VPBTechnique.hxx | 4 ++ 4 files changed, 69 insertions(+), 61 deletions(-) diff --git a/simgear/scene/tgdb/VPBMaterialHandler.cxx b/simgear/scene/tgdb/VPBMaterialHandler.cxx index 57ed562a..722d40c8 100644 --- a/simgear/scene/tgdb/VPBMaterialHandler.cxx +++ b/simgear/scene/tgdb/VPBMaterialHandler.cxx @@ -58,16 +58,6 @@ bool VPBMaterialHandler::checkAgainstObjectMask( return false; } -bool VPBMaterialHandler::checkAgainstConstraints( - osg::ref_ptr constraintGroup, osg::Vec3d origin, - osg::Vec3d vertex) { - osg::ref_ptr intersector; - intersector = new osgUtil::LineSegmentIntersector(origin, vertex); - osgUtil::IntersectionVisitor visitor(intersector.get()); - constraintGroup->accept(visitor); - return intersector->containsIntersections(); -} - double VPBMaterialHandler::det2(const osg::Vec2d a, const osg::Vec2d b) { return a.x() * b.y() - b.x() * a.y(); } @@ -160,12 +150,13 @@ bool VegetationHandler::handleNewMaterial(SGMaterial *mat) { } bool VegetationHandler::handleIteration( - SGMaterial *mat, osg::Image *objectMaskImage, - osg::ref_ptr constraintGroup, const double lon, - const double lat, osg::Vec2d p, const double D, const osg::Vec2d ll_O, - const osg::Vec2d ll_x, const osg::Vec2d ll_y, const osg::Vec2d t_0, - osg::Vec2d t_x, osg::Vec2d t_y, const osg::Vec3d v_0, osg::Vec3d v_x, - osg::Vec3d v_y, float x_scale, float y_scale, osg::Vec3 n, osg::Vec3d up) { + SGMaterial* mat, osg::Image* objectMaskImage, + const double lon, const double lat, + osg::Vec2d p, const double D, + const osg::Vec2d ll_O, const osg::Vec2d ll_x, const osg::Vec2d ll_y, + const osg::Vec2d t_0, osg::Vec2d t_x, osg::Vec2d t_y, + float x_scale, float y_scale, osg::Vec2f& pointInTriangle) +{ const int lat_int = (lat + ll_O.y()) / delta_lat; const int lon_int = (lon + ll_O.x()) / delta_lon; @@ -195,16 +186,14 @@ bool VegetationHandler::handleIteration( return false; } - // Check against constraints to stop trees growing from roads; - const osg::Vec3 vp = v_x * x + v_y * y + v_0; - if (checkAgainstConstraints(constraintGroup, vp - up * 100, vp + up * 100)) - return false; - - bin->insert(SGVec3f(vp.x(), vp.y(), vp.z()), SGVec3f(n.x(), n.y(), n.z())); - + pointInTriangle.set(x, y); return true; } +void VegetationHandler::placeObject(const osg::Vec3 vp, const osg::Vec3d up, const osg::Vec3 n) { + bin->insert(SGVec3f(vp.x(), vp.y(), vp.z()), SGVec3f(n.x(), n.y(), n.z())); +} + void VegetationHandler::finish(osg::ref_ptr options, osg::ref_ptr transform, const SGGeod loc) { @@ -287,12 +276,13 @@ bool RandomLightsHandler::handleNewMaterial(SGMaterial *mat) { } bool RandomLightsHandler::handleIteration( - SGMaterial *mat, osg::Image *objectMaskImage, - osg::ref_ptr constraintGroup, const double lon, - const double lat, osg::Vec2d p, const double D, const osg::Vec2d ll_O, - const osg::Vec2d ll_x, const osg::Vec2d ll_y, const osg::Vec2d t_0, - osg::Vec2d t_x, osg::Vec2d t_y, const osg::Vec3d v_0, osg::Vec3d v_x, - osg::Vec3d v_y, float x_scale, float y_scale, osg::Vec3 n, osg::Vec3d up) { + SGMaterial* mat, osg::Image* objectMaskImage, + const double lon, const double lat, + osg::Vec2d p, const double D, + const osg::Vec2d ll_O, const osg::Vec2d ll_x, const osg::Vec2d ll_y, + const osg::Vec2d t_0, osg::Vec2d t_x, osg::Vec2d t_y, + float x_scale, float y_scale, osg::Vec2f& pointInTriangle) +{ const int lat_int = (lat + ll_O.y()) / delta_lat; const int lon_int = (lon + ll_O.x()) / delta_lon; @@ -325,13 +315,15 @@ bool RandomLightsHandler::handleIteration( return false; } - // Check against constraints to stop lights on roads - const osg::Vec3 vp = v_x * x + v_y * y + v_0; - if (checkAgainstConstraints(constraintGroup, vp - up * 100, vp + up * 100)) - return false; + pointInTriangle.set(x, y); - float zombie = pc_map_rand(lon_int, lat_int, 6); - float factor = pc_map_rand(lon_int, lat_int, 7); + return true; +} + +void RandomLightsHandler::placeObject(const osg::Vec3 vp, const osg::Vec3d up, const osg::Vec3 n) +{ + float zombie = pc_map_rand(vp.x(), vp.y() + vp.z(), 6); + float factor = pc_map_rand(vp.x(), vp.y() + vp.z(), 7); factor *= factor; float bright = 1; @@ -364,8 +356,6 @@ bool RandomLightsHandler::handleIteration( bin->insert( SGVec3f(finalPosition.x(), finalPosition.y(), finalPosition.z()), size, intensity, onPeriod, color); - - return true; } void RandomLightsHandler::finish(osg::ref_ptr options, diff --git a/simgear/scene/tgdb/VPBMaterialHandler.hxx b/simgear/scene/tgdb/VPBMaterialHandler.hxx index 689c8037..23c626b7 100644 --- a/simgear/scene/tgdb/VPBMaterialHandler.hxx +++ b/simgear/scene/tgdb/VPBMaterialHandler.hxx @@ -56,11 +56,6 @@ class VPBMaterialHandler { float y_scale, const osg::Vec2d t_0, osg::Vec2d t_x, osg::Vec2d t_y); - // Check a given vertex against any constraints E.g. to ensure we - // don't get objects like trees sprouting from roads or runways. - bool checkAgainstConstraints(osg::ref_ptr constraintGroup, - osg::Vec3d origin, osg::Vec3d vertex); - double det2(const osg::Vec2d a, const osg::Vec2d b); public: @@ -80,16 +75,20 @@ class VPBMaterialHandler { // Function that is called for each point in the scanline reading process // Return false if the material is irrelevant to the handler - virtual bool handleIteration(SGMaterial *mat, osg::Image *objectMaskImage, - osg::ref_ptr constraintGroup, + // Return true if the point should be used to place an object, updating + // the pointInTriangle variable with the x and y location within the + // current triangle + virtual bool handleIteration(SGMaterial* mat, osg::Image* objectMaskImage, const double lon, const double lat, osg::Vec2d p, const double D, const osg::Vec2d ll_O, const osg::Vec2d ll_x, const osg::Vec2d ll_y, const osg::Vec2d t_0, osg::Vec2d t_x, osg::Vec2d t_y, - const osg::Vec3d v_0, osg::Vec3d v_x, - osg::Vec3d v_y, float x_scale, float y_scale, - osg::Vec3 n, osg::Vec3d up) = 0; + float x_scale, float y_scale, + osg::Vec2f& pointInTriangle) = 0; + + // Place an object at the point given by vp + virtual void placeObject(const osg::Vec3 vp, const osg::Vec3d up, const osg::Vec3 n) = 0; // Function that is called after the scanline is complete virtual void finish(osg::ref_ptr options, @@ -116,15 +115,13 @@ class VegetationHandler : public VPBMaterialHandler { osg::ref_ptr terrainTile); void setLocation(const SGGeod loc, double r_E_lat, double r_E_lon); bool handleNewMaterial(SGMaterial *mat); - bool handleIteration(SGMaterial *mat, osg::Image *objectMaskImage, - osg::ref_ptr constraintGroup, + bool handleIteration(SGMaterial* mat, osg::Image* objectMaskImage, const double lon, const double lat, osg::Vec2d p, const double D, const osg::Vec2d ll_O, const osg::Vec2d ll_x, const osg::Vec2d ll_y, const osg::Vec2d t_0, osg::Vec2d t_x, osg::Vec2d t_y, - const osg::Vec3d v_0, osg::Vec3d v_x, osg::Vec3d v_y, - float x_scale, float y_scale, osg::Vec3 n, - osg::Vec3d up); + float x_scale, float y_scale, osg::Vec2f& pointInTriangle); + void placeObject(const osg::Vec3 vp, const osg::Vec3d up, const osg::Vec3 n); void finish(osg::ref_ptr options, osg::ref_ptr transform, const SGGeod loc); @@ -151,15 +148,13 @@ class RandomLightsHandler : public VPBMaterialHandler { osg::ref_ptr terrainTile); void setLocation(const SGGeod loc, double r_E_lat, double r_E_lon); bool handleNewMaterial(SGMaterial *mat); - bool handleIteration(SGMaterial *mat, osg::Image *objectMaskImage, - osg::ref_ptr constraintGroup, + bool handleIteration(SGMaterial* mat, osg::Image* objectMaskImage, const double lon, const double lat, osg::Vec2d p, const double D, const osg::Vec2d ll_O, const osg::Vec2d ll_x, const osg::Vec2d ll_y, const osg::Vec2d t_0, osg::Vec2d t_x, osg::Vec2d t_y, - const osg::Vec3d v_0, osg::Vec3d v_x, osg::Vec3d v_y, - float x_scale, float y_scale, osg::Vec3 n, - osg::Vec3d up); + float x_scale, float y_scale, osg::Vec2f& pointInTriangle); + void placeObject(const osg::Vec3 vp, const osg::Vec3d up, const osg::Vec3 n); void finish(osg::ref_ptr options, osg::ref_ptr transform, const SGGeod loc); diff --git a/simgear/scene/tgdb/VPBTechnique.cxx b/simgear/scene/tgdb/VPBTechnique.cxx index 837ef90a..53c78c89 100644 --- a/simgear/scene/tgdb/VPBTechnique.cxx +++ b/simgear/scene/tgdb/VPBTechnique.cxx @@ -1634,10 +1634,18 @@ void VPBTechnique::applyMaterials(BufferData& buffer, Locator* masterLocator) if (!mat) continue; - handler->handleIteration(mat, object_mask_image, - _randomObjectsConstraintGroup, lon, lat, p, - D, ll_O, ll_x, ll_y, t_0, t_x, t_y, v_0, - v_x, v_y, x_scale, y_scale, n, up); + osg::Vec2f pointInTriangle; + + if (handler->handleIteration(mat, object_mask_image, + lon, lat, p, + 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)) + continue; + + handler->placeObject(vp, up, n); + } } } @@ -2382,6 +2390,17 @@ void VPBTechnique::addRandomObjectsConstraint(osg::ref_ptr constraint _randomObjectsConstraintGroup->addChild(constraint.get()); } +bool VPBTechnique::checkAgainstRandomObjectsConstraints( + osg::ref_ptr constraintGroup, osg::Vec3d origin, + osg::Vec3d vertex) +{ + osg::ref_ptr intersector; + intersector = new osgUtil::LineSegmentIntersector(origin, vertex); + osgUtil::IntersectionVisitor visitor(intersector.get()); + constraintGroup->accept(visitor); + return intersector->containsIntersections(); +} + // Remove a previously added constraint. E.g on model unload. void VPBTechnique::removeRandomObjectsConstraint(osg::ref_ptr constraint) { diff --git a/simgear/scene/tgdb/VPBTechnique.hxx b/simgear/scene/tgdb/VPBTechnique.hxx index 766ef251..1436c0b5 100644 --- a/simgear/scene/tgdb/VPBTechnique.hxx +++ b/simgear/scene/tgdb/VPBTechnique.hxx @@ -186,6 +186,10 @@ class VPBTechnique : public TerrainTechnique // we only use these internally and during generation of this particular tile. virtual void addRandomObjectsConstraint(osg::ref_ptr constraint); virtual void removeRandomObjectsConstraint(osg::ref_ptr constraint); + // Check a given vertex against any constraints E.g. to ensure we + // don't get objects like trees sprouting from roads or runways. + bool checkAgainstRandomObjectsConstraints(osg::ref_ptr constraintGroup, + osg::Vec3d origin, osg::Vec3d vertex); virtual void clearRandomObjectsConstraints(); OpenThreads::Mutex _writeBufferMutex;