model.[ch]xx:

add abstract class SGModelData. If a pointer to such a class is handed over
  to sgLoad3DModel, then its modelLoaded() method is called with path, property
  node and branch. And then it's added to the scene graph so that it's
  destroyed when the model branch is removed from the graph.

modellib.[ch]xx:
  only cache objects when asked to. This is the case for OBJECT_SHARED
  and random objects (like before), but no longer for OBJECT_STATIC.
  These are now removed from the graph when they are "out of sight". This
  prevents accumulation of static models, and makes destroying model data
  possible (e.g. removing Nasal modules)

matmodel.cxx:
  set cache flag for random objects (same behavior as before)
This commit is contained in:
mfranz 2006-03-09 09:03:57 +00:00
parent dcb95d131b
commit 359a8c4a81
5 changed files with 39 additions and 8 deletions

View File

@ -146,7 +146,8 @@ SGMatModel::load_models ( SGModelLib *modellib,
if (!_models_loaded) { if (!_models_loaded) {
for (unsigned int i = 0; i < _paths.size(); i++) { for (unsigned int i = 0; i < _paths.size(); i++) {
ssgEntity *entity = modellib->load_model( fg_root, _paths[i], ssgEntity *entity = modellib->load_model( fg_root, _paths[i],
prop_root, sim_time_sec ); prop_root, sim_time_sec,
/*cache_object*/ true );
if (entity != 0) { if (entity != 0) {
// FIXME: this stuff can be handled // FIXME: this stuff can be handled
// in the XML wrapper as well (at least, // in the XML wrapper as well (at least,

View File

@ -245,7 +245,8 @@ static void makeDList( ssgBranch *b, const set<ssgBranch *> &ignore )
ssgBranch * ssgBranch *
sgLoad3DModel( const string &fg_root, const string &path, sgLoad3DModel( const string &fg_root, const string &path,
SGPropertyNode *prop_root, SGPropertyNode *prop_root,
double sim_time_sec, ssgEntity *(*load_panel)(SGPropertyNode *) ) double sim_time_sec, ssgEntity *(*load_panel)(SGPropertyNode *),
SGModelData *data )
{ {
ssgBranch * model = 0; ssgBranch * model = 0;
SGPropertyNode props; SGPropertyNode props;
@ -336,6 +337,11 @@ sgLoad3DModel( const string &fg_root, const string &path,
model->addKid(panel); model->addKid(panel);
} }
} }
if (data) {
data->modelLoaded(path, &props, model);
model->setUserData(data);
}
// Load animations // Load animations
set<ssgBranch *> ignore_branches; set<ssgBranch *> ignore_branches;
vector<SGPropertyNode_ptr> animation_nodes = props.getChildren("animation"); vector<SGPropertyNode_ptr> animation_nodes = props.getChildren("animation");
@ -353,6 +359,9 @@ sgLoad3DModel( const string &fg_root, const string &path,
} }
#endif #endif
int m = props.getIntValue("dump", 0);
if (m > 0)
model->print(stderr, "", m - 1);
return alignmainmodel; return alignmainmodel;
} }

View File

@ -32,6 +32,19 @@ SG_USING_STD(set);
#endif #endif
/**
* Abstract class for adding data to the scene graph. modelLoaded() is
* called by sgLoad3DModel() after the model was loaded, and the destructor
* when the branch is removed from the graph.
*/
class SGModelData : public ssgBase {
public:
virtual ~SGModelData() {}
virtual void modelLoaded( const string& path, SGPropertyNode *prop,
ssgBranch *branch) {}
};
/** /**
* Load a 3D model with or without XML wrapper. Note, this version * Load a 3D model with or without XML wrapper. Note, this version
* Does not know about or load the panel/cockpit information. Use the * Does not know about or load the panel/cockpit information. Use the
@ -47,7 +60,8 @@ SG_USING_STD(set);
ssgBranch * ssgBranch *
sgLoad3DModel( const string& fg_root, const string &path, sgLoad3DModel( const string& fg_root, const string &path,
SGPropertyNode *prop_root, double sim_time_sec, SGPropertyNode *prop_root, double sim_time_sec,
ssgEntity *(*load_panel)(SGPropertyNode *) = 0 ); ssgEntity *(*load_panel)(SGPropertyNode *) = 0,
SGModelData *data = 0 );
/** /**

View File

@ -81,7 +81,9 @@ ssgEntity *
SGModelLib::load_model( const string &fg_root, SGModelLib::load_model( const string &fg_root,
const string &path, const string &path,
SGPropertyNode *prop_root, SGPropertyNode *prop_root,
double sim_time_sec ) double sim_time_sec,
bool cache_object,
SGModelData *data )
{ {
ssgBranch *personality_branch = new SGPersonalityBranch; ssgBranch *personality_branch = new SGPersonalityBranch;
personality_branch->setTravCallback(SSG_CALLBACK_PRETRAV, personality_pretrav_callback); personality_branch->setTravCallback(SSG_CALLBACK_PRETRAV, personality_pretrav_callback);
@ -90,10 +92,12 @@ SGModelLib::load_model( const string &fg_root,
// FIXME: normalize path to // FIXME: normalize path to
// avoid duplicates. // avoid duplicates.
map<string, ssgSharedPtr<ssgEntity> >::iterator it = _table.find(path); map<string, ssgSharedPtr<ssgEntity> >::iterator it = _table.find(path);
if (it == _table.end()) { if (!cache_object || it == _table.end()) {
ssgSharedPtr<ssgEntity> model = sgLoad3DModel(fg_root, path, prop_root, ssgSharedPtr<ssgEntity> model = sgLoad3DModel(fg_root, path, prop_root,
sim_time_sec ); sim_time_sec, 0, data );
if (cache_object)
_table[path] = model; // add one reference to keep it around _table[path] = model; // add one reference to keep it around
personality_branch->addKid( model ); personality_branch->addKid( model );
} else { } else {
personality_branch->addKid( it->second ); personality_branch->addKid( it->second );

View File

@ -16,6 +16,7 @@
#include <simgear/structure/ssgSharedPtr.hxx> #include <simgear/structure/ssgSharedPtr.hxx>
#include <simgear/props/props.hxx> #include <simgear/props/props.hxx>
#include "model.hxx"
SG_USING_STD(map); SG_USING_STD(map);
SG_USING_STD(string); SG_USING_STD(string);
@ -36,7 +37,9 @@ public:
virtual ssgEntity *load_model( const string &fg_root, virtual ssgEntity *load_model( const string &fg_root,
const string &path, const string &path,
SGPropertyNode *prop_root, SGPropertyNode *prop_root,
double sim_time_sec ); double sim_time_sec,
bool cache_object,
SGModelData *data = 0 );
protected: protected:
map<string,ssgSharedPtr<ssgEntity> > _table; map<string,ssgSharedPtr<ssgEntity> > _table;