]> git.mxchange.org Git - flightgear.git/commitdiff
Add aubmodels to AI objects
authorVivian Meazza <vivian.meazza@lineone.net>
Sat, 14 Aug 2010 12:39:30 +0000 (13:39 +0100)
committerVivian Meazza <vivian.meazza@lineone.net>
Sat, 14 Aug 2010 12:39:30 +0000 (13:39 +0100)
Signed-off-by: Vivian Meazza <vivian.meazza@lineone.net>
src/AIModel/AIBallistic.cxx
src/AIModel/AIBase.cxx
src/AIModel/AIBase.hxx
src/AIModel/AIGroundVehicle.cxx
src/AIModel/AIWingman.cxx
src/AIModel/submodel.cxx
src/AIModel/submodel.hxx
src/Environment/environment_mgr.cxx

index 76e412c0c81db406a40936036d300ac5d58b82f9..e94844eaf473aa09d256e19d618ebebb319d01e1 100644 (file)
@@ -39,34 +39,34 @@ const double FGAIBallistic::slugs_to_kgs = 14.5939029372;
 const double FGAIBallistic::slugs_to_lbs = 32.1740485564;
 
 FGAIBallistic::FGAIBallistic(object_type ot) :
-    FGAIBase(ot),
-    _height(0.0),
-    _ht_agl_ft(0.0),
-    _azimuth(0.0),
-    _elevation(0.0),
-    _rotation(0.0),
-    _formate_to_ac(false),
-    _aero_stabilised(false),
-    _drag_area(0.007),
-    _life_timer(0.0),
-    _gravity(32.1740485564),
-    _buoyancy(0),
-    _wind(true),
-    _mass(0),
-    _random(false),
-    _load_resistance(0),
-    _solid(false),
-    _force_stabilised(false),
-    _slave_to_ac(false),
-    _slave_load_to_ac(false),
-    _contents_lb(0),
-    _report_collision(false),
-       _report_expiry(false),
-    _report_impact(false),
-    _external_force(false),
-    _impact_report_node(fgGetNode("/ai/models/model-impact", true)),
-    _old_height(0),
-       _elapsed_time(0)
+FGAIBase(ot),
+_height(0.0),
+_ht_agl_ft(0.0),
+_azimuth(0.0),
+_elevation(0.0),
+_rotation(0.0),
+_formate_to_ac(false),
+_aero_stabilised(false),
+_drag_area(0.007),
+_life_timer(0.0),
+_gravity(32.1740485564),
+_buoyancy(0),
+_wind(true),
+_mass(0),
+_random(false),
+_load_resistance(0),
+_solid(false),
+_force_stabilised(false),
+_slave_to_ac(false),
+_slave_load_to_ac(false),
+_contents_lb(0),
+_report_collision(false),
+_report_expiry(false),
+_report_impact(false),
+_external_force(false),
+_impact_report_node(fgGetNode("/ai/models/model-impact", true)),
+_old_height(0),
+_elapsed_time(0)
 
 {
     no_roll = false;
@@ -83,7 +83,7 @@ void FGAIBallistic::readFromScenario(SGPropertyNode* scFileNode) {
     FGAIBase::readFromScenario(scFileNode);
 
     //setPath(scFileNode->getStringValue("model", "Models/Geometry/rocket.ac")); 
-       setRandom(scFileNode->getBoolValue("random", false));
+    setRandom(scFileNode->getBoolValue("random", false));
     setAzimuth(scFileNode->getDoubleValue("azimuth", 0.0));
     setElevation(scFileNode->getDoubleValue("elevation", 0));
     setDragArea(scFileNode->getDoubleValue("eda", 0.007));
@@ -99,8 +99,8 @@ void FGAIBallistic::readFromScenario(SGPropertyNode* scFileNode) {
     setStabilisation(scFileNode->getBoolValue("aero-stabilised", false));
     setNoRoll(scFileNode->getBoolValue("no-roll", false));
     setImpact(scFileNode->getBoolValue("impact", false));
-       setExpiry(scFileNode->getBoolValue("expiry", false));
-       setCollision(scFileNode->getBoolValue("collision", false));
+    setExpiry(scFileNode->getBoolValue("expiry", false));
+    setCollision(scFileNode->getBoolValue("collision", false));
     setImpactReportNode(scFileNode->getStringValue("impact-reports"));
     setName(scFileNode->getStringValue("name", "Rocket"));
     setFuseRange(scFileNode->getDoubleValue("fuse-range", 0.0));
@@ -127,9 +127,9 @@ bool FGAIBallistic::init(bool search_in_AI_path) {
 
     _impact_reported = false;
     _collision_reported = false;
-       _expiry_reported = false;
+    _expiry_reported = false;
 
-       _impact_lat = 0;
+    _impact_lat = 0;
     _impact_lon = 0;
     _impact_elev = 0;
     _impact_hdg = 0;
@@ -144,8 +144,8 @@ bool FGAIBallistic::init(bool search_in_AI_path) {
     props->setStringValue("material/name", "");
     props->setStringValue("name", _name.c_str());
     props->setStringValue("submodels/path", _submodel.c_str());
-       props->setStringValue("force/path", _force_path.c_str());
-       //props->setStringValue("vector/path", _vector_path.c_str());
+    props->setStringValue("force/path", _force_path.c_str());
+    //props->setStringValue("vector/path", _vector_path.c_str());
 
     // start with high value so that animations don't trigger yet
     _ht_agl_ft = 1e10;
@@ -168,11 +168,11 @@ void FGAIBallistic::bind() {
         SGRawValueMethods<FGAIBallistic,double>(*this,
         &FGAIBallistic::getMass));
     props->tie("material/load-resistance",
-                SGRawValuePointer<double>(&_load_resistance));
+        SGRawValuePointer<double>(&_load_resistance));
     props->tie("material/solid",
-                SGRawValuePointer<bool>(&_solid));
+        SGRawValuePointer<bool>(&_solid));
     props->tie("altitude-agl-ft",
-                SGRawValuePointer<double>(&_ht_agl_ft));
+        SGRawValuePointer<double>(&_ht_agl_ft));
     props->tie("controls/slave-to-ac",
         SGRawValueMethods<FGAIBallistic,bool>
         (*this, &FGAIBallistic::getSlaved, &FGAIBallistic::setSlaved));
@@ -271,20 +271,20 @@ void FGAIBallistic::update(double dt) {
         Transform();
         setHitchVelocity(dt);
     } else if (!invisible){
-    Run(dt);
-    Transform();
-}
+        Run(dt);
+        Transform();
+    }
 
 }
 
 void FGAIBallistic::setAzimuth(double az) {
-    
-       if (_random)
-               hdg = _azimuth = (az - 5 ) + (10 * sg_random());
-       else 
-               hdg = _azimuth = az;
 
-       //cout << _name << " init hdg " << hdg << " random " << _random << endl;
+    if (_random)
+        hdg = _azimuth = (az - 5 ) + (10 * sg_random());
+    else 
+        hdg = _azimuth = az;
+
+    //cout << _name << " init hdg " << hdg << " random " << _random << endl;
 }
 
 void FGAIBallistic::setElevation(double el) {
@@ -313,11 +313,11 @@ void FGAIBallistic::setDragArea(double a) {
 
 void FGAIBallistic::setLife(double seconds) {
 
-       if (_random){
-               life = seconds * _randomness + (seconds * (1 -_randomness) * sg_random());
-               //cout << "life " << life << endl;
-       } else
-               life = seconds;
+    if (_random){
+        life = seconds * _randomness + (seconds * (1 -_randomness) * sg_random());
+        //cout << "life " << life << endl;
+    } else
+        life = seconds;
 }
 
 void FGAIBallistic::setBuoyancy(double fpss) {
@@ -366,7 +366,7 @@ void FGAIBallistic::setCollision(bool c) {
 
 void FGAIBallistic::setExpiry(bool e) {
     _report_expiry = e;
-       //cout <<  "_report_expiry " << _report_expiry << endl;
+    //cout <<  "_report_expiry " << _report_expiry << endl;
 }
 
 void FGAIBallistic::setExternalForce(bool f) {
@@ -465,7 +465,7 @@ void FGAIBallistic::setForcePath(const string& p) {
 bool FGAIBallistic::getHtAGL(){
 
     if (getGroundElevationM(SGGeod::fromGeodM(pos, 10000),
-                            _elevation_m, &_material)) {
+        _elevation_m, &_material)) {
             _ht_agl_ft = pos.getElevationFt() - _elevation_m * SG_METER_TO_FEET;
             if (_material) {
                 const vector<string>& names = _material->get_names();
@@ -515,16 +515,16 @@ void FGAIBallistic::setHt(double h, double dt, double coeff){
 }
 
 void FGAIBallistic::setHdg(double az, double dt, double coeff){
-       double recip = getRecip(hdg);
-       double c = dt / (coeff + dt);
-       //we need to ensure that we turn the short way to the new hdg
-       if (az < recip && az < hdg && hdg > 180) {
-               hdg = ((az + 360) * c) + (hdg * (1 - c));
-       } else if (az > recip && az > hdg && hdg <= 180){
-               hdg = ((az - 360) * c) + (hdg * (1 - c));
-       } else {
-               hdg = (az * c) + (hdg * (1 - c));
-       }
+    double recip = getRecip(hdg);
+    double c = dt / (coeff + dt);
+    //we need to ensure that we turn the short way to the new hdg
+    if (az < recip && az < hdg && hdg > 180) {
+        hdg = ((az + 360) * c) + (hdg * (1 - c));
+    } else if (az > recip && az > hdg && hdg <= 180){
+        hdg = ((az - 360) * c) + (hdg * (1 - c));
+    } else {
+        hdg = (az * c) + (hdg * (1 - c));
+    }
 }
 
 double  FGAIBallistic::getTgtXOffset() const {
@@ -541,6 +541,7 @@ double  FGAIBallistic::getTgtZOffset() const {
 
 void FGAIBallistic::setTgtXOffset(double x){
     _tgt_x_offset = x;
+    cout <<"setTgtXOffset " <<_tgt_x_offset << endl;
 }
 
 void FGAIBallistic::setTgtYOffset(double y){
@@ -572,15 +573,15 @@ void FGAIBallistic::Run(double dt) {
     _life_timer += dt;
 
     // if life = -1 the object does not die
-       if (_life_timer > life && life != -1){
+    if (_life_timer > life && life != -1){
 
-               if (_report_expiry && !_expiry_reported){
-                       //cout<<"AIBallistic: expiry"<< endl;
-                       handle_expiry();
-               } else
-                       setDie(true);
+        if (_report_expiry && !_expiry_reported){
+            //cout<<"AIBallistic: expiry"<< endl;
+            handle_expiry();
+        } else
+            setDie(true);
 
-       }
+    }
 
     //set the contents in the appropriate tank or other property in the parent to zero
     setContents(0);
@@ -644,7 +645,7 @@ void FGAIBallistic::Run(double dt) {
     //calculate velocity due to external force
     double force_speed_north_deg_sec = 0;
     double force_speed_east_deg_sec = 0;
-//    double vs_force_fps = 0;
+    //    double vs_force_fps = 0;
     double hs_force_fps = 0;
     double v_force_acc_fpss = 0;
     double force_speed_north_fps = 0;
@@ -660,13 +661,13 @@ void FGAIBallistic::Run(double dt) {
     double friction_force_speed_east_deg_sec = 0;
     double force_elevation_deg = 0;
 
-       if (_external_force) {
+    if (_external_force) {
 
         SGPropertyNode *n = fgGetNode(_force_path.c_str(), true);
         double force_lbs            = n->getChild("force-lb", 0, true)->getDoubleValue();
         force_elevation_deg         = n->getChild("force-elevation-deg", 0, true)->getDoubleValue();
         double force_azimuth_deg    = n->getChild("force-azimuth-deg", 0, true)->getDoubleValue();
-               
+
         //resolve force into vertical and horizontal components:
         double v_force_lbs = force_lbs * sin( force_elevation_deg * SG_DEGREES_TO_RADIANS );
         h_force_lbs = force_lbs * cos( force_elevation_deg * SG_DEGREES_TO_RADIANS );
@@ -795,10 +796,10 @@ void FGAIBallistic::Run(double dt) {
     if (_azimuth < 0)
         _azimuth += 360;
 
-       //cout << "_azimuth " << _azimuth << " hdg "<<  hdg << endl;
+    //cout << "_azimuth " << _azimuth << " hdg "<<  hdg << endl;
 
     if (_aero_stabilised) { // we simulate rotational moment of inertia by using a filter
-               //cout<< "_aero_stabilised "<< endl;
+        //cout<< "_aero_stabilised "<< endl;
         const double coeff = 0.9;
 
         // we assume a symetrical MI about the pitch and yaw axis
@@ -806,8 +807,8 @@ void FGAIBallistic::Run(double dt) {
         setHdg(_azimuth, dt, coeff);
     } else if (_force_stabilised) { // we simulate rotational moment of inertia by using a filter
         //cout<< "_force_stabilised "<< endl;
-               
-               const double coeff = 0.9;
+
+        const double coeff = 0.9;
         double ratio = h_force_lbs/(_mass * slugs_to_lbs);
 
         if (ratio >  1) ratio =  1;
@@ -859,23 +860,23 @@ void FGAIBallistic::handle_impact() {
 }
 
 void FGAIBallistic::handle_expiry() {
-       
-               SG_LOG(SG_GENERAL, SG_DEBUG, "AIBallistic: handle_expiry " << pos.getElevationM());
 
-        report_impact(pos.getElevationM());
-        _expiry_reported = true;
+    SG_LOG(SG_GENERAL, SG_DEBUG, "AIBallistic: handle_expiry " << pos.getElevationM());
+
+    report_impact(pos.getElevationM());
+    _expiry_reported = true;
+
+    //if (life == -1){
+    //    invisible = true;
+    //} else if (_subID == 0)  // kill the AIObject if there is no subsubmodel
+    //    setDie(true);
 
-        //if (life == -1){
-        //    invisible = true;
-        //} else if (_subID == 0)  // kill the AIObject if there is no subsubmodel
-        //    setDie(true);
-   
 }
 
 void FGAIBallistic::handle_collision()
 {
     const FGAIBase *object = manager->calcCollision(pos.getElevationFt(),
-            pos.getLatitudeDeg(),pos.getLongitudeDeg(), _fuse_range);
+        pos.getLatitudeDeg(),pos.getLongitudeDeg(), _fuse_range);
 
     if (object) {
         SG_LOG(SG_GENERAL, SG_DEBUG, "AIBallistic: object hit");
index d143296a18f04b8f931701721924fb4bf5634fd8..460ccc2e063cd47c0cbe9133786908b71663cf44 100644 (file)
@@ -154,6 +154,9 @@ void FGAIBase::readFromScenario(SGPropertyNode* scFileNode)
     SGPropertyNode* submodels = scFileNode->getChild("submodels");
 
     if (submodels) {
+        //cout << "IN submodels path  " << submodels->getStringValue("path")
+        //    << "IN serviceable " << submodels->getBoolValue("serviceable")
+        //    << endl;
         setServiceable(submodels->getBoolValue("serviceable", false));
         setSMPath(submodels->getStringValue("path", ""));
     }
@@ -227,14 +230,17 @@ bool FGAIBase::init(bool search_in_AI_path) {
 void FGAIBase::initModel(osg::Node *node)
 {
     if (model.valid()) {
-
+        if( _path != ""){
+            props->setStringValue("submodels/path", _path.c_str());
+            //props->setStringValue("submodel/path", _path.c_str());
+            SG_LOG(SG_INPUT, SG_ALERT, "AIBase: submodels/path " << _path);
+        }
         fgSetString("/ai/models/model-added", props->getPath().c_str());
-
     } else if (!model_path.empty()) {
         SG_LOG(SG_INPUT, SG_WARN, "AIBase: Could not load model " << model_path);
     }
 
-    props->setStringValue("submodels/path", _path.c_str());
+    //props->setStringValue("submodels/path", _path.c_str());
     setDie(false);
 }
 
@@ -533,7 +539,7 @@ double FGAIBase::_getLatitude() const {
     return pos.getLatitudeDeg();
 }
 
-double FGAIBase::_getElevationFt () const {
+double FGAIBase::_getElevationFt() const {
     return pos.getElevationFt();
 }
 
index e47f778d0ce20426816b5eecaf75fabb87fa4a62..68127fe4de3a23b18c1078fc2f61d1728bb9189e 100644 (file)
@@ -44,9 +44,9 @@ class FGAIBase : public SGReferenced {
 
 public:
     enum object_type { otNull = 0, otAircraft, otShip, otCarrier, otBallistic,
-                       otRocket, otStorm, otThermal, otStatic, otWingman, otGroundVehicle,
-                       otEscort, otMultiplayer,
-                       MAX_OBJECTS };  // Needs to be last!!!
+        otRocket, otStorm, otThermal, otStatic, otWingman, otGroundVehicle,
+        otEscort, otMultiplayer,
+        MAX_OBJECTS }; // Needs to be last!!!
 
     FGAIBase(object_type ot);
     virtual ~FGAIBase();
@@ -95,7 +95,7 @@ public:
     SGVec3d getCartPos() const;
 
     bool getGroundElevationM(const SGGeod& pos, double& elev,
-                             const SGMaterial** material) const;
+        const SGMaterial** material) const;
 
     double _getCartPosX() const;
     double _getCartPosY() const;
@@ -177,7 +177,7 @@ protected:
 
     bool _impact_reported;
     bool _collision_reported;
-       bool _expiry_reported;
+    bool _expiry_reported;
 
     double _impact_lat;
     double _impact_lon;
@@ -247,7 +247,7 @@ public:
     bool   _getImpact();
     bool   _getImpactData();
     bool   _getCollisionData();
-       bool   _getExpiryData();
+    bool   _getExpiryData();
 
     SGPropertyNode* _getProps() const;
 
@@ -274,8 +274,8 @@ public:
     inline double _getBearing() { return bearing; };
 
     virtual osg::Node* load3DModel(const string &path,
-                           SGPropertyNode *prop_root);
+        SGPropertyNode *prop_root);
+
     static bool _isNight();
 };
 
@@ -289,6 +289,7 @@ inline void FGAIBase::setPath(const char* model ) {
 }
 
 inline void FGAIBase::setSMPath(const string& p) {
+    cout << "setSMPath " << p <<endl;
     _path = p;
 }
 
@@ -335,6 +336,8 @@ inline void FGAIBase::setCallSign(const string& s) {
 }
 inline void FGAIBase::setXoffset(double x) {
     _x_offset = x;
+    cout << "setXoffset " << _x_offset << endl;
+
 }
 
 inline void FGAIBase::setYoffset(double y) {
index bde684941ef443f1f0e90851e96bcbc8fe14a911..e65ea5b7ee7d6eba8326b165c7407211598080c7 100644 (file)
@@ -316,7 +316,7 @@ bool FGAIGroundVehicle::getPitch() {
             //cout << "new waypoint, calculating pitch " << endl;
             curr_alt = curr->altitude;
             prev_alt = prev->altitude;
-            cout << "prev_alt" <<prev_alt << endl;
+            //cout << "prev_alt" <<prev_alt << endl;
             d_alt = (curr_alt - prev_alt) * SG_METER_TO_FEET;
             //_elevation = prev->altitude;
             distance = SGGeodesy::distanceM(SGGeod::fromDeg(prev->longitude, prev->latitude),
index 4a081ee116e64b9af26e97d1945da4a10dd886a1..82874017be54461883d0d17791d5857f0833d1f2 100644 (file)
@@ -42,7 +42,7 @@ void FGAIWingman::readFromScenario(SGPropertyNode* scFileNode) {
     setLife(scFileNode->getDoubleValue("life", -1));
     setNoRoll(scFileNode->getBoolValue("no-roll", false));
     setName(scFileNode->getStringValue("name", "Wingman"));
-    setSMPath(scFileNode->getStringValue("submodel-path", ""));
+    //setSMPath(scFileNode->getStringValue("submodel-path", ""));
     setSubID(scFileNode->getIntValue("SubID", 0));
     setXoffset(scFileNode->getDoubleValue("x-offset", 0.0));
     setYoffset(scFileNode->getDoubleValue("y-offset", 0.0));
@@ -57,6 +57,28 @@ void FGAIWingman::readFromScenario(SGPropertyNode* scFileNode) {
 void FGAIWingman::bind() {
     FGAIBallistic::bind();
 
+    props->tie("id", SGRawValueMethods<FGAIBase,int>(*this,
+        &FGAIBase::getID));
+    props->tie("subID", SGRawValueMethods<FGAIBase,int>(*this,
+        &FGAIBase::_getSubID));
+    props->tie("position/altitude-ft",
+        SGRawValueMethods<FGAIBase,double>(*this,
+        &FGAIBase::_getElevationFt,
+        &FGAIBase::_setAltitude));
+    props->tie("position/latitude-deg",
+        SGRawValueMethods<FGAIBase,double>(*this,
+        &FGAIBase::_getLatitude,
+        &FGAIBase::_setLatitude));
+    props->tie("position/longitude-deg",
+        SGRawValueMethods<FGAIBase,double>(*this,
+        &FGAIBase::_getLongitude,
+        &FGAIBase::_setLongitude));
+
+    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("load/rel-brg-to-user-deg",
         SGRawValueMethods<FGAIBallistic,double>
         (*this, &FGAIBallistic::getRelBrgHitchToUser));
@@ -64,7 +86,7 @@ void FGAIWingman::bind() {
         SGRawValueMethods<FGAIBallistic,double>
         (*this, &FGAIBallistic::getElevHitchToUser));
     props->tie("velocities/vertical-speed-fps",
-        SGRawValuePointer<double>(&vs));  
+        SGRawValuePointer<double>(&vs));
     props->tie("position/x-offset", 
         SGRawValueMethods<FGAIBase,double>(*this, &FGAIBase::_getXOffset, &FGAIBase::setXoffset));
     props->tie("position/y-offset", 
@@ -72,16 +94,27 @@ void FGAIWingman::bind() {
     props->tie("position/z-offset", 
         SGRawValueMethods<FGAIBase,double>(*this, &FGAIBase::_getZOffset, &FGAIBase::setZoffset));
     props->tie("position/tgt-x-offset", 
-        SGRawValueMethods<FGAIWingman,double>(*this, &FGAIWingman::getTgtXOffset, &FGAIWingman::setTgtXOffset));
+        SGRawValueMethods<FGAIBallistic,double>(*this, &FGAIBallistic::getTgtXOffset, &FGAIBallistic::setTgtXOffset));
     props->tie("position/tgt-y-offset", 
-        SGRawValueMethods<FGAIWingman,double>(*this, &FGAIWingman::getTgtYOffset, &FGAIWingman::setTgtYOffset));
+        SGRawValueMethods<FGAIBallistic,double>(*this, &FGAIBallistic::getTgtYOffset, &FGAIBallistic::setTgtYOffset));
     props->tie("position/tgt-z-offset", 
-        SGRawValueMethods<FGAIWingman,double>(*this, &FGAIWingman::getTgtZOffset, &FGAIWingman::setTgtZOffset));
+        SGRawValueMethods<FGAIBallistic,double>(*this, &FGAIBallistic::getTgtZOffset, &FGAIBallistic::setTgtZOffset));
 }
 
 void FGAIWingman::unbind() {
     FGAIBallistic::unbind();
 
+    props->untie("id");
+    props->untie("SubID");
+
+    props->untie("position/altitude-ft");
+    props->untie("position/latitude-deg");
+    props->untie("position/longitude-deg");
+
+    props->untie("orientation/pitch-deg");
+    props->untie("orientation/roll-deg");
+    props->untie("orientation/true-heading-deg");
+
     props->untie("load/rel-brg-to-user-deg");
     props->untie("load/elev-to-user-deg");
     props->untie("velocities/vertical-speed-fps");
index 0958923c1bae9af9dc89a31a24109dcc0f03aa9f..733bff3cb3130c62cc8828be0cd3d1055f689843 100644 (file)
@@ -37,7 +37,7 @@ FGSubmodelMgr::FGSubmodelMgr()
     string contents_node;
     contrail_altitude = 30000;
     _count = 0;
-       _found_sub = true;
+    _found_sub = true;
 }
 
 FGSubmodelMgr::~FGSubmodelMgr()
@@ -78,16 +78,23 @@ void FGSubmodelMgr::init()
     ai = (FGAIManager*)globals->get_subsystem("ai_model");
 
     load();
+
+//    _model_added_node = fgGetNode("ai/models/model-added", true);
+    //_model_added_node->addChangeListener(this, false);
+
 }
 
 void FGSubmodelMgr::postinit() {
     // postinit, so that the AI list is populated
     loadAI();
 
-       while (_found_sub)
-               loadSubmodels();
+    while (_found_sub)
+        loadSubmodels();
 
     //TODO reload submodels if an MP ac joins
+
+    _model_added_node = fgGetNode("ai/models/model-added", true);
+    _model_added_node->addChangeListener(this, false);
 }
 
 void FGSubmodelMgr::bind()
@@ -109,7 +116,7 @@ void FGSubmodelMgr::update(double dt)
 
     _impact = false;
     _hit = false;
-       _expiry = false;
+    _expiry = false;
 
     // check if the submodel hit an object or terrain
     sm_list = ai->get_ai_list();
@@ -119,7 +126,8 @@ void FGSubmodelMgr::update(double dt)
     for (; sm_list_itr != end; ++sm_list_itr) {
         _impact = (*sm_list_itr)->_getImpactData();
         _hit = (*sm_list_itr)->_getCollisionData();
-               _expiry = (*sm_list_itr)->_getExpiryData();
+        _expiry = (*sm_list_itr)->_getExpiryData();
+
         int parent_subID = (*sm_list_itr)->_getSubID();
 
         //SG_LOG(SG_GENERAL, SG_DEBUG, "Submodel: Impact " << _impact << " hit! "
@@ -130,7 +138,7 @@ void FGSubmodelMgr::update(double dt)
 
         if (_impact || _hit || _expiry) {
     //        SG_LOG(SG_GENERAL, SG_ALERT, "Submodel: Impact " << _impact << " hit! " << _hit 
-                               //<< " exipiry :-( " << _expiry );
+                //<< " exipiry :-( " << _expiry );
 
             submodel_iterator = submodels.begin();
 
@@ -147,9 +155,9 @@ void FGSubmodelMgr::update(double dt)
                     _parent_roll = (*sm_list_itr)->_getImpactRoll();
                     _parent_speed = (*sm_list_itr)->_getImpactSpeed();
                     (*submodel_iterator)->first_time = true;
-                                       //cout << "Impact: parent SubID = child_ID elev " << _parent_elev << endl;
+                    //cout << "Impact: parent SubID = child_ID elev " << _parent_elev << endl;
 
-                                       if (release(*submodel_iterator, dt))
+                    if (release(*submodel_iterator, dt))
                         (*sm_list_itr)->setDie(true);
 
                 }
@@ -162,19 +170,18 @@ void FGSubmodelMgr::update(double dt)
     _contrail_trigger->setBoolValue(_user_alt_node->getDoubleValue() > contrail_altitude);
 
 
-    bool in_range = true;
+//    bool in_range = true;
     bool trigger = false;
     int i = -1;
 
     submodel_iterator = submodels.begin();
     while (submodel_iterator != submodels.end())  {
         i++;
-        in_range = true;
 
         /*SG_LOG(SG_GENERAL, SG_DEBUG,
                 "Submodels:  " << (*submodel_iterator)->id
                 << " name " << (*submodel_iterator)->name
-                << " in range " << in_range);*/
+                );*/
 
         if ((*submodel_iterator)->trigger_node != 0) {
             _trigger_node = (*submodel_iterator)->trigger_node;
@@ -185,20 +192,20 @@ void FGSubmodelMgr::update(double dt)
             //cout << (*submodel_iterator)->name << "trigger node not found " << trigger << endl;
         }
 
-               if (trigger && (*submodel_iterator)->count != 0) {
+        if (trigger && (*submodel_iterator)->count != 0) {
 
-                       int id = (*submodel_iterator)->id;
-                       string name = (*submodel_iterator)->name;
-                       
-                       /*SG_LOG(SG_GENERAL, SG_DEBUG,
-                       "Submodels end:  " << (*submodel_iterator)->id
-                       << " name " << (*submodel_iterator)->name
-                       << " count " << (*submodel_iterator)->count
-                       << " in range " << in_range);*/
+            int id = (*submodel_iterator)->id;
+            string name = (*submodel_iterator)->name;
+            
+            SG_LOG(SG_GENERAL, SG_DEBUG,
+            "Submodels release:  " << (*submodel_iterator)->id
+            << " name " << (*submodel_iterator)->name
+            << " count " << (*submodel_iterator)->count
+            );
 
-                       release(*submodel_iterator, dt);
-               } else
-                       (*submodel_iterator)->first_time = true;
+            release(*submodel_iterator, dt);
+        } else
+            (*submodel_iterator)->first_time = true;
 
         ++submodel_iterator;
     } // end while
@@ -222,8 +229,8 @@ bool FGSubmodelMgr::release(submodel *sm, double dt)
         //cout << "not yet: timer " << sm->timer << " delay " << sm->delay << endl;
         return false;
     }
-       
-       //cout << "released timer: " << sm->timer << " delay " << sm->delay << endl;
+    
+    //cout << "released timer: " << sm->timer << " delay " << sm->delay << endl;
 
     sm->timer = 0.0;
 
@@ -237,11 +244,11 @@ bool FGSubmodelMgr::release(submodel *sm, double dt)
     FGAIBallistic* ballist = new FGAIBallistic;
     ballist->setPath(sm->model.c_str());
     ballist->setName(sm->name);
-       ballist->setRandom(sm->random);
-       ballist->setRandomness(sm->randomness);
-       ballist->setLatitude(offsetpos.getLatitudeDeg());
-       ballist->setLongitude(offsetpos.getLongitudeDeg());
-       ballist->setAltitude(offsetpos.getElevationFt());
+    ballist->setRandom(sm->random);
+    ballist->setRandomness(sm->randomness);
+    ballist->setLatitude(offsetpos.getLatitudeDeg());
+    ballist->setLongitude(offsetpos.getLongitudeDeg());
+    ballist->setAltitude(offsetpos.getElevationFt());
     ballist->setAzimuth(IC.azimuth);
     ballist->setElevation(IC.elevation);
     ballist->setRoll(IC.roll);
@@ -257,7 +264,7 @@ bool FGSubmodelMgr::release(submodel *sm, double dt)
     ballist->setStabilisation(sm->aero_stabilised);
     ballist->setNoRoll(sm->no_roll);
     ballist->setCollision(sm->collision);
-       ballist->setExpiry(sm->expiry);
+    ballist->setExpiry(sm->expiry);
     ballist->setImpact(sm->impact);
     ballist->setImpactReportNode(sm->impact_report);
     ballist->setFuseRange(sm->fuse_range);
@@ -309,12 +316,12 @@ void FGSubmodelMgr::transform(submodel *sm)
         sm->speed = sm->speed_node->getDoubleValue();
 
     int id = sm->id;
-    //int sub_id = (*submodel)->sub_id;
+    int sub_id = sm->sub_id;
     string name = sm->name;
 
     //cout << " name " << name << " id " << id << " sub id" << sub_id << endl;
 
-       // set the Initial Conditions for the types of submodel parent 
+    // set the Initial Conditions for the types of submodel parent 
 
     if (_impact || _hit || _expiry) {
         // set the data for a submodel tied to a submodel
@@ -347,6 +354,7 @@ void FGSubmodelMgr::transform(submodel *sm)
 
     } else {
         // set the data for a submodel tied to an AI Object
+        //cout << " set the data for a submodel tied to an AI Object " << id << endl;
         sm_list_iterator sm_list_itr = sm_list.begin();
         sm_list_iterator end = sm_list.end();
 
@@ -358,19 +366,20 @@ void FGSubmodelMgr::transform(submodel *sm)
                 continue;
             }
 
-            //cout << "found id " << id << endl;
+            //cout << " AI found id " << id <<  " alt " << (*sm_list_itr)->_getElevationFt()<< endl;
             IC.lat             = (*sm_list_itr)->_getLatitude();
             IC.lon             = (*sm_list_itr)->_getLongitude();
-            IC.alt             = (*sm_list_itr)->_getAltitude();
+            IC.alt             = (*sm_list_itr)->_getElevationFt();
             IC.roll            = (*sm_list_itr)->_getRoll();
             IC.elevation       = (*sm_list_itr)->_getPitch();
             IC.azimuth         = (*sm_list_itr)->_getHeading();
-            IC.alt             = (*sm_list_itr)->_getAltitude();
             IC.speed           = (*sm_list_itr)->_getSpeed() * SG_KT_TO_FPS;
             IC.speed_down_fps  = -(*sm_list_itr)->_getVS_fps();
             IC.speed_east_fps  = (*sm_list_itr)->_get_speed_east_fps();
             IC.speed_north_fps = (*sm_list_itr)->_get_speed_north_fps();
 
+            break;
+
             ++sm_list_itr;
         }
     }
@@ -381,22 +390,22 @@ void FGSubmodelMgr::transform(submodel *sm)
     cout << "speed north " << IC.speed_north_fps << endl ;
     cout << "parent speed fps in" << IC.speed << "sm speed in " << sm->speed << endl ;*/
 
-       // Set the Initial Conditions that are common to all types of parent
+    // Set the Initial Conditions that are common to all types of parent
     IC.wind_from_east =  _user_wind_from_east_node->getDoubleValue();
     IC.wind_from_north = _user_wind_from_north_node->getDoubleValue();
 
-       userpos.setLatitudeDeg(IC.lat);
-       userpos.setLongitudeDeg(IC.lon);
-       userpos.setElevationFt(IC.alt);
+    userpos.setLatitudeDeg(IC.lat);
+    userpos.setLongitudeDeg(IC.lon);
+    userpos.setElevationFt(IC.alt);
 
     _x_offset = sm->x_offset;
     _y_offset = sm->y_offset;
     _z_offset = sm->z_offset;
 
-       setOffsetPos();
+    setOffsetPos();
 
-       //IC.elevation += sm->pitch_offset;
-       //IC.azimuth   += sm->yaw_offset ;
+    //IC.elevation += sm->pitch_offset;
+    //IC.azimuth   += sm->yaw_offset ;
 
     // pre-process the trig functions
     cosRx = cos(-IC.roll * SG_DEGREES_TO_RADIANS);
@@ -460,7 +469,7 @@ void FGSubmodelMgr::loadAI()
     sm_list = ai->get_ai_list();
 
     if (sm_list.empty()) {
-        SG_LOG(SG_GENERAL, SG_DEBUG, "Submodels: Unable to read AI submodel list");
+        SG_LOG(SG_GENERAL, SG_ALERT, "Submodels: Unable to read AI submodel list");
         return;
     }
 
@@ -476,7 +485,11 @@ void FGSubmodelMgr::loadAI()
         }
 
         int id = (*sm_list_itr)->getID();
+        string type = (*sm_list_itr)->getTypeString();
         bool serviceable = (*sm_list_itr)->_getServiceable();
+
+        //cout << "loadAI: type " << type << " path "<< path << " serviceable " << serviceable << endl;
+
         setData(id, path, serviceable);
         ++sm_list_itr;
     }
@@ -490,13 +503,13 @@ void FGSubmodelMgr::setData(int id, string& path, bool serviceable)
 
     SGPath config(globals->get_fg_root());
     config.append(path);
-    SG_LOG(SG_GENERAL, SG_DEBUG, "Submodels: path " << path);
+    SG_LOG(SG_GENERAL, SG_DEBUG, "setData: path " << path);
     try {
         SG_LOG(SG_GENERAL, SG_DEBUG,
                 "Submodels: Trying to read AI submodels file: " << config.str());
         readProperties(config.str(), &root);
     } catch (const sg_exception &) {
-        SG_LOG(SG_GENERAL, SG_DEBUG,
+        SG_LOG(SG_GENERAL, SG_ALERT,
                 "Submodels: Unable to read AI submodels file: " << config.str());
         return;
     }
@@ -530,18 +543,18 @@ void FGSubmodelMgr::setData(int id, string& path, bool serviceable)
         sm->aero_stabilised = entry_node->getBoolValue("aero-stabilised", true);
         sm->no_roll         = entry_node->getBoolValue("no-roll", false);
         sm->collision       = entry_node->getBoolValue("collision", false);
-               sm->expiry                      = entry_node->getBoolValue("expiry", false);
+        sm->expiry                     = entry_node->getBoolValue("expiry", false);
         sm->impact          = entry_node->getBoolValue("impact", false);
         sm->impact_report   = entry_node->getStringValue("impact-reports");
         sm->fuse_range      = entry_node->getDoubleValue("fuse-range", 0.0);
         sm->contents_node   = fgGetNode(entry_node->getStringValue("contents", "none"), false);
-        sm->speed_node      = fgGetNode(entry_node->getStringValue("speed-node", "none"), false);
+        sm->speed_node      = fgGetNode(entry_node->getStringValue("speed-prop", "none"), false);
         sm->submodel        = entry_node->getStringValue("submodel-path", "");
         sm->force_stabilised= entry_node->getBoolValue("force-stabilised", false);
         sm->ext_force       = entry_node->getBoolValue("external-force", false);
         sm->force_path      = entry_node->getStringValue("force-path", "");
-               sm->random                      = entry_node->getBoolValue("random", false);
-               sm->randomness          = entry_node->getDoubleValue("randomness", 0.5);
+        sm->random                     = entry_node->getBoolValue("random", false);
+        sm->randomness         = entry_node->getDoubleValue("randomness", 0.5);
 
 
         //cout <<  "sm->contents_node " << sm->contents_node << endl;
@@ -566,7 +579,7 @@ void FGSubmodelMgr::setData(int id, string& path, bool serviceable)
         sm->sub_id = 0;
 
         sm->prop = fgGetNode("/ai/submodels/submodel", index, true);
-               sm->prop->tie("delay", SGRawValuePointer<double>(&(sm->delay)));
+        sm->prop->tie("delay", SGRawValuePointer<double>(&(sm->delay)));
         sm->prop->tie("count", SGRawValuePointer<int>(&(sm->count)));
         sm->prop->tie("repeat", SGRawValuePointer<bool>(&(sm->repeat)));
         sm->prop->tie("id", SGRawValuePointer<int>(&(sm->id)));
@@ -598,10 +611,10 @@ void FGSubmodelMgr::setSubData(int id, string& path, bool serviceable)
 
     SGPath config(globals->get_fg_root());
     config.append(path);
-    SG_LOG(SG_GENERAL, SG_DEBUG,
-        "Submodels: path " << path);
+    SG_LOG(SG_GENERAL, SG_ALERT, "setSubData: path " << path);
+
     try {
-        SG_LOG(SG_GENERAL, SG_DEBUG,
+        SG_LOG(SG_GENERAL, SG_ALERT,
                 "Submodels: Trying to read AI submodels file: " << config.str());
         readProperties(config.str(), &root);
 
@@ -640,18 +653,18 @@ void FGSubmodelMgr::setSubData(int id, string& path, bool serviceable)
         sm->aero_stabilised = entry_node->getBoolValue("aero-stabilised", true);
         sm->no_roll         = entry_node->getBoolValue("no-roll", false);
         sm->collision       = entry_node->getBoolValue("collision", false);
-               sm->expiry                      = entry_node->getBoolValue("expiry", false);
+        sm->expiry          = entry_node->getBoolValue("expiry", false);
         sm->impact          = entry_node->getBoolValue("impact", false);
         sm->impact_report   = entry_node->getStringValue("impact-reports");
         sm->fuse_range      = entry_node->getDoubleValue("fuse-range", 0.0);
         sm->contents_node   = fgGetNode(entry_node->getStringValue("contents", "none"), false);
-        sm->speed_node      = fgGetNode(entry_node->getStringValue("speed-node", "none"), false);
+        sm->speed_node      = fgGetNode(entry_node->getStringValue("speed-prop", "none"), false);
         sm->submodel        = entry_node->getStringValue("submodel-path", "");
-               sm->force_stabilised= entry_node->getBoolValue("force-stabilised", false);
+        sm->force_stabilised= entry_node->getBoolValue("force-stabilised", false);
         sm->ext_force       = entry_node->getBoolValue("external-force", false);
         sm->force_path      = entry_node->getStringValue("force-path", "");
-               sm->random                      = entry_node->getBoolValue("random", false);
-               sm->randomness          = entry_node->getDoubleValue("randomness", 0.5);
+        sm->random          = entry_node->getBoolValue("random", false);
+        sm->randomness      = entry_node->getDoubleValue("randomness", 0.5);
 
         //cout <<  "sm->contents_node " << sm->contents_node << endl;
         if (sm->contents_node != 0)
@@ -680,7 +693,7 @@ void FGSubmodelMgr::setSubData(int id, string& path, bool serviceable)
         sm->prop->tie("id", SGRawValuePointer<int>(&(sm->id)));
         sm->prop->tie("sub-id", SGRawValuePointer<int>(&(sm->sub_id)));
         sm->prop->tie("serviceable", SGRawValuePointer<bool>(&(sm->serviceable)));
-               sm->prop->tie("random", SGRawValuePointer<bool>(&(sm->random)));
+        sm->prop->tie("random", SGRawValuePointer<bool>(&(sm->random)));
         string name = sm->name;
         sm->prop->setStringValue("name", name.c_str());
 
@@ -704,29 +717,29 @@ void FGSubmodelMgr::loadSubmodels()
 {
     SG_LOG(SG_GENERAL, SG_DEBUG, "Submodels: Loading sub submodels");
 
-       _found_sub = false;
+    _found_sub = false;
 
     submodel_iterator = submodels.begin();
 
-       while (submodel_iterator != submodels.end()) {
-               string submodel  = (*submodel_iterator)->submodel;
-               if (!submodel.empty()) {
-                       //int id = (*submodel_iterator)->id;
-                       bool serviceable = true;
-                       //SG_LOG(SG_GENERAL, SG_DEBUG, "found path sub sub "
-                       //        << submodel
-                       //        << " index " << index
-                       //        << "name " << (*submodel_iterator)->name);
-
-                       if ((*submodel_iterator)->sub_id == 0){
-                               (*submodel_iterator)->sub_id = index;
-                               _found_sub = true;
-                               setSubData(index, submodel, serviceable);
-                       }
-               }
-
-               ++submodel_iterator;
-       } // end while
+    while (submodel_iterator != submodels.end()) {
+        string submodel  = (*submodel_iterator)->submodel;
+        if (!submodel.empty()) {
+            //int id = (*submodel_iterator)->id;
+            bool serviceable = true;
+            //SG_LOG(SG_GENERAL, SG_DEBUG, "found path sub sub "
+            //        << submodel
+            //        << " index " << index
+            //        << "name " << (*submodel_iterator)->name);
+
+            if ((*submodel_iterator)->sub_id == 0){
+                (*submodel_iterator)->sub_id = index;
+                _found_sub = true;
+                setSubData(index, submodel, serviceable);
+            }
+        }
+
+        ++submodel_iterator;
+    } // end while
 
     subsubmodel_iterator = subsubmodels.begin();
 
@@ -735,7 +748,7 @@ void FGSubmodelMgr::loadSubmodels()
         ++subsubmodel_iterator;
     } // end while
 
-       subsubmodels.clear();
+    subsubmodels.clear();
 
     //submodel_iterator = submodels.begin();
 
@@ -760,7 +773,7 @@ SGVec3d FGSubmodelMgr::getCartOffsetPos() const{
     // in the simulation usual body x-forward, y-right, z-down coordinates
     // (meters) )
 
-       SGVec3d _off(_x_offset * SG_FEET_TO_METER,
+    SGVec3d _off(_x_offset * SG_FEET_TO_METER,
         _y_offset * SG_FEET_TO_METER,
         -_z_offset * SG_FEET_TO_METER);
 
@@ -789,5 +802,60 @@ void FGSubmodelMgr::setOffsetPos(){
     SGVec3d cartoffsetPos = getCartOffsetPos();
 
     SGGeodesy::SGCartToGeod(cartoffsetPos, offsetpos);
+}
+
+void FGSubmodelMgr::valueChanged(SGPropertyNode *prop)
+{
+
+    const char* _model_added = _model_added_node->getStringValue();
+
+    basic_string <char>::size_type indexCh2b;
+
+    string str2 = _model_added;
+    const char *cstr2b = "ballistic";
+    indexCh2b = str2.find( cstr2b, 0 );
+
+    if (indexCh2b != string::npos ){        // we will ignore Ballistic Objects - there are potentially too many 
+        return;
+    } else {
+        //cout << "model added - " << str2 <<" now do something "<< endl;
+
+        SGPropertyNode *a_node = fgGetNode(_model_added, true );
+        SGPropertyNode *sub_node = a_node->getChild("submodels", 0, true);
+        SGPropertyNode_ptr path_node = sub_node->getChild("path", 0, true);
+
+        string path = path_node->getStringValue();
+
+        if (path.empty()){
+            // nothing to do - return
+            //cout << "subpath empty - return"  << endl << endl;
+            return;
+        } else {
+            //cout << "subpath not empty: " << path << endl << endl;
+            SGPropertyNode_ptr ident_node = a_node->getChild("id", 0, true);
+            int id = ident_node->getIntValue();
+
+            setData(id, path, true);
+
+            _found_sub = true;
+
+            while (_found_sub)
+                loadSubmodels();
+
+        }
+
+
+
+
+    }
+
+
+
+
+
+
+
+
+
 }
 // end of submodel.cxx
index cd645f64e66d4e9333b4518123b06f821eefea24..95e62f6b74b3dabca98f99995bdfb40d2d97565a 100644 (file)
@@ -25,7 +25,7 @@ using std::list;
 
 class FGAIBase;
 
-class FGSubmodelMgr : public SGSubsystem
+class FGSubmodelMgr : public SGSubsystem, public SGPropertyChangeListener
 {
 
 public:
@@ -53,7 +53,7 @@ public:
         double             drag_area;
         double             life;
         double             buoyancy;
-               double                     randomness;
+        double             randomness;
         bool               wind;
         bool               first_time;
         double             cd;
@@ -63,9 +63,9 @@ public:
         int                id;
         bool               no_roll;
         bool               serviceable;
-               bool               random;
+        bool               random;
         bool               collision;
-               bool                       expiry;
+        bool               expiry;
         bool               impact;
         string             impact_report;
         double             fuse_range;
@@ -144,7 +144,7 @@ private:
     double _parent_pitch;
     double _parent_roll;
     double _parent_speed;
-       double _x_offset;
+    double _x_offset;
     double _y_offset;
     double _z_offset;
 
@@ -155,8 +155,8 @@ private:
 
     bool _impact;
     bool _hit;
-       bool _expiry;
-       bool _found_sub;
+    bool _expiry;
+    bool _found_sub;
 
     SGPropertyNode_ptr _serviceable_node;
     SGPropertyNode_ptr _user_lat_node;
@@ -178,6 +178,9 @@ private:
     SGPropertyNode_ptr _count_node;
     SGPropertyNode_ptr _trigger_node;
     SGPropertyNode_ptr props;
+    SGPropertyNode_ptr _model_added_node;
+    SGPropertyNode_ptr _path_node;
+
 
     FGAIManager* ai;
     IC_struct  IC;
@@ -201,11 +204,11 @@ private:
 
 
     int _count;
-       
-       SGGeod userpos;
-       SGGeod offsetpos;
-       SGVec3d getCartOffsetPos() const;
-       void setOffsetPos();
+
+    SGGeod userpos;
+    SGGeod offsetpos;
+    SGVec3d getCartOffsetPos() const;
+    void setOffsetPos();
 
 };
 
index 4a3fc96061ea8fb9be0e1a56c9df259ca5334c75..98184acf97112a3c9216b96051180e1ec5a0ff14 100644 (file)
@@ -297,19 +297,9 @@ FGEnvironmentMgr::update (double dt)
   osg::Vec3 windVec(_environment->get_wind_from_north_fps(),
                     -_environment->get_wind_from_east_fps(),
                     0);
-         // SG_LOG(SG_GENERAL, SG_ALERT, "-_environment->get_wind_from_north_mps() " <<
-                  //_environment->get_wind_from_north_fps() * SG_FEET_TO_METER
-                  //<< " -_environment->get_wind_from_east_mps() " 
-                  //<< -_environment->get_wind_from_east_fps() * SG_FEET_TO_METER
-                  //);
-
-  // simgear::Particles::setWindVector(windVec * SG_FEET_TO_METER);
-  simgear::Particles::setWindFrom( _environment->get_wind_from_heading_deg(),
-                                  _environment->get_wind_speed_kt() );
-  //double wind_true_deg = _environment->get_wind_from_heading_deg();
-  //simgear::Particles::setWindFrom( wind_true_deg,
-  //                                _environment->get_wind_speed_kt() );
-
+  simgear::Particles::setWindVector(windVec * SG_FEET_TO_METER);
+  //simgear::Particles::setWindFrom( _environment->get_wind_from_heading_deg(),
+  //                      _environment->get_wind_speed_kt() );
 }
 
 FGEnvironment