f05c0297c0
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
255 lines
8.1 KiB
C++
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
|