]> git.mxchange.org Git - flightgear.git/blobdiff - src/Scenery/scenery.cxx
Property predicate for techniques
[flightgear.git] / src / Scenery / scenery.cxx
index 13cc67ffcadf120ee5bba41040264e703a19969d..6853cfd9b968cdad339c8786c7031fced1e5bbec 100644 (file)
@@ -33,8 +33,9 @@
 #include <simgear/constants.h>
 #include <simgear/debug/logstream.hxx>
 #include <simgear/scene/tgdb/userdata.hxx>
-#include <simgear/math/sg_geodesy.hxx>
-#include <simgear/scene/model/placementtrans.hxx>
+#include <simgear/scene/material/Effect.hxx>
+#include <simgear/scene/material/EffectGeode.hxx>
+#include <simgear/scene/material/Technique.hxx>
 #include <simgear/scene/material/matlib.hxx>
 #include <simgear/scene/util/SGNodeMasks.hxx>
 #include <simgear/scene/util/SGSceneUserData.hxx>
@@ -46,6 +47,7 @@
 #include "scenery.hxx"
 
 using namespace flightgear;
+using namespace simgear;
 
 class FGGroundPickCallback : public SGPickCallback {
 public:
@@ -117,13 +119,6 @@ void FGScenery::bind() {
 void FGScenery::unbind() {
 }
 
-bool
-FGScenery::get_elevation_m(double lat, double lon, double max_alt,
-                           double& alt, const SGMaterial** material)
-{
-  return get_elevation_m(SGGeod::fromDegM(lon, lat, max_alt), alt, material);
-}
-
 bool
 FGScenery::get_cart_elevation_m(const SGVec3d& pos, double max_altoff,
                                 double& alt, const SGMaterial** material)
@@ -163,8 +158,11 @@ FGScenery::get_elevation_m(const SGGeod& geod, double& alt,
       if (alt < elevation) {
         alt = elevation;
         if (material) {
-          const osg::StateSet* stateSet = hit.getDrawable()->getStateSet();
-          *material = SGMaterialLib::findMaterial(stateSet);
+          *material = 0;
+          const EffectGeode* eg
+            = dynamic_cast<const EffectGeode*>(hit.getGeode());
+          if (eg)
+            *material = SGMaterialLib::findMaterial(eg->getEffect());
         }
       }
     }
@@ -212,13 +210,13 @@ FGScenery::get_cart_ground_intersection(const SGVec3d& pos, const SGVec3d& dir,
   return hits;
 }
 
-bool FGScenery::scenery_available(double lat, double lon, double range_m)
+bool FGScenery::scenery_available(const SGGeod& position, double range_m)
 {
-  if(globals->get_tile_mgr()->scenery_available(lat, lon, range_m))
+  if(globals->get_tile_mgr()->scenery_available(position, range_m))
   {
     double elev;
-    get_elevation_m(lat, lon, SG_MAX_ELEVATION_M, elev, 0);
-    SGVec3f p = SGVec3f::fromGeod(SGGeod::fromDegM(lon,lat,elev));
+    get_elevation_m(SGGeod::fromGeodM(position, SG_MAX_ELEVATION_M), elev, 0);
+    SGVec3f p = SGVec3f::fromGeod(SGGeod::fromGeodM(position, elev));
     simgear::CheckSceneryVisitor csnv(getPagerSingleton(), p.osg(), range_m);
     // currently the PagedLODs will not be loaded by the DatabasePager
     // while the splashscreen is there, so CheckSceneryVisitor force-loads
@@ -236,3 +234,48 @@ SceneryPager* FGScenery::getPagerSingleton()
     static osg::ref_ptr<SceneryPager> pager = new SceneryPager;
     return pager.get();
 }
+
+// Effect initialization stuff
+
+class PropertyExpression : public SGExpression<bool>
+{
+public:
+    PropertyExpression(SGPropertyNode* pnode) : _pnode(pnode) {}
+    
+    void eval(bool& value, const expression::Binding*) const
+    {
+        value = _pnode->getValue<bool>();
+    }
+protected:
+    SGPropertyNode_ptr _pnode;
+};
+
+class EffectPropertyListener : public SGPropertyChangeListener
+{
+public:
+    EffectPropertyListener(Technique* tniq) : _tniq(tniq) {}
+    
+    void valueChanged(SGPropertyNode* node)
+    {
+        _tniq->refreshValidity();
+    }
+protected:
+    osg::ref_ptr<Technique> _tniq;
+};
+
+Expression* propertyExpressionParser(const SGPropertyNode* exp,
+                                     expression::Parser* parser)
+{
+    SGPropertyNode_ptr pnode = fgGetNode(exp->getStringValue(), true);
+    PropertyExpression* pexp = new PropertyExpression(pnode);
+    TechniquePredParser* predParser
+        = dynamic_cast<TechniquePredParser*>(parser);
+    if (predParser)
+        pnode->addChangeListener(new EffectPropertyListener(predParser
+                                                            ->getTechnique()));
+    return pexp;
+}
+
+expression::ExpParserRegistrar propertyRegistrar("property",
+                                                 propertyExpressionParser);
+