WS30: Lighting for roads
Using attributes on the LINE_FEATURE_LIST we now generate lighting for roads.
This commit is contained in:
parent
1174124144
commit
fafa259c1d
@ -271,6 +271,18 @@ SGMaterial::read_properties(const SGReaderWriterOptions* options,
|
||||
mipmap = props->getBoolValue("mipmap", true);
|
||||
light_coverage = props->getDoubleValue("light-coverage", 0.0);
|
||||
|
||||
light_edge_spacing_m = props->getDoubleValue("light-edge-spacing-m", 0.0);
|
||||
light_edge_size_cm = props->getDoubleValue("light-edge-size-cm", 40.0);
|
||||
light_edge_height_m = props->getDoubleValue("light-edge-height-m", 5.0);
|
||||
light_edge_intensity_cd = props->getDoubleValue("light-edge-intensity-cd", 50.0);
|
||||
light_edge_angle_horizontal_deg = props->getDoubleValue("light-edge-angle-horizontal-deg", 360.0);
|
||||
light_edge_angle_vertical_deg = props->getDoubleValue("light-edge-angle-vertical-deg", 360.0);
|
||||
|
||||
light_edge_colour[0] = props->getDoubleValue("light-edge-color/r", 1.0);
|
||||
light_edge_colour[1] = props->getDoubleValue("light-edge-color/g", 1.0);
|
||||
light_edge_colour[2] = props->getDoubleValue("light-edge-color/b", 1.0);
|
||||
light_edge_colour[3] = props->getDoubleValue("light-edge-color/a", 1.0);
|
||||
|
||||
// Building properties
|
||||
building_coverage = props->getDoubleValue("building-coverage", 0.0);
|
||||
building_spacing = props->getDoubleValue("building-spacing-m", 5.0);
|
||||
@ -437,6 +449,15 @@ SGMaterial::init ()
|
||||
|
||||
mipmap = true;
|
||||
light_coverage = 0.0;
|
||||
|
||||
light_edge_spacing_m = 0.0;
|
||||
light_edge_size_cm = 50.0;
|
||||
light_edge_height_m = 5.0;
|
||||
light_edge_intensity_cd = 100.0;
|
||||
light_edge_angle_horizontal_deg = 360.0;
|
||||
light_edge_angle_vertical_deg = 360.0;
|
||||
light_edge_colour = SGVec4f(1.0,1.0,1.0,1.0);
|
||||
|
||||
building_coverage = 0.0;
|
||||
|
||||
shininess = 1.0;
|
||||
|
@ -175,6 +175,19 @@ 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
|
||||
*/
|
||||
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; };
|
||||
inline double get_light_edge_height_m() const { return light_edge_height_m; };
|
||||
inline double get_light_edge_intensity_cd() const { return light_edge_intensity_cd; };
|
||||
inline double get_light_edge_angle_horizontal_deg() const { return light_edge_angle_horizontal_deg; };
|
||||
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; };
|
||||
|
||||
/**
|
||||
* Get the building coverage.
|
||||
*
|
||||
@ -430,6 +443,15 @@ private:
|
||||
|
||||
// coverage of night lighting.
|
||||
double light_coverage;
|
||||
|
||||
// Edge lighting
|
||||
double light_edge_spacing_m;
|
||||
double light_edge_size_cm;
|
||||
double light_edge_height_m;
|
||||
double light_edge_intensity_cd;
|
||||
double light_edge_angle_horizontal_deg;
|
||||
double light_edge_angle_vertical_deg;
|
||||
SGVec4f light_edge_colour;
|
||||
|
||||
// coverage of buildings
|
||||
double building_coverage;
|
||||
|
@ -213,7 +213,7 @@ osg::Drawable* createDrawable(LightBin& lightList, const osg::Matrix& transform)
|
||||
osg::Vec3Array* direction_params_1 = new osg::Vec3Array;
|
||||
osg::Vec2Array* direction_params_2 = new osg::Vec2Array;
|
||||
|
||||
for (int lightIdx = 0; lightIdx < lightList.getNumLights(); lightIdx++) {
|
||||
for (unsigned int lightIdx = 0; lightIdx < lightList.getNumLights(); lightIdx++) {
|
||||
const auto l = lightList.getLight(lightIdx);
|
||||
vertices->push_back(toOsg(l.position) * transform);
|
||||
light_params->push_back(toOsg(SGVec3f(l.size, l.intensity, l.on_period)));
|
||||
|
@ -26,6 +26,7 @@
|
||||
|
||||
#include <simgear/math/SGMath.hxx>
|
||||
#include <simgear/scene/material/EffectGeode.hxx>
|
||||
#include <simgear/scene/tgdb/LightBin.hxx>
|
||||
|
||||
namespace simgear
|
||||
{
|
||||
|
@ -1650,6 +1650,7 @@ void VPBTechnique::applyLineFeatures(BufferData& buffer, Locator* masterLocator)
|
||||
const osg::Vec3d world = buffer._transform->getMatrix().getTrans();
|
||||
const SGGeod loc = SGGeod::fromCart(toSG(world));
|
||||
const SGBucket bucket = SGBucket(loc);
|
||||
string material_name = "";
|
||||
auto roads = std::find_if(_lineFeatureLists.begin(), _lineFeatureLists.end(), [bucket](BucketLineFeatureBinList b){return (b.first == bucket);});
|
||||
|
||||
if (roads == _lineFeatureLists.end()) return;
|
||||
@ -1661,7 +1662,11 @@ void VPBTechnique::applyLineFeatures(BufferData& buffer, Locator* masterLocator)
|
||||
|
||||
for (auto rb = roadBins.begin(); rb != roadBins.end(); ++rb)
|
||||
{
|
||||
mat = matcache->find(rb->getMaterial());
|
||||
if (material_name != rb->getMaterial()) {
|
||||
// Cache the material to reduce lookups.
|
||||
mat = matcache->find(rb->getMaterial());
|
||||
material_name = rb->getMaterial();
|
||||
}
|
||||
|
||||
if (!mat) {
|
||||
SG_LOG(SG_TERRAIN, SG_ALERT, "Unable to find material " << rb->getMaterial() << " at " << loc << " " << bucket);
|
||||
@ -1670,17 +1675,20 @@ void VPBTechnique::applyLineFeatures(BufferData& buffer, Locator* masterLocator)
|
||||
|
||||
unsigned int xsize = mat->get_xsize();
|
||||
unsigned int ysize = mat->get_ysize();
|
||||
double light_edge_spacing = mat->get_light_edge_spacing_m();
|
||||
double light_edge_height = mat->get_light_edge_height_m();
|
||||
|
||||
// Generate a geometry for this set of roads.
|
||||
osg::Vec3Array* v = new osg::Vec3Array;
|
||||
osg::Vec2Array* t = new osg::Vec2Array;
|
||||
osg::Vec3Array* n = new osg::Vec3Array;
|
||||
osg::Vec4Array* c = new osg::Vec4Array;
|
||||
osg::Vec3Array* lights = new osg::Vec3Array;
|
||||
|
||||
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, xsize, ysize);
|
||||
if (r->_width > minWidth) generateLineFeature(buffer, masterLocator, *r, world, v, t, n, lights, xsize, ysize, light_edge_spacing, light_edge_height);
|
||||
}
|
||||
|
||||
if (v->size() == 0) continue;
|
||||
@ -1705,11 +1713,29 @@ void VPBTechnique::applyLineFeatures(BufferData& buffer, Locator* masterLocator)
|
||||
geode->setNodeMask(SG_NODEMASK_TERRAIN_BIT);
|
||||
buffer._transform->addChild(geode);
|
||||
addVegetationConstraint(geode);
|
||||
|
||||
if (lights->size() > 0) {
|
||||
LightBin lightbin;
|
||||
const double size = mat->get_light_edge_size_cm();
|
||||
const double intensity = mat->get_light_edge_intensity_cd();
|
||||
const SGVec4f color = mat->get_light_edge_colour();
|
||||
const double horiz = mat->get_light_edge_angle_horizontal_deg();
|
||||
const double vertical = mat->get_light_edge_angle_vertical_deg();
|
||||
// Assume street lights point down.
|
||||
osg::Vec3d up = world;
|
||||
up.normalize();
|
||||
const SGVec3f direction = toSG(- (osg::Vec3f) up);
|
||||
|
||||
std::for_each(lights->begin(), lights->end(),
|
||||
[&, size, intensity, color, direction, horiz, vertical] (osg::Vec3f p) { lightbin.insert(toSG(p), size, intensity, 1, color, direction, horiz, vertical); } );
|
||||
|
||||
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, unsigned int xsize, unsigned int ysize)
|
||||
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)
|
||||
{
|
||||
// We're in Earth-centered coordinates, so "up" is simply directly away from (0,0,0)
|
||||
osg::Vec3d up = modelCenter;
|
||||
@ -1753,6 +1779,7 @@ void VPBTechnique::generateLineFeature(BufferData& buffer, Locator* masterLocato
|
||||
|
||||
float yTexBaseA = 0.0f;
|
||||
float yTexBaseB = 0.0f;
|
||||
float last_light_distance = 0.0f;
|
||||
|
||||
for (; iter != roadPoints.end(); iter++) {
|
||||
|
||||
@ -1802,6 +1829,35 @@ void VPBTechnique::generateLineFeature(BufferData& buffer, Locator* masterLocato
|
||||
yTexBaseA = yTexA;
|
||||
yTexBaseB = yTexB;
|
||||
last_spanwise = spanwise;
|
||||
float edge_length = (c-a).length() + last_light_distance;
|
||||
|
||||
if ((road._attributes == 1) && (light_edge_spacing > 0.0)) {
|
||||
// We have some edge lighting. Traverse edges a-c and b-d adding lights as appropriate.
|
||||
if (edge_length > light_edge_spacing) {
|
||||
int num_lights = (int) floor(edge_length / light_edge_spacing);
|
||||
|
||||
// Get a pair of vector to travel along the edges
|
||||
osg::Vec3f p1 = (c-a);
|
||||
p1.normalize();
|
||||
p1 = p1 * light_edge_spacing;
|
||||
|
||||
osg::Vec3f p2 = (d-b);
|
||||
p2.normalize();
|
||||
p2 = p2 * light_edge_spacing;
|
||||
|
||||
for (int i = 1; i <= num_lights; i++) {
|
||||
// Place the lights, 5m above the road itself on either side.
|
||||
lights->push_back((osg::Vec3f) a + p1 * (i - last_light_distance / light_edge_spacing) + up * (light_edge_height + 1.0));
|
||||
lights->push_back((osg::Vec3f) b + p2 * (i - last_light_distance / light_edge_spacing) + up * (light_edge_height + 1.0));
|
||||
}
|
||||
|
||||
last_light_distance = fmodf(edge_length, light_edge_spacing);
|
||||
} else {
|
||||
// For small road segments, keep track of the distance since the last light so we generate
|
||||
// some lights on curves.
|
||||
last_light_distance += edge_length;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include <simgear/scene/material/EffectGeode.hxx>
|
||||
#include <simgear/scene/material/matlib.hxx>
|
||||
#include <simgear/scene/tgdb/AreaFeatureBin.hxx>
|
||||
#include <simgear/scene/tgdb/LightBin.hxx>
|
||||
#include <simgear/scene/tgdb/LineFeatureBin.hxx>
|
||||
#include <simgear/scene/tgdb/CoastlineBin.hxx>
|
||||
|
||||
@ -146,8 +147,11 @@ class VPBTechnique : public TerrainTechnique
|
||||
osg::Vec3Array* v,
|
||||
osg::Vec2Array* t,
|
||||
osg::Vec3Array* n,
|
||||
osg::Vec3Array* lights,
|
||||
unsigned int xsize,
|
||||
unsigned int ysize);
|
||||
unsigned int ysize,
|
||||
double light_edge_spacing,
|
||||
double light_edge_height);
|
||||
|
||||
virtual void applyAreaFeatures(BufferData& buffer, Locator* masterLocator);
|
||||
virtual void generateAreaFeature(BufferData& buffer,
|
||||
|
Loading…
Reference in New Issue
Block a user