Changes to the model interior LOD management.
If a model is marked as <usage>interior</usage> there were a number of problems. 1 - the LOD setting AI/MP interior used the distance from the aircraft; this obviously doesn't quite work for when using the model view. 2 - with the way that models are now loaded as two LOD levels only the interior from the first model loaded (usually the lowest detail) would be considered or processed because the model loader had marked itself as already run (which it had, but not for the model that was actually just loaded. (2) above could also be the cause of other things not working because the nasal model loaded would not be called, nor would the sound path be setup. There could be other things that aren't working properly because the assumption is that there is just one model. The fix for (1) is to use the standard OSG PagedLOD and let it handle the details, so I've changed the interior to use this and removed the distane from ownship checks. The fix for (2) is to use a map to decide if the model that has just finished loading has already been processed, and if not then proceed as normal.
This commit is contained in:
parent
e970db3c61
commit
88720a031b
3 changed files with 34 additions and 14 deletions
|
@ -77,9 +77,12 @@ public:
|
|||
void modelLoaded(const std::string& path, SGPropertyNode *prop, osg::Node *n)
|
||||
{
|
||||
// WARNING: Called in a separate OSG thread! Only use thread-safe stuff here...
|
||||
if (_ready)
|
||||
if (_ready && _modelLoaded.count(path) > 0)
|
||||
return;
|
||||
|
||||
_modelLoaded[path] = true;
|
||||
_ready = true;
|
||||
|
||||
if(prop->hasChild("interior-path")){
|
||||
_interiorPath = prop->getStringValue("interior-path");
|
||||
_hasInteriorPath = true;
|
||||
|
@ -88,7 +91,6 @@ public:
|
|||
_fxpath = prop->getStringValue("sound/path");
|
||||
_nasal->modelLoaded(path, prop, n);
|
||||
|
||||
_ready = true;
|
||||
|
||||
}
|
||||
|
||||
|
@ -109,6 +111,7 @@ private:
|
|||
std::string _fxpath;
|
||||
std::string _interiorPath;
|
||||
|
||||
std::map<string, bool> _modelLoaded;
|
||||
bool _ready = false;
|
||||
bool _initialized = false;
|
||||
bool _hasInteriorPath = false;
|
||||
|
@ -305,16 +308,21 @@ void FGAIBase::updateInterior()
|
|||
if(!_modeldata || !_modeldata->hasInteriorPath())
|
||||
return;
|
||||
|
||||
if(!_modeldata->getInteriorLoaded()){ // interior is not yet load
|
||||
double d2 = dist(SGVec3d::fromGeod(pos), globals->get_aircraft_position_cart());
|
||||
if(d2 <= _maxRangeInterior){ // if the AI is in-range we load the interior
|
||||
_interior = SGModelLib::loadPagedModel(_modeldata->getInteriorPath(), props, _modeldata);
|
||||
if(_interior.valid()){
|
||||
_interior->setRange(0, 0.0, _maxRangeInterior);
|
||||
aip.add(_interior.get());
|
||||
_modeldata->setInteriorLoaded(true);
|
||||
SG_LOG(SG_AI, SG_INFO, "AIBase: Loaded interior model " << _interior->getName());
|
||||
if (!_modeldata->getInteriorLoaded()) { // interior is not yet load
|
||||
_interior = SGModelLib::loadPagedModel(_modeldata->getInteriorPath(), props, _modeldata);
|
||||
if (_interior.valid()) {
|
||||
bool pixel_mode = !fgGetBool("/sim/rendering/static-lod/aimp-range-mode-distance", false);
|
||||
if (pixel_mode) {
|
||||
_interior->setRangeMode(osg::LOD::PIXEL_SIZE_ON_SCREEN);
|
||||
_interior->setRange(0, _maxRangeInterior, FLT_MAX);
|
||||
}
|
||||
else {
|
||||
_interior->setRangeMode(osg::LOD::DISTANCE_FROM_EYE_POINT);
|
||||
_interior->setRange(0, 0.0, _maxRangeInterior);
|
||||
}
|
||||
aip.add(_interior.get());
|
||||
_modeldata->setInteriorLoaded(true);
|
||||
SG_LOG(SG_AI, SG_INFO, "AIBase: Loaded interior model " << _interior->getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -324,7 +332,6 @@ void FGAIBase::updateLOD()
|
|||
{
|
||||
double maxRangeDetail = fgGetDouble("/sim/rendering/static-lod/aimp-detailed", 3000.0);
|
||||
double maxRangeBare = fgGetDouble("/sim/rendering/static-lod/aimp-bare", 10000.0);
|
||||
|
||||
_maxRangeInterior = fgGetDouble("/sim/rendering/static-lod/aimp-interior", 50.0);
|
||||
|
||||
if (_model.valid())
|
||||
|
@ -431,6 +438,16 @@ void FGAIBase::updateLOD()
|
|||
}
|
||||
}
|
||||
}
|
||||
if (_modeldata->getInteriorLoaded() && _interior.valid()) {
|
||||
if (pixel_mode) {
|
||||
_interior->setRangeMode(osg::LOD::PIXEL_SIZE_ON_SCREEN);
|
||||
_interior->setRange(0, _maxRangeInterior, FLT_MAX);
|
||||
}
|
||||
else {
|
||||
_interior->setRangeMode(osg::LOD::DISTANCE_FROM_EYE_POINT);
|
||||
_interior->setRange(0, 0.0, _maxRangeInterior);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -106,8 +106,10 @@ private:
|
|||
FGAIManager::FGAIManager() :
|
||||
cb_ai_bare(SGPropertyChangeCallback<FGAIManager>(this,&FGAIManager::updateLOD,
|
||||
fgGetNode("/sim/rendering/static-lod/aimp-bare", true))),
|
||||
cb_ai_detailed(SGPropertyChangeCallback<FGAIManager>(this,&FGAIManager::updateLOD,
|
||||
fgGetNode("/sim/rendering/static-lod/aimp-detailed", true)))
|
||||
cb_ai_detailed(SGPropertyChangeCallback<FGAIManager>(this, &FGAIManager::updateLOD,
|
||||
fgGetNode("/sim/rendering/static-lod/aimp-detailed", true))),
|
||||
cb_interior(SGPropertyChangeCallback<FGAIManager>(this, &FGAIManager::updateLOD,
|
||||
fgGetNode("/sim/rendering/static-lod/aimp-interior", true)))
|
||||
{
|
||||
|
||||
}
|
||||
|
|
|
@ -150,6 +150,7 @@ private:
|
|||
|
||||
SGPropertyChangeCallback<FGAIManager> cb_ai_bare;
|
||||
SGPropertyChangeCallback<FGAIManager> cb_ai_detailed;
|
||||
SGPropertyChangeCallback<FGAIManager> cb_interior;
|
||||
|
||||
class Scenario;
|
||||
typedef std::map<std::string, Scenario*> ScenarioDict;
|
||||
|
|
Loading…
Reference in a new issue