WS30: Landclass to material mapping

Using indirection in materials.xml

<landclass-mapping>
  <map>
    <description>111 - Continuous urban fabric</description>
    <landclass>1</landclass>
    <material-name>Urban</material-name>
  </map>
</landclass-mapping>
This commit is contained in:
Stuart Buchanan 2020-11-29 19:28:58 +00:00
parent de268300fb
commit 023a3de5f1
2 changed files with 71 additions and 5 deletions

View File

@ -51,7 +51,6 @@
using std::string; using std::string;
class SGMaterialLib::MatLibPrivate class SGMaterialLib::MatLibPrivate
{ {
public: public:
@ -127,8 +126,7 @@ bool SGMaterialLib::load( const SGPath &fg_root, const SGPath& mpath,
} }
// Now build all the materials for this set of areas and conditions // Now build all the materials for this set of areas and conditions
const std::string region = node->getStringValue("name");
const std::string region = node->getStringValue("name");
const simgear::PropertyList materials = node->getChildren("material"); const simgear::PropertyList materials = node->getChildren("material");
simgear::PropertyList::const_iterator materials_iter = materials.begin(); simgear::PropertyList::const_iterator materials_iter = materials.begin();
for (; materials_iter != materials.end(); materials_iter++) { for (; materials_iter != materials.end(); materials_iter++) {
@ -148,6 +146,23 @@ bool SGMaterialLib::load( const SGPath &fg_root, const SGPath& mpath,
} }
} }
simgear::PropertyList landclasses = materialblocks.getNode("landclass-mapping", true)->getChildren("map");
simgear::PropertyList::const_iterator lc_iter = landclasses.begin();
for (; lc_iter != landclasses.end(); lc_iter++) {
SGPropertyNode_ptr node = lc_iter->get();
int lc = node->getIntValue("landclass");
const std::string mat = node->getStringValue("material-name");
// Verify that the landclass mapping exists before creating the mapping
const_material_map_iterator it = matlib.find( mat );
if ( it == end() ) {
SG_LOG(SG_TERRAIN, SG_ALERT, "Unable to find material " << mat << " for landclass " << lc);
} else {
landclasslib[lc] = mat;
}
}
return true; return true;
} }
@ -174,6 +189,16 @@ SGMaterial *SGMaterialLib::find( const string& material, const SGVec2f center )
return NULL; return NULL;
} }
SGMaterial *SGMaterialLib::find( int lc, const SGVec2f center ) const
{
const_landclass_map_iterator it = landclasslib.find( lc );
if (it != landclasslib.end()) {
return find(it->second, center);
} else {
return NULL;
}
}
// find a material record by material name and tile center // find a material record by material name and tile center
SGMaterial *SGMaterialLib::find( const string& material, const SGGeod& center ) const SGMaterial *SGMaterialLib::find( const string& material, const SGGeod& center ) const
{ {
@ -181,6 +206,17 @@ SGMaterial *SGMaterialLib::find( const string& material, const SGGeod& center )
return find(material, c); return find(material, c);
} }
// find a material record by material name and tile center
SGMaterial *SGMaterialLib::find( int lc, const SGGeod& center ) const
{
const_landclass_map_iterator it = landclasslib.find( lc );
if (it != landclasslib.end()) {
return find(it->second, center);
} else {
return NULL;
}
}
SGMaterialCache *SGMaterialLib::generateMatCache(SGVec2f center) SGMaterialCache *SGMaterialLib::generateMatCache(SGVec2f center)
{ {
SGMaterialCache* newCache = new SGMaterialCache(); SGMaterialCache* newCache = new SGMaterialCache();
@ -188,7 +224,13 @@ SGMaterialCache *SGMaterialLib::generateMatCache(SGVec2f center)
for (; it != matlib.rend(); ++it) { for (; it != matlib.rend(); ++it) {
newCache->insert(it->first, find(it->first, center)); newCache->insert(it->first, find(it->first, center));
} }
// Collapse down the mapping from landclasses to materials.
const_landclass_map_iterator lc_iter = landclasslib.begin();
for (; lc_iter != landclasslib.end(); ++lc_iter) {
newCache->insert(lc_iter->first, find(lc_iter->second, center));
}
return newCache; return newCache;
} }
@ -229,9 +271,14 @@ SGMaterialCache::SGMaterialCache ( void )
// Insertion into the material cache // Insertion into the material cache
void SGMaterialCache::insert(const std::string& name, SGSharedPtr<SGMaterial> material) { void SGMaterialCache::insert(const std::string& name, SGSharedPtr<SGMaterial> material) {
cache[name] = material; cache[name] = material;
} }
void SGMaterialCache::insert(int lc, SGSharedPtr<SGMaterial> material) {
cache[getNameFromLandclass(lc)] = material;
}
// Search of the material cache // Search of the material cache
SGMaterial *SGMaterialCache::find(const string& material) const SGMaterial *SGMaterialCache::find(const string& material) const
{ {
@ -242,6 +289,12 @@ SGMaterial *SGMaterialCache::find(const string& material) const
return it->second; return it->second;
} }
// Search of the material cache for a material code as an integer (e.g. from a VPB landclass texture).
SGMaterial *SGMaterialCache::find(int lc) const
{
return find(getNameFromLandclass(lc));
}
// Destructor // Destructor
SGMaterialCache::~SGMaterialCache ( void ) { SGMaterialCache::~SGMaterialCache ( void ) {
SG_LOG( SG_TERRAIN, SG_DEBUG, "SGMaterialCache::~SGMaterialCache() size=" << cache.size()); SG_LOG( SG_TERRAIN, SG_DEBUG, "SGMaterialCache::~SGMaterialCache() size=" << cache.size());

View File

@ -50,15 +50,21 @@ private:
typedef std::map < std::string, SGSharedPtr<SGMaterial> > material_cache; typedef std::map < std::string, SGSharedPtr<SGMaterial> > material_cache;
material_cache cache; material_cache cache;
const std::string getNameFromLandclass(int lc) const {
return std::string("WS30_").append(std::to_string(lc));
}
public: public:
// Constructor // Constructor
SGMaterialCache ( void ); SGMaterialCache ( void );
// Insertion // Insertion
void insert( const std::string& name, SGSharedPtr<SGMaterial> material ); void insert( const std::string& name, SGSharedPtr<SGMaterial> material );
void insert( int lc, SGSharedPtr<SGMaterial> material );
// Lookup // Lookup
SGMaterial *find( const std::string& material ) const; SGMaterial *find( const std::string& material ) const;
SGMaterial *find( int material ) const;
// Destructor // Destructor
~SGMaterialCache ( void ); ~SGMaterialCache ( void );
@ -80,7 +86,12 @@ private:
typedef material_map::iterator material_map_iterator; typedef material_map::iterator material_map_iterator;
typedef material_map::const_iterator const_material_map_iterator; typedef material_map::const_iterator const_material_map_iterator;
typedef std::map < int, std::string> landclass_map;
typedef landclass_map::iterator landclass_map_iterator;
typedef landclass_map::const_iterator const_landclass_map_iterator;
material_map matlib; material_map matlib;
landclass_map landclasslib;
public: public:
@ -93,6 +104,8 @@ public:
// find a material record by material name // find a material record by material name
SGMaterial *find( const std::string& material, SGVec2f center ) const; SGMaterial *find( const std::string& material, SGVec2f center ) const;
SGMaterial *find( const std::string& material, const SGGeod& center ) const; SGMaterial *find( const std::string& material, const SGGeod& center ) const;
SGMaterial *find( const int lc, SGVec2f center ) const;
SGMaterial *find( const int lc, const SGGeod& center ) const;
/** /**
* Material lookup involves evaluation of position and SGConditions to * Material lookup involves evaluation of position and SGConditions to