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.
This commit is contained in:
@@ -58,16 +58,6 @@ bool VPBMaterialHandler::checkAgainstObjectMask(
|
||||
return false;
|
||||
}
|
||||
|
||||
bool VPBMaterialHandler::checkAgainstConstraints(
|
||||
osg::ref_ptr<osg::Group> constraintGroup, osg::Vec3d origin,
|
||||
osg::Vec3d vertex) {
|
||||
osg::ref_ptr<osgUtil::LineSegmentIntersector> 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<osg::Group> 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<SGReaderWriterOptions> options,
|
||||
osg::ref_ptr<osg::MatrixTransform> transform,
|
||||
const SGGeod loc) {
|
||||
@@ -287,12 +276,13 @@ bool RandomLightsHandler::handleNewMaterial(SGMaterial *mat) {
|
||||
}
|
||||
|
||||
bool RandomLightsHandler::handleIteration(
|
||||
SGMaterial *mat, osg::Image *objectMaskImage,
|
||||
osg::ref_ptr<osg::Group> 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<SGReaderWriterOptions> options,
|
||||
|
||||
@@ -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<osg::Group> 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<osg::Group> 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<SGReaderWriterOptions> options,
|
||||
@@ -116,15 +115,13 @@ class VegetationHandler : public VPBMaterialHandler {
|
||||
osg::ref_ptr<TerrainTile> 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<osg::Group> 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<SGReaderWriterOptions> options,
|
||||
osg::ref_ptr<osg::MatrixTransform> transform, const SGGeod loc);
|
||||
|
||||
@@ -151,15 +148,13 @@ class RandomLightsHandler : public VPBMaterialHandler {
|
||||
osg::ref_ptr<TerrainTile> 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<osg::Group> 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<SGReaderWriterOptions> options,
|
||||
osg::ref_ptr<osg::MatrixTransform> transform, const SGGeod loc);
|
||||
|
||||
|
||||
@@ -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<osg::Node> constraint
|
||||
_randomObjectsConstraintGroup->addChild(constraint.get());
|
||||
}
|
||||
|
||||
bool VPBTechnique::checkAgainstRandomObjectsConstraints(
|
||||
osg::ref_ptr<osg::Group> constraintGroup, osg::Vec3d origin,
|
||||
osg::Vec3d vertex)
|
||||
{
|
||||
osg::ref_ptr<osgUtil::LineSegmentIntersector> 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<osg::Node> constraint)
|
||||
{
|
||||
|
||||
@@ -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<osg::Node> constraint);
|
||||
virtual void removeRandomObjectsConstraint(osg::ref_ptr<osg::Node> 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<osg::Group> constraintGroup,
|
||||
osg::Vec3d origin, osg::Vec3d vertex);
|
||||
virtual void clearRandomObjectsConstraints();
|
||||
|
||||
OpenThreads::Mutex _writeBufferMutex;
|
||||
|
||||
Reference in New Issue
Block a user