Runway lights improvements from Sascha Reißner

(Sascha Reißner <reiszner@novaplan.at>)
This commit is contained in:
James Turner 2019-10-20 13:02:30 +01:00
parent de3625d992
commit 4b1a53367f
3 changed files with 82 additions and 69 deletions

View File

@ -903,12 +903,7 @@ public:
} }
Effect* runwayEffect = 0; Effect* runwayEffect = 0;
if (runwayLights.getNumLights() > 0 if (runwayLights.getNumLights() > 0 || taxiLights.getNumLights() > 0) {
|| !rabitLights.empty()
|| !reilLights.empty()
|| !odalLights.empty()
|| taxiLights.getNumLights() > 0) {
runwayEffect = getLightEffect(16, osg::Vec3(1, 0.001, 0.0002), 1, 16, true, _options); runwayEffect = getLightEffect(16, osg::Vec3(1, 0.001, 0.0002), 1, 16, true, _options);
} }
@ -918,49 +913,38 @@ public:
|| !odalLights.empty() || !odalLights.empty()
|| !holdshortLights.empty() || !holdshortLights.empty()
|| !guardLights.empty()) { || !guardLights.empty()) {
osg::Group* rwyLights = new osg::Group;
osg::StateSet* ss = lightManager->getRunwayLightStateSet(); osg::Group* rwyLightsGroup = new osg::Group;
rwyLights->setStateSet(ss); rwyLightsGroup->setStateSet(lightManager->getRunwayLightStateSet());
rwyLights->setNodeMask(RUNWAYLIGHTS_BIT); rwyLightsGroup->setNodeMask(RUNWAYLIGHTS_BIT);
if (runwayLights.getNumLights() != 0) {
EffectGeode* geode = new EffectGeode;
geode->setEffect(runwayEffect);
osg::Drawable* rldraw = SGLightFactory::getLights(runwayLights);
geode->addDrawable( rldraw );
rwyLights->addChild(geode);
}
SGDirectionalLightListBin::const_iterator i; SGDirectionalLightListBin::const_iterator i;
for (i = rabitLights.begin();
i != rabitLights.end(); ++i) { for (i = rabitLights.begin() ; i != rabitLights.end() ; ++i) {
osg::Node* seqNode = SGLightFactory::getSequenced(*i, _options); rwyLightsGroup->addChild(SGLightFactory::getSequenced(*i, _options));
rwyLights->addChild( seqNode );
} }
for (i = reilLights.begin(); for (i = reilLights.begin() ; i != reilLights.end() ; ++i) {
i != reilLights.end(); ++i) { rwyLightsGroup->addChild(SGLightFactory::getReil(*i, _options));
osg::Node* seqNode = SGLightFactory::getSequenced(*i, _options);
rwyLights->addChild(seqNode);
} }
for (i = holdshortLights.begin(); for (i = holdshortLights.begin() ; i != holdshortLights.end() ; ++i) {
i != holdshortLights.end(); ++i) { rwyLightsGroup->addChild(SGLightFactory::getHoldShort(*i, _options));
osg::Node* seqNode = SGLightFactory::getHoldShort(*i, _options);
rwyLights->addChild(seqNode);
} }
for (i = guardLights.begin(); for (i = guardLights.begin() ; i != guardLights.end() ; ++i) {
i != guardLights.end(); ++i) { rwyLightsGroup->addChild(SGLightFactory::getGuard(*i, _options));
osg::Node* seqNode = SGLightFactory::getGuard(*i, _options);
rwyLights->addChild(seqNode);
} }
SGLightListBin::const_iterator j; SGLightListBin::const_iterator j;
for (j = odalLights.begin(); for (j = odalLights.begin() ; j != odalLights.end() ; ++j) {
j != odalLights.end(); ++j) { rwyLightsGroup->addChild(SGLightFactory::getOdal(*j, _options));
osg::Node* seqNode = SGLightFactory::getOdal(*j, _options);
rwyLights->addChild(seqNode);
} }
lightGroup->addChild(rwyLights);
if (runwayLights.getNumLights() > 0) {
osg::ref_ptr<EffectGeode> geode = new EffectGeode;
geode->setEffect(runwayEffect);
geode->addDrawable(SGLightFactory::getLights(runwayLights));
rwyLightsGroup->addChild(geode);
}
lightGroup->addChild(rwyLightsGroup);
} }
if (taxiLights.getNumLights() > 0) { if (taxiLights.getNumLights() > 0) {

View File

@ -214,8 +214,7 @@ SGLightFactory::getLights(const SGLightBin& lights, unsigned inc, float alphaOff
geometry->setDataVariance(osg::Object::STATIC); geometry->setDataVariance(osg::Object::STATIC);
geometry->setVertexArray(vertices); geometry->setVertexArray(vertices);
geometry->setNormalBinding(osg::Geometry::BIND_OFF); geometry->setNormalBinding(osg::Geometry::BIND_OFF);
geometry->setColorArray(colors); geometry->setColorArray(colors, osg::Array::BIND_PER_VERTEX);
geometry->setColorBinding(osg::Geometry::BIND_PER_VERTEX);
osg::DrawArrays* drawArrays; osg::DrawArrays* drawArrays;
drawArrays = new osg::DrawArrays(osg::PrimitiveSet::POINTS, drawArrays = new osg::DrawArrays(osg::PrimitiveSet::POINTS,
@ -275,7 +274,7 @@ SGLightFactory::getLights(const SGDirectionalLightBin& lights)
//stateSet->setMode(GL_LIGHTING, osg::StateAttribute::OFF); //stateSet->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
osg::DrawArrays* drawArrays; osg::DrawArrays* drawArrays;
drawArrays = new osg::DrawArrays(osg::PrimitiveSet::POINTS, drawArrays = new osg::DrawArrays(osg::PrimitiveSet::TRIANGLES,
0, vertices->size()); 0, vertices->size());
geometry->addPrimitiveSet(drawArrays); geometry->addPrimitiveSet(drawArrays);
return geometry; return geometry;
@ -370,18 +369,46 @@ SGLightFactory::getSequenced(const SGDirectionalLightBin& lights, const SGReader
// generate a repeatable random seed // generate a repeatable random seed
sg_srandom(unsigned(lights.getLight(0).position[0])); sg_srandom(unsigned(lights.getLight(0).position[0]));
float flashTime = 2e-2 + 5e-3*sg_random(); float flashTime = 0.065 + 0.003 * sg_random();
osg::Sequence* sequence = new osg::Sequence; osg::Sequence* sequence = new osg::Sequence;
sequence->setDefaultTime(flashTime); sequence->setDefaultTime(flashTime);
Effect* effect = getLightEffect(10.0f, osg::Vec3(1.0, 0.0001, 0.00000001), Effect* effect = getLightEffect(24.0f, osg::Vec3(1.0, 0.0001, 0.000001),
6.0f, 10.0f, true, options); 1.0f, 24.0f, true, options);
for (int i = lights.getNumLights() - 1; 0 <= i; --i) { for (int i = lights.getNumLights() - 1; 0 <= i; --i) {
EffectGeode* egeode = new EffectGeode; EffectGeode* egeode = new EffectGeode;
egeode->setEffect(effect); egeode->setEffect(effect);
egeode->addDrawable(getLightDrawable(lights.getLight(i))); egeode->addDrawable(getLightDrawable(lights.getLight(i)));
sequence->addChild(egeode, flashTime); sequence->addChild(egeode, flashTime);
} }
sequence->addChild(new osg::Group, 1 + 1e-1*sg_random()); sequence->addChild(new osg::Group, 1.9 + (0.1 * sg_random()) - (lights.getNumLights() * flashTime));
sequence->setInterval(osg::Sequence::LOOP, 0, -1);
sequence->setDuration(1.0f, -1);
sequence->setMode(osg::Sequence::START);
sequence->setSync(true);
return sequence;
}
osg::Node*
SGLightFactory::getReil(const SGDirectionalLightBin& lights, const SGReaderWriterOptions* options)
{
if (lights.getNumLights() <= 0)
return 0;
// generate a repeatable random seed
sg_srandom(unsigned(lights.getLight(0).position[0]));
float flashTime = 0.065 + 0.003 * sg_random();
osg::Sequence* sequence = new osg::Sequence;
sequence->setDefaultTime(flashTime);
Effect* effect = getLightEffect(24.0f, osg::Vec3(1.0, 0.0001, 0.000001),
1.0f, 24.0f, true, options);
EffectGeode* egeode = new EffectGeode;
egeode->setEffect(effect);
for (int i = lights.getNumLights() - 1; 0 <= i; --i) {
egeode->addDrawable(getLightDrawable(lights.getLight(i)));
}
sequence->addChild(egeode, flashTime);
sequence->addChild(new osg::Group, 1.9 + 0.1 * sg_random() - flashTime);
sequence->setInterval(osg::Sequence::LOOP, 0, -1); sequence->setInterval(osg::Sequence::LOOP, 0, -1);
sequence->setDuration(1.0f, -1); sequence->setDuration(1.0f, -1);
sequence->setMode(osg::Sequence::START); sequence->setMode(osg::Sequence::START);
@ -397,11 +424,11 @@ SGLightFactory::getOdal(const SGLightBin& lights, const SGReaderWriterOptions* o
// generate a repeatable random seed // generate a repeatable random seed
sg_srandom(unsigned(lights.getLight(0).position[0])); sg_srandom(unsigned(lights.getLight(0).position[0]));
float flashTime = 2e-2 + 5e-3*sg_random(); float flashTime = 0.065 + 0.003 * sg_random();
osg::Sequence* sequence = new osg::Sequence; osg::Sequence* sequence = new osg::Sequence;
sequence->setDefaultTime(flashTime); sequence->setDefaultTime(flashTime);
Effect* effect = getLightEffect(10.0f, osg::Vec3(1.0, 0.0001, 0.00000001), Effect* effect = getLightEffect(20.0f, osg::Vec3(1.0, 0.0001, 0.000001),
6.0, 10.0, false, options); 1.0f, 20.0f, false, options);
// centerline lights // centerline lights
for (int i = lights.getNumLights() - 1; i >= 2; i--) { for (int i = lights.getNumLights() - 1; i >= 2; i--) {
EffectGeode* egeode = new EffectGeode; EffectGeode* egeode = new EffectGeode;
@ -409,18 +436,18 @@ SGLightFactory::getOdal(const SGLightBin& lights, const SGReaderWriterOptions* o
egeode->addDrawable(getLightDrawable(lights.getLight(i))); egeode->addDrawable(getLightDrawable(lights.getLight(i)));
sequence->addChild(egeode, flashTime); sequence->addChild(egeode, flashTime);
} }
// add extra empty group for a break
sequence->addChild(new osg::Group, 4 * flashTime);
// runway end lights // runway end lights
osg::Group* group = new osg::Group;
for (unsigned i = 0; i < 2; ++i) {
EffectGeode* egeode = new EffectGeode; EffectGeode* egeode = new EffectGeode;
egeode->setEffect(effect); egeode->setEffect(effect);
for (unsigned i = 0; i < 2; ++i) {
egeode->addDrawable(getLightDrawable(lights.getLight(i))); egeode->addDrawable(getLightDrawable(lights.getLight(i)));
group->addChild(egeode);
} }
sequence->addChild(group, flashTime); sequence->addChild(egeode, flashTime);
// add an extra empty group for a break // add an extra empty group for a break
sequence->addChild(new osg::Group, 2 + 1e-1*sg_random()); sequence->addChild(new osg::Group, 1.9 + (0.1 * sg_random()) - ((lights.getNumLights() + 2) * flashTime));
sequence->setInterval(osg::Sequence::LOOP, 0, -1); sequence->setInterval(osg::Sequence::LOOP, 0, -1);
sequence->setDuration(1.0f, -1); sequence->setDuration(1.0f, -1);
sequence->setMode(osg::Sequence::START); sequence->setMode(osg::Sequence::START);
@ -437,23 +464,22 @@ SGLightFactory::getHoldShort(const SGDirectionalLightBin& lights, const SGReader
return 0; return 0;
sg_srandom(unsigned(lights.getLight(0).position[0])); sg_srandom(unsigned(lights.getLight(0).position[0]));
float flashTime = 1 + 0.1 * sg_random(); float flashTime = 0.9 + 0.2 * sg_random();
osg::Sequence* sequence = new osg::Sequence; osg::Sequence* sequence = new osg::Sequence;
// start with lights off // start with lights off
sequence->addChild(new osg::Group, flashTime); sequence->addChild(new osg::Group, 0.2);
// ...and increase the lights in steps // ...and increase the lights in steps
for (int i = 2; i < 7; i+=2) { for (int i = 0; i < 5; i++) {
Effect* effect = getLightEffect(i, osg::Vec3(1, 0.001, 0.000002), Effect* effect = getLightEffect(12.0f + i, osg::Vec3(1, 0.001, 0.0002),
0.0f, i, true, options); 1.0f, 12.0f + i, true, options);
EffectGeode* egeode = new EffectGeode; EffectGeode* egeode = new EffectGeode;
egeode->setEffect(effect);
for (unsigned int j = 0; j < lights.getNumLights(); ++j) { for (unsigned int j = 0; j < lights.getNumLights(); ++j) {
egeode->addDrawable(getLightDrawable(lights.getLight(j))); egeode->addDrawable(getLightDrawable(lights.getLight(j)));
egeode->setEffect(effect);
} }
sequence->addChild(egeode, (i==6) ? flashTime : 0.1); sequence->addChild(egeode, (i==4) ? flashTime : 0.1);
} }
sequence->setInterval(osg::Sequence::SWING, 0, -1); sequence->setInterval(osg::Sequence::SWING, 0, -1);
sequence->setDuration(1.0f, -1); sequence->setDuration(1.0f, -1);
sequence->setMode(osg::Sequence::START); sequence->setMode(osg::Sequence::START);
@ -470,11 +496,11 @@ SGLightFactory::getGuard(const SGDirectionalLightBin& lights, const SGReaderWrit
// generate a repeatable random seed // generate a repeatable random seed
sg_srandom(unsigned(lights.getLight(0).position[0])); sg_srandom(unsigned(lights.getLight(0).position[0]));
float flashTime = 1.0f + 1*sg_random(); float flashTime = 0.9 + 0.2 * sg_random();
osg::Sequence* sequence = new osg::Sequence; osg::Sequence* sequence = new osg::Sequence;
sequence->setDefaultTime(flashTime); sequence->setDefaultTime(flashTime);
Effect* effect = getLightEffect(10.0f, osg::Vec3(1.0, 0.001, 0.000002), Effect* effect = getLightEffect(16.0f, osg::Vec3(1.0, 0.001, 0.0002),
0.0f, 8.0f, true, options); 1.0f, 16.0f, true, options);
for (unsigned int i = 0; i < lights.getNumLights(); ++i) { for (unsigned int i = 0; i < lights.getNumLights(); ++i) {
EffectGeode* egeode = new EffectGeode; EffectGeode* egeode = new EffectGeode;
egeode->setEffect(effect); egeode->setEffect(effect);

View File

@ -87,6 +87,9 @@ public:
static osg::Node* static osg::Node*
getSequenced(const SGDirectionalLightBin& lights, const simgear::SGReaderWriterOptions* options); getSequenced(const SGDirectionalLightBin& lights, const simgear::SGReaderWriterOptions* options);
static osg::Node*
getReil(const SGDirectionalLightBin& lights, const simgear::SGReaderWriterOptions* options);
static osg::Node* static osg::Node*
getOdal(const SGLightBin& lights, const simgear::SGReaderWriterOptions* options); getOdal(const SGLightBin& lights, const simgear::SGReaderWriterOptions* options);