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:
parent
662ea715e8
commit
fd492a297a
39 changed files with 251 additions and 201 deletions
|
@ -26,9 +26,11 @@
|
|||
#include <simgear/math/point3d.hxx>
|
||||
#include <simgear/math/sg_random.h>
|
||||
#include <simgear/math/sg_geodesy.hxx>
|
||||
#include <simgear/scene/model/modellib.hxx>
|
||||
|
||||
#include <Scenery/scenery.hxx>
|
||||
|
||||
#include "AIModelData.hxx"
|
||||
#include "AIBallistic.hxx"
|
||||
|
||||
#include <Main/util.hxx>
|
||||
|
@ -36,6 +38,8 @@
|
|||
const double FGAIBallistic::slugs_to_kgs = 14.5939029372;
|
||||
const double FGAIBallistic::slugs_to_lbs = 32.1740485564;
|
||||
|
||||
using namespace simgear;
|
||||
|
||||
FGAIBallistic::FGAIBallistic(object_type ot) :
|
||||
FGAIBase(ot),
|
||||
_elevation(0),
|
||||
|
@ -114,6 +118,12 @@ void FGAIBallistic::readFromScenario(SGPropertyNode* scFileNode) {
|
|||
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) {
|
||||
FGAIBase::init(search_in_AI_path);
|
||||
|
||||
|
|
|
@ -43,6 +43,8 @@ public:
|
|||
|
||||
void readFromScenario(SGPropertyNode* scFileNode);
|
||||
|
||||
virtual osg::Node* load3DModel(const string &path,
|
||||
SGPropertyNode *prop_root);
|
||||
bool init(bool search_in_AI_path=false);
|
||||
virtual void bind();
|
||||
virtual void unbind();
|
||||
|
|
|
@ -24,20 +24,20 @@
|
|||
# include <config.h>
|
||||
#endif
|
||||
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
|
||||
#include STL_STRING
|
||||
|
||||
#include <osg/ref_ptr>
|
||||
#include <osg/Node>
|
||||
#include <osgDB/FileUtils>
|
||||
|
||||
#include <simgear/math/point3d.hxx>
|
||||
#include <simgear/math/polar3d.hxx>
|
||||
#include <simgear/math/sg_geodesy.hxx>
|
||||
#include <simgear/misc/sg_path.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/debug/logstream.hxx>
|
||||
#include <simgear/props/props.hxx>
|
||||
|
@ -47,11 +47,13 @@
|
|||
#include <Scripting/NasalSys.hxx>
|
||||
|
||||
#include "AIBase.hxx"
|
||||
#include "AIModelData.hxx"
|
||||
#include "AIManager.hxx"
|
||||
|
||||
const double FGAIBase::e = 2.71828183;
|
||||
const double FGAIBase::lbs_to_slugs = 0.031080950172; //conversion factor
|
||||
|
||||
using namespace simgear;
|
||||
|
||||
FGAIBase::FGAIBase(object_type ot) :
|
||||
props( NULL ),
|
||||
|
@ -155,38 +157,41 @@ void FGAIBase::Transform() {
|
|||
}
|
||||
|
||||
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
|
||||
&& (model_path.substr(model_path.size() - 4, 4) == ".xml")) {
|
||||
SGPath ai_path("AI");
|
||||
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(search_in_AI_path)
|
||||
{
|
||||
SGPath ai_path(globals->get_fg_root());
|
||||
ai_path.append("AI");
|
||||
opt->getDatabasePathList().push_front(ai_path.str());
|
||||
}
|
||||
|
||||
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.setVisible(true);
|
||||
invisible = false;
|
||||
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());
|
||||
|
||||
} else if (!model_path.empty()) {
|
||||
|
@ -195,18 +200,12 @@ bool FGAIBase::init(bool search_in_AI_path) {
|
|||
|
||||
props->setStringValue("submodels/path", _path.c_str());
|
||||
setDie(false);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
osg::Node* FGAIBase::load3DModel(const string& fg_root,
|
||||
const string &path,
|
||||
SGPropertyNode *prop_root,
|
||||
double sim_time_sec)
|
||||
osg::Node* FGAIBase::load3DModel(const string &path, SGPropertyNode *prop_root)
|
||||
{
|
||||
model = sgLoad3DModel(fg_root, path, prop_root, sim_time_sec, 0,
|
||||
new FGNasalModelData(prop_root));
|
||||
model->setNodeMask(model->getNodeMask() & ~SG_NODEMASK_TERRAIN_BIT);
|
||||
model = SGModelLib::loadPagedModel(path, prop_root, new FGAIModelData(this, prop_root));
|
||||
return model.get();
|
||||
}
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@ SG_USING_STD(list);
|
|||
class FGAIManager;
|
||||
class FGAIFlightPlan;
|
||||
|
||||
class FGAIBase : public SGReferenced {
|
||||
class FGAIBase : public osg::Referenced {
|
||||
|
||||
public:
|
||||
enum object_type { otNull = 0, otAircraft, otShip, otCarrier, otBallistic,
|
||||
|
@ -54,6 +54,7 @@ public:
|
|||
virtual void readFromScenario(SGPropertyNode* scFileNode);
|
||||
|
||||
virtual bool init(bool search_in_AI_path=false);
|
||||
virtual void initModel(osg::Node *node);
|
||||
virtual void update(double dt);
|
||||
virtual void bind();
|
||||
virtual void unbind();
|
||||
|
@ -266,11 +267,9 @@ public:
|
|||
inline double _getRange() { return range; };
|
||||
inline double _getBearing() { return bearing; };
|
||||
|
||||
osg::Node* load3DModel(const string& fg_root,
|
||||
const string &path,
|
||||
SGPropertyNode *prop_root,
|
||||
double sim_time_sec);
|
||||
|
||||
virtual osg::Node* load3DModel(const string &path,
|
||||
SGPropertyNode *prop_root);
|
||||
|
||||
static bool _isNight();
|
||||
};
|
||||
|
||||
|
|
|
@ -71,6 +71,7 @@ public:
|
|||
!= mSolidObjects.end()) {
|
||||
mFoundHot = true;
|
||||
mUserData = FGAICarrierHardware::newSolid(mCarrier);
|
||||
//SG_LOG(SG_GENERAL, SG_ALERT, "AICarrierVisitor::apply() solidObject" );
|
||||
}
|
||||
node.setUserData(mUserData.get());
|
||||
|
||||
|
@ -313,20 +314,6 @@ bool FGAICarrier::init(bool search_in_AI_path) {
|
|||
if (!FGAIShip::init(search_in_AI_path))
|
||||
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);
|
||||
_latitude_node = fgGetNode("/position/latitude-deg", true);
|
||||
_altitude_node = fgGetNode("/position/altitude-ft", true);
|
||||
|
@ -357,6 +344,27 @@ bool FGAICarrier::init(bool search_in_AI_path) {
|
|||
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() {
|
||||
FGAIShip::bind();
|
||||
|
||||
|
|
|
@ -103,6 +103,7 @@ public:
|
|||
bool OutsideBox();
|
||||
|
||||
bool init(bool search_in_AI_path=false);
|
||||
void initModel(osg::Node *node);
|
||||
|
||||
virtual const char* getTypeString(void) const { return "carrier"; }
|
||||
|
||||
|
|
|
@ -145,7 +145,7 @@ FGAIManager::update(double dt) {
|
|||
tmgr->release((*ai_list_itr)->getID());
|
||||
--mNumAiModels;
|
||||
--(mNumAiTypeModels[(*ai_list_itr)->getType()]);
|
||||
FGAIBase *base = *ai_list_itr;
|
||||
FGAIBase *base = (*ai_list_itr).get();
|
||||
SGPropertyNode *props = base->_getProps();
|
||||
|
||||
props->setBoolValue("valid", false);
|
||||
|
@ -162,7 +162,7 @@ FGAIManager::update(double dt) {
|
|||
} else {
|
||||
fetchUserState();
|
||||
if ((*ai_list_itr)->isa(FGAIBase::otThermal)) {
|
||||
FGAIBase *base = *ai_list_itr;
|
||||
FGAIBase *base = (*ai_list_itr).get();
|
||||
processThermal((FGAIThermal*)base);
|
||||
} else {
|
||||
(*ai_list_itr)->update(_dt);
|
||||
|
@ -175,7 +175,7 @@ FGAIManager::update(double dt) {
|
|||
}
|
||||
|
||||
void
|
||||
FGAIManager::attach(SGSharedPtr<FGAIBase> model)
|
||||
FGAIManager::attach(FGAIBase *model)
|
||||
{
|
||||
//unsigned idx = mNumAiTypeModels[model->getType()];
|
||||
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 name = scEntry->getStringValue("name");
|
||||
if (type == "carrier" && (pnumber == id || name == id)) {
|
||||
SGSharedPtr<FGAICarrier> carrier = new FGAICarrier;
|
||||
osg::ref_ptr<FGAICarrier> carrier = new FGAICarrier;
|
||||
carrier->readFromScenario(scEntry);
|
||||
|
||||
if (carrier->getParkPosition(pid, geodPos, hdng, uvw)) {
|
||||
|
@ -431,7 +431,7 @@ FGAIManager::calcCollision(double alt, double lat, double lon, double fuse_range
|
|||
<< " range " << range
|
||||
<< " alt " << tgt_alt
|
||||
);
|
||||
return *ai_list_itr;
|
||||
return (*ai_list_itr).get();
|
||||
}
|
||||
++ai_list_itr;
|
||||
}
|
||||
|
|
|
@ -46,13 +46,13 @@ class FGAIManager : public SGSubsystem
|
|||
public:
|
||||
|
||||
// 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::const_iterator ai_list_const_iterator;
|
||||
|
||||
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());
|
||||
return ai_list;
|
||||
}
|
||||
|
@ -66,7 +66,7 @@ public:
|
|||
void bind();
|
||||
void unbind();
|
||||
void update(double dt);
|
||||
void attach(SGSharedPtr<FGAIBase> model);
|
||||
void attach(FGAIBase *model);
|
||||
|
||||
void destroyObject( int ID );
|
||||
const FGAIBase *calcCollision(double alt, double lat, double lon, double fuse_range);
|
||||
|
|
11
src/AIModel/AIModelData.cxx
Normal file
11
src/AIModel/AIModelData.cxx
Normal 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);
|
||||
}
|
18
src/AIModel/AIModelData.hxx
Normal file
18
src/AIModel/AIModelData.hxx
Normal 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
|
|
@ -44,6 +44,7 @@ FGAIMultiplayer::~FGAIMultiplayer() {
|
|||
}
|
||||
|
||||
bool FGAIMultiplayer::init(bool search_in_AI_path) {
|
||||
props->setStringValue("sim/model/path", model_path.c_str());
|
||||
//refuel_node = fgGetNode("systems/refuel/contact", true);
|
||||
isTanker = false; // do this until this property is
|
||||
// passed over the net
|
||||
|
|
|
@ -3,6 +3,7 @@ noinst_LIBRARIES = libAIModel.a
|
|||
libAIModel_a_SOURCES = submodel.cxx submodel.hxx \
|
||||
AIManager.hxx AIManager.cxx \
|
||||
AIBase.hxx AIBase.cxx \
|
||||
AIModelData.cxx \
|
||||
AIAircraft.hxx AIAircraft.cxx \
|
||||
AIMultiplayer.hxx AIMultiplayer.cxx \
|
||||
AIShip.hxx AIShip.cxx \
|
||||
|
|
|
@ -514,7 +514,7 @@ void FGSubmodelMgr::loadAI()
|
|||
sm_list = ai->get_ai_list();
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -559,7 +559,7 @@ void FGSubmodelMgr::setData(int id, string& path, bool serviceable)
|
|||
"Submodels: Trying to read AI submodels file: " << config.str());
|
||||
readProperties(config.str(), &root);
|
||||
} 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());
|
||||
return;
|
||||
}
|
||||
|
@ -664,7 +664,7 @@ void FGSubmodelMgr::setSubData(int id, string& path, bool serviceable)
|
|||
readProperties(config.str(), &root);
|
||||
|
||||
} 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());
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -173,7 +173,7 @@ private:
|
|||
IC_struct IC;
|
||||
|
||||
// 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::const_iterator sm_list_const_iterator;
|
||||
|
||||
|
|
|
@ -22,7 +22,6 @@
|
|||
#define _FG_AIEntity_HXX
|
||||
|
||||
#include <simgear/math/point3d.hxx>
|
||||
#include <simgear/scene/model/model.hxx>
|
||||
#include <simgear/scene/model/placement.hxx>
|
||||
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include <Main/globals.hxx>
|
||||
#include <simgear/misc/sg_path.hxx>
|
||||
#include <simgear/math/sg_random.h>
|
||||
#include <simgear/scene/model/modellib.hxx>
|
||||
#include <list>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
|
@ -48,6 +49,8 @@
|
|||
SG_USING_STD(list);
|
||||
SG_USING_STD(cout);
|
||||
|
||||
using namespace simgear;
|
||||
|
||||
FGAIMgr::FGAIMgr() {
|
||||
ATC = globals->get_ATC_mgr();
|
||||
initDone = false;
|
||||
|
@ -81,10 +84,7 @@ void FGAIMgr::init() {
|
|||
string planepath = "Aircraft/c172p/Models/c172p.xml";
|
||||
bool _loadedDefaultOK = true;
|
||||
try {
|
||||
_defaultModel = sgLoad3DModel( globals->get_fg_root(),
|
||||
planepath.c_str(),
|
||||
globals->get_props(),
|
||||
globals->get_sim_time_sec() );
|
||||
_defaultModel = SGModelLib::loadPagedModel(planepath.c_str(), globals->get_props());
|
||||
} catch(sg_exception&) {
|
||||
_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!
|
||||
// TODO - implement robust determination of availability of GA AI aircraft models
|
||||
planepath = "Aircraft/c172p/Models/c172p.ac";
|
||||
_defaultModel = sgLoad3DModel( globals->get_fg_root(),
|
||||
planepath.c_str(),
|
||||
globals->get_props(),
|
||||
globals->get_sim_time_sec() );
|
||||
_defaultModel = SGModelLib::loadPagedModel(planepath.c_str(), globals->get_props());
|
||||
}
|
||||
|
||||
planepath = "Aircraft/pa28-161/Models/pa28-161.ac";
|
||||
try {
|
||||
_piperModel = sgLoad3DModel( globals->get_fg_root(),
|
||||
planepath.c_str(),
|
||||
globals->get_props(),
|
||||
globals->get_sim_time_sec() );
|
||||
_piperModel = SGModelLib::loadPagedModel(planepath.c_str(), globals->get_props());
|
||||
} catch(sg_exception&) {
|
||||
_havePiperModel = false;
|
||||
}
|
||||
|
|
|
@ -22,7 +22,6 @@
|
|||
#define _FG_AI_PLANE_HXX
|
||||
|
||||
#include <simgear/math/point3d.hxx>
|
||||
#include <simgear/scene/model/model.hxx>
|
||||
|
||||
#include "AIEntity.hxx"
|
||||
#include "ATC.hxx"
|
||||
|
|
|
@ -67,7 +67,7 @@ SG_USING_STD(setfill);
|
|||
#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::const_iterator radar_list_const_iterator;
|
||||
|
||||
|
@ -617,7 +617,7 @@ wxRadarBg::update_aircraft()
|
|||
int selected_id = fgGetInt("/instrumentation/radar/selected-id", -1);
|
||||
|
||||
for (; it != end; ++it) {
|
||||
FGAIBase *ac = *it;
|
||||
FGAIBase *ac = (*it).get();
|
||||
int type = ac->getType();
|
||||
double lat = ac->_getLatitude();
|
||||
double lon = ac->_getLongitude();
|
||||
|
|
|
@ -260,6 +260,7 @@ static int status = 0;
|
|||
void fgOSExit(int code)
|
||||
{
|
||||
viewer->setDone(true);
|
||||
viewer->getDatabasePager()->cancel();
|
||||
status = code;
|
||||
}
|
||||
|
||||
|
|
|
@ -24,7 +24,6 @@
|
|||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <simgear/scene/model/modellib.hxx>
|
||||
#include <simgear/sound/soundmgr_openal.hxx>
|
||||
#include <simgear/structure/commands.hxx>
|
||||
#include <simgear/misc/sg_path.hxx>
|
||||
|
@ -92,7 +91,6 @@ FGGlobals::FGGlobals() :
|
|||
initial_state( NULL ),
|
||||
locale( NULL ),
|
||||
commands( SGCommandMgr::instance() ),
|
||||
model_lib( NULL ),
|
||||
acmodel( NULL ),
|
||||
model_mgr( NULL ),
|
||||
channel_options_list( NULL ),
|
||||
|
@ -127,35 +125,32 @@ FGGlobals::~FGGlobals()
|
|||
// shut down all subsystems, make sure we take down the
|
||||
// AIModels system first.
|
||||
subsystem_mgr->get_group(SGSubsystemMgr::GENERAL)->remove_subsystem("ai_model");
|
||||
delete subsystem_mgr;
|
||||
delete event_mgr;
|
||||
delete time_params;
|
||||
delete ephem;
|
||||
delete mag;
|
||||
delete matlib;
|
||||
delete route_mgr;
|
||||
delete current_panel;
|
||||
delete soundmgr;
|
||||
delete airports;
|
||||
delete subsystem_mgr;
|
||||
delete event_mgr;
|
||||
delete time_params;
|
||||
delete ephem;
|
||||
delete mag;
|
||||
delete matlib;
|
||||
delete route_mgr;
|
||||
delete current_panel;
|
||||
delete soundmgr;
|
||||
delete airports;
|
||||
|
||||
delete runways;
|
||||
delete ATC_mgr;
|
||||
delete AI_mgr;
|
||||
delete controls;
|
||||
delete viewmgr;
|
||||
delete runways;
|
||||
delete ATC_mgr;
|
||||
delete AI_mgr;
|
||||
delete controls;
|
||||
delete viewmgr;
|
||||
|
||||
delete initial_state;
|
||||
// //delete locale; Don't delete locale
|
||||
// delete commands;
|
||||
delete model_lib;
|
||||
delete acmodel;
|
||||
delete model_mgr;
|
||||
delete channel_options_list;
|
||||
delete initial_waypoints;
|
||||
delete scenery;
|
||||
//delete tile_mgr; // Don't delete tile manager yet, because loader thread problems
|
||||
delete io;
|
||||
delete fontcache;
|
||||
delete acmodel;
|
||||
delete model_mgr;
|
||||
delete channel_options_list;
|
||||
delete initial_waypoints;
|
||||
delete tile_mgr;
|
||||
delete scenery;
|
||||
delete io;
|
||||
delete fontcache;
|
||||
|
||||
delete navlist;
|
||||
delete loclist;
|
||||
|
@ -168,8 +163,6 @@ FGGlobals::~FGGlobals()
|
|||
delete fixlist;
|
||||
delete airwaynet;
|
||||
delete multiplayer_mgr;
|
||||
|
||||
delete props;
|
||||
}
|
||||
|
||||
|
||||
|
@ -272,7 +265,6 @@ FGGlobals::get_event_mgr () const
|
|||
void
|
||||
FGGlobals::saveInitialState ()
|
||||
{
|
||||
delete initial_state;
|
||||
initial_state = new SGPropertyNode();
|
||||
|
||||
if (!copyProperties(props, initial_state))
|
||||
|
|
|
@ -57,7 +57,6 @@ class SGEphemeris;
|
|||
class SGCommandMgr;
|
||||
class SGMagVar;
|
||||
class SGMaterialLib;
|
||||
class SGModelLib;
|
||||
class SGPropertyNode;
|
||||
class SGTime;
|
||||
class SGSoundMgr;
|
||||
|
@ -97,6 +96,13 @@ class FGGlobals
|
|||
|
||||
private:
|
||||
|
||||
// properties, destroy last
|
||||
SGPropertyNode_ptr props;
|
||||
SGPropertyNode_ptr initial_state;
|
||||
|
||||
// localization
|
||||
SGPropertyNode_ptr locale;
|
||||
|
||||
FGRenderer *renderer;
|
||||
SGSubsystemMgr *subsystem_mgr;
|
||||
SGEventMgr *event_mgr;
|
||||
|
@ -162,17 +168,8 @@ private:
|
|||
// viewer manager
|
||||
FGViewMgr *viewmgr;
|
||||
|
||||
// properties
|
||||
SGPropertyNode *props;
|
||||
SGPropertyNode *initial_state;
|
||||
|
||||
// localization
|
||||
SGPropertyNode *locale;
|
||||
|
||||
SGCommandMgr *commands;
|
||||
|
||||
SGModelLib *model_lib;
|
||||
|
||||
//FGFlightPlanDispatcher *fpDispatcher;
|
||||
|
||||
FGAircraftModel *acmodel;
|
||||
|
@ -299,12 +296,6 @@ public:
|
|||
|
||||
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 void set_aircraft_model (FGAircraftModel * model)
|
||||
|
|
|
@ -47,6 +47,8 @@
|
|||
#include <simgear/timing/sg_time.hxx>
|
||||
#include <simgear/math/sg_random.h>
|
||||
|
||||
#include <osgDB/Registry>
|
||||
|
||||
// Class references
|
||||
#include <simgear/ephemeris/ephemeris.hxx>
|
||||
#include <simgear/scene/model/modellib.hxx>
|
||||
|
@ -135,9 +137,9 @@ void fgUpdateTimeDepCalcs() {
|
|||
double lat = fgGetDouble("/sim/presets/latitude-deg");
|
||||
// We require just to have 50 meter scenery availabe around
|
||||
// the aircraft.
|
||||
double range = 50.0;
|
||||
if (globals->get_tile_mgr()->scenery_available(lat, lon, range)) {
|
||||
SG_LOG(SG_FLIGHT,SG_INFO, "Finally initializing fdm");
|
||||
double range = 1000.0;
|
||||
if (globals->get_scenery()->scenery_available(lat, lon, range)) {
|
||||
SG_LOG(SG_FLIGHT,SG_ALERT, "Finally initializing fdm");
|
||||
cur_fdm_state->init();
|
||||
if ( cur_fdm_state->get_bound() ) {
|
||||
cur_fdm_state->unbind();
|
||||
|
@ -766,7 +768,7 @@ static void fgIdleFunction ( void ) {
|
|||
// Initialize the material manager
|
||||
////////////////////////////////////////////////////////////////////
|
||||
globals->set_matlib( new SGMaterialLib );
|
||||
globals->set_model_lib(new SGModelLib);
|
||||
simgear::SGModelLib::init(globals->get_fg_root());
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -66,8 +66,6 @@
|
|||
#include <simgear/screen/extensions.hxx>
|
||||
#include <simgear/scene/material/matlib.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/util/SGUpdateVisitor.hxx>
|
||||
#include <simgear/scene/util/RenderConstants.hxx>
|
||||
|
|
|
@ -150,7 +150,7 @@ private:
|
|||
|
||||
SGPropertyNode_ptr view_number;
|
||||
vector<SGPropertyNode_ptr> config_list;
|
||||
typedef vector<FGViewer *> viewer_list;
|
||||
typedef vector<SGSharedPtr<FGViewer> > viewer_list;
|
||||
viewer_list views;
|
||||
|
||||
int current;
|
||||
|
|
|
@ -50,36 +50,17 @@ FGAircraftModel::~FGAircraftModel ()
|
|||
void
|
||||
FGAircraftModel::init ()
|
||||
{
|
||||
SGPath liveryPath;
|
||||
_aircraft = new SGModelPlacement;
|
||||
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 {
|
||||
osg::Node *model = fgLoad3DModelPanel( globals->get_fg_root(),
|
||||
path,
|
||||
globals->get_props(),
|
||||
globals->get_sim_time_sec(),
|
||||
liveryPath);
|
||||
osg::Node *model = fgLoad3DModelPanel( path, globals->get_props());
|
||||
_aircraft->init( model );
|
||||
} catch (const sg_exception &ex) {
|
||||
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, "(Falling back to glider.ac.)");
|
||||
osg::Node *model = fgLoad3DModelPanel( globals->get_fg_root(),
|
||||
"Models/Geometry/glider.ac",
|
||||
globals->get_props(),
|
||||
globals->get_sim_time_sec(),
|
||||
liveryPath);
|
||||
osg::Node *model = fgLoad3DModelPanel( "Models/Geometry/glider.ac",
|
||||
globals->get_props());
|
||||
_aircraft->init( model );
|
||||
}
|
||||
_selector->addChild(_aircraft->getSceneGraph(), true);
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
#include <osg/Geode>
|
||||
|
||||
#include <simgear/props/props.hxx>
|
||||
#include <simgear/scene/model/model.hxx>
|
||||
#include <simgear/scene/model/modellib.hxx>
|
||||
#include <simgear/scene/util/SGNodeMasks.hxx>
|
||||
|
||||
#include "panelnode.hxx"
|
||||
|
@ -21,12 +21,14 @@
|
|||
|
||||
SG_USING_STD(vector);
|
||||
|
||||
using namespace simgear;
|
||||
|
||||
static
|
||||
osg::Node* load_panel(SGPropertyNode *n)
|
||||
{
|
||||
osg::Geode* geode = new osg::Geode;
|
||||
geode->addDrawable(new FGPanelNode(n));
|
||||
return geode;
|
||||
osg::Geode* geode = new osg::Geode;
|
||||
geode->addDrawable(new FGPanelNode(n));
|
||||
return geode;
|
||||
}
|
||||
|
||||
|
||||
|
@ -35,14 +37,11 @@ osg::Node* load_panel(SGPropertyNode *n)
|
|||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
osg::Node *
|
||||
fgLoad3DModelPanel( const string &fg_root, const string &path,
|
||||
SGPropertyNode *prop_root,
|
||||
double sim_time_sec, const SGPath& livery )
|
||||
fgLoad3DModelPanel(const string &path, SGPropertyNode *prop_root)
|
||||
{
|
||||
osg::Node* node = sgLoad3DModel( fg_root, path, prop_root, sim_time_sec,
|
||||
load_panel, 0, livery );
|
||||
node->setNodeMask(~SG_NODEMASK_TERRAIN_BIT);
|
||||
return node;
|
||||
osg::Node* node = SGModelLib::loadModel(path, prop_root, load_panel);
|
||||
node->setNodeMask(~SG_NODEMASK_TERRAIN_BIT);
|
||||
return node;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -46,9 +46,7 @@ class FGLocation;
|
|||
* Subsystems should not normally invoke this function directly;
|
||||
* instead, they should use the SGModelLoader declared in loader.hxx.
|
||||
*/
|
||||
osg::Node *fgLoad3DModelPanel( const string& fg_root, const string &path,
|
||||
SGPropertyNode *prop_root,
|
||||
double sim_time_sec, const SGPath& livery );
|
||||
osg::Node *fgLoad3DModelPanel( const string &path, SGPropertyNode *prop_root);
|
||||
|
||||
|
||||
#endif // __MODEL_HXX
|
||||
|
|
|
@ -27,10 +27,11 @@
|
|||
|
||||
SG_USING_STD(vector);
|
||||
|
||||
using namespace simgear;
|
||||
|
||||
// OSGFIXME
|
||||
// extern SGShadowVolume *shadows;
|
||||
|
||||
|
||||
FGModelMgr::FGModelMgr ()
|
||||
: _models(fgGetNode("/models", true)),
|
||||
_listener(new Listener(this))
|
||||
|
@ -68,17 +69,12 @@ FGModelMgr::add_model (SGPropertyNode * node)
|
|||
SGModelPlacement *model = new SGModelPlacement;
|
||||
instance->model = model;
|
||||
instance->node = node;
|
||||
SGModelLib *model_lib = globals->get_model_lib();
|
||||
|
||||
const char *path = node->getStringValue("path", "Models/Geometry/glider.ac");
|
||||
osg::Node *object;
|
||||
|
||||
try {
|
||||
object = model_lib->load_model(
|
||||
globals->get_fg_root(),
|
||||
path,
|
||||
globals->get_props(),
|
||||
globals->get_sim_time_sec(), /*cache_object=*/false);
|
||||
object = SGModelLib::loadPagedModel(path, globals->get_props());
|
||||
} catch (const sg_throwable& t) {
|
||||
SG_LOG(SG_GENERAL, SG_ALERT, "Error loading " << path << ":\n "
|
||||
<< t.getFormattedMessage() << t.getOrigin());
|
||||
|
|
|
@ -799,7 +799,7 @@ FGMultiplayMgr::addMultiplayer(const std::string& callsign,
|
|||
const std::string& modelName)
|
||||
{
|
||||
if (0 < mMultiPlayerMap.count(callsign))
|
||||
return mMultiPlayerMap[callsign];
|
||||
return mMultiPlayerMap[callsign].get();
|
||||
|
||||
FGAIMultiplayer* mp = new FGAIMultiplayer;
|
||||
mp->setPath(modelName.c_str());
|
||||
|
@ -825,7 +825,7 @@ FGAIMultiplayer*
|
|||
FGMultiplayMgr::getMultiplayer(const std::string& callsign)
|
||||
{
|
||||
if (0 < mMultiPlayerMap.count(callsign))
|
||||
return mMultiPlayerMap[callsign];
|
||||
return mMultiPlayerMap[callsign].get();
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -83,7 +83,7 @@ private:
|
|||
FGAIMultiplayer* getMultiplayer(const std::string& callsign);
|
||||
|
||||
/// 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;
|
||||
|
||||
netSocket* mSocket;
|
||||
|
|
|
@ -32,7 +32,6 @@
|
|||
#include STL_STRING
|
||||
|
||||
#include <simgear/props/props.hxx>
|
||||
#include <simgear/scene/model/model.hxx>
|
||||
|
||||
#include <Main/globals.hxx>
|
||||
#include <Main/fg_props.hxx>
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
#include <simgear/scene/model/SGPagedLOD.hxx>
|
||||
#include "SceneryPager.hxx"
|
||||
#include <algorithm>
|
||||
#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,
|
||||
float priority, osg::FrameStamp* frameStamp)
|
||||
{
|
||||
|
|
|
@ -33,6 +33,11 @@ class SceneryPager : public osgDB::DatabasePager
|
|||
public:
|
||||
SceneryPager();
|
||||
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,
|
||||
float priority, osg::FrameStamp* frameStamp);
|
||||
// This is passed a ref_ptr so that it can "take ownership" of the
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
|
||||
#include <osgUtil/IntersectVisitor>
|
||||
|
||||
#include <simgear/constants.h>
|
||||
#include <simgear/debug/logstream.hxx>
|
||||
#include <simgear/scene/tgdb/userdata.hxx>
|
||||
#include <simgear/math/sg_geodesy.hxx>
|
||||
|
@ -37,9 +38,11 @@
|
|||
#include <simgear/scene/material/matlib.hxx>
|
||||
#include <simgear/scene/util/SGNodeMasks.hxx>
|
||||
#include <simgear/scene/util/SGSceneUserData.hxx>
|
||||
#include <simgear/scene/model/CheckSceneryVisitor.hxx>
|
||||
|
||||
#include <Main/fg_props.hxx>
|
||||
|
||||
#include "tilemgr.hxx"
|
||||
#include "scenery.hxx"
|
||||
|
||||
using namespace flightgear;
|
||||
|
@ -72,12 +75,11 @@ FGScenery::FGScenery()
|
|||
SG_LOG( SG_TERRAIN, SG_INFO, "Initializing scenery subsystem" );
|
||||
}
|
||||
|
||||
|
||||
// Initialize the Scenery Management system
|
||||
FGScenery::~FGScenery() {
|
||||
}
|
||||
|
||||
|
||||
// Initialize the Scenery Management system
|
||||
void FGScenery::init() {
|
||||
// Scene graph root
|
||||
scene_graph = new osg::Group;
|
||||
|
@ -100,8 +102,7 @@ void FGScenery::init() {
|
|||
scene_graph->addChild( aircraft_branch.get() );
|
||||
|
||||
// Initials values needed by the draw-time object loader
|
||||
sgUserDataInit( globals->get_model_lib(), globals->get_fg_root(),
|
||||
globals->get_props(), globals->get_sim_time_sec() );
|
||||
sgUserDataInit( globals->get_props() );
|
||||
}
|
||||
|
||||
|
||||
|
@ -211,6 +212,25 @@ FGScenery::get_cart_ground_intersection(const SGVec3d& pos, const SGVec3d& dir,
|
|||
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()
|
||||
{
|
||||
static osg::ref_ptr<SceneryPager> pager = new SceneryPager;
|
||||
|
|
|
@ -102,6 +102,11 @@ public:
|
|||
osg::Group *get_models_branch () const { return models_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
|
||||
// the scenery is initialized.
|
||||
static flightgear::SceneryPager* getPagerSingleton();
|
||||
|
|
|
@ -436,7 +436,7 @@ FGTileEntry::loadTileByName(const string& index_str,
|
|||
if ( obj->type == OBJECT_STATIC ) {
|
||||
custom_path = obj->path;
|
||||
} else {
|
||||
custom_path = globals->get_fg_root();
|
||||
// custom_path = globals->get_fg_root();
|
||||
}
|
||||
custom_path.append( obj->name );
|
||||
|
||||
|
|
|
@ -50,6 +50,7 @@
|
|||
|
||||
using std::for_each;
|
||||
using flightgear::SceneryPager;
|
||||
using simgear::SGModelLib;
|
||||
|
||||
#define TEST_LAST_HIT_CACHE
|
||||
|
||||
|
@ -244,13 +245,18 @@ FGTileMgr::loadTileModel(const string& modelPath, bool cacheModel)
|
|||
{
|
||||
osg::Node* result = 0;
|
||||
try {
|
||||
result =
|
||||
globals->get_model_lib()->load_model(".",
|
||||
modelPath,
|
||||
globals->get_props(),
|
||||
globals->get_sim_time_sec(),
|
||||
cacheModel,
|
||||
new FGNasalModelData );
|
||||
if(cacheModel)
|
||||
{
|
||||
result =
|
||||
SGModelLib::loadModel(modelPath, globals->get_props(),
|
||||
new FGNasalModelData);
|
||||
}
|
||||
else
|
||||
{
|
||||
result=
|
||||
SGModelLib::loadPagedModel(modelPath, globals->get_props(),
|
||||
new FGNasalModelData);
|
||||
}
|
||||
} catch (const sg_io_exception& exc) {
|
||||
string m(exc.getMessage());
|
||||
m += " ";
|
||||
|
|
|
@ -1082,12 +1082,16 @@ bool FGNasalListener::changed(SGPropertyNode* node)
|
|||
void FGNasalModelData::modelLoaded(const string& path, SGPropertyNode *prop,
|
||||
osg::Node *)
|
||||
{
|
||||
if(!prop)
|
||||
return;
|
||||
|
||||
/*
|
||||
SGPropertyNode *n = prop->getNode("nasal"), *load;
|
||||
if(!n)
|
||||
return;
|
||||
|
||||
load = n->getNode("load");
|
||||
_unload = n->getNode("unload");
|
||||
*/
|
||||
SGPropertyNode *load = load = prop->getNode("load");
|
||||
_unload = prop->getNode("unload");
|
||||
if(!load && !_unload)
|
||||
return;
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
#include <simgear/misc/sg_path.hxx>
|
||||
#include <simgear/structure/subsystem_mgr.hxx>
|
||||
#include <simgear/nasal/nasal.h>
|
||||
#include <simgear/scene/model/model.hxx>
|
||||
#include <simgear/scene/model/modellib.hxx>
|
||||
#include <simgear/xml/easyxml.hxx>
|
||||
|
||||
#include <map>
|
||||
|
@ -159,7 +159,7 @@ private:
|
|||
};
|
||||
|
||||
|
||||
class FGNasalModelData : public SGModelData {
|
||||
class FGNasalModelData : public simgear::SGModelData {
|
||||
public:
|
||||
FGNasalModelData(SGPropertyNode *props = 0) : _props(props), _unload(0) {}
|
||||
~FGNasalModelData();
|
||||
|
|
Loading…
Reference in a new issue