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;