]> git.mxchange.org Git - flightgear.git/blobdiff - src/AIModel/AIBase.cxx
Interim windows build fix
[flightgear.git] / src / AIModel / AIBase.cxx
index 0f371c45478458e875f23dc22e91c2c7dad13f34..339de5f27f17557dd42b435722d19b238b4b42e8 100644 (file)
 #include <simgear/props/props.hxx>
 
 #include <Main/globals.hxx>
+#include <Main/fg_props.hxx>
 #include <Scenery/scenery.hxx>
 #include <Scripting/NasalSys.hxx>
 #include <Scripting/NasalModelData.hxx>
 #include <Sound/fg_fx.hxx>
 
+#include "AIFlightPlan.hxx"
 #include "AIBase.hxx"
 #include "AIManager.hxx"
 
@@ -62,7 +64,9 @@ public:
     FGAIModelData(SGPropertyNode *root = NULL)
         : _nasal( new FGNasalModelDataProxy(root) ),
         _ready(false),
-        _initialized(false)
+        _initialized(false),
+        _hasInteriorPath(false),
+        _interiorLoaded(false)
     {
     }
 
@@ -80,6 +84,11 @@ public:
         if (_ready)
             return;
         
+        if(prop->hasChild("interior-path")){
+            _interiorPath = prop->getStringValue("interior-path");
+            _hasInteriorPath = true;
+        }
+
         _fxpath = prop->getStringValue("sound/path");
         _nasal->modelLoaded(path, prop, n);
         
@@ -94,12 +103,20 @@ public:
     bool needInitilization(void) { return _ready && !_initialized;}
     bool isInitialized(void) { return _initialized;}
     inline std::string& get_sound_path() { return _fxpath;}
-    
+
+    void setInteriorLoaded(const bool state) { _interiorLoaded = state;}
+    bool getInteriorLoaded(void) { return _interiorLoaded;}
+    bool hasInteriorPath(void) { return _hasInteriorPath;}
+    inline std::string& getInteriorPath() { return _interiorPath; }
 private:
     std::auto_ptr<FGNasalModelDataProxy> _nasal;
     std::string _fxpath;
     bool _ready;
     bool _initialized;
+
+    std::string _interiorPath;
+    bool _hasInteriorPath;
+    bool _interiorLoaded;
 };
 
 FGAIBase::FGAIBase(object_type ot, bool enableHot) :
@@ -204,19 +221,23 @@ FGAIBase::removeModel()
         return;
 
     FGScenery* pSceneryManager = globals->get_scenery();
-    if (pSceneryManager)
+    if (pSceneryManager && pSceneryManager->get_models_branch())
     {
         osg::ref_ptr<osg::Object> temp = _model.get();
-        pSceneryManager->get_scene_graph()->removeChild(aip.getSceneGraph());
+        pSceneryManager->get_models_branch()->removeChild(aip.getSceneGraph());
         // withdraw from SGModelPlacement and drop own reference (unref)
-        aip.init( 0 );
+        aip.clear();
+        _modeldata = 0;
         _model = 0;
+        
         // pass it on to the pager, to be be deleted in the pager thread
         pSceneryManager->getPager()->queueDeleteRequest(temp);
     }
     else
     {
-        SG_LOG(SG_AI, SG_ALERT, "AIBase: Could not unload model. Missing scenery manager!");
+        aip.clear();
+        _model = 0;
+        _modeldata = 0;
     }
 }
 
@@ -291,13 +312,36 @@ void FGAIBase::update(double dt) {
             }
         }
     }
+
+    updateInterior();
+}
+
+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());
+            }
+        }
+    }
 }
 
 /** update LOD properties of the model */
 void FGAIBase::updateLOD()
 {
     double maxRangeDetail = fgGetDouble("/sim/rendering/static-lod/ai-detailed", 10000.0);
-    double maxRangeBare   = fgGetDouble("/sim/rendering/static-lod/ai-bare", 20000.0);
+//    double maxRangeBare   = fgGetDouble("/sim/rendering/static-lod/ai-bare", 20000.0);
+
+    _maxRangeInterior     = fgGetDouble("/sim/rendering/static-lod/ai-interior", 50.0);
     if (_model.valid())
     {
         if( maxRangeDetail == 0.0 )
@@ -308,8 +352,14 @@ void FGAIBase::updateLOD()
         }
         else
         {
-            _model->setRange(0, 0.0, maxRangeDetail);
-            _model->setRange(1, maxRangeDetail,maxRangeBare);
+            if( fgGetBool("/sim/rendering/static-lod/ai-range-mode-pixel", false ) ) 
+            {
+                _model->setRangeMode( osg::LOD::PIXEL_SIZE_ON_SCREEN );
+                _model->setRange(0, maxRangeDetail, 100000 );
+            } else {
+                _model->setRangeMode( osg::LOD:: DISTANCE_FROM_EYE_POINT);
+                _model->setRange(0, 0.0, maxRangeDetail);
+            }
         }
     }
 }
@@ -344,23 +394,17 @@ bool FGAIBase::init(bool search_in_AI_path)
     string f;
     if(search_in_AI_path)
     {
-    // setup a modified Options structure, with only the $fg-root/AI defined;
-    // we'll check that first, then give the normal search logic a chance.
-    // this ensures that models in AI/ are preferred to normal models, where
-    // both exist.
-        osg::ref_ptr<osgDB::ReaderWriter::Options> 
-          opt(osg::clone(osgDB::Registry::instance()->getOptions(), osg::CopyOp::SHALLOW_COPY));
-
-        osgDB::FilePathList& paths(opt->getDatabasePathList());
-        paths.clear();
         BOOST_FOREACH(SGPath p, globals->get_data_paths("AI")) {
-            paths.push_back(p.str());
-        }
-        f = osgDB::findDataFile(model_path, opt.get());
-    }
+            p.append(model_path);
+            if (p.exists()) {
+                f = p.str();
+                break;
+            }
+        } // of AI data paths iteration
+    } // of search in AI path
 
     if (f.empty()) {
-      f = simgear::SGModelLib::findDataFile(model_path);
+        f = simgear::SGModelLib::findDataFile(model_path);
     }
     
     if(f.empty())
@@ -368,27 +412,27 @@ bool FGAIBase::init(bool search_in_AI_path)
     else
         _installed = true;
 
+    props->addChild("type")->setStringValue("AI");
     _modeldata = new FGAIModelData(props);
-    osg::Node * mdl = SGModelLib::loadDeferredModel(f, props, _modeldata);
+    _model= SGModelLib::loadPagedModel(f, props, _modeldata);
 
-    _model = new osg::LOD;
     _model->setName("AI-model range animation node");
 
-    _model->addChild( mdl, 0, FLT_MAX );
-    _model->setCenterMode(osg::LOD::USE_BOUNDING_SPHERE_CENTER);
-    _model->setRangeMode(osg::LOD::DISTANCE_FROM_EYE_POINT);
+  //  _model->setCenterMode(osg::LOD::USE_BOUNDING_SPHERE_CENTER);
+  //  _model->setRangeMode(osg::LOD::DISTANCE_FROM_EYE_POINT);
+  
 //    We really need low-resolution versions of AI/MP aircraft.
 //    Or at least dummy "stubs" with some default silhouette.
 //        _model->addChild( SGModelLib::loadPagedModel(fgGetString("/sim/multiplay/default-model", default_model),
 //                                                    props, new FGNasalModelData(props)), FLT_MAX, FLT_MAX);
     updateLOD();
-
-    initModel(mdl);
+    initModel();
+  
     if (_model.valid() && _initialized == false) {
         aip.init( _model.get() );
         aip.setVisible(true);
         invisible = false;
-        globals->get_scenery()->get_scene_graph()->addChild(aip.getSceneGraph());
+        globals->get_scenery()->get_models_branch()->addChild(aip.getSceneGraph());
         _initialized = true;
 
         SG_LOG(SG_AI, SG_DEBUG, "AIBase: Loaded model " << model_path);
@@ -403,7 +447,7 @@ bool FGAIBase::init(bool search_in_AI_path)
     return true;
 }
 
-void FGAIBase::initModel(osg::Node *node)
+void FGAIBase::initModel()
 {
     if (_model.valid()) { 
 
@@ -891,5 +935,7 @@ int FGAIBase::_newAIModelID() {
     return id;
 }
 
-
-
+bool FGAIBase::isValid() { 
+       //Either no flightplan or it is valid
+       return !fp || fp->isValidPlan(); 
+}