]> git.mxchange.org Git - simgear.git/commitdiff
Evaluate <condition> statements in materials.xml at tile loading time
authorStuart Buchanan <stuart_d_buchanan@yahoo.co.uk>
Fri, 2 Mar 2012 23:04:18 +0000 (23:04 +0000)
committerStuart Buchanan <stuart_d_buchanan@yahoo.co.uk>
Fri, 2 Mar 2012 23:04:18 +0000 (23:04 +0000)
rather than on startup.  This will allow changing between winter and
summer textures in-sim, and also allow more interesting regional
textures to be defined.

simgear/scene/material/mat.cxx
simgear/scene/material/mat.hxx
simgear/scene/material/matlib.cxx
simgear/scene/material/matlib.hxx

index defab591f6992cdf932c43a2174c1cf7780d99cc..cf68c2d65d9cc4606e289f6be6c87472841615a4 100644 (file)
@@ -40,6 +40,7 @@
 #include <osg/ShadeModel>
 #include <osg/StateSet>
 #include <osg/TexEnv>
+#include <osg/Texture>
 #include <osg/Texture2D>
 #include <osgDB/ReaderWriter>
 #include <osgDB/ReadFile>
@@ -87,21 +88,23 @@ void SGMaterial::_internal_state::add_texture(const std::string &t, int i)
 }
 
 SGMaterial::SGMaterial( const SGReaderWriterOptions* options,
-                        const SGPropertyNode *props )
+                        const SGPropertyNode *props,
+                        SGPropertyNode *prop_root )
 {
     init();
-    read_properties( options, props );
+    read_properties( options, props, prop_root );
     buildEffectProperties(options);
 }
 
 SGMaterial::SGMaterial( const osgDB::ReaderWriter::Options* options,
-                        const SGPropertyNode *props )
+                        const SGPropertyNode *props, 
+                        SGPropertyNode *prop_root)
 {
     osg::ref_ptr<const SGReaderWriterOptions> sgOptions;
     if (options)
         sgOptions = new SGReaderWriterOptions(*options);
     init();
-    read_properties( sgOptions.get(), props );
+    read_properties( sgOptions.get(), props, prop_root);
     buildEffectProperties(sgOptions.get());
 }
 
@@ -116,7 +119,8 @@ SGMaterial::~SGMaterial (void)
 
 void
 SGMaterial::read_properties(const SGReaderWriterOptions* options,
-                            const SGPropertyNode *props)
+                            const SGPropertyNode *props,
+                            SGPropertyNode *prop_root)
 {
   std::vector<bool> dds;
   std::vector<SGPropertyNode_ptr> textures = props->getChildren("texture");
@@ -226,6 +230,12 @@ SGMaterial::read_properties(const SGReaderWriterOptions* options,
         }
         
         object_mask->setImage(image);
+        
+        // We force the filtering to be nearest, as the red channel (rotation)
+        // in particular, doesn't make sense to be interpolated between pixels.
+        object_mask->setFilter(osg::Texture::MIN_FILTER, osg::Texture::NEAREST);
+        object_mask->setFilter(osg::Texture::MAG_FILTER, osg::Texture::NEAREST);
+        
         object_mask->setDataVariance(osg::Object::STATIC);
         object_mask->setWrap(osg::Texture::WRAP_S, osg::Texture::REPEAT);
         object_mask->setWrap(osg::Texture::WRAP_T, osg::Texture::REPEAT);
@@ -309,6 +319,14 @@ SGMaterial::read_properties(const SGReaderWriterOptions* options,
     if (name)
       glyphs[name] = new SGMaterialGlyph(glyph_nodes[i]);
   }
+  
+  // Read conditions node  
+  const SGPropertyNode *conditionNode = props->getChild("condition");
+  if (conditionNode) {
+    condition = sgReadCondition(prop_root, conditionNode);
+  } 
+  
+  
 }
 
 
index c6da610191c0e9521288fc0bd4d5755687be1543..c3b7b3c3986f7483778b7541ce6d2fc40f7c26c5 100644 (file)
@@ -52,6 +52,7 @@ class StateSet;
 #include <simgear/props/props.hxx>
 #include <simgear/structure/SGSharedPtr.hxx>
 #include <simgear/scene/util/SGSceneFeatures.hxx>
+#include <simgear/props/condition.hxx>
 
 #include "matmodel.hxx"
 
@@ -88,10 +89,13 @@ public:
    * state information for the material.  This node is usually
    * loaded from the $FG_ROOT/materials.xml file.
    */
-  SGMaterial( const osgDB::ReaderWriter::Options*, const SGPropertyNode *props);
+  SGMaterial( const osgDB::ReaderWriter::Options*, 
+              const SGPropertyNode *props, 
+              SGPropertyNode *prop_root);
 
   SGMaterial(const simgear::SGReaderWriterOptions*,
-             const SGPropertyNode *props);
+             const SGPropertyNode *props,
+             SGPropertyNode *prop_root);
   /**
    * Destructor.
    */
@@ -233,6 +237,18 @@ public:
   SGMatModelGroup * get_object_group (int index) const {
     return object_groups[index];
   }
+  
+  /**
+   * Evaluate whether this material is valid given the current global
+   * property state.
+   */
+   bool valid() { 
+     if (condition) {
+       return condition->test();       
+     } else {
+       return true;
+     }
+   }
 
   /**
    * Return pointer to glyph class, or 0 if it doesn't exist.
@@ -352,13 +368,17 @@ private:
   // Object mask, a simple RGB texture used as a mask when placing
   // random vegetation, objects and buildings
   std::vector<osg::Texture2D*> _masks;
-\f
+  
+  // Condition, indicating when this material is active
+  SGSharedPtr<const SGCondition> condition;
+
   ////////////////////////////////////////////////////////////////////
   // Internal constructors and methods.
   ////////////////////////////////////////////////////////////////////
 
   void read_properties(const simgear::SGReaderWriterOptions* options,
-                        const SGPropertyNode *props);
+                        const SGPropertyNode *props,
+                        SGPropertyNode *prop_root);
   void buildEffectProperties(const simgear::SGReaderWriterOptions* options);
   simgear::Effect* get_effect(int i);
 };
index 5de7e01c75d9e227d8fb989370f7049a2b7e5272..e69fd60ddfc1d800299fad77d7fb93df2182c2ef 100644 (file)
@@ -75,23 +75,13 @@ bool SGMaterialLib::load( const string &fg_root, const string& mpath,
     for (int i = 0; i < nMaterials; i++) {
         const SGPropertyNode *node = materials.getChild(i);
         if (!strcmp(node->getName(), "material")) {
-            const SGPropertyNode *conditionNode = node->getChild("condition");
-            if (conditionNode) {
-                SGSharedPtr<const SGCondition> condition = sgReadCondition(prop_root, conditionNode);
-                if (!condition->test()) {
-                    SG_LOG(SG_INPUT, SG_DEBUG, "Skipping material entry #"
-                        << i << " (condition false)");
-                    continue;
-                }
-            }
-
-            SGSharedPtr<SGMaterial> m = new SGMaterial(options.get(), node);
+            SGSharedPtr<SGMaterial> m = new SGMaterial(options.get(), node, prop_root);
 
             vector<SGPropertyNode_ptr>names = node->getChildren("name");
             for ( unsigned int j = 0; j < names.size(); j++ ) {
                 string name = names[j]->getStringValue();
                 // cerr << "Material " << name << endl;
-                matlib[name] = m;
+                matlib[name].push_back(m);
                 m->add_name(name);
                 SG_LOG( SG_TERRAIN, SG_DEBUG, "  Loading material "
                         << names[j]->getStringValue() );
@@ -109,9 +99,19 @@ bool SGMaterialLib::load( const string &fg_root, const string& mpath,
 SGMaterial *SGMaterialLib::find( const string& material ) {
     SGMaterial *result = NULL;
     material_map_iterator it = matlib.find( material );
-    if ( it != end() ) {
-       result = it->second;
-       return result;
+    if ( it != end() ) {            
+        // We now have a list of materials that match this
+        // name. Find the first one that either doesn't have
+        // a condition, or has a condition that evaluates
+        // to true.
+        material_list_iterator iter = it->second.begin();        
+        while (iter != it->second.end()) {            
+            result = *iter;
+            if (result->valid()) {
+                return result;
+            }
+            iter++;
+        }
     }
 
     return NULL;
@@ -122,8 +122,7 @@ SGMaterialLib::~SGMaterialLib ( void ) {
     SG_LOG( SG_GENERAL, SG_INFO, "SGMaterialLib::~SGMaterialLib() size=" << matlib.size());
 }
 
-const SGMaterial*
-SGMaterialLib::findMaterial(const osg::Geode* geode)
+const SGMaterial *SGMaterialLib::findMaterial(const osg::Geode* geode)
 {
     if (!geode)
         return 0;
index b3e8c9005427f3419f1ebb3eb24772f7edb24531..7d52e5c133539857f4fa491c0ec4130b49c9d69a 100644 (file)
@@ -58,7 +58,9 @@ class SGMaterialLib {
 private:
 
     // associative array of materials
-    typedef map < string, SGSharedPtr<SGMaterial> > material_map;
+    typedef std::vector< SGSharedPtr<SGMaterial> > material_list;    
+    typedef material_list::iterator material_list_iterator;
+    typedef map < string,  material_list> material_map;
     typedef material_map::iterator material_map_iterator;
     typedef material_map::const_iterator const_material_map_iterator;
 
@@ -81,7 +83,7 @@ public:
     material_map_iterator end() { return matlib.end(); }
     const_material_map_iterator end() const { return matlib.end(); }
 
-    static const SGMaterialfindMaterial(const osg::Geode* geode);
+    static const SGMaterial *findMaterial(const osg::Geode* geode);
 
     // Destructor
     ~SGMaterialLib ( void );