Merge branch 'next' of gitorious.org:fg/flightgear into next
This commit is contained in:
commit
94e4d19ad1
8 changed files with 177 additions and 65 deletions
|
@ -75,8 +75,7 @@ FGAIBase::FGAIBase(object_type ot, bool enableHot) :
|
||||||
_refID( _newAIModelID() ),
|
_refID( _newAIModelID() ),
|
||||||
_otype(ot),
|
_otype(ot),
|
||||||
_initialized(false),
|
_initialized(false),
|
||||||
_aimodel(0),
|
_modeldata(0),
|
||||||
_fxpath(""),
|
|
||||||
_fx(0)
|
_fx(0)
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -232,21 +231,28 @@ void FGAIBase::update(double dt) {
|
||||||
pitch*speed );
|
pitch*speed );
|
||||||
_fx->set_velocity( velocity );
|
_fx->set_velocity( velocity );
|
||||||
}
|
}
|
||||||
else if ((_aimodel)&&(fgGetBool("/sim/sound/aimodels/enabled",false)))
|
else if ((_modeldata)&&(_modeldata->needInitilization()))
|
||||||
{
|
{
|
||||||
string fxpath = _aimodel->get_sound_path();
|
// process deferred nasal initialization,
|
||||||
if (fxpath != "")
|
// which must be done in main thread
|
||||||
{
|
_modeldata->init();
|
||||||
_fxpath = fxpath;
|
|
||||||
props->setStringValue("sim/sound/path", _fxpath.c_str());
|
|
||||||
|
|
||||||
// initialize the sound configuration
|
// sound initialization
|
||||||
SGSoundMgr *smgr = globals->get_soundmgr();
|
if (fgGetBool("/sim/sound/aimodels/enabled",false))
|
||||||
stringstream name;
|
{
|
||||||
name << "aifx:";
|
string fxpath = _modeldata->get_sound_path();
|
||||||
name << _refID;
|
if (fxpath != "")
|
||||||
_fx = new FGFX(smgr, name.str(), props);
|
{
|
||||||
_fx->init();
|
props->setStringValue("sim/sound/path", fxpath.c_str());
|
||||||
|
|
||||||
|
// initialize the sound configuration
|
||||||
|
SGSoundMgr *smgr = globals->get_soundmgr();
|
||||||
|
stringstream name;
|
||||||
|
name << "aifx:";
|
||||||
|
name << _refID;
|
||||||
|
_fx = new FGFX(smgr, name.str(), props);
|
||||||
|
_fx->init();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -324,8 +330,8 @@ bool FGAIBase::init(bool search_in_AI_path)
|
||||||
else
|
else
|
||||||
_installed = true;
|
_installed = true;
|
||||||
|
|
||||||
_aimodel = new FGAIModelData(props);
|
_modeldata = new FGAIModelData(props);
|
||||||
osg::Node * mdl = SGModelLib::loadDeferredModel(f, props, _aimodel);
|
osg::Node * mdl = SGModelLib::loadDeferredModel(f, props, _modeldata);
|
||||||
|
|
||||||
_model = new osg::LOD;
|
_model = new osg::LOD;
|
||||||
_model->setName("AI-model range animation node");
|
_model->setName("AI-model range animation node");
|
||||||
|
@ -912,7 +918,8 @@ int FGAIBase::_newAIModelID() {
|
||||||
|
|
||||||
FGAIModelData::FGAIModelData(SGPropertyNode *root)
|
FGAIModelData::FGAIModelData(SGPropertyNode *root)
|
||||||
: _nasal( new FGNasalModelData(root) ),
|
: _nasal( new FGNasalModelData(root) ),
|
||||||
_path("")
|
_ready(false),
|
||||||
|
_initialized(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -923,9 +930,21 @@ FGAIModelData::~FGAIModelData()
|
||||||
|
|
||||||
void FGAIModelData::modelLoaded(const string& path, SGPropertyNode *prop, osg::Node *n)
|
void FGAIModelData::modelLoaded(const string& path, SGPropertyNode *prop, osg::Node *n)
|
||||||
{
|
{
|
||||||
const char* fxpath = prop->getStringValue("sound/path");
|
// WARNING: All this is called in a separate OSG thread! Only use thread-safe stuff
|
||||||
if (fxpath) {
|
// here that is fine to be run concurrently with stuff in the main loop!
|
||||||
_path = string(fxpath);
|
if (_ready)
|
||||||
}
|
return;
|
||||||
_nasal->modelLoaded(path, prop, n);
|
_fxpath = _prop->getStringValue("sound/path");
|
||||||
|
_prop = prop;
|
||||||
|
_path = path;
|
||||||
|
_ready = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// do Nasal initialization (must be called in the main loop)
|
||||||
|
void FGAIModelData::init()
|
||||||
|
{
|
||||||
|
// call FGNasalSys to create context and run hooks (not-thread safe!)
|
||||||
|
_nasal->modelLoaded(_path, _prop, 0);
|
||||||
|
_prop = 0;
|
||||||
|
_initialized = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,6 @@
|
||||||
#define _FG_AIBASE_HXX
|
#define _FG_AIBASE_HXX
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <list>
|
|
||||||
|
|
||||||
#include <simgear/constants.h>
|
#include <simgear/constants.h>
|
||||||
#include <simgear/math/SGMath.hxx>
|
#include <simgear/math/SGMath.hxx>
|
||||||
|
@ -38,7 +37,6 @@
|
||||||
|
|
||||||
|
|
||||||
using std::string;
|
using std::string;
|
||||||
using std::list;
|
|
||||||
|
|
||||||
class SGMaterial;
|
class SGMaterial;
|
||||||
class FGAIManager;
|
class FGAIManager;
|
||||||
|
@ -230,9 +228,8 @@ private:
|
||||||
bool _initialized;
|
bool _initialized;
|
||||||
osg::ref_ptr<osg::LOD> _model; //The 3D model LOD object
|
osg::ref_ptr<osg::LOD> _model; //The 3D model LOD object
|
||||||
|
|
||||||
osg::ref_ptr<FGAIModelData> _aimodel;
|
osg::ref_ptr<FGAIModelData> _modeldata;
|
||||||
|
|
||||||
string _fxpath;
|
|
||||||
SGSharedPtr<FGFX> _fx;
|
SGSharedPtr<FGFX> _fx;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -453,12 +450,24 @@ class FGAIModelData : public simgear::SGModelData {
|
||||||
public:
|
public:
|
||||||
FGAIModelData(SGPropertyNode *root = 0);
|
FGAIModelData(SGPropertyNode *root = 0);
|
||||||
~FGAIModelData();
|
~FGAIModelData();
|
||||||
|
|
||||||
|
/** osg callback, thread-safe */
|
||||||
void modelLoaded(const string& path, SGPropertyNode *prop, osg::Node *n);
|
void modelLoaded(const string& path, SGPropertyNode *prop, osg::Node *n);
|
||||||
inline string& get_sound_path() { return _path; };
|
|
||||||
|
/** init hook to be called after model is loaded.
|
||||||
|
* Not thread-safe. Call from main thread only. */
|
||||||
|
void init(void);
|
||||||
|
|
||||||
|
bool needInitilization(void) { return _ready && !_initialized;}
|
||||||
|
bool isInitialized(void) { return _initialized;}
|
||||||
|
inline std::string& get_sound_path() { return _fxpath;}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
FGNasalModelData *_nasal;
|
FGNasalModelData *_nasal;
|
||||||
string _path;
|
SGPropertyNode_ptr _prop;
|
||||||
|
std::string _path, _fxpath;
|
||||||
|
bool _ready;
|
||||||
|
bool _initialized;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // _FG_AIBASE_HXX
|
#endif // _FG_AIBASE_HXX
|
||||||
|
|
|
@ -580,9 +580,23 @@ FGTaxiRoute FGGroundNetwork::findShortestRoute(int start, int end,
|
||||||
}
|
}
|
||||||
|
|
||||||
FGTaxiNode *firstNode = findNode(start);
|
FGTaxiNode *firstNode = findNode(start);
|
||||||
|
if (!firstNode)
|
||||||
|
{
|
||||||
|
SG_LOG(SG_GENERAL, SG_ALERT,
|
||||||
|
"Error in ground network. Failed to find first waypoint: " << start
|
||||||
|
<< " at " << ((parent) ? parent->getId() : "<unknown>"));
|
||||||
|
return FGTaxiRoute();
|
||||||
|
}
|
||||||
firstNode->setPathScore(0);
|
firstNode->setPathScore(0);
|
||||||
|
|
||||||
FGTaxiNode *lastNode = findNode(end);
|
FGTaxiNode *lastNode = findNode(end);
|
||||||
|
if (!lastNode)
|
||||||
|
{
|
||||||
|
SG_LOG(SG_GENERAL, SG_ALERT,
|
||||||
|
"Error in ground network. Failed to find last waypoint: " << end
|
||||||
|
<< " at " << ((parent) ? parent->getId() : "<unknown>"));
|
||||||
|
return FGTaxiRoute();
|
||||||
|
}
|
||||||
|
|
||||||
FGTaxiNodeVector unvisited(*currNodesSet); // working copy
|
FGTaxiNodeVector unvisited(*currNodesSet); // working copy
|
||||||
|
|
||||||
|
@ -606,6 +620,13 @@ FGTaxiRoute FGGroundNetwork::findShortestRoute(int start, int end,
|
||||||
seg != best->getEndRoute(); seg++) {
|
seg != best->getEndRoute(); seg++) {
|
||||||
if (fullSearch || (*seg)->isPushBack()) {
|
if (fullSearch || (*seg)->isPushBack()) {
|
||||||
FGTaxiNode *tgt = (*seg)->getEnd();
|
FGTaxiNode *tgt = (*seg)->getEnd();
|
||||||
|
if (!tgt)
|
||||||
|
{
|
||||||
|
SG_LOG(SG_GENERAL, SG_ALERT,
|
||||||
|
"Error in ground network. Found empty segment "
|
||||||
|
<< " at " << ((parent) ? parent->getId() : "<unknown>"));
|
||||||
|
return FGTaxiRoute();
|
||||||
|
}
|
||||||
double alt =
|
double alt =
|
||||||
best->getPathScore() + (*seg)->getLength() +
|
best->getPathScore() + (*seg)->getLength() +
|
||||||
(*seg)->getPenalty(nParkings);
|
(*seg)->getPenalty(nParkings);
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include <simgear/props/props_io.hxx>
|
#include <simgear/props/props_io.hxx>
|
||||||
#include <simgear/debug/logstream.hxx>
|
#include <simgear/debug/logstream.hxx>
|
||||||
#include <simgear/structure/SGBinding.hxx>
|
#include <simgear/structure/SGBinding.hxx>
|
||||||
|
#include <simgear/misc/strutils.hxx>
|
||||||
|
|
||||||
#include <Main/fg_props.hxx>
|
#include <Main/fg_props.hxx>
|
||||||
|
|
||||||
|
@ -16,6 +17,7 @@
|
||||||
using std::string;
|
using std::string;
|
||||||
using std::map;
|
using std::map;
|
||||||
using std::cout;
|
using std::cout;
|
||||||
|
using namespace simgear;
|
||||||
|
|
||||||
typedef std::map<NSMenuItem*, SGBindingList> MenuItemBindings;
|
typedef std::map<NSMenuItem*, SGBindingList> MenuItemBindings;
|
||||||
|
|
||||||
|
@ -27,7 +29,6 @@ public:
|
||||||
CocoaMenuBarPrivate();
|
CocoaMenuBarPrivate();
|
||||||
~CocoaMenuBarPrivate();
|
~CocoaMenuBarPrivate();
|
||||||
|
|
||||||
bool labelIsSeparator(const std::string& s) const;
|
|
||||||
void menuFromProps(NSMenu* menu, SGPropertyNode* menuNode);
|
void menuFromProps(NSMenu* menu, SGPropertyNode* menuNode);
|
||||||
|
|
||||||
void fireBindingsForItem(NSMenuItem* item);
|
void fireBindingsForItem(NSMenuItem* item);
|
||||||
|
@ -63,6 +64,51 @@ static NSString* stdStringToCocoa(const string& s)
|
||||||
return [NSString stringWithUTF8String:s.c_str()];
|
return [NSString stringWithUTF8String:s.c_str()];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void setFunctionKeyShortcut(NSMenuItem* item, unichar shortcut)
|
||||||
|
{
|
||||||
|
unichar ch[1];
|
||||||
|
ch[0] = shortcut;
|
||||||
|
[item setKeyEquivalentModifierMask:NSFunctionKeyMask];
|
||||||
|
[item setKeyEquivalent:[NSString stringWithCharacters:ch length:1]];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void setItemShortcutFromString(NSMenuItem* item, const string& s)
|
||||||
|
{
|
||||||
|
const char* shortcut = "";
|
||||||
|
|
||||||
|
bool hasCtrl = strutils::starts_with(s, "Ctrl-");
|
||||||
|
bool hasShift = strutils::starts_with(s, "Shift-");
|
||||||
|
bool hasAlt = strutils::starts_with(s, "Alt-");
|
||||||
|
|
||||||
|
int offset = 0; // character offset from start of string
|
||||||
|
if (hasShift) offset += 6;
|
||||||
|
if (hasCtrl) offset += 5;
|
||||||
|
if (hasAlt) offset += 4;
|
||||||
|
|
||||||
|
shortcut = s.c_str() + offset;
|
||||||
|
if (!strcmp(shortcut, "Esc"))
|
||||||
|
shortcut = "\e";
|
||||||
|
|
||||||
|
if (!strcmp(shortcut, "F11")) {
|
||||||
|
setFunctionKeyShortcut(item, NSF11FunctionKey);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strcmp(shortcut, "F12")) {
|
||||||
|
setFunctionKeyShortcut(item, NSF12FunctionKey);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
[item setKeyEquivalent:[NSString stringWithCString:shortcut encoding:NSUTF8StringEncoding]];
|
||||||
|
NSUInteger modifiers = 0;
|
||||||
|
if (hasCtrl) modifiers |= NSControlKeyMask;
|
||||||
|
if (hasShift) modifiers |= NSShiftKeyMask;
|
||||||
|
if (hasAlt) modifiers |= NSAlternateKeyMask;
|
||||||
|
|
||||||
|
[item setKeyEquivalentModifierMask:modifiers];
|
||||||
|
}
|
||||||
|
|
||||||
class EnabledListener : public SGPropertyChangeListener
|
class EnabledListener : public SGPropertyChangeListener
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -94,15 +140,9 @@ FGCocoaMenuBar::CocoaMenuBarPrivate::~CocoaMenuBarPrivate()
|
||||||
[delegate release];
|
[delegate release];
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FGCocoaMenuBar::CocoaMenuBarPrivate::labelIsSeparator(const std::string& s) const
|
static bool labelIsSeparator(NSString* s)
|
||||||
{
|
{
|
||||||
for (unsigned int i=0; i<s.size(); ++i) {
|
return [s hasPrefix:@"---"];
|
||||||
if (s[i] != '-') {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FGCocoaMenuBar::CocoaMenuBarPrivate::menuFromProps(NSMenu* menu, SGPropertyNode* menuNode)
|
void FGCocoaMenuBar::CocoaMenuBarPrivate::menuFromProps(NSMenu* menu, SGPropertyNode* menuNode)
|
||||||
|
@ -113,21 +153,28 @@ void FGCocoaMenuBar::CocoaMenuBarPrivate::menuFromProps(NSMenu* menu, SGProperty
|
||||||
n->setBoolValue("enabled", true);
|
n->setBoolValue("enabled", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string shortcut;
|
||||||
string l = n->getStringValue("label");
|
string l = n->getStringValue("label");
|
||||||
string::size_type pos = l.find("(");
|
string::size_type pos = l.find("(");
|
||||||
if (pos != string::npos) {
|
if (pos != string::npos) {
|
||||||
l = l.substr(0, pos);
|
string full(l);
|
||||||
|
l = full.substr(0, pos);
|
||||||
|
shortcut = full.substr(pos + 1, full.size() - (pos + 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
NSString* label = stdStringToCocoa(l);
|
NSString* label = stdStringToCocoa(strutils::simplify(l));
|
||||||
NSString* shortcut = @"";
|
|
||||||
NSMenuItem* item;
|
NSMenuItem* item;
|
||||||
if (index >= [menu numberOfItems]) {
|
if (index >= [menu numberOfItems]) {
|
||||||
if (labelIsSeparator(l)) {
|
if (labelIsSeparator(label)) {
|
||||||
item = [NSMenuItem separatorItem];
|
item = [NSMenuItem separatorItem];
|
||||||
[menu addItem:item];
|
[menu addItem:item];
|
||||||
} else {
|
} else {
|
||||||
item = [menu addItemWithTitle:label action:nil keyEquivalent:shortcut];
|
item = [menu addItemWithTitle:label action:nil keyEquivalent:@""];
|
||||||
|
if (!shortcut.empty()) {
|
||||||
|
setItemShortcutFromString(item, shortcut);
|
||||||
|
}
|
||||||
|
|
||||||
n->getNode("enabled")->addChangeListener(new EnabledListener(item));
|
n->getNode("enabled")->addChangeListener(new EnabledListener(item));
|
||||||
[item setTarget:delegate];
|
[item setTarget:delegate];
|
||||||
[item setAction:@selector(itemAction:)];
|
[item setAction:@selector(itemAction:)];
|
||||||
|
|
|
@ -1123,6 +1123,16 @@ void NavDisplay::computePositionedState(FGPositioned* pos, string_set& states)
|
||||||
} // FGPositioned::Type switch
|
} // FGPositioned::Type switch
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static string mapAINodeToType(SGPropertyNode* model)
|
||||||
|
{
|
||||||
|
// assume all multiplayer items are aircraft for the moment. Not ideal.
|
||||||
|
if (!strcmp(model->getName(), "multiplayer")) {
|
||||||
|
return "ai-aircraft";
|
||||||
|
}
|
||||||
|
|
||||||
|
return string("ai-") + model->getName();
|
||||||
|
}
|
||||||
|
|
||||||
void NavDisplay::processAI()
|
void NavDisplay::processAI()
|
||||||
{
|
{
|
||||||
SGPropertyNode *ai = fgGetNode("/ai/models", true);
|
SGPropertyNode *ai = fgGetNode("/ai/models", true);
|
||||||
|
@ -1137,7 +1147,7 @@ void NavDisplay::processAI()
|
||||||
string_set ss;
|
string_set ss;
|
||||||
computeAIStates(model, ss);
|
computeAIStates(model, ss);
|
||||||
SymbolDefVector rules;
|
SymbolDefVector rules;
|
||||||
findRules(string("ai-") + model->getName(), ss, rules);
|
findRules(mapAINodeToType(model), ss, rules);
|
||||||
if (rules.empty()) {
|
if (rules.empty()) {
|
||||||
return; // no rules matched, we can skip this item
|
return; // no rules matched, we can skip this item
|
||||||
}
|
}
|
||||||
|
@ -1160,13 +1170,14 @@ void NavDisplay::processAI()
|
||||||
void NavDisplay::computeAIStates(const SGPropertyNode* ai, string_set& states)
|
void NavDisplay::computeAIStates(const SGPropertyNode* ai, string_set& states)
|
||||||
{
|
{
|
||||||
int threatLevel = ai->getIntValue("tcas/threat-level",-1);
|
int threatLevel = ai->getIntValue("tcas/threat-level",-1);
|
||||||
if (threatLevel >= 0) {
|
if (threatLevel < 1)
|
||||||
states.insert("tcas");
|
threatLevel = 0;
|
||||||
|
|
||||||
std::ostringstream os;
|
states.insert("tcas");
|
||||||
os << "tcas-threat-level-" << threatLevel;
|
|
||||||
states.insert(os.str());
|
std::ostringstream os;
|
||||||
}
|
os << "tcas-threat-level-" << threatLevel;
|
||||||
|
states.insert(os.str());
|
||||||
|
|
||||||
double vspeed = ai->getDoubleValue("velocities/vertical-speed-fps");
|
double vspeed = ai->getDoubleValue("velocities/vertical-speed-fps");
|
||||||
if (vspeed < -3.0) {
|
if (vspeed < -3.0) {
|
||||||
|
|
|
@ -502,7 +502,7 @@ static SGPath platformDefaultDataPath()
|
||||||
|
|
||||||
SGPath appData;
|
SGPath appData;
|
||||||
appData.set((const char*) path);
|
appData.set((const char*) path);
|
||||||
appData.append("flightgear.org");
|
appData.append("FlightGear");
|
||||||
return appData;
|
return appData;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -365,11 +365,8 @@ getMagDip ()
|
||||||
static double
|
static double
|
||||||
getHeadingMag ()
|
getHeadingMag ()
|
||||||
{
|
{
|
||||||
double magheading;
|
double magheading = fgGetDouble("/orientation/heading-deg") - getMagVar();
|
||||||
magheading = fgGetDouble("/orientation/heading-deg") - getMagVar();
|
return SGMiscd::normalizePeriodic(0.5, 360.5, magheading );
|
||||||
if (magheading <= 0) magheading += 360;
|
|
||||||
else if (magheading > 360) magheading -= 360;
|
|
||||||
return magheading;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -378,11 +375,8 @@ getHeadingMag ()
|
||||||
static double
|
static double
|
||||||
getTrackMag ()
|
getTrackMag ()
|
||||||
{
|
{
|
||||||
double magtrack;
|
double magtrack = fgGetDouble("/orientation/track-deg") - getMagVar();
|
||||||
magtrack = fgGetDouble("/orientation/track-deg") - getMagVar();
|
return SGMiscd::normalizePeriodic(0.5, 360.5, magtrack );
|
||||||
if (magtrack <= 0) magtrack += 360;
|
|
||||||
else if (magtrack > 360) magtrack -= 360;
|
|
||||||
return magtrack;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
|
|
|
@ -247,9 +247,20 @@ FGTileMgr::loadTileModel(const string& modelPath, bool cacheModel)
|
||||||
SGModelLib::loadModel(fullPath.str(), globals->get_props(),
|
SGModelLib::loadModel(fullPath.str(), globals->get_props(),
|
||||||
new FGNasalModelData);
|
new FGNasalModelData);
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
/* TODO FGNasalModelData's callback "modelLoaded" isn't thread-safe.
|
||||||
|
* But deferred (or paged) OSG loading runs in a separate thread, which would
|
||||||
|
* trigger the FGNasalModelData::modelLoaded callback. We're easily doomed
|
||||||
|
* when this happens and the model actually contains a Nasal "load" hook - which
|
||||||
|
* would run the Nasal parser and Nasal script execution in a separate thread...
|
||||||
|
* => Disabling the callback for now, to test if all Nasal related segfaults are
|
||||||
|
* gone. Proper resolution is TBD. We'll need to somehow decouple the OSG callback,
|
||||||
|
* so we can run the Nasal stuff in the main thread.
|
||||||
|
*/
|
||||||
result=
|
result=
|
||||||
SGModelLib::loadDeferredModel(fullPath.str(), globals->get_props(),
|
SGModelLib::loadDeferredModel(fullPath.str(), globals->get_props()/*,
|
||||||
new FGNasalModelData);
|
new FGNasalModelData*/);
|
||||||
|
}
|
||||||
} catch (const sg_io_exception& exc) {
|
} catch (const sg_io_exception& exc) {
|
||||||
string m(exc.getMessage());
|
string m(exc.getMessage());
|
||||||
m += " ";
|
m += " ";
|
||||||
|
|
Loading…
Reference in a new issue