1
0
Fork 0
flightgear/src/Scenery/terrain_pgt.cxx
Richard Harrison f05c0297c0 OSG < 3.4.x fixes
This will use the inherently unsafe versions of the load methods which can result in deleting an object (from the cache) that has just been loaded in the database thread.

Symptom OSG WARN deleting still referenced object.

branches next, origin/next
2019-01-26 18:20:52 +01:00

255 lines
8.1 KiB
C++

// terrain_pgt.cxx -- data structures and routines for managing scenery.
//
// Written by Curtis Olson, started May 1997.
//
// Copyright (C) 1997 Curtis L. Olson - http://www.flightgear.org/~curt
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
// $Id$
#include <config.h>
#include <simgear/simgear_config.h>
#ifdef ENABLE_GDAL
#include <boost/lexical_cast.hpp>
#include <simgear/scene/material/mat.hxx>
#include <simgear/scene/util/SGReaderWriterOptions.hxx>
#include <Main/globals.hxx>
#include <Main/fg_props.hxx>
#include <Viewer/splash.hxx>
#include "terrain_pgt.hxx"
#include "scenery.hxx"
using namespace flightgear;
using namespace simgear;
using flightgear::SceneryPager;
// Terrain Management system
FGPgtTerrain::FGPgtTerrain() :
_scenery_loaded(fgGetNode("/sim/sceneryloaded", true)),
_scenery_override(fgGetNode("/sim/sceneryloaded-override", true))
{
_inited = false;
}
FGPgtTerrain::~FGPgtTerrain()
{
}
// Initialize the Scenery Management system
void FGPgtTerrain::init( osg::Group* terrain ) {
// Already set up.
if (_inited)
return;
SG_LOG(SG_TERRAIN, SG_INFO, "FGPgtTerrain::init");
// remember the scene terrain branch on scenegraph
terrain_branch = terrain;
// load the whole planet tile - database pager handles
// the quad tree / loading the highres tiles
osg::ref_ptr<simgear::SGReaderWriterOptions> options;
// drops the previous options reference
options = new simgear::SGReaderWriterOptions;
options->setPropertyNode(globals->get_props());
osgDB::FilePathList &fp = options->getDatabasePathList();
const PathList &sc = globals->get_fg_scenery();
fp.clear();
PathList::const_iterator it;
for (it = sc.begin(); it != sc.end(); ++it) {
fp.push_back(it->local8BitStr());
}
options->setPluginStringData("SimGear::FG_ROOT", globals->get_fg_root().local8BitStr());
options->setPluginStringData("SimGear::BARE_LOD_RANGE", fgGetString("/sim/rendering/static-lod/bare-delta", boost::lexical_cast<string>(SG_OBJECT_RANGE_BARE)));
options->setPluginStringData("SimGear::ROUGH_LOD_RANGE", fgGetString("/sim/rendering/static-lod/rough-delta", boost::lexical_cast<string>(SG_OBJECT_RANGE_ROUGH)));
options->setPluginStringData("SimGear::ROUGH_LOD_DETAILED", fgGetString("/sim/rendering/static-lod/detailed", boost::lexical_cast<string>(SG_OBJECT_RANGE_DETAILED)));
options->setPluginStringData("SimGear::RENDER_BUILDING_MESH", fgGetBool("/sim/rendering/building-mesh", false) ? "true" : "false");
options->setPluginStringData("SimGear::FG_EARTH", "ON");
// tunables
options->setPluginStringData("SimGear::SPT_PAGE_LEVELS", fgGetString("/sim/scenery/lod-levels", "1 3 5 7 9" ));
options->setPluginStringData("SimGear::SPT_RANGE_MULTIPLIER", fgGetString("/sim/scenery/lod-range-mult", "2" ));
options->setPluginStringData("SimGear::SPT_MESH_RESOLUTION", fgGetString("/sim/scenery/lod-res", "1" ));
options->setPluginStringData("SimGear::SPT_LOD_TEXTURING", fgGetString("/sim/scenery/lod-texturing", "bluemarble" ));
options->setMaterialLib(globals->get_matlib());
// a DEM can contain multiple levels from multiple locations
// priority is based on first found...
_dem = new SGDem;
if ( _dem ) {
for (osgDB::FilePathList::const_iterator i = fp.begin(); i != fp.end(); ++i) {
SGPath demPath(*i);
demPath.append("DEM");
int numLevels = _dem->addRoot(demPath);
if ( numLevels ) {
SG_LOG(SG_TERRAIN, SG_INFO, "Terrain init - dem path " << demPath << " has " << numLevels << " LOD Levels " );
} else {
SG_LOG(SG_TERRAIN, SG_INFO, "Terrain init - dem path " << demPath << " has NO LOD Levels " );
}
}
options->setDem(_dem);
SG_LOG(SG_TERRAIN, SG_INFO, "Terrain init - Load w180s90-360x180.pgt" );
#if OSG_VERSION_LESS_THAN(3,4,0)
osg::ref_ptr<osg::Node> loadedModel = osgDB::readNodeFile("w180s90-360x180.pgt", options.get());
#else
osg::ref_ptr<osg::Node> loadedModel = osgDB::readRefNodeFile("w180s90-360x180.pgt", options.get());
#endif
if ( loadedModel ) {
terrain_branch->addChild( loadedModel.get() );
// Toggle the setup flag.
_inited = true;
}
}
}
void FGPgtTerrain::reinit()
{
}
void FGPgtTerrain::shutdown()
{
terrain_branch = NULL;
// Toggle the setup flag.
_inited = false;
}
void FGPgtTerrain::update(double dt)
{
// scenery loading check, triggers after each sim (tile manager) reinit
if (!_scenery_loaded->getBoolValue())
{
bool fdmInited = fgGetBool("sim/fdm-initialized");
bool positionFinalized = fgGetBool("sim/position-finalized");
bool sceneryOverride = _scenery_override->getBoolValue();
// we are done if final position is set and the scenery & FDM are done.
// scenery-override can ignore the last two, but not position finalization.
if (positionFinalized && (sceneryOverride || fdmInited))
{
_scenery_loaded->setBoolValue(true);
fgSplashProgress("");
}
else
{
if (!positionFinalized) {
fgSplashProgress("finalize-position");
} else {
fgSplashProgress("loading-scenery");
}
// be nice to loader threads while waiting for initial scenery, reduce to 20fps
SGTimeStamp::sleepForMSec(50);
}
}
}
void FGPgtTerrain::bind()
{
}
void FGPgtTerrain::unbind()
{
}
bool
FGPgtTerrain::get_cart_elevation_m(const SGVec3d& pos, double max_altoff,
double& alt,
const simgear::BVHMaterial** material,
const osg::Node* butNotFrom)
{
SGGeod geod = SGGeod::fromCart(pos);
geod.setElevationM(geod.getElevationM() + max_altoff);
return get_elevation_m(geod, alt, material, butNotFrom);
}
static simgear::BVHMaterial def_mat;
bool
FGPgtTerrain::get_elevation_m(const SGGeod& geod, double& alt,
const simgear::BVHMaterial** material,
const osg::Node* butNotFrom)
{
alt = 100.0;
if (material) {
*material = &def_mat;
} else {
// SG_LOG(SG_TERRAIN, SG_INFO, "FGStgTerrain::get_elevation_m: alt " << alt << " no material " );
}
return true;
}
bool FGPgtTerrain::get_cart_ground_intersection(const SGVec3d& pos, const SGVec3d& dir,
SGVec3d& nearestHit,
const osg::Node* butNotFrom)
{
return true;
}
bool FGPgtTerrain::scenery_available(const SGGeod& position, double range_m)
{
if( schedule_scenery(position, range_m, 0.0) )
{
return true;
}
else
{
return false;
}
}
bool FGPgtTerrain::schedule_scenery(const SGGeod& position, double range_m, double duration)
{
// sanity check (unfortunately needed!)
if (!position.isValid()) {
SG_LOG(SG_TERRAIN, SG_INFO, "FGSptTerrain::schedule_scenery - position invalid");
return false;
}
return true;
}
void FGPgtTerrain::materialLibChanged()
{
// PSADRO: TODO - passing down new regional textures won't work. these need to be set in the
// lod tree at init time, as OSGDBPager generates the load request, not the tile cache.
// _options->setMaterialLib(globals->get_matlib());
}
#endif