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

View File

@@ -122,6 +122,11 @@ public:
simgear::Effect* get_one_effect(int texIndex);
simgear::Effect* get_effect();
/**
* Get the Effect Name.
*/
std::string get_effect_name() const { return effect; }
/**
* Get the textured state.
*/
@@ -154,7 +159,7 @@ public:
* @return The area (m^2) covered by each light.
*/
inline double get_light_coverage () const { return light_coverage; }
/**
* Get the building coverage.
*
@@ -190,12 +195,12 @@ public:
* @return The lightmap for auto-generated buildings.
*/
inline std::string get_building_lightmap () const { return building_lightmap; }
// Ratio of the 3 random building sizes
inline double get_building_small_fraction () const { return building_small_ratio / (building_small_ratio + building_medium_ratio + building_large_ratio); }
inline double get_building_medium_fraction () const { return building_medium_ratio / (building_small_ratio + building_medium_ratio + building_large_ratio); }
inline double get_building_large_fraction () const { return building_large_ratio / (building_small_ratio + building_medium_ratio + building_large_ratio); }
// Proportion of buildings with pitched roofs
inline double get_building_small_pitch () const { return building_small_pitch; }
inline double get_building_medium_pitch () const { return building_medium_pitch; }
@@ -208,25 +213,25 @@ public:
inline int get_building_medium_max_floors () const { return building_medium_max_floors; }
inline int get_building_large_min_floors () const { return building_large_min_floors; }
inline int get_building_large_max_floors () const { return building_large_max_floors; }
// Minimum width and depth for each size
inline double get_building_small_min_width () const { return building_small_min_width; }
inline double get_building_small_max_width () const { return building_small_max_width; }
inline double get_building_small_min_depth () const { return building_small_min_depth; }
inline double get_building_small_max_depth () const { return building_small_max_depth; }
inline double get_building_medium_min_width () const { return building_medium_min_width; }
inline double get_building_medium_max_width () const { return building_medium_max_width; }
inline double get_building_medium_min_depth () const { return building_medium_min_depth; }
inline double get_building_medium_max_depth () const { return building_medium_max_depth; }
inline double get_building_large_min_width () const { return building_large_min_width; }
inline double get_building_large_max_width () const { return building_large_max_width; }
inline double get_building_large_min_depth () const { return building_large_min_depth; }
inline double get_building_large_max_depth () const { return building_large_max_depth; }
inline double get_building_range () const { return building_range; }
inline double get_cos_object_max_density_slope_angle () const { return cos_object_max_density_slope_angle; }
inline double get_cos_object_zero_density_slope_angle () const { return cos_object_zero_density_slope_angle; }
@@ -238,7 +243,7 @@ public:
* @return The area (m^2) covered by each wood.
*/
inline double get_wood_coverage () const { return wood_coverage; }
/**
* Get the tree height.
*
@@ -259,14 +264,14 @@ public:
* @return The LoD range for the trees.
*/
inline double get_tree_range () const { return tree_range; }
/**
* Get the number of tree varieties available
*
* @return the number of different trees defined in the texture strip
*/
inline int get_tree_varieties () const { return tree_varieties; }
/**
* Get the texture strip to use for trees
*
@@ -281,25 +286,25 @@ public:
* @return the effect to use for this set of trees.
*/
inline std::string get_tree_effect () const { return tree_effect; }
/**
* Get the cosine of the maximum tree density slope angle. We
* use the cosine as it can be compared directly to the z component
* of a triangle normal.
*
*
* @return the cosine of the maximum tree density slope angle.
*/
inline double get_cos_tree_max_density_slope_angle () const { return cos_tree_max_density_slope_angle; }
/**
* Get the cosine of the maximum tree density slope angle. We
* use the cosine as it can be compared directly to the z component
* of a triangle normal.
*
*
* @return the cosine of the maximum tree density slope angle.
*/
inline double get_cos_tree_zero_density_slope_angle () const { return cos_tree_zero_density_slope_angle; }
/**
* Get the list of names for this material
*/
@@ -321,7 +326,7 @@ public:
SGMatModelGroup * get_object_group (int index) const {
return object_groups[index];
}
/**
* Evaluate whether this material is valid given the current global
* property state and the tile location.
@@ -346,7 +351,7 @@ public:
return SGVec2f((0 < tex_width) ? 1000.0f/tex_width : 1.0f,
(0 < tex_height) ? 1000.0f/tex_height : 1.0f);
}
protected:
@@ -394,13 +399,13 @@ private:
// coverage of night lighting.
double light_coverage;
// coverage of buildings
double building_coverage;
// building spacing
double building_spacing;
// building texture & lightmap
std::string building_texture;
std::string building_lightmap;
@@ -409,44 +414,44 @@ private:
double building_small_ratio;
double building_medium_ratio;
double building_large_ratio;
// Proportion of buildings with pitched roofs
double building_small_pitch;
double building_medium_pitch;
double building_large_pitch;
// Min/Max number of floors for each size
int building_small_min_floors;
int building_small_min_floors;
int building_small_max_floors;
int building_medium_min_floors;
int building_medium_max_floors;
int building_large_min_floors;
int building_large_max_floors;
// Minimum width and depth for each size
double building_small_min_width;
double building_small_max_width;
double building_small_min_depth;
double building_small_max_depth;
double building_medium_min_width;
double building_medium_max_width;
double building_medium_min_depth;
double building_medium_max_depth;
double building_large_min_width;
double building_large_max_width;
double building_large_min_depth;
double building_large_max_depth;
double building_range;
// Cosine of the angle of maximum and zero density,
// used to stop buildings and random objects from being
// Cosine of the angle of maximum and zero density,
// used to stop buildings and random objects from being
// created on too steep a slope.
double cos_object_max_density_slope_angle;
double cos_object_zero_density_slope_angle;
// coverage of woods
double wood_coverage;
@@ -461,7 +466,7 @@ private:
// Number of varieties of tree texture
int tree_varieties;
// cosine of the tile angle of maximum and zero density,
// used to stop trees from being created on too steep a slope.
double cos_tree_max_density_slope_angle;
@@ -481,20 +486,20 @@ private:
// taxiway-/runway-sign texture elements
std::map<std::string, SGSharedPtr<SGMaterialGlyph> > glyphs;
// Tree texture, typically a strip of applicable tree textures
std::string tree_texture;
// Tree effect to be used for a particular material
std::string tree_effect;
// Object mask, a simple RGB texture used as a mask when placing
// random vegetation, objects and buildings
std::vector<Texture2DRef> _masks;
// Condition, indicating when this material is active
SGSharedPtr<const SGCondition> condition;
// List of geographical rectangles for this material
AreaList* areas;
@@ -547,4 +552,4 @@ SGSetTextureFilter( int max);
int
SGGetTextureFilter();
#endif // _SG_MAT_HXX
#endif // _SG_MAT_HXX

View File

@@ -417,8 +417,8 @@ public:
// XXX I understand why we want this, but this seems like a weird
// place to set this option.
#if OSG_VERSION_LESS_THAN(3,5,4)
//RJH - see OSG 11ddd53eb46d15903d036b594bfa3826d9e89393 -
// Removed redundent Referenced::s/getThreadSafeReferenceCounting() and associated static and env vars
//RJH - see OSG 11ddd53eb46d15903d036b594bfa3826d9e89393 -
// Removed redundent Referenced::s/getThreadSafeReferenceCounting() and associated static and env vars
// as there are now inapprorpiate and no longer supported
Referenced::setThreadSafeReferenceCounting(true);
#endif
@@ -463,8 +463,13 @@ struct ACOptimizePolicy : public OptimizeModelPolicy {
}
const SGReaderWriterOptions* sgopt
= 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);
}
return optimized.release();
}
};

View File

@@ -336,5 +336,35 @@ ref_ptr<Node> instantiateEffects(osg::Node* modelGroup,
osg::NodeList& result = visitor.getResults();
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

View File

@@ -104,6 +104,18 @@ instantiateEffects(osg::Node* model,
PropertyList& effectProps,
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
* EffectGeodes for osg::Geodes with osg::StateSets, inheriting from

View File

@@ -53,6 +53,13 @@
#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 {
/// 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
opt->setInstantiateEffects(false);
_ObjectStatic obj;
obj._errorLocation = absoluteFileName;
obj._token = token;
obj._name = name;
@@ -428,31 +436,51 @@ struct ReaderWriterSTG::_ModelBin {
sign._agl = (token == "OBJECT_SIGN_AGL");
in >> sign._lon >> sign._lat >> sign._elev >> sign._hdg >> sign._size;
_signList.push_back(sign);
} else if (token == "OBJECT_BUILDING_MESH_ROUGH" || token == "OBJECT_BUILDING_MESH_DETAILED") {
osg::ref_ptr<SGReaderWriterOptions> opt;
opt = staticOptions(filePath, options);
if (SGPath(name).lower_extension() == "ac")
opt->setInstantiateEffects(true);
else
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;
} else if (token == BUILDING_ROUGH || token == BUILDING_DETAILED ||
token == ROAD_ROUGH || token == ROAD_DETAILED ||
token == RAILWAY_ROUGH || token == RAILWAY_DETAILED) {
osg::ref_ptr<SGReaderWriterOptions> opt;
opt = staticOptions(filePath, options);
_ObjectStatic obj;
if (token == "OBJECT_BUILDING_MESH_DETAILED") {
// Apply a lower LOD range if this is a detailed building
opt->setInstantiateEffects(false);
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;
double lrand = mt_rand(&seed);
if (lrand < 0.1) range = range * 2.0;
else if (lrand < 0.4) range = range * 1.5;
}
obj._range = range;
obj._options = opt;
obj._range = range;
obj._options = opt;
checkInsideBucket(absoluteFileName, obj._lon, obj._lat);
_objectStaticList.push_back(obj);
} else {

View File

@@ -42,14 +42,16 @@ public:
_materialLib(0),
_load_panel(0),
_model_data(0),
_instantiateEffects(false)
_instantiateEffects(false),
_instantiateMaterialEffects(false)
{ }
SGReaderWriterOptions(const std::string& str) :
osgDB::Options(str),
_materialLib(0),
_load_panel(0),
_model_data(0),
_instantiateEffects(false)
_instantiateEffects(false),
_instantiateMaterialEffects(false)
{ }
SGReaderWriterOptions(const osgDB::Options& options,
const osg::CopyOp& copyop = osg::CopyOp::SHALLOW_COPY) :
@@ -57,7 +59,8 @@ public:
_materialLib(0),
_load_panel(0),
_model_data(0),
_instantiateEffects(false)
_instantiateEffects(false),
_instantiateMaterialEffects(false)
{ }
SGReaderWriterOptions(const SGReaderWriterOptions& options,
const osg::CopyOp& copyop = osg::CopyOp::SHALLOW_COPY) :
@@ -70,6 +73,8 @@ public:
_load_panel(options._load_panel),
_model_data(options._model_data),
_instantiateEffects(options._instantiateEffects),
_instantiateMaterialEffects(options._instantiateMaterialEffects),
_materialName(options._materialName),
_sceneryPathSuffixes(options._sceneryPathSuffixes)
{ }
@@ -109,6 +114,16 @@ public:
void setInstantiateEffects(bool 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
{ return _sceneryPathSuffixes; }
@@ -118,6 +133,12 @@ public:
static SGReaderWriterOptions* copyOrCreate(const osgDB::Options* options);
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:
virtual ~SGReaderWriterOptions();
@@ -131,7 +152,10 @@ private:
osg::Node *(*_load_panel)(SGPropertyNode *);
osg::ref_ptr<SGModelData> _model_data;
bool _instantiateEffects;
bool _instantiateMaterialEffects;
string _materialName;
string_list _sceneryPathSuffixes;
SGGeod _geod;
};
}