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/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);

View file

@ -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();

View file

@ -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();
}

View file

@ -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,10 +267,8 @@ 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();
};

View file

@ -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();

View file

@ -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"; }

View file

@ -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;
}

View file

@ -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);

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) {
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

View file

@ -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 \

View file

@ -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;
}

View file

@ -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;

View file

@ -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>

View file

@ -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;
}

View file

@ -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"

View file

@ -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();

View file

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

View file

@ -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))

View file

@ -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)

View file

@ -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());
////////////////////////////////////////////////////////////////////

View file

@ -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>

View file

@ -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;

View file

@ -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);

View file

@ -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;
}

View file

@ -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

View file

@ -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());

View file

@ -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;
}

View file

@ -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;

View file

@ -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>

View file

@ -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)
{

View file

@ -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

View file

@ -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;

View file

@ -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();

View file

@ -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 );

View file

@ -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 += " ";

View file

@ -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;

View file

@ -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();