1
0
Fork 0
flightgear/Simulator/Main/fg_init.cxx
curt 28ee2efbf9 Changes to support plib-1.0.7's font code.
GUI improvements contributed by Norman Vine.
3dfx.sh wrapper script now sets voodoo2 variables as well.
Start of support for user defined texture scale.
Start of support for precalculated texture coordinates.
1999-05-12 02:07:21 +00:00

520 lines
16 KiB
C++

//
// fg_init.cxx -- Flight Gear top level initialization routines
//
// Written by Curtis Olson, started August 1997.
//
// Copyright (C) 1997 Curtis L. Olson - curt@infoplane.com
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
//
// $Id$
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
// For BC 5.01 this must be included before OpenGL includes.
#ifdef FG_MATH_EXCEPTION_CLASH
# include <math.h>
#endif
#include <GL/glut.h>
#include <XGL/xgl.h>
#include <stdio.h>
#include <stdlib.h>
// work around a stdc++ lib bug in some versions of linux, but doesn't
// seem to hurt to have this here for all versions of Linux.
#ifdef linux
# define _G_NO_EXTERN_TEMPLATES
#endif
#include <Include/compiler.h>
#include STL_STRING
#include <Debug/logstream.hxx>
#include <Aircraft/aircraft.hxx>
#include <Airports/simple.hxx>
#include <Astro/sky.hxx>
#include <Astro/stars.hxx>
#include <Astro/solarsystem.hxx>
#include <Autopilot/autopilot.hxx>
#include <Cockpit/cockpit.hxx>
#include <Include/fg_constants.h>
#include <Include/general.hxx>
#include <Joystick/joystick.hxx>
#include <Math/fg_geodesy.hxx>
#include <Math/point3d.hxx>
#include <Math/polar3d.hxx>
#include <Scenery/scenery.hxx>
#include <Scenery/tilemgr.hxx>
#include <Time/event.hxx>
#include <Time/fg_time.hxx>
#include <Time/light.hxx>
#include <Time/sunpos.hxx>
#include <Time/moonpos.hxx>
#include <Weather/weather.hxx>
#include "fg_init.hxx"
#include "options.hxx"
#include "views.hxx"
#include "fg_serial.hxx"
#if defined(FX) && defined(XMESA)
#include <GL/xmesa.h>
#endif
FG_USING_STD(string);
extern const char *default_root;
// Set initial position and orientation
int fgInitPosition( void ) {
string id;
FGInterface *f;
f = current_aircraft.fdm_state;
id = current_options.get_airport_id();
if ( id.length() ) {
// set initial position from airport id
fgAIRPORTS airports;
fgAIRPORT a;
FG_LOG( FG_GENERAL, FG_INFO,
"Attempting to set starting position from airport code "
<< id );
airports.load("apt_simple");
if ( ! airports.search( id, &a ) ) {
FG_LOG( FG_GENERAL, FG_ALERT,
"Failed to find " << id << " in database." );
exit(-1);
} else {
f->set_Longitude( a.longitude * DEG_TO_RAD );
f->set_Latitude( a.latitude * DEG_TO_RAD );
}
} else {
// set initial position from default or command line coordinates
f->set_Longitude( current_options.get_lon() * DEG_TO_RAD );
f->set_Latitude( current_options.get_lat() * DEG_TO_RAD );
}
FG_LOG( FG_GENERAL, FG_INFO,
"starting altitude is = " << current_options.get_altitude() );
f->set_Altitude( current_options.get_altitude() * METER_TO_FEET );
fgFDMSetGroundElevation( current_options.get_flight_model(),
(f->get_Altitude() - 3.758099) * FEET_TO_METER );
FG_LOG( FG_GENERAL, FG_INFO,
"Initial position is: ("
<< (f->get_Longitude() * RAD_TO_DEG) << ", "
<< (f->get_Latitude() * RAD_TO_DEG) << ", "
<< (f->get_Altitude() * FEET_TO_METER) << ")" );
return(1);
}
// General house keeping initializations
int fgInitGeneral( void ) {
string root;
char *mesa_win_state;
FG_LOG( FG_GENERAL, FG_INFO, "General Initialization" );
FG_LOG( FG_GENERAL, FG_INFO, "======= ==============" );
root = current_options.get_fg_root();
if ( ! root.length() ) {
// No root path set? Then bail ...
FG_LOG( FG_GENERAL, FG_ALERT,
"Cannot continue without environment variable FG_ROOT"
<< "being defined." );
exit(-1);
}
FG_LOG( FG_GENERAL, FG_INFO, "FG_ROOT = " << root << endl );
#if defined(FX) && defined(XMESA)
// initialize full screen flag
global_fullscreen = false;
if ( strstr ( general.get_glRenderer(), "Glide" ) ) {
// Test for the MESA_GLX_FX env variable
if ( (mesa_win_state = getenv( "MESA_GLX_FX" )) != NULL) {
// test if we are fullscreen mesa/glide
if ( (mesa_win_state[0] == 'f') ||
(mesa_win_state[0] == 'F') ) {
global_fullscreen = true;
}
}
}
#endif
return 1;
}
// This is the top level init routine which calls all the other
// initialization routines. If you are adding a subsystem to flight
// gear, its initialization call should located in this routine.
// Returns non-zero if a problem encountered.
int fgInitSubsystems( void )
{
FGTime::cur_time_params = new FGTime();
FGInterface *f; // assigned later
fgLIGHT *l = &cur_light_params;
FGTime *t = FGTime::cur_time_params;
FGView *v = &current_view;
FG_LOG( FG_GENERAL, FG_INFO, "Initialize Subsystems");
FG_LOG( FG_GENERAL, FG_INFO, "========== ==========");
// allocates structures so must happen before any of the flight
// model or control parameters are set
fgAircraftInit(); // In the future this might not be the case.
f = current_aircraft.fdm_state;
// set the initial position
fgInitPosition();
// Initialize the Scenery Management subsystem
if ( fgSceneryInit() ) {
// Scenery initialized ok.
} else {
FG_LOG( FG_GENERAL, FG_ALERT, "Error in Scenery initialization!" );
exit(-1);
}
if( fgTileMgrInit() ) {
// Load the local scenery data
fgTileMgrUpdate();
} else {
FG_LOG( FG_GENERAL, FG_ALERT, "Error in Tile Manager initialization!" );
exit(-1);
}
FG_LOG( FG_GENERAL, FG_DEBUG,
"Current terrain elevation after tile mgr init " <<
scenery.cur_elev );
// Calculate ground elevation at starting point (we didn't have
// tmp_abs_view_pos calculated when fgTileMgrUpdate() was called above
//
// calculalate a cartesian point somewhere along the line between
// the center of the earth and our view position. Doesn't have to
// be the exact elevation (this is good because we don't know it
// yet :-)
// now handled inside of the fgTileMgrUpdate()
/*
geod_pos = Point3D( f->get_Longitude(), f->get_Latitude(), 0.0);
tmp_abs_view_pos = fgGeodToCart(geod_pos);
FG_LOG( FG_GENERAL, FG_DEBUG,
"Initial abs_view_pos = " << tmp_abs_view_pos );
scenery.cur_elev =
fgTileMgrCurElev( f->get_Longitude(), f->get_Latitude(),
tmp_abs_view_pos );
FG_LOG( FG_GENERAL, FG_DEBUG,
"Altitude after update " << scenery.cur_elev );
*/
fgFDMSetGroundElevation( current_options.get_flight_model(),
scenery.cur_elev );
// Reset our altitude if we are below ground
FG_LOG( FG_GENERAL, FG_DEBUG, "Current altitude = " << f->get_Altitude() );
FG_LOG( FG_GENERAL, FG_DEBUG, "Current runway altitude = " <<
f->get_Runway_altitude() );
if ( f->get_Altitude() < f->get_Runway_altitude() + 3.758099) {
f->set_Altitude( f->get_Runway_altitude() + 3.758099 );
}
FG_LOG( FG_GENERAL, FG_INFO,
"Updated position (after elevation adj): ("
<< (f->get_Latitude() * RAD_TO_DEG) << ", "
<< (f->get_Longitude() * RAD_TO_DEG) << ", "
<< (f->get_Altitude() * FEET_TO_METER) << ")" );
// We need to calculate a few more values here that would normally
// be calculated by the FDM so that the v->UpdateViewMath()
// routine doesn't get hosed.
double sea_level_radius_meters;
double lat_geoc;
// Set the FG variables first
fgGeodToGeoc( f->get_Latitude(), f->get_Altitude(),
&sea_level_radius_meters, &lat_geoc);
f->set_Geocentric_Position( lat_geoc, f->get_Longitude(),
f->get_Altitude() +
(sea_level_radius_meters * METER_TO_FEET) );
f->set_Sea_level_radius( sea_level_radius_meters * METER_TO_FEET );
f->set_sin_cos_longitude(f->get_Longitude());
f->set_sin_cos_latitude(f->get_Latitude());
f->set_sin_lat_geocentric(sin(lat_geoc));
f->set_cos_lat_geocentric(cos(lat_geoc));
// The following section sets up the flight model EOM parameters
// and should really be read in from one or more files.
// Initial Velocity
f->set_Velocities_Local( 0.0, 0.0, 0.0 );
// Initial Orientation
f->set_Euler_Angles( current_options.get_roll() * DEG_TO_RAD,
current_options.get_pitch() * DEG_TO_RAD,
current_options.get_heading() * DEG_TO_RAD );
// Initial Angular Body rates
f->set_Omega_Body( 7.206685E-05, 0.0, 9.492658E-05 );
f->set_Earth_position_angle( 0.0 );
// Mass properties and geometry values
f->set_Inertias( 8.547270E+01,
1.048000E+03, 3.000000E+03, 3.530000E+03, 0.000000E+00 );
// CG position w.r.t. ref. point
f->set_CG_Position( 0.0, 0.0, 0.0 );
// Initialize the event manager
global_events.Init();
// Output event stats every 60 seconds
global_events.Register( "fgEVENT_MGR::PrintStats()",
fgMethodCallback<fgEVENT_MGR>( &global_events,
&fgEVENT_MGR::PrintStats),
fgEVENT::FG_EVENT_READY, 60000 );
// Initialize the time dependent variables
t->init();
t->update(f);
// Initialize view parameters
FG_LOG( FG_GENERAL, FG_DEBUG, "Before v->init()");
v->Init();
FG_LOG( FG_GENERAL, FG_DEBUG, "After v->init()");
v->UpdateViewMath(f);
FG_LOG( FG_GENERAL, FG_DEBUG, " abs_view_pos = " << v->get_abs_view_pos());
v->UpdateWorldToEye(f);
// Build the solar system
//fgSolarSystemInit(*t);
FG_LOG(FG_GENERAL, FG_INFO, "Building SolarSystem");
SolarSystem::theSolarSystem = new SolarSystem(t);
// Initialize the Stars subsystem
if( fgStarsInit() ) {
// Stars initialized ok.
} else {
FG_LOG( FG_GENERAL, FG_ALERT, "Error in Stars initialization!" );
exit(-1);
}
// Initialize the planetary subsystem
// global_events.Register( "fgPlanetsInit()", fgPlanetsInit,
// fgEVENT::FG_EVENT_READY, 600000);
// Initialize the sun's position
// global_events.Register( "fgSunInit()", fgSunInit,
// fgEVENT::FG_EVENT_READY, 30000 );
// Intialize the moon's position
// global_events.Register( "fgMoonInit()", fgMoonInit,
// fgEVENT::FG_EVENT_READY, 600000 );
// register the periodic update of Sun, moon, and planets
global_events.Register( "ssolsysUpdate", solarSystemRebuild,
fgEVENT::FG_EVENT_READY, 600000);
// fgUpdateSunPos() needs a few position and view parameters set
// so it can calculate local relative sun angle and a few other
// things for correctly orienting the sky.
fgUpdateSunPos();
fgUpdateMoonPos();
global_events.Register( "fgUpdateSunPos()", fgUpdateSunPos,
fgEVENT::FG_EVENT_READY, 60000);
global_events.Register( "fgUpdateMoonPos()", fgUpdateMoonPos,
fgEVENT::FG_EVENT_READY, 60000);
// Initialize Lighting interpolation tables
l->Init();
// update the lighting parameters (based on sun angle)
global_events.Register( "fgLight::Update()",
fgMethodCallback<fgLIGHT>( &cur_light_params,
&fgLIGHT::Update),
fgEVENT::FG_EVENT_READY, 30000 );
// Initialize the weather modeling subsystem
current_weather.Init();
// Initialize the Cockpit subsystem
if( fgCockpitInit( &current_aircraft )) {
// Cockpit initialized ok.
} else {
FG_LOG( FG_GENERAL, FG_ALERT, "Error in Cockpit initialization!" );
exit(-1);
}
// Initialize the "sky"
fgSkyInit();
// Initialize the flight model subsystem data structures base on
// above values
fgFDMInit( current_options.get_flight_model(), cur_fdm_state,
1.0 / DEFAULT_MODEL_HZ );
// I'm just sticking this here for now, it should probably move
// eventually
scenery.cur_elev = f->get_Runway_altitude() * FEET_TO_METER;
if ( f->get_Altitude() < f->get_Runway_altitude() + 3.758099) {
f->set_Altitude( f->get_Runway_altitude() + 3.758099 );
}
FG_LOG( FG_GENERAL, FG_INFO,
"Updated position (after elevation adj): ("
<< (f->get_Latitude() * RAD_TO_DEG) << ", "
<< (f->get_Longitude() * RAD_TO_DEG) << ", "
<< (f->get_Altitude() * FEET_TO_METER) << ")" );
// end of thing that I just stuck in that I should probably move
// Joystick support
if ( fgJoystickInit() ) {
// Joystick initialized ok.
} else {
FG_LOG( FG_GENERAL, FG_ALERT, "Error in Joystick initialization!" );
}
// Autopilot init added here, by Jeff Goeke-Smith
fgAPInit(&current_aircraft);
// Initialize serial ports
#if ! defined( MACOS )
fgSerialInit();
#endif
FG_LOG( FG_GENERAL, FG_INFO, endl);
return(1);
}
void fgReInitSubsystems( void )
{
FGInterface *f = current_aircraft.fdm_state;
FGView *v = &current_view;
FGTime *t = FGTime::cur_time_params;
int toggle_pause = t->getPause();
if( !toggle_pause )
t->togglePauseMode();
fgInitPosition();
if( fgTileMgrInit() ) {
// Load the local scenery data
fgTileMgrUpdate();
} else {
FG_LOG( FG_GENERAL, FG_ALERT, "Error in Tile Manager initialization!" );
exit(-1);
}
fgFDMSetGroundElevation( current_options.get_flight_model(),
scenery.cur_elev );
// Reset our altitude if we are below ground
FG_LOG( FG_GENERAL, FG_DEBUG, "Current altitude = " << f->get_Altitude() );
FG_LOG( FG_GENERAL, FG_DEBUG, "Current runway altitude = " <<
f->get_Runway_altitude() );
if ( f->get_Altitude() < f->get_Runway_altitude() + 3.758099) {
f->set_Altitude( f->get_Runway_altitude() + 3.758099 );
}
double sea_level_radius_meters;
double lat_geoc;
// Set the FG variables first
fgGeodToGeoc( f->get_Latitude(), f->get_Altitude(),
&sea_level_radius_meters, &lat_geoc);
f->set_Geocentric_Position( lat_geoc, f->get_Longitude(),
f->get_Altitude() +
(sea_level_radius_meters * METER_TO_FEET) );
f->set_Sea_level_radius( sea_level_radius_meters * METER_TO_FEET );
f->set_sin_cos_longitude(f->get_Longitude());
f->set_sin_cos_latitude(f->get_Latitude());
f->set_sin_lat_geocentric(sin(lat_geoc));
f->set_cos_lat_geocentric(cos(lat_geoc));
// The following section sets up the flight model EOM parameters
// and should really be read in from one or more files.
// Initial Velocity
f->set_Velocities_Local( 0.0, 0.0, 0.0 );
// Initial Orientation
f->set_Euler_Angles( current_options.get_roll() * DEG_TO_RAD,
current_options.get_pitch() * DEG_TO_RAD,
current_options.get_heading() * DEG_TO_RAD );
// Initial Angular Body rates
f->set_Omega_Body( 7.206685E-05, 0.0, 9.492658E-05 );
f->set_Earth_position_angle( 0.0 );
// Mass properties and geometry values
f->set_Inertias( 8.547270E+01,
1.048000E+03, 3.000000E+03, 3.530000E+03, 0.000000E+00 );
// CG position w.r.t. ref. point
f->set_CG_Position( 0.0, 0.0, 0.0 );
// Initialize view parameters
FG_LOG( FG_GENERAL, FG_DEBUG, "Before v->init()");
v->Init();
FG_LOG( FG_GENERAL, FG_DEBUG, "After v->init()");
v->UpdateViewMath(f);
FG_LOG( FG_GENERAL, FG_DEBUG, " abs_view_pos = " << v->get_abs_view_pos());
v->UpdateWorldToEye(f);
fgFDMInit( current_options.get_flight_model(), cur_fdm_state,
1.0 / DEFAULT_MODEL_HZ );
scenery.cur_elev = f->get_Runway_altitude() * FEET_TO_METER;
if ( f->get_Altitude() < f->get_Runway_altitude() + 3.758099) {
f->set_Altitude( f->get_Runway_altitude() + 3.758099 );
}
controls.reset_all();
fgAPReset();
if( !toggle_pause )
t->togglePauseMode();
}