materials.xml support for osm2city Buildings etc.
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user