From: Vivian Meazza Date: Sat, 14 Aug 2010 12:39:30 +0000 (+0100) Subject: Add aubmodels to AI objects X-Git-Url: https://git.mxchange.org/?a=commitdiff_plain;h=72c5a314e6daa5052165310a600c4a9a4c20e43f;p=flightgear.git Add aubmodels to AI objects Signed-off-by: Vivian Meazza --- diff --git a/src/AIModel/AIBallistic.cxx b/src/AIModel/AIBallistic.cxx index 76e412c0c..e94844eaf 100644 --- a/src/AIModel/AIBallistic.cxx +++ b/src/AIModel/AIBallistic.cxx @@ -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(*this, &FGAIBallistic::getMass)); props->tie("material/load-resistance", - SGRawValuePointer(&_load_resistance)); + SGRawValuePointer(&_load_resistance)); props->tie("material/solid", - SGRawValuePointer(&_solid)); + SGRawValuePointer(&_solid)); props->tie("altitude-agl-ft", - SGRawValuePointer(&_ht_agl_ft)); + SGRawValuePointer(&_ht_agl_ft)); props->tie("controls/slave-to-ac", SGRawValueMethods (*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& 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"); diff --git a/src/AIModel/AIBase.cxx b/src/AIModel/AIBase.cxx index d143296a1..460ccc2e0 100644 --- a/src/AIModel/AIBase.cxx +++ b/src/AIModel/AIBase.cxx @@ -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(); } diff --git a/src/AIModel/AIBase.hxx b/src/AIModel/AIBase.hxx index e47f778d0..68127fe4d 100644 --- a/src/AIModel/AIBase.hxx +++ b/src/AIModel/AIBase.hxx @@ -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 <altitude; prev_alt = prev->altitude; - cout << "prev_alt" <altitude; distance = SGGeodesy::distanceM(SGGeod::fromDeg(prev->longitude, prev->latitude), diff --git a/src/AIModel/AIWingman.cxx b/src/AIModel/AIWingman.cxx index 4a081ee11..82874017b 100644 --- a/src/AIModel/AIWingman.cxx +++ b/src/AIModel/AIWingman.cxx @@ -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(*this, + &FGAIBase::getID)); + props->tie("subID", SGRawValueMethods(*this, + &FGAIBase::_getSubID)); + props->tie("position/altitude-ft", + SGRawValueMethods(*this, + &FGAIBase::_getElevationFt, + &FGAIBase::_setAltitude)); + props->tie("position/latitude-deg", + SGRawValueMethods(*this, + &FGAIBase::_getLatitude, + &FGAIBase::_setLatitude)); + props->tie("position/longitude-deg", + SGRawValueMethods(*this, + &FGAIBase::_getLongitude, + &FGAIBase::_setLongitude)); + + props->tie("orientation/pitch-deg", SGRawValuePointer(&pitch)); + props->tie("orientation/roll-deg", SGRawValuePointer(&roll)); + props->tie("orientation/true-heading-deg", SGRawValuePointer(&hdg)); + + props->tie("load/rel-brg-to-user-deg", SGRawValueMethods (*this, &FGAIBallistic::getRelBrgHitchToUser)); @@ -64,7 +86,7 @@ void FGAIWingman::bind() { SGRawValueMethods (*this, &FGAIBallistic::getElevHitchToUser)); props->tie("velocities/vertical-speed-fps", - SGRawValuePointer(&vs)); + SGRawValuePointer(&vs)); props->tie("position/x-offset", SGRawValueMethods(*this, &FGAIBase::_getXOffset, &FGAIBase::setXoffset)); props->tie("position/y-offset", @@ -72,16 +94,27 @@ void FGAIWingman::bind() { props->tie("position/z-offset", SGRawValueMethods(*this, &FGAIBase::_getZOffset, &FGAIBase::setZoffset)); props->tie("position/tgt-x-offset", - SGRawValueMethods(*this, &FGAIWingman::getTgtXOffset, &FGAIWingman::setTgtXOffset)); + SGRawValueMethods(*this, &FGAIBallistic::getTgtXOffset, &FGAIBallistic::setTgtXOffset)); props->tie("position/tgt-y-offset", - SGRawValueMethods(*this, &FGAIWingman::getTgtYOffset, &FGAIWingman::setTgtYOffset)); + SGRawValueMethods(*this, &FGAIBallistic::getTgtYOffset, &FGAIBallistic::setTgtYOffset)); props->tie("position/tgt-z-offset", - SGRawValueMethods(*this, &FGAIWingman::getTgtZOffset, &FGAIWingman::setTgtZOffset)); + SGRawValueMethods(*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"); diff --git a/src/AIModel/submodel.cxx b/src/AIModel/submodel.cxx index 0958923c1..733bff3cb 100644 --- a/src/AIModel/submodel.cxx +++ b/src/AIModel/submodel.cxx @@ -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(&(sm->delay))); + sm->prop->tie("delay", SGRawValuePointer(&(sm->delay))); sm->prop->tie("count", SGRawValuePointer(&(sm->count))); sm->prop->tie("repeat", SGRawValuePointer(&(sm->repeat))); sm->prop->tie("id", SGRawValuePointer(&(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(&(sm->id))); sm->prop->tie("sub-id", SGRawValuePointer(&(sm->sub_id))); sm->prop->tie("serviceable", SGRawValuePointer(&(sm->serviceable))); - sm->prop->tie("random", SGRawValuePointer(&(sm->random))); + sm->prop->tie("random", SGRawValuePointer(&(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 ::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 diff --git a/src/AIModel/submodel.hxx b/src/AIModel/submodel.hxx index cd645f64e..95e62f6b7 100644 --- a/src/AIModel/submodel.hxx +++ b/src/AIModel/submodel.hxx @@ -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(); }; diff --git a/src/Environment/environment_mgr.cxx b/src/Environment/environment_mgr.cxx index 4a3fc9606..98184acf9 100644 --- a/src/Environment/environment_mgr.cxx +++ b/src/Environment/environment_mgr.cxx @@ -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