namespace
{
typedef boost::tuple<float, osg::Vec3, float, float, bool> PointParams;
-typedef std::map<PointParams, ref_ptr<Effect> > EffectMap;
+typedef std::map<PointParams, observer_ptr<Effect> > EffectMap;
EffectMap effectMap;
ScopedLock<Mutex> lock(lightMutex);
EffectMap::iterator eitr = effectMap.find(pointParams);
if (eitr != effectMap.end())
- return eitr->second.get();
+ {
+ ref_ptr<Effect> effect;
+ if (eitr->second.lock(effect))
+ return effect.release();
+ }
// Basic stuff; no sprite or attenuation support
Pass *basicPass = new Pass;
- basicPass->setRenderBinDetails(POINT_LIGHTS_BIN, "RenderBin");
+ basicPass->setRenderBinDetails(POINT_LIGHTS_BIN, "DepthSortedBin");
basicPass->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
StateAttributeFactory *attrFact = StateAttributeFactory::instance();
basicPass->setAttributeAndModes(attrFact->getStandardBlendFunc());
spritePass->setTextureAttribute(0, attrFact->getStandardTexEnv());
Pass *combinedPass = clone(spritePass, CopyOp::SHALLOW_COPY);
combinedPass->setAttributeAndModes(point);
- Effect* effect = new Effect;
+ ref_ptr<Effect> effect = new Effect;
std::vector<std::string> parameterExtensions;
if (SGSceneFeatures::instance()->getEnablePointSpriteLights())
Technique* basicTniq = new Technique(true);
basicTniq->passes.push_back(basicPass);
effect->techniques.push_back(basicTniq);
- effectMap.insert(std::make_pair(pointParams, effect));
- return effect;
+ if (eitr == effectMap.end())
+ effectMap.insert(std::make_pair(pointParams, effect));
+ else
+ eitr->second = effect; // update existing, but empty observer
+ return effect.release();
}
if (!simpleLightSS.valid()) {
StateAttributeFactory *attrFact = StateAttributeFactory::instance();
simpleLightSS = new StateSet;
- simpleLightSS->setRenderBinDetails(POINT_LIGHTS_BIN, "RenderBin");
+ simpleLightSS->setRenderBinDetails(POINT_LIGHTS_BIN, "DepthSortedBin");
simpleLightSS->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
simpleLightSS->setAttributeAndModes(attrFact->getStandardBlendFunc());
simpleLightSS->setAttributeAndModes(attrFact->getStandardAlphaFunc());
return 0;
osg::StateSet* stateSet = drawable->getOrCreateStateSet();
- stateSet->setRenderBinDetails(POINT_LIGHTS_BIN, "RenderBin");
+ stateSet->setRenderBinDetails(POINT_LIGHTS_BIN, "DepthSortedBin");
stateSet->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
osg::BlendFunc* blendFunc = new osg::BlendFunc;
float flashTime = 2e-2 + 5e-3*sg_random();
osg::Sequence* sequence = new osg::Sequence;
sequence->setDefaultTime(flashTime);
- Effect* effect = getLightEffect(40.0f, osg::Vec3(1.0, 0.0001, 0.00000001),
- 10.0f, 40.0f, true);
+ Effect* effect = getLightEffect(10.0f, osg::Vec3(1.0, 0.0001, 0.00000001),
+ 6.0f, 10.0f, true);
for (int i = lights.getNumLights() - 1; 0 <= i; --i) {
EffectGeode* egeode = new EffectGeode;
egeode->setEffect(effect);
float flashTime = 2e-2 + 5e-3*sg_random();
osg::Sequence* sequence = new osg::Sequence;
sequence->setDefaultTime(flashTime);
- Effect* effect = getLightEffect(40.0f, osg::Vec3(1.0, 0.0001, 0.00000001),
- 10.0, 40.0, false);
+ Effect* effect = getLightEffect(10.0f, osg::Vec3(1.0, 0.0001, 0.00000001),
+ 6.0, 10.0, false);
// centerline lights
for (int i = lights.getNumLights() - 1; 2 <= i; --i) {
EffectGeode* egeode = new EffectGeode;
return sequence;
}
+
+// Blinking hold short line lights
+osg::Node*
+SGLightFactory::getHoldShort(const SGDirectionalLightBin& lights)
+{
+ if (lights.getNumLights() < 2)
+ return 0;
+
+ sg_srandom(unsigned(lights.getLight(0).position[0]));
+ float flashTime = 2 + 0.1 * sg_random();
+ osg::Sequence* sequence = new osg::Sequence;
+
+ // start with lights off
+ sequence->addChild(new osg::Group, flashTime);
+ // ...and increase the lights in steps
+ for (int i = 2; i < 7; i+=2) {
+ Effect* effect = getLightEffect(i, osg::Vec3(1, 0.001, 0.000002),
+ 0, i, true);
+ EffectGeode* egeode = new EffectGeode;
+ for (unsigned int j = 0; j < lights.getNumLights(); ++j) {
+ egeode->addDrawable(getLightDrawable(lights.getLight(j)));
+ egeode->setEffect(effect);
+ }
+ sequence->addChild(egeode, (i==6) ? flashTime : 0.1);
+ }
+
+ sequence->setInterval(osg::Sequence::SWING, 0, -1);
+ sequence->setDuration(1.0f, -1);
+ sequence->setMode(osg::Sequence::START);
+
+ return sequence;
+}