#include <simgear/debug/logstream.hxx>
#include <simgear/scene/util/RenderConstants.hxx>
#include <simgear/scene/util/SGEnlargeBoundingBox.hxx>
+#include <simgear/scene/util/OsgMath.hxx>
#include <simgear/scene/util/StateAttributeFactory.hxx>
#include <simgear/scene/material/Effect.hxx>
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, "DepthSortedBin");
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();
}
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;
+}