From 023a3de5f11e0ffc709ec3a38cf894c60adfd560 Mon Sep 17 00:00:00 2001 From: Stuart Buchanan Date: Sun, 29 Nov 2020 19:28:58 +0000 Subject: [PATCH] WS30: Landclass to material mapping Using indirection in materials.xml 111 - Continuous urban fabric 1 Urban --- simgear/scene/material/matlib.cxx | 63 ++++++++++++++++++++++++++++--- simgear/scene/material/matlib.hxx | 13 +++++++ 2 files changed, 71 insertions(+), 5 deletions(-) diff --git a/simgear/scene/material/matlib.cxx b/simgear/scene/material/matlib.cxx index 43b33384..e79fb365 100644 --- a/simgear/scene/material/matlib.cxx +++ b/simgear/scene/material/matlib.cxx @@ -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(); @@ -188,7 +224,13 @@ SGMaterialCache *SGMaterialLib::generateMatCache(SGVec2f center) for (; it != matlib.rend(); ++it) { 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; } @@ -229,9 +271,14 @@ SGMaterialCache::SGMaterialCache ( void ) // Insertion into the material cache void SGMaterialCache::insert(const std::string& name, SGSharedPtr material) { - cache[name] = material; + cache[name] = material; } +void SGMaterialCache::insert(int lc, SGSharedPtr 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()); diff --git a/simgear/scene/material/matlib.hxx b/simgear/scene/material/matlib.hxx index ff80d795..826d70c5 100644 --- a/simgear/scene/material/matlib.hxx +++ b/simgear/scene/material/matlib.hxx @@ -50,15 +50,21 @@ private: typedef std::map < std::string, SGSharedPtr > 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 material ); + void insert( int lc, SGSharedPtr 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