Multiple LoD levels of MP Aircraft

Support loading multiple models into PagedLOD.
This commit is contained in:
Stuart Buchanan 2018-06-05 21:56:36 +01:00
parent 1d7c3984ca
commit 7fb89e4d45
2 changed files with 93 additions and 17 deletions

View File

@ -161,33 +161,68 @@ SGModelLib::loadDeferredModel(const string &path, SGPropertyNode *prop_root,
return proxyNode;
}
/*
* Load a set of models at different LOD range_nearest
*
*/
osg::PagedLOD*
SGModelLib::loadPagedModel(const string &path, SGPropertyNode *prop_root,
SGModelData *data)
SGModelLib::loadPagedModel(SGPropertyNode *prop_root, SGModelData *data, SGModelLOD model_lods)
{
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;
opt = SGReaderWriterOptions::copyOrCreate(osgDB::Registry::instance()->getOptions());
opt->setPropertyNode(prop_root ? prop_root: static_propRoot.get());
opt->setModelData(data);
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))
opt->setObjectCacheHint(osgDB::Options::CACHE_ALL);
else
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());
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

View File

@ -39,6 +39,7 @@ namespace osg {
namespace simgear {
class SGModelData; // defined below
class SGModelLOD; // defined below
/**
* Class for loading and managing models with XML wrappers.
@ -51,9 +52,9 @@ public:
static void init(const std::string &root_dir, SGPropertyNode* root);
static void resetPropertyRoot();
static void setPanelFunc(panel_func pf);
// Load a 3D model (any format)
// data->modelLoaded() will be called after the model is loaded
static osg::Node* loadModel(const std::string &path,
@ -72,17 +73,24 @@ public:
// the model file. Once the viewer steps onto that node the
// model will be loaded. When the viewer does no longer reference this
// 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,
SGPropertyNode *prop_root = NULL,
SGModelData *data=0);
static std::string findDataFile(const std::string& file,
static osg::PagedLOD* loadPagedModel(std::vector<string> paths,
SGPropertyNode *prop_root = NULL,
SGModelData *data=0);
static std::string findDataFile(const std::string& file,
const osgDB::Options* opts = NULL,
SGPath currentDir = SGPath());
SGPath currentDir = SGPath());
protected:
SGModelLib();
~SGModelLib ();
private:
static SGPropertyNode_ptr static_propRoot;
static panel_func static_panelFunc;
@ -102,6 +110,39 @@ public:
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