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;
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));
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));
_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;
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;
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));
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) {
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) {
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) {
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();
}
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 {
void FGAIBallistic::setTgtXOffset(double x){
_tgt_x_offset = x;
+ cout <<"setTgtXOffset " <<_tgt_x_offset << endl;
}
void FGAIBallistic::setTgtYOffset(double y){
_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);
//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;
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 );
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
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;
}
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");
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", ""));
}
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);
}
return pos.getLatitudeDeg();
}
-double FGAIBase::_getElevationFt () const {
+double FGAIBase::_getElevationFt() const {
return pos.getElevationFt();
}
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();
SGVec3d getCartPos() const;
bool getGroundElevationM(const SGGeod& pos, double& elev,
- const SGMaterial** material) const;
+ const SGMaterial** material) const;
double _getCartPosX() const;
double _getCartPosY() const;
bool _impact_reported;
bool _collision_reported;
- bool _expiry_reported;
+ bool _expiry_reported;
double _impact_lat;
double _impact_lon;
bool _getImpact();
bool _getImpactData();
bool _getCollisionData();
- bool _getExpiryData();
+ bool _getExpiryData();
SGPropertyNode* _getProps() const;
inline double _getBearing() { return bearing; };
virtual osg::Node* load3DModel(const string &path,
- SGPropertyNode *prop_root);
-
+ SGPropertyNode *prop_root);
+
static bool _isNight();
};
}
inline void FGAIBase::setSMPath(const string& p) {
+ cout << "setSMPath " << p <<endl;
_path = p;
}
}
inline void FGAIBase::setXoffset(double x) {
_x_offset = x;
+ cout << "setXoffset " << _x_offset << endl;
+
}
inline void FGAIBase::setYoffset(double y) {
//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),
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));
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));
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",
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");
string contents_node;
contrail_altitude = 30000;
_count = 0;
- _found_sub = true;
+ _found_sub = true;
}
FGSubmodelMgr::~FGSubmodelMgr()
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()
_impact = false;
_hit = false;
- _expiry = false;
+ _expiry = false;
// check if the submodel hit an object or terrain
sm_list = ai->get_ai_list();
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! "
if (_impact || _hit || _expiry) {
// SG_LOG(SG_GENERAL, SG_ALERT, "Submodel: Impact " << _impact << " hit! " << _hit
- //<< " exipiry :-( " << _expiry );
+ //<< " exipiry :-( " << _expiry );
submodel_iterator = submodels.begin();
_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);
}
_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;
//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
//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;
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);
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);
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
} 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();
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;
}
}
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);
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;
}
}
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;
}
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;
}
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;
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)));
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);
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)
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());
{
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();
++subsubmodel_iterator;
} // end while
- subsubmodels.clear();
+ subsubmodels.clear();
//submodel_iterator = submodels.begin();
// 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);
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
class FGAIBase;
-class FGSubmodelMgr : public SGSubsystem
+class FGSubmodelMgr : public SGSubsystem, public SGPropertyChangeListener
{
public:
double drag_area;
double life;
double buoyancy;
- double randomness;
+ double randomness;
bool wind;
bool first_time;
double cd;
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;
double _parent_pitch;
double _parent_roll;
double _parent_speed;
- double _x_offset;
+ double _x_offset;
double _y_offset;
double _z_offset;
bool _impact;
bool _hit;
- bool _expiry;
- bool _found_sub;
+ bool _expiry;
+ bool _found_sub;
SGPropertyNode_ptr _serviceable_node;
SGPropertyNode_ptr _user_lat_node;
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;
int _count;
-
- SGGeod userpos;
- SGGeod offsetpos;
- SGVec3d getCartOffsetPos() const;
- void setOffsetPos();
+
+ SGGeod userpos;
+ SGGeod offsetpos;
+ SGVec3d getCartOffsetPos() const;
+ void setOffsetPos();
};
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