materials.xml support for osm2city Buildings etc.

This commit is contained in:
Stuart Buchanan
2017-05-09 14:30:57 +01:00
parent 7512bc0fb2
commit a7dee1164d
6 changed files with 165 additions and 61 deletions
+5
View File
@@ -122,6 +122,11 @@ public:
simgear::Effect* get_one_effect(int texIndex); simgear::Effect* get_one_effect(int texIndex);
simgear::Effect* get_effect(); simgear::Effect* get_effect();
/**
* Get the Effect Name.
*/
std::string get_effect_name() const { return effect; }
/** /**
* Get the textured state. * Get the textured state.
*/ */
+6 -1
View File
@@ -463,8 +463,13 @@ struct ACOptimizePolicy : public OptimizeModelPolicy {
} }
const SGReaderWriterOptions* sgopt const SGReaderWriterOptions* sgopt
= dynamic_cast<const SGReaderWriterOptions*>(opt); = dynamic_cast<const SGReaderWriterOptions*>(opt);
if (sgopt && sgopt->getInstantiateEffects())
if (sgopt && sgopt->getInstantiateMaterialEffects()) {
optimized = instantiateMaterialEffects(optimized.get(), sgopt);
} else if (sgopt && sgopt->getInstantiateEffects()) {
optimized = instantiateEffects(optimized.get(), sgopt); optimized = instantiateEffects(optimized.get(), sgopt);
}
return optimized.release(); return optimized.release();
} }
}; };
+30
View File
@@ -336,5 +336,35 @@ ref_ptr<Node> instantiateEffects(osg::Node* modelGroup,
osg::NodeList& result = visitor.getResults(); osg::NodeList& result = visitor.getResults();
return ref_ptr<Node>(result[0].get()); return ref_ptr<Node>(result[0].get());
} }
ref_ptr<Node> instantiateMaterialEffects(osg::Node* modelGroup,
const SGReaderWriterOptions* options)
{
SGPropertyNode_ptr effect;
PropertyList effectProps;
if (options->getMaterialLib()) {
const SGGeod loc = SGGeod(options->getLocation());
SGMaterialCache* matcache = options->getMaterialLib()->generateMatCache(loc);
SGMaterial* mat = matcache->find(options->getMaterialName());
delete matcache;
if (mat) {
effect = new SGPropertyNode();
makeChild(effect, "inherits-from")->setStringValue(mat->get_effect_name());
} else {
effect = DefaultEffect::instance()->getEffect();
SG_LOG( SG_TERRAIN, SG_ALERT, "Unable to get effect for " << options->getMaterialName());
}
} else {
effect = DefaultEffect::instance()->getEffect();
}
effect->addChild("default")->setBoolValue(true);
effectProps.push_back(effect);
return instantiateEffects(modelGroup, effectProps, options);
}
} }
// end of model.cxx // end of model.cxx
+12
View File
@@ -104,6 +104,18 @@ instantiateEffects(osg::Node* model,
PropertyList& effectProps, PropertyList& effectProps,
const SGReaderWriterOptions* options); const SGReaderWriterOptions* options);
/**
* Apply a set of material-defined effects to a model
* Transform an OSG subgraph by substituting Effects and EffectGeodes
* for osg::Geodes with osg::StateSets. This is only guaranteed to
* work for models prouced by the .ac loader.
*
* returns a copy if any nodes are changed
*/
osg::ref_ptr<osg::Node>
instantiateMaterialEffects(osg::Node* model,
const SGReaderWriterOptions* options);
/** /**
* Transform an OSG subgraph by substituting the Effects and * Transform an OSG subgraph by substituting the Effects and
* EffectGeodes for osg::Geodes with osg::StateSets, inheriting from * EffectGeodes for osg::Geodes with osg::StateSets, inheriting from
+46 -18
View File
@@ -53,6 +53,13 @@
#include "SGOceanTile.hxx" #include "SGOceanTile.hxx"
#define BUILDING_ROUGH "OBJECT_BUILDING_MESH_ROUGH"
#define BUILDING_DETAILED "OBJECT_BUILDING_MESH_DETAILED"
#define ROAD_ROUGH "OBJECT_ROAD_ROUGH"
#define ROAD_DETAILED "OBJECT_ROAD_DETAILED"
#define RAILWAY_ROUGH "OBJECT_RAILWAY_ROUGH"
#define RAILWAY_DETAILED "OBJECT_RAILWAY_DETAILED"
namespace simgear { namespace simgear {
/// Ok, this is a hack - we do not exactly know if it's an airport or not. /// Ok, this is a hack - we do not exactly know if it's an airport or not.
@@ -393,6 +400,7 @@ struct ReaderWriterSTG::_ModelBin {
else else
opt->setInstantiateEffects(false); opt->setInstantiateEffects(false);
_ObjectStatic obj; _ObjectStatic obj;
obj._errorLocation = absoluteFileName; obj._errorLocation = absoluteFileName;
obj._token = token; obj._token = token;
obj._name = name; obj._name = name;
@@ -428,31 +436,51 @@ struct ReaderWriterSTG::_ModelBin {
sign._agl = (token == "OBJECT_SIGN_AGL"); sign._agl = (token == "OBJECT_SIGN_AGL");
in >> sign._lon >> sign._lat >> sign._elev >> sign._hdg >> sign._size; in >> sign._lon >> sign._lat >> sign._elev >> sign._hdg >> sign._size;
_signList.push_back(sign); _signList.push_back(sign);
} else if (token == "OBJECT_BUILDING_MESH_ROUGH" || token == "OBJECT_BUILDING_MESH_DETAILED") { } else if (token == BUILDING_ROUGH || token == BUILDING_DETAILED ||
osg::ref_ptr<SGReaderWriterOptions> opt; token == ROAD_ROUGH || token == ROAD_DETAILED ||
opt = staticOptions(filePath, options); token == RAILWAY_ROUGH || token == RAILWAY_DETAILED) {
if (SGPath(name).lower_extension() == "ac") osg::ref_ptr<SGReaderWriterOptions> opt;
opt->setInstantiateEffects(true); opt = staticOptions(filePath, options);
else _ObjectStatic obj;
opt->setInstantiateEffects(false);
_ObjectStatic obj;
obj._errorLocation = absoluteFileName;
obj._token = token;
obj._name = name;
obj._agl = false;
obj._proxy = true;
in >> obj._lon >> obj._lat >> obj._elev >> obj._hdg >> obj._pitch >> obj._roll;
if (token == "OBJECT_BUILDING_MESH_DETAILED") { opt->setInstantiateEffects(false);
// Apply a lower LOD range if this is a detailed building if (SGPath(name).lower_extension() == "ac") {
// Generate material/Effects lookups for raw models, i.e.
// those not wrapped in an XML while will include Effects
opt->setInstantiateMaterialEffects(true);
if (token == BUILDING_ROUGH || token == BUILDING_DETAILED) {
opt->setMaterialName("OSM_Building");
} else if (token == ROAD_ROUGH || token == ROAD_DETAILED) {
opt->setMaterialName("OSM_Road");
} else if (token == RAILWAY_ROUGH || token == RAILWAY_DETAILED) {
opt->setMaterialName("OSM_Railway");
} else {
// Programming error. If we get here then someone has added a verb to the list of
// tokens above but not in this set of if-else statements.
SG_LOG(SG_TERRAIN, SG_ALERT, "Programming Error - STG token without material branch");
}
}
obj._errorLocation = absoluteFileName;
obj._token = token;
obj._name = name;
obj._agl = false;
obj._proxy = true;
in >> obj._lon >> obj._lat >> obj._elev >> obj._hdg >> obj._pitch >> obj._roll;
opt->setLocation(obj._lon, obj._lat);
if (token == BUILDING_DETAILED || token == ROAD_DETAILED || token == RAILWAY_DETAILED ) {
// Apply a lower LOD range if this is a detailed mesh
range = _object_range_detailed; range = _object_range_detailed;
double lrand = mt_rand(&seed); double lrand = mt_rand(&seed);
if (lrand < 0.1) range = range * 2.0; if (lrand < 0.1) range = range * 2.0;
else if (lrand < 0.4) range = range * 1.5; else if (lrand < 0.4) range = range * 1.5;
} }
obj._range = range; obj._range = range;
obj._options = opt;
obj._options = opt;
checkInsideBucket(absoluteFileName, obj._lon, obj._lat); checkInsideBucket(absoluteFileName, obj._lon, obj._lat);
_objectStaticList.push_back(obj); _objectStaticList.push_back(obj);
} else { } else {
+27 -3
View File
@@ -42,14 +42,16 @@ public:
_materialLib(0), _materialLib(0),
_load_panel(0), _load_panel(0),
_model_data(0), _model_data(0),
_instantiateEffects(false) _instantiateEffects(false),
_instantiateMaterialEffects(false)
{ } { }
SGReaderWriterOptions(const std::string& str) : SGReaderWriterOptions(const std::string& str) :
osgDB::Options(str), osgDB::Options(str),
_materialLib(0), _materialLib(0),
_load_panel(0), _load_panel(0),
_model_data(0), _model_data(0),
_instantiateEffects(false) _instantiateEffects(false),
_instantiateMaterialEffects(false)
{ } { }
SGReaderWriterOptions(const osgDB::Options& options, SGReaderWriterOptions(const osgDB::Options& options,
const osg::CopyOp& copyop = osg::CopyOp::SHALLOW_COPY) : const osg::CopyOp& copyop = osg::CopyOp::SHALLOW_COPY) :
@@ -57,7 +59,8 @@ public:
_materialLib(0), _materialLib(0),
_load_panel(0), _load_panel(0),
_model_data(0), _model_data(0),
_instantiateEffects(false) _instantiateEffects(false),
_instantiateMaterialEffects(false)
{ } { }
SGReaderWriterOptions(const SGReaderWriterOptions& options, SGReaderWriterOptions(const SGReaderWriterOptions& options,
const osg::CopyOp& copyop = osg::CopyOp::SHALLOW_COPY) : const osg::CopyOp& copyop = osg::CopyOp::SHALLOW_COPY) :
@@ -70,6 +73,8 @@ public:
_load_panel(options._load_panel), _load_panel(options._load_panel),
_model_data(options._model_data), _model_data(options._model_data),
_instantiateEffects(options._instantiateEffects), _instantiateEffects(options._instantiateEffects),
_instantiateMaterialEffects(options._instantiateMaterialEffects),
_materialName(options._materialName),
_sceneryPathSuffixes(options._sceneryPathSuffixes) _sceneryPathSuffixes(options._sceneryPathSuffixes)
{ } { }
@@ -109,6 +114,16 @@ public:
void setInstantiateEffects(bool instantiateEffects) void setInstantiateEffects(bool instantiateEffects)
{ _instantiateEffects = instantiateEffects; } { _instantiateEffects = instantiateEffects; }
bool getInstantiateMaterialEffects() const
{ return _instantiateMaterialEffects; }
void setInstantiateMaterialEffects(bool instantiateMaterialEffects)
{ _instantiateMaterialEffects = instantiateMaterialEffects; }
string getMaterialName() const
{ return _materialName; }
void setMaterialName(string materialName)
{ _materialName = materialName; }
const string_list& getSceneryPathSuffixes() const const string_list& getSceneryPathSuffixes() const
{ return _sceneryPathSuffixes; } { return _sceneryPathSuffixes; }
@@ -118,6 +133,12 @@ public:
static SGReaderWriterOptions* copyOrCreate(const osgDB::Options* options); static SGReaderWriterOptions* copyOrCreate(const osgDB::Options* options);
static SGReaderWriterOptions* fromPath(const std::string& path); static SGReaderWriterOptions* fromPath(const std::string& path);
void setLocation(double lon, double lat)
{ _geod = SGGeod::fromDeg(lon, lat); }
const SGGeod& getLocation() const
{ return _geod; }
protected: protected:
virtual ~SGReaderWriterOptions(); virtual ~SGReaderWriterOptions();
@@ -131,7 +152,10 @@ private:
osg::Node *(*_load_panel)(SGPropertyNode *); osg::Node *(*_load_panel)(SGPropertyNode *);
osg::ref_ptr<SGModelData> _model_data; osg::ref_ptr<SGModelData> _model_data;
bool _instantiateEffects; bool _instantiateEffects;
bool _instantiateMaterialEffects;
string _materialName;
string_list _sceneryPathSuffixes; string_list _sceneryPathSuffixes;
SGGeod _geod;
}; };
} }