Cleanup.
Additional null pointer checks. Simplify redundant interface arguments. Modified Files: simgear/scene/material/mat.cxx simgear/scene/material/mat.hxx simgear/scene/material/matlib.cxx simgear/scene/material/matlib.hxx simgear/scene/tgdb/ReaderWriterSTG.cxx simgear/scene/tgdb/SGReaderWriterBTG.cxx simgear/scene/tgdb/SGReaderWriterBTGOptions.hxx simgear/scene/tgdb/TileEntry.cxx simgear/scene/tgdb/TileEntry.hxx simgear/scene/tgdb/obj.cxx
This commit is contained in:
@@ -57,10 +57,10 @@ using namespace simgear;
|
|||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
SGMaterial::SGMaterial( const string &fg_root, const SGPropertyNode *props, const char *season )
|
SGMaterial::SGMaterial( const string &fg_root, const SGPropertyNode *props )
|
||||||
{
|
{
|
||||||
init();
|
init();
|
||||||
read_properties( fg_root, props, season );
|
read_properties( fg_root, props );
|
||||||
build_state( false );
|
build_state( false );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -84,23 +84,20 @@ SGMaterial::~SGMaterial (void)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
// Public methods.
|
// Public methods.
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void
|
void
|
||||||
SGMaterial::read_properties( const string &fg_root, const SGPropertyNode * props, const char *season )
|
SGMaterial::read_properties( const string &fg_root, const SGPropertyNode *props)
|
||||||
{
|
{
|
||||||
// Gather the path(s) to the texture(s)
|
// Gather the path(s) to the texture(s)
|
||||||
vector<SGPropertyNode_ptr> textures = props->getChildren("texture");
|
vector<SGPropertyNode_ptr> textures = props->getChildren("texture");
|
||||||
for (unsigned int i = 0; i < textures.size(); i++)
|
for (unsigned int i = 0; i < textures.size(); i++)
|
||||||
{
|
{
|
||||||
string tname = textures[i]->getStringValue();
|
string tname = textures[i]->getStringValue();
|
||||||
string otname = tname;
|
if (tname.empty()) {
|
||||||
|
|
||||||
if (tname == "") {
|
|
||||||
tname = "unknown.rgb";
|
tname = "unknown.rgb";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -304,9 +301,8 @@ void SGMaterial::assignTexture( osg::StateSet *state, const std::string &fname,
|
|||||||
texture->setMaxAnisotropy( SGGetTextureFilter());
|
texture->setMaxAnisotropy( SGGetTextureFilter());
|
||||||
state->setTextureAttributeAndModes(0, texture);
|
state->setTextureAttributeAndModes(0, texture);
|
||||||
|
|
||||||
osg::TexEnv* texEnv = new osg::TexEnv;
|
StateAttributeFactory *attrFact = StateAttributeFactory::instance();
|
||||||
texEnv->setMode(osg::TexEnv::MODULATE);
|
state->setTextureAttributeAndModes(0, attrFact->getStandardTexEnv());
|
||||||
state->setTextureAttributeAndModes(0, texEnv);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SGMaterialGlyph* SGMaterial::get_glyph (const string& name) const
|
SGMaterialGlyph* SGMaterial::get_glyph (const string& name) const
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ public:
|
|||||||
* state information for the material. This node is usually
|
* state information for the material. This node is usually
|
||||||
* loaded from the $FG_ROOT/materials.xml file.
|
* loaded from the $FG_ROOT/materials.xml file.
|
||||||
*/
|
*/
|
||||||
SGMaterial( const string &fg_root, const SGPropertyNode *props, const char *season );
|
SGMaterial( const string &fg_root, const SGPropertyNode *props);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -355,7 +355,7 @@ private:
|
|||||||
|
|
||||||
SGMaterial( const string &fg_root, const SGMaterial &mat ); // unimplemented
|
SGMaterial( const string &fg_root, const SGMaterial &mat ); // unimplemented
|
||||||
|
|
||||||
void read_properties( const string &fg_root, const SGPropertyNode *props, const char *season );
|
void read_properties( const string &fg_root, const SGPropertyNode *props );
|
||||||
void build_state( bool defer_tex_load );
|
void build_state( bool defer_tex_load );
|
||||||
void set_state( osg::StateSet *s );
|
void set_state( osg::StateSet *s );
|
||||||
|
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ SGMaterialLib::SGMaterialLib ( void ) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Load a library of material properties
|
// Load a library of material properties
|
||||||
bool SGMaterialLib::load( const string &fg_root, const string& mpath, const char *season,
|
bool SGMaterialLib::load( const string &fg_root, const string& mpath,
|
||||||
SGPropertyNode *prop_root )
|
SGPropertyNode *prop_root )
|
||||||
{
|
{
|
||||||
SGPropertyNode materials;
|
SGPropertyNode materials;
|
||||||
@@ -95,7 +95,7 @@ bool SGMaterialLib::load( const string &fg_root, const string& mpath, const char
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SGSharedPtr<SGMaterial> m = new SGMaterial(fg_root, node, season);
|
SGSharedPtr<SGMaterial> m = new SGMaterial(fg_root, node);
|
||||||
|
|
||||||
vector<SGPropertyNode_ptr>names = node->getChildren("name");
|
vector<SGPropertyNode_ptr>names = node->getChildren("name");
|
||||||
for ( unsigned int j = 0; j < names.size(); j++ ) {
|
for ( unsigned int j = 0; j < names.size(); j++ ) {
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ public:
|
|||||||
SGMaterialLib ( void );
|
SGMaterialLib ( void );
|
||||||
|
|
||||||
// Load a library of material properties
|
// Load a library of material properties
|
||||||
bool load( const string &fg_root, const string& mpath, const char *season,
|
bool load( const string &fg_root, const string& mpath,
|
||||||
SGPropertyNode *prop_root );
|
SGPropertyNode *prop_root );
|
||||||
|
|
||||||
// Add the named texture with default properties
|
// Add the named texture with default properties
|
||||||
|
|||||||
@@ -57,6 +57,7 @@ ReaderWriterSTG::readNode(const std::string& fileName,
|
|||||||
const osgDB::ReaderWriter::Options* options) const
|
const osgDB::ReaderWriter::Options* options) const
|
||||||
{
|
{
|
||||||
std::string tileName = osgDB::getNameLessExtension(fileName);
|
std::string tileName = osgDB::getNameLessExtension(fileName);
|
||||||
|
|
||||||
osg::Node* result = TileEntry::loadTileByName(tileName, options);
|
osg::Node* result = TileEntry::loadTileByName(tileName, options);
|
||||||
// For debugging race conditions
|
// For debugging race conditions
|
||||||
#ifdef SLOW_PAGER
|
#ifdef SLOW_PAGER
|
||||||
|
|||||||
@@ -26,11 +26,6 @@
|
|||||||
|
|
||||||
using namespace simgear;
|
using namespace simgear;
|
||||||
|
|
||||||
// SGReaderWriterBTGOptions static value here to avoid an additional,
|
|
||||||
// tiny source file.
|
|
||||||
|
|
||||||
std::string SGReaderWriterBTGOptions::defaultOptions;
|
|
||||||
|
|
||||||
SGReaderWriterBTG::SGReaderWriterBTG()
|
SGReaderWriterBTG::SGReaderWriterBTG()
|
||||||
{
|
{
|
||||||
supportsExtension("btg", "SimGear btg database format");
|
supportsExtension("btg", "SimGear btg database format");
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
#include <simgear/scene/tgdb/obj.hxx>
|
#include <simgear/scene/tgdb/obj.hxx>
|
||||||
class SGReaderWriterBTGOptions : public osgDB::ReaderWriter::Options {
|
class SGReaderWriterBTGOptions : public osgDB::ReaderWriter::Options {
|
||||||
public:
|
public:
|
||||||
SGReaderWriterBTGOptions(const std::string& str = defaultOptions) :
|
SGReaderWriterBTGOptions(const std::string& str = std::string()) :
|
||||||
osgDB::ReaderWriter::Options(str),
|
osgDB::ReaderWriter::Options(str),
|
||||||
_matlib(0), _calcLights(true),
|
_matlib(0), _calcLights(true),
|
||||||
_useRandomObjects(false),
|
_useRandomObjects(false),
|
||||||
@@ -57,6 +57,5 @@ protected:
|
|||||||
bool _calcLights;
|
bool _calcLights;
|
||||||
bool _useRandomObjects;
|
bool _useRandomObjects;
|
||||||
bool _useRandomVegetation;
|
bool _useRandomVegetation;
|
||||||
static std::string defaultOptions;
|
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -141,7 +141,6 @@ TileEntry::TileEntry ( const SGBucket& b )
|
|||||||
: tile_bucket( b ),
|
: tile_bucket( b ),
|
||||||
_node( new osg::LOD ),
|
_node( new osg::LOD ),
|
||||||
is_inner_ring(false),
|
is_inner_ring(false),
|
||||||
free_tracker(0),
|
|
||||||
tileFileName(b.gen_index_str())
|
tileFileName(b.gen_index_str())
|
||||||
{
|
{
|
||||||
_node->setUpdateCallback(new FGTileUpdateCallback);
|
_node->setUpdateCallback(new FGTileUpdateCallback);
|
||||||
@@ -172,50 +171,16 @@ static void WorldCoordinate(osg::Matrix& obj_pos, double lat,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Free "n" leaf elements of an ssg tree. returns the number of
|
|
||||||
// elements freed. An empty branch node is considered a leaf. This
|
|
||||||
// is intended to spread the load of freeing a complex tile out over
|
|
||||||
// several frames.
|
|
||||||
static int fgPartialFreeSSGtree( osg::Group *b, int n ) {
|
|
||||||
int num_deletes = b->getNumChildren();
|
|
||||||
|
|
||||||
b->removeChildren(0, b->getNumChildren());
|
|
||||||
|
|
||||||
return num_deletes;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Clean up the memory used by this tile and delete the arrays used by
|
// Clean up the memory used by this tile and delete the arrays used by
|
||||||
// ssg as well as the whole ssg branch
|
// ssg as well as the whole ssg branch
|
||||||
bool TileEntry::free_tile() {
|
bool TileEntry::free_tile() {
|
||||||
int delete_size = 100;
|
|
||||||
SG_LOG( SG_TERRAIN, SG_DEBUG,
|
SG_LOG( SG_TERRAIN, SG_DEBUG,
|
||||||
"FREEING TILE = (" << tile_bucket << ")" );
|
"FREEING TILE = (" << tile_bucket << ")" );
|
||||||
|
|
||||||
SG_LOG( SG_TERRAIN, SG_DEBUG, "(start) free_tracker = " << free_tracker );
|
_node->removeChildren(0, _node->getNumChildren());
|
||||||
|
_node = 0;
|
||||||
|
|
||||||
if ( !(free_tracker & NODES) ) {
|
return true;
|
||||||
free_tracker |= NODES;
|
|
||||||
} else if ( !(free_tracker & VEC_PTRS) ) {
|
|
||||||
free_tracker |= VEC_PTRS;
|
|
||||||
} else if ( !(free_tracker & TERRA_NODE) ) {
|
|
||||||
// delete the terrain branch (this should already have been
|
|
||||||
// disconnected from the scene graph)
|
|
||||||
SG_LOG( SG_TERRAIN, SG_DEBUG, "FREEING terra_transform" );
|
|
||||||
if ( fgPartialFreeSSGtree( _node.get(), delete_size ) == 0 ) {
|
|
||||||
_node = 0;
|
|
||||||
free_tracker |= TERRA_NODE;
|
|
||||||
}
|
|
||||||
} else if ( !(free_tracker & LIGHTMAPS) ) {
|
|
||||||
free_tracker |= LIGHTMAPS;
|
|
||||||
} else {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
SG_LOG( SG_TERRAIN, SG_DEBUG, "(end) free_tracker = " << free_tracker );
|
|
||||||
|
|
||||||
// if we fall down to here, we still have work todo, return false
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -230,8 +195,8 @@ void TileEntry::prep_ssg_node(float vis) {
|
|||||||
_node->setRange( 0, 0, vis + bounding_radius );
|
_node->setRange( 0, 0, vis + bounding_radius );
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TileEntry::obj_load( const string& path,
|
bool TileEntry::obj_load(const string& path, osg::Group *geometry, bool is_base,
|
||||||
osg::Group *geometry, bool is_base, const osgDB::ReaderWriter::Options*options)
|
const osgDB::ReaderWriter::Options* options)
|
||||||
{
|
{
|
||||||
osg::Node* node = osgDB::readNodeFile(path, options);
|
osg::Node* node = osgDB::readNodeFile(path, options);
|
||||||
if (node)
|
if (node)
|
||||||
@@ -386,7 +351,13 @@ TileEntry::loadTileByName(const string& index_str,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SGReaderWriterBTGOptions *opt = new SGReaderWriterBTGOptions(*dynamic_cast<const SGReaderWriterBTGOptions *>(options));
|
const SGReaderWriterBTGOptions* btgOpt;
|
||||||
|
btgOpt = dynamic_cast<const SGReaderWriterBTGOptions *>(options);
|
||||||
|
osg::ref_ptr<SGReaderWriterBTGOptions> opt;
|
||||||
|
if (btgOpt)
|
||||||
|
opt = new SGReaderWriterBTGOptions(*btgOpt);
|
||||||
|
else
|
||||||
|
opt = new SGReaderWriterBTGOptions;
|
||||||
|
|
||||||
// obj_load() will generate ground lighting for us ...
|
// obj_load() will generate ground lighting for us ...
|
||||||
osg::Group* new_tile = new osg::Group;
|
osg::Group* new_tile = new osg::Group;
|
||||||
@@ -394,7 +365,7 @@ TileEntry::loadTileByName(const string& index_str,
|
|||||||
if (found_tile_base) {
|
if (found_tile_base) {
|
||||||
// load tile if found ...
|
// load tile if found ...
|
||||||
opt->setCalcLights(true);
|
opt->setCalcLights(true);
|
||||||
obj_load( object_base.str(), new_tile, true, options);
|
obj_load( object_base.str(), new_tile, true, opt);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// ... or generate an ocean tile on the fly
|
// ... or generate an ocean tile on the fly
|
||||||
@@ -415,7 +386,7 @@ TileEntry::loadTileByName(const string& index_str,
|
|||||||
SGPath custom_path = obj->path;
|
SGPath custom_path = obj->path;
|
||||||
custom_path.append( obj->name );
|
custom_path.append( obj->name );
|
||||||
opt->setCalcLights(true);
|
opt->setCalcLights(true);
|
||||||
obj_load( custom_path.str(), new_tile, false, options);
|
obj_load( custom_path.str(), new_tile, false, opt);
|
||||||
|
|
||||||
} else if (obj->type == OBJECT_SHARED || obj->type == OBJECT_STATIC) {
|
} else if (obj->type == OBJECT_SHARED || obj->type == OBJECT_STATIC) {
|
||||||
// object loading is deferred to main render thread,
|
// object loading is deferred to main render thread,
|
||||||
|
|||||||
@@ -91,22 +91,6 @@ private:
|
|||||||
*/
|
*/
|
||||||
bool is_inner_ring;
|
bool is_inner_ring;
|
||||||
|
|
||||||
/**
|
|
||||||
* this variable tracks the status of the incremental memory
|
|
||||||
* freeing.
|
|
||||||
*/
|
|
||||||
enum {
|
|
||||||
NODES = 0x01,
|
|
||||||
VEC_PTRS = 0x02,
|
|
||||||
TERRA_NODE = 0x04,
|
|
||||||
GROUND_LIGHTS = 0x08,
|
|
||||||
VASI_LIGHTS = 0x10,
|
|
||||||
RWY_LIGHTS = 0x20,
|
|
||||||
TAXI_LIGHTS = 0x40,
|
|
||||||
LIGHTMAPS = 0x80
|
|
||||||
};
|
|
||||||
int free_tracker;
|
|
||||||
|
|
||||||
static ModelLoadHelper *_modelLoader;
|
static ModelLoadHelper *_modelLoader;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -129,7 +129,9 @@ struct SGTileGeometryBin {
|
|||||||
|
|
||||||
for (unsigned grp = 0; grp < obj.get_pts_v().size(); ++grp) {
|
for (unsigned grp = 0; grp < obj.get_pts_v().size(); ++grp) {
|
||||||
std::string materialName = obj.get_pt_materials()[grp];
|
std::string materialName = obj.get_pt_materials()[grp];
|
||||||
SGMaterial* material = matlib->find(materialName);
|
SGMaterial* material = 0;
|
||||||
|
if (matlib)
|
||||||
|
material = matlib->find(materialName);
|
||||||
SGVec4f color = getMaterialLightColor(material);
|
SGVec4f color = getMaterialLightColor(material);
|
||||||
|
|
||||||
if (3 <= materialName.size() && materialName.substr(0, 3) != "RWY") {
|
if (3 <= materialName.size() && materialName.substr(0, 3) != "RWY") {
|
||||||
@@ -369,7 +371,9 @@ struct SGTileGeometryBin {
|
|||||||
SGMaterialTriangleMap::const_iterator i;
|
SGMaterialTriangleMap::const_iterator i;
|
||||||
for (i = materialTriangleMap.begin(); i != materialTriangleMap.end(); ++i) {
|
for (i = materialTriangleMap.begin(); i != materialTriangleMap.end(); ++i) {
|
||||||
osg::Geometry* geometry = i->second.buildGeometry();
|
osg::Geometry* geometry = i->second.buildGeometry();
|
||||||
SGMaterial *mat = matlib->find(i->first);
|
SGMaterial *mat = 0;
|
||||||
|
if (matlib)
|
||||||
|
mat = matlib->find(i->first);
|
||||||
if (mat)
|
if (mat)
|
||||||
geometry->setStateSet(mat->get_state());
|
geometry->setStateSet(mat->get_state());
|
||||||
geode->addDrawable(geometry);
|
geode->addDrawable(geometry);
|
||||||
@@ -584,7 +588,8 @@ SGLoadBTG(const std::string& path, SGMaterialLib *matlib, bool calc_lights, bool
|
|||||||
|
|
||||||
if (use_random_objects || use_random_vegetation) {
|
if (use_random_objects || use_random_vegetation) {
|
||||||
if (use_random_objects) {
|
if (use_random_objects) {
|
||||||
tileGeometryBin.computeRandomObjects(matlib);
|
if (matlib)
|
||||||
|
tileGeometryBin.computeRandomObjects(matlib);
|
||||||
|
|
||||||
if (tileGeometryBin.randomModels.getNumModels() > 0) {
|
if (tileGeometryBin.randomModels.getNumModels() > 0) {
|
||||||
// Generate a repeatable random seed
|
// Generate a repeatable random seed
|
||||||
@@ -621,7 +626,7 @@ SGLoadBTG(const std::string& path, SGMaterialLib *matlib, bool calc_lights, bool
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (use_random_vegetation) {
|
if (use_random_vegetation && matlib) {
|
||||||
// Now add some random forest.
|
// Now add some random forest.
|
||||||
tileGeometryBin.computeRandomForest(matlib);
|
tileGeometryBin.computeRandomForest(matlib);
|
||||||
|
|
||||||
@@ -635,7 +640,8 @@ SGLoadBTG(const std::string& path, SGMaterialLib *matlib, bool calc_lights, bool
|
|||||||
|
|
||||||
if (calc_lights) {
|
if (calc_lights) {
|
||||||
// FIXME: ugly, has a side effect
|
// FIXME: ugly, has a side effect
|
||||||
tileGeometryBin.computeRandomSurfaceLights(matlib);
|
if (matlib)
|
||||||
|
tileGeometryBin.computeRandomSurfaceLights(matlib);
|
||||||
|
|
||||||
if (tileGeometryBin.tileLights.getNumLights() > 0
|
if (tileGeometryBin.tileLights.getNumLights() > 0
|
||||||
|| tileGeometryBin.randomTileLights.getNumLights() > 0) {
|
|| tileGeometryBin.randomTileLights.getNumLights() > 0) {
|
||||||
@@ -669,11 +675,15 @@ SGLoadBTG(const std::string& path, SGMaterialLib *matlib, bool calc_lights, bool
|
|||||||
if (!tileGeometryBin.vasiLights.empty()) {
|
if (!tileGeometryBin.vasiLights.empty()) {
|
||||||
osg::Geode* vasiGeode = new osg::Geode;
|
osg::Geode* vasiGeode = new osg::Geode;
|
||||||
SGVec4f red(1, 0, 0, 1);
|
SGVec4f red(1, 0, 0, 1);
|
||||||
SGMaterial* mat = matlib->find("RWY_RED_LIGHTS");
|
SGMaterial* mat = 0;
|
||||||
|
if (matlib)
|
||||||
|
mat = matlib->find("RWY_RED_LIGHTS");
|
||||||
if (mat)
|
if (mat)
|
||||||
red = mat->get_light_color();
|
red = mat->get_light_color();
|
||||||
SGVec4f white(1, 1, 1, 1);
|
SGVec4f white(1, 1, 1, 1);
|
||||||
mat = matlib->find("RWY_WHITE_LIGHTS");
|
mat = 0;
|
||||||
|
if (matlib)
|
||||||
|
mat = matlib->find("RWY_WHITE_LIGHTS");
|
||||||
if (mat)
|
if (mat)
|
||||||
white = mat->get_light_color();
|
white = mat->get_light_color();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user