]> git.mxchange.org Git - flightgear.git/blobdiff - src/AIModel/AIBase.cxx
bvh: Adapt to upstream bvh changes in simgear.
[flightgear.git] / src / AIModel / AIBase.cxx
index 95d023296daeead9e0194f595f86300ecad6dd70..ed6d0a9d9d0c0e4efdfd1acca4b7a8a456fe52ea 100644 (file)
@@ -34,7 +34,6 @@
 #include <osg/Node>
 #include <osgDB/FileUtils>
 
-#include <simgear/math/SGMath.hxx>
 #include <simgear/misc/sg_path.hxx>
 #include <simgear/scene/model/modellib.hxx>
 #include <simgear/scene/util/SGNodeMasks.hxx>
@@ -75,8 +74,7 @@ FGAIBase::FGAIBase(object_type ot, bool enableHot) :
     _refID( _newAIModelID() ),
     _otype(ot),
     _initialized(false),
-    _aimodel(0),
-    _fxpath(""),
+    _modeldata(0),
     _fx(0)
 
 {
@@ -145,7 +143,7 @@ FGAIBase::~FGAIBase() {
             model_removed->setStringValue(props->getPath());
     }
 
-    if (_refID != 0 && _refID !=  1) {
+    if (_fx && _refID != 0 && _refID !=  1) {
         SGSoundMgr *smgr = globals->get_soundmgr();
         stringstream name; 
         name <<  "aifx:";
@@ -153,7 +151,8 @@ FGAIBase::~FGAIBase() {
         smgr->remove(name.str());
     }
 
-    delete fp;
+    if (fp)
+        delete fp;
     fp = 0;
 }
 
@@ -163,6 +162,9 @@ FGAIBase::~FGAIBase() {
 void
 FGAIBase::removeModel()
 {
+    if (!_model.valid())
+        return;
+
     FGScenery* pSceneryManager = globals->get_scenery();
     if (pSceneryManager)
     {
@@ -172,7 +174,7 @@ FGAIBase::removeModel()
         aip.init( 0 );
         _model = 0;
         // pass it on to the pager, to be be deleted in the pager thread
-        pSceneryManager->getPagerSingleton()->queueDeleteRequest(temp);
+        pSceneryManager->getPager()->queueDeleteRequest(temp);
     }
     else
     {
@@ -228,21 +230,28 @@ void FGAIBase::update(double dt) {
                             pitch*speed );
         _fx->set_velocity( velocity );
     }
-    else if (_aimodel)
+    else if ((_modeldata)&&(_modeldata->needInitilization()))
     {
-        string fxpath = _aimodel->get_sound_path();
-        if (fxpath != "")
+        // process deferred nasal initialization,
+        // which must be done in main thread
+        _modeldata->init();
+
+        // sound initialization
+        if (fgGetBool("/sim/sound/aimodels/enabled",false))
         {
-            _fxpath = fxpath;
-            props->setStringValue("sim/sound/path", _fxpath.c_str());
-
-            // initialize the sound configuration
-            SGSoundMgr *smgr = globals->get_soundmgr();
-            stringstream name;
-            name <<  "aifx:";
-            name << _refID;
-            _fx = new FGFX(smgr, name.str(), props);
-            _fx->init();
+            string fxpath = _modeldata->get_sound_path();
+            if (fxpath != "")
+            {
+                props->setStringValue("sim/sound/path", fxpath.c_str());
+
+                // initialize the sound configuration
+                SGSoundMgr *smgr = globals->get_soundmgr();
+                stringstream name;
+                name <<  "aifx:";
+                name << _refID;
+                _fx = new FGFX(smgr, name.str(), props);
+                _fx->init();
+            }
         }
     }
 }
@@ -287,8 +296,14 @@ void FGAIBase::Transform() {
 
 }
 
-bool FGAIBase::init(bool search_in_AI_path) {
-    
+bool FGAIBase::init(bool search_in_AI_path)
+{
+    if (_model.valid())
+    {
+        SG_LOG(SG_AI, SG_ALERT, "AIBase: Cannot initialize a model multiple times! " << model_path);
+        return false;
+    }
+
     string f;
     if(search_in_AI_path)
     {
@@ -314,14 +329,8 @@ bool FGAIBase::init(bool search_in_AI_path) {
     else
         _installed = true;
 
-    _aimodel = new FGAIModelData(props);
-    osg::Node * mdl = SGModelLib::loadDeferredModel(f, props, _aimodel);
-
-    if (_model.valid())
-    {
-        // reinit, dump the old model
-        removeModel();
-    }
+    _modeldata = new FGAIModelData(props);
+    osg::Node * mdl = SGModelLib::loadDeferredModel(f, props, _modeldata);
 
     _model = new osg::LOD;
     _model->setName("AI-model range animation node");
@@ -341,11 +350,10 @@ bool FGAIBase::init(bool search_in_AI_path) {
         aip.setVisible(true);
         invisible = false;
         globals->get_scenery()->get_scene_graph()->addChild(aip.getSceneGraph());
-
-        // Get the sound-path tag from the configuration file and store it
-        // in the property tree.
         _initialized = true;
 
+        SG_LOG(SG_AI, SG_DEBUG, "AIBase: Loaded model " << model_path);
+
     } else if (!model_path.empty()) {
         SG_LOG(SG_AI, SG_WARN, "AIBase: Could not load model " << model_path);
         // not properly installed...
@@ -384,61 +392,62 @@ bool FGAIBase::isa( object_type otype ) {
 
 
 void FGAIBase::bind() {
-    props->tie("id", SGRawValueMethods<FGAIBase,int>(*this,
+    _tiedProperties.setRoot(props);
+    tie("id", SGRawValueMethods<FGAIBase,int>(*this,
         &FGAIBase::getID));
-    props->tie("velocities/true-airspeed-kt",  SGRawValuePointer<double>(&speed));
-    props->tie("velocities/vertical-speed-fps",
+    tie("velocities/true-airspeed-kt",  SGRawValuePointer<double>(&speed));
+    tie("velocities/vertical-speed-fps",
         SGRawValueMethods<FGAIBase,double>(*this,
         &FGAIBase::_getVS_fps,
         &FGAIBase::_setVS_fps));
 
-    props->tie("position/altitude-ft",
+    tie("position/altitude-ft",
         SGRawValueMethods<FGAIBase,double>(*this,
         &FGAIBase::_getAltitude,
         &FGAIBase::_setAltitude));
-    props->tie("position/latitude-deg",
+    tie("position/latitude-deg",
         SGRawValueMethods<FGAIBase,double>(*this,
         &FGAIBase::_getLatitude,
         &FGAIBase::_setLatitude));
-    props->tie("position/longitude-deg",
+    tie("position/longitude-deg",
         SGRawValueMethods<FGAIBase,double>(*this,
         &FGAIBase::_getLongitude,
         &FGAIBase::_setLongitude));
 
-    props->tie("position/global-x",
+    tie("position/global-x",
         SGRawValueMethods<FGAIBase,double>(*this,
         &FGAIBase::_getCartPosX,
         0));
-    props->tie("position/global-y",
+    tie("position/global-y",
         SGRawValueMethods<FGAIBase,double>(*this,
         &FGAIBase::_getCartPosY,
         0));
-    props->tie("position/global-z",
+    tie("position/global-z",
         SGRawValueMethods<FGAIBase,double>(*this,
         &FGAIBase::_getCartPosZ,
         0));
-    props->tie("callsign",
+    tie("callsign",
         SGRawValueMethods<FGAIBase,const char*>(*this,
         &FGAIBase::_getCallsign,
         0));
 
-    props->tie("orientation/pitch-deg",   SGRawValuePointer<double>(&pitch));
-    props->tie("orientation/roll-deg",    SGRawValuePointer<double>(&roll));
-    props->tie("orientation/true-heading-deg", SGRawValuePointer<double>(&hdg));
-
-    props->tie("radar/in-range", SGRawValuePointer<bool>(&in_range));
-    props->tie("radar/bearing-deg",   SGRawValuePointer<double>(&bearing));
-    props->tie("radar/elevation-deg", SGRawValuePointer<double>(&elevation));
-    props->tie("radar/range-nm", SGRawValuePointer<double>(&range));
-    props->tie("radar/h-offset", SGRawValuePointer<double>(&horiz_offset));
-    props->tie("radar/v-offset", SGRawValuePointer<double>(&vert_offset));
-    props->tie("radar/x-shift", SGRawValuePointer<double>(&x_shift));
-    props->tie("radar/y-shift", SGRawValuePointer<double>(&y_shift));
-    props->tie("radar/rotation", SGRawValuePointer<double>(&rotation));
-    props->tie("radar/ht-diff-ft", SGRawValuePointer<double>(&ht_diff));
-    props->tie("subID", SGRawValuePointer<int>(&_subID));
-    props->tie("controls/lighting/nav-lights",
-        SGRawValueFunctions<bool>(_isNight));
+    tie("orientation/pitch-deg",   SGRawValuePointer<double>(&pitch));
+    tie("orientation/roll-deg",    SGRawValuePointer<double>(&roll));
+    tie("orientation/true-heading-deg", SGRawValuePointer<double>(&hdg));
+
+    tie("radar/in-range", SGRawValuePointer<bool>(&in_range));
+    tie("radar/bearing-deg",   SGRawValuePointer<double>(&bearing));
+    tie("radar/elevation-deg", SGRawValuePointer<double>(&elevation));
+    tie("radar/range-nm", SGRawValuePointer<double>(&range));
+    tie("radar/h-offset", SGRawValuePointer<double>(&horiz_offset));
+    tie("radar/v-offset", SGRawValuePointer<double>(&vert_offset));
+    tie("radar/x-shift", SGRawValuePointer<double>(&x_shift));
+    tie("radar/y-shift", SGRawValuePointer<double>(&y_shift));
+    tie("radar/rotation", SGRawValuePointer<double>(&rotation));
+    tie("radar/ht-diff-ft", SGRawValuePointer<double>(&ht_diff));
+    tie("subID", SGRawValuePointer<int>(&_subID));
+    tie("controls/lighting/nav-lights", SGRawValueFunctions<bool>(_isNight));
+
     props->setBoolValue("controls/lighting/beacon", true);
     props->setBoolValue("controls/lighting/strobe", true);
     props->setBoolValue("controls/glide-path", true);
@@ -457,41 +466,15 @@ void FGAIBase::bind() {
     props->setDoubleValue("sim/sound/avionics/volume", 0.0);
     props->setBoolValue("sim/sound/avionics/external-view", false);
     props->setBoolValue("sim/current-view/internal", false);
-
 }
 
 void FGAIBase::unbind() {
-    props->untie("id");
-    props->untie("velocities/true-airspeed-kt");
-    props->untie("velocities/vertical-speed-fps");
-
-    props->untie("position/altitude-ft");
-    props->untie("position/latitude-deg");
-    props->untie("position/longitude-deg");
-    props->untie("position/global-x");
-    props->untie("position/global-y");
-    props->untie("position/global-z");
-    props->untie("callsign");
-
-    props->untie("orientation/pitch-deg");
-    props->untie("orientation/roll-deg");
-    props->untie("orientation/true-heading-deg");
+    _tiedProperties.Untie();
 
-    props->untie("radar/in-range");
-    props->untie("radar/bearing-deg");
-    props->untie("radar/elevation-deg");
-    props->untie("radar/range-nm");
-    props->untie("radar/h-offset");
-    props->untie("radar/v-offset");
-    props->untie("radar/x-shift");
-    props->untie("radar/y-shift");
-    props->untie("radar/rotation");
-    props->untie("radar/ht-diff-ft");
-
-    props->untie("controls/lighting/nav-lights");
-
-    props->setBoolValue("/sim/controls/radar/", true);
+    props->setBoolValue("/sim/controls/radar", true);
 
+    // drop reference to sound effects now
+    _fx = 0;
 }
 
 double FGAIBase::UpdateRadar(FGAIManager* manager) {
@@ -746,7 +729,7 @@ double FGAIBase::_getAltitude() const {
 
 double FGAIBase::_getAltitudeAGL(SGGeod inpos, double start){
     getGroundElevationM(SGGeod::fromGeodM(inpos, start),
-        _elevation_m, &_material);
+        _elevation_m, NULL);
     return inpos.getElevationFt() - _elevation_m * SG_METER_TO_FEET;
 }
 
@@ -905,24 +888,26 @@ int FGAIBase::_newAIModelID() {
 
 
 FGAIModelData::FGAIModelData(SGPropertyNode *root)
-  : _nasal( new FGNasalModelData(root) ),
-    _path("")
+  : _nasal( new FGNasalModelDataProxy(root) ),
+    _ready(false),
+    _initialized(false)
 {
 }
 
 FGAIModelData::~FGAIModelData()
 {
     delete _nasal;
+    _nasal = NULL;
 }
 
 void FGAIModelData::modelLoaded(const string& path, SGPropertyNode *prop, osg::Node *n)
 {
-    const char* fxpath = prop->getStringValue("sound/path");
-    if (fxpath) {
-        string sound_path = string(fxpath);
-        if (sound_path != "") {
-            _path = "/AI/"+sound_path;
-        }
-    }
+    // WARNING: Called in a separate OSG thread! Only use thread-safe stuff here...
+    if (_ready)
+        return;
+
+    _fxpath = prop->getStringValue("sound/path");
     _nasal->modelLoaded(path, prop, n);
+
+    _ready = true;
 }