1
0
Fork 0

model paging patch from Till Busch

From Till:
i started the project at the end of february with a simple idea: move all
3d-model loading to the DatabasePager-thread. my first attempts looked
promising, though they were a little too optimistic (or naive?). the patch
has evolved a lot since.

currently it does the following things:
1. revive SGModelLib, move functions for xml-model-loading there

2. replace all calls to sgLoad3dModel with calls to either
SGModelLib::loadModel() or SGModelLib::loadPagedModel()
almost all models will be loaded by the DatabasePager. the few exceptions are:
your own plane, shared models in scenery, random objects, AIBallistic models.

3. simplify mode-loading functions (avoid passing around fg_root)

4. avoid supurious MatrixTransform nodes in loaded models

5. fix some memory leaks
This commit is contained in:
timoore 2008-03-22 09:31:06 +00:00
parent 662ea715e8
commit fd492a297a
39 changed files with 251 additions and 201 deletions

View file

@ -26,9 +26,11 @@
#include <simgear/math/point3d.hxx> #include <simgear/math/point3d.hxx>
#include <simgear/math/sg_random.h> #include <simgear/math/sg_random.h>
#include <simgear/math/sg_geodesy.hxx> #include <simgear/math/sg_geodesy.hxx>
#include <simgear/scene/model/modellib.hxx>
#include <Scenery/scenery.hxx> #include <Scenery/scenery.hxx>
#include "AIModelData.hxx"
#include "AIBallistic.hxx" #include "AIBallistic.hxx"
#include <Main/util.hxx> #include <Main/util.hxx>
@ -36,6 +38,8 @@
const double FGAIBallistic::slugs_to_kgs = 14.5939029372; const double FGAIBallistic::slugs_to_kgs = 14.5939029372;
const double FGAIBallistic::slugs_to_lbs = 32.1740485564; const double FGAIBallistic::slugs_to_lbs = 32.1740485564;
using namespace simgear;
FGAIBallistic::FGAIBallistic(object_type ot) : FGAIBallistic::FGAIBallistic(object_type ot) :
FGAIBase(ot), FGAIBase(ot),
_elevation(0), _elevation(0),
@ -114,6 +118,12 @@ void FGAIBallistic::readFromScenario(SGPropertyNode* scFileNode) {
setRandom(scFileNode->getBoolValue("random", false)); setRandom(scFileNode->getBoolValue("random", false));
} }
osg::Node* FGAIBallistic::load3DModel(const string &path, SGPropertyNode *prop_root)
{
model = SGModelLib::loadModel(path, prop_root, new FGAIModelData(this, prop_root));
return model.get();
}
bool FGAIBallistic::init(bool search_in_AI_path) { bool FGAIBallistic::init(bool search_in_AI_path) {
FGAIBase::init(search_in_AI_path); FGAIBase::init(search_in_AI_path);

View file

@ -43,6 +43,8 @@ public:
void readFromScenario(SGPropertyNode* scFileNode); void readFromScenario(SGPropertyNode* scFileNode);
virtual osg::Node* load3DModel(const string &path,
SGPropertyNode *prop_root);
bool init(bool search_in_AI_path=false); bool init(bool search_in_AI_path=false);
virtual void bind(); virtual void bind();
virtual void unbind(); virtual void unbind();

View file

@ -24,20 +24,20 @@
# include <config.h> # include <config.h>
#endif #endif
#include <simgear/compiler.h> #include <simgear/compiler.h>
#include STL_STRING #include STL_STRING
#include <osg/ref_ptr> #include <osg/ref_ptr>
#include <osg/Node> #include <osg/Node>
#include <osgDB/FileUtils>
#include <simgear/math/point3d.hxx> #include <simgear/math/point3d.hxx>
#include <simgear/math/polar3d.hxx> #include <simgear/math/polar3d.hxx>
#include <simgear/math/sg_geodesy.hxx> #include <simgear/math/sg_geodesy.hxx>
#include <simgear/misc/sg_path.hxx> #include <simgear/misc/sg_path.hxx>
#include <simgear/scene/model/location.hxx> #include <simgear/scene/model/location.hxx>
#include <simgear/scene/model/model.hxx> #include <simgear/scene/model/modellib.hxx>
#include <simgear/scene/util/SGNodeMasks.hxx> #include <simgear/scene/util/SGNodeMasks.hxx>
#include <simgear/debug/logstream.hxx> #include <simgear/debug/logstream.hxx>
#include <simgear/props/props.hxx> #include <simgear/props/props.hxx>
@ -47,11 +47,13 @@
#include <Scripting/NasalSys.hxx> #include <Scripting/NasalSys.hxx>
#include "AIBase.hxx" #include "AIBase.hxx"
#include "AIModelData.hxx"
#include "AIManager.hxx" #include "AIManager.hxx"
const double FGAIBase::e = 2.71828183; const double FGAIBase::e = 2.71828183;
const double FGAIBase::lbs_to_slugs = 0.031080950172; //conversion factor const double FGAIBase::lbs_to_slugs = 0.031080950172; //conversion factor
using namespace simgear;
FGAIBase::FGAIBase(object_type ot) : FGAIBase::FGAIBase(object_type ot) :
props( NULL ), props( NULL ),
@ -155,38 +157,41 @@ void FGAIBase::Transform() {
} }
bool FGAIBase::init(bool search_in_AI_path) { bool FGAIBase::init(bool search_in_AI_path) {
osg::ref_ptr<osgDB::ReaderWriter::Options> opt=
new osgDB::ReaderWriter::Options(*osgDB::Registry::instance()->getOptions());
if (!model_path.empty()) { if(search_in_AI_path)
{
if ( search_in_AI_path SGPath ai_path(globals->get_fg_root());
&& (model_path.substr(model_path.size() - 4, 4) == ".xml")) { ai_path.append("AI");
SGPath ai_path("AI"); opt->getDatabasePathList().push_front(ai_path.str());
ai_path.append(model_path);
try {
model = load3DModel( globals->get_fg_root(), ai_path.str(), props,
globals->get_sim_time_sec() );
} catch (const sg_exception &e) {
model = NULL;
}
} else
model = NULL;
if (!model.get()) {
try {
model = load3DModel( globals->get_fg_root(), model_path, props,
globals->get_sim_time_sec() );
} catch (const sg_exception &e) {
model = NULL;
}
}
} }
if (model.get()) { string f = osgDB::findDataFile(model_path, opt.get());
if(f.empty())
f="Models/Geometry/glider.ac";
model = load3DModel(f, props);
if (model.valid()) {
model->setNodeMask(model->getNodeMask() & ~SG_NODEMASK_TERRAIN_BIT);
aip.init( model.get() ); aip.init( model.get() );
aip.setVisible(true); aip.setVisible(true);
invisible = false; invisible = false;
globals->get_scenery()->get_scene_graph()->addChild(aip.getSceneGraph()); globals->get_scenery()->get_scene_graph()->addChild(aip.getSceneGraph());
} else if (!model_path.empty()) {
SG_LOG(SG_INPUT, SG_WARN, "AIBase: Could not load model " << model_path);
}
setDie(false);
return true;
}
void FGAIBase::initModel(osg::Node *node)
{
if (model.valid()) {
fgSetString("/ai/models/model-added", props->getPath()); fgSetString("/ai/models/model-added", props->getPath());
} else if (!model_path.empty()) { } else if (!model_path.empty()) {
@ -195,18 +200,12 @@ bool FGAIBase::init(bool search_in_AI_path) {
props->setStringValue("submodels/path", _path.c_str()); props->setStringValue("submodels/path", _path.c_str());
setDie(false); setDie(false);
return true;
} }
osg::Node* FGAIBase::load3DModel(const string& fg_root, osg::Node* FGAIBase::load3DModel(const string &path, SGPropertyNode *prop_root)
const string &path,
SGPropertyNode *prop_root,
double sim_time_sec)
{ {
model = sgLoad3DModel(fg_root, path, prop_root, sim_time_sec, 0, model = SGModelLib::loadPagedModel(path, prop_root, new FGAIModelData(this, prop_root));
new FGNasalModelData(prop_root));
model->setNodeMask(model->getNodeMask() & ~SG_NODEMASK_TERRAIN_BIT);
return model.get(); return model.get();
} }

View file

@ -40,7 +40,7 @@ SG_USING_STD(list);
class FGAIManager; class FGAIManager;
class FGAIFlightPlan; class FGAIFlightPlan;
class FGAIBase : public SGReferenced { class FGAIBase : public osg::Referenced {
public: public:
enum object_type { otNull = 0, otAircraft, otShip, otCarrier, otBallistic, enum object_type { otNull = 0, otAircraft, otShip, otCarrier, otBallistic,
@ -54,6 +54,7 @@ public:
virtual void readFromScenario(SGPropertyNode* scFileNode); virtual void readFromScenario(SGPropertyNode* scFileNode);
virtual bool init(bool search_in_AI_path=false); virtual bool init(bool search_in_AI_path=false);
virtual void initModel(osg::Node *node);
virtual void update(double dt); virtual void update(double dt);
virtual void bind(); virtual void bind();
virtual void unbind(); virtual void unbind();
@ -266,10 +267,8 @@ public:
inline double _getRange() { return range; }; inline double _getRange() { return range; };
inline double _getBearing() { return bearing; }; inline double _getBearing() { return bearing; };
osg::Node* load3DModel(const string& fg_root, virtual osg::Node* load3DModel(const string &path,
const string &path, SGPropertyNode *prop_root);
SGPropertyNode *prop_root,
double sim_time_sec);
static bool _isNight(); static bool _isNight();
}; };

View file

@ -71,6 +71,7 @@ public:
!= mSolidObjects.end()) { != mSolidObjects.end()) {
mFoundHot = true; mFoundHot = true;
mUserData = FGAICarrierHardware::newSolid(mCarrier); mUserData = FGAICarrierHardware::newSolid(mCarrier);
//SG_LOG(SG_GENERAL, SG_ALERT, "AICarrierVisitor::apply() solidObject" );
} }
node.setUserData(mUserData.get()); node.setUserData(mUserData.get());
@ -313,20 +314,6 @@ bool FGAICarrier::init(bool search_in_AI_path) {
if (!FGAIShip::init(search_in_AI_path)) if (!FGAIShip::init(search_in_AI_path))
return false; return false;
// process the 3d model here
// mark some objects solid, mark the wires ...
// The model should be used for altitude computations.
// To avoid that every detail in a carrier 3D model will end into
// the aircraft local cache, only set the HOT traversal bit on
// selected objects.
osg::Node* sel = aip.getSceneGraph();
// Clear the HOT traversal flag
// Selectively set that flag again for wires/cats/solid objects.
// Attach a pointer to this carrier class to those objects.
FGCarrierVisitor carrierVisitor(this, wire_objects, catapult_objects, solid_objects);
sel->accept(carrierVisitor);
_longitude_node = fgGetNode("/position/longitude-deg", true); _longitude_node = fgGetNode("/position/longitude-deg", true);
_latitude_node = fgGetNode("/position/latitude-deg", true); _latitude_node = fgGetNode("/position/latitude-deg", true);
_altitude_node = fgGetNode("/position/altitude-ft", true); _altitude_node = fgGetNode("/position/altitude-ft", true);
@ -357,6 +344,27 @@ bool FGAICarrier::init(bool search_in_AI_path) {
return true; return true;
} }
void FGAICarrier::initModel(osg::Node *node)
{
SG_LOG(SG_GENERAL, SG_ALERT, "AICarrier::initModel()" );
FGAIShip::initModel(node);
// process the 3d model here
// mark some objects solid, mark the wires ...
// The model should be used for altitude computations.
// To avoid that every detail in a carrier 3D model will end into
// the aircraft local cache, only set the HOT traversal bit on
// selected objects.
// Clear the HOT traversal flag
// Selectively set that flag again for wires/cats/solid objects.
// Attach a pointer to this carrier class to those objects.
SG_LOG(SG_GENERAL, SG_ALERT, "AICarrier::initModel() visit" );
FGCarrierVisitor carrierVisitor(this, wire_objects, catapult_objects, solid_objects);
model->accept(carrierVisitor);
// model->setNodeMask(node->getNodeMask() & SG_NODEMASK_TERRAIN_BIT | model->getNodeMask());
}
void FGAICarrier::bind() { void FGAICarrier::bind() {
FGAIShip::bind(); FGAIShip::bind();

View file

@ -103,6 +103,7 @@ public:
bool OutsideBox(); bool OutsideBox();
bool init(bool search_in_AI_path=false); bool init(bool search_in_AI_path=false);
void initModel(osg::Node *node);
virtual const char* getTypeString(void) const { return "carrier"; } virtual const char* getTypeString(void) const { return "carrier"; }

View file

@ -145,7 +145,7 @@ FGAIManager::update(double dt) {
tmgr->release((*ai_list_itr)->getID()); tmgr->release((*ai_list_itr)->getID());
--mNumAiModels; --mNumAiModels;
--(mNumAiTypeModels[(*ai_list_itr)->getType()]); --(mNumAiTypeModels[(*ai_list_itr)->getType()]);
FGAIBase *base = *ai_list_itr; FGAIBase *base = (*ai_list_itr).get();
SGPropertyNode *props = base->_getProps(); SGPropertyNode *props = base->_getProps();
props->setBoolValue("valid", false); props->setBoolValue("valid", false);
@ -162,7 +162,7 @@ FGAIManager::update(double dt) {
} else { } else {
fetchUserState(); fetchUserState();
if ((*ai_list_itr)->isa(FGAIBase::otThermal)) { if ((*ai_list_itr)->isa(FGAIBase::otThermal)) {
FGAIBase *base = *ai_list_itr; FGAIBase *base = (*ai_list_itr).get();
processThermal((FGAIThermal*)base); processThermal((FGAIThermal*)base);
} else { } else {
(*ai_list_itr)->update(_dt); (*ai_list_itr)->update(_dt);
@ -175,7 +175,7 @@ FGAIManager::update(double dt) {
} }
void void
FGAIManager::attach(SGSharedPtr<FGAIBase> model) FGAIManager::attach(FGAIBase *model)
{ {
//unsigned idx = mNumAiTypeModels[model->getType()]; //unsigned idx = mNumAiTypeModels[model->getType()];
const char* typeString = model->getTypeString(); const char* typeString = model->getTypeString();
@ -365,7 +365,7 @@ FGAIManager::getStartPosition(const string& id, const string& pid,
std::string pnumber = scEntry->getStringValue("pennant-number"); std::string pnumber = scEntry->getStringValue("pennant-number");
std::string name = scEntry->getStringValue("name"); std::string name = scEntry->getStringValue("name");
if (type == "carrier" && (pnumber == id || name == id)) { if (type == "carrier" && (pnumber == id || name == id)) {
SGSharedPtr<FGAICarrier> carrier = new FGAICarrier; osg::ref_ptr<FGAICarrier> carrier = new FGAICarrier;
carrier->readFromScenario(scEntry); carrier->readFromScenario(scEntry);
if (carrier->getParkPosition(pid, geodPos, hdng, uvw)) { if (carrier->getParkPosition(pid, geodPos, hdng, uvw)) {
@ -431,7 +431,7 @@ FGAIManager::calcCollision(double alt, double lat, double lon, double fuse_range
<< " range " << range << " range " << range
<< " alt " << tgt_alt << " alt " << tgt_alt
); );
return *ai_list_itr; return (*ai_list_itr).get();
} }
++ai_list_itr; ++ai_list_itr;
} }

View file

@ -46,13 +46,13 @@ class FGAIManager : public SGSubsystem
public: public:
// A list of pointers to AI objects // A list of pointers to AI objects
typedef list <SGSharedPtr<FGAIBase> > ai_list_type; typedef list <osg::ref_ptr<FGAIBase> > ai_list_type;
typedef ai_list_type::iterator ai_list_iterator; typedef ai_list_type::iterator ai_list_iterator;
typedef ai_list_type::const_iterator ai_list_const_iterator; typedef ai_list_type::const_iterator ai_list_const_iterator;
ai_list_type ai_list; ai_list_type ai_list;
inline const list <SGSharedPtr<FGAIBase> >& get_ai_list() const { inline const ai_list_type& get_ai_list() const {
SG_LOG(SG_GENERAL, SG_DEBUG, "AI Manager: AI model return list size " << ai_list.size()); SG_LOG(SG_GENERAL, SG_DEBUG, "AI Manager: AI model return list size " << ai_list.size());
return ai_list; return ai_list;
} }
@ -66,7 +66,7 @@ public:
void bind(); void bind();
void unbind(); void unbind();
void update(double dt); void update(double dt);
void attach(SGSharedPtr<FGAIBase> model); void attach(FGAIBase *model);
void destroyObject( int ID ); void destroyObject( int ID );
const FGAIBase *calcCollision(double alt, double lat, double lon, double fuse_range); const FGAIBase *calcCollision(double alt, double lat, double lon, double fuse_range);

View file

@ -0,0 +1,11 @@
#include "AIBase.hxx"
#include "AIModelData.hxx"
void FGAIModelData::modelLoaded(const string& path, SGPropertyNode *prop,
osg::Node *n)
{
FGNasalModelData::modelLoaded(path, prop, n);
// SG_LOG(SG_NASAL, SG_ALERT, "FGAIModelData::modelLoaded(" << path << ")");
if(_base.valid())
_base->initModel(n);
}

View file

@ -0,0 +1,18 @@
#ifndef __FGAIMODELDATA_HXX
#define __FGAIMODELDATA_HXX
#include <osg/observer_ptr>
#include <Scripting/NasalSys.hxx>
class FGAIBase;
class FGAIModelData : public FGNasalModelData {
public:
FGAIModelData(FGAIBase *b, SGPropertyNode *props = 0) : FGNasalModelData(props), _base(b) {}
virtual void modelLoaded(const string& path, SGPropertyNode *prop, osg::Node *);
private:
osg::observer_ptr<FGAIBase> _base;
};
#endif

View file

@ -44,6 +44,7 @@ FGAIMultiplayer::~FGAIMultiplayer() {
} }
bool FGAIMultiplayer::init(bool search_in_AI_path) { bool FGAIMultiplayer::init(bool search_in_AI_path) {
props->setStringValue("sim/model/path", model_path.c_str());
//refuel_node = fgGetNode("systems/refuel/contact", true); //refuel_node = fgGetNode("systems/refuel/contact", true);
isTanker = false; // do this until this property is isTanker = false; // do this until this property is
// passed over the net // passed over the net

View file

@ -3,6 +3,7 @@ noinst_LIBRARIES = libAIModel.a
libAIModel_a_SOURCES = submodel.cxx submodel.hxx \ libAIModel_a_SOURCES = submodel.cxx submodel.hxx \
AIManager.hxx AIManager.cxx \ AIManager.hxx AIManager.cxx \
AIBase.hxx AIBase.cxx \ AIBase.hxx AIBase.cxx \
AIModelData.cxx \
AIAircraft.hxx AIAircraft.cxx \ AIAircraft.hxx AIAircraft.cxx \
AIMultiplayer.hxx AIMultiplayer.cxx \ AIMultiplayer.hxx AIMultiplayer.cxx \
AIShip.hxx AIShip.cxx \ AIShip.hxx AIShip.cxx \

View file

@ -514,7 +514,7 @@ void FGSubmodelMgr::loadAI()
sm_list = ai->get_ai_list(); sm_list = ai->get_ai_list();
if (sm_list.empty()) { if (sm_list.empty()) {
SG_LOG(SG_GENERAL, SG_ALERT, "Submodels: Unable to read AI submodel list"); SG_LOG(SG_GENERAL, SG_DEBUG, "Submodels: Unable to read AI submodel list");
return; return;
} }
@ -559,7 +559,7 @@ void FGSubmodelMgr::setData(int id, string& path, bool serviceable)
"Submodels: Trying to read AI submodels file: " << config.str()); "Submodels: Trying to read AI submodels file: " << config.str());
readProperties(config.str(), &root); readProperties(config.str(), &root);
} catch (const sg_exception &e) { } catch (const sg_exception &e) {
SG_LOG(SG_GENERAL, SG_ALERT, SG_LOG(SG_GENERAL, SG_DEBUG,
"Submodels: Unable to read AI submodels file: " << config.str()); "Submodels: Unable to read AI submodels file: " << config.str());
return; return;
} }
@ -664,7 +664,7 @@ void FGSubmodelMgr::setSubData(int id, string& path, bool serviceable)
readProperties(config.str(), &root); readProperties(config.str(), &root);
} catch (const sg_exception &e) { } catch (const sg_exception &e) {
SG_LOG(SG_GENERAL, SG_ALERT, SG_LOG(SG_GENERAL, SG_DEBUG,
"Submodels: Unable to read AI submodels file: " << config.str()); "Submodels: Unable to read AI submodels file: " << config.str());
return; return;
} }

View file

@ -173,7 +173,7 @@ private:
IC_struct IC; IC_struct IC;
// A list of pointers to AI objects // A list of pointers to AI objects
typedef list <SGSharedPtr<FGAIBase> > sm_list_type; typedef list <osg::ref_ptr<FGAIBase> > sm_list_type;
typedef sm_list_type::iterator sm_list_iterator; typedef sm_list_type::iterator sm_list_iterator;
typedef sm_list_type::const_iterator sm_list_const_iterator; typedef sm_list_type::const_iterator sm_list_const_iterator;

View file

@ -22,7 +22,6 @@
#define _FG_AIEntity_HXX #define _FG_AIEntity_HXX
#include <simgear/math/point3d.hxx> #include <simgear/math/point3d.hxx>
#include <simgear/scene/model/model.hxx>
#include <simgear/scene/model/placement.hxx> #include <simgear/scene/model/placement.hxx>

View file

@ -27,6 +27,7 @@
#include <Main/globals.hxx> #include <Main/globals.hxx>
#include <simgear/misc/sg_path.hxx> #include <simgear/misc/sg_path.hxx>
#include <simgear/math/sg_random.h> #include <simgear/math/sg_random.h>
#include <simgear/scene/model/modellib.hxx>
#include <list> #include <list>
#ifdef _MSC_VER #ifdef _MSC_VER
@ -48,6 +49,8 @@
SG_USING_STD(list); SG_USING_STD(list);
SG_USING_STD(cout); SG_USING_STD(cout);
using namespace simgear;
FGAIMgr::FGAIMgr() { FGAIMgr::FGAIMgr() {
ATC = globals->get_ATC_mgr(); ATC = globals->get_ATC_mgr();
initDone = false; initDone = false;
@ -81,10 +84,7 @@ void FGAIMgr::init() {
string planepath = "Aircraft/c172p/Models/c172p.xml"; string planepath = "Aircraft/c172p/Models/c172p.xml";
bool _loadedDefaultOK = true; bool _loadedDefaultOK = true;
try { try {
_defaultModel = sgLoad3DModel( globals->get_fg_root(), _defaultModel = SGModelLib::loadPagedModel(planepath.c_str(), globals->get_props());
planepath.c_str(),
globals->get_props(),
globals->get_sim_time_sec() );
} catch(sg_exception&) { } catch(sg_exception&) {
_loadedDefaultOK = false; _loadedDefaultOK = false;
} }
@ -93,18 +93,12 @@ void FGAIMgr::init() {
// Just load the same 3D model as the default user plane - that's *bound* to exist! // Just load the same 3D model as the default user plane - that's *bound* to exist!
// TODO - implement robust determination of availability of GA AI aircraft models // TODO - implement robust determination of availability of GA AI aircraft models
planepath = "Aircraft/c172p/Models/c172p.ac"; planepath = "Aircraft/c172p/Models/c172p.ac";
_defaultModel = sgLoad3DModel( globals->get_fg_root(), _defaultModel = SGModelLib::loadPagedModel(planepath.c_str(), globals->get_props());
planepath.c_str(),
globals->get_props(),
globals->get_sim_time_sec() );
} }
planepath = "Aircraft/pa28-161/Models/pa28-161.ac"; planepath = "Aircraft/pa28-161/Models/pa28-161.ac";
try { try {
_piperModel = sgLoad3DModel( globals->get_fg_root(), _piperModel = SGModelLib::loadPagedModel(planepath.c_str(), globals->get_props());
planepath.c_str(),
globals->get_props(),
globals->get_sim_time_sec() );
} catch(sg_exception&) { } catch(sg_exception&) {
_havePiperModel = false; _havePiperModel = false;
} }

View file

@ -22,7 +22,6 @@
#define _FG_AI_PLANE_HXX #define _FG_AI_PLANE_HXX
#include <simgear/math/point3d.hxx> #include <simgear/math/point3d.hxx>
#include <simgear/scene/model/model.hxx>
#include "AIEntity.hxx" #include "AIEntity.hxx"
#include "ATC.hxx" #include "ATC.hxx"

View file

@ -67,7 +67,7 @@ SG_USING_STD(setfill);
#include "wxradar.hxx" #include "wxradar.hxx"
typedef list <SGSharedPtr<FGAIBase> > radar_list_type; typedef list <osg::ref_ptr<FGAIBase> > radar_list_type;
typedef radar_list_type::iterator radar_list_iterator; typedef radar_list_type::iterator radar_list_iterator;
typedef radar_list_type::const_iterator radar_list_const_iterator; typedef radar_list_type::const_iterator radar_list_const_iterator;
@ -617,7 +617,7 @@ wxRadarBg::update_aircraft()
int selected_id = fgGetInt("/instrumentation/radar/selected-id", -1); int selected_id = fgGetInt("/instrumentation/radar/selected-id", -1);
for (; it != end; ++it) { for (; it != end; ++it) {
FGAIBase *ac = *it; FGAIBase *ac = (*it).get();
int type = ac->getType(); int type = ac->getType();
double lat = ac->_getLatitude(); double lat = ac->_getLatitude();
double lon = ac->_getLongitude(); double lon = ac->_getLongitude();

View file

@ -260,6 +260,7 @@ static int status = 0;
void fgOSExit(int code) void fgOSExit(int code)
{ {
viewer->setDone(true); viewer->setDone(true);
viewer->getDatabasePager()->cancel();
status = code; status = code;
} }

View file

@ -24,7 +24,6 @@
# include <config.h> # include <config.h>
#endif #endif
#include <simgear/scene/model/modellib.hxx>
#include <simgear/sound/soundmgr_openal.hxx> #include <simgear/sound/soundmgr_openal.hxx>
#include <simgear/structure/commands.hxx> #include <simgear/structure/commands.hxx>
#include <simgear/misc/sg_path.hxx> #include <simgear/misc/sg_path.hxx>
@ -92,7 +91,6 @@ FGGlobals::FGGlobals() :
initial_state( NULL ), initial_state( NULL ),
locale( NULL ), locale( NULL ),
commands( SGCommandMgr::instance() ), commands( SGCommandMgr::instance() ),
model_lib( NULL ),
acmodel( NULL ), acmodel( NULL ),
model_mgr( NULL ), model_mgr( NULL ),
channel_options_list( NULL ), channel_options_list( NULL ),
@ -127,35 +125,32 @@ FGGlobals::~FGGlobals()
// shut down all subsystems, make sure we take down the // shut down all subsystems, make sure we take down the
// AIModels system first. // AIModels system first.
subsystem_mgr->get_group(SGSubsystemMgr::GENERAL)->remove_subsystem("ai_model"); subsystem_mgr->get_group(SGSubsystemMgr::GENERAL)->remove_subsystem("ai_model");
delete subsystem_mgr; delete subsystem_mgr;
delete event_mgr; delete event_mgr;
delete time_params; delete time_params;
delete ephem; delete ephem;
delete mag; delete mag;
delete matlib; delete matlib;
delete route_mgr; delete route_mgr;
delete current_panel; delete current_panel;
delete soundmgr; delete soundmgr;
delete airports; delete airports;
delete runways; delete runways;
delete ATC_mgr; delete ATC_mgr;
delete AI_mgr; delete AI_mgr;
delete controls; delete controls;
delete viewmgr; delete viewmgr;
delete initial_state;
// //delete locale; Don't delete locale
// delete commands; // delete commands;
delete model_lib; delete acmodel;
delete acmodel; delete model_mgr;
delete model_mgr; delete channel_options_list;
delete channel_options_list; delete initial_waypoints;
delete initial_waypoints; delete tile_mgr;
delete scenery; delete scenery;
//delete tile_mgr; // Don't delete tile manager yet, because loader thread problems delete io;
delete io; delete fontcache;
delete fontcache;
delete navlist; delete navlist;
delete loclist; delete loclist;
@ -168,8 +163,6 @@ FGGlobals::~FGGlobals()
delete fixlist; delete fixlist;
delete airwaynet; delete airwaynet;
delete multiplayer_mgr; delete multiplayer_mgr;
delete props;
} }
@ -272,7 +265,6 @@ FGGlobals::get_event_mgr () const
void void
FGGlobals::saveInitialState () FGGlobals::saveInitialState ()
{ {
delete initial_state;
initial_state = new SGPropertyNode(); initial_state = new SGPropertyNode();
if (!copyProperties(props, initial_state)) if (!copyProperties(props, initial_state))

View file

@ -57,7 +57,6 @@ class SGEphemeris;
class SGCommandMgr; class SGCommandMgr;
class SGMagVar; class SGMagVar;
class SGMaterialLib; class SGMaterialLib;
class SGModelLib;
class SGPropertyNode; class SGPropertyNode;
class SGTime; class SGTime;
class SGSoundMgr; class SGSoundMgr;
@ -97,6 +96,13 @@ class FGGlobals
private: private:
// properties, destroy last
SGPropertyNode_ptr props;
SGPropertyNode_ptr initial_state;
// localization
SGPropertyNode_ptr locale;
FGRenderer *renderer; FGRenderer *renderer;
SGSubsystemMgr *subsystem_mgr; SGSubsystemMgr *subsystem_mgr;
SGEventMgr *event_mgr; SGEventMgr *event_mgr;
@ -162,17 +168,8 @@ private:
// viewer manager // viewer manager
FGViewMgr *viewmgr; FGViewMgr *viewmgr;
// properties
SGPropertyNode *props;
SGPropertyNode *initial_state;
// localization
SGPropertyNode *locale;
SGCommandMgr *commands; SGCommandMgr *commands;
SGModelLib *model_lib;
//FGFlightPlanDispatcher *fpDispatcher; //FGFlightPlanDispatcher *fpDispatcher;
FGAircraftModel *acmodel; FGAircraftModel *acmodel;
@ -299,12 +296,6 @@ public:
inline SGCommandMgr *get_commands () { return commands; } inline SGCommandMgr *get_commands () { return commands; }
inline SGModelLib * get_model_lib () { return model_lib; }
inline void set_model_lib (SGModelLib *m) {
model_lib = m;
}
inline FGAircraftModel *get_aircraft_model () { return acmodel; } inline FGAircraftModel *get_aircraft_model () { return acmodel; }
inline void set_aircraft_model (FGAircraftModel * model) inline void set_aircraft_model (FGAircraftModel * model)

View file

@ -47,6 +47,8 @@
#include <simgear/timing/sg_time.hxx> #include <simgear/timing/sg_time.hxx>
#include <simgear/math/sg_random.h> #include <simgear/math/sg_random.h>
#include <osgDB/Registry>
// Class references // Class references
#include <simgear/ephemeris/ephemeris.hxx> #include <simgear/ephemeris/ephemeris.hxx>
#include <simgear/scene/model/modellib.hxx> #include <simgear/scene/model/modellib.hxx>
@ -135,9 +137,9 @@ void fgUpdateTimeDepCalcs() {
double lat = fgGetDouble("/sim/presets/latitude-deg"); double lat = fgGetDouble("/sim/presets/latitude-deg");
// We require just to have 50 meter scenery availabe around // We require just to have 50 meter scenery availabe around
// the aircraft. // the aircraft.
double range = 50.0; double range = 1000.0;
if (globals->get_tile_mgr()->scenery_available(lat, lon, range)) { if (globals->get_scenery()->scenery_available(lat, lon, range)) {
SG_LOG(SG_FLIGHT,SG_INFO, "Finally initializing fdm"); SG_LOG(SG_FLIGHT,SG_ALERT, "Finally initializing fdm");
cur_fdm_state->init(); cur_fdm_state->init();
if ( cur_fdm_state->get_bound() ) { if ( cur_fdm_state->get_bound() ) {
cur_fdm_state->unbind(); cur_fdm_state->unbind();
@ -766,7 +768,7 @@ static void fgIdleFunction ( void ) {
// Initialize the material manager // Initialize the material manager
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
globals->set_matlib( new SGMaterialLib ); globals->set_matlib( new SGMaterialLib );
globals->set_model_lib(new SGModelLib); simgear::SGModelLib::init(globals->get_fg_root());
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////

View file

@ -66,8 +66,6 @@
#include <simgear/screen/extensions.hxx> #include <simgear/screen/extensions.hxx>
#include <simgear/scene/material/matlib.hxx> #include <simgear/scene/material/matlib.hxx>
#include <simgear/scene/model/animation.hxx> #include <simgear/scene/model/animation.hxx>
#include <simgear/scene/model/model.hxx>
#include <simgear/scene/model/modellib.hxx>
#include <simgear/scene/model/placement.hxx> #include <simgear/scene/model/placement.hxx>
#include <simgear/scene/util/SGUpdateVisitor.hxx> #include <simgear/scene/util/SGUpdateVisitor.hxx>
#include <simgear/scene/util/RenderConstants.hxx> #include <simgear/scene/util/RenderConstants.hxx>

View file

@ -150,7 +150,7 @@ private:
SGPropertyNode_ptr view_number; SGPropertyNode_ptr view_number;
vector<SGPropertyNode_ptr> config_list; vector<SGPropertyNode_ptr> config_list;
typedef vector<FGViewer *> viewer_list; typedef vector<SGSharedPtr<FGViewer> > viewer_list;
viewer_list views; viewer_list views;
int current; int current;

View file

@ -50,36 +50,17 @@ FGAircraftModel::~FGAircraftModel ()
void void
FGAircraftModel::init () FGAircraftModel::init ()
{ {
SGPath liveryPath;
_aircraft = new SGModelPlacement; _aircraft = new SGModelPlacement;
string path = fgGetString("/sim/model/path", "Models/Geometry/glider.ac"); string path = fgGetString("/sim/model/path", "Models/Geometry/glider.ac");
string texture_path = fgGetString("/sim/model/texture-path");
if( texture_path.size() ) {
SGPath temp_path;
if ( !ulIsAbsolutePathName( texture_path.c_str() ) ) {
temp_path = globals->get_fg_root();
temp_path.append( SGPath( path ).dir() );
temp_path.append( texture_path );
liveryPath = temp_path;
} else
liveryPath = texture_path;
}
try { try {
osg::Node *model = fgLoad3DModelPanel( globals->get_fg_root(), osg::Node *model = fgLoad3DModelPanel( path, globals->get_props());
path,
globals->get_props(),
globals->get_sim_time_sec(),
liveryPath);
_aircraft->init( model ); _aircraft->init( model );
} catch (const sg_exception &ex) { } catch (const sg_exception &ex) {
SG_LOG(SG_GENERAL, SG_ALERT, "Failed to load aircraft from " << path << ':'); SG_LOG(SG_GENERAL, SG_ALERT, "Failed to load aircraft from " << path << ':');
SG_LOG(SG_GENERAL, SG_ALERT, " " << ex.getFormattedMessage()); SG_LOG(SG_GENERAL, SG_ALERT, " " << ex.getFormattedMessage());
SG_LOG(SG_GENERAL, SG_ALERT, "(Falling back to glider.ac.)"); SG_LOG(SG_GENERAL, SG_ALERT, "(Falling back to glider.ac.)");
osg::Node *model = fgLoad3DModelPanel( globals->get_fg_root(), osg::Node *model = fgLoad3DModelPanel( "Models/Geometry/glider.ac",
"Models/Geometry/glider.ac", globals->get_props());
globals->get_props(),
globals->get_sim_time_sec(),
liveryPath);
_aircraft->init( model ); _aircraft->init( model );
} }
_selector->addChild(_aircraft->getSceneGraph(), true); _selector->addChild(_aircraft->getSceneGraph(), true);

View file

@ -12,7 +12,7 @@
#include <osg/Geode> #include <osg/Geode>
#include <simgear/props/props.hxx> #include <simgear/props/props.hxx>
#include <simgear/scene/model/model.hxx> #include <simgear/scene/model/modellib.hxx>
#include <simgear/scene/util/SGNodeMasks.hxx> #include <simgear/scene/util/SGNodeMasks.hxx>
#include "panelnode.hxx" #include "panelnode.hxx"
@ -21,12 +21,14 @@
SG_USING_STD(vector); SG_USING_STD(vector);
using namespace simgear;
static static
osg::Node* load_panel(SGPropertyNode *n) osg::Node* load_panel(SGPropertyNode *n)
{ {
osg::Geode* geode = new osg::Geode; osg::Geode* geode = new osg::Geode;
geode->addDrawable(new FGPanelNode(n)); geode->addDrawable(new FGPanelNode(n));
return geode; return geode;
} }
@ -35,14 +37,11 @@ osg::Node* load_panel(SGPropertyNode *n)
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
osg::Node * osg::Node *
fgLoad3DModelPanel( const string &fg_root, const string &path, fgLoad3DModelPanel(const string &path, SGPropertyNode *prop_root)
SGPropertyNode *prop_root,
double sim_time_sec, const SGPath& livery )
{ {
osg::Node* node = sgLoad3DModel( fg_root, path, prop_root, sim_time_sec, osg::Node* node = SGModelLib::loadModel(path, prop_root, load_panel);
load_panel, 0, livery ); node->setNodeMask(~SG_NODEMASK_TERRAIN_BIT);
node->setNodeMask(~SG_NODEMASK_TERRAIN_BIT); return node;
return node;
} }

View file

@ -46,9 +46,7 @@ class FGLocation;
* Subsystems should not normally invoke this function directly; * Subsystems should not normally invoke this function directly;
* instead, they should use the SGModelLoader declared in loader.hxx. * instead, they should use the SGModelLoader declared in loader.hxx.
*/ */
osg::Node *fgLoad3DModelPanel( const string& fg_root, const string &path, osg::Node *fgLoad3DModelPanel( const string &path, SGPropertyNode *prop_root);
SGPropertyNode *prop_root,
double sim_time_sec, const SGPath& livery );
#endif // __MODEL_HXX #endif // __MODEL_HXX

View file

@ -27,10 +27,11 @@
SG_USING_STD(vector); SG_USING_STD(vector);
using namespace simgear;
// OSGFIXME // OSGFIXME
// extern SGShadowVolume *shadows; // extern SGShadowVolume *shadows;
FGModelMgr::FGModelMgr () FGModelMgr::FGModelMgr ()
: _models(fgGetNode("/models", true)), : _models(fgGetNode("/models", true)),
_listener(new Listener(this)) _listener(new Listener(this))
@ -68,17 +69,12 @@ FGModelMgr::add_model (SGPropertyNode * node)
SGModelPlacement *model = new SGModelPlacement; SGModelPlacement *model = new SGModelPlacement;
instance->model = model; instance->model = model;
instance->node = node; instance->node = node;
SGModelLib *model_lib = globals->get_model_lib();
const char *path = node->getStringValue("path", "Models/Geometry/glider.ac"); const char *path = node->getStringValue("path", "Models/Geometry/glider.ac");
osg::Node *object; osg::Node *object;
try { try {
object = model_lib->load_model( object = SGModelLib::loadPagedModel(path, globals->get_props());
globals->get_fg_root(),
path,
globals->get_props(),
globals->get_sim_time_sec(), /*cache_object=*/false);
} catch (const sg_throwable& t) { } catch (const sg_throwable& t) {
SG_LOG(SG_GENERAL, SG_ALERT, "Error loading " << path << ":\n " SG_LOG(SG_GENERAL, SG_ALERT, "Error loading " << path << ":\n "
<< t.getFormattedMessage() << t.getOrigin()); << t.getFormattedMessage() << t.getOrigin());

View file

@ -799,7 +799,7 @@ FGMultiplayMgr::addMultiplayer(const std::string& callsign,
const std::string& modelName) const std::string& modelName)
{ {
if (0 < mMultiPlayerMap.count(callsign)) if (0 < mMultiPlayerMap.count(callsign))
return mMultiPlayerMap[callsign]; return mMultiPlayerMap[callsign].get();
FGAIMultiplayer* mp = new FGAIMultiplayer; FGAIMultiplayer* mp = new FGAIMultiplayer;
mp->setPath(modelName.c_str()); mp->setPath(modelName.c_str());
@ -825,7 +825,7 @@ FGAIMultiplayer*
FGMultiplayMgr::getMultiplayer(const std::string& callsign) FGMultiplayMgr::getMultiplayer(const std::string& callsign)
{ {
if (0 < mMultiPlayerMap.count(callsign)) if (0 < mMultiPlayerMap.count(callsign))
return mMultiPlayerMap[callsign]; return mMultiPlayerMap[callsign].get();
else else
return 0; return 0;
} }

View file

@ -83,7 +83,7 @@ private:
FGAIMultiplayer* getMultiplayer(const std::string& callsign); FGAIMultiplayer* getMultiplayer(const std::string& callsign);
/// maps from the callsign string to the FGAIMultiplayer /// maps from the callsign string to the FGAIMultiplayer
typedef std::map<std::string, SGSharedPtr<FGAIMultiplayer> > MultiPlayerMap; typedef std::map<std::string, osg::ref_ptr<FGAIMultiplayer> > MultiPlayerMap;
MultiPlayerMap mMultiPlayerMap; MultiPlayerMap mMultiPlayerMap;
netSocket* mSocket; netSocket* mSocket;

View file

@ -32,7 +32,6 @@
#include STL_STRING #include STL_STRING
#include <simgear/props/props.hxx> #include <simgear/props/props.hxx>
#include <simgear/scene/model/model.hxx>
#include <Main/globals.hxx> #include <Main/globals.hxx>
#include <Main/fg_props.hxx> #include <Main/fg_props.hxx>

View file

@ -16,6 +16,7 @@
// along with this program; if not, write to the Free Software // along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include <simgear/scene/model/SGPagedLOD.hxx>
#include "SceneryPager.hxx" #include "SceneryPager.hxx"
#include <algorithm> #include <algorithm>
#include <functional> #include <functional>
@ -39,6 +40,16 @@ SceneryPager::~SceneryPager()
{ {
} }
void SceneryPager::requestNodeFile(const std::string& fileName,osg::Group* group,
float priority, const osg::FrameStamp* framestamp)
{
simgear::SGPagedLOD *sgplod = dynamic_cast<simgear::SGPagedLOD*>(group);
if(sgplod)
DatabasePager::requestNodeFile(fileName,group,priority,framestamp,sgplod->getReaderWriterOptions());
else
DatabasePager::requestNodeFile(fileName,group,priority,framestamp);
}
void SceneryPager::queueRequest(const std::string& fileName, osg::Group* group, void SceneryPager::queueRequest(const std::string& fileName, osg::Group* group,
float priority, osg::FrameStamp* frameStamp) float priority, osg::FrameStamp* frameStamp)
{ {

View file

@ -33,6 +33,11 @@ class SceneryPager : public osgDB::DatabasePager
public: public:
SceneryPager(); SceneryPager();
SceneryPager(const SceneryPager& rhs); SceneryPager(const SceneryPager& rhs);
// reimplement to add readerWriterOptions from SGPagedLOD
virtual void requestNodeFile(const std::string& fileName,osg::Group* group,
float priority, const osg::FrameStamp* framestamp);
void queueRequest(const std::string& fileName, osg::Group* node, void queueRequest(const std::string& fileName, osg::Group* node,
float priority, osg::FrameStamp* frameStamp); float priority, osg::FrameStamp* frameStamp);
// This is passed a ref_ptr so that it can "take ownership" of the // This is passed a ref_ptr so that it can "take ownership" of the

View file

@ -30,6 +30,7 @@
#include <osgUtil/IntersectVisitor> #include <osgUtil/IntersectVisitor>
#include <simgear/constants.h>
#include <simgear/debug/logstream.hxx> #include <simgear/debug/logstream.hxx>
#include <simgear/scene/tgdb/userdata.hxx> #include <simgear/scene/tgdb/userdata.hxx>
#include <simgear/math/sg_geodesy.hxx> #include <simgear/math/sg_geodesy.hxx>
@ -37,9 +38,11 @@
#include <simgear/scene/material/matlib.hxx> #include <simgear/scene/material/matlib.hxx>
#include <simgear/scene/util/SGNodeMasks.hxx> #include <simgear/scene/util/SGNodeMasks.hxx>
#include <simgear/scene/util/SGSceneUserData.hxx> #include <simgear/scene/util/SGSceneUserData.hxx>
#include <simgear/scene/model/CheckSceneryVisitor.hxx>
#include <Main/fg_props.hxx> #include <Main/fg_props.hxx>
#include "tilemgr.hxx"
#include "scenery.hxx" #include "scenery.hxx"
using namespace flightgear; using namespace flightgear;
@ -72,12 +75,11 @@ FGScenery::FGScenery()
SG_LOG( SG_TERRAIN, SG_INFO, "Initializing scenery subsystem" ); SG_LOG( SG_TERRAIN, SG_INFO, "Initializing scenery subsystem" );
} }
// Initialize the Scenery Management system
FGScenery::~FGScenery() { FGScenery::~FGScenery() {
} }
// Initialize the Scenery Management system
void FGScenery::init() { void FGScenery::init() {
// Scene graph root // Scene graph root
scene_graph = new osg::Group; scene_graph = new osg::Group;
@ -100,8 +102,7 @@ void FGScenery::init() {
scene_graph->addChild( aircraft_branch.get() ); scene_graph->addChild( aircraft_branch.get() );
// Initials values needed by the draw-time object loader // Initials values needed by the draw-time object loader
sgUserDataInit( globals->get_model_lib(), globals->get_fg_root(), sgUserDataInit( globals->get_props() );
globals->get_props(), globals->get_sim_time_sec() );
} }
@ -211,6 +212,25 @@ FGScenery::get_cart_ground_intersection(const SGVec3d& pos, const SGVec3d& dir,
return hits; return hits;
} }
bool FGScenery::scenery_available(double lat, double lon, double range_m)
{
if(globals->get_tile_mgr()->scenery_available(lat, lon, range_m))
{
double elev;
get_elevation_m(lat, lon, SG_MAX_ELEVATION_M, elev, 0);
SGVec3f p = SGVec3f::fromGeod(SGGeod::fromDegM(lon,lat,elev));
simgear::CheckSceneryVisitor csnv(getPagerSingleton(), p.osg(), range_m);
// currently the PagedLODs will not be loaded by the DatabasePager
// while the splashscreen is there, so CheckSceneryVisitor force-loads
// missing objects in the main thread
get_scene_graph()->accept(csnv);
if(!csnv.isLoaded())
return false;
return true;
}
return false;
}
SceneryPager* FGScenery::getPagerSingleton() SceneryPager* FGScenery::getPagerSingleton()
{ {
static osg::ref_ptr<SceneryPager> pager = new SceneryPager; static osg::ref_ptr<SceneryPager> pager = new SceneryPager;

View file

@ -102,6 +102,11 @@ public:
osg::Group *get_models_branch () const { return models_branch.get(); } osg::Group *get_models_branch () const { return models_branch.get(); }
osg::Group *get_aircraft_branch () const { return aircraft_branch.get(); } osg::Group *get_aircraft_branch () const { return aircraft_branch.get(); }
/// Returns true if scenery is avaliable for the given lat, lon position
/// within a range of range_m.
/// lat and lon are expected to be in degrees.
bool scenery_available(double lat, double lon, double range_m);
// Static because access to the pager is needed before the rest of // Static because access to the pager is needed before the rest of
// the scenery is initialized. // the scenery is initialized.
static flightgear::SceneryPager* getPagerSingleton(); static flightgear::SceneryPager* getPagerSingleton();

View file

@ -436,7 +436,7 @@ FGTileEntry::loadTileByName(const string& index_str,
if ( obj->type == OBJECT_STATIC ) { if ( obj->type == OBJECT_STATIC ) {
custom_path = obj->path; custom_path = obj->path;
} else { } else {
custom_path = globals->get_fg_root(); // custom_path = globals->get_fg_root();
} }
custom_path.append( obj->name ); custom_path.append( obj->name );

View file

@ -50,6 +50,7 @@
using std::for_each; using std::for_each;
using flightgear::SceneryPager; using flightgear::SceneryPager;
using simgear::SGModelLib;
#define TEST_LAST_HIT_CACHE #define TEST_LAST_HIT_CACHE
@ -244,13 +245,18 @@ FGTileMgr::loadTileModel(const string& modelPath, bool cacheModel)
{ {
osg::Node* result = 0; osg::Node* result = 0;
try { try {
result = if(cacheModel)
globals->get_model_lib()->load_model(".", {
modelPath, result =
globals->get_props(), SGModelLib::loadModel(modelPath, globals->get_props(),
globals->get_sim_time_sec(), new FGNasalModelData);
cacheModel, }
new FGNasalModelData ); else
{
result=
SGModelLib::loadPagedModel(modelPath, globals->get_props(),
new FGNasalModelData);
}
} catch (const sg_io_exception& exc) { } catch (const sg_io_exception& exc) {
string m(exc.getMessage()); string m(exc.getMessage());
m += " "; m += " ";

View file

@ -1082,12 +1082,16 @@ bool FGNasalListener::changed(SGPropertyNode* node)
void FGNasalModelData::modelLoaded(const string& path, SGPropertyNode *prop, void FGNasalModelData::modelLoaded(const string& path, SGPropertyNode *prop,
osg::Node *) osg::Node *)
{ {
if(!prop)
return;
/*
SGPropertyNode *n = prop->getNode("nasal"), *load; SGPropertyNode *n = prop->getNode("nasal"), *load;
if(!n) if(!n)
return; return;
*/
load = n->getNode("load"); SGPropertyNode *load = load = prop->getNode("load");
_unload = n->getNode("unload"); _unload = prop->getNode("unload");
if(!load && !_unload) if(!load && !_unload)
return; return;

View file

@ -4,7 +4,7 @@
#include <simgear/misc/sg_path.hxx> #include <simgear/misc/sg_path.hxx>
#include <simgear/structure/subsystem_mgr.hxx> #include <simgear/structure/subsystem_mgr.hxx>
#include <simgear/nasal/nasal.h> #include <simgear/nasal/nasal.h>
#include <simgear/scene/model/model.hxx> #include <simgear/scene/model/modellib.hxx>
#include <simgear/xml/easyxml.hxx> #include <simgear/xml/easyxml.hxx>
#include <map> #include <map>
@ -159,7 +159,7 @@ private:
}; };
class FGNasalModelData : public SGModelData { class FGNasalModelData : public simgear::SGModelData {
public: public:
FGNasalModelData(SGPropertyNode *props = 0) : _props(props), _unload(0) {} FGNasalModelData(SGPropertyNode *props = 0) : _props(props), _unload(0) {}
~FGNasalModelData(); ~FGNasalModelData();