SGMaterial::SGMaterial( const SGReaderWriterOptions* options,
const SGPropertyNode *props,
- SGPropertyNode *prop_root )
+ SGPropertyNode *prop_root,
+ AreaList *a,
+ SGSharedPtr<const SGCondition> c)
{
init();
+ areas = a;
+ condition = c;
read_properties( options, props, prop_root );
buildEffectProperties(options);
}
SGMaterial::SGMaterial( const osgDB::Options* options,
const SGPropertyNode *props,
- SGPropertyNode *prop_root)
+ SGPropertyNode *prop_root,
+ AreaList *a,
+ SGSharedPtr<const SGCondition> c)
{
osg::ref_ptr<SGReaderWriterOptions> opt;
opt = SGReaderWriterOptions::copyOrCreate(options);
+ areas = a;
+ condition = c;
init();
read_properties(opt.get(), props, prop_root);
buildEffectProperties(opt.get());
} else {
parameters = new SGPropertyNode();
}
-
- // Read conditions node
- const SGPropertyNode *conditionNode = props->getChild("condition");
- if (conditionNode) {
- condition = sgReadCondition(prop_root, conditionNode);
- }
}
return it->second;
}
-bool SGMaterial::valid() const
-{
- if (condition) {
- return condition->test();
- } else {
- return true;
- }
+bool SGMaterial::valid(SGVec2f loc) const
+{
+ SG_LOG( SG_TERRAIN, SG_BULK, "Checking materials for location ("
+ << loc.x() << ","
+ << loc.y() << ")");
+
+ // Check location first again the areas the material is valid for
+ AreaList::const_iterator i = areas->begin();
+
+ if (i == areas->end()) {
+ // No areas defined, so simply check against condition
+ if (condition) {
+ return condition->test();
+ } else {
+ return true;
+ }
+ }
+
+ for (; i != areas->end(); i++) {
+
+ SG_LOG( SG_TERRAIN, SG_BULK, "Checking area ("
+ << i->x() << ","
+ << i->y() << ") width:"
+ << i->width() << " height:"
+ << i->height());
+ // Areas defined, so check that the tile location falls within it
+ // before checking against condition
+ if (i->contains(loc.x(), loc.y())) {
+ if (condition) {
+ return condition->test();
+ } else {
+ return true;
+ }
+ }
+ }
+
+ return false;
}
\f
class StateSet;
}
-
-typedef osg::ref_ptr<osg::Texture2D> Texture2DRef;
-
#include <simgear/structure/SGSharedPtr.hxx>
#include <simgear/threads/SGThread.hxx> // for SGMutex
+#include <simgear/math/SGLimits.hxx>
+#include <simgear/math/SGMisc.hxx>
#include <simgear/math/SGMath.hxx>
+#include <simgear/math/SGVec2.hxx>
+#include <simgear/math/SGRect.hxx>
#include <simgear/bvh/BVHMaterial.hxx>
+typedef osg::ref_ptr<osg::Texture2D> Texture2DRef;
+typedef std::vector<SGRect <float> > AreaList;
+
namespace simgear
{
class Effect;
* state information for the material. This node is usually
* loaded from the $FG_ROOT/materials.xml file.
*/
- SGMaterial( const osgDB::Options*,
- const SGPropertyNode *props,
- SGPropertyNode *prop_root);
+ SGMaterial(const osgDB::Options*,
+ const SGPropertyNode *props,
+ SGPropertyNode *prop_root,
+ AreaList *a,
+ SGSharedPtr<const SGCondition> c);
+
SGMaterial(const simgear::SGReaderWriterOptions*,
const SGPropertyNode *props,
- SGPropertyNode *prop_root);
+ SGPropertyNode *prop_root,
+ AreaList *a,
+ SGSharedPtr<const SGCondition> c);
+
/**
* Destructor.
*/
/**
* Evaluate whether this material is valid given the current global
- * property state.
+ * property state and the tile location.
*/
- bool valid() const;
+ bool valid(SGVec2f loc) const;
/**
* Return pointer to glyph class, or 0 if it doesn't exist.
// Condition, indicating when this material is active
SGSharedPtr<const SGCondition> condition;
+ // List of geographical rectangles for this material
+ AreaList* areas;
+
// Parameters from the materials file
const SGPropertyNode* parameters;
#include <simgear/debug/logstream.hxx>
#include <simgear/misc/sg_path.hxx>
#include <simgear/misc/sgstream.hxx>
+#include <simgear/props/props.hxx>
#include <simgear/props/props_io.hxx>
#include <simgear/props/condition.hxx>
#include <simgear/scene/tgdb/userdata.hxx>
bool SGMaterialLib::load( const string &fg_root, const string& mpath,
SGPropertyNode *prop_root )
{
- SGPropertyNode materials;
+ SGPropertyNode materialblocks;
SG_LOG( SG_INPUT, SG_INFO, "Reading materials from " << mpath );
try {
- readProperties( mpath, &materials );
+ readProperties( mpath, &materialblocks );
} catch (const sg_exception &ex) {
SG_LOG( SG_INPUT, SG_ALERT, "Error reading materials: "
<< ex.getMessage() );
= new osgDB::Options;
options->setObjectCacheHint(osgDB::Options::CACHE_ALL);
options->setDatabasePath(fg_root);
- int nMaterials = materials.nChildren();
- for (int i = 0; i < nMaterials; i++) {
- const SGPropertyNode *node = materials.getChild(i);
- if (!strcmp(node->getName(), "material")) {
- SGSharedPtr<SGMaterial> m = new SGMaterial(options.get(), node, prop_root);
-
- std::vector<SGPropertyNode_ptr>names = node->getChildren("name");
- for ( unsigned int j = 0; j < names.size(); j++ ) {
- string name = names[j]->getStringValue();
- // cerr << "Material " << name << endl;
- matlib[name].push_back(m);
- m->add_name(name);
- SG_LOG( SG_TERRAIN, SG_DEBUG, " Loading material "
- << names[j]->getStringValue() );
- }
- } else {
- SG_LOG(SG_INPUT, SG_WARN,
- "Skipping bad material entry " << node->getName());
- }
+
+ simgear::PropertyList blocks = materialblocks.getChildren("region");
+ simgear::PropertyList::const_iterator block_iter = blocks.begin();
+
+ for (; block_iter != blocks.end(); block_iter++) {
+ SGPropertyNode_ptr node = block_iter->get();
+
+ // Read name node purely for logging purposes
+ const SGPropertyNode *nameNode = node->getChild("name");
+ if (nameNode) {
+ SG_LOG( SG_TERRAIN, SG_INFO, "Loading region "
+ << nameNode->getStringValue());
+ }
+
+ // Read list of areas
+ AreaList* arealist = new AreaList;
+
+ const simgear::PropertyList areas = node->getChildren("area");
+ simgear::PropertyList::const_iterator area_iter = areas.begin();
+ for (; area_iter != areas.end(); area_iter++) {
+ float x1 = area_iter->get()->getFloatValue("lon1", -180.0f);
+ float x2 = area_iter->get()->getFloatValue("lon2", 180.0);
+ float y1 = area_iter->get()->getFloatValue("lat1", -90.0f);
+ float y2 = area_iter->get()->getFloatValue("lat2", 90.0f);
+ SGRect<float> rect = SGRect<float>(
+ fminf(x1, x2),
+ fminf(y1, y2),
+ fabs(x2 - x1),
+ fabs(y2 - y1));
+ arealist->push_back(rect);
+ SG_LOG( SG_TERRAIN, SG_INFO, " Area ("
+ << rect.x() << ","
+ << rect.y() << ") width:"
+ << rect.width() << " height:"
+ << rect.height());
+ }
+
+ // Read conditions node
+ const SGPropertyNode *conditionNode = node->getChild("condition");
+ SGSharedPtr<const SGCondition> condition;
+ if (conditionNode) {
+ condition = sgReadCondition(prop_root, conditionNode);
+ }
+
+ // Now build all the materials for this set of areas and conditions
+
+ const simgear::PropertyList materials = node->getChildren("material");
+ simgear::PropertyList::const_iterator materials_iter = materials.begin();
+ for (; materials_iter != materials.end(); materials_iter++) {
+ const SGPropertyNode *node = materials_iter->get();
+ SGSharedPtr<SGMaterial> m =
+ new SGMaterial(options.get(), node, prop_root, arealist, condition);
+
+ std::vector<SGPropertyNode_ptr>names = node->getChildren("name");
+ for ( unsigned int j = 0; j < names.size(); j++ ) {
+ string name = names[j]->getStringValue();
+ // cerr << "Material " << name << endl;
+ matlib[name].push_back(m);
+ m->add_name(name);
+ SG_LOG( SG_TERRAIN, SG_DEBUG, " Loading material "
+ << names[j]->getStringValue() );
+ }
+ }
}
return true;
}
-// find a material record by material name
-SGMaterial *SGMaterialLib::find( const string& material ) const
+// find a material record by material name and tile center
+SGMaterial *SGMaterialLib::find( const string& material, const SGVec2f center ) const
{
SGMaterial *result = NULL;
const_material_map_iterator it = matlib.find( material );
if ( it != end() ) {
// We now have a list of materials that match this
- // name. Find the first one that either doesn't have
- // a condition, or has a condition that evaluates
- // to true.
- material_list::const_iterator iter = it->second.begin();
- while (iter != it->second.end()) {
+ // name. Find the first one that matches.
+ // We start at the end of the list, as the materials
+ // list is ordered with the smallest regions at the end.
+ material_list::const_reverse_iterator iter = it->second.rbegin();
+ while (iter != it->second.rend()) {
result = *iter;
- if (result->valid()) {
+ if (result->valid(center)) {
return result;
}
iter++;
return NULL;
}
-void SGMaterialLib::refreshActiveMaterials()
+// find a material record by material name and tile center
+SGMaterial *SGMaterialLib::find( const string& material, const SGGeod& center ) const
{
- active_material_cache newCache;
- material_map_iterator it = matlib.begin();
- for (; it != matlib.end(); ++it) {
- newCache[it->first] = find(it->first);
+ SGVec2f c = SGVec2f(center.getLongitudeDeg(), center.getLatitudeDeg());
+ return find(material, c);
+}
+
+SGMaterialCache *SGMaterialLib::generateMatCache(SGVec2f center)
+{
+ SGMaterialCache* newCache = new SGMaterialCache();
+ material_map::const_reverse_iterator it = matlib.rbegin();
+ for (; it != matlib.rend(); ++it) {
+ newCache->insert(it->first, find(it->first, center));
}
- // use this approach to minimise the time we're holding the lock
- // lock on the mutex (and hence, would block findCached calls)
- SGGuard<SGMutex> g(d->mutex);
- active_cache = newCache;
+ return newCache;
}
-SGMaterial *SGMaterialLib::findCached( const string& material ) const
+SGMaterialCache *SGMaterialLib::generateMatCache(SGGeod center)
{
- SGGuard<SGMutex> g(d->mutex);
-
- active_material_cache::const_iterator it = active_cache.find(material);
- if (it == active_cache.end())
- return NULL;
-
- return it->second;
+ SGVec2f c = SGVec2f(center.getLongitudeDeg(), center.getLatitudeDeg());
+ return SGMaterialLib::generateMatCache(c);
}
+
// Destructor
SGMaterialLib::~SGMaterialLib ( void ) {
SG_LOG( SG_GENERAL, SG_INFO, "SGMaterialLib::~SGMaterialLib() size=" << matlib.size());
return 0;
return userData->getMaterial();
}
+
+// Constructor
+SGMaterialCache::SGMaterialCache ( void )
+{
+}
+
+// Insertion into the material cache
+void SGMaterialCache::insert(const std::string& name, SGSharedPtr<SGMaterial> material) {
+ cache[name] = material;
+}
+
+// Search of the material cache
+SGMaterial *SGMaterialCache::find(const string& material) const
+{
+ SGMaterialCache::material_cache::const_iterator it = cache.find(material);
+ if (it == cache.end())
+ return NULL;
+
+ return it->second;
+}
+
+// Destructor
+SGMaterialCache::~SGMaterialCache ( void ) {
+ SG_LOG( SG_GENERAL, SG_INFO, "SGMaterialCache::~SGMaterialCache() size=" << cache.size());
+}
#include <simgear/structure/SGReferenced.hxx>
#include <simgear/structure/SGSharedPtr.hxx>
+#include <simgear/math/SGMath.hxx>
#include <memory>
#include <string> // Standard C++ string library
namespace simgear { class Effect; }
namespace osg { class Geode; }
+// Material cache class
+class SGMaterialCache : public osg::Referenced
+{
+private:
+ typedef std::map < std::string, SGSharedPtr<SGMaterial> > material_cache;
+ material_cache cache;
+
+public:
+ // Constructor
+ SGMaterialCache ( void );
+
+ // Insertion
+ void insert( const std::string& name, SGSharedPtr<SGMaterial> material );
+
+ // Lookup
+ SGMaterial *find( const std::string& material ) const;
+
+ // Destructor
+ ~SGMaterialCache ( void );
+};
+
// Material management class
class SGMaterialLib : public SGReferenced
{
material_map matlib;
- typedef std::map < std::string, SGSharedPtr<SGMaterial> > active_material_cache;
- active_material_cache active_cache;
-
public:
// Constructor
bool load( const std::string &fg_root, const std::string& mpath,
SGPropertyNode *prop_root );
// find a material record by material name
- SGMaterial *find( const std::string& material ) const;
+ SGMaterial *find( const std::string& material, SGVec2f center ) const;
+ SGMaterial *find( const std::string& material, const SGGeod& center ) const;
/**
- * Material lookup involves evaluation of SGConditions to determine which
- * possible material (by season, region, etc) is valid. This involves
- * vproperty tree queries, so repeated calls to find() can cause
+ * Material lookup involves evaluation of position and SGConditions to
+ * determine which possible material (by season, region, etc) is valid.
+ * This involves property tree queries, so repeated calls to find() can cause
* race conditions when called from the osgDB pager thread. (especially
* during startup)
*
* To fix this, and also avoid repeated re-evaluation of the material
- * conditions, we provide a version which uses a cached, threadsafe table
- * of the currently valid materials. The main thread calls the refresh
- * method below to evaluate the valid materials, and findCached can be
- * safely called from other threads with no access to unprotected state.
+ * conditions, we provide factory method to generate a material library
+ * cache of the valid materials based on the current state and a given position.
*/
- SGMaterial *findCached( const std::string& material ) const;
- void refreshActiveMaterials();
-
+
+ SGMaterialCache *generateMatCache( SGVec2f center);
+ SGMaterialCache *generateMatCache( SGGeod center);
+
material_map_iterator begin() { return matlib.begin(); }
const_material_map_iterator begin() const { return matlib.begin(); }
// Destructor
~SGMaterialLib ( void );
+
};
typedef SGSharedPtr<SGMaterialLib> SGMaterialLibPtr;
double tex_width = 1000.0;
// find Ocean material in the properties list
- SGMaterial *mat = matlib->findCached( "Ocean" );
+ SGMaterialCache* matcache = matlib->generateMatCache(b.get_center());
+ SGMaterial* mat = matcache->find( "Ocean" );
+ delete matcache;
+
if ( mat != NULL ) {
// set the texture width and height values for this
// material
assert(mats);
d->materials = mats;
- d->signCaseGeometry = d->getGeometry(d->materials->find("signcase")->get_effect());
+ d->signCaseGeometry = d->getGeometry(d->materials->find("signcase", center)->get_effect());
}
osg::Node* AirportSignBuilder::getSignsGroup()
}
if (! newmat.empty()) {
- material = d->materials->find(newmat);
+ material = d->materials->find(newmat, pos);
newmat.clear();
}
// Part II: typeset
double boxwidth = std::max(total_width1, total_width2) * 0.5;
double hpos = -boxwidth;
- SGMaterial *mat = d->materials->find("signcase");
+ SGMaterial *mat = d->materials->find("signcase", pos);
double coverSize = fabs(total_width1 - total_width2) * 0.5;
element_info* s1 = new element_info(mat, mat->get_glyph("cover1"), sign_height, coverSize);
}
bool
- insertPtGeometry(const SGBinObject& obj, SGMaterialLib* matlib)
+ insertPtGeometry(const SGBinObject& obj, SGMaterialCache* matcache)
{
if (obj.get_pts_v().size() != obj.get_pts_n().size()) {
SG_LOG(SG_TERRAIN, SG_ALERT,
for (unsigned grp = 0; grp < obj.get_pts_v().size(); ++grp) {
std::string materialName = obj.get_pt_materials()[grp];
- SGMaterial* material = 0;
- if (matlib)
- material = matlib->findCached(materialName);
+ SGMaterial* material = matcache->find(materialName);
SGVec4f color = getMaterialLightColor(material);
if (3 <= materialName.size() && materialName.substr(0, 3) != "RWY") {
}
}
- SGVec2f getTexCoordScale(const std::string& name, SGMaterialLib* matlib)
+ SGVec2f getTexCoordScale(const std::string& name, SGMaterialCache* matcache)
{
- if (!matlib)
+ if (!matcache)
return SGVec2f(1, 1);
- SGMaterial* material = matlib->findCached(name);
+ SGMaterial* material = matcache->find(name);
if (!material)
return SGVec2f(1, 1);
}
bool
- insertSurfaceGeometry(const SGBinObject& obj, SGMaterialLib* matlib)
+ insertSurfaceGeometry(const SGBinObject& obj, SGMaterialCache* matcache)
{
if (obj.get_tris_n().size() < obj.get_tris_v().size() ||
obj.get_tris_tcs().size() < obj.get_tris_v().size()) {
for (unsigned grp = 0; grp < obj.get_tris_v().size(); ++grp) {
std::string materialName = obj.get_tri_materials()[grp];
- SGVec2f tc0Scale = getTexCoordScale(materialName, matlib);
+ SGVec2f tc0Scale = getTexCoordScale(materialName, matcache);
SGVec2f tc1Scale(1.0, 1.0);
addTriangleGeometry(materialTriangleMap[materialName],
obj, grp, tc0Scale, tc1Scale );
}
for (unsigned grp = 0; grp < obj.get_strips_v().size(); ++grp) {
std::string materialName = obj.get_strip_materials()[grp];
- SGVec2f tc0Scale = getTexCoordScale(materialName, matlib);
+ SGVec2f tc0Scale = getTexCoordScale(materialName, matcache);
SGVec2f tc1Scale(1.0, 1.0);
addStripGeometry(materialTriangleMap[materialName],
obj, grp, tc0Scale, tc1Scale);
}
for (unsigned grp = 0; grp < obj.get_fans_v().size(); ++grp) {
std::string materialName = obj.get_fan_materials()[grp];
- SGVec2f tc0Scale = getTexCoordScale(materialName, matlib);
+ SGVec2f tc0Scale = getTexCoordScale(materialName, matcache);
SGVec2f tc1Scale(1.0, 1.0);
addFanGeometry(materialTriangleMap[materialName],
obj, grp, tc0Scale, tc1Scale );
return true;
}
- osg::Node* getSurfaceGeometry(SGMaterialLib* matlib, bool useVBOs) const
+ osg::Node* getSurfaceGeometry(SGMaterialCache* matcache, bool useVBOs) const
{
if (materialTriangleMap.empty())
return 0;
for (i = materialTriangleMap.begin(); i != materialTriangleMap.end(); ++i) {
osg::Geometry* geometry = i->second.buildGeometry(useVBOs);
SGMaterial *mat = NULL;
- if (matlib) {
- mat = matlib->findCached(i->first);
+ if (matcache) {
+ mat = matcache->find(i->first);
}
eg = new EffectGeode;
eg->setName("EffectGeode");
}
}
- void computeRandomSurfaceLights(SGMaterialLib* matlib)
+ void computeRandomSurfaceLights(SGMaterialCache* matcache)
{
SGMaterialTriangleMap::iterator i;
mt_init(&seed, unsigned(123));
for (i = materialTriangleMap.begin(); i != materialTriangleMap.end(); ++i) {
- SGMaterial *mat = matlib->findCached(i->first);
+ SGMaterial *mat = matcache->find(i->first);
if (!mat)
continue;
}
void computeRandomObjectsAndBuildings(
- SGMaterialLib* matlib,
+ SGMaterialCache* matcache,
float building_density,
bool use_random_objects,
bool use_random_buildings,
mt_init(&seed, unsigned(123));
for (i = materialTriangleMap.begin(); i != materialTriangleMap.end(); ++i) {
- SGMaterial *mat = matlib->findCached(i->first);
+ SGMaterial *mat = matcache->find(i->first);
SGTexturedTriangleBin triangleBin = i->second;
if (!mat)
}
}
- void computeRandomForest(SGMaterialLib* matlib, float vegetation_density)
+ void computeRandomForest(SGMaterialCache* matcache, float vegetation_density)
{
SGMaterialTriangleMap::iterator i;
mt_init(&seed, unsigned(586));
for (i = materialTriangleMap.begin(); i != materialTriangleMap.end(); ++i) {
- SGMaterial *mat = matlib->findCached(i->first);
+ SGMaterial *mat = matcache->find(i->first);
if (!mat)
continue;
}
}
- bool insertBinObj(const SGBinObject& obj, SGMaterialLib* matlib)
+ bool insertBinObj(const SGBinObject& obj, SGMaterialCache* matcache)
{
- if (!insertPtGeometry(obj, matlib))
+ if (!insertPtGeometry(obj, matcache))
return false;
- if (!insertSurfaceGeometry(obj, matlib))
+ if (!insertSurfaceGeometry(obj, matcache))
return false;
return true;
}
return NULL;
SGMaterialLibPtr matlib;
+ SGMaterialCache* matcache = 0;
bool useVBOs = false;
bool simplifyNear = false;
double ratio = SG_SIMPLIFIER_RATIO;
SGGeod geodPos = SGGeod::fromCart(center);
SGQuatd hlOr = SGQuatd::fromLonLat(geodPos)*SGQuatd::fromEulerDeg(0, 0, 180);
+ // Generate a materials cache
+ if (matlib) matcache = matlib->generateMatCache(geodPos);
+
// rotate the tiles so that the bounding boxes get nearly axis aligned.
// this will help the collision tree's bounding boxes a bit ...
std::vector<SGVec3d> nodes = tile.get_wgs84_nodes();
osg::ref_ptr<SGTileGeometryBin> tileGeometryBin = new SGTileGeometryBin;
- if (!tileGeometryBin->insertBinObj(tile, matlib))
+ if (!tileGeometryBin->insertBinObj(tile, matcache))
return NULL;
- osg::Node* node = tileGeometryBin->getSurfaceGeometry(matlib, useVBOs);
+ osg::Node* node = tileGeometryBin->getSurfaceGeometry(matcache, useVBOs);
if (node && simplifyNear) {
osgUtil::Simplifier simplifier(ratio, maxError, maxLength);
node->accept(simplifier);
// Generate all the lighting objects for the tile.
osg::LOD* generateLightingTileObjects()
{
- SGMaterialLibPtr matlib;
-
- if (_options)
- matlib = _options->getMaterialLib();
-
- // FIXME: ugly, has a side effect
- if (matlib)
- _tileGeometryBin->computeRandomSurfaceLights(matlib);
+ if (_matcache)
+ _tileGeometryBin->computeRandomSurfaceLights(_matcache);
GroundLightManager* lightManager = GroundLightManager::instance();
osg::ref_ptr<osg::Group> lightGroup = new SGOffsetTransform(0.94);
vasiGeode->setEffect(vasiEffect);
SGVec4f red(1, 0, 0, 1);
SGMaterial* mat = 0;
- if (matlib)
- mat = matlib->findCached("RWY_RED_LIGHTS");
+ if (_matcache)
+ mat = _matcache->find("RWY_RED_LIGHTS");
if (mat)
red = mat->get_light_color();
SGVec4f white(1, 1, 1, 1);
mat = 0;
- if (matlib)
- mat = matlib->findCached("RWY_WHITE_LIGHTS");
+ if (_matcache)
+ mat = _matcache->find("RWY_WHITE_LIGHTS");
if (mat)
white = mat->get_light_color();
SGDirectionalLightListBin::const_iterator i;
if (matlib && (use_random_objects || use_random_buildings)) {
- _tileGeometryBin->computeRandomObjectsAndBuildings(matlib,
+ _tileGeometryBin->computeRandomObjectsAndBuildings(_matcache,
building_density,
use_random_objects,
use_random_buildings,
if (use_random_vegetation && matlib) {
// Now add some random forest.
- _tileGeometryBin->computeRandomForest(matlib, vegetation_density);
+ _tileGeometryBin->computeRandomForest(_matcache, vegetation_density);
if (! _tileGeometryBin->randomForest.empty()) {
forestNode = createForest(_tileGeometryBin->randomForest, osg::Matrix::identity(),
/// The original options to use for this bunch of models
osg::ref_ptr<SGReaderWriterOptions> _options;
+ osg::ref_ptr<SGMaterialCache> _matcache;
osg::ref_ptr<SGTileGeometryBin> _tileGeometryBin;
string _path;
bool _loadterrain;
return NULL;
SGMaterialLibPtr matlib;
+ osg::ref_ptr<SGMaterialCache> matcache;
bool useVBOs = false;
bool simplifyDistant = false;
bool simplifyNear = false;
SGVec3d center = tile.get_gbs_center();
SGGeod geodPos = SGGeod::fromCart(center);
SGQuatd hlOr = SGQuatd::fromLonLat(geodPos)*SGQuatd::fromEulerDeg(0, 0, 180);
+ if (matlib)
+ matcache = matlib->generateMatCache(geodPos);
// rotate the tiles so that the bounding boxes get nearly axis aligned.
// this will help the collision tree's bounding boxes a bit ...
osg::ref_ptr<SGTileGeometryBin> tileGeometryBin = new SGTileGeometryBin;
- if (!tileGeometryBin->insertBinObj(tile, matlib))
+ if (!tileGeometryBin->insertBinObj(tile, matcache))
return NULL;
-
- osg::Node* node = tileGeometryBin->getSurfaceGeometry(matlib, useVBOs);
+ osg::Node* node = tileGeometryBin->getSurfaceGeometry(matcache, useVBOs);
if (node && simplifyDistant) {
osgUtil::Simplifier simplifier(ratio, maxError, maxLength);
node->accept(simplifier);
randomObjectCallback->_tileGeometryBin = tileGeometryBin;
randomObjectCallback->_path = std::string(path);
randomObjectCallback->_loadterrain = ! (simplifyNear == simplifyDistant);
+ randomObjectCallback->_matcache = matcache;
osg::ref_ptr<osgDB::Options> callbackOptions = new osgDB::Options;
callbackOptions->setReadFileCallback(randomObjectCallback.get());