]> git.mxchange.org Git - simgear.git/blobdiff - simgear/scene/tgdb/pt_lights.cxx
pt_lights: softly fade in and out the blinking lights
[simgear.git] / simgear / scene / tgdb / pt_lights.cxx
index 59003fcb36279df4195b39df69c464d76c3959a8..7e123a475da55583f31b65ba2dd59e28ae846fa8 100644 (file)
@@ -159,7 +159,7 @@ gen_standard_light_sprite(void)
 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;
 
@@ -175,7 +175,11 @@ Effect* getLightEffect(float size, const Vec3& attenuation,
     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");
@@ -204,7 +208,7 @@ Effect* getLightEffect(float size, const Vec3& attenuation,
     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())
@@ -232,8 +236,11 @@ Effect* getLightEffect(float size, const Vec3& attenuation,
     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();
 }
 
 
@@ -533,3 +540,35 @@ SGLightFactory::getOdal(const SGLightBin& lights)
 
   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;
+}