using namespace simgear;
FGAIBase::FGAIBase(object_type ot) :
+ _max_speed(300),
+ _name(""),
+ _parent(""),
props( NULL ),
model_removed( fgGetNode("/ai/models/model-removed", true) ),
manager( NULL ),
fp( NULL ),
-
+ _installed(false),
_impact_lat(0),
_impact_lon(0),
_impact_elev(0),
_impact_pitch(0),
_impact_roll(0),
_impact_speed(0),
-
_refID( _newAIModelID() ),
_otype(ot),
_initialized(false)
+
{
tgt_heading = hdg = tgt_altitude_ft = tgt_speed = 0.0;
tgt_roll = roll = tgt_pitch = tgt_yaw = tgt_vs = vs = pitch = 0.0;
delete_me = false;
_impact_reported = false;
_collision_reported = false;
- _expiry_reported = false;
+ _expiry_reported = false;
_subID = 0;
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", ""));
}
}
bool FGAIBase::init(bool search_in_AI_path) {
- osg::ref_ptr<osgDB::ReaderWriter::Options> opt=
- new osgDB::ReaderWriter::Options(*osgDB::Registry::instance()->getOptions());
-
+
+ string f;
if(search_in_AI_path)
{
- SGPath ai_path(globals->get_fg_root());
- ai_path.append("AI");
- opt->getDatabasePathList().push_front(ai_path.str());
+ // setup a modified Options structure, with only the $fg-root/AI defined;
+ // we'll check that first, then give the normal search logic a chance.
+ // this ensures that models in AI/ are preferred to normal models, where
+ // both exist.
+ osg::ref_ptr<osgDB::ReaderWriter::Options>
+ opt(osg::clone(osgDB::Registry::instance()->getOptions(), osg::CopyOp::SHALLOW_COPY));
+
+ SGPath ai_path(globals->get_fg_root(), "AI");
+ opt->setDatabasePath(ai_path.str());
+
+ f = osgDB::findDataFile(model_path, opt.get());
}
- string f = osgDB::findDataFile(model_path, opt.get());
-
+ if (f.empty()) {
+ f = simgear::SGModelLib::findDataFile(model_path);
+ }
+
if(f.empty())
f = fgGetString("/sim/multiplay/default-model", default_model);
+ else
+ _installed = true;
model = load3DModel(f, props);
} else if (!model_path.empty()) {
SG_LOG(SG_INPUT, SG_WARN, "AIBase: Could not load model " << model_path);
+ // not properly installed...
+ _installed = false;
}
setDie(false);
void FGAIBase::initModel(osg::Node *node)
{
- if (model.valid()) {
+ 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);
+ SG_LOG(SG_INPUT, SG_DEBUG, "AIBase: submodels/path " << _path);
}
+
+ if( _parent!= ""){
+ props->setStringValue("parent-name", _parent.c_str());
+ }
+
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());
setDie(false);
}
hlTrans *= SGQuatd::fromYawPitchRollDeg(hdg, pitch, roll);
// The offset converted to the usual body fixed coordinate system
- // rotated to the earth fiexed coordinates axis
+ // rotated to the earth fixed coordinates axis
SGVec3d off = hlTrans.backTransform(_off);
// Add the position offset of the AIModel to gain the earth centered position
_subID = s;
}
+bool FGAIBase::setParentNode() {
+
+ if (_parent == ""){
+ SG_LOG(SG_GENERAL, SG_ALERT, "AIBase: " << _name
+ << " parent not set ");
+ return false;
+ }
+
+ const SGPropertyNode_ptr ai = fgGetNode("/ai/models", true);
+
+ for (int i = ai->nChildren() - 1; i >= -1; i--) {
+ SGPropertyNode_ptr model;
+
+ if (i < 0) { // last iteration: selected model
+ model = _selected_ac;
+ } else {
+ model = ai->getChild(i);
+ string path = ai->getPath();
+ const string name = model->getStringValue("name");
+
+ if (!model->nChildren()){
+ continue;
+ }
+ if (name == _parent) {
+ _selected_ac = model; // save selected model for last iteration
+ break;
+ }
+
+ }
+ if (!model)
+ continue;
+
+ }// end for loop
+
+ if (_selected_ac != 0){
+ const string name = _selected_ac->getStringValue("name");
+ return true;
+ } else {
+ SG_LOG(SG_GENERAL, SG_ALERT, "AIBase: " << _name
+ << " parent not found: dying ");
+ setDie(true);
+ return false;
+ }
+
+}
+
double FGAIBase::_getLongitude() const {
return pos.getLongitudeDeg();
}
}
double FGAIBase::_getVS_fps() const {
- return vs*60.0;
+ return vs/60.0;
}
double FGAIBase::_get_speed_east_fps() const {
}
void FGAIBase::_setVS_fps( double _vs ) {
- vs = _vs/60.0;
+ vs = _vs*60.0;
}
double FGAIBase::_getAltitude() const {
return altitude_ft;
}
+double FGAIBase::_getAltitudeAGL(SGGeod inpos, double start){
+ getGroundElevationM(SGGeod::fromGeodM(inpos, start),
+ _elevation_m, &_material);
+ return inpos.getElevationFt() - _elevation_m * SG_METER_TO_FEET;
+}
+
bool FGAIBase::_getServiceable() const {
return serviceable;
}