#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>
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
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() );
&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;
}
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;
}
&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;
#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>
// 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();
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
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
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
copy_from_LaRCsim();
}
+/* getting a namespace conflict...
void FGLaRCsim::set_Velocities_Local_Airmass (double wnorth,
double weast,
double wdown ) {
set_ls();
copy_from_LaRCsim();
}
+*/
void FGLaRCsim::set_Static_pressure(double p) {
SG_LOG( SG_FLIGHT, SG_INFO,
void set_Static_temperature(double T);
void set_Density(double rho);
+/*
void set_Velocities_Local_Airmass (double wnorth,
double weast,
double wdown );
+*/
};
#include <simgear/xml/easyxml.hxx>
#include <Main/globals.hxx>
#include <Main/fg_props.hxx>
-#include <Scenery/scenery.hxx>
#include "FGFDM.hpp"
#include "Atmosphere.hpp"
// 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;
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;
sin_latitude=cos_latitude=0;
sin_longitude=cos_longitude=0;
altitude_agl=0;
+ _acmodel = 0;
}
void
// 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")
* 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);
_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 );
_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 );
// #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);
// 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);
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; }
+
};
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.
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() );
////////////////////////////////////////////////////////////////////
- // 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 lightingsubsystem.
+ // Initialize the lighting subsystem.
////////////////////////////////////////////////////////////////////
// fgUpdateSunPos() needs a few position and view parameters set
#include <simgear/compiler.h>
#include <simgear/constants.h>
+#include <simgear/bucket/newbucket.hxx>
#include <plib/sg.h> // plib include
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; }
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;
#endif // _LOCATION_HXX
-
-
-
-
-
-
-
-
-
-
-
-
-
-
#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
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(),
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, "======= ==== ====");
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() )
- {
- if ( cur_fdm_state->get_Altitude() * SG_FEET_TO_METER <
- (globals->get_scenery()->get_cur_elev() + alt_adjust_m - 3.0) ) {
+// 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 <
+ (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(),
// 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, "" );
}
}
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
#include <simgear/math/sg_geodesy.hxx>
#include <Scenery/scenery.hxx>
-//#include <Main/location.hxx>
#include <simgear/math/vector.hxx>
#include <Main/globals.hxx>
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
void
FGViewer::recalc ()
{
- sgVec3 right, forward;
- sgMat4 tmpROT; // temp rotation work matrices
- 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.
-
if (_type == FG_LOOKFROM) {
- // LOOKFROM mode...
- if ( _from_model ) {
- // update or data from model location
- updateFromModelLocation(_location);
- } else {
- // update from our own data...
- 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());
- }
-
+ recalcLookFrom();
} else {
+ recalcLookAt();
+ }
- // 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);
+ set_clean();
+}
- }
+// recalculate for LookFrom view type...
+void
+FGViewer::recalcLookFrom ()
+{
- // the coordinates generated by the above "recalcPositionVectors"
- sgCopyVec3(_zero_elev, _zero_elev_view_pos);
- sgCopyVec3(_view_pos, _relative_view_pos);
+ sgVec3 right, forward;
+ sgVec3 eye_pos;
+ sgVec3 position_offset; // eye position offsets (xyz)
+
+ // LOOKFROM mode...
- // 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"));
+ // Update location data...
+ if ( _from_model ) {
+ // update or data from model location
+ updateFromModelLocation(_location);
+ } else {
+ // update from our own data...
+ recalcOurOwnLocation( _location, _lon_deg, _lat_deg, _alt_ft,
+ _roll_deg, _pitch_deg, _heading_deg );
}
+ // 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);
+ // 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
+ // "LOCAL" matrix above)
- sgXformVec3( position_offset, position_offset, VIEW_OFFSET );
+ // Orientation Offsets matrix
+ MakeVIEW_OFFSET( VIEW_OFFSET,
+ _heading_offset_deg * SG_DEGREES_TO_RADIANS, _view_up,
+ _pitch_offset_deg * SG_DEGREES_TO_RADIANS, right );
- // add the Position offsets from object to the eye position
- sgAddVec3( eye_pos, eye_pos, position_offset );
+ // Make the VIEW matrix.
+ sgSetVec4(VIEW[0], right[0], right[1], right[2],SG_ZERO);
+ sgSetVec4(VIEW[1], forward[0], forward[1], forward[2],SG_ZERO);
+ sgSetVec4(VIEW[2], _view_up[0], _view_up[1], _view_up[2],SG_ZERO);
+ sgSetVec4(VIEW[3], SG_ZERO, SG_ZERO, SG_ZERO,SG_ONE);
- // at position (what we are looking at)
- sgCopyVec3( at_pos, _view_pos );
+ // rotate matrix to get a matrix to apply Eye Position Offsets
+ sgMat4 VIEW_UP; // L0 forward L1 right L2 up
+ sgCopyVec4(VIEW_UP[0], LOCAL[1]);
+ sgCopyVec4(VIEW_UP[1], LOCAL[2]);
+ sgCopyVec4(VIEW_UP[2], LOCAL[0]);
+ sgZeroVec4(VIEW_UP[3]);
- // Make the VIEW matrix for a "LOOKAT".
- sgMakeLookAtMat4( VIEW, eye_pos, at_pos, _view_up );
- }
+ // Eye Position Offsets to vector
+ sgSetVec3( position_offset, _x_offset_m, _y_offset_m, _z_offset_m );
+ sgXformVec3( position_offset, position_offset, VIEW_UP);
- if (_type == FG_LOOKFROM) {
+ // add the offsets including rotations to the translation vector
+ sgAddVec3( _view_pos, position_offset );
- // 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
- // "LOCAL" matrix above)
+ // multiply the OFFSETS (for heading and pitch) into the VIEW
+ sgPostMultMat4(VIEW, VIEW_OFFSET);
- // Orientation Offsets matrix
- MakeVIEW_OFFSET( VIEW_OFFSET,
- _heading_offset_deg * SG_DEGREES_TO_RADIANS, _view_up,
- _pitch_offset_deg * SG_DEGREES_TO_RADIANS, right );
+ // add the position data to the matrix
+ sgSetVec4(VIEW[3], _view_pos[0], _view_pos[1], _view_pos[2],SG_ONE);
- // Make the VIEW matrix.
- sgSetVec4(VIEW[0], right[0], right[1], right[2],SG_ZERO);
- sgSetVec4(VIEW[1], forward[0], forward[1], forward[2],SG_ZERO);
- sgSetVec4(VIEW[2], _view_up[0], _view_up[1], _view_up[2],SG_ZERO);
- sgSetVec4(VIEW[3], SG_ZERO, SG_ZERO, SG_ZERO,SG_ONE);
+}
- // rotate matrix to get a matrix to apply Eye Position Offsets
- sgMat4 VIEW_UP; // L0 forward L1 right L2 up
- sgCopyVec4(VIEW_UP[0], LOCAL[1]);
- sgCopyVec4(VIEW_UP[1], LOCAL[2]);
- sgCopyVec4(VIEW_UP[2], LOCAL[0]);
- sgZeroVec4(VIEW_UP[3]);
+void
+FGViewer::recalcLookAt ()
+{
- // Eye Position Offsets to vector
- sgSetVec3( position_offset, _x_offset_m, _y_offset_m, _z_offset_m );
- sgXformVec3( position_offset, position_offset, VIEW_UP);
+ sgVec3 right;
+ sgVec3 eye_pos, at_pos;
+ sgVec3 position_offset; // eye position offsets (xyz)
- // add the offsets including rotations to the translation vector
- sgAddVec3( _view_pos, position_offset );
+ // The position vectors originate from the view point or target location
+ // depending on the type of view.
- // multiply the OFFSETS (for heading and pitch) into the VIEW
- sgPostMultMat4(VIEW, VIEW_OFFSET);
+ // LOOKAT mode...
- // add the position data to the matrix
- sgSetVec4(VIEW[3], _view_pos[0], _view_pos[1], _view_pos[2],SG_ONE);
+ // 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());
- set_clean();
-}
+ // copy data from location class to local items...
+ copyLocationData();
-void
-FGViewer::recalcPositionVectors (double lon_deg, double lat_deg, double alt_ft) const
-{
- double sea_level_radius_m;
- double lat_geoc_rad;
+ // 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);
- // 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);
+ sgXformVec3( position_offset, position_offset, VIEW_OFFSET );
- // 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]);
+ // add the Position offsets from object to the eye position
+ sgAddVec3( eye_pos, eye_pos, position_offset );
- // 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]);
+ // Make the VIEW matrix for a "LOOKAT".
+ sgMakeLookAtMat4( VIEW, eye_pos, at_pos, _view_up );
- // 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);
+}
+// copy results from location class to viewer...
+// FIXME: some of these should be changed to reference directly to FGLocation...
+void
+FGViewer::copyLocationData()
+{
+ // 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();
+
+ // 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
return 0.0;
}
+
+
double
FGViewer::get_v_fov()
{
inline void set_dirty() { _dirty = true; }
inline void set_clean() { _dirty = false; }
+
+ // return eye location...
+ virtual FGLocation * getFGLocation () const { return _location; }
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
// Constructor
FGNewCache::FGNewCache( void ) :
- max_cache_size(50)
+ max_cache_size(100)
{
tile_cache.clear();
}
while ( (int)tile_cache.size() >= max_cache_size ) {
sgdVec3 abs_view_pos;
float dist;
- float max_dist = 0.0;
+ 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();
for ( ; current != end; ++current ) {
long index = current->first;
FGTileEntry *e = current->second;
-
if ( e->is_loaded() && (e->get_pending_models() == 0) ) {
- // calculate approximate distance from view point
- sgdCopyVec3( abs_view_pos,
- globals->get_current_view()->get_absolute_view_pos() );
-
- SG_LOG( SG_TERRAIN, SG_DEBUG, "DIST Abs view pos = "
- << abs_view_pos[0] << ","
- << abs_view_pos[1] << ","
- << abs_view_pos[2] );
- SG_LOG( SG_TERRAIN, SG_DEBUG,
- " ref point = " << e->center );
-
- sgdVec3 center;
- sgdSetVec3( center,
- e->center.x(), e->center.y(), e->center.z() );
- dist = sgdDistanceVec3( center, abs_view_pos );
- SG_LOG( SG_TERRAIN, SG_DEBUG, " distance = " << dist );
+ timestamp = e->get_timestamp();
+ if ( timestamp < min_time ) {
+ max_index = index;
+ min_time = timestamp;
+ }
+ if ( timestamp > max_time ) {
+ max_time = timestamp;
+ }
- if ( dist > max_dist ) {
- max_dist = dist;
- max_index = index;
- }
} else {
SG_LOG( SG_TERRAIN, SG_INFO, "loaded = " << e->is_loaded()
- << " pending models = " << e->get_pending_models() );
+ << " 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 furthest cache entry and return true
+ // We will instead free the oldest cache entry and return true
- SG_LOG( SG_TERRAIN, SG_INFO, " max_dist = " << max_dist );
+ 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;
* 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
}
}
+// 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" );
+ 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;
+ float max_dist = 0.0;
+ int max_index = -1;
+
+ // 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) ) {
+ // calculate approximate distance from view point
+ sgdCopyVec3( abs_view_pos,
+ globals->get_current_view()->get_absolute_view_pos() );
+
+ SG_LOG( SG_TERRAIN, SG_DEBUG, "DIST Abs view pos = "
+ << abs_view_pos[0] << ","
+ << abs_view_pos[1] << ","
+ << abs_view_pos[2] );
+ SG_LOG( SG_TERRAIN, SG_DEBUG,
+ " ref point = " << e->center );
+
+ sgdVec3 center;
+ sgdSetVec3( center,
+ e->center.x(), e->center.y(), e->center.z() );
+ dist = sgdDistanceVec3( center, abs_view_pos );
+
+ SG_LOG( SG_TERRAIN, SG_DEBUG, " distance = " << dist );
+
+ if ( dist > max_dist ) {
+ max_dist = dist;
+ max_index = index;
+ }
+ } else {
+ SG_LOG( SG_TERRAIN, SG_INFO, "loaded = " << e->is_loaded()
+ << " pending models = " << e->get_pending_models() );
+ }
+ }
+
+ // If we made it this far, then there were no open cache entries.
+ // We will instead free the furthest cache entry and return true
+
+ SG_LOG( SG_TERRAIN, SG_INFO, " max_dist = " << max_dist );
+ SG_LOG( SG_TERRAIN, SG_INFO, " index = " << max_index );
+ 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;
+}
+#endif
+
+
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;
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
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
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
ssgLeaf* gen_lights( ssgVertexArray *lights, int inc, float bright );
+ double timestamp;
+
public:
// ADA --->
* 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; }
+
};
// 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 )
// 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;
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;
// "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
// 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);
- }
+ 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, current_bucket);
+ }
} else if ( state == Start || state == Inited ) {
SG_LOG( SG_TERRAIN, SG_INFO, "State == Start || Inited" );
initialize_queue();
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.
if ( !model_queue.empty() ) {
- // cout << "loading next model ..." << endl;
+ // cout << "loading next model ..." << endl;
// load the next tile in the queue
#ifdef ENABLE_THREADS
FGDeferredModel* dm = model_queue.pop();
delete dm;
}
-
+
// 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();
-
+ // Notify the tile loader that it can load another tile
+ loader.update();
+ } else {
+ counter_hack = (counter_hack + 1) % 5;
}
- counter_hack = (counter_hack + 1) % 5;
if ( !attach_queue.empty() ) {
#ifdef ENABLE_THREADS
// cout << "Adding ssg nodes for "
}
- 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;
- double hit_radius = 0.0;
- sgdVec3 hit_normal = { 0.0, 0.0, 0.0 };
-
- bool hit = false;
- if ( fabs(sc[0]) > 1.0 || fabs(sc[1]) > 1.0 || fabs(sc[2]) > 1.0 ) {
- // scenery center has been properly defined so any hit
- // should be valid (and not just luck)
- sgdSetVec3( sc,
- 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(),
- sc,
- current_tile->get_terra_transform(),
- &hit_list,
- &hit_elev,
- &hit_radius,
- hit_normal);
- }
+ // no reason to update this if we haven't moved...
+ if ( longitude != last_longitude || latitude == last_latitude ) {
+ // update current elevation...
+ updateCurrentElevAtPos(abs_pos_vector);
+ }
- if ( hit ) {
- globals->get_scenery()->set_cur_elev( hit_elev );
- globals->get_scenery()->set_cur_radius( hit_radius );
- globals->get_scenery()->set_cur_normal( hit_normal );
- } else {
- globals->get_scenery()->set_cur_elev( -9999.0 );
- globals->get_scenery()->set_cur_radius( 0.0 );
- globals->get_scenery()->set_cur_normal( hit_normal );
- }
- // cout << "Current elevation = " << scenery.get_cur_elev() << endl;
+ last_longitude = longitude;
+ last_latitude = latitude;
#if 0
}
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] );
+
+ // overridden with actual values if a terrain intersection is
+ // found
+ double hit_elev = -9999.0;
+ double hit_radius = 0.0;
+ sgdVec3 hit_normal = { 0.0, 0.0, 0.0 };
+
+ bool hit = false;
+ if ( fabs(sc[0]) > 1.0 || fabs(sc[1]) > 1.0 || fabs(sc[2]) > 1.0 ) {
+ // scenery center has been properly defined so any hit
+ // should be valid (and not just luck)
+ sgdSetVec3( sc,
+ globals->get_scenery()->get_center()[0],
+ globals->get_scenery()->get_center()[1],
+ globals->get_scenery()->get_center()[2] );
+ hit = fgCurrentElev(abs_pos_vector,
+ sc,
+ current_tile->get_terra_transform(),
+ &hit_list,
+ &hit_elev,
+ &hit_radius,
+ hit_normal);
+ }
+
+ if ( hit ) {
+ globals->get_scenery()->set_cur_elev( hit_elev );
+ globals->get_scenery()->set_cur_radius( hit_radius );
+ globals->get_scenery()->set_cur_normal( hit_normal );
+ } else {
+ globals->get_scenery()->set_cur_elev( -9999.0 );
+ globals->get_scenery()->set_cur_radius( 0.0 );
+ globals->get_scenery()->set_cur_normal( hit_normal );
+ }
+
+}
void FGTileMgr::prep_ssg_nodes(float vis) {
// float vis = 0.0;
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 );
// 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
// 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; }
};