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;
class SGMaterialLib::MatLibPrivate
{
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
const std::string region = node->getStringValue("name");
const std::string region = node->getStringValue("name");
const simgear::PropertyList materials = node->getChildren("material");
simgear::PropertyList::const_iterator materials_iter = materials.begin();
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;
}
@ -174,6 +189,16 @@ SGMaterial *SGMaterialLib::find( const string& material, const SGVec2f center )
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
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);
}
// 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* newCache = new SGMaterialCache();
@ -189,6 +225,12 @@ SGMaterialCache *SGMaterialLib::generateMatCache(SGVec2f 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;
}
@ -232,6 +274,11 @@ void SGMaterialCache::insert(const std::string& name, SGSharedPtr<SGMaterial> ma
cache[name] = material;
}
void SGMaterialCache::insert(int lc, SGSharedPtr<SGMaterial> material) {
cache[getNameFromLandclass(lc)] = material;
}
// Search of the material cache
SGMaterial *SGMaterialCache::find(const string& material) const
{
@ -242,6 +289,12 @@ SGMaterial *SGMaterialCache::find(const string& material) const
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
SGMaterialCache::~SGMaterialCache ( void ) {
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;
material_cache cache;
const std::string getNameFromLandclass(int lc) const {
return std::string("WS30_").append(std::to_string(lc));
}
public:
// Constructor
SGMaterialCache ( void );
// Insertion
void insert( const std::string& name, SGSharedPtr<SGMaterial> material );
void insert( int lc, SGSharedPtr<SGMaterial> material );
// Lookup
SGMaterial *find( const std::string& material ) const;
SGMaterial *find( int material ) const;
// Destructor
~SGMaterialCache ( void );
@ -80,7 +86,12 @@ private:
typedef material_map::iterator 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;
landclass_map landclasslib;
public:
@ -93,6 +104,8 @@ public:
// find a material record by material name
SGMaterial *find( const std::string& material, SGVec2f 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