X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FAIModel%2FAIBase.cxx;h=7cfcfcb0a33418517ff24f767da13d599e186191;hb=bcea720db3e29a62626b361f2149a7147e149f3b;hp=7871f7e8e08b999ca0b8f15b528b3a6e9681a21b;hpb=b796df3bd7d8fa6998a30ed033198a41a63a32b7;p=flightgear.git diff --git a/src/AIModel/AIBase.cxx b/src/AIModel/AIBase.cxx index 7871f7e8e..7cfcfcb0a 100644 --- a/src/AIModel/AIBase.cxx +++ b/src/AIModel/AIBase.cxx @@ -34,7 +34,6 @@ #include #include -#include #include #include #include @@ -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,12 +143,17 @@ FGAIBase::~FGAIBase() { model_removed->setStringValue(props->getPath()); } + // refID=0 is supposedley impossible, refID=1 is the special ai_ac aircaft + // representing the current user, in the ATCManager. Maybe both these + // tests could die? if (_fx && _refID != 0 && _refID != 1) { SGSoundMgr *smgr = globals->get_soundmgr(); - stringstream name; - name << "aifx:"; - name << _refID; - smgr->remove(name.str()); + if (smgr) { + stringstream name; + name << "aifx:"; + name << _refID; + smgr->remove(name.str()); + } } if (fp) @@ -176,7 +179,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 { @@ -232,21 +235,27 @@ void FGAIBase::update(double dt) { pitch*speed ); _fx->set_velocity( velocity ); } - else if ((_aimodel)&&(fgGetBool("/sim/sound/aimodels/enabled",false))) + 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 + stringstream name; + name << "aifx:"; + name << _refID; + _fx = new FGFX(name.str(), props); + _fx->init(); + } } } } @@ -324,8 +333,8 @@ bool FGAIBase::init(bool search_in_AI_path) else _installed = true; - _aimodel = new FGAIModelData(props); - osg::Node * mdl = SGModelLib::loadDeferredModel(f, props, _aimodel); + _modeldata = new FGAIModelData(props); + osg::Node * mdl = SGModelLib::loadDeferredModel(f, props, _modeldata); _model = new osg::LOD; _model->setName("AI-model range animation node"); @@ -345,11 +354,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... @@ -388,61 +396,62 @@ bool FGAIBase::isa( object_type otype ) { void FGAIBase::bind() { - props->tie("id", SGRawValueMethods(*this, + _tiedProperties.setRoot(props); + tie("id", SGRawValueMethods(*this, &FGAIBase::getID)); - props->tie("velocities/true-airspeed-kt", SGRawValuePointer(&speed)); - props->tie("velocities/vertical-speed-fps", + tie("velocities/true-airspeed-kt", SGRawValuePointer(&speed)); + tie("velocities/vertical-speed-fps", SGRawValueMethods(*this, &FGAIBase::_getVS_fps, &FGAIBase::_setVS_fps)); - props->tie("position/altitude-ft", + tie("position/altitude-ft", SGRawValueMethods(*this, &FGAIBase::_getAltitude, &FGAIBase::_setAltitude)); - props->tie("position/latitude-deg", + tie("position/latitude-deg", SGRawValueMethods(*this, &FGAIBase::_getLatitude, &FGAIBase::_setLatitude)); - props->tie("position/longitude-deg", + tie("position/longitude-deg", SGRawValueMethods(*this, &FGAIBase::_getLongitude, &FGAIBase::_setLongitude)); - props->tie("position/global-x", + tie("position/global-x", SGRawValueMethods(*this, &FGAIBase::_getCartPosX, 0)); - props->tie("position/global-y", + tie("position/global-y", SGRawValueMethods(*this, &FGAIBase::_getCartPosY, 0)); - props->tie("position/global-z", + tie("position/global-z", SGRawValueMethods(*this, &FGAIBase::_getCartPosZ, 0)); - props->tie("callsign", + tie("callsign", SGRawValueMethods(*this, &FGAIBase::_getCallsign, 0)); - props->tie("orientation/pitch-deg", SGRawValuePointer(&pitch)); - props->tie("orientation/roll-deg", SGRawValuePointer(&roll)); - props->tie("orientation/true-heading-deg", SGRawValuePointer(&hdg)); - - props->tie("radar/in-range", SGRawValuePointer(&in_range)); - props->tie("radar/bearing-deg", SGRawValuePointer(&bearing)); - props->tie("radar/elevation-deg", SGRawValuePointer(&elevation)); - props->tie("radar/range-nm", SGRawValuePointer(&range)); - props->tie("radar/h-offset", SGRawValuePointer(&horiz_offset)); - props->tie("radar/v-offset", SGRawValuePointer(&vert_offset)); - props->tie("radar/x-shift", SGRawValuePointer(&x_shift)); - props->tie("radar/y-shift", SGRawValuePointer(&y_shift)); - props->tie("radar/rotation", SGRawValuePointer(&rotation)); - props->tie("radar/ht-diff-ft", SGRawValuePointer(&ht_diff)); - props->tie("subID", SGRawValuePointer(&_subID)); - props->tie("controls/lighting/nav-lights", - SGRawValueFunctions(_isNight)); + tie("orientation/pitch-deg", SGRawValuePointer(&pitch)); + tie("orientation/roll-deg", SGRawValuePointer(&roll)); + tie("orientation/true-heading-deg", SGRawValuePointer(&hdg)); + + tie("radar/in-range", SGRawValuePointer(&in_range)); + tie("radar/bearing-deg", SGRawValuePointer(&bearing)); + tie("radar/elevation-deg", SGRawValuePointer(&elevation)); + tie("radar/range-nm", SGRawValuePointer(&range)); + tie("radar/h-offset", SGRawValuePointer(&horiz_offset)); + tie("radar/v-offset", SGRawValuePointer(&vert_offset)); + tie("radar/x-shift", SGRawValuePointer(&x_shift)); + tie("radar/y-shift", SGRawValuePointer(&y_shift)); + tie("radar/rotation", SGRawValuePointer(&rotation)); + tie("radar/ht-diff-ft", SGRawValuePointer(&ht_diff)); + tie("subID", SGRawValuePointer(&_subID)); + tie("controls/lighting/nav-lights", SGRawValueFunctions(_isNight)); + props->setBoolValue("controls/lighting/beacon", true); props->setBoolValue("controls/lighting/strobe", true); props->setBoolValue("controls/glide-path", true); @@ -461,40 +470,12 @@ 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"); - - 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); + _tiedProperties.Untie(); + + props->setBoolValue("/sim/controls/radar", true); // drop reference to sound effects now _fx = 0; @@ -630,7 +611,7 @@ SGVec3d FGAIBase::getCartPos() const { } bool FGAIBase::getGroundElevationM(const SGGeod& pos, double& elev, - const SGMaterial** material) const { + const simgear::BVHMaterial** material) const { return globals->get_scenery()->get_elevation_m(pos, elev, material, _model.get()); } @@ -752,7 +733,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; } @@ -911,24 +892,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; }