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:
parent
dcb95d131b
commit
359a8c4a81
@ -146,7 +146,8 @@ SGMatModel::load_models ( SGModelLib *modellib,
|
||||
if (!_models_loaded) {
|
||||
for (unsigned int i = 0; i < _paths.size(); 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) {
|
||||
// FIXME: this stuff can be handled
|
||||
// in the XML wrapper as well (at least,
|
||||
|
@ -245,7 +245,8 @@ static void makeDList( ssgBranch *b, const set<ssgBranch *> &ignore )
|
||||
ssgBranch *
|
||||
sgLoad3DModel( const string &fg_root, const string &path,
|
||||
SGPropertyNode *prop_root,
|
||||
double sim_time_sec, ssgEntity *(*load_panel)(SGPropertyNode *) )
|
||||
double sim_time_sec, ssgEntity *(*load_panel)(SGPropertyNode *),
|
||||
SGModelData *data )
|
||||
{
|
||||
ssgBranch * model = 0;
|
||||
SGPropertyNode props;
|
||||
@ -336,6 +337,11 @@ sgLoad3DModel( const string &fg_root, const string &path,
|
||||
model->addKid(panel);
|
||||
}
|
||||
}
|
||||
|
||||
if (data) {
|
||||
data->modelLoaded(path, &props, model);
|
||||
model->setUserData(data);
|
||||
}
|
||||
// Load animations
|
||||
set<ssgBranch *> ignore_branches;
|
||||
vector<SGPropertyNode_ptr> animation_nodes = props.getChildren("animation");
|
||||
@ -353,6 +359,9 @@ sgLoad3DModel( const string &fg_root, const string &path,
|
||||
}
|
||||
#endif
|
||||
|
||||
int m = props.getIntValue("dump", 0);
|
||||
if (m > 0)
|
||||
model->print(stderr, "", m - 1);
|
||||
|
||||
return alignmainmodel;
|
||||
}
|
||||
|
@ -32,6 +32,19 @@ SG_USING_STD(set);
|
||||
#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
|
||||
* Does not know about or load the panel/cockpit information. Use the
|
||||
@ -47,7 +60,8 @@ SG_USING_STD(set);
|
||||
ssgBranch *
|
||||
sgLoad3DModel( const string& fg_root, const string &path,
|
||||
SGPropertyNode *prop_root, double sim_time_sec,
|
||||
ssgEntity *(*load_panel)(SGPropertyNode *) = 0 );
|
||||
ssgEntity *(*load_panel)(SGPropertyNode *) = 0,
|
||||
SGModelData *data = 0 );
|
||||
|
||||
|
||||
/**
|
||||
|
@ -81,7 +81,9 @@ ssgEntity *
|
||||
SGModelLib::load_model( const string &fg_root,
|
||||
const string &path,
|
||||
SGPropertyNode *prop_root,
|
||||
double sim_time_sec )
|
||||
double sim_time_sec,
|
||||
bool cache_object,
|
||||
SGModelData *data )
|
||||
{
|
||||
ssgBranch *personality_branch = new SGPersonalityBranch;
|
||||
personality_branch->setTravCallback(SSG_CALLBACK_PRETRAV, personality_pretrav_callback);
|
||||
@ -90,10 +92,12 @@ SGModelLib::load_model( const string &fg_root,
|
||||
// FIXME: normalize path to
|
||||
// avoid duplicates.
|
||||
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,
|
||||
sim_time_sec );
|
||||
_table[path] = model; // add one reference to keep it around
|
||||
sim_time_sec, 0, data );
|
||||
if (cache_object)
|
||||
_table[path] = model; // add one reference to keep it around
|
||||
|
||||
personality_branch->addKid( model );
|
||||
} else {
|
||||
personality_branch->addKid( it->second );
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
#include <simgear/structure/ssgSharedPtr.hxx>
|
||||
#include <simgear/props/props.hxx>
|
||||
#include "model.hxx"
|
||||
|
||||
SG_USING_STD(map);
|
||||
SG_USING_STD(string);
|
||||
@ -36,7 +37,9 @@ public:
|
||||
virtual ssgEntity *load_model( const string &fg_root,
|
||||
const string &path,
|
||||
SGPropertyNode *prop_root,
|
||||
double sim_time_sec );
|
||||
double sim_time_sec,
|
||||
bool cache_object,
|
||||
SGModelData *data = 0 );
|
||||
protected:
|
||||
|
||||
map<string,ssgSharedPtr<ssgEntity> > _table;
|
||||
|
Loading…
Reference in New Issue
Block a user