Multiple LoD levels of MP Aircraft
Support loading multiple models into PagedLOD.
This commit is contained in:
@@ -161,33 +161,68 @@ SGModelLib::loadDeferredModel(const string &path, SGPropertyNode *prop_root,
|
|||||||
return proxyNode;
|
return proxyNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Load a set of models at different LOD range_nearest
|
||||||
|
*
|
||||||
|
*/
|
||||||
osg::PagedLOD*
|
osg::PagedLOD*
|
||||||
SGModelLib::loadPagedModel(const string &path, SGPropertyNode *prop_root,
|
SGModelLib::loadPagedModel(SGPropertyNode *prop_root, SGModelData *data, SGModelLOD model_lods)
|
||||||
SGModelData *data)
|
|
||||||
{
|
{
|
||||||
osg::PagedLOD *plod = new osg::PagedLOD;
|
osg::PagedLOD *plod = new osg::PagedLOD;
|
||||||
plod->setName("Paged LOD for \"" + path + "\"");
|
|
||||||
plod->setFileName(0, path);
|
|
||||||
plod->setRange(0, 0.0, 50.0*SG_NM_TO_METER);
|
|
||||||
plod->setMinimumExpiryTime( 0, prop_root->getDoubleValue("/sim/rendering/plod-minimum-expiry-time-secs", 180.0 ) );
|
|
||||||
|
|
||||||
osg::ref_ptr<SGReaderWriterOptions> opt;
|
osg::ref_ptr<SGReaderWriterOptions> opt;
|
||||||
opt = SGReaderWriterOptions::copyOrCreate(osgDB::Registry::instance()->getOptions());
|
opt = SGReaderWriterOptions::copyOrCreate(osgDB::Registry::instance()->getOptions());
|
||||||
opt->setPropertyNode(prop_root ? prop_root: static_propRoot.get());
|
opt->setPropertyNode(prop_root ? prop_root: static_propRoot.get());
|
||||||
opt->setModelData(data);
|
opt->setModelData(data);
|
||||||
opt->setLoadPanel(static_panelFunc);
|
opt->setLoadPanel(static_panelFunc);
|
||||||
std::string lext = SGPath(path).lower_extension();
|
|
||||||
|
|
||||||
if ((lext == "ac") || (lext == "obj")) {
|
|
||||||
opt->setInstantiateEffects(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!prop_root || prop_root->getBoolValue("/sim/rendering/cache", true))
|
if (!prop_root || prop_root->getBoolValue("/sim/rendering/cache", true))
|
||||||
opt->setObjectCacheHint(osgDB::Options::CACHE_ALL);
|
opt->setObjectCacheHint(osgDB::Options::CACHE_ALL);
|
||||||
else
|
else
|
||||||
opt->setObjectCacheHint(osgDB::Options::CACHE_NONE);
|
opt->setObjectCacheHint(osgDB::Options::CACHE_NONE);
|
||||||
|
|
||||||
|
for(unsigned int i = 0; i < model_lods.getNumLODs(); i++) {
|
||||||
|
SGModelLOD::ModelLOD lod = model_lods.getModelLOD(i);
|
||||||
|
plod->setName("Paged LOD for \"" + lod.path + "\"");
|
||||||
|
plod->setFileName(i, lod.path);
|
||||||
|
plod->setRange(i, lod.min_range, lod.max_range);
|
||||||
|
plod->setMinimumExpiryTime(i, prop_root->getDoubleValue("/sim/rendering/plod-minimum-expiry-time-secs", 180.0 ) );
|
||||||
|
|
||||||
|
std::string lext = SGPath(lod.path).lower_extension();
|
||||||
|
|
||||||
|
// We can only have one set of ReaderWriterOptions for the PagedLOD, so
|
||||||
|
// we will just have to assume that if one of the defined models can
|
||||||
|
// handle instantiated effects, then the other can as well.
|
||||||
|
if ((lext == "ac") || (lext == "obj")) {
|
||||||
|
opt->setInstantiateEffects(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
plod->setDatabaseOptions(opt.get());
|
plod->setDatabaseOptions(opt.get());
|
||||||
|
|
||||||
return plod;
|
return plod;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
osg::PagedLOD*
|
||||||
|
SGModelLib::loadPagedModel(const string &path, SGPropertyNode *prop_root,
|
||||||
|
SGModelData *data)
|
||||||
|
{
|
||||||
|
SGModelLOD model_lods;
|
||||||
|
model_lods.insert(path, 0.0, 50.0*SG_NM_TO_METER);
|
||||||
|
return SGModelLib::loadPagedModel(prop_root, data, model_lods);
|
||||||
|
}
|
||||||
|
|
||||||
|
osg::PagedLOD*
|
||||||
|
SGModelLib::loadPagedModel(std::vector<string> paths, SGPropertyNode *prop_root,
|
||||||
|
SGModelData *data)
|
||||||
|
{
|
||||||
|
SGModelLOD model_lods;
|
||||||
|
for(unsigned int i = 0; i < paths.size(); i++) {
|
||||||
|
// We don't have any range data, so simply set them all up to full range.
|
||||||
|
// Some other code will update the LoD ranges later. (AIBase::updateLOD)
|
||||||
|
model_lods.insert(paths[i], 0.0, 50.0*SG_NM_TO_METER);
|
||||||
|
}
|
||||||
|
return SGModelLib::loadPagedModel(prop_root, data, model_lods);
|
||||||
|
}
|
||||||
|
|
||||||
// end of modellib.cxx
|
// end of modellib.cxx
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ namespace osg {
|
|||||||
namespace simgear {
|
namespace simgear {
|
||||||
|
|
||||||
class SGModelData; // defined below
|
class SGModelData; // defined below
|
||||||
|
class SGModelLOD; // defined below
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class for loading and managing models with XML wrappers.
|
* Class for loading and managing models with XML wrappers.
|
||||||
@@ -72,10 +73,17 @@ public:
|
|||||||
// the model file. Once the viewer steps onto that node the
|
// the model file. Once the viewer steps onto that node the
|
||||||
// model will be loaded. When the viewer does no longer reference this
|
// model will be loaded. When the viewer does no longer reference this
|
||||||
// node for a long time the node is unloaded again.
|
// node for a long time the node is unloaded again.
|
||||||
|
static osg::PagedLOD* loadPagedModel(SGPropertyNode *prop_root,
|
||||||
|
SGModelData *data,
|
||||||
|
SGModelLOD model_lods);
|
||||||
static osg::PagedLOD* loadPagedModel(const std::string &path,
|
static osg::PagedLOD* loadPagedModel(const std::string &path,
|
||||||
SGPropertyNode *prop_root = NULL,
|
SGPropertyNode *prop_root = NULL,
|
||||||
SGModelData *data=0);
|
SGModelData *data=0);
|
||||||
|
|
||||||
|
static osg::PagedLOD* loadPagedModel(std::vector<string> paths,
|
||||||
|
SGPropertyNode *prop_root = NULL,
|
||||||
|
SGModelData *data=0);
|
||||||
|
|
||||||
static std::string findDataFile(const std::string& file,
|
static std::string findDataFile(const std::string& file,
|
||||||
const osgDB::Options* opts = NULL,
|
const osgDB::Options* opts = NULL,
|
||||||
SGPath currentDir = SGPath());
|
SGPath currentDir = SGPath());
|
||||||
@@ -102,6 +110,39 @@ public:
|
|||||||
virtual SGModelData* clone() const = 0;
|
virtual SGModelData* clone() const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Data for a model with multiple LoD versions
|
||||||
|
*/
|
||||||
|
|
||||||
|
class SGModelLOD {
|
||||||
|
public:
|
||||||
|
struct ModelLOD {
|
||||||
|
ModelLOD(const string &p, float minrange, float maxrange) :
|
||||||
|
path(p), min_range(minrange), max_range(maxrange)
|
||||||
|
{ }
|
||||||
|
const string &path;
|
||||||
|
float min_range;
|
||||||
|
float max_range;
|
||||||
|
};
|
||||||
|
typedef std::vector<ModelLOD> ModelLODList;
|
||||||
|
|
||||||
|
void insert(const ModelLOD& model)
|
||||||
|
{
|
||||||
|
_models.push_back(model);
|
||||||
|
}
|
||||||
|
|
||||||
|
void insert(const string &p, float minrange, float maxrange)
|
||||||
|
{
|
||||||
|
insert(ModelLOD(p, minrange, maxrange));
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned getNumLODs() const { return _models.size(); }
|
||||||
|
const ModelLOD& getModelLOD(unsigned i) const { return _models[i]; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
ModelLODList _models;
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // _SG_MODEL_LIB_HXX
|
#endif // _SG_MODEL_LIB_HXX
|
||||||
|
|||||||
Reference in New Issue
Block a user