diff --git a/src/AIModel/AIBallistic.cxx b/src/AIModel/AIBallistic.cxx index 000ce3266..0de56a46d 100644 --- a/src/AIModel/AIBallistic.cxx +++ b/src/AIModel/AIBallistic.cxx @@ -26,9 +26,11 @@ #include #include #include +#include #include +#include "AIModelData.hxx" #include "AIBallistic.hxx" #include
@@ -36,6 +38,8 @@ const double FGAIBallistic::slugs_to_kgs = 14.5939029372; const double FGAIBallistic::slugs_to_lbs = 32.1740485564; +using namespace simgear; + FGAIBallistic::FGAIBallistic(object_type ot) : FGAIBase(ot), _elevation(0), @@ -114,6 +118,12 @@ void FGAIBallistic::readFromScenario(SGPropertyNode* scFileNode) { setRandom(scFileNode->getBoolValue("random", false)); } +osg::Node* FGAIBallistic::load3DModel(const string &path, SGPropertyNode *prop_root) +{ + model = SGModelLib::loadModel(path, prop_root, new FGAIModelData(this, prop_root)); + return model.get(); +} + bool FGAIBallistic::init(bool search_in_AI_path) { FGAIBase::init(search_in_AI_path); diff --git a/src/AIModel/AIBallistic.hxx b/src/AIModel/AIBallistic.hxx index f00e389d0..b6fb58a0f 100644 --- a/src/AIModel/AIBallistic.hxx +++ b/src/AIModel/AIBallistic.hxx @@ -43,6 +43,8 @@ public: void readFromScenario(SGPropertyNode* scFileNode); + virtual osg::Node* load3DModel(const string &path, + SGPropertyNode *prop_root); bool init(bool search_in_AI_path=false); virtual void bind(); virtual void unbind(); diff --git a/src/AIModel/AIBase.cxx b/src/AIModel/AIBase.cxx index 35be09b9d..391cc577b 100644 --- a/src/AIModel/AIBase.cxx +++ b/src/AIModel/AIBase.cxx @@ -24,20 +24,20 @@ # include #endif - #include #include STL_STRING #include #include +#include #include #include #include #include #include -#include +#include #include #include #include @@ -47,11 +47,13 @@ #include #include "AIBase.hxx" +#include "AIModelData.hxx" #include "AIManager.hxx" const double FGAIBase::e = 2.71828183; const double FGAIBase::lbs_to_slugs = 0.031080950172; //conversion factor +using namespace simgear; FGAIBase::FGAIBase(object_type ot) : props( NULL ), @@ -155,38 +157,41 @@ void FGAIBase::Transform() { } bool FGAIBase::init(bool search_in_AI_path) { + osg::ref_ptr opt= + new osgDB::ReaderWriter::Options(*osgDB::Registry::instance()->getOptions()); - if (!model_path.empty()) { - - if ( search_in_AI_path - && (model_path.substr(model_path.size() - 4, 4) == ".xml")) { - SGPath ai_path("AI"); - ai_path.append(model_path); - try { - model = load3DModel( globals->get_fg_root(), ai_path.str(), props, - globals->get_sim_time_sec() ); - } catch (const sg_exception &e) { - model = NULL; - } - } else - model = NULL; - - if (!model.get()) { - try { - model = load3DModel( globals->get_fg_root(), model_path, props, - globals->get_sim_time_sec() ); - } catch (const sg_exception &e) { - model = NULL; - } - } - + if(search_in_AI_path) + { + SGPath ai_path(globals->get_fg_root()); + ai_path.append("AI"); + opt->getDatabasePathList().push_front(ai_path.str()); } - if (model.get()) { + string f = osgDB::findDataFile(model_path, opt.get()); + + if(f.empty()) + f="Models/Geometry/glider.ac"; + + model = load3DModel(f, props); + + if (model.valid()) { + model->setNodeMask(model->getNodeMask() & ~SG_NODEMASK_TERRAIN_BIT); aip.init( model.get() ); aip.setVisible(true); invisible = false; globals->get_scenery()->get_scene_graph()->addChild(aip.getSceneGraph()); + + } else if (!model_path.empty()) { + SG_LOG(SG_INPUT, SG_WARN, "AIBase: Could not load model " << model_path); + } + + setDie(false); + return true; +} + +void FGAIBase::initModel(osg::Node *node) +{ + if (model.valid()) { fgSetString("/ai/models/model-added", props->getPath()); } else if (!model_path.empty()) { @@ -195,18 +200,12 @@ bool FGAIBase::init(bool search_in_AI_path) { props->setStringValue("submodels/path", _path.c_str()); setDie(false); - return true; } -osg::Node* FGAIBase::load3DModel(const string& fg_root, - const string &path, - SGPropertyNode *prop_root, - double sim_time_sec) +osg::Node* FGAIBase::load3DModel(const string &path, SGPropertyNode *prop_root) { - model = sgLoad3DModel(fg_root, path, prop_root, sim_time_sec, 0, - new FGNasalModelData(prop_root)); - model->setNodeMask(model->getNodeMask() & ~SG_NODEMASK_TERRAIN_BIT); + model = SGModelLib::loadPagedModel(path, prop_root, new FGAIModelData(this, prop_root)); return model.get(); } diff --git a/src/AIModel/AIBase.hxx b/src/AIModel/AIBase.hxx index 0bdd6f85b..ec55ce998 100644 --- a/src/AIModel/AIBase.hxx +++ b/src/AIModel/AIBase.hxx @@ -40,7 +40,7 @@ SG_USING_STD(list); class FGAIManager; class FGAIFlightPlan; -class FGAIBase : public SGReferenced { +class FGAIBase : public osg::Referenced { public: enum object_type { otNull = 0, otAircraft, otShip, otCarrier, otBallistic, @@ -54,6 +54,7 @@ public: virtual void readFromScenario(SGPropertyNode* scFileNode); virtual bool init(bool search_in_AI_path=false); + virtual void initModel(osg::Node *node); virtual void update(double dt); virtual void bind(); virtual void unbind(); @@ -266,11 +267,9 @@ public: inline double _getRange() { return range; }; inline double _getBearing() { return bearing; }; - osg::Node* load3DModel(const string& fg_root, - const string &path, - SGPropertyNode *prop_root, - double sim_time_sec); - + virtual osg::Node* load3DModel(const string &path, + SGPropertyNode *prop_root); + static bool _isNight(); }; diff --git a/src/AIModel/AICarrier.cxx b/src/AIModel/AICarrier.cxx index d3fa369a1..3791ab8d2 100644 --- a/src/AIModel/AICarrier.cxx +++ b/src/AIModel/AICarrier.cxx @@ -71,6 +71,7 @@ public: != mSolidObjects.end()) { mFoundHot = true; mUserData = FGAICarrierHardware::newSolid(mCarrier); + //SG_LOG(SG_GENERAL, SG_ALERT, "AICarrierVisitor::apply() solidObject" ); } node.setUserData(mUserData.get()); @@ -313,20 +314,6 @@ bool FGAICarrier::init(bool search_in_AI_path) { if (!FGAIShip::init(search_in_AI_path)) return false; - // process the 3d model here - // mark some objects solid, mark the wires ... - - // The model should be used for altitude computations. - // To avoid that every detail in a carrier 3D model will end into - // the aircraft local cache, only set the HOT traversal bit on - // selected objects. - osg::Node* sel = aip.getSceneGraph(); - // Clear the HOT traversal flag - // Selectively set that flag again for wires/cats/solid objects. - // Attach a pointer to this carrier class to those objects. - FGCarrierVisitor carrierVisitor(this, wire_objects, catapult_objects, solid_objects); - sel->accept(carrierVisitor); - _longitude_node = fgGetNode("/position/longitude-deg", true); _latitude_node = fgGetNode("/position/latitude-deg", true); _altitude_node = fgGetNode("/position/altitude-ft", true); @@ -357,6 +344,27 @@ bool FGAICarrier::init(bool search_in_AI_path) { return true; } +void FGAICarrier::initModel(osg::Node *node) +{ + SG_LOG(SG_GENERAL, SG_ALERT, "AICarrier::initModel()" ); + FGAIShip::initModel(node); + // process the 3d model here + // mark some objects solid, mark the wires ... + + // The model should be used for altitude computations. + // To avoid that every detail in a carrier 3D model will end into + // the aircraft local cache, only set the HOT traversal bit on + // selected objects. + + // Clear the HOT traversal flag + // Selectively set that flag again for wires/cats/solid objects. + // Attach a pointer to this carrier class to those objects. + SG_LOG(SG_GENERAL, SG_ALERT, "AICarrier::initModel() visit" ); + FGCarrierVisitor carrierVisitor(this, wire_objects, catapult_objects, solid_objects); + model->accept(carrierVisitor); +// model->setNodeMask(node->getNodeMask() & SG_NODEMASK_TERRAIN_BIT | model->getNodeMask()); +} + void FGAICarrier::bind() { FGAIShip::bind(); diff --git a/src/AIModel/AICarrier.hxx b/src/AIModel/AICarrier.hxx index 33c674055..0e88ba452 100644 --- a/src/AIModel/AICarrier.hxx +++ b/src/AIModel/AICarrier.hxx @@ -103,6 +103,7 @@ public: bool OutsideBox(); bool init(bool search_in_AI_path=false); + void initModel(osg::Node *node); virtual const char* getTypeString(void) const { return "carrier"; } diff --git a/src/AIModel/AIManager.cxx b/src/AIModel/AIManager.cxx index 7ed3d9d7a..bc56af32f 100644 --- a/src/AIModel/AIManager.cxx +++ b/src/AIModel/AIManager.cxx @@ -145,7 +145,7 @@ FGAIManager::update(double dt) { tmgr->release((*ai_list_itr)->getID()); --mNumAiModels; --(mNumAiTypeModels[(*ai_list_itr)->getType()]); - FGAIBase *base = *ai_list_itr; + FGAIBase *base = (*ai_list_itr).get(); SGPropertyNode *props = base->_getProps(); props->setBoolValue("valid", false); @@ -162,7 +162,7 @@ FGAIManager::update(double dt) { } else { fetchUserState(); if ((*ai_list_itr)->isa(FGAIBase::otThermal)) { - FGAIBase *base = *ai_list_itr; + FGAIBase *base = (*ai_list_itr).get(); processThermal((FGAIThermal*)base); } else { (*ai_list_itr)->update(_dt); @@ -175,7 +175,7 @@ FGAIManager::update(double dt) { } void -FGAIManager::attach(SGSharedPtr model) +FGAIManager::attach(FGAIBase *model) { //unsigned idx = mNumAiTypeModels[model->getType()]; const char* typeString = model->getTypeString(); @@ -365,7 +365,7 @@ FGAIManager::getStartPosition(const string& id, const string& pid, std::string pnumber = scEntry->getStringValue("pennant-number"); std::string name = scEntry->getStringValue("name"); if (type == "carrier" && (pnumber == id || name == id)) { - SGSharedPtr carrier = new FGAICarrier; + osg::ref_ptr carrier = new FGAICarrier; carrier->readFromScenario(scEntry); if (carrier->getParkPosition(pid, geodPos, hdng, uvw)) { @@ -431,7 +431,7 @@ FGAIManager::calcCollision(double alt, double lat, double lon, double fuse_range << " range " << range << " alt " << tgt_alt ); - return *ai_list_itr; + return (*ai_list_itr).get(); } ++ai_list_itr; } diff --git a/src/AIModel/AIManager.hxx b/src/AIModel/AIManager.hxx index d208ace8c..19303fc34 100644 --- a/src/AIModel/AIManager.hxx +++ b/src/AIModel/AIManager.hxx @@ -46,13 +46,13 @@ class FGAIManager : public SGSubsystem public: // A list of pointers to AI objects - typedef list > ai_list_type; + typedef list > ai_list_type; typedef ai_list_type::iterator ai_list_iterator; typedef ai_list_type::const_iterator ai_list_const_iterator; ai_list_type ai_list; - inline const list >& get_ai_list() const { + inline const ai_list_type& get_ai_list() const { SG_LOG(SG_GENERAL, SG_DEBUG, "AI Manager: AI model return list size " << ai_list.size()); return ai_list; } @@ -66,7 +66,7 @@ public: void bind(); void unbind(); void update(double dt); - void attach(SGSharedPtr model); + void attach(FGAIBase *model); void destroyObject( int ID ); const FGAIBase *calcCollision(double alt, double lat, double lon, double fuse_range); diff --git a/src/AIModel/AIModelData.cxx b/src/AIModel/AIModelData.cxx new file mode 100644 index 000000000..fe4762e83 --- /dev/null +++ b/src/AIModel/AIModelData.cxx @@ -0,0 +1,11 @@ +#include "AIBase.hxx" +#include "AIModelData.hxx" + +void FGAIModelData::modelLoaded(const string& path, SGPropertyNode *prop, + osg::Node *n) +{ + FGNasalModelData::modelLoaded(path, prop, n); + // SG_LOG(SG_NASAL, SG_ALERT, "FGAIModelData::modelLoaded(" << path << ")"); + if(_base.valid()) + _base->initModel(n); +} diff --git a/src/AIModel/AIModelData.hxx b/src/AIModel/AIModelData.hxx new file mode 100644 index 000000000..6ebabf02b --- /dev/null +++ b/src/AIModel/AIModelData.hxx @@ -0,0 +1,18 @@ +#ifndef __FGAIMODELDATA_HXX +#define __FGAIMODELDATA_HXX + +#include +#include + +class FGAIBase; + +class FGAIModelData : public FGNasalModelData { +public: + FGAIModelData(FGAIBase *b, SGPropertyNode *props = 0) : FGNasalModelData(props), _base(b) {} + virtual void modelLoaded(const string& path, SGPropertyNode *prop, osg::Node *); + +private: + osg::observer_ptr _base; +}; + +#endif diff --git a/src/AIModel/AIMultiplayer.cxx b/src/AIModel/AIMultiplayer.cxx index b7b0f689c..a34a92775 100755 --- a/src/AIModel/AIMultiplayer.cxx +++ b/src/AIModel/AIMultiplayer.cxx @@ -44,6 +44,7 @@ FGAIMultiplayer::~FGAIMultiplayer() { } bool FGAIMultiplayer::init(bool search_in_AI_path) { + props->setStringValue("sim/model/path", model_path.c_str()); //refuel_node = fgGetNode("systems/refuel/contact", true); isTanker = false; // do this until this property is // passed over the net diff --git a/src/AIModel/Makefile.am b/src/AIModel/Makefile.am index 6dbfd7be2..350d69ee1 100644 --- a/src/AIModel/Makefile.am +++ b/src/AIModel/Makefile.am @@ -3,6 +3,7 @@ noinst_LIBRARIES = libAIModel.a libAIModel_a_SOURCES = submodel.cxx submodel.hxx \ AIManager.hxx AIManager.cxx \ AIBase.hxx AIBase.cxx \ + AIModelData.cxx \ AIAircraft.hxx AIAircraft.cxx \ AIMultiplayer.hxx AIMultiplayer.cxx \ AIShip.hxx AIShip.cxx \ diff --git a/src/AIModel/submodel.cxx b/src/AIModel/submodel.cxx index e246523a1..774820dc8 100644 --- a/src/AIModel/submodel.cxx +++ b/src/AIModel/submodel.cxx @@ -514,7 +514,7 @@ void FGSubmodelMgr::loadAI() sm_list = ai->get_ai_list(); if (sm_list.empty()) { - SG_LOG(SG_GENERAL, SG_ALERT, "Submodels: Unable to read AI submodel list"); + SG_LOG(SG_GENERAL, SG_DEBUG, "Submodels: Unable to read AI submodel list"); return; } @@ -559,7 +559,7 @@ void FGSubmodelMgr::setData(int id, string& path, bool serviceable) "Submodels: Trying to read AI submodels file: " << config.str()); readProperties(config.str(), &root); } catch (const sg_exception &e) { - SG_LOG(SG_GENERAL, SG_ALERT, + SG_LOG(SG_GENERAL, SG_DEBUG, "Submodels: Unable to read AI submodels file: " << config.str()); return; } @@ -664,7 +664,7 @@ void FGSubmodelMgr::setSubData(int id, string& path, bool serviceable) readProperties(config.str(), &root); } catch (const sg_exception &e) { - SG_LOG(SG_GENERAL, SG_ALERT, + SG_LOG(SG_GENERAL, SG_DEBUG, "Submodels: Unable to read AI submodels file: " << config.str()); return; } diff --git a/src/AIModel/submodel.hxx b/src/AIModel/submodel.hxx index 88f5694d7..3f6965fcc 100644 --- a/src/AIModel/submodel.hxx +++ b/src/AIModel/submodel.hxx @@ -173,7 +173,7 @@ private: IC_struct IC; // A list of pointers to AI objects - typedef list > sm_list_type; + typedef list > sm_list_type; typedef sm_list_type::iterator sm_list_iterator; typedef sm_list_type::const_iterator sm_list_const_iterator; diff --git a/src/ATC/AIEntity.hxx b/src/ATC/AIEntity.hxx index dc9070b8b..1b184a833 100644 --- a/src/ATC/AIEntity.hxx +++ b/src/ATC/AIEntity.hxx @@ -22,7 +22,6 @@ #define _FG_AIEntity_HXX #include -#include #include diff --git a/src/ATC/AIMgr.cxx b/src/ATC/AIMgr.cxx index 8b38de663..23d44bbf1 100644 --- a/src/ATC/AIMgr.cxx +++ b/src/ATC/AIMgr.cxx @@ -27,6 +27,7 @@ #include
#include #include +#include #include #ifdef _MSC_VER @@ -48,6 +49,8 @@ SG_USING_STD(list); SG_USING_STD(cout); +using namespace simgear; + FGAIMgr::FGAIMgr() { ATC = globals->get_ATC_mgr(); initDone = false; @@ -81,10 +84,7 @@ void FGAIMgr::init() { string planepath = "Aircraft/c172p/Models/c172p.xml"; bool _loadedDefaultOK = true; try { - _defaultModel = sgLoad3DModel( globals->get_fg_root(), - planepath.c_str(), - globals->get_props(), - globals->get_sim_time_sec() ); + _defaultModel = SGModelLib::loadPagedModel(planepath.c_str(), globals->get_props()); } catch(sg_exception&) { _loadedDefaultOK = false; } @@ -93,18 +93,12 @@ void FGAIMgr::init() { // Just load the same 3D model as the default user plane - that's *bound* to exist! // TODO - implement robust determination of availability of GA AI aircraft models planepath = "Aircraft/c172p/Models/c172p.ac"; - _defaultModel = sgLoad3DModel( globals->get_fg_root(), - planepath.c_str(), - globals->get_props(), - globals->get_sim_time_sec() ); + _defaultModel = SGModelLib::loadPagedModel(planepath.c_str(), globals->get_props()); } planepath = "Aircraft/pa28-161/Models/pa28-161.ac"; try { - _piperModel = sgLoad3DModel( globals->get_fg_root(), - planepath.c_str(), - globals->get_props(), - globals->get_sim_time_sec() ); + _piperModel = SGModelLib::loadPagedModel(planepath.c_str(), globals->get_props()); } catch(sg_exception&) { _havePiperModel = false; } diff --git a/src/ATC/AIPlane.hxx b/src/ATC/AIPlane.hxx index 3cf218dfd..b29726c39 100644 --- a/src/ATC/AIPlane.hxx +++ b/src/ATC/AIPlane.hxx @@ -22,7 +22,6 @@ #define _FG_AI_PLANE_HXX #include -#include #include "AIEntity.hxx" #include "ATC.hxx" diff --git a/src/Instrumentation/wxradar.cxx b/src/Instrumentation/wxradar.cxx index e7df08b85..0cc0801e8 100644 --- a/src/Instrumentation/wxradar.cxx +++ b/src/Instrumentation/wxradar.cxx @@ -67,7 +67,7 @@ SG_USING_STD(setfill); #include "wxradar.hxx" -typedef list > radar_list_type; +typedef list > radar_list_type; typedef radar_list_type::iterator radar_list_iterator; typedef radar_list_type::const_iterator radar_list_const_iterator; @@ -617,7 +617,7 @@ wxRadarBg::update_aircraft() int selected_id = fgGetInt("/instrumentation/radar/selected-id", -1); for (; it != end; ++it) { - FGAIBase *ac = *it; + FGAIBase *ac = (*it).get(); int type = ac->getType(); double lat = ac->_getLatitude(); double lon = ac->_getLongitude(); diff --git a/src/Main/fg_os_osgviewer.cxx b/src/Main/fg_os_osgviewer.cxx index 4ccb39c19..a713e0627 100644 --- a/src/Main/fg_os_osgviewer.cxx +++ b/src/Main/fg_os_osgviewer.cxx @@ -260,6 +260,7 @@ static int status = 0; void fgOSExit(int code) { viewer->setDone(true); + viewer->getDatabasePager()->cancel(); status = code; } diff --git a/src/Main/globals.cxx b/src/Main/globals.cxx index ecea15d0c..3a28be27c 100644 --- a/src/Main/globals.cxx +++ b/src/Main/globals.cxx @@ -24,7 +24,6 @@ # include #endif -#include #include #include #include @@ -92,7 +91,6 @@ FGGlobals::FGGlobals() : initial_state( NULL ), locale( NULL ), commands( SGCommandMgr::instance() ), - model_lib( NULL ), acmodel( NULL ), model_mgr( NULL ), channel_options_list( NULL ), @@ -127,35 +125,32 @@ FGGlobals::~FGGlobals() // shut down all subsystems, make sure we take down the // AIModels system first. subsystem_mgr->get_group(SGSubsystemMgr::GENERAL)->remove_subsystem("ai_model"); - delete subsystem_mgr; - delete event_mgr; - delete time_params; - delete ephem; - delete mag; - delete matlib; - delete route_mgr; - delete current_panel; - delete soundmgr; - delete airports; + delete subsystem_mgr; + delete event_mgr; + delete time_params; + delete ephem; + delete mag; + delete matlib; + delete route_mgr; + delete current_panel; + delete soundmgr; + delete airports; - delete runways; - delete ATC_mgr; - delete AI_mgr; - delete controls; - delete viewmgr; + delete runways; + delete ATC_mgr; + delete AI_mgr; + delete controls; + delete viewmgr; - delete initial_state; -// //delete locale; Don't delete locale // delete commands; - delete model_lib; - delete acmodel; - delete model_mgr; - delete channel_options_list; - delete initial_waypoints; - delete scenery; - //delete tile_mgr; // Don't delete tile manager yet, because loader thread problems - delete io; - delete fontcache; + delete acmodel; + delete model_mgr; + delete channel_options_list; + delete initial_waypoints; + delete tile_mgr; + delete scenery; + delete io; + delete fontcache; delete navlist; delete loclist; @@ -168,8 +163,6 @@ FGGlobals::~FGGlobals() delete fixlist; delete airwaynet; delete multiplayer_mgr; - - delete props; } @@ -272,7 +265,6 @@ FGGlobals::get_event_mgr () const void FGGlobals::saveInitialState () { - delete initial_state; initial_state = new SGPropertyNode(); if (!copyProperties(props, initial_state)) diff --git a/src/Main/globals.hxx b/src/Main/globals.hxx index 8db8f5557..9182326ee 100644 --- a/src/Main/globals.hxx +++ b/src/Main/globals.hxx @@ -57,7 +57,6 @@ class SGEphemeris; class SGCommandMgr; class SGMagVar; class SGMaterialLib; -class SGModelLib; class SGPropertyNode; class SGTime; class SGSoundMgr; @@ -97,6 +96,13 @@ class FGGlobals private: + // properties, destroy last + SGPropertyNode_ptr props; + SGPropertyNode_ptr initial_state; + + // localization + SGPropertyNode_ptr locale; + FGRenderer *renderer; SGSubsystemMgr *subsystem_mgr; SGEventMgr *event_mgr; @@ -162,17 +168,8 @@ private: // viewer manager FGViewMgr *viewmgr; - // properties - SGPropertyNode *props; - SGPropertyNode *initial_state; - - // localization - SGPropertyNode *locale; - SGCommandMgr *commands; - SGModelLib *model_lib; - //FGFlightPlanDispatcher *fpDispatcher; FGAircraftModel *acmodel; @@ -299,12 +296,6 @@ public: inline SGCommandMgr *get_commands () { return commands; } - inline SGModelLib * get_model_lib () { return model_lib; } - - inline void set_model_lib (SGModelLib *m) { - model_lib = m; - } - inline FGAircraftModel *get_aircraft_model () { return acmodel; } inline void set_aircraft_model (FGAircraftModel * model) diff --git a/src/Main/main.cxx b/src/Main/main.cxx index 615ed6c54..d0acc2776 100644 --- a/src/Main/main.cxx +++ b/src/Main/main.cxx @@ -47,6 +47,8 @@ #include #include +#include + // Class references #include #include @@ -135,9 +137,9 @@ void fgUpdateTimeDepCalcs() { double lat = fgGetDouble("/sim/presets/latitude-deg"); // We require just to have 50 meter scenery availabe around // the aircraft. - double range = 50.0; - if (globals->get_tile_mgr()->scenery_available(lat, lon, range)) { - SG_LOG(SG_FLIGHT,SG_INFO, "Finally initializing fdm"); + double range = 1000.0; + if (globals->get_scenery()->scenery_available(lat, lon, range)) { + SG_LOG(SG_FLIGHT,SG_ALERT, "Finally initializing fdm"); cur_fdm_state->init(); if ( cur_fdm_state->get_bound() ) { cur_fdm_state->unbind(); @@ -766,7 +768,7 @@ static void fgIdleFunction ( void ) { // Initialize the material manager //////////////////////////////////////////////////////////////////// globals->set_matlib( new SGMaterialLib ); - globals->set_model_lib(new SGModelLib); + simgear::SGModelLib::init(globals->get_fg_root()); //////////////////////////////////////////////////////////////////// diff --git a/src/Main/renderer.cxx b/src/Main/renderer.cxx index a67a832f3..e41703224 100644 --- a/src/Main/renderer.cxx +++ b/src/Main/renderer.cxx @@ -66,8 +66,6 @@ #include #include #include -#include -#include #include #include #include diff --git a/src/Main/viewmgr.hxx b/src/Main/viewmgr.hxx index 321f6a2e1..1823cbbf4 100644 --- a/src/Main/viewmgr.hxx +++ b/src/Main/viewmgr.hxx @@ -150,7 +150,7 @@ private: SGPropertyNode_ptr view_number; vector config_list; - typedef vector viewer_list; + typedef vector > viewer_list; viewer_list views; int current; diff --git a/src/Model/acmodel.cxx b/src/Model/acmodel.cxx index d3af3b4be..1f9b15a7e 100644 --- a/src/Model/acmodel.cxx +++ b/src/Model/acmodel.cxx @@ -50,36 +50,17 @@ FGAircraftModel::~FGAircraftModel () void FGAircraftModel::init () { - SGPath liveryPath; _aircraft = new SGModelPlacement; string path = fgGetString("/sim/model/path", "Models/Geometry/glider.ac"); - string texture_path = fgGetString("/sim/model/texture-path"); - if( texture_path.size() ) { - SGPath temp_path; - if ( !ulIsAbsolutePathName( texture_path.c_str() ) ) { - temp_path = globals->get_fg_root(); - temp_path.append( SGPath( path ).dir() ); - temp_path.append( texture_path ); - liveryPath = temp_path; - } else - liveryPath = texture_path; - } try { - osg::Node *model = fgLoad3DModelPanel( globals->get_fg_root(), - path, - globals->get_props(), - globals->get_sim_time_sec(), - liveryPath); + osg::Node *model = fgLoad3DModelPanel( path, globals->get_props()); _aircraft->init( model ); } catch (const sg_exception &ex) { SG_LOG(SG_GENERAL, SG_ALERT, "Failed to load aircraft from " << path << ':'); SG_LOG(SG_GENERAL, SG_ALERT, " " << ex.getFormattedMessage()); SG_LOG(SG_GENERAL, SG_ALERT, "(Falling back to glider.ac.)"); - osg::Node *model = fgLoad3DModelPanel( globals->get_fg_root(), - "Models/Geometry/glider.ac", - globals->get_props(), - globals->get_sim_time_sec(), - liveryPath); + osg::Node *model = fgLoad3DModelPanel( "Models/Geometry/glider.ac", + globals->get_props()); _aircraft->init( model ); } _selector->addChild(_aircraft->getSceneGraph(), true); diff --git a/src/Model/model_panel.cxx b/src/Model/model_panel.cxx index ef9854479..ea24a2fa2 100644 --- a/src/Model/model_panel.cxx +++ b/src/Model/model_panel.cxx @@ -12,7 +12,7 @@ #include #include -#include +#include #include #include "panelnode.hxx" @@ -21,12 +21,14 @@ SG_USING_STD(vector); +using namespace simgear; + static osg::Node* load_panel(SGPropertyNode *n) { - osg::Geode* geode = new osg::Geode; - geode->addDrawable(new FGPanelNode(n)); - return geode; + osg::Geode* geode = new osg::Geode; + geode->addDrawable(new FGPanelNode(n)); + return geode; } @@ -35,14 +37,11 @@ osg::Node* load_panel(SGPropertyNode *n) //////////////////////////////////////////////////////////////////////// osg::Node * -fgLoad3DModelPanel( const string &fg_root, const string &path, - SGPropertyNode *prop_root, - double sim_time_sec, const SGPath& livery ) +fgLoad3DModelPanel(const string &path, SGPropertyNode *prop_root) { - osg::Node* node = sgLoad3DModel( fg_root, path, prop_root, sim_time_sec, - load_panel, 0, livery ); - node->setNodeMask(~SG_NODEMASK_TERRAIN_BIT); - return node; + osg::Node* node = SGModelLib::loadModel(path, prop_root, load_panel); + node->setNodeMask(~SG_NODEMASK_TERRAIN_BIT); + return node; } diff --git a/src/Model/model_panel.hxx b/src/Model/model_panel.hxx index 0c1c34a14..0b82d3313 100644 --- a/src/Model/model_panel.hxx +++ b/src/Model/model_panel.hxx @@ -46,9 +46,7 @@ class FGLocation; * Subsystems should not normally invoke this function directly; * instead, they should use the SGModelLoader declared in loader.hxx. */ -osg::Node *fgLoad3DModelPanel( const string& fg_root, const string &path, - SGPropertyNode *prop_root, - double sim_time_sec, const SGPath& livery ); +osg::Node *fgLoad3DModelPanel( const string &path, SGPropertyNode *prop_root); #endif // __MODEL_HXX diff --git a/src/Model/modelmgr.cxx b/src/Model/modelmgr.cxx index 4d19b7be1..a7f543f1e 100644 --- a/src/Model/modelmgr.cxx +++ b/src/Model/modelmgr.cxx @@ -27,10 +27,11 @@ SG_USING_STD(vector); +using namespace simgear; + // OSGFIXME // extern SGShadowVolume *shadows; - FGModelMgr::FGModelMgr () : _models(fgGetNode("/models", true)), _listener(new Listener(this)) @@ -68,17 +69,12 @@ FGModelMgr::add_model (SGPropertyNode * node) SGModelPlacement *model = new SGModelPlacement; instance->model = model; instance->node = node; - SGModelLib *model_lib = globals->get_model_lib(); const char *path = node->getStringValue("path", "Models/Geometry/glider.ac"); osg::Node *object; try { - object = model_lib->load_model( - globals->get_fg_root(), - path, - globals->get_props(), - globals->get_sim_time_sec(), /*cache_object=*/false); + object = SGModelLib::loadPagedModel(path, globals->get_props()); } catch (const sg_throwable& t) { SG_LOG(SG_GENERAL, SG_ALERT, "Error loading " << path << ":\n " << t.getFormattedMessage() << t.getOrigin()); diff --git a/src/MultiPlayer/multiplaymgr.cxx b/src/MultiPlayer/multiplaymgr.cxx index 271c0f41e..a31325a55 100644 --- a/src/MultiPlayer/multiplaymgr.cxx +++ b/src/MultiPlayer/multiplaymgr.cxx @@ -799,7 +799,7 @@ FGMultiplayMgr::addMultiplayer(const std::string& callsign, const std::string& modelName) { if (0 < mMultiPlayerMap.count(callsign)) - return mMultiPlayerMap[callsign]; + return mMultiPlayerMap[callsign].get(); FGAIMultiplayer* mp = new FGAIMultiplayer; mp->setPath(modelName.c_str()); @@ -825,7 +825,7 @@ FGAIMultiplayer* FGMultiplayMgr::getMultiplayer(const std::string& callsign) { if (0 < mMultiPlayerMap.count(callsign)) - return mMultiPlayerMap[callsign]; + return mMultiPlayerMap[callsign].get(); else return 0; } diff --git a/src/MultiPlayer/multiplaymgr.hxx b/src/MultiPlayer/multiplaymgr.hxx index ca9072e40..073b57a5c 100644 --- a/src/MultiPlayer/multiplaymgr.hxx +++ b/src/MultiPlayer/multiplaymgr.hxx @@ -83,7 +83,7 @@ private: FGAIMultiplayer* getMultiplayer(const std::string& callsign); /// maps from the callsign string to the FGAIMultiplayer - typedef std::map > MultiPlayerMap; + typedef std::map > MultiPlayerMap; MultiPlayerMap mMultiPlayerMap; netSocket* mSocket; diff --git a/src/Network/multiplay.hxx b/src/Network/multiplay.hxx index decbdc1c4..145f1054d 100644 --- a/src/Network/multiplay.hxx +++ b/src/Network/multiplay.hxx @@ -32,7 +32,6 @@ #include STL_STRING #include -#include #include
#include
diff --git a/src/Scenery/SceneryPager.cxx b/src/Scenery/SceneryPager.cxx index 5615436e4..6da6d4b72 100644 --- a/src/Scenery/SceneryPager.cxx +++ b/src/Scenery/SceneryPager.cxx @@ -16,6 +16,7 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +#include #include "SceneryPager.hxx" #include #include @@ -39,6 +40,16 @@ SceneryPager::~SceneryPager() { } +void SceneryPager::requestNodeFile(const std::string& fileName,osg::Group* group, + float priority, const osg::FrameStamp* framestamp) +{ + simgear::SGPagedLOD *sgplod = dynamic_cast(group); + if(sgplod) + DatabasePager::requestNodeFile(fileName,group,priority,framestamp,sgplod->getReaderWriterOptions()); + else + DatabasePager::requestNodeFile(fileName,group,priority,framestamp); +} + void SceneryPager::queueRequest(const std::string& fileName, osg::Group* group, float priority, osg::FrameStamp* frameStamp) { diff --git a/src/Scenery/SceneryPager.hxx b/src/Scenery/SceneryPager.hxx index a0c87e78e..283c9db95 100644 --- a/src/Scenery/SceneryPager.hxx +++ b/src/Scenery/SceneryPager.hxx @@ -33,6 +33,11 @@ class SceneryPager : public osgDB::DatabasePager public: SceneryPager(); SceneryPager(const SceneryPager& rhs); + + // reimplement to add readerWriterOptions from SGPagedLOD + virtual void requestNodeFile(const std::string& fileName,osg::Group* group, + float priority, const osg::FrameStamp* framestamp); + void queueRequest(const std::string& fileName, osg::Group* node, float priority, osg::FrameStamp* frameStamp); // This is passed a ref_ptr so that it can "take ownership" of the diff --git a/src/Scenery/scenery.cxx b/src/Scenery/scenery.cxx index 93f5c2f7e..84c5b9fad 100644 --- a/src/Scenery/scenery.cxx +++ b/src/Scenery/scenery.cxx @@ -30,6 +30,7 @@ #include +#include #include #include #include @@ -37,9 +38,11 @@ #include #include #include +#include #include
+#include "tilemgr.hxx" #include "scenery.hxx" using namespace flightgear; @@ -72,12 +75,11 @@ FGScenery::FGScenery() SG_LOG( SG_TERRAIN, SG_INFO, "Initializing scenery subsystem" ); } - -// Initialize the Scenery Management system FGScenery::~FGScenery() { } +// Initialize the Scenery Management system void FGScenery::init() { // Scene graph root scene_graph = new osg::Group; @@ -100,8 +102,7 @@ void FGScenery::init() { scene_graph->addChild( aircraft_branch.get() ); // Initials values needed by the draw-time object loader - sgUserDataInit( globals->get_model_lib(), globals->get_fg_root(), - globals->get_props(), globals->get_sim_time_sec() ); + sgUserDataInit( globals->get_props() ); } @@ -211,6 +212,25 @@ FGScenery::get_cart_ground_intersection(const SGVec3d& pos, const SGVec3d& dir, return hits; } +bool FGScenery::scenery_available(double lat, double lon, double range_m) +{ + if(globals->get_tile_mgr()->scenery_available(lat, lon, range_m)) + { + double elev; + get_elevation_m(lat, lon, SG_MAX_ELEVATION_M, elev, 0); + SGVec3f p = SGVec3f::fromGeod(SGGeod::fromDegM(lon,lat,elev)); + simgear::CheckSceneryVisitor csnv(getPagerSingleton(), p.osg(), range_m); + // currently the PagedLODs will not be loaded by the DatabasePager + // while the splashscreen is there, so CheckSceneryVisitor force-loads + // missing objects in the main thread + get_scene_graph()->accept(csnv); + if(!csnv.isLoaded()) + return false; + return true; + } + return false; +} + SceneryPager* FGScenery::getPagerSingleton() { static osg::ref_ptr pager = new SceneryPager; diff --git a/src/Scenery/scenery.hxx b/src/Scenery/scenery.hxx index 0b2d8832b..0fdd9cd89 100644 --- a/src/Scenery/scenery.hxx +++ b/src/Scenery/scenery.hxx @@ -102,6 +102,11 @@ public: osg::Group *get_models_branch () const { return models_branch.get(); } osg::Group *get_aircraft_branch () const { return aircraft_branch.get(); } + /// Returns true if scenery is avaliable for the given lat, lon position + /// within a range of range_m. + /// lat and lon are expected to be in degrees. + bool scenery_available(double lat, double lon, double range_m); + // Static because access to the pager is needed before the rest of // the scenery is initialized. static flightgear::SceneryPager* getPagerSingleton(); diff --git a/src/Scenery/tileentry.cxx b/src/Scenery/tileentry.cxx index 354a10971..06f1192e3 100644 --- a/src/Scenery/tileentry.cxx +++ b/src/Scenery/tileentry.cxx @@ -436,7 +436,7 @@ FGTileEntry::loadTileByName(const string& index_str, if ( obj->type == OBJECT_STATIC ) { custom_path = obj->path; } else { - custom_path = globals->get_fg_root(); + // custom_path = globals->get_fg_root(); } custom_path.append( obj->name ); diff --git a/src/Scenery/tilemgr.cxx b/src/Scenery/tilemgr.cxx index b3c1e3ec4..adf548d54 100644 --- a/src/Scenery/tilemgr.cxx +++ b/src/Scenery/tilemgr.cxx @@ -50,6 +50,7 @@ using std::for_each; using flightgear::SceneryPager; +using simgear::SGModelLib; #define TEST_LAST_HIT_CACHE @@ -244,13 +245,18 @@ FGTileMgr::loadTileModel(const string& modelPath, bool cacheModel) { osg::Node* result = 0; try { - result = - globals->get_model_lib()->load_model(".", - modelPath, - globals->get_props(), - globals->get_sim_time_sec(), - cacheModel, - new FGNasalModelData ); + if(cacheModel) + { + result = + SGModelLib::loadModel(modelPath, globals->get_props(), + new FGNasalModelData); + } + else + { + result= + SGModelLib::loadPagedModel(modelPath, globals->get_props(), + new FGNasalModelData); + } } catch (const sg_io_exception& exc) { string m(exc.getMessage()); m += " "; diff --git a/src/Scripting/NasalSys.cxx b/src/Scripting/NasalSys.cxx index e312ac3d4..a836e37a5 100644 --- a/src/Scripting/NasalSys.cxx +++ b/src/Scripting/NasalSys.cxx @@ -1082,12 +1082,16 @@ bool FGNasalListener::changed(SGPropertyNode* node) void FGNasalModelData::modelLoaded(const string& path, SGPropertyNode *prop, osg::Node *) { + if(!prop) + return; + +/* SGPropertyNode *n = prop->getNode("nasal"), *load; if(!n) return; - - load = n->getNode("load"); - _unload = n->getNode("unload"); +*/ + SGPropertyNode *load = load = prop->getNode("load"); + _unload = prop->getNode("unload"); if(!load && !_unload) return; diff --git a/src/Scripting/NasalSys.hxx b/src/Scripting/NasalSys.hxx index 04313ea16..d1bf0a4c8 100644 --- a/src/Scripting/NasalSys.hxx +++ b/src/Scripting/NasalSys.hxx @@ -4,7 +4,7 @@ #include #include #include -#include +#include #include #include @@ -159,7 +159,7 @@ private: }; -class FGNasalModelData : public SGModelData { +class FGNasalModelData : public simgear::SGModelData { public: FGNasalModelData(SGPropertyNode *props = 0) : _props(props), _unload(0) {} ~FGNasalModelData();