Update osg AI model LOD structure
This commit is contained in:
parent
b5dd4a8b6b
commit
bda359558c
3 changed files with 87 additions and 17 deletions
|
@ -237,6 +237,9 @@ FGAIBase::removeModel()
|
||||||
aip.clear();
|
aip.clear();
|
||||||
_modeldata = nullptr;
|
_modeldata = nullptr;
|
||||||
_model = nullptr;
|
_model = nullptr;
|
||||||
|
_interior = nullptr;
|
||||||
|
_high_res = nullptr;
|
||||||
|
_low_res = nullptr;
|
||||||
|
|
||||||
// pass it on to the pager, to be be deleted in the pager thread
|
// pass it on to the pager, to be be deleted in the pager thread
|
||||||
pSceneryManager->getPager()->queueDeleteRequest(temp);
|
pSceneryManager->getPager()->queueDeleteRequest(temp);
|
||||||
|
@ -378,6 +381,7 @@ void FGAIBase::updateInterior()
|
||||||
|
|
||||||
if (!_modeldata->getInteriorLoaded()) { // interior is not yet load
|
if (!_modeldata->getInteriorLoaded()) { // interior is not yet load
|
||||||
_interior = SGModelLib::loadPagedModel(_modeldata->getInteriorPath(), props, _modeldata);
|
_interior = SGModelLib::loadPagedModel(_modeldata->getInteriorPath(), props, _modeldata);
|
||||||
|
_group->addChild(_interior);
|
||||||
if (_interior.valid()) {
|
if (_interior.valid()) {
|
||||||
bool pixel_mode = !fgGetBool("/sim/rendering/static-lod/aimp-range-mode-distance", false);
|
bool pixel_mode = !fgGetBool("/sim/rendering/static-lod/aimp-range-mode-distance", false);
|
||||||
if (pixel_mode) {
|
if (pixel_mode) {
|
||||||
|
@ -388,7 +392,6 @@ void FGAIBase::updateInterior()
|
||||||
_interior->setRangeMode(osg::LOD::DISTANCE_FROM_EYE_POINT);
|
_interior->setRangeMode(osg::LOD::DISTANCE_FROM_EYE_POINT);
|
||||||
_interior->setRange(0, 0.0, _maxRangeInterior);
|
_interior->setRange(0, 0.0, _maxRangeInterior);
|
||||||
}
|
}
|
||||||
aip.add(_interior.get());
|
|
||||||
_modeldata->setInteriorLoaded(true);
|
_modeldata->setInteriorLoaded(true);
|
||||||
SG_LOG(SG_AI, SG_INFO, "AIBase: Loaded interior model " << _interior->getName());
|
SG_LOG(SG_AI, SG_INFO, "AIBase: Loaded interior model " << _interior->getName());
|
||||||
}
|
}
|
||||||
|
@ -416,23 +419,27 @@ void FGAIBase::updateLOD()
|
||||||
{
|
{
|
||||||
// High detail model (only)
|
// High detail model (only)
|
||||||
// - disables the low detail detail model by setting its visibility from 0 to 0
|
// - disables the low detail detail model by setting its visibility from 0 to 0
|
||||||
if (_model->getNumFileNames() == 2) {
|
if (_high_res.valid()) {
|
||||||
_model->setRange(modelHighDetailIndex, 0.0, FLT_MAX); // all ranges.
|
_model->setRange(modelHighDetailIndex, 0.0, FLT_MAX); // all ranges.
|
||||||
_model->setRange(modelLowDetailIndex, 0.0, 0.0); // turn it off
|
_model->setRange(modelLowDetailIndex, 0.0, 0.0); // turn it off
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
_model->setRange(0, 0.0, FLT_MAX); // only one model.
|
// only having low-res model
|
||||||
|
_model->setRange(modelLowDetailIndex, 0.0, FLT_MAX); // only having low-res model.
|
||||||
|
_model->setRange(modelHighDetailIndex, 0.0, 0.0); // only having low-res model.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ((int)maxRangeBare == (int)maxRangeDetail)
|
else if ((int)maxRangeBare == (int)maxRangeDetail)
|
||||||
{
|
{
|
||||||
// low detail model (only)
|
// low detail model (only)
|
||||||
if (_model->getNumFileNames() == 2) {
|
if (_low_res.valid()) {
|
||||||
_model->setRange(modelHighDetailIndex, 0, 0); // turn it off
|
_model->setRange(modelHighDetailIndex, 0, 0); // turn it off
|
||||||
_model->setRange(modelLowDetailIndex, 0, FLT_MAX);
|
_model->setRange(modelLowDetailIndex, 0, FLT_MAX);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
_model->setRange(0, 0, FLT_MAX);
|
// Only having high_res model
|
||||||
|
_model->setRange(modelHighDetailIndex, 0, FLT_MAX);
|
||||||
|
_model->setRange(modelLowDetailIndex, 0, 0.0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -459,7 +466,7 @@ void FGAIBase::updateLOD()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_model->getNumFileNames() == 2) {
|
if (_low_res.valid() && _high_res.valid()) {
|
||||||
/*if (_model->getRadius() < 0)
|
/*if (_model->getRadius() < 0)
|
||||||
{
|
{
|
||||||
osg::BoundingSphere bs = _model->computeBound();
|
osg::BoundingSphere bs = _model->computeBound();
|
||||||
|
@ -470,9 +477,14 @@ void FGAIBase::updateLOD()
|
||||||
}*/
|
}*/
|
||||||
_model->setRange(modelHighDetailIndex , maxRangeDetail, FLT_MAX); // most detailed
|
_model->setRange(modelHighDetailIndex , maxRangeDetail, FLT_MAX); // most detailed
|
||||||
_model->setRange(modelLowDetailIndex , maxRangeBare, maxRangeDetail); // least detailed
|
_model->setRange(modelLowDetailIndex , maxRangeBare, maxRangeDetail); // least detailed
|
||||||
} else {
|
} else if (_low_res.valid() && !_high_res.valid()) {
|
||||||
// we have only one model it obviously will have to be displayed from the smallest value
|
// we have only low_res_model model it obviously will have to be displayed from the smallest value
|
||||||
_model->setRange(0, min(maxRangeBare, maxRangeDetail), FLT_MAX );
|
_model->setRange(modelLowDetailIndex, min(maxRangeBare, maxRangeDetail), FLT_MAX );
|
||||||
|
_model->setRange(modelHighDetailIndex, 0,0);
|
||||||
|
} else if (!_low_res.valid() && _high_res.valid()) {
|
||||||
|
// we have only high_res model it obviously will have to be displayed from the smallest value
|
||||||
|
_model->setRange(modelHighDetailIndex, min(maxRangeBare, maxRangeDetail), FLT_MAX );
|
||||||
|
_model->setRange(modelLowDetailIndex, 0,0);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* In non-pixel range mode we're dealing with straight distance.
|
/* In non-pixel range mode we're dealing with straight distance.
|
||||||
|
@ -491,11 +503,15 @@ void FGAIBase::updateLOD()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (_model->getNumFileNames() == 2) {
|
if (_low_res.valid() && _high_res.valid()) {
|
||||||
_model->setRange(modelHighDetailIndex , 0, maxRangeDetail); // most detailed
|
_model->setRange(modelHighDetailIndex , 0, maxRangeDetail); // most detailed
|
||||||
_model->setRange(modelLowDetailIndex , maxRangeDetail, maxRangeDetail+maxRangeBare); // least detailed
|
_model->setRange(modelLowDetailIndex , maxRangeDetail, maxRangeDetail+maxRangeBare); // least detailed
|
||||||
} else {
|
} else if (_low_res.valid() && !_high_res.valid()) {
|
||||||
_model->setRange(0, 0, maxRangeBare + maxRangeDetail); // only one model, so display from 0 to the highest value in meters
|
_model->setRange(modelLowDetailIndex, 0, maxRangeBare + maxRangeDetail); // only low_res, so display from 0 to the highest value in meters
|
||||||
|
_model->setRange(modelHighDetailIndex, 0, 0);
|
||||||
|
} else if (!_low_res.valid() && _high_res.valid()) {
|
||||||
|
_model->setRange(modelHighDetailIndex, 0, maxRangeBare + maxRangeDetail); // only high_res, so display from 0 to the highest value in meters
|
||||||
|
_model->setRange(modelLowDetailIndex, 0, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -645,8 +661,44 @@ bool FGAIBase::init(ModelSearchOrder searchOrder)
|
||||||
_modeldata->addErrorContext("multiplayer", getCallSign());
|
_modeldata->addErrorContext("multiplayer", getCallSign());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Load models
|
||||||
|
_model = new osg::LOD();
|
||||||
vector<string> model_list = resolveModelPath(searchOrder);
|
vector<string> model_list = resolveModelPath(searchOrder);
|
||||||
_model= SGModelLib::loadPagedModel(model_list, props, _modeldata);
|
if(model_list.size() == 1 && _modeldata && _modeldata->hasInteriorPath()) {
|
||||||
|
// Only one model and interior available (expecting this to be a high_res model)
|
||||||
|
_low_res = new osg::PagedLOD(); // Dummy node to keep LOD node happy
|
||||||
|
_model->addChild(_low_res);
|
||||||
|
_high_res = SGModelLib::loadPagedModel(model_list[0], props, _modeldata);
|
||||||
|
_group = osg::ref_ptr<osg::Group>(new osg::Group());
|
||||||
|
_group->addChild(_high_res);
|
||||||
|
_model->addChild(_group);
|
||||||
|
} else if (model_list.size() == 1) {
|
||||||
|
// low_res model only (as we do not have any interior)
|
||||||
|
_low_res = SGModelLib::loadPagedModel(model_list[0], props, _modeldata);
|
||||||
|
_model->addChild(_low_res);
|
||||||
|
_group = osg::ref_ptr<osg::Group>(new osg::Group()); // Dummy node to keep LOD node happy
|
||||||
|
_model->addChild(_group);
|
||||||
|
} else {
|
||||||
|
// high and low-res model
|
||||||
|
assert(model_list.size() == 2);
|
||||||
|
_low_res = SGModelLib::loadPagedModel(model_list[0], props, _modeldata);
|
||||||
|
_model->addChild(_low_res);
|
||||||
|
_high_res = SGModelLib::loadPagedModel(model_list[1], props, _modeldata);
|
||||||
|
_group = osg::ref_ptr<osg::Group>(new osg::Group());
|
||||||
|
_group->addChild(_high_res);
|
||||||
|
_model->addChild(_group);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set PagedLODs to MAX Range. The visibility is controlled with the top-level LOD node
|
||||||
|
if(_high_res.valid()) {
|
||||||
|
_high_res->setRangeMode(osg::LOD::DISTANCE_FROM_EYE_POINT);
|
||||||
|
_high_res->setRange(0, 0, FLT_MAX);
|
||||||
|
}
|
||||||
|
if(_low_res.valid()) {
|
||||||
|
_low_res->setRangeMode(osg::LOD::DISTANCE_FROM_EYE_POINT);
|
||||||
|
_low_res->setRange(0, 0, FLT_MAX);
|
||||||
|
}
|
||||||
|
|
||||||
_model->setName("AI-model range animation node");
|
_model->setName("AI-model range animation node");
|
||||||
_model->setRadius(getDefaultModelRadius());
|
_model->setRadius(getDefaultModelRadius());
|
||||||
|
|
||||||
|
@ -1198,11 +1250,20 @@ bool FGAIBase::isValid() const
|
||||||
return !fp || fp->isValidPlan();
|
return !fp || fp->isValidPlan();
|
||||||
}
|
}
|
||||||
|
|
||||||
osg::PagedLOD* FGAIBase::getSceneBranch() const
|
osg::LOD* FGAIBase::getSceneBranch() const
|
||||||
{
|
{
|
||||||
return _model;
|
return _model;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool FGAIBase::modelLoaded() const
|
||||||
|
{
|
||||||
|
if(_low_res.valid())
|
||||||
|
return _low_res->getNumChildren() >= 1;
|
||||||
|
else if (_high_res.valid())
|
||||||
|
return _high_res->getNumChildren() >= 1;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
SGGeod FGAIBase::getGeodPos() const
|
SGGeod FGAIBase::getGeodPos() const
|
||||||
{
|
{
|
||||||
return pos;
|
return pos;
|
||||||
|
|
|
@ -147,7 +147,13 @@ public:
|
||||||
double _getCartPosY() const;
|
double _getCartPosY() const;
|
||||||
double _getCartPosZ() const;
|
double _getCartPosZ() const;
|
||||||
|
|
||||||
osg::PagedLOD* getSceneBranch() const;
|
osg::LOD* getSceneBranch() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return true if at least one model (either low_res or high_res) is loaded
|
||||||
|
*/
|
||||||
|
bool modelLoaded() const;
|
||||||
|
|
||||||
void setScenarioPath(const std::string& scenarioPath);
|
void setScenarioPath(const std::string& scenarioPath);
|
||||||
|
|
||||||
|
@ -271,7 +277,10 @@ private:
|
||||||
int _refID;
|
int _refID;
|
||||||
object_type _otype;
|
object_type _otype;
|
||||||
bool _initialized = false;
|
bool _initialized = false;
|
||||||
osg::ref_ptr<osg::PagedLOD> _model;
|
osg::ref_ptr<osg::LOD> _model;
|
||||||
|
osg::ref_ptr<osg::PagedLOD> _low_res;
|
||||||
|
osg::ref_ptr<osg::PagedLOD> _high_res;
|
||||||
|
osg::ref_ptr<osg::Group> _group;
|
||||||
osg::ref_ptr<osg::PagedLOD> _interior;
|
osg::ref_ptr<osg::PagedLOD> _interior;
|
||||||
|
|
||||||
osg::ref_ptr<FGAIModelData> _modeldata;
|
osg::ref_ptr<FGAIModelData> _modeldata;
|
||||||
|
|
|
@ -402,7 +402,7 @@ static InitPosResult checkCarrierSceneryLoaded(const SGSharedPtr<FGAICarrier> ca
|
||||||
}
|
}
|
||||||
|
|
||||||
// and then wait for the load to actually be synced to the main thread
|
// and then wait for the load to actually be synced to the main thread
|
||||||
if (carrierRef->getSceneBranch()->getNumChildren() < 1) {
|
if (!carrierRef->modelLoaded()) {
|
||||||
return ContinueWaiting;
|
return ContinueWaiting;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue