diff --git a/simgear/scene/material/mat.cxx b/simgear/scene/material/mat.cxx index 7b048ae4..57bbc26a 100644 --- a/simgear/scene/material/mat.cxx +++ b/simgear/scene/material/mat.cxx @@ -284,6 +284,11 @@ SGMaterial::read_properties(const SGReaderWriterOptions* options, light_edge_colour[2] = props->getDoubleValue("light-edge-color/b", 1.0); light_edge_colour[3] = props->getDoubleValue("light-edge-color/a", 1.0); + // Line feature texture coordinates + line_feature_tex_x0 = props->getDoubleValue("line-feature-tex-x0", 0.0); + line_feature_tex_x1 = props->getDoubleValue("line-feature-tex-x1", 0.0); + line_feature_offset_m = props->getDoubleValue("line-feature-offset-m", 1.0); + // Building properties building_coverage = props->getDoubleValue("building-coverage", 0.0); building_spacing = props->getDoubleValue("building-spacing-m", 5.0); diff --git a/simgear/scene/material/mat.hxx b/simgear/scene/material/mat.hxx index a2feee4d..88e8cd2f 100644 --- a/simgear/scene/material/mat.hxx +++ b/simgear/scene/material/mat.hxx @@ -176,9 +176,7 @@ public: inline double get_light_coverage () const { return light_coverage; } /** - * Get the edge lighting for Roads etc. - * - * @return The spacing (in m) between individual lights + * Get the edge lighting and other parameters for line features (Roads, Railways) etc. */ inline double get_light_edge_spacing_m () const { return light_edge_spacing_m; } inline double get_light_edge_size_cm() const { return light_edge_size_cm; }; @@ -188,6 +186,10 @@ public: inline double get_light_edge_angle_vertical_deg() const { return light_edge_angle_vertical_deg; }; inline SGVec4f get_light_edge_colour() const { return light_edge_colour; }; inline bool get_light_edge_offset() const { return light_edge_offset; }; + inline double get_line_feature_tex_x0() const { return line_feature_tex_x0; }; + inline double get_line_feature_tex_x1() const { return line_feature_tex_x1; }; + inline double get_line_feature_offset_m() const { return line_feature_offset_m; }; + /** * Get the building coverage. @@ -454,6 +456,9 @@ private: double light_edge_angle_vertical_deg; SGVec4f light_edge_colour; bool light_edge_offset; + double line_feature_tex_x0; + double line_feature_tex_x1; + double line_feature_offset_m; // coverage of buildings double building_coverage; diff --git a/simgear/scene/tgdb/VPBTechnique.cxx b/simgear/scene/tgdb/VPBTechnique.cxx index 38511efc..de34b43b 100644 --- a/simgear/scene/tgdb/VPBTechnique.cxx +++ b/simgear/scene/tgdb/VPBTechnique.cxx @@ -1674,11 +1674,13 @@ void VPBTechnique::applyLineFeatures(BufferData& buffer, Locator* masterLocator) continue; } - const unsigned int xsize = mat->get_xsize(); const unsigned int ysize = mat->get_ysize(); const bool light_edge_offset = mat->get_light_edge_offset(); const double light_edge_spacing = mat->get_light_edge_spacing_m(); const double light_edge_height = mat->get_light_edge_height_m(); + const double x0 = mat->get_line_feature_tex_x0(); + const double x1 = mat->get_line_feature_tex_x1(); + const double elevation_offset_m = mat->get_line_feature_offset_m(); // Generate a geometry for this set of roads. osg::Vec3Array* v = new osg::Vec3Array; @@ -1690,7 +1692,7 @@ void VPBTechnique::applyLineFeatures(BufferData& buffer, Locator* masterLocator) auto lineFeatures = rb->getLineFeatures(); for (auto r = lineFeatures.begin(); r != lineFeatures.end(); ++r) { - if (r->_width > minWidth) generateLineFeature(buffer, masterLocator, *r, world, v, t, n, lights, xsize, ysize, light_edge_spacing, light_edge_height, light_edge_offset); + if (r->_width > minWidth) generateLineFeature(buffer, masterLocator, *r, world, v, t, n, lights, x0, x1, ysize, light_edge_spacing, light_edge_height, light_edge_offset, elevation_offset_m); } if (v->size() == 0) continue; @@ -1736,7 +1738,7 @@ void VPBTechnique::applyLineFeatures(BufferData& buffer, Locator* masterLocator) if (lightbin.getNumLights() > 0) buffer._transform->addChild(createLights(lightbin, osg::Matrix::identity(), _options)); } -void VPBTechnique::generateLineFeature(BufferData& buffer, Locator* masterLocator, LineFeatureBin::LineFeature road, osg::Vec3d modelCenter, osg::Vec3Array* v, osg::Vec2Array* t, osg::Vec3Array* n, osg::Vec3Array* lights, unsigned int xsize, unsigned int ysize, double light_edge_spacing, double light_edge_height, bool light_edge_offset) +void VPBTechnique::generateLineFeature(BufferData& buffer, Locator* masterLocator, LineFeatureBin::LineFeature road, osg::Vec3d modelCenter, osg::Vec3Array* v, osg::Vec2Array* t, osg::Vec3Array* n, osg::Vec3Array* lights, double x0, double x1, unsigned int ysize, double light_edge_spacing, double light_edge_height, bool light_edge_offset, double elevation_offset_m) { // We're in Earth-centered coordinates, so "up" is simply directly away from (0,0,0) osg::Vec3d up = modelCenter; @@ -1794,13 +1796,12 @@ void VPBTechnique::generateLineFeature(BufferData& buffer, Locator* masterLocato spanwise.normalize(); // Define the road extents - const osg::Vec3d a = start - last_spanwise * road._width * 0.5 + up; - const osg::Vec3d b = start + last_spanwise * road._width * 0.5 + up; - const osg::Vec3d c = end - spanwise * road._width * 0.5 + up; - const osg::Vec3d d = end + spanwise * road._width * 0.5 + up; + const osg::Vec3d a = start - last_spanwise * road._width * 0.5 + up * elevation_offset_m; + const osg::Vec3d b = start + last_spanwise * road._width * 0.5 + up * elevation_offset_m; + const osg::Vec3d c = end - spanwise * road._width * 0.5 + up * elevation_offset_m; + const osg::Vec3d d = end + spanwise * road._width * 0.5 + up * elevation_offset_m; // Determine the x and y texture coordinates for the edges - const float xTex = 1.0 / xsize; const float yTexA = yTexBaseA + (c-a).length() / ysize; const float yTexB = yTexBaseB + (d-b).length() / ysize; @@ -1809,17 +1810,17 @@ void VPBTechnique::generateLineFeature(BufferData& buffer, Locator* masterLocato v->push_back(b); v->push_back(c); - t->push_back(osg::Vec2d(0, yTexBaseA)); - t->push_back(osg::Vec2d(xTex, yTexBaseB)); - t->push_back(osg::Vec2d(0, yTexA)); + t->push_back(osg::Vec2d(x0, yTexBaseA)); + t->push_back(osg::Vec2d(x1, yTexBaseB)); + t->push_back(osg::Vec2d(x0, yTexA)); v->push_back(b); v->push_back(d); v->push_back(c); - t->push_back(osg::Vec2d(xTex, yTexBaseB)); - t->push_back(osg::Vec2d(xTex, yTexB)); - t->push_back(osg::Vec2d(0, yTexA)); + t->push_back(osg::Vec2d(x1, yTexBaseB)); + t->push_back(osg::Vec2d(x1, yTexB)); + t->push_back(osg::Vec2d(x0, yTexA)); // Normal is straight from the quad osg::Vec3d normal = -(end-start)^spanwise; @@ -2211,7 +2212,7 @@ void VPBTechnique::generateCoastlineFeature(BufferData& buffer, Locator* masterL t->push_back(osg::Vec2d(xTex, yTexBaseB)); t->push_back(osg::Vec2d(xTex, yTexB)); - t->push_back(osg::Vec2d(0, yTexBaseA)); + t->push_back(osg::Vec2d(0, yTexA)); // Normal is straight from the quad osg::Vec3d normal = -(end-start)^spanwise; diff --git a/simgear/scene/tgdb/VPBTechnique.hxx b/simgear/scene/tgdb/VPBTechnique.hxx index 7fc9577a..e00cb234 100644 --- a/simgear/scene/tgdb/VPBTechnique.hxx +++ b/simgear/scene/tgdb/VPBTechnique.hxx @@ -147,12 +147,14 @@ class VPBTechnique : public TerrainTechnique osg::Vec3Array* v, osg::Vec2Array* t, osg::Vec3Array* n, - osg::Vec3Array* lights, - unsigned int xsize, + osg::Vec3Array* lights, + double x0, + double x1, unsigned int ysize, double light_edge_spacing, double light_edge_height, - bool light_edge_offset); + bool light_edge_offset, + double elevation_offset_m); virtual void applyAreaFeatures(BufferData& buffer, Locator* masterLocator); virtual void generateAreaFeature(BufferData& buffer,