]> git.mxchange.org Git - flightgear.git/commitdiff
model paging patch from Till Busch
authortimoore <timoore>
Sat, 22 Mar 2008 09:31:06 +0000 (09:31 +0000)
committertimoore <timoore>
Sat, 22 Mar 2008 09:31:06 +0000 (09:31 +0000)
From Till:
i started the project at the end of february with a simple idea: move all
3d-model loading to the DatabasePager-thread. my first attempts looked
promising, though they were a little too optimistic (or naive?). the patch
has evolved a lot since.

currently it does the following things:
1. revive SGModelLib, move functions for xml-model-loading there

2. replace all calls to sgLoad3dModel with calls to either
SGModelLib::loadModel() or SGModelLib::loadPagedModel()
almost all models will be loaded by the DatabasePager. the few exceptions are:
your own plane, shared models in scenery, random objects, AIBallistic models.

3. simplify mode-loading functions (avoid passing around fg_root)

4. avoid supurious MatrixTransform nodes in loaded models

5. fix some memory leaks

39 files changed:
src/AIModel/AIBallistic.cxx
src/AIModel/AIBallistic.hxx
src/AIModel/AIBase.cxx
src/AIModel/AIBase.hxx
src/AIModel/AICarrier.cxx
src/AIModel/AICarrier.hxx
src/AIModel/AIManager.cxx
src/AIModel/AIManager.hxx
src/AIModel/AIModelData.cxx [new file with mode: 0644]
src/AIModel/AIModelData.hxx [new file with mode: 0644]
src/AIModel/AIMultiplayer.cxx
src/AIModel/Makefile.am
src/AIModel/submodel.cxx
src/AIModel/submodel.hxx
src/ATC/AIEntity.hxx
src/ATC/AIMgr.cxx
src/ATC/AIPlane.hxx
src/Instrumentation/wxradar.cxx
src/Main/fg_os_osgviewer.cxx
src/Main/globals.cxx
src/Main/globals.hxx
src/Main/main.cxx
src/Main/renderer.cxx
src/Main/viewmgr.hxx
src/Model/acmodel.cxx
src/Model/model_panel.cxx
src/Model/model_panel.hxx
src/Model/modelmgr.cxx
src/MultiPlayer/multiplaymgr.cxx
src/MultiPlayer/multiplaymgr.hxx
src/Network/multiplay.hxx
src/Scenery/SceneryPager.cxx
src/Scenery/SceneryPager.hxx
src/Scenery/scenery.cxx
src/Scenery/scenery.hxx
src/Scenery/tileentry.cxx
src/Scenery/tilemgr.cxx
src/Scripting/NasalSys.cxx
src/Scripting/NasalSys.hxx

index 000ce326611a51de8f513c79c4024fcaecfa246b..0de56a46d63d4578fddc7cb25093941ac6857de7 100644 (file)
 #include <simgear/math/point3d.hxx>
 #include <simgear/math/sg_random.h>
 #include <simgear/math/sg_geodesy.hxx>
+#include <simgear/scene/model/modellib.hxx>
 
 #include <Scenery/scenery.hxx>
 
+#include "AIModelData.hxx"
 #include "AIBallistic.hxx"
 
 #include <Main/util.hxx>
@@ -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);
 
index f00e389d0986c0742a27fad2e2cd5b63185877ec..b6fb58a0fd263a4849cef36db1972fef57740098 100644 (file)
@@ -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();
index 35be09b9d183f67b01c2256cbefe08249e3b85a2..391cc577b04d4ba3974cb487492ecfa5c1294108 100644 (file)
 #  include <config.h>
 #endif
 
-
 #include <simgear/compiler.h>
 
 #include STL_STRING
 
 #include <osg/ref_ptr>
 #include <osg/Node>
+#include <osgDB/FileUtils>
 
 #include <simgear/math/point3d.hxx>
 #include <simgear/math/polar3d.hxx>
 #include <simgear/math/sg_geodesy.hxx>
 #include <simgear/misc/sg_path.hxx>
 #include <simgear/scene/model/location.hxx>
-#include <simgear/scene/model/model.hxx>
+#include <simgear/scene/model/modellib.hxx>
 #include <simgear/scene/util/SGNodeMasks.hxx>
 #include <simgear/debug/logstream.hxx>
 #include <simgear/props/props.hxx>
 #include <Scripting/NasalSys.hxx>
 
 #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<osgDB::ReaderWriter::Options> opt=
+        new osgDB::ReaderWriter::Options(*osgDB::Registry::instance()->getOptions());
+
+    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_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;
-            }
-        }
+    string f = osgDB::findDataFile(model_path, opt.get());
 
-    }
+    if(f.empty())
+        f="Models/Geometry/glider.ac";
+
+    model = load3DModel(f, props);
 
-    if (model.get()) {
+    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();
 }
 
index 0bdd6f85b0711ae990ed42e6700de7668e540876..ec55ce998d56d6c384a2424b7a5836484e2aab81 100644 (file)
@@ -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();
 };
 
index d3fa369a17a1783ced6e51bee7a6ae2f831b56ec..3791ab8d22a5b678bca6cb23dd6e5199fffb896d 100644 (file)
@@ -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();
 
index 33c674055c69b377c71eb033df51f0bb1e761230..0e88ba4527b8161549abf68f4e7fe226bb6a0271 100644 (file)
@@ -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"; }
 
index 7ed3d9d7a3ebb2ff8e827e7205415f19d82f071e..bc56af32f9a1467c15d04e0fd8c871771b68c096 100644 (file)
@@ -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<FGAIBase> 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<FGAICarrier> carrier = new FGAICarrier;
+                            osg::ref_ptr<FGAICarrier> 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;
     }
index d208ace8c0f53cbbbe997e387f0fdc15f203f074..19303fc34a21070458288f0b70ca46caac16bdf5 100644 (file)
@@ -46,13 +46,13 @@ class FGAIManager : public SGSubsystem
 public:
 
     // A list of pointers to AI objects
-    typedef list <SGSharedPtr<FGAIBase> > ai_list_type;
+    typedef list <osg::ref_ptr<FGAIBase> > 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 <SGSharedPtr<FGAIBase> >& 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<FGAIBase> 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 (file)
index 0000000..fe4762e
--- /dev/null
@@ -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 (file)
index 0000000..6ebabf0
--- /dev/null
@@ -0,0 +1,18 @@
+#ifndef __FGAIMODELDATA_HXX
+#define __FGAIMODELDATA_HXX
+
+#include <osg/observer_ptr>
+#include <Scripting/NasalSys.hxx>
+
+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<FGAIBase> _base;
+};
+
+#endif
index b7b0f689cb8dc2e89118f1cc1257c676697beb79..a34a92775635f1bbd2353b9ce71a528e56d74f6b 100755 (executable)
@@ -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
index 6dbfd7be2d04254c1b58199c09fbd670af52d588..350d69ee1e8cbefe2cb969c260be60c1197952dc 100644 (file)
@@ -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 \
index e246523a10db7bf7435270f243808329aca998c2..774820dc8343ffda2fb313b72d86c3ecfd78c1c4 100644 (file)
@@ -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;
     }
index 88f5694d7f6a96dddb92211ef95662e4b6e366a4..3f6965fcc917f6ec1823bff1c760abed543a681e 100644 (file)
@@ -173,7 +173,7 @@ private:
     IC_struct  IC;
 
     // A list of pointers to AI objects
-    typedef list <SGSharedPtr<FGAIBase> > sm_list_type;
+    typedef list <osg::ref_ptr<FGAIBase> > sm_list_type;
     typedef sm_list_type::iterator sm_list_iterator;
     typedef sm_list_type::const_iterator sm_list_const_iterator;
 
index dc9070b8bfebc3e4bd1c52387c62231b65b96e64..1b184a83344ed5282ff7c270c35527b285b76125 100644 (file)
@@ -22,7 +22,6 @@
 #define _FG_AIEntity_HXX
 
 #include <simgear/math/point3d.hxx>
-#include <simgear/scene/model/model.hxx>
 #include <simgear/scene/model/placement.hxx>
 
 
index 8b38de6639829aa11182c61f7cb1851c6a2368b5..23d44bbf1b4ac5365a1ca4319649d643d8b36f0d 100644 (file)
@@ -27,6 +27,7 @@
 #include <Main/globals.hxx>
 #include <simgear/misc/sg_path.hxx>
 #include <simgear/math/sg_random.h>
+#include <simgear/scene/model/modellib.hxx>
 #include <list>
 
 #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;
        }
index 3cf218dfddb4eeae17ee16bafb99f995d316f25d..b29726c39f262ed72866f7eda71a48a41881864c 100644 (file)
@@ -22,7 +22,6 @@
 #define _FG_AI_PLANE_HXX
 
 #include <simgear/math/point3d.hxx>
-#include <simgear/scene/model/model.hxx>
 
 #include "AIEntity.hxx"
 #include "ATC.hxx"
index e7df08b854a1bb4cc027af95446969d8404e716b..0cc0801e8491990db442207446270cae2f3d8d39 100644 (file)
@@ -67,7 +67,7 @@ SG_USING_STD(setfill);
 #include "wxradar.hxx"
 
 
-typedef list <SGSharedPtr<FGAIBase> > radar_list_type;
+typedef list <osg::ref_ptr<FGAIBase> > 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();
index 4ccb39c19c466ffb13cfabf68c95ff18eb318e06..a713e0627e16fa74a2eee4b3453bc08ef8f4838f 100644 (file)
@@ -260,6 +260,7 @@ static int status = 0;
 void fgOSExit(int code)
 {
     viewer->setDone(true);
+    viewer->getDatabasePager()->cancel();
     status = code;
 }
 
index ecea15d0c251eb9835af6664ba07e1d8eec4665c..3a28be27ccfffab7e76a846b2c0269a6ef78ea45 100644 (file)
@@ -24,7 +24,6 @@
 #  include <config.h>
 #endif
 
-#include <simgear/scene/model/modellib.hxx>
 #include <simgear/sound/soundmgr_openal.hxx>
 #include <simgear/structure/commands.hxx>
 #include <simgear/misc/sg_path.hxx>
@@ -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 runways;
-     delete ATC_mgr;
-     delete AI_mgr;
-     delete controls;
-     delete viewmgr;
-
-     delete initial_state;
-//     //delete locale; Don't delete locale
+    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 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))
index 8db8f5557e9b4d761024f5e0a9d6fbafcb17a5fb..9182326ee245bd0f01545bdb33ae3af4e139a137 100644 (file)
@@ -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)
index 615ed6c548091e32eb7473cbf64ca64c6809183a..d0acc277654a3c744f86a2bec90df91ee6db7842 100644 (file)
@@ -47,6 +47,8 @@
 #include <simgear/timing/sg_time.hxx>
 #include <simgear/math/sg_random.h>
 
+#include <osgDB/Registry>
+
 // Class references
 #include <simgear/ephemeris/ephemeris.hxx>
 #include <simgear/scene/model/modellib.hxx>
@@ -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());
 
 
         ////////////////////////////////////////////////////////////////////
index a67a832f3df2d60aac2a069c45ac1e2b0ac61737..e4170322473b3747ceff299a738a7a343928b7ae 100644 (file)
@@ -66,8 +66,6 @@
 #include <simgear/screen/extensions.hxx>
 #include <simgear/scene/material/matlib.hxx>
 #include <simgear/scene/model/animation.hxx>
-#include <simgear/scene/model/model.hxx>
-#include <simgear/scene/model/modellib.hxx>
 #include <simgear/scene/model/placement.hxx>
 #include <simgear/scene/util/SGUpdateVisitor.hxx>
 #include <simgear/scene/util/RenderConstants.hxx>
index 321f6a2e157ac88943eb3d5d40b62b8231b65508..1823cbbf45b557959446e88d5ceff6cc32d24a96 100644 (file)
@@ -150,7 +150,7 @@ private:
 
     SGPropertyNode_ptr view_number;
     vector<SGPropertyNode_ptr> config_list;
-    typedef vector<FGViewer *> viewer_list;
+    typedef vector<SGSharedPtr<FGViewer> > viewer_list;
     viewer_list views;
 
     int current;
index d3af3b4be5e0d34544ee2a53bc33cd159c4f5cc6..1f9b15a7e692c8b87607603adccaa71f1bb51f89 100644 (file)
@@ -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);
index ef98544793cc2d39c2c844fc3766baf400d9d952..ea24a2fa2e0c6fb0d503b0b83cf387388fc004ee 100644 (file)
@@ -12,7 +12,7 @@
 #include <osg/Geode>
 
 #include <simgear/props/props.hxx>
-#include <simgear/scene/model/model.hxx>
+#include <simgear/scene/model/modellib.hxx>
 #include <simgear/scene/util/SGNodeMasks.hxx>
 
 #include "panelnode.hxx"
 
 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;
 }
 
 \f
@@ -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;
 }
 
 
index 0c1c34a14739ee80fdf4328a89064c334ce00f35..0b82d3313289d3f777e55a913b6762865a2ff382 100644 (file)
@@ -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
index 4d19b7be16ca61bd4d9bf2b5c49e2b755ae9723b..a7f543f1ebada0c253283faca328533b254153f0 100644 (file)
 
 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());
index 271c0f41e67c2faf085ce215833be679ea039ce6..a31325a55ca4e452e45c6c7dc2159c60836b6131 100644 (file)
@@ -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;
 }
index ca9072e405fb70216365b4255799866964fc70ea..073b57a5c15cfdacd348d022f9459e36add3f68d 100644 (file)
@@ -83,7 +83,7 @@ private:
   FGAIMultiplayer* getMultiplayer(const std::string& callsign);
 
   /// maps from the callsign string to the FGAIMultiplayer
-  typedef std::map<std::string, SGSharedPtr<FGAIMultiplayer> > MultiPlayerMap;
+  typedef std::map<std::string, osg::ref_ptr<FGAIMultiplayer> > MultiPlayerMap;
   MultiPlayerMap mMultiPlayerMap;
 
   netSocket* mSocket;
index decbdc1c4771e3190521b3c6ab421aaab05584c9..145f1054dd8ef5df90443654baba73acd57b1e08 100644 (file)
@@ -32,7 +32,6 @@
 #include STL_STRING
 
 #include <simgear/props/props.hxx>
-#include <simgear/scene/model/model.hxx>
 
 #include <Main/globals.hxx>
 #include <Main/fg_props.hxx>
index 5615436e4c4db1162440a1789c0ae4b75533293e..6da6d4b726d58c8eff4bdae38deb5cf16e238443 100644 (file)
@@ -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 <simgear/scene/model/SGPagedLOD.hxx>
 #include "SceneryPager.hxx"
 #include <algorithm>
 #include <functional>
@@ -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<simgear::SGPagedLOD*>(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)
 {
index a0c87e78e74f776e8cb5b0056b6f36012e7a2da8..283c9db95bf6beec18d7af975b7c95ad4bcd260e 100644 (file)
@@ -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
index 93f5c2f7ecd254d41c1551d53f9fa285dc401ab8..84c5b9fad2d2e1006c7a12e2be67d32f6f00275f 100644 (file)
@@ -30,6 +30,7 @@
 
 #include <osgUtil/IntersectVisitor>
 
+#include <simgear/constants.h>
 #include <simgear/debug/logstream.hxx>
 #include <simgear/scene/tgdb/userdata.hxx>
 #include <simgear/math/sg_geodesy.hxx>
 #include <simgear/scene/material/matlib.hxx>
 #include <simgear/scene/util/SGNodeMasks.hxx>
 #include <simgear/scene/util/SGSceneUserData.hxx>
+#include <simgear/scene/model/CheckSceneryVisitor.hxx>
 
 #include <Main/fg_props.hxx>
 
+#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<SceneryPager> pager = new SceneryPager;
index 0b2d8832bfadcaea04212db5ab6dc7f63ce01a9d..0fdd9cd89f615dd5990b008b5e59c861b5e39621 100644 (file)
@@ -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();
index 354a10971deacf7cabe653b498ecb91fab79fe6b..06f1192e3641378aadf26b114dee843eef2c6723 100644 (file)
@@ -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 );
 
index b3c1e3ec43ec722708a4028b50e7c0f0624b8df4..adf548d5492f3835fab6617454ffa78509698fbb 100644 (file)
@@ -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 += " ";
index e312ac3d49d39ed43ab1f8609ec347d91ba4e66e..a836e37a599166ae3584ea473b31b0d3f3d1209e 100644 (file)
@@ -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;
 
index 04313ea1661cbbd5bd7bd94bd89e3c49679e951b..d1bf0a4c8e8f952cfb0775ff0d0a4f7ad859c509 100644 (file)
@@ -4,7 +4,7 @@
 #include <simgear/misc/sg_path.hxx>
 #include <simgear/structure/subsystem_mgr.hxx>
 #include <simgear/nasal/nasal.h>
-#include <simgear/scene/model/model.hxx>
+#include <simgear/scene/model/modellib.hxx>
 #include <simgear/xml/easyxml.hxx>
 
 #include <map>
@@ -159,7 +159,7 @@ private:
 };
 
 
-class FGNasalModelData : public SGModelData {
+class FGNasalModelData : public simgear::SGModelData {
 public:
     FGNasalModelData(SGPropertyNode *props = 0) : _props(props), _unload(0) {}
     ~FGNasalModelData();