From: "Jim Wilson" <jimw@kelcomaine.com>
This is a new improved patch for the previous tile manager fixes. Rather than building dependencies between FGlocation or the viewer or fdm with tilemgr what I ended up doing was linking the pieces together in the Mainloop in main.cxx. You'll see what I mean...it's been commented fairly well. More than likely we should move that chunk somewhere...just not sure where yet. The changes seem clean now. As I get more ideas there could be some further improvement in organizing the update in tilemgr. You'll note that I left an override in there for the tilemgr::update() function to preserve earlier functionality if someone needs it (e.g. usage independent of an fdm or viewer), not to mention there are a few places in flightgear that call it directly that have not been changed to the new interface (and may not need to be). The code has been optimized to avoid duplicate traversals and seems to run generally quite well. Note that there can be a short delay reloading tiles that have been dropped from static views. We could call the tile scheduler on a view switch, but it's not a big deal and at the moment I'd like to get this in so people can try it and comment on it as it is. Everything has been resycned with CVS tonight and I've included the description submitted earlier (below). Best, Jim Changes synced with CVS approx 20:30EDT 2002-05-09 (after this evenings updates). Files: http://www.spiderbark.com/fgfs/viewer-update-20020516.tar.gz or http://www.spiderbark.com/fgfs/viewer-update-20020516.diffs.gz Description: In a nutshell, these patches begin to take what was one value for ground elevation and calculate ground elevation values seperately for the FDM and the viewer (eye position). Several outstanding view related bugs have been fixed. With the introduction of the new viewer code a lot of that Flight Gear code broke related to use of a global variable called "scenery.cur_elev". Therefore the ground_elevation and other associated items (like the current tile bucket) is maintained per FDM instance and per View. Each of these has a "point" or location that can be identified. See changes to FGLocation class and main.cxx. Most of the problems related to the new viewer in terms of sky, ground and runway lights, and tower views are fixed. There are four minor problems remaining. 1) The sun/moon spins when you pan the "lookat" tower view only (view #3). 2) Under stress (esp. magic carpet full speed with max visibility), there is a memory leak in the tile caching that was not introduced with these changes. 3) I have not tested these changes or made corrections to the ADA or External FDM interfaces. 4) The change view function doesn't call the time/light update (not a problem unless a tower is very far away). Details: FDM/flight.cxx, flight.hxx - FGInterface ties to FGAircraftModel so that it's location data can be accessed for runway (ground elevation under aircraft) elevation. FDM/larsim.cxx, larcsim.hxx - gets runway elevation from FGInterface now. Commented out function that is causing a namespace conflict, hasn't been called with recent code anyway. FDM/JSBSim/JSBSim.cxx, YASim/YASim.cxx - gets runway elevation from FGInterface now. Scenery/newcache.cxx, newcache.hxx - changed caching scheme to time based (oldest tiles discard). Scenery/tileentry.cxx, tileentry.hxx - added place to record time, changed rendering to reference viewer altitude in order to fix a problem with ground and runway lights. Scenery/tilemgr.cxx, tilemgr.hxx - Modified update() to accept values for multiple locations. Refresh function added in order to periodically make the tiles current for a non-moving view (like a tower). Main/fg_init.cxx - register event for making tiles current in a non-moving view (like a tower). Main/location.hxx - added support for current ground elevation data. Main/main.cxx - added second tilemgr call for fdm, fixed places where viewer position data was required for correct sky rendering. Main/options.cxx - fixed segfault reported by Curtis when using --view-offset command line parameter. Main/viewer.cxx, viewer.hxx - removed fudging of view position. Fixed numerous bugs that were causing eye and target values to get mixed up.
This commit is contained in:
parent
e8a6836525
commit
b1674cb506
18 changed files with 559 additions and 414 deletions
|
@ -34,7 +34,7 @@
|
|||
#include <simgear/math/sg_geodesy.hxx>
|
||||
#include <simgear/misc/sg_path.hxx>
|
||||
|
||||
#include <Scenery/scenery.hxx>
|
||||
#include <FDM/flight.hxx>
|
||||
|
||||
#include <Aircraft/aircraft.hxx>
|
||||
#include <Controls/controls.hxx>
|
||||
|
@ -291,9 +291,8 @@ FGJSBsim::update( double dt ) {
|
|||
if ( startup_trim->getBoolValue() ) {
|
||||
SG_LOG(SG_FLIGHT, SG_INFO,
|
||||
"Ready to trim, terrain altitude is: "
|
||||
<< globals->get_scenery()->get_cur_elev() * SG_METER_TO_FEET );
|
||||
fgic->SetTerrainAltitudeFtIC( globals->get_scenery()->get_cur_elev()
|
||||
* SG_METER_TO_FEET );
|
||||
<< cur_fdm_state->get_Runway_altitude() * SG_METER_TO_FEET );
|
||||
fgic->SetTerrainAltitudeFtIC( cur_fdm_state->get_ground_elev_ft() );
|
||||
do_trim();
|
||||
} else {
|
||||
fdmex->RunIC(fgic); //apply any changes made through the set_ functions
|
||||
|
@ -370,8 +369,7 @@ bool FGJSBsim::copy_to_JSBsim() {
|
|||
eng->SetStarter( globals->get_controls()->get_starter(i) );
|
||||
}
|
||||
|
||||
_set_Runway_altitude( globals->get_scenery()->get_cur_elev()
|
||||
* SG_METER_TO_FEET );
|
||||
_set_Runway_altitude( cur_fdm_state->get_Runway_altitude() );
|
||||
Position->SetSeaLevelRadius( get_Sea_level_radius() );
|
||||
Position->SetRunwayRadius( get_Runway_altitude()
|
||||
+ get_Sea_level_radius() );
|
||||
|
@ -588,10 +586,8 @@ void FGJSBsim::set_Latitude(double lat) {
|
|||
&sea_level_radius_meters, &lat_geoc );
|
||||
_set_Sea_level_radius( sea_level_radius_meters * SG_METER_TO_FEET );
|
||||
fgic->SetSeaLevelRadiusFtIC( sea_level_radius_meters * SG_METER_TO_FEET );
|
||||
_set_Runway_altitude( globals->get_scenery()->get_cur_elev()
|
||||
* SG_METER_TO_FEET );
|
||||
fgic->SetTerrainAltitudeFtIC( globals->get_scenery()->get_cur_elev()
|
||||
* SG_METER_TO_FEET );
|
||||
_set_Runway_altitude( cur_fdm_state->get_Runway_altitude() );
|
||||
fgic->SetTerrainAltitudeFtIC( cur_fdm_state->get_ground_elev_ft() );
|
||||
fgic->SetLatitudeRadIC( lat_geoc );
|
||||
needTrim=true;
|
||||
}
|
||||
|
@ -601,10 +597,8 @@ void FGJSBsim::set_Longitude(double lon) {
|
|||
SG_LOG(SG_FLIGHT,SG_INFO,"FGJSBsim::set_Longitude: " << lon );
|
||||
update_ic();
|
||||
fgic->SetLongitudeRadIC( lon );
|
||||
_set_Runway_altitude( globals->get_scenery()->get_cur_elev()
|
||||
* SG_METER_TO_FEET );
|
||||
fgic->SetTerrainAltitudeFtIC( globals->get_scenery()->get_cur_elev()
|
||||
* SG_METER_TO_FEET );
|
||||
_set_Runway_altitude( cur_fdm_state->get_Runway_altitude() );
|
||||
fgic->SetTerrainAltitudeFtIC( cur_fdm_state->get_ground_elev_ft() );
|
||||
needTrim=true;
|
||||
}
|
||||
|
||||
|
@ -621,13 +615,10 @@ void FGJSBsim::set_Altitude(double alt) {
|
|||
&sea_level_radius_meters, &lat_geoc);
|
||||
_set_Sea_level_radius( sea_level_radius_meters * SG_METER_TO_FEET );
|
||||
fgic->SetSeaLevelRadiusFtIC( sea_level_radius_meters * SG_METER_TO_FEET );
|
||||
_set_Runway_altitude( globals->get_scenery()->get_cur_elev()
|
||||
* SG_METER_TO_FEET );
|
||||
fgic->SetTerrainAltitudeFtIC( globals->get_scenery()->get_cur_elev()
|
||||
* SG_METER_TO_FEET );
|
||||
_set_Runway_altitude( cur_fdm_state->get_Runway_altitude() );
|
||||
fgic->SetTerrainAltitudeFtIC( cur_fdm_state->get_ground_elev_ft() );
|
||||
SG_LOG(SG_FLIGHT, SG_INFO,
|
||||
"Terrain altitude: " << globals->get_scenery()->get_cur_elev()
|
||||
* SG_METER_TO_FEET );
|
||||
"Terrain altitude: " << cur_fdm_state->get_Runway_altitude() * SG_METER_TO_FEET );
|
||||
fgic->SetLatitudeRadIC( lat_geoc );
|
||||
fgic->SetAltitudeFtIC(alt);
|
||||
needTrim=true;
|
||||
|
|
|
@ -25,8 +25,6 @@
|
|||
#include <simgear/constants.h>
|
||||
#include <simgear/debug/logstream.hxx>
|
||||
|
||||
#include <Scenery/scenery.hxx>
|
||||
|
||||
#include <Main/fg_props.hxx>
|
||||
#include <Aircraft/aircraft.hxx>
|
||||
#include <Controls/controls.hxx>
|
||||
|
@ -188,8 +186,7 @@ void FGLaRCsim::update( double dt ) {
|
|||
|
||||
// Inform LaRCsim of the local terrain altitude
|
||||
// Runway_altitude = get_Runway_altitude();
|
||||
Runway_altitude = globals->get_scenery()->get_cur_elev() * SG_METER_TO_FEET;
|
||||
|
||||
Runway_altitude = getACModel()->get3DModel()->getFGLocation()->get_cur_elev_m() * SG_METER_TO_FEET;
|
||||
// Weather
|
||||
/* V_north_airmass = get_V_north_airmass();
|
||||
V_east_airmass = get_V_east_airmass();
|
||||
|
@ -616,8 +613,6 @@ void FGLaRCsim::snap_shot(void) {
|
|||
void FGLaRCsim::set_Latitude(double lat) {
|
||||
SG_LOG( SG_FLIGHT, SG_INFO, "FGLaRCsim::set_Latitude: " << lat );
|
||||
snap_shot();
|
||||
_set_Runway_altitude( globals->get_scenery()->get_cur_elev()
|
||||
* SG_METER_TO_FEET );
|
||||
lsic->SetLatitudeGDRadIC(lat);
|
||||
set_ls();
|
||||
copy_from_LaRCsim(); //update the bus
|
||||
|
@ -626,9 +621,6 @@ void FGLaRCsim::set_Latitude(double lat) {
|
|||
void FGLaRCsim::set_Longitude(double lon) {
|
||||
SG_LOG( SG_FLIGHT, SG_INFO, "FGLaRCsim::set_Longitude: " << lon );
|
||||
snap_shot();
|
||||
|
||||
_set_Runway_altitude( globals->get_scenery()->get_cur_elev()
|
||||
* SG_METER_TO_FEET );
|
||||
lsic->SetLongitudeRadIC(lon);
|
||||
set_ls();
|
||||
copy_from_LaRCsim(); //update the bus
|
||||
|
@ -637,8 +629,6 @@ void FGLaRCsim::set_Longitude(double lon) {
|
|||
void FGLaRCsim::set_Altitude(double alt) {
|
||||
SG_LOG( SG_FLIGHT, SG_INFO, "FGLaRCsim::set_Altitude: " << alt );
|
||||
snap_shot();
|
||||
_set_Runway_altitude( globals->get_scenery()->get_cur_elev()
|
||||
* SG_METER_TO_FEET );
|
||||
lsic->SetAltitudeFtIC(alt);
|
||||
set_ls();
|
||||
copy_from_LaRCsim(); //update the bus
|
||||
|
@ -717,6 +707,7 @@ void FGLaRCsim::set_AltitudeAGL(double altagl) {
|
|||
copy_from_LaRCsim();
|
||||
}
|
||||
|
||||
/* getting a namespace conflict...
|
||||
void FGLaRCsim::set_Velocities_Local_Airmass (double wnorth,
|
||||
double weast,
|
||||
double wdown ) {
|
||||
|
@ -727,6 +718,7 @@ void FGLaRCsim::set_Velocities_Local_Airmass (double wnorth,
|
|||
set_ls();
|
||||
copy_from_LaRCsim();
|
||||
}
|
||||
*/
|
||||
|
||||
void FGLaRCsim::set_Static_pressure(double p) {
|
||||
SG_LOG( SG_FLIGHT, SG_INFO,
|
||||
|
|
|
@ -84,9 +84,11 @@ public:
|
|||
void set_Static_temperature(double T);
|
||||
void set_Density(double rho);
|
||||
|
||||
/*
|
||||
void set_Velocities_Local_Airmass (double wnorth,
|
||||
double weast,
|
||||
double wdown );
|
||||
*/
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
#include <simgear/xml/easyxml.hxx>
|
||||
#include <Main/globals.hxx>
|
||||
#include <Main/fg_props.hxx>
|
||||
#include <Scenery/scenery.hxx>
|
||||
|
||||
#include "FGFDM.hpp"
|
||||
#include "Atmosphere.hpp"
|
||||
|
@ -161,8 +160,7 @@ void YASim::init()
|
|||
|
||||
// Are we at ground level? If so, lift the plane up so the gear
|
||||
// clear the ground.
|
||||
double runway_altitude =
|
||||
fgGetDouble("/environment/ground-elevation-m") * SG_METER_TO_FEET;
|
||||
double runway_altitude = get_Runway_altitude();
|
||||
fgSetBool("/controls/gear-down", false);
|
||||
if(get_Altitude() - runway_altitude < 50) {
|
||||
float minGearZ = 1e18;
|
||||
|
@ -232,10 +230,9 @@ void YASim::copyToYASim(bool copyState)
|
|||
wind[1] = get_V_east_airmass() * FT2M * -1.0;
|
||||
wind[2] = get_V_down_airmass() * FT2M * -1.0;
|
||||
|
||||
// The ground elevation doesn't come from FGInterface; query it
|
||||
// from the scenery and set it for others to find.
|
||||
double ground = globals->get_scenery()->get_cur_elev();
|
||||
_set_Runway_altitude(ground * FT2M);
|
||||
// Get ground elevation from the FGinterface's FGlocation data
|
||||
double ground = getACModel()->get3DModel()->getFGLocation()->get_cur_elev_m();
|
||||
// cout << "YASIM: ground = " << ground << endl;
|
||||
|
||||
float pressure = fgGetDouble("/environment/pressure-inhg") * INHG2PA;
|
||||
float temp = fgGetDouble("/environment/temperature-degC") + 273.15;
|
||||
|
|
|
@ -159,6 +159,7 @@ FGInterface::_setup ()
|
|||
sin_latitude=cos_latitude=0;
|
||||
sin_longitude=cos_longitude=0;
|
||||
altitude_agl=0;
|
||||
_acmodel = 0;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -182,6 +183,12 @@ FGInterface::common_init ()
|
|||
// stamp();
|
||||
// set_remainder( 0 );
|
||||
|
||||
// linking in FGAircraft instance...
|
||||
// FIXME: when using multiple instances, then there will be more than
|
||||
// one model so get_aircraft_model will have to be indexed to the correct
|
||||
// model.
|
||||
_acmodel = globals->get_aircraft_model();
|
||||
|
||||
// Set initial position
|
||||
SG_LOG( SG_FLIGHT, SG_INFO, "...initializing position..." );
|
||||
set_Longitude( fgGetDouble("/position/longitude-deg")
|
||||
|
@ -190,6 +197,8 @@ FGInterface::common_init ()
|
|||
* SGD_DEGREES_TO_RADIANS );
|
||||
double ground_elev_m = globals->get_scenery()->get_cur_elev();
|
||||
double ground_elev_ft = ground_elev_m * SG_METER_TO_FEET;
|
||||
_acmodel->get3DModel()->getFGLocation()->set_cur_elev_m( ground_elev_m );
|
||||
_set_Runway_altitude ( ground_elev_ft );
|
||||
if ( fgGetBool("/sim/startup/onground")
|
||||
|| fgGetDouble("/position/altitude-ft") < ground_elev_ft ) {
|
||||
fgSetDouble("/position/altitude-ft", ground_elev_ft);
|
||||
|
@ -448,8 +457,7 @@ void FGInterface::_updateGeodeticPosition( double lat, double lon, double alt )
|
|||
_set_Geodetic_Position( lat, lon, alt );
|
||||
|
||||
_set_Sea_level_radius( sl_radius * SG_METER_TO_FEET );
|
||||
_set_Runway_altitude( globals->get_scenery()->get_cur_elev()
|
||||
* SG_METER_TO_FEET );
|
||||
_set_Runway_altitude( getACModel()->get3DModel()->getFGLocation()->get_cur_elev_m() * SG_METER_TO_FEET );
|
||||
|
||||
_set_sin_lat_geocentric( lat_geoc );
|
||||
_set_cos_lat_geocentric( lat_geoc );
|
||||
|
@ -505,8 +513,7 @@ void FGInterface::_updateGeocentricPosition( double lat_geoc, double lon,
|
|||
_set_Geodetic_Position( lat_geod, lon, alt );
|
||||
|
||||
_set_Sea_level_radius( sl_radius2 * SG_METER_TO_FEET );
|
||||
_set_Runway_altitude( globals->get_scenery()->get_cur_elev()
|
||||
* SG_METER_TO_FEET );
|
||||
_set_Runway_altitude( getACModel()->get3DModel()->getFGLocation()->get_cur_elev_m() * SG_METER_TO_FEET );
|
||||
|
||||
_set_sin_lat_geocentric( lat_geoc );
|
||||
_set_cos_lat_geocentric( lat_geoc );
|
||||
|
|
|
@ -93,6 +93,9 @@
|
|||
// #include <simgear/timing/timestamp.hxx>
|
||||
|
||||
#include <Main/fgfs.hxx>
|
||||
#include <Model/acmodel.hxx>
|
||||
#include <Model/model.hxx>
|
||||
#include <Main/location.hxx>
|
||||
|
||||
SG_USING_STD(list);
|
||||
SG_USING_STD(vector);
|
||||
|
@ -224,6 +227,9 @@ private:
|
|||
// SGTimeStamp valid_stamp; // time this record is valid
|
||||
// SGTimeStamp next_stamp; // time this record is valid
|
||||
|
||||
// Model tied to FDM
|
||||
FGAircraftModel * _acmodel;
|
||||
|
||||
protected:
|
||||
|
||||
int _calc_multiloop (double dt);
|
||||
|
@ -1071,6 +1077,12 @@ public:
|
|||
inline float get_faux( int n ) const { return faux[n]; }
|
||||
inline int get_iaux( int n ) const { return iaux[n]; }
|
||||
|
||||
// Model tied to FDM
|
||||
FGAircraftModel * getACModel() const { return _acmodel; }
|
||||
|
||||
// Note that currently this is the "same" value runway altitude...
|
||||
inline double get_ground_elev_ft() const { return runway_altitude; }
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -740,6 +740,17 @@ bool fgInitSubsystems( void ) {
|
|||
exit(-1);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Initialize the event manager subsystem.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
global_events.init();
|
||||
|
||||
// Output event stats every 60 seconds
|
||||
global_events.Register( "FGEventMgr::print_stats()",
|
||||
&global_events, &FGEventMgr::print_stats,
|
||||
60000 );
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Initialize the scenery management subsystem.
|
||||
|
@ -757,6 +768,11 @@ bool fgInitSubsystems( void ) {
|
|||
exit(-1);
|
||||
}
|
||||
|
||||
// cause refresh of viewer scenery timestamps every 15 seconds...
|
||||
global_events.Register( "FGTileMgr::refresh_view_timestamps()",
|
||||
&global_tile_mgr, &FGTileMgr::refresh_view_timestamps,
|
||||
15000 );
|
||||
|
||||
SG_LOG( SG_GENERAL, SG_DEBUG,
|
||||
"Current terrain elevation after tile mgr init " <<
|
||||
globals->get_scenery()->get_cur_elev() );
|
||||
|
@ -780,18 +796,6 @@ bool fgInitSubsystems( void ) {
|
|||
fgInitView();
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Initialize the event manager subsystem.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
global_events.init();
|
||||
|
||||
// Output event stats every 60 seconds
|
||||
global_events.Register( "FGEventMgr::print_stats()",
|
||||
&global_events, &FGEventMgr::print_stats,
|
||||
60000 );
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Initialize the lighting subsystem.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
|
||||
#include <simgear/compiler.h>
|
||||
#include <simgear/constants.h>
|
||||
#include <simgear/bucket/newbucket.hxx>
|
||||
|
||||
#include <plib/sg.h> // plib include
|
||||
|
||||
|
@ -106,6 +107,14 @@ public:
|
|||
virtual float *get_surface_east() { return _surface_east; }
|
||||
// Get surface south vector
|
||||
virtual float *get_surface_south() { return _surface_south; }
|
||||
// Elevation of ground under location (based on scenery output)...
|
||||
void set_cur_elev_m ( double elev ) { _cur_elev_m = elev; }
|
||||
inline double get_cur_elev_m () { return _cur_elev_m; }
|
||||
// Interface to current buckets for use with tilemgr...
|
||||
void set_current_bucket ( SGBucket current_bucket ) { _current_bucket = current_bucket; }
|
||||
inline SGBucket get_current_bucket () { return _current_bucket; }
|
||||
void set_previous_bucket ( SGBucket previous_bucket ) { _previous_bucket = previous_bucket; }
|
||||
inline SGBucket get_previous_bucket () { return _previous_bucket; }
|
||||
|
||||
// Matrices...
|
||||
virtual const sgVec4 * getTransformMatrix() { if ( _dirty ) { recalc(); } return TRANS; }
|
||||
|
@ -135,6 +144,13 @@ private:
|
|||
double _pitch_deg;
|
||||
double _heading_deg;
|
||||
|
||||
// elevation of ground under this location...
|
||||
double _cur_elev_m;
|
||||
// current and previous scenery buckets to be saved for use in
|
||||
// getting current elevation from tilemgr.
|
||||
SGBucket _previous_bucket;
|
||||
SGBucket _current_bucket;
|
||||
|
||||
// surface vector heading south
|
||||
sgVec3 _surface_south;
|
||||
|
||||
|
@ -163,17 +179,3 @@ private:
|
|||
|
||||
|
||||
#endif // _LOCATION_HXX
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -100,6 +100,8 @@ SG_USING_STD(endl);
|
|||
#include <GUI/gui.h>
|
||||
#include <Model/acmodel.hxx>
|
||||
#include <Model/modelmgr.hxx>
|
||||
#include <Model/model.hxx>
|
||||
#include <Main/location.hxx>
|
||||
#ifdef FG_NETWORK_OLK
|
||||
#include <NetworkOLK/network.h>
|
||||
#endif
|
||||
|
@ -534,11 +536,11 @@ void fgRenderFrame() {
|
|||
thesky->reposition( current__view->get_view_pos(),
|
||||
current__view->get_zero_elev(),
|
||||
current__view->get_world_up(),
|
||||
longitude->getDoubleValue()
|
||||
current__view->getLongitude_deg()
|
||||
* SGD_DEGREES_TO_RADIANS,
|
||||
latitude->getDoubleValue()
|
||||
current__view->getLatitude_deg()
|
||||
* SGD_DEGREES_TO_RADIANS,
|
||||
altitude->getDoubleValue() * SG_FEET_TO_METER,
|
||||
current__view->getAltitudeASL_ft() * SG_FEET_TO_METER,
|
||||
cur_light_params.sun_rotation,
|
||||
globals->get_time_params()->getGst(),
|
||||
globals->get_ephem()->getSunRightAscension(),
|
||||
|
@ -860,6 +862,11 @@ static void fgMainLoop( void ) {
|
|||
|
||||
SGTime *t = globals->get_time_params();
|
||||
|
||||
FGLocation * acmodel_location = 0;
|
||||
if(cur_fdm_state->getACModel() != 0) {
|
||||
acmodel_location = (FGLocation *) cur_fdm_state->getACModel()->get3DModel()->getFGLocation();
|
||||
}
|
||||
|
||||
SG_LOG( SG_ALL, SG_DEBUG, "Running Main Loop");
|
||||
SG_LOG( SG_ALL, SG_DEBUG, "======= ==== ====");
|
||||
|
||||
|
@ -897,25 +904,26 @@ static void fgMainLoop( void ) {
|
|||
cur_fdm_state->get_Runway_altitude() * SG_FEET_TO_METER,
|
||||
cur_fdm_state->get_Altitude() * SG_FEET_TO_METER); */
|
||||
|
||||
if ( globals->get_scenery()->get_cur_elev() > -9990
|
||||
&& cur_fdm_state->get_inited() )
|
||||
{
|
||||
// Curt is this code used? I don't see any problems when I comment it out.
|
||||
if ( acmodel_location != 0 ) {
|
||||
if ( acmodel_location->get_cur_elev_m() > -9990 && cur_fdm_state->get_inited() ) {
|
||||
if ( cur_fdm_state->get_Altitude() * SG_FEET_TO_METER <
|
||||
(globals->get_scenery()->get_cur_elev() + alt_adjust_m - 3.0) ) {
|
||||
(acmodel_location->get_cur_elev_m() + alt_adjust_m - 3.0) ) {
|
||||
// now set aircraft altitude above ground
|
||||
printf("(*) Current Altitude = %.2f < %.2f forcing to %.2f\n",
|
||||
cur_fdm_state->get_Altitude() * SG_FEET_TO_METER,
|
||||
globals->get_scenery()->get_cur_elev() + alt_adjust_m - 3.0,
|
||||
globals->get_scenery()->get_cur_elev() + alt_adjust_m );
|
||||
cur_fdm_state->set_Altitude( globals->get_scenery()->get_cur_elev()
|
||||
+ alt_adjust_m );
|
||||
|
||||
acmodel_location->get_cur_elev_m() + alt_adjust_m - 3.0,
|
||||
acmodel_location->get_cur_elev_m() + alt_adjust_m );
|
||||
cur_fdm_state->set_Altitude( (acmodel_location->get_cur_elev_m()
|
||||
+ alt_adjust_m) * SG_METER_TO_FEET );
|
||||
SG_LOG( SG_ALL, SG_DEBUG,
|
||||
"<*> resetting altitude to "
|
||||
<< cur_fdm_state->get_Altitude() * SG_FEET_TO_METER
|
||||
<< " meters" );
|
||||
}
|
||||
}
|
||||
}
|
||||
// End of code in question. (see Curt is this code used? above)
|
||||
|
||||
/* printf("Adjustment - ground = %.2f runway = %.2f alt = %.2f\n",
|
||||
scenery.get_cur_elev(),
|
||||
|
@ -1057,10 +1065,67 @@ static void fgMainLoop( void ) {
|
|||
// redraw display
|
||||
fgRenderFrame();
|
||||
|
||||
// see if we need to load any new scenery tiles
|
||||
|
||||
//
|
||||
// Tile Manager updates - see if we need to load any new scenery tiles.
|
||||
// this code ties together the fdm, viewer and scenery classes...
|
||||
// we may want to move this to it's own class at some point
|
||||
//
|
||||
double visibility_meters = fgGetDouble("/environment/visibility-m");
|
||||
global_tile_mgr.update( longitude->getDoubleValue(),
|
||||
latitude->getDoubleValue(), visibility_meters );
|
||||
FGViewer *current_view = globals->get_current_view();
|
||||
|
||||
// update tile manager for FDM...
|
||||
// ...only if location is different than the viewer (to avoid duplicating effort)
|
||||
if( acmodel_location != current_view->getFGLocation() ) {
|
||||
if( acmodel_location != 0 ) {
|
||||
global_tile_mgr.update( acmodel_location->getLongitude_deg(),
|
||||
acmodel_location->getLatitude_deg(),
|
||||
visibility_meters,
|
||||
acmodel_location->get_absolute_view_pos(),
|
||||
acmodel_location->get_current_bucket(),
|
||||
acmodel_location->get_previous_bucket()
|
||||
);
|
||||
// save results of update in FGLocation for fdm...
|
||||
if ( globals->get_scenery()->get_cur_elev() > -9990 ) {
|
||||
acmodel_location->set_cur_elev_m( globals->get_scenery()->get_cur_elev() );
|
||||
}
|
||||
acmodel_location->set_current_bucket( global_tile_mgr.get_current_bucket() );
|
||||
acmodel_location->set_previous_bucket( global_tile_mgr.get_previous_bucket() );
|
||||
}
|
||||
}
|
||||
|
||||
// update tile manager for view...
|
||||
// IMPORTANT!!! the tilemgr update for view location _must_ be done last
|
||||
// after the FDM's until all of Flight Gear code references the viewer's location
|
||||
// for elevation instead of the "scenery's" current elevation.
|
||||
global_tile_mgr.update( current_view->getLongitude_deg(),
|
||||
current_view->getLatitude_deg(),
|
||||
visibility_meters,
|
||||
current_view->get_absolute_view_pos(),
|
||||
current_view->getFGLocation()->get_current_bucket(),
|
||||
current_view->getFGLocation()->get_previous_bucket()
|
||||
);
|
||||
// save results of update in FGLocation for fdm...
|
||||
if ( globals->get_scenery()->get_cur_elev() > -9990 ) {
|
||||
current_view->getFGLocation()->set_cur_elev_m( globals->get_scenery()->get_cur_elev() );
|
||||
}
|
||||
current_view->getFGLocation()->set_current_bucket( global_tile_mgr.get_current_bucket() );
|
||||
current_view->getFGLocation()->set_previous_bucket( global_tile_mgr.get_previous_bucket() );
|
||||
|
||||
// If fdm location is same as viewer's then we didn't do the update for fdm location
|
||||
// above so we need to save the viewer results in the fdm FGLocation as well...
|
||||
if( acmodel_location == current_view->getFGLocation() ) {
|
||||
if( acmodel_location != 0 ) {
|
||||
if ( globals->get_scenery()->get_cur_elev() > -9990 ) {
|
||||
acmodel_location->set_cur_elev_m( globals->get_scenery()->get_cur_elev() );
|
||||
}
|
||||
acmodel_location->set_current_bucket( global_tile_mgr.get_current_bucket() );
|
||||
acmodel_location->set_previous_bucket( global_tile_mgr.get_previous_bucket() );
|
||||
}
|
||||
}
|
||||
|
||||
// END Tile Manager udpates
|
||||
|
||||
|
||||
SG_LOG( SG_ALL, SG_DEBUG, "" );
|
||||
}
|
||||
|
|
|
@ -886,8 +886,7 @@ parse_option (const string& arg)
|
|||
}
|
||||
FGViewer *pilot_view =
|
||||
(FGViewer *)globals->get_viewmgr()->get_view( 0 );
|
||||
pilot_view->setHeadingOffset_deg( default_view_offset * SGD_RADIANS_TO_DEGREES );
|
||||
pilot_view->setGoalHeadingOffset_deg( default_view_offset * SGD_RADIANS_TO_DEGREES );
|
||||
// this will work without calls to the viewer...
|
||||
fgSetDouble( "/sim/current-view/heading-offset-deg",
|
||||
default_view_offset * SGD_RADIANS_TO_DEGREES );
|
||||
// $$$ end - added VS Renganathan, 14 Oct 2K
|
||||
|
|
|
@ -39,7 +39,6 @@
|
|||
#include <simgear/math/sg_geodesy.hxx>
|
||||
|
||||
#include <Scenery/scenery.hxx>
|
||||
//#include <Main/location.hxx>
|
||||
|
||||
#include <simgear/math/vector.hxx>
|
||||
#include <Main/globals.hxx>
|
||||
|
@ -446,36 +445,16 @@ void
|
|||
FGViewer::updateFromModelLocation (FGLocation * location)
|
||||
{
|
||||
sgCopyMat4(LOCAL, location->getCachedTransformMatrix());
|
||||
_lon_deg = location->getLongitude_deg();
|
||||
_lat_deg = location->getLatitude_deg();
|
||||
_alt_ft = location->getAltitudeASL_ft();
|
||||
_roll_deg = location->getRoll_deg();
|
||||
_pitch_deg = location->getPitch_deg();
|
||||
_heading_deg = location->getHeading_deg();
|
||||
sgCopyVec3(_zero_elev_view_pos, location->get_zero_elev());
|
||||
sgCopyVec3(_relative_view_pos, location->get_view_pos());
|
||||
sgdCopyVec3(_absolute_view_pos, location->get_absolute_view_pos());
|
||||
sgCopyMat4(UP, location->getCachedUpMatrix());
|
||||
sgCopyVec3(_world_up, location->get_world_up());
|
||||
// these are the vectors that the sun and moon code like to get...
|
||||
sgCopyVec3(_surface_east, location->get_surface_east());
|
||||
sgCopyVec3(_surface_south, location->get_surface_south());
|
||||
}
|
||||
|
||||
void
|
||||
FGViewer::recalcOurOwnLocation (double lon_deg, double lat_deg, double alt_ft,
|
||||
FGViewer::recalcOurOwnLocation (FGLocation * location, double lon_deg, double lat_deg, double alt_ft,
|
||||
double roll_deg, double pitch_deg, double heading_deg)
|
||||
{
|
||||
// update from our own data...
|
||||
_location->setPosition( lon_deg, lat_deg, alt_ft );
|
||||
_location->setOrientation( roll_deg, pitch_deg, heading_deg );
|
||||
sgCopyMat4(LOCAL, _location->getTransformMatrix());
|
||||
sgCopyVec3(_zero_elev_view_pos, _location->get_zero_elev());
|
||||
sgCopyVec3(_relative_view_pos, _location->get_view_pos());
|
||||
sgdCopyVec3(_absolute_view_pos, _location->get_absolute_view_pos());
|
||||
// these are the vectors that the sun and moon code like to get...
|
||||
sgCopyVec3(_surface_east, _location->get_surface_east());
|
||||
sgCopyVec3(_surface_south, _location->get_surface_south());
|
||||
location->setPosition( lon_deg, lat_deg, alt_ft );
|
||||
location->setOrientation( roll_deg, pitch_deg, heading_deg );
|
||||
sgCopyMat4(LOCAL, location->getTransformMatrix());
|
||||
}
|
||||
|
||||
// recalc() is done every time one of the setters is called (making the
|
||||
|
@ -484,115 +463,44 @@ FGViewer::recalcOurOwnLocation (double lon_deg, double lat_deg, double alt_ft,
|
|||
void
|
||||
FGViewer::recalc ()
|
||||
{
|
||||
if (_type == FG_LOOKFROM) {
|
||||
recalcLookFrom();
|
||||
} else {
|
||||
recalcLookAt();
|
||||
}
|
||||
|
||||
set_clean();
|
||||
}
|
||||
|
||||
// recalculate for LookFrom view type...
|
||||
void
|
||||
FGViewer::recalcLookFrom ()
|
||||
{
|
||||
|
||||
sgVec3 right, forward;
|
||||
sgMat4 tmpROT; // temp rotation work matrices
|
||||
sgVec3 eye_pos, at_pos;
|
||||
sgVec3 eye_pos;
|
||||
sgVec3 position_offset; // eye position offsets (xyz)
|
||||
|
||||
// The position vectors originate from the view point or target location
|
||||
// depending on the type of view.
|
||||
|
||||
if (_type == FG_LOOKFROM) {
|
||||
// LOOKFROM mode...
|
||||
|
||||
// Update location data...
|
||||
if ( _from_model ) {
|
||||
// update or data from model location
|
||||
updateFromModelLocation(_location);
|
||||
} else {
|
||||
// update from our own data...
|
||||
recalcOurOwnLocation( _lon_deg, _lat_deg, _alt_ft,
|
||||
recalcOurOwnLocation( _location, _lon_deg, _lat_deg, _alt_ft,
|
||||
_roll_deg, _pitch_deg, _heading_deg );
|
||||
// get world up data from just recalced location
|
||||
sgCopyMat4(UP, _location->getUpMatrix());
|
||||
sgCopyVec3(_world_up, _location->get_world_up());
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
// LOOKAT mode...
|
||||
if ( _from_model ) {
|
||||
// update or data from model location
|
||||
updateFromModelLocation(_location);
|
||||
} else {
|
||||
// update from our own data, just the rotation here...
|
||||
recalcOurOwnLocation( _lon_deg, _lat_deg, _alt_ft,
|
||||
_roll_deg, _pitch_deg, _heading_deg );
|
||||
// get world up data from just recalced location
|
||||
sgCopyMat4(UP, _location->getUpMatrix());
|
||||
sgCopyVec3(_world_up, _location->get_world_up());
|
||||
}
|
||||
// save they eye positon...
|
||||
sgCopyVec3(eye_pos, _location->get_view_pos());
|
||||
// save the eye rotation before getting target values!!!
|
||||
sgCopyMat4(tmpROT, LOCAL);
|
||||
|
||||
if ( _at_model ) {
|
||||
// update or data from model location
|
||||
updateFromModelLocation(_target_location);
|
||||
} else {
|
||||
// if not model then calculate our own target position...
|
||||
recalcOurOwnLocation( _target_lon_deg, _target_lat_deg, _target_alt_ft,
|
||||
_target_roll_deg, _target_pitch_deg, _target_heading_deg );
|
||||
}
|
||||
// restore the eye rotation (the from position rotation)
|
||||
sgCopyMat4(LOCAL, tmpROT);
|
||||
|
||||
}
|
||||
|
||||
// the coordinates generated by the above "recalcPositionVectors"
|
||||
sgCopyVec3(_zero_elev, _zero_elev_view_pos);
|
||||
sgCopyVec3(_view_pos, _relative_view_pos);
|
||||
|
||||
// FIXME:
|
||||
// Doing this last recalc here for published values...where the airplane is
|
||||
// This should be per aircraft or model (for published values) before
|
||||
// multiple FDM can be done.
|
||||
// This info should come directly from the model (not through viewer),
|
||||
// because in some cases there is no model directly assigned as a lookfrom
|
||||
// position. The problem that arises is related to the FDM interface looking
|
||||
// indirectly to the viewer to find the altitude of the aircraft on the runway.
|
||||
//
|
||||
// Note that recalcPositionVectors can be removed from viewer when this
|
||||
// issue is addressed.
|
||||
//
|
||||
if (!_from_model) {
|
||||
recalcPositionVectors(fgGetDouble("/position/longitude-deg"),
|
||||
fgGetDouble("/position/latitude-deg"),
|
||||
fgGetDouble("/position/altitude-ft"));
|
||||
}
|
||||
// copy data from location class to local items...
|
||||
copyLocationData();
|
||||
|
||||
// make sg vectors view up, right and forward vectors from LOCAL
|
||||
sgSetVec3( _view_up, LOCAL[2][0], LOCAL[2][1], LOCAL[2][2] );
|
||||
sgSetVec3( right, LOCAL[1][0], LOCAL[1][1], LOCAL[1][2] );
|
||||
sgSetVec3( forward, -LOCAL[0][0], -LOCAL[0][1], -LOCAL[0][2] );
|
||||
|
||||
if (_type == FG_LOOKAT) {
|
||||
|
||||
// Note that when in "lookat" view the "world up" vector is always applied
|
||||
// to the viewer. World up is based on verticle at a given lon/lat (see
|
||||
// matrix "UP" above).
|
||||
|
||||
// Orientation Offsets matrix
|
||||
MakeVIEW_OFFSET( VIEW_OFFSET,
|
||||
(_heading_offset_deg -_heading_deg) * SG_DEGREES_TO_RADIANS, _world_up,
|
||||
_pitch_offset_deg * SG_DEGREES_TO_RADIANS, right );
|
||||
|
||||
// add in the Orientation Offsets here
|
||||
sgSetVec3( position_offset, _x_offset_m, _y_offset_m, _z_offset_m );
|
||||
sgXformVec3( position_offset, position_offset, UP);
|
||||
|
||||
sgXformVec3( position_offset, position_offset, VIEW_OFFSET );
|
||||
|
||||
// add the Position offsets from object to the eye position
|
||||
sgAddVec3( eye_pos, eye_pos, position_offset );
|
||||
|
||||
// at position (what we are looking at)
|
||||
sgCopyVec3( at_pos, _view_pos );
|
||||
|
||||
// Make the VIEW matrix for a "LOOKAT".
|
||||
sgMakeLookAtMat4( VIEW, eye_pos, at_pos, _view_up );
|
||||
}
|
||||
|
||||
if (_type == FG_LOOKFROM) {
|
||||
|
||||
// Note that when in "lookfrom" view the "view up" vector is always applied
|
||||
// to the viewer. View up is based on verticle of the aircraft itself. (see
|
||||
|
@ -631,51 +539,109 @@ FGViewer::recalc ()
|
|||
|
||||
}
|
||||
|
||||
set_clean();
|
||||
void
|
||||
FGViewer::recalcLookAt ()
|
||||
{
|
||||
|
||||
sgVec3 right;
|
||||
sgVec3 eye_pos, at_pos;
|
||||
sgVec3 position_offset; // eye position offsets (xyz)
|
||||
|
||||
// The position vectors originate from the view point or target location
|
||||
// depending on the type of view.
|
||||
|
||||
// LOOKAT mode...
|
||||
|
||||
// Update location data for target...
|
||||
if ( _at_model ) {
|
||||
// update or data from model location
|
||||
updateFromModelLocation(_target_location);
|
||||
} else {
|
||||
// if not model then calculate our own target position...
|
||||
recalcOurOwnLocation( _target_location, _target_lon_deg, _target_lat_deg, _target_alt_ft,
|
||||
_target_roll_deg, _target_pitch_deg, _target_heading_deg );
|
||||
}
|
||||
// save the "at" target object positon...
|
||||
sgCopyVec3(at_pos, _target_location->get_view_pos());
|
||||
|
||||
// Update location data for eye...
|
||||
if ( _from_model ) {
|
||||
// update or data from model location
|
||||
updateFromModelLocation(_location);
|
||||
} else {
|
||||
// update from our own data, just the rotation here...
|
||||
recalcOurOwnLocation( _location, _lon_deg, _lat_deg, _alt_ft,
|
||||
_roll_deg, _pitch_deg, _heading_deg );
|
||||
}
|
||||
// save the eye positon...
|
||||
sgCopyVec3(eye_pos, _location->get_view_pos());
|
||||
|
||||
// copy data from location class to local items...
|
||||
copyLocationData();
|
||||
|
||||
// make sg vectors view up, right and forward vectors from LOCAL
|
||||
sgSetVec3( _view_up, LOCAL[2][0], LOCAL[2][1], LOCAL[2][2] );
|
||||
sgSetVec3( right, LOCAL[1][0], LOCAL[1][1], LOCAL[1][2] );
|
||||
|
||||
// Note that when in "lookat" view the "world up" vector is always applied
|
||||
// to the viewer. World up is based on verticle at a given lon/lat (see
|
||||
// matrix "UP" above).
|
||||
|
||||
// Orientation Offsets matrix
|
||||
MakeVIEW_OFFSET( VIEW_OFFSET,
|
||||
(_heading_offset_deg -_heading_deg) * SG_DEGREES_TO_RADIANS, _world_up,
|
||||
_pitch_offset_deg * SG_DEGREES_TO_RADIANS, right );
|
||||
|
||||
// add in the Orientation Offsets here
|
||||
sgSetVec3( position_offset, _x_offset_m, _y_offset_m, _z_offset_m );
|
||||
sgXformVec3( position_offset, position_offset, UP);
|
||||
|
||||
sgXformVec3( position_offset, position_offset, VIEW_OFFSET );
|
||||
|
||||
// add the Position offsets from object to the eye position
|
||||
sgAddVec3( eye_pos, eye_pos, position_offset );
|
||||
|
||||
// Make the VIEW matrix for a "LOOKAT".
|
||||
sgMakeLookAtMat4( VIEW, eye_pos, at_pos, _view_up );
|
||||
|
||||
}
|
||||
|
||||
// copy results from location class to viewer...
|
||||
// FIXME: some of these should be changed to reference directly to FGLocation...
|
||||
void
|
||||
FGViewer::recalcPositionVectors (double lon_deg, double lat_deg, double alt_ft) const
|
||||
FGViewer::copyLocationData()
|
||||
{
|
||||
double sea_level_radius_m;
|
||||
double lat_geoc_rad;
|
||||
// Get our friendly vectors from the eye location...
|
||||
sgCopyVec3(_zero_elev_view_pos, _location->get_zero_elev());
|
||||
sgCopyVec3(_relative_view_pos, _location->get_view_pos());
|
||||
sgdCopyVec3(_absolute_view_pos, _location->get_absolute_view_pos());
|
||||
sgCopyMat4(UP, _location->getCachedUpMatrix());
|
||||
sgCopyVec3(_world_up, _location->get_world_up());
|
||||
// these are the vectors that the sun and moon code like to get...
|
||||
sgCopyVec3(_surface_east, _location->get_surface_east());
|
||||
sgCopyVec3(_surface_south, _location->get_surface_south());
|
||||
|
||||
// Update viewer's postion data for the eye location...
|
||||
_lon_deg = _location->getLongitude_deg();
|
||||
_lat_deg = _location->getLatitude_deg();
|
||||
_alt_ft = _location->getAltitudeASL_ft();
|
||||
_roll_deg = _location->getRoll_deg();
|
||||
_pitch_deg = _location->getPitch_deg();
|
||||
_heading_deg = _location->getHeading_deg();
|
||||
|
||||
// Convert from geodetic to geocentric
|
||||
// coordinates.
|
||||
sgGeodToGeoc(lat_deg * SGD_DEGREES_TO_RADIANS,
|
||||
alt_ft * SG_FEET_TO_METER,
|
||||
&sea_level_radius_m,
|
||||
&lat_geoc_rad);
|
||||
|
||||
// Calculate the cartesian coordinates
|
||||
// of point directly below at sea level.
|
||||
// aka Zero Elevation Position
|
||||
Point3D p = Point3D(lon_deg * SG_DEGREES_TO_RADIANS,
|
||||
lat_geoc_rad,
|
||||
sea_level_radius_m);
|
||||
Point3D tmp = sgPolarToCart3d(p) - globals->get_scenery()->get_next_center();
|
||||
sgSetVec3(_zero_elev_view_pos, tmp[0], tmp[1], tmp[2]);
|
||||
|
||||
// Calculate the absolute view position
|
||||
// in fgfs coordinates.
|
||||
// aka Absolute View Position
|
||||
p.setz(p.radius() + alt_ft * SG_FEET_TO_METER);
|
||||
tmp = sgPolarToCart3d(p);
|
||||
sgdSetVec3(_absolute_view_pos, tmp[0], tmp[1], tmp[2]);
|
||||
|
||||
// Calculate the relative view position
|
||||
// from the scenery center.
|
||||
// aka Relative View Position
|
||||
sgdVec3 scenery_center;
|
||||
sgdSetVec3(scenery_center,
|
||||
globals->get_scenery()->get_next_center().x(),
|
||||
globals->get_scenery()->get_next_center().y(),
|
||||
globals->get_scenery()->get_next_center().z());
|
||||
sgdVec3 view_pos;
|
||||
sgdSubVec3(view_pos, _absolute_view_pos, scenery_center);
|
||||
sgSetVec3(_relative_view_pos, view_pos);
|
||||
// Update viewer's postion data for the target (at object) location
|
||||
if (_type == FG_LOOKAT) {
|
||||
_target_lon_deg = _target_location->getLongitude_deg();
|
||||
_target_lat_deg = _target_location->getLatitude_deg();
|
||||
_target_alt_ft = _target_location->getAltitudeASL_ft();
|
||||
_target_roll_deg = _target_location->getRoll_deg();
|
||||
_target_pitch_deg = _target_location->getPitch_deg();
|
||||
_target_heading_deg = _target_location->getHeading_deg();
|
||||
}
|
||||
|
||||
// copy coordinates to outputs for viewer...
|
||||
sgCopyVec3(_zero_elev, _zero_elev_view_pos);
|
||||
sgCopyVec3(_view_pos, _relative_view_pos);
|
||||
}
|
||||
|
||||
double
|
||||
|
@ -699,6 +665,8 @@ FGViewer::get_h_fov()
|
|||
return 0.0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
double
|
||||
FGViewer::get_v_fov()
|
||||
{
|
||||
|
|
|
@ -245,6 +245,9 @@ public:
|
|||
inline void set_dirty() { _dirty = true; }
|
||||
inline void set_clean() { _dirty = false; }
|
||||
|
||||
// return eye location...
|
||||
virtual FGLocation * getFGLocation () const { return _location; }
|
||||
|
||||
|
||||
private:
|
||||
|
||||
|
@ -349,9 +352,11 @@ private:
|
|||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
void recalc ();
|
||||
void recalcPositionVectors (double lon_deg, double lat_deg, double alt_ft) const;
|
||||
void recalcLookFrom();
|
||||
void recalcLookAt();
|
||||
void copyLocationData();
|
||||
void updateFromModelLocation (FGLocation * location);
|
||||
void recalcOurOwnLocation (double lon_deg, double lat_deg, double alt_ft,
|
||||
void recalcOurOwnLocation (FGLocation * location, double lon_deg, double lat_deg, double alt_ft,
|
||||
double roll_deg, double pitch_deg, double heading_deg);
|
||||
|
||||
// add to _heading_offset_deg
|
||||
|
|
|
@ -51,7 +51,7 @@ SG_USING_NAMESPACE(std);
|
|||
|
||||
// Constructor
|
||||
FGNewCache::FGNewCache( void ) :
|
||||
max_cache_size(50)
|
||||
max_cache_size(100)
|
||||
{
|
||||
tile_cache.clear();
|
||||
}
|
||||
|
@ -105,6 +105,116 @@ bool FGNewCache::exists( const SGBucket& b ) const {
|
|||
}
|
||||
|
||||
|
||||
// Ensure at least one entry is free in the cache
|
||||
bool FGNewCache::make_space() {
|
||||
SG_LOG( SG_TERRAIN, SG_DEBUG, "Make space in cache" );
|
||||
SG_LOG( SG_TERRAIN, SG_DEBUG, "cache entries = " << tile_cache.size() );
|
||||
SG_LOG( SG_TERRAIN, SG_DEBUG, "max size = " << max_cache_size );
|
||||
|
||||
if ( (int)tile_cache.size() < max_cache_size ) {
|
||||
// space in the cache, return
|
||||
return true;
|
||||
}
|
||||
|
||||
while ( (int)tile_cache.size() >= max_cache_size ) {
|
||||
sgdVec3 abs_view_pos;
|
||||
float dist;
|
||||
double timestamp = 0.0;
|
||||
int max_index = -1;
|
||||
double min_time = 2419200000.0f; // one month should be enough
|
||||
double max_time = 0;
|
||||
|
||||
// we need to free the furthest entry
|
||||
tile_map_iterator current = tile_cache.begin();
|
||||
tile_map_iterator end = tile_cache.end();
|
||||
|
||||
for ( ; current != end; ++current ) {
|
||||
long index = current->first;
|
||||
FGTileEntry *e = current->second;
|
||||
if ( e->is_loaded() && (e->get_pending_models() == 0) ) {
|
||||
|
||||
timestamp = e->get_timestamp();
|
||||
if ( timestamp < min_time ) {
|
||||
max_index = index;
|
||||
min_time = timestamp;
|
||||
}
|
||||
if ( timestamp > max_time ) {
|
||||
max_time = timestamp;
|
||||
}
|
||||
|
||||
} else {
|
||||
SG_LOG( SG_TERRAIN, SG_INFO, "loaded = " << e->is_loaded()
|
||||
<< " pending models = " << e->get_pending_models()
|
||||
<< " time stamp = " << e->get_timestamp() );
|
||||
}
|
||||
}
|
||||
|
||||
// If we made it this far, then there were no open cache entries.
|
||||
// We will instead free the oldest cache entry and return true
|
||||
|
||||
SG_LOG( SG_TERRAIN, SG_INFO, " min_time = " << min_time );
|
||||
SG_LOG( SG_TERRAIN, SG_INFO, " index = " << max_index );
|
||||
SG_LOG( SG_TERRAIN, SG_INFO, " max_time = " << max_time );
|
||||
if ( max_index >= 0 ) {
|
||||
entry_free( max_index );
|
||||
return true;
|
||||
} else {
|
||||
SG_LOG( SG_TERRAIN, SG_ALERT, "WHOOPS!!! can't make_space(), tile "
|
||||
"cache is full, but no entries available for removal." );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
SG_LOG( SG_TERRAIN, SG_ALERT, "WHOOPS!!! Hit an unhandled condition in "
|
||||
"FGNewCache::make_space()." );
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Clear all completely loaded tiles (ignores partially loaded tiles)
|
||||
void FGNewCache::clear_cache() {
|
||||
|
||||
tile_map_iterator current = tile_cache.begin();
|
||||
tile_map_iterator end = tile_cache.end();
|
||||
|
||||
for ( ; current != end; ++current ) {
|
||||
long index = current->first;
|
||||
SG_LOG( SG_TERRAIN, SG_DEBUG, "clearing " << index );
|
||||
FGTileEntry *e = current->second;
|
||||
if ( e->is_loaded() && (e->get_pending_models() == 0) ) {
|
||||
e->tile_bucket.make_bad();
|
||||
entry_free(index);
|
||||
}
|
||||
}
|
||||
|
||||
// and ... just in case we missed something ...
|
||||
globals->get_scenery()->get_terrain_branch()->removeAllKids();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a new tile and schedule it for loading.
|
||||
*/
|
||||
bool FGNewCache::insert_tile( FGTileEntry *e ) {
|
||||
// set time of insertion for tracking age of tiles...
|
||||
e->set_timestamp(globals->get_sim_time_sec());
|
||||
// clear out a distant entry in the cache if needed.
|
||||
if ( make_space() ) {
|
||||
// register it in the cache
|
||||
long tile_index = e->get_tile_bucket().gen_index();
|
||||
tile_cache[tile_index] = e;
|
||||
|
||||
return true;
|
||||
} else {
|
||||
// failed to find cache space
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Note this is the old version of FGNewCache::make_space(), currently disabled
|
||||
// It uses distance from a center point to determine tiles to be discarded...
|
||||
#ifdef 0
|
||||
// Ensure at least one entry is free in the cache
|
||||
bool FGNewCache::make_space() {
|
||||
SG_LOG( SG_TERRAIN, SG_DEBUG, "Make space in cache" );
|
||||
|
@ -178,44 +288,6 @@ bool FGNewCache::make_space() {
|
|||
"FGNewCache::make_space()." );
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// Clear all completely loaded tiles (ignores partially loaded tiles)
|
||||
void FGNewCache::clear_cache() {
|
||||
|
||||
tile_map_iterator current = tile_cache.begin();
|
||||
tile_map_iterator end = tile_cache.end();
|
||||
|
||||
for ( ; current != end; ++current ) {
|
||||
long index = current->first;
|
||||
SG_LOG( SG_TERRAIN, SG_DEBUG, "clearing " << index );
|
||||
FGTileEntry *e = current->second;
|
||||
if ( e->is_loaded() && (e->get_pending_models() == 0) ) {
|
||||
e->tile_bucket.make_bad();
|
||||
entry_free(index);
|
||||
}
|
||||
}
|
||||
|
||||
// and ... just in case we missed something ...
|
||||
globals->get_scenery()->get_terrain_branch()->removeAllKids();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a new tile and schedule it for loading.
|
||||
*/
|
||||
bool FGNewCache::insert_tile( FGTileEntry *e ) {
|
||||
// clear out a distant entry in the cache if needed.
|
||||
if ( make_space() ) {
|
||||
// register it in the cache
|
||||
long tile_index = e->get_tile_bucket().gen_index();
|
||||
tile_cache[tile_index] = e;
|
||||
|
||||
return true;
|
||||
} else {
|
||||
// failed to find cache space
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -95,6 +95,7 @@ public:
|
|||
inline FGTileEntry *get_tile( const long tile_index ) {
|
||||
tile_map_iterator it = tile_cache.find( tile_index );
|
||||
if ( it != tile_cache.end() ) {
|
||||
it->second->set_timestamp(globals->get_sim_time_sec());
|
||||
return it->second;
|
||||
} else {
|
||||
return NULL;
|
||||
|
|
|
@ -797,12 +797,8 @@ void FGTileEntry::prep_ssg_node( const Point3D& p, sgVec3 up, float vis) {
|
|||
sgCopyVec3( lift_vec, up );
|
||||
|
||||
double agl;
|
||||
if ( current_aircraft.fdm_state ) {
|
||||
agl = current_aircraft.fdm_state->get_Altitude() * SG_FEET_TO_METER
|
||||
- globals->get_scenery()->get_cur_elev();
|
||||
} else {
|
||||
agl = 0.0;
|
||||
}
|
||||
agl = globals->get_current_view()->getAltitudeASL_ft()
|
||||
* SG_FEET_TO_METER - globals->get_scenery()->get_cur_elev();
|
||||
|
||||
// sgTrans just happens to be the
|
||||
// vector from scenery center to the center of this tile which
|
||||
|
@ -845,12 +841,8 @@ void FGTileEntry::prep_ssg_node( const Point3D& p, sgVec3 up, float vis) {
|
|||
sgCopyVec3( lift_vec, up );
|
||||
|
||||
double agl;
|
||||
if ( current_aircraft.fdm_state ) {
|
||||
agl = current_aircraft.fdm_state->get_Altitude() * SG_FEET_TO_METER
|
||||
- globals->get_scenery()->get_cur_elev();
|
||||
} else {
|
||||
agl = 0.0;
|
||||
}
|
||||
agl = globals->get_current_view()->getAltitudeASL_ft()
|
||||
* SG_FEET_TO_METER - globals->get_scenery()->get_cur_elev();
|
||||
|
||||
// sgTrans just happens to be the
|
||||
// vector from scenery center to the center of this tile which
|
||||
|
@ -900,12 +892,8 @@ void FGTileEntry::prep_ssg_node( const Point3D& p, sgVec3 up, float vis) {
|
|||
sgCopyVec3( lift_vec, up );
|
||||
|
||||
double agl1;
|
||||
if ( current_aircraft.fdm_state ) {
|
||||
agl1 = current_aircraft.fdm_state->get_Altitude() * SG_FEET_TO_METER
|
||||
- globals->get_scenery()->get_cur_elev();
|
||||
} else {
|
||||
agl1 = 0.0;
|
||||
}
|
||||
agl1 = globals->get_current_view()->getAltitudeASL_ft()
|
||||
* SG_FEET_TO_METER - globals->get_scenery()->get_cur_elev();
|
||||
|
||||
// sgTrans just happens to be the
|
||||
// vector from scenery center to the center of this tile which
|
||||
|
|
|
@ -190,6 +190,8 @@ private:
|
|||
|
||||
ssgLeaf* gen_lights( ssgVertexArray *lights, int inc, float bright );
|
||||
|
||||
double timestamp;
|
||||
|
||||
public:
|
||||
|
||||
// ADA --->
|
||||
|
@ -272,6 +274,11 @@ public:
|
|||
* return the SSG Transform node for the terrain
|
||||
*/
|
||||
inline ssgTransform *get_terra_transform() { return terra_transform; }
|
||||
|
||||
void set_timestamp(double time_ms) { timestamp = time_ms; }
|
||||
|
||||
inline double get_timestamp() const { return timestamp; }
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -145,7 +145,7 @@ void FGTileMgr::sched_tile( const SGBucket& b ) {
|
|||
|
||||
|
||||
// schedule a needed buckets for loading
|
||||
void FGTileMgr::schedule_needed( double vis) {
|
||||
void FGTileMgr::schedule_needed( double vis, SGBucket curr_bucket) {
|
||||
// sanity check (unfortunately needed!)
|
||||
if ( longitude < -180.0 || longitude > 180.0
|
||||
|| latitude < -90.0 || latitude > 90.0 )
|
||||
|
@ -162,8 +162,8 @@ void FGTileMgr::schedule_needed( double vis) {
|
|||
|
||||
// vis = fgGetDouble("/environment/visibility-m");
|
||||
|
||||
double tile_width = current_bucket.get_width_m();
|
||||
double tile_height = current_bucket.get_height_m();
|
||||
double tile_width = curr_bucket.get_width_m();
|
||||
double tile_height = curr_bucket.get_height_m();
|
||||
// cout << "tile width = " << tile_width << " tile_height = "
|
||||
// << tile_height !<< endl;
|
||||
|
||||
|
@ -173,7 +173,8 @@ void FGTileMgr::schedule_needed( double vis) {
|
|||
if ( yrange < 1 ) { yrange = 1; }
|
||||
// cout << "xrange = " << xrange << " yrange = " << yrange << endl;
|
||||
|
||||
tile_cache.set_max_cache_size( (2*xrange + 2) * (2*yrange + 2) );
|
||||
// note * 2 at end doubles cache size (for fdm and viewer)
|
||||
tile_cache.set_max_cache_size( (2*xrange + 2) * (2*yrange + 2) * 2 );
|
||||
|
||||
SGBucket b;
|
||||
|
||||
|
@ -223,7 +224,7 @@ void FGTileMgr::initialize_queue()
|
|||
// "rings"
|
||||
|
||||
double visibility_meters = fgGetDouble("/environment/visibility-m");
|
||||
schedule_needed(visibility_meters);
|
||||
schedule_needed(visibility_meters, current_bucket);
|
||||
|
||||
// do we really want to lose this? CLO
|
||||
#if 0
|
||||
|
@ -248,31 +249,35 @@ void FGTileMgr::initialize_queue()
|
|||
// chunks. If the chunk isn't already in the cache, then read it from
|
||||
// disk.
|
||||
int FGTileMgr::update( double lon, double lat, double visibility_meters ) {
|
||||
sgdVec3 abs_pos_vector;
|
||||
sgdCopyVec3(abs_pos_vector , globals->get_current_view()->get_absolute_view_pos());
|
||||
return update( lon, lat, visibility_meters, abs_pos_vector, current_bucket, previous_bucket );
|
||||
}
|
||||
|
||||
int FGTileMgr::update( double lon, double lat, double visibility_meters, sgdVec3 abs_pos_vector, SGBucket p_current, SGBucket p_previous ) {
|
||||
// SG_LOG( SG_TERRAIN, SG_DEBUG, "FGTileMgr::update() for "
|
||||
// << lon << " " << lat );
|
||||
|
||||
longitude = lon;
|
||||
latitude = lat;
|
||||
current_bucket = p_current;
|
||||
previous_bucket = p_previous;
|
||||
|
||||
// SG_LOG( SG_TERRAIN, SG_DEBUG, "lon "<< lonlat[LON] <<
|
||||
// " lat " << lonlat[LAT] );
|
||||
|
||||
current_bucket.set_bucket( longitude, latitude );
|
||||
// SG_LOG( SG_TERRAIN, SG_DEBUG, "Updating Tile list for " << current_bucket );
|
||||
|
||||
if ( tile_cache.exists( current_bucket ) ) {
|
||||
current_tile = tile_cache.get_tile( current_bucket );
|
||||
globals->get_scenery()->set_next_center( current_tile->center );
|
||||
} else {
|
||||
SG_LOG( SG_TERRAIN, SG_WARN, "Tile not found (Ok if initializing)" );
|
||||
globals->get_scenery()->set_next_center( Point3D(0.0) );
|
||||
}
|
||||
setCurrentTile( longitude, latitude);
|
||||
|
||||
// do tile load scheduling.
|
||||
// Note that we need keep track of both viewer buckets and fdm buckets.
|
||||
if ( state == Running ) {
|
||||
SG_LOG( SG_TERRAIN, SG_DEBUG, "State == Running" );
|
||||
if (!(current_bucket == previous_bucket )) {
|
||||
// We've moved to a new bucket, we need to schedule any
|
||||
// needed tiles for loading.
|
||||
schedule_needed(visibility_meters);
|
||||
schedule_needed(visibility_meters, current_bucket);
|
||||
}
|
||||
} else if ( state == Start || state == Inited ) {
|
||||
SG_LOG( SG_TERRAIN, SG_INFO, "State == Start || Inited" );
|
||||
|
@ -284,6 +289,7 @@ int FGTileMgr::update( double lon, double lat, double visibility_meters ) {
|
|||
loader.update();
|
||||
}
|
||||
|
||||
|
||||
// load the next model in the load queue. Currently this must
|
||||
// happen in the render thread because model loading can trigger
|
||||
// texture loading which involves use of the opengl api.
|
||||
|
@ -310,18 +316,17 @@ int FGTileMgr::update( double lon, double lat, double visibility_meters ) {
|
|||
|
||||
// cout << "current elevation (ssg) == " << scenery.get_cur_elev() << endl;
|
||||
|
||||
|
||||
// save bucket...
|
||||
previous_bucket = current_bucket;
|
||||
last_longitude = longitude;
|
||||
last_latitude = latitude;
|
||||
|
||||
// activate loader thread one out of every 5 frames
|
||||
if ( counter_hack == 0 ) {
|
||||
// Notify the tile loader that it can load another tile
|
||||
|
||||
loader.update();
|
||||
|
||||
}
|
||||
} else {
|
||||
counter_hack = (counter_hack + 1) % 5;
|
||||
}
|
||||
|
||||
if ( !attach_queue.empty() ) {
|
||||
#ifdef ENABLE_THREADS
|
||||
|
@ -336,27 +341,51 @@ int FGTileMgr::update( double lon, double lat, double visibility_meters ) {
|
|||
// cout << "Adding ssg nodes for "
|
||||
}
|
||||
|
||||
// no reason to update this if we haven't moved...
|
||||
if ( longitude != last_longitude || latitude == last_latitude ) {
|
||||
// update current elevation...
|
||||
updateCurrentElevAtPos(abs_pos_vector);
|
||||
}
|
||||
|
||||
last_longitude = longitude;
|
||||
last_latitude = latitude;
|
||||
|
||||
#if 0
|
||||
}
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// timer event driven call to scheduler for the purpose of refreshing the tile timestamps
|
||||
void FGTileMgr::refresh_view_timestamps() {
|
||||
SG_LOG( SG_TERRAIN, SG_INFO,
|
||||
"Refreshing timestamps for " << current_bucket.get_center_lon() << " " << current_bucket.get_center_lat() );
|
||||
schedule_needed(fgGetDouble("/environment/visibility-m"), current_bucket);
|
||||
}
|
||||
|
||||
// check and set current tile and scenery center...
|
||||
void FGTileMgr::setCurrentTile(double longitude, double latitude) {
|
||||
|
||||
// check tile cache entry...
|
||||
current_bucket.set_bucket( longitude, latitude );
|
||||
if ( tile_cache.exists( current_bucket ) ) {
|
||||
current_tile = tile_cache.get_tile( current_bucket );
|
||||
globals->get_scenery()->set_next_center( current_tile->center );
|
||||
} else {
|
||||
SG_LOG( SG_TERRAIN, SG_WARN, "Tile not found (Ok if initializing)" );
|
||||
globals->get_scenery()->set_next_center( Point3D(0.0) );
|
||||
}
|
||||
}
|
||||
|
||||
void FGTileMgr::updateCurrentElevAtPos(sgdVec3 abs_pos_vector) {
|
||||
|
||||
sgdVec3 sc;
|
||||
sgdSetVec3( sc,
|
||||
globals->get_scenery()->get_center()[0],
|
||||
globals->get_scenery()->get_center()[1],
|
||||
globals->get_scenery()->get_center()[2] );
|
||||
|
||||
/*
|
||||
cout << "abs view pos = "
|
||||
<< globals->get_current_view()->get_abs_view_pos()[0] << ","
|
||||
<< globals->get_current_view()->get_abs_view_pos()[1] << ","
|
||||
<< globals->get_current_view()->get_abs_view_pos()[2]
|
||||
<< " view pos = "
|
||||
<< globals->get_current_view()->get_view_pos()[0] << ","
|
||||
<< globals->get_current_view()->get_view_pos()[1] << ","
|
||||
<< globals->get_current_view()->get_view_pos()[2]
|
||||
<< endl;
|
||||
cout << "current_tile = " << current_tile << endl;
|
||||
cout << "Scenery center = " << sc[0] << "," << sc[1] << "," << sc[2]
|
||||
<< endl;
|
||||
*/
|
||||
|
||||
// overridden with actual values if a terrain intersection is
|
||||
// found
|
||||
double hit_elev = -9999.0;
|
||||
|
@ -371,7 +400,7 @@ int FGTileMgr::update( double lon, double lat, double visibility_meters ) {
|
|||
globals->get_scenery()->get_center()[0],
|
||||
globals->get_scenery()->get_center()[1],
|
||||
globals->get_scenery()->get_center()[2] );
|
||||
hit = fgCurrentElev(globals->get_current_view()->get_absolute_view_pos(),
|
||||
hit = fgCurrentElev(abs_pos_vector,
|
||||
sc,
|
||||
current_tile->get_terra_transform(),
|
||||
&hit_list,
|
||||
|
@ -389,15 +418,8 @@ int FGTileMgr::update( double lon, double lat, double visibility_meters ) {
|
|||
globals->get_scenery()->set_cur_radius( 0.0 );
|
||||
globals->get_scenery()->set_cur_normal( hit_normal );
|
||||
}
|
||||
// cout << "Current elevation = " << scenery.get_cur_elev() << endl;
|
||||
|
||||
#if 0
|
||||
}
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
void FGTileMgr::prep_ssg_nodes(float vis) {
|
||||
// float vis = 0.0;
|
||||
|
|
|
@ -78,7 +78,7 @@ private:
|
|||
void sched_tile( const SGBucket& b );
|
||||
|
||||
// schedule a needed buckets for loading
|
||||
void schedule_needed(double visibility_meters);
|
||||
void schedule_needed(double visibility_meters, SGBucket curr_bucket);
|
||||
|
||||
// see comment at prep_ssg_nodes()
|
||||
void prep_ssg_node( int idx );
|
||||
|
@ -163,6 +163,9 @@ public:
|
|||
// local chunks. If the chunk isn't already in the cache, then
|
||||
// read it from disk.
|
||||
int update( double lon, double lat, double visibility_meters );
|
||||
int update( double lon, double lat, double visibility_meters, sgdVec3 abs_pos_vector, SGBucket p_current, SGBucket p_previous );
|
||||
void setCurrentTile( double longitude, double latitude );
|
||||
void updateCurrentElevAtPos(sgdVec3 abs_pos_vector);
|
||||
|
||||
// Determine scenery altitude. Normally this just happens when we
|
||||
// render the scene, but we'd also like to be able to do this
|
||||
|
@ -179,6 +182,14 @@ public:
|
|||
// transform and update it's range selector based on current
|
||||
// visibilty
|
||||
void prep_ssg_nodes(float visibility_meters);
|
||||
|
||||
//
|
||||
// Set flag with event manager so that non-moving view refreshes tiles...
|
||||
//
|
||||
void refresh_view_timestamps();
|
||||
|
||||
inline SGBucket get_current_bucket () { return current_bucket; }
|
||||
inline SGBucket get_previous_bucket () { return previous_bucket; }
|
||||
};
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue