FlightGear next
terrain_pgt.cxx
Go to the documentation of this file.
1// terrain_pgt.cxx -- data structures and routines for managing scenery.
2//
3// Written by Curtis Olson, started May 1997.
4//
5// Copyright (C) 1997 Curtis L. Olson - http://www.flightgear.org/~curt
6//
7// This program is free software; you can redistribute it and/or
8// modify it under the terms of the GNU General Public License as
9// published by the Free Software Foundation; either version 2 of the
10// License, or (at your option) any later version.
11//
12// This program is distributed in the hope that it will be useful, but
13// WITHOUT ANY WARRANTY; without even the implied warranty of
14// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15// General Public License for more details.
16//
17// You should have received a copy of the GNU General Public License
18// along with this program; if not, write to the Free Software
19// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20//
21// $Id$
22
23
24#include <config.h>
25#include <simgear/simgear_config.h>
26
27#ifdef ENABLE_GDAL
28
29#include <simgear/scene/material/mat.hxx>
30#include <simgear/scene/util/SGReaderWriterOptions.hxx>
31
32#include <Main/globals.hxx>
33#include <Main/fg_props.hxx>
34#include <Viewer/splash.hxx>
35
36#include "terrain_pgt.hxx"
37#include "scenery.hxx"
38
39using namespace flightgear;
40using namespace simgear;
41
43
44// Terrain Management system
46 _scenery_loaded(fgGetNode("/sim/sceneryloaded", true)),
47 _scenery_override(fgGetNode("/sim/sceneryloaded-override", true))
48{
49 _inited = false;
50}
51
53{
54}
55
56// Initialize the Scenery Management system
57void FGPgtTerrain::init( osg::Group* terrain ) {
58 // Already set up.
59 if (_inited)
60 return;
61
62 SG_LOG(SG_TERRAIN, SG_INFO, "FGPgtTerrain::init");
63
64 // remember the scene terrain branch on scenegraph
65 terrain_branch = terrain;
66
67 // load the whole planet tile - database pager handles
68 // the quad tree / loading the highres tiles
69 osg::ref_ptr<simgear::SGReaderWriterOptions> options;
70
71 // drops the previous options reference
72 options = new simgear::SGReaderWriterOptions;
73 options->setPropertyNode(globals->get_props());
74
75 osgDB::FilePathList &fp = options->getDatabasePathList();
76 const PathList &sc = globals->get_fg_scenery();
77 fp.clear();
78 PathList::const_iterator it;
79 for (it = sc.begin(); it != sc.end(); ++it) {
80 fp.push_back(it->local8BitStr());
81 }
82
83 options->setPluginStringData("SimGear::FG_ROOT", globals->get_fg_root().utf8Str());
84
85 options->setPluginStringData("SimGear::BARE_LOD_RANGE",
86 fgGetString("/sim/rendering/static-lod/bare-delta",
87 std::to_string(SG_OBJECT_RANGE_BARE)));
88 options->setPluginStringData("SimGear::ROUGH_LOD_RANGE",
89 fgGetString("/sim/rendering/static-lod/rough-delta",
90 std::to_string(SG_OBJECT_RANGE_ROUGH)));
91 options->setPluginStringData("SimGear::ROUGH_LOD_DETAILED",
92 fgGetString("/sim/rendering/static-lod/detailed",
93 std::to_string(SG_OBJECT_RANGE_DETAILED)));
94 options->setPluginStringData("SimGear::RENDER_BUILDING_MESH", fgGetBool("/sim/rendering/building-mesh", false) ? "true" : "false");
95
96 options->setPluginStringData("SimGear::FG_EARTH", "ON");
97
98 // tunables
99 options->setPluginStringData("SimGear::SPT_PAGE_LEVELS", fgGetString("/sim/scenery/lod-levels", "1 3 5 7 9" ));
100 options->setPluginStringData("SimGear::SPT_RANGE_MULTIPLIER", fgGetString("/sim/scenery/lod-range-mult", "2" ));
101 options->setPluginStringData("SimGear::SPT_MESH_RESOLUTION", fgGetString("/sim/scenery/lod-res", "1" ));
102 options->setPluginStringData("SimGear::SPT_LOD_TEXTURING", fgGetString("/sim/scenery/lod-texturing", "bluemarble" ));
103 options->setMaterialLib(globals->get_matlib());
104
105 // a DEM can contain multiple levels from multiple locations
106 // priority is based on first found...
107 _dem = new SGDem;
108 if ( _dem ) {
109 for (osgDB::FilePathList::const_iterator i = fp.begin(); i != fp.end(); ++i) {
110 SGPath demPath(*i);
111 demPath.append("DEM");
112
113 int numLevels = _dem->addRoot(demPath);
114 if ( numLevels ) {
115 SG_LOG(SG_TERRAIN, SG_INFO, "Terrain init - dem path " << demPath << " has " << numLevels << " LOD Levels " );
116 } else {
117 SG_LOG(SG_TERRAIN, SG_INFO, "Terrain init - dem path " << demPath << " has NO LOD Levels " );
118 }
119 }
120
121 options->setDem(_dem);
122
123 SG_LOG(SG_TERRAIN, SG_INFO, "Terrain init - Load w180s90-360x180.pgt" );
124 osg::ref_ptr<osg::Node> loadedModel = osgDB::readRefNodeFile("w180s90-360x180.pgt", options.get());
125
126 if ( loadedModel ) {
127 terrain_branch->addChild( loadedModel.get() );
128
129 // Toggle the setup flag.
130 _inited = true;
131 }
132 }
133}
134
136{
137
138}
139
141{
142 terrain_branch = NULL;
143
144 // Toggle the setup flag.
145 _inited = false;
146}
147
148
149void FGPgtTerrain::update(double dt)
150{
151 // scenery loading check, triggers after each sim (tile manager) reinit
152 if (!_scenery_loaded->getBoolValue())
153 {
154 bool fdmInited = fgGetBool("sim/fdm-initialized");
155 bool positionFinalized = fgGetBool("sim/position-finalized");
156 bool sceneryOverride = _scenery_override->getBoolValue();
157
158 // we are done if final position is set and the scenery & FDM are done.
159 // scenery-override can ignore the last two, but not position finalization.
160 if (positionFinalized && (sceneryOverride || fdmInited))
161 {
162 _scenery_loaded->setBoolValue(true);
164 }
165 else
166 {
167 if (!positionFinalized) {
168 fgSplashProgress("finalize-position");
169 } else {
170 fgSplashProgress("loading-scenery");
171 }
172
173 // be nice to loader threads while waiting for initial scenery, reduce to 20fps
174 SGTimeStamp::sleepForMSec(50);
175 }
176 }
177}
178
179void FGPgtTerrain::bind()
180{
181
182}
183
185{
186
187}
188
189bool
190FGPgtTerrain::get_cart_elevation_m(const SGVec3d& pos, double max_altoff,
191 double& alt,
192 const simgear::BVHMaterial** material,
193 const osg::Node* butNotFrom)
194{
195 SGGeod geod = SGGeod::fromCart(pos);
196 geod.setElevationM(geod.getElevationM() + max_altoff);
197
198 return get_elevation_m(geod, alt, material, butNotFrom);
199}
200
201static simgear::BVHMaterial def_mat;
202
203bool
204FGPgtTerrain::get_elevation_m(const SGGeod& geod, double& alt,
205 const simgear::BVHMaterial** material,
206 const osg::Node* butNotFrom)
207{
208 alt = 100.0;
209 if (material) {
210 *material = &def_mat;
211 } else {
212// SG_LOG(SG_TERRAIN, SG_INFO, "FGStgTerrain::get_elevation_m: alt " << alt << " no material " );
213 }
214
215 return true;
216}
217
218bool FGPgtTerrain::get_cart_ground_intersection(const SGVec3d& pos, const SGVec3d& dir,
219 SGVec3d& nearestHit,
220 const osg::Node* butNotFrom)
221{
222 return true;
223}
224
225bool FGPgtTerrain::scenery_available(const SGGeod& position, double range_m)
226{
227 if( schedule_scenery(position, range_m, 0.0) )
228 {
229 return true;
230 }
231 else
232 {
233 return false;
234 }
235}
236
237bool FGPgtTerrain::schedule_scenery(const SGGeod& position, double range_m, double duration)
238{
239 // sanity check (unfortunately needed!)
240 if (!position.isValid()) {
241 SG_LOG(SG_TERRAIN, SG_INFO, "FGSptTerrain::schedule_scenery - position invalid");
242 return false;
243 }
244
245 return true;
246}
247
249{
250 // PSADRO: TODO: passing down new regional textures won't work. these need to be set in the
251 // lod tree at init time, as OSGDBPager generates the load request, not the tile cache.
252
253 // _options->setMaterialLib(globals->get_matlib());
254}
255
256#endif
bool options(int, char **)
Definition JSBSim.cpp:568
#define i(x)
SGPropertyNode * get_props()
Definition globals.hxx:320
const PathList & get_fg_scenery() const
Definition globals.hxx:234
const SGPath & get_fg_root() const
Definition globals.hxx:189
SGMaterialLib * get_matlib() const
Definition globals.hxx:314
bool scenery_available(const SGGeod &position, double range_m)
Returns true if scenery is available for the given lat, lon position within a range of range_m.
void shutdown()
bool get_cart_ground_intersection(const SGVec3d &start, const SGVec3d &dir, SGVec3d &nearestHit, const osg::Node *butNotFrom=0)
Compute the nearest intersection point of the line starting from start going in direction dir with th...
void init(osg::Group *terrain)
void update(double dt)
bool schedule_scenery(const SGGeod &position, double range_m, double duration=0.0)
bool get_elevation_m(const SGGeod &geod, double &alt, const simgear::BVHMaterial **material, const osg::Node *butNotFrom=0)
Compute the elevation of the scenery at geodetic latitude lat, geodetic longitude lon and not higher ...
bool get_cart_elevation_m(const SGVec3d &pos, double max_altoff, double &elevation, const simgear::BVHMaterial **material, const osg::Node *butNotFrom=0)
Compute the elevation of the scenery below the cartesian point pos.
void materialLibChanged()
std::string fgGetString(const char *name, const char *defaultValue)
Get a string value for a property.
Definition fg_props.cxx:556
FGGlobals * globals
Definition globals.cxx:142
std::vector< SGPath > PathList
Definition globals.hxx:37
FlightPlan.hxx - defines a full flight-plan object, including departure, cruise, arrival information ...
Definition Addon.cxx:53
bool fgGetBool(char const *name, bool def)
Get a bool value for a property.
Definition proptest.cpp:25
SGPropertyNode * fgGetNode(const char *path, bool create)
Get a property node.
Definition proptest.cpp:27
void fgSplashProgress(const char *identifier, unsigned int percent)
Set progress information.
Definition splash.cxx:863